]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Move away from openvpn_basename() over to platform provided basename()
authorDavid Sommerseth <davids@redhat.com>
Wed, 7 Dec 2011 23:40:45 +0000 (00:40 +0100)
committerDavid Sommerseth <davids@redhat.com>
Tue, 10 Jan 2012 18:38:35 +0000 (19:38 +0100)
This kicks out the openvpn_basename() function from misc.[ch] and puts
glibc equivalents into compat.[ch].  This is to provide the same
functionality on platforms not having a native basename() function
available.

In addition this patch adds dirname() which commit 0f2bc0dd92f43c91e
depends.  Without dirname(), openvpn won't build in Visual Studio.

v2: Move all functions from compat.h to compat.c
v3: Use glibc versions of basename() and dirname() instead

Signed-off-by: David Sommerseth <davids@redhat.com>
Acked-by: Alon Bar-Lev <alon.barlev@gmail.com>
URL: http://thread.gmane.org/gmane.network.openvpn.devel/5178/focus=5215

Makefile.am
compat.c [new file with mode: 0644]
compat.h [new file with mode: 0644]
configure.ac
init.c
misc.c
misc.h
options.c
syshead.h

index a47c0c1f2e5f1839c9656e39d40ecd5114045d08..ab86cc18c6f666d500dec1f84552189807461c58 100644 (file)
@@ -84,6 +84,7 @@ openvpn_SOURCES = \
        circ_list.h \
        clinat.c clinat.h \
        common.h \
+       compat.h compat.c \
        config-win32.h \
        crypto.c crypto.h crypto_backend.h \
        crypto_openssl.c crypto_openssl.h \
