Imported Upstream version 0.9.7 upstream/0.9.7
authorGerfried Fuchs <rhonda@debian.org>
Tue, 22 Feb 2011 10:01:08 +0000 (11:01 +0100)
committerGerfried Fuchs <rhonda@debian.org>
Tue, 22 Feb 2011 10:01:08 +0000 (11:01 +0100)
100 files changed:
AUTHORS
ChangeLog
INSTALL
README
TODO
aclocal.m4
config.guess
config.h.in
config.sub
configure
configure.ac
connwrap/connwrap.c
contrib/events/eventcmd
doc/help/de/hlp_buffer.txt
doc/help/de/hlp_room.txt
doc/help/de/hlp_say_to.txt
doc/help/de/hlp_status.txt
doc/help/de/hlp_status_to.txt
doc/help/en/hlp_buffer.txt
doc/help/en/hlp_room.txt
doc/help/en/hlp_say_to.txt
doc/help/en/hlp_status.txt
doc/help/en/hlp_status_to.txt
doc/help/fr/hlp_buffer.txt
doc/help/fr/hlp_room.txt
doc/help/fr/hlp_say_to.txt
doc/help/fr/hlp_status.txt
doc/help/fr/hlp_status_to.txt
doc/help/it/hlp_buffer.txt
doc/help/it/hlp_group.txt
doc/help/it/hlp_room.txt
doc/help/it/hlp_roster.txt
doc/help/it/hlp_say_to.txt
doc/help/it/hlp_status.txt
doc/help/it/hlp_status_to.txt
doc/help/nl/hlp_buffer.txt
doc/help/nl/hlp_room.txt
doc/help/nl/hlp_say_to.txt
doc/help/nl/hlp_status.txt
doc/help/nl/hlp_status_to.txt
doc/help/pl/hlp_buffer.txt
doc/help/pl/hlp_room.txt
doc/help/pl/hlp_say_to.txt
doc/help/pl/hlp_status.txt
doc/help/pl/hlp_status_to.txt
doc/help/ru/hlp_buffer.txt
doc/help/ru/hlp_room.txt
doc/help/ru/hlp_say_to.txt
doc/help/ru/hlp_status.txt
doc/help/ru/hlp_status_to.txt
doc/help/uk/hlp_alias.txt
doc/help/uk/hlp_buffer.txt
doc/help/uk/hlp_color.txt
doc/help/uk/hlp_group.txt
doc/help/uk/hlp_room.txt
doc/help/uk/hlp_roster.txt
doc/help/uk/hlp_say_to.txt
doc/help/uk/hlp_source.txt
doc/help/uk/hlp_status.txt
doc/help/uk/hlp_status_to.txt
doc/mcabber.1
doc/mcabber.1.html
doc/mcabber.1.txt
ltmain.sh
macros/missing/libotr.m4
mcabberrc.example
src/Makefile.am
src/Makefile.in
src/commands.c
src/commands.h
src/compl.c
src/events.c
src/fifo.c [new file with mode: 0644]
src/fifo.h [new file with mode: 0644]
src/hbuf.c
src/hbuf.h
src/help.c
src/histolog.c
src/histolog.h
src/hooks.c
src/hooks.h
src/jab_iq.c
src/jab_priv.h
src/jabglue.c
src/jabglue.h
src/logprint.h
src/main.c
src/nohtml.c [new file with mode: 0644]
src/nohtml.h [new file with mode: 0644]
src/otr.c
src/pgp.c
src/pgp.h
src/roster.c
src/roster.h
src/screen.c
src/screen.h
src/settings.c
src/settings.h
src/utils.c
src/utils.h

diff --git a/AUTHORS b/AUTHORS
index cb77b36..4c79bd9 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -22,6 +22,7 @@ Thanks to the following contributors:
   Oleg Nemanov (aka Lego_12239)
   Piotr Zielonka (aka entragian)
   Michal Vaner (aka vorner)
+  Markus Hennecke
 
 Translators:
   FR    Mikael Berthe
index 2763afd..2bf56bc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,42 @@
+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
diff --git a/INSTALL b/INSTALL
index 88c104d..f2e9418 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -20,6 +20,11 @@ If you want SSL support, you will need openssl lib & dev packages as well.
 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
diff --git a/README b/README
index 208a00e..a22cf33 100644 (file)
--- a/README
+++ b/README
@@ -29,7 +29,7 @@ This is an overview of mcabber Jabber features:
   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
@@ -38,7 +38,7 @@ This software is under development, please give me some feedback (and some
 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>
diff --git a/TODO b/TODO
index 1c17d81..99716eb 100644 (file)
--- a/TODO
+++ b/TODO
@@ -2,24 +2,20 @@
 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
@@ -30,6 +26,13 @@ TODO:
 * 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? :)
 
@@ -42,12 +45,4 @@ TODO:
   - /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
index 52978dc..edb8663 100644 (file)
@@ -15,8 +15,8 @@
 # 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 
