/pidgin/main: 5bcb306a4edf: cross-win32: FHS support for win32

Tomasz Wasilczyk twasilczyk at pidgin.im
Fri Apr 25 06:52:48 EDT 2014


Changeset: 5bcb306a4edfa748f89644b924ec4de4a7ab9af5
Author:	 Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date:	 2014-04-25 12:52 +0200
Branch:	 default
URL: https://hg.pidgin.im/pidgin/main/rev/5bcb306a4edf

Description:

cross-win32: FHS support for win32

diffstat:

 config.h.mingw                           |    8 +-
 configure.ac                             |   48 ++++++++++-
 libpurple/certificate.c                  |    2 +-
 libpurple/protocols/jabber/Makefile.am   |    9 +-
 libpurple/protocols/jabber/jabber.c      |    2 +-
 libpurple/protocols/oscar/Makefile.am    |    8 +-
 libpurple/protocols/yahoo/Makefile.am    |    7 +-
 libpurple/win32/win32dep.c               |  129 ++++++++++++++++++++++++++++--
 libpurple/win32/win32dep.h               |    5 +-
 pidgin/gtkconv-theme.c                   |    2 +-
 pidgin/gtkconv.c                         |    2 +-
 pidgin/plugins/win32/winprefs/winprefs.c |    2 +-
 pidgin/win32/gtkwin32dep.c               |    2 +-
 pidgin/win32/winpidgin.c                 |    4 +
 pidgin/win32/wspell.c                    |    2 +-
 15 files changed, 202 insertions(+), 30 deletions(-)

diffs (truncated from 479 to 300 lines):

diff --git a/config.h.mingw b/config.h.mingw
--- a/config.h.mingw
+++ b/config.h.mingw
@@ -406,10 +406,10 @@
  */
 #define HAVE_VSNPRINTF 1
 
