Remove use of gnulib (part 2)
authorWerner Koch <wk@gnupg.org>
Tue, 11 Nov 2014 14:14:31 +0000 (15:14 +0100)
committerWerner Koch <wk@gnupg.org>
Tue, 11 Nov 2014 14:14:31 +0000 (15:14 +0100)
* configure.ac (strpbrk): Add to AC_CHECK_FUNCS.
(gl_EARLY): Remove.
* common/stringhelp.c (strpbrk) [!HAVE_STRPBRK]: New.
* common/sysutils.c (gnupg_mkdtemp): New.  Based on code from
glibc-2.6.
(gnupg_setenv): Rewrite.
(gnupg_unsetenv): Rewrite.
* g10/exec.c: Include sysutils.h and replace mkdtemp by gnupg_mkdtemp.
* g13/be-encfs.c: Ditto.
* g13/mount.c: Ditto.
* tools/symcryptrun.c (confucius_mktmpdir): Ditto.

Signed-off-by: Werner Koch <wk@gnupg.org>
common/stringhelp.c
common/stringhelp.h
common/sysutils.c
common/sysutils.h
common/t-sysutils.c
configure.ac
g10/exec.c
g13/be-encfs.c
g13/mount.c
tools/symcryptrun.c

index e1ddf2c..7ce041d 100644 (file)
@@ -1035,6 +1035,26 @@ stpcpy(char *a,const char *b)
 }
 #endif
 
 }
 #endif
 
+#ifndef HAVE_STRPBRK
+/* Find the first occurrence in S of any character in ACCEPT.
+   Code taken from glibc-2.6/string/strpbrk.c (LGPLv2.1+) and modified. */
+char *
+strpbrk (const char *s, const char *accept)
+{
+  while (*s != '\0')
+    {
+      const char *a = accept;
+      while (*a != '\0')
+       if (*a++ == *s)
+         return (char *) s;
+      ++s;
+    }
+
+  return NULL;
+}
+#endif /*!HAVE_STRPBRK*/
+
+
 #ifndef HAVE_STRSEP
 /* Code taken from glibc-2.2.1/sysdeps/generic/strsep.c. */
 char *
 #ifndef HAVE_STRSEP
 /* Code taken from glibc-2.2.1/sysdeps/generic/strsep.c. */
 char *
index 1ad380e..1d3ee72 100644 (file)
@@ -99,6 +99,9 @@ int memicmp( const char *a, const char *b, size_t n );
 #ifndef HAVE_STPCPY
 char *stpcpy(char *a,const char *b);
 #endif
 #ifndef HAVE_STPCPY
 char *stpcpy(char *a,const char *b);
 #endif
+#ifndef HAVE_STRPBRK
+char *strpbrk (const char *s, const char *accept);
+#endif
 #ifndef HAVE_STRSEP
 char *strsep (char **stringp, const char *delim);
 #endif
 #ifndef HAVE_STRSEP
 char *strsep (char **stringp, const char *delim);
 #endif
