Compare commits

..

1 Commits

Author SHA1 Message Date
7909738a09 add get_list(networks) to plugin api 2013-06-23 01:19:02 -04:00
485 changed files with 173735 additions and 178973 deletions

View File

@ -1,19 +0,0 @@
# EditorConfig is awesome: http://EditorConfig.org
# top-most EditorConfig file
root = true
[*.{c,cpp,h,hpp,m}]
indent_style = tab
indent_size = 4
end_of_line = lf
[*.cs]
indent_style = space
indent_size = 4
end_of_line = lf
[{meson.build,meson_options.txt}]
indent_size = 2
indent_style = space
insert_final_newline = true

67
.gitignore vendored
View File

@ -1,29 +1,70 @@
/build
builddir/
# git ignore file
# Unix generated files
.deps/
.libs/
Makefile
Makefile.in
aclocal.m4
autom4te.cache/
compile
confdefs.h
conftest
conftest.c
conftest.err
config.guess
config.h.in
config.h
config.log
config.status
config.sub
configure
configure.tmp
depcomp
doxygen*.tmp
html/
*.patch
tags
install-sh
intl/
libtool
ltmain.sh
m4/
missing
plugins/perl/irc.pm.h
plugins/perl/xchat.pm.h
po/Makefile.in.in
po/POTFILES
po/remove-potcdate.sed
po/stamp-po
share/pkgconfig/hexchat-plugin.pc
src/common/dbus/example
src/common/dbus/marshallers.h
src/common/dbus/org.hexchat.service.service
src/common/dbus/remote-object-glue.h
src/common/make-te
src/common/textenums.h
src/common/textevents.h
src/fe-gtk/hexchat
src/fe-text/hexchat-text
src/htm/thememan.exe
stamp-h1
*.a
*.o
*.la
*.lo
*.gmo
*.mo
*.po~
# Win32 generated files
plugins/wmpa/wmpa_h.h
plugins/wmpa/wmpa_i.c
src/pixmaps/inline_pngs.h
src/htm/obj/*
win32/ipch/*
win32/ext/perl/perl-x86-cache
win32/ext/perl/perl-x86-SetupFiles
win32/ext/perl/perl-x64-cache
win32/ext/perl/perl-x64-SetupFiles
win32/installer/hexchat.iss
resource.h
*.opensdf
*.sdf
*.suo
*.user
*.exe
# OSX
osx/HexChat.app
osx/.HexChat.app
*.zip
*.dmg
*.VC.db
*.VC.opendb

View File

@ -1,10 +0,0 @@
Berke Viktor <github.bviktor@outlook.com> <berkeviktor@aol.com>
Berke Viktor <github.bviktor@outlook.com> <bviktor@hexchat.org>
Berke Viktor <github.bviktor@outlook.com> <bviktor@outlook.com>
Berke Viktor <github.bviktor@outlook.com> berkeviktor@aol.com
Patrick Griffis <tingping@tingping.se> TingPing <tingping@fedoraproject.org>
Patrick Griffis <tingping@tingping.se> TingPing <tingping@tingping.se>
Patrick Griffis <tingping@tingping.se> TingPing <tngpng@gmail.com>
Patrick Griffis <tingping@tingping.se> TingPing <TingPing@users.noreply.github.com>
Arnav Singh <arnavion@gmail.com> Arnavion
Eustachy Kapusta <Eustachy.kapusta@gmail.com> tomek

View File

@ -1,20 +1,14 @@
sudo: required
services: docker
before_install:
- docker pull ubuntu:16.04
- docker run --privileged --cidfile=/tmp/cid ubuntu:16.04 /bin/sh -c 'apt-get update && apt-get install -y meson/xenial-backports libcanberra-dev libdbus-glib-1-dev libglib2.0-dev libgtk2.0-dev libluajit-5.1-dev libnotify-dev libpci-dev libperl-dev libproxy-dev libssl-dev python3-dev mono-devel desktop-file-utils'
- docker commit `cat /tmp/cid` hexchat/ubuntu-ci
- rm -f /tmp/cid
install:
- docker run -d --privileged --cidfile=/tmp/cid --volume=${PWD}:/opt/hexchat hexchat/ubuntu-ci /bin/systemd --system
script:
- docker exec `cat /tmp/cid` /bin/sh -c 'meson /opt/hexchat /opt/hexchat-build -Dwith-text=true -Dwith-theme-manager=true && ninja -C /opt/hexchat-build install'
after_script:
- docker kill `cat /tmp/cid`
language: c
compiler: gcc
before_script:
- sudo apt-get build-dep -qq xchat
- sudo apt-get install -qq libnotify-dev libproxy-dev libpci-dev libcanberra-dev
script:
- ./autogen.sh
- ./configure --enable-textfe
- make
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

View File

@ -1,8 +1,9 @@
[main]
host = https://www.transifex.com
[hexchat.main]
file_filter = po/<lang>.po
source_file = po/hexchat.pot
source_lang = en
type = PO
[main]
host = https://www.transifex.com
[hexchat.main]
file_filter = po\<lang>.po
source_file = po\hexchat.pot
source_lang = en
type = PO

6
Makefile.am Normal file
View File

@ -0,0 +1,6 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = po intl src plugins man share
EXTRA_DIST = autogen.sh

40
acinclude.m4 Normal file
View File

@ -0,0 +1,40 @@
dnl AS_AC_EXPAND(VAR, CONFIGURE_VAR)
dnl
dnl example
dnl AS_AC_EXPAND(SYSCONFDIR, $sysconfdir)
dnl will set SYSCONFDIR to /usr/local/etc if prefix=/usr/local
AC_DEFUN([AS_AC_EXPAND],
[
EXP_VAR=[$1]
FROM_VAR=[$2]
dnl first expand prefix and exec_prefix if necessary
prefix_save=$prefix
exec_prefix_save=$exec_prefix
dnl if no prefix given, then use /usr/local, the default prefix
if test "x$prefix" = "xNONE"; then
prefix=$ac_default_prefix
fi
dnl if no exec_prefix given, then use prefix
if test "x$exec_prefix" = "xNONE"; then
exec_prefix=$prefix
fi
full_var="$FROM_VAR"
dnl loop until it doesn't change anymore
while true; do
new_full_var="`eval echo $full_var`"
if test "x$new_full_var" = "x$full_var"; then break; fi
full_var=$new_full_var
done
dnl clean up
full_var=$new_full_var
AC_SUBST([$1], "$full_var")
dnl restore prefix and exec_prefix
prefix=$prefix_save
exec_prefix=$exec_prefix_save
])

113
autogen.sh Executable file
View File

@ -0,0 +1,113 @@
#!/bin/bash
have_automake=false
if automake --version < /dev/null > /dev/null 2>&1 ; then
automake_version=`automake --version | grep 'automake (GNU automake)' | sed 's/^[^0-9]*\(.*\)/\1/'`
case $automake_version in
1.2*|1.3*|1.4|1.4*|1.5*|1.6*|1.7*|1.8*)
;;
*)
have_automake=true
;;
esac
fi
if $have_automake ; then
AUTOMAKE="automake"
ACLOCAL="aclocal"
else
if automake-1.9 --version < /dev/null > /dev/null 2>&1 ; then
AUTOMAKE="automake-1.9"
ACLOCAL="aclocal-1.9"
else
echo "automake missing or too old. This requires at least automake 1.9"
exit 1
fi
fi
# ------ START GETTEXT ------
echo searching for GNU gettext intl directory...
dirs="/usr/share /usr/local/share /opt/share /usr /usr/local /opt /usr/gnu/share /opt/local /opt/local/share"
found=0
for try in $dirs; do
echo -n " -> $try/gettext/intl... "
if test -d $try/gettext/intl; then
echo found it
found=1
break
fi
echo no
done
if test "$found" != 1; then
echo ERROR: Cannot find gettext/intl directory.
echo ERROR: Install GNU gettext in /usr or /usr/local prefix.
exit 7
fi;
echo copying gettext intl files...
if test -f $try/gettext/mkinstalldirs; then
ln -s $try/gettext/mkinstalldirs mkinstalldirs
fi
intldir="$try/gettext/intl"
if test ! -d intl; then
mkdir intl
fi
olddir=`pwd`
cd $intldir
for file in *; do
if test $file != COPYING.LIB-2.0 && test $file != COPYING.LIB-2.1; then
rm -f $olddir/intl/$file
cp $intldir/$file $olddir/intl/
fi
done
cp -f $try/gettext/po/Makefile.in.in $olddir/po/
cd $olddir
if test -f intl/plural.c; then
sleep 2
touch intl/plural.c
fi
# ------ END GETTEXT ------
echo running $ACLOCAL...
$ACLOCAL $ACLOCAL_FLAGS
if test "$?" != "0"; then
echo aclocal failed, stopping.
exit 2
fi
echo running libtoolize...
libtoolize --force
if test "$?" != "0"; then
echo libtoolize failed, stopping.
exit 3
fi
echo running autoheader...
autoheader
if test "$?" != "0"; then
echo autoheader failed, stopping.
exit 4
fi
echo running $AUTOMAKE...
$AUTOMAKE -a
if test "$?" != "0"; then
echo automake failed, stopping.
exit 5
fi
echo running autoconf...
autoconf
if test "$?" != "0"; then
echo autoconf failed, stopping.
exit 6
fi
echo if no errors occured, run ./configure
exit 0
#autogen.sh generates:
# aclocal.m4 Makefile.in config.guess config.sub ltmain.sh
# configure install-sh missing mkinstalldirs depcomp
#
#configure generates:
# config.status libtool Makefile.in

View File

@ -1,14 +1,18 @@
#define LOCALEDIR ".\\share\\locale"
#define ENABLE_NLS
#define USE_GMODULE
#define USE_PLUGIN
#define USE_OPENSSL
#define USE_LIBSEXY
#define USE_IPV6
#define HAVE_ISO_CODES
#define ISO_CODES_PREFIX ".\\"
#define ISO_CODES_LOCALEDIR LOCALEDIR
#define PACKAGE_NAME "hexchat"
#define PACKAGE_VERSION "<#= [string]::Join('.', $versionParts) #>"
#define PACKAGE_VERSION "2.9.5"
#define HEXCHATLIBDIR ".\\plugins"
#define HEXCHATSHAREDIR "."
#define OLD_PERL
#define GETTEXT_PACKAGE "hexchat"
#define PACKAGE_TARNAME "hexchat-<#= [string]::Join('.', $versionParts) #>"
#define PACKAGE_TARNAME "hexchat-2.9.5"
#ifndef USE_IPV6
#define socklen_t int
#endif

672
config.rpath Normal file
View File

@ -0,0 +1,672 @@
#! /bin/sh
# Output a system dependent set of variables, describing how to set the
# run time search path of shared libraries in an executable.
#
# Copyright 1996-2010 Free Software Foundation, Inc.
# Taken from GNU libtool, 2001
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# The first argument passed to this file is the canonical host specification,
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
# should be set by the caller.
#
# The set of defined variables is at the end of this script.
# Known limitations:
# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
# than 256 bytes, otherwise the compiler driver will dump core. The only
# known workaround is to choose shorter directory names for the build
# directory and/or the installation directory.
# All known linkers require a `.a' archive for static linking (except MSVC,
# which needs '.lib').
libext=a
shrext=.so
host="$1"
host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
# Code taken from libtool.m4's _LT_CC_BASENAME.
for cc_temp in $CC""; do
case $cc_temp in
compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
\-*) ;;
*) break;;
esac
done
cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
# Code taken from libtool.m4's _LT_COMPILER_PIC.
wl=
if test "$GCC" = yes; then
wl='-Wl,'
else
case "$host_os" in
aix*)
wl='-Wl,'
;;
darwin*)
case $cc_basename in
xlc*)
wl='-Wl,'
;;
esac
;;
mingw* | cygwin* | pw32* | os2* | cegcc*)
;;
hpux9* | hpux10* | hpux11*)
wl='-Wl,'
;;
irix5* | irix6* | nonstopux*)
wl='-Wl,'
;;
newsos6)
;;
linux* | k*bsd*-gnu)
case $cc_basename in
ecc*)
wl='-Wl,'
;;
icc* | ifort*)
wl='-Wl,'
;;
lf95*)
wl='-Wl,'
;;
pgcc | pgf77 | pgf90)
wl='-Wl,'
;;
ccc*)
wl='-Wl,'
;;
como)
wl='-lopt='
;;
*)
case `$CC -V 2>&1 | sed 5q` in
*Sun\ C*)
wl='-Wl,'
;;
esac
;;
esac
;;
osf3* | osf4* | osf5*)
wl='-Wl,'
;;
rdos*)
;;
solaris*)
wl='-Wl,'
;;
sunos4*)
wl='-Qoption ld '
;;
sysv4 | sysv4.2uw2* | sysv4.3*)
wl='-Wl,'
;;
sysv4*MP*)
;;
sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
wl='-Wl,'
;;
unicos*)
wl='-Wl,'
;;
uts4*)
;;
esac
fi
# Code taken from libtool.m4's _LT_LINKER_SHLIBS.
hardcode_libdir_flag_spec=
hardcode_libdir_separator=
hardcode_direct=no
hardcode_minus_L=no
case "$host_os" in
cygwin* | mingw* | pw32* | cegcc*)
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
if test "$GCC" != yes; then
with_gnu_ld=no
fi
;;
interix*)
# we just hope/assume this is gcc and not c89 (= MSVC++)
with_gnu_ld=yes
;;
openbsd*)
with_gnu_ld=no
;;
esac
ld_shlibs=yes
if test "$with_gnu_ld" = yes; then
# Set some defaults for GNU ld with shared library support. These
# are reset later if shared libraries are not supported. Putting them
# here allows them to be overridden if necessary.
# Unlike libtool, we use -rpath here, not --rpath, since the documented
# option of GNU ld is called -rpath, not --rpath.
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
case "$host_os" in
aix[3-9]*)
# On AIX/PPC, the GNU linker is very broken
if test "$host_cpu" != ia64; then
ld_shlibs=no
fi
;;
amigaos*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
# Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
# that the semantics of dynamic libraries on AmigaOS, at least up
# to version 4, is to share data among multiple programs linked
# with the same dynamic library. Since this doesn't match the
# behavior of shared libraries on other platforms, we cannot use
# them.
ld_shlibs=no
;;
beos*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
cygwin* | mingw* | pw32* | cegcc*)
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec='-L$libdir'
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
interix[3-9]*)
hardcode_direct=no
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
gnu* | linux* | k*bsd*-gnu)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
netbsd*)
;;
solaris*)
if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
ld_shlibs=no
elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
case `$LD -v 2>&1` in
*\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
ld_shlibs=no
;;
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
else
ld_shlibs=no
fi
;;
esac
;;
sunos4*)
hardcode_direct=yes
;;
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
esac
if test "$ld_shlibs" = no; then
hardcode_libdir_flag_spec=
fi
else
case "$host_os" in
aix3*)
# Note: this linker hardcodes the directories in LIBPATH if there
# are no directories specified by -L.
hardcode_minus_L=yes
if test "$GCC" = yes; then
# Neither direct hardcoding nor static linking is supported with a
# broken collect2.
hardcode_direct=unsupported
fi
;;
aix[4-9]*)
if test "$host_cpu" = ia64; then
# On IA64, the linker does run time linking by default, so we don't
# have to do anything special.
aix_use_runtimelinking=no
else
aix_use_runtimelinking=no
# Test if we are trying to use run time linking or normal
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
# need to do runtime linking.
case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
for ld_flag in $LDFLAGS; do
if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
aix_use_runtimelinking=yes
break
fi
done
;;
esac
fi
hardcode_direct=yes
hardcode_libdir_separator=':'
if test "$GCC" = yes; then
case $host_os in aix4.[012]|aix4.[012].*)
collect2name=`${CC} -print-prog-name=collect2`
if test -f "$collect2name" && \
strings "$collect2name" | grep resolve_lib_name >/dev/null
then
# We have reworked collect2
:
else
# We have old collect2
hardcode_direct=unsupported
hardcode_minus_L=yes
hardcode_libdir_flag_spec='-L$libdir'
hardcode_libdir_separator=
fi
;;
esac
fi
# Begin _LT_AC_SYS_LIBPATH_AIX.
echo 'int main () { return 0; }' > conftest.c
${CC} ${LDFLAGS} conftest.c -o conftest
aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
}'`
if test -z "$aix_libpath"; then
aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
}'`
fi
if test -z "$aix_libpath"; then
aix_libpath="/usr/lib:/lib"
fi
rm -f conftest.c conftest
# End _LT_AC_SYS_LIBPATH_AIX.
if test "$aix_use_runtimelinking" = yes; then
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
else
if test "$host_cpu" = ia64; then
hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
else
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
fi
fi
;;
amigaos*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
# see comment about different semantics on the GNU ld section
ld_shlibs=no
;;
bsdi[45]*)
;;
cygwin* | mingw* | pw32* | cegcc*)
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec=' '
libext=lib
;;
darwin* | rhapsody*)
hardcode_direct=no
if test "$GCC" = yes ; then
:
else
case $cc_basename in
xlc*)
;;
*)
ld_shlibs=no
;;
esac
fi
;;
dgux*)
hardcode_libdir_flag_spec='-L$libdir'
;;
freebsd1*)
ld_shlibs=no
;;
freebsd2.2*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
freebsd2*)
hardcode_direct=yes
hardcode_minus_L=yes
;;
freebsd* | dragonfly*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
hpux9*)
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
;;
hpux10*)
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
fi
;;
hpux11*)
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
case $host_cpu in
hppa*64*|ia64*)
hardcode_direct=no
;;
*)
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
;;
esac
fi
;;
irix5* | irix6* | nonstopux*)
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
netbsd*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
newsos6)
hardcode_direct=yes
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
openbsd*)
if test -f /usr/libexec/ld.so; then
hardcode_direct=yes
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
else
case "$host_os" in
openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
hardcode_libdir_flag_spec='-R$libdir'
;;
*)
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
esac
fi
else
ld_shlibs=no
fi
;;
os2*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
;;
osf3*)
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
osf4* | osf5*)
if test "$GCC" = yes; then
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
else
# Both cc and cxx compiler support -rpath directly
hardcode_libdir_flag_spec='-rpath $libdir'
fi
hardcode_libdir_separator=:
;;
solaris*)
hardcode_libdir_flag_spec='-R$libdir'
;;
sunos4*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_direct=yes
hardcode_minus_L=yes
;;
sysv4)
case $host_vendor in
sni)
hardcode_direct=yes # is this really true???
;;
siemens)
hardcode_direct=no
;;
motorola)
hardcode_direct=no #Motorola manual says yes, but my tests say they lie
;;
esac
;;
sysv4.3*)
;;
sysv4*MP*)
if test -d /usr/nec; then
ld_shlibs=yes
fi
;;
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
;;
sysv5* | sco3.2v5* | sco5v6*)
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
hardcode_libdir_separator=':'
;;
uts4*)
hardcode_libdir_flag_spec='-L$libdir'
;;
*)
ld_shlibs=no
;;
esac
fi
# Check dynamic linker characteristics
# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER.
# Unlike libtool.m4, here we don't care about _all_ names of the library, but
# only about the one the linker finds when passed -lNAME. This is the last
# element of library_names_spec in libtool.m4, or possibly two of them if the
# linker has special search rules.
library_names_spec= # the last element of library_names_spec in libtool.m4
libname_spec='lib$name'
case "$host_os" in
aix3*)
library_names_spec='$libname.a'
;;
aix[4-9]*)
library_names_spec='$libname$shrext'
;;
amigaos*)
library_names_spec='$libname.a'
;;
beos*)
library_names_spec='$libname$shrext'
;;
bsdi[45]*)
library_names_spec='$libname$shrext'
;;
cygwin* | mingw* | pw32* | cegcc*)
shrext=.dll
library_names_spec='$libname.dll.a $libname.lib'
;;
darwin* | rhapsody*)
shrext=.dylib
library_names_spec='$libname$shrext'
;;
dgux*)
library_names_spec='$libname$shrext'
;;
freebsd1*)
;;
freebsd* | dragonfly*)
case "$host_os" in
freebsd[123]*)
library_names_spec='$libname$shrext$versuffix' ;;
*)
library_names_spec='$libname$shrext' ;;
esac
;;
gnu*)
library_names_spec='$libname$shrext'
;;
hpux9* | hpux10* | hpux11*)
case $host_cpu in
ia64*)
shrext=.so
;;
hppa*64*)
shrext=.sl
;;
*)
shrext=.sl
;;
esac
library_names_spec='$libname$shrext'
;;
interix[3-9]*)
library_names_spec='$libname$shrext'
;;
irix5* | irix6* | nonstopux*)
library_names_spec='$libname$shrext'
case "$host_os" in
irix5* | nonstopux*)
libsuff= shlibsuff=
;;
*)
case $LD in
*-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
*-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
*-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
*) libsuff= shlibsuff= ;;
esac
;;
esac
;;
linux*oldld* | linux*aout* | linux*coff*)
;;
linux* | k*bsd*-gnu)
library_names_spec='$libname$shrext'
;;
knetbsd*-gnu)
library_names_spec='$libname$shrext'
;;
netbsd*)
library_names_spec='$libname$shrext'
;;
newsos6)
library_names_spec='$libname$shrext'
;;
nto-qnx*)
library_names_spec='$libname$shrext'
;;
openbsd*)
library_names_spec='$libname$shrext$versuffix'
;;
os2*)
libname_spec='$name'
shrext=.dll
library_names_spec='$libname.a'
;;
osf3* | osf4* | osf5*)
library_names_spec='$libname$shrext'
;;
rdos*)
;;
solaris*)
library_names_spec='$libname$shrext'
;;
sunos4*)
library_names_spec='$libname$shrext$versuffix'
;;
sysv4 | sysv4.3*)
library_names_spec='$libname$shrext'
;;
sysv4*MP*)
library_names_spec='$libname$shrext'
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
library_names_spec='$libname$shrext'
;;
uts4*)
library_names_spec='$libname$shrext'
;;
esac
sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
# How to pass a linker flag through the compiler.
wl="$escaped_wl"
# Static library suffix (normally "a").
libext="$libext"
# Shared library suffix (normally "so").
shlibext="$shlibext"
# Format of library name prefix.
libname_spec="$escaped_libname_spec"
# Library names that the linker finds when passed -lNAME.
library_names_spec="$escaped_library_names_spec"
# Flag to hardcode \$libdir into a binary during linking.
# This must work even if \$libdir does not exist.
hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
# Whether we need a single -rpath flag with a separated argument.
hardcode_libdir_separator="$hardcode_libdir_separator"
# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
# resulting binary.
hardcode_direct="$hardcode_direct"
# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
# resulting binary.
hardcode_minus_L="$hardcode_minus_L"
EOF

1030
configure.ac Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/icons">
<file alias="hexchat.png" preprocess="to-pixdata">icons/hexchat.png</file>
<file alias="book.png" preprocess="to-pixdata">icons/book.png</file>
<file alias="ulist_voice.png" preprocess="to-pixdata">icons/ulist_voice.png</file>
<file alias="ulist_halfop.png" preprocess="to-pixdata">icons/ulist_halfop.png</file>
<file alias="ulist_op.png" preprocess="to-pixdata">icons/ulist_op.png</file>
<file alias="ulist_owner.png" preprocess="to-pixdata">icons/ulist_owner.png</file>
<file alias="ulist_founder.png" preprocess="to-pixdata">icons/ulist_founder.png</file>
<file alias="ulist_netop.png" preprocess="to-pixdata">icons/ulist_netop.png</file>
<file alias="tray_normal.png" preprocess="to-pixdata">icons/hexchat.png</file>
<file alias="tray_fileoffer.png" preprocess="to-pixdata">icons/tray_fileoffer.png</file>
<file alias="tray_highlight.png" preprocess="to-pixdata">icons/tray_highlight.png</file>
<file alias="tray_message.png" preprocess="to-pixdata">icons/tray_message.png</file>
<file alias="tree_channel.png" preprocess="to-pixdata">icons/tree_channel.png</file>
<file alias="tree_dialog.png" preprocess="to-pixdata">icons/tree_dialog.png</file>
<file alias="tree_server.png" preprocess="to-pixdata">icons/tree_server.png</file>
<file alias="tree_util.png" preprocess="to-pixdata">icons/tree_util.png</file>
</gresource>
</gresources>

View File

@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
height="64"
width="64">
<metadata>
<rdf:RDF>
<cc:Work>
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:creator>
<cc:Agent>
<dc:title>Guglielmi David</dc:title>
</cc:Agent>
</dc:creator>
<cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
<dc:rights>
<cc:Agent>
<dc:title>Peter Zelezny</dc:title>
</cc:Agent>
</dc:rights>
<dc:contributor>
<cc:Agent>
<dc:title>Samuel Messner</dc:title>
</cc:Agent>
</dc:contributor>
</cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
<cc:requires rdf:resource="http://web.resource.org/cc/Notice" />
<cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" />
<cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" />
<cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" />
<cc:permits rdf:resource="http://web.resource.org/cc/Distribution" />
<cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<defs>
<linearGradient id="hexchatGradient" x1="0" y1="1" x2="0" y2="0">
<stop id="hgRedStop" offset="0" style="stop-color: #FF2600; stop-opacity: 1;" />
<stop id="hgYellowStop" offset="1" style="stop-color: #FFD600; stop-opacity: 1;" />
</linearGradient>
<filter inkscape:collect="always" id="dropshadow">
<feGaussianBlur inkscape:collect="always" stdDeviation="1.9736701" id="dropshadowGaussian" />
</filter>
</defs>
<path
style="fill: #000000; fill-opacity: 1;"
d="m 31.62506,4.4248023 c -7.285288,0.0713 -14.595323,0.526836 -15.96875,1.3125 C 12.909458,7.3086297 -0.0321942,29.523731 6.0185229e-5,32.612303 0.0323162,35.700876 13.470952,57.688808 16.25006,59.206053 c 2.779105,1.517245 29.159399,1.258827 31.90625,-0.3125 2.746852,-1.571328 15.688504,-23.786428 15.65625,-26.875 C 63.7803,28.929981 50.372918,6.9107967 47.59381,5.3935523 46.204258,4.6349293 38.910347,4.3535003 31.62506,4.4248023 z m -0.1875,9.2500007 c 3.386631,-0.03246 6.676687,0.05409 8.75,0.28125 l -8.71875,9.71875 -9.0625,-9.5 c 2.055746,-0.283043 5.521157,-0.466366 9.03125,-0.5 z m 17.34375,9.84375 c 2.298293,3.744897 4.302354,7.392556 4.3125,8.34375 0.01126,1.055883 -2.358157,5.507241 -4.875,9.6875 l -9.03125,-8.03125 z m -34.46875,0.25 8.75,9.75 -8.1875,7.875 c -2.482342,-3.992634 -4.707927,-8.110307 -4.71875,-9.125 -0.01021,-0.95736 1.927117,-4.687748 4.15625,-8.5 z m 17.15625,16.90625 9.8125,9.21875 c -4.111037,0.67314 -16.108253,0.781873 -19.46875,0.125 z"
id="outline"
sodipodi:nodetypes="ssssssssscccscsccccccsccccc" />
<path
style="fill: url(#hexchatGradient); fill-opacity: 1;"
d="m 31.25006,6.4873027 c -6.857093,0.06521 -13.707297,0.469014 -15,1.1875 -2.585405,1.4369712 -14.780358,21.7692653 -14.75,24.5937503 0.03036,2.824486 12.665486,22.924987 15.28125,24.3125 2.615763,1.387513 27.445846,1.186972 30.03125,-0.25 2.585405,-1.436972 14.780359,-21.769265 14.75,-24.59375 C 61.5322,28.912818 48.897074,8.7810649 46.28131,7.3935527 44.973429,6.6997957 38.107152,6.4220967 31.25006,6.4873027 z m 0.0625,5.0625003 c 5.36199,-0.05245 10.696035,0.19201 11.71875,0.75 0.06132,0.03346 0.143803,0.127745 0.21875,0.1875 l -11.28125,12.59375 -0.5,0.53125 -0.46875,-0.53125 -11.75,-12.3125 c 0.10903,-0.09884 0.228263,-0.201843 0.3125,-0.25 1.010846,-0.577879 6.38801,-0.916306 11.75,-0.96875 z m 18.0625,9.46875 c 2.883844,4.661341 5.612556,9.652893 5.625,10.84375 0.01348,1.290331 -3.064699,7.087557 -6.09375,12.09375 l -11.09375,-9.90625 -0.53125,-0.46875 0.5,-0.46875 11.59375,-12.09375 z m -35.78125,0.03125 10.84375,12.0625 0.4375,0.46875 -0.46875,0.4375 -10.28125,9.90625 c -3.04689,-4.86606 -6.049362,-10.36778 -6.0625,-11.625 -0.01271,-1.216102 2.689239,-6.451996 5.53125,-11.25 z m 17.875,17.78125 0.4375,0.4375 12.34375,11.59375 c -0.318014,0.365376 -0.587006,0.638955 -0.78125,0.75 -2.02169,1.155758 -21.423322,1.397228 -23.46875,0.28125 -0.228202,-0.124506 -0.601742,-0.47821 -1,-0.9375 l 12,-11.6875 0.46875,-0.4375 z"
id="coloredX" />
</svg>

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:xlink="http://www.w3.org/1999/xlink"
height="64"
width="64">
<metadata>
<rdf:RDF>
<cc:Work>
<dc:format>image/svg+xml</dc:format>
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:creator>
<cc:Agent>
<dc:title>Guglielmi David</dc:title>
</cc:Agent>
</dc:creator>
<cc:license rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
<dc:rights>
<cc:Agent>
<dc:title>Peter Zelezny</dc:title>
</cc:Agent>
</dc:rights>
<dc:contributor>
<cc:Agent>
<dc:title>Samuel Messner</dc:title>
</cc:Agent>
</dc:contributor>
</cc:Work>
<cc:License rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
<cc:requires rdf:resource="http://web.resource.org/cc/Notice" />
<cc:requires rdf:resource="http://web.resource.org/cc/ShareAlike" />
<cc:requires rdf:resource="http://web.resource.org/cc/SourceCode" />
<cc:permits rdf:resource="http://web.resource.org/cc/Reproduction" />
<cc:permits rdf:resource="http://web.resource.org/cc/Distribution" />
<cc:permits rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<defs>
<linearGradient id="hexchatGradient" x1="0" y1="0" x2="0" y2="1">
<stop id="hgYellowStop" offset="0" style="stop-color: #FFD600" />
<stop id="hgRedStop" offset="1" style="stop-color: #FF2600" />
</linearGradient>
</defs>
<use xlink:href="#outline" style="opacity:0.15" transform="translate(0,2)" id="shadow" />
<path
style="fill:#000000; fill-opacity: 1;"
d="M 31.71875,4.1088109 C 24.433462,4.1801109 17.123427,4.6356469 15.75,5.4213109 13.003148,6.9926379 0.06149557,29.207739 0.09374996,32.296311 0.12600597,35.384884 13.564642,57.372816 16.34375,58.890061 19.122855,60.407306 45.503149,60.148888 48.25,58.577561 50.996852,57.006233 63.938504,34.791133 63.90625,31.702561 63.87399,28.613989 50.466608,6.5948049 47.6875,5.0775609 46.297948,4.3189379 39.004037,4.0375089 31.71875,4.1088109 Z m -0.1875,9.2500001 c 3.386631,-0.03246 6.676687,0.05409 8.75,0.28125 l -8.71875,9.71875 -9.0625,-9.5 c 2.055746,-0.283043 5.521157,-0.466366 9.03125,-0.5 z m 17.34375,9.84375 c 2.298293,3.744897 4.302354,7.392556 4.3125,8.34375 0.01126,1.055883 -2.358157,5.507241 -4.875,9.6875 l -9.03125,-8.03125 z m -34.46875,0.25 8.75,9.75 -8.1875,7.875 c -2.482342,-3.992634 -4.707927,-8.110307 -4.71875,-9.125 -0.01021,-0.95736 1.927117,-4.687748 4.15625,-8.5 z m 17.15625,16.90625 9.8125,9.21875 c -4.111037,0.67314 -16.108253,0.781873 -19.46875,0.125 z"
id="outline" />
<path
style="fill:url(#hexchatGradient); fill-opacity: 1;"
d="m 31.34375,6.1713109 c -6.857093,0.06521 -13.707297,0.469014 -15,1.1875 C 13.758345,8.7957819 1.5633917,29.128076 1.5937497,31.952561 c 0.03036,2.824486 12.6654863,22.924987 15.2812503,24.3125 2.615763,1.387513 27.445846,1.186972 30.03125,-0.25 2.585405,-1.436972 14.780359,-21.769265 14.75,-24.59375 C 61.62589,28.596826 48.990764,8.4650729 46.375,7.0775609 45.067119,6.3838039 38.200842,6.1061049 31.34375,6.1713109 Z m 0.0625,5.0625001 c 5.36199,-0.05245 10.696035,0.19201 11.71875,0.75 0.06132,0.03346 0.143803,0.127745 0.21875,0.1875 l -11.28125,12.59375 -0.5,0.53125 -0.46875,-0.53125 -11.75,-12.3125 c 0.10903,-0.09884 0.228263,-0.201843 0.3125,-0.25 1.010846,-0.577879 6.38801,-0.916306 11.75,-0.96875 z m 18.0625,9.46875 c 2.883844,4.661341 5.612556,9.652893 5.625,10.84375 0.01348,1.290331 -3.064699,7.087557 -6.09375,12.09375 l -11.09375,-9.90625 -0.53125,-0.46875 0.5,-0.46875 11.59375,-12.09375 z m -35.78125,0.03125 10.84375,12.0625 0.4375,0.46875 -0.46875,0.4375 -10.28125,9.90625 c -3.04689,-4.86606 -6.0493623,-10.36778 -6.0625003,-11.625 -0.01271,-1.216102 2.6892393,-6.451996 5.5312503,-11.25 z m 17.875,17.78125 0.4375,0.4375 12.34375,11.59375 c -0.318014,0.365376 -0.587006,0.638955 -0.78125,0.75 -2.02169,1.155758 -21.423322,1.397228 -23.46875,0.28125 -0.228202,-0.124506 -0.601742,-0.47821 -1,-0.9375 l 12,-11.6875 0.46875,-0.4375 z"
id="coloredX" />
</svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -1,9 +0,0 @@
icondir = join_paths(get_option('datadir'), 'icons/hicolor')
install_data(
'hexchat.png',
install_dir: join_paths(icondir, '48x48/apps')
)
install_data(
'hexchat.svg',
install_dir: join_paths(icondir, 'scalable/apps')
)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -1,10 +0,0 @@
man_conf = configuration_data()
man_conf.set('VERSION', meson.project_version())
configure_file(
input: 'hexchat.1.in',
output: 'hexchat.1',
configuration: man_conf,
install: true,
install_dir: join_paths(get_option('mandir'), 'man1')
)

View File

@ -1,11 +0,0 @@
if get_option('with-plugin')
subdir('pkgconfig')
endif
if get_option('with-gtk')
subdir('icons')
subdir('misc')
subdir('man')
elif get_option('with-theme-manager')
subdir('misc')
endif

View File

@ -1,7 +0,0 @@
[Desktop Entry]
Name=HexChat Theme Manager
Exec=thememan %f
Icon=hexchat
Terminal=false
Type=Application
MimeType=application/x-hct;

View File

@ -1,8 +0,0 @@
<?xml version="1.0"?>
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
<mime-type type="application/x-hct">
<comment>HexChat theme archives</comment>
<icon name="hexchat" />
<glob pattern="*.hct" weight="100" />
</mime-type>
</mime-info>

View File

@ -1,87 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop">
<id>io.github.Hexchat.desktop</id>
<name>HexChat</name>
<developer_name>HexChat</developer_name>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-2.0+</project_license>
<translation type="gettext">hexchat</translation>
<summary>IRC Client</summary>
<description>
<p>HexChat is an easy to use yet extensible IRC Client. It allows you to securely join multiple networks and talk to users privately or in channels using a customizable interface. You can even transfer files.</p>
<p>HexChat supports features such as: DCC, SASL, proxies, spellcheck, alerts, logging, custom themes, and Python/Perl scripts.</p>
</description>
<url type="homepage">http://hexchat.github.io</url>
<url type="bugtracker">https://github.com/hexchat/hexchat</url>
<url type="translate">https://www.transifex.com/hexchat/hexchat</url>
<url type="donation">https://goo.gl/jESZvU</url>
<url type="help">https://hexchat.readthedocs.io/en/latest/</url>
<screenshots>
<screenshot type="default">
<image>http://i.imgur.com/tLMguQz.png</image>
<caption>Main Chat Window</caption>
</screenshot>
</screenshots>
<provides>
<!-- Renamed from this -->
<id>hexchat.desktop</id>
</provides>
<releases>
<release date="2018-03-10" version="2.14.0">
<description>
<p>This is largely a bug fix release though it has some large behind the scenes changes:</p>
<ul>
<li>Rename data files to use *io.github.Hexchat* name</li>
<li>Add option (irc_reconnect_rejoin) to disable auto-rejoin on reconnect</li>
<li>Add ability to set custom tray icon separate of app icon</li>
<li>Fix Enchant 2.0+ support</li>
<li>Fix input box theming with Adwaita-dark</li>
<li>Fix custom sounds not respecting omit if away option</li>
<li>Fix detecting if a tray doesn't exist on x11</li>
<li>Fix cutting off ctcp text after ending \01</li>
<li>Fix /ignore not accepting full hosts</li>
<li>Fix characters getting cut off when their width changes</li>
<li>Fix various possible crashes</li>
<li>Change preference window to be scroll-able</li>
<li>Remove ctrl+w binding by default</li>
<li>doat: Fix channels with / in them</li>
<li>fishlim: Fix key exchange</li>
<li>fishlim: Fix building against LibreSSL</li>
<li>sysinfo: Fix pci.ids file not being found on some distros</li>
<li>sysinfo: Make libpci optional</li>
<li>lua: Avoid loading the same script multiple times</li>
<li>Update translations</li>
</ul>
</description>
</release>
<release date="2016-12-10" version="2.12.4">
<description>
<p>This is another bug fix release:</p>
<ul>
<li>Fix issue with timers causing ping timeouts</li>
<li>Fix building against OpenSSL 1.1</li>
<li>Fix /exec output printing invalid utf8</li>
<li>Replace doat plugin with an internal command</li>
<li>Change how tab colors interact with plugins</li>
<li>Enable filtering the beep character by default</li>
</ul>
</description>
</release>
<release date="2016-10-22" version="2.12.3">
<description>
<p>This is a minor bug fix release just cleaning up a few issues:</p>
<ul>
<li>Fix crash with bad translations</li>
<li>Add new mhop command</li>
<li>Change ping timeout to 60 by default</li>
</ul>
</description>
</release>
</releases>
<kudos>
<kudo>UserDocs</kudo>
<kudo>HiDpiIcon</kudo>
<kudo>Notifications</kudo>
</kudos>
<update_contact>tingping_at_fedoraproject.org</update_contact>
</component>

View File

@ -1,19 +0,0 @@
[Desktop Entry]
Name=HexChat
GenericName=IRC Client
Comment=Chat with other people online
Keywords=IM;Chat;
Exec=@exec_command@
Icon=hexchat
Terminal=false
Type=Application
Categories=GTK;Network;IRCClient;
StartupNotify=true
StartupWMClass=Hexchat
X-GNOME-UsesNotifications=true
MimeType=x-scheme-handler/irc;x-scheme-handler/ircs;
Actions=SafeMode;
[Desktop Action SafeMode]
Name=Open Safe Mode
Exec=hexchat --no-auto --no-plugins

View File

@ -1,68 +0,0 @@
appdir = join_paths(get_option('datadir'), 'applications')
desktop_utils = find_program('desktop-file-validate', required: false)
if get_option('with-gtk')
hexchat_appdata = i18n.merge_file(
input: 'io.github.Hexchat.appdata.xml.in',
output: 'io.github.Hexchat.appdata.xml',
po_dir: '../../po',
install: true,
install_dir: join_paths(get_option('datadir'), 'metainfo')
)
appstream_util = find_program('appstream-util', required: false)
if appstream_util.found()
test('Validate io.github.Hexchat.appdata.xml', appstream_util,
args: ['validate-relax', hexchat_appdata]
)
endif
desktop_conf = configuration_data()
if get_option('with-dbus')
desktop_conf.set('exec_command', 'hexchat --existing %U')
else
desktop_conf.set('exec_command', 'hexchat %U')
endif
desktop_file = configure_file(
input: 'io.github.Hexchat.desktop.in.in',
output: 'io.github.Hexchat.desktop.in',
configuration: desktop_conf
)
hexchat_desktop = i18n.merge_file(
input: desktop_file,
output: 'io.github.Hexchat.desktop',
po_dir: '../../po',
type: 'desktop',
install: true,
install_dir: appdir
)
if desktop_utils.found()
test('Validate io.github.Hexchat.desktop', desktop_utils,
args: [hexchat_desktop]
)
endif
endif
if get_option('with-theme-manager')
htm_desktop = i18n.merge_file(
input: 'io.github.Hexchat.ThemeManager.desktop.in',
output: 'io.github.Hexchat.ThemeManager.desktop',
po_dir: '../../po',
type: 'desktop',
install: true,
install_dir: appdir
)
if desktop_utils.found()
test('Validate io.github.Hexchat.ThemeManager.desktop', desktop_utils,
args: [htm_desktop]
)
endif
install_data('io.github.Hexchat.ThemeManager.xml',
install_dir: join_paths(get_option('datadir'), 'mime/packages')
)
endif

View File

@ -1,14 +0,0 @@
pkg_conf = configuration_data()
prefix = get_option('prefix')
pkg_conf.set('prefix', prefix)
pkg_conf.set('VERSION', meson.project_version())
pkg_conf.set('hexchatlibdir', join_paths(prefix, plugindir))
pkg_conf.set('includedir', join_paths(prefix, get_option('includedir')))
configure_file(
input: 'hexchat-plugin.pc.in',
output: 'hexchat-plugin.pc',
configuration: pkg_conf,
install: true,
install_dir: join_paths(get_option('libdir'), 'pkgconfig'),
)

View File

@ -1,14 +0,0 @@
; dnf install mingw64-{gtk,openssl}
[binaries]
c = '/usr/bin/x86_64-w64-mingw32-gcc'
cpp = '/usr/bin/x86_64-w64-mingw32-g++'
ar = '/usr/bin/x86_64-w64-mingw32-gcc-ar'
strip = '/usr/bin/x86_64-w64-mingw32-strip'
pkgconfig = '/usr/bin/x86_64-w64-mingw32-pkg-config'
[host_machine]
system = 'windows'
cpu_family = 'x86_64'
cpu = 'x86_64'
endian = 'little'

1
man/Makefile.am Normal file
View File

@ -0,0 +1 @@
man_MANS = hexchat.1

View File

@ -1,10 +1,10 @@
.TH HEXCHAT "1" "April 2013" "HexChat @VERSION@" "User Commands"
.TH HEXCHAT "1" "April 2013" "HexChat 2.9.5" "User Commands"
.SH NAME
HexChat \- IRC Client
.SH DESCRIPTION
.SS "Usage:"
.IP
hexchat [OPTION...] URL
hexchat [OPTION...]
.SS "Help Options:"
.TP
\fB\-h\fR, \fB\-\-help\fR

View File

@ -1,157 +0,0 @@
project('hexchat', 'c',
version: '2.14.0',
meson_version: '>= 0.38.0',
default_options: [
'c_std=gnu89',
'buildtype=debugoptimized',
'warning_level=1',
]
)
i18n = import('i18n')
gnome = import('gnome')
cc = meson.get_compiler('c')
libgio_dep = dependency('gio-2.0', version: '>= 2.34.0')
libgmodule_dep = dependency('gmodule-2.0')
global_deps = []
if cc.get_id() == 'msvc'
libssl_dep = cc.find_library('libeay32')
else
libssl_dep = dependency('openssl', version: '>= 0.9.8',
required: get_option('with-ssl'))
endif
config_h = configuration_data()
config_h.set_quoted('PACKAGE_VERSION', meson.project_version())
config_h.set_quoted('PACKAGE_NAME', meson.project_name())
config_h.set_quoted('GETTEXT_PACKAGE', 'hexchat')
config_h.set_quoted('LOCALEDIR', join_paths(get_option('prefix'),
get_option('datadir'), 'locale'))
config_h.set10('ENABLE_NLS', true)
# Optional features
config_h.set('USE_OPENSSL', get_option('with-ssl'))
config_h.set('USE_LIBPROXY', get_option('with-libproxy'))
config_h.set('USE_LIBCANBERRA', get_option('with-libcanberra'))
config_h.set('USE_DBUS', get_option('with-dbus'))
config_h.set('USE_PLUGIN', get_option('with-plugin'))
config_h.set('G_DISABLE_SINGLE_INCLUDES', true)
config_h.set('GTK_DISABLE_DEPRECATED', true)
config_h.set('GTK_DISABLE_SINGLE_INCLUDES', true)
config_h.set('GDK_PIXBUF_DISABLE_SINGLE_INCLUDES', true)
config_h.set('GLIB_VERSION_MAX_ALLOWED', 'GLIB_VERSION_2_34')
config_h.set('GLIB_VERSION_MIN_REQUIRED', 'GLIB_VERSION_2_34')
# Detected features
config_h.set('HAVE_MEMRCHR', cc.has_function('memrchr'))
config_h.set('HAVE_STRINGS_H', cc.has_header('strings.h'))
if libssl_dep.found()
config_h.set('HAVE_X509_GET_SIGNATURE_NID',
cc.has_function('X509_get_signature_nid', dependencies: libssl_dep)
)
config_h.set('HAVE_SSL_CTX_GET_SSL_METHOD',
cc.has_function('SSL_CTX_get_ssl_method', dependencies: libssl_dep)
)
config_h.set('HAVE_DH_SET0_PQG',
cc.has_function('DH_set0_pqg', dependencies: libssl_dep)
)
config_h.set('HAVE_DH_GET0_KEY',
cc.has_function('DH_get0_key', dependencies: libssl_dep)
)
config_h.set('HAVE_DH_SET0_KEY',
cc.has_function('DH_set0_key', dependencies: libssl_dep)
)
config_h.set('HAVE_ERR_REMOVE_THREAD_STATE',
cc.has_function('ERR_remove_thread_state', dependencies: libssl_dep)
)
config_h.set('HAVE_ASN1_STRING_GET0_DATA',
cc.has_function('ASN1_STRING_get0_data', dependencies: libssl_dep)
)
endif
configure_file(output: 'config.h', configuration: config_h)
config_h_include = include_directories('.')
if host_machine.system() == 'windows'
add_project_arguments(
'-DWIN32',
'-DNTDDI_VERSION=NTDDI_WIN7',
'-D_WIN32_WINNT=_WIN32_WINNT_WIN7',
language: 'c')
endif
global_cflags = []
test_cflags = [
'-pipe',
'-fPIE',
'-funsigned-char',
'-Wno-conversion',
'-Wno-pointer-sign',
'-Wno-padded',
'-Wno-unused-parameter',
'-Wno-missing-prototypes',
'-Winline',
'-Wstrict-prototypes',
'-Werror=implicit-function-declaration',
'-Werror=pointer-arith',
'-Werror=init-self',
['-Werror=format-security', '-Werror=format=1'],
'-Werror=missing-include-dirs',
'-Werror=date-time',
]
foreach cflag : test_cflags
if cc.has_multi_arguments(cflag)
global_cflags += cflag
endif
endforeach
if get_option('buildtype') != 'plain'
if cc.has_argument('-fstack-protector-strong') and cc.links('''
int main (void) {
char buffer[16];
strcpy(buffer, "foo");
return 0;
}
''', args: '-fstack-protector-all')
global_cflags += '-fstack-protector-strong'
if host_machine.system() == 'windows'
global_deps += cc.find_library('ssp')
endif
endif
endif
add_project_arguments(global_cflags, language: 'c')
global_ldflags = []
test_ldflags = [
'-Wl,-z,relro',
'-Wl,-z,now',
'-Wl,-pie',
# mingw
'-Wl,--dynamicbase',
'-Wl,--nxcompat',
]
foreach ldflag : test_ldflags
if cc.has_argument(ldflag) and cc.links('int main (void) { return 0; }', args: ldflag)
global_ldflags += ldflag
endif
endforeach
add_project_link_arguments(global_ldflags, language: 'c')
subdir('src')
if get_option('with-plugin')
subdir('plugins')
endif
if cc.get_id() != 'msvc'
subdir('data')
subdir('po') # FIXME: build xgettext
meson.add_install_script('meson_post_install.py',
'@0@'.format(get_option('with-theme-manager'))
)
endif

View File

@ -1,59 +0,0 @@
option('with-gtk', type: 'boolean',
description: 'Main graphical interface'
)
option('with-text', type: 'boolean', value: false,
description: 'Text interface (not generally useful)'
)
option('with-ssl', type: 'boolean',
description: 'Support for TLS connections, requires openssl'
)
option('with-plugin', type: 'boolean',
description: 'Support for loadable plugins'
)
option('with-dbus', type: 'boolean',
description: 'Support used for single-instance and scripting interface, Unix only'
)
option('with-libproxy', type: 'boolean',
description: 'Support for getting proxy information, Unix only'
)
option('with-libnotify', type: 'boolean',
description: 'Support for freedesktop notifications, Unix only'
)
option('with-libcanberra', type: 'boolean',
description: 'Support for sound alerts, Unix only'
)
option('with-theme-manager', type: 'boolean', value: false,
description: 'Utility to help manage themes, requires mono/.net'
)
option('dbus-service-use-appid', type: 'boolean', value: false,
description: 'Rename dbus service to match app-id, required for Flatpak'
)
# Plugins
option('with-checksum', type: 'boolean',
description: 'DCC checksum plugin'
)
option('with-exec', type: 'boolean',
description: '/exec plugin, Windows only'
)
option('with-fishlim', type: 'boolean',
description: 'Fish encryption plugin, requires openssl'
)
option('with-lua', type: 'string', value: 'luajit',
description: 'Lua scripting plugin, value is pkg-config name to use or "false"'
)
option('with-perl', type: 'boolean',
description: 'Perl scripting plugin'
)
option('with-python', type: 'string', value: 'python3',
description: 'Python scripting plugin. value is pkg-config name to use or "false"'
)
option('with-sysinfo', type: 'boolean',
description: 'System information plugin, requires libpci on Unix'
)
option('with-upd', type: 'boolean',
description: 'Update plugin, Windows only'
)
option('with-winamp', type: 'boolean',
description: 'Winamp plugin, Windows only'
)

View File

@ -1,24 +0,0 @@
#!/usr/bin/env python3
import os
import sys
import subprocess
prefix = os.environ.get('MESON_INSTALL_PREFIX', '/usr/local')
datadir = os.path.join(prefix, 'share')
with_thememan = sys.argv[1] == 'true'
# Packaging tools define DESTDIR and this isn't needed for them
if 'DESTDIR' not in os.environ:
print('Updating icon cache...')
subprocess.call(['gtk-update-icon-cache', '-qtf',
os.path.join(datadir, 'icons', 'hicolor')])
print('Updating desktop database...')
subprocess.call(['update-desktop-database', '-q',
os.path.join(datadir, 'applications')])
if with_thememan:
print('Updating mime database...')
subprocess.call(['update-mime-database',
os.path.join(datadir, 'mime')])

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>HexChat</string>
<key>CFBundleGetInfoString</key>
<string>@VERSION@</string>
<key>CFBundleIconFile</key>
<string>hexchat.icns</string>
<key>CFBundleIdentifier</key>
<string>org.hexchat</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>@VERSION@</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>@VERSION@</string>
<key>NSHumanReadableCopyright</key>
<string></string>
<key>LSMinimumSystemVersion</key>
<string>10.4</string>
</dict>
</plist>

435
osx/gtkrc
View File

@ -1,435 +0,0 @@
# Mac Theme for Xamarin composed by Lanedo GmbH
# Copyright 2012 Xamarin Inc.
# Authors:
# Christian Kellner <christian.kellner@lanedo.com>
# Carlos Garnacho <carlos.garnacho@lanedo.com>
#
# Modified by HexChat
#
gtk-color-scheme =
"bg_color: #f5f5f5
fg_color: #000
base_color: #fff
text_color: #000
selected_bg_color: #0066FF
selected_fg_color: #fff
tooltip_bg_color: #fafaba
tooltip_fg_color: #000"
gtk-button-images = 0
gtk-menu-images = 0
gtk-toolbar-style = 0
gtk-enable-mnemonics = 0
gtk-icon-sizes = "gtk-small-toolbar=16,16:gtk-large-toolbar=22,22"
gtk-toolbar-icon-size = large-toolbar
gtk-auto-mnemonics = 1
gtk-error-bell = 0
gtk-show-input-method-menu = 0
gtk-key-theme-name="Mac"
style "default" {
xthickness = 1
ythickness = 1
### colours
bg[NORMAL] = @bg_color
bg[PRELIGHT] = @bg_color
bg[SELECTED] = @selected_bg_color
bg[INSENSITIVE] = @bg_color
bg[ACTIVE] = @bg_color
fg[NORMAL] = @fg_color
fg[PRELIGHT] = @fg_color
fg[SELECTED] = @selected_fg_color
fg[INSENSITIVE] = darker (@bg_color)
fg[ACTIVE] = @fg_color
text[NORMAL] = @text_color
text[PRELIGHT] = @text_color
text[SELECTED] = @selected_fg_color
text[INSENSITIVE] = darker (@bg_color)
text[ACTIVE] = @text_color
base[NORMAL] = @base_color
base[PRELIGHT] = @selected_bg_color
base[SELECTED] = @selected_bg_color
base[INSENSITIVE] = @bg_color
base[ACTIVE] = shade (1.3, @selected_bg_color)
### style properties
GtkWidget::new-tooltip-style = 1
GtkEntry::honors-transparent-bg-hint = 1
GtkEntry::inner-border = { 2, 2, 2, 2 }
GtkButton::child-displacement-x = 0
GtkButton::child-displacement-y = 0
GtkButton::default-border = { 0, 0, 0, 0 }
GtkButton::inner-border = { 2, 2, 4, 4 }
GtkButtonBox::child-min-width = 70
GtkButtonBox::child-min-height = 22
GtkTreeView::odd-row-color = "#f0f4f9"
GtkScrolledWindow::scrollbar-spacing = 0
GtkScrolledWindow::scrollbars-within-bevel = 1
GtkScale::slider-length = 14
GtkRange::trough-side-details = 1
GtkTreeView::expander-size = 8
GtkExpander::expander-size = 8
GtkComboBox::arrow-size = 12
GtkMenu::vertical-padding = 4
GtkMenuItem::horizontal-padding = 9
GtkMenuItem::toggle-spacing = 0
GtkSeparatorMenuItem::horizontal-padding = 2
engine "xamarin" {
arrowstyle = 2
rgba = TRUE
roundness = 3
glazestyle = 0
menustyle = 0
menuitemstyle = 0
menubaritemstyle = 0
comboboxstyle = 1
spinbuttonstyle = 1
colorize_scrollbar = FALSE
progressbarstyle = 0
trough_shades = { 0.842, 0.886 }
}
}
style "wide" = "default" {
xthickness = 2
ythickness = 2
}
style "wider" = "default" {
xthickness = 3
ythickness = 3
}
style "button" {
xthickness = 2
ythickness = 2
bg[NORMAL] = @bg_color
bg[PRELIGHT] = shade(1.1, @bg_color)
bg[ACTIVE] = @bg_color
bg[INSENSITIVE] = @bg_color
GtkWidget::focus-padding = 0
engine "quartz" {
}
}
style "combo-box-button" {
xthickness = 2
ythickness = 4
bg[NORMAL] = @base_color
bg[PRELIGHT] = shade(1.1, @base_color)
bg[ACTIVE] = @base_color
bg[INSENSITIVE] = @base_color
GtkWidget::focus-padding = 0
engine "xamarin" {
contrast = 1.0
gradient_shades = {0.99, 0.98, 0.97, 0.96}
focus_color = shade(0.6, @base_color)
textstyle = 1
}
}
style "dialog-button" = "default" {
xthickness = 3
ythickness = 2
font_name = "Lucida Grande 13"
GtkWidget::draw-border = { 2, 2, 2, 2 }
GtkWidget::focus-line-width = 1
GtkButton::inner-border = { 8, 8, 0, 3 }
engine "quartz" {
buttontype = "aqua"
}
}
style "toggle-button" = "button" {
bg[NORMAL] = @base_color
bg[PRELIGHT] = shade(0.98, @base_color)
}
style "menu" {
xthickness = 0
ythickness = 0
font_name = "Lucida Grande 14"
bg[PRELIGHT] = @selected_fg_color
fg[PRELIGHT] = @selected_fg_color
text[PRELIGHT] = @selected_fg_color
engine "quartz" {
}
}
style "menu-item" = "menu" {
ythickness = 2
GtkWidget::draw-border = { 0, 0, 0, 2 }
}
style "menu-separator" = "menu-item" {
ythickness = 3
}
style "toolbar" = "default"
{
bg[NORMAL] = "#ddd"
engine "xamarin" {
toolbarstyle = 2
}
}
style "toolbar-button"
{
engine "xamarin" {
contrast = 1.0
focus_color = @bg_color
}
}
style "tooltip"
{
xthickness = 5
ythickness = 5
fg[NORMAL] = @tooltip_fg_color
bg[NORMAL] = @tooltip_bg_color
engine "xamarin" {
roundness = 0
}
}
style "treeview" = "default"
{
GtkTreeView::odd-row-color = "#f5f5f5"
base[SELECTED] = "#2b5dcd"
base[ACTIVE] = "#cacaca"
text[SELECTED] = "#FFF"
text[ACTIVE] = "#000"
font_name = "Lucida Grande 12"
engine "quartz" {
}
}
style "tree-header"
{
ythickness = 0
bg[NORMAL] = "#f2f2f2"
font_name = "Lucida Grande 11"
GtkWidget::focus-line-width = 0
GtkWidget::draw-border = { 1, 1, 1, 1 }
GtkButton::inner-border = { 3, 3, 1, 3 }
engine "quartz" {
}
}
style "icon-view" = "default"
{
bg[SELECTED] = "#f5f7fa"
base[SELECTED] = "#f5f7fa"
fg[SELECTED] = "#000"
text[SELECTED] = "#000"
}
style "toolbar-combo-box" = "default"
{
fg[NORMAL] = "#616161"
text[NORMAL] = @fg_color
bg[NORMAL] = "#fff"
base[NORMAL] = "#fff"
ythickness = 4
xthickness = 2
engine "xamarin" {
comboboxstyle = 0
arrowstyle = 2
}
}
style "combo-box" = "default"
{
fg[NORMAL] = "#616161"
xthickness = 2
ythickness = 4
engine "xamarin" {
arrowstyle = 4
}
}
style "combo-box-entry" = "combo-box"
{
engine "xamarin" {
arrowstyle = 3
}
}
style "combo-box-label" = "combo-box"
{
fg[NORMAL] = "#595959"
}
style "combo-box-menu" = "menu" {
font_name = "Lucida Grande 12"
}
style "notebook" = "default"
{
GtkNotebook::tab-overlap = 1
#bg[ACTIVE] = @base_color
bg[NORMAL] = @base_color
engine "xamarin" {
gradient_shades = { 0.945, 0.945, 0.945, 0.685 }
}
}
style "radio-or-check-box"
{
ythickness = 6
#GtkCheckButton::indicator-size = 14
GtkCheckButton::indicator-spacing = 4
engine "quartz" {
}
}
style "entry" = "default"
{
xthickness = 2
ythickness = 2
GtkEntry::inner-border = { 2, 2, 2, 2 }
base[INSENSITIVE] = shade(1.02, @bg_color)
engine "quartz" {
}
}
style "search-entry" = "wider"
{
xthickness = 6
ythickness = 4
bg[NORMAL] = @base_color
}
style "scrollbar" = "default"
{
GtkScrollbar::has-forward-stepper = 0
GtkScrollbar::has-backward-stepper = 0
GtkRange::slider-width = 15
GtkRange::trough-border = 0
GtkRange::trough-side-details = 0
engine "quartz" {
}
}
style "progressbar" = "default"
{
engine "quartz" {
}
}
style "scrolled-window" = "default"
{
xthickness = 1
ythickness = 1
}
style "scale" = "default"
{
bg[SELECTED] = @selected_bg_color
engine "xamarin" {
roundness = 7
}
}
style "spin-button" = "wider"
{
fg[NORMAL] = "#616161"
ythickness = 4
GtkEntry::inner-border = { 2, 2, 1, 1 }
engine "xamarin" {
arrowstyle = 3
}
}
### Apply the styles
class "GtkWidget" style "default"
class "GtkEntry" style "entry"
class "GtkSpinButton" style "spin-button"
class "GtkFrame" style "wider"
class "GtkRange" style "wide"
class "GtkSeparator" style "wide"
class "GtkScrollbar" style "scrollbar"
class "GtkProgressBar" style "progressbar"
class "GtkScrolledWindow" style "scrolled-window"
class "GtkNotebook" style "notebook"
class "GtkButton" style "button"
class "GtkToggleButton" style "toggle-button"
class "GtkScale" style "scale"
#widget "*GtkEntry" style "entry"
widget "*search-entry*" style "search-entry"
widget "*GtkTextView" style "entry"
widget_class "<GtkDialog>*<GtkCheckButton>" style "radio-or-check-box"
widget_class "<GtkDialog>.<GtkVBox>.<GtkButtonBox>.<GtkButton>*" style "dialog-button"
widget_class "<GtkDialog>.<GtkVBox>.<GtkHBox>.<GtkButtonBox>.<GtkButton>*" style "dialog-button"
widget "*.toggleFindInFiles" style "toggle-button"
widget "*.toggleReplaceInFiles" style "toggle-button"
widget_class "*<GtkMenu>*" style "menu"
widget_class "*<GtkMenuItem>*" style "menu-item"
widget_class "*<GtkSeparatorMenuItem>" style "menu-separator"
widget "*.gtk-combobox-popup-menu*" style "combo-box-menu"
widget_class "*<GtkToolbar>*" style "toolbar"
widget_class "*ToolButton*" style "toolbar-button"
widget_class "*.<GtkTreeView>*" style "treeview"
widget_class "*.GtkTreeView.GtkButton" style "tree-header"
widget_class "*.GtkList.GtkButton" style "tree-header"
widget_class "*<GtkIconView>" style "icon-view"
widget_class "*.<GtkComboBox>.*" style "combo-box"
widget_class "*.<GtkComboBoxText>.*" style "combo-box-entry"
widget_class "*.<GtkComboBoxEntry>.*" style "combo-box-entry"
widget_class "*.<GtkComboBoxText>.<GtkEntry>" style "combo-box-entry"
widget_class "*.<GtkComboBoxEntry>.<GtkEntry>" style "combo-box-entry"
widget_class "*.<GtkComboBoxText>.<GtkToggleButton>" style "combo-box-button"
widget_class "*.<GtkComboBoxEntry>.<GtkToggleButton>" style "combo-box-button"
widget_class "*.<GtkComboBox>.*.GtkLabel" style "combo-box-label"
# Comboboxes within toolbars
widget_class "*.<GtkToolbar>.*.<GtkComboBox>.*" style "toolbar-combo-box"
widget "*MainToolbar*.GtkComboBox.*" style "toolbar-combo-box"
widget "gtk-tooltip*" style "tooltip"

View File

@ -1,68 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<app-bundle>
<meta>
<prefix name="default">/usr/local</prefix>
<prefix name="enchant">/usr/local/opt/enchant-applespell</prefix>
<destination overwrite="yes">${project}</destination>
<run-install-name-tool/>
<launcher-script>${project}/launcher.sh</launcher-script >
<gtk>gtk+-2.0</gtk>
</meta>
<plist>${project}/Info.plist</plist>
<main-binary>
${prefix}/bin/hexchat
</main-binary>
<binary>
${prefix}/lib/hexchat/plugins/*.so
</binary>
<binary>
${prefix:enchant}/lib/libenchant.dylib
</binary>
<binary>
${prefix:enchant}/lib/enchant/libenchant_applespell.so
</binary>
<binary>
${prefix}/lib/${gtkdir}/modules/*.so
</binary>
<binary>
${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/engines/libquartz.so
</binary>
<binary>
${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/engines/libxamarin.so
</binary>
<binary>
${prefix}/lib/${gtkdir}/${pkg:${gtk}:gtk_binary_version}/printbackends/*.so
</binary>
<binary>
${prefix}/lib/gdk-pixbuf-2.0/${pkg:${gtk}:gtk_binary_version}/loaders/*.so
</binary>
<binary>
${prefix}/lib/pango/${pkg:pango:pango_module_version}/modules/
</binary>
<data>
${prefix}/share/themes/Mac/gtk-2.0-key/gtkrc
</data>
<translations name="gtk20">
${prefix}/share/locale
</translations>
<translations name="hexchat">
${prefix}/share/locale
</translations>
<data dest="${bundle}/Contents/Resources/etc/${gtkdir}/gtkrc">
${project}/gtkrc
</data>
<data dest="${bundle}/Contents/Resources">
${project}/hexchat.icns
</data>
</app-bundle>

Binary file not shown.

View File

@ -1,174 +0,0 @@
#!/bin/sh
if test "x$GTK_DEBUG_LAUNCHER" != x; then
set -x
fi
if test "x$GTK_DEBUG_GDB" != x; then
EXEC="gdb --args"
else
EXEC=exec
fi
name=`basename "$0"`
tmp="$0"
tmp=`dirname "$tmp"`
tmp=`dirname "$tmp"`
bundle=`dirname "$tmp"`
bundle_contents="$bundle"/Contents
bundle_res="$bundle_contents"/Resources
bundle_lib="$bundle_res"/lib
bundle_bin="$bundle_res"/bin
bundle_data="$bundle_res"/share
bundle_etc="$bundle_res"/etc
export PREFIX="$bundle_res"
export DYLD_LIBRARY_PATH="$bundle_lib"
export XDG_CONFIG_DIRS="$bundle_etc"/xdg
export XDG_DATA_DIRS="$bundle_data"
export GTK_DATA_PREFIX="$bundle_res"
export GTK_EXE_PREFIX="$bundle_res"
export GTK_PATH="$bundle_res"
export GTK2_RC_FILES="$bundle_etc/gtk-2.0/gtkrc"
export GTK_IM_MODULE_FILE="$bundle_etc/gtk-2.0/gtk.immodules"
export GDK_PIXBUF_MODULE_FILE="$bundle_etc/gtk-2.0/gdk-pixbuf.loaders"
export PANGO_LIBDIR="$bundle_lib"
export PANGO_SYSCONFDIR="$bundle_etc"
export OPENSSL_CONF="/System/Library/OpenSSL/openssl.cnf"
export HEXCHAT_LIBDIR="$bundle_lib/hexchat/plugins"
APP=name
I18NDIR="$bundle_data/locale"
# Set the locale-related variables appropriately:
unset LANG LC_MESSAGES LC_MONETARY LC_COLLATE
# Has a language ordering been set?
# If so, set LC_MESSAGES and LANG accordingly; otherwise skip it.
# First step uses sed to clean off the quotes and commas, to change - to _, and change the names for the chinese scripts from "Hans" to CN and "Hant" to TW.
APPLELANGUAGES=`defaults read .GlobalPreferences AppleLanguages | sed -En -e 's/\-/_/' -e 's/Hant/TW/' -e 's/Hans/CN/' -e 's/[[:space:]]*\"?([[:alnum:]_]+)\"?,?/\1/p' `
if test "$APPLELANGUAGES"; then
# A language ordering exists.
# Test, item per item, to see whether there is an corresponding locale.
for L in $APPLELANGUAGES; do
#test for exact matches:
if test -f "$I18NDIR/${L}/LC_MESSAGES/$APP.mo"; then
export LANG=$L
break
fi
#This is a special case, because often the original strings are in US
#English and there is no translation file.
if test "x$L" == "xen_US"; then
export LANG=$L
break
fi
#OK, now test for just the first two letters:
if test -f "$I18NDIR/${L:0:2}/LC_MESSAGES/$APP.mo"; then
export LANG=${L:0:2}
break
fi
#Same thing, but checking for any english variant.
if test "x${L:0:2}" == "xen"; then
export LANG=$L
break
fi;
done
fi
unset APPLELANGUAGES L
# If we didn't get a language from the language list, try the Collation preference, in case it's the only setting that exists.
APPLECOLLATION=`defaults read .GlobalPreferences AppleCollationOrder`
if test -z ${LANG} -a -n $APPLECOLLATION; then
if test -f "$I18NDIR/${APPLECOLLATION:0:2}/LC_MESSAGES/$APP.mo"; then
export LANG=${APPLECOLLATION:0:2}
fi
fi
if test ! -z $APPLECOLLATION; then
export LC_COLLATE=$APPLECOLLATION
fi
unset APPLECOLLATION
# Continue by attempting to find the Locale preference.
APPLELOCALE=`defaults read .GlobalPreferences AppleLocale`
if test -f "$I18NDIR/${APPLELOCALE:0:5}/LC_MESSAGES/$APP.mo"; then
if test -z $LANG; then
export LANG="${APPLELOCALE:0:5}"
fi
elif test -z $LANG -a -f "$I18NDIR/${APPLELOCALE:0:2}/LC_MESSAGES/$APP.mo"; then
export LANG="${APPLELOCALE:0:2}"
fi
#Next we need to set LC_MESSAGES. If at all possilbe, we want a full
#5-character locale to avoid the "Locale not supported by C library"
#warning from Gtk -- even though Gtk will translate with a
#two-character code.
if test -n $LANG; then
#If the language code matches the applelocale, then that's the message
#locale; otherwise, if it's longer than two characters, then it's
#probably a good message locale and we'll go with it.
if test $LANG == ${APPLELOCALE:0:5} -o $LANG != ${LANG:0:2}; then
export LC_MESSAGES=$LANG
#Next try if the Applelocale is longer than 2 chars and the language
#bit matches $LANG
elif test $LANG == ${APPLELOCALE:0:2} -a $APPLELOCALE > ${APPLELOCALE:0:2}; then
export LC_MESSAGES=${APPLELOCALE:0:5}
#Fail. Get a list of the locales in $PREFIX/share/locale that match
#our two letter language code and pick the first one, special casing
#english to set en_US
elif test $LANG == "en"; then
export LC_MESSAGES="en_US"
else
LOC=`find $PREFIX/share/locale -name $LANG???`
for L in $LOC; do
export LC_MESSAGES=$L
done
fi
else
#All efforts have failed, so default to US english
export LANG="en_US"
export LC_MESSAGES="en_US"
fi
CURRENCY=`echo $APPLELOCALE | sed -En 's/.*currency=([[:alpha:]]+).*/\1/p'`
if test "x$CURRENCY" != "x"; then
#The user has set a special currency. Gtk doesn't install LC_MONETARY files, but Apple does in /usr/share/locale, so we're going to look there for a locale to set LC_CURRENCY to.
if test -f /usr/local/share/$LC_MESSAGES/LC_MONETARY; then
if test -a `cat /usr/local/share/$LC_MESSAGES/LC_MONETARY` == $CURRENCY; then
export LC_MONETARY=$LC_MESSAGES
fi
fi
if test -z "$LC_MONETARY"; then
FILES=`find /usr/share/locale -name LC_MONETARY -exec grep -H $CURRENCY {} \;`
if test -n "$FILES"; then
export LC_MONETARY=`echo $FILES | sed -En 's%/usr/share/locale/([[:alpha:]_]+)/LC_MONETARY.*%\1%p'`
fi
fi
fi
#No currency value means that the AppleLocale governs:
if test -z "$LC_MONETARY"; then
LC_MONETARY=${APPLELOCALE:0:5}
fi
#For Gtk, which only looks at LC_ALL:
export LC_ALL=$LC_MESSAGES
unset APPLELOCALE FILES LOC
if test -f "$bundle_lib/charset.alias"; then
export CHARSETALIASDIR="$bundle_lib"
fi
# Extra arguments can be added in environment.sh.
EXTRA_ARGS=
if test -f "$bundle_res/environment.sh"; then
source "$bundle_res/environment.sh"
fi
# Strip out the argument added by the OS.
if /bin/expr "x$1" : '^x-psn_' > /dev/null; then
shift 1
fi
$EXEC "$bundle_contents/MacOS/$name-bin" "$@" $EXTRA_ARGS