@@ -41,10 +41,13 @@ AC_ARG_ENABLE(glibtest, [  --disable-glibtest      do not try to compile and run
          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=""
 
@@ -604,7 +607,7 @@ AC_DEFUN([AM_PATH_LIBGCRYPT],
     fi
   fi
   if test $ok = yes; then
-    AC_MSG_RESULT(yes)
+    AC_MSG_RESULT([yes ($libgcrypt_config_version)])
   else
     AC_MSG_RESULT(no)
   fi
@@ -616,10 +619,10 @@ AC_DEFUN([AM_PATH_LIBGCRYPT],
         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
index 278f9e9..f32079a 100755 (executable)
@@ -1,10 +1,10 @@
 #! /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
@@ -56,8 +56,8 @@ version="\
 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."
@@ -532,7 +532,7 @@ EOF
                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
@@ -799,6 +799,9 @@ EOF
            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
@@ -833,7 +836,14 @@ EOF
        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
@@ -954,8 +964,8 @@ EOF
     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
@@ -1474,9 +1484,9 @@ This script, last modified $timestamp, has failed to recognize
 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
index 6e08f39..6823f51 100644 (file)
@@ -7,7 +7,7 @@
 #undef DATA_DIR
 
 /* Devel compilation options */
-#undef DEBUG_ENABLE
+#undef ENABLE_DEBUG
 
 /* Use Mercurial changeset */
 #undef ENABLE_HGCSET
@@ -41,6 +41,9 @@
 /* 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
 
@@ -68,6 +71,9 @@
 /* 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
 
@@ -83,6 +89,9 @@
 /* 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
 
index 1761d8b..6759825 100755 (executable)
@@ -1,10 +1,10 @@
 #! /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
@@ -72,8 +72,8 @@ Report bugs and patches to <config-patches@gnu.org>."
 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."
@@ -369,10 +369,14 @@ case $basic_machine in
        | 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)
@@ -443,6 +447,14 @@ case $basic_machine in
                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
@@ -668,6 +680,14 @@ case $basic_machine in
                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
                ;;
@@ -813,6 +833,14 @@ case $basic_machine in
                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
                ;;
@@ -1021,6 +1049,10 @@ case $basic_machine in
                basic_machine=tic6x-unknown
                os=-coff
                ;;
+       tile*)
+               basic_machine=tile-unknown
+               os=-linux-gnu
+               ;;
        tx39)
                basic_machine=mipstx39-unknown
                ;;
index 519d952..acc050b 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /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>.
 #
@@ -574,8 +574,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # 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"
@@ -1230,7 +1230,7 @@ if test "$ac_init_help" = "long"; then
   # 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]...
 
@@ -1296,7 +1296,7 @@ fi
 
 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
 
@@ -1305,12 +1305,13 @@ Optional Features:
   --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]
@@ -1401,7 +1402,7 @@ fi
 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,
@@ -1415,7 +1416,7 @@ cat >config.log <<_ACEOF
 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 $@
@@ -2085,7 +2086,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='mcabber'
- VERSION='0.9.5'
+ VERSION='0.9.7'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -4179,9 +4180,11 @@ done
 
 
 
+
 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
@@ -7019,8 +7022,98 @@ _ACEOF
 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
@@ -8706,6 +8799,69 @@ else
 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
@@ -8731,6 +8887,9 @@ fi
          gthread)
              pkg_config_args="$pkg_config_args gthread-2.0"
          ;;
+         gio*)
+             pkg_config_args="$pkg_config_args $module-2.0"
+         ;;
       esac
   done
 
@@ -8841,7 +9000,7 @@ fi
 
 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; }
@@ -9383,8 +9542,8 @@ echo $ECHO_N "checking LIBGCRYPT API version... $ECHO_C" >&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
@@ -10336,7 +10495,7 @@ if test x"${datadir}" != x""; then
   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"
 
@@ -10360,7 +10519,7 @@ fi
 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
@@ -10841,7 +11000,7 @@ exec 6>&1
 # 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
@@ -10894,7 +11053,7 @@ Report bugs to <bug-autoconf@gnu.org>."
 _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'`\\"
 
index 2795885..969a804 100644 (file)
@@ -2,7 +2,7 @@
 # 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)
@@ -33,7 +33,8 @@ fi
 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
 
@@ -66,8 +67,20 @@ AC_CHECK_DECLS([strptime],,,
 # 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"
@@ -101,11 +114,25 @@ else
     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
@@ -117,7 +144,7 @@ if test x"${enable_gpgme}" != x"no"; then
 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
@@ -168,7 +195,7 @@ if test "$with_ssl" != "no"; then
 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 ])
@@ -189,14 +216,14 @@ AC_DEFINE(BUILD_JABBER, 1, [build with jabber support])
 
 # 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"
@@ -211,9 +238,9 @@ else
 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
index 2c83930..e3772c4 100644 (file)
@@ -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(":");
index 8929878..e9d7ba8 100755 (executable)
@@ -43,5 +43,7 @@ if [ $event = "MSG" ]; then
 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
-
index 98c051c..c4c5ba7 100644 (file)
@@ -1,5 +1,5 @@
 
- /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]
 
@@ -13,6 +13,8 @@ Befehl um den Puffer für den momentan ausgewählten Buddy zu verändern. Man ka
  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
index a4f7a85..133b0ff 100644 (file)
@@ -1,6 +1,7 @@
 
  /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.
@@ -36,7 +37,12 @@ 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.
index bd4c683..84713f4 100644 (file)
@@ -1,6 +1,8 @@
 
- /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.
index b388890..78791f3 100644 (file)
@@ -1,8 +1,10 @@
 
  /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.
index 64aa3cb..a1bf349 100644 (file)
@@ -1,5 +1,6 @@
 
  /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!
index e6168ea..a8d775f 100644 (file)
@@ -1,5 +1,5 @@
 
- /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]
 
@@ -13,6 +13,8 @@ Buddy's buffer manipulation command.  Eg. you can search through buffer for "tex
  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
index 15ec483..bbc0700 100644 (file)
@@ -1,6 +1,7 @@
 
  /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.
@@ -37,6 +38,11 @@ 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.
index 15795ec..a79b0e5 100644 (file)
@@ -1,6 +1,8 @@
 
- /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).
index 68699a8..851f8e4 100644 (file)
@@ -1,8 +1,10 @@
 
  /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.
index bcf8afa..182ca75 100644 (file)
@@ -1,5 +1,6 @@
 
  /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.
index 4e9e6b1..c587c9f 100644 (file)
@@ -1,5 +1,5 @@
 
- /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]
 
@@ -10,9 +10,11 @@ Cette commande permet de gérer les tampons de discussions avec les différents
 /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
index 9009579..e4ed0f3 100644 (file)
@@ -1,6 +1,7 @@
 
  /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).
@@ -37,6 +38,11 @@ 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.
index 94e5311..0ed69fb 100644 (file)
@@ -1,5 +1,7 @@
 
- /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).
index ca454f1..2618ffc 100644 (file)
@@ -1,8 +1,10 @@
 
  /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.
index 0414b1d..5652ad7 100644 (file)
@@ -1,5 +1,6 @@
 
  /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é.
index 71b44bc..c518900 100644 (file)
@@ -1,5 +1,5 @@
 
- /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]
 
@@ -13,6 +13,8 @@ Comandi per la manipolazione del buffer del contatto. Per esempio, 
  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
index ba09ece..42f4242 100644 (file)
@@ -1,11 +1,11 @@
 
- /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
index 95e86e5..16e8ea0 100644 (file)
@@ -1,6 +1,7 @@
 
  /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.
@@ -38,6 +39,11 @@ 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.
index 63916b5..c80a379 100644 (file)
@@ -46,6 +46,7 @@ Ecco i parametri disponibili.
 /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
index 9e1e32f..73d77cc 100644 (file)
@@ -1,7 +1,9 @@
 
- /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).
index fb3d731..c9a85fb 100644 (file)
@@ -1,8 +1,10 @@
 
  /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.
index 5727110..512b3ea 100644 (file)
@@ -1,7 +1,8 @@
 
  /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).
index 9873f6f..4061f2b 100644 (file)
@@ -1,5 +1,5 @@
 
- /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]
 
@@ -13,6 +13,8 @@ Manipuleer de chat buffer van de actieve buddy.  Je kunt bijvoorbeeld de buffer
  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
index 6cc518d..b2472e6 100644 (file)
@@ -1,6 +1,7 @@
 
  /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.
@@ -37,6 +38,11 @@ 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.
index fdd9b80..c8c6e9a 100644 (file)
@@ -1,5 +1,8 @@
 
- /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).
index 3c53b34..ed5d6fa 100644 (file)
@@ -1,8 +1,10 @@
 
  /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.
index b82da1a..be670f5 100644 (file)
@@ -1,5 +1,6 @@
 
  /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.
index 929f71f..030e350 100644 (file)
@@ -1,5 +1,5 @@
 
- /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]
 
@@ -13,6 +13,8 @@ Polecenie pozwalające zarządzać buforem rozmowy. Dzięki niemu możemy np. pr
  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
index c12d3ed..1fbd0ec 100644 (file)
@@ -1,6 +1,7 @@
 
  /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.
@@ -37,6 +38,11 @@ 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.
index 39d8609..4a60f65 100644 (file)
@@ -1,6 +1,8 @@
 
- /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")
index 4296825..9590721 100644 (file)
@@ -1,8 +1,10 @@
 
  /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.
index 0cc81e2..becde13 100644 (file)
@@ -1,5 +1,6 @@
 
  /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.
index 3fc8e63..2c1e934 100644 (file)
@@ -1,5 +1,5 @@
 
- /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]
 
@@ -15,6 +15,8 @@
  Очищает текущее окно чата и очищает все содержимое буфера (истории переписки)
 /buffer bottom
  Перемещает к концу буфера (истории переписки) с текущим пользователем
+/buffer list
+ Выводит список всех буферов вместе с количеством содержащихся в них строк/блоков. 
 /buffer top
  Перемещает к началу буфера (истории переписки) с текущим пользователем
 /buffer up [n]
index 362fc0e..f0116ee 100644 (file)
@@ -1,6 +1,7 @@
 
  /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-сервером.
index 416debf..882364a 100644 (file)
@@ -1,6 +1,8 @@
 
- /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").
index 13864b3..b439a3a 100644 (file)
@@ -1,8 +1,10 @@
 
  /STATUS [online|avail|invisible|free|dnd|notavail|away [-|StatusMessage]]
+ /STATUS message -|StatusMessage
 
-Отображает или устанавливает текущий статус.
-Если статус не задан - отображается текущий статус.
-Если статус задан, он будет задан согласно списку переменных в файле конфигурации.
-Если указанного статуса не найдено в списке переменных, устанавливается текущий статус.
-Если "StatusMessage" задан как "-", текущий статус очищается.
+Отображает или устанавливает текущий статус и статусное сообщение.
+Если параметры не заданы, то отобразится текущий статус и статусное сообщение.
+Если статусное сообщение не указано, то оно будет задано согласно списку переменных в файле конфигурации.
+Если указанный статус не найден в списке переменных, сохранится текущее статусное сообщение.
+Если "StatusMessage" имеет вид "-", то статусное сообщение будет очищено.
+Когда команда имеет вид "/status message", устанавливается новое статусное сообщение, а текущий статус сохраняется.
index a3e58eb..c4cc0e2 100644 (file)
@@ -1,5 +1,6 @@
 
  /STATUS_TO jid online|avail|invisible|free|dnd|notavail|away [StatusMessage]
+ /STATUS_TO jid message StatusMessage
 
 Отправляет запрос на определение статуса определенного пользователя.
 Если "jid" указан как "." используется текущий пользователь.
index d395678..4755372 100644 (file)
@@ -14,3 +14,4 @@
  Призначає для "рядок команди" інше ім'я "скорочення"
 
 Приклад: "/alias кава = status away Пішов варити каву..."
+Примітка: наразі кириличні скорочення підтримуються лише у однобайтових кодуваннях.
index bd99efe..d678238 100644 (file)
@@ -1,5 +1,5 @@
 
- /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]
 
@@ -13,6 +13,8 @@
  Потерти всі буфери з пам'яті і позакривати вікна діалогу.
 /buffer purge [jid]
  Очистити вікно діалогу а також потерти його вміст з пам'яті.
+/buffer list
+ Показати перелік усіх відкритих буферів та їх розмір (рядків/блоків).
 /buffer top
  Перейти до початку буферу.
 /buffer bottom
index 95c19e8..0823b85 100644 (file)
@@ -1,6 +1,6 @@
 
  /COLOR roster (статус маска (колір|-)|clear)
- /COLOR mucnick nick (color|-|!)
+ /COLOR mucnick прізвисько (колір|-|!)
  /COLOR muc (jid|.|*) [on|preset|off|-]
 
 Керує кольорами контактів у списку.
@@ -16,4 +16,4 @@
  У режимі on забарвлюються усі прізвиська, у режимі preset - лише ті, для яких колір встановлено командою /color mucnick, а режим off вимикає забарвлення прізвиськ. Режим - прибирає з вказаних jid особисті режими забарвлення. Тоді до них докладається глобальний. Глобальний режим прибрати не можна.
  Початковий глобальний режим - off.
 /color mucnick прізвисько (колір|-|!)
- Створює правило забарвлювати прізвисько вказаним кольором. Якщо вказано -, колір позначається як автоматично обраний, тобто його не буде використано у режимі preset, але у режимі on він залишиться тим самим. Колір ! означає випадковий колір (позначений як автоматично обраний).
+ Створює правило забарвлювати прізвисько вказаним кольором. Якщо вказано -, колір позначається як автоматично обраний, тобто його не буде використано у режимі preset, але у режимі on він залишиться тим самим. Колір ! означає випадковий колір (й позначає його як автоматично обраний). Випадкові кольори беруться з параметру "nick_colors" (mcabberrc)
index 5ebcc67..30472a1 100644 (file)
@@ -1,11 +1,11 @@
 
- /GROUP fold|unfold|toggle [groupname]
+ /GROUP fold|unfold|toggle [назва групи]
 
-Змінює відображення поточної групи.
+Змінює стан відображення вказаної групи. Якщо групу не вказано, береться та, у якій знаходиться вибраний контакт.
 
-/group fold [groupname]
- Згорнути дерево поточної групи у списку.
-/group unfold [groupname]
- Розгорнути дерево поточної групи у списку.
-/group toggle [groupname]
- Змінити стан відображення поточної групи.
+/group fold [назва групи]
+ Згорнути (приховати) дерево групи у списку.
+/group unfold [назва групи]
+ Розгорнути (показати) дерево групи у списку.
+/group toggle [назва групи]
+ Змінити стан відображення групи.
index b6e7e09..aec5c51 100644 (file)
@@ -1,16 +1,17 @@
 
  /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 буде заходити в цю кімнату після з'єднання з сервером.
index ffb6e78..ef62b16 100644 (file)
@@ -45,6 +45,7 @@
 /roster item_unlock [jid]
  Відміняє дію item_lock.
 /roster item_toggle_lock [jid]
+ Перемикає "закріпленість" об'єкта.
 /roster hide
  Сховати список.
 /roster show
index 1836b28..8ef283f 100644 (file)
@@ -1,6 +1,8 @@
 
- /SAY_TO [-n|-h|--] jid текст
+ /SAY_TO [-n|-h] [-q] [-f файл] jid текст
 
 Надсилає текст до вказаного jid.
 Майте на увазі, що ця команда не встановлює стандартного ресурсу для контакту, отже, якщо вам треба надіслати декілька повідомлень до визначених ресурсів, вам треба використовувати "/say_to" для кожного повідомлення.
 Флаги -n та -h змінюють тип повідомлення у "normal" або "headline". "--" використовується, щоб надіслати звичайне повідомлення, що починається з -n чи -h.
+Флаг -q дозволяє надсилати повідомлення, не перемикаючи вікна розмови (корисно при автоматичному надсиланні через fifo).
+Ви можете узяти текст повідомлення із текстового файлу за допомогою аргументу -f. Звісно, якщо вказано файл з повідомленням, "текст" ігнорується, й його можна не вказувати взагалі.
index ed54b40..97b1590 100644 (file)
@@ -2,3 +2,4 @@
  /SOURCE файл
 
 Читає налаштування з файлу.
+Примітка: у під'єднаному до сервера стані команда розуміє й звичайні команди (як то say, group та інші) це можна використати у hook-post-connect (див. mcabberrc).
index 3951c38..bf52535 100644 (file)
@@ -1,8 +1,10 @@
 
  /STATUS [online|avail|invisible|free|dnd|notavail|away [-|повідомлення]]
+ /STATUS message -|повідомлення
 
 Друкує або встановлює ваш статус.
 Якщо статус не вказано, друкує поточний.
 Якщо не вказане повідомлення, використовується повідомлення вказане відповідним параметром message* (з mcabberrc).
 Якщо відповідний message* не визначений, залишається поточне повідомлення.
 "-" тре поточне повідомлення.
+"/status message" змінює лише повідомлення, не чіпаючи поточний статус.
index 02885e6..4ecc58f 100644 (file)
@@ -1,5 +1,6 @@
 
  /STATUS_TO jid online|avail|invisible|free|dnd|notavail|away [повідомлення]
+ /STATUS_TO jid message повідомлення
 
 Надсилає до jid вказаний статус. Поточний контакт можна вказати як "." .
 Примітка: Цей статус буде скинуто наступною командою "/status". Автоматична зміна статусу також це робить.
index 8f4a0e7..00ce9b7 100644 (file)
@@ -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
index cfb6b49..039573c 100644 (file)
@@ -1307,13 +1307,13 @@ consult the AUTHORS file for details.</p>
 <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
index 024a065..18ee50f 100644 (file)
@@ -1,7 +1,7 @@
 MCABBER(1)
 ===========
 Mikael BERTHE <mcabber@lilotux.net>
-v0.9.5, November 2007
+v0.9.7, April 2008
 
 NAME
 ----
@@ -437,7 +437,7 @@ http://www.lilotux.net/~mikael/mcabber/[Main web site]
 
 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
index c715b59..bba8b1c 100644 (file)
--- a/ltmain.sh
+++ b/ltmain.sh
@@ -1,8 +1,8 @@
 # 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
@@ -43,14 +43,22 @@ EXIT_FAILURE=1
 
 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
@@ -105,11 +113,19 @@ esac
 # 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
@@ -136,6 +152,8 @@ duplicate_deps=no
 preserve_args=
 lo2o="s/\\.lo\$/.${objext}/"
 o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
 
 #####################################
 # Shell function definitions:
@@ -196,7 +214,13 @@ func_win32_libid ()
     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";;
@@ -327,7 +351,17 @@ func_extract_archives ()
        *) 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"
@@ -454,11 +488,12 @@ do
     ;;
 
   --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 $?
     ;;
 
@@ -755,9 +790,11 @@ if test -z "$show_help"; then
     *.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/"`
@@ -926,7 +963,7 @@ EOF
       $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
@@ -998,7 +1035,7 @@ EOF
       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
@@ -1131,6 +1168,7 @@ EOF
     thread_safe=no
     vinfo=
     vinfo_number=no
+    single_module="${wl}-single_module"
 
     func_infer_tag $base_compile
 
@@ -1138,8 +1176,9 @@ EOF
     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
@@ -1147,12 +1186,20 @@ EOF
            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
@@ -1600,13 +1647,18 @@ EOF
        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
@@ -1620,10 +1672,11 @@ EOF
       # -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.
@@ -1651,9 +1704,9 @@ EOF
 
       -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
@@ -1712,7 +1765,7 @@ EOF
        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
@@ -2097,7 +2150,7 @@ EOF
        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"
@@ -2112,7 +2165,12 @@ EOF
            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}"
@@ -2493,7 +2551,9 @@ EOF
 
        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.
@@ -2906,12 +2966,18 @@ EOF
                  # 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
@@ -3059,9 +3125,10 @@ EOF
 
     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
@@ -3189,7 +3256,7 @@ EOF
          # 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"
@@ -3200,9 +3267,10 @@ EOF
            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
@@ -3266,7 +3334,8 @@ EOF
          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)
@@ -3280,8 +3349,11 @@ EOF
          ;;
 
        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 ;;
@@ -3418,11 +3490,11 @@ EOF
       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.
@@ -3523,13 +3595,12 @@ EOF
          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 "*)
@@ -3568,9 +3639,7 @@ EOF
              # 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
@@ -3602,7 +3671,7 @@ EOF
                  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
@@ -3888,7 +3957,10 @@ EOF
             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
@@ -4198,9 +4270,10 @@ EOF
       ;;
 
     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
@@ -4247,12 +4320,14 @@ EOF
       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"
@@ -4700,16 +4775,16 @@ static const void *lt_preloaded_setup() {
           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
          ;;
@@ -4724,13 +4799,13 @@ static const void *lt_preloaded_setup() {
        # 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.
@@ -4817,7 +4892,7 @@ static const void *lt_preloaded_setup() {
        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=
@@ -4854,7 +4929,7 @@ static const void *lt_preloaded_setup() {
          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.
@@ -5261,6 +5336,20 @@ EOF
 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
@@ -5403,7 +5492,7 @@ else
          ;;
        esac
        $echo >> $output "\
-      \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+      \$echo \"\$0: cannot exec \$program \$*\"
       exit $EXIT_FAILURE
     fi
   else
@@ -5589,7 +5678,7 @@ fi\
       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
@@ -5934,9 +6023,9 @@ relink_command=\"$relink_command\""
 
          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
@@ -6145,7 +6234,7 @@ relink_command=\"$relink_command\""
              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 :
@@ -6356,8 +6445,10 @@ relink_command=\"$relink_command\""
        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
        ;;
 
@@ -6421,12 +6512,12 @@ relink_command=\"$relink_command\""
       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"
@@ -6783,9 +6874,9 @@ The following components of LINK-COMMAND are treated specially:
   -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
@@ -6799,9 +6890,11 @@ The following components of LINK-COMMAND are treated specially:
   -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.
 
index a21ac3e..36f8b84 100644 (file)
@@ -40,11 +40,11 @@ dnl
 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
index a21286e..8e140f9 100644 (file)
@@ -12,7 +12,7 @@
 # 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
@@ -20,9 +20,14 @@ set username = yourusername
 #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).
@@ -145,7 +150,12 @@ set cmdhistory_lines = 250
 # 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
@@ -185,6 +195,7 @@ set cmdhistory_lines = 250
 #   $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
 #
@@ -193,6 +204,10 @@ set cmdhistory_lines = 250
 #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
@@ -211,6 +226,14 @@ set cmdhistory_lines = 250
 # 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:
@@ -245,6 +268,12 @@ set cmdhistory_lines = 250
 # 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
@@ -267,13 +296,24 @@ set cmdhistory_lines = 250
 # 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
@@ -360,6 +400,10 @@ set message_autoaway = Auto-away (idle)
 # 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
index 65537e2..1d313fd 100644 (file)
@@ -5,10 +5,10 @@ mcabber_SOURCES = main.c roster.c roster.h events.c events.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
+                 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) \
index 6253855..ece1109 100644 (file)
@@ -35,7 +35,7 @@ NORMAL_UNINSTALL = :
 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
@@ -55,15 +55,15 @@ am__mcabber_SOURCES_DIST = main.c roster.c roster.h events.c events.h \
        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 =
@@ -187,7 +187,8 @@ mcabber_SOURCES = main.c roster.c roster.h events.c events.h 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 $(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
 
@@ -264,6 +265,7 @@ distclean-compile:
 @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@
@@ -271,6 +273,7 @@ distclean-compile:
 @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@
index ac4a370..5b2ef74 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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
@@ -20,6 +20,9 @@
  */
 
 #include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
 #include "commands.h"
 #include "help.h"
@@ -33,6 +36,7 @@
 #include "settings.h"
 #include "events.h"
 #include "otr.h"
+#include "utf8.h"
 
 #define IMSTATUS_AWAY           "away"
 #define IMSTATUS_ONLINE         "online"
@@ -167,6 +171,7 @@ void cmd_init(void)
   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");
@@ -207,6 +212,7 @@ void cmd_init(void)
   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");
@@ -236,6 +242,7 @@ void cmd_init(void)
   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");
@@ -305,20 +312,14 @@ char *expandalias(const char *line)
   // 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;
 }
 
@@ -447,9 +448,13 @@ int process_line(const char *line)
       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;
   }
@@ -784,11 +789,11 @@ void do_color(char *arg)
   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;
@@ -800,6 +805,12 @@ void setstatus(const char *recipient, const char *arg)
     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);
@@ -817,7 +828,15 @@ void setstatus(const char *recipient, const char *arg)
   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;
@@ -847,7 +866,7 @@ static void do_status(char *arg)
     return;
   }
   arg = to_utf8(arg);