index 858cb65..3971845 100644 (file)
@@ -1,7 +1,7 @@
 /* sysutils.c -  system helpers
 /* sysutils.c -  system helpers
- * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004,
- *               2007, 2008  Free Software Foundation, Inc.
- * Copyright (C) 2013 Werner Koch
+ * Copyright (C) 1991-2001, 2003-2004,
+ *               2006-2008  Free Software Foundation, Inc.
+ * Copyright (C) 2013-2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
  *
  * This file is part of GnuPG.
  *
@@ -38,6 +38,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <string.h>
 #include <unistd.h>
 #include <errno.h>
 #include <string.h>
 #include <unistd.h>
 #include <errno.h>
@@ -617,6 +618,90 @@ gnupg_mkdir (const char *name, const char *modestr)
 }
 
 
 }
 
 
+/* Our version of mkdtemp.  The API is identical to POSIX.1-2008
+   version.  We do not use a system provided mkdtemp because we have a
+   good RNG instantly available and this way we don't have diverging
+   versions.  */
+char *
+gnupg_mkdtemp (char *tmpl)
+{
+  /* A lower bound on the number of temporary files to attempt to
+     generate.  The maximum total number of temporary file names that
+     can exist for a given template is 62**6 (5*36**3 for Windows).
+     It should never be necessary to try all these combinations.
+     Instead if a reasonable number of names is tried (we define
+     reasonable as 62**3 or 5*36**3) fail to give the system
+     administrator the chance to remove the problems.  */
+#ifdef HAVE_W32_SYSTEM
+  static const char letters[] =
+    "abcdefghijklmnopqrstuvwxyz0123456789";
+# define NUMBER_OF_LETTERS 36
+# define ATTEMPTS_MIN (5 * 36 * 36 * 36)
+#else
+  static const char letters[] =
+    "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+# define NUMBER_OF_LETTERS 62
+# define ATTEMPTS_MIN (62 * 62 * 62)
+#endif
+  int len;
+  char *XXXXXX;
+  uint64_t value;
+  unsigned int count;
+  int save_errno = errno;
+  /* The number of times to attempt to generate a temporary file.  To
+     conform to POSIX, this must be no smaller than TMP_MAX.  */
+#if ATTEMPTS_MIN < TMP_MAX
+  unsigned int attempts = TMP_MAX;
+#else
+  unsigned int attempts = ATTEMPTS_MIN;
+#endif
+
+  len = strlen (tmpl);
+  if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
+    {
+      gpg_err_set_errno (EINVAL);
+      return NULL;
+    }
+
+  /* This is where the Xs start.  */
+  XXXXXX = &tmpl[len - 6];
+
+  /* Get a random start value.  */
+  gcry_create_nonce (&value, sizeof value);
+
+  /* Loop until a directory was created.  */
+  for (count = 0; count < attempts; value += 7777, ++count)
+    {
+      uint64_t v = value;
+
+      /* Fill in the random bits.  */
+      XXXXXX[0] = letters[v % NUMBER_OF_LETTERS];
+      v /= NUMBER_OF_LETTERS;
+      XXXXXX[1] = letters[v % NUMBER_OF_LETTERS];
+      v /= NUMBER_OF_LETTERS;
+      XXXXXX[2] = letters[v % NUMBER_OF_LETTERS];
+      v /= NUMBER_OF_LETTERS;
+      XXXXXX[3] = letters[v % NUMBER_OF_LETTERS];
+      v /= NUMBER_OF_LETTERS;
+      XXXXXX[4] = letters[v % NUMBER_OF_LETTERS];
+      v /= NUMBER_OF_LETTERS;
+      XXXXXX[5] = letters[v % NUMBER_OF_LETTERS];
+
+      if (!gnupg_mkdir (tmpl, "-rwx"))
+        {
+          gpg_err_set_errno (save_errno);
+          return tmpl;
+        }
+      if (errno != EEXIST)
+       return NULL;
+    }
+
+  /* We got out of the loop because we ran out of combinations to try.  */
+  gpg_err_set_errno (EEXIST);
+  return NULL;
+}
+
+
 int
 gnupg_setenv (const char *name, const char *value, int overwrite)
 {
 int
 gnupg_setenv (const char *name, const char *value, int overwrite)
 {
@@ -625,23 +710,72 @@ gnupg_setenv (const char *name, const char *value, int overwrite)
   (void)value;
   (void)overwrite;
   return 0;
   (void)value;
   (void)overwrite;
   return 0;
-#else
+#elif defined(HAVE_W32_SYSTEM)
+  if (!overwrite)
+    {
+      char tmpbuf[10];
+      if (GetEnvironmentVariable (name, tmpbuf, sizeof tmpbuf))
+        return 0; /* Exists but overwrite was not requested.  */
+    }
+  if (!SetEnvironmentVariable (name, value))
+    {
+      gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
+      return -1;
+    }
+  return 0;
+#elif defined(HAVE_SETENV)
   return setenv (name, value, overwrite);
   return setenv (name, value, overwrite);
+#else
+  char *buf;
+
+  (void)overwrite;
+  if (!name || !value)
+    {
+      gpg_err_set_errno (EINVAL);
+      return -1;
+    }
+  buf = xtrymalloc (strlen (name) + 1 + strlen (value) + 1);
+  if (!buf)
+    return -1;
+  strcpy (stpcpy (stpcpy (buf, name), "="), value);
+#if __GNUC__
+# warning no setenv - using putenv but leaking memory.
+#endif
+  return putenv (buf);
 #endif
 }
 
 #endif
 }
 