View File

@ -1,11 +0,0 @@
#!/bin/sh
rm -rf HexChat.app
rm -f *.app.zip
python $HOME/.local/bin/gtk-mac-bundler hexchat.bundle
echo "Compressing bundle"
#hdiutil create -format UDBZ -srcdir HexChat.app -quiet HexChat-2.9.6.1-$(git rev-parse --short master).dmg
zip -9rXq ./HexChat-$(git describe --tags).app.zip ./HexChat.app

38
plugins/Make.plugin Normal file
View 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
#

31
plugins/Makefile.am Normal file
View File

@ -0,0 +1,31 @@
# temp. solution while mailcheck & xdcc arn't in SUBDIRS
EXTRA_DIST = Make.plugin plugin-conf.in xdcc/xdcc.c xdcc/Makefile.am
# noinst_HEADERS = hexchat-plugin.h
if DO_PYTHON
pythondir = python
endif
if DO_PERL
perldir = perl
endif
if DO_DOAT
doatdir = doat
endif
if DO_FISHLIM
fishlimdir = fishlim
endif
if DO_CHECKSUM
checksumdir = checksum
endif
if DO_SYSINFO
sysinfodir = sysinfo
endif
#SUBDIRS = . $(pythondir) $(perldir) mailcheck xdcc
SUBDIRS = . $(pythondir) $(perldir) $(checksumdir) $(doatdir) $(fishlimdir) $(sysinfodir)

