Improved detection of ketrings specified several times.
authorWerner Koch <wk@gnupg.org>
Fri, 24 Aug 2007 09:51:58 +0000 (09:51 +0000)
committerWerner Koch <wk@gnupg.org>
Fri, 24 Aug 2007 09:51:58 +0000 (09:51 +0000)
NEWS
g10/ChangeLog
g10/keyring.c
include/ChangeLog
include/util.h
po/de.glo
util/ChangeLog
util/fileutil.c

diff --git a/NEWS b/NEWS
index 71af4f5..31c3b12 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,8 +3,9 @@ Noteworthy changes in version 1.4.8 (unreleased)
     
     * Changed the license to GPLv3.
 
+    * Improved detection of keyrings specified multiple times.
+
     * Minor bug fixes.
-    
 
 Noteworthy changes in version 1.4.7 (2007-03-05)
 ------------------------------------------------
index 713dab4..804d2fc 100644 (file)
@@ -1,3 +1,8 @@
+2007-08-24  Werner Koch  <wk@g10code.com>
+
+       * keyring.c (keyring_register_filename): Use same_file_p.
+       Suggested by Kurt Fitzner.
+
 2007-07-19  David Shaw  <dshaw@jabberwocky.com>
 
        * gpg.c (main): Fix typo.  Noted by John Clizbe.
