summaryrefslogtreecommitdiff
path: root/libpurple/win32
diff options
context:
space:
mode:
authorDaniel Atallah <datallah@pidgin.im>2014-12-16 18:18:42 -0500
committerDaniel Atallah <datallah@pidgin.im>2014-12-16 18:18:42 -0500
commit8233ce84d8795a21f7a63cfb9c71dc714df60f35 (patch)
treee171b094cee58f3f9e9d6ebb628239e6a593e767 /libpurple/win32
parentdfcf0fb70d02e1cb172855ec3fab5a803d63fbdb (diff)
parentfb9a018a3aca7f18147a2f418bd9468fd9ff42ee (diff)
downloadpidgin-8233ce84d8795a21f7a63cfb9c71dc714df60f35.tar.gz
Merge with release-2.x.y with a few manual conflict resolutions
Diffstat (limited to 'libpurple/win32')
-rw-r--r--libpurple/win32/giowin32.c10
-rw-r--r--libpurple/win32/global.mak65
-rw-r--r--libpurple/win32/libc_interface.c28
-rw-r--r--libpurple/win32/libc_interface.h19
-rw-r--r--libpurple/win32/libc_internal.h3
-rw-r--r--libpurple/win32/libpurplerc.rc.in13
-rw-r--r--libpurple/win32/rules.mak11
-rw-r--r--libpurple/win32/targets.mak19
-rw-r--r--libpurple/win32/win32dep.c344
-rw-r--r--libpurple/win32/win32dep.h29
10 files changed, 444 insertions, 97 deletions
diff --git a/libpurple/win32/giowin32.c b/libpurple/win32/giowin32.c
index 4b82d90fd1..fd96ceed15 100644
--- a/libpurple/win32/giowin32.c
+++ b/libpurple/win32/giowin32.c
@@ -32,7 +32,7 @@
/* Define this to get (very) verbose logging of all channels */
/* #define G_IO_WIN32_DEBUG */
-/* #include "config.h" */
+#include <config.h>
#include <glib.h>
@@ -222,7 +222,7 @@ init_reset_sockets (GIOWin32Channel *channel)
int len;
channel->reset_send = (gint) socket (AF_INET, SOCK_DGRAM, 0);
- if (channel->reset_send == INVALID_SOCKET)
+ if (channel->reset_send == (gint)INVALID_SOCKET)
{
g_warning (G_STRLOC ": Error creating reset_send socket: %s\n",
g_win32_error_message (WSAGetLastError ()));
@@ -243,7 +243,7 @@ init_reset_sockets (GIOWin32Channel *channel)
local2.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
channel->reset_recv = (gint) socket (AF_INET, SOCK_DGRAM, 0);
- if (channel->reset_recv == INVALID_SOCKET)
+ if (channel->reset_recv == (gint)INVALID_SOCKET)
{
g_warning (G_STRLOC ": Error creating reset_recv socket: %s\n",
g_win32_error_message (WSAGetLastError ()));
@@ -603,9 +603,9 @@ g_io_win32_free (GIOChannel *channel)
win32_channel->thread_id,
win32_channel->fd);
- if (win32_channel->reset_send && win32_channel->reset_send != INVALID_SOCKET)
+ if (win32_channel->reset_send && win32_channel->reset_send != (gint)INVALID_SOCKET)
closesocket (win32_channel->reset_send);
- if (win32_channel->reset_recv && win32_channel->reset_recv != INVALID_SOCKET)
+ if (win32_channel->reset_recv && win32_channel->reset_recv != (gint)INVALID_SOCKET)
closesocket (win32_channel->reset_recv);
if (win32_channel->data_avail_event)
CloseHandle (win32_channel->data_avail_event);
diff --git a/libpurple/win32/global.mak b/libpurple/win32/global.mak
index 79892b93d9..c8ed552aa0 100644
--- a/libpurple/win32/global.mak
+++ b/libpurple/win32/global.mak
@@ -8,21 +8,34 @@
#include optional $(PIDGIN_TREE_TOP)/local.mak to allow overriding of any definitions
-include $(PIDGIN_TREE_TOP)/local.mak
+# TODO: we should do parsing like for PURPLE_VERSION, if we won't drop
+# Makefile.mingw files before 3.0.0 release
+PURPLE_MAJOR_VERSION := 3
+PURPLE_MINOR_VERSION := 0
+PURPLE_MICRO_VERSION := 0
+PURPLE_API_VERSION := 20
+
# Locations of our various dependencies
WIN32_DEV_TOP ?= $(PIDGIN_TREE_TOP)/../win32-dev
-GTKSPELL_TOP ?= $(WIN32_DEV_TOP)/gtkspell-2.0.16
-ENCHANT_TOP ?= $(WIN32_DEV_TOP)/enchant_1.6.0_win32
-GTK_TOP ?= $(WIN32_DEV_TOP)/gtk_2_0-2.14
+ENCHANT_TOP ?= $(WIN32_DEV_TOP)/enchant-1.6
+GNUTLS_TOP ?= $(WIN32_DEV_TOP)/gnutls-3.1
+GTK_TOP ?= $(WIN32_DEV_TOP)/gtk2-2.24
GTK_BIN ?= $(GTK_TOP)/bin
-LIBXML2_TOP ?= $(WIN32_DEV_TOP)/libxml2-2.9.0
-MEANWHILE_TOP ?= $(WIN32_DEV_TOP)/meanwhile-1.0.2_daa3
+JSON_GLIB_TOP ?= $(WIN32_DEV_TOP)/json-glib-0.14
+LIBXML2_TOP ?= $(WIN32_DEV_TOP)/libxml2-2.9
+MEANWHILE_TOP ?= $(WIN32_DEV_TOP)/meanwhile-1.0
NSS_TOP ?= $(WIN32_DEV_TOP)/nss-3.17.1-nspr-4.10.7
-PERL_LIB_TOP ?= $(WIN32_DEV_TOP)/perl-5.10.0
-SILC_TOOLKIT ?= $(WIN32_DEV_TOP)/silc-toolkit-1.1.10
-TCL_LIB_TOP ?= $(WIN32_DEV_TOP)/tcl-8.4.5
-GSTREAMER_TOP ?= $(WIN32_DEV_TOP)/gstreamer-0.10.13
+PERL_LIB_TOP ?= $(WIN32_DEV_TOP)/perl-5.10
+SILC_TOOLKIT ?= $(WIN32_DEV_TOP)/silc-toolkit-1.1
+TCL_LIB_TOP ?= $(WIN32_DEV_TOP)/tcl-8.5
+GSTREAMER_TOP ?= $(WIN32_DEV_TOP)/gstreamer-0.10
GCC_SSP_TOP ?= $(shell dirname $(shell which $(CC)))
-CYRUS_SASL_TOP ?= $(WIN32_DEV_TOP)/cyrus-sasl-2.1.25
+CYRUS_SASL_TOP ?= $(WIN32_DEV_TOP)/cyrus-sasl-2.1
+WEBKITGTK_TOP ?= $(WIN32_DEV_TOP)/libwebkitgtk-1.10
+LIBSOUP_TOP ?= $(WIN32_DEV_TOP)/libsoup-2.42
+GETTEXT_TOP ?= $(WIN32_DEV_TOP)/gettext-0.18
+INTLTOOL_TOP ?= $(WIN32_DEV_TOP)/intltool-0.50
+LIBGADU_TOP ?= $(WIN32_DEV_TOP)/libgadu-1.12
# Where we installing this stuff to?
PIDGIN_INSTALL_DIR := $(PIDGIN_TREE_TOP)/win32-install-dir
@@ -61,6 +74,7 @@ GCCWARNINGS ?= -Waggregate-return -Wcast-align -Wdeclaration-after-statement -We
CC_HARDENING_OPTIONS ?= -Wstack-protector -fwrapv -fno-strict-overflow -Wno-missing-field-initializers -Wformat-security -fstack-protector-all --param ssp-buffer-size=1
LD_HARDENING_OPTIONS ?= -Wl,--dynamicbase -Wl,--nxcompat
+TAG := @$(PURPLE_TOP)/tag.sh
# parse the version number from the configure.ac file if it is newer
#m4_define([purple_major_version], [2])
@@ -102,18 +116,45 @@ DLL_LD_FLAGS += -Wl,--enable-auto-image-base -Wl,--enable-auto-import $(LD_HARDE
ifeq "$(origin CC)" "default"
CC := gcc.exe
endif
-GMSGFMT ?= $(WIN32_DEV_TOP)/gettext-0.17/bin/msgfmt
+# comment out the next line to make output more verbose
+CC := $(TAG) "auto" $(CC)
+
+GMSGFMT ?= $(GETTEXT_TOP)/bin/msgfmt
MAKENSIS ?= makensis.exe
PERL ?= perl
WINDRES ?= windres
STRIP ?= strip
-INTLTOOL_MERGE ?= $(WIN32_DEV_TOP)/intltool_0.40.4-1_win32/bin/intltool-merge
+INTLTOOL_MERGE ?= $(INTLTOOL_TOP)/bin/intltool-merge
MONO_SIGNCODE ?= signcode
GPG_SIGN ?= gpg
+GLIB_GENMARSHAL ?= $(GTK_BIN)/glib-genmarshal
+GLIB_MKENUMS ?= $(GTK_BIN)/glib-mkenums
PIDGIN_COMMON_RULES := $(PURPLE_TOP)/win32/rules.mak
PIDGIN_COMMON_TARGETS := $(PURPLE_TOP)/win32/targets.mak
MINGW_MAKEFILE := Makefile.mingw
+MAKE_at := @
+
+USE_VV ?= 1
+
+ifeq "$(USE_VV)" "1"
+VV_LIBS := \
+ -lgstreamer-0.10 \
+ -lgstvideo-0.10 \
+ -lgstinterfaces-0.10 \
+ -lfarstream-0.1
+VV_INCLUDE_PATHS := \
+ -I$(GSTREAMER_TOP)/include/gstreamer-0.10 \
+ -I$(GSTREAMER_TOP)/include/farstream-0.1 \
+ -I$(LIBXML2_TOP)/include/libxml2
+VV_LIB_PATHS := \
+ -L$(GSTREAMER_TOP)/lib
+DEFINES += -DUSE_GSTREAMER -DUSE_VV
+else
+VV_LIBS :=
+VV_INCLUDE_PATHS :=
+VV_LIB_PATHS :=
+endif
INSTALL_PIXMAPS ?= 1
INSTALL_SSL_CERTIFICATES ?= 1
diff --git a/libpurple/win32/libc_interface.c b/libpurple/win32/libc_interface.c
index 493dfca53f..fc4e171940 100644
--- a/libpurple/win32/libc_interface.c
+++ b/libpurple/win32/libc_interface.c
@@ -18,6 +18,9 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*
*/
+
+#include <config.h>
+
#include <winsock2.h>
#include <ws2tcpip.h>
#include <io.h>
@@ -28,7 +31,6 @@
#include <sys/stat.h>
#include <time.h>
#include <glib.h>
-#include "config.h"
#include "debug.h"
#include "libc_internal.h"
#include <glib/gstdio.h>
@@ -82,7 +84,7 @@ int wpurple_socket (int namespace, int style, int protocol) {
ret = socket( namespace, style, protocol );
- if( ret == INVALID_SOCKET ) {
+ if (ret == (int)INVALID_SOCKET) {
errno = WSAGetLastError();
return -1;
}
@@ -308,7 +310,7 @@ wpurple_inet_pton(int af, const char *src, void *dst)
struct sockaddr_in6 sin6;
struct sockaddr_in sin;
} sa;
- size_t srcsize;
+ int srcsize;
switch(af)
{
@@ -325,7 +327,7 @@ wpurple_inet_pton(int af, const char *src, void *dst)
return -1;
}
- if (WSAStringToAddress(src, af, NULL, (struct sockaddr *) &sa, &srcsize) != 0)
+ if (WSAStringToAddress((LPTSTR)src, af, NULL, (struct sockaddr *) &sa, &srcsize) != 0)
{
errno = WSAGetLastError();
return -1;
@@ -511,12 +513,6 @@ int wpurple_gettimeofday(struct timeval *p, struct timezone *z) {
return res;
}
-/* stdio.h */
-
-int wpurple_rename (const char *oldname, const char *newname) {
- return g_rename(oldname, newname);
-}
-
/* time.h */
struct tm * wpurple_localtime_r (const time_t *time, struct tm *resultp) {
@@ -1091,15 +1087,3 @@ wpurple_get_timezone_abbreviation(const struct tm *tm)
purple_debug_warning("wpurple", "could not find a match for Windows timezone \"%s\"\n", tzname);
return "";
}
-
-int wpurple_g_access (const gchar *filename, int mode);
-/**
- * @deprecated - remove for 3.0.0
- */
-int
-wpurple_g_access (const gchar *filename, int mode)
-{
- return g_access(filename, mode);
-}
-
-
diff --git a/libpurple/win32/libc_interface.h b/libpurple/win32/libc_interface.h
index 1aacf56863..011d178d51 100644
--- a/libpurple/win32/libc_interface.h
+++ b/libpurple/win32/libc_interface.h
@@ -22,12 +22,16 @@
*/
#ifndef _LIBC_INTERFACE_H_
#define _LIBC_INTERFACE_H_
+
+#include <config.h>
+
#include <winsock2.h>
#include <ws2tcpip.h>
#include <io.h>
#include <errno.h>
#include "libc_internal.h"
#include <glib.h>
+#include "glibcompat.h"
#ifdef __cplusplus
extern "C" {
@@ -132,18 +136,23 @@ wpurple_gethostname( name, size )
wpurple_gettimeofday( timeval, timezone )
/* stdio.h */
-#undef snprintf
-#define snprintf _snprintf
-#undef vsnprintf
-#define vsnprintf _vsnprintf
+#if !defined(__MINGW64_VERSION_MAJOR) || __MINGW64_VERSION_MAJOR < 3 || \
+ !defined(IS_WIN32_CROSS_COMPILED)
+# undef snprintf
+# define snprintf _snprintf
+# undef vsnprintf
+# define vsnprintf _vsnprintf
+#endif
#define rename( oldname, newname ) \
-wpurple_rename( oldname, newname )
+g_rename( oldname, newname )
/* sys/stat.h */
#define fchmod(a,b)
/* time.h */
+/* XXX: it may be also defined by pthread.h */
+#undef localtime_r
#define localtime_r( time, resultp ) \
wpurple_localtime_r( time, resultp )
diff --git a/libpurple/win32/libc_internal.h b/libpurple/win32/libc_internal.h
index 565af6ea3e..10fa2483e8 100644
--- a/libpurple/win32/libc_internal.h
+++ b/libpurple/win32/libc_internal.h
@@ -142,9 +142,6 @@ int wpurple_close(int fd);
int wpurple_gethostname(char *name, size_t size);
-/* stdio.h */
-int wpurple_rename(const char *oldname, const char *newname);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/libpurple/win32/libpurplerc.rc.in b/libpurple/win32/libpurplerc.rc.in
index 3d5e9e3e1d..26441110b7 100644
--- a/libpurple/win32/libpurplerc.rc.in
+++ b/libpurple/win32/libpurplerc.rc.in
@@ -1,9 +1,8 @@
#include <winver.h>
-#include "version.h"
VS_VERSION_INFO VERSIONINFO
- FILEVERSION PURPLE_MAJOR_VERSION,PURPLE_MINOR_VERSION,PURPLE_MICRO_VERSION,0
- PRODUCTVERSION PURPLE_MAJOR_VERSION,PURPLE_MINOR_VERSION,PURPLE_MICRO_VERSION,0
+ FILEVERSION @PURPLE_MAJOR_VERSION@,@PURPLE_MINOR_VERSION@,@PURPLE_MICRO_VERSION@,0
+ PRODUCTVERSION @PURPLE_MAJOR_VERSION@,@PURPLE_MINOR_VERSION@,@PURPLE_MICRO_VERSION@,0
FILEFLAGSMASK 0
FILEFLAGS 0
FILEOS VOS__WINDOWS32
@@ -15,12 +14,12 @@ VS_VERSION_INFO VERSIONINFO
BLOCK "040904B0"
BEGIN
VALUE "CompanyName", "The Pidgin developer community"
- VALUE "FileDescription", "LibPurple Library"
+ VALUE "FileDescription", "libpurple library"
VALUE "FileVersion", "@PURPLE_VERSION@"
VALUE "InternalName", "libpurple"
- VALUE "LegalCopyright", "Copyright (C) 1998-2010 The Pidgin developer community (See the COPYRIGHT file in the source distribution)."
- VALUE "OriginalFilename", "libpurple.dll"
- VALUE "ProductName", "LibPurple"
+ VALUE "LegalCopyright", "Copyright (C) 1998-2014 The Pidgin developer community (See the COPYRIGHT file in the source distribution)."
+ VALUE "OriginalFilename", "libpurple-@PURPLE_API_VERSION@.dll"
+ VALUE "ProductName", "libpurple"
VALUE "ProductVersion", "@PURPLE_VERSION@"
END
END
diff --git a/libpurple/win32/rules.mak b/libpurple/win32/rules.mak
index f372f2a5be..9ea9372495 100644
--- a/libpurple/win32/rules.mak
+++ b/libpurple/win32/rules.mak
@@ -4,10 +4,17 @@
$(CC) $(CFLAGS) $(DEFINES) $(INCLUDE_PATHS) -o $@ -c $<
%.c: %.xs
- $(PERL) -MExtUtils::ParseXS -e 'ExtUtils::ParseXS::process_file(filename => "$<", output => "$@", typemap => "$(PURPLE_PERL_TOP)/common/typemap");'
+ $(TAG) "PERL" $(PERL) -MExtUtils::ParseXS -e 'ExtUtils::ParseXS::process_file(filename => "$<", output => "$@", typemap => "$(PURPLE_PERL_TOP)/common/typemap");'
%.o: %.rc
- $(WINDRES) -I$(PURPLE_TOP) -i $< -o $@
+ @echo -e " GEN\t$@"
+ @$(WINDRES) -I$(PURPLE_TOP) -i $< -o $@
%.desktop: %.desktop.in $(wildcard $(PIDGIN_TREE_TOP)/po/*.po)
LC_ALL=C $(PERL) $(INTLTOOL_MERGE) -d -u -c $(PIDGIN_TREE_TOP)/po/.intltool-merge-cache $(PIDGIN_TREE_TOP)/po $< $@
+
+%.html.h: %.html
+ @echo -e " GEN\t$@"
+ @echo "static const char $*_html[] = {" > $@
+ @sed -e 's/^[ ]\+//g' -e 's/[ ]\+/ /g' $< | xxd -i | sed -e 's/\(0x[0-9a-f][0-9a-f]\)$$/\1, 0x00/' >> $@
+ @echo "};" >> $@
diff --git a/libpurple/win32/targets.mak b/libpurple/win32/targets.mak
index e4f8049459..f48f2ba836 100644
--- a/libpurple/win32/targets.mak
+++ b/libpurple/win32/targets.mak
@@ -6,26 +6,31 @@
#
$(PIDGIN_CONFIG_H): $(PIDGIN_CONFIG_H).mingw $(PIDGIN_TREE_TOP)/configure.ac
- sed -e 's/@VERSION@/$(PIDGIN_VERSION)/; s/@DISPLAY_VERSION@/$(DISPLAY_VERSION)/' $@.mingw > $@
+ @echo -e " GEN\t$@"
+ @sed -e 's/@VERSION@/$(PIDGIN_VERSION)/; s/@DISPLAY_VERSION@/$(DISPLAY_VERSION)/' $@.mingw > $@
$(PURPLE_PURPLE_H): $(PURPLE_PURPLE_H).in
- sed -e 's/@PLUGINS_DEFINE@/#define PURPLE_PLUGINS 1/' $@.in > $@
+ @echo -e " GEN\t$@"
+ @sed -e 's/@PLUGINS_DEFINE@/#define PURPLE_PLUGINS 1/' $@.in > $@
$(PURPLE_VERSION_H): $(PURPLE_VERSION_H).in $(PIDGIN_TREE_TOP)/configure.ac
- awk 'BEGIN {FS="[\\(\\)\\[\\]]"} \
+ @echo -e " GEN\t$@"
+ @awk 'BEGIN {FS="[\\(\\)\\[\\]]"} \
/^m4_define..purple_major_version/ {system("sed -e s/@PURPLE_MAJOR_VERSION@/"$$5"/ $@.in > $@");} \
/^m4_define..purple_minor_version/ {system("sed -e s/@PURPLE_MINOR_VERSION@/"$$5"/ $@ > $@.tmp && mv $@.tmp $@");} \
/^m4_define..purple_micro_version/ {system("sed -e s/@PURPLE_MICRO_VERSION@/"$$5"/ $@ > $@.tmp && mv $@.tmp $@"); exit}' $(PIDGIN_TREE_TOP)/configure.ac
$(PIDGIN_REVISION_RAW_TXT):
- (hg --cwd $(PIDGIN_TREE_TOP) id -i --debug) 2>/dev/null >$@ \
+ @echo -e " GEN\t$@"
+ @(hg --cwd $(PIDGIN_TREE_TOP) id -i --debug) 2>/dev/null >$@ \
|| rm -f $@
$(PIDGIN_REVISION_H): $(PIDGIN_REVISION_RAW_TXT)
- if [ -f $< ]; then \
+ @echo -e " GEN\t$@"
+ @if [ -f $< ]; then \
sed 's/^\(.\{1,\}\)$$/#define REVISION "\1"/' $< > $@; \
fi
- [ -f $@ ] || echo "#define REVISION \"unknown\"" > $@
+ @[ -f $@ ] || echo "#define REVISION \"unknown\"" > $@
$(PURPLE_DLL) $(PURPLE_DLL).a: $(PURPLE_VERSION_H)
$(MAKE) -C $(PURPLE_TOP) -f $(MINGW_MAKEFILE) libpurple.dll
@@ -34,7 +39,7 @@ $(PURPLE_PERL_DLL) $(PURPLE_PERL_DLL).a:
$(MAKE) -C $(PURPLE_PERL_TOP) -f $(MINGW_MAKEFILE) perl.dll
$(PIDGIN_DLL) $(PIDGIN_DLL).a:
- $(MAKE) -C $(PIDGIN_TOP) -f $(MINGW_MAKEFILE) pidgin.dll
+ $(MAKE_at) $(MAKE) -C $(PIDGIN_TOP) -f $(MINGW_MAKEFILE) pidgin.dll
$(PIDGIN_EXE):
$(MAKE) -C $(PIDGIN_TOP) -f $(MINGW_MAKEFILE) pidgin.exe
diff --git a/libpurple/win32/win32dep.c b/libpurple/win32/win32dep.c
index 2c2824f744..6ca5e737f5 100644
--- a/libpurple/win32/win32dep.c
+++ b/libpurple/win32/win32dep.c
@@ -22,18 +22,21 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*
*/
-#define _WIN32_IE 0x501
#include "internal.h"
#include <winuser.h>
#include "debug.h"
+#include "glibcompat.h"
#include "notify.h"
+#define MAX_PATH_LEN 2048
+
/*
* LOCALS
*/
-static char *app_data_dir = NULL, *install_dir = NULL,
- *lib_dir = NULL, *locale_dir = NULL;
+static char *app_data_dir = NULL, *bin_dir = NULL, *data_dir = NULL,
+ *lib_dir = NULL, *locale_dir = NULL, *sysconf_dir = NULL,
+ *cert_dir = NULL;
static HINSTANCE libpurpledll_hInstance = NULL;
@@ -80,7 +83,8 @@ FARPROC wpurple_find_and_loadproc(const char *dllname, const char *procedure) {
wchar_t *wc_dllname = g_utf8_to_utf16(dllname, -1, NULL, NULL, NULL);
if(!(hmod = GetModuleHandleW(wc_dllname))) {
- purple_debug_warning("wpurple", "%s not already loaded; loading it...\n", dllname);
+ if (purple_debug_is_verbose())
+ purple_debug_info("wpurple", "%s not already loaded; loading it...\n", dllname);
if(!(hmod = LoadLibraryW(wc_dllname))) {
purple_debug_error("wpurple", "Could not load: %s (%s)\n", dllname,
g_win32_error_message(GetLastError()));
@@ -95,8 +99,10 @@ FARPROC wpurple_find_and_loadproc(const char *dllname, const char *procedure) {
wc_dllname = NULL;
if((proc = GetProcAddress(hmod, procedure))) {
- purple_debug_info("wpurple", "This version of %s contains %s\n",
- dllname, procedure);
+ if (purple_debug_is_verbose()) {
+ purple_debug_info("wpurple", "This version of %s contains %s\n",
+ dllname, procedure);
+ }
return proc;
}
else {
@@ -125,12 +131,17 @@ gchar *wpurple_get_special_folder(int folder_type) {
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,
@@ -144,48 +155,144 @@ 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;
+}
+
+#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(void) {
+const char *wpurple_lib_dir(const char *subdir)
+{
static gboolean initialized = FALSE;
+ static gchar subpath[MAX_PATH_LEN];
if (!initialized) {
- const char *inst_dir = wpurple_install_dir();
+#ifdef USE_WIN32_FHS
+ lib_dir = wpurple_install_relative_path(WIN32_FHS_LIBDIR);
+ initialized = TRUE;
+#else
+ const char *inst_dir = wpurple_bin_dir();
if (inst_dir != NULL) {
lib_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "plugins", inst_dir);
initialized = TRUE;
} else {
return NULL;
}
+#endif
}
- return lib_dir;
+ if (subdir == NULL)
+ return lib_dir;
+
+ g_snprintf(subpath, sizeof(subpath),
+ "%s" G_DIR_SEPARATOR_S "%s", lib_dir, subdir);
+ return subpath;
}
const char *wpurple_locale_dir(void) {
static gboolean initialized = FALSE;
if (!initialized) {
- const char *inst_dir = wpurple_install_dir();
+#ifdef USE_WIN32_FHS
+ locale_dir = wpurple_install_relative_path(WIN32_FHS_LOCALEDIR);
+ initialized = TRUE;
+#else
+ const char *inst_dir = wpurple_bin_dir();
if (inst_dir != NULL) {
locale_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "locale", inst_dir);
initialized = TRUE;
} else {
return NULL;
}
+#endif
}
return locale_dir;
}
-const char *wpurple_data_dir(void) {
+const char *wpurple_home_dir(void) {
if (!app_data_dir) {
/* Set app data dir, used by purple_home_dir */
@@ -204,6 +311,38 @@ const char *wpurple_data_dir(void) {
return app_data_dir;
}
+const char *wpurple_sysconf_dir(void)
+{
+ static gboolean initialized = FALSE;
+
+ if (!initialized) {
+#ifdef USE_WIN32_FHS
+ sysconf_dir = wpurple_install_relative_path(WIN32_FHS_SYSCONFDIR);
+#else
+ sysconf_dir = wpurple_get_special_folder(CSIDL_COMMON_APPDATA);
+#endif
+ initialized = TRUE;
+ }
+
+ return sysconf_dir;
+}
+
+#if defined(USE_WIN32_FHS) && defined(SSL_CERTIFICATES_DIR)
+const char *
+wpurple_cert_dir(void)
+{
+ static gboolean initialized = FALSE;
+
+ if (initialized)
+ return sysconf_dir;
+
+ sysconf_dir = wpurple_install_relative_path(SSL_CERTIFICATES_DIR);
+ initialized = TRUE;
+
+ return sysconf_dir;
+}
+#endif
+
/* Miscellaneous */
gboolean wpurple_write_reg_string(HKEY rootkey, const char *subkey, const char *valname,
@@ -287,6 +426,52 @@ static gboolean _reg_read(HKEY reg_key, const char *valname, LPDWORD type, LPBYT
return (rv == ERROR_SUCCESS);
}
+gboolean wpurple_reg_val_exists(HKEY rootkey, const char *subkey, const char *valname)
+{
+ HKEY hkey;
+ LONG retv;
+ DWORD index;
+ wchar_t name_buffer[100];
+ BOOL exists = FALSE;
+ wchar_t *wc_valname = NULL;
+ wchar_t *wc_subkey;
+
+ if (subkey == NULL)
+ return FALSE;
+
+ wc_subkey = g_utf8_to_utf16(subkey, -1, NULL, NULL, NULL);
+ retv = RegOpenKeyExW(rootkey, wc_subkey, 0, KEY_ENUMERATE_SUB_KEYS, &hkey);
+ g_free(wc_subkey);
+
+ if (retv != ERROR_SUCCESS)
+ return FALSE;
+
+ if (valname[0] == '\0' || valname == NULL) {
+ RegCloseKey(hkey);
+ return TRUE;
+ }
+
+ wc_valname = g_utf8_to_utf16(valname, -1, NULL, NULL, NULL);
+ index = 0;
+ while (TRUE)
+ {
+ DWORD name_size = sizeof(name_buffer);
+ retv = RegEnumValueW(hkey, index++, name_buffer, &name_size,
+ NULL, NULL, NULL, NULL);
+ if (retv != ERROR_SUCCESS)
+ break;
+ name_size /= sizeof(wchar_t);
+ if (wcsncmp(name_buffer, wc_valname, name_size) == 0) {
+ exists = TRUE;
+ break;
+ }
+ }
+ g_free(wc_valname);
+
+ RegCloseKey(hkey);
+ return exists;
+}
+
gboolean wpurple_read_reg_dword(HKEY rootkey, const char *subkey, const char *valname, LPDWORD result) {
DWORD type;
@@ -328,17 +513,129 @@ char *wpurple_read_reg_string(HKEY rootkey, const char *subkey, const char *valn
return result;
}
+int wpurple_input_pipe(int pipefd[2])
+{
+ SOCKET sock_server, sock_client, sock_server_established;
+ struct sockaddr_in saddr_in;
+ struct sockaddr * const saddr_p = (struct sockaddr *)&saddr_in;
+ int saddr_len = sizeof(struct sockaddr_in);
+ u_long arg;
+ fd_set select_set;
+ char succ = 1;
+
+ sock_server = sock_client = sock_server_established = INVALID_SOCKET;
+
+ purple_debug_misc("wpurple", "wpurple_input_pipe(0x%x[%d,%d])\n",
+ (unsigned int)pipefd, pipefd[0], pipefd[1]);
+
+ /* create client and passive server sockets */
+ sock_server = socket(AF_INET, SOCK_STREAM, 0);
+ sock_client = socket(AF_INET, SOCK_STREAM, 0);
+ succ = (sock_server != INVALID_SOCKET || sock_client != INVALID_SOCKET);
+
+ /* set created sockets into nonblocking mode */
+ arg = 1;
+ succ = (succ &&
+ ioctlsocket(sock_server, FIONBIO, &arg) != SOCKET_ERROR);
+ arg = 1;
+ succ = (succ &&
+ ioctlsocket(sock_client, FIONBIO, &arg) != SOCKET_ERROR);
+
+ /* listen on server socket */
+ memset(&saddr_in, 0, saddr_len);
+ saddr_in.sin_family = AF_INET;
+ saddr_in.sin_port = 0;
+ saddr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ succ = (succ &&
+ bind(sock_server, saddr_p, saddr_len) != SOCKET_ERROR &&
+ listen(sock_server, 1) != SOCKET_ERROR &&
+ getsockname(sock_server, saddr_p, &saddr_len) != SOCKET_ERROR);
+
+ /* request a connection from client to server socket */
+ succ = (succ &&
+ connect(sock_client, saddr_p, saddr_len) == SOCKET_ERROR &&
+ WSAGetLastError() == WSAEWOULDBLOCK);
+
+ /* ensure, that server socket is readable */
+ if (succ)
+ {
+ FD_ZERO(&select_set);
+ FD_SET(sock_server, &select_set);
+ }
+ succ = (succ &&
+ select(0, &select_set, NULL, NULL, NULL) != SOCKET_ERROR &&
+ FD_ISSET(sock_server, &select_set));
+
+ /* accept (establish) connection from client socket */
+ if (succ)
+ {
+ sock_server_established =
+ accept(sock_server, saddr_p, &saddr_len);
+ succ = (sock_server_established != INVALID_SOCKET);
+ }
+
+ /* ensure, that client socket is writable */
+ if (succ)
+ {
+ FD_ZERO(&select_set);
+ FD_SET(sock_client, &select_set);
+ }
+ succ = (succ &&
+ select(0, NULL, &select_set, NULL, NULL) != SOCKET_ERROR &&
+ FD_ISSET(sock_client, &select_set));
+
+ /* set sockets into blocking mode */
+ arg = 0;
+ succ = (succ &&
+ ioctlsocket(sock_client, FIONBIO, &arg) != SOCKET_ERROR);
+ arg = 0;
+ succ = (succ &&
+ ioctlsocket(sock_server_established, FIONBIO, &arg)
+ != SOCKET_ERROR);
+
+ /* we don't need (passive) server socket anymore */
+ if (sock_server != INVALID_SOCKET)
+ closesocket(sock_server);
+
+ if (succ)
+ {
+ purple_debug_misc("wpurple",
+ "wpurple_input_pipe created pipe [%d,%d]\n",
+ sock_client, sock_server_established);
+ pipefd[0] = sock_client; /* for reading */
+ pipefd[1] = sock_server_established; /* for writing */
+ return 0;
+ }
+ else
+ {
+ purple_debug_error("wpurple", "wpurple_input_pipe failed\n");
+ if (sock_client != INVALID_SOCKET)
+ closesocket(sock_client);
+ if (sock_server_established != INVALID_SOCKET)
+ closesocket(sock_server_established);
+ errno = EMFILE;
+ return -1;
+ }
+}
+
void wpurple_init(void) {
WORD wVersionRequested;
WSADATA wsaData;
+#if !GLIB_CHECK_VERSION(2, 32, 0)
+ /* GLib threading system is automaticaly initialized since 2.32.
+ * For earlier versions, it have to be initialized before calling any
+ * Glib or GTK+ functions.
+ */
if (!g_thread_supported())
g_thread_init(NULL);
+#endif
- purple_debug_info("wpurple", "wpurple_init start\n");
- purple_debug_info("wpurple", "libpurple version: " DISPLAY_VERSION "\n");
+ if (purple_debug_is_verbose())
+ purple_debug_misc("wpurple", "wpurple_init start\n");
- purple_debug_info("wpurple", "Glib:%u.%u.%u\n",
+ purple_debug_info("wpurple", "libpurple version: " DISPLAY_VERSION "\n");
+ purple_debug_info("wpurple", "Glib: %u.%u.%u\n",
glib_major_version, glib_minor_version, glib_micro_version);
/* Winsock init */
@@ -354,7 +651,8 @@ void wpurple_init(void) {
WSACleanup();
}
- purple_debug_info("wpurple", "wpurple_init end\n");
+ if (purple_debug_is_verbose())
+ purple_debug_misc("wpurple", "wpurple_init end\n");
}
/* Windows Cleanup */
@@ -366,14 +664,20 @@ void wpurple_cleanup(void) {
WSACleanup();
g_free(app_data_dir);
- g_free(install_dir);
+ g_free(bin_dir);
+ g_free(data_dir);
g_free(lib_dir);
g_free(locale_dir);
+ g_free(sysconf_dir);
+ g_free(cert_dir);
app_data_dir = NULL;
- install_dir = NULL;
+ bin_dir = NULL;
+ data_dir = NULL;
lib_dir = NULL;
locale_dir = NULL;
+ sysconf_dir = NULL;
+ cert_dir = NULL;
libpurpledll_hInstance = NULL;
}
diff --git a/libpurple/win32/win32dep.h b/libpurple/win32/win32dep.h
index 673b7d7abc..d4311ad519 100644
--- a/libpurple/win32/win32dep.h
+++ b/libpurple/win32/win32dep.h
@@ -22,6 +22,9 @@
*/
#ifndef _WIN32DEP_H_
#define _WIN32DEP_H_
+
+#include <config.h>
+
#include <winsock2.h>
#include <windows.h>
#include <shlobj.h>
@@ -54,18 +57,27 @@ typedef struct {
**/
/* Windows helper functions */
FARPROC wpurple_find_and_loadproc(const char *dllname, const char *procedure);
+gboolean wpurple_reg_val_exists(HKEY rootkey, const char *subkey, const char *valname);
gboolean wpurple_read_reg_dword(HKEY rootkey, const char *subkey, const char *valname, LPDWORD result);
char *wpurple_read_reg_string(HKEY rootkey, const char *subkey, const char *valname); /* needs to be g_free'd */
gboolean wpurple_write_reg_string(HKEY rootkey, const char *subkey, const char *valname, const char *value);
char *wpurple_escape_dirsep(const char *filename); /* needs to be g_free'd */
GIOChannel *wpurple_g_io_channel_win32_new_socket(int socket); /* Until we get the post-2.8 glib win32 giochannel implementation working, use the thread-based one */
+/* Simulate unix pipes by creating a pair of connected sockets */
+int wpurple_input_pipe(int pipefd[2]);
+
/* Determine Purple paths */
gchar *wpurple_get_special_folder(int folder_type); /* needs to be g_free'd */
-const char *wpurple_install_dir(void);
-const char *wpurple_lib_dir(void);
-const char *wpurple_locale_dir(void);
+const char *wpurple_bin_dir(void);
const char *wpurple_data_dir(void);
+const char *wpurple_lib_dir(const char *subdir);
+const char *wpurple_locale_dir(void);
+const char *wpurple_home_dir(void);
+const char *wpurple_sysconf_dir(void);
+#if defined(USE_WIN32_FHS) && defined(SSL_CERTIFICATES_DIR)
+const char *wpurple_cert_dir(void);
+#endif
/* init / cleanup */
void wpurple_init(void);
@@ -73,17 +85,6 @@ void wpurple_cleanup(void);
long wpurple_get_tz_offset(void);
-/*
- * MACROS
- */
-
-/*
- * Purple specific
- */
-#define DATADIR wpurple_install_dir()
-#define LIBDIR wpurple_lib_dir()
-#define LOCALEDIR wpurple_locale_dir()
-
#ifdef __cplusplus
}
#endif /* __cplusplus */