View File

@ -0,0 +1,7 @@
libdir = $(hexchatlibdir)
lib_LTLIBRARIES = checksum.la
checksum_la_SOURCES = checksum.c
checksum_la_LDFLAGS = -avoid-version -module
checksum_la_LIBADD =
AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/../../src/common

View File

@ -20,194 +20,217 @@
* THE SOFTWARE.
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <openssl/sha.h>
#include <glib.h>
#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");
}
}
static int
get_limit (void)
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 +241,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 +254,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 +272,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);

View File

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
@ -20,19 +19,58 @@
<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>
<Optimization>MaxSpeed</Optimization>
<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 +78,20 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<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 +104,6 @@
<None Include="checksum.def" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,6 +0,0 @@
shared_module('checksum', 'checksum.c',
dependencies: [libgio_dep, hexchat_plugin_dep],
install: true,
install_dir: plugindir,
name_prefix: '',
)

332
plugins/dns/dns.c Normal file
View File

@ -0,0 +1,332 @@
/* HexChat Win32 DNS Plugin
* Copyright (C) 2003-2004 Peter Zelezny.
* Copyright (C) 2012 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
*/
/*
* Requires MS Visual Studio and IPV6 headers to compile (run nmake).
* Compiling with gcc (mingw) will fail due to missing gai_strerror.
*/
#define DNS_VERSION "2.4"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#define USE_IPV6
#ifdef WIN32
#ifdef USE_IPV6
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <winsock2.h>
#endif
#include <io.h>
#else
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#endif
#include "hexchat-plugin.h"
#include "thread.h"
#define HELP "Usage: DNS <nickname|hostname|numerical address>\n"
#define HEAD "\0034[DNS]\017\t"
#define PIPE_READ 0
#define PIPE_WRITE 1
#define MAX_HOSTNAME 128
static hexchat_plugin *ph;
static thread *active_thread = NULL;
static int
waitline (void *source, char *buf, int bufsize)
{
int i = 0;
int len;
while(1)
{
len = 1;
/* we can't read() here, due to glib's giowin32 */
if (ph->hexchat_read_fd (ph, source, buf + i, &len) != 0)
{
return -1;
}
if (buf[i] == '\n' || bufsize == i + 1)
{
buf[i] = 0;
return i;
}
i++;
}
}
static void *
thread_function (void *ud)
{
#ifdef USE_IPV6
struct addrinfo *ent;
struct addrinfo *cur;
struct addrinfo hints;
#else
struct hostent *ent;
#endif
thread *th = ud;
int fd = th->pipe_fd[PIPE_WRITE];
int ret;
char ipstring[MAX_HOSTNAME];
char reverse[MAX_HOSTNAME];
// int i;
active_thread = th;
#ifdef USE_IPV6
memset (&hints, 0, sizeof (hints));
hints.ai_family = PF_UNSPEC; /* support ipv6 and ipv4 */
hints.ai_flags = AI_CANONNAME;
// hints.ai_socktype = SOCK_STREAM;
ret = getaddrinfo (th->userdata, NULL, &hints, &ent);
if (ret != 0)
{
sprintf (ipstring, "1%d\n", ret); /* failed */
write (fd, ipstring, strlen (ipstring));
// Sleep (3000);
active_thread = NULL;
return 0;
}
// i = 0;
cur = ent;
while (cur)
{
/* find the numeric IP number */
ipstring[0] = 0;
getnameinfo (cur->ai_addr, cur->ai_addrlen,
ipstring, sizeof (ipstring), NULL, 0, NI_NUMERICHOST);
if (cur->ai_canonname)
{
/* force reverse lookup if canonname & ipstring are the same */
if (/*i == 0 &&*/ strcmp (cur->ai_canonname, ipstring) == 0)
goto lamecode;
}
if (cur->ai_canonname)
{
write (fd, "0", 1);
write (fd, ipstring, strlen (ipstring));
write (fd, "\n", 1);
write (fd, cur->ai_canonname, strlen (cur->ai_canonname));
} else
{
lamecode:
// ret = 1;
// if (i == 0)
{
/* reverse lookup */
reverse[0] = 0;
ret = getnameinfo (cur->ai_addr, cur->ai_addrlen,
reverse, sizeof (reverse), NULL, 0, NI_NAMEREQD);
}
write (fd, "0", 1);
write (fd, ipstring, strlen (ipstring));
write (fd, "\n", 1);
if (ret == 0)
write (fd, reverse, strlen (reverse));
}
write (fd, "\n", 1);
// i++;
cur = cur->ai_next;
}
/* tell the parent we're done */
write (fd, "2\n", 2);
freeaddrinfo (ent);
#else
ent = gethostbyname (th->userdata);
if (ent)
{
write (fd, "0", 1);
write (fd, ent->h_name, strlen (ent->h_name));
write (fd, "\n", 1);
write (fd, ent->h_name, strlen (ent->h_name));
write (fd, "\n", 1);
write (fd, "2\n", 2);
} else
{
write (fd, "10\n", 1);
}
#endif
// Sleep (3000);
active_thread = NULL; /* race condition, better than nothing */
return 0;
}
static int
dns_close_pipe (int fd)
{
close (fd);
return 0;
}
/* read messages comming from the child (through the pipe) */
static int
dns_read_cb (int fd, int flags, thread *th, void *source)
{
char buf[512];
char buf2[512];
while (waitline (source, buf, sizeof (buf)))
{
switch (buf[0])
{
case '0': /* got data to show */
waitline (source, buf2, sizeof (buf2));
if (buf2[0] == 0)
hexchat_printf(ph, HEAD"\002Numerical\002: %s\n", buf + 1);
else
hexchat_printf(ph, HEAD"\002Canonical\002: %s \002Numerical\002: %s\n", buf2, buf + 1);
return 1;
case '1': /* failed */
hexchat_printf(ph, HEAD"Lookup failed. %s\n", gai_strerrorA (atoi (buf + 1)));
case '2': /* done */
// close (th->pipe_fd[PIPE_WRITE]);
// close (th->pipe_fd[PIPE_READ]);
hexchat_hook_timer(ph, 3000, dns_close_pipe, (void *)th->pipe_fd[PIPE_WRITE]);
hexchat_hook_timer(ph, 4000, dns_close_pipe, (void *)th->pipe_fd[PIPE_READ]);
free (th->userdata); /* hostname strdup'ed */
free (th);
return 0;
}
}
return 1;
}
/* find hostname from nickname (search the userlist, current chan only) */
static char *
find_nick_host (char *nick)
{
hexchat_list *list;
char *at;
const char *host;
list = hexchat_list_get (ph, "users");
if (!list)
return NULL;
while (hexchat_list_next (ph, list))
{
if (stricmp (nick, hexchat_list_str (ph, list, "nick")) == 0)
{
host = hexchat_list_str (ph, list, "host");
if (host)
{
at = strrchr (host, '@');
if (at)
return at + 1;
}
break;
}
}
return NULL;
}
static int
dns_cmd_cb (char *word[], char *word_eol[], void *ud)
{
thread *th;
char *nickhost;
if (!word[2][0])
{
hexchat_print (ph, HELP);
return HEXCHAT_EAT_ALL;
}
th = thread_new ();
if (th)
{
nickhost = find_nick_host (word[2]);
if (nickhost)
{
hexchat_printf (ph, HEAD"Looking up %s (%s)...\n", nickhost, word[2]);
th->userdata = strdup (nickhost);
} else
{
hexchat_printf (ph, HEAD"Looking up %s...\n", word[2]);
th->userdata = strdup (word[2]);
}
if (thread_start (th, thread_function, th))
{
hexchat_hook_fd(ph, th->pipe_fd[PIPE_READ],
HEXCHAT_FD_READ | HEXCHAT_FD_EXCEPTION | HEXCHAT_FD_NOTSOCKET,
(void *)dns_read_cb, th);
}
}
return HEXCHAT_EAT_ALL;
}
int
hexchat_plugin_deinit (hexchat_plugin *plugin_handle)
{
while (active_thread) /* children will set this var to NULL soon... */
{
Sleep (1000);
}
hexchat_printf (ph, "DNS plugin unloaded\n");
return 1;
}
int
hexchat_plugin_init
(hexchat_plugin *plugin_handle, char **plugin_name,
char **plugin_desc, char **plugin_version, char *arg)
{
/* we need to save this for use with any hexchat_* functions */
ph = plugin_handle;
*plugin_name = "DNS";
*plugin_desc = "Threaded IPv4/6 DNS Command";
*plugin_version = DNS_VERSION;
hexchat_hook_command(ph, "DNS", HEXCHAT_PRI_LOW, dns_cmd_cb, HELP, 0);
hexchat_printf (ph, "DNS plugin loaded\n");
return 1; /* return 1 for success */
}

