From b9420c3bfc2a8b9d35d0c8e5f6849007c2bc21fa Mon Sep 17 00:00:00 2001
From: Darik Horn <dajhorn@vanadac.com>
Date: Mon, 14 Apr 2014 13:22:24 -0400
Subject: [PATCH] Use FHS installation directories.

Install to `/usr/sbin`, `/usr/lib`, and `/var/lib` according to the Linux
filesystem hierarchy standard if SoftEther is built through autotools.

In a managed installation, the FHS stipulates that the application must
accomodate a read-only installation path.  This requires a new `GetStateDir`
function that substitues `GetExeDir` in some parts of the code.

Taken from Github at
https://github.com/dajhorn/SoftEtherVPN/commit/b9420c3bfc2a8b9d35d0c8e5f6849007c2bc21fa.

Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 autotools/softether.am      |  1 +
 src/Cedar/Admin.c           |  2 +-
 src/Cedar/Command.c         |  6 +++++-
 src/Cedar/Logging.c         |  2 +-
 src/Cedar/Server.c          |  4 ++--
 src/Mayaqua/Encrypt.c       |  2 +-
 src/Mayaqua/FileIO.c        | 39 ++++++++++++++++++++++++++++++++++++---
 src/Mayaqua/FileIO.h        |  2 ++
 src/Mayaqua/Mayaqua.c       |  4 ++++
 src/Mayaqua/Table.c         |  6 +++++-
 src/Mayaqua/Unix.c          |  6 +++---
 src/bin/hamcore/Makefile.am |  8 ++++++--
 12 files changed, 67 insertions(+), 15 deletions(-)

Index: b/autotools/softether.am
===================================================================
--- a/autotools/softether.am
+++ b/autotools/softether.am
@@ -27,6 +27,7 @@
 	-I$(top_srcdir)/src \
 	-I$(top_srcdir)/src/Mayaqua \
 	-I$(top_srcdir)/src/Cedar \
+	-DSTATE_DIR='"@localstatedir@/lib/softether"' \
 	-DUNIX \
 	-DUNIX_LINUX \
 	-D_REENTRANT \
Index: b/src/Cedar/Admin.c
===================================================================
--- a/src/Cedar/Admin.c
+++ b/src/Cedar/Admin.c
@@ -10334,7 +10334,7 @@
 
 	Zero(t, sizeof(RPC_READ_LOG_FILE));
 
-	GetExeDir(exe_dir, sizeof(exe_dir));
+	GetStateDir(exe_dir, sizeof(exe_dir));
 	Format(full_path, sizeof(full_path), "%s/%s", exe_dir, filepath);
 
 	// Read file
Index: b/src/Cedar/Command.c
===================================================================
--- a/src/Cedar/Command.c
+++ b/src/Cedar/Command.c
@@ -527,7 +527,7 @@
 	UINT i;
 
 	GetExeName(exe, sizeof(exe));
-	GetExeDir(exe_dir, sizeof(exe_dir));
+	GetStateDir(exe_dir, sizeof(exe_dir));
 
 	ok = false;
 	dirs = EnumDir(exe_dir);
@@ -552,7 +552,11 @@
 		UCHAR *buf;
 		IO *io;
 #ifndef	OS_WIN32
+#ifdef STATE_DIR
+		wchar_t *filename = L"" STATE_DIR L"/vpn_checker_tmp";
+#else
 		wchar_t *filename = L"/tmp/vpn_checker_tmp";
+#endif
 #else	// OS_WIN32
 		wchar_t filename[MAX_PATH];
 		CombinePathW(filename, sizeof(filename), MsGetMyTempDirW(), L"vpn_checker_tmp");
Index: b/src/Cedar/Logging.c
===================================================================
--- a/src/Cedar/Logging.c
+++ b/src/Cedar/Logging.c
@@ -508,7 +508,7 @@
 
 	e = ZeroMalloc(sizeof(ERASER));
 
-	GetExeDir(dir, sizeof(dir));
+	GetStateDir(dir, sizeof(dir));
 
 	e->Log = log;
 	e->MinFreeSpace = min_size;
Index: b/src/Cedar/Server.c
===================================================================
--- a/src/Cedar/Server.c
+++ b/src/Cedar/Server.c
@@ -1060,7 +1060,7 @@
 		hubname = NULL;
 	}
 
