Skip to contentSkip to conversation

Windows does not have dirname() - reimplement a portable version

PATCH In review David Sommerseth 3 participants 5 messages Dec 2, 2011

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Windows does not have dirname() - reimplement a portable version

Commit 0f2bc0dd92f43c91e33bba8a66b06b98f281efc1 adds some extra checks on configured files and directories. This required use of the dirname() function. Unfortunately, this function is not available on Windows.

This function reimplements the POSIX variant of dirname(), using the framework already available in openvpn_basename(). The POSIX variant of dirname() will modify the input data.

---
 misc.c    |   36 ++++++++++++++++++++++++++++++++----
 misc.h    |    3 +++
 options.c |    3 +--
 3 files changed, 36 insertions(+), 6 deletions(-)
misc.c +32 -4
index 99e5bc5..eb04918 100644
@@ -2370,10 +2370,13 @@ argv_test (void)
 }
 #endif
 
-const char *
-openvpn_basename (const char *path)
+
+enum ovpn_dirbasename_t { DIRNAME, BASENAME };
+
+static inline char *
+openvpn_dirbasename(char *path, enum ovpn_dirbasename_t type)
 {
-  const char *ret;
+  char *ret;
   const int dirsep = OS_SPECIFIC_DIRSEP;
 
   if (path)
@@ -2384,11 +2387,36 @@ openvpn_basename (const char *path)
       else
 	ret = path;
       if (*ret)
-	return ret;
+        switch( type ) {
+        case BASENAME:
+          return ret;
+
+        case DIRNAME:
+          /* This implements the POSIX variant of dirname(),
+           * which do modify the input
+           */
+          *(ret-1) = 0;
+          return path;
+        }
     }
   return NULL;
 }
 
+const char *
+openvpn_basename (const char *path)
+{
+  /* the path is recasted as non-const, as we are sure it will not be modified
+   * in the basename type
+   */
+  return (const char *) openvpn_dirbasename((char *) path, BASENAME);
+}
+
+const char *
+openvpn_dirname (char *path)
+{
+        return openvpn_dirbasename(path, DIRNAME);
+}
+
 /*
  * Remove security-sensitive strings from control message
  * so that they will not be output to log file.
misc.h +3 -0
index b2e6f91..9b35f18 100644
@@ -384,6 +384,9 @@ size_t adjust_power_of_2 (size_t u);
 /* return the basename of path */
 const char *openvpn_basename (const char *path);
 
+/* return the dirname of path - POSIX variant, which modifies the input */
+const char *openvpn_dirname (char *path);
+
 /*
  * A printf-like function (that only recognizes a subset of standard printf
  * format operators) that prints arguments to an argv list instead
options.c +1 -2
index 28296a5..a29c115 100644
@@ -53,7 +53,6 @@
 #include "forward.h"
 #include <ctype.h>
 #include <unistd.h>
-#include <libgen.h>
 
 #include "memdbg.h"
 
@@ -2616,7 +2615,7 @@ check_file_access(const int type, const char *file, const int mode, const char *
   if (type & CHKACC_DIRPATH)
     {
       char *fullpath = strdup(file);  /* POSIX dirname() implementaion may modify its arguments */
-      char *dirpath = dirname(fullpath);
+      const char *dirpath = openvpn_dirname(fullpath);
 
       if (access (dirpath, mode|X_OK) != 0)
           errcode = errno;
Signature · 1 line
1.7.4.4
#1 lore raw

I think the whole code should be more autoconf depended. Autoconf can detect if POSIX version is available and if not, code can provide alternative.
No need for the openvpn_ functions and wrappers.

Quoted 126 lines · David Sommerseth

Commit 0f2bc0dd92f43c91e33bba8a66b06b98f281efc1 adds some extra checks on configured files and directories.  This required use of the dirname() function.  Unfortunately, this function is not available on Windows.

This function reimplements the POSIX variant of dirname(), using the framework already available in openvpn_basename().  The POSIX variant of dirname() will modify the input data.

---
 misc.c    |   36 ++++++++++++++++++++++++++++++++---- misc.h    |    3 +++
 options.c |    3 +--

 3 files changed, 36 insertions(+), 6 deletions(-)
misc.c +6 -3
index 99e5bc5..eb04918 100644
@@ -2370,10 +2370,13 @@ argv_test (void)
  }
  #endif
 