3
plugins/dns/dns.def Normal file
View File

@ -0,0 +1,3 @@
EXPORTS
hexchat_plugin_init
hexchat_plugin_deinit

113
plugins/dns/dns.vcxproj Normal file
View File

@ -0,0 +1,113 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration">
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3786FA8C-3E76-45E3-984E-FCCFF44729C9}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>dns</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\win32\hexchat.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\win32\hexchat.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<TargetName>hcdns</TargetName>
<OutDir>$(HexChatBin)</OutDir>
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>hcdns</TargetName>
<OutDir>$(HexChatBin)</OutDir>
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DNS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>dns.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;DNS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>dns.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="dns.def" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dns.c" />
<ClCompile Include="thread.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="thread.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="dns.def">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dns.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="thread.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="thread.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

34
plugins/dns/thread.c Normal file
View File

@ -0,0 +1,34 @@
#include <io.h>
#include <fcntl.h>
#include "thread.h"
thread *
thread_new (void)
{
thread *th;
th = calloc (1, sizeof (*th));
if (!th)
{
return NULL;
}
if (_pipe (th->pipe_fd, 4096, _O_BINARY) == -1)
{
free (th);
return NULL;
}
return th;
}
int
thread_start (thread *th, void *(*start_routine)(void *), void *arg)
{
DWORD id;
CloseHandle (CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, arg, 0, (DWORD *)&id));
th->threadid = id;
return 1;
}

11
plugins/dns/thread.h Normal file
View File

@ -0,0 +1,11 @@
#include <windows.h>
typedef struct
{
DWORD threadid;
int pipe_fd[2];
void *userdata;
} thread;
thread *thread_new (void);
int thread_start (thread *th, void *(*start_routine)(void *), void *arg);

8
plugins/doat/Makefile.am Normal file
View File

@ -0,0 +1,8 @@
libdir = $(hexchatlibdir)
lib_LTLIBRARIES = doat.la
doat_la_SOURCES = doat.c
doat_la_LDFLAGS = -avoid-version -module
doat_la_LIBADD =
AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/../../src/common

94
plugins/doat/doat.c Normal file
View File

@ -0,0 +1,94 @@
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING or http://lwsitu.com/xchat/COPYING
* for more details. */
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "hexchat-plugin.h"
static hexchat_plugin *ph;
static int
parse_command( char *word[], char *word_eol[], void *userdata ) {
char *channel = NULL, *server = NULL, *token = NULL;
/* char *save_ptr1 = NULL;*/
char *str1 = NULL;
char *delimiter = NULL;
hexchat_context *ctx = NULL;
if( word[2] != NULL && word[3] != NULL ) {
for( str1 = word[2]; ; str1 = NULL ) {
/* token = strtok_r( str1, ",", &save_ptr1 );*/
token = strtok( str1, "," );
/* printf( "token: %s\n", token );*/
if( token == NULL ) {
break;
}
channel = strdup( token );
delimiter = strchr( channel, '/' );
server = NULL;
if( delimiter != NULL ) {
*delimiter = '\0';
if( strlen( delimiter + 1 ) > 0 ) {
server = strdup( delimiter + 1 );
}
}
/* /Network form */
if( strlen( channel ) == 0 ) {
free( channel );
channel = NULL;
}
/* printf( "channel[%s] server[%s]\n", channel, server );*/
if( (ctx = hexchat_find_context( ph, server, channel ) ) != NULL ) {
if( hexchat_set_context( ph, ctx ) ) {
hexchat_command( ph, word_eol[3] );
}
}
if( channel != NULL ) {
free( channel );
}
if( server != NULL ) {
free( server );
}
}
}
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 = "Do At";
*plugin_version = "1.0001";
*plugin_desc = "Perform an arbitrary command on multiple channels";
hexchat_hook_command( ph, "doat", HEXCHAT_PRI_NORM, parse_command, "DOAT [channel,list,/network] [command], perform a command on multiple contexts", NULL );
hexchat_print (ph, "Do At plugin loaded\n");
return 1;
}
int
hexchat_plugin_deinit (void)
{
hexchat_print (ph, "Do At plugin unloaded\n");
return 1;
}

3
plugins/doat/doat.def Normal file
View File

@ -0,0 +1,3 @@
EXPORTS
hexchat_plugin_init
hexchat_plugin_deinit

105
plugins/doat/doat.vcxproj Normal file
View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration">
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{4980AF24-9D42-427D-A8E6-0DF3B97C455D}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>doat</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\win32\hexchat.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\win32\hexchat.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<TargetName>hcdoat</TargetName>
<OutDir>$(HexChatBin)</OutDir>
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<TargetName>hcdoat</TargetName>
<OutDir>$(HexChatBin)</OutDir>
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DOAT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<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>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;DOAT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\src\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>doat.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="doat.c" />
</ItemGroup>
<ItemGroup>
<None Include="doat.def" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -5,18 +5,19 @@
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="win8_provider.cpp">
<ClCompile Include="doat.c">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
<ItemGroup>
<None Include="doat.def">
<Filter>Resource Files</Filter>
</None>
</ItemGroup>
</Project>

502
plugins/ewc/COPYING Normal file
View File

