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