-	GetExeDir(exe_dir, sizeof(exe_dir));
+	GetStateDir(exe_dir, sizeof(exe_dir));
 
 	// Enumerate in the server_log
 	if (hubname == NULL)
@@ -1134,7 +1134,7 @@
 		return;
 	}
 
-	GetExeDir(exe_dir, sizeof(exe_dir));
+	GetStateDir(exe_dir, sizeof(exe_dir));
 	Format(dir_full_path, sizeof(dir_full_path), "%s/%s", exe_dir, dirname);
 
 	dir = EnumDir(dir_full_path);
Index: b/src/Mayaqua/Encrypt.c
===================================================================
--- a/src/Mayaqua/Encrypt.c
+++ b/src/Mayaqua/Encrypt.c
@@ -579,7 +579,7 @@
 		return false;
 	}
 
-	GetExeDir(dirname, sizeof(dirname));
+	GetStateDir(dirname, sizeof(dirname));
 
 	// Search the CRL file
 	t = EnumDir(dirname);
Index: b/src/Mayaqua/FileIO.c
===================================================================
--- a/src/Mayaqua/FileIO.c
+++ b/src/Mayaqua/FileIO.c
@@ -122,8 +122,14 @@
 #include <errno.h>
 #include <Mayaqua/Mayaqua.h>
 
+#ifdef STATE_DIR
+static char exe_file_name[MAX_SIZE] = STATE_DIR "/a.out";
+static wchar_t exe_file_name_w[MAX_SIZE] = L"" STATE_DIR L"/a.out";
+#else
 static char exe_file_name[MAX_SIZE] = "/tmp/a.out";
 static wchar_t exe_file_name_w[MAX_SIZE] = L"/tmp/a.out";
+#endif
+
 static LIST *hamcore = NULL;
 static IO *hamcore_io = NULL;
 
@@ -1038,7 +1044,7 @@
 	}
 
 	// If the file exist in hamcore/ directory on the local disk, read it
-	GetExeDirW(exe_dir, sizeof(exe_dir));
+	GetStateDirW(exe_dir, sizeof(exe_dir));
 
 	UniFormat(tmp, sizeof(tmp), L"%s/%S/%S", exe_dir, HAMCORE_DIR_NAME, filename);
 
@@ -1154,7 +1160,7 @@
 		return;
 	}
 
-	GetExeDirW(exe_dir, sizeof(exe_dir));
+	GetStateDirW(exe_dir, sizeof(exe_dir));
 	UniFormat(tmp, sizeof(tmp), L"%s/%S", exe_dir, HAMCORE_FILE_NAME);
 
 	UniFormat(tmp2, sizeof(tmp2), L"%s/%S", exe_dir, HAMCORE_FILE_NAME_2);
@@ -1438,6 +1444,33 @@
 	GetDirNameFromFilePathW(name, size, exe_file_name_w);
 }
 
+void GetStateDir(char *name, UINT size)
+{
+	// Validate arguments
+	if (name == NULL)
+	{
+		return;
+	}
+#ifdef STATE_DIR
+	StrCpy(name, size, STATE_DIR);
+#else
+	GetExeDir(name, size)
+#endif
+}
+void GetStateDirW(wchar_t *name, UINT size)
+{
+	// Validate arguments
+	if (name == NULL)
+	{
+		return;
+	}
+#ifdef STATE_DIR
+	UniStrCpy(name, size, L"" STATE_DIR L"");
+#else
+	GetExeDirW(name, size)
+#endif
+}
+
 // Get the EXE file name
 void GetExeName(char *name, UINT size)
 {
@@ -2389,7 +2422,7 @@
 	else
 	{
 		wchar_t dir[MAX_SIZE];
-		GetExeDirW(dir, sizeof(dir));
+		GetStateDirW(dir, sizeof(dir));
 		ConbinePathW(dst, size, dir, &src[1]);
 	}
 }
Index: b/src/Mayaqua/FileIO.h
===================================================================
--- a/src/Mayaqua/FileIO.h
+++ b/src/Mayaqua/FileIO.h
@@ -349,6 +349,8 @@
 void GetExeNameW(wchar_t *name, UINT size);
 void GetExeDir(char *name, UINT size);
 void GetExeDirW(wchar_t *name, UINT size);
