diff options
207 files changed, 7439 insertions, 10340 deletions
diff --git a/.gitignore b/.gitignore index 137204b8..63675ee5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ # Unix generated files .deps/ .libs/ +.dirstamp Makefile Makefile.in aclocal.m4 @@ -69,6 +70,7 @@ stamp-h1 *.po~ *.pot *.patch +src/**/*.plist # Win32 generated files plugins/wmpa/wmpa_h.h plugins/wmpa/wmpa_i.c @@ -85,6 +87,7 @@ resource.h *.sdf *.suo *.user +*.exe #OSX osx/HexChat.app osx/.HexChat.app diff --git a/.travis.yml b/.travis.yml index f5f5d4b7..5f61475d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,16 @@ language: c -compiler: - - gcc - - clang +compiler: clang before_script: - sudo apt-get update - sudo apt-get build-dep -qq xchat - - sudo apt-get install -qq libnotify-dev libproxy-dev libpci-dev libcanberra-dev monodevelop gnome-common + - sudo apt-get install -qq libnotify-dev libproxy-dev libpci-dev libcanberra-dev monodevelop intltool script: - - ./autogen.sh - - ./configure --enable-textfe --with-theme-manager + - ./autogen.sh --enable-textfe --with-theme-manager --enable-static-analysis - make V=1 -j$(nproc) notifications: irc: channels: "chat.freenode.net#hexchat-devel" - template: "Build #%{build_number} (%{commit}) by %{author}: %{message}" + template: "Build %{build_url} (%{commit} in %{branch}) by %{author}: %{message}" on_success: change matrix: fast_finish: true diff --git a/autogen.sh b/autogen.sh index b1e4db22..d669a37b 100755 --- a/autogen.sh +++ b/autogen.sh @@ -4,19 +4,24 @@ srcdir=`dirname $0` test -z "$srcdir" && srcdir=. -NOCONFIGURE=1 -PKG_NAME="hexchat" - (test -f $srcdir/src/common/hexchat.c) || { - echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" - echo " top-level $PKG_NAME directory" + echo -n "**Error**: Directory "\`$srcdir\'" does not look like the top-level directory" exit 1 } -which gnome-autogen.sh || { - echo "You need to install gnome-common" - exit 1 -} +aclocal --install -I m4 || exit 1 +glib-gettextize --force --copy || exit 1 +intltoolize --force --copy --automake || exit 1 +autoreconf --force --install -Wno-portability || exit 1 + +if [ "$NOCONFIGURE" = "" ]; then + $srcdir/configure "$@" || exit 1 -. gnome-autogen.sh + if [ "$1" = "--help" ]; then exit 0 else + echo "Now type \`make\' to compile" || exit 1 + fi +else + echo "Skipping configure process." +fi +set +x diff --git a/configure.ac b/configure.ac index 61feba80..1c186016 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT([HexChat],[2.11.0]) -AC_PREREQ([2.60]) +AC_PREREQ([2.64]) AC_COPYRIGHT([Copyright (C) 1998-2010 Peter Zelezny]) AC_CONFIG_HEADERS([config.h]) @@ -10,19 +10,25 @@ AC_CONFIG_SRCDIR([configure.ac]) AC_CONFIG_MACRO_DIR([m4]) -AM_INIT_AUTOMAKE([1.11 dist-bzip2 subdir-objects no-define foreign]) +AM_INIT_AUTOMAKE([1.11.1 dist-bzip2 subdir-objects no-define foreign]) AM_SILENT_RULES([yes]) +AX_IS_RELEASE([minor-version]) +AX_CHECK_ENABLE_DEBUG([yes]) +AX_REQUIRE_DEFINED([PKG_PROG_PKG_CONFIG]) + AC_USE_SYSTEM_EXTENSIONS -AM_MAINTAINER_MODE +AM_MAINTAINER_MODE([enable]) AC_PROG_CC AM_PROG_CC_C_O AC_PROG_CPP +AC_PROG_OBJC AM_PROG_AS AM_PROG_AR -AM_DISABLE_STATIC -AC_PROG_LIBTOOL +LT_PREREQ([2.2.6]) +LT_INIT([disable-static]) AC_PATH_PROG(MDTOOL, mdtool, no) +PKG_PROG_PKG_CONFIG dnl ----------------------------------------------------------- dnl Language Support @@ -38,14 +44,12 @@ AH_VERBATIM([OLD_PERL],[#undef OLD_PERL]) AH_VERBATIM([PREFIX],[#undef PREFIX]) AH_VERBATIM([HEXCHATLIBDIR],[#undef HEXCHATLIBDIR]) AH_VERBATIM([HEXCHATSHAREDIR],[#undef HEXCHATSHAREDIR]) -AH_VERBATIM([SOCKS],[#undef SOCKS]) -AH_VERBATIM([USE_MSPROXY],[#undef USE_MSPROXY]) AH_VERBATIM([USE_LIBPROXY],[#undef USE_LIBPROXY]) +AH_VERBATIM([HAVE_LIBPCI],[#undef HAVE_LIBPCI]) AH_VERBATIM([HAVE_ISO_CODES],[#undef HAVE_ISO_CODES]) AH_VERBATIM([HAVE_GTK_MAC],[#undef HAVE_GTK_MAC]) AH_VERBATIM([USE_LIBNOTIFY],[#undef USE_LIBNOTIFY]) AH_VERBATIM([USE_LIBCANBERRA],[#undef USE_LIBCANBERRA]) -AH_VERBATIM([USE_IPV6],[#undef USE_IPV6]) AH_VERBATIM([USE_OPENSSL],[#undef USE_OPENSSL]) AH_VERBATIM([USE_PLUGIN],[#undef USE_PLUGIN]) AH_VERBATIM([USE_SIGACTION],[#undef USE_SIGACTION]) @@ -55,37 +59,39 @@ AH_VERBATIM([socklen_t],[#undef socklen_t]) AH_VERBATIM([USE_DBUS],[#undef USE_DBUS]) AC_PATH_PROG(sedpath, sed) -if test "_$sedpath" = _; then +AS_IF([test "_$sedpath" = _], [ AC_MSG_ERROR(Cannot find sed: I need it!) -fi +]) AC_PATH_PROG(unamepath, uname) -if test "_$unamepath" = _; then +AS_IF([test "_$unamepath" = _], [ system="unknown" -else +], [ AC_MSG_CHECKING(system type) system=`$unamepath -s` AC_MSG_RESULT($system) - if test "$system" = "Linux"; then + AS_IF([test "$system" = "Linux"], [ AC_DEFINE(USING_LINUX) - fi - if test "$system" = "FreeBSD"; then + ], [test "$system" = "FreeBSD"], [ AC_DEFINE(USING_FREEBSD) - fi -fi + ]) +]) + +platform_win32=no +platform_osx=no +AS_CASE([$host_os], + [*mingw*|*cygwin*|*msys*], [ + platform_win32=yes + ], + [darwin*], [ + platform_osx=yes + ] +) dnl ********************************************************************* dnl ** configure switches *********************************************** dnl ********************************************************************* -AC_ARG_ENABLE(socks, - [AS_HELP_STRING([--enable-socks],[link with SOCKS5 library (default: no)])], - socks=$enableval, socks=no) - -AC_ARG_ENABLE(ipv6, - [AS_HELP_STRING([--disable-ipv6],[disable IPv6])], - ipv6=$enableval, ipv6=yes) - AC_ARG_ENABLE(openssl, [AS_HELP_STRING([--enable-openssl[=PATH]],[enable use of openSSL])], openssl=$enableval, openssl=yes) @@ -143,10 +149,6 @@ AC_ARG_ENABLE(libcanberra, [AS_HELP_STRING([--disable-libcanberra],[disable libcanberra support])], libcanberra=$enableval, libcanberra=yes) -AC_ARG_ENABLE(ntlm, - [AS_HELP_STRING([--enable-ntlm],[enable Microsoft\'s NTLM auth (libntlm) library support (default: no)])], - ntlm=$enableval, ntlm=no) - AC_ARG_ENABLE(libproxy, [AS_HELP_STRING([--disable-libproxy],[disable libproxy support (default: auto)])], libproxy=$enableval, libproxy=auto) @@ -155,9 +157,9 @@ AC_ARG_ENABLE(isocodes, [AS_HELP_STRING([--disable-isocodes],[disable iso-codes with spell-check])], isocodes=$enableval, isocodes=yes) -AC_ARG_ENABLE(minimal-flags, - [AS_HELP_STRING([--enable-minimal-flags],[only add those CFLAGS that are really needed or not intrusive (default: no)])], - minimalflags=$enableval, minimalflags=no) +AC_ARG_ENABLE(static-analysis, + [AS_HELP_STRING([--enable-static-analysis],[if using clang run static analysis during build (default: no)])], + analyze=$enableval, analyze=no) AC_ARG_WITH(theme-manager, [AS_HELP_STRING([--with-theme-manager],[compile theme manager (needs monodevelop, default: off)])], @@ -168,174 +170,141 @@ AC_ARG_WITH(theme-manager, dnl ********************************************************************* dnl ** THEME-MANAGER **************************************************** dnl ********************************************************************* -if test "x$theme_manager" != "xno" ; then - if test "x$MDTOOL" = "xno"; then +AS_IF([test "x$theme_manager" != "xno"], [ + AS_IF([test "x$MDTOOL" = "xno"], [ AC_MSG_ERROR([No "mdtool" found, you need to install monodevelop!]) - fi -fi + ]) +]) dnl ********************************************************************* dnl ** GLIB ************************************************************* dnl ********************************************************************* -AM_PATH_GLIB_2_0(2.28.0, glib=yes, glib=no) -if test "$glib" = no; then - AC_MSG_ERROR(Cannot find GLib!) -fi - -PKG_CHECK_MODULES([GOBJECT], [gobject-2.0], [], [AC_MSG_ERROR(Cannot find gobject-2.0!)]) -PKG_CHECK_MODULES([GIO], [gio-2.0], [], [AC_MSG_ERROR(Cannot find gio-2.0!)]) -PKG_CHECK_MODULES([GMODULE], [gmodule-2.0], [], [AC_MSG_ERROR(Cannot find gmodule-2.0!)]) - -COMMON_CFLAGS="$GLIB_CFLAGS $GIO_CFLAGS $GOBJECT_CFLAGS $GMODULE_CFLAGS -DG_DISABLE_SINGLE_INCLUDES" -COMMON_LIBS="$GLIB_LIBS $GIO_LIBS $GOBJECT_LIBS $GMODULE_LIBS" +AM_PATH_GLIB_2_0([2.32.0], [], [AC_MSG_ERROR([Glib not found!])], [gmodule gobject gio]) +COMMON_CFLAGS="$GLIB_CFLAGS -DG_DISABLE_SINGLE_INCLUDES" +COMMON_LIBS="$GLIB_LIBS" +AC_DEFINE([GLIB_VERSION_MIN_REQUIRED], [GLIB_VERSION_2_32], [Dont warn using older APIs]) +AC_DEFINE([GLIB_VERSION_MAX_ALLOWED], [GLIB_VERSION_2_32], [Prevents using newer APIs]) dnl ********************************************************************* dnl ** GTK ************************************************************** dnl ********************************************************************* -# we might get undefined macro without this test -if test "$gtkfe" = yes ; then - AM_PATH_GTK_2_0(2.24.0, havegtk=yes, havegtk=no) - - if test "$havegtk" = no; then +AS_IF([test "$gtkfe" = yes], [ + PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.24.0], [ + GUI_LIBS="$GUI_LIBS $GTK_LIBS" + GUI_CFLAGS="$GUI_CFLAGS $GTK_CFLAGS -DGDK_PIXBUF_DISABLE_SINGLE_INCLUDES -DGTK_DISABLE_SINGLE_INCLUDES -DGTK_DISABLE_DEPRECATED" + ], [ gtkfe=no - echo - echo Cannot find GTK\! Not building GTK FrontEnd. - echo - fi -fi - -GUI_LIBS="$GUI_LIBS $GTK_LIBS" -GUI_CFLAGS="$GUI_CFLAGS $GTK_CFLAGS -DG_DISABLE_SINGLE_INCLUDES -DGDK_PIXBUF_DISABLE_SINGLE_INCLUDES -DGTK_DISABLE_SINGLE_INCLUDES -DGTK_DISABLE_DEPRECATED" + ]) +]) dnl ********************************************************************* dnl ** MAC_INTEGRATION ************************************************** dnl ********************************************************************* _gdk_tgt=`$PKG_CONFIG --variable=target gdk-2.0` -if test "x$_gdk_tgt" = xquartz; then - PKG_CHECK_MODULES(GTK_MAC, gtk-mac-integration-gtk2, [ - GUI_LIBS="$GUI_LIBS $GTK_MAC_LIBS" - GUI_CFLAGS="$GUI_CFLAGS $GTK_MAC_CFLAGS" - AC_DEFINE(HAVE_GTK_MAC) - ]) -fi +AS_IF([test "x$_gdk_tgt" = xquartz], [ + PKG_CHECK_MODULES(GTK_MAC, gtk-mac-integration-gtk2, [ + GUI_LIBS="$GUI_LIBS $GTK_MAC_LIBS" + GUI_CFLAGS="$GUI_CFLAGS $GTK_MAC_CFLAGS" + AC_DEFINE(HAVE_GTK_MAC) + ]) +]) dnl ********************************************************************* dnl ** PERL ************************************************************* dnl ********************************************************************* -if test "$perl" = yes; then +AS_IF([test "$perl" = yes], [ AC_MSG_CHECKING(for plugin interface used by Perl) - if test "$plugin" = yes; then + AS_IF([test "$plugin" = yes], [ AC_MSG_RESULT([yes]) - AC_PATH_PROG(perlpath, perl) - AC_MSG_CHECKING(for Perl compile flags) - PERL_CFLAGS=`$perlpath -MExtUtils::Embed -e ccopts 2>/dev/null` - if test "_$PERL_CFLAGS" = _ ; then - AC_MSG_RESULT([not found, building without perl.]) + + AX_PERL_EXT_FLAGS([PERL_CFLAGS], [PERL_LDFLAGS]) + original_cflags="$CFLAGS" + original_ldflags="$LDFLAGS" + CFLAGS="$PERL_CFLAGS" + LDFLAGS="$PERL_LDFLAGS" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #define PERL_NO_INLINE_FUNCTIONS + #include <EXTERN.h> + #include <perl.h> + ]], [[]])],[perl_is_usable=yes],[perl_is_usable=no]) + CFLAGS="$original_cflags" + LDFLAGS="$original_ldflags" + AS_IF([test "$perl_is_usable" = "no"], [ + AC_MSG_WARN([perl test failed to compile, disabling]) perl=no - else - PERL_LDFLAGS=`$perlpath -MExtUtils::Embed -e ldopts |$sedpath 's/-lgdbm //'` - PERL_LDFLAGS=`echo $PERL_LDFLAGS |$sedpath 's/-ldb //'` - PERL_LDFLAGS=`echo $PERL_LDFLAGS |$sedpath 's/-lndbm //'` - if test "$system" = "Linux"; then - PERL_LDFLAGS=`echo $PERL_LDFLAGS |$sedpath 's/-lnsl //'` - PERL_LDFLAGS=`echo $PERL_LDFLAGS |$sedpath 's/-lposix //'` - fi - PERL_LDFLAGS=`echo $PERL_LDFLAGS |$sedpath 's/-lc //'` - AC_MSG_RESULT(ok) - - AC_MSG_CHECKING(for perl >= 5.8.0) - PERL_VER=`$perlpath -e 'print $]>= 5.008?"yes":"no"'` - if test "$PERL_VER" = "yes"; then - original_cflags="$CFLAGS" - original_ldflags="$LDFLAGS" - CFLAGS="$PERL_CFLAGS" - LDFLAGS="$PERL_LDFLAGS" - AC_TRY_LINK([#include <EXTERN.h> - #include <perl.h>], [], perl_is_usable=yes, perl_is_usable=no) - CFLAGS="$original_cflags" - LDFLAGS="$original_ldflags" - if test x$perl_is_usable = xno ; then - AC_MSG_RESULT(no) - perl=no - else - AC_MSG_RESULT(yes) - AC_MSG_CHECKING(if perl plugin will be backward compatible) - if test "$perl_old" = "yes"; then - AC_MSG_RESULT(yes) - AC_DEFINE(OLD_PERL) - else - AC_MSG_RESULT(no) - fi - fi - else - AC_MSG_RESULT(no) - echo "perl version too old, building without perl." - perl=no - fi - fi - else + ], [ + AC_MSG_CHECKING([if perl plugin will be backward compatible]) + AS_IF([test "$perl_old" = "yes"], [ + AC_MSG_RESULT([yes]) + AC_DEFINE(OLD_PERL) + ], [ + AC_MSG_RESULT([no]) + ]) + ]) + ], [ AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option for Perl]) perl=no - fi -fi + ]) +]) dnl ********************************************************************* dnl ** PYTHON *********************************************************** dnl ********************************************************************* -if test "x$python" != xno ; then +AS_IF([test "x$python" != xno], [ AC_MSG_CHECKING(for plugin interface used by Python) - if test "$plugin" = yes; then + AS_IF([test "$plugin" = yes], [ AC_MSG_RESULT([yes]) - case $python in + AS_CASE([$python], dnl set python2 default here - python2) + [python2], [ PKG_CHECK_MODULES([PY], [python-2.7], [PY_VER="`$PKG_CONFIG --modversion python-2.7`"], [true]) - ;; + ], dnl set python3 default here - python3) + [python3], [ PKG_CHECK_MODULES([PY], [python-3.4], [PY_VER="`$PKG_CONFIG --modversion python-3.4`"], [true]) - if test "$PY_VER" = "" ; then + AS_IF([test "$PY_VER" = ""], [ PKG_CHECK_MODULES([PY], [python-3.3], [PY_VER="`$PKG_CONFIG --modversion python-3.3`"], [true]) - fi - ;; + ]) + ], dnl add broken versions here - python2.5|python2.6|python3.1|python3.2) - AC_MSG_WARN(Unsupported Python version ${python}!);; - python*) + [python2.5|python2.6|python3.1|python3.2], [ + AC_MSG_WARN(Unsupported Python version ${python}!) + ], + [python*], [ python="python-${python#python}" # stay posix compliant PKG_CHECK_MODULES([PY], [${python}], [PY_VER="`$PKG_CONFIG --modversion ${python}`"], [AC_MSG_WARN(Cannot find "${python}.pc"!)]) - ;; - *) + ],[ AC_MSG_WARN(Unsupported Python ${python}!) - esac + ] + ) AC_MSG_CHECKING(Python version) - if test "$PY_VER"; then + AS_IF([test "$PY_VER"], [ AC_MSG_RESULT($PY_VER) python="python-${PY_VER}" - else + ], [ AC_MSG_RESULT(Not found) python=no - fi - else + ]) + ], [ AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option for Python]) python=no - fi -fi + ]) +]) dnl ********************************************************************* dnl ** IPv6 ************************************************************* @@ -351,182 +320,175 @@ AC_CHECK_FUNC(select, , AC_MSG_WARN(i can not find select. you might need to help me))))))) AC_CHECK_LIB(socket, select) -if test "$ipv6" = yes; then - AC_CHECK_FUNCS(getaddrinfo, have_getaddrinfo=yes) - AC_MSG_CHECKING(whether to enable IPv6 support) - if test "$have_getaddrinfo" = yes; then - AC_MSG_RESULT(yes) - AC_DEFINE(USE_IPV6) - else - ipv6=no - AC_MSG_RESULT(no) - fi -fi +AC_CHECK_FUNCS(getaddrinfo, have_getaddrinfo=yes) +AC_MSG_CHECKING(whether IPv6 is supported) +AS_IF([test "$have_getaddrinfo" = yes], [ + AC_MSG_RESULT(yes) +], [ + AC_MSG_RESULT(no) + AC_MSG_ERROR(ipv6 support not found!) +]) dnl ********************************************************************* dnl ** OPENSSL ********************************************************** dnl ********************************************************************* -retry=no -if test "$openssl" != no; then - AC_MSG_CHECKING(for openssl through pkg-config) - if $PKG_CONFIG openssl --exists; then - CPPFLAGS="$CPPFLAGS `$PKG_CONFIG openssl --cflags`" - LIBS="$LIBS `$PKG_CONFIG openssl --libs`" + +AS_IF([test "$openssl" != no], [ + PKG_CHECK_MODULES(OPENSSL, [openssl], [ AC_DEFINE(USE_OPENSSL) - AC_MSG_RESULT(yes) openssl=yes - else - AC_MSG_RESULT(no) - retry=yes - fi -fi - -if test "$retry" = "yes"; then - unset openssl_path ac_cv_lib_ssl_SSL_new ac_cv_header_openssl_ssl_h - if test "$openssl" != yes; then - openssl_path=$openssl - fi - openssl=no - SAVED_LIBS=$LIBS - LIBS="$LIBS -lcrypto" - if test -n "$openssl_path"; then - LIBS="-L$openssl_path/lib $LIBS" - fi - AC_CHECK_LIB(ssl, SSL_new, have_openssl=yes) - LIBS=$SAVED_LIBS - if test "$have_openssl" = yes; then - SAVED_CPPFLAGS=$CPPFLAGS - if test -n "$openssl_path"; then - CPPFLAGS="-I$openssl_path/include $CPPFLAGS" - fi - AC_CHECK_HEADERS(openssl/ssl.h, have_openssl_h=yes) - if test "$have_openssl_h" = yes; then - openssl=yes - AC_DEFINE(USE_OPENSSL) - LIBS="$LIBS -lssl -lcrypto" - if test -n "$openssl_path"; then - LIBS="-L$openssl_path/lib $LIBS" - fi - else - CPPFLAGS=$SAVED_CPPFLAGS - fi - fi -fi + COMMON_LIBS="$COMMON_LIBS $OPENSSL_LIBS" + COMMON_CFLAGS="$COMMON_CFLAGS $OPENSSL_CFLAGS" + ], [ + unset openssl_path ac_cv_lib_ssl_SSL_new ac_cv_header_openssl_ssl_h + AS_IF([test "$openssl" != yes], [ + openssl_path=$openssl + ]) + openssl=no + OPENSSL_LIBS="-lcrypto" + AS_IF([test -n "$openssl_path"], [ + OPENSSL_LIBS="-L$openssl_path/lib $OPENSSL_LIBS" + ]) + SAVED_LIBS=$LIBS + LIBS="$LIBS $OPENSSL_LIBS" + AC_CHECK_LIB(ssl, SSL_new, [ + AS_IF([test -n "$openssl_path"], [ + OPENSSL_CFLAGS="-I$openssl_path/include" + ]) + SAVED_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS $OPENSSL_CFLAGS" + AC_CHECK_HEADERS(openssl/ssl.h, [ + openssl=yes + AC_DEFINE(USE_OPENSSL) + OPENSSL_LIBS="$OPENSSL_LIBS -lssl" + + COMMON_LIBS="$COMMON_LIBS $OPENSSL_LIBS" + COMMON_CFLAGS="$COMMON_CFLAGS $OPENSSL_CFLAGS" + ]) + CFLAGS=$SAVED_CFLAGS + ]) + LIBS=$SAVED_LIBS + ]) +]) dnl ********************************************************************* dnl ** LIBPROXY ********************************************************* dnl ********************************************************************* -if test "x$libproxy" = "xyes" -o "x$libproxy" = "xauto" ; then +AS_IF([test "x$libproxy" = "xyes" -o "x$libproxy" = "xauto"], [ PKG_CHECK_MODULES([LIBPROXY], [libproxy-1.0], [ COMMON_LIBS="$COMMON_LIBS $LIBPROXY_LIBS" COMMON_CFLAGS="$COMMON_CFLAGS $LIBPROXY_CFLAGS" AC_DEFINE(USE_LIBPROXY) libproxy=yes ], [ - if test "x$libproxy" = "xyes" ; then + AS_IF([test "x$libproxy" = "xyes"], [ AC_MSG_ERROR(Cannot find libproxy!) - fi + ]) libproxy=no ]) -else +], [ libproxy=no -fi +]) dnl ********************************************************************* dnl ** PLUGIN *********************************************************** dnl ********************************************************************* -if test "$plugin" = yes; then +AS_IF([test "$plugin" = yes], [ AC_DEFINE(USE_PLUGIN) -fi + PLUGIN_LDFLAGS="-avoid-version" + AS_IF([test "$platform_win32" = yes], [ + PLUGIN_LDFLAGS="$PLUGIN_LDFLAGS -no-undefined" + ]) +]) dnl ********************************************************************* dnl ** Checksum ********************************************************* dnl ********************************************************************* -if test "$checksum" != "no"; then +AS_IF([test "$checksum" != "no"], [ checksum=no AC_MSG_CHECKING(for plugin interface used by Checksum) - if test "$plugin" = yes; then + AS_IF([test "$plugin" = yes], [ + checksum=yes AC_MSG_RESULT([yes]) - AC_MSG_CHECKING(for OpenSSL used by Checksum) - if test "$openssl" = yes; then - checksum=yes - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([OpenSSL cannot be found, use the --enable-openssl option]) - fi - else + ], [ AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option]) - fi -fi + ]) +]) dnl ********************************************************************* dnl ** DO AT ************************************************************ dnl ********************************************************************* -if test "$doat" != "no"; then +AS_IF([test "$doat" != "no"], [ AC_MSG_CHECKING(for plugin interface used by Do At) doat=no - if test "$plugin" = yes; then + AS_IF([test "$plugin" = yes], [ doat=yes AC_MSG_RESULT([yes]) - else + ], [ AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option for Do At]) - fi -fi + ]) +]) dnl ********************************************************************* dnl ** FiSHLiM ********************************************************** dnl ********************************************************************* -if test "$fishlim" != "no"; then +AS_IF([test "$fishlim" != "no"], [ fishlim=no AC_MSG_CHECKING(for plugin interface used by FiSHLiM) - if test "$plugin" = yes; then + AS_IF([test "$plugin" = yes], [ AC_MSG_RESULT([yes]) AC_MSG_CHECKING(for OpenSSL used by FiSHLiM) - if test "$openssl" = yes; then + AS_IF([test "$openssl" = yes], [ fishlim=yes AC_MSG_RESULT([yes]) - else + ], [ AC_MSG_RESULT([OpenSSL cannot be found, use the --enable-openssl option]) - fi - else + ]) + ], [ AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option]) - fi -fi + ]) +]) dnl ********************************************************************* dnl ** SYSINFO ********************************************************** dnl ********************************************************************* -if test "$sysinfo" != "no"; then +AS_IF([test "$sysinfo" != "no"], [ AC_MSG_CHECKING(for plugin interface used by SysInfo) - if test "$plugin" = yes; then + AS_IF([test "$plugin" = yes], [ AC_MSG_RESULT([yes]) - PKG_CHECK_MODULES(LIBPCI, libpci >= 3.0.0, [sysinfo=yes], [sysinfo=no]) - else + AS_IF([test "$platform_osx" = yes], [ + sysinfo=yes + ], [ + PKG_CHECK_MODULES(LIBPCI, libpci >= 3.0.0, [ + sysinfo=yes + AC_DEFINE(HAVE_LIBPCI) + ], [sysinfo=no]) + ]) + ], [ AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option for SysInfo]) sysinfo=no - fi -fi + ]) +]) dnl ####################################################################### dnl # Check for DBUS libraries dnl ####################################################################### -if test "x$dbus" = "xyes" ; then +AS_IF([test "x$dbus" = "xyes"], [ PKG_CHECK_MODULES(DBUS, [dbus-1 >= 0.60 dbus-glib-1 >= 0.60 gthread-2.0], dbus=yes, [ dbus=no ]) AC_PATH_PROG(DBUS_BINDING_TOOL, dbus-binding-tool, no) - AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal, no) - if test "x$DBUS_BINDING_TOOL" = "xno" || test "x$GLIB_GENMARSHAL" = "xno" || test "x$dbus" = "xno" ; then + AS_IF([test "x$DBUS_BINDING_TOOL" = "xno" || test "x$dbus" = "xno"], [ dbus="no" - else + ], [ COMMON_LIBS="$COMMON_LIBS $DBUS_LIBS" COMMON_CFLAGS="$COMMON_CFLAGS $DBUS_CFLAGS" AC_DEFINE(USE_DBUS) @@ -534,44 +496,44 @@ if test "x$dbus" = "xyes" ; then AS_AC_EXPAND(DBUS_SERVICES_DIR, "$datadir/dbus-1/services") AC_SUBST(DBUS_SERVICES_DIR) AC_DEFINE_UNQUOTED(DBUS_SERVICES_DIR, "$DBUS_SERVICES_DIR", [Where services dir for DBUS is]) - fi -fi + ]) +]) dnl ********************************************************************* dnl ** LIBNOTIFY ******************************************************** dnl ********************************************************************* -if test "x$libnotify" = "xyes" ; then +AS_IF([test "x$libnotify" = "xyes"], [ PKG_CHECK_MODULES(LIBNOTIFY, libnotify >= 0.4, [], [ libnotify=no ]) - if test "$libnotify" != "no" ; then + AS_IF([test "$libnotify" != "no"], [ GUI_LIBS="$GUI_LIBS $LIBNOTIFY_LIBS" GUI_CFLAGS="$GUI_CFLAGS $LIBNOTIFY_CFLAGS" AC_DEFINE(USE_LIBNOTIFY) - fi -fi + ]) +]) dnl ********************************************************************* dnl ** LIBCANBERRA ****************************************************** dnl ********************************************************************* -if test "x$libcanberra" = "xyes" ; then +AS_IF([test "x$libcanberra" = "xyes"], [ PKG_CHECK_MODULES(LIBCANBERRA, libcanberra >= 0.22, [], [ libcanberra=no ]) - if test "$libcanberra" != "no" ; then + AS_IF([test "$libcanberra" != "no"], [ COMMON_LIBS="$COMMON_LIBS $LIBCANBERRA_LIBS" COMMON_CFLAGS="$COMMON_CFLAGS $LIBCANBERRA_CFLAGS" AC_DEFINE(USE_LIBCANBERRA) - fi -fi + ]) +]) dnl ********************************************************************* dnl ** SPELL ************************************************************ dnl ********************************************************************* -if test "x$isocodes" = "xyes" ; then +AS_IF([test "x$isocodes" = "xyes"], [ PKG_CHECK_MODULES(ISOCODES, "iso-codes", [ iso_codes_prefix=`$PKG_CONFIG --variable=prefix iso-codes 2>/dev/null || echo /usr` AC_MSG_NOTICE([iso-codes prefix: $iso_codes_prefix]) @@ -582,7 +544,18 @@ if test "x$isocodes" = "xyes" ; then isocodes=no AC_MSG_WARN(iso-codes not found!) ]) -fi +]) + +dnl ********************************************************************* +dnl ** Static Analysis ************************************************** +dnl ********************************************************************* + +AS_IF([test "x$analyze" = "xyes"], [ + AS_IF([test "$CC" != "clang"], [ + AC_MSG_WARN(CC is not clang for static analysis) + analyze=no + ]) +]) dnl ********************************************************************* dnl ** CONDITIONALS ***************************************************** @@ -591,7 +564,6 @@ dnl ********************************************************************* AM_CONDITIONAL(USE_OPENSSL, test "x$openssl" = "xyes") AM_CONDITIONAL(USE_LIBNOTIFY, test "x$libnotify" = "xyes") AM_CONDITIONAL(USE_LIBCANBERRA, test "x$libcanberra" = "xyes") -AM_CONDITIONAL(USE_MSPROXY, test "x$ntlm" = "xyes") AM_CONDITIONAL(DO_TEXT, test "x$textfe" = "xyes") AM_CONDITIONAL(DO_GTK, test "x$gtkfe" = "xyes") AM_CONDITIONAL(DO_PERL, test "x$perl" = "xyes") @@ -601,128 +573,30 @@ AM_CONDITIONAL(DO_CHECKSUM, test "x$checksum" = "xyes") AM_CONDITIONAL(DO_DOAT, test "x$doat" = "xyes") AM_CONDITIONAL(DO_FISHLIM, test "x$fishlim" = "xyes") AM_CONDITIONAL(DO_SYSINFO, test "x$sysinfo" = "xyes") +AM_CONDITIONAL(DO_STATIC_ANALYSIS, test "x$analyze" = "xyes") AM_CONDITIONAL(USE_DBUS, test "x$dbus" = "xyes") AM_CONDITIONAL(HAVE_ISO_CODES, test "x$isocodes" = "xyes") +AM_CONDITIONAL(HAVE_GTK_MAC, test "x$_gdk_tgt" = xquartz) AM_CONDITIONAL(WITH_TM, test "x$theme_manager" != "xno") +AM_CONDITIONAL(PLATFORM_OSX, test "x$platform_osx" == "xyes") dnl ********************************************************************* -dnl ** SOCKS5 *********************************************************** +dnl ** CFLAGS *********************************************************** dnl ********************************************************************* -if test "$socks" = yes; then - socks=no - AC_CHECK_LIB(socks5, SOCKSconnect, have_socks=yes) - if test "$have_socks" = yes; then - AC_CHECK_HEADERS(socks.h, have_socks_h=yes) - if test "$have_socks_h" = yes; then - socks=yes - AC_DEFINE(SOCKS) - LIBS="$LIBS -lsocks5" - fi - fi -fi - -dnl ********************************************************************* -dnl ** MS PROXY ********************************************************* -dnl ********************************************************************* - -have_ntlm="no" -if test "x$ntlm" = "xyes" ; then - have_ntlm="no" - AC_CHECK_LIB(ntlm, ntlm_smb_encrypt, have_ntlm=yes) - if test "$have_ntlm" = yes; then - LIBS="$LIBS -lntlm" - AC_DEFINE(USE_MSPROXY) - fi -fi - -dnl ********************************************************************* -dnl ** GCC FLAGS ******************************************************** -dnl ********************************************************************* - -dnl Only use -Wall and -pipe if we have gcc -if test "x$GCC" = "xyes"; then - if test -z "`echo "$CFLAGS" | grep "\-Wall" 2> /dev/null`" ; then - CFLAGS="$CFLAGS -Wall" - fi - dnl these flags might be unwanted - if test x$minimalflags != xyes; then - if test "$system" = "Linux" -o "$system" = "FreeBSD"; then - if test -z "`echo "$CFLAGS" | grep "\-pipe" 2> /dev/null`" ; then - CFLAGS="$CFLAGS -pipe" - fi - fi - if test -z "`echo "$CFLAGS" | grep "\-g " 2> /dev/null`" ; then - CFLAGS="$CFLAGS -g" - fi - fi -fi - -dnl does this compiler support -Wno-pointer-sign ? -AC_MSG_CHECKING([if $CC accepts -Wno-pointer-sign ]) - -safe_CFLAGS=$CFLAGS -CFLAGS="-Wno-pointer-sign" - -AC_TRY_COMPILE(, [ -return 0; -], -[ -no_pointer_sign=yes -AC_MSG_RESULT([yes]) -], [ -no_pointer_sign=no -AC_MSG_RESULT([no]) -]) -CFLAGS=$safe_CFLAGS - -if test x$no_pointer_sign = xyes; then - CFLAGS="$CFLAGS -Wno-pointer-sign" -fi - -dnl does this compiler support -funsigned-char ? -AC_MSG_CHECKING([if $CC accepts -funsigned-char ]) - -safe_CFLAGS=$CFLAGS -CFLAGS="-funsigned-char" - -AC_TRY_COMPILE(, [ -return 0; -], -[ -unsigned_char=yes -AC_MSG_RESULT([yes]) -], [ -unsigned_char=no -AC_MSG_RESULT([no]) +CC_CHECK_FLAGS_APPEND([CFLAGS], [CFLAGS], [ \ + -pipe \ + -funsigned-char \ + -Wall \ + -Wextra \ + -Wno-unused-parameter \ + -Wno-sign-compare \ + -Wno-pointer-sign \ + -Wno-missing-field-initializers \ + -Wno-unused-result \ + -Werror=format-security \ + -Werror=declaration-after-statement \ ]) -CFLAGS=$safe_CFLAGS - -if test x$unsigned_char = xyes; then - CFLAGS="$CFLAGS -funsigned-char" -fi - -dnl does this compiler support -Wno-unused-result ? -AC_MSG_CHECKING([if $CC accepts -Wno-unused-result ]) - -safe_CFLAGS=$CFLAGS -CFLAGS="-Wno-unused-result" - -AC_TRY_COMPILE(, [ -return 0; -], -[ -no_unused_result=yes -AC_MSG_RESULT([yes]) -], [ -no_unused_result=no -AC_MSG_RESULT([no]) -]) -CFLAGS=$safe_CFLAGS - -if test x$no_unused_result = xyes; then - CFLAGS="$CFLAGS -Wno-unused-result" -fi dnl ********************************************************************* dnl ** FUNCTIONS/LIBS/CFLAGS ******************************************** @@ -731,19 +605,14 @@ dnl ********************************************************************* AC_MSG_CHECKING(for modern sigaction) dnl libc5 on linux and FreeBSD 3.x doesn\'t have siginfo_t dnl and the sa_sigation field. -AC_TRY_COMPILE( - [#include <signal.h>], - [struct sigaction act; +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <signal.h>]], [[struct sigaction act; siginfo_t *si; - act.sa_sigaction = 0;], - [ + act.sa_sigaction = 0;]])],[ AC_MSG_RESULT(yes) AC_DEFINE(USE_SIGACTION) - ], - AC_MSG_RESULT(no)) + ],[AC_MSG_RESULT(no)]) -dnl if we don\'t have this, use g_snprintf instead -AC_CHECK_FUNCS(snprintf vsnprintf memrchr strtoull) +AC_CHECK_FUNCS(memrchr) AC_CHECK_FUNC(gethostbyname, , AC_CHECK_LIB(resolv, gethostbyname, , @@ -765,9 +634,9 @@ AC_EGREP_CPP([socklen_t[^a-zA-Z_0-9]], [#include <sys/types.h> ac_cv_type_socklen_t=yes, ac_cv_type_socklen_t=no) ]) -if test $ac_cv_type_socklen_t = no; then +AS_IF([test $ac_cv_type_socklen_t = no], [ AC_DEFINE(socklen_t, int) -fi +]) dnl Mac OS X and Darwin use lookupd, which caches DNS queries by default AC_EGREP_CPP(lookupd, dnl @@ -777,7 +646,6 @@ AC_EGREP_CPP(lookupd, dnl dnl freebsd needs this LIBS="$LIBS $INTLLIBS" -CFLAGS="$CFLAGS $CPPFLAGS" GUI_LIBS="$GUI_LIBS $COMMON_LIBS" @@ -792,15 +660,19 @@ AC_SUBST(PY_CFLAGS) AC_SUBST(PY_LIBS) AC_SUBST(DBUS_CFLAGS) AC_SUBST(DBUS_LIBS) +AC_SUBST(OPENSSL_LIBS) +AC_SUBST(OPENSSL_CFLAGS) +AC_SUBST(PLUGIN_LDFLAGS) m4_ifdef([PKG_INSTALLDIR], [PKG_INSTALLDIR], AC_SUBST([pkgconfigdir], ${libdir}/pkgconfig)) -PLUGIN_INCLUDES='-I$(top_srcdir)/plugins' -AC_SUBST(PLUGIN_INCLUDES) - dnl for plugin.c and pixmaps.c -test "x$prefix" = xNONE && prefix="$ac_default_prefix" -test "x$exec_prefix" = xNONE && exec_prefix="$prefix" +AS_IF([test "x$prefix" = xNONE], [ + prefix="$ac_default_prefix" +]) +AS_IF([test "x$exec_prefix" = xNONE], [ + exec_prefix="$prefix" +]) AC_DEFINE_UNQUOTED(PREFIX, "${prefix}") @@ -855,8 +727,6 @@ echo D-Bus support ......... : $dbus echo libnotify support ..... : $libnotify echo libcanberra support ... : $libcanberra echo Plugin interface ...... : $plugin -echo IPv6 support .......... : $ipv6 -echo MS Proxy NTLM \(ISA\) ... : $have_ntlm echo libproxy support ...... : $libproxy echo echo Perl .................. : $perl @@ -867,6 +737,8 @@ echo Do At ................. : $doat echo FiSHLiM ............... : $fishlim echo SysInfo ............... : $sysinfo echo +echo Debug mode ............ : $enable_debug +echo echo The binary will be installed in $prefix/bin echo diff --git a/m4/ac-check-cflags.m4 b/m4/ac-check-cflags.m4 new file mode 100644 index 00000000..a45b17f0 --- /dev/null +++ b/m4/ac-check-cflags.m4 @@ -0,0 +1,60 @@ +dnl Macros to check the presence of generic (non-typed) symbols. +dnl Copyright (c) 2006-2008 Diego Pettenò <flameeyes@gmail.com> +dnl Copyright (c) 2006-2008 xine project +dnl Copyright (c) 2012 Lucas De Marchi <lucas.de.marchi@gmail.com> +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2, or (at your option) +dnl any later version. +dnl +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +dnl 02110-1301, USA. +dnl +dnl As a special exception, the copyright owners of the +dnl macro gives unlimited permission to copy, distribute and modify the +dnl configure scripts that are the output of Autoconf when processing the +dnl Macro. You need not follow the terms of the GNU General Public +dnl License when using or distributing such scripts, even though portions +dnl of the text of the Macro appear in them. The GNU General Public +dnl License (GPL) does govern all other use of the material that +dnl constitutes the Autoconf Macro. +dnl +dnl This special exception to the GPL applies to versions of the +dnl Autoconf Macro released by this project. When you make and +dnl distribute a modified version of the Autoconf Macro, you may extend +dnl this special exception to the GPL to apply to your modified version as +dnl well. + +dnl Check if FLAG in ENV-VAR is supported by compiler and append it +dnl to WHERE-TO-APPEND variable +dnl CC_CHECK_FLAG_APPEND([WHERE-TO-APPEND], [ENV-VAR], [FLAG]) + +AC_DEFUN([CC_CHECK_FLAG_APPEND], [ + AC_CACHE_CHECK([if $CC supports flag $3 in envvar $2], + AS_TR_SH([cc_cv_$2_$3]), + [eval "AS_TR_SH([cc_save_$2])='${$2}'" + eval "AS_TR_SH([$2])='$3'" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a = 0; int main(void) { return a; } ])], + [eval "AS_TR_SH([cc_cv_$2_$3])='yes'"], + [eval "AS_TR_SH([cc_cv_$2_$3])='no'"]) + eval "AS_TR_SH([$2])='$cc_save_$2'"]) + + AS_IF([eval test x$]AS_TR_SH([cc_cv_$2_$3])[ = xyes], + [eval "$1='${$1} $3'"]) +]) + +dnl CC_CHECK_FLAGS_APPEND([WHERE-TO-APPEND], [ENV-VAR], [FLAG1 FLAG2]) +AC_DEFUN([CC_CHECK_FLAGS_APPEND], [ + for flag in $3; do + CC_CHECK_FLAG_APPEND($1, $2, $flag) + done +]) + diff --git a/m4/ax_check_enable_debug.m4 b/m4/ax_check_enable_debug.m4 new file mode 100644 index 00000000..f99d75fe --- /dev/null +++ b/m4/ax_check_enable_debug.m4 @@ -0,0 +1,124 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_check_enable_debug.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_ENABLE_DEBUG([enable by default=yes/info/profile/no], [ENABLE DEBUG VARIABLES ...], [DISABLE DEBUG VARIABLES NDEBUG ...], [IS-RELEASE]) +# +# DESCRIPTION +# +# Check for the presence of an --enable-debug option to configure, with +# the specified default value used when the option is not present. Return +# the value in the variable $ax_enable_debug. +# +# Specifying 'yes' adds '-g -O0' to the compilation flags for all +# languages. Specifying 'info' adds '-g' to the compilation flags. +# Specifying 'profile' adds '-g -pg' to the compilation flags and '-pg' to +# the linking flags. Otherwise, nothing is added. +# +# Define the variables listed in the second argument if debug is enabled, +# defaulting to no variables. Defines the variables listed in the third +# argument if debug is disabled, defaulting to NDEBUG. All lists of +# variables should be space-separated. +# +# If debug is not enabled, ensure AC_PROG_* will not add debugging flags. +# Should be invoked prior to any AC_PROG_* compiler checks. +# +# IS-RELEASE can be used to change the default to 'no' when making a +# release. Set IS-RELEASE to 'yes' or 'no' as appropriate. By default, it +# uses the value of $ax_is_release, so if you are using the AX_IS_RELEASE +# macro, there is no need to pass this parameter. +# +# AX_IS_RELEASE([git-directory]) +# AX_CHECK_ENABLE_DEBUG() +# +# LICENSE +# +# Copyright (c) 2011 Rhys Ulerich <rhys.ulerich@gmail.com> +# Copyright (c) 2014, 2015 Philip Withnall <philip@tecnocode.co.uk> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +#serial 5 + +AC_DEFUN([AX_CHECK_ENABLE_DEBUG],[ + AC_BEFORE([$0],[AC_PROG_CC])dnl + AC_BEFORE([$0],[AC_PROG_CXX])dnl + AC_BEFORE([$0],[AC_PROG_F77])dnl + AC_BEFORE([$0],[AC_PROG_FC])dnl + + AC_MSG_CHECKING(whether to enable debugging) + + ax_enable_debug_default=m4_tolower(m4_normalize(ifelse([$1],,[no],[$1]))) + ax_enable_debug_is_release=m4_tolower(m4_normalize(ifelse([$4],, + [$ax_is_release], + [$4]))) + + # If this is a release, override the default. + AS_IF([test "$ax_enable_debug_is_release" = "yes"], + [ax_enable_debug_default="no"]) + + m4_define(ax_enable_debug_vars,[m4_normalize(ifelse([$2],,,[$2]))]) + m4_define(ax_disable_debug_vars,[m4_normalize(ifelse([$3],,[NDEBUG],[$3]))]) + + AC_ARG_ENABLE(debug, + [AS_HELP_STRING([--enable-debug=]@<:@yes/info/profile/no@:>@,[compile with debugging])], + [],enable_debug=$ax_enable_debug_default) + + # empty mean debug yes + AS_IF([test "x$enable_debug" = "x"], + [enable_debug="yes"]) + + # case of debug + AS_CASE([$enable_debug], + [yes],[ + AC_MSG_RESULT(yes) + CFLAGS="${CFLAGS} -g -O0" + CXXFLAGS="${CXXFLAGS} -g -O0" + FFLAGS="${FFLAGS} -g -O0" + FCFLAGS="${FCFLAGS} -g -O0" + OBJCFLAGS="${OBJCFLAGS} -g -O0" + ], + [info],[ + AC_MSG_RESULT(info) + CFLAGS="${CFLAGS} -g" + CXXFLAGS="${CXXFLAGS} -g" + FFLAGS="${FFLAGS} -g" + FCFLAGS="${FCFLAGS} -g" + OBJCFLAGS="${OBJCFLAGS} -g" + ], + [profile],[ + AC_MSG_RESULT(profile) + CFLAGS="${CFLAGS} -g -pg" + CXXFLAGS="${CXXFLAGS} -g -pg" + FFLAGS="${FFLAGS} -g -pg" + FCFLAGS="${FCFLAGS} -g -pg" + OBJCFLAGS="${OBJCFLAGS} -g -pg" + LDFLAGS="${LDFLAGS} -pg" + ], + [ + AC_MSG_RESULT(no) + dnl Ensure AC_PROG_CC/CXX/F77/FC/OBJC will not enable debug flags + dnl by setting any unset environment flag variables + AS_IF([test "x${CFLAGS+set}" != "xset"], + [CFLAGS=""]) + AS_IF([test "x${CXXFLAGS+set}" != "xset"], + [CXXFLAGS=""]) + AS_IF([test "x${FFLAGS+set}" != "xset"], + [FFLAGS=""]) + AS_IF([test "x${FCFLAGS+set}" != "xset"], + [FCFLAGS=""]) + AS_IF([test "x${OBJCFLAGS+set}" != "xset"], + [OBJCFLAGS=""]) + ]) + + dnl Define various variables if debugging is disabled. + dnl assert.h is a NOP if NDEBUG is defined, so define it by default. + AS_IF([test "x$enable_debug" = "xyes"], + [m4_map_args_w(ax_enable_debug_vars, [AC_DEFINE(], [,,[Define if debugging is enabled])])], + [m4_map_args_w(ax_disable_debug_vars, [AC_DEFINE(], [,,[Define if debugging is disabled])])]) + ax_enable_debug=$enable_debug +]) diff --git a/m4/ax_is_release.m4 b/m4/ax_is_release.m4 new file mode 100644 index 00000000..9ec67469 --- /dev/null +++ b/m4/ax_is_release.m4 @@ -0,0 +1,69 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_is_release.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_IS_RELEASE(POLICY) +# +# DESCRIPTION +# +# Determine whether the code is being configured as a release, or from +# git. Set the ax_is_release variable to 'yes' or 'no'. +# +# If building a release version, it is recommended that the configure +# script disable compiler errors and debug features, by conditionalising +# them on the ax_is_release variable. If building from git, these +# features should be enabled. +# +# The POLICY parameter specifies how ax_is_release is determined. It can +# take the following values: +# +# * git-directory: ax_is_release will be 'no' if a '.git' directory exists +# * minor-version: ax_is_release will be 'no' if the minor version number +# in $PACKAGE_VERSION is odd; this assumes +# $PACKAGE_VERSION follows the 'major.minor.micro' scheme +# * micro-version: ax_is_release will be 'no' if the micro version number +# in $PACKAGE_VERSION is odd; this assumes +# $PACKAGE_VERSION follows the 'major.minor.micro' scheme +# * always: ax_is_release will always be 'yes' +# * never: ax_is_release will always be 'no' +# +# Other policies may be added in future. +# +# LICENSE +# +# Copyright (c) 2015 Philip Withnall <philip@tecnocode.co.uk> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. + +#serial 3 + +AC_DEFUN([AX_IS_RELEASE],[ + AC_BEFORE([AC_INIT],[$0]) + + m4_case([$1], + [git-directory],[ + # $is_release = (.git directory does not exist) + AS_IF([test -d .git],[ax_is_release=no],[ax_is_release=yes]) + ], + [minor-version],[ + # $is_release = ($minor_version is even) + minor_version=`echo "$PACKAGE_VERSION" | sed 's/[[^.]][[^.]]*.\([[^.]][[^.]]*\).*/\1/'` + AS_IF([test "$(( $minor_version % 2 ))" -ne 0], + [ax_is_release=no],[ax_is_release=yes]) + ], + [micro-version],[ + # $is_release = ($micro_version is even) + micro_version=`echo "$PACKAGE_VERSION" | sed 's/[[^.]]*\.[[^.]]*\.\([[^.]]*\).*/\1/'` + AS_IF([test "$(( $micro_version % 2 ))" -ne 0], + [ax_is_release=no],[ax_is_release=yes]) + ], + [always],[ax_is_release=yes], + [never],[ax_is_release=no], + [ + AC_MSG_ERROR([Invalid policy. Valid policies: git-directory, minor-version.]) + ]) +]) diff --git a/m4/ax_perl_ext_flags.m4 b/m4/ax_perl_ext_flags.m4 new file mode 100644 index 00000000..03f16435 --- /dev/null +++ b/m4/ax_perl_ext_flags.m4 @@ -0,0 +1,116 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_perl_ext_flags.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_PERL_EXT_FLAGS([CFLAGS-VARIABLE], [LDFLAGS-VARIABLE], [EXTRA-MODULES]) +# AX_PERL_EXT_CFLAGS([CFLAGS-VARIABLE]) +# AX_PERL_EXT_LDFLAGS([LDFLAGS-VARIABLE], [EXTRA-MODULES]) +# +# DESCRIPTION +# +# Fetches the linker flags and C compiler flags for compiling and linking +# programs that embed a Perl interpreter. If the EXTRA-MODULES argument is +# submitted, it is a space separated list of extra modules to link. The +# flags will be stored in the provided variables. +# +# Examples: +# +# AX_PERL_EXT_FLAGS([PERLXS_CFLAGS], [PERLXS_LDFLAGS]) +# AC_SUBST([PERLXS_CFLAGS]) +# AC_SUBST([PERLXS_LDFLAGS]) +# +# AX_PERL_EXT_CFLAGS([PERLXS_CFLAGS]) +# AC_SUBST([PERLXS_CFLAGS]) +# +# AX_PERL_EXT_LDFLAGS([PERLXS_LDFLAGS], [-std Socket]) +# +# LICENSE +# +# Copyright (c) 2009 Mats Kindahl of Sun Microsystems <mats@sun.com> +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +#serial 5 + +AC_DEFUN([AX_PERL_EXT_CFLAGS], +[AC_CHECK_PROG(PERL,perl,perl) + _AX_PERL_EXT_MODULE_CHECK([ExtUtils::Embed], [have_embed=yes], + [have_embed=no]) + AS_IF([test $have_embed = no], + AC_MSG_ERROR([Require ExtUtils::Embed to proceed])) + _AX_PERL_EXT_EMBED_CHECK([$1],[ccopts]) +]) + + +AC_DEFUN([AX_PERL_EXT_LDFLAGS], +[AC_CHECK_PROG(PERL,perl,perl) + _AX_PERL_EXT_MODULE_CHECK([ExtUtils::Embed], [have_embed=yes], + [have_embed=no]) + AS_IF([test $have_embed = no], + AC_MSG_ERROR([Require ExtUtils::Embed to proceed])) + _AX_PERL_EXT_EMBED_CHECK([$1],[ldopts],[$2]) +]) + + +AC_DEFUN([AX_PERL_EXT_FLAGS], +[AC_CHECK_PROG(PERL,perl,perl) + _AX_PERL_EXT_MODULE_CHECK([ExtUtils::Embed], [have_embed=yes], + [have_embed=no]) + AS_IF([test $have_embed = no], + AC_MSG_ERROR([Require ExtUtils::Embed to proceed])) + _AX_PERL_EXT_EMBED_CHECK([$1],[ccopts]) + _AX_PERL_EXT_EMBED_CHECK([$2],[ldopts],[$3]) +]) + + +dnl _AX_PERL_EXT_MODULE_CHECK(MODULE-NAME, ACTION-IF-FOUND, ACTION-IF-NOT-FOUND) +dnl +dnl Check for the existance of the perl module given by MODULE-NAME. +dnl +AC_DEFUN([_AX_PERL_EXT_MODULE_CHECK], +[AC_MSG_CHECKING([for perl module $1]) + $PERL "-M$1" -e exit > /dev/null 2>&1 + AS_IF([test $? -eq 0], + [AC_MSG_RESULT(yes) + $2], + [AC_MSG_RESULT(no) + $3]) +]) + +dnl _AX_PERL_EXT_EMBED_CHECK(VARIABLE, COMMAND, [EXTRA-FLAGS]) Use +dnl +dnl ExtUtils::Embed fetch flags for embedding Perl in a C/C++ +dnl application +dnl +AC_DEFUN([_AX_PERL_EXT_EMBED_CHECK], +[AC_MSG_CHECKING([for perl $2 embed flags]) + ax_c_perlxs_extras="$3" + $1=`$PERL -MExtUtils::Embed -e $2 ${ax_c_perlxs_extras:+"-- $3"}` + AC_MSG_RESULT($$1) +]) diff --git a/m4/ax_require_defined.m4 b/m4/ax_require_defined.m4 new file mode 100644 index 00000000..cae11112 --- /dev/null +++ b/m4/ax_require_defined.m4 @@ -0,0 +1,37 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_require_defined.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_REQUIRE_DEFINED(MACRO) +# +# DESCRIPTION +# +# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have +# been defined and thus are available for use. This avoids random issues +# where a macro isn't expanded. Instead the configure script emits a +# non-fatal: +# +# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found +# +# It's like AC_REQUIRE except it doesn't expand the required macro. +# +# Here's an example: +# +# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG]) +# +# LICENSE +# +# Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 1 + +AC_DEFUN([AX_REQUIRE_DEFINED], [dnl + m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])]) +])dnl AX_REQUIRE_DEFINED diff --git a/m4/clang-analyze.am b/m4/clang-analyze.am new file mode 100644 index 00000000..a5765774 --- /dev/null +++ b/m4/clang-analyze.am @@ -0,0 +1,8 @@ +analysis_verbose = $(analysis_verbose_$(V)) +analysis_verbose_ = $(analysis_verbose_$(AM_DEFAULT_VERBOSITY)) +analysis_verbose_0 = @echo " CCSA " $@; $(COMPILE) --analyze $< -o $@; +analysis_verbose_1 = $(COMPILE) --analyze $< -o $@; + +%.plist: %.c + $(analysis_verbose) + diff --git a/plugins/Make.plugin b/plugins/Make.plugin deleted file mode 100644 index 4a4c56fd..00000000 --- a/plugins/Make.plugin +++ /dev/null @@ -1,38 +0,0 @@ -# Makefile stub for creating standalone plugin distributions. - -plugin_dist: pg_dist pg_dist/config.status - pgi=`cd $(srcdir)/.. && pwd`; cd pg_dist; \ - $(MAKE) $(AM_MAKEFLAGS) PLUGIN_INCLUDES=-I$$pgi distcheck dist - -pg_dist: pg_distdir pg_dist/configure.in pg_dist/install-sh - cd pg_dist \ - && libtoolize --copy --force --automake \ - && automake --copy --add-missing --foreign \ - && autoconf -l ../$(top_srcdir) - -pg_distdir: $(DISTFILES) - test -d pg_dist || mkdir pg_dist - for dfile in $(DISTFILES); do \ - test -f $$dfile && cp $$dfile pg_dist \ - || test -f $(srcdir)/$$dfile && cp $(srcdir)/$$dfile pg_dist; done - sed '/Make.plugin/d' < $(srcdir)/Makefile.am > pg_dist/Makefile.am - -pg_dist/configure.in: $(srcdir)/../plugin-conf.in - rm -f pg_dist/configure.in - test -f $(srcdir)/config.stub \ - && cat $(srcdir)/config.stub > pg_dist/configure.in || true - cat $(srcdir)/../plugin-conf.in | \ - sed 's%@PLUGIN_VERSION@%$(PLUGIN_VERSION)%; \ - s%@PLUGIN@%$(PLUGIN)%' >> pg_dist/configure.in - -pg_dist/install-sh: pg_distdir - cp $(top_srcdir)/install-sh pg_dist - -pg_dist/config.status: pg_dist/configure - cd pg_dist \ - && test -f config.status && $(SHELL) ./config.status --recheck \ - || $(SHELL) ./configure --enable-maintainer-mode - -DISTCLEANFILES = pg_dist/* pg_dist - -# diff --git a/plugins/checksum/Makefile.am b/plugins/checksum/Makefile.am index 419c762f..4e911f28 100644 --- a/plugins/checksum/Makefile.am +++ b/plugins/checksum/Makefile.am @@ -2,6 +2,6 @@ libdir = $(hexchatlibdir) lib_LTLIBRARIES = checksum.la checksum_la_SOURCES = checksum.c -checksum_la_LDFLAGS = -avoid-version -module -checksum_la_LIBADD = -AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/../../src/common +checksum_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module +checksum_la_LIBADD = $(GLIB_LIBS) +checksum_la_CFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)/src/common diff --git a/plugins/checksum/checksum.c b/plugins/checksum/checksum.c index 6ace8543..9a7f0ebd 100644 --- a/plugins/checksum/checksum.c +++ b/plugins/checksum/checksum.c @@ -20,222 +20,194 @@ * THE SOFTWARE. */ -#ifdef __APPLE__ -#define __AVAILABILITYMACROS__ -#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER -#endif +#include "config.h" -#include <stdio.h> -#include <string.h> #include <stdlib.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <openssl/sha.h> #include <glib.h> - -#ifdef WIN32 -#ifndef snprintf -#define snprintf _snprintf -#endif -#define stat _stat64 -#else -/* for INT_MAX */ -#include <limits.h> -#define __USE_LARGEFILE64 -#define _LARGEFILE_SOURCE -#define _LARGEFILE64_SOURCE -#endif +#include <glib/gstdio.h> +#include <gio/gio.h> #include "hexchat-plugin.h" #define BUFSIZE 32768 #define DEFAULT_LIMIT 256 /* default size is 256 MiB */ +#define SHA256_DIGEST_LENGTH 32 +#define SHA256_BUFFER_LENGTH 65 static hexchat_plugin *ph; /* plugin handle */ static char name[] = "Checksum"; static char desc[] = "Calculate checksum for DCC file transfers"; static char version[] = "3.1"; -/* Use of OpenSSL SHA256 interface: http://adamlamers.com/?p=5 */ static void -sha256_hash_string (unsigned char hash[SHA256_DIGEST_LENGTH], char outputBuffer[65]) +set_limit (char *size) { - int i; - for (i = 0; i < SHA256_DIGEST_LENGTH; i++) + int limit = atoi (size); + + if (limit > 0 && limit < INT_MAX) { - sprintf (outputBuffer + (i * 2), "%02x", hash[i]); + if (hexchat_pluginpref_set_int (ph, "limit", limit)) + hexchat_printf (ph, "Checksum: File size limit has successfully been set to: %d MiB\n", limit); + else + hexchat_printf (ph, "Checksum: File access error while saving!\n"); } - outputBuffer[64] = 0; -} - -#if 0 -static void -sha256 (char *string, char outputBuffer[65]) -{ - int i; - unsigned char hash[SHA256_DIGEST_LENGTH]; - SHA256_CTX sha256; - - SHA256_Init (&sha256); - SHA256_Update (&sha256, string, strlen (string)); - SHA256_Final (hash, &sha256); - - for (i = 0; i < SHA256_DIGEST_LENGTH; i++) + else { - sprintf (outputBuffer + (i * 2), "%02x", hash[i]); + hexchat_printf (ph, "Checksum: Invalid input!\n"); } - outputBuffer[64] = 0; } -#endif static int -sha256_file (char *path, char outputBuffer[65]) +get_limit () { - int bytesRead; - unsigned char *buffer; - unsigned char hash[SHA256_DIGEST_LENGTH]; - SHA256_CTX sha256; + int size = hexchat_pluginpref_get_int (ph, "limit"); - FILE *file = fopen (path, "rb"); - if (!file) - { - return -534; - } + if (size <= 0 || size >= INT_MAX) + return DEFAULT_LIMIT; + else + return size; +} - SHA256_Init (&sha256); - buffer = malloc (BUFSIZE); - bytesRead = 0; +static gboolean +check_limit (GFile *file) +{ + GFileInfo *file_info; + goffset file_size; - if (!buffer) - { - fclose (file); - return ENOMEM; - } + file_info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, + NULL, NULL); - while ((bytesRead = fread (buffer, 1, BUFSIZE, file))) - { - SHA256_Update (&sha256, buffer, bytesRead); - } + if (!file_info) + return FALSE; - SHA256_Final (hash, &sha256); - sha256_hash_string (hash, outputBuffer); + file_size = g_file_info_get_size (file_info); + g_object_unref (file_info); - fclose (file); - free (buffer); - return 0; + if (file_size > get_limit () * 1048576ll) + return FALSE; + + return TRUE; } -static void -set_limit (char* size) +static gboolean +sha256_from_stream (GFileInputStream *file_stream, char out_buf[]) { - int buffer = atoi (size); + GChecksum *checksum; + gssize bytes_read; + guint8 digest[SHA256_DIGEST_LENGTH]; + gsize digest_len = sizeof(digest); + guchar buffer[BUFSIZE]; + gsize i; + + checksum = g_checksum_new (G_CHECKSUM_SHA256); - if (buffer > 0 && buffer < INT_MAX) + while ((bytes_read = g_input_stream_read (G_INPUT_STREAM (file_stream), buffer, sizeof (buffer), NULL, NULL))) { - if (hexchat_pluginpref_set_int (ph, "limit", buffer)) - { - hexchat_printf (ph, "File size limit has successfully been set to: %d MiB\n", buffer); - } - else + if (bytes_read == -1) { - hexchat_printf (ph, "File access error while saving!\n"); + g_checksum_free (checksum); + return FALSE; } + + g_checksum_update (checksum, buffer, bytes_read); } - else + + g_checksum_get_digest (checksum, digest, &digest_len); + g_checksum_free (checksum); + + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { - hexchat_printf (ph, "Invalid input!\n"); + /* out_buf will be exactly SHA256_BUFFER_LENGTH including null */ + g_sprintf (out_buf + (i * 2), "%02x", digest[i]); } + + return TRUE; } -static int -get_limit () +static gboolean +sha256_from_file (char *filename, char out_buf[]) { - int size = hexchat_pluginpref_get_int (ph, "limit"); + GFileInputStream *file_stream; + char *filename_fs; + GFile *file; - if (size <= -1 || size >= INT_MAX) + filename_fs = g_filename_from_utf8 (filename, -1, NULL, NULL, NULL); + if (!filename_fs) { - return DEFAULT_LIMIT; + hexchat_printf (ph, "Checksum: Invalid filename (%s)\n", filename); + return FALSE; } - else + + file = g_file_new_for_path (filename_fs); + g_free (filename_fs); + if (!file) { - return size; + hexchat_printf (ph, "Checksum: Failed to open %s\n", filename); + return FALSE; } -} - -static void -print_limit () -{ - hexchat_printf (ph, "File size limit for checksums: %d MiB", get_limit ()); -} -static int -dccrecv_cb (char *word[], void *userdata) -{ - int result; - struct stat buffer; /* buffer for storing file info */ - char sum[65]; /* buffer for checksum */ - const char *file; - char *cfile; - - if (hexchat_get_prefs (ph, "dcc_completed_dir", &file, NULL) == 1 && file[0] != 0) + if (!check_limit (file)) { - cfile = g_strconcat (file, G_DIR_SEPARATOR_S, word[1], NULL); + hexchat_printf (ph, "Checksum: %s is larger than size limit. You can increase it with /CHECKSUM SET.\n", filename); + g_object_unref (file); + return FALSE; } - else + + file_stream = g_file_read (file, NULL, NULL); + if (!file_stream) { - cfile = g_strdup(word[2]); + hexchat_printf (ph, "Checksum: Failed to read file %s\n", filename); + g_object_unref (file); + return FALSE; } - result = stat (cfile, &buffer); - if (result == 0) /* stat returns 0 on success */ + if (!sha256_from_stream (file_stream, out_buf)) { - if (buffer.st_size <= (unsigned long long) get_limit () * 1048576) - { - sha256_file (cfile, sum); /* file is the full filename even if completed dir set */ - /* try to print the checksum in the privmsg tab of the sender */ - hexchat_set_context (ph, hexchat_find_context (ph, NULL, word[3])); - hexchat_printf (ph, "SHA-256 checksum for %s (local): %s\n", word[1], sum); - } - else - { - hexchat_set_context (ph, hexchat_find_context (ph, NULL, word[3])); - hexchat_printf (ph, "SHA-256 checksum for %s (local): (size limit reached, no checksum calculated, you can increase it with /CHECKSUM INC)\n", word[1]); - } + hexchat_printf (ph, "Checksum: Failed to generate checksum for %s\n", filename); + g_object_unref (file_stream); + g_object_unref (file); + return FALSE; } + + g_object_unref (file_stream); + g_object_unref (file); + return TRUE; +} + +static int +dccrecv_cb (char *word[], void *userdata) +{ + const char *dcc_completed_dir; + char *filename, checksum[SHA256_BUFFER_LENGTH]; + + /* Print in the privmsg tab of the sender */ + hexchat_set_context (ph, hexchat_find_context (ph, NULL, word[3])); + + if (hexchat_get_prefs (ph, "dcc_completed_dir", &dcc_completed_dir, NULL) == 1 && dcc_completed_dir[0] != '\0') + filename = g_build_filename (dcc_completed_dir, word[1], NULL); else + filename = g_strdup (word[2]); + + if (sha256_from_file (filename, checksum)) { - hexchat_printf (ph, "File access error!\n"); + hexchat_printf (ph, "SHA-256 checksum for %s (local): %s\n", word[1], checksum); } - g_free (cfile); + g_free (filename); return HEXCHAT_EAT_NONE; } static int dccoffer_cb (char *word[], void *userdata) { - int result; - struct stat buffer; /* buffer for storing file info */ - char sum[65]; /* buffer for checksum */ + char checksum[SHA256_BUFFER_LENGTH]; - result = stat (word[3], &buffer); - if (result == 0) /* stat returns 0 on success */ - { - if (buffer.st_size <= (unsigned long long) get_limit () * 1048576) - { - sha256_file (word[3], sum); /* word[3] is the full filename */ - hexchat_commandf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): %s", word[2], word[1], sum); - } - else - { - hexchat_set_context (ph, hexchat_find_context (ph, NULL, word[3])); - hexchat_printf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): (size limit reached, no checksum calculated)", word[2], word[1]); - } - } - else + /* Print in the privmsg tab of the receiver */ + hexchat_set_context (ph, hexchat_find_context (ph, NULL, word[3])); + + if (sha256_from_file (word[3], checksum)) { - hexchat_printf (ph, "File access error!\n"); + hexchat_commandf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): %s", word[2], word[1], checksum); } return HEXCHAT_EAT_NONE; @@ -246,7 +218,7 @@ checksum (char *word[], char *word_eol[], void *userdata) { if (!g_ascii_strcasecmp ("GET", word[2])) { - print_limit (); + hexchat_printf (ph, "File size limit for checksums: %d MiB", get_limit ()); } else if (!g_ascii_strcasecmp ("SET", word[2])) { @@ -259,7 +231,7 @@ checksum (char *word[], char *word_eol[], void *userdata) hexchat_printf (ph, " SET <filesize> - set the maximum file size (in MiB) to be hashed\n"); } - return HEXCHAT_EAT_NONE; + return HEXCHAT_EAT_ALL; } int @@ -277,7 +249,7 @@ hexchat_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **p hexchat_pluginpref_set_int (ph, "limit", DEFAULT_LIMIT); } - hexchat_hook_command (ph, "CHECKSUM", HEXCHAT_PRI_NORM, checksum, "Usage: /CHECKSUM GET|SET", 0); + hexchat_hook_command (ph, "CHECKSUM", HEXCHAT_PRI_NORM, checksum, "Usage: /CHECKSUM GET|SET", NULL); hexchat_hook_print (ph, "DCC RECV Complete", HEXCHAT_PRI_NORM, dccrecv_cb, NULL); hexchat_hook_print (ph, "DCC Offer", HEXCHAT_PRI_NORM, dccoffer_cb, NULL); diff --git a/plugins/checksum/checksum.vcxproj b/plugins/checksum/checksum.vcxproj index 7838cb4a..948295a0 100644 --- a/plugins/checksum/checksum.vcxproj +++ b/plugins/checksum/checksum.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -19,57 +20,19 @@ <RootNamespace>checksum</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <TargetName>hcchecksum</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\hexchat.props" /> + <PropertyGroup> <TargetName>hcchecksum</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <OutDir>$(HexChatRel)plugins\</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CHECKSUM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> <ModuleDefinitionFile>checksum.def</ModuleDefinitionFile> <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> @@ -77,19 +40,10 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;CHECKSUM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> <ModuleDefinitionFile>checksum.def</ModuleDefinitionFile> <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> @@ -102,6 +56,4 @@ <None Include="checksum.def" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/plugins/doat/Makefile.am b/plugins/doat/Makefile.am index abfca29e..a04d2863 100644 --- a/plugins/doat/Makefile.am +++ b/plugins/doat/Makefile.am @@ -2,7 +2,7 @@ libdir = $(hexchatlibdir) lib_LTLIBRARIES = doat.la doat_la_SOURCES = doat.c -doat_la_LDFLAGS = -avoid-version -module -doat_la_LIBADD = -AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/../../src/common +doat_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module +doat_la_LIBADD = $(GLIB_LIBS) +doat_la_CFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)/src/common diff --git a/plugins/doat/doat.c b/plugins/doat/doat.c index 194be1a3..1d1bfcdf 100644 --- a/plugins/doat/doat.c +++ b/plugins/doat/doat.c @@ -5,9 +5,12 @@ * http://sam.zoy.org/wtfpl/COPYING or http://lwsitu.com/xchat/COPYING * for more details. */ +#include "config.h" + #include <stdlib.h> #include <string.h> #include <stdio.h> +#include <glib.h> #include "hexchat-plugin.h" static hexchat_plugin *ph; @@ -31,7 +34,7 @@ parse_command( char *word[], char *word_eol[], void *userdata ) { break; } - channel = strdup( token ); + channel = g_strdup( token ); delimiter = strchr( channel, '/' ); @@ -40,13 +43,13 @@ parse_command( char *word[], char *word_eol[], void *userdata ) { *delimiter = '\0'; if( strlen( delimiter + 1 ) > 0 ) { - server = strdup( delimiter + 1 ); + server = g_strdup( delimiter + 1 ); } } /* /Network form */ if( strlen( channel ) == 0 ) { - free( channel ); + g_free( channel ); channel = NULL; } @@ -58,13 +61,8 @@ parse_command( char *word[], char *word_eol[], void *userdata ) { } } - if( channel != NULL ) { - free( channel ); - } - - if( server != NULL ) { - free( server ); - } + g_free( channel ); + g_free( server ); } } return HEXCHAT_EAT_HEXCHAT; diff --git a/plugins/doat/doat.vcxproj b/plugins/doat/doat.vcxproj index 171e2b0d..ae44d7f8 100644 --- a/plugins/doat/doat.vcxproj +++ b/plugins/doat/doat.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -19,75 +20,32 @@ <RootNamespace>doat</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <TargetName>hcdoat</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\hexchat.props" /> + <PropertyGroup> <TargetName>hcdoat</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <OutDir>$(HexChatRel)plugins\</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DOAT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>..\..\src\common;$(HexChatLib);$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> <ModuleDefinitionFile>doat.def</ModuleDefinitionFile> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;DOAT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>..\..\src\common;$(HexChatLib);$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> <ModuleDefinitionFile>doat.def</ModuleDefinitionFile> </Link> </ItemDefinitionGroup> @@ -98,6 +56,4 @@ <None Include="doat.def" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/plugins/exec/exec.vcxproj b/plugins/exec/exec.vcxproj index a04c0046..d691bb11 100644 --- a/plugins/exec/exec.vcxproj +++ b/plugins/exec/exec.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -19,75 +20,28 @@ <RootNamespace>exec</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <TargetName>hcexec</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\hexchat.props" /> + <PropertyGroup> <TargetName>hcexec</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <OutDir>$(HexChatRel)plugins\</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXEC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MultiProcessorCompilation>true</MultiProcessorCompilation> <AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> <ModuleDefinitionFile>exec.def</ModuleDefinitionFile> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;EXEC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MultiProcessorCompilation>true</MultiProcessorCompilation> <AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> <ModuleDefinitionFile>exec.def</ModuleDefinitionFile> </Link> </ItemDefinitionGroup> @@ -98,6 +52,4 @@ <ClCompile Include="exec.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/plugins/fishlim/Makefile.am b/plugins/fishlim/Makefile.am index 255ea0c3..df541396 100644 --- a/plugins/fishlim/Makefile.am +++ b/plugins/fishlim/Makefile.am @@ -3,7 +3,7 @@ EXTRA_DIST = INSTALL LICENSE libdir = $(hexchatlibdir) lib_LTLIBRARIES = fishlim.la -fishlim_la_SOURCES = fish.c irc.c keystore.c misc.c plugin_hexchat.c -fishlim_la_LDFLAGS = -avoid-version -module -fishlim_la_LIBADD = -AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/../../src/common +fishlim_la_SOURCES = fish.c irc.c keystore.c plugin_hexchat.c +fishlim_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module +fishlim_la_LIBADD = $(GLIB_LIBS) $(OPENSSL_LIBS) +fishlim_la_CFLAGS = $(GLIB_CFLAGS) $(OPENSSL_CFLAGS) -I$(top_srcdir)/src/common diff --git a/plugins/fishlim/fish.c b/plugins/fishlim/fish.c index 93420f23..00ecfbfa 100644 --- a/plugins/fishlim/fish.c +++ b/plugins/fishlim/fish.c @@ -39,17 +39,17 @@ static const char fish_base64[64] = "./0123456789abcdefghijklmnopqrstuvwxyzABCDE static const signed char fish_unbase64[256] = { IB,IB,IB,IB,IB,IB,IB,IB, IB,IB,IB,IB,IB,IB,IB,IB, IB,IB,IB,IB,IB,IB,IB,IB, IB,IB,IB,IB,IB,IB,IB,IB, -// ! " # $ % & ' ( ) * + , - . / +/* ! " # $ % & ' ( ) * + , - . / */ IB,IB,IB,IB,IB,IB,IB,IB, IB,IB,IB,IB,IB,IB, 0, 1, -// 0 1 2 3 4 5 6 7 8 9 : ; < = > ? +/* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ 2, 3, 4, 5, 6, 7, 8, 9, 10,11,IB,IB,IB,IB,IB,IB, -// @ A B C D E F G H I J K L M N O +/* @ A B C D E F G H I J K L M N O */ IB,38,39,40,41,42,43,44, 45,46,47,48,49,50,51,52, -// P Q R S T U V W X Y Z [ \ ] ^ _ +/* P Q R S T U V W X Y Z [ \ ] ^ _*/ 53,54,55,56,57,58,59,60, 61,62,63,IB,IB,IB,IB,IB, -// ` a b c d e f g h i j k l m n o +/* ` a b c d e f g h i j k l m n o */ IB,12,13,14,15,16,17,18, 19,20,21,22,23,24,25,26, -// p q r s t u v w x y z { | } ~ <del> +/* p q r s t u v w x y z { | } ~ <del> */ 27,28,29,30,31,32,33,34, 35,36,37,IB,IB,IB,IB,IB, }; @@ -75,12 +75,11 @@ char *fish_encrypt(const char *key, size_t keylen, const char *message) { messagelen = strlen(message); if (messagelen == 0) return NULL; - encrypted = malloc(((messagelen-1)/8)*12 + 12 + 1); // each 8-byte block becomes 12 bytes + encrypted = g_malloc(((messagelen - 1) / 8) * 12 + 12 + 1); /* each 8-byte block becomes 12 bytes */ end = encrypted; - if (!encrypted) return NULL; while (*message) { - // Read 8 bytes (a Blowfish block) + /* Read 8 bytes (a Blowfish block) */ BF_LONG binary[2] = { 0, 0 }; unsigned char c; for (i = 0; i < 8; i++) { @@ -90,10 +89,10 @@ char *fish_encrypt(const char *key, size_t keylen, const char *message) { } message += 8; - // Encrypt block + /* Encrypt block */ BF_encrypt(binary, &bfkey); - // Emit FiSH-BASE64 + /* Emit FiSH-BASE64 */ bit = 0; word = 1; for (j = 0; j < 12; j++) { @@ -106,7 +105,7 @@ char *fish_encrypt(const char *key, size_t keylen, const char *message) { } } - // Stop if a null terminator was found + /* Stop if a null terminator was found */ if (c == '\0') break; } *end = '\0'; @@ -124,12 +123,11 @@ char *fish_decrypt(const char *key, size_t keylen, const char *data) { unsigned char d; BF_set_key(&bfkey, keylen, (const unsigned char*)key); - decrypted = malloc(strlen(data)+1); + decrypted = g_malloc(strlen(data) + 1); end = decrypted; - if (!decrypted) return NULL; while (*data) { - // Convert from FiSH-BASE64 + /* Convert from FiSH-BASE64 */ BF_LONG binary[2] = { 0, 0 }; bit = 0; word = 1; @@ -144,10 +142,10 @@ char *fish_decrypt(const char *key, size_t keylen, const char *data) { } } - // Decrypt block + /* Decrypt block */ BF_decrypt(binary, &bfkey); - // Copy to buffer + /* Copy to buffer */ GET_BYTES(end, binary[0]); GET_BYTES(end, binary[1]); } @@ -165,14 +163,14 @@ char *fish_encrypt_for_nick(const char *nick, const char *data) { char *key; char *encrypted; - // Look for key + /* Look for key */ key = keystore_get_key(nick); if (!key) return NULL; - // Encrypt + /* Encrypt */ encrypted = fish_encrypt(key, strlen(key), data); - free(key); + g_free(key); return encrypted; } @@ -183,14 +181,14 @@ char *fish_encrypt_for_nick(const char *nick, const char *data) { char *fish_decrypt_from_nick(const char *nick, const char *data) { char *key; char *decrypted; - // Look for key + /* Look for key */ key = keystore_get_key(nick); if (!key) return NULL; - // Decrypt + /* Decrypt */ decrypted = fish_decrypt(key, strlen(key), data); - free(key); + g_free(key); return decrypted; } diff --git a/plugins/fishlim/fish.h b/plugins/fishlim/fish.h index db471326..238f52e7 100644 --- a/plugins/fishlim/fish.h +++ b/plugins/fishlim/fish.h @@ -25,9 +25,10 @@ #ifndef FISH_H #define FISH_H -#include <stdbool.h> #include <stddef.h> +#include <glib.h> + char *fish_encrypt(const char *key, size_t keylen, const char *message); char *fish_decrypt(const char *key, size_t keylen, const char *data); char *fish_encrypt_for_nick(const char *nick, const char *data); diff --git a/plugins/fishlim/fishlim.vcxproj b/plugins/fishlim/fishlim.vcxproj index f1eb95ba..25492a82 100644 --- a/plugins/fishlim/fishlim.vcxproj +++ b/plugins/fishlim/fishlim.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -19,57 +20,19 @@ <RootNamespace>fishlim</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <TargetName>hcfishlim</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\hexchat.props" /> + <PropertyGroup> <TargetName>hcfishlim</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <OutDir>$(HexChatRel)plugins\</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MultiProcessorCompilation>true</MultiProcessorCompilation> - <AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> <ModuleDefinitionFile>fishlim.def</ModuleDefinitionFile> <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> @@ -77,19 +40,10 @@ </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MultiProcessorCompilation>true</MultiProcessorCompilation> - <AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> <ModuleDefinitionFile>fishlim.def</ModuleDefinitionFile> <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> @@ -103,17 +57,13 @@ <ClInclude Include="fish.h" /> <ClInclude Include="irc.h" /> <ClInclude Include="keystore.h" /> - <ClInclude Include="misc.h" /> <ClInclude Include="plugin_hexchat.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="fish.c" /> <ClCompile Include="irc.c" /> <ClCompile Include="keystore.c" /> - <ClCompile Include="misc.c" /> <ClCompile Include="plugin_hexchat.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/plugins/fishlim/fishlim.vcxproj.filters b/plugins/fishlim/fishlim.vcxproj.filters index 7c13733b..d8fbf454 100644 --- a/plugins/fishlim/fishlim.vcxproj.filters +++ b/plugins/fishlim/fishlim.vcxproj.filters @@ -32,9 +32,6 @@ <ClInclude Include="keystore.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="misc.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="plugin_hexchat.h"> <Filter>Header Files</Filter> </ClInclude> @@ -49,9 +46,6 @@ <ClCompile Include="keystore.c"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="misc.c"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="plugin_hexchat.c"> <Filter>Source Files</Filter> </ClCompile> diff --git a/plugins/fishlim/irc.c b/plugins/fishlim/irc.c index 3586921b..deba545b 100644 --- a/plugins/fishlim/irc.c +++ b/plugins/fishlim/irc.c @@ -22,8 +22,9 @@ */ -#include <stdlib.h> -#include <string.h> +#include "config.h" + +#include <glib.h> #include "irc.h" /** @@ -31,26 +32,26 @@ * at spaces. The prefix and command is extracted from the message, and * parameters_offset is set to the index of the first parameter. */ -bool irc_parse_message(const char *words[], +gboolean irc_parse_message(const char *words[], const char **prefix, const char **command, size_t *parameters_offset) { size_t w = 1; if (prefix) *prefix = NULL; if (command) *command = NULL; - // See if the message starts with a prefix (sender user) + /* See if the message starts with a prefix (sender user) */ if (words[w][0] == ':') { if (prefix) *prefix = &words[w][1]; w++; } - // Check command - if (words[w][0] == '\0') return false; + /* Check command */ + if (words[w][0] == '\0') return FALSE; if (command) *command = words[w]; w++; *parameters_offset = w; - return true; + return TRUE; } @@ -65,48 +66,15 @@ bool irc_parse_message(const char *words[], */ char *irc_prefix_get_nick(const char *prefix) { const char *end; - char *nick; size_t length; if (!prefix) return NULL; - // Find end of nick + /* Find end of nick */ end = prefix; while (*end != '\0' && *end != '!' && *end != '@') end++; - // Allocate string + /* Allocate string */ length = end - prefix; - nick = malloc(length+1); - if (!nick) return NULL; - - // Copy to string - memcpy(nick, prefix, length); - nick[length] = '\0'; - return nick; -} - - -/** - * Compares two nick names. Return 0 if equal. Otherwise the return value is - * less than zero if a is less than b or greater than zero if a is greater - * than b. - */ -int irc_nick_cmp(const char *a, const char *b) { - char ac; - char bc; - char diff; - for (;;) { - ac = *(a++); - bc = *(b++); - - // Change into IRC uppercase (see RFC 2812 section 2.2) - if (ac >= 'a' && ac <= '~') ac &= ~0x20; - if (bc >= 'a' && bc <= '~') bc &= ~0x20; - - diff = ac - bc; - if (diff) return diff; - if (!ac) return 0; - } + return g_strndup (prefix, length); } - - diff --git a/plugins/fishlim/irc.h b/plugins/fishlim/irc.h index 87317130..c5649233 100644 --- a/plugins/fishlim/irc.h +++ b/plugins/fishlim/irc.h @@ -25,14 +25,13 @@ #ifndef IRC_H #define IRC_H -#include <stdbool.h> #include <stddef.h> +#include <glib.h> -bool irc_parse_message(const char *words[], +gboolean irc_parse_message(const char *words[], const char **prefix, const char **command, size_t *parameters_offset); char *irc_prefix_get_nick(const char *prefix); -int irc_nick_cmp(const char *a, const char *b); #endif diff --git a/plugins/fishlim/keystore.c b/plugins/fishlim/keystore.c index 9f1c446e..84373996 100644 --- a/plugins/fishlim/keystore.c +++ b/plugins/fishlim/keystore.c @@ -22,12 +22,13 @@ */ +#include "config.h" + #include <glib.h> #include <stdlib.h> #include <string.h> #include "irc.h" #include "fish.h" -#include "misc.h" #include "keystore.h" #include "plugin_hexchat.h" @@ -57,7 +58,7 @@ static GKeyFile *getConfigFile() { static const char *get_keystore_password() { return (keystore_password != NULL ? keystore_password : - // Silly default value... + /* Silly default value... */ "blowinikey"); } @@ -87,17 +88,17 @@ static gchar *get_nick_value(GKeyFile *keyfile, const char *nick, const char *it * Extracts a key from the key store file. */ char *keystore_get_key(const char *nick) { - // Get the key + /* Get the key */ GKeyFile *keyfile = getConfigFile(); gchar *value = get_nick_value(keyfile, nick, "key"); g_key_file_free(keyfile); if (!value) return NULL; if (strncmp(value, "+OK ", 4) != 0) { - // Key is stored in plaintext - return import_glib_string(value); + /* Key is stored in plaintext */ + return value; } else { - // Key is encrypted + /* Key is encrypted */ const char *encrypted = value+4; const char *password = get_keystore_password(); char *decrypted = fish_decrypt(password, strlen(password), encrypted); @@ -109,10 +110,10 @@ char *keystore_get_key(const char *nick) { /** * Deletes a nick and the associated key in the key store file. */ -static bool delete_nick(GKeyFile *keyfile, const char *nick) { +static gboolean delete_nick(GKeyFile *keyfile, const char *nick) { gchar **group; gchar **groups = g_key_file_get_groups(keyfile, NULL); - bool ok = false; + gboolean ok = FALSE; for (group = groups; *group != NULL; group++) { if (!irc_nick_cmp(*group, nick)) { @@ -125,58 +126,77 @@ static bool delete_nick(GKeyFile *keyfile, const char *nick) { return ok; } +#if !GLIB_CHECK_VERSION(2,40,0) /** * Writes the key store file to disk. */ -static bool save_keystore(GKeyFile *keyfile) { - char *filename; - bool ok; - // Serialize +static gboolean keyfile_save_to_file (GKeyFile *keyfile, char *filename) { + gboolean ok; + + /* Serialize */ gsize file_length; gchar *file_data = g_key_file_to_data(keyfile, &file_length, NULL); - if (!file_data) return false; - - // Write to file - filename = get_config_filename(); - ok = g_file_set_contents(filename, file_data, file_length, NULL); - g_free(filename); + if (!file_data) + return FALSE; + + /* Write to file */ + ok = g_file_set_contents (filename, file_data, file_length, NULL); g_free(file_data); return ok; } +#endif + +/** + * Writes the key store file to disk. + */ +static gboolean save_keystore(GKeyFile *keyfile) { + char *filename; + gboolean ok; + + filename = get_config_filename(); +#if !GLIB_CHECK_VERSION(2,40,0) + ok = keyfile_save_to_file (keyfile, filename); +#else + ok = g_key_file_save_to_file (keyfile, filename, NULL); +#endif + g_free (filename); + + return ok; +} /** * Sets a key in the key store file. */ -bool keystore_store_key(const char *nick, const char *key) { +gboolean keystore_store_key(const char *nick, const char *key) { const char *password; char *encrypted; char *wrapped; - bool ok = false; + gboolean ok = FALSE; GKeyFile *keyfile = getConfigFile(); - // Remove old key + /* Remove old key */ delete_nick(keyfile, nick); - // Add new key + /* Add new key */ password = get_keystore_password(); if (password) { - // Encrypt the password + /* Encrypt the password */ encrypted = fish_encrypt(password, strlen(password), key); if (!encrypted) goto end; - // Prepend "+OK " + /* Prepend "+OK " */ wrapped = g_strconcat("+OK ", encrypted, NULL); g_free(encrypted); - // Store encrypted in file + /* Store encrypted in file */ g_key_file_set_string(keyfile, nick, "key", wrapped); - free(wrapped); + g_free(wrapped); } else { - // Store unencrypted in file + /* Store unencrypted in file */ g_key_file_set_string(keyfile, nick, "key", key); } - // Save key store file + /* Save key store file */ ok = save_keystore(keyfile); end: @@ -187,23 +207,15 @@ bool keystore_store_key(const char *nick, const char *key) { /** * Deletes a nick from the key store. */ -bool keystore_delete_nick(const char *nick) { +gboolean keystore_delete_nick(const char *nick) { GKeyFile *keyfile = getConfigFile(); - // Delete entry - bool ok = delete_nick(keyfile, nick); + /* Delete entry */ + gboolean ok = delete_nick(keyfile, nick); - // Save + /* Save */ if (ok) save_keystore(keyfile); g_key_file_free(keyfile); return ok; } - - -void keystore_secure_free(void *ptr, size_t size) { - secure_erase(ptr, size); - free(ptr); -} - - diff --git a/plugins/fishlim/keystore.h b/plugins/fishlim/keystore.h index a2c33f02..3d90606a 100644 --- a/plugins/fishlim/keystore.h +++ b/plugins/fishlim/keystore.h @@ -25,14 +25,13 @@ #ifndef KEYSTORE_H #define KEYSTORE_H -#include <stdbool.h> #include <stddef.h> -char *keystore_get_key(const char *nick); -bool keystore_store_key(const char *nick, const char *key); -bool keystore_delete_nick(const char *nick); +#include <glib.h> -void keystore_secure_free(void *ptr, size_t size); +char *keystore_get_key(const char *nick); +gboolean keystore_store_key(const char *nick, const char *key); +gboolean keystore_delete_nick(const char *nick); #endif diff --git a/plugins/fishlim/misc.c b/plugins/fishlim/misc.c deleted file mode 100644 index 2b78961d..00000000 --- a/plugins/fishlim/misc.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - - Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - -*/ - -#include <glib.h> -#include <stdlib.h> -#include <string.h> -#include "misc.h" - - -void secure_erase(void *ptr, size_t size) { - // "volatile" prevents this code from being optimized away - volatile char* volptr = ptr; - while (size--) *volptr++ = 0; -} - -/** - * Re-allocates a string with the native allocator. - */ -char *import_glib_string(gchar *gstr) { - size_t size; - char *native; - if (g_mem_is_system_malloc()) return gstr; - - size = strlen(gstr)+1; - native = malloc(size); - memcpy(native, gstr, size); - - secure_erase(gstr, size); - g_free(gstr); - return native; -} - - diff --git a/plugins/fishlim/misc.h b/plugins/fishlim/misc.h deleted file mode 100644 index ee4fc5b8..00000000 --- a/plugins/fishlim/misc.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - - Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - -*/ - -#ifndef MISC_H -#define MISC_H - -void secure_erase(void *ptr, size_t size); - -#ifdef __G_LIB_H__ -char *import_glib_string(gchar *gstr); -#endif - -#endif - - diff --git a/plugins/fishlim/plugin_hexchat.c b/plugins/fishlim/plugin_hexchat.c index f200ea8c..556a2f51 100644 --- a/plugins/fishlim/plugin_hexchat.c +++ b/plugins/fishlim/plugin_hexchat.c @@ -22,17 +22,14 @@ */ +#include "config.h" + #include <glib.h> #include <stdlib.h> #include <string.h> -// #pragma GCC visibility push(default) #include "hexchat-plugin.h" #define HEXCHAT_MAX_WORDS 32 -// #pragma GCC visibility pop - -//#define EXPORT __attribute((visibility("default"))) -//#define EXPORT #include "fish.h" #include "keystore.h" @@ -52,26 +49,18 @@ static hexchat_plugin *ph; * Returns the path to the key store file. */ gchar *get_config_filename() { - return g_build_filename(hexchat_get_info(ph, "configdir"), "addon_fishlim.conf", NULL); -} + char *filename_fs, *filename_utf8; -/** - * Appends data to a string. Returns true if there was sufficient memory. - * Frees *s and returns false if an error occurs. - */ -static bool append(char **s, size_t *length, const char *data) { - size_t datalen = strlen(data); - char *extended = realloc(*s, *length + datalen + 1); - if (!extended) { - free(*s); - return false; - } - memcpy(extended + *length, data, datalen + 1); - *s = extended; - *length += datalen; - return true; + filename_utf8 = g_build_filename(hexchat_get_info(ph, "configdir"), "addon_fishlim.conf", NULL); + filename_fs = g_filename_from_utf8 (filename_utf8, -1, NULL, NULL, NULL); + + g_free (filename_utf8); + return filename_fs; } +int irc_nick_cmp(const char *a, const char *b) { + return hexchat_nickcmp (ph, a, b); +} /*static int handle_debug(char *word[], char *word_eol[], void *userdata) { hexchat_printf(ph, "debug incoming: "); @@ -87,26 +76,26 @@ static bool append(char **s, size_t *length, const char *data) { */ static int handle_outgoing(char *word[], char *word_eol[], void *userdata) { const char *own_nick; - // Encrypt the message if possible + /* Encrypt the message if possible */ const char *channel = hexchat_get_info(ph, "channel"); char *encrypted = fish_encrypt_for_nick(channel, word_eol[1]); if (!encrypted) return HEXCHAT_EAT_NONE; - // Display message + /* Display message */ own_nick = hexchat_get_info(ph, "nick"); hexchat_emit_print(ph, "Your Message", own_nick, word_eol[1], NULL); - // Send message + /* Send message */ hexchat_commandf(ph, "PRIVMSG %s :+OK %s", channel, encrypted); - free(encrypted); + g_free(encrypted); return HEXCHAT_EAT_HEXCHAT; } /** * Called when a channel message or private message is received. */ -static int handle_incoming(char *word[], char *word_eol[], void *userdata) { +static int handle_incoming(char *word[], char *word_eol[], hexchat_event_attrs *attrs, void *userdata) { const char *prefix; const char *command; const char *recipient; @@ -114,20 +103,19 @@ static int handle_incoming(char *word[], char *word_eol[], void *userdata) { const char *peice; char *sender_nick; char *decrypted; - char *message; size_t w; size_t ew; size_t uw; - size_t length; char prefix_char = 0; + GString *message; if (!irc_parse_message((const char **)word, &prefix, &command, &w)) return HEXCHAT_EAT_NONE; - // Topic (command 332) has an extra parameter + /* Topic (command 332) has an extra parameter */ if (!strcmp(command, "332")) w++; - // Look for encrypted data + /* Look for encrypted data */ for (ew = w+1; ew < HEXCHAT_MAX_WORDS-1; ew++) { const char *s = (ew == w+1 ? word[ew]+1 : word[ew]); if (*s && (s[1] == '+' || s[1] == 'm')) { prefix_char = *(s++); } @@ -136,61 +124,70 @@ static int handle_incoming(char *word[], char *word_eol[], void *userdata) { } return HEXCHAT_EAT_NONE; has_encrypted_data: ; - // Extract sender nick and recipient nick/channel + /* Extract sender nick and recipient nick/channel */ sender_nick = irc_prefix_get_nick(prefix); recipient = word[w]; - // Try to decrypt with these (the keys are searched for in the key store) + /* Try to decrypt with these (the keys are searched for in the key store) */ encrypted = word[ew+1]; decrypted = fish_decrypt_from_nick(recipient, encrypted); if (!decrypted) decrypted = fish_decrypt_from_nick(sender_nick, encrypted); - // Check for error + /* Check for error */ if (!decrypted) goto decrypt_error; - // Build unecrypted message - message = NULL; - length = 0; - if (!append(&message, &length, "RECV")) goto decrypt_error; - + /* Build unecrypted message */ + message = g_string_sized_new (100); /* TODO: more accurate estimation of size */ + g_string_append (message, "RECV"); + + if (attrs->server_time_utc) + { + GTimeVal tv = { (glong)attrs->server_time_utc, 0 }; + char *timestamp = g_time_val_to_iso8601 (&tv); + + g_string_append (message, " @time="); + g_string_append (message, timestamp); + g_free (timestamp); + } + for (uw = 1; uw < HEXCHAT_MAX_WORDS; uw++) { - if (word[uw][0] != '\0' && !append(&message, &length, " ")) goto decrypt_error; + if (word[uw][0] != '\0') + g_string_append_c (message, ' '); if (uw == ew) { - // Add the encrypted data + /* Add the encrypted data */ peice = decrypted; - uw++; // Skip "OK+" + uw++; /* Skip "OK+" */ if (ew == w+1) { - // Prefix with colon, which gets stripped out otherwise - if (!append(&message, &length, ":")) goto decrypt_error; + /* Prefix with colon, which gets stripped out otherwise */ + g_string_append_c (message, ':'); } if (prefix_char) { - char prefix_str[2] = { prefix_char, '\0' }; - if (!append(&message, &length, prefix_str)) goto decrypt_error; + g_string_append_c (message, prefix_char); } } else { - // Add unencrypted data (for example, a prefix from a bouncer or bot) + /* Add unencrypted data (for example, a prefix from a bouncer or bot) */ peice = word[uw]; } - - if (!append(&message, &length, peice)) goto decrypt_error; + + g_string_append (message, peice); } - free(decrypted); + g_free(decrypted); - // Simulate unencrypted message - //hexchat_printf(ph, "simulating: %s\n", message); - hexchat_command(ph, message); - - free(message); - free(sender_nick); + /* Simulate unencrypted message */ + /* hexchat_printf(ph, "simulating: %s\n", message->str); */ + hexchat_command(ph, message->str); + + g_string_free (message, TRUE); + g_free(sender_nick); return HEXCHAT_EAT_HEXCHAT; decrypt_error: - free(decrypted); - free(sender_nick); + g_free(decrypted); + g_free(sender_nick); return HEXCHAT_EAT_NONE; } @@ -201,23 +198,23 @@ static int handle_setkey(char *word[], char *word_eol[], void *userdata) { const char *nick; const char *key; - // Check syntax + /* Check syntax */ if (*word[2] == '\0') { hexchat_printf(ph, "%s\n", usage_setkey); return HEXCHAT_EAT_HEXCHAT; } if (*word[3] == '\0') { - // /setkey password + /* /setkey password */ nick = hexchat_get_info(ph, "channel"); key = word_eol[2]; } else { - // /setkey #channel password + /* /setkey #channel password */ nick = word[2]; key = word_eol[3]; } - // Set password + /* Set password */ if (keystore_store_key(nick, key)) { hexchat_printf(ph, "Stored key for %s\n", nick); } else { @@ -233,15 +230,15 @@ static int handle_setkey(char *word[], char *word_eol[], void *userdata) { static int handle_delkey(char *word[], char *word_eol[], void *userdata) { const char *nick; - // Check syntax + /* Check syntax */ if (*word[2] == '\0' || *word[3] != '\0') { hexchat_printf(ph, "%s\n", usage_delkey); return HEXCHAT_EAT_HEXCHAT; } - nick = word_eol[2]; + nick = g_strstrip (word_eol[2]); - // Delete the given nick from the key store + /* Delete the given nick from the key store */ if (keystore_delete_nick(nick)) { hexchat_printf(ph, "Deleted key for %s\n", nick); } else { @@ -282,11 +279,11 @@ int hexchat_plugin_init(hexchat_plugin *plugin_handle, /* Add handlers */ hexchat_hook_command(ph, "", HEXCHAT_PRI_NORM, handle_outgoing, NULL, NULL); - hexchat_hook_server(ph, "NOTICE", HEXCHAT_PRI_NORM, handle_incoming, NULL); - hexchat_hook_server(ph, "PRIVMSG", HEXCHAT_PRI_NORM, handle_incoming, NULL); - //hexchat_hook_server(ph, "RAW LINE", HEXCHAT_PRI_NORM, handle_debug, NULL); - hexchat_hook_server(ph, "TOPIC", HEXCHAT_PRI_NORM, handle_incoming, NULL); - hexchat_hook_server(ph, "332", HEXCHAT_PRI_NORM, handle_incoming, NULL); + hexchat_hook_server_attrs(ph, "NOTICE", HEXCHAT_PRI_NORM, handle_incoming, NULL); + hexchat_hook_server_attrs(ph, "PRIVMSG", HEXCHAT_PRI_NORM, handle_incoming, NULL); + /* hexchat_hook_server(ph, "RAW LINE", HEXCHAT_PRI_NORM, handle_debug, NULL); */ + hexchat_hook_server_attrs(ph, "TOPIC", HEXCHAT_PRI_NORM, handle_incoming, NULL); + hexchat_hook_server_attrs(ph, "332", HEXCHAT_PRI_NORM, handle_incoming, NULL); hexchat_printf(ph, "%s plugin loaded\n", plugin_name); /* Return success */ diff --git a/plugins/fishlim/plugin_hexchat.h b/plugins/fishlim/plugin_hexchat.h index 04a1f4ff..f60522e6 100644 --- a/plugins/fishlim/plugin_hexchat.h +++ b/plugins/fishlim/plugin_hexchat.h @@ -26,6 +26,7 @@ #define PLUGIN_HEXCHAT_H gchar *get_config_filename(); +int irc_nick_cmp (const char *, const char *); #endif diff --git a/plugins/fishlim/test.c b/plugins/fishlim/test.c deleted file mode 100644 index b4dc8d91..00000000 --- a/plugins/fishlim/test.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - - Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se> - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - -*/ - -#include <glib.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "fish.h" - -// We can't use the HexChat plugin API from here... -gchar *get_config_filename() { - const gchar *homedir = g_get_home_dir(); - return g_build_filename(homedir, ".config", "hexchat", "blow.ini", NULL); -} - - -static int decrypt(int nick_count, char *nicks[]) { - char encrypted[8192]; - while (fgets(encrypted, sizeof(encrypted), stdin)) { - char *msg; - for (int i = 0; i < nick_count; i++) { - msg = fish_decrypt_from_nick(nicks[i], encrypted); - if (msg) goto success; - } - fprintf(stderr, "None of the recipients were found in the key store!\n"); - return 1; - success: - fprintf(stderr, "Decrypted text >>>%s<<<\n", msg); - free(msg); - } - return 0; -} - -static int encrypt(int nick_count, char *nicks[]) { - char message[8192]; - while (fgets(message, sizeof(message), stdin)) { - // Remove newline character - char *newline = strchr(message, '\n'); - if (newline) *newline = '\0'; - - bool error = false; - for (int i = 0; i < nick_count; i++) { - char *encrypted = fish_encrypt_for_nick(nicks[i], message); - if (encrypted) { - fprintf(stderr, "Encrypted [%s]: >>>%s<<<\n", nicks[i], encrypted); - free(encrypted); - } else { - error = true; - } - } - - if (error) { - fprintf(stderr, "Some of the recipients were't found in the key store!\n"); - return 1; - } - } - return 0; -} - -int main(int argc, char *argv[]) { - if (argc < 2) { - fprintf(stderr, "usage: %s [-e] nick...\n", argv[0]); - return 2; - } - - if (strcmp(argv[1], "-e") == 0) { - return encrypt(argc-2, &argv[2]); - } else { - return decrypt(argc-1, &argv[1]); - } -} - - diff --git a/plugins/mpcinfo/functions.c b/plugins/mpcinfo/functions.c index ff2d563e..e5993948 100644 --- a/plugins/mpcinfo/functions.c +++ b/plugins/mpcinfo/functions.c @@ -14,54 +14,27 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -/* -typedef int (*MYPROC)(HWND,HWND,char*,char*,BOOL,BOOL); - -int dllProc(char *name, char *data){ - HINSTANCE hinstLib; - hinstLib = LoadLibrary("mpcinfo"); - //MYPROC proc; - int res; - if (hinstLib != NULL){ - //proc = ; - if ((MYPROC) GetProcAddress(hinstLib, name)!=NULL){ - res=(MYPROC)(NULL,NULL,data,NULL,TRUE,TRUE); - } - else{fprintf(stderr,"can't get proc: %s\n",name);res=-2;} - } - else{fprintf(stderr,"can't access dll\n");return -1;} - FreeLibrary(hinstLib); - return res; -} -*/ +#include <glib.h> -/* -int dllProc(char *name, char *data) +char *split(char *text, char separator) { - static HMODULE lib = NULL; - if (!lib) + int pos = -1; + size_t i; + for (i = 0; i < strlen(text); i++) { - lib = LoadLibraryA ("mpcinfo"); - if (!lib) - { - return FALSE; + if (text[i] == separator) { + pos = i; + i = strlen(text) + 1; } - FreeLibrary (lib); } - return TRUE; -} -*/ + if (pos == -1) + { + return text; + } -char *split(char *text, char seperator){ - //if (DEBUG==1) putlog("splitting"); - int i;int pos=-1; - for (i=0;i<strlen(text);i++){ - if (text[i]==seperator){pos=i;i=strlen(text)+1;} - } - if (pos==-1) return text; - text[pos]=0; - return &(text[pos+1]); + text[pos] = 0; + return &(text[pos + 1]); } int endsWith(char *text, char *suffix){ @@ -71,21 +44,32 @@ int endsWith(char *text, char *suffix){ return 0; } -int inStr(char *s1, int sl1, char *s2){ - //if (DEBUG==1) putlog("checking instr"); - int i;int j; - for(i=0;i<sl1-strlen(s2);i++){ - for (j=0;j<strlen(s2);j++){ - if (s1[i+j]!=s2[j]) j=strlen(s2)+2; +int inStr(char *s1, size_t sl1, char *s2) +{ + size_t i; + for (i = 0; i < sl1 - strlen(s2); i++) + { + size_t j; + for (j = 0; j < strlen(s2); j++) + { + if (s1[i + j] != s2[j]) + { + j = strlen(s2) + 2; + } + } + + if (j == strlen(s2)) + { + return i; } - if (j==strlen(s2)) return i; } + return -1; } static char *subString(char *text, int first, int length, int spcKill){ //if (DEBUG==1) putlog("creating substring"); - char *ret=(char*) calloc (length+1,sizeof(char)); //malloc(sizeof(char)*(length+1)); + char *ret = g_new (char, length + 1); int i; ret[length]=0; for (i=0;i<length;i++){ @@ -107,7 +91,7 @@ static char *substring(char *text, int first, int length){return subString(text, char *readLine(FILE *f){ //if (DEBUG==1) putlog("reading line from file"); - char *buffer=(char*)calloc(1024,sizeof(char)); //malloc(sizeof(char)*1024); + char *buffer = g_new (char, 1024); int pos=0; int cc=0; while((cc!=EOF)&&(pos<1024)&&(cc!=10)){ @@ -121,14 +105,19 @@ char *readLine(FILE *f){ return buffer; } -char *toUpper(char *text){ - //if (DEBUG==1) putlog("converting text to upper case"); - char *ret=(char*) calloc(strlen(text)+1,sizeof(char)); - int i; - for (i=0;i<strlen(text);i++) ret[i]=toupper(text[i]); - ret[strlen(text)]=0; - //if (DEBUG==1) putlog("uc done"); - return ret; +char *toUpper(char *text) +{ + char *ret = (char*) calloc(strlen(text) + 1, sizeof(char)); + + size_t i; + for (i = 0; i < strlen(text); i++) + { + ret[i] = toupper(text[i]); + } + + ret[strlen(text)] = 0; + + return ret; } static char *str3cat(char *s1, char *s2, char *s3){ diff --git a/plugins/mpcinfo/mp3Info.c b/plugins/mpcinfo/mp3Info.c index 99718624..1af29e45 100644 --- a/plugins/mpcinfo/mp3Info.c +++ b/plugins/mpcinfo/mp3Info.c @@ -75,62 +75,25 @@ static char MODES [][13]={"Stereo","Joint-Stereo","Dual-Channel","Mono"}; int iPow(int x, int y){return (int)(pow((double)x,(double) y));} -int str2int(char *text){ - //if (DEBUG==1) putlog("converting string to int"); - int i; - int ret=0; - for (i=1;i<=strlen(text);i++){ - if ((text[strlen(text)-i]>57)||(text[strlen(text)-i]<48)){ - hexchat_printf(ph,"invalid char in string: %i",text[strlen(text)-i]); - return 255; - } - ret+=((int)text[strlen(text)-i]-48)*iPow(10,i-1); - } - //hexchat_printf(ph, "str2int(%s)=%i",text,ret); - //if (DEBUG==1) putlog("int converted"); - return ret; -} -/* -static int getSize(char *file){ - //if (DEBUG==1) putlog("reading filesize"); - struct stat info; - if (stat(file,&info)!=0) return -1; - return info.st_size; -}*/ -/* -int inStr(char *s1, int sl1, char *s2){ - //if (DEBUG==1) putlog("checking instr"); - int i;int j; - for(i=0;i<sl1-strlen(s2);i++){ - for (j=0;j<strlen(s2);j++){ - if (s1[i+j]!=s2[j]) j=strlen(s2)+2; +int str2int(char *text) +{ + int ret = 0; + + size_t i; + for (i = 1; i <= strlen(text); i++) + { + if ((text[strlen(text) - i] > 57) || (text[strlen(text) - i] < 48)) + { + hexchat_printf(ph, "invalid char in string: %i", (int) text[strlen(text) - i]); + return 255; } - if (j==strlen(s2)) return i; - } - return -1; -} -static char *subString(char *text, int first, int length, int spcKill){ -//if (DEBUG==1) putlog("creating substring"); - char *ret=(char*) calloc (length+1,sizeof(char)); //malloc(sizeof(char)*(length+1)); - ret[length]=0;int i; - for (i=0;i<length;i++){ - ret[i]=text[i+first]; - //if (ret[i]==0) ret[i]='0'; + ret += ((int) text[strlen(text) - i] - 48)*iPow(10, i - 1); } - if (spcKill==1){ - for (i=length-1;i>=0;i--){ - if (ret[i]==32) ret[i]=0; - else i=-1; - } - } - //if (DEBUG==1) putlog("substring created"); + return ret; } -static char *substring(char *text, int first, int length){return subString(text,first,length,0);} //1 -*/ - static char *tagExtract(char *tag, int tagLen, char* info){ //if (DEBUG==1) putlog("extracting tag"); int pos, len, i; @@ -204,23 +167,28 @@ struct tagInfo readID3V1(char *file){ return ret; } -char *extractID3Genre(char *tag){ - //if (DEBUG==1) putlog("extracting id3 genre"); - if (tag[strlen(tag)-1]==')'){ - tag[strlen(tag)-1]=0; - tag=&tag[1]; - return GENRES[str2int(tag)]; - //return tag; - } - else{ - int i; - //hexchat_print(ph, "Using 2 criteria"); - for (i=0;i<strlen(tag);i++){ - if (tag[i]==')'){ tag=&tag[i]+1;return tag;} - //return tag; - } - } - return "[152] failed"; +char *extractID3Genre(char *tag) +{ + if (tag[strlen(tag) - 1] == ')') + { + tag[strlen(tag) - 1] = 0; + tag = &tag[1]; + return GENRES[str2int(tag)]; + } + else + { + size_t i; + for (i = 0; i < strlen(tag); i++) + { + if (tag[i] == ')') + { + tag = &tag[i] + 1; + return tag; + } + } + } + + return "[152] failed"; } struct tagInfo readID3V2(char *file){ diff --git a/plugins/mpcinfo/mpcInfo.c b/plugins/mpcinfo/mpcInfo.c index 4ab16642..4ad17689 100644 --- a/plugins/mpcinfo/mpcInfo.c +++ b/plugins/mpcinfo/mpcInfo.c @@ -48,12 +48,20 @@ static int mpc_tell(char *word[], char *word_eol[], void *userdata){ HWND hwnd = FindWindow("MediaPlayerClassicW",NULL); if (hwnd==0) {hexchat_print(ph, randomLine(notRunTheme));return HEXCHAT_EAT_ALL;} - tTitle=(char*)malloc(sizeof(char)*1024); + tTitle = g_new(char, 1024); GetWindowText(hwnd, tTitle, 1024); - zero=strstr(tTitle," - Media Player Classic"); - if (zero!=NULL) zero[0]=0; - else hexchat_print(ph,"pattern not found"); - + zero = strstr (tTitle, " - Media Player Classic"); + if (zero != NULL) + { + zero[0] = 0; + } + else + { + g_free(tTitle); + hexchat_print(ph, "pattern not found"); + return HEXCHAT_EAT_ALL; + } + if ((tTitle[1]==':')&&(tTitle[2]=='\\')){ //hexchat_print(ph,"seams to be full path"); if (endsWith(tTitle,".mp3")==1){ @@ -82,7 +90,8 @@ static int mpc_tell(char *word[], char *word_eol[], void *userdata){ //mp3Line=intReplace(mp3Line,"%perc",perc); //mp3Line=replace(mp3Line,"%plTitle",title); mp3Line=replace(mp3Line,"%file",tTitle); - hexchat_command(ph, mp3Line); + g_free(tTitle); + hexchat_command(ph, mp3Line); return HEXCHAT_EAT_ALL; } } @@ -111,14 +120,16 @@ static int mpc_tell(char *word[], char *word_eol[], void *userdata){ //oggLine=intReplace(oggLine,"%perc",perc); //oggLine=replace(oggLine,"%plTitle",title); oggLine=replace(oggLine,"%file",tTitle); - hexchat_command(ph, oggLine); + g_free(tTitle); + hexchat_command(ph, oggLine); return HEXCHAT_EAT_ALL; } } } line=randomLine(titleTheme); line=replace(line,"%title", tTitle); - hexchat_command(ph,line); + g_free(tTitle); + hexchat_command(ph, line); return HEXCHAT_EAT_ALL; } diff --git a/plugins/mpcinfo/mpcinfo.vcxproj b/plugins/mpcinfo/mpcinfo.vcxproj index f69e8968..3c4b3e7d 100644 --- a/plugins/mpcinfo/mpcinfo.vcxproj +++ b/plugins/mpcinfo/mpcinfo.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -19,75 +20,32 @@ <RootNamespace>mpcinfo</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <TargetName>hcmpcinfo</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\hexchat.props" /> + <PropertyGroup> <TargetName>hcmpcinfo</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <OutDir>$(HexChatRel)plugins\</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MPCINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MultiProcessorCompilation>true</MultiProcessorCompilation> - <AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>..\..\src\common;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> <ModuleDefinitionFile>mpcinfo.def</ModuleDefinitionFile> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;MPCINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MultiProcessorCompilation>true</MultiProcessorCompilation> - <AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>..\..\src\common;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> <ModuleDefinitionFile>mpcinfo.def</ModuleDefinitionFile> </Link> </ItemDefinitionGroup> @@ -98,6 +56,4 @@ <ClCompile Include="mpcInfo.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/plugins/mpcinfo/oggInfo.c b/plugins/mpcinfo/oggInfo.c index 59d84791..e1191649 100644 --- a/plugins/mpcinfo/oggInfo.c +++ b/plugins/mpcinfo/oggInfo.c @@ -25,14 +25,18 @@ static int getOggInt(char *buff, int beg, int bytes){ return ret; } -static char *upperStr(char *text){ -//if (DEBUG==1) putlog("converting text to uc"); - //printf("upperStr(%s)\n",text); - int i; - char *ret=(char*) malloc(sizeof(char)*(strlen(text)+1)); - ret[strlen(text)]=0; - for (i=0;i<strlen(text);i++) ret[i]=toupper(text[i]); - //printf("Result: %s\n",ret); +static char *upperStr(char *text) +{ + char *ret = (char*) malloc(sizeof(char)*(strlen(text) + 1)); + + size_t i; + for (i = 0; i < strlen(text); i++) + { + ret[i] = toupper(text[i]); + } + + ret[strlen(text)] = 0; + return ret; } diff --git a/plugins/mpcinfo/theme.c b/plugins/mpcinfo/theme.c index 3f98a59c..3d8a7a0e 100644 --- a/plugins/mpcinfo/theme.c +++ b/plugins/mpcinfo/theme.c @@ -49,24 +49,32 @@ void printThemes(){ hexchat_printf(ph,"\nTitle-Theme:\n");printTheme(titleTheme); } -void cbFix(char *line){ - //if (DEBUG==1) putlog("cbfix"); - int i, j; - for (i=0;i<strlen(line);i++){ - if (line[i]=='%'){ - if ((line[i+1]=='C')||(line[i+1]=='B')||(line[i+1]=='U')||(line[i+1]=='O')||(line[i+1]=='R')){ - if(line[i+1]=='C') line[i]=3; - if(line[i+1]=='B') line[i]=2; - if(line[i+1]=='U') line[i]=37; - if(line[i+1]=='O') line[i]=17; - if(line[i+1]=='R') line[i]=26; - - for (j=i+1;j<strlen(line)-1;j++) line[j]=line[j+1]; - line[strlen(line)-1]=0; - } - } - } - //if (DEBUG==1) putlog("cbfix done"); +void cbFix(char *line) +{ + size_t i; + for (i = 0; i < strlen(line); i++) + { + size_t j; + + if (line[i] == '%') + { + if ((line[i + 1] == 'C') || (line[i + 1] == 'B') || (line[i + 1] == 'U') || (line[i + 1] == 'O') || (line[i + 1] == 'R')) + { + if (line[i + 1] == 'C') line[i] = 3; + if (line[i + 1] == 'B') line[i] = 2; + if (line[i + 1] == 'U') line[i] = 37; + if (line[i + 1] == 'O') line[i] = 17; + if (line[i + 1] == 'R') line[i] = 26; + + for (j = i + 1; j < strlen(line) - 1; j++) + { + line[j] = line[j + 1]; + } + + line[strlen(line) - 1] = 0; + } + } + } } struct theme themeAdd(struct theme data, char *info){ diff --git a/plugins/perl/Makefile.am b/plugins/perl/Makefile.am index 79621549..83239672 100644 --- a/plugins/perl/Makefile.am +++ b/plugins/perl/Makefile.am @@ -6,12 +6,13 @@ libdir = $(hexchatlibdir) lib_LTLIBRARIES = perl.la perl_la_SOURCES = perl.c -perl_la_LDFLAGS = -avoid-version -module -perl_la_LIBADD = $(PERL_LDFLAGS) +perl_la_LDFLAGS = $(PERL_LDFLAGS) $(PLUGIN_LDFLAGS) -module +perl_la_LIBADD = $(GLIB_LIBS) +perl_la_CFLAGS = $(PERL_CFLAGS) $(GLIB_CFLAGS) -I$(top_srcdir)/src/common + BUILT_SOURCES = hexchat.pm.h irc.pm.h -#CFLAGS = @CFLAGS@ -Wno-unused -AM_CPPFLAGS = $(PERL_CFLAGS) $(COMMON_CFLAGS) -I$(srcdir)/../../src/common -CLEANFILES = hexchat.pm.h irc.pm.h +CLEANFILES = $(BUILT_SOURCES) + hexchat.pm.h irc.pm.h: lib/HexChat.pm lib/Xchat.pm lib/HexChat/Embed.pm \ lib/HexChat/List/Network.pm lib/HexChat/List/Network/Entry.pm \ lib/HexChat/List/Network/AutoJoin.pm lib/IRC.pm diff --git a/plugins/perl/perl.c b/plugins/perl/perl.c index 74333516..b954fb0b 100644 --- a/plugins/perl/perl.c +++ b/plugins/perl/perl.c @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -31,8 +33,9 @@ #include <dirent.h> #endif +#include <glib.h> + #undef PACKAGE -#include "../../config.h" #include "hexchat-plugin.h" @@ -75,37 +78,26 @@ thread_mbox (char *str) static void perl_auto_load_from_path (const char *path) { - WIN32_FIND_DATA find_data; - HANDLE find_handle; - char *search_path; - int path_len = strlen (path); - - /* +6 for \*.pl and \0 */ - search_path = malloc(path_len + 6); - sprintf (search_path, "%s\\*.pl", path); - - find_handle = FindFirstFile (search_path, &find_data); + char *search_path = g_build_filename (path, "*.pl", NULL); + WIN32_FIND_DATAA find_data; + HANDLE find_handle = FindFirstFileA (search_path, &find_data); if (find_handle != INVALID_HANDLE_VALUE) { do { - if (!(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY - ||find_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) + if ((find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 && (find_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0) { - char *full_path = - malloc (path_len + strlen (find_data.cFileName) + 2); - sprintf (full_path, "%s\\%s", path, find_data.cFileName); - + char *full_path = g_build_filename (path, find_data.cFileName, NULL); perl_load_file (full_path); - free (full_path); + g_free (full_path); } } - while (FindNextFile (find_handle, &find_data) != 0); + while (FindNextFileA (find_handle, &find_data) != 0); FindClose (find_handle); } - free (search_path); + g_free (search_path); } #else static void @@ -115,14 +107,16 @@ perl_auto_load_from_path (const char *path) struct dirent *ent; dir = opendir (path); - if (dir) { - while ((ent = readdir (dir))) { + if (dir) + { + while ((ent = readdir (dir))) + { int len = strlen (ent->d_name); - if (len > 3 && strcasecmp (".pl", ent->d_name + len - 3) == 0) { - char *file = malloc (len + strlen (path) + 2); - sprintf (file, "%s/%s", path, ent->d_name); + if (len > 3 && strcasecmp (".pl", ent->d_name + len - 3) == 0) + { + char *file = g_build_filename (path, ent->d_name, NULL); perl_load_file (file); - free (file); + g_free (file); } } closedir (dir); @@ -145,31 +139,10 @@ perl_auto_load (void *unused) /* don't pollute the filesystem with script files, this only causes misuse of the folders * only use ~/.config/hexchat/addons/ and %APPDATA%\HexChat\addons */ -#if 0 - /* autoload from ~/.config/hexchat/ or %APPDATA%\HexChat\ on win32 */ - perl_auto_load_from_path (xdir); -#endif - - sub_dir = malloc (strlen (xdir) + 8); - strcpy (sub_dir, xdir); - strcat (sub_dir, "/addons"); + sub_dir = g_build_filename (xdir, "addons", NULL); perl_auto_load_from_path (sub_dir); - free (sub_dir); + g_free (sub_dir); -#if 0 -#ifdef WIN32 - /* autoload from C:\Program Files\HexChat\plugins\ */ - sub_dir = malloc (1025 + 9); - copied = GetModuleFileName( 0, sub_dir, 1024 ); - sub_dir[copied] = '\0'; - slash = strrchr( sub_dir, '\\' ); - if( slash != NULL ) { - *slash = '\0'; - } - perl_auto_load_from_path ( strncat (sub_dir, "\\plugins", 9)); - free (sub_dir); -#endif -#endif return 0; } @@ -288,7 +261,19 @@ list_item_to_sv ( hexchat_list *list, const char *const *fields ) field_value = newSVuv (hexchat_list_int (ph, list, field_name)); break; case 't': - field_value = newSVnv (hexchat_list_time (ph, list, field_name)); + /* From perldoc for Perl's own timelocal() and timegm(): + * <quote> + * On perl versions older than 5.12.0, the range of dates that can be actually be handled depends on the size of time_t (usually a signed integer) on the given platform. + * As of version 5.12.0, perl has stopped using the underlying time library of the operating system it's running on and has its own implementation of those routines with a + * safe range of at least +/ 2**52 (about 142 million years). + * </quote> + * + * This is further confirmed from looking at the source for Time::Local - it's a Perl module and the implementations of timelocal() and timegm() use simple addition and + * subtraction of numbers. Perl automatically promotes numbers from int32_t (IV) to uint32_t (UV) to 64-bit IEEE754 double (NV) as required. + * + * This means that using a double (NV) for our own time_t suffers from the same assumptions that Perl's own functions do. + */ + field_value = newSVnv ((const NV) hexchat_list_time (ph, list, field_name)); break; default: field_value = &PL_sv_undef; @@ -372,7 +357,7 @@ fd_cb (int fd, int flags, void *userdata) if (data->userdata) { SvREFCNT_dec (data->userdata); } - free (data); + g_free (data); } } @@ -736,7 +721,7 @@ XS (XS_HexChat_send_modes) if (SvROK (ST (0))) { p_targets = (AV*) SvRV (ST (0)); target_count = av_len (p_targets) + 1; - targets = malloc (target_count * sizeof (char *)); + targets = g_new (const char *, target_count); for (i = 0; i < target_count; i++ ) { elem = av_fetch (p_targets, i, 0); @@ -747,13 +732,13 @@ XS (XS_HexChat_send_modes) } } } else{ - targets = malloc (sizeof (char *)); + targets = g_new (const char *, 1); targets[0] = SvPV_nolen (ST (0)); target_count = 1; } if (target_count == 0) { - free (targets); + g_free ((char**) targets); XSRETURN_EMPTY; } @@ -765,7 +750,7 @@ XS (XS_HexChat_send_modes) } hexchat_send_modes (ph, targets, target_count, modes_per_line, sign, mode); - free (targets); + g_free ((char**) targets); } } static @@ -883,11 +868,7 @@ XS (XS_HexChat_hook_server) userdata = ST (3); package = ST (4); data = NULL; - data = malloc (sizeof (HookData)); - if (data == NULL) { - XSRETURN_UNDEF; - } - + data = g_new (HookData, 1); data->callback = newSVsv (callback); data->userdata = newSVsv (userdata); data->depth = 0; @@ -932,11 +913,7 @@ XS (XS_HexChat_hook_command) package = ST (5); data = NULL; - data = malloc (sizeof (HookData)); - if (data == NULL) { - XSRETURN_UNDEF; - } - + data = g_new (HookData, 1); data->callback = newSVsv (callback); data->userdata = newSVsv (userdata); data->depth = 0; @@ -972,11 +949,7 @@ XS (XS_HexChat_hook_print) userdata = ST (3); package = ST (4); - data = malloc (sizeof (HookData)); - if (data == NULL) { - XSRETURN_UNDEF; - } - + data = g_new (HookData, 1); data->callback = newSVsv (callback); data->userdata = newSVsv (userdata); data->depth = 0; @@ -1010,11 +983,7 @@ XS (XS_HexChat_hook_timer) userdata = ST (2); package = ST (3); - data = malloc (sizeof (HookData)); - if (data == NULL) { - XSRETURN_UNDEF; - } - + data = g_new (HookData, 1); data->callback = newSVsv (callback); data->userdata = newSVsv (userdata); data->ctx = hexchat_get_context (ph); @@ -1064,11 +1033,7 @@ XS (XS_HexChat_hook_fd) } #endif - data = malloc (sizeof (HookData)); - if (data == NULL) { - XSRETURN_UNDEF; - } - + data = g_new (HookData, 1); data->callback = newSVsv (callback); data->userdata = newSVsv (userdata); data->depth = 0; @@ -1108,7 +1073,7 @@ XS (XS_HexChat_unhook) SvREFCNT_dec (userdata->package); } - free (userdata); + g_free (userdata); } XSRETURN (retCount); } diff --git a/plugins/perl/perl.vcxproj b/plugins/perl/perl.vcxproj index 1a76928d..e9b380ee 100644 --- a/plugins/perl/perl.vcxproj +++ b/plugins/perl/perl.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -19,66 +20,28 @@ <RootNamespace>perl520</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <TargetName>$(PerlOutput)</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - <TargetName>$(PerlOutput)</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\hexchat.props" /> + <PropertyGroup> + <TargetName>hcperl</TargetName> + <OutDir>$(HexChatRel)plugins\</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PERL520_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(PerlPath)\lib\CORE;$(IntDir);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>$(IntDir);..\..\src\common;$(HexChatLib);$(PerlPath)\lib\CORE;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - <AdditionalDependencies>$(PerlLib).lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(IntDir);$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>$(PerlLib).lib;$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> <ModuleDefinitionFile>perl.def</ModuleDefinitionFile> <DelayLoadDLLs>$(PerlLib).dll;%(DelayLoadDLLs)</DelayLoadDLLs> </Link> <PreBuildEvent> <Command>"$(GendefPath)\gendef" "$(PerlPath)\bin\$(PerlLib).dll" move $(PerlLib).def "$(IntDir)" -lib /nologo /machine:x86 "/def:$(IntDir)$(PerlLib).def" "/out:$(OutDir)\$(PerlLib).lib" +lib /nologo /machine:x86 "/def:$(IntDir)$(PerlLib).def" "/out:$(IntDir)\$(PerlLib).lib" "$(PerlPath)\bin\perl.exe" generate_header move irc.pm.h "$(IntDir)" move hexchat.pm.h "$(IntDir)"</Command> @@ -86,28 +49,19 @@ move hexchat.pm.h "$(IntDir)"</Command> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;PERL520_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(PerlPath)\lib\CORE;$(IntDir);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>$(IntDir);..\..\src\common;$(HexChatLib);$(PerlPath)\lib\CORE;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - <AdditionalDependencies>$(PerlLib).lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(IntDir);$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>$(PerlLib).lib;$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> <ModuleDefinitionFile>perl.def</ModuleDefinitionFile> <DelayLoadDLLs>$(PerlLib).dll;%(DelayLoadDLLs)</DelayLoadDLLs> </Link> <PreBuildEvent> <Command>"$(GendefPath)\gendef" "$(PerlPath)\bin\$(PerlLib).dll" move $(PerlLib).def "$(IntDir)" -lib /nologo /machine:x64 "/def:$(IntDir)$(PerlLib).def" "/out:$(OutDir)\$(PerlLib).lib" +lib /nologo /machine:x64 "/def:$(IntDir)$(PerlLib).def" "/out:$(IntDir)\$(PerlLib).lib" "$(PerlPath)\bin\perl.exe" generate_header move irc.pm.h "$(IntDir)" move hexchat.pm.h "$(IntDir)"</Command> @@ -120,6 +74,4 @@ move hexchat.pm.h "$(IntDir)"</Command> <ClCompile Include="perl.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/plugins/plugin-conf.in b/plugins/plugin-conf.in deleted file mode 100644 index f43f5c53..00000000 --- a/plugins/plugin-conf.in +++ /dev/null @@ -1,19 +0,0 @@ -AC_INIT(@PLUGIN@-config.h.in) -AM_CONFIG_HEADER(@PLUGIN@-config.h) -AM_INIT_AUTOMAKE(hexchat-@PLUGIN@, @PLUGIN_VERSION@) -AM_MAINTAINER_MODE -AM_DISABLE_STATIC -AM_PROG_LIBTOOL - -AC_ARG_WITH(plugin-includes, -[ --with-plugin-includes directory containing hexchat-plugin.h], - PLUGIN_INCLUDES=$enableval) - -AC_SUBST(PLUGIN_INCLUDES) - -hexchatlibdir=${libdir}/hexchat -AC_SUBST(hexchatlibdir) - -AC_OUTPUT( -Makefile -) diff --git a/plugins/python/Makefile.am b/plugins/python/Makefile.am index 259f2a0f..063f2009 100644 --- a/plugins/python/Makefile.am +++ b/plugins/python/Makefile.am @@ -1,10 +1,8 @@ -EXTRA_DIST = - libdir = $(hexchatlibdir) lib_LTLIBRARIES = python.la python_la_SOURCES = python.c -python_la_LDFLAGS = -avoid-version -module -python_la_LIBADD = $(PY_LIBS) -AM_CPPFLAGS = $(PY_CFLAGS) $(COMMON_CFLAGS) -I$(srcdir)/../../src/common +python_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module +python_la_LIBADD = $(PY_LIBS) $(GLIB_LIBS) +python_la_CFLAGS = $(PY_CFLAGS) $(GLIB_CFLAGS) -I$(top_srcdir)/src/common diff --git a/plugins/python/python.c b/plugins/python/python.c index 1904a3e9..1f9c7cc9 100644 --- a/plugins/python/python.c +++ b/plugins/python/python.c @@ -51,6 +51,8 @@ * */ +#include "config.h" + #include <glib.h> #include <glib/gstdio.h> #include <string.h> @@ -64,9 +66,9 @@ #include <dirent.h> #endif -#include "../../config.h" #include "hexchat-plugin.h" -#undef _POSIX_C_SOURCE /* Avoid warning: also in /usr/include/features.h from glib.h */ +#undef _POSIX_C_SOURCE /* Avoid warnings from /usr/include/features.h */ +#undef _XOPEN_SOURCE #include <Python.h> #include <structmember.h> #include <pythread.h> @@ -414,6 +416,9 @@ Util_BuildEOLList(char *word[]) PyObject *list; int listsize = 31; int i; + char *accum = NULL; + char *last = NULL; + /* Find the last valid array member; there may be intermediate NULLs that * would otherwise cause us to drop some members. */ while (listsize > 0 && @@ -424,10 +429,9 @@ Util_BuildEOLList(char *word[]) PyErr_Print(); return NULL; } - char *accum = NULL; - char *last = NULL; for (i = listsize; i > 0; i--) { char *part = word[i]; + PyObject *uni_part; if (accum == NULL) { accum = g_strdup (part); } else if (part != NULL && part[0] != 0) { @@ -443,14 +447,12 @@ Util_BuildEOLList(char *word[]) return NULL; } } - PyObject *uni_part = PyUnicode_FromString(accum); + uni_part = PyUnicode_FromString(accum); PyList_SetItem(list, i - 1, uni_part); } - if (last) - g_free (last); - if (accum) - g_free (accum); + g_free (last); + g_free (accum); return list; } @@ -800,9 +802,7 @@ Callback_ThreadTimer(void *userdata) /* We keep this information global, so we can reset it when the * deinit function is called. */ /* XXX This should be somehow bound to the printing context. */ -static char *xchatout_buffer = NULL; -static int xchatout_buffer_size = 0; -static int xchatout_buffer_pos = 0; +static GString *xchatout_buffer = NULL; static PyObject * XChatOut_New() @@ -826,76 +826,42 @@ XChatOut_dealloc(PyObject *self) static PyObject * XChatOut_write(PyObject *self, PyObject *args) { - int new_buffer_pos, data_size, print_limit, add_space; + gboolean add_space; char *data, *pos; - if (!PyArg_ParseTuple(args, "s#:write", &data, &data_size)) + + if (!PyArg_ParseTuple(args, "s:write", &data)) return NULL; - if (!data_size) { - Py_INCREF(Py_None); - return Py_None; + if (!data || !*data) { + Py_RETURN_NONE; } BEGIN_XCHAT_CALLS(RESTORE_CONTEXT|ALLOW_THREADS); if (((XChatOutObject *)self)->softspace) { - add_space = 1; + add_space = TRUE; ((XChatOutObject *)self)->softspace = 0; } else { - add_space = 0; - } - if (xchatout_buffer_size-xchatout_buffer_pos < data_size+add_space) { - char *new_buffer; - /* This buffer grows whenever needed, and does not - * shrink. If we ever implement unloading of the - * python interface, we must find some way to free - * this buffer as well. */ - xchatout_buffer_size += data_size*2+16; - new_buffer = g_realloc(xchatout_buffer, xchatout_buffer_size); - if (new_buffer == NULL) { - hexchat_print(ph, "Not enough memory to print"); - /* The system is out of resources. Let's help. */ - g_free(xchatout_buffer); - xchatout_buffer = NULL; - xchatout_buffer_size = 0; - xchatout_buffer_pos = 0; - /* Return something valid, since we have - * already warned the user, and he probably - * won't be able to notice this exception. */ - goto exit; - } - xchatout_buffer = new_buffer; - } - memcpy(xchatout_buffer+xchatout_buffer_pos, data, data_size); - print_limit = new_buffer_pos = xchatout_buffer_pos+data_size; - pos = xchatout_buffer+print_limit; - if (add_space && *(pos-1) != '\n') { - *pos = ' '; - *(pos+1) = 0; - new_buffer_pos++; - } - while (*pos != '\n' && print_limit > xchatout_buffer_pos) { - pos--; - print_limit--; - } - if (*pos == '\n') { - /* Crop it, inserting the string limiter there. */ - *pos = 0; - hexchat_print(ph, xchatout_buffer); - if (print_limit < new_buffer_pos) { - /* There's still data to be printed. */ - print_limit += 1; /* Include the limiter. */ - xchatout_buffer_pos = new_buffer_pos-print_limit; - memmove(xchatout_buffer, xchatout_buffer+print_limit, - xchatout_buffer_pos); - } else { - xchatout_buffer_pos = 0; - } - } else { - xchatout_buffer_pos = new_buffer_pos; + add_space = FALSE; + } + + g_string_append (xchatout_buffer, data); + + /* If not end of line add space to continue buffer later */ + if (add_space && xchatout_buffer->str[xchatout_buffer->len - 1] != '\n') + { + g_string_append_c (xchatout_buffer, ' '); + } + + /* If there is an end of line print up to that */ + if ((pos = strrchr (xchatout_buffer->str, '\n'))) + { + *pos = '\0'; + hexchat_print (ph, xchatout_buffer->str); + + /* Then remove it from buffer */ + g_string_erase (xchatout_buffer, 0, pos - xchatout_buffer->str + 1); } -exit: END_XCHAT_CALLS(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } #define OFF(x) offsetof(XChatOutObject, x) @@ -1047,8 +1013,7 @@ Context_set(ContextObject *self, PyObject *args) { PyObject *plugin = Plugin_GetCurrent(); Plugin_SetContext(plugin, self->context); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } static PyObject * @@ -1061,8 +1026,7 @@ Context_command(ContextObject *self, PyObject *args) hexchat_set_context(ph, self->context); hexchat_command(ph, text); END_XCHAT_CALLS(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } static PyObject * @@ -1075,8 +1039,7 @@ Context_prnt(ContextObject *self, PyObject *args) hexchat_set_context(ph, self->context); hexchat_print(ph, text); END_XCHAT_CALLS(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } static PyObject * @@ -1121,8 +1084,7 @@ Context_get_info(ContextObject *self, PyObject *args) info = hexchat_get_info(ph, name); END_XCHAT_CALLS(); if (info == NULL) { - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } return PyUnicode_FromString(info); } @@ -1405,11 +1367,7 @@ static Hook * Plugin_AddHook(int type, PyObject *plugin, PyObject *callback, PyObject *userdata, char *name, void *data) { - Hook *hook = (Hook *) g_malloc(sizeof(Hook)); - if (hook == NULL) { - PyErr_NoMemory(); - return NULL; - } + Hook *hook = g_new(Hook, 1); hook->type = type; hook->plugin = plugin; Py_INCREF(callback); @@ -1463,8 +1421,7 @@ Plugin_RemoveHook(PyObject *plugin, Hook *hook) hook)); Py_DECREF(hook->callback); Py_DECREF(hook->userdata); - if (hook->name) - g_free(hook->name); + g_free(hook->name); g_free(hook); } } @@ -1483,8 +1440,7 @@ Plugin_RemoveAllHooks(PyObject *plugin) } Py_DECREF(hook->callback); Py_DECREF(hook->userdata); - if (hook->name) - g_free(hook->name); + g_free(hook->name); g_free(hook); list = list->next; } @@ -1713,8 +1669,7 @@ Module_hexchat_command(PyObject *self, PyObject *args) BEGIN_XCHAT_CALLS(RESTORE_CONTEXT|ALLOW_THREADS); hexchat_command(ph, text); END_XCHAT_CALLS(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } static PyObject * @@ -1726,8 +1681,7 @@ Module_xchat_prnt(PyObject *self, PyObject *args) BEGIN_XCHAT_CALLS(RESTORE_CONTEXT|ALLOW_THREADS); hexchat_print(ph, text); END_XCHAT_CALLS(); - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } static PyObject * @@ -1770,8 +1724,7 @@ Module_hexchat_get_info(PyObject *self, PyObject *args) info = hexchat_get_info(ph, name); END_XCHAT_CALLS(); if (info == NULL) { - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } if (strcmp (name, "gtkwin_ptr") == 0) return PyUnicode_FromFormat("%p", info); /* format as pointer */ @@ -1824,8 +1777,7 @@ Module_hexchat_get_context(PyObject *self, PyObject *args) return NULL; ctxobj = Context_FromContext(Plugin_GetContext(plugin)); if (ctxobj == NULL) { - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } return ctxobj; } @@ -1842,8 +1794,7 @@ Module_hexchat_find_context(PyObject *self, PyObject *args, PyObject *kwargs) return NULL; ctxobj = Context_FromServerAndChannel(server, channel); if (ctxobj == NULL) { - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } return ctxobj; } @@ -1889,7 +1840,7 @@ Module_hexchat_pluginpref_get(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "s:get_pluginpref", &var)) return NULL; - // This will always return numbers as integers. + /* This will always return numbers as integers. */ BEGIN_XCHAT_CALLS(NONE); result = hexchat_pluginpref_get_str(prefph, var, retstr); END_XCHAT_CALLS(); @@ -2223,8 +2174,7 @@ Module_hexchat_unhook(PyObject *self, PyObject *args) Plugin_RemoveHook(plugin, hook); } - Py_INCREF(Py_None); - return Py_None; + Py_RETURN_NONE; } static PyObject * @@ -2532,11 +2482,8 @@ IInterp_Exec(char *command) } d = PyModule_GetDict(m); len = strlen(command); - buffer = (char *) g_malloc(len+2); - if (buffer == NULL) { - hexchat_print(ph, "Not enough memory for command buffer"); - goto fail; - } + + buffer = g_malloc(len + 2); memcpy(buffer, command, len); buffer[len] = '\n'; buffer[len+1] = 0; @@ -2782,6 +2729,7 @@ hexchat_plugin_init(hexchat_plugin *plugin_handle, Py_Initialize(); PySys_SetArgv(1, argv); + xchatout_buffer = g_string_new (NULL); xchatout = XChatOut_New(); if (xchatout == NULL) { hexchat_print(ph, "Can't allocate xchatout object"); @@ -2852,10 +2800,8 @@ hexchat_plugin_deinit() plugin_list = NULL; /* Reset xchatout buffer. */ - g_free(xchatout_buffer); + g_string_free (xchatout_buffer, TRUE); xchatout_buffer = NULL; - xchatout_buffer_size = 0; - xchatout_buffer_pos = 0; if (interp_plugin) { Py_DECREF(interp_plugin); diff --git a/plugins/python/python2.vcxproj b/plugins/python/python2.vcxproj index 58a9e45e..ecf0df75 100644 --- a/plugins/python/python2.vcxproj +++ b/plugins/python/python2.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -19,80 +20,33 @@ <RootNamespace>python2</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <TargetName>$(Python2Output)</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\hexchat.props" /> + <PropertyGroup> <TargetName>$(Python2Output)</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <OutDir>$(HexChatRel)plugins\</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PYTHON_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(Glib);$(Python2Path)\include;..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>$(Glib);$(Python2Path)\include;..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> <ModuleDefinitionFile>python.def</ModuleDefinitionFile> <AdditionalDependencies>"$(Python2Lib).lib";$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>$(DepsRoot)\lib;$(OutDir);$(Python2Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;$(Python2Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;PYTHON_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(Glib);$(Python2Path)\include;..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>$(Glib);$(Python2Path)\include;..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> <ModuleDefinitionFile>python.def</ModuleDefinitionFile> <AdditionalDependencies>"$(Python2Lib).lib";$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>$(DepsRoot)\lib;$(OutDir);$(Python2Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;$(Python2Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemGroup> @@ -102,6 +56,4 @@ <ClCompile Include="python.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/plugins/python/python3.vcxproj b/plugins/python/python3.vcxproj index 5f970975..511421e6 100644 --- a/plugins/python/python3.vcxproj +++ b/plugins/python/python3.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -19,80 +20,33 @@ <RootNamespace>python3</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <TargetName>$(Python3Output)</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\hexchat.props" /> + <PropertyGroup> <TargetName>$(Python3Output)</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <OutDir>$(HexChatRel)plugins\</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PYTHON_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(Glib);$(Python3Path)\include;..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>$(Glib);$(Python3Path)\include;..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> <ModuleDefinitionFile>python.def</ModuleDefinitionFile> <AdditionalDependencies>"$(Python3Lib).lib";$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>$(DepsRoot)\lib;$(OutDir);$(Python3Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;$(Python3Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;PYTHON_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(Glib);$(Python3Path)\include;..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>$(Glib);$(Python3Path)\include;..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> <ModuleDefinitionFile>python.def</ModuleDefinitionFile> <AdditionalDependencies>"$(Python3Lib).lib";$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>$(DepsRoot)\lib;$(OutDir);$(Python3Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;$(Python3Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemGroup> @@ -102,6 +56,4 @@ <ClCompile Include="python.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/plugins/sysinfo/Makefile.am b/plugins/sysinfo/Makefile.am index 0b8d7fad..bd44a19d 100644 --- a/plugins/sysinfo/Makefile.am +++ b/plugins/sysinfo/Makefile.am @@ -1,7 +1,17 @@ libdir = $(hexchatlibdir) +sources = sysinfo.c format.c shared/df.c + +if PLATFORM_OSX +sources += osx/backend.m +else +sources += unix/backend.c unix/match.c unix/parse.c unix/pci.c +endif + +EXTRA_DIST = osx unix win32 shared format.h sysinfo.h sysinfo-backend.h + lib_LTLIBRARIES = sysinfo.la -sysinfo_la_SOURCES = hwmon.c match.c parse.c pci.c xsys.c -sysinfo_la_LDFLAGS = -avoid-version -module -sysinfo_la_LIBADD = -lpci -AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/../../src/common +sysinfo_la_SOURCES = $(sources) +sysinfo_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module +sysinfo_la_LIBADD = $(LIBPCI_LIBS) $(GLIB_LIBS) +AM_CPPFLAGS = $(LIBPCI_CFLAGS) $(GLIB_CFLAGS) -I$(top_srcdir)/src/common -I$(srcdir)/shared diff --git a/plugins/sysinfo/format.c b/plugins/sysinfo/format.c new file mode 100644 index 00000000..741c43e2 --- /dev/null +++ b/plugins/sysinfo/format.c @@ -0,0 +1,90 @@ +/* + * SysInfo - sysinfo plugin for HexChat + * Copyright (c) 2015 Patrick Griffis. + * + * This program is free software you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <glib.h> + +char * +sysinfo_format_uptime (gint64 uptime) +{ + char buffer[128]; + + gint64 weeks = uptime / 604800; + int days = (uptime / 86400) % 7; + int hours = (uptime / 3600) % 24; + int minutes = (uptime / 60) % 60; + int seconds = uptime % 60; + + if (weeks != 0) + { + g_snprintf (buffer, sizeof(buffer), "%" G_GINT64_FORMAT "w %dd %dh %dm %ds", weeks, days, hours, minutes, seconds); + } + else if (days != 0) + { + g_snprintf (buffer, sizeof(buffer), "%dd %dh %dm %ds", days, hours, minutes, seconds); + } + else if (hours != 0) + { + g_snprintf (buffer, sizeof(buffer), "%dh %dm %ds", hours, minutes, seconds); + } + else if (minutes != 0) + { + g_snprintf (buffer, sizeof(buffer), "%dm %ds", minutes, seconds); + } + else + { + g_snprintf (buffer, sizeof(buffer), "%ds", seconds); + } + + return g_strdup (buffer); +} + +char * +sysinfo_format_memory (guint64 totalmem, guint64 freemem) +{ + char *total_fmt, *free_fmt, *ret; + + total_fmt = g_format_size_full (totalmem, G_FORMAT_SIZE_IEC_UNITS); + free_fmt = g_format_size_full (freemem, G_FORMAT_SIZE_IEC_UNITS); + ret = g_strdup_printf ("%s Total (%s Free)", total_fmt, free_fmt); + + g_free (total_fmt); + g_free (free_fmt); + return ret; +} + +char * +sysinfo_format_disk (guint64 total, guint64 free) +{ + char *total_fmt, *free_fmt, *used_fmt, *ret; + GFormatSizeFlags format_flags = G_FORMAT_SIZE_DEFAULT; + +#ifdef WIN32 /* Windows uses IEC size (with SI format) */ + format_flags = G_FORMAT_SIZE_IEC_UNITS; +#endif + + total_fmt = g_format_size_full (total, format_flags); + free_fmt = g_format_size_full (free, format_flags); + used_fmt = g_format_size_full (total - free, format_flags); + ret = g_strdup_printf ("%s / %s (%s Free)", used_fmt, total_fmt, free_fmt); + + g_free (total_fmt); + g_free (free_fmt); + g_free (used_fmt); + return ret; +} diff --git a/plugins/sysinfo/xsys.h b/plugins/sysinfo/format.h index 4daf8545..5fe209be 100644 --- a/plugins/sysinfo/xsys.h +++ b/plugins/sysinfo/format.h @@ -1,7 +1,6 @@ /* - * xsys.h - X-Sys general parameters header - * Copyright (C) 2005 Gustavo Zacarias - * Copyright (C) 2006, 2007 Tony Vroon + * SysInfo - sysinfo plugin for HexChat + * Copyright (c) 2015 Patrick Griffis. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,14 +18,11 @@ */ -#ifndef _XSYS_H_ -#define _XSYS_H_ +#ifndef FORMAT_H +#define FORMAT_H -#define bsize 1024 -#define delims ":=" - -int sysinfo_get_percent (); -void sysinfo_get_pciids (char *dest); -void sysinfo_print_error (const char* msg); +char *sysinfo_format_uptime(gint64 uptime); +char *sysinfo_format_memory(guint64 totalmem, guint64 freemem); +char *sysinfo_format_disk(guint64 total, guint64 free); #endif diff --git a/plugins/sysinfo/hwmon.c b/plugins/sysinfo/hwmon.c deleted file mode 100644 index 389244ac..00000000 --- a/plugins/sysinfo/hwmon.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * hwmon.c - Hardware monitoring functions for X-Sys - * Copyright (C) 2005 Tony Vroon - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#include "xsys.h" - -int hwmon_chip_present() -{ - FILE *fp = fopen("/sys/class/hwmon/hwmon0/device/name", "r"); - if(fp != NULL) { - fclose(fp); - return 1; - } - return 0; -} - -#if 0 -void get_hwmon_chip_name(char *name) -{ - char *position, buffer[bsize]; - FILE *fp = fopen("/sys/class/hwmon/hwmon0/device/name", "r"); - if(fp != NULL) { - if(fgets(buffer, bsize, fp) != NULL) { - position = strstr(buffer, "\n"); - *(position) = '\0'; - snprintf(name, sizeof(name), "%s", buffer); - } - fclose(fp); - } -} -#endif - -void get_hwmon_temp(unsigned int *value, unsigned int *sensor) -{ - char buffer[bsize]; - snprintf(buffer, bsize, "/sys/class/hwmon/hwmon0/device/temp%i_input", *sensor); - FILE *fp = fopen(buffer, "r"); - if(fp != NULL) { - if(fgets(buffer, bsize, fp) != NULL) - *value = atoi(buffer); - fclose(fp); - } -} diff --git a/plugins/sysinfo/match.c b/plugins/sysinfo/match.c deleted file mode 100644 index adfbff1b..00000000 --- a/plugins/sysinfo/match.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * match.c - matching functions for X-Sys - * Copyright (C) 2005, 2006, 2007 Tony Vroon - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#include "xsys.h" - -float percentage(unsigned long long *free, unsigned long long *total) -{ - unsigned long long result = (*free) * (unsigned long long)1000 / (*total); - return result / 10.0; -} - -char *pretty_freespace(const char *desc, unsigned long long *free_k, unsigned long long *total_k) -{ - char *result, **quantity; - double free_space, total_space; - free_space = *free_k; - total_space = *total_k; - result = malloc(bsize * sizeof(char)); - char *quantities[] = { "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", 0 }; - if (total_space == 0) - { - snprintf(result, bsize, "%s: none", desc); - return result; - } - quantity = quantities; - while (total_space > 1023 && *(quantity + 1)) - { - quantity++; - free_space = free_space / 1024; - total_space = total_space / 1024; - } - if (sysinfo_get_percent () != 0) - snprintf(result, bsize, "%s: %.1f%s, %.1f%% free", - desc, total_space, *quantity, - percentage(free_k, total_k)); - else - snprintf(result, bsize, "%s: %.1f%s/%.1f%s free", - desc, free_space, *quantity, total_space, *quantity); - return result; -} - - -void remove_leading_whitespace(char *buffer) -{ - char *buffer2 = NULL; - int i = 0, j = 0, ews = 0; - - buffer2 = (char*)malloc(strlen(buffer) * sizeof(char)); - if (buffer2 == NULL) - return; - - memset (buffer2, (char)0, strlen(buffer)); - while (i < strlen(buffer)) - { - /* count tabs, spaces as whitespace. */ - if (!(buffer[i] == (char)32 || buffer[i] == (char)9) || ews == 1) - { - ews = 1; - buffer2[j] = buffer[i]; - j++; - } - i++; - } - memset (buffer, (char)0, strlen(buffer)); - strcpy (buffer, buffer2); - free (buffer2); -} - -char *decruft_filename(char *buffer) -{ - char *match, *match_end; - - while ((match = strstr(buffer, "%20"))) - { - match_end = match + 3; - *match++ = ' '; - while (*match_end) - *match++ = *match_end++; - *match = 0; - } - return buffer; -} - -void find_match_char(char *buffer, char *match, char *result) -{ - char *position; - remove_leading_whitespace(buffer); - if(strstr(buffer, match) == strstr(buffer, buffer)) - { - position = strpbrk(buffer, delims); - if (position != NULL) { - position += 1; - strcpy(result, position); - position = strstr(result, "\n"); - *(position) = '\0'; - remove_leading_whitespace(result); - } - else - strcpy(result, "\0"); - } -} - -void find_match_double(char *buffer, char *match, double *result) -{ - char *position; - remove_leading_whitespace(buffer); - if(strstr(buffer, match) == strstr(buffer, buffer)) - { - position = strpbrk(buffer, delims); - if (position != NULL) { - position += 1; - *result = strtod(position, NULL); - } - else - *result = 0; - } -} - -void find_match_double_hex(char *buffer, char *match, double *result) -{ - char *position; - remove_leading_whitespace(buffer); - if(strstr(buffer, match) == strstr(buffer, buffer)) - { - position = strpbrk(buffer, delims); - if (position != NULL) { - memcpy(position,"0x",2); - *result = strtod(position,NULL); - } - else - *result = 0; - } -} - -void find_match_int(char *buffer, char *match, unsigned int *result) -{ - char *position; - remove_leading_whitespace(buffer); - if(strstr(buffer, match) == strstr(buffer, buffer)) - { - position = strpbrk(buffer, delims); - if (position != NULL) { - position += 1; - *result = atoi(position); - } - else - *result = 0; - } -} - -void find_match_ll(char *buffer, char *match, unsigned long long *result) -{ - char *position; - remove_leading_whitespace(buffer); - if(strstr(buffer, match) == strstr(buffer, buffer)) - { - position = strpbrk(buffer, delims); - if (position != NULL) { - position += 1; - *result = strtoll(position, NULL, 10); - } - else - *result = 0; - } -} - -void format_output(const char *arg, char *string, char *format) -{ - char *pos1, *pos2, buffer[bsize]; - pos1 = &format[0]; - strncpy(buffer, string, bsize); - string[0] = '\0'; - - while((pos2 = strstr(pos1, "%")) != NULL) - { - strncat(string, pos1, (size_t)(pos2-pos1)); - if(*(pos2+1) == '1') - strcat(string, arg); - else if(*(pos2+1) == '2') - strcat(string, buffer); - else if(*(pos2+1) == 'C' || *(pos2+1) == 'c') - strcat(string, "\003"); - else if(*(pos2+1) == 'B' || *(pos2+1) == 'b') - strcat(string, "\002"); - else if(*(pos2+1) == 'R' || *(pos2+1) == 'r') - strcat(string, "\026"); - else if(*(pos2+1) == 'O' || *(pos2+1) == 'o') - strcat(string, "\017"); - else if(*(pos2+1) == 'U' || *(pos2+1) == 'u') - strcat(string, "\037"); - else if(*(pos2+1) == '%') - strcat(string, "%"); - pos1=pos2+2; - } - - strcat(string, pos1); -} - -void flat_format_output(const char *arg, char *string, char *format) -{ - char *pos1, *pos2, buffer[bsize]; - pos1 = &format[0]; - strncpy(buffer, string, bsize); - string[0] = '\0'; - - while((pos2 = strstr(pos1, "%")) != NULL) - { - strncat(string, pos1, (size_t)(pos2-pos1)); - if(*(pos2+1) == '1') - strcat(string, arg); - else if(*(pos2+1) == '2') - strcat(string, buffer); - else if(*(pos2+1) == '%') - strcat(string, "%"); - pos1=pos2+2; - } - - strcat(string, pos1); -} diff --git a/plugins/sysinfo/osx/backend.m b/plugins/sysinfo/osx/backend.m new file mode 100644 index 00000000..450a557a --- /dev/null +++ b/plugins/sysinfo/osx/backend.m @@ -0,0 +1,263 @@ +/* + * SysInfo - sysinfo plugin for HexChat + * Copyright (c) 2015 Patrick Griffis. + * + * This program is free software you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + + /* + * Some snippets based upon Textual's System Profiler plugin. + * https://github.com/Codeux-Software/Textual + */ + +#import <Cocoa/Cocoa.h> + +#include <sys/sysctl.h> +#include <mach/mach.h> +#include <mach/mach_host.h> +#include <mach/host_info.h> +#include <mach/mach_vm.h> + +#include <glib.h> + +#include "format.h" +#include "df.h" + +static char * +get_os (void) +{ + NSDictionary *systemversion = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"]; + NSString *build = [systemversion objectForKey:@"ProductBuildVersion"]; + if (!build) + return NULL; + NSString *version = [systemversion objectForKey:@"ProductUserVisibleVersion"]; + if (!version) + { + [build release]; + return NULL; + } + + NSDictionary *profiler = [NSDictionary dictionaryWithContentsOfFile:[@"~/Library/Preferences/com.apple.SystemProfiler.plist" stringByExpandingTildeInPath]]; + NSDictionary *names = [profiler objectForKey:@"OS Names"]; + NSString *os_name = nil; + + for (NSString *name in names) + { + if ([name hasPrefix:build]) + { + os_name = [names objectForKey:name]; + break; + } + } + [build release]; + + if (!os_name) + { + [version release]; + return NULL; + } + + char *ret = g_strdup_printf ("%s %s", [os_name UTF8String], [version UTF8String]); + [version release]; + + return ret; +} + +static char * +get_os_fallback (void) +{ + NSProcessInfo *info = [NSProcessInfo processInfo]; + NSOperatingSystemVersion version = [info operatingSystemVersion]; + + return g_strdup_printf ("OS X %ld.%ld.%ld", version.majorVersion, version.minorVersion, version.patchVersion); +} +char * +sysinfo_backend_get_os(void) +{ + static char *os_str = NULL; + if (!os_str) + { + os_str = get_os(); + if (!os_str) + os_str = get_os_fallback(); + } + return g_strdup (os_str); +} + +char * +sysinfo_backend_get_disk(void) +{ + gint64 total, free_space; + + if (xs_parse_df (&total, &free_space)) + { + return NULL; + } + + return sysinfo_format_disk (total, free_space); +} + +static guint64 +get_free_memory (void) +{ + mach_msg_type_number_t infoCount = (sizeof(vm_statistics_data_t) / sizeof(natural_t)); + + vm_size_t pagesize; + vm_statistics_data_t vm_stat; + + host_page_size(mach_host_self(), &pagesize); + + if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vm_stat, &infoCount) == KERN_SUCCESS) + return ((vm_stat.inactive_count + vm_stat.free_count) * pagesize); + + return 0; +} + +char * +sysinfo_backend_get_memory(void) +{ + NSProcessInfo *info = [NSProcessInfo processInfo]; + guint64 totalmem, freemem; + + totalmem = [info physicalMemory]; + + if ((freemem = get_free_memory()) == 0) + return NULL; + + return sysinfo_format_memory (totalmem, freemem); +} + +char * +sysinfo_backend_get_cpu(void) +{ + guint64 cpu_clock_uint = 0; + double cpu_clock; + char cpu_string[256]; + gsize len; + gboolean giga = FALSE; + + len = sizeof(cpu_string); + if (sysctlbyname ("machdep.cpu.brand_string", cpu_string, &len, NULL, 0) != 0) + return NULL; + cpu_string[sizeof(cpu_string) - 1] = '\0'; + + len = sizeof(cpu_clock_uint); + if (sysctlbyname("hw.cpufrequency", &cpu_clock_uint, &len, NULL, 0) < 0) + return NULL; + + cpu_clock = cpu_clock_uint / 1000000; + if (cpu_clock > 1000) + { + cpu_clock /= 1000; + giga = TRUE; + } + + if (giga) + return g_strdup_printf ("%s (%.2fGHz)", cpu_string, cpu_clock); + else + return g_strdup_printf ("%s (%.0fMHz)", cpu_string, cpu_clock); +} + +static char * +get_gpu(void) +{ + CFMutableDictionaryRef pciDevices = IOServiceMatching("IOPCIDevice"); + io_iterator_t entry_iterator, serviceObject; + + if (IOServiceGetMatchingServices(kIOMasterPortDefault, pciDevices, &entry_iterator) != kIOReturnSuccess) + return NULL; + + GString *gpu_list = g_string_new(NULL); + while ((serviceObject = IOIteratorNext(entry_iterator))) + { + CFMutableDictionaryRef serviceDictionary; + + kern_return_t status = IORegistryEntryCreateCFProperties(serviceObject, &serviceDictionary, + kCFAllocatorDefault, kNilOptions); + + if (status != kIOReturnSuccess) + { + IOObjectRelease(serviceObject); + continue; + } + + const void *class = CFDictionaryGetValue(serviceDictionary, @"class-code"); + if (!class || *(guint32*)CFDataGetBytePtr(class) != 0x30000) /* DISPLAY_VGA */ + { + CFRelease(serviceDictionary); + continue; + } + + const void *model = CFDictionaryGetValue(serviceDictionary, @"model"); + if (model) + { + if (CFGetTypeID(model) == CFDataGetTypeID() && CFDataGetLength(model) > 1) + { + if (gpu_list->len != 0) + g_string_append (gpu_list, ", "); + g_string_append_len (gpu_list, (const char*)CFDataGetBytePtr(model), CFDataGetLength(model) - 1); + } + } + + CFRelease(serviceDictionary); + } + + if (gpu_list->len == 0) + { + g_string_free (gpu_list, TRUE); + return NULL; + } + + /* The string may contain nul-chars we must replace */ + int i; + for (i = 0; i < gpu_list->len; i++) + { + if (gpu_list->str[i] == '\0') + gpu_list->str[i] = ' '; + } + + return g_string_free (gpu_list, FALSE); +} + +char * +sysinfo_backend_get_gpu(void) +{ + static char *gpu_str = NULL; + if (!gpu_str) + gpu_str = get_gpu(); + + return g_strdup (gpu_str); +} + +char * +sysinfo_backend_get_sound(void) +{ + return NULL; +} + +char * +sysinfo_backend_get_uptime(void) +{ + NSProcessInfo *info = [NSProcessInfo processInfo]; + double uptime = [info systemUptime]; + + return sysinfo_format_uptime ((gint64)uptime); +} + +char * +sysinfo_backend_get_network(void) +{ + return NULL; +} diff --git a/plugins/sysinfo/pci.c b/plugins/sysinfo/pci.c deleted file mode 100644 index bc8fb11f..00000000 --- a/plugins/sysinfo/pci.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * pci.c - PCI functions for X-Sys - * Copyright (C) 1997-1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz> [PCI routines from lspci] - * Copyright (C) 2000 Tom Rini <trini@kernel.crashing.org> [XorgAutoConfig pci.c, based on lspci] - * Copyright (C) 2005, 2006 Tony Vroon - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <unistd.h> -#include <pci/pci.h> -#include "xsys.h" - -static struct pci_filter filter; /* Device filter */ -static struct pci_access *pacc; -int bus, dev, func; /* Location of the card */ - -struct device { - struct device *next; - struct pci_dev *dev; - unsigned int config_cnt; - u8 config[256]; -}; - -static struct device *first_dev; - -static struct device *scan_device(struct pci_dev *p) -{ - int how_much = 64; - struct device *d; - - if (!pci_filter_match(&filter, p)) - return NULL; - d = malloc(sizeof(struct device)); - bzero(d, sizeof(*d)); - d->dev = p; - if (!pci_read_block(p, 0, d->config, how_much)) - exit(1); - if (how_much < 128 && (d->config[PCI_HEADER_TYPE] & 0x7f) == PCI_HEADER_TYPE_CARDBUS) { - /* For cardbus bridges, we need to fetch 64 bytes more to get the full standard header... */ - if (!pci_read_block(p, 64, d->config+64, 64)) - exit(1); - how_much = 128; - } - d->config_cnt = how_much; - pci_setup_cache(p, d->config, d->config_cnt); - pci_fill_info(p, PCI_FILL_IDENT); - return d; -} - -static void scan_devices(void) -{ - struct device *d; - struct pci_dev *p; - - pci_scan_bus(pacc); - for(p=pacc->devices; p; p=p->next) - if ((d = scan_device(p))) { - d->next = first_dev; - first_dev = d; - } -} - -static u16 get_conf_word(struct device *d, unsigned int pos) -{ - return d->config[pos] | (d->config[pos+1] << 8); -} - -int pci_find_by_class(u16 *class, char *vendor, char *device) -{ - struct device *d; - struct pci_dev *p; - int nomatch = 1; - - pacc = pci_alloc(); - pci_filter_init(pacc, &filter); - pci_init(pacc); - scan_devices(); - - for(d=first_dev; d; d=d->next) { - p = d->dev; - /* Acquire vendor & device ID if the class matches */ - if(get_conf_word(d, PCI_CLASS_DEVICE) == *class) { - nomatch = 0; - snprintf(vendor,7,"%04x",p->vendor_id); - snprintf(device,7,"%04x",p->device_id); - break; - } - } - - pci_cleanup(pacc); - return nomatch; -} - -void pci_find_fullname(char *fullname, char *vendor, char *device) -{ - char buffer[bsize]; - char vendorname[bsize/2] = ""; - char devicename[bsize/2] = ""; - char *position; - int cardfound = 0; - - sysinfo_get_pciids (buffer); - FILE *fp = fopen (buffer, "r"); - - if(fp == NULL) { - snprintf(fullname, bsize, "%s:%s", vendor, device); - sysinfo_print_error ("pci.ids file not found! You might want to adjust your pciids setting with /SYSINFO SET pciids (you can query its current value with /SYSINFO LIST).\n"); - return; - } - - while(fgets(buffer, bsize, fp) != NULL) { - if (!isspace(buffer[0]) && strstr(buffer, vendor) != NULL) { - position = strstr(buffer, vendor); - position += 6; - strncpy(vendorname, position, bsize/2); - position = strstr(vendorname, "\n"); - *(position) = '\0'; - break; - } - } - while(fgets(buffer, bsize, fp) != NULL) { - if(strstr(buffer, device) != NULL) { - position = strstr(buffer, device); - position += 6; - strncpy(devicename, position, bsize/2); - position = strstr(devicename, " ("); - if (position == NULL) - position = strstr(devicename, "\n"); - *(position) = '\0'; - cardfound = 1; - break; - } - } - if (cardfound == 1) - snprintf(fullname, bsize, "%s %s", vendorname, devicename); - else - snprintf(fullname, bsize, "%s:%s", vendor, device); - fclose(fp); -} diff --git a/plugins/sysinfo/shared/df.c b/plugins/sysinfo/shared/df.c new file mode 100644 index 00000000..ce0760a6 --- /dev/null +++ b/plugins/sysinfo/shared/df.c @@ -0,0 +1,53 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <glib.h> + +#include "sysinfo.h" + +int xs_parse_df(gint64 *out_total, gint64 *out_free) +{ + FILE *pipe; + char buffer[bsize]; + + pipe = popen("df -k -l -P", "r"); + if(pipe==NULL) + return 1; + + *out_total = *out_free = 0; + + while(fgets(buffer, bsize, pipe) != NULL) + { + long long int avail, total; + + /* Filesystem 1024-blocks Used Available Capacity Mounted-on */ + if (sscanf (buffer, "%*s %lld %*s %lld %*s %*s", &total, &avail) == 2) + { + *out_total += total; + *out_free += avail; + } + } + + /* Convert to bytes */ + *out_total *= 1000; + *out_free *= 1000; + + pclose(pipe); + return 0; +} diff --git a/src/common/identd.h b/plugins/sysinfo/shared/df.h index 3b29135f..5f7f3296 100644 --- a/src/common/identd.h +++ b/plugins/sysinfo/shared/df.h @@ -1,7 +1,4 @@ -/* HexChat - * Copyright (C) 1998-2010 Peter Zelezny. - * Copyright (C) 2009-2013 Berke Viktor. - * +/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -17,9 +14,10 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#ifndef HEXCHAT_IDENTD_H -#define HEXCHAT_IDENTD_H -void identd_start (char *username); +#ifndef SYSINFO_SHARED_H +#define SYSINFO_SHARED_H + +int xs_parse_df(gint64 *total_bytes, gint64 *free_bytes); #endif diff --git a/plugins/sysinfo/sysinfo-backend.h b/plugins/sysinfo/sysinfo-backend.h new file mode 100644 index 00000000..c69a0853 --- /dev/null +++ b/plugins/sysinfo/sysinfo-backend.h @@ -0,0 +1,33 @@ +/* + * SysInfo - sysinfo plugin for HexChat + * Copyright (c) 2015 Patrick Griffis. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + + +#ifndef SYSINFO_BACKEND_H +#define SYSINFO_BACKEND_H + +char *sysinfo_backend_get_os(void); +char *sysinfo_backend_get_disk(void); +char *sysinfo_backend_get_memory(void); +char *sysinfo_backend_get_cpu(void); +char *sysinfo_backend_get_gpu(void); +char *sysinfo_backend_get_sound(void); +char *sysinfo_backend_get_uptime(void); +char *sysinfo_backend_get_network(void); + +#endif diff --git a/plugins/sysinfo/sysinfo.c b/plugins/sysinfo/sysinfo.c new file mode 100644 index 00000000..10c9d796 --- /dev/null +++ b/plugins/sysinfo/sysinfo.c @@ -0,0 +1,277 @@ +/* + * SysInfo - sysinfo plugin for HexChat + * Copyright (c) 2012 Berke Viktor. + * + * xsys.c - main functions for X-Sys 2 + * by mikeshoup + * Copyright (C) 2003, 2004, 2005 Michael Shoup + * Copyright (C) 2005, 2006, 2007 Tony Vroon + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <glib.h> + +#include "hexchat-plugin.h" +#include "sysinfo-backend.h" +#include "sysinfo.h" + +#define _(x) hexchat_gettext(ph,x) +#define DEFAULT_ANNOUNCE TRUE + +static hexchat_plugin *ph; + +static char name[] = "Sysinfo"; +static char desc[] = "Display info about your hardware and OS"; +static char version[] = "1.0"; +static char sysinfo_help[] = "SysInfo Usage:\n /SYSINFO [-e|-o] [CLIENT|OS|CPU|RAM|DISK|VGA|SOUND|ETHERNET|UPTIME], print various details about your system or print a summary without arguments\n /SYSINFO SET <variable>\n"; + +typedef struct +{ + const char *name; /* Lower case name used for prefs */ + const char *title; /* Used for the end formatting */ + char *(*callback) (void); + gboolean def; /* Hide by default? */ +} hwinfo; + +static char * +get_client (void) +{ + return g_strdup_printf ("HexChat %s", hexchat_get_info(ph, "version")); +} + +static hwinfo hwinfos[] = { + {"client", "Client", get_client}, + {"os", "OS", sysinfo_backend_get_os}, + {"cpu", "CPU", sysinfo_backend_get_cpu}, + {"memory", "Memory", sysinfo_backend_get_memory}, + {"storage", "Storage", sysinfo_backend_get_disk}, + {"vga", "VGA", sysinfo_backend_get_gpu}, + {"sound", "Sound", sysinfo_backend_get_sound, TRUE}, + {"ethernet", "Ethernet", sysinfo_backend_get_network, TRUE}, + {"uptime", "Uptime", sysinfo_backend_get_uptime}, + {NULL, NULL}, +}; + +static gboolean sysinfo_get_bool_pref (const char *pref, gboolean def); + +static gboolean +should_show_info (hwinfo info) +{ + char hide_pref[32]; + + g_snprintf (hide_pref, sizeof(hide_pref), "hide_%s", info.name); + return !sysinfo_get_bool_pref (hide_pref, info.def); +} + +static void +print_summary (gboolean announce) +{ + char **strings = g_new0 (char*, G_N_ELEMENTS(hwinfos)); + int i, x; + char *output; + + for (i = 0, x = 0; hwinfos[i].name != NULL; i++) + { + if (should_show_info (hwinfos[i])) + { + char *str = hwinfos[i].callback(); + if (str) + { + strings[x++] = g_strdup_printf ("\002%s\002: %s", hwinfos[i].title, str); + g_free (str); + } + } + } + + output = g_strjoinv (" \002\342\200\242\002 ", strings); + hexchat_commandf (ph, "%s %s", announce ? "SAY" : "ECHO", output); + + g_strfreev (strings); + g_free (output); +} + +static void +print_info (char *info, gboolean announce) +{ + int i; + + for (i = 0; hwinfos[i].name != NULL; i++) + { + if (!g_ascii_strcasecmp (info, hwinfos[i].name)) + { + char *str = hwinfos[i].callback(); + if (str) + { + hexchat_commandf (ph, "%s \002%s\002: %s", announce ? "SAY" : "ECHO", + hwinfos[i].title, str); + g_free (str); + } + else + hexchat_print (ph, _("Sysinfo: Failed to get info. Either not supported or error.")); + return; + } + } + + hexchat_print (ph, _("Sysinfo: No info by that name\n")); +} + +/* + * Simple wrapper for backend specific options. + * Ensure dest >= 512. + */ +int +sysinfo_get_str_pref (const char *pref, char *dest) +{ + return hexchat_pluginpref_get_str (ph, pref, dest); +} + +static gboolean +sysinfo_get_bool_pref (const char *pref, gboolean def) +{ + int value = hexchat_pluginpref_get_int (ph, pref); + + if (value != -1) + return value; + + return def; +} + +static void +sysinfo_set_pref_real (const char *pref, char *value, gboolean def) +{ + if (value && value[0]) + { + guint64 i = g_ascii_strtoull (value, NULL, 0); + hexchat_pluginpref_set_int (ph, pref, i != 0); + hexchat_printf (ph, _("Sysinfo: %s is set to: %d\n"), pref, i != 0); + } + else + { + hexchat_printf (ph, _("Sysinfo: %s is set to: %d\n"), pref, + sysinfo_get_bool_pref(pref, def)); + } +} + +static void +sysinfo_set_pref (char *key, char *value) +{ + if (!key || !key[0]) + { + hexchat_print (ph, _("Sysinfo: Valid settings are: announce and hide_* for each piece of information. e.g. hide_os. Without a value it will show current (or default) setting.\n")); + return; + } + + if (!strcmp (key, "announce")) + { + sysinfo_set_pref_real (key, value, DEFAULT_ANNOUNCE); + return; + } +#ifdef HAVE_LIBPCI + else if (!strcmp (key, "pciids")) + { + if (value && value[0]) + { + hexchat_pluginpref_set_str (ph, "pciids", value); + hexchat_printf (ph, _("Sysinfo: pciids is set to: %s\n"), value); + } + else + { + char buf[512]; + if (hexchat_pluginpref_get_str (ph, "pciids", buf) == 0) + strcpy (buf, DEFAULT_PCIIDS); + hexchat_printf (ph, _("Sysinfo: pciids is set to: %s\n"), buf); + } + return; + } +#endif + else if (g_str_has_prefix (key, "hide_")) + { + int i; + for (i = 0; hwinfos[i].name != NULL; i++) + { + if (!strcmp (key + 5, hwinfos[i].name)) + { + sysinfo_set_pref_real (key, value, hwinfos[i].def); + return; + } + } + } + + hexchat_print (ph, _("Sysinfo: Invalid variable name\n")); +} + +static int +sysinfo_cb (char *word[], char *word_eol[], void *userdata) +{ + gboolean announce = sysinfo_get_bool_pref("announce", DEFAULT_ANNOUNCE); + int offset = 0, channel_type; + char *cmd; + + /* Allow overriding global announce setting */ + if (!strcmp ("-e", word[2])) + { + announce = FALSE; + offset++; + } + else if (!strcmp ("-o", word[2])) + { + announce = TRUE; + offset++; + } + + /* Cannot send to server tab */ + channel_type = hexchat_list_int (ph, NULL, "type"); + if (channel_type != 2 /* SESS_CHANNEL */ && channel_type != 3 /* SESS_DIALOG */) + announce = FALSE; + + cmd = word[2+offset]; + if (!g_ascii_strcasecmp ("SET", cmd)) + sysinfo_set_pref (word[3+offset], word_eol[4+offset]); + else if (!cmd || !cmd[0]) + print_summary (announce); + else + print_info (cmd, announce); + + return HEXCHAT_EAT_ALL; +} + +int +hexchat_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg) +{ + ph = plugin_handle; + *plugin_name = name; + *plugin_desc = desc; + *plugin_version = version; + + hexchat_hook_command (ph, "SYSINFO", HEXCHAT_PRI_NORM, sysinfo_cb, sysinfo_help, NULL); + + hexchat_command (ph, "MENU ADD \"Window/Send System Info\" \"SYSINFO\""); + hexchat_printf (ph, _("%s plugin loaded\n"), name); + return 1; +} + +int +hexchat_plugin_deinit (void) +{ + hexchat_command (ph, "MENU DEL \"Window/Display System Info\""); + hexchat_printf (ph, _("%s plugin unloaded\n"), name); + return 1; +} diff --git a/plugins/sysinfo/sysinfo.cpp b/plugins/sysinfo/sysinfo.cpp deleted file mode 100644 index 43ab48c0..00000000 --- a/plugins/sysinfo/sysinfo.cpp +++ /dev/null @@ -1,416 +0,0 @@ -/* HexChat - * Copyright (c) 2011-2012 Berke Viktor. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include <stdio.h> -#include <windows.h> -#include <comutil.h> -#include <wbemidl.h> - -#include "hexchat-plugin.h" - -static hexchat_plugin *ph; /* plugin handle */ -static char name[] = "SysInfo"; -static char desc[] = "Display info about your hardware and OS"; -static char version[] = "1.1"; -static char helptext[] = "USAGE: /sysinfo - Sends info about your hardware and OS to current channel."; -static int firstRun; -static char *wmiOs; -static char *wmiCpu; -static char *wmiVga; - -static int -getCpuArch (void) -{ - OSVERSIONINFOEX osvi; - SYSTEM_INFO si; - - osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX); - GetVersionEx ((LPOSVERSIONINFOW) &osvi); - - GetSystemInfo (&si); - - if (si.wProcessorArchitecture == 9) - { - return 64; - } - else - { - return 86; - } -} - -#if 0 -/* use WMI instead, wProcessorArchitecture displays current binary arch instead of OS arch anyway */ -static char * -getOsName (void) -{ - static char winver[32]; - double mhz; - OSVERSIONINFOEX osvi; - SYSTEM_INFO si; - - osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX); - GetVersionEx ((LPOSVERSIONINFOW) &osvi); - - GetSystemInfo (&si); - - strcpy (winver, "Windows "); - - switch (osvi.dwMajorVersion) - { - case 5: - switch (osvi.dwMinorVersion) - { - case 1: - strcat (winver, "XP"); - break; - case 2: - if (osvi.wProductType == VER_NT_WORKSTATION) - { - strcat (winver, "XP x64 Edition"); - } - else - { - if (GetSystemMetrics(SM_SERVERR2) == 0) - { - strcat (winver, "Server 2003"); - } - else - { - strcat (winver, "Server 2003 R2"); - } - } - break; - } - break; - case 6: - switch (osvi.dwMinorVersion) - { - case 0: - if (osvi.wProductType == VER_NT_WORKSTATION) - { - strcat (winver, "Vista"); - } - else - { - strcat (winver, "Server 2008"); - } - break; - case 1: - if (osvi.wProductType == VER_NT_WORKSTATION) - { - strcat (winver, "7"); - } - else - { - strcat (winver, "Server 2008 R2"); - } - break; - case 2: - if (osvi.wProductType == VER_NT_WORKSTATION) - { - strcat (winver, "8"); - } - else - { - strcat (winver, "8 Server"); - } - break; - } - break; - } - - if (si.wProcessorArchitecture == 9) - { - strcat (winver, " (x64)"); - } - else - { - strcat (winver, " (x86)"); - } - - return winver; -} - -/* x86-only, SDK-only, use WMI instead */ -static char * -getCpuName (void) -{ - // Get extended ids. - unsigned int nExIds; - unsigned int i; - int CPUInfo[4] = {-1}; - static char CPUBrandString[128]; - - __cpuid (CPUInfo, 0x80000000); - nExIds = CPUInfo[0]; - - /* Get the information associated with each extended ID. */ - for (i=0x80000000; i <= nExIds; ++i) - { - __cpuid (CPUInfo, i); - - if (i == 0x80000002) - { - memcpy (CPUBrandString, CPUInfo, sizeof (CPUInfo)); - } - else if (i == 0x80000003) - { - memcpy( CPUBrandString + 16, CPUInfo, sizeof (CPUInfo)); - } - else if (i == 0x80000004) - { - memcpy (CPUBrandString + 32, CPUInfo, sizeof (CPUInfo)); - } - } - - return CPUBrandString; -} -#endif - -static char * -getCpuMhz (void) -{ - HKEY hKey; - int result; - int data; - int dataSize; - double cpuspeed; - static char buffer[16]; - const char *cpuspeedstr; - - if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, TEXT("Hardware\\Description\\System\\CentralProcessor\\0"), 0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS) - { - dataSize = sizeof (data); - result = RegQueryValueEx (hKey, TEXT("~MHz"), 0, 0, (LPBYTE)&data, (LPDWORD)&dataSize); - RegCloseKey (hKey); - if (result == ERROR_SUCCESS) - { - cpuspeed = ( data > 1000 ) ? data / 1000 : data; - cpuspeedstr = ( data > 1000 ) ? "GHz" : "MHz"; - sprintf (buffer, "%.2f %s", cpuspeed, cpuspeedstr); - } - } - - return buffer; -} - -static char * -getMemoryInfo (void) -{ - static char buffer[32]; - MEMORYSTATUSEX meminfo; - - meminfo.dwLength = sizeof (meminfo); - GlobalMemoryStatusEx (&meminfo); - - sprintf (buffer, "%I64d MB Total (%I64d MB Free)", meminfo.ullTotalPhys / 1024 / 1024, meminfo.ullAvailPhys / 1024 / 1024); - - return buffer; -} - -static char * -getWmiInfo (int mode) -{ - /* for more details about this wonderful API, see - http://msdn.microsoft.com/en-us/site/aa394138 - http://msdn.microsoft.com/en-us/site/aa390423 - http://msdn.microsoft.com/en-us/library/windows/desktop/aa394138%28v=vs.85%29.aspx - http://social.msdn.microsoft.com/forums/en-US/vcgeneral/thread/d6420012-e432-4964-8506-6f6b65e5a451 - */ - - char *buffer = (char *) malloc (128); - HRESULT hres; - HRESULT hr; - IWbemLocator *pLoc = NULL; - IWbemServices *pSvc = NULL; - IEnumWbemClassObject *pEnumerator = NULL; - IWbemClassObject *pclsObj; - ULONG uReturn = 0; - - hres = CoInitializeEx (0, COINIT_APARTMENTTHREADED | COINIT_SPEED_OVER_MEMORY); - - if (FAILED (hres)) - { - strcpy (buffer, "Error Code 0"); - return buffer; - } - - hres = CoInitializeSecurity (NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); - - /* mysteriously failing after the first execution, but only when used as a plugin, skip it */ - /*if (FAILED (hres)) - { - CoUninitialize (); - strcpy (buffer, "Error Code 1"); - return buffer; - }*/ - - hres = CoCreateInstance (CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc); - - if (FAILED (hres)) - { - CoUninitialize (); - strcpy (buffer, "Error Code 2"); - return buffer; - } - - hres = pLoc->ConnectServer (_bstr_t (L"root\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc); - - if (FAILED (hres)) - { - pLoc->Release (); - CoUninitialize (); - strcpy (buffer, "Error Code 3"); - return buffer; - } - - hres = CoSetProxyBlanket (pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); - - if (FAILED (hres)) - { - pSvc->Release (); - pLoc->Release (); - CoUninitialize (); - strcpy (buffer, "Error Code 4"); - return buffer; - } - - switch (mode) - { - case 0: - hres = pSvc->ExecQuery (_bstr_t ("WQL"), _bstr_t ("SELECT * FROM Win32_OperatingSystem"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); - break; - case 1: - hres = pSvc->ExecQuery (_bstr_t ("WQL"), _bstr_t ("SELECT * FROM Win32_Processor"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); - break; - case 2: - hres = pSvc->ExecQuery (_bstr_t ("WQL"), _bstr_t ("SELECT * FROM Win32_VideoController"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); - break; - - } - - if (FAILED (hres)) - { - pSvc->Release (); - pLoc->Release (); - CoUninitialize (); - strcpy (buffer, "Error Code 5"); - return buffer; - } - - while (pEnumerator) - { - hr = pEnumerator->Next (WBEM_INFINITE, 1, &pclsObj, &uReturn); - if (0 == uReturn) - { - break; - } - VARIANT vtProp; - switch (mode) - { - case 0: - hr = pclsObj->Get (L"Caption", 0, &vtProp, 0, 0); - break; - case 1: - hr = pclsObj->Get (L"Name", 0, &vtProp, 0, 0); - break; - case 2: - hr = pclsObj->Get (L"Name", 0, &vtProp, 0, 0); - break; - } - WideCharToMultiByte (CP_ACP, 0, vtProp.bstrVal, -1, buffer, SysStringLen (vtProp.bstrVal)+1, NULL, NULL); - VariantClear (&vtProp); - } - - pSvc->Release (); - pLoc->Release (); - pEnumerator->Release (); - pclsObj->Release (); - CoUninitialize (); - return buffer; -} - -static int -printInfo (char *word[], char *word_eol[], void *user_data) -{ - /* query WMI info only at the first time SysInfo is called, then cache it to save time */ - if (firstRun) - { - hexchat_printf (ph, "%s first execution, querying and caching WMI info...\n", name); - wmiOs = getWmiInfo (0); - wmiCpu = getWmiInfo (1); - wmiVga = getWmiInfo (2); - firstRun = 0; - } - if (hexchat_list_int (ph, NULL, "type") >= 2) - { - /* uptime will work correctly for up to 50 days, should be enough */ - hexchat_commandf (ph, "ME ** SysInfo ** Client: HexChat %s (x%d) ** OS: %s ** CPU: %s (%s) ** RAM: %s ** VGA: %s ** Uptime: %.2f Hours **", - hexchat_get_info (ph, "version"), - getCpuArch (), - wmiOs, - wmiCpu, - getCpuMhz (), - getMemoryInfo (), - wmiVga, (float) GetTickCount() / 1000 / 60 / 60); - } - else - { - hexchat_printf (ph, " * Client: HexChat %s (x%d)\n", hexchat_get_info (ph, "version"), getCpuArch ()); - hexchat_printf (ph, " * OS: %s\n", wmiOs); - hexchat_printf (ph, " * CPU: %s (%s)\n", wmiCpu, getCpuMhz ()); - hexchat_printf (ph, " * RAM: %s\n", getMemoryInfo ()); - hexchat_printf (ph, " * VGA: %s\n", wmiVga); - hexchat_printf (ph, " * Uptime: %.2f Hours\n", (float) GetTickCount() / 1000 / 60 / 60); - } - - return HEXCHAT_EAT_HEXCHAT; -} - -int -hexchat_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg) -{ - ph = plugin_handle; - - *plugin_name = name; - *plugin_desc = desc; - *plugin_version = version; - - firstRun = 1; - - hexchat_hook_command (ph, "SYSINFO", HEXCHAT_PRI_NORM, printInfo, helptext, NULL); - hexchat_command (ph, "MENU -ishare\\system.png ADD \"Window/Send System Info\" \"SYSINFO\""); - - hexchat_printf (ph, "%s plugin loaded\n", name); - - return 1; /* return 1 for success */ -} - - -int -hexchat_plugin_deinit (void) -{ - hexchat_command (ph, "MENU DEL \"Window/Display System Info\""); - hexchat_printf (ph, "%s plugin unloaded\n", name); - return 1; -} diff --git a/plugins/sysinfo/hwmon.h b/plugins/sysinfo/sysinfo.h index fe71274b..cfde8408 100644 --- a/plugins/sysinfo/hwmon.h +++ b/plugins/sysinfo/sysinfo.h @@ -1,6 +1,6 @@ /* - * hwmon.h - Hardware monitoring header for X-Sys - * Copyright (C) 2005 Tony Vroon + * SysInfo - sysinfo plugin for HexChat + * Copyright (c) 2015 Patrick Griffis. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,11 +18,12 @@ */ -#ifndef _HWMON_H_ -#define _HWMON_H_ +#ifndef SYSINFO_H +#define SYSINFO_H -int hwmon_chip_present(); -void get_hwmon_chip_name(char *name); -void get_hwmon_temp(unsigned int *value, unsigned int *sensor); +#define bsize 1024 +#define DEFAULT_PCIIDS "/usr/share/hwdata/pci.ids" + +int sysinfo_get_str_pref (const char *name, char *dest); #endif diff --git a/plugins/sysinfo/sysinfo.vcxproj b/plugins/sysinfo/sysinfo.vcxproj index 7286b89a..3d429295 100644 --- a/plugins/sysinfo/sysinfo.vcxproj +++ b/plugins/sysinfo/sysinfo.vcxproj @@ -2,6 +2,8 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -19,91 +21,51 @@ <RootNamespace>sysinfo</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>Unicode</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\hexchat.props" /> + <PropertyGroup> <TargetName>hcsysinfo</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - <TargetName>hcsysinfo</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <OutDir>$(HexChatRel)plugins\</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SYSINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>..\..\src\common;$(DepsRoot)\include;$(Glib);$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <ModuleDefinitionFile>sysinfo.def</ModuleDefinitionFile> - <AdditionalDependencies>wbemuuid.lib;comsupp.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>wbemuuid.lib;comsupp.lib;$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> <IgnoreSpecificDefaultLibraries>comsupp.lib</IgnoreSpecificDefaultLibraries> + <ModuleDefinitionFile>sysinfo.def</ModuleDefinitionFile> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;SYSINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>..\..\src\common;$(DepsRoot)\include;$(Glib);$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <ModuleDefinitionFile>sysinfo.def</ModuleDefinitionFile> - <AdditionalDependencies>wbemuuid.lib;comsupp.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>wbemuuid.lib;comsupp.lib;$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> <IgnoreSpecificDefaultLibraries>comsupp.lib</IgnoreSpecificDefaultLibraries> + <ModuleDefinitionFile>sysinfo.def</ModuleDefinitionFile> </Link> </ItemDefinitionGroup> <ItemGroup> <None Include="sysinfo.def" /> </ItemGroup> <ItemGroup> - <ClCompile Include="sysinfo.cpp" /> + <ClCompile Include="format.c" /> + <ClCompile Include="sysinfo.c" /> + <ClCompile Include="win32\backend.c" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="format.h" /> + <ClInclude Include="sysinfo-backend.h" /> + <ClInclude Include="sysinfo.h" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/plugins/sysinfo/sysinfo.vcxproj.filters b/plugins/sysinfo/sysinfo.vcxproj.filters index 1ef90f5b..aa173bb5 100644 --- a/plugins/sysinfo/sysinfo.vcxproj.filters +++ b/plugins/sysinfo/sysinfo.vcxproj.filters @@ -9,6 +9,9 @@ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{c873eb6b-aca6-434d-8ec9-199838b80838}</UniqueIdentifier> + </Filter> </ItemGroup> <ItemGroup> <None Include="sysinfo.def"> @@ -16,8 +19,25 @@ </None> </ItemGroup> <ItemGroup> - <ClCompile Include="sysinfo.cpp"> + <ClCompile Include="sysinfo.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="win32\backend.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="format.c"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ClInclude Include="sysinfo.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="sysinfo-backend.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="format.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> </Project> \ No newline at end of file diff --git a/plugins/sysinfo/unix/backend.c b/plugins/sysinfo/unix/backend.c new file mode 100644 index 00000000..dc065518 --- /dev/null +++ b/plugins/sysinfo/unix/backend.c @@ -0,0 +1,170 @@ +/* + * SysInfo - sysinfo plugin for HexChat + * Copyright (c) 2015 Patrick Griffis. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <glib.h> +#include "parse.h" +#include "match.h" +#include "sysinfo.h" +#include "format.h" +#include "df.h" + +char *sysinfo_backend_get_os(void) +{ + char name[bsize]; + + if (xs_parse_distro (name) != 0) + { + return NULL; + } + + return g_strdup(name); +} + +char *sysinfo_backend_get_disk(void) +{ + gint64 total, free; + + if (xs_parse_df (&total, &free)) + { + return NULL; + } + + return sysinfo_format_disk (total, free); +} + +char *sysinfo_backend_get_memory(void) +{ + unsigned long long mem_total; + unsigned long long mem_free; + unsigned long long swap_total; + unsigned long long swap_free; + char *swap_fmt = NULL, *mem_fmt, *ret; + + if (xs_parse_meminfo (&mem_total, &mem_free, 0) == 1) + { + return NULL; + } + if (xs_parse_meminfo (&swap_total, &swap_free, 1) != 1) + { + swap_fmt = sysinfo_format_memory (swap_total, swap_free); + } + + mem_fmt = sysinfo_format_memory (mem_total, mem_free); + + if (swap_fmt) + { + ret = g_strdup_printf ("Physical: %s Swap: %s", mem_fmt, swap_fmt); + g_free (mem_fmt); + g_free (swap_fmt); + } + else + ret = mem_fmt; + + return ret; +} + +char *sysinfo_backend_get_cpu(void) +{ + char model[bsize]; + char vendor[bsize]; + char buffer[bsize]; + double freq; + int giga = 0; + + if (xs_parse_cpu (model, vendor, &freq) != 0) + { + return NULL; + } + + if (freq > 1000) + { + freq /= 1000; + giga = 1; + } + + if (giga) + { + g_snprintf (buffer, bsize, "%s (%.2fGHz)", model, freq); + } + else + { + g_snprintf (buffer, bsize, "%s (%.0fMHz)", model, freq); + } + + return g_strdup (buffer); +} + +char *sysinfo_backend_get_gpu(void) +{ + char vid_card[bsize]; + char agp_bridge[bsize]; + char buffer[bsize]; + int ret; + + if ((ret = xs_parse_video (vid_card)) != 0) + { + return NULL; + } + + if (xs_parse_agpbridge (agp_bridge) != 0) + { + g_snprintf (buffer, bsize, "%s", vid_card); + } + else + { + g_snprintf (buffer, bsize, "%s @ %s", vid_card, agp_bridge); + } + + return g_strdup (buffer); +} + +char *sysinfo_backend_get_sound(void) +{ + char sound[bsize]; + + if (xs_parse_sound (sound) != 0) + { + return NULL; + } + return g_strdup (sound); +} + +char *sysinfo_backend_get_uptime(void) +{ + gint64 uptime; + + if ((uptime = xs_parse_uptime ()) == 0) + { + return NULL; + } + + return sysinfo_format_uptime (uptime); +} + +char *sysinfo_backend_get_network(void) +{ + char ethernet_card[bsize]; + + if (xs_parse_ether (ethernet_card)) + { + g_strlcpy (ethernet_card, "None found", bsize); + } + + return g_strdup (ethernet_card); +} diff --git a/plugins/sysinfo/unix/match.c b/plugins/sysinfo/unix/match.c new file mode 100644 index 00000000..2ef51f3f --- /dev/null +++ b/plugins/sysinfo/unix/match.c @@ -0,0 +1,98 @@ +/* + * match.c - matching functions for X-Sys + * Copyright (C) 2005, 2006, 2007 Tony Vroon + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <glib.h> +#include "sysinfo.h" + +#define delims ":=" + +void find_match_char(char *buffer, char *match, char *result) +{ + char *position; + g_strchug(buffer); + if(strstr(buffer, match) == strstr(buffer, buffer)) + { + position = strpbrk(buffer, delims); + if (position != NULL) + { + position += 1; + strcpy(result, position); + position = strstr(result, "\n"); + *(position) = '\0'; + g_strchug(result); + } + else + strcpy(result, "\0"); + } +} + +void find_match_double(char *buffer, char *match, double *result) +{ + char *position; + g_strchug(buffer); + if(strstr(buffer, match) == strstr(buffer, buffer)) + { + position = strpbrk(buffer, delims); + if (position != NULL) + { + position += 1; + *result = strtod(position, NULL); + } + else + *result = 0; + } +} + +void find_match_double_hex(char *buffer, char *match, double *result) +{ + char *position; + g_strchug(buffer); + if(strstr(buffer, match) == strstr(buffer, buffer)) + { + position = strpbrk(buffer, delims); + if (position != NULL) + { + memcpy(position,"0x",2); + *result = strtod(position,NULL); + } + else + *result = 0; + } +} + +void find_match_ll(char *buffer, char *match, unsigned long long *result) +{ + char *position; + g_strchug(buffer); + if(strstr(buffer, match) == strstr(buffer, buffer)) + { + position = strpbrk(buffer, delims); + if (position != NULL) + { + position += 1; + *result = strtoll(position, NULL, 10); + } + else + *result = 0; + } +} + diff --git a/plugins/sysinfo/match.h b/plugins/sysinfo/unix/match.h index 61811e4a..16999fa2 100644 --- a/plugins/sysinfo/match.h +++ b/plugins/sysinfo/unix/match.h @@ -23,13 +23,7 @@ void find_match_char(char *buffer, char *match, char *result); void find_match_double(char *buffer, char *match, double *result); void find_match_double_hex(char *buffer, char *match, double *result); -void find_match_int(char *buffer, char *match, unsigned int *result); void find_match_ll(char *buffer, char *match, unsigned long long *result); -void format_output(const char *arg, char *string, char *format); -void flat_format_output(const char *arg, char *string, char *format); -float percentage(unsigned long long *free, unsigned long long *total); -char *pretty_freespace(const char *desc, unsigned long long *free_k, unsigned long long *total_k); void remove_leading_whitespace(char *buffer); -char *decruft_filename(char *buffer); #endif diff --git a/plugins/sysinfo/parse.c b/plugins/sysinfo/unix/parse.c index 4c15897a..f41f89a7 100644 --- a/plugins/sysinfo/parse.c +++ b/plugins/sysinfo/unix/parse.c @@ -23,19 +23,19 @@ #include <stdlib.h> #include <string.h> #include <ctype.h> -#include <sys/utsname.h> -#include <unistd.h> -#include <time.h> -#include <dirent.h> -#include <sys/types.h> #include <pci/header.h> +#include <glib.h> + +#ifdef __sparc__ +#include <dirent.h> +#endif #include "pci.h" #include "match.h" -#include "hwmon.h" -#include "xsys.h" +#include "parse.h" +#include "sysinfo.h" -int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned int *count) +int xs_parse_cpu(char *model, char *vendor, double *freq) { #if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(__alpha__) || defined(__ia64__) || defined(__parisc__) || defined(__sparc__) char buffer[bsize]; @@ -46,8 +46,6 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned FILE *fp = fopen("/proc/cpuinfo", "r"); if(fp == NULL) return 1; - if(count != NULL) *count = 0; - strcpy(cache,"unknown\0"); #if defined(__i386__) || defined(__x86_64__) while(fgets(buffer, bsize, fp) != NULL) @@ -55,10 +53,7 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned find_match_char(buffer, "model name", model); find_match_char(buffer, "vendor_id", vendor); find_match_double(buffer, "cpu MHz", freq); - find_match_char(buffer, "cache size", cache); - find_match_int(buffer, "processor", count); } - *count = *count + 1; #endif #ifdef __powerpc__ while(fgets(buffer, bsize, fp) != NULL) @@ -66,10 +61,7 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned find_match_char(buffer, "cpu", model); find_match_char(buffer, "machine", vendor); find_match_double(buffer, "clock", freq); - find_match_char(buffer, "L2 cache", cache); - find_match_int(buffer, "processor", count); } - *count = *count + 1; pos = strstr(model, ","); if (pos != NULL) *pos = '\0'; #endif @@ -79,8 +71,6 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned find_match_char(buffer, "cpu model", model); find_match_char(buffer, "system type", vendor); find_match_double(buffer, "cycle frequency [Hz]", freq); - find_match_char(buffer, "L2 cache", cache); - find_match_int(buffer, "cpus detected", count); } *freq = *freq / 1000000; #endif @@ -90,20 +80,15 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned find_match_char(buffer, "model", model); find_match_char(buffer, "vendor", vendor); find_match_double(buffer, "cpu MHz", freq); - find_match_int(buffer, "processor", count); } - *count = *count + 1; #endif #ifdef __parisc__ while(fgets(buffer, bsize, fp) != NULL) { find_match_char(buffer, "cpu ", model); find_match_char(buffer, "cpu family", vendor); - find_match_char(buffer, "D-cache", cache); find_match_double(buffer, "cpu MHz", freq); - find_match_int(buffer, "processor", count); } - *count = *count + 1; #endif #ifdef __sparc__ DIR *dir; @@ -113,22 +98,8 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned { find_match_char(buffer, "cpu ", model); find_match_char(buffer, "type ", vendor); - find_match_int(buffer, "ncpus active", count); find_match_double_hex(buffer, "Cpu0ClkTck", freq); } - /* Cache is tricky, only implemented for sparc64 */ - if ((dir = opendir("/proc/openprom")) != NULL) - while ((entry = readdir(dir)) != NULL) - if (strncmp(entry->d_name,"SUNW,UltraSPARC",15) == 0) - { - snprintf(buffer,bsize,"/proc/openprom/%s/ecache-size",entry->d_name); - fp2 = fopen(buffer, "r"); - if (fp2 == NULL) break; - fscanf(fp2,"%16s",cache); - fclose(fp2); - sprintf(buffer,"0x%s",cache); - sprintf(cache,"%0.0f KB",strtod(buffer,NULL)/1024); - } *freq = *freq / 1000000; #endif fclose(fp); @@ -136,43 +107,20 @@ int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned return 0; } -int xs_parse_uptime(int *weeks, int *days, int *hours, int *minutes, int *seconds) +gint64 xs_parse_uptime(void) { char buffer[bsize]; - long long uptime = 0; + gint64 uptime = 0; FILE *fp = fopen("/proc/uptime", "r"); if(fp == NULL) - return 1; + return 0; if(fgets(buffer, bsize, fp) != NULL) - uptime = strtol(buffer, NULL, 0); - - *seconds = uptime%60; - *minutes = (uptime/60)%60; - *hours = (uptime/3600)%24; - *days = (uptime/86400)%7; - *weeks = uptime/604800; + uptime = g_ascii_strtoll(buffer, NULL, 0); fclose(fp); - return 0; -} - -int xs_parse_os(char *user, char *host, char *kernel) -{ - struct utsname osinfo; - char hostn[bsize], *usern = getenv("USER"); - - if(uname(&osinfo)<0) - return 1; - if(gethostname(hostn, bsize)<0) - return 1; - - strncpy(user, usern, bsize); - strcpy(host, hostn); - snprintf(kernel, bsize, "%s %s %s", osinfo.sysname, osinfo.release, osinfo.machine); - - return 0; + return uptime; } int xs_parse_sound(char *snd_card) @@ -181,12 +129,13 @@ int xs_parse_sound(char *snd_card) u16 class = PCI_CLASS_MULTIMEDIA_AUDIO; FILE *fp = NULL; - if((fp = fopen("/proc/asound/cards", "r"))== NULL) { + if((fp = fopen("/proc/asound/cards", "r"))== NULL) + { if (pci_find_by_class(&class, vendor, device) == 0) - { - pci_find_fullname(snd_card, vendor, device); - return 0; - } + { + pci_find_fullname(snd_card, vendor, device); + return 0; + } else return 1; } @@ -197,13 +146,13 @@ int xs_parse_sound(char *snd_card) if(isdigit(buffer[0]) || isdigit(buffer[1])) { char card_buf[bsize]; - long card_id = 0; + gint64 card_id = 0; pos = strstr(buffer, ":"); - card_id = strtoll(buffer, NULL, 0); + card_id = g_ascii_strtoll(buffer, NULL, 0); if (card_id == 0) - snprintf(card_buf, bsize, "%s", pos+2); + g_snprintf(card_buf, bsize, "%s", pos+2); else - snprintf(card_buf, bsize, "%ld: %s", card_id, pos+2); + g_snprintf(card_buf, bsize, "%"G_GINT64_FORMAT": %s", card_id, pos+2); pos = strstr(card_buf, "\n"); *pos = '\0'; strcat(cards, card_buf); @@ -249,129 +198,42 @@ int xs_parse_agpbridge(char *agp_bridge) return 0; } -int xs_parse_netdev(const char *device, unsigned long long *bytes_recv, unsigned long long *bytes_sent) -{ - FILE *fp; - char buffer[bsize], *pos; - int i; - - fp=fopen("/proc/net/dev", "r"); - if(fp==NULL) - return 1; - - while(fgets(buffer, bsize, fp) != NULL) - { - for(i=0; isspace(buffer[i]); i++); - if(strncmp(device, &buffer[i], strlen(device)) == 0) break; - } - fclose(fp); - pos = strstr(buffer, ":"); - pos++; - *bytes_recv = strtoull(pos, &pos, 0); - - for(i=0;i<7;i++) strtoull(pos, &pos, 0); - - *bytes_sent = strtoull(pos, NULL, 0); - - return 0; -} - -int xs_parse_df(const char *mount_point, char *result) -{ - FILE *pipe; - char buffer[bsize], *pos; - unsigned long long total_k=0, free_k=0; - int i=0; - - pipe = popen("df -k -l -P", "r"); - if(pipe==NULL) - return 1; - - while(fgets(buffer, bsize, pipe) != NULL) - { - /* Skip over pseudo-filesystems and description line */ - if(isalpha(buffer[0])) - continue; - - for(pos=buffer; !isspace(*pos); pos++); - for(;isspace(*pos);pos++); - if(mount_point == NULL) - { - total_k += strtoull(pos, &pos, 0); - strtoull(pos, &pos, 0); - free_k += strtoull(pos, &pos, 0); - continue; - } - total_k = strtoull(pos, &pos, 0); - strtoull(pos, &pos, 0); - free_k = strtoull(pos, &pos, 0); - strtoull(pos, &pos, 0); - for(;isspace(*pos);pos++); - for(;*pos!='/';pos++); - for(i=0;*(buffer+i)!='\n';i++); - *(buffer+i)='\0'; - - if(strncasecmp(mount_point, "ALL", 3)==0) - { - char *tmp_buf = pretty_freespace(pos, &free_k, &total_k); - strcat(tmp_buf, " | "); - strcat(result, tmp_buf); - free(tmp_buf); - } - else if(strncmp(mount_point, pos, strlen(mount_point)) == 0) - { - char *tmp_buf = pretty_freespace(mount_point, &free_k, &total_k); - strncpy(result, tmp_buf, bsize); - free(tmp_buf); - break; - } - else snprintf(result, bsize, "Mount point %s not found!", mount_point); - } - - if(mount_point != NULL && strncasecmp(mount_point, "ALL", 3)==0) - *(result+strlen(result)-3) = '\0'; - - if(mount_point == NULL) - { - char *tmp_buf = pretty_freespace("Total", &free_k, &total_k); - strncpy(result, tmp_buf, bsize); - free(tmp_buf); - } - pclose(pipe); - return 0; -} - int xs_parse_meminfo(unsigned long long *mem_tot, unsigned long long *mem_free, int swap) { FILE *fp; - char buffer[bsize]; + char buffer[bsize]; unsigned long long freemem = 0, buffers = 0, cache = 0; - *mem_tot = 0; - *mem_free = 0; + *mem_tot = 0; + *mem_free = 0; - if((fp = fopen("/proc/meminfo", "r")) == NULL) - return 1; + if((fp = fopen("/proc/meminfo", "r")) == NULL) + return 1; - while(fgets(buffer, bsize, fp) != NULL) - { - if(!swap) - { + while(fgets(buffer, bsize, fp) != NULL) + { + if(!swap) + { find_match_ll(buffer, "MemTotal:", mem_tot); find_match_ll(buffer, "MemFree:", &freemem); find_match_ll(buffer, "Buffers:", &buffers); find_match_ll(buffer, "Cached:", &cache); - } - else - { + } + else + { find_match_ll(buffer, "SwapTotal:", mem_tot); find_match_ll(buffer, "SwapFree:", mem_free); - } - } - if (!swap) { + } + } + if (!swap) + { *mem_free = freemem + buffers + cache; } - fclose(fp); - return 0; + fclose(fp); + + /* Convert to bytes */ + *mem_free *= 1000; + *mem_tot *= 1000; + return 0; } int xs_parse_distro(char *name) @@ -387,9 +249,9 @@ int xs_parse_distro(char *name) find_match_char(buffer, "ACCEPT_KEYWORDS", keywords); /* cppcheck-suppress uninitvar */ if (strstr(keywords, "\"") == NULL) - snprintf(buffer, bsize, "Gentoo Linux (stable)"); + g_snprintf(buffer, bsize, "Gentoo Linux (stable)"); else - snprintf(buffer, bsize, "Gentoo Linux %s", keywords); + g_snprintf(buffer, bsize, "Gentoo Linux %s", keywords); } else if((fp = fopen("/etc/redhat-release", "r")) != NULL) fgets(buffer, bsize, fp); @@ -404,7 +266,7 @@ int xs_parse_distro(char *name) else if((fp = fopen("/etc/turbolinux-release", "r")) != NULL) fgets(buffer, bsize, fp); else if((fp = fopen("/etc/arch-release", "r")) != NULL) - snprintf(buffer, bsize, "ArchLinux"); + g_snprintf(buffer, bsize, "ArchLinux"); else if((fp = fopen("/etc/lsb-release", "r")) != NULL) { char id[bsize], codename[bsize], release[bsize]; @@ -417,45 +279,22 @@ int xs_parse_distro(char *name) find_match_char(buffer, "DISTRIB_CODENAME", codename); find_match_char(buffer, "DISTRIB_RELEASE", release); } - snprintf(buffer, bsize, "%s \"%s\" %s", id, codename, release); + g_snprintf(buffer, bsize, "%s \"%s\" %s", id, codename, release); } else if((fp = fopen("/etc/debian_version", "r")) != NULL) { char release[bsize]; fgets(release, bsize, fp); - snprintf(buffer, bsize, "Debian %s", release); + g_snprintf(buffer, bsize, "Debian %s", release); } else - snprintf(buffer, bsize, "Unknown Distro"); - if(fp != NULL) fclose(fp); + g_snprintf(buffer, bsize, "Unknown Distro"); + if(fp != NULL) + fclose(fp); pos=strchr(buffer, '\n'); - if(pos != NULL) *pos = '\0'; + if(pos != NULL) + *pos = '\0'; strcpy(name, buffer); return 0; } - -int xs_parse_hwmon_chip(char *chip) -{ - if (!hwmon_chip_present()) - return 1; -#if 0 - else - get_hwmon_chip_name(chip); -#endif - return 0; -} - -int xs_parse_hwmon_temp(char *temp, unsigned int *sensor) -{ - unsigned int value; - float celsius; - - if (!hwmon_chip_present()) - return 1; - else - get_hwmon_temp(&value, sensor); - celsius = (float)value; - snprintf(temp, bsize, "%.1fC", celsius/1000.0); - return 0; -} diff --git a/plugins/sysinfo/parse.h b/plugins/sysinfo/unix/parse.h index 27aac7da..c7cb571e 100644 --- a/plugins/sysinfo/parse.h +++ b/plugins/sysinfo/unix/parse.h @@ -23,18 +23,13 @@ #ifndef _PARSE_H_ #define _PARSE_H_ -int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned int *count); -int xs_parse_uptime(int *weeks, int *days, int *hours, int *minutes, int *seconds); -int xs_parse_os(char *user, char *host, char *kernel); +int xs_parse_cpu(char *model, char *vendor, double *freq); +gint64 xs_parse_uptime(void); int xs_parse_sound(char *snd_card); -int xs_parse_netdev(const char *device, unsigned long long *bytes_recv, unsigned long long *bytes_sent); -int xs_parse_df(const char *mount_point, char *string); int xs_parse_meminfo(unsigned long long *mem_tot, unsigned long long *mem_free, int swap); int xs_parse_video(char *vid_card); int xs_parse_agpbridge(char *agp_bridge); int xs_parse_ether(char *ethernet_card); int xs_parse_distro(char *name); -int xs_parse_hwmon_chip(char *chip); -int xs_parse_hwmon_temp(char *temp, unsigned int *sensor); #endif diff --git a/plugins/sysinfo/unix/pci.c b/plugins/sysinfo/unix/pci.c new file mode 100644 index 00000000..71b085fe --- /dev/null +++ b/plugins/sysinfo/unix/pci.c @@ -0,0 +1,169 @@ +/* + * pci.c - PCI functions for X-Sys + * Copyright (C) 1997-1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz> [PCI routines from lspci] + * Copyright (C) 2000 Tom Rini <trini@kernel.crashing.org> [XorgAutoConfig pci.c, based on lspci] + * Copyright (C) 2005, 2006 Tony Vroon + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <pci/pci.h> +#include <glib.h> + +#include "sysinfo.h" + +static struct pci_filter filter; /* Device filter */ +static struct pci_access *pacc; +int bus, dev, func; /* Location of the card */ + +struct device { + struct device *next; + struct pci_dev *dev; + unsigned int config_cnt; + u8 config[256]; +}; + +static struct device *first_dev; + +static struct device *scan_device(struct pci_dev *p) +{ + int how_much = 64; + struct device *d; + + if (!pci_filter_match(&filter, p)) + return NULL; + d = g_new0 (struct device, 1); + d->dev = p; + if (!pci_read_block(p, 0, d->config, how_much)) + exit(1); + if (how_much < 128 && (d->config[PCI_HEADER_TYPE] & 0x7f) == PCI_HEADER_TYPE_CARDBUS) + { + /* For cardbus bridges, we need to fetch 64 bytes more to get the full standard header... */ + if (!pci_read_block(p, 64, d->config+64, 64)) + exit(1); + how_much = 128; + } + d->config_cnt = how_much; + pci_setup_cache(p, d->config, d->config_cnt); + pci_fill_info(p, PCI_FILL_IDENT); + return d; +} + +static void scan_devices(void) +{ + struct device *d; + struct pci_dev *p; + + pci_scan_bus(pacc); + for(p=pacc->devices; p; p=p->next) + { + if ((d = scan_device(p))) + { + d->next = first_dev; + first_dev = d; + } + } +} + +static u16 get_conf_word(struct device *d, unsigned int pos) +{ + return d->config[pos] | (d->config[pos+1] << 8); +} + +int pci_find_by_class(u16 *class, char *vendor, char *device) +{ + struct device *d; + struct pci_dev *p; + int nomatch = 1; + + pacc = pci_alloc(); + pci_filter_init(pacc, &filter); + pci_init(pacc); + scan_devices(); + + for(d=first_dev; d; d=d->next) + { + p = d->dev; + /* Acquire vendor & device ID if the class matches */ + if(get_conf_word(d, PCI_CLASS_DEVICE) == *class) + { + nomatch = 0; + g_snprintf(vendor,7,"%04x",p->vendor_id); + g_snprintf(device,7,"%04x",p->device_id); + break; + } + } + + pci_cleanup(pacc); + return nomatch; +} + +void pci_find_fullname(char *fullname, char *vendor, char *device) +{ + char buffer[bsize]; + char vendorname[bsize/2] = ""; + char devicename[bsize/2] = ""; + char *position; + int cardfound = 0; + FILE *fp; + + if (!sysinfo_get_str_pref ("pciids", buffer)) + strcpy (buffer, DEFAULT_PCIIDS); + + fp = fopen (buffer, "r"); + if(fp == NULL) + { + g_snprintf(fullname, bsize, "%s:%s", vendor, device); + //sysinfo_print_error ("pci.ids file not found! You might want to adjust your pciids setting with /SYSINFO SET pciids (you can query its current value with /SYSINFO LIST).\n"); + return; + } + + while(fgets(buffer, bsize, fp) != NULL) + { + if (!isspace(buffer[0]) && strstr(buffer, vendor) != NULL) + { + position = strstr(buffer, vendor); + position += 6; + strncpy(vendorname, position, bsize/2); + position = strstr(vendorname, "\n"); + *(position) = '\0'; + break; + } + } + while(fgets(buffer, bsize, fp) != NULL) + { + if(strstr(buffer, device) != NULL) + { + position = strstr(buffer, device); + position += 6; + strncpy(devicename, position, bsize/2); + position = strstr(devicename, " ("); + if (position == NULL) + position = strstr(devicename, "\n"); + *(position) = '\0'; + cardfound = 1; + break; + } + } + if (cardfound == 1) + g_snprintf(fullname, bsize, "%s %s", vendorname, devicename); + else + g_snprintf(fullname, bsize, "%s:%s", vendor, device); + fclose(fp); +} diff --git a/plugins/sysinfo/pci.h b/plugins/sysinfo/unix/pci.h index 673f0a0a..673f0a0a 100644 --- a/plugins/sysinfo/pci.h +++ b/plugins/sysinfo/unix/pci.h diff --git a/plugins/sysinfo/win32/backend.c b/plugins/sysinfo/win32/backend.c new file mode 100644 index 00000000..2451c122 --- /dev/null +++ b/plugins/sysinfo/win32/backend.c @@ -0,0 +1,493 @@ +/* HexChat + * Copyright (c) 2011-2012 Berke Viktor. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <stdio.h> +#include <windows.h> +#include <wbemidl.h> + +#include <glib.h> + +#include "../format.h" + +/* Cache the info for subsequent invocations of /SYSINFO */ +static int cpu_arch = 0; +static char *os_name = NULL; +static char *cpu_info = NULL; +static char *vga_name = NULL; + +static int command_callback (char *word[], char *word_eol[], void *user_data); + +typedef enum +{ + QUERY_WMI_OS, + QUERY_WMI_CPU, + QUERY_WMI_VGA, + QUERY_WMI_HDD, +} QueryWmiType; + +void print_info (void); +int get_cpu_arch (void); +char *query_wmi (QueryWmiType mode); +char *read_os_name (IWbemClassObject *object); +char *read_cpu_info (IWbemClassObject *object); +char *read_vga_name (IWbemClassObject *object); + +guint64 hdd_capacity; +guint64 hdd_free_space; +char *read_hdd_info (IWbemClassObject *object); + +char *get_memory_info (void); +char *bstr_to_utf8 (BSTR bstr); +guint64 variant_to_uint64 (VARIANT *variant); + +char * +sysinfo_backend_get_sound (void) +{ + return NULL; +} + +char * +sysinfo_backend_get_network (void) +{ + return NULL; +} + +char * +sysinfo_backend_get_uptime (void) +{ + return sysinfo_format_uptime (GetTickCount64 () / 1000); +} + +char * +sysinfo_backend_get_disk (void) +{ + char *hdd_info; + + /* HDD information is always loaded dynamically since it includes the current amount of free space */ + hdd_capacity = 0; + hdd_free_space = 0; + hdd_info = query_wmi (QUERY_WMI_HDD); + if (hdd_info) + return sysinfo_format_disk (hdd_capacity, hdd_free_space); + + return NULL; +} + +char * +sysinfo_backend_get_cpu (void) +{ + if (cpu_info == NULL) + cpu_info = query_wmi (QUERY_WMI_CPU); + + return g_strdup (cpu_info); +} + +char * +sysinfo_backend_get_memory (void) +{ + /* Memory information is always loaded dynamically since it includes the current amount of free memory */ + return get_memory_info (); +} + +char * +sysinfo_backend_get_gpu (void) +{ + if (vga_name == NULL) + vga_name = query_wmi (QUERY_WMI_VGA); + + return g_strdup (vga_name); +} + +char * +sysinfo_backend_get_os (void) +{ + if (os_name == NULL) + os_name = query_wmi (QUERY_WMI_OS); + + if (cpu_arch == 0) + cpu_arch = get_cpu_arch (); + + return g_strdup_printf ("%s (x%d)", os_name, cpu_arch); +} + +static int get_cpu_arch (void) +{ + SYSTEM_INFO si; + + GetNativeSystemInfo (&si); + + if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) + { + return 64; + } + else + { + return 86; + } +} + +/* http://msdn.microsoft.com/en-us/site/aa390423 */ +static char *query_wmi (QueryWmiType type) +{ + GString *result = NULL; + HRESULT hr; + + IWbemLocator *locator = NULL; + BSTR namespaceName = NULL; + BSTR queryLanguageName = NULL; + BSTR query = NULL; + IWbemServices *namespace = NULL; + IUnknown *namespaceUnknown = NULL; + IEnumWbemClassObject *enumerator = NULL; + int i; + gboolean atleast_one_appended = FALSE; + + hr = CoCreateInstance (&CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, &IID_IWbemLocator, (LPVOID *) &locator); + if (FAILED (hr)) + { + goto exit; + } + + namespaceName = SysAllocString (L"root\\CIMV2"); + + hr = locator->lpVtbl->ConnectServer (locator, namespaceName, NULL, NULL, NULL, 0, NULL, NULL, &namespace); + if (FAILED (hr)) + { + goto release_locator; + } + + hr = namespace->lpVtbl->QueryInterface (namespace, &IID_IUnknown, &namespaceUnknown); + if (FAILED (hr)) + { + goto release_namespace; + } + + hr = CoSetProxyBlanket (namespaceUnknown, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); + if (FAILED (hr)) + { + goto release_namespaceUnknown; + } + + queryLanguageName = SysAllocString (L"WQL"); + + switch (type) + { + case QUERY_WMI_OS: + query = SysAllocString (L"SELECT Caption FROM Win32_OperatingSystem"); + break; + case QUERY_WMI_CPU: + query = SysAllocString (L"SELECT Name, MaxClockSpeed FROM Win32_Processor"); + break; + case QUERY_WMI_VGA: + query = SysAllocString (L"SELECT Name FROM Win32_VideoController"); + break; + case QUERY_WMI_HDD: + query = SysAllocString (L"SELECT Name, Capacity, FreeSpace FROM Win32_Volume"); + break; + default: + goto release_queryLanguageName; + } + + hr = namespace->lpVtbl->ExecQuery (namespace, queryLanguageName, query, WBEM_FLAG_FORWARD_ONLY, NULL, &enumerator); + if (FAILED (hr)) + { + goto release_query; + } + + result = g_string_new (""); + + for (i = 0;; i++) + { + ULONG numReturned = 0; + IWbemClassObject *object; + char *line; + + hr = enumerator->lpVtbl->Next (enumerator, WBEM_INFINITE, 1, &object, &numReturned); + if (FAILED (hr) || numReturned == 0) + { + break; + } + + switch (type) + { + case QUERY_WMI_OS: + line = read_os_name (object); + break; + + case QUERY_WMI_CPU: + line = read_cpu_info (object); + break; + + case QUERY_WMI_VGA: + line = read_vga_name (object); + break; + + case QUERY_WMI_HDD: + line = read_hdd_info (object); + break; + + default: + break; + } + + object->lpVtbl->Release (object); + + if (line != NULL) + { + if (atleast_one_appended) + { + g_string_append (result, ", "); + } + + g_string_append (result, line); + + g_free (line); + + atleast_one_appended = TRUE; + } + } + + enumerator->lpVtbl->Release (enumerator); + +release_query: + SysFreeString (query); + +release_queryLanguageName: + SysFreeString (queryLanguageName); + +release_namespaceUnknown: + namespaceUnknown->lpVtbl->Release (namespaceUnknown); + +release_namespace: + namespace->lpVtbl->Release (namespace); + +release_locator: + locator->lpVtbl->Release (locator); + SysFreeString (namespaceName); + +exit: + if (result == NULL) + { + return NULL; + } + + return g_string_free (result, FALSE); +} + +static char *read_os_name (IWbemClassObject *object) +{ + HRESULT hr; + VARIANT caption_variant; + char *caption_utf8; + + hr = object->lpVtbl->Get (object, L"Caption", 0, &caption_variant, NULL, NULL); + if (FAILED (hr)) + { + return NULL; + } + + caption_utf8 = bstr_to_utf8 (caption_variant.bstrVal); + + VariantClear(&caption_variant); + + if (caption_utf8 == NULL) + { + return NULL; + } + + g_strchomp (caption_utf8); + + return caption_utf8; +} + +static char *read_cpu_info (IWbemClassObject *object) +{ + HRESULT hr; + VARIANT name_variant; + char *name_utf8; + VARIANT max_clock_speed_variant; + guint cpu_freq_mhz; + char *result; + + hr = object->lpVtbl->Get (object, L"Name", 0, &name_variant, NULL, NULL); + if (FAILED (hr)) + { + return NULL; + } + + name_utf8 = bstr_to_utf8 (name_variant.bstrVal); + + VariantClear (&name_variant); + + if (name_utf8 == NULL) + { + return NULL; + } + + hr = object->lpVtbl->Get (object, L"MaxClockSpeed", 0, &max_clock_speed_variant, NULL, NULL); + if (FAILED (hr)) + { + g_free (name_utf8); + + return NULL; + } + + cpu_freq_mhz = max_clock_speed_variant.uintVal; + + VariantClear (&max_clock_speed_variant); + + if (cpu_freq_mhz > 1000) + { + result = g_strdup_printf ("%s (%.2fGHz)", name_utf8, cpu_freq_mhz / 1000.f); + } + else + { + result = g_strdup_printf ("%s (%" G_GUINT32_FORMAT "MHz)", name_utf8, cpu_freq_mhz); + } + + g_free (name_utf8); + + return result; +} + +static char *read_vga_name (IWbemClassObject *object) +{ + HRESULT hr; + VARIANT name_variant; + char *name_utf8; + + hr = object->lpVtbl->Get (object, L"Name", 0, &name_variant, NULL, NULL); + if (FAILED (hr)) + { + return NULL; + } + + name_utf8 = bstr_to_utf8 (name_variant.bstrVal); + + VariantClear (&name_variant); + + if (name_utf8 == NULL) + { + return NULL; + } + + return g_strchomp (name_utf8); +} + +static char *read_hdd_info (IWbemClassObject *object) +{ + HRESULT hr; + VARIANT name_variant; + BSTR name_bstr; + gsize name_len; + VARIANT capacity_variant; + guint64 capacity; + VARIANT free_space_variant; + guint64 free_space; + + hr = object->lpVtbl->Get (object, L"Name", 0, &name_variant, NULL, NULL); + if (FAILED (hr)) + { + return NULL; + } + + name_bstr = name_variant.bstrVal; + name_len = SysStringLen (name_variant.bstrVal); + + if (name_len >= 4 && name_bstr[0] == L'\\' && name_bstr[1] == L'\\' && name_bstr[2] == L'?' && name_bstr[3] == L'\\') + { + // This is not a named volume. Skip it. + VariantClear (&name_variant); + + return NULL; + } + + VariantClear (&name_variant); + + hr = object->lpVtbl->Get (object, L"Capacity", 0, &capacity_variant, NULL, NULL); + if (FAILED (hr)) + { + return NULL; + } + + capacity = variant_to_uint64 (&capacity_variant); + + VariantClear (&capacity_variant); + + if (capacity == 0) + { + return NULL; + } + + hr = object->lpVtbl->Get (object, L"FreeSpace", 0, &free_space_variant, NULL, NULL); + if (FAILED (hr)) + { + return NULL; + } + + free_space = variant_to_uint64 (&free_space_variant); + + VariantClear (&free_space_variant); + + if (free_space == 0) + { + return NULL; + } + + hdd_capacity += capacity; + hdd_free_space += free_space; + + return NULL; +} + +static char *get_memory_info (void) +{ + MEMORYSTATUSEX meminfo = { 0 }; + meminfo.dwLength = sizeof (meminfo); + + if (!GlobalMemoryStatusEx (&meminfo)) + { + return NULL; + } + + return sysinfo_format_memory (meminfo.ullTotalPhys, meminfo.ullAvailPhys); +} + +static char *bstr_to_utf8 (BSTR bstr) +{ + return g_utf16_to_utf8 (bstr, SysStringLen (bstr), NULL, NULL, NULL); +} + +static guint64 variant_to_uint64 (VARIANT *variant) +{ + switch (V_VT (variant)) + { + case VT_UI8: + return variant->ullVal; + + case VT_BSTR: + return wcstoull (variant->bstrVal, NULL, 10); + + default: + return 0; + } +} diff --git a/plugins/sysinfo/xsys-changelog b/plugins/sysinfo/xsys-changelog deleted file mode 100644 index 9ea20727..00000000 --- a/plugins/sysinfo/xsys-changelog +++ /dev/null @@ -1,116 +0,0 @@ -v2.2.0 - * (Thomas Cort) Report L2 cache info for Alpha CPUs - * (Tony Vroon) Drop XMMS, port audacious features to D-Bus, make dependency mandatory - * (Tony Vroon) Use pretty_freespace for memory & swap reporting as well as disk space - * (Tony Vroon) Make pretty_freespace report none if total_size is 0, thanks to Emopig <andrew@nelless.net> for the report - * (Tony Vroon) Make pretty_freespace aware of terabytes, petabytes, exabytes, zettabytes & yottabytes - * (Tony Vroon) Remove xchatdirfs workaround - -v2.1.0 - Removals & pending removal: - * (Tony Vroon) Remove support for BMP, it is an abandoned project. Suggested upgrade path: audacious - * (Tony Vroon) Remove /uname & /euname; the OS part of sysinfo displays similar info without requiring a process pipe - * (Tony Vroon) Added a note that the xchatdirfs workaround is due for removal as X-Chat Gnome has fixed the bug - - Bugfixes: - * (Tony Vroon) Actually show the vendor that we retrieve in cpuinfo - * (Tony Vroon) Display Gentoo Linux as stable or ~arch, the baselayout version doesn't really interest anyone - * (Tony Vroon) Match framework: Make remove_leading_whitespace actually work - * (Tony Vroon) Match framework: Do not assume that a delimiter is always followed by a space - - Code improvements: - * (Tony Vroon) PCI framework: We were requesting more info then we actually return to the caller - * (Tony Vroon) Match framework: Consolidate delimiters in a single define & use 1 strpbrk instead of 2 strstr's - * (Tony Vroon) Display the machine string instead of the pmac-generation as vendor info for PPC machines - - New features - * (Tony Vroon) Show memory capacity in gigabytes instead of in megabytes when appropriate - * (Tony Vroon) Cut cpu name at comma (so overly long other info such as "altivec supported" is no longer displayed) - * (Tony Vroon) Now Playing: Report time played as well as the song length - * (Tony Vroon) Now Playing: Support reporting as an action; configurable at runtime - * (Tony Vroon) Check LSB release data, prefer above all others; based on a code sample submitted by Thomas Winwood - -v2.0.9 - * (Tony Vroon) Protect the matching framework against spurious matches (bug reported by Harm Geerts) - * (Tony Vroon) Unexporting unnecessary symbols for PCI framework - * (Tony Vroon) Deal with incompatible header changes in pciutils - * (Tony Vroon) Begin implementing hardware monitoring support, not yet activated - * (Tony Vroon) Add support for Audacious, a BMP fork - -v2.0.8 - * (Tony Vroon) Make XMMS interface actually work, thanks to a patch from Morten Cools - * (Tony Vroon) Use percentages for df information as well - * (Gustavo Zacarias) Add support for Sparc architecture, cache size detection on sparc64 only - * (Gustavo Zacarias) Consolidate buffer sizes into a single define - -v2.0.7 - * (Tony Vroon) Have df parser ignore pseudo-filesystems; deal with other locales more gracefully - * (Tony Vroon) Change default formatstring not to use mIRC color codes - * (Tony Vroon) Add fallback to ~/.xchat2 for xchat-gnome which does not report xchatdirfs properly - * (Tony Vroon) Revert to beepctrl.h style calls as infopipe is too unreliable - -v2.0.6 - * (Tony Vroon) Rewrote PCI framework, no longer depends on sysfs, kernel 2.4 and lower will work now - * (Tony Vroon) Made percentages configurable, can be set at runtime (feature request by Halcy0n) - * (Tony Vroon) Abstract out all pointer voodoo from xsys.c - * (Tony Vroon) Do not return XCHAT_EAT_NONE, causes spurious "unknown command" errors - * (Tony Vroon) Deal more gracefully with a missing soundcard or unknown linux distribution - * (Tony Vroon) Add error handling to the matching framework - -v2.0.5 - * (Tony Vroon) Added support for parisc/hppa & ia64 architectures - * (Tony Vroon) Proper report of L2 cache as "unknown" instead of showing bits of unitialized memory - * (Tony Vroon) Upped PCI parser yield for ppc64 architecture, has high bus number for AGP card - * (Tony Vroon) Use percentages in memory/swap information - -v2.0.4 - * (Tony Vroon) /sound uses ALSA if possible, PCI now fallback (false positives reported with PCI code) - * (Tony Vroon) Remove 0 prefix from first ALSA card; 1: and up will be shown for extra cards - * (Tony Vroon) Matching code rewritten and separated out from other code - * (Tony Vroon) Use new matching framework where possible - * (Tony Vroon) Added support for Alpha architecture, thanks to Bert (bert@ev6.net) - -v2.0.3 - * (Tony Vroon) Fix buttons, XMMS -> NP - * (Tony Vroon) PCI functions separated out from other code; fully rewritten - * (Tony Vroon) Use new PCI framework for sound detection; ALSA is now fallback - * (Tony Vroon) Implement /ether - * (Tony Vroon) /video now reports video card @ AGP bridge; resolution info dropped - -v2.0.2 - * (Tony Vroon) XMMS/BMP: Delete XMMS/BMP detection; it just got obsoleted by a BMP bugfix - * (Tony Vroon) XMMS/BMP: Change to /np & /enp as commands (np -> now playing) - * (Tony Vroon) Allow customization of now_playing with /playing - * (Tony Vroon) Separate out the length field for now_playing - * (Tony Vroon) Better configuration file handling - * (Tony Vroon) Set homepage to http://dev.gentoo.org/~chainsaw/xsys - * (Tony Vroon) Make channel buttons optional, not everyone appreciates them - * (Tony Vroon) Fix cpuinfo parsing on x86_64, a necessary define was missing - -v2.0.1 - * (Tony Vroon) XMMS/BMP: Report "stream" if song length is -1 - * (Tony Vroon) XMMS/BMP: Determine whether XMMS or BMP is playing - * (Tony Vroon) Better errorhandling if pci.ids parsing fails; at least mention raw PCI ID of card - * (Tony Vroon) Remove AGP from video card messages; we detect plain PCI cards too - * (Tony Vroon) Fix Debian release detector - -v2.0.0 - * (mikeshoup) Clean up of code for 2.0.0 release - * (Tony Vroon) Added PowerPC /proc/cpuinfo support - * (Tony Vroon) Changed LSPCI to SYSFS - -v1.9.3 - * (mikeshoup) Introduced distro function - * (mikeshoup, Tony Vroon's suggestion) Removed bitrate from /XMMS - -v1.9.2 - * 2005/01/14 (mikeshoup) Put in the userlist buttons - * 2005/01/10 (mikeshoup) Added XMMS/BMP Support - -v1.9.1 - * 2004/12/20 (mikeshoup) Added a dynamic formatting scheme - * 2004/12/19 (mikeshoup) Changed some commands - * 2004/12/18 (mikeshoup) Reintroducted /VIDEO - -v1.9.0 - * 2004/12/17 (mikeshoup) Initial Release diff --git a/plugins/sysinfo/xsys-install b/plugins/sysinfo/xsys-install deleted file mode 100644 index 8f148569..00000000 --- a/plugins/sysinfo/xsys-install +++ /dev/null @@ -1,15 +0,0 @@ -INSTALLATION -============ -Installation is straightforward. You need Audacious 1.4 or higher and D-Bus. -Open up the Makefile, check to make sure PCIIDS points to your pci.ids file. - (Symptom if you get it wrong: raw PCI ID's (XXXX:XXXX) emitted by /VIDEO and friends). - -Run: make -Run: make install - -Voila! - -NOTES: -`make install' copies the compiled library (something like xsys-v.v.v.so) to -$HOME/.xchat2/xsys-plugin.so for autoloading. If $HOME/.xchat2/xsys-plugin.so -exists, it is removed first. diff --git a/plugins/sysinfo/xsys-makefile b/plugins/sysinfo/xsys-makefile deleted file mode 100644 index 8b51a53d..00000000 --- a/plugins/sysinfo/xsys-makefile +++ /dev/null @@ -1,38 +0,0 @@ -#### SET THIS VALUE TO THE LOCATION OF THE `pci.ids` file #### -PCIIDS = /usr/share/misc/pci.ids - -#### UNCOMMENT THIS IF YOU WANT THE BUTTONS #### -#BUTTON = -Dbuttonbar - -#### SHOULD NOT NEED TO EDIT BELOW THIS LINE #### -VER_MAJOR = 2 -VER_MINOR = 2 -VER_PATCH = 0 -CC = gcc -CFLAGS += -O2 -Wall -fPIC -CFLAGS += -DVER_MINOR=$(VER_MINOR) -DVER_MAJOR=$(VER_MAJOR) -DVER_PATCH=$(VER_PATCH) \ - -DVER_STRING=\"$(VER_MAJOR).$(VER_MINOR).$(VER_PATCH)\" -DPCIIDS=\"$(PCIIDS)\" $(BUTTON) -LDFLAGS = $(CFLAGS) -shared -LIBRARY = xsys-$(VER_MAJOR).$(VER_MINOR).$(VER_PATCH).so -OBJECTS = xsys.o parse.o pci.o match.o hwmon.o - -ALL : $(LIBRARY) - -$(LIBRARY) : $(OBJECTS) - $(CC) $(LDFLAGS) -o $(LIBRARY) $(OBJECTS) -lpci - -xsys.o : xsys.c -parse.o : parse.c -pci.o : pci.c -match.o : match.c -hwmon.o : hwmon.c - -.PHONY : clean -clean : - rm -rf *.o *.so *~ - -.PHONY : install -install : $(LIBRARY) - rm -f $(HOME)/.xchat2/xsys-plugin.so - cp ./$(LIBRARY) $(HOME)/.xchat2/xsys-plugin.so - diff --git a/plugins/sysinfo/xsys-readme b/plugins/sysinfo/xsys-readme deleted file mode 100644 index 6226e725..00000000 --- a/plugins/sysinfo/xsys-readme +++ /dev/null @@ -1,105 +0,0 @@ -X-Sys README -============ -What is X-Sys? - -X-Sys is a plugin for X-Chat that allows you to display your current system statistics in -a channel, private conversation or just in an echo to yourself for testing purposes. -It is supported on Linux, running on various architectures. Right now x86, ppc, ppc64, sparc, -sparc64 and alpha are supported, with parisc and ia64 implemented but awaiting testing. - ---------------- -Who wrote this? - -X-Sys is originally a Mike Shoup creation, from the very first alpha releases to the open-source -version 1 releases. But then, things stalled. For a few months (more like a year almost) -Mike didn't work on X-Sys. The last version that had been written was 1.0.5. -The website was gone, and I (Tony) couldn't find Mike. So, I took over and improved it to my liking. -It turned out that Mike was still around, though, he contacted me and started development again, -now called version 2, a complete rewrite. Various 1.9 betas came out that I contributed patches to, -and starting with version 2.0.0 I'm maintaining xchat-xsys again, this time with Mike's blessing. - ---------------- -What do I need? - -- X-Chat (regular or Gnome version) -- Audacious 1.4 or higher -- D-Bus (for communication with Audacious) -- a working toolchain (compiler, binutils, etc). - ------------------------------------------------- -What if I get errors about u8 not being defined? - -Sorry to hear that, it appears your linux distribution neglected to install essential headers on your -system. On Debian & Ubuntu, apt-get install pciutils-dev should make it happy. - -======== -COMMANDS - -X-Sys 2 has the following implemented commands: -/XSYS & /EXSYS - Output current version, either to channel or echoed on screen. -/CPUINFO & /ECPUINFO - Echoes or says current cpu statistics -/SYSUPTIME & /ESYSUPTIME - Echoes or says current uptime -/OSINFO & /EOSINFO - Echoes or says various OS statistics -/SOUND & /ESOUND - Echoes or says the current sound card, as determined by ALSA -/NETDATA & /ENETDATA - Echoes or says total amount transferred through a network - interface. Use like: `/netdata eth0' (where eth0 is a network interface) -/NETSTREAM & /ENETSTREAM - Echoes or says amount of bandwidth being used. - Use like: `/netstream eth0' (where eth0 is a network interface) -/DISKINFO & /EDISKINFO - Echoes or says free space on partitions. The DISK command has a - few arguments as follows: - ALL - Displays every partitions - /mount - Displays free space for that specific mount point - No arguments just displays total free space -/MEMINFO & /EMEMINFO - Echoes or says memory information. -/VIDEO & /EVIDEO - Echoes or says the current video card on the PCI bus -/ETHER & /EETHER - Echoes or says the current network card on the PCI bus -/DISTRO & /EDISTRO - Echoes or says which distro you're running - If this doesn't work for your distro, look for a *-release file or similar in /etc - E-mail this to chainsaw@gentoo.org - -and the big one: -/SYSINFO & /ESYSINFO - Complete system information! - -Two output control commands: -/XSYS2FORMAT , No arguments, it will print just the current formatting string. - It will take any arguments to it as the formatting string. - The formatting string can consist of any letter/numbers, and is used to format - the output. The following special symbols can be used: - - %B : Bold - %Cnn : Foreground Color, where nn is a number corresponding to a mIRC color - %Cnn,nn : Foreground,Background Color - %R : Reverse Foreground/Background Colors - %O : Reset Color and Format (thats an 'oh' not a 'zero (0)') - %C : Reset Color - %U : Underline - -/PLAYING will either print or allow you to set the text for /np. -The default is now_playing, but you can set this to whatever text you prefer. - -/PERCENTAGES will allow you to set whether to use percentages in plugin output or not. -Percentages are enabled by default. Use a zero value to disable, and a non-zero value -to enable. If unsure, use 1. - -/NP & /ENP - Reports what's currently playing in Audacious. - -==== -BUGS -(none known) - -E-mail me your bug reports at chainsaw@gentoo.org -Please include the following information: -- what architecture you are using (amd64, ia64, parisc, ppc, ppc64, sparc, sparc64 or x86) -- what linux distribution you are using (Gentoo 2007.1, Fedora Core 8, etc) -- what compiler you have used to compile X-Sys, i.e. gcc (GCC) 4.1.2 (Gentoo 4.1.2) -- what version of X-Sys you are using - -======= -Thanks! -Remember, everything here is: -(C) 2003, 2004, 2005 by Michael Shoup -(C) 2005, 2006, 2007 by Tony Vroon -All Rights Reserved. -Visit http://dev.gentoo.org/~chainsaw/xsys/ for release information. - -Feel free to e-mail me for feature requests, or see if I'm online on irc.freenode.net diff --git a/plugins/sysinfo/xsys.c b/plugins/sysinfo/xsys.c deleted file mode 100644 index 4ab6e873..00000000 --- a/plugins/sysinfo/xsys.c +++ /dev/null @@ -1,923 +0,0 @@ -/* - * SysInfo - sysinfo plugin for HexChat - * Copyright (c) 2012 Berke Viktor. - * - * xsys.c - main functions for X-Sys 2 - * by mikeshoup - * Copyright (C) 2003, 2004, 2005 Michael Shoup - * Copyright (C) 2005, 2006, 2007 Tony Vroon - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <glib.h> - -#include "hexchat-plugin.h" -#include "parse.h" -#include "match.h" -#include "xsys.h" - -#define DEFAULT_FORMAT "%B%1:%B %2 **" -#define DEFAULT_PERCENT 1 -#define DEFAULT_ANNOUNCE 1 -#define DEFAULT_PCIIDS "/usr/share/hwdata/pci.ids" - -static hexchat_plugin *ph; /* plugin handle */ -static int error_printed = 0; /* semaphore, make sure not to print the same error more than once during one execution */ - -static char name[] = "SysInfo"; -static char desc[] = "Display info about your hardware and OS"; -static char version[] = "3.0"; -static char sysinfo_help[] = "SysInfo Usage:\n /SYSINFO [-e|-o] [OS|DISTRO|CPU|RAM|DISK|VGA|SOUND|ETHERNET|UPTIME], print various details about your system or print a summary without arguments\n /SYSINFO LIST, print current settings\n /SYSINFO SET <variable>, update given setting\n /SYSINFO RESET, reset settings to defaults\n /NETDATA <iface>, show transmitted data on given interface\n /NETSTREAM <iface>, show current bandwidth on given interface\n"; - -void -sysinfo_get_pciids (char* dest) -{ - hexchat_pluginpref_get_str (ph, "pciids", dest); -} - -int -sysinfo_get_percent () -{ - return hexchat_pluginpref_get_int (ph, "percent"); -} - -int -sysinfo_get_announce () -{ - return hexchat_pluginpref_get_int (ph, "announce"); -} - -void -sysinfo_print_error (const char* msg) -{ - if (!error_printed) - { - hexchat_printf (ph, "%s\t%s", name, msg); - } - error_printed++; - -} - -static int -print_summary (int announce, char* format) -{ - char sysinfo[bsize]; - char buffer[bsize]; - char cpu_model[bsize]; - char cpu_cache[bsize]; - char cpu_vendor[bsize]; - char os_host[bsize]; - char os_user[bsize]; - char os_kernel[bsize]; - unsigned long long mem_total; - unsigned long long mem_free; - unsigned int count; - double cpu_freq; - int giga = 0; - int weeks; - int days; - int hours; - int minutes; - int seconds; - sysinfo[0] = '\0'; - - snprintf (buffer, bsize, "%s", hexchat_get_info (ph, "version")); - format_output ("HexChat", buffer, format); - strcat (sysinfo, "\017 "); - strncat (sysinfo, buffer, bsize - strlen (sysinfo)); - - /* BEGIN OS PARSING */ - if (xs_parse_os (os_user, os_host, os_kernel) != 0) - { - hexchat_printf (ph, "%s\tERROR in parse_os()", name); - return HEXCHAT_EAT_ALL; - } - - snprintf (buffer, bsize, "%s", os_kernel); - format_output ("OS", buffer, format); - strcat (sysinfo, "\017 "); - strncat (sysinfo, buffer, bsize - strlen (sysinfo)); - - /* BEGIN DISTRO PARSING */ - if (xs_parse_distro (buffer) != 0) - { - strncpy (buffer, "Unknown", bsize); - } - - format_output ("Distro", buffer, format); - strcat (sysinfo, "\017 "); - strncat (sysinfo, buffer, bsize - strlen (sysinfo)); - - /* BEGIN CPU PARSING */ - if (xs_parse_cpu (cpu_model, cpu_vendor, &cpu_freq, cpu_cache, &count) != 0) - { - hexchat_printf (ph, "%s\tERROR in parse_cpu()", name); - return HEXCHAT_EAT_ALL; - } - - if (cpu_freq > 1000) - { - cpu_freq /= 1000; - giga = 1; - } - - if (giga) - { - snprintf (buffer, bsize, "%u x %s (%s) @ %.2fGHz", count, cpu_model, cpu_vendor, cpu_freq); - } - else - { - snprintf (buffer, bsize, "%u x %s (%s) @ %.0fMHz", count, cpu_model, cpu_vendor, cpu_freq); - } - - format_output ("CPU", buffer, format); - strcat (sysinfo, "\017 "); - strncat (sysinfo, buffer, bsize - strlen (sysinfo)); - - /* BEGIN MEMORY PARSING */ - if (xs_parse_meminfo (&mem_total, &mem_free, 0) == 1) - { - hexchat_printf (ph, "%s\tERROR in parse_meminfo!", name); - return HEXCHAT_EAT_ALL; - } - - snprintf (buffer, bsize, "%s", pretty_freespace ("Physical", &mem_free, &mem_total)); - format_output ("RAM", buffer, format); - strcat (sysinfo, "\017 "); - strncat (sysinfo, buffer, bsize - strlen (sysinfo)); - - /* BEGIN DISK PARSING */ - if (xs_parse_df (NULL, buffer)) - { - hexchat_printf (ph, "%s\tERROR in parse_df", name); - return HEXCHAT_EAT_ALL; - } - - format_output ("Disk", buffer, format); - strcat (sysinfo, "\017 "); - strncat (sysinfo, buffer, bsize - strlen (buffer)); - - /* BEGIN VIDEO PARSING */ - if (xs_parse_video (buffer)) - { - hexchat_printf (ph, "%s\tERROR in parse_video", name); - return HEXCHAT_EAT_ALL; - } - - format_output ("VGA", buffer, format); - strcat (sysinfo, "\017 "); - strncat (sysinfo, buffer, bsize - strlen (buffer)); - - /* BEGIN SOUND PARSING */ - if (xs_parse_sound (buffer)) - { - strncpy (buffer, "Not present", bsize); - } - - format_output ("Sound", buffer, format); - strcat (sysinfo, "\017 "); - strncat (sysinfo, buffer, bsize - strlen (buffer)); - - /* BEGIN ETHERNET PARSING */ - if (xs_parse_ether (buffer)) - { - strncpy (buffer, "None found", bsize); - } - - format_output ("Ethernet", buffer, format); - strcat (sysinfo, "\017 "); - strncat (sysinfo, buffer, bsize - strlen (buffer)); - - /* BEGIN UPTIME PARSING */ - if (xs_parse_uptime (&weeks, &days, &hours, &minutes, &seconds)) - { - hexchat_printf (ph, "%s\tERROR in parse_uptime()", name); - return HEXCHAT_EAT_ALL; - } - - if (minutes != 0 || hours != 0 || days != 0 || weeks != 0) - { - if (hours != 0 || days != 0 || weeks != 0) - { - if (days !=0 || weeks != 0) - { - if (weeks != 0) - { - snprintf (buffer, bsize, "%dw %dd %dh %dm %ds", weeks, days, hours, minutes, seconds); - } - else - { - snprintf (buffer, bsize, "%dd %dh %dm %ds", days, hours, minutes, seconds); - } - } - else - { - snprintf (buffer, bsize, "%dh %dm %ds", hours, minutes, seconds); - } - } - else - { - snprintf (buffer, bsize, "%dm %ds", minutes, seconds); - } - } - - format_output ("Uptime", buffer, format); - strcat (sysinfo, "\017 "); - strncat (sysinfo, buffer, bsize - strlen (buffer)); - - if (announce) - { - hexchat_commandf (ph, "SAY %s", sysinfo); - } - else - { - hexchat_printf (ph, "%s", sysinfo); - } - - return HEXCHAT_EAT_ALL; -} - -static int -print_os (int announce, char* format) -{ - char buffer[bsize]; - char user[bsize]; - char host[bsize]; - char kernel[bsize]; - - if (xs_parse_os (user, host, kernel) != 0) - { - hexchat_printf (ph, "%s\tERROR in parse_os()", name); - return HEXCHAT_EAT_ALL; - } - - snprintf (buffer, bsize, "%s@%s, %s", user, host, kernel); - format_output ("OS", buffer, format); - - if (announce) - { - hexchat_commandf (ph, "SAY %s", buffer); - } - else - { - hexchat_printf (ph, "%s", buffer); - } - - return HEXCHAT_EAT_ALL; -} - -static int -print_distro (int announce, char* format) -{ - char name[bsize]; - - if (xs_parse_distro (name) != 0) - { - hexchat_printf (ph, "%s\tERROR in parse_distro()!", name); - return HEXCHAT_EAT_ALL; - } - - format_output("Distro", name, format); - - if (announce) - { - hexchat_commandf (ph, "SAY %s", name); - } - else - { - hexchat_printf (ph, "%s", name); - } - return HEXCHAT_EAT_ALL; -} - -static int -print_cpu (int announce, char* format) -{ - char model[bsize]; - char vendor[bsize]; - char cache[bsize]; - char buffer[bsize]; - unsigned int count; - double freq; - int giga = 0; - - if (xs_parse_cpu (model, vendor, &freq, cache, &count) != 0) - { - hexchat_printf (ph, "%s\tERROR in parse_cpu()", name); - return HEXCHAT_EAT_ALL; - } - - if (freq > 1000) - { - freq /= 1000; - giga = 1; - } - - if (giga) - { - snprintf (buffer, bsize, "%u x %s (%s) @ %.2fGHz w/ %s L2 Cache", count, model, vendor, freq, cache); - } - else - { - snprintf (buffer, bsize, "%u x %s (%s) @ %.0fMHz w/ %s L2 Cache", count, model, vendor, freq, cache); - } - - format_output ("CPU", buffer, format); - - if (announce) - { - hexchat_commandf (ph, "SAY %s", buffer); - } - else - { - hexchat_printf (ph, "%s", buffer); - } - - return HEXCHAT_EAT_ALL; -} - -static int -print_ram (int announce, char* format) -{ - unsigned long long mem_total; - unsigned long long mem_free; - unsigned long long swap_total; - unsigned long long swap_free; - char string[bsize]; - - if (xs_parse_meminfo (&mem_total, &mem_free, 0) == 1) - { - hexchat_printf (ph, "%s\tERROR in parse_meminfo!", name); - return HEXCHAT_EAT_ALL; - } - if (xs_parse_meminfo (&swap_total, &swap_free, 1) == 1) - { - hexchat_printf (ph, "%s\tERROR in parse_meminfo!", name); - return HEXCHAT_EAT_ALL; - } - - snprintf (string, bsize, "%s - %s", pretty_freespace ("Physical", &mem_free, &mem_total), pretty_freespace ("Swap", &swap_free, &swap_total)); - format_output ("RAM", string, format); - - if (announce) - { - hexchat_commandf (ph, "SAY %s", string); - } - else - { - hexchat_printf (ph, "%s", string); - } - - return HEXCHAT_EAT_ALL; -} - -static int -print_disk (int announce, char* format) -{ - char string[bsize] = {0,}; - -#if 0 - if (*word == '\0') - { - if (xs_parse_df (NULL, string)) - { - hexchat_printf (ph, "ERROR in parse_df"); - return HEXCHAT_EAT_ALL; - } - } - else - { - if (xs_parse_df (*word, string)) - { - hexchat_printf (ph, "ERROR in parse_df"); - return HEXCHAT_EAT_ALL; - } - } -#endif - - if (xs_parse_df (NULL, string)) - { - hexchat_printf (ph, "%s\tERROR in parse_df", name); - return HEXCHAT_EAT_ALL; - } - - format_output ("Disk", string, format); - - if (announce) - { - hexchat_commandf (ph, "SAY %s", string); - } - else - { - hexchat_printf (ph, "%s", string); - } - - return HEXCHAT_EAT_ALL; -} - -static int -print_vga (int announce, char* format) -{ - char vid_card[bsize]; - char agp_bridge[bsize]; - char buffer[bsize]; - int ret; - - if ((ret = xs_parse_video (vid_card)) != 0) - { - hexchat_printf (ph, "%s\tERROR in parse_video! %d", name, ret); - return HEXCHAT_EAT_ALL; - } - - if (xs_parse_agpbridge (agp_bridge) != 0) - { - snprintf (buffer, bsize, "%s", vid_card); - } - else - { - snprintf (buffer, bsize, "%s @ %s", vid_card, agp_bridge); - } - - format_output ("VGA", buffer, format); - - if (announce) - { - hexchat_commandf (ph, "SAY %s", buffer); - } - else - { - hexchat_printf (ph, "%s", buffer); - } - - return HEXCHAT_EAT_ALL; -} - -static int -print_sound (int announce, char* format) -{ - char sound[bsize]; - - if (xs_parse_sound (sound) != 0) - { - hexchat_printf (ph, "%s\tERROR in parse_asound()!", name); - return HEXCHAT_EAT_ALL; - } - - format_output ("Sound", sound, format); - - if (announce) - { - hexchat_commandf (ph, "SAY %s", sound); - } - else - { - hexchat_printf (ph, "%s", sound); - } - - return HEXCHAT_EAT_ALL; -} - - -static int -print_ethernet (int announce, char* format) -{ - char ethernet_card[bsize]; - - if (xs_parse_ether (ethernet_card)) - { - strncpy (ethernet_card, "None found", bsize); - } - - format_output ("Ethernet", ethernet_card, format); - - if (announce) - { - hexchat_commandf (ph, "SAY %s", ethernet_card); - } - else - { - hexchat_printf (ph, "%s", ethernet_card); - } - - return HEXCHAT_EAT_ALL; -} - -static int -print_uptime (int announce, char* format) -{ - char buffer[bsize]; - int weeks; - int days; - int hours; - int minutes; - int seconds; - - if (xs_parse_uptime (&weeks, &days, &hours, &minutes, &seconds)) - { - hexchat_printf (ph, "%s\tERROR in parse_uptime()", name); - return HEXCHAT_EAT_ALL; - } - - if (minutes != 0 || hours != 0 || days != 0 || weeks != 0) - { - if (hours != 0 || days != 0 || weeks != 0) - { - if (days !=0 || weeks != 0) - { - if (weeks != 0) - { - snprintf (buffer, bsize, "%dw %dd %dh %dm %ds", weeks, days, hours, minutes, seconds); - } - else - { - snprintf (buffer, bsize, "%dd %dh %dm %ds", days, hours, minutes, seconds); - } - } - else - { - snprintf (buffer, bsize, "%dh %dm %ds", hours, minutes, seconds); - } - } - else - { - snprintf (buffer, bsize, "%dm %ds", minutes, seconds); - } - } - - format_output ("Uptime", buffer, format); - - if (announce) - { - hexchat_commandf (ph, "SAY %s", buffer); - } - else - { - hexchat_printf (ph, "%s", buffer); - } - - return HEXCHAT_EAT_ALL; -} - -static int -netdata_cb (char *word[], char *word_eol[], void *userdata) -{ - char netdata[bsize]; - char format[bsize]; - unsigned long long bytes_recv; - unsigned long long bytes_sent; - - if (*word[2] == '\0') - { - hexchat_printf (ph, "%s\tYou must specify a network device (e.g. /NETDATA eth0)!", name); - return HEXCHAT_EAT_ALL; - } - - if (xs_parse_netdev (word[2], &bytes_recv, &bytes_sent) != 0) - { - hexchat_printf (ph, "%s\tERROR in parse_netdev", name); - return HEXCHAT_EAT_ALL; - } - - bytes_recv /= 1024; - bytes_sent /= 1024; - - snprintf (netdata, bsize, "%s: %.1f MB Received, %.1f MB Sent", word[2], (double)bytes_recv/1024.0, (double)bytes_sent/1024.0); - hexchat_pluginpref_get_str (ph, "format", format); - format_output ("Netdata", netdata, format); - - if (hexchat_list_int (ph, NULL, "type") >= 2) - { - hexchat_commandf (ph, "SAY %s", netdata); - } - else - { - hexchat_printf (ph, "%s", netdata); - } - - return HEXCHAT_EAT_ALL; -} - -static int -netstream_cb (char *word[], char *word_eol[], void *userdata) -{ - char netstream[bsize]; - char mag_r[5]; - char mag_s[5]; - char format[bsize]; - unsigned long long bytes_recv; - unsigned long long bytes_sent; - unsigned long long bytes_recv_p; - unsigned long long bytes_sent_p; - - struct timespec ts = {1, 0}; - - if (*word[2] == '\0') - { - hexchat_printf (ph, "%s\tYou must specify a network device (e.g. /NETSTREAM eth0)!", name); - return HEXCHAT_EAT_ALL; - } - - if (xs_parse_netdev(word[2], &bytes_recv, &bytes_sent) != 0) - { - hexchat_printf (ph, "%s\tERROR in parse_netdev", name); - return HEXCHAT_EAT_ALL; - } - - while (nanosleep (&ts, &ts) < 0); - - if (xs_parse_netdev(word[2], &bytes_recv_p, &bytes_sent_p) != 0) - { - hexchat_printf (ph, "%s\tERROR in parse_netdev", name); - return HEXCHAT_EAT_ALL; - } - - bytes_recv = (bytes_recv_p - bytes_recv); - bytes_sent = (bytes_sent_p - bytes_sent); - - if (bytes_recv > 1024) - { - bytes_recv /= 1024; - snprintf (mag_r, 5, "KB/s"); - } - else - { - snprintf (mag_r, 5, "B/s"); - } - - if (bytes_sent > 1024) - { - bytes_sent /= 1024; - snprintf (mag_s, 5, "KB/s"); - } - else - { - snprintf (mag_s, 5, "B/s"); - } - - snprintf (netstream, bsize, "%s: Receiving %llu %s, Sending %llu %s", word[2], bytes_recv, mag_r, bytes_sent, mag_s); - hexchat_pluginpref_get_str (ph, "format", format); - format_output ("Netstream", netstream, format); - - if (hexchat_list_int (ph, NULL, "type") >= 2) - { - hexchat_commandf (ph, "SAY %s", netstream); - } - else - { - hexchat_printf (ph, "%s", netstream); - } - - return HEXCHAT_EAT_ALL; -} - -static void -list_settings () -{ - char list[512]; - char buffer[512]; - char* token; - - hexchat_pluginpref_list (ph, list); - hexchat_printf (ph, "%s\tCurrent Settings:", name); - token = strtok (list, ","); - - while (token != NULL) - { - hexchat_pluginpref_get_str (ph, token, buffer); - hexchat_printf (ph, "%s\t%s: %s\n", name, token, buffer); - token = strtok (NULL, ","); - } -} - -static void -reset_settings () -{ - hexchat_pluginpref_set_str (ph, "pciids", DEFAULT_PCIIDS); - hexchat_pluginpref_set_str (ph, "format", DEFAULT_FORMAT); - hexchat_pluginpref_set_int (ph, "percent", DEFAULT_PERCENT); - hexchat_pluginpref_set_int (ph, "announce", DEFAULT_ANNOUNCE); -} - -static int -sysinfo_cb (char *word[], char *word_eol[], void *userdata) -{ - error_printed = 0; - int announce = sysinfo_get_announce (); - int offset = 0; - int buffer; - char format[bsize]; - - if (!hexchat_pluginpref_get_str (ph, "format", format)) - { - hexchat_printf (ph, "%s\tError reading config file!", name); - return HEXCHAT_EAT_ALL; - } - - /* Cannot send to server tab */ - if (hexchat_list_int (ph, NULL, "type") == 1) - { - announce = 0; - } - - /* Allow overriding global announce setting */ - if (!strcmp ("-e", word[2])) - { - announce = 0; - offset++; - } - else if (!strcmp ("-o", word[2])) - { - announce = 1; - offset++; - } - - if (!g_ascii_strcasecmp ("HELP", word[2+offset])) - { - hexchat_printf (ph, "%s", sysinfo_help); - return HEXCHAT_EAT_ALL; - } - else if (!g_ascii_strcasecmp ("LIST", word[2+offset])) - { - list_settings (); - return HEXCHAT_EAT_ALL; - } - else if (!g_ascii_strcasecmp ("SET", word[2+offset])) - { - if (!g_ascii_strcasecmp ("", word_eol[4+offset])) - { - hexchat_printf (ph, "%s\tEnter a value!\n", name); - return HEXCHAT_EAT_ALL; - } - if (!g_ascii_strcasecmp ("format", word[3+offset])) - { - hexchat_pluginpref_set_str (ph, "format", word_eol[4+offset]); - hexchat_printf (ph, "%s\tformat is set to: %s\n", name, word_eol[4+offset]); - } - else if (!g_ascii_strcasecmp ("percent", word[3+offset])) - { - buffer = atoi (word[4+offset]); /* don't use word_eol, numbers must not contain spaces */ - - if (buffer > 0 && buffer < INT_MAX) - { - hexchat_pluginpref_set_int (ph, "percent", buffer); - hexchat_printf (ph, "%s\tpercent is set to: %d\n", name, buffer); - } - else - { - hexchat_printf (ph, "%s\tInvalid input!\n", name); - } - } - else if (!g_ascii_strcasecmp ("announce", word[3+offset])) - { - buffer = atoi (word[4+offset]); /* don't use word_eol, numbers must not contain spaces */ - - if (buffer > 0) - { - hexchat_pluginpref_set_int (ph, "announce", 1); - hexchat_printf (ph, "%s\tannounce is set to: On\n", name); - } - else - { - hexchat_pluginpref_set_int (ph, "announce", 0); - hexchat_printf (ph, "%s\tannounce is set to: Off\n", name); - } - } - else if (!g_ascii_strcasecmp ("pciids", word[3+offset])) - { - hexchat_pluginpref_set_str (ph, "pciids", word_eol[4+offset]); - hexchat_printf (ph, "%s\tpciids is set to: %s\n", name, word_eol[4+offset]); - } - else - { - hexchat_printf (ph, "%s\tInvalid variable name! Use 'pciids', 'format' or 'percent'!\n", name); - return HEXCHAT_EAT_ALL; - } - - return HEXCHAT_EAT_ALL; - } - else if (!g_ascii_strcasecmp ("RESET", word[2+offset])) - { - reset_settings (); - hexchat_printf (ph, "%s\tSettings have been restored to defaults.\n", name); - return HEXCHAT_EAT_ALL; - } - else if (!g_ascii_strcasecmp ("OS", word[2+offset])) - { - print_os (announce, format); - return HEXCHAT_EAT_ALL; - } - else if (!g_ascii_strcasecmp ("DISTRO", word[2+offset])) - { - print_distro (announce, format); - return HEXCHAT_EAT_ALL; - } - else if (!g_ascii_strcasecmp ("CPU", word[2+offset])) - { - print_cpu (announce, format); - return HEXCHAT_EAT_ALL; - } - else if (!g_ascii_strcasecmp ("RAM", word[2+offset])) - { - print_ram (announce, format); - return HEXCHAT_EAT_ALL; - } - else if (!g_ascii_strcasecmp ("DISK", word[2+offset])) - { - print_disk (announce, format); - return HEXCHAT_EAT_ALL; - } - else if (!g_ascii_strcasecmp ("VGA", word[2+offset])) - { - print_vga (announce, format); - return HEXCHAT_EAT_ALL; - } - else if (!g_ascii_strcasecmp ("SOUND", word[2+offset])) - { - print_sound (announce, format); - return HEXCHAT_EAT_ALL; - } - else if (!g_ascii_strcasecmp ("ETHERNET", word[2+offset])) - { - print_ethernet (announce, format); - return HEXCHAT_EAT_ALL; - } - else if (!g_ascii_strcasecmp ("UPTIME", word[2+offset])) - { - print_uptime (announce, format); - return HEXCHAT_EAT_ALL; - } - else if (!g_ascii_strcasecmp ("", word[2+offset])) - { - print_summary (announce, format); - return HEXCHAT_EAT_ALL; - } - else - { - hexchat_printf (ph, "%s", sysinfo_help); - return HEXCHAT_EAT_ALL; - } -} - -int -hexchat_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg) -{ - ph = plugin_handle; - *plugin_name = name; - *plugin_desc = desc; - *plugin_version = version; - char buffer[bsize]; - - hexchat_hook_command (ph, "SYSINFO", HEXCHAT_PRI_NORM, sysinfo_cb, sysinfo_help, NULL); - hexchat_hook_command (ph, "NETDATA", HEXCHAT_PRI_NORM, netdata_cb, NULL, NULL); - hexchat_hook_command (ph, "NETSTREAM", HEXCHAT_PRI_NORM, netstream_cb, NULL, NULL); - - /* this is required for the very first run */ - if (hexchat_pluginpref_get_str (ph, "pciids", buffer) == 0) - { - hexchat_pluginpref_set_str (ph, "pciids", DEFAULT_PCIIDS); - } - - if (hexchat_pluginpref_get_str (ph, "format", buffer) == 0) - { - hexchat_pluginpref_set_str (ph, "format", DEFAULT_FORMAT); - } - - if (hexchat_pluginpref_get_int (ph, "percent") == -1) - { - hexchat_pluginpref_set_int (ph, "percent", DEFAULT_PERCENT); - } - - if (hexchat_pluginpref_get_int (ph, "announce") == -1) - { - hexchat_pluginpref_set_int (ph, "announce", DEFAULT_ANNOUNCE); - } - - hexchat_command (ph, "MENU ADD \"Window/Send System Info\" \"SYSINFO\""); - hexchat_printf (ph, "%s plugin loaded\n", name); - return 1; -} - -int -hexchat_plugin_deinit (void) -{ - hexchat_command (ph, "MENU DEL \"Window/Display System Info\""); - hexchat_printf (ph, "%s plugin unloaded\n", name); - return 1; -} diff --git a/plugins/upd/upd.c b/plugins/upd/upd.c index 6fcf3be9..c9011c04 100644 --- a/plugins/upd/upd.c +++ b/plugins/upd/upd.c @@ -20,260 +20,50 @@ * THE SOFTWARE. */ -#include <windows.h> -#include <wininet.h> - -#include <glib.h> +#include <winsparkle.h> #include "hexchat-plugin.h" -#define DEFAULT_DELAY 30 /* 30 seconds */ -#define DEFAULT_FREQ 360 /* 6 hours */ -#define DOWNLOAD_URL "http://dl.hexchat.net/hexchat" +#define APPCAST_URL "https://dl.hexchat.net/appcast.xml" static hexchat_plugin *ph; /* plugin handle */ static char name[] = "Update Checker"; static char desc[] = "Check for HexChat updates automatically"; -static char version[] = "4.0"; -static const char upd_help[] = "Update Checker Usage:\n /UPDCHK, check for HexChat updates\n /UPDCHK SET delay|freq, set startup delay or check frequency\n"; - -static char* -check_version () -{ - HINTERNET hOpen, hConnect, hResource; - - hOpen = InternetOpen (TEXT ("Update Checker"), - INTERNET_OPEN_TYPE_PRECONFIG, - NULL, - NULL, - 0); - if (!hOpen) - { - return "Unknown"; - } - - hConnect = InternetConnect (hOpen, - TEXT ("raw.github.com"), - INTERNET_DEFAULT_HTTPS_PORT, - NULL, - NULL, - INTERNET_SERVICE_HTTP, - 0, - 0); - if (!hConnect) - { - InternetCloseHandle (hOpen); - return "Unknown"; - } - - hResource = HttpOpenRequest (hConnect, - TEXT ("GET"), - TEXT ("/hexchat/hexchat/master/win32/version.txt"), - TEXT ("HTTP/1.0"), - NULL, - NULL, - INTERNET_FLAG_SECURE | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_AUTH, - 0); - if (!hResource) - { - InternetCloseHandle (hConnect); - InternetCloseHandle (hOpen); - return "Unknown"; - } - else - { - static char buffer[1024]; - char infobuffer[32]; - int statuscode; - - DWORD dwRead; - DWORD infolen = sizeof(infobuffer); - - HttpAddRequestHeaders (hResource, TEXT ("Connection: close\r\n"), -1L, HTTP_ADDREQ_FLAG_ADD); /* workaround for GC bug */ - HttpSendRequest (hResource, NULL, 0, NULL, 0); - - while (InternetReadFile (hResource, buffer, 1023, &dwRead)) - { - if (dwRead == 0) - { - break; - } - buffer[dwRead] = 0; - } - - HttpQueryInfo(hResource, - HTTP_QUERY_STATUS_CODE, - &infobuffer, - &infolen, - NULL); - - InternetCloseHandle (hResource); - InternetCloseHandle (hConnect); - InternetCloseHandle (hOpen); - - statuscode = atoi(infobuffer); - if (statuscode == 200) - return buffer; - else - return "Unknown"; - } -} - -static int -print_version (char *word[], char *word_eol[], void *userdata) -{ - char *version; - int prevbuf; - int convbuf; - - if (!g_ascii_strcasecmp ("HELP", word[2])) - { - hexchat_printf (ph, "%s", upd_help); - return HEXCHAT_EAT_HEXCHAT; - } - else if (!g_ascii_strcasecmp ("SET", word[2])) - { - if (!g_ascii_strcasecmp ("", word_eol[4])) - { - hexchat_printf (ph, "%s\tEnter a value!\n", name); - return HEXCHAT_EAT_HEXCHAT; - } - if (!g_ascii_strcasecmp ("delay", word[3])) - { - convbuf = atoi (word[4]); /* don't use word_eol, numbers must not contain spaces */ - - if (convbuf > 0 && convbuf < INT_MAX) - { - prevbuf = hexchat_pluginpref_get_int (ph, "delay"); - hexchat_pluginpref_set_int (ph, "delay", convbuf); - hexchat_printf (ph, "%s\tUpdate check startup delay is set to %d seconds (from %d).\n", name, convbuf, prevbuf); - } - else - { - hexchat_printf (ph, "%s\tInvalid input!\n", name); - } - } - else if (!g_ascii_strcasecmp ("freq", word[3])) - { - convbuf = atoi (word[4]); /* don't use word_eol, numbers must not contain spaces */ - - if (convbuf > 0 && convbuf < INT_MAX) - { - prevbuf = hexchat_pluginpref_get_int (ph, "freq"); - hexchat_pluginpref_set_int (ph, "freq", convbuf); - hexchat_printf (ph, "%s\tUpdate check frequency is set to %d minutes (from %d).\n", name, convbuf, prevbuf); - } - else - { - hexchat_printf (ph, "%s\tInvalid input!\n", name); - } - } - else - { - hexchat_printf (ph, "%s\tInvalid variable name! Use 'delay' or 'freq'!\n", name); - return HEXCHAT_EAT_HEXCHAT; - } - - return HEXCHAT_EAT_HEXCHAT; - } - else if (!g_ascii_strcasecmp ("", word[2])) - { - version = check_version (); - - if (strcmp (version, hexchat_get_info (ph, "version")) == 0) - { - hexchat_printf (ph, "%s\tYou have the latest version of HexChat installed!\n", name); - } - else if (strcmp (version, "Unknown") == 0) - { - hexchat_printf (ph, "%s\tUnable to check for HexChat updates!\n", name); - } - else - { -#ifdef _WIN64 /* use this approach, the wProcessorArchitecture method always returns 0 (=x86) for some reason */ - hexchat_printf (ph, "%s:\tA HexChat update is available! You can download it from here:\n%s/HexChat%%20%s%%20x64.exe\n", name, DOWNLOAD_URL, version); -#else - hexchat_printf (ph, "%s:\tA HexChat update is available! You can download it from here:\n%s/HexChat%%20%s%%20x86.exe\n", name, DOWNLOAD_URL, version); -#endif - } - return HEXCHAT_EAT_HEXCHAT; - } - else - { - hexchat_printf (ph, "%s", upd_help); - return HEXCHAT_EAT_HEXCHAT; - } -} - -static int -print_version_quiet (void *userdata) -{ - char *version = check_version (); - - /* if it's not the current version AND not network error */ - if (!(strcmp (version, hexchat_get_info (ph, "version")) == 0) && !(strcmp (version, "Unknown") == 0)) - { -#ifdef _WIN64 /* use this approach, the wProcessorArchitecture method always returns 0 (=x86) for plugins for some reason */ - hexchat_printf (ph, "%s\tA HexChat update is available! You can download it from here:\n%s/HexChat%%20%s%%20x64.exe\n", name, DOWNLOAD_URL, version); -#else - hexchat_printf (ph, "%s\tA HexChat update is available! You can download it from here:\n%s/HexChat%%20%s%%20x86.exe\n", name, DOWNLOAD_URL, version); -#endif - /* print update url once, then stop the timer */ - return 0; - } - /* keep checking */ - return 1; -} +static char version[] = "5.0"; +static const char upd_help[] = "Update Checker Usage:\n /UPDCHK, check for HexChat updates\n"; static int -delayed_check (void *userdata) +check_cmd (char *word[], char *word_eol[], void *userdata) { - int freq = hexchat_pluginpref_get_int (ph, "freq"); + win_sparkle_check_update_with_ui (); - /* only start the timer if there's no update available during startup */ - if (print_version_quiet (NULL)) - { - /* check for updates, every 6 hours by default */ - hexchat_hook_timer (ph, freq * 1000 * 60, print_version_quiet, NULL); - } - - return 0; /* run delayed_check() only once */ + return HEXCHAT_EAT_ALL; } int hexchat_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg) { - int delay; ph = plugin_handle; *plugin_name = name; *plugin_desc = desc; *plugin_version = version; - /* these are required for the very first run */ - delay = hexchat_pluginpref_get_int (ph, "delay"); - if (delay == -1) - { - delay = DEFAULT_DELAY; - hexchat_pluginpref_set_int (ph, "delay", DEFAULT_DELAY); - } - - if (hexchat_pluginpref_get_int (ph, "freq") == -1) - { - hexchat_pluginpref_set_int (ph, "freq", DEFAULT_FREQ); - } + win_sparkle_set_appcast_url (APPCAST_URL); + win_sparkle_init (); - hexchat_hook_command (ph, "UPDCHK", HEXCHAT_PRI_NORM, print_version, upd_help, NULL); - hexchat_hook_timer (ph, delay * 1000, delayed_check, NULL); + hexchat_hook_command (ph, "UPDCHK", HEXCHAT_PRI_NORM, check_cmd, upd_help, NULL); hexchat_command (ph, "MENU -ishare\\download.png ADD \"Help/Check for Updates\" \"UPDCHK\""); hexchat_printf (ph, "%s plugin loaded\n", name); - return 1; /* return 1 for success */ + return 1; } int hexchat_plugin_deinit (void) { + win_sparkle_cleanup (); + hexchat_command (ph, "MENU DEL \"Help/Check for updates\""); hexchat_printf (ph, "%s plugin unloaded\n", name); return 1; diff --git a/plugins/upd/upd.vcxproj b/plugins/upd/upd.vcxproj index e7e7785a..e39a2887 100644 --- a/plugins/upd/upd.vcxproj +++ b/plugins/upd/upd.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -19,80 +20,33 @@ <RootNamespace>upd</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <TargetName>hcupd</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\hexchat.props" /> + <PropertyGroup> <TargetName>hcupd</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <OutDir>$(HexChatRel)plugins\</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;UPD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MultiProcessorCompilation>true</MultiProcessorCompilation> - <AdditionalIncludeDirectories>..\..\src\common;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;UPD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <AdditionalIncludeDirectories>..\..\src\common;$(WinSparklePath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> <ModuleDefinitionFile>upd.def</ModuleDefinitionFile> - <AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>$(DepLibs);WinSparkle.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;$(WinSparklePath);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;UPD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MultiProcessorCompilation>true</MultiProcessorCompilation> - <AdditionalIncludeDirectories>..\..\src\common;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + <AdditionalIncludeDirectories>..\..\src\common;$(WinSparklePath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> <ModuleDefinitionFile>upd.def</ModuleDefinitionFile> - <AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> - <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>$(DepLibs);WinSparkle.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;$(WinSparklePath);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemGroup> @@ -102,6 +56,4 @@ <ClCompile Include="upd.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/plugins/winamp/winamp.c b/plugins/winamp/winamp.c index 389adcbc..d8788164 100644 --- a/plugins/winamp/winamp.c +++ b/plugins/winamp/winamp.c @@ -13,6 +13,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <glib.h> #include "hexchat-plugin.h" @@ -21,163 +22,127 @@ static hexchat_plugin *ph; /* plugin handle */ -BOOL winamp_found = FALSE; - -int status = 0; - -/* Slightly modified from X-Chat's log_escape_strcpy */ -static char * -song_strcpy (char *dest, char *src) +static int +winamp(char *word[], char *word_eol[], void *userdata) { - while (*src) - { - *dest = *src; - dest++; - src++; + HWND hwndWinamp = FindWindowW(L"Winamp v1.x",NULL); - if (*src == '%') + if (hwndWinamp) + { + if (!stricmp("PAUSE", word[2])) { - dest[0] = '%'; - dest++; + if (SendMessage(hwndWinamp,WM_USER, 0, 104)) + { + SendMessage(hwndWinamp, WM_COMMAND, 40046, 0); + + if (SendMessage(hwndWinamp, WM_USER, 0, 104) == PLAYING) + hexchat_printf(ph, "Winamp: playing"); + else + hexchat_printf(ph, "Winamp: paused"); + } } - } - - dest[0] = 0; - return dest - 1; -} - -static int -winamp(char *word[], char *word_eol[], void *userdata) -{ + else if (!stricmp("STOP", word[2])) + { + SendMessage(hwndWinamp, WM_COMMAND, 40047, 0); + hexchat_printf(ph, "Winamp: stopped"); + } + else if (!stricmp("PLAY", word[2])) + { + SendMessage(hwndWinamp, WM_COMMAND, 40045, 0); + hexchat_printf(ph, "Winamp: playing"); + } + else if (!stricmp("NEXT", word[2])) + { + SendMessage(hwndWinamp, WM_COMMAND, 40048, 0); + hexchat_printf(ph, "Winamp: next playlist entry"); + } + else if (!stricmp("PREV", word[2])) + { + SendMessage(hwndWinamp, WM_COMMAND, 40044, 0); + hexchat_printf(ph, "Winamp: previous playlist entry"); + } + else if (!stricmp("START", word[2])) + { + SendMessage(hwndWinamp, WM_COMMAND, 40154, 0); + hexchat_printf(ph, "Winamp: playlist start"); + } + else if (!word_eol[2][0]) + { + wchar_t wcurrent_play[2048]; + char *current_play, *p; + int len = GetWindowTextW(hwndWinamp, wcurrent_play, G_N_ELEMENTS(wcurrent_play)); -char current_play[2048], *p; -char p_esc[2048]; -char cur_esc[2048]; -char truc[2048]; -HWND hwndWinamp = FindWindow("Winamp v1.x",NULL); + current_play = g_utf16_to_utf8 (wcurrent_play, len, NULL, NULL, NULL); + if (!current_play) + { + hexchat_print (ph, "Winamp: Error getting song information."); + return HEXCHAT_EAT_ALL; + } - if (hwndWinamp) - { - { - if (!stricmp("PAUSE", word[2])) + if (strchr(current_play, '-')) { - if (SendMessage(hwndWinamp,WM_USER, 0, 104)) + /* Remove any trailing text and whitespace */ + p = current_play + strlen(current_play) - 8; + while (p >= current_play) { - SendMessage(hwndWinamp, WM_COMMAND, 40046, 0); - - if (SendMessage(hwndWinamp, WM_USER, 0, 104) == PLAYING) - hexchat_printf(ph, "Winamp: playing"); - else - hexchat_printf(ph, "Winamp: paused"); + if (!strnicmp(p, "- Winamp", 8)) + break; + p--; } - } - else - if (!stricmp("STOP", word[2])) - { - SendMessage(hwndWinamp, WM_COMMAND, 40047, 0); - hexchat_printf(ph, "Winamp: stopped"); - } - else - if (!stricmp("PLAY", word[2])) - { - SendMessage(hwndWinamp, WM_COMMAND, 40045, 0); - hexchat_printf(ph, "Winamp: playing"); - } - else - - if (!stricmp("NEXT", word[2])) - { - SendMessage(hwndWinamp, WM_COMMAND, 40048, 0); - hexchat_printf(ph, "Winamp: next playlist entry"); - } - else - if (!stricmp("PREV", word[2])) - { - SendMessage(hwndWinamp, WM_COMMAND, 40044, 0); - hexchat_printf(ph, "Winamp: previous playlist entry"); - } - else - - if (!stricmp("START", word[2])) - { - SendMessage(hwndWinamp, WM_COMMAND, 40154, 0); - hexchat_printf(ph, "Winamp: playlist start"); - } - - else - - if (!word_eol[2][0]) - { - GetWindowText(hwndWinamp, current_play, sizeof(current_play)); - - if (strchr(current_play, '-')) - { - - p = current_play + strlen(current_play) - 8; - while (p >= current_play) - { - if (!strnicmp(p, "- Winamp", 8)) break; - p--; - } - - if (p >= current_play) p--; - - while (p >= current_play && *p == ' ') p--; - *++p=0; - - - p = strchr(current_play, '.') + 1; - - song_strcpy(p_esc, p); - song_strcpy(cur_esc, current_play); - - if (p) - { - sprintf(truc, "me is now playing:%s", p_esc); - } - else - { - sprintf(truc, "me is now playing:%s", cur_esc); - } - - hexchat_commandf(ph, truc); - - } - else hexchat_print(ph, "Winamp: Nothing being played."); + if (p >= current_play) + p--; + + while (p >= current_play && *p == ' ') + p--; + *++p = '\0'; + + /* Ignore any leading track number */ + p = strstr (current_play, ". "); + if (p) + p += 2; + else + p = current_play; + + if (*p != '\0') + hexchat_commandf (ph, "me is now playing: %s", p); + else + hexchat_print (ph, "Winamp: No song information found."); + g_free (current_play); } - else - hexchat_printf(ph, "Usage: /WINAMP [PAUSE|PLAY|STOP|NEXT|PREV|START]\n"); - } - + else + hexchat_print(ph, "Winamp: Nothing being played."); + } + else + hexchat_printf(ph, "Usage: /WINAMP [PAUSE|PLAY|STOP|NEXT|PREV|START]\n"); } else { - hexchat_print(ph, "Winamp not found.\n"); + hexchat_print(ph, "Winamp not found.\n"); } return HEXCHAT_EAT_ALL; } int hexchat_plugin_init(hexchat_plugin *plugin_handle, - char **plugin_name, - char **plugin_desc, - char **plugin_version, - char *arg) + char **plugin_name, + char **plugin_desc, + char **plugin_version, + char *arg) { /* we need to save this for use with any hexchat_* functions */ ph = plugin_handle; *plugin_name = "Winamp"; *plugin_desc = "Winamp plugin for HexChat"; - *plugin_version = "0.5"; + *plugin_version = "0.6"; hexchat_hook_command (ph, "WINAMP", HEXCHAT_PRI_NORM, winamp, "Usage: /WINAMP [PAUSE|PLAY|STOP|NEXT|PREV|START] - control Winamp or show what's currently playing", 0); hexchat_command (ph, "MENU -ishare\\music.png ADD \"Window/Display Current Song (Winamp)\" \"WINAMP\""); hexchat_print (ph, "Winamp plugin loaded\n"); - return 1; /* return 1 for success */ + return 1; /* return 1 for success */ } int diff --git a/plugins/winamp/winamp.vcxproj b/plugins/winamp/winamp.vcxproj index 3c0cfb34..cf839cfa 100644 --- a/plugins/winamp/winamp.vcxproj +++ b/plugins/winamp/winamp.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -19,76 +20,31 @@ <RootNamespace>winamp</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>DynamicLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <TargetName>hcwinamp</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\hexchat.props" /> + <PropertyGroup> <TargetName>hcwinamp</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <OutDir>$(HexChatRel)plugins\</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WINAMP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MultiProcessorCompilation>true</MultiProcessorCompilation> - <AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> - <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <ModuleDefinitionFile>winamp.def</ModuleDefinitionFile> - </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;WINAMP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MultiProcessorCompilation>true</MultiProcessorCompilation> - <AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + </ItemDefinitionGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> <ModuleDefinitionFile>winamp.def</ModuleDefinitionFile> + <AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemGroup> @@ -98,6 +54,4 @@ <ClCompile Include="winamp.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> </Project> \ No newline at end of file diff --git a/po/POTFILES.in b/po/POTFILES.in index fa918608..5bde0376 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -10,6 +10,7 @@ src/common/inbound.c src/common/notify.c src/common/outbound.c src/common/plugin.c +src/common/plugin-identd.c src/common/plugin-timer.c src/common/server.c src/common/servlist.c @@ -31,6 +32,7 @@ src/fe-gtk/joind.c src/fe-gtk/maingui.c src/fe-gtk/menu.c src/fe-gtk/notifygui.c +src/fe-gtk/plugin-notification.c src/fe-gtk/plugin-tray.c src/fe-gtk/plugingui.c src/fe-gtk/rawlog.c @@ -41,3 +43,4 @@ src/fe-gtk/textgui.c src/fe-gtk/urlgrab.c src/fe-gtk/userlistgui.c src/fe-text/fe-text.c +plugins/sysinfo/sysinfo.c diff --git a/src/common/Makefile.am b/src/common/Makefile.am index e9255d0c..75aa12bc 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -1,5 +1,7 @@ ## Process this file with automake to produce Makefile.in +include $(top_srcdir)/m4/clang-analyze.am + noinst_LIBRARIES = libhexchatcommon.a AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(top_srcdir) @@ -14,17 +16,16 @@ EXTRA_DIST = \ hexchatc.h \ hexchat-plugin.h \ history.h \ - identd.c \ ignore.h \ inbound.h \ inet.h \ make-te.c \ modes.h \ - msproxy.h \ network.h \ notify.h \ outbound.h \ plugin.h \ + plugin-identd.h \ plugin-timer.h \ proto-irc.h \ server.h \ @@ -32,6 +33,7 @@ EXTRA_DIST = \ ssl.h \ ssl.c \ text.h \ + typedef.h \ textenums.h \ textevents.h \ textevents.in \ @@ -44,10 +46,6 @@ if USE_OPENSSL ssl_c = ssl.c endif -if USE_MSPROXY -msproxy_c = msproxy.c -endif - if USE_DBUS dbusdir = dbus libhexchatcommon_a_LIBADD = \ @@ -62,8 +60,8 @@ endif noinst_PROGRAMS = make-te libhexchatcommon_a_SOURCES = cfgfiles.c chanopt.c ctcp.c dcc.c hexchat.c \ - history.c ignore.c inbound.c marshal.c modes.c $(msproxy_c) network.c notify.c \ - outbound.c plugin.c plugin-timer.c proto-irc.c server.c servlist.c \ + history.c ignore.c inbound.c marshal.c modes.c network.c notify.c \ + outbound.c plugin.c plugin-identd.c plugin-timer.c proto-irc.c server.c servlist.c \ $(ssl_c) text.c tree.c url.c userlist.c util.c libhexchatcommon_a_CFLAGS = $(LIBPROXY_CFLAGS) @@ -79,6 +77,12 @@ marshal.c: $(srcdir)/marshalers.list $(AM_V_GEN) $(GLIB_GENMARSHAL) --prefix=_hexchat_marshal --body $< > $@ +if DO_STATIC_ANALYSIS +analyze_plists = $(libhexchatcommon_a_SOURCES:%.c=%.plist) +all-local: $(analyze_plists) +MOSTLYCLEANFILES = $(analyze_plists) +endif + BUILT_SOURCES = textenums.h textevents.h marshal.c marshal.h CLEANFILES = $(BUILT_SOURCES) diff --git a/src/common/cfgfiles.c b/src/common/cfgfiles.c index a8bd32f9..a49e17ae 100644 --- a/src/common/cfgfiles.c +++ b/src/common/cfgfiles.c @@ -39,7 +39,7 @@ #endif #define DEF_FONT "Monospace 9" -#define DEF_FONT_ALTER "Arial Unicode MS,Lucida Sans Unicode,MS Gothic,Unifont" +#define DEF_FONT_ALTER "Arial Unicode MS,Segoe UI Emoji,Lucida Sans Unicode,Meiryo,Symbola,Unifont" const char * const languages[LANGUAGES_LENGTH] = { "af", "sq", "am", "ast", "az", "eu", "be", "bg", "ca", "zh_CN", /* 0 .. 9 */ @@ -57,15 +57,11 @@ list_addentry (GSList ** list, char *cmd, char *name) size_t name_len; size_t cmd_len = 1; - /* remove <2.8.0 stuff */ - if (!strcmp (cmd, "away") && !strcmp (name, "BACK")) - return; - if (cmd) cmd_len = strlen (cmd) + 1; name_len = strlen (name) + 1; - pop = malloc (sizeof (struct popup) + cmd_len + name_len); + pop = g_malloc (sizeof (struct popup) + cmd_len + name_len); pop->name = (char *) pop + sizeof (struct popup); pop->cmd = pop->name + name_len; @@ -137,13 +133,13 @@ list_loadconf (char *file, GSList ** list, char *defaultconf) abort (); } - ibuf = malloc (st.st_size); + ibuf = g_malloc (st.st_size); read (fd, ibuf, st.st_size); close (fd); list_load_from_data (list, ibuf, st.st_size); - free (ibuf); + g_free (ibuf); } void @@ -153,7 +149,7 @@ list_free (GSList ** list) while (*list) { data = (void *) (*list)->data; - free (data); + g_free (data); *list = g_slist_remove (*list, data); } } @@ -170,7 +166,7 @@ list_delentry (GSList ** list, char *name) if (!g_ascii_strcasecmp (name, pop->name)) { *list = g_slist_remove (*list, pop); - free (pop); + g_free (pop); return 1; } alist = alist->next; @@ -211,10 +207,10 @@ cfg_get_str (char *cfg, const char *var, char *dest, int dest_len) while (*cfg != 0 && *cfg != '\n') cfg++; if (*cfg == 0) - return 0; + return NULL; cfg++; if (*cfg == 0) - return 0; + return NULL; } } @@ -224,18 +220,18 @@ cfg_put_str (int fh, char *var, char *value) char buf[512]; int len; - snprintf (buf, sizeof buf, "%s = %s\n", var, value); + g_snprintf (buf, sizeof buf, "%s = %s\n", var, value); len = strlen (buf); return (write (fh, buf, len) == len); } int -cfg_put_color (int fh, int r, int g, int b, char *var) +cfg_put_color (int fh, guint16 r, guint16 g, guint16 b, char *var) { char buf[400]; int len; - snprintf (buf, sizeof buf, "%s = %04x %04x %04x\n", var, r, g, b); + g_snprintf (buf, sizeof buf, "%s = %04hx %04hx %04hx\n", var, r, g, b); len = strlen (buf); return (write (fh, buf, len) == len); } @@ -249,20 +245,20 @@ cfg_put_int (int fh, int value, char *var) if (value == -1) value = 1; - snprintf (buf, sizeof buf, "%s = %d\n", var, value); + g_snprintf (buf, sizeof buf, "%s = %d\n", var, value); len = strlen (buf); return (write (fh, buf, len) == len); } int -cfg_get_color (char *cfg, char *var, int *r, int *g, int *b) +cfg_get_color (char *cfg, char *var, guint16 *r, guint16 *g, guint16 *b) { char str[128]; if (!cfg_get_str (cfg, var, str, sizeof (str))) return 0; - sscanf (str, "%04x %04x %04x", r, g, b); + sscanf (str, "%04hx %04hx %04hx", r, g, b); return 1; } @@ -312,9 +308,7 @@ get_xdir (void) if (portable_mode () || SHGetKnownFolderPath (&FOLDERID_RoamingAppData, 0, NULL, &roaming_path_wide) != S_OK) { - char *path; - - path = g_win32_get_package_installation_directory_of_module (NULL); + char *path = g_win32_get_package_installation_directory_of_module (NULL); if (path) { xdir = g_build_filename (path, "config", NULL); @@ -440,6 +434,7 @@ const struct prefs vars[] = {"gui_tab_dots", P_OFFINT (hex_gui_tab_dots), TYPE_BOOL}, {"gui_tab_icons", P_OFFINT (hex_gui_tab_icons), TYPE_BOOL}, {"gui_tab_layout", P_OFFINT (hex_gui_tab_layout), TYPE_INT}, + {"gui_tab_middleclose", P_OFFINT (hex_gui_tab_middleclose), TYPE_BOOL}, {"gui_tab_newtofront", P_OFFINT (hex_gui_tab_newtofront), TYPE_INT}, {"gui_tab_pos", P_OFFINT (hex_gui_tab_pos), TYPE_INT}, {"gui_tab_scrollchans", P_OFFINT (hex_gui_tab_scrollchans), TYPE_BOOL}, @@ -482,11 +477,11 @@ const struct prefs vars[] = {"gui_win_width", P_OFFINT (hex_gui_win_width), TYPE_INT}, {"identd", P_OFFINT (hex_identd), TYPE_BOOL}, + {"identd_port", P_OFFINT (hex_identd_port), TYPE_INT}, {"input_balloon_chans", P_OFFINT (hex_input_balloon_chans), TYPE_BOOL}, {"input_balloon_hilight", P_OFFINT (hex_input_balloon_hilight), TYPE_BOOL}, {"input_balloon_priv", P_OFFINT (hex_input_balloon_priv), TYPE_BOOL}, - {"input_balloon_time", P_OFFINT (hex_input_balloon_time), TYPE_INT}, {"input_beep_chans", P_OFFINT (hex_input_beep_chans), TYPE_BOOL}, {"input_beep_hilight", P_OFFINT (hex_input_beep_hilight), TYPE_BOOL}, {"input_beep_priv", P_OFFINT (hex_input_beep_priv), TYPE_BOOL}, @@ -590,10 +585,10 @@ const struct prefs vars[] = {0, 0, 0}, }; -static char * +static const char * convert_with_fallback (const char *str, const char *fallback) { - char *utf; + const char *utf; #ifndef WIN32 /* On non-Windows, g_get_user_name and g_get_real_name return a string in system locale, so convert it to utf-8. */ @@ -652,7 +647,7 @@ get_default_language (void) if (lang_no >= 0) { - free (lang); + g_free (lang); return lang_no; } @@ -661,7 +656,7 @@ get_default_language (void) lang_no = find_language_number (lang); - free (lang); + g_free (lang); return lang_no >= 0 ? lang_no : find_language_number ("en"); } @@ -703,8 +698,8 @@ get_default_spell_languages (void) } } } - if (last != NULL) - g_free(last); + + g_free (last); if (lang_list[0]) return g_strdup (ret); @@ -765,6 +760,7 @@ load_default_config(void) prefs.hex_gui_tab_chans = 1; prefs.hex_gui_tab_dialogs = 1; prefs.hex_gui_tab_icons = 1; + prefs.hex_gui_tab_middleclose = 1; prefs.hex_gui_tab_server = 1; prefs.hex_gui_tab_sort = 1; prefs.hex_gui_topicbar = 1; @@ -776,7 +772,6 @@ load_default_config(void) prefs.hex_gui_ulist_resizable = 1; prefs.hex_gui_ulist_style = 1; prefs.hex_gui_win_save = 1; - prefs.hex_identd = 1; prefs.hex_input_flash_hilight = 1; prefs.hex_input_flash_priv = 1; prefs.hex_input_tray_hilight = 1; @@ -832,7 +827,6 @@ load_default_config(void) prefs.hex_gui_ulist_pos = 3; prefs.hex_gui_win_height = 400; prefs.hex_gui_win_width = 640; - prefs.hex_input_balloon_time = 20; prefs.hex_irc_ban_type = 1; prefs.hex_irc_join_delay = 5; prefs.hex_net_reconnect_delay = 10; @@ -847,7 +841,7 @@ load_default_config(void) #ifdef WIN32 if (portable_mode () || SHGetKnownFolderPath (&FOLDERID_Downloads, 0, NULL, &roaming_path_wide) != S_OK) { - snprintf (prefs.hex_dcc_dir, sizeof (prefs.hex_dcc_dir), "%s\\downloads", get_xdir ()); + g_snprintf (prefs.hex_dcc_dir, sizeof (prefs.hex_dcc_dir), "%s\\downloads", get_xdir ()); } else { @@ -861,34 +855,36 @@ load_default_config(void) #else if (g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD)) { - strcpy (prefs.hex_dcc_dir, g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD)); + safe_strcpy (prefs.hex_dcc_dir, g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD), sizeof(prefs.hex_dcc_dir)); } else { - strcpy (prefs.hex_dcc_dir, g_build_filename (g_get_home_dir (), "Downloads", NULL)); + char *download_dir = g_build_filename (g_get_home_dir (), "Downloads", NULL); + safe_strcpy (prefs.hex_dcc_dir, download_dir, sizeof(prefs.hex_dcc_dir)); + g_free (download_dir); } #endif strcpy (prefs.hex_gui_ulist_doubleclick, "QUERY %s"); strcpy (prefs.hex_input_command_char, "/"); - strcpy (prefs.hex_irc_logmask, g_build_filename ("%n", "%c.log", NULL)); - strcpy (prefs.hex_irc_nick1, username); - strcpy (prefs.hex_irc_nick2, username); - strcat (prefs.hex_irc_nick2, "_"); - strcpy (prefs.hex_irc_nick3, username); - strcat (prefs.hex_irc_nick3, "__"); + strcpy (prefs.hex_irc_logmask, "%n"G_DIR_SEPARATOR_S"%c.log"); + safe_strcpy (prefs.hex_irc_nick1, username, sizeof(prefs.hex_irc_nick1)); + safe_strcpy (prefs.hex_irc_nick2, username, sizeof(prefs.hex_irc_nick2)); + g_strlcat (prefs.hex_irc_nick2, "_", sizeof(prefs.hex_irc_nick2)); + safe_strcpy (prefs.hex_irc_nick3, username, sizeof(prefs.hex_irc_nick3)); + g_strlcat (prefs.hex_irc_nick3, "__", sizeof(prefs.hex_irc_nick3)); strcpy (prefs.hex_irc_no_hilight, "NickServ,ChanServ,InfoServ,N,Q"); - strcpy (prefs.hex_irc_part_reason, _("Leaving")); - strcpy (prefs.hex_irc_quit_reason, prefs.hex_irc_part_reason); - strcpy (prefs.hex_irc_real_name, realname); - strcpy (prefs.hex_irc_user_name, username); + safe_strcpy (prefs.hex_irc_part_reason, _("Leaving"), sizeof(prefs.hex_irc_part_reason)); + safe_strcpy (prefs.hex_irc_quit_reason, prefs.hex_irc_part_reason, sizeof(prefs.hex_irc_quit_reason)); + safe_strcpy (prefs.hex_irc_real_name, realname, sizeof(prefs.hex_irc_real_name)); + safe_strcpy (prefs.hex_irc_user_name, username, sizeof(prefs.hex_irc_user_name)); strcpy (prefs.hex_stamp_log_format, "%b %d %H:%M:%S "); strcpy (prefs.hex_stamp_text_format, "[%H:%M:%S] "); font = fe_get_default_font (); if (font) { - strcpy (prefs.hex_text_font, font); - strcpy (prefs.hex_text_font_main, font); + safe_strcpy (prefs.hex_text_font, font, sizeof(prefs.hex_text_font)); + safe_strcpy (prefs.hex_text_font_main, font, sizeof(prefs.hex_text_font_main)); } else { @@ -898,7 +894,7 @@ load_default_config(void) strcpy (prefs.hex_text_font_alternative, DEF_FONT_ALTER); langs = get_default_spell_languages (); - strcpy (prefs.hex_text_spell_langs, langs); + safe_strcpy (prefs.hex_text_spell_langs, langs, sizeof(prefs.hex_text_spell_langs)); /* private variables */ @@ -1228,7 +1224,7 @@ cmd_set (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (erase || *val) { /* save the previous value until we print it out */ - prev_string = (char*) malloc (vars[i].len + 1); + prev_string = g_malloc (vars[i].len + 1); strncpy (prev_string, (char *) &prefs + vars[i].offset, vars[i].len); /* update the variable */ @@ -1240,7 +1236,7 @@ cmd_set (struct session *sess, char *tbuf, char *word[], char *word_eol[]) PrintTextf (sess, "%s set to: %s (was: %s)\n", var, (char *) &prefs + vars[i].offset, prev_string); } - free (prev_string); + g_free (prev_string); } else { @@ -1315,7 +1311,7 @@ cmd_set (struct session *sess, char *tbuf, char *word[], char *word_eol[]) } int -hexchat_open_file (char *file, int flags, int mode, int xof_flags) +hexchat_open_file (const char *file, int flags, int mode, int xof_flags) { char *buf; int fd; @@ -1351,7 +1347,7 @@ hexchat_fopen_file (const char *file, const char *mode, int xof_flags) FILE *fh; if (xof_flags & XOF_FULLPATH) - return fopen (file, mode); + return g_fopen (file, mode); buf = g_build_filename (get_xdir (), file, NULL); fh = g_fopen (buf, mode); diff --git a/src/common/cfgfiles.h b/src/common/cfgfiles.h index 8b996ca0..b421884a 100644 --- a/src/common/cfgfiles.h +++ b/src/common/cfgfiles.h @@ -34,8 +34,8 @@ int cfg_get_bool (char *var); int cfg_get_int_with_result (char *cfg, char *var, int *result); int cfg_get_int (char *cfg, char *var); int cfg_put_int (int fh, int value, char *var); -int cfg_get_color (char *cfg, char *var, int *r, int *g, int *b); -int cfg_put_color (int fh, int r, int g, int b, char *var); +int cfg_get_color (char *cfg, char *var, guint16 *r, guint16 *g, guint16 *b); +int cfg_put_color (int fh, guint16 r, guint16 g, guint16 b, char *var); char *get_xdir (void); int check_config_dir (void); void load_default_config (void); @@ -48,7 +48,7 @@ void list_loadconf (char *file, GSList ** list, char *defaultconf); int list_delentry (GSList ** list, char *name); void list_addentry (GSList ** list, char *cmd, char *name); int cmd_set (session *sess, char *tbuf, char *word[], char *word_eol[]); -int hexchat_open_file (char *file, int flags, int mode, int xof_flags); +int hexchat_open_file (const char *file, int flags, int mode, int xof_flags); FILE *hexchat_fopen_file (const char *file, const char *mode, int xof_flags); #define XOF_DOMODE 1 diff --git a/src/common/chanopt.c b/src/common/chanopt.c index 820a31fb..7bd66b4a 100644 --- a/src/common/chanopt.c +++ b/src/common/chanopt.c @@ -119,7 +119,7 @@ chanopt_command (session *sess, char *tbuf, char *word[], char *word_eol[]) if (!quiet) PrintTextf (sess, "\002Network\002: %s \002Channel\002: %s\n", sess->server->network ? server_get_network (sess->server, TRUE) : _("<none>"), - sess->channel[0] ? sess->channel : _("<none>")); + sess->session_name[0] ? sess->session_name : _("<none>")); while (i < sizeof (chanopt) / sizeof (channel_options)) { @@ -208,7 +208,7 @@ chanopt_find (char *network, char *channel, gboolean add_new) return NULL; /* allocate a new one */ - co = g_malloc0 (sizeof (chanopt_in_memory)); + co = g_new0 (chanopt_in_memory, 1); co->channel = g_strdup (channel); co->network = g_strdup (network); @@ -298,7 +298,7 @@ chanopt_load (session *sess) chanopt_in_memory *co; char *network; - if (sess->channel[0] == 0) + if (sess->session_name[0] == 0) return; network = server_get_network (sess->server, FALSE); @@ -311,7 +311,7 @@ chanopt_load (session *sess) chanopt_load_all (); } - co = chanopt_find (network, sess->channel, FALSE); + co = chanopt_find (network, sess->session_name, FALSE); if (!co) return; @@ -334,7 +334,7 @@ chanopt_save (session *sess) chanopt_in_memory *co; char *network; - if (sess->channel[0] == 0) + if (sess->session_name[0] == 0) return; network = server_get_network (sess->server, FALSE); @@ -343,7 +343,7 @@ chanopt_save (session *sess) /* 2. reconcile sess with what we loaded from disk */ - co = chanopt_find (network, sess->channel, TRUE); + co = chanopt_find (network, sess->session_name, TRUE); i = 0; while (i < sizeof (chanopt) / sizeof (channel_options)) @@ -368,10 +368,10 @@ chanopt_save_one_channel (chanopt_in_memory *co, int fh) char buf[256]; guint8 val; - snprintf (buf, sizeof (buf), "%s = %s\n", "network", co->network); + g_snprintf (buf, sizeof (buf), "%s = %s\n", "network", co->network); write (fh, buf, strlen (buf)); - snprintf (buf, sizeof (buf), "%s = %s\n", "channel", co->channel); + g_snprintf (buf, sizeof (buf), "%s = %s\n", "channel", co->channel); write (fh, buf, strlen (buf)); i = 0; @@ -380,7 +380,7 @@ chanopt_save_one_channel (chanopt_in_memory *co, int fh) val = G_STRUCT_MEMBER (guint8, co, chanopt[i].offset); if (val != SET_DEFAULT) { - snprintf (buf, sizeof (buf), "%s = %d\n", chanopt[i].name, val); + g_snprintf (buf, sizeof (buf), "%s = %d\n", chanopt[i].name, val); write (fh, buf, strlen (buf)); } i++; diff --git a/src/common/common.vcxproj b/src/common/common.vcxproj index 02449340..28a4da11 100644 --- a/src/common/common.vcxproj +++ b/src/common/common.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>StaticLibrary</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -20,16 +21,15 @@ <ClInclude Include="dcc.h" /> <ClInclude Include="fe.h" /> <ClInclude Include="history.h" /> - <ClInclude Include="identd.h" /> <ClInclude Include="ignore.h" /> <ClInclude Include="inbound.h" /> <ClInclude Include="inet.h" /> - <ClInclude Include="marshal.h" /> + <ClInclude Include="$(HexChatLib)marshal.h" /> <ClInclude Include="modes.h" /> - <ClInclude Include="msproxy.h" /> <ClInclude Include="network.h" /> <ClInclude Include="notify.h" /> <ClInclude Include="outbound.h" /> + <ClInclude Include="plugin-identd.h" /> <ClInclude Include="plugin-timer.h" /> <ClInclude Include="plugin.h" /> <ClInclude Include="proto-irc.h" /> @@ -37,8 +37,8 @@ <ClInclude Include="servlist.h" /> <ClInclude Include="ssl.h" /> <ClInclude Include="text.h" /> - <ClInclude Include="textenums.h" /> - <ClInclude Include="textevents.h" /> + <ClInclude Include="$(HexChatLib)textenums.h" /> + <ClInclude Include="$(HexChatLib)textevents.h" /> <ClInclude Include="tree.h" /> <ClInclude Include="typedef.h" /> <ClInclude Include="url.h" /> @@ -54,12 +54,11 @@ <ClCompile Include="ctcp.c" /> <ClCompile Include="dcc.c" /> <ClCompile Include="history.c" /> - <ClCompile Include="identd.c" /> + <ClCompile Include="plugin-identd.c" /> <ClCompile Include="ignore.c" /> <ClCompile Include="inbound.c" /> - <ClCompile Include="marshal.c" /> + <ClCompile Include="$(HexChatLib)marshal.c" /> <ClCompile Include="modes.c" /> - <ClCompile Include="msproxy.c" /> <ClCompile Include="network.c" /> <ClCompile Include="notify.c" /> <ClCompile Include="outbound.c" /> @@ -78,7 +77,7 @@ </ItemGroup> <ItemGroup> <None Include="..\..\win32\config.h.tt" /> - <ClInclude Include="..\..\config.h" /> + <ClInclude Include="$(HexChatLib)config.h" /> </ItemGroup> <PropertyGroup Label="Globals"> <ProjectGuid>{87554B59-006C-4D94-9714-897B27067BA3}</ProjectGuid> @@ -86,85 +85,36 @@ <RootNamespace>common</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>StaticLibrary</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\hexchat.props" /> + <PropertyGroup> + <OutDir>$(HexChatLib)</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(SolutionDir)..;$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>$(HexChatLib);$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> - <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_LIB;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(SolutionDir)..;$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>$(HexChatLib);$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <DisableSpecificWarnings>4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> </ClCompile> - <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - </Link> </ItemDefinitionGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> <ItemDefinitionGroup> <PreBuildEvent> <Command><![CDATA[ SET SOLUTIONDIR=$(SolutionDir)..\ -powershell -File "$(SolutionDir)..\win32\version-template.ps1" "$(SolutionDir)..\win32\config.h.tt" "$(SolutionDir)..\config.h" -"$(DepsRoot)\bin\glib-genmarshal.exe" --prefix=_hexchat_marshal --header "$(ProjectDir)marshalers.list" > "$(ProjectDir)marshal.h" -"$(DepsRoot)\bin\glib-genmarshal.exe" --prefix=_hexchat_marshal --body "$(ProjectDir)marshalers.list" > "$(ProjectDir)marshal.c" +"$(HexChatLib)make-te.exe" < "$(ProjectDir)textevents.in" > "$(HexChatLib)textevents.h" 2> "$(HexChatLib)textenums.h" +powershell -File "$(SolutionDir)..\win32\version-template.ps1" "$(SolutionDir)..\win32\config.h.tt" "$(HexChatLib)config.h" +"$(DepsRoot)\bin\glib-genmarshal.exe" --prefix=_hexchat_marshal --header "$(ProjectDir)marshalers.list" > "$(HexChatLib)marshal.h" +"$(DepsRoot)\bin\glib-genmarshal.exe" --prefix=_hexchat_marshal --body "$(ProjectDir)marshalers.list" > "$(HexChatLib)marshal.c" ]]></Command> </PreBuildEvent> </ItemDefinitionGroup> -</Project> \ No newline at end of file +</Project> diff --git a/src/common/common.vcxproj.filters b/src/common/common.vcxproj.filters index c2d0ce5d..79e64cb4 100644 --- a/src/common/common.vcxproj.filters +++ b/src/common/common.vcxproj.filters @@ -29,9 +29,6 @@ <ClInclude Include="history.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="identd.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="ignore.h"> <Filter>Header Files</Filter> </ClInclude> @@ -44,9 +41,6 @@ <ClInclude Include="modes.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="msproxy.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="network.h"> <Filter>Header Files</Filter> </ClInclude> @@ -77,10 +71,10 @@ <ClInclude Include="text.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="textenums.h"> + <ClInclude Include="$(HexChatLib)textenums.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="textevents.h"> + <ClInclude Include="$(HexChatLib)textevents.h"> <Filter>Header Files</Filter> </ClInclude> <ClInclude Include="tree.h"> @@ -104,13 +98,16 @@ <ClInclude Include="hexchat-plugin.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="..\..\config.h"> + <ClInclude Include="$(HexChatLib)config.h"> <Filter>Header Files</Filter> </ClInclude> <ClInclude Include="typedef.h"> <Filter>Header Files</Filter> </ClInclude> - <ClInclude Include="marshal.h"> + <ClInclude Include="$(HexChatLib)marshal.h"> + <Filter>Header Files</Filter> + </ClInclude> + <ClInclude Include="plugin-identd.h"> <Filter>Header Files</Filter> </ClInclude> </ItemGroup> @@ -130,9 +127,6 @@ <ClCompile Include="history.c"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="identd.c"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="ignore.c"> <Filter>Source Files</Filter> </ClCompile> @@ -142,9 +136,6 @@ <ClCompile Include="modes.c"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="msproxy.c"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="network.c"> <Filter>Source Files</Filter> </ClCompile> @@ -190,11 +181,14 @@ <ClCompile Include="hexchat.c"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="marshal.c"> + <ClCompile Include="$(HexChatLib)marshal.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="plugin-identd.c"> <Filter>Source Files</Filter> </ClCompile> </ItemGroup> <ItemGroup> <None Include="..\..\win32\config.h.tt" /> </ItemGroup> -</Project> \ No newline at end of file +</Project> diff --git a/src/common/ctcp.c b/src/common/ctcp.c index b4fb55b7..bf0a8e7f 100644 --- a/src/common/ctcp.c +++ b/src/common/ctcp.c @@ -44,12 +44,12 @@ ctcp_reply (session *sess, char *nick, char *word[], char *word_eol[], { char tbuf[4096]; /* can receive 2048 from IRC, so this is enough */ - conf = strdup (conf); + conf = g_strdup (conf); /* process %C %B etc */ check_special_chars (conf, TRUE); auto_insert (tbuf, sizeof (tbuf), conf, word, word_eol, "", "", word_eol[5], server_get_network (sess->server, TRUE), "", "", nick, ""); - free (conf); + g_free (conf); handle_command (sess, tbuf, FALSE); } @@ -139,10 +139,10 @@ ctcp_handle (session *sess, char *to, char *nick, char *ip, if (!g_ascii_strcasecmp (msg, "VERSION") && !prefs.hex_irc_hide_version) { #ifdef WIN32 - snprintf (outbuf, sizeof (outbuf), "VERSION HexChat "PACKAGE_VERSION" [x%d] / %s", + g_snprintf (outbuf, sizeof (outbuf), "VERSION HexChat "PACKAGE_VERSION" [x%d] / %s", get_cpu_arch (), get_sys_str (1)); #else - snprintf (outbuf, sizeof (outbuf), "VERSION HexChat "PACKAGE_VERSION" / %s", + g_snprintf (outbuf, sizeof (outbuf), "VERSION HexChat "PACKAGE_VERSION" / %s", get_sys_str (1)); #endif serv->p_nctcp (serv, nick, outbuf); diff --git a/src/common/dbus/dbus-client.c b/src/common/dbus/dbus-client.c index e507883d..bbbe10e8 100644 --- a/src/common/dbus/dbus-client.c +++ b/src/common/dbus/dbus-client.c @@ -19,6 +19,8 @@ * xclaesse@gmail.com */ +#include "config.h" + #define GLIB_DISABLE_DEPRECATION_WARNINGS #include <dbus/dbus-glib.h> #include "dbus-client.h" @@ -91,7 +93,7 @@ hexchat_remote (void) g_object_unref (dbus); if (!hexchat_running) { - //dbus_g_connection_unref (connection); + /* dbus_g_connection_unref (connection); */ return; } diff --git a/src/common/dbus/dbus-plugin.c b/src/common/dbus/dbus-plugin.c index ee8accfe..1afd9ef0 100644 --- a/src/common/dbus/dbus-plugin.c +++ b/src/common/dbus/dbus-plugin.c @@ -26,6 +26,7 @@ #include <dbus/dbus-glib-lowlevel.h> #include <glib/gi18n.h> #include "hexchat-plugin.h" +#include "dbus-plugin.h" #define PNAME _("remote access") #define PDESC _("plugin for remote access using DBUS") @@ -365,6 +366,7 @@ remote_object_connect (RemoteObject *obj, static guint count = 0; char *sender, *path; RemoteObject *remote_object; + gchar count_buffer[15]; sender = dbus_g_method_get_sender (context); remote_object = g_hash_table_lookup (clients, sender); @@ -373,7 +375,8 @@ remote_object_connect (RemoteObject *obj, g_free (sender); return TRUE; } - path = g_build_filename (DBUS_OBJECT_PATH, count++, NULL); + g_snprintf(count_buffer, sizeof(count_buffer), "%u", count++); + path = g_build_filename (DBUS_OBJECT_PATH, count_buffer, NULL); remote_object = g_object_new (REMOTE_TYPE_OBJECT, NULL); remote_object->dbus_path = path; remote_object->filename = g_path_get_basename (filename); diff --git a/src/common/dbus/example.c b/src/common/dbus/example.c index c3ad4ff3..0228b884 100644 --- a/src/common/dbus/example.c +++ b/src/common/dbus/example.c @@ -33,7 +33,7 @@ guint command_id; guint server_id; static void -write_error (char *message, +write_error (const char *message, GError **error) { if (error == NULL || *error == NULL) { diff --git a/src/common/dcc.c b/src/common/dcc.c index 169a0f76..881bcf78 100644 --- a/src/common/dcc.c +++ b/src/common/dcc.c @@ -23,8 +23,9 @@ * Jim Seymour (jseymour@LinxNet.com) */ -/* we only use 32 bits, but without this define, you get only 31! */ +/* Required to make lseek use off64_t, but doesn't work on Windows */ #define _FILE_OFFSET_BITS 64 + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -57,13 +58,9 @@ #include "url.h" #include "hexchatc.h" -#ifdef USE_DCC64 -#define BIG_STR_TO_INT(x) strtoull(x,NULL,10) +/* Setting _FILE_OFFSET_BITS to 64 doesn't change lseek to use off64_t on Windows, so override lseek to the version that does */ #ifdef WIN32 -#define stat _stat64 -#endif -#else -#define BIG_STR_TO_INT(x) strtoul(x,NULL,10) +#define lseek _lseeki64 #endif static char *dcctypes[] = { "SEND", "RECV", "CHAT", "CHAT" }; @@ -78,7 +75,7 @@ struct dccstat_info dccstat[] = { }; static int dcc_global_throttle; /* 0x1 = sends, 0x2 = gets */ -/*static*/ int dcc_sendcpssum, dcc_getcpssum; +static gint64 dcc_sendcpssum, dcc_getcpssum; static struct DCC *new_dcc (void); static void dcc_close (struct DCC *dcc, int dccstat, int destroy); @@ -127,11 +124,12 @@ static void dcc_calc_cps (struct DCC *dcc) { GTimeVal now; - int oldcps; + gint64 oldcps; double timediff, startdiff; int glob_throttle_bit, wasthrottled; - int *cpssum, glob_limit; - DCC_SIZE pos, posdiff; + gint64 *cpssum; + int glob_limit; + goffset pos, posdiff; g_get_current_time (&now); @@ -169,8 +167,7 @@ dcc_calc_cps (struct DCC *dcc) posdiff = pos - dcc->lastcpspos; oldcps = dcc->cps; - dcc->cps = ((double) posdiff / timediff) * (timediff / startdiff) + - (double) dcc->cps * (1.0 - (timediff / startdiff)); + dcc->cps = (gint64) ((posdiff / timediff) * (timediff / startdiff) + dcc->cps * (1.0 - (timediff / startdiff))); *cpssum += dcc->cps - oldcps; } @@ -312,7 +309,7 @@ dcc_lookup_proxy (char *host, struct sockaddr_in *addr) memcpy (&addr->sin_addr, &cache_addr, 4); return TRUE; } - free (cache_host); + g_free (cache_host); cache_host = NULL; } @@ -321,7 +318,7 @@ dcc_lookup_proxy (char *host, struct sockaddr_in *addr) { memcpy (&addr->sin_addr, h->h_addr, 4); memcpy (&cache_addr, h->h_addr, 4); - cache_host = strdup (host); + cache_host = g_strdup (host); /* cppcheck-suppress memleak */ return TRUE; } @@ -409,7 +406,7 @@ dcc_close (struct DCC *dcc, int dccstat, int destroy) dcc->dccstat = dccstat; if (dcc->dccchat) { - free (dcc->dccchat); + g_free (dcc->dccchat); dcc->dccchat = NULL; } @@ -417,14 +414,11 @@ dcc_close (struct DCC *dcc, int dccstat, int destroy) { dcc_list = g_slist_remove (dcc_list, dcc); fe_dcc_remove (dcc); - if (dcc->proxy) - free (dcc->proxy); - if (dcc->file) - free (dcc->file); - if (dcc->destfile) - g_free (dcc->destfile); - free (dcc->nick); - free (dcc); + g_free (dcc->proxy); + g_free (dcc->file); + g_free (dcc->destfile); + g_free (dcc->nick); + g_free (dcc); return; } @@ -493,14 +487,13 @@ dcc_write_chat (char *nick, char *text) if (dcc && dcc->dccstat == STAT_ACTIVE) { len = strlen (text); - tcp_send_real (NULL, dcc->sok, dcc->serv->encoding, dcc->serv->using_irc, - text, len); + tcp_send_real (NULL, dcc->sok, dcc->serv->write_converter, text, len); send (dcc->sok, "\n", 1, 0); dcc->size += len; fe_dcc_update (dcc); return dcc; } - return 0; + return NULL; } /* returns: 0 - ok @@ -512,36 +505,11 @@ dcc_chat_line (struct DCC *dcc, char *line) session *sess; char *word[PDIWORDS]; char *po; - char *utf; - char *conv; int ret, i; - int len; - gsize utf_len; char portbuf[32]; message_tags_data no_tags = MESSAGE_TAGS_DATA_INIT; - len = strlen (line); - if (dcc->serv->using_cp1255) - len++; /* include the NUL terminator */ - - if (dcc->serv->using_irc) /* using "IRC" encoding (CP1252/UTF-8 hybrid) */ - utf = NULL; - else if (dcc->serv->encoding == NULL) /* system */ - utf = g_locale_to_utf8 (line, len, NULL, &utf_len, NULL); - else - utf = g_convert (line, len, "UTF-8", dcc->serv->encoding, 0, &utf_len, 0); - - if (utf) - { - line = utf; - len = utf_len; - } - - if (dcc->serv->using_cp1255 && len > 0) - len--; - - /* we really need valid UTF-8 now */ - conv = text_validate (&line, &len); + line = text_convert_invalid (line, -1, dcc->serv->read_converter, unicode_fallback_string, NULL); sess = find_dialog (dcc->serv, dcc->nick); if (!sess) @@ -562,24 +530,18 @@ dcc_chat_line (struct DCC *dcc, char *line) /* did the plugin close it? */ if (!g_slist_find (dcc_list, dcc)) { - if (utf) - g_free (utf); - if (conv) - g_free (conv); + g_free (line); return 1; } /* did the plugin eat the event? */ if (ret) { - if (utf) - g_free (utf); - if (conv) - g_free (conv); + g_free (line); return 0; } - url_check_line (line, len); + url_check_line (line); if (line[0] == 1 && !g_ascii_strncasecmp (line + 1, "ACTION", 6)) { @@ -592,10 +554,7 @@ dcc_chat_line (struct DCC *dcc, char *line) { inbound_privmsg (dcc->serv, dcc->nick, "", line, FALSE, &no_tags); } - if (utf) - g_free (utf); - if (conv) - g_free (conv); + g_free (line); return 0; } @@ -700,20 +659,26 @@ dcc_read (GIOChannel *source, GIOCondition condition, struct DCC *dcc) if (dcc->resumable) { - dcc->fp = g_open (dcc->destfile, O_WRONLY | O_APPEND | OFLAGS, 0); + gchar *filename_fs = g_filename_from_utf8(dcc->destfile, -1, NULL, NULL, NULL); + dcc->fp = g_open(dcc->destfile, O_WRONLY | O_APPEND | OFLAGS, 0); + g_free (filename_fs); + dcc->pos = dcc->resumable; dcc->ack = dcc->resumable; - } else + } + else { + gchar *filename_fs; + if (g_access (dcc->destfile, F_OK) == 0) { n = 0; do { n++; - snprintf (buf, sizeof (buf), "%s.%d", dcc->destfile, n); + g_snprintf (buf, sizeof (buf), "%s.%d", dcc->destfile, n); } - while (access (buf, F_OK) == 0); + while (g_access (buf, F_OK) == 0); old = dcc->destfile; dcc->destfile = g_strdup (buf); @@ -722,9 +687,10 @@ dcc_read (GIOChannel *source, GIOCondition condition, struct DCC *dcc) old, dcc->destfile, NULL, NULL, 0); g_free (old); } - dcc->fp = - g_open (dcc->destfile, OFLAGS | O_TRUNC | O_WRONLY | O_CREAT, - prefs.hex_dcc_permissions); + + filename_fs = g_filename_from_utf8 (dcc->destfile, -1, NULL, NULL, NULL); + dcc->fp = g_open (filename_fs, OFLAGS | O_TRUNC | O_WRONLY | O_CREAT, prefs.hex_dcc_permissions); + g_free (filename_fs); } } if (dcc->fp == -1) @@ -792,7 +758,7 @@ dcc_read (GIOChannel *source, GIOCondition condition, struct DCC *dcc) dcc_close (dcc, STAT_DONE, FALSE); dcc_calc_average_cps (dcc); /* this must be done _after_ dcc_close, or dcc_remove_from_sum will see the wrong value in dcc->cps */ /* cppcheck-suppress deallocuse */ - sprintf (buf, "%d", dcc->cps); + sprintf (buf, "%" G_GINT64_FORMAT, dcc->cps); EMIT_SIGNAL (XP_TE_DCCRECVCOMP, dcc->serv->front_session, dcc->file, dcc->destfile, dcc->nick, buf, 0); return TRUE; @@ -870,7 +836,7 @@ dcc_connect_finished (GIOChannel *source, GIOCondition condition, struct DCC *dc return TRUE; dcc->dccstat = STAT_ACTIVE; - snprintf (host, sizeof host, "%s:%d", net_ip (dcc->addr), dcc->port); + g_snprintf (host, sizeof host, "%s:%d", net_ip (dcc->addr), dcc->port); switch (dcc->type) { @@ -893,8 +859,7 @@ dcc_connect_finished (GIOChannel *source, GIOCondition condition, struct DCC *dc dcc_open_query (dcc->serv, dcc->nick); case TYPE_CHATRECV: /* normal chat */ dcc->iotag = fe_input_add (dcc->sok, FIA_READ|FIA_EX, dcc_read_chat, dcc); - dcc->dccchat = malloc (sizeof (struct dcc_chat)); - dcc->dccchat->pos = 0; + dcc->dccchat = g_new0 (struct dcc_chat, 1); EMIT_SIGNAL (XP_TE_DCCCONCHAT, dcc->serv->front_session, dcc->nick, host, NULL, NULL, 0); break; @@ -990,7 +955,7 @@ dcc_wingate_proxy_traverse (GIOChannel *source, GIOCondition condition, struct D struct proxy_state *proxy = dcc->proxy; if (proxy->phase == 0) { - proxy->buffersize = snprintf ((char*) proxy->buffer, MAX_PROXY_BUFFER, + proxy->buffersize = g_snprintf ((char*) proxy->buffer, MAX_PROXY_BUFFER, "%s %d\r\n", net_ip(dcc->addr), dcc->port); proxy->bufferused = 0; @@ -1288,16 +1253,16 @@ dcc_http_proxy_traverse (GIOChannel *source, GIOCondition condition, struct DCC char auth_data2[68]; int n, n2; - n = snprintf (buf, sizeof (buf), "CONNECT %s:%d HTTP/1.0\r\n", + n = g_snprintf (buf, sizeof (buf), "CONNECT %s:%d HTTP/1.0\r\n", net_ip(dcc->addr), dcc->port); if (prefs.hex_net_proxy_auth) { - n2 = snprintf (auth_data2, sizeof (auth_data2), "%s:%s", + n2 = g_snprintf (auth_data2, sizeof (auth_data2), "%s:%s", prefs.hex_net_proxy_user, prefs.hex_net_proxy_pass); base64_encode (auth_data, auth_data2, n2); - n += snprintf (buf+n, sizeof (buf)-n, "Proxy-Authorization: Basic %s\r\n", auth_data); + n += g_snprintf (buf+n, sizeof (buf)-n, "Proxy-Authorization: Basic %s\r\n", auth_data); } - n += snprintf (buf+n, sizeof (buf)-n, "\r\n"); + n += g_snprintf (buf+n, sizeof (buf)-n, "\r\n"); proxy->buffersize = n; proxy->bufferused = 0; memcpy (proxy->buffer, buf, proxy->buffersize); @@ -1373,14 +1338,7 @@ dcc_proxy_connect (GIOChannel *source, GIOCondition condition, struct DCC *dcc) if (!dcc_did_connect (source, condition, dcc)) return TRUE; - dcc->proxy = malloc (sizeof (struct proxy_state)); - if (!dcc->proxy) - { - dcc->dccstat = STAT_FAILED; - fe_dcc_update (dcc); - return TRUE; - } - memset (dcc->proxy, 0, sizeof (struct proxy_state)); + dcc->proxy = g_new0 (struct proxy_state, 1); switch (prefs.hex_net_proxy_type) { @@ -1415,12 +1373,12 @@ dcc_connect (struct DCC *dcc) } /* possible problems with filenames containing spaces? */ if (dcc->type == TYPE_RECV) - snprintf (tbuf, sizeof (tbuf), strchr (dcc->file, ' ') ? - "DCC SEND \"%s\" %u %d %"DCC_SFMT" %d" : - "DCC SEND %s %u %d %"DCC_SFMT" %d", dcc->file, + g_snprintf (tbuf, sizeof (tbuf), strchr (dcc->file, ' ') ? + "DCC SEND \"%s\" %u %d %" G_GUINT64_FORMAT " %d" : + "DCC SEND %s %u %d %" G_GUINT64_FORMAT " %d", dcc->file, dcc->addr, dcc->port, dcc->size, dcc->pasvid); else - snprintf (tbuf, sizeof (tbuf), "DCC CHAT chat %u %d %d", + g_snprintf (tbuf, sizeof (tbuf), "DCC CHAT chat %u %d %d", dcc->addr, dcc->port, dcc->pasvid); dcc->serv->p_ctcp (dcc->serv, dcc->nick, tbuf); } @@ -1463,15 +1421,13 @@ dcc_send_data (GIOChannel *source, GIOCondition condition, struct DCC *dcc) if (!dcc->fastsend) { - if (dcc->ack < dcc->pos) + if (dcc->ack < (dcc->pos & 0xFFFFFFFF)) return TRUE; } else if (!dcc->wiotag) dcc->wiotag = fe_input_add (sok, FIA_WRITE, dcc_send_data, dcc); - buf = malloc (prefs.hex_dcc_blocksize); - if (!buf) - return TRUE; + buf = g_malloc (prefs.hex_dcc_blocksize); lseek (dcc->fp, dcc->pos, SEEK_SET); len = read (dcc->fp, buf, prefs.hex_dcc_blocksize); @@ -1482,7 +1438,7 @@ dcc_send_data (GIOChannel *source, GIOCondition condition, struct DCC *dcc) if (sent < 0 && !(would_block ())) { abortit: - free (buf); + g_free (buf); EMIT_SIGNAL (XP_TE_DCCSENDFAIL, dcc->serv->front_session, file_part (dcc->file), dcc->nick, errorstring (sock_error ()), NULL, 0); @@ -1506,7 +1462,7 @@ abortit: } } - free (buf); + g_free (buf); return TRUE; } @@ -1538,7 +1494,7 @@ dcc_handle_new_ack (struct DCC *dcc) dcc_close (dcc, STAT_DONE, FALSE); dcc_calc_average_cps (dcc); /* this must be done _after_ dcc_close, or dcc_remove_from_sum will see the wrong value in dcc->cps */ /* cppcheck-suppress deallocuse */ - sprintf (buf, "%d", dcc->cps); + sprintf (buf, "%" G_GINT64_FORMAT, dcc->cps); EMIT_SIGNAL (XP_TE_DCCSENDCOMP, dcc->serv->front_session, file_part (dcc->file), dcc->nick, buf, NULL, 0); done = TRUE; @@ -1548,12 +1504,10 @@ dcc_handle_new_ack (struct DCC *dcc) dcc_send_data (NULL, 0, (gpointer)dcc); } -#ifdef USE_DCC64 /* take the top 32 of "bytes send" and bottom 32 of "ack" */ dcc->ack = (dcc->pos & G_GINT64_CONSTANT (0xffffffff00000000)) | (dcc->ack & 0xffffffff); /* dcc->ack is only used for CPS and PERCENTAGE calcs from now on... */ -#endif return done; } @@ -1622,7 +1576,7 @@ dcc_accept (GIOChannel *source, GIOCondition condition, struct DCC *dcc) dcc->lasttime = dcc->starttime = time (0); dcc->fastsend = prefs.hex_dcc_fast_send; - snprintf (host, sizeof (host), "%s:%d", net_ip (dcc->addr), dcc->port); + g_snprintf (host, sizeof (host), "%s:%d", net_ip (dcc->addr), dcc->port); switch (dcc->type) { @@ -1638,8 +1592,7 @@ dcc_accept (GIOChannel *source, GIOCondition condition, struct DCC *dcc) case TYPE_CHATSEND: dcc_open_query (dcc->serv, dcc->nick); dcc->iotag = fe_input_add (dcc->sok, FIA_READ|FIA_EX, dcc_read_chat, dcc); - dcc->dccchat = malloc (sizeof (struct dcc_chat)); - dcc->dccchat->pos = 0; + dcc->dccchat = g_new0 (struct dcc_chat, 1); EMIT_SIGNAL (XP_TE_DCCCONCHAT, dcc->serv->front_session, dcc->nick, host, NULL, NULL, 0); break; @@ -1762,7 +1715,7 @@ dcc_listen_init (struct DCC *dcc, session *sess) static struct session *dccsess; static char *dccto; /* lame!! */ -static int dccmaxcps; +static gint64 dccmaxcps; static int recursive = FALSE; static void @@ -1772,21 +1725,25 @@ dcc_send_wild (char *file) } void -dcc_send (struct session *sess, char *to, char *file, int maxcps, int passive) +dcc_send (struct session *sess, char *to, char *filename, gint64 maxcps, int passive) { char outbuf[512]; - GStatBuf st; + GFileInfo *file_info; + GFile *file; struct DCC *dcc; + gchar *filename_fs; + GFileType file_type; + goffset file_size; - file = expand_homedir (file); + filename = expand_homedir (filename); - if (!recursive && (strchr (file, '*') || strchr (file, '?'))) + if (!recursive && (strchr (filename, '*') || strchr (filename, '?'))) { char path[256]; char wild[256]; - safe_strcpy (wild, file_part (file), sizeof (wild)); - path_part (file, path, sizeof (path)); + safe_strcpy (wild, file_part (filename), sizeof (wild)); + path_part (filename, path, sizeof (path)); if (path[0] != '/' || path[1] != '\0') path[strlen (path) - 1] = 0; /* remove trailing slash */ @@ -1794,7 +1751,7 @@ dcc_send (struct session *sess, char *to, char *file, int maxcps, int passive) dccto = to; dccmaxcps = maxcps; - free (file); + g_free (filename); recursive = TRUE; for_files (path, wild, dcc_send_wild); @@ -1806,91 +1763,135 @@ dcc_send (struct session *sess, char *to, char *file, int maxcps, int passive) dcc = new_dcc (); if (!dcc) { - free (file); + g_free (filename); return; } - dcc->file = file; + + dcc->file = filename; dcc->maxcps = maxcps; - if (g_stat (file, &st) != -1) + filename_fs = g_filename_from_utf8 (filename, -1, NULL, NULL, NULL); + if (filename_fs == NULL) { + PrintTextf (sess, _("Cannot access %s\n"), dcc->file); + PrintTextf (sess, "%s %d: %s\n", _("Error"), errno, errorstring (errno)); -#ifndef USE_DCC64 - if (sizeof (st.st_size) > 4 && st.st_size > 4294967295U) - { - PrintText (sess, "Cannot send files larger than 4 GB.\n"); - goto xit; - } -#endif + dcc_close (dcc, 0, TRUE); /* dcc_close will free dcc->file */ - if (!(*file_part (file)) || S_ISDIR (st.st_mode) || st.st_size < 1) - { - PrintText (sess, "Cannot send directories or empty files.\n"); - goto xit; - } + return; + } - dcc->starttime = dcc->offertime = time (0); - dcc->serv = sess->server; - dcc->dccstat = STAT_QUEUED; - dcc->size = st.st_size; - dcc->type = TYPE_SEND; - dcc->fp = g_open (file, OFLAGS | O_RDONLY, 0); - if (dcc->fp != -1) - { - if (passive || dcc_listen_init (dcc, sess)) - { - char havespaces = 0; - while (*file) - { - if (*file == ' ') - { - if (prefs.hex_dcc_send_fillspaces) - *file = '_'; - else - havespaces = 1; - } - file++; - } - dcc->nick = strdup (to); - if (prefs.hex_gui_autoopen_send) - { - if (fe_dcc_open_send_win (TRUE)) /* already open? add */ - fe_dcc_add (dcc); - } else - fe_dcc_add (dcc); + file = g_file_new_for_path (filename_fs); + if (file == NULL) + { + PrintTextf (sess, _("Cannot access %s\n"), dcc->file); + PrintTextf (sess, "%s %d: %s\n", _("Error"), errno, errorstring (errno)); - if (passive) - { - dcc->pasvid = new_id(); - snprintf (outbuf, sizeof (outbuf), (havespaces) ? - "DCC SEND \"%s\" 199 0 %" DCC_SFMT " %d" : - "DCC SEND %s 199 0 %" DCC_SFMT " %d", - file_part (dcc->file), - dcc->size, dcc->pasvid); - } - else - { - snprintf (outbuf, sizeof (outbuf), (havespaces) ? - "DCC SEND \"%s\" %u %d %"DCC_SFMT : - "DCC SEND %s %u %d %"DCC_SFMT, - file_part (dcc->file), dcc->addr, - dcc->port, dcc->size); - } - sess->server->p_ctcp (sess->server, to, outbuf); + dcc_close (dcc, 0, TRUE); /* dcc_close will free dcc->file */ - EMIT_SIGNAL (XP_TE_DCCOFFER, sess, file_part (dcc->file), - to, dcc->file, NULL, 0); - } else + g_free (filename_fs); + + return; + } + + file_info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE "," G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, NULL, NULL); + + g_object_unref (file); + + if (file_info == NULL) + { + PrintTextf (sess, _("Cannot access %s\n"), dcc->file); + PrintTextf (sess, "%s %d: %s\n", _("Error"), errno, errorstring (errno)); + + dcc_close (dcc, 0, TRUE); /* dcc_close will free dcc->file */ + + g_free (filename_fs); + + return; + } + + file_type = g_file_info_get_file_type (file_info); + file_size = g_file_info_get_size (file_info); + + g_object_unref (file_info); + + if (*file_part (filename) == '\0' || file_type == G_FILE_TYPE_DIRECTORY || file_size <= 0) + { + PrintText (sess, "Cannot send directories or empty files.\n"); + + dcc_close (dcc, 0, TRUE); /* dcc_close will free dcc->file */ + + g_free (filename_fs); + + return; + } + + dcc->starttime = dcc->offertime = time (0); + dcc->serv = sess->server; + dcc->dccstat = STAT_QUEUED; + dcc->size = file_size; + dcc->type = TYPE_SEND; + dcc->fp = g_open (filename_fs, OFLAGS | O_RDONLY, 0); + + g_free (filename_fs); + + if (dcc->fp == -1) + { + PrintText (sess, "Cannot send directories or empty files.\n"); + + dcc_close (dcc, 0, TRUE); /* dcc_close will free dcc->file */ + + return; + } + + if (passive || dcc_listen_init (dcc, sess)) + { + char havespaces = 0; + while (*filename) + { + if (*filename == ' ') { - dcc_close (dcc, 0, TRUE); + if (prefs.hex_dcc_send_fillspaces) + *filename = '_'; + else + havespaces = 1; } - return; + filename++; } + dcc->nick = g_strdup (to); + if (prefs.hex_gui_autoopen_send) + { + if (fe_dcc_open_send_win (TRUE)) /* already open? add */ + fe_dcc_add (dcc); + } else + fe_dcc_add (dcc); + + if (passive) + { + dcc->pasvid = new_id(); + g_snprintf (outbuf, sizeof (outbuf), (havespaces) ? + "DCC SEND \"%s\" 199 0 %" G_GUINT64_FORMAT " %d" : + "DCC SEND %s 199 0 %" G_GUINT64_FORMAT " %d", + file_part (dcc->file), + dcc->size, dcc->pasvid); + } + else + { + g_snprintf (outbuf, sizeof (outbuf), (havespaces) ? + "DCC SEND \"%s\" %u %d %" G_GUINT64_FORMAT : + "DCC SEND %s %u %d %" G_GUINT64_FORMAT, + file_part (dcc->file), dcc->addr, + dcc->port, dcc->size); + } + sess->server->p_ctcp (sess->server, to, outbuf); + + EMIT_SIGNAL (XP_TE_DCCOFFER, sess, file_part (dcc->file), + to, dcc->file, NULL, 0); + } + else + { + dcc_close (dcc, 0, TRUE); } - PrintTextf (sess, _("Cannot access %s\n"), dcc->file); - PrintTextf (sess, "%s %d: %s\n", _("Error"), errno, errorstring (errno)); -xit: - dcc_close (dcc, 0, TRUE); /* dcc_close will free dcc->file */ } static struct DCC * @@ -1906,7 +1907,7 @@ find_dcc_from_id (int id, int type) return dcc; list = list->next; } - return 0; + return NULL; } static struct DCC * @@ -1922,7 +1923,7 @@ find_dcc_from_port (int port, int type) return dcc; list = list->next; } - return 0; + return NULL; } struct DCC * @@ -1947,7 +1948,7 @@ find_dcc (char *nick, char *file, int type) } list = list->next; } - return 0; + return NULL; } /* called when we receive a NICK change from server */ @@ -1965,9 +1966,8 @@ dcc_change_nick (struct server *serv, char *oldnick, char *newnick) { if (!serv->p_cmp (dcc->nick, oldnick)) { - if (dcc->nick) - free (dcc->nick); - dcc->nick = strdup (newnick); + g_free (dcc->nick); + dcc->nick = g_strdup (newnick); } } list = list->next; @@ -1976,68 +1976,153 @@ dcc_change_nick (struct server *serv, char *oldnick, char *newnick) /* is the destination file the same? new_dcc is not opened yet */ -static int +static gboolean is_same_file (struct DCC *dcc, struct DCC *new_dcc) { -#ifndef WIN32 - GStatBuf st_a, st_b; -#endif + gboolean result = FALSE; + gchar *filename_fs = NULL, *new_filename_fs = NULL; + GFile *file = NULL, *new_file = NULL; + GFileInfo *file_info = NULL, *new_file_info = NULL; + char *file_id = NULL, *new_file_id = NULL; + char *filesystem_id = NULL, *new_filesystem_id = NULL; /* if it's the same filename, must be same */ if (strcmp (dcc->destfile, new_dcc->destfile) == 0) + { return TRUE; + } - /* now handle case-insensitive Filesystems: HFS+, FAT */ -#ifdef WIN32 - /* warning no win32 implementation - behaviour may be unreliable */ -#else - /* this fstat() shouldn't really fail */ - if ((dcc->fp == -1 ? g_stat (dcc->destfile, &st_a) : fstat (dcc->fp, &st_a)) == -1) - return FALSE; - if (g_stat (new_dcc->destfile, &st_b) == -1) - return FALSE; + filename_fs = g_filename_from_utf8 (dcc->file, -1, NULL, NULL, NULL); + if (filename_fs == NULL) + { + goto exit; + } - /* same inode, same device, same file! */ - if (st_a.st_ino == st_b.st_ino && - st_a.st_dev == st_b.st_dev) - return TRUE; -#endif + new_filename_fs = g_filename_from_utf8 (new_dcc->file, -1, NULL, NULL, NULL); + if (new_filename_fs == NULL) + { + goto exit; + } - return FALSE; + file = g_file_new_for_path (filename_fs); + if (file == NULL) + { + goto exit; + } + + new_file = g_file_new_for_path (new_filename_fs); + if (new_file == NULL) + { + goto exit; + } + + file_info = g_file_query_info (file, G_FILE_ATTRIBUTE_ID_FILE "," G_FILE_ATTRIBUTE_ID_FILESYSTEM, G_FILE_QUERY_INFO_NONE, NULL, NULL); + if (file_info == NULL) + { + goto exit; + } + + new_file_info = g_file_query_info (new_file, G_FILE_ATTRIBUTE_ID_FILE "," G_FILE_ATTRIBUTE_ID_FILESYSTEM, G_FILE_QUERY_INFO_NONE, NULL, NULL); + if (new_file_info == NULL) + { + goto exit; + } + + file_id = g_file_info_get_attribute_as_string (file_info, G_FILE_ATTRIBUTE_ID_FILE); + new_file_id = g_file_info_get_attribute_as_string (new_file_info, G_FILE_ATTRIBUTE_ID_FILE); + + filesystem_id = g_file_info_get_attribute_as_string (file_info, G_FILE_ATTRIBUTE_ID_FILE); + new_filesystem_id = g_file_info_get_attribute_as_string (new_file_info, G_FILE_ATTRIBUTE_ID_FILE); + + if (file_id != NULL && new_file_id != NULL && filesystem_id != NULL && new_filesystem_id != NULL && strcmp (file_id, new_file_id) == 0 && strcmp (filesystem_id, new_filesystem_id) == 0) + { + result = TRUE; + } + +exit: + g_free (filename_fs); + g_free (new_filename_fs); + + if (file != NULL) + { + g_object_unref (file); + } + + if (new_file != NULL) + { + g_object_unref (new_file); + } + + if (file_info != NULL) + { + g_object_unref (file_info); + } + + if (new_file_info != NULL) + { + g_object_unref (new_file_info); + } + + g_free (file_id); + g_free (new_file_id); + g_free(filesystem_id); + g_free(new_filesystem_id); + + return result; } -static int -is_resumable (struct DCC *dcc) +static void +update_is_resumable (struct DCC *dcc) { + gchar *filename_fs = g_filename_from_utf8 (dcc->destfile, -1, NULL, NULL, NULL); + dcc->resumable = 0; /* Check the file size */ - if (g_access (dcc->destfile, W_OK) == 0) + if (filename_fs != NULL && g_access(filename_fs, W_OK) == 0) { - GStatBuf st; - - if (g_stat (dcc->destfile, &st) != -1) + GFile *file = g_file_new_for_path (filename_fs); + if (file != NULL) { - if (st.st_size < dcc->size) + GFileInfo *file_info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE "," G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_QUERY_INFO_NONE, NULL, NULL); + + if (file_info != NULL) { - dcc->resumable = st.st_size; - dcc->pos = st.st_size; + goffset file_size_offset = g_file_info_get_size (file_info); + guint64 file_size = (file_size_offset >= 0) ? (guint64) file_size_offset : 0; + if (file_size < dcc->size) + { + dcc->resumable = file_size; + dcc->pos = file_size; + } + else + { + dcc->resume_error = 2; + } + + g_object_unref (file_info); } else - dcc->resume_error = 2; - } else + { + dcc->resume_errno = errno; + dcc->resume_error = 1; + } + + g_object_unref(file); + } + else { dcc->resume_errno = errno; dcc->resume_error = 1; } - } else + } + else { dcc->resume_errno = errno; dcc->resume_error = 1; } /* Now verify that this DCC is not already in progress from someone else */ - if (dcc->resumable) { GSList *list = dcc_list; @@ -2059,8 +2144,6 @@ is_resumable (struct DCC *dcc) list = list->next; } } - - return dcc->resumable; } void @@ -2100,7 +2183,7 @@ dcc_get_with_destfile (struct DCC *dcc, char *file) dcc->destfile = g_strdup (file); /* utf-8 */ /* since destfile changed, must check resumability again */ - is_resumable (dcc); + update_is_resumable (dcc); dcc_get (dcc); } @@ -2133,14 +2216,11 @@ dcc_get_nick (struct session *sess, char *nick) static struct DCC * new_dcc (void) { - struct DCC *dcc = malloc (sizeof (struct DCC)); - if (!dcc) - return 0; - memset (dcc, 0, sizeof (struct DCC)); + struct DCC *dcc = g_new0 (struct DCC, 1); dcc->sok = -1; dcc->fp = -1; dcc_list = g_slist_prepend (dcc_list, dcc); - return (dcc); + return dcc; } void @@ -2187,7 +2267,7 @@ dcc_chat (struct session *sess, char *nick, int passive) dcc->serv = sess->server; dcc->dccstat = STAT_QUEUED; dcc->type = TYPE_CHATSEND; - dcc->nick = strdup (nick); + dcc->nick = g_strdup (nick); if (passive || dcc_listen_init (dcc, sess)) { if (prefs.hex_gui_autoopen_chat) @@ -2200,11 +2280,11 @@ dcc_chat (struct session *sess, char *nick, int passive) if (passive) { dcc->pasvid = new_id (); - snprintf (outbuf, sizeof (outbuf), "DCC CHAT chat 199 %d %d", + g_snprintf (outbuf, sizeof (outbuf), "DCC CHAT chat 199 %d %d", dcc->port, dcc->pasvid); } else { - snprintf (outbuf, sizeof (outbuf), "DCC CHAT chat %u %d", + g_snprintf (outbuf, sizeof (outbuf), "DCC CHAT chat %u %d", dcc->addr, dcc->port); } dcc->serv->p_ctcp (dcc->serv, nick, outbuf); @@ -2230,9 +2310,9 @@ dcc_resume (struct DCC *dcc) { dcc->resume_sent = 1; /* filename contains spaces? Quote them! */ - snprintf (tbuf, sizeof (tbuf) - 10, strchr (dcc->file, ' ') ? - "DCC RESUME \"%s\" %d %"DCC_SFMT : - "DCC RESUME %s %d %"DCC_SFMT, + g_snprintf (tbuf, sizeof (tbuf) - 10, strchr (dcc->file, ' ') ? + "DCC RESUME \"%s\" %d %" G_GUINT64_FORMAT : + "DCC RESUME %s %d %" G_GUINT64_FORMAT, dcc->file, dcc->port, dcc->resumable); if (dcc->pasvid) @@ -2287,7 +2367,7 @@ dcc_add_chat (session *sess, char *nick, int port, guint32 addr, int pasvid) dcc->addr = addr; dcc->port = port; dcc->pasvid = pasvid; - dcc->nick = strdup (nick); + dcc->nick = g_strdup (nick); dcc->starttime = time (0); EMIT_SIGNAL (XP_TE_DCCCHATOFFER, sess->server->front_session, nick, @@ -2307,7 +2387,7 @@ dcc_add_chat (session *sess, char *nick, int port, guint32 addr, int pasvid) else { char buff[128]; - snprintf (buff, sizeof (buff), "%s is offering DCC Chat. Do you want to accept?", nick); + g_snprintf (buff, sizeof (buff), "%s is offering DCC Chat. Do you want to accept?", nick); fe_confirm (buff, dcc_confirm_chat, dcc_deny_chat, dcc); } } @@ -2316,7 +2396,7 @@ dcc_add_chat (session *sess, char *nick, int port, guint32 addr, int pasvid) } static struct DCC * -dcc_add_file (session *sess, char *file, DCC_SIZE size, int port, char *nick, guint32 addr, int pasvid) +dcc_add_file (session *sess, char *file, guint64 size, int port, char *nick, guint32 addr, int pasvid) { struct DCC *dcc; char tbuf[512]; @@ -2324,7 +2404,7 @@ dcc_add_file (session *sess, char *file, DCC_SIZE size, int port, char *nick, gu dcc = new_dcc (); if (dcc) { - dcc->file = strdup (file); + dcc->file = g_strdup (file); dcc->destfile = g_malloc (strlen (prefs.hex_dcc_dir) + strlen (nick) + strlen (file) + 4); @@ -2359,14 +2439,14 @@ dcc_add_file (session *sess, char *file, DCC_SIZE size, int port, char *nick, gu dcc->port = port; dcc->pasvid = pasvid; dcc->size = size; - dcc->nick = strdup (nick); + dcc->nick = g_strdup (nick); dcc->maxcps = prefs.hex_dcc_max_get_cps; - is_resumable (dcc); + update_is_resumable (dcc); if (prefs.hex_dcc_auto_recv == 1) { - snprintf (tbuf, sizeof (tbuf), _("%s is offering \"%s\". Do you want to accept?"), nick, file); + g_snprintf (tbuf, sizeof (tbuf), _("%s is offering \"%s\". Do you want to accept?"), nick, file); fe_confirm (tbuf, dcc_confirm_send, dcc_deny_send, dcc); } else if (prefs.hex_dcc_auto_recv == 2) @@ -2380,8 +2460,8 @@ dcc_add_file (session *sess, char *file, DCC_SIZE size, int port, char *nick, gu } else fe_dcc_add (dcc); } - sprintf (tbuf, "%"DCC_SFMT, size); - snprintf (tbuf + 24, 300, "%s:%d", net_ip (addr), port); + sprintf (tbuf, "%" G_GUINT64_FORMAT, size); + g_snprintf (tbuf + 24, 300, "%s:%d", net_ip (addr), port); EMIT_SIGNAL (XP_TE_DCCSENDOFFER, sess->server->front_session, nick, file, tbuf, tbuf + 24, 0); @@ -2397,7 +2477,7 @@ handle_dcc (struct session *sess, char *nick, char *word[], char *word_eol[], char *type = word[5]; int port, pasvid = 0; guint32 addr; - DCC_SIZE size; + guint64 size; int psend = 0; if (!g_ascii_strcasecmp (type, "CHAT")) @@ -2463,7 +2543,7 @@ handle_dcc (struct session *sess, char *nick, char *word[], char *word_eol[], dcc = find_dcc (nick, word[6], TYPE_SEND); if (dcc) { - size = BIG_STR_TO_INT (word[8]); + size = g_ascii_strtoull (word[8], NULL, 10); dcc->resumable = size; if (dcc->resumable < dcc->size) { @@ -2473,19 +2553,19 @@ handle_dcc (struct session *sess, char *nick, char *word[], char *word_eol[], /* Checking if dcc is passive and if filename contains spaces */ if (dcc->pasvid) - snprintf (tbuf, sizeof (tbuf), strchr (file_part (dcc->file), ' ') ? - "DCC ACCEPT \"%s\" %d %"DCC_SFMT" %d" : - "DCC ACCEPT %s %d %"DCC_SFMT" %d", + g_snprintf (tbuf, sizeof (tbuf), strchr (file_part (dcc->file), ' ') ? + "DCC ACCEPT \"%s\" %d %" G_GUINT64_FORMAT " %d" : + "DCC ACCEPT %s %d %" G_GUINT64_FORMAT " %d", file_part (dcc->file), port, dcc->resumable, dcc->pasvid); else - snprintf (tbuf, sizeof (tbuf), strchr (file_part (dcc->file), ' ') ? - "DCC ACCEPT \"%s\" %d %"DCC_SFMT : - "DCC ACCEPT %s %d %"DCC_SFMT, + g_snprintf (tbuf, sizeof (tbuf), strchr (file_part (dcc->file), ' ') ? + "DCC ACCEPT \"%s\" %d %" G_GUINT64_FORMAT : + "DCC ACCEPT %s %d %" G_GUINT64_FORMAT, file_part (dcc->file), port, dcc->resumable); dcc->serv->p_ctcp (dcc->serv, dcc->nick, tbuf); } - sprintf (tbuf, "%"DCC_SFMT, dcc->pos); + sprintf (tbuf, "%" G_GUINT64_FORMAT, dcc->pos); EMIT_SIGNAL_TIMESTAMP (XP_TE_DCCRESUMEREQUEST, sess, nick, file_part (dcc->file), tbuf, NULL, 0, tags_data->timestamp); @@ -2508,7 +2588,7 @@ handle_dcc (struct session *sess, char *nick, char *word[], char *word_eol[], port = atoi (word[8]); addr = strtoul (word[7], NULL, 10); - size = BIG_STR_TO_INT (word[9]); + size = g_ascii_strtoull (word[9], NULL, 10); if (port == 0) /* Passive dcc requested */ pasvid = atoi (word[10]); @@ -2576,7 +2656,7 @@ dcc_show_list (struct session *sess) { dcc = (struct DCC *) list->data; i++; - PrintTextf (sess, " %s %-10.10s %-7.7s %-7"DCC_SFMT" %-7"DCC_SFMT" %s\n", + PrintTextf (sess, " %s %-10.10s %-7.7s %-7" G_GUINT64_FORMAT " %-7" G_GUINT64_FORMAT " %s\n", dcctypes[dcc->type], dcc->nick, _(dccstat[dcc->dccstat].name), dcc->size, dcc->pos, file_part (dcc->file)); diff --git a/src/common/dcc.h b/src/common/dcc.h index ade1dae7..e7115b32 100644 --- a/src/common/dcc.h +++ b/src/common/dcc.h @@ -39,17 +39,6 @@ #define CPS_AVG_WINDOW 10 -/* can we do 64-bit dcc? */ -#if defined(G_GINT64_FORMAT) && defined(HAVE_STRTOULL) -#define USE_DCC64 -/* we really get only 63 bits, since st_size is signed */ -#define DCC_SIZE gint64 -#define DCC_SFMT G_GINT64_FORMAT -#else -#define DCC_SIZE unsigned int -#define DCC_SFMT "u" -#endif - struct DCC { struct server *serv; @@ -62,21 +51,21 @@ struct DCC int wiotag; /* writing/sending io tag */ int port; int pasvid; /* mIRC's passive DCC id */ - int cps; + gint64 cps; int resume_error; int resume_errno; GTimeVal lastcpstv, firstcpstv; - DCC_SIZE lastcpspos; - int maxcps; + goffset lastcpspos; + gint64 maxcps; unsigned char ack_buf[4]; /* buffer for reading 4-byte ack */ int ack_pos; - DCC_SIZE size; - DCC_SIZE resumable; - DCC_SIZE ack; - DCC_SIZE pos; + guint64 size; + guint64 resumable; + guint64 ack; + guint64 pos; time_t starttime; time_t offertime; time_t lasttime; @@ -125,7 +114,7 @@ void dcc_check_timeouts (void); void dcc_change_nick (server *serv, char *oldnick, char *newnick); void dcc_notify_kill (struct server *serv); struct DCC *dcc_write_chat (char *nick, char *text); -void dcc_send (struct session *sess, char *to, char *file, int maxcps, int passive); +void dcc_send (struct session *sess, char *to, char *file, gint64 maxcps, int passive); struct DCC *find_dcc (char *nick, char *file, int type); void dcc_get_nick (struct session *sess, char *nick); void dcc_chat (session *sess, char *nick, int passive); diff --git a/src/common/fe.h b/src/common/fe.h index 2ca15c60..a3bd2afa 100644 --- a/src/common/fe.h +++ b/src/common/fe.h @@ -88,11 +88,10 @@ void fe_progressbar_start (struct session *sess); void fe_progressbar_end (struct server *serv); void fe_print_text (struct session *sess, char *text, time_t stamp, gboolean no_activity); -void fe_userlist_insert (struct session *sess, struct User *newuser, int row, int sel); +void fe_userlist_insert (struct session *sess, struct User *newuser, gboolean sel); int fe_userlist_remove (struct session *sess, struct User *user); void fe_userlist_rehash (struct session *sess, struct User *user); void fe_userlist_update (struct session *sess, struct User *user); -void fe_userlist_move (struct session *sess, struct User *user, int new_row); void fe_userlist_numbers (struct session *sess); void fe_userlist_clear (struct session *sess); void fe_userlist_set_selected (struct session *sess); @@ -179,7 +178,6 @@ typedef enum } feicon; void fe_tray_set_icon (feicon icon); void fe_tray_set_tooltip (const char *text); -void fe_tray_set_balloon (const char *title, const char *text); void fe_open_chan_list (server *serv, char *filter, int do_refresh); const char *fe_get_default_font (); diff --git a/src/common/hexchat.c b/src/common/hexchat.c index 09afa445..a76db332 100644 --- a/src/common/hexchat.c +++ b/src/common/hexchat.c @@ -41,7 +41,9 @@ #include "chanopt.h" #include "ignore.h" #include "hexchat-plugin.h" +#include "inbound.h" #include "plugin.h" +#include "plugin-identd.h" #include "plugin-timer.h" #include "notify.h" #include "server.h" @@ -55,15 +57,6 @@ #include <glib-object.h> /* for g_type_init() */ #endif -#ifdef USE_OPENSSL -#include <openssl/ssl.h> /* SSL_() */ -#include "ssl.h" -#endif - -#ifdef USE_MSPROXY -#include "msproxy.h" -#endif - #ifdef USE_LIBPROXY #include <proxy.h> #endif @@ -118,10 +111,6 @@ struct session *current_tab; struct session *current_sess = 0; struct hexchatprefs prefs; -#ifdef USE_OPENSSL -SSL_CTX *ctx = NULL; -#endif - #ifdef USE_LIBPROXY pxProxyFactory *libproxy_factory; #endif @@ -221,7 +210,7 @@ find_dialog (server *serv, char *nick) } list = list->next; } - return 0; + return NULL; } session * @@ -232,14 +221,14 @@ find_channel (server *serv, char *chan) while (list) { sess = list->data; - if ((!serv || serv == sess->server) && sess->type == SESS_CHANNEL) + if ((serv == sess->server) && sess->type == SESS_CHANNEL) { if (!serv->p_cmp (chan, sess->channel)) return sess; } list = list->next; } - return 0; + return NULL; } static void @@ -269,7 +258,7 @@ lag_check (void) unsigned long tim; char tbuf[128]; time_t now = time (0); - int lag; + time_t lag; tim = make_ping_time (); @@ -279,16 +268,17 @@ lag_check (void) if (serv->connected && serv->end_of_motd) { lag = now - serv->ping_recv; - if (prefs.hex_net_ping_timeout && lag > prefs.hex_net_ping_timeout && lag > 0) + if (prefs.hex_net_ping_timeout != 0 && lag > prefs.hex_net_ping_timeout && lag > 0) { - sprintf (tbuf, "%d", lag); + sprintf (tbuf, "%" G_GINT64_FORMAT, (gint64) lag); EMIT_SIGNAL (XP_TE_PINGTIMEOUT, serv->server_session, tbuf, NULL, NULL, NULL, 0); if (prefs.hex_net_auto_reconnect) serv->auto_reconnect (serv, FALSE, -1); - } else + } + else { - snprintf (tbuf, sizeof (tbuf), "LAG%lu", tim); + g_snprintf (tbuf, sizeof (tbuf), "LAG%lu", tim); serv->p_ping (serv, "", tbuf); if (!serv->lag_sent) @@ -368,9 +358,6 @@ static int hexchat_misc_checks (void) /* this gets called every 1/2 second */ { static int count = 0; -#ifdef USE_MSPROXY - static int count2 = 0; -#endif count++; @@ -386,15 +373,6 @@ hexchat_misc_checks (void) /* this gets called every 1/2 second */ count = 0; } -#ifdef USE_MSPROXY - count2++; - if (count2 >= 720) /* 720 every 6 minutes */ - { - msproxy_keepalive (); - count2 = 0; - } -#endif - return 1; } @@ -405,7 +383,6 @@ irc_init (session *sess) { static int done_init = FALSE; char *buf; - int i; if (done_init) return; @@ -413,6 +390,7 @@ irc_init (session *sess) done_init = TRUE; plugin_add (sess, NULL, NULL, timer_plugin_init, NULL, NULL, FALSE); + plugin_add (sess, NULL, NULL, identd_plugin_init, identd_plugin_deinit, NULL, FALSE); #ifdef USE_PLUGIN if (!arg_skip_plugins) @@ -440,7 +418,8 @@ irc_init (session *sess) if (arg_urls != NULL) { - for (i = 0; i < g_strv_length(arg_urls); i++) + guint i; + for (i = 0; i < g_strv_length (arg_urls); i++) { buf = g_strdup_printf ("%s %s", i==0? "server" : "newserver", arg_urls[i]); handle_command (sess, buf, FALSE); @@ -464,12 +443,7 @@ session_new (server *serv, char *from, int type, int focus) { session *sess; - sess = malloc (sizeof (struct session)); - if (sess == NULL) - { - return NULL; - } - memset (sess, 0, sizeof (struct session)); + sess = g_new0 (struct session, 1); sess->server = serv; sess->logfd = -1; @@ -488,7 +462,10 @@ session_new (server *serv, char *from, int type, int focus) sess->lastact_idx = LACT_NONE; if (from != NULL) - safe_strcpy (sess->channel, from, CHANLEN); + { + safe_strcpy(sess->channel, from, CHANLEN); + safe_strcpy(sess->session_name, from, CHANLEN); + } sess_list = g_slist_prepend (sess_list, sess); @@ -515,7 +492,6 @@ new_ircwindow (server *serv, char *name, int type, int focus) break; case SESS_DIALOG: sess = session_new (serv, name, type, focus); - log_open_or_close (sess); break; default: /* case SESS_CHANNEL: @@ -530,6 +506,16 @@ new_ircwindow (server *serv, char *name, int type, int focus) scrollback_load (sess); if (sess->scrollwritten && sess->scrollback_replay_marklast) sess->scrollback_replay_marklast (sess); + if (type == SESS_DIALOG) + { + struct User *user; + + log_open_or_close (sess); + + user = userlist_find_global (serv, name); + if (user && user->hostname) + set_topic (sess, user->hostname, user->hostname); + } plugin_emit_dummy_print (sess, "Open Context"); return sess; @@ -548,9 +534,8 @@ exec_notify_kill (session * sess) waitpid (re->childpid, NULL, WNOHANG); fe_input_remove (re->iotag); close (re->myfd); - if (re->linebuf) - free(re->linebuf); - free (re); + g_free(re->linebuf); + g_free (re); } #endif } @@ -656,10 +641,8 @@ session_free (session *killsess) send_quit_or_part (killsess); history_free (&killsess->history); - if (killsess->topic) - free (killsess->topic); - if (killsess->current_modes) - free (killsess->current_modes); + g_free (killsess->topic); + g_free (killsess->current_modes); fe_session_callback (killsess); @@ -670,7 +653,7 @@ session_free (session *killsess) current_sess = sess_list->data; } - free (killsess); + g_free (killsess); if (!sess_list && !in_hexchat_exit) hexchat_exit (); /* sess_list is empty, quit! */ @@ -784,20 +767,15 @@ static void xchat_init (void) { char buf[3068]; - const char *cs = NULL; #ifdef WIN32 WSADATA wsadata; -#ifdef USE_IPV6 if (WSAStartup(0x0202, &wsadata) != 0) { MessageBox (NULL, "Cannot find winsock 2.2+", "Error", MB_OK); exit (0); } -#else - WSAStartup(0x0101, &wsadata); -#endif /* !USE_IPV6 */ #endif /* !WIN32 */ #ifdef USE_SIGACTION @@ -826,15 +804,12 @@ xchat_init (void) #endif #endif - if (g_get_charset (&cs)) - prefs.utf8_locale = TRUE; - load_text_events (); sound_load (); notify_load (); ignore_load (); - snprintf (buf, sizeof (buf), + g_snprintf (buf, sizeof (buf), "NAME %s~%s~\n" "CMD query %%s\n\n"\ "NAME %s~%s~\n" "CMD send %%s\n\n"\ "NAME %s~%s~\n" "CMD whois %%s %%s\n\n"\ @@ -890,7 +865,7 @@ xchat_init (void) list_loadconf ("popup.conf", &popup_list, buf); - snprintf (buf, sizeof (buf), + g_snprintf (buf, sizeof (buf), "NAME %s\n" "CMD part\n\n" "NAME %s\n" "CMD getstr # join \"%s\"\n\n" "NAME %s\n" "CMD quote LINKS\n\n" @@ -904,7 +879,7 @@ xchat_init (void) _("Hide Version")); list_loadconf ("usermenu.conf", &usermenu_list, buf); - snprintf (buf, sizeof (buf), + g_snprintf (buf, sizeof (buf), "NAME %s\n" "CMD op %%a\n\n" "NAME %s\n" "CMD deop %%a\n\n" "NAME %s\n" "CMD ban %%s\n\n" @@ -921,7 +896,7 @@ xchat_init (void) _("Dialog")); list_loadconf ("buttons.conf", &button_list, buf); - snprintf (buf, sizeof (buf), + g_snprintf (buf, sizeof (buf), "NAME %s\n" "CMD whois %%s %%s\n\n" "NAME %s\n" "CMD send %%s\n\n" "NAME %s\n" "CMD dcc chat %%s\n\n" @@ -1021,29 +996,37 @@ main (int argc, char *argv[]) int i; int ret; - srand (time (0)); /* CL: do this only once! */ +#ifdef WIN32 + HRESULT coinit_result; +#endif + + srand ((unsigned int) time (NULL)); /* CL: do this only once! */ /* We must check for the config dir parameter, otherwise load_config() will behave incorrectly. * load_config() must come before fe_args() because fe_args() calls gtk_init() which needs to * know the language which is set in the config. The code below is copy-pasted from fe_args() * for the most part. */ - if (argc >= 3) + if (argc >= 2) { - for (i = 1; i < argc - 1; i++) + for (i = 1; i < argc; i++) { - if (strcmp (argv[i], "-d") == 0) + if ((strcmp (argv[i], "-d") == 0 || strcmp (argv[i], "--cfgdir") == 0) + && i + 1 < argc) { - if (xdir) - { - g_free (xdir); - } - - xdir = strdup (argv[i + 1]); + xdir = g_strdup (argv[i + 1]); + } + else if (strncmp (argv[i], "--cfgdir=", 9) == 0) + { + xdir = g_strdup (argv[i] + 9); + } + if (xdir != NULL) + { if (xdir[strlen (xdir) - 1] == G_DIR_SEPARATOR) { xdir[strlen (xdir) - 1] = 0; } + break; } } } @@ -1067,10 +1050,6 @@ main (int argc, char *argv[]) /* we MUST do this after load_config () AND before fe_init (thus gtk_init) otherwise it will fail */ set_locale (); -#ifdef SOCKS - SOCKSinit (argv[0]); -#endif - ret = fe_args (argc, argv); if (ret != -1) return ret; @@ -1083,6 +1062,14 @@ main (int argc, char *argv[]) libproxy_factory = px_proxy_factory_new(); #endif +#ifdef WIN32 + coinit_result = CoInitializeEx (NULL, COINIT_APARTMENTTHREADED); + if (SUCCEEDED (coinit_result)) + { + CoInitializeSecurity (NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); + } +#endif + fe_init (); /* This is done here because cfgfiles.c is too early in @@ -1110,13 +1097,15 @@ main (int argc, char *argv[]) fe_main (); -#ifdef USE_LIBPROXY - px_proxy_factory_free(libproxy_factory); +#ifdef WIN32 + if (SUCCEEDED (coinit_result)) + { + CoUninitialize (); + } #endif -#ifdef USE_OPENSSL - if (ctx) - _SSL_context_free (ctx); +#ifdef USE_LIBPROXY + px_proxy_factory_free(libproxy_factory); #endif #ifdef WIN32 diff --git a/src/common/hexchat.h b/src/common/hexchat.h index bbf32da5..652dcf1d 100644 --- a/src/common/hexchat.h +++ b/src/common/hexchat.h @@ -22,6 +22,7 @@ #include <glib.h> #include <glib/gstdio.h> #include <glib/gi18n.h> +#include <gio/gio.h> #include <time.h> /* need time_t */ @@ -36,22 +37,7 @@ #endif #include "history.h" - -#ifndef HAVE_SNPRINTF -#define snprintf g_snprintf -#endif - -#ifndef HAVE_VSNPRINTF -#define vsnprintf _vsnprintf -#endif - -#ifdef SOCKS -#ifdef __sgi -#include <sys/time.h> -#define INCLUDE_PROTOTYPES 1 -#endif -#include <socks.h> -#endif +#include "tree.h" #ifdef USE_OPENSSL #include <openssl/ssl.h> /* SSL_() */ @@ -262,6 +248,7 @@ struct hexchatprefs int hex_gui_search_pos; int hex_gui_slist_select; int hex_gui_tab_layout; + int hex_gui_tab_middleclose; int hex_gui_tab_newtofront; int hex_gui_tab_pos; int hex_gui_tab_small; @@ -277,7 +264,7 @@ struct hexchatprefs int hex_gui_win_state; int hex_gui_win_top; int hex_gui_win_width; - int hex_input_balloon_time; + int hex_identd_port; int hex_irc_ban_type; int hex_irc_join_delay; int hex_irc_notice_pos; @@ -329,7 +316,6 @@ struct hexchatprefs guint32 dcc_ip; unsigned int wait_on_exit; /* wait for logs to be flushed to disk IF we're connected */ - unsigned int utf8_locale; /* Tells us if we need to save, only when they've been edited. This is so that we continue using internal defaults (which can @@ -382,12 +368,12 @@ typedef struct session guint8 text_strip; struct server *server; - void *usertree_alpha; /* pure alphabetical tree */ - void *usertree; /* ordered with Ops first */ + tree *usertree; /* alphabetical tree */ struct User *me; /* points to myself in the usertree */ char channel[CHANLEN]; char waitchannel[CHANLEN]; /* waiting to join channel (/join sent) */ char willjoinchannel[CHANLEN]; /* will issue /join for this channel */ + char session_name[CHANLEN]; /* the name of the session, should not modified */ char channelkey[64]; /* XXX correct max length? */ int limit; /* channel user limit */ int logfd; @@ -434,14 +420,6 @@ typedef struct session void (*scrollback_replay_marklast) (struct session *sess); } session; -struct msproxy_state_t -{ - gint32 clientid; - gint32 serverid; - unsigned char seq_recv; /* seq number of last packet recv. */ - unsigned char seq_sent; /* seq number of last packet sent. */ -}; - /* SASL Mechanisms */ #define MECH_PLAIN 0 #define MECH_BLOWFISH 1 @@ -499,9 +477,9 @@ typedef struct server int proxy_sok; /* Additional information for MS Proxy beast */ int proxy_sok4; int proxy_sok6; - struct msproxy_state_t msp_state; int id; /* unique ID number (for plugin API) */ #ifdef USE_OPENSSL + SSL_CTX *ctx; SSL *ssl; int ssl_do_connect_tag; #else @@ -554,7 +532,10 @@ typedef struct server time_t ping_recv; /* when we last got a ping reply */ time_t away_time; /* when we were marked away */ - char *encoding; /* NULL for system */ + char *encoding; + GIConv read_converter; /* iconv converter for converting from server encoding to UTF-8. */ + GIConv write_converter; /* iconv converter for converting from UTF-8 to server encoding. */ + GSList *favlist; /* list of channels & keys to join */ unsigned int motd_skipped:1; @@ -587,8 +568,6 @@ typedef struct server unsigned int have_except:1; /* ban exemptions +e */ unsigned int have_invite:1; /* invite exemptions +I */ unsigned int have_cert:1; /* have loaded a cert */ - unsigned int using_cp1255:1; /* encoding is CP1255/WINDOWS-1255? */ - unsigned int using_irc:1; /* encoding is "IRC" (CP1252/UTF-8 hybrid)? */ unsigned int use_who:1; /* whether to use WHO command to get dcc_ip */ unsigned int sasl_mech; /* mechanism for sasl auth */ unsigned int sent_saslauth:1; /* have sent AUTHENICATE yet */ @@ -631,7 +610,4 @@ struct popup /* CL: get a random int in the range [0..n-1]. DON'T use rand() % n, it gives terrible results. */ #define RAND_INT(n) ((int)(rand() / (RAND_MAX + 1.0) * (n))) -#define hexchat_filename_from_utf8 g_filename_from_utf8 -#define hexchat_filename_to_utf8 g_filename_to_utf8 - #endif diff --git a/src/common/history.c b/src/common/history.c index 1acd3327..23a8463e 100644 --- a/src/common/history.c +++ b/src/common/history.c @@ -18,14 +18,14 @@ #include <string.h> #include <stdlib.h> +#include <glib.h> #include "history.h" void history_add (struct history *his, char *text) { - if (his->lines[his->realpos]) - free (his->lines[his->realpos]); - his->lines[his->realpos] = strdup (text); + g_free (his->lines[his->realpos]); + his->lines[his->realpos] = g_strdup (text); his->realpos++; if (his->realpos == HISTORY_SIZE) his->realpos = 0; @@ -40,7 +40,7 @@ history_free (struct history *his) { if (his->lines[i]) { - free (his->lines[i]); + g_free (his->lines[i]); his->lines[i] = 0; } } @@ -52,7 +52,7 @@ history_down (struct history *his) int next; if (his->pos == his->realpos) /* allow down only after up */ - return 0; + return NULL; if (his->realpos == 0) { if (his->pos == HISTORY_SIZE - 1) @@ -79,7 +79,7 @@ history_down (struct history *his) return his->lines[his->pos]; } - return 0; + return NULL; } char * @@ -90,11 +90,11 @@ history_up (struct history *his, char *current_text) if (his->realpos == HISTORY_SIZE - 1) { if (his->pos == 0) - return 0; + return NULL; } else { if (his->pos == his->realpos + 1) - return 0; + return NULL; } next = HISTORY_SIZE - 1; @@ -117,5 +117,5 @@ history_up (struct history *his, char *current_text) return his->lines[his->pos]; } - return 0; + return NULL; } diff --git a/src/common/identd.c b/src/common/identd.c deleted file mode 100644 index c4050929..00000000 --- a/src/common/identd.c +++ /dev/null @@ -1,201 +0,0 @@ -/* HexChat - * Copyright (C) 1998-2010 Peter Zelezny. - * Copyright (C) 2009-2013 Berke Viktor. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -/* simple identd server for HexChat under Win32 */ - -#include "inet.h" -#include "hexchat.h" -#include "hexchatc.h" -#include "text.h" - -static int identd_is_running = FALSE; -#ifdef USE_IPV6 -static int identd_ipv6_is_running = FALSE; -#endif - -static int -identd (char *username) -{ - int sok, read_sok, len; - char *p; - char buf[256]; - char outbuf[256]; - char ipbuf[INET_ADDRSTRLEN]; - struct sockaddr_in addr; - - sok = socket (AF_INET, SOCK_STREAM, 0); - if (sok == INVALID_SOCKET) - { - free (username); - return 0; - } - - len = 1; - setsockopt (sok, SOL_SOCKET, SO_REUSEADDR, (char *) &len, sizeof (len)); - - memset (&addr, 0, sizeof (addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons (113); - - if (bind (sok, (struct sockaddr *) &addr, sizeof (addr)) == SOCKET_ERROR) - { - closesocket (sok); - free (username); - return 0; - } - - if (listen (sok, 1) == SOCKET_ERROR) - { - closesocket (sok); - free (username); - return 0; - } - - len = sizeof (addr); - read_sok = accept (sok, (struct sockaddr *) &addr, &len); - closesocket (sok); - if (read_sok == INVALID_SOCKET) - { - free (username); - return 0; - } - - identd_is_running = FALSE; - -#if 0 /* causes random crashes, probably due to CreateThread */ - EMIT_SIGNAL (XP_TE_IDENTD, current_sess, inet_ntoa (addr.sin_addr), username, NULL, NULL, 0); -#endif - inet_ntop (AF_INET, &addr.sin_addr, ipbuf, sizeof (ipbuf)); - snprintf (outbuf, sizeof (outbuf), "*\tServicing ident request from %s as %s\n", ipbuf, username); - PrintText (current_sess, outbuf); - - recv (read_sok, buf, sizeof (buf) - 1, 0); - buf[sizeof (buf) - 1] = 0; /* ensure null termination */ - - p = strchr (buf, ','); - if (p) - { - snprintf (outbuf, sizeof (outbuf) - 1, "%d, %d : USERID : UNIX : %s\r\n", - atoi (buf), atoi (p + 1), username); - outbuf[sizeof (outbuf) - 1] = 0; /* ensure null termination */ - send (read_sok, outbuf, strlen (outbuf), 0); - } - - sleep (1); - closesocket (read_sok); - free (username); - - return 0; -} - -#ifdef USE_IPV6 -static int -identd_ipv6 (char *username) -{ - int sok, read_sok, len; - char *p; - char buf[256]; - char outbuf[256]; - char ipbuf[INET6_ADDRSTRLEN]; - struct sockaddr_in6 addr; - - sok = socket (AF_INET6, SOCK_STREAM, 0); - if (sok == INVALID_SOCKET) - { - free (username); - return 0; - } - - len = 1; - setsockopt (sok, SOL_SOCKET, SO_REUSEADDR, (char *) &len, sizeof (len)); - - memset (&addr, 0, sizeof (addr)); - addr.sin6_family = AF_INET6; - addr.sin6_port = htons (113); - - if (bind (sok, (struct sockaddr *) &addr, sizeof (addr)) == SOCKET_ERROR) - { - closesocket (sok); - free (username); - return 0; - } - - if (listen (sok, 1) == SOCKET_ERROR) - { - closesocket (sok); - free (username); - return 0; - } - - len = sizeof (addr); - read_sok = accept (sok, (struct sockaddr *) &addr, &len); - closesocket (sok); - if (read_sok == INVALID_SOCKET) - { - free (username); - return 0; - } - - identd_ipv6_is_running = FALSE; - - inet_ntop (AF_INET6, &addr.sin6_addr, ipbuf, sizeof (ipbuf)); - snprintf (outbuf, sizeof (outbuf), "*\tServicing ident request from %s as %s\n", ipbuf, username); - PrintText (current_sess, outbuf); - - recv (read_sok, buf, sizeof (buf) - 1, 0); - buf[sizeof (buf) - 1] = 0; /* ensure null termination */ - - p = strchr (buf, ','); - if (p) - { - snprintf (outbuf, sizeof (outbuf) - 1, "%d, %d : USERID : UNIX : %s\r\n", atoi (buf), atoi (p + 1), username); - outbuf[sizeof (outbuf) - 1] = 0; /* ensure null termination */ - send (read_sok, outbuf, strlen (outbuf), 0); - } - - sleep (1); - closesocket (read_sok); - free (username); - - return 0; -} -#endif - -void -identd_start (char *username) -{ - DWORD tid; - -#ifdef USE_IPV6 - DWORD tidv6; - if (identd_ipv6_is_running == FALSE) - { - identd_ipv6_is_running = TRUE; - CloseHandle (CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) identd_ipv6, - strdup (username), 0, &tidv6)); - } -#endif - - if (identd_is_running == FALSE) - { - identd_is_running = TRUE; - CloseHandle (CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) identd, - strdup (username), 0, &tid)); - } -} diff --git a/src/common/ignore.c b/src/common/ignore.c index 045224ba..6085b657 100644 --- a/src/common/ignore.c +++ b/src/common/ignore.c @@ -53,7 +53,7 @@ static int ignored_total = 0; struct ignore * ignore_exists (char *mask) { - struct ignore *ig = 0; + struct ignore *ig = NULL; GSList *list; list = ignore_list; @@ -79,7 +79,7 @@ ignore_exists (char *mask) int ignore_add (char *mask, int type, gboolean overwrite) { - struct ignore *ig = 0; + struct ignore *ig = NULL; int change_only = FALSE; /* first check if it's already ignored */ @@ -88,12 +88,9 @@ ignore_add (char *mask, int type, gboolean overwrite) change_only = TRUE; if (!change_only) - ig = malloc (sizeof (struct ignore)); + ig = g_new (struct ignore, 1); - if (!ig) - return 0; - - ig->mask = strdup (mask); + ig->mask = g_strdup (mask); if (!overwrite && change_only) ig->type |= type; @@ -125,7 +122,7 @@ ignore_showlist (session *sess) ig = list->data; i++; - snprintf (tbuf, sizeof (tbuf), " %-25s ", ig->mask); + g_snprintf (tbuf, sizeof (tbuf), " %-25s ", ig->mask); if (ig->type & IG_PRIV) strcat (tbuf, _("YES ")); else @@ -192,8 +189,8 @@ ignore_del (char *mask, struct ignore *ig) if (ig) { ignore_list = g_slist_remove (ignore_list, ig); - free (ig->mask); - free (ig); + g_free (ig->mask); + g_free (ig); fe_ignore_update (1); return TRUE; } @@ -265,7 +262,7 @@ ignore_read_next_entry (char *my_cfg, struct ignore *ignore) my_cfg = cfg_get_str (my_cfg, "mask", tbuf, sizeof (tbuf)); if (!my_cfg) return NULL; - ignore->mask = strdup (tbuf); + ignore->mask = g_strdup (tbuf); } if (my_cfg) { @@ -281,7 +278,7 @@ ignore_load () struct ignore *ignore; struct stat st; char *cfg, *my_cfg; - int fh, i; + int fh; fh = hexchat_open_file ("ignore.conf", O_RDONLY, 0, 0); if (fh != -1) @@ -289,22 +286,18 @@ ignore_load () fstat (fh, &st); if (st.st_size) { - cfg = malloc (st.st_size + 1); - cfg[0] = '\0'; - i = read (fh, cfg, st.st_size); - if (i >= 0) - cfg[i] = '\0'; + cfg = g_malloc0 (st.st_size + 1); + read (fh, cfg, st.st_size); my_cfg = cfg; while (my_cfg) { - ignore = malloc (sizeof (struct ignore)); - memset (ignore, 0, sizeof (struct ignore)); + ignore = g_new0 (struct ignore, 1); if ((my_cfg = ignore_read_next_entry (my_cfg, ignore))) ignore_list = g_slist_prepend (ignore_list, ignore); else - free (ignore); + g_free (ignore); } - free (cfg); + g_free (cfg); } close (fh); } @@ -326,7 +319,7 @@ ignore_save () ig = (struct ignore *) temp->data; if (!(ig->type & IG_NOSAVE)) { - snprintf (buf, sizeof (buf), "mask = %s\ntype = %u\n\n", + g_snprintf (buf, sizeof (buf), "mask = %s\ntype = %u\n\n", ig->mask, ig->type); write (fh, buf, strlen (buf)); } @@ -379,9 +372,9 @@ flood_check (char *nick, char *ip, server *serv, session *sess, int what) /*0=ct for (i = 0; i < 128; i++) if (ip[i] == '@') break; - snprintf (real_ip, sizeof (real_ip), "*!*%s", &ip[i]); + g_snprintf (real_ip, sizeof (real_ip), "*!*%s", &ip[i]); - snprintf (buf, sizeof (buf), + g_snprintf (buf, sizeof (buf), _("You are being CTCP flooded from %s, ignoring %s\n"), nick, real_ip); PrintText (sess, buf); @@ -406,7 +399,7 @@ flood_check (char *nick, char *ip, server *serv, session *sess, int what) /*0=ct serv->msg_counter++; if (serv->msg_counter == prefs.hex_flood_msg_num) /*if we reached the maximun numbers of ctcp in the seconds limits */ { - snprintf (buf, sizeof (buf), + g_snprintf (buf, sizeof (buf), _("You are being MSG flooded from %s, setting gui_autoopen_dialog OFF.\n"), ip); PrintText (sess, buf); diff --git a/src/common/inbound.c b/src/common/inbound.c index b80553b3..ef26890b 100644 --- a/src/common/inbound.c +++ b/src/common/inbound.c @@ -33,8 +33,6 @@ #define WANTDNS #include "inet.h" -#include <gio/gio.h> - #include "hexchat.h" #include "util.h" #include "ignore.h" @@ -64,7 +62,7 @@ clear_channel (session *sess) if (sess->current_modes) { - free (sess->current_modes); + g_free (sess->current_modes); sess->current_modes = NULL; } @@ -83,9 +81,17 @@ clear_channel (session *sess) void set_topic (session *sess, char *topic, char *stripped_topic) { - if (sess->topic) - free (sess->topic); - sess->topic = strdup (stripped_topic); + /* The topic of dialogs are the users hostname which is logged is new */ + if (sess->type == SESS_DIALOG && (!sess->topic || strcmp(sess->topic, stripped_topic)) + && sess->logfd != -1) + { + char tbuf[1024]; + g_snprintf (tbuf, sizeof (tbuf), "[%s has address %s]\n", sess->channel, stripped_topic); + write (sess->logfd, tbuf, strlen (tbuf)); + } + + g_free (sess->topic); + sess->topic = g_strdup (stripped_topic); fe_set_topic (sess, topic, stripped_topic); } @@ -121,7 +127,7 @@ find_session_from_nick (char *nick, server *serv) } list = list->next; } - return 0; + return NULL; } static session * @@ -182,16 +188,7 @@ inbound_privmsg (server *serv, char *from, char *ip, char *text, int id, } if (ip && ip[0]) - { - if (prefs.hex_irc_logging && sess->logfd != -1 && - (!sess->topic || strcmp(sess->topic, ip))) - { - char tbuf[1024]; - snprintf (tbuf, sizeof (tbuf), "[%s has address %s]\n", from, ip); - write (sess->logfd, tbuf, strlen (tbuf)); - } set_topic (sess, ip, ip); - } inbound_chanmsg (serv, NULL, NULL, from, text, FALSE, id, tags_data); return; } @@ -558,7 +555,7 @@ find_unused_session (server *serv) } list = list->next; } - return 0; + return NULL; } static session * @@ -576,7 +573,7 @@ find_session_from_waitchannel (char *chan, struct server *serv) } list = list->next; } - return 0; + return NULL; } void @@ -682,7 +679,8 @@ inbound_nameslist (server *serv, char *chan, char *names, char **name_list; char *host, *nopre_name; char name[NICKLEN]; - int i, offset; + int i; + size_t offset; sess = find_channel (serv, chan); if (!sess) @@ -916,7 +914,7 @@ inbound_ping_reply (session *sess, char *timestring, char *from, tags_data->timestamp); } else { - snprintf (outbuf, sizeof (outbuf), "%ld.%03ld", dif / 1000, dif % 1000); + g_snprintf (outbuf, sizeof (outbuf), "%ld.%03ld", dif / 1000, dif % 1000); EMIT_SIGNAL_TIMESTAMP (XP_TE_PINGREP, sess, from, outbuf, NULL, NULL, 0, tags_data->timestamp); } @@ -934,7 +932,7 @@ find_session_from_type (int type, server *serv) return sess; list = list->next; } - return 0; + return NULL; } void @@ -969,14 +967,14 @@ inbound_notice (server *serv, char *to, char *nick, char *msg, char *ip, int id, /* guess where chanserv meant to post this -sigh- */ if (!g_ascii_strcasecmp (nick, "ChanServ") && !find_dialog (serv, nick)) { - char *dest = strdup (msg + 1); + char *dest = g_strdup (msg + 1); char *end = strchr (dest, ']'); if (end) { *end = 0; sess = find_channel (serv, dest); } - free (dest); + g_free (dest); } } if (!sess) @@ -1455,8 +1453,7 @@ inbound_user_info (session *sess, char *chan, char *user, char *host, if (user && host) { - uhost = g_malloc (strlen (user) + strlen (host) + 2); - sprintf (uhost, "%s@%s", user, host); + uhost = g_strdup_printf ("%s@%s", user, host); } if (chan) diff --git a/src/common/inet.h b/src/common/inet.h index 990415be..7056d473 100644 --- a/src/common/inet.h +++ b/src/common/inet.h @@ -47,13 +47,9 @@ #else -#include "../../config.h" -#ifdef USE_IPV6 +#include "config.h" #include <winsock2.h> #include <ws2tcpip.h> -#else -#include <winsock2.h> -#endif #define set_blocking(sok) { \ unsigned long zero = 0; \ diff --git a/src/common/make-te.c b/src/common/make-te.c index 309eec2f..834646ef 100644 --- a/src/common/make-te.c +++ b/src/common/make-te.c @@ -42,7 +42,7 @@ #include <string.h> #include <stdlib.h> -int main() +int main(void) { char name[512]; char num[512]; @@ -87,9 +87,11 @@ int main() if (i + 1 < max) { fprintf(stderr, "\t%s,\t\t%s,\n", defines[i], defines[i+1]); + free (defines[i]); i++; } else fprintf(stderr, "\t%s,\n", defines[i]); + free (defines[i]); i++; } fprintf(stderr, "\tNUM_XP\n};\n"); diff --git a/src/common/make-te.vcxproj b/src/common/make-te.vcxproj index e9b4c533..24d8f9b6 100644 --- a/src/common/make-te.vcxproj +++ b/src/common/make-te.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -19,82 +20,30 @@ <RootNamespace>makete</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\hexchat.props" /> + <PropertyGroup> + <OutDir>$(HexChatLib)</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> </Link> - <PostBuildEvent> - <Command>"$(HexChatBin)make-te.exe" < "$(ProjectDir)textevents.in" > "$(ProjectDir)textevents.h" 2> "$(ProjectDir)textenums.h"</Command> - </PostBuildEvent> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> - <MultiProcessorCompilation>true</MultiProcessorCompilation> </ClCompile> <Link> <SubSystem>Console</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> </Link> - <PostBuildEvent> - <Command>"$(HexChatBin)make-te.exe" < "$(ProjectDir)textevents.in" > "$(ProjectDir)textevents.h" 2> "$(ProjectDir)textenums.h"</Command> - </PostBuildEvent> </ItemDefinitionGroup> <ItemGroup> <ClCompile Include="make-te.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/src/common/modes.c b/src/common/modes.c index b7cd471f..c65bf279 100644 --- a/src/common/modes.c +++ b/src/common/modes.c @@ -331,7 +331,7 @@ record_chan_mode (session *sess, char sign, char mode, char *arg) current = g_string_erase(current, argument_offset+1, argument_length-1); current = g_string_insert(current, argument_offset+1, arg); - free(sess->current_modes); + g_free(sess->current_modes); sess->current_modes = g_string_free(current, FALSE); } } @@ -348,7 +348,7 @@ record_chan_mode (session *sess, char sign, char mode, char *arg) current = g_string_append(current, arg); } - free(sess->current_modes); + g_free(sess->current_modes); sess->current_modes = g_string_free(current, FALSE); } } @@ -361,7 +361,7 @@ record_chan_mode (session *sess, char sign, char mode, char *arg) /* remove the mode character */ current = g_string_erase(current, mode_pos, 1); - free(sess->current_modes); + g_free(sess->current_modes); sess->current_modes = g_string_free(current, FALSE); } } @@ -374,12 +374,13 @@ mode_cat (char *str, char *addition) if (str) { len = strlen (str) + strlen (addition) + 2; - str = realloc (str, len); + str = g_realloc (str, len); strcat (str, " "); strcat (str, addition); - } else + } + else { - str = strdup (addition); + str = g_strdup (addition); } return str; @@ -560,12 +561,12 @@ handle_single_mode (mode_run *mr, char sign, char mode, char *nick, { if (*arg) { - char *buf = malloc (strlen (chan) + strlen (arg) + 2); - sprintf (buf, "%s %s", chan, arg); + char *buf = g_strdup_printf ("%s %s", chan, arg); EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANMODEGEN, sess, nick, outbuf, outbuf + 2, buf, 0, tags_data->timestamp); - free (buf); - } else + g_free (buf); + } + else EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANMODEGEN, sess, nick, outbuf, outbuf + 2, chan, 0, tags_data->timestamp); } @@ -635,7 +636,7 @@ mode_print_grouped (session *sess, char *nick, mode_run *mr, { EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANOP, sess, nick, mr->op, NULL, NULL, 0, tags_data->timestamp); - free (mr->op); + g_free(mr->op); mr->op = NULL; } @@ -643,7 +644,7 @@ mode_print_grouped (session *sess, char *nick, mode_run *mr, { EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANDEOP, sess, nick, mr->deop, NULL, NULL, 0, tags_data->timestamp); - free (mr->deop); + g_free(mr->deop); mr->deop = NULL; } @@ -651,7 +652,7 @@ mode_print_grouped (session *sess, char *nick, mode_run *mr, { EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANVOICE, sess, nick, mr->voice, NULL, NULL, 0, tags_data->timestamp); - free (mr->voice); + g_free(mr->voice); mr->voice = NULL; } @@ -659,7 +660,7 @@ mode_print_grouped (session *sess, char *nick, mode_run *mr, { EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANDEVOICE, sess, nick, mr->devoice, NULL, NULL, 0, tags_data->timestamp); - free (mr->devoice); + g_free(mr->devoice); mr->devoice = NULL; } } @@ -677,10 +678,10 @@ handle_mode (server * serv, char *word[], char *word_eol[], char *argstr; char sign; int len; - int arg; - int i, num_args; + size_t arg; + size_t i, num_args; int num_modes; - int offset = 3; + size_t offset = 3; int all_modes_have_args = FALSE; int using_front_tab = FALSE; mode_run mr; @@ -717,9 +718,8 @@ handle_mode (server * serv, char *word[], char *word_eol[], if (numeric_324 && !using_front_tab) { - if (sess->current_modes) - free (sess->current_modes); - sess->current_modes = strdup (word_eol[offset+1]); + g_free (sess->current_modes); + sess->current_modes = g_strdup (word_eol[offset+1]); } sign = *modes; @@ -762,7 +762,7 @@ handle_mode (server * serv, char *word[], char *word_eol[], break; default: argstr = ""; - if ((all_modes_have_args || mode_has_arg (serv, sign, *modes)) && arg < (num_args+1)) + if ((all_modes_have_args || mode_has_arg (serv, sign, *modes)) && arg < (num_args + 1)) { arg++; argstr = word[arg + offset]; @@ -799,30 +799,29 @@ inbound_005 (server * serv, char *word[], const message_tags_data *tags_data) serv->modes_per_line = atoi (word[w] + 6); } else if (strncmp (word[w], "CHANTYPES=", 10) == 0) { - free (serv->chantypes); - serv->chantypes = strdup (word[w] + 10); + g_free (serv->chantypes); + serv->chantypes = g_strdup (word[w] + 10); } else if (strncmp (word[w], "CHANMODES=", 10) == 0) { - free (serv->chanmodes); - serv->chanmodes = strdup (word[w] + 10); + g_free (serv->chanmodes); + serv->chanmodes = g_strdup (word[w] + 10); } else if (strncmp (word[w], "PREFIX=", 7) == 0) { pre = strchr (word[w] + 7, ')'); if (pre) { pre[0] = 0; /* NULL out the ')' */ - free (serv->nick_prefixes); - free (serv->nick_modes); - serv->nick_prefixes = strdup (pre + 1); - serv->nick_modes = strdup (word[w] + 8); + g_free (serv->nick_prefixes); + g_free (serv->nick_modes); + serv->nick_prefixes = g_strdup (pre + 1); + serv->nick_modes = g_strdup (word[w] + 8); } else { /* bad! some ircds don't give us the modes. */ /* in this case, we use it only to strip /NAMES */ serv->bad_prefix = TRUE; - if (serv->bad_nick_prefixes) - free (serv->bad_nick_prefixes); - serv->bad_nick_prefixes = strdup (word[w] + 7); + g_free (serv->bad_nick_prefixes); + serv->bad_nick_prefixes = g_strdup (word[w] + 7); } } else if (strncmp (word[w], "WATCH=", 6) == 0) { @@ -832,10 +831,6 @@ inbound_005 (server * serv, char *word[], const message_tags_data *tags_data) serv->supports_monitor = TRUE; } else if (strncmp (word[w], "NETWORK=", 8) == 0) { -/* if (serv->networkname) - free (serv->networkname); - serv->networkname = strdup (word[w] + 8);*/ - if (serv->server_session->type == SESS_SERVER) { safe_strcpy (serv->server_session->channel, word[w] + 8, CHANLEN); diff --git a/src/common/msproxy.c b/src/common/msproxy.c deleted file mode 100644 index 5f631c7f..00000000 --- a/src/common/msproxy.c +++ /dev/null @@ -1,470 +0,0 @@ -/* X-Chat - * Copyright (C) 1998 Peter Zelezny. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - * MS Proxy (ISA server) support is (c) 2006 Pavel Fedin <sonic_amiga@rambler.ru> - * based on Dante source code - * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - * Inferno Nettverk A/S, Norway. All rights reserved. - */ - -/*#define DEBUG_MSPROXY*/ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <fcntl.h> - -#ifndef WIN32 -#include <unistd.h> -#endif - -#define WANTSOCKET -#define WANTARPA -#include "inet.h" - -#include "hexchat.h" -#include "network.h" -#include "hexchatc.h" -#include "server.h" -#include "msproxy.h" - - -#ifdef USE_MSPROXY -#include <ntlm.h> - -static int -send_msprequest(s, state, request, end) - int s; - struct msproxy_state_t *state; - struct msproxy_request_t *request; - char *end; -{ - ssize_t w; - size_t l; - - request->magic25 = htonl(MSPROXY_VERSION); - request->serverack = state->seq_recv; - /* don't start incrementing sequence until we are acking packet #2. */ - request->sequence = (unsigned char)(request->serverack >= 2 ? state->seq_sent + 1 : 0); - - memcpy(request->RWSP, "RWSP", sizeof(request->RWSP)); - - l = end - (char *)request; - /* all requests must be atleast MSPROXY_MINLENGTH it seems. */ - if (l < MSPROXY_MINLENGTH) { - bzero(end, (size_t)(MSPROXY_MINLENGTH - l)); - l = MSPROXY_MINLENGTH; - } - - if ((w = send(s, request, l, 0)) != l) { -#ifdef DEBUG_MSPROXY - printf ("send_msprequest(): send() failed (%ld bytes sent instead of %Iu\n", w, l); - perror ("Error is"); -#endif - return -1; - } - state->seq_sent = request->sequence; - - return w; -} - -static int -recv_mspresponse(s, state, response) - int s; - struct msproxy_state_t *state; - struct msproxy_response_t *response; -{ - ssize_t r; - - do { - if ((r = recv (s, response, sizeof (*response), 0)) < MSPROXY_MINLENGTH) { -#ifdef DEBUG_MSPROXY - printf ("recv_mspresponse(): expected to read atleast %d, read %ld\n", MSPROXY_MINLENGTH, r); -#endif - return -1; - } - if (state->seq_recv == 0) - break; /* not started incrementing yet. */ -#ifdef DEBUG_MSPROXY - if (response->sequence == state->seq_recv) - printf ("seq_recv: %d, dup response, seqnumber: 0x%x\n", state->seq_recv, response->sequence); -#endif - } while (response->sequence == state->seq_recv); - - state->seq_recv = response->sequence; - - return r; -} - -int -traverse_msproxy (int sok, char *serverAddr, int port, struct msproxy_state_t *state, netstore *ns_proxy, int csok4, int csok6, int *csok, char bound) -{ - struct msproxy_request_t req; - struct msproxy_response_t res; - char *data, *p; - char hostname[NT_MAXNAMELEN]; - char ntdomain[NT_MAXNAMELEN]; - char challenge[8]; - netstore *ns_client; - int clientport; - guint32 destaddr; - guint32 flags; - - if (!prefs.hex_net_proxy_auth || !prefs.hex_net_proxy_user[0] || !prefs.hex_net_proxy_pass[0] ) - return 1; - - /* MS proxy protocol implementation currently doesn't support IPv6 */ - destaddr = net_getsockaddr_v4 (ns_proxy); - if (!destaddr) - return 1; - - state->seq_recv = 0; - state->seq_sent = 0; - -#ifdef DEBUG_MSPROXY - printf ("Connecting to %s:%d via MS proxy\n", serverAddr, port); -#endif - - gethostname (hostname, NT_MAXNAMELEN); - p = strchr (hostname, '.'); - if (p) - *p = '\0'; - - bzero (&req, sizeof(req)); - req.clientid = htonl(0x0a000000); /* Initial client ID is always 0x0a */ - req.command = htons(MSPROXY_HELLO); /* HELLO command */ - req.packet.hello.magic5 = htons(0x4b00); /* Fill in magic values */ - req.packet.hello.magic10 = htons(0x1400); - req.packet.hello.magic15 = htons(0x0400); - req.packet.hello.magic20 = htons(0x5704); - req.packet.hello.magic25 = htons(0x0004); - req.packet.hello.magic30 = htons(0x0100); - req.packet.hello.magic35 = htons(0x4a02); - req.packet.hello.magic40 = htons(0x3000); - req.packet.hello.magic45 = htons(0x4400); - req.packet.hello.magic50 = htons(0x3900); - data = req.packet.hello.data; - strcpy (data, prefs.hex_net_proxy_user); /* Append a username */ - data += strlen (prefs.hex_net_proxy_user)+2; /* +2 automatically creates second empty string */ - strcpy (data, MSPROXY_EXECUTABLE); /* Append an application name */ - data += strlen (MSPROXY_EXECUTABLE)+1; - strcpy (data, hostname); /* Append a hostname */ - data += strlen (hostname)+1; - - if (send_msprequest(sok, state, &req, data) == -1) - return 1; - - if (recv_mspresponse(sok, state, &res) == -1) - return 1; - - if (strcmp(res.RWSP, "RWSP") != 0) { -#ifdef DEBUG_MSPROXY - printf ("Received mailformed packet (no RWSP signature)\n"); -#endif - return 1; - } - - if (ntohs(res.command) >> 8 != 0x10) { -#ifdef DEBUG_MSPROXY - printf ("expected res.command = 10??, is %x", ntohs(res.command)); -#endif - return 1; - } - - state->clientid = htonl(rand()); - state->serverid = res.serverid; - -#ifdef DEBUG_MSPROXY - printf ("clientid: 0x%x, serverid: 0x%0x\n", state->clientid, state->serverid); - printf ("packet #2\n"); -#endif - - /* almost identical. */ - req.clientid = state->clientid; - req.serverid = state->serverid; - - if (send_msprequest(sok, state, &req, data) == -1) - return 1; - - if (recv_mspresponse(sok, state, &res) == -1) - return 1; - - if (res.serverid != state->serverid) { -#ifdef DEBUG_MSPROXY - printf ("expected serverid = 0x%x, is 0x%x\n",state->serverid, res.serverid); -#endif - return 1; - } - - if (res.sequence != 0x01) { -#ifdef DEBUG_MSPROXY - printf ("expected res.sequence = 0x01, is 0x%x\n", res.sequence); -#endif - return 1; - } - - if (ntohs(res.command) != MSPROXY_USERINFO_ACK) { -#ifdef DEBUG_MSPROXY - printf ("expected res.command = 0x%x, is 0x%x\n", MSPROXY_USERINFO_ACK, ntohs(res.command)); -#endif - return 1; - } - -#ifdef DEBUG_MSPROXY - printf ("packet #3\n"); -#endif - - bzero(&req, sizeof(req)); - req.clientid = state->clientid; - req.serverid = state->serverid; - req.command = htons(MSPROXY_AUTHENTICATE); - memcpy(req.packet.auth.NTLMSSP, "NTLMSSP", sizeof("NTLMSSP")); - req.packet.auth.bindaddr = htonl(0x02000000); - req.packet.auth.msgtype = htonl(0x01000000); - /* NTLM flags: 0x80000000 Negotiate LAN Manager key - 0x10000000 Negotiate sign - 0x04000000 Request target - 0x02000000 Negotiate OEM - 0x00800000 Always sign - 0x00020000 Negotiate NTLM - */ - req.packet.auth.flags = htonl(0x06020000); - - if (send_msprequest(sok, state, &req, &req.packet.auth.data) == -1) - return 1; - - if (recv_mspresponse(sok, state, &res) == -1) - return 1; - - if (res.serverid != state->serverid) { -#ifdef DEBUG_MSPROXY - printf ("expected serverid = 0x%x, is 0x%x\n", state->serverid, res.serverid); -#endif - return 1; - } - - if (ntohs(res.command) != MSPROXY_AUTHENTICATE_ACK) { -#ifdef DEBUG_MSPROXY - printf ("expected res.command = 0x%x, is 0x%x\n", MSPROXY_AUTHENTICATE_ACK, ntohs(res.command)); -#endif - return 1; - } - - flags = res.packet.auth.flags & htonl(0x00020000); /* Remember if the server supports NTLM */ - memcpy(challenge, &res.packet.auth.challenge, sizeof(challenge)); - memcpy(ntdomain, &res.packet.auth.NTLMSSP[res.packet.auth.target.offset], res.packet.auth.target.len); - ntdomain[res.packet.auth.target.len] = 0; - -#ifdef DEBUG_MSPROXY - printf ("ntdomain: \"%s\"\n", ntdomain); - printf ("packet #4\n"); -#endif - - bzero(&req, sizeof(req)); - req.clientid = state->clientid; - req.serverid = state->serverid; - req.command = htons(MSPROXY_AUTHENTICATE_2); /* Authentication response */ - req.packet.auth2.magic3 = htons(0x0200); /* Something */ - memcpy(req.packet.auth2.NTLMSSP, "NTLMSSP", sizeof("NTLMSSP")); /* Start of NTLM message */ - req.packet.auth2.msgtype = htonl(0x03000000); /* Message type 2 */ - req.packet.auth2.flags = flags | htonl(0x02000000); /* Choose authentication method */ - data = req.packet.auth2.data; - if (flags) { - req.packet.auth2.lm_resp.len = 0; /* We are here if NTLM is supported, */ - req.packet.auth2.lm_resp.alloc = 0; /* Do not fill in insecure LM response */ - req.packet.auth2.lm_resp.offset = data - req.packet.auth2.NTLMSSP; - req.packet.auth2.ntlm_resp.len = 24; /* Fill in NTLM response security buffer */ - req.packet.auth2.ntlm_resp.alloc = 24; - req.packet.auth2.ntlm_resp.offset = data - req.packet.auth2.NTLMSSP; - ntlm_smb_nt_encrypt(prefs.hex_net_proxy_pass, challenge, data); /* Append an NTLM response */ - data += 24; - } else { - req.packet.auth2.lm_resp.len = 24; /* Fill in LM response security buffer */ - req.packet.auth2.lm_resp.alloc = 24; - req.packet.auth2.lm_resp.offset = data - req.packet.auth2.NTLMSSP; - ntlm_smb_encrypt(prefs.hex_net_proxy_pass, challenge, data); /* Append an LM response */ - data += 24; - req.packet.auth2.ntlm_resp.len = 0; /* NTLM response is empty */ - req.packet.auth2.ntlm_resp.alloc = 0; - req.packet.auth2.ntlm_resp.offset = data - req.packet.auth2.NTLMSSP; - } - req.packet.auth2.ntdomain_buf.len = strlen(ntdomain); /* Domain name */ - req.packet.auth2.ntdomain_buf.alloc = req.packet.auth2.ntdomain_buf.len; - req.packet.auth2.ntdomain_buf.offset = data - req.packet.auth2.NTLMSSP; - strcpy(data, ntdomain); - data += req.packet.auth2.ntdomain_buf.len; - req.packet.auth2.username_buf.len = strlen(prefs.hex_net_proxy_user); /* Username */ - req.packet.auth2.username_buf.alloc = req.packet.auth2.username_buf.len; - req.packet.auth2.username_buf.offset = data - req.packet.auth2.NTLMSSP; - strcpy(data, prefs.hex_net_proxy_user); - data += req.packet.auth2.username_buf.len; - req.packet.auth2.clienthost_buf.len = strlen(hostname); /* Hostname */ - req.packet.auth2.clienthost_buf.alloc = req.packet.auth2.clienthost_buf.len; - req.packet.auth2.clienthost_buf.offset = data - req.packet.auth2.NTLMSSP; - strcpy(data, hostname); - data += req.packet.auth2.clienthost_buf.len; - req.packet.auth2.sessionkey_buf.len = 0; /* Session key (we don't use it) */ - req.packet.auth2.sessionkey_buf.alloc = 0; - req.packet.auth2.sessionkey_buf.offset = data - req.packet.auth2.NTLMSSP; - - if (send_msprequest(sok, state, &req, data) == -1) - return 1; - - if (recv_mspresponse(sok, state, &res) == -1) - return 1; - - if (res.serverid != state->serverid) { -#ifdef DEBUG_MSPROXY - printf ("expected res.serverid = 0x%x, is 0x%x\n", state->serverid, res.serverid); -#endif - return 1; - } - - if (res.clientack != 0x01) { -#ifdef DEBUG_MSPROXY - printf ("expected res.clientack = 0x01, is 0x%x\n", res.clientack); -#endif - return 1; - } - - if (ntohs(res.command) >> 8 != 0x47) { -#ifdef DEBUG_MSPROXY - printf ("expected res.command = 47??, is 0x%x\n", ntohs(res.command)); -#endif - return 1; - } - - if (ntohs(res.command) == MSPROXY_AUTHENTICATE_2_NAK) { -#ifdef DEBUG_MSPROXY - printf ("Authentication failed\n"); -#endif - return -1; - } - -#ifdef DEBUG_MSPROXY - printf ("packet #5\n"); -#endif - - bzero(&req, sizeof(req)); - req.clientid = state->clientid; - req.serverid = state->serverid; - req.command = htons(MSPROXY_CONNECT); - req.packet.connect.magic2 = htons(0x0200); - req.packet.connect.magic6 = htons(0x0200); - req.packet.connect.destport = htons(port); - req.packet.connect.destaddr = destaddr; - data = req.packet.connect.executable; - strcpy(data, MSPROXY_EXECUTABLE); - data += strlen(MSPROXY_EXECUTABLE) + 1; - - /* - * need to tell server what port we will connect from, so we bind our sockets. - */ - ns_client = net_store_new (); - if (!bound) { - net_store_fill_any (ns_client); - net_bind(ns_client, csok4, csok6); -#ifdef DEBUG_MSPROXY - perror ("bind() result"); -#endif - } - clientport = net_getsockport(csok4, csok6); - if (clientport == -1) { -#ifdef DEBUG_MSPROXY - printf ("Unable to obtain source port\n"); -#endif - return 1; - } - req.packet.connect.srcport = clientport; - - if (send_msprequest(sok, state, &req, data) == -1) - return 1; - - if (recv_mspresponse(sok, state, &res) == -1) - return 1; - - if (ntohs(res.command) != MSPROXY_CONNECT_ACK) { -#ifdef DEBUG_MSPROXY - printf ("expected res.command = 0x%x, is 0x%x\n",MSPROXY_CONNECT_ACK, ntohs(res.command)); -#endif - return 1; - } - - net_store_fill_v4 (ns_client, res.packet.connect.clientaddr, res.packet.connect.clientport); - -#ifdef DEBUG_MSPROXY - printf ("Connecting...\n"); -#endif - if (net_connect (ns_client, csok4, csok6, csok) != 0) { -#ifdef DEBUG_MSPROXY - printf ("Failed to connect to port %d\n", htons(res.packet.connect.clientport)); -#endif - net_store_destroy (ns_client); - return 1; - } - net_store_destroy (ns_client); -#ifdef DEBUG_MSPROXY - printf ("packet #6\n"); -#endif - - req.clientid = state->clientid; - req.serverid = state->serverid; - req.command = htons(MSPROXY_USERINFO_ACK); - - if (send_msprequest(sok, state, &req, req.packet.connack.data) == -1) - return 1; - - return 0; -} - -void -msproxy_keepalive (void) -{ - server *serv; - GSList *list = serv_list; - struct msproxy_request_t req; - struct msproxy_response_t res; - - while (list) - { - serv = list->data; - if (serv->connected && (serv->proxy_sok != -1)) - { -#ifdef DEBUG_MSPROXY - printf ("sending MS proxy keepalive packet\n"); -#endif - - bzero(&req, sizeof(req)); - req.clientid = serv->msp_state.clientid; - req.serverid = serv->msp_state.serverid; - req.command = htons(MSPROXY_HELLO); - - if (send_msprequest(serv->proxy_sok, &serv->msp_state, &req, req.packet.hello.data) == -1) - continue; - - recv_mspresponse(serv->proxy_sok, &serv->msp_state, &res); - -#ifdef DEBUG_MSPROXY - if (ntohs(res.command) != MSPROXY_USERINFO_ACK) - printf ("expected res.command = 0x%x, is 0x%x\n", MSPROXY_USERINFO_ACK, ntohs(res.command)); -#endif - } - list = list->next; - } -} - -#endif diff --git a/src/common/msproxy.h b/src/common/msproxy.h deleted file mode 100644 index 4371d704..00000000 --- a/src/common/msproxy.h +++ /dev/null @@ -1,262 +0,0 @@ -/* X-Chat - * Copyright (C) 1998 Peter Zelezny. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - * MS Proxy (ISA server) support is (c) 2006 Pavel Fedin <sonic_amiga@rambler.ru> - * based on Dante source code - * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - * Inferno Nettverk A/S, Norway. All rights reserved. - */ - -#ifndef HEXCHAT_MSPROXY_H -#define HEXCHAT_MSPROXY_H - -#include "network.h" - -#define MSPROXY_EXECUTABLE "hexchat.exe" /* This probably can be used for access control on the server side */ - -#define MSPROXY_MINLENGTH 172 /* minimum length of packet. */ -#define NT_MAXNAMELEN 17 /* maximum name length (domain etc), comes from NetBIOS */ -#define MSPROXY_VERSION 0x00010200 /* MS Proxy v2 ? */ - -/* Commands / responses */ -#define MSPROXY_HELLO 0x0500 /* packet 1 from client. */ -#define MSPROXY_HELLO_ACK 0x1000 /* packet 1 from server. */ - -#define MSPROXY_USERINFO_ACK 0x0400 /* packet 2 from server. */ - -#define MSPROXY_AUTHENTICATE 0x4700 /* authentication request */ -#define MSPROXY_AUTHENTICATE_ACK 0x4714 /* authentication challenge */ - -#define MSPROXY_AUTHENTICATE_2 0x4701 /* authentication response */ -#define MSPROXY_AUTHENTICATE_2_ACK 0x4715 /* authentication passed */ -#define MSPROXY_AUTHENTICATE_2_NAK 0x4716 /* authentication failure */ - -#define MSPROXY_CONNECT 0x071e /* connect request. */ -#define MSPROXY_CONNECT_ACK 0x0703 /* connect request accepted. */ - -#pragma pack(1) - -struct ntlm_buffer { - guint16 len; - guint16 alloc; - guint32 offset; -}; - -struct msproxy_request_t { - guint32 clientid; /* 1-4 */ - guint32 magic25; /* 5-8 */ - guint32 serverid; /* 9-12 */ - unsigned char serverack; /* 13: ack of last server packet */ - char pad10[3]; /* 14-16 */ - unsigned char sequence; /* 17: sequence # of this packet. */ - char pad11[7]; /* 18-24 */ - char RWSP[4]; /* 25-28: 0x52,0x57,0x53,0x50 */ - char pad15[8]; /* 29-36 */ - guint16 command; /* 37-38 */ - - /* packet specifics start at 39. */ - union { - struct { - char pad1[18]; /* 39-56 */ - guint16 magic3; /* 57-58 */ - char pad3[114]; /* 59-172 */ - guint16 magic5; /* 173-174: 0x4b, 0x00 */ - char pad5[2]; /* 175-176 */ - guint16 magic10; /* 177-178: 0x14, 0x00 */ - char pad6[2]; /* 179-180 */ - guint16 magic15; /* 181-182: 0x04, 0x00 */ - char pad10[2]; /* 183-184 */ - guint16 magic16; /* 185-186 */ - char pad11[2]; /* 187-188 */ - guint16 magic20; /* 189-190: 0x57, 0x04 */ - guint16 magic25; /* 191-192: 0x00, 0x04 */ - guint16 magic30; /* 193-194: 0x01, 0x00 */ - char pad20[2]; /* 195-196: 0x4a, 0x02 */ - guint16 magic35; /* 197-198: 0x4a, 0x02 */ - char pad30[10]; /* 199-208 */ - guint16 magic40; /* 209-210: 0x30, 0x00 */ - char pad40[2]; /* 211-212 */ - guint16 magic45; /* 213-214: 0x44, 0x00 */ - char pad45[2]; /* 215-216 */ - guint16 magic50; /* 217-218: 0x39, 0x00 */ - char pad50[2]; /* 219-220 */ - char data[256]; /* 221-EOP: a sequence of NULL-terminated strings: - - username; - - empty string (just a NULL); - - application name; - - hostname */ - } hello; - - struct { - char pad1[4]; /* 39-42 */ - guint16 magic2; /* 43-44 */ - char pad10[12]; /* 45-56 */ - guint32 bindaddr; /* 57-60: address to bind. */ - guint16 bindport; /* 61-62: port to bind. */ - char pad15[2]; /* 63-64 */ - guint16 magic3; /* 65-66 */ - guint16 boundport; /* 67-68 */ - char pad20[104]; /* 69-172 */ - char NTLMSSP[sizeof("NTLMSSP")]; /* 173-180: "NTLMSSP" */ - guint32 msgtype; /* 181-184: NTLM message type = 1 */ - guint32 flags; /* 185-188: NTLM message flags */ - guint16 magic20; /* 189-190: 0x28, 0x00 */ - char pad30[2]; /* 191-192 */ - guint16 magic25; /* 193-194: 0x96, 0x82 */ - guint16 magic30; /* 195-196: 0x01, 0x00 */ - char pad40[12]; /* 197-208 */ - guint16 magic50; /* 209-210: 0x30, 0x00 */ - char pad50[6]; /* 211-216 */ - guint16 magic55; /* 217-218: 0x30, 0x00 */ - char pad55[2]; /* 219-220 */ - char data[0]; /* Dummy end marker, no real data required */ - } auth; - - struct { - char pad1[4]; /* 39-42 */ - guint16 magic1; /* 43-44 */ - guint32 magic2; /* 45-48 */ - char pad2[8]; /* 49-56 */ - guint16 magic3; /* 57-58 */ - char pad3[6]; /* 59-64 */ - guint16 magic4; /* 65-66 */ - guint16 boundport; /* 67-68 */ - char pad4[104]; /* 69-172 */ - char NTLMSSP[sizeof("NTLMSSP")]; /* 173-180: "NTLMSSP" */ - guint32 msgtype; /* 181-184: NTLM message type = 3 */ - struct ntlm_buffer lm_resp; /* 185-192: LM response security buffer */ - struct ntlm_buffer ntlm_resp; /* 193-200: NTLM response security buffer */ - struct ntlm_buffer ntdomain_buf; /* 201-208: domain name security buffer */ - struct ntlm_buffer username_buf; /* 209-216: username security buffer */ - struct ntlm_buffer clienthost_buf; /* 217-224: hostname security buffer */ - struct ntlm_buffer sessionkey_buf; /* 225-232: session key security buffer */ - guint32 flags; /* 233-236: message flags */ - char data[1024]; /* 237-EOP: data area */ - } auth2; - - struct { - guint16 magic1; /* 39-40 */ - char pad1[2]; /* 41-42 */ - guint16 magic2; /* 43-44 */ - guint32 magic3; /* 45-48 */ - char pad5[8]; /* 48-56 */ - guint16 magic6; /* 57-58: 0x0200 */ - guint16 destport; /* 59-60 */ - guint32 destaddr; /* 61-64 */ - char pad10[4]; /* 65-68 */ - guint16 magic10; /* 69-70 */ - char pad15[2]; /* 71-72 */ - guint16 srcport; /* 73-74: port client connects from */ - char pad20[82]; /* 75-156 */ - char executable[256]; /* 76-EOP: application name */ - } connect; - - struct { - guint16 magic1; /* 39-40 */ - char pad5[2]; /* 41-42 */ - guint16 magic5; /* 43-44 */ - guint32 magic10; /* 45-48 */ - char pad10[2]; /* 49-50 */ - guint16 magic15; /* 51-52 */ - guint32 magic16; /* 53-56 */ - guint16 magic20; /* 57-58 */ - guint16 clientport; /* 59-60: forwarded port. */ - guint32 clientaddr; /* 61-64: forwarded address. */ - guint32 magic30; /* 65-68 */ - guint32 magic35; /* 69-72 */ - guint16 serverport; /* 73-74: port server will connect to us from. */ - guint16 srcport; /* 75-76: connect request; port used on client behalf. */ - guint16 boundport; /* 77-78: bind request; port used on client behalf. */ - guint32 boundaddr; /* 79-82: addr used on client behalf */ - char pad30[90]; /* 83-172 */ - char data[0]; /* End marker */ - } connack; - - } packet; -}; - -struct msproxy_response_t { - guint32 packetid; /* 1-4 */ - guint32 magic5; /* 5-8 */ - guint32 serverid; /* 9-12 */ - char clientack; /* 13: ack of last client packet. */ - char pad5[3]; /* 14-16 */ - unsigned char sequence; /* 17: sequence # of this packet. */ - char pad10[7]; /* 18-24 */ - char RWSP[4]; /* 25-28: 0x52,0x57,0x53,0x50 */ - char pad15[8]; /* 29-36 */ - guint16 command; /* 37-38 */ - - union { - struct { - char pad5[18]; /* 39-56 */ - guint16 magic20; /* 57-58: 0x02, 0x00 */ - char pad10[6]; /* 59-64 */ - guint16 magic30; /* 65-66: 0x74, 0x01 */ - char pad15[2]; /* 67-68 */ - guint16 magic35; /* 69-70: 0x0c, 0x00 */ - char pad20[6]; /* 71-76 */ - guint16 magic50; /* 77-78: 0x04, 0x00 */ - char pad30[6]; /* 79-84 */ - guint16 magic60; /* 85-86: 0x65, 0x05 */ - char pad35[2]; /* 87-88 */ - guint16 magic65; /* 89-90: 0x02, 0x00 */ - char pad40[8]; /* 91-98 */ - guint16 udpport; /* 99-100 */ - guint32 udpaddr; /* 101-104 */ - } hello; - - struct { - char pad1[6]; /* 39-44 */ - guint32 magic10; /* 45-48 */ - char pad3[10]; /* 49-58 */ - guint16 boundport; /* 59-60: port server bound for us. */ - guint32 boundaddr; /* 61-64: addr server bound for us. */ - char pad10[4]; /* 65-68 */ - guint16 magic15; /* 69-70 */ - char pad15[102]; /* 70-172 */ - char NTLMSSP[sizeof("NTLMSSP")]; /* 173-180: "NTLMSSP" */ - guint32 msgtype; /* 181-184: NTLM message type = 2 */ - struct ntlm_buffer target; /* 185-192: target security buffer */ - guint32 flags; /* 193-196: NTLM message flags */ - char challenge[8]; /* 197-204: NTLM challenge request */ - char context[8]; /* 205-212: NTLM context */ - char data[1024]; /* 213-EOP: target information data */ - } auth; - - struct { - guint16 magic1; /* 39-40 */ - char pad5[18]; /* 41-58 */ - guint16 clientport; /* 59-60: forwarded port. */ - guint32 clientaddr; /* 61-64: forwarded address. */ - guint32 magic10; /* 65-68 */ - guint32 magic15; /* 69-72 */ - guint16 serverport; /* 73-74: port server will connect to us from. */ - guint16 srcport; /* 75-76: connect request; port used on client behalf. */ - guint16 boundport; /* 77-78: bind request; port used on client behalf. */ - guint32 boundaddr; /* 79-82: addr used on client behalf */ - char pad10[90]; /* 83-172 */ - } connect; - } packet; -}; - -#pragma pack() - -int traverse_msproxy (int sok, char *serverAddr, int port, struct msproxy_state_t *state, netstore *ns_proxy, int csok4, int csok6, int *csok, char bound); -void msproxy_keepalive (void); - -#endif diff --git a/src/common/network.c b/src/common/network.c index 8790f673..fcdaf547 100644 --- a/src/common/network.c +++ b/src/common/network.c @@ -18,6 +18,8 @@ /* ipv4 and ipv6 networking functions with a common interface */ +#include "config.h" + #include <stdlib.h> #include <string.h> #include <stdio.h> @@ -26,7 +28,6 @@ #ifndef WIN32 #include <unistd.h> #endif -#include "../../config.h" #define WANTSOCKET #define WANTARPA @@ -64,128 +65,17 @@ net_ip (guint32 addr) void net_store_destroy (netstore * ns) { -#ifdef USE_IPV6 if (ns->ip6_hostent) freeaddrinfo (ns->ip6_hostent); -#endif - free (ns); + g_free (ns); } netstore * net_store_new (void) { - netstore *ns; - - ns = malloc (sizeof (netstore)); - memset (ns, 0, sizeof (netstore)); - - return ns; -} - -#ifndef USE_IPV6 - -/* =================== IPV4 ================== */ - -/* - A note about net_resolve and lookupd: - - Many IRC networks rely on round-robin DNS for load balancing, rotating the list - of IP address on each query. However, this method breaks when DNS queries are - cached. Mac OS X and Darwin handle DNS lookups through the lookupd daemon, which - caches queries in its default configuration: thus, if we always pick the first - address, we will be stuck with the same host (which might be down!) until the - TTL reaches 0 or lookupd is reset (typically, at reboot). Therefore, we need to - pick a random address from the result list, instead of always using the first. -*/ - -char * -net_resolve (netstore * ns, char *hostname, int port, char **real_host) -{ - ns->ip4_hostent = gethostbyname (hostname); - if (!ns->ip4_hostent) - return NULL; - - memset (&ns->addr, 0, sizeof (ns->addr)); -#ifdef LOOKUPD - int count = 0; - while (ns->ip4_hostent->h_addr_list[count]) count++; - memcpy (&ns->addr.sin_addr, - ns->ip4_hostent->h_addr_list[RAND_INT(count)], - ns->ip4_hostent->h_length); -#else - memcpy (&ns->addr.sin_addr, ns->ip4_hostent->h_addr, - ns->ip4_hostent->h_length); -#endif - ns->addr.sin_port = htons (port); - ns->addr.sin_family = AF_INET; - - *real_host = strdup (ns->ip4_hostent->h_name); - return strdup (inet_ntoa (ns->addr.sin_addr)); -} - -int -net_connect (netstore * ns, int sok4, int sok6, int *sok_return) -{ - *sok_return = sok4; - return connect (sok4, (struct sockaddr *) &ns->addr, sizeof (ns->addr)); -} - -void -net_bind (netstore * tobindto, int sok4, int sok6) -{ - bind (sok4, (struct sockaddr *) &tobindto->addr, sizeof (tobindto->addr)); -} - -void -net_sockets (int *sok4, int *sok6) -{ - *sok4 = socket (AF_INET, SOCK_STREAM, 0); - *sok6 = -1; - net_set_socket_options (*sok4); -} - -void -udp_sockets (int *sok4, int *sok6) -{ - *sok4 = socket (AF_INET, SOCK_DGRAM, 0); - *sok6 = -1; -} - -void -net_store_fill_any (netstore *ns) -{ - ns->addr.sin_family = AF_INET; - ns->addr.sin_addr.s_addr = INADDR_ANY; - ns->addr.sin_port = 0; -} - -void -net_store_fill_v4 (netstore *ns, guint32 addr, int port) -{ - ns->addr.sin_family = AF_INET; - ns->addr.sin_addr.s_addr = addr; - ns->addr.sin_port = port; + return g_new0 (netstore, 1); } -guint32 -net_getsockaddr_v4 (netstore *ns) -{ - return ns->addr.sin_addr.s_addr; -} - -int -net_getsockport (int sok4, int sok6) -{ - struct sockaddr_in addr; - int len = sizeof (addr); - - if (getsockname (sok4, (struct sockaddr *)&addr, &len) == -1) - return -1; - return addr.sin_port; -} - -#else - /* =================== IPV6 ================== */ char * @@ -231,11 +121,11 @@ net_resolve (netstore * ns, char *hostname, int port, char **real_host) ipstring, sizeof (ipstring), NULL, 0, NI_NUMERICHOST); if (ns->ip6_hostent->ai_canonname) - *real_host = strdup (ns->ip6_hostent->ai_canonname); + *real_host = g_strdup (ns->ip6_hostent->ai_canonname); else - *real_host = strdup (hostname); + *real_host = g_strdup (hostname); - return strdup (ipstring); + return g_strdup (ipstring); } /* the only thing making this interface unclean, this shitty sok4, sok6 business */ @@ -298,88 +188,3 @@ udp_sockets (int *sok4, int *sok6) *sok4 = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); *sok6 = socket (AF_INET6, SOCK_DGRAM, IPPROTO_UDP); } - -/* the following functions are used only by MSPROXY and are not - proper ipv6 implementations - do not use in new code! */ - -void -net_store_fill_any (netstore *ns) -{ - struct addrinfo *ai; - struct sockaddr_in *sin; - - ai = ns->ip6_hostent; - if (!ai) { - ai = malloc (sizeof (struct addrinfo)); - memset (ai, 0, sizeof (struct addrinfo)); - ns->ip6_hostent = ai; - } - sin = (struct sockaddr_in *)ai->ai_addr; - if (!sin) { - sin = malloc (sizeof (struct sockaddr_in)); - memset (sin, 0, sizeof (struct sockaddr_in)); - ai->ai_addr = (struct sockaddr *)sin; - } - ai->ai_family = AF_INET; - ai->ai_addrlen = sizeof(struct sockaddr_in); - sin->sin_family = AF_INET; - sin->sin_addr.s_addr = INADDR_ANY; - sin->sin_port = 0; - ai->ai_next = NULL; -} - -void -net_store_fill_v4 (netstore *ns, guint32 addr, int port) -{ - struct addrinfo *ai; - struct sockaddr_in *sin; - - ai = ns->ip6_hostent; - if (!ai) { - ai = malloc (sizeof (struct addrinfo)); - memset (ai, 0, sizeof (struct addrinfo)); - ns->ip6_hostent = ai; - } - sin = (struct sockaddr_in *)ai->ai_addr; - if (!sin) { - sin = malloc (sizeof (struct sockaddr_in)); - memset (sin, 0, sizeof (struct sockaddr_in)); - ai->ai_addr = (struct sockaddr *)sin; - } - ai->ai_family = AF_INET; - ai->ai_addrlen = sizeof(struct sockaddr_in); - sin->sin_family = AF_INET; - sin->sin_addr.s_addr = addr; - sin->sin_port = port; - ai->ai_next = NULL; -} - -guint32 -net_getsockaddr_v4 (netstore *ns) -{ - struct addrinfo *ai; - struct sockaddr_in *sin; - - ai = ns->ip6_hostent; - - while (ai->ai_family != AF_INET) { - ai = ai->ai_next; - if (!ai) - return 0; - } - sin = (struct sockaddr_in *)ai->ai_addr; - return sin->sin_addr.s_addr; -} - -int -net_getsockport (int sok4, int sok6) -{ - struct sockaddr_in addr; - int len = sizeof (addr); - - if (getsockname (sok4, (struct sockaddr *)&addr, &len) == -1) - return -1; - return addr.sin_port; -} - -#endif diff --git a/src/common/network.h b/src/common/network.h index 6a4dce39..8c1c0c79 100644 --- a/src/common/network.h +++ b/src/common/network.h @@ -23,13 +23,8 @@ typedef struct netstore_ { #ifdef NETWORK_PRIVATE -#ifdef USE_IPV6 struct addrinfo *ip6_hostent; #else - struct hostent *ip4_hostent; - struct sockaddr_in addr; -#endif -#else int _dummy; /* some compilers don't like empty structs */ #endif } netstore; @@ -43,11 +38,5 @@ char *net_resolve (netstore *ns, char *hostname, int port, char **real_host); void net_bind (netstore *tobindto, int sok4, int sok6); char *net_ip (guint32 addr); void net_sockets (int *sok4, int *sok6); -/* functions for MSPROXY only! */ -void udp_sockets (int *sok4, int *sok6); -void net_store_fill_any (netstore *ns); -void net_store_fill_v4 (netstore *ns, guint32 addr, int port); -guint32 net_getsockaddr_v4 (netstore *ns); -int net_getsockport(int sok4, int sok6); #endif diff --git a/src/common/notify.c b/src/common/notify.c index bf80a1b5..b5316c36 100644 --- a/src/common/notify.c +++ b/src/common/notify.c @@ -47,7 +47,7 @@ int notify_tag = 0; static char * despacify_dup (char *str) { - char *p, *res = malloc (strlen (str) + 1); + char *p, *res = g_malloc (strlen (str) + 1); p = res; while (1) @@ -70,11 +70,11 @@ notify_netcmp (char *str, void *serv) if (rfc_casecmp (str, net) == 0) { - free (net); + g_free (net); return 0; /* finish & return FALSE from token_foreach() */ } - free (net); + g_free (net); return 1; /* keep going... */ } @@ -111,14 +111,10 @@ notify_find_server_entry (struct notify *notify, struct server *serv) if (!notify_do_network (notify, serv)) return NULL; - servnot = malloc (sizeof (struct notify_per_server)); - if (servnot) - { - memset (servnot, 0, sizeof (struct notify_per_server)); - servnot->server = serv; - servnot->notify = notify; - notify->server_list = g_slist_prepend (notify->server_list, servnot); - } + servnot = g_new0 (struct notify_per_server, 1); + servnot->server = serv; + servnot->notify = notify; + notify->server_list = g_slist_prepend (notify->server_list, servnot); return servnot; } @@ -200,7 +196,7 @@ notify_find (server *serv, char *nick) list = list->next; } - return 0; + return NULL; } static void @@ -247,10 +243,9 @@ notify_announce_online (server * serv, struct notify_per_server *servnot, /* Let's do whois with idle time (like in /quote WHOIS %s %s) */ - char *wii_str = malloc (strlen (nick) * 2 + 2); - sprintf (wii_str, "%s %s", nick, nick); + char *wii_str = g_strdup_printf ("%s %s", nick, nick); serv->p_whois (serv, wii_str); - free (wii_str); + g_free (wii_str); } } @@ -346,9 +341,9 @@ notify_watch (server * serv, char *nick, int add) addchar = '-'; if (serv->supports_monitor) - snprintf (tbuf, sizeof (tbuf), "MONITOR %c %s", addchar, nick); + g_snprintf (tbuf, sizeof (tbuf), "MONITOR %c %s", addchar, nick); else if (serv->supports_watch) - snprintf (tbuf, sizeof (tbuf), "WATCH %c%s", addchar, nick); + g_snprintf (tbuf, sizeof (tbuf), "WATCH %c%s", addchar, nick); else return; @@ -561,9 +556,9 @@ notify_showlist (struct session *sess, const message_tags_data *tags_data) notify = (struct notify *) list->data; servnot = notify_find_server_entry (notify, sess->server); if (servnot && servnot->ison) - snprintf (outbuf, sizeof (outbuf), _(" %-20s online\n"), notify->name); + g_snprintf (outbuf, sizeof (outbuf), _(" %-20s online\n"), notify->name); else - snprintf (outbuf, sizeof (outbuf), _(" %-20s offline\n"), notify->name); + g_snprintf (outbuf, sizeof (outbuf), _(" %-20s offline\n"), notify->name); PrintTextTimeStamp (sess, outbuf, tags_data->timestamp); list = list->next; } @@ -596,14 +591,13 @@ notify_deluser (char *name) servnot = (struct notify_per_server *) notify->server_list->data; notify->server_list = g_slist_remove (notify->server_list, servnot); - free (servnot); + g_free (servnot); } notify_list = g_slist_remove (notify_list, notify); notify_watch_all (notify, FALSE); - if (notify->networks) - free (notify->networks); - free (notify->name); - free (notify); + g_free (notify->networks); + g_free (notify->name); + g_free (notify); fe_notify_update (0); return 1; } @@ -615,27 +609,18 @@ notify_deluser (char *name) void notify_adduser (char *name, char *networks) { - struct notify *notify = malloc (sizeof (struct notify)); - if (notify) - { - memset (notify, 0, sizeof (struct notify)); - if (strlen (name) >= NICKLEN) - { - notify->name = malloc (NICKLEN); - safe_strcpy (notify->name, name, NICKLEN); - } else - { - notify->name = strdup (name); - } - if (networks) - notify->networks = despacify_dup (networks); - notify->server_list = 0; - notify_list = g_slist_prepend (notify_list, notify); - notify_checklist (); - fe_notify_update (notify->name); - fe_notify_update (0); - notify_watch_all (notify, TRUE); - } + struct notify *notify = g_new0 (struct notify, 1); + + notify->name = g_strndup (name, NICKLEN - 1); + + if (networks != NULL) + notify->networks = despacify_dup (networks); + notify->server_list = 0; + notify_list = g_slist_prepend (notify_list, notify); + notify_checklist (); + fe_notify_update (notify->name); + fe_notify_update (0); + notify_watch_all (notify, TRUE); } gboolean @@ -714,7 +699,7 @@ notify_cleanup () { notify->server_list = g_slist_remove (notify->server_list, servnot); - free (servnot); + g_free (servnot); nslist = notify->server_list; } else { diff --git a/src/common/outbound.c b/src/common/outbound.c index 651558ce..a4611927 100644 --- a/src/common/outbound.c +++ b/src/common/outbound.c @@ -90,7 +90,7 @@ random_line (char *file_name) { nofile: /* reason is not a file, an actual reason! */ - return strdup (file_name); + return g_strdup (file_name); } /* count number of lines in file */ @@ -111,7 +111,7 @@ random_line (char *file_name) } while (lines > ran); fclose (fh); - return strdup (buf); + return g_strdup (buf); } void @@ -121,7 +121,7 @@ server_sendpart (server * serv, char *channel, char *reason) { reason = random_line (prefs.hex_irc_part_reason); serv->p_part (serv, channel, reason); - free (reason); + g_free (reason); } else { /* reason set by /quit, /close argument */ @@ -136,12 +136,12 @@ server_sendquit (session * sess) if (!sess->quitreason) { - colrea = strdup (prefs.hex_irc_quit_reason); + colrea = g_strdup (prefs.hex_irc_quit_reason); check_special_chars (colrea, FALSE); rea = random_line (colrea); - free (colrea); + g_free (colrea); sess->server->p_quit (sess->server, rea); - free (rea); + g_free (rea); } else { /* reason set by /quit, /close argument */ @@ -269,7 +269,7 @@ cmd_addserver (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (!network) { network = servlist_net_add (word[2], "", TRUE); - network->encoding = strdup (IRC_DEFAULT_CHARSET); + network->encoding = g_strdup (IRC_DEFAULT_CHARSET); } /* if we had the network already, check if the given server already exists */ else if (servlist_server_find (network, word_eol[3], NULL)) @@ -379,11 +379,10 @@ cmd_away (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (sess->server->last_away_reason != reason) { - if (sess->server->last_away_reason) - free (sess->server->last_away_reason); + g_free (sess->server->last_away_reason); if (reason == word_eol[2]) - sess->server->last_away_reason = strdup (reason); + sess->server->last_away_reason = g_strdup (reason); else sess->server->last_away_reason = reason; } @@ -406,8 +405,7 @@ cmd_back (struct session *sess, char *tbuf, char *word[], char *word_eol[]) PrintText (sess, _("Already marked back.\n")); } - if (sess->server->last_away_reason) - free (sess->server->last_away_reason); + g_free (sess->server->last_away_reason); sess->server->last_away_reason = NULL; return TRUE; @@ -483,19 +481,19 @@ create_mask (session * sess, char *mask, char *mode, char *typestr, int deop) switch (type) { case 0: - snprintf (buf, sizeof (buf), "%s %s *!*@%s.*", mode, p2, domain); + g_snprintf (buf, sizeof (buf), "%s %s *!*@%s.*", mode, p2, domain); break; case 1: - snprintf (buf, sizeof (buf), "%s %s *!*@%s", mode, p2, fullhost); + g_snprintf (buf, sizeof (buf), "%s %s *!*@%s", mode, p2, fullhost); break; case 2: - snprintf (buf, sizeof (buf), "%s %s *!%s@%s.*", mode, p2, username, domain); + g_snprintf (buf, sizeof (buf), "%s %s *!%s@%s.*", mode, p2, username, domain); break; case 3: - snprintf (buf, sizeof (buf), "%s %s *!%s@%s", mode, p2, username, fullhost); + g_snprintf (buf, sizeof (buf), "%s %s *!%s@%s", mode, p2, username, fullhost); break; } } else @@ -503,26 +501,26 @@ create_mask (session * sess, char *mask, char *mode, char *typestr, int deop) switch (type) { case 0: - snprintf (buf, sizeof (buf), "%s %s *!*@*%s", mode, p2, domain); + g_snprintf (buf, sizeof (buf), "%s %s *!*@*%s", mode, p2, domain); break; case 1: - snprintf (buf, sizeof (buf), "%s %s *!*@%s", mode, p2, fullhost); + g_snprintf (buf, sizeof (buf), "%s %s *!*@%s", mode, p2, fullhost); break; case 2: - snprintf (buf, sizeof (buf), "%s %s *!%s@*%s", mode, p2, username, domain); + g_snprintf (buf, sizeof (buf), "%s %s *!%s@*%s", mode, p2, username, domain); break; case 3: - snprintf (buf, sizeof (buf), "%s %s *!%s@%s", mode, p2, username, fullhost); + g_snprintf (buf, sizeof (buf), "%s %s *!%s@%s", mode, p2, username, fullhost); break; } } } else { - snprintf (buf, sizeof (buf), "%s %s", mode, mask); + g_snprintf (buf, sizeof (buf), "%s %s", mode, mask); } return g_strdup (buf); @@ -592,7 +590,6 @@ static int cmd_charset (struct session *sess, char *tbuf, char *word[], char *word_eol[]) { server *serv = sess->server; - const char *locale = NULL; int offset = 0; if (strcmp (word[2], "-quiet") == 0) @@ -600,9 +597,7 @@ cmd_charset (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (!word[2 + offset][0]) { - g_get_charset (&locale); - PrintTextf (sess, "Current charset: %s\n", - serv->encoding ? serv->encoding : locale); + PrintTextf (sess, "Current charset: %s\n", serv->encoding); return TRUE; } @@ -1002,14 +997,14 @@ mdehop_cb (struct User *user, multidata *data) static int cmd_mdehop (struct session *sess, char *tbuf, char *word[], char *word_eol[]) { - char **nicks = malloc (sizeof (char *) * sess->hops); + char **nicks = g_new0 (char *, sess->hops); multidata data; data.nicks = nicks; data.i = 0; tree_foreach (sess->usertree, (tree_traverse_func *)mdehop_cb, &data); send_channel_modes (sess, tbuf, nicks, 0, data.i, '-', 'h', 0); - free (nicks); + g_free (nicks); return TRUE; } @@ -1028,14 +1023,14 @@ mdeop_cb (struct User *user, multidata *data) static int cmd_mdeop (struct session *sess, char *tbuf, char *word[], char *word_eol[]) { - char **nicks = malloc (sizeof (char *) * sess->ops); + char **nicks = g_new0(char *, sess->ops); multidata data; data.nicks = nicks; data.i = 0; tree_foreach (sess->usertree, (tree_traverse_func *)mdeop_cb, &data); send_channel_modes (sess, tbuf, nicks, 0, data.i, '-', 'o', 0); - free (nicks); + g_free (nicks); return TRUE; } @@ -1045,18 +1040,13 @@ GSList *menu_list = NULL; static void menu_free (menu_entry *me) { - free (me->path); - if (me->label) - free (me->label); - if (me->cmd) - free (me->cmd); - if (me->ucmd) - free (me->ucmd); - if (me->group) - free (me->group); - if (me->icon) - free (me->icon); - free (me); + g_free (me->path); + g_free (me->label); + g_free (me->cmd); + g_free (me->ucmd); + g_free (me->group); + g_free (me->icon); + g_free (me); } /* strings equal? but ignore underscores */ @@ -1115,9 +1105,9 @@ menu_del_children (char *path, char *label) if (!label) label = ""; if (path[0]) - snprintf (buf, sizeof (buf), "%s/%s", path, label); + g_snprintf (buf, sizeof (buf), "%s/%s", path, label); else - snprintf (buf, sizeof (buf), "%s", label); + g_snprintf (buf, sizeof (buf), "%s", label); list = menu_list; while (list) @@ -1168,7 +1158,9 @@ menu_is_mainmenu_root (char *path, gint16 *offset) { if (!strncmp (path, menus[i] + 1, menus[i][0])) { - *offset = menus[i][0] + 1; /* number of bytes to offset the root */ + *offset = menus[i][0]; /* number of bytes to offset the root */ + if (path[*offset] != '\0') + *offset += 1; return 0; /* is not main menu */ } } @@ -1193,7 +1185,7 @@ menu_add (char *path, char *label, char *cmd, char *ucmd, int pos, int state, in return; } - me = malloc (sizeof (menu_entry)); + me = g_new (menu_entry, 1); me->pos = pos; me->modifier = mod; me->is_main = menu_is_mainmenu_root (path, &me->root_offset); @@ -1201,31 +1193,26 @@ menu_add (char *path, char *label, char *cmd, char *ucmd, int pos, int state, in me->markup = markup; me->enable = enable; me->key = key; - me->path = strdup (path); + me->path = g_strdup (path); me->label = NULL; me->cmd = NULL; me->ucmd = NULL; me->group = NULL; me->icon = NULL; - if (label) - me->label = strdup (label); - if (cmd) - me->cmd = strdup (cmd); - if (ucmd) - me->ucmd = strdup (ucmd); - if (group) - me->group = strdup (group); - if (icon) - me->icon = strdup (icon); + me->label = g_strdup (label); + me->cmd = g_strdup (cmd); + me->ucmd = g_strdup (ucmd); + me->group = g_strdup (group); + me->icon = g_strdup (icon); menu_list = g_slist_append (menu_list, me); label = fe_menu_add (me); if (label) { /* FE has given us a stripped label */ - free (me->label); - me->label = strdup (label); + g_free (me->label); + me->label = g_strdup (label); g_free (label); /* this is from pango */ } } @@ -1321,7 +1308,7 @@ cmd_menu (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (markup) { char *p; /* to force pango closing tags through */ - for (p = label; *p; p++) + for (p = label; p && *p; p++) if (*p == 3) *p = '/'; } @@ -1454,7 +1441,7 @@ exec_check_process (struct session *sess) { close (sess->running_exec->myfd); fe_input_remove (sess->running_exec->iotag); - free (sess->running_exec); + g_free (sess->running_exec); sess->running_exec = NULL; } } @@ -1531,11 +1518,10 @@ cmd_execw (struct session *sess, char *tbuf, char *word[], char *word_eol[]) return FALSE; } len = strlen(word_eol[2]); - temp = malloc(len + 2); - sprintf(temp, "%s\n", word_eol[2]); + temp = g_strconcat (word_eol[2], "\n", NULL); PrintText(sess, temp); write(sess->running_exec->myfd, temp, len + 1); - free(temp); + g_free(temp); return TRUE; } @@ -1559,7 +1545,7 @@ exec_handle_colors (char *buf, int len) if (strchr (buf, 27) == 0) return; - nbuf = malloc (len + 1); + nbuf = g_malloc (len + 1); while (i < len) { @@ -1653,7 +1639,7 @@ norm: nbuf[j] = buf[i]; nbuf[j] = 0; memcpy (buf, nbuf, j + 1); - free (nbuf); + g_free (nbuf); } #ifndef HAVE_MEMRCHR @@ -1665,7 +1651,7 @@ memrchr (const void *block, int c, size_t size) for (p = (unsigned char *)block + size; p != block; p--) if (*p == c) return p; - return 0; + return NULL; } #endif @@ -1679,14 +1665,14 @@ exec_data (GIOChannel *source, GIOCondition condition, struct nbexec *s) len = s->buffill; if (len) { /* append new data to buffered incomplete line */ - buf = malloc(len + 2050); + buf = g_malloc (len + 2050); memcpy(buf, s->linebuf, len); readpos = buf + len; - free(s->linebuf); + g_free (s->linebuf); s->linebuf = NULL; } else - readpos = buf = malloc(2050); + readpos = buf = g_malloc (2050); rd = read (sok, readpos, 2048); if (rd < 1) @@ -1707,12 +1693,12 @@ exec_data (GIOChannel *source, GIOCondition condition, struct nbexec *s) else PrintText (s->sess, buf); } - free(buf); + g_free(buf); waitpid (s->childpid, NULL, 0); s->sess->running_exec = NULL; fe_input_remove (s->iotag); close (sok); - free (s); + g_free (s); return TRUE; } len += rd; @@ -1725,7 +1711,7 @@ exec_data (GIOChannel *source, GIOCondition condition, struct nbexec *s) rest = buf; if (*rest) { s->buffill = len - (rest - buf); /* = strlen(rest) */ - s->linebuf = malloc(s->buffill + 1); + s->linebuf = g_malloc (s->buffill + 1); memcpy(s->linebuf, rest, s->buffill); *rest = '\0'; len -= s->buffill; /* possibly 0 */ @@ -1741,7 +1727,7 @@ exec_data (GIOChannel *source, GIOCondition condition, struct nbexec *s) PrintText (s->sess, buf); } - free(buf); + g_free (buf); return TRUE; } @@ -1803,8 +1789,7 @@ cmd_exec (struct session *sess, char *tbuf, char *word[], char *word_eol[]) return FALSE; } #endif - s = (struct nbexec *) malloc (sizeof (struct nbexec)); - memset(s, 0, sizeof(*s)); + s = g_new0 (struct nbexec, 1); s->myfd = fds[0]; s->tochannel = tochannel; s->sess = sess; @@ -1851,8 +1836,9 @@ cmd_exec (struct session *sess, char *tbuf, char *word[], char *word_eol[]) PrintText (sess, "Error in fork(2)\n"); close(fds[0]); close(fds[1]); - free (s); - } else + g_free (s); + } + else { /* Parent path */ close(fds[1]); @@ -1940,12 +1926,12 @@ get_bool_cb (int val, getvalinfo *info) { char buf[512]; - snprintf (buf, sizeof (buf), "%s %d", info->cmd, val); + g_snprintf (buf, sizeof (buf), "%s %d", info->cmd, val); if (is_session (info->sess)) handle_command (info->sess, buf, FALSE); - free (info->cmd); - free (info); + g_free (info->cmd); + g_free (info); } static int @@ -1956,8 +1942,8 @@ cmd_getbool (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (!word[4][0]) return FALSE; - info = malloc (sizeof (*info)); - info->cmd = strdup (word[2]); + info = g_new (getvalinfo, 1); + info->cmd = g_strdup (word[2]); info->sess = sess; fe_get_bool (word[3], word_eol[4], get_bool_cb, info); @@ -1972,13 +1958,13 @@ get_int_cb (int cancel, int val, getvalinfo *info) if (!cancel) { - snprintf (buf, sizeof (buf), "%s %d", info->cmd, val); + g_snprintf (buf, sizeof (buf), "%s %d", info->cmd, val); if (is_session (info->sess)) handle_command (info->sess, buf, FALSE); } - free (info->cmd); - free (info); + g_free (info->cmd); + g_free (info); } static int @@ -1989,8 +1975,8 @@ cmd_getint (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (!word[4][0]) return FALSE; - info = malloc (sizeof (*info)); - info->cmd = strdup (word[3]); + info = g_new (getvalinfo, 1); + info->cmd = g_strdup (word[3]); info->sess = sess; fe_get_int (word[4], atoi (word[2]), get_int_cb, info); @@ -2007,13 +1993,13 @@ get_file_cb (char *cmd, char *file) no args */ if (file) { - snprintf (buf, sizeof (buf), "%s %s", cmd, file); + g_snprintf (buf, sizeof (buf), "%s %s", cmd, file); handle_command (current_sess, buf, FALSE); } else { handle_command (current_sess, cmd, FALSE); - free (cmd); + g_free (cmd); } } @@ -2044,7 +2030,7 @@ cmd_getfile (struct session *sess, char *tbuf, char *word[], char *word_eol[]) idx++; } - fe_get_file (word[idx+1], word[idx+2], (void *)get_file_cb, strdup (word[idx]), flags); + fe_get_file (word[idx+1], word[idx+2], (void *)get_file_cb, g_strdup (word[idx]), flags); return TRUE; } @@ -2056,13 +2042,13 @@ get_str_cb (int cancel, char *val, getvalinfo *info) if (!cancel) { - snprintf (buf, sizeof (buf), "%s %s", info->cmd, val); + g_snprintf (buf, sizeof (buf), "%s %s", info->cmd, val); if (is_session (info->sess)) handle_command (info->sess, buf, FALSE); } - free (info->cmd); - free (info); + g_free (info->cmd); + g_free (info); } static int @@ -2073,8 +2059,8 @@ cmd_getstr (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (!word[4][0]) return FALSE; - info = malloc (sizeof (*info)); - info->cmd = strdup (word[3]); + info = g_new (getvalinfo, 1); + info->cmd = g_strdup (word[3]); info->sess = sess; fe_get_str (word[4], word[2], get_str_cb, info); @@ -2200,7 +2186,7 @@ cmd_help (struct session *sess, char *tbuf, char *word[], char *word_eol[]) } else { struct popup *pop; - char *buf = malloc (4096); + char *buf = g_malloc (4096); help_list hl; hl.longfmt = longfmt; @@ -2245,7 +2231,7 @@ cmd_help (struct session *sess, char *tbuf, char *word[], char *word_eol[]) plugin_command_foreach (sess, &hl, (void *)show_help_line); strcat (buf, "\n"); PrintText (sess, buf); - free (buf); + g_free (buf); PrintTextf (sess, "\n%s\n\n", _("Type /HELP <command> for more information, or /HELP -l")); } @@ -2293,7 +2279,7 @@ cmd_ignore (struct session *sess, char *tbuf, char *word[], char *word_eol[]) strchr (mask, '*') == NULL) { mask = tbuf; - snprintf (tbuf, TBUFSIZE, "%s!*@*", word[2]); + g_snprintf (tbuf, TBUFSIZE, "%s!*@*", word[2]); } i = ignore_add (mask, type, TRUE); @@ -2549,7 +2535,7 @@ cmd_load (struct session *sess, char *tbuf, char *word[], char *word_eol[]) PrintText (sess, errorstring (errno)); g_free (buf); } - free (file); + g_free (file); return TRUE; } @@ -2562,7 +2548,7 @@ cmd_load (struct session *sess, char *tbuf, char *word[], char *word_eol[]) file = expand_homedir (word[2]); error = plugin_load (sess, file, arg); - free (file); + g_free (file); if (error) PrintText (sess, error); @@ -2651,7 +2637,7 @@ cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[]) return TRUE; } - snprintf (tbuf, TBUFSIZE, "\001ACTION %s\001\r", act); + g_snprintf (tbuf, TBUFSIZE, "\001ACTION %s\001\r", act); /* first try through DCC CHAT */ if (dcc_write_chat (sess->channel, tbuf)) { @@ -2674,7 +2660,7 @@ cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (*split_text) offset += strlen(split_text); - g_free(split_text); + g_free (split_text); } sess->server->p_action (sess->server, sess->channel, act + offset); @@ -2693,17 +2679,26 @@ cmd_me (struct session *sess, char *tbuf, char *word[], char *word_eol[]) static int cmd_mode (struct session *sess, char *tbuf, char *word[], char *word_eol[]) { - /* +channel channels are dying, let those servers whine about modes. - * return info about current channel if available and no info is given */ - if ((*word[2] == '+') || (*word[2] == 0) || (!is_channel(sess->server, word[2]) && - !(rfc_casecmp(sess->server->nick, word[2]) == 0))) + /* We allow omitting the target, so we have to figure it out: + * - Can only use info from channels or dialogs + * - Empty arg is always sess info + * - Assume + is mode not channel + * - We know valid channels and our nick + * - We cannot easily know if other nick or valid mode (Need to store 004) + */ + if ((sess->type != SESS_CHANNEL && sess->type != SESS_DIALOG) + || (!(*word[2] == '-' || *word[2] == '+' || *word[2] == '\0') + && (is_channel (sess->server, word[2]) || !rfc_casecmp (sess->server->nick, word[2]))) + ) + { + sess->server->p_mode (sess->server, word[2], word_eol[3]); + } + else { if(sess->channel[0] == 0) return FALSE; sess->server->p_mode (sess->server, sess->channel, word_eol[2]); } - else - sess->server->p_mode (sess->server, word[2], word_eol[3]); return TRUE; } @@ -2721,7 +2716,7 @@ mop_cb (struct User *user, multidata *data) static int cmd_mop (struct session *sess, char *tbuf, char *word[], char *word_eol[]) { - char **nicks = malloc (sizeof (char *) * (sess->total - sess->ops)); + char **nicks = g_new0 (char *, sess->total - sess->ops); multidata data; data.nicks = nicks; @@ -2729,7 +2724,7 @@ cmd_mop (struct session *sess, char *tbuf, char *word[], char *word_eol[]) tree_foreach (sess->usertree, (tree_traverse_func *)mop_cb, &data); send_channel_modes (sess, tbuf, nicks, 0, data.i, '+', 'o', 0); - free (nicks); + g_free (nicks); return TRUE; } @@ -2780,7 +2775,7 @@ cmd_msg (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (*split_text) offset += strlen(split_text); - g_free(split_text); + g_free (split_text); } sess->server->p_message (sess->server, nick, msg + offset); offset = 0; @@ -2801,7 +2796,7 @@ cmd_msg (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (*split_text) offset += strlen(split_text); - g_free(split_text); + g_free (split_text); } inbound_chanmsg (newsess->server, NULL, newsess->channel, newsess->server->nick, msg + offset, TRUE, FALSE, @@ -2895,7 +2890,7 @@ cmd_notice (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (*split_text) offset += strlen(split_text); - g_free(split_text); + g_free (split_text); } sess->server->p_notice (sess->server, word[2], text + offset); @@ -2991,7 +2986,7 @@ cmd_ping (struct session *sess, char *tbuf, char *word[], char *word_eol[]) tim = make_ping_time (); - snprintf (timestring, sizeof (timestring), "%lu", tim); + g_snprintf (timestring, sizeof (timestring), "%lu", tim); sess->server->p_ping (sess->server, to, timestring); return TRUE; @@ -3054,7 +3049,7 @@ cmd_query (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if (*split_text) offset += strlen(split_text); - g_free(split_text); + g_free (split_text); } sess->server->p_message (sess->server, nick, msg + offset); inbound_chanmsg (nick_sess->server, nick_sess, nick_sess->channel, @@ -3231,9 +3226,9 @@ cmd_send (struct session *sess, char *tbuf, char *word[], char *word_eol[]) if ((addr & 0xffff0000) == 0xc0a80000 || /* 192.168.x.x */ (addr & 0xff000000) == 0x0a000000) /* 10.x.x.x */ /* we got a private net address, let's PSEND or it'll fail */ - snprintf (tbuf, 512, "DCC PSEND %s", word_eol[2]); + g_snprintf (tbuf, 512, "DCC PSEND %s", word_eol[2]); else - snprintf (tbuf, 512, "DCC SEND %s", word_eol[2]); + g_snprintf (tbuf, 512, "DCC SEND %s", word_eol[2]); handle_command (sess, tbuf, FALSE); @@ -3418,8 +3413,9 @@ cmd_server (struct session *sess, char *tbuf, char *word[], char *word_eol[]) safe_strcpy (serv->password, net->pass, sizeof (serv->password)); serv->loginmethod = net->logintype; } - else /* Otherwise ensure no password is sent */ + else /* Otherwise ensure no password is sent or SASL started */ { + serv->loginmethod = LOGIN_DEFAULT; serv->password[0] = 0; } } @@ -3484,12 +3480,6 @@ cmd_topic (struct session *sess, char *tbuf, char *word[], char *word_eol[]) static int cmd_tray (struct session *sess, char *tbuf, char *word[], char *word_eol[]) { - if (strcmp (word[2], "-b") == 0) - { - fe_tray_set_balloon (word[3], word[4][0] ? word[4] : NULL); - return TRUE; - } - if (strcmp (word[2], "-t") == 0) { fe_tray_set_tooltip (word[3][0] ? word[3] : NULL); @@ -3533,7 +3523,7 @@ cmd_unignore (struct session *sess, char *tbuf, char *word[], if (strchr (mask, '?') == NULL && strchr (mask, '*') == NULL) { mask = tbuf; - snprintf (tbuf, TBUFSIZE, "%s!*@*", word[2]); + g_snprintf (tbuf, TBUFSIZE, "%s!*@*", word[2]); } if (ignore_del (mask, NULL)) @@ -3873,7 +3863,7 @@ const struct commands xc_cmds[] = { N_("ALLCHANL <cmd>, sends a command to all channels on the current server")}, {"ALLSERV", cmd_allservers, 0, 0, 1, N_("ALLSERV <cmd>, sends a command to all servers you're in")}, - {"AWAY", cmd_away, 1, 0, 1, N_("AWAY [<reason>], sets you away")}, + {"AWAY", cmd_away, 1, 0, 1, N_("AWAY [<reason>], sets you away (use /BACK to unset)")}, {"BACK", cmd_back, 1, 0, 1, N_("BACK, sets you back (not away)")}, {"BAN", cmd_ban, 1, 1, 1, N_("BAN <mask> [<bantype>], bans everyone matching the mask from the current channel. If they are already on the channel this doesn't kick them (needs chanop)")}, @@ -4096,7 +4086,7 @@ usercommand_show_help (session *sess, char *name) pop = (struct popup *) list->data; if (!g_ascii_strcasecmp (pop->name, name)) { - snprintf (buf, sizeof(buf), _("User Command for: %s\n"), pop->cmd); + g_snprintf (buf, sizeof(buf), _("User Command for: %s\n"), pop->cmd); PrintText (sess, buf); found = TRUE; @@ -4123,7 +4113,7 @@ help (session *sess, char *tbuf, char *helpcmd, int quiet) { if (cmd->help) { - snprintf (tbuf, TBUFSIZE, _("Usage: %s\n"), _(cmd->help)); + g_snprintf (tbuf, TBUFSIZE, _("Usage: %s\n"), _(cmd->help)); PrintText (sess, tbuf); } else { @@ -4145,7 +4135,7 @@ help (session *sess, char *tbuf, char *helpcmd, int quiet) * - this beast is used for UserCommands, UserlistButtons and CTCP replies */ int -auto_insert (char *dest, int destlen, unsigned char *src, char *word[], +auto_insert (char *dest, gsize destlen, unsigned char *src, char *word[], char *word_eol[], char *a, char *c, char *d, char *e, char *h, char *n, char *s, char *u) { @@ -4217,7 +4207,7 @@ auto_insert (char *dest, int destlen, unsigned char *src, char *word[], switch (src[0]) { case '%': - if ((dest - orig) + 2 >= destlen) + if ((dest - orig) + 2u >= destlen) return 2; dest[0] = '%'; dest[1] = 0; @@ -4252,7 +4242,7 @@ auto_insert (char *dest, int destlen, unsigned char *src, char *word[], case 'y': now = time (0); tm_ptr = localtime (&now); - snprintf (buf, sizeof (buf), "%4d%02d%02d", 1900 + + g_snprintf (buf, sizeof (buf), "%4d%02d%02d", 1900 + tm_ptr->tm_year, 1 + tm_ptr->tm_mon, tm_ptr->tm_mday); utf = buf; break; @@ -4311,81 +4301,78 @@ check_special_chars (char *cmd, int do_ascii) /* check for %X */ if (!len) return; - buf = malloc (len + 1); + buf = g_malloc (len + 1); - if (buf) + while (cmd[j]) { - while (cmd[j]) + switch (cmd[j]) { - switch (cmd[j]) + case '%': + occur++; + if ( do_ascii && + j + 3 < len && + (isdigit ((unsigned char) cmd[j + 1]) && isdigit ((unsigned char) cmd[j + 2]) && + isdigit ((unsigned char) cmd[j + 3]))) { - case '%': - occur++; - if ( do_ascii && - j + 3 < len && - (isdigit ((unsigned char) cmd[j + 1]) && isdigit ((unsigned char) cmd[j + 2]) && - isdigit ((unsigned char) cmd[j + 3]))) + tbuf[0] = cmd[j + 1]; + tbuf[1] = cmd[j + 2]; + tbuf[2] = cmd[j + 3]; + tbuf[3] = 0; + buf[i] = atoi (tbuf); + utf = g_locale_to_utf8 (buf + i, 1, 0, &utf_len, 0); + if (utf) { - tbuf[0] = cmd[j + 1]; - tbuf[1] = cmd[j + 2]; - tbuf[2] = cmd[j + 3]; - tbuf[3] = 0; - buf[i] = atoi (tbuf); - utf = g_locale_to_utf8 (buf + i, 1, 0, &utf_len, 0); - if (utf) - { - memcpy (buf + i, utf, utf_len); - g_free (utf); - i += (utf_len - 1); - } - j += 3; - } else + memcpy (buf + i, utf, utf_len); + g_free (utf); + i += (utf_len - 1); + } + j += 3; + } else + { + switch (cmd[j + 1]) { - switch (cmd[j + 1]) - { - case 'R': - buf[i] = '\026'; - break; - case 'U': - buf[i] = '\037'; - break; - case 'B': - buf[i] = '\002'; - break; - case 'I': - buf[i] = '\035'; - break; - case 'C': - buf[i] = '\003'; - break; - case 'O': - buf[i] = '\017'; - break; - case 'H': /* CL: invisible text code */ - buf[i] = HIDDEN_CHAR; - break; - case '%': - buf[i] = '%'; - break; - default: - buf[i] = '%'; - j--; - break; - } - j++; + case 'R': + buf[i] = '\026'; + break; + case 'U': + buf[i] = '\037'; + break; + case 'B': + buf[i] = '\002'; + break; + case 'I': + buf[i] = '\035'; + break; + case 'C': + buf[i] = '\003'; + break; + case 'O': + buf[i] = '\017'; + break; + case 'H': /* CL: invisible text code */ + buf[i] = HIDDEN_CHAR; + break; + case '%': + buf[i] = '%'; + break; + default: + buf[i] = '%'; + j--; break; - default: - buf[i] = cmd[j]; } + j++; + break; + default: + buf[i] = cmd[j]; } - j++; - i++; } - buf[i] = 0; - if (occur) - strcpy (cmd, buf); - free (buf); + j++; + i++; } + buf[i] = 0; + if (occur) + strcpy (cmd, buf); + g_free (buf); } typedef struct @@ -4408,7 +4395,7 @@ nick_comp_cb (struct User *user, nickdata *data) lenu = strlen (user->nick); if (lenu == data->len) { - snprintf (data->tbuf, TBUFSIZE, "%s%s", user->nick, data->space); + g_snprintf (data->tbuf, TBUFSIZE, "%s%s", user->nick, data->space); data->len = -1; return FALSE; } else if (lenu < data->bestlen) @@ -4452,7 +4439,7 @@ perform_nick_completion (struct session *sess, char *cmd, char *tbuf) if (data.best) { - snprintf (tbuf, TBUFSIZE, "%s%s", data.best->nick, space - 1); + g_snprintf (tbuf, TBUFSIZE, "%s%s", data.best->nick, space - 1); return; } } @@ -4485,12 +4472,10 @@ handle_say (session *sess, char *text, int check_spch) struct DCC *dcc; char *word[PDIWORDS+1]; char *word_eol[PDIWORDS+1]; - char pdibuf_static[1024]; - char newcmd_static[1024]; - char *pdibuf = pdibuf_static; - char *newcmd = newcmd_static; + char *pdibuf; + char *newcmd; int len; - int newcmdlen = sizeof newcmd_static; + int newcmdlen; message_tags_data no_tags = MESSAGE_TAGS_DATA_INIT; if (strcmp (sess->channel, "(lastlog)") == 0) @@ -4500,11 +4485,9 @@ handle_say (session *sess, char *text, int check_spch) } len = strlen (text); - if (len >= sizeof pdibuf_static) - pdibuf = malloc (len + 1); - - if (len + NICKLEN >= newcmdlen) - newcmd = malloc (newcmdlen = len + NICKLEN + 1); + pdibuf = g_malloc (len + 1); + newcmdlen = MAX(len + NICKLEN + 1, TBUFSIZE); + newcmd = g_malloc (newcmdlen); if (check_spch && prefs.hex_input_perc_color) check_special_chars (text, prefs.hex_input_perc_ascii); @@ -4565,7 +4548,7 @@ handle_say (session *sess, char *text, int check_spch) if (*split_text) offset += strlen(split_text); - g_free(split_text); + g_free (split_text); } inbound_chanmsg (sess->server, sess, sess->channel, sess->server->nick, @@ -4577,11 +4560,9 @@ handle_say (session *sess, char *text, int check_spch) } xit: - if (pdibuf != pdibuf_static) - free (pdibuf); + g_free (pdibuf); - if (newcmd != newcmd_static) - free (newcmd); + g_free (newcmd); } char * @@ -4675,8 +4656,6 @@ handle_command (session *sess, char *cmd, int check_spch) char *word_eol[PDIWORDS+1]; static int command_level = 0; struct commands *int_cmd; - char pdibuf_static[1024]; - char tbuf_static[TBUFSIZE]; char *pdibuf; char *tbuf; int len; @@ -4691,23 +4670,8 @@ handle_command (session *sess, char *cmd, int check_spch) /* anything below MUST DEC command_level before returning */ len = strlen (cmd); - if (len >= sizeof (pdibuf_static)) - { - pdibuf = malloc (len + 1); - } - else - { - pdibuf = pdibuf_static; - } - - if ((len * 2) >= sizeof (tbuf_static)) - { - tbuf = malloc ((len * 2) + 1); - } - else - { - tbuf = tbuf_static; - } + pdibuf = g_malloc (len + 1); + tbuf = g_malloc (MAX(TBUFSIZE, (len * 2) + 1)); /* split the text into words and word_eol */ process_data_init (pdibuf, cmd, word, word_eol, TRUE, TRUE); @@ -4786,13 +4750,13 @@ handle_command (session *sess, char *cmd, int check_spch) } else { - /* unknown command, just send it to the server and hope */ if (!sess->server->connected) { - PrintText (sess, _("Unknown Command. Try /help\n")); + PrintTextf (sess, _("Unknown Command %s. Try /help\n"), word[1]); } else { + /* unknown command, just send it to the server and hope */ sess->server->p_raw (sess->server, cmd); } } @@ -4800,15 +4764,8 @@ handle_command (session *sess, char *cmd, int check_spch) xit: command_level--; - if (pdibuf != pdibuf_static) - { - free (pdibuf); - } - - if (tbuf != tbuf_static) - { - free (tbuf); - } + g_free (pdibuf); + g_free (tbuf); return ret; } diff --git a/src/common/outbound.h b/src/common/outbound.h index b9fe6331..490a58ca 100644 --- a/src/common/outbound.h +++ b/src/common/outbound.h @@ -25,7 +25,7 @@ extern const struct commands xc_cmds[]; extern GSList *menu_list; -int auto_insert (char *dest, int destlen, unsigned char *src, char *word[], char *word_eol[], +int auto_insert (char *dest, gsize destlen, unsigned char *src, char *word[], char *word_eol[], char *a, char *c, char *d, char *e, char *h, char *n, char *s, char *u); char *command_insert_vars (session *sess, char *cmd); int handle_command (session *sess, char *cmd, int check_spch); diff --git a/src/common/plugin-identd.c b/src/common/plugin-identd.c new file mode 100644 index 00000000..ce1bd1e6 --- /dev/null +++ b/src/common/plugin-identd.c @@ -0,0 +1,220 @@ +/* HexChat +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA +*/ + +#include "config.h" + +#include <string.h> +#include <gio/gio.h> +#include "hexchat-plugin.h" + +#define _(x) hexchat_gettext(ph,x) + +static hexchat_plugin *ph; +static GSocketService *service; +static GHashTable *responses; + +typedef struct ident_info +{ + GSocketConnection *conn; + gchar *username; + gchar read_buf[16]; +} ident_info; + +static int +identd_cleanup_response_cb (gpointer userdata) +{ + g_return_val_if_fail (responses != NULL, 0); + + g_hash_table_remove (responses, userdata); + + return 0; +} + +static int +identd_command_cb (char *word[], char *word_eol[], void *userdata) +{ + g_return_val_if_fail (responses != NULL, HEXCHAT_EAT_ALL); + + if (service == NULL) /* If we are not running plugins can handle it */ + return HEXCHAT_EAT_HEXCHAT; + + if (word[2] && *word[2] && word[3] && *word[3]) + { + guint64 port = g_ascii_strtoull (word[2], NULL, 0); + + if (port && port <= G_MAXUINT16) + { + g_hash_table_insert (responses, GINT_TO_POINTER (port), g_strdup (word[3])); + /* Automatically remove entry after 30 seconds */ + hexchat_hook_timer (ph, 30000, identd_cleanup_response_cb, GINT_TO_POINTER (port)); + } + } + else + { + hexchat_command (ph, "HELP IDENTD"); + } + + return HEXCHAT_EAT_ALL; +} + +static void +identd_write_ready (GOutputStream *stream, GAsyncResult *res, ident_info *info) +{ + g_output_stream_write_finish (stream, res, NULL); + + g_free (info->username); + g_object_unref (info->conn); + g_free (info); +} + +static void +identd_read_ready (GInputStream *in_stream, GAsyncResult *res, ident_info *info) +{ + GSocketAddress *sok_addr; + GOutputStream *out_stream; + guint64 local, remote; + gchar buf[512], *p; + + if (g_input_stream_read_finish (in_stream, res, NULL)) + { + local = g_ascii_strtoull (info->read_buf, NULL, 0); + p = strchr (info->read_buf, ','); + if (!p) + goto cleanup; + + remote = g_ascii_strtoull (p + 1, NULL, 0); + + if (!local || !remote || local > G_MAXUINT16 || remote > G_MAXUINT16) + goto cleanup; + + info->username = g_strdup (g_hash_table_lookup (responses, GINT_TO_POINTER (local))); + if (!info->username) + goto cleanup; + g_hash_table_remove (responses, GINT_TO_POINTER (local)); + + if ((sok_addr = g_socket_connection_get_remote_address (info->conn, NULL))) + { + GInetAddress *inet_addr; + gchar *addr; + + inet_addr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (sok_addr)); + addr = g_inet_address_to_string (inet_addr); + + hexchat_printf (ph, _("*\tServicing ident request from %s as %s"), addr, info->username); + + g_object_unref (sok_addr); + g_object_unref (inet_addr); + g_free (addr); + } + + g_snprintf (buf, sizeof (buf), "%"G_GUINT16_FORMAT", %"G_GUINT16_FORMAT" : USERID : UNIX : %s\r\n", (guint16)local, (guint16)remote, info->username); + out_stream = g_io_stream_get_output_stream (G_IO_STREAM (info->conn)); + g_output_stream_write_async (out_stream, buf, strlen (buf), G_PRIORITY_DEFAULT, + NULL, (GAsyncReadyCallback)identd_write_ready, info); + } + + return; + +cleanup: + g_object_unref (info->conn); + g_free (info); +} + +static gboolean +identd_incoming_cb (GSocketService *service, GSocketConnection *conn, + GObject *source, gpointer userdata) +{ + GInputStream *stream; + ident_info *info; + + info = g_new0 (ident_info, 1); + + info->conn = conn; + g_object_ref (conn); + + stream = g_io_stream_get_input_stream (G_IO_STREAM (conn)); + g_input_stream_read_async (stream, info->read_buf, sizeof (info->read_buf), G_PRIORITY_DEFAULT, + NULL, (GAsyncReadyCallback)identd_read_ready, info); + + return TRUE; +} + +static void +identd_start_server (void) +{ + GError *error = NULL; + int enabled, port = 113; + + if (hexchat_get_prefs (ph, "identd", NULL, &enabled) == 3) + { + if (!enabled) + return; + } + if (hexchat_get_prefs (ph, "identd_port", NULL, &port) == 2 && (port <= 0 || port > G_MAXUINT16)) + { + port = 113; + } + + service = g_socket_service_new (); + + g_socket_listener_add_inet_port (G_SOCKET_LISTENER (service), port, NULL, &error); + if (error) + { + hexchat_printf (ph, _("*\tError starting identd server: %s"), error->message); + + g_object_unref (service); + service = NULL; + return; + } + /*hexchat_printf (ph, "*\tIdentd listening on port: %d", port); */ + + g_signal_connect (G_OBJECT (service), "incoming", G_CALLBACK(identd_incoming_cb), NULL); + g_socket_service_start (service); +} + +int +identd_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, + char **plugin_desc, char **plugin_version, char *arg) +{ + ph = plugin_handle; + *plugin_name = ""; + *plugin_desc = ""; + *plugin_version = ""; + + + responses = g_hash_table_new_full (NULL, NULL, NULL, g_free); + hexchat_hook_command (ph, "IDENTD", HEXCHAT_PRI_NORM, identd_command_cb, + _("IDENTD <port> <username>"), NULL); + + identd_start_server (); + + return 1; /* This must always succeed for /identd to work */ +} + +int +identd_plugin_deinit (void) +{ + if (service) + { + g_socket_service_stop (service); + g_object_unref (service); + } + + g_hash_table_destroy (responses); + + return 1; +} diff --git a/src/common/plugin-identd.h b/src/common/plugin-identd.h new file mode 100644 index 00000000..5efc2600 --- /dev/null +++ b/src/common/plugin-identd.h @@ -0,0 +1,28 @@ +/* HexChat + * Copyright (C) 1998-2010 Peter Zelezny. + * Copyright (C) 2009-2013 Berke Viktor. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef HEXCHAT_PLUGIN_IDENTD_H +#define HEXCHAT_PLUGIN_IDENTD_H + +int identd_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, + char **plugin_desc, char **plugin_version, char *arg); + +int identd_plugin_deinit (); + +#endif diff --git a/src/common/plugin-timer.c b/src/common/plugin-timer.c index e6944330..d0c82c28 100644 --- a/src/common/plugin-timer.c +++ b/src/common/plugin-timer.c @@ -17,6 +17,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + #include <stdlib.h> #include <string.h> #include <glib.h> @@ -43,7 +45,7 @@ typedef struct char *command; int ref; int repeat; - float timeout; + int timeout; unsigned int forever:1; } timer; @@ -51,9 +53,9 @@ static void timer_del (timer *tim) { timer_list = g_slist_remove (timer_list, tim); - free (tim->command); + g_free (tim->command); hexchat_unhook (ph, tim->hook); - free (tim); + g_free (tim); } static void @@ -99,7 +101,7 @@ timeout_cb (timer *tim) } static void -timer_add (int ref, float timeout, int repeat, char *command) +timer_add (int ref, int timeout, int repeat, char *command) { timer *tim; GSList *list; @@ -117,18 +119,18 @@ timer_add (int ref, float timeout, int repeat, char *command) } } - tim = malloc (sizeof (timer)); + tim = g_new (timer, 1); tim->ref = ref; tim->repeat = repeat; tim->timeout = timeout; - tim->command = strdup (command); + tim->command = g_strdup (command); tim->context = hexchat_get_context (ph); tim->forever = FALSE; if (repeat == 0) tim->forever = TRUE; - tim->hook = hexchat_hook_timer (ph, timeout * 1000.0, (void *)timeout_cb, tim); + tim->hook = hexchat_hook_timer (ph, timeout, (void *)timeout_cb, tim); timer_list = g_slist_append (timer_list, tim); } @@ -150,7 +152,7 @@ timer_showlist (void) while (list) { tim = list->data; - hexchat_printf (ph, _("%5d %8.1f %7d %s\n"), tim->ref, tim->timeout, + hexchat_printf (ph, _("%5d %8.1f %7d %s\n"), tim->ref, tim->timeout / 1000.0f, tim->repeat, tim->command); list = list->next; } @@ -160,7 +162,7 @@ static int timer_cb (char *word[], char *word_eol[], void *userdata) { int repeat = 1; - float timeout; + double timeout; int offset = 0; int ref = 0; int quiet = FALSE; @@ -199,10 +201,10 @@ timer_cb (char *word[], char *word_eol[], void *userdata) timeout = atof (word[2 + offset]); command = word_eol[3 + offset]; - if (timeout < 0.1 || !command[0]) + if (timeout < 0.1 || timeout * 1000 > INT_MAX || !command[0]) hexchat_print (ph, HELP); else - timer_add (ref, timeout, repeat, command); + timer_add (ref, (int) timeout * 1000, repeat, command); return HEXCHAT_EAT_HEXCHAT; } diff --git a/src/common/plugin.c b/src/common/plugin.c index d83b69ff..a397c878 100644 --- a/src/common/plugin.c +++ b/src/common/plugin.c @@ -161,16 +161,12 @@ plugin_free (hexchat_plugin *pl, int do_deinit, int allow_refuse) xit: if (pl->free_strings) { - if (pl->name) - free (pl->name); - if (pl->desc) - free (pl->desc); - if (pl->version) - free (pl->version); + g_free (pl->name); + g_free (pl->desc); + g_free (pl->version); } - if (pl->filename) - free ((char *)pl->filename); - free (pl); + g_free ((char *)pl->filename); + g_free (pl); plugin_list = g_slist_remove (plugin_list, pl); @@ -188,7 +184,7 @@ plugin_list_add (hexchat_context *ctx, char *filename, const char *name, { hexchat_plugin *pl; - pl = malloc (sizeof (hexchat_plugin)); + pl = g_new (hexchat_plugin, 1); pl->handle = handle; pl->filename = filename; pl->context = ctx; @@ -239,9 +235,7 @@ plugin_add (session *sess, char *filename, void *handle, void *init_func, hexchat_plugin *pl; char *file; - file = NULL; - if (filename) - file = strdup (filename); + file = g_strdup (filename); pl = plugin_list_add (sess, file, file, NULL, NULL, handle, deinit_func, fake, FALSE); @@ -361,15 +355,11 @@ plugin_kill_all (void) #ifdef USE_PLUGIN -/* load a plugin from a filename. Returns: NULL-success or an error string */ - -char * -plugin_load (session *sess, char *filename, char *arg) +GModule * +module_load (char *filename) { void *handle; char *filepart; - hexchat_init_func *init_func; - hexchat_deinit_func *deinit_func; char *pluginpath; /* get the filename without path */ @@ -389,6 +379,18 @@ plugin_load (session *sess, char *filename, char *arg) handle = g_module_open (filename, 0); } + return handle; +} + +/* load a plugin from a filename. Returns: NULL-success or an error string */ + +char * +plugin_load (session *sess, char *filename, char *arg) +{ + GModule *handle = module_load (filename); + hexchat_init_func *init_func; + hexchat_deinit_func *deinit_func; + if (handle == NULL) return (char *)g_module_error (); @@ -596,7 +598,7 @@ xit: if (!hook || hook->type == HOOK_DELETED) { hook_list = g_slist_remove (hook_list, hook); - free (hook); + g_free (hook); } list = next; } @@ -615,13 +617,7 @@ plugin_emit_command (session *sess, char *name, char *word[], char *word_eol[]) hexchat_event_attrs * hexchat_event_attrs_create (hexchat_plugin *ph) { - hexchat_event_attrs *attrs; - - attrs = g_malloc (sizeof (*attrs)); - - attrs->server_time_utc = (time_t) 0; - - return attrs; + return g_new0 (hexchat_event_attrs, 1); } void @@ -671,26 +667,31 @@ plugin_emit_dummy_print (session *sess, char *name) } int -plugin_emit_keypress (session *sess, unsigned int state, unsigned int keyval, - int len, char *string) +plugin_emit_keypress (session *sess, unsigned int state, unsigned int keyval, gunichar key) { char *word[PDIWORDS]; char keyval_str[16]; char state_str[16]; char len_str[16]; - int i; + char key_str[7]; + int i, len; if (!hook_list) return 0; sprintf (keyval_str, "%u", keyval); sprintf (state_str, "%u", state); + if (!key) + len = 0; + else + len = g_unichar_to_utf8 (key, key_str); + key_str[len] = '\0'; sprintf (len_str, "%d", len); word[0] = "Key Press"; word[1] = keyval_str; word[2] = state_str; - word[3] = string; + word[3] = key_str; word[4] = len_str; for (i = 5; i < PDIWORDS; i++) word[i] = "\000"; @@ -796,15 +797,11 @@ plugin_add_hook (hexchat_plugin *pl, int type, int pri, const char *name, { hexchat_hook *hook; - hook = malloc (sizeof (hexchat_hook)); - memset (hook, 0, sizeof (hexchat_hook)); - + hook = g_new0 (hexchat_hook, 1); hook->type = type; hook->pri = pri; - if (name) - hook->name = strdup (name); - if (help_text) - hook->help_text = strdup (help_text); + hook->name = g_strdup (name); + hook->help_text = g_strdup (help_text); hook->callback = callb; hook->pl = pl; hook->userdata = userdata; @@ -892,10 +889,8 @@ hexchat_unhook (hexchat_plugin *ph, hexchat_hook *hook) hook->type = HOOK_DELETED; /* expunge later */ - if (hook->name) - free (hook->name); /* NULL for timers & fds */ - if (hook->help_text) - free (hook->help_text); /* NULL for non-commands */ + g_free (hook->name); /* NULL for timers & fds */ + g_free (hook->help_text); /* NULL for non-commands */ return hook->userdata; } @@ -988,8 +983,7 @@ hexchat_printf (hexchat_plugin *ph, const char *format, ...) void hexchat_command (hexchat_plugin *ph, const char *command) { - char *conv; - int len = -1; + char *command_utf8; if (!is_session (ph->context)) { @@ -998,9 +992,9 @@ hexchat_command (hexchat_plugin *ph, const char *command) } /* scripts/plugins continue to send non-UTF8... *sigh* */ - conv = text_validate ((char **)&command, &len); - handle_command (ph->context, (char *)command, FALSE); - g_free (conv); + command_utf8 = text_fixup_invalid_utf8 (command, -1, NULL); + handle_command (ph->context, command_utf8, FALSE); + g_free (command_utf8); } void @@ -1263,8 +1257,7 @@ hexchat_list_get (hexchat_plugin *ph, const char *name) { hexchat_list *list; - list = malloc (sizeof (hexchat_list)); - list->pos = NULL; + list = g_new0 (hexchat_list, 1); switch (str_hash (name)) { @@ -1299,7 +1292,7 @@ hexchat_list_get (hexchat_plugin *ph, const char *name) } /* fall through */ default: - free (list); + g_free (list); return NULL; } @@ -1311,7 +1304,7 @@ hexchat_list_free (hexchat_plugin *ph, hexchat_list *xlist) { if (xlist->type == LIST_USERS) g_slist_free (xlist->head); - free (xlist); + g_free (xlist); } int @@ -1531,7 +1524,14 @@ hexchat_list_int (hexchat_plugin *ph, hexchat_list *xlist, const char *name) case 0x34207553: /* address32 */ return ((struct DCC *)data)->addr; case 0x181a6: /* cps */ - return ((struct DCC *)data)->cps; + { + gint64 cps = ((struct DCC *)data)->cps; + if (cps <= INT_MAX) + { + return (int) cps; + } + return INT_MAX; + } case 0x349881: /* port */ return ((struct DCC *)data)->port; case 0x1b254: /* pos */ @@ -1569,7 +1569,7 @@ hexchat_list_int (hexchat_plugin *ph, hexchat_list *xlist, const char *name) case 0x5cfee87: /* flags */ /* used if text_strip is unset */ /* 16 */ tmp <<= 1; - tmp = ((struct session *)data)->text_strip; /* 15 */ + tmp |= ((struct session *)data)->text_strip; /* 15 */ tmp <<= 1; /* used if text_scrollback is unset */ /* 14 */ tmp <<= 1; @@ -1644,8 +1644,8 @@ hexchat_plugingui_add (hexchat_plugin *ph, const char *filename, const char *version, char *reserved) { #ifdef USE_PLUGIN - ph = plugin_list_add (NULL, strdup (filename), strdup (name), strdup (desc), - strdup (version), NULL, NULL, TRUE, TRUE); + ph = plugin_list_add (NULL, g_strdup (filename), g_strdup (name), g_strdup (desc), + g_strdup (version), NULL, NULL, TRUE, TRUE); fe_pluginlist_update (); #endif @@ -1771,6 +1771,8 @@ hexchat_pluginpref_set_str_real (hexchat_plugin *pl, const char *var, const char { g_free (confname); g_free (confname_tmp); + if (fpIn) + fclose (fpIn); return 0; } else if (fpIn == NULL) /* no previous config file, no parsing */ @@ -1819,7 +1821,7 @@ hexchat_pluginpref_set_str_real (hexchat_plugin *pl, const char *var, const char { prevSetting = 0; - while (fscanf (fpIn, " %[^\n]", line_bufp) != EOF) /* read whole lines including whitespaces */ + while (fscanf (fpIn, " %511[^\n]", line_bufp) != EOF) /* read whole lines including whitespaces */ { buffer_tmp = g_strdup_printf ("%s ", var); /* add one space, this way it works against var - var2 checks too */ @@ -1908,7 +1910,6 @@ hexchat_pluginpref_get_str_real (hexchat_plugin *pl, const char *var, char *dest g_free (confname); return 0; } - g_free (confname); if (!cfg_get_str (cfg, var, buf, sizeof(buf))) @@ -1937,7 +1938,7 @@ hexchat_pluginpref_set_int (hexchat_plugin *pl, const char *var, int value) { char buffer[12]; - snprintf (buffer, sizeof (buffer), "%d", value); + g_snprintf (buffer, sizeof (buffer), "%d", value); return hexchat_pluginpref_set_str_real (pl, var, buffer, 1); } diff --git a/src/common/plugin.h b/src/common/plugin.h index cd3f70a8..5743f39a 100644 --- a/src/common/plugin.h +++ b/src/common/plugin.h @@ -163,6 +163,7 @@ struct _hexchat_plugin }; #endif +GModule *module_load (char *filename); char *plugin_load (session *sess, char *filename, char *arg); int plugin_reload (session *sess, char *name, int by_filename); void plugin_add (session *sess, char *filename, void *handle, void *init_func, void *deinit_func, char *arg, int fake); @@ -174,7 +175,7 @@ int plugin_emit_server (session *sess, char *name, char *word[], char *word_eol[ time_t server_time); int plugin_emit_print (session *sess, char *word[], time_t server_time); int plugin_emit_dummy_print (session *sess, char *name); -int plugin_emit_keypress (session *sess, unsigned int state, unsigned int keyval, int len, char *string); +int plugin_emit_keypress (session *sess, unsigned int state, unsigned int keyval, gunichar key); GList* plugin_command_list(GList *tmp_list); int plugin_show_help (session *sess, char *cmd); void plugin_command_foreach (session *sess, void *userdata, void (*cb) (session *sess, void *userdata, char *name, char *usage)); diff --git a/src/common/proto-irc.c b/src/common/proto-irc.c index 34b4ece1..d8f15cb5 100644 --- a/src/common/proto-irc.c +++ b/src/common/proto-irc.c @@ -429,7 +429,7 @@ irc_raw (server *serv, char *raw) len = strlen (raw); if (len < sizeof (tbuf) - 3) { - len = snprintf (tbuf, sizeof (tbuf), "%s\r\n", raw); + len = g_snprintf (tbuf, sizeof (tbuf), "%s\r\n", raw); tcp_send_len (serv, tbuf, len); } else { @@ -590,7 +590,7 @@ process_numeric (session * sess, int n, char *tim; char outbuf[64]; - snprintf (outbuf, sizeof (outbuf), + g_snprintf (outbuf, sizeof (outbuf), "%02ld:%02ld:%02ld", idle / 3600, (idle / 60) % 60, idle % 60); if (timestamp == 0) @@ -666,7 +666,6 @@ process_numeric (session * sess, int n, EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANMODES, sess, word[4], word_eol[5], NULL, NULL, 0, tags_data->timestamp); fe_update_mode_buttons (sess, 'c', '-'); - fe_update_mode_buttons (sess, 'r', '-'); fe_update_mode_buttons (sess, 't', '-'); fe_update_mode_buttons (sess, 'n', '-'); fe_update_mode_buttons (sess, 'i', '-'); @@ -816,10 +815,7 @@ process_numeric (session * sess, int n, case 349: /* end of exemption list */ sess = find_channel (serv, word[4]); if (!sess) - { - sess = serv->front_session; goto def; - } if (!fe_ban_list_end (sess, 349)) goto def; break; @@ -844,10 +840,7 @@ process_numeric (session * sess, int n, case 368: sess = find_channel (serv, word[4]); if (!sess) - { - sess = serv->front_session; goto def; - } if (!fe_ban_list_end (sess, 368)) goto def; break; @@ -1355,8 +1348,8 @@ process_named_servermsg (session *sess, char *buf, char *rawname, char *word_eol /* Returns the timezone offset. This should be the same as the variable * "timezone" in time.h, but *BSD doesn't have it. */ -static int -get_timezone(void) +static time_t +get_timezone (void) { struct tm tm_utc, tm_local; time_t t, time_utc, time_local; @@ -1481,13 +1474,10 @@ irc_inline (server *serv, char *buf, int len) char *type, *text; char *word[PDIWORDS+1]; char *word_eol[PDIWORDS+1]; - char pdibuf_static[522]; /* 1 line can potentially be 512*6 in utf8 */ - char *pdibuf = pdibuf_static; + char *pdibuf; message_tags_data tags_data = MESSAGE_TAGS_DATA_INIT; - /* need more than 522? fall back to malloc */ - if (len >= sizeof (pdibuf_static)) - pdibuf = malloc (len + 1); + pdibuf = g_malloc (len + 1); sess = serv->front_session; @@ -1509,7 +1499,7 @@ irc_inline (server *serv, char *buf, int len) handle_message_tags(serv, tags, &tags_data); } - url_check_line (buf, len); + url_check_line (buf); /* split line into words and words_to_end_of_line */ process_data_init (pdibuf, buf, word, word_eol, FALSE, FALSE); @@ -1566,8 +1556,7 @@ irc_inline (server *serv, char *buf, int len) } xit: - if (pdibuf != pdibuf_static) - free (pdibuf); + g_free (pdibuf); } void diff --git a/src/common/server.c b/src/common/server.c index 98785937..8ff81553 100644 --- a/src/common/server.c +++ b/src/common/server.c @@ -21,8 +21,6 @@ * Inferno Nettverk A/S, Norway. All rights reserved. */ -/*#define DEBUG_MSPROXY*/ - #include <stdio.h> #include <string.h> #include <stdlib.h> @@ -63,20 +61,11 @@ #include "ssl.h" #endif -#ifdef USE_MSPROXY -#include "msproxy.h" -#endif - -#ifdef WIN32 -#include "identd.h" -#endif - #ifdef USE_LIBPROXY #include <proxy.h> #endif #ifdef USE_OPENSSL -extern SSL_CTX *ctx; /* hexchat.c */ /* local variables */ static struct session *g_sess = NULL; #endif @@ -97,57 +86,21 @@ extern pxProxyFactory *libproxy_factory; send via SSL. server/dcc both use this function. */ int -tcp_send_real (void *ssl, int sok, char *encoding, int using_irc, char *buf, int len) +tcp_send_real (void *ssl, int sok, GIConv write_converter, char *buf, int len) { int ret; - char *locale; - gsize loc_len; - - if (encoding == NULL) /* system */ - { - locale = NULL; - if (!prefs.utf8_locale) - { - const gchar *charset; - - g_get_charset (&charset); - locale = g_convert_with_fallback (buf, len, charset, "UTF-8", - "?", 0, &loc_len, 0); - } - } else - { - if (using_irc) /* using "IRC" encoding (CP1252/UTF-8 hybrid) */ - /* if all chars fit inside CP1252, use that. Otherwise this - returns NULL and we send UTF-8. */ - locale = g_convert (buf, len, "CP1252", "UTF-8", 0, &loc_len, 0); - else - locale = g_convert_with_fallback (buf, len, encoding, "UTF-8", - "?", 0, &loc_len, 0); - } - if (locale) - { - len = loc_len; + gsize buf_encoded_len; + gchar *buf_encoded = text_convert_invalid (buf, len, write_converter, "?", &buf_encoded_len); #ifdef USE_OPENSSL - if (!ssl) - ret = send (sok, locale, len, 0); - else - ret = _SSL_send (ssl, locale, len); -#else - ret = send (sok, locale, len, 0); -#endif - g_free (locale); - } else - { -#ifdef USE_OPENSSL - if (!ssl) - ret = send (sok, buf, len, 0); - else - ret = _SSL_send (ssl, buf, len); + if (!ssl) + ret = send (sok, buf_encoded, buf_encoded_len, 0); + else + ret = _SSL_send (ssl, buf_encoded, buf_encoded_len); #else - ret = send (sok, buf, len, 0); + ret = send (sok, buf_encoded, buf_encoded_len, 0); #endif - } + g_free (buf_encoded); return ret; } @@ -157,10 +110,9 @@ server_send_real (server *serv, char *buf, int len) { fe_add_rawlog (serv, buf, len, TRUE); - url_check_line (buf, len); + url_check_line (buf); - return tcp_send_real (serv->ssl, serv->sok, serv->encoding, serv->using_irc, - buf, len); + return tcp_send_real (serv->ssl, serv->sok, serv->write_converter, buf, len); } /* new throttling system, uses the same method as the Undernet @@ -213,7 +165,7 @@ tcp_send_queue (server *serv) buf--; serv->outbound_queue = g_slist_remove (serv->outbound_queue, buf); - free (buf); + g_free (buf); list = serv->outbound_queue; } else { @@ -235,7 +187,7 @@ tcp_send_len (server *serv, char *buf, int len) if (!prefs.hex_net_throttle) return server_send_real (serv, buf, len); - dbuf = malloc (len + 2); /* first byte is the priority */ + dbuf = g_malloc (len + 2); /* first byte is the priority */ dbuf[0] = 2; /* pri 2 for most things */ memcpy (dbuf + 1, buf, len); dbuf[len + 1] = 0; @@ -266,12 +218,6 @@ tcp_send_len (server *serv, char *buf, int len) return 1; } -/*int -tcp_send (server *serv, char *buf) -{ - return tcp_send_len (serv, buf, strlen (buf)); -}*/ - void tcp_sendf (server *serv, const char *fmt, ...) { @@ -282,7 +228,7 @@ tcp_sendf (server *serv, const char *fmt, ...) int len; va_start (args, fmt); - len = vsnprintf (send_buf, sizeof (send_buf) - 1, fmt, args); + len = g_vsnprintf (send_buf, sizeof (send_buf) - 1, fmt, args); va_end (args); send_buf[sizeof (send_buf) - 1] = '\0'; @@ -309,103 +255,17 @@ close_socket (int sok) /* handle 1 line of text received from the server */ static void -server_inline (server *serv, char *line, int len) +server_inline (server *serv, char *line, gssize len) { - char *utf_line_allocated = NULL; - - /* Checks whether we're set to use UTF-8 charset */ - if (serv->using_irc || /* 1. using CP1252/UTF-8 Hybrid */ - (serv->encoding == NULL && prefs.utf8_locale) || /* OR 2. using system default->UTF-8 */ - (serv->encoding != NULL && /* OR 3. explicitly set to UTF-8 */ - (g_ascii_strcasecmp (serv->encoding, "UTF8") == 0 || - g_ascii_strcasecmp (serv->encoding, "UTF-8") == 0))) - { - /* The user has the UTF-8 charset set, either via /charset - command or from his UTF-8 locale. Thus, we first try the - UTF-8 charset, and if we fail to convert, we assume - it to be ISO-8859-1 (see text_validate). */ - - utf_line_allocated = text_validate (&line, &len); - - } else - { - /* Since the user has an explicit charset set, either - via /charset command or from his non-UTF8 locale, - we don't fallback to ISO-8859-1 and instead try to remove - errnoeous octets till the string is convertable in the - said charset. */ + gsize len_utf8; + line = text_convert_invalid (line, len, serv->read_converter, unicode_fallback_string, &len_utf8); - const char *encoding = NULL; - - if (serv->encoding != NULL) - encoding = serv->encoding; - else - g_get_charset (&encoding); - - if (encoding != NULL) - { - char *conv_line; /* holds a copy of the original string */ - int conv_len; /* tells g_convert how much of line to convert */ - gsize utf_len; - gsize read_len; - GError *err; - gboolean retry; - - conv_line = g_malloc (len + 1); - memcpy (conv_line, line, len); - conv_line[len] = 0; - conv_len = len; - - /* if CP1255, convert it with the NUL terminator. - Works around SF bug #1122089 */ - if (serv->using_cp1255) - conv_len++; - - do - { - err = NULL; - retry = FALSE; - utf_line_allocated = g_convert_with_fallback (conv_line, conv_len, "UTF-8", encoding, "?", &read_len, &utf_len, &err); - if (err != NULL) - { - if (err->code == G_CONVERT_ERROR_ILLEGAL_SEQUENCE && conv_len > (read_len + 1)) - { - /* Make our best bet by removing the erroneous char. - This will work for casual 8-bit strings with non-standard chars. */ - memmove (conv_line + read_len, conv_line + read_len + 1, conv_len - read_len -1); - conv_len--; - retry = TRUE; - } - g_error_free (err); - } - } while (retry); - - g_free (conv_line); - - /* If any conversion has occured at all. Conversion might fail - due to errors other than invalid sequences, e.g. unknown charset. */ - if (utf_line_allocated != NULL) - { - line = utf_line_allocated; - len = utf_len; - if (serv->using_cp1255 && len > 0) - len--; - } - else - { - /* If all fails, treat as UTF-8 with fallback to ISO-8859-1. */ - utf_line_allocated = text_validate (&line, &len); - } - } - } - - fe_add_rawlog (serv, line, len, FALSE); + fe_add_rawlog (serv, line, len_utf8, FALSE); /* let proto-irc.c handle it */ - serv->p_inline (serv, line, len); + serv->p_inline (serv, line, len_utf8); - if (utf_line_allocated != NULL) /* only if a special copy was allocated */ - g_free (utf_line_allocated); + g_free (line); } /* read data from socket */ @@ -529,7 +389,7 @@ server_close_pipe (int *pipefd) /* see comments below */ { close (pipefd[0]); /* close WRITE end first to cause an EOF on READ */ close (pipefd[1]); /* in giowin32, and end that thread. */ - free (pipefd); + g_free (pipefd); return FALSE; } @@ -562,7 +422,7 @@ server_stopconnecting (server * serv) { /* if we close the pipe now, giowin32 will crash. */ - int *pipefd = malloc (sizeof (int) * 2); + int *pipefd = g_new (int, 2); pipefd[0] = serv->childwrite; pipefd[1] = serv->childread; g_idle_add ((GSourceFunc)server_close_pipe, pipefd); @@ -593,7 +453,7 @@ ssl_cb_info (SSL * s, int where, int ret) return; /* FIXME: make debug level adjustable in serverlist or settings */ -/* snprintf (buf, sizeof (buf), "%s (%d)", SSL_state_string_long (s), where); +/* g_snprintf (buf, sizeof (buf), "%s (%d)", SSL_state_string_long (s), where); if (g_sess) EMIT_SIGNAL (XP_TE_SSLMESSAGE, g_sess, buf, NULL, NULL, NULL, 0); else @@ -613,9 +473,9 @@ ssl_cb_verify (int ok, X509_STORE_CTX * ctx) X509_NAME_oneline (X509_get_issuer_name (ctx->current_cert), issuer, sizeof (issuer)); - snprintf (buf, sizeof (buf), "* Subject: %s", subject); + g_snprintf (buf, sizeof (buf), "* Subject: %s", subject); EMIT_SIGNAL (XP_TE_SSLMESSAGE, g_sess, buf, NULL, NULL, NULL, 0); - snprintf (buf, sizeof (buf), "* Issuer: %s", issuer); + g_snprintf (buf, sizeof (buf), "* Issuer: %s", issuer); EMIT_SIGNAL (XP_TE_SSLMESSAGE, g_sess, buf, NULL, NULL, NULL, 0); return (TRUE); /* always ok */ @@ -627,6 +487,10 @@ ssl_do_connect (server * serv) char buf[128]; g_sess = serv->server_session; + + /* Set SNI hostname before connect */ + SSL_set_tlsext_host_name(serv->ssl, serv->hostname); + if (SSL_connect (serv->ssl) <= 0) { char err_buf[128]; @@ -636,7 +500,7 @@ ssl_do_connect (server * serv) if ((err = ERR_get_error ()) > 0) { ERR_error_string (err, err_buf); - snprintf (buf, sizeof (buf), "(%d) %s", err, err_buf); + g_snprintf (buf, sizeof (buf), "(%d) %s", err, err_buf); EMIT_SIGNAL (XP_TE_CONNFAIL, serv->server_session, buf, NULL, NULL, NULL, 0); @@ -662,59 +526,59 @@ ssl_do_connect (server * serv) if (!_SSL_get_cert_info (&cert_info, serv->ssl)) { - snprintf (buf, sizeof (buf), "* Certification info:"); + g_snprintf (buf, sizeof (buf), "* Certification info:"); EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, 0); - snprintf (buf, sizeof (buf), " Subject:"); + g_snprintf (buf, sizeof (buf), " Subject:"); EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, 0); for (i = 0; cert_info.subject_word[i]; i++) { - snprintf (buf, sizeof (buf), " %s", cert_info.subject_word[i]); + g_snprintf (buf, sizeof (buf), " %s", cert_info.subject_word[i]); EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, 0); } - snprintf (buf, sizeof (buf), " Issuer:"); + g_snprintf (buf, sizeof (buf), " Issuer:"); EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, 0); for (i = 0; cert_info.issuer_word[i]; i++) { - snprintf (buf, sizeof (buf), " %s", cert_info.issuer_word[i]); + g_snprintf (buf, sizeof (buf), " %s", cert_info.issuer_word[i]); EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, 0); } - snprintf (buf, sizeof (buf), " Public key algorithm: %s (%d bits)", + g_snprintf (buf, sizeof (buf), " Public key algorithm: %s (%d bits)", cert_info.algorithm, cert_info.algorithm_bits); EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, 0); /*if (cert_info.rsa_tmp_bits) { - snprintf (buf, sizeof (buf), + g_snprintf (buf, sizeof (buf), " Public key algorithm uses ephemeral key with %d bits", cert_info.rsa_tmp_bits); EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, 0); }*/ - snprintf (buf, sizeof (buf), " Sign algorithm %s", + g_snprintf (buf, sizeof (buf), " Sign algorithm %s", cert_info.sign_algorithm/*, cert_info.sign_algorithm_bits*/); EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, 0); - snprintf (buf, sizeof (buf), " Valid since %s to %s", + g_snprintf (buf, sizeof (buf), " Valid since %s to %s", cert_info.notbefore, cert_info.notafter); EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, 0); } else { - snprintf (buf, sizeof (buf), " * No Certificate"); + g_snprintf (buf, sizeof (buf), " * No Certificate"); EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, 0); } chiper_info = _SSL_get_cipher_info (serv->ssl); /* static buffer */ - snprintf (buf, sizeof (buf), "* Cipher info:"); + g_snprintf (buf, sizeof (buf), "* Cipher info:"); EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, 0); - snprintf (buf, sizeof (buf), " Version: %s, cipher %s (%u bits)", + g_snprintf (buf, sizeof (buf), " Version: %s, cipher %s (%u bits)", chiper_info->version, chiper_info->chiper, chiper_info->chiper_bits); EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, @@ -724,9 +588,22 @@ ssl_do_connect (server * serv) switch (verify_error) { case X509_V_OK: - /* snprintf (buf, sizeof (buf), "* Verify OK (?)"); */ + { + X509 *cert = SSL_get_peer_certificate (serv->ssl); + int hostname_err; + if ((hostname_err = _SSL_check_hostname(cert, serv->hostname)) != 0) + { + g_snprintf (buf, sizeof (buf), "* Verify E: Failed to validate hostname? (%d)%s", + hostname_err, serv->accept_invalid_cert ? " -- Ignored" : ""); + if (serv->accept_invalid_cert) + EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, 0); + else + goto conn_fail; + } + break; + } + /* g_snprintf (buf, sizeof (buf), "* Verify OK (?)"); */ /* EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, NULL, 0); */ - break; case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: @@ -734,7 +611,7 @@ ssl_do_connect (server * serv) case X509_V_ERR_CERT_HAS_EXPIRED: if (serv->accept_invalid_cert) { - snprintf (buf, sizeof (buf), "* Verify E: %s.? (%d) -- Ignored", + g_snprintf (buf, sizeof (buf), "* Verify E: %s.? (%d) -- Ignored", X509_verify_cert_error_string (verify_error), verify_error); EMIT_SIGNAL (XP_TE_SSLMESSAGE, serv->server_session, buf, NULL, NULL, @@ -742,9 +619,10 @@ ssl_do_connect (server * serv) break; } default: - snprintf (buf, sizeof (buf), "%s.? (%d)", + g_snprintf (buf, sizeof (buf), "%s.? (%d)", X509_verify_cert_error_string (verify_error), verify_error); +conn_fail: EMIT_SIGNAL (XP_TE_CONNFAIL, serv->server_session, buf, NULL, NULL, NULL, 0); @@ -763,7 +641,7 @@ ssl_do_connect (server * serv) { if (serv->ssl->session && serv->ssl->session->time + SSLTMOUT < time (NULL)) { - snprintf (buf, sizeof (buf), "SSL handshake timed out"); + g_snprintf (buf, sizeof (buf), "SSL handshake timed out"); EMIT_SIGNAL (XP_TE_CONNFAIL, serv->server_session, buf, NULL, NULL, NULL, 0); server_cleanup (serv); /* ->connecting = FALSE */ @@ -861,8 +739,8 @@ server_connect_success (server *serv) /* it'll be a memory leak, if connection isn't terminated by server_cleanup() */ - serv->ssl = _SSL_socket (ctx, serv->sok); - if ((err = _SSL_set_verify (ctx, ssl_cb_verify, NULL))) + serv->ssl = _SSL_socket (serv->ctx, serv->sok); + if ((err = _SSL_set_verify (serv->ctx, ssl_cb_verify, NULL))) { EMIT_SIGNAL (XP_TE_CONNFAIL, serv->server_session, err, NULL, NULL, NULL, 0); @@ -894,9 +772,6 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv) char outbuf[512]; char host[100]; char ip[100]; -#ifdef USE_MSPROXY - char *p; -#endif waitline2 (source, tbuf, sizeof tbuf); @@ -911,12 +786,10 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv) closesocket (serv->sok4); if (serv->proxy_sok4 != -1) closesocket (serv->proxy_sok4); -#ifdef USE_IPV6 if (serv->sok6 != -1) closesocket (serv->sok6); if (serv->proxy_sok6 != -1) closesocket (serv->proxy_sok6); -#endif EMIT_SIGNAL (XP_TE_UKNHOST, sess, NULL, NULL, NULL, NULL, 0); if (!servlist_cycle (serv)) if (prefs.hex_net_auto_reconnectonfail) @@ -928,12 +801,10 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv) closesocket (serv->sok4); if (serv->proxy_sok4 != -1) closesocket (serv->proxy_sok4); -#ifdef USE_IPV6 if (serv->sok6 != -1) closesocket (serv->sok6); if (serv->proxy_sok6 != -1) closesocket (serv->proxy_sok6); -#endif EMIT_SIGNAL (XP_TE_CONNFAIL, sess, errorstring (atoi (tbuf)), NULL, NULL, NULL, 0); if (!servlist_cycle (serv)) @@ -945,49 +816,10 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv) waitline2 (source, ip, sizeof ip); waitline2 (source, outbuf, sizeof outbuf); EMIT_SIGNAL (XP_TE_CONNECT, sess, host, ip, outbuf, NULL, 0); -#ifdef WIN32 - if (prefs.hex_identd) - { - if (serv->network && ((ircnet *)serv->network)->user) - { - identd_start (((ircnet *)serv->network)->user); - } - else - { - identd_start (prefs.hex_irc_user_name); - } - } -#else - snprintf (outbuf, sizeof (outbuf), "%s/auth/xchat_auth", - g_get_home_dir ()); - if (access (outbuf, X_OK) == 0) - { - snprintf (outbuf, sizeof (outbuf), "exec -d %s/auth/xchat_auth %s", - g_get_home_dir (), prefs.hex_irc_user_name); - handle_command (serv->server_session, outbuf, FALSE); - } -#endif break; case '4': /* success */ waitline2 (source, tbuf, sizeof (tbuf)); -#ifdef USE_MSPROXY - serv->sok = strtol (tbuf, &p, 10); - if (*p++ == ' ') - { - serv->proxy_sok = strtol (p, &p, 10); - serv->msp_state.clientid = strtol (++p, &p, 10); - serv->msp_state.serverid = strtol (++p, &p, 10); - serv->msp_state.seq_sent = atoi (++p); - } else - serv->proxy_sok = -1; -#ifdef DEBUG_MSPROXY - printf ("Parent got main socket: %d, proxy socket: %d\n", serv->sok, serv->proxy_sok); - printf ("Client ID 0x%08x server ID 0x%08x seq_sent %d\n", serv->msp_state.clientid, serv->msp_state.serverid, serv->msp_state.seq_sent); -#endif -#else serv->sok = atoi (tbuf); -#endif -#ifdef USE_IPV6 /* close the one we didn't end up using */ if (serv->sok == serv->sok4) closesocket (serv->sok6); @@ -1000,7 +832,29 @@ server_read_child (GIOChannel *source, GIOCondition condition, server *serv) else closesocket (serv->proxy_sok4); } -#endif + + { + struct sockaddr addr; + int addr_len = sizeof (addr); + guint16 port; + + if (!getsockname (serv->sok, &addr, &addr_len)) + { + if (addr.sa_family == AF_INET) + port = ntohs(((struct sockaddr_in *)&addr)->sin_port); + else + port = ntohs(((struct sockaddr_in6 *)&addr)->sin6_port); + + g_snprintf (outbuf, sizeof (outbuf), "IDENTD %"G_GUINT16_FORMAT" ", port); + if (serv->network && ((ircnet *)serv->network)->user) + g_strlcat (outbuf, ((ircnet *)serv->network)->user, sizeof (outbuf)); + else + g_strlcat (outbuf, prefs.hex_irc_user_name, sizeof (outbuf)); + + handle_command (serv->server_session, outbuf, FALSE); + } + } + server_connect_success (serv); break; case '5': /* prefs ip discovered */ @@ -1186,7 +1040,7 @@ traverse_socks (int print_fd, int sok, char *serverAddr, int port) if (buf[1] == 90) return 0; - snprintf (buf, sizeof (buf), "SOCKS\tServer reported error %d,%d.\n", buf[0], buf[1]); + g_snprintf (buf, sizeof (buf), "SOCKS\tServer reported error %d,%d.\n", buf[0], buf[1]); proxy_error (print_fd, buf); return 1; } @@ -1270,7 +1124,7 @@ traverse_socks5 (int print_fd, int sok, char *serverAddr, int port) addrlen = strlen (serverAddr); packetlen = 4 + 1 + addrlen + 2; - sc2 = malloc (packetlen); + sc2 = g_malloc (packetlen); sc2[0] = 5; /* version */ sc2[1] = 1; /* command */ sc2[2] = 0; /* reserved */ @@ -1279,7 +1133,7 @@ traverse_socks5 (int print_fd, int sok, char *serverAddr, int port) memcpy (sc2 + 5, serverAddr, addrlen); *((unsigned short *) (sc2 + 5 + addrlen)) = htons (port); send (sok, sc2, packetlen, 0); - free (sc2); + g_free (sc2); /* consume all of the reply */ if (recv (sok, buf, 4, 0) != 4) @@ -1287,9 +1141,9 @@ traverse_socks5 (int print_fd, int sok, char *serverAddr, int port) if (buf[0] != 5 || buf[1] != 0) { if (buf[1] == 2) - snprintf (buf, sizeof (buf), "SOCKS\tProxy refused to connect to host (not allowed).\n"); + g_snprintf (buf, sizeof (buf), "SOCKS\tProxy refused to connect to host (not allowed).\n"); else - snprintf (buf, sizeof (buf), "SOCKS\tProxy failed to connect to host (error %d).\n", buf[1]); + g_snprintf (buf, sizeof (buf), "SOCKS\tProxy failed to connect to host (error %d).\n", buf[1]); proxy_error (print_fd, buf); return 1; } @@ -1322,7 +1176,7 @@ traverse_wingate (int print_fd, int sok, char *serverAddr, int port) { char buf[128]; - snprintf (buf, sizeof (buf), "%s %d\r\n", serverAddr, port); + g_snprintf (buf, sizeof (buf), "%s %d\r\n", serverAddr, port); send (sok, buf, strlen (buf), 0); return 0; @@ -1410,16 +1264,16 @@ traverse_http (int print_fd, int sok, char *serverAddr, int port) char auth_data2[252]; int n, n2; - n = snprintf (buf, sizeof (buf), "CONNECT %s:%d HTTP/1.0\r\n", + n = g_snprintf (buf, sizeof (buf), "CONNECT %s:%d HTTP/1.0\r\n", serverAddr, port); if (prefs.hex_net_proxy_auth) { - n2 = snprintf (auth_data2, sizeof (auth_data2), "%s:%s", + n2 = g_snprintf (auth_data2, sizeof (auth_data2), "%s:%s", prefs.hex_net_proxy_user, prefs.hex_net_proxy_pass); base64_encode (auth_data, auth_data2, n2); - n += snprintf (buf+n, sizeof (buf)-n, "Proxy-Authorization: Basic %s\r\n", auth_data); + n += g_snprintf (buf+n, sizeof (buf)-n, "Proxy-Authorization: Basic %s\r\n", auth_data); } - n += snprintf (buf+n, sizeof (buf)-n, "\r\n"); + n += g_snprintf (buf+n, sizeof (buf)-n, "\r\n"); send (sok, buf, n, 0); n = http_read_line (print_fd, sok, buf, sizeof (buf)); @@ -1439,7 +1293,7 @@ traverse_http (int print_fd, int sok, char *serverAddr, int port) } static int -traverse_proxy (int proxy_type, int print_fd, int sok, char *ip, int port, struct msproxy_state_t *state, netstore *ns_proxy, int csok4, int csok6, int *csok, char bound) +traverse_proxy (int proxy_type, int print_fd, int sok, char *ip, int port, netstore *ns_proxy, int csok4, int csok6, int *csok, char bound) { switch (proxy_type) { @@ -1451,10 +1305,6 @@ traverse_proxy (int proxy_type, int print_fd, int sok, char *ip, int port, struc return traverse_socks5 (print_fd, sok, ip, port); case 4: return traverse_http (print_fd, sok, ip, port); -#ifdef USE_MSPROXY - case 5: - return traverse_msproxy (sok, ip, port, state, ns_proxy, csok4, csok6, csok, bound); -#endif } return 1; @@ -1492,7 +1342,7 @@ server_child (server * serv) local_ip = net_resolve (ns_local, prefs.hex_net_bind_host, 0, &real_hostname); if (local_ip != NULL) { - snprintf (buf, sizeof (buf), "5\n%s\n", local_ip); + g_snprintf (buf, sizeof (buf), "5\n%s\n", local_ip); write (serv->childwrite, buf, strlen (buf)); net_bind (ns_local, serv->sok4, serv->sok6); bound = 1; @@ -1505,10 +1355,8 @@ server_child (server * serv) if (!serv->dont_use_proxy) /* blocked in serverlist? */ { - if (FALSE) - ; #ifdef USE_LIBPROXY - else if (prefs.hex_net_proxy_type == 5) + if (prefs.hex_net_proxy_type == 5) { char **proxy_list; char *url, *proxy; @@ -1532,7 +1380,7 @@ server_child (server * serv) if (proxy_type) { char *c; c = strchr (proxy, ':') + 3; - proxy_host = strdup (c); + proxy_host = g_strdup (c); c = strchr (proxy_host, ':'); *c = '\0'; proxy_port = atoi (c + 1); @@ -1542,12 +1390,12 @@ server_child (server * serv) g_free (url); } #endif - else if (prefs.hex_net_proxy_host[0] && + if (prefs.hex_net_proxy_host[0] && prefs.hex_net_proxy_type > 0 && prefs.hex_net_proxy_use != 2) /* proxy is NOT dcc-only */ { proxy_type = prefs.hex_net_proxy_type; - proxy_host = strdup (prefs.hex_net_proxy_host); + proxy_host = g_strdup (prefs.hex_net_proxy_host); proxy_port = prefs.hex_net_proxy_port; } } @@ -1557,10 +1405,10 @@ server_child (server * serv) /* first resolve where we want to connect to */ if (proxy_type > 0) { - snprintf (buf, sizeof (buf), "9\n%s\n", proxy_host); + g_snprintf (buf, sizeof (buf), "9\n%s\n", proxy_host); write (serv->childwrite, buf, strlen (buf)); ip = net_resolve (ns_server, proxy_host, proxy_port, &real_hostname); - free (proxy_host); + g_free (proxy_host); if (!ip) { write (serv->childwrite, "1\n", 2); @@ -1579,7 +1427,7 @@ server_child (server * serv) goto xit; } } else /* otherwise we can just use the hostname */ - proxy_ip = strdup (hostname); + proxy_ip = g_strdup (hostname); } else { ip = net_resolve (ns_server, hostname, port, &real_hostname); @@ -1591,7 +1439,7 @@ server_child (server * serv) connect_port = port; } - snprintf (buf, sizeof (buf), "3\n%s\n%s\n%d\n", + g_snprintf (buf, sizeof (buf), "3\n%s\n%s\n%d\n", real_hostname, ip, connect_port); write (serv->childwrite, buf, strlen (buf)); @@ -1605,23 +1453,17 @@ server_child (server * serv) if (error != 0) { - snprintf (buf, sizeof (buf), "2\n%d\n", sock_error ()); + g_snprintf (buf, sizeof (buf), "2\n%d\n", sock_error ()); write (serv->childwrite, buf, strlen (buf)); } else { /* connect succeeded */ if (proxy_ip) { - switch (traverse_proxy (proxy_type, serv->childwrite, psok, proxy_ip, port, &serv->msp_state, ns_proxy, serv->sok4, serv->sok6, &sok, bound)) + switch (traverse_proxy (proxy_type, serv->childwrite, psok, proxy_ip, port, ns_proxy, serv->sok4, serv->sok6, &sok, bound)) { case 0: /* success */ -#ifdef USE_MSPROXY - if (!serv->dont_use_proxy && (proxy_type == 5)) - snprintf (buf, sizeof (buf), "4\n%d %d %d %d %d\n", sok, psok, serv->msp_state.clientid, serv->msp_state.serverid, - serv->msp_state.seq_sent); - else -#endif - snprintf (buf, sizeof (buf), "4\n%d\n", sok); /* success */ + g_snprintf (buf, sizeof (buf), "4\n%d\n", sok); /* success */ write (serv->childwrite, buf, strlen (buf)); break; case 1: /* socks traversal failed */ @@ -1630,29 +1472,24 @@ server_child (server * serv) } } else { - snprintf (buf, sizeof (buf), "4\n%d\n", sok); /* success */ + g_snprintf (buf, sizeof (buf), "4\n%d\n", sok); /* success */ write (serv->childwrite, buf, strlen (buf)); } } xit: -#if defined (USE_IPV6) || defined (WIN32) /* this is probably not needed */ net_store_destroy (ns_server); if (ns_proxy) net_store_destroy (ns_proxy); -#endif /* no need to free ip/real_hostname, this process is exiting */ #ifdef WIN32 /* under win32 we use a thread -> shared memory, must free! */ - if (proxy_ip) - free (proxy_ip); - if (ip) - free (ip); - if (real_hostname) - free (real_hostname); + g_free (proxy_ip); + g_free (ip); + g_free (real_hostname); #endif return 0; @@ -1666,9 +1503,9 @@ server_connect (server *serv, char *hostname, int port, int no_login) session *sess = serv->server_session; #ifdef USE_OPENSSL - if (!ctx && serv->use_ssl) + if (!serv->ctx && serv->use_ssl) { - if (!(ctx = _SSL_context_init (ssl_cb_info, FALSE))) + if (!(serv->ctx = _SSL_context_init (ssl_cb_info))) { fprintf (stderr, "_SSL_context_init failed\n"); exit (1); @@ -1711,18 +1548,18 @@ server_connect (server *serv, char *hostname, int port, int no_login) /* first try network specific cert/key */ cert_file = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "certs" G_DIR_SEPARATOR_S "%s.pem", get_xdir (), server_get_network (serv, TRUE)); - if (SSL_CTX_use_certificate_file (ctx, cert_file, SSL_FILETYPE_PEM) == 1) + if (SSL_CTX_use_certificate_file (serv->ctx, cert_file, SSL_FILETYPE_PEM) == 1) { - if (SSL_CTX_use_PrivateKey_file (ctx, cert_file, SSL_FILETYPE_PEM) == 1) + if (SSL_CTX_use_PrivateKey_file (serv->ctx, cert_file, SSL_FILETYPE_PEM) == 1) serv->have_cert = TRUE; } else { /* if that doesn't exist, try <config>/certs/client.pem */ cert_file = g_build_filename (get_xdir (), "certs", "client.pem", NULL); - if (SSL_CTX_use_certificate_file (ctx, cert_file, SSL_FILETYPE_PEM) == 1) + if (SSL_CTX_use_certificate_file (serv->ctx, cert_file, SSL_FILETYPE_PEM) == 1) { - if (SSL_CTX_use_PrivateKey_file (ctx, cert_file, SSL_FILETYPE_PEM) == 1) + if (SSL_CTX_use_PrivateKey_file (serv->ctx, cert_file, SSL_FILETYPE_PEM) == 1) serv->have_cert = TRUE; } } @@ -1754,16 +1591,8 @@ server_connect (server *serv, char *hostname, int port, int no_login) /* create both sockets now, drop one later */ net_sockets (&serv->sok4, &serv->sok6); -#ifdef USE_MSPROXY - /* In case of MS Proxy we have a separate UDP control connection */ - if (!serv->dont_use_proxy && (serv->proxy_type == 5)) - udp_sockets (&serv->proxy_sok4, &serv->proxy_sok6); - else -#endif - { - serv->proxy_sok4 = -1; - serv->proxy_sok6 = -1; - } + serv->proxy_sok4 = -1; + serv->proxy_sok6 = -1; #ifdef WIN32 CloseHandle (CreateThread (NULL, 0, @@ -1815,31 +1644,46 @@ server_set_encoding (server *serv, char *new_encoding) { char *space; - if (serv->encoding) - { - free (serv->encoding); - /* can be left as NULL to indicate system encoding */ - serv->encoding = NULL; - serv->using_cp1255 = FALSE; - serv->using_irc = FALSE; - } + g_free (serv->encoding); if (new_encoding) { - serv->encoding = strdup (new_encoding); + serv->encoding = g_strdup (new_encoding); /* the serverlist GUI might have added a space and short description - remove it. */ space = strchr (serv->encoding, ' '); if (space) space[0] = 0; - /* server_inline() uses these flags */ - if (!g_ascii_strcasecmp (serv->encoding, "CP1255") || - !g_ascii_strcasecmp (serv->encoding, "WINDOWS-1255")) - serv->using_cp1255 = TRUE; - else if (!g_ascii_strcasecmp (serv->encoding, "IRC")) - serv->using_irc = TRUE; + /* Default legacy "IRC" encoding to utf-8. */ + if (g_ascii_strcasecmp (serv->encoding, "IRC") == 0) + { + g_free (serv->encoding); + serv->encoding = g_strdup ("UTF-8"); + } + + else if (!servlist_check_encoding (serv->encoding)) + { + g_free (serv->encoding); + serv->encoding = g_strdup ("UTF-8"); + } + } + else + { + serv->encoding = g_strdup ("UTF-8"); + } + + if (serv->read_converter != NULL) + { + g_iconv_close (serv->read_converter); } + serv->read_converter = g_iconv_open ("UTF-8", serv->encoding); + + if (serv->write_converter != NULL) + { + g_iconv_close (serv->write_converter); + } + serv->write_converter = g_iconv_open (serv->encoding, "UTF-8"); } server * @@ -1848,8 +1692,7 @@ server_new (void) static int id = 0; server *serv; - serv = malloc (sizeof (struct server)); - memset (serv, 0, sizeof (struct server)); + serv = g_new0 (struct server, 1); /* use server.c and proto-irc.c functions */ server_fill_her_up (serv); @@ -1875,19 +1718,17 @@ is_server (server *serv) void server_set_defaults (server *serv) { - if (serv->chantypes) - free (serv->chantypes); - if (serv->chanmodes) - free (serv->chanmodes); - if (serv->nick_prefixes) - free (serv->nick_prefixes); - if (serv->nick_modes) - free (serv->nick_modes); - - serv->chantypes = strdup ("#&!+"); - serv->chanmodes = strdup ("beI,k,l"); - serv->nick_prefixes = strdup ("@%+"); - serv->nick_modes = strdup ("ohv"); + g_free (serv->chantypes); + g_free (serv->chanmodes); + g_free (serv->nick_prefixes); + g_free (serv->nick_modes); + + serv->chantypes = g_strdup ("#&!+"); + serv->chanmodes = g_strdup ("beI,k,l"); + serv->nick_prefixes = g_strdup ("@%+"); + serv->nick_modes = g_strdup ("ohv"); + + server_set_encoding (serv, "UTF-8"); serv->nickcount = 1; serv->end_of_motd = FALSE; @@ -1991,9 +1832,8 @@ server_away_free_messages (server *serv) if (away->server == serv) { away_list = g_slist_remove (away_list, away); - if (away->message) - free (away->message); - free (away); + g_free (away->message); + g_free (away); next = away_list; } list = next; @@ -2007,20 +1847,17 @@ server_away_save_message (server *serv, char *nick, char *msg) if (away) /* Change message for known user */ { - if (away->message) - free (away->message); - away->message = strdup (msg); - } else - /* Create brand new entry */ + g_free (away->message); + away->message = g_strdup (msg); + } + else { - away = malloc (sizeof (struct away_msg)); - if (away) - { - away->server = serv; - safe_strcpy (away->nick, nick, sizeof (away->nick)); - away->message = strdup (msg); - away_list = g_slist_prepend (away_list, away); - } + /* Create brand new entry */ + away = g_new(struct away_msg, 1); + away->server = serv; + safe_strcpy (away->nick, nick, sizeof (away->nick)); + away->message = g_strdup (msg); + away_list = g_slist_prepend (away_list, away); } } @@ -2035,22 +1872,27 @@ server_free (server *serv) serv->flush_queue (serv); server_away_free_messages (serv); - free (serv->nick_modes); - free (serv->nick_prefixes); - free (serv->chanmodes); - free (serv->chantypes); - if (serv->bad_nick_prefixes) - free (serv->bad_nick_prefixes); - if (serv->last_away_reason) - free (serv->last_away_reason); - if (serv->encoding) - free (serv->encoding); + g_free (serv->nick_modes); + g_free (serv->nick_prefixes); + g_free (serv->chanmodes); + g_free (serv->chantypes); + g_free (serv->bad_nick_prefixes); + g_free (serv->last_away_reason); + g_free (serv->encoding); + + g_iconv_close (serv->read_converter); + g_iconv_close (serv->write_converter); + if (serv->favlist) g_slist_free_full (serv->favlist, (GDestroyNotify) servlist_favchan_free); +#ifdef USE_OPENSSL + if (serv->ctx) + _SSL_context_free (serv->ctx); +#endif fe_server_callback (serv); - free (serv); + g_free (serv); notify_cleanup (); } diff --git a/src/common/server.h b/src/common/server.h index 90e9a9c1..ff8ef404 100644 --- a/src/common/server.h +++ b/src/common/server.h @@ -24,9 +24,8 @@ extern GSList *serv_list; /* eventually need to keep the tcp_* functions isolated to server.c */ int tcp_send_len (server *serv, char *buf, int len); -int tcp_send (server *serv, char *buf); void tcp_sendf (server *serv, const char *fmt, ...) G_GNUC_PRINTF (2, 3); -int tcp_send_real (void *ssl, int sok, char *encoding, int using_irc, char *buf, int len); +int tcp_send_real (void *ssl, int sok, GIConv write_converter, char *buf, int len); server *server_new (void); int is_server (server *serv); diff --git a/src/common/servlist.c b/src/common/servlist.c index 7de77596..6f9f9ed2 100644 --- a/src/common/servlist.c +++ b/src/common/servlist.c @@ -45,6 +45,7 @@ struct defaultserver char *charset; int loginmode; /* default authentication type */ char *connectcmd; /* default connect command - should only be used for rare login types, paired with LOGIN_CUSTOM */ + gboolean ssl; }; static const struct defaultserver def[] = @@ -59,20 +60,11 @@ static const struct defaultserver def[] = {"AccessIRC", 0}, {0, "irc.accessirc.net"}, - {0, "eu.accessirc.net"}, {"AfterNET", 0}, {0, "irc.afternet.org"}, - {0, "us.afternet.org"}, - {0, "eu.afternet.org"}, {"Aitvaras", 0}, -#ifdef USE_IPV6 -#ifdef USE_OPENSSL - {0, "irc6.ktu.lt/+7668"}, -#endif - {0, "irc6.ktu.lt/7666"}, -#endif #ifdef USE_OPENSSL {0, "irc.data.lt/+6668"}, {0, "irc.omnitel.net/+6668"}, @@ -86,52 +78,25 @@ static const struct defaultserver def[] = {0, "irc.kis.lt"}, {0, "irc.vub.lt"}, - {"AlphaChat", 0, 0, 0, LOGIN_SASL}, - {0, "irc.alphachat.net"}, - {0, "na.alphachat.net"}, - {0, "eu.alphachat.net"}, - {0, "au.alphachat.net"}, - {0, "za.alphachat.net"}, - - {"Anthrochat", 0}, -#ifdef USE_OPENSSL - {0, "irc.anthrochat.net/+6697"}, -#endif + {"Anthrochat", 0, 0, 0, 0, 0, TRUE}, {0, "irc.anthrochat.net"}, {"ARCNet", 0}, - {0, "se1.arcnet.vapor.com"}, - {0, "us1.arcnet.vapor.com"}, - {0, "us2.arcnet.vapor.com"}, - {0, "us3.arcnet.vapor.com"}, - {0, "ca1.arcnet.vapor.com"}, - {0, "de1.arcnet.vapor.com"}, - {0, "de3.arcnet.vapor.com"}, - {0, "ch1.arcnet.vapor.com"}, - {0, "be1.arcnet.vapor.com"}, - {0, "nl3.arcnet.vapor.com"}, - {0, "uk1.arcnet.vapor.com"}, - {0, "uk2.arcnet.vapor.com"}, - {0, "fr1.arcnet.vapor.com"}, + {0, "arcnet-irc.org"}, + + {"AthemeNet", 0, 0, 0, LOGIN_SASL, 0, TRUE}, + {0, "irc.atheme.org"}, {"AustNet", 0}, - {0, "au.austnet.org"}, - {0, "us.austnet.org"}, + {0, "irc.austnet.org"}, {"AzzurraNet", 0}, {0, "irc.azzurra.org"}, - {0, "crypto.azzurra.org"}, - {"Canternet", 0, 0, 0, LOGIN_SASL}, -#ifdef USE_OPENSSL - {0, "irc.canternet.org/+6697"}, -#endif + {"Canternet", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "irc.canternet.org"}, - {"Chat4all", 0}, -#ifdef USE_OPENSSL - {0, "irc.chat4all.org/+7001"}, -#endif + {"Chat4all", 0, 0, 0, 0, 0, TRUE}, {0, "irc.chat4all.org"}, {"ChattingAway", 0}, @@ -139,26 +104,21 @@ static const struct defaultserver def[] = {"ChatJunkies", 0}, {0, "irc.chatjunkies.org"}, - {0, "nl.chatjunkies.org"}, {"ChatNet", 0}, - {0, "US.ChatNet.Org"}, + {0, "irc.chatnet.org"}, {"ChatSpike", 0}, {0, "irc.chatspike.net"}, {"Criten", 0}, {0, "irc.criten.net"}, - {0, "irc.eu.criten.net"}, {"DALnet", 0}, {0, "irc.dal.net"}, - {0, "irc.eu.dal.net"}, {"Dark-Tou-Net", 0}, {0, "irc.d-t-net.de"}, - {0, "bw.d-t-net.de"}, - {0, "nc.d-t-net.de"}, {"DarkMyst", 0, 0, 0, LOGIN_SASL}, {0, "irc.darkmyst.org"}, @@ -177,66 +137,36 @@ static const struct defaultserver def[] = {0, "irc.lightning.net"}, {0, "irc.servercentral.net"}, - {"ElectroCode", 0}, -#ifdef USE_OPENSSL - - {0, "irc.electrocode.net/+6697"}, -#endif + {"ElectroCode", 0, 0, 0, 0, 0, TRUE}, {0, "irc.electrocode.net"}, {"EnterTheGame", 0}, - {0, "IRC.EnterTheGame.Com"}, + {0, "irc.enterthegame.com"}, - {"EntropyNet", 0, 0, 0, LOGIN_SASL}, -#ifdef USE_OPENSSL - {0, "irc.entropynet.net/+6697"}, -#endif + {"EntropyNet", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "irc.entropynet.net"}, -#ifdef USE_IPV6 -#ifdef USE_OPENSSL - {0, "irc6.entropynet.net/+6697"}, -#endif - {0, "irc6.entropynet.net"}, -#endif - {"EsperNet", 0, 0, 0, LOGIN_SASL}, -#ifdef USE_OPENSSL - {0, "irc.esper.net/+6697"}, -#endif + {"EsperNet", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "irc.esper.net"}, {"EUIrc", 0}, {0, "irc.euirc.net"}, - {0, "irc.ham.de.euirc.net"}, - {0, "irc.ber.de.euirc.net"}, - {0, "irc.ffm.de.euirc.net"}, - {0, "irc.bre.de.euirc.net"}, - {0, "irc.hes.de.euirc.net"}, - {0, "irc.inn.at.euirc.net"}, - {0, "irc.bas.ch.euirc.net"}, {"EuropNet", 0}, {0, "irc.europnet.org"}, {"FDFNet", 0}, {0, "irc.fdfnet.net"}, - {0, "irc.eu.fdfnet.net"}, {"FEFNet", 0, 0, 0, LOGIN_SASL}, {0, "irc.fef.net"}, - {"freenode", 0, 0, 0, LOGIN_SASL}, -#ifdef USE_OPENSSL - {0, "chat.freenode.net/+6697"}, -#endif + {"freenode", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "chat.freenode.net"}, /* irc. points to chat. but many users and urls still reference it */ {0, "irc.freenode.net"}, - {"Furnet", 0}, -#ifdef USE_OPENSSL - {0, "irc.furnet.org/+6697"}, -#endif + {"Furnet", 0, 0, 0, 0, 0, TRUE}, {0, "irc.furnet.org"}, {"GalaxyNet", 0}, @@ -245,18 +175,14 @@ static const struct defaultserver def[] = {"GameSurge", 0}, {0, "irc.gamesurge.net"}, - {"GeeksIRC", 0, 0, 0, LOGIN_SASL}, -#ifdef USE_OPENSSL - {0, "irc.geeksirc.net/+6697"}, -#endif + {"GeeksIRC", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "irc.geeksirc.net"}, {"GeekShed", 0}, {0, "irc.geekshed.net"}, {"German-Elite", 0}, - {0, "dominion.german-elite.net"}, - {0, "komatu.german-elite.net"}, + {0, "irc.german-elite.net"}, {"GIMPNet", 0}, {0, "irc.gimp.org"}, @@ -268,22 +194,13 @@ static const struct defaultserver def[] = {"IdleMonkeys", 0}, {0, "irc.idlemonkeys.net"}, - {"IndirectIRC", 0}, -#ifdef USE_OPENSSL - {0, "irc.indirectirc.com/+6697"}, -#endif + {"IndirectIRC", 0, 0, 0, 0, 0, TRUE}, {0, "irc.indirectirc.com"}, - {"Interlinked", 0, 0, 0, LOGIN_SASL}, -#ifdef USE_OPENSSL - {0, "irc.interlinked.me/+6697"}, -#endif + {"Interlinked", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "irc.interlinked.me"}, - {"IRC4Fun", 0, 0, 0, LOGIN_SASL}, -#ifdef USE_OPENSSL - {0, "irc.irc4fun.net/+6697"}, -#endif + {"IRC4Fun", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "irc.irc4fun.net"}, {"IRCHighWay", 0}, @@ -294,28 +211,15 @@ static const struct defaultserver def[] = {"IrcLink", 0}, {0, "irc.irclink.net"}, - {0, "Alesund.no.eu.irclink.net"}, - {0, "Oslo.no.eu.irclink.net"}, - {0, "frogn.no.eu.irclink.net"}, - {0, "tonsberg.no.eu.irclink.net"}, {"IRCNet", 0}, {0, "open.ircnet.net"}, - {0, "irc.de.ircnet.net"}, - - {"IRCNode", 0, 0, 0, LOGIN_SASL}, -#ifdef USE_OPENSSL - {0, "irc.ircnode.org/+6697"}, -#endif - {0, "irc.ircnode.org"}, {"Irctoo.net", 0}, {0, "irc.irctoo.net"}, {"iZ-smart.net", 0}, - {0, "irc.iZ-smart.net/6666"}, - {0, "irc.iZ-smart.net/6667"}, - {0, "irc.iZ-smart.net/6668"}, + {0, "irc.iz-smart.net"}, {"Krstarica", 0}, {0, "irc.krstarica.com"}, @@ -323,12 +227,6 @@ static const struct defaultserver def[] = #ifdef USE_OPENSSL {"LinkNet", 0}, {0, "irc.link-net.org/+7000"}, - {0, "as.link-net.org/+7000"}, - {0, "eu.link-net.org/+7000"}, - {0, "us.link-net.org/+7000"}, -#ifdef USE_IPV6 - {0, "irc6.link-net.org/+7000"}, -#endif #endif {"MindForge", 0}, @@ -358,31 +256,14 @@ static const struct defaultserver def[] = {"PIRC.PL", 0}, {0, "irc.pirc.pl"}, - {"PonyChat", 0, 0, 0, LOGIN_SASL}, -#ifdef USE_OPENSSL - {0, "irc.ponychat.net/+6697"}, -#endif + {"PonyChat", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "irc.ponychat.net"}, {"PTNet.org", 0}, - {0, "irc.PTNet.org"}, - {0, "world.PTnet.org"}, - {0, "netvisao.PTnet.org"}, - {0, "uevora.PTnet.org"}, - {0, "vianetworks.PTnet.org"}, - {0, "uc.PTnet.org"}, - {0, "nfsi.ptnet.org"}, - {0, "fctunl.ptnet.org"}, + {0, "irc.ptnet.org"}, {"QuakeNet", 0, 0, 0, LOGIN_CHALLENGEAUTH}, {0, "irc.quakenet.org"}, - {0, "irc.se.quakenet.org"}, - {0, "irc.dk.quakenet.org"}, - {0, "irc.no.quakenet.org"}, - {0, "irc.fi.quakenet.org"}, - {0, "irc.be.quakenet.org"}, - {0, "irc.uk.quakenet.org"}, - {0, "irc.it.quakenet.org"}, {"Rizon", 0}, {0, "irc.rizon.net"}, @@ -395,37 +276,21 @@ static const struct defaultserver def[] = {"SceneNet", 0}, {0, "irc.scene.org"}, - {0, "irc.eu.scene.org"}, - {0, "irc.us.scene.org"}, {"SeilEn.de", 0}, {0, "irc.seilen.de"}, - {"SeionIRC", 0, 0, 0, LOGIN_SASL}, -#ifdef USE_OPENSSL - {0, "irc.seion.us/+6697"}, -#endif - {0, "irc.seion.us"}, - {"Serenity-IRC", 0}, {0, "irc.serenity-irc.net"}, - {0, "eu.serenity-irc.net"}, - {0, "us.serenity-irc.net"}, {"SlashNET", 0}, {0, "irc.slashnet.org"}, - {0, "area51.slashnet.org"}, - {0, "moo.slashnet.org"}, - {0, "radon.slashnet.org"}, - {"Snoonet", 0, 0, 0, LOGIN_SASL}, -#ifdef USE_OPENSSL - {0, "irc.snoonet.org/+6697"}, -#endif - {0, "irc.snoonet.org/6667"}, + {"Snoonet", 0, 0, 0, LOGIN_SASL, 0, TRUE}, + {0, "irc.snoonet.org"}, {"Snyde", 0}, - {0, "irc.snyde.net/6667"}, + {0, "irc.snyde.net"}, {"Sohbet.Net", 0}, {0, "irc.sohbet.net"}, @@ -434,57 +299,28 @@ static const struct defaultserver def[] = {0, "irc.solidirc.com"}, {"SorceryNet", 0, 0, 0, LOGIN_SASL}, - {0, "irc.sorcery.net/9000"}, - {0, "irc.us.sorcery.net/9000"}, - {0, "irc.eu.sorcery.net/9000"}, + {0, "irc.sorcery.net"}, - {"SpotChat", 0, 0, 0, LOGIN_SASL}, -#ifdef USE_OPENSSL - {0, "irc.spotchat.org/+6697"}, -#endif - {0, "irc.spotchat.org/6667"}, + {"SpotChat", 0, 0, 0, LOGIN_SASL, 0, TRUE}, + {0, "irc.spotchat.org"}, {"StarChat", 0}, {0, "irc.starchat.net"}, - {0, "gainesville.starchat.net"}, - {0, "freebsd.starchat.net"}, - {0, "sunset.starchat.net"}, - {0, "revenge.starchat.net"}, - {0, "tahoma.starchat.net"}, - {0, "neo.starchat.net"}, - {"StaticBox", 0, 0, 0, LOGIN_SASL}, - {0, "irc.staticbox.net"}, - - {"Station51", 0}, -#ifdef USE_OPENSSL - {0, "irc.station51.net/+6697"}, -#endif + {"Station51", 0, 0, 0, 0, 0, TRUE}, {0, "irc.station51.net"}, - {"StormBit", 0, 0, 0, LOGIN_SASL}, -#ifdef USE_OPENSSL - {0, "irc.stormbit.net/+6697"}, -#endif + {"StormBit", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "irc.stormbit.net"}, - {"SwiftIRC", 0}, -#ifdef USE_OPENSSL - {0, "irc.swiftirc.net/+6697"}, -#endif - {0, "irc.swiftirc.net/6667"}, + {"SwiftIRC", 0, 0, 0, 0, 0, TRUE}, + {0, "irc.swiftirc.net"}, - {"synIRC", 0}, -#ifdef USE_OPENSSL - {0, "irc.synirc.net/+6697"}, -#endif - {0, "irc.synirc.net/6667"}, + {"synIRC", 0, 0, 0, 0, 0, TRUE}, + {0, "irc.synirc.net"}, - {"Techman's World IRC", 0, 0, 0, LOGIN_SASL}, -#ifdef USE_OPENSSL - {0, "irc.techmansworld.com/+6697"}, -#endif - {0, "irc.techmansworld.com/6667"}, + {"Techtronix", 0, 0, 0, LOGIN_SASL, 0, TRUE}, + {0, "irc.techtronix.net"}, {"TinyCrab", 0, 0, 0, LOGIN_SASL}, {0, "irc.tinycrab.net"}, @@ -508,16 +344,10 @@ static const struct defaultserver def[] = {"Worldnet", 0}, {0, "irc.worldnet.net"}, - {"Windfyre", 0}, -#ifdef USE_OPENSSL - {0, "irc.windfyre.net/+6697"}, -#endif + {"Windfyre", 0, 0, 0, 0, 0, TRUE}, {0, "irc.windfyre.net"}, - {"Xertion", 0, 0, 0, LOGIN_SASL}, -#ifdef USE_OPENSSL - {0, "irc.xertion.org/+6697"}, -#endif + {"Xertion", 0, 0, 0, LOGIN_SASL, 0, TRUE}, {0, "irc.xertion.org"}, {0,0} @@ -566,9 +396,7 @@ servlist_favchan_copy (favchannel *fav) { favchannel *newfav; - newfav = malloc (sizeof (favchannel)); - memset (newfav, 0, sizeof (favchannel)); - + newfav = g_new (favchannel, 1); newfav->name = g_strdup (fav->name); newfav->key = g_strdup (fav->key); /* g_strdup() can handle NULLs so no need to check it */ @@ -924,9 +752,8 @@ servlist_server_add (ircnet *net, char *name) { ircserver *serv; - serv = malloc (sizeof (ircserver)); - memset (serv, 0, sizeof (ircserver)); - serv->hostname = strdup (name); + serv = g_new (ircserver, 1); + serv->hostname = g_strdup (name); net->servlist = g_slist_append (net->servlist, serv); @@ -938,9 +765,8 @@ servlist_command_add (ircnet *net, char *cmd) { commandentry *entry; - entry = malloc (sizeof (commandentry)); - memset (entry, 0, sizeof (commandentry)); - entry->command = strdup (cmd); + entry = g_new (commandentry, 1); + entry->command = g_strdup (cmd); net->commandlist = g_slist_append (net->commandlist, entry); @@ -952,9 +778,7 @@ servlist_favchan_listadd (GSList *chanlist, char *channel, char *key) { favchannel *chan; - chan = malloc (sizeof (favchannel)); - memset (chan, 0, sizeof (favchannel)); - + chan = g_new (favchannel, 1); chan->name = g_strdup (channel); chan->key = g_strdup (key); chanlist = g_slist_append (chanlist, chan); @@ -990,8 +814,8 @@ servlist_favchan_add (ircnet *net, char *channel) void servlist_server_remove (ircnet *net, ircserver *serv) { - free (serv->hostname); - free (serv); + g_free (serv->hostname); + g_free (serv); net->servlist = g_slist_remove (net->servlist, serv); } @@ -1044,7 +868,7 @@ free_and_clear (char *str) char *orig = str; while (*str) *str++ = 0; - free (orig); + g_free (orig); } } @@ -1072,25 +896,18 @@ servlist_net_remove (ircnet *net) servlist_server_remove_all (net); network_list = g_slist_remove (network_list, net); - if (net->nick) - free (net->nick); - if (net->nick2) - free (net->nick2); - if (net->user) - free (net->user); - if (net->real) - free (net->real); + g_free (net->nick); + g_free (net->nick2); + g_free (net->user); + g_free (net->real); free_and_clear (net->pass); if (net->favchanlist) g_slist_free_full (net->favchanlist, (GDestroyNotify) servlist_favchan_free); if (net->commandlist) g_slist_free_full (net->commandlist, (GDestroyNotify) servlist_command_free); - if (net->comment) - free (net->comment); - if (net->encoding) - free (net->encoding); - free (net->name); - free (net); + g_free (net->encoding); + g_free (net->name); + g_free (net); /* for safety */ list = serv_list; @@ -1110,10 +927,8 @@ servlist_net_add (char *name, char *comment, int prepend) { ircnet *net; - net = malloc (sizeof (ircnet)); - memset (net, 0, sizeof (ircnet)); - net->name = strdup (name); -/* net->comment = strdup (comment);*/ + net = g_new0 (ircnet, 1); + net->name = g_strdup (name); net->flags = FLAG_CYCLE | FLAG_USE_GLOBAL | FLAG_USE_PROXY; if (prepend) @@ -1156,6 +971,10 @@ servlist_load_defaults (void) { servlist_command_add (net, def[i].connectcmd); } + if (def[i].ssl) + { + net->flags |= FLAG_USE_SSL; + } if (g_str_hash (def[i].network) == def_hash) { @@ -1210,25 +1029,25 @@ servlist_load (void) switch (buf[0]) { case 'I': - net->nick = strdup (buf + 2); + net->nick = g_strdup (buf + 2); break; case 'i': - net->nick2 = strdup (buf + 2); + net->nick2 = g_strdup (buf + 2); break; case 'U': - net->user = strdup (buf + 2); + net->user = g_strdup (buf + 2); break; case 'R': - net->real = strdup (buf + 2); + net->real = g_strdup (buf + 2); break; case 'P': - net->pass = strdup (buf + 2); + net->pass = g_strdup (buf + 2); break; case 'L': net->logintype = atoi (buf + 2); break; case 'E': - net->encoding = strdup (buf + 2); + net->encoding = servlist_check_encoding (buf + 2) ? g_strdup (buf + 2) : g_strdup ("UTF-8"); break; case 'F': net->flags = atoi (buf + 2); @@ -1258,7 +1077,7 @@ servlist_load (void) case 'A': if (!net->pass) { - net->pass = strdup (buf + 2); + net->pass = g_strdup (buf + 2); if (!net->logintype) { net->logintype = LOGIN_SASL; @@ -1267,7 +1086,7 @@ servlist_load (void) case 'B': if (!net->pass) { - net->pass = strdup (buf + 2); + net->pass = g_strdup (buf + 2); if (!net->logintype) { net->logintype = LOGIN_NICKSERV; @@ -1302,13 +1121,6 @@ servlist_check_encoding (char *charset) if (c) c[0] = 0; - if (!g_ascii_strcasecmp (charset, "IRC")) /* special case */ - { - if (c) - c[0] = ' '; - return TRUE; - } - gic = g_iconv_open (charset, "UTF-8"); if (c) @@ -1379,8 +1191,7 @@ servlist_save (void) fprintf (fp, "P=%s\n", net->pass); if (net->logintype) fprintf (fp, "L=%d\n", net->logintype); - if (net->encoding && g_ascii_strcasecmp (net->encoding, "System") && - g_ascii_strcasecmp (net->encoding, "System default")) + if (net->encoding) { fprintf (fp, "E=%s\n", net->encoding); if (!servlist_check_encoding (net->encoding)) diff --git a/src/common/servlist.h b/src/common/servlist.h index 6d6f1bd3..a305aede 100644 --- a/src/common/servlist.h +++ b/src/common/servlist.h @@ -45,7 +45,6 @@ typedef struct ircnet char *real; char *pass; int logintype; - char *comment; char *encoding; GSList *servlist; GSList *commandlist; diff --git a/src/common/ssl.c b/src/common/ssl.c index cfa9b6cf..f4e23665 100644 --- a/src/common/ssl.c +++ b/src/common/ssl.c @@ -25,18 +25,29 @@ #include "inet.h" /* make it first to avoid macro redefinitions */ #include <openssl/ssl.h> /* SSL_() */ #include <openssl/err.h> /* ERR_() */ +#include <openssl/x509v3.h> #ifdef WIN32 #include <openssl/rand.h> /* RAND_seed() */ #endif -#include "../../config.h" +#include "config.h" #include <time.h> /* asctime() */ #include <string.h> /* strncpy() */ #include "ssl.h" /* struct cert_info */ #include <glib.h> #include <glib/gprintf.h> +#include <gio/gio.h> #include "util.h" +/* If openssl was built without ec */ +#ifndef SSL_OP_SINGLE_ECDH_USE +#define SSL_OP_SINGLE_ECDH_USE 0 +#endif + +#ifndef SSL_OP_NO_COMPRESSION +#define SSL_OP_NO_COMPRESSION 0 +#endif + /* globals */ static struct chiper_info chiper_info; /* static buffer for _SSL_get_cipher_info() */ static char err_buf[256]; /* generic error buffer */ @@ -69,32 +80,29 @@ __SSL_critical_error (char *funcname) /* +++++ SSL functions +++++ */ SSL_CTX * -_SSL_context_init (void (*info_cb_func), int server) +_SSL_context_init (void (*info_cb_func)) { SSL_CTX *ctx; -#ifdef WIN32 - int i, r; -#endif SSLeay_add_ssl_algorithms (); SSL_load_error_strings (); - ctx = SSL_CTX_new (server ? SSLv23_server_method() : SSLv23_client_method ()); + ctx = SSL_CTX_new (SSLv23_client_method ()); SSL_CTX_set_session_cache_mode (ctx, SSL_SESS_CACHE_BOTH); SSL_CTX_set_timeout (ctx, 300); + SSL_CTX_set_options (ctx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3 + |SSL_OP_NO_COMPRESSION + |SSL_OP_SINGLE_DH_USE|SSL_OP_SINGLE_ECDH_USE + |SSL_OP_NO_TICKET + |SSL_OP_CIPHER_SERVER_PREFERENCE); + +#if OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined (OPENSSL_NO_COMP) /* workaround for OpenSSL 0.9.8 */ + sk_SSL_COMP_zero(SSL_COMP_get_compression_methods()); +#endif /* used in SSL_connect(), SSL_accept() */ SSL_CTX_set_info_callback (ctx, info_cb_func); -#ifdef WIN32 - /* under win32, OpenSSL needs to be seeded with some randomness */ - for (i = 0; i < 128; i++) - { - r = rand (); - RAND_seed ((unsigned char *)&r, sizeof (r)); - } -#endif - return(ctx); } @@ -329,3 +337,202 @@ _SSL_close (SSL * ssl) SSL_free (ssl); ERR_remove_state (0); /* free state buffer */ } + +/* Hostname validation code based on OpenBSD's libtls. */ + +static int +_SSL_match_hostname (const char *cert_hostname, const char *hostname) +{ + const char *cert_domain, *domain, *next_dot; + + if (g_ascii_strcasecmp (cert_hostname, hostname) == 0) + return 0; + + /* Wildcard match? */ + if (cert_hostname[0] == '*') + { + /* + * Valid wildcards: + * - "*.domain.tld" + * - "*.sub.domain.tld" + * - etc. + * Reject "*.tld". + * No attempt to prevent the use of eg. "*.co.uk". + */ + cert_domain = &cert_hostname[1]; + /* Disallow "*" */ + if (cert_domain[0] == '\0') + return -1; + /* Disallow "*foo" */ + if (cert_domain[0] != '.') + return -1; + /* Disallow "*.." */ + if (cert_domain[1] == '.') + return -1; + next_dot = strchr (&cert_domain[1], '.'); + /* Disallow "*.bar" */ + if (next_dot == NULL) + return -1; + /* Disallow "*.bar.." */ + if (next_dot[1] == '.') + return -1; + + domain = strchr (hostname, '.'); + + /* No wildcard match against a hostname with no domain part. */ + if (domain == NULL || strlen(domain) == 1) + return -1; + + if (g_ascii_strcasecmp (cert_domain, domain) == 0) + return 0; + } + + return -1; +} + +static int +_SSL_check_subject_altname (X509 *cert, const char *host) +{ + STACK_OF(GENERAL_NAME) *altname_stack = NULL; + GInetAddress *addr; + GSocketFamily family; + int type = GEN_DNS; + int count, i; + int rv = -1; + + altname_stack = X509_get_ext_d2i (cert, NID_subject_alt_name, NULL, NULL); + if (altname_stack == NULL) + return -1; + + addr = g_inet_address_new_from_string (host); + if (addr != NULL) + { + family = g_inet_address_get_family (addr); + if (family == G_SOCKET_FAMILY_IPV4 || family == G_SOCKET_FAMILY_IPV6) + type = GEN_IPADD; + } + + count = sk_GENERAL_NAME_num(altname_stack); + for (i = 0; i < count; i++) + { + GENERAL_NAME *altname; + + altname = sk_GENERAL_NAME_value (altname_stack, i); + + if (altname->type != type) + continue; + + if (type == GEN_DNS) + { + unsigned char *data; + int format; + + format = ASN1_STRING_type (altname->d.dNSName); + if (format == V_ASN1_IA5STRING) + { + data = ASN1_STRING_data (altname->d.dNSName); + + if (ASN1_STRING_length (altname->d.dNSName) != (int)strlen(data)) + { + g_warning("NUL byte in subjectAltName, probably a malicious certificate.\n"); + rv = -2; + break; + } + + if (_SSL_match_hostname (data, host) == 0) + { + rv = 0; + break; + } + } + else + g_warning ("unhandled subjectAltName dNSName encoding (%d)\n", format); + + } + else if (type == GEN_IPADD) + { + unsigned char *data; + const guint8 *addr_bytes; + int datalen, addr_len; + + datalen = ASN1_STRING_length (altname->d.iPAddress); + data = ASN1_STRING_data (altname->d.iPAddress); + + addr_bytes = g_inet_address_to_bytes (addr); + addr_len = (int)g_inet_address_get_native_size (addr); + + if (datalen == addr_len && memcmp (data, addr_bytes, addr_len) == 0) + { + rv = 0; + break; + } + } + } + + if (addr != NULL) + g_object_unref (addr); + sk_GENERAL_NAME_pop_free (altname_stack, GENERAL_NAME_free); + return rv; +} + +static int +_SSL_check_common_name (X509 *cert, const char *host) +{ + X509_NAME *name; + char *common_name = NULL; + int common_name_len; + int rv = -1; + GInetAddress *addr; + + name = X509_get_subject_name (cert); + if (name == NULL) + return -1; + + common_name_len = X509_NAME_get_text_by_NID (name, NID_commonName, NULL, 0); + if (common_name_len < 0) + return -1; + + common_name = g_malloc0 (common_name_len + 1); + + X509_NAME_get_text_by_NID (name, NID_commonName, common_name, common_name_len + 1); + + /* NUL bytes in CN? */ + if (common_name_len != (int)strlen(common_name)) + { + g_warning ("NUL byte in Common Name field, probably a malicious certificate.\n"); + rv = -2; + goto out; + } + + if ((addr = g_inet_address_new_from_string (host)) != NULL) + { + /* + * We don't want to attempt wildcard matching against IP + * addresses, so perform a simple comparison here. + */ + if (g_strcmp0 (common_name, host) == 0) + rv = 0; + else + rv = -1; + + g_object_unref (addr); + } + else if (_SSL_match_hostname (common_name, host) == 0) + rv = 0; + +out: + g_free(common_name); + return rv; +} + +int +_SSL_check_hostname (X509 *cert, const char *host) +{ + int rv; + + rv = _SSL_check_subject_altname (cert, host); + if (rv == 0 || rv == -2) + return rv; + + return _SSL_check_common_name (cert, host); +} diff --git a/src/common/ssl.h b/src/common/ssl.h index 9c729855..e722f831 100644 --- a/src/common/ssl.h +++ b/src/common/ssl.h @@ -41,7 +41,7 @@ struct chiper_info { int chiper_bits; }; -SSL_CTX *_SSL_context_init (void (*info_cb_func), int server); +SSL_CTX *_SSL_context_init (void (*info_cb_func)); #define _SSL_context_free(a) SSL_CTX_free(a); SSL *_SSL_socket (SSL_CTX *ctx, int sd); @@ -52,7 +52,7 @@ char *_SSL_set_verify (SSL_CTX *ctx, void *(verify_callback), char *cacert); int SSL_get_fd(SSL *); */ void _SSL_close (SSL * ssl); - +int _SSL_check_hostname(X509 *cert, const char *host); int _SSL_get_cert_info (struct cert_info *cert_info, SSL * ssl); struct chiper_info *_SSL_get_cipher_info (SSL * ssl); diff --git a/src/common/text.c b/src/common/text.c index 329ef37b..cd9ea26e 100644 --- a/src/common/text.c +++ b/src/common/text.c @@ -51,6 +51,9 @@ #include <canberra.h> #endif +const gchar* unicode_fallback_string = "\357\277\275"; /* The Unicode replacement character 0xFFFD */ +const gchar* arbitrary_encoding_fallback_string = "?"; + struct pevt_stage1 { int len; @@ -83,7 +86,7 @@ scrollback_get_filename (session *sess) buf = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "scrollback" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S "%s.txt", get_xdir (), net, chan); else buf = NULL; - free (chan); + g_free (chan); return buf; } @@ -173,11 +176,11 @@ scrollback_shrink (session *sess) p++; } - fh = g_open (file, O_CREAT | O_TRUNC | O_APPEND | O_WRONLY, 0644); + fh = g_open (file, O_CREAT | O_TRUNC | O_APPEND | O_WRONLY | OFLAGS, 0644); g_free (file); if (fh == -1) { - free (buf); + g_free (buf); return; } @@ -200,14 +203,13 @@ scrollback_shrink (session *sess) } close (fh); - free (buf); + g_free (buf); } static void -scrollback_save (session *sess, char *text) +scrollback_save (session *sess, char *text, time_t stamp) { char *buf; - time_t stamp; int len; if (sess->type == SESS_SERVER && prefs.hex_gui_tab_server == 1) @@ -229,13 +231,14 @@ scrollback_save (session *sess, char *text) if ((buf = scrollback_get_filename (sess)) == NULL) return; - sess->scrollfd = g_open (buf, O_CREAT | O_APPEND | O_WRONLY, 0644); + sess->scrollfd = g_open (buf, O_CREAT | O_APPEND | O_WRONLY | OFLAGS, 0644); g_free (buf); if (sess->scrollfd == -1) return; } - stamp = time (0); + if (!stamp) + stamp = time(0); if (sizeof (stamp) == 4) /* gcc will optimize one of these out */ buf = g_strdup_printf ("T %d ", (int) stamp); else @@ -298,13 +301,6 @@ scrollback_load (session *sess) { char *buf_tmp; - /* If nothing but funny trailing matter e.g. 0x0d or 0x0d0a, toss it */ - if (n_bytes >= 1 && buf[0] == 0x0d) - { - g_free (buf); - continue; - } - n_bytes--; buf_tmp = buf; buf = g_strndup (buf_tmp, n_bytes); @@ -319,9 +315,9 @@ scrollback_load (session *sess) if (buf[0] == 'T') { if (sizeof (time_t) == 4) - stamp = strtoul (buf + 2, NULL, 10); + stamp = g_ascii_strtoull (buf + 2, NULL, 10); else - stamp = strtoull (buf + 2, NULL, 10); /* in case time_t is 64 bits */ + stamp = g_ascii_strtoull (buf + 2, NULL, 10); /* in case time_t is 64 bits */ text = strchr (buf + 3, ' '); if (text && text[1]) { @@ -383,7 +379,7 @@ log_close (session *sess) { currenttime = time (NULL); write (sess->logfd, obuf, - snprintf (obuf, sizeof (obuf) - 1, _("**** ENDING LOGGING AT %s\n"), + g_snprintf (obuf, sizeof (obuf) - 1, _("**** ENDING LOGGING AT %s\n"), ctime (¤ttime))); close (sess->logfd); sess->logfd = -1; @@ -393,9 +389,7 @@ log_close (session *sess) static void mkdir_p (char *filename) { - char *dirname; - - dirname = g_path_get_dirname (filename); + char *dirname = g_path_get_dirname (filename); g_mkdir_with_parents (dirname, 0700); @@ -408,7 +402,7 @@ log_create_filename (char *channame) char *tmp, *ret; int mbl; - ret = tmp = strdup (channame); + ret = tmp = g_strdup (channame); while (*tmp) { mbl = g_utf8_skip[((unsigned char *)tmp)[0]]; @@ -507,34 +501,6 @@ log_insert_vars (char *buf, int bufsize, char *fmt, char *c, char *n, char *s) } } -static int -logmask_is_fullpath () -{ - /* Check if final path/filename is absolute or relative. - * If one uses log mask variables, such as "%c/...", %c will be empty upon - * connecting since there's no channel name yet, so we have to make sure - * we won't try to write to the FS root. On Windows we can be sure it's - * full path if the 2nd character is a colon since Windows doesn't allow - * colons in filenames. - */ -#ifdef WIN32 - /* Treat it as full path if it - * - starts with '\' which denotes the root directory of the current drive letter - * - starts with a drive letter and followed by ':' - */ - if (prefs.hex_irc_logmask[0] == '\\' || (((prefs.hex_irc_logmask[0] >= 'A' && prefs.hex_irc_logmask[0] <= 'Z') || (prefs.hex_irc_logmask[0] >= 'a' && prefs.hex_irc_logmask[0] <= 'z')) && prefs.hex_irc_logmask[1] == ':')) -#else - if (prefs.hex_irc_logmask[0] == '/') -#endif - { - return 1; - } - else - { - return 0; - } -} - static char * log_create_pathname (char *servname, char *channame, char *netname) { @@ -544,7 +510,7 @@ log_create_pathname (char *servname, char *channame, char *netname) if (!netname) { - netname = strdup ("NETWORK"); + netname = g_strdup ("NETWORK"); } else { @@ -554,7 +520,7 @@ log_create_pathname (char *servname, char *channame, char *netname) /* first, everything is in UTF-8 */ if (!rfc_casecmp (channame, servname)) { - channame = strdup ("server"); + channame = g_strdup ("server"); } else { @@ -562,27 +528,29 @@ log_create_pathname (char *servname, char *channame, char *netname) } log_insert_vars (fname, sizeof (fname), prefs.hex_irc_logmask, channame, netname, servname); - free (channame); - free (netname); + g_free (channame); + g_free (netname); /* insert time/date */ now = time (NULL); strftime_utf8 (fnametime, sizeof (fnametime), fname, now); - /* create final path/filename */ - if (logmask_is_fullpath ()) + /* If one uses log mask variables, such as "%c/...", %c will be empty upon + * connecting since there's no channel name yet, so we have to make sure + * we won't try to write to the FS root. */ + if (g_path_is_absolute (prefs.hex_irc_logmask)) { - snprintf (fname, sizeof (fname), "%s", fnametime); + g_snprintf (fname, sizeof (fname), "%s", fnametime); } else /* relative path */ { - snprintf (fname, sizeof (fname), "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s", get_xdir (), fnametime); + g_snprintf (fname, sizeof (fname), "%s" G_DIR_SEPARATOR_S "logs" G_DIR_SEPARATOR_S "%s", get_xdir (), fnametime); } /* create all the subdirectories */ mkdir_p (fname); - return g_strdup(fname); + return g_strdup (fname); } static int @@ -597,18 +565,14 @@ log_open_file (char *servname, char *channame, char *netname) if (!file) return -1; -#ifdef WIN32 - fd = g_open (file, O_CREAT | O_APPEND | O_WRONLY, S_IREAD|S_IWRITE); -#else - fd = g_open (file, O_CREAT | O_APPEND | O_WRONLY, 0644); -#endif + fd = g_open (file, O_CREAT | O_APPEND | O_WRONLY | OFLAGS, 0644); g_free (file); if (fd == -1) return -1; currenttime = time (NULL); write (fd, buf, - snprintf (buf, sizeof (buf), _("**** BEGIN LOGGING AT %s\n"), + g_snprintf (buf, sizeof (buf), _("**** BEGIN LOGGING AT %s\n"), ctime (¤ttime))); return fd; @@ -625,14 +589,15 @@ log_open (session *sess) if (!log_error && sess->logfd == -1) { - char *message; + char *filename = log_create_pathname (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE)); + char *message = g_strdup_printf (_("* Can't open log file(s) for writing. Check the\npermissions on %s"), filename); - message = g_strdup_printf (_("* Can't open log file(s) for writing. Check the\npermissions on %s"), - log_create_pathname (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE))); + g_free (filename); fe_message (message, FE_MSG_WAIT | FE_MSG_ERROR); g_free (message); + log_error = TRUE; } } @@ -659,34 +624,29 @@ log_open_or_close (session *sess) int get_stamp_str (char *fmt, time_t tim, char **ret) { - char *loc = NULL; char dest[128]; - gsize len; + gsize len_locale; + gsize len_utf8; - /* strftime wants the format string in LOCALE! */ - if (!prefs.utf8_locale) - { - const gchar *charset; + /* strftime requires the format string to be in locale encoding. */ + fmt = g_locale_from_utf8 (fmt, -1, NULL, NULL, NULL); - g_get_charset (&charset); - loc = g_convert_with_fallback (fmt, -1, charset, "UTF-8", "?", 0, 0, 0); - if (loc) - fmt = loc; - } + len_locale = strftime_validated (dest, sizeof (dest), fmt, localtime (&tim)); - len = strftime_validated (dest, sizeof (dest), fmt, localtime (&tim)); - if (len) + g_free (fmt); + + if (len_locale == 0) { - if (prefs.utf8_locale) - *ret = g_strdup (dest); - else - *ret = g_locale_to_utf8 (dest, len, 0, &len, 0); + return 0; } - if (loc) - g_free (loc); + *ret = g_locale_to_utf8 (dest, len_locale, NULL, &len_utf8, NULL); + if (*ret == NULL) + { + return 0; + } - return len; + return len_utf8; } static void @@ -709,22 +669,32 @@ log_write (session *sess, char *text, time_t ts) } if (sess->logfd == -1) + { log_open (sess); + } /* change to a different log file? */ - file = log_create_pathname (sess->server->servername, sess->channel, - server_get_network (sess->server, FALSE)); + file = log_create_pathname (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE)); if (file) { if (g_access (file, F_OK) != 0) { - close (sess->logfd); - sess->logfd = log_open_file (sess->server->servername, sess->channel, - server_get_network (sess->server, FALSE)); + if (sess->logfd != -1) + { + close (sess->logfd); + } + + sess->logfd = log_open_file (sess->server->servername, sess->channel, server_get_network (sess->server, FALSE)); } + g_free (file); } + if (sess->logfd == -1) + { + return; + } + if (prefs.hex_stamp_log) { if (!ts) ts = time(0); @@ -735,6 +705,7 @@ log_write (session *sess, char *text, time_t ts) g_free (stamp); } } + temp = strip_color (text, -1, STRIP_ALL); len = strlen (temp); write (sess->logfd, temp, len); @@ -744,156 +715,104 @@ log_write (session *sess, char *text, time_t ts) g_free (temp); } -/* converts a CP1252/ISO-8859-1(5) hybrid to UTF-8 */ -/* Features: 1. It never fails, all 00-FF chars are converted to valid UTF-8 */ -/* 2. Uses CP1252 in the range 80-9f because ISO doesn't have any- */ -/* thing useful in this range and it helps us receive from mIRC */ -/* 3. The five undefined chars in CP1252 80-9f are replaced with */ -/* ISO-8859-15 control codes. */ -/* 4. Handles 0xa4 as a Euro symbol ala ISO-8859-15. */ -/* 5. Uses ISO-8859-1 (which matches CP1252) for everything else. */ -/* 6. This routine measured 3x faster than g_convert :) */ - -static unsigned char * -iso_8859_1_to_utf8 (unsigned char *text, int len, gsize *bytes_written) +/** + * Converts a given string using the given iconv converter. This is similar to g_convert_with_fallback, except that it is tolerant of sequences in + * the original input that are invalid even in from_encoding. g_convert_with_fallback fails for such text, whereas this function replaces such a + * sequence with the fallback string. + * + * If len is -1, strlen(text) is used to calculate the length. Do not pass -1 if text is supposed to contain \0 bytes, such as if from_encoding is a + * multi-byte encoding like UTF-16. + */ +gchar * +text_convert_invalid (const gchar* text, gssize len, GIConv converter, const gchar *fallback, gsize *len_out) { - unsigned int idx; - unsigned char *res, *output; - static const unsigned short lowtable[] = /* 74 byte table for 80-a4 */ - { - /* compressed utf-8 table: if the first byte's 0x20 bit is set, it - indicates a 2-byte utf-8 sequence, otherwise prepend a 0xe2. */ - 0x82ac, /* 80 Euro. CP1252 from here on... */ - 0xe281, /* 81 NA */ - 0x809a, /* 82 */ - 0xe692, /* 83 */ - 0x809e, /* 84 */ - 0x80a6, /* 85 */ - 0x80a0, /* 86 */ - 0x80a1, /* 87 */ - 0xeb86, /* 88 */ - 0x80b0, /* 89 */ - 0xe5a0, /* 8a */ - 0x80b9, /* 8b */ - 0xe592, /* 8c */ - 0xe28d, /* 8d NA */ - 0xe5bd, /* 8e */ - 0xe28f, /* 8f NA */ - 0xe290, /* 90 NA */ - 0x8098, /* 91 */ - 0x8099, /* 92 */ - 0x809c, /* 93 */ - 0x809d, /* 94 */ - 0x80a2, /* 95 */ - 0x8093, /* 96 */ - 0x8094, /* 97 */ - 0xeb9c, /* 98 */ - 0x84a2, /* 99 */ - 0xe5a1, /* 9a */ - 0x80ba, /* 9b */ - 0xe593, /* 9c */ - 0xe29d, /* 9d NA */ - 0xe5be, /* 9e */ - 0xe5b8, /* 9f */ - 0xe2a0, /* a0 */ - 0xe2a1, /* a1 */ - 0xe2a2, /* a2 */ - 0xe2a3, /* a3 */ - 0x82ac /* a4 ISO-8859-15 Euro. */ - }; + gchar *result_part; + gsize result_part_len; + const gchar *end; + gsize invalid_start_pos; + GString *result; + const gchar *current_start; if (len == -1) + { len = strlen (text); + } - /* worst case scenario: every byte turns into 3 bytes */ - res = output = g_malloc ((len * 3) + 1); - if (!output) - return NULL; + end = text + len; - while (len) + /* Find the first position of an invalid sequence. */ + result_part = g_convert_with_iconv (text, len, converter, &invalid_start_pos, &result_part_len, NULL); + if (result_part != NULL) { - if (G_LIKELY (*text < 0x80)) + /* All text converted successfully on the first try. Return it. */ + + if (len_out != NULL) { - *output = *text; /* ascii maps directly */ + *len_out = result_part_len; } - else if (*text <= 0xa4) /* 80-a4 use a lookup table */ + + return result_part; + } + + /* One or more invalid sequences exist that need to be replaced with the fallback. */ + + result = g_string_sized_new (len); + current_start = text; + + for (;;) + { + g_assert (current_start + invalid_start_pos < end); + + /* Convert everything before the position of the invalid sequence. It should be successful. */ + result_part = g_convert_with_iconv (current_start, invalid_start_pos, converter, &invalid_start_pos, &result_part_len, NULL); + g_assert (result_part != NULL); + g_string_append_len (result, result_part, result_part_len); + g_free (result_part); + + /* Append the fallback */ + g_string_append (result, fallback); + + /* Now try converting everything after the invalid sequence. */ + current_start += invalid_start_pos + 1; + + result_part = g_convert_with_iconv (current_start, end - current_start, converter, &invalid_start_pos, &result_part_len, NULL); + if (result_part != NULL) { - idx = *text - 0x80; - if (lowtable[idx] & 0x2000) - { - *output++ = (lowtable[idx] >> 8) & 0xdf; /* 2 byte utf-8 */ - *output = lowtable[idx] & 0xff; - } - else + /* The rest of the text converted successfully. Append it and return the whole converted text. */ + + g_string_append_len (result, result_part, result_part_len); + g_free (result_part); + + if (len_out != NULL) { - *output++ = 0xe2; /* 3 byte utf-8 */ - *output++ = (lowtable[idx] >> 8) & 0xff; - *output = lowtable[idx] & 0xff; + *len_out = result->len; } + + return g_string_free (result, FALSE); } - else if (*text < 0xc0) - { - *output++ = 0xc2; - *output = *text; - } - else - { - *output++ = 0xc3; - *output = *text - 0x40; - } - output++; - text++; - len--; - } - *output = 0; /* terminate */ - *bytes_written = output - res; - return res; + /* The rest of the text didn't convert successfully. invalid_start_pos has the position of the next invalid sequence. */ + } } -char * -text_validate (char **text, int *len) +/** + * Replaces any invalid UTF-8 in the given text with the unicode replacement character. + */ +gchar * +text_fixup_invalid_utf8 (const gchar* text, gssize len, gsize *len_out) { - char *utf; - gsize utf_len; - - /* valid utf8? */ - if (g_utf8_validate (*text, *len, 0)) - return NULL; - -#ifdef WIN32 - if (GetACP () == 1252) /* our routine is better than iconv's 1252 */ -#else - if (prefs.utf8_locale) -#endif - /* fallback to iso-8859-1 */ - utf = iso_8859_1_to_utf8 (*text, *len, &utf_len); - else + static GIConv utf8_fixup_converter = NULL; + if (utf8_fixup_converter == NULL) { - /* fallback to locale */ - utf = g_locale_to_utf8 (*text, *len, 0, &utf_len, NULL); - if (!utf) - utf = iso_8859_1_to_utf8 (*text, *len, &utf_len); + utf8_fixup_converter = g_iconv_open ("UTF-8", "UTF-8"); } - if (!utf) - { - *text = g_strdup ("%INVALID%"); - *len = 9; - } else - { - *text = utf; - *len = utf_len; - } - - return utf; + return text_convert_invalid (text, len, utf8_fixup_converter, unicode_fallback_string, len_out); } void PrintTextTimeStamp (session *sess, char *text, time_t timestamp) { - char *conv; - if (!sess) { if (!sess_list) @@ -902,22 +821,19 @@ PrintTextTimeStamp (session *sess, char *text, time_t timestamp) } /* make sure it's valid utf8 */ - if (text[0] == 0) + if (text[0] == '\0') { - text = "\n"; - conv = NULL; - } else + text = g_strdup ("\n"); + } + else { - int len = -1; - conv = text_validate ((char **)&text, &len); + text = text_fixup_invalid_utf8 (text, -1, NULL); } log_write (sess, text, timestamp); - scrollback_save (sess, text); + scrollback_save (sess, text, timestamp); fe_print_text (sess, text, timestamp, FALSE); - - if (conv) - g_free (conv); + g_free (text); } void @@ -1004,7 +920,7 @@ PrintTextTimeStampf (session *sess, time_t timestamp, const char *format, ...) Each XP_TE_* signal is hard coded to call text_emit which calls display_event which decodes the data - This means that this system *should be faster* than snprintf because + This means that this system *should be faster* than g_snprintf because it always 'knows' that format of the string (basically is preparses much of the work) @@ -1211,26 +1127,26 @@ static char * const pevt_chanrmlimit_help[] = { }; static char * const pevt_chandeop_help[] = { - N_("The nick of the person of did the deop'ing"), + N_("The nick of the person who did the deop'ing"), N_("The nick of the person who has been deop'ed"), }; static char * const pevt_chandehop_help[] = { - N_("The nick of the person of did the dehalfop'ing"), + N_("The nick of the person who did the dehalfop'ing"), N_("The nick of the person who has been dehalfop'ed"), }; static char * const pevt_chandevoice_help[] = { - N_("The nick of the person of did the devoice'ing"), + N_("The nick of the person who did the devoice'ing"), N_("The nick of the person who has been devoice'ed"), }; static char * const pevt_chanunban_help[] = { - N_("The nick of the person of did the unban'ing"), + N_("The nick of the person who did the unban'ing"), N_("The ban mask"), }; static char * const pevt_chanunquiet_help[] = { - N_("The nick of the person of did the unquiet'ing"), + N_("The nick of the person who did the unquiet'ing"), N_("The quiet mask"), }; @@ -1569,14 +1485,13 @@ pevent_load_defaults () for (i = 0; i < NUM_XP; i++) { - if (pntevts_text[i]) - free (pntevts_text[i]); + g_free (pntevts_text[i]); /* make-te.c sets this 128 flag (DON'T call gettext() flag) */ if (te[i].num_args & 128) - pntevts_text[i] = strdup (te[i].def); + pntevts_text[i] = g_strdup (te[i].def); else - pntevts_text[i] = strdup (_(te[i].def)); + pntevts_text[i] = g_strdup (_(te[i].def)); } } @@ -1588,19 +1503,18 @@ pevent_make_pntevts () for (i = 0; i < NUM_XP; i++) { - if (pntevts[i] != NULL) - free (pntevts[i]); + g_free (pntevts[i]); if (pevt_build_string (pntevts_text[i], &(pntevts[i]), &m) != 0) { - snprintf (out, sizeof (out), + g_snprintf (out, sizeof (out), _("Error parsing event %s.\nLoading default."), te[i].name); fe_message (out, FE_MSG_WARN); - free (pntevts_text[i]); + g_free (pntevts_text[i]); /* make-te.c sets this 128 flag (DON'T call gettext() flag) */ if (te[i].num_args & 128) - pntevts_text[i] = strdup (te[i].def); + pntevts_text[i] = g_strdup (te[i].def); else - pntevts_text[i] = strdup (_(te[i].def)); + pntevts_text[i] = g_strdup (_(te[i].def)); if (pevt_build_string (pntevts_text[i], &(pntevts[i]), &m) != 0) { fprintf (stderr, @@ -1622,22 +1536,17 @@ pevent_make_pntevts () static void pevent_trigger_load (int *i_penum, char **i_text, char **i_snd) { - int penum = *i_penum, len; + int penum = *i_penum; char *text = *i_text, *snd = *i_snd; if (penum != -1 && text != NULL) { - len = strlen (text) + 1; - if (pntevts_text[penum]) - free (pntevts_text[penum]); - pntevts_text[penum] = malloc (len); - memcpy (pntevts_text[penum], text, len); + g_free (pntevts_text[penum]); + pntevts_text[penum] = g_strdup (text); } - if (text) - free (text); - if (snd) - free (snd); + g_free (text); + g_free (snd); *i_text = NULL; *i_snd = NULL; *i_penum = 0; @@ -1690,7 +1599,7 @@ pevent_load (char *filename) close (fd); return 1; } - ibuf = malloc (st.st_size); + ibuf = g_malloc (st.st_size); read (fd, ibuf, st.st_size); close (fd); @@ -1706,8 +1615,6 @@ pevent_load (char *filename) continue; *ofs = 0; ofs++; - /*if (*ofs == 0) - continue;*/ if (strcmp (buf, "event_name") == 0) { @@ -1717,53 +1624,16 @@ pevent_load (char *filename) continue; } else if (strcmp (buf, "event_text") == 0) { - if (text) - free (text); - -#if 0 - /* This allows updating of old strings. We don't use new defaults - if the user has customized the strings (.e.g a text theme). - Hash of the old default is enough to identify and replace it. - This only works in English. */ - - switch (g_str_hash (ofs)) - { - case 0x526743a4: - /* %C08,02 Hostmask PRIV NOTI CHAN CTCP INVI UNIG %O */ - text = strdup (te[XP_TE_IGNOREHEADER].def); - break; - - case 0xe91bc9c2: - /* %C08,02 %O */ - text = strdup (te[XP_TE_IGNOREFOOTER].def); - break; - - case 0x1fbfdf22: - /* -%C10-%C11-%O$tDCC RECV: Cannot open $1 for writing - aborting. */ - text = strdup (te[XP_TE_DCCFILEERR].def); - break; - - default: - text = strdup (ofs); - } -#else - text = strdup (ofs); -#endif - - continue; - }/* else if (strcmp (buf, "event_sound") == 0) - { - if (snd) - free (snd); - snd = strdup (ofs); + g_free (text); + text = g_strdup (ofs); continue; - }*/ + } continue; } pevent_trigger_load (&penum, &text, &snd); - free (ibuf); + g_free (ibuf); return 0; } @@ -1777,13 +1647,13 @@ pevent_check_all_loaded () if (pntevts_text[i] == NULL) { /*printf ("%s\n", te[i].name); - snprintf(out, sizeof(out), "The data for event %s failed to load. Reverting to defaults.\nThis may be because a new version of HexChat is loading an old config file.\n\nCheck all print event texts are correct", evtnames[i]); + g_snprintf(out, sizeof(out), "The data for event %s failed to load. Reverting to defaults.\nThis may be because a new version of HexChat is loading an old config file.\n\nCheck all print event texts are correct", evtnames[i]); gtkutil_simpledialog(out); */ /* make-te.c sets this 128 flag (DON'T call gettext() flag) */ if (te[i].num_args & 128) - pntevts_text[i] = strdup (te[i].def); + pntevts_text[i] = g_strdup (te[i].def); else - pntevts_text[i] = strdup (_(te[i].def)); + pntevts_text[i] = g_strdup (_(te[i].def)); } } } @@ -1808,9 +1678,10 @@ load_text_events () #define ARG_FLAG(argn) (1 << (argn)) void -format_event (session *sess, int index, char **args, char *o, int sizeofo, unsigned int stripcolor_args) +format_event (session *sess, int index, char **args, char *o, gsize sizeofo, unsigned int stripcolor_args) { - int len, oi, ii, numargs; + int len, ii, numargs; + gsize oi; char *i, *ar, d, a, done_all = FALSE; i = pntevts[index]; @@ -1868,19 +1739,10 @@ format_event (session *sess, int index, char **args, char *o, int sizeofo, unsig done_all = TRUE; continue; case 3: -/* if (sess->type == SESS_DIALOG) - { - if (prefs.dialog_indent_nicks) - o[oi++] = '\t'; - else - o[oi++] = ' '; - } else - {*/ - if (prefs.hex_text_indent) - o[oi++] = '\t'; - else - o[oi++] = ' '; - /*}*/ + if (prefs.hex_text_indent) + o[oi++] = '\t'; + else + o[oi++] = ' '; break; } } @@ -1908,7 +1770,7 @@ pevt_build_string (const char *input, char **output, int *max_arg) int oi, ii, max = -1, len, x; len = strlen (input); - i = malloc (len + 1); + i = g_malloc (len + 1); memcpy (i, input, len + 1); check_special_chars (i, TRUE); @@ -1933,14 +1795,14 @@ pevt_build_string (const char *input, char **output, int *max_arg) } if (oi > 0) { - s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1)); + s = g_new (struct pevt_stage1, 1); if (base == NULL) base = s; if (last != NULL) last->next = s; last = s; s->next = NULL; - s->data = malloc (oi + sizeof (int) + 1); + s->data = g_malloc (oi + sizeof (int) + 1); s->len = oi + sizeof (int) + 1; clen += oi + sizeof (int) + 1; s->data[0] = 0; @@ -1951,12 +1813,12 @@ pevt_build_string (const char *input, char **output, int *max_arg) if (ii == len) { fe_message ("String ends with a $", FE_MSG_WARN); - return 1; + goto err; } d = i[ii++]; if (d == 'a') - { /* Hex value */ - x = 0; + { + /* Hex value */ if (ii == len) goto a_len_error; d = i[ii++]; @@ -1977,24 +1839,24 @@ pevt_build_string (const char *input, char **output, int *max_arg) o[oi++] = x; continue; - a_len_error: + a_len_error: fe_message ("String ends in $a", FE_MSG_WARN); - return 1; - a_range_error: + goto err; + a_range_error: fe_message ("$a value is greater than 255", FE_MSG_WARN); - return 1; + goto err; } if (d == 't') { /* Tab - if tabnicks is set then write '\t' else ' ' */ - s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1)); + s = g_new (struct pevt_stage1, 1); if (base == NULL) base = s; if (last != NULL) last->next = s; last = s; s->next = NULL; - s->data = malloc (1); + s->data = g_malloc (1); s->len = 1; clen += 1; s->data[0] = 3; @@ -2003,21 +1865,21 @@ pevt_build_string (const char *input, char **output, int *max_arg) } if (d < '1' || d > '9') { - snprintf (o, sizeof (o), "Error, invalid argument $%c\n", d); + g_snprintf (o, sizeof (o), "Error, invalid argument $%c\n", d); fe_message (o, FE_MSG_WARN); - return 1; + goto err; } d -= '0'; if (max < d) max = d; - s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1)); + s = g_new (struct pevt_stage1, 1); if (base == NULL) base = s; if (last != NULL) last->next = s; last = s; s->next = NULL; - s->data = malloc (2); + s->data = g_malloc (2); s->len = 2; clen += 2; s->data[0] = 1; @@ -2025,14 +1887,14 @@ pevt_build_string (const char *input, char **output, int *max_arg) } if (oi > 0) { - s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1)); + s = g_new (struct pevt_stage1, 1); if (base == NULL) base = s; if (last != NULL) last->next = s; last = s; s->next = NULL; - s->data = malloc (oi + sizeof (int) + 1); + s->data = g_malloc (oi + sizeof (int) + 1); s->len = oi + sizeof (int) + 1; clen += oi + sizeof (int) + 1; s->data[0] = 0; @@ -2040,39 +1902,54 @@ pevt_build_string (const char *input, char **output, int *max_arg) memcpy (&(s->data[1 + sizeof (int)]), o, oi); oi = 0; } - s = (struct pevt_stage1 *) malloc (sizeof (struct pevt_stage1)); + s = g_new (struct pevt_stage1, 1); if (base == NULL) base = s; if (last != NULL) last->next = s; - last = s; s->next = NULL; - s->data = malloc (1); + s->data = g_malloc (1); s->len = 1; clen += 1; s->data[0] = 2; oi = 0; s = base; - obuf = malloc (clen); + obuf = g_malloc (clen); + while (s) { next = s->next; memcpy (&obuf[oi], s->data, s->len); oi += s->len; - free (s->data); - free (s); + g_free (s->data); + g_free (s); s = next; } - free (i); + g_free (i); if (max_arg) *max_arg = max; if (output) *output = obuf; + else + g_free (obuf); return 0; + +err: + while (s) + { + next = s->next; + g_free (s->data); + g_free (s); + s = next; + } + + g_free(i); + + return 1; } @@ -2107,7 +1984,7 @@ text_emit (int index, session *sess, char *a, char *b, char *c, char *d, if (prefs.hex_text_color_nicks && (index == XP_TE_CHANACTION || index == XP_TE_CHANMSG)) { - snprintf (tbuf, sizeof (tbuf), "\003%d%s", text_color_of (a), a); + g_snprintf (tbuf, sizeof (tbuf), "\003%d%s", text_color_of (a), a); a = tbuf; stripcolor_args &= ~ARG_FLAG(1); /* don't strip color from this argument */ } @@ -2239,9 +2116,9 @@ pevent_save (char *fn) for (i = 0; i < NUM_XP; i++) { - write (fd, buf, snprintf (buf, sizeof (buf), + write (fd, buf, g_snprintf (buf, sizeof (buf), "event_name=%s\n", te[i].name)); - write (fd, buf, snprintf (buf, sizeof (buf), + write (fd, buf, g_snprintf (buf, sizeof (buf), "event_text=%s\n\n", pntevts_text[i])); } @@ -2257,7 +2134,7 @@ char *sound_files[NUM_XP]; void sound_beep (session *sess) { - if (!prefs.hex_gui_focus_omitalerts || !fe_gui_info (sess, 0) == 1) + if (!prefs.hex_gui_focus_omitalerts || fe_gui_info (sess, 0) != 1) { if (sound_files[XP_TE_BEEP] && sound_files[XP_TE_BEEP][0]) /* user defined beep _file_ */ @@ -2283,12 +2160,8 @@ sound_play (const char *file, gboolean quiet) return; } -#ifdef WIN32 /* check for fullpath */ - if (file[0] == '\\' || (((file[0] >= 'A' && file[0] <= 'Z') || (file[0] >= 'a' && file[0] <= 'z')) && file[1] == ':')) -#else - if (file[0] == '/') -#endif + if (g_path_is_absolute (file)) { wavfile = g_strdup (file); } @@ -2363,9 +2236,8 @@ sound_load_event (char *evt, char *file) if (file[0] && pevent_find (evt, &i) != -1) { - if (sound_files[i]) - free (sound_files[i]); - sound_files[i] = strdup (file); + g_free (sound_files[i]); + sound_files[i] = g_strdup (file); } } @@ -2417,9 +2289,9 @@ sound_save () { if (sound_files[i] && sound_files[i][0]) { - write (fd, buf, snprintf (buf, sizeof (buf), + write (fd, buf, g_snprintf (buf, sizeof (buf), "event=%s\n", te[i].name)); - write (fd, buf, snprintf (buf, sizeof (buf), + write (fd, buf, g_snprintf (buf, sizeof (buf), "sound=%s\n\n", sound_files[i])); } } diff --git a/src/common/text.h b/src/common/text.h index 9a385167..28fc0c0d 100644 --- a/src/common/text.h +++ b/src/common/text.h @@ -57,11 +57,15 @@ void text_emit (int index, session *sess, char *a, char *b, char *c, char *d, time_t timestamp); int text_emit_by_name (char *name, session *sess, time_t timestamp, char *a, char *b, char *c, char *d); -char *text_validate (char **text, int *len); +gchar *text_convert_invalid (const gchar* text, gssize len, GIConv converter, const gchar *fallback, gsize *len_out); +gchar *text_fixup_invalid_utf8 (const gchar* text, gssize len, gsize *len_out); int get_stamp_str (char *fmt, time_t tim, char **ret); -void format_event (session *sess, int index, char **args, char *o, int sizeofo, unsigned int stripcolor_args); +void format_event (session *sess, int index, char **args, char *o, gsize sizeofo, unsigned int stripcolor_args); char *text_find_format_string (char *name); - + +extern const gchar* unicode_fallback_string; +extern const gchar* arbitrary_encoding_fallback_string; + void sound_play (const char *file, gboolean quiet); void sound_play_event (int i); void sound_beep (session *); diff --git a/src/common/tree.c b/src/common/tree.c index 587d15f0..b9a894d2 100644 --- a/src/common/tree.c +++ b/src/common/tree.c @@ -42,7 +42,7 @@ struct _tree tree * tree_new (tree_cmp_func *cmp, void *data) { - tree *t = calloc (1, sizeof (tree)); + tree *t = g_new0 (tree, 1); t->cmp = cmp; t->data = data; return t; @@ -53,9 +53,8 @@ tree_destroy (tree *t) { if (t) { - if (t->array) - free (t->array); - free (t); + g_free (t->array); + g_free (t); } } diff --git a/src/common/tree.h b/src/common/tree.h index 848f5abf..8cde93ea 100644 --- a/src/common/tree.h +++ b/src/common/tree.h @@ -20,6 +20,8 @@ #ifndef HEXCHAT_TREE_H #define HEXCHAT_TREE_H +#include <glib.h> + typedef struct _tree tree; typedef int (tree_cmp_func) (const void *keya, const void *keyb, void *data); diff --git a/src/common/url.c b/src/common/url.c index 1321374f..0354d98c 100644 --- a/src/common/url.c +++ b/src/common/url.c @@ -53,7 +53,7 @@ static gboolean match_path (const char *word, int *start, int *end); static int url_free (char *url, void *data) { - free (url); + g_free (url); return TRUE; } @@ -124,13 +124,7 @@ url_add (char *urltext, int len) return; } - data = malloc (len + 1); - if (!data) - { - return; - } - memcpy (data, urltext, len); - data[len] = 0; + data = g_strndup (urltext, len); if (data[len - 1] == '.') /* chop trailing dot */ { @@ -151,7 +145,7 @@ url_add (char *urltext, int len) /* the URL is saved already, only continue if we need the URL grabber too */ if (!prefs.hex_url_grabber) { - free (data); + g_free (data); return; } @@ -163,7 +157,7 @@ url_add (char *urltext, int len) if (url_find (data)) { - free (data); + g_free (data); return; } @@ -180,7 +174,7 @@ url_add (char *urltext, int len) pos = tree_remove_at_pos (url_tree, 0); g_tree_remove (url_btree, pos); - free (pos); + g_free (pos); } } @@ -332,7 +326,7 @@ static char *commands[] = { #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0])) void -url_check_line (char *buf, int len) +url_check_line (char *buf) { GRegex *re(void); GMatchInfo *gmi; @@ -415,7 +409,7 @@ regex_match (const GRegex *re, const char *word, int *start, int *end) } /* Miscellaneous description --- */ -#define DOMAIN "[_\\pL\\pN][-_\\pL\\pN]*(\\.[-_\\pL\\pN]+)*" +#define DOMAIN "[_\\pL\\pN\\pS][-_\\pL\\pN\\pS]*(\\.[-_\\pL\\pN\\pS]+)*" #define TLD "\\.[\\pL][-\\pL\\pN]*[\\pL]" #define IPADDR "[0-9]{1,3}(\\.[0-9]{1,3}){3}" #define IPV6GROUP "([0-9a-f]{0,4})" @@ -429,7 +423,7 @@ regex_match (const GRegex *re, const char *word, int *start, int *end) #define OPT_PORT "(" PORT ")?" static GRegex * -make_re (char *grist) +make_re (const char *grist) { GRegex *ret; GError *err = NULL; @@ -587,18 +581,14 @@ re_url (void) if (uri[i].flags & URI_PATH) { - char *sep_escaped; - - sep_escaped = g_regex_escape_string (uri[i].path_sep, - strlen(uri[i].path_sep)); + char *sep_escaped = g_regex_escape_string (uri[i].path_sep, strlen(uri[i].path_sep)); - g_string_append_printf(grist_gstr, "(" "%s" PATH ")?", - sep_escaped); + g_string_append_printf (grist_gstr, "(" "%s" PATH ")?", sep_escaped); - g_free(sep_escaped); + g_free (sep_escaped); } - g_string_append(grist_gstr, ")"); + g_string_append (grist_gstr, ")"); } grist = g_string_free (grist_gstr, FALSE); diff --git a/src/common/url.h b/src/common/url.h index 676f9a6d..1b1deb3d 100644 --- a/src/common/url.h +++ b/src/common/url.h @@ -36,6 +36,6 @@ void url_clear (void); void url_save_tree (const char *fname, const char *mode, gboolean fullpath); int url_last (int *, int *); int url_check_word (const char *word); -void url_check_line (char *buf, int len); +void url_check_line (char *buf); #endif diff --git a/src/common/userlist.c b/src/common/userlist.c index e08cb857..54ed6f03 100644 --- a/src/common/userlist.c +++ b/src/common/userlist.c @@ -29,7 +29,7 @@ #include "util.h" -static int +int nick_cmp_az_ops (server *serv, struct User *user1, struct User *user2) { unsigned int access1 = user1->access; @@ -52,30 +52,12 @@ nick_cmp_az_ops (server *serv, struct User *user1, struct User *user2) return serv->p_cmp (user1->nick, user2->nick); } -static int +int nick_cmp_alpha (struct User *user1, struct User *user2, server *serv) { return serv->p_cmp (user1->nick, user2->nick); } -static int -nick_cmp (struct User *user1, struct User *user2, server *serv) -{ - switch (prefs.hex_gui_ulist_sort) - { - case 0: - return nick_cmp_az_ops (serv, user1, user2); - case 1: - return serv->p_cmp (user1->nick, user2->nick); - case 2: - return -1 * nick_cmp_az_ops (serv, user1, user2); - case 3: - return -1 * serv->p_cmp (user1->nick, user2->nick); - default: - return -1; - } -} - /* insert name in appropriate place in linked list. Returns row number or: -1: duplicate @@ -86,11 +68,9 @@ userlist_insertname (session *sess, struct User *newuser) { if (!sess->usertree) { - sess->usertree = tree_new ((tree_cmp_func *)nick_cmp, sess->server); - sess->usertree_alpha = tree_new ((tree_cmp_func *)nick_cmp_alpha, sess->server); + sess->usertree = tree_new ((tree_cmp_func *)nick_cmp_alpha, sess->server); } - tree_insert (sess->usertree_alpha, newuser); return tree_insert (sess->usertree, newuser); } @@ -121,13 +101,12 @@ userlist_set_account (struct session *sess, char *nick, char *account) user = userlist_find (sess, nick); if (user) { - if (user->account) - free (user->account); + g_free (user->account); if (strcmp (account, "*") == 0) user->account = NULL; else - user->account = strdup (account); + user->account = g_strdup (account); /* gui doesnt currently reflect login status, maybe later fe_userlist_rehash (sess, user); */ @@ -148,14 +127,14 @@ userlist_add_hostname (struct session *sess, char *nick, char *hostname, { if (prefs.hex_gui_ulist_show_hosts) do_rehash = TRUE; - user->hostname = strdup (hostname); + user->hostname = g_strdup (hostname); } if (!user->realname && realname && *realname) - user->realname = strdup (realname); + user->realname = g_strdup (realname); if (!user->servername && servername) - user->servername = strdup (servername); + user->servername = g_strdup (servername); if (!user->account && account && strcmp (account, "0") != 0) - user->account = strdup (account); + user->account = g_strdup (account); if (away != 0xff) { if (user->away != away) @@ -175,15 +154,11 @@ userlist_add_hostname (struct session *sess, char *nick, char *hostname, static int free_user (struct User *user, gpointer data) { - if (user->realname) - free (user->realname); - if (user->hostname) - free (user->hostname); - if (user->servername) - free (user->servername); - if (user->account) - free (user->account); - free (user); + g_free (user->realname); + g_free (user->hostname); + g_free (user->servername); + g_free (user->account); + g_free (user); return TRUE; } @@ -193,10 +168,8 @@ userlist_free (session *sess) { tree_foreach (sess->usertree, (tree_traverse_func *)free_user, NULL); tree_destroy (sess->usertree); - tree_destroy (sess->usertree_alpha); sess->usertree = NULL; - sess->usertree_alpha = NULL; sess->me = NULL; sess->ops = 0; @@ -224,8 +197,8 @@ userlist_find (struct session *sess, const char *name) { int pos; - if (sess->usertree_alpha) - return tree_find (sess->usertree_alpha, name, + if (sess->usertree) + return tree_find (sess->usertree, name, (tree_cmp_func *)find_cmp, sess->server, &pos); return NULL; @@ -248,7 +221,7 @@ userlist_find_global (struct server *serv, char *name) } list = list->next; } - return 0; + return NULL; } static void @@ -288,7 +261,7 @@ userlist_update_mode (session *sess, char *name, char mode, char sign) /* remove from binary trees, before we loose track of it */ tree_remove (sess->usertree, user, &pos); - tree_remove (sess->usertree_alpha, user, &pos); + fe_userlist_remove (sess, user); /* which bit number is affected? */ access = mode_access (sess->server, mode, &prefix); @@ -318,11 +291,8 @@ userlist_update_mode (session *sess, char *name, char mode, char sign) update_counts (sess, user, prefix, level, offset); /* insert it back into its new place */ - tree_insert (sess->usertree_alpha, user); - pos = tree_insert (sess->usertree, user); - - /* let GTK move it too */ - fe_userlist_move (sess, user, pos); + tree_insert (sess->usertree, user); + fe_userlist_insert (sess, user, FALSE); fe_userlist_numbers (sess); } @@ -335,14 +305,12 @@ userlist_change (struct session *sess, char *oldname, char *newname) if (user) { tree_remove (sess->usertree, user, &pos); - tree_remove (sess->usertree_alpha, user, &pos); + fe_userlist_remove (sess, user); safe_strcpy (user->nick, newname, NICKLEN); - tree_insert (sess->usertree_alpha, user); - - fe_userlist_move (sess, user, tree_insert (sess->usertree, user)); - fe_userlist_numbers (sess); + tree_insert (sess->usertree, user); + fe_userlist_insert (sess, user, FALSE); return 1; } @@ -381,7 +349,6 @@ userlist_remove_user (struct session *sess, struct User *user) sess->me = NULL; tree_remove (sess->usertree, user, &pos); - tree_remove (sess->usertree_alpha, user, &pos); free_user (user, NULL); } @@ -397,8 +364,7 @@ userlist_add (struct session *sess, char *name, char *hostname, notify_set_online (sess->server, name + prefix_chars, tags_data); - user = malloc (sizeof (struct User)); - memset (user, 0, sizeof (struct User)); + user = g_new0 (struct User, 1); user->access = acc; @@ -408,7 +374,7 @@ userlist_add (struct session *sess, char *name, char *hostname, /* add it to our linked list */ if (hostname) - user->hostname = strdup (hostname); + user->hostname = g_strdup (hostname); safe_strcpy (user->nick, name + prefix_chars, NICKLEN); /* is it me? */ if (!sess->server->p_cmp (user->nick, sess->server->nick)) @@ -417,9 +383,9 @@ userlist_add (struct session *sess, char *name, char *hostname, if (sess->server->have_extjoin) { if (account && *account) - user->account = strdup (account); + user->account = g_strdup (account); if (realname && *realname) - user->realname = strdup (realname); + user->realname = g_strdup (realname); } row = userlist_insertname (sess, user); @@ -427,13 +393,10 @@ userlist_add (struct session *sess, char *name, char *hostname, /* duplicate? some broken servers trigger this */ if (row == -1) { - if (user->hostname) - free (user->hostname); - if (user->account) - free (user->account); - if (user->realname) - free (user->realname); - free (user); + g_free (user->hostname); + g_free (user->account); + g_free (user->realname); + g_free (user); return; } @@ -451,7 +414,7 @@ userlist_add (struct session *sess, char *name, char *hostname, if (user->me) sess->me = user; - fe_userlist_insert (sess, user, row, FALSE); + fe_userlist_insert (sess, user, FALSE); fe_userlist_numbers (sess); } @@ -465,7 +428,7 @@ rehash_cb (struct User *user, session *sess) void userlist_rehash (session *sess) { - tree_foreach (sess->usertree_alpha, (tree_traverse_func *)rehash_cb, sess); + tree_foreach (sess->usertree, (tree_traverse_func *)rehash_cb, sess); } static int @@ -480,7 +443,7 @@ userlist_flat_list (session *sess) { GSList *list = NULL; - tree_foreach (sess->usertree_alpha, (tree_traverse_func *)flat_cb, &list); + tree_foreach (sess->usertree, (tree_traverse_func *)flat_cb, &list); return g_slist_reverse (list); } @@ -496,6 +459,6 @@ userlist_double_list(session *sess) { GList *list = NULL; - tree_foreach (sess->usertree_alpha, (tree_traverse_func *)double_cb, &list); + tree_foreach (sess->usertree, (tree_traverse_func *)double_cb, &list); return list; } diff --git a/src/common/userlist.h b/src/common/userlist.h index ebf95606..0c53dc71 100644 --- a/src/common/userlist.h +++ b/src/common/userlist.h @@ -61,5 +61,7 @@ void userlist_update_mode (session *sess, char *name, char mode, char sign); GSList *userlist_flat_list (session *sess); GList *userlist_double_list (session *sess); void userlist_rehash (session *sess); +int nick_cmp_az_ops (server *serv, struct User *user1, struct User *user2); +int nick_cmp_alpha (struct User *user1, struct User *user2, server *serv); #endif diff --git a/src/common/util.c b/src/common/util.c index b5ee1af2..be3dcac2 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -31,7 +31,6 @@ #ifdef WIN32 #include <sys/timeb.h> -#include <process.h> #include <io.h> #include <VersionHelpers.h> #else @@ -41,7 +40,7 @@ #include <sys/utsname.h> #endif -#include "../../config.h" +#include "config.h" #include <fcntl.h> #include <errno.h> #include "hexchat.h" @@ -52,9 +51,6 @@ #if defined (USING_FREEBSD) || defined (__APPLE__) #include <sys/sysctl.h> #endif -#ifdef SOCKS -#include <socks.h> -#endif /* SASL mechanisms */ #ifdef USE_OPENSSL @@ -67,10 +63,6 @@ #endif #endif -#ifndef HAVE_SNPRINTF -#define snprintf g_snprintf -#endif - char * file_part (char *file) { @@ -254,11 +246,11 @@ expand_homedir (char *file) if (file[0] == '~') { + char *slash_pos; + if (file[1] == '\0' || file[1] == '/') return g_strconcat (g_get_home_dir (), &file[1], NULL); - char *slash_pos; - user = g_strdup(file); slash_pos = strchr(user, '/'); @@ -370,13 +362,13 @@ strip_hidden_attribute (char *src, char *dst) return len; } -#if defined (USING_LINUX) || defined (USING_FREEBSD) || defined (__APPLE__) +#if defined (USING_LINUX) || defined (USING_FREEBSD) || defined (__APPLE__) || defined (__CYGWIN__) static void get_cpu_info (double *mhz, int *cpus) { -#ifdef USING_LINUX +#if defined(USING_LINUX) || defined (__CYGWIN__) char buf[256]; int fh; @@ -508,7 +500,22 @@ get_sys_str (int with_cpu) static char winver[20]; double mhz; - if (IsWindows8Point1OrGreater ()) + /* Broken since major bumped to 10, should start to work eventually. + * No, IsWindowsVersionOrGreater (10, 0, 0) doesn't work either. + * TODO: replace with IsWindows10OrGreater() once added to the SDK. + */ + if (IsWindowsVersionOrGreater (6, 4, 0)) + { + if (IsWindowsServer ()) + { + strcpy (winver, "Server 10"); + } + else + { + strcpy (winver, "10"); + } + } + else if (IsWindows8Point1OrGreater ()) { if (IsWindowsServer ()) { @@ -610,7 +617,7 @@ get_sys_str (int with_cpu) char * get_sys_str (int with_cpu) { -#if defined (USING_LINUX) || defined (USING_FREEBSD) || defined (__APPLE__) +#if defined (USING_LINUX) || defined (USING_FREEBSD) || defined (__APPLE__) || defined (__CYGWIN__) double mhz; #endif int cpus = 1; @@ -620,24 +627,24 @@ get_sys_str (int with_cpu) if (buf) return buf; - buf = malloc (128); - uname (&un); -#if defined (USING_LINUX) || defined (USING_FREEBSD) || defined (__APPLE__) +#if defined (USING_LINUX) || defined (USING_FREEBSD) || defined (__APPLE__) || defined (__CYGWIN__) get_cpu_info (&mhz, &cpus); if (mhz && with_cpu) { double cpuspeed = ( mhz > 1000 ) ? mhz / 1000 : mhz; const char *cpuspeedstr = ( mhz > 1000 ) ? "GHz" : "MHz"; - snprintf (buf, 128, - (cpus == 1) ? "%s %s [%s/%.2f%s]" : "%s %s [%s/%.2f%s/SMP]", - un.sysname, un.release, un.machine, - cpuspeed, cpuspeedstr); + buf = g_strdup_printf ( + (cpus == 1) ? "%s %s [%s/%.2f%s]" : "%s %s [%s/%.2f%s/SMP]", + un.sysname, un.release, un.machine, + cpuspeed, cpuspeedstr); } else + buf = g_strdup_printf ("%s %s", un.sysname, un.release); +#else + buf = g_strdup_printf ("%s %s", un.sysname, un.release); #endif - snprintf (buf, 128, "%s %s", un.sysname, un.release); return buf; } @@ -1217,80 +1224,6 @@ const unsigned char rfc_tolowertab[] = 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff }; -/*static unsigned char touppertab[] = - { 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, - 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14, - 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, - 0x1e, 0x1f, - ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')', - '*', '+', ',', '-', '.', '/', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', - ':', ';', '<', '=', '>', '?', - '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', - 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', - 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', - 0x5f, - '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', - 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', - 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^', - 0x7f, - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, - 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, - 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, - 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, - 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, - 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, - 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, - 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, - 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, - 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, - 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, - 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, - 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, - 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff -};*/ - -/*static int -rename_utf8 (char *oldname, char *newname) -{ - int sav, res; - char *fso, *fsn; - - fso = hexchat_filename_from_utf8 (oldname, -1, 0, 0, 0); - if (!fso) - return FALSE; - fsn = hexchat_filename_from_utf8 (newname, -1, 0, 0, 0); - if (!fsn) - { - g_free (fso); - return FALSE; - } - - res = rename (fso, fsn); - sav = errno; - g_free (fso); - g_free (fsn); - errno = sav; - return res; -} - -static int -unlink_utf8 (char *fname) -{ - int res; - char *fs; - - fs = hexchat_filename_from_utf8 (fname, -1, 0, 0, 0); - if (!fs) - return FALSE; - - res = unlink (fs); - g_free (fs); - return res; -}*/ - static gboolean file_exists (char *fname) { @@ -1526,7 +1459,7 @@ canonalize_key (char *key) } int -portable_mode () +portable_mode (void) { #ifdef WIN32 if ((_access( "portable-mode", 0 )) != -1) @@ -1543,7 +1476,7 @@ portable_mode () } int -unity_mode () +unity_mode (void) { #ifdef G_OS_UNIX const char *env = g_getenv("XDG_CURRENT_DESKTOP"); @@ -1578,7 +1511,7 @@ parse_dh (char *str, DH **dh_out, unsigned char **secret_out, int *keysize_out) { DH *dh; guchar *data, *decoded_data; - guchar *secret; + guchar *secret = NULL; gsize data_len; guint size; guint16 size16; @@ -1630,7 +1563,7 @@ parse_dh (char *str, DH **dh_out, unsigned char **secret_out, int *keysize_out) if (!(DH_generate_key (dh))) goto fail; - secret = (unsigned char*)malloc (DH_size(dh)); + secret = g_malloc (DH_size (dh)); key_size = DH_compute_key (secret, pubkey, dh); if (key_size == -1) goto fail; @@ -1643,8 +1576,9 @@ parse_dh (char *str, DH **dh_out, unsigned char **secret_out, int *keysize_out) return 1; fail: - if (decoded_data) - g_free (decoded_data); + g_free (secret); + g_free (decoded_data); + return 0; } @@ -1652,7 +1586,7 @@ char * encode_sasl_pass_blowfish (char *user, char *pass, char *data) { DH *dh; - char *response, *ret; + char *response, *ret = NULL; unsigned char *secret; unsigned char *encrypted_pass; char *plain_pass; @@ -1667,11 +1601,9 @@ encode_sasl_pass_blowfish (char *user, char *pass, char *data) return NULL; BF_set_key (&key, key_size, secret); - encrypted_pass = (guchar*)malloc (pass_len); - memset (encrypted_pass, 0, pass_len); - plain_pass = (char*)malloc (pass_len); - memset (plain_pass, 0, pass_len); - memcpy (plain_pass, pass, pass_len); + encrypted_pass = g_malloc0 (pass_len); + plain_pass = g_malloc0 (pass_len); + memcpy (plain_pass, pass, strlen(pass)); out_ptr = (char*)encrypted_pass; in_ptr = (char*)plain_pass; @@ -1680,7 +1612,7 @@ encode_sasl_pass_blowfish (char *user, char *pass, char *data) /* Create response */ length = 2 + BN_num_bytes (dh->pub_key) + pass_len + user_len + 1; - response = (char*)malloc (length); + response = g_malloc0 (length); out_ptr = response; /* our key */ @@ -1699,11 +1631,12 @@ encode_sasl_pass_blowfish (char *user, char *pass, char *data) ret = g_base64_encode ((const guchar*)response, length); - DH_free (dh); - free (plain_pass); - free (encrypted_pass); - free (secret); - free (response); + g_free (response); + + DH_free(dh); + g_free (plain_pass); + g_free (encrypted_pass); + g_free (secret); return ret; } @@ -1729,10 +1662,8 @@ encode_sasl_pass_aes (char *user, char *pass, char *data) if (!parse_dh (data, &dh, &secret, &key_size)) return NULL; - encrypted_userpass = (guchar*)malloc (userpass_len); - memset (encrypted_userpass, 0, userpass_len); - plain_userpass = (guchar*)malloc (userpass_len); - memset (plain_userpass, 0, userpass_len); + encrypted_userpass = g_malloc0 (userpass_len); + plain_userpass = g_malloc0 (userpass_len); /* create message */ /* format of: <username>\0<password>\0<padding> */ @@ -1763,7 +1694,7 @@ encode_sasl_pass_aes (char *user, char *pass, char *data) /* Create response */ /* format of: <size pubkey><pubkey><iv (always 16 bytes)><ciphertext> */ length = 2 + key_size + sizeof(iv) + userpass_len; - response = (char*)malloc (length); + response = g_malloc (length); out_ptr = response; /* our key */ @@ -1784,11 +1715,10 @@ encode_sasl_pass_aes (char *user, char *pass, char *data) end: DH_free (dh); - free (plain_userpass); - free (encrypted_userpass); - free (secret); - if (response) - free (response); + g_free (plain_userpass); + g_free (encrypted_userpass); + g_free (secret); + g_free (response); return ret; } @@ -1866,9 +1796,7 @@ challengeauth_response (char *username, char *password, char *challenge) g_string_append_printf (buf, "%02x", (unsigned int) digest[i]); } - digest = (unsigned char *) g_string_free (buf, FALSE); - - return (char *) digest; + return g_string_free (buf, FALSE); } #endif diff --git a/src/common/util.h b/src/common/util.h index 5231e56d..2c9f790c 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -73,12 +73,12 @@ guint32 str_hash (const char *key); guint32 str_ihash (const unsigned char *key); void safe_strcpy (char *dest, const char *src, int bytes_left); void canonalize_key (char *key); -int portable_mode (); -int unity_mode (); +int portable_mode (void); +int unity_mode (void); char *encode_sasl_pass_plain (char *user, char *pass); char *encode_sasl_pass_blowfish (char *user, char *pass, char *data); char *encode_sasl_pass_aes (char *user, char *pass, char *data); char *challengeauth_response (char *username, char *password, char *challenge); size_t strftime_validated (char *dest, size_t destsize, const char *format, const struct tm *time); -size_t strftime_utf8 (char *dest, size_t destsize, const char *format, time_t time); +gsize strftime_utf8 (char *dest, gsize destsize, const char *format, time_t time); #endif diff --git a/src/dirent/dirent-win32.h b/src/dirent/dirent-win32.h index cf3fe567..d1954c6b 100644 --- a/src/dirent/dirent-win32.h +++ b/src/dirent/dirent-win32.h @@ -198,13 +198,13 @@ * only defined for compatibility. These macros should always return false * on Windows. */ -#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) -#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) -#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) -#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) -#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) -#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) -#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) +#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO) +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) +#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) +#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) +#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) +#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) /* Return the exact length of d_namlen without zero terminator */ #define _D_EXACT_NAMLEN(p) ((p)->d_namlen) @@ -305,6 +305,7 @@ _wopendir( { _WDIR *dirp = NULL; int error; + DWORD n; /* Must have directory name */ if (dirname == NULL || dirname[0] == '\0') { @@ -313,73 +314,58 @@ _wopendir( } /* Allocate new _WDIR structure */ - dirp = (_WDIR*) malloc (sizeof (struct _WDIR)); - if (dirp != NULL) { - DWORD n; - - /* Reset _WDIR structure */ - dirp->handle = INVALID_HANDLE_VALUE; - dirp->patt = NULL; - dirp->cached = 0; - - /* Compute the length of full path plus zero terminator */ - n = GetFullPathNameW (dirname, 0, NULL, NULL); - - /* Allocate room for absolute directory name and search pattern */ - dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16); - if (dirp->patt) { - - /* - * Convert relative directory name to an absolute one. This - * allows rewinddir() to function correctly even when current - * working directory is changed between opendir() and rewinddir(). - */ - n = GetFullPathNameW (dirname, n, dirp->patt, NULL); - if (n > 0) { - wchar_t *p; - - /* Append search pattern \* to the directory name */ - p = dirp->patt + n; - if (dirp->patt < p) { - switch (p[-1]) { - case '\\': - case '/': - case ':': - /* Directory ends in path separator, e.g. c:\temp\ */ - /*NOP*/; - break; - - default: - /* Directory name doesn't end in path separator */ - *p++ = '\\'; - } - } - *p++ = '*'; - *p = '\0'; - - /* Open directory stream and retrieve the first entry */ - if (dirent_first (dirp)) { - /* Directory stream opened successfully */ - error = 0; - } else { - /* Cannot retrieve first entry */ - error = 1; - dirent_set_errno (ENOENT); - } - - } else { - /* Cannot retrieve full path name */ - dirent_set_errno (ENOENT); - error = 1; + dirp = (_WDIR*) g_new (struct _WDIR, 1); + /* Reset _WDIR structure */ + dirp->handle = INVALID_HANDLE_VALUE; + dirp->patt = NULL; + dirp->cached = 0; + + /* Compute the length of full path plus zero terminator */ + n = GetFullPathNameW (dirname, 0, NULL, NULL); + + /* Allocate room for absolute directory name and search pattern */ + dirp->patt = g_malloc (sizeof (wchar_t) * n + 16); + /* + * Convert relative directory name to an absolute one. This + * allows rewinddir() to function correctly even when current + * working directory is changed between opendir() and rewinddir(). + */ + n = GetFullPathNameW (dirname, n, dirp->patt, NULL); + if (n > 0) { + wchar_t *p; + + /* Append search pattern \* to the directory name */ + p = dirp->patt + n; + if (dirp->patt < p) { + switch (p[-1]) { + case '\\': + case '/': + case ':': + /* Directory ends in path separator, e.g. c:\temp\ */ + /*NOP*/; + break; + + default: + /* Directory name doesn't end in path separator */ + *p++ = '\\'; } + } + *p++ = '*'; + *p = '\0'; + /* Open directory stream and retrieve the first entry */ + if (dirent_first (dirp)) { + /* Directory stream opened successfully */ + error = 0; } else { - /* Cannot allocate memory for search pattern */ + /* Cannot retrieve first entry */ error = 1; + dirent_set_errno (ENOENT); } } else { - /* Cannot allocate _WDIR structure */ + /* Cannot retrieve full path name */ + dirent_set_errno (ENOENT); error = 1; } @@ -472,13 +458,11 @@ _wclosedir( } /* Release search pattern */ - if (dirp->patt) { - free (dirp->patt); - dirp->patt = NULL; - } + g_free (dirp->patt); + dirp->patt = NULL; /* Release directory structure */ - free (dirp); + g_free (dirp); ok = /*success*/0; } else { @@ -579,6 +563,8 @@ opendir( { struct DIR *dirp; int error; + wchar_t wname[PATH_MAX + 1]; + size_t n; /* Must have directory name */ if (dirname == NULL || dirname[0] == '\0') { @@ -587,44 +573,36 @@ opendir( } /* Allocate memory for DIR structure */ - dirp = (DIR*) malloc (sizeof (struct DIR)); - if (dirp) { - wchar_t wname[PATH_MAX + 1]; - size_t n; - - /* Convert directory name to wide-character string */ - error = dirent_mbstowcs_s( - &n, wname, PATH_MAX + 1, dirname, PATH_MAX); - if (!error) { - - /* Open directory stream using wide-character name */ - dirp->wdirp = _wopendir (wname); - if (dirp->wdirp) { - /* Directory stream opened */ - error = 0; - } else { - /* Failed to open directory stream */ - error = 1; - } - + dirp = (DIR*) g_new (struct DIR, 1); + + /* Convert directory name to wide-character string */ + error = dirent_mbstowcs_s( + &n, wname, PATH_MAX + 1, dirname, PATH_MAX); + if (!error) { + + /* Open directory stream using wide-character name */ + dirp->wdirp = _wopendir (wname); + if (dirp->wdirp) { + /* Directory stream opened */ + error = 0; } else { - /* - * Cannot convert file name to wide-character string. This - * occurs if the string contains invalid multi-byte sequences or - * the output buffer is too small to contain the resulting - * string. - */ + /* Failed to open directory stream */ error = 1; } } else { - /* Cannot allocate DIR structure */ + /* + * Cannot convert file name to wide-character string. This + * occurs if the string contains invalid multi-byte sequences or + * the output buffer is too small to contain the resulting + * string. + */ error = 1; } /* Clean up in case of error */ - if (error && dirp) { - free (dirp); + if (error != 0) { + g_free (dirp); dirp = NULL; } @@ -733,14 +711,14 @@ closedir( DIR *dirp) { int ok; - if (dirp) { + if (dirp != NULL) { /* Close wide-character directory stream */ ok = _wclosedir (dirp->wdirp); dirp->wdirp = NULL; /* Release multi-byte character version */ - free (dirp); + g_free (dirp); } else { diff --git a/src/fe-gtk/Makefile.am b/src/fe-gtk/Makefile.am index a8f43ac5..71179853 100644 --- a/src/fe-gtk/Makefile.am +++ b/src/fe-gtk/Makefile.am @@ -1,3 +1,6 @@ + +include $(top_srcdir)/m4/clang-analyze.am + localedir = $(datadir)/locale bin_PROGRAMS = hexchat @@ -9,7 +12,7 @@ hexchat_LDADD = ../common/libhexchatcommon.a $(GUI_LIBS) EXTRA_DIST = \ ascii.h banlist.h chanlist.h chanview.h chanview-tabs.c \ chanview-tree.c custom-list.h editlist.h fe-gtk.h fkeys.h gtkutil.h joind.h \ - maingui.h menu.h notifygui.h palette.h pixmaps.h \ + maingui.h menu.h notifygui.h notifications palette.h pixmaps.h plugin-notification.h \ plugin-tray.h plugingui.c plugingui.h rawlog.h sexy-iso-codes.h \ sexy-spell-entry.h textgui.h urlgrab.h userlistgui.h xtext.h \ ../../data/hexchat.gresource.xml @@ -26,12 +29,29 @@ if HAVE_ISO_CODES iso_codes_c = sexy-iso-codes.c endif +if USE_LIBNOTIFY +notify_c = notifications/notification-libnotify.c +else +if HAVE_GTK_MAC +notify_c = notifications/notification-osx.m +hexchat_LDFLAGS = -framework Foundation +else +notify_c = notifications/notification-dummy.c +endif +endif + hexchat_SOURCES = ascii.c banlist.c chanlist.c chanview.c custom-list.c \ dccgui.c editlist.c fe-gtk.c fkeys.c gtkutil.c ignoregui.c joind.c menu.c \ - maingui.c notifygui.c palette.c pixmaps.c plugin-tray.c $(plugingui_c) \ - rawlog.c resources.c servlistgui.c setup.c $(iso_codes_c) \ + maingui.c notifygui.c $(notify_c) palette.c pixmaps.c plugin-tray.c $(plugingui_c) \ + plugin-notification.c rawlog.c resources.c servlistgui.c setup.c $(iso_codes_c) \ sexy-spell-entry.c textgui.c urlgrab.c userlistgui.c xtext.c hexchat_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/src/common resources.c: $(top_srcdir)/data/hexchat.gresource.xml $(shell $(GLIB_COMPILE_RESOURCES) --sourcedir=$(top_srcdir)/data --generate-dependencies $(top_srcdir)/data/hexchat.gresource.xml) $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(top_srcdir)/data --generate-source $< + +if DO_STATIC_ANALYSIS +analyze_plists = $(hexchat_SOURCES:%.c=%.plist) +all-local: $(analyze_plists) +MOSTLYCLEANFILES = $(analyze_plists) +endif diff --git a/src/fe-gtk/banlist.c b/src/fe-gtk/banlist.c index d6f44811..e10aaa67 100644 --- a/src/fe-gtk/banlist.c +++ b/src/fe-gtk/banlist.c @@ -491,7 +491,7 @@ banlist_unban_inner (gpointer none, banlist_info *banl, int mode_num) if (!gtk_tree_model_get_iter_first (model, &iter)) return 0; - masks = g_malloc (sizeof (char *) * banl->line_ct); + masks = g_new (char *, banl->line_ct); num_sel = 0; do { @@ -577,17 +577,17 @@ static void banlist_add_selected_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data) { GSList **lp = data; - GSList *list = NULL; GtkTreeIter *copy; - if (!lp) return; - list = *lp; - copy = g_malloc (sizeof (GtkTreeIter)); - g_return_if_fail (copy != NULL); + if (lp == NULL) + { + return; + } + + copy = g_new (GtkTreeIter, 1); *copy = *iter; - list = g_slist_append (list, copy); - *(GSList **)data = list; + *lp = g_slist_append (*lp, copy); } static void @@ -786,14 +786,9 @@ banlist_opengui (struct session *sess) return; } - if (!sess->res->banlist) + if (sess->res->banlist == NULL) { - sess->res->banlist = g_malloc0 (sizeof (banlist_info)); - if (!sess->res->banlist) - { - fe_message (_("Banlist initialization failed."), FE_MSG_ERROR); - return; - } + sess->res->banlist = g_new0 (banlist_info, 1); } banl = sess->res->banlist; if (banl->window) diff --git a/src/fe-gtk/chanlist.c b/src/fe-gtk/chanlist.c index f3a2259d..f6ef46f3 100644 --- a/src/fe-gtk/chanlist.c +++ b/src/fe-gtk/chanlist.c @@ -94,7 +94,7 @@ chanlist_update_caption (server *serv) { gchar tbuf[256]; - snprintf (tbuf, sizeof tbuf, + g_snprintf (tbuf, sizeof tbuf, _("Displaying %d/%d users on %d/%d channels."), serv->gui->chanlist_users_shown_count, serv->gui->chanlist_users_found_count, @@ -148,7 +148,7 @@ chanlist_data_free (server *serv) data = rows->data; g_free (data->topic); g_free (data->collation_key); - free (data); + g_free (data); } g_slist_free (serv->gui->chanlist_data_stored_rows); @@ -370,7 +370,7 @@ fe_add_chan_list (server *serv, char *chan, char *users, char *topic) int len = strlen (chan) + 1; /* we allocate the struct and channel string in one go */ - next_row = malloc (sizeof (chanlistrow) + len); + next_row = g_malloc (sizeof (chanlistrow) + len); memcpy (((char *)next_row) + sizeof (chanlistrow), chan, len); next_row->topic = strip_color (topic, -1, STRIP_ALL); next_row->collation_key = g_utf8_collate_key (chan, len-1); @@ -456,7 +456,7 @@ chanlist_join (GtkWidget * wid, server *serv) { if (serv->connected && (strcmp (chan, "*") != 0)) { - snprintf (tbuf, sizeof (tbuf), "join %s", chan); + g_snprintf (tbuf, sizeof (tbuf), "join %s", chan); handle_command (serv->server_session, tbuf, FALSE); } else gdk_beep (); @@ -482,7 +482,7 @@ chanlist_filereq_done (server *serv, char *file) if (fh == -1) return; - snprintf (buf, sizeof buf, "HexChat Channel List: %s - %s\n", + g_snprintf (buf, sizeof buf, "HexChat Channel List: %s - %s\n", serv->servername, ctime (&t)); write (fh, buf, strlen (buf)); @@ -494,7 +494,7 @@ chanlist_filereq_done (server *serv, char *file) COL_CHANNEL, &chan, COL_USERS, &users, COL_TOPIC, &topic, -1); - snprintf (buf, sizeof buf, "%-16s %-5d%s\n", chan, users, topic); + g_snprintf (buf, sizeof buf, "%-16s %-5d%s\n", chan, users, topic); g_free (chan); g_free (topic); write (fh, buf, strlen (buf)); @@ -717,7 +717,7 @@ chanlist_opengui (server *serv, int do_refresh) return; } - snprintf (tbuf, sizeof tbuf, _(DISPLAY_NAME": Channel List (%s)"), + g_snprintf (tbuf, sizeof tbuf, _(DISPLAY_NAME": Channel List (%s)"), server_get_network (serv, TRUE)); serv->gui->chanlist_pending_rows = NULL; diff --git a/src/fe-gtk/chanview-tabs.c b/src/fe-gtk/chanview-tabs.c index 8f940c24..5681f9d6 100644 --- a/src/fe-gtk/chanview-tabs.c +++ b/src/fe-gtk/chanview-tabs.c @@ -62,12 +62,13 @@ cv_tabs_sizerequest (GtkWidget *viewport, GtkRequisition *requisition, chanview static void cv_tabs_sizealloc (GtkWidget *widget, GtkAllocation *allocation, chanview *cv) { + GdkWindow *parent_win; GtkAdjustment *adj; GtkWidget *inner; gint viewport_size; inner = ((tabview *)cv)->inner; - GdkWindow *parent_win = gtk_widget_get_window (gtk_widget_get_parent (inner)); + parent_win = gtk_widget_get_window (gtk_widget_get_parent (inner)); if (cv->vertical) { @@ -141,7 +142,7 @@ tab_scroll_left_up_clicked (GtkWidget *widget, chanview *cv) gfloat new_value; GtkWidget *inner; GdkWindow *parent_win; - gfloat i; + gdouble i; inner = ((tabview *)cv)->inner; parent_win = gtk_widget_get_window (gtk_widget_get_parent (inner)); @@ -190,7 +191,7 @@ tab_scroll_right_down_clicked (GtkWidget *widget, chanview *cv) gfloat new_value; GtkWidget *inner; GdkWindow *parent_win; - gfloat i; + gdouble i; inner = ((tabview *)cv)->inner; parent_win = gtk_widget_get_window (gtk_widget_get_parent (inner)); diff --git a/src/fe-gtk/chanview.c b/src/fe-gtk/chanview.c index 4c50d922..e5556d9f 100644 --- a/src/fe-gtk/chanview.c +++ b/src/fe-gtk/chanview.c @@ -111,9 +111,8 @@ truncate_tab_name (char *name, int max) if (max > 2 && g_utf8_strlen (name, -1) > max) { /* truncate long channel names */ - buf = malloc (strlen (name) + 4); - strcpy (buf, name); - g_utf8_offset_to_pointer (buf, max)[0] = 0; + buf = g_malloc (strlen (name) + 4); + g_utf8_strncpy (buf, name, max); strcat (buf, ".."); return buf; } @@ -231,7 +230,7 @@ chanview_free_ch (chanview *cv, GtkTreeIter *iter) chan *ch; gtk_tree_model_get (GTK_TREE_MODEL (cv->store), iter, COL_CHAN, &ch, -1); - free (ch); + g_free (ch); } static void @@ -251,7 +250,7 @@ chanview_destroy (chanview *cv) gtk_widget_destroy (cv->box); chanview_destroy_store (cv); - free (cv); + g_free (cv); } static void @@ -267,7 +266,7 @@ chanview_new (int type, int trunc_len, gboolean sort, gboolean use_icons, { chanview *cv; - cv = calloc (1, sizeof (chanview)); + cv = g_new0 (chanview, 1); cv->store = gtk_tree_store_new (4, G_TYPE_STRING, G_TYPE_POINTER, PANGO_TYPE_ATTR_LIST, GDK_TYPE_PIXBUF); cv->style = style; @@ -368,7 +367,7 @@ chanview_add_real (chanview *cv, char *name, void *family, void *userdata, if (!ch) { - ch = calloc (1, sizeof (chan)); + ch = g_new0 (chan, 1); ch->userdata = userdata; ch->family = family; ch->cv = cv; @@ -401,7 +400,7 @@ chanview_add (chanview *cv, char *name, void *family, void *userdata, gboolean a ret = chanview_add_real (cv, new_name, family, userdata, allow_closure, tag, icon, NULL, NULL); if (new_name != name) - free (new_name); + g_free (new_name); return ret; } @@ -492,7 +491,7 @@ chan_rename (chan *ch, char *name, int trunc_len) ch->cv->trunc_len = trunc_len; if (new_name != name) - free (new_name); + g_free (new_name); } /* this thing is overly complicated */ @@ -645,7 +644,7 @@ chan_remove (chan *ch, gboolean force) ch->cv->size--; gtk_tree_store_remove (ch->cv->store, &ch->iter); - free (ch); + g_free (ch); return TRUE; } diff --git a/src/fe-gtk/custom-list.c b/src/fe-gtk/custom-list.c index a954b4a0..f1241947 100644 --- a/src/fe-gtk/custom-list.c +++ b/src/fe-gtk/custom-list.c @@ -134,7 +134,6 @@ custom_list_get_type (void) return custom_list_type; /* Some boilerplate type registration stuff */ - if (1) { static const GTypeInfo custom_list_info = { sizeof (CustomListClass), @@ -154,7 +153,6 @@ custom_list_get_type (void) } /* Here we register our GtkTreeModel interface with the type system */ - if (1) { static const GInterfaceInfo tree_model_info = { (GInterfaceInitFunc) custom_list_tree_model_init, @@ -167,7 +165,6 @@ custom_list_get_type (void) } /* Add GtkTreeSortable interface */ - if (1) { static const GInterfaceInfo tree_sortable_info = { (GInterfaceInitFunc) custom_list_sortable_init, @@ -336,7 +333,7 @@ custom_list_get_iter (GtkTreeModel * tree_model, gint n; n = gtk_tree_path_get_indices (path)[0]; - if (n >= custom_list->num_rows || n < 0) + if (n < 0 || (guint) n >= custom_list->num_rows) return FALSE; record = custom_list->rows[n]; @@ -533,7 +530,7 @@ custom_list_iter_nth_child (GtkTreeModel * tree_model, return FALSE; /* special case: if parent == NULL, set iter to n-th top-level row */ - if (n >= custom_list->num_rows) + if (n < 0 || (guint) n >= custom_list->num_rows) return FALSE; iter->user_data = custom_list->rows[n]; @@ -730,7 +727,7 @@ custom_list_resort (CustomList * custom_list) custom_list); /* let other objects know about the new order */ - neworder = malloc (sizeof (gint) * custom_list->num_rows); + neworder = g_new (gint, custom_list->num_rows); for (i = custom_list->num_rows - 1; i >= 0; i--) { @@ -747,7 +744,7 @@ custom_list_resort (CustomList * custom_list) gtk_tree_model_rows_reordered (GTK_TREE_MODEL (custom_list), path, NULL, neworder); gtk_tree_path_free (path); - free (neworder); + g_free (neworder); } void diff --git a/src/fe-gtk/custom-list.h b/src/fe-gtk/custom-list.h index 64f0535f..30a73919 100644 --- a/src/fe-gtk/custom-list.h +++ b/src/fe-gtk/custom-list.h @@ -77,10 +77,10 @@ struct _CustomList { GObject parent; - guint num_rows; /* number of rows that we have used */ - guint num_alloc; /* number of rows allocated */ - chanlistrow **rows; /* a dynamically allocated array of pointers to the - * CustomRecord structure for each row */ + guint num_rows; /* number of rows that we have used */ + guint num_alloc; /* number of rows allocated */ + chanlistrow **rows; /* a dynamically allocated array of pointers to the + * CustomRecord structure for each row */ gint n_columns; GType column_types[CUSTOM_LIST_N_COLUMNS]; diff --git a/src/fe-gtk/dccgui.c b/src/fe-gtk/dccgui.c index 10ec8388..8c9dc8b4 100644 --- a/src/fe-gtk/dccgui.c +++ b/src/fe-gtk/dccgui.c @@ -88,7 +88,7 @@ struct my_dcc_send { struct session *sess; char *nick; - int maxcps; + gint64 maxcps; int passive; }; @@ -105,7 +105,7 @@ static short view_mode; /* 1=download 2=upload 3=both */ static void -proper_unit (DCC_SIZE size, char *buf, int buf_len) +proper_unit (guint64 size, char *buf, size_t buf_len) { gchar *formatted_str; GFormatSizeFlags format_flags = G_FORMAT_SIZE_DEFAULT; @@ -117,7 +117,7 @@ proper_unit (DCC_SIZE size, char *buf, int buf_len) format_flags = G_FORMAT_SIZE_IEC_UNITS; #endif - formatted_str = g_format_size_full ((guint64)size, format_flags); + formatted_str = g_format_size_full (size, format_flags); g_strlcpy (buf, formatted_str, buf_len); g_free (formatted_str); @@ -130,45 +130,45 @@ dcc_send_filereq_file (struct my_dcc_send *mdc, char *file) dcc_send (mdc->sess, mdc->nick, file, mdc->maxcps, mdc->passive); else { - free (mdc->nick); - free (mdc); + g_free (mdc->nick); + g_free (mdc); } } void fe_dcc_send_filereq (struct session *sess, char *nick, int maxcps, int passive) { - char tbuf[128]; - struct my_dcc_send *mdc; - - mdc = malloc (sizeof (*mdc)); + char* tbuf = g_strdup_printf (_("Send file to %s"), nick); + + struct my_dcc_send *mdc = g_new (struct my_dcc_send, 1); mdc->sess = sess; - mdc->nick = strdup (nick); + mdc->nick = g_strdup (nick); mdc->maxcps = maxcps; mdc->passive = passive; - snprintf (tbuf, sizeof tbuf, _("Send file to %s"), nick); gtkutil_file_req (tbuf, dcc_send_filereq_file, mdc, prefs.hex_dcc_dir, NULL, FRF_MULTIPLE|FRF_FILTERISINITIAL); + + g_free (tbuf); } static void dcc_prepare_row_chat (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter, gboolean update_only) { - static char pos[16], siz[16]; + static char pos[16], size[16]; char *date; date = ctime (&dcc->starttime); date[strlen (date) - 1] = 0; /* remove the \n */ proper_unit (dcc->pos, pos, sizeof (pos)); - proper_unit (dcc->size, siz, sizeof (siz)); + proper_unit (dcc->size, size, sizeof (size)); gtk_list_store_set (store, iter, CCOL_STATUS, _(dccstat[dcc->dccstat].name), CCOL_NICK, dcc->nick, CCOL_RECV, pos, - CCOL_SENT, siz, + CCOL_SENT, size, CCOL_START, date, CCOL_DCC, dcc, CCOL_COLOR, @@ -194,13 +194,12 @@ dcc_prepare_row_send (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter, per = (float) ((dcc->ack * 100.00) / dcc->size); proper_unit (dcc->size, size, sizeof (size)); proper_unit (dcc->pos, pos, sizeof (pos)); - snprintf (kbs, sizeof (kbs), "%.1f", ((float)dcc->cps) / 1024); -/* proper_unit (dcc->ack, ack, sizeof (ack));*/ - snprintf (perc, sizeof (perc), "%.0f%%", per); + g_snprintf (kbs, sizeof (kbs), "%.1f", ((float)dcc->cps) / 1024); + g_snprintf (perc, sizeof (perc), "%.0f%%", per); if (dcc->cps != 0) { to_go = (dcc->size - dcc->ack) / dcc->cps; - snprintf (eta, sizeof (eta), "%.2d:%.2d:%.2d", + g_snprintf (eta, sizeof (eta), "%.2d:%.2d:%.2d", to_go / 3600, (to_go / 60) % 60, to_go % 60); } else strcpy (eta, "--:--:--"); @@ -253,14 +252,14 @@ dcc_prepare_row_recv (struct DCC *dcc, GtkListStore *store, GtkTreeIter *iter, proper_unit (dcc->resumable, pos, sizeof (pos)); else proper_unit (dcc->pos, pos, sizeof (pos)); - snprintf (kbs, sizeof (kbs), "%.1f", ((float)dcc->cps) / 1024); + g_snprintf (kbs, sizeof (kbs), "%.1f", ((float)dcc->cps) / 1024); /* percentage recv'ed */ per = (float) ((dcc->pos * 100.00) / dcc->size); - snprintf (perc, sizeof (perc), "%.0f%%", per); + g_snprintf (perc, sizeof (perc), "%.0f%%", per); if (dcc->cps != 0) { to_go = (dcc->size - dcc->pos) / dcc->cps; - snprintf (eta, sizeof (eta), "%.2d:%.2d:%.2d", + g_snprintf (eta, sizeof (eta), "%.2d:%.2d:%.2d", to_go / 3600, (to_go / 60) % 60, to_go % 60); } else strcpy (eta, "--:--:--"); @@ -526,7 +525,7 @@ resume_clicked (GtkWidget * wid, gpointer none) fe_message (_("That file is not resumable."), FE_MSG_ERROR); break; case 1: - snprintf (buf, sizeof (buf), + g_snprintf (buf, sizeof (buf), _( "Cannot access file: %s\n" "%s.\n" "Resuming not possible."), dcc->destfile, @@ -607,7 +606,7 @@ browse_folder (char *dir) #else char buf[512]; - snprintf (buf, sizeof (buf), "file://%s", dir); + g_snprintf (buf, sizeof (buf), "file://%s", dir); fe_open_url (buf); #endif } @@ -640,7 +639,7 @@ dcc_details_populate (struct DCC *dcc) gtk_label_set_text (GTK_LABEL (dccfwin.file_label), dcc->file); /* address and port */ - snprintf (buf, sizeof (buf), "%s : %d", net_ip (dcc->addr), dcc->port); + g_snprintf (buf, sizeof (buf), "%s : %d", net_ip (dcc->addr), dcc->port); gtk_label_set_text (GTK_LABEL (dccfwin.address_label), buf); } @@ -738,7 +737,7 @@ dcc_detail_label (char *text, GtkWidget *box, int num) char buf[64]; label = gtk_label_new (NULL); - snprintf (buf, sizeof (buf), "<b>%s</b>", text); + g_snprintf (buf, sizeof (buf), "<b>%s</b>", text); gtk_label_set_markup (GTK_LABEL (label), buf); gtk_misc_set_alignment (GTK_MISC (label), 0, 0); gtk_table_attach (GTK_TABLE (box), label, 0, 1, 0 + num, 1 + num, GTK_FILL, GTK_FILL, 0, 0); diff --git a/src/fe-gtk/editlist.c b/src/fe-gtk/editlist.c index f7e22d52..4b236dc1 100644 --- a/src/fe-gtk/editlist.c +++ b/src/fe-gtk/editlist.c @@ -283,6 +283,7 @@ editlist_treeview_new (GtkWidget *box, char *title1, char *title2) view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (view), TRUE); gtk_tree_view_set_enable_search (GTK_TREE_VIEW (view), FALSE); + gtk_tree_view_set_reorderable (GTK_TREE_VIEW (view), TRUE); g_signal_connect (G_OBJECT (view), "key_press_event", G_CALLBACK (editlist_keypress), NULL); @@ -313,7 +314,6 @@ editlist_treeview_new (GtkWidget *box, char *title1, char *title2) gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_AUTOSIZE); gtk_tree_view_column_set_resizable (col, TRUE); gtk_tree_view_column_set_min_width (col, 100); - col = gtk_tree_view_get_column (GTK_TREE_VIEW (view), CMD_COLUMN); gtk_container_add (GTK_CONTAINER (scroll), view); gtk_container_add (GTK_CONTAINER (box), scroll); diff --git a/src/fe-gtk/fe-gtk.c b/src/fe-gtk/fe-gtk.c index 4b7d916f..8c163eb7 100644 --- a/src/fe-gtk/fe-gtk.c +++ b/src/fe-gtk/fe-gtk.c @@ -52,6 +52,7 @@ #include "plugin-tray.h" #include "urlgrab.h" #include "setup.h" +#include "plugin-notification.h" #ifdef USE_LIBCANBERRA #include <canberra.h> @@ -224,7 +225,7 @@ fe_args (int argc, char *argv[]) /* cuts can. So we have to set the current dir manually, to the path */ /* of the exe. */ { - char *tmp = strdup (argv[0]); + char *tmp = g_strdup (argv[0]); char *sl; sl = strrchr (tmp, G_DIR_SEPARATOR); @@ -233,7 +234,7 @@ fe_args (int argc, char *argv[]) *sl = 0; chdir (tmp); } - free (tmp); + g_free (tmp); } #endif @@ -265,7 +266,7 @@ create_input_style (GtkStyle *style) /* fall back */ if (pango_font_description_get_size (style->font_desc) == 0) { - snprintf (buf, sizeof (buf), _("Failed to open font:\n\n%s"), prefs.hex_text_font); + g_snprintf (buf, sizeof (buf), _("Failed to open font:\n\n%s"), prefs.hex_text_font); fe_message (buf, FE_MSG_ERROR); pango_font_description_free (style->font_desc); style->font_desc = pango_font_description_from_string ("sans 11"); @@ -381,6 +382,8 @@ fe_idle (gpointer data) { session *sess = sess_list->data; + plugin_add (sess, NULL, NULL, notification_plugin_init, notification_plugin_deinit, NULL, FALSE); + plugin_add (sess, NULL, NULL, tray_plugin_init, tray_plugin_deinit, NULL, FALSE); if (arg_minimize == 1) @@ -424,8 +427,7 @@ fe_new_window (session *sess, int focus) void fe_new_server (struct server *serv) { - serv->gui = malloc (sizeof (struct server_gui)); - memset (serv->gui, 0, sizeof (struct server_gui)); + serv->gui = g_new0 (struct server_gui, 1); } void @@ -510,18 +512,15 @@ fe_set_topic (session *sess, char *topic, char *stripped_topic) } else { - if (sess->res->topic_text) - { - free (sess->res->topic_text); - } + g_free (sess->res->topic_text); if (prefs.hex_text_stripcolor_topic) { - sess->res->topic_text = strdup (stripped_topic); + sess->res->topic_text = g_strdup (stripped_topic); } else { - sess->res->topic_text = strdup (topic); + sess->res->topic_text = g_strdup (topic); } } } @@ -547,9 +546,8 @@ fe_update_mode_entry (session *sess, GtkWidget *entry, char **text, char *new_te { if (sess->gui->is_tab) { - if (*text) - free (*text); - *text = strdup (new_text); + g_free (*text); + *text = g_strdup (new_text); } } } @@ -721,7 +719,7 @@ fe_lastlog (session *sess, session *lastlog_sess, char *sstr, gtk_xtext_search_f lbuf->search_lnee = strlen (lbuf->search_nee); } lbuf->search_flags = flags; - lbuf->search_text = strdup (sstr); + lbuf->search_text = g_strdup (sstr); gtk_xtext_lastlog (lbuf, buf); } @@ -751,9 +749,9 @@ fe_set_lag (server *serv, long lag) if (per > 1.0) per = 1.0; - snprintf (lagtext, sizeof (lagtext) - 1, "%s%ld.%lds", + g_snprintf (lagtext, sizeof (lagtext) - 1, "%s%ld.%lds", serv->lag_sent ? "+" : "", lag / 1000, (lag/100) % 10); - snprintf (lagtip, sizeof (lagtip) - 1, "Lag: %s%ld.%ld seconds", + g_snprintf (lagtip, sizeof (lagtip) - 1, "Lag: %s%ld.%ld seconds", serv->lag_sent ? "+" : "", lag / 1000, (lag/100) % 10); while (list) @@ -761,9 +759,8 @@ fe_set_lag (server *serv, long lag) sess = list->data; if (sess->server == serv) { - if (sess->res->lag_tip) - free (sess->res->lag_tip); - sess->res->lag_tip = strdup (lagtip); + g_free (sess->res->lag_tip); + sess->res->lag_tip = g_strdup (lagtip); if (!sess->gui->is_tab || current_tab == sess) { @@ -777,9 +774,8 @@ fe_set_lag (server *serv, long lag) } else { sess->res->lag_value = per; - if (sess->res->lag_text) - free (sess->res->lag_text); - sess->res->lag_text = strdup (lagtext); + g_free (sess->res->lag_text); + sess->res->lag_text = g_strdup (lagtext); } } list = list->next; @@ -804,12 +800,11 @@ fe_set_throttle (server *serv) sess = list->data; if (sess->server == serv) { - snprintf (tbuf, sizeof (tbuf) - 1, _("%d bytes"), serv->sendq_len); - snprintf (tip, sizeof (tip) - 1, _("Network send queue: %d bytes"), serv->sendq_len); + g_snprintf (tbuf, sizeof (tbuf) - 1, _("%d bytes"), serv->sendq_len); + g_snprintf (tip, sizeof (tip) - 1, _("Network send queue: %d bytes"), serv->sendq_len); - if (sess->res->queue_tip) - free (sess->res->queue_tip); - sess->res->queue_tip = strdup (tip); + g_free (sess->res->queue_tip); + sess->res->queue_tip = g_strdup (tip); if (!sess->gui->is_tab || current_tab == sess) { @@ -823,9 +818,8 @@ fe_set_throttle (server *serv) } else { sess->res->queue_value = per; - if (sess->res->queue_text) - free (sess->res->queue_text); - sess->res->queue_text = strdup (tbuf); + g_free (sess->res->queue_text); + sess->res->queue_text = g_strdup (tbuf); } } list = list->next; @@ -882,11 +876,10 @@ fe_confirm (const char *message, void (*yesproc)(void *), void (*noproc)(void *) { /* warning, assuming fe_confirm is used by DCC only! */ struct DCC *dcc = ud; - char *filepath; if (dcc->file) { - filepath = g_build_filename (prefs.hex_dcc_dir, dcc->file, NULL); + char *filepath = g_build_filename (prefs.hex_dcc_dir, dcc->file, NULL); gtkutil_file_req (message, dcc_saveas_cb, ud, filepath, NULL, FRF_WRITE|FRF_NOASKOVERWRITE|FRF_FILTERISINITIAL); g_free (filepath); @@ -978,9 +971,8 @@ fe_set_inputbox_contents (session *sess, char *text) SPELL_ENTRY_SET_TEXT (sess->gui->input_box, text); } else { - if (sess->res->input_text) - free (sess->res->input_text); - sess->res->input_text = strdup (text); + g_free (sess->res->input_text); + sess->res->input_text = g_strdup (text); } } @@ -1092,9 +1084,9 @@ fe_open_url (const char *url) /* the http:// part's missing, prepend it, otherwise it won't always work */ else if (strchr (url, ':') == NULL) { - url = g_strdup_printf ("http://%s", url); - fe_open_url_inner (url); - g_free ((char *)url); + uri = g_strdup_printf ("http://%s", url); + fe_open_url_inner (uri); + g_free (uri); } /* we have a sane URL, send it to the browser untouched */ else diff --git a/src/fe-gtk/fe-gtk.h b/src/fe-gtk/fe-gtk.h index 17d1ab4d..ab776f63 100644 --- a/src/fe-gtk/fe-gtk.h +++ b/src/fe-gtk/fe-gtk.h @@ -20,7 +20,7 @@ #ifndef HEXCHAT_FE_GTK_H #define HEXCHAT_FE_GTK_H -#include "../../config.h" +#include "config.h" #define DISPLAY_NAME "HexChat" @@ -39,14 +39,13 @@ #define flag_c flag_wid[0] #define flag_n flag_wid[1] -#define flag_r flag_wid[2] -#define flag_t flag_wid[3] -#define flag_i flag_wid[4] -#define flag_m flag_wid[5] -#define flag_l flag_wid[6] -#define flag_k flag_wid[7] -#define flag_b flag_wid[8] -#define NUM_FLAG_WIDS 9 +#define flag_t flag_wid[2] +#define flag_i flag_wid[3] +#define flag_m flag_wid[4] +#define flag_l flag_wid[5] +#define flag_k flag_wid[6] +#define flag_b flag_wid[7] +#define NUM_FLAG_WIDS 8 #ifdef HAVE_GTK_MAC extern GtkosxApplication *osx_app; @@ -92,9 +91,9 @@ struct server_gui guint chanlist_channels_shown_count; /* total number of displayed channels */ - int chanlist_maxusers; - int chanlist_minusers; - int chanlist_minusers_downloaded; /* used by LIST IRC command */ + guint32 chanlist_maxusers; + guint32 chanlist_minusers; + guint32 chanlist_minusers_downloaded; /* used by LIST IRC command */ int chanlist_search_type; /* 0=simple 1=pattern/wildcard 2=regexp */ gboolean chanlist_caption_is_stale; }; @@ -108,7 +107,7 @@ typedef struct restore_gui void *tab; /* (chan *) */ /* information stored when this tab isn't front-most */ - void *user_model; /* for filling the GtkTreeView */ + GtkListStore *user_model; /* for filling the GtkTreeView */ void *buffer; /* xtext_Buffer */ char *input_text; /* input text buffer (while not-front tab) */ char *topic_text; /* topic GtkEntry buffer */ diff --git a/src/fe-gtk/fe-gtk.vcxproj b/src/fe-gtk/fe-gtk.vcxproj index 59ab17c6..401518b4 100644 --- a/src/fe-gtk/fe-gtk.vcxproj +++ b/src/fe-gtk/fe-gtk.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -19,79 +20,38 @@ <RootNamespace>fegtk</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <TargetName>hexchat</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\hexchat.props" /> + <PropertyGroup> <TargetName>hexchat</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <OutDir>$(HexChatRel)</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> + <!-- WholeProgramOptimization must be turned off for gresource constructors to work, otherwise the .CRT$XCU section is not emitted. --> + <WholeProgramOptimization>false</WholeProgramOptimization> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(SolutionDir)..;$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>..\common;$(HexChatLib);$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <DisableSpecificWarnings>4244;%(DisableSpecificWarnings)</DisableSpecificWarnings> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <AdditionalLibraryDirectories>$(DepsRoot)\lib;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - <AdditionalDependencies>$(DepLibs);common.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>$(DepLibs);$(HexChatLib)common.lib;%(AdditionalDependencies)</AdditionalDependencies> <EntryPointSymbol>mainCRTStartup</EntryPointSymbol> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> + <!-- WholeProgramOptimization must be turned off for gresource constructors to work, otherwise the .CRT$XCU section is not emitted. --> + <WholeProgramOptimization>false</WholeProgramOptimization> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(SolutionDir)..;$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>..\common;$(HexChatLib);$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <DisableSpecificWarnings>4244;4267;%(DisableSpecificWarnings)</DisableSpecificWarnings> </ClCompile> <Link> - <SubSystem>Windows</SubSystem> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - <AdditionalLibraryDirectories>$(DepsRoot)\lib;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> - <AdditionalDependencies>$(DepLibs);common.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <AdditionalDependencies>$(DepLibs);$(HexChatLib)common.lib;%(AdditionalDependencies)</AdditionalDependencies> <EntryPointSymbol>mainCRTStartup</EntryPointSymbol> </Link> </ItemDefinitionGroup> @@ -99,10 +59,10 @@ <PreBuildEvent> <Command><![CDATA[ SET SOLUTIONDIR=$(SolutionDir)..\ -powershell -File "$(SolutionDir)..\win32\version-template.ps1" "$(SolutionDir)..\src\fe-gtk\hexchat.rc.tt" "$(SolutionDir)..\src\fe-gtk\hexchat.rc.utf8" +powershell -File "$(SolutionDir)..\win32\version-template.ps1" "$(SolutionDir)..\src\fe-gtk\hexchat.rc.tt" "$(HexChatLib)hexchat.rc.utf8" REM hexchat.rc needs to be in UCS-2 or Resource Compiler will complain -powershell "Get-Content -Encoding UTF8 '$(SolutionDir)..\src\fe-gtk\hexchat.rc.utf8' | Out-File '$(SolutionDir)..\src\fe-gtk\hexchat.rc'; Remove-Item '$(SolutionDir)..\src\fe-gtk\hexchat.rc.utf8'" -"$(DepsRoot)\bin\glib-compile-resources.exe" --generate-source --sourcedir "$(DataDir)" --target "$(ProjectDir)resources.c" "$(DataDir)hexchat.gresource.xml" +powershell "Get-Content -Encoding UTF8 '$(HexChatLib)hexchat.rc.utf8' | Out-File '$(HexChatLib)hexchat.rc'; Remove-Item '$(HexChatLib)hexchat.rc.utf8'" +"$(DepsRoot)\bin\glib-compile-resources.exe" --generate-source --sourcedir "$(DataDir)" --target "$(HexChatLib)resources.c" "$(DataDir)hexchat.gresource.xml" ]]></Command> <Message>Build hexchat.rc and gresource file</Message> </PreBuildEvent> @@ -120,6 +80,7 @@ powershell "Get-Content -Encoding UTF8 '$(SolutionDir)..\src\fe-gtk\hexchat.rc.u <ClInclude Include="joind.h" /> <ClInclude Include="maingui.h" /> <ClInclude Include="menu.h" /> + <ClInclude Include="notifications\notification-backend.h" /> <ClInclude Include="notifygui.h" /> <ClInclude Include="palette.h" /> <ClInclude Include="pixmaps.h" /> @@ -150,13 +111,15 @@ powershell "Get-Content -Encoding UTF8 '$(SolutionDir)..\src\fe-gtk\hexchat.rc.u <ClCompile Include="joind.c" /> <ClCompile Include="maingui.c" /> <ClCompile Include="menu.c" /> + <ClCompile Include="notifications\notification-windows.c" /> <ClCompile Include="notifygui.c" /> <ClCompile Include="palette.c" /> <ClCompile Include="pixmaps.c" /> + <ClCompile Include="plugin-notification.c" /> <ClCompile Include="plugin-tray.c" /> <ClCompile Include="plugingui.c" /> <ClCompile Include="rawlog.c" /> - <ClCompile Include="resources.c" /> + <ClCompile Include="$(HexChatLib)resources.c" /> <ClCompile Include="servlistgui.c" /> <ClCompile Include="setup.c" /> <ClCompile Include="sexy-iso-codes.c" /> @@ -167,11 +130,11 @@ powershell "Get-Content -Encoding UTF8 '$(SolutionDir)..\src\fe-gtk\hexchat.rc.u <ClCompile Include="xtext.c" /> </ItemGroup> <ItemGroup> - <Manifest Include="hexchat.exe.manifest" /> + <Manifest Include="..\..\win32\hexchat.exe.manifest" /> </ItemGroup> <ItemGroup> <None Include="hexchat.rc.tt" /> - <ResourceCompile Include="hexchat.rc" /> + <ResourceCompile Include="$(HexChatLib)hexchat.rc" /> </ItemGroup> <ItemGroup> <None Include="..\..\data\icons\hexchat.ico" /> @@ -180,6 +143,4 @@ powershell "Get-Content -Encoding UTF8 '$(SolutionDir)..\src\fe-gtk\hexchat.rc.u <Xml Include="..\..\data\hexchat.gresource.xml" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/src/fe-gtk/fe-gtk.vcxproj.filters b/src/fe-gtk/fe-gtk.vcxproj.filters index 4598b1f2..fe211a2d 100644 --- a/src/fe-gtk/fe-gtk.vcxproj.filters +++ b/src/fe-gtk/fe-gtk.vcxproj.filters @@ -93,6 +93,9 @@ <ClInclude Include="setup.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="notifications\notification-backend.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="ascii.c"> @@ -179,17 +182,23 @@ <ClCompile Include="xtext.c"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="resources.c"> + <ClCompile Include="$(HexChatLib)resources.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="plugin-notification.c"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="notifications\notification-windows.c"> <Filter>Source Files</Filter> </ClCompile> </ItemGroup> <ItemGroup> - <Manifest Include="hexchat.exe.manifest"> + <Manifest Include="..\..\win32\hexchat.exe.manifest"> <Filter>Resource Files</Filter> </Manifest> </ItemGroup> <ItemGroup> - <ResourceCompile Include="hexchat.rc"> + <ResourceCompile Include="$(HexChatLib)hexchat.rc"> <Filter>Resource Files</Filter> </ResourceCompile> </ItemGroup> diff --git a/src/fe-gtk/fkeys.c b/src/fe-gtk/fkeys.c index 59086a5e..e762d208 100644 --- a/src/fe-gtk/fkeys.c +++ b/src/fe-gtk/fkeys.c @@ -198,6 +198,7 @@ static const struct key_action key_actions[KEY_MAX_ACTIONS + 1] = { "ACCEL=Down\nNext Command\nD1!\nD2!\n\n"\ "ACCEL=Up\nLast Command\nD1!\nD2!\n\n"\ "ACCEL=Tab\nComplete nick/command\nD1!\nD2!\n\n"\ + "ACCEL=<Shift>ISO_Left_Tab\nComplete nick/command\nD1:Previous\nD2!\n\n"\ "ACCEL=space\nCheck For Replace\nD1!\nD2!\n\n"\ "ACCEL=Return\nCheck For Replace\nD1!\nD2!\n\n"\ "ACCEL=KP_Enter\nCheck For Replace\nD1!\nD2!\n\n"\ @@ -241,10 +242,8 @@ key_free (gpointer data) g_return_if_fail (kb != NULL); - if (kb->data1) - g_free (kb->data1); - if (kb->data2) - g_free (kb->data2); + g_free (kb->data1); + g_free (kb->data2); g_free (kb); } @@ -323,7 +322,7 @@ key_handle_key_press (GtkWidget *wid, GdkEventKey *evt, session *sess) return FALSE; current_sess = sess; - if (plugin_emit_keypress (sess, evt->state, evt->keyval, evt->length, evt->string)) + if (plugin_emit_keypress (sess, evt->state, evt->keyval, gdk_keyval_to_unicode (evt->keyval))) return 1; /* maybe the plugin closed this tab? */ @@ -567,7 +566,7 @@ key_dialog_save (GtkWidget *wid, gpointer userdata) { do { - kb = (struct key_binding *) g_malloc0 (sizeof (struct key_binding)); + kb = g_new0 (struct key_binding, 1); gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, ACCEL_COLUMN, &accel, ACTION_COLUMN, &actiontext, @@ -598,7 +597,8 @@ key_dialog_save (GtkWidget *wid, gpointer userdata) else keybind_list = g_slist_append (keybind_list, kb); - } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter)); + } + while (gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter)); } if (key_save_kbs () == 0) @@ -666,6 +666,7 @@ key_dialog_treeview_new (GtkWidget *box) view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store)); gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (view), TRUE); gtk_tree_view_set_enable_search (GTK_TREE_VIEW (view), FALSE); + gtk_tree_view_set_reorderable (GTK_TREE_VIEW (view), TRUE); g_signal_connect (G_OBJECT (view), "key-press-event", G_CALLBACK (key_dialog_keypress), NULL); @@ -850,7 +851,7 @@ key_save_kbs (void) 0x180, XOF_DOMODE); if (fd < 0) return 1; - write (fd, buf, snprintf (buf, 510, "# HexChat key bindings config file\n\n")); + write (fd, buf, g_snprintf (buf, 510, "# HexChat key bindings config file\n\n")); while (list) { @@ -858,17 +859,17 @@ key_save_kbs (void) accel_text = gtk_accelerator_name (kb->keyval, kb->mod); - snprintf (buf, 510, "ACCEL=%s\n%s\n", accel_text, key_actions[kb->action].name); + g_snprintf (buf, 510, "ACCEL=%s\n%s\n", accel_text, key_actions[kb->action].name); write (fd, buf, strlen (buf)); g_free (accel_text); if (kb->data1 && kb->data1[0]) - write (fd, buf, snprintf (buf, 510, "D1:%s\n", kb->data1)); + write (fd, buf, g_snprintf (buf, 510, "D1:%s\n", kb->data1)); else write (fd, "D1!\n", 4); if (kb->data2 && kb->data2[0]) - write (fd, buf, snprintf (buf, 510, "D2:%s\n", kb->data2)); + write (fd, buf, g_snprintf (buf, 510, "D2:%s\n", kb->data2)); else write (fd, "D2!\n", 4); @@ -946,7 +947,7 @@ key_load_kbs (void) fd = hexchat_open_file ("keybindings.conf", O_RDONLY, 0, 0); if (fd < 0) { - ibuf = strdup (default_kb_cfg); + ibuf = g_strdup (default_kb_cfg); size = strlen (default_kb_cfg); } else @@ -957,7 +958,7 @@ key_load_kbs (void) return 1; } - ibuf = malloc (st.st_size); + ibuf = g_malloc(st.st_size); read (fd, ibuf, st.st_size); size = st.st_size; close (fd); @@ -979,7 +980,7 @@ key_load_kbs (void) switch (state) { case KBSTATE_MOD: - kb = (struct key_binding *) g_malloc0 (sizeof (struct key_binding)); + kb = g_new0 (struct key_binding, 1); /* New format */ if (strncmp (buf, "ACCEL=", 6) == 0) @@ -1010,7 +1011,7 @@ key_load_kbs (void) keyval = gdk_keyval_from_name (buf); if (keyval == 0) { - free (ibuf); + g_free (ibuf); return 2; } @@ -1026,7 +1027,7 @@ key_load_kbs (void) if (kb->action == KEY_MAX_ACTIONS + 1) { - free (ibuf); + g_free (ibuf); return 3; } @@ -1043,7 +1044,7 @@ key_load_kbs (void) if (buf[0] != 'D') { - free (ibuf); + g_free (ibuf); return 4; } @@ -1069,12 +1070,10 @@ key_load_kbs (void) len -= 3; if (state == KBSTATE_DT1) { - kb->data1 = g_malloc (len); - memcpy (kb->data1, &buf[3], len); + kb->data1 = g_strndup (&buf[3], len); } else { - kb->data2 = g_malloc (len); - memcpy (kb->data2, &buf[3], len); + kb->data2 = g_strndup (&buf[3], len); } } else if (buf[2] == '!') { @@ -1097,12 +1096,12 @@ key_load_kbs (void) continue; } } - free (ibuf); + g_free (ibuf); return 0; corrupt_file: - free (ibuf); - free (kb); + g_free (ibuf); + g_free (kb); return 5; } @@ -1410,9 +1409,6 @@ key_action_tab_clean(void) } } -/* Used in the followig completers */ -#define COMP_BUF 2048 - /* For use in sorting the user list for completion */ static int talked_recent_cmp (struct User *a, struct User *b) @@ -1426,16 +1422,31 @@ talked_recent_cmp (struct User *a, struct User *b) return 0; } +#define COMP_BUF 2048 + +static inline glong +len_to_offset (const char *str, glong len) +{ + return g_utf8_pointer_to_offset (str, str + len); +} + +static inline glong +offset_to_len (const char *str, glong offset) +{ + return g_utf8_offset_to_pointer (str, offset) - str; +} + static int key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2, struct session *sess) { - int len = 0, elen = 0, i = 0, cursor_pos, ent_start = 0, comp = 0, found = 0, - prefix_len, skip_len = 0, is_nick, is_cmd = 0; - char buf[COMP_BUF], ent[CHANLEN], *postfix = NULL, *result, *ch; + int len = 0, elen = 0, i = 0, cursor_pos, ent_start = 0, comp = 0, prefix_len, skip_len = 0; + gboolean is_nick = FALSE, is_cmd = FALSE, found = FALSE, has_nick_prefix = FALSE; + char ent[CHANLEN], *postfix = NULL, *result, *ch; GList *list = NULL, *tmp_list = NULL; const char *text; GCompletion *gcomp = NULL; + GString *buf; /* force the IM Context to reset */ SPELL_ENTRY_SET_EDITABLE (t, FALSE); @@ -1449,8 +1460,6 @@ key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2, cursor_pos = SPELL_ENTRY_GET_POS (t); - buf[0] = 0; /* make sure we don't get garbage in the buffer */ - /* handle "nick: " or "nick " or "#channel "*/ ch = g_utf8_find_prev_char(text, g_utf8_offset_to_pointer(text,cursor_pos)); if (ch && ch[0] == ' ') @@ -1489,15 +1498,23 @@ key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2, if (ent_start == 0 && text[0] == prefs.hex_input_command_char[0]) { ent_start++; - is_cmd = 1; + is_cmd = TRUE; } - + else if (strchr (sess->server->chantypes, text[ent_start]) == NULL) + { + is_nick = TRUE; + if (strchr (sess->server->nick_prefixes, text[ent_start]) != NULL) + { + if (ent_start == 0) + has_nick_prefix = TRUE; + ent_start++; + } + } + prefix_len = ent_start; elen = cursor_pos - ent_start; g_utf8_strncpy (ent, g_utf8_offset_to_pointer (text, prefix_len), elen); - - is_nick = (ent[0] == '#' || ent[0] == '&' || is_cmd) ? 0 : 1; if (sess->type == SESS_DIALOG && is_nick) { @@ -1505,7 +1522,7 @@ key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2, if (rfc_ncasecmp (sess->channel, ent, elen) == 0) { result = sess->channel; - is_nick = 0; + is_nick = FALSE; } else return 2; @@ -1562,7 +1579,7 @@ key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2, { if(rfc_ncasecmp(list->data, ent, elen) == 0) { - found = 1; + found = TRUE; break; } list = list->next; @@ -1600,7 +1617,7 @@ key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2, old_gcomp.elen = elen; /* Get the first nick and put out the data for future nickcompletes */ - if (prefs.hex_completion_amount && g_list_length (list) <= prefs.hex_completion_amount) + if (prefs.hex_completion_amount > 0 && g_list_length (list) <= (guint) prefs.hex_completion_amount) { g_free(result); result = (char*)list->data; @@ -1610,40 +1627,42 @@ key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2, /* bash style completion */ if (g_list_next(list) != NULL) { + buf = g_string_sized_new (MAX(COMP_BUF, len + NICKLEN)); if (strlen (result) > elen) /* the largest common prefix is larger than nick, change the data */ { if (prefix_len) - g_utf8_strncpy (buf, text, prefix_len); - strncat (buf, result, COMP_BUF - prefix_len); - cursor_pos = strlen (buf); + g_string_append_len (buf, text, offset_to_len (text, prefix_len)); + g_string_append (buf, result); + cursor_pos = buf->len; g_free(result); if (postfix) { - strcat (buf, " "); - strncat (buf, postfix, COMP_BUF - cursor_pos -1); + g_string_append_c (buf, ' '); + g_string_append (buf, postfix); } - SPELL_ENTRY_SET_TEXT (t, buf); - SPELL_ENTRY_SET_POS (t, g_utf8_pointer_to_offset(buf, buf + cursor_pos)); - buf[0] = 0; + SPELL_ENTRY_SET_TEXT (t, buf->str); + SPELL_ENTRY_SET_POS (t, len_to_offset (buf->str, cursor_pos)); + g_string_erase (buf, 0, -1); } else g_free(result); + while (list) { - len = strlen (buf); /* current buffer */ + len = buf->len; elen = strlen (list->data); /* next item to add */ if (len + elen + 2 >= COMP_BUF) /* +2 is space + null */ { - PrintText (sess, buf); - buf[0] = 0; - len = 0; + PrintText (sess, buf->str); + g_string_erase (buf, 0, -1); } - strcpy (buf + len, (char *) list->data); - strcpy (buf + len + elen, " "); + g_string_append (buf, (char*)list->data); + g_string_append_c (buf, ' '); list = list->next; } - PrintText (sess, buf); + PrintText (sess, buf->str); g_completion_free(gcomp); + g_string_free (buf, TRUE); return 2; } /* Only one matching entry */ @@ -1655,17 +1674,19 @@ key_action_tab_comp (GtkWidget *t, GdkEventKey *entry, char *d1, char *d2, if(result) { + buf = g_string_sized_new (len + NICKLEN); if (prefix_len) - g_utf8_strncpy(buf, text, prefix_len); - strncat (buf, result, COMP_BUF - (prefix_len + 3)); /* make sure nicksuffix and space fits */ - if(!prefix_len && is_nick) - strcat (buf, &prefs.hex_completion_suffix[0]); - strcat (buf, " "); - cursor_pos = strlen (buf); + g_string_append_len (buf, text, offset_to_len (text, prefix_len)); + g_string_append (buf, result); + if((!prefix_len || has_nick_prefix) && is_nick && prefs.hex_completion_suffix[0] != '\0') + g_string_append_unichar (buf, g_utf8_get_char_validated (prefs.hex_completion_suffix, -1)); + g_string_append_c (buf, ' '); + cursor_pos = buf->len; if (postfix) - strncat (buf, postfix, COMP_BUF - cursor_pos - 2); - SPELL_ENTRY_SET_TEXT (t, buf); - SPELL_ENTRY_SET_POS (t, g_utf8_pointer_to_offset(buf, buf + cursor_pos)); + g_string_append (buf, postfix); + SPELL_ENTRY_SET_TEXT (t, buf->str); + SPELL_ENTRY_SET_POS (t, len_to_offset (buf->str, cursor_pos)); + g_string_free (buf, TRUE); } if (gcomp) g_completion_free(gcomp); @@ -1794,10 +1815,10 @@ replace_handle (GtkWidget *t) memcpy (outbuf, text, xlen); outbuf[xlen] = 0; if (postfix_pnt == NULL) - snprintf (word, sizeof (word), "%s", pop->cmd); + g_snprintf (word, sizeof (word), "%s", pop->cmd); else - snprintf (word, sizeof (word), "%s%s", pop->cmd, postfix); - strcat (outbuf, word); + g_snprintf (word, sizeof (word), "%s%s", pop->cmd, postfix); + g_strlcat (outbuf, word, sizeof(outbuf)); SPELL_ENTRY_SET_TEXT (t, outbuf); SPELL_ENTRY_SET_POS (t, -1); return; diff --git a/src/fe-gtk/gtkutil.c b/src/fe-gtk/gtkutil.c index eabe9c75..e2ca1192 100644 --- a/src/fe-gtk/gtkutil.c +++ b/src/fe-gtk/gtkutil.c @@ -62,7 +62,7 @@ static void gtkutil_file_req_destroy (GtkWidget * wid, struct file_req *freq) { freq->callback (freq->userdata, NULL); - free (freq); + g_free (freq); } static void @@ -255,7 +255,7 @@ gtkutil_file_req (const char *title, void *callback, void *userdata, char *filte gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (dialog), get_xdir (), NULL); - freq = malloc (sizeof (struct file_req)); + freq = g_new (struct file_req, 1); freq->dialog = dialog; freq->flags = flags; freq->callback = callback; diff --git a/src/fe-gtk/gtkutil.h b/src/fe-gtk/gtkutil.h index 87beed08..9547cb3b 100644 --- a/src/fe-gtk/gtkutil.h +++ b/src/fe-gtk/gtkutil.h @@ -33,14 +33,6 @@ GtkWidget *gtkutil_button (GtkWidget *box, char *stock, char *tip, void *callbac void gtkutil_label_new (char *text, GtkWidget * box); GtkWidget *gtkutil_entry_new (int max, GtkWidget * box, void *callback, gpointer userdata); -GtkWidget *gtkutil_clist_new (int columns, char *titles[], GtkWidget * box, - int policy, void *select_callback, - gpointer select_userdata, - void *unselect_callback, - gpointer unselect_userdata, int selection_mode); -int gtkutil_clist_selection (GtkWidget * clist); -int gtkutil_clist_multiple_selection (GtkWidget * clist, - int ** rows, const int max_rows); void show_and_unfocus (GtkWidget * wid); void gtkutil_set_icon (GtkWidget *win); GtkWidget *gtkutil_window_new (char *title, char *role, int width, int height, int flags); diff --git a/src/fe-gtk/hexchat.rc.tt b/src/fe-gtk/hexchat.rc.tt index 684ddfdb..35b0e6aa 100644 --- a/src/fe-gtk/hexchat.rc.tt +++ b/src/fe-gtk/hexchat.rc.tt @@ -1,9 +1,9 @@ #include <winver.h> -#include "../../config.h" +#include "config.h" #define COMMA_VERSION <#= [string]::Join(',', $versionParts) #>,0 -XC_ICON ICON "../../data/icons/hexchat.ico" +XC_ICON ICON "<#= $env:SOLUTIONDIR -replace '\\', '/' #>data/icons/hexchat.ico" VS_VERSION_INFO VERSIONINFO FILEVERSION COMMA_VERSION @@ -15,6 +15,7 @@ VS_VERSION_INFO VERSIONINFO BEGIN VALUE "FileDescription", "HexChat IRC Client" + VALUE "CompanyName", "HexChat" VALUE "ProductName", "HexChat" VALUE "ProductVersion", PACKAGE_VERSION VALUE "FileVersion", PACKAGE_VERSION diff --git a/src/fe-gtk/joind.c b/src/fe-gtk/joind.c index 61ce8828..2fdbeb32 100644 --- a/src/fe-gtk/joind.c +++ b/src/fe-gtk/joind.c @@ -151,16 +151,16 @@ joind_show_dialog (server *serv) image1 = gtk_image_new_from_stock (GTK_STOCK_NETWORK, GTK_ICON_SIZE_LARGE_TOOLBAR); gtk_widget_show (image1); gtk_box_pack_start (GTK_BOX (hbox1), image1, FALSE, TRUE, 24); - gtk_misc_set_alignment (GTK_MISC (image1), 0.5, 0.06); + gtk_misc_set_alignment (GTK_MISC (image1), 0.5f, 0.06f); vbox2 = gtk_vbox_new (FALSE, 10); gtk_container_set_border_width (GTK_CONTAINER (vbox2), 6); gtk_widget_show (vbox2); gtk_box_pack_start (GTK_BOX (hbox1), vbox2, TRUE, TRUE, 0); - snprintf (buf2, sizeof (buf2), _("Connection to %s complete."), + g_snprintf (buf2, sizeof (buf2), _("Connection to %s complete."), server_get_network (serv, TRUE)); - snprintf (buf, sizeof (buf), "\n<b>%s</b>", buf2); + g_snprintf (buf, sizeof (buf), "\n<b>%s</b>", buf2); label = gtk_label_new (buf); gtk_widget_show (label); gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, FALSE, 0); @@ -198,7 +198,7 @@ joind_show_dialog (server *serv) gtk_widget_show (entry1); gtk_box_pack_start (GTK_BOX (hbox2), entry1, TRUE, TRUE, 8); - snprintf (buf, sizeof (buf), "<small> %s</small>", + g_snprintf (buf, sizeof (buf), "<small> %s</small>", _("If you know the name of the channel you want to join, enter it here.")); label = gtk_label_new (buf); gtk_widget_show (label); @@ -210,9 +210,8 @@ joind_show_dialog (server *serv) gtk_widget_show (radiobutton3); gtk_box_pack_start (GTK_BOX (vbox2), radiobutton3, FALSE, FALSE, 0); gtk_radio_button_set_group (GTK_RADIO_BUTTON (radiobutton3), radiobutton1_group); - radiobutton1_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radiobutton3)); - snprintf (buf, sizeof (buf), "<small> %s</small>", + g_snprintf (buf, sizeof (buf), "<small> %s</small>", _("Retrieving the Channel-List may take a minute or two.")); label = gtk_label_new (buf); gtk_widget_show (label); @@ -250,7 +249,6 @@ joind_show_dialog (server *serv) if (g_ascii_strcasecmp(((ircnet*)serv->network)->name, "freenode") == 0) { gtk_entry_set_text (GTK_ENTRY (entry1), "#hexchat"); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(radiobutton2), TRUE); } gtk_widget_grab_focus (okbutton1); diff --git a/src/fe-gtk/maingui.c b/src/fe-gtk/maingui.c index 2d50a98c..d718dba0 100644 --- a/src/fe-gtk/maingui.c +++ b/src/fe-gtk/maingui.c @@ -78,7 +78,7 @@ static void mg_link_irctab (session *sess, int focus); static session_gui static_mg_gui; static session_gui *mg_gui = NULL; /* the shared irc tab */ static int ignore_chanmode = FALSE; -static const char chan_flags[] = { 'c', 'n', 'r', 't', 'i', 'm', 'l', 'k' }; +static const char chan_flags[] = { 'c', 'n', 't', 'i', 'm', 'l', 'k' }; static chan *active_tab = NULL; /* active tab */ GtkWidget *parent_window = NULL; /* the master window */ @@ -312,7 +312,7 @@ mg_inputbox_cb (GtkWidget *igad, session_gui *gui) if (cmd[0] == 0) return; - cmd = strdup (cmd); + cmd = g_strdup (cmd); /* avoid recursive loop */ ignore = TRUE; @@ -340,7 +340,7 @@ mg_inputbox_cb (GtkWidget *igad, session_gui *gui) if (sess) handle_multiline (sess, cmd, TRUE, FALSE); - free (cmd); + g_free (cmd); } static gboolean @@ -393,42 +393,42 @@ fe_set_title (session *sess) switch (type) { case SESS_DIALOG: - snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME": %s %s @ %s", + g_snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME": %s %s @ %s", _("Dialog with"), sess->channel, server_get_network (sess->server, TRUE)); break; case SESS_SERVER: - snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME": %s @ %s", + g_snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME": %s @ %s", sess->server->nick, server_get_network (sess->server, TRUE)); break; case SESS_CHANNEL: /* don't display keys in the titlebar */ if (prefs.hex_gui_win_modes) { - snprintf (tbuf, sizeof (tbuf), + g_snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME": %s @ %s / %s (%s)", sess->server->nick, server_get_network (sess->server, TRUE), sess->channel, sess->current_modes ? sess->current_modes : ""); } else { - snprintf (tbuf, sizeof (tbuf), + g_snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME": %s @ %s / %s", sess->server->nick, server_get_network (sess->server, TRUE), sess->channel); } if (prefs.hex_gui_win_ucount) { - snprintf (tbuf + strlen (tbuf), 9, " (%d)", sess->total); + g_snprintf (tbuf + strlen (tbuf), 9, " (%d)", sess->total); } break; case SESS_NOTICES: case SESS_SNOTICES: - snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME": %s @ %s (notices)", + g_snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME": %s @ %s (notices)", sess->server->nick, server_get_network (sess->server, TRUE)); break; default: def: - snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME); + g_snprintf (tbuf, sizeof (tbuf), DISPLAY_NAME); gtk_window_set_title (GTK_WINDOW (sess->gui->window), tbuf); return; } @@ -557,7 +557,7 @@ static int mg_progressbar_update (GtkWidget *bar) { static int type = 0; - static float pos = 0; + static gdouble pos = 0; pos += 0.05; if (pos >= 0.99) @@ -609,14 +609,14 @@ mg_unpopulate (session *sess) gui = sess->gui; res = sess->res; - res->input_text = strdup (SPELL_ENTRY_GET_TEXT (gui->input_box)); - res->topic_text = strdup (gtk_entry_get_text (GTK_ENTRY (gui->topic_entry))); - res->limit_text = strdup (gtk_entry_get_text (GTK_ENTRY (gui->limit_entry))); - res->key_text = strdup (gtk_entry_get_text (GTK_ENTRY (gui->key_entry))); + res->input_text = g_strdup (SPELL_ENTRY_GET_TEXT (gui->input_box)); + res->topic_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (gui->topic_entry))); + res->limit_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (gui->limit_entry))); + res->key_text = g_strdup (gtk_entry_get_text (GTK_ENTRY (gui->key_entry))); if (gui->laginfo) - res->lag_text = strdup (gtk_label_get_text (GTK_LABEL (gui->laginfo))); + res->lag_text = g_strdup (gtk_label_get_text (GTK_LABEL (gui->laginfo))); if (gui->throttleinfo) - res->queue_text = strdup (gtk_label_get_text (GTK_LABEL (gui->throttleinfo))); + res->queue_text = g_strdup (gtk_label_get_text (GTK_LABEL (gui->throttleinfo))); for (i = 0; i < NUM_FLAG_WIDS - 1; i++) res->flag_wid_state[i] = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (gui->flag_wid[i])); @@ -645,7 +645,7 @@ mg_restore_label (GtkWidget *label, char **text) if (*text) { gtk_label_set_text (GTK_LABEL (label), *text); - free (*text); + g_free (*text); *text = NULL; } else { @@ -659,7 +659,7 @@ mg_restore_entry (GtkWidget *entry, char **text) if (*text) { gtk_entry_set_text (GTK_ENTRY (entry), *text); - free (*text); + g_free (*text); *text = NULL; } else { @@ -674,7 +674,7 @@ mg_restore_speller (GtkWidget *entry, char **text) if (*text) { SPELL_ENTRY_SET_TEXT (entry, *text); - free (*text); + g_free (*text); *text = NULL; } else { @@ -1096,8 +1096,11 @@ mg_tab_close (session *sess) else { for (i = 0, list = sess_list; list; list = list->next) - if (((session *)list->data)->server == sess->server) + { + session *s = (session*)list->data; + if (s->server == sess->server && (s->type == SESS_CHANNEL || s->type == SESS_DIALOG)) i++; + } dialog = gtk_message_dialog_new (GTK_WINDOW (parent_window), 0, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, _("This server still has %d channels or dialogs associated with it. " @@ -1331,8 +1334,7 @@ mg_close_gen (chan *ch, GtkWidget *box) { char *title = g_object_get_data (G_OBJECT (box), "title"); - if (title) - free (title); + g_free (title); if (!ch) ch = g_object_get_data (G_OBJECT (box), "ch"); if (ch) @@ -1568,7 +1570,7 @@ mg_create_tabmenu (session *sess, GdkEventButton *event, chan *ch) if (sess) { char *name = g_markup_escape_text (sess->channel[0] ? sess->channel : _("<none>"), -1); - snprintf (buf, sizeof (buf), "<span foreground=\"#3344cc\"><b>%s</b></span>", name); + g_snprintf (buf, sizeof (buf), "<span foreground=\"#3344cc\"><b>%s</b></span>", name); g_free (name); item = gtk_menu_item_new_with_label (""); @@ -1617,7 +1619,7 @@ static gboolean mg_tab_contextmenu_cb (chanview *cv, chan *ch, int tag, gpointer ud, GdkEventButton *event) { /* middle-click or shift-click to close a tab */ - if ((event->button == 2 || (event->button == 1 && event->state & STATE_SHIFT)) + if (((prefs.hex_gui_tab_middleclose && event->button == 2) || (event->button == 1 && event->state & STATE_SHIFT)) && event->type == GDK_BUTTON_PRESS) { mg_xbutton_cb (cv, ch, tag, ud); @@ -1640,7 +1642,7 @@ mg_dnd_drop_file (session *sess, char *target, char *uri) { char *p, *data, *next, *fname; - p = data = strdup (uri); + p = data = g_strdup (uri); while (*p) { next = strchr (p, '\r'); @@ -1652,7 +1654,7 @@ mg_dnd_drop_file (session *sess, char *target, char *uri) if (fname) { /* dcc_send() expects utf-8 */ - p = hexchat_filename_to_utf8 (fname, -1, 0, 0, 0); + p = g_filename_from_utf8 (fname, -1, 0, 0, 0); if (p) { dcc_send (sess, target, p, prefs.hex_dcc_max_send_cps, 0); @@ -1667,7 +1669,7 @@ mg_dnd_drop_file (session *sess, char *target, char *uri) if (*p == '\n') p++; } - free (data); + g_free (data); } @@ -1716,7 +1718,7 @@ mg_add_chan (session *sess) { sess->res->buffer = gtk_xtext_buffer_new (GTK_XTEXT (sess->gui->xtext)); gtk_xtext_set_time_stamp (sess->res->buffer, prefs.hex_stamp_text); - sess->res->user_model = userlist_create_model (); + sess->res->user_model = userlist_create_model (sess); } } @@ -1837,7 +1839,7 @@ mg_changui_destroy (session *sess) /* it fixes: Gdk-CRITICAL **: gdk_colormap_get_screen: */ /* assertion `GDK_IS_COLORMAP (cmap)' failed */ ret = sess->gui->window; - free (sess->gui); + g_free (sess->gui); sess->gui = NULL; } return ret; @@ -1941,7 +1943,7 @@ flagl_hit (GtkWidget * wid, struct session *sess) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wid), FALSE); return; } - snprintf (modes, sizeof (modes), "+l %d", atoi (limit_str)); + g_snprintf (modes, sizeof (modes), "+l %d", atoi (limit_str)); serv->p_mode (serv, sess->channel, modes); serv->p_join_info (serv, sess->channel); } @@ -1957,7 +1959,7 @@ flagk_hit (GtkWidget * wid, struct session *sess) if (serv->connected && sess->channel[0]) { - snprintf (modes, sizeof (modes), "-k %s", + g_snprintf (modes, sizeof (modes), "-k %s", gtk_entry_get_text (GTK_ENTRY (sess->gui->key_entry))); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (wid))) @@ -2001,17 +2003,24 @@ mg_flagbutton_cb (GtkWidget *but, char *flag) static GtkWidget * mg_create_flagbutton (char *tip, GtkWidget *box, char *face) { - GtkWidget *wid; + GtkWidget *btn, *lbl; + char label_markup[16]; + + g_snprintf (label_markup, sizeof(label_markup), "<tt>%s</tt>", face); + lbl = gtk_label_new (NULL); + gtk_label_set_markup (GTK_LABEL(lbl), label_markup); - wid = gtk_toggle_button_new_with_label (face); - gtk_widget_set_size_request (wid, 18, 0); - gtk_widget_set_tooltip_text (wid, tip); - gtk_box_pack_start (GTK_BOX (box), wid, 0, 0, 0); - g_signal_connect (G_OBJECT (wid), "toggled", + btn = gtk_toggle_button_new (); + gtk_widget_set_size_request (btn, -1, 0); + gtk_widget_set_tooltip_text (btn, tip); + gtk_container_add (GTK_CONTAINER(btn), lbl); + + gtk_box_pack_start (GTK_BOX (box), btn, 0, 0, 0); + g_signal_connect (G_OBJECT (btn), "toggled", G_CALLBACK (mg_flagbutton_cb), face); - show_and_unfocus (wid); + show_and_unfocus (btn); - return wid; + return btn; } static void @@ -2023,7 +2032,7 @@ mg_key_entry_cb (GtkWidget * igad, gpointer userdata) if (serv->connected && sess->channel[0]) { - snprintf (modes, sizeof (modes), "+k %s", + g_snprintf (modes, sizeof (modes), "+k %s", gtk_entry_get_text (GTK_ENTRY (igad))); serv->p_mode (serv, sess->channel, modes); serv->p_join_info (serv, sess->channel); @@ -2046,7 +2055,7 @@ mg_limit_entry_cb (GtkWidget * igad, gpointer userdata) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sess->gui->flag_l), FALSE); return; } - snprintf (modes, sizeof(modes), "+l %d", + g_snprintf (modes, sizeof(modes), "+l %d", atoi (gtk_entry_get_text (GTK_ENTRY (igad)))); serv->p_mode (serv, sess->channel, modes); serv->p_join_info (serv, sess->channel); @@ -2066,7 +2075,6 @@ mg_create_chanmodebuttons (session_gui *gui, GtkWidget *box) { gui->flag_c = mg_create_flagbutton (_("Filter Colors"), box, "c"); gui->flag_n = mg_create_flagbutton (_("No outside messages"), box, "n"); - gui->flag_r = mg_create_flagbutton (_("Registered Only"), box, "r"); gui->flag_t = mg_create_flagbutton (_("Topic Protection"), box, "t"); gui->flag_i = mg_create_flagbutton (_("Invite Only"), box, "i"); gui->flag_m = mg_create_flagbutton (_("Moderated"), box, "m"); @@ -2287,7 +2295,7 @@ mg_word_clicked (GtkWidget *xtext, char *word, GdkEventButton *even) case WORD_EMAIL: word[end] = 0; word += start; - tmp = g_strdup_printf("mailto:%s", word + (ispunct (*word)? 1: 0)); + tmp = g_strdup_printf ("mailto:%s", word + (ispunct (*word) ? 1 : 0)); menu_urlmenu (even, tmp); g_free (tmp); break; @@ -2597,7 +2605,7 @@ mg_change_nick (int cancel, char *text, gpointer userdata) if (!cancel) { - snprintf (buf, sizeof (buf), "nick %s", text); + g_snprintf (buf, sizeof (buf), "nick %s", text); handle_command (current_sess, buf, FALSE); } } @@ -2940,7 +2948,7 @@ mg_create_search(session *sess, GtkWidget *box) gtk_box_pack_start(GTK_BOX(gui->shbox), next, FALSE, FALSE, 0); g_signal_connect(G_OBJECT(next), "clicked", G_CALLBACK(mg_search_handle_next), sess); - highlight = gtk_check_button_new_with_mnemonic (_("Highlight _all")); + highlight = gtk_check_button_new_with_mnemonic (_("_Highlight all")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(highlight), prefs.hex_text_search_highlight_all); gtk_widget_set_can_focus (highlight, FALSE); g_signal_connect (G_OBJECT (highlight), "toggled", G_CALLBACK (search_set_option), &prefs.hex_text_search_highlight_all); @@ -3165,7 +3173,7 @@ mg_create_topwindow (session *sess) sess->res->buffer = gtk_xtext_buffer_new (GTK_XTEXT (sess->gui->xtext)); gtk_xtext_buffer_show (GTK_XTEXT (sess->gui->xtext), sess->res->buffer, TRUE); gtk_xtext_set_time_stamp (sess->res->buffer, prefs.hex_stamp_text); - sess->res->user_model = userlist_create_model (); + sess->res->user_model = userlist_create_model (sess); } userlist_show (sess); @@ -3332,7 +3340,7 @@ mg_add_generic_tab (char *name, char *title, void *family, GtkWidget *box) ch = chanview_add (mg_gui->chanview, name, NULL, box, TRUE, TAG_UTIL, pix_tree_util); chan_set_color (ch, plain_list); /* FIXME: memory leak */ - g_object_set_data (G_OBJECT (box), "title", strdup (title)); + g_object_set_data (G_OBJECT (box), "title", g_strdup (title)); g_object_set_data (G_OBJECT (box), "ch", ch); if (prefs.hex_gui_tab_newtofront) @@ -3395,7 +3403,7 @@ fe_clear_channel (session *sess) { if (sess->res->topic_text) { - free (sess->res->topic_text); + g_free (sess->res->topic_text); sess->res->topic_text = NULL; } } @@ -3506,32 +3514,26 @@ mg_changui_new (session *sess, restore_gui *res, int tab, int focus) { int first_run = FALSE; session_gui *gui; - struct User *user = NULL; - if (!res) + if (res == NULL) { - res = malloc (sizeof (restore_gui)); - memset (res, 0, sizeof (restore_gui)); + res = g_new0 (restore_gui, 1); } sess->res = res; - if (!sess->server->front_session) + if (sess->server->front_session == NULL) + { sess->server->front_session = sess; - - if (!is_channel (sess->server, sess->channel)) - user = userlist_find_global (sess->server, sess->channel); + } if (!tab) { - gui = malloc (sizeof (session_gui)); - memset (gui, 0, sizeof (session_gui)); + gui = g_new0 (session_gui, 1); gui->is_tab = FALSE; sess->gui = gui; mg_create_topwindow (sess); fe_set_title (sess); - if (user && user->hostname) - set_topic (sess, user->hostname, user->hostname); return; } @@ -3551,9 +3553,6 @@ mg_changui_new (session *sess, restore_gui *res, int tab, int focus) gui->is_tab = TRUE; } - if (user && user->hostname) - set_topic (sess, user->hostname, user->hostname); - mg_add_chan (sess); if (first_run || (prefs.hex_gui_tab_newtofront == FOCUS_NEW_ONLY_ASKED && focus) @@ -3631,8 +3630,8 @@ mg_set_title (GtkWidget *vbox, char *title) /* for non-irc tab/window only */ old = g_object_get_data (G_OBJECT (vbox), "title"); if (old) { - g_object_set_data (G_OBJECT (vbox), "title", strdup (title)); - free (old); + g_object_set_data (G_OBJECT (vbox), "title", g_strdup (title)); + g_free (old); } else { gtk_window_set_title (GTK_WINDOW (vbox), title); @@ -3650,7 +3649,7 @@ fe_server_callback (server *serv) if (serv->gui->rawlog_window) mg_close_gen (NULL, serv->gui->rawlog_window); - free (serv->gui); + g_free (serv->gui); } /* called when a session is being killed */ @@ -3661,34 +3660,21 @@ fe_session_callback (session *sess) if (sess->res->banlist && sess->res->banlist->window) mg_close_gen (NULL, sess->res->banlist->window); - if (sess->res->input_text) - free (sess->res->input_text); - - if (sess->res->topic_text) - free (sess->res->topic_text); - - if (sess->res->limit_text) - free (sess->res->limit_text); - - if (sess->res->key_text) - free (sess->res->key_text); - - if (sess->res->queue_text) - free (sess->res->queue_text); - if (sess->res->queue_tip) - free (sess->res->queue_tip); - - if (sess->res->lag_text) - free (sess->res->lag_text); - if (sess->res->lag_tip) - free (sess->res->lag_tip); + g_free (sess->res->input_text); + g_free (sess->res->topic_text); + g_free (sess->res->limit_text); + g_free (sess->res->key_text); + g_free (sess->res->queue_text); + g_free (sess->res->queue_tip); + g_free (sess->res->lag_text); + g_free (sess->res->lag_tip); if (sess->gui->bartag) fe_timeout_remove (sess->gui->bartag); if (sess->gui != &static_mg_gui) - free (sess->gui); - free (sess->res); + g_free (sess->gui); + g_free (sess->res); } /* ===== DRAG AND DROP STUFF ===== */ diff --git a/src/fe-gtk/menu.c b/src/fe-gtk/menu.c index 945f6360..902af92e 100644 --- a/src/fe-gtk/menu.c +++ b/src/fe-gtk/menu.c @@ -137,7 +137,7 @@ nick_command_parse (session *sess, char *cmd, char *nick, char *allnick) /* this can't overflow, since popup->cmd is only 256 */ len = strlen (cmd) + strlen (nick) + strlen (allnick) + 512; - buf = malloc (len); + buf = g_malloc (len); auto_insert (buf, len, cmd, 0, 0, allnick, sess->channel, "", server_get_network (sess->server, TRUE), host, @@ -145,7 +145,7 @@ nick_command_parse (session *sess, char *cmd, char *nick, char *allnick) nick_command (sess, buf); - free (buf); + g_free (buf); } /* userlist button has been clicked */ @@ -166,11 +166,12 @@ userlist_button_cb (GtkWidget * button, char *cmd) if (sess->type == SESS_DIALOG) { /* fake a selection */ - nicks = malloc (sizeof (char *) * 2); + nicks = g_new (char *, 2); nicks[0] = g_strdup (sess->channel); nicks[1] = NULL; num_sel = 1; - } else + } + else { /* find number of selected rows */ nicks = userlist_selection_list (sess->gui->user_tree, &num_sel); @@ -178,14 +179,13 @@ userlist_button_cb (GtkWidget * button, char *cmd) { nick_command_parse (sess, cmd, "", ""); - if (nicks) - free (nicks); + g_free (nicks); return; } } /* create "allnicks" string */ - allnicks = malloc (((NICKLEN + 1) * num_sel) + 1); + allnicks = g_malloc (((NICKLEN + 1) * num_sel) + 1); *allnicks = 0; i = 0; @@ -218,8 +218,8 @@ userlist_button_cb (GtkWidget * button, char *cmd) g_free (nicks[num_sel]); } - free (nicks); - free (allnicks); + g_free (nicks); + g_free (allnicks); } /* a popup-menu-item has been selected */ @@ -393,9 +393,9 @@ toggle_cb (GtkWidget *item, char *pref_name) char buf[256]; if (GTK_CHECK_MENU_ITEM (item)->active) - snprintf (buf, sizeof (buf), "set %s 1", pref_name); + g_snprintf (buf, sizeof (buf), "set %s 1", pref_name); else - snprintf (buf, sizeof (buf), "set %s 0", pref_name); + g_snprintf (buf, sizeof (buf), "set %s 0", pref_name); handle_command (current_sess, buf, FALSE); } @@ -403,12 +403,11 @@ toggle_cb (GtkWidget *item, char *pref_name) static int is_in_path (char *cmd) { - char *prog = g_strdup (cmd + 1); /* 1st char is "!" */ - char *path, *orig; + char *orig = g_strdup (cmd + 1); /* 1st char is "!" */ + char *prog = orig; char **argv; int argc; - orig = prog; /* save for free()ing */ /* special-case these default entries. */ /* 123456789012345678 */ if (strncmp (prog, "gnome-terminal -x ", 18) == 0) @@ -417,15 +416,14 @@ is_in_path (char *cmd) if (g_shell_parse_argv (prog, &argc, &argv, NULL)) { - path = g_find_program_in_path (argv[0]); + char *path = g_find_program_in_path (argv[0]); + g_strfreev (argv); if (path) { g_free (path); g_free (orig); - g_strfreev (argv); return 1; } - g_strfreev (argv); } g_free (orig); @@ -588,7 +586,7 @@ menu_nickinfo_cb (GtkWidget *menu, session *sess) return; /* issue a /WHOIS */ - snprintf (buf, sizeof (buf), "WHOIS %s %s", str_copy, str_copy); + g_snprintf (buf, sizeof (buf), "WHOIS %s %s", str_copy, str_copy); handle_command (sess, buf, FALSE); /* and hide the output */ sess->server->skip_next_whois = 1; @@ -614,30 +612,30 @@ menu_create_nickinfo_menu (struct User *user, GtkWidget *submenu) /* let the translators tweak this if need be */ fmt = _("<tt><b>%-11s</b></tt> %s"); - snprintf (unknown, sizeof (unknown), "<i>%s</i>", _("Unknown")); + g_snprintf (unknown, sizeof (unknown), "<i>%s</i>", _("Unknown")); if (user->realname) { real = strip_color (user->realname, -1, STRIP_ALL|STRIP_ESCMARKUP); - snprintf (buf, sizeof (buf), fmt, _("Real Name:"), real); + g_snprintf (buf, sizeof (buf), fmt, _("Real Name:"), real); g_free (real); } else { - snprintf (buf, sizeof (buf), fmt, _("Real Name:"), unknown); + g_snprintf (buf, sizeof (buf), fmt, _("Real Name:"), unknown); } item = menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (copy_to_clipboard_cb), user->realname ? user->realname : unknown); - snprintf (buf, sizeof (buf), fmt, _("User:"), + g_snprintf (buf, sizeof (buf), fmt, _("User:"), user->hostname ? user->hostname : unknown); item = menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (copy_to_clipboard_cb), user->hostname ? user->hostname : unknown); - snprintf (buf, sizeof (buf), fmt, _("Account:"), + g_snprintf (buf, sizeof (buf), fmt, _("Account:"), user->account ? user->account : unknown); item = menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0); g_signal_connect (G_OBJECT (item), "activate", @@ -647,13 +645,13 @@ menu_create_nickinfo_menu (struct User *user, GtkWidget *submenu) users_country = country (user->hostname); if (users_country) { - snprintf (buf, sizeof (buf), fmt, _ ("Country:"), users_country); + g_snprintf (buf, sizeof (buf), fmt, _ ("Country:"), users_country); item = menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0); g_signal_connect (G_OBJECT (item), "activate", G_CALLBACK (copy_to_clipboard_cb), users_country); } - snprintf (buf, sizeof (buf), fmt, _("Server:"), + g_snprintf (buf, sizeof (buf), fmt, _("Server:"), user->servername ? user->servername : unknown); item = menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0); g_signal_connect (G_OBJECT (item), "activate", @@ -664,12 +662,12 @@ menu_create_nickinfo_menu (struct User *user, GtkWidget *submenu) { char min[96]; - snprintf (min, sizeof (min), _("%u minutes ago"), + g_snprintf (min, sizeof (min), _("%u minutes ago"), (unsigned int) ((time (0) - user->lasttalk) / 60)); - snprintf (buf, sizeof (buf), fmt, _("Last Msg:"), min); + g_snprintf (buf, sizeof (buf), fmt, _("Last Msg:"), min); } else { - snprintf (buf, sizeof (buf), fmt, _("Last Msg:"), unknown); + g_snprintf (buf, sizeof (buf), fmt, _("Last Msg:"), unknown); } menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0); @@ -679,7 +677,7 @@ menu_create_nickinfo_menu (struct User *user, GtkWidget *submenu) if (away) { char *msg = strip_color (away->message ? away->message : unknown, -1, STRIP_ALL|STRIP_ESCMARKUP); - snprintf (buf, sizeof (buf), fmt, _("Away Msg:"), msg); + g_snprintf (buf, sizeof (buf), fmt, _("Away Msg:"), msg); g_free (msg); item = menu_quick_item (0, buf, submenu, XCMENU_MARKUP, 0, 0); g_signal_connect (G_OBJECT (item), "activate", @@ -728,16 +726,15 @@ menu_nickmenu (session *sess, GdkEventButton *event, char *nick, int num_sel) struct User *user; GtkWidget *submenu, *menu = gtk_menu_new (); - if (str_copy) - free (str_copy); - str_copy = strdup (nick); + g_free (str_copy); + str_copy = g_strdup (nick); submenu_list = 0; /* first time through, might not be 0 */ /* more than 1 nick selected? */ if (num_sel > 1) { - snprintf (buf, sizeof (buf), _("%d nicks selected."), num_sel); + g_snprintf (buf, sizeof (buf), _("%d nicks selected."), num_sel); menu_quick_item (0, buf, menu, 0, 0, 0); menu_quick_item (0, 0, menu, XCMENU_SHADED, 0, 0); } else @@ -938,7 +935,7 @@ open_url_cb (GtkWidget *item, char *url) char buf[512]; /* pass this to /URL so it can handle irc:// */ - snprintf (buf, sizeof (buf), "URL %s", url); + g_snprintf (buf, sizeof (buf), "URL %s", url); handle_command (current_sess, buf, FALSE); } @@ -948,20 +945,19 @@ menu_urlmenu (GdkEventButton *event, char *url) GtkWidget *menu; char *tmp, *chop; - if (str_copy) - free (str_copy); - str_copy = strdup (url); + g_free (str_copy); + str_copy = g_strdup (url); menu = gtk_menu_new (); /* more than 51 chars? Chop it */ if (g_utf8_strlen (str_copy, -1) >= 52) { - tmp = strdup (str_copy); + tmp = g_strdup (str_copy); chop = g_utf8_offset_to_pointer (tmp, 48); chop[0] = chop[1] = chop[2] = '.'; chop[3] = 0; menu_quick_item (0, tmp, menu, XCMENU_SHADED, 0, 0); - free (tmp); + g_free (tmp); } else { menu_quick_item (0, str_copy, menu, XCMENU_SHADED, 0, 0); @@ -988,7 +984,7 @@ menu_chan_cycle (GtkWidget * menu, char *chan) if (current_sess) { - snprintf (tbuf, sizeof tbuf, "CYCLE %s", chan); + g_snprintf (tbuf, sizeof tbuf, "CYCLE %s", chan); handle_command (current_sess, tbuf, FALSE); } } @@ -1000,7 +996,7 @@ menu_chan_part (GtkWidget * menu, char *chan) if (current_sess) { - snprintf (tbuf, sizeof tbuf, "part %s", chan); + g_snprintf (tbuf, sizeof tbuf, "part %s", chan); handle_command (current_sess, tbuf, FALSE); } } @@ -1012,7 +1008,7 @@ menu_chan_join (GtkWidget * menu, char *chan) if (current_sess) { - snprintf (tbuf, sizeof tbuf, "join %s", chan); + g_snprintf (tbuf, sizeof tbuf, "join %s", chan); handle_command (current_sess, tbuf, FALSE); } } @@ -1026,9 +1022,8 @@ menu_chanmenu (struct session *sess, GdkEventButton * event, char *chan) if (find_channel (sess->server, chan)) is_joined = TRUE; - if (str_copy) - free (str_copy); - str_copy = strdup (chan); + g_free (str_copy); + str_copy = g_strdup (chan); menu = gtk_menu_new (); @@ -1074,9 +1069,8 @@ menu_addfavoritemenu (server *serv, GtkWidget *menu, char *channel, gboolean ist if (channel != str_copy) { - if (str_copy) - free (str_copy); - str_copy = strdup (channel); + g_free (str_copy); + str_copy = g_strdup (channel); } if (istree) @@ -1717,7 +1711,7 @@ menu_about (GtkWidget *wid, gpointer sess) "You should have received a copy of the GNU General Public License\n" \ "along with this program. If not, see <http://www.gnu.org/licenses/>"; - g_snprintf (comment, sizeof(comment), "Compiled: "__DATE__"\n" + g_snprintf (comment, sizeof(comment), "" #ifdef WIN32 "Portable Mode: %s\n" "Build Type: x%d\n" diff --git a/src/fe-gtk/notifications/notification-backend.h b/src/fe-gtk/notifications/notification-backend.h new file mode 100644 index 00000000..b60ced4e --- /dev/null +++ b/src/fe-gtk/notifications/notification-backend.h @@ -0,0 +1,27 @@ +/* HexChat + * Copyright (C) 2015 Patrick Griffis. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef HEXCHAT_PLUGIN_NOTIFICATION_BACKEND_H +#define HEXCHAT_PLUGIN_NOTIFICATION_BACKEND_H + +int notification_backend_supported (void); +void notification_backend_show (const char *title, const char *text); +int notification_backend_init (void); +void notification_backend_deinit (void); + +#endif diff --git a/src/fe-gtk/notifications/notification-dummy.c b/src/fe-gtk/notifications/notification-dummy.c new file mode 100644 index 00000000..022443bf --- /dev/null +++ b/src/fe-gtk/notifications/notification-dummy.c @@ -0,0 +1,39 @@ +/* HexChat + * Copyright (C) 2015 Patrick Griffis. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +void +notification_backend_show (const char *title, const char *text) +{ +} + +int +notification_backend_init (void) +{ + return 0; +} + +void +notification_backend_deinit (void) +{ +} + +int +notification_backend_supported (void) +{ + return 0; +} diff --git a/src/fe-gtk/notifications/notification-libnotify.c b/src/fe-gtk/notifications/notification-libnotify.c new file mode 100644 index 00000000..94f9679d --- /dev/null +++ b/src/fe-gtk/notifications/notification-libnotify.c @@ -0,0 +1,72 @@ +/* HexChat + * Copyright (C) 2015 Patrick Griffis. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include <glib.h> +#include <libnotify/notify.h> + +static gboolean strip_markup = FALSE; + +void +notification_backend_show (const char *title, const char *text) +{ + NotifyNotification *notification; + + if (strip_markup) + text = g_markup_escape_text (text, -1); + + notification = notify_notification_new (title, text, "hexchat"); + notify_notification_set_hint (notification, "desktop-entry", g_variant_new_string ("hexchat")); + + notify_notification_show (notification, NULL); + + g_object_unref (notification); + if (strip_markup) + g_free ((char*)text); +} + +int +notification_backend_init (void) +{ + GList* server_caps; + + if (!NOTIFY_CHECK_VERSION (0, 7, 0)) + return 0; + + if (!notify_init (PACKAGE_NAME)) + return 0; + + server_caps = notify_get_server_caps (); + if (g_list_find_custom (server_caps, "body-markup", (GCompareFunc)g_strcmp0)) + strip_markup = TRUE; + g_list_free_full (server_caps, g_free); + + return 1; +} + +void +notification_backend_deinit (void) +{ + notify_uninit (); +} + +int +notification_backend_supported (void) +{ + return notify_is_initted (); +} diff --git a/src/fe-gtk/notifications/notification-osx.m b/src/fe-gtk/notifications/notification-osx.m new file mode 100644 index 00000000..c9ad72d0 --- /dev/null +++ b/src/fe-gtk/notifications/notification-osx.m @@ -0,0 +1,54 @@ +/* HexChat + * Copyright (C) 2015 Patrick Griffis. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#import <Cocoa/Cocoa.h> +#include <gtkosxapplication.h> + +void +notification_backend_show (const char *title, const char *text) +{ + NSString *str_title = [[NSString alloc] initWithUTF8String:title]; + NSString *str_text = [[NSString alloc] initWithUTF8String:text]; + + NSUserNotification *userNotification = [NSUserNotification new]; + userNotification.title = str_title; + userNotification.informativeText = str_text; + + NSUserNotificationCenter *center = [NSUserNotificationCenter defaultUserNotificationCenter]; + [center scheduleNotification:userNotification]; + + [str_title release]; + [str_text release]; +} + +int +notification_backend_init (void) +{ + return 1; +} + +void +notification_backend_deinit (void) +{ +} + +int +notification_backend_supported (void) +{ + return gtkosx_application_get_bundle_id () != NULL; +} diff --git a/src/fe-gtk/notifications/notification-windows.c b/src/fe-gtk/notifications/notification-windows.c new file mode 100644 index 00000000..3fade306 --- /dev/null +++ b/src/fe-gtk/notifications/notification-windows.c @@ -0,0 +1,87 @@ +/* HexChat + * Copyright (C) 2015 Arnav Singh. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <gmodule.h> + +#include "hexchat.h" +#include "plugin.h" + +#include <Windows.h> + +void (*winrt_notification_backend_show) (const char *title, const char *text) = NULL; +int (*winrt_notification_backend_init) (void) = NULL; +void (*winrt_notification_backend_deinit) (void) = NULL; +int (*winrt_notification_backend_supported) (void) = NULL; + +void +notification_backend_show (const char *title, const char *text) +{ + if (winrt_notification_backend_show == NULL) + { + return; + } + + winrt_notification_backend_show (title, text); +} + +int +notification_backend_init (void) +{ + UINT original_error_mode; + GModule *module; + + /* Temporarily suppress the "DLL could not be loaded" dialog box before trying to load hcnotifications-winrt.dll */ + original_error_mode = GetErrorMode (); + SetErrorMode(SEM_FAILCRITICALERRORS); + module = module_load (HEXCHATLIBDIR "\\hcnotifications-winrt.dll"); + SetErrorMode (original_error_mode); + + if (module == NULL) + { + return 0; + } + + g_module_symbol (module, "notification_backend_show", (gpointer *) &winrt_notification_backend_show); + g_module_symbol (module, "notification_backend_init", (gpointer *) &winrt_notification_backend_init); + g_module_symbol (module, "notification_backend_deinit", (gpointer *) &winrt_notification_backend_deinit); + g_module_symbol (module, "notification_backend_supported", (gpointer *) &winrt_notification_backend_supported); + + return winrt_notification_backend_init (); +} + +void +notification_backend_deinit (void) +{ + if (winrt_notification_backend_deinit == NULL) + { + return; + } + + winrt_notification_backend_deinit (); +} + +int +notification_backend_supported (void) +{ + if (winrt_notification_backend_supported == NULL) + { + return 0; + } + + return winrt_notification_backend_supported (); +} diff --git a/src/fe-gtk/notifications/notification-winrt.cpp b/src/fe-gtk/notifications/notification-winrt.cpp new file mode 100644 index 00000000..663f9c08 --- /dev/null +++ b/src/fe-gtk/notifications/notification-winrt.cpp @@ -0,0 +1,100 @@ +/* HexChat + * Copyright (c) 2014 Leetsoftwerx + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <string> +#include <codecvt> + +#include <roapi.h> +#include <windows.ui.notifications.h> + +using namespace Windows::UI::Notifications; +using namespace Windows::Data::Xml::Dom; + +static ToastNotifier ^ notifier = nullptr; + +static std::wstring +widen(const std::string & to_widen) +{ + std::wstring_convert<std::codecvt_utf8_utf16<wchar_t> > converter; + return converter.from_bytes(to_widen); +} + +extern "C" +{ + __declspec (dllexport) void + notification_backend_show (const char *title, const char *text) + { + try + { + auto toastTemplate = ToastNotificationManager::GetTemplateContent (ToastTemplateType::ToastText02); + auto node_list = toastTemplate->GetElementsByTagName ("text"); + UINT node_count = node_list->Length; + + auto wtitle = widen (title); + node_list->GetAt (0)->AppendChild ( + toastTemplate->CreateTextNode (Platform::StringReference (wtitle.c_str (), wtitle.size ()))); + + auto wtext = widen (text); + node_list->GetAt (1)->AppendChild ( + toastTemplate->CreateTextNode (Platform::StringReference (wtext.c_str (), wtext.size ()))); + + // Mute sound, we already play our own + auto node = toastTemplate->SelectSingleNode ("/toast"); + auto audio_elem = toastTemplate->CreateElement ("audio"); + audio_elem->SetAttribute ("silent", "true"); + static_cast<XmlElement^>(node)->AppendChild (audio_elem); + + notifier->Show (ref new ToastNotification (toastTemplate)); + } + catch (Platform::Exception ^ ex) + { + } + catch (...) + { + } + } + + __declspec (dllexport) int + notification_backend_init (void) + { + if (!notifier) + notifier = ToastNotificationManager::CreateToastNotifier ("HexChat.Desktop.Notify"); + + if (FAILED (Windows::Foundation::Initialize (RO_INIT_SINGLETHREADED))) + return 0; + + return 1; + } + + __declspec (dllexport) void + notification_backend_deinit (void) + { + notifier = nullptr; + Windows::Foundation::Uninitialize (); + } + + __declspec (dllexport) int + notification_backend_supported (void) + { + return 1; + } +} diff --git a/src/fe-gtk/notifications/notifications-winrt.vcxproj b/src/fe-gtk/notifications/notifications-winrt.vcxproj new file mode 100644 index 00000000..dcd2a2b7 --- /dev/null +++ b/src/fe-gtk/notifications/notifications-winrt.vcxproj @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <ItemGroup> + <ClCompile Include="notification-winrt.cpp"> + <CompileAsWinRT>true</CompileAsWinRT> + </ClCompile> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{C53145CC-D021-40C9-B97C-0249AB9A43C9}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>notifications-winrt</RootNamespace> + <ProjectName>notifications-winrt</ProjectName> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\..\win32\hexchat.props" /> + <PropertyGroup> + <TargetName>hcnotifications-winrt</TargetName> + <OutDir>$(HexChatRel)plugins\</OutDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PreprocessorDefinitions>WIN32;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY;_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES_MEMORY;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT;NDEBUG;_WINDOWS;_USRDLL;NOTIFICATIONS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + <AdditionalUsingDirectories>$(VCInstallDir)vcpackages;$(FrameworkSdkDir)References\CommonConfiguration\Neutral;%(AdditionalUsingDirectories)</AdditionalUsingDirectories> + </ClCompile> + <Link> + <AdditionalDependencies>$(DepLibs);mincore.lib;runtimeobject.lib;%(AdditionalDependencies)</AdditionalDependencies> + <MinimumRequiredVersion>6.03</MinimumRequiredVersion> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PreprocessorDefinitions>WIN32;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_MEMORY;_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES_MEMORY;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT;NDEBUG;_WINDOWS;_USRDLL;NOTIFICATIONS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + <AdditionalUsingDirectories>$(VCInstallDir)vcpackages;$(FrameworkSdkDir)References\CommonConfiguration\Neutral;%(AdditionalUsingDirectories)</AdditionalUsingDirectories> + </ClCompile> + <Link> + <AdditionalDependencies>$(DepLibs);mincore.lib;runtimeobject.lib;%(AdditionalDependencies)</AdditionalDependencies> + <MinimumRequiredVersion>6.03</MinimumRequiredVersion> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + </Link> + </ItemDefinitionGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project> diff --git a/src/fe-gtk/notifications/notifications-winrt.vcxproj.filters b/src/fe-gtk/notifications/notifications-winrt.vcxproj.filters new file mode 100644 index 00000000..06f4e558 --- /dev/null +++ b/src/fe-gtk/notifications/notifications-winrt.vcxproj.filters @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="notification-winrt.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project> \ No newline at end of file diff --git a/src/fe-gtk/notifygui.c b/src/fe-gtk/notifygui.c index 5aa60d0a..ed16f44f 100644 --- a/src/fe-gtk/notifygui.c +++ b/src/fe-gtk/notifygui.c @@ -190,11 +190,11 @@ notify_gui_update (void) { lastseenminutes = (int)(time (0) - lastseen) / 60; if (lastseenminutes < 60) - snprintf (agobuf, sizeof (agobuf), _("%d minutes ago"), lastseenminutes); + g_snprintf (agobuf, sizeof (agobuf), _("%d minutes ago"), lastseenminutes); else if (lastseenminutes < 120) - snprintf (agobuf, sizeof (agobuf), _("An hour ago")); + g_snprintf (agobuf, sizeof (agobuf), _("An hour ago")); else - snprintf (agobuf, sizeof (agobuf), _("%d hours ago"), lastseenminutes / 60); + g_snprintf (agobuf, sizeof (agobuf), _("%d hours ago"), lastseenminutes / 60); seen = agobuf; } if (!valid) /* create new tree row if required */ @@ -219,7 +219,7 @@ notify_gui_update (void) name = ""; server = server_get_network (servnot->server, TRUE); - snprintf (agobuf, sizeof (agobuf), _("%d minutes ago"), (int)(time (0) - lastseen) / 60); + g_snprintf (agobuf, sizeof (agobuf), _("%d minutes ago"), (int)(time (0) - lastseen) / 60); seen = agobuf; if (!valid) /* create new tree row if required */ @@ -380,7 +380,7 @@ fe_notify_ask (char *nick, char *networks) gtk_table_attach_defaults (GTK_TABLE (table), wid, 1, 2, 2, 3); label = gtk_label_new (NULL); - snprintf (buf, sizeof (buf), "<i><span size=\"smaller\">%s</span></i>", _("Comma separated list of networks is accepted.")); + g_snprintf (buf, sizeof (buf), "<i><span size=\"smaller\">%s</span></i>", _("Comma separated list of networks is accepted.")); gtk_label_set_markup (GTK_LABEL (label), buf); gtk_table_attach_defaults (GTK_TABLE (table), label, 1, 2, 3, 4); diff --git a/src/fe-gtk/palette.c b/src/fe-gtk/palette.c index 435ba84b..17689756 100644 --- a/src/fe-gtk/palette.c +++ b/src/fe-gtk/palette.c @@ -106,45 +106,39 @@ palette_alloc (GtkWidget * widget) void palette_load (void) { - int i, j, l, fh; + int i, j, fh; char prefname[256]; struct stat st; char *cfg; - int red, green, blue; + guint16 red, green, blue; fh = hexchat_open_file ("colors.conf", O_RDONLY, 0, 0); if (fh != -1) { fstat (fh, &st); - cfg = malloc (st.st_size + 1); - if (cfg) + cfg = g_malloc0 (st.st_size + 1); + read (fh, cfg, st.st_size); + + /* mIRC colors 0-31 are here */ + for (i = 0; i < 32; i++) + { + g_snprintf (prefname, sizeof prefname, "color_%d", i); + cfg_get_color (cfg, prefname, &red, &green, &blue); + colors[i].red = red; + colors[i].green = green; + colors[i].blue = blue; + } + + /* our special colors are mapped at 256+ */ + for (i = 256, j = 32; j < MAX_COL+1; i++, j++) { - cfg[0] = '\0'; - l = read (fh, cfg, st.st_size); - if (l >= 0) - cfg[l] = '\0'; - - /* mIRC colors 0-31 are here */ - for (i = 0; i < 32; i++) - { - snprintf (prefname, sizeof prefname, "color_%d", i); - cfg_get_color (cfg, prefname, &red, &green, &blue); - colors[i].red = red; - colors[i].green = green; - colors[i].blue = blue; - } - - /* our special colors are mapped at 256+ */ - for (i = 256, j = 32; j < MAX_COL+1; i++, j++) - { - snprintf (prefname, sizeof prefname, "color_%d", i); - cfg_get_color (cfg, prefname, &red, &green, &blue); - colors[j].red = red; - colors[j].green = green; - colors[j].blue = blue; - } - free (cfg); + g_snprintf (prefname, sizeof prefname, "color_%d", i); + cfg_get_color (cfg, prefname, &red, &green, &blue); + colors[j].red = red; + colors[j].green = green; + colors[j].blue = blue; } + g_free (cfg); close (fh); } } @@ -161,14 +155,14 @@ palette_save (void) /* mIRC colors 0-31 are here */ for (i = 0; i < 32; i++) { - snprintf (prefname, sizeof prefname, "color_%d", i); + g_snprintf (prefname, sizeof prefname, "color_%d", i); cfg_put_color (fh, colors[i].red, colors[i].green, colors[i].blue, prefname); } /* our special colors are mapped at 256+ */ for (i = 256, j = 32; j < MAX_COL+1; i++, j++) { - snprintf (prefname, sizeof prefname, "color_%d", i); + g_snprintf (prefname, sizeof prefname, "color_%d", i); cfg_put_color (fh, colors[j].red, colors[j].green, colors[j].blue, prefname); } diff --git a/src/fe-gtk/pixmaps.c b/src/fe-gtk/pixmaps.c index cbec6f71..053afaaf 100644 --- a/src/fe-gtk/pixmaps.c +++ b/src/fe-gtk/pixmaps.c @@ -87,10 +87,9 @@ pixmap_load_from_file (char *filename) static GdkPixbuf * load_pixmap (const char *filename) { - gchar *path; GdkPixbuf *pixbuf; - path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "icons" G_DIR_SEPARATOR_S "%s.png", get_xdir (), filename); + gchar *path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "icons" G_DIR_SEPARATOR_S "%s.png", get_xdir (), filename); pixbuf = gdk_pixbuf_new_from_file (path, 0); g_free (path); diff --git a/src/fe-gtk/plugin-notification.c b/src/fe-gtk/plugin-notification.c new file mode 100644 index 00000000..04a64213 --- /dev/null +++ b/src/fe-gtk/plugin-notification.c @@ -0,0 +1,215 @@ +/* HexChat + * Copyright (C) 2015 Patrick Griffis. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" +#include <glib.h> + +#include "../common/hexchat-plugin.h" +#include "../common/inbound.h" /* For alert_match_word() */ +#include "notifications/notification-backend.h" + +static hexchat_plugin *ph; + +static gboolean +should_alert (void) +{ + int omit_away, omit_focused, omit_tray; + + if (hexchat_get_prefs (ph, "gui_focus_omitalerts", NULL, &omit_focused) == 3 && omit_focused) + { + const char *status = hexchat_get_info (ph, "win_status"); + + if (status && !g_strcmp0 (status, "active")) + return FALSE; + } + + if (hexchat_get_prefs (ph, "away_omit_alerts", NULL, &omit_away) == 3 && omit_away) + { + if (hexchat_get_info (ph, "away")) + return FALSE; + } + + if (hexchat_get_prefs (ph, "gui_tray_quiet", NULL, &omit_tray) == 3 && omit_tray) + { + int tray_enabled; + + if (hexchat_get_prefs (ph, "gui_tray", NULL, &tray_enabled) == 3 && tray_enabled) + { + const char *status = hexchat_get_info (ph, "win_status"); + + if (status && g_strcmp0 (status, "hidden") != 0) + return FALSE; + } + } + + return TRUE; +} + +static gboolean +is_ignored (char *nick) +{ + const char *no_hilight; + + if (hexchat_get_prefs (ph, "irc_no_hilight", &no_hilight, NULL) == 1 && no_hilight) + { + return alert_match_word (nick, (char*)no_hilight); + } + return FALSE; +} + +static void +show_notification (const char *title, const char *text) +{ + char *stripped_title, *stripped_text; + + /* Strip all colors */ + stripped_title = hexchat_strip (ph, title, -1, 7); + stripped_text = hexchat_strip (ph, text, -1, 7); + + notification_backend_show (stripped_title, stripped_text); + + hexchat_free (ph, stripped_title); + hexchat_free (ph, stripped_text); +} + +static void +show_notificationf (const char *text, const char *format, ...) +{ + va_list args; + char *buf; + + va_start (args, format); + buf = g_strdup_vprintf (format, args); + va_end (args); + + show_notification (buf, text); + g_free (buf); +} + +static int +incoming_hilight_cb (char *word[], gpointer userdata) +{ + int hilight; + + if (hexchat_get_prefs (ph, "input_balloon_hilight", NULL, &hilight) == 3 && hilight && should_alert()) + { + show_notificationf (word[2], _("Highlighted message from: %s (%s)"), word[1], hexchat_get_info (ph, "channel")); + } + return HEXCHAT_EAT_NONE; +} + +static int +incoming_message_cb (char *word[], gpointer userdata) +{ + int message; + + if (hexchat_get_prefs (ph, "input_balloon_chans", NULL, &message) == 3 && message && should_alert ()) + { + show_notificationf (word[2], _("Channel message from: %s (%s)"), word[1], hexchat_get_info (ph, "channel")); + } + return HEXCHAT_EAT_NONE; +} + +static int +incoming_priv_cb (char *word[], gpointer userdata) +{ + int priv; + + if (hexchat_get_prefs (ph, "input_balloon_priv", NULL, &priv) == 3 && priv && should_alert ()) + { + const char *network = hexchat_get_info (ph, "network"); + if (!network) + network = hexchat_get_info (ph, "server"); + + if (userdata != NULL) /* Special event */ + { + if (GPOINTER_TO_INT (userdata) == 3) + { + if (!is_ignored (word[2])) + show_notificationf (word[1], _("File offer from: %s (%s)"), word[2], network); + } + else if (GPOINTER_TO_INT (userdata) == 2) + { + if (!is_ignored (word[2])) + show_notificationf (word[1], _("Invited to channel by: %s (%s)"), word[2], network); + } + else + { + if (!is_ignored (word[1])) + show_notificationf (word[2], _("Notice from: %s (%s)"), word[1], network); + } + } + else + show_notificationf (word[2], _("Private message from: %s (%s)"), word[1], network); + } + return HEXCHAT_EAT_NONE; +} + +static int +tray_cmd_cb (char *word[], char *word_eol[], gpointer userdata) +{ + if (word[2] && !g_ascii_strcasecmp (word[2], "-b") && word[3] && word[4]) + { + if (should_alert ()) + show_notification (word[3], word_eol[4]); + return HEXCHAT_EAT_ALL; + } + + return HEXCHAT_EAT_NONE; +} + +int +notification_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg) +{ + if (!notification_backend_init ()) + return 0; + + ph = plugin_handle; + *plugin_name = ""; + *plugin_desc = ""; + *plugin_version = ""; + + hexchat_hook_print (ph, "Channel Msg Hilight", HEXCHAT_PRI_LOWEST, incoming_hilight_cb, NULL); + hexchat_hook_print (ph, "Channel Action Hilight", HEXCHAT_PRI_LOWEST, incoming_hilight_cb, NULL); + + hexchat_hook_print (ph, "Channel Message", HEXCHAT_PRI_LOWEST, incoming_message_cb, NULL); + hexchat_hook_print (ph, "Channel Action", HEXCHAT_PRI_LOWEST, incoming_message_cb, NULL); + hexchat_hook_print (ph, "Channel Notice", HEXCHAT_PRI_LOWEST, incoming_message_cb, NULL); + + hexchat_hook_print (ph, "Private Message", HEXCHAT_PRI_LOWEST, incoming_priv_cb, NULL); + hexchat_hook_print (ph, "Private Message to Dialog", HEXCHAT_PRI_LOWEST, incoming_priv_cb, NULL); + hexchat_hook_print (ph, "Private Action", HEXCHAT_PRI_LOWEST, incoming_priv_cb, NULL); + hexchat_hook_print (ph, "Private Action to Dialog", HEXCHAT_PRI_LOWEST, incoming_priv_cb, NULL); + + /* Special events treated as priv */ + hexchat_hook_print (ph, "Notice", HEXCHAT_PRI_LOWEST, incoming_priv_cb, GINT_TO_POINTER (1)); + hexchat_hook_print (ph, "Invited", HEXCHAT_PRI_LOWEST, incoming_priv_cb, GINT_TO_POINTER (2)); + hexchat_hook_print (ph, "DCC Offer", HEXCHAT_PRI_LOWEST, incoming_priv_cb, GINT_TO_POINTER (3)); + + hexchat_hook_command (ph, "TRAY", HEXCHAT_PRI_HIGH, tray_cmd_cb, NULL, NULL); + + return 1; +} + + +int +notification_plugin_deinit (void) +{ + notification_backend_deinit (); + return 1; +} diff --git a/src/fe-gtk/plugin-notification.h b/src/fe-gtk/plugin-notification.h new file mode 100644 index 00000000..07ad1609 --- /dev/null +++ b/src/fe-gtk/plugin-notification.h @@ -0,0 +1,25 @@ +/* HexChat + * Copyright (C) 2015 Patrick Griffis. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef HEXCHAT_PLUGIN_NOTIFICATION_H +#define HEXCHAT_PLUGIN_NOTIFICATION_H + +int notification_plugin_init (void *, char **, char **, char **, char *); +int notification_plugin_deinit (void *); + +#endif diff --git a/src/fe-gtk/plugin-tray.c b/src/fe-gtk/plugin-tray.c index b3e34c0a..077a7c63 100644 --- a/src/fe-gtk/plugin-tray.c +++ b/src/fe-gtk/plugin-tray.c @@ -34,18 +34,6 @@ #include <unistd.h> #endif -#ifdef USE_LIBNOTIFY -#include <libnotify/notify.h> -#ifndef NOTIFY_CHECK_VERSION -#define NOTIFY_CHECK_VERSION(x,y,z) 0 -#endif -#if NOTIFY_CHECK_VERSION(0,7,0) -#define XC_NOTIFY_NEW(a,b,c,d) notify_notification_new(a,b,c) -#else -#define XC_NOTIFY_NEW(a,b,c,d) notify_notification_new(a,b,c,d) -#endif -#endif - typedef enum /* current icon status */ { TS_NONE, @@ -154,82 +142,6 @@ fe_tray_set_tooltip (const char *text) gtk_status_icon_set_tooltip_text (sticon, text); } -void -fe_tray_set_balloon (const char *title, const char *text) -{ -#ifndef WIN32 -#if 0 - const char *argv[8]; - const char *path; - char time[16]; -#endif - WinStatus ws; - - /* no balloons if the window is focused */ - ws = tray_get_window_status (); - if ((prefs.hex_away_omit_alerts && hexchat_get_info(ph, "away")) || - (prefs.hex_gui_focus_omitalerts && ws == WS_FOCUSED)) - return; - - /* bit 1 of flags means "no balloons unless hidden/iconified" */ - if (ws != WS_HIDDEN && prefs.hex_gui_tray_quiet) - return; - - /* FIXME: this should close the current balloon */ - if (!text) - return; - -#ifdef USE_LIBNOTIFY - static int notify_text_strip_flags = STRIP_ALL; - NotifyNotification *notification; - char *notify_text, *notify_title; - - if (!notify_is_initted()) - { - notify_init(PACKAGE_NAME); - - GList* server_caps = notify_get_server_caps (); - if (g_list_find_custom (server_caps, "body-markup", (GCompareFunc)strcmp)) - { - notify_text_strip_flags |= STRIP_ESCMARKUP; - } - g_list_free_full (server_caps, g_free); - } - - notify_text = strip_color (text, -1, notify_text_strip_flags); - notify_title = strip_color (title, -1, STRIP_ALL); - - notification = XC_NOTIFY_NEW (notify_title, notify_text, HEXCHATSHAREDIR "/icons/hicolor/scalable/apps/hexchat.svg", NULL); - -#if NOTIFY_CHECK_VERSION(0,7,0) - notify_notification_set_hint (notification, "desktop-entry", g_variant_new_string ("hexchat")); -#endif - - g_free ((char *)notify_title); - g_free ((char *)notify_text); - - notify_notification_set_timeout (notification, prefs.hex_input_balloon_time*1000); - notify_notification_show (notification, NULL); - - g_object_unref (notification); -#endif -#endif -} - -static void -tray_set_balloonf (const char *text, const char *format, ...) -{ - va_list args; - char *buf; - - va_start (args, format); - buf = g_strdup_vprintf (format, args); - va_end (args); - - fe_tray_set_balloon (buf, text); - g_free (buf); -} - static void tray_set_tipf (const char *format, ...) { @@ -575,26 +487,32 @@ tray_menu_destroy (GtkWidget *menu, gpointer userdata) } #ifdef WIN32 -static void +static gboolean tray_menu_enter_cb (GtkWidget *menu) { tray_menu_inactivetime = 0; + return FALSE; } -static void +static gboolean tray_menu_left_cb (GtkWidget *menu) { tray_menu_inactivetime = g_get_real_time (); + return FALSE; } -static void +static gboolean tray_check_hide (GtkWidget *menu) { if (tray_menu_inactivetime && g_get_real_time () - tray_menu_inactivetime >= 2000000) { tray_menu_destroy (menu, NULL); + return G_SOURCE_REMOVE; } + + return G_SOURCE_CONTINUE; } +#endif static void tray_menu_settings (GtkWidget * wid, gpointer none) @@ -602,7 +520,6 @@ tray_menu_settings (GtkWidget * wid, gpointer none) extern void setup_open (void); setup_open (); } -#endif static void tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata) @@ -651,10 +568,9 @@ tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata) gtk_widget_set_sensitive (item, FALSE); menu_add_plugin_items (menu, "\x5$TRAY", NULL); -#ifdef WIN32 + tray_make_item (menu, NULL, tray_menu_quit_cb, NULL); mg_create_icon_item (_("_Preferences"), GTK_STOCK_PREFERENCES, menu, tray_menu_settings, NULL); -#endif tray_make_item (menu, NULL, tray_menu_quit_cb, NULL); mg_create_icon_item (_("_Quit"), GTK_STOCK_QUIT, menu, tray_menu_quit_cb, NULL); @@ -669,7 +585,7 @@ tray_menu_cb (GtkWidget *widget, guint button, guint time, gpointer userdata) g_signal_connect (G_OBJECT (menu), "enter-notify-event", G_CALLBACK (tray_menu_enter_cb), NULL); - tray_menu_timer = g_timeout_add(500, (GSourceFunc) tray_check_hide, menu); + tray_menu_timer = g_timeout_add (500, tray_check_hide, menu); #endif gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, @@ -718,10 +634,6 @@ tray_hilight_cb (char *word[], void *userdata) tray_hilight_count, word[1], hexchat_get_info (ph, "channel")); } - if (prefs.hex_input_balloon_hilight) - tray_set_balloonf (word[2], _("Highlighted message from: %s (%s)"), - word[1], hexchat_get_info (ph, "channel")); - return HEXCHAT_EAT_NONE; } @@ -743,10 +655,6 @@ tray_message_cb (char *word[], void *userdata) tray_set_tipf (_(DISPLAY_NAME": %u channel messages."), tray_pub_count); } - if (prefs.hex_input_balloon_chans) - tray_set_balloonf (word[2], _("Channel message from: %s (%s)"), - word[1], hexchat_get_info (ph, "channel")); - return HEXCHAT_EAT_NONE; } @@ -774,10 +682,6 @@ tray_priv (char *from, char *text) tray_set_tipf (_(DISPLAY_NAME": %u private messages, latest from: %s (%s)"), tray_priv_count, from, network); } - - if (prefs.hex_input_balloon_priv) - tray_set_balloonf (text, _("Private message from: %s (%s)"), - from, network); } static int @@ -822,10 +726,6 @@ tray_dcc_cb (char *word[], void *userdata) tray_file_count, word[1], network); } - if (prefs.hex_input_balloon_priv && (!prefs.hex_away_omit_alerts || tray_find_away_status () != 1)) - tray_set_balloonf ("", _("File offer from: %s (%s)"), - word[1], network); - return HEXCHAT_EAT_NONE; } @@ -904,8 +804,6 @@ tray_plugin_deinit (hexchat_plugin *plugin_handle) { #ifdef WIN32 tray_cleanup (); -#elif defined(USE_LIBNOTIFY) - notify_uninit (); #endif return 1; } diff --git a/src/fe-gtk/plugingui.c b/src/fe-gtk/plugingui.c index 9b3186a6..83e05727 100644 --- a/src/fe-gtk/plugingui.c +++ b/src/fe-gtk/plugingui.c @@ -142,23 +142,21 @@ plugingui_load_cb (session *sess, char *file) { if (file) { - char *buf = malloc (strlen (file) + 9); + char *buf; if (strchr (file, ' ')) - sprintf (buf, "LOAD \"%s\"", file); + buf = g_strdup_printf ("LOAD \"%s\"", file); else - sprintf (buf, "LOAD %s", file); + buf = g_strdup_printf ("LOAD %s", file); handle_command (sess, buf, FALSE); - free (buf); + g_free (buf); } } void plugingui_load (void) { - char *sub_dir; - - sub_dir = g_build_filename (get_xdir(), "addons", NULL); + char *sub_dir = g_build_filename (get_xdir(), "addons", NULL); gtkutil_file_req (_("Select a Plugin or Script to load"), plugingui_load_cb, current_sess, sub_dir, "*."G_MODULE_SUFFIX";*.lua;*.pl;*.py;*.tcl;*.js", FRF_FILTERISINITIAL|FRF_EXTENSIONS); @@ -175,7 +173,7 @@ plugingui_loadbutton_cb (GtkWidget * wid, gpointer unused) static void plugingui_unload (GtkWidget * wid, gpointer unused) { - char *modname, *file, *buf; + char *modname, *file; GtkTreeView *view; GtkTreeIter iter; @@ -188,16 +186,17 @@ plugingui_unload (GtkWidget * wid, gpointer unused) { if (plugin_kill (modname, FALSE) == 2) fe_message (_("That plugin is refusing to unload.\n"), FE_MSG_ERROR); - } else + } + else { + char *buf; /* let python.so or perl.so handle it */ - buf = malloc (strlen (file) + 10); if (strchr (file, ' ')) - sprintf (buf, "UNLOAD \"%s\"", file); + buf = g_strdup_printf ("UNLOAD \"%s\"", file); else - sprintf (buf, "UNLOAD %s", file); + buf = g_strdup_printf ("UNLOAD %s", file); handle_command (current_sess, buf, FALSE); - free (buf); + g_free (buf); } g_free (modname); @@ -211,14 +210,14 @@ plugingui_reloadbutton_cb (GtkWidget *wid, GtkTreeView *view) if (file) { - char *buf = malloc (strlen (file) + 9); + char *buf; if (strchr (file, ' ')) - sprintf (buf, "RELOAD \"%s\"", file); + buf = g_strdup_printf ("RELOAD \"%s\"", file); else - sprintf (buf, "RELOAD %s", file); + buf = g_strdup_printf ("RELOAD %s", file); handle_command (current_sess, buf, FALSE); - free (buf); + g_free (buf); g_free (file); } } diff --git a/src/fe-gtk/rawlog.c b/src/fe-gtk/rawlog.c index f2527492..1d4bf9fd 100644 --- a/src/fe-gtk/rawlog.c +++ b/src/fe-gtk/rawlog.c @@ -109,7 +109,7 @@ open_rawlog (struct server *serv) return; } - snprintf (tbuf, sizeof tbuf, _(DISPLAY_NAME": Raw Log (%s)"), serv->servername); + g_snprintf (tbuf, sizeof tbuf, _(DISPLAY_NAME": Raw Log (%s)"), serv->servername); serv->gui->rawlog_window = mg_create_generic_tab ("RawLog", tbuf, FALSE, TRUE, close_rawlog, serv, 640, 320, &vbox, serv); @@ -146,7 +146,7 @@ fe_add_rawlog (server *serv, char *text, int len, int outbound) { char **split_text; char *new_text; - int i; + size_t i; if (!serv->gui->rawlog_window) return; @@ -163,7 +163,7 @@ fe_add_rawlog (server *serv, char *text, int len, int outbound) else new_text = g_strconcat ("\0033>>\017 ", split_text[i], NULL); - gtk_xtext_append (GTK_XTEXT (serv->gui->rawlog_textlist)->buffer, new_text, strlen (new_text)); + gtk_xtext_append (GTK_XTEXT (serv->gui->rawlog_textlist)->buffer, new_text, strlen (new_text), 0); g_free (new_text); } diff --git a/src/fe-gtk/servlistgui.c b/src/fe-gtk/servlistgui.c index f43a225a..f7909f72 100644 --- a/src/fe-gtk/servlistgui.c +++ b/src/fe-gtk/servlistgui.c @@ -90,7 +90,7 @@ static GtkWidget *servlist_open_edit (GtkWidget *parent, ircnet *net); static const char *pages[]= { IRC_DEFAULT_CHARSET, - "IRC (Latin/Unicode Hybrid)", + "CP1252 (Windows-1252)", "ISO-8859-15 (Western Europe)", "ISO-8859-2 (Central Europe)", "ISO-8859-7 (Greek)", @@ -497,7 +497,7 @@ servlist_addnet_cb (GtkWidget *item, GtkTreeView *treeview) ircnet *net; net = servlist_net_add (_("New Network"), "", TRUE); - net->encoding = strdup (IRC_DEFAULT_CHARSET); + net->encoding = g_strdup (IRC_DEFAULT_CHARSET); servlist_server_add (net, "newserver/6667"); store = (GtkListStore *)gtk_tree_view_get_model (treeview); @@ -668,13 +668,12 @@ servlist_favor (GtkWidget *button, gpointer none) static void servlist_update_from_entry (char **str, GtkWidget *entry) { - if (*str) - free (*str); + g_free (*str); if (gtk_entry_get_text (GTK_ENTRY (entry))[0] == 0) *str = NULL; else - *str = strdup (gtk_entry_get_text (GTK_ENTRY (entry))); + *str = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))); } static void @@ -960,10 +959,10 @@ servlist_savegui (void) if (!rfc_casecmp (nick1, nick2)) return 2; - strcpy (prefs.hex_irc_nick1, nick1); - strcpy (prefs.hex_irc_nick2, nick2); - strcpy (prefs.hex_irc_nick3, gtk_entry_get_text (GTK_ENTRY (entry_nick3))); - strcpy (prefs.hex_irc_user_name, gtk_entry_get_text (GTK_ENTRY (entry_guser))); + safe_strcpy (prefs.hex_irc_nick1, nick1, sizeof(prefs.hex_irc_nick1)); + safe_strcpy (prefs.hex_irc_nick2, nick2, sizeof(prefs.hex_irc_nick2)); + safe_strcpy (prefs.hex_irc_nick3, gtk_entry_get_text (GTK_ENTRY (entry_nick3)), sizeof(prefs.hex_irc_nick3)); + safe_strcpy (prefs.hex_irc_user_name, gtk_entry_get_text (GTK_ENTRY (entry_guser)), sizeof(prefs.hex_irc_user_name)); sp = strchr (prefs.hex_irc_user_name, ' '); if (sp) sp[0] = 0; /* spaces will break the login */ @@ -1203,9 +1202,9 @@ servlist_celledit_cb (GtkCellRendererText *cell, gchar *arg1, gchar *arg2, } netname = net->name; - net->name = strdup (arg2); + net->name = g_strdup (arg2); gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, net->name, -1); - free (netname); + g_free (netname); } gtk_tree_path_free (path); @@ -1311,7 +1310,7 @@ servlist_sanitize_hostname (char *host) { char *ret, *c, *e; - ret = strdup (host); + ret = g_strdup (host); c = strchr (ret, ':'); e = strrchr (ret, ':'); @@ -1371,7 +1370,7 @@ servlist_editserver_cb (GtkCellRendererText *cell, gchar *name, gchar *newval, g servname = serv->hostname; serv->hostname = servlist_sanitize_hostname (newval); gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, serv->hostname, -1); - free (servname); + g_free (servname); } } @@ -1409,7 +1408,7 @@ servlist_editcommand_cb (GtkCellRendererText *cell, gchar *name, gchar *newval, cmd = entry->command; entry->command = servlist_sanitize_command (newval); gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, entry->command, -1); - free (cmd); + g_free (cmd); } } @@ -1508,9 +1507,8 @@ servlist_combo_cb (GtkEntry *entry, gpointer userdata) if (!selected_net) return; - if (selected_net->encoding) - free (selected_net->encoding); - selected_net->encoding = strdup (gtk_entry_get_text (entry)); + g_free (selected_net->encoding); + selected_net->encoding = g_strdup (gtk_entry_get_text (entry)); } /* Fills up the network's authentication type so that it's guaranteed to be either NULL or a valid value. */ @@ -1594,7 +1592,6 @@ servlist_create_charsetcombo (void) int i; cb = gtk_combo_box_text_new_with_entry (); - gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (cb), "System default"); i = 0; while (pages[i]) { @@ -1602,7 +1599,7 @@ servlist_create_charsetcombo (void) i++; } - gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN(cb))), selected_net->encoding ? selected_net->encoding : "System default"); + gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN(cb))), selected_net->encoding ? selected_net->encoding : pages[0]); g_signal_connect (G_OBJECT (gtk_bin_get_child (GTK_BIN (cb))), "changed", G_CALLBACK (servlist_combo_cb), NULL); @@ -1660,7 +1657,7 @@ bold_label (char *text) char buf[128]; GtkWidget *label; - snprintf (buf, sizeof (buf), "<b>%s</b>", text); + g_snprintf (buf, sizeof (buf), "<b>%s</b>", text); label = gtk_label_new (buf); gtk_label_set_use_markup (GTK_LABEL (label), TRUE); gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); @@ -1702,7 +1699,7 @@ servlist_open_edit (GtkWidget *parent, ircnet *net) editwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_container_set_border_width (GTK_CONTAINER (editwindow), 4); - snprintf (buf, sizeof (buf), _(DISPLAY_NAME": Edit %s"), net->name); + g_snprintf (buf, sizeof (buf), _(DISPLAY_NAME": Edit %s"), net->name); gtk_window_set_title (GTK_WINDOW (editwindow), buf); gtk_window_set_default_size (GTK_WINDOW (editwindow), netedit_win_width, netedit_win_height); gtk_window_set_transient_for (GTK_WINDOW (editwindow), GTK_WINDOW (parent)); diff --git a/src/fe-gtk/setup.c b/src/fe-gtk/setup.c index e4372dc9..dc469591 100644 --- a/src/fe-gtk/setup.c +++ b/src/fe-gtk/setup.c @@ -36,6 +36,7 @@ #include "pixmaps.h" #include "menu.h" #include "plugin-tray.h" +#include "notifications/notification-backend.h" #ifdef WIN32 #include "../common/fe.h" @@ -314,6 +315,7 @@ static const setting tabs_settings[] = {ST_TOGGLE, N_("Show icons in the channel tree"), P_OFFINTNL(hex_gui_tab_icons), 0, 0, 0}, {ST_TOGGLE, N_("Show dotted lines in the channel tree"), P_OFFINTNL(hex_gui_tab_dots), 0, 0, 0}, {ST_TOGGLE, N_("Scroll mouse-wheel to change tabs"), P_OFFINTNL (hex_gui_tab_scrollchans), 0, 0, 0}, + {ST_TOGGLE, N_("Middle click to close tab"), P_OFFINTNL(hex_gui_tab_middleclose), 0, 0, 0}, {ST_TOGGLE, N_("Smaller text"), P_OFFINTNL(hex_gui_tab_small), 0, 0, 0}, {ST_MENU, N_("Focus new tabs:"), P_OFFINTNL(hex_gui_tab_newtofront), 0, focusnewtabsmenu, 0}, {ST_MENU, N_("Placement of notices:"), P_OFFINTNL(hex_irc_notice_pos), 0, noticeposmenu, 0}, @@ -396,9 +398,47 @@ static const setting alert_settings[] = {ST_HEADER, N_("Alerts"),0,0,0}, {ST_ALERTHEAD}, -#if !defined (WIN32) && !defined (__APPLE__) - {ST_3OGGLE, N_("Show tray balloons on:"), 0, 0, (void *)balloonlist, 0}, + + + {ST_3OGGLE, N_("Show notifications on:"), 0, 0, (void *)balloonlist, 0}, + {ST_3OGGLE, N_("Blink tray icon on:"), 0, 0, (void *)trayblinklist, 0}, + {ST_3OGGLE, N_("Blink task bar on:"), 0, 0, (void *)taskbarlist, 0}, +#ifdef WIN32 + {ST_3OGGLE, N_("Make a beep sound on:"), 0, N_("Play the \"Instant Message Notification\" system sound upon the selected events"), (void *)beeplist, 0}, +#else +#ifdef USE_LIBCANBERRA + {ST_3OGGLE, N_("Make a beep sound on:"), 0, N_("Play \"message-new-instant\" from the freedesktop.org sound theme upon the selected events"), (void *)beeplist, 0}, +#else + {ST_3OGGLE, N_("Make a beep sound on:"), 0, N_("Play a GTK beep upon the selected events"), (void *)beeplist, 0}, #endif +#endif + + {ST_TOGGLE, N_("Omit alerts when marked as being away"), P_OFFINTNL(hex_away_omit_alerts), 0, 0, 0}, + {ST_TOGGLE, N_("Omit alerts while the window is focused"), P_OFFINTNL(hex_gui_focus_omitalerts), 0, 0, 0}, + + {ST_HEADER, N_("Tray Behavior"), 0, 0, 0}, + {ST_TOGGLE, N_("Enable system tray icon"), P_OFFINTNL(hex_gui_tray), 0, 0, 4}, + {ST_TOGGLE, N_("Minimize to tray"), P_OFFINTNL(hex_gui_tray_minimize), 0, 0, 0}, + {ST_TOGGLE, N_("Close to tray"), P_OFFINTNL(hex_gui_tray_close), 0, 0, 0}, + {ST_TOGGLE, N_("Automatically mark away/back"), P_OFFINTNL(hex_gui_tray_away), N_("Automatically change status when hiding to tray."), 0, 0}, + {ST_TOGGLE, N_("Only show notifications when hidden or iconified"), P_OFFINTNL(hex_gui_tray_quiet), 0, 0, 0}, + + {ST_HEADER, N_("Highlighted Messages"),0,0,0}, + {ST_LABEL, N_("Highlighted messages are ones where your nickname is mentioned, but also:"), 0, 0, 0, 1}, + + {ST_ENTRY, N_("Extra words to highlight:"), P_OFFSETNL(hex_irc_extra_hilight), 0, 0, sizeof prefs.hex_irc_extra_hilight}, + {ST_ENTRY, N_("Nick names not to highlight:"), P_OFFSETNL(hex_irc_no_hilight), 0, 0, sizeof prefs.hex_irc_no_hilight}, + {ST_ENTRY, N_("Nick names to always highlight:"), P_OFFSETNL(hex_irc_nick_hilight), 0, 0, sizeof prefs.hex_irc_nick_hilight}, + {ST_LABEL, N_("Separate multiple words with commas.\nWildcards are accepted.")}, + + {ST_END, 0, 0, 0, 0, 0} +}; + +static const setting alert_settings_nonotifications[] = +{ + {ST_HEADER, N_("Alerts"),0,0,0}, + + {ST_ALERTHEAD}, {ST_3OGGLE, N_("Blink tray icon on:"), 0, 0, (void *)trayblinklist, 0}, #ifdef HAVE_GTK_MAC {ST_3OGGLE, N_("Bounce dock icon on:"), 0, 0, (void *)taskbarlist, 0}, @@ -421,17 +461,10 @@ static const setting alert_settings[] = {ST_TOGGLE, N_("Omit alerts while the window is focused"), P_OFFINTNL(hex_gui_focus_omitalerts), 0, 0, 0}, {ST_HEADER, N_("Tray Behavior"), 0, 0, 0}, -#ifdef WIN32 - {ST_TOGGLE, N_("Enable system tray icon"), P_OFFINTNL(hex_gui_tray), 0, 0, 3}, -#else {ST_TOGGLE, N_("Enable system tray icon"), P_OFFINTNL(hex_gui_tray), 0, 0, 4}, -#endif {ST_TOGGLE, N_("Minimize to tray"), P_OFFINTNL(hex_gui_tray_minimize), 0, 0, 0}, {ST_TOGGLE, N_("Close to tray"), P_OFFINTNL(hex_gui_tray_close), 0, 0, 0}, {ST_TOGGLE, N_("Automatically mark away/back"), P_OFFINTNL(hex_gui_tray_away), N_("Automatically change status when hiding to tray."), 0, 0}, -#ifndef WIN32 - {ST_TOGGLE, N_("Only show tray balloons when hidden or iconified"), P_OFFINTNL(hex_gui_tray_quiet), 0, 0, 0}, -#endif {ST_HEADER, N_("Highlighted Messages"),0,0,0}, {ST_LABEL, N_("Highlighted messages are ones where your nickname is mentioned, but also:"), 0, 0, 0, 1}, @@ -449,7 +482,7 @@ static const setting alert_settings_unity[] = {ST_HEADER, N_("Alerts"),0,0,0}, {ST_ALERTHEAD}, - {ST_3OGGLE, N_("Show tray balloons on:"), 0, 0, (void *)balloonlist, 0}, + {ST_3OGGLE, N_("Show notifications on:"), 0, 0, (void *)balloonlist, 0}, {ST_3OGGLE, N_("Blink task bar on:"), 0, 0, (void *)taskbarlist, 0}, {ST_3OGGLE, N_("Make a beep sound on:"), 0, 0, (void *)beeplist, 0}, @@ -467,6 +500,28 @@ static const setting alert_settings_unity[] = {ST_END, 0, 0, 0, 0, 0} }; +static const setting alert_settings_unityandnonotifications[] = +{ + {ST_HEADER, N_("Alerts"), 0, 0, 0}, + + {ST_ALERTHEAD}, + {ST_3OGGLE, N_("Blink task bar on:"), 0, 0, (void *)taskbarlist, 0}, + {ST_3OGGLE, N_("Make a beep sound on:"), 0, 0, (void *)beeplist, 0}, + + {ST_TOGGLE, N_("Omit alerts when marked as being away"), P_OFFINTNL (hex_away_omit_alerts), 0, 0, 0}, + {ST_TOGGLE, N_("Omit alerts while the window is focused"), P_OFFINTNL (hex_gui_focus_omitalerts), 0, 0, 0}, + + {ST_HEADER, N_("Highlighted Messages"), 0, 0, 0}, + {ST_LABEL, N_("Highlighted messages are ones where your nickname is mentioned, but also:"), 0, 0, 0, 1}, + + {ST_ENTRY, N_("Extra words to highlight:"), P_OFFSETNL (hex_irc_extra_hilight), 0, 0, sizeof prefs.hex_irc_extra_hilight}, + {ST_ENTRY, N_("Nick names not to highlight:"), P_OFFSETNL (hex_irc_no_hilight), 0, 0, sizeof prefs.hex_irc_no_hilight}, + {ST_ENTRY, N_("Nick names to always highlight:"), P_OFFSETNL (hex_irc_nick_hilight), 0, 0, sizeof prefs.hex_irc_nick_hilight}, + {ST_LABEL, N_("Separate multiple words with commas.\nWildcards are accepted.")}, + + {ST_END, 0, 0, 0, 0, 0} +}; + static const setting general_settings[] = { {ST_HEADER, N_("Default Messages"),0,0,0}, @@ -559,9 +614,6 @@ static const char *const proxytypes[] = N_("Socks4"), N_("Socks5"), N_("HTTP"), -#ifdef USE_MSPROXY - N_("MS Proxy (ISA)"), -#endif #ifdef USE_LIBPROXY N_("Auto"), #endif @@ -598,11 +650,7 @@ static const setting network_settings[] = {ST_MENU, N_("Use proxy for:"), P_OFFINTNL(hex_net_proxy_use), 0, proxyuse, 0}, {ST_HEADER, N_("Proxy Authentication"), 0, 0, 0, 0}, -#ifdef USE_MSPROXY - {ST_TOGGLE, N_("Use Authentication (MS Proxy, HTTP or Socks5 only)"), P_OFFINTNL(hex_net_proxy_auth), 0, 0, 0}, -#else {ST_TOGGLE, N_("Use Authentication (HTTP or Socks5 only)"), P_OFFINTNL(hex_net_proxy_auth), 0, 0, 0}, -#endif {ST_ENTRY, N_("Username:"), P_OFFSETNL(hex_net_proxy_user), 0, 0, sizeof prefs.hex_net_proxy_user}, {ST_ENTRY, N_("Password:"), P_OFFSETNL(hex_net_proxy_pass), 0, GINT_TO_POINTER(1), sizeof prefs.hex_net_proxy_pass}, @@ -630,7 +678,7 @@ setup_headlabel (GtkWidget *tab, int row, int col, char *text) char buf[128]; char *sp; - snprintf (buf, sizeof (buf), "<b><span size=\"smaller\">%s</span></b>", text); + g_snprintf (buf, sizeof (buf), "<b><span size=\"smaller\">%s</span></b>", text); sp = strchr (buf + 17, ' '); if (sp) *sp = '\n'; @@ -752,7 +800,7 @@ setup_create_italic_label (char *text) char buf[256]; label = gtk_label_new (NULL); - snprintf (buf, sizeof (buf), "<i><span size=\"smaller\">%s</span></i>", text); + g_snprintf (buf, sizeof (buf), "<i><span size=\"smaller\">%s</span></i>", text); gtk_label_set_markup (GTK_LABEL (label), buf); gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER); @@ -1121,8 +1169,8 @@ setup_entry_cb (GtkEntry *entry, setting *set) { int size; int pos; - int len = gtk_entry_get_text_length (entry); unsigned char *p = (unsigned char*)gtk_entry_get_text (entry); + int len = strlen (p); /* need to truncate? */ if (len >= set->extra) @@ -1220,9 +1268,9 @@ setup_create_header (GtkWidget *table, int row, char *labeltext) char buf[128]; if (row == 0) - snprintf (buf, sizeof (buf), "<b>%s</b>", _(labeltext)); + g_snprintf (buf, sizeof (buf), "<b>%s</b>", _(labeltext)); else - snprintf (buf, sizeof (buf), "\n<b>%s</b>", _(labeltext)); + g_snprintf (buf, sizeof (buf), "\n<b>%s</b>", _(labeltext)); label = gtk_label_new (NULL); gtk_label_set_markup (GTK_LABEL (label), buf); @@ -1683,9 +1731,8 @@ setup_snd_changed_cb (GtkEntry *ent, GtkTreeView *tree) return; /* get the new sound file */ - if (sound_files[n]) - free (sound_files[n]); - sound_files[n] = strdup (gtk_entry_get_text (GTK_ENTRY (ent))); + g_free (sound_files[n]); + sound_files[n] = g_strdup (gtk_entry_get_text (GTK_ENTRY (ent))); /* update the TreeView list */ store = (GtkListStore *)gtk_tree_view_get_model (tree); @@ -1790,7 +1837,7 @@ setup_add_page (const char *title, GtkWidget *book, GtkWidget *tab) /* label */ label = gtk_label_new (NULL); - snprintf (buf, sizeof (buf), "<b><big>%s</big></b>", _(title)); + g_snprintf (buf, sizeof (buf), "<b><big>%s</big></b>", _(title)); gtk_label_set_markup (GTK_LABEL (label), buf); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); gtk_misc_set_padding (GTK_MISC (label), 2, 1); @@ -1839,10 +1886,18 @@ setup_create_pages (GtkWidget *box) setup_add_page (cata[8], book, setup_create_page (general_settings)); - if (unity_mode ()) + if (unity_mode () && !notification_backend_supported ()) + { + setup_add_page (cata[9], book, setup_create_page (alert_settings_unityandnonotifications)); + } + else if (unity_mode ()) { setup_add_page (cata[9], book, setup_create_page (alert_settings_unity)); } + else if (!notification_backend_supported ()) + { + setup_add_page (cata[9], book, setup_create_page (alert_settings_nonotifications)); + } else { setup_add_page (cata[9], book, setup_create_page (alert_settings)); @@ -2121,6 +2176,8 @@ setup_apply (struct hexchatprefs *pr) noapply = TRUE; if (DIFF (hex_gui_ulist_style)) noapply = TRUE; + if (DIFF (hex_gui_ulist_sort)) + noapply = TRUE; if (DIFF (hex_gui_tab_dots)) do_layout = TRUE; @@ -2137,6 +2194,13 @@ setup_apply (struct hexchatprefs *pr) " menu first."), FE_MSG_WARN | FE_MSG_MARKUP); + /* format cannot be blank, there is already a setting for this */ + if (pr->hex_stamp_text_format[0] == 0) + { + pr->hex_stamp_text = 0; + strcpy (pr->hex_stamp_text_format, prefs.hex_stamp_text_format); + } + memcpy (&prefs, pr, sizeof (prefs)); #ifdef WIN32 diff --git a/src/fe-gtk/sexy-iso-codes.c b/src/fe-gtk/sexy-iso-codes.c index e6acb726..06c8cd07 100644 --- a/src/fe-gtk/sexy-iso-codes.c +++ b/src/fe-gtk/sexy-iso-codes.c @@ -19,10 +19,11 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "config.h" + #include "sexy-iso-codes.h" #include <libintl.h> #include <string.h> -#include "../../config.h" #define ISO_639_DOMAIN "iso_639" #define ISO_3166_DOMAIN "iso_3166" diff --git a/src/fe-gtk/sexy-spell-entry.c b/src/fe-gtk/sexy-spell-entry.c index bac1e2b5..f57c7f41 100644 --- a/src/fe-gtk/sexy-spell-entry.c +++ b/src/fe-gtk/sexy-spell-entry.c @@ -31,7 +31,12 @@ #include <sys/types.h> #include <sys/stat.h> #include "sexy-iso-codes.h" + +#ifdef WIN32 +#include "marshal.h" +#else #include "../common/marshal.h" +#endif #ifdef WIN32 #include "../common/typedef.h" @@ -136,6 +141,8 @@ enum }; static guint signals[LAST_SIGNAL] = {0}; +static PangoAttrList *empty_attrs_list = NULL; + static gboolean spell_accumulator(GSignalInvocationHint *hint, GValue *return_accu, const GValue *handler_return, gpointer data) { @@ -243,6 +250,11 @@ sexy_spell_entry_class_init(SexySpellEntryClass *klass) _hexchat_marshal_BOOLEAN__STRING, G_TYPE_BOOLEAN, 1, G_TYPE_STRING); + + if (empty_attrs_list == NULL) + { + empty_attrs_list = pango_attr_list_new (); + } } static void @@ -292,7 +304,7 @@ insert_hiddenchar (SexySpellEntry *entry, guint start, guint end) * is 'hidden' */ #if 0 PangoAttribute *hattr; - PangoRectangle *rect = g_malloc (sizeof (PangoRectangle)); + PangoRectangle *rect = g_new (PangoRectangle, 1); rect->x = 0; rect->y = 0; @@ -758,12 +770,9 @@ sexy_spell_entry_finalize(GObject *obj) pango_attr_list_unref(entry->priv->attr_list); if (entry->priv->dict_hash) g_hash_table_destroy(entry->priv->dict_hash); - if (entry->priv->words) - g_strfreev(entry->priv->words); - if (entry->priv->word_starts) - g_free(entry->priv->word_starts); - if (entry->priv->word_ends) - g_free(entry->priv->word_ends); + g_strfreev(entry->priv->words); + g_free(entry->priv->word_starts); + g_free(entry->priv->word_ends); if (have_enchant) { if (entry->priv->broker) { @@ -1038,7 +1047,7 @@ sexy_spell_entry_recheck_all(SexySpellEntry *entry) { /* Check for attributes */ text = gtk_entry_get_text (GTK_ENTRY (entry)); - text_len = gtk_entry_get_text_length (GTK_ENTRY (entry)); + text_len = strlen (text); check_attributes (entry, text, text_len); } @@ -1078,7 +1087,14 @@ sexy_spell_entry_expose(GtkWidget *widget, GdkEventExpose *event) layout = gtk_entry_get_layout(gtk_entry); - pango_layout_set_attributes(layout, entry->priv->attr_list); + if (gtk_entry->preedit_length == 0) + { + pango_layout_set_attributes(layout, entry->priv->attr_list); + } + else + { + pango_layout_set_attributes(layout, empty_attrs_list); + } return GTK_WIDGET_CLASS(parent_class)->expose_event (widget, event); } diff --git a/src/fe-gtk/textgui.c b/src/fe-gtk/textgui.c index 9956e9c6..b0f2f392 100644 --- a/src/fe-gtk/textgui.c +++ b/src/fe-gtk/textgui.c @@ -81,14 +81,14 @@ PrintTextLine (xtext_buffer *xtbuf, unsigned char *text, int len, int indent, ti timet = time (0); stamp_size = get_stamp_str (prefs.hex_stamp_text_format, timet, &stamp); - new_text = malloc (len + stamp_size + 1); + new_text = g_malloc (len + stamp_size + 1); memcpy (new_text, stamp, stamp_size); g_free (stamp); memcpy (new_text + stamp_size, text, len); - gtk_xtext_append (xtbuf, new_text, len + stamp_size); - free (new_text); + gtk_xtext_append (xtbuf, new_text, len + stamp_size, timet); + g_free (new_text); } else - gtk_xtext_append (xtbuf, text, len); + gtk_xtext_append (xtbuf, text, len, timet); return; } @@ -173,13 +173,12 @@ pevent_edited (GtkCellRendererText *render, gchar *pathstr, gchar *new_text, gpo } if (m > (te[sig].num_args & 0x7f)) { - free (out); - out = malloc (4096); - snprintf (out, 4096, - _("This signal is only passed %d args, $%d is invalid"), - te[sig].num_args & 0x7f, m); + g_free (out); + out = g_strdup_printf ( + _("This signal is only passed %d args, $%d is invalid"), + te[sig].num_args & 0x7f, m); fe_message (out, FE_MSG_WARN); - free (out); + g_free (out); return; } @@ -188,23 +187,20 @@ pevent_edited (GtkCellRendererText *render, gchar *pathstr, gchar *new_text, gpo gtk_list_store_set (GTK_LIST_STORE (model), &iter, TEXT_COLUMN, new_text, -1); gtk_tree_path_free (path); - if (pntevts_text[sig]) - free (pntevts_text[sig]); - if (pntevts[sig]) - free (pntevts[sig]); + g_free (pntevts_text[sig]); + g_free (pntevts[sig]); - pntevts_text[sig] = malloc (len + 1); - memcpy (pntevts_text[sig], text, len + 1); + pntevts_text[sig] = g_strdup (text); pntevts[sig] = out; - out = malloc (len + 2); + out = g_malloc (len + 2); memcpy (out, text, len + 1); out[len] = '\n'; out[len + 1] = 0; check_special_chars (out, TRUE); PrintTextRaw (xtext->buffer, out, 0, 0); - free (out); + g_free (out); /* Scroll to bottom */ gtk_adjustment_set_value (xtext->adj, gtk_adjustment_get_upper (xtext->adj)); @@ -328,14 +324,14 @@ pevent_test_cb (GtkWidget * wid, GtkWidget * twid) text = _(pntevts_text[n]); len = strlen (text); - out = malloc (len + 2); + out = g_malloc (len + 2); memcpy (out, text, len + 1); out[len] = '\n'; out[len + 1] = 0; check_special_chars (out, TRUE); PrintTextRaw (GTK_XTEXT (twid)->buffer, out, 0, 0); - free (out); + g_free (out); } } diff --git a/src/fe-gtk/userlistgui.c b/src/fe-gtk/userlistgui.c index 19564ece..d06975ca 100644 --- a/src/fe-gtk/userlistgui.c +++ b/src/fe-gtk/userlistgui.c @@ -42,11 +42,11 @@ enum { - COL_PIX=0, // GdkPixbuf * - COL_NICK=1, // char * - COL_HOST=2, // char * - COL_USER=3, // struct User * - COL_GDKCOLOR=4 // GdkColor * + COL_PIX=0, /* GdkPixbuf * */ + COL_NICK=1, /* char * */ + COL_HOST=2, /* char * */ + COL_USER=3, /* struct User * */ + COL_GDKCOLOR=4 /* GdkColor * */ }; @@ -105,7 +105,7 @@ fe_userlist_numbers (session *sess) { if (sess->total) { - snprintf (tbuf, sizeof (tbuf), _("%d ops, %d total"), sess->ops, sess->total); + g_snprintf (tbuf, sizeof (tbuf), _("%d ops, %d total"), sess->ops, sess->total); tbuf[sizeof (tbuf) - 1] = 0; gtk_label_set_text (GTK_LABEL (sess->gui->namelistinfo), tbuf); } else @@ -188,7 +188,7 @@ userlist_selection_list (GtkWidget *widget, int *num_ret) if (num_sel < 1) return NULL; - nicks = malloc (sizeof (char *) * (num_sel + 1)); + nicks = g_new (char *, num_sel + 1); i = 0; gtk_tree_model_get_iter_first (model, &iter); @@ -286,7 +286,7 @@ fe_userlist_remove (session *sess, struct User *user) int sel; iter = find_row (GTK_TREE_VIEW (sess->gui->user_tree), - sess->res->user_model, user, &sel); + GTK_TREE_MODEL(sess->res->user_model), user, &sel); if (!iter) return 0; @@ -316,7 +316,7 @@ fe_userlist_rehash (session *sess, struct User *user) int nick_color = 0; iter = find_row (GTK_TREE_VIEW (sess->gui->user_tree), - sess->res->user_model, user, &sel); + GTK_TREE_MODEL(sess->res->user_model), user, &sel); if (!iter) return; @@ -332,9 +332,9 @@ fe_userlist_rehash (session *sess, struct User *user) } void -fe_userlist_insert (session *sess, struct User *newuser, int row, int sel) +fe_userlist_insert (session *sess, struct User *newuser, gboolean sel) { - GtkTreeModel *model = sess->res->user_model; + GtkTreeModel *model = GTK_TREE_MODEL(sess->res->user_model); GdkPixbuf *pix = get_user_icon (sess->server, newuser); GtkTreeIter iter; char *nick; @@ -348,16 +348,16 @@ fe_userlist_insert (session *sess, struct User *newuser, int row, int sel) nick = newuser->nick; if (!prefs.hex_gui_ulist_icons) { - nick = malloc (strlen (newuser->nick) + 2); + nick = g_malloc (strlen (newuser->nick) + 2); nick[0] = newuser->prefix[0]; - if (!nick[0] || nick[0] == ' ') + if (nick[0] == '\0' || nick[0] == ' ') strcpy (nick, newuser->nick); else strcpy (nick + 1, newuser->nick); pix = NULL; } - gtk_list_store_insert_with_values (GTK_LIST_STORE (model), &iter, row, + gtk_list_store_insert_with_values (GTK_LIST_STORE (model), &iter, 0, COL_PIX, pix, COL_NICK, nick, COL_HOST, newuser->hostname, @@ -367,7 +367,7 @@ fe_userlist_insert (session *sess, struct User *newuser, int row, int sel) if (!prefs.hex_gui_ulist_icons) { - free (nick); + g_free (nick); } /* is it me? */ @@ -377,14 +377,6 @@ fe_userlist_insert (session *sess, struct User *newuser, int row, int sel) mg_set_access_icon (sess->gui, pix, sess->server->is_away); } -#if 0 - if (prefs.hilitenotify && notify_isnotify (sess, newuser->nick)) - { - gtk_clist_set_foreground ((GtkCList *) sess->gui->user_clist, row, - &colors[prefs.nu_color]); - } -#endif - /* is it the front-most tab? */ if (gtk_tree_view_get_model (GTK_TREE_VIEW (sess->gui->user_tree)) == model) @@ -396,12 +388,6 @@ fe_userlist_insert (session *sess, struct User *newuser, int row, int sel) } void -fe_userlist_move (session *sess, struct User *user, int new_row) -{ - fe_userlist_insert (sess, user, new_row, fe_userlist_remove (sess, user)); -} - -void fe_userlist_clear (session *sess) { gtk_list_store_clear (sess->res->user_model); @@ -459,11 +445,67 @@ userlist_dnd_leave (GtkTreeView *widget, GdkDragContext *context, guint ttime) return TRUE; } -void * -userlist_create_model (void) +static int +userlist_alpha_cmp (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer userdata) +{ + struct User *user_a, *user_b; + + gtk_tree_model_get (model, iter_a, COL_USER, &user_a, -1); + gtk_tree_model_get (model, iter_b, COL_USER, &user_b, -1); + + return nick_cmp_alpha (user_a, user_b, ((session*)userdata)->server); +} + +static int +userlist_ops_cmp (GtkTreeModel *model, GtkTreeIter *iter_a, GtkTreeIter *iter_b, gpointer userdata) { - return gtk_list_store_new (5, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, + struct User *user_a, *user_b; + + gtk_tree_model_get (model, iter_a, COL_USER, &user_a, -1); + gtk_tree_model_get (model, iter_b, COL_USER, &user_b, -1); + + return nick_cmp_az_ops (((session*)userdata)->server, user_a, user_b); +} + +GtkListStore * +userlist_create_model (session *sess) +{ + GtkListStore *store; + GtkTreeIterCompareFunc cmp_func; + GtkSortType sort_type; + + store = gtk_list_store_new (5, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, GDK_TYPE_COLOR); + + switch (prefs.hex_gui_ulist_sort) + { + case 0: + cmp_func = userlist_ops_cmp; + sort_type = GTK_SORT_ASCENDING; + break; + case 1: + cmp_func = userlist_alpha_cmp; + sort_type = GTK_SORT_ASCENDING; + break; + case 2: + cmp_func = userlist_ops_cmp; + sort_type = GTK_SORT_DESCENDING; + break; + case 3: + cmp_func = userlist_alpha_cmp; + sort_type = GTK_SORT_DESCENDING; + break; + default: + /* No sorting */ + gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE(store), NULL, NULL, NULL); + return store; + } + + gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE(store), cmp_func, sess, NULL); + gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(store), + GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, sort_type); + + return store; } static void @@ -525,7 +567,7 @@ userlist_click_cb (GtkWidget *widget, GdkEventButton *event, gpointer userdata) i--; g_free (nicks[i]); } - free (nicks); + g_free (nicks); } return TRUE; } @@ -542,13 +584,13 @@ userlist_click_cb (GtkWidget *widget, GdkEventButton *event, gpointer userdata) i--; g_free (nicks[i]); } - free (nicks); + g_free (nicks); return TRUE; } if (nicks) { g_free (nicks[0]); - free (nicks); + g_free (nicks); } sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget)); @@ -567,7 +609,7 @@ userlist_click_cb (GtkWidget *widget, GdkEventButton *event, gpointer userdata) i--; g_free (nicks[i]); } - free (nicks); + g_free (nicks); } } else { @@ -668,7 +710,7 @@ void userlist_show (session *sess) { gtk_tree_view_set_model (GTK_TREE_VIEW (sess->gui->user_tree), - sess->res->user_model); + GTK_TREE_MODEL(sess->res->user_model)); } void diff --git a/src/fe-gtk/userlistgui.h b/src/fe-gtk/userlistgui.h index 993fe8f0..e24f2ebc 100644 --- a/src/fe-gtk/userlistgui.h +++ b/src/fe-gtk/userlistgui.h @@ -23,7 +23,7 @@ void userlist_set_value (GtkWidget *treeview, gfloat val); gfloat userlist_get_value (GtkWidget *treeview); GtkWidget *userlist_create (GtkWidget *box); -void *userlist_create_model (void); +GtkListStore *userlist_create_model (session *sess); void userlist_show (session *sess); void userlist_select (session *sess, char *name); char **userlist_selection_list (GtkWidget *widget, int *num_ret); diff --git a/src/fe-gtk/xtext.c b/src/fe-gtk/xtext.c index 6a499f52..6692b360 100644 --- a/src/fe-gtk/xtext.c +++ b/src/fe-gtk/xtext.c @@ -31,13 +31,19 @@ #include <stdlib.h> #include <time.h> -#include "../../config.h" +#include "config.h" #include "../common/hexchat.h" #include "../common/fe.h" #include "../common/util.h" #include "../common/hexchatc.h" #include "../common/url.h" + +#ifdef WIN32 +#include "marshal.h" +#else #include "../common/marshal.h" +#endif + #include "fe-gtk.h" #include "xtext.h" #include "fkeys.h" @@ -484,7 +490,10 @@ gtk_xtext_adjustment_set (xtext_buffer *buf, int fire_signal) adj->page_increment = adj->page_size; if (adj->value > adj->upper - adj->page_size) + { + buf->scrollbar_down = TRUE; adj->value = adj->upper - adj->page_size; + } if (adj->value < 0) adj->value = 0; @@ -829,7 +838,6 @@ find_x (GtkXText *xtext, textentry *ent, int x, int subline, int indent) int off, len, wid, mbl, mbw; /* Skip to the first chunk of stuff for the subline */ - list = ent->slp; if (subline > 0) { suboff = GPOINTER_TO_INT (g_slist_nth_data (ent->sublines, subline - 1)); @@ -846,6 +854,8 @@ find_x (GtkXText *xtext, textentry *ent, int x, int subline, int indent) list = ent->slp; } /* Step to the first character of the subline */ + if (list == NULL) + return 0; meta = list->data; off = meta->off; len = meta->len; @@ -934,12 +944,12 @@ gtk_xtext_find_x (GtkXText * xtext, int x, textentry * ent, int subline, } static textentry * -gtk_xtext_find_char (GtkXText * xtext, int x, int y, int *off, - int *out_of_bounds, int *ret_subline) +gtk_xtext_find_char (GtkXText * xtext, int x, int y, int *off, int *out_of_bounds) { textentry *ent; int line; int subline; + int outofbounds; /* Adjust y value for negative rounding, double to int */ if (y < 0) @@ -948,13 +958,12 @@ gtk_xtext_find_char (GtkXText * xtext, int x, int y, int *off, line = (y + xtext->pixel_offset) / xtext->fontsize; ent = gtk_xtext_nth (xtext, line + (int)xtext->adj->value, &subline); if (!ent) - return 0; + return NULL; if (off) - *off = gtk_xtext_find_x (xtext, x, ent, subline, line, out_of_bounds); - - if (ret_subline) - *ret_subline = subline; + *off = gtk_xtext_find_x (xtext, x, ent, subline, line, &outofbounds); + if (out_of_bounds) + *out_of_bounds = outofbounds; return ent; } @@ -1049,14 +1058,14 @@ gtk_xtext_paint (GtkWidget *widget, GdkRectangle *area) return; } - ent_start = gtk_xtext_find_char (xtext, area->x, area->y, NULL, NULL, NULL); + ent_start = gtk_xtext_find_char (xtext, area->x, area->y, NULL, NULL); if (!ent_start) { xtext_draw_bg (xtext, area->x, area->y, area->width, area->height); goto xit; } ent_end = gtk_xtext_find_char (xtext, area->x + area->width, - area->y + area->height, NULL, NULL, NULL); + area->y + area->height, NULL, NULL); if (!ent_end) ent_end = xtext->buffer->text_last; @@ -1244,13 +1253,14 @@ lamejump: } } /* marking upward? */ - else if (xtext->buffer->last_ent_end == end_ent && + else if (xtext->buffer->last_ent_start != NULL && + xtext->buffer->last_ent_end == end_ent && xtext->buffer->last_offset_end == end_offset) { ent = end_ent; while (ent) { - if (ent == start_ent) + if (ent == start_ent && xtext->buffer->last_ent_start) { gtk_xtext_selection_up (xtext, xtext->buffer->last_ent_start, ent, start_offset); /*gtk_xtext_render_ents (xtext, xtext->buffer->last_ent_start, ent);*/ @@ -1299,99 +1309,104 @@ gtk_xtext_selection_draw (GtkXText * xtext, GdkEventMotion * event, gboolean ren textentry *ent; textentry *ent_end; textentry *ent_start; - int offset_start; - int offset_end; - int subline_start; - int subline_end; - int oob; - int marking_up = FALSE; - int len_start; - int len_end; + int offset_start = 0; + int offset_end = 0; + textentry *low_ent, *high_ent; + int low_x, low_y, low_offs; + int high_x, high_y, high_offs, high_len; - ent_start = gtk_xtext_find_char (xtext, xtext->select_start_x, xtext->select_start_y, &offset_start, &oob, &subline_start); - ent_end = gtk_xtext_find_char (xtext, xtext->select_end_x, xtext->select_end_y, &offset_end, &oob, &subline_end); + if (xtext->buffer->text_first == NULL) + return; - if ((!ent_start || !ent_end) && !xtext->buffer->text_last && xtext->adj->value != xtext->buffer->old_value) - { - gtk_xtext_render_page (xtext); + ent_start = gtk_xtext_find_char (xtext, xtext->select_start_x, xtext->select_start_y, &offset_start, NULL); + ent_end = gtk_xtext_find_char (xtext, xtext->select_end_x, xtext->select_end_y, &offset_end, NULL); + if (ent_start == NULL && ent_end == NULL) return; - } - if (!ent_start) + if ((ent_start != ent_end && xtext->select_start_y > xtext->select_end_y) || /* different entries */ + (ent_start == ent_end && offset_start > offset_end)) /* same entry, different character offsets */ { - ent_start = xtext->buffer->text_last; - offset_start = ent_start->str_len; + /* marking up */ + low_ent = ent_end; + low_x = xtext->select_end_x; + low_y = xtext->select_end_y; + low_offs = offset_end; + high_ent = ent_start; + high_x = xtext->select_start_x; + high_y = xtext->select_start_y; + high_offs = offset_start; } - - if (!ent_end) + else { - ent_end = xtext->buffer->text_last; - offset_end = ent_end->str_len; + /* marking down */ + low_ent = ent_start; + low_x = xtext->select_start_x; + low_y = xtext->select_start_y; + low_offs = offset_start; + high_ent = ent_end; + high_x = xtext->select_end_x; + high_y = xtext->select_end_y; + high_offs = offset_end; } - - if ((ent_start != ent_end && xtext->select_start_y > xtext->select_end_y) || /* different entries */ - (ent_start == ent_end && subline_start > subline_end) || /* different lines */ - (ent_start == ent_end && subline_start == subline_end && xtext->select_start_x > xtext->select_end_x)) /* marking to the left */ + if (low_ent == NULL) + { + low_ent = xtext->buffer->text_first; + low_offs = 0; + } + if (high_ent == NULL) { - marking_up = TRUE; + high_ent = xtext->buffer->text_last; + high_offs = high_ent->str_len; } /* word selection */ if (xtext->word_select) { /* a word selection cannot be started if the cursor is out of bounds in gtk_xtext_button_press */ - gtk_xtext_get_word (xtext, xtext->select_start_x, xtext->select_start_y, NULL, &offset_start, &len_start, NULL); + gtk_xtext_get_word (xtext, low_x, low_y, NULL, &low_offs, NULL, NULL); /* in case the cursor is out of bounds we keep offset_end from gtk_xtext_find_char and fix the length */ - if (gtk_xtext_get_word (xtext, xtext->select_end_x, xtext->select_end_y, NULL, &offset_end, &len_end, NULL) == NULL) - len_end = offset_end == ent_end->str_len? 0: -1; /* -1 for the space, 0 if at the end */ - - if (!marking_up) - offset_end += len_end; - else - offset_start += len_start; + if (gtk_xtext_get_word (xtext, high_x, high_y, NULL, &high_offs, &high_len, NULL) == NULL) + high_len = high_offs == high_ent->str_len? 0: -1; /* -1 for the space, 0 if at the end */ + high_offs += high_len; + if (low_y < 0) + low_offs = xtext->buffer->last_offset_start; + if (high_y > xtext->buffer->window_height) + high_offs = xtext->buffer->last_offset_end; } /* line/ent selection */ else if (xtext->line_select) { - offset_start = marking_up? ent_start->str_len: 0; - offset_end = marking_up? 0: ent_end->str_len; + low_offs = 0; + high_offs = high_ent->str_len; } - - if (marking_up) + /* character selection */ + else { - int temp; - - /* ensure ent_start is above ent_end */ - if (ent_start != ent_end) - { - ent = ent_start; - ent_start = ent_end; - ent_end = ent; - } - - /* switch offsets as well */ - temp = offset_start; - offset_start = offset_end; - offset_end = temp; + if (low_y < 0) + low_offs = xtext->buffer->last_offset_start; + if (high_y > xtext->buffer->window_height) + high_offs = xtext->buffer->last_offset_end; } /* set all the old mark_ fields to -1 */ gtk_xtext_selection_clear (xtext->buffer); - /* set the default values */ - ent_start->mark_end = ent_start->str_len; - ent_end->mark_start = 0; + low_ent->mark_start = low_offs; + low_ent->mark_end = high_offs; - /* set the calculated values (this overwrites the default values if we're on the same ent) */ - ent_start->mark_start = offset_start; - ent_end->mark_end = offset_end; - - /* set all the mark_ fields of the ents within the selection */ - if (ent_start != ent_end) + if (low_ent != high_ent) { - ent = ent_start->next; - while (ent && ent != ent_end) + low_ent->mark_end = low_ent->str_len; + if (high_offs != 0) + { + high_ent->mark_start = 0; + high_ent->mark_end = high_offs; + } + + /* set all the mark_ fields of the ents within the selection */ + ent = low_ent->next; + while (ent && ent != high_ent) { ent->mark_start = 0; ent->mark_end = ent->str_len; @@ -1400,7 +1415,7 @@ gtk_xtext_selection_draw (GtkXText * xtext, GdkEventMotion * event, gboolean ren } if (render) - gtk_xtext_selection_render (xtext, ent_start, ent_end); + gtk_xtext_selection_render (xtext, low_ent, high_ent); } static int @@ -1532,7 +1547,7 @@ gtk_xtext_get_word (GtkXText * xtext, int x, int y, textentry ** ret_ent, int out_of_bounds = 0; int len_to_offset = 0; - ent = gtk_xtext_find_char (xtext, x, y, &offset, &out_of_bounds, NULL); + ent = gtk_xtext_find_char (xtext, x, y, &offset, &out_of_bounds); if (ent == NULL || out_of_bounds || offset < 0 || offset >= ent->str_len) return NULL; @@ -1585,11 +1600,11 @@ gtk_xtext_get_word (GtkXText * xtext, int x, int y, textentry ** ret_ent, /* make sure we're not before the start of the match */ if (len_to_offset < start) - return 0; + return NULL; /* and not after it */ if (len_to_offset - start >= end - start) - return 0; + return NULL; } return word; @@ -1646,7 +1661,8 @@ gtk_xtext_check_mark_stamp (GtkXText *xtext, GdkModifierType mask) { gboolean redraw = FALSE; - if (mask & STATE_SHIFT || prefs.hex_text_autocopy_stamp) + if ((mask & STATE_SHIFT || prefs.hex_text_autocopy_stamp) + && (!prefs.hex_stamp_text || prefs.hex_text_indent)) { if (!xtext->mark_stamp) { @@ -1707,7 +1723,7 @@ gtk_xtext_get_word_adjust (GtkXText *xtext, int x, int y, textentry **word_ent, } } } - g_slist_free_full (slp, free); + g_slist_free_full (slp, g_free); return word_type; } @@ -1853,7 +1869,7 @@ gtk_xtext_set_clip_owner (GtkWidget * xtext, GdkEventButton * event) gtk_selection_owner_set (xtext, GDK_SELECTION_SECONDARY, event ? event->time : GDK_CURRENT_TIME); } - free (str); + g_free (str); } } @@ -2107,7 +2123,7 @@ gtk_xtext_selection_get_text (GtkXText *xtext, int *len_ret) return NULL; /* now allocate mem and copy buffer */ - pos = txt = malloc (len); + pos = txt = g_malloc (len); ent = buf->last_ent_start; while (ent) { @@ -2147,10 +2163,11 @@ gtk_xtext_selection_get_text (GtkXText *xtext, int *len_ret) /*stripped = gtk_xtext_conv_color (txt, strlen (txt), &len);*/ stripped = txt; len = strlen (txt); - } else + } + else { stripped = gtk_xtext_strip_color (txt, strlen (txt), NULL, &len, NULL, FALSE); - free (txt); + g_free (txt); } *len_ret = len; @@ -2205,7 +2222,7 @@ gtk_xtext_selection_get (GtkWidget * widget, g_free (new_text); } - free (stripped); + g_free (stripped); } static gboolean @@ -2360,7 +2377,7 @@ xtext_do_chunk(chunk_t *c) if (c->len1 == 0) return; - meta = malloc (sizeof *meta); + meta = g_new (offlen_t, 1); meta->off = c->off1; meta->len = c->len1; meta->emph = c->emph; @@ -2383,7 +2400,7 @@ gtk_xtext_strip_color (unsigned char *text, int len, unsigned char *outbuf, int mbl; /* multi-byte length */ if (outbuf == NULL) - new_str = malloc (len + 2); + new_str = g_malloc (len + 2); else new_str = outbuf; @@ -2459,7 +2476,7 @@ bad_utf8: /* Normal ending sequence, and give up if bad utf8 */ if (slpp) *slpp = c.slp; else - g_slist_free_full (c.slp, free); + g_slist_free_full (c.slp, g_free); return new_str; } @@ -2475,7 +2492,7 @@ gtk_xtext_text_width_ent (GtkXText *xtext, textentry *ent) if (ent->slp) { - g_slist_free_full (ent->slp, free); + g_slist_free_full (ent->slp, g_free); ent->slp = NULL; } @@ -2507,7 +2524,7 @@ gtk_xtext_text_width (GtkXText *xtext, unsigned char *text, int len) &new_len, &slp, !xtext->ignore_hidden); width = backend_get_text_width_slp (xtext, new_buf, slp); - g_slist_free_full (slp, free); + g_slist_free_full (slp, g_free); return width; } @@ -3254,7 +3271,7 @@ gtk_xtext_render_stamp (GtkXText * xtext, textentry * ent, { textentry tmp_ent; int jo, ji, hs; - int xsize, y; + int xsize, y, emphasis; /* trashing ent here, so make a backup first */ memcpy (&tmp_ent, ent, sizeof (tmp_ent)); @@ -3264,7 +3281,7 @@ gtk_xtext_render_stamp (GtkXText * xtext, textentry * ent, xtext->jump_out_offset = 0; xtext->jump_in_offset = 0; xtext->hilight_start = 0xffff; /* temp disable */ - int emphasis = 0; + emphasis = 0; if (xtext->mark_stamp) { @@ -3530,7 +3547,7 @@ gtk_xtext_save (GtkXText * xtext, int fh) &newlen, NULL, FALSE); write (fh, buf, newlen); write (fh, "\n", 1); - free (buf); + g_free (buf); ent = ent->next; } } @@ -3641,7 +3658,7 @@ gtk_xtext_nth (GtkXText *xtext, int line, int *subline) break; lines -= g_slist_length (ent->sublines); } - return 0; + return NULL; } } /* -- end of optimization -- */ @@ -3656,7 +3673,7 @@ gtk_xtext_nth (GtkXText *xtext, int line, int *subline) } ent = ent->next; } - return 0; + return NULL; } /* render enta (or an inclusive range enta->entb) */ @@ -3895,10 +3912,10 @@ gtk_xtext_kill_ent (xtext_buffer *buffer, textentry *ent) gtk_xtext_search_textentry_del (buffer, ent); } - g_slist_free_full (ent->slp, free); + g_slist_free_full (ent->slp, g_free); g_slist_free (ent->sublines); - free (ent); + g_free (ent); return visible; } @@ -4033,7 +4050,7 @@ gtk_xtext_clear (xtext_buffer *buf, int lines) while (buf->text_first) { next = buf->text_first->next; - free (buf->text_first); + g_free (buf->text_first); buf->text_first = next; } buf->text_last = NULL; @@ -4191,7 +4208,6 @@ gtk_xtext_search_textentry (xtext_buffer *buf, textentry *ent) hay = match? g_strdup (str): g_utf8_casefold (str, lstr); lhay = strlen (hay); - off = 0; for (pos = hay, len = lhay; len; off += buf->search_lnee, pos = hay + off, len = lhay - off) @@ -4210,7 +4226,7 @@ gtk_xtext_search_textentry (xtext_buffer *buf, textentry *ent) } /* Common processing --- */ - g_slist_free_full (slp, free); + g_slist_free_full (slp, g_free); return gl; } @@ -4639,7 +4655,7 @@ gtk_xtext_append_indent (xtext_buffer *buf, if (right_text[right_len-1] == '\n') right_len--; - ent = malloc (left_len + right_len + 2 + sizeof (textentry)); + ent = g_malloc (left_len + right_len + 2 + sizeof (textentry)); str = (unsigned char *) ent + sizeof (textentry); memcpy (str, left_text, left_len); @@ -4660,7 +4676,9 @@ gtk_xtext_append_indent (xtext_buffer *buf, space = 0; /* do we need to auto adjust the separator position? */ - if (buf->xtext->auto_indent && ent->indent < MARGIN + space) + if (buf->xtext->auto_indent && + buf->indent < buf->xtext->max_auto_indent && + ent->indent < MARGIN + space) { tempindent = MARGIN + space + buf->xtext->space_width + left_width; @@ -4681,7 +4699,7 @@ gtk_xtext_append_indent (xtext_buffer *buf, } void -gtk_xtext_append (xtext_buffer *buf, unsigned char *text, int len) +gtk_xtext_append (xtext_buffer *buf, unsigned char *text, int len, time_t stamp) { textentry *ent; @@ -4694,7 +4712,7 @@ gtk_xtext_append (xtext_buffer *buf, unsigned char *text, int len) if (len >= sizeof (buf->xtext->scratch_buffer)) len = sizeof (buf->xtext->scratch_buffer) - 1; - ent = malloc (len + 1 + sizeof (textentry)); + ent = g_malloc (len + 1 + sizeof (textentry)); ent->str = (unsigned char *) ent + sizeof (textentry); ent->str_len = len; if (len) @@ -4703,7 +4721,7 @@ gtk_xtext_append (xtext_buffer *buf, unsigned char *text, int len) ent->indent = 0; ent->left_len = -1; - gtk_xtext_append_entry (buf, ent, 0); + gtk_xtext_append_entry (buf, ent, stamp); } gboolean @@ -4738,11 +4756,14 @@ gtk_xtext_lastlog (xtext_buffer *out, xtext_buffer *search_area) } else { - gtk_xtext_append (out, ent->str, ent->str_len); + gtk_xtext_append (out, ent->str, ent->str_len, 0); } - out->text_last->stamp = ent->stamp; - gtk_xtext_search_textentry_add (out, out->text_last, gl, TRUE); + if (out->text_last) + { + out->text_last->stamp = ent->stamp; + gtk_xtext_search_textentry_add (out, out->text_last, gl, TRUE); + } } ent = ent->next; } @@ -4936,6 +4957,7 @@ gtk_xtext_buffer_show (GtkXText *xtext, xtext_buffer *buf, int render) if (buf->window_width != w) { buf->window_width = w; + buf->window_height = h; gtk_xtext_calc_lines (buf, FALSE); if (buf->scrollbar_down) gtk_adjustment_set_value (xtext->adj, xtext->adj->upper - @@ -4959,8 +4981,7 @@ gtk_xtext_buffer_new (GtkXText *xtext) { xtext_buffer *buf; - buf = malloc (sizeof (xtext_buffer)); - memset (buf, 0, sizeof (xtext_buffer)); + buf = g_new0 (xtext_buffer, 1); buf->old_value = -1; buf->xtext = xtext; buf->scrollbar_down = TRUE; @@ -4990,9 +5011,9 @@ gtk_xtext_buffer_free (xtext_buffer *buf) while (ent) { next = ent->next; - free (ent); + g_free (ent); ent = next; } - free (buf); + g_free (buf); } diff --git a/src/fe-gtk/xtext.h b/src/fe-gtk/xtext.h index 73f5b52d..d6853f9f 100644 --- a/src/fe-gtk/xtext.h +++ b/src/fe-gtk/xtext.h @@ -252,7 +252,7 @@ struct _GtkXTextClass }; GtkWidget *gtk_xtext_new (GdkColor palette[], int separator); -void gtk_xtext_append (xtext_buffer *buf, unsigned char *text, int len); +void gtk_xtext_append (xtext_buffer *buf, unsigned char *text, int len, time_t stamp); void gtk_xtext_append_indent (xtext_buffer *buf, unsigned char *left_text, int left_len, unsigned char *right_text, int right_len, diff --git a/src/fe-text/fe-text.c b/src/fe-text/fe-text.c index c8b64ab0..209a3d03 100644 --- a/src/fe-text/fe-text.c +++ b/src/fe-text/fe-text.c @@ -16,6 +16,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "config.h" + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -78,7 +80,6 @@ fe_new_window (struct session *sess, int focus) { char buf[512]; - sess->gui = malloc (4); current_sess = sess; if (!sess->server->front_session) @@ -92,13 +93,11 @@ fe_new_window (struct session *sess, int focus) return; done_intro = 1; - snprintf (buf, sizeof (buf), + g_snprintf (buf, sizeof (buf), "\n" " \017HexChat-Text \00310"PACKAGE_VERSION"\n" - " \017Running on \00310%s \017glib \00310%d.%d.%d\n" - " \017This binary compiled \00310"__DATE__"\017\n", - get_sys_str (1), - glib_major_version, glib_minor_version, glib_micro_version); + " \017Running on \00310%s\n", + get_sys_str (1)); fe_print_text (sess, buf, 0, FALSE); fe_print_text (sess, "\n\nCompiled in Features\0032:\017 " @@ -111,9 +110,6 @@ fe_new_window (struct session *sess, int focus) #ifdef USE_OPENSSL "OpenSSL " #endif -#ifdef USE_IPV6 - "IPv6" -#endif "\n\n", 0, FALSE); fflush (stdout); } @@ -140,7 +136,7 @@ timecat (char *buf, time_t stamp) /* Windows doesn't handle ANSI codes in cmd.exe, need to not display them */ #ifndef WIN32 -/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ +/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ static const short colconv[] = { 0, 7, 4, 2, 1, 3, 5, 11, 13, 12, 6, 16, 14, 15, 10, 7 }; void @@ -151,7 +147,7 @@ fe_print_text (struct session *sess, char *text, time_t stamp, char num[8]; int reverse = 0, under = 0, bold = 0, comma, k, i = 0, j = 0, len = strlen (text); - unsigned char *newtext = malloc (len + 1024); + unsigned char *newtext = g_malloc (len + 1024); if (prefs.hex_stamp_text) { @@ -207,7 +203,7 @@ fe_print_text (struct session *sess, char *text, time_t stamp, else col = 30; mirc = atoi (num); - mirc = colconv[mirc]; + mirc = colconv[mirc % G_N_ELEMENTS(colconv)]; if (mirc > 9) { mirc += 50; @@ -308,7 +304,7 @@ fe_print_text (struct session *sess, char *text, time_t stamp, newtext[j] = 0; write (STDOUT_FILENO, newtext, j); - free (newtext); + g_free (newtext); } #else /* The win32 version for cmd.exe */ @@ -319,7 +315,7 @@ fe_print_text (struct session *sess, char *text, time_t stamp, int dotime = FALSE; int comma, k, i = 0, j = 0, len = strlen (text); - unsigned char *newtext = malloc (len + 1024); + unsigned char *newtext = g_malloc (len + 1024); if (prefs.hex_stamp_text) { @@ -403,7 +399,7 @@ fe_print_text (struct session *sess, char *text, time_t stamp, newtext[j] = 0; write (STDOUT_FILENO, newtext, j); - free (newtext); + g_free (newtext); } #endif @@ -508,14 +504,14 @@ fe_args (int argc, char *argv[]) { #ifdef WIN32 /* see the chdir() below */ - char *sl, *exe = strdup (argv[0]); + char *sl, *exe = g_strdup (argv[0]); sl = strrchr (exe, '\\'); if (sl) { *sl = 0; printf ("%s\\plugins\n", exe); } - free (exe); + g_free (exe); #else printf ("%s\n", HEXCHATLIBDIR); #endif @@ -530,8 +526,7 @@ fe_args (int argc, char *argv[]) if (arg_cfgdir) /* we want filesystem encoding */ { - if (xdir) - g_free (xdir); + g_free (xdir); xdir = strdup (arg_cfgdir); if (xdir[strlen (xdir) - 1] == '/') xdir[strlen (xdir) - 1] = 0; @@ -583,7 +578,6 @@ fe_exit (void) void fe_new_server (struct server *serv) { - serv->gui = malloc (4); } void @@ -682,7 +676,7 @@ fe_progressbar_end (struct server *serv) { } void -fe_userlist_insert (struct session *sess, struct User *newuser, int row, int sel) +fe_userlist_insert (struct session *sess, struct User *newuser, gboolean sel) { } int @@ -695,10 +689,6 @@ fe_userlist_rehash (struct session *sess, struct User *user) { } void -fe_userlist_move (struct session *sess, struct User *user, int new_row) -{ -} -void fe_userlist_numbers (struct session *sess) { } @@ -910,7 +900,6 @@ void fe_tray_set_flash (const char *filename1, const char *filename2, int timeou void fe_tray_set_file (const char *filename){} void fe_tray_set_icon (feicon icon){} void fe_tray_set_tooltip (const char *text){} -void fe_tray_set_balloon (const char *title, const char *text){} void fe_userlist_update (session *sess, struct User *user){} void fe_open_chan_list (server *serv, char *filter, int do_refresh) diff --git a/src/fe-text/fe-text.vcxproj b/src/fe-text/fe-text.vcxproj index c59c57bc..1da7e733 100644 --- a/src/fe-text/fe-text.vcxproj +++ b/src/fe-text/fe-text.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -19,77 +20,38 @@ <RootNamespace>fetext</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\..\win32\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <LinkIncremental>false</LinkIncremental> - <TargetName>hexchat-text</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <LinkIncremental>false</LinkIncremental> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\..\win32\hexchat.props" /> + <PropertyGroup> <TargetName>hexchat-text</TargetName> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <OutDir>$(HexChatRel)</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(SolutionDir)..;$(DepsRoot)\include;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>$(HexChatLib);$(DepsRoot)\include;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> <SubSystem>Console</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> - <AdditionalDependencies>$(DepLibs);"$(OutDir)\common.lib";%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>$(DepLibs);$(HexChatLib)common.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ClCompile> - <PrecompiledHeader> - </PrecompiledHeader> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_CONSOLE;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions> - <AdditionalIncludeDirectories>$(SolutionDir)..;$(DepsRoot)\include;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> - <MultiProcessorCompilation>true</MultiProcessorCompilation> + <AdditionalIncludeDirectories>$(HexChatLib);$(DepsRoot)\include;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> </ClCompile> <Link> <SubSystem>Console</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <EnableCOMDATFolding>true</EnableCOMDATFolding> <OptimizeReferences>true</OptimizeReferences> - <AdditionalDependencies>$(DepLibs);"$(OutDir)\common.lib";%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>$(DepLibs);$(HexChatLib)common.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> </Link> </ItemDefinitionGroup> @@ -100,6 +62,4 @@ <ClCompile Include="fe-text.c" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/src/htm/htm.csproj b/src/htm/htm.csproj index eea953d2..d56f2188 100644 --- a/src/htm/htm.csproj +++ b/src/htm/htm.csproj @@ -61,22 +61,13 @@ </PropertyGroup> <PropertyGroup /> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> + <PlatformTarget>x64</PlatformTarget> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> <OutputPath>..\..\..\hexchat-build\x64\bin\</OutputPath> <DefineConstants>TRACE</DefineConstants> - <Optimize>true</Optimize> - <DebugType>pdbonly</DebugType> - <PlatformTarget>x64</PlatformTarget> - <CodeAnalysisLogFile>bin\Release\thememan.exe.CodeAnalysisLog.xml</CodeAnalysisLogFile> - <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression> - <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile> <ErrorReport>prompt</ErrorReport> <CodeAnalysisIgnoreGeneratedCode>false</CodeAnalysisIgnoreGeneratedCode> - <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet> - <CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories> - <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets> - <CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories> - <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules> - <CodeAnalysisFailOnMissingRules>false</CodeAnalysisFailOnMissingRules> </PropertyGroup> <ItemGroup> <Reference Include="System" /> diff --git a/src/libenchant_win8/libenchant_win8.def b/src/libenchant_win8/libenchant_win8.def new file mode 100644 index 00000000..cf367651 --- /dev/null +++ b/src/libenchant_win8/libenchant_win8.def @@ -0,0 +1,2 @@ +EXPORTS +init_enchant_provider diff --git a/src/libenchant_win8/libenchant_win8.vcxproj b/src/libenchant_win8/libenchant_win8.vcxproj new file mode 100644 index 00000000..aab7acc8 --- /dev/null +++ b/src/libenchant_win8/libenchant_win8.vcxproj @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{BF0EBC16-68AD-4CD1-864C-5B56836EBE2A}</ProjectGuid> + <Keyword>Win32Proj</Keyword> + <RootNamespace>libenchant_win8</RootNamespace> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <Import Project="..\..\win32\hexchat.props" /> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup> + <OutDir>$(HexChatRel)lib\enchant\</OutDir> + <TargetName>libenchant_win8</TargetName> + </PropertyGroup> + <ItemDefinitionGroup> + <ClCompile> + <AdditionalIncludeDirectories>..\common;$(HexChatLib);$(DepsRoot)\include\enchant;$(DepsRoot)\include;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> + </ClCompile> + <Link> + <AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> + <ModuleDefinitionFile>libenchant_win8.def</ModuleDefinitionFile> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="win8_provider.cpp" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> +</Project> diff --git a/src/libenchant_win8/libenchant_win8.vcxproj.filters b/src/libenchant_win8/libenchant_win8.vcxproj.filters new file mode 100644 index 00000000..ff2f3024 --- /dev/null +++ b/src/libenchant_win8/libenchant_win8.vcxproj.filters @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="win8_provider.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> +</Project> diff --git a/src/libenchant_win8/win8_provider.cpp b/src/libenchant_win8/win8_provider.cpp new file mode 100644 index 00000000..73f16610 --- /dev/null +++ b/src/libenchant_win8/win8_provider.cpp @@ -0,0 +1,293 @@ +/* HexChat + * Copyright (c) 2015 Patrick Griffis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "config.h" + +#include <Spellcheck.h> +#include <glib.h> + +#include "typedef.h" // for ssize_t +#include <enchant-provider.h> + +ENCHANT_PLUGIN_DECLARE ("win8") + +/* --------- Utils ----------*/ + +static char * +utf16_to_utf8 (const wchar_t * const str, gboolean from_bcp47) +{ + char *utf8 = g_utf16_to_utf8 ((gunichar2*)str, -1, nullptr, nullptr, nullptr); + if (utf8 && from_bcp47) + { + char *p = utf8; + /* bcp47 tags use syntax "en-US" while the myspell versions are "en_US" */ + while (*p) + { + if (*p == '-') + *p = '_'; + p++; + } + } + return utf8; +} + +static wchar_t * +utf8_to_utf16 (const char * const str, size_t len, gboolean to_bcp47) +{ + wchar_t *utf16 = (wchar_t*)g_utf8_to_utf16 (str, len, nullptr, nullptr, nullptr); + if (utf16 && to_bcp47) + { + wchar_t *p = utf16; + /* bcp47 tags use syntax "en-US" while the myspell versions are "en_US" */ + while (*p) + { + if (*p == L'_') + *p = L'-'; + p++; + } + } + return utf16; +} + +static char ** +enumstring_to_chararray (IEnumString *strings, size_t *out_len, gboolean from_bcp47) +{ + char **chars = g_new (char*, 256); /* Hopefully large enough */ + LPOLESTR wstr = nullptr; + size_t i = 0; + + while (SUCCEEDED (strings->Next (1, &wstr, nullptr)) && i < 256 && wstr) + { + char *str = utf16_to_utf8 (wstr, from_bcp47); + if (str) + { + chars[i] = str; + i++; + } + CoTaskMemFree (wstr); + } + chars[i] = nullptr; + strings->Release (); + + *out_len = i; + return chars; +} + +/* ---------- Dict ------------ */ + +static void +win8_dict_add_to_personal (EnchantDict *dict, const char *const word, size_t len) +{ + auto checker = static_cast<ISpellChecker*>(dict->user_data); + wchar_t *wword = utf8_to_utf16 (word, len, FALSE); + + checker->Add (wword); + g_free (wword); +} + +static void +win8_dict_add_to_session (EnchantDict *dict, const char *const word, size_t len) +{ + auto checker = static_cast<ISpellChecker*>(dict->user_data); + wchar_t *wword = utf8_to_utf16 (word, len, FALSE); + + checker->Ignore (wword); + g_free (wword); +} + +static int +win8_dict_check (EnchantDict *dict, const char *const word, size_t len) +{ + auto checker = static_cast<ISpellChecker*>(dict->user_data); + wchar_t *wword = utf8_to_utf16 (word, len, FALSE); + IEnumSpellingError *errors; + ISpellingError *error = nullptr; + HRESULT hr; + + hr = checker->Check (wword, &errors); + g_free (wword); + + if (FAILED (hr)) + return -1; /* Error */ + + if (errors->Next (&error) == S_OK) + { + error->Release (); + errors->Release (); + return 1; /* Spelling Issue */ + } + else + { + errors->Release (); + return 0; /* Correct */ + } +} + +static char ** +win8_dict_suggest (EnchantDict *dict, const char *const word, size_t len, size_t *out_n_suggs) +{ + auto checker = static_cast<ISpellChecker*>(dict->user_data); + wchar_t *wword = utf8_to_utf16 (word, len, FALSE); + IEnumString *suggestions; + HRESULT hr; + + hr = checker->Suggest (wword, &suggestions); + g_free (wword); + + if (FAILED (hr)) + { + *out_n_suggs = 0; + return nullptr; + } + + return enumstring_to_chararray (suggestions, out_n_suggs, FALSE); +} + +/* ---------- Provider ------------ */ + +static EnchantDict * +win8_provider_request_dict (EnchantProvider *provider, const char *const tag) +{ + auto factory = static_cast<ISpellCheckerFactory*>(provider->user_data); + ISpellChecker *checker; + EnchantDict *dict; + wchar_t *wtag = utf8_to_utf16 (tag, -1, TRUE); + HRESULT hr; + + hr = factory->CreateSpellChecker (wtag, &checker); + g_free (wtag); + + if (FAILED (hr)) + return nullptr; + + dict = g_new0 (EnchantDict, 1); + dict->suggest = win8_dict_suggest; + dict->check = win8_dict_check; + dict->add_to_personal = win8_dict_add_to_personal; + dict->add_to_exclude = win8_dict_add_to_personal; /* Basically the same */ + dict->add_to_session = win8_dict_add_to_session; + + dict->user_data = checker; + + return dict; +} + +static void +win8_provider_dispose_dict (EnchantProvider *provider, EnchantDict *dict) +{ + if (dict) + { + auto checker = static_cast<ISpellChecker*>(dict->user_data); + + checker->Release (); + g_free (dict); + } +} + +static int +win8_provider_dictionary_exists (EnchantProvider *provider, const char *const tag) +{ + auto factory = static_cast<ISpellCheckerFactory*>(provider->user_data); + wchar_t *wtag = utf8_to_utf16 (tag, -1, TRUE); + + BOOL is_supported = FALSE; + factory->IsSupported (wtag, &is_supported); + + g_free (wtag); + return is_supported; +} + + +static char ** +win8_provider_list_dicts (EnchantProvider *provider, size_t *out_n_dicts) +{ + auto factory = static_cast<ISpellCheckerFactory*>(provider->user_data); + IEnumString *dicts; + + if (FAILED(factory->get_SupportedLanguages (&dicts))) + { + *out_n_dicts = 0; + return nullptr; + } + + return enumstring_to_chararray (dicts, out_n_dicts, TRUE); +} + +static void +win8_provider_free_string_list (EnchantProvider *provider, char **str_list) +{ + g_strfreev (str_list); +} + +static void +win8_provider_dispose (EnchantProvider *provider) +{ + if (provider) + { + auto factory = static_cast<ISpellCheckerFactory*>(provider->user_data); + + factory->Release(); + g_free (provider); + } +} + +static const char * +win8_provider_identify (EnchantProvider *provider) +{ + return "win8"; +} + +static const char * +win8_provider_describe (EnchantProvider *provider) +{ + return "Windows 8 SpellCheck Provider"; +} + +extern "C" +{ + +EnchantProvider * +init_enchant_provider (void) +{ + EnchantProvider *provider; + ISpellCheckerFactory *factory; + + if (FAILED (CoCreateInstance (__uuidof(SpellCheckerFactory), nullptr, + CLSCTX_INPROC_SERVER, IID_PPV_ARGS (&factory)))) + return nullptr; + + provider = g_new0 (EnchantProvider, 1); + provider->dispose = win8_provider_dispose; + provider->request_dict = win8_provider_request_dict; + provider->dispose_dict = win8_provider_dispose_dict; + provider->dictionary_exists = win8_provider_dictionary_exists; + provider->identify = win8_provider_identify; + provider->describe = win8_provider_describe; + provider->list_dicts = win8_provider_list_dicts; + provider->free_string_list = win8_provider_free_string_list; + + provider->user_data = factory; + + return provider; +} + +} diff --git a/win32/config.h.tt b/win32/config.h.tt index 77da3b38..ad518964 100644 --- a/win32/config.h.tt +++ b/win32/config.h.tt @@ -2,7 +2,6 @@ #define ENABLE_NLS #define USE_PLUGIN #define USE_OPENSSL -#define USE_IPV6 #define HAVE_ISO_CODES #define ISO_CODES_PREFIX ".\\" #define ISO_CODES_LOCALEDIR LOCALEDIR @@ -13,6 +12,3 @@ #define OLD_PERL #define GETTEXT_PACKAGE "hexchat" #define PACKAGE_TARNAME "hexchat-<#= [string]::Join('.', $versionParts) #>" -#ifndef USE_IPV6 -#define socklen_t int -#endif diff --git a/win32/copy/copy.vcxproj b/win32/copy/copy.vcxproj index d0c1150b..557ca702 100644 --- a/win32/copy/copy.vcxproj +++ b/win32/copy/copy.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -18,73 +19,65 @@ <RootNamespace>copy</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - </ClCompile> - <Link> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - </Link> - <PreBuildEvent> - <Command>$(HexChatCopy)</Command> - </PreBuildEvent> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - </ClCompile> - <Link> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - </Link> - <PreBuildEvent> - <Command>$(HexChatCopy)</Command> - </PreBuildEvent> - </ItemDefinitionGroup> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\hexchat.props" /> <ItemGroup> + <None Include="$(DepsRoot)\bin\cert.pem" /> + <None Include="$(DepsRoot)\bin\atk-1.0.dll" /> + <None Include="$(DepsRoot)\bin\cairo.dll" /> + <None Include="$(DepsRoot)\bin\fontconfig.dll" /> + <None Include="$(DepsRoot)\bin\gdk_pixbuf-2.0.dll" /> + <None Include="$(DepsRoot)\bin\gdk-win32-2.0.dll" /> + <None Include="$(DepsRoot)\bin\gio-2.0.dll" /> + <None Include="$(DepsRoot)\bin\glib-2.0.dll" /> + <None Include="$(DepsRoot)\bin\gmodule-2.0.dll" /> + <None Include="$(DepsRoot)\bin\gobject-2.0.dll" /> + <None Include="$(DepsRoot)\bin\gspawn-win$(PlatformArchitecture)-helper.exe" /> + <None Include="$(DepsRoot)\bin\gspawn-win$(PlatformArchitecture)-helper-console.exe" /> + <None Include="$(DepsRoot)\bin\gthread-2.0.dll" /> + <None Include="$(DepsRoot)\bin\gtk-win32-2.0.dll" /> + <None Include="$(DepsRoot)\bin\harfbuzz.dll" /> + <None Include="$(DepsRoot)\bin\iconv.dll" /> + <None Include="$(DepsRoot)\bin\libeay32.dll" /> + <None Include="$(DepsRoot)\bin\libenchant.dll" /> + <None Include="$(DepsRoot)\bin\libintl.dll" /> + <None Include="$(DepsRoot)\bin\libpng16.dll" /> + <None Include="$(DepsRoot)\bin\libxml2.dll" /> + <None Include="$(DepsRoot)\bin\pango-1.0.dll" /> + <None Include="$(DepsRoot)\bin\pangocairo-1.0.dll" /> + <None Include="$(DepsRoot)\bin\pangoft2-1.0.dll" /> + <None Include="$(DepsRoot)\bin\pangowin32-1.0.dll" /> + <None Include="$(DepsRoot)\bin\pixman-1.dll" /> + <None Include="$(DepsRoot)\bin\ssleay32.dll" /> + <None Include="$(DepsRoot)\bin\zlib1.dll" /> + <None Include="$(WinSparklePath)\WinSparkle.dll" /> + <None Include="$(HexChatBin)thememan.exe" /> <None Include="changelog.url" /> <None Include="readme.url" /> - <None Include="share\xml\iso-codes\iso_3166.xml" /> - <None Include="share\xml\iso-codes\iso_639.xml" /> + + <Engines Include="$(DepsRoot)\lib\gtk-2.0\i686-pc-vs10\engines\**\*" /> + + <Share Include="share\**\*" /> + + <DepsRootDocs Include="$(DepsRoot)\share\doc\**\*" /> + + <Locale Include="$(HexChatBin)locale\**\*;$(DepsRoot)\share\locale\**\*" /> + + <MSWindowsTheme Include="$(DepsRoot)\share\themes\MS-Windows\**\*" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file + <Target Name="Build"> + <Copy SourceFiles="@(None)" DestinationFolder="$(HexChatRel)" /> + <Copy SourceFiles="@(Engines)" DestinationFiles="@(Engines->'$(HexChatRel)\lib\gtk-2.0\i686-pc-vs10\engines\%(RecursiveDir)%(Filename)%(Extension)')" /> + <Copy SourceFiles="@(Share)" DestinationFiles="@(Share->'$(HexChatRel)\share\%(RecursiveDir)%(Filename)%(Extension)')" /> + <Copy SourceFiles="@(DepsRootDocs)" DestinationFiles="@(DepsRootDocs->'$(HexChatRel)\share\doc\%(RecursiveDir)%(Filename)%(Extension)')" /> + <Copy SourceFiles="..\..\COPYING" DestinationFolder="$(HexChatRel)\share\doc\hexchat" /> + <Copy SourceFiles="$(WinSparklePath)\COPYING" DestinationFolder="$(HexChatRel)\share\doc\WinSparkle" /> + <Copy SourceFiles="$(DepsRoot)\lib\enchant\libenchant_myspell.dll" DestinationFolder="$(HexChatRel)\lib\enchant" /> + <Copy SourceFiles="@(Locale)" DestinationFiles="@(Locale->'$(HexChatRel)\share\locale\%(RecursiveDir)%(Filename)%(Extension)')" /> + <Copy SourceFiles="@(MSWindowsTheme)" DestinationFiles="@(MSWindowsTheme->'$(HexChatRel)\share\themes\MS-Windows\%(RecursiveDir)%(Filename)%(Extension)')" /> + + <WriteLinesToFile File="$(HexChatRel)portable-mode" Lines="2" Overwrite="true" /> + </Target> +</Project> diff --git a/win32/copy/copy.vcxproj.filters b/win32/copy/copy.vcxproj.filters index af2be024..695b5c78 100644 --- a/win32/copy/copy.vcxproj.filters +++ b/win32/copy/copy.vcxproj.filters @@ -1,52 +1,3 @@ <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ItemGroup> - <Filter Include="Resource Files"> - <UniqueIdentifier>{e02a8c67-767c-4c6e-a854-81fae08cf4da}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files\etc"> - <UniqueIdentifier>{503881c0-011d-443b-a373-4bfe125dcfa6}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files\share"> - <UniqueIdentifier>{4316433a-2a8e-48f7-9020-e1f4de0d23d1}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files\etc\gtk-2.0"> - <UniqueIdentifier>{832ebebc-ab71-4bf6-9f3a-02ec748f7c14}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files\share\xml"> - <UniqueIdentifier>{9a881586-aed2-4f80-ba84-e521e6785566}</UniqueIdentifier> - </Filter> - <Filter Include="Resource Files\share\xml\iso-codes"> - <UniqueIdentifier>{c825f724-0618-4160-97b7-12d6e0f2bc7b}</UniqueIdentifier> - </Filter> - </ItemGroup> - <ItemGroup> - <None Include="etc\download.png"> - <Filter>Resource Files\etc</Filter> - </None> - <None Include="etc\gtkpref.png"> - <Filter>Resource Files\etc</Filter> - </None> - <None Include="etc\music.png"> - <Filter>Resource Files\etc</Filter> - </None> - <None Include="etc\system.png"> - <Filter>Resource Files\etc</Filter> - </None> - <None Include="etc\gtk-2.0\gtkrc"> - <Filter>Resource Files\etc\gtk-2.0</Filter> - </None> - <None Include="share\xml\iso-codes\iso_639.xml"> - <Filter>Resource Files\share\xml\iso-codes</Filter> - </None> - <None Include="share\xml\iso-codes\iso_3166.xml"> - <Filter>Resource Files\share\xml\iso-codes</Filter> - </None> - <None Include="readme.url"> - <Filter>Resource Files</Filter> - </None> - <None Include="changelog.url"> - <Filter>Resource Files</Filter> - </None> - </ItemGroup> </Project> \ No newline at end of file diff --git a/win32/ext/nss-wdk/build-x64.bat b/win32/ext/nss-wdk/build-x64.bat deleted file mode 100644 index 96bb0422..00000000 --- a/win32/ext/nss-wdk/build-x64.bat +++ /dev/null @@ -1,13 +0,0 @@ -@echo off -set WDK_ROOT=c:\WinDDK\7600.16385.1 -set INCLUDE=%WDK_ROOT%\inc\api;%WDK_ROOT%\inc\crt;%WDK_ROOT%\inc\ddk -set LIB=%WDK_ROOT%\lib\wnet\amd64;%WDK_ROOT%\lib\Crt\amd64 -set PATH=%PROGRAMFILES(X86)%\Microsoft Visual Studio 10.0\VC\bin\amd64;%PROGRAMFILES(X86)%\Microsoft SDKs\Windows\v7.0A\Bin\x64;c:\mozilla-build\msys\bin;c:\mozilla-build\moztools-x64\bin -set BUILD_OPT=1 -set USE_64=1 -set WINDDK_BUILD=1 -cd mozilla\security\nss -make nss_build_all -cd ..\..\.. -echo.Finished! -pause diff --git a/win32/ext/nss-wdk/build-x86.bat b/win32/ext/nss-wdk/build-x86.bat deleted file mode 100644 index c6d4868e..00000000 --- a/win32/ext/nss-wdk/build-x86.bat +++ /dev/null @@ -1,13 +0,0 @@ -@echo off -set WDK_ROOT=c:\WinDDK\7600.16385.1 -set INCLUDE=%WDK_ROOT%\inc\api;%WDK_ROOT%\inc\crt -set LIB=%WDK_ROOT%\lib\wxp\i386;%WDK_ROOT%\lib\Crt\i386 -set PATH=%PROGRAMFILES(X86)%\Microsoft Visual Studio 10.0\VC\bin;%PROGRAMFILES(X86)%\Microsoft Visual Studio 10.0\Common7\IDE;%PROGRAMFILES(X86)%\Microsoft SDKs\Windows\v7.0A\Bin;c:\mozilla-build\msys\bin;c:\mozilla-build\moztools\bin -set BUILD_OPT=1 -set USE_64= -set WINDDK_BUILD=1 -cd mozilla\security\nss -make nss_build_all -cd ..\..\.. -echo.Finished! -pause diff --git a/win32/ext/nss-wdk/nss-wdk.patch b/win32/ext/nss-wdk/nss-wdk.patch deleted file mode 100644 index 7d663491..00000000 --- a/win32/ext/nss-wdk/nss-wdk.patch +++ /dev/null @@ -1,257 +0,0 @@ -diff -ruN --strip-trailing-cr nss-3.13.6.orig/mozilla/dbm/include/mcom_db.h nss-3.13.6/mozilla/dbm/include/mcom_db.h ---- nss-3.13.6.orig/mozilla/dbm/include/mcom_db.h 2009-06-05 01:18:50 +0200 -+++ nss-3.13.6/mozilla/dbm/include/mcom_db.h 2012-10-06 00:54:22 +0200 -@@ -40,6 +40,15 @@ - #define off_t long - #endif - -+#ifdef WINDDK_BUILD -+#ifndef stat -+#define stat _stat -+#endif -+#ifndef getpid -+#define getpid GetCurrentProcessId -+#endif -+#endif -+ - #ifndef macintosh - #include <sys/types.h> - #endif -diff -ruN --strip-trailing-cr nss-3.13.6.orig/mozilla/dbm/src/mktemp.c nss-3.13.6/mozilla/dbm/src/mktemp.c ---- nss-3.13.6.orig/mozilla/dbm/src/mktemp.c 2009-06-05 01:19:31 +0200 -+++ nss-3.13.6/mozilla/dbm/src/mktemp.c 2012-10-06 00:54:22 +0200 -@@ -45,13 +45,13 @@ - #include <ctype.h> - #include "mcom_db.h" - --#ifndef _WINDOWS --#include <unistd.h> --#endif -- - #ifdef _WINDOWS -+#ifndef WINDDK_BUILD - #include <process.h> -+#endif - #include "winfile.h" -+#else -+#include <unistd.h> - #endif - - static int _gettemp(char *path, register int *doopen, int extraFlags); -diff -ruN --strip-trailing-cr nss-3.13.6.orig/mozilla/nsprpub/config/config.mk nss-3.13.6/mozilla/nsprpub/config/config.mk ---- nss-3.13.6.orig/mozilla/nsprpub/config/config.mk 2012-03-06 14:13:38 +0100 -+++ nss-3.13.6/mozilla/nsprpub/config/config.mk 2012-10-06 00:54:22 +0200 -@@ -132,6 +132,15 @@ - DEFINES += -DMOZ_UNICODE - endif - -+ifdef WINDDK_BUILD -+OS_CFLAGS += -DWINDDK_BUILD -+ifdef USE_64 -+OS_LIBS += msvcrt_win2003.obj -+else -+OS_LIBS += msvcrt_winxp.obj -+endif -+endif -+ - #################################################################### - # - # Configuration for the release process -diff -ruN --strip-trailing-cr nss-3.13.6.orig/mozilla/nsprpub/pr/src/Makefile.in nss-3.13.6/mozilla/nsprpub/pr/src/Makefile.in ---- nss-3.13.6.orig/mozilla/nsprpub/pr/src/Makefile.in 2012-03-06 14:13:59 +0100 -+++ nss-3.13.6/mozilla/nsprpub/pr/src/Makefile.in 2012-10-06 00:54:22 +0200 -@@ -170,9 +170,17 @@ - ifdef NS_USE_GCC - OS_LIBS = -ladvapi32 -lwsock32 -lwinmm - else -+ifdef WINDDK_BUILD -+ifdef USE_64 -+OS_LIBS = advapi32.lib wsock32.lib winmm.lib msvcrt_win2003.obj -+else -+OS_LIBS = advapi32.lib wsock32.lib winmm.lib msvcrt_winxp.obj -+endif -+else - OS_LIBS = advapi32.lib wsock32.lib winmm.lib - endif - endif -+endif - - ifeq ($(OS_ARCH),WINCE) - OS_LIBS = ws2.lib -diff -ruN --strip-trailing-cr nss-3.13.6.orig/mozilla/nsprpub/pr/src/md/windows/ntmisc.c nss-3.13.6/mozilla/nsprpub/pr/src/md/windows/ntmisc.c ---- nss-3.13.6.orig/mozilla/nsprpub/pr/src/md/windows/ntmisc.c 2012-03-06 14:14:17 +0100 -+++ nss-3.13.6/mozilla/nsprpub/pr/src/md/windows/ntmisc.c 2012-10-06 00:54:22 +0200 -@@ -593,7 +593,11 @@ - */ - hasFdInheritBuffer = (attr && attr->fdInheritBuffer); - if ((envp == NULL) && hasFdInheritBuffer) { -+#ifdef WINDDK_BUILD -+ envp = getenv; -+#else - envp = environ; -+#endif - } - - if (envp != NULL) { -diff -ruN --strip-trailing-cr nss-3.13.6.orig/mozilla/security/coreconf/WIN32.mk nss-3.13.6/mozilla/security/coreconf/WIN32.mk ---- nss-3.13.6.orig/mozilla/security/coreconf/WIN32.mk 2011-09-14 19:59:43 +0200 -+++ nss-3.13.6/mozilla/security/coreconf/WIN32.mk 2012-10-06 00:54:22 +0200 -@@ -146,6 +146,14 @@ - OS_CFLAGS += -W3 -nologo -D_CRT_SECURE_NO_WARNINGS \ - -D_CRT_NONSTDC_NO_WARNINGS - OS_DLLFLAGS += -nologo -DLL -SUBSYSTEM:WINDOWS -+ ifdef WINDDK_BUILD -+ OS_CFLAGS += -DWINDDK_BUILD -+ ifdef USE_64 -+ OS_LIBS += msvcrt_win2003.obj -+ else -+ OS_LIBS += msvcrt_winxp.obj -+ endif -+ endif - ifeq ($(_MSC_VER),$(_MSC_VER_6)) - ifndef MOZ_DEBUG_SYMBOLS - OS_DLLFLAGS += -PDB:NONE -diff -ruN --strip-trailing-cr nss-3.13.6.orig/mozilla/security/coreconf/arch.mk nss-3.13.6/mozilla/security/coreconf/arch.mk ---- nss-3.13.6.orig/mozilla/security/coreconf/arch.mk 2009-06-05 04:14:49 +0200 -+++ nss-3.13.6/mozilla/security/coreconf/arch.mk 2012-10-06 00:54:22 +0200 -@@ -268,7 +268,15 @@ - # the uname.exe in the MSYS toolkit. - # - ifeq (MINGW32_NT,$(findstring MINGW32_NT,$(OS_ARCH))) -- OS_RELEASE := $(patsubst MINGW32_NT-%,%,$(OS_ARCH)) -+ ifdef WINDDK_BUILD -+ ifdef USE_64 -+ OS_RELEASE := 5.2 -+ else -+ OS_RELEASE := 5.1 -+ endif -+ else -+ OS_RELEASE := $(patsubst MINGW32_NT-%,%,$(OS_ARCH)) -+ endif - OS_ARCH = WINNT - USE_MSYS = 1 - ifndef CPU_ARCH -diff -ruN --strip-trailing-cr nss-3.13.6.orig/mozilla/security/nss/cmd/platlibs.mk nss-3.13.6/mozilla/security/nss/cmd/platlibs.mk ---- nss-3.13.6.orig/mozilla/security/nss/cmd/platlibs.mk 2010-06-12 02:58:33 +0200 -+++ nss-3.13.6/mozilla/security/nss/cmd/platlibs.mk 2012-10-06 00:54:22 +0200 -@@ -249,3 +249,11 @@ - endif - - JAR_LIBS = $(DIST)/lib/$(LIB_PREFIX)jar.$(LIB_SUFFIX) -+ -+ifdef WINDDK_BUILD -+ifdef USE_64 -+OS_LIBS += msvcrt_win2003.obj -+else -+OS_LIBS += msvcrt_winxp.obj -+endif -+endif -diff -ruN --strip-trailing-cr nss-3.13.6.orig/mozilla/security/nss/cmd/selfserv/selfserv.c nss-3.13.6/mozilla/security/nss/cmd/selfserv/selfserv.c ---- nss-3.13.6.orig/mozilla/security/nss/cmd/selfserv/selfserv.c 2012-03-01 19:38:24 +0100 -+++ nss-3.13.6/mozilla/security/nss/cmd/selfserv/selfserv.c 2012-10-06 00:54:22 +0200 -@@ -51,8 +51,13 @@ - #endif - - #if defined(_WINDOWS) -+#ifdef WINDDK_BUILD -+#include <windows.h> -+#define getpid GetCurrentProcessId -+#else - #include <process.h> /* for getpid() */ - #endif -+#endif - - #include <signal.h> - #include <stdlib.h> -diff -ruN --strip-trailing-cr nss-3.13.6.orig/mozilla/security/nss/lib/freebl/mpi/mpcpucache.c nss-3.13.6/mozilla/security/nss/lib/freebl/mpi/mpcpucache.c ---- nss-3.13.6.orig/mozilla/security/nss/lib/freebl/mpi/mpcpucache.c 2011-09-30 18:07:16 +0200 -+++ nss-3.13.6/mozilla/security/nss/lib/freebl/mpi/mpcpucache.c 2012-10-06 00:54:22 +0200 -@@ -80,7 +80,11 @@ - - #elif defined(_MSC_VER) - -+#ifdef WINDDK_BUILD -+#include <ntddk.h> -+#else - #include <intrin.h> -+#endif - - void freebl_cpuid(unsigned long op, unsigned long *eax, - unsigned long *ebx, unsigned long *ecx, -diff -ruN --strip-trailing-cr nss-3.13.6.orig/mozilla/security/nss/lib/freebl/win_rand.c nss-3.13.6/mozilla/security/nss/lib/freebl/win_rand.c ---- nss-3.13.6.orig/mozilla/security/nss/lib/freebl/win_rand.c 2011-01-06 20:00:52 +0100 -+++ nss-3.13.6/mozilla/security/nss/lib/freebl/win_rand.c 2012-10-06 00:54:22 +0200 -@@ -50,6 +50,13 @@ - #include <sys/types.h> - #include <sys/stat.h> - #endif -+ -+#ifdef WINDDK_BUILD -+#ifndef stat -+#define stat _stat -+#endif -+#endif -+ - #include <stdio.h> - #include "prio.h" - #include "prerror.h" -diff -ruN --strip-trailing-cr nss-3.13.6.orig/mozilla/security/nss/lib/softoken/legacydb/config.mk nss-3.13.6/mozilla/security/nss/lib/softoken/legacydb/config.mk ---- nss-3.13.6.orig/mozilla/security/nss/lib/softoken/legacydb/config.mk 2011-11-06 00:01:08 +0100 -+++ nss-3.13.6/mozilla/security/nss/lib/softoken/legacydb/config.mk 2012-10-06 00:54:22 +0200 -@@ -95,3 +95,11 @@ - ifeq ($(OS_TARGET),WINCE) - DEFINES += -DDBM_USING_NSPR - endif -+ -+ifdef WINDDK_BUILD -+ifdef USE_64 -+OS_LIBS += msvcrt_win2003.obj -+else -+OS_LIBS += msvcrt_winxp.obj -+endif -+endif -diff -ruN --strip-trailing-cr nss-3.13.6.orig/mozilla/security/nss/lib/sqlite/sqlite3.c nss-3.13.6/mozilla/security/nss/lib/sqlite/sqlite3.c ---- nss-3.13.6.orig/mozilla/security/nss/lib/sqlite/sqlite3.c 2010-01-08 06:42:38 +0100 -+++ nss-3.13.6/mozilla/security/nss/lib/sqlite/sqlite3.c 2012-10-06 00:54:22 +0200 -@@ -10980,7 +10980,8 @@ - ** localtime_s(). - */ - #if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \ -- defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) -+ defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE) && \ -+ !defined(WINDDK_BUILD) - #define HAVE_LOCALTIME_S 1 - #endif - -diff -ruN --strip-trailing-cr nss-3.13.6.orig/mozilla/security/nss/lib/ssl/sslimpl.h nss-3.13.6/mozilla/security/nss/lib/ssl/sslimpl.h ---- nss-3.13.6.orig/mozilla/security/nss/lib/ssl/sslimpl.h 2012-02-15 22:52:08 +0100 -+++ nss-3.13.6/mozilla/security/nss/lib/ssl/sslimpl.h 2012-10-06 00:54:22 +0200 -@@ -1657,8 +1657,13 @@ - #elif defined(_WIN32_WCE) - #define SSL_GETPID GetCurrentProcessId - #elif defined(WIN32) -+#ifdef WINDDK_BUILD -+#include <windows.h> -+#define SSL_GETPID GetCurrentProcessId -+#else - extern int __cdecl _getpid(void); - #define SSL_GETPID _getpid -+#endif - #else - #define SSL_GETPID() 0 - #endif -diff -ruN --strip-trailing-cr nss-3.13.6.orig/mozilla/security/nss/lib/zlib/config.mk nss-3.13.6/mozilla/security/nss/lib/zlib/config.mk ---- nss-3.13.6.orig/mozilla/security/nss/lib/zlib/config.mk 2009-11-07 02:13:10 +0100 -+++ nss-3.13.6/mozilla/security/nss/lib/zlib/config.mk 2012-10-06 00:54:22 +0200 -@@ -46,3 +46,11 @@ - PROGRAM = - - EXTRA_LIBS = $(LIBRARY) -+ -+ifdef WINDDK_BUILD -+ifdef USE_64 -+OS_LIBS += msvcrt_win2003.obj -+else -+OS_LIBS += msvcrt_winxp.obj -+endif -+endif diff --git a/src/fe-gtk/hexchat.exe.manifest b/win32/hexchat.exe.manifest index 39c4eb4c..1ea11920 100644 --- a/src/fe-gtk/hexchat.exe.manifest +++ b/win32/hexchat.exe.manifest @@ -19,4 +19,14 @@ /> </dependentAssembly> </dependency> -</assembly> + <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> + <application> + <!--This Id value indicates the application supports Windows 7 functionality--> + <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> + <!--This Id value indicates the application supports Windows 8 functionality--> + <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> + <!--This Id value indicates the application supports Windows 8.1 functionality--> + <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> + </application> + </compatibility> +</assembly> \ No newline at end of file diff --git a/win32/hexchat.props b/win32/hexchat.props index 8af53c79..b8ee2446 100644 --- a/win32/hexchat.props +++ b/win32/hexchat.props @@ -1,17 +1,16 @@ <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <ImportGroup Label="PropertySheets" /> - <PropertyGroup Label="UserMacros"> <!-- SPECIFY YOUR DEPENDENCY DIRECTORIES HERE --> - <YourDepsPath>c:\mozilla-build\hexchat\gtk</YourDepsPath> - <YourGendefPath>c:\mozilla-build\gendef</YourGendefPath> - <YourMsgfmtPath>c:\mozilla-build\msgfmt</YourMsgfmtPath> - <YourPerlPath>c:\mozilla-build\perl-5.20</YourPerlPath> - <YourPython2Path>c:\mozilla-build\python-2.7</YourPython2Path> - <YourPython3Path>c:\mozilla-build\python-3.4</YourPython3Path> + <YourDepsPath>c:\gtk-build\gtk</YourDepsPath> + <YourGendefPath>c:\gtk-build\gendef</YourGendefPath> + <YourMsgfmtPath>c:\gtk-build\msgfmt</YourMsgfmtPath> + <YourPerlPath>c:\gtk-build\perl-5.20</YourPerlPath> + <YourPython2Path>c:\gtk-build\python-2.7</YourPython2Path> + <YourPython3Path>c:\gtk-build\python-3.4</YourPython3Path> + <YourWinSparklePath>c:\gtk-build\WinSparkle</YourWinSparklePath> <!-- YOU SHOULDN'T TOUCH ANYTHING BELOW --> @@ -21,9 +20,9 @@ <DepsRoot>$(YourDepsPath)\$(PlatformName)</DepsRoot> <GendefPath>$(YourGendefPath)</GendefPath> <MsgfmtPath>$(YourMsgfmtPath)</MsgfmtPath> + <WinSparklePath>$(YourWinSparklePath)\$(PlatformName)</WinSparklePath> <PerlPath>$(YourPerlPath)\$(PlatformName)</PerlPath> <PerlLib>perl520</PerlLib> - <PerlOutput>hcperl</PerlOutput> <Python2Path>$(YourPython2Path)\$(PlatformName)</Python2Path> <Python2Lib>python27</Python2Lib> <Python2Output>hcpython2</Python2Output> @@ -37,79 +36,49 @@ <HexChatBuild>$(SolutionDir)..\..\hexchat-build</HexChatBuild> <HexChatBin>$(HexChatBuild)\$(PlatformName)\bin\</HexChatBin> <HexChatObj>$(HexChatBuild)\$(PlatformName)\obj\</HexChatObj> - <HexChatRel>$(HexChatBuild)\$(PlatformName)\rel</HexChatRel> - <HexChatCopy> -rmdir /q /s "$(HexChatRel)" -mkdir "$(HexChatRel)" -echo 2> portable-mode -move portable-mode "$(HexChatRel)" -copy changelog.url "$(HexChatRel)" -copy readme.url "$(HexChatRel)" -copy "$(DepsRoot)\bin\cert.pem" "$(HexChatRel)" -copy "$(HexChatBin)hexchat.exe" "$(HexChatRel)" -copy "$(HexChatBin)hexchat-text.exe" "$(HexChatRel)" -copy "$(HexChatBin)thememan.exe" "$(HexChatRel)" -copy "$(DepsRoot)\bin\atk-1.0.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\cairo.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\fontconfig.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\gdk_pixbuf-2.0.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\gdk-win32-2.0.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\gio-2.0.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\glib-2.0.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\gmodule-2.0.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\gobject-2.0.dll" "$(HexChatRel) -copy "$(DepsRoot)\bin\gthread-2.0.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\gtk-win32-2.0.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\harfbuzz.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\iconv.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\libeay32.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\libenchant.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\libintl.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\libpng16.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\libxml2.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\pango-1.0.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\pangocairo-1.0.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\pangoft2-1.0.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\pangowin32-1.0.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\pixman-1.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\ssleay32.dll" "$(HexChatRel)" -copy "$(DepsRoot)\bin\zlib1.dll" "$(HexChatRel)" -xcopy /q /s /i "$(DepsRoot)\lib\gtk-2.0\i686-pc-vs10\engines" "$(HexChatRel)\lib\gtk-2.0\i686-pc-vs10\engines" -xcopy /q /s /i share "$(HexChatRel)\share" -xcopy /q /s /i "..\..\COPYING" "$(HexChatRel)\share\doc\hexchat\" -xcopy /q /s /i "$(DepsRoot)\share\doc" "$(HexChatRel)\share\doc" -xcopy /q /s /i "$(DepsRoot)\share\themes\MS-Windows" "$(HexChatRel)\share\themes\MS-Windows" -xcopy /q /s /i "$(DepsRoot)\lib\enchant\libenchant_myspell.dll" "$(HexChatRel)\lib\enchant\" -xcopy /q /s /i "$(HexChatBin)hcchecksum.dll" "$(HexChatRel)\plugins\" -copy "$(HexChatBin)hcdoat.dll" "$(HexChatRel)\plugins" -copy "$(HexChatBin)hcexec.dll" "$(HexChatRel)\plugins" -copy "$(HexChatBin)hcfishlim.dll" "$(HexChatRel)\plugins" -copy "$(HexChatBin)hcmpcinfo.dll" "$(HexChatRel)\plugins" -copy "$(HexChatBin)hcperl.dll" "$(HexChatRel)\plugins" -copy "$(HexChatBin)hcpython2.dll" "$(HexChatRel)\plugins" -copy "$(HexChatBin)hcpython3.dll" "$(HexChatRel)\plugins" -copy "$(HexChatBin)hcupd.dll" "$(HexChatRel)\plugins" -copy "$(HexChatBin)hcwinamp.dll" "$(HexChatRel)\plugins" -copy "$(HexChatBin)hcsysinfo.dll" "$(HexChatRel)\plugins" -xcopy /q /s /i "$(HexChatBin)locale" "$(HexChatRel)\share\locale" -xcopy /q /s /i "$(DepsRoot)\share\locale" "$(HexChatRel)\share\locale" - </HexChatCopy> - <IsccPath Condition="'$(Platform)'=='Win32'">"%PROGRAMFILES%\Inno Setup 5\iscc.exe"</IsccPath> - <IsccPath Condition="'$(Platform)'=='x64'">"%PROGRAMFILES(x86)%\Inno Setup 5\iscc.exe"</IsccPath> + <HexChatLib>$(HexChatBuild)\$(PlatformName)\lib\</HexChatLib> + <HexChatPdb>$(HexChatBuild)\$(PlatformName)\pdb\</HexChatPdb> + <HexChatRel>$(HexChatBuild)\$(PlatformName)\rel\</HexChatRel> + <IsccPath>"$(MSBuildExtensionsPath32)\..\Inno Setup 5\iscc.exe"</IsccPath> + </PropertyGroup> + + <PropertyGroup> + <LinkIncremental>false</LinkIncremental> + <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> </PropertyGroup> <ItemDefinitionGroup> <ClCompile> <WarningLevel>Level3</WarningLevel> + <PrecompiledHeader>NotUsing</PrecompiledHeader> <DisableSpecificWarnings>4996</DisableSpecificWarnings> - <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions> - <WholeProgramOptimization>false</WholeProgramOptimization> + <AdditionalOptions>/d2Zi+ %(AdditionalOptions)</AdditionalOptions> + <WholeProgramOptimization>true</WholeProgramOptimization> <!-- UNCOMMENT ONLY ONE --> <!--Optimization>Disabled</Optimization--> <Optimization>MaxSpeed</Optimization> <!--Optimization>MinSpace</Optimization--> <!--Optimization>Full</Optimization--> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <MultiProcessorCompilation>true</MultiProcessorCompilation> + <PreProcessorDefinitions>NTDDI_VERSION=NTDDI_WIN8;_WIN32_WINNT=_WIN32_WINNT_WIN8;%(PreProcessorDefinitions)</PreProcessorDefinitions> </ClCompile> + <Lib> + <LinkTimeCodeGeneration>true</LinkTimeCodeGeneration> + </Lib> + <Link> + <ImportLibrary>$(HexChatLib)$(TargetName).lib</ImportLibrary> + <ProgramDatabaseFile>$(HexChatPdb)$(TargetName).pdb</ProgramDatabaseFile> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration> + </Link> </ItemDefinitionGroup> <ItemGroup /> diff --git a/win32/hexchat.sln b/win32/hexchat.sln index 03b75c5d..272c96df 100644 --- a/win32/hexchat.sln +++ b/win32/hexchat.sln @@ -1,7 +1,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 -VisualStudioVersion = 12.0.21005.1 +VisualStudioVersion = 12.0.30501.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "..\src\common\common.vcxproj", "{87554B59-006C-4D94-9714-897B27067BA3}" ProjectSection(ProjectDependencies) = postProject @@ -78,28 +78,31 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nls", "nls\nls.vcxproj", "{ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy", "copy\copy.vcxproj", "{C9B735E4-75BC-45AC-A5E3-39A6D076F912}" ProjectSection(ProjectDependencies) = postProject + {B10A2C41-344C-43E0-A32D-B9587C198D8B} = {B10A2C41-344C-43E0-A32D-B9587C198D8B} + {DE87FFCA-9606-4116-B747-062D88A56A28} = {DE87FFCA-9606-4116-B747-062D88A56A28} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "installer", "installer\installer.vcxproj", "{5A0F4962-E670-4DA2-9E45-52CC47F26E2F}" + ProjectSection(ProjectDependencies) = postProject {C2321A03-0BA7-45B3-8740-ABD82B36B0BF} = {C2321A03-0BA7-45B3-8740-ABD82B36B0BF} {19C52A0A-A790-409E-A28A-9745FF990F5C} = {19C52A0A-A790-409E-A28A-9745FF990F5C} + {BF0EBC16-68AD-4CD1-864C-5B56836EBE2A} = {BF0EBC16-68AD-4CD1-864C-5B56836EBE2A} {4980AF24-9D42-427D-A8E6-0DF3B97C455D} = {4980AF24-9D42-427D-A8E6-0DF3B97C455D} {17E4BE39-76F7-4A06-AD21-EFD0C5091F76} = {17E4BE39-76F7-4A06-AD21-EFD0C5091F76} {B10A2C41-344C-43E0-A32D-B9587C198D8B} = {B10A2C41-344C-43E0-A32D-B9587C198D8B} {461DC24A-A410-4171-8C02-CCDBF3702C2A} = {461DC24A-A410-4171-8C02-CCDBF3702C2A} {E93E1255-95D1-4B08-8FDF-B53CC6A21280} = {E93E1255-95D1-4B08-8FDF-B53CC6A21280} - {87554B59-006C-4D94-9714-897B27067BA3} = {87554B59-006C-4D94-9714-897B27067BA3} + {A7D7CE59-2A31-48AE-BED2-A9828E241832} = {A7D7CE59-2A31-48AE-BED2-A9828E241832} {5EF7F47D-D09C-43C4-BF64-B28B11A0FF91} = {5EF7F47D-D09C-43C4-BF64-B28B11A0FF91} {6C0CA980-97C5-427A-BE61-5BCECAFABBDA} = {6C0CA980-97C5-427A-BE61-5BCECAFABBDA} {B0E36D93-CA2A-49FE-9EB9-9C96C6016EEC} = {B0E36D93-CA2A-49FE-9EB9-9C96C6016EEC} {E78C0D9A-798E-4BF6-B0CC-6FECB8CA2FCE} = {E78C0D9A-798E-4BF6-B0CC-6FECB8CA2FCE} {E4BDB4C8-2335-415A-ACEE-BA88B19BFE82} = {E4BDB4C8-2335-415A-ACEE-BA88B19BFE82} {DE87FFCA-9606-4116-B747-062D88A56A28} = {DE87FFCA-9606-4116-B747-062D88A56A28} + {C53145CC-D021-40C9-B97C-0249AB9A43C9} = {C53145CC-D021-40C9-B97C-0249AB9A43C9} {D90BC3E3-1341-4849-9354-5F40489D39D1} = {D90BC3E3-1341-4849-9354-5F40489D39D1} - {3C4F42FC-292A-420B-B63D-C03DFBDD8E4E} = {3C4F42FC-292A-420B-B63D-C03DFBDD8E4E} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "installer", "installer\installer.vcxproj", "{5A0F4962-E670-4DA2-9E45-52CC47F26E2F}" - ProjectSection(ProjectDependencies) = postProject - {87554B59-006C-4D94-9714-897B27067BA3} = {87554B59-006C-4D94-9714-897B27067BA3} {C9B735E4-75BC-45AC-A5E3-39A6D076F912} = {C9B735E4-75BC-45AC-A5E3-39A6D076F912} + {3C4F42FC-292A-420B-B63D-C03DFBDD8E4E} = {3C4F42FC-292A-420B-B63D-C03DFBDD8E4E} EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "htm", "..\src\htm\htm.csproj", "{DE87FFCA-9606-4116-B747-062D88A56A28}" @@ -119,6 +122,15 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python3", "..\plugins\pytho {87554B59-006C-4D94-9714-897B27067BA3} = {87554B59-006C-4D94-9714-897B27067BA3} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "notifications-winrt", "..\src\fe-gtk\notifications\notifications-winrt.vcxproj", "{C53145CC-D021-40C9-B97C-0249AB9A43C9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "external", "external", "{021EC1D0-FF67-4700-9AB2-EAABF1159C09}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libenchant_win8", "..\src\libenchant_win8\libenchant_win8.vcxproj", "{BF0EBC16-68AD-4CD1-864C-5B56836EBE2A}" + ProjectSection(ProjectDependencies) = postProject + {87554B59-006C-4D94-9714-897B27067BA3} = {87554B59-006C-4D94-9714-897B27067BA3} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Release|Win32 = Release|Win32 @@ -201,16 +213,23 @@ Global {C2321A03-0BA7-45B3-8740-ABD82B36B0BF}.Release|Win32.Build.0 = Release|Win32 {C2321A03-0BA7-45B3-8740-ABD82B36B0BF}.Release|x64.ActiveCfg = Release|x64 {C2321A03-0BA7-45B3-8740-ABD82B36B0BF}.Release|x64.Build.0 = Release|x64 + {C53145CC-D021-40C9-B97C-0249AB9A43C9}.Release|Win32.ActiveCfg = Release|Win32 + {C53145CC-D021-40C9-B97C-0249AB9A43C9}.Release|Win32.Build.0 = Release|Win32 + {C53145CC-D021-40C9-B97C-0249AB9A43C9}.Release|x64.ActiveCfg = Release|x64 + {C53145CC-D021-40C9-B97C-0249AB9A43C9}.Release|x64.Build.0 = Release|x64 + {BF0EBC16-68AD-4CD1-864C-5B56836EBE2A}.Release|Win32.ActiveCfg = Release|Win32 + {BF0EBC16-68AD-4CD1-864C-5B56836EBE2A}.Release|Win32.Build.0 = Release|Win32 + {BF0EBC16-68AD-4CD1-864C-5B56836EBE2A}.Release|x64.ActiveCfg = Release|x64 + {BF0EBC16-68AD-4CD1-864C-5B56836EBE2A}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution + {87554B59-006C-4D94-9714-897B27067BA3} = {AAACEB12-9475-410E-AF5A-FDFF907E9043} {E4BDB4C8-2335-415A-ACEE-BA88B19BFE82} = {AAACEB12-9475-410E-AF5A-FDFF907E9043} {E93E1255-95D1-4B08-8FDF-B53CC6A21280} = {AAACEB12-9475-410E-AF5A-FDFF907E9043} - {87554B59-006C-4D94-9714-897B27067BA3} = {AAACEB12-9475-410E-AF5A-FDFF907E9043} - {DE87FFCA-9606-4116-B747-062D88A56A28} = {AAACEB12-9475-410E-AF5A-FDFF907E9043} - {A7D7CE59-2A31-48AE-BED2-A9828E241832} = {AAACEB12-9475-410E-AF5A-FDFF907E9043} + {19C52A0A-A790-409E-A28A-9745FF990F5C} = {D237DA6B-BD5F-46C0-8BEA-50E9A1340240} {4980AF24-9D42-427D-A8E6-0DF3B97C455D} = {561126F4-FA18-45FC-A2BF-8F858F161D6D} {5EF7F47D-D09C-43C4-BF64-B28B11A0FF91} = {561126F4-FA18-45FC-A2BF-8F858F161D6D} {17E4BE39-76F7-4A06-AD21-EFD0C5091F76} = {561126F4-FA18-45FC-A2BF-8F858F161D6D} @@ -219,11 +238,14 @@ Global {461DC24A-A410-4171-8C02-CCDBF3702C2A} = {561126F4-FA18-45FC-A2BF-8F858F161D6D} {E78C0D9A-798E-4BF6-B0CC-6FECB8CA2FCE} = {561126F4-FA18-45FC-A2BF-8F858F161D6D} {6C0CA980-97C5-427A-BE61-5BCECAFABBDA} = {561126F4-FA18-45FC-A2BF-8F858F161D6D} - {19C52A0A-A790-409E-A28A-9745FF990F5C} = {D237DA6B-BD5F-46C0-8BEA-50E9A1340240} - {D90BC3E3-1341-4849-9354-5F40489D39D1} = {D237DA6B-BD5F-46C0-8BEA-50E9A1340240} - {C2321A03-0BA7-45B3-8740-ABD82B36B0BF} = {D237DA6B-BD5F-46C0-8BEA-50E9A1340240} {B10A2C41-344C-43E0-A32D-B9587C198D8B} = {0FD996A7-464F-4981-8380-3DCA3A244A13} {C9B735E4-75BC-45AC-A5E3-39A6D076F912} = {0FD996A7-464F-4981-8380-3DCA3A244A13} {5A0F4962-E670-4DA2-9E45-52CC47F26E2F} = {0FD996A7-464F-4981-8380-3DCA3A244A13} + {DE87FFCA-9606-4116-B747-062D88A56A28} = {AAACEB12-9475-410E-AF5A-FDFF907E9043} + {A7D7CE59-2A31-48AE-BED2-A9828E241832} = {AAACEB12-9475-410E-AF5A-FDFF907E9043} + {D90BC3E3-1341-4849-9354-5F40489D39D1} = {D237DA6B-BD5F-46C0-8BEA-50E9A1340240} + {C2321A03-0BA7-45B3-8740-ABD82B36B0BF} = {D237DA6B-BD5F-46C0-8BEA-50E9A1340240} + {C53145CC-D021-40C9-B97C-0249AB9A43C9} = {561126F4-FA18-45FC-A2BF-8F858F161D6D} + {BF0EBC16-68AD-4CD1-864C-5B56836EBE2A} = {021EC1D0-FF67-4700-9AB2-EAABF1159C09} EndGlobalSection EndGlobal diff --git a/win32/installer/hexchat.iss.tt b/win32/installer/hexchat.iss.tt index 0ccf2097..6c71de12 100644 --- a/win32/installer/hexchat.iss.tt +++ b/win32/installer/hexchat.iss.tt @@ -124,6 +124,13 @@ Source: "gio-2.0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "glib-2.0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "gmodule-2.0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "gobject-2.0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs +#if APPARCH == "x64" +Source: "gspawn-win64-helper.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs +Source: "gspawn-win64-helper-console.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs +#else +Source: "gspawn-win32-helper.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs +Source: "gspawn-win32-helper-console.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: libs +#endif Source: "gthread-2.0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "gtk-win32-2.0.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "harfbuzz.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs @@ -141,7 +148,9 @@ Source: "pixman-1.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "ssleay32.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs Source: "zlib1.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: libs -Source: "lib\enchant\libenchant_myspell.dll"; DestDir: "{app}\lib\enchant"; Flags: ignoreversion; Components: libs +Source: "plugins\hcnotifications-winrt.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: libs + +Source: "lib\enchant\*"; DestDir: "{app}\lib\enchant"; Flags: ignoreversion; Components: libs Source: "lib\gtk-2.0\i686-pc-vs10\engines\*"; DestDir: "{app}\lib\gtk-2.0\i686-pc-vs10\engines"; Flags: ignoreversion; Components: libs @@ -153,6 +162,7 @@ Source: "share\music.png"; DestDir: "{app}\share"; Flags: ignoreversion; Compone Source: "plugins\hcmpcinfo.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: plugins\mpcinfo Source: "share\download.png"; DestDir: "{app}\share"; Flags: ignoreversion; Components: plugins\upd Source: "plugins\hcupd.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: plugins\upd +Source: "WinSparkle.dll"; DestDir: "{app}"; Flags: ignoreversion; Components: plugins\upd Source: "plugins\hcwinamp.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: plugins\winamp Source: "share\system.png"; DestDir: "{app}\share"; Flags: ignoreversion; Components: plugins\sysinfo Source: "plugins\hcsysinfo.dll"; DestDir: "{app}\plugins"; Flags: ignoreversion; Components: plugins\sysinfo @@ -166,7 +176,7 @@ Source: "hexchat-text.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: Source: "thememan.exe"; DestDir: "{app}"; Flags: ignoreversion; Components: xtm [Icons] -Name: "{group}\HexChat"; Filename: "{app}\hexchat.exe"; Tasks: not portable +Name: "{group}\HexChat"; Filename: "{app}\hexchat.exe"; AppUserModelID: "HexChat.Desktop.Notify"; Tasks: not portable Name: "{group}\HexChat Safe Mode"; Filename: "{app}\hexchat.exe"; Parameters: "--no-auto --no-plugins"; Tasks: not portable Name: "{group}\HexChat ChangeLog"; Filename: "{app}\changelog.url"; IconFilename: "{sys}\shell32.dll"; IconIndex: 165; Tasks: not portable Name: "{group}\HexChat ReadMe"; Filename: "{app}\readme.url"; IconFilename: "{sys}\shell32.dll"; IconIndex: 23; Tasks: not portable @@ -220,8 +230,16 @@ end; ///////////////////////////////////////////////////////////////////// function CheckSpellInstall(): Boolean; +var + Version: TWindowsVersion; begin - Result := DirExists(ExpandConstant('{localappdata}') + '\enchant');; + GetWindowsVersionEx(Version); + + // Windows 8 or greater has built in spell check. + if Version.NTPlatform and (Version.Major > 6) or ((Version.Major = 6) and (Version.Minor > 1)) then + Result := True + else + Result := DirExists(ExpandConstant('{localappdata}') + '\enchant\myspell'); end; ///////////////////////////////////////////////////////////////////// @@ -250,18 +268,18 @@ begin begin #if APPARCH == "x64" - REDIST := 'http://dl.hexchat.net/misc/vcredist_2013_x64.exe'; - PERL := 'http://dl.hexchat.net/misc/perl/Perl%205.20.0%20x64.msi'; + REDIST := 'https://dl.hexchat.net/misc/vcredist_2013_x64.exe'; + PERL := 'https://dl.hexchat.net/misc/perl/Perl%205.20.0%20x64.msi'; PY2 := 'http://python.org/ftp/python/2.7.8/python-2.7.8.amd64.msi'; PY3 := 'http://python.org/ftp/python/3.4.1/python-3.4.1.amd64.msi'; #else - REDIST := 'http://dl.hexchat.net/misc/vcredist_2013_x86.exe'; - PERL := 'http://dl.hexchat.net/misc/perl/Perl%205.20.0%20x86.msi'; + REDIST := 'https://dl.hexchat.net/misc/vcredist_2013_x86.exe'; + PERL := 'https://dl.hexchat.net/misc/perl/Perl%205.20.0%20x86.msi'; PY2 := 'http://python.org/ftp/python/2.7.8/python-2.7.8.msi'; PY3 := 'http://python.org/ftp/python/3.4.1/python-3.4.1.msi'; #endif - DOTNET := 'http://dl.hexchat.net/misc/dotnet_40.exe'; - SPELL := 'http://dl.hexchat.net/hexchat/HexChat%20Spelling%20Dictionaries%20r2.exe'; + DOTNET := 'https://dl.hexchat.net/misc/dotnet_40.exe'; + SPELL := 'https://dl.hexchat.net/hexchat/HexChat%20Spelling%20Dictionaries%20r2.exe'; if not CheckVCInstall() then idpAddFile(REDIST, ExpandConstant('{tmp}\vcredist.exe')); diff --git a/win32/installer/installer.vcxproj b/win32/installer/installer.vcxproj index a3d546c9..713411a5 100644 --- a/win32/installer/installer.vcxproj +++ b/win32/installer/installer.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -18,42 +19,14 @@ <RootNamespace>installer</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\hexchat.props" /> + <PropertyGroup> + <OutDir>$(HexChatRel)</OutDir> </PropertyGroup> <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'"> <ClCompile> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> </ClCompile> <Link> <GenerateDebugInformation>true</GenerateDebugInformation> @@ -64,10 +37,8 @@ <Command> <![CDATA[ SET SOLUTIONDIR=$(SolutionDir)..\ -powershell -File "$(SolutionDir)..\win32\version-template.ps1" "$(SolutionDir)..\win32\installer\hexchat.iss.tt" "$(SolutionDir)..\win32\installer\hexchat.iss" -del "$(OutDir)hexchat.iss" -type hexchat.iss >> "$(OutDir)hexchat.iss" -$(IsccPath) /dPROJECTDIR="$(ProjectDir)" /dAPPARCH="$(Platform)" "$(OutDir)hexchat.iss" +powershell -File "$(SolutionDir)..\win32\version-template.ps1" "$(SolutionDir)..\win32\installer\hexchat.iss.tt" "$(HexChatBin)hexchat.iss" +$(IsccPath) /dPROJECTDIR="$(ProjectDir)" /dAPPARCH="$(Platform)" "$(HexChatBin)hexchat.iss" ]]> </Command> </PreBuildEvent> @@ -78,6 +49,4 @@ $(IsccPath) /dPROJECTDIR="$(ProjectDir)" /dAPPARCH="$(Platform)" "$(OutDir)hexch <None Include="hexchat.iss" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> </Project> diff --git a/win32/nls/nls.vcxproj b/win32/nls/nls.vcxproj index 928fb225..36977f3c 100644 --- a/win32/nls/nls.vcxproj +++ b/win32/nls/nls.vcxproj @@ -2,6 +2,7 @@ <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Label="Configuration"> <PlatformToolset>v120</PlatformToolset> + <ConfigurationType>Application</ConfigurationType> </PropertyGroup> <ItemGroup Label="ProjectConfigurations"> <ProjectConfiguration Include="Release|Win32"> @@ -18,68 +19,13 @@ <RootNamespace>nls</RootNamespace> </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> - <ConfigurationType>Application</ConfigurationType> - <UseDebugLibraries>false</UseDebugLibraries> - <WholeProgramOptimization>true</WholeProgramOptimization> - <CharacterSet>MultiByte</CharacterSet> - </PropertyGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> - <ImportGroup Label="ExtensionSettings"> - </ImportGroup> - <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\hexchat.props" /> - </ImportGroup> - <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> - <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> - <Import Project="..\hexchat.props" /> - </ImportGroup> - <PropertyGroup Label="UserMacros" /> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="..\hexchat.props" /> + <PropertyGroup> <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> </PropertyGroup> - <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <OutDir>$(HexChatBin)</OutDir> - <IntDir>$(HexChatObj)$(ProjectName)\</IntDir> - </PropertyGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> - <ClCompile> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - </ClCompile> - <Link> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - </Link> - <PreBuildEvent> - <Command>cd ..\..\po -rmdir /q /s "$(OutDir)\locale" -mkdir "$(OutDir)\locale" -for %%A in (*.po) do ( -mkdir "$(OutDir)\locale\%%~nA\LC_MESSAGES" -"$(MsgfmtPath)\msgfmt" -co "$(OutDir)\locale\%%~nA\LC_MESSAGES\hexchat.mo" %%A -)</Command> - </PreBuildEvent> - </ItemDefinitionGroup> - <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> - <ClCompile> - <FunctionLevelLinking>true</FunctionLevelLinking> - <IntrinsicFunctions>true</IntrinsicFunctions> - </ClCompile> - <Link> - <GenerateDebugInformation>true</GenerateDebugInformation> - <EnableCOMDATFolding>true</EnableCOMDATFolding> - <OptimizeReferences>true</OptimizeReferences> - </Link> + <ItemDefinitionGroup> <PreBuildEvent> <Command>cd ..\..\po rmdir /q /s "$(OutDir)\locale" @@ -93,6 +39,4 @@ mkdir "$(OutDir)\locale\%%~nA\LC_MESSAGES" <ItemGroup> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> - <ImportGroup Label="ExtensionTargets"> - </ImportGroup> -</Project> \ No newline at end of file +</Project> diff --git a/win32/version.txt b/win32/version.txt index 5cc82157..d332044b 100644 --- a/win32/version.txt +++ b/win32/version.txt @@ -1 +1 @@ -2.10.1 \ No newline at end of file +2.10.2 \ No newline at end of file diff --git a/win32/wdkpt/vs2010/Microsoft.Cpp.Win32.WDK7.props b/win32/wdkpt/vs2010/Microsoft.Cpp.Win32.WDK7.props deleted file mode 100644 index 41e4baae..00000000 --- a/win32/wdkpt/vs2010/Microsoft.Cpp.Win32.WDK7.props +++ /dev/null @@ -1,68 +0,0 @@ -<!-- -*********************************************************************************************** -Microsoft.Cpp.Win32.v100.props - -WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have - created a backup copy. Incorrect changes to this file will make it - impossible to load or build your projects from the command-line or the IDE. - -Copyright (C) Microsoft Corporation. All rights reserved. -*********************************************************************************************** ---> - -<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(VCTargetsPath)\Platforms\Win32\PlatformToolsets\v100\ImportBefore\*.props" Condition="Exists('$(VCTargetsPath)\Platforms\Win32\PlatformToolsets\v100\ImportBefore')" /> - - <PropertyGroup> - <PlatformToolsetVersion>100</PlatformToolsetVersion> - - <WDKInstallDir>$(SystemDrive)\WinDDK\7600.16385.1</WDKInstallDir> - - <VCInstallDir>$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0\Setup\VC@ProductDir)</VCInstallDir> - <VCInstallDir Condition="'$(VCInstallDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\Setup\VC@ProductDir)</VCInstallDir> - <VCInstallDir Condition="'$(VCInstallDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VCExpress\10.0\Setup\VC@ProductDir)</VCInstallDir> - <VCInstallDir Condition="'$(VCInstallDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VCExpress\10.0\Setup\VC@ProductDir)</VCInstallDir> - - <VSInstallDir>$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0\Setup\VS@ProductDir)</VSInstallDir> - <VSInstallDir Condition="'$(VSInstallDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\Setup\VS@ProductDir)</VSInstallDir> - <VSInstallDir Condition="'$(VSInstallDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VCExpress\10.0\Setup\VS@ProductDir)</VSInstallDir> - <VSInstallDir Condition="'$(VSInstallDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VCExpress\10.0\Setup\VS@ProductDir)</VSInstallDir> - - <WindowsSdkDir Condition="'$(UseEnv)' != 'true'">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A@InstallationFolder)</WindowsSdkDir> - <WindowsSdkDir Condition="'$(WindowsSdkDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v7.0A@InstallationFolder)</WindowsSdkDir> - - <FrameworkDir Condition="'$(UseEnv)' != 'true'">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework@InstallRoot)</FrameworkDir> - <FrameworkDir Condition="'$(FrameworkDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework@InstallRoot)</FrameworkDir> - - <FrameworkSdkDir Condition="'$(UseEnv)' != 'true'">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A@InstallationFolder)</FrameworkSdkDir> - <FrameworkSdkDir Condition="'$(FrameworkSdkDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v7.0A@InstallationFolder)</FrameworkSdkDir> - - <FrameworkVersion Condition="'$(UseEnv)' != 'true'">v4.0</FrameworkVersion> - <Framework35Version Condition="'$(UseEnv)' != 'true'">v3.5</Framework35Version> - - <ExecutablePath Condition="'$(ExecutablePath)' == ''">$(VCInstallDir)bin;$(WindowsSdkDir)bin\NETFX 4.0 Tools;$(WindowsSdkDir)bin;$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;$(ProgramFiles)\HTML Help Workshop;$(FrameworkSDKDir)\bin;$(MSBuildToolsPath32);$(VSInstallDir);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath> - <IncludePath>$(WDKInstallDir)\inc\api;$(WDKInstallDir)\inc\crt;$(WDKInstallDir)\inc\api\crt\stl70;$(WDKInstallDir)\inc\mfc42;$(WDKInstallDir)\inc\ddk;$(WDKInstallDir)\inc\api\dao360;</IncludePath> - <LibraryPath>$(WDKInstallDir)\lib\wxp\i386;$(WDKInstallDir)\lib\Crt\i386;$(WDKInstallDir)\lib\Mfc\i386;$(WDKInstallDir)\lib\ATL\i386</LibraryPath> - <SourcePath Condition="'$(SourcePath)' == ''">$(VCInstallDir)atlmfc\src\mfc;$(VCInstallDir)atlmfc\src\mfcm;$(VCInstallDir)atlmfc\src\atl;$(VCInstallDir)crt\src;</SourcePath> - <NativeExecutablePath Condition="'$(NativeExecutablePath)' == ''">$(ExecutablePath)</NativeExecutablePath> - </PropertyGroup> - - <ItemDefinitionGroup> - <Link> - <AdditionalDependencies>msvcrt_winxp.obj;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - <ResourceCompile> - <SuppressStartupBanner Condition="'%(ResourceCompile.SuppressStartupBanner)' == ''">true</SuppressStartupBanner> - </ResourceCompile> - <ManifestResourceCompile> - <SuppressStartupBanner Condition="'%(ManifestResourceCompile.SuppressStartupBanner)'==''">true</SuppressStartupBanner> - </ManifestResourceCompile> - <Manifest> - <EnableDPIAwareness Condition="'$(EnableDPIAwareness)' == '' AND '$(UseOfMFC)' == 'static'">true</EnableDPIAwareness> - <EnableDPIAwareness Condition="'$(EnableDPIAwareness)' == '' AND '$(UseOfMFC)' == 'dynamic'">true</EnableDPIAwareness> - <EnableDPIAwareness Condition="'$(EnableDPIAwareness)' == '' AND '$(UseOfMFC)' != 'static' AND '$(UseOfMFC)' != 'dynamic'">false</EnableDPIAwareness> - </Manifest> - </ItemDefinitionGroup> - - <Import Project="$(VCTargetsPath)\Platforms\Win32\PlatformToolsets\v100\ImportAfter\*.props" Condition="Exists('$(VCTargetsPath)\Platforms\Win32\PlatformToolsets\v100\ImportAfter')" /> -</Project> diff --git a/win32/wdkpt/vs2010/Microsoft.Cpp.Win32.WDK7.targets b/win32/wdkpt/vs2010/Microsoft.Cpp.Win32.WDK7.targets deleted file mode 100644 index f68a78bc..00000000 --- a/win32/wdkpt/vs2010/Microsoft.Cpp.Win32.WDK7.targets +++ /dev/null @@ -1,20 +0,0 @@ -<!-- -*********************************************************************************************** -Microsoft.Cpp.Win32.v100.targets - -WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have - created a backup copy. Incorrect changes to this file will make it - impossible to load or build your projects from the command-line or the IDE. - -This file defines the steps/targets required to build Visual C++ (version 10.0) projects -specifically on x86 platforms. - -Copyright (C) Microsoft Corporation. All rights reserved. -*********************************************************************************************** ---> - -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(VCTargetsPath)\Platforms\Win32\PlatformToolsets\v100\ImportBefore\*.targets" Condition="Exists('$(VCTargetsPath)\Platforms\Win32\PlatformToolsets\v100\ImportBefore')" /> - - <Import Project="$(VCTargetsPath)\Platforms\Win32\PlatformToolsets\v100\ImportAfter\*.targets" Condition="Exists('$(VCTargetsPath)\Platforms\Win32\PlatformToolsets\v100\ImportAfter')" /> -</Project> diff --git a/win32/wdkpt/vs2010/Microsoft.Cpp.x64.WDK7.props b/win32/wdkpt/vs2010/Microsoft.Cpp.x64.WDK7.props deleted file mode 100644 index 7f72f8e2..00000000 --- a/win32/wdkpt/vs2010/Microsoft.Cpp.x64.WDK7.props +++ /dev/null @@ -1,68 +0,0 @@ -<!-- -*********************************************************************************************** -Microsoft.Cpp.x64.v100.props - -WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have - created a backup copy. Incorrect changes to this file will make it - impossible to load or build your projects from the command-line or the IDE. - -Copyright (C) Microsoft Corporation. All rights reserved. -*********************************************************************************************** ---> - -<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(VCTargetsPath)\Platforms\x64\PlatformToolsets\v100\ImportBefore\*.props" Condition="Exists('$(VCTargetsPath)\Platforms\x64\PlatformToolsets\v100\ImportBefore')" /> - - <PropertyGroup> - <PlatformToolsetVersion>100</PlatformToolsetVersion> - - <WDKInstallDir>$(SystemDrive)\WinDDK\7600.16385.1</WDKInstallDir> - - <VCInstallDir>$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0\Setup\VC@ProductDir)</VCInstallDir> - <VCInstallDir Condition="'$(VCInstallDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\Setup\VC@ProductDir)</VCInstallDir> - <VCInstallDir Condition="'$(VCInstallDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VCExpress\10.0\Setup\VC@ProductDir)</VCInstallDir> - <VCInstallDir Condition="'$(VCInstallDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VCExpress\10.0\Setup\VC@ProductDir)</VCInstallDir> - - <VSInstallDir>$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0\Setup\VS@ProductDir)</VSInstallDir> - <VSInstallDir Condition="'$(VSInstallDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\Setup\VS@ProductDir)</VSInstallDir> - <VSInstallDir Condition="'$(VSInstallDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VCExpress\10.0\Setup\VS@ProductDir)</VSInstallDir> - <VSInstallDir Condition="'$(VSInstallDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VCExpress\10.0\Setup\VS@ProductDir)</VSInstallDir> - - <WindowsSdkDir Condition="'$(UseEnv)' != 'true'">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A@InstallationFolder)</WindowsSdkDir> - <WindowsSdkDir Condition="'$(WindowsSdkDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v7.0A@InstallationFolder)</WindowsSdkDir> - - <FrameworkDir Condition="'$(UseEnv)' != 'true'">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework@InstallRoot)</FrameworkDir> - <FrameworkDir Condition="'$(FrameworkDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework@InstallRoot)</FrameworkDir> - - <FrameworkSdkDir Condition="'$(UseEnv)' != 'true'">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A@InstallationFolder)</FrameworkSdkDir> - <FrameworkSdkDir Condition="'$(FrameworkSdkDir)' == ''">$(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows\v7.0A@InstallationFolder)</FrameworkSdkDir> - - <FrameworkVersion Condition="'$(UseEnv)' != 'true'">v4.0</FrameworkVersion> - <Framework35Version Condition="'$(UseEnv)' != 'true'">v3.5</Framework35Version> - - <ExecutablePath Condition="'$(ExecutablePath)' == ''">$(VCInstallDir)bin\x86_amd64;$(VCInstallDir)bin;$(WindowsSdkDir)bin\NETFX 4.0 Tools;$(WindowsSdkDir)bin;$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;$(ProgramFiles)\HTML Help Workshop;$(FrameworkSDKDir)\bin;$(FrameworkSDKDir)\lib\win64;$(MSBuildToolsPath32);$(FxCopDir);$(PATH);</ExecutablePath> - <IncludePath>$(WDKInstallDir)\inc\api;$(WDKInstallDir)\inc\crt;$(WDKInstallDir)\inc\api\crt\stl70;$(WDKInstallDir)\inc\mfc42;$(WDKInstallDir)\inc\ddk;$(WDKInstallDir)\inc\api\dao360;</IncludePath> - <LibraryPath>$(WDKInstallDir)\lib\wnet\amd64;$(WDKInstallDir)\lib\Crt\amd64;$(WDKInstallDir)\lib\Mfc\amd64;$(WDKInstallDir)\lib\ATL\amd64;</LibraryPath> - <SourcePath Condition="'$(SourcePath)' == ''">$(VCInstallDir)atlmfc\src\mfc;$(VCInstallDir)atlmfc\src\mfcm;$(VCInstallDir)atlmfc\src\atl;$(VCInstallDir)crt\src;</SourcePath> - <NativeExecutablePath Condition="'$(NativeExecutablePath)' == ''">$(VCInstallDir)bin\AMD64;$(VCInstallDir)VCPackages;$(WindowsSdkDir)bin\NETFX 4.0 Tools\x64;$(WindowsSdkDir)bin\NETFX 4.0 Tools;$(WindowsSdkDir)bin\x64;$(WindowsSdkDir)bin\win64\x64;$(WindowsSdkDir)bin;$(MSBuildToolsPath);$(PATH);</NativeExecutablePath> - </PropertyGroup> - - <ItemDefinitionGroup> - <Link> - <AdditionalDependencies>msvcrt_win2003.obj;%(AdditionalDependencies)</AdditionalDependencies> - </Link> - <ResourceCompile> - <SuppressStartupBanner Condition="'%(ResourceCompile.SuppressStartupBanner)' == ''">true</SuppressStartupBanner> - </ResourceCompile> - <ManifestResourceCompile> - <SuppressStartupBanner Condition="'%(ManifestResourceCompile.SuppressStartupBanner)'==''">true</SuppressStartupBanner> - </ManifestResourceCompile> - <Manifest> - <EnableDPIAwareness Condition="'$(EnableDPIAwareness)' == '' AND '$(UseOfMFC)' == 'static'">true</EnableDPIAwareness> - <EnableDPIAwareness Condition="'$(EnableDPIAwareness)' == '' AND '$(UseOfMFC)' == 'dynamic'">true</EnableDPIAwareness> - <EnableDPIAwareness Condition="'$(EnableDPIAwareness)' == '' AND '$(UseOfMFC)' != 'static' AND '$(UseOfMFC)' != 'dynamic'">false</EnableDPIAwareness> - </Manifest> - </ItemDefinitionGroup> - - <Import Project="$(VCTargetsPath)\Platforms\x64\PlatformToolsets\v100\ImportAfter\*.props" Condition="Exists('$(VCTargetsPath)\Platforms\x64\PlatformToolsets\v100\ImportAfter')" /> -</Project> diff --git a/win32/wdkpt/vs2010/Microsoft.Cpp.x64.WDK7.targets b/win32/wdkpt/vs2010/Microsoft.Cpp.x64.WDK7.targets deleted file mode 100644 index fa6651e1..00000000 --- a/win32/wdkpt/vs2010/Microsoft.Cpp.x64.WDK7.targets +++ /dev/null @@ -1,20 +0,0 @@ -<!-- -*********************************************************************************************** -Microsoft.Cpp.x64.v100.targets - -WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have - created a backup copy. Incorrect changes to this file will make it - impossible to load or build your projects from the command-line or the IDE. - -This file defines the steps/targets required to build Visual C++ (version 10.0) projects -specifically on X64 platforms. - -Copyright (C) Microsoft Corporation. All rights reserved. -*********************************************************************************************** ---> - -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(VCTargetsPath)\Platforms\x64\PlatformToolsets\v100\ImportBefore\*.targets" Condition="Exists('$(VCTargetsPath)\Platforms\x64\PlatformToolsets\v100\ImportBefore')" /> - - <Import Project="$(VCTargetsPath)\Platforms\x64\PlatformToolsets\v100\ImportAfter\*.targets" Condition="Exists('$(VCTargetsPath)\Platforms\x64\PlatformToolsets\v100\ImportAfter')" /> -</Project> diff --git a/win32/wdkpt/vs2010/wdkpt.aip b/win32/wdkpt/vs2010/wdkpt.aip deleted file mode 100644 index 38502e5e..00000000 --- a/win32/wdkpt/vs2010/wdkpt.aip +++ /dev/null @@ -1,137 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<DOCUMENT Type="Advanced Installer" CreateVersion="9.2" version="9.5" Modules="simple" RootPath="." Language="en" Id="{F800981F-A57B-40E4-91FE-3C228741E1AD}"> - <COMPONENT cid="caphyon.advinst.msicomp.MsiValidationComponent"> - <ROW Table="File" Column="Sequence" MinValue="1" MaxValue="32767" Description="Sequence with respect to the media images; order must track cabinet order." Options="0" ColumnType="2" ColumnIndex="7" ColumnSize="2" MsiKey="File#Sequence"/> - <ROW Table="Media" Column="LastSequence" MinValue="0" MaxValue="32767" Description="File sequence number for the last file for this media." Options="0" ColumnType="2" ColumnIndex="1" ColumnSize="2" MsiKey="Media#LastSequence"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent"> - <ROW Property="ALLUSERS" Value="2" MultiBuildValue="DefaultBuild:1"/> - <ROW Property="ARPCOMMENTS" Value="This installer database contains the logic and data required to install [|ProductName]." ValueLocId="*"/> - <ROW Property="ARPHELPLINK" Value="http://www.hexchat.org/developers/wdk-platform-toolset"/> - <ROW Property="ARPURLINFOABOUT" Value="http://www.hexchat.org/developers/wdk-platform-toolset"/> - <ROW Property="ARPURLUPDATEINFO" Value="http://www.hexchat.org/developers/wdk-platform-toolset"/> - <ROW Property="Manufacturer" Value="HexChat" ValueLocId="*"/> - <ROW Property="ProductCode" Value="1033:{6C7B98A1-9E15-4756-9FCA-0566ED776BE3} " Type="16"/> - <ROW Property="ProductLanguage" Value="1033"/> - <ROW Property="ProductName" Value="Visual Studio 2010 Windows Driver Kit Platform Toolset" ValueLocId="*"/> - <ROW Property="ProductVersion" Value="1.1" Type="32"/> - <ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND"/> - <ROW Property="UpgradeCode" Value="{1947FE78-21A1-4B81-99CE-E07AAEE6077D}"/> - <ROW Property="WindowsType9X" MultiBuildValue="DefaultBuild:Windows 9x/ME" ValueLocId="-"/> - <ROW Property="WindowsType9XDisplay" MultiBuildValue="DefaultBuild:Windows 9x/ME" ValueLocId="-"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiDirsComponent"> - <ROW Directory="APPDIR" Directory_Parent="TARGETDIR" DefaultDir="APPDIR:." IsPseudoRoot="1"/> - <ROW Directory="MSBuild_Dir" Directory_Parent="ProgramFilesFolder" DefaultDir="MSBuild"/> - <ROW Directory="Microsoft.Cpp_Dir" Directory_Parent="MSBuild_Dir" DefaultDir="Micros~1.Cpp|Microsoft.Cpp"/> - <ROW Directory="PlatformToolsets_1_Dir" Directory_Parent="x64_Dir" DefaultDir="Platfo~1|PlatformToolsets"/> - <ROW Directory="PlatformToolsets_Dir" Directory_Parent="Win32_Dir" DefaultDir="Platfo~1|PlatformToolsets"/> - <ROW Directory="Platforms_Dir" Directory_Parent="v4.0_Dir" DefaultDir="Platfo~1|Platforms"/> - <ROW Directory="ProgramFilesFolder" Directory_Parent="TARGETDIR" DefaultDir="Progra~1|ProgramFilesFolder" IsPseudoRoot="1"/> - <ROW Directory="TARGETDIR" DefaultDir="SourceDir"/> - <ROW Directory="WDK7_1_Dir" Directory_Parent="PlatformToolsets_1_Dir" DefaultDir="WDK7"/> - <ROW Directory="WDK7_Dir" Directory_Parent="PlatformToolsets_Dir" DefaultDir="WDK7"/> - <ROW Directory="Win32_Dir" Directory_Parent="Platforms_Dir" DefaultDir="Win32"/> - <ROW Directory="v4.0_Dir" Directory_Parent="Microsoft.Cpp_Dir" DefaultDir="v4.0"/> - <ROW Directory="x64_Dir" Directory_Parent="Platforms_Dir" DefaultDir="x64"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent"> - <ROW Component="Microsoft.Cpp.Win32.WDK7.props" ComponentId="{3EA16365-3C7E-4F84-A326-C7F28B33F487}" Directory_="WDK7_Dir" Attributes="0" KeyPath="Microsoft.Cpp.Win32.WDK7.props" Type="0"/> - <ROW Component="Microsoft.Cpp.x64.WDK7.props" ComponentId="{50DB333C-5D3E-4A14-80B9-BA1D727BD220}" Directory_="WDK7_1_Dir" Attributes="0" KeyPath="Microsoft.Cpp.x64.WDK7.props" Type="0"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent"> - <ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0" Components="Microsoft.Cpp.Win32.WDK7.props Microsoft.Cpp.x64.WDK7.props"/> - <ATTRIBUTE name="CurrentFeature" value="MainFeature"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiFilesComponent"> - <ROW File="Microsoft.Cpp.Win32.WDK7.props" Component_="Microsoft.Cpp.Win32.WDK7.props" FileName="Micros~1.pro|Microsoft.Cpp.Win32.WDK7.props" Attributes="0" SourcePath="Microsoft.Cpp.Win32.WDK7.props" SelfReg="false" NextFile="Microsoft.Cpp.Win32.WDK7.targets"/> - <ROW File="Microsoft.Cpp.Win32.WDK7.targets" Component_="Microsoft.Cpp.Win32.WDK7.props" FileName="Micros~1.tar|Microsoft.Cpp.Win32.WDK7.targets" Attributes="0" SourcePath="Microsoft.Cpp.Win32.WDK7.targets" SelfReg="false" NextFile="Microsoft.Cpp.x64.WDK7.props"/> - <ROW File="Microsoft.Cpp.x64.WDK7.props" Component_="Microsoft.Cpp.x64.WDK7.props" FileName="Micros~1.pro|Microsoft.Cpp.x64.WDK7.props" Attributes="0" SourcePath="Microsoft.Cpp.x64.WDK7.props" SelfReg="false" NextFile="Microsoft.Cpp.x64.WDK7.targets"/> - <ROW File="Microsoft.Cpp.x64.WDK7.targets" Component_="Microsoft.Cpp.x64.WDK7.props" FileName="Micros~1.tar|Microsoft.Cpp.x64.WDK7.targets" Attributes="0" SourcePath="Microsoft.Cpp.x64.WDK7.targets" SelfReg="false"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.BuildComponent"> - <ROW BuildKey="DefaultBuild" BuildName="DefaultBuild" BuildOrder="1" BuildType="0" PackageFolder="." PackageFileName="Visual Studio 2010 Windows Driver Kit Platform Toolset 1.1" Languages="en" InstallationType="4" UseLargeSchema="true"/> - <ATTRIBUTE name="CurrentBuild" value="DefaultBuild"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.DictionaryComponent"> - <ROW Path="<AI_DICTS>ui.ail"/> - <ROW Path="<AI_DICTS>ui_en.ail"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.FragmentComponent"> - <ROW Fragment="CommonUI.aip" Path="<AI_FRAGS>CommonUI.aip"/> - <ROW Fragment="MaintenanceTypeDlg.aip" Path="<AI_THEMES>classic\fragments\MaintenanceTypeDlg.aip"/> - <ROW Fragment="MaintenanceWelcomeDlg.aip" Path="<AI_THEMES>classic\fragments\MaintenanceWelcomeDlg.aip"/> - <ROW Fragment="SequenceDialogs.aip" Path="<AI_THEMES>classic\fragments\SequenceDialogs.aip"/> - <ROW Fragment="Sequences.aip" Path="<AI_FRAGS>Sequences.aip"/> - <ROW Fragment="StaticUIStrings.aip" Path="<AI_FRAGS>StaticUIStrings.aip"/> - <ROW Fragment="UI.aip" Path="<AI_THEMES>classic\fragments\UI.aip"/> - <ROW Fragment="Validation.aip" Path="<AI_FRAGS>Validation.aip"/> - <ROW Fragment="VerifyRemoveDlg.aip" Path="<AI_THEMES>classic\fragments\VerifyRemoveDlg.aip"/> - <ROW Fragment="VerifyRepairDlg.aip" Path="<AI_THEMES>classic\fragments\VerifyRepairDlg.aip"/> - <ROW Fragment="WelcomeDlg.aip" Path="<AI_THEMES>classic\fragments\WelcomeDlg.aip"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiBinaryComponent"> - <ROW Name="aicustact.dll" SourcePath="<AI_CUSTACTS>aicustact.dll"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiControlComponent"> - <ATTRIBUTE name="FixedSizeBitmaps" value="0"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiControlEventComponent"> - <ROW Dialog_="WelcomeDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_INSTALL" Ordering="1"/> - <ROW Dialog_="MaintenanceWelcomeDlg" Control_="Next" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT" Ordering="99"/> - <ROW Dialog_="CustomizeDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_MAINT" Ordering="101"/> - <ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_INSTALL" Ordering="197"/> - <ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="WelcomeDlg" Condition="AI_INSTALL" Ordering="201"/> - <ROW Dialog_="CustomizeDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT" Ordering="1"/> - <ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_MAINT" Ordering="198"/> - <ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="CustomizeDlg" Condition="AI_MAINT" Ordering="202"/> - <ROW Dialog_="MaintenanceTypeDlg" Control_="ChangeButton" Event="NewDialog" Argument="CustomizeDlg" Condition="AI_MAINT" Ordering="501"/> - <ROW Dialog_="MaintenanceTypeDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceWelcomeDlg" Condition="AI_MAINT" Ordering="1"/> - <ROW Dialog_="MaintenanceTypeDlg" Control_="RemoveButton" Event="NewDialog" Argument="VerifyRemoveDlg" Condition="AI_MAINT AND InstallMode="Remove"" Ordering="601"/> - <ROW Dialog_="VerifyRemoveDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT AND InstallMode="Remove"" Ordering="1"/> - <ROW Dialog_="MaintenanceTypeDlg" Control_="RepairButton" Event="NewDialog" Argument="VerifyRepairDlg" Condition="AI_MAINT AND InstallMode="Repair"" Ordering="601"/> - <ROW Dialog_="VerifyRepairDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT AND InstallMode="Repair"" Ordering="1"/> - <ROW Dialog_="VerifyRepairDlg" Control_="Repair" Event="EndDialog" Argument="Return" Condition="AI_MAINT AND InstallMode="Repair"" Ordering="399"/> - <ROW Dialog_="VerifyRemoveDlg" Control_="Remove" Event="EndDialog" Argument="Return" Condition="AI_MAINT AND InstallMode="Remove"" Ordering="299"/> - <ROW Dialog_="PatchWelcomeDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_PATCH" Ordering="201"/> - <ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_PATCH" Ordering="199"/> - <ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="PatchWelcomeDlg" Condition="AI_PATCH" Ordering="203"/> - <ROW Dialog_="ResumeDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_RESUME" Ordering="299"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiCustActComponent"> - <ROW Action="AI_DOWNGRADE" Type="19" Target="4010"/> - <ROW Action="AI_InstallModeCheck" Type="1" Source="aicustact.dll" Target="UpdateInstallMode" WithoutSeq="true"/> - <ROW Action="AI_PREPARE_UPGRADE" Type="65" Source="aicustact.dll" Target="PrepareUpgrade"/> - <ROW Action="AI_RESTORE_LOCATION" Type="65" Source="aicustact.dll" Target="RestoreLocation"/> - <ROW Action="AI_ResolveKnownFolders" Type="1" Source="aicustact.dll" Target="AI_ResolveKnownFolders"/> - <ROW Action="AI_ResolveLocalizedCredentials" Type="1" Source="aicustact.dll" Target="GetLocalizedCredentials"/> - <ROW Action="AI_SHOW_LOG" Type="65" Source="aicustact.dll" Target="LaunchLogFile" WithoutSeq="true"/> - <ROW Action="AI_STORE_LOCATION" Type="51" Source="ARPINSTALLLOCATION" Target="[APPDIR]"/> - <ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]"/> - <ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]"/> - <ROW Action="SET_TARGETDIR_TO_APPDIR" Type="51" Source="TARGETDIR" Target="[APPDIR]"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiInstExSeqComponent"> - <ROW Action="AI_DOWNGRADE" Condition="AI_NEWERPRODUCTFOUND AND (UILevel <> 5)" Sequence="210"/> - <ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=""" Sequence="749"/> - <ROW Action="AI_STORE_LOCATION" Condition="(Not Installed) OR REINSTALL" Sequence="1501"/> - <ROW Action="AI_PREPARE_UPGRADE" Condition="AI_UPGRADE="No" AND (Not Installed)" Sequence="1399"/> - <ROW Action="AI_ResolveKnownFolders" Sequence="52"/> - <ROW Action="AI_ResolveLocalizedCredentials" Sequence="51"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent"> - <ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=""" Sequence="749"/> - <ROW Action="AI_ResolveKnownFolders" Sequence="52"/> - <ROW Action="AI_ResolveLocalizedCredentials" Sequence="51"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiLaunchConditionsComponent"> - <ROW Condition="VersionNT" Description="[ProductName] cannot be installed on [WindowsType9XDisplay]" DescriptionLocId="AI.LaunchCondition.No9X" IsPredefined="true" Builds="DefaultBuild"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiThemeComponent"> - <ATTRIBUTE name="UsedTheme" value="classic"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiUpgradeComponent"> - <ROW UpgradeCode="[|UpgradeCode]" VersionMax="[|ProductVersion]" Attributes="1025" ActionProperty="OLDPRODUCTS"/> - <ROW UpgradeCode="[|UpgradeCode]" VersionMin="[|ProductVersion]" Attributes="2" ActionProperty="AI_NEWERPRODUCTFOUND"/> - </COMPONENT> -</DOCUMENT> diff --git a/win32/wdkpt/vs2012/Microsoft.Cpp.Win32.WDK7.props b/win32/wdkpt/vs2012/Microsoft.Cpp.Win32.WDK7.props deleted file mode 100644 index 8a9fe767..00000000 --- a/win32/wdkpt/vs2012/Microsoft.Cpp.Win32.WDK7.props +++ /dev/null @@ -1,52 +0,0 @@ -<!-- -*********************************************************************************************** -Microsoft.Cpp.Win32.v110.props - -WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have - created a backup copy. Incorrect changes to this file will make it - impossible to load or build your projects from the command-line or the IDE. - -Copyright (C) Microsoft Corporation. All rights reserved. -*********************************************************************************************** ---> - -<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(VCTargetsPath)\Platforms\Win32\PlatformToolsets\v110\ImportBefore\*.props" Condition="Exists('$(VCTargetsPath)\Platforms\Win32\PlatformToolsets\v110\ImportBefore')" /> - - <PropertyGroup> - <WDKInstallDir>$(SystemDrive)\WinDDK\7600.16385.1</WDKInstallDir> - <!-- Required for enabling Team Build for packaging Windows Store app projects --> - <OutDirWasSpecified Condition=" '$(OutDir)'!='' AND '$(OutDirWasSpecified)'=='' ">true</OutDirWasSpecified> - <OutDirWasSpecified Condition=" '$(OutDir)'=='' AND '$(OutDirWasSpecified)'=='' ">false</OutDirWasSpecified> - - <IntDir Condition="'$(IntDir)'=='' AND '$(IntermediateOutputPath)'!=''">$(IntermediateOutputPath)</IntDir> - <IntDir Condition="'$(IntDir)'=='' AND '$(IntermediateOutputPath)'==''">$(Configuration)\</IntDir> - <OutDir Condition="'$(OutDir)'=='' AND '$(SolutionDir)' != ''">$(SolutionDir)$(Configuration)\</OutDir> - <OutDir Condition="'$(OutDir)'=='' AND '$(SolutionDir)' == ''">$(IntDir)</OutDir> - </PropertyGroup> - - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Common.props" /> - - <PropertyGroup> - <ExecutablePath Condition="'$(ExecutablePath)' == ''">$(VCInstallDir)bin;$(WindowsSDK_ExecutablePath_x86);$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;$(ProgramFiles)\HTML Help Workshop;$(MSBuildToolsPath32);$(VSInstallDir);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath> - <IncludePath>$(WDKInstallDir)\inc\api;$(WDKInstallDir)\inc\crt;$(WDKInstallDir)\inc\api\crt\stl70;$(WDKInstallDir)\inc\mfc42;$(WDKInstallDir)\inc\ddk;$(WDKInstallDir)\inc\api\dao360;</IncludePath> - <ReferencePath Condition="'$(ReferencePath)' == ''">$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib</ReferencePath> - <LibraryPath>$(WDKInstallDir)\lib\wxp\i386;$(WDKInstallDir)\lib\Crt\i386;$(WDKInstallDir)\lib\Mfc\i386;$(WDKInstallDir)\lib\ATL\i386</LibraryPath> - <LibraryWPath Condition="'$(LibraryWPath)' == ''">$(WindowsSDK_MetadataPath)</LibraryWPath> - <SourcePath Condition="'$(SourcePath)' == ''">$(VCInstallDir)atlmfc\src\mfc;$(VCInstallDir)atlmfc\src\mfcm;$(VCInstallDir)atlmfc\src\atl;$(VCInstallDir)crt\src;</SourcePath> - <ExcludePath Condition="'$(ExcludePath)' == ''">$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);$(MSBuildToolsPath32);$(VCInstallDir)atlmfc\lib;$(VCInstallDir)lib;</ExcludePath> - <NativeExecutablePath Condition="'$(NativeExecutablePath)' == ''">$(ExecutablePath)</NativeExecutablePath> - <DebugCppRuntimeFilesPath Condition="'$(DebugCppRuntimeFilesPath)' == ''">$(VCInstallDir)redist\Debug_NonRedist\x86</DebugCppRuntimeFilesPath> - </PropertyGroup> - - <ItemDefinitionGroup> - <Link> - <AdditionalDependencies>msvcrt_winxp.obj;%(AdditionalDependencies)</AdditionalDependencies> - <MinimumRequiredVersion>5.1</MinimumRequiredVersion> - </Link> - </ItemDefinitionGroup> - - <Import Project="$(VCTargetsPath)\Platforms\Win32\PlatformToolsets\v110\ImportAfter\*.props" Condition="Exists('$(VCTargetsPath)\Platforms\Win32\PlatformToolsets\v110\ImportAfter')" /> - - <Import Project="$(VCTargetsPath)\Platforms\Win32\Microsoft.Cpp.Win32.Common.props" /> -</Project> diff --git a/win32/wdkpt/vs2012/Microsoft.Cpp.Win32.WDK7.targets b/win32/wdkpt/vs2012/Microsoft.Cpp.Win32.WDK7.targets deleted file mode 100644 index 3f50fc93..00000000 --- a/win32/wdkpt/vs2012/Microsoft.Cpp.Win32.WDK7.targets +++ /dev/null @@ -1,20 +0,0 @@ -<!-- -*********************************************************************************************** -Microsoft.Cpp.Win32.v110.targets - -WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have - created a backup copy. Incorrect changes to this file will make it - impossible to load or build your projects from the command-line or the IDE. - -This file defines the steps/targets required to build Visual C++ (version 11.0) projects -specifically on x86 platforms. - -Copyright (C) Microsoft Corporation. All rights reserved. -*********************************************************************************************** ---> - -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(VCTargetsPath)\Platforms\Win32\PlatformToolsets\v110\ImportBefore\*.targets" Condition="Exists('$(VCTargetsPath)\Platforms\Win32\PlatformToolsets\v110\ImportBefore')" /> - <Import Project="$(VCTargetsPath)\Microsoft.CppCommon.targets" /> - <Import Project="$(VCTargetsPath)\Platforms\Win32\PlatformToolsets\v110\ImportAfter\*.targets" Condition="Exists('$(VCTargetsPath)\Platforms\Win32\PlatformToolsets\v110\ImportAfter')" /> -</Project> diff --git a/win32/wdkpt/vs2012/Microsoft.Cpp.x64.WDK7.props b/win32/wdkpt/vs2012/Microsoft.Cpp.x64.WDK7.props deleted file mode 100644 index 9d7825c0..00000000 --- a/win32/wdkpt/vs2012/Microsoft.Cpp.x64.WDK7.props +++ /dev/null @@ -1,52 +0,0 @@ -<!-- -*********************************************************************************************** -Microsoft.Cpp.x64.v110.props - -WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have - created a backup copy. Incorrect changes to this file will make it - impossible to load or build your projects from the command-line or the IDE. - -Copyright (C) Microsoft Corporation. All rights reserved. -*********************************************************************************************** ---> - -<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(VCTargetsPath)\Platforms\x64\PlatformToolsets\v110\ImportBefore\*.props" Condition="Exists('$(VCTargetsPath)\Platforms\x64\PlatformToolsets\v110\ImportBefore')" /> - - <PropertyGroup> - <WDKInstallDir>$(SystemDrive)\WinDDK\7600.16385.1</WDKInstallDir> - <!-- Required for enabling Team Build for packaging Windows Store app projects --> - <OutDirWasSpecified Condition=" '$(OutDir)'!='' AND '$(OutDirWasSpecified)'=='' ">true</OutDirWasSpecified> - <OutDirWasSpecified Condition=" '$(OutDir)'=='' AND '$(OutDirWasSpecified)'=='' ">false</OutDirWasSpecified> - - <IntDir Condition="'$(IntDir)'=='' AND '$(IntermediateOutputPath)'!=''">$(IntermediateOutputPath)</IntDir> - <IntDir Condition="'$(IntDir)'=='' AND '$(IntermediateOutputPath)'==''">$(Platform)\$(Configuration)\</IntDir> - <OutDir Condition="'$(OutDir)'=='' AND '$(SolutionDir)' == ''">$(IntDir)</OutDir> - <OutDir Condition="'$(OutDir)'=='' AND '$(SolutionDir)' != ''">$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> - </PropertyGroup> - - <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Common.props" /> - - <PropertyGroup> - <ExecutablePath Condition="'$(ExecutablePath)' == ''">$(VCInstallDir)bin\x86_amd64;$(VCInstallDir)bin;$(WindowsSDK_ExecutablePath_x86);$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;$(ProgramFiles)\HTML Help Workshop;$(MSBuildToolsPath32);$(FxCopDir);$(PATH);</ExecutablePath> - <IncludePath>$(WDKInstallDir)\inc\api;$(WDKInstallDir)\inc\crt;$(WDKInstallDir)\inc\api\crt\stl70;$(WDKInstallDir)\inc\mfc42;$(WDKInstallDir)\inc\ddk;$(WDKInstallDir)\inc\api\dao360;</IncludePath> - <ReferencePath Condition="'$(ReferencePath)' == ''">$(VCInstallDir)atlmfc\lib\amd64;$(VCInstallDir)lib\amd64;</ReferencePath> - <LibraryPath>$(WDKInstallDir)\lib\wnet\amd64;$(WDKInstallDir)\lib\Crt\amd64;$(WDKInstallDir)\lib\Mfc\amd64;$(WDKInstallDir)\lib\ATL\amd64;</LibraryPath> - <LibraryWPath Condition="'$(LibraryWPath)' == ''">$(WindowsSDK_MetadataPath)</LibraryWPath> - <SourcePath Condition="'$(SourcePath)' == ''">$(VCInstallDir)atlmfc\src\mfc;$(VCInstallDir)atlmfc\src\mfcm;$(VCInstallDir)atlmfc\src\atl;$(VCInstallDir)crt\src;</SourcePath> - <ExcludePath Condition="'$(ExcludePath)' == ''">$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSDK_IncludePath);$(MSBuildToolsPath);$(MSBuildToolsPath32);$(VCInstallDir)atlmfc\lib\amd64;$(VCInstallDir)lib\amd64;</ExcludePath> - <NativeExecutablePath Condition="'$(NativeExecutablePath)' == ''">$(VCInstallDir)bin\AMD64;$(VCInstallDir)VCPackages;$(WindowsSDK_ExecutablePath_x64);$(WindowsSDK_ExecutablePath_x86);$(MSBuildToolsPath);$(PATH);</NativeExecutablePath> - <DebugCppRuntimeFilesPath Condition="'$(DebugCppRuntimeFilesPath)' == ''">$(VCInstallDir)redist\Debug_NonRedist\x64</DebugCppRuntimeFilesPath> - </PropertyGroup> - - <ItemDefinitionGroup> - <Link> - <AdditionalDependencies>msvcrt_win2003.obj;%(AdditionalDependencies)</AdditionalDependencies> - <MinimumRequiredVersion>5.2</MinimumRequiredVersion> - </Link> - </ItemDefinitionGroup> - - <Import Project="$(VCTargetsPath)\Platforms\x64\PlatformToolsets\v110\ImportAfter\*.props" Condition="Exists('$(VCTargetsPath)\Platforms\x64\PlatformToolsets\v110\ImportAfter')" /> - - <Import Project="$(VCTargetsPath)\Platforms\x64\Microsoft.Cpp.x64.Common.props" /> -</Project> diff --git a/win32/wdkpt/vs2012/Microsoft.Cpp.x64.WDK7.targets b/win32/wdkpt/vs2012/Microsoft.Cpp.x64.WDK7.targets deleted file mode 100644 index 2c6271c8..00000000 --- a/win32/wdkpt/vs2012/Microsoft.Cpp.x64.WDK7.targets +++ /dev/null @@ -1,20 +0,0 @@ -<!-- -*********************************************************************************************** -Microsoft.Cpp.x64.v110.targets - -WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have - created a backup copy. Incorrect changes to this file will make it - impossible to load or build your projects from the command-line or the IDE. - -This file defines the steps/targets required to build Visual C++ (version 11.0) projects -specifically on X64 platforms. - -Copyright (C) Microsoft Corporation. All rights reserved. -*********************************************************************************************** ---> - -<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(VCTargetsPath)\Platforms\x64\PlatformToolsets\v110\ImportBefore\*.targets" Condition="Exists('$(VCTargetsPath)\Platforms\x64\PlatformToolsets\v110\ImportBefore')" /> - <Import Project="$(VCTargetsPath)\Microsoft.CppCommon.targets" /> - <Import Project="$(VCTargetsPath)\Platforms\x64\PlatformToolsets\v110\ImportAfter\*.targets" Condition="Exists('$(VCTargetsPath)\Platforms\x64\PlatformToolsets\v110\ImportAfter')" /> -</Project> diff --git a/win32/wdkpt/vs2012/wdkpt.aip b/win32/wdkpt/vs2012/wdkpt.aip deleted file mode 100644 index b6763d29..00000000 --- a/win32/wdkpt/vs2012/wdkpt.aip +++ /dev/null @@ -1,138 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<DOCUMENT Type="Advanced Installer" CreateVersion="9.2" version="9.5" Modules="simple" RootPath="." Language="en" Id="{F800981F-A57B-40E4-91FE-3C228741E1AD}"> - <COMPONENT cid="caphyon.advinst.msicomp.MsiValidationComponent"> - <ROW Table="File" Column="Sequence" MinValue="1" MaxValue="32767" Description="Sequence with respect to the media images; order must track cabinet order." Options="0" ColumnType="2" ColumnIndex="7" ColumnSize="2" MsiKey="File#Sequence"/> - <ROW Table="Media" Column="LastSequence" MinValue="0" MaxValue="32767" Description="File sequence number for the last file for this media." Options="0" ColumnType="2" ColumnIndex="1" ColumnSize="2" MsiKey="Media#LastSequence"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent"> - <ROW Property="ALLUSERS" Value="2" MultiBuildValue="DefaultBuild:1"/> - <ROW Property="ARPCOMMENTS" Value="This installer database contains the logic and data required to install [|ProductName]." ValueLocId="*"/> - <ROW Property="ARPHELPLINK" Value="http://www.hexchat.org/developers/wdk-platform-toolset"/> - <ROW Property="ARPURLINFOABOUT" Value="http://www.hexchat.org/developers/wdk-platform-toolset"/> - <ROW Property="ARPURLUPDATEINFO" Value="http://www.hexchat.org/developers/wdk-platform-toolset"/> - <ROW Property="Manufacturer" Value="HexChat" ValueLocId="*"/> - <ROW Property="ProductCode" Value="1033:{2EE972A9-9913-48AF-B0D7-BF76215BE858} " Type="16"/> - <ROW Property="ProductLanguage" Value="1033"/> - <ROW Property="ProductName" Value="Visual Studio 2012 Windows Driver Kit Platform Toolset" ValueLocId="*"/> - <ROW Property="ProductVersion" Value="1.2" Type="32"/> - <ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND"/> - <ROW Property="UpgradeCode" Value="{A569B016-AF0C-4D04-8EF8-0144088E92D0}"/> - <ROW Property="WindowsType9X" MultiBuildValue="DefaultBuild:Windows 9x/ME" ValueLocId="-"/> - <ROW Property="WindowsType9XDisplay" MultiBuildValue="DefaultBuild:Windows 9x/ME" ValueLocId="-"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiDirsComponent"> - <ROW Directory="APPDIR" Directory_Parent="TARGETDIR" DefaultDir="APPDIR:." IsPseudoRoot="1"/> - <ROW Directory="MSBuild_Dir" Directory_Parent="ProgramFilesFolder" DefaultDir="MSBuild"/> - <ROW Directory="Microsoft.Cpp_Dir" Directory_Parent="MSBuild_Dir" DefaultDir="Micros~1.Cpp|Microsoft.Cpp"/> - <ROW Directory="PlatformToolsets_1_Dir" Directory_Parent="x64_Dir" DefaultDir="Platfo~1|PlatformToolsets"/> - <ROW Directory="PlatformToolsets_Dir" Directory_Parent="Win32_Dir" DefaultDir="Platfo~1|PlatformToolsets"/> - <ROW Directory="Platforms_Dir" Directory_Parent="V110_Dir" DefaultDir="Platfo~1|Platforms"/> - <ROW Directory="ProgramFilesFolder" Directory_Parent="TARGETDIR" DefaultDir="Progra~1|ProgramFilesFolder" IsPseudoRoot="1"/> - <ROW Directory="TARGETDIR" DefaultDir="SourceDir"/> - <ROW Directory="V110_Dir" Directory_Parent="v4.0_Dir" DefaultDir="V110"/> - <ROW Directory="WDK7_1_Dir" Directory_Parent="PlatformToolsets_1_Dir" DefaultDir="WDK7"/> - <ROW Directory="WDK7_Dir" Directory_Parent="PlatformToolsets_Dir" DefaultDir="WDK7"/> - <ROW Directory="Win32_Dir" Directory_Parent="Platforms_Dir" DefaultDir="Win32"/> - <ROW Directory="v4.0_Dir" Directory_Parent="Microsoft.Cpp_Dir" DefaultDir="v4.0"/> - <ROW Directory="x64_Dir" Directory_Parent="Platforms_Dir" DefaultDir="x64"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent"> - <ROW Component="Microsoft.Cpp.Win32.WDK7.props" ComponentId="{3EA16365-3C7E-4F84-A326-C7F28B33F487}" Directory_="WDK7_Dir" Attributes="0" KeyPath="Microsoft.Cpp.Win32.WDK7.props" Type="0"/> - <ROW Component="Microsoft.Cpp.x64.WDK7.props" ComponentId="{50DB333C-5D3E-4A14-80B9-BA1D727BD220}" Directory_="WDK7_1_Dir" Attributes="0" KeyPath="Microsoft.Cpp.x64.WDK7.props" Type="0"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent"> - <ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0" Components="Microsoft.Cpp.Win32.WDK7.props Microsoft.Cpp.x64.WDK7.props"/> - <ATTRIBUTE name="CurrentFeature" value="MainFeature"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiFilesComponent"> - <ROW File="Microsoft.Cpp.Win32.WDK7.props" Component_="Microsoft.Cpp.Win32.WDK7.props" FileName="Micros~1.pro|Microsoft.Cpp.Win32.WDK7.props" Attributes="0" SourcePath="Microsoft.Cpp.Win32.WDK7.props" SelfReg="false" NextFile="Microsoft.Cpp.Win32.WDK7.targets"/> - <ROW File="Microsoft.Cpp.Win32.WDK7.targets" Component_="Microsoft.Cpp.Win32.WDK7.props" FileName="Micros~1.tar|Microsoft.Cpp.Win32.WDK7.targets" Attributes="0" SourcePath="Microsoft.Cpp.Win32.WDK7.targets" SelfReg="false" NextFile="Microsoft.Cpp.x64.WDK7.props"/> - <ROW File="Microsoft.Cpp.x64.WDK7.props" Component_="Microsoft.Cpp.x64.WDK7.props" FileName="Micros~1.pro|Microsoft.Cpp.x64.WDK7.props" Attributes="0" SourcePath="Microsoft.Cpp.x64.WDK7.props" SelfReg="false" NextFile="Microsoft.Cpp.x64.WDK7.targets"/> - <ROW File="Microsoft.Cpp.x64.WDK7.targets" Component_="Microsoft.Cpp.x64.WDK7.props" FileName="Micros~1.tar|Microsoft.Cpp.x64.WDK7.targets" Attributes="0" SourcePath="Microsoft.Cpp.x64.WDK7.targets" SelfReg="false"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.BuildComponent"> - <ROW BuildKey="DefaultBuild" BuildName="DefaultBuild" BuildOrder="1" BuildType="0" PackageFolder="." PackageFileName="Visual Studio 2012 Windows Driver Kit Platform Toolset 1.2" Languages="en" InstallationType="4" UseLargeSchema="true"/> - <ATTRIBUTE name="CurrentBuild" value="DefaultBuild"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.DictionaryComponent"> - <ROW Path="<AI_DICTS>ui.ail"/> - <ROW Path="<AI_DICTS>ui_en.ail"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.FragmentComponent"> - <ROW Fragment="CommonUI.aip" Path="<AI_FRAGS>CommonUI.aip"/> - <ROW Fragment="MaintenanceTypeDlg.aip" Path="<AI_THEMES>classic\fragments\MaintenanceTypeDlg.aip"/> - <ROW Fragment="MaintenanceWelcomeDlg.aip" Path="<AI_THEMES>classic\fragments\MaintenanceWelcomeDlg.aip"/> - <ROW Fragment="SequenceDialogs.aip" Path="<AI_THEMES>classic\fragments\SequenceDialogs.aip"/> - <ROW Fragment="Sequences.aip" Path="<AI_FRAGS>Sequences.aip"/> - <ROW Fragment="StaticUIStrings.aip" Path="<AI_FRAGS>StaticUIStrings.aip"/> - <ROW Fragment="UI.aip" Path="<AI_THEMES>classic\fragments\UI.aip"/> - <ROW Fragment="Validation.aip" Path="<AI_FRAGS>Validation.aip"/> - <ROW Fragment="VerifyRemoveDlg.aip" Path="<AI_THEMES>classic\fragments\VerifyRemoveDlg.aip"/> - <ROW Fragment="VerifyRepairDlg.aip" Path="<AI_THEMES>classic\fragments\VerifyRepairDlg.aip"/> - <ROW Fragment="WelcomeDlg.aip" Path="<AI_THEMES>classic\fragments\WelcomeDlg.aip"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiBinaryComponent"> - <ROW Name="aicustact.dll" SourcePath="<AI_CUSTACTS>aicustact.dll"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiControlComponent"> - <ATTRIBUTE name="FixedSizeBitmaps" value="0"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiControlEventComponent"> - <ROW Dialog_="WelcomeDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_INSTALL" Ordering="1"/> - <ROW Dialog_="MaintenanceWelcomeDlg" Control_="Next" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT" Ordering="99"/> - <ROW Dialog_="CustomizeDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_MAINT" Ordering="101"/> - <ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_INSTALL" Ordering="197"/> - <ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="WelcomeDlg" Condition="AI_INSTALL" Ordering="201"/> - <ROW Dialog_="CustomizeDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT" Ordering="1"/> - <ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_MAINT" Ordering="198"/> - <ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="CustomizeDlg" Condition="AI_MAINT" Ordering="202"/> - <ROW Dialog_="MaintenanceTypeDlg" Control_="ChangeButton" Event="NewDialog" Argument="CustomizeDlg" Condition="AI_MAINT" Ordering="501"/> - <ROW Dialog_="MaintenanceTypeDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceWelcomeDlg" Condition="AI_MAINT" Ordering="1"/> - <ROW Dialog_="MaintenanceTypeDlg" Control_="RemoveButton" Event="NewDialog" Argument="VerifyRemoveDlg" Condition="AI_MAINT AND InstallMode="Remove"" Ordering="601"/> - <ROW Dialog_="VerifyRemoveDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT AND InstallMode="Remove"" Ordering="1"/> - <ROW Dialog_="MaintenanceTypeDlg" Control_="RepairButton" Event="NewDialog" Argument="VerifyRepairDlg" Condition="AI_MAINT AND InstallMode="Repair"" Ordering="601"/> - <ROW Dialog_="VerifyRepairDlg" Control_="Back" Event="NewDialog" Argument="MaintenanceTypeDlg" Condition="AI_MAINT AND InstallMode="Repair"" Ordering="1"/> - <ROW Dialog_="VerifyRepairDlg" Control_="Repair" Event="EndDialog" Argument="Return" Condition="AI_MAINT AND InstallMode="Repair"" Ordering="399"/> - <ROW Dialog_="VerifyRemoveDlg" Control_="Remove" Event="EndDialog" Argument="Return" Condition="AI_MAINT AND InstallMode="Remove"" Ordering="299"/> - <ROW Dialog_="PatchWelcomeDlg" Control_="Next" Event="NewDialog" Argument="VerifyReadyDlg" Condition="AI_PATCH" Ordering="201"/> - <ROW Dialog_="VerifyReadyDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_PATCH" Ordering="199"/> - <ROW Dialog_="VerifyReadyDlg" Control_="Back" Event="NewDialog" Argument="PatchWelcomeDlg" Condition="AI_PATCH" Ordering="203"/> - <ROW Dialog_="ResumeDlg" Control_="Install" Event="EndDialog" Argument="Return" Condition="AI_RESUME" Ordering="299"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiCustActComponent"> - <ROW Action="AI_DOWNGRADE" Type="19" Target="4010"/> - <ROW Action="AI_InstallModeCheck" Type="1" Source="aicustact.dll" Target="UpdateInstallMode" WithoutSeq="true"/> - <ROW Action="AI_PREPARE_UPGRADE" Type="65" Source="aicustact.dll" Target="PrepareUpgrade"/> - <ROW Action="AI_RESTORE_LOCATION" Type="65" Source="aicustact.dll" Target="RestoreLocation"/> - <ROW Action="AI_ResolveKnownFolders" Type="1" Source="aicustact.dll" Target="AI_ResolveKnownFolders"/> - <ROW Action="AI_ResolveLocalizedCredentials" Type="1" Source="aicustact.dll" Target="GetLocalizedCredentials"/> - <ROW Action="AI_SHOW_LOG" Type="65" Source="aicustact.dll" Target="LaunchLogFile" WithoutSeq="true"/> - <ROW Action="AI_STORE_LOCATION" Type="51" Source="ARPINSTALLLOCATION" Target="[APPDIR]"/> - <ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]"/> - <ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]"/> - <ROW Action="SET_TARGETDIR_TO_APPDIR" Type="51" Source="TARGETDIR" Target="[APPDIR]"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiInstExSeqComponent"> - <ROW Action="AI_DOWNGRADE" Condition="AI_NEWERPRODUCTFOUND AND (UILevel <> 5)" Sequence="210"/> - <ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=""" Sequence="749"/> - <ROW Action="AI_STORE_LOCATION" Condition="(Not Installed) OR REINSTALL" Sequence="1501"/> - <ROW Action="AI_PREPARE_UPGRADE" Condition="AI_UPGRADE="No" AND (Not Installed)" Sequence="1399"/> - <ROW Action="AI_ResolveKnownFolders" Sequence="52"/> - <ROW Action="AI_ResolveLocalizedCredentials" Sequence="51"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent"> - <ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=""" Sequence="749"/> - <ROW Action="AI_ResolveKnownFolders" Sequence="52"/> - <ROW Action="AI_ResolveLocalizedCredentials" Sequence="51"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiLaunchConditionsComponent"> - <ROW Condition="VersionNT" Description="[ProductName] cannot be installed on [WindowsType9XDisplay]" DescriptionLocId="AI.LaunchCondition.No9X" IsPredefined="true" Builds="DefaultBuild"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiThemeComponent"> - <ATTRIBUTE name="UsedTheme" value="classic"/> - </COMPONENT> - <COMPONENT cid="caphyon.advinst.msicomp.MsiUpgradeComponent"> - <ROW UpgradeCode="[|UpgradeCode]" VersionMax="[|ProductVersion]" Attributes="1025" ActionProperty="OLDPRODUCTS"/> - <ROW UpgradeCode="[|UpgradeCode]" VersionMin="[|ProductVersion]" Attributes="2" ActionProperty="AI_NEWERPRODUCTFOUND"/> - </COMPONENT> -</DOCUMENT> |