Changes in / [36cf9fd:2288705]
- Files:
-
- 9 added
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
r36cf9fd r2288705 10 10 11 11 # Program variables 12 objects = account.o bitlbee.o chat.o crypting.o help.o ipc.o irc.o irc_commands.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) user.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.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 -
conf.c
r36cf9fd r2288705 63 63 conf->ping_timeout = 300; 64 64 conf->user = NULL; 65 conf->ft_max_size = SIZE_MAX; 66 conf->ft_max_kbps = G_MAXUINT; 67 conf->ft_listen = NULL; 65 68 proxytype = 0; 66 69 … … 306 309 conf->user = g_strdup( ini->value ); 307 310 } 311 else if( g_strcasecmp( ini->key, "ft_max_size" ) == 0 ) 312 { 313 size_t ft_max_size; 314 if( sscanf( ini->value, "%zu", &ft_max_size ) != 1 ) 315 { 316 fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value ); 317 return 0; 318 } 319 conf->ft_max_size = ft_max_size; 320 } 321 else if( g_strcasecmp( ini->key, "ft_max_kbps" ) == 0 ) 322 { 323 if( sscanf( ini->value, "%d", &i ) != 1 ) 324 { 325 fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value ); 326 return 0; 327 } 328 conf->ft_max_kbps = i; 329 } 330 else if( g_strcasecmp( ini->key, "ft_listen" ) == 0 ) 331 { 332 g_free( conf->ft_listen ); 333 conf->ft_listen = g_strdup( ini->value ); 334 } 308 335 else 309 336 { -
conf.h
r36cf9fd r2288705 50 50 int ping_timeout; 51 51 char *user; 52 size_t ft_max_size; 53 int ft_max_kbps; 54 char *ft_listen; 52 55 } conf_t; 53 56 -
doc/user-guide/commands.xml
r36cf9fd r2288705 960 960 961 961 </bitlbee-command> 962 963 <bitlbee-command name="transfers"> 964 <short-description>Monitor, cancel, or reject file transfers</short-description> 965 <syntax>transfers [<cancel> id | <reject>]</syntax> 966 967 <description> 968 <para> 969 Without parameters the currently pending file transfers and their status will be listed. Available actions are <emphasis>cancel</emphasis> and <emphasis>reject</emphasis>. See <emphasis>help transfers <action></emphasis> for more information. 970 </para> 971 972 <ircexample> 973 <ircline nick="ulim">transfers</ircline> 974 </ircexample> 975 </description> 976 977 <bitlbee-command name="cancel"> 978 <short-description>Cancels the file transfer with the given id</short-description> 979 <syntax>transfers <cancel> id</syntax> 980 981 <description> 982 <para>Cancels the file transfer with the given id</para> 983 </description> 984 985 <ircexample> 986 <ircline nick="ulim">transfers cancel 1</ircline> 987 <ircline nick="root">Canceling file transfer for test</ircline> 988 </ircexample> 989 </bitlbee-command> 990 991 <bitlbee-command name="reject"> 992 <short-description>Rejects all incoming transfers</short-description> 993 <syntax>transfers <reject></syntax> 994 995 <description> 996 <para>Rejects all incoming (not already transferring) file transfers. Since you probably have only one incoming transfer at a time, no id is neccessary. Or is it?</para> 997 </description> 998 999 <ircexample> 1000 <ircline nick="ulim">transfers reject</ircline> 1001 </ircexample> 1002 </bitlbee-command> 1003 </bitlbee-command> 1004 962 1005 </chapter> -
irc.c
r36cf9fd r2288705 29 29 #include "crypting.h" 30 30 #include "ipc.h" 31 #include "dcc.h" 31 32 32 33 static gboolean irc_userping( gpointer _irc, int fd, b_input_condition cond ); … … 1083 1084 return( 1 ); 1084 1085 } 1086 else if( g_strncasecmp( s + 1, "DCC", 3 ) == 0 ) 1087 { 1088 if( u && u->ic && u->ic->acc->prpl->transfer_request ) 1089 { 1090 file_transfer_t *ft = dcc_request( u->ic, s + 5 ); 1091 if ( ft ) 1092 u->ic->acc->prpl->transfer_request( u->ic, ft, u->handle ); 1093 } 1094 return( 1 ); 1095 } 1085 1096 else 1086 1097 { 1087 irc_usermsg( irc, " Non-ACTION CTCP's aren't supported" );1098 irc_usermsg( irc, "Supported CTCPs are ACTION, VERSION, PING, TYPING, DCC" ); 1088 1099 return( 0 ); 1089 1100 } -
irc.h
r36cf9fd r2288705 83 83 struct query *queries; 84 84 struct account *accounts; 85 GSList *file_transfers; 85 86 struct chat *chatrooms; 86 87 -
lib/Makefile
r36cf9fd r2288705 10 10 11 11 # [SH] Program variables 12 objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o 12 objects = arc.o base64.o $(EVENT_HANDLER) http_client.o ini.o md5.o misc.o proxy.o sha1.o $(SSL_CLIENT) url.o xmltree.o ftutil.o 13 13 14 14 CFLAGS += -Wall -
protocols/jabber/Makefile
r36cf9fd r2288705 10 10 11 11 # [SH] Program variables 12 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o 12 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o si.o s5bytestream.o 13 13 14 14 CFLAGS += -Wall -
protocols/jabber/iq.c
r36cf9fd r2288705 91 91 pack = 0; 92 92 } 93 else if( strcmp( s, XMLNS_DISCO VER) == 0 )94 { 95 const char *features[] = { XMLNS_DISCO VER,93 else if( strcmp( s, XMLNS_DISCO_INFO ) == 0 ) 94 { 95 const char *features[] = { XMLNS_DISCO_INFO, 96 96 XMLNS_VERSION, 97 97 XMLNS_TIME, … … 99 99 XMLNS_MUC, 100 100 XMLNS_PING, 101 XMLNS_SI, 102 XMLNS_BYTESTREAMS, 103 XMLNS_FILETRANSFER, 101 104 NULL }; 102 105 const char **f; … … 118 121 { 119 122 xt_free_node( reply ); 120 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel" );123 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel", NULL ); 121 124 pack = 0; 122 125 } … … 124 127 else if( strcmp( type, "set" ) == 0 ) 125 128 { 126 if( !( c = xt_find_node( node->children, "query" ) ) || 129 if( ( c = xt_find_node( node->children, "si" ) ) && 130 ( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_SI ) == 0 ) ) 131 { 132 return jabber_si_handle_request( ic, node, c ); 133 } else if( !( c = xt_find_node( node->children, "query" ) ) || 127 134 !( s = xt_find_attr( c, "xmlns" ) ) ) 128 135 { 129 136 imcb_log( ic, "Warning: Received incomplete IQ-%s packet", type ); 130 137 return XT_HANDLED; 131 } 132 138 } else if( strcmp( s, XMLNS_ROSTER ) == 0 ) 139 { 133 140 /* This is a roster push. XMPP servers send this when someone 134 141 was added to (or removed from) the buddy list. AFAIK they're 135 142 sent even if we added this buddy in our own session. */ 136 if( strcmp( s, XMLNS_ROSTER ) == 0 )137 {138 143 int bare_len = strlen( ic->acc->user ); 139 144 … … 152 157 153 158 xt_free_node( reply ); 154 reply = jabber_make_error_packet( node, "not-allowed", "cancel" );159 reply = jabber_make_error_packet( node, "not-allowed", "cancel", NULL ); 155 160 pack = 0; 156 161 } 157 } 158 else 162 } else if( strcmp( s, XMLNS_BYTESTREAMS ) == 0 ) 163 { 164 /* Bytestream Request (stage 2 of file transfer) */ 165 return jabber_bs_recv_request( ic, node, c ); 166 } else 159 167 { 160 168 xt_free_node( reply ); 161 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel" );169 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel", NULL ); 162 170 pack = 0; 163 171 } … … 594 602 return st; 595 603 } 604 605 xt_status jabber_iq_parse_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ); 606 607 xt_status jabber_iq_query_features( struct im_connection *ic, char *bare_jid ) 608 { 609 struct xt_node *node, *query; 610 struct jabber_buddy *bud; 611 612 if( ( bud = jabber_buddy_by_jid( ic, bare_jid , 0 ) ) == NULL ) 613 { 614 /* Who cares about the unknown... */ 615 imcb_log( ic, "Couldn't find buddy: %s", bare_jid); 616 return 0; 617 } 618 619 if( bud->features ) /* been here already */ 620 return XT_HANDLED; 621 622 node = xt_new_node( "query", NULL, NULL ); 623 xt_add_attr( node, "xmlns", XMLNS_DISCO_INFO ); 624 625 if( !( query = jabber_make_packet( "iq", "get", bare_jid, node ) ) ) 626 { 627 imcb_log( ic, "WARNING: Couldn't generate feature query" ); 628 xt_free_node( node ); 629 return 0; 630 } 631 632 jabber_cache_add( ic, query, jabber_iq_parse_features ); 633 634 return jabber_write_packet( ic, query ); 635 } 636 637 xt_status jabber_iq_parse_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) 638 { 639 struct xt_node *c; 640 struct jabber_buddy *bud; 641 char *feature; 642 643 if( !( c = xt_find_node( node->children, "query" ) ) || 644 !( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_DISCO_INFO ) == 0 ) ) 645 { 646 imcb_log( ic, "WARNING: Received incomplete IQ-result packet for discover" ); 647 return XT_HANDLED; 648 } 649 if( ( bud = jabber_buddy_by_jid( ic, xt_find_attr( node, "from") , 0 ) ) == NULL ) 650 { 651 /* Who cares about the unknown... */ 652 imcb_log( ic, "Couldn't find buddy: %s", xt_find_attr( node, "from")); 653 return 0; 654 } 655 656 c = c->children; 657 while( ( c = xt_find_node( c, "feature" ) ) ) { 658 feature = xt_find_attr( c, "var" ); 659 bud->features = g_slist_append(bud->features, g_strdup(feature) ); 660 c = c->next; 661 } 662 663 return XT_HANDLED; 664 } 665 666 xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ); 667 668 xt_status jabber_iq_query_server( struct im_connection *ic, char *jid, char *xmlns ) 669 { 670 struct xt_node *node, *query; 671 struct jabber_data *jd = ic->proto_data; 672 673 node = xt_new_node( "query", NULL, NULL ); 674 xt_add_attr( node, "xmlns", xmlns ); 675 676 if( !( query = jabber_make_packet( "iq", "get", jid, node ) ) ) 677 { 678 imcb_log( ic, "WARNING: Couldn't generate server query" ); 679 xt_free_node( node ); 680 } 681 682 jd->have_streamhosts--; 683 jabber_cache_add( ic, query, jabber_iq_parse_server_features ); 684 685 return jabber_write_packet( ic, query ); 686 } 687 688 /* 689 * Query the server for "items", query each "item" for identities, query each "item" that's a proxy for it's bytestream info 690 */ 691 xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) 692 { 693 struct xt_node *c; 694 struct jabber_data *jd = ic->proto_data; 695 696 if( !( c = xt_find_node( node->children, "query" ) ) || 697 !xt_find_attr( node, "from" ) ) 698 { 699 imcb_log( ic, "WARNING: Received incomplete IQ-result packet for discover" ); 700 return XT_HANDLED; 701 } 702 703 jd->have_streamhosts++; 704 705 if( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_DISCO_ITEMS ) == 0 ) 706 { 707 char *item, *itemjid; 708 709 /* answer from server */ 710 711 c = c->children; 712 while( ( c = xt_find_node( c, "item" ) ) ) 713 { 714 item = xt_find_attr( c, "name" ); 715 itemjid = xt_find_attr( c, "jid" ); 716 717 jabber_iq_query_server( ic, itemjid, XMLNS_DISCO_INFO ); 718 719 c = c->next; 720 } 721 } else if( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_DISCO_INFO ) == 0 ) 722 { 723 char *category, *type; 724 725 /* answer from potential proxy */ 726 727 c = c->children; 728 while( ( c = xt_find_node( c, "identity" ) ) ) 729 { 730 category = xt_find_attr( c, "category" ); 731 type = xt_find_attr( c, "type" ); 732 733 if( type && ( strcmp( type, "bytestreams" ) == 0 ) && 734 category && ( strcmp( category, "proxy" ) == 0 ) ) 735 jabber_iq_query_server( ic, xt_find_attr( node, "from" ), XMLNS_BYTESTREAMS ); 736 737 c = c->next; 738 } 739 } else if( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_BYTESTREAMS ) == 0 ) 740 { 741 char *host, *jid; 742 int port; 743 744 /* answer from proxy */ 745 746 if( ( c = xt_find_node( c->children, "streamhost" ) ) && 747 ( host = xt_find_attr( c, "host" ) ) && 748 ( port = atoi( xt_find_attr( c, "port" ) ) ) && 749 ( jid = xt_find_attr( c, "jid" ) ) ) 750 { 751 jabber_streamhost_t *sh = g_new0( jabber_streamhost_t, 1 ); 752 sh->jid = g_strdup( jid ); 753 sh->host = g_strdup( host ); 754 sprintf( sh->port, "%u", port ); 755 756 imcb_log( ic, "Proxy found: jid %s host %s port %u", jid, host, port ); 757 jd->streamhosts = g_slist_append( jd->streamhosts, sh ); 758 } 759 } 760 761 if( jd->have_streamhosts == 0 ) 762 jd->have_streamhosts++; 763 return XT_HANDLED; 764 } -
protocols/jabber/jabber.c
r36cf9fd r2288705 80 80 s = set_add( &acc->set, "xmlconsole", "false", set_eval_bool, acc ); 81 81 s->flags |= ACC_SET_OFFLINE_ONLY; 82 83 s = set_add( &acc->set, "proxy", "<local>;<auto>", NULL, acc ); 82 84 } 83 85 … … 260 262 struct jabber_data *jd = ic->proto_data; 261 263 264 while( jd->filetransfers ) 265 imcb_file_canceled( ( ( struct jabber_transfer *) jd->filetransfers->data )->ft, "Logging out" ); 266 267 while( jd->streamhosts ) 268 { 269 jabber_streamhost_t *sh = jd->streamhosts->data; 270 jd->streamhosts = g_slist_remove( jd->streamhosts, sh ); 271 g_free( sh->jid ); 272 g_free( sh->host ); 273 g_free( sh ); 274 } 275 262 276 if( jd->fd >= 0 ) 263 277 jabber_end_stream( ic ); … … 546 560 ret->send_typing = jabber_send_typing; 547 561 ret->handle_cmp = g_strcasecmp; 562 ret->transfer_request = jabber_si_transfer_request; 548 563 549 564 register_protocol( ret ); -
protocols/jabber/jabber.h
r36cf9fd r2288705 60 60 } jabber_buddy_flags_t; 61 61 62 /* Stores a streamhost's(a.k.a. proxy) data */ 63 typedef struct 64 { 65 char *jid; 66 char *host; 67 char port[6]; 68 } jabber_streamhost_t; 69 62 70 typedef enum 63 71 { … … 90 98 GHashTable *node_cache; 91 99 GHashTable *buddies; 100 101 GSList *filetransfers; 102 GSList *streamhosts; 103 int have_streamhosts; 92 104 }; 93 105 … … 119 131 struct jabber_away_state *away_state; 120 132 char *away_message; 133 GSList *features; 121 134 122 135 time_t last_act; … … 132 145 char *my_full_jid; /* Separate copy because of case sensitivity. */ 133 146 struct jabber_buddy *me; 147 }; 148 149 struct jabber_transfer 150 { 151 /* bitlbee's handle for this transfer */ 152 file_transfer_t *ft; 153 154 /* the stream's private handle */ 155 gpointer streamhandle; 156 157 /* timeout for discover queries */ 158 gint disco_timeout; 159 gint disco_timeout_fired; 160 161 struct im_connection *ic; 162 163 struct jabber_buddy *bud; 164 165 int watch_in; 166 int watch_out; 167 168 char *ini_jid; 169 char *tgt_jid; 170 char *iq_id; 171 char *sid; 172 int accepted; 173 174 size_t bytesread, byteswritten; 175 int fd; 176 struct sockaddr_storage saddr; 134 177 }; 135 178 … … 159 202 160 203 /* Some supported extensions/legacy stuff */ 161 #define XMLNS_AUTH "jabber:iq:auth" /* XEP-0078 */ 162 #define XMLNS_VERSION "jabber:iq:version" /* XEP-0092 */ 163 #define XMLNS_TIME "jabber:iq:time" /* XEP-0090 */ 164 #define XMLNS_PING "urn:xmpp:ping" /* XEP-0199 */ 165 #define XMLNS_VCARD "vcard-temp" /* XEP-0054 */ 166 #define XMLNS_DELAY "jabber:x:delay" /* XEP-0091 */ 167 #define XMLNS_CHATSTATES "http://jabber.org/protocol/chatstates" /* 0085 */ 168 #define XMLNS_DISCOVER "http://jabber.org/protocol/disco#info" /* 0030 */ 169 #define XMLNS_MUC "http://jabber.org/protocol/muc" /* XEP-0045 */ 170 #define XMLNS_MUC_USER "http://jabber.org/protocol/muc#user"/* XEP-0045 */ 171 #define XMLNS_CAPS "http://jabber.org/protocol/caps" /* XEP-0115 */ 204 #define XMLNS_AUTH "jabber:iq:auth" /* XEP-0078 */ 205 #define XMLNS_VERSION "jabber:iq:version" /* XEP-0092 */ 206 #define XMLNS_TIME "jabber:iq:time" /* XEP-0090 */ 207 #define XMLNS_PING "urn:xmpp:ping" /* XEP-0199 */ 208 #define XMLNS_VCARD "vcard-temp" /* XEP-0054 */ 209 #define XMLNS_DELAY "jabber:x:delay" /* XEP-0091 */ 210 #define XMLNS_XDATA "jabber:x:data" /* XEP-0004 */ 211 #define XMLNS_CHATSTATES "http://jabber.org/protocol/chatstates" /* XEP-0085 */ 212 #define XMLNS_DISCO_INFO "http://jabber.org/protocol/disco#info" /* XEP-0030 */ 213 #define XMLNS_DISCO_ITEMS "http://jabber.org/protocol/disco#items" /* XEP-0030 */ 214 #define XMLNS_MUC "http://jabber.org/protocol/muc" /* XEP-0045 */ 215 #define XMLNS_MUC_USER "http://jabber.org/protocol/muc#user" /* XEP-0045 */ 216 #define XMLNS_CAPS "http://jabber.org/protocol/caps" /* XEP-0115 */ 217 #define XMLNS_FEATURE "http://jabber.org/protocol/feature-neg" /* XEP-0020 */ 218 #define XMLNS_SI "http://jabber.org/protocol/si" /* XEP-0095 */ 219 #define XMLNS_FILETRANSFER "http://jabber.org/protocol/si/profile/file-transfer" /* XEP-0096 */ 220 #define XMLNS_BYTESTREAMS "http://jabber.org/protocol/bytestreams" /* XEP-0065 */ 221 #define XMLNS_IBB "http://jabber.org/protocol/ibb" /* XEP-0047 */ 172 222 173 223 /* iq.c */ … … 179 229 int jabber_add_to_roster( struct im_connection *ic, char *handle, char *name ); 180 230 int jabber_remove_from_roster( struct im_connection *ic, char *handle ); 231 xt_status jabber_iq_query_features( struct im_connection *ic, char *bare_jid ); 232 xt_status jabber_iq_query_server( struct im_connection *ic, char *jid, char *xmlns ); 233 234 /* si.c */ 235 int jabber_si_handle_request( struct im_connection *ic, struct xt_node *node, struct xt_node *sinode ); 236 void jabber_si_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who ); 237 void jabber_si_free_transfer( file_transfer_t *ft); 238 239 /* s5bytestream.c */ 240 int jabber_bs_recv_request( struct im_connection *ic, struct xt_node *node, struct xt_node *qnode); 241 gboolean jabber_bs_send_start( struct jabber_transfer *tf ); 242 gboolean jabber_bs_send_write( file_transfer_t *ft, char *buffer, unsigned int len ); 181 243 182 244 /* message.c */ … … 192 254 char *set_eval_tls( set_t *set, char *value ); 193 255 struct xt_node *jabber_make_packet( char *name, char *type, char *to, struct xt_node *children ); 194 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type );256 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type, char *err_code ); 195 257 void jabber_cache_add( struct im_connection *ic, struct xt_node *node, jabber_cache_event func ); 196 258 struct xt_node *jabber_cache_get( struct im_connection *ic, char *id ); -
protocols/jabber/jabber_util.c
r36cf9fd r2288705 99 99 } 100 100 101 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type )101 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type, char *err_code ) 102 102 { 103 103 struct xt_node *node, *c; … … 111 111 c = xt_new_node( "error", NULL, c ); 112 112 xt_add_attr( c, "type", err_type ); 113 114 /* Add the error code, if present */ 115 if (err_code) 116 xt_add_attr( c, "code", err_code ); 113 117 114 118 /* To make the actual error packet, we copy the original packet and -
protocols/msn/Makefile
r36cf9fd r2288705 10 10 11 11 # [SH] Program variables 12 objects = msn.o msn_util.o ns.o passport.o sb.o tables.o 12 objects = msn.o msn_util.o ns.o passport.o sb.o tables.o invitation.o 13 13 14 14 CFLAGS += -Wall -
protocols/msn/msn.c
r36cf9fd r2288705 77 77 if( md ) 78 78 { 79 while( md->filetransfers ) { 80 imcb_file_canceled( md->filetransfers->data, "Closing msn connection" ); 81 } 82 79 83 if( md->fd >= 0 ) 80 84 closesocket( md->fd ); … … 338 342 ret->send_typing = msn_send_typing; 339 343 ret->handle_cmp = g_strcasecmp; 344 ret->transfer_request = msn_ftp_transfer_request; 340 345 341 346 register_protocol(ret); -
protocols/msn/msn.h
r36cf9fd r2288705 69 69 int sb_failures; 70 70 time_t first_sb_failure; 71 GSList *filetransfers; 71 72 72 73 const struct msn_away_state *away_state; … … 181 182 int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m ); 182 183 184 /* invitation.c */ 185 void msn_ftp_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who ); 186 183 187 #endif //_MSN_H -
protocols/msn/sb.c
r36cf9fd r2288705 29 29 #include "passport.h" 30 30 #include "md5.h" 31 #include "invitation.h" 31 32 32 33 static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition cond ); … … 168 169 169 170 /* Build the message. Convert LF to CR-LF for normal messages. */ 170 if( strcmp( text, TYPING_NOTIFICATION_MESSAGE ) != 0 ) 171 if( strcmp( text, TYPING_NOTIFICATION_MESSAGE ) == 0 ) 172 { 173 i = strlen( MSN_TYPING_HEADERS ) + strlen( sb->ic->acc->user ); 174 buf = g_new0( char, i ); 175 i = g_snprintf( buf, i, MSN_TYPING_HEADERS, sb->ic->acc->user ); 176 } else if( strncmp( text, MSN_INVITE_HEADERS, sizeof( MSN_INVITE_HEADERS ) - 1 ) == 0 ) 177 { 178 buf = g_strdup( text ); 179 i = strlen( buf ); 180 } else 171 181 { 172 182 buf = g_new0( char, sizeof( MSN_MESSAGE_HEADERS ) + strlen( text ) * 2 + 1 ); … … 181 191 buf[i++] = text[j]; 182 192 } 183 }184 else185 {186 i = strlen( MSN_TYPING_HEADERS ) + strlen( sb->ic->acc->user );187 buf = g_new0( char, i );188 i = g_snprintf( buf, i, MSN_TYPING_HEADERS, sb->ic->acc->user );189 193 } 190 194 … … 687 691 else if( g_strncasecmp( ct, "text/x-msmsgsinvite", 19 ) == 0 ) 688 692 { 689 char *itype = msn_findheader( body, "Application-GUID:", blen ); 690 char buf[1024]; 693 char *command = msn_findheader( body, "Invitation-Command:", blen ); 694 char *cookie = msn_findheader( body, "Invitation-Cookie:", blen ); 695 unsigned int icookie; 691 696 692 697 g_free( ct ); 693 698 694 *buf = 0; 695 696 if( !itype ) 697 return( 1 ); 698 699 /* File transfer. */ 700 if( strcmp( itype, "{5D3E02AB-6190-11d3-BBBB-00C04F795683}" ) == 0 ) 701 { 702 char *name = msn_findheader( body, "Application-File:", blen ); 703 char *size = msn_findheader( body, "Application-FileSize:", blen ); 704 705 if( name && size ) 706 { 707 g_snprintf( buf, sizeof( buf ), "<< \x02""BitlBee\x02"" - Filetransfer: `%s', %s bytes >>\n" 708 "Filetransfers are not supported by BitlBee for now...", name, size ); 709 } 710 else 711 { 712 strcpy( buf, "<< \x02""BitlBee\x02"" - Corrupted MSN filetransfer invitation message >>" ); 713 } 714 715 if( name ) g_free( name ); 716 if( size ) g_free( size ); 717 } 718 else 719 { 720 char *iname = msn_findheader( body, "Application-Name:", blen ); 721 722 g_snprintf( buf, sizeof( buf ), "<< \x02""BitlBee\x02"" - Unknown MSN invitation - %s (%s) >>", 723 itype, iname ? iname : "no name" ); 724 725 if( iname ) g_free( iname ); 726 } 727 728 g_free( itype ); 729 730 if( !*buf ) 731 return( 1 ); 732 733 if( sb->who ) 734 { 735 imcb_buddy_msg( ic, cmd[1], buf, 0, 0 ); 736 } 737 else if( sb->chat ) 738 { 739 imcb_chat_msg( sb->chat, cmd[1], buf, 0, 0 ); 740 } 741 else 742 { 743 /* PANIC! */ 744 } 699 /* Every invite should have both a Command and Cookie header */ 700 if( !command || !cookie ) { 701 g_free( command ); 702 g_free( cookie ); 703 imcb_log( ic, "Warning: No command or cookie from %s", sb->who ); 704 return 1; 705 } 706 707 icookie = strtoul( cookie, NULL, 10 ); 708 g_free( cookie ); 709 710 if( g_strncasecmp( command, "INVITE", 6 ) == 0 ) { 711 msn_invitation_invite( sb, cmd[1], icookie, body, blen ); 712 } else if( g_strncasecmp( command, "ACCEPT", 6 ) == 0 ) { 713 msn_invitation_accept( sb, cmd[1], icookie, body, blen ); 714 } else if( g_strncasecmp( command, "CANCEL", 6 ) == 0 ) { 715 msn_invitation_cancel( sb, cmd[1], icookie, body, blen ); 716 } else { 717 imcb_log( ic, "Warning: Received invalid invitation with " 718 "command %s from %s", command, sb->who ); 719 } 720 721 g_free( command ); 722 } 723 else if( g_strncasecmp( ct, "application/x-msnmsgrp2p", 24 ) == 0 ) 724 { 725 imcb_error( sb->ic, "Cannot receive file from %s: BitlBee does not " 726 "support msnmsgrp2p yet.", sb->who ); 727 g_free( ct ); 745 728 } 746 729 else if( g_strncasecmp( ct, "text/x-msmsgscontrol", 20 ) == 0 ) -
protocols/nogaim.h
r36cf9fd r2288705 45 45 #include "proxy.h" 46 46 #include "query.h" 47 #include "md5.h" 48 #include "ft.h" 47 49 48 50 #define BUDDY_ALIAS_MAXLEN 388 /* because MSN names can be 387 characters */ … … 229 231 void (* auth_allow) (struct im_connection *, const char *who); 230 232 void (* auth_deny) (struct im_connection *, const char *who); 233 234 /* Incoming transfer request */ 235 void (* transfer_request) (struct im_connection *, file_transfer_t *ft, char *handle ); 231 236 }; 232 237 -
root_commands.c
r36cf9fd r2288705 1188 1188 } 1189 1189 #endif 1190 } 1191 1192 static void cmd_transfers( irc_t *irc, char **cmd ) 1193 { 1194 GSList *files = irc->file_transfers; 1195 enum { LIST, REJECT, CANCEL }; 1196 int subcmd = LIST; 1197 int fid; 1198 1199 if( !files ) 1200 { 1201 irc_usermsg( irc, "No pending transfers" ); 1202 return; 1203 } 1204 1205 if( cmd[1] && 1206 ( strcmp( cmd[1], "reject" ) == 0 ) ) 1207 { 1208 subcmd = REJECT; 1209 } 1210 else if( cmd[1] && 1211 ( strcmp( cmd[1], "cancel" ) == 0 ) && 1212 cmd[2] && 1213 ( fid = atoi( cmd[2] ) ) ) 1214 { 1215 subcmd = CANCEL; 1216 } 1217 1218 for( ; files; files = g_slist_next( files ) ) 1219 { 1220 file_transfer_t *file = files->data; 1221 1222 switch( subcmd ) { 1223 case LIST: 1224 if ( file->status == FT_STATUS_LISTENING ) 1225 irc_usermsg( irc, 1226 "Pending file(id %d): %s (Listening...)", file->local_id, file->file_name); 1227 else 1228 { 1229 int kb_per_s = 0; 1230 time_t diff = time( NULL ) - file->started ? : 1; 1231 if ( ( file->started > 0 ) && ( file->bytes_transferred > 0 ) ) 1232 kb_per_s = file->bytes_transferred / 1024 / diff; 1233 1234 irc_usermsg( irc, 1235 "Pending file(id %d): %s (%10zd/%zd kb, %d kb/s)", file->local_id, file->file_name, 1236 file->bytes_transferred/1024, file->file_size/1024, kb_per_s); 1237 } 1238 break; 1239 case REJECT: 1240 if( file->status == FT_STATUS_LISTENING ) 1241 { 1242 irc_usermsg( irc, "Rejecting file transfer for %s", file->file_name ); 1243 imcb_file_canceled( file, "Denied by user" ); 1244 } 1245 break; 1246 case CANCEL: 1247 if( file->local_id == fid ) 1248 { 1249 irc_usermsg( irc, "Canceling file transfer for %s", file->file_name ); 1250 imcb_file_canceled( file, "Canceled by user" ); 1251 } 1252 break; 1253 } 1254 } 1190 1255 } 1191 1256 … … 1211 1276 { "join_chat", 2, cmd_join_chat, 0 }, 1212 1277 { "chat", 1, cmd_chat, 0 }, 1278 { "transfers", 0, cmd_transfers, 0 }, 1213 1279 { NULL } 1214 1280 };
Note: See TracChangeset
for help on using the changeset viewer.