f5fae80c95773ded35e7d1afc557b830c9ab6b6a
[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 GNUNET_DISK_get_blocks_available (const char *part);
266
267
268 /**
269  * Checks whether a handle is invalid
270  *
271  * @param h handle to check
272  * @return GNUNET_YES if invalid, GNUNET_NO if valid
273  */
274 int GNUNET_DISK_handle_invalid (const struct GNUNET_DISK_FileHandle *h);
275
276
277 /**
278  * Check that fil corresponds to a filename
279  * (of a file that exists and that is not a directory).
280  *
281  * @param fil filename to check
282  * @return GNUNET_YES if yes, GNUNET_NO if not a file, GNUNET_SYSERR if something
283  * else (will print an error message in that case, too).
284  */
285 int GNUNET_DISK_file_test (const char *fil);
286
287
288 /**
289  * Move the read/write pointer in a file
290  * @param h handle of an open file
291  * @param offset position to move to
292  * @param whence specification to which position the offset parameter relates to
293  * @return the new position on success, GNUNET_SYSERR otherwise
294  */
295 off_t GNUNET_DISK_file_seek (const struct GNUNET_DISK_FileHandle *h,
296                              off_t offset, enum GNUNET_DISK_Seek whence);
297
298
299 /**
300  * Get the size of the file (or directory)
301  * of the given file (in bytes).
302  *
303  * @param filename name of the file or directory
304  * @param size set to the size of the file (or,
305  *             in the case of directories, the sum
306  *             of all sizes of files in the directory)
307  * @param includeSymLinks should symbolic links be
308  *        included?
309  * @return GNUNET_OK on success, GNUNET_SYSERR on error
310  */
311 int GNUNET_DISK_file_size (const char *filename, uint64_t * size,
312                            int includeSymLinks);
313
314
315 /**
316  * Obtain some unique identifiers for the given file
317  * that can be used to identify it in the local system.
318  * This function is used between GNUnet processes to
319  * quickly check if two files with the same absolute path
320  * are actually identical.  The two processes represent
321  * the same peer but may communicate over the network
322  * (and the file may be on an NFS volume).  This function
323  * may not be supported on all operating systems.
324  *
325  * @param filename name of the file
326  * @param dev set to the device ID
327  * @param ino set to the inode ID
328  * @return GNUNET_OK on success
329  */
330 int GNUNET_DISK_file_get_identifiers (const char *filename, uint64_t * dev,
331                                       uint64_t * ino);
332
333
334 /**
335  * Create an (empty) temporary file on disk.  If the given name is not
336  * an absolute path, the current 'TMPDIR' will be prepended.  In any case,
337  * 6 random characters will be appended to the name to create a unique
338  * filename.
339  * 
340  * @param t component to use for the name;
341  *        does NOT contain "XXXXXX" or "/tmp/".
342  * @return NULL on error, otherwise name of fresh
343  *         file on disk in directory for temporary files
344  */
345 char *GNUNET_DISK_mktemp (const char *t);
346
347
348 /**
349  * Open a file.  Note that the access permissions will only be
350  * used if a new file is created and if the underlying operating
351  * system supports the given permissions.
352  *
353  * @param fn file name to be opened
354  * @param flags opening flags, a combination of GNUNET_DISK_OPEN_xxx bit flags
355  * @param perm permissions for the newly created file, use
356  *             GNUNET_DISK_PERM_NONE if a file could not be created by this
357  *             call (because of flags)
358  * @return IO handle on success, NULL on error
359  */
360 struct GNUNET_DISK_FileHandle *GNUNET_DISK_file_open (const char *fn,
361                                                       enum GNUNET_DISK_OpenFlags
362                                                       flags,
363                                                       enum
364                                                       GNUNET_DISK_AccessPermissions
365                                                       perm);
366
367 /**
368  * Creates an interprocess channel
369  * @param blocking creates an asynchronous pipe if set to GNUNET_NO
370  * @param inherit_read 1 to make read handle inheritable, 0 otherwise (NT only)
371  * @param inherit_write 1 to make write handle inheritable, 0 otherwise (NT only)
372  * @return handle to the new pipe, NULL on error
373  */
374 struct GNUNET_DISK_PipeHandle *GNUNET_DISK_pipe (int blocking, int inherit_read,
375                                                  int inherit_write);
376
377
378 /**
379  * Closes an interprocess channel
380  * @param p pipe
381  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
382  */
383 int GNUNET_DISK_pipe_close (struct GNUNET_DISK_PipeHandle *p);
384
385 /**
386  * Closes one half of an interprocess channel
387  *
388  * @param p pipe to close end of
389  * @param end which end of the pipe to close
390  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
391  */
392 int GNUNET_DISK_pipe_close_end (struct GNUNET_DISK_PipeHandle *p,
393                                 enum GNUNET_DISK_PipeEnd end);
394
395 /**
396  * Close an open file.
397  *
398  * @param h file handle
399  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
400  */
401 int GNUNET_DISK_file_close (struct GNUNET_DISK_FileHandle *h);
402
403
404 /**
405  * Get the handle to a particular pipe end
406  *
407  * @param p pipe
408  * @param n end to access
409  * @return handle for the respective end
410  */
411 const struct GNUNET_DISK_FileHandle *GNUNET_DISK_pipe_handle (const struct
412                                                               GNUNET_DISK_PipeHandle
413                                                               *p,
414                                                               enum
415                                                               GNUNET_DISK_PipeEnd
416                                                               n);
417
418 /**
419  * Read the contents of a binary file into a buffer.
420  * @param h handle to an open file
421  * @param result the buffer to write the result to
422  * @param len the maximum number of bytes to read
423  * @return the number of bytes read on success, GNUNET_SYSERR on failure
424  */
425 ssize_t GNUNET_DISK_file_read (const struct GNUNET_DISK_FileHandle *h,
426                                void *result, size_t len);
427
428
429 /**
430  * Read the contents of a binary file into a buffer.
431  *
432  * @param fn file name
433  * @param result the buffer to write the result to
434  * @param len the maximum number of bytes to read
435  * @return number of bytes read, GNUNET_SYSERR on failure
436  */
437 ssize_t GNUNET_DISK_fn_read (const char *fn, void *result, size_t len);
438
439
440 /**
441  * Write a buffer to a file.
442  *
443  * @param h handle to open file
444  * @param buffer the data to write
445  * @param n number of bytes to write
446  * @return number of bytes written on success, GNUNET_SYSERR on error
447  */
448 ssize_t GNUNET_DISK_file_write (const struct GNUNET_DISK_FileHandle *h,
449                                 const void *buffer, size_t n);
450
451
452 /**
453  * Write a buffer to a file.  If the file is longer than
454  * the given buffer size, it will be truncated.
455  *
456  * @param fn file name
457  * @param buffer the data to write
458  * @param n number of bytes to write
459  * @param mode file permissions 
460  * @return number of bytes written on success, GNUNET_SYSERR on error
461  */
462 ssize_t GNUNET_DISK_fn_write (const char *fn, const void *buffer, size_t n,
463                               enum GNUNET_DISK_AccessPermissions mode);
464
465
466 /**
467  * Copy a file.
468  *
469  * @param src file to copy
470  * @param dst destination file name
471  * @return GNUNET_OK on success, GNUNET_SYSERR on error
472  */
473 int GNUNET_DISK_file_copy (const char *src, const char *dst);
474
475
476 /**
477  * Scan a directory for files.
478  *
479  * @param dirName the name of the directory
480  * @param callback the method to call for each file
481  * @param callback_cls closure for callback
482  * @return the number of files found, -1 on error
483  */
484 int GNUNET_DISK_directory_scan (const char *dirName,
485                                 GNUNET_FileNameCallback callback,
486                                 void *callback_cls);
487
488
489 /**
490  * Opaque handle used for iterating over a directory.
491  */
492 struct GNUNET_DISK_DirectoryIterator;
493
494
495 /**
496  * Function called to iterate over a directory.
497  *
498  * @param cls closure
499  * @param di argument to pass to "GNUNET_DISK_directory_iterator_next" to
500  *           get called on the next entry (or finish cleanly);
501  *           NULL on error (will be the last call in that case)
502  * @param filename complete filename (absolute path)
503  * @param dirname directory name (absolute path)
504  */
505 typedef void (*GNUNET_DISK_DirectoryIteratorCallback) (void *cls,
506                                                        struct
507                                                        GNUNET_DISK_DirectoryIterator
508                                                        * di,
509                                                        const char *filename,
510                                                        const char *dirname);
511
512
513 /**
514  * This function must be called during the DiskIteratorCallback
515  * (exactly once) to schedule the task to process the next
516  * filename in the directory (if there is one).
517  *
518  * @param iter opaque handle for the iterator
519  * @param can set to GNUNET_YES to terminate the iteration early
520  * @return GNUNET_YES if iteration will continue,
521  *         GNUNET_NO if this was the last entry (and iteration is complete),
522  *         GNUNET_SYSERR if "can" was YES
523  */
524 int GNUNET_DISK_directory_iterator_next (struct GNUNET_DISK_DirectoryIterator
525                                          *iter, int can);
526
527
528 /**
529  * Scan a directory for files using the scheduler to run a task for
530  * each entry.  The name of the directory must be expanded first (!).
531  * If a scheduler does not need to be used, GNUNET_DISK_directory_scan
532  * may provide a simpler API.
533  *
534  * @param prio priority to use
535  * @param dirName the name of the directory
536  * @param callback the method to call for each file
537  * @param callback_cls closure for callback
538  */
539 void GNUNET_DISK_directory_iterator_start (enum GNUNET_SCHEDULER_Priority prio,
540                                            const char *dirName,
541                                            GNUNET_DISK_DirectoryIteratorCallback
542                                            callback, void *callback_cls);
543
544
545 /**
546  * Create the directory structure for storing
547  * a file.
548  *
549  * @param filename name of a file in the directory
550  * @returns GNUNET_OK on success, GNUNET_SYSERR on failure,
551  *          GNUNET_NO if directory exists but is not writeable
552  */
553 int GNUNET_DISK_directory_create_for_file (const char *filename);
554
555
556 /**
557  * Test if "fil" is a directory that can be accessed.
558  * Will not print an error message if the directory
559  * does not exist.  Will log errors if GNUNET_SYSERR is
560  * returned.
561  *
562  * @param fil filename to test
563  * @return GNUNET_YES if yes, GNUNET_NO if does not exist, GNUNET_SYSERR
564  *   on any error and if exists but not directory
565  */
566 int GNUNET_DISK_directory_test (const char *fil);
567
568
569 /**
570  * Remove all files in a directory (rm -rf). Call with
571  * caution.
572  *
573  * @param fileName the file to remove
574  * @return GNUNET_OK on success, GNUNET_SYSERR on error
575  */
576 int GNUNET_DISK_directory_remove (const char *fileName);
577
578
579 /**
580  * Implementation of "mkdir -p"
581  *
582  * @param dir the directory to create
583  * @returns GNUNET_SYSERR on failure, GNUNET_OK otherwise
584  */
585 int GNUNET_DISK_directory_create (const char *dir);
586
587
588 /**
589  * Lock a part of a file.
590  *
591  * @param fh file handle
592  * @param lockStart absolute position from where to lock
593  * @param lockEnd absolute position until where to lock
594  * @param excl GNUNET_YES for an exclusive lock
595  * @return GNUNET_OK on success, GNUNET_SYSERR on error
596  */
597 int GNUNET_DISK_file_lock (struct GNUNET_DISK_FileHandle *fh, off_t lockStart,
598                            off_t lockEnd, int excl);
599
600
601 /**
602  * Unlock a part of a file
603  * @param fh file handle
604  * @param unlockStart absolute position from where to unlock
605  * @param unlockEnd absolute position until where to unlock
606  * @return GNUNET_OK on success, GNUNET_SYSERR on error
607  */
608 int GNUNET_DISK_file_unlock (struct GNUNET_DISK_FileHandle *fh,
609                              off_t unlockStart, off_t unlockEnd);
610
611
612 /**
613  * @brief Removes special characters as ':' from a filename.
614  * @param fn the filename to canonicalize
615  */
616 void GNUNET_DISK_filename_canonicalize (char *fn);
617
618
619 /**
620  * @brief Change owner of a file
621  * @param filename file to change
622  * @param user new owner of the file
623  * @return GNUNET_OK on success, GNUNET_SYSERR on failure
624  */
625 int GNUNET_DISK_file_change_owner (const char *filename, const char *user);
626
627
628 /**
629  * Construct full path to a file inside of the private
630  * directory used by GNUnet.  Also creates the corresponding
631  * directory.  If the resulting name is supposed to be
632  * a directory, end the last argument in '/' (or pass
633  * DIR_SEPARATOR_STR as the last argument before NULL).
634  *
635  * @param cfg configuration to use
636  * @param serviceName name of the service asking
637  * @param ... is NULL-terminated list of
638  *                path components to append to the
639  *                private directory name.
640  * @return the constructed filename
641  */
642 char *GNUNET_DISK_get_home_filename (const struct GNUNET_CONFIGURATION_Handle
643                                      *cfg, const char *serviceName, ...);
644
645
646 /**
647  * Opaque handle for a memory-mapping operation.
648  */
649 struct GNUNET_DISK_MapHandle;
650
651 /**
652  * Map a file into memory
653  * @param h open file handle
654  * @param m handle to the new mapping (will be set)
655  * @param access access specification, GNUNET_DISK_MAP_TYPE_xxx
656  * @param len size of the mapping
657  * @return pointer to the mapped memory region, NULL on failure
658  */
659 void *GNUNET_DISK_file_map (const struct GNUNET_DISK_FileHandle *h,
660                             struct GNUNET_DISK_MapHandle **m,
661                             enum GNUNET_DISK_MapType access, size_t len);
662
663 /**
664  * Unmap a file
665  *
666  * @param h mapping handle
667  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
668  */
669 int GNUNET_DISK_file_unmap (struct GNUNET_DISK_MapHandle *h);
670
671 /**
672  * Write file changes to disk
673  * @param h handle to an open file
674  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
675  */
676 int GNUNET_DISK_file_sync (const struct GNUNET_DISK_FileHandle *h);
677
678 /**
679  * Creates a named pipe/FIFO and opens it
680  * @param fn pointer to the name of the named pipe or to NULL
681  * @param flags open flags
682  * @param perm access permissions
683  * @return pipe handle on success, NULL on error
684  */
685 struct GNUNET_DISK_FileHandle *GNUNET_DISK_npipe_create (char **fn,
686                                                          enum
687                                                          GNUNET_DISK_OpenFlags
688                                                          flags,
689                                                          enum
690                                                          GNUNET_DISK_AccessPermissions
691                                                          perm);
692
693 /**
694  * Opens already existing named pipe/FIFO
695  *
696  * @param fn name of an existing named pipe
697  * @param flags open flags
698  * @param perm access permissions
699  * @return pipe handle on success, NULL on error
700  */
701 struct GNUNET_DISK_FileHandle *GNUNET_DISK_npipe_open (const char *fn,
702                                                        enum
703                                                        GNUNET_DISK_OpenFlags
704                                                        flags,
705                                                        enum
706                                                        GNUNET_DISK_AccessPermissions
707                                                        perm);
708
709 /**
710  * Closes a named pipe/FIFO
711  * @param pipe named pipe
712  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
713  */
714 int GNUNET_DISK_npipe_close (struct GNUNET_DISK_FileHandle *pipe);
715
716 #if 0                           /* keep Emacsens' auto-indent happy */
717 {
718 #endif
719 #ifdef __cplusplus
720 }
721 #endif
722
723
724 /* ifndef GNUNET_DISK_LIB_H */
725 #endif
726 /* end of gnunet_disk_lib.h */