@ -0,0 +1,502 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control compilation
and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply,
and the section as a whole is intended to apply in other circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License may add
an explicit geographical distribution limitation excluding those countries,
so that distribution is permitted only in or among countries not thus
excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
everyone can redistribute and change. You can do so by permitting
redistribution under these terms (or, alternatively, under the terms of the
ordinary General Public License).
To apply these terms, attach the following notices to the library. It is
safest to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
<one line to give the library's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the library, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
<signature of Ty Coon>, 1 April 1990
Ty Coon, President of Vice
That's all there is to it!

231
plugins/ewc/ewc.c Normal file
View File

@ -0,0 +1,231 @@
/*
EasyWinampControl - A Winamp "What's playing" plugin for HexChat
Copyright (C) Yann HAMON & contributors
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <windows.h>
#include "hexchat-plugin.h"
static hexchat_plugin *ph; /* plugin handle */
static int enable = 1;
// For example, circularstrstr("winamp", "pwi", 3) would return 5 (the index of p)
int circularstrstr(char* a, char* b, int nb)
{
int equal = 1;
int length;
int pos=-1;
int i, j;
length = strlen(a);
for (i=0; i<length && pos == -1; ++i) {
equal = 1;
for (j=0; j<nb;j++) {
if (a[(i+j)%length] != b[j])
equal = 0;
}
if (equal == 1)
pos = i;
}
return pos;
}
void GetCurrentSongsName(HWND hwndWinamp, char* title, int titlesize)
{
int pos;
char *title2;
int i, j=0;
int length;
char *p;
GetWindowText(hwndWinamp, title, titlesize);
length = strlen(title);
if ((pos = circularstrstr(title, "- Winamp ***", 12)) != -1) {
// The option "scroll song title in taskbar" is on
title2 = (char*) malloc (titlesize*sizeof(char));
for (i=(pos+12)%length; i!=pos; i=(i+1)%length)
title2[j++] = title[i];
title2[j] = '\0';
p = title2;
while (p<title2+titlesize && *p != '.')
p++;
p+=2; // Delete the . and the following white space
strcpy(title, p);
free(title2);
}
else {
p = title;
while (p<title+titlesize && *p != '.')
p++;
p+=2; // Delete the . and the following white space
if (p<title+titlesize)
strncpy(title, p, titlesize-(p-title));
// Delete the trailing "- winamp"
p = title + titlesize - 1;
while (p>title && *p != '-') p--;
*p = '\0';
}
}
// Controlling winamp
static int wcmd_cb(char *word[], char *word_eol[], void *userdata)
{
// Everything's here : http://winamp.com/nsdn/winamp2x/dev/sdk/api.php
// The previous url seems dead, see http://forums.winamp.com/showthread.php?threadid=180297
HWND hwndWinamp = NULL;
if ((hwndWinamp = FindWindow("Winamp v1.x",NULL)) == NULL) {
hexchat_print(ph, "Winamp's window not found - Is winamp really running?\n");
}
else {
if (strcmp(word[1], "") == 0)
hexchat_print(ph, "Usage: wcmd [command]\n");
else if (strcmp(word[2], "next") == 0) {
hexchat_print(ph, "Loading next song...\n");
SendMessage (hwndWinamp, WM_COMMAND, 40048, 0);
}
else if (strcmp(word[2], "prev") == 0) {
hexchat_print(ph, "Loading previous song...\n");
SendMessage (hwndWinamp, WM_COMMAND, 40044, 0);
}
else if (strcmp(word[2], "play") == 0) {
hexchat_print(ph, "Playin'...\n");
SendMessage (hwndWinamp, WM_COMMAND, 40045, 0);
}
else if (strcmp(word[2], "stop") == 0) {
hexchat_print(ph, "Winamp stopped!...\n");
SendMessage (hwndWinamp, WM_COMMAND, 40047, 0);
}
else if (strcmp(word[2], "pause") == 0) {
SendMessage (hwndWinamp, WM_COMMAND, 40046, 0);
}
}
return HEXCHAT_EAT_ALL;
}
// Display current song
static int wp_cb(char *word[], char *word_eol[], void *userdata)
{
HWND hwndWinamp = NULL;
int bitrate, length, elapsed, minutes, seconds, eminutes, eseconds, samplerate, nbchannels;
char elapsedtime[7];
char totaltime[7];
char this_title[1024];
if ((hwndWinamp = FindWindow("Winamp v1.x",NULL)) == NULL)
hexchat_print(ph, "Winamp's window not found - Is winamp really running?\n");
else {
//Winamp's running
// Seems buggy when winamp2's agent is running, and winamp not (or winamp3) -> crashes HexChat.
SendMessage(hwndWinamp, WM_USER, (WPARAM)0, (LPARAM)125);
if ((samplerate = SendMessage(hwndWinamp, WM_USER, (WPARAM)0, (LPARAM)126)) == 0) {
hexchat_print(ph, "Could not get current song's samplerate... !?\n");
return HEXCHAT_EAT_ALL;
}
if ((bitrate = SendMessage(hwndWinamp, WM_USER, (WPARAM)1, (LPARAM)126)) == 0) {
hexchat_print(ph, "Could not get current song's bitrate... !?\n");
return HEXCHAT_EAT_ALL;
}
if ((nbchannels = SendMessage(hwndWinamp, WM_USER, (WPARAM)2, (LPARAM)126)) == 0) {
hexchat_print(ph, "Could not get the number of channels... !?\n");
return HEXCHAT_EAT_ALL;
}
if ((length = SendMessage(hwndWinamp, WM_USER, (WPARAM)1, (LPARAM)105)) == 0) {
// Could be buggy when streaming audio or video, returned length is unexpected;
// How to detect is Winamp is streaming, and display ??:?? in that case?
hexchat_print(ph, "Could not get current song's length... !?\n");
return HEXCHAT_EAT_ALL;
}
else {
minutes = length/60;
seconds = length%60;
if (seconds>9)
wsprintf(totaltime, "%d:%d", minutes, seconds);
else
wsprintf(totaltime, "%d:0%d", minutes, seconds);
}
if ((elapsed = SendMessage(hwndWinamp, WM_USER, (WPARAM)0, (LPARAM)105)) == 0) {
hexchat_print(ph, "Could not get current song's elapsed time... !?\n");
return HEXCHAT_EAT_ALL;
}
else {
eminutes = (elapsed/1000)/60; /* kinda stupid sounding, but e is for elapsed */
eseconds = (elapsed/1000)%60;
if (eseconds>9)
wsprintf(elapsedtime, "%d:%d", eminutes, eseconds);
else
wsprintf(elapsedtime, "%d:0%d", eminutes, eseconds);
}
if ((bitrate = SendMessage(hwndWinamp, WM_USER, (WPARAM)1, (LPARAM)126)) == 0) {
hexchat_print(ph, "Could not get current song's bitrate... !?\n");
return HEXCHAT_EAT_ALL;
}
GetCurrentSongsName(hwndWinamp, this_title, 1024);
hexchat_commandf(ph, "dispcurrsong %d %d %d %s %s %s", samplerate, bitrate, nbchannels, elapsedtime, totaltime, this_title);
}
return HEXCHAT_EAT_ALL; /* eat this command so HexChat and other plugins can't process it */
}
int hexchat_plugin_init(hexchat_plugin *plugin_handle,
char **plugin_name,
char **plugin_desc,
char **plugin_version,
char *arg)
{
/* we need to save this for use with any hexchat_* functions */
ph = plugin_handle;
*plugin_name = "EasyWinampControl";
*plugin_desc = "Some commands to remotely control winamp";
*plugin_version = "1.2";
hexchat_hook_command(ph, "wp", HEXCHAT_PRI_NORM, wp_cb,
"Usage: wp", 0);
hexchat_hook_command(ph, "wcmd", HEXCHAT_PRI_NORM, wcmd_cb,
"Usage: wcmd [play|pause|stop|prev|next]", 0);
hexchat_print(ph, "EasyWinampControl plugin loaded\n");
return 1; /* return 1 for success */
}
int hexchat_plugin_deinit(void)
{
hexchat_print(ph, "EasyWinampControl plugin unloaded\n");
return 1;
}

18
plugins/ewc/makefile.mak Normal file
View File

@ -0,0 +1,18 @@
include "..\..\src\makeinc.mak"
all: ewc.obj ewc.def
link $(LDFLAGS) $(LIBS) /dll /out:xcewc.dll /def:ewc.def ewc.obj
ewc.def:
echo EXPORTS > ewc.def
echo hexchat_plugin_init >> ewc.def
echo hexchat_plugin_deinit >> ewc.def
ewc.obj: ewc.c makefile.mak
cl $(CFLAGS) ewc.c
clean:
del *.obj
del *.dll
del *.exp
del *.lib

View File

@ -28,7 +28,7 @@
static hexchat_plugin *ph; /* plugin handle */
static char name[] = "Exec";
static char desc[] = "Execute commands inside HexChat";
static char version[] = "1.2";
static char version[] = "1.1";
static int
run_command (char *word[], char *word_eol[], void *userdata)
@ -41,10 +41,6 @@ run_command (char *word[], char *word_eol[], void *userdata)
time_t start;
double timeElapsed;
char *token;
char *context = NULL;
int announce = 0;
HANDLE readPipe;
HANDLE writePipe;
STARTUPINFO sInfo;
@ -63,8 +59,9 @@ run_command (char *word[], char *word_eol[], void *userdata)
if (!stricmp("-O", word[2]))
{
strcat (commandLine, word_eol[3]);
announce = 1;
/*strcat (commandLine, word_eol[3]);*/
hexchat_printf (ph, "Printing Exec output to others is not supported yet.\n");
return HEXCHAT_EAT_HEXCHAT;
}
else
{
@ -93,19 +90,7 @@ run_command (char *word[], char *word_eol[], void *userdata)
{
/* avoid garbage */
buffer[dwRead] = '\0';
if (announce)
{
/* Say each line seperately, TODO: improve... */
token = strtok_s (buffer, "\n", &context);
while (token != NULL)
{
hexchat_commandf (ph, "SAY %s", token);
token = strtok_s (NULL, "\n", &context);
}
}
else
hexchat_printf (ph, "%s", buffer);
hexchat_printf (ph, "%s", buffer);
}
}
else
@ -115,25 +100,20 @@ run_command (char *word[], char *word_eol[], void *userdata)
}
timeElapsed = difftime (time (0), start);
}
/* display a newline to separate things */
if (!announce)
hexchat_printf (ph, "\n");
if (timeElapsed >= 10)
{
hexchat_printf (ph, "Command took too much time to run, execution aborted.\n");
}
CloseHandle (readPipe);
CloseHandle (pInfo.hProcess);
CloseHandle (pInfo.hThread);
}
else
/* display a newline to separate things */
hexchat_printf (ph, "\n");
if (timeElapsed >= 10)
{
hexchat_command (ph, "help exec");
hexchat_printf (ph, "Command took too much time to run, execution aborted.\n");
}
CloseHandle (readPipe);
CloseHandle (pInfo.hProcess);
CloseHandle (pInfo.hThread);
return HEXCHAT_EAT_HEXCHAT;
}

View File

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
@ -20,28 +19,77 @@
<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>
<Optimization>MaxSpeed</Optimization>
<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>
<Optimization>MaxSpeed</Optimization>
<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 +100,6 @@
<ClCompile Include="exec.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,5 +0,0 @@
shared_module('exec', 'exec.c',
dependencies: hexchat_plugin_dep,
install: true,
install_dir: plugindir
)

16
plugins/fishlim/INSTALL Normal file
View File

@ -0,0 +1,16 @@
Install dependencies (on Debian/Ubuntu):
sudo apt-get install build-essential libglib2.0-dev libssl-dev
Build the plugin with:
make
Install with:
sudo make install

View File

@ -0,0 +1,9 @@
EXTRA_DIST = INSTALL LICENSE README
libdir = $(hexchatlibdir)
lib_LTLIBRARIES = fishlim.la
fishlim_la_SOURCES = fish.c irc.c keystore.c misc.c plugin_hexchat.c
fishlim_la_LDFLAGS = -avoid-version -module
fishlim_la_LIBADD =
AM_CPPFLAGS = $(COMMON_CFLAGS) -I$(srcdir)/../../src/common

5
plugins/fishlim/bool.h Normal file
View File

@ -0,0 +1,5 @@
/* stdbool.h replacement for MSVC */
#define false 0
#define true 1
#define bool _Bool
typedef int _Bool;

View File

@ -1,238 +0,0 @@
/* HexChat
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
/*
* For Diffie-Hellman key-exchange a 1080bit germain prime is used, the
* generator g=2 renders a field Fp from 1 to p-1. Therefore breaking it
* means to solve a discrete logarithm problem with no less than 1080bit.
*
* Base64 format is used to send the public keys over IRC.
*
* The calculated secret key is hashed with SHA-256, the result is converted
* to base64 for final use with blowfish.
*/
#include "config.h"
#include "dh1080.h"
#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/sha.h>
#include <string.h>
#include <glib.h>
#define DH1080_PRIME_BITS 1080
#define DH1080_PRIME_BYTES 135
#define SHA256_DIGEST_LENGTH 32
#define B64ABC "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
#define MEMZERO(x) memset(x, 0x00, sizeof(x))
/* All clients must use the same prime number to be able to keyx */
static const guchar prime1080[DH1080_PRIME_BYTES] =
{
0xFB, 0xE1, 0x02, 0x2E, 0x23, 0xD2, 0x13, 0xE8, 0xAC, 0xFA, 0x9A, 0xE8, 0xB9, 0xDF, 0xAD, 0xA3, 0xEA,
0x6B, 0x7A, 0xC7, 0xA7, 0xB7, 0xE9, 0x5A, 0xB5, 0xEB, 0x2D, 0xF8, 0x58, 0x92, 0x1F, 0xEA, 0xDE, 0x95,
0xE6, 0xAC, 0x7B, 0xE7, 0xDE, 0x6A, 0xDB, 0xAB, 0x8A, 0x78, 0x3E, 0x7A, 0xF7, 0xA7, 0xFA, 0x6A, 0x2B,
0x7B, 0xEB, 0x1E, 0x72, 0xEA, 0xE2, 0xB7, 0x2F, 0x9F, 0xA2, 0xBF, 0xB2, 0xA2, 0xEF, 0xBE, 0xFA, 0xC8,
0x68, 0xBA, 0xDB, 0x3E, 0x82, 0x8F, 0xA8, 0xBA, 0xDF, 0xAD, 0xA3, 0xE4, 0xCC, 0x1B, 0xE7, 0xE8, 0xAF,
0xE8, 0x5E, 0x96, 0x98, 0xA7, 0x83, 0xEB, 0x68, 0xFA, 0x07, 0xA7, 0x7A, 0xB6, 0xAD, 0x7B, 0xEB, 0x61,
0x8A, 0xCF, 0x9C, 0xA2, 0x89, 0x7E, 0xB2, 0x8A, 0x61, 0x89, 0xEF, 0xA0, 0x7A, 0xB9, 0x9A, 0x8A, 0x7F,
0xA9, 0xAE, 0x29, 0x9E, 0xFA, 0x7B, 0xA6, 0x6D, 0xEA, 0xFE, 0xFB, 0xEF, 0xBF, 0x0B, 0x7D, 0x8B
};
static DH *g_dh;
int
dh1080_init (void)
{
g_return_val_if_fail (g_dh == NULL, 0);
if ((g_dh = DH_new()))
{
int codes;
BIGNUM *p, *g;
p = BN_bin2bn (prime1080, DH1080_PRIME_BYTES, NULL);
g = BN_new ();
if (p == NULL || g == NULL)
return 1;
BN_set_word (g, 2);
#ifndef HAVE_DH_SET0_PQG
g_dh->p = p;
g_dh->g = g;
#else
if (!DH_set0_pqg (g_dh, p, NULL, g))
return 1;
#endif
if (DH_check (g_dh, &codes))
return codes == 0;
}
return 0;
}
void
dh1080_deinit (void)
{
g_clear_pointer (&g_dh, DH_free);
}
static inline int
DH_verifyPubKey (BIGNUM *pk)
{
int codes;
return DH_check_pub_key (g_dh, pk, &codes) && codes == 0;
}
static guchar *
dh1080_decode_b64 (const char *data, gsize *out_len)
{
GString *str = g_string_new (data);
guchar *ret;
if (str->len % 4 == 1 && str->str[str->len - 1] == 'A')
g_string_truncate (str, str->len - 1);
while (str->len % 4 != 0)
g_string_append_c (str, '=');
ret = g_base64_decode_inplace (str->str, out_len);
g_string_free (str, FALSE);
return ret;
}
static char *
dh1080_encode_b64 (const guchar *data, gsize data_len)
{
char *ret = g_base64_encode (data, data_len);
char *p;
if (!(p = strchr (ret, '=')))
{
char *new_ret = g_new(char, strlen(ret) + 2);
strcpy (new_ret, ret);
strcat (new_ret, "A");
g_free (ret);
ret = new_ret;
}
else
{
*p = '\0';
}
return ret;
}
int
dh1080_generate_key (char **priv_key, char **pub_key)
{
guchar buf[DH1080_PRIME_BYTES];
int len;
DH *dh;
const BIGNUM *dh_priv_key, *dh_pub_key;
g_assert (priv_key != NULL);
g_assert (pub_key != NULL);
dh = DHparams_dup (g_dh);
if (!dh)
return 0;
if (!DH_generate_key (dh))
{
DH_free (dh);
return 0;
}
#ifndef HAVE_DH_GET0_KEY
dh_pub_key = dh->pub_key;
dh_priv_key = dh->priv_key;
#else
DH_get0_key (dh, &dh_pub_key, &dh_priv_key);
#endif
MEMZERO (buf);
len = BN_bn2bin (dh_priv_key, buf);
*priv_key = dh1080_encode_b64 (buf, len);
MEMZERO (buf);
len = BN_bn2bin (dh_pub_key, buf);
*pub_key = dh1080_encode_b64 (buf, len);
OPENSSL_cleanse (buf, sizeof (buf));
DH_free (dh);
return 1;
}
int
dh1080_compute_key (const char *priv_key, const char *pub_key, char **secret_key)
{
char *pub_key_data;
gsize pub_key_len;
BIGNUM *pk;
DH *dh;
#ifdef HAVE_DH_SET0_KEY
BIGNUM *temp_pub_key = BN_new();
#endif
g_assert (secret_key != NULL);
/* Verify base64 strings */
if (strspn (priv_key, B64ABC) != strlen (priv_key)
|| strspn (pub_key, B64ABC) != strlen (pub_key))
return 0;
dh = DHparams_dup (g_dh);
pub_key_data = dh1080_decode_b64 (pub_key, &pub_key_len);
pk = BN_bin2bn (pub_key_data, pub_key_len, NULL);
if (DH_verifyPubKey (pk))
{
guchar shared_key[DH1080_PRIME_BYTES] = { 0 };
guchar sha256[SHA256_DIGEST_LENGTH] = { 0 };
char *priv_key_data;
gsize priv_key_len;
int shared_len;
BIGNUM *priv_key_num;
priv_key_data = dh1080_decode_b64 (priv_key, &priv_key_len);
priv_key_num = BN_bin2bn(priv_key_data, priv_key_len, NULL);
#ifndef HAVE_DH_SET0_KEY
dh->priv_key = priv_key_num;
#else
DH_set0_key (dh, temp_pub_key, priv_key_num);
#endif
shared_len = DH_compute_key (shared_key, pk, dh);
SHA256(shared_key, shared_len, sha256);
*secret_key = dh1080_encode_b64 (sha256, sizeof(sha256));
OPENSSL_cleanse (priv_key_data, priv_key_len);
g_free (priv_key_data);
}
BN_free (pk);
DH_free (dh);
g_free (pub_key_data);
return 1;
}

View File

