Changeset 2288705
- Timestamp:
- 2009-12-07T21:54:19Z (15 years ago)
- Branches:
- master
- Children:
- 1c3008a
- Parents:
- aac4017 (diff), 36cf9fd (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
- 55 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
raac4017 r2288705 10 10 11 11 # Program variables 12 objects = account.o bitlbee.o c rypting.o help.o ipc.o irc.o irc_commands.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) user.o dcc.o13 headers = account.h bitlbee.h commands.h conf.h config.h crypting.h help.h ipc.h irc.h log.h nick.h query.h set.h sock.h storage.h user.h lib/events.h lib/ http_client.h lib/ini.h lib/md5.h lib/misc.h lib/proxy.h lib/sha1.h lib/ssl_client.h lib/url.h protocols/nogaim.h protocols/ft.h lib/ftutil.h12 objects = account.o bitlbee.o chat.o crypting.o dcc.o help.o ipc.o irc.o irc_commands.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) user.o 13 headers = account.h bitlbee.h commands.h conf.h config.h crypting.h help.h ipc.h irc.h log.h nick.h query.h set.h sock.h storage.h user.h lib/events.h lib/ftutil.h lib/http_client.h lib/ini.h lib/md5.h lib/misc.h lib/proxy.h lib/sha1.h lib/ssl_client.h lib/url.h protocols/ft.h protocols/nogaim.h 14 14 subdirs = lib protocols 15 15 … … 105 105 x=$$(basename $$(pwd)); \ 106 106 cd ..; \ 107 tar czf $$x.tar.gz --exclude=debian --exclude=.bzr $$x107 tar czf $$x.tar.gz --exclude=debian --exclude=.bzr* $$x 108 108 109 109 $(subdirs): -
account.c
raac4017 r2288705 27 27 #include "bitlbee.h" 28 28 #include "account.h" 29 #include "chat.h" 29 30 30 31 account_t *account_add( irc_t *irc, struct prpl *prpl, char *user, char *pass ) … … 55 56 56 57 s = set_add( &a->set, "password", NULL, set_eval_account, a ); 57 s->flags |= ACC_SET_NOSAVE ;58 s->flags |= ACC_SET_NOSAVE | SET_NULL_OK; 58 59 59 60 s = set_add( &a->set, "username", NULL, set_eval_account, a ); … … 77 78 /* Double-check: We refuse to edit on-line accounts. */ 78 79 if( set->flags & ACC_SET_OFFLINE_ONLY && acc->ic ) 79 return NULL; 80 81 if( strcmp( set->key, "username" ) == 0 ) 80 return SET_INVALID; 81 82 if( strcmp( set->key, "server" ) == 0 ) 83 { 84 g_free( acc->server ); 85 if( value && *value ) 86 { 87 acc->server = g_strdup( value ); 88 return value; 89 } 90 else 91 { 92 acc->server = g_strdup( set->def ); 93 return g_strdup( set->def ); 94 } 95 } 96 else if( strcmp( set->key, "username" ) == 0 ) 82 97 { 83 98 g_free( acc->user ); … … 87 102 else if( strcmp( set->key, "password" ) == 0 ) 88 103 { 89 g_free( acc->pass ); 90 acc->pass = g_strdup( value ); 91 return NULL; /* password shouldn't be visible in plaintext! */ 92 } 93 else if( strcmp( set->key, "server" ) == 0 ) 94 { 95 g_free( acc->server ); 96 if( *value ) 97 { 98 acc->server = g_strdup( value ); 99 return value; 104 if( value ) 105 { 106 g_free( acc->pass ); 107 acc->pass = g_strdup( value ); 108 return NULL; /* password shouldn't be visible in plaintext! */ 100 109 } 101 110 else 102 111 { 103 acc->server = NULL; 104 return g_strdup( set->def ); 112 /* NULL can (should) be stored in the set_t 113 variable, but is otherwise not correct. */ 114 return SET_INVALID; 105 115 } 106 116 } … … 108 118 { 109 119 if( !is_bool( value ) ) 110 return NULL;120 return SET_INVALID; 111 121 112 122 acc->auto_connect = bool2int( value ); … … 114 124 } 115 125 116 return NULL;126 return SET_INVALID; 117 127 } 118 128 … … 181 191 { 182 192 account_t *a, *l = NULL; 193 struct chat *c, *nc; 183 194 184 195 if( acc->ic ) … … 193 204 else 194 205 irc->accounts = a->next; 206 207 for( c = irc->chatrooms; c; c = nc ) 208 { 209 nc = c->next; 210 if( acc == c->acc ) 211 chat_del( irc, c ); 212 } 195 213 196 214 while( a->set ) … … 254 272 255 273 /* Sure, call me evil for implementing my own fscanf here, but it's 256 dead simple and I 'm immediately at the next part to parse. */274 dead simple and I immediately know where to continue parsing. */ 257 275 258 276 if( *value == 0 ) … … 287 305 struct account_reconnect_delay p; 288 306 289 return account_reconnect_delay_parse( value, &p ) ? value : NULL;307 return account_reconnect_delay_parse( value, &p ) ? value : SET_INVALID; 290 308 } 291 309 -
account.h
raac4017 r2288705 56 56 int account_reconnect_delay( account_t *a ); 57 57 58 #define ACC_SET_NOSAVE 159 #define ACC_SET_OFFLINE_ONLY 260 #define ACC_SET_ONLINE_ONLY 458 #define ACC_SET_NOSAVE 0x01 59 #define ACC_SET_OFFLINE_ONLY 0x02 60 #define ACC_SET_ONLINE_ONLY 0x04 61 61 62 62 #endif -
bitlbee.h
raac4017 r2288705 33 33 34 34 #define PACKAGE "BitlBee" 35 #define BITLBEE_VERSION "1.2. 1"35 #define BITLBEE_VERSION "1.2.4" 36 36 #define VERSION BITLBEE_VERSION 37 37 -
conf.c
raac4017 r2288705 335 335 else 336 336 { 337 fprintf( stderr, "Error: Unknown setting `%s` in configuration file .\n", ini->key);337 fprintf( stderr, "Error: Unknown setting `%s` in configuration file (line %d).\n", ini->key, ini->line ); 338 338 return 0; 339 339 /* For now just ignore unknown keys... */ … … 342 342 else if( g_strcasecmp( ini->section, "defaults" ) != 0 ) 343 343 { 344 fprintf( stderr, "Error: Unknown section [%s] in configuration file . "345 "BitlBee configuration must be put in a [settings] section!\n", ini->section );344 fprintf( stderr, "Error: Unknown section [%s] in configuration file (line %d). " 345 "BitlBee configuration must be put in a [settings] section!\n", ini->section, ini->line ); 346 346 return 0; 347 347 } -
configure
raac4017 r2288705 267 267 detect_ldap() 268 268 { 269 TMPFILE= `mktemp`269 TMPFILE=$(mktemp) 270 270 if $CC -o $TMPFILE -shared -lldap 2>/dev/null >/dev/null; then 271 271 cat<<EOF>>Makefile.settings … … 280 280 ret=0 281 281 fi 282 } 283 284 RESOLV_TESTCODE=' 285 #include <arpa/nameser.h> 286 #include <resolv.h> 287 288 int main() 289 { 290 ns_initparse( NULL, 0, NULL ); 291 ns_parserr( NULL, ns_s_an, 0, NULL ); 292 } 293 ' 294 295 detect_resolv_dynamic() 296 { 297 echo "$RESOLV_TESTCODE" | $CC -o /dev/null -x c - -lresolv >/dev/null 2>/dev/null 298 if [ "$?" = "0" ]; then 299 echo 'EFLAGS+=-lresolv' >> Makefile.settings 300 return 0 301 fi 302 303 return 1 304 } 305 306 detect_resolv_static() 307 { 308 for i in $systemlibdirs; do 309 if [ -f $i/libresolv.a ]; then 310 echo "$RESOLV_TESTCODE" | $CC -o /dev/null -x c - -Wl,$i/libresolv.a >/dev/null 2>/dev/null 311 if [ "$?" = "0" ]; then 312 echo 'EFLAGS+='$i'/libresolv.a' >> Makefile.settings 313 return 0 314 fi 315 fi 316 done 317 318 return 1 282 319 } 283 320 … … 349 386 echo 'SSL_CLIENT=ssl_'$ssl'.o' >> Makefile.settings 350 387 351 for i in $systemlibdirs; do 352 if [ -f $i/libresolv.a ]; then 353 echo '#define HAVE_RESOLV_A' >> config.h 354 echo 'EFLAGS+='$i'/libresolv.a' >> Makefile.settings 355 break 356 fi 357 done 388 if detect_resolv_dynamic || detect_resolv_static; then 389 echo '#define HAVE_RESOLV_A' >> config.h 390 fi 358 391 359 392 STORAGES="text xml" -
debian/bitlbee.init
raac4017 r2288705 32 32 fi 33 33 34 [ "$BITLBEE_DISABLED" = "1" ] && exit 035 36 34 37 35 # … … 41 39 # Make sure BitlBee can actually write its PID... 42 40 touch /var/run/bitlbee.pid 43 chown bitlbee /var/run/bitlbee.pid41 chown bitlbee: /var/run/bitlbee.pid 44 42 45 start-stop-daemon --start --quiet --pidfile $PIDFILE \ 43 # Clean up after the bug between 1.2-5 and 1.2.1-2 where BitlBee ran 44 # as root. (#494656 and #495877) Fixing this in the postinst script 45 # is not enough since the user will restart his BitlBee after up- 46 # grading the package, and the BitlBee running as root will then 47 # save its settings, re-setting ownership of the file to root. 48 # TODO: Remove this after a few revisions. 49 find /var/lib/bitlbee -uid 0 -name '*.xml' -exec chown bitlbee: {} \; 50 51 start-stop-daemon --start --quiet \ 46 52 --exec $DAEMON -- -p $BITLBEE_PORT -P $PIDFILE $BITLBEE_OPTS 47 53 } … … 58 64 case "$1" in 59 65 start) 66 [ "$BITLBEE_DISABLED" = "1" ] && exit 0 67 60 68 echo -n "Starting $DESC: $NAME" 61 69 d_start -
debian/changelog
raac4017 r2288705 1 bitlbee (1.2-6) UNRELEASED; urgency=low 2 3 * Add Homepage and Vcs-Bzr fields. 4 5 -- Jelmer Vernooij <jelmer@samba.org> Sun, 11 May 2008 14:18:16 +0200 1 bitlbee (1.2.2-1) unstable; urgency=critical 2 3 * New upstream version. 4 * Fixes a security issue (account hijacking), hence the high priority. 5 * Using a patch to set the User setting in bitlbee.conf properly to keep 6 upstream and Debian properly separated in my bzr tree. 7 8 -- Wilmer van der Gaast <wilmer@gaast.net> Wed, 27 Aug 2008 23:59:50 +0100 9 10 bitlbee (1.2.1-3) unstable; urgency=high 11 12 * chown /var/lib/bitlbee/*.xml to bitlbee:bitlbee to clean up after 13 1.2-5 and the bugfix in 1.2.1-2. (Closes: #495877) 14 * Moved BITLBEE_DISABLED check to only check when trying to *start* 15 the daemon. (Closes: #488611) 16 17 -- Wilmer van der Gaast <wilmer@gaast.net> Sat, 23 Aug 2008 18:53:54 +0100 18 19 bitlbee (1.2.1-2) unstable; urgency=low 20 21 * Properly set the User= line to something sensible so BitlBee won't 22 run as root anymore. 1.2-5 was a bad upload. :-( (Closes: #494656) 23 24 -- Wilmer van der Gaast <wilmer@gaast.net> Tue, 12 Aug 2008 00:36:03 +0100 25 26 bitlbee (1.2.1-1.1) unstable; urgency=low 27 28 * Non-Maintainer Upload 29 * Use invoke-rc.d as per policy. (Closes: #492637) [Thanks to Matt 30 Kraai] 31 32 -- Don Armstrong <don@debian.org> Wed, 06 Aug 2008 06:57:18 -0700 33 34 bitlbee (1.2.1-1) unstable; urgency=low 35 36 * New upstream release. 37 * Add Homepage and Vcs-Bzr fields. (From Jelmer.) 38 39 -- Wilmer van der Gaast <wilmer@gaast.net> Thu, 26 Jun 2008 00:07:50 +0100 6 40 7 41 bitlbee (1.2-5) unstable; urgency=low -
debian/postinst
raac4017 r2288705 64 64 fi 65 65 66 if ! grep -qi '^User *= *' /etc/bitlbee/bitlbee.conf; then 67 echo 'Updating configuration file, enabling User-setting...' 68 if ! sed -i -e 's/# *User *= *.*/User = bitlbee/i' /etc/bitlbee/bitlbee.conf; then 69 echo 'Failed! BitlBee may run as root now, please check your configs.' 70 fi 71 fi 72 66 73 if [ -n "$2" -a "$BITLBEE_UPGRADE_DONT_RESTART" != "1" ]; then 67 /etc/init.d/bitlbee restart 74 if which invoke-rc.d >/dev/null 2>&1; then 75 invoke-rc.d bitlbee restart 76 else 77 /etc/init.d/bitlbee restart 78 fi 68 79 fi 69 80 70 81 ## If we're upgrading, we'll probably skip this next part 71 if [ -d $CONFDIR ] && chown -R bitlbee $CONFDIR; then82 if [ -d $CONFDIR ] && chown -R bitlbee: $CONFDIR; then 72 83 echo 'BitlBee (probably) already installed, skipping user/configdir installation' 73 84 exit 0 … … 91 102 92 103 if [ -z "$2" ]; then 93 /etc/init.d/bitlbee start 104 if which invoke-rc.d >/dev/null 2>&1; then 105 invoke-rc.d bitlbee start 106 else 107 /etc/init.d/bitlbee start 108 fi 94 109 fi -
debian/prerm
raac4017 r2288705 10 10 fi 11 11 else 12 /etc/init.d/bitlbee stop || exit 0 12 if which invoke-rc.d >/dev/null 2>&1; then 13 invoke-rc.d bitblee stop || exit 0 14 else 15 /etc/init.d/bitlbee stop || exit 0 16 fi 13 17 fi -
debian/rules
raac4017 r2288705 55 55 cp utils/* debian/bitlbee/usr/share/doc/bitlbee/examples/ 56 56 cp debian/bitlbee.init debian/bitlbee/etc/init.d/bitlbee 57 patch -p0 < debian/patches/bitlbee.conf.diff 57 58 cd debian/bitlbee/usr/share/; \ 58 59 gzip -9 doc/bitlbee/changelog.Debian doc/bitlbee/changelog doc/bitlbee/user-guide.txt \ -
doc/CHANGES
raac4017 r2288705 3 3 4 4 http://bugs.bitlbee.org/bitlbee/timeline?daysback=90&changeset=on 5 6 Version 1.2.4: 7 - Most important change (and main reason for releasing now): Upgraded Yahoo! 8 module to a newer version to get it working again. 9 - join_chat command replaced with the much better chat command: 10 * Similar to how account replaced login/slist/logout. Add a chatroom once, 11 then just /join it like any other room. Also automatic joining at login 12 time is now possible. 13 * Note that the old way of starting groupchats (/join #nickname) is now 14 also deprecated, use "chat with" instead. 15 * See "help chat" and "help chat add" for more information. 16 - Rewrote bitlbee.conf parser to be less dumb. 17 - Fixed compatibility (hopefully) with AIM mobile messages, certain kinds 18 of Google Talk chatrooms. 19 - Fixed numerous stability/reliability bugs over the last year. 20 21 Finished 17 Oct 2009 22 23 Version 1.2.3: 24 - Fixed one more flaw similar to the previous hijacking bug, caused by incon- 25 sistent handling of the USTATUS_IDENTIFIED state. All code touching these 26 variables was reviewed and should be correct now. 27 28 Finished 7 Sep 2008 29 30 Version 1.2.2: 31 - Security bugfix: It was possible to hijack accounts (without gaining access 32 to the old account, it's simply an overwrite) 33 - Some more stability improvements. 34 - Fixed bug where people with non-lowercase nicks couldn't drop their account. 35 - Easier upgrades of non-forking daemon mode servers (using the DEAF 36 command). 37 - Can be cross-compiled for Win32 now! (No support for SSL yet though, which 38 makes it less useful for now.) 39 - Exponential backoff on auto-reconnect. 40 - Changing passwords gives less confusing feedback ("password is empty") now. 41 42 Finished 26 Aug 2008 5 43 6 44 Version 1.2.1: -
doc/user-guide/Makefile
raac4017 r2288705 13 13 14 14 %.html: %.db.xml 15 xsltproc --output $@ http://docbook.sourceforge.net/release/xsl/current/ html/docbook.xsl $<15 xsltproc --output $@ http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl $< 16 16 17 17 %.pdf: %.db.xml -
doc/user-guide/commands.xml
raac4017 r2288705 125 125 <description> 126 126 <para> 127 This command gives you a list of all the accounts known by BitlBee , including the numbers you'll need for most account commands.127 This command gives you a list of all the accounts known by BitlBee. 128 128 </para> 129 129 </description> … … 138 138 <description> 139 139 <para> 140 This accountcan be used to change various settings for IM accounts. For all protocols, this command can be used to change the handle or the password BitlBee uses to log in and if it should be logged in automatically. Some protocols have additional settings. You can see the settings available for a connection by typing <emphasis>account set <account id></emphasis>.140 This command can be used to change various settings for IM accounts. For all protocols, this command can be used to change the handle or the password BitlBee uses to log in and if it should be logged in automatically. Some protocols have additional settings. You can see the settings available for a connection by typing <emphasis>account set <account id></emphasis>. 141 141 </para> 142 142 143 143 <para> 144 For more infomation about a setting, see <emphasis>help set <setting></emphasis>. For details about the syntax of this command, see <emphasis>help set</emphasis>.144 For more infomation about a setting, see <emphasis>help set <setting></emphasis>. 145 145 </para> 146 146 147 147 <para> 148 148 The account ID can be a number (see <emphasis>account list</emphasis>), the protocol name or (part of) the screenname, as long as it matches only one connection. 149 </para> 150 </description> 151 </bitlbee-command> 152 </bitlbee-command> 153 154 <bitlbee-command name="chat"> 155 <short-description>Chatroom list maintenance</short-description> 156 <syntax>chat <action> [<arguments>]</syntax> 157 158 <description> 159 160 <para> 161 Available actions: add, del, list, with and set. See <emphasis>help chat <action></emphasis> for more information. 162 </para> 163 164 </description> 165 166 <bitlbee-command name="add"> 167 <syntax>chat add <account> <room> [<channel>]</syntax> 168 169 <description> 170 <para> 171 Add a chatroom to the list of chatrooms you're interested in. BitlBee needs this list to map room names to a proper IRC channel name. 172 </para> 173 174 <para> 175 After adding a room to your list, you can simply use the IRC /join command to enter the room. Also, you can tell BitlBee to automatically join the room when you log in. (See <emphasis>chat set</emphasis>) 176 </para> 177 178 <para> 179 Password-protected rooms work exactly like on IRC, by passing the password as an extra argument to /join. 180 </para> 181 </description> 182 183 </bitlbee-command> 184 185 <bitlbee-command name="del"> 186 <syntax>chat del <chat id></syntax> 187 188 <description> 189 <para> 190 This commands deletes an chatroom from your list. 191 </para> 192 193 <para> 194 The room ID can be a number (see <emphasis>chat list</emphasis>), or (part of) the name of the room/channel. 195 </para> 196 </description> 197 </bitlbee-command> 198 199 <bitlbee-command name="list"> 200 <syntax>chat list</syntax> 201 202 <description> 203 <para> 204 This command gives you a list of all the chatrooms known by BitlBee. 205 </para> 206 </description> 207 </bitlbee-command> 208 209 <bitlbee-command name="with"> 210 <syntax>chat with <nickname></syntax> 211 212 <description> 213 <para> 214 While most <emphasis>chat</emphasis> subcommands are about named chatrooms, this command can be used to open an unnamed groupchat with one or more persons. This command is what <emphasis>/join #nickname</emphasis> used to do in older BitlBee versions. 215 </para> 216 </description> 217 </bitlbee-command> 218 219 <bitlbee-command name="set"> 220 <syntax>chat set <chat id></syntax> 221 <syntax>chat set <chat id>/<setting></syntax> 222 <syntax>chat set <chat id>/<setting> <value></syntax> 223 <syntax>chat set -del <chat id>/<setting></syntax> 224 225 <description> 226 <para> 227 This command can be used to change various settings for chatrooms. 228 </para> 229 230 <para> 231 For more infomation about a setting, see <emphasis>help set <setting></emphasis>. 232 </para> 233 234 <para> 235 The room ID can be a number (see <emphasis>chat list</emphasis>), or (part of) the name of the room/channel. 149 236 </para> 150 237 </description> … … 303 390 </bitlbee-setting> 304 391 392 <bitlbee-setting name="auto_join" type="boolean" scope="chat"> 393 <default>false</default> 394 395 <description> 396 <para> 397 With this option enabled, BitlBee will automatically join this chatroom when you log in. 398 </para> 399 </description> 400 </bitlbee-setting> 401 305 402 <bitlbee-setting name="auto_reconnect" type="boolean" scope="both"> 306 403 <default>false</default> … … 486 583 </bitlbee-setting> 487 584 585 <bitlbee-setting name="nick" type="string" scope="chat"> 586 587 <description> 588 <para> 589 You can use this option to set your nickname in a chatroom. You won't see this nickname yourself, but other people in the room will. By default, BitlBee will use your username as the chatroom nickname. 590 </para> 591 </description> 592 </bitlbee-setting> 593 488 594 <bitlbee-setting name="ops" type="string" scope="global"> 489 595 <default>both</default> … … 580 686 <bitlbee-setting name="resource_select" type="string" scope="account"> 581 687 <default>priority</default> 582 <possible-values>priority, time</possible-values>688 <possible-values>priority, activity</possible-values> 583 689 584 690 <description> … … 588 694 589 695 <para> 590 Normally it's set to <emphasis>priority</emphasis> which means messages will always be delivered to the buddy's resource with the highest priority. If the setting is set to <emphasis> time</emphasis>, messages will be delivered to the resource that was last used to send you a message (or the resource that most recently connected).696 Normally it's set to <emphasis>priority</emphasis> which means messages will always be delivered to the buddy's resource with the highest priority. If the setting is set to <emphasis>activity</emphasis>, messages will be delivered to the resource that was last used to send you a message (or the resource that most recently connected). 591 697 </para> 592 698 </description> … … 851 957 <ircline nick="wouter">account set 1/display_name "The majestik møøse"</ircline> 852 958 <ircline nick="root">display_name = `The majestik møøse'</ircline> 853 </ircexample>854 855 </bitlbee-command>856 857 <bitlbee-command name="join_chat">858 <short-description>Join a named groupchat/conference room</short-description>859 <syntax>join_chat <connection> <room name> [<channel name>] [<room nickname>] [<password>]</syntax>860 861 <description>862 <para>863 On most IM-networks groupchats can be started using the /join command. (<emphasis>/join #foo</emphasis> to start a chatroom with you and <emphasis>foo</emphasis>) This doesn't work with names groupchats though (which exist on Jabber networks and AIM, for example), instead you can use this command.864 </para>865 866 <para>867 The first two arguments are required. <emphasis>room name</emphasis> is the name of the chatroom on the IM-network. <emphasis>channel name</emphasis> is the IRC channel name BitlBee should map this to. <emphasis>room nickname</emphasis> is the nickname you want to have in this channel. If you don't give these options, BitlBee will do the right guesses.868 </para>869 870 <para>871 The following command will join you to the chatroom called <emphasis>bitlbee@conference.bitlbee.org</emphasis>. The channel will be called <emphasis>&bitlbee-help</emphasis> because <emphasis>&bitlbee</emphasis> will already be in use. Your nickname will be <emphasis>help-me</emphasis>.872 </para>873 </description>874 875 <ircexample>876 <ircline nick="wilmer">join_chat jabber bitlbee@conference.bitlbee.org &bitlbee-help help-me</ircline>877 959 </ircexample> 878 960 -
doc/user-guide/help.xml
raac4017 r2288705 1 <?xml version="1.0" encoding=" iso-8859-1"?>1 <?xml version="1.0" encoding="utf-8"?> 2 2 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> 3 3 -
doc/user-guide/misc.xml
raac4017 r2288705 69 69 70 70 <para> 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 itwill create a new virtual channel with root, you and lisa_msn in it.71 To open a groupchat, use the <emphasis>chat with</emphasis> command. For example, to start a groupchat with the person <emphasis>lisa_msn</emphasis> in it, just type <emphasis>chat with lisa_msn</emphasis>. BitlBee will create a new virtual channel with root, you and lisa_msn in it. 72 72 </para> 73 73 74 74 <para> 75 Of course a channel with only two people isn't really exciting yet. So the next step is to invite some other people to the channel. For this, you can use the <emphasis>/invite</emphasis> command of your IRC client. Please do keep in mind that all the people have to be on the same network and contact list! You can't invite Yahoo! buddies into an MSN groupchat.75 Then, just use the ordinary IRC <emphasis>/invite</emphasis> command to invite more people. Please do keep in mind that all the people have to be on the same network and contact list! You can't invite Yahoo! buddies into an MSN groupchat. 76 76 </para> 77 77 78 78 <para> 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.79 Some protocols (like Jabber) also support named groupchats. BitlBee now supports these too. You can use the <emphasis>chat add</emphasis> command to join them. See <emphasis>help chat add</emphasis> for more information. 80 80 </para> 81 81 -
doc/user-guide/user-guide.xml
raac4017 r2288705 1 <?xml version="1.0" encoding=" iso-8859-1"?>1 <?xml version="1.0" encoding="utf-8"?> 2 2 <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> 3 3 -
irc.c
raac4017 r2288705 35 35 GSList *irc_connection_list = NULL; 36 36 37 static char * passchange( set_t *set, char *value )37 static char *set_eval_password( set_t *set, char *value ) 38 38 { 39 39 irc_t *irc = set->data; 40 40 41 irc_setpass( irc, value ); 42 irc_usermsg( irc, "Password successfully changed" ); 43 return NULL; 41 if( irc->status & USTATUS_IDENTIFIED && value ) 42 { 43 irc_setpass( irc, value ); 44 return NULL; 45 } 46 else 47 { 48 return SET_INVALID; 49 } 44 50 } 45 51 … … 78 84 struct sockaddr_storage sock; 79 85 socklen_t socklen = sizeof( sock ); 86 set_t *s; 80 87 81 88 irc = g_new0( irc_t, 1 ); … … 137 144 irc_connection_list = g_slist_append( irc_connection_list, irc ); 138 145 139 set_add( &irc->set, "away_devoice", "true", set_eval_away_devoice, irc ); 140 set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc ); 141 set_add( &irc->set, "auto_reconnect", "false", set_eval_bool, irc ); 142 set_add( &irc->set, "auto_reconnect_delay", "5*3<900", set_eval_account_reconnect_delay, irc ); 143 set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc ); 144 set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc ); 145 set_add( &irc->set, "charset", "utf-8", set_eval_charset, irc ); 146 set_add( &irc->set, "debug", "false", set_eval_bool, irc ); 147 set_add( &irc->set, "default_target", "root", NULL, irc ); 148 set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc ); 149 set_add( &irc->set, "handle_unknown", "root", NULL, irc ); 150 set_add( &irc->set, "lcnicks", "true", set_eval_bool, irc ); 151 set_add( &irc->set, "ops", "both", set_eval_ops, irc ); 152 set_add( &irc->set, "password", NULL, passchange, irc ); 153 set_add( &irc->set, "private", "true", set_eval_bool, irc ); 154 set_add( &irc->set, "query_order", "lifo", NULL, irc ); 155 set_add( &irc->set, "root_nick", irc->mynick, set_eval_root_nick, irc ); 156 set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc ); 157 set_add( &irc->set, "simulate_netsplit", "true", set_eval_bool, irc ); 158 set_add( &irc->set, "strip_html", "true", NULL, irc ); 159 set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc ); 160 set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc ); 146 s = set_add( &irc->set, "away_devoice", "true", set_eval_away_devoice, irc ); 147 s = set_add( &irc->set, "auto_connect", "true", set_eval_bool, irc ); 148 s = set_add( &irc->set, "auto_reconnect", "false", set_eval_bool, irc ); 149 s = set_add( &irc->set, "auto_reconnect_delay", "5*3<900", set_eval_account_reconnect_delay, irc ); 150 s = set_add( &irc->set, "buddy_sendbuffer", "false", set_eval_bool, irc ); 151 s = set_add( &irc->set, "buddy_sendbuffer_delay", "200", set_eval_int, irc ); 152 s = set_add( &irc->set, "charset", "utf-8", set_eval_charset, irc ); 153 s = set_add( &irc->set, "debug", "false", set_eval_bool, irc ); 154 s = set_add( &irc->set, "default_target", "root", NULL, irc ); 155 s = set_add( &irc->set, "display_namechanges", "false", set_eval_bool, irc ); 156 s = set_add( &irc->set, "handle_unknown", "root", NULL, irc ); 157 s = set_add( &irc->set, "lcnicks", "true", set_eval_bool, irc ); 158 s = set_add( &irc->set, "ops", "both", set_eval_ops, irc ); 159 s = set_add( &irc->set, "password", NULL, set_eval_password, irc ); 160 s->flags |= SET_NULL_OK; 161 s = set_add( &irc->set, "private", "true", set_eval_bool, irc ); 162 s = set_add( &irc->set, "query_order", "lifo", NULL, irc ); 163 s = set_add( &irc->set, "root_nick", irc->mynick, set_eval_root_nick, irc ); 164 s = set_add( &irc->set, "save_on_quit", "true", set_eval_bool, irc ); 165 s = set_add( &irc->set, "simulate_netsplit", "true", set_eval_bool, irc ); 166 s = set_add( &irc->set, "strip_html", "true", NULL, irc ); 167 s = set_add( &irc->set, "to_char", ": ", set_eval_to_char, irc ); 168 s = set_add( &irc->set, "typing_notice", "false", set_eval_bool, irc ); 161 169 162 170 conf_loaddefaults( irc ); … … 232 240 233 241 if( irc->status & USTATUS_IDENTIFIED && set_getbool( &irc->set, "save_on_quit" ) ) 234 if( storage_save( irc, TRUE ) != STORAGE_OK )242 if( storage_save( irc, NULL, TRUE ) != STORAGE_OK ) 235 243 irc_usermsg( irc, "Error while saving settings!" ); 236 244 … … 400 408 } 401 409 402 if( lines[i] ) 403 { 404 if( ( cmd = irc_parse_line( lines[i] ) ) == NULL ) 405 continue; 410 if( lines[i] && ( cmd = irc_parse_line( lines[i] ) ) ) 411 { 406 412 irc_exec( irc, cmd ); 407 413 g_free( cmd ); … … 478 484 if( line[0] == ':' ) 479 485 { 480 for( i = 0; line[i] != ' '; i ++ );486 for( i = 0; line[i] && line[i] != ' '; i ++ ); 481 487 line = line + i; 482 488 } … … 774 780 irc_reply( irc, 3, ":%s", IRCD_INFO ); 775 781 irc_reply( irc, 4, "%s %s %s %s", irc->myhost, BITLBEE_VERSION, UMODES UMODES_PRIV, CMODES ); 776 irc_reply( irc, 5, "PREFIX=(ov)@+ CHANTYPES=#& CHANMODES=,,,%s NICKLEN=%d NETWORK=BitlBee CASEMAPPING=rfc1459 MAXTARGETS=1 WATCH=128 :are supported by this server", CMODES, MAX_NICK_LENGTH - 1 ); 782 irc_reply( irc, 5, "PREFIX=(ov)@+ CHANTYPES=%s CHANMODES=,,,%s NICKLEN=%d NETWORK=BitlBee " 783 "CASEMAPPING=rfc1459 MAXTARGETS=1 WATCH=128 :are supported by this server", 784 CTYPES, CMODES, MAX_NICK_LENGTH - 1 ); 777 785 irc_motd( irc ); 778 786 irc->umode[0] = '\0'; … … 1015 1023 user_t *u = NULL; 1016 1024 1017 if( *nick == '#' || *nick == '&')1025 if( strchr( CTYPES, *nick ) ) 1018 1026 { 1019 1027 if( !( c = irc_chat_by_channel( irc, nick ) ) ) -
irc.h
raac4017 r2288705 38 38 #define CMODE "t" 39 39 #define UMODE "s" 40 #define CTYPES "&#" 40 41 41 42 typedef enum … … 47 48 USTATUS_SHUTDOWN = 8 48 49 } irc_status_t; 49 50 typedef struct channel51 {52 char *name;53 } channel_t;54 50 55 51 typedef struct irc … … 88 84 struct account *accounts; 89 85 GSList *file_transfers; 86 struct chat *chatrooms; 90 87 91 88 struct __USER *users; … … 101 98 102 99 #include "user.h" 103 // #include "nick.h"104 100 105 101 extern GSList *irc_connection_list; -
irc_commands.c
raac4017 r2288705 27 27 #include "bitlbee.h" 28 28 #include "ipc.h" 29 #include "chat.h" 29 30 30 31 static void irc_cmd_pass( irc_t *irc, char **cmd ) … … 125 126 static void irc_cmd_mode( irc_t *irc, char **cmd ) 126 127 { 127 if( *cmd[1] == '#' || *cmd[1] == '&')128 if( strchr( CTYPES, *cmd[1] ) ) 128 129 { 129 130 if( cmd[2] ) … … 193 194 else if( cmd[1] ) 194 195 { 195 if( ( cmd[1][0] == '#' || cmd[1][0] == '&' ) && cmd[1][1] ) 196 { 197 user_t *u = user_find( irc, cmd[1] + 1 ); 198 199 if( u && u->ic && u->ic->acc->prpl->chat_with ) 200 { 201 irc_reply( irc, 403, "%s :Initializing groupchat in a different channel", cmd[1] ); 202 203 if( !u->ic->acc->prpl->chat_with( u->ic, u->handle ) ) 204 { 205 irc_usermsg( irc, "Could not open a groupchat with %s.", u->nick ); 206 } 207 } 208 else if( u ) 209 { 210 irc_reply( irc, 403, "%s :Groupchats are not possible with %s", cmd[1], cmd[1]+1 ); 211 } 212 else 213 { 214 irc_reply( irc, 403, "%s :No such nick", cmd[1] ); 215 } 216 } 196 struct chat *c; 197 198 if( strchr( CTYPES, cmd[1][0] ) == NULL || cmd[1][1] == 0 ) 199 irc_reply( irc, 479, "%s :Invalid channel name", cmd[1] ); 200 else if( ( c = chat_bychannel( irc, cmd[1] ) ) && c->acc && c->acc->ic ) 201 chat_join( irc, c, cmd[2] ); 217 202 else 218 {219 203 irc_reply( irc, 403, "%s :No such channel", cmd[1] ); 220 }221 204 } 222 205 } … … 433 416 if( g_hash_table_lookup_extended( irc->watches, nick, &okey, &ovalue ) ) 434 417 { 418 g_hash_table_remove( irc->watches, okey ); 435 419 g_free( okey ); 436 g_hash_table_remove( irc->watches, okey );437 420 438 421 irc_reply( irc, 602, "%s %s %s %d :%s", nick, "*", "*", 0, "Stopped watching" ); -
lib/events_libevent.c
raac4017 r2288705 37 37 38 38 static void b_main_restart(); 39 static guint id_next = 1; 39 static guint id_next = 1; /* Next ID to be allocated to an event handler. */ 40 static guint id_cur = 0; /* Event ID that we're currently handling. */ 41 static guint id_dead; /* Set to 1 if b_event_remove removes id_cur. */ 40 42 static GHashTable *id_hash; 41 static int quitting = 0; 43 static int quitting = 0; /* Prepare to quit, stop handling events. */ 42 44 43 45 /* Since libevent doesn't handle two event handlers for one fd-condition … … 119 121 struct b_event_data *b_ev = data; 120 122 b_input_condition cond = 0; 121 int id;123 gboolean st; 122 124 123 125 if( fd >= 0 ) … … 133 135 /* Since the called function might cancel this handler already 134 136 (which free()s b_ev), we have to remember the ID here. */ 135 id = b_ev->id; 137 id_cur = b_ev->id; 138 id_dead = 0; 136 139 137 140 if( quitting ) 138 141 { 139 b_event_remove( id );142 b_event_remove( id_cur ); 140 143 return; 141 144 } 142 145 143 if( !b_ev->function( b_ev->data, fd, cond ) ) 146 st = b_ev->function( b_ev->data, fd, cond ); 147 if( id_dead ) 148 { 149 /* This event was killed already, don't touch it! */ 150 return; 151 } 152 else if( !st ) 144 153 { 145 154 event_debug( "Handler returned FALSE: " ); 146 b_event_remove( id );155 b_event_remove( id_cur ); 147 156 } 148 157 else if( fd == -1 ) 149 158 { 159 /* fd == -1 means it was a timer. These can't be auto-repeated 160 so it has to be recreated every time. */ 150 161 struct timeval tv; 151 162 … … 236 247 if( b_ev ) 237 248 { 249 if( id == id_cur ) 250 id_dead = TRUE; 251 238 252 g_hash_table_remove( id_hash, &b_ev->id ); 239 253 if( b_ev->evinfo.ev_fd >= 0 ) -
lib/http_client.c
raac4017 r2288705 59 59 if( error ) 60 60 { 61 g_free( req );62 return ( NULL );61 http_free( req ); 62 return NULL; 63 63 } 64 64 … … 160 160 161 161 req->func( req ); 162 163 g_free( req->request ); 164 g_free( req ); 165 162 http_free( req ); 166 163 return FALSE; 167 164 } … … 444 441 445 442 req->func( req ); 446 443 http_free( req ); 444 return FALSE; 445 } 446 447 void http_free( struct http_request *req ) 448 { 447 449 g_free( req->request ); 448 450 g_free( req->reply_headers ); 449 451 g_free( req->status_string ); 450 452 g_free( req ); 451 452 return FALSE; 453 } 453 } 454 -
lib/http_client.h
raac4017 r2288705 81 81 void *http_dorequest( char *host, int port, int ssl, char *request, http_input_function func, gpointer data ); 82 82 void *http_dorequest_url( char *url_string, http_input_function func, gpointer data ); 83 84 void http_free( struct http_request *req ); -
lib/ini.c
raac4017 r2288705 2 2 * BitlBee -- An IRC to other IM-networks gateway * 3 3 * * 4 * Copyright 2002-200 5Wilmer van der Gaast and others *4 * Copyright 2002-2008 Wilmer van der Gaast and others * 5 5 \********************************************************************/ 6 6 … … 28 28 ini_t *ini_open( char *file ) 29 29 { 30 ini_t *ini = g_new0( ini_t, 1 ); 30 int fd; 31 ini_t *ini = NULL; 32 struct stat fi; 31 33 32 if( ( ini->fp = fopen( file, "r" ) ) == NULL ) 34 if( ( fd = open( file, O_RDONLY ) ) != -1 && 35 fstat( fd, &fi ) == 0 && 36 fi.st_size <= 16384 && 37 ( ini = g_malloc( sizeof( ini_t ) + fi.st_size + 1 ) ) && 38 read( fd, ini->file, fi.st_size ) == fi.st_size ) 33 39 { 34 g_free( ini ); 35 return( NULL ); 40 memset( ini, 0, sizeof( ini_t ) ); 41 ini->size = fi.st_size; 42 ini->file[ini->size] = 0; 43 ini->cur = ini->file; 44 ini->c_section = ""; 45 46 close( fd ); 47 48 return ini; 36 49 } 50 51 if( fd >= 0 ) 52 close( fd ); 37 53 38 return( ini ); 54 ini_close( ini ); 55 56 return NULL; 57 } 58 59 /* Strips leading and trailing whitespace and returns a pointer to the first 60 non-ws character of the given string. */ 61 static char *ini_strip_whitespace( char *in ) 62 { 63 char *e; 64 65 while( isspace( *in ) ) 66 in++; 67 68 e = in + strlen( in ) - 1; 69 while( e > in && isspace( *e ) ) 70 e--; 71 e[1] = 0; 72 73 return in; 39 74 } 40 75 41 76 int ini_read( ini_t *file ) 42 77 { 43 char key[MAX_STRING], s[MAX_STRING], *t; 44 int i; 78 char *s; 45 79 46 while( !feof( file->fp ))80 while( file->cur && file->cur < file->file + file->size ) 47 81 { 48 *s = 0;49 fscanf( file->fp, "%127[^\n#]s", s );50 f scanf( file->fp, "%*[^\n]s" );51 fgetc( file->fp ); /* Skip newline */ 52 file->line ++;53 if( strchr( s, '=' ))82 char *e, *next; 83 84 file->line++; 85 86 /* Find the end of line */ 87 if( ( e = strchr( file->cur, '\n' ) ) != NULL ) 54 88 { 55 sscanf( s, "%[^ =]s", key ); 56 if( ( t = strchr( key, '.' ) ) ) 89 *e = 0; 90 next = e + 1; 91 } 92 else 93 { 94 /* No more lines. */ 95 e = file->cur + strlen( file->cur ); 96 next = NULL; 97 } 98 99 /* Comment? */ 100 if( ( s = strchr( file->cur, '#' ) ) != NULL ) 101 *s = 0; 102 103 file->cur = ini_strip_whitespace( file->cur ); 104 105 if( *file->cur == '[' ) 106 { 107 file->cur++; 108 if( ( s = strchr( file->cur, ']' ) ) != NULL ) 57 109 { 58 *t = 0; 59 strcpy( file->section, key ); 60 t ++; 110 *s = 0; 111 file->c_section = file->cur; 112 } 113 } 114 else if( ( s = strchr( file->cur, '=' ) ) != NULL ) 115 { 116 *s = 0; 117 file->key = ini_strip_whitespace( file->cur ); 118 file->value = ini_strip_whitespace( s + 1 ); 119 120 if( ( s = strchr( file->key, '.' ) ) != NULL ) 121 { 122 *s = 0; 123 file->section = file->key; 124 file->key = s + 1; 61 125 } 62 126 else 63 127 { 64 strcpy( file->section, file->c_section ); 65 t = key; 128 file->section = file->c_section; 66 129 } 67 sscanf( t, "%s", file->key );68 t = strchr( s, '=' ) + 1;69 for( i = 0; t[i] == ' '; i ++ );70 strcpy( file->value, &t[i] );71 for( i = strlen( file->value ) - 1; file->value[i] == 32; i -- )72 file->value[i] = 0;73 130 74 return( 1 ); 131 file->cur = next; 132 return 1; 75 133 } 76 else if( ( t = strchr( s, '[' ) ) ) 77 { 78 strcpy( file->c_section, t + 1 ); 79 t = strchr( file->c_section, ']' ); 80 *t = 0; 81 } 134 /* else: noise/comment/etc, let's just ignore it. */ 135 136 file->cur = next; 82 137 } 83 return( 0 ); 138 139 return 0; 84 140 } 85 141 86 142 void ini_close( ini_t *file ) 87 143 { 88 fclose( file->fp );89 144 g_free( file ); 90 145 } -
lib/ini.h
raac4017 r2288705 29 29 typedef struct 30 30 { 31 FILE *fp;32 31 int line; 33 char c_section[MAX_STRING]; 34 char section[MAX_STRING]; 35 char key[MAX_STRING]; 36 char value[MAX_STRING]; 32 char *c_section; 33 char *section; 34 char *key; 35 char *value; 36 int size; 37 char *cur, *tok; 38 char file[]; 37 39 } ini_t; 38 40 -
lib/misc.c
raac4017 r2288705 46 46 #endif 47 47 48 #include "md5.h" 48 49 #include "ssl_client.h" 49 50 -
lib/proxy.c
raac4017 r2288705 558 558 return proxy_connect_socks5(host, port, phb); 559 559 560 if (phb->host) g_free(phb);561 560 g_free(phb); 562 561 return -1; -
lib/xmltree.c
raac4017 r2288705 472 472 } 473 473 474 struct xt_node *xt_new_node( char *name, c har *text, struct xt_node *children )474 struct xt_node *xt_new_node( char *name, const char *text, struct xt_node *children ) 475 475 { 476 476 struct xt_node *node, *c; -
lib/xmltree.h
raac4017 r2288705 90 90 char *xt_find_attr( struct xt_node *node, const char *key ); 91 91 92 struct xt_node *xt_new_node( char *name, c har *text, struct xt_node *children );92 struct xt_node *xt_new_node( char *name, const char *text, struct xt_node *children ); 93 93 void xt_add_child( struct xt_node *parent, struct xt_node *child ); 94 94 void xt_add_attr( struct xt_node *node, const char *key, const char *value ); -
protocols/jabber/conference.c
raac4017 r2288705 26 26 static xt_status jabber_chat_join_failed( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ); 27 27 28 struct groupchat *jabber_chat_join( struct im_connection *ic, c har *room, char *nick,char *password )28 struct groupchat *jabber_chat_join( struct im_connection *ic, const char *room, const char *nick, const char *password ) 29 29 { 30 30 struct jabber_chat *jc; … … 36 36 node = xt_new_node( "x", NULL, NULL ); 37 37 xt_add_attr( node, "xmlns", XMLNS_MUC ); 38 node = jabber_make_packet( "presence", NULL, roomjid, node );39 38 if( password ) 40 39 xt_add_child( node, xt_new_node( "password", password, NULL ) ); 40 node = jabber_make_packet( "presence", NULL, roomjid, node ); 41 41 jabber_cache_add( ic, node, jabber_chat_join_failed ); 42 42 … … 234 234 ( strcmp( s, XMLNS_MUC_USER ) == 0 ) ) 235 235 { 236 c = xt_find_node( c->children, "item" ); 237 if( ( s = xt_find_attr( c, "jid" ) ) ) 236 struct xt_node *item; 237 238 item = xt_find_node( c->children, "item" ); 239 if( ( s = xt_find_attr( item, "jid" ) ) ) 238 240 { 239 241 /* Yay, found what we need. :-) */ … … 283 285 else if( type ) /* type can only be NULL or "unavailable" in this function */ 284 286 { 285 s = strchr( bud->ext_jid, '/' ); 286 if( s ) *s = 0; 287 imcb_chat_remove_buddy( chat, bud->ext_jid, NULL ); 288 if( bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS ) 289 imcb_remove_buddy( ic, bud->ext_jid, NULL ); 290 if( s ) *s = '/'; 287 if( ( bud->flags & JBFLAG_IS_CHATROOM ) && bud->ext_jid ) 288 { 289 s = strchr( bud->ext_jid, '/' ); 290 if( s ) *s = 0; 291 imcb_chat_remove_buddy( chat, bud->ext_jid, NULL ); 292 if( bud != jc->me && bud->flags & JBFLAG_IS_ANONYMOUS ) 293 imcb_remove_buddy( ic, bud->ext_jid, NULL ); 294 if( s ) *s = '/'; 295 } 291 296 292 297 if( bud == jc->me ) -
protocols/jabber/iq.c
raac4017 r2288705 51 51 { 52 52 if( !( ( c = xt_find_node( node->children, "query" ) ) || 53 ( c = xt_find_node( node->children, "ping" ) ) ) || /* O_o WHAT is wrong with just <query/> ????? */53 ( c = xt_find_node( node->children, "ping" ) ) ) || 54 54 !( s = xt_find_attr( c, "xmlns" ) ) ) 55 55 { 56 imcb_log( ic, "Warning: Received incomplete IQ-%s packet", type ); 56 /* Sigh. Who decided to suddenly invent new elements 57 instead of just sticking with <query/>? */ 57 58 return XT_HANDLED; 58 59 } -
protocols/jabber/jabber.c
raac4017 r2288705 70 70 71 71 s = set_add( &acc->set, "server", NULL, set_eval_account, acc ); 72 s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY ;72 s->flags |= ACC_SET_NOSAVE | ACC_SET_OFFLINE_ONLY | SET_NULL_OK; 73 73 74 74 s = set_add( &acc->set, "ssl", "false", set_eval_bool, acc ); … … 439 439 } 440 440 441 static struct groupchat *jabber_chat_join_( struct im_connection *ic, c har *room, char *nick,char *password )441 static struct groupchat *jabber_chat_join_( struct im_connection *ic, const char *room, const char *nick, const char *password ) 442 442 { 443 443 if( strchr( room, '@' ) == NULL ) -
protocols/jabber/jabber.h
raac4017 r2288705 27 27 #include <glib.h> 28 28 29 #include "bitlbee.h" 30 #include "md5.h" 29 31 #include "xmltree.h" 30 #include "bitlbee.h"31 32 32 33 extern GSList *jabber_connections; … … 302 303 303 304 /* conference.c */ 304 struct groupchat *jabber_chat_join( struct im_connection *ic, c har *room, char *nick,char *password );305 struct groupchat *jabber_chat_join( struct im_connection *ic, const char *room, const char *nick, const char *password ); 305 306 struct groupchat *jabber_chat_by_jid( struct im_connection *ic, const char *name ); 306 307 void jabber_chat_free( struct groupchat *c ); -
protocols/jabber/jabber_util.c
raac4017 r2288705 37 37 /* Priority is a signed 8-bit integer, according to RFC 3921. */ 38 38 if( i < -128 || i > 127 ) 39 return NULL;39 return SET_INVALID; 40 40 } 41 41 else 42 return NULL;42 return SET_INVALID; 43 43 44 44 /* Only run this stuff if the account is online ATM, -
protocols/jabber/presence.c
raac4017 r2288705 49 49 if( !( bud = jabber_buddy_by_jid( ic, from, GET_BUDDY_EXACT | GET_BUDDY_CREAT ) ) ) 50 50 { 51 if( set_getbool( &ic->irc->set, "debug" ) ) 52 imcb_log( ic, "Warning: Could not handle presence information from JID: %s", from ); 51 /* 52 imcb_log( ic, "Warning: Could not handle presence information from JID: %s", from ); 53 */ 53 54 return XT_HANDLED; 54 55 } … … 106 107 if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) == NULL ) 107 108 { 108 if( set_getbool( &ic->irc->set, "debug" ) ) 109 imcb_log( ic, "Warning: Received presence information from unknown JID: %s", from ); 109 /* 110 imcb_log( ic, "Warning: Received presence information from unknown JID: %s", from ); 111 */ 110 112 return XT_HANDLED; 111 113 } -
protocols/nogaim.c
raac4017 r2288705 33 33 34 34 #define BITLBEE_CORE 35 #include <ctype.h> 36 35 37 #include "nogaim.h" 36 #include <ctype.h>38 #include "chat.h" 37 39 38 40 static int remove_chat_buddy_silent( struct groupchat *b, const char *handle ); … … 249 251 void imcb_connected( struct im_connection *ic ) 250 252 { 253 irc_t *irc = ic->irc; 254 struct chat *c; 251 255 user_t *u; 252 256 … … 271 275 exponential backoff timer. */ 272 276 ic->acc->auto_reconnect_delay = 0; 277 278 for( c = irc->chatrooms; c; c = c->next ) 279 { 280 if( c->acc != ic->acc ) 281 continue; 282 283 if( set_getbool( &c->set, "auto_join" ) ) 284 chat_join( irc, c, NULL ); 285 } 273 286 } 274 287 … … 309 322 ic->acc->prpl->logout( ic ); 310 323 b_event_remove( ic->inpa ); 324 325 g_free( ic->away ); 326 ic->away = NULL; 311 327 312 328 u = irc->users; … … 492 508 } 493 509 494 /* prpl.c */ 495 496 struct show_got_added_data 510 511 struct imcb_ask_cb_data 497 512 { 498 513 struct im_connection *ic; … … 500 515 }; 501 516 502 void show_got_added_no( void *data ) 503 { 504 g_free( ((struct show_got_added_data*)data)->handle ); 517 static void imcb_ask_auth_cb_no( void *data ) 518 { 519 struct imcb_ask_cb_data *cbd = data; 520 521 cbd->ic->acc->prpl->auth_deny( cbd->ic, cbd->handle ); 522 523 g_free( cbd->handle ); 524 g_free( cbd ); 525 } 526 527 static void imcb_ask_auth_cb_yes( void *data ) 528 { 529 struct imcb_ask_cb_data *cbd = data; 530 531 cbd->ic->acc->prpl->auth_allow( cbd->ic, cbd->handle ); 532 533 g_free( cbd->handle ); 534 g_free( cbd ); 535 } 536 537 void imcb_ask_auth( struct im_connection *ic, const char *handle, const char *realname ) 538 { 539 struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1 ); 540 char *s, *realname_ = NULL; 541 542 if( realname != NULL ) 543 realname_ = g_strdup_printf( " (%s)", realname ); 544 545 s = g_strdup_printf( "The user %s%s wants to add you to his/her buddy list.", 546 handle, realname_ ?: "" ); 547 548 g_free( realname_ ); 549 550 data->ic = ic; 551 data->handle = g_strdup( handle ); 552 query_add( ic->irc, ic, s, imcb_ask_auth_cb_yes, imcb_ask_auth_cb_no, data ); 553 } 554 555 556 static void imcb_ask_add_cb_no( void *data ) 557 { 558 g_free( ((struct imcb_ask_cb_data*)data)->handle ); 505 559 g_free( data ); 506 560 } 507 561 508 void show_got_added_yes( void *data ) 509 { 510 struct show_got_added_data *sga = data; 511 512 sga->ic->acc->prpl->add_buddy( sga->ic, sga->handle, NULL ); 513 /* imcb_add_buddy( sga->ic, NULL, sga->handle, sga->handle ); */ 514 515 return show_got_added_no( data ); 516 } 517 518 void imcb_ask_add( struct im_connection *ic, char *handle, const char *realname ) 519 { 520 struct show_got_added_data *data = g_new0( struct show_got_added_data, 1 ); 562 static void imcb_ask_add_cb_yes( void *data ) 563 { 564 struct imcb_ask_cb_data *cbd = data; 565 566 cbd->ic->acc->prpl->add_buddy( cbd->ic, cbd->handle, NULL ); 567 568 return imcb_ask_add_cb_no( data ); 569 } 570 571 void imcb_ask_add( struct im_connection *ic, const char *handle, const char *realname ) 572 { 573 struct imcb_ask_cb_data *data = g_new0( struct imcb_ask_cb_data, 1 ); 521 574 char *s; 522 575 … … 529 582 data->ic = ic; 530 583 data->handle = g_strdup( handle ); 531 query_add( ic->irc, ic, s, show_got_added_yes, show_got_added_no, data );584 query_add( ic->irc, ic, s, imcb_ask_add_cb_yes, imcb_ask_add_cb_no, data ); 532 585 } 533 586 … … 699 752 } 700 753 701 struct groupchat *imcb_chat_new( struct im_connection *ic, c har *handle )754 struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle ) 702 755 { 703 756 struct groupchat *c; … … 928 981 int st; 929 982 930 if( ( g_strcasecmp( value, "true" ) == 0 ) || ( g_strcasecmp( value, "yes" ) == 0 ) || ( g_strcasecmp( value, "on" ) == 0 ) ) 931 st = 1; 932 else if( ( g_strcasecmp( value, "false" ) == 0 ) || ( g_strcasecmp( value, "no" ) == 0 ) || ( g_strcasecmp( value, "off" ) == 0 ) ) 933 st = 0; 934 else if( sscanf( value, "%d", &st ) != 1 ) 935 return( NULL ); 936 937 st = st != 0; 983 if( !is_bool( value ) ) 984 return SET_INVALID; 985 986 st = bool2int( value ); 938 987 939 988 /* Horror.... */ … … 979 1028 } 980 1029 981 return ( set_eval_bool( set, value ) );1030 return value; 982 1031 } 983 1032 -
protocols/nogaim.h
raac4017 r2288705 39 39 #define _NOGAIM_H 40 40 41 #include <stdint.h> 42 41 43 #include "bitlbee.h" 42 44 #include "account.h" … … 210 212 * not implement this. */ 211 213 struct groupchat * 212 (* chat_join) (struct im_connection *, c har *room, char *nick,char *password);214 (* chat_join) (struct im_connection *, const char *room, const char *nick, const char *password); 213 215 /* Change the topic, if supported. Note that BitlBee expects the IM 214 216 server to confirm the topic change with a regular topic change … … 225 227 * - Most protocols will just want to set this to g_strcasecmp().*/ 226 228 int (* handle_cmp) (const char *who1, const char *who2); 229 230 /* Implement these callbacks if you want to use imcb_ask_auth() */ 231 void (* auth_allow) (struct im_connection *, const char *who); 232 void (* auth_deny) (struct im_connection *, const char *who); 227 233 228 234 /* Incoming transfer request */ … … 243 249 * the account_t parameter. */ 244 250 G_MODULE_EXPORT struct im_connection *imcb_new( account_t *acc ); 245 G_MODULE_EXPORT void imc b_free( struct im_connection *ic );251 G_MODULE_EXPORT void imc_free( struct im_connection *ic ); 246 252 /* Once you're connected, you should call this function, so that the user will 247 253 * see the success. */ … … 256 262 /* To tell the user an error, ie. before logging out when an error occurs. */ 257 263 G_MODULE_EXPORT void imcb_error( struct im_connection *ic, char *format, ... ) G_GNUC_PRINTF( 2, 3 ); 264 258 265 /* To ask a your about something. 259 266 * - 'msg' is the question. … … 262 269 */ 263 270 G_MODULE_EXPORT void imcb_ask( struct im_connection *ic, char *msg, void *data, query_callback doit, query_callback dont ); 264 G_MODULE_EXPORT void imcb_ask_add( struct im_connection *ic, char *handle, const char *realname ); 271 272 /* Two common questions you may want to ask: 273 * - X added you to his contact list, allow? 274 * - X is not in your contact list, want to add? 275 */ 276 G_MODULE_EXPORT void imcb_ask_auth( struct im_connection *ic, const char *handle, const char *realname ); 277 G_MODULE_EXPORT void imcb_ask_add( struct im_connection *ic, const char *handle, const char *realname ); 265 278 266 279 /* Buddy management */ … … 294 307 * the user her/himself. At that point the group chat will be visible to the 295 308 * user, too. */ 296 G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, c har *handle );309 G_MODULE_EXPORT struct groupchat *imcb_chat_new( struct im_connection *ic, const char *handle ); 297 310 G_MODULE_EXPORT void imcb_chat_add_buddy( struct groupchat *b, char *handle ); 298 311 /* To remove a handle from a group chat. Reason can be NULL. */ -
protocols/oscar/aim.h
raac4017 r2288705 144 144 } 145 145 146 #define AIM_CLIENTINFO_KNOWNGOOD_5_1_3036 { \ 147 "AOL Instant Messenger, version 5.1.3036/WIN32", \ 148 0x0109, \ 149 0x0005, \ 150 0x0001, \ 151 0x0000, \ 152 0x0bdc, \ 153 "us", \ 154 "en", \ 155 } 156 146 157 /* 147 158 * I would make 4.1.2010 the default, but they seem to have found … … 152 163 * around. (see login.c::memrequest()) 153 164 */ 154 #define AIM_CLIENTINFO_KNOWNGOOD AIM_CLIENTINFO_KNOWNGOOD_ 3_5_1670165 #define AIM_CLIENTINFO_KNOWNGOOD AIM_CLIENTINFO_KNOWNGOOD_5_1_3036 155 166 156 167 #ifndef TRUE -
protocols/oscar/oscar.c
raac4017 r2288705 91 91 GSList *oscar_chats; 92 92 93 gboolean killme ;93 gboolean killme, no_reconnect; 94 94 gboolean icq; 95 95 GSList *evilhack; … … 181 181 static int gaim_parse_auth_resp (aim_session_t *, aim_frame_t *, ...); 182 182 static int gaim_parse_login (aim_session_t *, aim_frame_t *, ...); 183 static int gaim_parse_logout (aim_session_t *, aim_frame_t *, ...); 183 184 static int gaim_handle_redirect (aim_session_t *, aim_frame_t *, ...); 184 185 static int gaim_parse_oncoming (aim_session_t *, aim_frame_t *, ...); … … 294 295 aim_rxdispatch(odata->sess); 295 296 if (odata->killme) 296 imc_logout(ic, TRUE);297 imc_logout(ic, !odata->no_reconnect); 297 298 } else { 298 299 if ((conn->type == AIM_CONN_TYPE_BOS) || … … 520 521 case 0x18: 521 522 /* connecting too frequently */ 523 od->no_reconnect = TRUE; 522 524 imcb_error(ic, _("You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer.")); 523 525 break; … … 572 574 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, gaim_parseaiminfo, 0); 573 575 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MTN, gaim_parsemtn, 0); 576 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_parse_logout, 0); 574 577 575 578 ((struct oscar_data *)ic->proto_data)->conn = bosconn; … … 747 750 748 751 aim_send_login(sess, fr->conn, ic->acc->user, ic->acc->pass, &info, key); 752 753 return 1; 754 } 755 756 static int gaim_parse_logout(aim_session_t *sess, aim_frame_t *fr, ...) { 757 struct im_connection *ic = sess->aux_data; 758 struct oscar_data *odata = ic->proto_data; 759 int code; 760 va_list ap; 761 762 va_start(ap, fr); 763 code = va_arg(ap, int); 764 va_end(ap); 765 766 imcb_error( ic, "Connection aborted by server: %s", code == 1 ? 767 "someone else logged in with your account" : 768 "unknown reason" ); 769 770 /* Tell BitlBee to disable auto_reconnect if code == 1, since that 771 means a concurrent login somewhere else. */ 772 odata->no_reconnect = code == 1; 773 774 /* DO NOT log out here! Just tell the callback to do it. */ 775 odata->killme = TRUE; 749 776 750 777 return 1; … … 1939 1966 aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_NORMAL); 1940 1967 1941 if (ic->away) 1942 g_free(ic->away); 1968 g_free(ic->away); 1943 1969 ic->away = NULL; 1944 1970 … … 1960 1986 static void oscar_set_away_icq(struct im_connection *ic, struct oscar_data *od, const char *state, const char *message) 1961 1987 { 1962 1988 const char *msg = NULL; 1963 1989 gboolean no_message = FALSE; 1964 1990 1965 1991 /* clean old states */ 1966 if (ic->away) { 1967 g_free(ic->away); 1968 ic->away = NULL; 1969 } 1992 g_free(ic->away); 1993 ic->away = NULL; 1970 1994 od->sess->aim_icq_state = 0; 1971 1995 1972 1996 /* if no message, then use an empty message */ 1973 1974 1975 1976 1997 if (message) { 1998 msg = message; 1999 } else { 2000 msg = ""; 1977 2001 no_message = TRUE; 1978 2002 } 1979 2003 1980 2004 if (!g_strcasecmp(state, "Online")) { … … 1982 2006 } else if (!g_strcasecmp(state, "Away")) { 1983 2007 aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY); 1984 2008 ic->away = g_strdup(msg); 1985 2009 od->sess->aim_icq_state = AIM_MTYPE_AUTOAWAY; 1986 2010 } else if (!g_strcasecmp(state, "Do Not Disturb")) { 1987 2011 aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_DND | AIM_ICQ_STATE_BUSY); 1988 2012 ic->away = g_strdup(msg); 1989 2013 od->sess->aim_icq_state = AIM_MTYPE_AUTODND; 1990 2014 } else if (!g_strcasecmp(state, "Not Available")) { 1991 2015 aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_OUT | AIM_ICQ_STATE_AWAY); 1992 2016 ic->away = g_strdup(msg); 1993 2017 od->sess->aim_icq_state = AIM_MTYPE_AUTONA; 1994 2018 } else if (!g_strcasecmp(state, "Occupied")) { 1995 2019 aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_BUSY); 1996 2020 ic->away = g_strdup(msg); 1997 2021 od->sess->aim_icq_state = AIM_MTYPE_AUTOBUSY; 1998 2022 } else if (!g_strcasecmp(state, "Free For Chat")) { 1999 2023 aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_CHAT); 2000 2024 ic->away = g_strdup(msg); 2001 2025 od->sess->aim_icq_state = AIM_MTYPE_AUTOFFC; 2002 2026 } else if (!g_strcasecmp(state, "Invisible")) { 2003 2027 aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_INVISIBLE); 2004 2028 ic->away = g_strdup(msg); 2005 2029 } else if (!g_strcasecmp(state, GAIM_AWAY_CUSTOM)) { 2006 2030 if (no_message) { … … 2008 2032 } else { 2009 2033 aim_setextstatus(od->sess, od->conn, AIM_ICQ_STATE_AWAY); 2010 2034 ic->away = g_strdup(msg); 2011 2035 od->sess->aim_icq_state = AIM_MTYPE_AUTOAWAY; 2012 2036 } … … 2020 2044 struct oscar_data *od = (struct oscar_data *)ic->proto_data; 2021 2045 2022 2046 oscar_set_away_aim(ic, od, state, message); 2023 2047 if (od->icq) 2024 2048 oscar_set_away_icq(ic, od, state, message); … … 2581 2605 } 2582 2606 2583 struct groupchat *oscar_chat_join(struct im_connection * ic, c har * room, char * nick,char * password )2607 struct groupchat *oscar_chat_join(struct im_connection * ic, const char * room, const char * nick, const char * password ) 2584 2608 { 2585 2609 struct oscar_data * od = (struct oscar_data *)ic->proto_data; -
protocols/yahoo/libyahoo2.c
raac4017 r2288705 89 89 90 90 #include "base64.h" 91 #include "http_client.h" 91 92 92 93 #ifdef USE_STRUCT_CALLBACKS … … 169 170 YAHOO_SERVICE_GOTGROUPRENAME, /* < 1, 36(old), 37(new) */ 170 171 YAHOO_SERVICE_SYSMESSAGE = 0x14, 172 YAHOO_SERVICE_SKINNAME = 0x15, 171 173 YAHOO_SERVICE_PASSTHROUGH2 = 0x16, 172 174 YAHOO_SERVICE_CONFINVITE = 0x18, … … 192 194 YAHOO_SERVICE_LIST, 193 195 YAHOO_SERVICE_AUTH = 0x57, 196 YAHOO_SERVICE_AUTHBUDDY = 0x6d, 194 197 YAHOO_SERVICE_ADDBUDDY = 0x83, 195 198 YAHOO_SERVICE_REMBUDDY, … … 197 200 YAHOO_SERVICE_REJECTCONTACT, 198 201 YAHOO_SERVICE_GROUPRENAME = 0x89, /* > 1, 65(new), 66(0), 67(old) */ 202 YAHOO_SERVICE_Y7_PING = 0x8A, /* 0 - id and that's it?? */ 199 203 YAHOO_SERVICE_CHATONLINE = 0x96, /* > 109(id), 1, 6(abcde) < 0,1*/ 200 204 YAHOO_SERVICE_CHATGOTO, … … 202 206 YAHOO_SERVICE_CHATLEAVE, 203 207 YAHOO_SERVICE_CHATEXIT = 0x9b, 208 YAHOO_SERVICE_CHATADDINVITE = 0x9d, 204 209 YAHOO_SERVICE_CHATLOGOUT = 0xa0, 205 210 YAHOO_SERVICE_CHATPING, … … 209 214 YAHOO_SERVICE_PICTURE = 0xbe, 210 215 YAHOO_SERVICE_PICTURE_UPDATE = 0xc1, 211 YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2 216 YAHOO_SERVICE_PICTURE_UPLOAD = 0xc2, 217 YAHOO_SERVICE_Y6_VISIBILITY=0xc5, 218 YAHOO_SERVICE_Y6_STATUS_UPDATE=0xc6, 219 YAHOO_PHOTOSHARE_INIT=0xd2, 220 YAHOO_SERVICE_CONTACT_YMSG13=0xd6, 221 YAHOO_PHOTOSHARE_PREV=0xd7, 222 YAHOO_PHOTOSHARE_KEY=0xd8, 223 YAHOO_PHOTOSHARE_TRANS=0xda, 224 YAHOO_FILE_TRANSFER_INIT_YMSG13=0xdc, 225 YAHOO_FILE_TRANSFER_GET_YMSG13=0xdd, 226 YAHOO_FILE_TRANSFER_PUT_YMSG13=0xde, 227 YAHOO_SERVICE_YMSG15_STATUS=0xf0, 228 YAHOO_SERVICE_YMSG15_BUDDY_LIST=0xf1, 212 229 }; 213 230 … … 733 750 734 751 memcpy(data + pos, "YMSG", 4); pos += 4; 735 pos += yahoo_put16(data + pos, 0x000c);752 pos += yahoo_put16(data + pos, YAHOO_PROTO_VER); 736 753 pos += yahoo_put16(data + pos, 0x0000); 737 754 pos += yahoo_put16(data + pos, pktlen + extra_pad); … … 747 764 yahoo_send_data(yid->fd, data, len); 748 765 else 749 yahoo_add_to_send_queue(yid, data, len);766 yahoo_add_to_send_queue(yid, data, len); 750 767 FREE(data); 751 768 } … … 1467 1484 1468 1485 if (u->name != NULL) { 1469 if (pkt->service == YAHOO_SERVICE_LOGOFF || u->flags == 0) {1486 if (pkt->service == YAHOO_SERVICE_LOGOFF) { /* || u->flags == 0) { Not in YMSG16 */ 1470 1487 YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, YAHOO_STATUS_OFFLINE, NULL, 1, 0, 0); 1471 1488 } else { 1489 /* Key 47 always seems to be 1 for YMSG16 */ 1490 if(!u->state) 1491 u->away = 0; 1492 else 1493 u->away = 1; 1494 1472 1495 YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, u->name, u->state, u->msg, u->away, u->idle, u->mobile); 1473 1496 } … … 1477 1500 y_list_free_1(t); 1478 1501 FREE(u); 1502 } 1503 } 1504 1505 static void yahoo_process_buddy_list(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 1506 { 1507 struct yahoo_data *yd = yid->yd; 1508 YList *l; 1509 int last_packet = 0; 1510 char *cur_group = NULL; 1511 struct yahoo_buddy *newbud = NULL; 1512 1513 /* we could be getting multiple packets here */ 1514 for (l = pkt->hash; l; l = l->next) { 1515 struct yahoo_pair *pair = l->data; 1516 1517 switch(pair->key) { 1518 case 300: 1519 case 301: 1520 case 302: 1521 case 303: 1522 if ( 315 == atoi(pair->value) ) 1523 last_packet = 1; 1524 break; 1525 case 65: 1526 g_free(cur_group); 1527 cur_group = strdup(pair->value); 1528 break; 1529 case 7: 1530 newbud = y_new0(struct yahoo_buddy, 1); 1531 newbud->id = strdup(pair->value); 1532 if(cur_group) 1533 newbud->group = strdup(cur_group); 1534 else { 1535 struct yahoo_buddy *lastbud = (struct yahoo_buddy *)y_list_nth( 1536 yd->buddies, y_list_length(yd->buddies)-1)->data; 1537 newbud->group = strdup(lastbud->group); 1538 } 1539 1540 yd->buddies = y_list_append(yd->buddies, newbud); 1541 1542 break; 1543 } 1544 } 1545 1546 g_free(cur_group); 1547 1548 /* we could be getting multiple packets here */ 1549 if (last_packet) 1550 return; 1551 1552 YAHOO_CALLBACK(ext_yahoo_got_buddies)(yd->client_id, yd->buddies); 1553 1554 /*** We login at the very end of the packet communication */ 1555 if (!yd->logged_in) { 1556 yd->logged_in = TRUE; 1557 if(yd->current_status < 0) 1558 yd->current_status = yd->initial_status; 1559 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, YAHOO_LOGIN_OK, NULL); 1479 1560 } 1480 1561 } … … 1549 1630 } 1550 1631 1551 if(yd->cookie_y && yd->cookie_t && yd->cookie_c)1632 if(yd->cookie_y && yd->cookie_t) 1552 1633 YAHOO_CALLBACK(ext_yahoo_got_cookies)(yd->client_id); 1553 1634 … … 2226 2307 } 2227 2308 2309 struct yahoo_https_auth_data 2310 { 2311 struct yahoo_input_data *yid; 2312 char *token; 2313 char *chal; 2314 }; 2315 2316 static void yahoo_https_auth_token_init(struct yahoo_https_auth_data *had); 2317 static void yahoo_https_auth_token_finish(struct http_request *req); 2318 static void yahoo_https_auth_init(struct yahoo_https_auth_data *had); 2319 static void yahoo_https_auth_finish(struct http_request *req); 2320 2321 /* Extract a value from a login.yahoo.com response. Assume CRLF-linebreaks 2322 and FAIL miserably if they're not there... */ 2323 static char *yahoo_ha_find_key(char *response, char *key) 2324 { 2325 char *s, *end; 2326 int len = strlen(key); 2327 2328 s = response; 2329 do { 2330 if (strncmp(s, key, len) == 0 && s[len] == '=') { 2331 s += len + 1; 2332 if ((end = strchr(s, '\r'))) 2333 return g_strndup(s, end - s); 2334 else 2335 return g_strdup(s); 2336 } 2337 2338 if ((s = strchr(s, '\n'))) 2339 s ++; 2340 } while (s && *s); 2341 2342 return NULL; 2343 } 2344 2345 static enum yahoo_status yahoo_https_status_parse(int code) 2346 { 2347 switch (code) 2348 { 2349 case 1212: return YAHOO_LOGIN_PASSWD; 2350 case 1213: return YAHOO_LOGIN_LOCK; 2351 case 1235: return YAHOO_LOGIN_UNAME; 2352 default: return (enum yahoo_status) code; 2353 } 2354 } 2355 2356 static void yahoo_process_auth_0x10(struct yahoo_input_data *yid, const char *seed, const char *sn) 2357 { 2358 struct yahoo_https_auth_data *had = g_new0(struct yahoo_https_auth_data, 1); 2359 2360 had->yid = yid; 2361 had->chal = g_strdup(seed); 2362 2363 yahoo_https_auth_token_init(had); 2364 } 2365 2366 static void yahoo_https_auth_token_init(struct yahoo_https_auth_data *had) 2367 { 2368 struct yahoo_input_data *yid = had->yid; 2369 struct yahoo_data *yd = yid->yd; 2370 struct http_request *req; 2371 char *login, *passwd, *chal; 2372 char *url; 2373 2374 login = g_strndup(yd->user, 3 * strlen(yd->user)); 2375 http_encode(login); 2376 passwd = g_strndup(yd->password, 3 * strlen(yd->password)); 2377 http_encode(passwd); 2378 chal = g_strndup(had->chal, 3 * strlen(had->chal)); 2379 http_encode(chal); 2380 2381 url = g_strdup_printf("https://login.yahoo.com/config/pwtoken_get?src=ymsgr&ts=%d&login=%s&passwd=%s&chal=%s", 2382 (int) time(NULL), login, passwd, chal); 2383 2384 req = http_dorequest_url(url, yahoo_https_auth_token_finish, had); 2385 2386 g_free(url); 2387 g_free(chal); 2388 g_free(passwd); 2389 g_free(login); 2390 } 2391 2392 static void yahoo_https_auth_token_finish(struct http_request *req) 2393 { 2394 struct yahoo_https_auth_data *had = req->data; 2395 struct yahoo_input_data *yid = had->yid; 2396 struct yahoo_data *yd = yid->yd; 2397 int st; 2398 2399 if (req->status_code != 200) { 2400 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL); 2401 goto fail; 2402 } 2403 2404 if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) { 2405 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL); 2406 goto fail; 2407 } 2408 2409 if ((had->token = yahoo_ha_find_key(req->reply_body, "ymsgr")) == NULL) { 2410 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3001, NULL); 2411 goto fail; 2412 } 2413 2414 return yahoo_https_auth_init(had); 2415 2416 fail: 2417 g_free(had->token); 2418 g_free(had->chal); 2419 g_free(had); 2420 } 2421 2422 static void yahoo_https_auth_init(struct yahoo_https_auth_data *had) 2423 { 2424 struct http_request *req; 2425 char *url; 2426 2427 url = g_strdup_printf("https://login.yahoo.com/config/pwtoken_login?src=ymsgr&ts=%d&token=%s", 2428 (int) time(NULL), had->token); 2429 2430 req = http_dorequest_url(url, yahoo_https_auth_finish, had); 2431 2432 g_free(url); 2433 } 2434 2435 static void yahoo_https_auth_finish(struct http_request *req) 2436 { 2437 struct yahoo_https_auth_data *had = req->data; 2438 struct yahoo_input_data *yid = had->yid; 2439 struct yahoo_data *yd = yid->yd; 2440 struct yahoo_packet *pack; 2441 char *crumb; 2442 int st; 2443 2444 md5_byte_t result[16]; 2445 md5_state_t ctx; 2446 2447 unsigned char yhash[32]; 2448 2449 if (req->status_code != 200) { 2450 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 2000 + req->status_code, NULL); 2451 goto fail; 2452 } 2453 2454 if (sscanf(req->reply_body, "%d", &st) != 1 || st != 0) { 2455 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, yahoo_https_status_parse(st), NULL); 2456 goto fail; 2457 } 2458 2459 if ((yd->cookie_y = yahoo_ha_find_key(req->reply_body, "Y")) == NULL || 2460 (yd->cookie_t = yahoo_ha_find_key(req->reply_body, "T")) == NULL || 2461 (crumb = yahoo_ha_find_key(req->reply_body, "crumb")) == NULL) { 2462 YAHOO_CALLBACK(ext_yahoo_login_response)(yd->client_id, 3002, NULL); 2463 goto fail; 2464 } 2465 2466 md5_init(&ctx); 2467 md5_append(&ctx, (unsigned char*) crumb, 11); 2468 md5_append(&ctx, (unsigned char*) had->chal, strlen(had->chal)); 2469 md5_finish(&ctx, result); 2470 to_y64(yhash, result, 16); 2471 2472 pack = yahoo_packet_new(YAHOO_SERVICE_AUTHRESP, yd->initial_status, yd->session_id); 2473 yahoo_packet_hash(pack, 1, yd->user); 2474 yahoo_packet_hash(pack, 0, yd->user); 2475 yahoo_packet_hash(pack, 277, yd->cookie_y); 2476 yahoo_packet_hash(pack, 278, yd->cookie_t); 2477 yahoo_packet_hash(pack, 307, (char*) yhash); 2478 yahoo_packet_hash(pack, 244, "524223"); 2479 yahoo_packet_hash(pack, 2, yd->user); 2480 yahoo_packet_hash(pack, 2, "1"); 2481 yahoo_packet_hash(pack, 98, "us"); 2482 yahoo_packet_hash(pack, 135, "7.5.0.647"); 2483 2484 yahoo_send_packet(yid, pack, 0); 2485 2486 yahoo_packet_free(pack); 2487 2488 fail: 2489 g_free(crumb); 2490 g_free(had->token); 2491 g_free(had->chal); 2492 g_free(had); 2493 } 2494 2228 2495 static void yahoo_process_auth(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 2229 2496 { … … 2253 2520 case 1: 2254 2521 yahoo_process_auth_0x0b(yid, seed, sn); 2522 break; 2523 case 2: 2524 yahoo_process_auth_0x10(yid, seed, sn); 2255 2525 break; 2256 2526 default: … … 2408 2678 2409 2679 yd->buddies = y_list_append(yd->buddies, bud); 2410 2680 2411 2681 /* Possibly called already, but at least the call above doesn't 2412 2682 seem to happen every time (not anytime I tried). */ … … 2415 2685 2416 2686 /* YAHOO_CALLBACK(ext_yahoo_status_changed)(yd->client_id, who, status, NULL, (status==YAHOO_STATUS_AVAILABLE?0:1)); */ 2687 } 2688 2689 static void yahoo_process_contact_ymsg13(struct yahoo_input_data *yid, struct yahoo_packet *pkt) 2690 { 2691 char* who=NULL; 2692 char* me=NULL; 2693 char* msg=NULL; 2694 YList *l; 2695 for (l = pkt->hash; l; l = l->next) { 2696 struct yahoo_pair *pair = l->data; 2697 if (pair->key == 4) 2698 who = pair->value; 2699 else if (pair->key == 5) 2700 me = pair->value; 2701 else 2702 DEBUG_MSG(("unknown key: %d = %s", pair->key, pair->value)); 2703 } 2704 2705 if(pkt->status==3) 2706 YAHOO_CALLBACK(ext_yahoo_contact_auth_request)(yid->yd->client_id, me, who, msg); 2417 2707 } 2418 2708 … … 2628 2918 2629 2919 YList *l; 2630 yahoo_dump_unhandled(pkt);2920 // yahoo_dump_unhandled(pkt); 2631 2921 for (l = pkt->hash; l; l = l->next) { 2632 2922 struct yahoo_pair *pair = l->data; … … 2650 2940 { 2651 2941 DEBUG_MSG(("yahoo_packet_process: 0x%02x", pkt->service)); 2942 yahoo_dump_unhandled(pkt); 2652 2943 switch (pkt->service) 2653 2944 { … … 2661 2952 case YAHOO_SERVICE_IDACT: 2662 2953 case YAHOO_SERVICE_IDDEACT: 2954 case YAHOO_SERVICE_Y6_STATUS_UPDATE: 2955 case YAHOO_SERVICE_YMSG15_STATUS: 2663 2956 yahoo_process_status(yid, pkt); 2664 2957 break; … … 2674 2967 yahoo_process_mail(yid, pkt); 2675 2968 break; 2969 case YAHOO_SERVICE_REJECTCONTACT: 2676 2970 case YAHOO_SERVICE_NEWCONTACT: 2677 2971 yahoo_process_contact(yid, pkt); … … 2714 3008 yahoo_process_buddyadd(yid, pkt); 2715 3009 break; 3010 case YAHOO_SERVICE_CONTACT_YMSG13: 3011 yahoo_process_contact_ymsg13(yid,pkt); 3012 break; 2716 3013 case YAHOO_SERVICE_REMBUDDY: 2717 3014 yahoo_process_buddydel(yid, pkt); … … 2742 3039 case YAHOO_SERVICE_CHATLOGOFF: 2743 3040 case YAHOO_SERVICE_CHATMSG: 2744 case YAHOO_SERVICE_REJECTCONTACT:2745 3041 case YAHOO_SERVICE_PEERTOPEER: 2746 3042 WARNING(("unhandled service 0x%02x", pkt->service)); … … 2756 3052 yahoo_process_picture_upload(yid, pkt); 2757 3053 break; 3054 case YAHOO_SERVICE_YMSG15_BUDDY_LIST: /* Buddy List */ 3055 yahoo_process_buddy_list(yid, pkt); 2758 3056 default: 2759 3057 WARNING(("unknown service 0x%02x", pkt->service)); … … 3539 3837 yahoo_process_webcam_connection, 3540 3838 yahoo_process_chatcat_connection, 3541 yahoo_process_search_connection 3839 yahoo_process_search_connection, 3542 3840 }; 3543 3841 … … 3557 3855 } while(len == -1 && errno == EINTR); 3558 3856 3559 if(len == -1 && errno == EAGAIN) /* we'll try again later */3857 if(len == -1 && (errno == EAGAIN||errno == EINTR)) /* we'll try again later */ 3560 3858 return 1; 3561 3859 … … 3760 4058 3761 4059 yahoo_packet_hash(pkt, 5, who); 3762 yahoo_packet_hash(pkt, 4, from?from:yd->user);4060 yahoo_packet_hash(pkt, 1, from?from:yd->user); 3763 4061 yahoo_packet_hash(pkt, 14, " "); 3764 4062 yahoo_packet_hash(pkt, 13, typ ? "1" : "0"); … … 3775 4073 struct yahoo_data *yd; 3776 4074 struct yahoo_packet *pkt = NULL; 3777 int service;4075 int old_status; 3778 4076 char s[4]; 3779 4077 … … 3783 4081 yd = yid->yd; 3784 4082 3785 if (msg) { 4083 old_status = yd->current_status; 4084 4085 if (msg && strncmp(msg,"Invisible",9)) { 3786 4086 yd->current_status = YAHOO_STATUS_CUSTOM; 3787 4087 } else { … … 3789 4089 } 3790 4090 3791 if (yd->current_status == YAHOO_STATUS_AVAILABLE) 3792 service = YAHOO_SERVICE_ISBACK; 3793 else 3794 service = YAHOO_SERVICE_ISAWAY; 4091 /* Thank you libpurple :) */ 4092 if (yd->current_status == YAHOO_STATUS_INVISIBLE) { 4093 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0); 4094 yahoo_packet_hash(pkt, 13, "2"); 4095 yahoo_send_packet(yid, pkt, 0); 4096 yahoo_packet_free(pkt); 4097 4098 return; 4099 } 4100 4101 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_STATUS_UPDATE, yd->current_status, yd->session_id); 4102 snprintf(s, sizeof(s), "%d", yd->current_status); 4103 yahoo_packet_hash(pkt, 10, s); 3795 4104 3796 if ((away == 2) && (yd->current_status == YAHOO_STATUS_AVAILABLE)) { 3797 pkt = yahoo_packet_new(YAHOO_SERVICE_ISAWAY, YAHOO_STATUS_BRB, yd->session_id); 3798 yahoo_packet_hash(pkt, 10, "999"); 3799 yahoo_packet_hash(pkt, 47, "2"); 3800 }else { 3801 pkt = yahoo_packet_new(service, YAHOO_STATUS_AVAILABLE, yd->session_id); 3802 snprintf(s, sizeof(s), "%d", yd->current_status); 3803 yahoo_packet_hash(pkt, 10, s); 3804 if (yd->current_status == YAHOO_STATUS_CUSTOM) { 3805 yahoo_packet_hash(pkt, 19, msg); 3806 yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0"); 3807 } else { 3808 yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0"); 3809 } 3810 3811 3812 3813 } 4105 if (yd->current_status == YAHOO_STATUS_CUSTOM) { 4106 yahoo_packet_hash(pkt, 19, msg); 4107 } else { 4108 yahoo_packet_hash(pkt, 19, ""); 4109 } 4110 4111 yahoo_packet_hash(pkt, 47, (away == 2)? "2": (away) ?"1":"0"); 3814 4112 3815 4113 yahoo_send_packet(yid, pkt, 0); 3816 4114 yahoo_packet_free(pkt); 4115 4116 if(old_status == YAHOO_STATUS_INVISIBLE) { 4117 pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBILITY, YAHOO_STATUS_AVAILABLE, 0); 4118 yahoo_packet_hash(pkt, 13, "1"); 4119 yahoo_send_packet(yid, pkt, 0); 4120 yahoo_packet_free(pkt); 4121 } 3817 4122 } 3818 4123 … … 3829 4134 LOG(("yahoo_logoff: current status: %d", yd->current_status)); 3830 4135 3831 if(yd->current_status != -1) { 4136 if(yd->current_status != -1 && 0) { 4137 /* Meh. Don't send this. The event handlers are not going to 4138 get to do this so it'll just leak memory. And the TCP 4139 connection reset will hopefully be clear enough. */ 3832 4140 pkt = yahoo_packet_new(YAHOO_SERVICE_LOGOFF, YAHOO_STATUS_AVAILABLE, yd->session_id); 3833 4141 yd->current_status = -1; … … 4062 4370 return; 4063 4371 4064 pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YAHOO_STATUS_AVAILABLE, yd->session_id); 4065 yahoo_packet_hash(pkt, 1, yd->user); 4066 yahoo_packet_hash(pkt, 7, who); 4067 yahoo_packet_hash(pkt, 65, group); 4372 pkt = yahoo_packet_new(YAHOO_SERVICE_ADDBUDDY, YPACKET_STATUS_DEFAULT, yd->session_id); 4373 4068 4374 if (msg != NULL) /* add message/request "it's me add me" */ 4069 4375 yahoo_packet_hash(pkt, 14, msg); 4376 else 4377 yahoo_packet_hash(pkt,14,""); 4378 4379 yahoo_packet_hash(pkt, 65, group); 4380 yahoo_packet_hash(pkt, 97, "1"); 4381 yahoo_packet_hash(pkt, 1, yd->user); 4382 yahoo_packet_hash(pkt, 302, "319"); 4383 yahoo_packet_hash(pkt, 300, "319"); 4384 yahoo_packet_hash(pkt, 7, who); 4385 yahoo_packet_hash(pkt, 334, "0"); 4386 yahoo_packet_hash(pkt, 301, "319"); 4387 yahoo_packet_hash(pkt, 303, "319"); 4388 4389 4070 4390 yahoo_send_packet(yid, pkt, 0); 4071 4391 yahoo_packet_free(pkt); … … 4089 4409 yahoo_send_packet(yid, pkt, 0); 4090 4410 yahoo_packet_free(pkt); 4411 } 4412 4413 void yahoo_accept_buddy_ymsg13(int id,const char* me,const char* who){ 4414 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4415 struct yahoo_data *yd; 4416 4417 if(!yid) 4418 return; 4419 yd = yid->yd; 4420 4421 struct yahoo_packet* pkt=NULL; 4422 pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0); 4423 4424 yahoo_packet_hash(pkt,1,me ?: yd->user); 4425 yahoo_packet_hash(pkt,5,who); 4426 yahoo_packet_hash(pkt,13,"1"); 4427 yahoo_packet_hash(pkt,334,"0"); 4428 yahoo_send_packet(yid, pkt, 0); 4429 yahoo_packet_free(pkt); 4430 } 4431 4432 void yahoo_reject_buddy_ymsg13(int id,const char* me,const char* who,const char* msg){ 4433 struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER); 4434 struct yahoo_data *yd; 4435 4436 if(!yid) 4437 return; 4438 yd = yid->yd; 4439 4440 struct yahoo_packet* pkt=NULL; 4441 pkt= yahoo_packet_new(YAHOO_SERVICE_CONTACT_YMSG13,YAHOO_STATUS_AVAILABLE,0); 4442 4443 yahoo_packet_hash(pkt,1,me ?: yd->user); 4444 yahoo_packet_hash(pkt,5,who); 4445 // yahoo_packet_hash(pkt,241,YAHOO_PROTO_VER); 4446 yahoo_packet_hash(pkt,13,"2"); 4447 yahoo_packet_hash(pkt,334,"0"); 4448 yahoo_packet_hash(pkt,97,"1"); 4449 yahoo_packet_hash(pkt,14,msg?:""); 4450 4451 yahoo_send_packet(yid, pkt, 0); 4452 yahoo_packet_free(pkt); 4453 4091 4454 } 4092 4455 -
protocols/yahoo/yahoo.c
raac4017 r2288705 197 197 { 198 198 struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data; 199 200 ic->away = NULL; 199 char *away; 200 201 away = NULL; 201 202 202 203 if( state && msg && g_strcasecmp( state, msg ) != 0 ) 203 204 { 204 205 yd->current_status = YAHOO_STATUS_CUSTOM; 205 ic->away = "";206 away = ""; 206 207 } 207 208 else if( state ) … … 212 213 msg = NULL; 213 214 214 ic->away = "";215 away = ""; 215 216 if( g_strcasecmp( state, "Available" ) == 0 ) 216 217 { 217 218 yd->current_status = YAHOO_STATUS_AVAILABLE; 218 ic->away = NULL;219 away = NULL; 219 220 } 220 221 else if( g_strcasecmp( state, "Be Right Back" ) == 0 ) … … 242 243 yd->current_status = YAHOO_STATUS_AVAILABLE; 243 244 244 ic->away = NULL;245 away = NULL; 245 246 } 246 247 } … … 248 249 yd->current_status = YAHOO_STATUS_AVAILABLE; 249 250 250 yahoo_set_away( yd->y2_id, yd->current_status, msg, ic->away != NULL ? 2 : 0 );251 yahoo_set_away( yd->y2_id, yd->current_status, msg, away != NULL ? 2 : 0 ); 251 252 } 252 253 253 254 static GList *byahoo_away_states( struct im_connection *ic ) 254 255 { 255 GList *m = NULL; 256 257 m = g_list_append( m, "Available" ); 258 m = g_list_append( m, "Be Right Back" ); 259 m = g_list_append( m, "Busy" ); 260 m = g_list_append( m, "Not At Home" ); 261 m = g_list_append( m, "Not At Desk" ); 262 m = g_list_append( m, "Not In Office" ); 263 m = g_list_append( m, "On Phone" ); 264 m = g_list_append( m, "On Vacation" ); 265 m = g_list_append( m, "Out To Lunch" ); 266 m = g_list_append( m, "Stepped Out" ); 267 m = g_list_append( m, "Invisible" ); 268 m = g_list_append( m, GAIM_AWAY_CUSTOM ); 256 static GList *m = NULL; 257 258 if( m == NULL ) 259 { 260 m = g_list_append( m, "Available" ); 261 m = g_list_append( m, "Be Right Back" ); 262 m = g_list_append( m, "Busy" ); 263 m = g_list_append( m, "Not At Home" ); 264 m = g_list_append( m, "Not At Desk" ); 265 m = g_list_append( m, "Not In Office" ); 266 m = g_list_append( m, "On Phone" ); 267 m = g_list_append( m, "On Vacation" ); 268 m = g_list_append( m, "Out To Lunch" ); 269 m = g_list_append( m, "Stepped Out" ); 270 m = g_list_append( m, "Invisible" ); 271 m = g_list_append( m, GAIM_AWAY_CUSTOM ); 272 } 269 273 270 274 return m; … … 345 349 346 350 return c; 351 } 352 353 static void byahoo_auth_allow( struct im_connection *ic, const char *who ) 354 { 355 struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data; 356 357 yahoo_accept_buddy_ymsg13( yd->y2_id, NULL, who ); 358 } 359 360 static void byahoo_auth_deny( struct im_connection *ic, const char *who ) 361 { 362 struct byahoo_data *yd = (struct byahoo_data *) ic->proto_data; 363 364 yahoo_reject_buddy_ymsg13( yd->y2_id, NULL, who, NULL ); 347 365 } 348 366 … … 372 390 ret->handle_cmp = g_strcasecmp; 373 391 392 ret->auth_allow = byahoo_auth_allow; 393 ret->auth_deny = byahoo_auth_deny; 394 374 395 register_protocol(ret); 375 396 } … … 451 472 struct byahoo_write_ready_data *d = data; 452 473 453 yahoo_write_ready( d->id, d->fd, d->data ); 454 455 return FALSE; 474 return yahoo_write_ready( d->id, d->fd, d->data ); 456 475 } 457 476 … … 790 809 { 791 810 struct byahoo_conf_invitation *inv = data; 792 793 yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name ); 794 imcb_chat_add_buddy( inv->c, inv->ic->acc->user ); 811 struct groupchat *b; 812 813 for( b = inv->ic->groupchats; b; b = b->next ) 814 if( b == inv->c ) 815 break; 816 817 if( b != NULL ) 818 { 819 yahoo_conference_logon( inv->yid, NULL, inv->members, inv->name ); 820 imcb_chat_add_buddy( inv->c, inv->ic->acc->user ); 821 } 822 else 823 { 824 imcb_log( inv->ic, "Duplicate/corrupted invitation to `%s'.", inv->name ); 825 } 826 795 827 g_free( inv->name ); 796 828 g_free( inv ); … … 908 940 } 909 941 942 void ext_yahoo_contact_auth_request( int id, const char *myid, const char *who, const char *msg ) 943 { 944 struct im_connection *ic = byahoo_get_ic_by_id( id ); 945 946 imcb_ask_auth( ic, who, NULL ); 947 } 948 910 949 void ext_yahoo_contact_added( int id, const char *myid, const char *who, const char *msg ) 911 950 { 912 /* Groups schmoups. If I want to handle groups properly I can get the913 buddy data from some internal libyahoo2 structure. */914 imcb_add_buddy( byahoo_get_ic_by_id( id ), (char*) who, NULL );951 struct im_connection *ic = byahoo_get_ic_by_id( id ); 952 953 imcb_add_buddy( ic, (char*) who, NULL ); 915 954 } 916 955 -
protocols/yahoo/yahoo2.h
raac4017 r2288705 217 217 void yahoo_buddyicon_request(int id, const char *who); 218 218 219 void yahoo_accept_buddy_ymsg13(int,const char*,const char*); 220 void yahoo_reject_buddy_ymsg13(int,const char*,const char*,const char*); 221 219 222 #include "yahoo_httplib.h" 220 223 -
protocols/yahoo/yahoo2_callbacks.h
raac4017 r2288705 361 361 362 362 /* 363 * Name: ext_yahoo_contact_auth_request 364 * Called when a contact wants to add you to his/her contact list 365 * Params: 366 * id - the id that identifies the server connection 367 * myid - the identity s/he added 368 * who - who did it 369 * msg - any message sent 370 */ 371 void YAHOO_CALLBACK_TYPE(ext_yahoo_contact_auth_request)(int id, const char *myid, const char *who, const char *msg); 372 373 374 /* 363 375 * Name: ext_yahoo_contact_added 364 376 * Called when a contact is added to your list -
protocols/yahoo/yahoo2_types.h
raac4017 r2288705 57 57 YAHOO_LOGIN_LOCK = 14, 58 58 YAHOO_LOGIN_DUPL = 99, 59 YAHOO_LOGIN_SOCK = -1 59 YAHOO_LOGIN_SOCK = -1, 60 }; 61 62 enum ypacket_status { 63 YPACKET_STATUS_DISCONNECTED = -1, 64 YPACKET_STATUS_DEFAULT = 0, 65 YPACKET_STATUS_SERVERACK = 1, 66 YPACKET_STATUS_GAME = 0x2, 67 YPACKET_STATUS_AWAY = 0x4, 68 YPACKET_STATUS_CONTINUED = 0x5, 69 YPACKET_STATUS_INVISIBLE = 12, 70 YPACKET_STATUS_NOTIFY = 0x16, /* TYPING */ 71 YPACKET_STATUS_WEBLOGIN = 0x5a55aa55, 72 YPACKET_STATUS_OFFLINE = 0x5a55aa56 60 73 }; 61 74 … … 85 98 }; 86 99 87 #define YAHOO_PROTO_VER 0x00 0b100 #define YAHOO_PROTO_VER 0x0010 88 101 89 102 /* Yahoo style/color directives */ … … 115 128 YAHOO_CONNECTION_WEBCAM, 116 129 YAHOO_CONNECTION_CHATCAT, 117 YAHOO_CONNECTION_SEARCH 130 YAHOO_CONNECTION_SEARCH, 131 YAHOO_CONNECTION_AUTH, 118 132 }; 119 133 … … 131 145 /* chat member attribs */ 132 146 #define YAHOO_CHAT_MALE 0x8000 133 #define YAHOO_CHAT_FEMALE 0x10000134 147 #define YAHOO_CHAT_FEMALE 0x10000 135 148 #define YAHOO_CHAT_DUNNO 0x400 -
root_commands.c
raac4017 r2288705 29 29 #include "bitlbee.h" 30 30 #include "help.h" 31 #include "chat.h" 31 32 32 33 #include <string.h> … … 78 79 } 79 80 81 #define MIN_ARGS( x, y... ) \ 82 do \ 83 { \ 84 int blaat; \ 85 for( blaat = 0; blaat <= x; blaat ++ ) \ 86 if( cmd[blaat] == NULL ) \ 87 { \ 88 irc_usermsg( irc, "Not enough parameters given (need %d).", x ); \ 89 return y; \ 90 } \ 91 } while( 0 ) 92 80 93 void root_command( irc_t *irc, char *cmd[] ) 81 94 { … … 88 101 if( g_strcasecmp( commands[i].command, cmd[0] ) == 0 ) 89 102 { 90 if( !cmd[commands[i].required_parameters] ) 91 { 92 irc_usermsg( irc, "Not enough parameters given (need %d)", commands[i].required_parameters ); 93 return; 94 } 103 MIN_ARGS( commands[i].required_parameters ); 104 95 105 commands[i].execute( irc, cmd ); 96 106 return; … … 131 141 static void cmd_identify( irc_t *irc, char **cmd ) 132 142 { 133 storage_status_t status = storage_load( irc ->nick, cmd[1], irc);143 storage_status_t status = storage_load( irc, cmd[1] ); 134 144 char *account_on[] = { "account", "on", NULL }; 135 145 … … 143 153 case STORAGE_OK: 144 154 irc_usermsg( irc, "Password accepted, settings and accounts loaded" ); 155 irc_setpass( irc, cmd[1] ); 156 irc->status |= USTATUS_IDENTIFIED; 145 157 irc_umode_set( irc, "+R", 1 ); 146 158 if( set_getbool( &irc->set, "auto_connect" ) ) … … 162 174 } 163 175 164 irc_setpass( irc, cmd[1] ); 165 switch( storage_save( irc, FALSE )) { 176 switch( storage_save( irc, cmd[1], FALSE ) ) { 166 177 case STORAGE_ALREADY_EXISTS: 167 178 irc_usermsg( irc, "Nick is already registered" ); … … 170 181 case STORAGE_OK: 171 182 irc_usermsg( irc, "Account successfully created" ); 183 irc_setpass( irc, cmd[1] ); 172 184 irc->status |= USTATUS_IDENTIFIED; 173 185 irc_umode_set( irc, "+R", 1 ); … … 238 250 } 239 251 252 static void cmd_showset( irc_t *irc, set_t **head, char *key ) 253 { 254 char *val; 255 256 if( ( val = set_getstr( head, key ) ) ) 257 irc_usermsg( irc, "%s = `%s'", key, val ); 258 else 259 irc_usermsg( irc, "%s is empty", key ); 260 } 261 262 typedef set_t** (*cmd_set_findhead)( irc_t*, char* ); 263 typedef int (*cmd_set_checkflags)( irc_t*, set_t *set ); 264 265 static int cmd_set_real( irc_t *irc, char **cmd, cmd_set_findhead findhead, cmd_set_checkflags checkflags ) 266 { 267 char *set_full = NULL, *set_name = NULL, *tmp; 268 set_t **head; 269 270 if( cmd[1] && g_strncasecmp( cmd[1], "-del", 4 ) == 0 ) 271 { 272 MIN_ARGS( 2, 0 ); 273 set_full = cmd[2]; 274 } 275 else 276 set_full = cmd[1]; 277 278 if( findhead == NULL ) 279 { 280 set_name = set_full; 281 282 head = &irc->set; 283 } 284 else 285 { 286 char *id; 287 288 if( ( tmp = strchr( set_full, '/' ) ) ) 289 { 290 id = g_strndup( set_full, ( tmp - set_full ) ); 291 set_name = tmp + 1; 292 } 293 else 294 { 295 id = g_strdup( set_full ); 296 } 297 298 if( ( head = findhead( irc, id ) ) == NULL ) 299 { 300 g_free( id ); 301 irc_usermsg( irc, "Could not find setting." ); 302 return 0; 303 } 304 g_free( id ); 305 } 306 307 if( cmd[1] && cmd[2] && set_name ) 308 { 309 set_t *s = set_find( head, set_name ); 310 int st; 311 312 if( s && checkflags && checkflags( irc, s ) == 0 ) 313 return 0; 314 315 if( g_strncasecmp( cmd[1], "-del", 4 ) == 0 ) 316 st = set_reset( head, set_name ); 317 else 318 st = set_setstr( head, set_name, cmd[2] ); 319 320 if( set_getstr( head, set_name ) == NULL ) 321 { 322 if( st ) 323 irc_usermsg( irc, "Setting changed successfully" ); 324 else 325 irc_usermsg( irc, "Failed to change setting" ); 326 } 327 else 328 { 329 cmd_showset( irc, head, set_name ); 330 } 331 } 332 else if( set_name ) 333 { 334 cmd_showset( irc, head, set_name ); 335 } 336 else 337 { 338 set_t *s = *head; 339 while( s ) 340 { 341 cmd_showset( irc, &s, s->key ); 342 s = s->next; 343 } 344 } 345 346 return 1; 347 } 348 349 static set_t **cmd_account_set_findhead( irc_t *irc, char *id ) 350 { 351 account_t *a; 352 353 if( ( a = account_get( irc, id ) ) ) 354 return &a->set; 355 else 356 return NULL; 357 } 358 359 static int cmd_account_set_checkflags( irc_t *irc, set_t *s ) 360 { 361 account_t *a = s->data; 362 363 if( a->ic && s && s->flags & ACC_SET_OFFLINE_ONLY ) 364 { 365 irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "off" ); 366 return 0; 367 } 368 else if( !a->ic && s && s->flags & ACC_SET_ONLINE_ONLY ) 369 { 370 irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "on" ); 371 return 0; 372 } 373 374 return 1; 375 } 376 240 377 static void cmd_account( irc_t *irc, char **cmd ) 241 378 { … … 252 389 struct prpl *prpl; 253 390 254 if( cmd[2] == NULL || cmd[3] == NULL || cmd[4] == NULL ) 255 { 256 irc_usermsg( irc, "Not enough parameters" ); 257 return; 258 } 259 260 prpl = find_protocol(cmd[2]); 391 MIN_ARGS( 4 ); 392 393 prpl = find_protocol( cmd[2] ); 261 394 262 395 if( prpl == NULL ) … … 278 411 else if( g_strcasecmp( cmd[1], "del" ) == 0 ) 279 412 { 280 if( !cmd[2] ) 281 { 282 irc_usermsg( irc, "Not enough parameters given (need %d)", 2 ); 283 } 284 else if( !( a = account_get( irc, cmd[2] ) ) ) 413 MIN_ARGS( 2 ); 414 415 if( !( a = account_get( irc, cmd[2] ) ) ) 285 416 { 286 417 irc_usermsg( irc, "Invalid account" ); … … 410 541 else if( g_strcasecmp( cmd[1], "set" ) == 0 ) 411 542 { 412 char *acc_handle, *set_name = NULL, *tmp; 413 414 if( !cmd[2] ) 415 { 416 irc_usermsg( irc, "Not enough parameters given (need %d)", 2 ); 417 return; 418 } 419 420 if( g_strncasecmp( cmd[2], "-del", 4 ) == 0 ) 421 acc_handle = g_strdup( cmd[3] ); 422 else 423 acc_handle = g_strdup( cmd[2] ); 424 425 if( !acc_handle ) 426 { 427 irc_usermsg( irc, "Not enough parameters given (need %d)", 3 ); 428 return; 429 } 430 431 if( ( tmp = strchr( acc_handle, '/' ) ) ) 432 { 433 *tmp = 0; 434 set_name = tmp + 1; 435 } 436 437 if( ( a = account_get( irc, acc_handle ) ) == NULL ) 438 { 439 g_free( acc_handle ); 440 irc_usermsg( irc, "Invalid account" ); 441 return; 442 } 443 444 if( cmd[3] && set_name ) 445 { 446 set_t *s = set_find( &a->set, set_name ); 447 448 if( a->ic && s && s->flags & ACC_SET_OFFLINE_ONLY ) 449 { 450 g_free( acc_handle ); 451 irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "off" ); 452 return; 453 } 454 else if( !a->ic && s && s->flags & ACC_SET_ONLINE_ONLY ) 455 { 456 g_free( acc_handle ); 457 irc_usermsg( irc, "This setting can only be changed when the account is %s-line", "on" ); 458 return; 459 } 460 461 if( g_strncasecmp( cmd[2], "-del", 4 ) == 0 ) 462 set_reset( &a->set, set_name ); 463 else 464 set_setstr( &a->set, set_name, cmd[3] ); 465 } 466 if( set_name ) /* else 'forgotten' on purpose.. Must show new value after changing */ 467 { 468 char *s = set_getstr( &a->set, set_name ); 469 if( s ) 470 irc_usermsg( irc, "%s = `%s'", set_name, s ); 471 else 472 irc_usermsg( irc, "%s is empty", set_name ); 473 } 474 else 475 { 476 set_t *s = a->set; 477 while( s ) 478 { 479 if( s->value || s->def ) 480 irc_usermsg( irc, "%s = `%s'", s->key, s->value ? s->value : s->def ); 481 else 482 irc_usermsg( irc, "%s is empty", s->key ); 483 s = s->next; 484 } 485 } 486 487 g_free( acc_handle ); 488 } 489 else 490 { 491 irc_usermsg( irc, "Unknown command: account %s. Please use \x02help commands\x02 to get a list of available commands.", cmd[1] ); 543 MIN_ARGS( 2 ); 544 545 cmd_set_real( irc, cmd + 1, cmd_account_set_findhead, cmd_account_set_checkflags ); 546 } 547 else 548 { 549 irc_usermsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "account", cmd[1] ); 492 550 } 493 551 } … … 500 558 if( g_strcasecmp( cmd[1], "-tmp" ) == 0 ) 501 559 { 560 MIN_ARGS( 3 ); 502 561 add_on_server = 0; 503 562 cmd ++; … … 610 669 irc->mynick = g_strdup( cmd[2] ); 611 670 671 /* If we're called internally (user did "set root_nick"), 672 let's not go O(INF). :-) */ 612 673 if( strcmp( cmd[0], "set_rename" ) != 0 ) 613 674 set_setstr( &irc->set, "root_nick", cmd[2] ); … … 633 694 } 634 695 635 return strcmp( irc->mynick, new_nick ) == 0 ? new_nick : NULL;696 return strcmp( irc->mynick, new_nick ) == 0 ? new_nick : SET_INVALID; 636 697 } 637 698 … … 817 878 static void cmd_set( irc_t *irc, char **cmd ) 818 879 { 819 char *set_name = cmd[1]; 820 821 if( cmd[1] && cmd[2] ) 822 { 823 if( g_strncasecmp( cmd[1], "-del", 4 ) == 0 ) 824 { 825 set_reset( &irc->set, cmd[2] ); 826 set_name = cmd[2]; 827 } 828 else 829 { 830 set_setstr( &irc->set, cmd[1], cmd[2] ); 831 } 832 } 833 if( set_name ) /* else 'forgotten' on purpose.. Must show new value after changing */ 834 { 835 char *s = set_getstr( &irc->set, set_name ); 836 if( s ) 837 irc_usermsg( irc, "%s = `%s'", set_name, s ); 838 else 839 irc_usermsg( irc, "%s is empty", set_name ); 840 841 if( strchr( set_name, '/' ) ) 842 irc_usermsg( irc, "Warning: / found in setting name, you're probably looking for the `account set' command." ); 843 } 844 else 845 { 846 set_t *s = irc->set; 847 while( s ) 848 { 849 if( s->value || s->def ) 850 irc_usermsg( irc, "%s = `%s'", s->key, s->value ? s->value : s->def ); 851 else 852 irc_usermsg( irc, "%s is empty", s->key ); 853 s = s->next; 854 } 855 } 880 cmd_set_real( irc, cmd, NULL, NULL ); 856 881 } 857 882 858 883 static void cmd_save( irc_t *irc, char **cmd ) 859 884 { 860 if( storage_save( irc, TRUE ) == STORAGE_OK ) 885 if( ( irc->status & USTATUS_IDENTIFIED ) == 0 ) 886 irc_usermsg( irc, "Please create an account first" ); 887 else if( storage_save( irc, NULL, TRUE ) == STORAGE_OK ) 861 888 irc_usermsg( irc, "Configuration saved" ); 862 889 else … … 974 1001 static void cmd_join_chat( irc_t *irc, char **cmd ) 975 1002 { 1003 irc_usermsg( irc, "This command is now obsolete. " 1004 "Please try the `chat' command instead." ); 1005 } 1006 1007 static set_t **cmd_chat_set_findhead( irc_t *irc, char *id ) 1008 { 1009 struct chat *c; 1010 1011 if( ( c = chat_get( irc, id ) ) ) 1012 return &c->set; 1013 else 1014 return NULL; 1015 } 1016 1017 static void cmd_chat( irc_t *irc, char **cmd ) 1018 { 1019 account_t *acc; 1020 struct chat *c; 1021 1022 if( g_strcasecmp( cmd[1], "add" ) == 0 ) 1023 { 1024 char *channel, *s; 1025 1026 MIN_ARGS( 3 ); 1027 1028 if( !( acc = account_get( irc, cmd[2] ) ) ) 1029 { 1030 irc_usermsg( irc, "Invalid account" ); 1031 return; 1032 } 1033 1034 if( cmd[4] == NULL ) 1035 { 1036 channel = g_strdup( cmd[3] ); 1037 if( ( s = strchr( channel, '@' ) ) ) 1038 *s = 0; 1039 } 1040 else 1041 { 1042 channel = g_strdup( cmd[4] ); 1043 } 1044 1045 if( strchr( CTYPES, channel[0] ) == NULL ) 1046 { 1047 s = g_strdup_printf( "%c%s", CTYPES[0], channel ); 1048 g_free( channel ); 1049 channel = s; 1050 } 1051 1052 if( ( c = chat_add( irc, acc, cmd[3], channel ) ) ) 1053 irc_usermsg( irc, "Chatroom added successfully." ); 1054 else 1055 irc_usermsg( irc, "Could not add chatroom." ); 1056 1057 g_free( channel ); 1058 } 1059 else if( g_strcasecmp( cmd[1], "list" ) == 0 ) 1060 { 1061 int i = 0; 1062 1063 if( strchr( irc->umode, 'b' ) ) 1064 irc_usermsg( irc, "Chatroom list:" ); 1065 1066 for( c = irc->chatrooms; c; c = c->next ) 1067 { 1068 irc_usermsg( irc, "%2d. %s(%s) %s, %s", i, c->acc->prpl->name, 1069 c->acc->user, c->handle, c->channel ); 1070 1071 i ++; 1072 } 1073 irc_usermsg( irc, "End of chatroom list" ); 1074 } 1075 else if( g_strcasecmp( cmd[1], "set" ) == 0 ) 1076 { 1077 MIN_ARGS( 2 ); 1078 1079 cmd_set_real( irc, cmd + 1, cmd_chat_set_findhead, NULL ); 1080 } 1081 else if( g_strcasecmp( cmd[1], "del" ) == 0 ) 1082 { 1083 MIN_ARGS( 2 ); 1084 1085 if( ( c = chat_get( irc, cmd[2] ) ) ) 1086 { 1087 chat_del( irc, c ); 1088 } 1089 else 1090 { 1091 irc_usermsg( irc, "Could not remove chat." ); 1092 } 1093 } 1094 else if( g_strcasecmp( cmd[1], "with" ) == 0 ) 1095 { 1096 user_t *u; 1097 1098 MIN_ARGS( 2 ); 1099 1100 if( ( u = user_find( irc, cmd[2] ) ) && u->ic && u->ic->acc->prpl->chat_with ) 1101 { 1102 if( !u->ic->acc->prpl->chat_with( u->ic, u->handle ) ) 1103 { 1104 irc_usermsg( irc, "(Possible) failure while trying to open " 1105 "a groupchat with %s.", u->nick ); 1106 } 1107 } 1108 else 1109 { 1110 irc_usermsg( irc, "Can't open a groupchat with %s.", cmd[2] ); 1111 } 1112 } 1113 else 1114 { 1115 irc_usermsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "chat", cmd[1] ); 1116 } 1117 1118 1119 1120 #if 0 976 1121 account_t *a; 977 1122 struct im_connection *ic; … … 999 1144 if( cmd[3] ) 1000 1145 { 1001 if( cmd[3][0] != '#' && cmd[3][0] != '&')1146 if( strchr( CTYPES, cmd[3][0] ) == NULL ) 1002 1147 channel = g_strdup_printf( "&%s", cmd[3] ); 1003 1148 else … … 1042 1187 g_free( channel ); 1043 1188 } 1189 #endif 1044 1190 } 1045 1191 … … 1129 1275 { "qlist", 0, cmd_qlist, 0 }, 1130 1276 { "join_chat", 2, cmd_join_chat, 0 }, 1277 { "chat", 1, cmd_chat, 0 }, 1131 1278 { "transfers", 0, cmd_transfers, 0 }, 1132 1279 { NULL } -
set.c
raac4017 r2288705 25 25 #define BITLBEE_CORE 26 26 #include "bitlbee.h" 27 28 /* Used to use NULL for this, but NULL is actually a "valid" value. */ 29 char *SET_INVALID = "nee"; 27 30 28 31 set_t *set_add( set_t **head, char *key, char *def, set_eval eval, void *data ) … … 114 117 115 118 if( !s ) 119 /* 120 Used to do this, but it never really made sense. 116 121 s = set_add( head, key, NULL, NULL, NULL ); 117 118 if( s->eval && !( nv = s->eval( s, value ) ) ) 122 */ 123 return 0; 124 125 if( value == NULL && ( s->flags & SET_NULL_OK ) == 0 ) 126 return 0; 127 128 /* Call the evaluator. For invalid values, evaluators should now 129 return SET_INVALID, but previously this was NULL. Try to handle 130 that too if NULL is not an allowed value for this setting. */ 131 if( s->eval && ( ( nv = s->eval( s, value ) ) == SET_INVALID || 132 ( ( s->flags & SET_NULL_OK ) == 0 && nv == NULL ) ) ) 119 133 return 0; 120 134 … … 168 182 } 169 183 170 voidset_reset( set_t **head, char *key )184 int set_reset( set_t **head, char *key ) 171 185 { 172 186 set_t *s; … … 174 188 s = set_find( head, key ); 175 189 if( s ) 176 set_setstr( head, key, s->def ); 190 return set_setstr( head, key, s->def ); 191 192 return 0; 177 193 } 178 194 … … 187 203 for( ; *s; s ++ ) 188 204 if( !isdigit( *s ) ) 189 return NULL;205 return SET_INVALID; 190 206 191 207 return value; … … 194 210 char *set_eval_bool( set_t *set, char *value ) 195 211 { 196 return is_bool( value ) ? value : NULL;212 return is_bool( value ) ? value : SET_INVALID; 197 213 } 198 214 … … 226 242 irc->channel, "-oo", irc->nick, irc->mynick ); 227 243 else 228 return NULL;244 return SET_INVALID; 229 245 230 246 return value; -
set.h
raac4017 r2288705 44 44 typedef char *(*set_eval) ( struct set *set, char *value ); 45 45 46 extern char *SET_INVALID; 47 48 #define SET_NULL_OK 0x0100 49 46 50 typedef struct set 47 51 { … … 61 65 this (yet?). */ 62 66 63 /* Eval: Returns NULL if the value is incorrect or exactly the64 passed value variable. When returning a corrected value,67 /* Eval: Returns SET_INVALID if the value is incorrect or exactly 68 the passed value variable. When returning a corrected value, 65 69 set_setstr() should be able to free() the returned string! */ 66 70 set_eval eval; … … 88 92 int set_setint( set_t **head, char *key, int value ); 89 93 void set_del( set_t **head, char *key ); 90 voidset_reset( set_t **head, char *key );94 int set_reset( set_t **head, char *key ); 91 95 92 96 /* Two very useful generic evaluators. */ -
storage.c
raac4017 r2288705 103 103 } 104 104 105 storage_status_t storage_load (const char *nick, const char *password, irc_t * irc) 106 { 107 GList *gl; 105 storage_status_t storage_load (irc_t * irc, const char *password) 106 { 107 GList *gl; 108 109 if (irc && irc->status & USTATUS_IDENTIFIED) 110 return STORAGE_OTHER_ERROR; 108 111 109 112 /* Loop until we don't get NO_SUCH_USER */ … … 112 115 storage_status_t status; 113 116 114 status = st->load(nick, password, irc); 115 if (status == STORAGE_OK) { 116 irc_setpass(irc, password); 117 status = st->load(irc, password); 118 if (status == STORAGE_OK) 117 119 return status; 118 }119 120 120 121 if (status != STORAGE_NO_SUCH_USER) … … 125 126 } 126 127 127 storage_status_t storage_save (irc_t *irc, int overwrite) 128 { 129 return ((storage_t *)global.storage->data)->save(irc, overwrite); 128 storage_status_t storage_save (irc_t *irc, char *password, int overwrite) 129 { 130 storage_status_t st; 131 132 if (password != NULL) { 133 /* Should only use this in the "register" command. */ 134 if (irc->password || overwrite) 135 return STORAGE_OTHER_ERROR; 136 137 irc_setpass(irc, password); 138 } else if ((irc->status & USTATUS_IDENTIFIED) == 0) { 139 return STORAGE_NO_SUCH_USER; 140 } 141 142 st = ((storage_t *)global.storage->data)->save(irc, overwrite); 143 144 if (password != NULL) { 145 irc_setpass(irc, NULL); 146 } 147 148 return st; 130 149 } 131 150 … … 143 162 144 163 status = st->remove(nick, password); 145 if (status != STORAGE_NO_SUCH_USER && 146 status != STORAGE_OK) 164 if (status != STORAGE_NO_SUCH_USER && status != STORAGE_OK) 147 165 ret = status; 148 166 } … … 150 168 return ret; 151 169 } 170 171 #if 0 172 Not using this yet. Test thoroughly before adding UI hooks to this function. 152 173 153 174 storage_status_t storage_rename (const char *onick, const char *nnick, const char *password) … … 189 210 return STORAGE_OK; 190 211 } 212 #endif -
storage.h
raac4017 r2288705 45 45 storage_status_t (*check_pass) (const char *nick, const char *password); 46 46 47 storage_status_t (*load) ( const char *nick, const char *password, irc_t * irc);47 storage_status_t (*load) (irc_t *irc, const char *password); 48 48 storage_status_t (*save) (irc_t *irc, int overwrite); 49 49 storage_status_t (*remove) (const char *nick, const char *password); … … 55 55 storage_status_t storage_check_pass (const char *nick, const char *password); 56 56 57 storage_status_t storage_load ( const char *nick, const char *password, irc_t * irc);58 storage_status_t storage_save (irc_t *irc, int overwrite);57 storage_status_t storage_load (irc_t * irc, const char *password); 58 storage_status_t storage_save (irc_t *irc, char *password, int overwrite); 59 59 storage_status_t storage_remove (const char *nick, const char *password); 60 60 61 storage_status_t storage_rename (const char *onick, const char *nnick, const char *password); 61 /* storage_status_t storage_rename (const char *onick, const char *nnick, const char *password); */ 62 62 63 63 void register_storage_backend(storage_t *); -
storage_text.c
raac4017 r2288705 44 44 } 45 45 46 static storage_status_t text_load ( const char *my_nick, const char* password, irc_t *irc)46 static storage_status_t text_load( irc_t *irc, const char* password ) 47 47 { 48 48 char s[512]; … … 54 54 account_t *acc, *acc_lookup[9]; 55 55 56 if( irc->status & USTATUS_IDENTIFIED ) 57 return( 1 ); 58 59 g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".accounts" ); 56 g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".accounts" ); 60 57 fp = fopen( s, "r" ); 61 58 if( !fp ) return STORAGE_NO_SUCH_USER; … … 68 65 return STORAGE_INVALID_PASSWORD; 69 66 } 70 71 /* Do this now. If the user runs with AuthMode = Registered, the72 account command will not work otherwise. */73 irc->status |= USTATUS_IDENTIFIED;74 67 75 68 while( fscanf( fp, "%511[^\n]s", s ) > 0 ) … … 101 94 } 102 95 103 g_snprintf( s, 511, "%s%s%s", global.conf->configdir, my_nick, ".nicks" );96 g_snprintf( s, 511, "%s%s%s", global.conf->configdir, irc->nick, ".nicks" ); 104 97 fp = fopen( s, "r" ); 105 98 if( !fp ) return STORAGE_NO_SUCH_USER; -
storage_xml.c
raac4017 r2288705 29 29 #include "arc.h" 30 30 #include "md5.h" 31 #include "chat.h" 32 33 #if GLIB_CHECK_VERSION(2,8,0) 31 34 #include <glib/gstdio.h> 32 33 #if !GLIB_CHECK_VERSION(2,8,0) 35 #else 34 36 /* GLib < 2.8.0 doesn't have g_access, so just use the system access(). */ 37 #include <unistd.h> 35 38 #define g_access access 36 39 #endif … … 52 55 char *current_setting; 53 56 account_t *current_account; 57 struct chat *current_chat; 58 set_t **current_set_head; 54 59 char *given_nick; 55 60 char *given_pass; … … 170 175 171 176 if( ( setting = xml_attr( attr_names, attr_values, "name" ) ) ) 177 { 178 if( xd->current_chat != NULL ) 179 xd->current_set_head = &xd->current_chat->set; 180 else if( xd->current_account != NULL ) 181 xd->current_set_head = &xd->current_account->set; 182 else 183 xd->current_set_head = &xd->irc->set; 184 172 185 xd->current_setting = g_strdup( setting ); 186 } 173 187 else 174 188 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, … … 192 206 } 193 207 } 208 else if( g_strcasecmp( element_name, "chat" ) == 0 ) 209 { 210 char *handle, *channel; 211 212 handle = xml_attr( attr_names, attr_values, "handle" ); 213 channel = xml_attr( attr_names, attr_values, "channel" ); 214 215 if( xd->current_account && handle && channel ) 216 { 217 xd->current_chat = chat_add( xd->irc, xd->current_account, handle, channel ); 218 } 219 else 220 { 221 g_set_error( error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, 222 "Missing attributes for %s element", element_name ); 223 } 224 } 194 225 else 195 226 { … … 212 243 xd->current_account = NULL; 213 244 } 245 else if( g_strcasecmp( element_name, "chat" ) == 0 ) 246 { 247 xd->current_chat = NULL; 248 } 214 249 } 215 250 … … 218 253 char text[text_len+1]; 219 254 struct xml_parsedata *xd = data; 220 irc_t *irc = xd->irc;221 255 222 256 strncpy( text, text_orig, text_len ); … … 231 265 else if( g_strcasecmp( g_markup_parse_context_get_element( ctx ), "setting" ) == 0 && xd->current_setting ) 232 266 { 233 set_setstr( xd->current_account ? &xd->current_account->set : &irc->set, 234 xd->current_setting, (char*) text ); 267 set_setstr( xd->current_set_head, xd->current_setting, (char*) text ); 235 268 g_free( xd->current_setting ); 236 269 xd->current_setting = NULL; … … 256 289 } 257 290 258 static storage_status_t xml_load_real( const char *my_nick, const char *password, irc_t *irc, xml_pass_st action )291 static storage_status_t xml_load_real( irc_t *irc, const char *my_nick, const char *password, xml_pass_st action ) 259 292 { 260 293 GMarkupParseContext *ctx; … … 263 296 GError *gerr = NULL; 264 297 int fd, st; 265 266 if( irc && irc->status & USTATUS_IDENTIFIED )267 return( 1 );268 298 269 299 xd = g_new0( struct xml_parsedata, 1 ); … … 318 348 return STORAGE_OK; 319 349 320 irc->status |= USTATUS_IDENTIFIED;321 322 350 return STORAGE_OK; 323 351 } 324 352 325 static storage_status_t xml_load( const char *my_nick, const char *password, irc_t *irc)326 { 327 return xml_load_real( my_nick, password, irc, XML_PASS_UNKNOWN );353 static storage_status_t xml_load( irc_t *irc, const char *password ) 354 { 355 return xml_load_real( irc, irc->nick, password, XML_PASS_UNKNOWN ); 328 356 } 329 357 … … 332 360 /* This is a little bit risky because we have to pass NULL for the 333 361 irc_t argument. This *should* be fine, if I didn't miss anything... */ 334 return xml_load_real( my_nick, password, NULL, XML_PASS_CHECK_ONLY );362 return xml_load_real( NULL, my_nick, password, XML_PASS_CHECK_ONLY ); 335 363 } 336 364 … … 367 395 md5_byte_t pass_md5[21]; 368 396 md5_state_t md5_state; 369 370 if( irc->password == NULL )371 {372 irc_usermsg( irc, "Please register yourself if you want to save your settings." );373 return STORAGE_OTHER_ERROR;374 }375 397 376 398 path2 = g_strdup( irc->nick ); … … 406 428 407 429 for( set = irc->set; set; set = set->next ) 408 if( set->value && set->def)430 if( set->value ) 409 431 if( !xml_printf( fd, 1, "<setting name=\"%s\">%s</setting>\n", set->key, set->value ) ) 410 432 goto write_error; … … 415 437 char *pass_b64; 416 438 int pass_len; 439 struct chat *c; 417 440 418 441 pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password, 12 ); … … 433 456 434 457 for( set = acc->set; set; set = set->next ) 435 if( set->value && set->def &&!( set->flags & ACC_SET_NOSAVE ) )458 if( set->value && !( set->flags & ACC_SET_NOSAVE ) ) 436 459 if( !xml_printf( fd, 2, "<setting name=\"%s\">%s</setting>\n", set->key, set->value ) ) 437 460 goto write_error; … … 447 470 goto write_error; 448 471 472 for( c = irc->chatrooms; c; c = c->next ) 473 { 474 if( c->acc != acc ) 475 continue; 476 477 if( !xml_printf( fd, 2, "<chat handle=\"%s\" channel=\"%s\" type=\"%s\">\n", 478 c->handle, c->channel, "room" ) ) 479 goto write_error; 480 481 for( set = c->set; set; set = set->next ) 482 if( set->value && !( set->flags & ACC_SET_NOSAVE ) ) 483 if( !xml_printf( fd, 3, "<setting name=\"%s\">%s</setting>\n", 484 set->key, set->value ) ) 485 goto write_error; 486 487 if( !xml_printf( fd, 2, "</chat>\n" ) ) 488 goto write_error; 489 } 490 449 491 if( !xml_printf( fd, 1, "</account>\n" ) ) 450 492 goto write_error; -
tests/Makefile
raac4017 r2288705 11 11 distclean: clean 12 12 13 main_objs = account.o bitlbee.o c onf.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.o13 main_objs = account.o bitlbee.o chat.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 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 check_jabber_util.o -
tests/check_set.c
raac4017 r2288705 96 96 END_TEST 97 97 98 START_TEST(test_setstr_implicit)99 void *data = "data";100 set_t *s = NULL, *t;101 set_setstr(&s, "name", "bloe");102 fail_unless(set_find(&s, "name") != NULL);103 END_TEST104 105 98 START_TEST(test_set_get_int_unknown) 106 99 set_t *s = NULL; … … 126 119 tcase_add_test (tc_core, test_setint); 127 120 tcase_add_test (tc_core, test_setstr); 128 tcase_add_test (tc_core, test_setstr_implicit);129 121 return s; 130 122 } -
user.c
raac4017 r2288705 141 141 } 142 142 143 user_t *user_findhandle( struct im_connection *ic, c har *handle )143 user_t *user_findhandle( struct im_connection *ic, const char *handle ) 144 144 { 145 145 user_t *u; -
user.h
raac4017 r2288705 56 56 int user_del( irc_t *irc, char *nick ); 57 57 G_MODULE_EXPORT user_t *user_find( irc_t *irc, char *nick ); 58 G_MODULE_EXPORT user_t *user_findhandle( struct im_connection *ic, c har *handle );58 G_MODULE_EXPORT user_t *user_findhandle( struct im_connection *ic, const char *handle ); 59 59 void user_rename( irc_t *irc, char *oldnick, char *newnick ); 60 60
Note: See TracChangeset
for help on using the changeset viewer.