Compare commits
1 Commits
wip/plugin
...
sslalert
Author | SHA1 | Date | |
---|---|---|---|
ba143b4260 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,7 +2,6 @@
|
||||
# Unix generated files
|
||||
.deps/
|
||||
.libs/
|
||||
.dirstamp
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
@ -70,7 +69,6 @@ stamp-h1
|
||||
*.po~
|
||||
*.pot
|
||||
*.patch
|
||||
src/**/*.plist
|
||||
# Win32 generated files
|
||||
plugins/wmpa/wmpa_h.h
|
||||
plugins/wmpa/wmpa_i.c
|
||||
@ -87,7 +85,6 @@ resource.h
|
||||
*.sdf
|
||||
*.suo
|
||||
*.user
|
||||
*.exe
|
||||
#OSX
|
||||
osx/HexChat.app
|
||||
osx/.HexChat.app
|
||||
|
@ -1,17 +1,19 @@
|
||||
language: c
|
||||
compiler: clang
|
||||
compiler:
|
||||
- gcc
|
||||
- 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
|
||||
script:
|
||||
- ./autogen.sh
|
||||
- ./configure --enable-textfe --with-theme-manager --enable-static-analysis
|
||||
- ./configure --enable-textfe --with-theme-manager
|
||||
- make V=1 -j$(nproc)
|
||||
notifications:
|
||||
irc:
|
||||
channels: "chat.freenode.net#hexchat-devel"
|
||||
template: "Build %{build_url} (%{commit} in %{branch}) by %{author}: %{message}"
|
||||
template: "Build #%{build_number} (%{commit}) by %{author}: %{message}"
|
||||
on_success: change
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
309
configure.ac
309
configure.ac
@ -18,7 +18,6 @@ AM_MAINTAINER_MODE
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_CPP
|
||||
AC_PROG_OBJC
|
||||
AM_PROG_AS
|
||||
AM_PROG_AR
|
||||
AM_DISABLE_STATIC
|
||||
@ -39,12 +38,14 @@ 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])
|
||||
@ -73,20 +74,18 @@ else
|
||||
fi
|
||||
fi
|
||||
|
||||
platform_win32=no
|
||||
platform_osx=no
|
||||
case $host_os in
|
||||
*mingw*|*cygwin*|*msys*)
|
||||
platform_win32=yes;;
|
||||
darwin*)
|
||||
platform_osx=yes;;
|
||||
*);;
|
||||
esac
|
||||
|
||||
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)
|
||||
@ -144,6 +143,10 @@ 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)
|
||||
@ -156,10 +159,6 @@ 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)])],
|
||||
theme_manager=$withval, theme_manager=no)
|
||||
@ -180,25 +179,37 @@ dnl *********************************************************************
|
||||
dnl ** GLIB *************************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
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])
|
||||
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"
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** GTK **************************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
# we might get undefined macro without this test
|
||||
if test "$gtkfe" = yes ; then
|
||||
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"
|
||||
], [
|
||||
AM_PATH_GTK_2_0(2.24.0, havegtk=yes, havegtk=no)
|
||||
|
||||
if test "$havegtk" = no; then
|
||||
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 *********************************************************************
|
||||
@ -343,13 +354,16 @@ AC_CHECK_FUNC(select, ,
|
||||
AC_MSG_WARN(i can not find select. you might need to help me)))))))
|
||||
AC_CHECK_LIB(socket, select)
|
||||
|
||||
AC_CHECK_FUNCS(getaddrinfo, have_getaddrinfo=yes)
|
||||
AC_MSG_CHECKING(whether IPv6 is supported)
|
||||
if test "$have_getaddrinfo" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR(ipv6 support not found!)
|
||||
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
|
||||
|
||||
dnl *********************************************************************
|
||||
@ -358,14 +372,17 @@ dnl *********************************************************************
|
||||
|
||||
retry=no
|
||||
if test "$openssl" != no; then
|
||||
PKG_CHECK_MODULES(OPENSSL, [openssl], [
|
||||
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`"
|
||||
AC_DEFINE(USE_OPENSSL)
|
||||
AC_MSG_RESULT(yes)
|
||||
openssl=yes
|
||||
COMMON_LIBS="$COMMON_LIBS $OPENSSL_LIBS"
|
||||
COMMON_CFLAGS="$COMMON_CFLAGS $OPENSSL_CFLAGS"
|
||||
], [
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
retry=yes
|
||||
])
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$retry" = "yes"; then
|
||||
@ -374,29 +391,30 @@ if test "$retry" = "yes"; then
|
||||
openssl_path=$openssl
|
||||
fi
|
||||
openssl=no
|
||||
OPENSSL_LIBS="-lcrypto"
|
||||
if test -n "$openssl_path"; then
|
||||
OPENSSL_LIBS="-L$openssl_path/lib $OPENSSL_LIBS"
|
||||
fi
|
||||
SAVED_LIBS=$LIBS
|
||||
LIBS="$LIBS $OPENSSL_LIBS"
|
||||
AC_CHECK_LIB(ssl, SSL_new, [
|
||||
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
|
||||
OPENSSL_CFLAGS="-I$openssl_path/include"
|
||||
CPPFLAGS="-I$openssl_path/include $CPPFLAGS"
|
||||
fi
|
||||
SAVED_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS $OPENSSL_CFLAGS"
|
||||
AC_CHECK_HEADERS(openssl/ssl.h, [
|
||||
AC_CHECK_HEADERS(openssl/ssl.h, have_openssl_h=yes)
|
||||
if test "$have_openssl_h" = yes; then
|
||||
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
|
||||
LIBS="$LIBS -lssl -lcrypto"
|
||||
if test -n "$openssl_path"; then
|
||||
LIBS="-L$openssl_path/lib $LIBS"
|
||||
fi
|
||||
else
|
||||
CPPFLAGS=$SAVED_CPPFLAGS
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
@ -425,10 +443,6 @@ dnl *********************************************************************
|
||||
|
||||
if test "$plugin" = yes; then
|
||||
AC_DEFINE(USE_PLUGIN)
|
||||
PLUGIN_LDFLAGS="-avoid-version"
|
||||
if test "$platform_win32" = yes; then
|
||||
PLUGIN_LDFLAGS="$PLUGIN_LDFLAGS -no-undefined"
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
@ -439,8 +453,14 @@ if test "$checksum" != "no"; then
|
||||
checksum=no
|
||||
AC_MSG_CHECKING(for plugin interface used by Checksum)
|
||||
if test "$plugin" = yes; then
|
||||
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
|
||||
@ -490,14 +510,7 @@ if test "$sysinfo" != "no"; then
|
||||
AC_MSG_CHECKING(for plugin interface used by SysInfo)
|
||||
if test "$plugin" = yes; then
|
||||
AC_MSG_RESULT([yes])
|
||||
if test "$platform_osx" = yes; then
|
||||
sysinfo=yes
|
||||
else
|
||||
PKG_CHECK_MODULES(LIBPCI, libpci >= 3.0.0, [
|
||||
sysinfo=yes
|
||||
AC_DEFINE(HAVE_LIBPCI)
|
||||
], [sysinfo=no])
|
||||
fi
|
||||
PKG_CHECK_MODULES(LIBPCI, libpci >= 3.0.0, [sysinfo=yes], [sysinfo=no])
|
||||
else
|
||||
AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option for SysInfo])
|
||||
sysinfo=no
|
||||
@ -513,7 +526,8 @@ if test "x$dbus" = "xyes" ; then
|
||||
dbus=no
|
||||
])
|
||||
AC_PATH_PROG(DBUS_BINDING_TOOL, dbus-binding-tool, no)
|
||||
if test "x$DBUS_BINDING_TOOL" = "xno" || test "x$dbus" = "xno" ; then
|
||||
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
|
||||
dbus="no"
|
||||
else
|
||||
COMMON_LIBS="$COMMON_LIBS $DBUS_LIBS"
|
||||
@ -573,17 +587,6 @@ if test "x$isocodes" = "xyes" ; then
|
||||
])
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** Static Analysis **************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
if test "x$analyze" = "xyes"; then
|
||||
if test "$CC" != "clang"; then
|
||||
AC_MSG_WARN(CC is not clang for static analysis)
|
||||
analyze=no
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** CONDITIONALS *****************************************************
|
||||
dnl *********************************************************************
|
||||
@ -591,6 +594,7 @@ 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")
|
||||
@ -600,35 +604,128 @@ 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 ** CFLAGS ***********************************************************
|
||||
dnl ** SOCKS5 ***********************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
dnl these flags might be unwanted
|
||||
if test x$minimalflags != xyes; then
|
||||
CC_CHECK_FLAGS_APPEND([CFLAGS], [CFLAGS], [-g])
|
||||
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
|
||||
|
||||
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 \
|
||||
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])
|
||||
])
|
||||
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 ********************************************
|
||||
@ -648,7 +745,8 @@ AC_TRY_COMPILE(
|
||||
],
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
AC_CHECK_FUNCS(memrchr)
|
||||
dnl if we don\'t have this, use g_snprintf instead
|
||||
AC_CHECK_FUNCS(snprintf vsnprintf memrchr strtoull)
|
||||
|
||||
AC_CHECK_FUNC(gethostbyname, ,
|
||||
AC_CHECK_LIB(resolv, gethostbyname, ,
|
||||
@ -682,6 +780,7 @@ AC_EGREP_CPP(lookupd, dnl
|
||||
|
||||
dnl freebsd needs this
|
||||
LIBS="$LIBS $INTLLIBS"
|
||||
CFLAGS="$CFLAGS $CPPFLAGS"
|
||||
|
||||
GUI_LIBS="$GUI_LIBS $COMMON_LIBS"
|
||||
|
||||
@ -696,12 +795,12 @@ 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"
|
||||
@ -759,6 +858,8 @@ 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
|
||||
|
@ -1,60 +0,0 @@
|
||||
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
|
||||
])
|
||||
|
@ -1,8 +0,0 @@
|
||||
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)
|
||||
|
38
plugins/Make.plugin
Normal file
38
plugins/Make.plugin
Normal file
@ -0,0 +1,38 @@
|
||||
# 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
|
||||
|
||||
#
|
@ -2,6 +2,6 @@ libdir = $(hexchatlibdir)
|
||||
|
||||
lib_LTLIBRARIES = checksum.la
|
||||
checksum_la_SOURCES = checksum.c
|
||||
checksum_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
|
||||
checksum_la_LIBADD = $(GLIB_LIBS)
|
||||
checksum_la_CFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)/src/common
|
||||
checksum_la_LDFLAGS = -avoid-version -module
|
||||
checksum_la_LIBADD =
|
||||
AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/../../src/common
|
||||
|
@ -20,40 +20,131 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#ifdef __APPLE__
|
||||
#define __AVAILABILITYMACROS__
|
||||
#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
|
||||
#endif
|
||||
|
||||
#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>
|
||||
#include <glib/gstdio.h>
|
||||
#include <gio/gio.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 "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
|
||||
set_limit (char *size)
|
||||
sha256_hash_string (unsigned char hash[SHA256_DIGEST_LENGTH], char outputBuffer[65])
|
||||
{
|
||||
int limit = atoi (size);
|
||||
|
||||
if (limit > 0 && limit < INT_MAX)
|
||||
int i;
|
||||
for (i = 0; i < SHA256_DIGEST_LENGTH; 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);
|
||||
sprintf (outputBuffer + (i * 2), "%02x", hash[i]);
|
||||
}
|
||||
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++)
|
||||
{
|
||||
sprintf (outputBuffer + (i * 2), "%02x", hash[i]);
|
||||
}
|
||||
outputBuffer[64] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
sha256_file (char *path, char outputBuffer[65])
|
||||
{
|
||||
int bytesRead;
|
||||
unsigned char *buffer;
|
||||
unsigned char hash[SHA256_DIGEST_LENGTH];
|
||||
SHA256_CTX sha256;
|
||||
|
||||
FILE *file = fopen (path, "rb");
|
||||
if (!file)
|
||||
{
|
||||
return -534;
|
||||
}
|
||||
|
||||
SHA256_Init (&sha256);
|
||||
buffer = malloc (BUFSIZE);
|
||||
bytesRead = 0;
|
||||
|
||||
if (!buffer)
|
||||
{
|
||||
fclose (file);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
while ((bytesRead = fread (buffer, 1, BUFSIZE, file)))
|
||||
{
|
||||
SHA256_Update (&sha256, buffer, bytesRead);
|
||||
}
|
||||
|
||||
SHA256_Final (hash, &sha256);
|
||||
sha256_hash_string (hash, outputBuffer);
|
||||
|
||||
fclose (file);
|
||||
free (buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
set_limit (char* size)
|
||||
{
|
||||
int buffer = atoi (size);
|
||||
|
||||
if (buffer > 0 && buffer < INT_MAX)
|
||||
{
|
||||
if (hexchat_pluginpref_set_int (ph, "limit", buffer))
|
||||
{
|
||||
hexchat_printf (ph, "File size limit has successfully been set to: %d MiB\n", buffer);
|
||||
}
|
||||
else
|
||||
hexchat_printf (ph, "Checksum: File access error while saving!\n");
|
||||
{
|
||||
hexchat_printf (ph, "File access error while saving!\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hexchat_printf (ph, "Checksum: Invalid input!\n");
|
||||
hexchat_printf (ph, "Invalid input!\n");
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,152 +153,89 @@ get_limit ()
|
||||
{
|
||||
int size = hexchat_pluginpref_get_int (ph, "limit");
|
||||
|
||||
if (size <= 0 || size >= INT_MAX)
|
||||
if (size <= -1 || size >= INT_MAX)
|
||||
{
|
||||
return DEFAULT_LIMIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_limit (GFile *file)
|
||||
static void
|
||||
print_limit ()
|
||||
{
|
||||
GFileInfo *file_info;
|
||||
goffset file_size;
|
||||
|
||||
file_info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE,
|
||||
NULL, NULL);
|
||||
|
||||
if (!file_info)
|
||||
return FALSE;
|
||||
|
||||
file_size = g_file_info_get_size (file_info);
|
||||
g_object_unref (file_info);
|
||||
|
||||
if (file_size > get_limit () * 1048576ll)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sha256_from_stream (GFileInputStream *file_stream, char out_buf[])
|
||||
{
|
||||
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);
|
||||
|
||||
while ((bytes_read = g_input_stream_read (G_INPUT_STREAM (file_stream), buffer, sizeof (buffer), NULL, NULL)))
|
||||
{
|
||||
if (bytes_read == -1)
|
||||
{
|
||||
g_checksum_free (checksum);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_checksum_update (checksum, buffer, bytes_read);
|
||||
}
|
||||
|
||||
g_checksum_get_digest (checksum, digest, &digest_len);
|
||||
g_checksum_free (checksum);
|
||||
|
||||
for (i = 0; i < SHA256_DIGEST_LENGTH; i++)
|
||||
{
|
||||
/* out_buf will be exactly SHA256_BUFFER_LENGTH including null */
|
||||
g_sprintf (out_buf + (i * 2), "%02x", digest[i]);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
sha256_from_file (char *filename, char out_buf[])
|
||||
{
|
||||
GFileInputStream *file_stream;
|
||||
char *filename_fs;
|
||||
GFile *file;
|
||||
|
||||
filename_fs = g_filename_from_utf8 (filename, -1, NULL, NULL, NULL);
|
||||
if (!filename_fs)
|
||||
{
|
||||
hexchat_printf (ph, "Checksum: Invalid filename (%s)\n", filename);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
file = g_file_new_for_path (filename_fs);
|
||||
g_free (filename_fs);
|
||||
if (!file)
|
||||
{
|
||||
hexchat_printf (ph, "Checksum: Failed to open %s\n", filename);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!check_limit (file))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
file_stream = g_file_read (file, NULL, NULL);
|
||||
if (!file_stream)
|
||||
{
|
||||
hexchat_printf (ph, "Checksum: Failed to read file %s\n", filename);
|
||||
g_object_unref (file);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!sha256_from_stream (file_stream, out_buf))
|
||||
{
|
||||
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;
|
||||
hexchat_printf (ph, "File size limit for checksums: %d MiB", get_limit ());
|
||||
}
|
||||
|
||||
static int
|
||||
dccrecv_cb (char *word[], void *userdata)
|
||||
{
|
||||
const char *dcc_completed_dir;
|
||||
char *filename, checksum[SHA256_BUFFER_LENGTH];
|
||||
int result;
|
||||
struct stat buffer; /* buffer for storing file info */
|
||||
char sum[65]; /* buffer for checksum */
|
||||
const char *file;
|
||||
char *cfile;
|
||||
|
||||
/* 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))
|
||||
if (hexchat_get_prefs (ph, "dcc_completed_dir", &file, NULL) == 1 && file[0] != 0)
|
||||
{
|
||||
hexchat_printf (ph, "SHA-256 checksum for %s (local): %s\n", word[1], checksum);
|
||||
cfile = g_strconcat (file, G_DIR_SEPARATOR_S, word[1], NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
cfile = g_strdup(word[2]);
|
||||
}
|
||||
|
||||
g_free (filename);
|
||||
result = stat (cfile, &buffer);
|
||||
if (result == 0) /* stat returns 0 on success */
|
||||
{
|
||||
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]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hexchat_printf (ph, "File access error!\n");
|
||||
}
|
||||
|
||||
g_free (cfile);
|
||||
return HEXCHAT_EAT_NONE;
|
||||
}
|
||||
|
||||
static int
|
||||
dccoffer_cb (char *word[], void *userdata)
|
||||
{
|
||||
char checksum[SHA256_BUFFER_LENGTH];
|
||||
int result;
|
||||
struct stat buffer; /* buffer for storing file info */
|
||||
char sum[65]; /* buffer for checksum */
|
||||
|
||||
/* 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))
|
||||
result = stat (word[3], &buffer);
|
||||
if (result == 0) /* stat returns 0 on success */
|
||||
{
|
||||
hexchat_commandf (ph, "quote PRIVMSG %s :SHA-256 checksum for %s (remote): %s", word[2], word[1], checksum);
|
||||
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
|
||||
{
|
||||
hexchat_printf (ph, "File access error!\n");
|
||||
}
|
||||
|
||||
return HEXCHAT_EAT_NONE;
|
||||
@ -218,7 +246,7 @@ checksum (char *word[], char *word_eol[], void *userdata)
|
||||
{
|
||||
if (!g_ascii_strcasecmp ("GET", word[2]))
|
||||
{
|
||||
hexchat_printf (ph, "File size limit for checksums: %d MiB", get_limit ());
|
||||
print_limit ();
|
||||
}
|
||||
else if (!g_ascii_strcasecmp ("SET", word[2]))
|
||||
{
|
||||
@ -231,7 +259,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_ALL;
|
||||
return HEXCHAT_EAT_NONE;
|
||||
}
|
||||
|
||||
int
|
||||
@ -249,7 +277,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", NULL);
|
||||
hexchat_hook_command (ph, "CHECKSUM", HEXCHAT_PRI_NORM, checksum, "Usage: /CHECKSUM GET|SET", 0);
|
||||
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);
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
<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">
|
||||
@ -20,19 +19,57 @@
|
||||
<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" />
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\win32\hexchat.props" />
|
||||
<PropertyGroup>
|
||||
<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>$(HexChatRel)plugins\</OutDir>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>hcchecksum</TargetName>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</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;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</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>
|
||||
@ -40,10 +77,19 @@
|
||||
</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;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</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>
|
||||
@ -56,4 +102,6 @@
|
||||
<None Include="checksum.def" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -2,7 +2,7 @@ libdir = $(hexchatlibdir)
|
||||
|
||||
lib_LTLIBRARIES = doat.la
|
||||
doat_la_SOURCES = doat.c
|
||||
doat_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
|
||||
doat_la_LIBADD = $(GLIB_LIBS)
|
||||
doat_la_CFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)/src/common
|
||||
doat_la_LDFLAGS = -avoid-version -module
|
||||
doat_la_LIBADD =
|
||||
AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/../../src/common
|
||||
|
||||
|
@ -5,12 +5,9 @@
|
||||
* 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;
|
||||
@ -34,7 +31,7 @@ parse_command( char *word[], char *word_eol[], void *userdata ) {
|
||||
break;
|
||||
}
|
||||
|
||||
channel = g_strdup( token );
|
||||
channel = strdup( token );
|
||||
|
||||
delimiter = strchr( channel, '/' );
|
||||
|
||||
@ -43,13 +40,13 @@ parse_command( char *word[], char *word_eol[], void *userdata ) {
|
||||
*delimiter = '\0';
|
||||
|
||||
if( strlen( delimiter + 1 ) > 0 ) {
|
||||
server = g_strdup( delimiter + 1 );
|
||||
server = strdup( delimiter + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* /Network form */
|
||||
if( strlen( channel ) == 0 ) {
|
||||
g_free( channel );
|
||||
free( channel );
|
||||
channel = NULL;
|
||||
}
|
||||
|
||||
@ -61,8 +58,13 @@ parse_command( char *word[], char *word_eol[], void *userdata ) {
|
||||
}
|
||||
}
|
||||
|
||||
g_free( channel );
|
||||
g_free( server );
|
||||
if( channel != NULL ) {
|
||||
free( channel );
|
||||
}
|
||||
|
||||
if( server != NULL ) {
|
||||
free( server );
|
||||
}
|
||||
}
|
||||
}
|
||||
return HEXCHAT_EAT_HEXCHAT;
|
||||
|
@ -2,7 +2,6 @@
|
||||
<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">
|
||||
@ -20,32 +19,75 @@
|
||||
<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" />
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\win32\hexchat.props" />
|
||||
<PropertyGroup>
|
||||
<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>$(HexChatRel)plugins\</OutDir>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>hcdoat</TargetName>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</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;$(HexChatLib);$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<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;$(HexChatLib);$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>doat.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@ -56,4 +98,6 @@
|
||||
<None Include="doat.def" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -2,7 +2,6 @@
|
||||
<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">
|
||||
@ -20,28 +19,75 @@
|
||||
<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" />
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\win32\hexchat.props" />
|
||||
<PropertyGroup>
|
||||
<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>$(HexChatRel)plugins\</OutDir>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>hcexec</TargetName>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</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>
|
||||
@ -52,4 +98,6 @@
|
||||
<ClCompile Include="exec.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -3,7 +3,7 @@ EXTRA_DIST = INSTALL LICENSE
|
||||
libdir = $(hexchatlibdir)
|
||||
|
||||
lib_LTLIBRARIES = fishlim.la
|
||||
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
|
||||
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
|
||||
|
@ -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,11 +75,12 @@ char *fish_encrypt(const char *key, size_t keylen, const char *message) {
|
||||
|
||||
messagelen = strlen(message);
|
||||
if (messagelen == 0) return NULL;
|
||||
encrypted = g_malloc(((messagelen - 1) / 8) * 12 + 12 + 1); /* each 8-byte block becomes 12 bytes */
|
||||
encrypted = 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++) {
|
||||
@ -89,10 +90,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++) {
|
||||
@ -105,7 +106,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';
|
||||
@ -123,11 +124,12 @@ 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 = g_malloc(strlen(data) + 1);
|
||||
decrypted = 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;
|
||||
@ -142,10 +144,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]);
|
||||
}
|
||||
@ -163,14 +165,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);
|
||||
|
||||
g_free(key);
|
||||
free(key);
|
||||
return encrypted;
|
||||
}
|
||||
|
||||
@ -181,14 +183,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);
|
||||
|
||||
g_free(key);
|
||||
free(key);
|
||||
return decrypted;
|
||||
}
|
||||
|
||||
|
@ -25,10 +25,9 @@
|
||||
#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);
|
||||
|
@ -2,7 +2,6 @@
|
||||
<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">
|
||||
@ -20,19 +19,57 @@
|
||||
<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" />
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\win32\hexchat.props" />
|
||||
<PropertyGroup>
|
||||
<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>$(HexChatRel)plugins\</OutDir>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>hcfishlim</TargetName>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</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>
|
||||
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;%(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>
|
||||
@ -40,10 +77,19 @@
|
||||
</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>
|
||||
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;%(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>
|
||||
@ -57,13 +103,17 @@
|
||||
<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" />
|
||||
</Project>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -32,6 +32,9 @@
|
||||
<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>
|
||||
@ -46,6 +49,9 @@
|
||||
<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>
|
||||
|
@ -22,9 +22,8 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "irc.h"
|
||||
|
||||
/**
|
||||
@ -32,26 +31,26 @@
|
||||
* at spaces. The prefix and command is extracted from the message, and
|
||||
* parameters_offset is set to the index of the first parameter.
|
||||
*/
|
||||
gboolean irc_parse_message(const char *words[],
|
||||
bool 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;
|
||||
}
|
||||
|
||||
|
||||
@ -66,15 +65,48 @@ gboolean 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;
|
||||
return g_strndup (prefix, length);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,13 +25,14 @@
|
||||
#ifndef IRC_H
|
||||
#define IRC_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <glib.h>
|
||||
|
||||
gboolean irc_parse_message(const char *words[],
|
||||
bool 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
|
||||
|
||||
|
@ -22,13 +22,12 @@
|
||||
|
||||
*/
|
||||
|
||||
#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"
|
||||
|
||||
@ -58,7 +57,7 @@ static GKeyFile *getConfigFile() {
|
||||
static const char *get_keystore_password() {
|
||||
return (keystore_password != NULL ?
|
||||
keystore_password :
|
||||
/* Silly default value... */
|
||||
// Silly default value...
|
||||
"blowinikey");
|
||||
}
|
||||
|
||||
@ -88,17 +87,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 value;
|
||||
// Key is stored in plaintext
|
||||
return import_glib_string(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);
|
||||
@ -110,10 +109,10 @@ char *keystore_get_key(const char *nick) {
|
||||
/**
|
||||
* Deletes a nick and the associated key in the key store file.
|
||||
*/
|
||||
static gboolean delete_nick(GKeyFile *keyfile, const char *nick) {
|
||||
static bool delete_nick(GKeyFile *keyfile, const char *nick) {
|
||||
gchar **group;
|
||||
gchar **groups = g_key_file_get_groups(keyfile, NULL);
|
||||
gboolean ok = FALSE;
|
||||
bool ok = false;
|
||||
|
||||
for (group = groups; *group != NULL; group++) {
|
||||
if (!irc_nick_cmp(*group, nick)) {
|
||||
@ -126,77 +125,58 @@ static gboolean delete_nick(GKeyFile *keyfile, const char *nick) {
|
||||
return ok;
|
||||
}
|
||||
|
||||
#if !GLIB_CHECK_VERSION(2,40,0)
|
||||
/**
|
||||
* Writes the key store file to disk.
|
||||
*/
|
||||
static gboolean keyfile_save_to_file (GKeyFile *keyfile, char *filename) {
|
||||
gboolean ok;
|
||||
|
||||
/* Serialize */
|
||||
static bool save_keystore(GKeyFile *keyfile) {
|
||||
char *filename;
|
||||
bool 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 */
|
||||
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;
|
||||
|
||||
if (!file_data) return false;
|
||||
|
||||
// Write to file
|
||||
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);
|
||||
|
||||
ok = g_file_set_contents(filename, file_data, file_length, NULL);
|
||||
g_free(filename);
|
||||
g_free(file_data);
|
||||
return ok;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a key in the key store file.
|
||||
*/
|
||||
gboolean keystore_store_key(const char *nick, const char *key) {
|
||||
bool keystore_store_key(const char *nick, const char *key) {
|
||||
const char *password;
|
||||
char *encrypted;
|
||||
char *wrapped;
|
||||
gboolean ok = FALSE;
|
||||
bool 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);
|
||||
g_free(wrapped);
|
||||
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:
|
||||
@ -207,15 +187,23 @@ gboolean keystore_store_key(const char *nick, const char *key) {
|
||||
/**
|
||||
* Deletes a nick from the key store.
|
||||
*/
|
||||
gboolean keystore_delete_nick(const char *nick) {
|
||||
bool keystore_delete_nick(const char *nick) {
|
||||
GKeyFile *keyfile = getConfigFile();
|
||||
|
||||
/* Delete entry */
|
||||
gboolean ok = delete_nick(keyfile, nick);
|
||||
// Delete entry
|
||||
bool 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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,13 +25,14 @@
|
||||
#ifndef KEYSTORE_H
|
||||
#define KEYSTORE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
char *keystore_get_key(const char *nick);
|
||||
gboolean keystore_store_key(const char *nick, const char *key);
|
||||
gboolean keystore_delete_nick(const char *nick);
|
||||
bool keystore_store_key(const char *nick, const char *key);
|
||||
bool keystore_delete_nick(const char *nick);
|
||||
|
||||
void keystore_secure_free(void *ptr, size_t size);
|
||||
|
||||
#endif
|
||||
|
||||
|
54
plugins/fishlim/misc.c
Normal file
54
plugins/fishlim/misc.c
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
36
plugins/fishlim/misc.h
Normal file
36
plugins/fishlim/misc.h
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
|
||||
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
|
||||
|
||||
|
@ -22,14 +22,17 @@
|
||||
|
||||
*/
|
||||
|
||||
#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"
|
||||
@ -49,19 +52,27 @@ static hexchat_plugin *ph;
|
||||
* Returns the path to the key store file.
|
||||
*/
|
||||
gchar *get_config_filename() {
|
||||
char *filename_fs, *filename_utf8;
|
||||
|
||||
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;
|
||||
return g_build_filename(hexchat_get_info(ph, "configdir"), "addon_fishlim.conf", NULL);
|
||||
}
|
||||
|
||||
int irc_nick_cmp(const char *a, const char *b) {
|
||||
return hexchat_nickcmp (ph, a, b);
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
/*static int handle_debug(char *word[], char *word_eol[], void *userdata) {
|
||||
hexchat_printf(ph, "debug incoming: ");
|
||||
for (size_t i = 1; word[i] != NULL && word[i][0] != '\0'; i++) {
|
||||
@ -76,26 +87,26 @@ int irc_nick_cmp(const char *a, const char *b) {
|
||||
*/
|
||||
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);
|
||||
|
||||
g_free(encrypted);
|
||||
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[], hexchat_event_attrs *attrs, void *userdata) {
|
||||
static int handle_incoming(char *word[], char *word_eol[], void *userdata) {
|
||||
const char *prefix;
|
||||
const char *command;
|
||||
const char *recipient;
|
||||
@ -103,19 +114,20 @@ static int handle_incoming(char *word[], char *word_eol[], hexchat_event_attrs *
|
||||
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++); }
|
||||
@ -124,70 +136,61 @@ static int handle_incoming(char *word[], char *word_eol[], hexchat_event_attrs *
|
||||
}
|
||||
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 = 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);
|
||||
}
|
||||
|
||||
// Build unecrypted message
|
||||
message = NULL;
|
||||
length = 0;
|
||||
if (!append(&message, &length, "RECV")) goto decrypt_error;
|
||||
|
||||
for (uw = 1; uw < HEXCHAT_MAX_WORDS; uw++) {
|
||||
if (word[uw][0] != '\0')
|
||||
g_string_append_c (message, ' ');
|
||||
if (word[uw][0] != '\0' && !append(&message, &length, " ")) goto decrypt_error;
|
||||
|
||||
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 */
|
||||
g_string_append_c (message, ':');
|
||||
// Prefix with colon, which gets stripped out otherwise
|
||||
if (!append(&message, &length, ":")) goto decrypt_error;
|
||||
}
|
||||
|
||||
if (prefix_char) {
|
||||
g_string_append_c (message, prefix_char);
|
||||
char prefix_str[2] = { prefix_char, '\0' };
|
||||
if (!append(&message, &length, prefix_str)) goto decrypt_error;
|
||||
}
|
||||
|
||||
} 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];
|
||||
}
|
||||
|
||||
g_string_append (message, peice);
|
||||
|
||||
if (!append(&message, &length, peice)) goto decrypt_error;
|
||||
}
|
||||
g_free(decrypted);
|
||||
free(decrypted);
|
||||
|
||||
/* 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);
|
||||
// Simulate unencrypted message
|
||||
//hexchat_printf(ph, "simulating: %s\n", message);
|
||||
hexchat_command(ph, message);
|
||||
|
||||
free(message);
|
||||
free(sender_nick);
|
||||
return HEXCHAT_EAT_HEXCHAT;
|
||||
|
||||
decrypt_error:
|
||||
g_free(decrypted);
|
||||
g_free(sender_nick);
|
||||
free(decrypted);
|
||||
free(sender_nick);
|
||||
return HEXCHAT_EAT_NONE;
|
||||
}
|
||||
|
||||
@ -198,23 +201,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 {
|
||||
@ -230,15 +233,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 = g_strstrip (word_eol[2]);
|
||||
nick = 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 {
|
||||
@ -279,11 +282,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_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_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_printf(ph, "%s plugin loaded\n", plugin_name);
|
||||
/* Return success */
|
||||
|
@ -26,7 +26,6 @@
|
||||
#define PLUGIN_HEXCHAT_H
|
||||
|
||||
gchar *get_config_filename();
|
||||
int irc_nick_cmp (const char *, const char *);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -47,7 +47,7 @@ static int decrypt(int nick_count, char *nicks[]) {
|
||||
return 1;
|
||||
success:
|
||||
fprintf(stderr, "Decrypted text >>>%s<<<\n", msg);
|
||||
g_free(msg);
|
||||
free(msg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -64,7 +64,7 @@ static int encrypt(int nick_count, char *nicks[]) {
|
||||
char *encrypted = fish_encrypt_for_nick(nicks[i], message);
|
||||
if (encrypted) {
|
||||
fprintf(stderr, "Encrypted [%s]: >>>%s<<<\n", nicks[i], encrypted);
|
||||
g_free(encrypted);
|
||||
free(encrypted);
|
||||
} else {
|
||||
error = true;
|
||||
}
|
||||
|
@ -14,27 +14,54 @@
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
/*
|
||||
typedef int (*MYPROC)(HWND,HWND,char*,char*,BOOL,BOOL);
|
||||
|
||||
char *split(char *text, char separator)
|
||||
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;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
int dllProc(char *name, char *data)
|
||||
{
|
||||
int pos = -1;
|
||||
size_t i;
|
||||
for (i = 0; i < strlen(text); i++)
|
||||
static HMODULE lib = NULL;
|
||||
if (!lib)
|
||||
{
|
||||
if (text[i] == separator) {
|
||||
pos = i;
|
||||
i = strlen(text) + 1;
|
||||
lib = LoadLibraryA ("mpcinfo");
|
||||
if (!lib)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
FreeLibrary (lib);
|
||||
}
|
||||
|
||||
if (pos == -1)
|
||||
{
|
||||
return text;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
*/
|
||||
|
||||
text[pos] = 0;
|
||||
return &(text[pos + 1]);
|
||||
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]);
|
||||
}
|
||||
|
||||
int endsWith(char *text, char *suffix){
|
||||
@ -44,32 +71,21 @@ int endsWith(char *text, char *suffix){
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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 = g_new (char, length + 1);
|
||||
char *ret=(char*) calloc (length+1,sizeof(char)); //malloc(sizeof(char)*(length+1));
|
||||
int i;
|
||||
ret[length]=0;
|
||||
for (i=0;i<length;i++){
|
||||
@ -91,7 +107,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 = g_new (char, 1024);
|
||||
char *buffer=(char*)calloc(1024,sizeof(char)); //malloc(sizeof(char)*1024);
|
||||
int pos=0;
|
||||
int cc=0;
|
||||
while((cc!=EOF)&&(pos<1024)&&(cc!=10)){
|
||||
@ -105,19 +121,14 @@ char *readLine(FILE *f){
|
||||
return buffer;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
static char *str3cat(char *s1, char *s2, char *s3){
|
||||
|
@ -75,25 +75,62 @@ 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)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
ret += ((int) text[strlen(text) - i] - 48)*iPow(10, i - 1);
|
||||
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';
|
||||
}
|
||||
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;
|
||||
@ -167,28 +204,23 @@ struct tagInfo readID3V1(char *file){
|
||||
return ret;
|
||||
}
|
||||
|
||||
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";
|
||||
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";
|
||||
}
|
||||
|
||||
struct tagInfo readID3V2(char *file){
|
||||
|
@ -48,20 +48,12 @@ 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 = g_new(char, 1024);
|
||||
tTitle=(char*)malloc(sizeof(char)*1024);
|
||||
GetWindowText(hwnd, tTitle, 1024);
|
||||
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;
|
||||
}
|
||||
|
||||
zero=strstr(tTitle," - Media Player Classic");
|
||||
if (zero!=NULL) zero[0]=0;
|
||||
else hexchat_print(ph,"pattern not found");
|
||||
|
||||
if ((tTitle[1]==':')&&(tTitle[2]=='\\')){
|
||||
//hexchat_print(ph,"seams to be full path");
|
||||
if (endsWith(tTitle,".mp3")==1){
|
||||
@ -90,8 +82,7 @@ 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);
|
||||
g_free(tTitle);
|
||||
hexchat_command(ph, mp3Line);
|
||||
hexchat_command(ph, mp3Line);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
}
|
||||
@ -120,16 +111,14 @@ 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);
|
||||
g_free(tTitle);
|
||||
hexchat_command(ph, oggLine);
|
||||
hexchat_command(ph, oggLine);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
}
|
||||
}
|
||||
line=randomLine(titleTheme);
|
||||
line=replace(line,"%title", tTitle);
|
||||
g_free(tTitle);
|
||||
hexchat_command(ph, line);
|
||||
hexchat_command(ph,line);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
<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">
|
||||
@ -20,32 +19,75 @@
|
||||
<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" />
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\win32\hexchat.props" />
|
||||
<PropertyGroup>
|
||||
<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>$(HexChatRel)plugins\</OutDir>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>hcmpcinfo</TargetName>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</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>
|
||||
<AdditionalIncludeDirectories>..\..\src\common;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<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>
|
||||
<AdditionalIncludeDirectories>..\..\src\common;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>mpcinfo.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@ -56,4 +98,6 @@
|
||||
<ClCompile Include="mpcInfo.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -25,18 +25,14 @@ static int getOggInt(char *buff, int beg, int bytes){
|
||||
return 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;
|
||||
|
||||
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);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -49,32 +49,24 @@ void printThemes(){
|
||||
hexchat_printf(ph,"\nTitle-Theme:\n");printTheme(titleTheme);
|
||||
}
|
||||
|
||||
void cbFix(char *line)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < strlen(line); i++)
|
||||
{
|
||||
size_t j;
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
||||
struct theme themeAdd(struct theme data, char *info){
|
||||
|
@ -6,13 +6,12 @@ libdir = $(hexchatlibdir)
|
||||
|
||||
lib_LTLIBRARIES = perl.la
|
||||
perl_la_SOURCES = perl.c
|
||||
perl_la_LDFLAGS = $(PERL_LDFLAGS) $(PLUGIN_LDFLAGS) -module
|
||||
perl_la_LIBADD = $(PERL_LIBS) $(GLIB_LIBS)
|
||||
perl_la_CFLAGS = $(PERL_CFLAGS) $(GLIB_CFLAGS) -I$(top_srcdir)/src/common
|
||||
|
||||
perl_la_LDFLAGS = -avoid-version -module
|
||||
perl_la_LIBADD = $(PERL_LDFLAGS)
|
||||
BUILT_SOURCES = hexchat.pm.h irc.pm.h
|
||||
CLEANFILES = $(BUILT_SOURCES)
|
||||
|
||||
#CFLAGS = @CFLAGS@ -Wno-unused
|
||||
AM_CPPFLAGS = $(PERL_CFLAGS) $(COMMON_CFLAGS) -I$(srcdir)/../../src/common
|
||||
CLEANFILES = hexchat.pm.h irc.pm.h
|
||||
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
|
||||
|
@ -16,8 +16,6 @@
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -33,9 +31,8 @@
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#undef PACKAGE
|
||||
#include "../../config.h"
|
||||
|
||||
#include "hexchat-plugin.h"
|
||||
|
||||
@ -78,26 +75,37 @@ thread_mbox (char *str)
|
||||
static void
|
||||
perl_auto_load_from_path (const char *path)
|
||||
{
|
||||
char *search_path = g_build_filename (path, "*.pl", NULL);
|
||||
WIN32_FIND_DATAA find_data;
|
||||
HANDLE find_handle = FindFirstFileA (search_path, &find_data);
|
||||
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);
|
||||
|
||||
if (find_handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do
|
||||
{
|
||||
if ((find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0 && (find_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == 0)
|
||||
if (!(find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
|
||||
||find_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
|
||||
{
|
||||
char *full_path = g_build_filename (path, find_data.cFileName, NULL);
|
||||
char *full_path =
|
||||
malloc (path_len + strlen (find_data.cFileName) + 2);
|
||||
sprintf (full_path, "%s\\%s", path, find_data.cFileName);
|
||||
|
||||
perl_load_file (full_path);
|
||||
g_free (full_path);
|
||||
free (full_path);
|
||||
}
|
||||
}
|
||||
while (FindNextFileA (find_handle, &find_data) != 0);
|
||||
while (FindNextFile (find_handle, &find_data) != 0);
|
||||
FindClose (find_handle);
|
||||
}
|
||||
|
||||
g_free (search_path);
|
||||
free (search_path);
|
||||
}
|
||||
#else
|
||||
static void
|
||||
@ -107,16 +115,14 @@ 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 = g_build_filename (path, ent->d_name, NULL);
|
||||
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);
|
||||
perl_load_file (file);
|
||||
g_free (file);
|
||||
free (file);
|
||||
}
|
||||
}
|
||||
closedir (dir);
|
||||
@ -139,10 +145,31 @@ 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 */
|
||||
sub_dir = g_build_filename (xdir, "addons", NULL);
|
||||
perl_auto_load_from_path (sub_dir);
|
||||
g_free (sub_dir);
|
||||
#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");
|
||||
perl_auto_load_from_path (sub_dir);
|
||||
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;
|
||||
}
|
||||
|
||||
@ -261,19 +288,7 @@ list_item_to_sv ( hexchat_list *list, const char *const *fields )
|
||||
field_value = newSVuv (hexchat_list_int (ph, list, field_name));
|
||||
break;
|
||||
case 't':
|
||||
/* 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));
|
||||
field_value = newSVnv (hexchat_list_time (ph, list, field_name));
|
||||
break;
|
||||
default:
|
||||
field_value = &PL_sv_undef;
|
||||
@ -357,7 +372,7 @@ fd_cb (int fd, int flags, void *userdata)
|
||||
if (data->userdata) {
|
||||
SvREFCNT_dec (data->userdata);
|
||||
}
|
||||
g_free (data);
|
||||
free (data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -721,7 +736,7 @@ XS (XS_HexChat_send_modes)
|
||||
if (SvROK (ST (0))) {
|
||||
p_targets = (AV*) SvRV (ST (0));
|
||||
target_count = av_len (p_targets) + 1;
|
||||
targets = g_new (const char *, target_count);
|
||||
targets = malloc (target_count * sizeof (char *));
|
||||
for (i = 0; i < target_count; i++ ) {
|
||||
elem = av_fetch (p_targets, i, 0);
|
||||
|
||||
@ -732,13 +747,13 @@ XS (XS_HexChat_send_modes)
|
||||
}
|
||||
}
|
||||
} else{
|
||||
targets = g_new (const char *, 1);
|
||||
targets = malloc (sizeof (char *));
|
||||
targets[0] = SvPV_nolen (ST (0));
|
||||
target_count = 1;
|
||||
}
|
||||
|
||||
if (target_count == 0) {
|
||||
g_free ((char**) targets);
|
||||
free (targets);
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
@ -750,7 +765,7 @@ XS (XS_HexChat_send_modes)
|
||||
}
|
||||
|
||||
hexchat_send_modes (ph, targets, target_count, modes_per_line, sign, mode);
|
||||
g_free ((char**) targets);
|
||||
free (targets);
|
||||
}
|
||||
}
|
||||
static
|
||||
@ -868,7 +883,11 @@ XS (XS_HexChat_hook_server)
|
||||
userdata = ST (3);
|
||||
package = ST (4);
|
||||
data = NULL;
|
||||
data = g_new (HookData, 1);
|
||||
data = malloc (sizeof (HookData));
|
||||
if (data == NULL) {
|
||||
XSRETURN_UNDEF;
|
||||
}
|
||||
|
||||
data->callback = newSVsv (callback);
|
||||
data->userdata = newSVsv (userdata);
|
||||
data->depth = 0;
|
||||
@ -913,7 +932,11 @@ XS (XS_HexChat_hook_command)
|
||||
package = ST (5);
|
||||
data = NULL;
|
||||
|
||||
data = g_new (HookData, 1);
|
||||
data = malloc (sizeof (HookData));
|
||||
if (data == NULL) {
|
||||
XSRETURN_UNDEF;
|
||||
}
|
||||
|
||||
data->callback = newSVsv (callback);
|
||||
data->userdata = newSVsv (userdata);
|
||||
data->depth = 0;
|
||||
@ -949,7 +972,11 @@ XS (XS_HexChat_hook_print)
|
||||
userdata = ST (3);
|
||||
package = ST (4);
|
||||
|
||||
data = g_new (HookData, 1);
|
||||
data = malloc (sizeof (HookData));
|
||||
if (data == NULL) {
|
||||
XSRETURN_UNDEF;
|
||||
}
|
||||
|
||||
data->callback = newSVsv (callback);
|
||||
data->userdata = newSVsv (userdata);
|
||||
data->depth = 0;
|
||||
@ -983,7 +1010,11 @@ XS (XS_HexChat_hook_timer)
|
||||
userdata = ST (2);
|
||||
package = ST (3);
|
||||
|
||||
data = g_new (HookData, 1);
|
||||
data = malloc (sizeof (HookData));
|
||||
if (data == NULL) {
|
||||
XSRETURN_UNDEF;
|
||||
}
|
||||
|
||||
data->callback = newSVsv (callback);
|
||||
data->userdata = newSVsv (userdata);
|
||||
data->ctx = hexchat_get_context (ph);
|
||||
@ -1033,7 +1064,11 @@ XS (XS_HexChat_hook_fd)
|
||||
}
|
||||
#endif
|
||||
|
||||
data = g_new (HookData, 1);
|
||||
data = malloc (sizeof (HookData));
|
||||
if (data == NULL) {
|
||||
XSRETURN_UNDEF;
|
||||
}
|
||||
|
||||
data->callback = newSVsv (callback);
|
||||
data->userdata = newSVsv (userdata);
|
||||
data->depth = 0;
|
||||
@ -1073,7 +1108,7 @@ XS (XS_HexChat_unhook)
|
||||
SvREFCNT_dec (userdata->package);
|
||||
}
|
||||
|
||||
g_free (userdata);
|
||||
free (userdata);
|
||||
}
|
||||
XSRETURN (retCount);
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
<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">
|
||||
@ -20,28 +19,66 @@
|
||||
<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" />
|
||||
<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>
|
||||
<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>
|
||||
</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>$(IntDir);..\..\src\common;$(HexChatLib);$(PerlPath)\lib\CORE;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(PerlPath)\lib\CORE;$(IntDir);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(IntDir);$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(PerlLib).lib;$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(PerlLib).lib;%(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:$(IntDir)\$(PerlLib).lib"
|
||||
lib /nologo /machine:x86 "/def:$(IntDir)$(PerlLib).def" "/out:$(OutDir)\$(PerlLib).lib"
|
||||
"$(PerlPath)\bin\perl.exe" generate_header
|
||||
move irc.pm.h "$(IntDir)"
|
||||
move hexchat.pm.h "$(IntDir)"</Command>
|
||||
@ -49,19 +86,28 @@ 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>$(IntDir);..\..\src\common;$(HexChatLib);$(PerlPath)\lib\CORE;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(PerlPath)\lib\CORE;$(IntDir);..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(IntDir);$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(PerlLib).lib;$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(PerlLib).lib;%(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:$(IntDir)\$(PerlLib).lib"
|
||||
lib /nologo /machine:x64 "/def:$(IntDir)$(PerlLib).def" "/out:$(OutDir)\$(PerlLib).lib"
|
||||
"$(PerlPath)\bin\perl.exe" generate_header
|
||||
move irc.pm.h "$(IntDir)"
|
||||
move hexchat.pm.h "$(IntDir)"</Command>
|
||||
@ -74,4 +120,6 @@ move hexchat.pm.h "$(IntDir)"</Command>
|
||||
<ClCompile Include="perl.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
19
plugins/plugin-conf.in
Normal file
19
plugins/plugin-conf.in
Normal file
@ -0,0 +1,19 @@
|
||||
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
|
||||
)
|
@ -1,8 +1,10 @@
|
||||
EXTRA_DIST =
|
||||
|
||||
libdir = $(hexchatlibdir)
|
||||
|
||||
lib_LTLIBRARIES = python.la
|
||||
python_la_SOURCES = python.c
|
||||
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
|
||||
python_la_LDFLAGS = -avoid-version -module
|
||||
python_la_LIBADD = $(PY_LIBS)
|
||||
AM_CPPFLAGS = $(PY_CFLAGS) $(COMMON_CFLAGS) -I$(srcdir)/../../src/common
|
||||
|
||||
|
@ -51,8 +51,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <string.h>
|
||||
@ -66,9 +64,9 @@
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#include "../../config.h"
|
||||
#include "hexchat-plugin.h"
|
||||
#undef _POSIX_C_SOURCE /* Avoid warnings from /usr/include/features.h */
|
||||
#undef _XOPEN_SOURCE
|
||||
#undef _POSIX_C_SOURCE /* Avoid warning: also in /usr/include/features.h from glib.h */
|
||||
#include <Python.h>
|
||||
#include <structmember.h>
|
||||
#include <pythread.h>
|
||||
@ -451,8 +449,10 @@ Util_BuildEOLList(char *word[])
|
||||
PyList_SetItem(list, i - 1, uni_part);
|
||||
}
|
||||
|
||||
g_free (last);
|
||||
g_free (accum);
|
||||
if (last)
|
||||
g_free (last);
|
||||
if (accum)
|
||||
g_free (accum);
|
||||
|
||||
return list;
|
||||
}
|
||||
@ -802,7 +802,9 @@ 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 GString *xchatout_buffer = NULL;
|
||||
static char *xchatout_buffer = NULL;
|
||||
static int xchatout_buffer_size = 0;
|
||||
static int xchatout_buffer_pos = 0;
|
||||
|
||||
static PyObject *
|
||||
XChatOut_New()
|
||||
@ -826,42 +828,76 @@ XChatOut_dealloc(PyObject *self)
|
||||
static PyObject *
|
||||
XChatOut_write(PyObject *self, PyObject *args)
|
||||
{
|
||||
gboolean add_space;
|
||||
int new_buffer_pos, data_size, print_limit, add_space;
|
||||
char *data, *pos;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:write", &data))
|
||||
if (!PyArg_ParseTuple(args, "s#:write", &data, &data_size))
|
||||
return NULL;
|
||||
if (!data || !*data) {
|
||||
Py_RETURN_NONE;
|
||||
if (!data_size) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
BEGIN_XCHAT_CALLS(RESTORE_CONTEXT|ALLOW_THREADS);
|
||||
if (((XChatOutObject *)self)->softspace) {
|
||||
add_space = TRUE;
|
||||
add_space = 1;
|
||||
((XChatOutObject *)self)->softspace = 0;
|
||||
} else {
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
exit:
|
||||
END_XCHAT_CALLS();
|
||||
Py_RETURN_NONE;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
#define OFF(x) offsetof(XChatOutObject, x)
|
||||
@ -1013,7 +1049,8 @@ Context_set(ContextObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *plugin = Plugin_GetCurrent();
|
||||
Plugin_SetContext(plugin, self->context);
|
||||
Py_RETURN_NONE;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
@ -1026,7 +1063,8 @@ Context_command(ContextObject *self, PyObject *args)
|
||||
hexchat_set_context(ph, self->context);
|
||||
hexchat_command(ph, text);
|
||||
END_XCHAT_CALLS();
|
||||
Py_RETURN_NONE;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
@ -1039,7 +1077,8 @@ Context_prnt(ContextObject *self, PyObject *args)
|
||||
hexchat_set_context(ph, self->context);
|
||||
hexchat_print(ph, text);
|
||||
END_XCHAT_CALLS();
|
||||
Py_RETURN_NONE;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
@ -1084,7 +1123,8 @@ Context_get_info(ContextObject *self, PyObject *args)
|
||||
info = hexchat_get_info(ph, name);
|
||||
END_XCHAT_CALLS();
|
||||
if (info == NULL) {
|
||||
Py_RETURN_NONE;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
return PyUnicode_FromString(info);
|
||||
}
|
||||
@ -1367,7 +1407,11 @@ static Hook *
|
||||
Plugin_AddHook(int type, PyObject *plugin, PyObject *callback,
|
||||
PyObject *userdata, char *name, void *data)
|
||||
{
|
||||
Hook *hook = g_new(Hook, 1);
|
||||
Hook *hook = (Hook *) g_malloc(sizeof(Hook));
|
||||
if (hook == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
hook->type = type;
|
||||
hook->plugin = plugin;
|
||||
Py_INCREF(callback);
|
||||
@ -1421,7 +1465,8 @@ Plugin_RemoveHook(PyObject *plugin, Hook *hook)
|
||||
hook));
|
||||
Py_DECREF(hook->callback);
|
||||
Py_DECREF(hook->userdata);
|
||||
g_free(hook->name);
|
||||
if (hook->name)
|
||||
g_free(hook->name);
|
||||
g_free(hook);
|
||||
}
|
||||
}
|
||||
@ -1440,7 +1485,8 @@ Plugin_RemoveAllHooks(PyObject *plugin)
|
||||
}
|
||||
Py_DECREF(hook->callback);
|
||||
Py_DECREF(hook->userdata);
|
||||
g_free(hook->name);
|
||||
if (hook->name)
|
||||
g_free(hook->name);
|
||||
g_free(hook);
|
||||
list = list->next;
|
||||
}
|
||||
@ -1669,7 +1715,8 @@ Module_hexchat_command(PyObject *self, PyObject *args)
|
||||
BEGIN_XCHAT_CALLS(RESTORE_CONTEXT|ALLOW_THREADS);
|
||||
hexchat_command(ph, text);
|
||||
END_XCHAT_CALLS();
|
||||
Py_RETURN_NONE;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
@ -1681,7 +1728,8 @@ Module_xchat_prnt(PyObject *self, PyObject *args)
|
||||
BEGIN_XCHAT_CALLS(RESTORE_CONTEXT|ALLOW_THREADS);
|
||||
hexchat_print(ph, text);
|
||||
END_XCHAT_CALLS();
|
||||
Py_RETURN_NONE;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
@ -1724,7 +1772,8 @@ Module_hexchat_get_info(PyObject *self, PyObject *args)
|
||||
info = hexchat_get_info(ph, name);
|
||||
END_XCHAT_CALLS();
|
||||
if (info == NULL) {
|
||||
Py_RETURN_NONE;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
if (strcmp (name, "gtkwin_ptr") == 0)
|
||||
return PyUnicode_FromFormat("%p", info); /* format as pointer */
|
||||
@ -1777,7 +1826,8 @@ Module_hexchat_get_context(PyObject *self, PyObject *args)
|
||||
return NULL;
|
||||
ctxobj = Context_FromContext(Plugin_GetContext(plugin));
|
||||
if (ctxobj == NULL) {
|
||||
Py_RETURN_NONE;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
return ctxobj;
|
||||
}
|
||||
@ -1794,7 +1844,8 @@ Module_hexchat_find_context(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
return NULL;
|
||||
ctxobj = Context_FromServerAndChannel(server, channel);
|
||||
if (ctxobj == NULL) {
|
||||
Py_RETURN_NONE;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
return ctxobj;
|
||||
}
|
||||
@ -1840,7 +1891,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();
|
||||
@ -2174,7 +2225,8 @@ Module_hexchat_unhook(PyObject *self, PyObject *args)
|
||||
Plugin_RemoveHook(plugin, hook);
|
||||
}
|
||||
|
||||
Py_RETURN_NONE;
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
@ -2482,8 +2534,11 @@ IInterp_Exec(char *command)
|
||||
}
|
||||
d = PyModule_GetDict(m);
|
||||
len = strlen(command);
|
||||
|
||||
buffer = g_malloc(len + 2);
|
||||
buffer = (char *) g_malloc(len+2);
|
||||
if (buffer == NULL) {
|
||||
hexchat_print(ph, "Not enough memory for command buffer");
|
||||
goto fail;
|
||||
}
|
||||
memcpy(buffer, command, len);
|
||||
buffer[len] = '\n';
|
||||
buffer[len+1] = 0;
|
||||
@ -2729,7 +2784,6 @@ 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");
|
||||
@ -2800,8 +2854,10 @@ hexchat_plugin_deinit()
|
||||
plugin_list = NULL;
|
||||
|
||||
/* Reset xchatout buffer. */
|
||||
g_string_free (xchatout_buffer, TRUE);
|
||||
g_free(xchatout_buffer);
|
||||
xchatout_buffer = NULL;
|
||||
xchatout_buffer_size = 0;
|
||||
xchatout_buffer_pos = 0;
|
||||
|
||||
if (interp_plugin) {
|
||||
Py_DECREF(interp_plugin);
|
||||
|
@ -2,7 +2,6 @@
|
||||
<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">
|
||||
@ -20,33 +19,80 @@
|
||||
<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" />
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\win32\hexchat.props" />
|
||||
<PropertyGroup>
|
||||
<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>$(HexChatRel)plugins\</OutDir>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>$(Python2Output)</TargetName>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</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;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(Glib);$(Python2Path)\include;..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</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;$(Python2Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;$(OutDir);$(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;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(Glib);$(Python2Path)\include;..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</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;$(Python2Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;$(OutDir);$(Python2Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
@ -56,4 +102,6 @@
|
||||
<ClCompile Include="python.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -2,7 +2,6 @@
|
||||
<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">
|
||||
@ -20,33 +19,80 @@
|
||||
<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" />
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\win32\hexchat.props" />
|
||||
<PropertyGroup>
|
||||
<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>$(HexChatRel)plugins\</OutDir>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>$(Python3Output)</TargetName>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</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;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(Glib);$(Python3Path)\include;..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</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;$(Python3Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;$(OutDir);$(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;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(Glib);$(Python3Path)\include;..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</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;$(Python3Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;$(OutDir);$(Python3Path)\libs;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
@ -56,4 +102,6 @@
|
||||
<ClCompile Include="python.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -1,17 +1,7 @@
|
||||
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 = $(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
|
||||
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
|
||||
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
64
plugins/sysinfo/hwmon.c
Normal file
64
plugins/sysinfo/hwmon.c
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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];
|
||||
FILE *fp;
|
||||
snprintf(buffer, bsize, "/sys/class/hwmon/hwmon0/device/temp%i_input", *sensor);
|
||||
fp = fopen(buffer, "r");
|
||||
if(fp != NULL) {
|
||||
if(fgets(buffer, bsize, fp) != NULL)
|
||||
*value = atoi(buffer);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* SysInfo - sysinfo plugin for HexChat
|
||||
* Copyright (c) 2015 Patrick Griffis.
|
||||
* hwmon.h - Hardware monitoring header 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
|
||||
@ -18,12 +18,11 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SYSINFO_H
|
||||
#define SYSINFO_H
|
||||
#ifndef _HWMON_H_
|
||||
#define _HWMON_H_
|
||||
|
||||
#define bsize 1024
|
||||
#define DEFAULT_PCIIDS "/usr/share/hwdata/pci.ids"
|
||||
|
||||
int sysinfo_get_str_pref (const char *name, char *dest);
|
||||
int hwmon_chip_present();
|
||||
void get_hwmon_chip_name(char *name);
|
||||
void get_hwmon_temp(unsigned int *value, unsigned int *sensor);
|
||||
|
||||
#endif
|
240
plugins/sysinfo/match.c
Normal file
240
plugins/sysinfo/match.c
Normal file
@ -0,0 +1,240 @@
|
||||
/*
|
||||
* 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 *quantities[] = { "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", 0 };
|
||||
char *result, **quantity;
|
||||
double free_space, total_space;
|
||||
free_space = *free_k;
|
||||
total_space = *total_k;
|
||||
result = malloc(bsize * sizeof(char));
|
||||
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);
|
||||
}
|
@ -23,7 +23,13 @@
|
||||
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
|
@ -1,263 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -23,19 +23,20 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <pci/header.h>
|
||||
#include <glib.h>
|
||||
|
||||
#ifdef __sparc__
|
||||
#include <sys/utsname.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <pci/header.h>
|
||||
|
||||
#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)
|
||||
int xs_parse_cpu(char *model, char *vendor, double *freq, char *cache, unsigned int *count)
|
||||
{
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(__alpha__) || defined(__ia64__) || defined(__parisc__) || defined(__sparc__)
|
||||
char buffer[bsize];
|
||||
@ -46,6 +47,8 @@ int xs_parse_cpu(char *model, char *vendor, double *freq)
|
||||
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)
|
||||
@ -53,7 +56,10 @@ int xs_parse_cpu(char *model, char *vendor, double *freq)
|
||||
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)
|
||||
@ -61,7 +67,10 @@ int xs_parse_cpu(char *model, char *vendor, double *freq)
|
||||
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
|
||||
@ -71,6 +80,8 @@ int xs_parse_cpu(char *model, char *vendor, double *freq)
|
||||
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
|
||||
@ -80,15 +91,20 @@ int xs_parse_cpu(char *model, char *vendor, double *freq)
|
||||
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;
|
||||
@ -98,8 +114,22 @@ int xs_parse_cpu(char *model, char *vendor, double *freq)
|
||||
{
|
||||
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);
|
||||
@ -107,20 +137,43 @@ int xs_parse_cpu(char *model, char *vendor, double *freq)
|
||||
return 0;
|
||||
}
|
||||
|
||||
gint64 xs_parse_uptime(void)
|
||||
int xs_parse_uptime(int *weeks, int *days, int *hours, int *minutes, int *seconds)
|
||||
{
|
||||
char buffer[bsize];
|
||||
gint64 uptime = 0;
|
||||
long long uptime = 0;
|
||||
FILE *fp = fopen("/proc/uptime", "r");
|
||||
if(fp == NULL)
|
||||
return 0;
|
||||
return 1;
|
||||
|
||||
if(fgets(buffer, bsize, fp) != NULL)
|
||||
uptime = g_ascii_strtoll(buffer, NULL, 0);
|
||||
uptime = strtol(buffer, NULL, 0);
|
||||
|
||||
*seconds = uptime%60;
|
||||
*minutes = (uptime/60)%60;
|
||||
*hours = (uptime/3600)%24;
|
||||
*days = (uptime/86400)%7;
|
||||
*weeks = uptime/604800;
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return uptime;
|
||||
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;
|
||||
}
|
||||
|
||||
int xs_parse_sound(char *snd_card)
|
||||
@ -129,13 +182,12 @@ 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;
|
||||
}
|
||||
@ -146,13 +198,13 @@ int xs_parse_sound(char *snd_card)
|
||||
if(isdigit(buffer[0]) || isdigit(buffer[1]))
|
||||
{
|
||||
char card_buf[bsize];
|
||||
gint64 card_id = 0;
|
||||
long card_id = 0;
|
||||
pos = strstr(buffer, ":");
|
||||
card_id = g_ascii_strtoll(buffer, NULL, 0);
|
||||
card_id = strtoll(buffer, NULL, 0);
|
||||
if (card_id == 0)
|
||||
g_snprintf(card_buf, bsize, "%s", pos+2);
|
||||
snprintf(card_buf, bsize, "%s", pos+2);
|
||||
else
|
||||
g_snprintf(card_buf, bsize, "%"G_GINT64_FORMAT": %s", card_id, pos+2);
|
||||
snprintf(card_buf, bsize, "%ld: %s", card_id, pos+2);
|
||||
pos = strstr(card_buf, "\n");
|
||||
*pos = '\0';
|
||||
strcat(cards, card_buf);
|
||||
@ -198,42 +250,129 @@ 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);
|
||||
|
||||
/* Convert to bytes */
|
||||
*mem_free *= 1000;
|
||||
*mem_tot *= 1000;
|
||||
return 0;
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xs_parse_distro(char *name)
|
||||
@ -249,9 +388,9 @@ int xs_parse_distro(char *name)
|
||||
find_match_char(buffer, "ACCEPT_KEYWORDS", keywords);
|
||||
/* cppcheck-suppress uninitvar */
|
||||
if (strstr(keywords, "\"") == NULL)
|
||||
g_snprintf(buffer, bsize, "Gentoo Linux (stable)");
|
||||
snprintf(buffer, bsize, "Gentoo Linux (stable)");
|
||||
else
|
||||
g_snprintf(buffer, bsize, "Gentoo Linux %s", keywords);
|
||||
snprintf(buffer, bsize, "Gentoo Linux %s", keywords);
|
||||
}
|
||||
else if((fp = fopen("/etc/redhat-release", "r")) != NULL)
|
||||
fgets(buffer, bsize, fp);
|
||||
@ -266,7 +405,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)
|
||||
g_snprintf(buffer, bsize, "ArchLinux");
|
||||
snprintf(buffer, bsize, "ArchLinux");
|
||||
else if((fp = fopen("/etc/lsb-release", "r")) != NULL)
|
||||
{
|
||||
char id[bsize], codename[bsize], release[bsize];
|
||||
@ -279,22 +418,45 @@ int xs_parse_distro(char *name)
|
||||
find_match_char(buffer, "DISTRIB_CODENAME", codename);
|
||||
find_match_char(buffer, "DISTRIB_RELEASE", release);
|
||||
}
|
||||
g_snprintf(buffer, bsize, "%s \"%s\" %s", id, codename, release);
|
||||
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);
|
||||
g_snprintf(buffer, bsize, "Debian %s", release);
|
||||
snprintf(buffer, bsize, "Debian %s", release);
|
||||
}
|
||||
else
|
||||
g_snprintf(buffer, bsize, "Unknown Distro");
|
||||
if(fp != NULL)
|
||||
fclose(fp);
|
||||
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;
|
||||
}
|
@ -23,13 +23,18 @@
|
||||
#ifndef _PARSE_H_
|
||||
#define _PARSE_H_
|
||||
|
||||
int xs_parse_cpu(char *model, char *vendor, double *freq);
|
||||
gint64 xs_parse_uptime(void);
|
||||
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_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
|
157
plugins/sysinfo/pci.c
Normal file
157
plugins/sysinfo/pci.c
Normal file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
* 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;
|
||||
FILE *fp;
|
||||
|
||||
sysinfo_get_pciids (buffer);
|
||||
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);
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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
|
@ -1,277 +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 "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;
|
||||
}
|
416
plugins/sysinfo/sysinfo.cpp
Normal file
416
plugins/sysinfo/sysinfo.cpp
Normal file
@ -0,0 +1,416 @@
|
||||
/* 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;
|
||||
}
|
@ -2,8 +2,6 @@
|
||||
<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">
|
||||
@ -21,51 +19,91 @@
|
||||
<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" />
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\win32\hexchat.props" />
|
||||
<PropertyGroup>
|
||||
<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>hcsysinfo</TargetName>
|
||||
<OutDir>$(HexChatRel)plugins\</OutDir>
|
||||
<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>
|
||||
</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;$(DepsRoot)\include;$(Glib);$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>wbemuuid.lib;comsupp.lib;$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>comsupp.lib</IgnoreSpecificDefaultLibraries>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>sysinfo.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>wbemuuid.lib;comsupp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>comsupp.lib</IgnoreSpecificDefaultLibraries>
|
||||
</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;$(DepsRoot)\include;$(Glib);$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>wbemuuid.lib;comsupp.lib;$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>comsupp.lib</IgnoreSpecificDefaultLibraries>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>sysinfo.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>wbemuuid.lib;comsupp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreSpecificDefaultLibraries>comsupp.lib</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<None Include="sysinfo.def" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<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" />
|
||||
<ClCompile Include="sysinfo.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -9,9 +9,6 @@
|
||||
<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">
|
||||
@ -19,25 +16,8 @@
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="sysinfo.c">
|
||||
<ClCompile Include="sysinfo.cpp">
|
||||
<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>
|
@ -1,170 +0,0 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
@ -1,98 +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 <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;
|
||||
}
|
||||
}
|
||||
|
@ -1,169 +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 <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);
|
||||
}
|
@ -1,493 +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 <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;
|
||||
}
|
||||
}
|
116
plugins/sysinfo/xsys-changelog
Normal file
116
plugins/sysinfo/xsys-changelog
Normal file
@ -0,0 +1,116 @@
|
||||
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
|
15
plugins/sysinfo/xsys-install
Normal file
15
plugins/sysinfo/xsys-install
Normal file
@ -0,0 +1,15 @@
|
||||
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.
|
38
plugins/sysinfo/xsys-makefile
Normal file
38
plugins/sysinfo/xsys-makefile
Normal file
@ -0,0 +1,38 @@
|
||||
#### 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
|
||||
|
105
plugins/sysinfo/xsys-readme
Normal file
105
plugins/sysinfo/xsys-readme
Normal file
@ -0,0 +1,105 @@
|
||||
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
|
923
plugins/sysinfo/xsys.c
Normal file
923
plugins/sysinfo/xsys.c
Normal file
@ -0,0 +1,923 @@
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
char buffer[bsize];
|
||||
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_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;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* SysInfo - sysinfo plugin for HexChat
|
||||
* Copyright (c) 2015 Patrick Griffis.
|
||||
* xsys.h - X-Sys general parameters header
|
||||
* Copyright (C) 2005 Gustavo Zacarias
|
||||
* Copyright (C) 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
|
||||
@ -18,11 +19,14 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FORMAT_H
|
||||
#define FORMAT_H
|
||||
#ifndef _XSYS_H_
|
||||
#define _XSYS_H_
|
||||
|
||||
char *sysinfo_format_uptime(gint64 uptime);
|
||||
char *sysinfo_format_memory(guint64 totalmem, guint64 freemem);
|
||||
char *sysinfo_format_disk(guint64 total, guint64 free);
|
||||
#define bsize 1024
|
||||
#define delims ":="
|
||||
|
||||
int sysinfo_get_percent ();
|
||||
void sysinfo_get_pciids (char *dest);
|
||||
void sysinfo_print_error (const char* msg);
|
||||
|
||||
#endif
|
@ -20,50 +20,260 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <winsparkle.h>
|
||||
#include <windows.h>
|
||||
#include <wininet.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "hexchat-plugin.h"
|
||||
|
||||
#define APPCAST_URL "https://dl.hexchat.net/appcast.xml"
|
||||
#define DEFAULT_DELAY 30 /* 30 seconds */
|
||||
#define DEFAULT_FREQ 360 /* 6 hours */
|
||||
#define DOWNLOAD_URL "http://dl.hexchat.net/hexchat"
|
||||
|
||||
static hexchat_plugin *ph; /* plugin handle */
|
||||
static char name[] = "Update Checker";
|
||||
static char desc[] = "Check for HexChat updates automatically";
|
||||
static char version[] = "5.0";
|
||||
static const char upd_help[] = "Update Checker Usage:\n /UPDCHK, check for HexChat updates\n";
|
||||
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
|
||||
check_cmd (char *word[], char *word_eol[], void *userdata)
|
||||
print_version (char *word[], char *word_eol[], void *userdata)
|
||||
{
|
||||
win_sparkle_check_update_with_ui ();
|
||||
char *version;
|
||||
int prevbuf;
|
||||
int convbuf;
|
||||
|
||||
return HEXCHAT_EAT_ALL;
|
||||
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 int
|
||||
delayed_check (void *userdata)
|
||||
{
|
||||
int freq = hexchat_pluginpref_get_int (ph, "freq");
|
||||
|
||||
/* 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 */
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
win_sparkle_set_appcast_url (APPCAST_URL);
|
||||
win_sparkle_init ();
|
||||
/* 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);
|
||||
}
|
||||
|
||||
hexchat_hook_command (ph, "UPDCHK", HEXCHAT_PRI_NORM, check_cmd, upd_help, NULL);
|
||||
if (hexchat_pluginpref_get_int (ph, "freq") == -1)
|
||||
{
|
||||
hexchat_pluginpref_set_int (ph, "freq", DEFAULT_FREQ);
|
||||
}
|
||||
|
||||
hexchat_hook_command (ph, "UPDCHK", HEXCHAT_PRI_NORM, print_version, upd_help, NULL);
|
||||
hexchat_hook_timer (ph, delay * 1000, delayed_check, 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; /* return 1 for success */
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -2,7 +2,6 @@
|
||||
<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">
|
||||
@ -20,33 +19,80 @@
|
||||
<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" />
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\win32\hexchat.props" />
|
||||
<PropertyGroup>
|
||||
<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>$(HexChatRel)plugins\</OutDir>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>hcupd</TargetName>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;UPD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\src\common;$(WinSparklePath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<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>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>upd.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>$(DepLibs);WinSparkle.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;$(WinSparklePath);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(DepLibs);%(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;_WINDOWS;_USRDLL;UPD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\src\common;$(WinSparklePath);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<AdditionalIncludeDirectories>..\..\src\common;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>upd.def</ModuleDefinitionFile>
|
||||
<AdditionalDependencies>$(DepLibs);WinSparkle.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;$(WinSparklePath);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
@ -56,4 +102,6 @@
|
||||
<ClCompile Include="upd.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -2,7 +2,6 @@
|
||||
<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">
|
||||
@ -20,28 +19,75 @@
|
||||
<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" />
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\win32\hexchat.props" />
|
||||
<PropertyGroup>
|
||||
<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>$(HexChatRel)plugins\</OutDir>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>hcwinamp</TargetName>
|
||||
<OutDir>$(HexChatBin)</OutDir>
|
||||
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
|
||||
</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>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<ModuleDefinitionFile>winamp.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
@ -52,4 +98,6 @@
|
||||
<ClCompile Include="winamp.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -10,7 +10,6 @@ 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
|
||||
@ -32,7 +31,6 @@ 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
|
||||
@ -43,4 +41,3 @@ 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
|
||||
|
@ -1,7 +1,5 @@
|
||||
## 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)
|
||||
@ -16,16 +14,17 @@ 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 \
|
||||
@ -33,7 +32,6 @@ EXTRA_DIST = \
|
||||
ssl.h \
|
||||
ssl.c \
|
||||
text.h \
|
||||
typedef.h \
|
||||
textenums.h \
|
||||
textevents.h \
|
||||
textevents.in \
|
||||
@ -46,6 +44,10 @@ if USE_OPENSSL
|
||||
ssl_c = ssl.c
|
||||
endif
|
||||
|
||||
if USE_MSPROXY
|
||||
msproxy_c = msproxy.c
|
||||
endif
|
||||
|
||||
if USE_DBUS
|
||||
dbusdir = dbus
|
||||
libhexchatcommon_a_LIBADD = \
|
||||
@ -60,8 +62,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 network.c notify.c \
|
||||
outbound.c plugin.c plugin-identd.c plugin-timer.c proto-irc.c server.c servlist.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 \
|
||||
$(ssl_c) text.c tree.c url.c userlist.c util.c
|
||||
libhexchatcommon_a_CFLAGS = $(LIBPROXY_CFLAGS)
|
||||
|
||||
@ -77,12 +79,6 @@ 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)
|
||||
|
@ -39,7 +39,7 @@
|
||||
#endif
|
||||
|
||||
#define DEF_FONT "Monospace 9"
|
||||
#define DEF_FONT_ALTER "Arial Unicode MS,Lucida Sans Unicode,Meiryo,Symbola,Unifont"
|
||||
#define DEF_FONT_ALTER "Arial Unicode MS,Lucida Sans Unicode,MS Gothic,Unifont"
|
||||
|
||||
const char * const languages[LANGUAGES_LENGTH] = {
|
||||
"af", "sq", "am", "ast", "az", "eu", "be", "bg", "ca", "zh_CN", /* 0 .. 9 */
|
||||
@ -61,7 +61,7 @@ list_addentry (GSList ** list, char *cmd, char *name)
|
||||
cmd_len = strlen (cmd) + 1;
|
||||
name_len = strlen (name) + 1;
|
||||
|
||||
pop = g_malloc (sizeof (struct popup) + cmd_len + name_len);
|
||||
pop = malloc (sizeof (struct popup) + cmd_len + name_len);
|
||||
pop->name = (char *) pop + sizeof (struct popup);
|
||||
pop->cmd = pop->name + name_len;
|
||||
|
||||
@ -133,13 +133,13 @@ list_loadconf (char *file, GSList ** list, char *defaultconf)
|
||||
abort ();
|
||||
}
|
||||
|
||||
ibuf = g_malloc (st.st_size);
|
||||
ibuf = malloc (st.st_size);
|
||||
read (fd, ibuf, st.st_size);
|
||||
close (fd);
|
||||
|
||||
list_load_from_data (list, ibuf, st.st_size);
|
||||
|
||||
g_free (ibuf);
|
||||
free (ibuf);
|
||||
}
|
||||
|
||||
void
|
||||
@ -149,7 +149,7 @@ list_free (GSList ** list)
|
||||
while (*list)
|
||||
{
|
||||
data = (void *) (*list)->data;
|
||||
g_free (data);
|
||||
free (data);
|
||||
*list = g_slist_remove (*list, data);
|
||||
}
|
||||
}
|
||||
@ -166,7 +166,7 @@ list_delentry (GSList ** list, char *name)
|
||||
if (!g_ascii_strcasecmp (name, pop->name))
|
||||
{
|
||||
*list = g_slist_remove (*list, pop);
|
||||
g_free (pop);
|
||||
free (pop);
|
||||
return 1;
|
||||
}
|
||||
alist = alist->next;
|
||||
@ -207,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 NULL;
|
||||
return 0;
|
||||
cfg++;
|
||||
if (*cfg == 0)
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,18 +220,18 @@ cfg_put_str (int fh, char *var, char *value)
|
||||
char buf[512];
|
||||
int len;
|
||||
|
||||
g_snprintf (buf, sizeof buf, "%s = %s\n", var, value);
|
||||
snprintf (buf, sizeof buf, "%s = %s\n", var, value);
|
||||
len = strlen (buf);
|
||||
return (write (fh, buf, len) == len);
|
||||
}
|
||||
|
||||
int
|
||||
cfg_put_color (int fh, guint16 r, guint16 g, guint16 b, char *var)
|
||||
cfg_put_color (int fh, int r, int g, int b, char *var)
|
||||
{
|
||||
char buf[400];
|
||||
int len;
|
||||
|
||||
g_snprintf (buf, sizeof buf, "%s = %04hx %04hx %04hx\n", var, r, g, b);
|
||||
snprintf (buf, sizeof buf, "%s = %04x %04x %04x\n", var, r, g, b);
|
||||
len = strlen (buf);
|
||||
return (write (fh, buf, len) == len);
|
||||
}
|
||||
@ -245,20 +245,20 @@ cfg_put_int (int fh, int value, char *var)
|
||||
if (value == -1)
|
||||
value = 1;
|
||||
|
||||
g_snprintf (buf, sizeof buf, "%s = %d\n", var, value);
|
||||
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, guint16 *r, guint16 *g, guint16 *b)
|
||||
cfg_get_color (char *cfg, char *var, int *r, int *g, int *b)
|
||||
{
|
||||
char str[128];
|
||||
|
||||
if (!cfg_get_str (cfg, var, str, sizeof (str)))
|
||||
return 0;
|
||||
|
||||
sscanf (str, "%04hx %04hx %04hx", r, g, b);
|
||||
sscanf (str, "%04x %04x %04x", r, g, b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -308,7 +308,9 @@ get_xdir (void)
|
||||
|
||||
if (portable_mode () || SHGetKnownFolderPath (&FOLDERID_RoamingAppData, 0, NULL, &roaming_path_wide) != S_OK)
|
||||
{
|
||||
char *path = g_win32_get_package_installation_directory_of_module (NULL);
|
||||
char *path;
|
||||
|
||||
path = g_win32_get_package_installation_directory_of_module (NULL);
|
||||
if (path)
|
||||
{
|
||||
xdir = g_build_filename (path, "config", NULL);
|
||||
@ -434,7 +436,6 @@ 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},
|
||||
@ -477,11 +478,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},
|
||||
@ -585,10 +586,10 @@ const struct prefs vars[] =
|
||||
{0, 0, 0},
|
||||
};
|
||||
|
||||
static const char *
|
||||
static char *
|
||||
convert_with_fallback (const char *str, const char *fallback)
|
||||
{
|
||||
const char *utf;
|
||||
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. */
|
||||
@ -647,7 +648,7 @@ get_default_language (void)
|
||||
|
||||
if (lang_no >= 0)
|
||||
{
|
||||
g_free (lang);
|
||||
free (lang);
|
||||
return lang_no;
|
||||
}
|
||||
|
||||
@ -656,7 +657,7 @@ get_default_language (void)
|
||||
|
||||
lang_no = find_language_number (lang);
|
||||
|
||||
g_free (lang);
|
||||
free (lang);
|
||||
|
||||
return lang_no >= 0 ? lang_no : find_language_number ("en");
|
||||
}
|
||||
@ -698,8 +699,8 @@ get_default_spell_languages (void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_free (last);
|
||||
if (last != NULL)
|
||||
g_free(last);
|
||||
|
||||
if (lang_list[0])
|
||||
return g_strdup (ret);
|
||||
@ -760,7 +761,6 @@ 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;
|
||||
@ -772,6 +772,7 @@ 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;
|
||||
@ -827,6 +828,7 @@ 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;
|
||||
@ -841,7 +843,7 @@ load_default_config(void)
|
||||
#ifdef WIN32
|
||||
if (portable_mode () || SHGetKnownFolderPath (&FOLDERID_Downloads, 0, NULL, &roaming_path_wide) != S_OK)
|
||||
{
|
||||
g_snprintf (prefs.hex_dcc_dir, sizeof (prefs.hex_dcc_dir), "%s\\downloads", get_xdir ());
|
||||
snprintf (prefs.hex_dcc_dir, sizeof (prefs.hex_dcc_dir), "%s\\downloads", get_xdir ());
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -855,36 +857,34 @@ load_default_config(void)
|
||||
#else
|
||||
if (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));
|
||||
strcpy (prefs.hex_dcc_dir, g_get_user_special_dir (G_USER_DIRECTORY_DOWNLOAD));
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
strcpy (prefs.hex_dcc_dir, g_build_filename (g_get_home_dir (), "Downloads", NULL));
|
||||
}
|
||||
#endif
|
||||
strcpy (prefs.hex_gui_ulist_doubleclick, "QUERY %s");
|
||||
strcpy (prefs.hex_input_command_char, "/");
|
||||
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_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_no_hilight, "NickServ,ChanServ,InfoServ,N,Q");
|
||||
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_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);
|
||||
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)
|
||||
{
|
||||
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));
|
||||
strcpy (prefs.hex_text_font, font);
|
||||
strcpy (prefs.hex_text_font_main, font);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -894,7 +894,7 @@ load_default_config(void)
|
||||
|
||||
strcpy (prefs.hex_text_font_alternative, DEF_FONT_ALTER);
|
||||
langs = get_default_spell_languages ();
|
||||
safe_strcpy (prefs.hex_text_spell_langs, langs, sizeof(prefs.hex_text_spell_langs));
|
||||
strcpy (prefs.hex_text_spell_langs, langs);
|
||||
|
||||
|
||||
/* private variables */
|
||||
@ -1224,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 = g_malloc (vars[i].len + 1);
|
||||
prev_string = (char*) malloc (vars[i].len + 1);
|
||||
strncpy (prev_string, (char *) &prefs + vars[i].offset, vars[i].len);
|
||||
|
||||
/* update the variable */
|
||||
@ -1236,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);
|
||||
}
|
||||
|
||||
g_free (prev_string);
|
||||
free (prev_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1347,7 +1347,7 @@ hexchat_fopen_file (const char *file, const char *mode, int xof_flags)
|
||||
FILE *fh;
|
||||
|
||||
if (xof_flags & XOF_FULLPATH)
|
||||
return g_fopen (file, mode);
|
||||
return fopen (file, mode);
|
||||
|
||||
buf = g_build_filename (get_xdir (), file, NULL);
|
||||
fh = g_fopen (buf, mode);
|
||||
|
@ -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, guint16 *r, guint16 *g, guint16 *b);
|
||||
int cfg_put_color (int fh, guint16 r, guint16 g, guint16 b, 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);
|
||||
char *get_xdir (void);
|
||||
int check_config_dir (void);
|
||||
void load_default_config (void);
|
||||
|
@ -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->session_name[0] ? sess->session_name : _("<none>"));
|
||||
sess->channel[0] ? sess->channel : _("<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_new0 (chanopt_in_memory, 1);
|
||||
co = g_malloc0 (sizeof (chanopt_in_memory));
|
||||
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->session_name[0] == 0)
|
||||
if (sess->channel[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->session_name, FALSE);
|
||||
co = chanopt_find (network, sess->channel, FALSE);
|
||||
if (!co)
|
||||
return;
|
||||
|
||||
@ -334,7 +334,7 @@ chanopt_save (session *sess)
|
||||
chanopt_in_memory *co;
|
||||
char *network;
|
||||
|
||||
if (sess->session_name[0] == 0)
|
||||
if (sess->channel[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->session_name, TRUE);
|
||||
co = chanopt_find (network, sess->channel, 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;
|
||||
|
||||
g_snprintf (buf, sizeof (buf), "%s = %s\n", "network", co->network);
|
||||
snprintf (buf, sizeof (buf), "%s = %s\n", "network", co->network);
|
||||
write (fh, buf, strlen (buf));
|
||||
|
||||
g_snprintf (buf, sizeof (buf), "%s = %s\n", "channel", co->channel);
|
||||
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)
|
||||
{
|
||||
g_snprintf (buf, sizeof (buf), "%s = %d\n", chanopt[i].name, val);
|
||||
snprintf (buf, sizeof (buf), "%s = %d\n", chanopt[i].name, val);
|
||||
write (fh, buf, strlen (buf));
|
||||
}
|
||||
i++;
|
||||
|
@ -2,7 +2,6 @@
|
||||
<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">
|
||||
@ -21,15 +20,16 @@
|
||||
<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="$(HexChatLib)marshal.h" />
|
||||
<ClInclude Include="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="$(HexChatLib)textenums.h" />
|
||||
<ClInclude Include="$(HexChatLib)textevents.h" />
|
||||
<ClInclude Include="textenums.h" />
|
||||
<ClInclude Include="textevents.h" />
|
||||
<ClInclude Include="tree.h" />
|
||||
<ClInclude Include="typedef.h" />
|
||||
<ClInclude Include="url.h" />
|
||||
@ -54,11 +54,12 @@
|
||||
<ClCompile Include="ctcp.c" />
|
||||
<ClCompile Include="dcc.c" />
|
||||
<ClCompile Include="history.c" />
|
||||
<ClCompile Include="plugin-identd.c" />
|
||||
<ClCompile Include="identd.c" />
|
||||
<ClCompile Include="ignore.c" />
|
||||
<ClCompile Include="inbound.c" />
|
||||
<ClCompile Include="$(HexChatLib)marshal.c" />
|
||||
<ClCompile Include="marshal.c" />
|
||||
<ClCompile Include="modes.c" />
|
||||
<ClCompile Include="msproxy.c" />
|
||||
<ClCompile Include="network.c" />
|
||||
<ClCompile Include="notify.c" />
|
||||
<ClCompile Include="outbound.c" />
|
||||
@ -77,7 +78,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\win32\config.h.tt" />
|
||||
<ClInclude Include="$(HexChatLib)config.h" />
|
||||
<ClInclude Include="..\..\config.h" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{87554B59-006C-4D94-9714-897B27067BA3}</ProjectGuid>
|
||||
@ -85,36 +86,85 @@
|
||||
<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" />
|
||||
<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>
|
||||
<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>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(HexChatLib);$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..;$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</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>$(HexChatLib);$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)..;$(DepsRoot)\include;$(Glib);$(Gtk);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<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)..\
|
||||
"$(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"
|
||||
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"
|
||||
|
||||
]]></Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
||||
</Project>
|
@ -29,6 +29,9 @@
|
||||
<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>
|
||||
@ -41,6 +44,9 @@
|
||||
<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>
|
||||
@ -71,10 +77,10 @@
|
||||
<ClInclude Include="text.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(HexChatLib)textenums.h">
|
||||
<ClInclude Include="textenums.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(HexChatLib)textevents.h">
|
||||
<ClInclude Include="textevents.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="tree.h">
|
||||
@ -98,16 +104,13 @@
|
||||
<ClInclude Include="hexchat-plugin.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(HexChatLib)config.h">
|
||||
<ClInclude Include="..\..\config.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="typedef.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(HexChatLib)marshal.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="plugin-identd.h">
|
||||
<ClInclude Include="marshal.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
@ -127,6 +130,9 @@
|
||||
<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>
|
||||
@ -136,6 +142,9 @@
|
||||
<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>
|
||||
@ -181,14 +190,11 @@
|
||||
<ClCompile Include="hexchat.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(HexChatLib)marshal.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="plugin-identd.c">
|
||||
<ClCompile Include="marshal.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\win32\config.h.tt" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
@ -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 = g_strdup (conf);
|
||||
conf = 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, "");
|
||||
g_free (conf);
|
||||
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
|
||||
g_snprintf (outbuf, sizeof (outbuf), "VERSION HexChat "PACKAGE_VERSION" [x%d] / %s",
|
||||
snprintf (outbuf, sizeof (outbuf), "VERSION HexChat "PACKAGE_VERSION" [x%d] / %s",
|
||||
get_cpu_arch (), get_sys_str (1));
|
||||
#else
|
||||
g_snprintf (outbuf, sizeof (outbuf), "VERSION HexChat "PACKAGE_VERSION" / %s",
|
||||
snprintf (outbuf, sizeof (outbuf), "VERSION HexChat "PACKAGE_VERSION" / %s",
|
||||
get_sys_str (1));
|
||||
#endif
|
||||
serv->p_nctcp (serv, nick, outbuf);
|
||||
|
@ -19,8 +19,6 @@
|
||||
* xclaesse@gmail.com
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include "dbus-client.h"
|
||||
@ -93,7 +91,7 @@ hexchat_remote (void)
|
||||
g_object_unref (dbus);
|
||||
|
||||
if (!hexchat_running) {
|
||||
/* dbus_g_connection_unref (connection); */
|
||||
//dbus_g_connection_unref (connection);
|
||||
return;
|
||||
}
|
||||
|
||||
|
598
src/common/dcc.c
598
src/common/dcc.c
File diff suppressed because it is too large
Load Diff
@ -39,6 +39,17 @@
|
||||
|
||||
#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;
|
||||
@ -51,21 +62,21 @@ struct DCC
|
||||
int wiotag; /* writing/sending io tag */
|
||||
int port;
|
||||
int pasvid; /* mIRC's passive DCC id */
|
||||
gint64 cps;
|
||||
int cps;
|
||||
int resume_error;
|
||||
int resume_errno;
|
||||
|
||||
GTimeVal lastcpstv, firstcpstv;
|
||||
goffset lastcpspos;
|
||||
gint64 maxcps;
|
||||
DCC_SIZE lastcpspos;
|
||||
int maxcps;
|
||||
|
||||
unsigned char ack_buf[4]; /* buffer for reading 4-byte ack */
|
||||
int ack_pos;
|
||||
|
||||
guint64 size;
|
||||
guint64 resumable;
|
||||
guint64 ack;
|
||||
guint64 pos;
|
||||
DCC_SIZE size;
|
||||
DCC_SIZE resumable;
|
||||
DCC_SIZE ack;
|
||||
DCC_SIZE pos;
|
||||
time_t starttime;
|
||||
time_t offertime;
|
||||
time_t lasttime;
|
||||
@ -114,7 +125,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, gint64 maxcps, int passive);
|
||||
void dcc_send (struct session *sess, char *to, char *file, int 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);
|
||||
|
@ -88,10 +88,11 @@ 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, gboolean sel);
|
||||
void fe_userlist_insert (struct session *sess, struct User *newuser, int row, int 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);
|
||||
@ -102,6 +103,7 @@ void fe_dcc_remove (struct DCC *dcc);
|
||||
int fe_dcc_open_recv_win (int passive);
|
||||
int fe_dcc_open_send_win (int passive);
|
||||
int fe_dcc_open_chat_win (int passive);
|
||||
void fe_sslalert_open (struct server *serv, void (*callback)(int, void *), void *callback_data);
|
||||
void fe_clear_channel (struct session *sess);
|
||||
void fe_session_callback (struct session *sess);
|
||||
void fe_server_callback (struct server *serv);
|
||||
@ -178,6 +180,7 @@ 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 ();
|
||||
|
||||
|
@ -39,16 +39,6 @@
|
||||
#define HEXCHAT_EAT_PLUGIN 2 /* don't let other plugins see this event */
|
||||
#define HEXCHAT_EAT_ALL (HEXCHAT_EAT_HEXCHAT|HEXCHAT_EAT_PLUGIN) /* don't let anything see this event */
|
||||
|
||||
/* Taken from glib/gmacros.h */
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||
#define HEXCHAT_DEPRECATED_FOR(f) __attribute__((__deprecated__("Use '" #f "' instead")))
|
||||
#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320)
|
||||
#define HEXCHAT_DEPRECATED_FOR(f) __declspec(deprecated("is deprecated. Use '" #f "' instead"))
|
||||
#else
|
||||
#define HEXCHAT_DEPRECATED_FOR(f)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -203,11 +193,6 @@ struct _hexchat_plugin
|
||||
hexchat_event_attrs *(*hexchat_event_attrs_create) (hexchat_plugin *ph);
|
||||
void (*hexchat_event_attrs_free) (hexchat_plugin *ph,
|
||||
hexchat_event_attrs *attrs);
|
||||
char *(*hexchat_pluginpref_get_str_ptr) (hexchat_plugin *ph,
|
||||
const char *var);
|
||||
char **(*hexchat_pluginpref_list_keys) (hexchat_plugin *ph);
|
||||
void (*hexchat_free_array) (hexchat_plugin *ph,
|
||||
char **arr);
|
||||
};
|
||||
#endif
|
||||
|
||||
@ -395,25 +380,16 @@ void
|
||||
hexchat_free (hexchat_plugin *ph,
|
||||
void *ptr);
|
||||
|
||||
void
|
||||
hexchat_free_array (hexchat_plugin *ph,
|
||||
char **arr);
|
||||
|
||||
int
|
||||
hexchat_pluginpref_set_str (hexchat_plugin *ph,
|
||||
const char *var,
|
||||
const char *value);
|
||||
|
||||
HEXCHAT_DEPRECATED_FOR(hexchat_pluginpref_get_str_ptr)
|
||||
int
|
||||
hexchat_pluginpref_get_str (hexchat_plugin *ph,
|
||||
const char *var,
|
||||
char *dest);
|
||||
|
||||
char *
|
||||
hexchat_pluginpref_get_str_ptr (hexchat_plugin *ph,
|
||||
const char *var);
|
||||
|
||||
int
|
||||
hexchat_pluginpref_set_int (hexchat_plugin *ph,
|
||||
const char *var,
|
||||
@ -426,14 +402,10 @@ int
|
||||
hexchat_pluginpref_delete (hexchat_plugin *ph,
|
||||
const char *var);
|
||||
|
||||
HEXCHAT_DEPRECATED_FOR(hexchat_pluginpref_list_keys)
|
||||
int
|
||||
hexchat_pluginpref_list (hexchat_plugin *ph,
|
||||
char *dest);
|
||||
|
||||
char **
|
||||
hexchat_pluginpref_list_keys (hexchat_plugin *ph);
|
||||
|
||||
#if !defined(PLUGIN_C) && defined(WIN32)
|
||||
#ifndef HEXCHAT_PLUGIN_HANDLE
|
||||
#define HEXCHAT_PLUGIN_HANDLE (ph)
|
||||
@ -473,15 +445,12 @@ hexchat_pluginpref_list_keys (hexchat_plugin *ph);
|
||||
#define hexchat_send_modes ((HEXCHAT_PLUGIN_HANDLE)->hexchat_send_modes)
|
||||
#define hexchat_strip ((HEXCHAT_PLUGIN_HANDLE)->hexchat_strip)
|
||||
#define hexchat_free ((HEXCHAT_PLUGIN_HANDLE)->hexchat_free)
|
||||
#define hexchat_free_array ((HEXCHAT_PLUGIN_HANDLE)->hexchat_free_array)
|
||||
#define hexchat_pluginpref_set_str ((HEXCHAT_PLUGIN_HANDLE)->hexchat_pluginpref_set_str)
|
||||
#define hexchat_pluginpref_get_str ((HEXCHAT_PLUGIN_HANDLE)->hexchat_pluginpref_get_str)
|
||||
#define hexchat_pluginpref_get_str_ptr ((HEXCHAT_PLUGIN_HANDLE)->hexchat_pluginpref_get_str_ptr)
|
||||
#define hexchat_pluginpref_set_int ((HEXCHAT_PLUGIN_HANDLE)->hexchat_pluginpref_set_int)
|
||||
#define hexchat_pluginpref_get_int ((HEXCHAT_PLUGIN_HANDLE)->hexchat_pluginpref_get_int)
|
||||
#define hexchat_pluginpref_delete ((HEXCHAT_PLUGIN_HANDLE)->hexchat_pluginpref_delete)
|
||||
#define hexchat_pluginpref_list ((HEXCHAT_PLUGIN_HANDLE)->hexchat_pluginpref_list)
|
||||
#define hexchat_pluginpref_list_keys ((HEXCHAT_PLUGIN_HANDLE)->hexchat_pluginpref_list_keys)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -41,9 +41,7 @@
|
||||
#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"
|
||||
@ -57,6 +55,10 @@
|
||||
#include <glib-object.h> /* for g_type_init() */
|
||||
#endif
|
||||
|
||||
#ifdef USE_MSPROXY
|
||||
#include "msproxy.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBPROXY
|
||||
#include <proxy.h>
|
||||
#endif
|
||||
@ -210,7 +212,7 @@ find_dialog (server *serv, char *nick)
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
session *
|
||||
@ -221,14 +223,14 @@ find_channel (server *serv, char *chan)
|
||||
while (list)
|
||||
{
|
||||
sess = list->data;
|
||||
if ((serv == sess->server) && sess->type == SESS_CHANNEL)
|
||||
if ((!serv || serv == sess->server) && sess->type == SESS_CHANNEL)
|
||||
{
|
||||
if (!serv->p_cmp (chan, sess->channel))
|
||||
return sess;
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -258,7 +260,7 @@ lag_check (void)
|
||||
unsigned long tim;
|
||||
char tbuf[128];
|
||||
time_t now = time (0);
|
||||
time_t lag;
|
||||
int lag;
|
||||
|
||||
tim = make_ping_time ();
|
||||
|
||||
@ -268,17 +270,16 @@ lag_check (void)
|
||||
if (serv->connected && serv->end_of_motd)
|
||||
{
|
||||
lag = now - serv->ping_recv;
|
||||
if (prefs.hex_net_ping_timeout != 0 && lag > prefs.hex_net_ping_timeout && lag > 0)
|
||||
if (prefs.hex_net_ping_timeout && lag > prefs.hex_net_ping_timeout && lag > 0)
|
||||
{
|
||||
sprintf (tbuf, "%" G_GINT64_FORMAT, (gint64) lag);
|
||||
sprintf (tbuf, "%d", 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
|
||||
{
|
||||
g_snprintf (tbuf, sizeof (tbuf), "LAG%lu", tim);
|
||||
snprintf (tbuf, sizeof (tbuf), "LAG%lu", tim);
|
||||
serv->p_ping (serv, "", tbuf);
|
||||
|
||||
if (!serv->lag_sent)
|
||||
@ -358,6 +359,9 @@ 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++;
|
||||
|
||||
@ -373,6 +377,15 @@ 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;
|
||||
}
|
||||
|
||||
@ -383,6 +396,7 @@ irc_init (session *sess)
|
||||
{
|
||||
static int done_init = FALSE;
|
||||
char *buf;
|
||||
int i;
|
||||
|
||||
if (done_init)
|
||||
return;
|
||||
@ -390,7 +404,6 @@ 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)
|
||||
@ -418,8 +431,7 @@ irc_init (session *sess)
|
||||
|
||||
if (arg_urls != NULL)
|
||||
{
|
||||
guint i;
|
||||
for (i = 0; i < g_strv_length (arg_urls); 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);
|
||||
@ -443,7 +455,12 @@ session_new (server *serv, char *from, int type, int focus)
|
||||
{
|
||||
session *sess;
|
||||
|
||||
sess = g_new0 (struct session, 1);
|
||||
sess = malloc (sizeof (struct session));
|
||||
if (sess == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
memset (sess, 0, sizeof (struct session));
|
||||
|
||||
sess->server = serv;
|
||||
sess->logfd = -1;
|
||||
@ -462,10 +479,7 @@ 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->session_name, from, CHANLEN);
|
||||
}
|
||||
safe_strcpy (sess->channel, from, CHANLEN);
|
||||
|
||||
sess_list = g_slist_prepend (sess_list, sess);
|
||||
|
||||
@ -492,6 +506,7 @@ 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:
|
||||
@ -506,16 +521,6 @@ 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;
|
||||
@ -534,8 +539,9 @@ exec_notify_kill (session * sess)
|
||||
waitpid (re->childpid, NULL, WNOHANG);
|
||||
fe_input_remove (re->iotag);
|
||||
close (re->myfd);
|
||||
g_free(re->linebuf);
|
||||
g_free (re);
|
||||
if (re->linebuf)
|
||||
free(re->linebuf);
|
||||
free (re);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -641,8 +647,10 @@ session_free (session *killsess)
|
||||
send_quit_or_part (killsess);
|
||||
|
||||
history_free (&killsess->history);
|
||||
g_free (killsess->topic);
|
||||
g_free (killsess->current_modes);
|
||||
if (killsess->topic)
|
||||
free (killsess->topic);
|
||||
if (killsess->current_modes)
|
||||
free (killsess->current_modes);
|
||||
|
||||
fe_session_callback (killsess);
|
||||
|
||||
@ -653,7 +661,7 @@ session_free (session *killsess)
|
||||
current_sess = sess_list->data;
|
||||
}
|
||||
|
||||
g_free (killsess);
|
||||
free (killsess);
|
||||
|
||||
if (!sess_list && !in_hexchat_exit)
|
||||
hexchat_exit (); /* sess_list is empty, quit! */
|
||||
@ -767,15 +775,20 @@ 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
|
||||
@ -804,12 +817,15 @@ xchat_init (void)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (g_get_charset (&cs))
|
||||
prefs.utf8_locale = TRUE;
|
||||
|
||||
load_text_events ();
|
||||
sound_load ();
|
||||
notify_load ();
|
||||
ignore_load ();
|
||||
|
||||
g_snprintf (buf, sizeof (buf),
|
||||
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"\
|
||||
@ -865,7 +881,7 @@ xchat_init (void)
|
||||
|
||||
list_loadconf ("popup.conf", &popup_list, buf);
|
||||
|
||||
g_snprintf (buf, sizeof (buf),
|
||||
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"
|
||||
@ -879,7 +895,7 @@ xchat_init (void)
|
||||
_("Hide Version"));
|
||||
list_loadconf ("usermenu.conf", &usermenu_list, buf);
|
||||
|
||||
g_snprintf (buf, sizeof (buf),
|
||||
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"
|
||||
@ -896,7 +912,7 @@ xchat_init (void)
|
||||
_("Dialog"));
|
||||
list_loadconf ("buttons.conf", &button_list, buf);
|
||||
|
||||
g_snprintf (buf, sizeof (buf),
|
||||
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"
|
||||
@ -917,6 +933,7 @@ xchat_init (void)
|
||||
defaultconf_urlhandlers);
|
||||
|
||||
servlist_init (); /* load server list */
|
||||
_SSL_certlist_init (); /* load known certificate fingerprints */
|
||||
|
||||
/* if we got a URL, don't open the server list GUI */
|
||||
if (!prefs.hex_gui_slist_skip && !arg_url && !arg_urls)
|
||||
@ -996,37 +1013,29 @@ main (int argc, char *argv[])
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
#ifdef WIN32
|
||||
HRESULT coinit_result;
|
||||
#endif
|
||||
|
||||
srand ((unsigned int) time (NULL)); /* CL: do this only once! */
|
||||
srand (time (0)); /* 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 >= 2)
|
||||
if (argc >= 3)
|
||||
{
|
||||
for (i = 1; i < argc; i++)
|
||||
for (i = 1; i < argc - 1; i++)
|
||||
{
|
||||
if ((strcmp (argv[i], "-d") == 0 || strcmp (argv[i], "--cfgdir") == 0)
|
||||
&& i + 1 < argc)
|
||||
if (strcmp (argv[i], "-d") == 0)
|
||||
{
|
||||
xdir = g_strdup (argv[i + 1]);
|
||||
}
|
||||
else if (strncmp (argv[i], "--cfgdir=", 9) == 0)
|
||||
{
|
||||
xdir = g_strdup (argv[i] + 9);
|
||||
}
|
||||
if (xdir)
|
||||
{
|
||||
g_free (xdir);
|
||||
}
|
||||
|
||||
xdir = strdup (argv[i + 1]);
|
||||
|
||||
if (xdir != NULL)
|
||||
{
|
||||
if (xdir[strlen (xdir) - 1] == G_DIR_SEPARATOR)
|
||||
{
|
||||
xdir[strlen (xdir) - 1] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1050,6 +1059,10 @@ 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;
|
||||
@ -1062,14 +1075,6 @@ 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
|
||||
@ -1097,13 +1102,6 @@ main (int argc, char *argv[])
|
||||
|
||||
fe_main ();
|
||||
|
||||
#ifdef WIN32
|
||||
if (SUCCEEDED (coinit_result))
|
||||
{
|
||||
CoUninitialize ();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBPROXY
|
||||
px_proxy_factory_free(libproxy_factory);
|
||||
#endif
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <glib.h>
|
||||
#include <glib/gstdio.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include <time.h> /* need time_t */
|
||||
|
||||
@ -37,10 +36,26 @@
|
||||
#endif
|
||||
|
||||
#include "history.h"
|
||||
#include "tree.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
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
#include <openssl/ssl.h> /* SSL_() */
|
||||
#include "ssl.h"
|
||||
#endif
|
||||
|
||||
#ifdef __EMX__ /* for o/s 2 */
|
||||
@ -248,7 +263,6 @@ 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;
|
||||
@ -264,7 +278,7 @@ struct hexchatprefs
|
||||
int hex_gui_win_state;
|
||||
int hex_gui_win_top;
|
||||
int hex_gui_win_width;
|
||||
int hex_identd_port;
|
||||
int hex_input_balloon_time;
|
||||
int hex_irc_ban_type;
|
||||
int hex_irc_join_delay;
|
||||
int hex_irc_notice_pos;
|
||||
@ -316,6 +330,7 @@ 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
|
||||
@ -368,12 +383,12 @@ typedef struct session
|
||||
guint8 text_strip;
|
||||
|
||||
struct server *server;
|
||||
tree *usertree; /* alphabetical tree */
|
||||
void *usertree_alpha; /* pure alphabetical tree */
|
||||
void *usertree; /* ordered with Ops first */
|
||||
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;
|
||||
@ -420,6 +435,14 @@ 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
|
||||
@ -477,6 +500,7 @@ 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;
|
||||
@ -532,10 +556,7 @@ 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;
|
||||
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. */
|
||||
|
||||
char *encoding; /* NULL for system */
|
||||
GSList *favlist; /* list of channels & keys to join */
|
||||
|
||||
unsigned int motd_skipped:1;
|
||||
@ -568,6 +589,8 @@ 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 */
|
||||
@ -575,6 +598,7 @@ typedef struct server
|
||||
#ifdef USE_OPENSSL
|
||||
unsigned int use_ssl:1; /* is server SSL capable? */
|
||||
unsigned int accept_invalid_cert:1;/* ignore result of server's cert. verify */
|
||||
struct cert_info *cert_info;
|
||||
#endif
|
||||
} server;
|
||||
|
||||
@ -610,4 +634,7 @@ 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
|
||||
|
@ -18,14 +18,14 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <glib.h>
|
||||
#include "history.h"
|
||||
|
||||
void
|
||||
history_add (struct history *his, char *text)
|
||||
{
|
||||
g_free (his->lines[his->realpos]);
|
||||
his->lines[his->realpos] = g_strdup (text);
|
||||
if (his->lines[his->realpos])
|
||||
free (his->lines[his->realpos]);
|
||||
his->lines[his->realpos] = 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])
|
||||
{
|
||||
g_free (his->lines[i]);
|
||||
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 NULL;
|
||||
return 0;
|
||||
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 NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
@ -90,11 +90,11 @@ history_up (struct history *his, char *current_text)
|
||||
if (his->realpos == HISTORY_SIZE - 1)
|
||||
{
|
||||
if (his->pos == 0)
|
||||
return NULL;
|
||||
return 0;
|
||||
} else
|
||||
{
|
||||
if (his->pos == his->realpos + 1)
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
next = HISTORY_SIZE - 1;
|
||||
@ -117,5 +117,5 @@ history_up (struct history *his, char *current_text)
|
||||
return his->lines[his->pos];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
201
src/common/identd.c
Normal file
201
src/common/identd.c
Normal file
@ -0,0 +1,201 @@
|
||||
/* 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));
|
||||
}
|
||||
}
|
@ -1,4 +1,7 @@
|
||||
/*
|
||||
/* 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
|
||||
@ -14,10 +17,9 @@
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef HEXCHAT_IDENTD_H
|
||||
#define HEXCHAT_IDENTD_H
|
||||
|
||||
#ifndef SYSINFO_SHARED_H
|
||||
#define SYSINFO_SHARED_H
|
||||
|
||||
int xs_parse_df(gint64 *total_bytes, gint64 *free_bytes);
|
||||
void identd_start (char *username);
|
||||
|
||||
#endif
|
@ -53,7 +53,7 @@ static int ignored_total = 0;
|
||||
struct ignore *
|
||||
ignore_exists (char *mask)
|
||||
{
|
||||
struct ignore *ig = NULL;
|
||||
struct ignore *ig = 0;
|
||||
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 = NULL;
|
||||
struct ignore *ig = 0;
|
||||
int change_only = FALSE;
|
||||
|
||||
/* first check if it's already ignored */
|
||||
@ -88,9 +88,12 @@ ignore_add (char *mask, int type, gboolean overwrite)
|
||||
change_only = TRUE;
|
||||
|
||||
if (!change_only)
|
||||
ig = g_new (struct ignore, 1);
|
||||
ig = malloc (sizeof (struct ignore));
|
||||
|
||||
ig->mask = g_strdup (mask);
|
||||
if (!ig)
|
||||
return 0;
|
||||
|
||||
ig->mask = strdup (mask);
|
||||
|
||||
if (!overwrite && change_only)
|
||||
ig->type |= type;
|
||||
@ -122,7 +125,7 @@ ignore_showlist (session *sess)
|
||||
ig = list->data;
|
||||
i++;
|
||||
|
||||
g_snprintf (tbuf, sizeof (tbuf), " %-25s ", ig->mask);
|
||||
snprintf (tbuf, sizeof (tbuf), " %-25s ", ig->mask);
|
||||
if (ig->type & IG_PRIV)
|
||||
strcat (tbuf, _("YES "));
|
||||
else
|
||||
@ -189,8 +192,8 @@ ignore_del (char *mask, struct ignore *ig)
|
||||
if (ig)
|
||||
{
|
||||
ignore_list = g_slist_remove (ignore_list, ig);
|
||||
g_free (ig->mask);
|
||||
g_free (ig);
|
||||
free (ig->mask);
|
||||
free (ig);
|
||||
fe_ignore_update (1);
|
||||
return TRUE;
|
||||
}
|
||||
@ -262,7 +265,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 = g_strdup (tbuf);
|
||||
ignore->mask = strdup (tbuf);
|
||||
}
|
||||
if (my_cfg)
|
||||
{
|
||||
@ -278,7 +281,7 @@ ignore_load ()
|
||||
struct ignore *ignore;
|
||||
struct stat st;
|
||||
char *cfg, *my_cfg;
|
||||
int fh;
|
||||
int fh, i;
|
||||
|
||||
fh = hexchat_open_file ("ignore.conf", O_RDONLY, 0, 0);
|
||||
if (fh != -1)
|
||||
@ -286,18 +289,22 @@ ignore_load ()
|
||||
fstat (fh, &st);
|
||||
if (st.st_size)
|
||||
{
|
||||
cfg = g_malloc0 (st.st_size + 1);
|
||||
read (fh, cfg, 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';
|
||||
my_cfg = cfg;
|
||||
while (my_cfg)
|
||||
{
|
||||
ignore = g_new0 (struct ignore, 1);
|
||||
ignore = malloc (sizeof (struct ignore));
|
||||
memset (ignore, 0, sizeof (struct ignore));
|
||||
if ((my_cfg = ignore_read_next_entry (my_cfg, ignore)))
|
||||
ignore_list = g_slist_prepend (ignore_list, ignore);
|
||||
else
|
||||
g_free (ignore);
|
||||
free (ignore);
|
||||
}
|
||||
g_free (cfg);
|
||||
free (cfg);
|
||||
}
|
||||
close (fh);
|
||||
}
|
||||
@ -319,7 +326,7 @@ ignore_save ()
|
||||
ig = (struct ignore *) temp->data;
|
||||
if (!(ig->type & IG_NOSAVE))
|
||||
{
|
||||
g_snprintf (buf, sizeof (buf), "mask = %s\ntype = %u\n\n",
|
||||
snprintf (buf, sizeof (buf), "mask = %s\ntype = %u\n\n",
|
||||
ig->mask, ig->type);
|
||||
write (fh, buf, strlen (buf));
|
||||
}
|
||||
@ -372,9 +379,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;
|
||||
g_snprintf (real_ip, sizeof (real_ip), "*!*%s", &ip[i]);
|
||||
snprintf (real_ip, sizeof (real_ip), "*!*%s", &ip[i]);
|
||||
|
||||
g_snprintf (buf, sizeof (buf),
|
||||
snprintf (buf, sizeof (buf),
|
||||
_("You are being CTCP flooded from %s, ignoring %s\n"),
|
||||
nick, real_ip);
|
||||
PrintText (sess, buf);
|
||||
@ -399,7 +406,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 */
|
||||
{
|
||||
g_snprintf (buf, sizeof (buf),
|
||||
snprintf (buf, sizeof (buf),
|
||||
_("You are being MSG flooded from %s, setting gui_autoopen_dialog OFF.\n"),
|
||||
ip);
|
||||
PrintText (sess, buf);
|
||||
|
@ -33,6 +33,8 @@
|
||||
#define WANTDNS
|
||||
#include "inet.h"
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "hexchat.h"
|
||||
#include "util.h"
|
||||
#include "ignore.h"
|
||||
@ -62,7 +64,7 @@ clear_channel (session *sess)
|
||||
|
||||
if (sess->current_modes)
|
||||
{
|
||||
g_free (sess->current_modes);
|
||||
free (sess->current_modes);
|
||||
sess->current_modes = NULL;
|
||||
}
|
||||
|
||||
@ -81,17 +83,9 @@ clear_channel (session *sess)
|
||||
void
|
||||
set_topic (session *sess, char *topic, char *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);
|
||||
if (sess->topic)
|
||||
free (sess->topic);
|
||||
sess->topic = strdup (stripped_topic);
|
||||
fe_set_topic (sess, topic, stripped_topic);
|
||||
}
|
||||
|
||||
@ -127,7 +121,7 @@ find_session_from_nick (char *nick, server *serv)
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static session *
|
||||
@ -188,7 +182,16 @@ 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;
|
||||
}
|
||||
@ -555,7 +558,7 @@ find_unused_session (server *serv)
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static session *
|
||||
@ -573,7 +576,7 @@ find_session_from_waitchannel (char *chan, struct server *serv)
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
@ -679,8 +682,7 @@ inbound_nameslist (server *serv, char *chan, char *names,
|
||||
char **name_list;
|
||||
char *host, *nopre_name;
|
||||
char name[NICKLEN];
|
||||
int i;
|
||||
size_t offset;
|
||||
int i, offset;
|
||||
|
||||
sess = find_channel (serv, chan);
|
||||
if (!sess)
|
||||
@ -914,7 +916,7 @@ inbound_ping_reply (session *sess, char *timestring, char *from,
|
||||
tags_data->timestamp);
|
||||
} else
|
||||
{
|
||||
g_snprintf (outbuf, sizeof (outbuf), "%ld.%03ld", dif / 1000, dif % 1000);
|
||||
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);
|
||||
}
|
||||
@ -932,7 +934,7 @@ find_session_from_type (int type, server *serv)
|
||||
return sess;
|
||||
list = list->next;
|
||||
}
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
@ -967,14 +969,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 = g_strdup (msg + 1);
|
||||
char *dest = strdup (msg + 1);
|
||||
char *end = strchr (dest, ']');
|
||||
if (end)
|
||||
{
|
||||
*end = 0;
|
||||
sess = find_channel (serv, dest);
|
||||
}
|
||||
g_free (dest);
|
||||
free (dest);
|
||||
}
|
||||
}
|
||||
if (!sess)
|
||||
@ -1453,7 +1455,8 @@ inbound_user_info (session *sess, char *chan, char *user, char *host,
|
||||
|
||||
if (user && host)
|
||||
{
|
||||
uhost = g_strdup_printf ("%s@%s", user, host);
|
||||
uhost = g_malloc (strlen (user) + strlen (host) + 2);
|
||||
sprintf (uhost, "%s@%s", user, host);
|
||||
}
|
||||
|
||||
if (chan)
|
||||
|
@ -47,9 +47,13 @@
|
||||
|
||||
#else
|
||||
|
||||
#include "config.h"
|
||||
#include "../../config.h"
|
||||
#ifdef USE_IPV6
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#define set_blocking(sok) { \
|
||||
unsigned long zero = 0; \
|
||||
|
@ -87,11 +87,9 @@ int main(void)
|
||||
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");
|
||||
|
@ -2,7 +2,6 @@
|
||||
<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">
|
||||
@ -20,30 +19,82 @@
|
||||
<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" />
|
||||
<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>
|
||||
<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>
|
||||
</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" />
|
||||
</Project>
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -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);
|
||||
|
||||
g_free(sess->current_modes);
|
||||
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);
|
||||
}
|
||||
|
||||
g_free(sess->current_modes);
|
||||
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);
|
||||
|
||||
g_free(sess->current_modes);
|
||||
free(sess->current_modes);
|
||||
sess->current_modes = g_string_free(current, FALSE);
|
||||
}
|
||||
}
|
||||
@ -374,13 +374,12 @@ mode_cat (char *str, char *addition)
|
||||
if (str)
|
||||
{
|
||||
len = strlen (str) + strlen (addition) + 2;
|
||||
str = g_realloc (str, len);
|
||||
str = realloc (str, len);
|
||||
strcat (str, " ");
|
||||
strcat (str, addition);
|
||||
}
|
||||
else
|
||||
} else
|
||||
{
|
||||
str = g_strdup (addition);
|
||||
str = strdup (addition);
|
||||
}
|
||||
|
||||
return str;
|
||||
@ -561,12 +560,12 @@ handle_single_mode (mode_run *mr, char sign, char mode, char *nick,
|
||||
{
|
||||
if (*arg)
|
||||
{
|
||||
char *buf = g_strdup_printf ("%s %s", chan, arg);
|
||||
char *buf = malloc (strlen (chan) + strlen (arg) + 2);
|
||||
sprintf (buf, "%s %s", chan, arg);
|
||||
EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANMODEGEN, sess, nick, outbuf,
|
||||
outbuf + 2, buf, 0, tags_data->timestamp);
|
||||
g_free (buf);
|
||||
}
|
||||
else
|
||||
free (buf);
|
||||
} else
|
||||
EMIT_SIGNAL_TIMESTAMP (XP_TE_CHANMODEGEN, sess, nick, outbuf,
|
||||
outbuf + 2, chan, 0, tags_data->timestamp);
|
||||
}
|
||||
@ -636,7 +635,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);
|
||||
g_free(mr->op);
|
||||
free (mr->op);
|
||||
mr->op = NULL;
|
||||
}
|
||||
|
||||
@ -644,7 +643,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);
|
||||
g_free(mr->deop);
|
||||
free (mr->deop);
|
||||
mr->deop = NULL;
|
||||
}
|
||||
|
||||
@ -652,7 +651,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);
|
||||
g_free(mr->voice);
|
||||
free (mr->voice);
|
||||
mr->voice = NULL;
|
||||
}
|
||||
|
||||
@ -660,7 +659,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);
|
||||
g_free(mr->devoice);
|
||||
free (mr->devoice);
|
||||
mr->devoice = NULL;
|
||||
}
|
||||
}
|
||||
@ -678,10 +677,10 @@ handle_mode (server * serv, char *word[], char *word_eol[],
|
||||
char *argstr;
|
||||
char sign;
|
||||
int len;
|
||||
size_t arg;
|
||||
size_t i, num_args;
|
||||
int arg;
|
||||
int i, num_args;
|
||||
int num_modes;
|
||||
size_t offset = 3;
|
||||
int offset = 3;
|
||||
int all_modes_have_args = FALSE;
|
||||
int using_front_tab = FALSE;
|
||||
mode_run mr;
|
||||
@ -718,8 +717,9 @@ handle_mode (server * serv, char *word[], char *word_eol[],
|
||||
|
||||
if (numeric_324 && !using_front_tab)
|
||||
{
|
||||
g_free (sess->current_modes);
|
||||
sess->current_modes = g_strdup (word_eol[offset+1]);
|
||||
if (sess->current_modes)
|
||||
free (sess->current_modes);
|
||||
sess->current_modes = 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,29 +799,30 @@ 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)
|
||||
{
|
||||
g_free (serv->chantypes);
|
||||
serv->chantypes = g_strdup (word[w] + 10);
|
||||
free (serv->chantypes);
|
||||
serv->chantypes = strdup (word[w] + 10);
|
||||
} else if (strncmp (word[w], "CHANMODES=", 10) == 0)
|
||||
{
|
||||
g_free (serv->chanmodes);
|
||||
serv->chanmodes = g_strdup (word[w] + 10);
|
||||
free (serv->chanmodes);
|
||||
serv->chanmodes = 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 ')' */
|
||||
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);
|
||||
free (serv->nick_prefixes);
|
||||
free (serv->nick_modes);
|
||||
serv->nick_prefixes = strdup (pre + 1);
|
||||
serv->nick_modes = 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;
|
||||
g_free (serv->bad_nick_prefixes);
|
||||
serv->bad_nick_prefixes = g_strdup (word[w] + 7);
|
||||
if (serv->bad_nick_prefixes)
|
||||
free (serv->bad_nick_prefixes);
|
||||
serv->bad_nick_prefixes = strdup (word[w] + 7);
|
||||
}
|
||||
} else if (strncmp (word[w], "WATCH=", 6) == 0)
|
||||
{
|
||||
@ -831,6 +832,10 @@ 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);
|
||||
|
470
src/common/msproxy.c
Normal file
470
src/common/msproxy.c
Normal file
@ -0,0 +1,470 @@
|
||||
/* 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
|
262
src/common/msproxy.h
Normal file
262
src/common/msproxy.h
Normal file
@ -0,0 +1,262 @@
|
||||
/* 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
|
@ -18,8 +18,6 @@
|
||||
|
||||
/* ipv4 and ipv6 networking functions with a common interface */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@ -28,6 +26,7 @@
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "../../config.h"
|
||||
|
||||
#define WANTSOCKET
|
||||
#define WANTARPA
|
||||
@ -65,17 +64,128 @@ net_ip (guint32 addr)
|
||||
void
|
||||
net_store_destroy (netstore * ns)
|
||||
{
|
||||
#ifdef USE_IPV6
|
||||
if (ns->ip6_hostent)
|
||||
freeaddrinfo (ns->ip6_hostent);
|
||||
g_free (ns);
|
||||
#endif
|
||||
free (ns);
|
||||
}
|
||||
|
||||
netstore *
|
||||
net_store_new (void)
|
||||
{
|
||||
return g_new0 (netstore, 1);
|
||||
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;
|
||||
}
|
||||
|
||||
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 *
|
||||
@ -121,11 +231,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 = g_strdup (ns->ip6_hostent->ai_canonname);
|
||||
*real_host = strdup (ns->ip6_hostent->ai_canonname);
|
||||
else
|
||||
*real_host = g_strdup (hostname);
|
||||
*real_host = strdup (hostname);
|
||||
|
||||
return g_strdup (ipstring);
|
||||
return strdup (ipstring);
|
||||
}
|
||||
|
||||
/* the only thing making this interface unclean, this shitty sok4, sok6 business */
|
||||
@ -188,3 +298,88 @@ 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
|
||||
|
@ -23,7 +23,12 @@
|
||||
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
|
||||
@ -38,5 +43,11 @@ 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
|
||||
|
@ -47,7 +47,7 @@ int notify_tag = 0;
|
||||
static char *
|
||||
despacify_dup (char *str)
|
||||
{
|
||||
char *p, *res = g_malloc (strlen (str) + 1);
|
||||
char *p, *res = malloc (strlen (str) + 1);
|
||||
|
||||
p = res;
|
||||
while (1)
|
||||
@ -70,11 +70,11 @@ notify_netcmp (char *str, void *serv)
|
||||
|
||||
if (rfc_casecmp (str, net) == 0)
|
||||
{
|
||||
g_free (net);
|
||||
free (net);
|
||||
return 0; /* finish & return FALSE from token_foreach() */
|
||||
}
|
||||
|
||||
g_free (net);
|
||||
free (net);
|
||||
return 1; /* keep going... */
|
||||
}
|
||||
|
||||
@ -111,10 +111,14 @@ notify_find_server_entry (struct notify *notify, struct server *serv)
|
||||
if (!notify_do_network (notify, serv))
|
||||
return NULL;
|
||||
|
||||
servnot = g_new0 (struct notify_per_server, 1);
|
||||
servnot->server = serv;
|
||||
servnot->notify = notify;
|
||||
notify->server_list = g_slist_prepend (notify->server_list, servnot);
|
||||
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);
|
||||
}
|
||||
return servnot;
|
||||
}
|
||||
|
||||
@ -196,7 +200,7 @@ notify_find (server *serv, char *nick)
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -243,9 +247,10 @@ 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 = g_strdup_printf ("%s %s", nick, nick);
|
||||
char *wii_str = malloc (strlen (nick) * 2 + 2);
|
||||
sprintf (wii_str, "%s %s", nick, nick);
|
||||
serv->p_whois (serv, wii_str);
|
||||
g_free (wii_str);
|
||||
free (wii_str);
|
||||
}
|
||||
}
|
||||
|
||||
@ -341,9 +346,9 @@ notify_watch (server * serv, char *nick, int add)
|
||||
addchar = '-';
|
||||
|
||||
if (serv->supports_monitor)
|
||||
g_snprintf (tbuf, sizeof (tbuf), "MONITOR %c %s", addchar, nick);
|
||||
snprintf (tbuf, sizeof (tbuf), "MONITOR %c %s", addchar, nick);
|
||||
else if (serv->supports_watch)
|
||||
g_snprintf (tbuf, sizeof (tbuf), "WATCH %c%s", addchar, nick);
|
||||
snprintf (tbuf, sizeof (tbuf), "WATCH %c%s", addchar, nick);
|
||||
else
|
||||
return;
|
||||
|
||||
@ -556,9 +561,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)
|
||||
g_snprintf (outbuf, sizeof (outbuf), _(" %-20s online\n"), notify->name);
|
||||
snprintf (outbuf, sizeof (outbuf), _(" %-20s online\n"), notify->name);
|
||||
else
|
||||
g_snprintf (outbuf, sizeof (outbuf), _(" %-20s offline\n"), notify->name);
|
||||
snprintf (outbuf, sizeof (outbuf), _(" %-20s offline\n"), notify->name);
|
||||
PrintTextTimeStamp (sess, outbuf, tags_data->timestamp);
|
||||
list = list->next;
|
||||
}
|
||||
@ -591,13 +596,14 @@ notify_deluser (char *name)
|
||||
servnot = (struct notify_per_server *) notify->server_list->data;
|
||||
notify->server_list =
|
||||
g_slist_remove (notify->server_list, servnot);
|
||||
g_free (servnot);
|
||||
free (servnot);
|
||||
}
|
||||
notify_list = g_slist_remove (notify_list, notify);
|
||||
notify_watch_all (notify, FALSE);
|
||||
g_free (notify->networks);
|
||||
g_free (notify->name);
|
||||
g_free (notify);
|
||||
if (notify->networks)
|
||||
free (notify->networks);
|
||||
free (notify->name);
|
||||
free (notify);
|
||||
fe_notify_update (0);
|
||||
return 1;
|
||||
}
|
||||
@ -609,18 +615,27 @@ notify_deluser (char *name)
|
||||
void
|
||||
notify_adduser (char *name, char *networks)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -699,7 +714,7 @@ notify_cleanup ()
|
||||
{
|
||||
notify->server_list =
|
||||
g_slist_remove (notify->server_list, servnot);
|
||||
g_free (servnot);
|
||||
free (servnot);
|
||||
nslist = notify->server_list;
|
||||
} else
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user