Changeset 767a148
- Timestamp:
- 2010-03-21T16:06:31Z (15 years ago)
- Branches:
- master
- Children:
- 1cc0df3, 85693e6
- Parents:
- 545d7c0 (diff), a81d679 (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:
-
- 9 added
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
r545d7c0 r767a148 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
r545d7c0 r767a148 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
r545d7c0 r767a148 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
r545d7c0 r767a148 1028 1028 1029 1029 </bitlbee-command> 1030 1031 <bitlbee-command name="transfers"> 1032 <short-description>Monitor, cancel, or reject file transfers</short-description> 1033 <syntax>transfers [<cancel> id | <reject>]</syntax> 1034 1035 <description> 1036 <para> 1037 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. 1038 </para> 1039 1040 <ircexample> 1041 <ircline nick="ulim">transfers</ircline> 1042 </ircexample> 1043 </description> 1044 1045 <bitlbee-command name="cancel"> 1046 <short-description>Cancels the file transfer with the given id</short-description> 1047 <syntax>transfers <cancel> id</syntax> 1048 1049 <description> 1050 <para>Cancels the file transfer with the given id</para> 1051 </description> 1052 1053 <ircexample> 1054 <ircline nick="ulim">transfers cancel 1</ircline> 1055 <ircline nick="root">Canceling file transfer for test</ircline> 1056 </ircexample> 1057 </bitlbee-command> 1058 1059 <bitlbee-command name="reject"> 1060 <short-description>Rejects all incoming transfers</short-description> 1061 <syntax>transfers <reject></syntax> 1062 1063 <description> 1064 <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> 1065 </description> 1066 1067 <ircexample> 1068 <ircline nick="ulim">transfers reject</ircline> 1069 </ircexample> 1070 </bitlbee-command> 1071 </bitlbee-command> 1072 1030 1073 </chapter> -
irc.c
r545d7c0 r767a148 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 ); … … 1107 1108 return( 1 ); 1108 1109 } 1110 else if( g_strncasecmp( s + 1, "DCC", 3 ) == 0 ) 1111 { 1112 if( u && u->ic && u->ic->acc->prpl->transfer_request ) 1113 { 1114 file_transfer_t *ft = dcc_request( u->ic, s + 5 ); 1115 if ( ft ) 1116 u->ic->acc->prpl->transfer_request( u->ic, ft, u->handle ); 1117 } 1118 return( 1 ); 1119 } 1109 1120 else 1110 1121 { 1111 irc_usermsg( irc, " Non-ACTION CTCP's aren't supported" );1122 irc_usermsg( irc, "Supported CTCPs are ACTION, VERSION, PING, TYPING, DCC" ); 1112 1123 return( 0 ); 1113 1124 } -
irc.h
r545d7c0 r767a148 83 83 struct query *queries; 84 84 struct account *accounts; 85 GSList *file_transfers; 85 86 struct chat *chatrooms; 86 87 -
lib/Makefile
r545d7c0 r767a148 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
r545d7c0 r767a148 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
r545d7c0 r767a148 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 ( s = xt_find_attr( c, "xmlns" ) ) && 131 ( strcmp( s, XMLNS_SI ) == 0 ) ) 132 { 133 return jabber_si_handle_request( ic, node, c ); 134 } 135 else if( !( c = xt_find_node( node->children, "query" ) ) || 136 !( s = xt_find_attr( c, "xmlns" ) ) ) 128 137 { 129 138 imcb_log( ic, "Warning: Received incomplete IQ-%s packet", type ); 130 139 return XT_HANDLED; 131 140 } 132 141 else if( strcmp( s, XMLNS_ROSTER ) == 0 ) 142 { 133 143 /* This is a roster push. XMPP servers send this when someone 134 144 was added to (or removed from) the buddy list. AFAIK they're 135 145 sent even if we added this buddy in our own session. */ 136 if( strcmp( s, XMLNS_ROSTER ) == 0 )137 {138 146 int bare_len = strlen( ic->acc->user ); 139 147 … … 152 160 153 161 xt_free_node( reply ); 154 reply = jabber_make_error_packet( node, "not-allowed", "cancel" );162 reply = jabber_make_error_packet( node, "not-allowed", "cancel", NULL ); 155 163 pack = 0; 156 164 } 157 165 } 166 else if( strcmp( s, XMLNS_BYTESTREAMS ) == 0 ) 167 { 168 /* Bytestream Request (stage 2 of file transfer) */ 169 return jabber_bs_recv_request( ic, node, c ); 170 } 158 171 else 159 172 { 160 173 xt_free_node( reply ); 161 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel" );174 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel", NULL ); 162 175 pack = 0; 163 176 } … … 609 622 return st; 610 623 } 624 625 xt_status jabber_iq_parse_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ); 626 627 xt_status jabber_iq_query_features( struct im_connection *ic, char *bare_jid ) 628 { 629 struct xt_node *node, *query; 630 struct jabber_buddy *bud; 631 632 if( ( bud = jabber_buddy_by_jid( ic, bare_jid , 0 ) ) == NULL ) 633 { 634 /* Who cares about the unknown... */ 635 imcb_log( ic, "Couldn't find buddy: %s", bare_jid); 636 return XT_HANDLED; 637 } 638 639 if( bud->features ) /* been here already */ 640 return XT_HANDLED; 641 642 node = xt_new_node( "query", NULL, NULL ); 643 xt_add_attr( node, "xmlns", XMLNS_DISCO_INFO ); 644 645 if( !( query = jabber_make_packet( "iq", "get", bare_jid, node ) ) ) 646 { 647 imcb_log( ic, "WARNING: Couldn't generate feature query" ); 648 xt_free_node( node ); 649 return XT_HANDLED; 650 } 651 652 jabber_cache_add( ic, query, jabber_iq_parse_features ); 653 654 return jabber_write_packet( ic, query ) ? XT_HANDLED : XT_ABORT; 655 } 656 657 xt_status jabber_iq_parse_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) 658 { 659 struct xt_node *c; 660 struct jabber_buddy *bud; 661 char *feature, *xmlns, *from; 662 663 if( !( from = xt_find_attr( node, "from" ) ) || 664 !( c = xt_find_node( node->children, "query" ) ) || 665 !( xmlns = xt_find_attr( c, "xmlns" ) ) || 666 !( strcmp( xmlns, XMLNS_DISCO_INFO ) == 0 ) ) 667 { 668 imcb_log( ic, "WARNING: Received incomplete IQ-result packet for discover" ); 669 return XT_HANDLED; 670 } 671 if( ( bud = jabber_buddy_by_jid( ic, from, 0 ) ) == NULL ) 672 { 673 /* Who cares about the unknown... */ 674 imcb_log( ic, "Couldn't find buddy: %s", from ); 675 return XT_HANDLED; 676 } 677 678 c = c->children; 679 while( ( c = xt_find_node( c, "feature" ) ) ) 680 { 681 feature = xt_find_attr( c, "var" ); 682 if( feature ) 683 bud->features = g_slist_append( bud->features, g_strdup( feature ) ); 684 c = c->next; 685 } 686 687 return XT_HANDLED; 688 } 689 690 xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ); 691 692 xt_status jabber_iq_query_server( struct im_connection *ic, char *jid, char *xmlns ) 693 { 694 struct xt_node *node, *query; 695 struct jabber_data *jd = ic->proto_data; 696 697 node = xt_new_node( "query", NULL, NULL ); 698 xt_add_attr( node, "xmlns", xmlns ); 699 700 if( !( query = jabber_make_packet( "iq", "get", jid, node ) ) ) 701 { 702 imcb_log( ic, "WARNING: Couldn't generate server query" ); 703 xt_free_node( node ); 704 } 705 706 jd->have_streamhosts--; 707 jabber_cache_add( ic, query, jabber_iq_parse_server_features ); 708 709 return jabber_write_packet( ic, query ) ? XT_HANDLED : XT_ABORT; 710 } 711 712 /* 713 * Query the server for "items", query each "item" for identities, query each "item" that's a proxy for it's bytestream info 714 */ 715 xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) 716 { 717 struct xt_node *c; 718 struct jabber_data *jd = ic->proto_data; 719 char *xmlns, *from; 720 721 if( !( c = xt_find_node( node->children, "query" ) ) || 722 !( from = xt_find_attr( node, "from" ) ) || 723 !( xmlns = xt_find_attr( c, "xmlns" ) ) ) 724 { 725 imcb_log( ic, "WARNING: Received incomplete IQ-result packet for discover" ); 726 return XT_HANDLED; 727 } 728 729 jd->have_streamhosts++; 730 731 if( strcmp( xmlns, XMLNS_DISCO_ITEMS ) == 0 ) 732 { 733 char *itemjid; 734 735 /* answer from server */ 736 737 c = c->children; 738 while( ( c = xt_find_node( c, "item" ) ) ) 739 { 740 itemjid = xt_find_attr( c, "jid" ); 741 742 if( itemjid ) 743 jabber_iq_query_server( ic, itemjid, XMLNS_DISCO_INFO ); 744 745 c = c->next; 746 } 747 } 748 else if( strcmp( xmlns, XMLNS_DISCO_INFO ) == 0 ) 749 { 750 char *category, *type; 751 752 /* answer from potential proxy */ 753 754 c = c->children; 755 while( ( c = xt_find_node( c, "identity" ) ) ) 756 { 757 category = xt_find_attr( c, "category" ); 758 type = xt_find_attr( c, "type" ); 759 760 if( type && ( strcmp( type, "bytestreams" ) == 0 ) && 761 category && ( strcmp( category, "proxy" ) == 0 ) ) 762 jabber_iq_query_server( ic, from, XMLNS_BYTESTREAMS ); 763 764 c = c->next; 765 } 766 } 767 else if( strcmp( xmlns, XMLNS_BYTESTREAMS ) == 0 ) 768 { 769 char *host, *jid, *port_s; 770 int port; 771 772 /* answer from proxy */ 773 774 if( ( c = xt_find_node( c->children, "streamhost" ) ) && 775 ( host = xt_find_attr( c, "host" ) ) && 776 ( port_s = xt_find_attr( c, "port" ) ) && 777 ( sscanf( port_s, "%d", &port ) == 1 ) && 778 ( jid = xt_find_attr( c, "jid" ) ) ) 779 { 780 jabber_streamhost_t *sh = g_new0( jabber_streamhost_t, 1 ); 781 782 sh->jid = g_strdup( jid ); 783 sh->host = g_strdup( host ); 784 g_snprintf( sh->port, sizeof( sh->port ), "%u", port ); 785 786 imcb_log( ic, "Proxy found: jid %s host %s port %u", jid, host, port ); 787 jd->streamhosts = g_slist_append( jd->streamhosts, sh ); 788 } 789 } 790 791 if( jd->have_streamhosts == 0 ) 792 jd->have_streamhosts++; 793 794 return XT_HANDLED; 795 } -
protocols/jabber/jabber.c
r545d7c0 r767a148 65 65 66 66 s = set_add( &acc->set, "priority", "0", set_eval_priority, acc ); 67 68 s = set_add( &acc->set, "proxy", "<local>;<auto>", NULL, acc ); 67 69 68 70 s = set_add( &acc->set, "resource", "BitlBee", NULL, acc ); … … 264 266 struct jabber_data *jd = ic->proto_data; 265 267 268 while( jd->filetransfers ) 269 imcb_file_canceled( ( ( struct jabber_transfer *) jd->filetransfers->data )->ft, "Logging out" ); 270 271 while( jd->streamhosts ) 272 { 273 jabber_streamhost_t *sh = jd->streamhosts->data; 274 jd->streamhosts = g_slist_remove( jd->streamhosts, sh ); 275 g_free( sh->jid ); 276 g_free( sh->host ); 277 g_free( sh ); 278 } 279 266 280 if( jd->fd >= 0 ) 267 281 jabber_end_stream( ic ); … … 544 558 ret->send_typing = jabber_send_typing; 545 559 ret->handle_cmp = g_strcasecmp; 560 ret->transfer_request = jabber_si_transfer_request; 546 561 547 562 register_protocol( ret ); -
protocols/jabber/jabber.h
r545d7c0 r767a148 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 … … 127 139 struct jabber_away_state *away_state; 128 140 char *away_message; 141 GSList *features; 129 142 130 143 time_t last_msg; … … 140 153 char *my_full_jid; /* Separate copy because of case sensitivity. */ 141 154 struct jabber_buddy *me; 155 }; 156 157 struct jabber_transfer 158 { 159 /* bitlbee's handle for this transfer */ 160 file_transfer_t *ft; 161 162 /* the stream's private handle */ 163 gpointer streamhandle; 164 165 /* timeout for discover queries */ 166 gint disco_timeout; 167 gint disco_timeout_fired; 168 169 struct im_connection *ic; 170 171 struct jabber_buddy *bud; 172 173 int watch_in; 174 int watch_out; 175 176 char *ini_jid; 177 char *tgt_jid; 178 char *iq_id; 179 char *sid; 180 int accepted; 181 182 size_t bytesread, byteswritten; 183 int fd; 184 struct sockaddr_storage saddr; 142 185 }; 143 186 … … 167 210 168 211 /* Some supported extensions/legacy stuff */ 169 #define XMLNS_AUTH "jabber:iq:auth" /* XEP-0078 */ 170 #define XMLNS_VERSION "jabber:iq:version" /* XEP-0092 */ 171 #define XMLNS_TIME "jabber:iq:time" /* XEP-0090 */ 172 #define XMLNS_PING "urn:xmpp:ping" /* XEP-0199 */ 173 #define XMLNS_VCARD "vcard-temp" /* XEP-0054 */ 174 #define XMLNS_DELAY "jabber:x:delay" /* XEP-0091 */ 175 #define XMLNS_CHATSTATES "http://jabber.org/protocol/chatstates" /* 0085 */ 176 #define XMLNS_DISCOVER "http://jabber.org/protocol/disco#info" /* 0030 */ 177 #define XMLNS_MUC "http://jabber.org/protocol/muc" /* XEP-0045 */ 178 #define XMLNS_MUC_USER "http://jabber.org/protocol/muc#user"/* XEP-0045 */ 179 #define XMLNS_CAPS "http://jabber.org/protocol/caps" /* XEP-0115 */ 212 #define XMLNS_AUTH "jabber:iq:auth" /* XEP-0078 */ 213 #define XMLNS_VERSION "jabber:iq:version" /* XEP-0092 */ 214 #define XMLNS_TIME "jabber:iq:time" /* XEP-0090 */ 215 #define XMLNS_PING "urn:xmpp:ping" /* XEP-0199 */ 216 #define XMLNS_VCARD "vcard-temp" /* XEP-0054 */ 217 #define XMLNS_DELAY "jabber:x:delay" /* XEP-0091 */ 218 #define XMLNS_XDATA "jabber:x:data" /* XEP-0004 */ 219 #define XMLNS_CHATSTATES "http://jabber.org/protocol/chatstates" /* XEP-0085 */ 220 #define XMLNS_DISCO_INFO "http://jabber.org/protocol/disco#info" /* XEP-0030 */ 221 #define XMLNS_DISCO_ITEMS "http://jabber.org/protocol/disco#items" /* XEP-0030 */ 222 #define XMLNS_MUC "http://jabber.org/protocol/muc" /* XEP-0045 */ 223 #define XMLNS_MUC_USER "http://jabber.org/protocol/muc#user" /* XEP-0045 */ 224 #define XMLNS_CAPS "http://jabber.org/protocol/caps" /* XEP-0115 */ 225 #define XMLNS_FEATURE "http://jabber.org/protocol/feature-neg" /* XEP-0020 */ 226 #define XMLNS_SI "http://jabber.org/protocol/si" /* XEP-0095 */ 227 #define XMLNS_FILETRANSFER "http://jabber.org/protocol/si/profile/file-transfer" /* XEP-0096 */ 228 #define XMLNS_BYTESTREAMS "http://jabber.org/protocol/bytestreams" /* XEP-0065 */ 229 #define XMLNS_IBB "http://jabber.org/protocol/ibb" /* XEP-0047 */ 180 230 181 231 /* iq.c */ … … 187 237 int jabber_add_to_roster( struct im_connection *ic, char *handle, char *name ); 188 238 int jabber_remove_from_roster( struct im_connection *ic, char *handle ); 239 xt_status jabber_iq_query_features( struct im_connection *ic, char *bare_jid ); 240 xt_status jabber_iq_query_server( struct im_connection *ic, char *jid, char *xmlns ); 241 242 /* si.c */ 243 int jabber_si_handle_request( struct im_connection *ic, struct xt_node *node, struct xt_node *sinode ); 244 void jabber_si_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who ); 245 void jabber_si_free_transfer( file_transfer_t *ft); 246 247 /* s5bytestream.c */ 248 int jabber_bs_recv_request( struct im_connection *ic, struct xt_node *node, struct xt_node *qnode); 249 gboolean jabber_bs_send_start( struct jabber_transfer *tf ); 250 gboolean jabber_bs_send_write( file_transfer_t *ft, char *buffer, unsigned int len ); 189 251 190 252 /* message.c */ … … 200 262 char *set_eval_tls( set_t *set, char *value ); 201 263 struct xt_node *jabber_make_packet( char *name, char *type, char *to, struct xt_node *children ); 202 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type );264 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type, char *err_code ); 203 265 void jabber_cache_add( struct im_connection *ic, struct xt_node *node, jabber_cache_event func ); 204 266 struct xt_node *jabber_cache_get( struct im_connection *ic, char *id ); -
protocols/jabber/jabber_util.c
r545d7c0 r767a148 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
r545d7c0 r767a148 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
r545d7c0 r767a148 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
r545d7c0 r767a148 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
r545d7c0 r767a148 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
r545d7c0 r767a148 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
r545d7c0 r767a148 1154 1154 { 1155 1155 irc_usermsg( irc, "Unknown command: %s %s. Please use \x02help commands\x02 to get a list of available commands.", "chat", cmd[1] ); 1156 } 1157 } 1158 1159 static void cmd_transfer( irc_t *irc, char **cmd ) 1160 { 1161 GSList *files = irc->file_transfers; 1162 enum { LIST, REJECT, CANCEL }; 1163 int subcmd = LIST; 1164 int fid; 1165 1166 if( !files ) 1167 { 1168 irc_usermsg( irc, "No pending transfers" ); 1169 return; 1170 } 1171 1172 if( cmd[1] && ( strcmp( cmd[1], "reject" ) == 0 ) ) 1173 { 1174 subcmd = REJECT; 1175 } 1176 else if( cmd[1] && ( strcmp( cmd[1], "cancel" ) == 0 ) && 1177 cmd[2] && ( sscanf( cmd[2], "%d", &fid ) == 1 ) ) 1178 { 1179 subcmd = CANCEL; 1180 } 1181 1182 for( ; files; files = g_slist_next( files ) ) 1183 { 1184 file_transfer_t *file = files->data; 1185 1186 switch( subcmd ) { 1187 case LIST: 1188 if ( file->status == FT_STATUS_LISTENING ) 1189 irc_usermsg( irc, 1190 "Pending file(id %d): %s (Listening...)", file->local_id, file->file_name); 1191 else 1192 { 1193 int kb_per_s = 0; 1194 time_t diff = time( NULL ) - file->started ? : 1; 1195 if ( ( file->started > 0 ) && ( file->bytes_transferred > 0 ) ) 1196 kb_per_s = file->bytes_transferred / 1024 / diff; 1197 1198 irc_usermsg( irc, 1199 "Pending file(id %d): %s (%10zd/%zd kb, %d kb/s)", file->local_id, file->file_name, 1200 file->bytes_transferred/1024, file->file_size/1024, kb_per_s); 1201 } 1202 break; 1203 case REJECT: 1204 if( file->status == FT_STATUS_LISTENING ) 1205 { 1206 irc_usermsg( irc, "Rejecting file transfer for %s", file->file_name ); 1207 imcb_file_canceled( file, "Denied by user" ); 1208 } 1209 break; 1210 case CANCEL: 1211 if( file->local_id == fid ) 1212 { 1213 irc_usermsg( irc, "Canceling file transfer for %s", file->file_name ); 1214 imcb_file_canceled( file, "Canceled by user" ); 1215 } 1216 break; 1217 } 1156 1218 } 1157 1219 } … … 1178 1240 { "join_chat", 2, cmd_join_chat, 0 }, 1179 1241 { "chat", 1, cmd_chat, 0 }, 1242 { "transfer", 0, cmd_transfer, 0 }, 1180 1243 { NULL } 1181 1244 };
Note: See TracChangeset
for help on using the changeset viewer.