-#define FINCH_LIBDIR wpurple_lib_dir()
-#define PIDGIN_LIBDIR wpurple_lib_dir()
-#define PURPLE_DATADIR wpurple_install_dir()
-#define PURPLE_LIBDIR wpurple_lib_dir()
+#define FINCH_LIBDIR wpurple_lib_dir(NULL)
+#define PIDGIN_LIBDIR wpurple_lib_dir(NULL)
+#define PURPLE_DATADIR wpurple_bin_dir()
+#define PURPLE_LIBDIR wpurple_lib_dir(NULL)
 #define PURPLE_LOCALEDIR wpurple_locale_dir()
 #define PURPLE_SYSCONFDIR wpurple_sysconf_dir()
 
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -177,12 +177,46 @@ AC_CHECK_SIZEOF(time_t, ,[
 
 AC_C_BIGENDIAN
 
+AC_ARG_WITH(win32-dirs, [AS_HELP_STRING([--with-win32-dirs=<classic|fhs>],
+	[use win32 classic (Program Files-like) or FHS (unix-like) directory structure (default: classic)])], [
+		if test "x$withval" != "xclassic" -a "x$withval" != "xfhs" ; then
+			AC_MSG_ERROR([Unsupported win32-dirs option. Please choose "classic" or "fhs".])
+		fi
+		with_win32_dirs="$withval"
+	], with_win32_dirs="classic")
+if test "x$is_win32" = "xyes" -a "x$with_win32_dirs" = "xfhs" ; then
+	AC_DEFINE(USE_WIN32_FHS, 1, [Define to 1, to use FHS on win32.])
+fi
+
 dnl Check for directories
 if test "x$is_win32" = "xyes" ; then
-	purple_datadir="wpurple_install_dir()"
-	purple_libdir="wpurple_lib_dir()"
-	pidgin_libdir="wpurple_lib_dir()"
-	finch_libdir="wpurple_lib_dir()"
+	if test "x$with_win32_dirs" = "xfhs" ; then
+		AS_AC_EXPAND(win32_fhs_bindir, "$bindir")
+		AC_DEFINE_UNQUOTED([WIN32_FHS_BINDIR], ["$win32_fhs_bindir"],
+			[bindir, as defined by configure])
+		AS_AC_EXPAND(win32_fhs_libdir, "$libdir")
+		AC_DEFINE_UNQUOTED([WIN32_FHS_LIBDIR], ["$win32_fhs_libdir"],
+			[libdir, as defined by configure])
+		AS_AC_EXPAND(win32_fhs_datadir, "$datadir")
+		AC_DEFINE_UNQUOTED([WIN32_FHS_DATADIR], ["$win32_fhs_datadir"],
+			[datadir, as defined by configure])
+		AS_AC_EXPAND(win32_fhs_sysconfdir, "$sysconfdir")
+		AC_DEFINE_UNQUOTED([WIN32_FHS_SYSCONFDIR], ["$win32_fhs_sysconfdir"],
+			[sysconfdir, as defined by configure])
+		AS_AC_EXPAND(win32_fhs_localedir, "$localedir")
+		AC_DEFINE_UNQUOTED([WIN32_FHS_LOCALEDIR], ["$win32_fhs_localedir"],
+			[localedir, as defined by configure])
+
+		purple_libdir="wpurple_lib_dir(\"purple-$PURPLE_MAJOR_VERSION\")"
+		pidgin_libdir="wpurple_lib_dir(\"pidgin-$PURPLE_MAJOR_VERSION\")"
+		finch_libdir="wpurple_lib_dir(\"finch-$PURPLE_MAJOR_VERSION\")"
+	else
+		purple_libdir="wpurple_lib_dir(NULL)"
+		pidgin_libdir="wpurple_lib_dir(NULL)"
+		finch_libdir="wpurple_lib_dir(NULL)"
+	fi
+
+	purple_datadir="wpurple_data_dir()"
 	purple_sysconfdir="wpurple_sysconf_dir()"
 	purple_localedir="wpurple_locale_dir()"
 else
@@ -3189,6 +3223,12 @@ echo Build with Mono support....... : $e
 echo Build with Perl support....... : $enable_perl
 echo Build with Tcl support........ : $enable_tcl
 echo Build with Tk support......... : $enable_tk
+
+if test "x$is_win32" = "xyes" ; then
+	echo
+	echo Win32 directory structure..... : $with_win32_dirs
+fi
+
 echo
 echo Print debugging messages...... : $enable_debug
 echo Generate documentation........ : $enable_gtk_doc
diff --git a/libpurple/certificate.c b/libpurple/certificate.c
--- a/libpurple/certificate.c
+++ b/libpurple/certificate.c
@@ -922,7 +922,7 @@ x509_ca_init(void)
 		x509_ca_paths = g_list_append(x509_ca_paths,
 			g_strdup(SSL_CERTIFICATES_DIR));
 #endif
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(USE_WIN32_FHS)
 		x509_ca_paths = g_list_append(x509_ca_paths, g_build_filename(
 			PURPLE_DATADIR, "ca-certs", NULL));
 #else
diff --git a/libpurple/protocols/jabber/Makefile.am b/libpurple/protocols/jabber/Makefile.am
--- a/libpurple/protocols/jabber/Makefile.am
+++ b/libpurple/protocols/jabber/Makefile.am
@@ -120,7 +120,14 @@ libjabber_la_LDFLAGS = @PLUGIN_LDFLAGS@
 else
 
 st =
-pkg_LTLIBRARIES      = libjabber.la libfacebook.la libgtalk.la libxmpp.la
+pkg_LTLIBRARIES      = libfacebook.la libgtalk.la libxmpp.la
+
+if IS_WIN32
+lib_LTLIBRARIES = libjabber.la
+else
+pkg_LTLIBRARIES += libjabber.la
+endif
+
 libjabber_la_SOURCES = $(JABBERSOURCES)
 libjabber_la_LIBADD  = @PURPLE_LIBS@ $(SASL_LIBS) $(LIBXML_LIBS) $(IDN_LIBS)\
 	$(FARSTREAM_LIBS) \
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -3814,7 +3814,7 @@ jabber_do_init(void)
 	if (!sasl_initialized) {
 		sasl_initialized = TRUE;
 #ifdef _WIN32
-		sasldir = g_build_filename(wpurple_install_dir(), "sasl2", NULL);
+		sasldir = g_build_filename(wpurple_bin_dir(), "sasl2", NULL);
 		sasl_set_path(SASL_PATH_TYPE_PLUGIN, sasldir);
 		g_free(sasldir);
 		/* Suppress error popups for failing to load sasl plugins */
diff --git a/libpurple/protocols/oscar/Makefile.am b/libpurple/protocols/oscar/Makefile.am
--- a/libpurple/protocols/oscar/Makefile.am
+++ b/libpurple/protocols/oscar/Makefile.am
@@ -64,7 +64,13 @@ liboscar_la_LDFLAGS = @PLUGIN_LDFLAGS@
 else
 
 st =
-pkg_LTLIBRARIES     = liboscar.la libaim.la libicq.la
+pkg_LTLIBRARIES     = libaim.la libicq.la
+if IS_WIN32
+lib_LTLIBRARIES = liboscar.la
+else
+pkg_LTLIBRARIES += liboscar.la
+endif
+
 liboscar_la_SOURCES = $(OSCARSOURCES)
 liboscar_la_LIBADD  = @PURPLE_LIBS@
 liboscar_la_LDFLAGS = @PLUGIN_LDFLAGS@
diff --git a/libpurple/protocols/yahoo/Makefile.am b/libpurple/protocols/yahoo/Makefile.am
--- a/libpurple/protocols/yahoo/Makefile.am
+++ b/libpurple/protocols/yahoo/Makefile.am
@@ -41,7 +41,12 @@ libymsg_la_LDFLAGS = @PLUGIN_LDFLAGS@
 else
 
 st =
-pkg_LTLIBRARIES     = libymsg.la libyahoo.la libyahoojp.la
+pkg_LTLIBRARIES     = libyahoo.la libyahoojp.la
+if IS_WIN32
+lib_LTLIBRARIES = libymsg.la
+else
+pkg_LTLIBRARIES += libymsg.la
+endif
 
 libymsg_la_SOURCES = $(YAHOOSOURCES)
 libymsg_la_LIBADD  = @PURPLE_LIBS@
diff --git a/libpurple/win32/win32dep.c b/libpurple/win32/win32dep.c
--- a/libpurple/win32/win32dep.c
+++ b/libpurple/win32/win32dep.c
@@ -29,10 +29,12 @@
 #include "glibcompat.h"
 #include "notify.h"
 
+#define MAX_PATH_LEN 2048
+
 /*
  * LOCALS
  */
-static char *app_data_dir = NULL, *install_dir = NULL,
+static char *app_data_dir = NULL, *bin_dir = NULL, *data_dir = NULL,
 	*lib_dir = NULL, *locale_dir = NULL, *sysconf_dir = NULL;
 
 static HINSTANCE libpurpledll_hInstance = NULL;
@@ -128,12 +130,17 @@ gchar *wpurple_get_special_folder(int fo
 	return retval;
 }
 
-const char *wpurple_install_dir(void) {
+const char *wpurple_bin_dir(void) {
 	static gboolean initialized = FALSE;
 
 	if (!initialized) {
 		char *tmp = NULL;
 		wchar_t winstall_dir[MAXPATHLEN];
+
+		/* We might use g_win32_get_package_installation_directory_of_module
+		 * here, but we won't because this routine strips bin or lib
+		 * part of the path.
+		 */
 		if (GetModuleFileNameW(libpurpledll_hInstance, winstall_dir,
 				MAXPATHLEN) > 0) {
 			tmp = g_utf16_to_utf8(winstall_dir, -1,
@@ -147,42 +154,138 @@ const char *wpurple_install_dir(void) {
 			g_free(tmp);
 			return NULL;
 		} else {
-			install_dir = g_path_get_dirname(tmp);
+			bin_dir = g_path_get_dirname(tmp);
 			g_free(tmp);
 			initialized = TRUE;
 		}
 	}
 
-	return install_dir;
+	return bin_dir;
 }
 
-const char *wpurple_lib_dir(void) {
+#ifdef USE_WIN32_FHS
+static gchar *
+wpurple_install_relative_path(const gchar *abspath)
+{
+	const gchar *bindir = WIN32_FHS_BINDIR;
+	const gchar *relpath;
+	int i, last_dirsep = -1, bin_esc_cnt;
+	gchar *ret;
+	GString *bin_esc;
+
+	g_return_val_if_fail(bindir != NULL, NULL);
+	g_return_val_if_fail(bindir[0] != '\0', NULL);
+	g_return_val_if_fail(abspath != NULL, NULL);
+	g_return_val_if_fail(abspath[0] != '\0', NULL);
+
+	/* let's find the common prefix of those paths */
+	for (i = 0; bindir[i] == abspath[i]; i++) {
+		if (bindir[i] == '\0')
+			break;
+		if (bindir[i] == '\\' || bindir[i] == '/')
+			last_dirsep = i;
+	}
+	if (bindir[i] == '\0' && (abspath[i] == '\\' || abspath[i] == '/'))
+		last_dirsep = i;
+	if (abspath[i] == '\0' && (bindir[i] == '\\' || bindir[i] == '/'))
+		last_dirsep = i;
+
+	/* there is no common prefix, return absolute path */
+	if (last_dirsep == -1)
+		return g_strdup(abspath);
+
+	/* let's check, how many dirs we need to go up to the common prefix */
+	bin_esc_cnt = 0;
+	for (i = last_dirsep; bindir[i]; i++) {
+		if (bindir[i] != '\\' && bindir[i] != '/')
+			continue;
+		if (bindir[i + 1] == '\0') /* trailing dir separator */
+			break;
+		bin_esc_cnt++;
+	}
+	bin_esc = g_string_new("");
+	for (i = 0; i < bin_esc_cnt; i++)
+		g_string_append(bin_esc, ".." G_DIR_SEPARATOR_S);
+
+	/* now, we need to go back deeper into the directory tree */
+	relpath = &abspath[last_dirsep];
+	if (relpath[0] != '\0')
+		relpath++;
+
+	/* - enter bin dir
+	 * - escape it to the common prefix
+	 * - dive into the abspath dir
+	 */
+	ret = g_build_filename(wpurple_bin_dir(), bin_esc->str, relpath, NULL);
+	g_string_free(bin_esc, TRUE);
+
+	purple_debug_misc("wpurple", "wpurple_install_relative_path(%s) = %s",
+		abspath, ret);
+
+	return ret;
+}
+#endif
+
+const char *
+wpurple_data_dir(void) {
+#ifdef USE_WIN32_FHS
 	static gboolean initialized = FALSE;
+	if (initialized)
+		return data_dir;
+	data_dir = wpurple_install_relative_path(WIN32_FHS_DATADIR);
+	initialized = TRUE;
+
+	return data_dir;
+#else
+	return wpurple_bin_dir();
+#endif
+}
+
+
+const char *wpurple_lib_dir(const char *subdir)
+{
+	static gboolean initialized = FALSE;
+	static gchar subpath[MAX_PATH_LEN];
 
 	if (!initialized) {



More information about the Commits mailing list