diff --git a/compat.c b/compat.c
new file mode 100644 (file)
index 0000000..cb599b0
--- /dev/null
+++ b/compat.c
@@ -0,0 +1,129 @@
+/*
+ *  OpenVPN -- An application to securely tunnel IP networks
+ *             over a single UDP port, with support for SSL/TLS-based
+ *             session authentication and key exchange,
+ *             packet encryption, packet authentication, and
+ *             packet compression.
+ *
+ *  Copyright (C) 2011 - David Sommerseth <davids@redhat.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "syshead.h"
+#include "compat.h"
+#include <string.h>
+
+
+#ifndef HAVE_DIRNAME
+/* Unoptimised version of glibc memrchr().
+ * This is considered fast enough, as only this compat
+ * version of dirname() depends on it.
+ */
+static const char *
+__memrchr(const char *str, int c, size_t n)
+{
+  const char *end = str;
+
+  end += n - 1; /* Go to the end of the string */
+  while (end >= str) {
+    if(c == *end)
+      return end;
+    else
+      end--;
+  }
+  return NULL;
+}
+
+/* Modified version based on glibc-2.14.1 by Ulrich Drepper <drepper@akkadia.org>
+ * This version is extended to handle both / and \ in path names.
+ */
+char *
+dirname (char *path)
+{
+  static const char dot[] = ".";
+  char *last_slash;
+  char separator = '/';
+
+  /* Find last '/'.  */
+  last_slash = path != NULL ? strrchr (path, '/') : NULL;
+  /* If NULL, check for \ instead ... might be Windows a path */
+  if (!last_slash) {
+    last_slash = path != NULL ? strrchr (path, '\\') : NULL;
+    separator = last_slash ? '\\' : '/';  /* Change the separator if \ was found */
+  }
+
+  if (last_slash != NULL && last_slash != path && last_slash[1] == '\0') {
+      /* Determine whether all remaining characters are slashes.  */
+      char *runp;
+
+      for (runp = last_slash; runp != path; --runp)
+       if (runp[-1] != separator)
+         break;
+
+      /* The '/' is the last character, we have to look further.  */
+      if (runp != path)
+       last_slash = (char *) __memrchr (path, separator, runp - path);
+    }
+
+  if (last_slash != NULL) {
+      /* Determine whether all remaining characters are slashes.  */
+      char *runp;
+
+      for (runp = last_slash; runp != path; --runp)
+       if (runp[-1] != separator)
+         break;
+
+      /* Terminate the path.  */
+      if (runp == path) {
+         /* The last slash is the first character in the string.  We have to
+            return "/".  As a special case we have to return "//" if there
+            are exactly two slashes at the beginning of the string.  See
+            XBD 4.10 Path Name Resolution for more information.  */
+         if (last_slash == path + 1)
+           ++last_slash;
+         else
+           last_slash = path + 1;
+       }
+      else
+       last_slash = runp;
+
+      last_slash[0] = '\0';
+  } else
+    /* This assignment is ill-designed but the XPG specs require to
+       return a string containing "." in any case no directory part is
+       found and so a static and constant string is required.  */
+    path = (char *) dot;
+
+  return path;
+}
+#endif /* HAVE_DIRNAME */
+
+
+#ifndef HAVE_BASENAME
+/* Modified version based on glibc-2.14.1 by Roland McGrath <roland@gnu.org>
+ * This version is extended to handle both / and \ in path names
+ */
+char *
+basename (const char *filename)
+{
+  char *p = strrchr (filenamem, '/');
+  if (!p) {
+    /* If NULL, check for \ instead ... might be Windows a path */
+    p = strrchr (filename, '\\');
+  }
+  return p ? p + 1 : (char *) filename;
+}
+#endif /* HAVE_BASENAME */
diff --git a/compat.h b/compat.h
new file mode 100644 (file)
index 0000000..b380f0b
--- /dev/null
+++ b/compat.h
@@ -0,0 +1,42 @@
+/*
+ *  OpenVPN -- An application to securely tunnel IP networks
+ *             over a single UDP port, with support for SSL/TLS-based
+ *             session authentication and key exchange,
+ *             packet encryption, packet authentication, and
+ *             packet compression.
+ *
+ *  Copyright (C) 2011 - David Sommerseth <davids@redhat.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef COMPAT_H
+#define COMPAT_H
+
+#include "config.h"
+
+#if defined(HAVE_BASENAME) || defined(HAVE_DIRNAME)
+#include <libgen.h>
+#endif
+
+#ifndef HAVE_DIRNAME
+char * dirname(char *str);
+#endif /* HAVE_DIRNAME */
+
+#ifndef HAVE_BASENAME
+char * basename(char *str);
+#endif /* HAVE_BASENAME */
+
+#endif /* COMPAT_H */
index 7143cc5df37afb1fae57e121f068788f4f1a322b..d147d3855a3e591ff9d8b73bb7ce3fc5da01b5de 100644 (file)
@@ -521,7 +521,7 @@ AC_CHECK_FUNCS(daemon chroot getpwnam setuid nice system getpid dup dup2 dnl
               getpass strerror syslog openlog mlockall getgrnam setgid dnl
               setgroups stat flock readv writev time dnl
               setsid chdir putenv getpeername unlink dnl
-              chsize ftruncate execve getpeereid umask)
+              chsize ftruncate execve getpeereid umask basename dirname)
 
 # Windows use stdcall for winsock so we cannot auto detect these
 m4_define([SOCKET_FUNCS], [socket recv recvfrom send sendto listen dnl
diff --git a/init.c b/init.c
index a225c266d690a991f1441f78e751583c1c7f016d..00e93c98c9ca44506d7e459057ff0ace80c8a2bc 100644 (file)
--- a/init.c
+++ b/init.c
@@ -879,8 +879,10 @@ init_verb_mute (struct context *c, unsigned int flags)
 void
 init_options_dev (struct options *options)
 {
-  if (!options->dev)
-    options->dev = openvpn_basename (options->dev_node);
+  if (!options->dev && options->dev_node) {
+    char *dev_node = strdup(options->dev_node); /* POSIX basename() implementaions may modify its arguments */
+    options->dev = basename (dev_node);
+  }
 }
 
 bool
diff --git a/misc.c b/misc.c
index b834a3e4e5cc23d428ed41138ddbb4cb14af704a..bff67a73eccaf90900cd297388dfa0374e7228c4 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -2145,13 +2145,15 @@ argv_extract_cmd_name (const char *path)
 {
   if (path)
     {
-      const char *bn = openvpn_basename (path);
+      char *path_cp = strdup(path); /* POSIX basename() implementaions may modify its arguments */
+      const char *bn = basename (path_cp);
       if (bn)
        {
          char *ret = string_alloc (bn, NULL);
          char *dot = strrchr (ret, '.');
          if (dot)
            *dot = '\0';
+         free(path_cp);
          if (ret[0] != '\0')
            return ret;
        }
@@ -2493,25 +2495,6 @@ argv_test (void)
 }
 #endif
 
-const char *
-openvpn_basename (const char *path)
-{
-  const char *ret;
-  const int dirsep = OS_SPECIFIC_DIRSEP;
-
-  if (path)
-    {
-      ret = strrchr (path, dirsep);
-      if (ret && *ret)
-       ++ret;
-      else
-       ret = path;
-      if (*ret)
-       return ret;
-    }
-  return NULL;
-}
-
 /*
  * Remove security-sensitive strings from control message
  * so that they will not be output to log file.
diff --git a/misc.h b/misc.h
index b2e6f91f8458e036bd35da35dd29a7cc227f89be..b1badd9c9a0d060bc959c2847a5fa0af74a5202b 100644 (file)
--- a/misc.h
+++ b/misc.h
@@ -381,9 +381,6 @@ extern int script_method; /* GLOBAL */
 /* return the next largest power of 2 */
 size_t adjust_power_of_2 (size_t u);
 
-/* return the basename of path */
-const char *openvpn_basename (const char *path);
-
 /*
  * A printf-like function (that only recognizes a subset of standard printf
  * format operators) that prints arguments to an argv list instead
index a186276b3d208141fb6a320ee713a2192c7f2c0c..67206aa5ed5f1b8b781234de575e0bde3dfd704e 100644 (file)
--- a/options.c
+++ b/options.c
@@ -53,7 +53,6 @@
 #include "forward.h"
 #include <ctype.h>
 #include <unistd.h>
-#include <libgen.h>
 
 #include "memdbg.h"
 
index 38de87b4f870d9048852d30fe066fbfff682dc5e..fba6f84ec3956d2e76bfc45f6775c6b3823fb15c 100644 (file)
--- a/syshead.h
+++ b/syshead.h
@@ -36,6 +36,8 @@
 #include "config.h"
 #endif
 
+#include "compat.h"
+
 /* branch prediction hints */
 #if defined(__GNUC__)
 # define likely(x)       __builtin_expect((x),1)