+
 int
 gnupg_unsetenv (const char *name)
 {
 #ifdef HAVE_W32CE_SYSTEM
   (void)name;
   return 0;
 int
 gnupg_unsetenv (const char *name)
 {
 #ifdef HAVE_W32CE_SYSTEM
   (void)name;
   return 0;
-#else
-# ifdef HAVE_UNSETENV
+#elif defined(HAVE_W32_SYSTEM)
+  if (!SetEnvironmentVariable (name, NULL))
+    {
+      gpg_err_set_errno (EINVAL); /* (Might also be ENOMEM.) */
+      return -1;
+    }
+  return 0;
+#elif defined(HAVE_UNSETENV)
   return unsetenv (name);
   return unsetenv (name);
-# else
-  return putenv (name);
-# endif
+#else
+  char *buf;
+
+  if (!name)
+    {
+      gpg_err_set_errno (EINVAL);
+      return -1;
+    }
+  buf = xtrystrdup (name);
+  if (!buf)
+    return -1;
+#if __GNUC__
+# warning no unsetenv - trying putenv but leaking memory.
+#endif
+  return putenv (buf);
 #endif
 }
 
 #endif
 }
 
index d139665..95276de 100644 (file)
@@ -61,6 +61,7 @@ void gnupg_reopen_std (const char *pgmname);
 void gnupg_allow_set_foregound_window (pid_t pid);
 int  gnupg_remove (const char *fname);
 int  gnupg_mkdir (const char *name, const char *modestr);
 void gnupg_allow_set_foregound_window (pid_t pid);
 int  gnupg_remove (const char *fname);
 int  gnupg_mkdir (const char *name, const char *modestr);
+char *gnupg_mkdtemp (char *template);
 int  gnupg_setenv (const char *name, const char *value, int overwrite);
 int  gnupg_unsetenv (const char *name);
 char *gnupg_getcwd (void);
 int  gnupg_setenv (const char *name, const char *value, int overwrite);
 int  gnupg_unsetenv (const char *name);
 char *gnupg_getcwd (void);
index d13bdfe..68c3e41 100644 (file)
@@ -83,6 +83,7 @@ main (int argc, char **argv)
     verbose = 1;
 
   test_gnupg_tmpfile ();
     verbose = 1;
 
   test_gnupg_tmpfile ();
+  /* Fixme: Add tests for setenv and unsetenv.  */
 
   return !!errcount;
 }
 
   return !!errcount;
 }
index 203f29b..f59c117 100644 (file)
@@ -577,7 +577,6 @@ AC_CHECK_TOOL(AR, ar, :)
 AC_PATH_PROG(PERL,"perl")
 AC_CHECK_TOOL(WINDRES, windres, :)
 AC_ISC_POSIX
 AC_PATH_PROG(PERL,"perl")
 AC_CHECK_TOOL(WINDRES, windres, :)
 AC_ISC_POSIX
-gl_EARLY
 AC_SYS_LARGEFILE
 GNUPG_CHECK_USTAR
 
 AC_SYS_LARGEFILE
 GNUPG_CHECK_USTAR
 
@@ -1293,7 +1292,7 @@ AC_CHECK_HEADERS([signal.h])
 AC_CHECK_FUNCS([memicmp stpcpy strsep strlwr strtoul memmove stricmp strtol \
                 memrchr isascii timegm getrusage setrlimit stat setlocale   \
                 flockfile funlockfile fopencookie funopen getpwnam getpwuid \
 AC_CHECK_FUNCS([memicmp stpcpy strsep strlwr strtoul memmove stricmp strtol \
                 memrchr isascii timegm getrusage setrlimit stat setlocale   \
                 flockfile funlockfile fopencookie funopen getpwnam getpwuid \
-                getenv inet_pton])
+                getenv inet_pton strpbrk])
 # end jnlib checks.
 
 
 # end jnlib checks.
 
 
index 5bcfc2e..0194e9d 100644 (file)
@@ -49,6 +49,7 @@
 #include "iobuf.h"
 #include "util.h"
 #include "membuf.h"
 #include "iobuf.h"
 #include "util.h"
 #include "membuf.h"
