curly wars / auto-indentation
[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  * Creates an interprocess channel
373  * @param blocking creates an asynchronous pipe if set to GNUNET_NO
374  * @param inherit_read 1 to make read handle inheritable, 0 otherwise (NT only)
375  * @param inherit_write 1 to make write handle inheritable, 0 otherwise (NT only)
376  * @return handle to the new pipe, NULL on error
377  */
378 struct GNUNET_DISK_PipeHandle *
379 GNUNET_DISK_pipe (int blocking, int inherit_read, int inherit_write);
380
381
382 /**
383  * Closes an interprocess channel
384  * @param p pipe
385  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
386  */
387 int
388 GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p);
389
390 /**
391  * Closes one half of an interprocess channel
392  *
393  * @param p pipe to close end of
394  * @param end which end of the pipe to close
395  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
396  */
397 int
398 GNUNET_DISK_pipe_close_end (struct GNUNET_DISK_PipeHandle *p,
399                             enum GNUNET_DISK_PipeEnd end);
400
401 /**
402  * Close an open file.
403  *
404  * @param h file handle
405  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
406  */
407 int
408 GNUNET_DISK_file_close (struct GNUNET_DISK_FileHandle *h);
409
410
411 /**
412  * Get the handle to a particular pipe end
413  *
414  * @param p pipe
415  * @param n end to access
416  * @return handle for the respective end
417  */
418 const struct GNUNET_DISK_FileHandle *
419 GNUNET_DISK_pipe_handle (const struct GNUNET_DISK_PipeHandle *p,
420                          enum GNUNET_DISK_PipeEnd n);
421
422 /**
423  * Read the contents of a binary file into a buffer.
424  * @param h handle to an open file
425  * @param result the buffer to write the result to
426  * @param len the maximum number of bytes to read
427  * @return the number of bytes read on success, GNUNET_SYSERR on failure
428  */
429 ssize_t
430 GNUNET_DISK_file_read (const struct GNUNET_DISK_FileHandle *h, void *result,
431                        size_t len);
432
433
434 /**
435  * Read the contents of a binary file into a buffer.
436  *
437  * @param fn file name
438  * @param result the buffer to write the result to
439  * @param len the maximum number of bytes to read
440  * @return number of bytes read, GNUNET_SYSERR on failure
441  */
442 ssize_t
443 GNUNET_DISK_fn_read (const char *fn, void *result, size_t len);
444
445
446 /**
447  * Write a buffer to a file.
448  *
449  * @param h handle to open file
450  * @param buffer the data to write
451  * @param n number of bytes to write
452  * @return number of bytes written on success, GNUNET_SYSERR on error
453  */
454 ssize_t
455 GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle *h,
456                         const void *buffer, size_t n);
457
458
459 /**
460  * Write a buffer to a file.  If the file is longer than
461  * the given buffer size, it will be truncated.
462  *
463  * @param fn file name
464  * @param buffer the data to write
465  * @param n number of bytes to write
466  * @param mode file permissions
467  * @return number of bytes written on success, GNUNET_SYSERR on error
468  */
469 ssize_t
470 GNUNET_DISK_fn_write (const char *fn, const void *buffer, size_t n,
471                       enum GNUNET_DISK_AccessPermissions mode);
472
473
474 /**
475  * Copy a file.
476  *
477  * @param src file to copy
478  * @param dst destination file name
479  * @return GNUNET_OK on success, GNUNET_SYSERR on error
480  */
481 int
482 GNUNET_DISK_file_copy (const char *src, const char *dst);
483
484
485 /**
486  * Scan a directory for files.
487  *
488  * @param dirName the name of the directory
489  * @param callback the method to call for each file
490  * @param callback_cls closure for callback
491  * @return the number of files found, -1 on error
492  */
493 int
494 GNUNET_DISK_directory_scan (const char *dirName,
495                             GNUNET_FileNameCallback callback,
496                             void *callback_cls);
497
498
499 /**
500  * Opaque handle used for iterating over a directory.
501  */
502 struct GNUNET_DISK_DirectoryIterator;
503
504
505 /**
506  * Function called to iterate over a directory.
507  *
508  * @param cls closure
509  * @param di argument to pass to "GNUNET_DISK_directory_iterator_next" to
510  *           get called on the next entry (or finish cleanly);
511  *           NULL on error (will be the last call in that case)
512  * @param filename complete filename (absolute path)
513  * @param dirname directory name (absolute path)
514  */
515 typedef void (*GNUNET_DISK_DirectoryIteratorCallback) (void *cls,
516                                                        struct
517                                                        GNUNET_DISK_DirectoryIterator
518                                                        * di,
519                                                        const char *filename,
520                                                        const char *dirname);
521
522
523 /**
524  * This function must be called during the DiskIteratorCallback
525  * (exactly once) to schedule the task to process the next
526  * filename in the directory (if there is one).
527  *
528  * @param iter opaque handle for the iterator
529  * @param can set to GNUNET_YES to terminate the iteration early
530  * @return GNUNET_YES if iteration will continue,
531  *         GNUNET_NO if this was the last entry (and iteration is complete),
532  *         GNUNET_SYSERR if "can" was YES
533  */
534 int
535 GNUNET_DISK_directory_iterator_next (struct GNUNET_DISK_DirectoryIterator *iter,
536                                      int can);
537
538
539 /**
540  * Scan a directory for files using the scheduler to run a task for
541  * each entry.  The name of the directory must be expanded first (!).
542  * If a scheduler does not need to be used, GNUNET_DISK_directory_scan
543  * may provide a simpler API.
544  *
545  * @param prio priority to use
546  * @param dirName the name of the directory
547  * @param callback the method to call for each file
548  * @param callback_cls closure for callback
549  */
550 void
551 GNUNET_DISK_directory_iterator_start (enum GNUNET_SCHEDULER_Priority prio,
552                                       const char *dirName,
553                                       GNUNET_DISK_DirectoryIteratorCallback
554                                       callback, void *callback_cls);
555
556
557 /**
558  * Create the directory structure for storing
559  * a file.
560  *
561  * @param filename name of a file in the directory
562  * @returns GNUNET_OK on success, GNUNET_SYSERR on failure,
563  *          GNUNET_NO if directory exists but is not writeable
564  */
565 int
566 GNUNET_DISK_directory_create_for_file (const char *filename);
567
568
569 /**
570  * Test if "fil" is a directory that can be accessed.
571  * Will not print an error message if the directory
572  * does not exist.  Will log errors if GNUNET_SYSERR is
573  * returned.
574  *
575  * @param fil filename to test
576  * @return GNUNET_YES if yes, GNUNET_NO if does not exist, GNUNET_SYSERR
577  *   on any error and if exists but not directory
578  */
579 int
580 GNUNET_DISK_directory_test (const char *fil);
581
582
583 /**
584  * Remove all files in a directory (rm -rf). Call with
585  * caution.
586  *
587  * @param fileName the file to remove
588  * @return GNUNET_OK on success, GNUNET_SYSERR on error
589  */
590 int
591 GNUNET_DISK_directory_remove (const char *fileName);
592
593
594 /**
595  * Implementation of "mkdir -p"
596  *
597  * @param dir the directory to create
598  * @returns GNUNET_SYSERR on failure, GNUNET_OK otherwise
599  */
600 int
601 GNUNET_DISK_directory_create (const char *dir);
602
603
604 /**
605  * Lock a part of a file.
606  *
607  * @param fh file handle
608  * @param lockStart absolute position from where to lock
609  * @param lockEnd absolute position until where to lock
610  * @param excl GNUNET_YES for an exclusive lock
611  * @return GNUNET_OK on success, GNUNET_SYSERR on error
612  */
613 int
614 GNUNET_DISK_file_lock (struct GNUNET_DISK_FileHandle *fh, off_t lockStart,
615                        off_t lockEnd, int excl);
616
617
618 /**
619  * Unlock a part of a file
620  * @param fh file handle
621  * @param unlockStart absolute position from where to unlock
622  * @param unlockEnd absolute position until where to unlock
623  * @return GNUNET_OK on success, GNUNET_SYSERR on error
624  */
625 int
626 GNUNET_DISK_file_unlock (struct GNUNET_DISK_FileHandle *fh, off_t unlockStart,
627                          off_t unlockEnd);
628
629
630 /**
631  * @brief Removes special characters as ':' from a filename.
632  * @param fn the filename to canonicalize
633  */
634 void
635 GNUNET_DISK_filename_canonicalize (char *fn);
636
637
638 /**
639  * @brief Change owner of a file
640  * @param filename file to change
641  * @param user new owner of the file
642  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
643  */
644 int
645 GNUNET_DISK_file_change_owner (const char *filename, const char *user);
646
647
648 /**
649  * Construct full path to a file inside of the private
650  * directory used by GNUnet.  Also creates the corresponding
651  * directory.  If the resulting name is supposed to be
652  * a directory, end the last argument in '/' (or pass
653  * DIR_SEPARATOR_STR as the last argument before NULL).
654  *
655  * @param cfg configuration to use
656  * @param serviceName name of the service asking
657  * @param ... is NULL-terminated list of
658  *                path components to append to the
659  *                private directory name.
660  * @return the constructed filename
661  */
662 char *
663 GNUNET_DISK_get_home_filename (const struct GNUNET_CONFIGURATION_Handle *cfg,
664                                const char *serviceName, ...);
665
666
667 /**
668  * Opaque handle for a memory-mapping operation.
669  */
670 struct GNUNET_DISK_MapHandle;
671
672 /**
673  * Map a file into memory
674  * @param h open file handle
675  * @param m handle to the new mapping (will be set)
676  * @param access access specification, GNUNET_DISK_MAP_TYPE_xxx
677  * @param len size of the mapping
678  * @return pointer to the mapped memory region, NULL on failure
679  */
680 void *
681 GNUNET_DISK_file_map (const struct GNUNET_DISK_FileHandle *h,
682                       struct GNUNET_DISK_MapHandle **m,
683                       enum GNUNET_DISK_MapType access, size_t len);
684
685 /**
686  * Unmap a file
687  *
688  * @param h mapping handle
689  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
690  */
691 int
692 GNUNET_DISK_file_unmap (struct GNUNET_DISK_MapHandle *h);
693
694 /**
695  * Write file changes to disk
696  * @param h handle to an open file
697  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
698  */
699 int
700 GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h);
701
702 /**
703  * Creates a named pipe/FIFO and opens it
704  * @param fn pointer to the name of the named pipe or to NULL
705  * @param flags open flags
706  * @param perm access permissions
707  * @return pipe handle on success, NULL on error
708  */
709 struct GNUNET_DISK_FileHandle *
710 GNUNET_DISK_npipe_create (char **fn, enum GNUNET_DISK_OpenFlags flags,
711                           enum GNUNET_DISK_AccessPermissions perm);
712
713 /**
714  * Opens already existing named pipe/FIFO
715  *
716  * @param fn name of an existing named pipe
717  * @param flags open flags
718  * @param perm access permissions
719  * @return pipe handle on success, NULL on error
720  */
721 struct GNUNET_DISK_FileHandle *
722 GNUNET_DISK_npipe_open (const char *fn, enum GNUNET_DISK_OpenFlags flags,
723                         enum GNUNET_DISK_AccessPermissions perm);
724
725 /**
726  * Closes a named pipe/FIFO
727  * @param pipe named pipe
728  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
729  */
730 int
731 GNUNET_DISK_npipe_close (struct GNUNET_DISK_FileHandle *pipe);
732
733 #if 0                           /* keep Emacsens' auto-indent happy */
734 {
735 #endif
736 #ifdef __cplusplus
737 }
738 #endif
739
740
741 /* ifndef GNUNET_DISK_LIB_H */
742 #endif
743 /* end of gnunet_disk_lib.h */