@ -1,24 +0,0 @@
/* HexChat
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#pragma once
int dh1080_generate_key (char **, char **);
int dh1080_compute_key (const char *, const char *, char **);
int dh1080_init (void);
void dh1080_deinit (void);

View File

@ -22,11 +22,6 @@
*/
#ifdef __APPLE__
#define __AVAILABILITYMACROS__
#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
#endif
#include <stdlib.h>
#include <string.h>
#include <openssl/blowfish.h>
@ -39,17 +34,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 +70,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 +85,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 +101,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,18 +119,19 @@ 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;
for (i = 0; i < 12; i++) {
d = fish_unbase64[(const unsigned char)*(data++)];
if (d == IB) goto decrypt_end;
binary[word] |= (unsigned long)d << bit;
binary[word] |= d << bit;
bit += 6;
if (i == 5) {
bit = 0;
@ -142,10 +139,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 +160,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 +178,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;
}

View File

@ -25,10 +25,13 @@
#ifndef FISH_H
#define FISH_H
#ifdef _MSC_VER
#include "bool.h"
#else
#include <stdbool.h>
#endif
#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);

View File

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration">
<PlatformToolset>v140</PlatformToolset>
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
@ -20,19 +19,58 @@
<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>
<Optimization>MaxSpeed</Optimization>
<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 +78,20 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<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>
@ -53,18 +101,21 @@
<None Include="fishlim.def" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="dh1080.h" />
<ClInclude Include="bool.h" />
<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="dh1080.c" />
<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>

View File

@ -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>

View File

@ -22,9 +22,8 @@
*/
#include "config.h"
#include <glib.h>
#include <stdlib.h>
#include <string.h>
#include "irc.h"
/**
@ -32,28 +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++;
if (parameters_offset)
*parameters_offset = w;
return TRUE;
*parameters_offset = w;
return true;
}
@ -68,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;
}
}

View File

@ -25,13 +25,18 @@
#ifndef IRC_H
#define IRC_H
#ifdef _MSC_VER
#include "bool.h"
#else
#include <stdbool.h>
#endif
#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

View File

@ -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"
@ -39,7 +38,7 @@ static char *keystore_password = NULL;
/**
* Opens the key store file: ~/.config/hexchat/addon_fishlim.conf
*/
static GKeyFile *getConfigFile(void) {
static GKeyFile *getConfigFile() {
gchar *filename = get_config_filename();
GKeyFile *keyfile = g_key_file_new();
@ -55,30 +54,14 @@ static GKeyFile *getConfigFile(void) {
/**
* Returns the key store password, or the default.
*/
static const char *get_keystore_password(void) {
static const char *get_keystore_password() {
return (keystore_password != NULL ?
keystore_password :
/* Silly default value... */
// Silly default value...
"blowinikey");
}
static char *escape_nickname(const char *nick) {
char *escaped = g_strdup(nick);
char *p = escaped;
while (*p) {
if (*p == '[')
*p = '~';
else if (*p == ']')
*p = '!';
++p;
}
return escaped;
}
/**
* Gets a value for a nick/channel from addon_fishlim.conf. Unlike
* g_key_file_get_string, this function is case insensitive.
@ -104,21 +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();
char *escaped_nick = escape_nickname(nick);
gchar *value = get_nick_value(keyfile, escaped_nick, "key");
gchar *value = get_nick_value(keyfile, nick, "key");
g_key_file_free(keyfile);
g_free(escaped_nick);
if (!value)
return NULL;
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);
@ -130,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)) {
@ -146,102 +125,85 @@ 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
G_GNUC_BEGIN_IGNORE_DEPRECATIONS /* Hide false positive */
ok = g_key_file_save_to_file (keyfile, filename, NULL);
G_GNUC_END_IGNORE_DEPRECATIONS
#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();
char *escaped_nick = escape_nickname(nick);
/* Remove old key */
delete_nick(keyfile, escaped_nick);
/* Add new key */
// Remove old key
delete_nick(keyfile, nick);
// 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 */
g_key_file_set_string(keyfile, escaped_nick, "key", wrapped);
g_free(wrapped);
// Store encrypted in file
g_key_file_set_string(keyfile, nick, "key", wrapped);
free(wrapped);
} else {
/* Store unencrypted in file */
g_key_file_set_string(keyfile, escaped_nick, "key", key);
// 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:
g_key_file_free(keyfile);
g_free(escaped_nick);
return ok;
}
/**
* Deletes a nick from the key store.
*/
gboolean keystore_delete_nick(const char *nick) {
bool keystore_delete_nick(const char *nick) {
GKeyFile *keyfile = getConfigFile();
char *escaped_nick = escape_nickname(nick);
/* Delete entry */
gboolean ok = delete_nick(keyfile, escaped_nick);
// Delete entry
bool ok = delete_nick(keyfile, nick);
/* Save */
// Save
if (ok) save_keystore(keyfile);
g_key_file_free(keyfile);
g_free(escaped_nick);
return ok;
}
void keystore_secure_free(void *ptr, size_t size) {
secure_erase(ptr, size);
free(ptr);
}

View File

@ -25,13 +25,18 @@
#ifndef KEYSTORE_H
#define KEYSTORE_H
#ifdef _MSC_VER
#include "bool.h"
#else
#include <stdbool.h>
#endif
#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

View File

@ -1,18 +0,0 @@
if not libssl_dep.found()
error('fish plugin requires openssl')
endif
fishlim_sources = [
'dh1080.c',
'fish.c',
'irc.c',
'keystore.c',
'plugin_hexchat.c'
]
shared_module('fishlim', fishlim_sources,
dependencies: [libgio_dep, hexchat_plugin_dep, libssl_dep],
install: true,
install_dir: plugindir,
name_prefix: '',
)

54
plugins/fishlim/misc.c Normal file
View 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
View 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

View File

@ -1,7 +1,6 @@
/*
Copyright (c) 2010-2011 Samuel Lidén Borell <samuel@kodafritt.se>
Copyright (c) 2015 <the.cypher@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -23,84 +22,56 @@
*/
#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 "dh1080.h"
#include "keystore.h"
#include "irc.h"
static const char plugin_name[] = "FiSHLiM";
static const char plugin_desc[] = "Encryption plugin for the FiSH protocol. Less is More!";
static const char plugin_version[] = "0.1.0";
static const char plugin_version[] = "0.0.16";
static const char usage_setkey[] = "Usage: SETKEY [<nick or #channel>] <password>, sets the key for a channel or nick";
static const char usage_delkey[] = "Usage: DELKEY <nick or #channel>, deletes the key for a channel or nick";
static const char usage_keyx[] = "Usage: KEYX [<nick>], performs DH1080 key-exchange with <nick>";
static const char usage_topic[] = "Usage: TOPIC+ <topic>, sets a new encrypted topic for the current channel";
static const char usage_notice[] = "Usage: NOTICE+ <nick or #channel> <notice>";
static const char usage_msg[] = "Usage: MSG+ <nick or #channel> <message>";
static hexchat_plugin *ph;
static GHashTable *pending_exchanges;
/**
* Returns the path to the key store file.
*/
gchar *get_config_filename(void) {
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;
gchar *get_config_filename() {
return g_build_filename(hexchat_get_info(ph, "configdir"), "addon_fishlim.conf", NULL);
}
static inline gboolean irc_is_query (const char *name) {
const char *chantypes = hexchat_list_str (ph, NULL, "chantypes");
return strchr (chantypes, name[0]) == NULL;
/**
* 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 hexchat_context *find_context_on_network (const char *name) {
hexchat_list *channels;
hexchat_context *ret = NULL;
int id;
if (hexchat_get_prefs(ph, "id", NULL, &id) != 2)
return NULL;
channels = hexchat_list_get(ph, "channels");
if (!channels)
return NULL;
while (hexchat_list_next(ph, channels)) {
int chan_id = hexchat_list_int(ph, channels, "id");
const char *chan_name = hexchat_list_str(ph, channels, "channel");
if (chan_id == id && chan_name && hexchat_nickcmp (ph, chan_name, name) == 0) {
ret = (hexchat_context*)hexchat_list_str(ph, channels, "context");
break;
}
};
hexchat_list_free(ph, channels);
return ret;
}
int irc_nick_cmp(const char *a, const char *b) {
return hexchat_nickcmp (ph, a, b);
}
/*static int handle_debug(char *word[], char *word_eol[], void *userdata) {
hexchat_printf(ph, "debug incoming: ");
@ -116,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;
@ -143,201 +114,108 @@ 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;
char prefix_char = 0;
GString *message;
size_t length;
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++); }
else { prefix_char = 0; }
if (strcmp(s, "+OK") == 0 || strcmp(s, "mcps") == 0) goto has_encrypted_data;
}
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);
}
} 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);
/* 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);
free(decrypted);
// 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;
}
static int handle_keyx_notice(char *word[], char *word_eol[], void *userdata) {
const char *dh_message = word[4];
const char *dh_pubkey = word[5];
hexchat_context *query_ctx;
const char *prefix;
gboolean cbc;
char *sender, *secret_key, *priv_key = NULL;
if (!*dh_message || !*dh_pubkey || strlen(dh_pubkey) != 181)
return HEXCHAT_EAT_NONE;
if (!irc_parse_message((const char**)word, &prefix, NULL, NULL) || !prefix)
return HEXCHAT_EAT_NONE;
sender = irc_prefix_get_nick(prefix);
query_ctx = find_context_on_network(sender);
if (query_ctx)
hexchat_set_context(ph, query_ctx);
dh_message++; /* : prefix */
if (*dh_message == '+' || *dh_message == '-')
dh_message++; /* identify-msg */
cbc = g_strcmp0 (word[6], "CBC") == 0;
if (!strcmp(dh_message, "DH1080_INIT")) {
char *pub_key;
if (cbc) {
hexchat_print(ph, "Received key exchange for CBC mode which is not supported.");
goto cleanup;
}
hexchat_printf(ph, "Received public key from %s, sending mine...", sender);
if (dh1080_generate_key(&priv_key, &pub_key)) {
hexchat_commandf(ph, "quote NOTICE %s :DH1080_FINISH %s", sender, pub_key);
g_free(pub_key);
} else {
hexchat_print(ph, "Failed to generate keys");
goto cleanup;
}
} else if (!strcmp (dh_message, "DH1080_FINISH")) {
char *sender_lower = g_ascii_strdown(sender, -1);
/* FIXME: Properly respect irc casing */
priv_key = g_hash_table_lookup(pending_exchanges, sender_lower);
g_hash_table_steal(pending_exchanges, sender_lower);
g_free(sender_lower);
if (cbc) {
hexchat_print(ph, "Received key exchange for CBC mode which is not supported.");
goto cleanup;
}
if (!priv_key) {
hexchat_printf(ph, "Received a key exchange response for unknown user: %s", sender);
goto cleanup;
}
} else {
/* Regular notice */
g_free(sender);
return HEXCHAT_EAT_NONE;
}
if (dh1080_compute_key(priv_key, dh_pubkey, &secret_key)) {
keystore_store_key(sender, secret_key);
hexchat_printf(ph, "Stored new key for %s", sender);
g_free(secret_key);
} else {
hexchat_print(ph, "Failed to create secret key!");
}
cleanup:
g_free(sender);
g_free(priv_key);
return HEXCHAT_EAT_ALL;
}
/**
* Command handler for /setkey
*/
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 {
hexchat_printf(ph, "\00305Failed to store key in addon_fishlim.conf\n");
hexchat_printf(ph, "\00305Failed to store key in blow.ini\n", nick, key);
}
return HEXCHAT_EAT_HEXCHAT;
}
@ -346,174 +224,25 @@ 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]);
/* Delete the given nick from the key store */
nick = word_eol[2];
// Delete the given nick from the key store
if (keystore_delete_nick(nick)) {
hexchat_printf(ph, "Deleted key for %s\n", nick);
} else {
hexchat_printf(ph, "\00305Failed to delete key in addon_fishlim.conf!\n");
hexchat_printf(ph, "\00305Failed to delete key in blow.ini!\n", nick);
}
return HEXCHAT_EAT_HEXCHAT;
}
static int handle_keyx(char *word[], char *word_eol[], void *userdata) {
const char *target = word[2];
hexchat_context *query_ctx = NULL;
char *pub_key, *priv_key;
int ctx_type;
if (*target)
query_ctx = find_context_on_network(target);
else {
target = hexchat_get_info(ph, "channel");
query_ctx = hexchat_get_context (ph);
}
if (query_ctx) {
hexchat_set_context(ph, query_ctx);
ctx_type = hexchat_list_int(ph, NULL, "type");
}
if ((query_ctx && ctx_type != 3) || (!query_ctx && !irc_is_query(target))) {
hexchat_print(ph, "You can only exchange keys with individuals");
return HEXCHAT_EAT_ALL;
}
if (dh1080_generate_key(&priv_key, &pub_key)) {
g_hash_table_replace (pending_exchanges, g_ascii_strdown(target, -1), priv_key);
hexchat_commandf(ph, "quote NOTICE %s :DH1080_INIT %s", target, pub_key);
hexchat_printf(ph, "Sent public key to %s, waiting for reply...", target);
g_free(pub_key);
} else {
hexchat_print(ph, "Failed to generate keys");
}
return HEXCHAT_EAT_ALL;
}
/**
* Command handler for /topic+
*/
static int handle_crypt_topic(char *word[], char *word_eol[], void *userdata) {
const char *target;
const char *topic = word_eol[2];
char *buf;
if (!*topic) {
hexchat_print(ph, usage_topic);
return HEXCHAT_EAT_ALL;
}
if (hexchat_list_int(ph, NULL, "type") != 2) {
hexchat_printf(ph, "Please change to the channel window where you want to set the topic!");
return HEXCHAT_EAT_ALL;
}
target = hexchat_get_info(ph, "channel");
buf = fish_encrypt_for_nick(target, topic);
if (buf == NULL) {
hexchat_printf(ph, "/topic+ error, no key found for %s", target);
return HEXCHAT_EAT_ALL;
}
hexchat_commandf(ph, "TOPIC %s +OK %s", target, buf);
g_free(buf);
return HEXCHAT_EAT_ALL;
}
/**
* Command handler for /notice+
*/
static int handle_crypt_notice(char *word[], char *word_eol[], void *userdata)
{
const char *target = word[2];
const char *notice = word_eol[3];
char *buf;
if (!*target || !*notice) {
hexchat_print(ph, usage_notice);
return HEXCHAT_EAT_ALL;
}
buf = fish_encrypt_for_nick(target, notice);
if (buf == NULL) {
hexchat_printf(ph, "/notice+ error, no key found for %s.", target);
return HEXCHAT_EAT_ALL;
}
hexchat_commandf(ph, "quote NOTICE %s :+OK %s", target, buf);
hexchat_emit_print(ph, "Notice Sent", target, notice);
g_free(buf);
return HEXCHAT_EAT_ALL;
}
/**
* Command handler for /msg+
*/
static int handle_crypt_msg(char *word[], char *word_eol[], void *userdata)
{
const char *target = word[2];
const char *message = word_eol[3];
hexchat_context *query_ctx;
char *buf;
if (!*target || !*message) {
hexchat_print(ph, usage_msg);
return HEXCHAT_EAT_ALL;
}
buf = fish_encrypt_for_nick(target, message);
if (buf == NULL) {
hexchat_printf(ph, "/msg+ error, no key found for %s", target);
return HEXCHAT_EAT_ALL;
}
hexchat_commandf(ph, "PRIVMSG %s :+OK %s", target, buf);
query_ctx = find_context_on_network(target);
if (query_ctx) {
hexchat_set_context(ph, query_ctx);
/* FIXME: Mode char */
hexchat_emit_print(ph, "Your Message", hexchat_get_info(ph, "nick"),
message, "", "");
}
else {
hexchat_emit_print(ph, "Message Send", target, message);
}
g_free(buf);
return HEXCHAT_EAT_ALL;
}
static int handle_crypt_me(char *word[], char *word_eol[], void *userdata) {
const char *channel = hexchat_get_info(ph, "channel");
char *buf;
buf = fish_encrypt_for_nick(channel, word_eol[2]);
if (!buf)
return HEXCHAT_EAT_NONE;
hexchat_commandf(ph, "PRIVMSG %s :\001ACTION +OK %s \001", channel, buf);
hexchat_emit_print(ph, "Your Action", hexchat_get_info(ph, "nick"),
word_eol[2], NULL);
g_free(buf);
return HEXCHAT_EAT_ALL;
}
/**
* Returns the plugin name version information.
*/
@ -533,44 +262,30 @@ int hexchat_plugin_init(hexchat_plugin *plugin_handle,
const char **version,
char *arg) {
ph = plugin_handle;
/* Send our info to HexChat */
*name = plugin_name;
*desc = plugin_desc;
*version = plugin_version;
/* Register commands */
hexchat_hook_command(ph, "SETKEY", HEXCHAT_PRI_NORM, handle_setkey, usage_setkey, NULL);
hexchat_hook_command(ph, "DELKEY", HEXCHAT_PRI_NORM, handle_delkey, usage_delkey, NULL);
hexchat_hook_command(ph, "KEYX", HEXCHAT_PRI_NORM, handle_keyx, usage_keyx, NULL);
hexchat_hook_command(ph, "TOPIC+", HEXCHAT_PRI_NORM, handle_crypt_topic, usage_topic, NULL);
hexchat_hook_command(ph, "NOTICE+", HEXCHAT_PRI_NORM, handle_crypt_notice, usage_notice, NULL);
hexchat_hook_command(ph, "MSG+", HEXCHAT_PRI_NORM, handle_crypt_msg, usage_msg, NULL);
hexchat_hook_command(ph, "ME", HEXCHAT_PRI_NORM, handle_crypt_me, NULL, NULL);
/* Add handlers */
hexchat_hook_command(ph, "", HEXCHAT_PRI_NORM, handle_outgoing, NULL, NULL);
hexchat_hook_server(ph, "NOTICE", HEXCHAT_PRI_HIGHEST, handle_keyx_notice, 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);
if (!dh1080_init())
return 0;
pending_exchanges = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
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 */
return 1;
}
int hexchat_plugin_deinit(void) {
g_clear_pointer(&pending_exchanges, g_hash_table_destroy);
dh1080_deinit();
hexchat_printf(ph, "%s plugin unloaded\n", plugin_name);
return 1;
}

View File

@ -25,8 +25,7 @@
#ifndef PLUGIN_HEXCHAT_H
#define PLUGIN_HEXCHAT_H
gchar *get_config_filename(void);
int irc_nick_cmp (const char *, const char *);
gchar *get_config_filename();
#endif

91
plugins/fishlim/test.c Normal file
View File

@ -0,0 +1,91 @@
/*
Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <glib.h>
#include <stdio.h>
#include <string.h>
#include "fish.h"
// We can't use the HexChat plugin API from here...
gchar *get_config_filename() {
const gchar *homedir = g_get_home_dir();
return g_build_filename(homedir, ".xchat2", "blow.ini", NULL);
}
static int decrypt(int nick_count, char *nicks[]) {
char encrypted[8192];
while (fgets(encrypted, sizeof(encrypted), stdin)) {
char *msg;
for (int i = 0; i < nick_count; i++) {
msg = fish_decrypt_from_nick(nicks[i], encrypted);
if (msg) goto success;
}
fprintf(stderr, "None of the recipients were found in the key store!\n");
return 1;
success:
fprintf(stderr, "Decrypted text >>>%s<<<\n", msg);
}
return 0;
}
static int encrypt(int nick_count, char *nicks[]) {
char message[8192];
while (fgets(message, sizeof(message), stdin)) {
// Remove newline character
char *newline = strchr(message, '\n');
if (newline) *newline = '\0';
bool error = false;
for (int i = 0; i < nick_count; i++) {
char *encrypted = fish_encrypt_for_nick(nicks[i], message);
if (encrypted) {
fprintf(stderr, "Encrypted [%s]: >>>%s<<<\n", nicks[i], encrypted);
} else {
error = true;
}
}
if (error) {
fprintf(stderr, "Some of the recipients were't found in the key store!\n");
return 1;
}
}
return 0;
}
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "usage: %s [-e] nick...\n", argv[0]);
return 2;
}
if (strcmp(argv[1], "-e") == 0) {
return encrypt(argc-2, &argv[2]);
} else {
return decrypt(argc-1, &argv[1]);
}
}

69
plugins/gtkpref/gtkpref.c Normal file
View File

@ -0,0 +1,69 @@
/* 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 <windows.h>
#include "hexchat-plugin.h"
static hexchat_plugin *ph; /* plugin handle */
static void
launch_tool ()
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory (&si, sizeof (si));
si.cb = sizeof (si);
ZeroMemory (&pi, sizeof (pi));
if (!CreateProcess ( NULL, "gtk2-prefs.exe", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
hexchat_print (ph, "Error launching the GTK+ Preference Tool! Maybe the executable is missing?");
}
CloseHandle (pi.hProcess);
CloseHandle (pi.hThread);
}
int
hexchat_plugin_init (hexchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg)
{
ph = plugin_handle;
*plugin_name = "GTKPref";
*plugin_desc = "GTK+ Preference Tool Launcher";
*plugin_version = "1.0";
hexchat_hook_command (ph, "GTKPREF", HEXCHAT_PRI_NORM, launch_tool, 0, 0);
hexchat_command (ph, "MENU -ietc\\gtkpref.png ADD \"Settings/GTK+ Preferences\" \"GTKPREF\"");
return 1; /* return 1 for success */
}
int
hexchat_plugin_deinit (void)
{
hexchat_command (ph, "MENU DEL \"Settings/GTK+ Preferences\"");
return 1;
}

View File

@ -0,0 +1,18 @@
include "..\..\src\makeinc.mak"
all: gtkpref.obj gtkpref.def
link $(LDFLAGS) $(LIBS) /dll /out:xcgtkpref.dll /def:gtkpref.def gtkpref.obj
gtkpref.def:
echo EXPORTS > gtkpref.def
echo hexchat_plugin_init >> gtkpref.def
echo hexchat_plugin_deinit >> gtkpref.def
gtkpref.obj: gtkpref.c makefile.mak
cl $(CFLAGS) $(GLIB) /I.. gtkpref.c
clean:
del *.obj
del *.dll
del *.exp
del *.lib

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,734 @@
/* X-Tray
* Copyright (C) 2005 Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>
*
* X-Tray 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.
*
* X-Tray 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 X-Tray; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define _WIN32_IE 0x0601
#include <windows.h>
#include <stdio.h>
#include <commctrl.h>
#include <tchar.h>
#include "hexchat-plugin.h"
#include "utility.h"
#include "hextray.h"
#include "hexchat.h"
#include "callbacks.h"
#include "resource.h"
#include "sdTray.h"
#include "sdAlerts.h"
HWND g_hPrefTabEvents;
HWND g_hPrefTabSettings;
HWND g_hPrefTabAlerts;
HWND g_hPrefTabAbout;
bool g_bCanQuit;
int g_iIsActive = 1;
BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam)
{
TCHAR szTitle[10];
GetWindowText(hWnd, szTitle, 9);
if(_tcsstr(szTitle, _T("HexChat [")))
{
g_hXchatWnd = hWnd;
return false;
}
return true;
}
/***********************************************************************************************/
/******* our HexChat event call back, get the name and info for each event and save it *********/
/******* for our alerts later ******************************************************************/
/***********************************************************************************************/
int event_cb(char *word[], void *userdata)
{
int iEvent = (int)userdata;
if(iEvent > 10 && iEvent != 21)
return HEXCHAT_EAT_NONE;
/***************************************************************************************/
/***** if the window is minimized or if we're allowed to show alerts when its not **/
/***** and if the option to show the specified alert is true and if we're even **/
/***** allowed to show alerts at all then we show them (a bit confusing but it works) **/
/***************************************************************************************/
if(((g_iIsActive == 0) || !(g_dwPrefs & (1<<PREF_OSBWM))) && (g_dwPrefs & (1<<PREF_AMAE)) && (g_dwPrefs & (1<<iEvent)))
{
/*********************************/
/*********** Our Buffers *********/
/*********************************/
char szInfo[512];
char szName[64];
DWORD dwInfoFlags;
int iTime = g_iTime*1000;
char *szTemp = NULL;
if(g_dwPrefs & (1<<PREF_KAOI))
{
iTime = 0;
}
switch(iEvent)
{
case CHAN_HILIGHT:
_snprintf(szInfo, 512, "%s:\r\n%s", word[1], word[2]);
_snprintf(szName, 64, "Highlight: %s", hexchat_get_info (ph, "channel"));
dwInfoFlags = NIIF_INFO;
break;
case CHAN_MESSAGE:
_snprintf(szInfo, 512, "%s:\r\n%s", word[1], word[2]);
_snprintf(szName, 64, "Channel Message: %s", hexchat_get_info (ph, "channel"));
dwInfoFlags = NIIF_INFO;
break;
case CHAN_TOPIC_CHANGE:
_snprintf(szInfo, 512, "%s has changed the topic to %s", word[1], word[2]);
_snprintf(szName, 64, "Topic Change: %s", word[3]);
dwInfoFlags = NIIF_INFO;
break;
case CHAN_INVITE:
_snprintf(szInfo, 512, "%s has invited you into %s", word[1], word[2]);
_snprintf(szName, 64, "Invite");
dwInfoFlags = NIIF_INFO;
break;
case CHAN_KICKED:
_snprintf(szInfo, 512, "Kicked from %s by %s:\r\n%s", word[2], word[3], word[4]);
_snprintf(szName, 64, "Kick");
dwInfoFlags = NIIF_WARNING;
break;
case CHAN_BANNED:
_snprintf(szInfo, 512, "Cannot join %s You are banned.", word[1]);
_snprintf(szName, 64, "Banned");
dwInfoFlags = NIIF_WARNING;
break;
case CTCP_GENERIC:
_snprintf(szInfo, 512, "%s:\r\nCTCP %s", word[2], word[1]);
_snprintf(szName, 64, "CTCP");
dwInfoFlags = NIIF_INFO;
break;
case PMSG_RECEIVE:
_snprintf(szInfo, 512, "%s:\r\n%s", word[1], word[2]);
_snprintf(szName, 64, "Private Message");
dwInfoFlags = NIIF_INFO;
break;
case SERV_DISCONNECT:
_snprintf(szInfo, 512, "Disconnected\r\nError: %s", word[1]);
_snprintf(szName, 64, "Disconnect");
dwInfoFlags = NIIF_ERROR;
break;
case SERV_KILLED:
_snprintf(szInfo, 512, "Killed(%s(%s))", word[1], word[2]);
_snprintf(szName, 64, "Server Admin has killed you");
dwInfoFlags = NIIF_ERROR;
break;
case SERV_NOTICE:
_snprintf(szInfo, 512, "Notice:\r\n%s: %s", word[1], word[2]);
_snprintf(szName, 64, "Notice");
dwInfoFlags = NIIF_INFO;
break;
case 11:
_snprintf(szInfo, 512, ":\r\n%s: %s", word[1], word[2]);
_snprintf(szName, 64, "Notice");
dwInfoFlags = NIIF_INFO;
break;
}
/**************************************************************************************/
/***** Use windows instead of balloons, and if its a window should we keep it open ****/
/***** indefinitely? ****/
/**************************************************************************************/
szTemp = hexchat_strip_color(szInfo);
if(g_dwPrefs & (1<<PREF_UWIOB))
{
sdSystemAlert((HINSTANCE)g_hInstance, IDD_ALERT, szTemp, szName, iTime);
}
else
{
ShowBalloon(g_hXchatWnd, 1, szTemp, szName, iTime, dwInfoFlags);
}
free(szTemp);
}
if(g_dwPrefs & (1<<PREF_BLINK) && (g_dwPrefs & (1<<iEvent)))
{
BlinkIcon(g_hXchatWnd, 1, g_hIcons[0], g_hIcons[(iEvent+1)], 700, 5);
}
/***********************************/
/***** pass the events to HexChat **/
/***********************************/
return HEXCHAT_EAT_NONE;
}
int command_cb(char *word[], char *word_eol[], void *userdata)
{
char szInfo[512];
char *szTemp = NULL;
int iTime = g_iTime*1000;
_snprintf(szInfo, 512, word_eol[2]);
szTemp = hexchat_strip_color(szInfo);
if(g_dwPrefs & (1<<PREF_KAOI))
{
iTime = 0;
}
if(((g_iIsActive == 0) || !(g_dwPrefs & (1<<PREF_OSBWM))) && (g_dwPrefs & (1<<PREF_AMAE)))
{
if(g_dwPrefs & (1<<PREF_UWIOB))
{
sdSystemAlert((HINSTANCE)g_hInstance, IDD_ALERT, szTemp, "Alert", iTime);
}
else
{
ShowBalloon(g_hXchatWnd, 1, szTemp, "Alert", iTime, NIIF_INFO);
}
}
free(szTemp);
return HEXCHAT_EAT_ALL;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch(msg)
{
case WM_CLOSE:
{
if((g_dwPrefs & (1<<PREF_MIOC)) && (g_bCanQuit == false))
{
/*******************************************/
/**** to autoaway or not to autoaway... ***/
/*******************************************/
if(g_dwPrefs & (1<<PREF_AOM))
{
hexchat_globally_away(g_szAway);
}
/**************************************************/
/**** Win32 API call to hide the window and **/
/**** save the fact that its minimized for later **/
/**************************************************/
g_iIsActive = 0;
ShowWindow(hWnd, SW_HIDE);
return 0;
}
else
{
if(g_hPrefDlg != NULL)
{
DestroyWindow(g_hPrefDlg);
}
StopBlink(hWnd, 1, g_hIcons[0]);
if(sdAlertNum())
{
sdCloseAlerts();
HoldClose();
return 0;
}
}
}
break;
case WM_SIZE:
{
/******************************************/
/***** User wants to minimize HexChat, ****/
/***** are we allowed to go to tray? ******/
/******************************************/
if((g_dwPrefs & (1<<PREF_TOT)) && (wparam == SIZE_MINIMIZED))
{
/*******************************************/
/**** to autoaway or not to autoaway... ***/
/*******************************************/
if(g_dwPrefs & (1<<PREF_AOM))
{
hexchat_globally_away(g_szAway);
}
/**************************************************/
/**** Win32 API call to hide the window and **/
/**** save the fact that its minimized for later **/
/**************************************************/
g_iIsActive = 0;
ShowWindow(hWnd, SW_HIDE);
}
}
break;
/**********************************/
/*** user clicked the tray icon ***/
/**********************************/
case WM_TRAYMSG:
{
switch(lparam)
{
case WM_LBUTTONDOWN:
{
if(!g_iIsActive)
{
/*********************************************************/
/*** 0: its hiden, restore it and show it, if autoaway ***/
/*** is on, set us as back ***/
/*********************************************************/
SendMessage(hWnd, WM_SYSCOMMAND, SC_RESTORE, 0);
SetForegroundWindow(hWnd);
g_iIsActive = 1;
if(g_dwPrefs & (1<<PREF_AOM))
{
hexchat_globally_back();
}
}
else
{
SendMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
}
}
break;
case WM_RBUTTONDOWN:
{
/******************************************/
/*** user wants to see the menu find out **/
/*** where the mouse is and show it **/
/******************************************/
POINT pt;
int iRet;
GetCursorPos(&pt);
SetForegroundWindow(hWnd);
ModifyMenu(g_hTrayMenu, 2, (MF_POPUP | MF_BYPOSITION), (UINT)setServerMenu(), _T("Away"));
Sleep(175);
iRet = TrackPopupMenuEx(g_hTrayMenu, (TPM_RETURNCMD | TPM_LEFTALIGN), pt.x, pt.y, hWnd, NULL);
/***********************************/
/*** nRet is the users selection, **/
/*** process it **/
/***********************************/
sdTrayProc(hWnd, iRet);
}
break;
}
}
break;
default:
{
/*****************************************************/
/*** the taskbar has been restarted, re-add our icon */
/*****************************************************/
if(msg == RegisterWindowMessage(_T("TaskbarCreated")))
{
char szVersion[64];
_snprintf(szVersion, 64, "HexChat [%s]", hexchat_get_info(ph, "version"));
AddIcon(g_hXchatWnd, 1, g_hIcons[0], szVersion, (NIF_ICON | NIF_MESSAGE | NIF_TIP), WM_TRAYMSG);
}
}
break;
}
return CallWindowProc(g_hOldProc, hWnd, msg, wparam, lparam);
}
/****************************************************/
/*** process messages from the tray menu ************/
/****************************************************/
LRESULT CALLBACK sdTrayProc(HWND hWnd, int msg)
{
switch(msg)
{
case ACT_EXIT:
{
g_bCanQuit = true;
PostMessage(hWnd, WM_CLOSE, 0, 0);
}
break;
case ACT_RESTORE:
{
/*************************************************/
/** user wants us to restore the HexChat window **/
/** and of autoaway is on, set as back ******** **/
/*************************************************/
SendMessage(g_hXchatWnd, WM_SYSCOMMAND, SC_RESTORE, 0);
SetForegroundWindow(hWnd);
if((!g_iIsActive) && (g_dwPrefs & (1<<PREF_AOM)))
{
hexchat_globally_back();
g_iIsActive = 1;
}
}
break;
case ACT_SETTINGS:
{
ShowWindow(g_hPrefDlg, SW_SHOW);
}
break;
case ACT_AWAY:
{
hexchat_globally_away(g_szAway);
}
break;
case ACT_BACK:
{
hexchat_globally_back();
}
break;
default:
{
if(msg > 0)
{
hexchat_set_context(ph, hexchat_find_server(msg-1));
if(!hexchat_get_info(ph, "away"))
{
hexchat_away(g_szAway);
}
else
{
hexchat_back();
}
}
}
break;
}
return 1;
}
int CALLBACK PrefProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch(msg)
{
case WM_INITDIALOG:
{
TCITEM tci1;
TCITEM tci2;
TCITEM tci3;
TCITEM tci4;
tci1.mask = TCIF_TEXT;
tci1.pszText = _T("Settings");
tci1.cchTextMax = strlen("Settings");
SendDlgItemMessage(hWnd, IDC_TAB_CONTROL, TCM_INSERTITEM, 0, (LPARAM)&tci1);
tci2.mask = TCIF_TEXT;
tci2.pszText = _T("Alerts");
tci2.cchTextMax = strlen("Alerts");
SendDlgItemMessage(hWnd, IDC_TAB_CONTROL, TCM_INSERTITEM, 1, (LPARAM)&tci2);
tci3.mask = TCIF_TEXT;
tci3.pszText = _T("Events");
tci3.cchTextMax = strlen("Events");
SendDlgItemMessage(hWnd, IDC_TAB_CONTROL, TCM_INSERTITEM, 2, (LPARAM)&tci3);
tci4.mask = TCIF_TEXT;
tci4.pszText = _T("About");
tci4.cchTextMax = strlen("About");
SendDlgItemMessage(hWnd, IDC_TAB_CONTROL, TCM_INSERTITEM, 3, (LPARAM)&tci4);
/***********************************************************************************/
/***********************************************************************************/
/***********************************************************************************/
g_hPrefTabSettings = CreateDialog((HINSTANCE)g_hInstance,
MAKEINTRESOURCE(IDD_SETTINGS),
hWnd,
(DLGPROC)SettingsProc);
SetDialog(g_hPrefTabSettings, IDD_SETTINGS);
g_hPrefTabAlerts = CreateDialog((HINSTANCE)g_hInstance,
MAKEINTRESOURCE(IDD_ALERTS),
hWnd,
(DLGPROC)AlertsProc);
SetDialog(g_hPrefTabAlerts, IDD_ALERTS);
g_hPrefTabEvents = CreateDialog((HINSTANCE)g_hInstance,
MAKEINTRESOURCE(IDD_EVENTS),
hWnd,
(DLGPROC)EventsProc);
SetDialog(g_hPrefTabEvents, IDD_EVENTS);
g_hPrefTabAbout = CreateDialog((HINSTANCE)g_hInstance,
MAKEINTRESOURCE(IDD_ABOUT),
hWnd,
(DLGPROC)AboutProc);
}
break;
case WM_SHOWWINDOW:
{
if(wparam)
{
SendDlgItemMessage(hWnd, IDC_TAB_CONTROL, TCM_SETCURSEL, 0, 0);
ShowWindow(g_hPrefTabSettings, SW_SHOW);
ShowWindow(g_hPrefTabAlerts, SW_HIDE);
ShowWindow(g_hPrefTabEvents, SW_HIDE);
ShowWindow(g_hPrefTabAbout, SW_HIDE);
}
}
break;
case WM_NOTIFY:
{
NMHDR *pData = (NMHDR *)lparam;
switch(pData->code)
{
case TCN_SELCHANGE:
{
switch(SendDlgItemMessage(hWnd, IDC_TAB_CONTROL, TCM_GETCURSEL, 0, 0))
{
case 0:
{
ShowWindow(g_hPrefTabSettings, SW_SHOW);
ShowWindow(g_hPrefTabAlerts, SW_HIDE);
ShowWindow(g_hPrefTabEvents, SW_HIDE);
ShowWindow(g_hPrefTabAbout, SW_HIDE);
}
break;
case 1:
{
ShowWindow(g_hPrefTabSettings, SW_HIDE);
ShowWindow(g_hPrefTabAlerts, SW_SHOW);
ShowWindow(g_hPrefTabEvents, SW_HIDE);
ShowWindow(g_hPrefTabAbout, SW_HIDE);
}
break;
case 2:
{
ShowWindow(g_hPrefTabSettings, SW_HIDE);
ShowWindow(g_hPrefTabAlerts, SW_HIDE);
ShowWindow(g_hPrefTabEvents, SW_SHOW);
ShowWindow(g_hPrefTabAbout, SW_HIDE);
}
break;
case 3:
{
ShowWindow(g_hPrefTabSettings, SW_HIDE);
ShowWindow(g_hPrefTabAlerts, SW_HIDE);
ShowWindow(g_hPrefTabEvents, SW_HIDE);
ShowWindow(g_hPrefTabAbout, SW_SHOW);
}
break;
}
}
break;
}
}
break;
case WM_CLOSE:
{
ShowWindow(g_hPrefTabEvents, SW_HIDE);
ShowWindow(g_hPrefTabSettings, SW_HIDE);
ShowWindow(g_hPrefTabAlerts, SW_HIDE);
ShowWindow(g_hPrefTabAbout, SW_HIDE);
ShowWindow(hWnd, SW_HIDE);
return TRUE;
}
break;
case WM_COMMAND:
{
switch(wparam)
{
case IDC_PREF_OK:
{
CheckPrefs(g_hPrefTabEvents, IDD_EVENTS);
CheckPrefs(g_hPrefTabSettings, IDD_SETTINGS);
CheckPrefs(g_hPrefTabAlerts, IDD_ALERTS);
SavePrefs(0);
ShowWindow(g_hPrefTabEvents, SW_HIDE);
ShowWindow(g_hPrefTabSettings, SW_HIDE);
ShowWindow(g_hPrefTabAlerts, SW_HIDE);
ShowWindow(g_hPrefTabAbout, SW_HIDE);
ShowWindow(hWnd, SW_HIDE);
return TRUE;
}
break;
case IDC_PREF_CANCEL:
{
ShowWindow(g_hPrefTabEvents, SW_HIDE);
ShowWindow(g_hPrefTabSettings, SW_HIDE);
ShowWindow(g_hPrefTabAlerts, SW_HIDE);
ShowWindow(g_hPrefTabAbout, SW_HIDE);
ShowWindow(hWnd, SW_HIDE);
return TRUE;
}
break;
case IDC_PREF_APPLY:
{
CheckPrefs(g_hPrefTabEvents, IDD_EVENTS);
CheckPrefs(g_hPrefTabSettings, IDD_SETTINGS);
CheckPrefs(g_hPrefTabAlerts, IDD_ALERTS);
SavePrefs(0);
return FALSE;
}
break;
}
}
break;
case WM_DESTROY:
{
SendMessage(g_hPrefTabEvents, WM_CLOSE, 0, 0);
SendMessage(g_hPrefTabSettings, WM_CLOSE, 0, 0);
SendMessage(g_hPrefTabAbout, WM_CLOSE, 0, 0);
SendMessage(g_hPrefTabAlerts, WM_CLOSE, 0, 0);
}
break;
}
return FALSE;
}
/****************************************************/
/****************************************************/
/****************************************************/
LRESULT CALLBACK AlertsProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch(msg)
{
case WM_CLOSE:
{
DestroyWindow(hWnd);
return TRUE;
break;
}
break;
case WM_COMMAND:
{
switch(LOWORD(wparam))
{
case PREF_AMAE:
{
SetToggle(hWnd, PREF_OSBWM, PREF_AMAE, TRUE);
SetToggle(hWnd, PREF_UWIOB, PREF_AMAE, TRUE);
SetToggle(hWnd, PREF_KAOI, PREF_AMAE, TRUE);
if(IsDlgButtonChecked(hWnd, PREF_AMAE))
{
SetToggle(hWnd, IDC_ALERT_HOTKEY, PREF_UWIOB, TRUE);
SetToggle(hWnd, IDC_ALERT_HOTKEY_TEXT, PREF_UWIOB, TRUE);
SetToggle(hWnd, IDC_ALERT_TIME, PREF_KAOI, FALSE);
SetToggle(hWnd, IDC_ALERT_TIME_TEXT, PREF_KAOI, FALSE);
}
else
{
SetToggle(hWnd, IDC_ALERT_HOTKEY, PREF_AMAE, TRUE);
SetToggle(hWnd, IDC_ALERT_HOTKEY_TEXT, PREF_AMAE, TRUE);
SetToggle(hWnd, IDC_ALERT_TIME, PREF_AMAE, TRUE);
SetToggle(hWnd, IDC_ALERT_TIME_TEXT, PREF_AMAE, TRUE);
}
}
break;
case PREF_UWIOB:
{
SetToggle(hWnd, IDC_ALERT_HOTKEY, PREF_UWIOB, TRUE);
SetToggle(hWnd, IDC_ALERT_HOTKEY_TEXT, PREF_UWIOB, TRUE);
}
break;
case PREF_KAOI:
{
SetToggle(hWnd, IDC_ALERT_TIME, PREF_KAOI, FALSE);
SetToggle(hWnd, IDC_ALERT_TIME_TEXT, PREF_KAOI, FALSE);
}
break;
}
break;
}
}
return FALSE;
}
/****************************************************/
/****************************************************/
/****************************************************/
LRESULT CALLBACK AboutProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
if(msg == WM_CLOSE)
{
DestroyWindow(hWnd);
return true;
}
return FALSE;
}
/*****************************************************/
/** Process the events for our event dialog **********/
/*****************************************************/
LRESULT CALLBACK EventsProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
if(msg == WM_CLOSE)
{
DestroyWindow(hWnd);
return true;
}
return FALSE;
}
/*****************************************************/
/** Process the events for our settings dialog this **/
/** is alot more complicated because options are **/
/** enabled/disabled based on the state of others **/
/*****************************************************/
LRESULT CALLBACK SettingsProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
if(msg == WM_CLOSE)
{
DestroyWindow(hWnd);
return true;
}
return FALSE;
}
/*****************************************************/
/** this is the hotkey message processing function **/
/** this window is always open and ready to be told **/
/** if someone has hit the hotkey, if they did, we **/
/** need to close out all of the tray alerts, for **/
/** this I wrote sdCloseAlerts, more info there **/
/*****************************************************/
LRESULT CALLBACK HotKeyProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
if(msg == WM_CLOSE)
{
DestroyWindow(hWnd);
return true;
}
else if(msg == WM_HOTKEY)
{
sdCloseAlerts();
}
return FALSE;
}

