Changes in / [f9928cb:e8c8d00]


Ignore:
Files:
9 added
18 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    rf9928cb re8c8d00  
    1010
    1111# 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.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
     12objects = 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
     13headers = 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
    1414subdirs = lib protocols
    1515
  • conf.c

    rf9928cb re8c8d00  
    6363        conf->ping_timeout = 300;
    6464        conf->user = NULL;
     65        conf->ft_max_size = SIZE_MAX;
     66        conf->ft_max_kbps = G_MAXUINT;
     67        conf->ft_listen = NULL;
    6568        conf->protocols = NULL;
    6669        proxytype = 0;
     
    308311                                conf->user = g_strdup( ini->value );
    309312                        }
     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                        }
    310337                        else if( g_strcasecmp( ini->key, "protocols" ) == 0 )
    311338                        {
  • conf.h

    rf9928cb re8c8d00  
    5050        int ping_timeout;
    5151        char *user;
     52        size_t ft_max_size;
     53        int ft_max_kbps;
     54        char *ft_listen;
    5255        char **protocols;
    5356} conf_t;
  • doc/user-guide/commands.xml

    rf9928cb re8c8d00  
    10071007
    10081008        </bitlbee-command>
     1009       
     1010        <bitlbee-command name="transfers">
     1011                <short-description>Monitor, cancel, or reject file transfers</short-description>
     1012                <syntax>transfers [&lt;cancel&gt; id | &lt;reject&gt;]</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 &lt;action&gt;</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 &lt;cancel&gt; 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 &lt;reject&gt;</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       
    10091052</chapter>
  • irc.c

    rf9928cb re8c8d00  
    2929#include "crypting.h"
    3030#include "ipc.h"
     31#include "dcc.h"
    3132
    3233static gboolean irc_userping( gpointer _irc, int fd, b_input_condition cond );
     
    11061107                        return( 1 );
    11071108                }
     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                }               
    11081119                else
    11091120                {
    1110                         irc_usermsg( irc, "Non-ACTION CTCP's aren't supported" );
     1121                        irc_usermsg( irc, "Supported CTCPs are ACTION, VERSION, PING, TYPING, DCC" );
    11111122                        return( 0 );
    11121123                }
  • irc.h

    rf9928cb re8c8d00  
    8383        struct query *queries;
    8484        struct account *accounts;
     85        GSList *file_transfers;
    8586        struct chat *chatrooms;
    8687       
  • lib/Makefile

    rf9928cb re8c8d00  
    1010
    1111# [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
     12objects = 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
    1313
    1414CFLAGS += -Wall
  • protocols/jabber/Makefile

    rf9928cb re8c8d00  
    1010
    1111# [SH] Program variables
    12 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o
     12objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o s5bytestream.o sasl.o si.o
    1313
    1414CFLAGS += -Wall
  • protocols/jabber/iq.c

    rf9928cb re8c8d00  
    9191                        pack = 0;
    9292                }
    93                 else if( strcmp( s, XMLNS_DISCOVER ) == 0 )
    94                 {
    95                         const char *features[] = { XMLNS_DISCOVER,
     93                else if( strcmp( s, XMLNS_DISCO_INFO ) == 0 )
     94                {
     95                        const char *features[] = { XMLNS_DISCO_INFO,
    9696                                                   XMLNS_VERSION,
    9797                                                   XMLNS_TIME,
     
    9999                                                   XMLNS_MUC,
    100100                                                   XMLNS_PING,
     101                                                   XMLNS_SI,
     102                                                   XMLNS_BYTESTREAMS,
     103                                                   XMLNS_FILETRANSFER,
    101104                                                   NULL };
    102105                        const char **f;
     
    118121                {
    119122                        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 );
    121124                        pack = 0;
    122125                }
     
    124127        else if( strcmp( type, "set" ) == 0 )
    125128        {
    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" ) ) )
    128136                {
    129137                        imcb_log( ic, "Warning: Received incomplete IQ-%s packet", type );
    130138                        return XT_HANDLED;
    131139                }
    132                
     140                else if( strcmp( s, XMLNS_ROSTER ) == 0 )
     141                {
    133142                /* This is a roster push. XMPP servers send this when someone
    134143                   was added to (or removed from) the buddy list. AFAIK they're
    135144                   sent even if we added this buddy in our own session. */
    136                 if( strcmp( s, XMLNS_ROSTER ) == 0 )
    137                 {
    138145                        int bare_len = strlen( ic->acc->user );
    139146                       
     
    152159                               
    153160                                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 );
    155162                                pack = 0;
    156163                        }
    157164                }
     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                }
    158170                else
    159171                {
    160172                        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 );
    162174                        pack = 0;
    163175                }
     
    609621        return st;
    610622}
     623
     624xt_status jabber_iq_parse_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
     625
     626xt_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
     656xt_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
     686xt_status jabber_iq_parse_server_features( struct im_connection *ic, struct xt_node *node, struct xt_node *orig );
     687
     688xt_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 */
     711xt_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  
    6363       
    6464        s = set_add( &acc->set, "priority", "0", set_eval_priority, acc );
     65
     66        s = set_add( &acc->set, "proxy", "<local>;<auto>", NULL, acc );
    6567       
    6668        s = set_add( &acc->set, "resource", "BitlBee", NULL, acc );
     
    262264        struct jabber_data *jd = ic->proto_data;
    263265       
     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
    264278        if( jd->fd >= 0 )
    265279                jabber_end_stream( ic );
     
    550564        ret->send_typing = jabber_send_typing;
    551565        ret->handle_cmp = g_strcasecmp;
     566        ret->transfer_request = jabber_si_transfer_request;
    552567
    553568        register_protocol( ret );
  • protocols/jabber/jabber.h

    rf9928cb re8c8d00  
    6161} jabber_buddy_flags_t;
    6262
     63/* Stores a streamhost's (a.k.a. proxy) data */
     64typedef struct
     65{
     66        char *jid;
     67        char *host;
     68        char port[6];
     69} jabber_streamhost_t;
     70
    6371typedef enum
    6472{
     
    9199        GHashTable *node_cache;
    92100        GHashTable *buddies;
     101
     102        GSList *filetransfers;
     103        GSList *streamhosts;
     104        int have_streamhosts;
    93105};
    94106
     
    120132        struct jabber_away_state *away_state;
    121133        char *away_message;
     134        GSList *features;
    122135       
    123136        time_t last_act;
     
    133146        char *my_full_jid; /* Separate copy because of case sensitivity. */
    134147        struct jabber_buddy *me;
     148};
     149
     150struct 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;
    135178};
    136179
     
    160203
    161204/* 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 */
    173223
    174224/* iq.c */
     
    180230int jabber_add_to_roster( struct im_connection *ic, char *handle, char *name );
    181231int jabber_remove_from_roster( struct im_connection *ic, char *handle );
     232xt_status jabber_iq_query_features( struct im_connection *ic, char *bare_jid );
     233xt_status jabber_iq_query_server( struct im_connection *ic, char *jid, char *xmlns );
     234
     235/* si.c */
     236int jabber_si_handle_request( struct im_connection *ic, struct xt_node *node, struct xt_node *sinode );
     237void jabber_si_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who );
     238void jabber_si_free_transfer( file_transfer_t *ft);
     239
     240/* s5bytestream.c */
     241int jabber_bs_recv_request( struct im_connection *ic, struct xt_node *node, struct xt_node *qnode);
     242gboolean jabber_bs_send_start( struct jabber_transfer *tf );
     243gboolean jabber_bs_send_write( file_transfer_t *ft, char *buffer, unsigned int len );
    182244
    183245/* message.c */
     
    193255char *set_eval_tls( set_t *set, char *value );
    194256struct 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 );
     257struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type, char *err_code );
    196258void jabber_cache_add( struct im_connection *ic, struct xt_node *node, jabber_cache_event func );
    197259struct xt_node *jabber_cache_get( struct im_connection *ic, char *id );
  • protocols/jabber/jabber_util.c

    rf9928cb re8c8d00  
    9999}
    100100
    101 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type )
     101struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type, char *err_code )
    102102{
    103103        struct xt_node *node, *c;
     
    111111        c = xt_new_node( "error", NULL, c );
    112112        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 );
    113117       
    114118        /* To make the actual error packet, we copy the original packet and
  • protocols/msn/Makefile

    rf9928cb re8c8d00  
    1010
    1111# [SH] Program variables
    12 objects = msn.o msn_util.o ns.o passport.o sb.o tables.o
     12objects = invitation.o msn.o msn_util.o ns.o passport.o sb.o tables.o
    1313
    1414CFLAGS += -Wall
  • protocols/msn/msn.c

    rf9928cb re8c8d00  
    8181        if( md )
    8282        {
     83                while( md->filetransfers ) {
     84                        imcb_file_canceled( md->filetransfers->data, "Closing connection" );
     85                }
     86               
    8387                if( md->fd >= 0 )
    8488                        closesocket( md->fd );
     
    340344        ret->send_typing = msn_send_typing;
    341345        ret->handle_cmp = g_strcasecmp;
     346        ret->transfer_request = msn_ftp_transfer_request;
    342347
    343348        register_protocol(ret);
  • protocols/msn/msn.h

    rf9928cb re8c8d00  
    6969        int sb_failures;
    7070        time_t first_sb_failure;
     71        GSList *filetransfers;
    7172       
    7273        const struct msn_away_state *away_state;
     
    180181int msn_sb_write_msg( struct im_connection *ic, struct msn_message *m );
    181182
     183/* invitation.c */
     184void msn_ftp_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who );
     185
    182186#endif //_MSN_H
  • protocols/msn/sb.c

    rf9928cb re8c8d00  
    2929#include "passport.h"
    3030#include "md5.h"
     31#include "invitation.h"
    3132
    3233static gboolean msn_sb_callback( gpointer data, gint source, b_input_condition cond );
     
    168169               
    169170                /* 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
    171183                {
    172184                        buf = g_new0( char, sizeof( MSN_MESSAGE_HEADERS ) + strlen( text ) * 2 + 1 );
     
    181193                                buf[i++] = text[j];
    182194                        }
    183                 }
    184                 else
    185                 {
    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 );
    189195                }
    190196               
     
    687693                else if( g_strncasecmp( ct, "text/x-msmsgsinvite", 19 ) == 0 )
    688694                {
    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;
    691698                       
    692699                        g_free( ct );
    693700                       
    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 );
    745730                }
    746731                else if( g_strncasecmp( ct, "text/x-msmsgscontrol", 20 ) == 0 )
  • protocols/nogaim.h

    rf9928cb re8c8d00  
    4545#include "proxy.h"
    4646#include "query.h"
     47#include "md5.h"
     48#include "ft.h"
    4749
    4850#define BUDDY_ALIAS_MAXLEN 388   /* because MSN names can be 387 characters */
     
    228230        void (* auth_allow)     (struct im_connection *, const char *who);
    229231        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 );
    230235};
    231236
  • root_commands.c

    rf9928cb re8c8d00  
    11251125        {
    11261126                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
     1130static 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                }
    11271192        }
    11281193}
     
    11491214        { "join_chat",      2, cmd_join_chat,      0 },
    11501215        { "chat",           1, cmd_chat,           0 },
     1216        { "transfers",      0, cmd_transfers,      0 },
    11511217        { NULL }
    11521218};
Note: See TracChangeset for help on using the changeset viewer.