Changes in / [8b8def58:38ff846]
- Files:
-
- 15 added
- 35 deleted
- 70 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
r8b8def58 r38ff846 10 10 11 11 # Program variables 12 objects = bitlbee.o dcc.o help.o ipc.o irc.o irc_im.o irc_channel.o irc_commands.o irc_send.o irc_user.o irc_util.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS)13 headers = account.h bitlbee.h commands.h conf.h config.h help.h ipc.h irc.h log.h nick.h query.h set.h sock.h storage.h user.h lib/events.h lib/ftutil.h lib/http_client.h lib/ini.h lib/md5.h lib/misc.h lib/proxy.h lib/sha1.h lib/ssl_client.h lib/url.h protocols/ft.h protocols/nogaim.h12 objects = account.o bitlbee.o chat.o crypting.o help.o ipc.o irc.o irc_commands.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) user.o 13 headers = account.h bitlbee.h commands.h conf.h config.h crypting.h help.h ipc.h irc.h log.h nick.h query.h set.h sock.h storage.h user.h lib/events.h lib/http_client.h lib/ini.h lib/md5.h lib/misc.h lib/proxy.h lib/sha1.h lib/ssl_client.h lib/url.h protocols/nogaim.h 14 14 subdirs = lib protocols 15 15 … … 82 82 install-dev: 83 83 mkdir -p $(DESTDIR)$(INCLUDEDIR) 84 install -m 0644 config.h $(DESTDIR)$(INCLUDEDIR) 85 for i in $(headers); do install -m 0644 $(SRCDIR)$$i $(DESTDIR)$(INCLUDEDIR); done 84 install -m 0644 $(headers) $(DESTDIR)$(INCLUDEDIR) 86 85 mkdir -p $(DESTDIR)$(PCDIR) 87 86 install -m 0644 bitlbee.pc $(DESTDIR)$(PCDIR) … … 94 93 install-etc: 95 94 mkdir -p $(DESTDIR)$(ETCDIR) 96 install -m 0644 $(SRCDIR)motd.txt $(DESTDIR)$(ETCDIR)/motd.txt97 install -m 0644 $(SRCDIR)bitlbee.conf $(DESTDIR)$(ETCDIR)/bitlbee.conf95 install -m 0644 motd.txt $(DESTDIR)$(ETCDIR)/motd.txt 96 install -m 0644 bitlbee.conf $(DESTDIR)$(ETCDIR)/bitlbee.conf 98 97 99 98 uninstall-etc: … … 111 110 @$(MAKE) -C $@ $(MAKECMDGOALS) 112 111 113 $(objects): %.o: $(SRCDIR)%.c112 $(objects): %.o: %.c 114 113 @echo '*' Compiling $< 115 114 @$(CC) -c $(CFLAGS) $< -o $@ -
bitlbee.c
r8b8def58 r38ff846 121 121 } 122 122 123 global.listen_watch_source_id = b_input_add( global.listen_socket, B_EV_IO_READ, bitlbee_io_new_client, NULL );123 global.listen_watch_source_id = b_input_add( global.listen_socket, GAIM_INPUT_READ, bitlbee_io_new_client, NULL ); 124 124 125 125 #ifndef _WIN32 … … 321 321 child->pid = client_pid; 322 322 child->ipc_fd = fds[0]; 323 child->ipc_inpa = b_input_add( child->ipc_fd, B_EV_IO_READ, ipc_master_read, child );323 child->ipc_inpa = b_input_add( child->ipc_fd, GAIM_INPUT_READ, ipc_master_read, child ); 324 324 child_list = g_slist_append( child_list, child ); 325 325 … … 349 349 /* We can store the IPC fd there now. */ 350 350 global.listen_socket = fds[1]; 351 global.listen_watch_source_id = b_input_add( fds[1], B_EV_IO_READ, ipc_child_read, irc );351 global.listen_watch_source_id = b_input_add( fds[1], GAIM_INPUT_READ, ipc_child_read, irc ); 352 352 353 353 close( fds[0] ); -
bitlbee.h
r8b8def58 r38ff846 43 43 44 44 #if HAVE_CONFIG_H 45 #include <config.h>45 #include "config.h" 46 46 #endif 47 47 … … 126 126 #define CONF_FILE_DEF ETCDIR "bitlbee.conf" 127 127 128 #include "bee.h"129 128 #include "irc.h" 130 129 #include "storage.h" … … 161 160 gboolean bitlbee_io_current_client_write( gpointer data, gint source, b_input_condition cond ); 162 161 163 void root_command_string( irc_t *irc, char *command);162 void root_command_string( irc_t *irc, user_t *u, char *command, int flags ); 164 163 void root_command( irc_t *irc, char *command[] ); 165 164 gboolean bitlbee_shutdown( gpointer data, gint fd, b_input_condition cond ); -
conf.c
r8b8def58 r38ff846 63 63 conf->ping_timeout = 300; 64 64 conf->user = NULL; 65 conf->ft_max_size = SIZE_MAX;66 conf->ft_max_kbps = G_MAXUINT;67 conf->ft_listen = NULL;68 65 conf->protocols = NULL; 69 66 proxytype = 0; … … 318 315 conf->user = g_strdup( ini->value ); 319 316 } 320 else if( g_strcasecmp( ini->key, "ft_max_size" ) == 0 )321 {322 size_t ft_max_size;323 if( sscanf( ini->value, "%zu", &ft_max_size ) != 1 )324 {325 fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );326 return 0;327 }328 conf->ft_max_size = ft_max_size;329 }330 else if( g_strcasecmp( ini->key, "ft_max_kbps" ) == 0 )331 {332 if( sscanf( ini->value, "%d", &i ) != 1 )333 {334 fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value );335 return 0;336 }337 conf->ft_max_kbps = i;338 }339 else if( g_strcasecmp( ini->key, "ft_listen" ) == 0 )340 {341 g_free( conf->ft_listen );342 conf->ft_listen = g_strdup( ini->value );343 }344 317 else if( g_strcasecmp( ini->key, "protocols" ) == 0 ) 345 318 { … … 376 349 if( g_strcasecmp( ini->section, "defaults" ) == 0 ) 377 350 { 378 set_t *s = set_find( &irc-> b->set, ini->key );351 set_t *s = set_find( &irc->set, ini->key ); 379 352 380 353 if( s ) -
conf.h
r8b8def58 r38ff846 50 50 int ping_timeout; 51 51 char *user; 52 size_t ft_max_size;53 int ft_max_kbps;54 char *ft_listen;55 52 char **protocols; 56 53 } conf_t; -
configure
r8b8def58 r38ff846 27 27 yahoo=1 28 28 twitter=1 29 twitter=130 purple=031 29 32 30 debug=0 … … 69 67 --oscar=0/1 Disable/enable Oscar part (ICQ, AIM) $oscar 70 68 --yahoo=0/1 Disable/enable Yahoo part $yahoo 71 --twitter=0/1 Disable/enable Twitter part $twitter 72 73 --purple=0/1 Disable/enable libpurple support $purple 69 --twitter=0/1 Disable/enable Twitter part $twitter 74 70 75 71 --debug=0/1 Disable/enable debugging $debug … … 125 121 EOF 126 122 127 srcdir="$(dirname $0)"128 if [ "$srcdir" != "." ]; then129 echo130 echo "configure script run from a different directory. Will create some symlinks..."131 if [ ! -e Makefile -o -L Makefile ]; then132 COPYDIRS="doc lib protocols tests utils"133 mkdir -p $(cd "$srcdir"; find $COPYDIRS -type d)134 find . -name Makefile -type l -print0 | xargs -0 rm 2> /dev/null135 dst="$PWD"136 cd "$srcdir"137 for i in $(find . -name Makefile -type f); do138 ln -s "$PWD${i#.}" "$dst/$i";139 done140 cd "$dst"141 rm -rf .bzr142 fi143 144 echo "SRCDIR=$srcdir/" >> Makefile.settings145 CFLAGS="$CFLAGS -I${dst}"146 else147 srcdir=$PWD148 fi149 150 123 cat<<EOF>config.h 151 124 /* BitlBee settings, generated by configure … … 185 158 186 159 echo CFLAGS=$CFLAGS >> Makefile.settings 187 echo CFLAGS+=-I ${srcdir} -I${srcdir}/lib -I${srcdir}/protocols -I. >> Makefile.settings160 echo CFLAGS+=-I`pwd` -I`pwd`/lib -I`pwd`/protocols -I. >> Makefile.settings 188 161 189 162 echo CFLAGS+=-DHAVE_CONFIG_H >> Makefile.settings … … 425 398 fi 426 399 427 STORAGES=" xml"400 STORAGES="text xml" 428 401 429 402 if [ "$ldap" = "auto" ]; then … … 535 508 protoobjs='' 536 509 537 if [ "$purple" = 0 ]; then538 echo '#undef WITH_PURPLE' >> config.h539 else540 if ! $PKG_CONFIG purple; then541 echo542 echo 'Cannot find libpurple development libraries, aborting. (Install libpurple-dev?)'543 exit 1544 fi545 echo '#define WITH_PURPLE' >> config.h546 cat<<EOF>>Makefile.settings547 EFLAGS += $($PKG_CONFIG purple --libs)548 PURPLE_CFLAGS += $($PKG_CONFIG purple --cflags)549 EOF550 protocols=$protocols'purple '551 protoobjs=$protoobjs'purple_mod.o '552 553 # Having both libpurple and native IM modules in one binary may554 # do strange things. Let's not do that.555 msn=0556 jabber=0557 oscar=0558 yahoo=0559 twitter=0560 561 if [ "$events" = "libevent" ]; then562 echo563 echo 'Warning: Some libpurple modules (including msn-pecan) do their event handling'564 echo 'outside libpurple, talking to GLib directly. At least for now the combination'565 echo 'libpurple + libevent is *not* recommended!'566 fi567 fi568 569 510 if [ "$msn" = 0 ]; then 570 511 echo '#undef WITH_MSN' >> config.h -
debian/bitlbee.init
-
Property
mode
changed from
100644
to100755
-
Property
mode
changed from
-
debian/changelog
r8b8def58 r38ff846 1 bitlbee (1.3-0) unstable; urgency=low2 3 * Setting some bogus version number, fix that later.4 * Now using debhelper to improve maintainability.5 * Added a bitlbee-libpurple package, and split off docs and stuff into6 bitlbee-common.7 8 -- Wilmer van der Gaast <wilmer@gaast.net> Sat, 05 Jun 2010 15:16:38 +01009 10 1 bitlbee (1.2.7-1) unstable; urgency=high 11 2 -
debian/control
r8b8def58 r38ff846 4 4 Maintainer: Wilmer van der Gaast <wilmer@gaast.net> 5 5 Uploaders: Jelmer Vernooij <jelmer@samba.org> 6 Standards-Version: 3.8. 47 Build-Depends: libglib2.0-dev (>= 2.4), libevent-dev, libgnutls-dev | libnss-dev (>= 1.6), po-debconf, libpurple-dev, debhelper (>= 6)6 Standards-Version: 3.8.0 7 Build-Depends: libglib2.0-dev (>= 2.4), libevent-dev, libgnutls-dev | libnss-dev (>= 1.6), debconf-2.0, po-debconf 8 8 Homepage: http://www.bitlbee.org/ 9 9 Vcs-Bzr: http://code.bitlbee.org/bitlbee/ … … 12 12 Package: bitlbee 13 13 Architecture: any 14 Depends: ${shlibs:Depends}, adduser, debianutils (>= 1.16), bitlbee-common (= ${bee:Version}) 15 Conflicts: bitlbee-libpurple 16 Replaces: bitlbee-libpurple 17 Description: An IRC to other chat networks gateway (default version) 14 Depends: ${shlibs:Depends}, adduser, net-tools, ${debconf-depends}, debianutils (>= 1.16) 15 Description: An IRC to other chat networks gateway 18 16 This program can be used as an IRC server which forwards everything you 19 17 say to people on other chat networks: Jabber, ICQ, AIM, MSN, Yahoo! and 20 18 Twitter. 21 19 22 Package: bitlbee-libpurple23 Architecture: any24 Depends: ${shlibs:Depends}, adduser, debianutils (>= 1.16), bitlbee-common (= ${bee:Version})25 Conflicts: bitlbee26 Replaces: bitlbee27 Description: An IRC to other chat networks gateway (using libpurple)28 This program can be used as an IRC server which forwards everything you29 say to people on other chat networks: Jabber, ICQ, AIM, MSN, Yahoo! and30 Twitter.31 .32 This package contains a version of BitlBee that uses the libpurple instant33 messaging library instead of built-in code, which adds support for more IM34 protocols (all protocols supported by Pidgin/Finch) and features (like file35 transfers), at the price of being less lightweight.36 .37 This variant may not be very suitable for BitlBee instances used by many38 (tens or hundreds) of clients.39 40 Package: bitlbee-common41 Architecture: all42 Depends: ${misc:Depends}, net-tools43 Replaces: bitlbee44 Description: An IRC to other chat networks gateway (common files/docs)45 This program can be used as an IRC server which forwards everything you46 say to people on other chat networks: Jabber, ICQ, AIM, MSN, Yahoo! and47 Twitter.48 .49 This package contains common files (mostly documentation) for bitlbee and50 bitlbee-libpurple.51 52 20 Package: bitlbee-dev 53 21 Architecture: all 54 Depends: ${misc:Depends}, bitlbee (>= ${bee:Version}), bitlbee (<< ${bee:Version}.1~)55 Description: An IRC to other chat networks gateway (dev files)22 Depends: bitlbee (>= ${source:Version}), bitlbee (<< ${source:Version}.1~) 23 Description: An IRC to other chat networks gateway 56 24 This program can be used as an IRC server which forwards everything you 57 25 say to people on other chat networks: Jabber, ICQ, AIM, MSN, Yahoo! and -
debian/patches/bitlbee.conf.diff
r8b8def58 r38ff846 1 --- bitlbee.conf 2009-06-01 00:20:24.000000000 +01002 +++ bitlbee.conf 2009-06-07 21:16:19.000000000 +01001 --- debian/bitlbee/etc/bitlbee/bitlbee.conf 2009-06-01 00:20:24.000000000 +0100 2 +++ debian/bitlbee/etc/bitlbee/bitlbee.conf 2009-06-07 21:16:19.000000000 +0100 3 3 @@ -23,13 +23,18 @@ 4 4 ## If BitlBee is started by root as a daemon, it can drop root privileges, -
debian/po/POTFILES.in
r8b8def58 r38ff846 1 [type: gettext/rfc822deb] bitlbee-common.templates1 [type: gettext/rfc822deb] templates -
debian/rules
r8b8def58 r38ff846 1 1 #!/usr/bin/make -f 2 #3 # Finally switching to debhelper.4 #5 # Not using debhelper was an exercise suggested to me by my AM (Gergely6 # Nagy). It was educating at the time but I finally decided that the7 # exercise is over now.8 #9 2 10 BITLBEE_CONFIGURE_FLAGS ?=11 3 DEBUG ?= 0 12 4 13 ifndef BITLBEE_VERSION 5 ifdef BITLBEE_VERSION 6 BITLBEE_FORCE_VERSION=1 7 else 14 8 # Want to use the full package version number instead of just the release. 15 BITLBEE_CONFIGURE_VERSION ?= BITLBEE_VERSION=\"$(shell dpkg-parsechangelog | grep ^Version: | awk '{print $$2}')\" 9 BITLBEE_VERSION ?= "$(shell dpkg-parsechangelog | grep ^Version: | awk '{print $$2}')" 10 export BITLBEE_VERSION 16 11 endif 17 12 18 build: build-stamp 19 build-stamp: 20 dh_testdir 21 22 mkdir -p debian/build-native 23 ROOT=$$PWD; cd debian/build-native; $(BITLBEE_CONFIGURE_VERSION) $$ROOT/configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee --events=libevent $(BITLBEE_CONFIGURE_FLAGS) 24 $(MAKE) -C debian/build-native 25 26 mkdir -p debian/build-libpurple 27 ROOT=$$PWD; cd debian/build-libpurple; $(BITLBEE_CONFIGURE_VERSION) $$ROOT/configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee --purple=1 $(BITLBEE_CONFIGURE_FLAGS) 28 $(MAKE) -C debian/build-libpurple 29 30 $(MAKE) -C doc 31 32 touch build-stamp 13 build-arch: build-arch-stamp 14 build-arch-stamp: 15 [ -d debian ] 16 ./configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee --events=libevent 17 $(MAKE) 18 # $(MAKE) -C doc/ all 19 touch build-arch-stamp 33 20 34 21 clean: 35 dh_testdir 36 dh_testroot 37 rm -f build-stamp 22 [ "`whoami`" = "root" -a -d debian ] 23 rm -rf build-arch-stamp debian/bitlbee debian/*.substvars debian/files debian/bitlbee-dev 24 $(MAKE) distclean 25 # -$(MAKE) -C doc/ clean 26 38 27 39 rm -rf build-arch-stamp debian/build-* 40 $(MAKE) distclean 28 install-arch: build-arch 29 [ "`whoami`" = "root" -a -d debian ] 30 mkdir -p debian/bitlbee/DEBIAN/ 31 $(MAKE) install install-etc DESTDIR=`pwd`/debian/bitlbee 41 32 42 dh_clean 33 mkdir -p debian/bitlbee/usr/share/doc/bitlbee/ 34 cp doc/user-guide/user-guide.txt debian/bitlbee/usr/share/doc/bitlbee/ 35 cp doc/user-guide/user-guide.html debian/bitlbee/usr/share/doc/bitlbee/ 43 36 44 install: build 45 dh_testdir 46 dh_testroot 47 dh_clean -k 48 dh_installdirs 37 install-indep: install-arch 38 [ "`whoami`" = "root" -a -d debian ] 39 mkdir -p debian/bitlbee-dev/DEBIAN/ 40 $(MAKE) install-dev DESTDIR=`pwd`/debian/bitlbee-dev 49 41 50 $(MAKE) -C debian/build-native install install-etc DESTDIR=`pwd`/debian/bitlbee 51 $(MAKE) -C debian/build-libpurple install install-etc DESTDIR=`pwd`/debian/bitlbee-libpurple 52 $(MAKE) -C debian/build-native install-dev DESTDIR=`pwd`/debian/bitlbee-dev 42 mkdir -p debian/bitlbee-dev/usr/share/doc/bitlbee-dev/ 53 43 54 patch debian/bitlbee/etc/bitlbee/bitlbee.conf debian/patches/bitlbee.conf.diff 55 patch debian/bitlbee-libpurple/etc/bitlbee/bitlbee.conf debian/patches/bitlbee.conf.diff44 binary-arch: build-arch install-arch 45 [ "`whoami`" = "root" -a -d debian ] 56 46 57 mkdir -p debian/bitlbee-common/usr 58 mv debian/bitlbee/usr/share debian/bitlbee-common/usr 59 rm -rf debian/bitlbee-libpurple/usr/share 47 chmod 755 debian/post* debian/pre* debian/config debian/bitlbee.init 60 48 61 binary-common: 62 dh_testdir 63 dh_testroot 49 mkdir -p debian/bitlbee/usr/share/doc/bitlbee/examples/ debian/bitlbee/etc/init.d/ 50 -cp doc/RELEASE-SPEECH* debian/bitlbee/usr/share/doc/bitlbee/ && gzip -9 debian/bitlbee/usr/share/doc/bitlbee/RELEASE-SPEECH* 51 cp doc/CREDITS doc/AUTHORS doc/README doc/FAQ debian/README.Debian debian/bitlbee/usr/share/doc/bitlbee/ 52 cp debian/changelog debian/bitlbee/usr/share/doc/bitlbee/changelog.Debian 53 cp debian/copyright debian/bitlbee/usr/share/doc/bitlbee/copyright 54 cp doc/CHANGES debian/bitlbee/usr/share/doc/bitlbee/changelog 55 cp utils/* debian/bitlbee/usr/share/doc/bitlbee/examples/ 56 cp debian/bitlbee.init debian/bitlbee/etc/init.d/bitlbee 57 patch -p0 < debian/patches/bitlbee.conf.diff 58 cd debian/bitlbee/usr/share/; \ 59 gzip -9 doc/bitlbee/changelog.Debian doc/bitlbee/changelog doc/bitlbee/user-guide.txt \ 60 doc/bitlbee/examples/* man/man8/bitlbee.8 man/man5/bitlbee.conf.5 61 62 chown -R root:root debian/bitlbee/ 63 find debian/bitlbee/usr/share/ -type d -exec chmod 755 {} \; 64 find debian/bitlbee/usr/share/ -type f -exec chmod 644 {} \; 65 66 cp debian/prerm debian/bitlbee/DEBIAN/ 67 cp debian/postinst debian/bitlbee/DEBIAN/ 68 cp debian/postrm debian/bitlbee/DEBIAN/ 69 cp debian/config debian/bitlbee/DEBIAN/ 64 70 65 dh_installchangelogs doc/CHANGES 66 dh_installexamples 67 dh_installdocs #--link-doc=bitlbee-common 68 # TODO: Restore --link-doc up here and remove the hack below once 69 # Hardy and Lenny are deprecated. 70 for p in bitlbee bitlbee-libpurple bitlbee-dev; do rm -rf debian/$$p/usr/share/doc/$$p; ln -s bitlbee-common debian/$$p/usr/share/doc/$$p; done 71 dh_installdebconf 72 dh_installinit 73 ifeq ($(DH_OPTIONS),-a) 74 cp -a debian/bitlbee/etc debian/bitlbee-libpurple 71 po2debconf debian/templates > debian/bitlbee/DEBIAN/templates 72 cp debian/conffiles debian/bitlbee/DEBIAN/ 73 74 if [ "$(DEBUG)" = "0" ]; then strip -R .comment -R .note debian/bitlbee/usr/sbin/bitlbee; fi 75 76 cd debian/bitlbee; \ 77 find usr -type f -exec md5sum {} \; > DEBIAN/md5sums 78 dpkg-shlibdeps -Tdebian/bitlbee.substvars -dDepends debian/bitlbee/usr/sbin/bitlbee 79 ifdef BITLBEE_FORCE_VERSION 80 dpkg-gencontrol -ldebian/changelog -isp -pbitlbee -Tdebian/bitlbee.substvars -Pdebian/bitlbee -v1:$(BITLBEE_VERSION)-0 -V'debconf-depends=debconf (>= 1.2.0) | debconf-2.0' 81 else 82 dpkg-gencontrol -ldebian/changelog -isp -pbitlbee -Tdebian/bitlbee.substvars -Pdebian/bitlbee -V'debconf-depends=debconf (>= 1.2.0) | debconf-2.0' 75 83 endif 76 dh_installman 77 dh_strip 78 dh_link 79 dh_compress 80 dh_fixperms 81 dh_installdeb 82 ifeq ($(DH_OPTIONS),-a) 83 cp -a debian/bitlbee/DEBIAN/post* debian/bitlbee/DEBIAN/pre* debian/bitlbee-libpurple/DEBIAN 84 85 dpkg --build debian/bitlbee .. 86 87 binary-indep: install-indep 88 [ "`whoami`" = "root" -a -d debian ] 89 90 chown -R root.root debian/bitlbee-dev/ 91 find debian/bitlbee-dev/usr/share/ -type d -exec chmod 755 {} \; 92 find debian/bitlbee-dev/usr/share/ -type f -exec chmod 644 {} \; 93 94 cp debian/changelog debian/bitlbee-dev/usr/share/doc/bitlbee-dev/changelog.Debian 95 gzip -9 debian/bitlbee-dev/usr/share/doc/bitlbee-dev/changelog.Debian 96 cp debian/copyright debian/bitlbee-dev/usr/share/doc/bitlbee-dev/copyright 97 98 cd debian/bitlbee-dev; \ 99 find usr -type f -exec md5sum {} \; > DEBIAN/md5sums 100 101 ifdef BITLBEE_FORCE_VERSION 102 dpkg-gencontrol -ldebian/changelog -isp -pbitlbee-dev -Pdebian/bitlbee-dev -v1:$(BITLBEE_VERSION)-0 103 else 104 dpkg-gencontrol -ldebian/changelog -isp -pbitlbee-dev -Pdebian/bitlbee-dev 84 105 endif 85 dh_shlibdeps86 ifdef BITLBEE_VERSION87 dh_gencontrol -- -v1:$(BITLBEE_VERSION)-0 -Vbee:Version=1:$(BITLBEE_VERSION)-088 else89 dh_gencontrol -- -Vbee:Version=$(shell dpkg-parsechangelog | grep ^Version: | awk '{print $$2}' | sed -e 's/+[^+]*$$//')90 endif91 dh_md5sums92 dh_builddeb93 106 94 binary-indep: build install 95 $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common 107 dpkg --build debian/bitlbee-dev .. 96 108 97 binary-arch: build install 98 $(MAKE) -f debian/rules DH_OPTIONS=-a binary-common 109 binary: binary-arch binary-indep 110 build: build-arch 111 install: install-arch install-indep 99 112 100 binary-%: build install 101 make -f debian/rules binary-common DH_OPTIONS=-p$* 102 103 binary: binary-indep binary-arch 104 .PHONY: build clean binary-indep binary-arch binary-common binary install 113 .PHONY: build-arch build clean binary-arch binary install-arch install binary-indep install-indep -
doc/Makefile
r8b8def58 r38ff846 1 1 -include ../Makefile.settings 2 ifdef SRCDIR3 SRCDIR := $(SRCDIR)doc/4 endif5 2 6 3 all: … … 10 7 install: 11 8 mkdir -p $(DESTDIR)$(MANDIR)/man8/ $(DESTDIR)$(MANDIR)/man5/ 12 install -m 0644 $(SRCDIR)bitlbee.8 $(DESTDIR)$(MANDIR)/man8/13 install -m 0644 $(SRCDIR)bitlbee.conf.5 $(DESTDIR)$(MANDIR)/man5/9 install -m 0644 bitlbee.8 $(DESTDIR)$(MANDIR)/man8/ 10 install -m 0644 bitlbee.conf.5 $(DESTDIR)$(MANDIR)/man5/ 14 11 $(MAKE) -C user-guide $@ 15 12 -
doc/user-guide/Makefile
r8b8def58 r38ff846 1 1 -include ../../Makefile.settings 2 ifdef SRCDIR3 SRCDIR := $(SRCDIR)doc/user-guide/4 endif5 6 2 EXTRAPARANEWLINE = 1 7 3 # EXTRAPARANEWLINE = 0 … … 42 38 chmod 0755 $(DESTDIR)$(DATADIR) 43 39 rm -f $(DESTDIR)$(DATADIR)/help.txt # Prevent help function from breaking in running sessions 44 install -m 0644 $(SRCDIR)help.txt $(DESTDIR)$(DATADIR)/help.txt40 install -m 0644 help.txt $(DESTDIR)$(DATADIR)/help.txt 45 41 46 42 uninstall: -
doc/user-guide/commands.xml
r8b8def58 r38ff846 484 484 </bitlbee-setting> 485 485 486 <bitlbee-setting name="away_reply_timeout" type="integer" scope="global"> 487 <default>3600</default> 488 489 <description> 490 <para> 491 Most IRC servers send a user's away message every time s/he gets a private message, to inform the sender that they may not get a response immediately. With this setting set to 0, BitlBee will also behave like this. 492 </para> 493 494 <para> 495 Since not all IRC clients do an excellent job at suppressing these messages, this setting lets BitlBee do it instead. BitlBee will wait this many seconds (or until the away state/message changes) before re-informing you that the person's away. 486 <bitlbee-setting name="buddy_sendbuffer" type="boolean" scope="global"> 487 <default>false</default> 488 489 <description> 490 <para> 491 By default, when you send a message to someone, BitlBee forwards this message to the user immediately. When you paste a large number of lines, the lines will be sent in separate messages, which might not be very nice to read. If you enable this setting, BitlBee will buffer your messages and wait for more data. 492 </para> 493 494 <para> 495 Using the <emphasis>buddy_sendbuffer_delay</emphasis> setting you can specify the number of seconds BitlBee should wait for more data before the complete message is sent. 496 </para> 497 498 <para> 499 Please note that if you remove a buddy from your list (or if the connection to that user drops) and there's still data in the buffer, this data will be lost. BitlBee will not try to send the message to the user in those cases. 500 </para> 501 </description> 502 </bitlbee-setting> 503 504 <bitlbee-setting name="buddy_sendbuffer_delay" type="integer" scope="global"> 505 <default>200</default> 506 507 <description> 508 509 <para> 510 Tell BitlBee after how many (mili)seconds a buffered message should be sent. Values greater than 5 will be interpreted as miliseconds, 5 and lower as seconds. 511 </para> 512 513 <para> 514 See also the <emphasis>buddy_sendbuffer</emphasis> setting. 496 515 </para> 497 516 </description> … … 574 593 575 594 <bitlbee-setting name="handle_unknown" type="string" scope="global"> 576 <default> add_channel</default>595 <default>root</default> 577 596 <possible-values>root, add, add_private, add_channel, ignore</possible-values> 578 597 … … 752 771 </description> 753 772 </bitlbee-setting> 754 755 <bitlbee-setting name="paste_buffer" type="boolean" scope="global">756 <default>false</default>757 758 <description>759 <para>760 By default, when you send a message to someone, BitlBee forwards this message to the user immediately. When you paste a large number of lines, the lines will be sent in separate messages, which might not be very nice to read. If you enable this setting, BitlBee will buffer your messages and wait for more data.761 </para>762 763 <para>764 Using the <emphasis>paste_buffer_delay</emphasis> setting you can specify the number of seconds BitlBee should wait for more data before the complete message is sent.765 </para>766 767 <para>768 Please note that if you remove a buddy from your list (or if the connection to that user drops) and there's still data in the buffer, this data will be lost. BitlBee will not try to send the message to the user in those cases.769 </para>770 </description>771 </bitlbee-setting>772 773 <bitlbee-setting name="paste_buffer_delay" type="integer" scope="global">774 <default>200</default>775 776 <description>777 778 <para>779 Tell BitlBee after how many (mili)seconds a buffered message should be sent. Values greater than 5 will be interpreted as miliseconds, 5 and lower as seconds.780 </para>781 782 <para>783 See also the <emphasis>paste_buffer</emphasis> setting.784 </para>785 </description>786 </bitlbee-setting>787 773 788 774 <bitlbee-setting name="port" type="integer" scope="account"> … … 1142 1128 1143 1129 <bitlbee-command name="identify"> 1144 <syntax>identify [-noload|-force]<password></syntax>1130 <syntax>identify <password></syntax> 1145 1131 <short-description>Identify yourself with your password</short-description> 1146 1132 … … 1152 1138 <para> 1153 1139 Once you're registered, you can change your password using <emphasis>set password <password></emphasis>. 1154 </para>1155 1156 <para>1157 The <emphasis>-noload</emphasis> and <emphasis>-force</emphasis> flags can be used to identify when you're logged into some IM accounts already. <emphasis>-force</emphasis> will let you identify yourself and load all saved accounts (and keep the accounts you're logged into already).1158 </para>1159 1160 <para>1161 <emphasis>-noload</emphasis> will log you in but not load any accounts and settings saved under your current nickname. These will be overwritten once you save your settings (i.e. when you disconnect).1162 1140 </para> 1163 1141 </description> … … 1204 1182 1205 1183 </bitlbee-command> 1206 1207 <bitlbee-command name="transfers">1208 <short-description>Monitor, cancel, or reject file transfers</short-description>1209 <syntax>transfers [<cancel> id | <reject>]</syntax>1210 1211 <description>1212 <para>1213 Without parameters the currently pending file transfers and their status will be listed. Available actions are <emphasis>cancel</emphasis> and <emphasis>reject</emphasis>. See <emphasis>help transfers <action></emphasis> for more information.1214 </para>1215 1216 <ircexample>1217 <ircline nick="ulim">transfers</ircline>1218 </ircexample>1219 </description>1220 1221 <bitlbee-command name="cancel">1222 <short-description>Cancels the file transfer with the given id</short-description>1223 <syntax>transfers <cancel> id</syntax>1224 1225 <description>1226 <para>Cancels the file transfer with the given id</para>1227 </description>1228 1229 <ircexample>1230 <ircline nick="ulim">transfers cancel 1</ircline>1231 <ircline nick="root">Canceling file transfer for test</ircline>1232 </ircexample>1233 </bitlbee-command>1234 1235 <bitlbee-command name="reject">1236 <short-description>Rejects all incoming transfers</short-description>1237 <syntax>transfers <reject></syntax>1238 1239 <description>1240 <para>Rejects all incoming (not already transferring) file transfers. Since you probably have only one incoming transfer at a time, no id is neccessary. Or is it?</para>1241 </description>1242 1243 <ircexample>1244 <ircline nick="ulim">transfers reject</ircline>1245 </ircexample>1246 </bitlbee-command>1247 </bitlbee-command>1248 1249 1184 </chapter> -
doc/user-guide/help.xml
r8b8def58 r38ff846 14 14 <varlistentry><term>quickstart</term><listitem><para>A short introduction into BitlBee</para></listitem></varlistentry> 15 15 <varlistentry><term>commands</term><listitem><para>All available commands and settings</para></listitem></varlistentry> 16 <varlistentry><term>channels</term><listitem><para>About creating and customizing channels</para></listitem></varlistentry>17 16 <varlistentry><term>away</term><listitem><para>About setting away states</para></listitem></varlistentry> 18 17 <varlistentry><term>smileys</term><listitem><para>A summary of some non-standard smileys you might find and fail to understand</para></listitem></varlistentry> -
doc/user-guide/misc.xml
r8b8def58 r38ff846 117 117 </sect1> 118 118 119 <sect1 id="nick_changes">120 <title>Changing your nickname</title>121 122 <para>123 BitlBee now allows you to change your nickname. So far this was not possible because it made managing saved accounts more complicated.124 </para>125 126 <para>127 The restriction no longer exists now though. When you change your nick (just using the <emphasis>/nick</emphasis> command), your logged-in status will be reset, which means any changes made to your settings/accounts will not be saved.128 </para>129 130 <para>131 To restore your logged-in status, you need to either use the <emphasis>register</emphasis> command to create an account under the new nickname, or use <emphasis>identify -noload</emphasis> to re-identify yourself under the new nickname. The <emphasis>-noload</emphasis> flag tells the command to verify your password and log you in, but not load any new settings. See <emphasis>help identify</emphasis> for more information.132 </para>133 134 </sect1>135 136 <sect1 id="channels">137 <title>Dealing with channels</title>138 139 <para>140 You can have as many channels in BitlBee as you want. You maintain your channel list using the <emphasis>channel</emphasis> command. You can create new channels by just joining them, like on regular IRC networks.141 </para>142 143 <para>144 You can create two kinds of channels. Control channels, and groupchat channels. By default, BitlBee will set up new channels as control channels if their name starts with an &, and as chat channels if it starts with a #.145 </para>146 147 <para>148 Control channels are where you see your contacts. By default, you will have one control channel called &bitlbee, containing all your contacts. But you can create more, if you want, and divide your contact list accross several channels.149 </para>150 151 <para>152 For example, you can have one channel with all contacts from your MSN Messenger account in it. Or all contacts from the group called "Work".153 </para>154 155 <para>156 Type <emphasis>help channels2</emphasis> to read more.157 </para>158 159 </sect1>160 161 <sect1 id="channels2">162 <title>Creating a channel</title>163 164 <para>165 When you create a new channel, BitlBee will try to guess from its name which contacts to fill it with. For example, if the channel name (excluding the &) matches the name of a group in which you have one or more contacts, the channel will contain all those contacts.166 </para>167 168 <para>169 Any valid account ID (so a number, protocol name or part of screenname, as long as it's unique) can also be used as a channel name. So if you just join &msn, it will contain all your MSN contacts (as long as you have only one MSN account set up). And if you have a Facebook account set up, you can see its contacts by just joining &facebook.170 </para>171 172 <para>173 To start a simple group chat, you simply join a channel which a name starting with #, and invite people into it. All people you invite have to be on the same IM network and contact list.174 </para>175 176 <para>177 If you want to configure your own channels, you can use the <emphasis>channel set</emphasis>.178 </para>179 180 </sect1>181 182 119 </chapter> -
help.c
r8b8def58 r38ff846 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-200 9Wilmer van der Gaast and others *4 * Copyright 2002-2005 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 169 169 return NULL; 170 170 } 171 172 int help_add_mem( help_t **help, const char *title, const char *content )173 {174 help_t *h, *l = NULL;175 176 for( h = *help; h; h = h->next )177 {178 if( g_strcasecmp( h->title, title ) == 0 )179 return 0;180 181 l = h;182 }183 184 if( l )185 h = l->next = g_new0( struct help, 1 );186 else187 *help = h = g_new0( struct help, 1 );188 h->fd = -1;189 h->title = g_strdup( title );190 h->length = strlen( content );191 h->offset.mem_offset = g_strdup( content );192 193 return 1;194 } -
help.h
r8b8def58 r38ff846 46 46 void help_free( help_t **help ); 47 47 char *help_get( help_t **help, char *title ); 48 int help_add_mem( help_t **help, const char *title, const char *content_ );49 48 50 49 #endif -
ipc.c
r8b8def58 r38ff846 138 138 139 139 if( strchr( irc->umode, 'w' ) ) 140 irc_write( irc, ":%s WALLOPS :%s", irc-> root->host, cmd[1] );140 irc_write( irc, ":%s WALLOPS :%s", irc->myhost, cmd[1] ); 141 141 } 142 142 … … 147 147 148 148 if( strchr( irc->umode, 's' ) ) 149 irc_write( irc, ":%s NOTICE %s :%s", irc-> root->host, irc->user->nick, cmd[1] );149 irc_write( irc, ":%s NOTICE %s :%s", irc->myhost, irc->nick, cmd[1] ); 150 150 } 151 151 … … 156 156 157 157 if( strchr( irc->umode, 'o' ) ) 158 irc_write( irc, ":%s NOTICE %s :*** OperMsg *** %s", irc-> root->host, irc->user->nick, cmd[1] );158 irc_write( irc, ":%s NOTICE %s :*** OperMsg *** %s", irc->myhost, irc->nick, cmd[1] ); 159 159 } 160 160 … … 176 176 return; 177 177 178 if( nick_cmp( cmd[1], irc-> user->nick ) != 0 )178 if( nick_cmp( cmd[1], irc->nick ) != 0 ) 179 179 return; /* It's not for us. */ 180 180 181 irc_write( irc, ":%s!%s@%s KILL %s :%s", irc-> root->nick, irc->root->nick, irc->root->host, irc->user->nick, cmd[2] );181 irc_write( irc, ":%s!%s@%s KILL %s :%s", irc->mynick, irc->mynick, irc->myhost, irc->nick, cmd[2] ); 182 182 irc_abort( irc, 0, "Killed by operator: %s", cmd[2] ); 183 183 } … … 188 188 ipc_to_master_str( "HELLO\r\n" ); 189 189 else 190 ipc_to_master_str( "HELLO %s %s :%s\r\n", irc-> user->host, irc->user->nick, irc->user->fullname );190 ipc_to_master_str( "HELLO %s %s :%s\r\n", irc->host, irc->nick, irc->realname ); 191 191 } 192 192 … … 514 514 } 515 515 516 child->ipc_inpa = b_input_add( child->ipc_fd, B_EV_IO_READ, ipc_master_read, child );516 child->ipc_inpa = b_input_add( child->ipc_fd, GAIM_INPUT_READ, ipc_master_read, child ); 517 517 518 518 child_list = g_slist_append( child_list, child ); … … 552 552 } 553 553 554 b_input_add( serversock, B_EV_IO_READ, new_ipc_client, NULL );554 b_input_add( serversock, GAIM_INPUT_READ, new_ipc_client, NULL ); 555 555 556 556 return 1; … … 597 597 return 0; 598 598 } 599 child->ipc_inpa = b_input_add( child->ipc_fd, B_EV_IO_READ, ipc_master_read, child );599 child->ipc_inpa = b_input_add( child->ipc_fd, GAIM_INPUT_READ, ipc_master_read, child ); 600 600 601 601 child_list = g_slist_append( child_list, child ); -
irc.c
r8b8def58 r38ff846 5 5 \********************************************************************/ 6 6 7 /* The IRC-based UI (for now the only one)*/7 /* The big hairy IRCd part of the project */ 8 8 9 9 /* … … 24 24 */ 25 25 26 #define BITLBEE_CORE 26 27 #include "bitlbee.h" 28 #include "sock.h" 29 #include "crypting.h" 27 30 #include "ipc.h" 28 #include "dcc.h" 29 30 GSList *irc_connection_list; 31 32 static gboolean irc_userping( gpointer _irc, gint fd, b_input_condition cond ); 33 static char *set_eval_charset( set_t *set, char *value ); 34 static char *set_eval_password( set_t *set, char *value ); 31 32 static gboolean irc_userping( gpointer _irc, int fd, b_input_condition cond ); 33 34 GSList *irc_connection_list = NULL; 35 36 static char *set_eval_password( set_t *set, char *value ) 37 { 38 irc_t *irc = set->data; 39 40 if( irc->status & USTATUS_IDENTIFIED && value ) 41 { 42 irc_setpass( irc, value ); 43 return NULL; 44 } 45 else 46 { 47 return SET_INVALID; 48 } 49 } 50 51 static char *set_eval_charset( set_t *set, char *value ) 52 { 53 irc_t *irc = set->data; 54 char *test; 55 gsize test_bytes = 0; 56 GIConv ic, oc; 57 58 if( g_strcasecmp( value, "none" ) == 0 ) 59 value = g_strdup( "utf-8" ); 60 61 if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 ) 62 { 63 return NULL; 64 } 65 66 /* Do a test iconv to see if the user picked an IRC-compatible 67 charset (for example utf-16 goes *horribly* wrong). */ 68 if( ( test = g_convert_with_iconv( " ", 1, oc, NULL, &test_bytes, NULL ) ) == NULL || 69 test_bytes > 1 ) 70 { 71 g_free( test ); 72 g_iconv_close( oc ); 73 irc_usermsg( irc, "Unsupported character set: The IRC protocol " 74 "only supports 8-bit character sets." ); 75 return NULL; 76 } 77 g_free( test ); 78 79 if( ( ic = g_iconv_open( "utf-8", value ) ) == (GIConv) -1 ) 80 { 81 g_iconv_close( oc ); 82 return NULL; 83 } 84 85 if( irc->iconv != (GIConv) -1 ) 86 g_iconv_close( irc->iconv ); 87 if( irc->oconv != (GIConv) -1 ) 88 g_iconv_close( irc->oconv ); 89 90 irc->iconv = ic; 91 irc->oconv = oc; 92 93 return value; 94 } 95 96 static char *set_eval_away_status( set_t *set, char *value ) 97 { 98 irc_t *irc = set->data; 99 account_t *a; 100 101 g_free( set->value ); 102 set->value = g_strdup( value ); 103 104 for( a = irc->accounts; a; a = a->next ) 105 { 106 struct im_connection *ic = a->ic; 107 108 if( ic && ic->flags & OPT_LOGGED_IN ) 109 imc_away_send_update( ic ); 110 } 111 112 return value; 113 } 35 114 36 115 irc_t *irc_new( int fd ) … … 39 118 struct sockaddr_storage sock; 40 119 socklen_t socklen = sizeof( sock ); 41 char *host = NULL, *myhost = NULL;42 irc_user_t *iu;43 120 set_t *s; 44 bee_t *b;45 121 46 122 irc = g_new0( irc_t, 1 ); … … 49 125 sock_make_nonblocking( irc->fd ); 50 126 51 irc->r_watch_source_id = b_input_add( irc->fd, B_EV_IO_READ, bitlbee_io_current_client_read, irc );127 irc->r_watch_source_id = b_input_add( irc->fd, GAIM_INPUT_READ, bitlbee_io_current_client_read, irc ); 52 128 53 129 irc->status = USTATUS_OFFLINE; 54 130 irc->last_pong = gettime(); 55 131 56 irc-> nick_user_hash = g_hash_table_new( g_str_hash, g_str_equal );132 irc->userhash = g_hash_table_new( g_str_hash, g_str_equal ); 57 133 irc->watches = g_hash_table_new( g_str_hash, g_str_equal ); 134 135 strcpy( irc->umode, UMODE ); 136 irc->mynick = g_strdup( ROOT_NICK ); 137 irc->channel = g_strdup( ROOT_CHAN ); 58 138 59 139 irc->iconv = (GIConv) -1; … … 62 142 if( global.conf->hostname ) 63 143 { 64 myhost = g_strdup( global.conf->hostname );144 irc->myhost = g_strdup( global.conf->hostname ); 65 145 } 66 146 else if( getsockname( irc->fd, (struct sockaddr*) &sock, &socklen ) == 0 ) … … 71 151 NI_MAXHOST, NULL, 0, 0 ) == 0 ) 72 152 { 73 myhost = g_strdup( ipv6_unwrap( buf ) );153 irc->myhost = g_strdup( ipv6_unwrap( buf ) ); 74 154 } 75 155 } … … 82 162 NI_MAXHOST, NULL, 0, 0 ) == 0 ) 83 163 { 84 host = g_strdup( ipv6_unwrap( buf ) );85 } 86 } 87 88 if( host == NULL )89 host = g_strdup( "localhost.localdomain" );90 if( myhost == NULL )91 myhost = g_strdup( "localhost.localdomain" );164 irc->host = g_strdup( ipv6_unwrap( buf ) ); 165 } 166 } 167 168 if( irc->host == NULL ) 169 irc->host = g_strdup( "localhost.localdomain" ); 170 if( irc->myhost == NULL ) 171 irc->myhost = g_strdup( "localhost.localdomain" ); 92 172 93 173 if( global.conf->ping_interval > 0 && global.conf->ping_timeout > 0 ) 94 174 irc->ping_source_id = b_timeout_add( global.conf->ping_interval * 1000, irc_userping, irc ); 175 176 irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost, "BitlBee-IRCd initialized, please go on" ); 95 177 96 178 irc_connection_list = g_slist_append( irc_connection_list, irc ); 97 179 98 b = irc->b = bee_new(); 99 b->ui_data = irc; 100 b->ui = &irc_ui_funcs; 101 102 s = set_add( &b->set, "away_devoice", "true", set_eval_away_devoice, irc ); 103 s = set_add( &b->set, "away_reply_timeout", "3600", set_eval_int, irc ); 104 s = set_add( &b->set, "charset", "utf-8", set_eval_charset, irc ); 105 s = set_add( &b->set, "default_target", "root", NULL, irc ); 106 s = set_add( &b->set, "display_namechanges", "false", set_eval_bool, irc ); 107 s = set_add( &b->set, "display_timestamps", "true", set_eval_bool, irc ); 108 s = set_add( &b->set, "handle_unknown", "add_channel", NULL, irc ); 109 s = set_add( &b->set, "lcnicks", "true", set_eval_bool, irc ); 110 s = set_add( &b->set, "ops", "both", set_eval_irc_channel_ops, irc ); 111 s = set_add( &b->set, "paste_buffer", "false", set_eval_bool, irc ); 112 s->old_key = g_strdup( "buddy_sendbuffer" ); 113 s = set_add( &b->set, "paste_buffer_delay", "200", set_eval_int, irc ); 114 s->old_key = g_strdup( "buddy_sendbuffer_delay" ); 115 s = set_add( &b->set, "password", NULL, set_eval_password, irc ); 180 s = set_add( &irc->set, "away", NULL, set_eval_away_status, irc ); 116 181 s->flags |= SET_NULL_OK; 117 s = set_add( &b->set, "private", "true", set_eval_bool, irc ); 118 s = set_add( &b->set, "query_order", "lifo", NULL, irc ); 119 s = set_add( &b->set, "root_nick", ROOT_NICK, set_eval_root_nick, irc ); 120 s = set_add( &b->set, "simulate_netsplit", "true", set_eval_bool, irc ); 121 s = set_add( &b->set, "timezone", "local", set_eval_timezone, irc ); 122 s = set_add( &b->set, "to_char", ": ", set_eval_to_char, irc ); 123 s = set_add( &b->set, "typing_notice", "false", set_eval_bool, irc ); 124 125 irc->root = iu = irc_user_new( irc, ROOT_NICK ); 126 iu->host = g_strdup( myhost ); 127 iu->fullname = g_strdup( ROOT_FN ); 128 iu->f = &irc_user_root_funcs; 129 130 iu = irc_user_new( irc, NS_NICK ); 131 iu->host = g_strdup( myhost ); 132 iu->fullname = g_strdup( ROOT_FN ); 133 iu->f = &irc_user_root_funcs; 134 135 irc->user = g_new0( irc_user_t, 1 ); 136 irc->user->host = g_strdup( host ); 182 s = set_add( &irc->set, "away_devoice", "true", set_eval_away_devoice, irc ); 183 s = set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc ); 184 s = set_add( &irc->set, "auto_reconnect", "true", set_eval_bool, irc ); 185 s = set_add( &irc->set, "auto_reconnect_delay", "5*3<900", set_eval_account_reconnect_delay, irc ); 186 s = set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc ); 187 s = set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc ); 188 s = set_add( &irc->set, "charset", "utf-8", set_eval_charset, irc ); 189 s = set_add( &irc->set, "control_channel", irc->channel, set_eval_control_channel, irc ); 190 s = set_add( &irc->set, "debug", "false", set_eval_bool, irc ); 191 s = set_add( &irc->set, "default_target", "root", NULL, irc ); 192 s = set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc ); 193 s = set_add( &irc->set, "display_timestamps", "true", set_eval_bool, irc ); 194 s = set_add( &irc->set, "handle_unknown", "root", NULL, irc ); 195 s = set_add( &irc->set, "lcnicks", "true", set_eval_bool, irc ); 196 s = set_add( &irc->set, "ops", "both", set_eval_ops, irc ); 197 s = set_add( &irc->set, "password", NULL, set_eval_password, irc ); 198 s->flags |= SET_NULL_OK; 199 s = set_add( &irc->set, "private", "true", set_eval_bool, irc ); 200 s = set_add( &irc->set, "query_order", "lifo", NULL, irc ); 201 s = set_add( &irc->set, "root_nick", irc->mynick, set_eval_root_nick, irc ); 202 s = set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc ); 203 s = set_add( &irc->set, "show_offline", "false", set_eval_bool, irc ); 204 s = set_add( &irc->set, "simulate_netsplit", "true", set_eval_bool, irc ); 205 s = set_add( &irc->set, "status", NULL, set_eval_away_status, irc ); 206 s->flags |= SET_NULL_OK; 207 s = set_add( &irc->set, "strip_html", "true", NULL, irc ); 208 s = set_add( &irc->set, "timezone", "local", set_eval_timezone, irc ); 209 s = set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc ); 210 s = set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc ); 137 211 138 212 conf_loaddefaults( irc ); 139 213 140 214 /* Evaluator sets the iconv/oconv structures. */ 141 set_eval_charset( set_find( &b->set, "charset" ), set_getstr( &b->set, "charset" ) ); 142 143 irc_write( irc, ":%s NOTICE AUTH :%s", irc->root->host, "BitlBee-IRCd initialized, please go on" ); 144 145 g_free( myhost ); 146 g_free( host ); 147 148 nogaim_init(); 149 150 return irc; 215 set_eval_charset( set_find( &irc->set, "charset" ), set_getstr( &irc->set, "charset" ) ); 216 217 return( irc ); 151 218 } 152 219 … … 169 236 170 237 ipc_to_master_str( "OPERMSG :Client exiting: %s@%s [%s]\r\n", 171 irc-> user->nick ? irc->user->nick : "(NONE)", irc->user->host, reason );238 irc->nick ? irc->nick : "(NONE)", irc->host, reason ); 172 239 173 240 g_free( reason ); … … 179 246 180 247 ipc_to_master_str( "OPERMSG :Client exiting: %s@%s [%s]\r\n", 181 irc-> user->nick ? irc->user->nick : "(NONE)", irc->user->host, "No reason given" );248 irc->nick ? irc->nick : "(NONE)", irc->host, "No reason given" ); 182 249 } 183 250 … … 200 267 } 201 268 202 static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data ); 203 269 static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data ) 270 { 271 g_free( key ); 272 273 return( TRUE ); 274 } 275 276 /* Because we have no garbage collection, this is quite annoying */ 204 277 void irc_free( irc_t * irc ) 205 278 { 279 user_t *user, *usertmp; 280 206 281 log_message( LOGLVL_INFO, "Destroying connection with fd %d", irc->fd ); 207 282 208 if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc-> b->set, "save_on_quit" ) )283 if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->set, "save_on_quit" ) ) 209 284 if( storage_save( irc, NULL, TRUE ) != STORAGE_OK ) 210 log_message( LOGLVL_WARNING, "Error while saving settings for user %s", irc->user->nick);285 irc_usermsg( irc, "Error while saving settings!" ); 211 286 212 287 irc_connection_list = g_slist_remove( irc_connection_list, irc ); 288 289 while( irc->accounts ) 290 { 291 if( irc->accounts->ic ) 292 imc_logout( irc->accounts->ic, FALSE ); 293 else if( irc->accounts->reconnect ) 294 cancel_auto_reconnect( irc->accounts ); 295 296 if( irc->accounts->ic == NULL ) 297 account_del( irc, irc->accounts ); 298 else 299 /* Nasty hack, but account_del() doesn't work in this 300 case and we don't want infinite loops, do we? ;-) */ 301 irc->accounts = irc->accounts->next; 302 } 213 303 214 304 while( irc->queries != NULL ) 215 305 query_del( irc, irc->queries ); 216 306 217 /* This is a little bit messy: bee_free() frees all b->users which 218 calls us back to free the corresponding irc->users. So do this 219 before we clear the remaining ones ourselves. */ 220 bee_free( irc->b ); 221 222 while( irc->users ) 223 irc_user_free( irc, (irc_user_t *) irc->users->data ); 224 225 while( irc->channels ) 226 irc_channel_free( irc->channels->data ); 307 while( irc->set ) 308 set_del( &irc->set, irc->set->key ); 309 310 if (irc->users != NULL) 311 { 312 user = irc->users; 313 while( user != NULL ) 314 { 315 g_free( user->nick ); 316 g_free( user->away ); 317 g_free( user->handle ); 318 if( user->user != user->nick ) g_free( user->user ); 319 if( user->host != user->nick ) g_free( user->host ); 320 if( user->realname != user->nick ) g_free( user->realname ); 321 b_event_remove( user->sendbuf_timer ); 322 323 usertmp = user; 324 user = user->next; 325 g_free( usertmp ); 326 } 327 } 227 328 228 329 if( irc->ping_source_id > 0 ) … … 236 337 irc->fd = -1; 237 338 238 g_hash_table_foreach_remove( irc-> nick_user_hash, irc_free_hashkey, NULL );239 g_hash_table_destroy( irc-> nick_user_hash );339 g_hash_table_foreach_remove( irc->userhash, irc_free_hashkey, NULL ); 340 g_hash_table_destroy( irc->userhash ); 240 341 241 342 g_hash_table_foreach_remove( irc->watches, irc_free_hashkey, NULL ); … … 249 350 g_free( irc->sendbuffer ); 250 351 g_free( irc->readbuffer ); 352 353 g_free( irc->nick ); 354 g_free( irc->user ); 355 g_free( irc->host ); 356 g_free( irc->realname ); 251 357 g_free( irc->password ); 252 g_free( irc->last_root_cmd ); 358 359 g_free( irc->myhost ); 360 g_free( irc->mynick ); 361 362 g_free( irc->channel ); 363 364 g_free( irc->last_target ); 253 365 254 366 g_free( irc ); … … 262 374 } 263 375 264 static gboolean irc_free_hashkey( gpointer key, gpointer value, gpointer data )265 {266 g_free( key );267 268 return( TRUE );269 }270 271 376 /* USE WITH CAUTION! 272 377 Sets pass without checking */ 273 void irc_setpass (irc_t *irc, const char *pass) 378 void irc_setpass (irc_t *irc, const char *pass) 274 379 { 275 380 g_free (irc->password); … … 282 387 } 283 388 284 static char *set_eval_password( set_t *set, char *value )285 {286 irc_t *irc = set->data;287 288 if( irc->status & USTATUS_IDENTIFIED && value )289 {290 irc_setpass( irc, value );291 return NULL;292 }293 else294 {295 return SET_INVALID;296 }297 }298 299 static char **irc_splitlines( char *buffer );300 301 389 void irc_process( irc_t *irc ) 302 390 { … … 306 394 if( irc->readbuffer != NULL ) 307 395 { 308 lines = irc_ splitlines( irc->readbuffer );396 lines = irc_tokenize( irc->readbuffer ); 309 397 310 398 for( i = 0; *lines[i] != '\0'; i ++ ) … … 343 431 "`help set charset' for more information. Your " 344 432 "message was ignored.", 345 set_getstr( &irc-> b->set, "charset" ) );433 set_getstr( &irc->set, "charset" ) ); 346 434 347 435 g_free( conv ); … … 350 438 else 351 439 { 352 irc_write( irc, ":%s NOTICE AUTH :%s", irc-> root->host,440 irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost, 353 441 "Warning: invalid characters received at login time." ); 354 442 … … 388 476 } 389 477 390 /* Splits a long string into separate lines. The array is NULL-terminated 391 and, unless the string contains an incomplete line at the end, ends with 392 an empty string. Could use g_strsplit() but this one does it in-place. 393 (So yes, it's destructive.) */ 394 static char **irc_splitlines( char *buffer ) 478 /* Splits a long string into separate lines. The array is NULL-terminated and, unless the string 479 contains an incomplete line at the end, ends with an empty string. */ 480 char **irc_tokenize( char *buffer ) 395 481 { 396 482 int i, j, n = 3; … … 523 609 } 524 610 611 void irc_reply( irc_t *irc, int code, char *format, ... ) 612 { 613 char text[IRC_MAX_LINE]; 614 va_list params; 615 616 va_start( params, format ); 617 g_vsnprintf( text, IRC_MAX_LINE, format, params ); 618 va_end( params ); 619 irc_write( irc, ":%s %03d %s %s", irc->myhost, code, irc->nick?irc->nick:"*", text ); 620 621 return; 622 } 623 624 int irc_usermsg( irc_t *irc, char *format, ... ) 625 { 626 char text[1024]; 627 va_list params; 628 char is_private = 0; 629 user_t *u; 630 631 u = user_find( irc, irc->mynick ); 632 is_private = u->is_private; 633 634 va_start( params, format ); 635 g_vsnprintf( text, sizeof( text ), format, params ); 636 va_end( params ); 637 638 return( irc_msgfrom( irc, u->nick, text ) ); 639 } 640 525 641 void irc_write( irc_t *irc, char *format, ... ) 526 642 { … … 533 649 return; 534 650 } 535 536 void irc_write_all( int now, char *format, ... )537 {538 va_list params;539 GSList *temp;540 541 va_start( params, format );542 543 temp = irc_connection_list;544 while( temp != NULL )545 {546 irc_t *irc = temp->data;547 548 if( now )549 {550 g_free( irc->sendbuffer );551 irc->sendbuffer = g_strdup( "\r\n" );552 }553 irc_vawrite( temp->data, format, params );554 if( now )555 {556 bitlbee_io_current_client_write( irc, irc->fd, B_EV_IO_WRITE );557 }558 temp = temp->next;559 }560 561 va_end( params );562 return;563 }564 651 565 652 void irc_vawrite( irc_t *irc, char *format, va_list params ) … … 609 696 in the event queue. */ 610 697 /* Really can't be done as long as the code doesn't do error checking very well: 611 if( bitlbee_io_current_client_write( irc, irc->fd, B_EV_IO_WRITE ) ) */698 if( bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE ) ) */ 612 699 613 700 /* So just always do it via the event handler. */ 614 irc->w_watch_source_id = b_input_add( irc->fd, B_EV_IO_WRITE, bitlbee_io_current_client_write, irc );701 irc->w_watch_source_id = b_input_add( irc->fd, GAIM_INPUT_WRITE, bitlbee_io_current_client_write, irc ); 615 702 } 616 703 … … 618 705 } 619 706 707 void irc_write_all( int now, char *format, ... ) 708 { 709 va_list params; 710 GSList *temp; 711 712 va_start( params, format ); 713 714 temp = irc_connection_list; 715 while( temp != NULL ) 716 { 717 irc_t *irc = temp->data; 718 719 if( now ) 720 { 721 g_free( irc->sendbuffer ); 722 irc->sendbuffer = g_strdup( "\r\n" ); 723 } 724 irc_vawrite( temp->data, format, params ); 725 if( now ) 726 { 727 bitlbee_io_current_client_write( irc, irc->fd, GAIM_INPUT_WRITE ); 728 } 729 temp = temp->next; 730 } 731 732 va_end( params ); 733 return; 734 } 735 736 void irc_names( irc_t *irc, char *channel ) 737 { 738 user_t *u; 739 char namelist[385] = ""; 740 struct groupchat *c = NULL; 741 char *ops = set_getstr( &irc->set, "ops" ); 742 743 /* RFCs say there is no error reply allowed on NAMES, so when the 744 channel is invalid, just give an empty reply. */ 745 746 if( g_strcasecmp( channel, irc->channel ) == 0 ) 747 { 748 for( u = irc->users; u; u = u->next ) if( u->online ) 749 { 750 if( strlen( namelist ) + strlen( u->nick ) > sizeof( namelist ) - 4 ) 751 { 752 irc_reply( irc, 353, "= %s :%s", channel, namelist ); 753 *namelist = 0; 754 } 755 756 if( u->ic && !u->away && set_getbool( &irc->set, "away_devoice" ) ) 757 strcat( namelist, "+" ); 758 else if( ( strcmp( u->nick, irc->mynick ) == 0 && ( strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) == 0 ) ) || 759 ( strcmp( u->nick, irc->nick ) == 0 && ( strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) == 0 ) ) ) 760 strcat( namelist, "@" ); 761 762 strcat( namelist, u->nick ); 763 strcat( namelist, " " ); 764 } 765 } 766 else if( ( c = irc_chat_by_channel( irc, channel ) ) ) 767 { 768 GList *l; 769 770 /* root and the user aren't in the channel userlist but should 771 show up in /NAMES, so list them first: */ 772 sprintf( namelist, "%s%s %s%s ", strcmp( ops, "root" ) == 0 || strcmp( ops, "both" ) ? "@" : "", irc->mynick, 773 strcmp( ops, "user" ) == 0 || strcmp( ops, "both" ) ? "@" : "", irc->nick ); 774 775 for( l = c->in_room; l; l = l->next ) if( ( u = user_findhandle( c->ic, l->data ) ) ) 776 { 777 if( strlen( namelist ) + strlen( u->nick ) > sizeof( namelist ) - 4 ) 778 { 779 irc_reply( irc, 353, "= %s :%s", channel, namelist ); 780 *namelist = 0; 781 } 782 783 strcat( namelist, u->nick ); 784 strcat( namelist, " " ); 785 } 786 } 787 788 if( *namelist ) 789 irc_reply( irc, 353, "= %s :%s", channel, namelist ); 790 791 irc_reply( irc, 366, "%s :End of /NAMES list", channel ); 792 } 793 620 794 int irc_check_login( irc_t *irc ) 621 795 { 622 if( irc->user ->user && irc->user->nick )796 if( irc->user && irc->nick ) 623 797 { 624 798 if( global.conf->authmode == AUTHMODE_CLOSED && !( irc->status & USTATUS_AUTHORIZED ) ) 625 799 { 626 irc_ send_num( irc, 464, ":This server is password-protected." );800 irc_reply( irc, 464, ":This server is password-protected." ); 627 801 return 0; 628 802 } 629 803 else 630 804 { 631 irc_channel_t *ic; 632 irc_user_t *iu = irc->user; 633 634 irc->user = irc_user_new( irc, iu->nick ); 635 irc->user->user = iu->user; 636 irc->user->host = iu->host; 637 irc->user->fullname = iu->fullname; 638 irc->user->f = &irc_user_self_funcs; 639 g_free( iu->nick ); 640 g_free( iu ); 641 642 if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON ) 643 ipc_to_master_str( "CLIENT %s %s :%s\r\n", irc->user->host, irc->user->nick, irc->user->fullname ); 644 645 irc->status |= USTATUS_LOGGED_IN; 646 647 irc_send_login( irc ); 648 649 irc->umode[0] = '\0'; 650 irc_umode_set( irc, "+" UMODE, TRUE ); 651 652 ic = irc->default_channel = irc_channel_new( irc, ROOT_CHAN ); 653 irc_channel_set_topic( ic, CONTROL_TOPIC, irc->root ); 654 irc_channel_add_user( ic, irc->user ); 655 656 irc->last_root_cmd = g_strdup( ROOT_CHAN ); 657 658 irc_send_msg( irc->root, "PRIVMSG", ROOT_CHAN, 659 "Welcome to the BitlBee gateway!\n\n" 660 "If you've never used BitlBee before, please do read the help " 661 "information using the \x02help\x02 command. Lots of FAQs are " 662 "answered there.\n" 663 "If you already have an account on this server, just use the " 664 "\x02identify\x02 command to identify yourself.", NULL ); 665 666 /* This is for bug #209 (use PASS to identify to NickServ). */ 667 if( irc->password != NULL ) 668 { 669 char *send_cmd[] = { "identify", g_strdup( irc->password ), NULL }; 670 671 irc_setpass( irc, NULL ); 672 root_command( irc, send_cmd ); 673 g_free( send_cmd[1] ); 674 } 675 805 irc_login( irc ); 676 806 return 1; 677 807 } … … 684 814 } 685 815 686 void irc_umode_set( irc_t *irc, const char *s, gboolean allow_priv ) 816 void irc_login( irc_t *irc ) 817 { 818 user_t *u; 819 820 irc_reply( irc, 1, ":Welcome to the BitlBee gateway, %s", irc->nick ); 821 irc_reply( irc, 2, ":Host %s is running BitlBee " BITLBEE_VERSION " " ARCH "/" CPU ".", irc->myhost ); 822 irc_reply( irc, 3, ":%s", IRCD_INFO ); 823 irc_reply( irc, 4, "%s %s %s %s", irc->myhost, BITLBEE_VERSION, UMODES UMODES_PRIV, CMODES ); 824 irc_reply( irc, 5, "PREFIX=(ov)@+ CHANTYPES=%s CHANMODES=,,,%s NICKLEN=%d NETWORK=BitlBee " 825 "CASEMAPPING=rfc1459 MAXTARGETS=1 WATCH=128 :are supported by this server", 826 CTYPES, CMODES, MAX_NICK_LENGTH - 1 ); 827 irc_motd( irc ); 828 irc->umode[0] = '\0'; 829 irc_umode_set( irc, "+" UMODE, 1 ); 830 831 u = user_add( irc, irc->mynick ); 832 u->host = g_strdup( irc->myhost ); 833 u->realname = g_strdup( ROOT_FN ); 834 u->online = 1; 835 u->send_handler = root_command_string; 836 u->is_private = 0; /* [SH] The channel is root's personal playground. */ 837 irc_spawn( irc, u ); 838 839 u = user_add( irc, NS_NICK ); 840 u->host = g_strdup( irc->myhost ); 841 u->realname = g_strdup( ROOT_FN ); 842 u->online = 0; 843 u->send_handler = root_command_string; 844 u->is_private = 1; /* [SH] NickServ is not in the channel, so should always /query. */ 845 846 u = user_add( irc, irc->nick ); 847 u->user = g_strdup( irc->user ); 848 u->host = g_strdup( irc->host ); 849 u->realname = g_strdup( irc->realname ); 850 u->online = 1; 851 irc_spawn( irc, u ); 852 853 irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\n" 854 "If you've never used BitlBee before, please do read the help " 855 "information using the \x02help\x02 command. Lots of FAQs are " 856 "answered there.\n" 857 "If you already have an account on this server, just use the " 858 "\x02identify\x02 command to identify yourself." ); 859 860 if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON ) 861 ipc_to_master_str( "CLIENT %s %s :%s\r\n", irc->host, irc->nick, irc->realname ); 862 863 irc->status |= USTATUS_LOGGED_IN; 864 865 /* This is for bug #209 (use PASS to identify to NickServ). */ 866 if( irc->password != NULL ) 867 { 868 char *send_cmd[] = { "identify", g_strdup( irc->password ), NULL }; 869 870 irc_setpass( irc, NULL ); 871 root_command( irc, send_cmd ); 872 g_free( send_cmd[1] ); 873 } 874 } 875 876 void irc_motd( irc_t *irc ) 877 { 878 int fd; 879 880 fd = open( global.conf->motdfile, O_RDONLY ); 881 if( fd == -1 ) 882 { 883 irc_reply( irc, 422, ":We don't need MOTDs." ); 884 } 885 else 886 { 887 char linebuf[80]; /* Max. line length for MOTD's is 79 chars. It's what most IRC networks seem to do. */ 888 char *add, max; 889 int len; 890 891 linebuf[79] = len = 0; 892 max = sizeof( linebuf ) - 1; 893 894 irc_reply( irc, 375, ":- %s Message Of The Day - ", irc->myhost ); 895 while( read( fd, linebuf + len, 1 ) == 1 ) 896 { 897 if( linebuf[len] == '\n' || len == max ) 898 { 899 linebuf[len] = 0; 900 irc_reply( irc, 372, ":- %s", linebuf ); 901 len = 0; 902 } 903 else if( linebuf[len] == '%' ) 904 { 905 read( fd, linebuf + len, 1 ); 906 if( linebuf[len] == 'h' ) 907 add = irc->myhost; 908 else if( linebuf[len] == 'v' ) 909 add = BITLBEE_VERSION; 910 else if( linebuf[len] == 'n' ) 911 add = irc->nick; 912 else 913 add = "%"; 914 915 strncpy( linebuf + len, add, max - len ); 916 while( linebuf[++len] ); 917 } 918 else if( len < max ) 919 { 920 len ++; 921 } 922 } 923 irc_reply( irc, 376, ":End of MOTD" ); 924 close( fd ); 925 } 926 } 927 928 void irc_topic( irc_t *irc, char *channel ) 929 { 930 struct groupchat *c = irc_chat_by_channel( irc, channel ); 931 932 if( c && c->topic ) 933 irc_reply( irc, 332, "%s :%s", channel, c->topic ); 934 else if( g_strcasecmp( channel, irc->channel ) == 0 ) 935 irc_reply( irc, 332, "%s :%s", channel, CONTROL_TOPIC ); 936 else 937 irc_reply( irc, 331, "%s :No topic for this channel", channel ); 938 } 939 940 void irc_umode_set( irc_t *irc, char *s, int allow_priv ) 687 941 { 688 942 /* allow_priv: Set to 0 if s contains user input, 1 if you want 689 943 to set a "privileged" mode (+o, +R, etc). */ 690 char m[128], st = 1; 691 const char *t; 944 char m[256], st = 1, *t; 692 945 int i; 693 946 char changes[512], *p, st2 = 2; … … 697 950 698 951 for( t = irc->umode; *t; t ++ ) 699 if( *t < sizeof( m ) ) 700 m[(int)*t] = 1; 701 952 m[(int)*t] = 1; 953 702 954 p = changes; 703 955 for( t = s; *t; t ++ ) … … 705 957 if( *t == '+' || *t == '-' ) 706 958 st = *t == '+'; 707 else if( ( st == 0 && ( !strchr( UMODES_KEEP, *t ) || allow_priv ) ) || 708 ( st == 1 && strchr( UMODES, *t ) ) || 709 ( st == 1 && allow_priv && strchr( UMODES_PRIV, *t ) ) ) 959 else if( st == 0 || ( strchr( UMODES, *t ) || ( allow_priv && strchr( UMODES_PRIV, *t ) ) ) ) 710 960 { 711 961 if( m[(int)*t] != st) … … 724 974 memset( irc->umode, 0, sizeof( irc->umode ) ); 725 975 726 for( i = 'A'; i <= 'z'&& strlen( irc->umode ) < ( sizeof( irc->umode ) - 1 ); i ++ )976 for( i = 0; i < 256 && strlen( irc->umode ) < ( sizeof( irc->umode ) - 1 ); i ++ ) 727 977 if( m[i] ) 728 978 irc->umode[strlen(irc->umode)] = i; 729 979 730 980 if( badflag ) 731 irc_send_num( irc, 501, ":Unknown MODE flag" ); 981 irc_reply( irc, 501, ":Unknown MODE flag" ); 982 /* Deliberately no !user@host on the prefix here */ 732 983 if( *changes ) 733 irc_write( irc, ":%s!%s@%s MODE %s :%s", irc->user->nick, 734 irc->user->user, irc->user->host, irc->user->nick, 735 changes ); 984 irc_write( irc, ":%s MODE %s %s", irc->nick, irc->nick, changes ); 985 } 986 987 void irc_spawn( irc_t *irc, user_t *u ) 988 { 989 irc_join( irc, u, irc->channel ); 990 } 991 992 void irc_join( irc_t *irc, user_t *u, char *channel ) 993 { 994 char *nick; 995 996 if( ( g_strcasecmp( channel, irc->channel ) != 0 ) || user_find( irc, irc->nick ) ) 997 irc_write( irc, ":%s!%s@%s JOIN :%s", u->nick, u->user, u->host, channel ); 998 999 if( nick_cmp( u->nick, irc->nick ) == 0 ) 1000 { 1001 irc_write( irc, ":%s MODE %s +%s", irc->myhost, channel, CMODE ); 1002 irc_names( irc, channel ); 1003 irc_topic( irc, channel ); 1004 } 1005 1006 nick = g_strdup( u->nick ); 1007 nick_lc( nick ); 1008 if( g_hash_table_lookup( irc->watches, nick ) ) 1009 { 1010 irc_reply( irc, 600, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "logged online" ); 1011 } 1012 g_free( nick ); 1013 } 1014 1015 void irc_part( irc_t *irc, user_t *u, char *channel ) 1016 { 1017 irc_write( irc, ":%s!%s@%s PART %s :%s", u->nick, u->user, u->host, channel, "" ); 1018 } 1019 1020 void irc_kick( irc_t *irc, user_t *u, char *channel, user_t *kicker ) 1021 { 1022 irc_write( irc, ":%s!%s@%s KICK %s %s :%s", kicker->nick, kicker->user, kicker->host, channel, u->nick, "" ); 1023 } 1024 1025 void irc_kill( irc_t *irc, user_t *u ) 1026 { 1027 char *nick, *s; 1028 char reason[128]; 1029 1030 if( u->ic && u->ic->flags & OPT_LOGGING_OUT && set_getbool( &irc->set, "simulate_netsplit" ) ) 1031 { 1032 if( u->ic->acc->server ) 1033 g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost, 1034 u->ic->acc->server ); 1035 else if( ( s = strchr( u->ic->acc->user, '@' ) ) ) 1036 g_snprintf( reason, sizeof( reason ), "%s %s", irc->myhost, 1037 s + 1 ); 1038 else 1039 g_snprintf( reason, sizeof( reason ), "%s %s.%s", irc->myhost, 1040 u->ic->acc->prpl->name, irc->myhost ); 1041 1042 /* proto_opt might contain garbage after the : */ 1043 if( ( s = strchr( reason, ':' ) ) ) 1044 *s = 0; 1045 } 1046 else 1047 { 1048 strcpy( reason, "Leaving..." ); 1049 } 1050 1051 irc_write( irc, ":%s!%s@%s QUIT :%s", u->nick, u->user, u->host, reason ); 1052 1053 nick = g_strdup( u->nick ); 1054 nick_lc( nick ); 1055 if( g_hash_table_lookup( irc->watches, nick ) ) 1056 { 1057 irc_reply( irc, 601, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "logged offline" ); 1058 } 1059 g_free( nick ); 1060 } 1061 1062 int irc_send( irc_t *irc, char *nick, char *s, int flags ) 1063 { 1064 struct groupchat *c = NULL; 1065 user_t *u = NULL; 1066 1067 if( strchr( CTYPES, *nick ) ) 1068 { 1069 if( !( c = irc_chat_by_channel( irc, nick ) ) ) 1070 { 1071 irc_reply( irc, 403, "%s :Channel does not exist", nick ); 1072 return( 0 ); 1073 } 1074 } 1075 else 1076 { 1077 u = user_find( irc, nick ); 1078 1079 if( !u ) 1080 { 1081 if( irc->is_private ) 1082 irc_reply( irc, 401, "%s :Nick does not exist", nick ); 1083 else 1084 irc_usermsg( irc, "Nick `%s' does not exist!", nick ); 1085 return( 0 ); 1086 } 1087 } 1088 1089 if( *s == 1 && s[strlen(s)-1] == 1 ) 1090 { 1091 if( g_strncasecmp( s + 1, "ACTION", 6 ) == 0 ) 1092 { 1093 if( s[7] == ' ' ) s ++; 1094 s += 3; 1095 *(s++) = '/'; 1096 *(s++) = 'm'; 1097 *(s++) = 'e'; 1098 *(s++) = ' '; 1099 s -= 4; 1100 s[strlen(s)-1] = 0; 1101 } 1102 else if( g_strncasecmp( s + 1, "VERSION", 7 ) == 0 ) 1103 { 1104 u = user_find( irc, irc->mynick ); 1105 irc_privmsg( irc, u, "NOTICE", irc->nick, "", "\001VERSION BitlBee " BITLBEE_VERSION " " ARCH "/" CPU "\001" ); 1106 return( 1 ); 1107 } 1108 else if( g_strncasecmp( s + 1, "PING", 4 ) == 0 ) 1109 { 1110 u = user_find( irc, irc->mynick ); 1111 irc_privmsg( irc, u, "NOTICE", irc->nick, "", s ); 1112 return( 1 ); 1113 } 1114 else if( g_strncasecmp( s + 1, "TYPING", 6 ) == 0 ) 1115 { 1116 if( u && u->ic && u->ic->acc->prpl->send_typing && strlen( s ) >= 10 ) 1117 { 1118 time_t current_typing_notice = time( NULL ); 1119 1120 if( current_typing_notice - u->last_typing_notice >= 5 ) 1121 { 1122 u->ic->acc->prpl->send_typing( u->ic, u->handle, ( s[8] - '0' ) << 8 ); 1123 u->last_typing_notice = current_typing_notice; 1124 } 1125 } 1126 return( 1 ); 1127 } 1128 else 1129 { 1130 irc_usermsg( irc, "Non-ACTION CTCP's aren't supported" ); 1131 return( 0 ); 1132 } 1133 } 1134 1135 if( u ) 1136 { 1137 /* For the next message, we probably do have to send new notices... */ 1138 u->last_typing_notice = 0; 1139 u->is_private = irc->is_private; 1140 1141 if( u->is_private ) 1142 { 1143 if( !u->online ) 1144 irc_reply( irc, 301, "%s :%s", u->nick, "User is offline" ); 1145 else if( u->away ) 1146 irc_reply( irc, 301, "%s :%s", u->nick, u->away ); 1147 } 1148 1149 if( u->send_handler ) 1150 { 1151 u->send_handler( irc, u, s, flags ); 1152 return 1; 1153 } 1154 } 1155 else if( c && c->ic && c->ic->acc && c->ic->acc->prpl ) 1156 { 1157 return( imc_chat_msg( c, s, 0 ) ); 1158 } 1159 1160 return( 0 ); 1161 } 1162 1163 static gboolean buddy_send_handler_delayed( gpointer data, gint fd, b_input_condition cond ) 1164 { 1165 user_t *u = data; 1166 1167 /* Shouldn't happen, but just to be sure. */ 1168 if( u->sendbuf_len < 2 ) 1169 return FALSE; 1170 1171 u->sendbuf[u->sendbuf_len-2] = 0; /* Cut off the last newline */ 1172 imc_buddy_msg( u->ic, u->handle, u->sendbuf, u->sendbuf_flags ); 1173 1174 g_free( u->sendbuf ); 1175 u->sendbuf = NULL; 1176 u->sendbuf_len = 0; 1177 u->sendbuf_timer = 0; 1178 u->sendbuf_flags = 0; 1179 1180 return FALSE; 1181 } 1182 1183 void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ) 1184 { 1185 if( !u || !u->ic ) return; 1186 1187 if( set_getbool( &irc->set, "buddy_sendbuffer" ) && set_getint( &irc->set, "buddy_sendbuffer_delay" ) > 0 ) 1188 { 1189 int delay; 1190 1191 if( u->sendbuf_len > 0 && u->sendbuf_flags != flags) 1192 { 1193 /* Flush the buffer */ 1194 b_event_remove( u->sendbuf_timer ); 1195 buddy_send_handler_delayed( u, -1, 0 ); 1196 } 1197 1198 if( u->sendbuf_len == 0 ) 1199 { 1200 u->sendbuf_len = strlen( msg ) + 2; 1201 u->sendbuf = g_new( char, u->sendbuf_len ); 1202 u->sendbuf[0] = 0; 1203 u->sendbuf_flags = flags; 1204 } 1205 else 1206 { 1207 u->sendbuf_len += strlen( msg ) + 1; 1208 u->sendbuf = g_renew( char, u->sendbuf, u->sendbuf_len ); 1209 } 1210 1211 strcat( u->sendbuf, msg ); 1212 strcat( u->sendbuf, "\n" ); 1213 1214 delay = set_getint( &irc->set, "buddy_sendbuffer_delay" ); 1215 if( delay <= 5 ) 1216 delay *= 1000; 1217 1218 if( u->sendbuf_timer > 0 ) 1219 b_event_remove( u->sendbuf_timer ); 1220 u->sendbuf_timer = b_timeout_add( delay, buddy_send_handler_delayed, u ); 1221 } 1222 else 1223 { 1224 imc_buddy_msg( u->ic, u->handle, msg, flags ); 1225 } 1226 } 1227 1228 int irc_privmsg( irc_t *irc, user_t *u, char *type, char *to, char *prefix, char *msg ) 1229 { 1230 char last = 0; 1231 char *s = msg, *line = msg; 1232 1233 /* The almighty linesplitter .. woohoo!! */ 1234 while( !last ) 1235 { 1236 if( *s == '\r' && *(s+1) == '\n' ) 1237 *(s++) = 0; 1238 if( *s == '\n' ) 1239 { 1240 last = s[1] == 0; 1241 *s = 0; 1242 } 1243 else 1244 { 1245 last = s[0] == 0; 1246 } 1247 if( *s == 0 ) 1248 { 1249 if( g_strncasecmp( line, "/me ", 4 ) == 0 && ( !prefix || !*prefix ) && g_strcasecmp( type, "PRIVMSG" ) == 0 ) 1250 { 1251 irc_write( irc, ":%s!%s@%s %s %s :\001ACTION %s\001", u->nick, u->user, u->host, 1252 type, to, line + 4 ); 1253 } 1254 else 1255 { 1256 irc_write( irc, ":%s!%s@%s %s %s :%s%s", u->nick, u->user, u->host, 1257 type, to, prefix ? prefix : "", line ); 1258 } 1259 line = s + 1; 1260 } 1261 s ++; 1262 } 1263 1264 return( 1 ); 1265 } 1266 1267 int irc_msgfrom( irc_t *irc, char *nick, char *msg ) 1268 { 1269 user_t *u = user_find( irc, nick ); 1270 static char *prefix = NULL; 1271 1272 if( !u ) return( 0 ); 1273 if( prefix && *prefix ) g_free( prefix ); 1274 1275 if( !u->is_private && nick_cmp( u->nick, irc->mynick ) != 0 ) 1276 { 1277 int len = strlen( irc->nick) + 3; 1278 prefix = g_new (char, len ); 1279 g_snprintf( prefix, len, "%s%s", irc->nick, set_getstr( &irc->set, "to_char" ) ); 1280 prefix[len-1] = 0; 1281 } 1282 else 1283 { 1284 prefix = ""; 1285 } 1286 1287 return( irc_privmsg( irc, u, "PRIVMSG", u->is_private ? irc->nick : irc->channel, prefix, msg ) ); 1288 } 1289 1290 int irc_noticefrom( irc_t *irc, char *nick, char *msg ) 1291 { 1292 user_t *u = user_find( irc, nick ); 1293 1294 if( u ) 1295 return( irc_privmsg( irc, u, "NOTICE", irc->nick, "", msg ) ); 1296 else 1297 return( 0 ); 736 1298 } 737 1299 … … 772 1334 } 773 1335 774 static char *set_eval_charset( set_t *set, char *value ) 775 { 776 irc_t *irc = (irc_t*) set->data; 777 char *test; 778 gsize test_bytes = 0; 779 GIConv ic, oc; 780 781 if( g_strcasecmp( value, "none" ) == 0 ) 782 value = g_strdup( "utf-8" ); 783 784 if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 ) 785 { 786 return NULL; 787 } 788 789 /* Do a test iconv to see if the user picked an IRC-compatible 790 charset (for example utf-16 goes *horribly* wrong). */ 791 if( ( test = g_convert_with_iconv( " ", 1, oc, NULL, &test_bytes, NULL ) ) == NULL || 792 test_bytes > 1 ) 793 { 794 g_free( test ); 795 g_iconv_close( oc ); 796 irc_usermsg( irc, "Unsupported character set: The IRC protocol " 797 "only supports 8-bit character sets." ); 798 return NULL; 799 } 800 g_free( test ); 801 802 if( ( ic = g_iconv_open( "utf-8", value ) ) == (GIConv) -1 ) 803 { 804 g_iconv_close( oc ); 805 return NULL; 806 } 807 808 if( irc->iconv != (GIConv) -1 ) 809 g_iconv_close( irc->iconv ); 810 if( irc->oconv != (GIConv) -1 ) 811 g_iconv_close( irc->oconv ); 812 813 irc->iconv = ic; 814 irc->oconv = oc; 815 816 return value; 817 } 818 819 char *set_eval_away_devoice( set_t *set, char *value ) 820 { 821 irc_t *irc = set->data; 822 823 if( !is_bool( value ) ) 824 return SET_INVALID; 825 826 /* The usual problem: The setting isn't actually changed at this 827 point and we need it to be, so do it by hand. */ 828 g_free( set->value ); 829 set->value = g_strdup( value ); 830 831 bee_irc_channel_update( irc, NULL, NULL ); 832 833 return value; 834 } 1336 struct groupchat *irc_chat_by_channel( irc_t *irc, char *channel ) 1337 { 1338 struct groupchat *c; 1339 account_t *a; 1340 1341 /* This finds the connection which has a conversation which belongs to this channel */ 1342 for( a = irc->accounts; a; a = a->next ) 1343 { 1344 if( a->ic == NULL ) 1345 continue; 1346 1347 c = a->ic->groupchats; 1348 while( c ) 1349 { 1350 if( c->channel && g_strcasecmp( c->channel, channel ) == 0 ) 1351 return c; 1352 1353 c = c->next; 1354 } 1355 } 1356 1357 return NULL; 1358 } -
irc.h
r8b8def58 r38ff846 5 5 \********************************************************************/ 6 6 7 /* The IRC-based UI (for now the only one)*/7 /* The big hairy IRCd part of the project */ 8 8 9 9 /* … … 33 33 #define IRC_PING_STRING "PinglBee" 34 34 35 #define UMODES "abisw" /* Allowed umodes (although they mostly do nothing) */ 36 #define UMODES_PRIV "Ro" /* Allowed, but not by user directly */ 37 #define UMODES_KEEP "R" /* Don't allow unsetting using /MODE */ 38 #define CMODES "nt" /* Allowed modes */ 39 #define CMODE "t" /* Default mode */ 40 #define UMODE "s" /* Default mode */ 41 42 #define CTYPES "&#" /* Valid channel name prefixes */ 35 #define UMODES "abisw" 36 #define UMODES_PRIV "Ro" 37 #define CMODES "nt" 38 #define CMODE "t" 39 #define UMODE "s" 40 #define CTYPES "&#" 43 41 44 42 typedef enum … … 50 48 USTATUS_SHUTDOWN = 8 51 49 } irc_status_t; 52 53 struct irc_user;54 50 55 51 typedef struct irc … … 63 59 GIConv iconv, oconv; 64 60 65 struct irc_user *root; 66 struct irc_user *user; 67 68 char *last_root_cmd; 61 int sentbytes; 62 time_t oldtime; 69 63 64 char *nick; 65 char *user; 66 char *host; 67 char *realname; 70 68 char *password; /* HACK: Used to save the user's password, but before 71 69 logging in, this may contain a password we should … … 74 72 char umode[8]; 75 73 74 char *myhost; 75 char *mynick; 76 77 char *channel; 78 int c_id; 79 80 char is_private; /* Not too nice... */ 81 char *last_target; 82 76 83 struct query *queries; 77 GSList *file_transfers; 84 struct account *accounts; 85 struct chat *chatrooms; 78 86 79 GSList *users, *channels; 80 struct irc_channel *default_channel; 81 GHashTable *nick_user_hash; 87 struct __USER *users; 88 GHashTable *userhash; 82 89 GHashTable *watches; 90 struct __NICK *nicks; 91 struct set *set; 83 92 84 93 gint r_watch_source_id; 85 94 gint w_watch_source_id; 86 95 gint ping_source_id; 87 88 struct bee *b;89 96 } irc_t; 90 97 91 typedef enum 92 { 93 IRC_USER_PRIVATE = 1, 94 IRC_USER_AWAY = 2, 95 } irc_user_flags_t; 98 #include "user.h" 96 99 97 typedef struct irc_user98 {99 irc_t *irc;100 101 char *nick;102 char *user;103 char *host;104 char *fullname;105 106 /* Nickname in lowercase for case sensitive searches */107 char *key;108 109 irc_user_flags_t flags;110 111 GString *pastebuf; /* Paste buffer (combine lines into a multiline msg). */112 guint pastebuf_timer;113 time_t away_reply_timeout; /* Only send a 301 if this time passed. */114 115 struct bee_user *bu;116 117 const struct irc_user_funcs *f;118 } irc_user_t;119 120 struct irc_user_funcs121 {122 gboolean (*privmsg)( irc_user_t *iu, const char *msg );123 gboolean (*ctcp)( irc_user_t *iu, char * const* ctcp );124 };125 126 extern const struct irc_user_funcs irc_user_root_funcs;127 extern const struct irc_user_funcs irc_user_self_funcs;128 129 typedef enum130 {131 IRC_CHANNEL_JOINED = 1,132 133 /* Hack: Set this flag right before jumping into IM when we expect134 a call to imcb_chat_new(). */135 IRC_CHANNEL_CHAT_PICKME = 0x10000,136 } irc_channel_flags_t;137 138 typedef struct irc_channel139 {140 irc_t *irc;141 char *name;142 char mode[8];143 int flags;144 145 char *topic;146 char *topic_who;147 time_t topic_time;148 149 GSList *users; /* struct irc_channel_user */150 struct set *set;151 152 GString *pastebuf; /* Paste buffer (combine lines into a multiline msg). */153 guint pastebuf_timer;154 155 const struct irc_channel_funcs *f;156 void *data;157 } irc_channel_t;158 159 struct irc_channel_funcs160 {161 gboolean (*privmsg)( irc_channel_t *ic, const char *msg );162 gboolean (*join)( irc_channel_t *ic );163 gboolean (*part)( irc_channel_t *ic, const char *msg );164 gboolean (*topic)( irc_channel_t *ic, const char *new );165 gboolean (*invite)( irc_channel_t *ic, irc_user_t *iu );166 167 gboolean (*_init)( irc_channel_t *ic );168 gboolean (*_free)( irc_channel_t *ic );169 };170 171 typedef enum172 {173 IRC_CHANNEL_USER_OP = 1,174 IRC_CHANNEL_USER_HALFOP = 2,175 IRC_CHANNEL_USER_VOICE = 4,176 } irc_channel_user_flags_t;177 178 typedef struct irc_channel_user179 {180 irc_user_t *iu;181 int flags;182 } irc_channel_user_t;183 184 typedef enum185 {186 IRC_CC_TYPE_DEFAULT,187 IRC_CC_TYPE_REST,188 IRC_CC_TYPE_GROUP,189 IRC_CC_TYPE_ACCOUNT,190 } irc_control_channel_type_t;191 192 struct irc_control_channel193 {194 irc_control_channel_type_t type;195 struct bee_group *group;196 struct account *account;197 };198 199 extern const struct bee_ui_funcs irc_ui_funcs;200 201 /* irc.c */202 100 extern GSList *irc_connection_list; 203 101 … … 205 103 void irc_abort( irc_t *irc, int immed, char *format, ... ) G_GNUC_PRINTF( 3, 4 ); 206 104 void irc_free( irc_t *irc ); 207 void irc_setpass (irc_t *irc, const char *pass);208 105 106 void irc_exec( irc_t *irc, char **cmd ); 209 107 void irc_process( irc_t *irc ); 210 108 char **irc_parse_line( char *line ); 211 109 char *irc_build_line( char **cmd ); 212 110 111 void irc_vawrite( irc_t *irc, char *format, va_list params ); 213 112 void irc_write( irc_t *irc, char *format, ... ) G_GNUC_PRINTF( 2, 3 ); 214 113 void irc_write_all( int now, char *format, ... ) G_GNUC_PRINTF( 2, 3 ); 215 void irc_vawrite( irc_t *irc, char *format, va_list params ); 114 void irc_reply( irc_t *irc, int code, char *format, ... ) G_GNUC_PRINTF( 3, 4 ); 115 G_MODULE_EXPORT int irc_usermsg( irc_t *irc, char *format, ... ) G_GNUC_PRINTF( 2, 3 ); 116 char **irc_tokenize( char *buffer ); 216 117 118 void irc_login( irc_t *irc ); 217 119 int irc_check_login( irc_t *irc ); 120 void irc_motd( irc_t *irc ); 121 void irc_names( irc_t *irc, char *channel ); 122 void irc_topic( irc_t *irc, char *channel ); 123 void irc_umode_set( irc_t *irc, char *s, int allow_priv ); 124 void irc_who( irc_t *irc, char *channel ); 125 void irc_spawn( irc_t *irc, user_t *u ); 126 void irc_join( irc_t *irc, user_t *u, char *channel ); 127 void irc_part( irc_t *irc, user_t *u, char *channel ); 128 void irc_kick( irc_t *irc, user_t *u, char *channel, user_t *kicker ); 129 void irc_kill( irc_t *irc, user_t *u ); 130 void irc_invite( irc_t *irc, char *nick, char *channel ); 131 void irc_whois( irc_t *irc, char *nick ); 132 void irc_setpass( irc_t *irc, const char *pass ); /* USE WITH CAUTION! */ 218 133 219 void irc_umode_set( irc_t *irc, const char *s, gboolean allow_priv ); 134 int irc_send( irc_t *irc, char *nick, char *s, int flags ); 135 int irc_privmsg( irc_t *irc, user_t *u, char *type, char *to, char *prefix, char *msg ); 136 int irc_msgfrom( irc_t *irc, char *nick, char *msg ); 137 int irc_noticefrom( irc_t *irc, char *nick, char *msg ); 220 138 221 /* irc_channel.c */ 222 irc_channel_t *irc_channel_new( irc_t *irc, const char *name ); 223 irc_channel_t *irc_channel_by_name( irc_t *irc, const char *name ); 224 irc_channel_t *irc_channel_get( irc_t *irc, char *id ); 225 int irc_channel_free( irc_channel_t *ic ); 226 int irc_channel_add_user( irc_channel_t *ic, irc_user_t *iu ); 227 int irc_channel_del_user( irc_channel_t *ic, irc_user_t *iu, gboolean silent, const char *msg ); 228 irc_channel_user_t *irc_channel_has_user( irc_channel_t *ic, irc_user_t *iu ); 229 int irc_channel_set_topic( irc_channel_t *ic, const char *topic, const irc_user_t *who ); 230 void irc_channel_user_set_mode( irc_channel_t *ic, irc_user_t *iu, irc_channel_user_flags_t flags ); 231 void irc_channel_printf( irc_channel_t *ic, char *format, ... ); 232 gboolean irc_channel_name_ok( const char *name ); 233 int irc_channel_name_cmp( const char *a_, const char *b_ ); 234 void irc_channel_update_ops( irc_channel_t *ic, char *value ); 235 char *set_eval_irc_channel_ops( struct set *set, char *value ); 236 237 /* irc_commands.c */ 238 void irc_exec( irc_t *irc, char **cmd ); 239 240 /* irc_send.c */ 241 void irc_send_num( irc_t *irc, int code, char *format, ... ) G_GNUC_PRINTF( 3, 4 ); 242 void irc_send_login( irc_t *irc ); 243 void irc_send_motd( irc_t *irc ); 244 void irc_usermsg( irc_t *irc, char *format, ... ); 245 void irc_send_join( irc_channel_t *ic, irc_user_t *iu ); 246 void irc_send_part( irc_channel_t *ic, irc_user_t *iu, const char *reason ); 247 void irc_send_quit( irc_user_t *iu, const char *reason ); 248 void irc_send_names( irc_channel_t *ic ); 249 void irc_send_topic( irc_channel_t *ic, gboolean topic_change ); 250 void irc_send_whois( irc_user_t *iu ); 251 void irc_send_who( irc_t *irc, GSList *l, const char *channel ); 252 void irc_send_msg( irc_user_t *iu, const char *type, const char *dst, const char *msg, const char *prefix ); 253 void irc_send_msg_raw( irc_user_t *iu, const char *type, const char *dst, const char *msg ); 254 void irc_send_msg_f( irc_user_t *iu, const char *type, const char *dst, const char *format, ... ) G_GNUC_PRINTF( 4, 5 ); 255 void irc_send_nick( irc_user_t *iu, const char *new ); 256 void irc_send_channel_user_mode_diff( irc_channel_t *ic, irc_user_t *iu, 257 irc_channel_user_flags_t old, irc_channel_user_flags_t new ); 258 259 /* irc_user.c */ 260 irc_user_t *irc_user_new( irc_t *irc, const char *nick ); 261 int irc_user_free( irc_t *irc, irc_user_t *iu ); 262 irc_user_t *irc_user_by_name( irc_t *irc, const char *nick ); 263 int irc_user_set_nick( irc_user_t *iu, const char *new ); 264 gint irc_user_cmp( gconstpointer a_, gconstpointer b_ ); 265 const char *irc_user_get_away( irc_user_t *iu ); 266 267 /* irc_util.c */ 268 char *set_eval_timezone( struct set *set, char *value ); 269 char *irc_format_timestamp( irc_t *irc, time_t msg_ts ); 270 271 /* irc_im.c */ 272 void bee_irc_channel_update( irc_t *irc, irc_channel_t *ic, irc_user_t *iu ); 139 void buddy_send_handler( irc_t *irc, user_t *u, char *msg, int flags ); 140 struct groupchat *irc_chat_by_channel( irc_t *irc, char *channel ); 273 141 274 142 #endif -
irc_commands.c
r8b8def58 r38ff846 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-20 10Wilmer van der Gaast and others *4 * Copyright 2002-2006 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 53 53 else if( global.conf->auth_pass ) 54 54 { 55 irc_ send_num( irc, 464, ":Incorrect password" );55 irc_reply( irc, 464, ":Incorrect password" ); 56 56 } 57 57 else … … 65 65 static void irc_cmd_user( irc_t *irc, char **cmd ) 66 66 { 67 irc->user ->user= g_strdup( cmd[1] );68 irc-> user->fullname = g_strdup( cmd[4] );67 irc->user = g_strdup( cmd[1] ); 68 irc->realname = g_strdup( cmd[4] ); 69 69 70 70 irc_check_login( irc ); … … 73 73 static void irc_cmd_nick( irc_t *irc, char **cmd ) 74 74 { 75 if( irc_user_by_name( irc, cmd[1] ) ) 76 { 77 irc_send_num( irc, 433, ":This nick is already in use" ); 75 if( irc->status & USTATUS_IDENTIFIED && irc->nick ) 76 { 77 irc_reply( irc, 438, "%s %s :You can only change your nick if you're not " 78 "logged in (i.e. pre-identify)", irc->nick, cmd[1] ); 79 } 80 /* This is not clean, but for now it'll have to be like this... */ 81 else if( ( nick_cmp( cmd[1], irc->mynick ) == 0 ) || ( nick_cmp( cmd[1], NS_NICK ) == 0 ) || ( user_find( irc, cmd[1] ) != NULL ) ) 82 { 83 irc_reply( irc, 433, "%s :This nick is already in use", cmd[1] ); 78 84 } 79 85 else if( !nick_ok( cmd[1] ) ) 80 86 { 81 87 /* [SH] Invalid characters. */ 82 irc_send_num( irc, 432, ":This nick contains invalid characters" ); 83 } 84 else if( irc->user->nick ) 85 { 86 if( irc->status & USTATUS_IDENTIFIED ) 87 { 88 irc_setpass( irc, NULL ); 89 irc->status &= ~USTATUS_IDENTIFIED; 90 irc_umode_set( irc, "-R", 1 ); 91 irc_usermsg( irc, "Changing nicks resets your identify status. " 92 "Re-identify or register a new account if you want " 93 "your configuration to be saved. See \x02help " 94 "nick_changes\x02." ); 95 } 96 97 irc_user_set_nick( irc->user, cmd[1] ); 98 } 99 else 100 { 101 irc->user->nick = g_strdup( cmd[1] ); 88 irc_reply( irc, 432, "%s :This nick contains invalid characters", cmd[1] ); 89 } 90 else if(irc->nick) 91 { 92 if( user_find( irc, irc->nick ) ) 93 user_rename(irc, irc->nick, cmd[1]); 94 95 irc_write( irc, ":%s!%s@%s NICK %s", irc->nick, irc->user, irc->host, cmd[1] ); 96 g_free(irc->nick); 97 irc->nick = g_strdup( cmd[1] ); 98 } 99 else 100 { 101 irc->nick = g_strdup( cmd[1] ); 102 102 103 103 irc_check_login( irc ); … … 115 115 static void irc_cmd_ping( irc_t *irc, char **cmd ) 116 116 { 117 irc_write( irc, ":%s PONG %s :%s", irc->root->host, 118 irc->root->host, cmd[1]?cmd[1]:irc->root->host ); 119 } 120 121 static void irc_cmd_pong( irc_t *irc, char **cmd ) 122 { 123 /* We could check the value we get back from the user, but in 124 fact we don't care, we're just happy s/he's still alive. */ 125 irc->last_pong = gettime(); 126 irc->pinging = 0; 127 } 128 129 static void irc_cmd_join( irc_t *irc, char **cmd ) 130 { 131 irc_channel_t *ic; 132 133 if( ( ic = irc_channel_by_name( irc, cmd[1] ) ) == NULL ) 134 ic = irc_channel_new( irc, cmd[1] ); 135 136 if( ic == NULL ) 137 { 138 irc_send_num( irc, 479, "%s :Invalid channel name", cmd[1] ); 139 return; 140 } 141 142 if( ic->flags & IRC_CHANNEL_JOINED ) 143 return; /* Dude, you're already there... 144 RFC doesn't have any reply for that though? */ 145 146 if( ic->f->join && !ic->f->join( ic ) ) 147 /* The story is: FALSE either means the handler showed an error 148 message, or is doing some work before the join should be 149 confirmed. (In the latter case, the caller should take care 150 of that confirmation.) 151 TRUE means all's good, let the user join the channel right away. */ 152 return; 153 154 irc_channel_add_user( ic, irc->user ); 155 } 156 157 static void irc_cmd_names( irc_t *irc, char **cmd ) 158 { 159 irc_channel_t *ic; 160 161 if( cmd[1] && ( ic = irc_channel_by_name( irc, cmd[1] ) ) ) 162 irc_send_names( ic ); 163 /* With no args, we should show /names of all chans. Make the code 164 below work well if necessary. 165 else 166 { 167 GSList *l; 168 169 for( l = irc->channels; l; l = l->next ) 170 irc_send_names( l->data ); 171 } 172 */ 173 } 174 175 static void irc_cmd_part( irc_t *irc, char **cmd ) 176 { 177 irc_channel_t *ic; 178 179 if( ( ic = irc_channel_by_name( irc, cmd[1] ) ) == NULL ) 180 { 181 irc_send_num( irc, 403, "%s :No such channel", cmd[1] ); 182 } 183 else if( irc_channel_del_user( ic, irc->user, FALSE, cmd[2] ) ) 184 { 185 if( ic->f->part ) 186 ic->f->part( ic, NULL ); 187 } 188 else 189 { 190 irc_send_num( irc, 442, "%s :You're not on that channel", cmd[1] ); 191 } 192 } 193 194 static void irc_cmd_whois( irc_t *irc, char **cmd ) 195 { 196 char *nick = cmd[1]; 197 irc_user_t *iu = irc_user_by_name( irc, nick ); 198 199 if( iu ) 200 irc_send_whois( iu ); 201 else 202 irc_send_num( irc, 401, "%s :Nick does not exist", nick ); 203 } 204 205 static void irc_cmd_whowas( irc_t *irc, char **cmd ) 206 { 207 /* For some reason irssi tries a whowas when whois fails. We can 208 ignore this, but then the user never gets a "user not found" 209 message from irssi which is a bit annoying. So just respond 210 with not-found and irssi users will get better error messages */ 211 212 irc_send_num( irc, 406, "%s :Nick does not exist", cmd[1] ); 213 irc_send_num( irc, 369, "%s :End of WHOWAS", cmd[1] ); 214 } 215 216 static void irc_cmd_motd( irc_t *irc, char **cmd ) 217 { 218 irc_send_motd( irc ); 219 } 220 221 static void irc_cmd_mode( irc_t *irc, char **cmd ) 222 { 223 if( irc_channel_name_ok( cmd[1] ) ) 224 { 225 irc_channel_t *ic; 226 227 if( ( ic = irc_channel_by_name( irc, cmd[1] ) ) == NULL ) 228 irc_send_num( irc, 403, "%s :No such channel", cmd[1] ); 229 else if( cmd[2] ) 230 { 231 if( *cmd[2] == '+' || *cmd[2] == '-' ) 232 irc_send_num( irc, 477, "%s :Can't change channel modes", cmd[1] ); 233 else if( *cmd[2] == 'b' ) 234 irc_send_num( irc, 368, "%s :No bans possible", cmd[1] ); 235 } 236 else 237 irc_send_num( irc, 324, "%s +%s", cmd[1], ic->mode ); 238 } 239 else 240 { 241 if( nick_cmp( cmd[1], irc->user->nick ) == 0 ) 242 { 243 if( cmd[2] ) 244 irc_umode_set( irc, cmd[2], 0 ); 245 else 246 irc_send_num( irc, 221, "+%s", irc->umode ); 247 } 248 else 249 irc_send_num( irc, 502, ":Don't touch their modes" ); 250 } 251 } 252 253 static void irc_cmd_who( irc_t *irc, char **cmd ) 254 { 255 char *channel = cmd[1]; 256 irc_channel_t *ic; 257 258 if( !channel || *channel == '0' || *channel == '*' || !*channel ) 259 irc_send_who( irc, irc->users, "**" ); 260 else if( ( ic = irc_channel_by_name( irc, channel ) ) ) 261 irc_send_who( irc, ic->users, channel ); 262 else 263 irc_send_num( irc, 403, "%s :No such channel", channel ); 264 } 265 266 static void irc_cmd_privmsg( irc_t *irc, char **cmd ) 267 { 268 irc_channel_t *ic; 269 irc_user_t *iu; 270 271 if( !cmd[2] ) 272 { 273 irc_send_num( irc, 412, ":No text to send" ); 274 return; 275 } 276 277 /* Don't treat CTCP actions as real CTCPs, just convert them right now. */ 278 if( g_strncasecmp( cmd[2], "\001ACTION", 7 ) == 0 ) 279 { 280 cmd[2] += 4; 281 strcpy( cmd[2], "/me" ); 282 if( cmd[2][strlen(cmd[2])-1] == '\001' ) 283 cmd[2][strlen(cmd[2])-1] = '\0'; 284 } 285 286 if( irc_channel_name_ok( cmd[1] ) && 287 ( ic = irc_channel_by_name( irc, cmd[1] ) ) ) 288 { 289 if( ic->f->privmsg ) 290 ic->f->privmsg( ic, cmd[2] ); 291 } 292 else if( ( iu = irc_user_by_name( irc, cmd[1] ) ) ) 293 { 294 if( cmd[2][0] == '\001' ) 295 { 296 char **ctcp; 297 298 if( iu->f->ctcp == NULL ) 299 return; 300 if( cmd[2][strlen(cmd[2])-1] == '\001' ) 301 cmd[2][strlen(cmd[2])-1] = '\0'; 302 303 ctcp = split_command_parts( cmd[2] + 1 ); 304 iu->f->ctcp( iu, ctcp ); 305 } 306 else if( iu->f->privmsg ) 307 { 308 iu->flags |= IRC_USER_PRIVATE; 309 iu->f->privmsg( iu, cmd[2] ); 310 } 311 } 312 else 313 { 314 irc_send_num( irc, 401, "%s :No such nick/channel", cmd[1] ); 315 } 316 } 317 318 static void irc_cmd_nickserv( irc_t *irc, char **cmd ) 319 { 320 /* [SH] This aliases the NickServ command to PRIVMSG root */ 321 /* [TV] This aliases the NS command to PRIVMSG root as well */ 322 root_command( irc, cmd + 1 ); 323 } 324 325 117 irc_write( irc, ":%s PONG %s :%s", irc->myhost, irc->myhost, cmd[1]?cmd[1]:irc->myhost ); 118 } 326 119 327 120 static void irc_cmd_oper( irc_t *irc, char **cmd ) … … 333 126 { 334 127 irc_umode_set( irc, "+o", 1 ); 335 irc_send_num( irc, 381, ":Password accepted" ); 336 } 337 else 338 { 339 irc_send_num( irc, 432, ":Incorrect password" ); 128 irc_reply( irc, 381, ":Password accepted" ); 129 } 130 else 131 { 132 irc_reply( irc, 432, ":Incorrect password" ); 133 } 134 } 135 136 static void irc_cmd_mode( irc_t *irc, char **cmd ) 137 { 138 if( strchr( CTYPES, *cmd[1] ) ) 139 { 140 if( cmd[2] ) 141 { 142 if( *cmd[2] == '+' || *cmd[2] == '-' ) 143 irc_reply( irc, 477, "%s :Can't change channel modes", cmd[1] ); 144 else if( *cmd[2] == 'b' ) 145 irc_reply( irc, 368, "%s :No bans possible", cmd[1] ); 146 } 147 else 148 irc_reply( irc, 324, "%s +%s", cmd[1], CMODE ); 149 } 150 else 151 { 152 if( nick_cmp( cmd[1], irc->nick ) == 0 ) 153 { 154 if( cmd[2] ) 155 irc_umode_set( irc, cmd[2], 0 ); 156 else 157 irc_reply( irc, 221, "+%s", irc->umode ); 158 } 159 else 160 irc_reply( irc, 502, ":Don't touch their modes" ); 161 } 162 } 163 164 static void irc_cmd_names( irc_t *irc, char **cmd ) 165 { 166 irc_names( irc, cmd[1]?cmd[1]:irc->channel ); 167 } 168 169 static void irc_cmd_part( irc_t *irc, char **cmd ) 170 { 171 struct groupchat *c; 172 173 if( g_strcasecmp( cmd[1], irc->channel ) == 0 ) 174 { 175 user_t *u = user_find( irc, irc->nick ); 176 177 /* Not allowed to leave control channel */ 178 irc_part( irc, u, irc->channel ); 179 irc_join( irc, u, irc->channel ); 180 } 181 else if( ( c = irc_chat_by_channel( irc, cmd[1] ) ) ) 182 { 183 user_t *u = user_find( irc, irc->nick ); 184 185 irc_part( irc, u, c->channel ); 186 187 if( c->ic ) 188 { 189 c->joined = 0; 190 c->ic->acc->prpl->chat_leave( c ); 191 } 192 } 193 else 194 { 195 irc_reply( irc, 403, "%s :No such channel", cmd[1] ); 196 } 197 } 198 199 static void irc_cmd_join( irc_t *irc, char **cmd ) 200 { 201 if( g_strcasecmp( cmd[1], irc->channel ) == 0 ) 202 ; /* Dude, you're already there... 203 RFC doesn't have any reply for that though? */ 204 else if( cmd[1] ) 205 { 206 struct chat *c; 207 208 if( strchr( CTYPES, cmd[1][0] ) == NULL || cmd[1][1] == 0 ) 209 irc_reply( irc, 479, "%s :Invalid channel name", cmd[1] ); 210 else if( ( c = chat_bychannel( irc, cmd[1] ) ) && c->acc && c->acc->ic ) 211 chat_join( irc, c, cmd[2] ); 212 else 213 irc_reply( irc, 403, "%s :No such channel", cmd[1] ); 340 214 } 341 215 } … … 343 217 static void irc_cmd_invite( irc_t *irc, char **cmd ) 344 218 { 345 irc_channel_t *ic; 346 irc_user_t *iu; 347 348 if( ( iu = irc_user_by_name( irc, cmd[1] ) ) == NULL ) 349 { 350 irc_send_num( irc, 401, "%s :No such nick", cmd[1] ); 351 return; 352 } 353 else if( ( ic = irc_channel_by_name( irc, cmd[2] ) ) == NULL ) 354 { 355 irc_send_num( irc, 403, "%s :No such channel", cmd[2] ); 356 return; 357 } 358 359 if( !ic->f->invite ) 360 irc_send_num( irc, 482, "%s :Can't invite people here", cmd[2] ); 361 else if( ic->f->invite( ic, iu ) ) 362 irc_send_num( irc, 341, "%s %s", iu->nick, ic->name ); 219 char *nick = cmd[1], *channel = cmd[2]; 220 struct groupchat *c = irc_chat_by_channel( irc, channel ); 221 user_t *u = user_find( irc, nick ); 222 223 if( u && c && ( u->ic == c->ic ) ) 224 if( c->ic && c->ic->acc->prpl->chat_invite ) 225 { 226 c->ic->acc->prpl->chat_invite( c, u->handle, NULL ); 227 irc_reply( irc, 341, "%s %s", nick, channel ); 228 return; 229 } 230 231 irc_reply( irc, 482, "%s :Invite impossible; User/Channel non-existent or incompatible", channel ); 232 } 233 234 static void irc_cmd_privmsg( irc_t *irc, char **cmd ) 235 { 236 if ( !cmd[2] ) 237 { 238 irc_reply( irc, 412, ":No text to send" ); 239 } 240 else if ( irc->nick && g_strcasecmp( cmd[1], irc->nick ) == 0 ) 241 { 242 irc_write( irc, ":%s!%s@%s %s %s :%s", irc->nick, irc->user, irc->host, cmd[0], cmd[1], cmd[2] ); 243 } 244 else 245 { 246 if( g_strcasecmp( cmd[1], irc->channel ) == 0 ) 247 { 248 unsigned int i; 249 char *t = set_getstr( &irc->set, "default_target" ); 250 251 if( g_strcasecmp( t, "last" ) == 0 && irc->last_target ) 252 cmd[1] = irc->last_target; 253 else if( g_strcasecmp( t, "root" ) == 0 ) 254 cmd[1] = irc->mynick; 255 256 for( i = 0; i < strlen( cmd[2] ); i ++ ) 257 { 258 if( cmd[2][i] == ' ' ) break; 259 if( cmd[2][i] == ':' || cmd[2][i] == ',' ) 260 { 261 cmd[1] = cmd[2]; 262 cmd[2] += i; 263 *cmd[2] = 0; 264 while( *(++cmd[2]) == ' ' ); 265 break; 266 } 267 } 268 269 irc->is_private = 0; 270 271 if( cmd[1] != irc->last_target ) 272 { 273 g_free( irc->last_target ); 274 irc->last_target = g_strdup( cmd[1] ); 275 } 276 } 277 else 278 { 279 irc->is_private = 1; 280 } 281 irc_send( irc, cmd[1], cmd[2], ( g_strcasecmp( cmd[0], "NOTICE" ) == 0 ) ? OPT_AWAY : 0 ); 282 } 283 } 284 285 static void irc_cmd_who( irc_t *irc, char **cmd ) 286 { 287 char *channel = cmd[1]; 288 user_t *u = irc->users; 289 struct groupchat *c; 290 GList *l; 291 292 if( !channel || *channel == '0' || *channel == '*' || !*channel ) 293 while( u ) 294 { 295 irc_reply( irc, 352, "%s %s %s %s %s %c :0 %s", u->online ? irc->channel : "*", u->user, u->host, irc->myhost, u->nick, u->online ? ( u->away ? 'G' : 'H' ) : 'G', u->realname ); 296 u = u->next; 297 } 298 else if( g_strcasecmp( channel, irc->channel ) == 0 ) 299 while( u ) 300 { 301 if( u->online ) 302 irc_reply( irc, 352, "%s %s %s %s %s %c :0 %s", channel, u->user, u->host, irc->myhost, u->nick, u->away ? 'G' : 'H', u->realname ); 303 u = u->next; 304 } 305 else if( ( c = irc_chat_by_channel( irc, channel ) ) ) 306 for( l = c->in_room; l; l = l->next ) 307 { 308 if( ( u = user_findhandle( c->ic, l->data ) ) ) 309 irc_reply( irc, 352, "%s %s %s %s %s %c :0 %s", channel, u->user, u->host, irc->myhost, u->nick, u->away ? 'G' : 'H', u->realname ); 310 } 311 else if( ( u = user_find( irc, channel ) ) ) 312 irc_reply( irc, 352, "%s %s %s %s %s %c :0 %s", channel, u->user, u->host, irc->myhost, u->nick, u->online ? ( u->away ? 'G' : 'H' ) : 'G', u->realname ); 313 314 irc_reply( irc, 315, "%s :End of /WHO list", channel?channel:"**" ); 363 315 } 364 316 365 317 static void irc_cmd_userhost( irc_t *irc, char **cmd ) 366 318 { 319 user_t *u; 367 320 int i; 368 321 … … 374 327 375 328 for( i = 1; cmd[i]; i ++ ) 376 { 377 irc_user_t *iu = irc_user_by_name( irc, cmd[i] ); 378 379 if( iu ) 380 irc_send_num( irc, 302, ":%s=%c%s@%s", iu->nick, 381 irc_user_get_away( iu ) ? '-' : '+', 382 iu->user, iu->host ); 383 } 329 if( ( u = user_find( irc, cmd[i] ) ) ) 330 { 331 if( u->online && u->away ) 332 irc_reply( irc, 302, ":%s=-%s@%s", u->nick, u->user, u->host ); 333 else 334 irc_reply( irc, 302, ":%s=+%s@%s", u->nick, u->user, u->host ); 335 } 384 336 } 385 337 386 338 static void irc_cmd_ison( irc_t *irc, char **cmd ) 387 339 { 340 user_t *u; 388 341 char buff[IRC_MAX_LINE]; 389 342 int lenleft, i; … … 401 354 while( *this ) 402 355 { 403 irc_user_t *iu;404 405 356 if( ( next = strchr( this, ' ' ) ) ) 406 357 *next = 0; 407 358 408 if( ( iu = irc_user_by_name( irc, this ) ) && 409 iu->bu && iu->bu->flags & BEE_USER_ONLINE ) 410 { 411 lenleft -= strlen( iu->nick ) + 1; 359 if( ( u = user_find( irc, this ) ) && u->online ) 360 { 361 lenleft -= strlen( u->nick ) + 1; 412 362 413 363 if( lenleft < 0 ) 414 364 break; 415 365 416 strcat( buff, iu->nick );366 strcat( buff, u->nick ); 417 367 strcat( buff, " " ); 418 368 } … … 437 387 buff[strlen(buff)-1] = '\0'; 438 388 439 irc_ send_num( irc, 303, ":%s", buff );389 irc_reply( irc, 303, ":%s", buff ); 440 390 } 441 391 … … 450 400 { 451 401 char *nick; 452 irc_user_t *iu;402 user_t *u; 453 403 454 404 if( !cmd[i][0] || !cmd[i][1] ) … … 458 408 nick_lc( nick ); 459 409 460 iu = irc_user_by_name( irc, nick );410 u = user_find( irc, nick ); 461 411 462 412 if( cmd[i][0] == '+' ) … … 465 415 g_hash_table_insert( irc->watches, nick, nick ); 466 416 467 if( iu && iu->bu && iu->bu->flags & BEE_USER_ONLINE ) 468 irc_send_num( irc, 604, "%s %s %s %d :%s", iu->nick, iu->user, 469 iu->host, (int) time( NULL ), "is online" ); 417 if( u && u->online ) 418 irc_reply( irc, 604, "%s %s %s %d :%s", u->nick, u->user, u->host, (int) time( NULL ), "is online" ); 470 419 else 471 irc_send_num( irc, 605, "%s %s %s %d :%s", nick, "*", "*", 472 (int) time( NULL ), "is offline" ); 420 irc_reply( irc, 605, "%s %s %s %d :%s", nick, "*", "*", (int) time( NULL ), "is offline" ); 473 421 } 474 422 else if( cmd[i][0] == '-' ) … … 481 429 g_free( okey ); 482 430 483 irc_ send_num( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" );431 irc_reply( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" ); 484 432 } 485 433 } … … 489 437 static void irc_cmd_topic( irc_t *irc, char **cmd ) 490 438 { 491 irc_channel_t *ic = irc_channel_by_name( irc, cmd[1] ); 492 const char *new = cmd[2]; 493 494 if( ic == NULL ) 495 { 496 irc_send_num( irc, 403, "%s :No such channel", cmd[1] ); 497 } 498 else if( new ) 499 { 500 if( ic->f->topic == NULL ) 501 irc_send_num( irc, 482, "%s :Can't change this channel's topic", ic->name ); 502 else if( ic->f->topic( ic, new ) ) 503 irc_send_topic( ic, TRUE ); 504 } 505 else 506 { 507 irc_send_topic( ic, FALSE ); 439 char *channel = cmd[1]; 440 char *topic = cmd[2]; 441 442 if( topic ) 443 { 444 /* Send the topic */ 445 struct groupchat *c = irc_chat_by_channel( irc, channel ); 446 if( c && c->ic && c->ic->acc->prpl->chat_topic ) 447 c->ic->acc->prpl->chat_topic( c, topic ); 448 } 449 else 450 { 451 /* Get the topic */ 452 irc_topic( irc, channel ); 508 453 } 509 454 } … … 511 456 static void irc_cmd_away( irc_t *irc, char **cmd ) 512 457 { 513 if( cmd[1] && *cmd[1] ) 514 { 515 char away[strlen(cmd[1])+1]; 458 user_t *u = user_find( irc, irc->nick ); 459 char *away = cmd[1]; 460 461 if( !u ) return; 462 463 if( away && *away ) 464 { 516 465 int i, j; 517 466 518 467 /* Copy away string, but skip control chars. Mainly because 519 468 Jabber really doesn't like them. */ 520 for( i = j = 0; cmd[1][i]; i ++ ) 521 if( ( away[j] = cmd[1][i] ) >= ' ' ) 469 u->away = g_malloc( strlen( away ) + 1 ); 470 for( i = j = 0; away[i]; i ++ ) 471 if( ( u->away[j] = away[i] ) >= ' ' ) 522 472 j ++; 523 away[j] = '\0'; 524 525 irc_send_num( irc, 306, ":You're now away: %s", away ); 526 set_setstr( &irc->b->set, "away", away ); 527 } 528 else 529 { 530 irc_send_num( irc, 305, ":Welcome back" ); 531 set_setstr( &irc->b->set, "away", NULL ); 532 } 473 u->away[j] = 0; 474 475 irc_reply( irc, 306, ":You're now away: %s", u->away ); 476 /* irc_umode_set( irc, irc->myhost, "+a" ); */ 477 } 478 else 479 { 480 if( u->away ) g_free( u->away ); 481 u->away = NULL; 482 /* irc_umode_set( irc, irc->myhost, "-a" ); */ 483 irc_reply( irc, 305, ":Welcome back" ); 484 } 485 486 set_setstr( &irc->set, "away", u->away ); 487 } 488 489 static void irc_cmd_whois( irc_t *irc, char **cmd ) 490 { 491 char *nick = cmd[1]; 492 user_t *u = user_find( irc, nick ); 493 494 if( u ) 495 { 496 irc_reply( irc, 311, "%s %s %s * :%s", u->nick, u->user, u->host, u->realname ); 497 498 if( u->ic ) 499 irc_reply( irc, 312, "%s %s.%s :%s network", u->nick, u->ic->acc->user, 500 u->ic->acc->server && *u->ic->acc->server ? u->ic->acc->server : "", 501 u->ic->acc->prpl->name ); 502 else 503 irc_reply( irc, 312, "%s %s :%s", u->nick, irc->myhost, IRCD_INFO ); 504 505 if( !u->online ) 506 irc_reply( irc, 301, "%s :%s", u->nick, "User is offline" ); 507 else if( u->away ) 508 irc_reply( irc, 301, "%s :%s", u->nick, u->away ); 509 if( u->status_msg ) 510 irc_reply( irc, 320, "%s :%s", u->nick, u->status_msg ); 511 512 irc_reply( irc, 318, "%s :End of /WHOIS list", nick ); 513 } 514 else 515 { 516 irc_reply( irc, 401, "%s :Nick does not exist", nick ); 517 } 518 } 519 520 static void irc_cmd_whowas( irc_t *irc, char **cmd ) 521 { 522 /* For some reason irssi tries a whowas when whois fails. We can 523 ignore this, but then the user never gets a "user not found" 524 message from irssi which is a bit annoying. So just respond 525 with not-found and irssi users will get better error messages */ 526 527 irc_reply( irc, 406, "%s :Nick does not exist", cmd[1] ); 528 irc_reply( irc, 369, "%s :End of WHOWAS", cmd[1] ); 529 } 530 531 static void irc_cmd_nickserv( irc_t *irc, char **cmd ) 532 { 533 /* [SH] This aliases the NickServ command to PRIVMSG root */ 534 /* [TV] This aliases the NS command to PRIVMSG root as well */ 535 root_command( irc, cmd + 1 ); 536 } 537 538 static void irc_cmd_motd( irc_t *irc, char **cmd ) 539 { 540 irc_motd( irc ); 541 } 542 543 static void irc_cmd_pong( irc_t *irc, char **cmd ) 544 { 545 /* We could check the value we get back from the user, but in 546 fact we don't care, we're just happy he's still alive. */ 547 irc->last_pong = gettime(); 548 irc->pinging = 0; 533 549 } 534 550 535 551 static void irc_cmd_version( irc_t *irc, char **cmd ) 536 552 { 537 irc_send_num( irc, 351, "bitlbee-%s. %s :%s/%s ", 538 BITLBEE_VERSION, irc->root->host, ARCH, CPU ); 553 irc_reply( irc, 351, "bitlbee-%s. %s :%s/%s ", BITLBEE_VERSION, irc->myhost, ARCH, CPU ); 539 554 } 540 555 541 556 static void irc_cmd_completions( irc_t *irc, char **cmd ) 542 557 { 558 user_t *u = user_find( irc, irc->mynick ); 543 559 help_t *h; 544 560 set_t *s; 545 561 int i; 546 562 547 irc_ send_msg_raw( irc->root, "NOTICE", irc->user->nick, "COMPLETIONSOK" );563 irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", "OK" ); 548 564 549 565 for( i = 0; commands[i].command; i ++ ) 550 irc_ send_msg_f( irc->root, "NOTICE", irc->user->nick, "COMPLETIONS %s", commands[i].command );566 irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", commands[i].command ); 551 567 552 568 for( h = global.help; h; h = h->next ) 553 irc_ send_msg_f( irc->root, "NOTICE", irc->user->nick, "COMPLETIONS help %s", h->title );554 555 for( s = irc-> b->set; s; s = s->next )556 irc_ send_msg_f( irc->root, "NOTICE", irc->user->nick, "COMPLETIONS set %s", s->key );557 558 irc_ send_msg_raw( irc->root, "NOTICE", irc->user->nick, "COMPLETIONSEND" );569 irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS help ", h->title ); 570 571 for( s = irc->set; s; s = s->next ) 572 irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS set ", s->key ); 573 574 irc_privmsg( irc, u, "NOTICE", irc->nick, "COMPLETIONS ", "END" ); 559 575 } 560 576 … … 566 582 ipc_to_master( cmd ); 567 583 568 irc_ send_num( irc, 382, "%s :Rehashing", global.conf_file );584 irc_reply( irc, 382, "%s :Rehashing", global.conf_file ); 569 585 } 570 586 … … 575 591 { "quit", 0, irc_cmd_quit, 0 }, 576 592 { "ping", 0, irc_cmd_ping, 0 }, 577 { "pong", 0, irc_cmd_pong, IRC_CMD_LOGGED_IN }, 593 { "oper", 2, irc_cmd_oper, IRC_CMD_LOGGED_IN }, 594 { "mode", 1, irc_cmd_mode, IRC_CMD_LOGGED_IN }, 595 { "names", 0, irc_cmd_names, IRC_CMD_LOGGED_IN }, 596 { "part", 1, irc_cmd_part, IRC_CMD_LOGGED_IN }, 578 597 { "join", 1, irc_cmd_join, IRC_CMD_LOGGED_IN }, 579 { "names", 1, irc_cmd_names, IRC_CMD_LOGGED_IN }, 580 { "part", 1, irc_cmd_part, IRC_CMD_LOGGED_IN }, 581 { "whois", 1, irc_cmd_whois, IRC_CMD_LOGGED_IN }, 582 { "whowas", 1, irc_cmd_whowas, IRC_CMD_LOGGED_IN }, 583 { "motd", 0, irc_cmd_motd, IRC_CMD_LOGGED_IN }, 584 { "mode", 1, irc_cmd_mode, IRC_CMD_LOGGED_IN }, 598 { "invite", 2, irc_cmd_invite, IRC_CMD_LOGGED_IN }, 599 { "privmsg", 1, irc_cmd_privmsg, IRC_CMD_LOGGED_IN }, 600 { "notice", 1, irc_cmd_privmsg, IRC_CMD_LOGGED_IN }, 585 601 { "who", 0, irc_cmd_who, IRC_CMD_LOGGED_IN }, 586 { "privmsg", 1, irc_cmd_privmsg, IRC_CMD_LOGGED_IN },587 { "nickserv", 1, irc_cmd_nickserv, IRC_CMD_LOGGED_IN },588 { "ns", 1, irc_cmd_nickserv, IRC_CMD_LOGGED_IN },589 { "away", 0, irc_cmd_away, IRC_CMD_LOGGED_IN },590 { "version", 0, irc_cmd_version, IRC_CMD_LOGGED_IN },591 { "completions", 0, irc_cmd_completions, IRC_CMD_LOGGED_IN },592 602 { "userhost", 1, irc_cmd_userhost, IRC_CMD_LOGGED_IN }, 593 603 { "ison", 1, irc_cmd_ison, IRC_CMD_LOGGED_IN }, 594 604 { "watch", 1, irc_cmd_watch, IRC_CMD_LOGGED_IN }, 595 { "invite", 2, irc_cmd_invite, IRC_CMD_LOGGED_IN },596 #if 0597 { "notice", 1, irc_cmd_privmsg, IRC_CMD_LOGGED_IN },598 #endif599 605 { "topic", 1, irc_cmd_topic, IRC_CMD_LOGGED_IN }, 600 { "oper", 2, irc_cmd_oper, IRC_CMD_LOGGED_IN }, 606 { "away", 0, irc_cmd_away, IRC_CMD_LOGGED_IN }, 607 { "whois", 1, irc_cmd_whois, IRC_CMD_LOGGED_IN }, 608 { "whowas", 1, irc_cmd_whowas, IRC_CMD_LOGGED_IN }, 609 { "nickserv", 1, irc_cmd_nickserv, IRC_CMD_LOGGED_IN }, 610 { "ns", 1, irc_cmd_nickserv, IRC_CMD_LOGGED_IN }, 611 { "motd", 0, irc_cmd_motd, IRC_CMD_LOGGED_IN }, 612 { "pong", 0, irc_cmd_pong, IRC_CMD_LOGGED_IN }, 613 { "version", 0, irc_cmd_version, IRC_CMD_LOGGED_IN }, 614 { "completions", 0, irc_cmd_completions, IRC_CMD_LOGGED_IN }, 601 615 { "die", 0, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, 602 616 { "deaf", 0, NULL, IRC_CMD_OPER_ONLY | IRC_CMD_TO_MASTER }, … … 624 638 if( irc_commands[i].flags & IRC_CMD_PRE_LOGIN && irc->status & USTATUS_LOGGED_IN ) 625 639 { 626 irc_ send_num( irc, 462, ":Only allowed before logging in" );640 irc_reply( irc, 462, ":Only allowed before logging in" ); 627 641 } 628 642 else if( irc_commands[i].flags & IRC_CMD_LOGGED_IN && !( irc->status & USTATUS_LOGGED_IN ) ) 629 643 { 630 irc_ send_num( irc, 451, ":Register first" );644 irc_reply( irc, 451, ":Register first" ); 631 645 } 632 646 else if( irc_commands[i].flags & IRC_CMD_OPER_ONLY && !strchr( irc->umode, 'o' ) ) 633 647 { 634 irc_ send_num( irc, 481, ":Permission denied - You're not an IRC operator" );648 irc_reply( irc, 481, ":Permission denied - You're not an IRC operator" ); 635 649 } 636 650 else if( n_arg < irc_commands[i].required_parameters ) 637 651 { 638 irc_ send_num( irc, 461, "%s :Need more parameters", cmd[0] );652 irc_reply( irc, 461, "%s :Need more parameters", cmd[0] ); 639 653 } 640 654 else if( irc_commands[i].flags & IRC_CMD_TO_MASTER ) … … 653 667 654 668 if( irc->status >= USTATUS_LOGGED_IN ) 655 irc_ send_num( irc, 421, "%s :Unknown command", cmd[0] );656 } 669 irc_reply( irc, 421, "%s :Unknown command", cmd[0] ); 670 } -
lib/Makefile
r8b8def58 r38ff846 8 8 9 9 -include ../Makefile.settings 10 ifdef SRCDIR11 SRCDIR := $(SRCDIR)lib/12 endif13 10 14 11 # [SH] Program variables 15 objects = arc.o base64.o $(EVENT_HANDLER) ftutil.ohttp_client.o ini.o md5.o misc.o oauth.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o12 objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o oauth.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o 16 13 17 14 CFLAGS += -Wall … … 40 37 $(objects): ../Makefile.settings Makefile 41 38 42 $(objects): %.o: $(SRCDIR)%.c39 $(objects): %.o: %.c 43 40 @echo '*' Compiling $< 44 41 @$(CC) -c $(CFLAGS) $< -o $@ -
lib/events.h
r8b8def58 r38ff846 48 48 the given callback function. */ 49 49 typedef enum { 50 B_EV_IO_READ = 1 << 0, 51 B_EV_IO_WRITE = 1 << 1, 52 B_EV_FLAG_FORCE_ONCE = 1 << 16, 53 B_EV_FLAG_FORCE_REPEAT = 1 << 17, 50 GAIM_INPUT_READ = 1 << 1, 51 GAIM_INPUT_WRITE = 1 << 2 54 52 } b_input_condition; 55 53 typedef gboolean (*b_event_handler)(gpointer data, gint fd, b_input_condition cond); -
lib/events_glib.c
r8b8def58 r38ff846 49 49 b_event_handler function; 50 50 gpointer data; 51 guint flags;52 51 } GaimIOClosure; 53 52 … … 77 76 78 77 if (condition & GAIM_READ_COND) 79 gaim_cond |= B_EV_IO_READ;78 gaim_cond |= GAIM_INPUT_READ; 80 79 if (condition & GAIM_WRITE_COND) 81 gaim_cond |= B_EV_IO_WRITE;80 gaim_cond |= GAIM_INPUT_WRITE; 82 81 83 82 event_debug( "gaim_io_invoke( %d, %d, 0x%x )\n", g_io_channel_unix_get_fd(source), condition, data ); … … 88 87 event_debug( "Returned FALSE, cancelling.\n" ); 89 88 90 if (closure->flags & B_EV_FLAG_FORCE_ONCE) 91 return FALSE; 92 else if (closure->flags & B_EV_FLAG_FORCE_REPEAT) 93 return TRUE; 94 else 95 return st; 89 return st; 96 90 } 97 91 … … 111 105 closure->function = function; 112 106 closure->data = data; 113 closure->flags = condition;114 107 115 if (condition & B_EV_IO_READ)108 if (condition & GAIM_INPUT_READ) 116 109 cond |= GAIM_READ_COND; 117 if (condition & B_EV_IO_WRITE)110 if (condition & GAIM_INPUT_WRITE) 118 111 cond |= GAIM_WRITE_COND; 119 112 -
lib/events_libevent.c
r8b8def58 r38ff846 60 60 b_event_handler function; 61 61 void *data; 62 guint flags;63 62 }; 64 63 … … 127 126 { 128 127 if( event & EV_READ ) 129 cond |= B_EV_IO_READ;128 cond |= GAIM_INPUT_READ; 130 129 if( event & EV_WRITE ) 131 cond |= B_EV_IO_WRITE;130 cond |= GAIM_INPUT_WRITE; 132 131 } 133 132 … … 151 150 return; 152 151 } 153 else if( !st && !( b_ev->flags & B_EV_FLAG_FORCE_REPEAT ))152 else if( !st ) 154 153 { 155 154 event_debug( "Handler returned FALSE: " ); … … 175 174 event_debug( "b_input_add( %d, %d, 0x%x, 0x%x ) ", fd, condition, function, data ); 176 175 177 if( ( condition & B_EV_IO_READ && ( b_ev = g_hash_table_lookup( read_hash, &fd ) ) ) ||178 ( condition & B_EV_IO_WRITE && ( b_ev = g_hash_table_lookup( write_hash, &fd ) ) ) )176 if( ( condition & GAIM_INPUT_READ && ( b_ev = g_hash_table_lookup( read_hash, &fd ) ) ) || 177 ( condition & GAIM_INPUT_WRITE && ( b_ev = g_hash_table_lookup( write_hash, &fd ) ) ) ) 179 178 { 180 179 /* We'll stick with this libevent entry, but give it a new BitlBee id. */ … … 199 198 200 199 out_cond = EV_PERSIST; 201 if( condition & B_EV_IO_READ )200 if( condition & GAIM_INPUT_READ ) 202 201 out_cond |= EV_READ; 203 if( condition & B_EV_IO_WRITE )202 if( condition & GAIM_INPUT_WRITE ) 204 203 out_cond |= EV_WRITE; 205 204 … … 213 212 } 214 213 215 b_ev->flags = condition;216 214 g_hash_table_insert( id_hash, &b_ev->id, b_ev ); 217 215 return b_ev->id; -
lib/http_client.c
r8b8def58 r38ff846 149 149 if( req->bytes_written < req->request_length ) 150 150 req->inpa = b_input_add( source, 151 req->ssl ? ssl_getdirection( req->ssl ) : B_EV_IO_WRITE,151 req->ssl ? ssl_getdirection( req->ssl ) : GAIM_INPUT_WRITE, 152 152 http_connected, req ); 153 153 else 154 req->inpa = b_input_add( source, B_EV_IO_READ, http_incoming_data, req );154 req->inpa = b_input_add( source, GAIM_INPUT_READ, http_incoming_data, req ); 155 155 156 156 return FALSE; … … 234 234 /* There will be more! */ 235 235 req->inpa = b_input_add( req->fd, 236 req->ssl ? ssl_getdirection( req->ssl ) : B_EV_IO_READ,236 req->ssl ? ssl_getdirection( req->ssl ) : GAIM_INPUT_READ, 237 237 http_incoming_data, req ); 238 238 -
lib/misc.c
r8b8def58 r38ff846 647 647 return ret; 648 648 } 649 650 char **split_command_parts( char *command )651 {652 static char *cmd[IRC_MAX_ARGS+1];653 char *s, q = 0;654 int k;655 656 memset( cmd, 0, sizeof( cmd ) );657 cmd[0] = command;658 k = 1;659 for( s = command; *s && k < IRC_MAX_ARGS; s ++ )660 if( *s == ' ' && !q )661 {662 *s = 0;663 while( *++s == ' ' );664 if( *s == '"' || *s == '\'' )665 {666 q = *s;667 s ++;668 }669 if( *s )670 {671 cmd[k++] = s;672 s --;673 }674 else675 {676 break;677 }678 }679 else if( *s == '\\' && ( ( !q && s[1] ) || ( q && q == s[1] ) ) )680 {681 char *cpy;682 683 for( cpy = s; *cpy; cpy ++ )684 cpy[0] = cpy[1];685 }686 else if( *s == q )687 {688 q = *s = 0;689 }690 691 /* Full zero-padding for easier argc checking. */692 while( k <= IRC_MAX_ARGS )693 cmd[k++] = NULL;694 695 return cmd;696 } -
lib/misc.h
r8b8def58 r38ff846 69 69 G_MODULE_EXPORT int md5_verify_password( char *password, char *hash ); 70 70 71 G_MODULE_EXPORT char **split_command_parts( char *command );72 73 71 #endif -
lib/proxy.c
r8b8def58 r38ff846 91 91 b_event_remove(phb->inpa); 92 92 if( phb->proxy_func ) 93 phb->proxy_func(phb->proxy_data, -1, B_EV_IO_READ);93 phb->proxy_func(phb->proxy_data, -1, GAIM_INPUT_READ); 94 94 else { 95 phb->func(phb->data, -1, B_EV_IO_READ);95 phb->func(phb->data, -1, GAIM_INPUT_READ); 96 96 g_free(phb); 97 97 } … … 102 102 b_event_remove(phb->inpa); 103 103 if( phb->proxy_func ) 104 phb->proxy_func(phb->proxy_data, source, B_EV_IO_READ);104 phb->proxy_func(phb->proxy_data, source, GAIM_INPUT_READ); 105 105 else { 106 phb->func(phb->data, source, B_EV_IO_READ);106 phb->func(phb->data, source, GAIM_INPUT_READ); 107 107 g_free(phb); 108 108 } … … 147 147 return -1; 148 148 } else { 149 phb->inpa = b_input_add(fd, B_EV_IO_WRITE, gaim_io_connected, phb);149 phb->inpa = b_input_add(fd, GAIM_INPUT_WRITE, gaim_io_connected, phb); 150 150 phb->fd = fd; 151 151 … … 179 179 if ((memcmp(HTTP_GOODSTRING, inputline, strlen(HTTP_GOODSTRING)) == 0) || 180 180 (memcmp(HTTP_GOODSTRING2, inputline, strlen(HTTP_GOODSTRING2)) == 0)) { 181 phb->func(phb->data, source, B_EV_IO_READ);181 phb->func(phb->data, source, GAIM_INPUT_READ); 182 182 g_free(phb->host); 183 183 g_free(phb); … … 186 186 187 187 close(source); 188 phb->func(phb->data, -1, B_EV_IO_READ);188 phb->func(phb->data, -1, GAIM_INPUT_READ); 189 189 g_free(phb->host); 190 190 g_free(phb); … … 204 204 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 205 205 close(source); 206 phb->func(phb->data, -1, B_EV_IO_READ);206 phb->func(phb->data, -1, GAIM_INPUT_READ); 207 207 g_free(phb->host); 208 208 g_free(phb); … … 215 215 if (send(source, cmd, strlen(cmd), 0) < 0) { 216 216 close(source); 217 phb->func(phb->data, -1, B_EV_IO_READ);217 phb->func(phb->data, -1, GAIM_INPUT_READ); 218 218 g_free(phb->host); 219 219 g_free(phb); … … 230 230 if (send(source, cmd, strlen(cmd), 0) < 0) { 231 231 close(source); 232 phb->func(phb->data, -1, B_EV_IO_READ);232 phb->func(phb->data, -1, GAIM_INPUT_READ); 233 233 g_free(phb->host); 234 234 g_free(phb); … … 240 240 if (send(source, cmd, strlen(cmd), 0) < 0) { 241 241 close(source); 242 phb->func(phb->data, -1, B_EV_IO_READ);243 g_free(phb->host); 244 g_free(phb); 245 return FALSE; 246 } 247 248 phb->inpa = b_input_add(source, B_EV_IO_READ, http_canread, phb);242 phb->func(phb->data, -1, GAIM_INPUT_READ); 243 g_free(phb->host); 244 g_free(phb); 245 return FALSE; 246 } 247 248 phb->inpa = b_input_add(source, GAIM_INPUT_READ, http_canread, phb); 249 249 250 250 return FALSE; … … 273 273 memset(packet, 0, sizeof(packet)); 274 274 if (read(source, packet, 9) >= 4 && packet[1] == 90) { 275 phb->func(phb->data, source, B_EV_IO_READ);275 phb->func(phb->data, source, GAIM_INPUT_READ); 276 276 g_free(phb->host); 277 277 g_free(phb); … … 280 280 281 281 close(source); 282 phb->func(phb->data, -1, B_EV_IO_READ);282 phb->func(phb->data, -1, GAIM_INPUT_READ); 283 283 g_free(phb->host); 284 284 g_free(phb); … … 299 299 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 300 300 close(source); 301 phb->func(phb->data, -1, B_EV_IO_READ);301 phb->func(phb->data, -1, GAIM_INPUT_READ); 302 302 g_free(phb->host); 303 303 g_free(phb); … … 309 309 if (!(hp = gethostbyname(phb->host))) { 310 310 close(source); 311 phb->func(phb->data, -1, B_EV_IO_READ);311 phb->func(phb->data, -1, GAIM_INPUT_READ); 312 312 g_free(phb->host); 313 313 g_free(phb); … … 326 326 if (write(source, packet, 9) != 9) { 327 327 close(source); 328 phb->func(phb->data, -1, B_EV_IO_READ);329 g_free(phb->host); 330 g_free(phb); 331 return FALSE; 332 } 333 334 phb->inpa = b_input_add(source, B_EV_IO_READ, s4_canread, phb);328 phb->func(phb->data, -1, GAIM_INPUT_READ); 329 g_free(phb->host); 330 g_free(phb); 331 return FALSE; 332 } 333 334 phb->inpa = b_input_add(source, GAIM_INPUT_READ, s4_canread, phb); 335 335 336 336 return FALSE; … … 359 359 if (read(source, buf, 10) < 10) { 360 360 close(source); 361 phb->func(phb->data, -1, B_EV_IO_READ);361 phb->func(phb->data, -1, GAIM_INPUT_READ); 362 362 g_free(phb->host); 363 363 g_free(phb); … … 366 366 if ((buf[0] != 0x05) || (buf[1] != 0x00)) { 367 367 close(source); 368 phb->func(phb->data, -1, B_EV_IO_READ);369 g_free(phb->host); 370 g_free(phb); 371 return FALSE; 372 } 373 374 phb->func(phb->data, source, B_EV_IO_READ);368 phb->func(phb->data, -1, GAIM_INPUT_READ); 369 g_free(phb->host); 370 g_free(phb); 371 return FALSE; 372 } 373 374 phb->func(phb->data, source, GAIM_INPUT_READ); 375 375 g_free(phb->host); 376 376 g_free(phb); … … 396 396 if (write(source, buf, (5 + strlen(phb->host) + 2)) < (5 + strlen(phb->host) + 2)) { 397 397 close(source); 398 phb->func(phb->data, -1, B_EV_IO_READ);398 phb->func(phb->data, -1, GAIM_INPUT_READ); 399 399 g_free(phb->host); 400 400 g_free(phb); … … 402 402 } 403 403 404 phb->inpa = b_input_add(source, B_EV_IO_READ, s5_canread_again, phb);404 phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_canread_again, phb); 405 405 } 406 406 … … 414 414 if (read(source, buf, 2) < 2) { 415 415 close(source); 416 phb->func(phb->data, -1, B_EV_IO_READ);416 phb->func(phb->data, -1, GAIM_INPUT_READ); 417 417 g_free(phb->host); 418 418 g_free(phb); … … 422 422 if ((buf[0] != 0x01) || (buf[1] != 0x00)) { 423 423 close(source); 424 phb->func(phb->data, -1, B_EV_IO_READ);424 phb->func(phb->data, -1, GAIM_INPUT_READ); 425 425 g_free(phb->host); 426 426 g_free(phb); … … 442 442 if (read(source, buf, 2) < 2) { 443 443 close(source); 444 phb->func(phb->data, -1, B_EV_IO_READ);444 phb->func(phb->data, -1, GAIM_INPUT_READ); 445 445 g_free(phb->host); 446 446 g_free(phb); … … 450 450 if ((buf[0] != 0x05) || (buf[1] == 0xff)) { 451 451 close(source); 452 phb->func(phb->data, -1, B_EV_IO_READ);452 phb->func(phb->data, -1, GAIM_INPUT_READ); 453 453 g_free(phb->host); 454 454 g_free(phb); … … 465 465 if (write(source, buf, 3 + i + j) < 3 + i + j) { 466 466 close(source); 467 phb->func(phb->data, -1, B_EV_IO_READ);467 phb->func(phb->data, -1, GAIM_INPUT_READ); 468 468 g_free(phb->host); 469 469 g_free(phb); … … 471 471 } 472 472 473 phb->inpa = b_input_add(source, B_EV_IO_READ, s5_readauth, phb);473 phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_readauth, phb); 474 474 } else { 475 475 s5_sendconnect(phb, source); … … 491 491 if (getsockopt(source, SOL_SOCKET, SO_ERROR, &error, &len) < 0) { 492 492 close(source); 493 phb->func(phb->data, -1, B_EV_IO_READ);493 phb->func(phb->data, -1, GAIM_INPUT_READ); 494 494 g_free(phb->host); 495 495 g_free(phb); … … 513 513 if (write(source, buf, i) < i) { 514 514 close(source); 515 phb->func(phb->data, -1, B_EV_IO_READ);516 g_free(phb->host); 517 g_free(phb); 518 return FALSE; 519 } 520 521 phb->inpa = b_input_add(source, B_EV_IO_READ, s5_canread, phb);515 phb->func(phb->data, -1, GAIM_INPUT_READ); 516 g_free(phb->host); 517 g_free(phb); 518 return FALSE; 519 } 520 521 phb->inpa = b_input_add(source, GAIM_INPUT_READ, s5_canread, phb); 522 522 523 523 return FALSE; -
lib/ssl_bogus.c
r8b8def58 r38ff846 59 59 b_input_condition ssl_getdirection( void *conn ) 60 60 { 61 return B_EV_IO_READ;61 return GAIM_INPUT_READ; 62 62 } 63 63 -
lib/ssl_client.h
r8b8def58 r38ff846 71 71 G_MODULE_EXPORT int ssl_getfd( void *conn ); 72 72 73 /* This function returns B_EV_IO_READ/WRITE. With SSL connections it's73 /* This function returns GAIM_INPUT_READ/WRITE. With SSL connections it's 74 74 possible that something has to be read while actually were trying to 75 75 write something (think about key exchange/refresh/etc). So when an -
lib/ssl_gnutls.c
r8b8def58 r38ff846 106 106 struct scd *conn = data; 107 107 108 return ssl_connected( conn, conn->fd, B_EV_IO_WRITE );108 return ssl_connected( conn, conn->fd, GAIM_INPUT_WRITE ); 109 109 } 110 110 … … 244 244 { 245 245 return( gnutls_record_get_direction( ((struct scd*)conn)->session ) ? 246 B_EV_IO_WRITE : B_EV_IO_READ );247 } 246 GAIM_INPUT_WRITE : GAIM_INPUT_READ ); 247 } -
lib/ssl_nss.c
r8b8def58 r38ff846 193 193 { 194 194 /* Just in case someone calls us, let's return the most likely case: */ 195 return B_EV_IO_READ;195 return GAIM_INPUT_READ; 196 196 } -
lib/ssl_openssl.c
r8b8def58 r38ff846 102 102 struct scd *conn = data; 103 103 104 return ssl_connected( conn, conn->fd, B_EV_IO_WRITE );104 return ssl_connected( conn, conn->fd, GAIM_INPUT_WRITE ); 105 105 } 106 106 … … 270 270 b_input_condition ssl_getdirection( void *conn ) 271 271 { 272 return( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ? B_EV_IO_WRITE : B_EV_IO_READ );273 } 272 return( ((struct scd*)conn)->lasterr == SSL_ERROR_WANT_WRITE ? GAIM_INPUT_WRITE : GAIM_INPUT_READ ); 273 } -
lib/ssl_sspi.c
r8b8def58 r38ff846 275 275 GaimInputCondition ssl_getdirection( void *conn ) 276 276 { 277 return B_EV_IO_WRITE; /* FIXME: or B_EV_IO_READ */278 } 277 return GAIM_INPUT_WRITE; /* FIXME: or GAIM_INPUT_READ */ 278 } -
nick.c
r8b8def58 r38ff846 78 78 79 79 nick_strip( nick ); 80 if( set_getbool( &acc-> bee->set, "lcnicks" ) )80 if( set_getbool( &acc->irc->set, "lcnicks" ) ) 81 81 nick_lc( nick ); 82 82 } … … 92 92 void nick_dedupe( account_t *acc, const char *handle, char nick[MAX_NICK_LENGTH+1] ) 93 93 { 94 irc_t *irc = (irc_t*) acc->bee->ui_data;95 94 int inf_protection = 256; 96 95 97 96 /* Now, find out if the nick is already in use at the moment, and make 98 97 subtle changes to make it unique. */ 99 while( !nick_ok( nick ) || irc_user_by_name(irc, nick ) )98 while( !nick_ok( nick ) || user_find( acc->irc, nick ) ) 100 99 { 101 100 if( strlen( nick ) < ( MAX_NICK_LENGTH - 1 ) ) … … 113 112 int i; 114 113 115 irc_usermsg( irc, "Warning: Almost had an infinite loop in nick_get()! "116 "This used to be a fatal BitlBee bug, but we tried to fix it. "117 "This message should *never* appear anymore. "118 "If it does, please *do* send us a bug report! "119 "Please send all the following lines in your report:" );120 121 irc_usermsg( irc, "Trying to get a sane nick for handle %s", handle );114 irc_usermsg( acc->irc, "Warning: Almost had an infinite loop in nick_get()! " 115 "This used to be a fatal BitlBee bug, but we tried to fix it. " 116 "This message should *never* appear anymore. " 117 "If it does, please *do* send us a bug report! " 118 "Please send all the following lines in your report:" ); 119 120 irc_usermsg( acc->irc, "Trying to get a sane nick for handle %s", handle ); 122 121 for( i = 0; i < MAX_NICK_LENGTH; i ++ ) 123 irc_usermsg( irc, "Char %d: %c/%d", i, nick[i], nick[i] );124 125 irc_usermsg( irc, "FAILED. Returning an insane nick now. Things might break. "126 "Good luck, and please don't forget to paste the lines up here "127 "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" );122 irc_usermsg( acc->irc, "Char %d: %c/%d", i, nick[i], nick[i] ); 123 124 irc_usermsg( acc->irc, "FAILED. Returning an insane nick now. Things might break. " 125 "Good luck, and please don't forget to paste the lines up here " 126 "in #bitlbee on OFTC or in a mail to wilmer@gaast.net" ); 128 127 129 128 g_snprintf( nick, MAX_NICK_LENGTH + 1, "xx%x", rand() ); -
protocols/Makefile
r8b8def58 r38ff846 8 8 9 9 -include ../Makefile.settings 10 ifdef SRCDIR11 SRCDIR := $(SRCDIR)protocols/12 endif13 10 14 11 # [SH] Program variables 15 objects = account.o bee.o bee_chat.o bee_ft.o bee_user.o nogaim.o 16 12 objects = nogaim.o 17 13 18 14 # [SH] The next two lines should contain the directory name (in $(subdirs)) … … 53 49 $(objects): ../Makefile.settings Makefile 54 50 55 $(objects): %.o: $(SRCDIR)%.c51 $(objects): %.o: %.c 56 52 @echo '*' Compiling $< 57 53 @$(CC) -c $(CFLAGS) $< -o $@ -
protocols/jabber/Makefile
r8b8def58 r38ff846 8 8 9 9 -include ../../Makefile.settings 10 ifdef SRCDIR11 SRCDIR := $(SRCDIR)protocols/jabber/12 endif13 10 14 11 # [SH] Program variables 15 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o s 5bytestream.o sasl.o si.o12 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o 16 13 17 14 CFLAGS += -Wall … … 36 33 $(objects): ../../Makefile.settings Makefile 37 34 38 $(objects): %.o: $(SRCDIR)%.c35 $(objects): %.o: %.c 39 36 @echo '*' Compiling $< 40 37 @$(CC) -c $(CFLAGS) $< -o $@ -
protocols/jabber/conference.c
r8b8def58 r38ff846 92 92 { 93 93 char *normalized = jabber_normalize( name ); 94 GSList *l;95 94 struct groupchat *ret; 96 95 struct jabber_chat *jc; 97 96 98 for( l = ic->groupchats; l; l = l->next ) 99 { 100 ret = l->data; 97 for( ret = ic->groupchats; ret; ret = ret->next ) 98 { 101 99 jc = ret->data; 102 100 if( strcmp( normalized, jc->name ) == 0 ) … … 105 103 g_free( normalized ); 106 104 107 return l ? ret : NULL;105 return ret; 108 106 } 109 107 -
protocols/jabber/io.c
r8b8def58 r38ff846 64 64 most cases it probably won't be necessary.) */ 65 65 if( ( ret = jabber_write_queue( ic ) ) && jd->tx_len > 0 ) 66 jd->w_inpa = b_input_add( jd->fd, B_EV_IO_WRITE, jabber_write_callback, ic );66 jd->w_inpa = b_input_add( jd->fd, GAIM_INPUT_WRITE, jabber_write_callback, ic ); 67 67 } 68 68 else … … 504 504 505 505 if( jd->r_inpa <= 0 ) 506 jd->r_inpa = b_input_add( jd->fd, B_EV_IO_READ, jabber_read_callback, ic );506 jd->r_inpa = b_input_add( jd->fd, GAIM_INPUT_READ, jabber_read_callback, ic ); 507 507 508 508 greet = g_strdup_printf( "%s<stream:stream to=\"%s\" xmlns=\"jabber:client\" " -
protocols/jabber/iq.c
r8b8def58 r38ff846 91 91 pack = 0; 92 92 } 93 else if( strcmp( s, XMLNS_DISCO _INFO) == 0 )94 { 95 const char *features[] = { XMLNS_DISCO _INFO,93 else if( strcmp( s, XMLNS_DISCOVER ) == 0 ) 94 { 95 const char *features[] = { XMLNS_DISCOVER, 96 96 XMLNS_VERSION, 97 97 XMLNS_TIME, … … 99 99 XMLNS_MUC, 100 100 XMLNS_PING, 101 XMLNS_SI,102 XMLNS_BYTESTREAMS,103 XMLNS_FILETRANSFER,104 101 NULL }; 105 102 const char **f; … … 121 118 { 122 119 xt_free_node( reply ); 123 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel" , NULL);120 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel" ); 124 121 pack = 0; 125 122 } … … 127 124 else if( strcmp( type, "set" ) == 0 ) 128 125 { 129 if( ( c = xt_find_node( node->children, "si" ) ) && 130 ( s = xt_find_attr( c, "xmlns" ) ) && 131 ( strcmp( s, XMLNS_SI ) == 0 ) ) 132 { 133 return jabber_si_handle_request( ic, node, c ); 134 } 135 else if( !( c = xt_find_node( node->children, "query" ) ) || 136 !( s = xt_find_attr( c, "xmlns" ) ) ) 126 if( !( c = xt_find_node( node->children, "query" ) ) || 127 !( s = xt_find_attr( c, "xmlns" ) ) ) 137 128 { 138 129 return XT_HANDLED; 139 130 } 140 else if( strcmp( s, XMLNS_ROSTER ) == 0 ) 141 { 131 142 132 /* This is a roster push. XMPP servers send this when someone 143 133 was added to (or removed from) the buddy list. AFAIK they're 144 134 sent even if we added this buddy in our own session. */ 135 if( strcmp( s, XMLNS_ROSTER ) == 0 ) 136 { 145 137 int bare_len = strlen( ic->acc->user ); 146 138 … … 159 151 160 152 xt_free_node( reply ); 161 reply = jabber_make_error_packet( node, "not-allowed", "cancel" , NULL);153 reply = jabber_make_error_packet( node, "not-allowed", "cancel" ); 162 154 pack = 0; 163 155 } 164 156 } 165 else if( strcmp( s, XMLNS_BYTESTREAMS ) == 0 )166 {167 /* Bytestream Request (stage 2 of file transfer) */168 return jabber_bs_recv_request( ic, node, c );169 }170 157 else 171 158 { 172 159 xt_free_node( reply ); 173 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel" , NULL);160 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel" ); 174 161 pack = 0; 175 162 } … … 382 369 while( ( c = xt_find_node( c, "item" ) ) ) 383 370 { 384 struct xt_node *group = xt_find_node( c->children, "group" );371 struct xt_node *group = xt_find_node( node->children, "group" ); 385 372 char *jid = xt_find_attr( c, "jid" ); 386 373 char *name = xt_find_attr( c, "name" ); … … 391 378 if( ( strcmp( sub, "both" ) == 0 || strcmp( sub, "to" ) == 0 ) ) 392 379 { 393 imcb_add_buddy( ic, jid, ( group && group->text_len ) ? 394 group->text : NULL ); 380 if( initial || imcb_find_buddy( ic, jid ) == NULL ) 381 imcb_add_buddy( ic, jid, ( group && group->text_len ) ? 382 group->text : NULL ); 395 383 396 384 if( name ) … … 555 543 static xt_status jabber_add_to_roster_callback( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ); 556 544 557 int jabber_add_to_roster( struct im_connection *ic, c onst char *handle, const char *name, const char *group)545 int jabber_add_to_roster( struct im_connection *ic, char *handle, char *name ) 558 546 { 559 547 struct xt_node *node; … … 565 553 if( name ) 566 554 xt_add_attr( node, "name", name ); 567 if( group )568 xt_add_child( node, xt_new_node( "group", group, NULL ) );569 555 570 556 /* And pack it into a roster-add packet */ … … 590 576 strcmp( s, "result" ) == 0 ) 591 577 { 592 if( bee_user_by_handle( ic->bee,ic, jid ) == NULL )578 if( imcb_find_buddy( ic, jid ) == NULL ) 593 579 imcb_add_buddy( ic, jid, NULL ); 594 580 } … … 622 608 return st; 623 609 } 624 625 xt_status jabber_iq_parse_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );626 627 xt_status jabber_iq_query_features( struct im_connection *ic, char *bare_jid )628 {629 struct xt_node *node, *query;630 struct jabber_buddy *bud;631 632 if( ( bud = jabber_buddy_by_jid( ic, bare_jid , 0 ) ) == NULL )633 {634 /* Who cares about the unknown... */635 imcb_log( ic, "Couldn't find buddy: %s", bare_jid);636 return XT_HANDLED;637 }638 639 if( bud->features ) /* been here already */640 return XT_HANDLED;641 642 node = xt_new_node( "query", NULL, NULL );643 xt_add_attr( node, "xmlns", XMLNS_DISCO_INFO );644 645 if( !( query = jabber_make_packet( "iq", "get", bare_jid, node ) ) )646 {647 imcb_log( ic, "WARNING: Couldn't generate feature query" );648 xt_free_node( node );649 return XT_HANDLED;650 }651 652 jabber_cache_add( ic, query, jabber_iq_parse_features );653 654 return jabber_write_packet( ic, query ) ? XT_HANDLED : XT_ABORT;655 }656 657 xt_status jabber_iq_parse_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )658 {659 struct xt_node *c;660 struct jabber_buddy *bud;661 char *feature, *xmlns, *from;662 663 if( !( from = xt_find_attr( node, "from" ) ) ||664 !( c = xt_find_node( node->children, "query" ) ) ||665 !( xmlns = xt_find_attr( c, "xmlns" ) ) ||666 !( strcmp( xmlns, XMLNS_DISCO_INFO ) == 0 ) )667 {668 imcb_log( ic, "WARNING: Received incomplete IQ-result packet for discover" );669 return XT_HANDLED;670 }671 if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) == NULL )672 {673 /* Who cares about the unknown... */674 imcb_log( ic, "Couldn't find buddy: %s", from );675 return XT_HANDLED;676 }677 678 c = c->children;679 while( ( c = xt_find_node( c, "feature" ) ) )680 {681 feature = xt_find_attr( c, "var" );682 if( feature )683 bud->features = g_slist_append( bud->features, g_strdup( feature ) );684 c = c->next;685 }686 687 return XT_HANDLED;688 }689 690 xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );691 692 xt_status jabber_iq_query_server( struct im_connection *ic, char *jid, char *xmlns )693 {694 struct xt_node *node, *query;695 struct jabber_data *jd = ic->proto_data;696 697 node = xt_new_node( "query", NULL, NULL );698 xt_add_attr( node, "xmlns", xmlns );699 700 if( !( query = jabber_make_packet( "iq", "get", jid, node ) ) )701 {702 imcb_log( ic, "WARNING: Couldn't generate server query" );703 xt_free_node( node );704 }705 706 jd->have_streamhosts--;707 jabber_cache_add( ic, query, jabber_iq_parse_server_features );708 709 return jabber_write_packet( ic, query ) ? XT_HANDLED : XT_ABORT;710 }711 712 /*713 * Query the server for "items", query each "item" for identities, query each "item" that's a proxy for it's bytestream info714 */715 xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig )716 {717 struct xt_node *c;718 struct jabber_data *jd = ic->proto_data;719 char *xmlns, *from;720 721 if( !( c = xt_find_node( node->children, "query" ) ) ||722 !( from = xt_find_attr( node, "from" ) ) ||723 !( xmlns = xt_find_attr( c, "xmlns" ) ) )724 {725 imcb_log( ic, "WARNING: Received incomplete IQ-result packet for discover" );726 return XT_HANDLED;727 }728 729 jd->have_streamhosts++;730 731 if( strcmp( xmlns, XMLNS_DISCO_ITEMS ) == 0 )732 {733 char *itemjid;734 735 /* answer from server */736 737 c = c->children;738 while( ( c = xt_find_node( c, "item" ) ) )739 {740 itemjid = xt_find_attr( c, "jid" );741 742 if( itemjid )743 jabber_iq_query_server( ic, itemjid, XMLNS_DISCO_INFO );744 745 c = c->next;746 }747 }748 else if( strcmp( xmlns, XMLNS_DISCO_INFO ) == 0 )749 {750 char *category, *type;751 752 /* answer from potential proxy */753 754 c = c->children;755 while( ( c = xt_find_node( c, "identity" ) ) )756 {757 category = xt_find_attr( c, "category" );758 type = xt_find_attr( c, "type" );759 760 if( type && ( strcmp( type, "bytestreams" ) == 0 ) &&761 category && ( strcmp( category, "proxy" ) == 0 ) )762 jabber_iq_query_server( ic, from, XMLNS_BYTESTREAMS );763 764 c = c->next;765 }766 }767 else if( strcmp( xmlns, XMLNS_BYTESTREAMS ) == 0 )768 {769 char *host, *jid, *port_s;770 int port;771 772 /* answer from proxy */773 774 if( ( c = xt_find_node( c->children, "streamhost" ) ) &&775 ( host = xt_find_attr( c, "host" ) ) &&776 ( port_s = xt_find_attr( c, "port" ) ) &&777 ( sscanf( port_s, "%d", &port ) == 1 ) &&778 ( jid = xt_find_attr( c, "jid" ) ) )779 {780 jabber_streamhost_t *sh = g_new0( jabber_streamhost_t, 1 );781 782 sh->jid = g_strdup( jid );783 sh->host = g_strdup( host );784 g_snprintf( sh->port, sizeof( sh->port ), "%u", port );785 786 imcb_log( ic, "Proxy found: jid %s host %s port %u", jid, host, port );787 jd->streamhosts = g_slist_append( jd->streamhosts, sh );788 }789 }790 791 if( jd->have_streamhosts == 0 )792 jd->have_streamhosts++;793 794 return XT_HANDLED;795 } -
protocols/jabber/jabber.c
r8b8def58 r38ff846 65 65 66 66 s = set_add( &acc->set, "priority", "0", set_eval_priority, acc ); 67 68 s = set_add( &acc->set, "proxy", "<local>;<auto>", NULL, acc );69 67 70 68 s = set_add( &acc->set, "resource", "BitlBee", NULL, acc ); … … 268 266 struct jabber_data *jd = ic->proto_data; 269 267 270 while( jd->filetransfers )271 imcb_file_canceled( ic, ( ( struct jabber_transfer *) jd->filetransfers->data )->ft, "Logging out" );272 273 while( jd->streamhosts )274 {275 jabber_streamhost_t *sh = jd->streamhosts->data;276 jd->streamhosts = g_slist_remove( jd->streamhosts, sh );277 g_free( sh->jid );278 g_free( sh->host );279 g_free( sh );280 }281 282 268 if( jd->fd >= 0 ) 283 269 jabber_end_stream( ic ); 284 270 285 271 while( ic->groupchats ) 286 jabber_chat_free( ic->groupchats ->data);272 jabber_chat_free( ic->groupchats ); 287 273 288 274 if( jd->r_inpa >= 0 ) … … 415 401 } 416 402 417 if( jabber_add_to_roster( ic, who, NULL , group) )403 if( jabber_add_to_roster( ic, who, NULL ) ) 418 404 presence_send_request( ic, who, "subscribe" ); 419 405 } … … 563 549 ret->send_typing = jabber_send_typing; 564 550 ret->handle_cmp = g_strcasecmp; 565 ret->transfer_request = jabber_si_transfer_request;566 551 567 552 register_protocol( ret ); -
protocols/jabber/jabber.h
r8b8def58 r38ff846 61 61 } jabber_buddy_flags_t; 62 62 63 /* Stores a streamhost's (a.k.a. proxy) data */64 typedef struct65 {66 char *jid;67 char *host;68 char port[6];69 } jabber_streamhost_t;70 71 63 typedef enum 72 64 { … … 99 91 GHashTable *node_cache; 100 92 GHashTable *buddies; 101 102 GSList *filetransfers;103 GSList *streamhosts;104 int have_streamhosts;105 93 }; 106 94 … … 139 127 struct jabber_away_state *away_state; 140 128 char *away_message; 141 GSList *features;142 129 143 130 time_t last_msg; … … 153 140 char *my_full_jid; /* Separate copy because of case sensitivity. */ 154 141 struct jabber_buddy *me; 155 };156 157 struct jabber_transfer158 {159 /* bitlbee's handle for this transfer */160 file_transfer_t *ft;161 162 /* the stream's private handle */163 gpointer streamhandle;164 165 /* timeout for discover queries */166 gint disco_timeout;167 gint disco_timeout_fired;168 169 struct im_connection *ic;170 171 struct jabber_buddy *bud;172 173 int watch_in;174 int watch_out;175 176 char *ini_jid;177 char *tgt_jid;178 char *iq_id;179 char *sid;180 int accepted;181 182 size_t bytesread, byteswritten;183 int fd;184 struct sockaddr_storage saddr;185 142 }; 186 143 … … 210 167 211 168 /* Some supported extensions/legacy stuff */ 212 #define XMLNS_AUTH "jabber:iq:auth" /* XEP-0078 */ 213 #define XMLNS_VERSION "jabber:iq:version" /* XEP-0092 */ 214 #define XMLNS_TIME "jabber:iq:time" /* XEP-0090 */ 215 #define XMLNS_PING "urn:xmpp:ping" /* XEP-0199 */ 216 #define XMLNS_VCARD "vcard-temp" /* XEP-0054 */ 217 #define XMLNS_DELAY "jabber:x:delay" /* XEP-0091 */ 218 #define XMLNS_XDATA "jabber:x:data" /* XEP-0004 */ 219 #define XMLNS_CHATSTATES "http://jabber.org/protocol/chatstates" /* XEP-0085 */ 220 #define XMLNS_DISCO_INFO "http://jabber.org/protocol/disco#info" /* XEP-0030 */ 221 #define XMLNS_DISCO_ITEMS "http://jabber.org/protocol/disco#items" /* XEP-0030 */ 222 #define XMLNS_MUC "http://jabber.org/protocol/muc" /* XEP-0045 */ 223 #define XMLNS_MUC_USER "http://jabber.org/protocol/muc#user" /* XEP-0045 */ 224 #define XMLNS_CAPS "http://jabber.org/protocol/caps" /* XEP-0115 */ 225 #define XMLNS_FEATURE "http://jabber.org/protocol/feature-neg" /* XEP-0020 */ 226 #define XMLNS_SI "http://jabber.org/protocol/si" /* XEP-0095 */ 227 #define XMLNS_FILETRANSFER "http://jabber.org/protocol/si/profile/file-transfer" /* XEP-0096 */ 228 #define XMLNS_BYTESTREAMS "http://jabber.org/protocol/bytestreams" /* XEP-0065 */ 229 #define XMLNS_IBB "http://jabber.org/protocol/ibb" /* XEP-0047 */ 169 #define XMLNS_AUTH "jabber:iq:auth" /* XEP-0078 */ 170 #define XMLNS_VERSION "jabber:iq:version" /* XEP-0092 */ 171 #define XMLNS_TIME "jabber:iq:time" /* XEP-0090 */ 172 #define XMLNS_PING "urn:xmpp:ping" /* XEP-0199 */ 173 #define XMLNS_VCARD "vcard-temp" /* XEP-0054 */ 174 #define XMLNS_DELAY "jabber:x:delay" /* XEP-0091 */ 175 #define XMLNS_CHATSTATES "http://jabber.org/protocol/chatstates" /* 0085 */ 176 #define XMLNS_DISCOVER "http://jabber.org/protocol/disco#info" /* 0030 */ 177 #define XMLNS_MUC "http://jabber.org/protocol/muc" /* XEP-0045 */ 178 #define XMLNS_MUC_USER "http://jabber.org/protocol/muc#user"/* XEP-0045 */ 179 #define XMLNS_CAPS "http://jabber.org/protocol/caps" /* XEP-0115 */ 230 180 231 181 /* iq.c */ … … 235 185 int jabber_get_roster( struct im_connection *ic ); 236 186 int jabber_get_vcard( struct im_connection *ic, char *bare_jid ); 237 int jabber_add_to_roster( struct im_connection *ic, c onst char *handle, const char *name, const char *group);187 int jabber_add_to_roster( struct im_connection *ic, char *handle, char *name ); 238 188 int jabber_remove_from_roster( struct im_connection *ic, char *handle ); 239 xt_status jabber_iq_query_features( struct im_connection *ic, char *bare_jid );240 xt_status jabber_iq_query_server( struct im_connection *ic, char *jid, char *xmlns );241 242 /* si.c */243 int jabber_si_handle_request( struct im_connection *ic, struct xt_node *node, struct xt_node *sinode );244 void jabber_si_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who );245 void jabber_si_free_transfer( file_transfer_t *ft);246 247 /* s5bytestream.c */248 int jabber_bs_recv_request( struct im_connection *ic, struct xt_node *node, struct xt_node *qnode);249 gboolean jabber_bs_send_start( struct jabber_transfer *tf );250 gboolean jabber_bs_send_write( file_transfer_t *ft, char *buffer, unsigned int len );251 189 252 190 /* message.c */ … … 262 200 char *set_eval_tls( set_t *set, char *value ); 263 201 struct xt_node *jabber_make_packet( char *name, char *type, char *to, struct xt_node *children ); 264 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type , char *err_code);202 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type ); 265 203 void jabber_cache_add( struct im_connection *ic, struct xt_node *node, jabber_cache_event func ); 266 204 struct xt_node *jabber_cache_get( struct im_connection *ic, char *id ); -
protocols/jabber/jabber_util.c
r8b8def58 r38ff846 99 99 } 100 100 101 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type , char *err_code)101 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type ) 102 102 { 103 103 struct xt_node *node, *c; … … 111 111 c = xt_new_node( "error", NULL, c ); 112 112 xt_add_attr( c, "type", err_type ); 113 114 /* Add the error code, if present */115 if (err_code)116 xt_add_attr( c, "code", err_code );117 113 118 114 /* To make the actual error packet, we copy the original packet and … … 279 275 presence_send_request( bla->ic, bla->handle, "subscribed" ); 280 276 281 imcb_ask_add( bla->ic, bla->handle, NULL ); 277 if( imcb_find_buddy( bla->ic, bla->handle ) == NULL ) 278 imcb_ask_add( bla->ic, bla->handle, NULL ); 282 279 283 280 g_free( bla->handle ); … … 461 458 462 459 if( bud == NULL && ( flags & GET_BUDDY_CREAT ) && 463 ( bare_exists || bee_user_by_handle( ic->bee,ic, jid ) ) )460 ( bare_exists || imcb_find_buddy( ic, jid ) ) ) 464 461 { 465 462 *s = '/'; … … 482 479 if( bud == NULL ) 483 480 /* No match. Create it now? */ 484 return ( ( flags & GET_BUDDY_CREAT ) && 485 bee_user_by_handle( ic->bee, ic, jid_ ) ) ? 481 return ( ( flags & GET_BUDDY_CREAT ) && imcb_find_buddy( ic, jid_ ) ) ? 486 482 jabber_buddy_add( ic, jid_ ) : NULL; 487 483 else if( bud->resource && ( flags & GET_BUDDY_EXACT ) ) -
protocols/jabber/presence.c
r8b8def58 r38ff846 205 205 struct jabber_data *jd = ic->proto_data; 206 206 struct xt_node *node, *cap; 207 GSList *l;207 struct groupchat *c; 208 208 int st; 209 209 … … 229 229 /* Have to send this update to all groupchats too, the server won't 230 230 do this automatically. */ 231 for( l = ic->groupchats; l && st; l = l->next ) 232 { 233 struct groupchat *c = l->data; 231 for( c = ic->groupchats; c && st; c = c->next ) 232 { 234 233 struct jabber_chat *jc = c->data; 235 234 -
protocols/msn/Makefile
r8b8def58 r38ff846 8 8 9 9 -include ../../Makefile.settings 10 ifdef SRCDIR11 SRCDIR := $(SRCDIR)protocols/msn/12 endif13 10 14 11 # [SH] Program variables … … 36 33 $(objects): ../../Makefile.settings Makefile 37 34 38 $(objects): %.o: $(SRCDIR)%.c35 $(objects): %.o: %.c 39 36 @echo '*' Compiling $< 40 37 @$(CC) -c $(CFLAGS) $< -o $@ -
protocols/msn/msn.c
r8b8def58 r38ff846 79 79 if( md ) 80 80 { 81 /** Disabling MSN ft support for now.82 while( md->filetransfers ) {83 imcb_file_canceled( md->filetransfers->data, "Closing connection" );84 }85 */86 87 81 if( md->fd >= 0 ) 88 82 closesocket( md->fd ); … … 104 98 g_free( md->grouplist ); 105 99 106 while( md->grpq )107 {108 struct msn_groupadd *ga = md->grpq->data;109 g_free( ga->group );110 g_free( ga->who );111 g_free( ga );112 md->grpq = g_slist_remove( md->grpq, ga );113 }114 115 100 g_free( md ); 116 101 } … … 131 116 struct msn_switchboard *sb; 132 117 133 #ifdef DEBUG134 if( strcmp( who, "raw" ) == 0 )135 {136 msn_write( ic, message, strlen( message ) );137 msn_write( ic, "\r\n", 2 );138 }139 else140 #endif141 118 if( ( sb = msn_sb_by_handle( ic, who ) ) ) 142 119 { … … 199 176 static void msn_add_buddy( struct im_connection *ic, char *who, char *group ) 200 177 { 201 msn_buddy_list_add( ic, "FL", who, who , group);178 msn_buddy_list_add( ic, "FL", who, who ); 202 179 } 203 180 … … 240 217 { 241 218 struct msn_switchboard *sb; 242 struct groupchat *c = imcb_chat_new( ic, who );243 219 244 220 if( ( sb = msn_sb_by_handle( ic, who ) ) ) … … 258 234 msn_sb_write_msg( ic, m ); 259 235 260 return c; 261 } 236 return NULL; 237 } 238 239 return NULL; 262 240 } 263 241 … … 269 247 static void msn_add_permit( struct im_connection *ic, char *who ) 270 248 { 271 msn_buddy_list_add( ic, "AL", who, who , NULL);249 msn_buddy_list_add( ic, "AL", who, who ); 272 250 } 273 251 … … 281 259 struct msn_switchboard *sb; 282 260 283 msn_buddy_list_add( ic, "BL", who, who , NULL);261 msn_buddy_list_add( ic, "BL", who, who ); 284 262 285 263 /* If there's still a conversation with this person, close it. */ … … 350 328 ret->send_typing = msn_send_typing; 351 329 ret->handle_cmp = g_strcasecmp; 352 //ret->transfer_request = msn_ftp_transfer_request;353 330 354 331 register_protocol(ret); -
protocols/msn/msn.h
r8b8def58 r38ff846 70 70 int trId; 71 71 72 GSList *msgq , *grpq;72 GSList *msgq; 73 73 GSList *switchboards; 74 74 int sb_failures; 75 75 time_t first_sb_failure; 76 GSList *filetransfers;77 76 78 77 const struct msn_away_state *away_state; … … 121 120 }; 122 121 123 struct msn_groupadd124 {125 char *who;126 char *group;127 };128 129 122 struct msn_handler_data 130 123 { … … 166 159 int msn_write( struct im_connection *ic, char *s, int len ); 167 160 int msn_logged_in( struct im_connection *ic ); 168 int msn_buddy_list_add( struct im_connection *ic, c onst char *list, const char *who, const char *realname_, const char *group);161 int msn_buddy_list_add( struct im_connection *ic, char *list, char *who, char *realname ); 169 162 int msn_buddy_list_remove( struct im_connection *ic, char *list, char *who ); 170 163 void msn_buddy_ask( struct im_connection *ic, char *handle, char *realname ); … … 196 189 void msn_sb_stop_keepalives( struct msn_switchboard *sb ); 197 190 198 /* invitation.c */199 void msn_ftp_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who );200 201 191 #endif //_MSN_H -
protocols/msn/msn_util.c
r8b8def58 r38ff846 51 51 } 52 52 53 int msn_buddy_list_add( struct im_connection *ic, c onst char *list, const char *who, const char *realname_, const char *group)53 int msn_buddy_list_add( struct im_connection *ic, char *list, char *who, char *realname_ ) 54 54 { 55 55 struct msn_data *md = ic->proto_data; 56 char buf[1024], *realname, groupid[8]; 57 58 *groupid = '\0'; 59 if( group ) 60 { 61 int i; 62 for( i = 0; i < md->groupcount; i ++ ) 63 if( g_strcasecmp( md->grouplist[i], group ) == 0 ) 64 { 65 g_snprintf( groupid, sizeof( groupid ), " %d", i ); 66 break; 67 } 68 69 if( *groupid == '\0' ) 70 { 71 /* Have to create this group, it doesn't exist yet. */ 72 struct msn_groupadd *ga; 73 GSList *l; 74 75 for( l = md->grpq; l; l = l->next ) 76 { 77 ga = l->data; 78 if( g_strcasecmp( ga->group, group ) == 0 ) 79 break; 80 } 81 82 ga = g_new0( struct msn_groupadd, 1 ); 83 ga->who = g_strdup( who ); 84 ga->group = g_strdup( group ); 85 md->grpq = g_slist_prepend( md->grpq, ga ); 86 87 if( l == NULL ) 88 { 89 char *groupname = msn_http_encode( group ); 90 g_snprintf( buf, sizeof( buf ), "ADG %d %s %d\r\n", ++md->trId, groupname, 0 ); 91 g_free( groupname ); 92 return msn_write( ic, buf, strlen( buf ) ); 93 } 94 else 95 { 96 /* This can happen if the user's doing lots of adds to a 97 new group at once; we're still waiting for the server 98 to confirm group creation. */ 99 return 1; 100 } 101 } 102 } 56 char buf[1024], *realname; 103 57 104 58 realname = msn_http_encode( realname_ ); 105 g_snprintf( buf, sizeof( buf ), "ADD %d %s %s %s%s\r\n", ++md->trId, list, who, realname, groupid ); 59 60 g_snprintf( buf, sizeof( buf ), "ADD %d %s %s %s\r\n", ++md->trId, list, who, realname ); 61 if( msn_write( ic, buf, strlen( buf ) ) ) 62 { 63 g_free( realname ); 64 65 return( 1 ); 66 } 67 106 68 g_free( realname ); 107 69 108 return msn_write( ic, buf, strlen( buf ));70 return( 0 ); 109 71 } 110 72 … … 132 94 struct msn_buddy_ask_data *bla = data; 133 95 134 msn_buddy_list_add( bla->ic, "AL", bla->handle, bla->realname, NULL ); 135 136 imcb_ask_add( bla->ic, bla->handle, NULL ); 96 msn_buddy_list_add( bla->ic, "AL", bla->handle, bla->realname ); 97 98 if( imcb_find_buddy( bla->ic, bla->handle ) == NULL ) 99 imcb_ask_add( bla->ic, bla->handle, NULL ); 137 100 138 101 g_free( bla->handle ); … … 145 108 struct msn_buddy_ask_data *bla = data; 146 109 147 msn_buddy_list_add( bla->ic, "BL", bla->handle, bla->realname , NULL);110 msn_buddy_list_add( bla->ic, "BL", bla->handle, bla->realname ); 148 111 149 112 g_free( bla->handle ); -
protocols/msn/ns.c
r8b8def58 r38ff846 76 76 if( msn_write( ic, s, strlen( s ) ) ) 77 77 { 78 ic->inpa = b_input_add( md->fd, B_EV_IO_READ, msn_ns_callback, ic );78 ic->inpa = b_input_add( md->fd, GAIM_INPUT_READ, msn_ns_callback, ic ); 79 79 imcb_log( ic, "Connected to server, waiting for reply" ); 80 80 } … … 533 533 else if( num_parts >= 6 && strcmp( cmd[2], "FL" ) == 0 ) 534 534 { 535 const char *group = NULL;536 int num;537 538 if( cmd[6] != NULL && sscanf( cmd[6], "%d", &num ) == 1 && num < md->groupcount )539 group = md->grouplist[num];540 541 535 http_decode( cmd[5] ); 542 imcb_add_buddy( ic, cmd[4], group);536 imcb_add_buddy( ic, cmd[4], NULL ); 543 537 imcb_rename_buddy( ic, cmd[4], cmd[5] ); 544 538 } … … 610 604 imc_logout( ic, TRUE ); 611 605 return( 0 ); 612 }613 }614 else if( strcmp( cmd[0], "ADG" ) == 0 )615 {616 char *group = g_strdup( cmd[3] );617 int groupnum, i;618 GSList *l, *next;619 620 http_decode( group );621 if( sscanf( cmd[4], "%d", &groupnum ) == 1 )622 {623 if( groupnum >= md->groupcount )624 {625 md->grouplist = g_renew( char *, md->grouplist, groupnum + 1 );626 for( i = md->groupcount; i <= groupnum; i ++ )627 md->grouplist[i] = NULL;628 md->groupcount = groupnum + 1;629 }630 g_free( md->grouplist[groupnum] );631 md->grouplist[groupnum] = group;632 }633 else634 {635 /* Shouldn't happen, but if it does, give up on the group. */636 g_free( group );637 imcb_error( ic, "Syntax error" );638 imc_logout( ic, TRUE );639 return 0;640 }641 642 for( l = md->grpq; l; l = next )643 {644 struct msn_groupadd *ga = l->data;645 next = l->next;646 if( g_strcasecmp( ga->group, group ) == 0 )647 {648 if( !msn_buddy_list_add( ic, "FL", ga->who, ga->who, group ) )649 return 0;650 651 g_free( ga->group );652 g_free( ga->who );653 g_free( ga );654 md->grpq = g_slist_remove( md->grpq, ga );655 }656 606 } 657 607 } -
protocols/msn/sb.c
r8b8def58 r38ff846 29 29 #include "passport.h" 30 30 #include "md5.h" 31 #include "invitation.h"32 31 33 32 static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition cond ); … … 178 177 { 179 178 buf = g_strdup( SB_KEEPALIVE_HEADERS ); 180 i = strlen( buf );181 }182 else if( strncmp( text, MSN_INVITE_HEADERS, sizeof( MSN_INVITE_HEADERS ) - 1 ) == 0 )183 {184 buf = g_strdup( text );185 179 i = strlen( buf ); 186 180 } … … 233 227 { 234 228 struct im_connection *ic = sb->ic; 235 struct groupchat *c = NULL;236 229 char buf[1024]; 237 230 238 231 /* Create the groupchat structure. */ 239 232 g_snprintf( buf, sizeof( buf ), "MSN groupchat session %d", sb->session ); 240 if( sb->who ) 241 c = bee_chat_by_title( ic->bee, ic, sb->who ); 242 if( c && !msn_sb_by_chat( c ) ) 243 sb->chat = c; 244 else 245 sb->chat = imcb_chat_new( ic, buf ); 233 sb->chat = imcb_chat_new( ic, buf ); 246 234 247 235 /* Populate the channel. */ … … 327 315 328 316 if( msn_sb_write( sb, buf, strlen( buf ) ) ) 329 sb->inp = b_input_add( sb->fd, B_EV_IO_READ, msn_sb_callback, sb );317 sb->inp = b_input_add( sb->fd, GAIM_INPUT_READ, msn_sb_callback, sb ); 330 318 else 331 319 debug( "Error %d while connecting to switchboard server", 2 ); … … 704 692 } 705 693 } 706 #if 0707 // Disable MSN ft support for now.708 694 else if( g_strncasecmp( ct, "text/x-msmsgsinvite", 19 ) == 0 ) 709 695 { 710 char *command = msn_findheader( body, "Invitation-Command:", blen ); 711 char *cookie = msn_findheader( body, "Invitation-Cookie:", blen ); 712 unsigned int icookie; 696 char *itype = msn_findheader( body, "Application-GUID:", blen ); 697 char buf[1024]; 713 698 714 699 g_free( ct ); 715 700 716 /* Every invite should have both a Command and Cookie header */ 717 if( !command || !cookie ) { 718 g_free( command ); 719 g_free( cookie ); 720 imcb_log( ic, "Warning: No command or cookie from %s", sb->who ); 721 return 1; 722 } 723 724 icookie = strtoul( cookie, NULL, 10 ); 725 g_free( cookie ); 726 727 if( g_strncasecmp( command, "INVITE", 6 ) == 0 ) { 728 msn_invitation_invite( sb, cmd[1], icookie, body, blen ); 729 } else if( g_strncasecmp( command, "ACCEPT", 6 ) == 0 ) { 730 msn_invitation_accept( sb, cmd[1], icookie, body, blen ); 731 } else if( g_strncasecmp( command, "CANCEL", 6 ) == 0 ) { 732 msn_invitation_cancel( sb, cmd[1], icookie, body, blen ); 733 } else { 734 imcb_log( ic, "Warning: Received invalid invitation with " 735 "command %s from %s", command, sb->who ); 736 } 737 738 g_free( command ); 739 } 740 #endif 741 else if( g_strncasecmp( ct, "application/x-msnmsgrp2p", 24 ) == 0 ) 742 { 743 imcb_error( sb->ic, "Cannot receive file from %s: BitlBee does not " 744 "support msnmsgrp2p yet.", sb->who ); 745 g_free( ct ); 701 *buf = 0; 702 703 if( !itype ) 704 return( 1 ); 705 706 /* File transfer. */ 707 if( strcmp( itype, "{5D3E02AB-6190-11d3-BBBB-00C04F795683}" ) == 0 ) 708 { 709 char *name = msn_findheader( body, "Application-File:", blen ); 710 char *size = msn_findheader( body, "Application-FileSize:", blen ); 711 712 if( name && size ) 713 { 714 g_snprintf( buf, sizeof( buf ), "<< \x02""BitlBee\x02"" - Filetransfer: `%s', %s bytes >>\n" 715 "Filetransfers are not supported by BitlBee for now...", name, size ); 716 } 717 else 718 { 719 strcpy( buf, "<< \x02""BitlBee\x02"" - Corrupted MSN filetransfer invitation message >>" ); 720 } 721 722 if( name ) g_free( name ); 723 if( size ) g_free( size ); 724 } 725 else 726 { 727 char *iname = msn_findheader( body, "Application-Name:", blen ); 728 729 g_snprintf( buf, sizeof( buf ), "<< \x02""BitlBee\x02"" - Unknown MSN invitation - %s (%s) >>", 730 itype, iname ? iname : "no name" ); 731 732 if( iname ) g_free( iname ); 733 } 734 735 g_free( itype ); 736 737 if( !*buf ) 738 return( 1 ); 739 740 if( sb->who ) 741 { 742 imcb_buddy_msg( ic, cmd[1], buf, 0, 0 ); 743 } 744 else if( sb->chat ) 745 { 746 imcb_chat_msg( sb->chat, cmd[1], buf, 0, 0 ); 747 } 748 else 749 { 750 /* PANIC! */ 751 } 746 752 } 747 753 else if( g_strncasecmp( ct, "text/x-msmsgscontrol", 20 ) == 0 ) … … 774 780 void msn_sb_start_keepalives( struct msn_switchboard *sb, gboolean initial ) 775 781 { 776 bee_user_t *bu;782 struct buddy *b; 777 783 778 784 if( sb && sb->who && sb->keepalive == 0 && 779 ( bu = bee_user_by_handle( sb->ic->bee, sb->ic, sb->who ) ) && 780 !( bu->flags & BEE_USER_ONLINE ) && 785 ( b = imcb_find_buddy( sb->ic, sb->who ) ) && !b->present && 781 786 set_getbool( &sb->ic->acc->set, "switchboard_keepalives" ) ) 782 787 { -
protocols/nogaim.c
r8b8def58 r38ff846 38 38 #include "chat.h" 39 39 40 static int remove_chat_buddy_silent( struct groupchat *b, const char *handle ); 41 static char *format_timestamp( irc_t *irc, time_t msg_ts ); 42 40 43 GSList *connections; 41 44 … … 89 92 } 90 93 #endif 94 95 /* nogaim.c */ 91 96 92 97 GList *protocols = NULL; … … 112 117 { 113 118 GList *gl; 114 115 for( gl = protocols; gl; gl = gl->next ) 119 for (gl = protocols; gl; gl = gl->next) 116 120 { 117 121 struct prpl *proto = gl->data; 118 119 if( g_strcasecmp( proto->name, name ) == 0 ) 122 if(!g_strcasecmp(proto->name, name)) 120 123 return proto; 121 124 } 122 123 125 return NULL; 124 126 } 125 127 128 /* nogaim.c */ 126 129 void nogaim_init() 127 130 { … … 131 134 extern void jabber_initmodule(); 132 135 extern void twitter_initmodule(); 133 extern void purple_initmodule();134 136 135 137 #ifdef WITH_MSN … … 153 155 #endif 154 156 155 #ifdef WITH_PURPLE156 purple_initmodule();157 #endif158 159 157 #ifdef WITH_PLUGINS 160 158 load_plugins(); … … 164 162 GSList *get_connections() { return connections; } 165 163 164 /* multi.c */ 165 166 166 struct im_connection *imcb_new( account_t *acc ) 167 167 { … … 170 170 ic = g_new0( struct im_connection, 1 ); 171 171 172 ic-> bee = acc->bee;172 ic->irc = acc->irc; 173 173 ic->acc = acc; 174 174 acc->ic = ic; … … 184 184 185 185 /* Destroy the pointer to this connection from the account list */ 186 for( a = ic-> bee->accounts; a; a = a->next )186 for( a = ic->irc->accounts; a; a = a->next ) 187 187 if( a->ic == ic ) 188 188 { … … 205 205 va_end( params ); 206 206 207 if( ( g_strcasecmp( set_getstr( &ic-> bee->set, "strip_html" ), "always" ) == 0 ) ||208 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic-> bee->set, "strip_html" ) ) )207 if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) || 208 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) ) 209 209 strip_html( text ); 210 210 211 211 /* Try to find a different connection on the same protocol. */ 212 for( a = ic-> bee->accounts; a; a = a->next )212 for( a = ic->irc->accounts; a; a = a->next ) 213 213 if( a->prpl == ic->acc->prpl && a->ic != ic ) 214 214 break; … … 216 216 /* If we found one, include the screenname in the message. */ 217 217 if( a ) 218 /* FIXME(wilmer): ui_log callback or so */ 219 irc_usermsg( ic->bee->ui_data, "%s(%s) - %s", ic->acc->prpl->name, ic->acc->user, text ); 218 irc_usermsg( ic->irc, "%s(%s) - %s", ic->acc->prpl->name, ic->acc->user, text ); 220 219 else 221 irc_usermsg( ic-> bee->ui_data, "%s - %s", ic->acc->prpl->name, text );220 irc_usermsg( ic->irc, "%s - %s", ic->acc->prpl->name, text ); 222 221 223 222 g_free( text ); … … 270 269 void imcb_connected( struct im_connection *ic ) 271 270 { 271 irc_t *irc = ic->irc; 272 struct chat *c; 273 user_t *u; 274 272 275 /* MSN servers sometimes redirect you to a different server and do 273 276 the whole login sequence again, so these "late" calls to this … … 276 279 return; 277 280 281 u = user_find( ic->irc, ic->irc->nick ); 282 278 283 imcb_log( ic, "Logged in" ); 279 284 … … 288 293 ic->acc->auto_reconnect_delay = 0; 289 294 290 /*291 295 for( c = irc->chatrooms; c; c = c->next ) 292 296 { … … 297 301 chat_join( irc, c, NULL ); 298 302 } 299 */300 303 } 301 304 … … 305 308 306 309 a->reconnect = 0; 307 account_on( a-> bee, a );310 account_on( a->irc, a ); 308 311 309 312 return( FALSE ); /* Only have to run the timeout once */ … … 318 321 void imc_logout( struct im_connection *ic, int allow_reconnect ) 319 322 { 320 bee_t *bee = ic->bee; 323 irc_t *irc = ic->irc; 324 user_t *t, *u; 321 325 account_t *a; 322 GSList *l;323 326 int delay; 324 327 … … 340 343 ic->away = NULL; 341 344 342 for( l = bee->users; l; ) 343 { 344 bee_user_t *bu = l->data; 345 GSList *next = l->next; 346 347 if( bu->ic == ic ) 348 bee_user_free( bee, bu ); 349 350 l = next; 351 } 352 353 query_del_by_conn( (irc_t*) ic->bee->ui_data, ic ); 354 355 for( a = bee->accounts; a; a = a->next ) 345 u = irc->users; 346 while( u ) 347 { 348 if( u->ic == ic ) 349 { 350 t = u->next; 351 user_del( irc, u->nick ); 352 u = t; 353 } 354 else 355 u = u->next; 356 } 357 358 query_del_by_conn( ic->irc, ic ); 359 360 for( a = irc->accounts; a; a = a->next ) 356 361 if( a->ic == ic ) 357 362 break; … … 361 366 /* Uhm... This is very sick. */ 362 367 } 363 else if( allow_reconnect && set_getbool( & bee->set, "auto_reconnect" ) &&368 else if( allow_reconnect && set_getbool( &irc->set, "auto_reconnect" ) && 364 369 set_getbool( &a->set, "auto_reconnect" ) && 365 370 ( delay = account_reconnect_delay( a ) ) > 0 ) … … 372 377 } 373 378 379 380 /* dialogs.c */ 381 374 382 void imcb_ask( struct im_connection *ic, char *msg, void *data, 375 383 query_callback doit, query_callback dont ) 376 384 { 377 query_add( (irc_t *) ic->bee->ui_data, ic, msg, doit, dont, data ); 378 } 385 query_add( ic->irc, ic, msg, doit, dont, data ); 386 } 387 388 389 /* list.c */ 379 390 380 391 void imcb_add_buddy( struct im_connection *ic, const char *handle, const char *group ) 381 392 { 382 bee_user_t *bu; 383 bee_t *bee = ic->bee; 384 385 if( !( bu = bee_user_by_handle( bee, ic, handle ) ) ) 386 bu = bee_user_new( bee, ic, handle, 0 ); 387 388 bu->group = bee_group_by_name( bee, group, TRUE ); 389 390 if( bee->ui->user_group ) 391 bee->ui->user_group( bee, bu ); 392 } 393 394 void imcb_rename_buddy( struct im_connection *ic, const char *handle, const char *fullname ) 395 { 396 bee_t *bee = ic->bee; 397 bee_user_t *bu = bee_user_by_handle( bee, ic, handle ); 398 399 if( !bu || !fullname ) return; 400 401 if( !bu->fullname || strcmp( bu->fullname, fullname ) != 0 ) 402 { 403 g_free( bu->fullname ); 404 bu->fullname = g_strdup( fullname ); 405 406 if( bee->ui->user_fullname ) 407 bee->ui->user_fullname( bee, bu ); 393 user_t *u; 394 char nick[MAX_NICK_LENGTH+1], *s; 395 irc_t *irc = ic->irc; 396 397 if( user_findhandle( ic, handle ) ) 398 { 399 if( set_getbool( &irc->set, "debug" ) ) 400 imcb_log( ic, "User already exists, ignoring add request: %s", handle ); 401 402 return; 403 404 /* Buddy seems to exist already. Let's ignore this request then... 405 Eventually subsequent calls to this function *should* be possible 406 when a buddy is in multiple groups. But for now BitlBee doesn't 407 even support groups so let's silently ignore this for now. */ 408 } 409 410 memset( nick, 0, MAX_NICK_LENGTH + 1 ); 411 strcpy( nick, nick_get( ic->acc, handle ) ); 412 413 u = user_add( ic->irc, nick ); 414 415 // if( !realname || !*realname ) realname = nick; 416 // u->realname = g_strdup( realname ); 417 418 if( ( s = strchr( handle, '@' ) ) ) 419 { 420 u->host = g_strdup( s + 1 ); 421 u->user = g_strndup( handle, s - handle ); 422 } 423 else if( ic->acc->server ) 424 { 425 u->host = g_strdup( ic->acc->server ); 426 u->user = g_strdup( handle ); 427 428 /* s/ /_/ ... important for AOL screennames */ 429 for( s = u->user; *s; s ++ ) 430 if( *s == ' ' ) 431 *s = '_'; 432 } 433 else 434 { 435 u->host = g_strdup( ic->acc->prpl->name ); 436 u->user = g_strdup( handle ); 437 } 438 439 u->ic = ic; 440 u->handle = g_strdup( handle ); 441 if( group ) u->group = g_strdup( group ); 442 u->send_handler = buddy_send_handler; 443 u->last_typing_notice = 0; 444 } 445 446 struct buddy *imcb_find_buddy( struct im_connection *ic, char *handle ) 447 { 448 static struct buddy b[1]; 449 user_t *u; 450 451 u = user_findhandle( ic, handle ); 452 453 if( !u ) 454 return( NULL ); 455 456 memset( b, 0, sizeof( b ) ); 457 strncpy( b->name, handle, 80 ); 458 strncpy( b->show, u->realname, BUDDY_ALIAS_MAXLEN ); 459 b->present = u->online; 460 b->ic = u->ic; 461 462 return( b ); 463 } 464 465 void imcb_rename_buddy( struct im_connection *ic, const char *handle, const char *realname ) 466 { 467 user_t *u = user_findhandle( ic, handle ); 468 char *set; 469 470 if( !u || !realname ) return; 471 472 if( g_strcasecmp( u->realname, realname ) != 0 ) 473 { 474 if( u->realname != u->nick ) g_free( u->realname ); 475 476 u->realname = g_strdup( realname ); 477 478 if( ( ic->flags & OPT_LOGGED_IN ) && set_getbool( &ic->irc->set, "display_namechanges" ) ) 479 imcb_log( ic, "User `%s' changed name to `%s'", u->nick, u->realname ); 480 } 481 482 set = set_getstr( &ic->acc->set, "nick_source" ); 483 if( strcmp( set, "handle" ) != 0 ) 484 { 485 char *name = g_strdup( realname ); 486 487 if( strcmp( set, "first_name" ) == 0 ) 488 { 489 int i; 490 for( i = 0; name[i] && !isspace( name[i] ); i ++ ) {} 491 name[i] = '\0'; 492 } 493 494 imcb_buddy_nick_hint( ic, handle, name ); 495 496 g_free( name ); 408 497 } 409 498 } … … 411 500 void imcb_remove_buddy( struct im_connection *ic, const char *handle, char *group ) 412 501 { 413 bee_user_free( ic->bee, bee_user_by_handle( ic->bee, ic, handle ) ); 502 user_t *u; 503 504 if( ( u = user_findhandle( ic, handle ) ) ) 505 user_del( ic->irc, u->nick ); 414 506 } 415 507 … … 418 510 void imcb_buddy_nick_hint( struct im_connection *ic, const char *handle, const char *nick ) 419 511 { 420 bee_t *bee = ic->bee; 421 bee_user_t *bu = bee_user_by_handle( bee, ic, handle ); 422 423 if( !bu || !nick ) return; 424 425 if( bee->ui->user_nick_hint ) 426 bee->ui->user_nick_hint( bee, bu, nick ); 512 user_t *u = user_findhandle( ic, handle ); 513 char newnick[MAX_NICK_LENGTH+1], *orig_nick; 514 515 if( u && !u->online && !nick_saved( ic->acc, handle ) ) 516 { 517 /* Only do this if the person isn't online yet (which should 518 be the case if we just added it) and if the user hasn't 519 assigned a nickname to this buddy already. */ 520 521 strncpy( newnick, nick, MAX_NICK_LENGTH ); 522 newnick[MAX_NICK_LENGTH] = 0; 523 524 /* Some processing to make sure this string is a valid IRC nickname. */ 525 nick_strip( newnick ); 526 if( set_getbool( &ic->irc->set, "lcnicks" ) ) 527 nick_lc( newnick ); 528 529 if( strcmp( u->nick, newnick ) != 0 ) 530 { 531 /* Only do this if newnick is different from the current one. 532 If rejoining a channel, maybe we got this nick already 533 (and dedupe would only add an underscore. */ 534 nick_dedupe( ic->acc, handle, newnick ); 535 536 /* u->nick will be freed halfway the process, so it can't be 537 passed as an argument. */ 538 orig_nick = g_strdup( u->nick ); 539 user_rename( ic->irc, orig_nick, newnick ); 540 g_free( orig_nick ); 541 } 542 } 427 543 } 428 544 … … 469 585 data->ic = ic; 470 586 data->handle = g_strdup( handle ); 471 query_add( (irc_t *) ic->bee->ui_data, ic, s, 472 imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, data ); 587 query_add( ic->irc, ic, s, imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, data ); 473 588 } 474 589 … … 495 610 496 611 /* TODO: Make a setting for this! */ 497 if( bee_user_by_handle( ic->bee,ic, handle ) != NULL )612 if( user_findhandle( ic, handle ) != NULL ) 498 613 return; 499 614 … … 502 617 data->ic = ic; 503 618 data->handle = g_strdup( handle ); 504 query_add( (irc_t *) ic->bee->ui_data, ic, s, 505 imcb_ask_add_cb_yes, imcb_ask_add_cb_no, data ); 506 } 507 508 struct bee_user *imcb_buddy_by_handle( struct im_connection *ic, const char *handle ) 509 { 510 return bee_user_by_handle( ic->bee, ic, handle ); 619 query_add( ic->irc, ic, s, imcb_ask_add_cb_yes, imcb_ask_add_cb_no, data ); 620 } 621 622 623 /* server.c */ 624 625 void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, const char *state, const char *message ) 626 { 627 user_t *u; 628 int oa, oo; 629 630 u = user_findhandle( ic, (char*) handle ); 631 632 if( !u ) 633 { 634 if( g_strcasecmp( set_getstr( &ic->irc->set, "handle_unknown" ), "add" ) == 0 ) 635 { 636 imcb_add_buddy( ic, (char*) handle, NULL ); 637 u = user_findhandle( ic, (char*) handle ); 638 } 639 else 640 { 641 if( set_getbool( &ic->irc->set, "debug" ) || g_strcasecmp( set_getstr( &ic->irc->set, "handle_unknown" ), "ignore" ) != 0 ) 642 { 643 imcb_log( ic, "imcb_buddy_status() for unknown handle %s:", handle ); 644 imcb_log( ic, "flags = %d, state = %s, message = %s", flags, 645 state ? state : "NULL", message ? message : "NULL" ); 646 } 647 648 return; 649 } 650 } 651 652 oa = u->away != NULL; 653 oo = u->online; 654 655 g_free( u->away ); 656 g_free( u->status_msg ); 657 u->away = u->status_msg = NULL; 658 659 if( set_getbool( &ic->irc->set, "show_offline" ) && !u->online ) 660 { 661 /* always set users as online */ 662 irc_spawn( ic->irc, u ); 663 u->online = 1; 664 if( !( flags & OPT_LOGGED_IN ) ) 665 { 666 /* set away message if user isn't really online */ 667 u->away = g_strdup( "User is offline" ); 668 } 669 } 670 else if( ( flags & OPT_LOGGED_IN ) && !u->online ) 671 { 672 irc_spawn( ic->irc, u ); 673 u->online = 1; 674 } 675 else if( !( flags & OPT_LOGGED_IN ) && u->online ) 676 { 677 struct groupchat *c; 678 679 if( set_getbool( &ic->irc->set, "show_offline" ) ) 680 { 681 /* keep offline users in channel and set away message to "offline" */ 682 u->away = g_strdup( "User is offline" ); 683 684 /* Keep showing him/her in the control channel but not in groupchats. */ 685 for( c = ic->groupchats; c; c = c->next ) 686 { 687 if( remove_chat_buddy_silent( c, handle ) && c->joined ) 688 irc_part( c->ic->irc, u, c->channel ); 689 } 690 } 691 else 692 { 693 /* kill offline users */ 694 irc_kill( ic->irc, u ); 695 u->online = 0; 696 697 /* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */ 698 for( c = ic->groupchats; c; c = c->next ) 699 remove_chat_buddy_silent( c, handle ); 700 } 701 } 702 703 if( flags & OPT_AWAY ) 704 { 705 if( state && message ) 706 { 707 u->away = g_strdup_printf( "%s (%s)", state, message ); 708 } 709 else if( state ) 710 { 711 u->away = g_strdup( state ); 712 } 713 else if( message ) 714 { 715 u->away = g_strdup( message ); 716 } 717 else 718 { 719 u->away = g_strdup( "Away" ); 720 } 721 } 722 else 723 { 724 u->status_msg = g_strdup( message ); 725 } 726 727 /* early if-clause for show_offline even if there is some redundant code here because this isn't LISP but C ;) */ 728 if( set_getbool( &ic->irc->set, "show_offline" ) && set_getbool( &ic->irc->set, "away_devoice" ) ) 729 { 730 char *from; 731 732 if( set_getbool( &ic->irc->set, "simulate_netsplit" ) ) 733 { 734 from = g_strdup( ic->irc->myhost ); 735 } 736 else 737 { 738 from = g_strdup_printf( "%s!%s@%s", ic->irc->mynick, ic->irc->mynick, 739 ic->irc->myhost ); 740 } 741 742 /* if we use show_offline, we op online users, voice away users, and devoice/deop offline users */ 743 if( flags & OPT_LOGGED_IN ) 744 { 745 /* user is "online" (either really online or away) */ 746 irc_write( ic->irc, ":%s MODE %s %cv%co %s %s", from, ic->irc->channel, 747 u->away?'+':'-', u->away?'-':'+', u->nick, u->nick ); 748 } 749 else 750 { 751 /* user is offline */ 752 irc_write( ic->irc, ":%s MODE %s -vo %s %s", from, ic->irc->channel, u->nick, u->nick ); 753 } 754 } 755 else 756 { 757 /* LISPy... */ 758 if( ( set_getbool( &ic->irc->set, "away_devoice" ) ) && /* Don't do a thing when user doesn't want it */ 759 ( u->online ) && /* Don't touch offline people */ 760 ( ( ( u->online != oo ) && !u->away ) || /* Voice joining people */ 761 ( ( u->online == oo ) && ( oa == !u->away ) ) ) ) /* (De)voice people changing state */ 762 { 763 char *from; 764 765 if( set_getbool( &ic->irc->set, "simulate_netsplit" ) ) 766 { 767 from = g_strdup( ic->irc->myhost ); 768 } 769 else 770 { 771 from = g_strdup_printf( "%s!%s@%s", ic->irc->mynick, ic->irc->mynick, 772 ic->irc->myhost ); 773 } 774 irc_write( ic->irc, ":%s MODE %s %cv %s", from, ic->irc->channel, 775 u->away?'-':'+', u->nick ); 776 g_free( from ); 777 } 778 } 779 } 780 781 void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, uint32_t flags, time_t sent_at ) 782 { 783 irc_t *irc = ic->irc; 784 char *wrapped, *ts = NULL; 785 user_t *u; 786 787 u = user_findhandle( ic, handle ); 788 789 if( !u ) 790 { 791 char *h = set_getstr( &irc->set, "handle_unknown" ); 792 793 if( g_strcasecmp( h, "ignore" ) == 0 ) 794 { 795 if( set_getbool( &irc->set, "debug" ) ) 796 imcb_log( ic, "Ignoring message from unknown handle %s", handle ); 797 798 return; 799 } 800 else if( g_strncasecmp( h, "add", 3 ) == 0 ) 801 { 802 int private = set_getbool( &irc->set, "private" ); 803 804 if( h[3] ) 805 { 806 if( g_strcasecmp( h + 3, "_private" ) == 0 ) 807 private = 1; 808 else if( g_strcasecmp( h + 3, "_channel" ) == 0 ) 809 private = 0; 810 } 811 812 imcb_add_buddy( ic, handle, NULL ); 813 u = user_findhandle( ic, handle ); 814 u->is_private = private; 815 } 816 else 817 { 818 imcb_log( ic, "Message from unknown handle %s:", handle ); 819 u = user_find( irc, irc->mynick ); 820 } 821 } 822 823 if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) || 824 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) ) 825 strip_html( msg ); 826 827 if( set_getbool( &ic->irc->set, "display_timestamps" ) && 828 ( ts = format_timestamp( irc, sent_at ) ) ) 829 { 830 char *new = g_strconcat( ts, msg, NULL ); 831 g_free( ts ); 832 ts = msg = new; 833 } 834 835 wrapped = word_wrap( msg, 425 ); 836 irc_msgfrom( irc, u->nick, wrapped ); 837 g_free( wrapped ); 838 g_free( ts ); 839 } 840 841 void imcb_buddy_typing( struct im_connection *ic, char *handle, uint32_t flags ) 842 { 843 user_t *u; 844 845 if( !set_getbool( &ic->irc->set, "typing_notice" ) ) 846 return; 847 848 if( ( u = user_findhandle( ic, handle ) ) ) 849 { 850 char buf[256]; 851 852 g_snprintf( buf, 256, "\1TYPING %d\1", ( flags >> 8 ) & 3 ); 853 irc_privmsg( ic->irc, u, "PRIVMSG", ic->irc->nick, NULL, buf ); 854 } 855 } 856 857 struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle ) 858 { 859 struct groupchat *c; 860 861 /* This one just creates the conversation structure, user won't see anything yet */ 862 863 if( ic->groupchats ) 864 { 865 for( c = ic->groupchats; c->next; c = c->next ); 866 c = c->next = g_new0( struct groupchat, 1 ); 867 } 868 else 869 ic->groupchats = c = g_new0( struct groupchat, 1 ); 870 871 c->ic = ic; 872 c->title = g_strdup( handle ); 873 c->channel = g_strdup_printf( "&chat_%03d", ic->irc->c_id++ ); 874 c->topic = g_strdup_printf( "BitlBee groupchat: \"%s\". Please keep in mind that root-commands won't work here. Have fun!", c->title ); 875 876 if( set_getbool( &ic->irc->set, "debug" ) ) 877 imcb_log( ic, "Creating new conversation: (id=%p,handle=%s)", c, handle ); 878 879 return c; 880 } 881 882 void imcb_chat_name_hint( struct groupchat *c, const char *name ) 883 { 884 if( !c->joined ) 885 { 886 struct im_connection *ic = c->ic; 887 char stripped[MAX_NICK_LENGTH+1], *full_name; 888 889 strncpy( stripped, name, MAX_NICK_LENGTH ); 890 stripped[MAX_NICK_LENGTH] = '\0'; 891 nick_strip( stripped ); 892 if( set_getbool( &ic->irc->set, "lcnicks" ) ) 893 nick_lc( stripped ); 894 895 full_name = g_strdup_printf( "&%s", stripped ); 896 897 if( stripped[0] && 898 nick_cmp( stripped, ic->irc->channel + 1 ) != 0 && 899 irc_chat_by_channel( ic->irc, full_name ) == NULL ) 900 { 901 g_free( c->channel ); 902 c->channel = full_name; 903 } 904 else 905 { 906 g_free( full_name ); 907 } 908 } 909 } 910 911 void imcb_chat_free( struct groupchat *c ) 912 { 913 struct im_connection *ic = c->ic; 914 struct groupchat *l; 915 GList *ir; 916 917 if( set_getbool( &ic->irc->set, "debug" ) ) 918 imcb_log( ic, "You were removed from conversation %p", c ); 919 920 if( c ) 921 { 922 if( c->joined ) 923 { 924 user_t *u, *r; 925 926 r = user_find( ic->irc, ic->irc->mynick ); 927 irc_privmsg( ic->irc, r, "PRIVMSG", c->channel, "", "Cleaning up channel, bye!" ); 928 929 u = user_find( ic->irc, ic->irc->nick ); 930 irc_kick( ic->irc, u, c->channel, r ); 931 /* irc_part( ic->irc, u, c->channel ); */ 932 } 933 934 /* Find the previous chat in the linked list. */ 935 for( l = ic->groupchats; l && l->next != c; l = l->next ); 936 937 if( l ) 938 l->next = c->next; 939 else 940 ic->groupchats = c->next; 941 942 for( ir = c->in_room; ir; ir = ir->next ) 943 g_free( ir->data ); 944 g_list_free( c->in_room ); 945 g_free( c->channel ); 946 g_free( c->title ); 947 g_free( c->topic ); 948 g_free( c ); 949 } 950 } 951 952 void imcb_chat_msg( struct groupchat *c, const char *who, char *msg, uint32_t flags, time_t sent_at ) 953 { 954 struct im_connection *ic = c->ic; 955 char *wrapped; 956 user_t *u; 957 958 /* Gaim sends own messages through this too. IRC doesn't want this, so kill them */ 959 if( g_strcasecmp( who, ic->acc->user ) == 0 ) 960 return; 961 962 u = user_findhandle( ic, who ); 963 964 if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) || 965 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) ) 966 strip_html( msg ); 967 968 wrapped = word_wrap( msg, 425 ); 969 if( c && u ) 970 { 971 char *ts = NULL; 972 if( set_getbool( &ic->irc->set, "display_timestamps" ) ) 973 ts = format_timestamp( ic->irc, sent_at ); 974 irc_privmsg( ic->irc, u, "PRIVMSG", c->channel, ts ? : "", wrapped ); 975 g_free( ts ); 976 } 977 else 978 { 979 imcb_log( ic, "Message from/to conversation %s@%p (unknown conv/user): %s", who, c, wrapped ); 980 } 981 g_free( wrapped ); 982 } 983 984 void imcb_chat_log( struct groupchat *c, char *format, ... ) 985 { 986 irc_t *irc = c->ic->irc; 987 va_list params; 988 char *text; 989 user_t *u; 990 991 va_start( params, format ); 992 text = g_strdup_vprintf( format, params ); 993 va_end( params ); 994 995 u = user_find( irc, irc->mynick ); 996 997 irc_privmsg( irc, u, "PRIVMSG", c->channel, "System message: ", text ); 998 999 g_free( text ); 1000 } 1001 1002 void imcb_chat_topic( struct groupchat *c, char *who, char *topic, time_t set_at ) 1003 { 1004 struct im_connection *ic = c->ic; 1005 user_t *u = NULL; 1006 1007 if( who == NULL) 1008 u = user_find( ic->irc, ic->irc->mynick ); 1009 else if( g_strcasecmp( who, ic->acc->user ) == 0 ) 1010 u = user_find( ic->irc, ic->irc->nick ); 1011 else 1012 u = user_findhandle( ic, who ); 1013 1014 if( ( g_strcasecmp( set_getstr( &ic->irc->set, "strip_html" ), "always" ) == 0 ) || 1015 ( ( ic->flags & OPT_DOES_HTML ) && set_getbool( &ic->irc->set, "strip_html" ) ) ) 1016 strip_html( topic ); 1017 1018 g_free( c->topic ); 1019 c->topic = g_strdup( topic ); 1020 1021 if( c->joined && u ) 1022 irc_write( ic->irc, ":%s!%s@%s TOPIC %s :%s", u->nick, u->user, u->host, c->channel, topic ); 1023 } 1024 1025 1026 /* buddy_chat.c */ 1027 1028 void imcb_chat_add_buddy( struct groupchat *b, const char *handle ) 1029 { 1030 user_t *u = user_findhandle( b->ic, handle ); 1031 int me = 0; 1032 1033 if( set_getbool( &b->ic->irc->set, "debug" ) ) 1034 imcb_log( b->ic, "User %s added to conversation %p", handle, b ); 1035 1036 /* It might be yourself! */ 1037 if( b->ic->acc->prpl->handle_cmp( handle, b->ic->acc->user ) == 0 ) 1038 { 1039 u = user_find( b->ic->irc, b->ic->irc->nick ); 1040 if( !b->joined ) 1041 irc_join( b->ic->irc, u, b->channel ); 1042 b->joined = me = 1; 1043 } 1044 1045 /* Most protocols allow people to join, even when they're not in 1046 your contact list. Try to handle that here */ 1047 if( !u ) 1048 { 1049 imcb_add_buddy( b->ic, handle, NULL ); 1050 u = user_findhandle( b->ic, handle ); 1051 } 1052 1053 /* Add the handle to the room userlist, if it's not 'me' */ 1054 if( !me ) 1055 { 1056 if( b->joined ) 1057 irc_join( b->ic->irc, u, b->channel ); 1058 b->in_room = g_list_append( b->in_room, g_strdup( handle ) ); 1059 } 1060 } 1061 1062 /* This function is one BIG hack... :-( EREWRITE */ 1063 void imcb_chat_remove_buddy( struct groupchat *b, const char *handle, const char *reason ) 1064 { 1065 user_t *u; 1066 int me = 0; 1067 1068 if( set_getbool( &b->ic->irc->set, "debug" ) ) 1069 imcb_log( b->ic, "User %s removed from conversation %p (%s)", handle, b, reason ? reason : "" ); 1070 1071 /* It might be yourself! */ 1072 if( g_strcasecmp( handle, b->ic->acc->user ) == 0 ) 1073 { 1074 if( b->joined == 0 ) 1075 return; 1076 1077 u = user_find( b->ic->irc, b->ic->irc->nick ); 1078 b->joined = 0; 1079 me = 1; 1080 } 1081 else 1082 { 1083 u = user_findhandle( b->ic, handle ); 1084 } 1085 1086 if( me || ( remove_chat_buddy_silent( b, handle ) && b->joined && u ) ) 1087 irc_part( b->ic->irc, u, b->channel ); 1088 } 1089 1090 static int remove_chat_buddy_silent( struct groupchat *b, const char *handle ) 1091 { 1092 GList *i; 1093 1094 /* Find the handle in the room userlist and shoot it */ 1095 i = b->in_room; 1096 while( i ) 1097 { 1098 if( g_strcasecmp( handle, i->data ) == 0 ) 1099 { 1100 g_free( i->data ); 1101 b->in_room = g_list_remove( b->in_room, i->data ); 1102 return( 1 ); 1103 } 1104 1105 i = i->next; 1106 } 1107 1108 return( 0 ); 1109 } 1110 1111 1112 /* Misc. BitlBee stuff which shouldn't really be here */ 1113 1114 char *set_eval_away_devoice( set_t *set, char *value ) 1115 { 1116 irc_t *irc = set->data; 1117 int st; 1118 1119 if( !is_bool( value ) ) 1120 return SET_INVALID; 1121 1122 st = bool2int( value ); 1123 1124 /* Horror.... */ 1125 1126 if( st != set_getbool( &irc->set, "away_devoice" ) ) 1127 { 1128 char list[80] = ""; 1129 user_t *u = irc->users; 1130 int i = 0, count = 0; 1131 char pm; 1132 char v[80]; 1133 1134 if( st ) 1135 pm = '+'; 1136 else 1137 pm = '-'; 1138 1139 while( u ) 1140 { 1141 if( u->ic && u->online && !u->away ) 1142 { 1143 if( ( strlen( list ) + strlen( u->nick ) ) >= 79 ) 1144 { 1145 for( i = 0; i < count; v[i++] = 'v' ); v[i] = 0; 1146 irc_write( irc, ":%s MODE %s %c%s%s", 1147 irc->myhost, 1148 irc->channel, pm, v, list ); 1149 1150 *list = 0; 1151 count = 0; 1152 } 1153 1154 sprintf( list + strlen( list ), " %s", u->nick ); 1155 count ++; 1156 } 1157 u = u->next; 1158 } 1159 1160 /* $v = 'v' x $i */ 1161 for( i = 0; i < count; v[i++] = 'v' ); v[i] = 0; 1162 irc_write( irc, ":%s MODE %s %c%s%s", irc->myhost, 1163 irc->channel, pm, v, list ); 1164 } 1165 1166 return value; 1167 } 1168 1169 char *set_eval_timezone( set_t *set, char *value ) 1170 { 1171 char *s; 1172 1173 if( strcmp( value, "local" ) == 0 || 1174 strcmp( value, "gmt" ) == 0 || strcmp( value, "utc" ) == 0 ) 1175 return value; 1176 1177 /* Otherwise: +/- at the beginning optional, then one or more numbers, 1178 possibly followed by a colon and more numbers. Don't bother bound- 1179 checking them since users are free to shoot themselves in the foot. */ 1180 s = value; 1181 if( *s == '+' || *s == '-' ) 1182 s ++; 1183 1184 /* \d+ */ 1185 if( !isdigit( *s ) ) 1186 return SET_INVALID; 1187 while( *s && isdigit( *s ) ) s ++; 1188 1189 /* EOS? */ 1190 if( *s == '\0' ) 1191 return value; 1192 1193 /* Otherwise, colon */ 1194 if( *s != ':' ) 1195 return SET_INVALID; 1196 s ++; 1197 1198 /* \d+ */ 1199 if( !isdigit( *s ) ) 1200 return SET_INVALID; 1201 while( *s && isdigit( *s ) ) s ++; 1202 1203 /* EOS */ 1204 return *s == '\0' ? value : SET_INVALID; 1205 } 1206 1207 static char *format_timestamp( irc_t *irc, time_t msg_ts ) 1208 { 1209 time_t now_ts = time( NULL ); 1210 struct tm now, msg; 1211 char *set; 1212 1213 /* If the timestamp is <= 0 or less than a minute ago, discard it as 1214 it doesn't seem to add to much useful info and/or might be noise. */ 1215 if( msg_ts <= 0 || msg_ts > now_ts - 60 ) 1216 return NULL; 1217 1218 set = set_getstr( &irc->set, "timezone" ); 1219 if( strcmp( set, "local" ) == 0 ) 1220 { 1221 localtime_r( &now_ts, &now ); 1222 localtime_r( &msg_ts, &msg ); 1223 } 1224 else 1225 { 1226 int hr, min = 0, sign = 60; 1227 1228 if( set[0] == '-' ) 1229 { 1230 sign *= -1; 1231 set ++; 1232 } 1233 else if( set[0] == '+' ) 1234 { 1235 set ++; 1236 } 1237 1238 if( sscanf( set, "%d:%d", &hr, &min ) >= 1 ) 1239 { 1240 msg_ts += sign * ( hr * 60 + min ); 1241 now_ts += sign * ( hr * 60 + min ); 1242 } 1243 1244 gmtime_r( &now_ts, &now ); 1245 gmtime_r( &msg_ts, &msg ); 1246 } 1247 1248 if( msg.tm_year == now.tm_year && msg.tm_yday == now.tm_yday ) 1249 return g_strdup_printf( "\x02[\x02\x02\x02%02d:%02d:%02d\x02]\x02 ", 1250 msg.tm_hour, msg.tm_min, msg.tm_sec ); 1251 else 1252 return g_strdup_printf( "\x02[\x02\x02\x02%04d-%02d-%02d " 1253 "%02d:%02d:%02d\x02]\x02 ", 1254 msg.tm_year + 1900, msg.tm_mon + 1, msg.tm_mday, 1255 msg.tm_hour, msg.tm_min, msg.tm_sec ); 511 1256 } 512 1257 513 1258 /* The plan is to not allow straight calls to prpl functions anymore, but do 514 1259 them all from some wrappers. We'll start to define some down here: */ 1260 1261 int imc_buddy_msg( struct im_connection *ic, char *handle, char *msg, int flags ) 1262 { 1263 char *buf = NULL; 1264 int st; 1265 1266 if( ( ic->flags & OPT_DOES_HTML ) && ( g_strncasecmp( msg, "<html>", 6 ) != 0 ) ) 1267 { 1268 buf = escape_html( msg ); 1269 msg = buf; 1270 } 1271 1272 st = ic->acc->prpl->buddy_msg( ic, handle, msg, flags ); 1273 g_free( buf ); 1274 1275 return st; 1276 } 515 1277 516 1278 int imc_chat_msg( struct groupchat *c, char *msg, int flags ) … … 541 1303 542 1304 away = set_getstr( &ic->acc->set, "away" ) ? 543 : set_getstr( &ic-> bee->set, "away" );1305 : set_getstr( &ic->irc->set, "away" ); 544 1306 if( away && *away ) 545 1307 { … … 552 1314 away = NULL; 553 1315 msg = set_getstr( &ic->acc->set, "status" ) ? 554 : set_getstr( &ic-> bee->set, "status" );1316 : set_getstr( &ic->irc->set, "status" ); 555 1317 } 556 1318 -
protocols/nogaim.h
r8b8def58 r38ff846 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-20 10Wilmer van der Gaast and others *4 * Copyright 2002-2004 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 45 45 #include "proxy.h" 46 46 #include "query.h" 47 #include "md5.h"48 #include "ft.h"49 47 50 48 #define BUDDY_ALIAS_MAXLEN 388 /* because MSN names can be 387 characters */ … … 87 85 88 86 /* BitlBee */ 89 bee_t *bee;90 91 GSList *groupchats;87 irc_t *irc; 88 89 struct groupchat *groupchats; 92 90 }; 93 91 … … 100 98 * already, for example to avoid adding somebody two times. */ 101 99 GList *in_room; 102 //GList *ignored; 103 104 //struct groupchat *next; 100 GList *ignored; 101 102 struct groupchat *next; 103 char *channel; 105 104 /* The title variable contains the ID you gave when you created the 106 105 * chat using imcb_chat_new(). */ … … 113 112 * structure for your protocol's needs. */ 114 113 void *data; 115 void *ui_data;116 114 }; 117 115 … … 134 132 * - The user sees this name ie. when imcb_log() is used. */ 135 133 const char *name; 136 void *data;137 134 138 135 /* Added this one to be able to add per-account settings, don't think … … 231 228 void (* auth_allow) (struct im_connection *, const char *who); 232 229 void (* auth_deny) (struct im_connection *, const char *who); 233 234 /* Incoming transfer request */235 void (* transfer_request) (struct im_connection *, file_transfer_t *ft, char *handle );236 230 }; 237 231 … … 287 281 G_MODULE_EXPORT void imcb_buddy_nick_hint( struct im_connection *ic, const char *handle, const char *nick ); 288 282 283 /* Buddy activity */ 284 /* To manipulate the status of a handle. 285 * - flags can be |='d with OPT_* constants. You will need at least: 286 * OPT_LOGGED_IN and OPT_AWAY. 287 * - 'state' and 'message' can be NULL */ 288 G_MODULE_EXPORT void imcb_buddy_status( struct im_connection *ic, const char *handle, int flags, const char *state, const char *message ); 289 /* Not implemented yet! */ G_MODULE_EXPORT void imcb_buddy_times( struct im_connection *ic, const char *handle, time_t login, time_t idle ); 290 /* Call when a handle says something. 'flags' and 'sent_at may be just 0. */ 291 G_MODULE_EXPORT void imcb_buddy_msg( struct im_connection *ic, const char *handle, char *msg, uint32_t flags, time_t sent_at ); 289 292 G_MODULE_EXPORT void imcb_buddy_typing( struct im_connection *ic, char *handle, uint32_t flags ); 290 G_MODULE_EXPORT struct bee_user *imcb_buddy_by_handle( struct im_connection *ic, const char *handle );291 293 G_MODULE_EXPORT void imcb_clean_handle( struct im_connection *ic, char *handle ); 292 294 … … 314 316 /* Actions, or whatever. */ 315 317 int imc_away_send_update( struct im_connection *ic ); 318 int imc_buddy_msg( struct im_connection *ic, char *handle, char *msg, int flags ); 316 319 int imc_chat_msg( struct groupchat *c, char *msg, int flags ); 317 320 -
protocols/oscar/Makefile
r8b8def58 r38ff846 8 8 9 9 -include ../../Makefile.settings 10 ifdef SRCDIR11 SRCDIR := $(SRCDIR)protocols/oscar/12 CFLAGS += -I$(SRCDIR)13 endif14 10 15 11 # [SH] Program variables … … 37 33 $(objects): ../../Makefile.settings Makefile 38 34 39 $(objects): %.o: $(SRCDIR)%.c35 $(objects): %.o: %.c 40 36 @echo '*' Compiling $< 41 37 @$(CC) -c $(CFLAGS) $< -o $@ -
protocols/oscar/oscar.c
r8b8def58 r38ff846 254 254 255 255 u = t = g_strdup(s); 256 257 strcpy(t, s); 256 258 g_strdown(t); 257 259 … … 288 290 odata = (struct oscar_data *)ic->proto_data; 289 291 290 if (condition & B_EV_IO_READ) {292 if (condition & GAIM_INPUT_READ) { 291 293 if (aim_get_command(odata->sess, conn) >= 0) { 292 294 aim_rxdispatch(odata->sess); … … 360 362 361 363 aim_conn_completeconnect(sess, conn); 362 ic->inpa = b_input_add(conn->fd, B_EV_IO_READ,364 ic->inpa = b_input_add(conn->fd, GAIM_INPUT_READ, 363 365 oscar_callback, conn); 364 366 … … 491 493 492 494 aim_conn_completeconnect(sess, bosconn); 493 ic->inpa = b_input_add(bosconn->fd, B_EV_IO_READ,495 ic->inpa = b_input_add(bosconn->fd, GAIM_INPUT_READ, 494 496 oscar_callback, bosconn); 495 497 imcb_log(ic, _("Connection established, cookie sent")); … … 650 652 struct im_connection *ic = sess->aux_data; 651 653 struct chat_connection *chatcon; 652 struct groupchat *c = NULL;653 654 static int id = 1; 654 655 … … 663 664 chatcon = find_oscar_chat_by_conn(ic, fr->conn); 664 665 chatcon->id = id; 665 666 c = bee_chat_by_title(ic->bee, ic, chatcon->show); 667 if (c && !c->data) 668 chatcon->cnv = c; 669 else 670 chatcon->cnv = imcb_chat_new(ic, chatcon->show); 666 chatcon->cnv = imcb_chat_new(ic, chatcon->show); 671 667 chatcon->cnv->data = chatcon; 672 668 … … 707 703 708 704 aim_conn_completeconnect(sess, tstconn); 709 odata->cnpa = b_input_add(tstconn->fd, B_EV_IO_READ,705 odata->cnpa = b_input_add(tstconn->fd, GAIM_INPUT_READ, 710 706 oscar_callback, tstconn); 711 707 … … 735 731 736 732 aim_conn_completeconnect(sess, tstconn); 737 odata->paspa = b_input_add(tstconn->fd, B_EV_IO_READ,733 odata->paspa = b_input_add(tstconn->fd, GAIM_INPUT_READ, 738 734 oscar_callback, tstconn); 739 735 … … 771 767 aim_conn_completeconnect(sess, ccon->conn); 772 768 ccon->inpa = b_input_add(tstconn->fd, 773 B_EV_IO_READ,769 GAIM_INPUT_READ, 774 770 oscar_callback, tstconn); 775 771 odata->oscar_chats = g_slist_append(odata->oscar_chats, ccon); … … 938 934 tmp = normalize(info->sn); 939 935 imcb_buddy_status(ic, tmp, flags, state_string, NULL); 940 imcb_buddy_times(ic, tmp, signon, time_idle);936 /* imcb_buddy_times(ic, tmp, signon, time_idle); */ 941 937 942 938 … … 1064 1060 aim_ssi_auth_reply(od->sess, od->conn, uin, 1, ""); 1065 1061 // aim_send_im_ch4(od->sess, uin, AIM_ICQMSG_AUTHGRANTED, &message); 1066 imcb_ask_add(data->ic, uin, NULL); 1062 if(imcb_find_buddy(data->ic, uin) == NULL) 1063 imcb_ask_add(data->ic, uin, NULL); 1067 1064 1068 1065 g_free(uin); … … 1825 1822 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 1826 1823 if (odata->icq) { 1827 /** FIXME(wilmer): Hmm, lost the ability to get away msgs here, do we care to get that back?1828 1824 struct buddy *budlight = imcb_find_buddy(g, who); 1829 1825 if (budlight) … … 1831 1827 if (budlight->caps & AIM_CAPS_ICQSERVERRELAY) 1832 1828 aim_send_im_ch2_geticqmessage(odata->sess, who, (budlight->uc & 0xff80) >> 7); 1833 */1834 1829 } else 1835 1830 aim_getinfo(odata->sess, odata->conn, who, AIM_GETINFO_AWAYMESSAGE); … … 1958 1953 static int gaim_ssi_parselist(aim_session_t *sess, aim_frame_t *fr, ...) { 1959 1954 struct im_connection *ic = sess->aux_data; 1960 struct aim_ssi_item *curitem , *curgroup;1955 struct aim_ssi_item *curitem; 1961 1956 int tmp; 1962 1957 char *nrm; … … 1969 1964 switch (curitem->type) { 1970 1965 case 0x0000: /* Buddy */ 1971 if ((curitem->name) && (!imcb_ buddy_by_handle(ic, nrm))) {1966 if ((curitem->name) && (!imcb_find_buddy(ic, nrm))) { 1972 1967 char *realname = NULL; 1973 1968 1974 1969 if (curitem->data && aim_gettlv(curitem->data, 0x0131, 1)) 1975 1970 realname = aim_gettlv_str(curitem->data, 0x0131, 1); 1976 1977 imcb_add_buddy(ic, nrm, curgroup->gid == curitem->gid ? curgroup->name :NULL);1971 1972 imcb_add_buddy(ic, nrm, NULL); 1978 1973 1979 1974 if (realname) { … … 1983 1978 } 1984 1979 } 1985 break;1986 1987 case 0x0001: /* Group */1988 curgroup = curitem;1989 1980 break; 1990 1981 … … 2529 2520 static int chat_id = 0; 2530 2521 char * chatname; 2531 struct groupchat *c;2532 2522 2533 2523 chatname = g_strdup_printf("%s%s_%d", isdigit(*ic->acc->user) ? "icq_" : "", 2534 2524 ic->acc->user, chat_id++); 2535 2536 c = imcb_chat_new(ic, chatname); 2525 2537 2526 ret = oscar_chat_join(ic, chatname, NULL, NULL); 2527 2538 2528 aim_chat_invite(od->sess, od->conn, who, "", 4, chatname, 0x0); 2539 2529 -
protocols/twitter/Makefile
r8b8def58 r38ff846 8 8 9 9 -include ../../Makefile.settings 10 ifdef SRCDIR11 SRCDIR := $(SRCDIR)protocols/twitter/12 endif13 10 14 11 # [SH] Program variables … … 36 33 $(objects): ../../Makefile.settings Makefile 37 34 38 $(objects): %.o: $(SRCDIR)%.c35 $(objects): %.o: %.c 39 36 @echo '*' Compiling $< 40 37 @$(CC) -c $(CFLAGS) $< -o $@ -
protocols/twitter/twitter_lib.c
r8b8def58 r38ff846 105 105 106 106 // Check if the buddy is allready in the buddy list. 107 if (! bee_user_by_handle( ic->bee,ic, name ))107 if (!imcb_find_buddy( ic, name )) 108 108 { 109 109 char *mode = set_getstr(&ic->acc->set, "mode"); -
protocols/yahoo/Makefile
r8b8def58 r38ff846 8 8 9 9 -include ../../Makefile.settings 10 ifdef SRCDIR11 SRCDIR := $(SRCDIR)protocols/yahoo/12 endif13 10 14 11 # [SH] Program variables … … 36 33 $(objects): ../../Makefile.settings Makefile 37 34 38 $(objects): %.o: $(SRCDIR)%.c35 $(objects): %.o: %.c 39 36 @echo '*' Compiling $< 40 37 @$(CC) -c $(CFLAGS) $< -o $@ -
protocols/yahoo/yahoo.c
r8b8def58 r38ff846 158 158 159 159 while( ic->groupchats ) 160 imcb_chat_free( ic->groupchats ->data);160 imcb_chat_free( ic->groupchats ); 161 161 162 162 for( l = yd->buddygroups; l; l = l->next ) … … 613 613 imcb_buddy_status( ic, who, flags, state_string, msg ); 614 614 615 /* Not implemented yet... 615 616 if( stat == YAHOO_STATUS_IDLE ) 616 imcb_buddy_times( ic, who, 0, idle ); 617 imcb_buddy_times( ic, who, 0, away ); 618 */ 617 619 } 618 620 … … 684 686 685 687 inp->d = d; 686 d->tag = inp->h = b_input_add( fd, B_EV_IO_READ, (b_event_handler) byahoo_read_ready_callback, (gpointer) d );688 d->tag = inp->h = b_input_add( fd, GAIM_INPUT_READ, (b_event_handler) byahoo_read_ready_callback, (gpointer) d ); 687 689 } 688 690 else if( cond == YAHOO_INPUT_WRITE ) … … 695 697 696 698 inp->d = d; 697 d->tag = inp->h = b_input_add( fd, B_EV_IO_WRITE, (b_event_handler) byahoo_write_ready_callback, (gpointer) d );699 d->tag = inp->h = b_input_add( fd, GAIM_INPUT_WRITE, (b_event_handler) byahoo_write_ready_callback, (gpointer) d ); 698 700 } 699 701 else … … 794 796 struct byahoo_conf_invitation *inv = data; 795 797 struct groupchat *b; 796 GSList *l; 797 798 for( l = inv->ic->groupchats; l; l = l->next ) 799 { 800 b = l->data; 798 799 for( b = inv->ic->groupchats; b; b = b->next ) 801 800 if( b == inv->c ) 802 801 break; 803 }804 802 805 803 if( b != NULL ) … … 867 865 { 868 866 struct im_connection *ic = byahoo_get_ic_by_id( id ); 869 struct groupchat *c = bee_chat_by_title( ic->bee, ic, room ); 867 struct groupchat *c; 868 869 for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next ); 870 870 871 871 if( c ) … … 877 877 { 878 878 struct im_connection *ic = byahoo_get_ic_by_id( id ); 879 struct groupchat *c = bee_chat_by_title( ic->bee, ic, room ); 879 struct groupchat *c; 880 881 for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next ); 880 882 881 883 if( c ) … … 887 889 struct im_connection *ic = byahoo_get_ic_by_id( id ); 888 890 char *m = byahoo_strip( msg ); 889 struct groupchat *c = bee_chat_by_title( ic->bee, ic, room ); 891 struct groupchat *c; 892 893 for( c = ic->groupchats; c && strcmp( c->title, room ) != 0; c = c->next ); 890 894 891 895 if( c ) -
query.c
r8b8def58 r38ff846 64 64 } 65 65 66 if( g_strcasecmp( set_getstr( &irc-> b->set, "query_order" ), "lifo" ) == 0 || irc->queries == q )66 if( g_strcasecmp( set_getstr( &irc->set, "query_order" ), "lifo" ) == 0 || irc->queries == q ) 67 67 query_display( irc, q ); 68 68 … … 179 179 query_t *q; 180 180 181 if( g_strcasecmp( set_getstr( &irc-> b->set, "query_order" ), "fifo" ) == 0 )181 if( g_strcasecmp( set_getstr( &irc->set, "query_order" ), "fifo" ) == 0 ) 182 182 q = irc->queries; 183 183 else -
root_commands.c
r8b8def58 r38ff846 26 26 #define BITLBEE_CORE 27 27 #include "commands.h" 28 #include "crypting.h" 28 29 #include "bitlbee.h" 29 30 #include "help.h" … … 32 33 #include <string.h> 33 34 34 void root_command_string( irc_t *irc, char *command ) 35 { 36 root_command( irc, split_command_parts( command ) ); 35 void root_command_string( irc_t *irc, user_t *u, char *command, int flags ) 36 { 37 char *cmd[IRC_MAX_ARGS]; 38 char *s; 39 int k; 40 char q = 0; 41 42 memset( cmd, 0, sizeof( cmd ) ); 43 cmd[0] = command; 44 k = 1; 45 for( s = command; *s && k < ( IRC_MAX_ARGS - 1 ); s ++ ) 46 if( *s == ' ' && !q ) 47 { 48 *s = 0; 49 while( *++s == ' ' ); 50 if( *s == '"' || *s == '\'' ) 51 { 52 q = *s; 53 s ++; 54 } 55 if( *s ) 56 { 57 cmd[k++] = s; 58 s --; 59 } 60 else 61 { 62 break; 63 } 64 } 65 else if( *s == '\\' && ( ( !q && s[1] ) || ( q && q == s[1] ) ) ) 66 { 67 char *cpy; 68 69 for( cpy = s; *cpy; cpy ++ ) 70 cpy[0] = cpy[1]; 71 } 72 else if( *s == q ) 73 { 74 q = *s = 0; 75 } 76 cmd[k] = NULL; 77 78 root_command( irc, cmd ); 37 79 } 38 80 … … 51 93 void root_command( irc_t *irc, char *cmd[] ) 52 94 { 53 int i , len;95 int i; 54 96 55 97 if( !cmd[0] ) 56 98 return; 57 99 58 len = strlen( cmd[0] );59 100 for( i = 0; commands[i].command; i++ ) 60 if( g_strncasecmp( commands[i].command, cmd[0], len ) == 0 ) 61 { 62 if( commands[i+1].command && 63 g_strncasecmp( commands[i+1].command, cmd[0], len ) == 0 ) 64 /* Only match on the first letters if the match is unique. */ 65 break; 66 101 if( g_strcasecmp( commands[i].command, cmd[0] ) == 0 ) 102 { 67 103 MIN_ARGS( commands[i].required_parameters ); 68 104 … … 105 141 static void cmd_identify( irc_t *irc, char **cmd ) 106 142 { 107 storage_status_t status ;143 storage_status_t status = storage_load( irc, cmd[1] ); 108 144 char *account_on[] = { "account", "on", NULL }; 109 gboolean load = TRUE; 110 char *password = cmd[1]; 111 112 if( irc->status & USTATUS_IDENTIFIED ) 145 146 if( strchr( irc->umode, 'R' ) != NULL ) 113 147 { 114 148 irc_usermsg( irc, "You're already logged in." ); 115 149 return; 116 150 } 117 118 if( strncmp( cmd[1], "-no", 3 ) == 0 )119 {120 load = FALSE;121 password = cmd[2];122 }123 else if( strncmp( cmd[1], "-force", 6 ) == 0 )124 {125 password = cmd[2];126 }127 else if( irc->b->accounts != NULL )128 {129 irc_usermsg( irc,130 "You're trying to identify yourself, but already have "131 "at least one IM account set up. "132 "Use \x02identify -noload\x02 or \x02identify -force\x02 "133 "instead (see \x02help identify\x02)." );134 return;135 }136 137 if( password == NULL )138 {139 MIN_ARGS( 2 );140 }141 142 if( load )143 status = storage_load( irc, password );144 else145 status = storage_check_pass( irc->user->nick, password );146 151 147 152 switch (status) { … … 153 158 break; 154 159 case STORAGE_OK: 155 irc_usermsg( irc, "Password accepted%s", 156 load ? ", settings and accounts loaded" : "" ); 157 irc_setpass( irc, password ); 160 irc_usermsg( irc, "Password accepted, settings and accounts loaded" ); 161 irc_setpass( irc, cmd[1] ); 158 162 irc->status |= USTATUS_IDENTIFIED; 159 163 irc_umode_set( irc, "+R", 1 ); 160 if( load && set_getbool( &irc->b->set, "auto_connect" ) )164 if( set_getbool( &irc->set, "auto_connect" ) ) 161 165 cmd_account( irc, account_on ); 162 166 break; … … 198 202 storage_status_t status; 199 203 200 status = storage_remove (irc-> user->nick, cmd[1]);204 status = storage_remove (irc->nick, cmd[1]); 201 205 switch (status) { 202 206 case STORAGE_NO_SUCH_USER: … … 210 214 irc->status &= ~USTATUS_IDENTIFIED; 211 215 irc_umode_set( irc, "-R", 1 ); 212 irc_usermsg( irc, "Account `%s' removed", irc-> user->nick );216 irc_usermsg( irc, "Account `%s' removed", irc->nick ); 213 217 break; 214 218 default: … … 218 222 } 219 223 220 static void cmd_save( irc_t *irc, char **cmd ) 221 { 222 if( ( irc->status & USTATUS_IDENTIFIED ) == 0 ) 223 irc_usermsg( irc, "Please create an account first" ); 224 else if( storage_save( irc, NULL, TRUE ) == STORAGE_OK ) 225 irc_usermsg( irc, "Configuration saved" ); 226 else 227 irc_usermsg( irc, "Configuration could not be saved!" ); 224 struct cmd_account_del_data 225 { 226 account_t *a; 227 irc_t *irc; 228 }; 229 230 void cmd_account_del_yes( void *data ) 231 { 232 struct cmd_account_del_data *cad = data; 233 account_t *a; 234 235 for( a = cad->irc->accounts; a && a != cad->a; a = a->next ); 236 237 if( a == NULL ) 238 { 239 irc_usermsg( cad->irc, "Account already deleted" ); 240 } 241 else if( a->ic ) 242 { 243 irc_usermsg( cad->irc, "Account is still logged in, can't delete" ); 244 } 245 else 246 { 247 account_del( cad->irc, a ); 248 irc_usermsg( cad->irc, "Account deleted" ); 249 } 250 g_free( data ); 251 } 252 253 void cmd_account_del_no( void *data ) 254 { 255 g_free( data ); 228 256 } 229 257 … … 258 286 set_name = set_full; 259 287 260 head = &irc-> b->set;288 head = &irc->set; 261 289 } 262 290 else … … 329 357 account_t *a; 330 358 331 if( ( a = account_get( irc ->b, id ) ) )359 if( ( a = account_get( irc, id ) ) ) 332 360 return &a->set; 333 361 else … … 377 405 } 378 406 379 a = account_add( irc ->b, prpl, cmd[3], cmd[4] );407 a = account_add( irc, prpl, cmd[3], cmd[4] ); 380 408 if( cmd[5] ) 381 409 { … … 391 419 MIN_ARGS( 2 ); 392 420 393 if( !( a = account_get( irc ->b, cmd[2] ) ) )421 if( !( a = account_get( irc, cmd[2] ) ) ) 394 422 { 395 423 irc_usermsg( irc, "Invalid account" ); … … 401 429 else 402 430 { 403 account_del( irc->b, a ); 404 irc_usermsg( irc, "Account deleted" ); 431 struct cmd_account_del_data *cad; 432 char *msg; 433 434 cad = g_malloc( sizeof( struct cmd_account_del_data ) ); 435 cad->a = a; 436 cad->irc = irc; 437 438 msg = g_strdup_printf( "If you remove this account (%s(%s)), BitlBee will " 439 "also forget all your saved nicknames. If you want " 440 "to change your username/password, use the `account " 441 "set' command. Are you sure you want to delete this " 442 "account?", a->prpl->name, a->user ); 443 query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, cad ); 444 g_free( msg ); 405 445 } 406 446 } … … 412 452 irc_usermsg( irc, "Account list:" ); 413 453 414 for( a = irc-> b->accounts; a; a = a->next )454 for( a = irc->accounts; a; a = a->next ) 415 455 { 416 456 char *con; … … 435 475 if( cmd[2] ) 436 476 { 437 if( ( a = account_get( irc ->b, cmd[2] ) ) )477 if( ( a = account_get( irc, cmd[2] ) ) ) 438 478 { 439 479 if( a->ic ) … … 444 484 else 445 485 { 446 account_on( irc ->b, a );486 account_on( irc, a ); 447 487 } 448 488 } … … 455 495 else 456 496 { 457 if ( irc->b->accounts ) 458 { 497 if ( irc->accounts ) { 459 498 irc_usermsg( irc, "Trying to get all accounts connected..." ); 460 499 461 for( a = irc-> b->accounts; a; a = a->next )500 for( a = irc->accounts; a; a = a->next ) 462 501 if( !a->ic && a->auto_connect ) 463 account_on( irc ->b, a );502 account_on( irc, a ); 464 503 } 465 504 else … … 475 514 irc_usermsg( irc, "Deactivating all active (re)connections..." ); 476 515 477 for( a = irc-> b->accounts; a; a = a->next )516 for( a = irc->accounts; a; a = a->next ) 478 517 { 479 518 if( a->ic ) 480 account_off( irc ->b, a );519 account_off( irc, a ); 481 520 else if( a->reconnect ) 482 521 cancel_auto_reconnect( a ); 483 522 } 484 523 } 485 else if( ( a = account_get( irc ->b, cmd[2] ) ) )524 else if( ( a = account_get( irc, cmd[2] ) ) ) 486 525 { 487 526 if( a->ic ) 488 527 { 489 account_off( irc ->b, a );528 account_off( irc, a ); 490 529 } 491 530 else if( a->reconnect ) … … 518 557 } 519 558 520 static set_t **cmd_channel_set_findhead( irc_t *irc, char *id )521 {522 irc_channel_t *ic;523 524 if( ( ic = irc_channel_get( irc, id ) ) )525 return &ic->set;526 else527 return NULL;528 }529 530 static void cmd_channel( irc_t *irc, char **cmd )531 {532 if( g_strcasecmp( cmd[1], "set" ) == 0 )533 {534 MIN_ARGS( 2 );535 536 cmd_set_real( irc, cmd + 1, cmd_channel_set_findhead, NULL );537 }538 else if( g_strcasecmp( cmd[1], "list" ) == 0 )539 {540 GSList *l;541 int i = 0;542 543 if( strchr( irc->umode, 'b' ) )544 irc_usermsg( irc, "Channel list:" );545 546 for( l = irc->channels; l; l = l->next )547 {548 irc_channel_t *ic = l->data;549 550 irc_usermsg( irc, "%2d. %s, %s channel%s", i, ic->name,551 set_getstr( &ic->set, "type" ),552 ic->flags & IRC_CHANNEL_JOINED ? " (joined)" : "" );553 554 i ++;555 }556 irc_usermsg( irc, "End of channel list" );557 }558 else if( g_strcasecmp( cmd[1], "del" ) == 0 )559 {560 irc_channel_t *ic;561 562 MIN_ARGS( 2 );563 564 if( ( ic = irc_channel_get( irc, cmd[2] ) ) &&565 !( ic->flags & IRC_CHANNEL_JOINED ) &&566 ic != ic->irc->default_channel )567 {568 irc_usermsg( irc, "Channel %s deleted.", ic->name );569 irc_channel_free( ic );570 }571 else572 irc_usermsg( irc, "Couldn't remove channel (main channel %s or "573 "channels you're still in cannot be deleted).",574 irc->default_channel->name );575 }576 else577 {578 irc_usermsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "channel", cmd[1] );579 }580 }581 582 559 static void cmd_add( irc_t *irc, char **cmd ) 583 560 { … … 592 569 } 593 570 594 if( !( a = account_get( irc ->b, cmd[1] ) ) )571 if( !( a = account_get( irc, cmd[1] ) ) ) 595 572 { 596 573 irc_usermsg( irc, "Invalid account" ); … … 610 587 return; 611 588 } 612 else if( irc_user_by_name( irc, cmd[3] ) )589 else if( user_find( irc, cmd[3] ) ) 613 590 { 614 591 irc_usermsg( irc, "The requested nick `%s' already exists", cmd[3] ); … … 622 599 623 600 if( add_on_server ) 624 a->prpl->add_buddy( a->ic, cmd[2], NULL ); 625 else 626 /* Only for add -tmp. For regular adds, this callback will 627 be called once the IM server confirms. */ 628 bee_user_new( irc->b, a->ic, cmd[2], BEE_USER_LOCAL ); 601 a->ic->acc->prpl->add_buddy( a->ic, cmd[2], NULL ); 602 else 603 /* Yeah, officially this is a call-*back*... So if we just 604 called add_buddy, we'll wait for the IM server to respond 605 before we do this. */ 606 imcb_add_buddy( a->ic, cmd[2], NULL ); 629 607 630 608 irc_usermsg( irc, "Adding `%s' to your contact list", cmd[2] ); 631 }632 633 static void cmd_remove( irc_t *irc, char **cmd )634 {635 irc_user_t *iu;636 bee_user_t *bu;637 char *s;638 639 if( !( iu = irc_user_by_name( irc, cmd[1] ) ) || !( bu = iu->bu ) )640 {641 irc_usermsg( irc, "Buddy `%s' not found", cmd[1] );642 return;643 }644 s = g_strdup( bu->handle );645 646 bu->ic->acc->prpl->remove_buddy( bu->ic, bu->handle, NULL );647 nick_del( bu->ic->acc, bu->handle );648 //TODO(wilmer): bee_user_free() and/or let the IM mod do it? irc_user_free( irc, cmd[1] );649 650 irc_usermsg( irc, "Buddy `%s' (nick %s) removed from contact list", s, cmd[1] );651 g_free( s );652 653 return;654 609 } 655 610 … … 661 616 if( !cmd[2] ) 662 617 { 663 irc_user_t *iu = irc_user_by_name( irc, cmd[1] );664 if( ! iu || !iu->bu)618 user_t *u = user_find( irc, cmd[1] ); 619 if( !u || !u->ic ) 665 620 { 666 621 irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] ); 667 622 return; 668 623 } 669 ic = iu->bu->ic;670 cmd[2] = iu->bu->handle;671 } 672 else if( !( a = account_get( irc ->b, cmd[1] ) ) )624 ic = u->ic; 625 cmd[2] = u->handle; 626 } 627 else if( !( a = account_get( irc, cmd[1] ) ) ) 673 628 { 674 629 irc_usermsg( irc, "Invalid account" ); … … 693 648 static void cmd_rename( irc_t *irc, char **cmd ) 694 649 { 695 irc_user_t *iu; 696 697 iu = irc_user_by_name( irc, cmd[1] ); 698 699 if( iu == NULL ) 650 user_t *u; 651 652 if( g_strcasecmp( cmd[1], irc->nick ) == 0 ) 653 { 654 irc_usermsg( irc, "Nick `%s' can't be changed", cmd[1] ); 655 } 656 else if( g_strcasecmp( cmd[1], irc->channel ) == 0 ) 657 { 658 if( strchr( CTYPES, cmd[2][0] ) && nick_ok( cmd[2] + 1 ) ) 659 { 660 u = user_find( irc, irc->nick ); 661 662 irc_part( irc, u, irc->channel ); 663 g_free( irc->channel ); 664 irc->channel = g_strdup( cmd[2] ); 665 irc_join( irc, u, irc->channel ); 666 667 if( strcmp( cmd[0], "set_rename" ) != 0 ) 668 set_setstr( &irc->set, "control_channel", cmd[2] ); 669 } 670 } 671 else if( user_find( irc, cmd[2] ) && ( nick_cmp( cmd[1], cmd[2] ) != 0 ) ) 672 { 673 irc_usermsg( irc, "Nick `%s' already exists", cmd[2] ); 674 } 675 else if( !nick_ok( cmd[2] ) ) 676 { 677 irc_usermsg( irc, "Nick `%s' is invalid", cmd[2] ); 678 } 679 else if( !( u = user_find( irc, cmd[1] ) ) ) 700 680 { 701 681 irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] ); 702 682 } 703 else if( iu == irc->user ) 704 { 705 irc_usermsg( irc, "Nick `%s' can't be changed", cmd[1] ); 706 } 707 else if( !nick_ok( cmd[2] ) ) 708 { 709 irc_usermsg( irc, "Nick `%s' is invalid", cmd[2] ); 710 } 711 else if( irc_user_by_name( irc, cmd[2] ) ) 712 { 713 irc_usermsg( irc, "Nick `%s' already exists", cmd[2] ); 714 } 715 else 716 { 717 if( !irc_user_set_nick( iu, cmd[2] ) ) 718 { 719 irc_usermsg( irc, "Error while changing nick" ); 720 return; 721 } 722 723 if( iu == irc->root ) 724 { 683 else 684 { 685 user_rename( irc, cmd[1], cmd[2] ); 686 irc_write( irc, ":%s!%s@%s NICK %s", cmd[1], u->user, u->host, cmd[2] ); 687 if( g_strcasecmp( cmd[1], irc->mynick ) == 0 ) 688 { 689 g_free( irc->mynick ); 690 irc->mynick = g_strdup( cmd[2] ); 691 725 692 /* If we're called internally (user did "set root_nick"), 726 693 let's not go O(INF). :-) */ 727 694 if( strcmp( cmd[0], "set_rename" ) != 0 ) 728 set_setstr( &irc-> b->set, "root_nick", cmd[2] );729 } 730 else if( iu->bu)731 { 732 nick_set( iu->bu->ic->acc, iu->bu->handle, cmd[2] );695 set_setstr( &irc->set, "root_nick", cmd[2] ); 696 } 697 else if( u->send_handler == buddy_send_handler ) 698 { 699 nick_set( u->ic->acc, u->handle, cmd[2] ); 733 700 } 734 701 … … 741 708 irc_t *irc = set->data; 742 709 743 if( strcmp( irc-> root->nick, new_nick ) != 0 )744 { 745 char *cmd[] = { "set_rename", irc-> root->nick, new_nick, NULL };710 if( strcmp( irc->mynick, new_nick ) != 0 ) 711 { 712 char *cmd[] = { "set_rename", irc->mynick, new_nick, NULL }; 746 713 747 714 cmd_rename( irc, cmd ); 748 715 } 749 716 750 return strcmp( irc->root->nick, new_nick ) == 0 ? new_nick : SET_INVALID; 717 return strcmp( irc->mynick, new_nick ) == 0 ? new_nick : SET_INVALID; 718 } 719 720 char *set_eval_control_channel( set_t *set, char *new_name ) 721 { 722 irc_t *irc = set->data; 723 724 if( strcmp( irc->channel, new_name ) != 0 ) 725 { 726 char *cmd[] = { "set_rename", irc->channel, new_name, NULL }; 727 728 cmd_rename( irc, cmd ); 729 } 730 731 return strcmp( irc->channel, new_name ) == 0 ? new_name : SET_INVALID; 732 } 733 734 static void cmd_remove( irc_t *irc, char **cmd ) 735 { 736 user_t *u; 737 char *s; 738 739 if( !( u = user_find( irc, cmd[1] ) ) || !u->ic ) 740 { 741 irc_usermsg( irc, "Buddy `%s' not found", cmd[1] ); 742 return; 743 } 744 s = g_strdup( u->handle ); 745 746 u->ic->acc->prpl->remove_buddy( u->ic, u->handle, NULL ); 747 nick_del( u->ic->acc, u->handle ); 748 user_del( irc, cmd[1] ); 749 750 irc_usermsg( irc, "Buddy `%s' (nick %s) removed from contact list", s, cmd[1] ); 751 g_free( s ); 752 753 return; 751 754 } 752 755 … … 756 759 account_t *a; 757 760 758 if( !cmd[2] && ( a = account_get( irc ->b, cmd[1] ) ) && a->ic )761 if( !cmd[2] && ( a = account_get( irc, cmd[1] ) ) && a->ic ) 759 762 { 760 763 char *format; … … 769 772 for( l = a->ic->deny; l; l = l->next ) 770 773 { 771 bee_user_t *bu = bee_user_by_handle( irc->b, a->ic, l->data ); 772 irc_user_t *iu = bu ? bu->ui_data : NULL; 773 irc_usermsg( irc, format, l->data, iu ? iu->nick : "(none)" ); 774 user_t *u = user_findhandle( a->ic, l->data ); 775 irc_usermsg( irc, format, l->data, u ? u->nick : "(none)" ); 774 776 } 775 777 irc_usermsg( irc, "End of list." ); … … 779 781 else if( !cmd[2] ) 780 782 { 781 irc_user_t *iu = irc_user_by_name( irc, cmd[1] );782 if( ! iu || !iu->bu)783 user_t *u = user_find( irc, cmd[1] ); 784 if( !u || !u->ic ) 783 785 { 784 786 irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] ); 785 787 return; 786 788 } 787 ic = iu->bu->ic;788 cmd[2] = iu->bu->handle;789 } 790 else if( !( a = account_get( irc ->b, cmd[1] ) ) )789 ic = u->ic; 790 cmd[2] = u->handle; 791 } 792 else if( !( a = account_get( irc, cmd[1] ) ) ) 791 793 { 792 794 irc_usermsg( irc, "Invalid account" ); … … 816 818 account_t *a; 817 819 818 if( !cmd[2] && ( a = account_get( irc ->b, cmd[1] ) ) && a->ic )820 if( !cmd[2] && ( a = account_get( irc, cmd[1] ) ) && a->ic ) 819 821 { 820 822 char *format; … … 829 831 for( l = a->ic->permit; l; l = l->next ) 830 832 { 831 bee_user_t *bu = bee_user_by_handle( irc->b, a->ic, l->data ); 832 irc_user_t *iu = bu ? bu->ui_data : NULL; 833 irc_usermsg( irc, format, l->data, iu ? iu->nick : "(none)" ); 833 user_t *u = user_findhandle( a->ic, l->data ); 834 irc_usermsg( irc, format, l->data, u ? u->nick : "(none)" ); 834 835 } 835 836 irc_usermsg( irc, "End of list." ); … … 839 840 else if( !cmd[2] ) 840 841 { 841 irc_user_t *iu = irc_user_by_name( irc, cmd[1] );842 if( ! iu || !iu->bu)842 user_t *u = user_find( irc, cmd[1] ); 843 if( !u || !u->ic ) 843 844 { 844 845 irc_usermsg( irc, "Nick `%s' does not exist", cmd[1] ); 845 846 return; 846 847 } 847 ic = iu->bu->ic;848 cmd[2] = iu->bu->handle;849 } 850 else if( !( a = account_get( irc ->b, cmd[1] ) ) )848 ic = u->ic; 849 cmd[2] = u->handle; 850 } 851 else if( !( a = account_get( irc, cmd[1] ) ) ) 851 852 { 852 853 irc_usermsg( irc, "Invalid account" ); … … 915 916 } 916 917 918 static void cmd_save( irc_t *irc, char **cmd ) 919 { 920 if( ( irc->status & USTATUS_IDENTIFIED ) == 0 ) 921 irc_usermsg( irc, "Please create an account first" ); 922 else if( storage_save( irc, NULL, TRUE ) == STORAGE_OK ) 923 irc_usermsg( irc, "Configuration saved" ); 924 else 925 irc_usermsg( irc, "Configuration could not be saved!" ); 926 } 927 917 928 static void cmd_blist( irc_t *irc, char **cmd ) 918 929 { 919 930 int online = 0, away = 0, offline = 0; 920 GSList *l;931 user_t *u; 921 932 char s[256]; 922 933 char *format; … … 939 950 format = "%-16.16s %-40.40s %s"; 940 951 941 irc_usermsg( irc, format, "Nick", "Handle/Account", "Status" ); 942 943 for( l = irc->users; l; l = l->next ) 944 { 945 irc_user_t *iu = l->data; 946 bee_user_t *bu = iu->bu; 947 948 if( !bu || ( bu->flags & ( BEE_USER_ONLINE | BEE_USER_AWAY ) ) != BEE_USER_ONLINE ) 949 continue; 950 952 irc_usermsg( irc, format, "Nick", "User/Host/Network", "Status" ); 953 954 for( u = irc->users; u; u = u->next ) if( u->ic && u->online && !u->away ) 955 { 951 956 if( online == 1 ) 952 957 { 953 958 char st[256] = "Online"; 954 959 955 if( bu->status_msg )956 g_snprintf( st, sizeof( st ) - 1, "Online (%s)", bu->status_msg );957 958 g_snprintf( s, sizeof( s ) - 1, "%s %s(%s)", bu->handle, bu->ic->acc->prpl->name, bu->ic->acc->user );959 irc_usermsg( irc, format, iu->nick, s, st );960 if( u->status_msg ) 961 g_snprintf( st, sizeof( st ) - 1, "Online (%s)", u->status_msg ); 962 963 g_snprintf( s, sizeof( s ) - 1, "%s@%s %s(%s)", u->user, u->host, u->ic->acc->prpl->name, u->ic->acc->user ); 964 irc_usermsg( irc, format, u->nick, s, st ); 960 965 } 961 966 … … 963 968 } 964 969 965 for( l = irc->users; l; l = l->next ) 966 { 967 irc_user_t *iu = l->data; 968 bee_user_t *bu = iu->bu; 969 970 if( !bu || !( bu->flags & BEE_USER_ONLINE ) || !( bu->flags & BEE_USER_AWAY ) ) 971 continue; 972 970 for( u = irc->users; u; u = u->next ) if( u->ic && u->online && u->away ) 971 { 973 972 if( away == 1 ) 974 973 { 975 g_snprintf( s, sizeof( s ) - 1, "%s %s(%s)", bu->handle, bu->ic->acc->prpl->name, bu->ic->acc->user );976 irc_usermsg( irc, format, iu->nick, s, irc_user_get_away( iu ));974 g_snprintf( s, sizeof( s ) - 1, "%s@%s %s(%s)", u->user, u->host, u->ic->acc->prpl->name, u->ic->acc->user ); 975 irc_usermsg( irc, format, u->nick, s, u->away ); 977 976 } 978 977 n_away ++; 979 978 } 980 979 981 for( l = irc->users; l; l = l->next ) 982 { 983 irc_user_t *iu = l->data; 984 bee_user_t *bu = iu->bu; 985 986 if( !bu || bu->flags & BEE_USER_ONLINE ) 987 continue; 988 980 for( u = irc->users; u; u = u->next ) if( u->ic && !u->online ) 981 { 989 982 if( offline == 1 ) 990 983 { 991 g_snprintf( s, sizeof( s ) - 1, "%s %s(%s)", bu->handle, bu->ic->acc->prpl->name, bu->ic->acc->user );992 irc_usermsg( irc, format, iu->nick, s, "Offline" );984 g_snprintf( s, sizeof( s ) - 1, "%s@%s %s(%s)", u->user, u->host, u->ic->acc->prpl->name, u->ic->acc->user ); 985 irc_usermsg( irc, format, u->nick, s, "Offline" ); 993 986 } 994 987 n_offline ++; … … 996 989 997 990 irc_usermsg( irc, "%d buddies (%d available, %d away, %d offline)", n_online + n_away + n_offline, n_online, n_away, n_offline ); 991 } 992 993 static void cmd_nick( irc_t *irc, char **cmd ) 994 { 995 account_t *a; 996 997 if( !cmd[1] || !( a = account_get( irc, cmd[1] ) ) ) 998 { 999 irc_usermsg( irc, "Invalid account"); 1000 } 1001 else if( !( a->ic && ( a->ic->flags & OPT_LOGGED_IN ) ) ) 1002 { 1003 irc_usermsg( irc, "That account is not on-line" ); 1004 } 1005 else if ( !cmd[2] ) 1006 { 1007 irc_usermsg( irc, "Your name is `%s'" , a->ic->displayname ? a->ic->displayname : "NULL" ); 1008 } 1009 else if ( !a->prpl->set_my_name ) 1010 { 1011 irc_usermsg( irc, "Command `%s' not supported by this protocol", cmd[0] ); 1012 } 1013 else 1014 { 1015 irc_usermsg( irc, "Setting your name to `%s'", cmd[2] ); 1016 1017 a->prpl->set_my_name( a->ic, cmd[2] ); 1018 } 998 1019 } 999 1020 … … 1018 1039 } 1019 1040 1041 static void cmd_join_chat( irc_t *irc, char **cmd ) 1042 { 1043 irc_usermsg( irc, "This command is now obsolete. " 1044 "Please try the `chat' command instead." ); 1045 } 1046 1047 static set_t **cmd_chat_set_findhead( irc_t *irc, char *id ) 1048 { 1049 struct chat *c; 1050 1051 if( ( c = chat_get( irc, id ) ) ) 1052 return &c->set; 1053 else 1054 return NULL; 1055 } 1056 1020 1057 static void cmd_chat( irc_t *irc, char **cmd ) 1021 1058 { 1022 1059 account_t *acc; 1060 struct chat *c; 1023 1061 1024 1062 if( g_strcasecmp( cmd[1], "add" ) == 0 ) 1025 1063 { 1026 1064 char *channel, *s; 1027 struct irc_channel *ic;1028 1065 1029 1066 MIN_ARGS( 3 ); 1030 1067 1031 if( !( acc = account_get( irc ->b, cmd[2] ) ) )1068 if( !( acc = account_get( irc, cmd[2] ) ) ) 1032 1069 { 1033 1070 irc_usermsg( irc, "Invalid account" ); 1034 return;1035 }1036 else if( !acc->prpl->chat_join )1037 {1038 irc_usermsg( irc, "Named chatrooms not supported on that account." );1039 1071 return; 1040 1072 } … … 1053 1085 if( strchr( CTYPES, channel[0] ) == NULL ) 1054 1086 { 1055 s = g_strdup_printf( " #%s", channel );1087 s = g_strdup_printf( "%c%s", CTYPES[0], channel ); 1056 1088 g_free( channel ); 1057 1089 channel = s; 1058 1090 } 1059 1091 1060 if( ( ic = irc_channel_new( irc, channel ) ) && 1061 set_setstr( &ic->set, "chat_type", "room" ) && 1062 set_setstr( &ic->set, "account", cmd[2] ) && 1063 set_setstr( &ic->set, "room", cmd[3] ) ) 1064 { 1065 irc_usermsg( irc, "Chatroom successfully added." ); 1066 } 1067 else 1068 { 1069 if( ic ) 1070 irc_channel_free( ic ); 1071 1092 if( ( c = chat_add( irc, acc, cmd[3], channel ) ) ) 1093 irc_usermsg( irc, "Chatroom added successfully." ); 1094 else 1072 1095 irc_usermsg( irc, "Could not add chatroom." ); 1073 }1096 1074 1097 g_free( channel ); 1075 1098 } 1099 else if( g_strcasecmp( cmd[1], "list" ) == 0 ) 1100 { 1101 int i = 0; 1102 1103 if( strchr( irc->umode, 'b' ) ) 1104 irc_usermsg( irc, "Chatroom list:" ); 1105 1106 for( c = irc->chatrooms; c; c = c->next ) 1107 { 1108 irc_usermsg( irc, "%2d. %s(%s) %s, %s", i, c->acc->prpl->name, 1109 c->acc->user, c->handle, c->channel ); 1110 1111 i ++; 1112 } 1113 irc_usermsg( irc, "End of chatroom list" ); 1114 } 1115 else if( g_strcasecmp( cmd[1], "set" ) == 0 ) 1116 { 1117 MIN_ARGS( 2 ); 1118 1119 cmd_set_real( irc, cmd + 1, cmd_chat_set_findhead, NULL ); 1120 } 1121 else if( g_strcasecmp( cmd[1], "del" ) == 0 ) 1122 { 1123 MIN_ARGS( 2 ); 1124 1125 if( ( c = chat_get( irc, cmd[2] ) ) ) 1126 { 1127 chat_del( irc, c ); 1128 } 1129 else 1130 { 1131 irc_usermsg( irc, "Could not remove chat." ); 1132 } 1133 } 1076 1134 else if( g_strcasecmp( cmd[1], "with" ) == 0 ) 1077 1135 { 1078 irc_user_t *iu;1136 user_t *u; 1079 1137 1080 1138 MIN_ARGS( 2 ); 1081 1139 1082 if( ( iu = irc_user_by_name( irc, cmd[2] ) ) && 1083 iu->bu && iu->bu->ic->acc->prpl->chat_with ) 1084 { 1085 if( !iu->bu->ic->acc->prpl->chat_with( iu->bu->ic, iu->bu->handle ) ) 1140 if( ( u = user_find( irc, cmd[2] ) ) && u->ic && u->ic->acc->prpl->chat_with ) 1141 { 1142 if( !u->ic->acc->prpl->chat_with( u->ic, u->handle ) ) 1086 1143 { 1087 1144 irc_usermsg( irc, "(Possible) failure while trying to open " 1088 "a groupchat with %s.", iu->nick );1145 "a groupchat with %s.", u->nick ); 1089 1146 } 1090 1147 } … … 1094 1151 } 1095 1152 } 1096 else if( g_strcasecmp( cmd[1], "list" ) == 0 ||1097 g_strcasecmp( cmd[1], "set" ) == 0 ||1098 g_strcasecmp( cmd[1], "del" ) == 0 )1099 {1100 irc_usermsg( irc, "Warning: The \002chat\002 command was mostly replaced with the \002channel\002 command." );1101 cmd_channel( irc, cmd );1102 }1103 1153 else 1104 1154 { … … 1107 1157 } 1108 1158 1109 static void cmd_transfer( irc_t *irc, char **cmd )1110 {1111 GSList *files = irc->file_transfers;1112 enum { LIST, REJECT, CANCEL };1113 int subcmd = LIST;1114 int fid;1115 1116 if( !files )1117 {1118 irc_usermsg( irc, "No pending transfers" );1119 return;1120 }1121 1122 if( cmd[1] && ( strcmp( cmd[1], "reject" ) == 0 ) )1123 {1124 subcmd = REJECT;1125 }1126 else if( cmd[1] && ( strcmp( cmd[1], "cancel" ) == 0 ) &&1127 cmd[2] && ( sscanf( cmd[2], "%d", &fid ) == 1 ) )1128 {1129 subcmd = CANCEL;1130 }1131 1132 for( ; files; files = g_slist_next( files ) )1133 {1134 file_transfer_t *file = files->data;1135 1136 switch( subcmd ) {1137 case LIST:1138 if ( file->status == FT_STATUS_LISTENING )1139 irc_usermsg( irc,1140 "Pending file(id %d): %s (Listening...)", file->local_id, file->file_name);1141 else1142 {1143 int kb_per_s = 0;1144 time_t diff = time( NULL ) - file->started ? : 1;1145 if ( ( file->started > 0 ) && ( file->bytes_transferred > 0 ) )1146 kb_per_s = file->bytes_transferred / 1024 / diff;1147 1148 irc_usermsg( irc,1149 "Pending file(id %d): %s (%10zd/%zd kb, %d kb/s)", file->local_id, file->file_name,1150 file->bytes_transferred/1024, file->file_size/1024, kb_per_s);1151 }1152 break;1153 case REJECT:1154 if( file->status == FT_STATUS_LISTENING )1155 {1156 irc_usermsg( irc, "Rejecting file transfer for %s", file->file_name );1157 imcb_file_canceled( file->ic, file, "Denied by user" );1158 }1159 break;1160 case CANCEL:1161 if( file->local_id == fid )1162 {1163 irc_usermsg( irc, "Canceling file transfer for %s", file->file_name );1164 imcb_file_canceled( file->ic, file, "Canceled by user" );1165 }1166 break;1167 }1168 }1169 }1170 1171 /* IMPORTANT: Keep this list sorted! The short command logic needs that. */1172 1159 const command_t commands[] = { 1160 { "help", 0, cmd_help, 0 }, 1161 { "identify", 1, cmd_identify, 0 }, 1162 { "register", 1, cmd_register, 0 }, 1163 { "drop", 1, cmd_drop, 0 }, 1173 1164 { "account", 1, cmd_account, 0 }, 1174 1165 { "add", 2, cmd_add, 0 }, 1166 { "info", 1, cmd_info, 0 }, 1167 { "rename", 2, cmd_rename, 0 }, 1168 { "remove", 1, cmd_remove, 0 }, 1169 { "block", 1, cmd_block, 0 }, 1175 1170 { "allow", 1, cmd_allow, 0 }, 1176 { "blist", 0, cmd_blist, 0 },1177 { "block", 1, cmd_block, 0 },1178 { "channel", 1, cmd_channel, 0 },1179 { "chat", 1, cmd_chat, 0 },1180 { "drop", 1, cmd_drop, 0 },1181 { "ft", 0, cmd_transfer, 0 },1182 { "help", 0, cmd_help, 0 },1183 { "identify", 1, cmd_identify, 0 },1184 { "info", 1, cmd_info, 0 },1185 { "no", 0, cmd_yesno, 0 },1186 { "qlist", 0, cmd_qlist, 0 },1187 { "register", 1, cmd_register, 0 },1188 { "remove", 1, cmd_remove, 0 },1189 { "rename", 2, cmd_rename, 0 },1190 1171 { "save", 0, cmd_save, 0 }, 1191 1172 { "set", 0, cmd_set, 0 }, 1192 { "transfer", 0, cmd_transfer, 0 },1193 1173 { "yes", 0, cmd_yesno, 0 }, 1174 { "no", 0, cmd_yesno, 0 }, 1175 { "blist", 0, cmd_blist, 0 }, 1176 { "nick", 1, cmd_nick, 0 }, 1177 { "qlist", 0, cmd_qlist, 0 }, 1178 { "join_chat", 2, cmd_join_chat, 0 }, 1179 { "chat", 1, cmd_chat, 0 }, 1194 1180 { NULL } 1195 1181 }; -
set.c
r8b8def58 r38ff846 29 29 char *SET_INVALID = "nee"; 30 30 31 set_t *set_add( set_t **head, c onst char *key, constchar *def, set_eval eval, void *data )31 set_t *set_add( set_t **head, char *key, char *def, set_eval eval, void *data ) 32 32 { 33 33 set_t *s = set_find( head, key ); … … 63 63 } 64 64 65 set_t *set_find( set_t **head, c onst char *key )65 set_t *set_find( set_t **head, char *key ) 66 66 { 67 67 set_t *s = *head; … … 69 69 while( s ) 70 70 { 71 if( g_strcasecmp( s->key, key ) == 0 || 72 ( s->old_key && g_strcasecmp( s->old_key, key ) == 0 ) ) 71 if( g_strcasecmp( s->key, key ) == 0 ) 73 72 break; 74 73 s = s->next; … … 78 77 } 79 78 80 char *set_getstr( set_t **head, c onst char *key )79 char *set_getstr( set_t **head, char *key ) 81 80 { 82 81 set_t *s = set_find( head, key ); … … 88 87 } 89 88 90 int set_getint( set_t **head, c onst char *key )89 int set_getint( set_t **head, char *key ) 91 90 { 92 91 char *s = set_getstr( head, key ); … … 102 101 } 103 102 104 int set_getbool( set_t **head, c onst char *key )103 int set_getbool( set_t **head, char *key ) 105 104 { 106 105 char *s = set_getstr( head, key ); … … 112 111 } 113 112 114 int set_setstr( set_t **head, c onst char *key, char *value )113 int set_setstr( set_t **head, char *key, char *value ) 115 114 { 116 115 set_t *s = set_find( head, key ); … … 151 150 } 152 151 153 int set_setint( set_t **head, c onst char *key, int value )152 int set_setint( set_t **head, char *key, int value ) 154 153 { 155 154 char s[24]; /* Not quite 128-bit clean eh? ;-) */ … … 159 158 } 160 159 161 void set_del( set_t **head, c onst char *key )160 void set_del( set_t **head, char *key ) 162 161 { 163 162 set_t *s = *head, *t = NULL; … … 177 176 178 177 g_free( s->key ); 179 g_free( s->old_key ); 180 g_free( s->value ); 181 g_free( s->def ); 178 if( s->value ) g_free( s->value ); 179 if( s->def ) g_free( s->def ); 182 180 g_free( s ); 183 181 } 184 182 } 185 183 186 int set_reset( set_t **head, c onst char *key )184 int set_reset( set_t **head, char *key ) 187 185 { 188 186 set_t *s; … … 213 211 { 214 212 return is_bool( value ) ? value : SET_INVALID; 215 }216 217 char *set_eval_list( set_t *set, char *value )218 {219 GSList *options = set->eval_data, *opt;220 221 for( opt = options; opt; opt = opt->next )222 if( strcmp( value, opt->data ) == 0 )223 return value;224 225 /* TODO: It'd be nice to show the user a list of allowed values,226 but we don't have enough context here to do that. May227 want to fix that. */228 229 return NULL;230 213 } 231 214 … … 242 225 } 243 226 244 /*245 227 char *set_eval_ops( set_t *set, char *value ) 246 228 { … … 264 246 return value; 265 247 } 266 */ -
set.h
r8b8def58 r38ff846 54 54 55 55 char *key; 56 char *old_key; /* Previously known as; for smooth upgrades. */57 56 char *value; 58 57 char *def; /* Default value. If the set_setstr() function … … 70 69 set_setstr() should be able to free() the returned string! */ 71 70 set_eval eval; 72 void *eval_data;73 71 struct set *next; 74 72 } set_t; 75 73 76 74 /* Should be pretty clear. */ 77 set_t *set_add( set_t **head, c onst char *key, constchar *def, set_eval eval, void *data );75 set_t *set_add( set_t **head, char *key, char *def, set_eval eval, void *data ); 78 76 79 77 /* Returns the raw set_t. Might be useful sometimes. */ 80 set_t *set_find( set_t **head, c onst char *key );78 set_t *set_find( set_t **head, char *key ); 81 79 82 80 /* Returns a pointer to the string value of this setting. Don't modify the 83 81 returned string, and don't free() it! */ 84 G_MODULE_EXPORT char *set_getstr( set_t **head, c onst char *key );82 G_MODULE_EXPORT char *set_getstr( set_t **head, char *key ); 85 83 86 84 /* Get an integer. In previous versions set_getint() was also used to read 87 85 boolean values, but this SHOULD be done with set_getbool() now! */ 88 G_MODULE_EXPORT int set_getint( set_t **head, c onst char *key );89 G_MODULE_EXPORT int set_getbool( set_t **head, c onst char *key );86 G_MODULE_EXPORT int set_getint( set_t **head, char *key ); 87 G_MODULE_EXPORT int set_getbool( set_t **head, char *key ); 90 88 91 89 /* set_setstr() strdup()s the given value, so after using this function 92 90 you can free() it, if you want. */ 93 int set_setstr( set_t **head, c onst char *key, char *value );94 int set_setint( set_t **head, c onst char *key, int value );95 void set_del( set_t **head, c onst char *key );96 int set_reset( set_t **head, c onst char *key );91 int set_setstr( set_t **head, char *key, char *value ); 92 int set_setint( set_t **head, char *key, int value ); 93 void set_del( set_t **head, char *key ); 94 int set_reset( set_t **head, char *key ); 97 95 98 96 /* Two very useful generic evaluators. */ 99 97 char *set_eval_int( set_t *set, char *value ); 100 98 char *set_eval_bool( set_t *set, char *value ); 101 102 /* Another more complicated one. */103 char *set_eval_list( set_t *set, char *value );104 99 105 100 /* Some not very generic evaluators that really shouldn't be here... */ -
storage.c
r8b8def58 r38ff846 28 28 #define BITLBEE_CORE 29 29 #include "bitlbee.h" 30 #include "crypting.h" 30 31 31 32 extern storage_t storage_text; … … 65 66 storage_t *storage; 66 67 68 register_storage_backend(&storage_text); 67 69 register_storage_backend(&storage_xml); 68 70 -
storage_xml.c
r8b8def58 r38ff846 147 147 arc_decode( pass_cr, pass_len, &password, xd->given_pass ) ) 148 148 { 149 xd->current_account = account_add( irc ->b, prpl, handle, password );149 xd->current_account = account_add( irc, prpl, handle, password ); 150 150 if( server ) 151 151 set_setstr( &xd->current_account->set, "server", server ); … … 181 181 xd->current_set_head = &xd->current_account->set; 182 182 else 183 xd->current_set_head = &xd->irc-> b->set;183 xd->current_set_head = &xd->irc->set; 184 184 185 185 xd->current_setting = g_strdup( setting ); … … 215 215 if( xd->current_account && handle && channel ) 216 216 { 217 //xd->current_chat = chat_add( xd->irc, xd->current_account, handle, channel );217 xd->current_chat = chat_add( xd->irc, xd->current_account, handle, channel ); 218 218 } 219 219 else … … 353 353 static storage_status_t xml_load( irc_t *irc, const char *password ) 354 354 { 355 return xml_load_real( irc, irc-> user->nick, password, XML_PASS_UNKNOWN );355 return xml_load_real( irc, irc->nick, password, XML_PASS_UNKNOWN ); 356 356 } 357 357 … … 396 396 md5_state_t md5_state; 397 397 398 path2 = g_strdup( irc-> user->nick );398 path2 = g_strdup( irc->nick ); 399 399 nick_lc( path2 ); 400 400 g_snprintf( path, sizeof( path ) - 2, "%s%s%s", global.conf->configdir, path2, ".xml" ); … … 422 422 pass_buf = base64_encode( pass_md5, 21 ); 423 423 424 if( !xml_printf( fd, 0, "<user nick=\"%s\" password=\"%s\" version=\"%d\">\n", irc-> user->nick, pass_buf, XML_FORMAT_VERSION ) )424 if( !xml_printf( fd, 0, "<user nick=\"%s\" password=\"%s\" version=\"%d\">\n", irc->nick, pass_buf, XML_FORMAT_VERSION ) ) 425 425 goto write_error; 426 426 427 427 g_free( pass_buf ); 428 428 429 for( set = irc-> b->set; set; set = set->next )429 for( set = irc->set; set; set = set->next ) 430 430 if( set->value ) 431 431 if( !xml_printf( fd, 1, "<setting name=\"%s\">%s</setting>\n", set->key, set->value ) ) 432 432 goto write_error; 433 433 434 for( acc = irc-> b->accounts; acc; acc = acc->next )434 for( acc = irc->accounts; acc; acc = acc->next ) 435 435 { 436 436 unsigned char *pass_cr; … … 470 470 goto write_error; 471 471 472 #if 0473 472 for( c = irc->chatrooms; c; c = c->next ) 474 473 { … … 489 488 goto write_error; 490 489 } 491 #endif492 490 493 491 if( !xml_printf( fd, 1, "</account>\n" ) ) -
tests/Makefile
r8b8def58 r38ff846 1 1 -include ../Makefile.settings 2 ifdef SRCDIR3 SRCDIR := $(SRCDIR)tests/4 endif5 2 6 3 LFLAGS +=-lcheck … … 22 19 @$(CC) $(CFLAGS) -o $@ $^ $(LFLAGS) $(EFLAGS) 23 20 24 %.o: $(SRCDIR)%.c21 %.o: %.c 25 22 @echo '*' Compiling $< 26 23 @$(CC) -c $(CFLAGS) $< -o $@ -
unix.c
r8b8def58 r38ff846 56 56 57 57 log_init(); 58 59 58 global.conf_file = g_strdup( CONF_FILE_DEF ); 60 59 global.conf = conf_load( argc, argv ); … … 63 62 64 63 b_main_init(); 64 nogaim_init(); 65 65 66 66 srand( time( NULL ) ^ getpid() ); 67 68 67 global.helpfile = g_strdup( HELP_FILE ); 69 if( help_init( &global.help, global.helpfile ) == NULL )70 log_message( LOGLVL_WARNING, "Error opening helpfile %s.", HELP_FILE );71 72 global.storage = storage_init( global.conf->primary_storage, global.conf->migrate_storage );73 if( global.storage == NULL )74 {75 log_message( LOGLVL_ERROR, "Unable to load storage backend '%s'", global.conf->primary_storage );76 return( 1 );77 }78 68 79 69 if( global.conf->runmode == RUNMODE_INETD ) … … 126 116 setuid( pw->pw_uid ); 127 117 } 118 } 119 120 global.storage = storage_init( global.conf->primary_storage, global.conf->migrate_storage ); 121 if( global.storage == NULL ) 122 { 123 log_message( LOGLVL_ERROR, "Unable to load storage backend '%s'", global.conf->primary_storage ); 124 return( 1 ); 128 125 } 129 126 … … 145 142 if( !getuid() || !geteuid() ) 146 143 log_message( LOGLVL_WARNING, "BitlBee is running with root privileges. Why?" ); 144 if( help_init( &global.help, global.helpfile ) == NULL ) 145 log_message( LOGLVL_WARNING, "Error opening helpfile %s.", HELP_FILE ); 147 146 148 147 b_main_run(); -
win32.c
r8b8def58 r38ff846 27 27 #include "bitlbee.h" 28 28 #include "commands.h" 29 #include "crypting.h" 29 30 #include "protocols/nogaim.h" 30 31 #include "help.h"
Note: See TracChangeset
for help on using the changeset viewer.