-  setstatus(NULL, arg);
+  cmd_setstatus(NULL, arg);
   g_free(arg);
 }
 
@@ -901,7 +920,7 @@ static void do_status_to(char *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);
@@ -1002,7 +1021,7 @@ static void do_group(char *arg)
   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.");
@@ -1056,13 +1075,7 @@ static void do_group(char *arg)
   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;
@@ -1072,7 +1085,7 @@ do_group_return:
 }
 
 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()
@@ -1161,7 +1178,7 @@ static void send_message(const char *msg, const char *subj,
     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)
@@ -1299,7 +1316,8 @@ static void do_msay(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);
@@ -1334,11 +1352,92 @@ do_msay_return:
   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.");
@@ -1346,20 +1445,66 @@ static void do_say_to(char *arg)
   }
 
   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);
@@ -1486,10 +1631,8 @@ static void do_buffer(char *arg)
     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!");
   }
@@ -1823,9 +1966,21 @@ static void do_move(char *arg)
 
   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);
@@ -2074,7 +2229,7 @@ static void room_join(gpointer bud, char *arg)
   // 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
@@ -2206,7 +2361,8 @@ static void room_role(gpointer bud, char *arg)
 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);
@@ -2224,12 +2380,35 @@ static void room_ban(gpointer bud, char *arg)
   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);
 }
 