index 9ef5b1b..5d10731 100644 (file)
@@ -207,7 +207,7 @@ keyring_register_filename (const char *fname, int secret, void **ptr)
 
     for (kr=kr_names; kr; kr = kr->next)
       {
-        if ( !compare_filenames (kr->fname, fname) )
+        if (same_file_p (kr->fname, fname) )
          {
             *ptr=kr;
            return 0; /* already registered */
index 0fbabad..8a96d50 100644 (file)
@@ -1,3 +1,7 @@
+2007-08-24  Werner Koch  <wk@g10code.com>
+
+       * util.h (same_file_p): Add prototype.
+
 2007-06-13  David Shaw  <dshaw@jabberwocky.com>
 
        * cipher.h (CIPHER_ALGO_CAMELLIA): Add Camellia define.
index 6269bd5..8c48e8c 100644 (file)
@@ -143,6 +143,7 @@ char * make_basename(const char *filepath, const char *inputpath);
 char * make_dirname(const char *filepath);
 char *make_filename( const char *first_part, ... );
 int compare_filenames( const char *a, const char *b );
+int same_file_p (const char *name1, const char *name2);
 const char *print_fname_stdin( const char *s );
 const char *print_fname_stdout( const char *s );
 int is_file_compressed(const char *s, int *r_status);
index 7e32f93..46716bc 100644 (file)
--- a/po/de.glo
+++ b/po/de.glo
@@ -143,7 +143,7 @@ ownertrust                  \"Owner trust\"  *Vertrauensw
 packet                 Paket
 packet type            Pakettyp
 parse                  -zerlegen
-passphrase             Mantra
+passphrase             Passphrase  -# Mantra
 permission [file]       Zugriffsrechte
 Photo-ID                Foto-ID
 policy                 Richtlinie
index f6a916f..189ab6d 100644 (file)
@@ -1,3 +1,9 @@
+2007-08-24  Werner Koch  <wk@g10code.com>
+
+       * fileutil.c (same_file_p): New.  Taken from SVN trunk.
+       (compare_filenames) [HAVE_DRIVE_LETTERS]: Take drive letters and
+       backslashes in account.
+
 2007-04-16  David Shaw  <dshaw@jabberwocky.com>
 
        * strgutil.c (ascii_toupper, ascii_tolower, ascii_strcasecmp,
index 5834e3d..dc27221 100644 (file)
@@ -1,5 +1,5 @@
 /* fileutil.c -  file utilities
- * Copyright (C) 1998, 2003, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 2003, 2005, 2007 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
 #ifdef HAVE_PWD_H
 #include <pwd.h>
 #endif
+#include <ctype.h>
+#ifdef HAVE_W32_SYSTEM
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#else /*!HAVE_W32_SYSTEM*/
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <unistd.h>
+#endif /*!HAVE_W32_SYSTEM*/
+
+
 #include "util.h"
 #include "memory.h"
 #include "ttyio.h"
@@ -194,32 +205,87 @@ make_filename( const char *first_part, ... )
 }
 
 
+/* Compare whether the filenames are identical.  This is a
+   special version of strcmp() taking the semantics of filenames in
+   account.  Note that this function works only on the supplied names
+   without considereing any context like the current directory.  See
+   also same_file_p(). */
 int
-compare_filenames( const char *a, const char *b )
+compare_filenames (const char *a, const char *b)
 {
-    /* ? check whether this is an absolute filename and
-     * resolve symlinks?
-     */
-#ifndef __riscos__
-#ifdef HAVE_DRIVE_LETTERS
-    return ascii_strcasecmp(a,b);
-#else
-    return strcmp(a,b);
+#ifdef __riscos__
+  int c = 0;
+  char *abuf, *bbuf;
+  
+  abuf = riscos_gstrans(a);
+  bbuf = riscos_gstrans(b);
+  c = ascii_strcasecmp (abuf, bbuf);
+  xfree(abuf);
+  xfree(bbuf);
+  
+  return c;
+#elif defined (HAVE_DRIVE_LETTERS)
+  for ( ; *a && *b; a++, b++ ) 
+    {
+      if (*a != *b 
+          && (toupper (*(const unsigned char*)a)
+              != toupper (*(const unsigned char*)b) )
+          && !((*a == '/' && *b == '\\') || (*a == '\\' && *b == '/')))
+        break;
+    }
+  if ((*a == '/' && *b == '\\') || (*a == '\\' && *b == '/'))
+    return 0;
+  else
+    return (toupper (*(const unsigned char*)a) 
+            - toupper (*(const unsigned char*)b));
+#else /*!HAVE_DRIVE_LETTERS*/
+  return strcmp (a,b);
 #endif
-#else /* __riscos__ */
-    int c = 0;
-    char *abuf, *bbuf;
-
-    abuf = riscos_gstrans(a);
-    bbuf = riscos_gstrans(b);
-
-    c = ascii_strcasecmp (abuf, bbuf);
-
-    xfree(abuf);
-    xfree(bbuf);
+}
 
-    return c;
-#endif /* __riscos__ */
+/* Check whether the files NAME1 and NAME2 are identical.  This is for
+   example achieved by comparing the inode numbers of the files.  */
+int
+same_file_p (const char *name1, const char *name2)
+{
+  int yes;
+      
+  /* First try a shortcut.  */
+  if (!compare_filenames (name1, name2))
+    yes = 1;
+  else
+    {
+#ifdef HAVE_W32_SYSTEM  
+      HANDLE file1, file2;
+      BY_HANDLE_FILE_INFORMATION info1, info2;
+      
+      file1 = CreateFile (name1, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
+      if (file1 == INVALID_HANDLE_VALUE)
+        yes = 0; /* If we can't open the file, it is not the same.  */
+      else
+        {
+          file2 = CreateFile (name2, 0, 0, NULL, OPEN_EXISTING, 0, NULL);
+          if (file1 == INVALID_HANDLE_VALUE)
+            yes = 0; /* If we can't open the file, it is not the same.  */
+          else
+            {
+              yes = (GetFileInformationByHandle (file1, &info1)
+                     && GetFileInformationByHandle (file2, &info2)
+                     && info1.dwVolumeSerialNumber==info2.dwVolumeSerialNumber
+                     && info1.nFileIndexHigh == info2.nFileIndexHigh
+                     && info1.nFileIndexLow == info2.nFileIndexLow);
+              CloseHandle (file2);
+            }
+          CloseHandle (file1);
+        }
+#else /*!HAVE_W32_SYSTEM*/
+      struct stat info1, info2;
+      
+      yes = (!stat (name1, &info1) && !stat (name2, &info2)
+             && info1.st_dev == info2.st_dev && info1.st_ino == info2.st_ino);
+#endif /*!HAVE_W32_SYSTEM*/
+    }
+  return yes;
 }