Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ca2b4d498c | ||
![]() |
085d9c368c |
@ -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
|
17
.github/workflows/flatpak-build.yml
vendored
@ -1,17 +0,0 @@
|
||||
name: Flatpak Build
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
flatpak_build:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: bilelmoussaoui/flatpak-github-actions:gnome-40
|
||||
options: --privileged
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- uses: bilelmoussaoui/flatpak-github-actions/flatpak-builder@v3
|
||||
with:
|
||||
bundle: hexchat.flatpak
|
||||
manifest-path: flatpak/io.github.Hexchat.json
|
41
.github/workflows/msys-build.yml
vendored
@ -1,41 +0,0 @@
|
||||
name: MSYS2 Build
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
msys2_build:
|
||||
runs-on: windows-latest
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
install: >-
|
||||
mingw-w64-x86_64-gcc
|
||||
mingw-w64-x86_64-pkg-config
|
||||
mingw-w64-x86_64-python3-cffi
|
||||
mingw-w64-x86_64-meson
|
||||
mingw-w64-x86_64-gtk2
|
||||
mingw-w64-x86_64-gtk-update-icon-cache
|
||||
mingw-w64-x86_64-luajit
|
||||
mingw-w64-x86_64-desktop-file-utils
|
||||
|
||||
- name: Configure
|
||||
run: >-
|
||||
meson build
|
||||
-Dtext-frontend=true
|
||||
-Ddbus=disabled
|
||||
-Dwith-upd=false
|
||||
-Dwith-perl=false
|
||||
|
||||
- name: Build
|
||||
run: ninja -C build
|
||||
|
||||
- name: Test
|
||||
run: ninja -C build test
|
||||
|
||||
- name: Install
|
||||
run: ninja -C build install
|
25
.github/workflows/ubuntu-build.yml
vendored
@ -1,25 +0,0 @@
|
||||
name: Ubuntu Build
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
ubuntu_build:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y meson libcanberra-dev libdbus-glib-1-dev libglib2.0-dev libgtk2.0-dev libluajit-5.1-dev libpci-dev libperl-dev libssl-dev python3-dev python3-cffi mono-devel desktop-file-utils
|
||||
|
||||
- name: Configure
|
||||
run: meson build -Dtext=true -Dtheme-manager=true -Dauto_features=enabled
|
||||
|
||||
- name: Build
|
||||
run: ninja -C build
|
||||
|
||||
- name: Test
|
||||
run: ninja -C build test
|
||||
|
||||
- name: Install
|
||||
run: sudo ninja -C build install
|
72
.github/workflows/windows-build.yml
vendored
@ -1,72 +0,0 @@
|
||||
name: Windows Build
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
windows_build:
|
||||
runs-on: windows-2019
|
||||
strategy:
|
||||
matrix:
|
||||
platform: [x64, win32]
|
||||
arch: [x64, x86]
|
||||
exclude:
|
||||
- platform: x64
|
||||
arch: x86
|
||||
- platform: win32
|
||||
arch: x64
|
||||
fail-fast: false
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
New-Item -Name "deps" -ItemType "Directory"
|
||||
|
||||
Invoke-WebRequest http://files.jrsoftware.org/is/5/innosetup-5.5.9-unicode.exe -OutFile deps\innosetup-unicode.exe
|
||||
& deps\innosetup-unicode.exe /VERYSILENT | Out-Null
|
||||
|
||||
Invoke-WebRequest https://dl.hexchat.net/misc/idpsetup-1.5.1.exe -OutFile deps\idpsetup.exe
|
||||
& deps\idpsetup.exe /VERYSILENT
|
||||
|
||||
Invoke-WebRequest https://dl.hexchat.net/gtk/gtk-${{ matrix.platform }}-2018-08-29-openssl1.1.7z -OutFile deps\gtk-${{ matrix.arch }}.7z
|
||||
& 7z.exe x deps\gtk-${{ matrix.arch }}.7z -oC:\gtk-build\gtk
|
||||
|
||||
Invoke-WebRequest https://dl.hexchat.net/gtk-win32/gendef-20111031.7z -OutFile deps\gendef.7z
|
||||
& 7z.exe x deps\gendef.7z -oC:\gtk-build
|
||||
|
||||
Invoke-WebRequest https://dl.hexchat.net/gtk-win32/WinSparkle-20151011.7z -OutFile deps\WinSparkle.7z
|
||||
& 7z.exe x deps\WinSparkle.7z -oC:\gtk-build\WinSparkle
|
||||
|
||||
Invoke-WebRequest https://dl.hexchat.net/misc/perl/perl-5.20.0-${{ matrix.arch }}.7z -OutFile deps\perl-${{ matrix.arch }}.7z
|
||||
& 7z.exe x deps\perl-${{ matrix.arch }}.7z -oC:\gtk-build\perl-5.20\${{ matrix.platform }}
|
||||
|
||||
New-Item -Path "c:\gtk-build" -Name "python-2.7" -ItemType "Directory"
|
||||
New-Item -Path "c:\gtk-build" -Name "python-3.8" -ItemType "Directory"
|
||||
New-Item -Path "c:\gtk-build\python-2.7" -Name "${{ matrix.platform }}" -ItemType "SymbolicLink" -Value "C:/hostedtoolcache/windows/Python/2.7.18/${{ matrix.arch }}"
|
||||
New-Item -Path "c:\gtk-build\python-3.8" -Name "${{ matrix.platform }}" -ItemType "SymbolicLink" -Value "C:/hostedtoolcache/windows/Python/3.8.10/${{ matrix.arch }}"
|
||||
|
||||
C:/hostedtoolcache/windows/Python/3.8.10/${{ matrix.arch }}/python.exe -m pip install cffi
|
||||
C:/hostedtoolcache/windows/Python/2.7.18/${{ matrix.arch }}/python.exe -m pip install -qq cffi
|
||||
shell: powershell
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\Tools\VsDevCmd.bat"
|
||||
msbuild win32\hexchat.sln /m /verbosity:minimal /p:Configuration=Release /p:Platform=${{ matrix.platform }}
|
||||
shell: cmd
|
||||
|
||||
- name: Preparing Artifacts
|
||||
run: |
|
||||
move ..\hexchat-build\${{ matrix.platform }}\HexChat*.exe .\
|
||||
move ..\hexchat-build .\
|
||||
shell: cmd
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Installer ${{ matrix.arch }}
|
||||
path: HexChat*.exe
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Build Files ${{ matrix.arch }}
|
||||
path: hexchat-build
|
79
.gitignore
vendored
@ -1,12 +1,80 @@
|
||||
/build
|
||||
builddir/
|
||||
# git ignore file
|
||||
# Unix generated files
|
||||
.deps/
|
||||
.libs/
|
||||
.dirstamp
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
compile
|
||||
ar-lib
|
||||
confdefs.h
|
||||
conftest
|
||||
conftest.c
|
||||
conftest.err
|
||||
config.guess
|
||||
config.h.in
|
||||
config.h.in~
|
||||
config.h
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
config-win32.h
|
||||
configure
|
||||
configure.tmp
|
||||
depcomp
|
||||
doxygen*.tmp
|
||||
html/
|
||||
install-sh
|
||||
intl/
|
||||
libtool
|
||||
ltmain.sh
|
||||
m4/
|
||||
missing
|
||||
plugins/perl/irc.pm.h
|
||||
plugins/perl/xchat.pm.h
|
||||
plugins/perl/hexchat.pm.h
|
||||
po/Makefile.in.in
|
||||
po/POTFILES
|
||||
po/remove-potcdate.sed
|
||||
po/stamp-*
|
||||
osx/Info.plist
|
||||
data/man/hexchat.1
|
||||
data/pkgconfig/hexchat-plugin.pc
|
||||
data/misc/hexchat.appdata.xml
|
||||
data/misc/hexchat.desktop
|
||||
data/misc/htm.desktop
|
||||
src/common/dbus/example
|
||||
src/common/dbus/org.hexchat.service.service
|
||||
src/common/dbus/remote-object-glue.h
|
||||
src/common/make-te
|
||||
src/common/marshal.*
|
||||
src/common/textenums.h
|
||||
src/common/textevents.h
|
||||
src/fe-gtk/hexchat
|
||||
src/fe-gtk/hexchat.rc
|
||||
src/fe-text/hexchat-text
|
||||
src/htm/Main.resources
|
||||
src/htm/thememan.exe
|
||||
src/htm/thememan.exe.config
|
||||
src/htm/thememan.exe.mdb
|
||||
src/htm/thememan
|
||||
stamp-h1
|
||||
*.a
|
||||
*.o
|
||||
*.la
|
||||
*.lo
|
||||
*.gmo
|
||||
*.mo
|
||||
*.po~
|
||||
*.pot
|
||||
*.patch
|
||||
tags
|
||||
src/**/*.plist
|
||||
# Win32 generated files
|
||||
plugins/wmpa/wmpa_h.h
|
||||
plugins/wmpa/wmpa_i.c
|
||||
src/fe-gtk/resources.c
|
||||
src/htm/obj/*
|
||||
win32/ipch/*
|
||||
win32/ext/perl/perl-x86-cache
|
||||
@ -20,10 +88,9 @@ resource.h
|
||||
*.suo
|
||||
*.user
|
||||
*.exe
|
||||
# OSX
|
||||
#OSX
|
||||
osx/HexChat.app
|
||||
osx/.HexChat.app
|
||||
po/.intltool-merge-cache
|
||||
*.zip
|
||||
*.dmg
|
||||
*.VC.db
|
||||
*.VC.opendb
|
||||
|
3
.gitmodules
vendored
@ -1,3 +0,0 @@
|
||||
[submodule "flatpak/shared-modules"]
|
||||
path = flatpak/shared-modules
|
||||
url = https://github.com/flathub/shared-modules.git
|
10
.mailmap
@ -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
|
17
.travis.yml
Normal file
@ -0,0 +1,17 @@
|
||||
language: c
|
||||
compiler: clang
|
||||
before_script:
|
||||
- sudo apt-get update
|
||||
- sudo apt-get build-dep -qq xchat
|
||||
- sudo apt-get install -qq libnotify-dev libproxy-dev libpci-dev libcanberra-dev monodevelop gnome-common
|
||||
script:
|
||||
- ./autogen.sh
|
||||
- ./configure --enable-textfe --with-theme-manager --enable-static-analysis
|
||||
- make V=1 -j$(nproc)
|
||||
notifications:
|
||||
irc:
|
||||
channels: "chat.freenode.net#hexchat-devel"
|
||||
template: "Build %{build_url} (%{commit} in %{branch}) by %{author}: %{message}"
|
||||
on_success: change
|
||||
matrix:
|
||||
fast_finish: true
|
8
Makefile.am
Normal file
@ -0,0 +1,8 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
SUBDIRS = po src plugins data
|
||||
|
||||
EXTRA_DIST = autogen.sh data
|
||||
|
22
autogen.sh
Executable file
@ -0,0 +1,22 @@
|
||||
#!/bin/sh
|
||||
# Run this to generate all the initial makefiles, etc.
|
||||
|
||||
srcdir=`dirname $0`
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
NOCONFIGURE=1
|
||||
PKG_NAME="hexchat"
|
||||
|
||||
(test -f $srcdir/src/common/hexchat.c) || {
|
||||
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
|
||||
echo " top-level $PKG_NAME directory"
|
||||
exit 1
|
||||
}
|
||||
|
||||
which gnome-autogen.sh || {
|
||||
echo "You need to install gnome-common"
|
||||
exit 1
|
||||
}
|
||||
|
||||
. gnome-autogen.sh
|
||||
|
847
configure.ac
Normal file
@ -0,0 +1,847 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT([HexChat],[2.11.0])
|
||||
|
||||
AC_PREREQ([2.60])
|
||||
AC_COPYRIGHT([Copyright (C) 1998-2010 Peter Zelezny])
|
||||
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_SRCDIR([configure.ac])
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AM_INIT_AUTOMAKE([1.11 dist-bzip2 subdir-objects no-define foreign])
|
||||
AM_SILENT_RULES([yes])
|
||||
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AM_MAINTAINER_MODE
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_CPP
|
||||
AC_PROG_OBJC
|
||||
AM_PROG_AS
|
||||
AM_PROG_AR
|
||||
AM_DISABLE_STATIC
|
||||
AC_PROG_LIBTOOL
|
||||
AC_PATH_PROG(MDTOOL, mdtool, no)
|
||||
|
||||
dnl -----------------------------------------------------------
|
||||
dnl Language Support
|
||||
dnl -----------------------------------------------------------
|
||||
GETTEXT_PACKAGE=hexchat
|
||||
AC_SUBST(GETTEXT_PACKAGE)
|
||||
AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[Gettext package name])
|
||||
IT_PROG_INTLTOOL([0.40.0])
|
||||
AM_GLIB_GNU_GETTEXT
|
||||
|
||||
dnl displaced from acconfig.h
|
||||
AH_VERBATIM([OLD_PERL],[#undef OLD_PERL])
|
||||
AH_VERBATIM([PREFIX],[#undef PREFIX])
|
||||
AH_VERBATIM([HEXCHATLIBDIR],[#undef HEXCHATLIBDIR])
|
||||
AH_VERBATIM([HEXCHATSHAREDIR],[#undef HEXCHATSHAREDIR])
|
||||
AH_VERBATIM([USE_LIBPROXY],[#undef USE_LIBPROXY])
|
||||
AH_VERBATIM([HAVE_LIBPCI],[#undef HAVE_LIBPCI])
|
||||
AH_VERBATIM([HAVE_ISO_CODES],[#undef HAVE_ISO_CODES])
|
||||
AH_VERBATIM([HAVE_GTK_MAC],[#undef HAVE_GTK_MAC])
|
||||
AH_VERBATIM([USE_LIBNOTIFY],[#undef USE_LIBNOTIFY])
|
||||
AH_VERBATIM([USE_LIBCANBERRA],[#undef USE_LIBCANBERRA])
|
||||
AH_VERBATIM([USE_OPENSSL],[#undef USE_OPENSSL])
|
||||
AH_VERBATIM([USE_PLUGIN],[#undef USE_PLUGIN])
|
||||
AH_VERBATIM([USE_SIGACTION],[#undef USE_SIGACTION])
|
||||
AH_VERBATIM([USING_FREEBSD],[#undef USING_FREEBSD])
|
||||
AH_VERBATIM([USING_LINUX],[#undef USING_LINUX])
|
||||
AH_VERBATIM([socklen_t],[#undef socklen_t])
|
||||
AH_VERBATIM([USE_DBUS],[#undef USE_DBUS])
|
||||
|
||||
AC_PATH_PROG(sedpath, sed)
|
||||
if test "_$sedpath" = _; then
|
||||
AC_MSG_ERROR(Cannot find sed: I need it!)
|
||||
fi
|
||||
|
||||
AC_PATH_PROG(unamepath, uname)
|
||||
if test "_$unamepath" = _; then
|
||||
system="unknown"
|
||||
else
|
||||
AC_MSG_CHECKING(system type)
|
||||
system=`$unamepath -s`
|
||||
AC_MSG_RESULT($system)
|
||||
if test "$system" = "Linux"; then
|
||||
AC_DEFINE(USING_LINUX)
|
||||
fi
|
||||
if test "$system" = "FreeBSD"; then
|
||||
AC_DEFINE(USING_FREEBSD)
|
||||
fi
|
||||
fi
|
||||
|
||||
platform_win32=no
|
||||
platform_osx=no
|
||||
case $host_os in
|
||||
*mingw*|*cygwin*|*msys*)
|
||||
platform_win32=yes;;
|
||||
darwin*)
|
||||
platform_osx=yes;;
|
||||
*);;
|
||||
esac
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** configure switches ***********************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
AC_ARG_ENABLE(openssl,
|
||||
[AS_HELP_STRING([--enable-openssl[=PATH]],[enable use of openSSL])],
|
||||
openssl=$enableval, openssl=yes)
|
||||
|
||||
AC_ARG_ENABLE(gtkfe,
|
||||
[AS_HELP_STRING([--disable-gtkfe],[disable building gtk frontend])],
|
||||
gtkfe=$enableval, gtkfe=yes)
|
||||
|
||||
AC_ARG_ENABLE(textfe,
|
||||
[AS_HELP_STRING([--enable-textfe],[build the text frontend (default: no)])],
|
||||
textfe=$enableval, textfe=no)
|
||||
|
||||
AC_ARG_ENABLE(python,
|
||||
[AS_HELP_STRING([--enable-python=pythonversion],[build the python plugin; possible values: "python2", "python3" or specific such as "python3.3" (default on, python2)])],
|
||||
python=$enableval, python=python2)
|
||||
AS_IF([test "x$python" = "xyes"], [python=python2])
|
||||
|
||||
AC_ARG_ENABLE(perl,
|
||||
[AS_HELP_STRING([--disable-perl],[don\'t build the perl plugin])],
|
||||
perl=$enableval, perl=yes)
|
||||
|
||||
AC_ARG_ENABLE(perl_old,
|
||||
[AS_HELP_STRING([--disable-perl_old],[no backwards compatibility for perl plugin])],
|
||||
perl_old=$enableval, perl_old=yes)
|
||||
|
||||
AC_ARG_ENABLE(plugin,
|
||||
[AS_HELP_STRING([--disable-plugin],[disable plugin support])],
|
||||
plugin=$enableval, plugin=yes)
|
||||
|
||||
AC_ARG_ENABLE(checksum,
|
||||
[AS_HELP_STRING([--disable-checksum],[disable the Checksum plugin])],
|
||||
checksum=$enableval, checksum=yes)
|
||||
|
||||
AC_ARG_ENABLE(doat,
|
||||
[AS_HELP_STRING([--disable-doat],[disable the Do At plugin])],
|
||||
doat=$enableval, doat=yes)
|
||||
|
||||
AC_ARG_ENABLE(fishlim,
|
||||
[AS_HELP_STRING([--disable-fishlim],[disable the FiSHLiM plugin])],
|
||||
fishlim=$enableval, fishlim=yes)
|
||||
|
||||
AC_ARG_ENABLE(sysinfo,
|
||||
[AS_HELP_STRING([--disable-sysinfo],[disable the SysInfo plugin])],
|
||||
sysinfo=$enableval, sysinfo=yes)
|
||||
|
||||
AC_ARG_ENABLE(dbus,
|
||||
[AS_HELP_STRING([--disable-dbus],[disable DBUS support])],
|
||||
dbus=$enableval, dbus=yes)
|
||||
|
||||
AC_ARG_ENABLE(libnotify,
|
||||
[AS_HELP_STRING([--disable-libnotify],[disable libnotify support])],
|
||||
libnotify=$enableval, libnotify=yes)
|
||||
|
||||
AC_ARG_ENABLE(libcanberra,
|
||||
[AS_HELP_STRING([--disable-libcanberra],[disable libcanberra support])],
|
||||
libcanberra=$enableval, libcanberra=yes)
|
||||
|
||||
AC_ARG_ENABLE(libproxy,
|
||||
[AS_HELP_STRING([--disable-libproxy],[disable libproxy support (default: auto)])],
|
||||
libproxy=$enableval, libproxy=auto)
|
||||
|
||||
AC_ARG_ENABLE(isocodes,
|
||||
[AS_HELP_STRING([--disable-isocodes],[disable iso-codes with spell-check])],
|
||||
isocodes=$enableval, isocodes=yes)
|
||||
|
||||
AC_ARG_ENABLE(minimal-flags,
|
||||
[AS_HELP_STRING([--enable-minimal-flags],[only add those CFLAGS that are really needed or not intrusive (default: no)])],
|
||||
minimalflags=$enableval, minimalflags=no)
|
||||
|
||||
AC_ARG_ENABLE(static-analysis,
|
||||
[AS_HELP_STRING([--enable-static-analysis],[if using clang run static analysis during build (default: no)])],
|
||||
analyze=$enableval, analyze=no)
|
||||
|
||||
AC_ARG_WITH(theme-manager,
|
||||
[AS_HELP_STRING([--with-theme-manager],[compile theme manager (needs monodevelop, default: off)])],
|
||||
theme_manager=$withval, theme_manager=no)
|
||||
|
||||
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** THEME-MANAGER ****************************************************
|
||||
dnl *********************************************************************
|
||||
if test "x$theme_manager" != "xno" ; then
|
||||
if test "x$MDTOOL" = "xno"; then
|
||||
AC_MSG_ERROR([No "mdtool" found, you need to install monodevelop!])
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** GLIB *************************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
AM_PATH_GLIB_2_0([2.32.0], [], [AC_MSG_ERROR([Glib not found!])], [gmodule gobject gio])
|
||||
COMMON_CFLAGS="$GLIB_CFLAGS -DG_DISABLE_SINGLE_INCLUDES"
|
||||
COMMON_LIBS="$GLIB_LIBS"
|
||||
AC_DEFINE([GLIB_VERSION_MIN_REQUIRED], [GLIB_VERSION_2_32], [Dont warn using older APIs])
|
||||
AC_DEFINE([GLIB_VERSION_MAX_ALLOWED], [GLIB_VERSION_2_32], [Prevents using newer APIs])
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** GTK **************************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
if test "$gtkfe" = yes ; then
|
||||
PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.24.0], [
|
||||
GUI_LIBS="$GUI_LIBS $GTK_LIBS"
|
||||
GUI_CFLAGS="$GUI_CFLAGS $GTK_CFLAGS -DGDK_PIXBUF_DISABLE_SINGLE_INCLUDES -DGTK_DISABLE_SINGLE_INCLUDES -DGTK_DISABLE_DEPRECATED"
|
||||
], [
|
||||
gtkfe=no
|
||||
])
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** MAC_INTEGRATION **************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
_gdk_tgt=`$PKG_CONFIG --variable=target gdk-2.0`
|
||||
if test "x$_gdk_tgt" = xquartz; then
|
||||
PKG_CHECK_MODULES(GTK_MAC, gtk-mac-integration-gtk2, [
|
||||
GUI_LIBS="$GUI_LIBS $GTK_MAC_LIBS"
|
||||
GUI_CFLAGS="$GUI_CFLAGS $GTK_MAC_CFLAGS"
|
||||
AC_DEFINE(HAVE_GTK_MAC)
|
||||
])
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** PERL *************************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
if test "$perl" = yes; then
|
||||
AC_MSG_CHECKING(for plugin interface used by Perl)
|
||||
if test "$plugin" = yes; then
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_PATH_PROG(perlpath, perl)
|
||||
AC_MSG_CHECKING(for Perl compile flags)
|
||||
PERL_CFLAGS=`$perlpath -MExtUtils::Embed -e ccopts 2>/dev/null`
|
||||
if test "_$PERL_CFLAGS" = _ ; then
|
||||
AC_MSG_RESULT([not found, building without perl.])
|
||||
perl=no
|
||||
else
|
||||
PERL_LDFLAGS=`$perlpath -MExtUtils::Embed -e ldopts |$sedpath 's/-lgdbm //'`
|
||||
PERL_LDFLAGS=`echo $PERL_LDFLAGS |$sedpath 's/-ldb //'`
|
||||
PERL_LDFLAGS=`echo $PERL_LDFLAGS |$sedpath 's/-lndbm //'`
|
||||
if test "$system" = "Linux"; then
|
||||
PERL_LDFLAGS=`echo $PERL_LDFLAGS |$sedpath 's/-lnsl //'`
|
||||
PERL_LDFLAGS=`echo $PERL_LDFLAGS |$sedpath 's/-lposix //'`
|
||||
fi
|
||||
PERL_LDFLAGS=`echo $PERL_LDFLAGS |$sedpath 's/-lc //'`
|
||||
AC_MSG_RESULT(ok)
|
||||
|
||||
AC_MSG_CHECKING(for perl >= 5.8.0)
|
||||
PERL_VER=`$perlpath -e 'print $]>= 5.008?"yes":"no"'`
|
||||
if test "$PERL_VER" = "yes"; then
|
||||
original_cflags="$CFLAGS"
|
||||
original_ldflags="$LDFLAGS"
|
||||
CFLAGS="$PERL_CFLAGS"
|
||||
LDFLAGS="$PERL_LDFLAGS"
|
||||
AC_TRY_LINK([
|
||||
#define PERL_NO_INLINE_FUNCTIONS
|
||||
#include <EXTERN.h>
|
||||
#include <perl.h>
|
||||
], [], perl_is_usable=yes, perl_is_usable=no)
|
||||
CFLAGS="$original_cflags"
|
||||
LDFLAGS="$original_ldflags"
|
||||
if test x$perl_is_usable = xno ; then
|
||||
AC_MSG_RESULT(no)
|
||||
perl=no
|
||||
else
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_MSG_CHECKING(if perl plugin will be backward compatible)
|
||||
if test "$perl_old" = "yes"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(OLD_PERL)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
echo "perl version too old, building without perl."
|
||||
perl=no
|
||||
fi
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option for Perl])
|
||||
perl=no
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** PYTHON ***********************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
if test "x$python" != xno ; then
|
||||
AC_MSG_CHECKING(for plugin interface used by Python)
|
||||
if test "$plugin" = yes; then
|
||||
AC_MSG_RESULT([yes])
|
||||
case $python in
|
||||
dnl set python2 default here
|
||||
python2)
|
||||
PKG_CHECK_MODULES([PY], [python-2.7],
|
||||
[PY_VER="`$PKG_CONFIG --modversion python-2.7`"],
|
||||
[true])
|
||||
;;
|
||||
dnl set python3 default here
|
||||
python3)
|
||||
PKG_CHECK_MODULES([PY], [python-3.4],
|
||||
[PY_VER="`$PKG_CONFIG --modversion python-3.4`"],
|
||||
[true])
|
||||
if test "$PY_VER" = "" ; then
|
||||
PKG_CHECK_MODULES([PY], [python-3.3],
|
||||
[PY_VER="`$PKG_CONFIG --modversion python-3.3`"],
|
||||
[true])
|
||||
fi
|
||||
;;
|
||||
dnl add broken versions here
|
||||
python2.5|python2.6|python3.1|python3.2)
|
||||
AC_MSG_WARN(Unsupported Python version ${python}!);;
|
||||
python*)
|
||||
python="python-${python#python}" # stay posix compliant
|
||||
PKG_CHECK_MODULES([PY], [${python}],
|
||||
[PY_VER="`$PKG_CONFIG --modversion ${python}`"],
|
||||
[AC_MSG_WARN(Cannot find "${python}.pc"!)])
|
||||
;;
|
||||
*)
|
||||
AC_MSG_WARN(Unsupported Python ${python}!)
|
||||
esac
|
||||
AC_MSG_CHECKING(Python version)
|
||||
|
||||
if test "$PY_VER"; then
|
||||
AC_MSG_RESULT($PY_VER)
|
||||
python="python-${PY_VER}"
|
||||
else
|
||||
AC_MSG_RESULT(Not found)
|
||||
python=no
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option for Python])
|
||||
python=no
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** IPv6 *************************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
dnl purely for Solaris
|
||||
AC_CHECK_FUNC(select, ,
|
||||
AC_CHECK_LIB(socket, select, ,
|
||||
AC_CHECK_LIB(nsl, select, ,
|
||||
AC_CHECK_LIB(inet, select, ,
|
||||
AC_CHECK_LIB(cposix, select, ,
|
||||
AC_CHECK_LIB(net, select, ,
|
||||
AC_MSG_WARN(i can not find select. you might need to help me)))))))
|
||||
AC_CHECK_LIB(socket, select)
|
||||
|
||||
AC_CHECK_FUNCS(getaddrinfo, have_getaddrinfo=yes)
|
||||
AC_MSG_CHECKING(whether IPv6 is supported)
|
||||
if test "$have_getaddrinfo" = yes; then
|
||||
AC_MSG_RESULT(yes)
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AC_MSG_ERROR(ipv6 support not found!)
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** OPENSSL **********************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
retry=no
|
||||
if test "$openssl" != no; then
|
||||
PKG_CHECK_MODULES(OPENSSL, [openssl], [
|
||||
AC_DEFINE(USE_OPENSSL)
|
||||
openssl=yes
|
||||
COMMON_LIBS="$COMMON_LIBS $OPENSSL_LIBS"
|
||||
COMMON_CFLAGS="$COMMON_CFLAGS $OPENSSL_CFLAGS"
|
||||
], [
|
||||
retry=yes
|
||||
])
|
||||
fi
|
||||
|
||||
if test "$retry" = "yes"; then
|
||||
unset openssl_path ac_cv_lib_ssl_SSL_new ac_cv_header_openssl_ssl_h
|
||||
if test "$openssl" != yes; then
|
||||
openssl_path=$openssl
|
||||
fi
|
||||
openssl=no
|
||||
OPENSSL_LIBS="-lcrypto"
|
||||
if test -n "$openssl_path"; then
|
||||
OPENSSL_LIBS="-L$openssl_path/lib $OPENSSL_LIBS"
|
||||
fi
|
||||
SAVED_LIBS=$LIBS
|
||||
LIBS="$LIBS $OPENSSL_LIBS"
|
||||
AC_CHECK_LIB(ssl, SSL_new, [
|
||||
if test -n "$openssl_path"; then
|
||||
OPENSSL_CFLAGS="-I$openssl_path/include"
|
||||
fi
|
||||
SAVED_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS $OPENSSL_CFLAGS"
|
||||
AC_CHECK_HEADERS(openssl/ssl.h, [
|
||||
openssl=yes
|
||||
AC_DEFINE(USE_OPENSSL)
|
||||
OPENSSL_LIBS="$OPENSSL_LIBS -lssl"
|
||||
|
||||
COMMON_LIBS="$COMMON_LIBS $OPENSSL_LIBS"
|
||||
COMMON_CFLAGS="$COMMON_CFLAGS $OPENSSL_CFLAGS"
|
||||
])
|
||||
CFLAGS=$SAVED_CFLAGS
|
||||
])
|
||||
LIBS=$SAVED_LIBS
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** LIBPROXY *********************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
if test "x$libproxy" = "xyes" -o "x$libproxy" = "xauto" ; then
|
||||
PKG_CHECK_MODULES([LIBPROXY], [libproxy-1.0], [
|
||||
COMMON_LIBS="$COMMON_LIBS $LIBPROXY_LIBS"
|
||||
COMMON_CFLAGS="$COMMON_CFLAGS $LIBPROXY_CFLAGS"
|
||||
AC_DEFINE(USE_LIBPROXY)
|
||||
libproxy=yes
|
||||
], [
|
||||
if test "x$libproxy" = "xyes" ; then
|
||||
AC_MSG_ERROR(Cannot find libproxy!)
|
||||
fi
|
||||
libproxy=no
|
||||
])
|
||||
else
|
||||
libproxy=no
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** PLUGIN ***********************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
if test "$plugin" = yes; then
|
||||
AC_DEFINE(USE_PLUGIN)
|
||||
PLUGIN_LDFLAGS="-avoid-version"
|
||||
if test "$platform_win32" = yes; then
|
||||
PLUGIN_LDFLAGS="$PLUGIN_LDFLAGS -no-undefined"
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** Checksum *********************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
if test "$checksum" != "no"; then
|
||||
checksum=no
|
||||
AC_MSG_CHECKING(for plugin interface used by Checksum)
|
||||
if test "$plugin" = yes; then
|
||||
checksum=yes
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** DO AT ************************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
if test "$doat" != "no"; then
|
||||
AC_MSG_CHECKING(for plugin interface used by Do At)
|
||||
doat=no
|
||||
if test "$plugin" = yes; then
|
||||
doat=yes
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option for Do At])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** FiSHLiM **********************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
if test "$fishlim" != "no"; then
|
||||
fishlim=no
|
||||
AC_MSG_CHECKING(for plugin interface used by FiSHLiM)
|
||||
if test "$plugin" = yes; then
|
||||
AC_MSG_RESULT([yes])
|
||||
AC_MSG_CHECKING(for OpenSSL used by FiSHLiM)
|
||||
if test "$openssl" = yes; then
|
||||
fishlim=yes
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([OpenSSL cannot be found, use the --enable-openssl option])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** SYSINFO **********************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
if test "$sysinfo" != "no"; then
|
||||
AC_MSG_CHECKING(for plugin interface used by SysInfo)
|
||||
if test "$plugin" = yes; then
|
||||
AC_MSG_RESULT([yes])
|
||||
if test "$platform_osx" = yes; then
|
||||
sysinfo=yes
|
||||
else
|
||||
PKG_CHECK_MODULES(LIBPCI, libpci >= 3.0.0, [
|
||||
sysinfo=yes
|
||||
AC_DEFINE(HAVE_LIBPCI)
|
||||
], [sysinfo=no])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option for SysInfo])
|
||||
sysinfo=no
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl #######################################################################
|
||||
dnl # Check for DBUS libraries
|
||||
dnl #######################################################################
|
||||
|
||||
if test "x$dbus" = "xyes" ; then
|
||||
PKG_CHECK_MODULES(DBUS, [dbus-1 >= 0.60 dbus-glib-1 >= 0.60 gthread-2.0], dbus=yes, [
|
||||
dbus=no
|
||||
])
|
||||
AC_PATH_PROG(DBUS_BINDING_TOOL, dbus-binding-tool, no)
|
||||
if test "x$DBUS_BINDING_TOOL" = "xno" || test "x$dbus" = "xno" ; then
|
||||
dbus="no"
|
||||
else
|
||||
COMMON_LIBS="$COMMON_LIBS $DBUS_LIBS"
|
||||
COMMON_CFLAGS="$COMMON_CFLAGS $DBUS_CFLAGS"
|
||||
AC_DEFINE(USE_DBUS)
|
||||
|
||||
AS_AC_EXPAND(DBUS_SERVICES_DIR, "$datadir/dbus-1/services")
|
||||
AC_SUBST(DBUS_SERVICES_DIR)
|
||||
AC_DEFINE_UNQUOTED(DBUS_SERVICES_DIR, "$DBUS_SERVICES_DIR", [Where services dir for DBUS is])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** LIBNOTIFY ********************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
if test "x$libnotify" = "xyes" ; then
|
||||
PKG_CHECK_MODULES(LIBNOTIFY, libnotify >= 0.4, [], [
|
||||
libnotify=no
|
||||
])
|
||||
if test "$libnotify" != "no" ; then
|
||||
GUI_LIBS="$GUI_LIBS $LIBNOTIFY_LIBS"
|
||||
GUI_CFLAGS="$GUI_CFLAGS $LIBNOTIFY_CFLAGS"
|
||||
AC_DEFINE(USE_LIBNOTIFY)
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** LIBCANBERRA ******************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
if test "x$libcanberra" = "xyes" ; then
|
||||
PKG_CHECK_MODULES(LIBCANBERRA, libcanberra >= 0.22, [], [
|
||||
libcanberra=no
|
||||
])
|
||||
if test "$libcanberra" != "no" ; then
|
||||
COMMON_LIBS="$COMMON_LIBS $LIBCANBERRA_LIBS"
|
||||
COMMON_CFLAGS="$COMMON_CFLAGS $LIBCANBERRA_CFLAGS"
|
||||
AC_DEFINE(USE_LIBCANBERRA)
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** SPELL ************************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
if test "x$isocodes" = "xyes" ; then
|
||||
PKG_CHECK_MODULES(ISOCODES, "iso-codes", [
|
||||
iso_codes_prefix=`$PKG_CONFIG --variable=prefix iso-codes 2>/dev/null || echo /usr`
|
||||
AC_MSG_NOTICE([iso-codes prefix: $iso_codes_prefix])
|
||||
AC_DEFINE_UNQUOTED([ISO_CODES_PREFIX], ["$iso_codes_prefix"], [ISO codes prefix])
|
||||
AC_DEFINE_UNQUOTED([ISO_CODES_LOCALEDIR], ["$iso_codes_prefix/share/locale"], [ISO codes locale dir])
|
||||
AC_DEFINE([HAVE_ISO_CODES], [1], [iso-codes available])
|
||||
], [
|
||||
isocodes=no
|
||||
AC_MSG_WARN(iso-codes not found!)
|
||||
])
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** Static Analysis **************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
if test "x$analyze" = "xyes"; then
|
||||
if test "$CC" != "clang"; then
|
||||
AC_MSG_WARN(CC is not clang for static analysis)
|
||||
analyze=no
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** CONDITIONALS *****************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
AM_CONDITIONAL(USE_OPENSSL, test "x$openssl" = "xyes")
|
||||
AM_CONDITIONAL(USE_LIBNOTIFY, test "x$libnotify" = "xyes")
|
||||
AM_CONDITIONAL(USE_LIBCANBERRA, test "x$libcanberra" = "xyes")
|
||||
AM_CONDITIONAL(DO_TEXT, test "x$textfe" = "xyes")
|
||||
AM_CONDITIONAL(DO_GTK, test "x$gtkfe" = "xyes")
|
||||
AM_CONDITIONAL(DO_PERL, test "x$perl" = "xyes")
|
||||
AM_CONDITIONAL(DO_PYTHON, test "x$python" != "xno")
|
||||
AM_CONDITIONAL(DO_PLUGIN, test "x$plugin" = "xyes")
|
||||
AM_CONDITIONAL(DO_CHECKSUM, test "x$checksum" = "xyes")
|
||||
AM_CONDITIONAL(DO_DOAT, test "x$doat" = "xyes")
|
||||
AM_CONDITIONAL(DO_FISHLIM, test "x$fishlim" = "xyes")
|
||||
AM_CONDITIONAL(DO_SYSINFO, test "x$sysinfo" = "xyes")
|
||||
AM_CONDITIONAL(DO_STATIC_ANALYSIS, test "x$analyze" = "xyes")
|
||||
AM_CONDITIONAL(USE_DBUS, test "x$dbus" = "xyes")
|
||||
AM_CONDITIONAL(HAVE_ISO_CODES, test "x$isocodes" = "xyes")
|
||||
AM_CONDITIONAL(HAVE_GTK_MAC, test "x$_gdk_tgt" = xquartz)
|
||||
AM_CONDITIONAL(WITH_TM, test "x$theme_manager" != "xno")
|
||||
AM_CONDITIONAL(PLATFORM_OSX, test "x$platform_osx" == "xyes")
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** GCC FLAGS ********************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
dnl Only use -Wall and -pipe if we have gcc
|
||||
if test "x$GCC" = "xyes"; then
|
||||
if test -z "`echo "$CFLAGS" | grep "\-Wall" 2> /dev/null`" ; then
|
||||
CFLAGS="$CFLAGS -Wall"
|
||||
fi
|
||||
dnl these flags might be unwanted
|
||||
if test x$minimalflags != xyes; then
|
||||
if test "$system" = "Linux" -o "$system" = "FreeBSD"; then
|
||||
if test -z "`echo "$CFLAGS" | grep "\-pipe" 2> /dev/null`" ; then
|
||||
CFLAGS="$CFLAGS -pipe"
|
||||
fi
|
||||
fi
|
||||
if test -z "`echo "$CFLAGS" | grep "\-g " 2> /dev/null`" ; then
|
||||
CFLAGS="$CFLAGS -g"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl does this compiler support -Wno-pointer-sign ?
|
||||
AC_MSG_CHECKING([if $CC accepts -Wno-pointer-sign ])
|
||||
|
||||
safe_CFLAGS=$CFLAGS
|
||||
CFLAGS="-Wno-pointer-sign"
|
||||
|
||||
AC_TRY_COMPILE(, [
|
||||
return 0;
|
||||
],
|
||||
[
|
||||
no_pointer_sign=yes
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
no_pointer_sign=no
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
CFLAGS=$safe_CFLAGS
|
||||
|
||||
if test x$no_pointer_sign = xyes; then
|
||||
CFLAGS="$CFLAGS -Wno-pointer-sign"
|
||||
fi
|
||||
|
||||
dnl does this compiler support -funsigned-char ?
|
||||
AC_MSG_CHECKING([if $CC accepts -funsigned-char ])
|
||||
|
||||
safe_CFLAGS=$CFLAGS
|
||||
CFLAGS="-funsigned-char"
|
||||
|
||||
AC_TRY_COMPILE(, [
|
||||
return 0;
|
||||
],
|
||||
[
|
||||
unsigned_char=yes
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
unsigned_char=no
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
CFLAGS=$safe_CFLAGS
|
||||
|
||||
if test x$unsigned_char = xyes; then
|
||||
CFLAGS="$CFLAGS -funsigned-char"
|
||||
fi
|
||||
|
||||
dnl does this compiler support -Wno-unused-result ?
|
||||
AC_MSG_CHECKING([if $CC accepts -Wno-unused-result ])
|
||||
|
||||
safe_CFLAGS=$CFLAGS
|
||||
CFLAGS="-Wno-unused-result"
|
||||
|
||||
AC_TRY_COMPILE(, [
|
||||
return 0;
|
||||
],
|
||||
[
|
||||
no_unused_result=yes
|
||||
AC_MSG_RESULT([yes])
|
||||
], [
|
||||
no_unused_result=no
|
||||
AC_MSG_RESULT([no])
|
||||
])
|
||||
CFLAGS=$safe_CFLAGS
|
||||
|
||||
if test x$no_unused_result = xyes; then
|
||||
CFLAGS="$CFLAGS -Wno-unused-result"
|
||||
fi
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** FUNCTIONS/LIBS/CFLAGS ********************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
AC_MSG_CHECKING(for modern sigaction)
|
||||
dnl libc5 on linux and FreeBSD 3.x doesn\'t have siginfo_t
|
||||
dnl and the sa_sigation field.
|
||||
AC_TRY_COMPILE(
|
||||
[#include <signal.h>],
|
||||
[struct sigaction act;
|
||||
siginfo_t *si;
|
||||
act.sa_sigaction = 0;],
|
||||
[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(USE_SIGACTION)
|
||||
],
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
AC_CHECK_FUNCS(memrchr)
|
||||
|
||||
AC_CHECK_FUNC(gethostbyname, ,
|
||||
AC_CHECK_LIB(resolv, gethostbyname, ,
|
||||
AC_CHECK_LIB(nsl, gethostbyname)))
|
||||
|
||||
AC_CHECK_FUNC(gethostname, , AC_CHECK_LIB(nsl, gethostname))
|
||||
|
||||
dnl necessary for IRIX
|
||||
AC_CHECK_HEADERS(strings.h)
|
||||
|
||||
dnl Check for type in sys/socket.h - from Squid source (GPL)
|
||||
AC_CACHE_CHECK(for socklen_t, ac_cv_type_socklen_t, [
|
||||
AC_EGREP_CPP([socklen_t[^a-zA-Z_0-9]], [#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#if STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#endif],
|
||||
ac_cv_type_socklen_t=yes,
|
||||
ac_cv_type_socklen_t=no)
|
||||
])
|
||||
if test $ac_cv_type_socklen_t = no; then
|
||||
AC_DEFINE(socklen_t, int)
|
||||
fi
|
||||
|
||||
dnl Mac OS X and Darwin use lookupd, which caches DNS queries by default
|
||||
AC_EGREP_CPP(lookupd, dnl
|
||||
[#if (defined(__APPLE__) && defined(__MACH__))
|
||||
lookupd
|
||||
#endif], AC_DEFINE([LOOKUPD],1,[Define to 1 if the system uses lookupd]))
|
||||
|
||||
dnl freebsd needs this
|
||||
LIBS="$LIBS $INTLLIBS"
|
||||
CFLAGS="$CFLAGS $CPPFLAGS"
|
||||
|
||||
GUI_LIBS="$GUI_LIBS $COMMON_LIBS"
|
||||
|
||||
dnl make these visible to all Makefiles
|
||||
AC_SUBST(GUI_LIBS)
|
||||
AC_SUBST(GUI_CFLAGS)
|
||||
AC_SUBST(COMMON_LIBS)
|
||||
AC_SUBST(COMMON_CFLAGS)
|
||||
AC_SUBST(PERL_CFLAGS)
|
||||
AC_SUBST(PERL_LDFLAGS)
|
||||
AC_SUBST(PY_CFLAGS)
|
||||
AC_SUBST(PY_LIBS)
|
||||
AC_SUBST(DBUS_CFLAGS)
|
||||
AC_SUBST(DBUS_LIBS)
|
||||
AC_SUBST(OPENSSL_LIBS)
|
||||
AC_SUBST(OPENSSL_CFLAGS)
|
||||
AC_SUBST(PLUGIN_LDFLAGS)
|
||||
|
||||
m4_ifdef([PKG_INSTALLDIR], [PKG_INSTALLDIR], AC_SUBST([pkgconfigdir], ${libdir}/pkgconfig))
|
||||
|
||||
dnl for plugin.c and pixmaps.c
|
||||
test "x$prefix" = xNONE && prefix="$ac_default_prefix"
|
||||
test "x$exec_prefix" = xNONE && exec_prefix="$prefix"
|
||||
|
||||
AC_DEFINE_UNQUOTED(PREFIX, "${prefix}")
|
||||
|
||||
AS_AC_EXPAND(HEXCHATLIBDIR, "${libdir}/hexchat/plugins")
|
||||
AC_DEFINE_UNQUOTED(HEXCHATLIBDIR, "$HEXCHATLIBDIR")
|
||||
|
||||
AS_AC_EXPAND(HEXCHATSHAREDIR, "$datadir")
|
||||
AC_DEFINE_UNQUOTED(HEXCHATSHAREDIR, "$HEXCHATSHAREDIR")
|
||||
|
||||
dnl for plugins/xxx/Makefile.am
|
||||
hexchatlibdir=${libdir}/hexchat/plugins
|
||||
AC_SUBST(hexchatlibdir)
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
data/Makefile
|
||||
data/icons/Makefile
|
||||
data/misc/Makefile
|
||||
data/man/Makefile
|
||||
data/man/hexchat.1
|
||||
data/pkgconfig/Makefile
|
||||
data/pkgconfig/hexchat-plugin.pc
|
||||
src/Makefile
|
||||
src/common/Makefile
|
||||
src/common/dbus/Makefile
|
||||
src/fe-text/Makefile
|
||||
src/fe-gtk/Makefile
|
||||
src/htm/Makefile
|
||||
src/htm/thememan
|
||||
osx/Info.plist
|
||||
plugins/Makefile
|
||||
plugins/python/Makefile
|
||||
plugins/perl/Makefile
|
||||
plugins/checksum/Makefile
|
||||
plugins/doat/Makefile
|
||||
plugins/fishlim/Makefile
|
||||
plugins/sysinfo/Makefile
|
||||
po/Makefile.in
|
||||
])
|
||||
|
||||
AC_OUTPUT
|
||||
|
||||
echo
|
||||
echo HexChat $VERSION
|
||||
echo
|
||||
echo GTK+ interface ........ : $gtkfe
|
||||
echo Text interface ........ : $textfe
|
||||
echo Theme manager ......... : $theme_manager
|
||||
echo
|
||||
echo OpenSSL support ....... : $openssl
|
||||
echo D-Bus support ......... : $dbus
|
||||
echo libnotify support ..... : $libnotify
|
||||
echo libcanberra support ... : $libcanberra
|
||||
echo Plugin interface ...... : $plugin
|
||||
echo libproxy support ...... : $libproxy
|
||||
echo
|
||||
echo Perl .................. : $perl
|
||||
echo Python ................ : $python
|
||||
echo
|
||||
echo Checksum .............. : $checksum
|
||||
echo Do At ................. : $doat
|
||||
echo FiSHLiM ............... : $fishlim
|
||||
echo SysInfo ............... : $sysinfo
|
||||
echo
|
||||
echo The binary will be installed in $prefix/bin
|
||||
echo
|
||||
|
||||
if test "$gtkfe" = no; then
|
||||
echo Warning: The GTK \(GUI\) frontend will not be built.
|
||||
echo
|
||||
fi
|
||||
|
||||
echo configure complete, now type \'make\' and pray.
|
||||
echo
|
5
data/Makefile.am
Normal file
@ -0,0 +1,5 @@
|
||||
SUBDIRS = pkgconfig man
|
||||
|
||||
if DO_GTK
|
||||
SUBDIRS += icons misc
|
||||
endif
|
@ -1,24 +1,23 @@
|
||||
<?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="hexchat.png" preprocess="to-pixdata" compressed="true">icons/hexchat.png</file>
|
||||
<file alias="book.png" preprocess="to-pixdata" compressed="true">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="ulist_voice.png" preprocess="to-pixdata" compressed="true">icons/ulist_voice.png</file>
|
||||
<file alias="ulist_halfop.png" preprocess="to-pixdata" compressed="true">icons/ulist_halfop.png</file>
|
||||
<file alias="ulist_op.png" preprocess="to-pixdata" compressed="true">icons/ulist_op.png</file>
|
||||
<file alias="ulist_owner.png" preprocess="to-pixdata" compressed="true">icons/ulist_owner.png</file>
|
||||
<file alias="ulist_founder.png" preprocess="to-pixdata" compressed="true">icons/ulist_founder.png</file>
|
||||
<file alias="ulist_netop.png" preprocess="to-pixdata" compressed="true">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="tray_fileoffer.png" preprocess="to-pixdata" compressed="true">icons/tray_fileoffer.png</file>
|
||||
<file alias="tray_highlight.png" preprocess="to-pixdata" compressed="true">icons/tray_highlight.png</file>
|
||||
<file alias="tray_message.png" preprocess="to-pixdata" compressed="true">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>
|
||||
<file alias="tree_dialog.png" preprocess="to-pixdata" compressed="true">icons/tree_dialog.png</file>
|
||||
<file alias="tree_server.png" preprocess="to-pixdata" compressed="true">icons/tree_server.png</file>
|
||||
<file alias="tree_util.png" preprocess="to-pixdata" compressed="true">icons/tree_util.png</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
13
data/icons/Makefile.am
Normal file
@ -0,0 +1,13 @@
|
||||
icon_DATA = hexchat.png
|
||||
icondir = $(datadir)/icons/hicolor/48x48/apps
|
||||
|
||||
hicolor_DATA = hexchat.svg
|
||||
hicolordir = $(datadir)/icons/hicolor/scalable/apps
|
||||
|
||||
UPDATE_ICON_CACHE = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor || :
|
||||
|
||||
install-data-hook:
|
||||
$(UPDATE_ICON_CACHE);
|
||||
|
||||
uninstall-hook:
|
||||
$(UPDATE_ICON_CACHE);
|
@ -1,63 +1,745 @@
|
||||
<?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>
|
||||
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:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
sodipodi:docname="hexchat.svg"
|
||||
version="1.0"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:version="0.32"
|
||||
id="svg2"
|
||||
height="64"
|
||||
width="64">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
id="linearGradient2289">
|
||||
<stop
|
||||
style="stop-color:#ff2600;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop2291" />
|
||||
<stop
|
||||
style="stop-color:#ffd600;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop2293" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient1335"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.545166,0,0,0.544959,0.186963,35.29511)"
|
||||
x1="16.88862"
|
||||
y1="77.796608"
|
||||
x2="72.348671"
|
||||
y2="20.59322" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient1337"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.545166,0,0,0.544959,0.186963,35.29511)"
|
||||
x1="16.88862"
|
||||
y1="77.796608"
|
||||
x2="16.88862"
|
||||
y2="19.001091" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient1317"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.052758,-16.66733)"
|
||||
x1="16.88862"
|
||||
y1="77.796608"
|
||||
x2="72.348671"
|
||||
y2="20.59322" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient1319"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.052758,-16.66733)"
|
||||
x1="16.88862"
|
||||
y1="77.796608"
|
||||
x2="16.88862"
|
||||
y2="19.001091" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient1320"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.172329,-1.111016)"
|
||||
x1="16.88862"
|
||||
y1="77.796608"
|
||||
x2="72.348671"
|
||||
y2="20.59322" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient1322"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.172329,-1.111016)"
|
||||
x1="16.88862"
|
||||
y1="77.796608"
|
||||
x2="16.88862"
|
||||
y2="19.001091" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient2997"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-160.10656,-7.1914058)"
|
||||
x1="130.2673"
|
||||
y1="78.743134"
|
||||
x2="129.2081"
|
||||
y2="25.771122" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient3011"
|
||||
x1="34.62241"
|
||||
y1="53.508884"
|
||||
x2="34.466503"
|
||||
y2="5.4893961"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient3030"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="34.62241"
|
||||
y1="53.508884"
|
||||
x2="34.466503"
|
||||
y2="5.4893961" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient3070"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="34.62241"
|
||||
y1="53.508884"
|
||||
x2="34.466503"
|
||||
y2="5.4893961"
|
||||
gradientTransform="matrix(0.99894925,0,0,0.97549134,-3.1829063,4.465557)" />
|
||||
<filter
|
||||
id="filter3281"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow">
|
||||
<feFlood
|
||||
id="feFlood3283"
|
||||
flood-opacity="0.33"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood" />
|
||||
<feComposite
|
||||
id="feComposite3285"
|
||||
in2="SourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3287"
|
||||
in="composite"
|
||||
stdDeviation="2"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3289"
|
||||
dx="4"
|
||||
dy="1"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3291"
|
||||
in2="offset"
|
||||
in="SourceGraphic"
|
||||
operator="over"
|
||||
result="composite2" />
|
||||
</filter>
|
||||
<filter
|
||||
id="filter3293"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow">
|
||||
<feFlood
|
||||
id="feFlood3295"
|
||||
flood-opacity="0.33"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood" />
|
||||
<feComposite
|
||||
id="feComposite3297"
|
||||
in2="SourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3299"
|
||||
in="composite"
|
||||
stdDeviation="2"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3301"
|
||||
dx="4"
|
||||
dy="1"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3303"
|
||||
in2="offset"
|
||||
in="SourceGraphic"
|
||||
operator="over"
|
||||
result="composite2" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient4089"
|
||||
x1="99.348503"
|
||||
y1="59.934135"
|
||||
x2="100.40916"
|
||||
y2="10.613438"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient4093"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="99.348503"
|
||||
y1="59.934135"
|
||||
x2="100.40916"
|
||||
y2="10.613438" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient4096"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="99.348503"
|
||||
y1="59.934135"
|
||||
x2="100.40916"
|
||||
y2="10.613438" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient4098"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="99.348503"
|
||||
y1="59.934135"
|
||||
x2="100.40916"
|
||||
y2="10.613438"
|
||||
gradientTransform="translate(-70.003571,-2.298097)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
id="linearGradient4101"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.94969205,0,0,0.89326813,1.6716955,2.7025635)"
|
||||
x1="31.372862"
|
||||
y1="60.111893"
|
||||
x2="31.559002"
|
||||
y2="5.6897221" />
|
||||
<filter
|
||||
id="filter4111"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow">
|
||||
<feFlood
|
||||
id="feFlood4113"
|
||||
flood-opacity="0.33"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood" />
|
||||
<feComposite
|
||||
id="feComposite4115"
|
||||
in2="SourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur4117"
|
||||
in="composite"
|
||||
stdDeviation="2"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset4119"
|
||||
dx="4"
|
||||
dy="1"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite4121"
|
||||
in2="offset"
|
||||
in="SourceGraphic"
|
||||
operator="over"
|
||||
result="composite2" />
|
||||
</filter>
|
||||
<filter
|
||||
id="filter4123"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow">
|
||||
<feFlood
|
||||
id="feFlood4125"
|
||||
flood-opacity="0.33"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood" />
|
||||
<feComposite
|
||||
id="feComposite4127"
|
||||
in2="SourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur4129"
|
||||
in="composite"
|
||||
stdDeviation="2"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset4131"
|
||||
dx="4"
|
||||
dy="1"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite4133"
|
||||
in2="offset"
|
||||
in="SourceGraphic"
|
||||
operator="over"
|
||||
result="composite2" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
y2="19.001091"
|
||||
x2="16.88862"
|
||||
y1="77.796608"
|
||||
x1="16.88862"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.172329,-1.111016)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1330"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="20.59322"
|
||||
x2="72.348671"
|
||||
y1="77.796608"
|
||||
x1="16.88862"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.172329,-1.111016)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1328"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="19.001091"
|
||||
x2="16.88862"
|
||||
y1="77.796608"
|
||||
x1="16.88862"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.172329,-1.111016)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1322-5"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="20.59322"
|
||||
x2="72.348671"
|
||||
y1="77.796608"
|
||||
x1="16.88862"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.172329,-1.111016)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1320-4"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="19.001091"
|
||||
x2="16.88862"
|
||||
y1="77.796608"
|
||||
x1="16.88862"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.052758,-16.66733)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1319-2"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="20.59322"
|
||||
x2="72.348671"
|
||||
y1="77.796608"
|
||||
x1="16.88862"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.052758,-16.66733)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1317-8"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="19.001091"
|
||||
x2="16.88862"
|
||||
y1="77.796608"
|
||||
x1="16.88862"
|
||||
gradientTransform="matrix(0.545166,0,0,0.544959,0.186963,35.29511)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1337-8"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="20.59322"
|
||||
x2="72.348671"
|
||||
y1="77.796608"
|
||||
x1="16.88862"
|
||||
gradientTransform="matrix(0.545166,0,0,0.544959,0.186963,35.29511)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1335-4"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
id="linearGradient2289-4">
|
||||
<stop
|
||||
id="stop2291-0"
|
||||
offset="0"
|
||||
style="stop-color:#ff2600;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop2293-9"
|
||||
offset="1"
|
||||
style="stop-color:#ffd600;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
id="linearGradient3133"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.51445624,0,0,0.53856587,7.3477348,6.9450134)"
|
||||
x1="46.881573"
|
||||
y1="91.824585"
|
||||
x2="47.225189"
|
||||
y2="1.5596932" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
id="linearGradient3136"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.51445624,0,0,0.53856587,-120.3871,-29.360443)"
|
||||
x1="16.88862"
|
||||
y1="77.796608"
|
||||
x2="72.348671"
|
||||
y2="20.59322" />
|
||||
<filter
|
||||
id="filter3138"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow">
|
||||
<feFlood
|
||||
id="feFlood3140"
|
||||
flood-opacity="0.33"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood" />
|
||||
<feComposite
|
||||
id="feComposite3142"
|
||||
in2="SourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3144"
|
||||
in="composite"
|
||||
stdDeviation="2"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3146"
|
||||
dx="4"
|
||||
dy="1"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3148"
|
||||
in2="offset"
|
||||
in="SourceGraphic"
|
||||
operator="over"
|
||||
result="composite2" />
|
||||
</filter>
|
||||
<filter
|
||||
id="filter3670"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow">
|
||||
<feFlood
|
||||
id="feFlood3672"
|
||||
flood-opacity="0.2"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood" />
|
||||
<feComposite
|
||||
id="feComposite3674"
|
||||
in2="SourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3676"
|
||||
in="composite"
|
||||
stdDeviation="1.5"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3678"
|
||||
dx="0"
|
||||
dy="4"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3680"
|
||||
in2="offset"
|
||||
in="SourceGraphic"
|
||||
operator="over"
|
||||
result="fbSourceGraphic" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix3682" />
|
||||
<feFlood
|
||||
id="feFlood3684"
|
||||
flood-opacity="0.2"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
in="fbSourceGraphic" />
|
||||
<feComposite
|
||||
id="feComposite3686"
|
||||
in2="fbSourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3688"
|
||||
in="composite"
|
||||
stdDeviation="1.5"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3690"
|
||||
dx="0"
|
||||
dy="2"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3692"
|
||||
in2="offset"
|
||||
in="fbSourceGraphic"
|
||||
operator="over"
|
||||
result="fbSourceGraphic" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix3706" />
|
||||
<feFlood
|
||||
id="feFlood3708"
|
||||
flood-opacity="0.2"
|
||||
flood-color="rgb(255,255,255)"
|
||||
result="flood"
|
||||
in="fbSourceGraphic" />
|
||||
<feComposite
|
||||
id="feComposite3710"
|
||||
in2="fbSourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3712"
|
||||
in="composite"
|
||||
stdDeviation="1"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3714"
|
||||
dx="0"
|
||||
dy="1"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3716"
|
||||
in2="offset"
|
||||
in="fbSourceGraphic"
|
||||
operator="over"
|
||||
result="fbSourceGraphic" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix3123" />
|
||||
<feFlood
|
||||
id="feFlood3125"
|
||||
flood-opacity="0.2"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
in="fbSourceGraphic" />
|
||||
<feComposite
|
||||
id="feComposite3127"
|
||||
in2="fbSourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3129"
|
||||
in="composite"
|
||||
stdDeviation="1"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3131"
|
||||
dx="0"
|
||||
dy="2"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3133"
|
||||
in2="offset"
|
||||
in="fbSourceGraphic"
|
||||
operator="over"
|
||||
result="composite2" />
|
||||
</filter>
|
||||
<filter
|
||||
id="filter3135"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow">
|
||||
<feFlood
|
||||
id="feFlood3137"
|
||||
flood-opacity="0.2"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood" />
|
||||
<feComposite
|
||||
id="feComposite3139"
|
||||
in2="SourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3141"
|
||||
in="composite"
|
||||
stdDeviation="1"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3143"
|
||||
dx="0"
|
||||
dy="1"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3145"
|
||||
in2="offset"
|
||||
in="SourceGraphic"
|
||||
operator="over"
|
||||
result="composite2" />
|
||||
</filter>
|
||||
<filter
|
||||
id="filter3183"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow">
|
||||
<feFlood
|
||||
id="feFlood3185"
|
||||
flood-opacity="0.3"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood" />
|
||||
<feComposite
|
||||
id="feComposite3187"
|
||||
in2="SourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3189"
|
||||
in="composite"
|
||||
stdDeviation="2"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3191"
|
||||
dx="0"
|
||||
dy="2"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3193"
|
||||
in2="offset"
|
||||
in="SourceGraphic"
|
||||
operator="over"
|
||||
result="composite2" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="7.9999999"
|
||||
inkscape:cx="61.011203"
|
||||
inkscape:cy="36.086679"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1270"
|
||||
inkscape:window-height="837"
|
||||
inkscape:window-x="287"
|
||||
inkscape:window-y="27"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:window-maximized="0">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3001" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
<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/" />
|
||||
<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:about="http://creativecommons.org/licenses/GPL/2.0/">
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/Distribution" />
|
||||
<cc:requires
|
||||
rdf:resource="http://web.resource.org/cc/Notice" />
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
|
||||
<cc:requires
|
||||
rdf:resource="http://web.resource.org/cc/ShareAlike" />
|
||||
<cc:requires
|
||||
rdf:resource="http://web.resource.org/cc/SourceCode" />
|
||||
</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" />
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<g
|
||||
id="g3663">
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;"
|
||||
d="m 31.404792,8.7464684 c -6.271873,0.05843 -12.553,0.431777 -13.735377,1.075609 C 15.304661,11.109737 4.1505773,29.32852 4.1783444,31.859522 c 0.02777,2.531005 11.5871596,20.543967 13.9796816,21.787309 2.392519,1.243342 25.106,1.037521 27.470753,-0.250141 C 47.993531,52.109028 59.147618,33.890246 59.119851,31.359242 59.092081,28.828238 47.532689,10.790262 45.140167,9.5469214 43.943907,8.9252504 37.676665,8.6880384 31.404792,8.7464684 z m 0.05429,4.5275596 c 4.90437,-0.047 9.786849,0.175368 10.722281,0.67538 1.870861,1.000021 10.917726,15.499216 10.939439,17.534904 C 53.142512,33.52 44.410541,48.158649 42.561393,49.194315 40.712245,50.229983 22.960549,50.419464 21.089689,49.419444 19.218826,48.419423 10.199106,33.920226 10.177392,31.884537 10.155682,29.84885 18.860508,15.185189 20.709656,14.14952 c 0.924575,-0.517833 5.845056,-0.828498 10.749425,-0.875492 z"
|
||||
id="path4107"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
transform="matrix(0.97890109,0,0,0.98965389,0.52623659,-1.3159842)"
|
||||
style="fill:#000000;fill-opacity:1;"
|
||||
d="M 31.801142,5.3887159 C 24.358829,5.4607629 16.905535,5.9211193 15.502506,6.7149966 12.696449,8.3027513 -0.53918189,30.767467 -0.50623228,33.888328 -0.47328049,37.00919 13.243292,59.220118 16.0823,60.753225 18.921305,62.286332 45.873514,62.032541 48.67957,60.444787 51.485627,58.857032 64.721258,36.392315 64.688309,33.271454 64.655357,30.150593 50.938784,7.9088218 48.099776,6.3757155 46.680274,5.6091623 39.243454,5.3166688 31.801142,5.3887159 z m 0.06442,5.5827171 c 5.81961,-0.05795 11.613244,0.216241 12.723243,0.83278 2.219996,1.233079 12.955163,19.111349 12.980929,21.621461 0.02577,2.51011 -10.335747,20.560333 -12.529979,21.837366 -2.19423,1.277031 -23.2587,1.510671 -25.478697,0.277592 C 17.341063,54.307554 6.638107,36.429283 6.6123418,33.919173 6.5865755,31.409062 16.915878,13.327995 19.110109,12.050964 20.207224,11.412447 26.045952,11.02938 31.865563,10.971433 z"
|
||||
id="path4103"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:transform-center-y="2.25"
|
||||
inkscape:transform-center-x="2.25"
|
||||
style="fill:url(#linearGradient3133);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.31593215000000008;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;"
|
||||
d="m 10.723737,18.285684 7.623916,-7.935243 13.238019,13.886676 12.492701,-13.886676 8.576909,7.935243 -14.294847,14.878584 13.341856,11.902864 -6.670928,6.94334 L 31.585672,39.351071 18.573785,52.010472 11.676724,45.086347 24.065591,33.164268 10.723737,18.285684 z"
|
||||
id="path2297"
|
||||
sodipodi:nodetypes="ccccccccccccc"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3305"
|
||||
d="M 31.293607,6.0952825 C 24.436514,6.1604875 17.569304,6.5771256 16.276601,7.2956116 13.691196,8.7325834 1.4963386,29.063913 1.5266972,31.888398 1.5570579,34.712884 14.195039,54.814527 16.810803,56.20204 19.426566,57.589553 44.25941,57.359866 46.844814,55.922894 49.430219,54.485922 61.625078,34.154591 61.594719,31.330106 61.564358,28.505621 48.926376,8.3760634 46.310612,6.9885506 45.002731,6.294794 38.150699,6.0300774 31.293607,6.0952825 z m 0.05936,5.0525485 c 5.36199,-0.05245 10.700046,0.195704 11.722761,0.753694 2.045429,1.115978 11.936445,17.296419 11.960184,19.568154 0.02374,2.271736 -9.523004,18.6078 -11.544693,19.763557 -2.02169,1.155758 -21.429773,1.36721 -23.475201,0.251232 C 17.970585,50.368491 8.1092472,34.188049 8.085508,31.916313 8.061768,29.644577 17.578834,13.2806 19.600523,12.124842 c 1.010846,-0.577879 6.39045,-0.924567 11.75244,-0.977011 z"
|
||||
style="fill:url(#linearGradient4101);fill-opacity:1;" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3077"
|
||||
d="M 14.640198,55.682743 C 9.6971439,47.360612 2.8950957,35.733851 2.9419881,35.686959 c 0.031272,-0.03127 0.5023581,0.289334 1.0468575,0.712459 0.5444994,0.423125 1.0414462,0.769317 1.1043264,0.769317 0.06288,0 2.6329414,4.276521 5.711247,9.50338 l 5.59692,9.503379 2.159128,0.007 2.159126,0.007 -0.34365,-0.584653 C 20.186937,55.28323 17.303514,50.518786 13.968339,45.017137 10.633164,39.515488 7.9043842,34.929294 7.9043842,34.825595 c 0,-0.103699 0.2455542,-0.59277 0.545676,-1.086823 0.3001218,-0.494053 0.545676,-0.941721 0.545676,-0.994816 0,-0.05309 -0.2788317,-0.09654 -0.619626,-0.09654 -0.8505388,0 -1.0953557,-0.488405 -1.0953557,-2.185211 0,-1.90734 -0.048411,-1.868066 2.30512,-1.870072 l 1.9823345,-0.0017 1.052375,-1.721616 c 0.578806,-0.94689 1.052375,-1.785869 1.052375,-1.8644 0,-0.07853 -0.829918,-0.162484 -1.844262,-0.186561 l -1.8442631,-0.04378 4.4809551,-7.327649 4.480953,-7.32765 12.466741,-0.0399 12.466738,-0.0399 0.517892,0.854518 0.517892,0.854518 2.335995,0.04287 2.335994,0.04287 2.742626,4.521316 c 1.508447,2.486723 4.136212,6.819001 5.839482,9.627283 1.703268,2.808283 3.157599,5.105969 3.231846,5.105969 0.256907,0 0.13186,-0.393635 -0.411085,-1.294044 -0.299901,-0.497351 -0.545275,-0.935841 -0.545275,-0.974422 0,-0.03858 0.310833,-0.07015 0.69074,-0.07015 0.575204,0 0.699074,-0.05324 0.740561,-0.318272 0.03599,-0.229934 0.273254,0.06215 0.854835,1.052375 0.702767,1.196557 0.780303,1.410253 0.610448,1.682462 -0.107012,0.171499 -0.377881,0.627528 -0.601929,1.013399 l -0.407361,0.701583 0.533953,0.857491 c 0.293674,0.47162 0.535536,0.950306 0.537472,1.063747 0.0019,0.113441 -3.098537,5.322698 -6.889942,11.576127 l -6.893462,11.36987 -16.876654,0 -16.876655,0 -1.226996,-2.065773 z"
|
||||
style="fill:none;" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 3.1 KiB |
@ -1,58 +1,746 @@
|
||||
<?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>
|
||||
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:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
sodipodi:docname="hexchat.svg"
|
||||
version="1.0"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:version="0.32"
|
||||
id="svg2"
|
||||
height="64"
|
||||
width="64">
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
id="linearGradient2289">
|
||||
<stop
|
||||
style="stop-color:#ff2600;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop2291" />
|
||||
<stop
|
||||
style="stop-color:#ffd600;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop2293" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient1335"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.545166,0,0,0.544959,0.186963,35.29511)"
|
||||
x1="16.88862"
|
||||
y1="77.796608"
|
||||
x2="72.348671"
|
||||
y2="20.59322" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient1337"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.545166,0,0,0.544959,0.186963,35.29511)"
|
||||
x1="16.88862"
|
||||
y1="77.796608"
|
||||
x2="16.88862"
|
||||
y2="19.001091" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient1317"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.052758,-16.66733)"
|
||||
x1="16.88862"
|
||||
y1="77.796608"
|
||||
x2="72.348671"
|
||||
y2="20.59322" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient1319"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.052758,-16.66733)"
|
||||
x1="16.88862"
|
||||
y1="77.796608"
|
||||
x2="16.88862"
|
||||
y2="19.001091" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient1320"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.172329,-1.111016)"
|
||||
x1="16.88862"
|
||||
y1="77.796608"
|
||||
x2="72.348671"
|
||||
y2="20.59322" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient1322"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.172329,-1.111016)"
|
||||
x1="16.88862"
|
||||
y1="77.796608"
|
||||
x2="16.88862"
|
||||
y2="19.001091" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient2997"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-160.10656,-7.1914058)"
|
||||
x1="130.2673"
|
||||
y1="78.743134"
|
||||
x2="129.2081"
|
||||
y2="25.771122" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient3011"
|
||||
x1="34.62241"
|
||||
y1="53.508884"
|
||||
x2="34.466503"
|
||||
y2="5.4893961"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient3030"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="34.62241"
|
||||
y1="53.508884"
|
||||
x2="34.466503"
|
||||
y2="5.4893961" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient3070"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="34.62241"
|
||||
y1="53.508884"
|
||||
x2="34.466503"
|
||||
y2="5.4893961"
|
||||
gradientTransform="matrix(0.99894925,0,0,0.97549134,-3.1829063,4.465557)" />
|
||||
<filter
|
||||
id="filter3281"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow">
|
||||
<feFlood
|
||||
id="feFlood3283"
|
||||
flood-opacity="0.33"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood" />
|
||||
<feComposite
|
||||
id="feComposite3285"
|
||||
in2="SourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3287"
|
||||
in="composite"
|
||||
stdDeviation="2"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3289"
|
||||
dx="4"
|
||||
dy="1"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3291"
|
||||
in2="offset"
|
||||
in="SourceGraphic"
|
||||
operator="over"
|
||||
result="composite2" />
|
||||
</filter>
|
||||
<filter
|
||||
id="filter3293"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow">
|
||||
<feFlood
|
||||
id="feFlood3295"
|
||||
flood-opacity="0.33"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood" />
|
||||
<feComposite
|
||||
id="feComposite3297"
|
||||
in2="SourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3299"
|
||||
in="composite"
|
||||
stdDeviation="2"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3301"
|
||||
dx="4"
|
||||
dy="1"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3303"
|
||||
in2="offset"
|
||||
in="SourceGraphic"
|
||||
operator="over"
|
||||
result="composite2" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient4089"
|
||||
x1="99.348503"
|
||||
y1="59.934135"
|
||||
x2="100.40916"
|
||||
y2="10.613438"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient4093"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="99.348503"
|
||||
y1="59.934135"
|
||||
x2="100.40916"
|
||||
y2="10.613438" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient4096"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="99.348503"
|
||||
y1="59.934135"
|
||||
x2="100.40916"
|
||||
y2="10.613438" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289"
|
||||
id="linearGradient4098"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="99.348503"
|
||||
y1="59.934135"
|
||||
x2="100.40916"
|
||||
y2="10.613438"
|
||||
gradientTransform="translate(-70.003571,-2.298097)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
id="linearGradient4101"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.94969205,0,0,0.89326813,1.6716955,2.7025635)"
|
||||
x1="31.372862"
|
||||
y1="60.111893"
|
||||
x2="31.559002"
|
||||
y2="5.6897221" />
|
||||
<filter
|
||||
id="filter4111"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow">
|
||||
<feFlood
|
||||
id="feFlood4113"
|
||||
flood-opacity="0.33"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood" />
|
||||
<feComposite
|
||||
id="feComposite4115"
|
||||
in2="SourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur4117"
|
||||
in="composite"
|
||||
stdDeviation="2"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset4119"
|
||||
dx="4"
|
||||
dy="1"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite4121"
|
||||
in2="offset"
|
||||
in="SourceGraphic"
|
||||
operator="over"
|
||||
result="composite2" />
|
||||
</filter>
|
||||
<filter
|
||||
id="filter4123"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow">
|
||||
<feFlood
|
||||
id="feFlood4125"
|
||||
flood-opacity="0.33"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood" />
|
||||
<feComposite
|
||||
id="feComposite4127"
|
||||
in2="SourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur4129"
|
||||
in="composite"
|
||||
stdDeviation="2"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset4131"
|
||||
dx="4"
|
||||
dy="1"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite4133"
|
||||
in2="offset"
|
||||
in="SourceGraphic"
|
||||
operator="over"
|
||||
result="composite2" />
|
||||
</filter>
|
||||
<linearGradient
|
||||
y2="19.001091"
|
||||
x2="16.88862"
|
||||
y1="77.796608"
|
||||
x1="16.88862"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.172329,-1.111016)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1330"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="20.59322"
|
||||
x2="72.348671"
|
||||
y1="77.796608"
|
||||
x1="16.88862"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.172329,-1.111016)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1328"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="19.001091"
|
||||
x2="16.88862"
|
||||
y1="77.796608"
|
||||
x1="16.88862"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.172329,-1.111016)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1322-5"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="20.59322"
|
||||
x2="72.348671"
|
||||
y1="77.796608"
|
||||
x1="16.88862"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.172329,-1.111016)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1320-4"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="19.001091"
|
||||
x2="16.88862"
|
||||
y1="77.796608"
|
||||
x1="16.88862"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.052758,-16.66733)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1319-2"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="20.59322"
|
||||
x2="72.348671"
|
||||
y1="77.796608"
|
||||
x1="16.88862"
|
||||
gradientTransform="matrix(0.735969,0,0,0.735801,-2.052758,-16.66733)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1317-8"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="19.001091"
|
||||
x2="16.88862"
|
||||
y1="77.796608"
|
||||
x1="16.88862"
|
||||
gradientTransform="matrix(0.545166,0,0,0.544959,0.186963,35.29511)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1337-8"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
y2="20.59322"
|
||||
x2="72.348671"
|
||||
y1="77.796608"
|
||||
x1="16.88862"
|
||||
gradientTransform="matrix(0.545166,0,0,0.544959,0.186963,35.29511)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="linearGradient1335-4"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
inkscape:collect="always" />
|
||||
<linearGradient
|
||||
id="linearGradient2289-4">
|
||||
<stop
|
||||
id="stop2291-0"
|
||||
offset="0"
|
||||
style="stop-color:#ff2600;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop2293-9"
|
||||
offset="1"
|
||||
style="stop-color:#ffd600;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
id="linearGradient3133"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.51445624,0,0,0.53856587,7.3477348,6.9450134)"
|
||||
x1="46.881573"
|
||||
y1="91.824585"
|
||||
x2="47.225189"
|
||||
y2="1.5596932" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2289-4"
|
||||
id="linearGradient3136"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.51445624,0,0,0.53856587,-120.3871,-29.360443)"
|
||||
x1="16.88862"
|
||||
y1="77.796608"
|
||||
x2="72.348671"
|
||||
y2="20.59322" />
|
||||
<filter
|
||||
id="filter3138"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow">
|
||||
<feFlood
|
||||
id="feFlood3140"
|
||||
flood-opacity="0.33"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood" />
|
||||
<feComposite
|
||||
id="feComposite3142"
|
||||
in2="SourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3144"
|
||||
in="composite"
|
||||
stdDeviation="2"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3146"
|
||||
dx="4"
|
||||
dy="1"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3148"
|
||||
in2="offset"
|
||||
in="SourceGraphic"
|
||||
operator="over"
|
||||
result="composite2" />
|
||||
</filter>
|
||||
<filter
|
||||
id="filter3670"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow">
|
||||
<feFlood
|
||||
id="feFlood3672"
|
||||
flood-opacity="0.2"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood" />
|
||||
<feComposite
|
||||
id="feComposite3674"
|
||||
in2="SourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3676"
|
||||
in="composite"
|
||||
stdDeviation="1.5"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3678"
|
||||
dx="0"
|
||||
dy="4"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3680"
|
||||
in2="offset"
|
||||
in="SourceGraphic"
|
||||
operator="over"
|
||||
result="fbSourceGraphic" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix3682" />
|
||||
<feFlood
|
||||
id="feFlood3684"
|
||||
flood-opacity="0.2"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
in="fbSourceGraphic" />
|
||||
<feComposite
|
||||
id="feComposite3686"
|
||||
in2="fbSourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3688"
|
||||
in="composite"
|
||||
stdDeviation="1.5"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3690"
|
||||
dx="0"
|
||||
dy="2"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3692"
|
||||
in2="offset"
|
||||
in="fbSourceGraphic"
|
||||
operator="over"
|
||||
result="fbSourceGraphic" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix3706" />
|
||||
<feFlood
|
||||
id="feFlood3708"
|
||||
flood-opacity="0.2"
|
||||
flood-color="rgb(255,255,255)"
|
||||
result="flood"
|
||||
in="fbSourceGraphic" />
|
||||
<feComposite
|
||||
id="feComposite3710"
|
||||
in2="fbSourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3712"
|
||||
in="composite"
|
||||
stdDeviation="1"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3714"
|
||||
dx="0"
|
||||
dy="1"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3716"
|
||||
in2="offset"
|
||||
in="fbSourceGraphic"
|
||||
operator="over"
|
||||
result="fbSourceGraphic" />
|
||||
<feColorMatrix
|
||||
result="fbSourceGraphicAlpha"
|
||||
in="fbSourceGraphic"
|
||||
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
|
||||
id="feColorMatrix3123" />
|
||||
<feFlood
|
||||
id="feFlood3125"
|
||||
flood-opacity="0.2"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood"
|
||||
in="fbSourceGraphic" />
|
||||
<feComposite
|
||||
id="feComposite3127"
|
||||
in2="fbSourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3129"
|
||||
in="composite"
|
||||
stdDeviation="1"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3131"
|
||||
dx="0"
|
||||
dy="2"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3133"
|
||||
in2="offset"
|
||||
in="fbSourceGraphic"
|
||||
operator="over"
|
||||
result="composite2" />
|
||||
</filter>
|
||||
<filter
|
||||
id="filter3135"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow">
|
||||
<feFlood
|
||||
id="feFlood3137"
|
||||
flood-opacity="0.2"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood" />
|
||||
<feComposite
|
||||
id="feComposite3139"
|
||||
in2="SourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3141"
|
||||
in="composite"
|
||||
stdDeviation="1"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3143"
|
||||
dx="0"
|
||||
dy="1"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3145"
|
||||
in2="offset"
|
||||
in="SourceGraphic"
|
||||
operator="over"
|
||||
result="composite2" />
|
||||
</filter>
|
||||
<filter
|
||||
id="filter3183"
|
||||
style="color-interpolation-filters:sRGB;"
|
||||
inkscape:label="Drop Shadow">
|
||||
<feFlood
|
||||
id="feFlood3185"
|
||||
flood-opacity="0.3"
|
||||
flood-color="rgb(0,0,0)"
|
||||
result="flood" />
|
||||
<feComposite
|
||||
id="feComposite3187"
|
||||
in2="SourceGraphic"
|
||||
in="flood"
|
||||
operator="in"
|
||||
result="composite1" />
|
||||
<feGaussianBlur
|
||||
id="feGaussianBlur3189"
|
||||
in="composite"
|
||||
stdDeviation="2"
|
||||
result="blur" />
|
||||
<feOffset
|
||||
id="feOffset3191"
|
||||
dx="0"
|
||||
dy="2"
|
||||
result="offset" />
|
||||
<feComposite
|
||||
id="feComposite3193"
|
||||
in2="offset"
|
||||
in="SourceGraphic"
|
||||
operator="over"
|
||||
result="composite2" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="7.9999999"
|
||||
inkscape:cx="60.761203"
|
||||
inkscape:cy="36.086679"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1270"
|
||||
inkscape:window-height="837"
|
||||
inkscape:window-x="287"
|
||||
inkscape:window-y="27"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:window-maximized="0">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3001" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
<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/" />
|
||||
<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:about="http://creativecommons.org/licenses/GPL/2.0/">
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/Distribution" />
|
||||
<cc:requires
|
||||
rdf:resource="http://web.resource.org/cc/Notice" />
|
||||
<cc:permits
|
||||
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
|
||||
<cc:requires
|
||||
rdf:resource="http://web.resource.org/cc/ShareAlike" />
|
||||
<cc:requires
|
||||
rdf:resource="http://web.resource.org/cc/SourceCode" />
|
||||
</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" />
|
||||
<g
|
||||
inkscape:label="Calque 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<g
|
||||
id="g3663"
|
||||
style="filter:url(#filter3183)">
|
||||
<path
|
||||
style="fill:#000000;fill-opacity:1;"
|
||||
d="m 31.404792,8.7464684 c -6.271873,0.05843 -12.553,0.431777 -13.735377,1.075609 C 15.304661,11.109737 4.1505773,29.32852 4.1783444,31.859522 c 0.02777,2.531005 11.5871596,20.543967 13.9796816,21.787309 2.392519,1.243342 25.106,1.037521 27.470753,-0.250141 C 47.993531,52.109028 59.147618,33.890246 59.119851,31.359242 59.092081,28.828238 47.532689,10.790262 45.140167,9.5469214 43.943907,8.9252504 37.676665,8.6880384 31.404792,8.7464684 z m 0.05429,4.5275596 c 4.90437,-0.047 9.786849,0.175368 10.722281,0.67538 1.870861,1.000021 10.917726,15.499216 10.939439,17.534904 C 53.142512,33.52 44.410541,48.158649 42.561393,49.194315 40.712245,50.229983 22.960549,50.419464 21.089689,49.419444 19.218826,48.419423 10.199106,33.920226 10.177392,31.884537 10.155682,29.84885 18.860508,15.185189 20.709656,14.14952 c 0.924575,-0.517833 5.845056,-0.828498 10.749425,-0.875492 z"
|
||||
id="path4107"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
transform="matrix(0.97890109,0,0,0.98965389,0.52623659,-1.3159842)"
|
||||
style="fill:#000000;fill-opacity:1;"
|
||||
d="M 31.801142,5.3887159 C 24.358829,5.4607629 16.905535,5.9211193 15.502506,6.7149966 12.696449,8.3027513 -0.53918189,30.767467 -0.50623228,33.888328 -0.47328049,37.00919 13.243292,59.220118 16.0823,60.753225 18.921305,62.286332 45.873514,62.032541 48.67957,60.444787 51.485627,58.857032 64.721258,36.392315 64.688309,33.271454 64.655357,30.150593 50.938784,7.9088218 48.099776,6.3757155 46.680274,5.6091623 39.243454,5.3166688 31.801142,5.3887159 z m 0.06442,5.5827171 c 5.81961,-0.05795 11.613244,0.216241 12.723243,0.83278 2.219996,1.233079 12.955163,19.111349 12.980929,21.621461 0.02577,2.51011 -10.335747,20.560333 -12.529979,21.837366 -2.19423,1.277031 -23.2587,1.510671 -25.478697,0.277592 C 17.341063,54.307554 6.638107,36.429283 6.6123418,33.919173 6.5865755,31.409062 16.915878,13.327995 19.110109,12.050964 20.207224,11.412447 26.045952,11.02938 31.865563,10.971433 z"
|
||||
id="path4103"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:transform-center-y="2.25"
|
||||
inkscape:transform-center-x="2.25"
|
||||
style="fill:url(#linearGradient3133);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.31593215000000008;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;"
|
||||
d="m 10.723737,18.285684 7.623916,-7.935243 13.238019,13.886676 12.492701,-13.886676 8.576909,7.935243 -14.294847,14.878584 13.341856,11.902864 -6.670928,6.94334 L 31.585672,39.351071 18.573785,52.010472 11.676724,45.086347 24.065591,33.164268 10.723737,18.285684 z"
|
||||
id="path2297"
|
||||
sodipodi:nodetypes="ccccccccccccc"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3305"
|
||||
d="M 31.293607,6.0952825 C 24.436514,6.1604875 17.569304,6.5771256 16.276601,7.2956116 13.691196,8.7325834 1.4963386,29.063913 1.5266972,31.888398 1.5570579,34.712884 14.195039,54.814527 16.810803,56.20204 19.426566,57.589553 44.25941,57.359866 46.844814,55.922894 49.430219,54.485922 61.625078,34.154591 61.594719,31.330106 61.564358,28.505621 48.926376,8.3760634 46.310612,6.9885506 45.002731,6.294794 38.150699,6.0300774 31.293607,6.0952825 z m 0.05936,5.0525485 c 5.36199,-0.05245 10.700046,0.195704 11.722761,0.753694 2.045429,1.115978 11.936445,17.296419 11.960184,19.568154 0.02374,2.271736 -9.523004,18.6078 -11.544693,19.763557 -2.02169,1.155758 -21.429773,1.36721 -23.475201,0.251232 C 17.970585,50.368491 8.1092472,34.188049 8.085508,31.916313 8.061768,29.644577 17.578834,13.2806 19.600523,12.124842 c 1.010846,-0.577879 6.39045,-0.924567 11.75244,-0.977011 z"
|
||||
style="fill:url(#linearGradient4101);fill-opacity:1;" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3077"
|
||||
d="M 14.640198,55.682743 C 9.6971439,47.360612 2.8950957,35.733851 2.9419881,35.686959 c 0.031272,-0.03127 0.5023581,0.289334 1.0468575,0.712459 0.5444994,0.423125 1.0414462,0.769317 1.1043264,0.769317 0.06288,0 2.6329414,4.276521 5.711247,9.50338 l 5.59692,9.503379 2.159128,0.007 2.159126,0.007 -0.34365,-0.584653 C 20.186937,55.28323 17.303514,50.518786 13.968339,45.017137 10.633164,39.515488 7.9043842,34.929294 7.9043842,34.825595 c 0,-0.103699 0.2455542,-0.59277 0.545676,-1.086823 0.3001218,-0.494053 0.545676,-0.941721 0.545676,-0.994816 0,-0.05309 -0.2788317,-0.09654 -0.619626,-0.09654 -0.8505388,0 -1.0953557,-0.488405 -1.0953557,-2.185211 0,-1.90734 -0.048411,-1.868066 2.30512,-1.870072 l 1.9823345,-0.0017 1.052375,-1.721616 c 0.578806,-0.94689 1.052375,-1.785869 1.052375,-1.8644 0,-0.07853 -0.829918,-0.162484 -1.844262,-0.186561 l -1.8442631,-0.04378 4.4809551,-7.327649 4.480953,-7.32765 12.466741,-0.0399 12.466738,-0.0399 0.517892,0.854518 0.517892,0.854518 2.335995,0.04287 2.335994,0.04287 2.742626,4.521316 c 1.508447,2.486723 4.136212,6.819001 5.839482,9.627283 1.703268,2.808283 3.157599,5.105969 3.231846,5.105969 0.256907,0 0.13186,-0.393635 -0.411085,-1.294044 -0.299901,-0.497351 -0.545275,-0.935841 -0.545275,-0.974422 0,-0.03858 0.310833,-0.07015 0.69074,-0.07015 0.575204,0 0.699074,-0.05324 0.740561,-0.318272 0.03599,-0.229934 0.273254,0.06215 0.854835,1.052375 0.702767,1.196557 0.780303,1.410253 0.610448,1.682462 -0.107012,0.171499 -0.377881,0.627528 -0.601929,1.013399 l -0.407361,0.701583 0.533953,0.857491 c 0.293674,0.47162 0.535536,0.950306 0.537472,1.063747 0.0019,0.113441 -3.098537,5.322698 -6.889942,11.576127 l -6.893462,11.36987 -16.876654,0 -16.876655,0 -1.226996,-2.065773 z"
|
||||
style="fill:none;" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 26 KiB |
@ -1,11 +0,0 @@
|
||||
icondir = join_paths(get_option('datadir'), 'icons/hicolor')
|
||||
install_data(
|
||||
'hexchat.png',
|
||||
rename: 'io.github.Hexchat.png',
|
||||
install_dir: join_paths(icondir, '48x48/apps')
|
||||
)
|
||||
install_data(
|
||||
'hexchat.svg',
|
||||
rename: 'io.github.Hexchat.svg',
|
||||
install_dir: join_paths(icondir, 'scalable/apps')
|
||||
)
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 5.0 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 4.7 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 4.6 KiB |
3
data/man/Makefile.am
Normal file
@ -0,0 +1,3 @@
|
||||
man_MANS = hexchat.1
|
||||
|
||||
EXTRA_DIST = hexchat.1.in
|
@ -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')
|
||||
)
|
@ -1,11 +0,0 @@
|
||||
if get_option('plugin')
|
||||
subdir('pkgconfig')
|
||||
endif
|
||||
|
||||
if get_option('gtk-frontend')
|
||||
subdir('icons')
|
||||
subdir('misc')
|
||||
subdir('man')
|
||||
elif get_option('theme-manager')
|
||||
subdir('misc')
|
||||
endif
|
29
data/misc/Makefile.am
Normal file
@ -0,0 +1,29 @@
|
||||
appdata_in_files = hexchat.appdata.xml.in
|
||||
appdata_DATA = $(appdata_in_files:.xml.in=.xml)
|
||||
appdatadir = $(datadir)/appdata
|
||||
@INTLTOOL_XML_RULE@
|
||||
|
||||
data_desktopdir = $(datadir)/applications
|
||||
data_desktop_in_files = hexchat.desktop.in
|
||||
|
||||
if WITH_TM
|
||||
data_desktop_in_files += htm.desktop.in
|
||||
mime_DATA = htm-mime.xml
|
||||
mimedir = $(datadir)/mime/packages
|
||||
endif
|
||||
|
||||
data_desktop_DATA = $(data_desktop_in_files:.desktop.in=.desktop)
|
||||
@INTLTOOL_DESKTOP_RULE@
|
||||
|
||||
UPDATE_MIME_DATABASE = update-mime-database "$(datadir)/mime" || :
|
||||
UPDATE_DESKTOP_DATABASE = update-desktop-database -q "$(datadir)/applications" || :
|
||||
|
||||
install-data-hook:
|
||||
$(UPDATE_MIME_DATABASE);
|
||||
$(UPDATE_DESKTOP_DATABASE);
|
||||
|
||||
uninstall-hook:
|
||||
$(UPDATE_MIME_DATABASE);
|
||||
$(UPDATE_DESKTOP_DATABASE);
|
||||
|
||||
CLEANFILES = $(appdata_DATA) $(data_desktop_DATA)
|
15
data/misc/hexchat.appdata.xml.in
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<application>
|
||||
<id type="desktop">hexchat.desktop</id>
|
||||
<licence>CC0</licence>
|
||||
<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>
|
||||
<screenshots>
|
||||
<screenshot type="default">http://i.imgur.com/XBbQKXf.png</screenshot>
|
||||
</screenshots>
|
||||
<updatecontact>tingping_at_fedoraproject.org</updatecontact>
|
||||
</application>
|
||||
|
@ -1,19 +1,18 @@
|
||||
[Desktop Entry]
|
||||
Name=HexChat
|
||||
GenericName=IRC Client
|
||||
Comment=Chat with other people online
|
||||
Keywords=IM;Chat;
|
||||
Exec=@exec_command@
|
||||
Icon=io.github.Hexchat
|
||||
_Name=HexChat
|
||||
_GenericName=IRC Client
|
||||
_Comment=Chat with other people online
|
||||
_Keywords=IM;Chat;
|
||||
Exec=hexchat %U
|
||||
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
|
||||
_Name=Open Safe Mode
|
||||
Exec=hexchat --no-auto --no-plugins
|
@ -1,5 +1,5 @@
|
||||
[Desktop Entry]
|
||||
Name=HexChat Theme Manager
|
||||
_Name=HexChat Theme Manager
|
||||
Exec=thememan %f
|
||||
Icon=hexchat
|
||||
Terminal=false
|
@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="addon">
|
||||
<id>io.github.Hexchat.Plugin.@NAME@</id>
|
||||
<extends>io.github.Hexchat</extends>
|
||||
<name>@NAME@ Plugin</name>
|
||||
<summary>@SUMMARY@</summary>
|
||||
<url type="homepage">https://hexchat.github.io/</url>
|
||||
<project_license>@LICENSE@</project_license>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<update_contact>tingping_AT_fedoraproject.org</update_contact>
|
||||
</component>
|
@ -1,151 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop-application">
|
||||
<id>io.github.Hexchat</id>
|
||||
<name>HexChat</name>
|
||||
<launchable type="desktop-id">io.github.Hexchat.desktop</launchable>
|
||||
<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="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="2022-02-12" version="2.16.1">
|
||||
<description>
|
||||
<p>This is a minor release with mostly bug-fixes:</p>
|
||||
<ul>
|
||||
<li>Add `-NOOVERRIDE` flag to the `GUI COLOR` command</li>
|
||||
<li>Add `-q` (quiet) flag to the `EXECWRITE` command</li>
|
||||
<li>Rename installed icon to match app-id (Fixes notification icon)</li>
|
||||
<li>Fix escaping already escaped URLs when opening them</li>
|
||||
<li>Fix Python scripts not being opened as UTF-8</li>
|
||||
<li>Fix `TIMER` command supporting decimals regardless of locale</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release date="2021-10-01" version="2.16.0">
|
||||
<description>
|
||||
<p>This is a feature release:</p>
|
||||
<ul>
|
||||
<li>Add support for IRCv3 SETNAME, invite-notify, account-tag, standard replies, and UTF8ONLY</li>
|
||||
<li>Add support for strikethrough formatting</li>
|
||||
<li>Fix text clipping issues by respecting font line height</li>
|
||||
<li>Fix URLs not being escaped when opened</li>
|
||||
<li>Fix possible hang when showing notifications</li>
|
||||
<li>Print ChanServ notices in the front tab by default</li>
|
||||
<li>Update network list</li>
|
||||
<li>python: Rewrite plugin improving memory usage and compatibility</li>
|
||||
<li>fishlim: Add support for CBC and other improvements</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release date="2019-12-20" version="2.14.3">
|
||||
<description>
|
||||
<p>This is a bug-fix release:</p>
|
||||
<ul>
|
||||
<li>Fix various incorrect parsing of IRC messages relating to trailing parameters</li>
|
||||
<li>Fix SASL negotiation combined with multi-line cap</li>
|
||||
<li>Fix input box theming with Yaru theme</li>
|
||||
<li>python: Work around Python 3.7 regression causing crash on unload</li>
|
||||
<li>sysinfo: Add support for /etc/os-release</li>
|
||||
<li>sysinfo: Ignore irrelevant mounts when calculating storage size</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release date="2018-08-29" version="2.14.2">
|
||||
<description>
|
||||
<p>This is a minor release:</p>
|
||||
<ul>
|
||||
<li>Remove shift+click to close tab binding</li>
|
||||
<li>Always unminimize when opening from tray</li>
|
||||
<li>Fix some translations containing invalid text events</li>
|
||||
<li>Fix sending server passwords starting with ":"</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release date="2018-03-13" version="2.14.1">
|
||||
<description>
|
||||
<p>This is a very minor bug-fix release:</p>
|
||||
<ul>
|
||||
<li>Fix performance regression</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<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>
|
||||
<content_rating type="oars-1.1">
|
||||
<content_attribute id="social-chat">intense</content_attribute>
|
||||
</content_rating>
|
||||
<update_contact>tingping_at_fedoraproject.org</update_contact>
|
||||
</component>
|
@ -1,127 +0,0 @@
|
||||
appdir = join_paths(get_option('datadir'), 'applications')
|
||||
metainfodir = join_paths(get_option('datadir'), 'metainfo')
|
||||
desktop_utils = find_program('desktop-file-validate', required: false)
|
||||
|
||||
if get_option('gtk-frontend')
|
||||
if get_option('install-appdata')
|
||||
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: metainfodir
|
||||
)
|
||||
|
||||
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
|
||||
endif
|
||||
|
||||
desktop_conf = configuration_data()
|
||||
if dbus_glib_dep.found()
|
||||
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('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
|
||||
|
||||
if get_option('plugin')
|
||||
plugin_metainfo = []
|
||||
|
||||
# FIXME: These should all get translated somewhere
|
||||
if get_option('with-checksum')
|
||||
plugin_metainfo += [
|
||||
['Checksum', 'Calculates a checksum for all sent and recieved DCC files', 'MIT']
|
||||
]
|
||||
endif
|
||||
|
||||
if get_option('with-fishlim')
|
||||
plugin_metainfo += [
|
||||
['Fishlim', 'Allows setting a key for encrypted conversations', 'MIT AND GPL-2.0+']
|
||||
]
|
||||
endif
|
||||
|
||||
if get_option('with-lua') != 'false'
|
||||
plugin_metainfo += [
|
||||
['Lua', 'Provides a scripting interface in Lua', 'MIT']
|
||||
]
|
||||
endif
|
||||
|
||||
if get_option('with-perl') != 'false'
|
||||
plugin_metainfo += [
|
||||
['Perl', 'Provides a scripting interface in Perl', 'GPL-2.0+']
|
||||
]
|
||||
endif
|
||||
|
||||
if get_option('with-python') != 'false'
|
||||
plugin_metainfo += [
|
||||
['Python', 'Provides a scripting interface in Python', 'GPL-2.0+']
|
||||
]
|
||||
endif
|
||||
|
||||
if get_option('with-sysinfo')
|
||||
plugin_metainfo += [
|
||||
['Sysinfo', 'Adds command to display system information', 'GPL-2.0+']
|
||||
]
|
||||
endif
|
||||
|
||||
foreach metainfo : plugin_metainfo
|
||||
name = metainfo[0]
|
||||
conf = configuration_data()
|
||||
conf.set('NAME', name)
|
||||
conf.set('SUMMARY', metainfo[1])
|
||||
conf.set('LICENSE', metainfo[2])
|
||||
|
||||
configure_file(
|
||||
input: 'io.github.Hexchat.Plugin.metainfo.xml.in',
|
||||
output: 'io.github.Hexchat.Plugin.@0@.metainfo.xml'.format(name),
|
||||
configuration: conf,
|
||||
install_dir: get_option('install-plugin-metainfo') ? metainfodir : '',
|
||||
)
|
||||
endforeach
|
||||
endif
|
4
data/pkgconfig/Makefile.am
Normal file
@ -0,0 +1,4 @@
|
||||
pkgcfgdir = $(pkgconfigdir)
|
||||
pkgcfg_DATA = hexchat-plugin.pc
|
||||
|
||||
EXTRA_DIST = hexchat-plugin.pc.in
|
@ -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'),
|
||||
)
|
@ -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,25 +0,0 @@
|
||||
From 918503d57c6740d20be68a6717158673a2a8b25f Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Griffis <tingping@tingping.se>
|
||||
Date: Sat, 17 Mar 2018 05:57:49 -0400
|
||||
Subject: [PATCH] Support loading Flatpak extensions
|
||||
|
||||
---
|
||||
src/common/plugin.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/src/common/plugin.c b/src/common/plugin.c
|
||||
index 3ad3c558..6addf962 100644
|
||||
--- a/src/common/plugin.c
|
||||
+++ b/src/common/plugin.c
|
||||
@@ -450,6 +450,8 @@ plugin_auto_load (session *sess)
|
||||
lib_dir = plugin_get_libdir ();
|
||||
sub_dir = g_build_filename (get_xdir (), "addons", NULL);
|
||||
|
||||
+ for_files ("/app/extensions/lib/hexchat/plugins", "*.so", plugin_auto_load_cb);
|
||||
+
|
||||
#ifdef WIN32
|
||||
/* a long list of bundled plugins that should be loaded automatically,
|
||||
* user plugins should go to <config>, leave Program Files alone! */
|
||||
--
|
||||
2.14.3
|
||||
|
@ -1,78 +0,0 @@
|
||||
{
|
||||
"app-id": "io.github.Hexchat",
|
||||
"branch": "stable",
|
||||
"runtime": "org.gnome.Platform",
|
||||
"runtime-version": "40",
|
||||
"sdk": "org.gnome.Sdk",
|
||||
"command": "hexchat",
|
||||
"finish-args": [
|
||||
"--share=ipc",
|
||||
"--socket=x11",
|
||||
"--share=network",
|
||||
"--socket=pulseaudio",
|
||||
"--filesystem=xdg-download",
|
||||
|
||||
"--talk-name=org.freedesktop.Notifications",
|
||||
|
||||
"--talk-name=org.mpris.MediaPlayer2.*"
|
||||
],
|
||||
"add-extensions": {
|
||||
"io.github.Hexchat.Plugin": {
|
||||
"version": "20.08",
|
||||
"directory": "extensions",
|
||||
"add-ld-path": "lib",
|
||||
"merge-dirs": "lib/hexchat/plugins",
|
||||
"subdirectories": true,
|
||||
"no-autodownload": true,
|
||||
"autodelete": true
|
||||
}
|
||||
},
|
||||
"modules": [
|
||||
"shared-modules/gtk2/gtk2.json",
|
||||
"shared-modules/gtk2/gtk2-common-themes.json",
|
||||
"shared-modules/dbus-glib/dbus-glib.json",
|
||||
"shared-modules/lua5.3/lua-5.3.5.json",
|
||||
"shared-modules/libcanberra/libcanberra.json",
|
||||
"python3-cffi.json",
|
||||
{
|
||||
"name": "lgi",
|
||||
"buildsystem": "meson",
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/pavouk/lgi.git",
|
||||
"commit": "95418635aa8151a516d43166227ea2b9d4c4403f"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "hexchat",
|
||||
"buildsystem": "meson",
|
||||
"config-opts": [
|
||||
"--buildtype=release",
|
||||
"-Ddbus-service-use-appid=true",
|
||||
"-Dwith-perl=false",
|
||||
"-Dwith-lua=lua"
|
||||
],
|
||||
"build-options": {
|
||||
"cflags": "-Wno-error=missing-include-dirs"
|
||||
},
|
||||
"cleanup": [
|
||||
"/share/man"
|
||||
],
|
||||
"post-install": [
|
||||
"install -d /app/extensions"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "dir",
|
||||
"path": ".."
|
||||
},
|
||||
{
|
||||
"type": "patch",
|
||||
"path": "Load-plugins-from-Flatpak-extensions.patch"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
{
|
||||
"name": "python3-cffi",
|
||||
"buildsystem": "simple",
|
||||
"build-commands": [
|
||||
"pip3 install --verbose --exists-action=i --no-index --find-links=\"file://${PWD}\" --prefix=${FLATPAK_DEST} \"cffi\" --no-build-isolation"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/0f/86/e19659527668d70be91d0369aeaa055b4eb396b0f387a4f92293a20035bd/pycparser-2.20.tar.gz",
|
||||
"sha256": "2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"
|
||||
},
|
||||
{
|
||||
"type": "file",
|
||||
"url": "https://files.pythonhosted.org/packages/a8/20/025f59f929bbcaa579704f443a438135918484fffaacfaddba776b374563/cffi-1.14.5.tar.gz",
|
||||
"sha256": "fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"
|
||||
}
|
||||
]
|
||||
}
|
@ -1 +0,0 @@
|
||||
Subproject commit 2c2f8fef2e926ff03158c0b3341526cce1b405ac
|
40
m4/as-ac-expand.m4
Normal 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
|
||||
])
|
8
m4/clang-analyze.am
Normal file
@ -0,0 +1,8 @@
|
||||
analysis_verbose = $(analysis_verbose_$(V))
|
||||
analysis_verbose_ = $(analysis_verbose_$(AM_DEFAULT_VERBOSITY))
|
||||
analysis_verbose_0 = @echo " CCSA " $@; $(COMPILE) --analyze $< -o $@;
|
||||
analysis_verbose_1 = $(COMPILE) --analyze $< -o $@;
|
||||
|
||||
%.plist: %.c
|
||||
$(analysis_verbose)
|
||||
|
197
meson.build
@ -1,197 +0,0 @@
|
||||
project('hexchat', 'c',
|
||||
version: '2.16.1',
|
||||
meson_version: '>= 0.47.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')
|
||||
|
||||
libcanberra_dep = dependency('libcanberra', version: '>= 0.22',
|
||||
required: get_option('libcanberra'))
|
||||
dbus_glib_dep = dependency('dbus-glib-1', required: get_option('dbus'))
|
||||
|
||||
global_deps = []
|
||||
if cc.get_id() == 'msvc'
|
||||
libssl_dep = cc.find_library('libssl')
|
||||
else
|
||||
libssl_dep = dependency('openssl', version: '>= 0.9.8',
|
||||
required: get_option('tls'))
|
||||
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.set_quoted('G_LOG_DOMAIN', 'hexchat')
|
||||
config_h.set10('ENABLE_NLS', true)
|
||||
|
||||
# Optional features
|
||||
config_h.set('USE_OPENSSL', libssl_dep.found())
|
||||
config_h.set('USE_LIBCANBERRA', libcanberra_dep.found())
|
||||
config_h.set('USE_DBUS', dbus_glib_dep.found())
|
||||
config_h.set('USE_PLUGIN', get_option('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'))
|
||||
|
||||
config_h.set_quoted('HEXCHATLIBDIR',
|
||||
join_paths(get_option('prefix'), get_option('libdir'), 'hexchat/plugins')
|
||||
)
|
||||
|
||||
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 = [
|
||||
'-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',
|
||||
# mingw
|
||||
'-Wl,--nxcompat',
|
||||
]
|
||||
if not (host_machine.system() == 'windows' and get_option('debug'))
|
||||
test_ldflags += '-Wl,--dynamicbase'
|
||||
endif
|
||||
foreach ldflag : test_ldflags
|
||||
if meson.version().version_compare('>= 0.46.0')
|
||||
has_arg = cc.has_link_argument(ldflag)
|
||||
else
|
||||
has_arg = cc.has_argument(ldflag)
|
||||
endif
|
||||
|
||||
if has_arg 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('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('theme-manager'))
|
||||
)
|
||||
endif
|
||||
|
||||
if meson.version().version_compare('>= 0.53.0')
|
||||
summary({
|
||||
'prefix': get_option('prefix'),
|
||||
'bindir': get_option('bindir'),
|
||||
'libdir': get_option('libdir'),
|
||||
'datadir': get_option('datadir'),
|
||||
}, section: 'Directories')
|
||||
|
||||
summary({
|
||||
'TLS (openssl)': libssl_dep.found(),
|
||||
'Plugin Support': get_option('plugin'),
|
||||
'DBus Support': dbus_glib_dep.found(),
|
||||
'libcanberra': libcanberra_dep.found(),
|
||||
}, section: 'Features')
|
||||
|
||||
summary({
|
||||
'Lua': get_option('with-lua'),
|
||||
'Python': get_option('with-python'),
|
||||
'Perl': get_option('with-perl'),
|
||||
'Perl Legacy API': get_option('with-perl-legacy-api'),
|
||||
'FiSH': get_option('with-fishlim'),
|
||||
'Sysinfo': get_option('with-sysinfo'),
|
||||
'DCC Checksum': get_option('with-checksum'),
|
||||
}, section: 'Plugins')
|
||||
endif
|
@ -1,67 +0,0 @@
|
||||
# Applications
|
||||
option('gtk-frontend', type: 'boolean',
|
||||
description: 'Main graphical interface'
|
||||
)
|
||||
option('text-frontend', type: 'boolean', value: false,
|
||||
description: 'Text interface (not generally useful)'
|
||||
)
|
||||
option('theme-manager', type: 'boolean', value: false,
|
||||
description: 'Utility to help manage themes, requires mono/.net'
|
||||
)
|
||||
|
||||
# Features
|
||||
option('tls', type: 'feature', value: 'enabled',
|
||||
description: 'Support for TLS connections, requires openssl'
|
||||
)
|
||||
option('plugin', type: 'boolean',
|
||||
description: 'Support for loadable plugins'
|
||||
)
|
||||
option('dbus', type: 'feature', value: 'auto',
|
||||
description: 'Support used for single-instance and scripting interface, Unix only'
|
||||
)
|
||||
option('libcanberra', type: 'feature', value: 'auto',
|
||||
description: 'Support for sound alerts, Unix only'
|
||||
)
|
||||
|
||||
# Install options
|
||||
option('dbus-service-use-appid', type: 'boolean', value: false,
|
||||
description: 'Rename dbus service to match app-id, required for Flatpak'
|
||||
)
|
||||
option('install-appdata', type: 'boolean',
|
||||
description: 'Install appdata files for app stores'
|
||||
)
|
||||
option('install-plugin-metainfo', type: 'boolean', value: false,
|
||||
description: 'Installs metainfo files for enabled plugins, useful when distros create split packages'
|
||||
)
|
||||
|
||||
# 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: 'string', value: 'perl',
|
||||
description: 'Perl scripting plugin, value is path to perl executable or "false"'
|
||||
)
|
||||
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'
|
||||
)
|
||||
option('with-perl-legacy-api', type: 'boolean', value: false,
|
||||
description: 'Enables the legacy IRC perl module for compatibility with old scripts'
|
||||
)
|
@ -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')])
|
38
plugins/Make.plugin
Normal file
@ -0,0 +1,38 @@
|
||||
# Makefile stub for creating standalone plugin distributions.
|
||||
|
||||
plugin_dist: pg_dist pg_dist/config.status
|
||||
pgi=`cd $(srcdir)/.. && pwd`; cd pg_dist; \
|
||||
$(MAKE) $(AM_MAKEFLAGS) PLUGIN_INCLUDES=-I$$pgi distcheck dist
|
||||
|
||||
pg_dist: pg_distdir pg_dist/configure.in pg_dist/install-sh
|
||||
cd pg_dist \
|
||||
&& libtoolize --copy --force --automake \
|
||||
&& automake --copy --add-missing --foreign \
|
||||
&& autoconf -l ../$(top_srcdir)
|
||||
|
||||
pg_distdir: $(DISTFILES)
|
||||
test -d pg_dist || mkdir pg_dist
|
||||
for dfile in $(DISTFILES); do \
|
||||
test -f $$dfile && cp $$dfile pg_dist \
|
||||
|| test -f $(srcdir)/$$dfile && cp $(srcdir)/$$dfile pg_dist; done
|
||||
sed '/Make.plugin/d' < $(srcdir)/Makefile.am > pg_dist/Makefile.am
|
||||
|
||||
pg_dist/configure.in: $(srcdir)/../plugin-conf.in
|
||||
rm -f pg_dist/configure.in
|
||||
test -f $(srcdir)/config.stub \
|
||||
&& cat $(srcdir)/config.stub > pg_dist/configure.in || true
|
||||
cat $(srcdir)/../plugin-conf.in | \
|
||||
sed 's%@PLUGIN_VERSION@%$(PLUGIN_VERSION)%; \
|
||||
s%@PLUGIN@%$(PLUGIN)%' >> pg_dist/configure.in
|
||||
|
||||
pg_dist/install-sh: pg_distdir
|
||||
cp $(top_srcdir)/install-sh pg_dist
|
||||
|
||||
pg_dist/config.status: pg_dist/configure
|
||||
cd pg_dist \
|
||||
&& test -f config.status && $(SHELL) ./config.status --recheck \
|
||||
|| $(SHELL) ./configure --enable-maintainer-mode
|
||||
|
||||
DISTCLEANFILES = pg_dist/* pg_dist
|
||||
|
||||
#
|
25
plugins/Makefile.am
Normal file
@ -0,0 +1,25 @@
|
||||
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) $(checksumdir) $(doatdir) $(fishlimdir) $(sysinfodir)
|
7
plugins/checksum/Makefile.am
Normal file
@ -0,0 +1,7 @@
|
||||
libdir = $(hexchatlibdir)
|
||||
|
||||
lib_LTLIBRARIES = checksum.la
|
||||
checksum_la_SOURCES = checksum.c
|
||||
checksum_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
|
||||
checksum_la_LIBADD = $(GLIB_LIBS)
|
||||
checksum_la_CFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)/src/common
|
@ -58,7 +58,7 @@ set_limit (char *size)
|
||||
}
|
||||
|
||||
static int
|
||||
get_limit (void)
|
||||
get_limit ()
|
||||
{
|
||||
int size = hexchat_pluginpref_get_int (ph, "limit");
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Configuration">
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
|
@ -1,7 +0,0 @@
|
||||
shared_module('checksum', 'checksum.c',
|
||||
dependencies: [libgio_dep, hexchat_plugin_dep],
|
||||
install: true,
|
||||
install_dir: plugindir,
|
||||
name_prefix: '',
|
||||
vs_module_defs: 'checksum.def',
|
||||
)
|
8
plugins/doat/Makefile.am
Normal file
@ -0,0 +1,8 @@
|
||||
libdir = $(hexchatlibdir)
|
||||
|
||||
lib_LTLIBRARIES = doat.la
|
||||
doat_la_SOURCES = doat.c
|
||||
doat_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
|
||||
doat_la_LIBADD = $(GLIB_LIBS)
|
||||
doat_la_CFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)/src/common
|
||||
|
92
plugins/doat/doat.c
Normal file
@ -0,0 +1,92 @@
|
||||
/* 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 "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <glib.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 = g_strdup( token );
|
||||
|
||||
delimiter = strchr( channel, '/' );
|
||||
|
||||
server = NULL;
|
||||
if( delimiter != NULL ) {
|
||||
*delimiter = '\0';
|
||||
|
||||
if( strlen( delimiter + 1 ) > 0 ) {
|
||||
server = g_strdup( delimiter + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
/* /Network form */
|
||||
if( strlen( channel ) == 0 ) {
|
||||
g_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] );
|
||||
}
|
||||
}
|
||||
|
||||
g_free( channel );
|
||||
g_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
@ -0,0 +1,3 @@
|
||||
EXPORTS
|
||||
hexchat_plugin_init
|
||||
hexchat_plugin_deinit
|
59
plugins/doat/doat.vcxproj
Normal file
@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Configuration">
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<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" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\win32\hexchat.props" />
|
||||
<PropertyGroup>
|
||||
<TargetName>hcdoat</TargetName>
|
||||
<OutDir>$(HexChatRel)plugins\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DOAT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\src\common;$(HexChatLib);$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>doat.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;DOAT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\src\common;$(HexChatLib);$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>doat.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="doat.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="doat.def" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
23
plugins/doat/doat.vcxproj.filters
Normal file
@ -0,0 +1,23 @@
|
||||
<?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="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="doat.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="doat.def">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Configuration">
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
|
@ -1,6 +0,0 @@
|
||||
shared_module('exec', 'exec.c',
|
||||
dependencies: hexchat_plugin_dep,
|
||||
install: true,
|
||||
install_dir: plugindir,
|
||||
vs_module_defs: 'exec.def',
|
||||
)
|
16
plugins/fishlim/INSTALL
Normal 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
|
||||
|
||||
|
9
plugins/fishlim/Makefile.am
Normal file
@ -0,0 +1,9 @@
|
||||
EXTRA_DIST = INSTALL LICENSE
|
||||
|
||||
libdir = $(hexchatlibdir)
|
||||
|
||||
lib_LTLIBRARIES = fishlim.la
|
||||
fishlim_la_SOURCES = fish.c irc.c keystore.c plugin_hexchat.c
|
||||
fishlim_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
|
||||
fishlim_la_LIBADD = $(GLIB_LIBS) $(OPENSSL_LIBS)
|
||||
fishlim_la_CFLAGS = $(GLIB_CFLAGS) $(OPENSSL_CFLAGS) -I$(top_srcdir)/src/common
|
@ -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;
|
||||
}
|
@ -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);
|
||||
|
@ -1,7 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se>
|
||||
Copyright (c) 2019-2020 <bakasura@protonmail.ch>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -28,22 +27,15 @@
|
||||
#define DEPRECATED_IN_MAC_OS_X_VERSION_10_7_AND_LATER
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/blowfish.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#include "keystore.h"
|
||||
#include "fish.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define IB 64
|
||||
/* rfc 2812; 512 - CR-LF = 510 */
|
||||
static const int MAX_COMMAND_LENGTH = 510;
|
||||
static const char fish_base64[] = "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
static const char fish_base64[64] = "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
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,
|
||||
@ -61,12 +53,6 @@ static const signed char fish_unbase64[256] = {
|
||||
27,28,29,30,31,32,33,34, 35,36,37,IB,IB,IB,IB,IB,
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert Int to 4 Bytes (Big-endian)
|
||||
*
|
||||
* @param int source
|
||||
* @param char* dest
|
||||
*/
|
||||
#define GET_BYTES(dest, source) do { \
|
||||
*((dest)++) = ((source) >> 24) & 0xFF; \
|
||||
*((dest)++) = ((source) >> 16) & 0xFF; \
|
||||
@ -74,488 +60,135 @@ static const signed char fish_unbase64[256] = {
|
||||
*((dest)++) = (source) & 0xFF; \
|
||||
} while (0);
|
||||
|
||||
/**
|
||||
* Convert 4 Bytes to Int (Big-endian)
|
||||
*
|
||||
* @param char* source
|
||||
* @param int dest
|
||||
*/
|
||||
#define GET_LONG(dest, source) do { \
|
||||
dest = ((uint8_t)*((source)++) << 24); \
|
||||
dest |= ((uint8_t)*((source)++) << 16); \
|
||||
dest |= ((uint8_t)*((source)++) << 8); \
|
||||
dest |= (uint8_t)*((source)++); \
|
||||
} while (0);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
#include <openssl/provider.h>
|
||||
static OSSL_PROVIDER *legacy_provider;
|
||||
static OSSL_PROVIDER *default_provider;
|
||||
static OSSL_LIB_CTX *ossl_ctx;
|
||||
#endif
|
||||
|
||||
int fish_init(void)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
ossl_ctx = OSSL_LIB_CTX_new();
|
||||
if (!ossl_ctx)
|
||||
return 0;
|
||||
|
||||
legacy_provider = OSSL_PROVIDER_load(ossl_ctx, "legacy");
|
||||
if (!legacy_provider) {
|
||||
fish_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
default_provider = OSSL_PROVIDER_load(ossl_ctx, "default");
|
||||
if (!default_provider) {
|
||||
fish_deinit();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
void fish_deinit(void)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
if (legacy_provider) {
|
||||
OSSL_PROVIDER_unload(legacy_provider);
|
||||
legacy_provider = NULL;
|
||||
}
|
||||
|
||||
if (default_provider) {
|
||||
OSSL_PROVIDER_unload(default_provider);
|
||||
default_provider = NULL;
|
||||
}
|
||||
|
||||
if (ossl_ctx) {
|
||||
OSSL_LIB_CTX_free(ossl_ctx);
|
||||
ossl_ctx = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode ECB FiSH Base64
|
||||
*
|
||||
* @param [in] message Bytes to encode
|
||||
* @param [in] message_len Size of bytes to encode
|
||||
* @return Array of char with encoded string
|
||||
*/
|
||||
char *fish_base64_encode(const char *message, size_t message_len) {
|
||||
BF_LONG left = 0, right = 0;
|
||||
int i, j;
|
||||
char *encoded = NULL;
|
||||
char *end = NULL;
|
||||
char *msg = NULL;
|
||||
|
||||
if (message_len == 0)
|
||||
return NULL;
|
||||
|
||||
/* Each 8-byte block becomes 12 bytes (fish base64 format) and add 1 byte for \0 */
|
||||
encoded = g_malloc(((message_len - 1) / 8) * 12 + 12 + 1);
|
||||
end = encoded;
|
||||
|
||||
/* Iterate over each 8-byte block (Blowfish block size) */
|
||||
for (j = 0; j < message_len; j += 8) {
|
||||
msg = (char *) message;
|
||||
|
||||
/* Set left and right longs */
|
||||
GET_LONG(left, msg);
|
||||
GET_LONG(right, msg);
|
||||
|
||||
for (i = 0; i < 6; ++i) {
|
||||
*end++ = fish_base64[right & 0x3fu];
|
||||
right = (right >> 6u);
|
||||
char *fish_encrypt(const char *key, size_t keylen, const char *message) {
|
||||
BF_KEY bfkey;
|
||||
size_t messagelen;
|
||||
size_t i;
|
||||
int j;
|
||||
char *encrypted;
|
||||
char *end;
|
||||
unsigned char bit;
|
||||
unsigned char word;
|
||||
unsigned char d;
|
||||
BF_set_key(&bfkey, keylen, (const unsigned char*)key);
|
||||
|
||||
messagelen = strlen(message);
|
||||
if (messagelen == 0) return NULL;
|
||||
encrypted = g_malloc(((messagelen - 1) / 8) * 12 + 12 + 1); /* each 8-byte block becomes 12 bytes */
|
||||
end = encrypted;
|
||||
|
||||
while (*message) {
|
||||
/* Read 8 bytes (a Blowfish block) */
|
||||
BF_LONG binary[2] = { 0, 0 };
|
||||
unsigned char c;
|
||||
for (i = 0; i < 8; i++) {
|
||||
c = message[i];
|
||||
binary[i >> 2] |= c << 8*(3 - (i&3));
|
||||
if (c == '\0') break;
|
||||
}
|
||||
|
||||
for (i = 0; i < 6; ++i) {
|
||||
*end++ = fish_base64[left & 0x3fu];
|
||||
left = (left >> 6u);
|
||||
}
|
||||
|
||||
/* The previous for'd ensure fill all bytes of encoded, we don't need will with zeros */
|
||||
message += 8;
|
||||
}
|
||||
|
||||
*end = '\0';
|
||||
return encoded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode ECB FiSH Base64
|
||||
*
|
||||
* @param [in] message Base64 encoded string
|
||||
* @param [out] final_len Real length of message
|
||||
* @return Array of char with decoded message
|
||||
*/
|
||||
char *fish_base64_decode(const char *message, size_t *final_len) {
|
||||
BF_LONG left, right;
|
||||
int i;
|
||||
char *bytes = NULL;
|
||||
char *msg = NULL;
|
||||
char *byt = NULL;
|
||||
size_t message_len;
|
||||
|
||||
message_len = strlen(message);
|
||||
|
||||
/* Ensure blocks of 12 bytes each one and valid characters */
|
||||
if (message_len == 0 || message_len % 12 != 0 || strspn(message, fish_base64) != message_len)
|
||||
return NULL;
|
||||
|
||||
/* Each 12 bytes becomes 8-byte block and add 1 byte for \0 */
|
||||
*final_len = ((message_len - 1) / 12) * 8 + 8 + 1;
|
||||
(*final_len)--; /* We support binary data */
|
||||
bytes = (char *) g_malloc0(*final_len);
|
||||
byt = bytes;
|
||||
|
||||
msg = (char *) message;
|
||||
|
||||
while (*msg) {
|
||||
right = 0;
|
||||
left = 0;
|
||||
for (i = 0; i < 6; i++) right |= (uint8_t) fish_unbase64[(int)*msg++] << (i * 6u);
|
||||
for (i = 0; i < 6; i++) left |= (uint8_t) fish_unbase64[(int)*msg++] << (i * 6u);
|
||||
GET_BYTES(byt, left);
|
||||
GET_BYTES(byt, right);
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt or decrypt data with Blowfish cipher, support binary data.
|
||||
*
|
||||
* Good documentation for EVP:
|
||||
*
|
||||
* - https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption
|
||||
*
|
||||
* - https://stackoverflow.com/questions/5727646/what-is-the-length-parameter-of-aes-evp-decrypt
|
||||
*
|
||||
* - https://stackoverflow.com/questions/26345175/correct-way-to-free-allocate-the-context-in-the-openssl
|
||||
*
|
||||
* - https://stackoverflow.com/questions/29874150/working-with-evp-and-openssl-coding-in-c
|
||||
*
|
||||
* @param [in] plaintext Bytes to encrypt or decrypt
|
||||
* @param [in] plaintext_len Size of plaintext
|
||||
* @param [in] key Bytes of key
|
||||
* @param [in] keylen Size of key
|
||||
* @param [in] encode 1 or encrypt 0 for decrypt
|
||||
* @param [in] mode EVP_CIPH_ECB_MODE or EVP_CIPH_CBC_MODE
|
||||
* @param [out] ciphertext_len The bytes written
|
||||
* @return Array of char with data encrypted or decrypted
|
||||
*/
|
||||
char *fish_cipher(const char *plaintext, size_t plaintext_len, const char *key, size_t keylen, int encode, int mode, size_t *ciphertext_len) {
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
EVP_CIPHER *cipher = NULL;
|
||||
int bytes_written = 0;
|
||||
unsigned char *ciphertext = NULL;
|
||||
unsigned char *iv_ciphertext = NULL;
|
||||
unsigned char *iv = NULL;
|
||||
size_t block_size = 0;
|
||||
|
||||
*ciphertext_len = 0;
|
||||
|
||||
if (plaintext_len == 0 || keylen == 0 || encode < 0 || encode > 1)
|
||||
return NULL;
|
||||
|
||||
block_size = plaintext_len;
|
||||
|
||||
if (mode == EVP_CIPH_CBC_MODE) {
|
||||
if (encode == 1) {
|
||||
iv = (unsigned char *) g_malloc0(8);
|
||||
RAND_bytes(iv, 8);
|
||||
} else {
|
||||
if (plaintext_len <= 8) /* IV + DATA */
|
||||
return NULL;
|
||||
|
||||
iv = (unsigned char *) plaintext;
|
||||
block_size -= 8;
|
||||
plaintext += 8;
|
||||
plaintext_len -= 8;
|
||||
|
||||
/* Encrypt block */
|
||||
BF_encrypt(binary, &bfkey);
|
||||
|
||||
/* Emit FiSH-BASE64 */
|
||||
bit = 0;
|
||||
word = 1;
|
||||
for (j = 0; j < 12; j++) {
|
||||
d = fish_base64[(binary[word] >> bit) & 63];
|
||||
*(end++) = d;
|
||||
bit += 6;
|
||||
if (j == 5) {
|
||||
bit = 0;
|
||||
word = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
cipher = EVP_CIPHER_fetch(ossl_ctx, "BF-CBC", NULL);
|
||||
#else
|
||||
cipher = (EVP_CIPHER *) EVP_bf_cbc();
|
||||
#endif
|
||||
|
||||
} else if (mode == EVP_CIPH_ECB_MODE) {
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
cipher = EVP_CIPHER_fetch(ossl_ctx, "BF-ECB", NULL);
|
||||
#else
|
||||
cipher = (EVP_CIPHER *) EVP_bf_ecb();
|
||||
#endif
|
||||
|
||||
/* Stop if a null terminator was found */
|
||||
if (c == '\0') break;
|
||||
}
|
||||
*end = '\0';
|
||||
return encrypted;
|
||||
}
|
||||
|
||||
/* Zero Padding */
|
||||
if (block_size % 8 != 0) {
|
||||
block_size = block_size + 8 - (block_size % 8);
|
||||
}
|
||||
|
||||
ciphertext = (unsigned char *) g_malloc0(block_size);
|
||||
memcpy(ciphertext, plaintext, plaintext_len);
|
||||
|
||||
/* Create and initialise the context */
|
||||
if (!(ctx = EVP_CIPHER_CTX_new()))
|
||||
return NULL;
|
||||
|
||||
/* Initialise the cipher operation only with mode */
|
||||
if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, encode))
|
||||
return NULL;
|
||||
|
||||
/* Set custom key length */
|
||||
if (!EVP_CIPHER_CTX_set_key_length(ctx, keylen))
|
||||
return NULL;
|
||||
|
||||
/* Finish the initiation the cipher operation */
|
||||
if (1 != EVP_CipherInit_ex(ctx, NULL, NULL, (const unsigned char *) key, iv, encode))
|
||||
return NULL;
|
||||
|
||||
/* We will manage this */
|
||||
EVP_CIPHER_CTX_set_padding(ctx, 0);
|
||||
|
||||
/* Do cipher operation */
|
||||
if (1 != EVP_CipherUpdate(ctx, ciphertext, &bytes_written, ciphertext, block_size))
|
||||
return NULL;
|
||||
|
||||
*ciphertext_len = bytes_written;
|
||||
|
||||
/* Finalise the cipher. Further ciphertext bytes may be written at this stage */
|
||||
if (1 != EVP_CipherFinal_ex(ctx, ciphertext + bytes_written, &bytes_written))
|
||||
return NULL;
|
||||
|
||||
*ciphertext_len += bytes_written;
|
||||
|
||||
/* Clean up */
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
|
||||
|
||||
if (mode == EVP_CIPH_CBC_MODE && encode == 1) {
|
||||
/* Join IV + DATA */
|
||||
iv_ciphertext = g_malloc0(8 + *ciphertext_len);
|
||||
|
||||
memcpy(iv_ciphertext, iv, 8);
|
||||
memcpy(&iv_ciphertext[8], ciphertext, *ciphertext_len);
|
||||
*ciphertext_len += 8;
|
||||
|
||||
g_free(ciphertext);
|
||||
g_free(iv);
|
||||
|
||||
return (char *) iv_ciphertext;
|
||||
} else {
|
||||
return (char *) ciphertext;
|
||||
|
||||
char *fish_decrypt(const char *key, size_t keylen, const char *data) {
|
||||
BF_KEY bfkey;
|
||||
size_t i;
|
||||
char *decrypted;
|
||||
char *end;
|
||||
unsigned char bit;
|
||||
unsigned char word;
|
||||
unsigned char d;
|
||||
BF_set_key(&bfkey, keylen, (const unsigned char*)key);
|
||||
|
||||
decrypted = g_malloc(strlen(data) + 1);
|
||||
end = decrypted;
|
||||
|
||||
while (*data) {
|
||||
/* 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;
|
||||
bit += 6;
|
||||
if (i == 5) {
|
||||
bit = 0;
|
||||
word = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Decrypt block */
|
||||
BF_decrypt(binary, &bfkey);
|
||||
|
||||
/* Copy to buffer */
|
||||
GET_BYTES(end, binary[0]);
|
||||
GET_BYTES(end, binary[1]);
|
||||
}
|
||||
|
||||
decrypt_end:
|
||||
*end = '\0';
|
||||
return decrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a fish or standard Base64 encoded string with data encrypted
|
||||
* is binary safe
|
||||
*
|
||||
* @param [in] key Bytes of key
|
||||
* @param [in] keylen Size of key
|
||||
* @param [in] message Bytes to encrypt
|
||||
* @param [in] message_len Size of message
|
||||
* @param [in] mode Chiper mode
|
||||
* @return Array of char with data encrypted
|
||||
* Encrypts a message (see fish_decrypt). The key is searched for in the
|
||||
* key store.
|
||||
*/
|
||||
char *fish_encrypt(const char *key, size_t keylen, const char *message, size_t message_len, enum fish_mode mode) {
|
||||
size_t ciphertext_len = 0;
|
||||
char *ciphertext = NULL;
|
||||
char *b64 = NULL;
|
||||
|
||||
if (keylen == 0 || message_len == 0)
|
||||
return NULL;
|
||||
|
||||
ciphertext = fish_cipher(message, message_len, key, keylen, 1, mode, &ciphertext_len);
|
||||
|
||||
if (ciphertext == NULL || ciphertext_len == 0)
|
||||
return NULL;
|
||||
|
||||
switch (mode) {
|
||||
case FISH_CBC_MODE:
|
||||
b64 = g_base64_encode((const unsigned char *) ciphertext, ciphertext_len);
|
||||
break;
|
||||
|
||||
case FISH_ECB_MODE:
|
||||
b64 = fish_base64_encode((const char *) ciphertext, ciphertext_len);
|
||||
}
|
||||
|
||||
g_free(ciphertext);
|
||||
|
||||
if (b64 == NULL)
|
||||
return NULL;
|
||||
|
||||
return b64;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of bytes with data decrypted
|
||||
* is binary safe
|
||||
*
|
||||
* @param [in] key Bytes of key
|
||||
* @param [in] keylen Size of key
|
||||
* @param [in] data Fish or standard Base64 encoded string
|
||||
* @param [in] mode Chiper mode
|
||||
* @param [out] final_len Length of returned array
|
||||
* @return Array of char with data decrypted
|
||||
*/
|
||||
char *fish_decrypt(const char *key, size_t keylen, const char *data, enum fish_mode mode, size_t *final_len) {
|
||||
size_t ciphertext_len = 0;
|
||||
char *ciphertext = NULL;
|
||||
char *plaintext = NULL;
|
||||
|
||||
*final_len = 0;
|
||||
|
||||
if (keylen == 0 || strlen(data) == 0)
|
||||
return NULL;
|
||||
|
||||
switch (mode) {
|
||||
case FISH_CBC_MODE:
|
||||
if (strspn(data, base64_chars) != strlen(data))
|
||||
return NULL;
|
||||
ciphertext = (char *) g_base64_decode(data, &ciphertext_len);
|
||||
break;
|
||||
|
||||
case FISH_ECB_MODE:
|
||||
ciphertext = fish_base64_decode(data, &ciphertext_len);
|
||||
}
|
||||
|
||||
if (ciphertext == NULL || ciphertext_len == 0)
|
||||
return NULL;
|
||||
|
||||
plaintext = fish_cipher(ciphertext, ciphertext_len, key, keylen, 0, mode, final_len);
|
||||
g_free(ciphertext);
|
||||
|
||||
if (*final_len == 0)
|
||||
return NULL;
|
||||
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to fish_decrypt, but pad with zeros any after the first zero in the decrypted data
|
||||
*
|
||||
* @param [in] key Bytes of key
|
||||
* @param [in] keylen Size of key
|
||||
* @param [in] data Fish or standard Base64 encoded string
|
||||
* @param [in] mode Chiper mode
|
||||
* @return Array of char with data decrypted
|
||||
*/
|
||||
char *fish_decrypt_str(const char *key, size_t keylen, const char *data, enum fish_mode mode) {
|
||||
char *decrypted = NULL;
|
||||
char *plaintext_str = NULL;
|
||||
size_t decrypted_len = 0;
|
||||
|
||||
decrypted = fish_decrypt(key, strlen(key), data, mode, &decrypted_len);
|
||||
|
||||
if (decrypted == NULL || decrypted_len == 0)
|
||||
return NULL;
|
||||
|
||||
plaintext_str = g_strndup(decrypted, decrypted_len);
|
||||
g_free(decrypted);
|
||||
|
||||
return plaintext_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a nick have a key
|
||||
*
|
||||
* @param [in] nick Nickname
|
||||
* @return TRUE if have a key or FALSE if not
|
||||
*/
|
||||
gboolean fish_nick_has_key(const char *nick) {
|
||||
gboolean has_key = FALSE;
|
||||
char *fish_encrypt_for_nick(const char *nick, const char *data) {
|
||||
char *key;
|
||||
enum fish_mode mode;
|
||||
|
||||
key = keystore_get_key(nick, &mode);
|
||||
if (key) {
|
||||
has_key = TRUE;
|
||||
g_free(key);
|
||||
};
|
||||
|
||||
return has_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a message (see fish_encrypt). The key is searched for in the key store
|
||||
*
|
||||
* @param [in] nick Nickname
|
||||
* @param [in] data Plaintext to encrypt
|
||||
* @param [out] omode Mode of encryption
|
||||
* @param [in] command_len Length of command to use without the message part
|
||||
* @return A list of encoded strings with the message encrypted or NULL if any error occurred
|
||||
*/
|
||||
GSList *fish_encrypt_for_nick(const char *nick, const char *data, enum fish_mode *omode, size_t command_len) {
|
||||
char *key;
|
||||
GSList *encrypted_list = NULL;
|
||||
char *encrypted = NULL;
|
||||
enum fish_mode mode;
|
||||
int max_len, max_chunks_len, chunks_len;
|
||||
char *encrypted;
|
||||
|
||||
/* Look for key */
|
||||
key = keystore_get_key(nick, &mode);
|
||||
key = keystore_get_key(nick);
|
||||
if (!key) return NULL;
|
||||
|
||||
*omode = mode;
|
||||
|
||||
/* Calculate max length of each line */
|
||||
max_len = MAX_COMMAND_LENGTH - command_len;
|
||||
/* Add '*' */
|
||||
if (mode == FISH_CBC_MODE) max_len--;
|
||||
|
||||
max_chunks_len = max_text_command_len(max_len, mode);
|
||||
|
||||
const char *data_chunk = data;
|
||||
|
||||
while(foreach_utf8_data_chunks(data_chunk, max_chunks_len, &chunks_len)) {
|
||||
encrypted = fish_encrypt(key, strlen(key), data_chunk, chunks_len, mode);
|
||||
|
||||
if (mode == FISH_CBC_MODE) {
|
||||
/* Add '*' for CBC */
|
||||
encrypted_list = g_slist_append(encrypted_list, g_strdup_printf("*%s", encrypted));
|
||||
g_free(encrypted);
|
||||
} else {
|
||||
encrypted_list = g_slist_append(encrypted_list, encrypted);
|
||||
}
|
||||
|
||||
/* Next chunk */
|
||||
data_chunk += chunks_len;
|
||||
}
|
||||
|
||||
return encrypted_list;
|
||||
|
||||
/* Encrypt */
|
||||
encrypted = fish_encrypt(key, strlen(key), data);
|
||||
|
||||
g_free(key);
|
||||
return encrypted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts a message (see fish_decrypt). The key is searched for in the key store
|
||||
*
|
||||
* @param [in] nick Nickname
|
||||
* @param [in] data Plaintext to encrypt
|
||||
* @param [out] omode Mode of encryption
|
||||
* @return Plaintext message or NULL if any error occurred
|
||||
* Decrypts a message (see fish_decrypt). The key is searched for in the
|
||||
* key store.
|
||||
*/
|
||||
char *fish_decrypt_from_nick(const char *nick, const char *data, enum fish_mode *omode) {
|
||||
char *fish_decrypt_from_nick(const char *nick, const char *data) {
|
||||
char *key;
|
||||
char *decrypted;
|
||||
enum fish_mode mode;
|
||||
|
||||
/* Look for key */
|
||||
key = keystore_get_key(nick, &mode);
|
||||
key = keystore_get_key(nick);
|
||||
if (!key) return NULL;
|
||||
|
||||
*omode = mode;
|
||||
|
||||
if (mode == FISH_CBC_MODE)
|
||||
++data;
|
||||
|
||||
|
||||
/* Decrypt */
|
||||
decrypted = fish_decrypt_str(key, strlen(key), data, mode);
|
||||
decrypted = fish_decrypt(key, strlen(key), data);
|
||||
|
||||
g_free(key);
|
||||
|
||||
return decrypted;
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se>
|
||||
Copyright (c) 2019-2020 <bakasura@protonmail.ch>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -30,21 +29,10 @@
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
enum fish_mode {
|
||||
FISH_ECB_MODE = 0x1,
|
||||
FISH_CBC_MODE = 0x2
|
||||
};
|
||||
|
||||
int fish_init(void);
|
||||
void fish_deinit(void);
|
||||
char *fish_base64_encode(const char *message, size_t message_len);
|
||||
char *fish_base64_decode(const char *message, size_t *final_len);
|
||||
char *fish_encrypt(const char *key, size_t keylen, const char *message, size_t message_len, enum fish_mode mode);
|
||||
char *fish_decrypt(const char *key, size_t keylen, const char *data, enum fish_mode mode, size_t *final_len);
|
||||
char *fish_decrypt_str(const char *key, size_t keylen, const char *data, enum fish_mode mode);
|
||||
gboolean fish_nick_has_key(const char *nick);
|
||||
GSList *fish_encrypt_for_nick(const char *nick, const char *data, enum fish_mode *omode, size_t command_len);
|
||||
char *fish_decrypt_from_nick(const char *nick, const char *data, enum fish_mode *omode);
|
||||
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);
|
||||
char *fish_decrypt_from_nick(const char *nick, const char *data);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Configuration">
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
@ -29,7 +29,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;HAVE_DH_SET0_PQG;HAVE_DH_GET0_KEY;HAVE_DH_SET0_KEY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@ -40,7 +40,7 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;HAVE_DH_SET0_PQG;HAVE_DH_GET0_KEY;HAVE_DH_SET0_KEY;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(DepsRoot)\include;$(Glib);..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@ -53,17 +53,14 @@
|
||||
<None Include="fishlim.def" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="dh1080.h" />
|
||||
<ClInclude Include="bool.h" />
|
||||
<ClInclude Include="fish.h" />
|
||||
<ClInclude Include="utils.h" />
|
||||
<ClInclude Include="irc.h" />
|
||||
<ClInclude Include="keystore.h" />
|
||||
<ClInclude Include="plugin_hexchat.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dh1080.c" />
|
||||
<ClCompile Include="fish.c" />
|
||||
<ClCompile Include="utils.c" />
|
||||
<ClCompile Include="irc.c" />
|
||||
<ClCompile Include="keystore.c" />
|
||||
<ClCompile Include="plugin_hexchat.c" />
|
||||
|
@ -23,15 +23,9 @@
|
||||
<ClInclude Include="bool.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="dh1080.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="fish.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="utils.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="irc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@ -43,15 +37,9 @@
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dh1080.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="fish.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="utils.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="irc.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@ -50,9 +50,7 @@ gboolean irc_parse_message(const char *words[],
|
||||
if (command) *command = words[w];
|
||||
w++;
|
||||
|
||||
if (parameters_offset)
|
||||
*parameters_offset = w;
|
||||
|
||||
*parameters_offset = w;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,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,7 +55,7 @@ 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... */
|
||||
@ -63,22 +63,6 @@ static const char *get_keystore_password(void) {
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
@ -103,55 +87,23 @@ 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, enum fish_mode *mode) {
|
||||
GKeyFile *keyfile;
|
||||
char *escaped_nick;
|
||||
gchar *value, *key_mode;
|
||||
int encrypted_mode;
|
||||
char *password;
|
||||
char *encrypted;
|
||||
char *decrypted;
|
||||
|
||||
char *keystore_get_key(const char *nick) {
|
||||
/* Get the key */
|
||||
keyfile = getConfigFile();
|
||||
escaped_nick = escape_nickname(nick);
|
||||
value = get_nick_value(keyfile, escaped_nick, "key");
|
||||
key_mode = get_nick_value(keyfile, escaped_nick, "mode");
|
||||
GKeyFile *keyfile = getConfigFile();
|
||||
gchar *value = get_nick_value(keyfile, nick, "key");
|
||||
g_key_file_free(keyfile);
|
||||
g_free(escaped_nick);
|
||||
|
||||
/* Determine cipher mode */
|
||||
*mode = FISH_ECB_MODE;
|
||||
if (key_mode) {
|
||||
if (*key_mode == '1')
|
||||
*mode = FISH_ECB_MODE;
|
||||
else if (*key_mode == '2')
|
||||
*mode = FISH_CBC_MODE;
|
||||
g_free(key_mode);
|
||||
}
|
||||
|
||||
if (!value)
|
||||
return NULL;
|
||||
|
||||
if (strncmp(value, "+OK ", 4) == 0) {
|
||||
/* Key is encrypted */
|
||||
encrypted = (char *) value;
|
||||
encrypted += 4;
|
||||
|
||||
encrypted_mode = FISH_ECB_MODE;
|
||||
|
||||
if (*encrypted == '*') {
|
||||
++encrypted;
|
||||
encrypted_mode = FISH_CBC_MODE;
|
||||
}
|
||||
|
||||
password = (char *) get_keystore_password();
|
||||
decrypted = fish_decrypt_str((const char *) password, strlen(password), (const char *) encrypted, encrypted_mode);
|
||||
g_free(value);
|
||||
return decrypted;
|
||||
} else {
|
||||
if (!value) return NULL;
|
||||
|
||||
if (strncmp(value, "+OK ", 4) != 0) {
|
||||
/* Key is stored in plaintext */
|
||||
return value;
|
||||
} else {
|
||||
/* Key is encrypted */
|
||||
const char *encrypted = value+4;
|
||||
const char *password = get_keystore_password();
|
||||
char *decrypted = fish_decrypt(password, strlen(password), encrypted);
|
||||
g_free(value);
|
||||
return decrypted;
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,9 +157,7 @@ static gboolean save_keystore(GKeyFile *keyfile) {
|
||||
#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);
|
||||
|
||||
@ -217,45 +167,40 @@ G_GNUC_END_IGNORE_DEPRECATIONS
|
||||
/**
|
||||
* Sets a key in the key store file.
|
||||
*/
|
||||
gboolean keystore_store_key(const char *nick, const char *key, enum fish_mode mode) {
|
||||
gboolean keystore_store_key(const char *nick, const char *key) {
|
||||
const char *password;
|
||||
char *encrypted;
|
||||
char *wrapped;
|
||||
gboolean ok = FALSE;
|
||||
GKeyFile *keyfile = getConfigFile();
|
||||
char *escaped_nick = escape_nickname(nick);
|
||||
|
||||
|
||||
/* Remove old key */
|
||||
delete_nick(keyfile, escaped_nick);
|
||||
delete_nick(keyfile, nick);
|
||||
|
||||
/* Add new key */
|
||||
password = get_keystore_password();
|
||||
if (password) {
|
||||
/* Encrypt the password */
|
||||
encrypted = fish_encrypt(password, strlen(password), key, strlen(key), FISH_CBC_MODE);
|
||||
encrypted = fish_encrypt(password, strlen(password), key);
|
||||
if (!encrypted) goto end;
|
||||
|
||||
/* Prepend "+OK " */
|
||||
wrapped = g_strconcat("+OK *", encrypted, NULL);
|
||||
wrapped = g_strconcat("+OK ", encrypted, NULL);
|
||||
g_free(encrypted);
|
||||
|
||||
/* Store encrypted in file */
|
||||
g_key_file_set_string(keyfile, escaped_nick, "key", wrapped);
|
||||
g_key_file_set_string(keyfile, nick, "key", wrapped);
|
||||
g_free(wrapped);
|
||||
} else {
|
||||
/* Store unencrypted in file */
|
||||
g_key_file_set_string(keyfile, escaped_nick, "key", key);
|
||||
g_key_file_set_string(keyfile, nick, "key", key);
|
||||
}
|
||||
|
||||
/* Store cipher mode */
|
||||
g_key_file_set_integer(keyfile, escaped_nick, "mode", mode);
|
||||
|
||||
/* Save key store file */
|
||||
ok = save_keystore(keyfile);
|
||||
|
||||
end:
|
||||
g_key_file_free(keyfile);
|
||||
g_free(escaped_nick);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -264,15 +209,13 @@ gboolean keystore_store_key(const char *nick, const char *key, enum fish_mode mo
|
||||
*/
|
||||
gboolean keystore_delete_nick(const char *nick) {
|
||||
GKeyFile *keyfile = getConfigFile();
|
||||
char *escaped_nick = escape_nickname(nick);
|
||||
|
||||
/* Delete entry */
|
||||
gboolean ok = delete_nick(keyfile, escaped_nick);
|
||||
gboolean ok = delete_nick(keyfile, nick);
|
||||
|
||||
/* Save */
|
||||
if (ok) save_keystore(keyfile);
|
||||
|
||||
g_key_file_free(keyfile);
|
||||
g_free(escaped_nick);
|
||||
return ok;
|
||||
}
|
||||
|
@ -28,10 +28,9 @@
|
||||
#include <stddef.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include "fish.h"
|
||||
|
||||
char *keystore_get_key(const char *nick, enum fish_mode *mode);
|
||||
gboolean keystore_store_key(const char *nick, const char *key, enum fish_mode mode);
|
||||
char *keystore_get_key(const char *nick);
|
||||
gboolean keystore_store_key(const char *nick, const char *key);
|
||||
gboolean keystore_delete_nick(const char *nick);
|
||||
|
||||
#endif
|
||||
|
@ -1,23 +0,0 @@
|
||||
if not libssl_dep.found()
|
||||
error('fish plugin requires openssl')
|
||||
endif
|
||||
|
||||
# Run tests
|
||||
subdir('tests')
|
||||
|
||||
fishlim_sources = [
|
||||
'dh1080.c',
|
||||
'fish.c',
|
||||
'utils.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: '',
|
||||
vs_module_defs: 'fishlim.def',
|
||||
)
|
@ -1,8 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2010-2011 Samuel Lidén Borell <samuel@kodafritt.se>
|
||||
Copyright (c) 2015 <the.cypher@gmail.com>
|
||||
Copyright (c) 2019-2020 <bakasura@protonmail.ch>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@ -29,42 +27,28 @@
|
||||
#include <glib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hexchat-plugin.h"
|
||||
#define HEXCHAT_MAX_WORDS 32
|
||||
|
||||
#include "fish.h"
|
||||
#include "dh1080.h"
|
||||
#include "keystore.h"
|
||||
#include "irc.h"
|
||||
|
||||
static const char *fish_modes[] = {"", "ECB", "CBC", NULL};
|
||||
|
||||
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[] = "1.0.0";
|
||||
|
||||
static const char usage_setkey[] = "Usage: SETKEY [<nick or #channel>] [<mode>:]<password>, sets the key for a channel or nick. Modes: ECB, CBC";
|
||||
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 const char plugin_version[] = "0.0.17";
|
||||
|
||||
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 hexchat_plugin *ph;
|
||||
static GHashTable *pending_exchanges;
|
||||
|
||||
|
||||
/**
|
||||
* Compare two nicks using the current plugin
|
||||
*/
|
||||
int irc_nick_cmp(const char *a, const char *b) {
|
||||
return hexchat_nickcmp (ph, a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to the key store file.
|
||||
*/
|
||||
gchar *get_config_filename(void) {
|
||||
gchar *get_config_filename() {
|
||||
char *filename_fs, *filename_utf8;
|
||||
|
||||
filename_utf8 = g_build_filename(hexchat_get_info(ph, "configdir"), "addon_fishlim.conf", NULL);
|
||||
@ -74,207 +58,8 @@ gchar *get_config_filename(void) {
|
||||
return filename_fs;
|
||||
}
|
||||
|
||||
static inline gboolean irc_is_query (const char *name) {
|
||||
const char *chantypes = hexchat_list_str (ph, NULL, "chantypes");
|
||||
|
||||
return strchr (chantypes, name[0]) == NULL;
|
||||
}
|
||||
|
||||
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 && irc_nick_cmp (chan_name, name) == 0) {
|
||||
ret = (hexchat_context*)hexchat_list_str(ph, channels, "context");
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
hexchat_list_free(ph, channels);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive the field for own user in current context
|
||||
* @return the field value
|
||||
*/
|
||||
char *get_my_info(const char *field, gboolean find_in_other_context) {
|
||||
char *result = NULL;
|
||||
const char *own_nick;
|
||||
hexchat_list *list;
|
||||
hexchat_context *ctx_current, *ctx_channel;
|
||||
|
||||
/* Display message */
|
||||
own_nick = hexchat_get_info(ph, "nick");
|
||||
|
||||
if (!own_nick)
|
||||
return NULL;
|
||||
|
||||
/* Get field for own nick if any */
|
||||
list = hexchat_list_get(ph, "users");
|
||||
if (list) {
|
||||
while (hexchat_list_next(ph, list)) {
|
||||
if (irc_nick_cmp(own_nick, hexchat_list_str(ph, list, "nick")) == 0)
|
||||
result = g_strdup(hexchat_list_str(ph, list, field));
|
||||
}
|
||||
hexchat_list_free(ph, list);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Try to get from a channel (we are outside a channel) */
|
||||
if (!find_in_other_context) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list = hexchat_list_get(ph, "channels");
|
||||
if (list) {
|
||||
ctx_current = hexchat_get_context(ph);
|
||||
while (hexchat_list_next(ph, list)) {
|
||||
ctx_channel = (hexchat_context *) hexchat_list_str(ph, list, "context");
|
||||
|
||||
hexchat_set_context(ph, ctx_channel);
|
||||
result = get_my_info(field, FALSE);
|
||||
hexchat_set_context(ph, ctx_current);
|
||||
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
hexchat_list_free(ph, list);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive the prefix character for own nick in current context
|
||||
* @return @ or + or NULL
|
||||
*/
|
||||
char *get_my_own_prefix(void) {
|
||||
return get_my_info("prefix", FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive the mask for own nick in current context
|
||||
* @return Host name in the form: user@host (or NULL if not known)
|
||||
*/
|
||||
char *get_my_own_host(void) {
|
||||
return get_my_info("host", TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the length of prefix for current user in current context
|
||||
*
|
||||
* @return Length of prefix
|
||||
*/
|
||||
int get_prefix_length(void) {
|
||||
char *own_host;
|
||||
int prefix_len = 0;
|
||||
|
||||
/* ':! ' + 'nick' + 'ident@host', e.g. ':user!~name@mynet.com ' */
|
||||
prefix_len = 3 + strlen(hexchat_get_info(ph, "nick"));
|
||||
own_host = get_my_own_host();
|
||||
if (own_host) {
|
||||
prefix_len += strlen(own_host);
|
||||
} else {
|
||||
/* https://stackoverflow.com/questions/8724954/what-is-the-maximum-number-of-characters-for-a-host-name-in-unix */
|
||||
prefix_len += 64;
|
||||
}
|
||||
g_free(own_host);
|
||||
|
||||
return prefix_len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to decrypt the first occurrence of fish message
|
||||
*
|
||||
* @param message Message to decrypt
|
||||
* @param key Key of message
|
||||
* @return Array of char with decrypted message or NULL. The returned string
|
||||
* should be freed with g_free() when no longer needed.
|
||||
*/
|
||||
char *decrypt_raw_message(const char *message, const char *key) {
|
||||
const char *prefixes[] = {"+OK ", "mcps ", NULL};
|
||||
char *start = NULL, *end = NULL;
|
||||
char *left = NULL, *right = NULL;
|
||||
char *encrypted = NULL, *decrypted = NULL;
|
||||
int length = 0;
|
||||
int index_prefix;
|
||||
enum fish_mode mode;
|
||||
GString *message_decrypted;
|
||||
char *result = NULL;
|
||||
|
||||
if (message == NULL || key == NULL)
|
||||
return NULL;
|
||||
|
||||
for (index_prefix = 0; index_prefix < 2; index_prefix++) {
|
||||
start = g_strstr_len(message, strlen(message), prefixes[index_prefix]);
|
||||
if (start) {
|
||||
/* Length ALWAYS will be less that original message
|
||||
* add '[CBC] ' length */
|
||||
message_decrypted = g_string_sized_new(strlen(message) + 6);
|
||||
|
||||
/* Left part of message */
|
||||
left = g_strndup(message, start - message);
|
||||
g_string_append(message_decrypted, left);
|
||||
g_free(left);
|
||||
|
||||
/* Encrypted part */
|
||||
start += strlen(prefixes[index_prefix]);
|
||||
end = g_strstr_len(start, strlen(message), " ");
|
||||
if (end) {
|
||||
length = end - start;
|
||||
right = end;
|
||||
}
|
||||
|
||||
if (length > 0) {
|
||||
encrypted = g_strndup(start, length);
|
||||
} else {
|
||||
encrypted = g_strdup(start);
|
||||
}
|
||||
decrypted = fish_decrypt_from_nick(key, encrypted, &mode);
|
||||
g_free(encrypted);
|
||||
|
||||
if (decrypted == NULL) {
|
||||
g_string_free(message_decrypted, TRUE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add encrypted flag */
|
||||
g_string_append(message_decrypted, "[");
|
||||
g_string_append(message_decrypted, fish_modes[mode]);
|
||||
g_string_append(message_decrypted, "] ");
|
||||
/* Decrypted message */
|
||||
g_string_append(message_decrypted, decrypted);
|
||||
g_free(decrypted);
|
||||
|
||||
/* Right part of message */
|
||||
if (right) {
|
||||
g_string_append(message_decrypted, right);
|
||||
}
|
||||
|
||||
result = message_decrypted->str;
|
||||
g_string_free(message_decrypted, FALSE);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
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) {
|
||||
@ -290,49 +75,20 @@ char *decrypt_raw_message(const char *message, const char *key) {
|
||||
* Called when a message is to be sent.
|
||||
*/
|
||||
static int handle_outgoing(char *word[], char *word_eol[], void *userdata) {
|
||||
char *prefix;
|
||||
enum fish_mode mode;
|
||||
char *message;
|
||||
GString *command;
|
||||
GSList *encrypted_list, *encrypted_item;
|
||||
|
||||
const char *own_nick;
|
||||
/* Encrypt the message if possible */
|
||||
const char *channel = hexchat_get_info(ph, "channel");
|
||||
|
||||
/* Check if we can encrypt */
|
||||
if (!fish_nick_has_key(channel)) return HEXCHAT_EAT_NONE;
|
||||
|
||||
command = g_string_new("");
|
||||
g_string_printf(command, "PRIVMSG %s :+OK ", channel);
|
||||
|
||||
encrypted_list = fish_encrypt_for_nick(channel, word_eol[1], &mode, get_prefix_length() + command->len);
|
||||
if (!encrypted_list) {
|
||||
g_string_free(command, TRUE);
|
||||
return HEXCHAT_EAT_NONE;
|
||||
}
|
||||
|
||||
/* Get prefix for own nick if any */
|
||||
prefix = get_my_own_prefix();
|
||||
|
||||
/* Add encrypted flag */
|
||||
message = g_strconcat("[", fish_modes[mode], "] ", word_eol[1], NULL);
|
||||
|
||||
char *encrypted = fish_encrypt_for_nick(channel, word_eol[1]);
|
||||
if (!encrypted) return HEXCHAT_EAT_NONE;
|
||||
|
||||
/* Display message */
|
||||
hexchat_emit_print(ph, "Your Message", hexchat_get_info(ph, "nick"), message, prefix, NULL);
|
||||
g_free(message);
|
||||
|
||||
/* Send encrypted messages */
|
||||
encrypted_item = encrypted_list;
|
||||
while (encrypted_item)
|
||||
{
|
||||
hexchat_commandf(ph, "%s%s", command->str, (char *)encrypted_item->data);
|
||||
|
||||
encrypted_item = encrypted_item->next;
|
||||
}
|
||||
|
||||
g_free(prefix);
|
||||
g_string_free(command, TRUE);
|
||||
g_slist_free_full(encrypted_list, g_free);
|
||||
|
||||
own_nick = hexchat_get_info(ph, "nick");
|
||||
hexchat_emit_print(ph, "Your Message", own_nick, word_eol[1], NULL);
|
||||
|
||||
/* Send message */
|
||||
hexchat_commandf(ph, "PRIVMSG %s :+OK %s", channel, encrypted);
|
||||
|
||||
g_free(encrypted);
|
||||
return HEXCHAT_EAT_HEXCHAT;
|
||||
}
|
||||
|
||||
@ -343,125 +99,96 @@ static int handle_incoming(char *word[], char *word_eol[], hexchat_event_attrs *
|
||||
const char *prefix;
|
||||
const char *command;
|
||||
const char *recipient;
|
||||
const char *raw_message = word_eol[1];
|
||||
const char *encrypted;
|
||||
const char *peice;
|
||||
char *sender_nick;
|
||||
char *decrypted;
|
||||
size_t parameters_offset;
|
||||
size_t w;
|
||||
size_t ew;
|
||||
size_t uw;
|
||||
char prefix_char = 0;
|
||||
GString *message;
|
||||
|
||||
if (!irc_parse_message((const char **)word, &prefix, &command, ¶meters_offset))
|
||||
if (!irc_parse_message((const char **)word, &prefix, &command, &w))
|
||||
return HEXCHAT_EAT_NONE;
|
||||
|
||||
|
||||
/* Topic (command 332) has an extra parameter */
|
||||
if (!strcmp(command, "332"))
|
||||
parameters_offset++;
|
||||
|
||||
/* Extract sender nick and recipient nick/channel and try to decrypt */
|
||||
recipient = word[parameters_offset];
|
||||
decrypted = decrypt_raw_message(raw_message, recipient);
|
||||
if (decrypted == NULL) {
|
||||
sender_nick = irc_prefix_get_nick(prefix);
|
||||
decrypted = decrypt_raw_message(raw_message, sender_nick);
|
||||
g_free(sender_nick);
|
||||
if (!strcmp(command, "332")) w++;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* Nothing to decrypt */
|
||||
if (decrypted == NULL)
|
||||
return HEXCHAT_EAT_NONE;
|
||||
|
||||
/* Build decrypted message */
|
||||
|
||||
/* decrypted + 'RECV ' + '@time=YYYY-MM-DDTHH:MM:SS.fffffZ ' */
|
||||
message = g_string_sized_new (strlen(decrypted) + 5 + 33);
|
||||
g_string_append (message, "RECV ");
|
||||
return HEXCHAT_EAT_NONE;
|
||||
has_encrypted_data: ;
|
||||
/* 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) */
|
||||
encrypted = word[ew+1];
|
||||
decrypted = fish_decrypt_from_nick(recipient, encrypted);
|
||||
if (!decrypted) decrypted = fish_decrypt_from_nick(sender_nick, encrypted);
|
||||
|
||||
/* 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, " @time=");
|
||||
g_string_append (message, timestamp);
|
||||
g_string_append (message, " ");
|
||||
g_free (timestamp);
|
||||
}
|
||||
|
||||
g_string_append (message, decrypted);
|
||||
g_free(decrypted);
|
||||
|
||||
/* Fake server message
|
||||
* RECV command will throw this function again, if message have multiple
|
||||
* encrypted data, we will decrypt all */
|
||||
hexchat_command(ph, message->str);
|
||||
g_string_free (message, TRUE);
|
||||
|
||||
return HEXCHAT_EAT_HEXCHAT;
|
||||
}
|
||||
|
||||
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;
|
||||
char *sender, *secret_key, *priv_key = NULL;
|
||||
enum fish_mode mode = FISH_ECB_MODE;
|
||||
|
||||
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)
|
||||
g_assert(hexchat_set_context(ph, query_ctx) == 1);
|
||||
|
||||
dh_message++; /* : prefix */
|
||||
|
||||
if (g_strcmp0 (word[6], "CBC") == 0)
|
||||
mode = FISH_CBC_MODE;
|
||||
|
||||
if (!strcmp(dh_message, "DH1080_INIT")) {
|
||||
char *pub_key;
|
||||
|
||||
hexchat_printf(ph, "Received public key from %s (%s), sending mine...", sender, fish_modes[mode]);
|
||||
if (dh1080_generate_key(&priv_key, &pub_key)) {
|
||||
hexchat_commandf(ph, "quote NOTICE %s :DH1080_FINISH %s%s", sender, pub_key, (mode == FISH_CBC_MODE) ? " CBC" : "");
|
||||
g_free(pub_key);
|
||||
for (uw = 1; uw < HEXCHAT_MAX_WORDS; uw++) {
|
||||
if (word[uw][0] != '\0')
|
||||
g_string_append_c (message, ' ');
|
||||
|
||||
if (uw == ew) {
|
||||
/* Add the encrypted data */
|
||||
peice = decrypted;
|
||||
uw++; /* Skip "OK+" */
|
||||
|
||||
if (ew == w+1) {
|
||||
/* Prefix with colon, which gets stripped out otherwise */
|
||||
g_string_append_c (message, ':');
|
||||
}
|
||||
|
||||
if (prefix_char) {
|
||||
g_string_append_c (message, prefix_char);
|
||||
}
|
||||
|
||||
} else {
|
||||
hexchat_print(ph, "Failed to generate keys");
|
||||
goto cleanup;
|
||||
/* Add unencrypted data (for example, a prefix from a bouncer or bot) */
|
||||
peice = word[uw];
|
||||
}
|
||||
} 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 (!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;
|
||||
g_string_append (message, peice);
|
||||
}
|
||||
g_free(decrypted);
|
||||
|
||||
/* Simulate unencrypted message */
|
||||
/* hexchat_printf(ph, "simulating: %s\n", message->str); */
|
||||
hexchat_command(ph, message->str);
|
||||
|
||||
if (dh1080_compute_key(priv_key, dh_pubkey, &secret_key)) {
|
||||
keystore_store_key(sender, secret_key, mode);
|
||||
hexchat_printf(ph, "Stored new key for %s (%s)", sender, fish_modes[mode]);
|
||||
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;
|
||||
g_string_free (message, TRUE);
|
||||
g_free(sender_nick);
|
||||
return HEXCHAT_EAT_HEXCHAT;
|
||||
|
||||
decrypt_error:
|
||||
g_free(decrypted);
|
||||
g_free(sender_nick);
|
||||
return HEXCHAT_EAT_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -470,14 +197,13 @@ cleanup:
|
||||
static int handle_setkey(char *word[], char *word_eol[], void *userdata) {
|
||||
const char *nick;
|
||||
const char *key;
|
||||
enum fish_mode mode;
|
||||
|
||||
|
||||
/* Check syntax */
|
||||
if (*word[2] == '\0') {
|
||||
hexchat_printf(ph, "%s\n", usage_setkey);
|
||||
return HEXCHAT_EAT_HEXCHAT;
|
||||
}
|
||||
|
||||
|
||||
if (*word[3] == '\0') {
|
||||
/* /setkey password */
|
||||
nick = hexchat_get_info(ph, "channel");
|
||||
@ -487,22 +213,14 @@ static int handle_setkey(char *word[], char *word_eol[], void *userdata) {
|
||||
nick = word[2];
|
||||
key = word_eol[3];
|
||||
}
|
||||
|
||||
mode = FISH_ECB_MODE;
|
||||
if (g_ascii_strncasecmp("cbc:", key, 4) == 0) {
|
||||
key = key+4;
|
||||
mode = FISH_CBC_MODE;
|
||||
} else if (g_ascii_strncasecmp("ecb:", key, 4) == 0) {
|
||||
key = key+4;
|
||||
}
|
||||
|
||||
|
||||
/* Set password */
|
||||
if (keystore_store_key(nick, key, mode)) {
|
||||
hexchat_printf(ph, "Stored key for %s (%s)\n", nick, fish_modes[mode]);
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
return HEXCHAT_EAT_HEXCHAT;
|
||||
}
|
||||
|
||||
@ -510,268 +228,26 @@ static int handle_setkey(char *word[], char *word_eol[], void *userdata) {
|
||||
* Command handler for /delkey
|
||||
*/
|
||||
static int handle_delkey(char *word[], char *word_eol[], void *userdata) {
|
||||
char *nick = NULL;
|
||||
int ctx_type = 0;
|
||||
|
||||
/* Delete key from input */
|
||||
if (*word[2] != '\0') {
|
||||
nick = g_strstrip(g_strdup(word_eol[2]));
|
||||
} else { /* Delete key from current context */
|
||||
nick = g_strdup(hexchat_get_info(ph, "channel"));
|
||||
ctx_type = hexchat_list_int(ph, NULL, "type");
|
||||
|
||||
/* Only allow channel or dialog */
|
||||
if (ctx_type < 2 || ctx_type > 3) {
|
||||
hexchat_printf(ph, "%s\n", usage_delkey);
|
||||
return HEXCHAT_EAT_HEXCHAT;
|
||||
}
|
||||
const char *nick;
|
||||
|
||||
/* 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 */
|
||||
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");
|
||||
}
|
||||
g_free(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) {
|
||||
g_assert(hexchat_set_context(ph, query_ctx) == 1);
|
||||
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 CBC", target, pub_key);
|
||||
hexchat_printf(ph, "Sent public key to %s (CBC), 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];
|
||||
enum fish_mode mode;
|
||||
GString *command;
|
||||
GSList *encrypted_list;
|
||||
|
||||
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");
|
||||
|
||||
/* Check if we can encrypt */
|
||||
if (!fish_nick_has_key(target)) {
|
||||
hexchat_printf(ph, "/topic+ error, no key found for %s", target);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
command = g_string_new("");
|
||||
g_string_printf(command, "TOPIC %s +OK ", target);
|
||||
|
||||
encrypted_list = fish_encrypt_for_nick(target, topic, &mode, get_prefix_length() + command->len);
|
||||
if (!encrypted_list) {
|
||||
g_string_free(command, TRUE);
|
||||
hexchat_printf(ph, "/topic+ error, can't encrypt %s", target);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
hexchat_commandf(ph, "%s%s", command->str, (char *) encrypted_list->data);
|
||||
|
||||
g_string_free(command, TRUE);
|
||||
g_slist_free_full(encrypted_list, g_free);
|
||||
|
||||
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 *notice_flag;
|
||||
enum fish_mode mode;
|
||||
GString *command;
|
||||
GSList *encrypted_list, *encrypted_item;
|
||||
|
||||
if (!*target || !*notice) {
|
||||
hexchat_print(ph, usage_notice);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
/* Check if we can encrypt */
|
||||
if (!fish_nick_has_key(target)) {
|
||||
hexchat_printf(ph, "/notice+ error, no key found for %s.", target);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
command = g_string_new("");
|
||||
g_string_printf(command, "quote NOTICE %s :+OK ", target);
|
||||
|
||||
encrypted_list = fish_encrypt_for_nick(target, notice, &mode, get_prefix_length() + command->len);
|
||||
if (!encrypted_list) {
|
||||
g_string_free(command, TRUE);
|
||||
hexchat_printf(ph, "/notice+ error, can't encrypt %s", target);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
notice_flag = g_strconcat("[", fish_modes[mode], "] ", notice, NULL);
|
||||
hexchat_emit_print(ph, "Notice Send", target, notice_flag);
|
||||
|
||||
/* Send encrypted messages */
|
||||
encrypted_item = encrypted_list;
|
||||
while (encrypted_item) {
|
||||
hexchat_commandf(ph, "%s%s", command->str, (char *) encrypted_item->data);
|
||||
|
||||
encrypted_item = encrypted_item->next;
|
||||
}
|
||||
|
||||
g_free(notice_flag);
|
||||
g_string_free(command, TRUE);
|
||||
g_slist_free_full(encrypted_list, g_free);
|
||||
|
||||
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];
|
||||
char *message_flag;
|
||||
char *prefix;
|
||||
hexchat_context *query_ctx;
|
||||
enum fish_mode mode;
|
||||
GString *command;
|
||||
GSList *encrypted_list, *encrypted_item;
|
||||
|
||||
if (!*target || !*message) {
|
||||
hexchat_print(ph, usage_msg);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
/* Check if we can encrypt */
|
||||
if (!fish_nick_has_key(target)) {
|
||||
hexchat_printf(ph, "/msg+ error, no key found for %s", target);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
command = g_string_new("");
|
||||
g_string_printf(command, "PRIVMSG %s :+OK ", target);
|
||||
|
||||
encrypted_list = fish_encrypt_for_nick(target, message, &mode, get_prefix_length() + command->len);
|
||||
if (!encrypted_list) {
|
||||
g_string_free(command, TRUE);
|
||||
hexchat_printf(ph, "/msg+ error, can't encrypt %s", target);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
/* Send encrypted messages */
|
||||
encrypted_item = encrypted_list;
|
||||
while (encrypted_item) {
|
||||
hexchat_commandf(ph, "%s%s", command->str, (char *) encrypted_item->data);
|
||||
|
||||
encrypted_item = encrypted_item->next;
|
||||
}
|
||||
|
||||
g_string_free(command, TRUE);
|
||||
g_slist_free_full(encrypted_list, g_free);
|
||||
|
||||
query_ctx = find_context_on_network(target);
|
||||
if (query_ctx) {
|
||||
g_assert(hexchat_set_context(ph, query_ctx) == 1);
|
||||
|
||||
prefix = get_my_own_prefix();
|
||||
|
||||
/* Add encrypted flag */
|
||||
message_flag = g_strconcat("[", fish_modes[mode], "] ", message, NULL);
|
||||
hexchat_emit_print(ph, "Your Message", hexchat_get_info(ph, "nick"), message_flag, prefix, NULL);
|
||||
g_free(prefix);
|
||||
g_free(message_flag);
|
||||
} else {
|
||||
hexchat_emit_print(ph, "Message Send", target, message);
|
||||
}
|
||||
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
static int handle_crypt_me(char *word[], char *word_eol[], void *userdata) {
|
||||
const char *channel = hexchat_get_info(ph, "channel");
|
||||
enum fish_mode mode;
|
||||
GString *command;
|
||||
GSList *encrypted_list, *encrypted_item;
|
||||
|
||||
/* Check if we can encrypt */
|
||||
if (!fish_nick_has_key(channel)) {
|
||||
return HEXCHAT_EAT_NONE;
|
||||
}
|
||||
|
||||
command = g_string_new("");
|
||||
g_string_printf(command, "PRIVMSG %s :\001ACTION +OK ", channel);
|
||||
|
||||
/* 2 = ' \001' */
|
||||
encrypted_list = fish_encrypt_for_nick(channel, word_eol[2], &mode, get_prefix_length() + command->len + 2);
|
||||
if (!encrypted_list) {
|
||||
g_string_free(command, TRUE);
|
||||
hexchat_printf(ph, "/me error, can't encrypt %s", channel);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
hexchat_emit_print(ph, "Your Action", hexchat_get_info(ph, "nick"), word_eol[2], NULL);
|
||||
|
||||
/* Send encrypted messages */
|
||||
encrypted_item = encrypted_list;
|
||||
while (encrypted_item) {
|
||||
hexchat_commandf(ph, "%s%s \001", command->str, (char *) encrypted_item->data);
|
||||
|
||||
encrypted_item = encrypted_item->next;
|
||||
}
|
||||
|
||||
g_string_free(command, TRUE);
|
||||
g_slist_free_full(encrypted_list, g_free);
|
||||
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the plugin name version information.
|
||||
*/
|
||||
@ -791,48 +267,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 (!fish_init())
|
||||
return 0;
|
||||
|
||||
if (!dh1080_init())
|
||||
return 0;
|
||||
|
||||
pending_exchanges = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
|
||||
|
||||
|
||||
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();
|
||||
fish_deinit();
|
||||
|
||||
hexchat_printf(ph, "%s plugin unloaded\n", plugin_name);
|
||||
return 1;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
#ifndef PLUGIN_HEXCHAT_H
|
||||
#define PLUGIN_HEXCHAT_H
|
||||
|
||||
gchar *get_config_filename(void);
|
||||
gchar *get_config_filename();
|
||||
int irc_nick_cmp (const char *, const char *);
|
||||
|
||||
#endif
|
||||
|
94
plugins/fishlim/test.c
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "fish.h"
|
||||
|
||||
// We can't use the HexChat plugin API from here...
|
||||
gchar *get_config_filename() {
|
||||
const gchar *homedir = g_get_home_dir();
|
||||
return g_build_filename(homedir, ".config", "hexchat", "blow.ini", NULL);
|
||||
}
|
||||
|
||||
|
||||
static int decrypt(int nick_count, char *nicks[]) {
|
||||
char encrypted[8192];
|
||||
while (fgets(encrypted, sizeof(encrypted), stdin)) {
|
||||
char *msg;
|
||||
for (int i = 0; i < nick_count; i++) {
|
||||
msg = fish_decrypt_from_nick(nicks[i], encrypted);
|
||||
if (msg) goto success;
|
||||
}
|
||||
fprintf(stderr, "None of the recipients were found in the key store!\n");
|
||||
return 1;
|
||||
success:
|
||||
fprintf(stderr, "Decrypted text >>>%s<<<\n", msg);
|
||||
g_free(msg);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int encrypt(int nick_count, char *nicks[]) {
|
||||
char message[8192];
|
||||
while (fgets(message, sizeof(message), stdin)) {
|
||||
// Remove newline character
|
||||
char *newline = strchr(message, '\n');
|
||||
if (newline) *newline = '\0';
|
||||
|
||||
bool error = false;
|
||||
for (int i = 0; i < nick_count; i++) {
|
||||
char *encrypted = fish_encrypt_for_nick(nicks[i], message);
|
||||
if (encrypted) {
|
||||
fprintf(stderr, "Encrypted [%s]: >>>%s<<<\n", nicks[i], encrypted);
|
||||
g_free(encrypted);
|
||||
} else {
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (error) {
|
||||
fprintf(stderr, "Some of the recipients were't found in the key store!\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "usage: %s [-e] nick...\n", argv[0]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "-e") == 0) {
|
||||
return encrypt(argc-2, &argv[2]);
|
||||
} else {
|
||||
return decrypt(argc-1, &argv[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
fishlim_test_sources = [
|
||||
'tests.c',
|
||||
'mock-keystore.c',
|
||||
'../fish.c',
|
||||
'../utils.c',
|
||||
]
|
||||
|
||||
fishlim_tests = executable('fishlim_tests', fishlim_test_sources,
|
||||
dependencies: [libgio_dep, libssl_dep, hexchat_plugin_dep],
|
||||
include_directories: include_directories('..'),
|
||||
)
|
||||
|
||||
test('Fishlim Tests', fishlim_tests,
|
||||
protocol: 'tap',
|
||||
timeout: 600,
|
||||
)
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2010 Samuel Lidén Borell <samuel@kodafritt.se>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#include "fish.h"
|
||||
|
||||
/**
|
||||
* Extracts a key from the key store file.
|
||||
*/
|
||||
char *
|
||||
keystore_get_key(const char *nick, enum fish_mode *mode)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a key in the key store file.
|
||||
*/
|
||||
gboolean
|
||||
keystore_store_key(const char *nick, const char *key, enum fish_mode mode)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a nick from the key store.
|
||||
*/
|
||||
gboolean
|
||||
keystore_delete_nick(const char *nick)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
@ -1,285 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2020 <bakasura@protonmail.ch>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "fish.h"
|
||||
#include "utils.h"
|
||||
|
||||
/**
|
||||
* Auxiliary function: Generate a random string
|
||||
* @param out Preallocated string to fill
|
||||
* @param len Size of bytes to fill
|
||||
*/
|
||||
static void
|
||||
random_string(char *out, size_t len)
|
||||
{
|
||||
GRand *rand = NULL;
|
||||
int i = 0;
|
||||
|
||||
rand = g_rand_new();
|
||||
for (i = 0; i < len; ++i) {
|
||||
out[i] = g_rand_int_range(rand, 1, 256);
|
||||
}
|
||||
|
||||
out[len] = 0;
|
||||
|
||||
g_rand_free(rand);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check encrypt and decrypt in ECB mode
|
||||
*/
|
||||
static void
|
||||
test_ecb(void)
|
||||
{
|
||||
char *b64 = NULL;
|
||||
char *de = NULL;
|
||||
int key_len, message_len = 0;
|
||||
char key[57];
|
||||
char message[1000];
|
||||
|
||||
/* Generate key 32–448 bits (Yes, I start with 8 bits) */
|
||||
for (key_len = 1; key_len < 57; ++key_len) {
|
||||
|
||||
random_string(key, key_len);
|
||||
|
||||
for (message_len = 1; message_len < 1000; ++message_len) {
|
||||
random_string(message, message_len);
|
||||
|
||||
/* Encrypt */
|
||||
b64 = fish_encrypt(key, key_len, message, message_len, FISH_ECB_MODE);
|
||||
g_assert_nonnull(b64);
|
||||
|
||||
/* Decrypt */
|
||||
/* Linear */
|
||||
de = fish_decrypt_str(key, key_len, b64, FISH_ECB_MODE);
|
||||
g_assert_cmpstr (de, ==, message);
|
||||
g_free(de);
|
||||
|
||||
/* Mixed */
|
||||
de = fish_decrypt_str(key, key_len, b64, FISH_ECB_MODE);
|
||||
g_assert_cmpstr (de, ==, message);
|
||||
g_free(de);
|
||||
|
||||
g_free(b64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check encrypt and decrypt in CBC mode
|
||||
*/
|
||||
static void
|
||||
test_cbc(void)
|
||||
{
|
||||
char *b64 = NULL;
|
||||
char *de = NULL;
|
||||
int key_len, message_len = 0;
|
||||
char key[57];
|
||||
char message[1000];
|
||||
|
||||
/* Generate key 32–448 bits (Yes, I start with 8 bits) */
|
||||
for (key_len = 1; key_len < 57; ++key_len) {
|
||||
|
||||
random_string(key, key_len);
|
||||
|
||||
for (message_len = 1; message_len < 1000; ++message_len) {
|
||||
random_string(message, message_len);
|
||||
|
||||
/* Encrypt */
|
||||
b64 = fish_encrypt(key, key_len, message, message_len, FISH_CBC_MODE);
|
||||
g_assert_nonnull(b64);
|
||||
|
||||
/* Decrypt */
|
||||
/* Linear */
|
||||
de = fish_decrypt_str(key, key_len, b64, FISH_CBC_MODE);
|
||||
g_assert_cmpstr (de, ==, message);
|
||||
g_free(de);
|
||||
|
||||
g_free(b64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the calculation of final length from an encoded string in Base64
|
||||
*/
|
||||
static void
|
||||
test_base64_len (void)
|
||||
{
|
||||
char *b64 = NULL;
|
||||
char message[1000];
|
||||
int message_end = sizeof (message) - 1;
|
||||
|
||||
random_string(message, message_end);
|
||||
|
||||
for (; message_end >= 0; --message_end) {
|
||||
message[message_end] = '\0'; /* Truncate instead of generating new strings */
|
||||
b64 = g_base64_encode((const unsigned char *) message, message_end);
|
||||
g_assert_nonnull(b64);
|
||||
g_assert_cmpuint(strlen(b64), == , base64_len(message_end));
|
||||
g_free(b64);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the calculation of final length from an encoded string in BlowcryptBase64
|
||||
*/
|
||||
static void
|
||||
test_base64_fish_len (void)
|
||||
{
|
||||
char *b64 = NULL;
|
||||
int message_len = 0;
|
||||
char message[1000];
|
||||
|
||||
for (message_len = 1; message_len < 1000; ++message_len) {
|
||||
random_string(message, message_len);
|
||||
b64 = fish_base64_encode(message, message_len);
|
||||
g_assert_nonnull(b64);
|
||||
g_assert_cmpuint(strlen(b64), == , base64_fish_len(message_len));
|
||||
g_free(b64);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the calculation of final length from an encrypted string in ECB mode
|
||||
*/
|
||||
static void
|
||||
test_base64_ecb_len(void)
|
||||
{
|
||||
char *b64 = NULL;
|
||||
int key_len, message_len = 0;
|
||||
char key[57];
|
||||
char message[1000];
|
||||
|
||||
/* Generate key 32–448 bits (Yes, I start with 8 bits) */
|
||||
for (key_len = 1; key_len < 57; ++key_len) {
|
||||
|
||||
random_string(key, key_len);
|
||||
|
||||
for (message_len = 1; message_len < 1000; ++message_len) {
|
||||
random_string(message, message_len);
|
||||
b64 = fish_encrypt(key, key_len, message, message_len, FISH_ECB_MODE);
|
||||
g_assert_nonnull(b64);
|
||||
g_assert_cmpuint(strlen(b64), == , ecb_len(message_len));
|
||||
g_free(b64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the calculation of final length from an encrypted string in CBC mode
|
||||
*/
|
||||
static void
|
||||
test_base64_cbc_len(void)
|
||||
{
|
||||
char *b64 = NULL;
|
||||
int key_len, message_len = 0;
|
||||
char key[57];
|
||||
char message[1000];
|
||||
|
||||
/* Generate key 32–448 bits (Yes, I start with 8 bits) */
|
||||
for (key_len = 1; key_len < 57; ++key_len) {
|
||||
|
||||
random_string(key, key_len);
|
||||
|
||||
for (message_len = 1; message_len < 1000; ++message_len) {
|
||||
random_string(message, message_len);
|
||||
b64 = fish_encrypt(key, key_len, message, message_len, FISH_CBC_MODE);
|
||||
g_assert_nonnull(b64);
|
||||
g_assert_cmpuint(strlen(b64), == , cbc_len(message_len));
|
||||
g_free(b64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the calculation of length limit for a plaintext in each encryption mode
|
||||
*/
|
||||
static void
|
||||
test_max_text_command_len(void)
|
||||
{
|
||||
int max_encoded_len, plaintext_len;
|
||||
enum fish_mode mode;
|
||||
|
||||
for (max_encoded_len = 0; max_encoded_len < 10000; ++max_encoded_len) {
|
||||
for (mode = FISH_ECB_MODE; mode <= FISH_CBC_MODE; ++mode) {
|
||||
plaintext_len = max_text_command_len(max_encoded_len, mode);
|
||||
g_assert_cmpuint(encoded_len(plaintext_len, mode), <= , max_encoded_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the calculation of length limit for a plaintext in each encryption mode
|
||||
*/
|
||||
static void
|
||||
test_foreach_utf8_data_chunks(void)
|
||||
{
|
||||
GRand *rand = NULL;
|
||||
GString *chunks = NULL;
|
||||
int max_chunks_len, chunks_len;
|
||||
char ascii_message[1001];
|
||||
char *data_chunk = NULL;
|
||||
|
||||
rand = g_rand_new();
|
||||
max_chunks_len = g_rand_int_range(rand, 2, 301);
|
||||
random_string(ascii_message, 1000);
|
||||
|
||||
data_chunk = ascii_message;
|
||||
|
||||
chunks = g_string_new(NULL);
|
||||
|
||||
while (foreach_utf8_data_chunks(data_chunk, max_chunks_len, &chunks_len)) {
|
||||
g_string_append(chunks, g_strndup(data_chunk, chunks_len));
|
||||
/* Next chunk */
|
||||
data_chunk += chunks_len;
|
||||
}
|
||||
/* Check data loss */
|
||||
g_assert_cmpstr(chunks->str, == , ascii_message);
|
||||
|
||||
g_string_free(chunks, TRUE);
|
||||
g_rand_free (rand);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func("/fishlim/ecb", test_ecb);
|
||||
g_test_add_func("/fishlim/cbc", test_cbc);
|
||||
g_test_add_func("/fishlim/base64_len", test_base64_len);
|
||||
g_test_add_func("/fishlim/base64_fish_len", test_base64_fish_len);
|
||||
g_test_add_func("/fishlim/base64_ecb_len", test_base64_ecb_len);
|
||||
g_test_add_func("/fishlim/base64_cbc_len", test_base64_cbc_len);
|
||||
g_test_add_func("/fishlim/max_text_command_len", test_max_text_command_len);
|
||||
g_test_add_func("/fishlim/foreach_utf8_data_chunks", test_foreach_utf8_data_chunks);
|
||||
|
||||
fish_init();
|
||||
int ret = g_test_run();
|
||||
fish_deinit();
|
||||
return ret;
|
||||
}
|
@ -1,151 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020 <bakasura@protonmail.ch>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "fish.h"
|
||||
|
||||
/**
|
||||
* Calculate the length of Base64-encoded string
|
||||
*
|
||||
* @param plaintext_len Size of clear text to encode
|
||||
* @return Size of encoded string
|
||||
*/
|
||||
unsigned long base64_len(size_t plaintext_len) {
|
||||
int length_unpadded = (4 * plaintext_len) / 3;
|
||||
/* Add padding */
|
||||
return length_unpadded % 4 != 0 ? length_unpadded + (4 - length_unpadded % 4) : length_unpadded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the length of BlowcryptBase64-encoded string
|
||||
*
|
||||
* @param plaintext_len Size of clear text to encode
|
||||
* @return Size of encoded string
|
||||
*/
|
||||
unsigned long base64_fish_len(size_t plaintext_len) {
|
||||
int length_unpadded = (12 * plaintext_len) / 8;
|
||||
/* Add padding */
|
||||
return length_unpadded % 12 != 0 ? length_unpadded + (12 - length_unpadded % 12) : length_unpadded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the length of fish-encrypted string in CBC mode
|
||||
*
|
||||
* @param plaintext_len Size of clear text to encode
|
||||
* @return Size of encoded string
|
||||
*/
|
||||
unsigned long cbc_len(size_t plaintext_len) {
|
||||
/*IV + DATA + Zero Padding */
|
||||
return base64_len(8 + (plaintext_len % 8 != 0 ? plaintext_len + 8 - (plaintext_len % 8) : plaintext_len));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the length of fish-encrypted string in ECB mode
|
||||
*
|
||||
* @param plaintext_len Size of clear text to encode
|
||||
* @return Size of encoded string
|
||||
*/
|
||||
unsigned long ecb_len(size_t plaintext_len) {
|
||||
return base64_fish_len(plaintext_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the length of encrypted string in 'mode' mode
|
||||
*
|
||||
* @param plaintext_len Length of plaintext
|
||||
* @param mode Encryption mode
|
||||
* @return Size of encoded string
|
||||
*/
|
||||
unsigned long encoded_len(size_t plaintext_len, enum fish_mode mode) {
|
||||
switch (mode) {
|
||||
|
||||
case FISH_CBC_MODE:
|
||||
return cbc_len(plaintext_len);
|
||||
break;
|
||||
|
||||
case FISH_ECB_MODE:
|
||||
return ecb_len(plaintext_len);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the maximum length of plaintext for a 'max_len' limit taking care the overload of encryption
|
||||
*
|
||||
* @param max_len Limit for plaintext
|
||||
* @param mode Encryption mode
|
||||
* @return Maximum allowed plaintext length
|
||||
*/
|
||||
int max_text_command_len(size_t max_len, enum fish_mode mode) {
|
||||
int len;
|
||||
|
||||
for (len = max_len; encoded_len(len, mode) > max_len; --len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate over 'data' in chunks of 'max_chunk_len' taking care the UTF-8 characters
|
||||
*
|
||||
* @param data Data to iterate
|
||||
* @param max_chunk_len Size of biggest chunk
|
||||
* @param [out] chunk_len Current chunk length
|
||||
* @return Pointer to current chunk position or NULL if not have more chunks
|
||||
*/
|
||||
const char *foreach_utf8_data_chunks(const char *data, int max_chunk_len, int *chunk_len) {
|
||||
int data_len, last_chunk_len = 0;
|
||||
|
||||
if (!*data) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Last chunk of data */
|
||||
data_len = strlen(data);
|
||||
if (data_len <= max_chunk_len) {
|
||||
*chunk_len = data_len;
|
||||
return data;
|
||||
}
|
||||
|
||||
*chunk_len = 0;
|
||||
const char *utf8_character = data;
|
||||
|
||||
/* Not valid UTF-8, but maybe valid text, just split into max length */
|
||||
if (!g_utf8_validate(data, -1, NULL)) {
|
||||
*chunk_len = max_chunk_len;
|
||||
return utf8_character;
|
||||
}
|
||||
|
||||
while (*utf8_character && *chunk_len <= max_chunk_len) {
|
||||
last_chunk_len = *chunk_len;
|
||||
*chunk_len = (g_utf8_next_char(utf8_character) - data) * sizeof(*utf8_character);
|
||||
utf8_character = g_utf8_next_char(utf8_character);
|
||||
}
|
||||
|
||||
/* We need the previous length before overflow the limit */
|
||||
*chunk_len = last_chunk_len;
|
||||
|
||||
return utf8_character;
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2020 <bakasura@protonmail.ch>
|
||||
|
||||
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 PLUGIN_HEXCHAT_FISHLIM_UTILS_H
|
||||
#define PLUGIN_HEXCHAT_FISHLIM_UTILS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "fish.h"
|
||||
|
||||
unsigned long base64_len(size_t plaintext_len);
|
||||
unsigned long base64_fish_len(size_t plaintext_len);
|
||||
unsigned long cbc_len(size_t plaintext_len);
|
||||
unsigned long ecb_len(size_t plaintext_len);
|
||||
unsigned long encoded_len(size_t plaintext_len, enum fish_mode mode);
|
||||
int max_text_command_len(size_t max_len, enum fish_mode mode);
|
||||
const char *foreach_utf8_data_chunks(const char *data, int max_chunk_len, int *chunk_len);
|
||||
|
||||
#endif
|
1771
plugins/lua/lua.c
@ -1,14 +0,0 @@
|
||||
<?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>{f4eaf231-f095-42d3-8427-b2b6006cacb1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{0166c0f9-7968-4a09-9ef5-a5179c7746eb}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="lua.c" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,12 +0,0 @@
|
||||
if cc.get_id() == 'msvc'
|
||||
lua_dep = cc.find_library('lua51')
|
||||
else
|
||||
lua_dep = dependency(get_option('with-lua'))
|
||||
endif
|
||||
|
||||
shared_module('lua', 'lua.c',
|
||||
dependencies: [libgio_dep, hexchat_plugin_dep, lua_dep],
|
||||
install: true,
|
||||
install_dir: plugindir,
|
||||
name_prefix: '',
|
||||
)
|
@ -1,39 +0,0 @@
|
||||
plugindir = join_paths(get_option('libdir'), 'hexchat/plugins')
|
||||
|
||||
if host_machine.system() == 'windows'
|
||||
if get_option('with-exec')
|
||||
subdir('exec')
|
||||
endif
|
||||
|
||||
if get_option('with-upd')
|
||||
subdir('upd')
|
||||
endif
|
||||
|
||||
if get_option('with-winamp')
|
||||
subdir('winamp')
|
||||
endif
|
||||
endif
|
||||
|
||||
if get_option('with-checksum')
|
||||
subdir('checksum')
|
||||
endif
|
||||
|
||||
if get_option('with-fishlim')
|
||||
subdir('fishlim')
|
||||
endif
|
||||
|
||||
if get_option('with-lua') != 'false'
|
||||
subdir('lua')
|
||||
endif
|
||||
|
||||
if get_option('with-perl') != 'false'
|
||||
subdir('perl')
|
||||
endif
|
||||
|
||||
if get_option('with-python') != 'false'
|
||||
subdir('python')
|
||||
endif
|
||||
|
||||
if get_option('with-sysinfo')
|
||||
subdir('sysinfo')
|
||||
endif
|
156
plugins/mpcinfo/functions.c
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
char *split(char *text, char separator)
|
||||
{
|
||||
int pos = -1;
|
||||
size_t i;
|
||||
for (i = 0; i < strlen(text); i++)
|
||||
{
|
||||
if (text[i] == separator) {
|
||||
pos = i;
|
||||
i = strlen(text) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (pos == -1)
|
||||
{
|
||||
return text;
|
||||
}
|
||||
|
||||
text[pos] = 0;
|
||||
return &(text[pos + 1]);
|
||||
}
|
||||
|
||||
int endsWith(char *text, char *suffix){
|
||||
char *tmp=strstr(text,suffix);
|
||||
if (tmp==NULL) return 0;
|
||||
if (strlen(tmp)==strlen(suffix)) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int inStr(char *s1, size_t sl1, char *s2)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < sl1 - strlen(s2); i++)
|
||||
{
|
||||
size_t j;
|
||||
for (j = 0; j < strlen(s2); j++)
|
||||
{
|
||||
if (s1[i + j] != s2[j])
|
||||
{
|
||||
j = strlen(s2) + 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == strlen(s2))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static char *subString(char *text, int first, int length, int spcKill){
|
||||
//if (DEBUG==1) putlog("creating substring");
|
||||
char *ret = g_new (char, length + 1);
|
||||
int i;
|
||||
ret[length]=0;
|
||||
for (i=0;i<length;i++){
|
||||
ret[i]=text[i+first];
|
||||
//if (ret[i]==0) ret[i]='0';
|
||||
}
|
||||
if (spcKill==1){
|
||||
for (i=length-1;i>=0;i--){
|
||||
if (ret[i]==32) ret[i]=0;
|
||||
else i=-1;
|
||||
}
|
||||
}
|
||||
//if (DEBUG==1) putlog("substring created");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *substring(char *text, int first, int length){return subString(text,first,length,0);}
|
||||
|
||||
|
||||
char *readLine(FILE *f){
|
||||
//if (DEBUG==1) putlog("reading line from file");
|
||||
char *buffer = g_new (char, 1024);
|
||||
int pos=0;
|
||||
int cc=0;
|
||||
while((cc!=EOF)&&(pos<1024)&&(cc!=10)){
|
||||
cc=fgetc(f);
|
||||
if ((cc!=10)&&(cc!=13)){
|
||||
if (cc==EOF) buffer[pos]=0;
|
||||
else buffer[pos]=(char)cc;pos++;
|
||||
}
|
||||
}
|
||||
if (buffer[pos]==EOF) hexchat_printf(ph,"EOF: %i\n",pos);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char *toUpper(char *text)
|
||||
{
|
||||
char *ret = (char*) calloc(strlen(text) + 1, sizeof(char));
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < strlen(text); i++)
|
||||
{
|
||||
ret[i] = toupper(text[i]);
|
||||
}
|
||||
|
||||
ret[strlen(text)] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *str3cat(char *s1, char *s2, char *s3){
|
||||
//if (DEBUG==1) putlog("cating 3 strings");
|
||||
char *ret=(char*)calloc(strlen(s1)+strlen(s2)+strlen(s3)+1,sizeof(char));
|
||||
strcpy(ret,s1);strcat(ret,s2);strcat(ret,s3);
|
||||
ret[strlen(s1)+strlen(s2)+strlen(s3)]=0;
|
||||
//if (DEBUG==1) putlog("strings cated");
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *replace(char *text, char *from, char *to){
|
||||
//if (DEBUG==1) putlog("replacing");
|
||||
char *ret=(char*)calloc( strlen(text)+(strlen(to)-strlen(from)),sizeof(char));
|
||||
char *left;
|
||||
char *right;
|
||||
int pos=inStr(text,strlen(text),from);
|
||||
if (pos!=-1){
|
||||
left=substring(text,0,pos);
|
||||
right=substring(text,pos+strlen(from),strlen(text)-(pos+strlen(from)));
|
||||
ret=str3cat(left,to,right);
|
||||
return replace(ret,from,to);
|
||||
}
|
||||
//if (DEBUG==1) putlog("replaced");
|
||||
return text;
|
||||
}
|
||||
|
||||
char *intReplaceF(char *text, char *from, int to, char *form){
|
||||
//if (DEBUG==1) putlog("replaceF");
|
||||
char *buffer=(char*) calloc(16,sizeof(char));
|
||||
sprintf(buffer,form,to);
|
||||
//if (DEBUG==1) putlog("replaceF done");
|
||||
return replace(text,from,buffer);
|
||||
}
|
||||
|
||||
char *intReplace(char *text, char *from, int to){return intReplaceF(text,from,to,"%i");}
|
330
plugins/mpcinfo/mp3Info.c
Normal file
@ -0,0 +1,330 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
//#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
//#include "functions.c"
|
||||
|
||||
struct tagInfo{
|
||||
int mode;
|
||||
int cbr;
|
||||
int bitrate;
|
||||
unsigned int freq;
|
||||
char *artist;
|
||||
char *title;
|
||||
char *album;
|
||||
char *comment;
|
||||
char *genre;
|
||||
//int genre;
|
||||
//int track;
|
||||
};
|
||||
|
||||
static int RATES[2][3][15]={
|
||||
{//mpeg2
|
||||
{-1,8,16,24,32,64,80,56,64,128,160,112,128,256,320},//layer3 (V2)
|
||||
{-1,32,48,56,64,80,96,112,128,160,192,224,256,320,384},//layer2 (V2)
|
||||
{-1,32,64,96,128,160,192,224,256,288,320,352,384,416,448},//layer1 (V2)
|
||||
},
|
||||
{//mpeg1
|
||||
{-1,32,40,48,56,64,80,96,112,128,160,192,224,256,320},//layer3 (V1)
|
||||
{-1,32,48,56,64,80,96,112,128,160,192,224,256,320,384},//layer2 (V1)
|
||||
{-1,32,64,96,128,160,192,224,256,288,320,352,384,416,448},//layer1 (V1)
|
||||
}};
|
||||
static int FREQS[2][4]={{22050,24000,16000,-1},{44100,48000,32000,-1}};
|
||||
//static double FRATES[]={38.5,32.5,27.8,0.0};
|
||||
|
||||
static char GENRES[][50]={"Blues","Classic Rock","Country","Dance","Disco","Funk","Grunge","Hip-Hop","Jazz","Metal",
|
||||
"New Age","Oldies","Other","Pop","R&B","Rap","Reggae","Rock","Techno","Industrial",
|
||||
"Alternative","Ska","Death Metal","Pranks","Soundtrack","Euro-Techno","Ambient","Trip-Hop","Vocal","Jazz+Funk",
|
||||
"Fusion","Trance","Classical","Instrumental","Acid","House","Game","Sound Clip","Gospel","Noise",
|
||||
"AlternRock","Bass","Soul","Punk","Space","Meditative","Instrumental Pop","Instrumental Rock","Ethnic","Gothic",
|
||||
"Darkwave","Techno-Industrial","Electronic","Pop-Folk","Eurodance","Dream","Southern Rock","Comedy","Cult","Gangsta",
|
||||
"Top 40","Christian Rap","Pop/Funk","Jungle","Native American","Cabaret","New Wave","Psychadelic","Rave","Showtunes",
|
||||
"Trailer","Lo-Fi","Tribal","Acid Punk","Acid Jazz","Polka","Retro","Musical","Rock & Roll","Hard Rock",
|
||||
|
||||
//################## END OF OFFICIAL ID3 TAGS, WINAMP TAGS BELOW ########################################
|
||||
|
||||
"Folk","Folk/Rock","National Folk","Swing","Fast Fusion","Bebob","Latin","Revival","Celtic","Bluegrass",
|
||||
"Avantgarde","Gothic Rock","Progressive Rock","Psychedelic Rock","Symphonic Rock","Slow Rock","Big Band","Chorus","Easy Listening","Acoustic",
|
||||
"Humour","Speech","Chanson","Opera","Chamber Music","Sonata","Symphony","Booty Bass","Primus","Porn Groove",
|
||||
"Satire","Slow Jam","Club","Tango","Samba","Folklore","Ballad","Poweer Ballad","Rhytmic Soul","Freestyle",
|
||||
"Duet","Punk Rock","Drum Solo","A Capela","Euro-House","Dance Hall",
|
||||
|
||||
//################## FOUND AT http://en.wikipedia.org/wiki/ID3 ###########################################
|
||||
|
||||
"Goa","Drum & Bass","Club-House","Hardcore",
|
||||
"Terror","Indie","BritPop","Negerpunk","Polsk Punk","Beat","Christian Gangsta Rap","Heavy Metal","Black Metal","Crossover",
|
||||
"Contemporary Christian","Christian Rock","Merengue","Salsa","Thrash Metal","Anime","JPop","Synthpop"
|
||||
|
||||
};
|
||||
|
||||
static char MODES [][13]={"Stereo","Joint-Stereo","Dual-Channel","Mono"};
|
||||
|
||||
int iPow(int x, int y){return (int)(pow((double)x,(double) y));}
|
||||
|
||||
int str2int(char *text)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
size_t i;
|
||||
for (i = 1; i <= strlen(text); i++)
|
||||
{
|
||||
if ((text[strlen(text) - i] > 57) || (text[strlen(text) - i] < 48))
|
||||
{
|
||||
hexchat_printf(ph, "invalid char in string: %i", (int) text[strlen(text) - i]);
|
||||
return 255;
|
||||
}
|
||||
|
||||
ret += ((int) text[strlen(text) - i] - 48)*iPow(10, i - 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *tagExtract(char *tag, int tagLen, char* info){
|
||||
//if (DEBUG==1) putlog("extracting tag");
|
||||
int pos, len, i;
|
||||
pos=inStr(tag,tagLen,info);
|
||||
//hexchat_printf(ph,"pos=%i",pos);
|
||||
if (pos==-1) return "";//NULL;
|
||||
//printf("position of %s = %i\n",info,pos);
|
||||
len=0;
|
||||
//for (i=pos;i<pos+10;i++)printf("tag[%i]=%i \n",i,tag[i]);
|
||||
for (i=0;i<4;i++) {
|
||||
len+=tag[pos+strlen(info)+i]*iPow(255,3-i);
|
||||
}
|
||||
//printf("Tag-Length: %i\n",len);
|
||||
if (strcmp("COMM",info)!=0) return substring(tag,pos+7+strlen(info),len-1);//11
|
||||
return substring(tag,pos+7+strlen(info),len-1);//11
|
||||
//char *ct=substring(tag,pos+7+strlen(info),len-1);//11
|
||||
//return substring(ct,strlen(ct)+1,len-1-strlen(ct)); //<-- do not understand, what i did here :(
|
||||
|
||||
}
|
||||
|
||||
struct tagInfo readID3V1(char *file){
|
||||
//if (DEBUG==1) putlog("reading ID3V1");
|
||||
FILE *f;
|
||||
struct tagInfo ret;
|
||||
int res, i, c, val;
|
||||
char *tag;
|
||||
char *id;
|
||||
char *tmp;
|
||||
tag = (char*) malloc(sizeof(char)*129);
|
||||
ret.artist=NULL;
|
||||
f=fopen(file,"rb");
|
||||
if (f==NULL){
|
||||
hexchat_print(ph,"file not found while trying to read id3v1");
|
||||
//if (DEBUG==1) putlog("file not found while trying to read id3v1");
|
||||
return ret;
|
||||
}
|
||||
//int offset=getSize(file)-128;
|
||||
res=fseek(f,-128,SEEK_END);
|
||||
if (res!=0) {printf("seek failed\n");fclose(f);return ret;}
|
||||
//long int pos=ftell(f);
|
||||
//printf("position= %li\n",pos);
|
||||
for (i=0;i<128;i++) {
|
||||
c=fgetc(f);
|
||||
if (c==EOF) {hexchat_printf(ph,"read ID3V1 failed\n");fclose(f);return ret;}
|
||||
tag[i]=(char)c;
|
||||
}
|
||||
fclose(f);
|
||||
//printf("tag readed: \n");
|
||||
id=substring(tag,0,3);
|
||||
//printf("header: %s\n",id);
|
||||
if (strcmp(id,"TAG")!=0){hexchat_printf(ph,"no id3 v1 found\n");return ret;}
|
||||
ret.title=subString(tag,3,30,1);
|
||||
ret.artist=subString(tag,33,30,1);
|
||||
ret.album=subString(tag,63,30,1);
|
||||
ret.comment=subString(tag,97,30,1);
|
||||
tmp=substring(tag,127,1);
|
||||
//ret.genre=substring(tag,127,1);
|
||||
|
||||
val=(int)tmp[0];
|
||||
if (val<0)val+=256;
|
||||
//hexchat_printf(ph, "tmp[0]=%i (%i)",val,tmp[0]);
|
||||
if ((val<148)&&(val>=0))
|
||||
ret.genre=GENRES[val];//#############changed
|
||||
else {
|
||||
ret.genre="unknown";
|
||||
//hexchat_printf(ph, "tmp[0]=%i (%i)",val,tmp[0]);
|
||||
}
|
||||
//hexchat_printf(ph, "tmp: \"%s\" -> %i",tmp,tmp[0]);
|
||||
//hexchat_printf(ph,"genre \"%s\"",ret.genre);
|
||||
//if (DEBUG==1) putlog("id3v1 extracted");
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *extractID3Genre(char *tag)
|
||||
{
|
||||
if (tag[strlen(tag) - 1] == ')')
|
||||
{
|
||||
tag[strlen(tag) - 1] = 0;
|
||||
tag = &tag[1];
|
||||
return GENRES[str2int(tag)];
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < strlen(tag); i++)
|
||||
{
|
||||
if (tag[i] == ')')
|
||||
{
|
||||
tag = &tag[i] + 1;
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "[152] failed";
|
||||
}
|
||||
|
||||
struct tagInfo readID3V2(char *file){
|
||||
//if (DEBUG==1) putlog("reading id3v2");
|
||||
FILE *f;
|
||||
int i, c, len;
|
||||
char header[10];
|
||||
char *tag;
|
||||
struct tagInfo ret;
|
||||
|
||||
f = fopen(file,"rb");
|
||||
//hexchat_printf(ph,"file :%s",file);
|
||||
if (f==NULL)
|
||||
{
|
||||
hexchat_print(ph,"file not found whilt trying to read ID3V2");
|
||||
//if (DEBUG==1)putlog("file not found while trying to read ID3V2");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret.artist=NULL;
|
||||
for (i=0;i<10;i++){
|
||||
c=fgetc(f);
|
||||
if (c==EOF){
|
||||
fclose(f);
|
||||
//putlog("found eof while reading id3v2");
|
||||
return ret;
|
||||
}
|
||||
header[i]=(char)c;
|
||||
}
|
||||
if (strstr(header,"ID3")==header){
|
||||
//hexchat_printf(ph,"found id3v2\n");
|
||||
len=0;
|
||||
for (i=6;i<10;i++) len+=(int)header[i]*iPow(256,9-i);
|
||||
|
||||
//char *tag=(char*)malloc(sizeof(char)*len);
|
||||
tag=(char*) calloc(len,sizeof(char)); //malloc(sizeof(char)*len);
|
||||
for (i=0;i<len;i++){c=fgetc(f);tag[i]=(char)c;}
|
||||
//hexchat_printf(ph,"tag length: %i\n",len);
|
||||
//hexchat_printf(ph,"tag: %s\n",tag);
|
||||
fclose(f);
|
||||
ret.comment=tagExtract(tag,len,"COMM");
|
||||
//hexchat_printf(ph,"Comment: %s\n",ret.comment);
|
||||
ret.genre=tagExtract(tag,len,"TCON");
|
||||
//if (strcmp(ret.genre,"(127)")==0) ret.genre="unknown";
|
||||
//hexchat_printf(ph, "ret.genre = %s",ret.genre);
|
||||
if ((ret.genre!=NULL)&&(ret.genre[0]=='(')) ret.genre=extractID3Genre(ret.genre);
|
||||
//hexchat_printf(ph,"genre: %s\n",ret.genre);
|
||||
ret.title=tagExtract(tag,len,"TIT2");
|
||||
//hexchat_printf(ph,"Title: %s\n",ret.title);
|
||||
ret.album=tagExtract(tag,len,"TALB");
|
||||
//hexchat_printf(ph,"Album: %s\n",ret.album);
|
||||
ret.artist=tagExtract(tag,len,"TPE1");
|
||||
//hexchat_printf(ph,"Artist: %s\n",ret.artist);
|
||||
}
|
||||
else{fclose(f);printf("no id3v2 tag found\n"); return ret;}
|
||||
//printf("id2v2 done\n");
|
||||
//if (DEBUG==1) putlog("id3v2 readed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct tagInfo readHeader(char *file){
|
||||
//if (DEBUG==1) putlog("reading header");
|
||||
FILE *f;
|
||||
//int buffer[5120];
|
||||
int versionB, layerB, bitrateB, freqB, modeB;
|
||||
int header[4];
|
||||
int count=0;
|
||||
int cc=0;
|
||||
struct tagInfo info;
|
||||
info.artist=NULL;
|
||||
|
||||
f = fopen(file,"rb");
|
||||
if (f==NULL)
|
||||
{
|
||||
hexchat_print(ph,"file not found while trying to read mp3 header");
|
||||
//if (DEBUG==1) putlog("file not found while trying to read mp3 header");
|
||||
return info;
|
||||
}
|
||||
//struct tagInfo tagv2
|
||||
|
||||
info=readID3V2(file);
|
||||
//struct tagInfo tagv1;//=readID3V1(file);
|
||||
//if (tagv2.artist!=NULL){info=tagv2;}
|
||||
//else {
|
||||
if (info.artist==NULL){
|
||||
//printf("searching for id3v1\n");
|
||||
//tagv1=readID3V1(file);
|
||||
info=readID3V1(file); //#####################
|
||||
}
|
||||
/*
|
||||
if (tagv1.artist!=NULL){
|
||||
//printf("Artist: %s\nTitle: %s\nAlbum: %s\nComment: %s\nGenre: %s\n",tagv1.artist,tagv1.title,tagv1.album,tagv1.comment,tagv1.genre);
|
||||
info=tagv1;
|
||||
}
|
||||
*/
|
||||
while ((count<5120)&&(cc!=EOF)&&(cc!=255)) {cc=fgetc(f);count++;}
|
||||
if ((cc==EOF)||(count==5119)) printf("no header found\n");
|
||||
else {
|
||||
//printf("located header at %i\n",count);
|
||||
header[0]=255;
|
||||
for (count=1;count<4;count++){
|
||||
header[count]=fgetc(f);
|
||||
//printf("header[%i]=%i\n",count,header[count]);
|
||||
}
|
||||
versionB=(header[1]&8)>>3;
|
||||
layerB=(header[1]&6)>>1;
|
||||
bitrateB=(header[2]&240)>>4; //4
|
||||
freqB=(header[2]&12)>>2;//2
|
||||
modeB=(header[3]&192)>>6;//6
|
||||
//printf("Mpeg: %i\nLayer: %i\nBitrate: %i\nFreq: %i\nMode: %i\n",versionB, layerB, bitrateB, freqB, modeB);
|
||||
//int Bitrate=RATES[versionB][layerB-1][bitrateB];
|
||||
//int Freq=FREQS[versionB][freqB];
|
||||
info.bitrate=RATES[versionB][layerB-1][bitrateB];
|
||||
info.freq=FREQS[versionB][freqB];
|
||||
info.mode=modeB;
|
||||
}
|
||||
fclose(f);
|
||||
//if (DEBUG==1) putlog("header readed");
|
||||
return info;
|
||||
}
|
||||
/*
|
||||
static void printMp3Info(char *file){
|
||||
//printf("\nScanning Mp3-File for Informations: %s\n",file);
|
||||
//printf("size:\t%10d byte\n",getSize(file));
|
||||
struct tagInfo info =readHeader(file);
|
||||
printf("%s | %10d",file,getSize(file));
|
||||
if (info.bitrate>0){
|
||||
//printf("Bitrate: %i\nFreq: %i\nMode: %s\n",info.bitrate,info.freq,MODES[info.mode]);
|
||||
printf(" | %i kbps | %i kHz | %s",info.bitrate,info.freq,MODES[info.mode]);
|
||||
//if (info.artist!=NULL) printf("\nArtist: %s\nTitle: %s\nAlbum: %s\nComment: %s\nGenre: %s\n",info.artist,info.title,info.album,info.comment,info.genre);
|
||||
if (info.artist!=NULL) {
|
||||
printf("| %s | %s | %s | %s | %s",info.artist,info.title,info.album,info.comment,info.genre);
|
||||
//printf("| %s ",info.title);//,info.title,info.album,info.comment,info.genre
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
*/
|
160
plugins/mpcinfo/mpcInfo.c
Normal file
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
//static int DEBUG=0;
|
||||
static char *VERSION="0.0.6";
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include "hexchat-plugin.h"
|
||||
static hexchat_plugin *ph;
|
||||
|
||||
#include "functions.c"
|
||||
#include "mp3Info.c"
|
||||
#include "oggInfo.c"
|
||||
#include "theme.c"
|
||||
|
||||
static int print_themes (char *word[], char *word_eol[], void *userdata){
|
||||
printThemes();
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
static int mpc_themeReload(char *word[], char *word_eol[], void *userdata){
|
||||
themeInit();
|
||||
loadThemes();
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
static int mpc_tell(char *word[], char *word_eol[], void *userdata){
|
||||
char *tTitle, *zero, *oggLine, *line;
|
||||
struct tagInfo info;
|
||||
HWND hwnd = FindWindow("MediaPlayerClassicW",NULL);
|
||||
if (hwnd==0) {hexchat_print(ph, randomLine(notRunTheme));return HEXCHAT_EAT_ALL;}
|
||||
|
||||
tTitle = g_new(char, 1024);
|
||||
GetWindowText(hwnd, tTitle, 1024);
|
||||
zero = strstr (tTitle, " - Media Player Classic");
|
||||
if (zero != NULL)
|
||||
{
|
||||
zero[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_free(tTitle);
|
||||
hexchat_print(ph, "pattern not found");
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
if ((tTitle[1]==':')&&(tTitle[2]=='\\')){
|
||||
//hexchat_print(ph,"seams to be full path");
|
||||
if (endsWith(tTitle,".mp3")==1){
|
||||
//hexchat_print(ph,"seams to be a mp3 file");
|
||||
info = readHeader(tTitle);
|
||||
|
||||
if ((info.artist!=NULL)&&(strcmp(info.artist,"")!=0)){
|
||||
char *mode=MODES[info.mode];
|
||||
//hexchat_printf(ph,"mode: %s\n",mode);
|
||||
char *mp3Line=randomLine(mp3Theme);
|
||||
mp3Line=replace(mp3Line,"%art",info.artist);
|
||||
mp3Line=replace(mp3Line,"%tit",info.title);
|
||||
mp3Line=replace(mp3Line,"%alb",info.album);
|
||||
mp3Line=replace(mp3Line,"%com",info.comment);
|
||||
mp3Line=replace(mp3Line,"%gen",info.genre);
|
||||
//mp3Line=replace(mp3Line,"%time",pos);
|
||||
//mp3Line=replace(mp3Line,"%length",len);
|
||||
//mp3Line=replace(mp3Line,"%ver",waVers);
|
||||
//mp3Line=intReplace(mp3Line,"%br",br);
|
||||
//mp3Line=intReplace(mp3Line,"%frq",frq);
|
||||
|
||||
mp3Line=intReplace(mp3Line,"%br",info.bitrate);
|
||||
mp3Line=intReplace(mp3Line,"%frq",info.freq);
|
||||
mp3Line=replace(mp3Line,"%mode",mode);
|
||||
//mp3Line=replace(mp3Line,"%size",size);
|
||||
//mp3Line=intReplace(mp3Line,"%perc",perc);
|
||||
//mp3Line=replace(mp3Line,"%plTitle",title);
|
||||
mp3Line=replace(mp3Line,"%file",tTitle);
|
||||
g_free(tTitle);
|
||||
hexchat_command(ph, mp3Line);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
}
|
||||
if (endsWith(tTitle,".ogg")==1){
|
||||
hexchat_printf(ph,"Ogg detected\n");
|
||||
info = getOggHeader(tTitle);
|
||||
if (info.artist!=NULL){
|
||||
char *cbr;
|
||||
if (info.cbr==1) cbr="CBR"; else cbr="VBR";
|
||||
oggLine=randomLine(oggTheme);
|
||||
//if (cue==1) oggLine=cueLine;
|
||||
//hexchat_printf(ph,"ogg-line: %s\n",oggLine);
|
||||
oggLine=replace(oggLine,"%art",info.artist);
|
||||
oggLine=replace(oggLine,"%tit",info.title);
|
||||
oggLine=replace(oggLine,"%alb",info.album);
|
||||
oggLine=replace(oggLine,"%com",info.comment);
|
||||
oggLine=replace(oggLine,"%gen",info.genre);
|
||||
//oggLine=replace(oggLine,"%time",pos);
|
||||
//oggLine=replace(oggLine,"%length",len);
|
||||
//oggLine=replace(oggLine,"%ver",waVers);
|
||||
oggLine=intReplace(oggLine,"%chan",info.mode);
|
||||
oggLine=replace(oggLine,"%cbr",cbr);
|
||||
oggLine=intReplace(oggLine,"%br",info.bitrate/1000);//br);
|
||||
oggLine=intReplace(oggLine,"%frq",info.freq);
|
||||
//oggLine=replace(oggLine,"%size",size);
|
||||
//oggLine=intReplace(oggLine,"%perc",perc);
|
||||
//oggLine=replace(oggLine,"%plTitle",title);
|
||||
oggLine=replace(oggLine,"%file",tTitle);
|
||||
g_free(tTitle);
|
||||
hexchat_command(ph, oggLine);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
}
|
||||
}
|
||||
line=randomLine(titleTheme);
|
||||
line=replace(line,"%title", tTitle);
|
||||
g_free(tTitle);
|
||||
hexchat_command(ph, line);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
int hexchat_plugin_init(hexchat_plugin *plugin_handle, char **plugin_name, char **plugin_desc, char **plugin_version, char *arg){
|
||||
ph = plugin_handle;
|
||||
*plugin_name = "mpcInfo";
|
||||
*plugin_desc = "Information-Script for Media Player Classic";
|
||||
*plugin_version=VERSION;
|
||||
|
||||
hexchat_hook_command(ph, "mpc", HEXCHAT_PRI_NORM, mpc_tell,"no help text", 0);
|
||||
hexchat_hook_command(ph, "mpc_themes", HEXCHAT_PRI_NORM, print_themes,"no help text", 0);
|
||||
hexchat_hook_command(ph, "mpc_reloadthemes", HEXCHAT_PRI_NORM, mpc_themeReload,"no help text", 0);
|
||||
hexchat_command (ph, "MENU -ishare\\music.png ADD \"Window/Display Current Song (MPC)\" \"MPC\"");
|
||||
|
||||
themeInit();
|
||||
loadThemes();
|
||||
hexchat_printf(ph, "%s plugin loaded\n", *plugin_name);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
hexchat_plugin_deinit (void)
|
||||
{
|
||||
hexchat_command (ph, "MENU DEL \"Window/Display Current Song (MPC)\"");
|
||||
hexchat_print (ph, "mpcInfo plugin unloaded\n");
|
||||
return 1;
|
||||
}
|
3
plugins/mpcinfo/mpcinfo.def
Normal file
@ -0,0 +1,3 @@
|
||||
EXPORTS
|
||||
hexchat_plugin_init
|
||||
hexchat_plugin_deinit
|
@ -1,54 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Configuration">
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</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>{4C0F3940-2EEE-4646-82F7-6CE75B9A72F4}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>lua</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\win32\hexchat.props" />
|
||||
<PropertyGroup>
|
||||
<TargetName>$(LuaOutput)</TargetName>
|
||||
<OutDir>$(HexChatRel)plugins\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(Glib);$(LuaInclude);..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>"$(LuaLib).lib";$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(Glib);$(LuaInclude);..\..\src\common;$(HexChatLib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>"$(LuaLib).lib";$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="lua.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Configuration">
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{B0E36D93-CA2A-49FE-9EB9-9C96C6016EEC}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>mpcinfo</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\win32\hexchat.props" />
|
||||
<PropertyGroup>
|
||||
<TargetName>hcmpcinfo</TargetName>
|
||||
<OutDir>$(HexChatRel)plugins\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MPCINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\src\common;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>mpcinfo.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;MPCINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\..\src\common;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(DepsRoot)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>$(DepLibs);%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ModuleDefinitionFile>mpcinfo.def</ModuleDefinitionFile>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<None Include="mpcinfo.def" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="mpcInfo.c" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
</Project>
|
23
plugins/mpcinfo/mpcinfo.vcxproj.filters
Normal file
@ -0,0 +1,23 @@
|
||||
<?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="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="mpcinfo.def">
|
||||
<Filter>Resource Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="mpcInfo.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
126
plugins/mpcinfo/oggInfo.c
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
static int getOggInt(char *buff, int beg, int bytes){
|
||||
//if (DEBUG==1) putlog("getOggInt");
|
||||
int ret=0;
|
||||
int i;
|
||||
for (i=0;i<bytes;i++){
|
||||
if (buff[i+beg]>=0) ret+=buff[i+beg]*iPow(256,i);else ret+=(256+buff[i+beg])*iPow(256,i);
|
||||
//printf("[%i]=%i\n",i,buff[i+beg]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static char *upperStr(char *text)
|
||||
{
|
||||
char *ret = (char*) malloc(sizeof(char)*(strlen(text) + 1));
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < strlen(text); i++)
|
||||
{
|
||||
ret[i] = toupper(text[i]);
|
||||
}
|
||||
|
||||
ret[strlen(text)] = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct tagInfo getOggHeader(char *file){
|
||||
//if (DEBUG==1) putlog("reading ogg header");
|
||||
char header[4096];
|
||||
int i, c;
|
||||
int h1pos, h3pos, maxBr, nomBr, minBr, pos, count, tagLen;
|
||||
char *sub;
|
||||
char *name;
|
||||
char *val;
|
||||
char *HEADLOC1, *HEADLOC3, *HEADLOC5;
|
||||
FILE *f;
|
||||
struct tagInfo info;
|
||||
|
||||
info.artist=NULL;
|
||||
f = fopen(file,"rb");
|
||||
if (f==NULL){
|
||||
hexchat_print(ph,"file not found while trying to read ogg header");
|
||||
//if (DEBUG==1) putlog("file not found while trying to read ogg header");
|
||||
return info;
|
||||
}
|
||||
|
||||
for (i=0;i<4095;i++) {c=fgetc(f);header[i]=(char)c;}
|
||||
fclose(f);
|
||||
HEADLOC1="_vorbis";
|
||||
HEADLOC1[0]=1;
|
||||
HEADLOC3="_vorbis";
|
||||
HEADLOC3[0]=3;
|
||||
HEADLOC5="_vorbis";
|
||||
HEADLOC5[0]=5;
|
||||
h1pos=inStr(header,4096,HEADLOC1);
|
||||
h3pos=inStr(header,4096,HEADLOC3);
|
||||
//int h5pos=inStr(header,4096,HEADLOC5); //not needed
|
||||
|
||||
//printf("loc1: %i\n",h1pos);printf("loc3: %i\n",h3pos);printf("loc5: %i\n",h5pos);
|
||||
maxBr=getOggInt(header,h1pos+7+9,4);
|
||||
nomBr=getOggInt(header,h1pos+7+13,4);
|
||||
minBr=getOggInt(header,h1pos+7+17,4);
|
||||
info.freq=getOggInt(header,h1pos+7+5,4);
|
||||
info.mode=header[h1pos+7+4];
|
||||
info.bitrate=nomBr;
|
||||
if (((maxBr==nomBr)&&(nomBr=minBr))||((minBr==0)&&(maxBr==0))||((minBr=-1)&&(maxBr=-1)) )info.cbr=1;else info.cbr=0;
|
||||
printf("bitrates: %i|%i|%i\n",maxBr,nomBr,minBr);
|
||||
printf("freq: %u\n",info.freq);
|
||||
pos=h3pos+7;
|
||||
pos+=getOggInt(header,pos,4)+4;
|
||||
count=getOggInt(header,pos,4);
|
||||
//printf("tags: %i\n",count);
|
||||
pos+=4;
|
||||
|
||||
info.artist=NULL;info.title=NULL;info.album=NULL;info.comment=NULL;info.genre=NULL;
|
||||
for (i=0;i<count;i++){
|
||||
tagLen=getOggInt(header,pos,4);
|
||||
//printf("taglength: %i\n",tagLen);
|
||||
sub=substring(header,pos+4,tagLen);
|
||||
name=upperStr(substring(sub,0,inStr(sub,tagLen,"=")));
|
||||
val=substring(sub,inStr(sub,tagLen,"=")+1,tagLen-inStr(sub,tagLen,"=")-1);
|
||||
//printf("Tag: %s\n",sub);
|
||||
//printf("Name: %s\n",name);
|
||||
//printf("value: %s\n",val);
|
||||
if (strcmp(name,"ARTIST")==0) info.artist=val;
|
||||
if (strcmp(name,"TITLE")==0) info.title=val;
|
||||
if (strcmp(name,"ALBUM")==0) info.album=val;
|
||||
if (strcmp(name,"GENRE")==0) info.genre=val;
|
||||
if (strcmp(name,"COMMENT")==0) info.comment=val;
|
||||
pos+=4+tagLen;
|
||||
}
|
||||
if (info.artist==NULL) info.artist="";
|
||||
if (info.album==NULL) info.album ="";
|
||||
if (info.title==NULL) info.title="";
|
||||
if (info.genre==NULL) info.genre="";
|
||||
if (info.comment==NULL) info.comment="";
|
||||
|
||||
printf("Artist: %s\nTitle: %s\nAlbum: %s\n",info.artist,info.title, info.album);
|
||||
printf("Genre: %s\nComment: %s\nMode: %i\nCBR: %i\n",info.genre,info.comment,info.mode,info.cbr);
|
||||
//if (DEBUG==1) putlog("ogg header readed");
|
||||
return info;
|
||||
}
|
||||
|
||||
/*
|
||||
void printOggInfo(char *file){
|
||||
printf("Scanning Ogg-File for Informations: %s\n",file);
|
||||
printf("size:\t%10d byte\n",getSize(file));
|
||||
struct tagInfo info = getOggHeader(file);
|
||||
}
|
||||
*/
|
144
plugins/mpcinfo/theme.c
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
|
||||
struct theme{
|
||||
int size;
|
||||
char **line;
|
||||
};
|
||||
|
||||
static struct theme notRunTheme;
|
||||
static struct theme titleTheme;
|
||||
static struct theme mp3Theme;
|
||||
static struct theme oggTheme;
|
||||
|
||||
|
||||
void themeInit(){
|
||||
//if (DEBUG==1) putlog("init theme");
|
||||
/*mp3Theme.size=0;oggTheme.size=0;cueTheme.size=0;streamTheme.size=0;etcTheme.size=0;
|
||||
stopTheme.size=0;pauseTheme.size=0;*/
|
||||
|
||||
notRunTheme.size=0;titleTheme.size=0;
|
||||
srand((unsigned int)time((time_t *)NULL));
|
||||
//if (DEBUG==1) putlog("theme init done");
|
||||
}
|
||||
|
||||
void printTheme(struct theme data){
|
||||
int i;
|
||||
for (i=0;i<data.size;i++) hexchat_printf(ph,"line[%i]=%s\n",i,data.line[i]);
|
||||
}
|
||||
|
||||
void printThemes(){
|
||||
hexchat_printf(ph,"\nNotRun-Theme:\n");printTheme(notRunTheme);
|
||||
hexchat_printf(ph,"\nMP3-Theme:\n");printTheme(mp3Theme);
|
||||
hexchat_printf(ph,"\nOGG-Theme:\n");printTheme(oggTheme);
|
||||
hexchat_printf(ph,"\nTitle-Theme:\n");printTheme(titleTheme);
|
||||
}
|
||||
|
||||
void cbFix(char *line)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < strlen(line); i++)
|
||||
{
|
||||
size_t j;
|
||||
|
||||
if (line[i] == '%')
|
||||
{
|
||||
if ((line[i + 1] == 'C') || (line[i + 1] == 'B') || (line[i + 1] == 'U') || (line[i + 1] == 'O') || (line[i + 1] == 'R'))
|
||||
{
|
||||
if (line[i + 1] == 'C') line[i] = 3;
|
||||
if (line[i + 1] == 'B') line[i] = 2;
|
||||
if (line[i + 1] == 'U') line[i] = 37;
|
||||
if (line[i + 1] == 'O') line[i] = 17;
|
||||
if (line[i + 1] == 'R') line[i] = 26;
|
||||
|
||||
for (j = i + 1; j < strlen(line) - 1; j++)
|
||||
{
|
||||
line[j] = line[j + 1];
|
||||
}
|
||||
|
||||
line[strlen(line) - 1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct theme themeAdd(struct theme data, char *info){
|
||||
//if (DEBUG==1) putlog("adding theme");
|
||||
struct theme ret;
|
||||
char **newLine=(char **)calloc(data.size+1,sizeof(char*));
|
||||
int i;
|
||||
for (i=0;i<data.size;i++) newLine[i]=data.line[i];
|
||||
cbFix(info);
|
||||
newLine[data.size]=info;
|
||||
ret.line=newLine;ret.size=data.size+1;
|
||||
//if (DEBUG==1) putlog("theme added");
|
||||
return ret;
|
||||
}
|
||||
|
||||
void loadThemes(){
|
||||
char *hDir, *hFile, *line, *val;
|
||||
FILE *f;
|
||||
hexchat_print(ph,"loading themes\n");
|
||||
hDir=(char*)calloc(1024,sizeof(char));
|
||||
strcpy(hDir,hexchat_get_info(ph,"configdir"));
|
||||
hFile=str3cat(hDir,"\\","mpcInfo.theme.txt");
|
||||
f = fopen(hFile,"r");
|
||||
if(f==NULL)
|
||||
{
|
||||
hexchat_print(ph,"no theme in homedir, checking global theme");
|
||||
f=fopen("mpcInfo.theme.txt","r");
|
||||
}
|
||||
//hexchat_printf(ph,"file_desc: %p\n",f);
|
||||
if (f==NULL) hexchat_print(ph, "no theme found, using hardcoded\n");
|
||||
else {
|
||||
if (f > 0)
|
||||
{
|
||||
line=" ";
|
||||
} else
|
||||
{
|
||||
line="\0";
|
||||
}
|
||||
|
||||
while (line[0]!=0)
|
||||
{
|
||||
line=readLine(f);
|
||||
val=split(line,'=');
|
||||
printf("line: %s\n",line);
|
||||
printf("val: %s\n",val);
|
||||
if (strcmp(toUpper(line),"OFF_LINE")==0) notRunTheme=themeAdd(notRunTheme,val);
|
||||
if (strcmp(toUpper(line),"TITLE_LINE")==0) titleTheme=themeAdd(titleTheme,val);
|
||||
if (strcmp(toUpper(line),"MP3_LINE")==0) mp3Theme=themeAdd(mp3Theme,val);
|
||||
if (strcmp(toUpper(line),"OGG_LINE")==0) mp3Theme=themeAdd(oggTheme,val);
|
||||
}
|
||||
fclose(f);
|
||||
hexchat_print(ph, "theme loaded successfull\n");
|
||||
}
|
||||
if (notRunTheme.size==0) notRunTheme=themeAdd(notRunTheme,"Media Player Classic not running");
|
||||
if (titleTheme.size==0) titleTheme=themeAdd(titleTheme,"say Playing %title in Media Player Classic");
|
||||
if (mp3Theme.size==0) mp3Theme=themeAdd(mp3Theme,"me listens to %art with %tit from %alb [%gen|%br kbps|%frq kHz|%mode] in Media Player Classic ");
|
||||
if (oggTheme.size==0) oggTheme=themeAdd(oggTheme,"me listens to %art with %tit from %alb [%gen|%br kbps|%frq kHz|%chan channels] in Media Player Classic ");
|
||||
//mp3Theme=themeAdd(mp3Theme,"me listens to %art with %tit from %alb [%time|%length|%perc%|%br kbps|%frq kHz|%mode] in Media Player Classic ");
|
||||
}
|
||||
|
||||
int rnd(int max){
|
||||
return rand()%max;
|
||||
}
|
||||
|
||||
char *randomLine(struct theme data){
|
||||
return data.line[rnd(data.size)];
|
||||
}
|
19
plugins/perl/Makefile.am
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
EXTRA_DIST=generate_header lib/HexChat.pm lib/Xchat.pm lib/HexChat/Embed.pm lib/HexChat/List/Network.pm \
|
||||
lib/HexChat/List/Network/Entry.pm lib/HexChat/List/Network/AutoJoin.pm lib/IRC.pm
|
||||
|
||||
libdir = $(hexchatlibdir)
|
||||
|
||||
lib_LTLIBRARIES = perl.la
|
||||
perl_la_SOURCES = perl.c
|
||||
perl_la_LDFLAGS = $(PERL_LDFLAGS) $(PLUGIN_LDFLAGS) -module
|
||||
perl_la_LIBADD = $(PERL_LIBS) $(GLIB_LIBS)
|
||||
perl_la_CFLAGS = $(PERL_CFLAGS) $(GLIB_CFLAGS) -I$(top_srcdir)/src/common
|
||||
|
||||
BUILT_SOURCES = hexchat.pm.h irc.pm.h
|
||||
CLEANFILES = $(BUILT_SOURCES)
|
||||
|
||||
hexchat.pm.h irc.pm.h: lib/HexChat.pm lib/Xchat.pm lib/HexChat/Embed.pm \
|
||||
lib/HexChat/List/Network.pm lib/HexChat/List/Network/Entry.pm \
|
||||
lib/HexChat/List/Network/AutoJoin.pm lib/IRC.pm
|
||||
cd $(srcdir); perl generate_header
|
@ -1,29 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
from os.path import basename
|
||||
|
||||
out_file = sys.argv[1]
|
||||
in_files = sys.argv[2:]
|
||||
|
||||
|
||||
def escape_perl(file):
|
||||
ret = ''
|
||||
for line in file:
|
||||
# Escape " and \, strip empty space, shove in C strings.
|
||||
ret += '"' + line.strip().replace('\\', '\\\\').replace('"', '\\"') + '\\n"\n'
|
||||
return ret
|
||||
|
||||
|
||||
with open(out_file, 'w') as o:
|
||||
o.write('"BEGIN {\\n"\n')
|
||||
for in_file in in_files:
|
||||
o.write("\"$INC{{'{}'}} = 'Compiled into the plugin.';\\n\"\n".format(basename(in_file)))
|
||||
o.write('"}\\n"\n')
|
||||
|
||||
for in_file in in_files:
|
||||
o.write('"{\\n"\n')
|
||||
o.write('"#line 1 \\"{}\\"\\n"\n'.format(basename(in_file)))
|
||||
with open(in_file) as i:
|
||||
o.write(escape_perl(i))
|
||||
o.write('"}\\n"\n')
|
@ -51,7 +51,7 @@ sub get_context;
|
||||
sub HexChat::Internal::context_info;
|
||||
sub HexChat::Internal::print;
|
||||
|
||||
#keep compatibility with Xchat scripts
|
||||
#keep compability with Xchat scripts
|
||||
sub EAT_XCHAT ();
|
||||
BEGIN {
|
||||
*Xchat:: = *HexChat::;
|
||||
|
@ -1,92 +0,0 @@
|
||||
generate_perl_header = find_program('generate_header.py')
|
||||
|
||||
hexchat_perl_module = custom_target('hexchat-perl-header',
|
||||
input: [
|
||||
'lib/HexChat.pm',
|
||||
'lib/Xchat.pm',
|
||||
'lib/HexChat/Embed.pm',
|
||||
'lib/HexChat/List/Network.pm',
|
||||
'lib/HexChat/List/Network/Entry.pm',
|
||||
'lib/HexChat/List/Network/AutoJoin.pm',
|
||||
],
|
||||
output: 'hexchat.pm.h',
|
||||
command: [generate_perl_header, '@OUTPUT@', '@INPUT@']
|
||||
)
|
||||
|
||||
perl_cflags = []
|
||||
irc_perl_module = []
|
||||
|
||||
if get_option('with-perl-legacy-api')
|
||||
irc_perl_module = custom_target('irc-perl-header',
|
||||
input: 'lib/IRC.pm',
|
||||
output: 'irc.pm.h',
|
||||
command: [generate_perl_header, '@OUTPUT@', '@INPUT@']
|
||||
)
|
||||
perl_cflags += '-DOLD_PERL'
|
||||
endif
|
||||
|
||||
perl = find_program(get_option('with-perl'))
|
||||
|
||||
ret = run_command([perl, '-MExtUtils::Embed', '-e', 'ccopts'])
|
||||
if ret.returncode() != 0
|
||||
error('perl: Failed to get cflags')
|
||||
endif
|
||||
foreach flag : ret.stdout().strip().split(' ')
|
||||
if flag.startswith('-I') or flag.startswith('-D')
|
||||
perl_cflags += flag
|
||||
endif
|
||||
endforeach
|
||||
|
||||
ret = run_command([perl, '-MExtUtils::Embed', '-e', 'ldopts'])
|
||||
if ret.returncode() != 0
|
||||
error('perl: Failed to get ldflags')
|
||||
endif
|
||||
perl_ldflags = []
|
||||
perl_rpath = ''
|
||||
foreach flag : ret.stdout().strip().split(' ')
|
||||
if flag.startswith('-L') or flag.startswith('-l')
|
||||
perl_ldflags += flag
|
||||
endif
|
||||
if flag.startswith('-Wl,-rpath,')
|
||||
# Install rpath
|
||||
split = flag.split(',')
|
||||
perl_rpath = split[split.length() - 1]
|
||||
|
||||
# For in tree
|
||||
perl_ldflags += flag
|
||||
endif
|
||||
endforeach
|
||||
|
||||
perl_cflags += [
|
||||
# Perl has its own 'config.h' that we must override
|
||||
# TODO: Just rename ours to something more unique.
|
||||
'-include', meson.build_root() + '/config.h'
|
||||
]
|
||||
|
||||
if not cc.links('''
|
||||
#define PERL_NO_INLINE_FUNCTIONS
|
||||
#include <EXTERN.h>
|
||||
#include <perl.h>
|
||||
|
||||
int main(void) {
|
||||
PerlInterpreter *my_perl = perl_alloc();
|
||||
return 0;
|
||||
}
|
||||
''', args: perl_cflags + perl_ldflags)
|
||||
error('found perl not suitable for plugin')
|
||||
endif
|
||||
|
||||
perl_dep = declare_dependency(
|
||||
compile_args: perl_cflags,
|
||||
link_args: perl_ldflags
|
||||
)
|
||||
|
||||
shared_module('perl',
|
||||
sources: ['perl.c', hexchat_perl_module, irc_perl_module],
|
||||
dependencies: [libgio_dep, hexchat_plugin_dep, perl_dep],
|
||||
install: true,
|
||||
install_dir: plugindir,
|
||||
install_rpath: perl_rpath,
|
||||
name_prefix: '',
|
||||
vs_module_defs: 'perl.def',
|
||||
)
|
@ -29,7 +29,6 @@
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
@ -208,6 +207,8 @@ get_filename (char *word[], char *word_eol[])
|
||||
int len;
|
||||
char *file;
|
||||
|
||||
len = strlen (word[2]);
|
||||
|
||||
/* if called as /load "filename.pl" the only difference between word and
|
||||
* word_eol will be the two quotes
|
||||
*/
|
||||
@ -283,8 +284,6 @@ list_item_to_sv ( hexchat_list *list, const char *const *fields )
|
||||
return sv_2mortal (newRV_noinc ((SV *) hash));
|
||||
}
|
||||
|
||||
#define WORD_ARRAY_LEN 32
|
||||
|
||||
static AV *
|
||||
array2av (char *array[])
|
||||
{
|
||||
@ -295,7 +294,7 @@ array2av (char *array[])
|
||||
|
||||
for (
|
||||
count = 1;
|
||||
count < WORD_ARRAY_LEN && array[count] != NULL && array[count][0] != 0;
|
||||
count < 32 && array[count] != NULL && array[count][0] != 0;
|
||||
count++
|
||||
) {
|
||||
temp = newSVpv (array[count], 0);
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Label="Configuration">
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
@ -29,7 +29,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PERL520_EXPORTS;HAS_BOOL;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PERL520_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(IntDir);..\..\src\common;$(HexChatLib);$(PerlPath)\lib\CORE;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@ -49,7 +49,7 @@ move hexchat.pm.h "$(IntDir)"</Command>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;PERL520_EXPORTS;HAS_BOOL;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;PERL520_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(IntDir);..\..\src\common;$(HexChatLib);$(PerlPath)\lib\CORE;$(Glib);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
|
19
plugins/plugin-conf.in
Normal file
@ -0,0 +1,19 @@
|
||||
AC_INIT(@PLUGIN@-config.h.in)
|
||||
AM_CONFIG_HEADER(@PLUGIN@-config.h)
|
||||
AM_INIT_AUTOMAKE(hexchat-@PLUGIN@, @PLUGIN_VERSION@)
|
||||
AM_MAINTAINER_MODE
|
||||
AM_DISABLE_STATIC
|
||||
AM_PROG_LIBTOOL
|
||||
|
||||
AC_ARG_WITH(plugin-includes,
|
||||
[ --with-plugin-includes directory containing hexchat-plugin.h],
|
||||
PLUGIN_INCLUDES=$enableval)
|
||||
|
||||
AC_SUBST(PLUGIN_INCLUDES)
|
||||
|
||||
hexchatlibdir=${libdir}/hexchat
|
||||
AC_SUBST(hexchatlibdir)
|
||||
|
||||
AC_OUTPUT(
|
||||
Makefile
|
||||
)
|
8
plugins/python/Makefile.am
Normal file
@ -0,0 +1,8 @@
|
||||
libdir = $(hexchatlibdir)
|
||||
|
||||
lib_LTLIBRARIES = python.la
|
||||
python_la_SOURCES = python.c
|
||||
python_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
|
||||
python_la_LIBADD = $(PY_LIBS) $(GLIB_LIBS)
|
||||
python_la_CFLAGS = $(PY_CFLAGS) $(GLIB_CFLAGS) -I$(top_srcdir)/src/common
|
||||
|