From ec302f7061b7ab4dd21bdac77dd115e75b50cbc0 Mon Sep 17 00:00:00 2001 From: David Sommerseth Date: Thu, 8 Dec 2011 00:40:45 +0100 Subject: Move away from openvpn_basename() over to platform provided basename() 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 Acked-by: Alon Bar-Lev URL: http://thread.gmane.org/gmane.network.openvpn.devel/5178/focus=5215 --- compat.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 compat.c (limited to 'compat.c') diff --git a/compat.c b/compat.c new file mode 100644 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 + * + * 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 + + +#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 + * 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 + * 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 */ -- cgit