diff options
author | grothoff <grothoff@140774ce-b5e7-0310-ab8b-a85725594a96> | 2012-12-09 15:38:55 +0000 |
---|---|---|
committer | grothoff <grothoff@140774ce-b5e7-0310-ab8b-a85725594a96> | 2012-12-09 15:38:55 +0000 |
commit | 73e7ff269e9c15cce71b8cba21ee0c12513bb09a (patch) | |
tree | 65fa45ef0f625551c6e94c6271ce3e74a3b36563 | |
parent | 6837b3c28e207d6ed0211755801bff0e2647021c (diff) |
adding GNUNET_DISK_file_backup function; fixing #2646
git-svn-id: https://gnunet.org/svn/gnunet@25333 140774ce-b5e7-0310-ab8b-a85725594a96
-rw-r--r-- | src/include/gnunet_disk_lib.h | 171 | ||||
-rw-r--r-- | src/util/crypto_rsa.c | 13 | ||||
-rw-r--r-- | src/util/disk.c | 32 |
3 files changed, 127 insertions, 89 deletions
diff --git a/src/include/gnunet_disk_lib.h b/src/include/gnunet_disk_lib.h index 9d4cd1820b..dd42f9e91f 100644 --- a/src/include/gnunet_disk_lib.h +++ b/src/include/gnunet_disk_lib.h @@ -1,6 +1,6 @@ /* This file is part of GNUnet. - (C) 2001, 2002, 2003, 2004, 2005, 2006, 2009 Christian Grothoff (and other contributing authors) + (C) 2001-2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published @@ -17,10 +17,10 @@ Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - /** * @file include/gnunet_disk_lib.h * @brief disk IO apis + * @author Christian Grothoff */ #ifndef GNUNET_DISK_LIB_H #define GNUNET_DISK_LIB_H @@ -85,8 +85,7 @@ struct GNUNET_DISK_FileHandle */ int fd; -#endif /* - */ +#endif }; @@ -113,39 +112,39 @@ extern "C" enum GNUNET_DISK_OpenFlags { - /** - * Open the file for reading - */ + /** + * Open the file for reading + */ GNUNET_DISK_OPEN_READ = 1, - /** - * Open the file for writing - */ + /** + * Open the file for writing + */ GNUNET_DISK_OPEN_WRITE = 2, - /** - * Open the file for both reading and writing - */ + /** + * Open the file for both reading and writing + */ GNUNET_DISK_OPEN_READWRITE = 3, - /** - * Fail if file already exists - */ + /** + * Fail if file already exists + */ GNUNET_DISK_OPEN_FAILIFEXISTS = 4, - /** - * Truncate file if it exists - */ + /** + * Truncate file if it exists + */ GNUNET_DISK_OPEN_TRUNCATE = 8, - /** - * Create file if it doesn't exist - */ + /** + * Create file if it doesn't exist + */ GNUNET_DISK_OPEN_CREATE = 16, - /** - * Append to the file - */ + /** + * Append to the file + */ GNUNET_DISK_OPEN_APPEND = 32 }; @@ -154,18 +153,19 @@ enum GNUNET_DISK_OpenFlags */ enum GNUNET_DISK_MapType { - /** - * Read-only memory map. - */ + /** + * Read-only memory map. + */ GNUNET_DISK_MAP_TYPE_READ = 1, - - /** - * Write-able memory map. - */ + + /** + * Write-able memory map. + */ GNUNET_DISK_MAP_TYPE_WRITE = 2, - /** - * Read-write memory map. - */ + + /** + * Read-write memory map. + */ GNUNET_DISK_MAP_TYPE_READWRITE = 3 }; @@ -175,54 +175,54 @@ enum GNUNET_DISK_MapType */ enum GNUNET_DISK_AccessPermissions { - /** - * Nobody is allowed to do anything to the file. - */ + /** + * Nobody is allowed to do anything to the file. + */ GNUNET_DISK_PERM_NONE = 0, - /** - * Owner can read. - */ + /** + * Owner can read. + */ GNUNET_DISK_PERM_USER_READ = 1, - /** - * Owner can write. - */ + /** + * Owner can write. + */ GNUNET_DISK_PERM_USER_WRITE = 2, - /** - * Owner can execute. - */ + /** + * Owner can execute. + */ GNUNET_DISK_PERM_USER_EXEC = 4, - /** - * Group can read. - */ + /** + * Group can read. + */ GNUNET_DISK_PERM_GROUP_READ = 8, - /** - * Group can write. - */ + /** + * Group can write. + */ GNUNET_DISK_PERM_GROUP_WRITE = 16, - /** - * Group can execute. - */ + /** + * Group can execute. + */ GNUNET_DISK_PERM_GROUP_EXEC = 32, - /** - * Everybody can read. - */ + /** + * Everybody can read. + */ GNUNET_DISK_PERM_OTHER_READ = 64, - /** - * Everybody can write. - */ + /** + * Everybody can write. + */ GNUNET_DISK_PERM_OTHER_WRITE = 128, - /** - * Everybody can execute. - */ + /** + * Everybody can execute. + */ GNUNET_DISK_PERM_OTHER_EXEC = 256 }; @@ -233,19 +233,19 @@ enum GNUNET_DISK_AccessPermissions */ enum GNUNET_DISK_Seek { - /** - * Seek an absolute position (from the start of the file). - */ + /** + * Seek an absolute position (from the start of the file). + */ GNUNET_DISK_SEEK_SET = 0, - /** - * Seek a relative position (from the current offset). - */ + /** + * Seek a relative position (from the current offset). + */ GNUNET_DISK_SEEK_CUR = 1, - /** - * Seek an absolute position from the end of the file. - */ + /** + * Seek an absolute position from the end of the file. + */ GNUNET_DISK_SEEK_END = 2 }; @@ -255,14 +255,14 @@ enum GNUNET_DISK_Seek */ enum GNUNET_DISK_PipeEnd { - /** - * The reading-end of a pipe. - */ + /** + * The reading-end of a pipe. + */ GNUNET_DISK_PIPE_END_READ = 0, - /** - * The writing-end of a pipe. - */ + /** + * The writing-end of a pipe. + */ GNUNET_DISK_PIPE_END_WRITE = 1 }; @@ -301,6 +301,17 @@ GNUNET_DISK_file_test (const char *fil); /** + * Move a file out of the way (create a backup) by + * renaming it to "orig.NUM~" where NUM is the smallest + * number that is not used yet. + * + * @param fil name of the file to back up + */ +void +GNUNET_DISK_file_backup (const char *fil); + + +/** * Move the read/write pointer in a file * @param h handle of an open file * @param offset position to move to diff --git a/src/util/crypto_rsa.c b/src/util/crypto_rsa.c index ff99ecf0b8..cd9a33f614 100644 --- a/src/util/crypto_rsa.c +++ b/src/util/crypto_rsa.c @@ -641,12 +641,11 @@ try_read_key (const char *filename) if (fs > UINT16_MAX) { LOG (GNUNET_ERROR_TYPE_ERROR, - _("File `%s' does not contain a valid private key (too long, %llu bytes). Deleting it.\n"), + _("File `%s' does not contain a valid private key (too long, %llu bytes). Renaming it.\n"), filename, (unsigned long long) fs); GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd)); - if (0 != UNLINK (filename)) - LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); + GNUNET_DISK_file_backup (filename); return NULL; } @@ -662,8 +661,7 @@ try_read_key (const char *filename) filename, (unsigned long long) fs); GNUNET_break (GNUNET_OK == GNUNET_DISK_file_close (fd)); - if (0 != UNLINK (filename)) - LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); + GNUNET_DISK_file_backup (filename); GNUNET_free (enc); return NULL; } @@ -857,10 +855,7 @@ GNUNET_CRYPTO_rsa_key_create_from_file (const char *filename) LOG (GNUNET_ERROR_TYPE_ERROR, _("File `%s' does not contain a valid private key. Deleting it.\n"), filename); - if (0 != UNLINK (filename)) - { - LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "unlink", filename); - } + GNUNET_DISK_file_backup (filename); } GNUNET_free (enc); if (GNUNET_YES != diff --git a/src/util/disk.c b/src/util/disk.c index 8d1fed897e..8cb69d2a4e 100644 --- a/src/util/disk.c +++ b/src/util/disk.c @@ -495,6 +495,38 @@ GNUNET_DISK_mkdtemp (const char *t) /** + * Move a file out of the way (create a backup) by + * renaming it to "orig.NUM~" where NUM is the smallest + * number that is not used yet. + * + * @param fil name of the file to back up + */ +void +GNUNET_DISK_file_backup (const char *fil) +{ + size_t slen; + char *target; + unsigned int num; + + slen = strlen (fil) + 20; + target = GNUNET_malloc (slen); + num = 0; + do + { + GNUNET_snprintf (target, slen, + "%s.%u~", + fil, + num++); + } while (0 == access (target, F_OK)); + if (0 != rename (fil, target)) + GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR, + "rename", + fil); + GNUNET_free (target); +} + + +/** * Create an (empty) temporary file on disk. If the given name is not * an absolute path, the current 'TMPDIR' will be prepended. In any case, * 6 random characters will be appended to the name to create a unique |