Fixed yesterday's W32 fix.
[gnupg.git] / g10 / keydb.c
index 5c7e2ed..3360f63 100644 (file)
@@ -1,11 +1,12 @@
 /* keydb.c - key database dispatcher
- * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2003, 2004, 2005, 
+ *               2008 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
  * GnuPG is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * GnuPG is distributed in the hope that it will be useful,
@@ -14,9 +15,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #include <config.h>
@@ -29,6 +28,7 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#include "gpg.h"
 #include "util.h"
 #include "options.h"
 #include "main.h" /*try_make_homedir ()*/
@@ -83,6 +83,7 @@ maybe_create_keyring (char *filename, int force)
   int rc;
   mode_t oldmask;
   char *last_slash_in_filename;
+  int save_slash;
 
   /* A quick test whether the filename already exists. */
   if (!access (filename, F_OK))
@@ -91,7 +92,7 @@ maybe_create_keyring (char *filename, int force)
   /* If we don't want to create a new file at all, there is no need to
      go any further - bail out right here.  */
   if (!force) 
-    return G10ERR_OPEN_FILE;
+    return gpg_error (GPG_ERR_ENOENT);
 
   /* First of all we try to create the home directory.  Note, that we
      don't do any locking here because any sane application of gpg
@@ -99,6 +100,18 @@ maybe_create_keyring (char *filename, int force)
      tricky auto-creation which is anyway only done for some home
      directory name patterns. */
   last_slash_in_filename = strrchr (filename, DIRSEP_C);
+#if HAVE_W32_SYSTEM
+  {
+    /* Windows may either have a slash or a backslash.  Take care of it.  */
+    char *p = strrchr (filename, '/');
+    if (!last_slash_in_filename || p > last_slash_in_filename)
+      last_slash_in_filename = p;
+  }
+#endif /*HAVE_W32_SYSTEM*/
+  if (!last_slash_in_filename)
+    return gpg_error (GPG_ERR_ENOENT);  /* No slash at all - should
+                                           not happen though.  */
+  save_slash = *last_slash_in_filename;
   *last_slash_in_filename = 0;
   if (access(filename, F_OK))
     { 
@@ -111,13 +124,12 @@ maybe_create_keyring (char *filename, int force)
         }
       if (access (filename, F_OK))
         {
-          rc = G10ERR_OPEN_FILE;
-          *last_slash_in_filename = DIRSEP_C;
+          rc = gpg_error_from_syserror ();
+          *last_slash_in_filename = save_slash;
           goto leave;
         }
     }
-  *last_slash_in_filename = DIRSEP_C;
-
+  *last_slash_in_filename = save_slash;
 
   /* To avoid races with other instances of gpg trying to create or
      update the keyring (it is removed during an update for a short
@@ -133,9 +145,9 @@ maybe_create_keyring (char *filename, int force)
         log_info ("can't allocate lock for `%s'\n", filename );
 
       if (!force) 
-        return G10ERR_OPEN_FILE
+        return gpg_error (GPG_ERR_ENOENT)
       else
-        return G10ERR_GENERAL;
+        return gpg_error (GPG_ERR_GENERAL);
     }
 
   if ( make_dotlock (lockhd, -1) )
@@ -165,9 +177,9 @@ maybe_create_keyring (char *filename, int force)
   umask (oldmask);
   if (!iobuf) 
     {
+      rc = gpg_error_from_syserror ();
       log_error ( _("error creating keyring `%s': %s\n"),
                   filename, strerror(errno));
-      rc = G10ERR_OPEN_FILE;
       goto leave;
     }
 
@@ -235,7 +247,7 @@ keydb_add_resource (const char *url, int flags, int secret)
            filename = make_filename (opt.homedir, resname, NULL);
     }
     else
-       filename = m_strdup (resname);
+       filename = xstrdup (resname);
 
     if (!force)
        force = secret? !any_secret : !any_public;
@@ -323,7 +335,7 @@ keydb_add_resource (const char *url, int flags, int secret)
        any_secret = 1;
     else
        any_public = 1;
-    m_free (filename);
+    xfree (filename);
     return rc;
 }
 
@@ -336,7 +348,7 @@ keydb_new (int secret)
   KEYDB_HANDLE hd;
   int i, j;
   
-  hd = m_alloc_clear (sizeof *hd);
+  hd = xmalloc_clear (sizeof *hd);
   hd->found = -1;
   
   assert (used_resources <= MAX_KEYDB_RESOURCES);
@@ -354,7 +366,7 @@ keydb_new (int secret)
           hd->active[j].secret = all_resources[i].secret;
           hd->active[j].u.kr = keyring_new (all_resources[i].token, secret);
           if (!hd->active[j].u.kr) {
-            m_free (hd);
+            xfree (hd);
             return NULL; /* fixme: release all previously allocated handles*/
           }
           j++;
@@ -388,7 +400,7 @@ keydb_release (KEYDB_HANDLE hd)
         }
     }
 
-    m_free (hd);
+    xfree (hd);
 }