Changeset b79308b
- Timestamp:
- 2008-04-14T13:10:53Z (17 years ago)
- Branches:
- master
- Children:
- 0cab388
- Parents:
- 6cac643 (diff), aa31117 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 3 added
- 70 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
Makefile
r6cac643 rb79308b 50 50 $(MAKE) -C tests 51 51 52 lcov:53 52 gcov: check 54 53 gcov *.c -
account.c
r6cac643 rb79308b 182 182 account_t *a, *l = NULL; 183 183 184 if( acc->ic ) 185 /* Caller should have checked, accounts still in use can't be deleted. */ 186 return; 187 184 188 for( a = irc->accounts; a; a = (l=a)->next ) 185 189 if( a == acc ) 186 190 { 187 if( a->ic ) return; /* Caller should have checked, accounts still in use can't be deleted. */188 189 191 if( l ) 190 {191 192 l->next = a->next; 192 }193 193 else 194 {195 194 irc->accounts = a->next; 196 }197 195 198 196 while( a->set ) … … 203 201 g_free( a->user ); 204 202 g_free( a->pass ); 205 if( a->server )g_free( a->server );203 g_free( a->server ); 206 204 if( a->reconnect ) /* This prevents any reconnect still queued to happen */ 207 205 cancel_auto_reconnect( a ); -
bitlbee.c
r6cac643 rb79308b 226 226 if( st == size ) 227 227 { 228 g_free( irc->sendbuffer );229 irc->sendbuffer = NULL;230 irc->w_watch_source_id = 0;231 232 228 if( irc->status & USTATUS_SHUTDOWN ) 229 { 233 230 irc_free( irc ); 231 } 232 else 233 { 234 g_free( irc->sendbuffer ); 235 irc->sendbuffer = NULL; 236 irc->w_watch_source_id = 0; 237 } 234 238 235 239 return FALSE; -
bitlbee.conf
r6cac643 rb79308b 49 49 ## 50 50 ## Password the user should enter when logging into a closed BitlBee server. 51 ## You can also have an MD5-encrypted password here. Format: "md5:", followed 52 ## by a hash as generated for the <user password=""> attribute in a BitlBee 53 ## XML file (for now there's no easier way to generate the hash). 51 54 ## 52 55 # AuthPassword = ItllBeBitlBee ## Heh.. Our slogan. ;-) 56 ## or 57 # AuthPassword = md5:gzkK0Ox/1xh+1XTsQjXxBJ571Vgl 53 58 54 59 ## OperPassword … … 57 62 ## 58 63 # OperPassword = ChangeMe! 64 ## or 65 # OperPassword = md5:I0mnZbn1t4R731zzRdDN2/pK7lRX 59 66 60 67 ## HostName -
bitlbee.h
r6cac643 rb79308b 30 30 31 31 #define PACKAGE "BitlBee" 32 #define BITLBEE_VERSION "1. 1.1dev"32 #define BITLBEE_VERSION "1.2" 33 33 #define VERSION BITLBEE_VERSION 34 34 35 #define MAX_STRING 12835 #define MAX_STRING 511 36 36 37 37 #if HAVE_CONFIG_H … … 160 160 gboolean bitlbee_shutdown( gpointer data, gint fd, b_input_condition cond ); 161 161 162 char *set_eval_root_nick( set_t *set, char *new_nick ); 163 162 164 extern global_t global; 163 165 -
conf.c
r6cac643 rb79308b 253 253 { 254 254 g_strfreev( conf->migrate_storage ); 255 conf->migrate_storage = g_strsplit ( ini->value, " \t,;", -1 );255 conf->migrate_storage = g_strsplit_set( ini->value, " \t,;", -1 ); 256 256 } 257 257 else if( g_strcasecmp( ini->key, "pinginterval" ) == 0 ) -
debian/README.Debian
r6cac643 rb79308b 1 *** NEWS (Version 1. 1and later) ***1 *** NEWS (Version 1.2 and later) *** 2 2 3 Starting from version 1. 1, BitlBee has a forking daemon mode. The Debian3 Starting from version 1.2, BitlBee has a forking daemon mode. The Debian 4 4 package now uses this mode by default, instead of inetd mode. If you don't 5 5 want to use this, you can disable the init scripts (best way to do this is … … 7 7 should be necessary only once, it won't be touched during upgrades. 8 8 9 -------------------------------------------------------------------------- 9 Another important change in BitlBee 1.2 is the file format used for your 10 personal settings. Everything's now saved in a single .xml (per account, 11 of course) file instead of $nick.accounts and $nick.nicks. One advantage 12 of this new format is that the passwords are actually encrypted instead of 13 just vaguely obfuscated. BitlBee can still read the old files, and will 14 save things in the new format when you save/disconnect. After that, you 15 can safely remove the old-style files (this is recommended). 16 17 I tried making this transition (the new file format but especially, in this 18 case, the inetd->forkdaemon mode change) as smooth as possible, but I'm 19 aware that many BitlBee users will have their own hacks already to run the 20 program. I hope the package won't break any of this for anyone. 1.2-2 21 should fix at least some of the issues. 22 23 --------------------------------------------------------------------------- 10 24 11 25 Debconf should have asked you on what port you want BitlBee to run. If it -
debian/bitlbee.init
r6cac643 rb79308b 1 1 #! /bin/sh 2 ### BEGIN INIT INFO 3 # Provides: bitlbee 4 # Required-Start: $remote_fs $syslog 5 # Required-Stop: $remote_fs $syslog 6 # Default-Start: 2 3 4 5 7 # Default-Stop: 1 8 ### END INIT INFO 2 9 # 3 10 # Init script for BitlBee Debian package. Based on skeleton init script: … … 18 25 # Default value 19 26 BITLBEE_PORT=6667 20 DAEMON_OPT=-F27 BITLBEE_OPTS=-F 21 28 22 29 # Read config file if it is present. … … 37 44 38 45 start-stop-daemon --start --quiet --pidfile $PIDFILE \ 39 -c bitlbee -g nogroup\40 --exec $DAEMON -- -p $BITLBEE_PORT -P $PIDFILE $ DAEMON_OPT46 -c bitlbee: \ 47 --exec $DAEMON -- -p $BITLBEE_PORT -P $PIDFILE $BITLBEE_OPTS 41 48 } 42 49 -
debian/changelog
r6cac643 rb79308b 1 bitlbee (1.1.1dev-0pre) unstable; urgency=low 2 1 bitlbee (1.2-4) unstable; urgency=low 2 3 * Not a real release, just a placeholder for the changelog. 4 * Fixed init script to use the BITLBEE_OPTS variable, not an undefined 5 DAEMON_OPT. 6 * Added dependency information to the init script. (Closes: #472567) 7 8 -- Wilmer van der Gaast <wilmer@gaast.net> Sat, 29 Mar 2008 21:10:33 +0000 9 10 bitlbee (1.2-3) unstable; urgency=low 11 12 * Removed DEB_BUILD_OPTIONS again (forgot to apply that change to the 1.2 13 branch when I finished 1.0.4-2, things diverged too much anyway.) 14 Closes: #472540. 15 16 -- Wilmer van der Gaast <wilmer@gaast.net> Mon, 24 Mar 2008 21:10:14 +0000 17 18 bitlbee (1.2-2) unstable; urgency=low 19 20 * Fixed some packaging issues reported by IRC and e-mail. (Closes: #472373) 21 * Fixed proxy support. (Closes: #472395) 22 * Added a BitlBee group so only root can edit the configs and BitlBee can 23 just *read* it. 24 * Manually deleting /var/lib/bitlbee/ when purging, deluser doesn't want to 25 do it. 26 27 -- Wilmer van der Gaast <wilmer@gaast.net> Mon, 24 Mar 2008 19:48:24 +0000 28 29 bitlbee (1.2-1) unstable; urgency=low 30 31 * New upstream release. (Closes: #325017, #386914, #437515) 32 * With hopefully completely sane charset handling (Closes: #296145) 3 33 * Switched to the new forking daemon mode. Added /etc/default/bitlbee 4 34 file, an init script. People who want to stick with inetd can do so, see 5 35 the defaults file. 36 (Closes: #460741, #466171, #294585, #345038, #306452, #392682) 6 37 * Got rid of debconf Woody compatibility stuff. 7 38 * No more MPL code in BitlBee, thanks to the Jabber module rewrite! 8 9 -- Wilmer van der Gaast <wilmer@gaast.net> Fri, 06 Jul 2007 09:09:36 +0100 39 * Added Italian translation, sorry for taking so long! (Closes: #448238) 40 * Added libevent dependency (more reliable event handling). 41 * Removed GLib 1.x dependency because BitlBee really requires GLib >=2.4. 42 43 -- Wilmer van der Gaast <wilmer@gaast.net> Tue, 18 Mar 2008 23:44:19 +0000 44 45 bitlbee (1.0.4-2) unstable; urgency=low 46 47 * Removed $DEB_BUILD_OPTIONS because apparently buildds fill it with crap. 48 (Closes: #458717) 49 50 -- Wilmer van der Gaast <wilmer@gaast.net> Mon, 11 Feb 2008 19:15:33 +0000 51 52 bitlbee (1.0.4-1) unstable; urgency=low 53 54 * New upstream release. 55 * Changed libnss-dev dependency. (Closes: #370442) 56 * Added build-indep rule to debian/rules. (Closes: #395673) 57 58 -- Wilmer van der Gaast <wilmer@gaast.net> Wed, 29 Aug 2007 20:24:28 +0100 10 59 11 60 bitlbee (1.0.3-1.3) unstable; urgency=low -
debian/conffiles
r6cac643 rb79308b 1 1 /etc/bitlbee/motd.txt 2 2 /etc/bitlbee/bitlbee.conf 3 /etc/init.d/bitlbee -
debian/control
r6cac643 rb79308b 4 4 Maintainer: Wilmer van der Gaast <wilmer@gaast.net> 5 5 Standards-Version: 3.5.9 6 Build-Depends: libglib2.0-dev | libglib-dev, libgnutls-dev | libnss-dev (>= 1.6), debconf-2.0, po-debconf6 Build-Depends: libglib2.0-dev (>= 2.4), libevent-dev, libgnutls-dev | libnss-dev (>= 1.6), debconf-2.0, po-debconf 7 7 8 8 Package: bitlbee -
debian/postinst
r6cac643 rb79308b 14 14 BITLBEE_DISABLED=0 15 15 BITLBEE_UPGRADE_DONT_RESTART=0 16 [ -r /etc/default/bitlbee ] && source/etc/default/bitlbee16 [ -r /etc/default/bitlbee ] && . /etc/default/bitlbee 17 17 18 if [ "$BITLBEE_DISABLED" = "0" ]; then 19 ## In case it's still there (if we're upgrading right now) 18 if [ "$BITLBEE_DISABLED" = "0" ] && type update-inetd > /dev/null 2> /dev/null && 19 ( expr "$2" : '0\..*' > /dev/null || expr "$2" : '1\.0\..*' > /dev/null ); then 20 ## Make sure the inetd entry is gone (can still be there from a 21 ## previous version. 20 22 update-inetd --remove '.*/usr/sbin/bitlbee' 23 if grep -q /usr/sbin/bitlbee /etc/inetd.conf 2> /dev/null; then 24 # Thanks for breaking update-inetd! (bugs.debian.org/311111) 25 # I hope that it works at least with xinetd, because this 26 # emergency hack doesn't: 27 perl -pi -e 's:^[^#].*/usr/sbin/bitlbee$:## Now using daemon mode\: # $&:' /etc/inetd.conf 28 killall -HUP inetd || true 29 fi 21 30 fi 22 31 … … 65 74 fi 66 75 67 adduser --system -- home /var/lib/bitlbee/ --disabled-login --disabled-passwordbitlbee76 adduser --system --group --disabled-login --disabled-password --home /var/lib/bitlbee/ bitlbee 68 77 chmod 700 /var/lib/bitlbee/ 69 78 70 79 ## Can't do this in packaging phase: Don't know the UID yet. Access to 71 ## the file should be limited, now that it stores passwords. 72 chmod 600 /etc/bitlbee/bitlbee.conf 73 chown bitlbee /etc/bitlbee/bitlbee.conf 80 ## the file should be limited, now that it stores passwords. Added 81 ## --group later for a little more security, but have to see if I can 82 ## apply this change to existing installations on upgrades. Will think 83 ## about that later. 84 if getent group bitlbee > /dev/null; then 85 chmod 640 /etc/bitlbee/bitlbee.conf 86 chown root:bitlbee /etc/bitlbee/bitlbee.conf 87 else 88 chmod 600 /etc/bitlbee/bitlbee.conf 89 chown bitlbee /etc/bitlbee/bitlbee.conf 90 fi 74 91 75 92 if [ -z "$2" ]; then -
debian/postrm
r6cac643 rb79308b 9 9 10 10 update-rc.d bitlbee remove > /dev/null 2>&1 || true 11 deluser --remove-home bitlbee || true 11 rm -f /etc/default/bitlbee 12 13 deluser --system --remove-home bitlbee || true 14 rm -rf /var/lib/bitlbee ## deluser doesn't seem to do this for homedirs in /var -
debian/rules
r6cac643 rb79308b 3 3 DEBUG ?= 0 4 4 5 ifdef BITLBEE_VERSION 6 BITLBEE_FORCE_VERSION=1 7 else 5 8 # Want to use the full package version number instead of just the release. 6 9 BITLBEE_VERSION ?= "$(shell dpkg-parsechangelog | grep ^Version: | awk '{print $$2}')" 7 10 export BITLBEE_VERSION 8 11 endif 9 12 10 13 build-arch: build-arch-stamp 11 14 build-arch-stamp: 12 15 if [ ! -d debian ]; then exit 1; fi 13 ./configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee $(DEB_BUILD_OPTIONS)16 ./configure --debug=$(DEBUG) --prefix=/usr --etcdir=/etc/bitlbee --events=libevent 14 17 $(MAKE) 15 18 # $(MAKE) -C doc/ all … … 66 69 find usr -type f -exec md5sum {} \; > DEBIAN/md5sums 67 70 dpkg-shlibdeps -Tdebian/bitlbee.substvars -dDepends debian/bitlbee/usr/sbin/bitlbee 68 ifdef BITLBEE_ VERSION71 ifdef BITLBEE_FORCE_VERSION 69 72 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' 70 73 else -
doc/CHANGES
r6cac643 rb79308b 1 Version 1.2.1: 2 - Fixed proxy support. 3 - Fixed stalling issues while connecting to Jabber when using the OpenSSL 4 module. 5 - Fixed problem with GLib and ForkDaemon where processes didn't die when 6 the client disconnects. 7 - Fixed handling of "set charset none". (Which pretty much breaks the account 8 completely in 1.2.) 9 - You can now automatically identify yourself to BitlBee by setting a server 10 password in your IRC client. 11 - Compatible with all crazy kinds of line endings that clients can send. 12 13 Finished ... 14 1 15 Version 1.2: 2 - First BitlBee development/testing RELEASE. This should be quite stable3 though (and for most people more stable than 1.0.x). It just has a couple4 of rough edges and needs a bit more testing.5 16 - Added ForkDaemon mode next to the existing Daemon- and inetd modes. With 6 17 ForkDaemon you can run BitlBee as a stand-alone daemon and every connection … … 21 32 1.x is so old that supporting it really isn't necessary anymore. 22 33 - Many, many, MANY little changes, improvements, fixes. Using non-blocking 23 I/O as much as possible, fixed lots of little bugs (including bugs that 24 affected daemon mode stability). See the bzr logs for more information. 25 - Added units tests, will have to add some more before the real release. 34 I/O as much as possible, replaced the Gaim (0.59, IOW heavily outdated) 35 API, fixed lots of little bugs (including bugs that affected daemon mode 36 stability). See the bzr logs for more information. 37 - One of the user-visible changes from the API change: You can finally see 38 all away states/messages properly. 39 - Added units tests. Test coverage is very minimal for now. 40 - Better charset handling: Everything is just converted from/to UTF-8 right 41 in the IRC core, and charset mismatches are detected (if possible) and the 42 user is asked to resolve this before continuing. Also, UTF-8 is the default 43 setting now, since that's how the world seems to work these days. 44 - One can now keep hashed passwords in bitlbee.conf instead of the cleartext 45 version. 26 46 - Most important change: New file format for user data (accounts, nicks and 27 47 settings). Migration to the new format should happen transparently, … … 69 89 * An XML console (add xmlconsole to your contact list or see "help set 70 90 xmlconsole" if you want it permanently). 71 72 Finished ??? 91 - The Yahoo! module now says it supports YMSG protocol version 12, which will 92 hopefully keep the Yahoo module working after 2008-04-02 (when Yahoo! is 93 dropping support for version 6.x of their client). 94 - MSN switchboard handling changes. Hopefully less messages will get lost now, 95 although things are still not perfect. 96 97 Finished 17 Mar 2008 73 98 74 99 Version 1.0.4: -
doc/README
r6cac643 rb79308b 41 41 by default) and chown it to the UID BitlBee is running as. Make sure this 42 42 directory is read-/writable by this user only. 43 44 --- (Fork)Daemon mode 45 46 If you don't want to run any inetd daemon, you can run BitlBee in Daemon 47 mode. Right now, daemon mode may be a bad idea on servers with multiple 48 users, since possible fatal BitlBee bugs will crash the BitlBee process and 49 disconnect all connected users at once. Instead, you can use ForkDaemon 50 mode, which serves every user from a separate process, without depending on 51 an inetd daemon. 52 53 To use BitlBee in daemon mode, just start it with the right flags or enable 54 it in bitlbee.conf. You probably want to write an init script to start 55 BitlBee automatically after a reboot. (This is where you realise using 56 a package from your distro would've been a better idea. :-P) 43 57 44 58 -
doc/user-guide/Support.xml
r6cac643 rb79308b 4 4 5 5 <sect1> 6 <title> BitlBee is beta software</title>6 <title>Disclaimer</title> 7 7 8 8 <para> 9 Although BitlBee has quite some functionality it is still beta. That means it 10 can crash at any time, corrupt your data or whatever. Don't use it in 11 any production environment and don't rely on it. 9 BitlBee doesn't come with a warranty and is still (and will probably always 10 be) under development. That means it can crash at any time, corrupt your 11 data or whatever. Don't use it in any production environment and don't rely 12 on it, or at least don't blame us if things blow up. :-) 12 13 </para> 13 14 -
doc/user-guide/commands.xml
r6cac643 rb79308b 163 163 164 164 <para> 165 If you want, you can also tell BitlBee what nick to give the new contact. Of course you can also use the <emphasis>rename</emphasis> command for that, but sometimes this might be more convenient. 166 </para> 167 168 <para> 169 Adding -tmp adds the buddy to the internal BitlBee structures only, not to the real contact list (like done by <emphasis>set handle_unknown add</emphasis>). This allows you to talk to people who are not in your contact list. 165 If you want, you can also tell BitlBee what nick to give the new contact. The -tmp option adds the buddy to the internal BitlBee structures only, not to the real contact list (like done by <emphasis>set handle_unknown add</emphasis>). This allows you to talk to people who are not in your contact list. This normally won't show you any presence notifications. 170 166 </para> 171 167 </description> … … 383 379 384 380 <bitlbee-setting name="charset" type="string" scope="global"> 385 <default> iso8859-1</default>381 <default>utf-8</default> 386 382 <possible-values>you can get a list of all possible values by doing 'iconv -l' in a shell</possible-values> 387 383 388 384 <description> 389 385 <para> 390 Th e charset setting enables you to use different character sets in BitlBee. These get converted to UTF-8 before sending and from UTF-8 when receiving.391 </para> 392 393 <para> 394 If you don't know what's the best value for this, at least iso8859-1 is the best choice for most Western countries. You can try to find what works best for you on http://czyborra.com/charsets/iso8859.html386 This setting tells BitlBee what your IRC client sends and expects. It should be equal to the charset setting of your IRC client if you want to be able to send and receive non-ASCII text properly. 387 </para> 388 389 <para> 390 Most systems use UTF-8 these days. On older systems, an iso8859 charset may work better. For example, iso8859-1 is the best choice for most Western countries. You can try to find what works best for you on http://www.unicodecharacter.com/charsets/iso8859.html 395 391 </para> 396 392 </description> … … 593 589 </bitlbee-setting> 594 590 591 <bitlbee-setting name="root_nick" type="string" scope="global"> 592 <default>root</default> 593 594 <description> 595 <para> 596 Normally the "bot" that takes all your BitlBee commands is called "root". If you don't like this name, you can rename it to anything else using the <emphasis>rename</emphasis> command, or by changing this setting. 597 </para> 598 </description> 599 </bitlbee-setting> 600 595 601 <bitlbee-setting name="save_on_quit" type="boolean" scope="global"> 596 602 <default>true</default> … … 677 683 <description> 678 684 <para> 679 Sends you a /notice when a user starts typing a message (if the protocol supports it, MSN for example). This is a bug, not a feature. (But please don't report it.. ;-) You don't want to use it. Really. In fact the typing-notification is just one of the least useful 'innovations' ever. It's just there because some guy will probably ask me about it anyway. ;-)685 Sends you a /notice when a user starts typing a message (if supported by the IM protocol and the user's client). To use this, you most likely want to use a script in your IRC client to show this information in a more sensible way. 680 686 </para> 681 687 </description> … … 830 836 <short-description>Change friendly name, nick</short-description> 831 837 <syntax>nick <connection> [<new nick>]</syntax> 832 <syntax>nick</syntax> 833 834 <description> 835 <para> 836 This command allows to set the friendly name of an im account. If no new name is specified the command will report the current name. When the name contains spaces, don't forget to quote the whole nick in double quotes. Currently this command is only supported by the MSN protocol. 837 </para> 838 839 <para> 840 It is recommended to use the per-account <emphasis>display_name</emphasis> setting to read and change this information. The <emphasis>nick</emphasis> command is deprecated. 838 <syntax>nick <connection></syntax> 839 840 <description> 841 <para> 842 Deprecated: Use the per-account <emphasis>display_name</emphasis> setting to read and change this information. 841 843 </para> 842 844 </description> 843 845 844 846 <ircexample> 845 <ircline nick="wouter"> nick 1 "Wouter Paesen"</ircline>846 <ircline nick="root"> Setting your name on connection 1 to `Wouter Paesen'</ircline>847 <ircline nick="wouter">account set 1/display_name "The majestik møøse"</ircline> 848 <ircline nick="root">display_name = `The majestik møøse'</ircline> 847 849 </ircexample> 848 850 -
doc/user-guide/misc.xml
r6cac643 rb79308b 47 47 </variablelist> 48 48 49 <para>50 This list was extracted from <ulink url="http://help.msn.com/!data/en_us/data/messengerv50.its51/$content$/EMOTICONS.HTM?H_APP=">http://help.msn.com/!data/en_us/data/messengerv50.its51/$content$/EMOTICONS.HTM?H_APP=</ulink>.51 </para>52 53 49 </sect1> 54 50 … … 56 52 <title>Groupchats</title> 57 53 <para> 58 Since version 0.8x, BitlBee supports groupchats on the MSN and Yahoo!networks. This text will try to explain you how they work.54 BitlBee now supports groupchats on all IM networks. This text will try to explain you how they work. 59 55 </para> 60 56 … … 73 69 74 70 <para> 75 If you want to start a groupchat with the person <emphasis> jim_msn</emphasis> in it, just join the channel <emphasis>#jim_msn</emphasis>. BitlBee will refuse to join you to the channel with that name, but it will create a new virtual channel with root, you and jim_msn in it.71 If you want to start a groupchat with the person <emphasis>lisa_msn</emphasis> in it, just join the channel <emphasis>#lisa_msn</emphasis>. BitlBee will refuse to join you to the channel with that name, but it will create a new virtual channel with root, you and lisa_msn in it. 76 72 </para> 77 73 … … 82 78 <para> 83 79 Some protocols (like Jabber) also support named groupchats. BitlBee now supports these too. You can use the <emphasis>join_chat</emphasis> command to join them. See <emphasis>help join_chat</emphasis> for more information. 84 </para>85 86 <para>87 This is all you'll probably need to know. If you have any problems, please read <emphasis>help groupchats3</emphasis>.88 </para>89 90 </sect1>91 92 <sect1 id="groupchats3">93 <title>Groupchat channel names</title>94 95 <para>96 Obviously the (numbered) channel names don't make a lot of sense. Problem is that groupchats usually don't have names at all in the IM-world, while IRC insists on a name. So BitlBee just generates something random, just don't pay attention to it. :-)97 </para>98 99 <para>100 Please also note that BitlBee doesn't support groupchats for all protocols yet. BitlBee will tell you so. Support for other protocols will hopefully come later.101 80 </para> 102 81 … … 121 100 <member>On the phone, Phone, On phone</member> 122 101 <member>Out to lunch, Lunch, Food</member> 102 <member>Invisible, Hidden</member> 123 103 </simplelist> 124 104 … … 128 108 129 109 <para> 130 You can also add more information to your away message. Setting it to "Busy - Fixing BitlBee bugs" will set your IM-away-states to Busy, but your away message will be more descriptive for people on IRC. Protocols like Yahoo! and Jabber will also show this complete away messageto your buddies.110 You can also add more information to your away message. Setting it to "Busy - Fixing BitlBee bugs" will set your IM-away-states to Busy, but your away message will be more descriptive for people on IRC. Most IM-protocols can also show this additional information to your buddies. 131 111 </para> 132 112 -
doc/user-guide/quickstart.xml
r6cac643 rb79308b 61 61 62 62 <para> 63 For most protocols (currently MSN, Jabber, Yahoo and AOL) BitlBee can download the contact list automatically from the IM server and all the on-line users should appear in the control channel when you log in.63 Now BitlBee logs in and downloads the contact list from the IM server. In a few seconds, all your on-line buddies should show up in the control channel. 64 64 </para> 65 65 66 66 <para> 67 BitlBee will convert names into irc-friendly form (for instance: tux@example.com will be given the nickname tux). If you have more than one person who would have the same name by this logic (for instance: tux@example.com and tux@bitlbee.org) the second one to log on will be tux_. The same is true if you have a tux log on to AOL and a tux log on from Yahoo.67 BitlBee will convert names into IRC-friendly form (for instance: tux@example.com will be given the nickname tux). If you have more than one person who would have the same name by this logic (for instance: tux@example.com and tux@bitlbee.org) the second one to log on will be tux_. The same is true if you have a tux log on to AOL and a tux log on from Yahoo. 68 68 </para> 69 69 … … 127 127 <ircexample> 128 128 <ircline nick="you">tux: hey, how's the weather down there?</ircline> 129 <ircline nick="tux"> 129 <ircline nick="tux">you: a bit chilly!</ircline> 130 130 </ircexample> 131 131 132 132 <para> 133 If you'd rather chat with them in a separate window use the <emphasis>/msg</emphasis> or <emphasis>/query</emphasis> command, just like you would for a private message in IRC. If you want to have messages automatically come up in private messages rather than in the &bitlbee channel, use the <emphasis>set private</emphasis> command: <emphasis>set private true</emphasis> (<emphasis>set private false</emphasis> to change back). 133 Note that, although all contacts are in the &bitlbee channel, only tux will actually receive this message. The &bitlbee channel shouldn't be confused with a real IRC channel. 134 </para> 135 136 <para> 137 If you prefer chatting in a separate window, use the <emphasis>/msg</emphasis> or <emphasis>/query</emphasis> command, just like on real IRC. BitlBee will remember how you talk to someone and show his/her responses the same way. If you want to change the default behaviour (for people you haven't talked to yet), see <emphasis>help set private</emphasis>. 134 138 </para> 135 139 -
ipc.c
r6cac643 rb79308b 258 258 else 259 259 { 260 ipc_master_free_fd( source ); 261 } 262 263 return TRUE; 264 } 265 266 gboolean ipc_child_read( gpointer data, gint source, b_input_condition cond ) 267 { 268 char *buf, **cmd; 269 270 if( ( buf = ipc_readline( source ) ) ) 271 { 272 cmd = irc_parse_line( buf ); 273 if( cmd ) 274 ipc_command_exec( data, cmd, ipc_child_commands ); 275 } 276 else 277 { 278 ipc_child_disable(); 279 } 280 281 return TRUE; 282 } 283 284 void ipc_to_master( char **cmd ) 285 { 286 if( global.conf->runmode == RUNMODE_FORKDAEMON ) 287 { 288 char *s = irc_build_line( cmd ); 289 ipc_to_master_str( "%s", s ); 290 g_free( s ); 291 } 292 else if( global.conf->runmode == RUNMODE_DAEMON ) 293 { 294 ipc_command_exec( NULL, cmd, ipc_master_commands ); 295 } 296 } 297 298 void ipc_to_master_str( char *format, ... ) 299 { 300 char *msg_buf; 301 va_list params; 302 303 va_start( params, format ); 304 msg_buf = g_strdup_vprintf( format, params ); 305 va_end( params ); 306 307 if( strlen( msg_buf ) > 512 ) 308 { 309 /* Don't send it, it's too long... */ 310 } 311 else if( global.conf->runmode == RUNMODE_FORKDAEMON ) 312 { 313 if( global.listen_socket >= 0 ) 314 if( write( global.listen_socket, msg_buf, strlen( msg_buf ) ) <= 0 ) 315 ipc_child_disable(); 316 } 317 else if( global.conf->runmode == RUNMODE_DAEMON ) 318 { 319 char **cmd, *s; 320 321 if( ( s = strchr( msg_buf, '\r' ) ) ) 322 *s = 0; 323 324 cmd = irc_parse_line( msg_buf ); 325 ipc_command_exec( NULL, cmd, ipc_master_commands ); 326 g_free( cmd ); 327 } 328 329 g_free( msg_buf ); 330 } 331 332 void ipc_to_children( char **cmd ) 333 { 334 if( global.conf->runmode == RUNMODE_FORKDAEMON ) 335 { 336 char *msg_buf = irc_build_line( cmd ); 337 ipc_to_children_str( "%s", msg_buf ); 338 g_free( msg_buf ); 339 } 340 else if( global.conf->runmode == RUNMODE_DAEMON ) 341 { 260 342 GSList *l; 261 struct bitlbee_child *c; 262 263 for( l = child_list; l; l = l->next ) 343 344 for( l = irc_connection_list; l; l = l->next ) 345 ipc_command_exec( l->data, cmd, ipc_child_commands ); 346 } 347 } 348 349 void ipc_to_children_str( char *format, ... ) 350 { 351 char *msg_buf; 352 va_list params; 353 354 va_start( params, format ); 355 msg_buf = g_strdup_vprintf( format, params ); 356 va_end( params ); 357 358 if( strlen( msg_buf ) > 512 ) 359 { 360 /* Don't send it, it's too long... */ 361 } 362 else if( global.conf->runmode == RUNMODE_FORKDAEMON ) 363 { 364 int msg_len = strlen( msg_buf ); 365 GSList *l, *next; 366 367 for( l = child_list; l; l = next ) 264 368 { 265 c = l->data; 266 if( c->ipc_fd == source ) 369 struct bitlbee_child *c = l->data; 370 371 next = l->next; 372 if( write( c->ipc_fd, msg_buf, msg_len ) <= 0 ) 267 373 { 268 374 ipc_master_free_one( c ); 269 375 child_list = g_slist_remove( child_list, c ); 270 break;271 376 } 272 }273 }274 275 return TRUE;276 }277 278 gboolean ipc_child_read( gpointer data, gint source, b_input_condition cond )279 {280 char *buf, **cmd;281 282 if( ( buf = ipc_readline( source ) ) )283 {284 cmd = irc_parse_line( buf );285 if( cmd )286 ipc_command_exec( data, cmd, ipc_child_commands );287 }288 else289 {290 b_event_remove( global.listen_watch_source_id );291 close( global.listen_socket );292 293 global.listen_socket = -1;294 }295 296 return TRUE;297 }298 299 void ipc_to_master( char **cmd )300 {301 if( global.conf->runmode == RUNMODE_FORKDAEMON )302 {303 char *s = irc_build_line( cmd );304 ipc_to_master_str( "%s", s );305 g_free( s );306 }307 else if( global.conf->runmode == RUNMODE_DAEMON )308 {309 ipc_command_exec( NULL, cmd, ipc_master_commands );310 }311 }312 313 void ipc_to_master_str( char *format, ... )314 {315 char *msg_buf;316 va_list params;317 318 va_start( params, format );319 msg_buf = g_strdup_vprintf( format, params );320 va_end( params );321 322 if( strlen( msg_buf ) > 512 )323 {324 /* Don't send it, it's too long... */325 }326 else if( global.conf->runmode == RUNMODE_FORKDAEMON )327 {328 write( global.listen_socket, msg_buf, strlen( msg_buf ) );329 }330 else if( global.conf->runmode == RUNMODE_DAEMON )331 {332 char **cmd, *s;333 334 if( ( s = strchr( msg_buf, '\r' ) ) )335 *s = 0;336 337 cmd = irc_parse_line( msg_buf );338 ipc_command_exec( NULL, cmd, ipc_master_commands );339 g_free( cmd );340 }341 342 g_free( msg_buf );343 }344 345 void ipc_to_children( char **cmd )346 {347 if( global.conf->runmode == RUNMODE_FORKDAEMON )348 {349 char *msg_buf = irc_build_line( cmd );350 ipc_to_children_str( "%s", msg_buf );351 g_free( msg_buf );352 }353 else if( global.conf->runmode == RUNMODE_DAEMON )354 {355 GSList *l;356 357 for( l = irc_connection_list; l; l = l->next )358 ipc_command_exec( l->data, cmd, ipc_child_commands );359 }360 }361 362 void ipc_to_children_str( char *format, ... )363 {364 char *msg_buf;365 va_list params;366 367 va_start( params, format );368 msg_buf = g_strdup_vprintf( format, params );369 va_end( params );370 371 if( strlen( msg_buf ) > 512 )372 {373 /* Don't send it, it's too long... */374 }375 else if( global.conf->runmode == RUNMODE_FORKDAEMON )376 {377 int msg_len = strlen( msg_buf );378 GSList *l;379 380 for( l = child_list; l; l = l->next )381 {382 struct bitlbee_child *c = l->data;383 write( c->ipc_fd, msg_buf, msg_len );384 377 } 385 378 } … … 410 403 } 411 404 405 void ipc_master_free_fd( int fd ) 406 { 407 GSList *l; 408 struct bitlbee_child *c; 409 410 for( l = child_list; l; l = l->next ) 411 { 412 c = l->data; 413 if( c->ipc_fd == fd ) 414 { 415 ipc_master_free_one( c ); 416 child_list = g_slist_remove( child_list, c ); 417 break; 418 } 419 } 420 } 421 412 422 void ipc_master_free_all() 413 423 { … … 419 429 g_slist_free( child_list ); 420 430 child_list = NULL; 431 } 432 433 void ipc_child_disable() 434 { 435 b_event_remove( global.listen_watch_source_id ); 436 close( global.listen_socket ); 437 438 global.listen_socket = -1; 421 439 } 422 440 -
ipc.h
r6cac643 rb79308b 44 44 45 45 void ipc_master_free_one( struct bitlbee_child *child ); 46 void ipc_master_free_fd( int fd ); 46 47 void ipc_master_free_all(); 48 49 void ipc_child_disable(); 47 50 48 51 void ipc_to_master( char **cmd ); -
irc.c
r6cac643 rb79308b 46 46 } 47 47 48 static char *set_eval_charset( set_t *set, char *value ) 49 { 50 irc_t *irc = set->data; 51 GIConv ic, oc; 52 53 if( g_strcasecmp( value, "none" ) == 0 ) 54 value = g_strdup( "utf-8" ); 55 56 if( ( ic = g_iconv_open( "utf-8", value ) ) == (GIConv) -1 ) 57 { 58 return NULL; 59 } 60 if( ( oc = g_iconv_open( value, "utf-8" ) ) == (GIConv) -1 ) 61 { 62 g_iconv_close( ic ); 63 return NULL; 64 } 65 66 if( irc->iconv != (GIConv) -1 ) 67 g_iconv_close( irc->iconv ); 68 if( irc->oconv != (GIConv) -1 ) 69 g_iconv_close( irc->oconv ); 70 71 irc->iconv = ic; 72 irc->oconv = oc; 73 74 return value; 75 } 76 48 77 irc_t *irc_new( int fd ) 49 78 { … … 68 97 irc->mynick = g_strdup( ROOT_NICK ); 69 98 irc->channel = g_strdup( ROOT_CHAN ); 99 100 irc->iconv = (GIConv) -1; 101 irc->oconv = (GIConv) -1; 70 102 71 103 if( global.conf->hostname ) … … 123 155 set_add( &irc->set, "private", "true", set_eval_bool, irc ); 124 156 set_add( &irc->set, "query_order", "lifo", NULL, irc ); 157 set_add( &irc->set, "root_nick", irc->mynick, set_eval_root_nick, irc ); 125 158 set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc ); 126 159 set_add( &irc->set, "simulate_netsplit", "true", set_eval_bool, irc ); … … 131 164 conf_loaddefaults( irc ); 132 165 166 /* Evaluator sets the iconv/oconv structures. */ 167 set_eval_charset( set_find( &irc->set, "charset" ), set_getstr( &irc->set, "charset" ) ); 168 133 169 return( irc ); 134 170 } … … 168 204 if( irc->sendbuffer && !immed ) 169 205 { 170 /* We won't read from this socket anymore. Instead, we'll connect a timer 171 to it that should shut down the connection in a second, just in case 172 bitlbee_.._write doesn't do it first. */ 206 /* Set up a timeout event that should shut down the connection 207 in a second, just in case ..._write doesn't do it first. */ 173 208 174 209 b_event_remove( irc->r_watch_source_id ); 175 irc->r_watch_source_id = b_timeout_add( 1000, (b_event_handler) irc_free, irc ); 210 irc->r_watch_source_id = 0; 211 212 b_event_remove( irc->ping_source_id ); 213 irc->ping_source_id = b_timeout_add( 1000, (b_event_handler) irc_free, irc ); 176 214 } 177 215 else … … 189 227 190 228 /* Because we have no garbage collection, this is quite annoying */ 191 void irc_free(irc_t * irc) 192 { 193 account_t *account; 229 void irc_free( irc_t * irc ) 230 { 194 231 user_t *user, *usertmp; 195 232 … … 200 237 irc_usermsg( irc, "Error while saving settings!" ); 201 238 202 closesocket( irc->fd );203 204 if( irc->ping_source_id > 0 )205 b_event_remove( irc->ping_source_id );206 b_event_remove( irc->r_watch_source_id );207 if( irc->w_watch_source_id > 0 )208 b_event_remove( irc->w_watch_source_id );209 210 239 irc_connection_list = g_slist_remove( irc_connection_list, irc ); 211 240 212 for (account = irc->accounts; account; account = account->next) { 213 if (account->ic) { 214 imc_logout(account->ic, TRUE); 215 } else if (account->reconnect) { 216 cancel_auto_reconnect(account); 217 } 218 } 219 220 g_free(irc->sendbuffer); 221 g_free(irc->readbuffer); 222 223 g_free(irc->nick); 224 g_free(irc->user); 225 g_free(irc->host); 226 g_free(irc->realname); 227 g_free(irc->password); 228 229 g_free(irc->myhost); 230 g_free(irc->mynick); 231 232 g_free(irc->channel); 233 234 while (irc->queries != NULL) 235 query_del(irc, irc->queries); 236 237 while (irc->accounts) 238 if (irc->accounts->ic == NULL) 239 account_del(irc, irc->accounts); 241 while( irc->accounts ) 242 { 243 if( irc->accounts->ic ) 244 imc_logout( irc->accounts->ic, FALSE ); 245 else if( irc->accounts->reconnect ) 246 cancel_auto_reconnect( irc->accounts ); 247 248 if( irc->accounts->ic == NULL ) 249 account_del( irc, irc->accounts ); 240 250 else 241 251 /* Nasty hack, but account_del() doesn't work in this 242 252 case and we don't want infinite loops, do we? ;-) */ 243 253 irc->accounts = irc->accounts->next; 244 245 while (irc->set) 246 set_del(&irc->set, irc->set->key); 247 248 if (irc->users != NULL) { 254 } 255 256 while( irc->queries != NULL ) 257 query_del( irc, irc->queries ); 258 259 while( irc->set ) 260 set_del( &irc->set, irc->set->key ); 261 262 if (irc->users != NULL) 263 { 249 264 user = irc->users; 250 while (user != NULL) { 251 g_free(user->nick); 252 g_free(user->away); 253 g_free(user->handle); 254 if(user->user!=user->nick) g_free(user->user); 255 if(user->host!=user->nick) g_free(user->host); 256 if(user->realname!=user->nick) g_free(user->realname); 257 b_event_remove(user->sendbuf_timer); 265 while( user != NULL ) 266 { 267 g_free( user->nick ); 268 g_free( user->away ); 269 g_free( user->handle ); 270 if( user->user != user->nick ) g_free( user->user ); 271 if( user->host != user->nick ) g_free( user->host ); 272 if( user->realname != user->nick ) g_free( user->realname ); 273 b_event_remove( user->sendbuf_timer ); 258 274 259 275 usertmp = user; 260 276 user = user->next; 261 g_free(usertmp); 262 } 263 } 264 265 g_hash_table_foreach_remove(irc->userhash, irc_free_hashkey, NULL); 266 g_hash_table_destroy(irc->userhash); 267 268 g_hash_table_foreach_remove(irc->watches, irc_free_hashkey, NULL); 269 g_hash_table_destroy(irc->watches); 270 271 g_free(irc); 277 g_free( usertmp ); 278 } 279 } 280 281 if( irc->ping_source_id > 0 ) 282 b_event_remove( irc->ping_source_id ); 283 if( irc->r_watch_source_id > 0 ) 284 b_event_remove( irc->r_watch_source_id ); 285 if( irc->w_watch_source_id > 0 ) 286 b_event_remove( irc->w_watch_source_id ); 287 288 closesocket( irc->fd ); 289 irc->fd = -1; 290 291 g_hash_table_foreach_remove( irc->userhash, irc_free_hashkey, NULL ); 292 g_hash_table_destroy( irc->userhash ); 293 294 g_hash_table_foreach_remove( irc->watches, irc_free_hashkey, NULL ); 295 g_hash_table_destroy( irc->watches ); 296 297 if( irc->iconv != (GIConv) -1 ) 298 g_iconv_close( irc->iconv ); 299 if( irc->oconv != (GIConv) -1 ) 300 g_iconv_close( irc->oconv ); 301 302 g_free( irc->sendbuffer ); 303 g_free( irc->readbuffer ); 304 305 g_free( irc->nick ); 306 g_free( irc->user ); 307 g_free( irc->host ); 308 g_free( irc->realname ); 309 g_free( irc->password ); 310 311 g_free( irc->myhost ); 312 g_free( irc->mynick ); 313 314 g_free( irc->channel ); 315 316 g_free( irc->last_target ); 317 318 g_free( irc ); 272 319 273 320 if( global.conf->runmode == RUNMODE_INETD || global.conf->runmode == RUNMODE_FORKDAEMON ) … … 290 337 void irc_process( irc_t *irc ) 291 338 { 292 char **lines, *temp, **cmd , *cs;339 char **lines, *temp, **cmd; 293 340 int i; 294 341 … … 299 346 for( i = 0; *lines[i] != '\0'; i ++ ) 300 347 { 301 char conv[IRC_MAX_LINE+1];348 char *conv = NULL; 302 349 303 /* [WvG] Because irc_tokenize splits at every newline, the lines[] list 304 should end with an empty string. This is why this actually works. 305 Took me a while to figure out, Maurits. :-P */ 350 /* [WvG] If the last line isn't empty, it's an incomplete line and we 351 should wait for the rest to come in before processing it. */ 306 352 if( lines[i+1] == NULL ) 307 353 { … … 313 359 } 314 360 315 if( ( cs = set_getstr( &irc->set, "charset" ) ) ) 316 { 317 conv[IRC_MAX_LINE] = 0; 318 if( do_iconv( cs, "UTF-8", lines[i], conv, 0, IRC_MAX_LINE - 2 ) == -1 ) 361 if( irc->iconv != (GIConv) -1 ) 362 { 363 gsize bytes_read, bytes_written; 364 365 conv = g_convert_with_iconv( lines[i], -1, irc->iconv, 366 &bytes_read, &bytes_written, NULL ); 367 368 if( conv == NULL || bytes_read != strlen( lines[i] ) ) 319 369 { 320 370 /* GLib can do strange things if things are not in the expected charset, … … 328 378 "expect by changing the charset setting. See " 329 379 "`help set charset' for more information. Your " 330 "message was ignored.", cs ); 331 *conv = 0; 380 "message was ignored.", 381 set_getstr( &irc->set, "charset" ) ); 382 383 g_free( conv ); 384 conv = NULL; 332 385 } 333 386 else 334 387 { 335 388 irc_write( irc, ":%s NOTICE AUTH :%s", irc->myhost, 336 "Warning: invalid (non-UTF8)characters received at login time." );389 "Warning: invalid characters received at login time." ); 337 390 338 strncpy( conv, lines[i], IRC_MAX_LINE);391 conv = g_strdup( lines[i] ); 339 392 for( temp = conv; *temp; temp ++ ) 340 393 if( *temp & 0x80 ) … … 345 398 } 346 399 347 if( ( cmd = irc_parse_line( lines[i] ) ) == NULL ) 348 continue; 349 irc_exec( irc, cmd ); 400 if( lines[i] ) 401 { 402 if( ( cmd = irc_parse_line( lines[i] ) ) == NULL ) 403 continue; 404 irc_exec( irc, cmd ); 405 g_free( cmd ); 406 } 350 407 351 g_free( c md);408 g_free( conv ); 352 409 353 410 /* Shouldn't really happen, but just in case... */ … … 373 430 char **irc_tokenize( char *buffer ) 374 431 { 375 int i, j ;432 int i, j, n = 3; 376 433 char **lines; 377 434 378 /* Count the number of elements we're gonna need. */ 379 for( i = 0, j = 1; buffer[i] != '\0'; i ++ ) 380 { 381 if( buffer[i] == '\n' ) 382 if( buffer[i+1] != '\r' && buffer[i+1] != '\n' ) 383 j ++; 384 } 385 386 /* Allocate j+1 elements. */ 387 lines = g_new( char *, j + 1 ); 435 /* Allocate n+1 elements. */ 436 lines = g_new( char *, n + 1 ); 437 438 lines[0] = buffer; 439 440 /* Split the buffer in several strings, and accept any kind of line endings, 441 * knowing that ERC on Windows may send something interesting like \r\r\n, 442 * and surely there must be clients that think just \n is enough... */ 443 for( i = 0, j = 0; buffer[i] != '\0'; i ++ ) 444 { 445 if( buffer[i] == '\r' || buffer[i] == '\n' ) 446 { 447 while( buffer[i] == '\r' || buffer[i] == '\n' ) 448 buffer[i++] = '\0'; 449 450 lines[++j] = buffer + i; 451 452 if( j >= n ) 453 { 454 n *= 2; 455 lines = g_renew( char *, lines, n + 1 ); 456 } 457 458 if( buffer[i] == '\0' ) 459 break; 460 } 461 } 388 462 389 463 /* NULL terminate our list. */ 390 lines[j] = NULL; 391 392 lines[0] = buffer; 393 394 /* Split the buffer in several strings, using \r\n as our seperator, where \r is optional. 395 * Although this is not in the RFC, some braindead ircds (newnet's) use this, so some clients might too. 396 */ 397 for( i = 0, j = 0; buffer[i] != '\0'; i ++) 398 { 399 if( buffer[i] == '\n' ) 400 { 401 buffer[i] = '\0'; 402 403 if( i > 0 && buffer[i-1] == '\r' ) 404 buffer[i-1] = '\0'; 405 if( buffer[i+1] != '\r' && buffer[i+1] != '\n' ) 406 lines[++j] = buffer + i + 1; 407 } 408 } 409 410 return( lines ); 464 lines[++j] = NULL; 465 466 return lines; 411 467 } 412 468 … … 542 598 543 599 return; 544 545 600 } 546 601 … … 548 603 { 549 604 int size; 550 char line[IRC_MAX_LINE+1] , *cs;605 char line[IRC_MAX_LINE+1]; 551 606 552 607 /* Don't try to write anything new anymore when shutting down. */ … … 554 609 return; 555 610 556 line[IRC_MAX_LINE] = 0;611 memset( line, 0, sizeof( line ) ); 557 612 g_vsnprintf( line, IRC_MAX_LINE - 2, format, params ); 558 559 613 strip_newlines( line ); 560 if( ( cs = set_getstr( &irc->set, "charset" ) ) && ( g_strcasecmp( cs, "utf-8" ) != 0 ) ) 561 { 562 char conv[IRC_MAX_LINE+1]; 563 564 conv[IRC_MAX_LINE] = 0; 565 if( do_iconv( "UTF-8", cs, line, conv, 0, IRC_MAX_LINE - 2 ) != -1 ) 566 strcpy( line, conv ); 567 } 568 strcat( line, "\r\n" ); 614 615 if( irc->oconv != (GIConv) -1 ) 616 { 617 gsize bytes_read, bytes_written; 618 char *conv; 619 620 conv = g_convert_with_iconv( line, -1, irc->oconv, 621 &bytes_read, &bytes_written, NULL ); 622 623 if( bytes_read == strlen( line ) ) 624 strncpy( line, conv, IRC_MAX_LINE - 2 ); 625 626 g_free( conv ); 627 } 628 g_strlcat( line, "\r\n", IRC_MAX_LINE + 1 ); 569 629 570 630 if( irc->sendbuffer != NULL ) … … 739 799 irc_spawn( irc, u ); 740 800 741 irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\nIf you've never used BitlBee before, please do read the help information using the \x02help\x02 command. Lots of FAQs are answered there." ); 801 irc_usermsg( irc, "Welcome to the BitlBee gateway!\n\n" 802 "If you've never used BitlBee before, please do read the help " 803 "information using the \x02help\x02 command. Lots of FAQs are " 804 "answered there.\n" 805 "If you already have an account on this server, just use the " 806 "\x02identify\x02 command to identify yourself." ); 742 807 743 808 if( global.conf->runmode == RUNMODE_FORKDAEMON || global.conf->runmode == RUNMODE_DAEMON ) … … 745 810 746 811 irc->status |= USTATUS_LOGGED_IN; 812 813 /* This is for bug #209 (use PASS to identify to NickServ). */ 814 if( irc->password != NULL ) 815 { 816 char *send_cmd[] = { "identify", g_strdup( irc->password ), NULL }; 817 818 irc_setpass( irc, NULL ); 819 root_command( irc, send_cmd ); 820 g_free( send_cmd[1] ); 821 } 747 822 } 748 823 -
irc.h
r6cac643 rb79308b 61 61 char *sendbuffer; 62 62 char *readbuffer; 63 GIConv iconv, oconv; 63 64 64 65 int sentbytes; … … 69 70 char *host; 70 71 char *realname; 71 char *password; 72 char *password; /* HACK: Used to save the user's password, but before 73 logging in, this may contain a password we should 74 send to identify after USER/NICK are received. */ 72 75 73 76 char umode[8]; -
irc_commands.c
r6cac643 rb79308b 30 30 static void irc_cmd_pass( irc_t *irc, char **cmd ) 31 31 { 32 if( global.conf->auth_pass && strcmp( cmd[1], global.conf->auth_pass ) == 0 ) 32 if( irc->status & USTATUS_LOGGED_IN ) 33 { 34 char *send_cmd[] = { "identify", cmd[1], NULL }; 35 36 /* We're already logged in, this client seems to send the PASS 37 command last. (Possibly it won't send it at all if it turns 38 out we don't require it, which will break this feature.) 39 Try to identify using the given password. */ 40 return root_command( irc, send_cmd ); 41 } 42 /* Handling in pre-logged-in state, first see if this server is 43 password-protected: */ 44 else if( global.conf->auth_pass && 45 ( strncmp( global.conf->auth_pass, "md5:", 4 ) == 0 ? 46 md5_verify_password( cmd[1], global.conf->auth_pass + 4 ) == 0 : 47 strcmp( cmd[1], global.conf->auth_pass ) == 0 ) ) 33 48 { 34 49 irc->status |= USTATUS_AUTHORIZED; 35 50 irc_check_login( irc ); 36 51 } 37 else 52 else if( global.conf->auth_pass ) 38 53 { 39 54 irc_reply( irc, 464, ":Incorrect password" ); 55 } 56 else 57 { 58 /* Remember the password and try to identify after USER/NICK. */ 59 irc_setpass( irc, cmd[1] ); 60 irc_check_login( irc ); 40 61 } 41 62 } … … 88 109 static void irc_cmd_oper( irc_t *irc, char **cmd ) 89 110 { 90 if( global.conf->oper_pass && strcmp( cmd[2], global.conf->oper_pass ) == 0 ) 111 if( global.conf->oper_pass && 112 ( strncmp( global.conf->oper_pass, "md5:", 4 ) == 0 ? 113 md5_verify_password( cmd[2], global.conf->oper_pass + 4 ) == 0 : 114 strcmp( cmd[2], global.conf->oper_pass ) == 0 ) ) 91 115 { 92 116 irc_umode_set( irc, "+o", 1 ); … … 254 278 if( cmd[1] != irc->last_target ) 255 279 { 256 if( irc->last_target ) 257 g_free( irc->last_target ); 280 g_free( irc->last_target ); 258 281 irc->last_target = g_strdup( cmd[1] ); 259 282 } … … 575 598 576 599 static const command_t irc_commands[] = { 577 { "pass", 1, irc_cmd_pass, IRC_CMD_PRE_LOGIN},600 { "pass", 1, irc_cmd_pass, 0 }, 578 601 { "user", 4, irc_cmd_user, IRC_CMD_PRE_LOGIN }, 579 602 { "nick", 1, irc_cmd_nick, 0 }, -
lib/Makefile
r6cac643 rb79308b 10 10 11 11 # [SH] Program variables 12 objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o $(SSL_CLIENT) url.o 12 objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o 13 13 14 14 CFLAGS += -Wall … … 18 18 all: lib.o 19 19 check: all 20 lcov: 20 lcov: check 21 21 gcov: 22 22 gcov *.c -
lib/arc.c
r6cac643 rb79308b 131 131 132 132 Both functions return the number of bytes in the result string. 133 134 Note that if you use the pad_to argument, you will need zero-termi- 135 nation to find back the original string length after decryption. So 136 it shouldn't be used if your string contains \0s by itself! 133 137 */ 134 138 135 int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password )139 int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to ) 136 140 { 137 141 struct arc_state *st; 138 142 unsigned char *key; 139 int key_len, i; 143 char *padded = NULL; 144 int key_len, i, padded_len; 140 145 141 146 key_len = strlen( password ) + ARC_IV_LEN; 142 147 if( clear_len <= 0 ) 143 148 clear_len = strlen( clear ); 149 150 /* Pad the string to the closest multiple of pad_to. This makes it 151 impossible to see the exact length of the password. */ 152 if( pad_to > 0 && ( clear_len % pad_to ) > 0 ) 153 { 154 padded_len = clear_len + pad_to - ( clear_len % pad_to ); 155 padded = g_malloc( padded_len ); 156 memcpy( padded, clear, clear_len ); 157 158 /* First a \0 and then random data, so we don't have to do 159 anything special when decrypting. */ 160 padded[clear_len] = 0; 161 random_bytes( (unsigned char*) padded + clear_len + 1, padded_len - clear_len - 1 ); 162 163 clear = padded; 164 clear_len = padded_len; 165 } 144 166 145 167 /* Prepare buffers and the key + IV */ … … 161 183 162 184 g_free( st ); 185 g_free( padded ); 163 186 164 187 return clear_len + ARC_IV_LEN; -
lib/arc.h
r6cac643 rb79308b 31 31 }; 32 32 33 struct arc_state *arc_keymaker( unsigned char *key, int kl, int cycles ); 33 #ifndef G_GNUC_MALLOC 34 #define G_GNUC_MALLOC 35 #endif 36 37 G_GNUC_MALLOC struct arc_state *arc_keymaker( unsigned char *key, int kl, int cycles ); 34 38 unsigned char arc_getbyte( struct arc_state *st ); 35 int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password );39 int arc_encode( char *clear, int clear_len, unsigned char **crypt, char *password, int pad_to ); 36 40 int arc_decode( unsigned char *crypt, int crypt_len, char **clear, char *password ); -
lib/base64.c
r6cac643 rb79308b 118 118 int i, outlen = 0; 119 119 120 for( i = 0; in[i] ; i += 4 )120 for( i = 0; in[i] && in[i+1] && in[i+2] && in[i+3]; i += 4 ) 121 121 { 122 122 int sx; -
lib/events_glib.c
r6cac643 rb79308b 51 51 } GaimIOClosure; 52 52 53 static GMainLoop *loop ;53 static GMainLoop *loop = NULL; 54 54 55 55 void b_main_init() 56 56 { 57 loop = g_main_new( FALSE ); 57 if( loop == NULL ) 58 loop = g_main_new( FALSE ); 58 59 } 59 60 -
lib/misc.c
r6cac643 rb79308b 33 33 #define BITLBEE_CORE 34 34 #include "nogaim.h" 35 #include "base64.h" 35 36 #include <stdio.h> 36 37 #include <stdlib.h> … … 597 598 return sockerr_again(); 598 599 } 600 601 /* Returns values: -1 == Failure (base64-decoded to something unexpected) 602 0 == Okay 603 1 == Password doesn't match the hash. */ 604 int md5_verify_password( char *password, char *hash ) 605 { 606 md5_byte_t *pass_dec = NULL; 607 md5_byte_t pass_md5[16]; 608 md5_state_t md5_state; 609 int ret, i; 610 611 if( base64_decode( hash, &pass_dec ) != 21 ) 612 { 613 ret = -1; 614 } 615 else 616 { 617 md5_init( &md5_state ); 618 md5_append( &md5_state, (md5_byte_t*) password, strlen( password ) ); 619 md5_append( &md5_state, (md5_byte_t*) pass_dec + 16, 5 ); /* Hmmm, salt! */ 620 md5_finish( &md5_state, pass_md5 ); 621 622 for( i = 0; i < 16; i ++ ) 623 { 624 if( pass_dec[i] != pass_md5[i] ) 625 { 626 ret = 1; 627 break; 628 } 629 } 630 631 /* If we reached the end of the loop, it was a match! */ 632 if( i == 16 ) 633 ret = 0; 634 } 635 636 g_free( pass_dec ); 637 638 return ret; 639 } -
lib/misc.h
r6cac643 rb79308b 67 67 G_MODULE_EXPORT gboolean ssl_sockerr_again( void *ssl ); 68 68 69 G_MODULE_EXPORT int md5_verify_password( char *password, char *hash ); 70 69 71 #endif -
lib/proxy.c
r6cac643 rb79308b 530 530 struct PHB *phb; 531 531 532 if (!host || !port || (port == -1)|| !func || strlen(host) > 128) {532 if (!host || port <= 0 || !func || strlen(host) > 128) { 533 533 return -1; 534 534 } … … 538 538 phb->data = data; 539 539 540 if ( (proxytype == PROXY_NONE) || strlen(proxyhost) > 0 || !proxyport || (proxyport == -1))540 if (proxytype == PROXY_NONE || !proxyhost[0] || proxyport <= 0) 541 541 return proxy_connect_none(host, port, phb); 542 542 else if (proxytype == PROXY_HTTP) -
lib/ssl_client.h
r6cac643 rb79308b 60 60 G_MODULE_EXPORT int ssl_write( void *conn, const char *buf, int len ); 61 61 62 /* See ssl_openssl.c for an explanation. */ 63 G_MODULE_EXPORT int ssl_pending( void *conn ); 64 62 65 /* Abort the SSL connection and disconnect the socket. Do not use close() 63 66 directly, both the SSL library and the peer will be unhappy! */ -
lib/ssl_gnutls.c
r6cac643 rb79308b 211 211 } 212 212 213 /* See ssl_openssl.c for an explanation. */ 214 int ssl_pending( void *conn ) 215 { 216 return 0; 217 } 218 213 219 void ssl_disconnect( void *conn_ ) 214 220 { -
lib/ssl_nss.c
r6cac643 rb79308b 169 169 } 170 170 171 /* See ssl_openssl.c for an explanation. */ 172 int ssl_pending( void *conn ) 173 { 174 return 0; 175 } 176 171 177 void ssl_disconnect( void *conn_ ) 172 178 { -
lib/ssl_openssl.c
r6cac643 rb79308b 62 62 63 63 conn->fd = proxy_connect( host, port, ssl_connected, conn ); 64 if( conn->fd < 0 ) 65 { 66 g_free( conn ); 67 return NULL; 68 } 69 64 70 conn->func = func; 65 71 conn->data = data; 66 72 conn->inpa = -1; 67 68 if( conn->fd < 0 )69 {70 g_free( conn );71 return NULL;72 }73 73 74 74 return conn; … … 231 231 } 232 232 233 /* Only OpenSSL *really* needs this (and well, maybe NSS). See for more info: 234 http://www.gnu.org/software/gnutls/manual/gnutls.html#index-gnutls_005frecord_005fcheck_005fpending-209 235 http://www.openssl.org/docs/ssl/SSL_pending.html 236 237 Required because OpenSSL empties the TCP buffer completely but doesn't 238 necessarily give us all the unencrypted data. 239 240 Returns 0 if there's nothing left or if we don't have to care (GnuTLS), 241 1 if there's more data. */ 242 int ssl_pending( void *conn ) 243 { 244 return ( ((struct scd*)conn) && ((struct scd*)conn)->established ) ? 245 SSL_pending( ((struct scd*)conn)->ssl ) > 0 : 0; 246 } 247 233 248 void ssl_disconnect( void *conn_ ) 234 249 { -
lib/url.c
r6cac643 rb79308b 26 26 #include "url.h" 27 27 28 /* Convert an URL to a url_t structure 28 /* Convert an URL to a url_t structure */ 29 29 int url_set( url_t *url, char *set_url ) 30 30 { 31 char s[MAX_STRING ];31 char s[MAX_STRING+1]; 32 32 char *i; 33 33 34 /* protocol:// */ 34 memset( url, 0, sizeof( url_t ) ); 35 memset( s, 0, sizeof( s ) ); 36 37 /* protocol:// */ 35 38 if( ( i = strstr( set_url, "://" ) ) == NULL ) 36 39 { … … 49 52 url->proto = PROTO_SOCKS5; 50 53 else 51 { 52 return( 0 ); 53 } 54 return 0; 55 54 56 strncpy( s, i + 3, MAX_STRING ); 55 57 } 56 58 57 /* Split 59 /* Split */ 58 60 if( ( i = strchr( s, '/' ) ) == NULL ) 59 61 { … … 67 69 strncpy( url->host, s, MAX_STRING ); 68 70 69 /* Check for username in host field 71 /* Check for username in host field */ 70 72 if( strrchr( url->host, '@' ) != NULL ) 71 73 { … … 76 78 *url->pass = 0; 77 79 } 78 /* If not: Fill in defaults 80 /* If not: Fill in defaults */ 79 81 else 80 82 { … … 82 84 } 83 85 84 /* Password? 86 /* Password? */ 85 87 if( ( i = strchr( url->user, ':' ) ) != NULL ) 86 88 { … … 88 90 strcpy( url->pass, i + 1 ); 89 91 } 90 /* Port number? 92 /* Port number? */ 91 93 if( ( i = strchr( url->host, ':' ) ) != NULL ) 92 94 { -
lib/url.h
r6cac643 rb79308b 26 26 #include "bitlbee.h" 27 27 28 #define PROTO_HTTP 29 #define PROTO_HTTPS 30 #define PROTO_SOCKS4 31 #define PROTO_SOCKS5 32 #define PROTO_DEFAULT 28 #define PROTO_HTTP 2 29 #define PROTO_HTTPS 5 30 #define PROTO_SOCKS4 3 31 #define PROTO_SOCKS5 4 32 #define PROTO_DEFAULT PROTO_HTTP 33 33 34 34 typedef struct url … … 36 36 int proto; 37 37 int port; 38 char host[MAX_STRING ];39 char file[MAX_STRING ];40 char user[MAX_STRING ];41 char pass[MAX_STRING ];38 char host[MAX_STRING+1]; 39 char file[MAX_STRING+1]; 40 char user[MAX_STRING+1]; 41 char pass[MAX_STRING+1]; 42 42 } url_t; 43 43 -
lib/xmltree.c
r6cac643 rb79308b 111 111 }; 112 112 113 struct xt_parser *xt_new( gpointer data )113 struct xt_parser *xt_new( const struct xt_handler_entry *handlers, gpointer data ) 114 114 { 115 115 struct xt_parser *xt = g_new0( struct xt_parser, 1 ); 116 116 117 117 xt->data = data; 118 xt->handlers = handlers; 118 119 xt_reset( xt ); 119 120 -
lib/xmltree.h
r6cac643 rb79308b 71 71 struct xt_node *cur; 72 72 73 struct xt_handler_entry *handlers;73 const struct xt_handler_entry *handlers; 74 74 gpointer data; 75 75 … … 77 77 }; 78 78 79 struct xt_parser *xt_new( gpointer data );79 struct xt_parser *xt_new( const struct xt_handler_entry *handlers, gpointer data ); 80 80 void xt_reset( struct xt_parser *xt ); 81 81 int xt_feed( struct xt_parser *xt, char *text, int text_len ); -
protocols/Makefile
r6cac643 rb79308b 27 27 all: protocols.o 28 28 check: all 29 lcov: 29 lcov: check 30 30 gcov: 31 31 gcov *.c -
protocols/jabber/Makefile
r6cac643 rb79308b 10 10 11 11 # [SH] Program variables 12 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o xmltree.osi.o s5bytestream.o12 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o si.o s5bytestream.o 13 13 14 14 CFLAGS += -Wall … … 18 18 all: jabber_mod.o 19 19 check: all 20 lcov: 20 lcov: check 21 21 gcov: 22 22 gcov *.c -
protocols/jabber/io.c
r6cac643 rb79308b 241 241 } 242 242 243 /* EAGAIN/etc or a successful read. */ 244 return TRUE; 243 if( ssl_pending( jd->ssl ) ) 244 /* OpenSSL empties the TCP buffers completely but may keep some 245 data in its internap buffers. select() won't see that, but 246 ssl_pending() does. */ 247 return jabber_read_callback( data, fd, cond ); 248 else 249 return TRUE; 245 250 } 246 251 … … 521 526 from the server too. */ 522 527 xt_free( jd->xt ); /* In case we're RE-starting. */ 523 jd->xt = xt_new( ic ); 524 jd->xt->handlers = (struct xt_handler_entry*) jabber_handlers; 528 jd->xt = xt_new( jabber_handlers, ic ); 525 529 526 530 if( jd->r_inpa <= 0 ) -
protocols/jabber/iq.c
r6cac643 rb79308b 534 534 } 535 535 536 static xt_status jabber_add_to_roster_callback( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ); 537 536 538 int jabber_add_to_roster( struct im_connection *ic, char *handle, char *name ) 537 539 { … … 549 551 xt_add_attr( node, "xmlns", XMLNS_ROSTER ); 550 552 node = jabber_make_packet( "iq", "set", NULL, node ); 553 jabber_cache_add( ic, node, jabber_add_to_roster_callback ); 551 554 552 555 st = jabber_write_packet( ic, node ); 553 556 554 xt_free_node( node );555 557 return st; 558 } 559 560 static xt_status jabber_add_to_roster_callback( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) 561 { 562 char *s, *jid = NULL; 563 struct xt_node *c; 564 565 if( ( c = xt_find_node( orig->children, "query" ) ) && 566 ( c = xt_find_node( c->children, "item" ) ) && 567 ( jid = xt_find_attr( c, "jid" ) ) && 568 ( s = xt_find_attr( node, "type" ) ) && 569 strcmp( s, "result" ) == 0 ) 570 { 571 if( imcb_find_buddy( ic, jid ) == NULL ) 572 imcb_add_buddy( ic, jid, NULL ); 573 } 574 else 575 { 576 imcb_log( ic, "Error while adding `%s' to your contact list.", 577 jid ? jid : "(unknown handle)" ); 578 } 579 580 return XT_HANDLED; 556 581 } 557 582 -
protocols/jabber/jabber.c
r6cac643 rb79308b 267 267 xt_free( jd->xt ); 268 268 269 g_free( jd->cached_id_prefix ); 269 270 g_free( jd->away_message ); 270 271 g_free( jd->username ); -
protocols/jabber/jabber_util.c
r6cac643 rb79308b 250 250 }; 251 251 252 static void jabber_buddy_ask_yes( gpointer w, struct jabber_buddy_ask_data *bla ) 253 { 252 static void jabber_buddy_ask_yes( void *data ) 253 { 254 struct jabber_buddy_ask_data *bla = data; 255 254 256 presence_send_request( bla->ic, bla->handle, "subscribed" ); 255 257 … … 261 263 } 262 264 263 static void jabber_buddy_ask_no( gpointer w, struct jabber_buddy_ask_data *bla ) 264 { 265 static void jabber_buddy_ask_no( void *data ) 266 { 267 struct jabber_buddy_ask_data *bla = data; 268 265 269 presence_send_request( bla->ic, bla->handle, "subscribed" ); 266 270 -
protocols/jabber/sasl.c
r6cac643 rb79308b 21 21 * * 22 22 \***************************************************************************/ 23 24 #include <ctype.h> 23 25 24 26 #include "jabber.h" … … 107 109 } 108 110 109 static char *sasl_get_part( char *data, char *field ) 111 /* Non-static function, but not mentioned in jabber.h because it's for internal 112 use, just that the unittest should be able to reach it... */ 113 char *sasl_get_part( char *data, char *field ) 110 114 { 111 115 int i, len; 112 116 113 117 len = strlen( field ); 118 119 while( isspace( *data ) || *data == ',' ) 120 data ++; 114 121 115 122 if( g_strncasecmp( data, field, len ) == 0 && data[len] == '=' ) … … 129 136 } 130 137 131 /* If we got a comma, we got a new field. Check it. */ 132 if( data[i] == ',' && 133 g_strncasecmp( data + i + 1, field, len ) == 0 && 134 data[i+len+1] == '=' ) 138 /* If we got a comma, we got a new field. Check it, 139 find the next key after it. */ 140 if( data[i] == ',' ) 135 141 { 136 i += len + 2; 137 break; 142 while( isspace( data[i] ) || data[i] == ',' ) 143 i ++; 144 145 if( g_strncasecmp( data + i, field, len ) == 0 && 146 data[i+len] == '=' ) 147 { 148 i += len + 1; 149 break; 150 } 138 151 } 139 152 } -
protocols/msn/Makefile
r6cac643 rb79308b 18 18 all: msn_mod.o 19 19 check: all 20 lcov: 20 lcov: check 21 21 gcov: 22 22 gcov *.c -
protocols/msn/msn.h
r6cac643 rb79308b 29 29 #define GROUPCHAT_SWITCHBOARD_MESSAGE "\r\r\rME WANT TALK TO MANY PEOPLE\r\r\r" 30 30 31 #ifdef DEBUG 31 #ifdef DEBUG_MSN 32 32 #define debug( text... ) imcb_log( ic, text ); 33 33 #else -
protocols/msn/msn_util.c
r6cac643 rb79308b 90 90 }; 91 91 92 static void msn_buddy_ask_yes( gpointer w, struct msn_buddy_ask_data *bla ) 93 { 92 static void msn_buddy_ask_yes( void *data ) 93 { 94 struct msn_buddy_ask_data *bla = data; 95 94 96 msn_buddy_list_add( bla->ic, "AL", bla->handle, bla->realname ); 95 97 … … 102 104 } 103 105 104 static void msn_buddy_ask_no( gpointer w, struct msn_buddy_ask_data *bla ) 105 { 106 static void msn_buddy_ask_no( void *data ) 107 { 108 struct msn_buddy_ask_data *bla = data; 109 106 110 msn_buddy_list_add( bla->ic, "BL", bla->handle, bla->realname ); 107 111 -
protocols/msn/ns.c
r6cac643 rb79308b 34 34 static int msn_ns_message( gpointer data, char *msg, int msglen, char **cmd, int num_parts ); 35 35 36 static void msn_auth_got_passport_ id( struct passport_reply *rep);36 static void msn_auth_got_passport_token( struct msn_auth_data *mad ); 37 37 38 38 gboolean msn_ns_connected( gpointer data, gint source, b_input_condition cond ) … … 214 214 { 215 215 /* Time for some Passport black magic... */ 216 if( !passport_get_ id( msn_auth_got_passport_id, ic, ic->acc->user, ic->acc->pass, cmd[4] ) )216 if( !passport_get_token( msn_auth_got_passport_token, ic, ic->acc->user, ic->acc->pass, cmd[4] ) ) 217 217 { 218 218 imcb_error( ic, "Error while contacting Passport server" ); … … 674 674 } 675 675 676 static void msn_auth_got_passport_ id( struct passport_reply *rep)676 static void msn_auth_got_passport_token( struct msn_auth_data *mad ) 677 677 { 678 struct im_connection *ic = rep->data; 679 struct msn_data *md = ic->proto_data; 680 char *key = rep->result; 681 char buf[1024]; 682 683 if( key == NULL ) 684 { 685 imcb_error( ic, "Error during Passport authentication (%s)", 686 rep->error_string ? rep->error_string : "Unknown error" ); 678 struct im_connection *ic = mad->data; 679 struct msn_data *md; 680 681 /* Dead connection? */ 682 if( g_slist_find( msn_connections, ic ) == NULL ) 683 return; 684 685 md = ic->proto_data; 686 if( mad->token ) 687 { 688 char buf[1024]; 689 690 g_snprintf( buf, sizeof( buf ), "USR %d TWN S %s\r\n", ++md->trId, mad->token ); 691 msn_write( ic, buf, strlen( buf ) ); 692 } 693 else 694 { 695 imcb_error( ic, "Error during Passport authentication: %s", mad->error ); 687 696 imc_logout( ic, TRUE ); 688 697 } 689 else690 {691 g_snprintf( buf, sizeof( buf ), "USR %d TWN S %s\r\n", ++md->trId, key );692 msn_write( ic, buf, strlen( buf ) );693 }694 698 } -
protocols/msn/passport.c
r6cac643 rb79308b 1 /* passport.c1 /** passport.c 2 2 * 3 * Functions to login to microsoft passport service for Messenger 4 * Copyright (C) 2004 Wouter Paesen <wouter@blue-gate.be> 5 * Copyright (C) 2004 Wilmer van der Gaast <wilmer@gaast.net> 3 * Functions to login to Microsoft Passport service for Messenger 4 * Copyright (C) 2004-2008 Wilmer van der Gaast <wilmer@gaast.net> 6 5 * 7 6 * This program is free software; you can redistribute it and/or modify … … 24 23 #include "msn.h" 25 24 #include "bitlbee.h" 25 #include "url.h" 26 #include "misc.h" 27 #include "xmltree.h" 26 28 #include <ctype.h> 27 29 #include <errno.h> 28 30 29 #define MSN_BUF_LEN 8192 31 static int passport_get_token_real( struct msn_auth_data *mad ); 32 static void passport_get_token_ready( struct http_request *req ); 30 33 31 static char *prd_cached = NULL; 32 33 static int passport_get_id_real( gpointer func, gpointer data, char *header ); 34 static void passport_get_id_ready( struct http_request *req ); 35 36 static int passport_retrieve_dalogin( gpointer data, gpointer func, char *header ); 37 static void passport_retrieve_dalogin_ready( struct http_request *req ); 38 39 static char *passport_create_header( char *cookie, char *email, char *pwd ); 40 static void destroy_reply( struct passport_reply *rep ); 41 42 int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie ) 34 int passport_get_token( gpointer func, gpointer data, char *username, char *password, char *cookie ) 43 35 { 44 char *header = passport_create_header( cookie, username, password ); 36 struct msn_auth_data *mad = g_new0( struct msn_auth_data, 1 ); 37 int i; 45 38 46 if( prd_cached == NULL ) 47 return passport_retrieve_dalogin( func, data, header ); 48 else 49 return passport_get_id_real( func, data, header ); 39 mad->username = g_strdup( username ); 40 mad->password = g_strdup( password ); 41 mad->cookie = g_strdup( cookie ); 42 43 mad->callback = func; 44 mad->data = data; 45 46 mad->url = g_strdup( SOAP_AUTHENTICATION_URL ); 47 mad->ttl = 3; /* Max. # of redirects. */ 48 49 /* HTTP-escape stuff and s/,/&/ */ 50 http_decode( mad->cookie ); 51 for( i = 0; mad->cookie[i]; i ++ ) 52 if( mad->cookie[i] == ',' ) 53 mad->cookie[i] = '&'; 54 55 /* Microsoft doesn't allow password longer than 16 chars and silently 56 fails authentication if you give the "full version" of your passwd. */ 57 if( strlen( mad->password ) > MAX_PASSPORT_PWLEN ) 58 mad->password[MAX_PASSPORT_PWLEN] = 0; 59 60 return passport_get_token_real( mad ); 50 61 } 51 62 52 static int passport_get_ id_real( gpointer func, gpointer data, char *header)63 static int passport_get_token_real( struct msn_auth_data *mad ) 53 64 { 54 struct passport_reply *rep; 55 char *server, *dummy, *reqs; 65 char *post_payload, *post_request; 56 66 struct http_request *req; 67 url_t url; 57 68 58 rep = g_new0( struct passport_reply, 1 ); 59 rep->data = data; 60 rep->func = func; 61 rep->header = header; 69 url_set( &url, mad->url ); 62 70 63 server = g_strdup( prd_cached ); 64 dummy = strchr( server, '/' ); 71 post_payload = g_markup_printf_escaped( SOAP_AUTHENTICATION_PAYLOAD, 72 mad->username, 73 mad->password, 74 mad->cookie ); 65 75 66 if( dummy == NULL ) 67 { 68 destroy_reply( rep ); 69 return( 0 ); 70 } 76 post_request = g_strdup_printf( SOAP_AUTHENTICATION_REQUEST, 77 url.file, url.host, 78 (int) strlen( post_payload ), 79 post_payload ); 80 81 req = http_dorequest( url.host, url.port, 1, post_request, 82 passport_get_token_ready, mad ); 71 83 72 reqs = g_strdup_printf( "GET %s HTTP/1.0\r\n%s\r\n\r\n", dummy, header ); 84 g_free( post_request ); 85 g_free( post_payload ); 73 86 74 *dummy = 0; 75 req = http_dorequest( server, 443, 1, reqs, passport_get_id_ready, rep ); 76 77 g_free( server ); 78 g_free( reqs ); 79 80 if( req == NULL ) 81 destroy_reply( rep ); 82 83 return( req != NULL ); 87 return req != NULL; 84 88 } 85 89 86 static void passport_get_id_ready( struct http_request *req ) 90 static xt_status passport_xt_extract_token( struct xt_node *node, gpointer data ); 91 static xt_status passport_xt_handle_fault( struct xt_node *node, gpointer data ); 92 93 static const struct xt_handler_entry passport_xt_handlers[] = { 94 { "wsse:BinarySecurityToken", "wst:RequestedSecurityToken", passport_xt_extract_token }, 95 { "S:Fault", "S:Envelope", passport_xt_handle_fault }, 96 { NULL, NULL, NULL } 97 }; 98 99 static void passport_get_token_ready( struct http_request *req ) 87 100 { 88 struct passport_reply *rep = req->data; 101 struct msn_auth_data *mad = req->data; 102 struct xt_parser *parser; 89 103 90 if( !g_slist_find( msn_connections, rep->data ) ) 104 g_free( mad->url ); 105 g_free( mad->error ); 106 mad->url = mad->error = NULL; 107 108 if( req->status_code == 200 ) 91 109 { 92 destroy_reply( rep ); 93 return; 94 } 95 96 if( req->finished && req->reply_headers && req->status_code == 200 ) 97 { 98 char *dummy; 99 100 if( ( dummy = strstr( req->reply_headers, "from-PP='" ) ) ) 101 { 102 char *responseend; 103 104 dummy += strlen( "from-PP='" ); 105 responseend = strchr( dummy, '\'' ); 106 if( responseend ) 107 *responseend = 0; 108 109 rep->result = g_strdup( dummy ); 110 } 111 else 112 { 113 rep->error_string = g_strdup( "Could not parse Passport server response" ); 114 } 110 parser = xt_new( passport_xt_handlers, mad ); 111 xt_feed( parser, req->reply_body, req->body_size ); 112 xt_handle( parser, NULL, -1 ); 113 xt_free( parser ); 115 114 } 116 115 else 117 116 { 118 rep->error_string = g_strdup_printf( "HTTP error: %s",119 req->status_string ? req->status_string : "Unknown error" );117 mad->error = g_strdup_printf( "HTTP error %d (%s)", req->status_code, 118 req->status_string ? req->status_string : "unknown" ); 120 119 } 121 120 122 rep->func( rep ); 123 destroy_reply( rep ); 121 if( mad->error == NULL && mad->token == NULL ) 122 mad->error = g_strdup( "Could not parse Passport server response" ); 123 124 if( mad->url && mad->token == NULL ) 125 { 126 passport_get_token_real( mad ); 127 } 128 else 129 { 130 mad->callback( mad ); 131 132 g_free( mad->url ); 133 g_free( mad->username ); 134 g_free( mad->password ); 135 g_free( mad->cookie ); 136 g_free( mad->token ); 137 g_free( mad->error ); 138 g_free( mad ); 139 } 124 140 } 125 141 126 static char *passport_create_header( char *cookie, char *email, char *pwd)142 static xt_status passport_xt_extract_token( struct xt_node *node, gpointer data ) 127 143 { 128 char *buffer; 129 char *currenttoken; 130 char *email_enc, *pwd_enc; 144 struct msn_auth_data *mad = data; 145 char *s; 131 146 132 currenttoken = strstr( cookie, "lc=" ); 133 if( currenttoken == NULL ) 134 return NULL; 147 if( ( s = xt_find_attr( node, "Id" ) ) && strcmp( s, "PPToken1" ) == 0 ) 148 mad->token = g_memdup( node->text, node->text_len + 1 ); 135 149 136 email_enc = g_new0( char, strlen( email ) * 3 + 1 ); 137 strcpy( email_enc, email ); 138 http_encode( email_enc ); 139 140 pwd_enc = g_new0( char, strlen( pwd ) * 3 + 1 ); 141 strcpy( pwd_enc, pwd ); 142 http_encode( pwd_enc ); 143 144 buffer = g_strdup_printf( "Authorization: Passport1.4 OrgVerb=GET," 145 "OrgURL=http%%3A%%2F%%2Fmessenger%%2Emsn%%2Ecom," 146 "sign-in=%s,pwd=%s,%s", email_enc, pwd_enc, 147 currenttoken ); 148 149 g_free( email_enc ); 150 g_free( pwd_enc ); 151 152 return buffer; 150 return XT_HANDLED; 153 151 } 154 152 155 static int passport_retrieve_dalogin( gpointer func, gpointer data, char *header)153 static xt_status passport_xt_handle_fault( struct xt_node *node, gpointer data ) 156 154 { 157 struct passport_reply *rep = g_new0( struct passport_reply, 1 ); 158 struct http_request *req; 155 struct msn_auth_data *mad = data; 156 struct xt_node *code = xt_find_node( node->children, "faultcode" ); 157 struct xt_node *string = xt_find_node( node->children, "faultstring" ); 158 struct xt_node *redirect = xt_find_node( node->children, "psf:redirectUrl" ); 159 159 160 rep->data = data; 161 rep->func = func; 162 rep->header = header; 160 if( redirect && redirect->text_len && mad->ttl-- > 0 ) 161 mad->url = g_memdup( redirect->text, redirect->text_len + 1 ); 163 162 164 req = http_dorequest_url( "https://nexus.passport.com/rdr/pprdr.asp", passport_retrieve_dalogin_ready, rep ); 163 if( code == NULL || code->text_len == 0 ) 164 mad->error = g_strdup( "Unknown error" ); 165 else 166 mad->error = g_strdup_printf( "%s (%s)", code->text, string && string->text_len ? 167 string->text : "no description available" ); 165 168 166 if( !req ) 167 destroy_reply( rep ); 168 169 return( req != NULL ); 169 return XT_HANDLED; 170 170 } 171 172 static void passport_retrieve_dalogin_ready( struct http_request *req )173 {174 struct passport_reply *rep = req->data;175 char *dalogin;176 char *urlend;177 178 if( !g_slist_find( msn_connections, rep->data ) )179 {180 destroy_reply( rep );181 return;182 }183 184 if( !req->finished || !req->reply_headers || req->status_code != 200 )185 {186 rep->error_string = g_strdup_printf( "HTTP error while fetching DALogin: %s",187 req->status_string ? req->status_string : "Unknown error" );188 goto failure;189 }190 191 dalogin = strstr( req->reply_headers, "DALogin=" );192 193 if( !dalogin )194 {195 rep->error_string = g_strdup( "Parse error while fetching DALogin" );196 goto failure;197 }198 199 dalogin += strlen( "DALogin=" );200 urlend = strchr( dalogin, ',' );201 if( urlend )202 *urlend = 0;203 204 /* strip the http(s):// part from the url */205 urlend = strstr( urlend, "://" );206 if( urlend )207 dalogin = urlend + strlen( "://" );208 209 if( prd_cached == NULL )210 prd_cached = g_strdup( dalogin );211 212 if( passport_get_id_real( rep->func, rep->data, rep->header ) )213 {214 rep->header = NULL;215 destroy_reply( rep );216 return;217 }218 219 failure:220 rep->func( rep );221 destroy_reply( rep );222 }223 224 static void destroy_reply( struct passport_reply *rep )225 {226 g_free( rep->result );227 g_free( rep->header );228 g_free( rep->error_string );229 g_free( rep );230 } -
protocols/msn/passport.h
r6cac643 rb79308b 1 #ifndef __PASSPORT_H__2 #define __PASSPORT_H__3 1 /* passport.h 4 2 * 5 * Functions to login to Microsoft Passport Service for Messenger 6 * Copyright (C) 2004 Wouter Paesen <wouter@blue-gate.be>, 7 * Wilmer van der Gaast <wilmer@gaast.net> 3 * Functions to login to Microsoft Passport service for Messenger 4 * Copyright (C) 2004-2008 Wilmer van der Gaast <wilmer@gaast.net> 8 5 * 9 6 * This program is free software; you can redistribute it and/or modify … … 18 15 * You should have received a copy of the GNU General Public License 19 16 * along with this program; if not, write to the Free Software 20 * 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 18 */ 19 20 /* Thanks to http://msnpiki.msnfanatic.com/index.php/MSNP13:SOAPTweener 21 for the specs! */ 22 23 #ifndef __PASSPORT_H__ 24 #define __PASSPORT_H__ 22 25 23 26 #include <stdio.h> … … 33 36 #include "nogaim.h" 34 37 35 struct passport_reply 38 #define MAX_PASSPORT_PWLEN 16 39 40 struct msn_auth_data 36 41 { 37 void (*func)( struct passport_reply * ); 38 void *data; 39 char *result; 40 char *header; 41 char *error_string; 42 char *url; 43 int ttl; 44 45 char *username; 46 char *password; 47 char *cookie; 48 49 /* The end result, the only thing we'll really be interested in 50 once finished. */ 51 char *token; 52 char *error; /* Yeah, or that... */ 53 54 void (*callback)( struct msn_auth_data *mad ); 55 gpointer data; 42 56 }; 43 57 44 int passport_get_id( gpointer func, gpointer data, char *username, char *password, char *cookie ); 58 #define SOAP_AUTHENTICATION_URL "https://loginnet.passport.com/RST.srf" 59 60 #define SOAP_AUTHENTICATION_REQUEST \ 61 "POST %s HTTP/1.0\r\n" \ 62 "Accept: text/*\r\n" \ 63 "User-Agent: BitlBee " BITLBEE_VERSION "\r\n" \ 64 "Host: %s\r\n" \ 65 "Content-Length: %d\r\n" \ 66 "Cache-Control: no-cache\r\n" \ 67 "\r\n" \ 68 "%s" 69 70 #define SOAP_AUTHENTICATION_PAYLOAD \ 71 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" \ 72 "<Envelope xmlns=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:wsse=\"http://schemas.xmlsoap.org/ws/2003/06/secext\" xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" xmlns:wsp=\"http://schemas.xmlsoap.org/ws/2002/12/policy\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\" xmlns:wsa=\"http://schemas.xmlsoap.org/ws/2004/03/addressing\" xmlns:wssc=\"http://schemas.xmlsoap.org/ws/2004/04/sc\" xmlns:wst=\"http://schemas.xmlsoap.org/ws/2004/04/trust\">" \ 73 "<Header>" \ 74 "<ps:AuthInfo xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" Id=\"PPAuthInfo\">" \ 75 "<ps:HostingApp>{7108E71A-9926-4FCB-BCC9-9A9D3F32E423}</ps:HostingApp>" \ 76 "<ps:BinaryVersion>4</ps:BinaryVersion>" \ 77 "<ps:UIVersion>1</ps:UIVersion>" \ 78 "<ps:Cookies></ps:Cookies>" \ 79 "<ps:RequestParams>AQAAAAIAAABsYwQAAAAzMDg0</ps:RequestParams>" \ 80 "</ps:AuthInfo>" \ 81 "<wsse:Security>" \ 82 "<wsse:UsernameToken Id=\"user\">" \ 83 "<wsse:Username>%s</wsse:Username>" \ 84 "<wsse:Password>%s</wsse:Password>" \ 85 "</wsse:UsernameToken>" \ 86 "</wsse:Security>" \ 87 "</Header>" \ 88 "<Body>" \ 89 "<ps:RequestMultipleSecurityTokens xmlns:ps=\"http://schemas.microsoft.com/Passport/SoapServices/PPCRL\" Id=\"RSTS\">" \ 90 "<wst:RequestSecurityToken Id=\"RST0\">" \ 91 "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ 92 "<wsp:AppliesTo>" \ 93 "<wsa:EndpointReference>" \ 94 "<wsa:Address>http://Passport.NET/tb</wsa:Address>" \ 95 "</wsa:EndpointReference>" \ 96 "</wsp:AppliesTo>" \ 97 "</wst:RequestSecurityToken>" \ 98 "<wst:RequestSecurityToken Id=\"RST1\">" \ 99 "<wst:RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</wst:RequestType>" \ 100 "<wsp:AppliesTo>" \ 101 "<wsa:EndpointReference>" \ 102 "<wsa:Address>messenger.msn.com</wsa:Address>" \ 103 "</wsa:EndpointReference>" \ 104 "</wsp:AppliesTo>" \ 105 "<wsse:PolicyReference URI=\"?%s\"></wsse:PolicyReference>" \ 106 "</wst:RequestSecurityToken>" \ 107 "</ps:RequestMultipleSecurityTokens>" \ 108 "</Body>" \ 109 "</Envelope>" 110 111 int passport_get_token( gpointer func, gpointer data, char *username, char *password, char *cookie ); 45 112 46 113 #endif /* __PASSPORT_H__ */ -
protocols/nogaim.c
r6cac643 rb79308b 343 343 /* dialogs.c */ 344 344 345 void imcb_ask( struct im_connection *ic, char *msg, void *data, void *doit, void *dont ) 345 void imcb_ask( struct im_connection *ic, char *msg, void *data, 346 query_callback doit, query_callback dont ) 346 347 { 347 348 query_add( ic->irc, ic, msg, doit, dont, data ); … … 495 496 }; 496 497 497 void show_got_added_no( gpointer w, struct show_got_added_data*data )498 { 499 g_free( data->handle );498 void show_got_added_no( void *data ) 499 { 500 g_free( ((struct show_got_added_data*)data)->handle ); 500 501 g_free( data ); 501 502 } 502 503 503 void show_got_added_yes( gpointer w, struct show_got_added_data *data ) 504 { 505 data->ic->acc->prpl->add_buddy( data->ic, data->handle, NULL ); 506 /* imcb_add_buddy( data->ic, NULL, data->handle, data->handle ); */ 507 508 return show_got_added_no( w, data ); 504 void show_got_added_yes( void *data ) 505 { 506 struct show_got_added_data *sga = data; 507 508 sga->ic->acc->prpl->add_buddy( sga->ic, sga->handle, NULL ); 509 /* imcb_add_buddy( sga->ic, NULL, sga->handle, sga->handle ); */ 510 511 return show_got_added_no( data ); 509 512 } 510 513 -
protocols/nogaim.h
r6cac643 rb79308b 42 42 #include "account.h" 43 43 #include "proxy.h" 44 #include "query.h" 44 45 #include "md5.h" 45 46 #include "ft.h" … … 265 266 * - 'doit' or 'dont' will be called depending of the answer of the user. 266 267 */ 267 G_MODULE_EXPORT void imcb_ask( struct im_connection *ic, char *msg, void *data, void *doit, void *dont );268 G_MODULE_EXPORT void imcb_ask( struct im_connection *ic, char *msg, void *data, query_callback doit, query_callback dont ); 268 269 G_MODULE_EXPORT void imcb_ask_add( struct im_connection *ic, char *handle, const char *realname ); 269 270 -
protocols/oscar/Makefile
r6cac643 rb79308b 18 18 all: oscar_mod.o 19 19 check: all 20 lcov: 20 lcov: check 21 21 gcov: 22 22 gcov *.c -
protocols/oscar/oscar.c
r6cac643 rb79308b 1084 1084 } 1085 1085 1086 void oscar_accept_chat( gpointer w, struct aim_chat_invitation * inv);1087 void oscar_reject_chat( gpointer w, struct aim_chat_invitation * inv);1086 void oscar_accept_chat(void *data); 1087 void oscar_reject_chat(void *data); 1088 1088 1089 1089 static int incomingim_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args) { … … 1119 1119 } 1120 1120 1121 static void gaim_icq_authgrant(gpointer w, struct icq_auth *data) { 1121 static void gaim_icq_authgrant(void *data_) { 1122 struct icq_auth *data = data_; 1122 1123 char *uin, message; 1123 1124 struct oscar_data *od = (struct oscar_data *)data->ic->proto_data; … … 1134 1135 } 1135 1136 1136 static void gaim_icq_authdeny(gpointer w, struct icq_auth *data) { 1137 static void gaim_icq_authdeny(void *data_) { 1138 struct icq_auth *data = data_; 1137 1139 char *uin, *message; 1138 1140 struct oscar_data *od = (struct oscar_data *)data->ic->proto_data; … … 2588 2590 } 2589 2591 2590 void oscar_accept_chat( gpointer w, struct aim_chat_invitation * inv)2592 void oscar_accept_chat(void *data) 2591 2593 { 2594 struct aim_chat_invitation * inv = data; 2595 2592 2596 oscar_chat_join(inv->ic, inv->name, NULL, NULL); 2593 2597 g_free(inv->name); … … 2595 2599 } 2596 2600 2597 void oscar_reject_chat( gpointer w, struct aim_chat_invitation * inv)2601 void oscar_reject_chat(void *data) 2598 2602 { 2603 struct aim_chat_invitation * inv = data; 2604 2599 2605 g_free(inv->name); 2600 2606 g_free(inv); -
protocols/yahoo/Makefile
r6cac643 rb79308b 18 18 all: yahoo_mod.o 19 19 check: all 20 lcov: 20 lcov: check 21 21 gcov: 22 22 gcov *.c -
protocols/yahoo/libyahoo2.c
r6cac643 rb79308b 737 737 738 738 memcpy(data + pos, "YMSG", 4); pos += 4; 739 pos += yahoo_put16(data + pos, 0x0 a00);739 pos += yahoo_put16(data + pos, 0x000c); 740 740 pos += yahoo_put16(data + pos, 0x0000); 741 741 pos += yahoo_put16(data + pos, pktlen + extra_pad); … … 3351 3351 break; 3352 3352 case 5: 3353 if( cp != "\005")3353 if(strcmp(cp, "5") != 0) 3354 3354 yct->location = cp; 3355 3355 k = 0; -
protocols/yahoo/yahoo.c
r6cac643 rb79308b 315 315 struct byahoo_data *yd = (struct byahoo_data *) c->ic->proto_data; 316 316 317 yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg );317 yahoo_conference_invite( yd->y2_id, NULL, c->data, c->title, msg ? msg : "" ); 318 318 } 319 319 … … 797 797 } 798 798 799 static void byahoo_accept_conf( gpointer w, struct byahoo_conf_invitation *inv ) 800 { 799 static void byahoo_accept_conf( void *data ) 800 { 801 struct byahoo_conf_invitation *inv = data; 802 801 803 yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name ); 802 804 imcb_chat_add_buddy( inv->c, inv->ic->acc->user ); … … 805 807 } 806 808 807 static void byahoo_reject_conf( gpointer w, struct byahoo_conf_invitation *inv ) 808 { 809 static void byahoo_reject_conf( void *data ) 810 { 811 struct byahoo_conf_invitation *inv = data; 812 809 813 yahoo_conference_decline( inv->yid, NULL, inv->members, inv->name, "User rejected groupchat" ); 810 814 imcb_chat_free( inv->c ); -
query.c
r6cac643 rb79308b 30 30 static query_t *query_default( irc_t *irc ); 31 31 32 query_t *query_add( irc_t *irc, struct im_connection *ic, char *question, void *yes, void *no, void *data ) 32 query_t *query_add( irc_t *irc, struct im_connection *ic, char *question, 33 query_callback yes, query_callback no, void *data ) 33 34 { 34 35 query_t *q = g_new0( query_t, 1 ); … … 140 141 if( ans ) 141 142 { 142 imcb_log( q->ic, "Accepted: %s", q->question ); 143 q->yes( NULL, q->data ); 143 if( q->ic ) 144 imcb_log( q->ic, "Accepted: %s", q->question ); 145 else 146 irc_usermsg( irc, "Accepted: %s", q->question ); 147 q->yes( q->data ); 144 148 } 145 149 else 146 150 { 147 imcb_log( q->ic, "Rejected: %s", q->question ); 148 q->no( NULL, q->data ); 151 if( q->ic ) 152 imcb_log( q->ic, "Rejected: %s", q->question ); 153 else 154 irc_usermsg( irc, "Rejected: %s", q->question ); 155 q->no( q->data ); 149 156 } 150 157 q->data = NULL; -
query.h
r6cac643 rb79308b 27 27 #define _QUERY_H 28 28 29 typedef void (*query_callback) ( void *data ); 30 29 31 typedef struct query 30 32 { 31 33 struct im_connection *ic; 32 34 char *question; 33 void (* yes) ( gpointer w, void *data ); 34 void (* no) ( gpointer w, void *data ); 35 query_callback yes, no; 35 36 void *data; 36 37 struct query *next; 37 38 } query_t; 38 39 39 query_t *query_add( irc_t *irc, struct im_connection *ic, char *question, void *yes, void *no, void *data ); 40 query_t *query_add( irc_t *irc, struct im_connection *ic, char *question, 41 query_callback yes, query_callback no, void *data ); 40 42 void query_del( irc_t *irc, query_t *q ); 41 43 void query_del_by_conn( irc_t *irc, struct im_connection *ic ); -
root_commands.c
r6cac643 rb79308b 204 204 } 205 205 206 struct cmd_account_del_data 207 { 208 account_t *a; 209 irc_t *irc; 210 }; 211 212 void cmd_account_del_yes( void *data ) 213 { 214 struct cmd_account_del_data *cad = data; 215 account_t *a; 216 217 for( a = cad->irc->accounts; a && a != cad->a; a = a->next ); 218 219 if( a == NULL ) 220 { 221 irc_usermsg( cad->irc, "Account already deleted" ); 222 } 223 else if( a->ic ) 224 { 225 irc_usermsg( cad->irc, "Account is still logged in, can't delete" ); 226 } 227 else 228 { 229 account_del( cad->irc, a ); 230 irc_usermsg( cad->irc, "Account deleted" ); 231 } 232 g_free( data ); 233 } 234 235 void cmd_account_del_no( void *data ) 236 { 237 g_free( data ); 238 } 239 206 240 static void cmd_account( irc_t *irc, char **cmd ) 207 241 { … … 258 292 else 259 293 { 260 account_del( irc, a ); 261 irc_usermsg( irc, "Account deleted" ); 294 struct cmd_account_del_data *cad; 295 char *msg; 296 297 cad = g_malloc( sizeof( struct cmd_account_del_data ) ); 298 cad->a = a; 299 cad->irc = irc; 300 301 msg = g_strdup_printf( "If you remove this account (%s(%s)), BitlBee will " 302 "also forget all your saved nicknames. If you want " 303 "to change your username/password, use the `account " 304 "set' command. Are you sure you want to delete this " 305 "account?", a->prpl->name, a->user ); 306 query_add( irc, NULL, msg, cmd_account_del_yes, cmd_account_del_no, cad ); 307 g_free( msg ); 262 308 } 263 309 } … … 557 603 g_free( irc->mynick ); 558 604 irc->mynick = g_strdup( cmd[2] ); 605 606 if( strcmp( cmd[0], "set_rename" ) != 0 ) 607 set_setstr( &irc->set, "root_nick", cmd[2] ); 559 608 } 560 609 else if( u->send_handler == buddy_send_handler ) … … 565 614 irc_usermsg( irc, "Nick successfully changed" ); 566 615 } 616 } 617 618 char *set_eval_root_nick( set_t *set, char *new_nick ) 619 { 620 irc_t *irc = set->data; 621 622 if( strcmp( irc->mynick, new_nick ) != 0 ) 623 { 624 char *cmd[] = { "set_rename", irc->mynick, new_nick, NULL }; 625 626 cmd_rename( irc, cmd ); 627 } 628 629 return strcmp( irc->mynick, new_nick ) == 0 ? new_nick : NULL; 567 630 } 568 631 … … 769 832 else 770 833 irc_usermsg( irc, "%s is empty", set_name ); 834 835 if( strchr( set_name, '/' ) ) 836 irc_usermsg( irc, "Warning: / found in setting name, you're probably looking for the `account set' command." ); 771 837 } 772 838 else -
set.c
r6cac643 rb79308b 230 230 return value; 231 231 } 232 233 char *set_eval_charset( set_t *set, char *value )234 {235 GIConv cd;236 237 if ( g_strncasecmp( value, "none", 4 ) == 0 )238 return value;239 240 cd = g_iconv_open( "UTF-8", value );241 if( cd == (GIConv) -1 )242 return NULL;243 244 g_iconv_close( cd );245 return value;246 } -
set.h
r6cac643 rb79308b 97 97 char *set_eval_to_char( set_t *set, char *value ); 98 98 char *set_eval_ops( set_t *set, char *value ); 99 char *set_eval_charset( set_t *set, char *value );100 99 101 100 #endif /* __SET_H__ */ -
storage_xml.c
r6cac643 rb79308b 80 80 char *nick = xml_attr( attr_names, attr_values, "nick" ); 81 81 char *pass = xml_attr( attr_names, attr_values, "password" ); 82 md5_byte_t *pass_dec = NULL;82 int st; 83 83 84 84 if( !nick || !pass ) … … 87 87 "Missing attributes for %s element", element_name ); 88 88 } 89 else if( base64_decode( pass, &pass_dec ) != 21 ) 90 { 89 else if( ( st = md5_verify_password( xd->given_pass, pass ) ) == -1 ) 90 { 91 xd->pass_st = XML_PASS_WRONG; 91 92 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, 92 93 "Error while decoding password attribute" ); 93 94 } 95 else if( st == 0 ) 96 { 97 if( xd->pass_st != XML_PASS_CHECK_ONLY ) 98 xd->pass_st = XML_PASS_OK; 99 } 94 100 else 95 101 { 96 md5_byte_t pass_md5[16]; 97 md5_state_t md5_state; 98 int i; 99 100 md5_init( &md5_state ); 101 md5_append( &md5_state, (md5_byte_t*) xd->given_pass, strlen( xd->given_pass ) ); 102 md5_append( &md5_state, (md5_byte_t*) pass_dec + 16, 5 ); /* Hmmm, salt! */ 103 md5_finish( &md5_state, pass_md5 ); 104 105 for( i = 0; i < 16; i ++ ) 106 { 107 if( pass_dec[i] != pass_md5[i] ) 108 { 109 xd->pass_st = XML_PASS_WRONG; 110 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, 111 "Password mismatch" ); 112 break; 113 } 114 } 115 116 /* If we reached the end of the loop, it was a match! */ 117 if( i == 16 ) 118 { 119 if( xd->pass_st != XML_PASS_CHECK_ONLY ) 120 xd->pass_st = XML_PASS_OK; 121 } 122 } 123 124 g_free( pass_dec ); 102 xd->pass_st = XML_PASS_WRONG; 103 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, 104 "Password mismatch" ); 105 } 125 106 } 126 107 else if( xd->pass_st < XML_PASS_OK ) … … 428 409 int pass_len; 429 410 430 pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password );411 pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password, 12 ); 431 412 pass_b64 = base64_encode( pass_cr, pass_len ); 432 413 g_free( pass_cr ); -
tests/Makefile
r6cac643 rb79308b 11 11 distclean: clean 12 12 13 main_objs = account.o bitlbee.o conf.o crypting.o help.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o storage_text.o user.o 13 main_objs = account.o bitlbee.o conf.o crypting.o help.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o storage_xml.o storage_text.o user.o 14 14 15 test_objs = check.o check_util.o check_nick.o check_md5.o check_arc.o check_irc.o check_help.o check_user.o check_crypting.o check_set.o 15 test_objs = check.o check_util.o check_nick.o check_md5.o check_arc.o check_irc.o check_help.o check_user.o check_crypting.o check_set.o check_jabber_sasl.o 16 16 17 17 check: $(test_objs) $(addprefix ../, $(main_objs)) ../protocols/protocols.o ../lib/lib.o -
tests/check.c
r6cac643 rb79308b 66 66 Suite *set_suite(void); 67 67 68 /* From check_jabber_sasl.c */ 69 Suite *jabber_sasl_suite(void); 70 68 71 int main (int argc, char **argv) 69 72 { … … 111 114 srunner_add_suite(sr, crypting_suite()); 112 115 srunner_add_suite(sr, set_suite()); 116 srunner_add_suite(sr, jabber_sasl_suite()); 113 117 if (no_fork) 114 118 srunner_set_fork_status(sr, CK_NOFORK); -
tests/check_arc.c
r6cac643 rb79308b 7 7 #include "arc.h" 8 8 9 char *password = " TotT";9 char *password = "ArcVier"; 10 10 11 11 char *clear_tests[] = … … 14 14 "ItllBeBitlBee", 15 15 "One more boring password", 16 "Hoi hoi", 16 17 NULL 17 18 }; … … 28 29 int len; 29 30 30 len = arc_encode( clear_tests[i], 0, &crypted, password );31 len = arc_encode( clear_tests[i], 0, &crypted, password, 12 ); 31 32 len = arc_decode( crypted, len, &decrypted, password ); 32 33 … … 41 42 struct 42 43 { 43 unsigned char crypted[ 24];44 unsigned char crypted[30]; 44 45 int len; 45 46 char *decrypted; 46 47 } decrypt_tests[] = { 48 /* One block with padding. */ 47 49 { 48 50 { 49 0x c3, 0x0d, 0x43, 0xc3, 0xee, 0x80, 0xe2, 0x8c, 0x0b, 0x29, 0x32, 0x7e,50 0x 38, 0x05, 0x82, 0x10, 0x21, 0x1c, 0x4a, 0x00, 0x2c51 }, 21, "Debugging sucks"51 0x3f, 0x79, 0xb0, 0xf5, 0x91, 0x56, 0xd2, 0x1b, 0xd1, 0x4b, 0x67, 0xac, 52 0xb1, 0x31, 0xc9, 0xdb, 0xf9, 0xaa 53 }, 18, "short pass" 52 54 }, 55 56 /* Two blocks with padding. */ 53 57 { 54 58 { 55 0xb0, 0x00, 0x57, 0x0d, 0x0d, 0x0d, 0x70, 0xe1, 0xc0, 0x00, 0xa4, 0x25, 56 0x7d, 0xbe, 0x03, 0xcc, 0x24, 0xd1, 0x0c 57 }, 19, "Testing rocks" 59 0xf9, 0xa6, 0xec, 0x5d, 0xc7, 0x06, 0xb8, 0x6b, 0x63, 0x9f, 0x2d, 0xb5, 60 0x7d, 0xaa, 0x32, 0xbb, 0xd8, 0x08, 0xfd, 0x81, 0x2e, 0xca, 0xb4, 0xd7, 61 0x2f, 0x36, 0x9c, 0xac, 0xa0, 0xbc 62 }, 30, "longer password" 58 63 }, 64 65 /* This string is exactly two "blocks" long, to make sure unpadded strings also decrypt 66 properly. */ 59 67 { 60 68 { 61 0xb6, 0x92, 0x59, 0xe4, 0xf9, 0xc1, 0x7a, 0xf6, 0xf3, 0x18, 0xea, 0x28, 62 0x73, 0x6d, 0xb3, 0x0a, 0x6f, 0x0a, 0x2b, 0x43, 0x57, 0xe9, 0x3e, 0x63 63 }, 24, "OSCAR is creepy..." 64 } 69 0x95, 0x4d, 0xcf, 0x4d, 0x5e, 0x6c, 0xcf, 0xef, 0xb9, 0x80, 0x00, 0xef, 70 0x25, 0xe9, 0x17, 0xf6, 0x29, 0x6a, 0x82, 0x79, 0x1c, 0xca, 0x68, 0xb5, 71 0x4e, 0xd0, 0xc1, 0x41, 0x8e, 0xe6 72 }, 30, "OSCAR is really creepy.." 73 }, 74 { "", 0, NULL } 65 75 }; 66 76 … … 69 79 int i; 70 80 71 for( i = 0; clear_tests[i]; i++ )81 for( i = 0; decrypt_tests[i].len; i++ ) 72 82 { 73 83 tcase_fn_start (decrypt_tests[i].decrypted, __FILE__, __LINE__); … … 79 89 80 90 fail_if( strcmp( decrypt_tests[i].decrypted, decrypted ) != 0, 81 " %s didn't decrypt properly", clear_tests[i]);91 "`%s' didn't decrypt properly", decrypt_tests[i].decrypted ); 82 92 83 93 g_free( decrypted ); -
tests/check_help.c
r6cac643 rb79308b 7 7 #include "help.h" 8 8 9 START_TEST(test_help_ none)9 START_TEST(test_help_initfree) 10 10 help_t *h, *r; 11 11 r = help_init(&h, "/dev/null"); 12 12 fail_if(r == NULL); 13 13 fail_if(r != h); 14 15 help_free(&h); 16 fail_if(h != NULL); 14 17 END_TEST 15 18 … … 25 28 TCase *tc_core = tcase_create("Core"); 26 29 suite_add_tcase (s, tc_core); 27 tcase_add_test (tc_core, test_help_ none);30 tcase_add_test (tc_core, test_help_initfree); 28 31 tcase_add_test (tc_core, test_help_nonexistent); 29 32 return s; -
tests/check_irc.c
r6cac643 rb79308b 37 37 irc = irc_new(g_io_channel_unix_get_fd(ch1)); 38 38 39 fail_unless(g_io_channel_write_chars(ch2, "NICK bla\r\ n"40 "USER a a a a\ r\n", -1, NULL, NULL) == G_IO_STATUS_NORMAL);39 fail_unless(g_io_channel_write_chars(ch2, "NICK bla\r\r\n" 40 "USER a a a a\n", -1, NULL, NULL) == G_IO_STATUS_NORMAL); 41 41 fail_unless(g_io_channel_flush(ch2, NULL) == G_IO_STATUS_NORMAL); 42 42
Note: See TracChangeset
for help on using the changeset viewer.