kbx: Add function keybox_tmp_names to avoid code duplication.
authorWerner Koch <wk@gnupg.org>
Thu, 14 Jan 2016 15:29:45 +0000 (16:29 +0100)
committerWerner Koch <wk@gnupg.org>
Thu, 14 Jan 2016 15:47:42 +0000 (16:47 +0100)
* kbx/keybox-update.c (create_tmp_file): Move some code to...
* kbx/keybox-util.c (keybox_tmp_names): new.
* g10/keyring.c: Include keybox.h.
(create_tmp_file): Replace parts by keybox_tmp_names.
--

Signed-off-by: Werner Koch <wk@gnupg.org>
g10/keyring.c
kbx/keybox-update.c
kbx/keybox-util.c
kbx/keybox.h

index a0b7a0e..535dd2b 100644 (file)
@@ -36,6 +36,8 @@
 #include "options.h"
 #include "main.h" /*for check_key_signature()*/
 #include "i18n.h"
+#include "../kbx/keybox.h"
+
 
 typedef struct keyring_resource *KR_RESOURCE;
 struct keyring_resource
@@ -1287,69 +1289,36 @@ static int
 create_tmp_file (const char *template,
                  char **r_bakfname, char **r_tmpfname, IOBUF *r_fp)
 {
-  char *bakfname, *tmpfname;
+  gpg_error_t err;
   mode_t oldmask;
 
-  *r_bakfname = NULL;
-  *r_tmpfname = NULL;
-
-# ifdef USE_ONLY_8DOT3
-  /* Here is another Windoze bug?:
-   * you can't rename("pubring.gpg.tmp", "pubring.gpg");
-   * but       rename("pubring.gpg.tmp", "pubring.aaa");
-   * works.  So we replace .gpg by .bak or .tmp
-   */
-  if (strlen (template) > 4
-      && !strcmp (template+strlen(template)-4, EXTSEP_S GPGEXT_GPG) )
-    {
-      bakfname = xmalloc (strlen (template) + 1);
-      strcpy (bakfname, template);
-      strcpy (bakfname+strlen(template)-4, EXTSEP_S "bak");
+  err = keybox_tmp_names (template, 1, r_bakfname, r_tmpfname);
+  if (err)
+    return err;
 
-      tmpfname = xmalloc (strlen( template ) + 1 );
-      strcpy (tmpfname,template);
-      strcpy (tmpfname+strlen(template)-4, EXTSEP_S "tmp");
+  /* Create the temp file with limited access.  Note that the umask
+     call is not anymore needed because iobuf_create now takes care of
+     it.  However, it does not harm and thus we keep it.  */
+  oldmask = umask (077);
+  if (is_secured_filename (*r_tmpfname))
+    {
+      *r_fp = NULL;
+      gpg_err_set_errno (EPERM);
     }
-    else
-      { /* file does not end with gpg; hmmm */
-       bakfname = xmalloc (strlen( template ) + 5);
-       strcpy (stpcpy(bakfname, template), EXTSEP_S "bak");
-
-       tmpfname = xmalloc (strlen( template ) + 5);
-       strcpy (stpcpy(tmpfname, template), EXTSEP_S "tmp");
+  else
+    *r_fp = iobuf_create (*r_tmpfname, 1);
+  umask (oldmask);
+  if (!*r_fp)
+    {
+      err = gpg_error_from_syserror ();
+      log_error (_("can't create '%s': %s\n"), *r_tmpfname, gpg_strerror (err));
+      xfree (*r_tmpfname);
+      *r_tmpfname = NULL;
+      xfree (*r_bakfname);
+      *r_bakfname = NULL;
     }
-# else /* Posix file names */
-    bakfname = xmalloc (strlen( template ) + 2);
-    strcpy (stpcpy (bakfname,template),"~");
-
-    tmpfname = xmalloc (strlen( template ) + 5);
-    strcpy (stpcpy(tmpfname,template), EXTSEP_S "tmp");
-# endif /* Posix filename */
-
-    /* Create the temp file with limited access.  Note that the umask
-       call is not anymore needed because iobuf_create now takes care
-       of it.  However, it does not harm and thus we keep it.  */
-    oldmask=umask(077);
-    if (is_secured_filename (tmpfname))
-      {
-        *r_fp = NULL;
-        gpg_err_set_errno (EPERM);
-      }
-    else
-      *r_fp = iobuf_create (tmpfname, 1);
-    umask(oldmask);
-    if (!*r_fp)
-      {
-        int rc = gpg_error_from_syserror ();
-       log_error(_("can't create '%s': %s\n"), tmpfname, strerror(errno) );
-        xfree (tmpfname);
-        xfree (bakfname);
-       return rc;
-      }
 
-    *r_bakfname = bakfname;
-    *r_tmpfname = tmpfname;
-    return 0;
+  return err;
 }
 
 
index aa80865..eebcfca 100644 (file)
@@ -68,88 +68,27 @@ fseeko (FILE * stream, off_t newpos, int whence)
 #endif /* !defined(HAVE_FSEEKO) && !defined(fseeko) */
 
 
-
 static int
 create_tmp_file (const char *template,
                  char **r_bakfname, char **r_tmpfname, FILE **r_fp)
 {
-  char *bakfname, *tmpfname;
-
-  *r_bakfname = NULL;
-  *r_tmpfname = NULL;
-
-# ifdef USE_ONLY_8DOT3
-  /* Here is another Windoze bug?:
-   * you can't rename("pubring.kbx.tmp", "pubring.kbx");
-   * but       rename("pubring.kbx.tmp", "pubring.aaa");
-   * works.  So we replace ".kbx" by ".kb_" or ".k__".  Note that we
-   * can't use ".bak" and ".tmp", because these suffixes are used by
-   * gpg and would lead to a sharing violation or data corruption.
-   */
-  if (strlen (template) > 4
-      && !strcmp (template+strlen(template)-4, EXTSEP_S "kbx") )
-    {
-      bakfname = xtrymalloc (strlen (template) + 1);
-      if (!bakfname)
-        return gpg_error_from_syserror ();
-      strcpy (bakfname, template);
-      strcpy (bakfname+strlen(template)-4, EXTSEP_S "kb_");
-
-      tmpfname = xtrymalloc (strlen (template) + 1);
-      if (!tmpfname)
-        {
-          gpg_error_t tmperr = gpg_error_from_syserror ();
-          xfree (bakfname);
-          return tmperr;
-        }
-      strcpy (tmpfname,template);
-      strcpy (tmpfname + strlen (template)-4, EXTSEP_S "k__");
-    }
-  else
-    { /* File does not end with kbx, thus we hope we are working on a
-         modern file system and appending a suffix works. */
-      bakfname = xtrymalloc ( strlen (template) + 5);
-      if (!bakfname)
-        return gpg_error_from_syserror ();
-      strcpy (stpcpy (bakfname, template), EXTSEP_S "kb_");
+  gpg_error_t err;
 
-      tmpfname = xtrymalloc ( strlen (template) + 5);
-      if (!tmpfname)
+  err = keybox_tmp_names (template, 0, r_bakfname, r_tmpfname);
+  if (!err)
+    {
+      *r_fp = fopen (*r_tmpfname, "wb");
+      if (!*r_fp)
         {
-          gpg_error_t tmperr = gpg_error_from_syserror ();
-          xfree (bakfname);
-          return tmperr;
+          err = gpg_error_from_syserror ();
+          xfree (*r_tmpfname);
+          *r_tmpfname = NULL;
+          xfree (*r_bakfname);
+          *r_bakfname = NULL;
         }
-      strcpy (stpcpy (tmpfname, template), EXTSEP_S "k__");
-    }
-# else /* Posix file names */
-  bakfname = xtrymalloc (strlen (template) + 2);
-  if (!bakfname)
-    return gpg_error_from_syserror ();
-  strcpy (stpcpy (bakfname,template),"~");
-
-  tmpfname = xtrymalloc ( strlen (template) + 5);
-  if (!tmpfname)
-    {
-      gpg_error_t tmperr = gpg_error_from_syserror ();
-      xfree (bakfname);
-      return tmperr;
     }
-  strcpy (stpcpy (tmpfname,template), EXTSEP_S "tmp");
-# endif /* Posix filename */
 
-  *r_fp = fopen (tmpfname, "wb");
-  if (!*r_fp)
-    {
-      gpg_error_t tmperr = gpg_error_from_syserror ();
-      xfree (tmpfname);
-      xfree (bakfname);
-      return tmperr;
-    }
-
-  *r_bakfname = bakfname;
-  *r_tmpfname = tmpfname;
-  return 0;
+  return err;
 }
 
 
index 9fe9290..f7efd1a 100644 (file)
@@ -68,3 +68,76 @@ _keybox_free (void *p)
   if (p)
     free_func (p);
 }
+
+
+/* Store the two malloced temporary file names used for keybox updates
+   of file FILENAME at R_BAKNAME and R_TMPNAME.  On error an error
+   code is returned and NULL stored at R_BAKNAME and R_TMPNAME.  If
+   FOR_KEYRING is true the returned names match those used by GnuPG's
+   keyring code.  */
+gpg_error_t
+keybox_tmp_names (const char *filename, int for_keyring,
+                  char **r_bakname, char **r_tmpname)
+{
+  gpg_error_t err;
+  char *bak_name, *tmp_name;
+
+  *r_bakname = NULL;
+  *r_tmpname = NULL;
+
+# ifdef USE_ONLY_8DOT3
+  /* Here is another Windoze bug?:
+   * you can't rename("pubring.kbx.tmp", "pubring.kbx");
+   * but       rename("pubring.kbx.tmp", "pubring.aaa");
+   * works.  So we replace ".kbx" by ".kb_" or ".k__".  Note that we
+   * can't use ".bak" and ".tmp", because these suffixes are used by
+   * gpg's keyrings and would lead to a sharing violation or data
+   * corruption.  If the name does not end in ".kbx" we assume working
+   * on a modern file system and append the suffix.  */
+  {
+    const char *ext   = for_keyring? EXTSEP_S GPGEXT_GPG : EXTSEP_S "kbx";
+    const char *b_ext = for_keyring? EXTSEP_S "bak"      : EXTSEP_S "kb_";
+    const char *t_ext = for_keyring? EXTSEP_S "tmp"      : EXTSEP_S "k__";
+    int repl;
+
+    if (strlen (ext) != 4 || strlen (b_ext) != 4)
+      BUG ();
+    repl = (strlen (filename) > 4
+            && !strcmp (filename + strlen (filename) - 4, ext));
+    bak_name = xtrymalloc (strlen (filename) + (repl?0:4) + 1);
+    if (!bak_name)
+      return gpg_error_from_syserror ();
+    strcpy (bak_name, filename);
+    strcpy (bak_name + strlen (filename) - (repl?4:0), b_ext);
+
+    tmp_name = xtrymalloc (strlen (filename) + (repl?0:4) + 1);
+    if (!tmp_name)
+      {
+        err = gpg_error_from_syserror ();
+        xfree (bak_name);
+        return err;
+      }
+    strcpy (tmp_name, filename);
+    strcpy (tmp_name + strlen (filename) - (repl?4:0), t_ext);
+  }
+# else /* Posix file names */
+  (void)for_keyring;
+  bak_name = xtrymalloc (strlen (filename) + 2);
+  if (!bak_name)
+    return gpg_error_from_syserror ();
+  strcpy (stpcpy (bak_name, filename), "~");
+
+  tmp_name = xtrymalloc (strlen (filename) + 5);
+  if (!tmp_name)
+    {
+      err = gpg_error_from_syserror ();
+      xfree (bak_name);
+      return err;
+    }
+  strcpy (stpcpy (tmp_name,filename), EXTSEP_S "tmp");
+# endif /* Posix filename */
+
+  *r_bakname = bak_name;
+  *r_tmpname = tmp_name;
+  return 0;
+}
index 3c60971..4d556c5 100644 (file)
@@ -132,6 +132,9 @@ void keybox_set_malloc_hooks ( void *(*new_alloc_func)(size_t n),
                                void *(*new_realloc_func)(void *p, size_t n),
                                void (*new_free_func)(void*) );
 
+gpg_error_t keybox_tmp_names (const char *filename, int for_keyring,
+                              char **r_bakname, char **r_tmpname);
+
 
 #ifdef __cplusplus
 }