Compare commits
7 Commits
v2.12.3
...
wip/file-h
Author | SHA1 | Date | |
---|---|---|---|
![]() |
eafc1e2b70 | ||
![]() |
06d323025d | ||
![]() |
c0c2668c10 | ||
![]() |
7cf631f93c | ||
![]() |
f5142c6724 | ||
![]() |
3ba5581c6b | ||
![]() |
d825b3514b |
19
.gitignore
vendored
19
.gitignore
vendored
@@ -7,19 +7,31 @@ Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
/build-aux/
|
||||
compile
|
||||
ar-lib
|
||||
confdefs.h
|
||||
conftest
|
||||
conftest.c
|
||||
conftest.err
|
||||
config.*
|
||||
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
|
||||
@@ -32,7 +44,6 @@ data/man/hexchat.1
|
||||
data/pkgconfig/hexchat-plugin.pc
|
||||
data/misc/hexchat.appdata.xml
|
||||
data/misc/hexchat.desktop
|
||||
data/misc/hexchat.desktop.in
|
||||
data/misc/htm.desktop
|
||||
src/common/dbus/example
|
||||
src/common/dbus/org.hexchat.service.service
|
||||
@@ -85,5 +96,3 @@ osx/.HexChat.app
|
||||
po/.intltool-merge-cache
|
||||
*.zip
|
||||
*.dmg
|
||||
*.VC.db
|
||||
*.VC.opendb
|
||||
|
10
.mailmap
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
|
@@ -1,5 +1,4 @@
|
||||
sudo: required
|
||||
dist: trusty
|
||||
sudo: false
|
||||
language: c
|
||||
cache: apt
|
||||
compiler: clang
|
||||
@@ -17,14 +16,13 @@ addons:
|
||||
apt:
|
||||
packages:
|
||||
- automake
|
||||
- autoconf-archive
|
||||
- autoconf
|
||||
- imagemagick
|
||||
- intltool
|
||||
- libcanberra-dev
|
||||
- libdbus-glib-1-dev
|
||||
- libglib2.0-dev
|
||||
- libgtk2.0-dev
|
||||
- libluajit-5.1-dev
|
||||
- libnotify-dev
|
||||
- libpci-dev
|
||||
- libperl-dev
|
||||
|
13
autogen.sh
13
autogen.sh
@@ -9,15 +9,10 @@ test -z "$srcdir" && srcdir=.
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ "$1" = "--copy" ]; then
|
||||
shift
|
||||
aclocal --force --install || exit 1
|
||||
intltoolize --force --copy --automake || exit 1
|
||||
autoreconf --force --install --include=m4 -Wno-portability || exit 1
|
||||
else
|
||||
intltoolize --automake || exit 1
|
||||
autoreconf --install --symlink --include=m4 -Wno-portability || exit 1
|
||||
fi
|
||||
aclocal --install -I m4 || exit 1
|
||||
glib-gettextize --force --copy || exit 1
|
||||
intltoolize --force --copy --automake || exit 1
|
||||
autoreconf --force --install -Wno-portability || exit 1
|
||||
|
||||
if [ "$NOCONFIGURE" = "" ]; then
|
||||
$srcdir/configure "$@" || exit 1
|
||||
|
83
configure.ac
83
configure.ac
@@ -1,6 +1,6 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_INIT([HexChat],[2.12.3])
|
||||
AC_INIT([HexChat],[2.11.0])
|
||||
|
||||
AC_PREREQ([2.64])
|
||||
AC_COPYRIGHT([Copyright (C) 1998-2010 Peter Zelezny])
|
||||
@@ -9,18 +9,13 @@ AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_SRCDIR([configure.ac])
|
||||
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
AC_CONFIG_AUX_DIR([build-aux])
|
||||
|
||||
AM_INIT_AUTOMAKE([1.11.1 dist-xz no-dist-gzip subdir-objects no-define foreign])
|
||||
AM_SILENT_RULES([yes])
|
||||
|
||||
AC_DEFUN([HEX_CHECK_MACRO], [m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined. Is ]$2[ installed?])])])
|
||||
|
||||
HEX_CHECK_MACRO([AX_APPEND_COMPILE_FLAGS], [autoconf-archive])
|
||||
HEX_CHECK_MACRO([PKG_PROG_PKG_CONFIG], [pkg-config])
|
||||
|
||||
AX_IS_RELEASE([minor-version])
|
||||
AX_CHECK_ENABLE_DEBUG([yes])
|
||||
AX_REQUIRE_DEFINED([PKG_PROG_PKG_CONFIG])
|
||||
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AM_MAINTAINER_MODE([enable])
|
||||
@@ -118,10 +113,6 @@ AC_ARG_ENABLE(perl,
|
||||
[AS_HELP_STRING([--disable-perl],[don\'t build the perl plugin])],
|
||||
perl=$enableval, perl=yes)
|
||||
|
||||
AC_ARG_ENABLE(lua,
|
||||
[AS_HELP_STRING([--disable-lua],[don\'t build the lua plugin])],
|
||||
lua=$enableval, lua=yes)
|
||||
|
||||
AC_ARG_ENABLE(perl_old,
|
||||
[AS_HELP_STRING([--disable-perl_old],[no backwards compatibility for perl plugin])],
|
||||
perl_old=$enableval, perl_old=yes)
|
||||
@@ -174,9 +165,6 @@ AC_ARG_WITH(theme-manager,
|
||||
[AS_HELP_STRING([--with-theme-manager],[compile theme manager (needs monodevelop, default: off)])],
|
||||
theme_manager=$withval, theme_manager=no)
|
||||
|
||||
AC_ARG_ENABLE(stack-protector,
|
||||
[AS_HELP_STRING([--disable-stack-protector],[disable building with stack-protector])],
|
||||
stack_protector=$enableval, stack_protector=yes)
|
||||
|
||||
|
||||
dnl *********************************************************************
|
||||
@@ -193,11 +181,11 @@ dnl *********************************************************************
|
||||
dnl ** GLIB *************************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
AM_PATH_GLIB_2_0([2.34.0], [], [AC_MSG_ERROR([Glib not found!])], [gmodule gobject gio])
|
||||
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_34], [Dont warn using older APIs])
|
||||
AC_DEFINE([GLIB_VERSION_MAX_ALLOWED], [GLIB_VERSION_2_34], [Prevents using newer APIs])
|
||||
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 **************************************************************
|
||||
@@ -225,40 +213,6 @@ AS_IF([test "x$_gdk_tgt" = xquartz], [
|
||||
])
|
||||
])
|
||||
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** Lua **************************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
AS_IF([test "$lua" = yes], [
|
||||
AC_MSG_CHECKING(for plugin interface used by lua)
|
||||
AS_IF([test "$plugin" = yes], [
|
||||
AC_MSG_RESULT([yes])
|
||||
|
||||
m4_define_default([_LUA_LIST], [luajit lua lua5.3 lua53 lua5.2 lua52 lua5.1 lua51])
|
||||
|
||||
AC_ARG_VAR([LUA], [The Lua pkgconfig name, e.g. luajit or lua5.2])
|
||||
AS_IF([test "x$LUA" = 'x'], [
|
||||
for lua_var in _LUA_LIST; do
|
||||
$PKG_CONFIG --exists $lua_var || continue
|
||||
LUA=$lua_var
|
||||
break
|
||||
done
|
||||
AS_IF([test "x$LUA" = 'x'], [
|
||||
AC_MSG_ERROR([Failed to find lua])
|
||||
])
|
||||
])
|
||||
|
||||
PKG_CHECK_MODULES([LUA], $LUA, [
|
||||
AC_SUBST([LUA_CFLAGS])
|
||||
AC_SUBST([LUA_LIBS])
|
||||
])
|
||||
], [
|
||||
AC_MSG_RESULT([plugins are disabled, use the --enable-plugin option for lua])
|
||||
lua=no
|
||||
])
|
||||
])
|
||||
|
||||
dnl *********************************************************************
|
||||
dnl ** PERL *************************************************************
|
||||
dnl *********************************************************************
|
||||
@@ -373,7 +327,7 @@ dnl *********************************************************************
|
||||
|
||||
|
||||
AS_IF([test "$openssl" != no], [
|
||||
PKG_CHECK_MODULES(OPENSSL, [openssl >= 0.9.8], [
|
||||
PKG_CHECK_MODULES(OPENSSL, [openssl], [
|
||||
AC_DEFINE(USE_OPENSSL)
|
||||
openssl=yes
|
||||
COMMON_LIBS="$COMMON_LIBS $OPENSSL_LIBS"
|
||||
@@ -605,7 +559,6 @@ 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_LUA, test "x$lua" = "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")
|
||||
@@ -623,38 +576,18 @@ dnl *********************************************************************
|
||||
dnl ** CFLAGS ***********************************************************
|
||||
dnl *********************************************************************
|
||||
|
||||
AX_APPEND_COMPILE_FLAGS([\
|
||||
CC_CHECK_FLAGS_APPEND([CFLAGS], [CFLAGS], [ \
|
||||
-pipe \
|
||||
-funsigned-char \
|
||||
-fPIE \
|
||||
-fPIC \
|
||||
-Wall \
|
||||
-Wextra \
|
||||
-Wstrict-prototypes \
|
||||
-Wno-unused-parameter \
|
||||
-Wno-sign-compare \
|
||||
-Wno-pointer-sign \
|
||||
-Wno-missing-field-initializers \
|
||||
-Wno-unused-result \
|
||||
-Werror=format-security \
|
||||
-Werror=init-self \
|
||||
-Werror=declaration-after-statement \
|
||||
-Werror=missing-include-dirs \
|
||||
-Werror=date-time \
|
||||
-Werror=implicit-function-declaration \
|
||||
-Werror=pointer-arith \
|
||||
])
|
||||
|
||||
AS_IF([test "$stack_protector" = "yes"], [
|
||||
AX_APPEND_COMPILE_FLAGS([ \
|
||||
-fstack-protector-strong \
|
||||
])
|
||||
])
|
||||
|
||||
AX_APPEND_LINK_FLAGS([ \
|
||||
-pie \
|
||||
-Wl,-z,relro \
|
||||
-Wl,-z,now \
|
||||
])
|
||||
|
||||
dnl *********************************************************************
|
||||
@@ -763,7 +696,6 @@ src/htm/Makefile
|
||||
src/htm/thememan
|
||||
osx/Info.plist
|
||||
plugins/Makefile
|
||||
plugins/lua/Makefile
|
||||
plugins/python/Makefile
|
||||
plugins/perl/Makefile
|
||||
plugins/checksum/Makefile
|
||||
@@ -789,7 +721,6 @@ echo libcanberra support ... : $libcanberra
|
||||
echo Plugin interface ...... : $plugin
|
||||
echo libproxy support ...... : $libproxy
|
||||
echo
|
||||
echo Lua ................... : $lua \($LUA\)
|
||||
echo Perl .................. : $perl
|
||||
echo Python ................ : $python
|
||||
echo
|
||||
|
@@ -1,15 +1,7 @@
|
||||
SUBDIRS =
|
||||
|
||||
if DO_PLUGIN
|
||||
SUBDIRS += pkgconfig
|
||||
endif
|
||||
SUBDIRS = pkgconfig man
|
||||
|
||||
if DO_GTK
|
||||
SUBDIRS += icons misc man
|
||||
else
|
||||
if WITH_TM
|
||||
SUBDIRS += misc
|
||||
endif
|
||||
SUBDIRS += icons misc
|
||||
endif
|
||||
|
||||
EXTRA_DIST = \
|
||||
|
@@ -1,29 +1,10 @@
|
||||
|
||||
appdatadir = $(datadir)/appdata
|
||||
appdata_in_files =
|
||||
|
||||
if DO_GTK
|
||||
appdata_in_files += hexchat.appdata.xml.in
|
||||
endif
|
||||
|
||||
appdata_in_files = hexchat.appdata.xml.in
|
||||
appdata_DATA = $(appdata_in_files:.xml.in=.xml)
|
||||
appdatadir = $(datadir)/appdata
|
||||
@INTLTOOL_XML_RULE@
|
||||
|
||||
if USE_DBUS
|
||||
exec_command = 'hexchat --existing %U'
|
||||
else
|
||||
exec_command = 'hexchat %U'
|
||||
endif
|
||||
|
||||
hexchat.desktop.in: hexchat.desktop.in.in
|
||||
$(AM_V_GEN)sed -e s!\@exec_command\@!$(exec_command)! < $< > $@
|
||||
|
||||
data_desktopdir = $(datadir)/applications
|
||||
data_desktop_in_files =
|
||||
|
||||
if DO_GTK
|
||||
data_desktop_in_files += hexchat.desktop.in
|
||||
endif
|
||||
data_desktop_in_files = hexchat.desktop.in
|
||||
|
||||
if WITH_TM
|
||||
data_desktop_in_files += htm.desktop.in
|
||||
@@ -45,6 +26,6 @@ uninstall-hook:
|
||||
$(UPDATE_MIME_DATABASE);
|
||||
$(UPDATE_DESKTOP_DATABASE);
|
||||
|
||||
EXTRA_DIST = hexchat.appdata.xml.in hexchat.desktop.in.in htm.desktop.in htm-mime.xml
|
||||
EXTRA_DIST = hexchat.appdata.xml.in hexchat.desktop.in htm.desktop.in htm-mime.xml
|
||||
|
||||
CLEANFILES = $(appdata_DATA) $(data_desktop_DATA) hexchat.desktop.in
|
||||
CLEANFILES = $(appdata_DATA) $(data_desktop_DATA)
|
||||
|
@@ -1,26 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop">
|
||||
<id>hexchat.desktop</id>
|
||||
<name>HexChat</name>
|
||||
<developer_name>HexChat</developer_name>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-2.0+</project_license>
|
||||
<translation type="gettext">hexchat</translation>
|
||||
<summary>IRC Client</summary>
|
||||
<description>
|
||||
<_p>HexChat is an easy to use yet extensible IRC Client. It allows you to securely join multiple networks and talk to users privately or in channels using a customizable interface. You can even transfer files.</_p>
|
||||
<_p>HexChat supports features such as: DCC, SASL, proxies, spellcheck, alerts, logging, custom themes, and Python/Perl scripts.</_p>
|
||||
</description>
|
||||
<url type="homepage">http://hexchat.github.io</url>
|
||||
<url type="bugtracker">https://github.com/hexchat/hexchat</url>
|
||||
<url type="translate">https://www.transifex.com/hexchat/hexchat</url>
|
||||
<url type="donation">https://goo.gl/jESZvU</url>
|
||||
<url type="help">https://hexchat.readthedocs.io/en/latest/</url>
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image>http://i.imgur.com/tLMguQz.png</image>
|
||||
<_caption>Main Chat Window</_caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<update_contact>tingping_at_fedoraproject.org</update_contact>
|
||||
</component>
|
||||
<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>
|
||||
|
||||
|
@@ -3,7 +3,7 @@ _Name=HexChat
|
||||
_GenericName=IRC Client
|
||||
_Comment=Chat with other people online
|
||||
_Keywords=IM;Chat;
|
||||
Exec=@exec_command@
|
||||
Exec=hexchat %U
|
||||
Icon=hexchat
|
||||
Terminal=false
|
||||
Type=Application
|
60
m4/ac-check-cflags.m4
Normal file
60
m4/ac-check-cflags.m4
Normal file
@@ -0,0 +1,60 @@
|
||||
dnl Macros to check the presence of generic (non-typed) symbols.
|
||||
dnl Copyright (c) 2006-2008 Diego Pettenò <flameeyes@gmail.com>
|
||||
dnl Copyright (c) 2006-2008 xine project
|
||||
dnl Copyright (c) 2012 Lucas De Marchi <lucas.de.marchi@gmail.com>
|
||||
dnl
|
||||
dnl This program is free software; you can redistribute it and/or modify
|
||||
dnl it under the terms of the GNU General Public License as published by
|
||||
dnl the Free Software Foundation; either version 2, or (at your option)
|
||||
dnl any later version.
|
||||
dnl
|
||||
dnl This program is distributed in the hope that it will be useful,
|
||||
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
dnl GNU General Public License for more details.
|
||||
dnl
|
||||
dnl You should have received a copy of the GNU General Public License
|
||||
dnl along with this program; if not, write to the Free Software
|
||||
dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
dnl 02110-1301, USA.
|
||||
dnl
|
||||
dnl As a special exception, the copyright owners of the
|
||||
dnl macro gives unlimited permission to copy, distribute and modify the
|
||||
dnl configure scripts that are the output of Autoconf when processing the
|
||||
dnl Macro. You need not follow the terms of the GNU General Public
|
||||
dnl License when using or distributing such scripts, even though portions
|
||||
dnl of the text of the Macro appear in them. The GNU General Public
|
||||
dnl License (GPL) does govern all other use of the material that
|
||||
dnl constitutes the Autoconf Macro.
|
||||
dnl
|
||||
dnl This special exception to the GPL applies to versions of the
|
||||
dnl Autoconf Macro released by this project. When you make and
|
||||
dnl distribute a modified version of the Autoconf Macro, you may extend
|
||||
dnl this special exception to the GPL to apply to your modified version as
|
||||
dnl well.
|
||||
|
||||
dnl Check if FLAG in ENV-VAR is supported by compiler and append it
|
||||
dnl to WHERE-TO-APPEND variable
|
||||
dnl CC_CHECK_FLAG_APPEND([WHERE-TO-APPEND], [ENV-VAR], [FLAG])
|
||||
|
||||
AC_DEFUN([CC_CHECK_FLAG_APPEND], [
|
||||
AC_CACHE_CHECK([if $CC supports flag $3 in envvar $2],
|
||||
AS_TR_SH([cc_cv_$2_$3]),
|
||||
[eval "AS_TR_SH([cc_save_$2])='${$2}'"
|
||||
eval "AS_TR_SH([$2])='$3'"
|
||||
AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a = 0; int main(void) { return a; } ])],
|
||||
[eval "AS_TR_SH([cc_cv_$2_$3])='yes'"],
|
||||
[eval "AS_TR_SH([cc_cv_$2_$3])='no'"])
|
||||
eval "AS_TR_SH([$2])='$cc_save_$2'"])
|
||||
|
||||
AS_IF([eval test x$]AS_TR_SH([cc_cv_$2_$3])[ = xyes],
|
||||
[eval "$1='${$1} $3'"])
|
||||
])
|
||||
|
||||
dnl CC_CHECK_FLAGS_APPEND([WHERE-TO-APPEND], [ENV-VAR], [FLAG1 FLAG2])
|
||||
AC_DEFUN([CC_CHECK_FLAGS_APPEND], [
|
||||
for flag in $3; do
|
||||
CC_CHECK_FLAG_APPEND($1, $2, $flag)
|
||||
done
|
||||
])
|
||||
|
116
m4/ax_perl_ext_flags.m4
Normal file
116
m4/ax_perl_ext_flags.m4
Normal file
@@ -0,0 +1,116 @@
|
||||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_perl_ext_flags.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_PERL_EXT_FLAGS([CFLAGS-VARIABLE], [LDFLAGS-VARIABLE], [EXTRA-MODULES])
|
||||
# AX_PERL_EXT_CFLAGS([CFLAGS-VARIABLE])
|
||||
# AX_PERL_EXT_LDFLAGS([LDFLAGS-VARIABLE], [EXTRA-MODULES])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# Fetches the linker flags and C compiler flags for compiling and linking
|
||||
# programs that embed a Perl interpreter. If the EXTRA-MODULES argument is
|
||||
# submitted, it is a space separated list of extra modules to link. The
|
||||
# flags will be stored in the provided variables.
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# AX_PERL_EXT_FLAGS([PERLXS_CFLAGS], [PERLXS_LDFLAGS])
|
||||
# AC_SUBST([PERLXS_CFLAGS])
|
||||
# AC_SUBST([PERLXS_LDFLAGS])
|
||||
#
|
||||
# AX_PERL_EXT_CFLAGS([PERLXS_CFLAGS])
|
||||
# AC_SUBST([PERLXS_CFLAGS])
|
||||
#
|
||||
# AX_PERL_EXT_LDFLAGS([PERLXS_LDFLAGS], [-std Socket])
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2009 Mats Kindahl of Sun Microsystems <mats@sun.com>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# 3. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#serial 5
|
||||
|
||||
AC_DEFUN([AX_PERL_EXT_CFLAGS],
|
||||
[AC_CHECK_PROG(PERL,perl,perl)
|
||||
_AX_PERL_EXT_MODULE_CHECK([ExtUtils::Embed], [have_embed=yes],
|
||||
[have_embed=no])
|
||||
AS_IF([test $have_embed = no],
|
||||
AC_MSG_ERROR([Require ExtUtils::Embed to proceed]))
|
||||
_AX_PERL_EXT_EMBED_CHECK([$1],[ccopts])
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN([AX_PERL_EXT_LDFLAGS],
|
||||
[AC_CHECK_PROG(PERL,perl,perl)
|
||||
_AX_PERL_EXT_MODULE_CHECK([ExtUtils::Embed], [have_embed=yes],
|
||||
[have_embed=no])
|
||||
AS_IF([test $have_embed = no],
|
||||
AC_MSG_ERROR([Require ExtUtils::Embed to proceed]))
|
||||
_AX_PERL_EXT_EMBED_CHECK([$1],[ldopts],[$2])
|
||||
])
|
||||
|
||||
|
||||
AC_DEFUN([AX_PERL_EXT_FLAGS],
|
||||
[AC_CHECK_PROG(PERL,perl,perl)
|
||||
_AX_PERL_EXT_MODULE_CHECK([ExtUtils::Embed], [have_embed=yes],
|
||||
[have_embed=no])
|
||||
AS_IF([test $have_embed = no],
|
||||
AC_MSG_ERROR([Require ExtUtils::Embed to proceed]))
|
||||
_AX_PERL_EXT_EMBED_CHECK([$1],[ccopts])
|
||||
_AX_PERL_EXT_EMBED_CHECK([$2],[ldopts],[$3])
|
||||
])
|
||||
|
||||
|
||||
dnl _AX_PERL_EXT_MODULE_CHECK(MODULE-NAME, ACTION-IF-FOUND, ACTION-IF-NOT-FOUND)
|
||||
dnl
|
||||
dnl Check for the existance of the perl module given by MODULE-NAME.
|
||||
dnl
|
||||
AC_DEFUN([_AX_PERL_EXT_MODULE_CHECK],
|
||||
[AC_MSG_CHECKING([for perl module $1])
|
||||
$PERL "-M$1" -e exit > /dev/null 2>&1
|
||||
AS_IF([test $? -eq 0],
|
||||
[AC_MSG_RESULT(yes)
|
||||
$2],
|
||||
[AC_MSG_RESULT(no)
|
||||
$3])
|
||||
])
|
||||
|
||||
dnl _AX_PERL_EXT_EMBED_CHECK(VARIABLE, COMMAND, [EXTRA-FLAGS]) Use
|
||||
dnl
|
||||
dnl ExtUtils::Embed fetch flags for embedding Perl in a C/C++
|
||||
dnl application
|
||||
dnl
|
||||
AC_DEFUN([_AX_PERL_EXT_EMBED_CHECK],
|
||||
[AC_MSG_CHECKING([for perl $2 embed flags])
|
||||
ax_c_perlxs_extras="$3"
|
||||
$1=`$PERL -MExtUtils::Embed -e $2 ${ax_c_perlxs_extras:+"-- $3"}`
|
||||
AC_MSG_RESULT($$1)
|
||||
])
|
37
m4/ax_require_defined.m4
Normal file
37
m4/ax_require_defined.m4
Normal file
@@ -0,0 +1,37 @@
|
||||
# ===========================================================================
|
||||
# http://www.gnu.org/software/autoconf-archive/ax_require_defined.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_REQUIRE_DEFINED(MACRO)
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
|
||||
# been defined and thus are available for use. This avoids random issues
|
||||
# where a macro isn't expanded. Instead the configure script emits a
|
||||
# non-fatal:
|
||||
#
|
||||
# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
|
||||
#
|
||||
# It's like AC_REQUIRE except it doesn't expand the required macro.
|
||||
#
|
||||
# Here's an example:
|
||||
#
|
||||
# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 1
|
||||
|
||||
AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
|
||||
m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
|
||||
])dnl AX_REQUIRE_DEFINED
|
@@ -1,7 +1,3 @@
|
||||
if DO_LUA
|
||||
lua = lua
|
||||
endif
|
||||
|
||||
if DO_PYTHON
|
||||
pythondir = python
|
||||
endif
|
||||
@@ -26,4 +22,4 @@ if DO_SYSINFO
|
||||
sysinfodir = sysinfo
|
||||
endif
|
||||
|
||||
SUBDIRS = $(lua) $(pythondir) $(perldir) $(checksumdir) $(doatdir) $(fishlimdir) $(sysinfodir)
|
||||
SUBDIRS = $(pythondir) $(perldir) $(checksumdir) $(doatdir) $(fishlimdir) $(sysinfodir)
|
||||
|
@@ -4,5 +4,4 @@ lib_LTLIBRARIES = checksum.la
|
||||
checksum_la_SOURCES = checksum.c
|
||||
checksum_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
|
||||
checksum_la_LIBADD = $(GLIB_LIBS)
|
||||
checksum_la_CPPFLAGS = -I$(top_srcdir)/src/common
|
||||
checksum_la_CFLAGS = $(GLIB_CFLAGS)
|
||||
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");
|
||||
|
||||
|
@@ -4,6 +4,5 @@ lib_LTLIBRARIES = doat.la
|
||||
doat_la_SOURCES = doat.c
|
||||
doat_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
|
||||
doat_la_LIBADD = $(GLIB_LIBS)
|
||||
doat_la_CPPFLAGS = -I$(top_srcdir)/src/common
|
||||
doat_la_CFLAGS = $(GLIB_CFLAGS)
|
||||
doat_la_CFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)/src/common
|
||||
|
||||
|
16
plugins/fishlim/INSTALL
Normal file
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
|
||||
|
||||
|
@@ -1,10 +1,9 @@
|
||||
EXTRA_DIST = LICENSE fish.h irc.h keystore.h plugin_hexchat.h dh1080.h
|
||||
EXTRA_DIST = INSTALL LICENSE fish.h irc.h keystore.h plugin_hexchat.h
|
||||
|
||||
libdir = $(hexchatlibdir)
|
||||
|
||||
lib_LTLIBRARIES = fishlim.la
|
||||
fishlim_la_SOURCES = fish.c irc.c keystore.c plugin_hexchat.c dh1080.c
|
||||
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_CPPFLAGS = -I$(top_srcdir)/src/common
|
||||
fishlim_la_CFLAGS = $(GLIB_CFLAGS) $(OPENSSL_CFLAGS)
|
||||
fishlim_la_CFLAGS = $(GLIB_CFLAGS) $(OPENSSL_CFLAGS) -I$(top_srcdir)/src/common
|
||||
|
@@ -1,209 +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 "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;
|
||||
|
||||
g_dh->p = BN_bin2bn (prime1080, DH1080_PRIME_BYTES, NULL);
|
||||
g_dh->g = BN_new ();
|
||||
|
||||
g_assert (g_dh->p != NULL && g_dh->g != NULL);
|
||||
BN_set_word(g_dh->g, 2);
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
priv_key_data = dh1080_decode_b64 (priv_key, &priv_key_len);
|
||||
dh->priv_key = BN_bin2bn(priv_key_data, priv_key_len, NULL);
|
||||
|
||||
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);
|
||||
|
@@ -53,14 +53,13 @@
|
||||
<None Include="fishlim.def" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="dh1080.h" />
|
||||
<ClInclude Include="bool.h" />
|
||||
<ClInclude Include="fish.h" />
|
||||
<ClInclude Include="irc.h" />
|
||||
<ClInclude Include="keystore.h" />
|
||||
<ClInclude Include="plugin_hexchat.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dh1080.c" />
|
||||
<ClCompile Include="fish.c" />
|
||||
<ClCompile Include="irc.c" />
|
||||
<ClCompile Include="keystore.c" />
|
||||
|
@@ -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.
|
||||
@@ -106,13 +90,9 @@ static gchar *get_nick_value(GKeyFile *keyfile, const char *nick, const char *it
|
||||
char *keystore_get_key(const char *nick) {
|
||||
/* Get the key */
|
||||
GKeyFile *keyfile = getConfigFile();
|
||||
char *escaped_nick = escape_nickname(nick);
|
||||
gchar *value = get_nick_value(keyfile, escaped_nick, "key");
|
||||
gchar *value = get_nick_value(keyfile, nick, "key");
|
||||
g_key_file_free(keyfile);
|
||||
g_free(escaped_nick);
|
||||
|
||||
if (!value)
|
||||
return NULL;
|
||||
if (!value) return NULL;
|
||||
|
||||
if (strncmp(value, "+OK ", 4) != 0) {
|
||||
/* Key is stored in plaintext */
|
||||
@@ -193,10 +173,9 @@ gboolean keystore_store_key(const char *nick, const char *key) {
|
||||
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();
|
||||
@@ -210,11 +189,11 @@ gboolean keystore_store_key(const char *nick, const char *key) {
|
||||
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);
|
||||
}
|
||||
|
||||
/* Save key store file */
|
||||
@@ -222,7 +201,6 @@ gboolean keystore_store_key(const char *nick, const char *key) {
|
||||
|
||||
end:
|
||||
g_key_file_free(keyfile);
|
||||
g_free(escaped_nick);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -231,15 +209,13 @@ gboolean keystore_store_key(const char *nick, const char *key) {
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
@@ -1,7 +1,6 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2010-2011 Samuel Lidén Borell <samuel@kodafritt.se>
|
||||
Copyright (c) 2015 <the.cypher@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -33,30 +32,23 @@
|
||||
#define HEXCHAT_MAX_WORDS 32
|
||||
|
||||
#include "fish.h"
|
||||
#include "dh1080.h"
|
||||
#include "keystore.h"
|
||||
#include "irc.h"
|
||||
|
||||
static const char plugin_name[] = "FiSHLiM";
|
||||
static const char plugin_desc[] = "Encryption plugin for the FiSH protocol. Less is More!";
|
||||
static const char plugin_version[] = "0.1.0";
|
||||
static const char plugin_version[] = "0.0.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 const char usage_keyx[] = "Usage: KEYX [<nick>], performs DH1080 key-exchange with <nick>";
|
||||
static const char usage_topic[] = "Usage: TOPIC+ <topic>, sets a new encrypted topic for the current channel";
|
||||
static const char usage_notice[] = "Usage: NOTICE+ <nick or #channel> <notice>";
|
||||
static const char usage_msg[] = "Usage: MSG+ <nick or #channel> <message>";
|
||||
|
||||
|
||||
static hexchat_plugin *ph;
|
||||
static GHashTable *pending_exchanges;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the path to the key store file.
|
||||
*/
|
||||
gchar *get_config_filename(void) {
|
||||
gchar *get_config_filename() {
|
||||
char *filename_fs, *filename_utf8;
|
||||
|
||||
filename_utf8 = g_build_filename(hexchat_get_info(ph, "configdir"), "addon_fishlim.conf", NULL);
|
||||
@@ -66,38 +58,6 @@ 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 && hexchat_nickcmp (ph, chan_name, name) == 0) {
|
||||
ret = (hexchat_context*)hexchat_list_str(ph, channels, "context");
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
hexchat_list_free(ph, channels);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int irc_nick_cmp(const char *a, const char *b) {
|
||||
return hexchat_nickcmp (ph, a, b);
|
||||
}
|
||||
@@ -203,11 +163,11 @@ static int handle_incoming(char *word[], char *word_eol[], hexchat_event_attrs *
|
||||
/* Prefix with colon, which gets stripped out otherwise */
|
||||
g_string_append_c (message, ':');
|
||||
}
|
||||
|
||||
|
||||
if (prefix_char) {
|
||||
g_string_append_c (message, prefix_char);
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
/* Add unencrypted data (for example, a prefix from a bouncer or bot) */
|
||||
peice = word[uw];
|
||||
@@ -216,7 +176,7 @@ static int handle_incoming(char *word[], char *word_eol[], hexchat_event_attrs *
|
||||
g_string_append (message, peice);
|
||||
}
|
||||
g_free(decrypted);
|
||||
|
||||
|
||||
/* Simulate unencrypted message */
|
||||
/* hexchat_printf(ph, "simulating: %s\n", message->str); */
|
||||
hexchat_command(ph, message->str);
|
||||
@@ -224,103 +184,26 @@ static int handle_incoming(char *word[], char *word_eol[], hexchat_event_attrs *
|
||||
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;
|
||||
}
|
||||
|
||||
static int handle_keyx_notice(char *word[], char *word_eol[], void *userdata) {
|
||||
const char *dh_message = word[4];
|
||||
const char *dh_pubkey = word[5];
|
||||
hexchat_context *query_ctx;
|
||||
const char *prefix;
|
||||
gboolean cbc;
|
||||
char *sender, *secret_key, *priv_key = NULL;
|
||||
|
||||
if (!*dh_message || !*dh_pubkey || strlen(dh_pubkey) != 181)
|
||||
return HEXCHAT_EAT_NONE;
|
||||
|
||||
if (!irc_parse_message((const char**)word, &prefix, NULL, NULL) || !prefix)
|
||||
return HEXCHAT_EAT_NONE;
|
||||
|
||||
sender = irc_prefix_get_nick(prefix);
|
||||
query_ctx = find_context_on_network(sender);
|
||||
if (query_ctx)
|
||||
hexchat_set_context(ph, query_ctx);
|
||||
|
||||
dh_message++; /* : prefix */
|
||||
if (*dh_message == '+' || *dh_message == '-')
|
||||
dh_message++; /* identify-msg */
|
||||
|
||||
cbc = g_strcmp0 (word[6], "CBC") == 0;
|
||||
|
||||
if (!strcmp(dh_message, "DH1080_INIT")) {
|
||||
char *pub_key;
|
||||
|
||||
if (cbc) {
|
||||
hexchat_print(ph, "Recieved key exchange for CBC mode which is not supported.");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hexchat_printf(ph, "Received public key from %s, sending mine...", sender);
|
||||
if (dh1080_generate_key(&priv_key, &pub_key)) {
|
||||
hexchat_commandf(ph, "quote NOTICE %s :DH1080_FINISH %s", sender, pub_key);
|
||||
g_free(pub_key);
|
||||
} else {
|
||||
hexchat_print(ph, "Failed to generate keys");
|
||||
goto cleanup;
|
||||
}
|
||||
} else if (!strcmp (dh_message, "DH1080_FINISH")) {
|
||||
char *sender_lower = g_ascii_strdown(sender, -1);
|
||||
/* FIXME: Properly respect irc casing */
|
||||
priv_key = g_hash_table_lookup(pending_exchanges, sender_lower);
|
||||
g_hash_table_steal(pending_exchanges, sender_lower);
|
||||
g_free(sender_lower);
|
||||
|
||||
if (cbc) {
|
||||
hexchat_print(ph, "Recieved key exchange for CBC mode which is not supported.");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!priv_key) {
|
||||
hexchat_printf(ph, "Recieved a key exchange response for unknown user: %s", sender);
|
||||
goto cleanup;
|
||||
}
|
||||
} else {
|
||||
/* Regular notice */
|
||||
g_free(sender);
|
||||
return HEXCHAT_EAT_NONE;
|
||||
}
|
||||
|
||||
if (dh1080_compute_key(priv_key, dh_pubkey, &secret_key)) {
|
||||
keystore_store_key(sender, secret_key);
|
||||
hexchat_printf(ph, "Stored new key for %s", sender);
|
||||
g_free(secret_key);
|
||||
} else {
|
||||
hexchat_print(ph, "Failed to create secret key!");
|
||||
}
|
||||
|
||||
cleanup:
|
||||
g_free(sender);
|
||||
g_free(priv_key);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command handler for /setkey
|
||||
*/
|
||||
static int handle_setkey(char *word[], char *word_eol[], void *userdata) {
|
||||
const char *nick;
|
||||
const char *key;
|
||||
|
||||
|
||||
/* Check syntax */
|
||||
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");
|
||||
@@ -330,14 +213,14 @@ static int handle_setkey(char *word[], char *word_eol[], void *userdata) {
|
||||
nick = word[2];
|
||||
key = word_eol[3];
|
||||
}
|
||||
|
||||
|
||||
/* Set password */
|
||||
if (keystore_store_key(nick, key)) {
|
||||
hexchat_printf(ph, "Stored key for %s\n", nick);
|
||||
} else {
|
||||
hexchat_printf(ph, "\00305Failed to store key in addon_fishlim.conf\n");
|
||||
}
|
||||
|
||||
|
||||
return HEXCHAT_EAT_HEXCHAT;
|
||||
}
|
||||
|
||||
@@ -346,174 +229,25 @@ static int handle_setkey(char *word[], char *word_eol[], void *userdata) {
|
||||
*/
|
||||
static int handle_delkey(char *word[], char *word_eol[], void *userdata) {
|
||||
const char *nick;
|
||||
|
||||
|
||||
/* Check syntax */
|
||||
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");
|
||||
}
|
||||
|
||||
|
||||
return HEXCHAT_EAT_HEXCHAT;
|
||||
}
|
||||
|
||||
static int handle_keyx(char *word[], char *word_eol[], void *userdata) {
|
||||
const char *target = word[2];
|
||||
hexchat_context *query_ctx = NULL;
|
||||
char *pub_key, *priv_key;
|
||||
int ctx_type;
|
||||
|
||||
if (*target)
|
||||
query_ctx = find_context_on_network(target);
|
||||
else {
|
||||
target = hexchat_get_info(ph, "channel");
|
||||
query_ctx = hexchat_get_context (ph);
|
||||
}
|
||||
|
||||
if (query_ctx) {
|
||||
hexchat_set_context(ph, query_ctx);
|
||||
ctx_type = hexchat_list_int(ph, NULL, "type");
|
||||
}
|
||||
|
||||
if ((query_ctx && ctx_type != 3) || (!query_ctx && !irc_is_query(target))) {
|
||||
hexchat_print(ph, "You can only exchange keys with individuals");
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
if (dh1080_generate_key(&priv_key, &pub_key)) {
|
||||
g_hash_table_replace (pending_exchanges, g_ascii_strdown(target, -1), priv_key);
|
||||
|
||||
hexchat_commandf(ph, "quote NOTICE %s :DH1080_INIT %s", target, pub_key);
|
||||
hexchat_printf(ph, "Sent public key to %s, waiting for reply...", target);
|
||||
|
||||
g_free(pub_key);
|
||||
} else {
|
||||
hexchat_print(ph, "Failed to generate keys");
|
||||
}
|
||||
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command handler for /topic+
|
||||
*/
|
||||
static int handle_crypt_topic(char *word[], char *word_eol[], void *userdata) {
|
||||
const char *target;
|
||||
const char *topic = word_eol[2];
|
||||
char *buf;
|
||||
|
||||
if (!*topic) {
|
||||
hexchat_print(ph, usage_topic);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
if (hexchat_list_int(ph, NULL, "type") != 2) {
|
||||
hexchat_printf(ph, "Please change to the channel window where you want to set the topic!");
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
target = hexchat_get_info(ph, "channel");
|
||||
buf = fish_encrypt_for_nick(target, topic);
|
||||
if (buf == NULL) {
|
||||
hexchat_printf(ph, "/topic+ error, no key found for %s", target);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
hexchat_commandf(ph, "TOPIC %s +OK %s", target, buf);
|
||||
g_free(buf);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command handler for /notice+
|
||||
*/
|
||||
static int handle_crypt_notice(char *word[], char *word_eol[], void *userdata)
|
||||
{
|
||||
const char *target = word[2];
|
||||
const char *notice = word_eol[3];
|
||||
char *buf;
|
||||
|
||||
if (!*target || !*notice) {
|
||||
hexchat_print(ph, usage_notice);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
buf = fish_encrypt_for_nick(target, notice);
|
||||
if (buf == NULL) {
|
||||
hexchat_printf(ph, "/notice+ error, no key found for %s.", target);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
hexchat_commandf(ph, "quote NOTICE %s :+OK %s", target, buf);
|
||||
hexchat_emit_print(ph, "Notice Sent", target, notice);
|
||||
g_free(buf);
|
||||
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Command handler for /msg+
|
||||
*/
|
||||
static int handle_crypt_msg(char *word[], char *word_eol[], void *userdata)
|
||||
{
|
||||
const char *target = word[2];
|
||||
const char *message = word_eol[3];
|
||||
hexchat_context *query_ctx;
|
||||
char *buf;
|
||||
|
||||
if (!*target || !*message) {
|
||||
hexchat_print(ph, usage_msg);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
buf = fish_encrypt_for_nick(target, message);
|
||||
if (buf == NULL) {
|
||||
hexchat_printf(ph, "/msg+ error, no key found for %s", target);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
hexchat_commandf(ph, "PRIVMSG %s :+OK %s", target, buf);
|
||||
|
||||
query_ctx = find_context_on_network(target);
|
||||
if (query_ctx) {
|
||||
hexchat_set_context(ph, query_ctx);
|
||||
|
||||
/* FIXME: Mode char */
|
||||
hexchat_emit_print(ph, "Your Message", hexchat_get_info(ph, "nick"),
|
||||
message, "", "");
|
||||
}
|
||||
else {
|
||||
hexchat_emit_print(ph, "Message Send", target, message);
|
||||
}
|
||||
|
||||
g_free(buf);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
static int handle_crypt_me(char *word[], char *word_eol[], void *userdata) {
|
||||
const char *channel = hexchat_get_info(ph, "channel");
|
||||
char *buf;
|
||||
|
||||
buf = fish_encrypt_for_nick(channel, word_eol[2]);
|
||||
if (!buf)
|
||||
return HEXCHAT_EAT_NONE;
|
||||
|
||||
hexchat_commandf(ph, "PRIVMSG %s :\001ACTION +OK %s \001", channel, buf);
|
||||
hexchat_emit_print(ph, "Your Action", hexchat_get_info(ph, "nick"),
|
||||
word_eol[2], NULL);
|
||||
|
||||
g_free(buf);
|
||||
return HEXCHAT_EAT_ALL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the plugin name version information.
|
||||
*/
|
||||
@@ -533,44 +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 (!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();
|
||||
|
||||
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
|
||||
|
@@ -1,9 +0,0 @@
|
||||
libdir = $(hexchatlibdir)
|
||||
|
||||
lib_LTLIBRARIES = lua.la
|
||||
lua_la_SOURCES = lua.c
|
||||
lua_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
|
||||
lua_la_LIBADD = $(LUA_LIBS) $(GLIB_LIBS)
|
||||
lua_la_CPPFLAGS = -I$(top_srcdir)/src/common
|
||||
lua_la_CFLAGS = $(GLIB_CFLAGS) $(LUA_CFLAGS)
|
||||
|
1745
plugins/lua/lua.c
1745
plugins/lua/lua.c
File diff suppressed because it is too large
Load Diff
@@ -1,54 +0,0 @@
|
||||
<?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>v140</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>
|
@@ -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>
|
@@ -122,6 +122,7 @@ struct tagInfo readID3V1(char *file){
|
||||
char *tag;
|
||||
char *id;
|
||||
char *tmp;
|
||||
tag = (char*) malloc(sizeof(char)*129);
|
||||
ret.artist=NULL;
|
||||
f=fopen(file,"rb");
|
||||
if (f==NULL){
|
||||
@@ -132,21 +133,18 @@ struct tagInfo readID3V1(char *file){
|
||||
//int offset=getSize(file)-128;
|
||||
res=fseek(f,-128,SEEK_END);
|
||||
if (res!=0) {printf("seek failed\n");fclose(f);return ret;}
|
||||
tag = (char*) malloc(sizeof(char)*129);
|
||||
//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);free(tag);return ret;}
|
||||
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);
|
||||
res=strcmp(id,"TAG");
|
||||
free(id);
|
||||
if (res!=0){hexchat_printf(ph,"no id3 v1 found\n");free(tag);return ret;}
|
||||
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);
|
||||
@@ -166,8 +164,6 @@ struct tagInfo readID3V1(char *file){
|
||||
//hexchat_printf(ph, "tmp: \"%s\" -> %i",tmp,tmp[0]);
|
||||
//hexchat_printf(ph,"genre \"%s\"",ret.genre);
|
||||
//if (DEBUG==1) putlog("id3v1 extracted");
|
||||
free(tmp);
|
||||
free(tag);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@@ -48,7 +48,7 @@ struct tagInfo getOggHeader(char *file){
|
||||
char *sub;
|
||||
char *name;
|
||||
char *val;
|
||||
char HEADLOC1[]="_vorbis", HEADLOC3[]="_vorbis", HEADLOC5[]="_vorbis";
|
||||
char *HEADLOC1, *HEADLOC3, *HEADLOC5;
|
||||
FILE *f;
|
||||
struct tagInfo info;
|
||||
|
||||
@@ -62,8 +62,11 @@ struct tagInfo getOggHeader(char *file){
|
||||
|
||||
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);
|
||||
@@ -101,7 +104,6 @@ struct tagInfo getOggHeader(char *file){
|
||||
if (strcmp(name,"GENRE")==0) info.genre=val;
|
||||
if (strcmp(name,"COMMENT")==0) info.comment=val;
|
||||
pos+=4+tagLen;
|
||||
free(name);
|
||||
}
|
||||
if (info.artist==NULL) info.artist="";
|
||||
if (info.album==NULL) info.album ="";
|
||||
|
@@ -91,15 +91,13 @@ struct theme themeAdd(struct theme data, char *info){
|
||||
}
|
||||
|
||||
void loadThemes(){
|
||||
char *hDir, *hFile, *line, *lineCap, *val;
|
||||
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");
|
||||
free(hDir);
|
||||
free(hFile);
|
||||
if(f==NULL)
|
||||
{
|
||||
hexchat_print(ph,"no theme in homedir, checking global theme");
|
||||
@@ -122,12 +120,10 @@ void loadThemes(){
|
||||
val=split(line,'=');
|
||||
printf("line: %s\n",line);
|
||||
printf("val: %s\n",val);
|
||||
lineCap=toUpper(line);
|
||||
if (strcmp(lineCap,"OFF_LINE")==0) notRunTheme=themeAdd(notRunTheme,val);
|
||||
if (strcmp(lineCap,"TITLE_LINE")==0) titleTheme=themeAdd(titleTheme,val);
|
||||
if (strcmp(lineCap,"MP3_LINE")==0) mp3Theme=themeAdd(mp3Theme,val);
|
||||
if (strcmp(lineCap,"OGG_LINE")==0) mp3Theme=themeAdd(oggTheme,val);
|
||||
free(lineCap);
|
||||
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");
|
||||
|
@@ -8,8 +8,7 @@ lib_LTLIBRARIES = perl.la
|
||||
perl_la_SOURCES = perl.c
|
||||
perl_la_LDFLAGS = $(PERL_LDFLAGS) $(PLUGIN_LDFLAGS) -module
|
||||
perl_la_LIBADD = $(GLIB_LIBS)
|
||||
perl_la_CPPFLAGS = -I$(top_srcdir)/src/common
|
||||
perl_la_CFLAGS = $(PERL_CFLAGS) $(GLIB_CFLAGS)
|
||||
perl_la_CFLAGS = $(PERL_CFLAGS) $(GLIB_CFLAGS) -I$(top_srcdir)/src/common
|
||||
|
||||
BUILT_SOURCES = hexchat.pm.h irc.pm.h
|
||||
CLEANFILES = $(BUILT_SOURCES)
|
||||
|
@@ -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
|
||||
*/
|
||||
|
@@ -4,6 +4,6 @@ lib_LTLIBRARIES = python.la
|
||||
python_la_SOURCES = python.c
|
||||
python_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
|
||||
python_la_LIBADD = $(PYTHON_LIBS) $(GLIB_LIBS)
|
||||
python_la_CPPFLAGS = -I$(top_srcdir)/src/common $(PYTHON_CPPFLAGS)
|
||||
python_la_CFLAGS = $(GLIB_CFLAGS)
|
||||
python_la_CPPFLAGS = $(PYTHON_CPPFLAGS)
|
||||
python_la_CFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)/src/common
|
||||
|
||||
|
@@ -273,7 +273,7 @@ typedef struct {
|
||||
|
||||
static PyObject *Util_BuildList(char *word[]);
|
||||
static PyObject *Util_BuildEOLList(char *word[]);
|
||||
static void Util_Autoload(void);
|
||||
static void Util_Autoload();
|
||||
static char *Util_Expand(char *filename);
|
||||
|
||||
static int Callback_Server(char *word[], char *word_eol[], hexchat_event_attrs *attrs, void *userdata);
|
||||
@@ -283,7 +283,7 @@ static int Callback_Print(char *word[], void *userdata);
|
||||
static int Callback_Timer(void *userdata);
|
||||
static int Callback_ThreadTimer(void *userdata);
|
||||
|
||||
static PyObject *XChatOut_New(void);
|
||||
static PyObject *XChatOut_New();
|
||||
static PyObject *XChatOut_write(PyObject *self, PyObject *args);
|
||||
static void XChatOut_dealloc(PyObject *self);
|
||||
|
||||
@@ -300,7 +300,7 @@ static PyObject *Context_FromContext(hexchat_context *context);
|
||||
static PyObject *Context_FromServerAndChannel(char *server, char *channel);
|
||||
|
||||
static PyObject *Plugin_New(char *filename, PyObject *xcoobj);
|
||||
static PyObject *Plugin_GetCurrent(void);
|
||||
static PyObject *Plugin_GetCurrent();
|
||||
static PluginObject *Plugin_ByString(char *str);
|
||||
static Hook *Plugin_AddHook(int type, PyObject *plugin, PyObject *callback,
|
||||
PyObject *userdata, char *name, void *data);
|
||||
@@ -336,11 +336,11 @@ static PyObject *Module_hexchat_pluginpref_list(PyObject *self, PyObject *args);
|
||||
static void IInterp_Exec(char *command);
|
||||
static int IInterp_Cmd(char *word[], char *word_eol[], void *userdata);
|
||||
|
||||
static void Command_PyList(void);
|
||||
static void Command_PyList();
|
||||
static void Command_PyLoad(char *filename);
|
||||
static void Command_PyUnload(char *name);
|
||||
static void Command_PyReload(char *name);
|
||||
static void Command_PyAbout(void);
|
||||
static void Command_PyAbout();
|
||||
static int Command_Py(char *word[], char *word_eol[], void *userdata);
|
||||
|
||||
/* ===================================================================== */
|
||||
@@ -1726,7 +1726,7 @@ Module_hexchat_get_info(PyObject *self, PyObject *args)
|
||||
if (info == NULL) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
if (strcmp (name, "gtkwin_ptr") == 0 || strcmp (name, "win_ptr") == 0)
|
||||
if (strcmp (name, "gtkwin_ptr") == 0)
|
||||
return PyUnicode_FromFormat("%p", info); /* format as pointer */
|
||||
else
|
||||
return PyUnicode_FromString(info);
|
||||
@@ -1849,7 +1849,7 @@ Module_hexchat_pluginpref_get(PyObject *self, PyObject *args)
|
||||
BEGIN_XCHAT_CALLS(NONE);
|
||||
retint = hexchat_pluginpref_get_int(prefph, var);
|
||||
END_XCHAT_CALLS();
|
||||
if ((retint == -1) && (strcmp(retstr, "-1") != 0))
|
||||
if ((retint == 0) && (strcmp(retstr, "0") != 0))
|
||||
ret = PyUnicode_FromString(retstr);
|
||||
else
|
||||
ret = PyLong_FromLong(retint);
|
||||
@@ -2518,7 +2518,7 @@ IInterp_Cmd(char *word[], char *word_eol[], void *userdata)
|
||||
/* Python command handling */
|
||||
|
||||
static void
|
||||
Command_PyList(void)
|
||||
Command_PyList()
|
||||
{
|
||||
GSList *list;
|
||||
list = plugin_list;
|
||||
@@ -2585,7 +2585,7 @@ Command_PyReload(char *name)
|
||||
}
|
||||
|
||||
static void
|
||||
Command_PyAbout(void)
|
||||
Command_PyAbout()
|
||||
{
|
||||
hexchat_print(ph, about);
|
||||
}
|
||||
@@ -2777,7 +2777,7 @@ hexchat_plugin_init(hexchat_plugin *plugin_handle,
|
||||
}
|
||||
|
||||
int
|
||||
hexchat_plugin_deinit(void)
|
||||
hexchat_plugin_deinit()
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
|
@@ -14,4 +14,4 @@ lib_LTLIBRARIES = sysinfo.la
|
||||
sysinfo_la_SOURCES = $(sources)
|
||||
sysinfo_la_LDFLAGS = $(PLUGIN_LDFLAGS) -module
|
||||
sysinfo_la_LIBADD = $(LIBPCI_LIBS) $(GLIB_LIBS)
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src/common -I$(srcdir)/shared $(LIBPCI_CFLAGS) $(GLIB_CFLAGS)
|
||||
AM_CPPFLAGS = $(LIBPCI_CFLAGS) $(GLIB_CFLAGS) -I$(top_srcdir)/src/common -I$(srcdir)/shared
|
||||
|
@@ -78,22 +78,10 @@ get_os (void)
|
||||
static char *
|
||||
get_os_fallback (void)
|
||||
{
|
||||
#if !defined (MAC_OS_X_VERSION_10_9) || MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_9
|
||||
SInt32 ver_major = 0,
|
||||
ver_minor = 0,
|
||||
ver_patch = 0;
|
||||
|
||||
Gestalt (gestaltSystemVersionMajor, &ver_major);
|
||||
Gestalt (gestaltSystemVersionMinor, &ver_minor);
|
||||
Gestalt (gestaltSystemVersionBugFix, &ver_patch);
|
||||
|
||||
return g_strdup_printf ("OS X %d.%d.%d", ver_major, ver_minor, ver_patch);
|
||||
#else
|
||||
NSProcessInfo *info = [NSProcessInfo processInfo];
|
||||
NSOperatingSystemVersion version = [info operatingSystemVersion];
|
||||
|
||||
return g_strdup_printf ("OS X %ld.%ld.%ld", version.majorVersion, version.minorVersion, version.patchVersion);
|
||||
#endif
|
||||
}
|
||||
char *
|
||||
sysinfo_backend_get_os(void)
|
||||
|
@@ -60,7 +60,7 @@ char *sysinfo_backend_get_memory(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (xs_parse_meminfo (&swap_total, &swap_free, 1) != 1 && swap_total != 0)
|
||||
if (xs_parse_meminfo (&swap_total, &swap_free, 1) != 1)
|
||||
{
|
||||
swap_fmt = sysinfo_format_memory (swap_total, swap_free);
|
||||
}
|
||||
|
@@ -40,37 +40,32 @@ int xs_parse_cpu(char *model, char *vendor, double *freq)
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || defined(__alpha__) || defined(__ia64__) || defined(__parisc__) || defined(__sparc__)
|
||||
char buffer[bsize];
|
||||
#endif
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen("/proc/cpuinfo", "r");
|
||||
#if defined(__powerpc__)
|
||||
char *pos = NULL;
|
||||
#endif
|
||||
FILE *fp = fopen("/proc/cpuinfo", "r");
|
||||
if(fp == NULL)
|
||||
return 1;
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
while(fgets(buffer, bsize, fp) != NULL)
|
||||
{
|
||||
find_match_char(buffer, "model name", model);
|
||||
find_match_char(buffer, "vendor_id", vendor);
|
||||
find_match_double(buffer, "cpu MHz", freq);
|
||||
}
|
||||
|
||||
#elif defined(__powerpc__)
|
||||
#endif
|
||||
#ifdef __powerpc__
|
||||
while(fgets(buffer, bsize, fp) != NULL)
|
||||
{
|
||||
char *pos;
|
||||
|
||||
while(fgets(buffer, bsize, fp) != NULL)
|
||||
{
|
||||
find_match_char(buffer, "cpu", model);
|
||||
find_match_char(buffer, "machine", vendor);
|
||||
find_match_double(buffer, "clock", freq);
|
||||
}
|
||||
pos = strstr(model, ",");
|
||||
if (pos != NULL)
|
||||
*pos = '\0';
|
||||
find_match_char(buffer, "cpu", model);
|
||||
find_match_char(buffer, "machine", vendor);
|
||||
find_match_double(buffer, "clock", freq);
|
||||
}
|
||||
#elif defined( __alpha__)
|
||||
|
||||
pos = strstr(model, ",");
|
||||
if (pos != NULL) *pos = '\0';
|
||||
#endif
|
||||
#ifdef __alpha__
|
||||
while(fgets(buffer, bsize, fp) != NULL)
|
||||
{
|
||||
find_match_char(buffer, "cpu model", model);
|
||||
@@ -78,47 +73,37 @@ int xs_parse_cpu(char *model, char *vendor, double *freq)
|
||||
find_match_double(buffer, "cycle frequency [Hz]", freq);
|
||||
}
|
||||
*freq = *freq / 1000000;
|
||||
|
||||
#elif defined(__ia64__)
|
||||
|
||||
#endif
|
||||
#ifdef __ia64__
|
||||
while(fgets(buffer, bsize, fp) != NULL)
|
||||
{
|
||||
find_match_char(buffer, "model", model);
|
||||
find_match_char(buffer, "vendor", vendor);
|
||||
find_match_double(buffer, "cpu MHz", freq);
|
||||
}
|
||||
|
||||
#elif defined(__parisc__)
|
||||
|
||||
#endif
|
||||
#ifdef __parisc__
|
||||
while(fgets(buffer, bsize, fp) != NULL)
|
||||
{
|
||||
find_match_char(buffer, "cpu ", model);
|
||||
find_match_char(buffer, "cpu family", vendor);
|
||||
find_match_double(buffer, "cpu MHz", freq);
|
||||
}
|
||||
|
||||
#elif defined(__sparc__)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
FILE *fp2;
|
||||
|
||||
while(fgets(buffer, bsize, fp) != NULL)
|
||||
{
|
||||
find_match_char(buffer, "cpu ", model);
|
||||
find_match_char(buffer, "type ", vendor);
|
||||
find_match_double_hex(buffer, "Cpu0ClkTck", freq);
|
||||
}
|
||||
*freq = *freq / 1000000;
|
||||
}
|
||||
#else
|
||||
|
||||
fclose(fp);
|
||||
return 1; /* Unsupported */
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#ifdef __sparc__
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
FILE *fp2;
|
||||
while(fgets(buffer, bsize, fp) != NULL)
|
||||
{
|
||||
find_match_char(buffer, "cpu ", model);
|
||||
find_match_char(buffer, "type ", vendor);
|
||||
find_match_double_hex(buffer, "Cpu0ClkTck", freq);
|
||||
}
|
||||
*freq = *freq / 1000000;
|
||||
#endif
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1 +0,0 @@
|
||||
data/misc/hexchat.desktop.in.in
|
3009
po/en_GB.po
3009
po/en_GB.po
File diff suppressed because it is too large
Load Diff
3606
po/ja_JP.po
3606
po/ja_JP.po
File diff suppressed because it is too large
Load Diff
6022
po/pt_BR.po
6022
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
2983
po/sr@latin.po
2983
po/sr@latin.po
File diff suppressed because it is too large
Load Diff
3057
po/zh_CN.po
3057
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
2977
po/zh_TW.po
2977
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
@@ -77,7 +77,7 @@ list_addentry (GSList ** list, char *cmd, char *name)
|
||||
/* read it in from a buffer to our linked list */
|
||||
|
||||
static void
|
||||
list_load_from_data (GSList ** list, char *ibuf, int size)
|
||||
list_load_from_data (GSList ** list, char *ibuf, gsize size)
|
||||
{
|
||||
char cmd[384];
|
||||
char name[128];
|
||||
@@ -110,36 +110,28 @@ list_load_from_data (GSList ** list, char *ibuf, int size)
|
||||
}
|
||||
|
||||
void
|
||||
list_loadconf (char *file, GSList ** list, char *defaultconf)
|
||||
list_loadconf (char *filename, GSList ** list, char *defaultconf)
|
||||
{
|
||||
char *filebuf;
|
||||
char *ibuf;
|
||||
int fd;
|
||||
struct stat st;
|
||||
GFile *file;
|
||||
char *data;
|
||||
gsize len;
|
||||
|
||||
filebuf = g_build_filename (get_xdir (), file, NULL);
|
||||
fd = g_open (filebuf, O_RDONLY | OFLAGS, 0);
|
||||
g_free (filebuf);
|
||||
file = hexchat_open_gfile (filename);
|
||||
|
||||
if (fd == -1)
|
||||
if (!g_file_query_exists (file, NULL))
|
||||
{
|
||||
if (defaultconf)
|
||||
list_load_from_data (list, defaultconf, strlen (defaultconf));
|
||||
return;
|
||||
}
|
||||
if (fstat (fd, &st) != 0)
|
||||
|
||||
if (g_file_load_contents (file, NULL, &data, &len, NULL, NULL))
|
||||
{
|
||||
perror ("fstat");
|
||||
abort ();
|
||||
list_load_from_data (list, data, len);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
ibuf = g_malloc (st.st_size);
|
||||
read (fd, ibuf, st.st_size);
|
||||
close (fd);
|
||||
|
||||
list_load_from_data (list, ibuf, st.st_size);
|
||||
|
||||
g_free (ibuf);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -214,40 +206,25 @@ cfg_get_str (char *cfg, const char *var, char *dest, int dest_len)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
cfg_put_str (int fh, char *var, char *value)
|
||||
int
|
||||
cfg_put_str (GOutputStream *ostream, const char *var, const char *value)
|
||||
{
|
||||
char buf[512];
|
||||
int len;
|
||||
|
||||
g_snprintf (buf, sizeof buf, "%s = %s\n", var, value);
|
||||
len = strlen (buf);
|
||||
return (write (fh, buf, len) == len);
|
||||
return (stream_writef (ostream, "%s = %s\n", var, value) != 0);
|
||||
}
|
||||
|
||||
int
|
||||
cfg_put_color (int fh, guint16 r, guint16 g, guint16 b, char *var)
|
||||
cfg_put_color (GOutputStream *ostream, guint16 r, guint16 g, guint16 b, char *var)
|
||||
{
|
||||
char buf[400];
|
||||
int len;
|
||||
|
||||
g_snprintf (buf, sizeof buf, "%s = %04hx %04hx %04hx\n", var, r, g, b);
|
||||
len = strlen (buf);
|
||||
return (write (fh, buf, len) == len);
|
||||
return (stream_writef (ostream, "%s = %04x %04x %04x\n", var, r, g, b) != 0);
|
||||
}
|
||||
|
||||
int
|
||||
cfg_put_int (int fh, int value, char *var)
|
||||
cfg_put_int (GOutputStream *ostream, int value, char *var)
|
||||
{
|
||||
char buf[400];
|
||||
int len;
|
||||
|
||||
if (value == -1)
|
||||
value = 1;
|
||||
|
||||
g_snprintf (buf, sizeof buf, "%s = %d\n", var, value);
|
||||
len = strlen (buf);
|
||||
return (write (fh, buf, len) == len);
|
||||
return (stream_writef (ostream, "%s = %d\n", var, value) != 0);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -338,18 +315,6 @@ check_config_dir (void)
|
||||
return g_access (get_xdir (), F_OK);
|
||||
}
|
||||
|
||||
static char *
|
||||
default_file (void)
|
||||
{
|
||||
static char *dfile = NULL;
|
||||
|
||||
if (!dfile)
|
||||
{
|
||||
dfile = g_build_filename (get_xdir (), "hexchat.conf", NULL);
|
||||
}
|
||||
return dfile;
|
||||
}
|
||||
|
||||
/* Keep these sorted!! */
|
||||
|
||||
const struct prefs vars[] =
|
||||
@@ -459,6 +424,7 @@ const struct prefs vars[] =
|
||||
{"gui_ulist_hide", P_OFFINT (hex_gui_ulist_hide), TYPE_BOOL},
|
||||
{"gui_ulist_icons", P_OFFINT (hex_gui_ulist_icons), TYPE_BOOL},
|
||||
{"gui_ulist_pos", P_OFFINT (hex_gui_ulist_pos), TYPE_INT},
|
||||
{"gui_ulist_resizable", P_OFFINT (hex_gui_ulist_resizable), TYPE_BOOL},
|
||||
{"gui_ulist_show_hosts", P_OFFINT(hex_gui_ulist_show_hosts), TYPE_BOOL},
|
||||
{"gui_ulist_sort", P_OFFINT (hex_gui_ulist_sort), TYPE_INT},
|
||||
{"gui_ulist_style", P_OFFINT (hex_gui_ulist_style), TYPE_BOOL},
|
||||
@@ -531,7 +497,7 @@ const struct prefs vars[] =
|
||||
{"net_auto_reconnectonfail", P_OFFINT (hex_net_auto_reconnectonfail), TYPE_BOOL},
|
||||
#endif
|
||||
{"net_bind_host", P_OFFSET (hex_net_bind_host), TYPE_STR},
|
||||
{"net_ping_timeout", P_OFFINT (hex_net_ping_timeout), TYPE_INT, hexchat_reinit_timers},
|
||||
{"net_ping_timeout", P_OFFINT (hex_net_ping_timeout), TYPE_INT},
|
||||
{"net_proxy_auth", P_OFFINT (hex_net_proxy_auth), TYPE_BOOL},
|
||||
{"net_proxy_host", P_OFFSET (hex_net_proxy_host), TYPE_STR},
|
||||
{"net_proxy_pass", P_OFFSET (hex_net_proxy_pass), TYPE_STR},
|
||||
@@ -770,6 +736,7 @@ load_default_config(void)
|
||||
prefs.hex_gui_tray_blink = 1;
|
||||
prefs.hex_gui_ulist_count = 1;
|
||||
prefs.hex_gui_ulist_icons = 1;
|
||||
prefs.hex_gui_ulist_resizable = 1;
|
||||
prefs.hex_gui_ulist_style = 1;
|
||||
prefs.hex_gui_win_save = 1;
|
||||
prefs.hex_input_flash_hilight = 1;
|
||||
@@ -829,7 +796,6 @@ load_default_config(void)
|
||||
prefs.hex_gui_win_width = 640;
|
||||
prefs.hex_irc_ban_type = 1;
|
||||
prefs.hex_irc_join_delay = 5;
|
||||
prefs.hex_net_ping_timeout = 60;
|
||||
prefs.hex_net_reconnect_delay = 10;
|
||||
prefs.hex_notify_timeout = 15;
|
||||
prefs.hex_text_max_indent = 256;
|
||||
@@ -952,13 +918,21 @@ make_dcc_dirs (void)
|
||||
int
|
||||
load_config (void)
|
||||
{
|
||||
GFile *file;
|
||||
char *cfg, *sp;
|
||||
int res, val, i;
|
||||
|
||||
g_assert(check_config_dir () == 0);
|
||||
|
||||
file = hexchat_open_gfile ("hexchat.conf");
|
||||
|
||||
if (!g_file_get_contents (default_file (), &cfg, NULL, NULL))
|
||||
if (!g_file_load_contents (file, NULL, &cfg, NULL, NULL, NULL))
|
||||
{
|
||||
g_object_unref (file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
g_object_unref (file);
|
||||
|
||||
/* If the config is incomplete we have the default values loaded */
|
||||
load_default_config();
|
||||
@@ -1000,26 +974,26 @@ load_config (void)
|
||||
int
|
||||
save_config (void)
|
||||
{
|
||||
int fh, i;
|
||||
char *config, *new_config;
|
||||
GFile *file, *tmpfile;
|
||||
GOutputStream *ostream;
|
||||
GFileIOStream *tmpstream;
|
||||
gboolean ret;
|
||||
int i;
|
||||
|
||||
if (check_config_dir () != 0)
|
||||
make_config_dirs ();
|
||||
|
||||
config = default_file ();
|
||||
new_config = g_strconcat (config, ".new", NULL);
|
||||
|
||||
fh = g_open (new_config, OFLAGS | O_TRUNC | O_WRONLY | O_CREAT, 0600);
|
||||
if (fh == -1)
|
||||
tmpfile = g_file_new_tmp (NULL, &tmpstream, NULL);
|
||||
if (!tmpfile)
|
||||
{
|
||||
g_free (new_config);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ostream = g_io_stream_get_output_stream (G_IO_STREAM(tmpstream));
|
||||
|
||||
if (!cfg_put_str (fh, "version", PACKAGE_VERSION))
|
||||
if (!cfg_put_str (ostream, "version", PACKAGE_VERSION))
|
||||
{
|
||||
close (fh);
|
||||
g_free (new_config);
|
||||
g_object_unref (tmpfile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1029,48 +1003,33 @@ save_config (void)
|
||||
switch (vars[i].type)
|
||||
{
|
||||
case TYPE_STR:
|
||||
if (!cfg_put_str (fh, vars[i].name, (char *) &prefs + vars[i].offset))
|
||||
if (!cfg_put_str (ostream, vars[i].name, (char *) &prefs + vars[i].offset))
|
||||
{
|
||||
close (fh);
|
||||
g_free (new_config);
|
||||
g_object_unref (tmpfile);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case TYPE_INT:
|
||||
case TYPE_BOOL:
|
||||
if (!cfg_put_int (fh, *((int *) &prefs + vars[i].offset), vars[i].name))
|
||||
if (!cfg_put_int (ostream, *((int *) &prefs + vars[i].offset), vars[i].name))
|
||||
{
|
||||
close (fh);
|
||||
g_free (new_config);
|
||||
g_object_unref (tmpfile);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (vars[i].after_update != NULL)
|
||||
{
|
||||
vars[i].after_update();
|
||||
}
|
||||
i++;
|
||||
}
|
||||
while (vars[i].name);
|
||||
|
||||
if (close (fh) == -1)
|
||||
{
|
||||
g_free (new_config);
|
||||
return 0;
|
||||
}
|
||||
g_object_unref (ostream);
|
||||
|
||||
#ifdef WIN32
|
||||
g_unlink (config); /* win32 can't rename to an existing file */
|
||||
#endif
|
||||
if (g_rename (new_config, config) == -1)
|
||||
{
|
||||
g_free (new_config);
|
||||
return 0;
|
||||
}
|
||||
g_free (new_config);
|
||||
file = hexchat_open_gfile ("hexchat.conf");
|
||||
ret = g_file_move (tmpfile, file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, NULL);
|
||||
|
||||
return 1;
|
||||
g_object_unref (tmpfile);
|
||||
g_object_unref (file);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1297,11 +1256,6 @@ cmd_set (struct session *sess, char *tbuf, char *word[], char *word_eol[])
|
||||
{
|
||||
set_showval (sess, &vars[i], tbuf);
|
||||
}
|
||||
|
||||
if (vars[i].after_update != NULL)
|
||||
{
|
||||
vars[i].after_update();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1366,3 +1320,69 @@ hexchat_fopen_file (const char *file, const char *mode, int xof_flags)
|
||||
|
||||
return fh;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a #GFile* to a file in HexChat's config dir.
|
||||
* Must be g_object_unref()'d when done.
|
||||
* @filename must be in utf8 encoding.
|
||||
*/
|
||||
GFile *
|
||||
hexchat_open_gfile (const char *filename)
|
||||
{
|
||||
GFile *file;
|
||||
gchar *full_path, *full_path_fs;
|
||||
|
||||
if (g_path_is_absolute (filename))
|
||||
full_path = g_strdup (filename);
|
||||
else
|
||||
full_path = g_build_filename (get_xdir(), filename, NULL);
|
||||
full_path_fs = g_filename_from_utf8 (full_path, -1, NULL, NULL, NULL);
|
||||
|
||||
file = g_file_new_for_path (full_path_fs);
|
||||
|
||||
g_free (full_path);
|
||||
g_free (full_path_fs);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
G_GNUC_PRINTF (2, 3)
|
||||
gsize
|
||||
stream_writef (GOutputStream *ostream, const char *fmt, ...)
|
||||
{
|
||||
char *tmp;
|
||||
va_list args;
|
||||
gint len;
|
||||
gsize ret;
|
||||
|
||||
va_start (args, fmt);
|
||||
len = g_vasprintf (&tmp, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
ret = g_output_stream_write (ostream, tmp, len, NULL, NULL);
|
||||
g_free (tmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GDataInputStream *
|
||||
file_get_datainputstream (GFile *file)
|
||||
{
|
||||
GInputStream *stream;
|
||||
GDataInputStream *datastream;
|
||||
|
||||
stream = G_INPUT_STREAM(g_file_read (file, NULL, NULL));
|
||||
if (!stream)
|
||||
return NULL;
|
||||
|
||||
datastream = g_data_input_stream_new (stream);
|
||||
/*
|
||||
* This is to avoid any issues moving between windows/unix
|
||||
* but the docs mention an invalid \r without a following \n
|
||||
* can lock up the program
|
||||
*/
|
||||
g_data_input_stream_set_newline_type (datastream, G_DATA_STREAM_NEWLINE_TYPE_ANY);
|
||||
g_object_unref (stream);
|
||||
|
||||
return datastream;
|
||||
}
|
||||
|
@@ -30,12 +30,13 @@ extern char *xdir;
|
||||
extern const char * const languages[LANGUAGES_LENGTH];
|
||||
|
||||
char *cfg_get_str (char *cfg, const char *var, char *dest, int dest_len);
|
||||
int cfg_put_str (GOutputStream *ostream, const char *var, const char *value);
|
||||
int cfg_get_bool (char *var);
|
||||
int cfg_get_int_with_result (char *cfg, char *var, int *result);
|
||||
int cfg_get_int (char *cfg, char *var);
|
||||
int cfg_put_int (int fh, int value, char *var);
|
||||
int cfg_put_int (GOutputStream *ostream, int value, char *var);
|
||||
int cfg_get_color (char *cfg, char *var, guint16 *r, guint16 *g, guint16 *b);
|
||||
int cfg_put_color (int fh, guint16 r, guint16 g, guint16 b, char *var);
|
||||
int cfg_put_color (GOutputStream *ostream, guint16 r, guint16 g, guint16 b, char *var);
|
||||
char *get_xdir (void);
|
||||
int check_config_dir (void);
|
||||
void load_default_config (void);
|
||||
@@ -44,12 +45,15 @@ int make_dcc_dirs (void);
|
||||
int load_config (void);
|
||||
int save_config (void);
|
||||
void list_free (GSList ** list);
|
||||
void list_loadconf (char *file, GSList ** list, char *defaultconf);
|
||||
void list_loadconf (char *filename, GSList ** list, char *defaultconf);
|
||||
int list_delentry (GSList ** list, char *name);
|
||||
void list_addentry (GSList ** list, char *cmd, char *name);
|
||||
int cmd_set (session *sess, char *tbuf, char *word[], char *word_eol[]);
|
||||
int hexchat_open_file (const char *file, int flags, int mode, int xof_flags);
|
||||
FILE *hexchat_fopen_file (const char *file, const char *mode, int xof_flags);
|
||||
GFile *hexchat_open_gfile (const char *filename);
|
||||
gsize stream_writef (GOutputStream *ostream, const char *fmt, ...) G_GNUC_PRINTF (2, 3);
|
||||
GDataInputStream *file_get_datainputstream (GFile *file);
|
||||
|
||||
#define XOF_DOMODE 1
|
||||
#define XOF_FULLPATH 2
|
||||
@@ -71,11 +75,6 @@ struct prefs
|
||||
unsigned short offset;
|
||||
unsigned short len;
|
||||
unsigned short type;
|
||||
/*
|
||||
* an optional function which will be called after the preference value has
|
||||
* been updated.
|
||||
*/
|
||||
void (*after_update)(void);
|
||||
};
|
||||
|
||||
#define TYPE_STR 0
|
||||
|
@@ -76,28 +76,14 @@ chanopt_value (guint8 val)
|
||||
switch (val)
|
||||
{
|
||||
case SET_OFF:
|
||||
return _("OFF");
|
||||
return "OFF";
|
||||
case SET_ON:
|
||||
return _("ON");
|
||||
case SET_DEFAULT:
|
||||
return _("{unset}");
|
||||
return "ON";
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
return "{unset}";
|
||||
}
|
||||
}
|
||||
|
||||
static guint8
|
||||
str_to_chanopt (const char *str)
|
||||
{
|
||||
if (!g_ascii_strcasecmp (str, "ON") || !strcmp (str, "1"))
|
||||
return SET_ON;
|
||||
else if (!g_ascii_strcasecmp (str, "OFF") || !strcmp (str, "0"))
|
||||
return SET_OFF;
|
||||
else
|
||||
return SET_DEFAULT;
|
||||
}
|
||||
|
||||
/* handle the /CHANOPT command */
|
||||
|
||||
int
|
||||
@@ -120,14 +106,19 @@ chanopt_command (session *sess, char *tbuf, char *word[], char *word_eol[])
|
||||
|
||||
if (word[offset][0])
|
||||
{
|
||||
newval = str_to_chanopt (word[offset]);
|
||||
if (!g_ascii_strcasecmp (word[offset], "ON"))
|
||||
newval = 1;
|
||||
else if (!g_ascii_strcasecmp (word[offset], "OFF"))
|
||||
newval = 0;
|
||||
else if (word[offset][0] == 'u')
|
||||
newval = SET_DEFAULT;
|
||||
else
|
||||
newval = atoi (word[offset]);
|
||||
}
|
||||
|
||||
if (!quiet)
|
||||
PrintTextf (sess, "\002%s\002: %s \002%s\002: %s\n",
|
||||
_("Network"),
|
||||
PrintTextf (sess, "\002Network\002: %s \002Channel\002: %s\n",
|
||||
sess->server->network ? server_get_network (sess->server, TRUE) : _("<none>"),
|
||||
_("Channel"),
|
||||
sess->session_name[0] ? sess->session_name : _("<none>"));
|
||||
|
||||
while (i < sizeof (chanopt) / sizeof (channel_options))
|
||||
@@ -290,7 +281,7 @@ chanopt_load_all (void)
|
||||
else
|
||||
{
|
||||
if (current)
|
||||
chanopt_add_opt (current, buf, str_to_chanopt (eq + 2));
|
||||
chanopt_add_opt (current, buf, atoi (eq + 2));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -397,7 +388,7 @@ chanopt_save_one_channel (chanopt_in_memory *co, int fh)
|
||||
}
|
||||
|
||||
void
|
||||
chanopt_save_all (gboolean flush)
|
||||
chanopt_save_all (void)
|
||||
{
|
||||
int i;
|
||||
int num_saved;
|
||||
@@ -439,21 +430,15 @@ chanopt_save_all (gboolean flush)
|
||||
}
|
||||
|
||||
cont:
|
||||
if (flush)
|
||||
{
|
||||
g_free (co->network);
|
||||
g_free (co->channel);
|
||||
g_free (co);
|
||||
}
|
||||
g_free (co->network);
|
||||
g_free (co->channel);
|
||||
g_free (co);
|
||||
}
|
||||
|
||||
close (fh);
|
||||
|
||||
if (flush)
|
||||
{
|
||||
g_slist_free (chanopt_list);
|
||||
chanopt_list = NULL;
|
||||
}
|
||||
g_slist_free (chanopt_list);
|
||||
chanopt_list = NULL;
|
||||
|
||||
chanopt_open = FALSE;
|
||||
chanopt_changed = FALSE;
|
||||
|
@@ -22,7 +22,7 @@
|
||||
|
||||
int chanopt_command (session *sess, char *tbuf, char *word[], char *word_eol[]);
|
||||
gboolean chanopt_is_set (unsigned int global, guint8 per_chan_setting);
|
||||
void chanopt_save_all (gboolean flush);
|
||||
void chanopt_save_all (void);
|
||||
void chanopt_save (session *sess);
|
||||
void chanopt_load (session *sess);
|
||||
|
||||
|
@@ -15,7 +15,7 @@ BUILT_SOURCES = \
|
||||
|
||||
CLEANFILES = $(BUILT_SOURCES)
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src/common $(COMMON_CFLAGS) $(DBUS_CFLAGS)
|
||||
AM_CPPFLAGS = $(COMMON_CFLAGS) $(DBUS_CFLAGS) -I$(top_srcdir)/src/common
|
||||
|
||||
noinst_PROGRAMS = example
|
||||
example_SOURCES = example.c
|
||||
|
@@ -21,22 +21,19 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#define GLIB_DISABLE_DEPRECATION_WARNINGS
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include "dbus-client.h"
|
||||
#include <stdlib.h>
|
||||
#include <gio/gio.h>
|
||||
#include "hexchat.h"
|
||||
#include "hexchatc.h"
|
||||
|
||||
#define DBUS_SERVICE "org.hexchat.service"
|
||||
#define DBUS_REMOTE_PATH "/org/hexchat/Remote"
|
||||
#define DBUS_REMOTE "/org/hexchat/Remote"
|
||||
#define DBUS_REMOTE_INTERFACE "org.hexchat.plugin"
|
||||
|
||||
#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
|
||||
#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
|
||||
#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
|
||||
|
||||
static void
|
||||
write_error (char *message, GError **error)
|
||||
write_error (char *message,
|
||||
GError **error)
|
||||
{
|
||||
if (error == NULL || *error == NULL) {
|
||||
return;
|
||||
@@ -45,15 +42,6 @@ write_error (char *message, GError **error)
|
||||
g_clear_error (error);
|
||||
}
|
||||
|
||||
static inline GVariant *
|
||||
new_param_variant (const char *arg)
|
||||
{
|
||||
GVariant * const args[1] = {
|
||||
g_variant_new_string (arg)
|
||||
};
|
||||
return g_variant_new_tuple (args, 1);
|
||||
}
|
||||
|
||||
void
|
||||
hexchat_remote (void)
|
||||
/* TODO: dbus_g_connection_unref (connection) are commented because it makes
|
||||
@@ -61,15 +49,21 @@ hexchat_remote (void)
|
||||
* https://launchpad.net/distros/ubuntu/+source/dbus/+bug/54375
|
||||
*/
|
||||
{
|
||||
GDBusConnection *connection;
|
||||
GDBusProxy *dbus = NULL;
|
||||
GVariant *ret;
|
||||
GDBusProxy *remote_object = NULL;
|
||||
DBusGConnection *connection;
|
||||
DBusGProxy *dbus = NULL;
|
||||
DBusGProxy *remote_object = NULL;
|
||||
gboolean hexchat_running;
|
||||
GError *error = NULL;
|
||||
char *command = NULL;
|
||||
int i;
|
||||
|
||||
/* GnomeVFS >=2.15 uses D-Bus and threads, so threads should be
|
||||
* initialised before opening for the first time a D-Bus connection */
|
||||
if (!g_thread_supported ()) {
|
||||
g_thread_init (NULL);
|
||||
}
|
||||
dbus_g_thread_init ();
|
||||
|
||||
/* if there is nothing to do, return now. */
|
||||
if (!arg_existing || !(arg_url || arg_urls || arg_command)) {
|
||||
return;
|
||||
@@ -77,63 +71,36 @@ hexchat_remote (void)
|
||||
|
||||
arg_dont_autoconnect = TRUE;
|
||||
|
||||
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
|
||||
if (!connection)
|
||||
{
|
||||
connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
|
||||
if (!connection) {
|
||||
write_error (_("Couldn't connect to session bus"), &error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Checks if HexChat is already running */
|
||||
dbus = g_dbus_proxy_new_sync (connection,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
NULL,
|
||||
DBUS_SERVICE_DBUS,
|
||||
DBUS_PATH_DBUS,
|
||||
DBUS_INTERFACE_DBUS,
|
||||
NULL,
|
||||
&error);
|
||||
|
||||
ret = g_dbus_proxy_call_sync (dbus, "NameHasOwner",
|
||||
new_param_variant (DBUS_SERVICE),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
&error);
|
||||
if (!ret)
|
||||
{
|
||||
dbus = dbus_g_proxy_new_for_name (connection,
|
||||
DBUS_SERVICE_DBUS,
|
||||
DBUS_PATH_DBUS,
|
||||
DBUS_INTERFACE_DBUS);
|
||||
if (!dbus_g_proxy_call (dbus, "NameHasOwner", &error,
|
||||
G_TYPE_STRING, DBUS_SERVICE,
|
||||
G_TYPE_INVALID,
|
||||
G_TYPE_BOOLEAN, &hexchat_running,
|
||||
G_TYPE_INVALID)) {
|
||||
write_error (_("Failed to complete NameHasOwner"), &error);
|
||||
hexchat_running = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
GVariant *child = g_variant_get_child_value (ret, 0);
|
||||
hexchat_running = g_variant_get_boolean (child);
|
||||
g_variant_unref (ret);
|
||||
g_variant_unref (child);
|
||||
}
|
||||
g_object_unref (dbus);
|
||||
|
||||
if (!hexchat_running) {
|
||||
g_object_unref (connection);
|
||||
/* dbus_g_connection_unref (connection); */
|
||||
return;
|
||||
}
|
||||
|
||||
remote_object = g_dbus_proxy_new_sync (connection,
|
||||
G_DBUS_PROXY_FLAGS_NONE,
|
||||
NULL,
|
||||
DBUS_SERVICE,
|
||||
DBUS_REMOTE_PATH,
|
||||
DBUS_REMOTE_INTERFACE,
|
||||
NULL,
|
||||
&error);
|
||||
|
||||
if (!remote_object)
|
||||
{
|
||||
write_error("Failed to connect to HexChat", &error);
|
||||
g_object_unref (connection);
|
||||
exit (0);
|
||||
}
|
||||
remote_object = dbus_g_proxy_new_for_name (connection,
|
||||
DBUS_SERVICE,
|
||||
DBUS_REMOTE,
|
||||
DBUS_REMOTE_INTERFACE);
|
||||
|
||||
if (arg_url) {
|
||||
command = g_strdup_printf ("url %s", arg_url);
|
||||
@@ -141,40 +108,31 @@ hexchat_remote (void)
|
||||
command = g_strdup (arg_command);
|
||||
}
|
||||
|
||||
if (command)
|
||||
{
|
||||
g_dbus_proxy_call_sync (remote_object, "Command",
|
||||
new_param_variant (command),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
&error);
|
||||
|
||||
if (error)
|
||||
if (command) {
|
||||
if (!dbus_g_proxy_call (remote_object, "Command",
|
||||
&error,
|
||||
G_TYPE_STRING, command,
|
||||
G_TYPE_INVALID,G_TYPE_INVALID)) {
|
||||
write_error (_("Failed to complete Command"), &error);
|
||||
}
|
||||
g_free (command);
|
||||
}
|
||||
|
||||
|
||||
if (arg_urls)
|
||||
{
|
||||
for (i = 0; i < g_strv_length(arg_urls); i++)
|
||||
{
|
||||
command = g_strdup_printf ("url %s", arg_urls[i]);
|
||||
|
||||
g_dbus_proxy_call_sync (remote_object, "Command",
|
||||
new_param_variant (command),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
NULL,
|
||||
&error);
|
||||
if (error)
|
||||
if (!dbus_g_proxy_call (remote_object, "Command",
|
||||
&error,
|
||||
G_TYPE_STRING, command,
|
||||
G_TYPE_INVALID, G_TYPE_INVALID)) {
|
||||
write_error (_("Failed to complete Command"), &error);
|
||||
}
|
||||
g_free (command);
|
||||
}
|
||||
g_strfreev (arg_urls);
|
||||
}
|
||||
}
|
||||
|
||||
g_object_unref (remote_object);
|
||||
g_object_unref (connection);
|
||||
exit (0);
|
||||
}
|
||||
|
51
src/common/dbus/example-gdbus.py
Normal file
51
src/common/dbus/example-gdbus.py
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
# HexChat
|
||||
# Copyright (C) 1998-2010 Peter Zelezny.
|
||||
# Copyright (C) 2009-2013 Berke Viktor.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
#
|
||||
|
||||
from gi.repository import Gio
|
||||
|
||||
bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
|
||||
connection = Gio.DBusProxy.new_sync(bus, Gio.DBusProxyFlags.NONE, None,
|
||||
'org.hexchat.service', '/org/hexchat/Remote', 'org.hexchat.connection', None)
|
||||
path = connection.Connect('(ssss)',
|
||||
'example.py',
|
||||
'Python example',
|
||||
'Example of a D-Bus client written in python',
|
||||
'1.0')
|
||||
hexchat = Gio.DBusProxy.new_sync(bus, Gio.DBusProxyFlags.NONE, None,
|
||||
'org.hexchat.service', path, 'org.hexchat.plugin', None)
|
||||
|
||||
# Note the type before every arguement, this must be done.
|
||||
# Type requirements are listed in our docs and characters are listed in the dbus docs.
|
||||
# s = string, u = uint, i = int, etc.
|
||||
|
||||
channels = hexchat.ListGet ('(s)', "channels")
|
||||
while hexchat.ListNext ('(u)', channels):
|
||||
name = hexchat.ListStr ('(us)', channels, "channel")
|
||||
print("------- " + name + " -------")
|
||||
hexchat.SetContext ('(u)', hexchat.ListInt ('(us)', channels, "context"))
|
||||
hexchat.EmitPrint ('(sas)', "Channel Message", ["John", "Hi there", "@"])
|
||||
users = hexchat.ListGet ('(s)', "users")
|
||||
while hexchat.ListNext ('(u)', users):
|
||||
print("Nick: " + hexchat.ListStr ('(us)', users, "nick"))
|
||||
hexchat.ListFree ('(u)', users)
|
||||
hexchat.ListFree ('(u)', channels)
|
||||
|
||||
print(hexchat.Strip ('(sii)', "\00312Blue\003 \002Bold!\002", -1, 1|2))
|
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/python
|
||||
#! /usr/bin/python
|
||||
|
||||
# HexChat
|
||||
# Copyright (C) 1998-2010 Peter Zelezny.
|
||||
@@ -19,33 +19,29 @@
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
#
|
||||
|
||||
from gi.repository import Gio
|
||||
import dbus
|
||||
|
||||
bus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
|
||||
connection = Gio.DBusProxy.new_sync(bus, Gio.DBusProxyFlags.NONE, None,
|
||||
'org.hexchat.service', '/org/hexchat/Remote', 'org.hexchat.connection', None)
|
||||
path = connection.Connect('(ssss)',
|
||||
'example.py',
|
||||
'Python example',
|
||||
'Example of a D-Bus client written in python',
|
||||
'1.0')
|
||||
hexchat = Gio.DBusProxy.new_sync(bus, Gio.DBusProxyFlags.NONE, None,
|
||||
'org.hexchat.service', path, 'org.hexchat.plugin', None)
|
||||
|
||||
# Note the type before every arguement, this must be done.
|
||||
# Type requirements are listed in our docs and characters are listed in the dbus docs.
|
||||
# s = string, u = uint, i = int, etc.
|
||||
bus = dbus.SessionBus()
|
||||
proxy = bus.get_object('org.hexchat.service', '/org/hexchat/Remote')
|
||||
remote = dbus.Interface(proxy, 'org.hexchat.connection')
|
||||
path = remote.Connect ("example.py",
|
||||
"Python example",
|
||||
"Example of a D-Bus client written in python",
|
||||
"1.0")
|
||||
proxy = bus.get_object('org.hexchat.service', path)
|
||||
hexchat = dbus.Interface(proxy, 'org.hexchat.plugin')
|
||||
|
||||
channels = hexchat.ListGet ('(s)', "channels")
|
||||
while hexchat.ListNext ('(u)', channels):
|
||||
name = hexchat.ListStr ('(us)', channels, "channel")
|
||||
channels = hexchat.ListGet ("channels")
|
||||
while hexchat.ListNext (channels):
|
||||
name = hexchat.ListStr (channels, "channel")
|
||||
print("------- " + name + " -------")
|
||||
hexchat.SetContext ('(u)', hexchat.ListInt ('(us)', channels, "context"))
|
||||
hexchat.EmitPrint ('(sas)', "Channel Message", ["John", "Hi there", "@"])
|
||||
users = hexchat.ListGet ('(s)', "users")
|
||||
while hexchat.ListNext ('(u)', users):
|
||||
print("Nick: " + hexchat.ListStr ('(us)', users, "nick"))
|
||||
hexchat.ListFree ('(u)', users)
|
||||
hexchat.ListFree ('(u)', channels)
|
||||
hexchat.SetContext (hexchat.ListInt (channels, "context"))
|
||||
hexchat.EmitPrint ("Channel Message", ["John", "Hi there", "@"])
|
||||
users = hexchat.ListGet ("users")
|
||||
while hexchat.ListNext (users):
|
||||
print("Nick: " + hexchat.ListStr (users, "nick"))
|
||||
hexchat.ListFree (users)
|
||||
hexchat.ListFree (channels)
|
||||
|
||||
print(hexchat.Strip ("\00312Blue\003 \002Bold!\002", -1, 1|2))
|
||||
|
||||
print(hexchat.Strip ('(sii)', "\00312Blue\003 \002Bold!\002", -1, 1|2))
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user