View File

@ -0,0 +1,37 @@
/* X-Tray
* Copyright (C) 2005 Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>
*
* X-Tray 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.
*
* X-Tray 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 X-Tray; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _H_CALLBACKS_H
#define _H_CALLBACKS_H
int event_cb (char *word[], void *userdata);
int command_cb (char *word[], char *word_eol[], void *userdata);
LRESULT CALLBACK WindowProc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
BOOL CALLBACK EnumWindowsProc (HWND hWnd, LPARAM lParam);
LRESULT CALLBACK sdTrayProc (HWND hwnd, int msg);
LRESULT CALLBACK AlertProc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
LRESULT CALLBACK HotKeyProc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
LRESULT CALLBACK EventsProc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
LRESULT CALLBACK AboutProc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
LRESULT CALLBACK AlertsProc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
LRESULT CALLBACK SettingsProc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
int CALLBACK PrefProc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
#endif

320
plugins/hextray/hexchat.cpp Normal file
View File

@ -0,0 +1,320 @@
/* X-Tray
* Copyright (C) 1998, 2005 Peter Zelezny, Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>
*
* X-Tray 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.
*
* X-Tray 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 X-Tray; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <windows.h>
#include <vector>
#include <algorithm>
#include <stdio.h>
#include <tchar.h>
#include "hexchat-plugin.h"
#include "hextray.h"
#include "resource.h"
#include "hexchat.h"
#include "utility.h"
// from util.c of HexChat source code ( slightly modified to fit HexTray Syntax )
char *hexchat_strip_color (char *text)
{
int nc = 0;
int i = 0;
int col = 0;
int len = strlen(text);
char *new_str = (char *)malloc(len + 2);
while (len > 0)
{
if ((col && isdigit(*text) && (nc < 2)) || (col && isdigit(*(text+1)) && (nc < 3) && (*text == ',')))
{
nc++;
if(*text == ',')
{
nc = 0;
}
}
else
{
col = 0;
switch (*text)
{
case '\003': /*ATTR_COLOR: */
{
col = 1;
nc = 0;
}
break;
case '\007': /*ATTR_BEEP: */
case '\017': /*ATTR_RESET: */
case '\026': /*ATTR_REVERSE: */
case '\002': /*ATTR_BOLD: */
case '\037': /*ATTR_UNDERLINE: */
break;
default:
{
new_str[i] = *text;
i++;
}
break;
}
}
text++;
len--;
}
new_str[i] = 0;
return new_str;
}
void check_special_chars (char *cmd)
{
int occur = 0;
int len = strlen (cmd);
int i = 0, j = 0;
char *buf;
if (!len)
return;
buf = (char *)malloc (len + 1);
if (buf)
{
while (cmd[j])
{
switch (cmd[j])
{
case '%':
{
occur++;
switch (cmd[j + 1])
{
case 'R':
buf[i] = '\026';
break;
case 'U':
buf[i] = '\037';
break;
case 'B':
buf[i] = '\002';
break;
case 'C':
buf[i] = '\003';
break;
case 'O':
buf[i] = '\017';
break;
case '%':
buf[i] = '%';
break;
default:
buf[i] = '%';
j--;
break;
}
j++;
}
break;
default:
{
buf[i] = cmd[j];
}
break;
}
j++;
i++;
}
buf[i] = 0;
if (occur)
strcpy (cmd, buf);
free (buf);
}
}
void hexchat_globally_away(TCHAR *tszAway)
{
char szTemp[512];
char szAway[512];
ConvertString(tszAway, szAway, 512);
_snprintf(szTemp, 512, "ALLSERV AWAY %s\0", szAway);
check_special_chars(szTemp);
hexchat_exec(szTemp);
}
void hexchat_away(TCHAR *tszAway)
{
char szTemp[512];
char szAway[512];
ConvertString(tszAway, szAway, 512);
_snprintf(szTemp, 512, szAway);
check_special_chars(szTemp);
hexchat_commandf(ph, "AWAY %s\0", szTemp);
}
void hexchat_globally_back()
{
std::vector<int> xs;
std::vector<int>::iterator xsi;
hexchat_list *xl = hexchat_list_get(ph, "channels");
if(xl)
{
while(hexchat_list_next(ph, xl))
{
xsi = std::find(xs.begin(), xs.end(), hexchat_list_int(ph, xl, "id"));
if((xsi == xs.end()) &&
((strlen(hexchat_list_str(ph, xl, "server")) > 0) ||
(strlen(hexchat_list_str(ph, xl, "channel")) > 0)))
{
xs.push_back(hexchat_list_int(ph, xl, "id"));
hexchat_set_context(ph, (hexchat_context *)hexchat_list_str(ph, xl, "context"));
hexchat_back();
}
}
hexchat_list_free(ph, xl);
}
}
void hexchat_back()
{
if(hexchat_get_info(ph, "away"))
{
hexchat_command(ph, "BACK");
}
}
HMENU setServerMenu()
{
HMENU sTemp = CreateMenu();
TCHAR wszServer[128];
TCHAR wszNick[128];
TCHAR wszMenuEntry[256];
std::vector<int> xs;
std::vector<int>::iterator xsi;
hexchat_list *xl = hexchat_list_get(ph, "channels");
AppendMenu(sTemp, MF_STRING, ACT_AWAY, _T("Set Globally Away"));
AppendMenu(sTemp, MF_STRING, ACT_BACK, _T("Set Globally Back"));
AppendMenu(sTemp, MF_SEPARATOR, 0, NULL);
if(xl)
{
while(hexchat_list_next(ph, xl))
{
xsi = std::find(xs.begin(), xs.end(), hexchat_list_int(ph, xl, "id"));
if( (xsi == xs.end()) &&
((strlen(hexchat_list_str(ph, xl, "server")) > 0) ||
(strlen(hexchat_list_str(ph, xl, "channel")) > 0)))
{
hexchat_set_context(ph, (hexchat_context *)hexchat_list_str(ph, xl, "context"));
xs.push_back(hexchat_list_int(ph, xl, "id"));
char *network = _strdup(hexchat_list_str(ph, xl, "network"));
char *server = _strdup(hexchat_list_str(ph, xl, "server"));
char *nick = _strdup(hexchat_get_info(ph, "nick"));
if(network != NULL)
{
ConvertString(network, wszServer, 128);
}
else
{
ConvertString(server, wszServer, 128);
}
if(server != NULL)
{
ConvertString(nick, wszNick, 128);
_sntprintf(wszMenuEntry, 256, _T("%s @ %s\0"), wszNick, wszServer);
if(!hexchat_get_info(ph, "away"))
{
AppendMenu(sTemp, MF_STRING, (hexchat_list_int(ph, xl, "id") + 1), wszMenuEntry);
}
else
{
AppendMenu(sTemp, (MF_CHECKED | MF_STRING), (hexchat_list_int(ph, xl, "id") + 1), wszMenuEntry);
}
}
free(network);
free(server);
free(nick);
}
}
hexchat_list_free(ph, xl);
}
return sTemp;
}
struct _hexchat_context *hexchat_find_server(int find_id)
{
hexchat_context *xc;
hexchat_list *xl = hexchat_list_get(ph, "channels");
int id;
if(!xl)
return NULL;
while(hexchat_list_next(ph, xl))
{
id = hexchat_list_int(ph, xl, "id");
if(id == -1)
{
return NULL;
}
else if(id == find_id)
{
xc = (hexchat_context *)hexchat_list_str(ph, xl, "context");
hexchat_list_free(ph, xl);
return xc;
}
}
hexchat_list_free(ph, xl);
return NULL;
}
void hexchat_exec(char *command)
{
hexchat_set_context(ph, hexchat_find_context(ph, NULL, NULL));
hexchat_command(ph, command);
}