-const char *
-openvpn_basename (const char *path)
+
+enum ovpn_dirbasename_t { DIRNAME, BASENAME };
+
+static inline char *
+openvpn_dirbasename(char *path, enum ovpn_dirbasename_t type)
  {
-  const char *ret;
+  char *ret;
   const int dirsep = OS_SPECIFIC_DIRSEP;
 
   if (path)
@@ -2384,11 +2387,36 @@ openvpn_basename (const char *path)

      else
       ret = path;
      if (*ret)
-       return ret;
+        switch( type ) {
+        case BASENAME:
+          return ret;
+
+        case DIRNAME:
+          /* This implements the POSIX variant of dirname(),
+           * which do modify the input
+           */
+          *(ret-1) = 0;
+          return path;
+        }
    }
  return NULL;
 }

misc.c +15 -0
+const char *
+openvpn_basename (const char *path)
+{
+  /* the path is recasted as non-const, as we are sure it will not be modified
+   * in the basename type
+   */
+  return (const char *) openvpn_dirbasename((char *) path, BASENAME);
+}
+
+const char *
+openvpn_dirname (char *path)
+{
+        return openvpn_dirbasename(path, DIRNAME);
+}
+

 /*
 * Remove security-sensitive strings from control message
 * so that they will not be output to log file.

misc.h +3 -0
index b2e6f91..9b35f18 100644
@@ -384,6 +384,9 @@ size_t adjust_power_of_2 (size_t u);
  /* return the basename of path */
  const char *openvpn_basename (const char *path);
 
+/* return the dirname of path - POSIX variant, which modifies the input */
+const char *openvpn_dirname (char *path);
+
  /*
  * A printf-like function (that only recognizes a subset of standard printf
  * format operators) that prints arguments to an argv list instead
options.c +0 -1
index 28296a5..a29c115 100644
@@ -53,7 +53,6 @@
  #include "forward.h"
  #include <ctype.h>
  #include <unistd.h>
-#include <libgen.h>
 
  #include "memdbg.h"
 
@@ -2616,7 +2615,7 @@ check_file_access(const int type, const char *file, const int mode, const char *
   if (type & CHKACC_DIRPATH)
     {

      char *fullpath = strdup(file);  /* POSIX dirname() implementaion may modify its arguments */
-      char *dirpath = dirname(fullpath);
+      const char *dirpath = openvpn_dirname(fullpath);

      if (access (dirpath, mode|X_OK) != 0)
          errcode = errno;
--
1.7.4.4

------------------------------------------------------------------------------
All the data continuously generated in your IT infrastructure contains a definitive record of customers, application performance, security threats, fraudulent activity, and more. Splunk takes this data and makes sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-novd2d
_______________________________________________
Openvpn-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

#2 lore raw

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 3 lines · Alon Bar-Lev

I think the whole code should be more autoconf depended. Autoconf can detect if POSIX version is available and if not, code can provide alternative. No need for the openvpn_ functions and wrappers.

Fair enough statement, but we have a python oriented build environment on Windows too, which will not be so easy to tackle in this regards. This environment is required by OpenVPN Technologies for their internal build farms (most likely for the OpenVPN Access Server product).

As we already had openvpn_basename(), I found it reasonable to reuse that function for a dirname() variant as well.

To be honest, I'm not too happy about needing to maintain two build environments, but that's the requirements we have right now. It might be that we at some point will change this - if a reasonable approach is found. But that will happen earliest after the 2.3 release is shipped.

kind regards,

David Sommerseth

Quoted 63 lines
Quoted 61 lines · David Sommerseth

Commit 0f2bc0dd92f43c91e33bba8a66b06b98f281efc1 adds some extra checks on configured files and directories. This required use of the dirname() function. Unfortunately, this function is not available on Windows.

This function reimplements the POSIX variant of dirname(), using the framework already available in openvpn_basename(). The POSIX variant of dirname() will modify the input data.

<[email protected]...> --- misc.c | 36
++++++++++++++++++++++++++++++++---- misc.h | 3 +++ options.c
| 3 +-- 3 files changed, 36 insertions(+), 6 deletions(-)

misc.c index 99e5bc5..eb04918 100644 --- renamed from misc.c +0 -0

a/misc.c +++ b/misc.c @@ -2370,10 +2370,13 @@ argv_test (void) } #endif