+void GetStateDir(char *name, UINT size);
+void GetStateDirW(wchar_t *name, UINT size);
 void BuildHamcore(char *dst_filename, char *src_dir, bool unix_only);
 int CompareHamcore(void *p1, void *p2);
 void InitHamcore();
Index: b/src/Mayaqua/Mayaqua.c
===================================================================
--- a/src/Mayaqua/Mayaqua.c
+++ b/src/Mayaqua/Mayaqua.c
@@ -611,7 +611,11 @@
 		_exit(0);
 	}
 
+#ifndef STATE_DIR
+	// This check causes hamcorebuilder to fail in an unprivileged
+	// environment, and is unnecessary for a managed installation.
 	CheckUnixTempDir();
+#endif
 
 	// Initialization of Probe
 	InitProbe();
Index: b/src/Mayaqua/Table.c
===================================================================
--- a/src/Mayaqua/Table.c
+++ b/src/Mayaqua/Table.c
@@ -1191,7 +1191,7 @@
 		return;
 	}
 
-	GetExeDirW(exe, sizeof(exe));
+	GetStateDirW(exe, sizeof(exe));
 	UniStrCpy(hashtemp, sizeof(hashtemp), strfilename);
 	BinToStrW(tmp, sizeof(tmp), filehash, MD5_SIZE);
 	UniStrCat(hashtemp, sizeof(hashtemp), tmp);
@@ -1204,7 +1204,11 @@
 	UniStrLower(tmp);
 
 #ifndef	OS_WIN32
+#ifdef STATE_DIR
+	UniStrCpy(exe, sizeof(exe), L"" STATE_DIR L"");
+#else
 	UniStrCpy(exe, sizeof(exe), L"/tmp");
+#endif
 #else	// OS_WIN32
 	StrToUni(exe, sizeof(exe), MsGetTempDir());
 #endif	// OS_WIN32
Index: b/src/Mayaqua/Unix.c
===================================================================
--- a/src/Mayaqua/Unix.c
+++ b/src/Mayaqua/Unix.c
@@ -928,7 +928,7 @@
 		StrCpy(tmp, sizeof(tmp), instance_name);
 	}
 
-	GetExeDir(dir, sizeof(dir));
+	GetStateDir(dir, sizeof(dir));
 
 	// File name generation
 	Format(name, sizeof(name), "%s/.%s", dir, tmp);
@@ -2260,7 +2260,7 @@
 		return;
 	}
 
-	GetExeDir(dir, sizeof(dir));
+	GetStateDir(dir, sizeof(dir));
 
 	GetExeName(exe_name, sizeof(exe_name));
 	StrCat(exe_name, sizeof(exe_name), ":pid_hash");
@@ -2305,7 +2305,7 @@
 		return;
 	}
 
-	GetExeDir(dir, sizeof(dir));
+	GetStateDir(dir, sizeof(dir));
 
 	GetExeName(exe_name, sizeof(exe_name));
 	StrCat(exe_name, sizeof(exe_name), ":pid_hash");
Index: b/src/bin/hamcore/Makefile.am
===================================================================
--- a/src/bin/hamcore/Makefile.am
+++ b/src/bin/hamcore/Makefile.am
@@ -18,12 +18,16 @@
 
 include $(top_srcdir)/autotools/softether.am
 
-# This is required to use a custom build rule with -Wall and -Werror enabled.
+# An empty EXEEXT required for overrides with -Wall and -Werror enabled.
 AUTOMAKE_OPTIONS = -Wno-override
 EXEEXT =
+
 HAMCOREBUILDER = $(top_builddir)/src/hamcorebuilder/hamcorebuilder
 
-sbin_PROGRAMS = hamcore.se2
+noinst_PROGRAMS = hamcore.se2
 
 hamcore.se2$(EXEEXT): $(HAMCOREBUILDER)
 	$(HAMCOREBUILDER) $(top_srcdir)/src/bin/hamcore $@
+
+install-exec-local: hamcore.se2$(EXEEXT)
+	$(INSTALL_DATA) -D hamcore.se2$(EXEEXT) $(DESTDIR)$(localstatedir)/lib/softether/hamcore.se2