@@ -2285,7 +2464,7 @@ static void room_kick(gpointer bud, char *arg)
   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;
@@ -2322,7 +2501,9 @@ static void room_nick(gpointer bud, char *arg)
     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);
@@ -2349,7 +2530,7 @@ static void room_privmsg(gpointer bud, char *arg)
   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);
@@ -2378,8 +2559,6 @@ static void room_remove(gpointer bud, char *arg)
 
 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;
@@ -2397,10 +2576,8 @@ static void room_topic(gpointer bud, char *arg)
 
   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)
@@ -2426,9 +2603,77 @@ static void room_unlock(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;
@@ -2439,6 +2684,7 @@ void room_whois(gpointer bud, char *arg, guint interactive)
   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;
@@ -2455,7 +2701,8 @@ void room_whois(gpointer bud, char *arg, guint interactive)
     // Enter chat mode
     scr_set_chatmode(TRUE);
     scr_ShowBuddyWindow();
-  }
+  } else
+    msg_flag |= HBB_PREFIX_NOFLAG;
 
   bjid = buddy_getjid(bud);
   rstatus = buddy_getstatus(bud, nick);
@@ -2479,38 +2726,32 @@ void room_whois(gpointer bud, char *arg, guint interactive)
   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);
@@ -2521,6 +2762,8 @@ static void room_bookmark(gpointer bud, char *arg)
 {
   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;
 
@@ -2548,9 +2791,12 @@ static void room_bookmark(gpointer bud, char *arg)
   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)
