Changes in / [718e05f:8661caa]
- Files:
-
- 5 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
r718e05f r8661caa 10 10 11 11 # Program variables 12 objects = account.o bitlbee.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.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/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 12 objects = account.o bitlbee.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.o dcc.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/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 14 14 subdirs = lib protocols 15 15 -
conf.c
r718e05f r8661caa 63 63 conf->ping_timeout = 300; 64 64 conf->user = NULL; 65 conf->max_filetransfer_size = G_MAXUINT; 65 66 proxytype = 0; 66 67 -
conf.h
r718e05f r8661caa 50 50 int ping_timeout; 51 51 char *user; 52 size_t max_filetransfer_size; 52 53 } conf_t; 53 54 -
doc/user-guide/commands.xml
r718e05f r8661caa 874 874 875 875 </bitlbee-command> 876 877 <bitlbee-command name="transfers"> 878 <short-description>Monitor, cancel, or reject file transfers</short-description> 879 <syntax>transfers [<cancel> id | <reject>]</syntax> 880 881 <description> 882 <para> 883 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. 884 </para> 885 886 <ircexample> 887 <ircline nick="ulim">transfers</ircline> 888 </ircexample> 889 </description> 890 891 <bitlbee-command name="cancel"> 892 <short-description>Cancels the file transfer with the given id</short-description> 893 <syntax>transfers <cancel> id</syntax> 894 895 <description> 896 <para>Cancels the file transfer with the given id</para> 897 </description> 898 899 <ircexample> 900 <ircline nick="ulim">transfers cancel 1</ircline> 901 <ircline nick="root">Canceling file transfer for test</ircline> 902 </ircexample> 903 </bitlbee-command> 904 905 <bitlbee-command name="reject"> 906 <short-description>Rejects all incoming transfers</short-description> 907 <syntax>transfers <reject></syntax> 908 909 <description> 910 <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> 911 </description> 912 913 <ircexample> 914 <ircline nick="ulim">transfers reject</ircline> 915 </ircexample> 916 </bitlbee-command> 917 </bitlbee-command> 918 876 919 </chapter> -
irc.c
r718e05f r8661caa 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 ); … … 1075 1076 return( 1 ); 1076 1077 } 1078 else if( g_strncasecmp( s + 1, "DCC", 3 ) == 0 ) 1079 { 1080 if( u && u->ic && u->ic->acc->prpl->transfer_request ) 1081 { 1082 file_transfer_t *ft = dcc_request( u->ic, s + 5 ); 1083 if ( ft ) 1084 u->ic->acc->prpl->transfer_request( u->ic, ft, u->handle ); 1085 } 1086 return( 1 ); 1087 } 1077 1088 else 1078 1089 { 1079 irc_usermsg( irc, " Non-ACTION CTCP's aren't supported" );1090 irc_usermsg( irc, "Supported CTCPs are ACTION, VERSION, PING, TYPING, DCC" ); 1080 1091 return( 0 ); 1081 1092 } -
irc.h
r718e05f r8661caa 87 87 struct query *queries; 88 88 struct account *accounts; 89 GSList *file_transfers; 89 90 90 91 struct __USER *users; -
protocols/jabber/Makefile
r718e05f r8661caa 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
r718e05f r8661caa 90 90 pack = 0; 91 91 } 92 else if( strcmp( s, XMLNS_DISCO VER) == 0 )93 { 94 const char *features[] = { XMLNS_DISCO VER,92 else if( strcmp( s, XMLNS_DISCO_INFO ) == 0 ) 93 { 94 const char *features[] = { XMLNS_DISCO_INFO, 95 95 XMLNS_VERSION, 96 96 XMLNS_TIME, … … 98 98 XMLNS_MUC, 99 99 XMLNS_PING, 100 XMLNS_SI, 101 XMLNS_BYTESTREAMS, 102 XMLNS_FILETRANSFER, 100 103 NULL }; 101 104 const char **f; … … 117 120 { 118 121 xt_free_node( reply ); 119 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel" );122 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel", NULL ); 120 123 pack = 0; 121 124 } … … 123 126 else if( strcmp( type, "set" ) == 0 ) 124 127 { 125 if( !( c = xt_find_node( node->children, "query" ) ) || 128 if( ( c = xt_find_node( node->children, "si" ) ) && 129 ( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_SI ) == 0 ) ) 130 { 131 return jabber_si_handle_request( ic, node, c ); 132 } else if( !( c = xt_find_node( node->children, "query" ) ) || 126 133 !( s = xt_find_attr( c, "xmlns" ) ) ) 127 134 { 128 135 imcb_log( ic, "Warning: Received incomplete IQ-%s packet", type ); 129 136 return XT_HANDLED; 130 } 131 137 } else if( strcmp( s, XMLNS_ROSTER ) == 0 ) 138 { 132 139 /* This is a roster push. XMPP servers send this when someone 133 140 was added to (or removed from) the buddy list. AFAIK they're 134 141 sent even if we added this buddy in our own session. */ 135 if( strcmp( s, XMLNS_ROSTER ) == 0 )136 {137 142 int bare_len = strlen( ic->acc->user ); 138 143 … … 151 156 152 157 xt_free_node( reply ); 153 reply = jabber_make_error_packet( node, "not-allowed", "cancel" );158 reply = jabber_make_error_packet( node, "not-allowed", "cancel", NULL ); 154 159 pack = 0; 155 160 } 156 } 157 else 161 } else if( strcmp( s, XMLNS_BYTESTREAMS ) == 0 ) 162 { 163 /* Bytestream Request (stage 2 of file transfer) */ 164 return jabber_bs_recv_request( ic, node, c ); 165 } else 158 166 { 159 167 xt_free_node( reply ); 160 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel" );168 reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel", NULL ); 161 169 pack = 0; 162 170 } … … 593 601 return st; 594 602 } 603 604 xt_status jabber_iq_parse_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ); 605 606 xt_status jabber_iq_query_features( struct im_connection *ic, char *bare_jid ) 607 { 608 struct xt_node *node, *query; 609 struct jabber_buddy *bud; 610 611 if( ( bud = jabber_buddy_by_jid( ic, bare_jid , 0 ) ) == NULL ) 612 { 613 /* Who cares about the unknown... */ 614 imcb_log( ic, "Couldn't find buddy: %s", bare_jid); 615 return 0; 616 } 617 618 if( bud->features ) /* been here already */ 619 return XT_HANDLED; 620 621 node = xt_new_node( "query", NULL, NULL ); 622 xt_add_attr( node, "xmlns", XMLNS_DISCO_INFO ); 623 624 if( !( query = jabber_make_packet( "iq", "get", bare_jid, node ) ) ) 625 { 626 imcb_log( ic, "WARNING: Couldn't generate feature query" ); 627 xt_free_node( node ); 628 return 0; 629 } 630 631 jabber_cache_add( ic, query, jabber_iq_parse_features ); 632 633 return jabber_write_packet( ic, query ); 634 } 635 636 xt_status jabber_iq_parse_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) 637 { 638 struct xt_node *c; 639 struct jabber_buddy *bud; 640 char *feature; 641 642 if( !( c = xt_find_node( node->children, "query" ) ) || 643 !( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_DISCO_INFO ) == 0 ) ) 644 { 645 imcb_log( ic, "WARNING: Received incomplete IQ-result packet for discover" ); 646 return XT_HANDLED; 647 } 648 if( ( bud = jabber_buddy_by_jid( ic, xt_find_attr( node, "from") , 0 ) ) == NULL ) 649 { 650 /* Who cares about the unknown... */ 651 imcb_log( ic, "Couldn't find buddy: %s", xt_find_attr( node, "from")); 652 return 0; 653 } 654 655 c = c->children; 656 while( ( c = xt_find_node( c, "feature" ) ) ) { 657 feature = xt_find_attr( c, "var" ); 658 bud->features = g_slist_append(bud->features, g_strdup(feature) ); 659 c = c->next; 660 } 661 662 return XT_HANDLED; 663 } 664 665 xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ); 666 667 xt_status jabber_iq_query_server( struct im_connection *ic, char *jid, char *xmlns ) 668 { 669 struct xt_node *node, *query; 670 struct jabber_data *jd = ic->proto_data; 671 672 node = xt_new_node( "query", NULL, NULL ); 673 xt_add_attr( node, "xmlns", xmlns ); 674 675 if( !( query = jabber_make_packet( "iq", "get", jid, node ) ) ) 676 { 677 imcb_log( ic, "WARNING: Couldn't generate server query" ); 678 xt_free_node( node ); 679 } 680 681 jd->have_streamhosts--; 682 jabber_cache_add( ic, query, jabber_iq_parse_server_features ); 683 684 return jabber_write_packet( ic, query ); 685 } 686 687 /* 688 * Query the server for "items", query each "item" for identities, query each "item" that's a proxy for it's bytestream info 689 */ 690 xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) 691 { 692 struct xt_node *c; 693 struct jabber_data *jd = ic->proto_data; 694 695 if( !( c = xt_find_node( node->children, "query" ) ) || 696 !xt_find_attr( node, "from" ) ) 697 { 698 imcb_log( ic, "WARNING: Received incomplete IQ-result packet for discover" ); 699 return XT_HANDLED; 700 } 701 702 jd->have_streamhosts++; 703 704 if( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_DISCO_ITEMS ) == 0 ) 705 { 706 char *item, *itemjid; 707 708 /* answer from server */ 709 710 c = c->children; 711 while( ( c = xt_find_node( c, "item" ) ) ) 712 { 713 item = xt_find_attr( c, "name" ); 714 itemjid = xt_find_attr( c, "jid" ); 715 716 jabber_iq_query_server( ic, itemjid, XMLNS_DISCO_INFO ); 717 718 c = c->next; 719 } 720 } else if( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_DISCO_INFO ) == 0 ) 721 { 722 char *category, *type; 723 724 /* answer from potential proxy */ 725 726 c = c->children; 727 while( ( c = xt_find_node( c, "identity" ) ) ) 728 { 729 category = xt_find_attr( c, "category" ); 730 type = xt_find_attr( c, "type" ); 731 732 if( type && ( strcmp( type, "bytestreams" ) == 0 ) && 733 category && ( strcmp( category, "proxy" ) == 0 ) ) 734 jabber_iq_query_server( ic, xt_find_attr( node, "from" ), XMLNS_BYTESTREAMS ); 735 736 c = c->next; 737 } 738 } else if( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_BYTESTREAMS ) == 0 ) 739 { 740 char *host, *jid; 741 int port; 742 743 /* answer from proxy */ 744 745 if( ( c = xt_find_node( c->children, "streamhost" ) ) && 746 ( host = xt_find_attr( c, "host" ) ) && 747 ( port = atoi( xt_find_attr( c, "port" ) ) ) && 748 ( jid = xt_find_attr( c, "jid" ) ) ) 749 { 750 jabber_streamhost_t *sh = g_new0( jabber_streamhost_t, 1 ); 751 sh->jid = g_strdup( jid ); 752 sh->host = g_strdup( host ); 753 sprintf( sh->port, "%u", port ); 754 755 imcb_log( ic, "Proxy found: jid %s host %s port %u", jid, host, port ); 756 jd->streamhosts = g_slist_append( jd->streamhosts, sh ); 757 } 758 } 759 760 if( jd->have_streamhosts == 0 ) 761 jd->have_streamhosts++; 762 return XT_HANDLED; 763 } -
protocols/jabber/jabber.c
r718e05f r8661caa 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
r718e05f r8661caa 59 59 } jabber_buddy_flags_t; 60 60 61 /* Stores a streamhost's(a.k.a. proxy) data */ 62 typedef struct 63 { 64 char *jid; 65 char *host; 66 char port[6]; 67 } jabber_streamhost_t; 68 61 69 typedef enum 62 70 { … … 89 97 GHashTable *node_cache; 90 98 GHashTable *buddies; 99 100 GSList *filetransfers; 101 GSList *streamhosts; 102 int have_streamhosts; 91 103 }; 92 104 … … 118 130 struct jabber_away_state *away_state; 119 131 char *away_message; 132 GSList *features; 120 133 121 134 time_t last_act; … … 131 144 char *my_full_jid; /* Separate copy because of case sensitivity. */ 132 145 struct jabber_buddy *me; 146 }; 147 148 struct jabber_transfer 149 { 150 /* bitlbee's handle for this transfer */ 151 file_transfer_t *ft; 152 153 /* the stream's private handle */ 154 gpointer streamhandle; 155 156 /* timeout for discover queries */ 157 gint disco_timeout; 158 gint disco_timeout_fired; 159 160 struct im_connection *ic; 161 162 struct jabber_buddy *bud; 163 164 int watch_in; 165 int watch_out; 166 167 char *ini_jid; 168 char *tgt_jid; 169 char *iq_id; 170 char *sid; 171 int accepted; 172 173 size_t bytesread, byteswritten; 174 int fd; 175 struct sockaddr_storage saddr; 133 176 }; 134 177 … … 158 201 159 202 /* Some supported extensions/legacy stuff */ 160 #define XMLNS_AUTH "jabber:iq:auth" /* XEP-0078 */ 161 #define XMLNS_VERSION "jabber:iq:version" /* XEP-0092 */ 162 #define XMLNS_TIME "jabber:iq:time" /* XEP-0090 */ 163 #define XMLNS_PING "urn:xmpp:ping" /* XEP-0199 */ 164 #define XMLNS_VCARD "vcard-temp" /* XEP-0054 */ 165 #define XMLNS_DELAY "jabber:x:delay" /* XEP-0091 */ 166 #define XMLNS_CHATSTATES "http://jabber.org/protocol/chatstates" /* 0085 */ 167 #define XMLNS_DISCOVER "http://jabber.org/protocol/disco#info" /* 0030 */ 168 #define XMLNS_MUC "http://jabber.org/protocol/muc" /* XEP-0045 */ 169 #define XMLNS_MUC_USER "http://jabber.org/protocol/muc#user"/* XEP-0045 */ 170 #define XMLNS_CAPS "http://jabber.org/protocol/caps" /* XEP-0115 */ 203 #define XMLNS_AUTH "jabber:iq:auth" /* XEP-0078 */ 204 #define XMLNS_VERSION "jabber:iq:version" /* XEP-0092 */ 205 #define XMLNS_TIME "jabber:iq:time" /* XEP-0090 */ 206 #define XMLNS_PING "urn:xmpp:ping" /* XEP-0199 */ 207 #define XMLNS_VCARD "vcard-temp" /* XEP-0054 */ 208 #define XMLNS_DELAY "jabber:x:delay" /* XEP-0091 */ 209 #define XMLNS_XDATA "jabber:x:data" /* XEP-0004 */ 210 #define XMLNS_CHATSTATES "http://jabber.org/protocol/chatstates" /* XEP-0085 */ 211 #define XMLNS_DISCO_INFO "http://jabber.org/protocol/disco#info" /* XEP-0030 */ 212 #define XMLNS_DISCO_ITEMS "http://jabber.org/protocol/disco#items" /* XEP-0030 */ 213 #define XMLNS_MUC "http://jabber.org/protocol/muc" /* XEP-0045 */ 214 #define XMLNS_MUC_USER "http://jabber.org/protocol/muc#user" /* XEP-0045 */ 215 #define XMLNS_CAPS "http://jabber.org/protocol/caps" /* XEP-0115 */ 216 #define XMLNS_FEATURE "http://jabber.org/protocol/feature-neg" /* XEP-0020 */ 217 #define XMLNS_SI "http://jabber.org/protocol/si" /* XEP-0095 */ 218 #define XMLNS_FILETRANSFER "http://jabber.org/protocol/si/profile/file-transfer" /* XEP-0096 */ 219 #define XMLNS_BYTESTREAMS "http://jabber.org/protocol/bytestreams" /* XEP-0065 */ 220 #define XMLNS_IBB "http://jabber.org/protocol/ibb" /* XEP-0047 */ 171 221 172 222 /* iq.c */ … … 178 228 int jabber_add_to_roster( struct im_connection *ic, char *handle, char *name ); 179 229 int jabber_remove_from_roster( struct im_connection *ic, char *handle ); 230 xt_status jabber_iq_query_features( struct im_connection *ic, char *bare_jid ); 231 xt_status jabber_iq_query_server( struct im_connection *ic, char *jid, char *xmlns ); 232 233 /* si.c */ 234 int jabber_si_handle_request( struct im_connection *ic, struct xt_node *node, struct xt_node *sinode ); 235 void jabber_si_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who ); 236 void jabber_si_free_transfer( file_transfer_t *ft); 237 238 /* s5bytestream.c */ 239 int jabber_bs_recv_request( struct im_connection *ic, struct xt_node *node, struct xt_node *qnode); 240 gboolean jabber_bs_send_start( struct jabber_transfer *tf ); 241 gboolean jabber_bs_send_write( file_transfer_t *ft, char *buffer, unsigned int len ); 180 242 181 243 /* message.c */ … … 191 253 char *set_eval_tls( set_t *set, char *value ); 192 254 struct xt_node *jabber_make_packet( char *name, char *type, char *to, struct xt_node *children ); 193 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type );255 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type, char *err_code ); 194 256 void jabber_cache_add( struct im_connection *ic, struct xt_node *node, jabber_cache_event func ); 195 257 struct xt_node *jabber_cache_get( struct im_connection *ic, char *id ); -
protocols/jabber/jabber_util.c
r718e05f r8661caa 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/nogaim.h
r718e05f r8661caa 44 44 #include "query.h" 45 45 #include "md5.h" 46 #include "ft.h" 46 47 47 48 #define BUDDY_ALIAS_MAXLEN 388 /* because MSN names can be 387 characters */ … … 224 225 * - Most protocols will just want to set this to g_strcasecmp().*/ 225 226 int (* handle_cmp) (const char *who1, const char *who2); 227 228 /* Incoming transfer request */ 229 void (* transfer_request) (struct im_connection *, file_transfer_t *ft, char *handle ); 226 230 }; 227 231 -
root_commands.c
r718e05f r8661caa 1041 1041 irc_usermsg( irc, "Tried to join chat, not sure if this was successful" ); 1042 1042 g_free( channel ); 1043 } 1044 } 1045 1046 static void cmd_transfers( irc_t *irc, char **cmd ) 1047 { 1048 GSList *files = irc->file_transfers; 1049 enum { LIST, REJECT, CANCEL }; 1050 int subcmd = LIST; 1051 int fid; 1052 1053 if( !files ) 1054 { 1055 irc_usermsg( irc, "No pending transfers" ); 1056 return; 1057 } 1058 1059 if( cmd[1] && 1060 ( strcmp( cmd[1], "reject" ) == 0 ) ) 1061 { 1062 subcmd = REJECT; 1063 } 1064 else if( cmd[1] && 1065 ( strcmp( cmd[1], "cancel" ) == 0 ) && 1066 cmd[2] && 1067 ( fid = atoi( cmd[2] ) ) ) 1068 { 1069 subcmd = CANCEL; 1070 } 1071 1072 for( ; files; files = g_slist_next( files ) ) 1073 { 1074 file_transfer_t *file = files->data; 1075 1076 switch( subcmd ) { 1077 case LIST: 1078 if ( file->status == FT_STATUS_LISTENING ) 1079 irc_usermsg( irc, 1080 "Pending file(id %d): %s (Listening...)", file->local_id, file->file_name); 1081 else 1082 { 1083 int kb_per_s = 0; 1084 time_t diff = time( NULL ) - file->started ? : 1; 1085 if ( ( file->started > 0 ) && ( file->bytes_transferred > 0 ) ) 1086 kb_per_s = file->bytes_transferred / 1024 / diff; 1087 1088 irc_usermsg( irc, 1089 "Pending file(id %d): %s (%10zd/%zd kb, %d kb/s)", file->local_id, file->file_name, 1090 file->bytes_transferred/1024, file->file_size/1024, kb_per_s); 1091 } 1092 break; 1093 case REJECT: 1094 if( file->status == FT_STATUS_LISTENING ) 1095 { 1096 irc_usermsg( irc, "Rejecting file transfer for %s", file->file_name ); 1097 imcb_file_canceled( file, "Denied by user" ); 1098 } 1099 break; 1100 case CANCEL: 1101 if( file->local_id == fid ) 1102 { 1103 irc_usermsg( irc, "Canceling file transfer for %s", file->file_name ); 1104 imcb_file_canceled( file, "Canceled by user" ); 1105 } 1106 break; 1107 } 1043 1108 } 1044 1109 } … … 1064 1129 { "qlist", 0, cmd_qlist, 0 }, 1065 1130 { "join_chat", 2, cmd_join_chat, 0 }, 1131 { "transfers", 0, cmd_transfers, 0 }, 1066 1132 { NULL } 1067 1133 };
Note: See TracChangeset
for help on using the changeset viewer.