Changes in / [f9928cb:e8c8d00]
- Files:
-
- 9 added
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
rf9928cb re8c8d00 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
rf9928cb re8c8d00 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 conf->protocols = NULL; 66 69 proxytype = 0; … … 308 311 conf->user = g_strdup( ini->value ); 309 312 } 313 else if( g_strcasecmp( ini->key, "ft_max_size" ) == 0 ) 314 { 315 size_t ft_max_size; 316 if( sscanf( ini->value, "%zu", &ft_max_size ) != 1 ) 317 { 318 fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value ); 319 return 0; 320 } 321 conf->ft_max_size = ft_max_size; 322 } 323 else if( g_strcasecmp( ini->key, "ft_max_kbps" ) == 0 ) 324 { 325 if( sscanf( ini->value, "%d", &i ) != 1 ) 326 { 327 fprintf( stderr, "Invalid %s value: %s\n", ini->key, ini->value ); 328 return 0; 329 } 330 conf->ft_max_kbps = i; 331 } 332 else if( g_strcasecmp( ini->key, "ft_listen" ) == 0 ) 333 { 334 g_free( conf->ft_listen ); 335 conf->ft_listen = g_strdup( ini->value ); 336 } 310 337 else if( g_strcasecmp( ini->key, "protocols" ) == 0 ) 311 338 { -
conf.h
rf9928cb re8c8d00 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 char **protocols; 53 56 } conf_t; -
doc/user-guide/commands.xml
rf9928cb re8c8d00 1007 1007 1008 1008 </bitlbee-command> 1009 1010 <bitlbee-command name="transfers"> 1011 <short-description>Monitor, cancel, or reject file transfers</short-description> 1012 <syntax>transfers [<cancel> id | <reject>]</syntax> 1013 1014 <description> 1015 <para> 1016 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. 1017 </para> 1018 1019 <ircexample> 1020 <ircline nick="ulim">transfers</ircline> 1021 </ircexample> 1022 </description> 1023 1024 <bitlbee-command name="cancel"> 1025 <short-description>Cancels the file transfer with the given id</short-description> 1026 <syntax>transfers <cancel> id</syntax> 1027 1028 <description> 1029 <para>Cancels the file transfer with the given id</para> 1030 </description> 1031 1032 <ircexample> 1033 <ircline nick="ulim">transfers cancel 1</ircline> 1034 <ircline nick="root">Canceling file transfer for test</ircline> 1035 </ircexample> 1036 </bitlbee-command> 1037 1038 <bitlbee-command name="reject"> 1039 <short-description>Rejects all incoming transfers</short-description> 1040 <syntax>transfers <reject></syntax> 1041 1042 <description> 1043 <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> 1044 </description> 1045 1046 <ircexample> 1047 <ircline nick="ulim">transfers reject</ircline> 1048 </ircexample> 1049 </bitlbee-command> 1050 </bitlbee-command> 1051 1009 1052 </chapter> -
irc.c
rf9928cb re8c8d00 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 ); … … 1106 1107 return( 1 ); 1107 1108 } 1109 else if( g_strncasecmp( s + 1, "DCC", 3 ) == 0 ) 1110 { 1111 if( u && u->ic && u->ic->acc->prpl->transfer_request ) 1112 { 1113 file_transfer_t *ft = dcc_request( u->ic, s + 5 ); 1114 if ( ft ) 1115 u->ic->acc->prpl->transfer_request( u->ic, ft, u->handle ); 1116 } 1117 return( 1 ); 1118 } 1108 1119 else 1109 1120 { 1110 irc_usermsg( irc, " Non-ACTION CTCP's aren't supported" );1121 irc_usermsg( irc, "Supported CTCPs are ACTION, VERSION, PING, TYPING, DCC" ); 1111 1122 return( 0 ); 1112 1123 } -
irc.h
rf9928cb re8c8d00 83 83 struct query *queries; 84 84 struct account *accounts; 85 GSList *file_transfers; 85 86 struct chat *chatrooms; 86 87 -
lib/Makefile
rf9928cb re8c8d00 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
rf9928cb re8c8d00 10 10 11 11 # [SH] Program variables 12 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o s asl.o12 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o s5bytestream.o sasl.o si.o 13 13 14 14 CFLAGS += -Wall -
protocols/jabber/iq.c
rf9928cb re8c8d00 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" ) ) || 127 !( s = xt_find_attr( c, "xmlns" ) ) ) 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 } 134 else if( !( c = xt_find_node( node->children, "query" ) ) || 135 !( s = xt_find_attr( c, "xmlns" ) ) ) 128 136 { 129 137 imcb_log( ic, "Warning: Received incomplete IQ-%s packet", type ); 130 138 return XT_HANDLED; 131 139 } 132 140 else if( strcmp( s, XMLNS_ROSTER ) == 0 ) 141 { 133 142 /* This is a roster push. XMPP servers send this when someone 134 143 was added to (or removed from) the buddy list. AFAIK they're 135 144 sent even if we added this buddy in our own session. */ 136 if( strcmp( s, XMLNS_ROSTER ) == 0 )137 {138 145 int bare_len = strlen( ic->acc->user ); 139 146 … … 152 159 153 160 xt_free_node( reply ); 154 reply = jabber_make_error_packet( node, "not-allowed", "cancel" );161 reply = jabber_make_error_packet( node, "not-allowed", "cancel", NULL ); 155 162 pack = 0; 156 163 } 157 164 } 165 else if( strcmp( s, XMLNS_BYTESTREAMS ) == 0 ) 166 { 167 /* Bytestream Request (stage 2 of file transfer) */ 168 return jabber_bs_recv_request( ic, node, c ); 169 } 158 170 else 159 171 { 160 172 xt_free_node( reply ); 161 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel" );173 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel", NULL ); 162 174 pack = 0; 163 175 } … … 609 621 return st; 610 622 } 623 624 xt_status jabber_iq_parse_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ); 625 626 xt_status jabber_iq_query_features( struct im_connection *ic, char *bare_jid ) 627 { 628 struct xt_node *node, *query; 629 struct jabber_buddy *bud; 630 631 if( ( bud = jabber_buddy_by_jid( ic, bare_jid , 0 ) ) == NULL ) 632 { 633 /* Who cares about the unknown... */ 634 imcb_log( ic, "Couldn't find buddy: %s", bare_jid); 635 return 0; 636 } 637 638 if( bud->features ) /* been here already */ 639 return XT_HANDLED; 640 641 node = xt_new_node( "query", NULL, NULL ); 642 xt_add_attr( node, "xmlns", XMLNS_DISCO_INFO ); 643 644 if( !( query = jabber_make_packet( "iq", "get", bare_jid, node ) ) ) 645 { 646 imcb_log( ic, "WARNING: Couldn't generate feature query" ); 647 xt_free_node( node ); 648 return 0; 649 } 650 651 jabber_cache_add( ic, query, jabber_iq_parse_features ); 652 653 return jabber_write_packet( ic, query ); 654 } 655 656 xt_status jabber_iq_parse_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) 657 { 658 struct xt_node *c; 659 struct jabber_buddy *bud; 660 char *feature; 661 662 if( !( c = xt_find_node( node->children, "query" ) ) || 663 !( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_DISCO_INFO ) == 0 ) ) 664 { 665 imcb_log( ic, "WARNING: Received incomplete IQ-result packet for discover" ); 666 return XT_HANDLED; 667 } 668 if( ( bud = jabber_buddy_by_jid( ic, xt_find_attr( node, "from") , 0 ) ) == NULL ) 669 { 670 /* Who cares about the unknown... */ 671 imcb_log( ic, "Couldn't find buddy: %s", xt_find_attr( node, "from")); 672 return 0; 673 } 674 675 c = c->children; 676 while( ( c = xt_find_node( c, "feature" ) ) ) 677 { 678 feature = xt_find_attr( c, "var" ); 679 bud->features = g_slist_append( bud->features, g_strdup( feature ) ); 680 c = c->next; 681 } 682 683 return XT_HANDLED; 684 } 685 686 xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ); 687 688 xt_status jabber_iq_query_server( struct im_connection *ic, char *jid, char *xmlns ) 689 { 690 struct xt_node *node, *query; 691 struct jabber_data *jd = ic->proto_data; 692 693 node = xt_new_node( "query", NULL, NULL ); 694 xt_add_attr( node, "xmlns", xmlns ); 695 696 if( !( query = jabber_make_packet( "iq", "get", jid, node ) ) ) 697 { 698 imcb_log( ic, "WARNING: Couldn't generate server query" ); 699 xt_free_node( node ); 700 } 701 702 jd->have_streamhosts--; 703 jabber_cache_add( ic, query, jabber_iq_parse_server_features ); 704 705 return jabber_write_packet( ic, query ); 706 } 707 708 /* 709 * Query the server for "items", query each "item" for identities, query each "item" that's a proxy for it's bytestream info 710 */ 711 xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) 712 { 713 struct xt_node *c; 714 struct jabber_data *jd = ic->proto_data; 715 716 if( !( c = xt_find_node( node->children, "query" ) ) || 717 !xt_find_attr( node, "from" ) ) 718 { 719 imcb_log( ic, "WARNING: Received incomplete IQ-result packet for discover" ); 720 return XT_HANDLED; 721 } 722 723 jd->have_streamhosts++; 724 725 if( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_DISCO_ITEMS ) == 0 ) 726 { 727 char *item, *itemjid; 728 729 /* answer from server */ 730 731 c = c->children; 732 while( ( c = xt_find_node( c, "item" ) ) ) 733 { 734 item = xt_find_attr( c, "name" ); 735 itemjid = xt_find_attr( c, "jid" ); 736 737 jabber_iq_query_server( ic, itemjid, XMLNS_DISCO_INFO ); 738 739 c = c->next; 740 } 741 } 742 else if( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_DISCO_INFO ) == 0 ) 743 { 744 char *category, *type; 745 746 /* answer from potential proxy */ 747 748 c = c->children; 749 while( ( c = xt_find_node( c, "identity" ) ) ) 750 { 751 category = xt_find_attr( c, "category" ); 752 type = xt_find_attr( c, "type" ); 753 754 if( type && ( strcmp( type, "bytestreams" ) == 0 ) && 755 category && ( strcmp( category, "proxy" ) == 0 ) ) 756 jabber_iq_query_server( ic, xt_find_attr( node, "from" ), XMLNS_BYTESTREAMS ); 757 758 c = c->next; 759 } 760 } 761 else if( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_BYTESTREAMS ) == 0 ) 762 { 763 char *host, *jid; 764 int port; 765 766 /* answer from proxy */ 767 768 if( ( c = xt_find_node( c->children, "streamhost" ) ) && 769 ( host = xt_find_attr( c, "host" ) ) && 770 ( port = atoi( xt_find_attr( c, "port" ) ) ) && 771 ( jid = xt_find_attr( c, "jid" ) ) ) 772 { 773 jabber_streamhost_t *sh = g_new0( jabber_streamhost_t, 1 ); 774 sh->jid = g_strdup( jid ); 775 sh->host = g_strdup( host ); 776 sprintf( sh->port, "%u", port ); 777 778 imcb_log( ic, "Proxy found: jid %s host %s port %u", jid, host, port ); 779 jd->streamhosts = g_slist_append( jd->streamhosts, sh ); 780 } 781 } 782 783 if( jd->have_streamhosts == 0 ) 784 jd->have_streamhosts++; 785 786 return XT_HANDLED; 787 } -
protocols/jabber/jabber.c
rf9928cb re8c8d00 63 63 64 64 s = set_add( &acc->set, "priority", "0", set_eval_priority, acc ); 65 66 s = set_add( &acc->set, "proxy", "<local>;<auto>", NULL, acc ); 65 67 66 68 s = set_add( &acc->set, "resource", "BitlBee", NULL, acc ); … … 262 264 struct jabber_data *jd = ic->proto_data; 263 265 266 while( jd->filetransfers ) 267 imcb_file_canceled( ( ( struct jabber_transfer *) jd->filetransfers->data )->ft, "Logging out" ); 268 269 while( jd->streamhosts ) 270 { 271 jabber_streamhost_t *sh = jd->streamhosts->data; 272 jd->streamhosts = g_slist_remove( jd->streamhosts, sh ); 273 g_free( sh->jid ); 274 g_free( sh->host ); 275 g_free( sh ); 276 } 277 264 278 if( jd->fd >= 0 ) 265 279 jabber_end_stream( ic ); … … 550 564 ret->send_typing = jabber_send_typing; 551 565 ret->handle_cmp = g_strcasecmp; 566 ret->transfer_request = jabber_si_transfer_request; 552 567 553 568 register_protocol( ret ); -
protocols/jabber/jabber.h
rf9928cb re8c8d00 61 61 } jabber_buddy_flags_t; 62 62 63 /* Stores a streamhost's (a.k.a. proxy) data */ 64 typedef struct 65 { 66 char *jid; 67 char *host; 68 char port[6]; 69 } jabber_streamhost_t; 70 63 71 typedef enum 64 72 { … … 91 99 GHashTable *node_cache; 92 100 GHashTable *buddies; 101 102 GSList *filetransfers; 103 GSList *streamhosts; 104 int have_streamhosts; 93 105 }; 94 106 … … 120 132 struct jabber_away_state *away_state; 121 133 char *away_message; 134 GSList *features; 122 135 123 136 time_t last_act; … … 133 146 char *my_full_jid; /* Separate copy because of case sensitivity. */ 134 147 struct jabber_buddy *me; 148 }; 149 150 struct jabber_transfer 151 { 152 /* bitlbee's handle for this transfer */ 153 file_transfer_t *ft; 154 155 /* the stream's private handle */ 156 gpointer streamhandle; 157 158 /* timeout for discover queries */ 159 gint disco_timeout; 160 gint disco_timeout_fired; 161 162 struct im_connection *ic; 163 164 struct jabber_buddy *bud; 165 166 int watch_in; 167 int watch_out; 168 169 char *ini_jid; 170 char *tgt_jid; 171 char *iq_id; 172 char *sid; 173 int accepted; 174 175 size_t bytesread, byteswritten; 176 int fd; 177 struct sockaddr_storage saddr; 135 178 }; 136 179 … … 160 203 161 204 /* Some supported extensions/legacy stuff */ 162 #define XMLNS_AUTH "jabber:iq:auth" /* XEP-0078 */ 163 #define XMLNS_VERSION "jabber:iq:version" /* XEP-0092 */ 164 #define XMLNS_TIME "jabber:iq:time" /* XEP-0090 */ 165 #define XMLNS_PING "urn:xmpp:ping" /* XEP-0199 */ 166 #define XMLNS_VCARD "vcard-temp" /* XEP-0054 */ 167 #define XMLNS_DELAY "jabber:x:delay" /* XEP-0091 */ 168 #define XMLNS_CHATSTATES "http://jabber.org/protocol/chatstates" /* 0085 */ 169 #define XMLNS_DISCOVER "http://jabber.org/protocol/disco#info" /* 0030 */ 170 #define XMLNS_MUC "http://jabber.org/protocol/muc" /* XEP-0045 */ 171 #define XMLNS_MUC_USER "http://jabber.org/protocol/muc#user"/* XEP-0045 */ 172 #define XMLNS_CAPS "http://jabber.org/protocol/caps" /* XEP-0115 */ 205 #define XMLNS_AUTH "jabber:iq:auth" /* XEP-0078 */ 206 #define XMLNS_VERSION "jabber:iq:version" /* XEP-0092 */ 207 #define XMLNS_TIME "jabber:iq:time" /* XEP-0090 */ 208 #define XMLNS_PING "urn:xmpp:ping" /* XEP-0199 */ 209 #define XMLNS_VCARD "vcard-temp" /* XEP-0054 */ 210 #define XMLNS_DELAY "jabber:x:delay" /* XEP-0091 */ 211 #define XMLNS_XDATA "jabber:x:data" /* XEP-0004 */ 212 #define XMLNS_CHATSTATES "http://jabber.org/protocol/chatstates" /* XEP-0085 */ 213 #define XMLNS_DISCO_INFO "http://jabber.org/protocol/disco#info" /* XEP-0030 */ 214 #define XMLNS_DISCO_ITEMS "http://jabber.org/protocol/disco#items" /* XEP-0030 */ 215 #define XMLNS_MUC "http://jabber.org/protocol/muc" /* XEP-0045 */ 216 #define XMLNS_MUC_USER "http://jabber.org/protocol/muc#user" /* XEP-0045 */ 217 #define XMLNS_CAPS "http://jabber.org/protocol/caps" /* XEP-0115 */ 218 #define XMLNS_FEATURE "http://jabber.org/protocol/feature-neg" /* XEP-0020 */ 219 #define XMLNS_SI "http://jabber.org/protocol/si" /* XEP-0095 */ 220 #define XMLNS_FILETRANSFER "http://jabber.org/protocol/si/profile/file-transfer" /* XEP-0096 */ 221 #define XMLNS_BYTESTREAMS "http://jabber.org/protocol/bytestreams" /* XEP-0065 */ 222 #define XMLNS_IBB "http://jabber.org/protocol/ibb" /* XEP-0047 */ 173 223 174 224 /* iq.c */ … … 180 230 int jabber_add_to_roster( struct im_connection *ic, char *handle, char *name ); 181 231 int jabber_remove_from_roster( struct im_connection *ic, char *handle ); 232 xt_status jabber_iq_query_features( struct im_connection *ic, char *bare_jid ); 233 xt_status jabber_iq_query_server( struct im_connection *ic, char *jid, char *xmlns ); 234 235 /* si.c */ 236 int jabber_si_handle_request( struct im_connection *ic, struct xt_node *node, struct xt_node *sinode ); 237 void jabber_si_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who ); 238 void jabber_si_free_transfer( file_transfer_t *ft); 239 240 /* s5bytestream.c */ 241 int jabber_bs_recv_request( struct im_connection *ic, struct xt_node *node, struct xt_node *qnode); 242 gboolean jabber_bs_send_start( struct jabber_transfer *tf ); 243 gboolean jabber_bs_send_write( file_transfer_t *ft, char *buffer, unsigned int len ); 182 244 183 245 /* message.c */ … … 193 255 char *set_eval_tls( set_t *set, char *value ); 194 256 struct xt_node *jabber_make_packet( char *name, char *type, char *to, struct xt_node *children ); 195 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type );257 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type, char *err_code ); 196 258 void jabber_cache_add( struct im_connection *ic, struct xt_node *node, jabber_cache_event func ); 197 259 struct xt_node *jabber_cache_get( struct im_connection *ic, char *id ); -
protocols/jabber/jabber_util.c
rf9928cb re8c8d00 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
rf9928cb re8c8d00 10 10 11 11 # [SH] Program variables 12 objects = msn.o msn_util.o ns.o passport.o sb.o tables.o12 objects = invitation.o msn.o msn_util.o ns.o passport.o sb.o tables.o 13 13 14 14 CFLAGS += -Wall -
protocols/msn/msn.c
rf9928cb re8c8d00 81 81 if( md ) 82 82 { 83 while( md->filetransfers ) { 84 imcb_file_canceled( md->filetransfers->data, "Closing connection" ); 85 } 86 83 87 if( md->fd >= 0 ) 84 88 closesocket( md->fd ); … … 340 344 ret->send_typing = msn_send_typing; 341 345 ret->handle_cmp = g_strcasecmp; 346 ret->transfer_request = msn_ftp_transfer_request; 342 347 343 348 register_protocol(ret); -
protocols/msn/msn.h
rf9928cb re8c8d00 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; … … 180 181 int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m ); 181 182 183 /* invitation.c */ 184 void msn_ftp_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who ); 185 182 186 #endif //_MSN_H -
protocols/msn/sb.c
rf9928cb re8c8d00 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 } 177 else if( strncmp( text, MSN_INVITE_HEADERS, sizeof( MSN_INVITE_HEADERS ) - 1 ) == 0 ) 178 { 179 buf = g_strdup( text ); 180 i = strlen( buf ); 181 } 182 else 171 183 { 172 184 buf = g_new0( char, sizeof( MSN_MESSAGE_HEADERS ) + strlen( text ) * 2 + 1 ); … … 181 193 buf[i++] = text[j]; 182 194 } 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 195 } 190 196 … … 687 693 else if( g_strncasecmp( ct, "text/x-msmsgsinvite", 19 ) == 0 ) 688 694 { 689 char *itype = msn_findheader( body, "Application-GUID:", blen ); 690 char buf[1024]; 695 char *command = msn_findheader( body, "Invitation-Command:", blen ); 696 char *cookie = msn_findheader( body, "Invitation-Cookie:", blen ); 697 unsigned int icookie; 691 698 692 699 g_free( ct ); 693 700 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 } 701 /* Every invite should have both a Command and Cookie header */ 702 if( !command || !cookie ) { 703 g_free( command ); 704 g_free( cookie ); 705 imcb_log( ic, "Warning: No command or cookie from %s", sb->who ); 706 return 1; 707 } 708 709 icookie = strtoul( cookie, NULL, 10 ); 710 g_free( cookie ); 711 712 if( g_strncasecmp( command, "INVITE", 6 ) == 0 ) { 713 msn_invitation_invite( sb, cmd[1], icookie, body, blen ); 714 } else if( g_strncasecmp( command, "ACCEPT", 6 ) == 0 ) { 715 msn_invitation_accept( sb, cmd[1], icookie, body, blen ); 716 } else if( g_strncasecmp( command, "CANCEL", 6 ) == 0 ) { 717 msn_invitation_cancel( sb, cmd[1], icookie, body, blen ); 718 } else { 719 imcb_log( ic, "Warning: Received invalid invitation with " 720 "command %s from %s", command, sb->who ); 721 } 722 723 g_free( command ); 724 } 725 else if( g_strncasecmp( ct, "application/x-msnmsgrp2p", 24 ) == 0 ) 726 { 727 imcb_error( sb->ic, "Cannot receive file from %s: BitlBee does not " 728 "support msnmsgrp2p yet.", sb->who ); 729 g_free( ct ); 745 730 } 746 731 else if( g_strncasecmp( ct, "text/x-msmsgscontrol", 20 ) == 0 ) -
protocols/nogaim.h
rf9928cb re8c8d00 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 */ … … 228 230 void (* auth_allow) (struct im_connection *, const char *who); 229 231 void (* auth_deny) (struct im_connection *, const char *who); 232 233 /* Incoming transfer request */ 234 void (* transfer_request) (struct im_connection *, file_transfer_t *ft, char *handle ); 230 235 }; 231 236 -
root_commands.c
rf9928cb re8c8d00 1125 1125 { 1126 1126 irc_usermsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "chat", cmd[1] ); 1127 } 1128 } 1129 1130 static void cmd_transfers( irc_t *irc, char **cmd ) 1131 { 1132 GSList *files = irc->file_transfers; 1133 enum { LIST, REJECT, CANCEL }; 1134 int subcmd = LIST; 1135 int fid; 1136 1137 if( !files ) 1138 { 1139 irc_usermsg( irc, "No pending transfers" ); 1140 return; 1141 } 1142 1143 if( cmd[1] && 1144 ( strcmp( cmd[1], "reject" ) == 0 ) ) 1145 { 1146 subcmd = REJECT; 1147 } 1148 else if( cmd[1] && 1149 ( strcmp( cmd[1], "cancel" ) == 0 ) && 1150 cmd[2] && 1151 ( fid = atoi( cmd[2] ) ) ) 1152 { 1153 subcmd = CANCEL; 1154 } 1155 1156 for( ; files; files = g_slist_next( files ) ) 1157 { 1158 file_transfer_t *file = files->data; 1159 1160 switch( subcmd ) { 1161 case LIST: 1162 if ( file->status == FT_STATUS_LISTENING ) 1163 irc_usermsg( irc, 1164 "Pending file(id %d): %s (Listening...)", file->local_id, file->file_name); 1165 else 1166 { 1167 int kb_per_s = 0; 1168 time_t diff = time( NULL ) - file->started ? : 1; 1169 if ( ( file->started > 0 ) && ( file->bytes_transferred > 0 ) ) 1170 kb_per_s = file->bytes_transferred / 1024 / diff; 1171 1172 irc_usermsg( irc, 1173 "Pending file(id %d): %s (%10zd/%zd kb, %d kb/s)", file->local_id, file->file_name, 1174 file->bytes_transferred/1024, file->file_size/1024, kb_per_s); 1175 } 1176 break; 1177 case REJECT: 1178 if( file->status == FT_STATUS_LISTENING ) 1179 { 1180 irc_usermsg( irc, "Rejecting file transfer for %s", file->file_name ); 1181 imcb_file_canceled( file, "Denied by user" ); 1182 } 1183 break; 1184 case CANCEL: 1185 if( file->local_id == fid ) 1186 { 1187 irc_usermsg( irc, "Canceling file transfer for %s", file->file_name ); 1188 imcb_file_canceled( file, "Canceled by user" ); 1189 } 1190 break; 1191 } 1127 1192 } 1128 1193 } … … 1149 1214 { "join_chat", 2, cmd_join_chat, 0 }, 1150 1215 { "chat", 1, cmd_chat, 0 }, 1216 { "transfers", 0, cmd_transfers, 0 }, 1151 1217 { NULL } 1152 1218 };
Note: See TracChangeset
for help on using the changeset viewer.