aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/gnunet_disk_lib.h171
-rw-r--r--src/util/crypto_rsa.c13
-rw-r--r--src/util/disk.c32
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