@@ -2637,7 +2883,7 @@ static void do_room(char *arg)
       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);
@@ -2656,12 +2902,15 @@ static void do_room(char *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)
@@ -3350,7 +3599,7 @@ static void do_connect(char *arg)
 static void do_disconnect(char *arg)
 {
   jb_disconnect();
-  AutoConnection = false;
+  AutoConnection = FALSE;
 }
 
 static void do_help(char *arg)
index 8d5e73a..2bd351e 100644 (file)
@@ -21,9 +21,9 @@ extern char *mcabber_version(void);
 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__ */
 
index 3bd98c0..b977f43 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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
index 55dcd78..7c9df40 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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
new file mode 100644 (file)
index 0000000..3de2a4d
--- /dev/null
@@ -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
new file mode 100644 (file)
index 0000000..4704644
--- /dev/null
@@ -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... */
index 2e660e3..c00ad3c 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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
@@ -412,7 +412,6 @@ GList *hbuf_jump_percent(GList *hbuf, int pc)
   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)
@@ -427,6 +426,5 @@ guint hbuf_get_blocks_number(GList *hbuf)
   }
   return count;
 }
-#endif
 
 /* vim: set expandtab cindent cinoptions=>2\:2(0:  For Vim users... */
index cdf7834..974a65c 100644 (file)
@@ -47,9 +47,7 @@ GList *hbuf_search(GList *hbuf, int direction, const char *string);
 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__ */
 
index 0940f94..a68f339 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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
index 65ebc3a..f6674dc 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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;
@@ -157,6 +159,7 @@ void hlog_read_history(const char *bjid, GList **p_buddyhbuf, guint width)
   char *filename;
   guchar type, info;
   char *data, *tail;
+  guint data_size;
   char *xtext;
   time_t timestamp;
   guint prefix_flags;
@@ -175,7 +178,8 @@ void hlog_read_history(const char *bjid, GList **p_buddyhbuf, guint width)
       (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;
@@ -214,12 +218,38 @@ void hlog_read_history(const char *bjid, GList **p_buddyhbuf, guint width)
   /* 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];
@@ -252,20 +282,34 @@ void hlog_read_history(const char *bjid, GList **p_buddyhbuf, guint width)
       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'))
@@ -349,6 +393,11 @@ void hlog_enable(guint enable, const char *root_dir, guint loadfiles)
   }
 }
 
+guint hlog_is_enabled(void)
+{
+  return UseFileLogging;
+}
+
 inline void hlog_write_message(const char *bjid, time_t timestamp, int sent,
         const char *msg)
 {
@@ -374,4 +423,115 @@ inline void hlog_write_status(const char *bjid, time_t timestamp,
           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... */
index c6b4668..d4f7b43 100644 (file)
@@ -8,10 +8,12 @@
 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__ */
 
index bfefae8..d873d62 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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)
 {
@@ -51,6 +68,7 @@ inline void hk_message_in(const char *bjid, const char *resname,
   char *wmsg = NULL, *bmsg = NULL, *mmsg = NULL;
   GSList *roster_usr;
   unsigned mucnicklen = 0;
+  const char *ename = NULL;
 
   if (encrypted)
     message_flags |= HBB_PREFIX_PGPCRYPT;
@@ -184,12 +202,15 @@ inline void hk_message_in(const char *bjid, const char *resname,
     }
   }
 
+  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) &&
@@ -225,7 +246,7 @@ inline void hk_message_in(const char *bjid, const char *resname,
 //  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;
@@ -263,43 +284,50 @@ inline void hk_message_out(const char *bjid, const char *nick,
   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",
@@ -383,23 +411,24 @@ void hk_ext_cmd(const char *bjid, guchar type, guchar info, const char *data)
   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);
@@ -407,6 +436,11 @@ void hk_ext_cmd(const char *bjid, guchar type, guchar info, const char *data)
           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;
   }
