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 0f2bc0dd92
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
This commit is contained in:
David Sommerseth 2011-12-08 00:40:45 +01:00
parent 8ee5646111
commit ec302f7061
9 changed files with 182 additions and 27 deletions

View 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 \

129
compat.c Normal file
View File

@ -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 */

42
compat.h Normal file
View File

@ -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 */

View 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

6
init.c
View File

@ -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

23
misc.c
View File

@ -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.

3
misc.h
View File

@ -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

View File

@ -53,7 +53,6 @@
#include "forward.h"
#include <ctype.h>
#include <unistd.h>
#include <libgen.h>
#include "memdbg.h"

View File

@ -36,6 +36,8 @@
#include "config.h"
#endif
#include "compat.h"
/* branch prediction hints */
#if defined(__GNUC__)
# define likely(x) __builtin_expect((x),1)