| author | Gerfried Fuchs <rhonda@debian.org> | |
| Tue, 22 Feb 2011 10:01:08 +0000 (11:01 +0100) | ||
| committer | Gerfried Fuchs <rhonda@debian.org> | |
| Tue, 22 Feb 2011 10:01:08 +0000 (11:01 +0100) |
100 files changed:
--- a/AUTHORS
+++ b/AUTHORS
Oleg Nemanov (aka Lego_12239)
Piotr Zielonka (aka entragian)
Michal Vaner (aka vorner)
+ Markus Hennecke
Translators:
FR Mikael Berthe
diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
+mcabber (0.9.7)
+
+ * Pressing enter when a group is selected will toggle the fold status
+ * New option 'ignore_self_presence'
+ * New option 'log_display_presence'
+ * New option 'eventcmd_use_nickname'
+ * New option 'statefile' to keep track of unread messages across restarts
+ * New option to customize the away/notavail priority (Michael Gehring)
+ * New external "UNREAD" event
+ * Add FIFO named command pipe
+ * New switches for /say_to: -q, -f
+ * New command /status message (to only change the status description string)
+ * Let /del remove a MUC entry from the roster
+ * Allow more than the 16 default colors (mjs)
+ * Randomize the default resource
+ * Improve OTR support
+ * Improve Remote Controlling Clients (XEP-0146)
+ * Improve reading of history files
+ * Fix compilation on systems which need -lcharset
+ * Add optional SIGWINCH handler (Markus Hennecke)
+ (improves resize events on OpenBSD)
+ * Fixes from MirBSD (Thorsten Glaser)
+ * Some more fixes and improvements (see detailed changelog)
+
+ -- Mikael, 2008-04-17
+
+mcabber (0.9.6)
+
+ * Improve Cygwin support
+ * Fix compilation on OpenBSD
+ * [UI] New option 'escdelay'
+ * [MUC] New command /room setopt
+ * [MUC] More room settings are stored in the server private storage
+ * [MUC] The command /room ban can be used with a nickname
+ * [MUC] New rooms are automatically unlocked (suggested by M. Weiser)
+ * A few misc. bugfixes
+
+ -- Mikael, 2008-01-13
+
mcabber (0.9.5)
* Implement internal hooks: post-connect, pre-disconnect
--- a/INSTALL
+++ b/INSTALL
If you want PGP support, install libgpgme (with dev package),
version >= 1.0.0.
+You may want to have a look at the wiki:
+ <http://wiki.mcabber.com/>
+and if you're using the development version (from the repository):
+ <http://wiki.mcabber.com/index.php/Building_mcabber_from_Mercurial>
+
Please have a look at the README file before launching mcabber.
Please send me a message (mcabber AT lilotux DOT net) if you have
--- a/README
+++ b/README
XEP-0092 - Software Version
XEP-0115 - Entity Capabilities support
XEP-0145 - Annotations
- XEP-0146 - Remote Controlling Clients
+ XEP-0146 - Remote Controlling Clients (partial)
XEP-0199 - XMPP Ping
XEP-0202 - Entity Time
XEP-0203 - Delayed Delivery
patches if you can!). Or just tell me you're using it... ;-)
There is a Mercurial repository on mcabber's website
- <http://www.lilotux.net/~mikael/mcabber/>
+ <http://mcabber.com/>
and a Jabber conference room: <jid:mcabber@conf.lilotux.net>.
- Mikael <mcabber@lilotux.net>
+ Mikael <mikael@lilotux.net>
--- a/TODO
+++ b/TODO
BUGS:
* SSL certificate verification does not work with gnutls
-* Renaming a MUC room should update the bookmark, not add a roster entry
+* Unicode JIDs are not supported
TODO:
* Improve the completion system
-* Connect hook
-* Macros
* Use new Entity Time specs (XEP-0202) if possible in
/request time.
-* New option to display only username in the roster when the name hasn't been
- set.
-* Remember group state (folded/unfolded) (using private storage for example)
* Enable /roster search for offline (hidden) buddies (hidden groups, etc.)
* Show number of online contacts in folded groups
* Publish personal information
* MUC: advanced settings for room creation
* MUC: display roles of room members
+* MUC: ignore patterns
* "Offline roster" (when disconnected)
* Maybe cache iq:version and show version in /info, if available
* Sort roster by status
* Use DNS _xmpp-client._tcp service
* Mouse support?
* Human-readable key binding config?
+* Possibility to hide log window(?)
+* Copy highlighted messages to the [status] window (or another one)
+* Improve /info, esp. in MUC rooms
+* Update the terminal's title
+ (Can this be done from an event script?)
+* Message filters
+* Data Forms
* File transfer? :)
- /server register|unregister
- /search <jid>|name
(server search)
- - Per room settings?
- /room setopt [+|-]autowhois ?
- /room setopt [+|-]'flag_joins' ?
- - A command (display?) to display only a few states in the roster
- . /roster display of Display avail/ffc people
- . /roster display - Display nobody (but incoming messages)
- . /roster display ofdna == hide_offline
- . /roster display ofdna_ == default behaviour
- (Or roster mask)
+ - /buffer save file
diff --git a/aclocal.m4 b/aclocal.m4
--- a/aclocal.m4
+++ b/aclocal.m4
# Owen Taylor 1997-2001
dnl AM_PATH_GLIB_2_0([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]])
-dnl Test for GLIB, and define GLIB_CFLAGS and GLIB_LIBS, if gmodule, gobject or
-dnl gthread is specified in MODULES, pass to pkg-config
+dnl Test for GLIB, and define GLIB_CFLAGS and GLIB_LIBS, if gmodule, gobject,
+dnl gthread, or gio is specified in MODULES, pass to pkg-config
dnl
AC_DEFUN([AM_PATH_GLIB_2_0],
[dnl
gthread)
pkg_config_args="$pkg_config_args gthread-2.0"
;;
+ gio*)
+ pkg_config_args="$pkg_config_args $module-2.0"
+ ;;
esac
done
- PKG_PROG_PKG_CONFIG([0.7])
+ PKG_PROG_PKG_CONFIG([0.16])
no_glib=""
fi
fi
if test $ok = yes; then
- AC_MSG_RESULT(yes)
+ AC_MSG_RESULT([yes ($libgcrypt_config_version)])
else
AC_MSG_RESULT(no)
fi
if test "$tmp" -gt 0 ; then
AC_MSG_CHECKING([LIBGCRYPT API version])
if test "$req_libgcrypt_api" -eq "$tmp" ; then
- AC_MSG_RESULT(okay)
+ AC_MSG_RESULT([okay])
else
ok=no
- AC_MSG_RESULT([does not match (want=$req_libgcrypt_api got=$tmp)])
+ AC_MSG_RESULT([does not match. want=$req_libgcrypt_api got=$tmp])
fi
fi
fi
diff --git a/config.guess b/config.guess
--- a/config.guess
+++ b/config.guess
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
-timestamp='2007-07-22'
+timestamp='2008-01-23'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
echo rs6000-ibm-aix3.2
fi
exit ;;
- *:AIX:*:[45])
+ *:AIX:*:[456])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
EM64T | authenticamd)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
echo ${UNAME_MACHINE}-pc-minix
exit ;;
arm*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
exit ;;
- xtensa:Linux:*:*)
- echo xtensa-unknown-linux-gnu
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
and
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
diff --git a/config.h.in b/config.h.in
--- a/config.h.in
+++ b/config.h.in
#undef DATA_DIR
/* Devel compilation options */
-#undef DEBUG_ENABLE
+#undef ENABLE_DEBUG
/* Use Mercurial changeset */
#undef ENABLE_HGCSET
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
#undef HAVE_DOPRNT
+/* Define if ncurses has ESCDELAY variable */
+#undef HAVE_ESCDELAY
+
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the `isascii' function. */
#undef HAVE_ISASCII
+/* Define to 1 if you have the `charset' library (-lcharset). */
+#undef HAVE_LIBCHARSET
+
/* Define to 1 if you have the `crypto' library (-lcrypto). */
#undef HAVE_LIBCRYPTO
/* Define to 1 if you have the `ssl' library (-lssl). */
#undef HAVE_LIBSSL
+/* Define to 1 if you have the <localcharset.h> header file. */
+#undef HAVE_LOCALCHARSET_H
+
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
#undef TM_IN_SYS_TIME
+/* Provide own SIGWINCH handler */
+#undef USE_SIGWINCH
+
/* Version number of package */
#undef VERSION
diff --git a/config.sub b/config.sub
--- a/config.sub
+++ b/config.sub
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
-timestamp='2007-06-28'
+timestamp='2008-01-16'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
version="\
GNU config.sub ($timestamp)
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
- | xstormy16-* | xtensa-* \
+ | xstormy16-* | xtensa*-* \
| ymp-* \
| z8k-*)
;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd)
basic_machine=ns32k-sequent
os=-dynix
;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
c90)
basic_machine=c90-cray
os=-unicos
basic_machine=m68k-isi
os=-sysv
;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
m88k-omron*)
basic_machine=m88k-omron
;;
basic_machine=i860-intel
os=-osf
;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
pbd)
basic_machine=sparc-tti
;;
basic_machine=tic6x-unknown
os=-coff
;;
+ tile*)
+ basic_machine=tile-unknown
+ os=-linux-gnu
+ ;;
tx39)
basic_machine=mipstx39-unknown
;;
diff --git a/configure b/configure
--- a/configure
+++ b/configure
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for mcabber 0.9.5.
+# Generated by GNU Autoconf 2.61 for mcabber 0.9.7.
#
# Report bugs to <mcabber@lilotux.net>.
#
# Identity of this package.
PACKAGE_NAME='mcabber'
PACKAGE_TARNAME='mcabber'
-PACKAGE_VERSION='0.9.5'
-PACKAGE_STRING='mcabber 0.9.5'
+PACKAGE_VERSION='0.9.7'
+PACKAGE_STRING='mcabber 0.9.7'
PACKAGE_BUGREPORT='mcabber@lilotux.net'
ac_unique_file="src"
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures mcabber 0.9.5 to adapt to many kinds of systems.
+\`configure' configures mcabber 0.9.7 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of mcabber 0.9.5:";;
+ short | recursive ) echo "Configuration of mcabber 0.9.7:";;
esac
cat <<\_ACEOF
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-dependency-tracking speeds up one-time build
--enable-dependency-tracking do not reject slow dependency extractors
+ --enable-sigwinch compile with SIGWINCH handler
--disable-glibtest do not try to compile and run a test GLIB program
- --disable-gpgme Disable GPGME support
- --enable-otr Enable OTR (Off-the-Record) messaging support
- --enable-aspell Enable aspell support
- --enable-debug Add development compilation options
- --disable-hgcset Do not use Mercurial changeset value
+ --disable-gpgme disable GPGME support
+ --enable-otr enable OTR (Off-the-Record) messaging support
+ --enable-aspell enable aspell support
+ --enable-debug add development compilation options
+ --disable-hgcset do not use Mercurial changeset value
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-mcabber configure 0.9.5
+mcabber configure 0.9.7
generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by mcabber $as_me 0.9.5, which was
+It was created by mcabber $as_me 0.9.7, which was
generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@
# Define the identity of the package.
PACKAGE='mcabber'
- VERSION='0.9.5'
+ VERSION='0.9.7'
cat >>confdefs.h <<_ACEOF
+
for ac_header in arpa/inet.h fcntl.h locale.h netdb.h netinet/in.h stddef.h \
stdlib.h string.h strings.h sys/socket.h sys/time.h \
- syslog.h termios.h unistd.h getopt.h wchar.h wctype.h
+ syslog.h termios.h unistd.h getopt.h wchar.h wctype.h \
+ localcharset.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
fi
+# Check if we must provide a SIGWINCH handler
+# Check whether --enable-sigwinch was given.
+if test "${enable_sigwinch+set}" = set; then
+ enableval=$enable_sigwinch; with_sigwinch=$enableval
+else
+ with_sigwinch=$with_ext_funcs
+fi
+
+{ echo "$as_me:$LINENO: result: $with_sigwinch" >&5
+echo "${ECHO_T}$with_sigwinch" >&6; }
+if test "$with_sigwinch" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_SIGWINCH
+_ACEOF
+
+fi
+
# Checks for libraries.
+
+{ echo "$as_me:$LINENO: checking for locale_charset in -lcharset" >&5
+echo $ECHO_N "checking for locale_charset in -lcharset... $ECHO_C" >&6; }
+if test "${ac_cv_lib_charset_locale_charset+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcharset $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char locale_charset ();
+int
+main ()
+{
+return locale_charset ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ ac_cv_lib_charset_locale_charset=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_lib_charset_locale_charset=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_charset_locale_charset" >&5
+echo "${ECHO_T}$ac_cv_lib_charset_locale_charset" >&6; }
+if test $ac_cv_lib_charset_locale_charset = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBCHARSET 1
+_ACEOF
+
+ LIBS="-lcharset $LIBS"
+
+fi
+
+
{ echo "$as_me:$LINENO: checking for initscr" >&5
echo $ECHO_N "checking for initscr... $ECHO_C" >&6; }
if test "${ac_cv_func_initscr+set}" = set; then
echo "$as_me: WARNING: Your ncurses installation does not support unicode" >&2;}
fi
+{ echo "$as_me:$LINENO: checking for ESCDELAY variable" >&5
+echo $ECHO_N "checking for ESCDELAY variable... $ECHO_C" >&6; }
+if test "${mc_cv_ncurses_escdelay+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ extern int ESCDELAY;
+ ESCDELAY = 0;
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext &&
+ $as_test_x conftest$ac_exeext; then
+ mc_cv_ncurses_escdelay=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ mc_cv_ncurses_escdelay=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext conftest.$ac_ext
+
+fi
+{ echo "$as_me:$LINENO: result: $mc_cv_ncurses_escdelay" >&5
+echo "${ECHO_T}$mc_cv_ncurses_escdelay" >&6; }
+if test "$mc_cv_ncurses_escdelay" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ESCDELAY 1
+_ACEOF
+
+fi
+
# Check for glib
# Check whether --enable-glibtest was given.
if test "${enable_glibtest+set}" = set; then
gthread)
pkg_config_args="$pkg_config_args gthread-2.0"
;;
+ gio*)
+ pkg_config_args="$pkg_config_args $module-2.0"
+ ;;
esac
done
fi
if test -n "$PKG_CONFIG"; then
- _pkg_min_version=0.7
+ _pkg_min_version=0.16
{ echo "$as_me:$LINENO: checking pkg-config is at least version $_pkg_min_version" >&5
echo $ECHO_N "checking pkg-config is at least version $_pkg_min_version... $ECHO_C" >&6; }
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
@@ -9364,8 +9523,8 @@ echo $ECHO_N "checking for LIBGCRYPT - version >= $min_libgcrypt_version... $ECH
fi
fi
if test $ok = yes; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
+ { echo "$as_me:$LINENO: result: yes ($libgcrypt_config_version)" >&5
+echo "${ECHO_T}yes ($libgcrypt_config_version)" >&6; }
else
{ echo "$as_me:$LINENO: result: no" >&5
echo "${ECHO_T}no" >&6; }
echo "${ECHO_T}okay" >&6; }
else
ok=no
- { echo "$as_me:$LINENO: result: does not match (want=$req_libgcrypt_api got=$tmp)" >&5
-echo "${ECHO_T}does not match (want=$req_libgcrypt_api got=$tmp)" >&6; }
+ { echo "$as_me:$LINENO: result: does not match. want=$req_libgcrypt_api got=$tmp" >&5
+echo "${ECHO_T}does not match. want=$req_libgcrypt_api got=$tmp" >&6; }
fi
fi
fi
exec_prefix_NONE=
test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix
test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix
- ac_define_dir=`eval echo $"${datadir}"`
+ ac_define_dir=`eval echo $datadir`
ac_define_dir=`eval echo $ac_define_dir`
DATA_DIR="$ac_define_dir"
if test x"${debug}" = x"yes"; then
cat >>confdefs.h <<_ACEOF
-#define DEBUG_ENABLE 1
+#define ENABLE_DEBUG 1
_ACEOF
if test "x$GCC" = "xyes"; then
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by mcabber $as_me 0.9.5, which was
+This file was extended by mcabber $as_me 0.9.7, which was
generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-mcabber config.status 0.9.5
+mcabber config.status 0.9.7
configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
-AC_INIT([mcabber],[0.9.5],[mcabber@lilotux.net])
+AC_INIT([mcabber],[0.9.7],[mcabber@lilotux.net])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([src])
AM_CONFIG_HEADER(config.h)
AC_HEADER_STDC
AC_CHECK_HEADERS([arpa/inet.h fcntl.h locale.h netdb.h netinet/in.h stddef.h \
stdlib.h string.h strings.h sys/socket.h sys/time.h \
- syslog.h termios.h unistd.h getopt.h wchar.h wctype.h])
+ syslog.h termios.h unistd.h getopt.h wchar.h wctype.h \
+ localcharset.h])
AC_CHECK_HEADERS([getopt.h], , AC_MSG_ERROR([Missing header file]))
AC_VAR_TIMEZONE_EXTERNALS
# Check for tm_gmtoff
MC_TM_GMTOFF
+# Check if we must provide a SIGWINCH handler
+AC_ARG_ENABLE(sigwinch,
+ [ --enable-sigwinch compile with SIGWINCH handler],
+ [with_sigwinch=$enableval],
+ [with_sigwinch=$with_ext_funcs])
+AC_MSG_RESULT($with_sigwinch)
+if test "$with_sigwinch" = yes; then
+ AC_DEFINE(USE_SIGWINCH, [], [Provide own SIGWINCH handler])
+fi
+
# Checks for libraries.
+AC_CHECK_LIB(charset, locale_charset)
+
AC_CHECK_FUNC(initscr,,
[
cf_ncurses="ncurses"
AC_MSG_WARN([Your ncurses installation does not support unicode])
fi
+AC_CACHE_CHECK([for ESCDELAY variable],
+ [mc_cv_ncurses_escdelay],
+ [AC_TRY_LINK([], [
+ extern int ESCDELAY;
+ ESCDELAY = 0;
+ ],
+ [mc_cv_ncurses_escdelay=yes],
+ [mc_cv_ncurses_escdelay=no])
+ ])
+if test "$mc_cv_ncurses_escdelay" = yes; then
+ AC_DEFINE(HAVE_ESCDELAY, 1,
+ [Define if ncurses has ESCDELAY variable])
+fi
+
# Check for glib
AM_PATH_GLIB_2_0(2.0.0, , AC_MSG_ERROR([glib is required]),[g_list_append])
# Check for gpgme
-AC_ARG_ENABLE(gpgme, AC_HELP_STRING([--disable-gpgme], [Disable GPGME support]),
+AC_ARG_ENABLE(gpgme, AC_HELP_STRING([--disable-gpgme], [disable GPGME support]),
[ if test x"$enableval" = x"no"; then
enable_gpgme=no
fi
fi
# Check for otr
-AC_ARG_ENABLE(otr, [ --enable-otr Enable OTR (Off-the-Record) messaging support],
+AC_ARG_ENABLE(otr, [ --enable-otr enable OTR (Off-the-Record) messaging support],
enable_otr=$enableval, otr="")
if test "x$enable_otr" = "xyes"; then
# Look for libgcrypt and libotr
fi
# Check for Aspell stuff
-AC_ARG_ENABLE(aspell, [ --enable-aspell Enable aspell support],
+AC_ARG_ENABLE(aspell, [ --enable-aspell enable aspell support],
enable_aspell=$enableval, aspell="")
if test "x$enable_aspell" = "xyes"; then
AC_CHECK_HEADERS(aspell.h, [ have_aspell_includes=yes ])
# Export $datadir to the source tree.
if test x"${datadir}" != x""; then
- AC_DEFINE_DIR(DATA_DIR, "${datadir}", [Data files directory])
+ AC_DEFINE_DIR(DATA_DIR, datadir, [Data files directory])
fi
AC_ARG_ENABLE(debug,
- [AC_HELP_STRING(--enable-debug, Add development compilation options)],
+ [AC_HELP_STRING(--enable-debug, add development compilation options)],
debug=$enableval, debug="")
if test x"${debug}" = x"yes"; then
- AC_DEFINE_UNQUOTED([DEBUG_ENABLE],[1],[Devel compilation options])
+ AC_DEFINE_UNQUOTED([ENABLE_DEBUG],[1],[Devel compilation options])
if test "x$GCC" = "xyes"; then
if test "$gccvernum" -ge "400"; then
CFLAGS="$CFLAGS -Wextra"
fi
AC_ARG_ENABLE(hgcset,
- [AC_HELP_STRING(--disable-hgcset, Do not use Mercurial changeset value)],
+ [AC_HELP_STRING(--disable-hgcset, do not use Mercurial changeset value)],
hgcset=$enableval, hgcset="yes")
-AM_CONDITIONAL(HGCSET, test x$hgcset = xyes)
+AM_CONDITIONAL(HGCSET, [test x$hgcset = xyes])
if test "${hgcset}" = "yes"; then
AC_DEFINE(ENABLE_HGCSET, 1, [Use Mercurial changeset])
fi
diff --git a/connwrap/connwrap.c b/connwrap/connwrap.c
--- a/connwrap/connwrap.c
+++ b/connwrap/connwrap.c
@@ -294,7 +294,7 @@ int cw_http_connect(int sockfd, const struct sockaddr *serv_addr, int addrlen) {
char *ip = inet_ntoa(sin->sin_addr), c;
struct timeval tv;
- sprintf(buf, "%d", ntohs(sin->sin_port));
+ snprintf(buf, sizeof(buf), "%d", ntohs(sin->sin_port));
SOCKOUT("CONNECT ");
SOCKOUT(ip);
SOCKOUT(":");
--- a/contrib/events/eventcmd
+++ b/contrib/events/eventcmd
elif [ $event = "STATUS" ]; then
# Buddy $arg2 status is $arg1 (_, O, I, F, D, N, A)
echo > /dev/null
+elif [ $event = "UNREAD" ]; then
+ # $arg1 is the number of unread buffers
+ echo > /dev/null
fi
-
- /BUFFER [clear|close|close_all|purge]
+ /BUFFER [clear|close|close_all|purge|list]
/BUFFER [top|bottom|date|%|search_backward|search_forward]
/BUFFER [scroll_lock|scroll_unlock|scroll_toggle]
Leert alle Chatpuffer und schließt alle Chatfenster
/buffer purge [jid]
Leere das Chatfenster und lösche den Inhalt des Chatpuffers
+/buffer list
+ Zeigt eine Liste der existierende Puffer und deren Länge(Zeilen/Blöcke) an.
/buffer top
Springe zum Anfang des momentanen Chat Puffers
/buffer bottom
--- a/doc/help/de/hlp_room.txt
+++ b/doc/help/de/hlp_room.txt
/ROOM join|leave|names|nick|remove|topic|unlock|destroy
/ROOM privmsg|invite|kick|ban|role|affil
+ /ROOM setopt print_status|auto_whois [wert]
/ROOM bookmark [add|del] [-autojoin|+autojoin]
Der "room" Befehl umfasst die Multi-User Chat (kurz MUC) Befehle.
/room role jid rolle [grund]
Ändert die Rolle der jid (rolle kann "none", "visitor", "participant" oder "moderator" sein)
/room affil jid zugeh [grund]
- Ändert die Zugehörigkeit der jid zum Raum. (zugh kann "none", "member", "admin" oder "owner" sein)
+ Ändert die Zugehörigkeit der jid zum Raum. (zugeh kann "none", "member", "admin" oder "owner" sein)
+/room setopt print_status|auto_whois [wert]
+ Ändert die Einstellungen für den aktuellen MUC.
+ Für "print_status" sind folgende Werte möglich: "default", "none", "in_and_out", "all".
+ Bei "auto_whois" sind die Werte "default", "off" und "on" gültig.
+ Wenn man die Einstellungen auf "default" setzt, so werden die Optionen muc_print_status / muc_auto_whois benutzt.
/room bookmark [add|del] [-autojoin|+autojoin]
Zum Hinzufügen, Löschen und Ändern von Raum-Bookmarks.
Wenn autojoin gesetzt ist, wird mcabber nach dem verbinden zum Server diesen MUC automatisch betreten.
- /SAY_TO [-n|-h|--] jid text
+ /SAY_TO [-n|-h] [-q] [-f file] jid text
Sendet die Nachricht "text" zu der jid.
Denk daran, dass dieser Befehl die Nachricht an alle Ressourcen der jid gleichzeitig schicken wird. Wenn du unterschiedliche Nachrichten an diese schicken willst, musst du die Ressource mit angeben.
-Mit den Schaltern -n und -h kann man den Typ der Nachricht setzen(normal und headline). Wenn man mal eine Nachricht mit -n oder -h am Anfang verschicken will, kann man auch "--" als Flag benutzen, damit mcabber die Nachricht mit dem Nachrichtentyp "chat" verschickt.
+Mit den Schaltern -n und -h kann man den Typ der Nachricht setzen(normal und headline).
+Um eine Nachricht im Hintergrund zu versenden, kann man den Schalter -q benutzen.
+Mit -f kann man eine Textdatei angeben, aus der die Nachricht ausgelesen wird.
/STATUS [online|avail|invisible|free|dnd|notavail|away [-|StatusMessage]]
+ /STATUS message -|StatusMessage
Zeigt den aktuellen Status an, bzw. setzt ihn.
Wenn kein Status angegeben wurde, wird der aktuelle Status angezeigt.
Wenn eine Statusmeldung angegeben wurde, überschreibt diese die message* Variablen, welche in der Konfigurationsdatei gesetzt werden können.
Wenn keine passende message* Variable gesetzt ist und keine Statusmeldung angegeben wurde, behält mcabber die momentane Statusmeldung.
Wenn die Statusmeldung "-" ist, wird die gerade Aktuelle gelöscht.
+Wenn nur die Statusmeldung verändert werden soll, so kann auch "/status message" benutzt werden.
/STATUS_TO jid online|avail|invisible|free|dnd|notavail|away [StatusMessage]
+ /STATUS_TO jid message StatusMessage
Sendet den angegebenen Status zu der jid. Wenn der aktuell ausgewählte Buddy gemeint ist, kann auch "." als jid benutzt werden.
Beachte, dass der Status durch weitere /status Befehle überschrieben wird. Auch, wenn man das auto-away Feature benutzt!
- /BUFFER [clear|close|close_all|purge]
+ /BUFFER [clear|close|close_all|purge|list]
/BUFFER [top|bottom|date|%|search_backward|search_forward]
/BUFFER [scroll_lock|scroll_unlock|scroll_toggle]
Empty all contents of the chat buffers and close the chat windows
/buffer purge [jid]
Clear the current buddy chat window and empty all contents of the chat buffer
+/buffer list
+ Display the list of existing buffers, with their length (lines/blocks)
/buffer top
Jump to the top of the current buddy chat buffer
/buffer bottom
--- a/doc/help/en/hlp_room.txt
+++ b/doc/help/en/hlp_room.txt
/ROOM join|leave|names|nick|remove|topic|unlock|destroy
/ROOM privmsg|invite|kick|ban|role|affil
+ /ROOM setopt print_status|auto_whois [value]
/ROOM bookmark [add|del] [-autojoin|+autojoin]
The 'room' command handles Multi-User Chat room actions.
Change jid's role (role can be "none", "visitor", "participant", "moderator")
/room affil jid affil [reason]
Change jid's affiliation (affil can be "none", "member", "admin", "owner")
+/room setopt print_status|auto_whois [value]
+ Change settings for the current room
+ For print_status, the possible values are "default", "none", "in_and_out", "all".
+ For auto_whois, the possible values are "default", "off", "on".
+ When the value is "default", the options muc_print_status / muc_auto_whois is used.
/room bookmark [add|del] [-autojoin|+autojoin]
Add, remove or update a bookmark (default is add).
If autojoin is set, mcabber will automatically join the MUC room when it connects to the server.
- /SAY_TO [-n|-h|--] jid text
+ /SAY_TO [-n|-h] [-q] [-f file] jid text
Send the "text" message to the specified jid.
Please note that this command doesn't set the default resource for a contact, so if you want to send several messages to a specific resource you will have to use "/say_to" for each message.
-The "-n" flag turn the message to "normal" type, "-h" to "headline". "--" can be used to send chat message beginning with -n or -h.
+The "-n" flag turns the message to "normal" type, "-h" to "headline". "--" can be used to send chat messages beginning with -n or -h.
+When "-q" is used, the message will be sent in the background and will not change the current active window.
+A text file can be provided with the "-f" switch (in which case there's no need to pass a text argument after the jid, of course).
/STATUS [online|avail|invisible|free|dnd|notavail|away [-|StatusMessage]]
+ /STATUS message -|StatusMessage
Show or set the current status.
If no status is specified, display the current status.
If a status message is specified, it will overrride the message* variables (these variables can be set in the configuration file).
If no relevant message* variable is set and no status message provided, the current status message is kept.
If StatusMessage is "-", the current status message is cleared.
+With the "/status message" command, mcabber will update the message while preserving the status.
/STATUS_TO jid online|avail|invisible|free|dnd|notavail|away [StatusMessage]
+ /STATUS_TO jid message StatusMessage
Send the requested status to the specified Jabber user.
If the specified jid is ".", the current buddy is used.
- /BUFFER [clear|close|close_all|purge]
+ /BUFFER [clear|close|close_all|purge|list]
/BUFFER [top|bottom|date|%|search_backward|search_forward]
/BUFFER [scroll_lock|scroll_unlock|scroll_toggle]
/buffer close [jid]
Ferme la fenêtre du contact sélectionné après avoir vidé le contenu du tampon associé
/buffer close_all
- Ferme les fenêtres dde tous les contacts après avoir vidé le contenu des tampons associés
+ Ferme les fenêtres de tous les contacts après avoir vidé le contenu des tampons associés
/buffer purge [jid]
Efface la fenêtre du contact sélectionné et vide le contenu du tampon associé
+/buffer list
+ Affiche la liste des tampons existants, avec leur taille (lignes/blocs)
/buffer top
Va au début du tampon
/buffer bottom
--- a/doc/help/fr/hlp_room.txt
+++ b/doc/help/fr/hlp_room.txt
/ROOM join|leave|names|nick|remove|topic|unlock|destroy
/ROOM privmsg|invite|kick|ban|role|affil
+ /ROOM setopt print_status|auto_whois [valeur]
/ROOM bookmark [add|del] [-autojoin|+autojoin]
Cette commande permet de gérer les salons de discussions MUC (Multi-User Chat).
Change le rôle de jid (role peut être "none", "visitor", "participant", "moderator")
/room affil jid affil [raison]
Change l'affiliation de jid (affil peut être "none", "member", "admin", "owner")
+/room setopt print_status|auto_whois [valeur]
+ Change certains paramètres du salon sélectionné
+ Pour print_status, les valeurs possibles sont "default", "none", "in_and_out", "all".
+ Pour auto_whois, les valeurs possibles sont "default", "off", "on".
+ Si la valeur est "default", la configuration utilisée sera celle des options muc_print_status et muc_auto_whois.
/room bookmark [add|del] [-autojoin|+autojoin]
Ajoute, supprime ou met à jour le signet (par défaut, ajoute).
Si "autojoin" est activé, mcabber entrera automatiquement dans la salle de conférence après s'être connecté au serveur.
- /SAY_TO jid texte
+ /SAY_TO [-n|-h] [-q] [-f fichier] jid texte
Envoie le message "texte" à l'utilisateur "jid".
Remarquez que cette commande ne définit pas la ressource par défaut d'un contact, par conséquent si vous désirez envoyer plusieurs messages à une ressource précise il faudra utiliser "/say_to" à chaque fois.
+Lorsque "-q" est utilisé, le message sera envoyé en arrière plan et la fenêtre active sera conservée.
+Un fichier texte peut être fourni avec l'option "-f" (auquel cas il est inutile de préciser le paramètre texte).
/STATUS [online|avail|invisible|free|dnd|notavail|away [-|StatusMessage]]
+ /STATUS message -|StatusMessage
Affiche ou définit l'état actuel.
Si aucun état n'est précisé, affiche l'état courant.
Si un message d'état est spécifié, il outrepassera les variables message* (définies dans le fichier de configuration).
Si aucune variable message* adéquate n'est définie et aucun message d'état n'est fourni, le message d'état actuel est conservé.
Si "StatusMessage" est "-", le message d'état actuel est effacé.
+Avec la commande "/status message", le message d'état est changé tout en préservant l'état actuel.
/STATUS_TO jid online|avail|invisible|free|dnd|notavail|away [StatusMessage]
+ /STATUS_TO jid message StatusMessage
Envoie l'état demandé à "jid".
Si le jid fourni est ".", le contact sélectionné est utilisé.
- /BUFFER [clear|close|close_all|purge]
+ /BUFFER [clear|close|close_all|purge|list]
/BUFFER [top|bottom|date|%|search_backward|search_forward]
/BUFFER [scroll_lock|scroll_unlock|scroll_toggle]
Svuota tutti i contenuti presenti in tutti i buffer e chiude le finestre di chat
/buffer purge [jid]
Pulisce la finestra di chat del contatto corrente - o del contatto identificato da jid - e svuota tutti i contenuti del buffer
+/buffer list
+ Mostra la lista dei buffer esistenti, inclusa la loro lunghezza (linee/blocchi)
/buffer top
Salta all'inizio del buffer di chat del contatto corrente
/buffer bottom
- /GROUP fold|unfold|toggle [groupname]
+ /GROUP fold|unfold|toggle [gruppo]
-Questo comando cambia la visualizzazione del gruppo corrente.
+Questo comando cambia la visualizzazione del gruppo corrente o del gruppo specificato come parametro.
-/group fold [groupname]
- Chiude (collassa) l'albero del gruppo corrente nel roster
-/group unfold [groupname]
- Apre (espande) l'albero del gruppo corrente nel roster
-/group toggle [groupname]
- Cambia lo stato (collassato/espanso) dell'albero corrente
+/group fold [gruppo]
+ Chiude (collassa) il gruppo nel roster
+/group unfold [gruppo]
+ Apre (espande) il gruppo nel roster
+/group toggle [gruppo]
+ Cambia lo stato (collassato/espanso) del gruppo nel roster
--- a/doc/help/it/hlp_room.txt
+++ b/doc/help/it/hlp_room.txt
/ROOM join|leave|names|nick|remove|topic|unlock|destroy
/ROOM privmsg|invite|kick|ban|unban|role|affil
+ /ROOM setopt print_status|auto_whois [valore]
/ROOM bookmark [add|del] [-autojoin|+autojoin]
Il comando 'room' gestisce le azioni per le stanze di chat multi-utente.
Cambia il ruolo di jid (il ruolo può essere "none", "visitor", "participant", "moderator")
/room affil jid affil [motivo]
Cambia l'affiliazione di jid (l'affiliazione può essere "none", "member", "admin", "owner")
+/room setopt print_status|auto_whois [value]
+ Cambia le impostazioni della stanza corrente.
+ Per l'opzione print_status i valori possibili sono "default", "none", "in_and_out", "all".
+ Per auto_whois, i valori possibili sono "default", "off", "on".
+ Quando il valore è impostato a "default", vengono usate le opzioni muc_print_status / muc_auto_whois.
/room bookmark [add|del] [-autojoin|+autojoin]
Aggiunge, rimuove o aggiorna un bookmark (di default aggiunge).
Se è impostato l'autojoin, mcabber entrerà automaticamente nella stanza quando si connette al server.
/roster item_unlock [jid]
Cancella gli effetti di item_lock
/roster item_toggle_lock [jid]
+ Inverte lo stato del lock per il contatto corrente o per il contatto specificato da jid
/roster hide
Nasconde il roster (chat a finestra piena)
/roster show
- /SAY_TO [-n|-h|--] jid testo
+ /SAY_TO [-n|-h] [-q] [-f file] jid testo
Invia il messaggio "testo" al jid specificato.
Nota che questo comando non imposta una risorsa di default per un contatto, quindi se vuoi inviare diversi messaggi alla specifica risorsa devi usare "/say_to" per ciascun messaggio.
L'opzione "-n" trasforma il messaggio in "normale", "-h" in "headline". "--" può essere utilizzato per inviare messaggi che comincino con -n o -h.
+Quando si usa "-q", il messaggio viene spedito in background e la finestra attiva non viene modificata.
+L'opzione "-f" serve a specificare un file di testo (nel qual caso non serve aggiungere testo dopo il jid, ovviamente).
/STATUS [online|avail|invisible|free|dnd|notavail|away [-|Messaggio di stato]]
+ /STATUS message -|StatusMessage
Mostra od imposta lo stato corrente.
Se non viene specificato uno stato, visualizza lo stato corrente.
Se viene specificato un messaggio, la variabili message* verranno sovrascritte (queste variabili possono essere impostate nel file di configurazione).
Se nessuna variabile message* è impostata, e non viene specificato alcun messaggio di stato, viene mantenuto lo stato corrente.
Se "Messaggio di stato" è "-", lo stato corrente viene cancellato.
+Con il comando "/status message", viene aggiornato il messaggio senza modificare lo stato corrente.
/STATUS_TO jid online|avail|invisible|free|dnd|notavail|away [Messaggio di stato]
+ /STATUS_TO jid message StatusMessage
-Mando lo stato richiesto all'utente jabber specificato.
+Manda lo stato richiesto all'utente jabber specificato.
Se il jid specificato è ".", viene usato il contatto corrente.
Nota: questo stato verrà sovrascritto dal comando "/status" successivo. Lo stato verrà sovrascritto anche se utilizzi la funzionalità di auto-away.
Nota: il jid può includere una risorsa (es: user@server/risorsa).
- /BUFFER [clear|close|close_all|purge]
+ /BUFFER [clear|close|close_all|purge|list]
/BUFFER [top|bottom|date|%|search_backward|search_forward]
/BUFFER [scroll_lock|scroll_unlock|scroll_toggle]
Wis de volledige inhoud van alle chat buffers en sluit alle chat vensters
/buffer purge [jid]
Wis het chat venster van de actieve buddy en verwijder de volledige inhoud van de chat buffer
+/buffer list
+ Toon de lijst van bestaande buffers, met hun lengte (regels/blokken)
/buffer top
Spring naar het begin van de chat buffer van de actieve buddy
/buffer bottom
--- a/doc/help/nl/hlp_room.txt
+++ b/doc/help/nl/hlp_room.txt
/ROOM join|leave|names|nick|remove|topic|unlock|destroy
/ROOM privmsg|invite|kick|ban|role|affil
+ /ROOM setopt print_status|auto_whois [waarde]
/ROOM bookmark [add|del] [-autojoin|+autojoin]
Het 'room' commando verzorgt de Multi-User Chat (MUC) room acties.
Verander jid's rol (rol kan zijn: "none", "visitor", "participant", "moderator")
/room affil jid affil [reden]
Verander jid's verbintenis (affil kan zijn: "none", "member", "admin", "owner")
+/room setopt print_status|auto_whois [waarde]
+ Verander instellingen voor de huidige chatroom
+ Voor print_status zijn de mogelijke waarden "default", "none", "in_and_out", "all".
+ Voor auto_whois zijn de mogelijke waarden "default", "off", "on".
+ Indien de waarde gelijk is aan "default" worden de waarden gebruikt van de opties muc_print_status en muc_auto_whois.
/room bookmark [add|del] [-autojoin|+autojoin]
Toevoegen, verwijderen of aanpassen van een bookmark (standaard is toevoegen).
Indien 'autojoin' actief is, zal mcabber automatisch de MUC chatroom betreden wanner het verbinding met de server heeft gemaakt.
- /SAY_TO jid tekst
+ /SAY_TO [-n|-h] [-q] [-f file] jid tekst
Verstuur het "tekst" bericht naar de gespecificeerde jid.
Let op dat dit commando geen standaard resource instelt voor een contact. Als je meerdere berichten aan een specifieke resource wilt versturen moet "/say_to" voor ieder bericht worden gebruikt.
+De "-n" vlag schakelt het bericht naar type "normaal", "-h" naar "koptekst" ('headline'). "--" kan gebruikt worden om chatberichten te versturen die beginnen met -n of -h.
+Wanneer "-q" wordt gebruikt, zal het bericht in de achtergrond worden verstuurd, en zal het huidige actieve venster niet veranderen.
+Een tekstbestand kan worden aangegeven met de "-f" vlag (in dat geval is het natuurlijk niet nodig om een tekst-argument na de 'jid' mee te geven).
/STATUS [online|avail|invisible|free|dnd|notavail|away [-|StatusBericht]]
+ /STATUS message -|StatusBericht
Tonen of instellen van de huidige status.
Indien geen status wordt gespecificeerd, wordt de huidige status getoond.
Indien een statusbericht wordt gespecificeerd, zal dat voorrang hebben op de message* variablelen (deze variabelen kunnen worden ingesteld in het configuratiebestand).
Indien geen relevante message* variabelen ingesteld zijn en er geen statusbericht wordt meegegeven, blijft het huidige statusbericht behouden.
Indien het StatusBericht "-" is, wordt het huidige statusbericht gewist.
+Met het "/status message" commando, zal mcabber het statusbericht aanpassen terwijl de status onveranderd blijft.
/STATUS_TO jid online|avail|invisible|free|dnd|notavail|away [StatusBericht]
+ /STATUS_TO jid message StatusBericht
Verstuur de aangegeven status naar het gespecificeerde Jabber account.
Indien de gespecificeerde jid "." is, wordt de actieve buddy gebruikt.
- /BUFFER [clear|close|close_all|purge]
+ /BUFFER [clear|close|close_all|purge|list]
/BUFFER [top|bottom|date|%|search_backward|search_forward]
/BUFFER [scroll_lock|scroll_unlock|scroll_toggle]
Czyści wszystkie bufory rozmów i zamyka okna z rozmowami
/buffer purge
Czyści okno rozmowy i usuwa całą zawartość bufora rozmowy
+/buffer list
+ Wyświetla liste wszystkich istniejących buforów, podając ich długość (linie/bloki)
/buffer top
Skacze na sam początek bufora rozmowy
/buffer bottom
--- a/doc/help/pl/hlp_room.txt
+++ b/doc/help/pl/hlp_room.txt
/ROOM join|leave|names|nick|remove|topic|unlock|destroy
/ROOM privmsg|invite|kick|ban|role|affil
+ /ROOM setopt print_status|auto_whois [wartość]
/ROOM bookmark [add|del] [-autojoin|+autojoin]
Polecenie 'room' służy do obsługi wieloużytkownikowych chat-room'ów.
Zmienia rolę użytkownika jid (może być: "none", "visitor", "participant", "moderator")
/room affil jid affil [powód]
Zmienia przynależność jid'a (może być: "none", "member", "admin", "owner")
+/room setopt print_status|auto_whois [warotść]
+ Zmienia ustawienia wyświetlania statusów dla aktualnego pokoju.
+ Możliwe wartości dla print_status: "default" (domyślne), "none" (wyłączone), "in_and_out" (wejścia i wyjścia), "all" (wszystkie).
+ Możliwe wartości dla auto_whois: "default" (domyślne), "off" (wyłączone), "on" (włączone).
+ Jeżeli została wybrana wartość "default", używane są ustawienia muc_print_status / muc_auto_whois.
/room bookmark [add|del] [-autojoin|+autojoin]
Dodaje, usuwa, aktualizuje zakładki (domyślnie dodaje).
Jeśli ustawiona jest opcja "autojoin", mcabber automatycznie dołączy do danego MUC po połączeniu z serwerem.
- /SAY_TO [-h|-h|--] jid tekst
+ /SAY_TO [-h|-h] [-q] [-f file] jid tekst
Wysyła wiadomość "tekst" do podanej osoby "jid".
Polecenie nie ustawia domyślnego zasobu dla kontaktu, więc jeżeli chcesz wysłać kilka wiadomości do konkretnego zasobu, musisz użyć "/say_to" dla każdej z wiadomości.
Flaga "-n" oraz "-h" pozwala ustawić tryby: "normal" oraz "headline". "--" może zostać użyte gdy wiadomość zaczyna się od -n lub -h.
+Kiedy "-q" jest użyte, wiadomośc zostanie wysłana w tle i nie zmieni bieżącego aktywnego okna.
+Plik zawierający tekst może być podany za pomocą przełącznika "-f" (w tym wypadku, oczywiście nie potrzeba podawać argumentu "tekst" po "jid")
/STATUS [online|avail|invisible|free|dnd|notavail|away [-|opis]]
+ /STATUS message -|opis
Wyświetla albo zmienia aktualny status.
Jeśli nie jest podany opis - zostaje wyświetlony aktualny status.
Jeśli podany jest status wraz z opisem, opis ten zastąpi zmienne message* (mogą one być ustawione w pliku konfiguracyjnym).
Jeśli zmieniamy status, a nie ma zdefiniowanych zmiennych message*, lub opis nie jest podany - aktualny opis jest zachowywany.
Jeżeli "opis" jest równy "-", aktualny opis jest czyszczony.
+Użycie polecenia "/status message" spowoduje, że mcabber uaktualni opis zachowując bieżący status.
/STATUS_TO jid online|avail|invisible|free|dnd|notavail|away [opis]
+ /STATUS_TO jid message opis
Wysyła aktualny status do wybranej osoby.
Jeśli jako jid podasz ".", aktualnie wybrana osoba zobaczy wybrany status.
- /BUFFER [clear|close|close_all|purge]
+ /BUFFER [clear|close|close_all|purge|list]
/BUFFER [top|bottom|date|%|search_backward|search_forward]
/BUFFER [scroll_lock|scroll_unlock|scroll_toggle]
Очищает текущее окно чата и очищает все содержимое буфера (истории переписки)
/buffer bottom
Перемещает к концу буфера (истории переписки) с текущим пользователем
+/buffer list
+ Выводит список всех буферов вместе с количеством содержащихся в них строк/блоков.
/buffer top
Перемещает к началу буфера (истории переписки) с текущим пользователем
/buffer up [n]
--- a/doc/help/ru/hlp_room.txt
+++ b/doc/help/ru/hlp_room.txt
/ROOM join|leave|names|nick|remove|topic|unlock|destroy
/ROOM privmsg|invite|kick|ban|role|affil
+ /ROOM setopt print_status|auto_whois [value]
/ROOM bookmark [add|del] [-autojoin|+autojoin]
Команда 'room' работает с конференциями (Multi-User Chat room).
Изменить статус пользователя "jid" (статус может быть "none", "visitor", "participant", "moderator")
/room affil jid affil [reason]
Принять пользователя "jid" в члены конференции (члены могут быть "none", "member", "admin", "owner")
+/room setopt print_status|auto_whois [value]
+ Изменяет настройки для текущей конференции (уведомления о событиях в конференции)
+ Для опции "print_status" доступны следующие значения "default", "none", "in_and_out", "all".
+ Для опции "auto_whois" возможные значения "default", "off", "on".
+ Когда опция выставлена в "default" используются параметры "muc_print_status" / "muc_auto_whois".
/room bookmark [add|del] [-autojoin|+autojoin]
Добавить, удалить или обновить закладку (по умолчанию: add - добавить)
Если включена опция autojoin, mcabber автоматически подключается к конференции после соединения с Jabber-сервером.
- /SAY_TO [-n|-h|--] jid text
+ /SAY_TO [-n|-h] [-q] [-f file] jid text
Отправляет сообщение "text" определенному пользователю "jid".
-Запомните, что, если Вы хотите отправить несколько сообщений определенному пользователю, данная команда должна вводиться перед каждым сообщением.
+Имейте ввиду, что если Вы хотите отправить несколько сообщений определенному пользователю, данная команда должна вводиться перед каждым сообщением.
Флаг "-n" задает сообщению тип "normal", "-h" - заголовок, "--" для отсылки сообщений начинающихся с -n / -h.
+При заданном флаге "-q" сообщение будет отправлено в фоновом режиме и текущее окно не измениться.
+Флаг "-f" отправит в сообщении содержимое текстового файла (при этом нет необходимости задавать параметр "text").
/STATUS [online|avail|invisible|free|dnd|notavail|away [-|StatusMessage]]
+ /STATUS message -|StatusMessage
-Отображает или устанавливает текущий статус.
-Если статус не задан - отображается текущий статус.
-Если статус задан, он будет задан согласно списку переменных в файле конфигурации.
-Если указанного статуса не найдено в списке переменных, устанавливается текущий статус.
-Если "StatusMessage" задан как "-", текущий статус очищается.
+Отображает или устанавливает текущий статус и статусное сообщение.
+Если параметры не заданы, то отобразится текущий статус и статусное сообщение.
+Если статусное сообщение не указано, то оно будет задано согласно списку переменных в файле конфигурации.
+Если указанный статус не найден в списке переменных, сохранится текущее статусное сообщение.
+Если "StatusMessage" имеет вид "-", то статусное сообщение будет очищено.
+Когда команда имеет вид "/status message", устанавливается новое статусное сообщение, а текущий статус сохраняется.
/STATUS_TO jid online|avail|invisible|free|dnd|notavail|away [StatusMessage]
+ /STATUS_TO jid message StatusMessage
Отправляет запрос на определение статуса определенного пользователя.
Если "jid" указан как "." используется текущий пользователь.
Призначає для "рядок команди" інше ім'я "скорочення"
Приклад: "/alias кава = status away Пішов варити каву..."
+Примітка: наразі кириличні скорочення підтримуються лише у однобайтових кодуваннях.
- /BUFFER [clear|close|close_all|purge]
+ /BUFFER [clear|close|close_all|purge|list]
/BUFFER [top|bottom|date|%|search_backward|search_forward]
/BUFFER [scroll_lock|scroll_unlock|scroll_toggle]
Потерти всі буфери з пам'яті і позакривати вікна діалогу.
/buffer purge [jid]
Очистити вікно діалогу а також потерти його вміст з пам'яті.
+/buffer list
+ Показати перелік усіх відкритих буферів та їх розмір (рядків/блоків).
/buffer top
Перейти до початку буферу.
/buffer bottom
/COLOR roster (статус маска (колір|-)|clear)
- /COLOR mucnick nick (color|-|!)
+ /COLOR mucnick прізвисько (колір|-|!)
/COLOR muc (jid|.|*) [on|preset|off|-]
Керує кольорами контактів у списку.
У режимі on забарвлюються усі прізвиська, у режимі preset - лише ті, для яких колір встановлено командою /color mucnick, а режим off вимикає забарвлення прізвиськ. Режим - прибирає з вказаних jid особисті режими забарвлення. Тоді до них докладається глобальний. Глобальний режим прибрати не можна.
Початковий глобальний режим - off.
/color mucnick прізвисько (колір|-|!)
- Створює правило забарвлювати прізвисько вказаним кольором. Якщо вказано -, колір позначається як автоматично обраний, тобто його не буде використано у режимі preset, але у режимі on він залишиться тим самим. Колір ! означає випадковий колір (позначений як автоматично обраний).
+ Створює правило забарвлювати прізвисько вказаним кольором. Якщо вказано -, колір позначається як автоматично обраний, тобто його не буде використано у режимі preset, але у режимі on він залишиться тим самим. Колір ! означає випадковий колір (й позначає його як автоматично обраний). Випадкові кольори беруться з параметру "nick_colors" (mcabberrc)
- /GROUP fold|unfold|toggle [groupname]
+ /GROUP fold|unfold|toggle [назва групи]
-Змінює відображення поточної групи.
+Змінює стан відображення вказаної групи. Якщо групу не вказано, береться та, у якій знаходиться вибраний контакт.
-/group fold [groupname]
- Згорнути дерево поточної групи у списку.
-/group unfold [groupname]
- Розгорнути дерево поточної групи у списку.
-/group toggle [groupname]
- Змінити стан відображення поточної групи.
+/group fold [назва групи]
+ Згорнути (приховати) дерево групи у списку.
+/group unfold [назва групи]
+ Розгорнути (показати) дерево групи у списку.
+/group toggle [назва групи]
+ Змінити стан відображення групи.
--- a/doc/help/uk/hlp_room.txt
+++ b/doc/help/uk/hlp_room.txt
/ROOM join|leave|names|nick|remove|topic|unlock|destroy
/ROOM privmsg|invite|kick|ban|unban|role|affil
+ /ROOM setopt print_status|auto_whois [значення]
/ROOM bookmark [add|del] [+autojoin|-autojoin]
Команда, відповідальна за дії при багатокористувацькій розмові.
/room join [кімната [прізвисько [пароль]]]
- Увійти до "кімнати", під іменем "прізвисько". Якщо не вказане (або ""), береться з параметру "nickname" (mcabberrc). Якщо поточний контакт є кімнатою, можна використати "." замість повного ім'я кімнати. Пароль може використовуватися для входу в захищені кімнати. Для імен з пробілами використовуйте лапки.
+ Увійти до "кімнати", під іменем "прізвисько". Якщо не вказане (або ""), береться з параметру "nickname" (mcabberrc). Якщо поточний контакт є кімнатою, можна використати "." замість повної назви кімнати. Пароль може бути потрбен для входу в захищені кімнати. Для назв з пробілами використовуйте лапки.
/room leave [повідомлення]
Вийти з поточної кімнати.
/room names [--detail|--short|--quiet]
- Друкує імена присутніх в кімнаті.
+ Друкує інформацію про присутніх в кімнаті з вказаним рівнем деталізації.
/room nick прізвисько
Змінити ваше прізвисько у поточній кімнаті.
/room privmsg прізвисько повідомлення
Змінити роль jid у комнаті ("none", "visitor", "participant", "moderator")
/room affil jid ступінь [причина]
Змінити ступінь довіри для jid ("none", "member", "admin", "owner").
+/room setopt print_status|auto_whois [значення]
+ Встановлює додаткові параметри для поточної кімнати
+ print_status керує відображенням змін у статусі присутніх ("default", "none", "in_and_out", "all").
+ auto_whois визначає, чи запитувати автоматично інформацію про новоприбульців до кімнати ("default", "off", "on").
+ Коли встановлено "default", мають силу глобальні опції muc_print_status / muc_auto_whois.
/room bookmark [add|del] [+autojoin|-autojoin]
Додати, потерти, або замінити закладку (якщо не вказано - додасть).
Якщо встановити автовхід, mcabber буде заходити в цю кімнату після з'єднання з сервером.
/roster item_unlock [jid]
Відміняє дію item_lock.
/roster item_toggle_lock [jid]
+ Перемикає "закріпленість" об'єкта.
/roster hide
Сховати список.
/roster show
- /SAY_TO [-n|-h|--] jid текст
+ /SAY_TO [-n|-h] [-q] [-f файл] jid текст
Надсилає текст до вказаного jid.
Майте на увазі, що ця команда не встановлює стандартного ресурсу для контакту, отже, якщо вам треба надіслати декілька повідомлень до визначених ресурсів, вам треба використовувати "/say_to" для кожного повідомлення.
Флаги -n та -h змінюють тип повідомлення у "normal" або "headline". "--" використовується, щоб надіслати звичайне повідомлення, що починається з -n чи -h.
+Флаг -q дозволяє надсилати повідомлення, не перемикаючи вікна розмови (корисно при автоматичному надсиланні через fifo).
+Ви можете узяти текст повідомлення із текстового файлу за допомогою аргументу -f. Звісно, якщо вказано файл з повідомленням, "текст" ігнорується, й його можна не вказувати взагалі.
/SOURCE файл
Читає налаштування з файлу.
+Примітка: у під'єднаному до сервера стані команда розуміє й звичайні команди (як то say, group та інші) це можна використати у hook-post-connect (див. mcabberrc).
/STATUS [online|avail|invisible|free|dnd|notavail|away [-|повідомлення]]
+ /STATUS message -|повідомлення
Друкує або встановлює ваш статус.
Якщо статус не вказано, друкує поточний.
Якщо не вказане повідомлення, використовується повідомлення вказане відповідним параметром message* (з mcabberrc).
Якщо відповідний message* не визначений, залишається поточне повідомлення.
"-" тре поточне повідомлення.
+"/status message" змінює лише повідомлення, не чіпаючи поточний статус.
/STATUS_TO jid online|avail|invisible|free|dnd|notavail|away [повідомлення]
+ /STATUS_TO jid message повідомлення
Надсилає до jid вказаний статус. Поточний контакт можна вказати як "." .
Примітка: Цей статус буде скинуто наступною командою "/status". Автоматична зміна статусу також це робить.
diff --git a/doc/mcabber.1 b/doc/mcabber.1
--- a/doc/mcabber.1
+++ b/doc/mcabber.1
@@ -1103,7 +1103,7 @@ Written by \fIMikael BERTHE\fR\&[1]. Originally based on \fICabber\fR\&[2], plea
\fIMain web site\fR\&[3]
.sp
.SH "COPYING"
-Copyright (C) 2005, 2006, 2007 Mikael Berthe. Some portions are Copyright (C) 2002\-2004 \fIcabber@ajmacias.com\fR\&[4].
+Copyright (C) 2005, 2006, 2007, 2008 Mikael Berthe. Some portions are Copyright (C) 2002\-2004 \fIcabber@ajmacias.com\fR\&[4].
.sp
Free use of this software is granted under the terms of the GNU General Public License (GPL).
.sp
diff --git a/doc/mcabber.1.html b/doc/mcabber.1.html
--- a/doc/mcabber.1.html
+++ b/doc/mcabber.1.html
<h2>RESOURCES</h2>\r
<p><a href="http://www.lilotux.net/~mikael/mcabber/">Main web site</a></p>\r
<h2>COPYING</h2>\r
-<p>Copyright (C) 2005, 2006, 2007 Mikael Berthe.<br />\r
+<p>Copyright (C) 2005, 2006, 2007, 2008 Mikael Berthe.<br />\r
Some portions are Copyright (C) 2002-2004 <a href="mailto:cabber@ajmacias.com">cabber@ajmacias.com</a>.</p>\r
<p>Free use of this software is granted under the terms of the GNU General Public\r
License (GPL).</p>\r
<div id="footer">\r
<p>\r
-Version 0.9.5<br />\r
+Version 0.9.7<br />\r
Last updated 27-Jun-2007 22:11:34 CEST\r
</p>\r
</div>\r
diff --git a/doc/mcabber.1.txt b/doc/mcabber.1.txt
--- a/doc/mcabber.1.txt
+++ b/doc/mcabber.1.txt
MCABBER(1)
===========
Mikael BERTHE <mcabber@lilotux.net>
-v0.9.5, November 2007
+v0.9.7, April 2008
NAME
----
COPYING
-------
-Copyright \(C) 2005, 2006, 2007 Mikael Berthe. +
+Copyright \(C) 2005, 2006, 2007, 2008 Mikael Berthe. +
Some portions are Copyright \(C) 2002-2004 mailto:cabber@ajmacias.com[].
Free use of this software is granted under the terms of the GNU General Public
diff --git a/ltmain.sh b/ltmain.sh
--- a/ltmain.sh
+++ b/ltmain.sh
# ltmain.sh - Provide generalized library-building support services.
# NOTE: Changing this file will not affect anything until you rerun configure.
#
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005
-# Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008 Free Software Foundation, Inc.
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
#
# This program is free software; you can redistribute it and/or modify
PROGRAM=ltmain.sh
PACKAGE=libtool
-VERSION="1.5.22 Debian 1.5.22-4"
-TIMESTAMP=" (1.1220.2.365 2005/12/18 22:14:06)"
-
-# See if we are running on zsh, and set the options which allow our
-# commands through without removal of \ escapes.
-if test -n "${ZSH_VERSION+set}" ; then
+VERSION="1.5.26 Debian 1.5.26-3"
+TIMESTAMP=" (1.1220.2.493 2008/02/01 16:58:18)"
+
+# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
# Check that we have a working $echo.
if test "X$1" = X--no-reexec; then
# These must not be set unconditionally because not all systems understand
# e.g. LANG=C (notably SCO).
# We save the old values to restore during execute mode.
-if test "${LC_ALL+set}" = set; then
- save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
-fi
-if test "${LANG+set}" = set; then
- save_LANG="$LANG"; LANG=C; export LANG
+lt_env=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+ eval "if test \"\${$lt_var+set}\" = set; then
+ save_$lt_var=\$$lt_var
+ lt_env=\"$lt_var=\$$lt_var \$lt_env\"
+ $lt_var=C
+ export $lt_var
+ fi"
+done
+
+if test -n "$lt_env"; then
+ lt_env="env $lt_env"
fi
# Make sure IFS has a sensible default
preserve_args=
lo2o="s/\\.lo\$/.${objext}/"
o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
#####################################
# Shell function definitions:
if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | \
$EGREP -e 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
win32_nmres=`eval $NM -f posix -A $1 | \
- $SED -n -e '1,100{/ I /{s,.*,import,;p;q;};}'`
+ $SED -n -e '1,100{
+ / I /{
+ s,.*,import,
+ p
+ q
+ }
+ }'`
case $win32_nmres in
import*) win32_libid_type="x86 archive import";;
*) win32_libid_type="x86 archive static";;
*) my_xabs=`pwd`"/$my_xlib" ;;
esac
my_xlib=`$echo "X$my_xlib" | $Xsed -e 's%^.*/%%'`
- my_xdir="$my_gentop/$my_xlib"
+ my_xlib_u=$my_xlib
+ while :; do
+ case " $extracted_archives " in
+ *" $my_xlib_u "*)
+ extracted_serial=`expr $extracted_serial + 1`
+ my_xlib_u=lt$extracted_serial-$my_xlib ;;
+ *) break ;;
+ esac
+ done
+ extracted_archives="$extracted_archives $my_xlib_u"
+ my_xdir="$my_gentop/$my_xlib_u"
$show "${rm}r $my_xdir"
$run ${rm}r "$my_xdir"
;;
--version)
- $echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
- $echo
- $echo "Copyright (C) 2005 Free Software Foundation, Inc."
- $echo "This is free software; see the source for copying conditions. There is NO"
- $echo "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+ echo "\
+$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
exit $?
;;
*.class) xform=class ;;
*.cpp) xform=cpp ;;
*.cxx) xform=cxx ;;
- *.f90) xform=f90 ;;
+ *.[fF][09]?) xform=[fF][09]. ;;
*.for) xform=for ;;
*.java) xform=java ;;
+ *.obj) xform=obj ;;
+ *.sx) xform=sx ;;
esac
libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
$run $rm "$lobj" "$output_obj"
$show "$command"
- if $run eval "$command"; then :
+ if $run eval $lt_env "$command"; then :
else
test -n "$output_obj" && $run $rm $removelist
exit $EXIT_FAILURE
command="$command$suppress_output"
$run $rm "$obj" "$output_obj"
$show "$command"
- if $run eval "$command"; then :
+ if $run eval $lt_env "$command"; then :
else
$run $rm $removelist
exit $EXIT_FAILURE
thread_safe=no
vinfo=
vinfo_number=no
+ single_module="${wl}-single_module"
func_infer_tag $base_compile
for arg
do
case $arg in
- -all-static | -static)
- if test "X$arg" = "X-all-static"; then
+ -all-static | -static | -static-libtool-libs)
+ case $arg in
+ -all-static)
if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
$echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
fi
dlopen_self=$dlopen_self_static
fi
prefer_static_libs=yes
- else
+ ;;
+ -static)
if test -z "$pic_flag" && test -n "$link_static_flag"; then
dlopen_self=$dlopen_self_static
fi
prefer_static_libs=built
- fi
+ ;;
+ -static-libtool-libs)
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ prefer_static_libs=yes
+ ;;
+ esac
build_libtool_libs=no
build_old_libs=yes
break
continue
;;
- -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
compiler_flags="$compiler_flags $arg"
compile_command="$compile_command $arg"
finalize_command="$finalize_command $arg"
continue
;;
+ -multi_module)
+ single_module="${wl}-multi_module"
+ continue
+ ;;
+
-module)
module=yes
continue
# -m* pass through architecture-specific compiler args for GCC
# -m*, -t[45]*, -txscale* pass through architecture-specific
# compiler args for GCC
- # -pg pass through profiling flag for GCC
+ # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
+ # -F/path gives path to uninstalled frameworks, gcc on darwin
# @file GCC response files
- -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*|-pg| \
- -t[45]*|-txscale*|@*)
+ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)
# Unknown arguments in both finalize_command and compile_command need
# to be aesthetically quoted because they are evaled later.
-no-install)
case $host in
- *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin*)
# The PATH hackery in wrapper scripts is required on Windows
- # in order for the loader to find any dlls it needs.
+ # and Darwin in order for the loader to find any dlls it needs.
$echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
$echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
fast_install=no
continue
;;
- -static)
+ -static | -static-libtool-libs)
# The effects of -static are defined in a previous loop.
# We used to do the same as -all-static on platforms that
# didn't have a PIC flag, but the assumption that the effects
lib=
found=no
case $deplib in
- -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe)
+ -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
if test "$linkmode,$pass" = "prog,link"; then
compile_deplibs="$deplib $compile_deplibs"
finalize_deplibs="$deplib $finalize_deplibs"
continue
fi
name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
- for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ if test "$linkmode" = lib; then
+ searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+ else
+ searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+ fi
+ for searchdir in $searchdirs; do
for search_ext in .la $std_shrext .so .a; do
# Search the libtool library
lib="$searchdir/lib${name}${search_ext}"
if test "$linkmode,$pass" = "prog,link"; then
if test -n "$library_names" &&
- { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+ { { test "$prefer_static_libs" = no ||
+ test "$prefer_static_libs,$installed" = "built,yes"; } ||
+ test -z "$old_library"; }; then
# We need to hardcode the library path
if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
# Make sure the rpath contains only unique directories.
# we do not want to link against static libs,
# but need to link against shared
eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+ eval deplibdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
if test -n "$deplibrary_names" ; then
for tmp in $deplibrary_names ; do
depdepl=$tmp
done
- if test -f "$path/$depdepl" ; then
+ if test -f "$deplibdir/$depdepl" ; then
+ depdepl="$deplibdir/$depdepl"
+ elif test -f "$path/$depdepl" ; then
depdepl="$path/$depdepl"
+ else
+ # Can't find it, oh well...
+ depdepl=
fi
# do not add paths which are already there
case " $newlib_search_path " in
case $linkmode in
oldlib)
- if test -n "$deplibs"; then
- $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
- fi
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 ;;
+ esac
if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
$echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
# which has an extra 1 added just for fun
#
case $version_type in
- darwin|linux|osf|windows)
+ darwin|linux|osf|windows|none)
current=`expr $number_major + $number_minor`
age="$number_minor"
revision="$number_revision"
age="0"
;;
irix|nonstopux)
- current=`expr $number_major + $number_minor - 1`
+ current=`expr $number_major + $number_minor`
age="$number_minor"
revision="$number_minor"
+ lt_irix_increment=no
;;
*)
$echo "$modename: unknown library version type \`$version_type'" 1>&2
versuffix="$major.$age.$revision"
# Darwin ld doesn't like 0 for these options...
minor_current=`expr $current + 1`
- verstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+ xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
;;
freebsd-aout)
;;
irix | nonstopux)
- major=`expr $current - $age + 1`
-
+ if test "X$lt_irix_increment" = "Xno"; then
+ major=`expr $current - $age`
+ else
+ major=`expr $current - $age + 1`
+ fi
case $version_type in
nonstopux) verstring_prefix=nonstopux ;;
*) verstring_prefix=sgi ;;
fi
# Eliminate all temporary directories.
- for path in $notinst_path; do
- lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"`
- deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"`
- dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"`
- done
+ #for path in $notinst_path; do
+ # lib_search_path=`$echo "$lib_search_path " | ${SED} -e "s% $path % %g"`
+ # deplibs=`$echo "$deplibs " | ${SED} -e "s% -L$path % %g"`
+ # dependency_libs=`$echo "$dependency_libs " | ${SED} -e "s% -L$path % %g"`
+ #done
if test -n "$xrpath"; then
# If the user specified any rpath flags, then add them.
int main() { return 0; }
EOF
$rm conftest
- $LTCC $LTCFLAGS -o conftest conftest.c $deplibs
- if test "$?" -eq 0 ; then
+ if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
ldd_output=`ldd conftest`
for i in $deplibs; do
name=`expr $i : '-l\(.*\)'`
# If $name is empty we are operating on a -L argument.
- if test "$name" != "" && test "$name" -ne "0"; then
+ if test "$name" != "" && test "$name" != "0"; then
if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
case " $predeps $postdeps " in
*" $i "*)
# If $name is empty we are operating on a -L argument.
if test "$name" != "" && test "$name" != "0"; then
$rm conftest
- $LTCC $LTCFLAGS -o conftest conftest.c $i
- # Did it work?
- if test "$?" -eq 0 ; then
+ if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
ldd_output=`ldd conftest`
if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
case " $predeps $postdeps " in
droppeddeps=yes
$echo
$echo "*** Warning! Library $i is needed by this library but I was not able to"
- $echo "*** make it link in! You will probably need to install it or some"
+ $echo "*** make it link in! You will probably need to install it or some"
$echo "*** library that it depends on before this library will be fully"
$echo "*** functional. Installing it before continuing would be even better."
fi
test -n "$hardcode_libdirs"; then
libdir="$hardcode_libdirs"
if test -n "$hardcode_libdir_flag_spec_ld"; then
- eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+ case $archive_cmds in
+ *\$LD*) eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" ;;
+ *) eval dep_rpath=\"$hardcode_libdir_flag_spec\" ;;
+ esac
else
eval dep_rpath=\"$hardcode_libdir_flag_spec\"
fi
;;
obj)
- if test -n "$deplibs"; then
- $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
- fi
+ case " $deplibs" in
+ *\ -l* | *\ -L*)
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 ;;
+ esac
if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
$echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
reload_conv_objs=
gentop=
# reload_cmds runs $LD directly, so let us get rid of
- # -Wl from whole_archive_flag_spec
+ # -Wl from whole_archive_flag_spec and hope we can get by with
+ # turning comma into space..
wl=
if test -n "$convenience"; then
if test -n "$whole_archive_flag_spec"; then
- eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+ eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+ reload_conv_objs=$reload_objs\ `$echo "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
else
gentop="$output_objdir/${obj}x"
generated="$generated $gentop"
case $host in
*cygwin* | *mingw* )
if test -f "$output_objdir/${outputname}.def" ; then
- compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"`
- finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%"`
+ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP`
+ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}.def $output_objdir/${outputname}S.${objext}%" | $NL2SP`
else
- compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
- finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
+ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
fi
;;
* )
- compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
- finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
+ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%" | $NL2SP`
;;
esac
;;
# really was required.
# Nullify the symbol file.
- compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
- finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP`
+ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "s% @SYMFILE@%%" | $NL2SP`
fi
if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
# Replace the output file specification.
- compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$output"'%g' | $NL2SP`
link_command="$compile_command$compile_rpath"
# We have no uninstalled library dependencies, so finalize right now.
if test "$fast_install" != no; then
link_command="$finalize_var$compile_command$finalize_rpath"
if test "$fast_install" = yes; then
- relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+ relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $SP2NL | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g' | $NL2SP`
else
# fast_install is set to needless
relink_command=
fi
done
relink_command="(cd `pwd`; $relink_command)"
- relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP`
fi
# Quote $echo for shipping.
Xsed='${SED} -e 1s/^X//'
sed_quote_subst='$sed_quote_subst'
+# Be Bourne compatible (taken from Autoconf:_AS_BOURNE_COMPATIBLE).
+if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then
+ emulate sh
+ NULLCMD=:
+ # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
# The HP-UX ksh and POSIX shell print the target directory to stdout
# if CDPATH is set.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
;;
esac
$echo >> $output "\
- \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+ \$echo \"\$0: cannot exec \$program \$*\"
exit $EXIT_FAILURE
fi
else
done
# Quote the link command for shipping.
relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
- relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e "$sed_quote_subst" | $NL2SP`
if test "$hardcode_automatic" = yes ; then
relink_command=
fi
if test -n "$inst_prefix_dir"; then
# Stick the inst_prefix_dir data into the link command.
- relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+ relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%" | $NL2SP`
else
- relink_command=`$echo "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
+ relink_command=`$echo "$relink_command" | $SP2NL | $SED "s%@inst_prefix_dir@%%" | $NL2SP`
fi
$echo "$modename: warning: relinking \`$file'" 1>&2
file=`$echo "X$file$stripped_ext" | $Xsed -e 's%^.*/%%'`
outputname="$tmpdir/$file"
# Replace the output file specification.
- relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+ relink_command=`$echo "X$relink_command" | $SP2NL | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g' | $NL2SP`
$show "$relink_command"
if $run eval "$relink_command"; then :
if test -f "$dir/$objdir/$dlname"; then
dir="$dir/$objdir"
else
- $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
- exit $EXIT_FAILURE
+ if test ! -f "$dir/$dlname"; then
+ $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+ exit $EXIT_FAILURE
+ fi
fi
;;
fi
# Restore saved environment variables
- if test "${save_LC_ALL+set}" = set; then
- LC_ALL="$save_LC_ALL"; export LC_ALL
- fi
- if test "${save_LANG+set}" = set; then
- LANG="$save_LANG"; export LANG
- fi
+ for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+ do
+ eval "if test \"\${save_$lt_var+set}\" = set; then
+ $lt_var=\$save_$lt_var; export $lt_var
+ fi"
+ done
# Now prepare to actually exec the command.
exec_cmd="\$cmd$args"
-dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
-export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
-export-symbols SYMFILE
- try to export only the symbols listed in SYMFILE
+ try to export only the symbols listed in SYMFILE
-export-symbols-regex REGEX
- try to export only the symbols matching REGEX
+ try to export only the symbols matching REGEX
-LLIBDIR search LIBDIR for required installed libraries
-lNAME OUTPUT-FILE requires the installed library libNAME
-module build a library that can dlopened
-release RELEASE specify package release information
-rpath LIBDIR the created library will eventually be installed in LIBDIR
-R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
- -static do not do any dynamic linking of libtool libraries
+ -static do not do any dynamic linking of uninstalled libtool libraries
+ -static-libtool-libs
+ do not do any dynamic linking of libtool libraries
-version-info CURRENT[:REVISION[:AGE]]
- specify library version info [each variable defaults to 0]
+ specify library version info [each variable defaults to 0]
All other options (arguments beginning with \`-') are ignored.
--- a/macros/missing/libotr.m4
+++ b/macros/missing/libotr.m4
dnl Get the cflags and libraries for libotr
dnl
AC_ARG_WITH(libotr-prefix,
-[ --with-libotr-prefix=PFX Prefix where libotr is installed(optional)],
+[ --with-libotr-prefix=PFX prefix where libotr is installed (optional)],
[libotr_prefix="$withval"], [libotr_prefix=""])
AC_ARG_WITH(libotr-inc-prefix,
-[ --with-libotr-inc-prefix=PFX Prefix where libotr includes are (optional)],
+[ --with-libotr-inc-prefix=PFX prefix where libotr includes are (optional)],
[libotr_inc_prefix="$withval"], [libotr_inc_prefix=""])
dnl Add any special include directories
diff --git a/mcabberrc.example b/mcabberrc.example
--- a/mcabberrc.example
+++ b/mcabberrc.example
# If port is not given, default Jabber port will be used.
#
# Warning to GTalk users! please see the FAQ:
-# <http://www.probsd.net/mcabber/index.php/Main_Page#FAQ>
+# <http://wiki.mcabber.com/index.php/Frequently_Asked_Questions>
set username = yourusername
# Note: if the password contains leading or trailing spaces, you must
#set password = yourpassword
set server = your.jabber.server
#set port = 5222
-# If you don't know what a resource is, you can leave "mcabber" here.
-set resource = mcabber
+# If you don't know what a resource is, do not set it.
+#set resource = mcabber
#set priority = 3
+#set priority_away = 0
+
+# Set 'ignore_self_presence' to 1 if you do not want to see your own
+# presence in your roster (default: 0).
+set ignore_self_presence = 1
# SSL options:
# Set ssl non-zero to use SSL (this also sets the default port to 5223).
# Default = 0 (disabled -- everything is loaded)
# Note: this option is only used when reading history files, not later.
#set max_history_age = 0
-#
+
+# mcabber can store the list of unread messages in a state file,
+# so that the message flags are set back at next startup.
+# Note that 'logging' must be enabled for this feature to work.
+#set statefile = ~/.mcabber/mcabber.state
+
# You can specify a maximum number of data blocks per buffer (1 block contains
# about 8kB). The default is 0 (unlimited). If set, this value must be > 2.
#set max_history_blocks = 8
# $events_command MSG OUT jabber@id (when sending a message)
# $events_command MSG MUC room_id [file] (when receiving a MUC message)
# $events_command STATUS X jabber@id (new buddy status is X)
+# $events_command UNREAD N (number of unread buddy buffers)
# See sample script in contrib/ directory.
#set events_command = ~/.mcabber/eventcmd
#
#set event_log_files = 0
#set event_log_dir = ~/.mcabber/event_files
+# If you set 'eventcmd_use_nickname' to 1, mcabber will pass the nickname
+# (if it is defined) to the event script instead of the JID (default: 0).
+#set eventcmd_use_nickname = 0
+
# External command status check
# You can request mcabber to inspect exit status value after each
# events_command. If this option is set, mcabber will beep if the
# the server.
#set hook-pre-disconnect = say_to foo@bar Goodbye!
+# FIFO
+# mcabber can create a FIFO named pipe and listen to this pipe for commands.
+# (The FIFO support has to be compiled in.) Default: disabled.
+# Set fifo_hide_commands to 1 if you don't want to see the FIFO commands
+# in the log window (they will still be written to the tracelog file).
+#set fifo_name = ~/.mcabber/mcabber.fifo
+#set fifo_hide_commands = 0
+
# Traces logging
# If you want advanced traces, please specify a file and a level here.
# There are currently 2 traceloglog levels:
# the roster when somebody joins a room. Set it to 2 if you want a flag
# for leaves too.
#set muc_flag_joins = 0
+# Set 'muc_print_status' to see status changes in MUC rooms:
+# 1: (none) do not display joining/leaving members
+# 2: (in_and_out) display joining/leaving members
+# 3: (all) display joining/leaving members and member status changes
+# (default: in_and_out)
+#set muc_print_status = 2
# Set 'muc_auto_whois' to 1 if you want to call /room whois each time
# somebody joins a room. (default: 0)
#set muc_auto_whois = 0
# isn't defined, the status message will stay unchanged.
set message_autoaway = Auto-away (idle)
+# Escape timeout delay (ESCDELAY)
+# The ESCDELAY variable specifies the time, in milliseconds, for which
+# the ncurses interface will await a character sequence.
+# The default is 1000 (1 second).
+# If you want mcabber to react faster after hitting Escape, you can lower
+# this value by setting the ESCDELAY environment variable or setting the
+# 'escdelay' option.
+set escdelay = 50
+
# Colors
# Colors are: black, red, green, yellow, blue, magenta, cyan, white
# For text colors (i.e. not background and bg* colors) you can also use
# the "bright" prefix to get a bright/bold color. Example: brightblue
-# You can use the "default" color, too (i.e. for transparent background)
+# You can use the "default" color, too (i.e. for transparent background).
+# If your terminal supports 256 colors, you can use the color number
+# directly (16-255).
#
-# You can have a look at the contrib/themes/ directory to see some sample
+# Have a look at the contrib/themes/ directory to see some sample
# color settings.
#
# background: background color of the chat window and the log window
# set "buddy_me_fulljid" to 1 (default: 0)
#set buddy_me_fulljid = 1
#
+# Display the status changes in the log window (default: 0, never)
+# Set 'log_display_presence' to 1 to enable.
+#set log_display_presence = 0
+#
# Display the status changes in the chat buffers (default: 0, never)
# Values: 0: never 1: only connect/disconnect 2: all
#set show_status_in_buffer = 1
diff --git a/src/Makefile.am b/src/Makefile.am
--- a/src/Makefile.am
+++ b/src/Makefile.am
hbuf.c hbuf.h screen.c screen.h logprint.h \
settings.c settings.h hooks.c hooks.h utf8.c utf8.h \
histolog.c histolog.h utils.c utils.h pgp.c pgp.h \
- help.c help.h
+ fifo.c fifo.h help.c help.h
if OTR
-mcabber_SOURCES += otr.c otr.h
+mcabber_SOURCES += otr.c otr.h nohtml.c nohtml.h
endif
LDADD = $(GLIB_LIBS) $(GPGME_LIBS) $(LIBOTR_LIBS) \
diff --git a/src/Makefile.in b/src/Makefile.in
--- a/src/Makefile.in
+++ b/src/Makefile.in
PRE_UNINSTALL = :
POST_UNINSTALL = :
bin_PROGRAMS = mcabber$(EXEEXT)
-@OTR_TRUE@am__append_1 = otr.c otr.h
+@OTR_TRUE@am__append_1 = otr.c otr.h nohtml.c nohtml.h
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in COPYING
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
jabglue.c jabglue.h jab_iq.c jab_priv.h commands.c commands.h \
compl.c compl.h hbuf.c hbuf.h screen.c screen.h logprint.h \
settings.c settings.h hooks.c hooks.h utf8.c utf8.h histolog.c \
- histolog.h utils.c utils.h pgp.c pgp.h help.c help.h otr.c \
- otr.h
-@OTR_TRUE@am__objects_1 = otr.$(OBJEXT)
+ histolog.h utils.c utils.h pgp.c pgp.h fifo.c fifo.h help.c \
+ help.h otr.c otr.h nohtml.c nohtml.h
+@OTR_TRUE@am__objects_1 = otr.$(OBJEXT) nohtml.$(OBJEXT)
am_mcabber_OBJECTS = main.$(OBJEXT) roster.$(OBJEXT) events.$(OBJEXT) \
jabglue.$(OBJEXT) jab_iq.$(OBJEXT) commands.$(OBJEXT) \
compl.$(OBJEXT) hbuf.$(OBJEXT) screen.$(OBJEXT) \
settings.$(OBJEXT) hooks.$(OBJEXT) utf8.$(OBJEXT) \
histolog.$(OBJEXT) utils.$(OBJEXT) pgp.$(OBJEXT) \
- help.$(OBJEXT) $(am__objects_1)
+ fifo.$(OBJEXT) help.$(OBJEXT) $(am__objects_1)
mcabber_OBJECTS = $(am_mcabber_OBJECTS)
mcabber_LDADD = $(LDADD)
am__DEPENDENCIES_1 =
jabglue.h jab_iq.c jab_priv.h commands.c commands.h compl.c \
compl.h hbuf.c hbuf.h screen.c screen.h logprint.h settings.c \
settings.h hooks.c hooks.h utf8.c utf8.h histolog.c histolog.h \
- utils.c utils.h pgp.c pgp.h help.c help.h $(am__append_1)
+ utils.c utils.h pgp.c pgp.h fifo.c fifo.h help.c help.h \
+ $(am__append_1)
LDADD = $(GLIB_LIBS) $(GPGME_LIBS) $(LIBOTR_LIBS) \
../libjabber/liblibjabber.a ../connwrap/libconnwrap.a
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commands.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compl.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/events.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fifo.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hbuf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/help.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/histolog.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jab_iq.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jabglue.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nohtml.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otr.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pgp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/roster.Po@am__quote@
diff --git a/src/commands.c b/src/commands.c
--- a/src/commands.c
+++ b/src/commands.c
/*
* commands.c -- user commands handling
*
- * Copyright (C) 2005-2007 Mikael Berthe <mikael@lilotux.net>
+ * Copyright (C) 2005-2008 Mikael Berthe <mikael@lilotux.net>
*
* 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
*/
#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include "commands.h"
#include "help.h"
#include "settings.h"
#include "events.h"
#include "otr.h"
+#include "utf8.h"
#define IMSTATUS_AWAY "away"
#define IMSTATUS_ONLINE "online"
compl_add_category_word(COMPL_STATUS, "notavail");
compl_add_category_word(COMPL_STATUS, "away");
compl_add_category_word(COMPL_STATUS, "offline");
+ compl_add_category_word(COMPL_STATUS, "message");
// Roster category
compl_add_category_word(COMPL_ROSTER, "bottom");
compl_add_category_word(COMPL_BUFFER, "scroll_lock");
compl_add_category_word(COMPL_BUFFER, "scroll_unlock");
compl_add_category_word(COMPL_BUFFER, "scroll_toggle");
+ compl_add_category_word(COMPL_BUFFER, "list");
// Group category
compl_add_category_word(COMPL_GROUP, "fold");
compl_add_category_word(COMPL_ROOM, "privmsg");
compl_add_category_word(COMPL_ROOM, "remove");
compl_add_category_word(COMPL_ROOM, "role");
+ compl_add_category_word(COMPL_ROOM, "setopt");
compl_add_category_word(COMPL_ROOM, "topic");
compl_add_category_word(COMPL_ROOM, "unban");
compl_add_category_word(COMPL_ROOM, "unlock");
// Locate the end of the word
for (p2 = p1 ; *p2 && (*p2 != ' ') ; p2++)
;
- // Extract the word
+ // Extract the word and look for an alias in the list
word = g_strndup(p1, p2-p1);
-
- // Look for an alias in the list
value = settings_get(SETTINGS_TYPE_ALIAS, (const char*)word);
- if (value) {
- // There is an alias to expand
- newline = g_new(char, strlen(value)+strlen(p2)+2);
- *newline = COMMAND_CHAR;
- strcpy(newline+1, value);
- strcat(newline, p2);
- }
g_free(word);
+ if (value)
+ newline = g_strdup_printf("%c%s%s", COMMAND_CHAR, value, p2);
+
return newline;
}
return 0;
}
if (current_buddy) {
- // Enter chat mode
- scr_set_chatmode(TRUE);
- scr_ShowBuddyWindow();
+ if (buddy_gettype(BUDDATA(current_buddy)) & ROSTER_TYPE_GROUP)
+ do_group("toggle");
+ else {
+ // Enter chat mode
+ scr_set_chatmode(TRUE);
+ scr_ShowBuddyWindow();
+ }
}
return 0;
}
free_arg_lst(paramlst);
}
-// setstatus(recipient, arg)
+// cmd_setstatus(recipient, arg)
// Set your Jabber status.
// - if recipient is not NULL, the status is sent to this contact only
// - arg must be "status message" (message is optional)
-void setstatus(const char *recipient, const char *arg)
+void cmd_setstatus(const char *recipient, const char *arg)
{
char **paramlst;
char *status;
return;
}
+ // It makes sense to reset autoaway before changing the status
+ // (esp. for FIFO or remote commands) or the behaviour could be
+ // unexpected...
+ if (!recipient)
+ scr_CheckAutoAway(TRUE);
+
paramlst = split_arg(arg, 2, 1); // status, message
status = *paramlst;
msg = *(paramlst+1);
else if (!strcasecmp(status, IMSTATUS_DONOTDISTURB)) st = dontdisturb;
else if (!strcasecmp(status, IMSTATUS_NOTAVAILABLE)) st = notavail;
else if (!strcasecmp(status, IMSTATUS_FREE4CHAT)) st = freeforchat;
- else {
+ else if (!strcasecmp(status, "message")) {
+ if (!msg || !*msg) {
+ // We want a message. If there's none, we give up.
+ scr_LogPrint(LPRINT_NORMAL, "Missing parameter.");
+ free_arg_lst(paramlst);
+ return;
+ }
+ st = jb_getstatus(); // Preserve current status
+ } else {
scr_LogPrint(LPRINT_NORMAL, "Unrecognized status!");
free_arg_lst(paramlst);
return;
return;
}
arg = to_utf8(arg);
- setstatus(NULL, arg);
+ cmd_setstatus(NULL, arg);
g_free(arg);
}
msg = to_utf8(msg);
cmdline = g_strdup_printf("%s %s", st, msg);
scr_LogPrint(LPRINT_LOGNORM, "Sending to <%s> /status %s", fjid, cmdline);
- setstatus(fjid, cmdline);
+ cmd_setstatus(fjid, cmdline);
g_free(msg);
g_free(cmdline);
g_free(jid_utf8);
guint leave_buddywindow;
char **paramlst;
char *subcmd;
- enum { group_unfold = 0, group_fold, group_toggle } group_state = 0;
+ enum { group_toggle = -1, group_unfold = 0, group_fold = 1 } group_state = 0;
if (!*arg) {
scr_LogPrint(LPRINT_NORMAL, "Missing parameter.");
if (group_state != group_unfold && leave_buddywindow)
scr_RosterPrevGroup();
- if (group_state == group_unfold)
- buddy_setflags(group, ROSTER_FLAG_HIDE, FALSE);
- else if (group_state == group_fold)
- buddy_setflags(group, ROSTER_FLAG_HIDE, TRUE);
- else if (group_state == group_toggle)
- buddy_setflags(group, ROSTER_FLAG_HIDE,
- !(buddy_getflags(group) & ROSTER_FLAG_HIDE));
+ buddy_hide_group(group, group_state);
buddylist_build();
update_roster = TRUE;
}
static int send_message_to(const char *fjid, const char *msg, const char *subj,
- const char *type_overwrite)
+ const char *type_overwrite, bool quiet)
{
char *bare_jid, *rp;
char *hmsg;
@@ -1100,11 +1113,15 @@ static int send_message_to(const char *fjid, const char *msg, const char *subj,
// We must use the bare jid in hk_message_out()
rp = strchr(fjid, JID_RESOURCE_SEPARATOR);
- if (rp) bare_jid = g_strndup(fjid, rp - fjid);
- else bare_jid = (char*)fjid;
+ if (rp)
+ bare_jid = g_strndup(fjid, rp - fjid);
+ else
+ bare_jid = (char*)fjid;
- // Jump to window, create one if needed
- scr_RosterJumpJid(bare_jid);
+ if (!quiet) {
+ // Jump to window, create one if needed
+ scr_RosterJumpJid(bare_jid);
+ }
// Check if we're sending a message to a conference room
// If not, we must make sure rp is NULL, for hk_message_out()
return;
}
- send_message_to(bjid, msg, subj, type_overwrite);
+ send_message_to(bjid, msg, subj, type_overwrite, FALSE);
}
static const char *scan_mtype(char **arg)
arg = to_utf8(arg);
msg_utf8 = to_utf8(scr_get_multiline());
if (msg_utf8) {
- err = send_message_to(arg, msg_utf8, scr_get_multimode_subj(), msg_type);
+ err = send_message_to(arg, msg_utf8, scr_get_multimode_subj(), msg_type,
+ FALSE);
g_free(msg_utf8);
}
g_free(arg);
free_arg_lst(paramlst);
}
+// load_message_from_file(filename)
+// Read the whole content of a file.
+// The data are converted to UTF8, they should be freed by the caller after
+// use.
+char *load_message_from_file(const char *filename)
+{
+ FILE *fd;
+ struct stat buf;
+ char *msgbuf, *msgbuf_utf8;
+ char *p;
+ char *next_utf8_char;
+ size_t len;
+
+ fd = fopen(filename, "r");
+
+ if (!fd || fstat(fileno(fd), &buf)) {
+ scr_LogPrint(LPRINT_LOGNORM, "Cannot open message file (%s)", filename);
+ return NULL;
+ }
+ if (!buf.st_size || buf.st_size >= HBB_BLOCKSIZE) {
+ if (!buf.st_size)
+ scr_LogPrint(LPRINT_LOGNORM, "Message file is empty (%s)", filename);
+ else
+ scr_LogPrint(LPRINT_LOGNORM, "Message file is too big (%s)", filename);
+ fclose(fd);
+ return NULL;
+ }
+
+ msgbuf = g_new0(char, HBB_BLOCKSIZE);
+ len = fread(msgbuf, 1, HBB_BLOCKSIZE-1, fd);
+ fclose(fd);
+
+ next_utf8_char = msgbuf;
+
+ // Check there is no binary data. It must be a *message* file!
+ for (p = msgbuf ; *p ; p++) {
+ if (utf8_mode) {
+ if (p == next_utf8_char) {
+ if (!iswprint(get_char(p)) && *p != '\n' && *p != '\t')
+ break;
+ next_utf8_char = next_char(p);
+ }
+ } else {
+ unsigned char sc = *p;
+ if (!iswprint(sc) && sc != '\n' && sc != '\t')
+ break;
+ }
+ }
+
+ if (*p || (size_t)(p-msgbuf) != len) { // We're not at the End Of Line...
+ scr_LogPrint(LPRINT_LOGNORM, "Message file contains "
+ "invalid characters (%s)", filename);
+ g_free(msgbuf);
+ return NULL;
+ }
+
+ // p is now at the EOL
+ // Let's strip trailing newlines
+ if (p > msgbuf)
+ p--;
+ while (p > msgbuf && *p == '\n')
+ *p-- = 0;
+
+ // It could be empty, once the trailing newlines are gone
+ if (p == msgbuf && *p == '\n') {
+ scr_LogPrint(LPRINT_LOGNORM, "Message file is empty (%s)", filename);
+ g_free(msgbuf);
+ return NULL;
+ }
+
+ msgbuf_utf8 = to_utf8(msgbuf);
+
+ if (!msgbuf_utf8 && msgbuf)
+ scr_LogPrint(LPRINT_LOGNORM, "Message file charset conversion error (%s)",
+ filename);
+ g_free(msgbuf);
+ return msgbuf_utf8;
+}
+
static void do_say_to(char *arg)
{
char **paramlst;
char *fjid, *msg;
+ char *file = NULL;
const char *msg_type = NULL;
+ bool quiet = FALSE;
if (!jb_getonline()) {
scr_LogPrint(LPRINT_NORMAL, "You are not connected.");
}
msg_type = scan_mtype(&arg);
- paramlst = split_arg(arg, 2, 1); // jid, message
+ paramlst = split_arg(arg, 2, 1); // jid, message (or option, jid, message)
+
+ if (!*paramlst) { // No parameter?
+ scr_LogPrint(LPRINT_NORMAL, "Please specify a Jabber ID.");
+ free_arg_lst(paramlst);
+ return;
+ }
+
+ // Check for an option parameter
+ while (TRUE) {
+ if (!strcmp(*paramlst, "-q")) {
+ char **oldparamlst = paramlst;
+ paramlst = split_arg(*(oldparamlst+1), 2, 1); // jid, message
+ free_arg_lst(oldparamlst);
+ quiet = TRUE;
+ } else if (!strcmp(*paramlst, "-f")) {
+ char **oldparamlst = paramlst;
+ paramlst = split_arg(*(oldparamlst+1), 2, 1); // filename, jid
+ free_arg_lst(oldparamlst);
+ file = g_strdup(*paramlst);
+ // One more parameter shift...
+ oldparamlst = paramlst;
+ paramlst = split_arg(*(oldparamlst+1), 2, 1); // jid, nothing
+ free_arg_lst(oldparamlst);
+ } else
+ break;
+ }
+
fjid = *paramlst;
msg = *(paramlst+1);
- if (!fjid || !strcmp(fjid, ".")) {
- scr_LogPrint(LPRINT_NORMAL, "Please specify a Jabber ID.");
+ if (!strcmp(fjid, ".")) {
+ // Send the message to the current buddy
+ if (current_buddy)
+ fjid = (char*)buddy_getjid(BUDDATA(current_buddy));
+ if (!fjid) {
+ scr_LogPrint(LPRINT_NORMAL, "Please specify a Jabber ID.");
+ free_arg_lst(paramlst);
+ return;
+ }
+ } else if (check_jid_syntax(fjid)) {
+ scr_LogPrint(LPRINT_NORMAL, "Please specify a valid Jabber ID.");
free_arg_lst(paramlst);
return;
}
fjid = to_utf8(fjid);
- msg = to_utf8(msg);
+ if (!file) {
+ msg = to_utf8(msg);
+ } else {
+ char *filename_xp;
+ if (msg)
+ scr_LogPrint(LPRINT_NORMAL, "say_to: extra parameter ignored.");
+ filename_xp = expand_filename(file);
+ msg = load_message_from_file(filename_xp);
+ g_free(filename_xp);
+ g_free(file);
+ }
- send_message_to(fjid, msg, NULL, msg_type);
+ send_message_to(fjid, msg, NULL, msg_type, quiet);
g_free(fjid);
g_free(msg);
buffer_date(arg);
} else if (*subcmd == '%') {
buffer_percent(subcmd+1, arg);
-#ifdef DEBUG_ENABLE
} else if (!strcasecmp(subcmd, "list")) {
scr_BufferList();
-#endif
} else {
scr_LogPrint(LPRINT_NORMAL, "Unrecognized parameter!");
}
group_utf8 = to_utf8(newgroupname);
if (strcmp(oldgroupname, group_utf8)) {
+ guint msgflag;
+
jb_updatebuddy(bjid, name, *group_utf8 ? group_utf8 : NULL);
scr_RosterUp();
+
+ // If the buddy has a pending message flag,
+ // we remove it temporarily in order to reset the global group
+ // flag. We set it back once the buddy is in the new group,
+ // which will update the new group's flag.
+ msgflag = buddy_getflags(bud) & ROSTER_FLAG_MSG;
+ if (msgflag)
+ roster_msg_setflag(bjid, FALSE, FALSE);
buddy_setgroup(bud, group_utf8);
+ if (msgflag)
+ roster_msg_setflag(bjid, FALSE, TRUE);
}
g_free(group_utf8);
// If no nickname is provided with the /join command,
// we try to get a default nickname.
if (!nick || !*nick)
- nick = default_muc_nickname();
+ nick = default_muc_nickname(roomname);
else
nick = to_utf8(nick);
// If we still have no nickname, give up
static void room_ban(gpointer bud, char *arg)
{
char **paramlst;
- gchar *fjid;
+ gchar *fjid, *bjid;
+ const gchar *banjid;
gchar *jid_utf8, *reason_utf8;
struct role_affil ra;
const char *roomid = buddy_getjid(bud);
ra.type = type_affil;
ra.val.affil = affil_outcast;
- jid_utf8 = to_utf8(fjid);
+ bjid = jidtodisp(fjid);
+ jid_utf8 = to_utf8(bjid);
+
+ // If the argument doesn't look like a jid, we'll try to find a matching
+ // nickname.
+ if (!strchr(bjid, JID_DOMAIN_SEPARATOR) || check_jid_syntax(bjid)) {
+ const gchar *tmp;
+ // We want the initial argument, so the fjid variable, because
+ // we don't want to strip a resource-like string from the nickname!
+ g_free(jid_utf8);
+ jid_utf8 = to_utf8(fjid);
+ tmp = buddy_getrjid(bud, jid_utf8);
+ if (!tmp) {
+ scr_LogPrint(LPRINT_NORMAL, "Wrong JID or nickname");
+ goto room_ban_return;
+ }
+ banjid = jidtodisp(tmp);
+ } else
+ banjid = jid_utf8;
+
+ scr_LogPrint(LPRINT_NORMAL, "Requesting a ban for %s", banjid);
+
reason_utf8 = to_utf8(arg);
- jb_room_setattrib(roomid, jid_utf8, NULL, ra, reason_utf8);
- g_free(jid_utf8);
+ jb_room_setattrib(roomid, banjid, NULL, ra, reason_utf8);
g_free(reason_utf8);
+room_ban_return:
+ g_free(bjid);
+ g_free(jid_utf8);
free_arg_lst(paramlst);
}
free_arg_lst(paramlst);
}
-void room_leave(gpointer bud, char *arg)
+void cmd_room_leave(gpointer bud, char *arg)
{
gchar *roomid, *desc;
const char *nickname;
mc_strtolower(roomname_tmp);
roomname = to_utf8(roomname_tmp);
g_free(roomname_tmp);
+
nick = to_utf8(arg);
+ strip_arg_special_chars(nick);
jb_room_join(roomname, nick, NULL);
g_free(roomname);
fjid = g_strdup_printf("%s/%s", buddy_getjid(bud), nick);
fjid_utf8 = to_utf8(fjid);
msg = to_utf8(arg);
- send_message_to(fjid_utf8, msg, NULL, NULL);
+ send_message_to(fjid_utf8, msg, NULL, NULL, FALSE);
g_free(fjid);
g_free(fjid_utf8);
g_free(msg);
static void room_topic(gpointer bud, char *arg)
{
- gchar *msg;
-
if (!buddy_getinsideroom(bud)) {
scr_LogPrint(LPRINT_NORMAL, "You are not in this room.");
return;
arg = to_utf8(arg);
// Set the topic
- msg = g_strdup_printf("%s has set the topic to: %s", mkcmdstr("me"), arg);
- jb_send_msg(buddy_getjid(bud), msg, ROSTER_TYPE_ROOM, arg, NULL, NULL, NULL);
+ jb_send_msg(buddy_getjid(bud), NULL, ROSTER_TYPE_ROOM, arg, NULL, NULL, NULL);
g_free(arg);
- g_free(msg);
}
static void room_destroy(gpointer bud, char *arg)
jb_room_unlock(buddy_getjid(bud));
}
-// room_whois(..)
+static void room_setopt(gpointer bud, char *arg)
+{
+ char **paramlst;
+ char *param, *value;
+ enum { opt_none = 0, opt_printstatus, opt_autowhois } option = 0;
+
+ paramlst = split_arg(arg, 2, 1); // param, value
+ param = *paramlst;
+ value = *(paramlst+1);
+ if (!param) {
+ scr_LogPrint(LPRINT_NORMAL, "Please specify a room option.");
+ free_arg_lst(paramlst);
+ return;
+ }
+
+ if (!strcasecmp(param, "print_status"))
+ option = opt_printstatus;
+ else if (!strcasecmp(param, "auto_whois"))
+ option = opt_autowhois;
+ else {
+ scr_LogPrint(LPRINT_NORMAL, "Wrong option!");
+ free_arg_lst(paramlst);
+ return;
+ }
+
+ // If no value is given, display the current value
+ if (!value) {
+ const char *strval;
+ if (option == opt_printstatus)
+ strval = strprintstatus[buddy_getprintstatus(bud)];
+ else
+ strval = strautowhois[buddy_getautowhois(bud)];
+ scr_LogPrint(LPRINT_NORMAL, "%s is set to: %s", param, strval);
+ free_arg_lst(paramlst);
+ return;
+ }
+
+ if (option == opt_printstatus) {
+ enum room_printstatus eval;
+ if (!strcasecmp(value, "none"))
+ eval = status_none;
+ else if (!strcasecmp(value, "in_and_out"))
+ eval = status_in_and_out;
+ else if (!strcasecmp(value, "all"))
+ eval = status_all;
+ else {
+ eval = status_default;
+ if (strcasecmp(value, "default") != 0)
+ scr_LogPrint(LPRINT_NORMAL, "Unrecognized value, assuming default...");
+ }
+ buddy_setprintstatus(bud, eval);
+ } else if (option == opt_autowhois) {
+ enum room_autowhois eval;
+ if (!strcasecmp(value, "on"))
+ eval = autowhois_on;
+ else if (!strcasecmp(value, "off"))
+ eval = autowhois_off;
+ else {
+ eval = autowhois_default;
+ if (strcasecmp(value, "default") != 0)
+ scr_LogPrint(LPRINT_NORMAL, "Unrecognized value, assuming default...");
+ }
+ buddy_setautowhois(bud, eval);
+ }
+
+ free_arg_lst(paramlst);
+}
+
+// cmd_room_whois(..)
// If interactive is TRUE, chatmode can be enabled.
-void room_whois(gpointer bud, char *arg, guint interactive)
+void cmd_room_whois(gpointer bud, char *arg, guint interactive)
{
char **paramlst;
gchar *nick, *buffer;
enum imrole role;
enum imaffiliation affil;
time_t rst_time;
+ guint msg_flag = HBB_PREFIX_INFO;
paramlst = split_arg(arg, 1, 0); // nickname
nick = *paramlst;
// Enter chat mode
scr_set_chatmode(TRUE);
scr_ShowBuddyWindow();
- }
+ } else
+ msg_flag |= HBB_PREFIX_NOFLAG;
bjid = buddy_getjid(bud);
rstatus = buddy_getstatus(bud, nick);
buffer = g_new(char, 4096);
snprintf(buffer, 4095, "Whois [%s]", nick);
- scr_WriteIncomingMessage(bjid, buffer, 0, HBB_PREFIX_INFO, 0);
+ scr_WriteIncomingMessage(bjid, buffer, 0, msg_flag, 0);
snprintf(buffer, 4095, "Status : [%c] %s", imstatus2char[rstatus],
rst_msg);
- scr_WriteIncomingMessage(bjid, buffer,
- 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
+ scr_WriteIncomingMessage(bjid, buffer, 0, msg_flag | HBB_PREFIX_CONT, 0);
if (rst_time) {
char tbuf[128];
strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M:%S", localtime(&rst_time));
snprintf(buffer, 127, "Timestamp: %s", tbuf);
- scr_WriteIncomingMessage(bjid, buffer,
- 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
+ scr_WriteIncomingMessage(bjid, buffer, 0, msg_flag | HBB_PREFIX_CONT, 0);
}
if (realjid) {
snprintf(buffer, 4095, "JID : <%s>", realjid);
- scr_WriteIncomingMessage(bjid, buffer,
- 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
+ scr_WriteIncomingMessage(bjid, buffer, 0, msg_flag | HBB_PREFIX_CONT, 0);
}
snprintf(buffer, 4095, "Role : %s", strrole[role]);
- scr_WriteIncomingMessage(bjid, buffer,
- 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
+ scr_WriteIncomingMessage(bjid, buffer, 0, msg_flag | HBB_PREFIX_CONT, 0);
snprintf(buffer, 4095, "Affiliat.: %s", straffil[affil]);
- scr_WriteIncomingMessage(bjid, buffer,
- 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
+ scr_WriteIncomingMessage(bjid, buffer, 0, msg_flag | HBB_PREFIX_CONT, 0);
snprintf(buffer, 4095, "Priority : %d", rprio);
- scr_WriteIncomingMessage(bjid, buffer,
- 0, HBB_PREFIX_INFO | HBB_PREFIX_CONT, 0);
+ scr_WriteIncomingMessage(bjid, buffer, 0, msg_flag | HBB_PREFIX_CONT, 0);
- scr_WriteIncomingMessage(bjid, "End of WHOIS", 0, HBB_PREFIX_INFO, 0);
+ scr_WriteIncomingMessage(bjid, "End of WHOIS", 0, msg_flag, 0);
g_free(buffer);
g_free(nick);
{
const char *roomid;
const char *name = NULL, *nick = NULL;
+ enum room_autowhois autowhois = 0;
+ enum room_printstatus printstatus = 0;
enum { bm_add = 0, bm_del = 1 } action = 0;
int autojoin = 0;
if (action == bm_add) {
name = buddy_getname(bud);
nick = buddy_getnickname(bud);
+ printstatus = buddy_getprintstatus(bud);
+ autowhois = buddy_getautowhois(bud);
}
- jb_set_storage_bookmark(roomid, name, nick, NULL, autojoin);
+ jb_set_storage_bookmark(roomid, name, nick, NULL, autojoin,
+ printstatus, autowhois);
}
static void display_all_bookmarks(void)
room_kick(bud, arg);
} else if (!strcasecmp(subcmd, "leave")) {
if ((arg = check_room_subcommand(arg, FALSE, bud)) != NULL)
- room_leave(bud, arg);
+ cmd_room_leave(bud, arg);
} else if (!strcasecmp(subcmd, "names")) {
if ((arg = check_room_subcommand(arg, FALSE, bud)) != NULL)
room_names(bud, arg);
} else if (!strcasecmp(subcmd, "unlock")) {
if ((arg = check_room_subcommand(arg, FALSE, bud)) != NULL)
room_unlock(bud, arg);
+ } else if (!strcasecmp(subcmd, "setopt")) {
+ if ((arg = check_room_subcommand(arg, FALSE, bud)) != NULL)
+ room_setopt(bud, arg);
} else if (!strcasecmp(subcmd, "topic")) {
if ((arg = check_room_subcommand(arg, FALSE, bud)) != NULL)
room_topic(bud, arg);
} else if (!strcasecmp(subcmd, "whois")) {
if ((arg = check_room_subcommand(arg, TRUE, bud)) != NULL)
- room_whois(bud, arg, TRUE);
+ cmd_room_whois(bud, arg, TRUE);
} else if (!strcasecmp(subcmd, "bookmark")) {
if (!arg && !buddy_getjid(BUDDATA(current_buddy)) &&
buddy_gettype(BUDDATA(current_buddy)) == ROSTER_TYPE_SPECIAL)
static void do_disconnect(char *arg)
{
jb_disconnect();
- AutoConnection = false;
+ AutoConnection = FALSE;
}
static void do_help(char *arg)
diff --git a/src/commands.h b/src/commands.h
--- a/src/commands.h
+++ b/src/commands.h
extern void mcabber_connect(void);
extern void mcabber_set_terminate_ui(void);
-void room_whois(gpointer bud, char *nick_locale, guint interactive);
-void room_leave(gpointer bud, char *arg);
-void setstatus(const char *recipient, const char *arg);
+void cmd_room_whois(gpointer bud, char *nick_locale, guint interactive);
+void cmd_room_leave(gpointer bud, char *arg);
+void cmd_setstatus(const char *recipient, const char *arg);
#endif /* __COMMANDS_H__ */
diff --git a/src/compl.c b/src/compl.c
--- a/src/compl.c
+++ b/src/compl.c
/*
* compl.c -- Completion system
*
- * Copyright (C) 2005-2007 Mikael Berthe <mikael@lilotux.net>
+ * Copyright (C) 2005-2008 Mikael Berthe <mikael@lilotux.net>
*
* 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
diff --git a/src/events.c b/src/events.c
--- a/src/events.c
+++ b/src/events.c
/*
* events.c -- Events fonctions
*
- * Copyright (C) 2006-2007 Mikael Berthe <mikael@lilotux.net>
+ * Copyright (C) 2006-2008 Mikael Berthe <mikael@lilotux.net>
*
* 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
diff --git a/src/fifo.c b/src/fifo.c
--- /dev/null
+++ b/src/fifo.c
@@ -0,0 +1,180 @@
+/*
+ * fifo.c -- Read commands from a named pipe
+ *
+ * Copyright (C) 2008 Mikael Berthe <mikael@lilotux.net>
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#include <stdio.h>
+#include <glib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include "commands.h"
+#include "logprint.h"
+#include "utils.h"
+#include "settings.h"
+
+#include "hbuf.h" // For HBB_BLOCKSIZE
+
+static FILE *sfd;
+static char *fifo_name;
+
+
+// fifo_init(fifo_path)
+// Create and open the FIFO file.
+// If fifo_path is NULL, reopen the current pipe.
+// Return 0 (success) or -1 (failure).
+int fifo_init(const char *fifo_path)
+{
+ struct stat buf;
+ int fd;
+ char *fifo_path_xp;
+
+ if (!sfd && !fifo_path)
+ return -1; // Nothing to do...
+
+ if (sfd && !fifo_path) { // We want to reinitialize the pipe
+ fclose(sfd);
+ sfd = NULL;
+ if (fifo_name)
+ goto fifo_init_open;
+ }
+ sfd = NULL;
+
+ fifo_path_xp = expand_filename(fifo_path);
+
+ if (!stat(fifo_path_xp, &buf)) {
+ if (!S_ISFIFO(buf.st_mode)) {
+ scr_LogPrint(LPRINT_LOGNORM, "WARNING: Cannot create the FIFO. "
+ "%s already exists and is not a pipe", fifo_path_xp);
+ g_free(fifo_path_xp);
+ return -1;
+ }
+
+ if (unlink(fifo_path_xp)) {
+ scr_LogPrint(LPRINT_LOGNORM, "WARNING: Unable to unlink FIFO %s [%s]",
+ fifo_path_xp, g_strerror(errno));
+ g_free(fifo_path_xp);
+ return -1;
+ }
+ }
+
+ if (mkfifo(fifo_path_xp, S_IWUSR | S_IRUSR)) {
+ scr_LogPrint(LPRINT_LOGNORM, "WARNING: Cannot create the FIFO [%s]",
+ g_strerror(errno));
+ g_free(fifo_path_xp);
+ return -1;
+ }
+
+ fifo_name = fifo_path_xp;
+
+fifo_init_open:
+ fd = open(fifo_name, O_RDONLY | O_NONBLOCK);
+ if (!fd)
+ return -1;
+
+ sfd = fdopen(fd, "r");
+ if (fifo_path)
+ scr_LogPrint(LPRINT_LOGNORM, "FIFO initialized (%s)", fifo_name);
+ return 0;
+}
+
+// fifo_deinit()
+// Close the current FIFO pipe and delete it.
+void fifo_deinit(void)
+{
+ if (sfd) {
+ fclose(sfd);
+ sfd = NULL;
+ }
+ if (fifo_name) {
+ unlink(fifo_name);
+ g_free(fifo_name);
+ fifo_name = NULL;
+ }
+}
+
+// fifo_read()
+// Read a line from the FIFO pipe (if available), and execute it.
+void fifo_read(void)
+{
+ struct timeval tv;
+ fd_set fds;
+ char *getbuf;
+ char buf[HBB_BLOCKSIZE+1];
+ int fd;
+
+ if (!sfd) {
+ return;
+ }
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+
+ fd = fileno(sfd);
+
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+
+ select(fd + 1, &fds, NULL, NULL, &tv);
+
+ if (!FD_ISSET(fd, &fds)) {
+ return;
+ }
+
+ getbuf = fgets(buf, HBB_BLOCKSIZE, sfd);
+ if (getbuf) {
+ guint logflag;
+ char *eol = buf;
+
+ // Strip trailing newlines
+ for ( ; *eol ; eol++)
+ ;
+ if (eol > buf)
+ eol--;
+ while (eol > buf && *eol == '\n')
+ *eol-- = 0;
+
+ if (settings_opt_get_int("fifo_hide_commands"))
+ logflag = LPRINT_LOG;
+ else
+ logflag = LPRINT_LOGNORM;
+ scr_LogPrint(logflag, "Executing FIFO command: %s", buf);
+ if (process_command(buf, TRUE) == 255)
+ mcabber_set_terminate_ui();
+ } else {
+ if (feof(sfd))
+ fifo_init(NULL); // Reopen the FIFO on EOF
+ }
+}
+
+// fifo_get_fd()
+// Return the FIFO file descriptor (-1 if none).
+int fifo_get_fd(void)
+{
+ if (sfd)
+ return fileno(sfd);
+ return -1;
+}
+
+/* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */
diff --git a/src/fifo.h b/src/fifo.h
--- /dev/null
+++ b/src/fifo.h
@@ -0,0 +1,11 @@
+#ifndef __FIFO_H__
+#define __FIFO_H__ 1
+
+int fifo_init(const char *fifo_path);
+void fifo_deinit(void);
+void fifo_read(void);
+int fifo_get_fd(void);
+
+#endif /* __FIFO_H__ */
+
+/* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */
diff --git a/src/hbuf.c b/src/hbuf.c
--- a/src/hbuf.c
+++ b/src/hbuf.c
/*
* hbuf.c -- History buffer implementation
*
- * Copyright (C) 2005-2007 Mikael Berthe <mikael@lilotux.net>
+ * Copyright (C) 2005-2008 Mikael Berthe <mikael@lilotux.net>
*
* 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
return g_list_nth(hbuf, pc*hlen/100);
}
-#ifdef DEBUG_ENABLE
// hbuf_get_blocks_number()
// Returns the number of allocated hbuf_block's.
guint hbuf_get_blocks_number(GList *hbuf)
}
return count;
}
-#endif
/* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */
diff --git a/src/hbuf.h b/src/hbuf.h
--- a/src/hbuf.h
+++ b/src/hbuf.h
GList *hbuf_jump_date(GList *hbuf, time_t t);
GList *hbuf_jump_percent(GList *hbuf, int pc);
-#ifdef DEBUG_ENABLE
guint hbuf_get_blocks_number(GList *p_hbuf);
-#endif
#endif /* __HBUF_H__ */
diff --git a/src/help.c b/src/help.c
--- a/src/help.c
+++ b/src/help.c
/*
* help.c -- Help command
*
- * Copyright (C) 2006-2007 Mikael Berthe <mikael@lilotux.net>
+ * Copyright (C) 2006-2008 Mikael Berthe <mikael@lilotux.net>
*
* 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
diff --git a/src/histolog.c b/src/histolog.c
--- a/src/histolog.c
+++ b/src/histolog.c
/*
* histolog.c -- File history handling
*
- * Copyright (C) 2005-2007 Mikael Berthe <mikael@lilotux.net>
+ * Copyright (C) 2005-2008 Mikael Berthe <mikael@lilotux.net>
*
* 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
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <unistd.h>
#include "histolog.h"
#include "hbuf.h"
#include "jabglue.h"
#include "utils.h"
-#include "logprint.h"
+#include "screen.h"
#include "settings.h"
#include "utils.h"
+#include "roster.h"
static guint UseFileLogging;
static guint FileLoadLogs;
char *filename;
guchar type, info;
char *data, *tail;
+ guint data_size;
char *xtext;
time_t timestamp;
guint prefix_flags;
(settings_opt_get_int("load_muc_logs") != 1))
return;
- data = g_new(char, HBB_BLOCKSIZE+32);
+ data_size = HBB_BLOCKSIZE+32;
+ data = g_new(char, data_size);
if (!data) {
scr_LogPrint(LPRINT_LOGNORM, "Not enough memory to read history file");
return;
/* See write_histo_line() for line format... */
while (!feof(fp)) {
guint dataoffset = 25;
+ guint noeol;
- if (fgets(data, HBB_BLOCKSIZE+27, fp) == NULL)
+ if (fgets(data, data_size-1, fp) == NULL)
break;
ln++;
- for (tail = data; *tail; tail++) ;
+ while (1) {
+ for (tail = data; *tail; tail++) ;
+ noeol = (*(tail-1) != '\n');
+ if (!noeol)
+ break;
+ /* TODO: duplicated code... could do better... */
+ if (tail == data + data_size-2) {
+ // The buffer is too small to contain the whole line.
+ // Let's allocate some more space.
+ if (!max_num_of_blocks ||
+ data_size/HBB_BLOCKSIZE < 5U*max_num_of_blocks) {
+ guint toffset = tail - data;
+ // Allocate one more block.
+ data_size = HBB_BLOCKSIZE * (1 + data_size/HBB_BLOCKSIZE);
+ data = g_renew(char, data, data_size);
+ // Update the tail pointer, as the data may have been moved.
+ tail = data + toffset;
+ if (fgets(tail, data_size-1 - (tail-data), fp) == NULL)
+ break;
+ } else {
+ scr_LogPrint(LPRINT_LOGNORM, "Line too long in history file!");
+ ln--;
+ break;
+ }
+ }
+ }
type = data[0];
info = data[1];
continue;
}
- // XXX This will fail when a message is too big
while (len--) {
ln++;
- if (fgets(tail, HBB_BLOCKSIZE+27 - (tail-data), fp) == NULL)
+ if (fgets(tail, data_size-1 - (tail-data), fp) == NULL)
break;
while (*tail) tail++;
- }
- // Small check for too long messages
- if (tail >= HBB_BLOCKSIZE+dataoffset+1 + data) {
- // Maybe we will have a parse error on next, because this
- // message is big (maybe too big).
- scr_LogPrint(LPRINT_LOGNORM, "A message could be too big "
- "in history file...");
+ noeol = (*(tail-1) != '\n');
+ if (tail == data + data_size-2 && (len || noeol)) {
+ // The buffer is too small to contain the whole message.
+ // Let's allocate some more space.
+ if (!max_num_of_blocks ||
+ data_size/HBB_BLOCKSIZE < 5U*max_num_of_blocks) {
+ guint toffset = tail - data;
+ // If the line hasn't been read completely and we reallocate the
+ // buffer, we want to read one more time.
+ if (noeol)
+ len++;
+ // Allocate one more block.
+ data_size = HBB_BLOCKSIZE * (1 + data_size/HBB_BLOCKSIZE);
+ data = g_renew(char, data, data_size);
+ // Update the tail pointer, as the data may have been moved.
+ tail = data + toffset;
+ } else {
+ // There will probably be a parse error on next read, because
+ // this message hasn't been read entirely.
+ scr_LogPrint(LPRINT_LOGNORM, "Message too big in history file!");
+ }
+ }
}
// Remove last CR (we keep it if the line is empty, too)
if ((tail > data+dataoffset+1) && (*(tail-1) == '\n'))
}
}
+guint hlog_is_enabled(void)
+{
+ return UseFileLogging;
+}
+
inline void hlog_write_message(const char *bjid, time_t timestamp, int sent,
const char *msg)
{
status_msg);
}
+
+// hlog_save_state()
+// If enabled, save the current state of the roster
+// (i.e. pending messages) to a temporary file.
+void hlog_save_state(void)
+{
+ gpointer unread_ptr, first_unread;
+ const char *bjid;
+ char *statefile_xp;
+ FILE *fp;
+ const char *statefile = settings_opt_get("statefile");
+
+ if (!statefile || !UseFileLogging)
+ return;
+
+ statefile_xp = expand_filename(statefile);
+ fp = fopen(statefile_xp, "w");
+ if (!fp) {
+ scr_LogPrint(LPRINT_NORMAL, "Cannot open state file [%s]",
+ strerror(errno));
+ goto hlog_save_state_return;
+ }
+
+ if (!jb_getonline()) {
+ // We're not connected. Let's use the unread_jids hash.
+ GList *unread_jid = unread_jid_get_list();
+ unread_ptr = unread_jid;
+ for ( ; unread_jid ; unread_jid = g_list_next(unread_jid))
+ fprintf(fp, "%s\n", (char*)unread_jid->data);
+ g_list_free(unread_ptr);
+ goto hlog_save_state_return;
+ }
+
+ if (!current_buddy) // Safety check -- shouldn't happen.
+ goto hlog_save_state_return;
+
+ // We're connected. Let's use unread_msg().
+ unread_ptr = first_unread = unread_msg(NULL);
+ if (!first_unread)
+ goto hlog_save_state_return;
+
+ do {
+ guint type = buddy_gettype(unread_ptr);
+ if (type & (ROSTER_TYPE_USER|ROSTER_TYPE_AGENT)) {
+ bjid = buddy_getjid(unread_ptr);
+ if (bjid)
+ fprintf(fp, "%s\n", bjid);
+ }
+ unread_ptr = unread_msg(unread_ptr);
+ } while (unread_ptr && unread_ptr != first_unread);
+
+hlog_save_state_return:
+ if (fp) {
+ long filelen = ftell(fp);
+ fclose(fp);
+ if (!filelen)
+ unlink(statefile_xp);
+ }
+ g_free(statefile_xp);
+}
+
+// hlog_load_state()
+// If enabled, load the current state of the roster
+// (i.e. pending messages) from a temporary file.
+// This function adds the JIDs to the unread_jids hash table,
+// so it should only be called at startup.
+void hlog_load_state(void)
+{
+ char bjid[1024];
+ char *statefile_xp;
+ FILE *fp;
+ const char *statefile = settings_opt_get("statefile");
+
+ if (!statefile || !UseFileLogging)
+ return;
+
+ statefile_xp = expand_filename(statefile);
+ fp = fopen(statefile_xp, "r");
+ if (fp) {
+ char *eol;
+ while (!feof(fp)) {
+ if (fgets(bjid, sizeof bjid, fp) == NULL)
+ break;
+ // Let's remove the trailing newline.
+ // Also remove whitespace, if the file as been (badly) manually modified.
+ for (eol = bjid; *eol; eol++) ;
+ for (eol--; eol >= bjid && (*eol == '\n' || *eol == ' '); *eol-- = 0) ;
+ // Safety checks...
+ if (!bjid[0])
+ continue;
+ if (check_jid_syntax(bjid)) {
+ scr_LogPrint(LPRINT_LOGNORM,
+ "ERROR: Invalid JID in state file. Corrupted file?");
+ break;
+ }
+ // Display a warning if there are pending messages but the user
+ // won't see them because load_log isn't set.
+ if (!FileLoadLogs) {
+ scr_LogPrint(LPRINT_LOGNORM, "WARNING: unread message from <%s>.",
+ bjid);
+ scr_setmsgflag_if_needed(SPECIAL_BUFFER_STATUS_ID, TRUE);
+ }
+ // Add the JID to unread_jids. It will be used when the contact is
+ // added to the roster.
+ unread_jid_add(bjid);
+ }
+ fclose(fp);
+ }
+ g_free(statefile_xp);
+}
+
/* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */
diff --git a/src/histolog.h b/src/histolog.h
--- a/src/histolog.h
+++ b/src/histolog.h
void hlog_enable(guint enable, const char *root_dir, guint loadfile);
char *hlog_get_log_jid(const char *bjid);
void hlog_read_history(const char *bjid, GList **p_buddyhbuf, guint width);
-inline void hlog_write_message(const char *bjid, time_t timestamp, int sent,
- const char *msg);
-inline void hlog_write_status(const char *bjid, time_t timestamp,
- enum imstatus status, const char *status_msg);
+void hlog_write_message(const char *bjid, time_t timestamp, int sent,
+ const char *msg);
+void hlog_write_status(const char *bjid, time_t timestamp,
+ enum imstatus status, const char *status_msg);
+void hlog_save_state(void);
+void hlog_load_state(void);
#endif /* __HISTOLOG_H__ */
diff --git a/src/hooks.c b/src/hooks.c
--- a/src/hooks.c
+++ b/src/hooks.c
/*
* hooks.c -- Hooks layer
*
- * Copyright (C) 2005-2007 Mikael Berthe <mikael@lilotux.net>
+ * Copyright (C) 2005-2008 Mikael Berthe <mikael@lilotux.net>
*
* 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
#include "utils.h"
#include "utf8.h"
#include "commands.h"
+#include "fifo.h"
static char *extcmd;
static const char *COMMAND_ME = "/me ";
-inline void hk_message_in(const char *bjid, const char *resname,
+void hk_mainloop(void)
+{
+ /*
+ static time_t last;
+ time_t now;
+
+ time(&now);
+
+ if (now > last + 1) {
+ // custom_hook();
+ last = now;
+ }
+ */
+ fifo_read();
+}
+
+void hk_message_in(const char *bjid, const char *resname,
time_t timestamp, const char *msg, const char *type,
guint encrypted)
{
char *wmsg = NULL, *bmsg = NULL, *mmsg = NULL;
GSList *roster_usr;
unsigned mucnicklen = 0;
+ const char *ename = NULL;
if (encrypted)
message_flags |= HBB_PREFIX_PGPCRYPT;
}
}
+ if (settings_opt_get_int("eventcmd_use_nickname"))
+ ename = roster_getname(bjid);
+
// External command
// - We do not call hk_ext_cmd() for history lines in MUC
// - We do call hk_ext_cmd() for private messages in a room
// - We do call hk_ext_cmd() for messages to the current window
if (!active_window && ((is_groupchat && !timestamp) || !is_groupchat))
- hk_ext_cmd(bjid, (is_groupchat ? 'G' : 'M'), 'R', wmsg);
+ hk_ext_cmd(ename ? ename : bjid, (is_groupchat ? 'G' : 'M'), 'R', wmsg);
// Display the sender in the log window
if ((!is_groupchat) && !(message_flags & HBB_PREFIX_ERR) &&
// hk_message_out()
// nick should be set for private messages in a chat room, and null for
// normal messages.
-inline void hk_message_out(const char *bjid, const char *nick,
+void hk_message_out(const char *bjid, const char *nick,
time_t timestamp, const char *msg, guint encrypted)
{
char *wmsg = NULL, *bmsg = NULL, *mmsg = NULL;
g_free(mmsg);
}
-inline void hk_statuschange(const char *bjid, const char *resname, gchar prio,
+void hk_statuschange(const char *bjid, const char *resname, gchar prio,
time_t timestamp, enum imstatus status,
const char *status_msg)
{
- int buddy_format;
int st_in_buf;
enum imstatus oldstat;
- char *bn = NULL;
+ char *bn;
char *logsmsg;
const char *rn = (resname ? resname : "");
+ const char *ename = NULL;
+
+ if (settings_opt_get_int("eventcmd_use_nickname"))
+ ename = roster_getname(bjid);
+
+ oldstat = roster_getstatus(bjid, resname);
st_in_buf = settings_opt_get_int("show_status_in_buffer");
- buddy_format = settings_opt_get_int("buddy_format");
- if (buddy_format) {
- const char *name = roster_getname(bjid);
- if (name && strcmp(name, bjid)) {
- if (buddy_format == 1)
- bn = g_strdup_printf("%s <%s/%s>", name, bjid, rn);
- else if (buddy_format == 2)
- bn = g_strdup_printf("%s/%s", name, rn);
- else if (buddy_format == 3)
- bn = g_strdup_printf("%s", name);
+
+ if (settings_opt_get_int("log_display_presence")) {
+ int buddy_format = settings_opt_get_int("buddy_format");
+ bn = NULL;
+ if (buddy_format) {
+ const char *name = roster_getname(bjid);
+ if (name && strcmp(name, bjid)) {
+ if (buddy_format == 1)
+ bn = g_strdup_printf("%s <%s/%s>", name, bjid, rn);
+ else if (buddy_format == 2)
+ bn = g_strdup_printf("%s/%s", name, rn);
+ else if (buddy_format == 3)
+ bn = g_strdup_printf("%s", name);
+ }
}
- }
- if (!bn) {
- bn = g_strdup_printf("<%s/%s>", bjid, rn);
- }
+ if (!bn)
+ bn = g_strdup_printf("<%s/%s>", bjid, rn);
- logsmsg = g_strdup(status_msg ? status_msg : "");
- replace_nl_with_dots(logsmsg);
+ logsmsg = g_strdup(status_msg ? status_msg : "");
+ replace_nl_with_dots(logsmsg);
- oldstat = roster_getstatus(bjid, resname);
- scr_LogPrint(LPRINT_LOGNORM, "Buddy status has changed: [%c>%c] %s %s",
- imstatus2char[oldstat], imstatus2char[status], bn, logsmsg);
- g_free(logsmsg);
- g_free(bn);
+ scr_LogPrint(LPRINT_LOGNORM, "Buddy status has changed: [%c>%c] %s %s",
+ imstatus2char[oldstat], imstatus2char[status], bn, logsmsg);
+ g_free(logsmsg);
+ g_free(bn);
+ }
if (st_in_buf == 2 ||
(st_in_buf == 1 && (status == offline || oldstat == offline))) {
@@ -320,10 +348,10 @@ inline void hk_statuschange(const char *bjid, const char *resname, gchar prio,
scr_DrawRoster();
hlog_write_status(bjid, timestamp, status, status_msg);
// External command
- hk_ext_cmd(bjid, 'S', imstatus2char[status], NULL);
+ hk_ext_cmd(ename ? ename : bjid, 'S', imstatus2char[status], NULL);
}
-inline void hk_mystatuschange(time_t timestamp, enum imstatus old_status,
+void hk_mystatuschange(time_t timestamp, enum imstatus old_status,
enum imstatus new_status, const char *msg)
{
scr_LogPrint(LPRINT_LOGNORM, "Your status has been set: [%c>%c] %s",
char *arg_data = NULL;
char status_str[2];
char *datafname = NULL;
+ char unread_str[16];
if (!extcmd) return;
// Prepare arg_* (external command parameters)
switch (type) {
- case 'M':
+ case 'M': /* Normal message */
arg_type = "MSG";
if (info == 'R')
arg_info = "IN";
else if (info == 'S')
arg_info = "OUT";
break;
- case 'G':
+ case 'G': /* Groupchat message */
arg_type = "MSG";
arg_info = "MUC";
break;
- case 'S':
+ case 'S': /* Status change */
arg_type = "STATUS";
if (strchr(imstatus2char, tolower(info))) {
status_str[0] = toupper(info);
arg_info = status_str;
}
break;
+ case 'U': /* Unread buffer count */
+ arg_type = "UNREAD";
+ g_snprintf(unread_str, sizeof unread_str, "%d", info);
+ arg_info = unread_str; /* number of remaining unread bjids */
+ break;
default:
return;
}
diff --git a/src/hooks.h b/src/hooks.h
--- a/src/hooks.h
+++ b/src/hooks.h
#include "jabglue.h"
-inline void hk_message_in(const char *bjid, const char *resname,
+void hk_mainloop(void);
+void hk_message_in(const char *bjid, const char *resname,
time_t timestamp, const char *msg, const char *type,
guint encrypted);
-inline void hk_message_out(const char *bjid, const char *nickname,
+void hk_message_out(const char *bjid, const char *nickname,
time_t timestamp, const char *msg, guint encrypted);
-inline void hk_statuschange(const char *bjid, const char *resname, gchar prio,
+void hk_statuschange(const char *bjid, const char *resname, gchar prio,
time_t timestamp, enum imstatus status,
char const *status_msg);
-inline void hk_mystatuschange(time_t timestamp,
+void hk_mystatuschange(time_t timestamp,
enum imstatus old_status,
enum imstatus new_status, const char *msg);
diff --git a/src/jab_iq.c b/src/jab_iq.c
--- a/src/jab_iq.c
+++ b/src/jab_iq.c
/*
* jab_iq.c -- Jabber protocol IQ-related fonctions
*
- * Copyright (C) 2005-2007 Mikael Berthe <mikael@lilotux.net>
+ * Copyright (C) 2005-2008 Mikael Berthe <mikael@lilotux.net>
* Some parts initially came from the centericq project:
* Copyright (C) 2002-2005 by Konstantin Klyagin <konst@konst.org.ua>
* Some small parts come from the Pidgin project <http://pidgin.im/>
static void storage_bookmarks_parse_conference(xmlnode xmldata)
{
const char *fjid, *name, *autojoin;
+ const char *pstatus, *awhois;
char *bjid;
GSList *room_elt;
return;
name = xmlnode_get_attrib(xmldata, "name");
autojoin = xmlnode_get_attrib(xmldata, "autojoin");
+ awhois = xmlnode_get_attrib(xmldata, "autowhois");
+ pstatus = xmlnode_get_tag_data(xmldata, "print_status");
bjid = jidtodisp(fjid); // Bare jid
*/
}
+ // Set the print_status and auto_whois values
+ if (pstatus) {
+ enum room_printstatus i;
+ for (i = status_none; i <= status_all; i++)
+ if (!strcasecmp(pstatus, strprintstatus[i]))
+ break;
+ if (i <= status_all)
+ buddy_setprintstatus(room_elt->data, i);
+ }
+ if (awhois) {
+ enum room_autowhois i = autowhois_default;
+ if (!strcmp(awhois, "1"))
+ i = autowhois_on;
+ else if (!strcmp(awhois, "0"))
+ i = autowhois_off;
+ if (i != autowhois_default)
+ buddy_setautowhois(room_elt->data, i);
+ }
+
// Is autojoin set?
// If it is, we'll look up for more information (nick? password?) and
// try to join the room.
nick = xmlnode_get_tag_data(xmldata, "nick");
passwd = xmlnode_get_tag_data(xmldata, "password");
if (!nick || !*nick)
- nick = tmpnick = default_muc_nickname();
+ nick = tmpnick = default_muc_nickname(NULL);
// Let's join now
scr_LogPrint(LPRINT_LOGNORM, "Auto-join bookmark <%s>", bjid);
jb_room_join(bjid, nick, passwd);
xmlnode myquery;
jid requester_jid;
const struct adhoc_command *command;
+ const char *node;
bool from_self;
+
x = jutil_iqnew(JPACKET__RESULT, NS_DISCO_ITEMS);
xmlnode_put_attrib(x, "id", id);
xmlnode_put_attrib(x, "to", xmlnode_get_attrib(xmldata, "from"));
myquery = xmlnode_get_tag(x, "query");
+ node = xmlnode_get_attrib(xmlnode_get_tag(xmldata, "query"), "node");
+ if (node)
+ xmlnode_put_attrib(myquery, "node", node);
+
requester_jid = jid_new(conn->p, xmlnode_get_attrib(xmldata, "from"));
from_self = !jid_cmpx(conn->user, requester_jid, JID_USER | JID_SERVER);
static void xmlnode_insert_dataform_result_message(xmlnode node, char *message)
{
- xmlnode x = xmlnode_insert_tag(node, "x");
+ xmlnode x, field, value;
+
+ x = xmlnode_insert_tag(node, "x");
xmlnode_put_attrib(x, "type", "result");
xmlnode_put_attrib(x, "xmlns", "jabber:x:data");
- xmlnode field = xmlnode_insert_tag(x, "field");
+ field = xmlnode_insert_tag(x, "field");
xmlnode_put_attrib(field, "type", "text-single");
xmlnode_put_attrib(field, "var", "message");
- xmlnode value = xmlnode_insert_tag(field, "value");
+ value = xmlnode_insert_tag(field, "value");
xmlnode_insert_cdata(value, message, -1);
}
char *result;
static int counter = 0;
counter++;
- // TODO better use timezone ?
+ // TODO better use timestamp?
result = g_strdup_printf("%s-%i", prefix, counter);
return result;
}
@@ -1112,6 +1142,8 @@ static void handle_iq_command_set_status(jconn conn, char *from, const char *id,
xmlnode_put_attrib(command, "xmlns", NS_COMMANDS);
if (!sessionid) {
+ xmlnode value;
+
sessionid = generate_session_id("set-status");
xmlnode_put_attrib(command, "sessionid", sessionid);
g_free(sessionid);
@@ -1133,7 +1165,7 @@ static void handle_iq_command_set_status(jconn conn, char *from, const char *id,
xmlnode_put_attrib(y, "type", "hidden");
xmlnode_put_attrib(y, "var", "FORM_TYPE");
- xmlnode value = xmlnode_insert_tag(y, "value");
+ value = xmlnode_insert_tag(y, "value");
xmlnode_insert_cdata(value, "http://jabber.org/protocol/rc", -1);
y = xmlnode_insert_tag(x, "field");
@@ -1172,7 +1204,7 @@ static void handle_iq_command_set_status(jconn conn, char *from, const char *id,
if (s->name) {
char *status = g_strdup_printf("%s %s", s->status,
message ? message : "");
- setstatus(NULL, status);
+ cmd_setstatus(NULL, status);
g_free(status);
xmlnode_put_attrib(command, "status", "completed");
xmlnode_put_attrib(iq, "type", "result");
@@ -1189,7 +1221,7 @@ static void handle_iq_command_set_status(jconn conn, char *from, const char *id,
static void _callback_foreach_buddy_groupchat(gpointer rosterdata, void *param)
{
- xmlnode value;
+ xmlnode value, option;
xmlnode *field;
const char *room_jid, *nickname;
char *desc;
@@ -1200,7 +1232,7 @@ static void _callback_foreach_buddy_groupchat(gpointer rosterdata, void *param)
if (!nickname) return;
field = param;
- xmlnode option = xmlnode_insert_tag(*field, "option");
+ option = xmlnode_insert_tag(*field, "option");
value = xmlnode_insert_tag(option, "value");
xmlnode_insert_cdata(value, room_jid, -1);
desc = g_strdup_printf("%s on %s", nickname, room_jid);
xmlnode_put_attrib(command, "xmlns", NS_COMMANDS);
if (!sessionid) {
+ xmlnode title, instructions, field, value;
+
sessionid = generate_session_id("leave-groupchats");
xmlnode_put_attrib(command, "sessionid", sessionid);
g_free(sessionid);
xmlnode_put_attrib(x, "type", "form");
xmlnode_put_attrib(x, "xmlns", "jabber:x:data");
- xmlnode title = xmlnode_insert_tag(x, "title");
+ title = xmlnode_insert_tag(x, "title");
xmlnode_insert_cdata(title, "Leave groupchat(s)", -1);
- xmlnode instructions = xmlnode_insert_tag(x, "instructions");
+ instructions = xmlnode_insert_tag(x, "instructions");
xmlnode_insert_cdata(instructions, "What groupchats do you want to leave?",
-1);
- xmlnode field = xmlnode_insert_tag(x, "field");
+ field = xmlnode_insert_tag(x, "field");
xmlnode_put_attrib(field, "type", "hidden");
xmlnode_put_attrib(field, "var", "FORM_TYPE");
- xmlnode value = xmlnode_insert_tag(field, "value");
+ value = xmlnode_insert_tag(field, "value");
xmlnode_insert_cdata(value, "http://jabber.org/protocol/rc", -1);
field = xmlnode_insert_tag(x, "field");
{
xmlnode form = xmlnode_get_tag(x, "x?xmlns=jabber:x:data");
if (form) {
+ xmlnode x, gc;
+
xmlnode_put_attrib(command, "status", "completed");
- xmlnode gc = xmlnode_get_tag(form, "field?var=groupchats");
- xmlnode x;
+ gc = xmlnode_get_tag(form, "field?var=groupchats");
for (x = xmlnode_get_firstchild(gc) ; x ; x = xmlnode_get_nextsibling(x))
{
if (to_leave) {
GList* b = buddy_search_jid(to_leave);
if (b)
- room_leave(b->data, "Asked by remote command");
+ cmd_room_leave(b->data, "Asked by remote command");
}
}
xmlnode_put_attrib(iq, "type", "result");
xmlnode xmldata)
{
xmlnode x;
- char *node;
+ const char *node;
x = xmlnode_get_tag(xmldata, "query");
node = xmlnode_get_attrib(x, "node");
if (node) {
time_t now_t;
struct tm *now;
char const *sign;
- int diff;
+ int diff = 0;
time(&now_t);
now = localtime(&now_t);
- if (now->tm_isdst < 0)
- diff = 0;
- else
+ if (now->tm_isdst >= 0) {
+#if defined HAVE_TM_GMTOFF
diff = now->tm_gmtoff;
+#elif defined HAVE_TIMEZONE
+ tzset();
+ diff = -timezone;
+#endif
+ }
+
if (diff < 0) {
sign = "-";
diff = -diff;
diff --git a/src/jab_priv.h b/src/jab_priv.h
--- a/src/jab_priv.h
+++ b/src/jab_priv.h
#include "events.h"
/* XEP-0115 (Entity Capabilities) node */
-#define MCABBER_CAPS_NODE "http://mcabber.lilotux.net/caps"
+#define MCABBER_CAPS_NODE "http://mcabber.com/caps"
#define JABBER_AGENT_GROUP "Jabber Agents"
extern time_t iqlast; /* last message/status change time */
-char *jidtodisp(const char *fjid);
void handle_packet_iq(jconn conn, char *type, char *from, xmlnode xmldata);
void display_server_error(xmlnode x);
eviqs *iqs_new(guint8 type, const char *ns, const char *prefix, time_t timeout);
diff --git a/src/jabglue.c b/src/jabglue.c
--- a/src/jabglue.c
+++ b/src/jabglue.c
/*
* jabglue.c -- Jabber protocol handling
*
- * Copyright (C) 2005-2007 Mikael Berthe <mikael@lilotux.net>
+ * Copyright (C) 2005-2008 Mikael Berthe <mikael@lilotux.net>
* Parts come from the centericq project:
* Copyright (C) 2002-2005 by Konstantin Klyagin <konst@konst.org.ua>
*
#include "commands.h"
#include "pgp.h"
#include "otr.h"
+#include "fifo.h"
#define JABBERPORT 5222
#define JABBERSSLPORT 5223
'_', 'o', 'f', 'd', 'n', 'a', 'i', '\0'
};
+static char *imstatus_showmap[] = {
+ "",
+ "",
+ "chat",
+ "dnd",
+ "xa",
+ "away",
+ ""
+};
+
static time_t LastPingTime;
static unsigned int KeepaliveDelay;
static enum imstatus mystatus = offline;
char *compose_jid(const char *username, const char *servername,
const char *resource)
{
- char *fjid = g_new(char, 3 +
- strlen(username) + strlen(servername) + strlen(resource));
- strcpy(fjid, username);
- if (!strchr(fjid, JID_DOMAIN_SEPARATOR)) {
- strcat(fjid, JID_DOMAIN_SEPARATORSTR);
- strcat(fjid, servername);
+ char *fjid;
+
+ if (!strchr(username, JID_DOMAIN_SEPARATOR)) {
+ fjid = g_strdup_printf("%s%c%s%c%s", username,
+ JID_DOMAIN_SEPARATOR, servername,
+ JID_RESOURCE_SEPARATOR, resource);
+ } else {
+ fjid = g_strdup_printf("%s%c%s", username,
+ JID_RESOURCE_SEPARATOR, resource);
}
- strcat(fjid, JID_RESOURCE_SEPARATORSTR);
- strcat(fjid, resource);
return fjid;
}
-inline unsigned char jb_getonline(void)
+unsigned char jb_getonline(void)
{
return online;
}
long tmout;
struct timeval tv;
static time_t last_eviqs_check = 0L;
+ int maxfd = 0;
+ int fifofd;
- if (!online) {
- safe_usleep(10000);
- check_connection();
- return;
+ FD_ZERO(&fds);
+ FD_SET(0, &fds);
+ if (jc && jc->fd > 0) {
+ FD_SET(jc->fd, &fds);
+ maxfd = jc->fd;
}
- if (jc && jc->state == JCONN_STATE_CONNECTING) {
- safe_usleep(75000);
- jab_start(jc);
- return;
+ fifofd = fifo_get_fd();
+ if (fifofd > 0) {
+ FD_SET(fifofd, &fds);
+ maxfd = MAX(maxfd, fifofd);
}
- FD_ZERO(&fds);
- FD_SET(0, &fds);
- FD_SET(jc->fd, &fds);
-
tv.tv_sec = 60;
tv.tv_usec = 0;
+ if (!online || (jc && jc->state == JCONN_STATE_CONNECTING)) {
+ if (online) {
+ // We're connecting and we need to reduce the timeout.
+ tv.tv_sec = 0;
+ tv.tv_usec = 250000;
+ } else {
+ tv.tv_sec = 30;
+ // Let's first update the screen, we could sleep for a long time...
+ scr_DoUpdate();
+ }
+ // If we're not connected, sleep for a while...
+ select(maxfd + 1, &fds, NULL, NULL, &tv);
+ if (!online)
+ check_connection();
+ else
+ jab_start(jc);
+ return;
+ }
+
time(&now);
if (KeepaliveDelay) {
- if (now >= LastPingTime + (time_t)KeepaliveDelay) {
+ if (now >= LastPingTime + (time_t)KeepaliveDelay)
tv.tv_sec = 0;
- } else {
+ else
tv.tv_sec = LastPingTime + (time_t)KeepaliveDelay - now;
- }
}
// Check auto-away timeout
tmout = scr_GetAutoAwayTimeout(now);
- if (tv.tv_sec > tmout) {
+ if (tv.tv_sec > tmout)
tv.tv_sec = tmout;
- }
#if defined JEP0022 || defined JEP0085
// Check composing timeout
tmout = scr_GetChatStatesTimeout(now);
- if (tv.tv_sec > tmout) {
+ if (tv.tv_sec > tmout)
tv.tv_sec = tmout;
- }
#endif
if (!tv.tv_sec)
tv.tv_usec = 350000;
scr_DoUpdate();
- if (select(jc->fd + 1, &fds, NULL, NULL, &tv) > 0) {
+ if (select(maxfd + 1, &fds, NULL, NULL, &tv) > 0) {
if (FD_ISSET(jc->fd, &fds))
jab_poll(jc, 0);
}
switch(st) {
case away:
- xmlnode_insert_cdata(xmlnode_insert_tag(x, "show"), "away",
- (unsigned) -1);
- break;
-
+ case notavail:
case dontdisturb:
- xmlnode_insert_cdata(xmlnode_insert_tag(x, "show"), "dnd",
- (unsigned) -1);
- break;
-
case freeforchat:
- xmlnode_insert_cdata(xmlnode_insert_tag(x, "show"), "chat",
- (unsigned) -1);
- break;
-
- case notavail:
- xmlnode_insert_cdata(xmlnode_insert_tag(x, "show"), "xa",
- (unsigned) -1);
+ xmlnode_insert_cdata(xmlnode_insert_tag(x, "show"),
+ imstatus_showmap[st], (unsigned) -1);
break;
case invisible:
break;
}
- prio = settings_opt_get_int("priority");
+ if (st == away || st == notavail)
+ prio = settings_opt_get_int("priority_away");
+ else
+ prio = settings_opt_get_int("priority");
+
if (prio) {
char strprio[8];
snprintf(strprio, 8, "%d", (int)prio);
return g_strdup_printf("%u%d", msg_idn, (int)(now%10L));
}
-// jb_send_msg(jid, text, type, subject, msgid, *encrypted)
+// jb_send_msg(jid, text, type, subject, msgid, *encrypted, type_overwrite)
// When encrypted is not NULL, the function set *encrypted to 1 if the
// message has been PGP-encrypted. If encryption enforcement is set and
// encryption fails, *encrypted is set to -1.
if (encrypted)
*encrypted = 0;
- if (!online) return;
+ if (!online)
+ return;
+
+ if (!text && type == ROSTER_TYPE_USER)
+ return;
if (type_overwrite)
strtype = type_overwrite;
* "Until receiving a reply to the initial content message (or a standalone
* notification) from the Contact, the User MUST NOT send subsequent chat
* state notifications to the Contact."
- * In our implementation support is initially "unknown", they it's "probed"
+ * In our implementation support is initially "unknown", then it's "probed"
* and can become "ok".
*/
if (jep85 && (jep85->support == CHATSTATES_SUPPORT_OK ||
const char *bjid;
#ifdef JEP0085
GSList *resources, *p_res, *p_next;
- struct jep0085 *jep85 = NULL;;
+ struct jep0085 *jep85 = NULL;
#endif
#ifdef JEP0022
struct jep0022 *jep22;
jb_reset_keepalive();
}
-// jb_is_bookmarked()
+// jb_is_bookmarked(roomjid)
// Return TRUE if there's a bookmark for the given jid.
guint jb_is_bookmarked(const char *bjid)
{
// Walk through the storage bookmark tags
x = xmlnode_get_firstchild(bookmarks);
for ( ; x; x = xmlnode_get_nextsibling(x)) {
- const char *fjid;
- const char *p;
- p = xmlnode_get_name(x);
+ const char *p = xmlnode_get_name(x);
// If the node is a conference item, check the jid.
if (p && !strcmp(p, "conference")) {
- fjid = xmlnode_get_attrib(x, "jid");
+ const char *fjid = xmlnode_get_attrib(x, "jid");
if (fjid && !strcasecmp(bjid, fjid))
return TRUE;
}
return FALSE;
}
+// jb_get_bookmark_nick(roomjid)
+// Return the room nickname if it is present in a bookmark.
+const char *jb_get_bookmark_nick(const char *bjid)
+{
+ xmlnode x;
+
+ if (!bookmarks || !bjid)
+ return NULL;
+
+ // Walk through the storage bookmark tags
+ x = xmlnode_get_firstchild(bookmarks);
+ for ( ; x; x = xmlnode_get_nextsibling(x)) {
+ const char *p = xmlnode_get_name(x);
+ // If the node is a conference item, check the jid.
+ if (p && !strcmp(p, "conference")) {
+ const char *fjid = xmlnode_get_attrib(x, "jid");
+ if (fjid && !strcasecmp(bjid, fjid))
+ return xmlnode_get_tag_data(x, "nick");
+ }
+ }
+ return NULL;
+}
+
+
// jb_get_all_storage_bookmarks()
// Return a GSList with all storage bookmarks.
// The caller should g_free the list (not the MUC jids).
// Walk through the storage bookmark tags
x = xmlnode_get_firstchild(bookmarks);
for ( ; x; x = xmlnode_get_nextsibling(x)) {
- const char *fjid;
- const char *p;
- p = xmlnode_get_name(x);
+ const char *p = xmlnode_get_name(x);
// If the node is a conference item, let's add the note to our list.
if (p && !strcmp(p, "conference")) {
- fjid = xmlnode_get_attrib(x, "jid");
+ const char *fjid = xmlnode_get_attrib(x, "jid");
if (!fjid)
continue;
sl_bookmarks = g_slist_append(sl_bookmarks, (char*)fjid);
return sl_bookmarks;
}
-// jb_set_storage_bookmark(roomid, name, nick, passwd, autojoin)
+// jb_set_storage_bookmark(roomid, name, nick, passwd, autojoin,
+// printstatus, autowhois)
// Update the private storage bookmarks: add a conference room.
// If name is nil, we remove the bookmark.
void jb_set_storage_bookmark(const char *roomid, const char *name,
- const char *nick, const char *passwd, int autojoin)
+ const char *nick, const char *passwd,
+ int autojoin, enum room_printstatus pstatus,
+ enum room_autowhois awhois)
{
xmlnode x;
bool changed = FALSE;
// Walk through the storage tags
x = xmlnode_get_firstchild(bookmarks);
for ( ; x; x = xmlnode_get_nextsibling(x)) {
- const char *fjid;
- const char *p;
- p = xmlnode_get_name(x);
+ const char *p = xmlnode_get_name(x);
// If the current node is a conference item, see if we have to replace it.
if (p && !strcmp(p, "conference")) {
- fjid = xmlnode_get_attrib(x, "jid");
+ const char *fjid = xmlnode_get_attrib(x, "jid");
if (!fjid)
continue;
if (!strcmp(fjid, roomid)) {
xmlnode_insert_cdata(xmlnode_insert_tag(x, "nick"), nick, -1);
if (passwd)
xmlnode_insert_cdata(xmlnode_insert_tag(x, "password"), passwd, -1);
+ if (pstatus)
+ xmlnode_insert_cdata(xmlnode_insert_tag(x, "print_status"),
+ strprintstatus[pstatus], -1);
+ if (awhois)
+ xmlnode_put_attrib(x, "autowhois", (awhois == autowhois_on ? "1" : "0"));
changed = TRUE;
scr_LogPrint(LPRINT_LOGNORM, "Updating bookmarks...");
}
// Walk through the storage tags
x = xmlnode_get_firstchild(rosternotes);
for ( ; x; x = xmlnode_get_nextsibling(x)) {
- const char *fjid;
- const char *p;
- p = xmlnode_get_name(x);
+ const char *p = xmlnode_get_name(x);
// If the current node is a conference item, see if we have to replace it.
if (p && !strcmp(p, "note")) {
- fjid = xmlnode_get_attrib(x, "jid");
+ const char *fjid = xmlnode_get_attrib(x, "jid");
if (!fjid)
continue;
if (!strcmp(fjid, barejid)) {
}
static void gotmessage(char *type, const char *from, const char *body,
- const char *enc, time_t timestamp,
+ const char *enc, const char *subject, time_t timestamp,
xmlnode xmldata_signed)
{
char *bjid;
(roster_getsubscription(bjid) & sub_from) ||
(type && strcmp(type, "chat")) ||
((s = settings_opt_get("server")) != NULL && !strcasecmp(bjid, s))) {
+ gchar *fullbody = NULL;
+ if (subject) {
+ if (body)
+ fullbody = g_strdup_printf("[%s]\n%s", subject, body);
+ else
+ fullbody = g_strdup_printf("[%s]\n", subject);
+ body = fullbody;
+ }
hk_message_in(bjid, rname, timestamp, body, type,
((decrypted_pgp || otr_msg) ? TRUE : FALSE));
+ g_free(fullbody);
} else {
scr_LogPrint(LPRINT_LOGNORM, "Blocked a message from <%s>", bjid);
}
online = TRUE;
update_last_use();
// We set AutoConnection to true after the 1st successful connection
- AutoConnection = true;
+ AutoConnection = TRUE;
break;
case JCONN_STATE_CONNECTING:
return 0;
}
+// muc_get_item_info(...)
+// Get room member's information from xmlndata.
+// The variables must be initialized before calling this function,
+// because they are not touched if the relevant information is missing.
+static void muc_get_item_info(const char *from, xmlnode xmldata,
+ enum imrole *mbrole, enum imaffiliation *mbaffil,
+ const char **mbjid, const char **mbnick,
+ const char **actorjid, const char **reason)
+{
+ xmlnode y, z;
+ char *p;
+
+ y = xmlnode_get_tag(xmldata, "item");
+ if (!y)
+ return;
+
+ p = xmlnode_get_attrib(y, "affiliation");
+ if (p) {
+ if (!strcmp(p, "owner")) *mbaffil = affil_owner;
+ else if (!strcmp(p, "admin")) *mbaffil = affil_admin;
+ else if (!strcmp(p, "member")) *mbaffil = affil_member;
+ else if (!strcmp(p, "outcast")) *mbaffil = affil_outcast;
+ else if (!strcmp(p, "none")) *mbaffil = affil_none;
+ else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown affiliation \"%s\"",
+ from, p);
+ }
+ p = xmlnode_get_attrib(y, "role");
+ if (p) {
+ if (!strcmp(p, "moderator")) *mbrole = role_moderator;
+ else if (!strcmp(p, "participant")) *mbrole = role_participant;
+ else if (!strcmp(p, "visitor")) *mbrole = role_visitor;
+ else if (!strcmp(p, "none")) *mbrole = role_none;
+ else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown role \"%s\"",
+ from, p);
+ }
+ *mbjid = xmlnode_get_attrib(y, "jid");
+ *mbnick = xmlnode_get_attrib(y, "nick");
+ // For kick/ban, there can be actor and reason tags
+ *reason = xmlnode_get_tag_data(y, "reason");
+ z = xmlnode_get_tag(y, "actor");
+ if (z)
+ *actorjid = xmlnode_get_attrib(z, "jid");
+}
+
+// muc_handle_join(...)
+// Handle a join event in a MUC room.
+// This function will return the new_member value TRUE if somebody else joins
+// the room (and FALSE if _we_ are joining the room).
+static bool muc_handle_join(const GSList *room_elt, const char *rname,
+ const char *roomjid, const char *ournick,
+ enum room_printstatus printstatus,
+ time_t usttime, int log_muc_conf)
+{
+ bool new_member = FALSE; // True if somebody else joins the room (not us)
+ gchar *mbuf;
+
+ if (!buddy_getinsideroom(room_elt->data)) {
+ // We weren't inside the room yet. Now we are.
+ // However, this could be a presence packet from another room member
+
+ buddy_setinsideroom(room_elt->data, TRUE);
+ // Set the message flag unless we're already in the room buffer window
+ scr_setmsgflag_if_needed(roomjid, FALSE);
+ // Add a message to the tracelog file
+ mbuf = g_strdup_printf("You have joined %s as \"%s\"", roomjid, ournick);
+ scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf);
+ g_free(mbuf);
+ mbuf = g_strdup_printf("You have joined as \"%s\"", ournick);
+
+ // The 1st presence message could be for another room member
+ if (strcmp(ournick, rname)) {
+ // Display current mbuf and create a new message for the member
+ // Note: the usttime timestamp is related to the other member,
+ // so we use 0 here.
+ scr_WriteIncomingMessage(roomjid, mbuf, 0,
+ HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
+ if (log_muc_conf)
+ hlog_write_message(roomjid, 0, -1, mbuf);
+ g_free(mbuf);
+ if (printstatus != status_none)
+ mbuf = g_strdup_printf("%s has joined", rname);
+ else
+ mbuf = NULL;
+ new_member = TRUE;
+ }
+ } else {
+ mbuf = NULL;
+ if (strcmp(ournick, rname)) {
+ if (printstatus != status_none)
+ mbuf = g_strdup_printf("%s has joined", rname);
+ new_member = TRUE;
+ }
+ }
+
+ if (mbuf) {
+ guint msgflags = HBB_PREFIX_INFO;
+ if (!settings_opt_get_int("muc_flag_joins"))
+ msgflags |= HBB_PREFIX_NOFLAG;
+ scr_WriteIncomingMessage(roomjid, mbuf, usttime, msgflags, 0);
+ if (log_muc_conf)
+ hlog_write_message(roomjid, 0, -1, mbuf);
+ g_free(mbuf);
+ }
+
+ return new_member;
+}
+
static void handle_presence_muc(const char *from, xmlnode xmldata,
const char *roomjid, const char *rname,
enum imstatus ust, char *ustmsg,
const char *ournick;
enum imrole mbrole = role_none;
enum imaffiliation mbaffil = affil_none;
+ enum room_printstatus printstatus;
+ enum room_autowhois autowhois;
const char *mbjid = NULL, *mbnick = NULL;
const char *actorjid = NULL, *reason = NULL;
bool new_member = FALSE; // True if somebody else joins the room (not us)
- unsigned int statuscode = 0;
+ guint statuscode = 0;
+ guint nickchange = 0;
GSList *room_elt;
int log_muc_conf;
guint msgflags;
}
// Get room member's information
- y = xmlnode_get_tag(xmldata, "item");
- if (y) {
- xmlnode z;
- p = xmlnode_get_attrib(y, "affiliation");
- if (p) {
- if (!strcmp(p, "owner")) mbaffil = affil_owner;
- else if (!strcmp(p, "admin")) mbaffil = affil_admin;
- else if (!strcmp(p, "member")) mbaffil = affil_member;
- else if (!strcmp(p, "outcast")) mbaffil = affil_outcast;
- else if (!strcmp(p, "none")) mbaffil = affil_none;
- else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown affiliation \"%s\"",
- from, p);
- }
- p = xmlnode_get_attrib(y, "role");
- if (p) {
- if (!strcmp(p, "moderator")) mbrole = role_moderator;
- else if (!strcmp(p, "participant")) mbrole = role_participant;
- else if (!strcmp(p, "visitor")) mbrole = role_visitor;
- else if (!strcmp(p, "none")) mbrole = role_none;
- else scr_LogPrint(LPRINT_LOGNORM, "<%s>: Unknown role \"%s\"",
- from, p);
- }
- mbjid = xmlnode_get_attrib(y, "jid");
- mbnick = xmlnode_get_attrib(y, "nick");
- // For kick/ban, there can be actor and reason tags
- reason = xmlnode_get_tag_data(y, "reason");
- z = xmlnode_get_tag(y, "actor");
- if (z)
- actorjid = xmlnode_get_attrib(z, "jid");
- }
+ muc_get_item_info(from, xmldata, &mbrole, &mbaffil, &mbjid, &mbnick,
+ &actorjid, &reason);
// Get our room nickname
ournick = buddy_getnickname(room_elt->data);
statuscode = atoi(p);
}
+ // Get the room's "print_status" settings
+ printstatus = buddy_getprintstatus(room_elt->data);
+ if (printstatus == status_default) {
+ printstatus = (guint) settings_opt_get_int("muc_print_status");
+ if (printstatus > 3)
+ printstatus = status_default;
+ }
+
+ // A new room has been created; accept MUC default config
+ if (statuscode == 201)
+ jb_room_unlock(roomjid);
+
// Check for nickname change
if (statuscode == 303 && mbnick) {
mbuf = g_strdup_printf("%s is now known as %s", rname, mbnick);
// Maybe it's _our_ nickname...
if (ournick && !strcmp(rname, ournick))
buddy_setnickname(room_elt->data, mbnick);
+ nickchange = TRUE;
}
// Check for departure/arrival
if (!mbnick && ust == offline) {
+ // Somebody is leaving
enum { leave=0, kick, ban } how = leave;
bool we_left = FALSE;
}
}
- msgflags = HBB_PREFIX_INFO;
- if (!we_left && settings_opt_get_int("muc_flag_joins") != 2)
- msgflags |= HBB_PREFIX_NOFLAG;
-
- scr_WriteIncomingMessage(roomjid, mbuf, usttime, msgflags, 0);
+ // Display the mbuf message if we're concerned
+ // or if the print_status isn't set to none.
+ if (we_left || printstatus != status_none) {
+ msgflags = HBB_PREFIX_INFO;
+ if (!we_left && settings_opt_get_int("muc_flag_joins") != 2)
+ msgflags |= HBB_PREFIX_NOFLAG;
+ scr_WriteIncomingMessage(roomjid, mbuf, usttime, msgflags, 0);
+ }
if (log_muc_conf)
hlog_write_message(roomjid, 0, -1, mbuf);
g_free(mbuf);
} else if (buddy_getstatus(room_elt->data, rname) == offline &&
ust != offline) {
+ // Somebody is joining
+ new_member = muc_handle_join(room_elt, rname, roomjid, ournick,
+ printstatus, usttime, log_muc_conf);
+ } else {
+ // This is a simple member status change
- if (!buddy_getinsideroom(room_elt->data)) {
- // We weren't inside the room yet. Now we are.
- // However, this could be a presence packet from another room member
-
- buddy_setinsideroom(room_elt->data, TRUE);
- // Set the message flag unless we're already in the room buffer window
- scr_setmsgflag_if_needed(roomjid, FALSE);
- // Add a message to the tracelog file
- mbuf = g_strdup_printf("You have joined %s as \"%s\"", roomjid, ournick);
- scr_LogPrint(LPRINT_LOGNORM, "%s", mbuf);
- g_free(mbuf);
- mbuf = g_strdup_printf("You have joined as \"%s\"", ournick);
-
- // The 1st presence message could be for another room member
- if (strcmp(ournick, rname)) {
- // Display current mbuf and create a new message for the member
- // Note: the usttime timestamp is related to the other member,
- // so we use 0 here.
- scr_WriteIncomingMessage(roomjid, mbuf, 0,
- HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
- if (log_muc_conf)
- hlog_write_message(roomjid, 0, -1, mbuf);
- g_free(mbuf);
- mbuf = g_strdup_printf("%s has joined", rname);
- new_member = TRUE;
- }
- } else {
- if (strcmp(ournick, rname)) {
- mbuf = g_strdup_printf("%s has joined", rname);
- new_member = TRUE;
- } else
- mbuf = NULL;
- }
-
- if (mbuf) {
- msgflags = HBB_PREFIX_INFO;
- if (!settings_opt_get_int("muc_flag_joins"))
- msgflags |= HBB_PREFIX_NOFLAG;
- scr_WriteIncomingMessage(roomjid, mbuf, usttime, msgflags, 0);
- if (log_muc_conf)
- hlog_write_message(roomjid, 0, -1, mbuf);
+ if (printstatus == status_all && !nickchange) {
+ mbuf = g_strdup_printf("Member status has changed: %s [%c] %s", rname,
+ imstatus2char[ust], ((ustmsg) ? ustmsg : ""));
+ scr_WriteIncomingMessage(roomjid, mbuf, usttime,
+ HBB_PREFIX_INFO|HBB_PREFIX_NOFLAG, 0);
g_free(mbuf);
}
}
+ // Sanity check, shouldn't happen...
+ if (!rname)
+ return;
+
// Update room member status
- if (rname) {
- roster_setstatus(roomjid, rname, bpprio, ust, ustmsg, usttime,
- mbrole, mbaffil, mbjid);
- if (new_member && settings_opt_get_int("muc_auto_whois")) {
- // FIXME: This will fail for some UTF-8 nicknames.
- gchar *joiner_nick = from_utf8(rname);
- room_whois(room_elt->data, joiner_nick, FALSE);
- g_free(joiner_nick);
- }
- } else
- scr_LogPrint(LPRINT_LOGNORM, "MUC DBG: no rname!"); /* DBG */
+ roster_setstatus(roomjid, rname, bpprio, ust, ustmsg, usttime,
+ mbrole, mbaffil, mbjid);
+
+ autowhois = buddy_getautowhois(room_elt->data);
+ if (autowhois == autowhois_default)
+ autowhois = (settings_opt_get_int("muc_auto_whois") ?
+ autowhois_on : autowhois_off);
+
+ if (new_member && autowhois == autowhois_on) {
+ // FIXME: This will fail for some UTF-8 nicknames.
+ gchar *joiner_nick = from_utf8(rname);
+ cmd_room_whois(room_elt->data, joiner_nick, FALSE);
+ g_free(joiner_nick);
+ }
scr_DrawRoster();
}
rname = strchr(from, JID_RESOURCE_SEPARATOR);
if (rname) rname++;
+ if (settings_opt_get_int("ignore_self_presence")) {
+ const char *self_fjid = jid_full(jc->user);
+ if (self_fjid && !strcasecmp(self_fjid, from)) {
+ return; // Ignoring self presence
+ }
+ }
+
r = jidtodisp(from);
// Check for MUC presence packet
xmlnode x;
char *body = NULL;
char *enc = NULL;
- char *tmp = NULL;
+ char *subject = NULL;
time_t timestamp = 0L;
body = xmlnode_get_tag_data(xmldata, "body");
+ x = xml_get_xmlns(xmldata, NS_ENCRYPTED);
+ if (x && (p = xmlnode_get_data(x)) != NULL)
+ enc = p;
+
p = xmlnode_get_tag_data(xmldata, "subject");
if (p != NULL) {
- if (type && !strcmp(type, TMSG_GROUPCHAT)) { // Room topic
+ if (!type || strcmp(type, TMSG_GROUPCHAT)) { // Chat message
+ subject = p;
+ } else { // Room topic
GSList *roombuddy;
gchar *mbuf;
gchar *subj = p;
g_free(mbuf);
// The topic is displayed in the chat status line, so refresh now.
scr_UpdateChatStatus(TRUE);
- } else { // Chat message
- tmp = g_new(char, (body ? strlen(body) : 0) + strlen(p) + 4);
- *tmp = '[';
- strcpy(tmp+1, p);
- strcat(tmp, "]\n");
- if (body) strcat(tmp, body);
- body = tmp;
}
}
- // Not used yet...
- x = xml_get_xmlns(xmldata, NS_ENCRYPTED);
- if (x && (p = xmlnode_get_data(x)) != NULL) {
- enc = p;
- }
-
// Timestamp?
timestamp = xml_get_timestamp(xmldata);
} else {
handle_state_events(from, xmldata);
}
- if (from && body)
- gotmessage(type, from, body, enc, timestamp,
+ if (from && (body || subject))
+ gotmessage(type, from, body, enc, subject, timestamp,
xml_get_xmlns(xmldata, NS_SIGNED));
if (from) {
if (x && !strcmp(xmlnode_get_name(x), "x"))
got_muc_message(from, x);
}
- g_free(tmp);
}
static void handle_state_events(char *from, xmlnode xmldata)
// evcontext: 0, 1 == reject, accept
if (evcontext & ~EVS_CONTEXT_USER) {
- char *nickname = default_muc_nickname();
+ char *nickname = default_muc_nickname(invitation->to);
jb_room_join(invitation->to, nickname, invitation->passwd);
g_free(nickname);
} else {
diff --git a/src/jabglue.h b/src/jabglue.h
--- a/src/jabglue.h
+++ b/src/jabglue.h
gchar *text;
};
+char *jidtodisp(const char *fjid);
char *compose_jid(const char *username, const char *servername,
const char *resource);
jconn jb_connect(const char *fjid, const char *server, unsigned int port,
int ssl, const char *pass);
-inline unsigned char jb_getonline(void);
+unsigned char jb_getonline(void);
void jb_disconnect(void);
void jb_main(void);
void jb_subscr_send_auth(const char *bjid);
void jb_addbuddy(const char *bjid, const char *name, const char *group);
void jb_delbuddy(const char *bjid);
void jb_updatebuddy(const char *bjid, const char *name, const char *group);
-inline enum imstatus jb_getstatus(void);
-inline const char *jb_getstatusmsg(void);
+enum imstatus jb_getstatus(void);
+const char *jb_getstatusmsg(void);
void jb_setstatus(enum imstatus st, const char *recipient, const char *msg,
int do_not_sign);
-inline void jb_setprevstatus(void);
+void jb_setprevstatus(void);
void jb_send_msg(const char *fjid, const char *text, int type,
const char *subject, const char *id, gint *encrypted,
const char *type_overwrite);
void jb_send_raw(const char *str);
void jb_send_chatstate(gpointer buddy, guint chatstate);
void jb_keepalive(void);
-inline void jb_reset_keepalive(void);
+void jb_reset_keepalive(void);
void jb_set_keepalive_delay(unsigned int delay);
void jb_room_join(const char *room, const char *nickname, const char *passwd);
void jb_room_unlock(const char *room);
void jb_iqs_display_list(void);
void jb_request(const char *fjid, enum iqreq_type reqtype);
guint jb_is_bookmarked(const char *bjid);
+const char *jb_get_bookmark_nick(const char *bjid);
GSList *jb_get_all_storage_bookmarks(void);
void jb_set_storage_bookmark(const char *roomid, const char *name,
const char *nick, const char *passwd,
- int autojoin);
+ int autojoin, enum room_printstatus pstatus,
+ enum room_autowhois awhois);
struct annotation *jb_get_storage_rosternotes(const char *barejid, int silent);
GSList *jb_get_all_storage_rosternotes(void);
void jb_set_storage_rosternotes(const char *barejid, const char *note);
diff --git a/src/logprint.h b/src/logprint.h
--- a/src/logprint.h
+++ b/src/logprint.h
void scr_LogPrint(unsigned int flag, const char *fmt, ...);
-inline void scr_DoUpdate(void);
+void scr_DoUpdate(void);
#endif /* __LOGPRINT_H__ */
diff --git a/src/main.c b/src/main.c
--- a/src/main.c
+++ b/src/main.c
/*
* main.c
*
- * Copyright (C) 2005-2007 Mikael Berthe <mikael@lilotux.net>
+ * Copyright (C) 2005-2008 Mikael Berthe <mikael@lilotux.net>
* Parts of this file come from Cabber <cabber@ajmacias.com>
*
* This program is free software; you can redistribute it and/or modify
#include "utils.h"
#include "pgp.h"
#include "otr.h"
+#include "fifo.h"
#ifdef ENABLE_HGCSET
# include "hgcset.h"
{
const char *username, *password, *resource, *servername;
const char *proxy_host;
- char *bjid;
+ char *dynresource = NULL;
+ char *fjid;
int ssl;
int sslverify = -1;
const char *sslvopt = NULL, *cafile = NULL, *capath = NULL, *ciphers = NULL;
scr_LogPrint(LPRINT_NORMAL, "Password has not been specified!");
return;
}
- if (!resource)
- resource = "mcabber";
port = (unsigned int) settings_opt_get_int("port");
cafile = capath = ciphers = NULL;
}
#elif defined HAVE_GNUTLS
- if (sslverify != 0) {
+ if (ssl && sslverify != 0) {
scr_LogPrint(LPRINT_LOGNORM, "** Error: SSL certificate checking "
"is not supported yet with GnuTLS.");
scr_LogPrint(LPRINT_LOGNORM,
// We can't free the ca*_xp variables now, because they're not duplicated
// in cw_set_ssl_options().
+ if (!resource) {
+ unsigned int tab[2];
+ srand(time(NULL));
+ tab[0] = (unsigned int) (0xffff * (rand() / (RAND_MAX + 1.0)));
+ tab[1] = (unsigned int) (0xffff * (rand() / (RAND_MAX + 1.0)));
+ dynresource = g_strdup_printf("%s.%04x%04x", PACKAGE_NAME,
+ tab[0], tab[1]);
+ resource = dynresource;
+ }
+
/* Connect to server */
scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, "Connecting to server: %s",
servername);
if (port)
scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, " using port %d", port);
+ scr_LogPrint(LPRINT_NORMAL|LPRINT_DEBUG, " resource %s", resource);
if (proxy_host) {
int proxy_port = settings_opt_get_int("proxy_port");
}
}
- bjid = compose_jid(username, servername, resource);
+ fjid = compose_jid(username, servername, resource);
#if defined(HAVE_LIBOTR)
- otr_init(bjid);
+ otr_init(fjid);
#endif
- jc = jb_connect(bjid, servername, port, ssl, password);
- g_free(bjid);
+ jc = jb_connect(fjid, servername, port, ssl, password);
+ g_free(fjid);
+ g_free(dynresource);
if (!jc)
scr_LogPrint(LPRINT_LOGNORM, "Error connecting to (%s)", servername);
mcabber_terminate("Killed by SIGTERM");
} else if (signum == SIGINT) {
mcabber_terminate("Killed by SIGINT");
+#ifdef USE_SIGWINCH
+ } else if (signum == SIGWINCH) {
+ ungetch(KEY_RESIZE);
+#endif
} else {
scr_LogPrint(LPRINT_LOGNORM, "Caught signal: %d", signum);
}
#ifdef WITH_ASPELL
puts("Compiled with Aspell support.");
#endif
-#ifdef DEBUG_ENABLE
+#ifdef ENABLE_DEBUG
puts("Compiled with debugging support.");
#endif
}
signal(SIGTERM, sig_handler);
signal(SIGINT, sig_handler);
signal(SIGCHLD, sig_handler);
+#ifdef USE_SIGWINCH
+ signal(SIGWINCH, sig_handler);
+#endif
signal(SIGPIPE, SIG_IGN);
/* Parse command line options */
chatstates_disabled = settings_opt_get_int("disable_chatstates");
+ /* Initialize FIFO named pipe */
+ fifo_init(settings_opt_get("fifo_name"));
+
+ /* Load previous roster state */
+ hlog_load_state();
+
if (ret < 0) {
scr_LogPrint(LPRINT_NORMAL, "No configuration file has been found.");
scr_ShowBuddyWindow();
scr_DrawRoster();
jb_main();
+ hk_mainloop();
}
}
scr_TerminateCurses();
+ fifo_deinit();
#ifdef HAVE_LIBOTR
otr_terminate();
#endif
#endif
#ifdef HAVE_ASPELL_H
/* Deinitialize aspell */
- if (settings_opt_get_int("aspell_enable")) {
+ if (settings_opt_get_int("aspell_enable"))
spellcheck_deinit();
- }
#endif
+ /* Save pending message state */
+ hlog_save_state();
printf("\n\nThanks for using mcabber!\n");
diff --git a/src/nohtml.c b/src/nohtml.c
--- /dev/null
+++ b/src/nohtml.c
@@ -0,0 +1,162 @@
+/*
+ * nohtml.c -- (X)HTML helper functions
+ *
+ * Copyright (C) 2008 Mikael Berthe <mikael@lilotux.net>
+ * Some portions come from the jabberd project, see below.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ *
+ *
+ * Some parts come from libjabber/str.c:
+ * Copyright (c) 1999-2002 Jabber.com, Inc. All Rights Reserved. Contact
+ * information for Jabber.com, Inc. is available at http://www.jabber.com/.
+ * Portions Copyright (c) 1998-1999 Jeremie Miller.
+ */
+
+#include <string.h>
+#include <glib.h>
+#include <config.h>
+
+
+/* html_strip(htmlbuf)
+ * Remove html entities from htmlbuf and try to convert it to plain text.
+ * The caller must g_free the string after use.
+ * Code mostly derived from strunescape(), in libjabber.
+ */
+char *html_strip(const char *htmlbuf)
+{
+ int i, j=0;
+ char *nohtml;
+
+ if (!htmlbuf) return(NULL);
+
+ nohtml = g_strdup(htmlbuf);
+
+ if (!strchr(htmlbuf, '&') && !strchr(htmlbuf, '<'))
+ return(nohtml);
+
+ for (i = 0; i < (int)strlen(htmlbuf); i++) {
+ if (htmlbuf[i] == '&') {
+ if (!strncmp(&htmlbuf[i],"&",5)) {
+ nohtml[j] = '&';
+ i += 4;
+ } else if (!strncmp(&htmlbuf[i],""", 6)) {
+ nohtml[j] = '\"';
+ i += 5;
+ } else if (!strncmp(&htmlbuf[i],"'", 6)) {
+ nohtml[j] = '\'';
+ i += 5;
+ } else if (!strncmp(&htmlbuf[i],"<", 4)) {
+ nohtml[j] = '<';
+ i += 3;
+ } else if (!strncmp(&htmlbuf[i],">", 4)) {
+ nohtml[j] = '>';
+ i += 3;
+ }
+ } else if (!strncmp(&htmlbuf[i],"<br>", 4) ||
+ !strncmp(&htmlbuf[i],"<br/>", 5)) {
+ nohtml[j] = '\n';
+ i += (htmlbuf[i+3] == '/' ? 4 : 3);
+ } else if (htmlbuf[i] == '<') {
+ /* Let's strip all unknown tags */
+ j--;
+ while (htmlbuf[++i] != '>');
+ } else
+ nohtml[j] = htmlbuf[i];
+ j++;
+ }
+ nohtml[j] = '\0';
+ return nohtml;
+}
+
+/* html_escape(text)
+ * Add (x)html entities to the text.
+ * The caller must g_free the string after use.
+ * Code mostly derived from strescape(), in libjabber.
+ */
+char *html_escape(const char *text)
+{
+ int i, j;
+ int oldlen, newlen;
+ char *html;
+
+ if (!text) return(NULL);
+
+ oldlen = newlen = strlen(text);
+
+ for (i = 0; i < oldlen; i++) {
+ switch(text[i])
+ {
+ case '&':
+ newlen += 5;
+ break;
+ case '\'':
+ newlen += 6;
+ break;
+ case '\"':
+ newlen += 6;
+ break;
+ case '<':
+ newlen += 4;
+ break;
+ case '>':
+ newlen += 4;
+ break;
+ case '\n':
+ newlen += 5;
+ }
+ }
+
+ if (oldlen == newlen)
+ return g_strdup(text);
+
+ html = g_new0(char, newlen+1);
+
+ for (i = j = 0; i < oldlen; i++) {
+ switch(text[i])
+ {
+ case '&':
+ memcpy(&html[j], "&", 5);
+ j += 5;
+ break;
+ case '\'':
+ memcpy(&html[j], "'", 6);
+ j += 6;
+ break;
+ case '\"':
+ memcpy(&html[j], """, 6);
+ j += 6;
+ break;
+ case '<':
+ memcpy(&html[j], "<", 4);
+ j += 4;
+ break;
+ case '>':
+ memcpy(&html[j], ">", 4);
+ j += 4;
+ break;
+ case '\n':
+ memcpy(&html[j], "<br/>", 5);
+ j += 5;
+ break;
+ default:
+ html[j++] = text[i];
+ }
+ }
+ return html;
+}
+
+/* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */
diff --git a/src/nohtml.h b/src/nohtml.h
--- /dev/null
+++ b/src/nohtml.h
@@ -0,0 +1,9 @@
+#ifndef __NOHTML_H__
+#define __NOHTML_H__ 1
+
+char *html_strip(const char *buf);
+char *html_escape(const char *text);
+
+#endif /* __NOHTML_H__ */
+
+/* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */
diff --git a/src/otr.c b/src/otr.c
--- a/src/otr.c
+++ b/src/otr.c
*/
#include <config.h>
+#include <glib.h>
#ifdef HAVE_LIBOTR
#include "utils.h"
#include "screen.h"
#include "settings.h"
+#include "nohtml.h"
static OtrlUserState userstate = NULL;
static char * otr_get_dir(void);
-void otr_init(const char *jid)
+void otr_init(const char *fjid)
{
char *root;
userstate = otrl_userstate_create ();
root = otr_get_dir();
- account = jidtodisp(jid);
+ account = jidtodisp(fjid);
keyfile = g_strdup_printf("%s%s.key", root, account);
fprfile = g_strdup_printf("%s%s.fpr", root, account);
g_free(root);
if (!ignore_message && newmessage) {
*free_msg = 1;
- *otr_data = g_strdup(newmessage);
+ *otr_data = html_strip(newmessage);
otrl_message_free(newmessage);
if (ctx->msgstate == OTRL_MSGSTATE_ENCRYPTED)
return 1;
{
gcry_error_t err;
char *newmessage = NULL;
+ char *htmlmsg;
ConnContext * ctx = otr_get_context(buddy);
+ htmlmsg = html_escape(*msg);
+
err = otrl_message_sending(userstate, &ops, NULL, account, "jabber", buddy,
- *msg, NULL, &newmessage, NULL, NULL);
+ htmlmsg, NULL, &newmessage, NULL, NULL);
+
+ g_free(htmlmsg);
if (err)
*msg = NULL; /*something went wrong, don't send the plain-message! */
const char *protocol, const char *username,
const char *msg)
{
- scr_WriteIncomingMessage(username, msg, 0, HBB_PREFIX_INFO, 0);
+ char *strippedmsg = html_strip(msg);
+ scr_WriteIncomingMessage(username, strippedmsg, 0, HBB_PREFIX_INFO, 0);
+ g_free(strippedmsg);
return 0;
}
diff --git a/src/pgp.c b/src/pgp.c
--- a/src/pgp.c
+++ b/src/pgp.c
/*
* pgp.c -- PGP utility functions
*
- * Copyright (C) 2006-2007 Mikael Berthe <mikael@lilotux.net>
+ * Copyright (C) 2006-2008 Mikael Berthe <mikael@lilotux.net>
* Some parts inspired by centericq (impgp.cc)
*
* This program is free software; you can redistribute it and/or modify
return -1;
}
-inline int gpg_enabled(void)
+int gpg_enabled(void)
{
return gpg.enabled;
}
#else /* not HAVE_GPGME */
-inline int gpg_enabled(void)
+int gpg_enabled(void)
{
return 0;
}
diff --git a/src/pgp.h b/src/pgp.h
--- a/src/pgp.h
+++ b/src/pgp.h
#endif /* HAVE_GPGME */
-inline int gpg_enabled(void);
+int gpg_enabled(void);
#endif /* __PGP_H__ */
diff --git a/src/roster.c b/src/roster.c
--- a/src/roster.c
+++ b/src/roster.c
/*
* roster.c -- Local roster implementation
*
- * Copyright (C) 2005-2007 Mikael Berthe <mikael@lilotux.net>
+ * Copyright (C) 2005-2008 Mikael Berthe <mikael@lilotux.net>
*
* 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
#include "roster.h"
#include "utils.h"
+#include "hooks.h"
+extern void hlog_save_state(void);
-char *strrole[] = { /* Should match enum in roster.h */
+char *strrole[] = { /* Should match enum in roster.h */
"none",
"moderator",
"participant",
"visitor"
};
-char *straffil[] = { /* Should match enum roster.h */
+char *straffil[] = { /* Should match enum in roster.h */
"none",
"owner",
"admin",
"outcast"
};
+char *strprintstatus[] = { /* Should match enum in roster.h */
+ "default",
+ "none",
+ "in_and_out",
+ "all"
+};
+
+char *strautowhois[] = { /* Should match enum in roster.h */
+ "default",
+ "off",
+ "on",
+};
+
/* Resource structure */
typedef struct {
gchar *nickname;
gchar *topic;
guint inside_room;
+ guint print_status;
+ guint auto_whois;
/* on_server is TRUE if the item is present on the server roster */
guint on_server;
static roster roster_special;
-void unread_jid_add(const char *jid);
-int unread_jid_del(const char *jid);
+static int unread_jid_del(const char *jid);
#define DFILTER_ALL 63
#define DFILTER_ONLINE 62
if (roster_usr->flags & ROSTER_FLAG_MSG)
unread_jid_add(roster_usr->jid);
+ sl_group = roster_usr->list;
+
// Let's free roster_usr memory (jid, name, status message...)
free_roster_user_data(roster_usr);
// That's a little complex, we need to dereference twice
- sl_group = ((roster*)sl_user->data)->list;
sl_group_listptr = &((roster*)(sl_group->data))->list;
*sl_group_listptr = g_slist_delete_link(*sl_group_listptr, sl_user);
GSList *sl_user;
roster *roster_usr, *roster_grp;
int new_roster_item = FALSE;
+ guint unread_list_modified = FALSE;
if (special) {
//sl_user = roster_find(jid, namesearch, ROSTER_TYPE_SPECIAL);
roster_usr = (roster*)sl_user->data;
roster_grp = (roster*)roster_usr->list->data;
if (value) {
+ if (!(roster_usr->flags & ROSTER_FLAG_MSG))
+ unread_list_modified = TRUE;
// Message flag is TRUE. This is easy, we just have to set both flags
// to TRUE...
roster_usr->flags |= ROSTER_FLAG_MSG;
} else {
// Message flag is FALSE.
guint msg = FALSE;
+ if (roster_usr->flags & ROSTER_FLAG_MSG)
+ unread_list_modified = TRUE;
roster_usr->flags &= ~ROSTER_FLAG_MSG;
if (unread_list) {
GSList *node = g_slist_find(unread_list, roster_usr);
if (buddylist && (new_roster_item || !g_list_find(buddylist, roster_usr)))
buddylist_build();
+
+ if (unread_list_modified) {
+ guint unread_count = g_slist_length(unread_list);
+ hlog_save_state();
+ /* Call external command */
+ hk_ext_cmd("", 'U', (guchar)MIN(255, unread_count), NULL);
+ }
}
const char *roster_getname(const char *jid)
}
}
-inline int buddylist_isset_filter(void)
+int buddylist_isset_filter(void)
{
return (display_filter != DFILTER_ALL);
}
const char *buddy_getjid(gpointer rosterdata)
{
+ roster *roster_usr = rosterdata;
if (!rosterdata)
return NULL;
- roster *roster_usr = rosterdata;
return roster_usr->jid;
}
return roster_usr->topic;
}
+void buddy_setprintstatus(gpointer rosterdata, enum room_printstatus pstatus)
+{
+ roster *roster_usr = rosterdata;
+ roster_usr->print_status = pstatus;
+}
+
+enum room_printstatus buddy_getprintstatus(gpointer rosterdata)
+{
+ roster *roster_usr = rosterdata;
+ return roster_usr->print_status;
+}
+
+void buddy_setautowhois(gpointer rosterdata, enum room_autowhois awhois)
+{
+ roster *roster_usr = rosterdata;
+ roster_usr->auto_whois = awhois;
+}
+
+enum room_autowhois buddy_getautowhois(gpointer rosterdata)
+{
+ roster *roster_usr = rosterdata;
+ return roster_usr->auto_whois;
+}
+
// buddy_getgroupname()
// Returns a pointer on buddy's group name.
const char *buddy_getgroupname(gpointer rosterdata)
// unread_jid_del(jid)
// Return TRUE if jid is found in the table (and remove it), FALSE if not
-int unread_jid_del(const char *jid)
+static int unread_jid_del(const char *jid)
{
if (!unread_jids)
return FALSE;
return g_hash_table_remove(unread_jids, jid);
}
+// Helper function for unread_jid_get_list()
+static void add_to_unreadjids(gpointer key, gpointer value, gpointer udata)
+{
+ GList **listp = udata;
+ *listp = g_list_append(*listp, key);
+}
+
+// unread_jid_get_list()
+// Return the JID list.
+// The content of the list should not be modified or freed.
+// The caller should call g_list_free() after use.
+GList *unread_jid_get_list(void)
+{
+ GList *list = NULL;
+
+ if (!unread_jids)
+ return NULL;
+
+ // g_hash_table_get_keys() is only in glib >= 2.14
+ //return g_hash_table_get_keys(unread_jids);
+
+ g_hash_table_foreach(unread_jids, add_to_unreadjids, &list);
+ return list;
+}
+
/* vim: set expandtab cindent cinoptions=>2\:2(0: For Vim users... */
diff --git a/src/roster.h b/src/roster.h
--- a/src/roster.h
+++ b/src/roster.h
namesearch
};
+extern char *strprintstatus[];
+
+// Note: do not change the ordering as these values are visible
+// to the user (option 'muc_print_status')!
+enum room_printstatus {
+ status_default,
+ status_none,
+ status_in_and_out,
+ status_all
+};
+
+extern char *strautowhois[];
+
+enum room_autowhois {
+ autowhois_default,
+ autowhois_off,
+ autowhois_on
+};
+
struct role_affil {
enum { type_role, type_affil } type;
union {
void buddylist_build(void);
void buddy_hide_group(gpointer rosterdata, int hide);
void buddylist_set_hide_offline_buddies(int hide);
-inline int buddylist_isset_filter(void);
+int buddylist_isset_filter(void);
void buddylist_set_filter(guchar);
guchar buddylist_get_filter(void);
const char *buddy_getjid(gpointer rosterdata);
guint buddy_getinsideroom(gpointer rosterdata);
void buddy_settopic(gpointer rosterdata, const char *newtopic);
const char *buddy_gettopic(gpointer rosterdata);
+void buddy_setprintstatus(gpointer rosterdata, enum room_printstatus);
+enum room_printstatus buddy_getprintstatus(gpointer rosterdata);
+void buddy_setautowhois(gpointer rosterdata, enum room_autowhois);
+enum room_autowhois buddy_getautowhois(gpointer rosterdata);
void buddy_settype(gpointer rosterdata, guint type);
guint buddy_gettype(gpointer rosterdata);
guint buddy_getsubscription(gpointer rosterdata);
void *param);
gpointer unread_msg(gpointer rosterdata);
+void unread_jid_add(const char *jid);
+GList *unread_jid_get_list(void);
+
GSList *compl_list(guint type);
#endif /* __ROSTER_H__ */
diff --git a/src/screen.c b/src/screen.c
--- a/src/screen.c
+++ b/src/screen.c
/*
* screen.c -- UI stuff
*
- * Copyright (C) 2005-2007 Mikael Berthe <mikael@lilotux.net>
+ * Copyright (C) 2005-2008 Mikael Berthe <mikael@lilotux.net>
* Parts of this file come from the Cabber project <cabber@ajmacias.com>
*
* This program is free software; you can redistribute it and/or modify
#include <string.h>
#include <time.h>
#include <ctype.h>
-#include <locale.h>
-#include <langinfo.h>
+
#include <config.h>
+#include <locale.h>
#include <assert.h>
+#ifdef USE_SIGWINCH
+# include <sys/ioctl.h>
+# include <termios.h>
+# include <unistd.h>
+#endif
+
+#ifdef HAVE_LOCALCHARSET_H
+# include <localcharset.h>
+#else
+# include <langinfo.h>
+#endif
#ifdef HAVE_ASPELL_H
# include <aspell.h>
#define DEFAULT_ROSTER_WIDTH 24
#define CHAT_WIN_HEIGHT (maxY-1-Log_Win_Height)
-char *LocaleCharSet = "C";
+const char *LocaleCharSet = "C";
static unsigned short int Log_Win_Height;
static unsigned short int Roster_Width;
unsigned int prefix_flags, int force_show,
unsigned mucnicklen);
+inline void scr_UpdateBuddyWindow(void);
+inline void scr_set_chatmode(int enable);
+
#ifdef HAVE_ASPELL_H
#define ASPELLBADCHAR 5
AspellConfig *spell_config;
static GHashTable *muccolors = NULL, *nickcolors = NULL;
typedef struct {
- bool manual;//Manually set?
+ bool manual; // Manually set?
int color;
} nickcolor;
if (result != -2)
return result;
+ // Directly support 256-color values
+ result = atoi(name);
+ if (result > 0 && result < COLORS)
+ return result;
+
scr_LogPrint(LPRINT_LOGNORM, "ERROR: Wrong color: %s", name);
return -1;
}
static int get_user_color(const char *color)
{
- bool isbright = false;
+ bool isbright = FALSE;
int cl;
if (!strncmp(color, "bright", 6)) {
- isbright = true;
+ isbright = TRUE;
color += 6;
}
cl = color_to_color_fg(FindColorInternal(color));
g_free(muclow);
} else {//Add or overwrite
if (strcmp(muc, "*")) {
- ensure_string_htable(&muccolors, g_free);
muccoltype *value = g_new(muccoltype, 1);
*value = type;
+ ensure_string_htable(&muccolors, g_free);
g_hash_table_replace(muccolors, muclow, value);
} else {
glob_muccol = type;
void scr_MucNickColor(const char *nick, const char *color)
{
char *snick, *mnick;
- bool need_update = false;
+ bool need_update = FALSE;
snick = g_strdup_printf("<%s>", nick);
mnick = g_strdup_printf("*%s ", nick);
if (!strcmp(color, "-")) {//Remove the color
if (nickcolors) {
nickcolor *nc = g_hash_table_lookup(nickcolors, snick);
if (nc) {//Have this nick already
- nc->manual = false;
+ nc->manual = FALSE;
nc = g_hash_table_lookup(nickcolors, mnick);
assert(nc);//Must have both at the same time
- nc->manual = false;
+ nc->manual = FALSE;
}// Else -> no color saved, nothing to delete
}
g_free(snick);//They are not saved in the hash
g_free(mnick);
- need_update = true;
+ need_update = TRUE;
} else if (!strcmp(color, "!")) {
if (nickcolors) {
g_free(g_hash_table_lookup(nickcolors, snick));
}
g_free(snick);//They are not saved in the hash
g_free(mnick);
- need_update = true;
+ need_update = TRUE;
} else {
int cl = get_user_color(color);
if (cl < 0) {
} else {
nickcolor *nc = g_new(nickcolor, 1);
ensure_string_htable(&nickcolors, NULL);
- nc->manual = true;
+ nc->manual = TRUE;
nc->color = cl;
//Free the struct, if any there already
g_free(g_hash_table_lookup(nickcolors, mnick));
//Save the new ones
g_hash_table_replace(nickcolors, mnick, nc);
g_hash_table_replace(nickcolors, snick, nc);
- need_update = true;
+ need_update = TRUE;
}
}
if (need_update && chatmode &&
void scr_InitLocaleCharSet(void)
{
setlocale(LC_CTYPE, "");
+#ifdef HAVE_LOCALCHARSET_H
+ LocaleCharSet = locale_charset();
+#else
LocaleCharSet = nl_langinfo(CODESET);
+#endif
utf8_mode = (strcmp(LocaleCharSet, "UTF-8") == 0);
}
start_color();
use_default_colors();
+ if (settings_opt_get("escdelay")) {
+#ifdef HAVE_ESCDELAY
+ ESCDELAY = (unsigned) settings_opt_get_int("escdelay");
+#else
+ scr_LogPrint(LPRINT_LOGNORM, "ERROR: no ESCDELAY support.");
+#endif
+ }
+
ParseColors();
getmaxyx(stdscr, maxY, maxX);
return;
}
-inline void scr_Beep(void)
+void scr_Beep(void)
{
beep();
}
};
static int timepreflengths[] = {
+ // (length of the corresponding timeprefix + 5)
17,
11,
6
static const char *gettprefix()
{
- return timeprefixes[settings_opt_get_int("time_prefix")];
+ guint n = settings_opt_get_int("time_prefix");
+ return timeprefixes[(n < 3 ? n : 0)];
}
static const char *getspectprefix()
{
- return spectimeprefixes[settings_opt_get_int("time_prefix")];
+ guint n = settings_opt_get_int("time_prefix");
+ return spectimeprefixes[(n < 3 ? n : 0)];
}
static unsigned getprefixwidth()
{
- return timepreflengths[settings_opt_get_int("time_prefix")];
+ guint n = settings_opt_get_int("time_prefix");
+ return timepreflengths[(n < 3 ? n : 0)];
}
// scr_LogPrint(...)
static void scr_UpdateWindow(winbuf *win_entry)
{
int n;
- int width;
+ int width, prefixwidth;
hbb_line **lines, *line;
GList *hbuf_head;
char date[64];
int color;
width = getmaxx(win_entry->win);
+ prefixwidth = getprefixwidth();
// Should the window be empty?
if (win_entry->bd->cleared) {
}
// Make sure we are at the right position
- wmove(win_entry->win, n, getprefixwidth()-1);
+ wmove(win_entry->win, n, prefixwidth-1);
- //The MUC nick - overwrite with propper color
+ // The MUC nick - overwrite with proper color
if (line->mucnicklen) {
- //Store the char after the nick
- char tmp = line->text[line->mucnicklen];
- muccoltype type = glob_muccol, *typetmp;
- //Terminate the string after the nick
+ char *mucjid;
+ char tmp;
+ nickcolor *actual = NULL;
+ muccoltype type, *typetmp;
+
+ // Store the char after the nick
+ tmp = line->text[line->mucnicklen];
+ type = glob_muccol;
+ // Terminate the string after the nick
line->text[line->mucnicklen] = '\0';
- char *mucjid = g_utf8_strdown(CURRENT_JID, -1);
+ mucjid = g_utf8_strdown(CURRENT_JID, -1);
if (muccolors) {
typetmp = g_hash_table_lookup(muccolors, mucjid);
if (typetmp)
type = *typetmp;
}
g_free(mucjid);
- nickcolor *actual = NULL;
// Need to generate some random color?
if ((type == MC_ALL) && (!nickcolors ||
!g_hash_table_lookup(nickcolors, line->text))) {
+ char *snick, *mnick;
+ nickcolor *nc;
+ snick = g_strdup(line->text);
+ mnick = g_strdup(line->text);
+ nc = g_new(nickcolor, 1);
ensure_string_htable(&nickcolors, NULL);
- char *snick = g_strdup(line->text), *mnick = g_strdup(line->text);
- nickcolor *nc = g_new(nickcolor, 1);
nc->color = nickcols[random() % nickcolcount];
- nc->manual = false;
+ nc->manual = FALSE;
*snick = '<';
snick[strlen(snick)-1] = '>';
*mnick = '*';
mnick[strlen(mnick)-1] = ' ';
- //Insert them
+ // Insert them
g_hash_table_insert(nickcolors, snick, nc);
g_hash_table_insert(nickcolors, mnick, nc);
}
(!(line->flags & HBB_PREFIX_HLIGHT_OUT)))
wattrset(win_entry->win, get_color(actual->color));
wprintw(win_entry->win, "%s", line->text);
- //Return the char
+ // Return the char
line->text[line->mucnicklen] = tmp;
- //Return the color back
+ // Return the color back
wattrset(win_entry->win, get_color(color));
}
ver = mcabber_version();
message = g_strdup_printf("MCabber version %s.\n", ver);
mvwprintw(chatWnd, 0, 0, message);
- mvwprintw(chatWnd, 1, 0, "http://www.lilotux.net/~mikael/mcabber/");
+ mvwprintw(chatWnd, 1, 0, "http://mcabber.com/");
g_free(ver);
g_free(message);
if (fullinit) {
// Enable keypad (+ special keys)
keypad(inputWnd, TRUE);
+#ifdef __MirBSD__
+ wtimeout(inputWnd, 50 /* ms */);
+#else
nodelay(inputWnd, TRUE);
+#endif
// Create panels
rosterPanel = new_panel(rosterWnd);
// We're moving to another buddy. We're thus inactive wrt current_buddy.
set_chatstate(0);
// We don't want the chatstate to be changed again right now.
- lock_chatstate = true;
+ lock_chatstate = TRUE;
prev_st = buddy_getstatus(BUDDATA(current_buddy), NULL);
buddy_setflags(BUDDATA(current_buddy), ROSTER_FLAG_LOCK, FALSE);
update_panels();
}
-#ifdef DEBUG_ENABLE
// buffer_list()
// key: winId/jid
// value: winbuf structure
scr_setmsgflag_if_needed(SPECIAL_BUFFER_STATUS_ID, TRUE);
update_roster = TRUE;
}
-#endif
// scr_set_chatmode()
// Public function to (un)set chatmode...
// Public function to (un)set multimode...
// Convention:
// 0 = disabled / 1 = multimode / 2 = multimode verbatim (commands disabled)
-inline void scr_set_multimode(int enable, char *subject)
+void scr_set_multimode(int enable, char *subject)
{
g_free(multiline);
multiline = NULL;
// scr_get_multiline()
// Public function to get the current multi-line.
-inline const char *scr_get_multiline(void)
+const char *scr_get_multiline(void)
{
if (multimode && multiline)
return multiline;
// scr_get_multimode_subj()
// Public function to get the multi-line subject, if any.
-inline const char *scr_get_multimode_subj(void)
+const char *scr_get_multimode_subj(void)
{
if (multimode)
return multimode_subj;
{
int i, n;
- if (scr_get_multimode() != 2) {
+ if (multimode != 2) {
// Not in verbatim multi-line mode
scr_handle_tab();
} else {
void readline_send_multiline(void)
{
// Validate current multi-line
- if (scr_get_multimode())
+ if (multimode)
process_command(mkcmdstr("msay send"), TRUE);
}
return;
}
-inline void scr_DoUpdate(void)
+void scr_DoUpdate(void)
{
doupdate();
}
int key = kcode.value;
int display_char = FALSE;
- lock_chatstate = false;
+ lock_chatstate = FALSE;
switch (kcode.mcode) {
case 0:
scr_handle_CtrlC();
break;
case KEY_RESIZE:
+#ifdef USE_SIGWINCH
+ {
+ struct winsize size;
+ if (ioctl(STDIN_FILENO, TIOCGWINSZ, &size) != -1)
+ resizeterm(size.ws_row, size.ws_col);
+ }
scr_Resize();
+ process_command(mkcmdstr("screen_refresh"), TRUE);
+#else
+ scr_Resize();
+#endif
break;
default:
display_char = TRUE;
display:
if (display_char) {
- if (kcode.utf8 ? iswprint(key) : (isprint(key) && !is_speckey(key))) {
+ guint printable;
+
+ if (kcode.utf8) {
+ printable = iswprint(key);
+ } else {
+#ifdef __CYGWIN__
+ printable = (isprint(key) || (key >= 161 && key <= 255))
+ && !is_speckey(key);
+#else
+ printable = isprint(key) && !is_speckey(key);
+#endif
+ }
+ if (printable) {
char tmpLine[INPUTLINE_LENGTH+1];
// Check the line isn't too long
diff --git a/src/screen.h b/src/screen.h
--- a/src/screen.h
+++ b/src/screen.h
guint prefix);
void scr_ShowBuddyWindow(void);
int scr_BuddyBufferExists(const char *jid);
-inline void scr_UpdateBuddyWindow(void);
-inline void scr_set_chatmode(int enable);
-inline int scr_get_chatmode(void);
-inline void scr_set_multimode(int enable, char *subject);
-inline int scr_get_multimode(void);
+void scr_UpdateBuddyWindow(void);
+void scr_set_chatmode(int enable);
+int scr_get_chatmode(void);
+void scr_set_multimode(int enable, char *subject);
+int scr_get_multimode(void);
void scr_setmsgflag_if_needed(const char *jid, int special);
void scr_append_multiline(const char *line);
-inline const char *scr_get_multiline(void);
-inline const char *scr_get_multimode_subj(void);
+const char *scr_get_multiline(void);
+const char *scr_get_multimode_subj(void);
-inline void scr_Beep(void);
+void scr_Beep(void);
bool Autoaway;
void scr_RosterClearColor(void);
void scr_MucColor(const char *muc, muccoltype type);
void scr_MucNickColor(const char *nick, const char *color);
-
-#ifdef DEBUG_ENABLE
void scr_BufferList(void);
-#endif
void readline_transpose_chars(void);
void readline_forward_kill_word(void);
diff --git a/src/settings.c b/src/settings.c
--- a/src/settings.c
+++ b/src/settings.c
/*
* settings.c -- Configuration stuff
*
- * Copyright (C) 2005-2007 Mikael Berthe <mikael@lilotux.net>
+ * Copyright (C) 2005-2008 Mikael Berthe <mikael@lilotux.net>
*
* 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
if (!filename) {
// Use default config file locations
char *home;
+ GString *sfilename;
if (!mainfile) {
scr_LogPrint(LPRINT_LOGNORM, "No file name provided");
err = -1;
goto cfg_read_file_return;
}
- filename = g_new(char, strlen(home)+24);
- sprintf(filename, "%s/.mcabber/mcabberrc", home);
- if ((fp = fopen(filename, "r")) == NULL) {
+ sfilename = g_string_new("");
+ g_string_printf(sfilename, "%s/.mcabber/mcabberrc", home);
+ if ((fp = fopen(sfilename->str, "r")) == NULL) {
// 2nd try...
- sprintf(filename, "%s/.mcabberrc", home);
- if ((fp = fopen(filename, "r")) == NULL) {
+ g_string_printf(sfilename, "%s/.mcabberrc", home);
+ if ((fp = fopen(sfilename->str, "r")) == NULL) {
fprintf(stderr, "Cannot open config file!\n");
- g_free(filename);
+ g_string_free(sfilename, TRUE);
err = -1;
goto cfg_read_file_return;
}
}
// Check configuration file permissions
// As it could contain sensitive data, we make it user-readable only.
- checkset_perm(filename, TRUE);
- scr_LogPrint(LPRINT_LOGNORM, "Reading %s", filename);
+ checkset_perm(sfilename->str, TRUE);
+ scr_LogPrint(LPRINT_LOGNORM, "Reading %s", sfilename->str);
// Check mcabber dir. Here we just warn, we don't change the modes.
- sprintf(filename, "%s/.mcabber/", home);
- checkset_perm(filename, FALSE);
- g_free(filename);
- filename = NULL;
+ g_string_printf(sfilename, "%s/.mcabber/", home);
+ checkset_perm(sfilename->str, FALSE);
+ g_string_free(sfilename, TRUE);
} else {
+ // filename was specified
if ((fp = fopen(filename, "r")) == NULL) {
const char *msg = "Cannot open configuration file";
if (mainfile)
@@ -387,10 +388,14 @@ void settings_foreach(guint type, void (*pfunc)(char *k, char *v, void *param),
// default_muc_nickname()
// Return the user's default nickname
// The caller should free the string after use
-char *default_muc_nickname(void)
+char *default_muc_nickname(const char *roomid)
{
char *nick;
+ nick = (char*)jb_get_bookmark_nick(roomid);
+ if (nick)
+ return g_strdup(nick);
+
// We try the "nickname" option, then the username part of the jid.
nick = (char*)settings_opt_get("nickname");
if (nick)
diff --git a/src/settings.h b/src/settings.h
--- a/src/settings.h
+++ b/src/settings.h
guint get_max_history_blocks(void);
-char *default_muc_nickname(void);
+char *default_muc_nickname(const char *roomid);
const gchar *isbound(int key);
diff --git a/src/utils.c b/src/utils.c
--- a/src/utils.c
+++ b/src/utils.c
/*
* utils.c -- Various utility functions
*
- * Copyright (C) 2005-2007 Mikael Berthe <mikael@lilotux.net>
+ * Copyright (C) 2005-2008 Mikael Berthe <mikael@lilotux.net>
* ut_* functions are derived from Cabber debug/log code.
* from_iso8601() comes from the Pidgin (libpurple) project.
*
struct stat buf;
#ifdef __CYGWIN__
- // Permission checking isn't efficent on Cygwin
+ // Permission checking isn't efficient on Cygwin
return 0;
#endif
- fd = lstat(name, &buf);
+ fd = stat(name, &buf);
if (fd == -1) return -1;
if (buf.st_uid != geteuid()) {
tm_time = gmtime(×tamp);
ret = snprintf(dststr, 19, "%.4d%02d%02dT%02d:%02d:%02dZ",
- 1900+tm_time->tm_year, tm_time->tm_mon+1, tm_time->tm_mday,
+ (int)(1900+tm_time->tm_year), tm_time->tm_mon+1, tm_time->tm_mday,
tm_time->tm_hour, tm_time->tm_min, tm_time->tm_sec);
return ((ret == -1) ? -1 : 0);
char *c;
int tzoff = 0;
int hms_succ = 0;
+ int tmpyear;
time(&retval);
localtime_r(&retval, &t);
c = buf;
/* 4 digit year */
- if (!sscanf(c, "%04d", &t.tm_year)) return 0;
+ if (!sscanf(c, "%04d", &tmpyear)) return 0;
+ t.tm_year = tmpyear;
c+=4;
if (*c == '-')
c++;
return retval;
}
-// Should only be used for delays < 1s
-inline void safe_usleep(unsigned int usec)
-{
- struct timespec req;
- req.tv_sec = 0;
- req.tv_nsec = (long)usec * 1000L;
- nanosleep(&req, NULL);
-}
-
/**
* Derived from libjabber/jid.c, because the libjabber version is not
* really convenient for our usage.
instring = !instring;
strcpy(p, p+1);
p--;
- } else {
+ } else
escape = FALSE;
- }
} else if (*p == '\\') {
if (!escape) {
- if (*(p+1) == '"') {
- strcpy(p, p+1);
- p--;
- }
- escape = TRUE;
- } else {
- escape = FALSE;
+ strcpy(p, p+1);
+ p--;
}
- }
+ escape = !escape;
+ } else
+ escape = FALSE;
}
}
diff --git a/src/utils.h b/src/utils.h
--- a/src/utils.h
+++ b/src/utils.h
#include <config.h>
-extern char *LocaleCharSet;
+extern const char *LocaleCharSet;
#define to_utf8(s) ((s) ? g_locale_to_utf8((s), -1, NULL,NULL,NULL) : NULL)
#define from_utf8(s) ((s) ? g_convert_with_fallback((s), -1, LocaleCharSet, \
int to_iso8601(char *dststr, time_t timestamp);
time_t from_iso8601(const char *timestamp, int utc);
-inline void safe_usleep(unsigned int usec); /* Only for delays < 1s */
-
int check_jid_syntax(const char *fjid);
-inline void mc_strtolower(char *str);
+void mc_strtolower(char *str);
void strip_arg_special_chars(char *s);
char **split_arg(const char *arg, unsigned int n, int dontstriplast);