index 8446026..550f146 100644 (file)
@@ -5,15 +5,16 @@
 #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);
 
index 2983571..9639f28 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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/>
@@ -739,6 +739,7 @@ void request_vcard(const char *bjid)
 static void storage_bookmarks_parse_conference(xmlnode xmldata)
 {
   const char *fjid, *name, *autojoin;
+  const char *pstatus, *awhois;
   char *bjid;
   GSList *room_elt;
 
@@ -747,6 +748,8 @@ static void storage_bookmarks_parse_conference(xmlnode xmldata)
     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
 
@@ -766,6 +769,25 @@ static void storage_bookmarks_parse_conference(xmlnode xmldata)
     */
   }
 
+  // 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.
@@ -775,7 +797,7 @@ static void storage_bookmarks_parse_conference(xmlnode xmldata)
     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);
@@ -1047,12 +1069,18 @@ static void handle_iq_commands_list(jconn conn, char *from, const char *id,
   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);
 
@@ -1072,15 +1100,17 @@ static void handle_iq_commands_list(jconn conn, char *from, const char *id,
 
 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);
 }
 
@@ -1089,7 +1119,7 @@ static char *generate_session_id(char *prefix)
   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);
@@ -1225,6 +1257,8 @@ static void handle_iq_command_leave_groupchats(jconn conn, char *from,
   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);
@@ -1234,18 +1268,18 @@ static void handle_iq_command_leave_groupchats(jconn conn, char *from,
     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");
@@ -1260,9 +1294,10 @@ static void handle_iq_command_leave_groupchats(jconn conn, char *from,
   {
     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))
       {
@@ -1270,7 +1305,7 @@ static void handle_iq_command_leave_groupchats(jconn conn, char *from,
         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");
@@ -1319,7 +1354,7 @@ static void handle_iq_disco_items(jconn conn, char *from, const char *id,
                                   xmlnode xmldata)
 {
   xmlnode x;
-  char *node;
+  const char *node;
   x = xmlnode_get_tag(xmldata, "query");
   node = xmlnode_get_attrib(x, "node");
   if (node) {
@@ -1552,7 +1587,7 @@ static void handle_iq_time202(jconn conn, char *from, const char *id,
   time_t now_t;
   struct tm *now;
   char const *sign;
-  int diff;
+  int diff = 0;
 
   time(&now_t);
 
@@ -1569,10 +1604,15 @@ static void handle_iq_time202(jconn conn, char *from, const char *id,
 
   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;
index bd3ad50..fffa93c 100644 (file)
@@ -7,7 +7,7 @@
 #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"
 
@@ -38,7 +38,6 @@ const char *entity_version(void);
 
 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);
index 9b2b68f..121d521 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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>
  *
@@ -34,6 +34,7 @@
 #include "commands.h"
 #include "pgp.h"
 #include "otr.h"
+#include "fifo.h"
 
 #define JABBERPORT      5222
 #define JABBERSSLPORT   5223
@@ -48,6 +49,16 @@ char imstatus2char[imstatus_size+1] = {
     '_', '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;
@@ -86,19 +97,20 @@ char *jidtodisp(const char *fjid)
 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;
 }
@@ -220,55 +232,70 @@ void jb_main()
   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);
   }
@@ -401,23 +428,11 @@ static xmlnode presnew(enum imstatus st, const char *recipient,
 
   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:
@@ -432,7 +447,11 @@ static xmlnode presnew(enum imstatus st, const char *recipient,
         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);
@@ -554,7 +573,7 @@ static char *new_msgid(void)
   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.
@@ -584,7 +603,11 @@ void jb_send_msg(const char *fjid, const char *text, int type,
   if (encrypted)
     *encrypted = 0;
 
-  if (!online) return;
+  if (!online)
+    return;
+
+  if (!text && type == ROSTER_TYPE_USER)
+    return;
 
   if (type_overwrite)
     strtype = type_overwrite;
@@ -688,7 +711,7 @@ void jb_send_msg(const char *fjid, const char *text, int type,
    * "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 ||
@@ -880,7 +903,7 @@ void jb_send_chatstate(gpointer buddy, guint chatstate)
   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;
@@ -1353,7 +1376,7 @@ void jb_room_invite(const char *room, const char *fjid, const char *reason)
   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)
 {
@@ -1365,12 +1388,10 @@ 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;
     }
@@ -1378,6 +1399,30 @@ guint jb_is_bookmarked(const char *bjid)
   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).
@@ -1393,12 +1438,10 @@ GSList *jb_get_all_storage_bookmarks(void)
   // 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);
@@ -1407,11 +1450,14 @@ GSList *jb_get_all_storage_bookmarks(void)
   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;
@@ -1429,12 +1475,10 @@ void jb_set_storage_bookmark(const char *roomid, const char *name,
   // 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)) {
@@ -1458,6 +1502,11 @@ void jb_set_storage_bookmark(const char *roomid, const char *name,
       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...");
   }
@@ -1577,12 +1626,10 @@ void jb_set_storage_rosternotes(const char *barejid, const char *note)
   // 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)) {
@@ -1717,7 +1764,7 @@ static void check_signature(const char *barejid, const char *rname,
 }
 
 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;
@@ -1793,8 +1840,17 @@ static void gotmessage(char *type, const char *from, const char *body,
       (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);
   }
@@ -1947,7 +2003,7 @@ static void statehandler(jconn conn, int state)
         online = TRUE;
         update_last_use();
         // We set AutoConnection to true after the 1st successful connection
-        AutoConnection = true;
+        AutoConnection = TRUE;
         break;
 
     case JCONN_STATE_CONNECTING:
@@ -1989,6 +2045,113 @@ static time_t xml_get_timestamp(xmlnode xmldata)
   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,
@@ -2000,10 +2163,13 @@ static void handle_presence_muc(const char *from, xmlnode xmldata,
   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;
@@ -2024,36 +2190,8 @@ static void handle_presence_muc(const char *from, xmlnode xmldata,
   }
 
   // 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);
@@ -2084,6 +2222,18 @@ static void handle_presence_muc(const char *from, xmlnode xmldata,
       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);
@@ -2096,10 +2246,12 @@ static void handle_presence_muc(const char *from, xmlnode xmldata,
     // 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;
 
@@ -2169,11 +2321,14 @@ static void handle_presence_muc(const char *from, xmlnode xmldata,
       }
     }
 
-    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);
@@ -2186,64 +2341,40 @@ static void handle_presence_muc(const char *from, xmlnode xmldata,
     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();
 }
@@ -2262,6 +2393,13 @@ static void handle_packet_presence(jconn conn, char *type, char *from,
   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
@@ -2421,14 +2559,20 @@ static void handle_packet_message(jconn conn, char *type, char *from,
   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;
@@ -2456,22 +2600,9 @@ static void handle_packet_message(jconn conn, char *type, char *from,
       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);
 
@@ -2486,8 +2617,8 @@ static void handle_packet_message(jconn conn, char *type, char *from,
   } 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) {
@@ -2495,7 +2626,6 @@ static void handle_packet_message(jconn conn, char *type, char *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)
@@ -2713,7 +2843,7 @@ static int evscallback_invitation(eviqs *evp, guint evcontext)
   // 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 {
index 2744ca5..9919363 100644 (file)
@@ -42,11 +42,12 @@ struct annotation {
   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);
@@ -56,18 +57,18 @@ void jb_subscr_request_cancel(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);
@@ -78,10 +79,12 @@ int  jb_room_setattrib(const char *roomid, const char *fjid, const char *nick,
 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);
index 93117a6..faaf756 100644 (file)
@@ -12,7 +12,7 @@
 
 void scr_LogPrint(unsigned int flag, const char *fmt, ...);
 
-inline void scr_DoUpdate(void);
+void scr_DoUpdate(void);
 
 #endif /* __LOGPRINT_H__ */
 
index e6e31fe..30b6079 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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
@@ -42,6 +42,7 @@
 #include "utils.h"
 #include "pgp.h"
 #include "otr.h"
+#include "fifo.h"
 
 #ifdef ENABLE_HGCSET
 # include "hgcset.h"
@@ -70,7 +71,8 @@ void mcabber_connect(void)
 {
   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;
@@ -100,8 +102,6 @@ void mcabber_connect(void)
     scr_LogPrint(LPRINT_NORMAL, "Password has not been specified!");
     return;
   }
-  if (!resource)
-    resource = "mcabber";
 
   port    = (unsigned int) settings_opt_get_int("port");
 
@@ -125,7 +125,7 @@ void mcabber_connect(void)
     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,
@@ -139,11 +139,22 @@ void mcabber_connect(void)
   // 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");
@@ -160,12 +171,13 @@ void mcabber_connect(void)
     }
   }
 
-  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);
@@ -210,6 +222,10 @@ void sig_handler(int signum)
     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);
   }
@@ -280,7 +296,7 @@ static void compile_options(void)
 #ifdef WITH_ASPELL
   puts("Compiled with Aspell support.");
 #endif
-#ifdef DEBUG_ENABLE
+#ifdef ENABLE_DEBUG
   puts("Compiled with debugging support.");
 #endif
 }
@@ -364,6 +380,9 @@ int main(int argc, char **argv)
   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 */
@@ -476,6 +495,12 @@ int main(int argc, char **argv)
 
   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();
@@ -499,10 +524,12 @@ int main(int argc, char **argv)
         scr_DrawRoster();
 
       jb_main();
+      hk_mainloop();
     }
   }
 
   scr_TerminateCurses();