-const char * -openvpn_basename (const char *path) + +enum ovpn_dirbasename_t { DIRNAME, BASENAME }; + +static inline char * +openvpn_dirbasename(char *path, enum ovpn_dirbasename_t type) { - const char *ret; + char *ret; const int dirsep = OS_SPECIFIC_DIRSEP;

if (path) @@ -2384,11 +2387,36 @@ openvpn_basename (const char
*path) else ret = path; if (*ret) - return ret; +
switch( type ) { + case BASENAME: + return ret; + +
case DIRNAME: + /* This implements the POSIX variant of
dirname(), + * which do modify the input + */ +
*(ret-1) = 0; + return path; + } } return NULL; }

+const char * +openvpn_basename (const char *path) +{ + /* the path is recasted as non-const, as we are sure it will not be modified +
* in the basename type + */ + return (const char *)
openvpn_dirbasename((char *) path, BASENAME); +} + +const char *
+openvpn_dirname (char *path) +{ + return
openvpn_dirbasename(path, DIRNAME); +} + /* * 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 b2e6f91..9b35f18 100644 --- a/misc.h +++ b/misc.h @@ -384,6 +384,9 @@ size_t adjust_power_of_2 (size_t u); /* return the basename of path */ const char *openvpn_basename (const char *path);

+/* return the dirname of path - POSIX variant, which modifies the input */ +const char *openvpn_dirname (char *path); + /* * A printf-like function (that only recognizes a subset of standard printf * format operators) that prints arguments to an argv list instead diff --git a/options.c b/options.c index 28296a5..a29c115 100644 --- 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"

misc.c index 99e5bc5..eb04918 100644 --- renamed from misc.c +0 -0
@@ -2616,7 +2615,7 @@ check_file_access(const int type, const char
 *file, const int mode, const char * if (type & CHKACC_DIRPATH) { 

char *fullpath = strdup(file); /* POSIX dirname() implementaion may
modify its arguments */ - char *dirpath = dirname(fullpath); +
const char *dirpath = openvpn_dirname(fullpath);

Quoted 6 lines
Quoted 6 lines

if (access (dirpath, mode|X_OK) != 0) errcode = errno; -- 1.7.4.4

------------------------------------------------------------------------------

All the data continuously generated in your IT infrastructure

Quoted 11 lines
Quoted 7 lines

contains a definitive record of customers, application performance, security threats, fraudulent activity, and more. Splunk takes this data and makes sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-novd2d
_______________________________________________ Openvpn-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

------------------------------------------------------------------------------

All the data continuously generated in your IT infrastructure

Quoted 8 lines

contains a definitive record of customers, application performance, security threats, fraudulent activity, and more. Splunk takes this data and makes sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-novd2d
_______________________________________________ Openvpn-devel mailing list [email protected]
https://lists.sourceforge.net/lists/listinfo/openvpn-devel

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk7Yxq0ACgkQDC186MBRfrqs9wCghKN+QHf0bFyrH8nyu6AVNj7t Z4EAn38YKbIHrP32H9eNUbT317utiNzq
=hBH4
-----END PGP SIGNATURE-----

#3 lore raw
Quoted 4 lines · David Sommerseth

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 02/12/11 13:28, Alon Bar-Lev wrote:

Quoted 9 lines
Quoted 3 lines

I think the whole code should be more autoconf depended. Autoconf can detect if POSIX version is available and if not, code can provide alternative. No need for the openvpn_ functions and wrappers.

Fair enough statement, but we have a python oriented build environment on Windows too, which will not be so easy to tackle in this regards.  This environment is required by OpenVPN Technologies for their internal build farms (most likely for the OpenVPN Access Server product).

It is not matter if you use python for Windows, as you create config-msvc.h with all constants that autoconf would have found.

Alon.

#4 lore raw

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 17 lines · Alon Bar-Lev
Quoted 8 lines · David Sommerseth

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1

Quoted 4 lines · Alon Bar-Lev

I think the whole code should be more autoconf depended. Autoconf can detect if POSIX version is available and if not, code can provide alternative. No need for the openvpn_ functions and wrappers.

Quoted 6 lines

Fair enough statement, but we have a python oriented build environment on Windows too, which will not be so easy to tackle in this regards. This environment is required by OpenVPN Technologies for their internal build farms (most likely for the OpenVPN Access Server product).

Quoted 2 lines

It is not matter if you use python for Windows, as you create config-msvc.h with all constants that autoconf would have found.

Fair enough. I'll give that a poke and come up with new patches.

kind regards,

David Sommerseth

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk7Y0RUACgkQDC186MBRfrqiJgCfcpObXpcbhHzhgMVYvqMbwdo7 ExoAn3W3cB8zU4rQtl7DV1DdK2XjRXO7
=n594
-----END PGP SIGNATURE-----