32
plugins/hextray/hexchat.h Normal file
View File

@ -0,0 +1,32 @@
/* X-Tray
* Copyright (C) 2005 Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>
*
* X-Tray 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.
*
* X-Tray 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 X-Tray; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _H_XCHAT_H
#define _H_XCHAT_H
void hexchat_exec (char *);
char *hexchat_strip_color (char *);
void hexchat_parse (char *);
struct _hexchat_context *hexchat_find_server (int);
void hexchat_globally_away (TCHAR *);
void hexchat_away (TCHAR *);
void hexchat_globally_back ();
void hexchat_back ();
HMENU setServerMenu ();
#endif

246
plugins/hextray/hextray.cpp Normal file
View File

@ -0,0 +1,246 @@
/* X-Tray
* Copyright (C) 2005 Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>
*
* X-Tray 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.
*
* X-Tray 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 X-Tray; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define _WIN32_IE 0x0601
#include <windows.h>
#include <list>
#include <string>
#include <shobjidl.h>
#include "hexchat-plugin.h"
#include "resource.h"
#include "callbacks.h"
#include "utility.h"
#include "hextray.h"
#include "sdTray.h"
#include "sdAlerts.h"
/*****************************************************/
/**** Don't want to pollute the namespace do we? *****/
/*****************************************************/
std::list<hexchat_hook *> g_vHooks;
/*****************************************************/
/************ Global Identifiers *********************/
/*****************************************************/
WNDPROC g_hOldProc;
hexchat_plugin *ph;
/*****************************************************/
/***************** Resources *************************/
/*****************************************************/
HWND g_hXchatWnd;
HWND g_hHotkeyWnd;
HWND g_hPrefDlg;
HMENU g_hTrayMenu;
HICON g_hIcons[24];
HANDLE g_hInstance;
/*****************************************************/
/***************** Preferences ***********************/
/*****************************************************/
unsigned int g_dwPrefs;
TCHAR g_szAway[512];
int g_iTime;
BOOL WINAPI DllMain(HANDLE hModule, DWORD fdwReason, LPVOID lpVoid)
{
if((fdwReason == DLL_PROCESS_ATTACH) || (fdwReason == DLL_THREAD_ATTACH))
{
g_hInstance = hModule;
}
return TRUE;
}
int hexchat_plugin_init(hexchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg)
{
ph = plugin_handle;
*plugin_name = "HexTray";
*plugin_desc = "Minimize HexChat to the Windows system tray";
*plugin_version = "1.3.0";
char buffer[256];
/***************************************************************************************************************************/
/************************* Initialize our preferences if they don't exist yet **********************************************/
/***************************************************************************************************************************/
if (hexchat_pluginpref_get_int (ph, "settings") == -1)
{
hexchat_pluginpref_set_int (ph, "settings", HT_DEF_SET);
}
if (hexchat_pluginpref_get_int (ph, "aot") == -1)
{
hexchat_pluginpref_set_int (ph, "aot", HT_DEF_AOT);
}
if (hexchat_pluginpref_get_int (ph, "key") == -1)
{
hexchat_pluginpref_set_int (ph, "key", HT_DEF_KEY);
}
if (hexchat_pluginpref_get_int (ph, "mod") == -1)
{
hexchat_pluginpref_set_int (ph, "mod", HT_DEF_MOD);
}
if (hexchat_pluginpref_get_str (ph, "away", buffer) == 0)
{
hexchat_pluginpref_set_str (ph, "away", "");
}
/***************************************************************************************************************************/
/************************* Load our preferences ****************************************************************************/
/***************************************************************************************************************************/
LoadPrefs();
/***************************************************************************************************************************/
/************************* Finds the HexChat window and saves it for later use *********************************************/
/***************************************************************************************************************************/
g_hXchatWnd = (HWND)hexchat_get_info(ph, "win_ptr");
if(g_hXchatWnd == NULL)
{
EnumThreadWindows(GetCurrentThreadId(), EnumWindowsProc, 0);
}
g_hOldProc = (WNDPROC)GetWindowLongPtr(g_hXchatWnd, GWLP_WNDPROC);
SetWindowLongPtr(g_hXchatWnd, GWLP_WNDPROC, (LONG_PTR)WindowProc);
/***************************************************************************************************************************/
/************************* Grab the HexChat Icon, Load our menu, create the window to receive the hotkey messages *********/
/************************* and register the windows message so we know if explorer crashes ***********/
/***************************************************************************************************************************/
g_hTrayMenu = GetSubMenu(LoadMenu((HINSTANCE)g_hInstance, MAKEINTRESOURCE(IDR_TRAY_MENU)), 0);
g_hHotkeyWnd = CreateDialog((HINSTANCE)g_hInstance, MAKEINTRESOURCE(IDD_ALERT), NULL, (DLGPROC)HotKeyProc);
g_hPrefDlg = CreateDialog((HINSTANCE)g_hInstance, MAKEINTRESOURCE(IDD_PREF), g_hXchatWnd, (DLGPROC)PrefProc);
g_hIcons[0] = (HICON)LoadImage((HINSTANCE)g_hInstance, MAKEINTRESOURCE(ICO_XCHAT), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
g_hIcons[2] = (HICON)LoadImage((HINSTANCE)g_hInstance, MAKEINTRESOURCE(ICO_HIGHLIGHT), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
g_hIcons[5] = (HICON)LoadImage((HINSTANCE)g_hInstance, MAKEINTRESOURCE(ICO_BANNED), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
g_hIcons[6] = (HICON)LoadImage((HINSTANCE)g_hInstance, MAKEINTRESOURCE(ICO_KICKED), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
g_hIcons[8] = (HICON)LoadImage((HINSTANCE)g_hInstance, MAKEINTRESOURCE(ICO_PMSG), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
g_hIcons[10]= (HICON)LoadImage((HINSTANCE)g_hInstance, MAKEINTRESOURCE(ICO_SNOTICE), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
g_hIcons[11]= (HICON)LoadImage((HINSTANCE)g_hInstance, MAKEINTRESOURCE(ICO_DISCONNECTED), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
g_hIcons[22] = (HICON)LoadImage((HINSTANCE)g_hInstance, MAKEINTRESOURCE(ICO_CHANMSG), IMAGE_ICON, 16, 16, LR_DEFAULTCOLOR);
/***************************************************************************************************************************/
/************************* Add our icon to the tray ************************************************************************/
/***************************************************************************************************************************/
char szVersion[64];
_snprintf(szVersion, 64, "HexChat %s", hexchat_get_info(ph, "version"));
AddIcon(g_hXchatWnd, 1, g_hIcons[0], szVersion, (NIF_ICON | NIF_MESSAGE | NIF_TIP), WM_TRAYMSG);
/***************************************************************************************************************************/
/***************************************************************************************************************************/
/***************************************************************************************************************************/
if(g_dwPrefs & (1<<PREF_DNSIT))
{
DWORD dwStyle;
dwStyle = GetWindowLong(g_hXchatWnd, GWL_STYLE);
dwStyle |= (1<<WS_CHILD);
SetWindowLongPtr(g_hXchatWnd, GWL_STYLE, (LONG_PTR)dwStyle);
SetWindowLongPtr(g_hXchatWnd, GWL_HWNDPARENT, (LONG_PTR)g_hHotkeyWnd);
}
/***************************************************************************************************************************/
/************************* Set our hooks and save them for later so we can unhook them *************************************/
/***************************************************************************************************************************/
g_vHooks.push_back(hexchat_hook_print(ph, "Channel Msg Hilight", HEXCHAT_PRI_NORM, event_cb, (void *)CHAN_HILIGHT));
g_vHooks.push_back(hexchat_hook_print(ph, "Channel Message", HEXCHAT_PRI_NORM, event_cb, (void *)CHAN_MESSAGE));
g_vHooks.push_back(hexchat_hook_print(ph, "Topic Change", HEXCHAT_PRI_NORM, event_cb, (void *)CHAN_TOPIC_CHANGE));
g_vHooks.push_back(hexchat_hook_print(ph, "Channel Action Hilight", HEXCHAT_PRI_NORM, event_cb, (void *)CHAN_HILIGHT));
g_vHooks.push_back(hexchat_hook_print(ph, "Channel INVITE", HEXCHAT_PRI_NORM, event_cb, (void *)CHAN_INVITE));
g_vHooks.push_back(hexchat_hook_print(ph, "You Kicked", HEXCHAT_PRI_NORM, event_cb, (void *)CHAN_KICKED));
g_vHooks.push_back(hexchat_hook_print(ph, "Banned", HEXCHAT_PRI_NORM, event_cb, (void *)CHAN_BANNED));
g_vHooks.push_back(hexchat_hook_print(ph, "CTCP Generic", HEXCHAT_PRI_NORM, event_cb, (void *)CTCP_GENERIC));
g_vHooks.push_back(hexchat_hook_print(ph, "Private Message", HEXCHAT_PRI_NORM, event_cb, (void *)PMSG_RECEIVE));
g_vHooks.push_back(hexchat_hook_print(ph, "Private Message to Dialog", HEXCHAT_PRI_NORM, event_cb, (void *)PMSG_RECEIVE));
g_vHooks.push_back(hexchat_hook_print(ph, "Disconnected", HEXCHAT_PRI_NORM, event_cb, (void *)SERV_DISCONNECT));
g_vHooks.push_back(hexchat_hook_print(ph, "Killed", HEXCHAT_PRI_NORM, event_cb, (void *)SERV_KILLED));
g_vHooks.push_back(hexchat_hook_print(ph, "Notice", HEXCHAT_PRI_NORM, event_cb, (void *)SERV_NOTICE));
g_vHooks.push_back(hexchat_hook_command(ph, "tray_alert", HEXCHAT_PRI_NORM, command_cb, "Create an Alert", NULL));
return 1;
}
int hexchat_plugin_deinit(hexchat_plugin *plugin_handle)
{
/******************************************/
/****** Remove the Icon from the tray *****/
/******************************************/
StopBlink(g_hXchatWnd, 1, g_hIcons[0]);
RemoveIcon(g_hXchatWnd, 1);
/*******************************************/
/*******************************************/
/*******************************************/
if(g_dwPrefs & (1<<PREF_DNSIT))
{
DWORD dwStyle;
dwStyle = GetWindowLong(g_hXchatWnd, GWL_STYLE);
dwStyle &= ~(1<<WS_CHILD);
SetWindowLongPtr(g_hXchatWnd, GWL_STYLE, (LONG_PTR)dwStyle);
SetWindowLongPtr(g_hXchatWnd, GWL_HWNDPARENT, NULL);
}
/******************************************/
/****** Unload our resources **************/
/******************************************/
DestroyMenu(g_hTrayMenu);
for(int i = 0; i <= 11; i++)
{
DestroyIcon(g_hIcons[i]);
}
/******************************************/
/****** Remove our window hook ************/
/******************************************/
SetWindowLongPtr(g_hXchatWnd, GWLP_WNDPROC, (LONG_PTR)g_hOldProc);
/******************************************/
/****** Remove our hotkey, and destroy ****/
/****** the window that receives its ****/
/****** messages ****/
/******************************************/
UnregisterHotKey(g_hHotkeyWnd, 1);
DestroyWindow(g_hHotkeyWnd);
DestroyWindow(g_hPrefDlg);
/******************************************/
/************* Clean up Isle 7 ************/
/******************************************/
if(sdAlertNum())
{
sdCloseAlerts();
}
/******************************************/
/****** remove our hexchat_hook_*s **********/
/******************************************/
while(!g_vHooks.empty())
{
if(g_vHooks.back() != NULL)
{
hexchat_unhook(ph, g_vHooks.back());
}
g_vHooks.pop_back();
}
return 1;
}

View File

@ -0,0 +1,3 @@
EXPORTS
hexchat_plugin_init
hexchat_plugin_deinit

83
plugins/hextray/hextray.h Normal file
View File

@ -0,0 +1,83 @@
/* X-Tray
* Copyright (C) 2005 Michael Hotaling <Mike.Hotaling@SinisterDevelopments.com>
*
* X-Tray 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.
*
* X-Tray 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 X-Tray; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef _XTRAY_H
#define _XTRAY_H
/******************** Default settings*****************/
#define HT_DEF_SET 13814
#define HT_DEF_AOT 5
#define HT_DEF_KEY 84
#define HT_DEF_MOD 6
/******************** Globals *************************/
extern HWND g_hXchatWnd;
extern HWND g_hHotkeyWnd;
extern HWND g_hPrefDlg;
extern HMENU g_hTrayMenu;
extern HICON g_hIcons[24];
extern HANDLE g_hInstance;
extern unsigned int g_dwPrefs;
extern TCHAR g_szAway[512];
extern int g_iTime;
extern WNDPROC g_hOldProc;
extern struct _hexchat_plugin *ph;
/******************************************************/
/******************** Messages ************************/
#define WM_TRAYMSG WM_APP
/******************************************************/
/********************* Events *************************/
#define CHAN_HILIGHT 1
#define CHAN_INVITE 2
#define CHAN_TOPIC_CHANGE 3
#define CHAN_BANNED 4
#define CHAN_KICKED 5
#define CTCP_GENERIC 6
#define PMSG_RECEIVE 7
#define SERV_KILLED 8
#define SERV_NOTICE 9
#define SERV_DISCONNECT 10
/* new events */
#define CHAN_MESSAGE 21
#define PREF_AOM 11 // away on minimize
#define PREF_TOT 12 // Tray on Taskbar
#define PREF_AMAE 13 // alert me about events
#define PREF_OSBWM 14 // Only Show Balloon When Minimized
#define PREF_UWIOB 15 // Use Window Instead of Balloon
#define PREF_KAOI 16 // Keep alerts open indefinitely
#define PREF_MIOC 17 // Minimize instead of close
#define PREF_BLINK 18 // blink icon
#define PREF_CICO 19 // change icon - not implemented
#define PREF_DNSIT 20 // Do not show in taskbar
/******************************************************/
#endif
#ifdef _WIN64
/* use replacement with the same value, and use SetWindowLongPtr instead
of SetWindowLong. more info:
http://msdn.microsoft.com/en-us/library/ms633591.aspx
http://msdn.microsoft.com/en-us/library/ms644898.aspx */
#define GWL_HWNDPARENT GWLP_HWNDPARENT
#endif

View File

@ -0,0 +1,131 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration">
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{3024CF36-85E5-4E00-9608-7002E2C7EF14}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>hextray</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\win32\hexchat.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\win32\hexchat.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(HexChatBin)</OutDir>
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
<TargetName>hchextray</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(HexChatBin)</OutDir>
<IntDir>$(HexChatObj)$(ProjectName)\</IntDir>
<TargetName>hchextray</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;XTRAY_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>hextray.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;XTRAY_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>hextray.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="bitmaps\sd.bmp" />
<None Include="icons\ban.ico" />
<None Include="icons\disconnect.ico" />
<None Include="icons\highlight.ico" />
<None Include="icons\kick.ico" />
<None Include="icons\message.ico" />
<None Include="icons\sd.ico" />
<None Include="icons\notice.ico" />
<None Include="icons\hexchat.ico" />
<None Include="hextray.def" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="callbacks.cpp" />
<ClCompile Include="sdAlerts.cpp" />
<ClCompile Include="sdTray.cpp" />
<ClCompile Include="utility.cpp" />
<ClCompile Include="hexchat.cpp" />
<ClCompile Include="hextray.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="callbacks.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="sdAlerts.h" />
<ClInclude Include="sdTray.h" />
<ClInclude Include="utility.h" />
<ClInclude Include="hexchat.h" />
<ClInclude Include="hextray.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Resource Files\bitmaps">
<UniqueIdentifier>{448b49a5-e68b-451e-bfbc-0855da024b2e}</UniqueIdentifier>
</Filter>
<Filter Include="Resource Files\icons">
<UniqueIdentifier>{8345128a-0635-43d6-9115-a85ad9c77ee2}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="hextray.def">
<Filter>Resource Files</Filter>
</None>
<None Include="bitmaps\sd.bmp">
<Filter>Resource Files\bitmaps</Filter>
</None>
<None Include="icons\ban.ico">
<Filter>Resource Files\icons</Filter>
</None>
<None Include="icons\disconnect.ico">
<Filter>Resource Files\icons</Filter>
</None>
<None Include="icons\highlight.ico">
<Filter>Resource Files\icons</Filter>
</None>
<None Include="icons\kick.ico">
<Filter>Resource Files\icons</Filter>
</None>
<None Include="icons\message.ico">
<Filter>Resource Files\icons</Filter>
</None>
<None Include="icons\sd.ico">
<Filter>Resource Files\icons</Filter>
</None>
<None Include="icons\notice.ico">
<Filter>Resource Files\icons</Filter>
</None>
<None Include="icons\hexchat.ico">
<Filter>Resource Files\icons</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="resource.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<ClCompile Include="callbacks.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="sdAlerts.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="sdTray.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="utility.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="hexchat.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="hextray.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="callbacks.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="sdAlerts.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="sdTray.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="utility.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="hexchat.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="hextray.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Some files were not shown because too many files have changed in this diff Show More