- doc
[oweals/gnunet.git] / src / util / disk.c
index ae9135b0c6664be7788879c03609067b6460fbf6..5cd85b67b3da3cabf98f8dbfb3348a51e3bd7e76 100644 (file)
@@ -436,12 +436,14 @@ mktemp_name (const char *t)
   return fn;
 }
 
+
 #if WINDOWS
 static char *
 mkdtemp (char *fn)
 {
   char *random_fn;
   char *tfn;
+
   while (1)
   {
     tfn = GNUNET_strdup (fn);
@@ -494,6 +496,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,
@@ -584,19 +618,19 @@ GNUNET_DISK_get_blocks_available (const char *part)
 
 
 /**
- * Test if "fil" is a directory and readable. Also check if the directory is
- * listable.  Will not print an error message if the directory does not exist.
- * Will log errors if GNUNET_SYSERR is returned (i.e., a file exists with the
- * same name).
+ * Test if "fil" is a directory and listable. Optionally, also check if the
+ * directory is readable.  Will not print an error message if the directory does
+ * not exist.  Will log errors if GNUNET_SYSERR is returned (i.e., a file exists
+ * with the same name).
  *
  * @param fil filename to test
- * @param is_listable GNUNET_YES to additionally check if "fil" is listable;
+ * @param is_readable GNUNET_YES to additionally check if "fil" is readable;
  *          GNUNET_NO to disable this check
  * @return GNUNET_YES if yes, GNUNET_NO if not; GNUNET_SYSERR if it
- *           does not exist
+ *           does not exist or stat'ed
  */
 int
-GNUNET_DISK_directory_test (const char *fil, int is_listable)
+GNUNET_DISK_directory_test (const char *fil, int is_readable)
 {
   struct stat filestat;
   int ret;
@@ -605,22 +639,23 @@ GNUNET_DISK_directory_test (const char *fil, int is_listable)
   if (ret != 0)
   {
     if (errno != ENOENT)
-    {
       LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "stat", fil);
-      return GNUNET_SYSERR;
-    }
-    return GNUNET_NO;
+    return GNUNET_SYSERR;
   }
   if (!S_ISDIR (filestat.st_mode))
+  {
+    LOG (GNUNET_ERROR_TYPE_WARNING,
+         "A file already exits with the same name %s\n", fil);
     return GNUNET_NO;
-  if (GNUNET_YES == is_listable)
+  }
+  if (GNUNET_YES == is_readable)
     ret = ACCESS (fil, R_OK | X_OK);
   else
-    ret = ACCESS (fil, R_OK);
+    ret = ACCESS (fil, X_OK);
   if (ret < 0)
   {
     LOG_STRERROR_FILE (GNUNET_ERROR_TYPE_WARNING, "access", fil);
-    return GNUNET_SYSERR;
+    return GNUNET_NO;
   }
   return GNUNET_YES;
 }
@@ -722,8 +757,8 @@ GNUNET_DISK_directory_create (const char *dir)
     if (DIR_SEPARATOR == rdir[pos2])
     {
       rdir[pos2] = '\0';
-      ret = GNUNET_DISK_directory_test (rdir, GNUNET_YES);
-      if (GNUNET_SYSERR == ret)
+      ret = GNUNET_DISK_directory_test (rdir, GNUNET_NO);
+      if (GNUNET_NO == ret)
       {
         GNUNET_free (rdir);
         return GNUNET_SYSERR;
@@ -746,13 +781,13 @@ GNUNET_DISK_directory_create (const char *dir)
     if ((rdir[pos] == DIR_SEPARATOR) || (pos == len))
     {
       rdir[pos] = '\0';
-      ret = GNUNET_DISK_directory_test (rdir, GNUNET_YES);
-      if (ret == GNUNET_SYSERR)
+      ret = GNUNET_DISK_directory_test (rdir, GNUNET_NO);
+      if (GNUNET_NO == ret)
       {
         GNUNET_free (rdir);
         return GNUNET_SYSERR;
       }
-      if (ret == GNUNET_NO)
+      if (GNUNET_SYSERR == ret)
       {
 #ifndef MINGW
         ret = mkdir (rdir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);        /* 755 */
@@ -2128,7 +2163,8 @@ create_selectable_pipe (PHANDLE read_pipe_ptr, PHANDLE write_pipe_ptr,
   /* Default to error. */
   *read_pipe_ptr = *write_pipe_ptr = INVALID_HANDLE_VALUE;
 
-  HANDLE read_pipe = INVALID_HANDLE_VALUE, write_pipe = INVALID_HANDLE_VALUE;
+  HANDLE read_pipe;
+  HANDLE write_pipe;
 
   /* Ensure that there is enough pipe buffer space for atomic writes.  */
   if (psize < PIPE_BUF)