diff options
author | Daniel Atallah <datallah@pidgin.im> | 2014-12-16 18:18:42 -0500 |
---|---|---|
committer | Daniel Atallah <datallah@pidgin.im> | 2014-12-16 18:18:42 -0500 |
commit | 8233ce84d8795a21f7a63cfb9c71dc714df60f35 (patch) | |
tree | e171b094cee58f3f9e9d6ebb628239e6a593e767 /libpurple/win32 | |
parent | dfcf0fb70d02e1cb172855ec3fab5a803d63fbdb (diff) | |
parent | fb9a018a3aca7f18147a2f418bd9468fd9ff42ee (diff) | |
download | pidgin-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.c | 10 | ||||
-rw-r--r-- | libpurple/win32/global.mak | 65 | ||||
-rw-r--r-- | libpurple/win32/libc_interface.c | 28 | ||||
-rw-r--r-- | libpurple/win32/libc_interface.h | 19 | ||||
-rw-r--r-- | libpurple/win32/libc_internal.h | 3 | ||||
-rw-r--r-- | libpurple/win32/libpurplerc.rc.in | 13 | ||||
-rw-r--r-- | libpurple/win32/rules.mak | 11 | ||||
-rw-r--r-- | libpurple/win32/targets.mak | 19 | ||||
-rw-r--r-- | libpurple/win32/win32dep.c | 344 | ||||
-rw-r--r-- | libpurple/win32/win32dep.h | 29 |
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 */ |