+  fifo_deinit();
 #ifdef HAVE_LIBOTR
   otr_terminate();
 #endif
@@ -512,10 +539,11 @@ int main(int argc, char **argv)
 #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
new file mode 100644 (file)
index 0000000..a4b7614
--- /dev/null
@@ -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],"&amp;",5)) {
+        nohtml[j] = '&';
+        i += 4;
+      } else if (!strncmp(&htmlbuf[i],"&quot;", 6)) {
+        nohtml[j] = '\"';
+        i += 5;
+      } else if (!strncmp(&htmlbuf[i],"&apos;", 6)) {
+        nohtml[j] = '\'';
+        i += 5;
+      } else if (!strncmp(&htmlbuf[i],"&lt;", 4)) {
+        nohtml[j] = '<';
+        i += 3;
+      } else if (!strncmp(&htmlbuf[i],"&gt;", 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], "&amp;", 5);
+          j += 5;
+          break;
+      case '\'':
+          memcpy(&html[j], "&apos;", 6);
+          j += 6;
+          break;
+      case '\"':
+          memcpy(&html[j], "&quot;", 6);
+          j += 6;
+          break;
+      case '<':
+          memcpy(&html[j], "&lt;", 4);
+          j += 4;
+          break;
+      case '>':
+          memcpy(&html[j], "&gt;", 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
new file mode 100644 (file)
index 0000000..9e373a3
--- /dev/null
@@ -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... */
index 67965ff..eb61279 100644 (file)
--- a/src/otr.c
+++ b/src/otr.c
@@ -20,6 +20,7 @@
  */
 
 #include <config.h>
+#include <glib.h>
 
 #ifdef HAVE_LIBOTR
 
@@ -31,6 +32,7 @@
 #include "utils.h"
 #include "screen.h"
 #include "settings.h"
+#include "nohtml.h"
 
 
 static OtrlUserState userstate = NULL;
@@ -112,7 +114,7 @@ static void otr_handle_smp_tlvs(OtrlTLV * tlvs, ConnContext * ctx);
 
 static char * otr_get_dir(void);
 
-void otr_init(const char *jid)
+void otr_init(const char *fjid)
 {
   char *root;
 
@@ -126,7 +128,7 @@ void otr_init(const char *jid)
   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);
@@ -379,7 +381,7 @@ int otr_receive(char **otr_data, const char * buddy, int * free_msg)
 
   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;
@@ -391,10 +393,15 @@ int otr_send(char **msg, const char *buddy)
 {
   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! */
@@ -655,7 +662,9 @@ static int cb_display_otr_message(void *opdata, const char *accountname,
                                   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;
 }
 
index 6433a5b..f4fc68a 100644 (file)
--- a/src/pgp.c
+++ b/src/pgp.c
@@ -1,7 +1,7 @@
 /*
  * 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
@@ -454,14 +454,14 @@ int gpg_test_passphrase(void)
   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;
 }
index 46c19c2..9871d04 100644 (file)
--- a/src/pgp.h
+++ b/src/pgp.h
@@ -22,7 +22,7 @@ int   gpg_test_passphrase(void);
 
 #endif /* HAVE_GPGME */
 
-inline int gpg_enabled(void);
+int gpg_enabled(void);
 
 #endif /* __PGP_H__ */
 
index 9d7236a..4f80f18 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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",
@@ -40,6 +42,19 @@ char *straffil[] = { /* Should match enum roster.h */
   "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 {
@@ -76,6 +91,8 @@ 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;
@@ -103,8 +120,7 @@ GList *alternate_buddy;
 
 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
@@ -432,11 +448,12 @@ void roster_del_user(const char *jid)
   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);
 
@@ -574,6 +591,7 @@ void roster_msg_setflag(const char *jid, guint special, guint value)
   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);
@@ -606,6 +624,8 @@ void roster_msg_setflag(const char *jid, guint special, guint value)
   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;
@@ -616,6 +636,8 @@ void roster_msg_setflag(const char *jid, guint special, guint value)
   } 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);
@@ -644,6 +666,13 @@ void roster_msg_setflag(const char *jid, guint special, guint value)
 
   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)
@@ -779,7 +808,7 @@ void buddylist_set_hide_offline_buddies(int hide)
   }
 }
 
-inline int buddylist_isset_filter(void)
+int buddylist_isset_filter(void)
 {
   return (display_filter != DFILTER_ALL);
 }
@@ -887,9 +916,9 @@ void buddy_hide_group(gpointer rosterdata, int hide)
 
 const char *buddy_getjid(gpointer rosterdata)
 {
+  roster *roster_usr = rosterdata;
   if (!rosterdata)
     return NULL;
-  roster *roster_usr = rosterdata;
   return roster_usr->jid;
 }
 
@@ -1026,6 +1055,30 @@ const char *buddy_gettopic(gpointer rosterdata)
   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)