+#include "sysutils.h"
 #include "exec.h"
 
 #ifdef NO_EXEC
 #include "exec.h"
 
 #ifdef NO_EXEC
@@ -194,7 +195,7 @@ make_tempdir(struct exec_info *info)
   xfree(tmp);
 #endif
 
   xfree(tmp);
 #endif
 
-  if(mkdtemp(info->tempdir)==NULL)
+  if (!gnupg_mkdtemp(info->tempdir))
     log_error(_("can't create directory '%s': %s\n"),
              info->tempdir,strerror(errno));
   else
     log_error(_("can't create directory '%s': %s\n"),
              info->tempdir,strerror(errno));
   else
index 265b4c2..f59f4d9 100644 (file)
@@ -30,6 +30,7 @@
 #include "keyblob.h"
 #include "be-encfs.h"
 #include "runner.h"
 #include "keyblob.h"
 #include "be-encfs.h"
 #include "runner.h"
+#include "../common/sysutils.h"
 #include "../common/exechelp.h"
 
 
 #include "../common/exechelp.h"
 
 
@@ -415,7 +416,7 @@ be_encfs_create_container (ctrl_t ctrl, const char *fname, tupledesc_t tuples,
       err = gpg_error_from_syserror ();
       goto leave;
     }
       err = gpg_error_from_syserror ();
       goto leave;
     }
-  if (!mkdtemp (mountpoint))
+  if (!gnupg_mkdtemp (mountpoint))
     {
       err = gpg_error_from_syserror ();
       log_error (_("can't create directory '%s': %s\n"),
     {
       err = gpg_error_from_syserror ();
       log_error (_("can't create directory '%s': %s\n"),
index 512e29d..fc640e0 100644 (file)
@@ -33,6 +33,7 @@
 #include "keyblob.h"
 #include "backend.h"
 #include "utils.h"
 #include "keyblob.h"
 #include "backend.h"
 #include "utils.h"
+#include "../common/sysutils.h"
 #include "call-gpg.h"
 #include "mountinfo.h"
 #include "runner.h"
 #include "call-gpg.h"
 #include "mountinfo.h"
 #include "runner.h"
@@ -260,7 +261,7 @@ g13_mount_container (ctrl_t ctrl, const char *filename, const char *mountpoint)
       mountpoint_buffer = xtrystrdup ("/tmp/g13-XXXXXX");
       if (!mountpoint_buffer)
         return gpg_error_from_syserror ();
       mountpoint_buffer = xtrystrdup ("/tmp/g13-XXXXXX");
       if (!mountpoint_buffer)
         return gpg_error_from_syserror ();
-      if (!mkdtemp (mountpoint_buffer))
+      if (!gnupg_mkdtemp (mountpoint_buffer))
         {
           err = gpg_error_from_syserror ();
           log_error (_("can't create directory '%s': %s\n"),
         {
           err = gpg_error_from_syserror ();
           log_error (_("can't create directory '%s': %s\n"),
index 48562b1..4873d76 100644 (file)
@@ -90,6 +90,7 @@
 #include "i18n.h"
 #include "../common/util.h"
 #include "../common/init.h"
 #include "i18n.h"
 #include "../common/util.h"
 #include "../common/init.h"
+#include "../common/sysutils.h"
 
 /* FIXME: Bah.  For spwq_secure_free.  */
 #define SIMPLE_PWQUERY_IMPLEMENTATION 1
 
 /* FIXME: Bah.  For spwq_secure_free.  */
 #define SIMPLE_PWQUERY_IMPLEMENTATION 1
@@ -315,7 +316,7 @@ confucius_mktmpdir (void)
     name = xstrconcat (p, "gpg-XXXXXX", NULL);
   else
     name = xstrconcat (p, "/", "gpg-XXXXXX", NULL);
     name = xstrconcat (p, "gpg-XXXXXX", NULL);
   else
     name = xstrconcat (p, "/", "gpg-XXXXXX", NULL);
-  if (!name || !mkdtemp (name))
+  if (!name || !gnupg_mkdtemp (name))
     {
       log_error (_("can't create temporary directory '%s': %s\n"),
                  name?name:"", strerror (errno));
     {
       log_error (_("can't create temporary directory '%s': %s\n"),
                  name?name:"", strerror (errno));