@@ -1501,11 +1554,36 @@ void unread_jid_add(const char *jid)
 
 //  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... */
index 7e1dcd4..d31236c 100644 (file)
@@ -56,6 +56,25 @@ enum findwhat {
   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 {
@@ -158,7 +177,7 @@ void    roster_unsubscribed(const char *jid);
 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);
@@ -170,6 +189,10 @@ void        buddy_setinsideroom(gpointer rosterdata, guint inside);
 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);
@@ -209,6 +232,9 @@ void    foreach_group_member(gpointer groupdata,
                              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__ */
index 499636c..e3fc2f1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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>
@@ -50,7 +61,7 @@
 #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;
@@ -139,6 +150,9 @@ void scr_WriteInWindow(const char *winId, const char *text, time_t timestamp,
                        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;
@@ -156,7 +170,7 @@ static GSList *rostercolrules = NULL;
 static GHashTable *muccolors = NULL, *nickcolors = NULL;
 
 typedef struct {
-  bool manual;//Manually set?
+  bool manual; // Manually set?
   int color;
 } nickcolor;
 
@@ -237,16 +251,21 @@ static int FindColor(const char *name)
   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));
@@ -283,9 +302,9 @@ void scr_MucColor(const char *muc, muccoltype type)
     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;
@@ -304,22 +323,22 @@ void scr_MucColor(const char *muc, muccoltype 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));
@@ -328,7 +347,7 @@ void scr_MucNickColor(const char *nick, const char *color)
     }
     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) {
@@ -338,14 +357,14 @@ void scr_MucNickColor(const char *nick, const char *color)
     } 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 &&
@@ -734,7 +753,11 @@ static int is_speckey(int key)
 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);
 }
 
@@ -751,6 +774,14 @@ void scr_InitCurses(void)
   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);
@@ -775,7 +806,7 @@ void scr_TerminateCurses(void)
   return;
 }
 
-inline void scr_Beep(void)
+void scr_Beep(void)
 {
   beep();
 }
@@ -794,6 +825,7 @@ static const char *spectimeprefixes[] = {
 };
 
 static int timepreflengths[] = {
+  // (length of the corresponding timeprefix + 5)
   17,
   11,
   6
@@ -801,17 +833,20 @@ static int timepreflengths[] = {
 
 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(...)
@@ -960,13 +995,14 @@ static winbuf *scr_new_buddy(const char *title, int dont_show)
 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) {
@@ -1055,36 +1091,43 @@ static void scr_UpdateWindow(winbuf *win_entry)
       }
 
       // 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);
         }
@@ -1095,9 +1138,9 @@ static void scr_UpdateWindow(winbuf *win_entry)
            (!(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));
       }
 
@@ -1430,7 +1473,7 @@ void scr_DrawMainWindow(unsigned int fullinit)
   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);
 
@@ -1441,7 +1484,11 @@ void scr_DrawMainWindow(unsigned int fullinit)
   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);
@@ -2085,7 +2132,7 @@ static void set_current_buddy(GList *newbuddy)
   // 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);
@@ -2630,7 +2677,6 @@ void scr_BufferDate(time_t t)
   update_panels();
 }
 
-#ifdef DEBUG_ENABLE
 //  buffer_list()
 // key: winId/jid
 // value: winbuf structure
@@ -2655,7 +2701,6 @@ void scr_BufferList(void)
   scr_setmsgflag_if_needed(SPECIAL_BUFFER_STATUS_ID, TRUE);
   update_roster = TRUE;
 }
-#endif
 
 //  scr_set_chatmode()
 // Public function to (un)set chatmode...
@@ -2710,7 +2755,7 @@ void scr_setmsgflag_if_needed(const char *bjid, int special)
 // 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;
@@ -2726,7 +2771,7 @@ inline void scr_set_multimode(int enable, char *subject)
 
 //  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;
@@ -2735,7 +2780,7 @@ inline const char *scr_get_multiline(void)
 
 //  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;
@@ -3085,7 +3130,7 @@ void readline_do_completion(void)
 {
   int i, n;
 
-  if (scr_get_multimode() != 2) {
+  if (multimode != 2) {
     // Not in verbatim multi-line mode
     scr_handle_tab();
   } else {
@@ -3209,7 +3254,7 @@ void readline_forward_kill_iline(void)
 void readline_send_multiline(void)
 {
   // Validate current multi-line
-  if (scr_get_multimode())
+  if (multimode)
     process_command(mkcmdstr("msay send"), TRUE);
 }
 
@@ -3653,7 +3698,7 @@ void scr_Getch(keycode *kcode)
   return;
 }
 
-inline void scr_DoUpdate(void)
+void scr_DoUpdate(void)
 {
   doupdate();
 }
@@ -3702,7 +3747,7 @@ void process_key(keycode kcode)
   int key = kcode.value;
   int display_char = FALSE;
 
-  lock_chatstate = false;
+  lock_chatstate = FALSE;
 
   switch (kcode.mcode) {
     case 0:
@@ -3742,7 +3787,17 @@ void process_key(keycode kcode)
         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;
@@ -3750,7 +3805,19 @@ void process_key(keycode kcode)
 
 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
index 018ebcb..48c0512 100644 (file)
@@ -119,17 +119,17 @@ void scr_WriteOutgoingMessage(const char *jidto,   const char *text,
                               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;
 
@@ -167,10 +167,7 @@ bool scr_RosterColor(const char *status, const char *wildcard,
 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);
index 0d0aedd..98ca47f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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
@@ -97,6 +97,7 @@ int cfg_read_file(char *filename, guint mainfile)
   if (!filename) {
     // Use default config file locations
     char *home;
+    GString *sfilename;
 
     if (!mainfile) {
       scr_LogPrint(LPRINT_LOGNORM, "No file name provided");
@@ -110,28 +111,28 @@ int cfg_read_file(char *filename, guint mainfile)
       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)
index b9b15d3..162dbc9 100644 (file)
@@ -52,7 +52,7 @@ void    settings_otr_setpolicy(const char *bjid, guint value);
 
 guint get_max_history_blocks(void);
 
-char *default_muc_nickname(void);
+char *default_muc_nickname(const char *roomid);
 
 const gchar *isbound(int key);
 
index d9a986f..13238d1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * 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.
  *
@@ -135,11 +135,11 @@ int checkset_perm(const char *name, unsigned int setmode)
   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()) {
@@ -203,7 +203,7 @@ int to_iso8601(char *dststr, time_t timestamp)
   tm_time = gmtime(&timestamp);
 
   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);
@@ -222,6 +222,7 @@ time_t from_iso8601(const char *timestamp, int utc)
   char *c;
   int tzoff = 0;
   int hms_succ = 0;
+  int tmpyear;
 
   time(&retval);
   localtime_r(&retval, &t);
@@ -233,7 +234,8 @@ time_t from_iso8601(const char *timestamp, int utc)
   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++;
@@ -301,15 +303,6 @@ time_t from_iso8601(const char *timestamp, int utc)
   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.
@@ -402,20 +395,16 @@ void strip_arg_special_chars(char *s)
         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;
   }
 }
 
index f967575..924fc22 100644 (file)
@@ -3,7 +3,7 @@
 
 #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, \
@@ -26,11 +26,9 @@ const char *ut_get_tmpdir(void);
 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);