Changeset 2c2df7d


Ignore:
Timestamp:
2007-11-28T21:07:30Z (13 years ago)
Author:
ulim <a.sporto+bee@…>
Branches:
master
Children:
2ff2076, fa30fa5
Parents:
221a273
Message:

Initial import of jabber file receive and DCC send support. This introduces
only a few changes to bitlbees code, mainly the addition of the "transfers"
command.

This is known to work with Kopete, Psi, and Pidgin (formerly known as gaim).
At least with Pidgin also over a proxy. DCC has only been tested with irssi.
IPV6 is untested but should work.

Currently, only receiving via SOCKS5BYTESREAMS is implemented. I'm not sure if
the alternative(in-band bytestreams IBB) is worth implementing since I didn't
see a client yet that can do it. Additionally, it is probably very slow and
needs support by the server as well.

Files:
5 added
10 edited

Legend:

Unmodified
Added
Removed
  • Makefile

    r221a273 r2c2df7d  
    1010
    1111# Program variables
    12 objects = account.o bitlbee.o conf.o crypting.o help.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) unix.o 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 conf.o crypting.o help.o ipc.o irc.o irc_commands.o log.o nick.o query.o root_commands.o set.o storage.o $(STORAGE_OBJS) unix.o user.o dcc.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 dcc.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
    1414subdirs = lib protocols
    1515
  • conf.c

    r221a273 r2c2df7d  
    6363        conf->ping_interval = 180;
    6464        conf->ping_timeout = 300;
     65        conf->max_filetransfer_size = G_MAXUINT;
    6566        proxytype = 0;
    6667       
  • conf.h

    r221a273 r2c2df7d  
    4949        int ping_interval;
    5050        int ping_timeout;
     51        size_t max_filetransfer_size;
    5152} conf_t;
    5253
  • irc.h

    r221a273 r2c2df7d  
    8484        struct query *queries;
    8585        struct account *accounts;
     86        GSList *file_transfers;
    8687       
    8788        struct __USER *users;
  • protocols/jabber/Makefile

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

    r221a273 r2c2df7d  
    104104                                                   XMLNS_CHATSTATES,
    105105                                                   XMLNS_MUC,
     106                                                   XMLNS_SI,
     107                                                   XMLNS_BYTESTREAMS,
     108                                                   XMLNS_FILETRANSFER,
    106109                                                   NULL };
    107110                        const char **f;
     
    123126                {
    124127                        xt_free_node( reply );
    125                         reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel" );
     128                        reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel", NULL );
    126129                        pack = 0;
    127130                }
     
    129132        else if( strcmp( type, "set" ) == 0 )
    130133        {
    131                 if( !( c = xt_find_node( node->children, "query" ) ) ||
     134                if(  ( c = xt_find_node( node->children, "si" ) ) &&
     135                     ( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_SI ) == 0 ) )
     136                {
     137                        return jabber_si_handle_request( ic, node, c );
     138                } else if( !( c = xt_find_node( node->children, "query" ) ) ||
    132139                    !( s = xt_find_attr( c, "xmlns" ) ) )
    133140                {
    134141                        imcb_log( ic, "WARNING: Received incomplete IQ-%s packet", type );
    135142                        return XT_HANDLED;
    136                 }
    137                
     143                } else if( strcmp( s, XMLNS_ROSTER ) == 0 )
     144                {
    138145                /* This is a roster push. XMPP servers send this when someone
    139146                   was added to (or removed from) the buddy list. AFAIK they're
    140147                   sent even if we added this buddy in our own session. */
    141                 if( strcmp( s, XMLNS_ROSTER ) == 0 )
    142                 {
    143148                        int bare_len = strlen( ic->acc->user );
    144149                       
     
    157162                               
    158163                                xt_free_node( reply );
    159                                 reply = jabber_make_error_packet( node, "not-allowed", "cancel" );
     164                                reply = jabber_make_error_packet( node, "not-allowed", "cancel", NULL );
    160165                                pack = 0;
    161166                        }
    162                 }
    163                 else
     167                } else if( strcmp( s, XMLNS_BYTESTREAMS ) == 0 )
     168                {
     169                        /* Bytestream Request (stage 2 of file transfer) */
     170                        return jabber_bs_request( ic, node, c );
     171                } else
    164172                {
    165173                        xt_free_node( reply );
    166                         reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel" );
     174                        reply = jabber_make_error_packet( node, "feature-not-implemented", "cancel", NULL );
    167175                        pack = 0;
    168176                }
  • protocols/jabber/jabber.h

    r221a273 r2c2df7d  
    8181        GHashTable *node_cache;
    8282        GHashTable *buddies;
     83
     84        GSList *filetransfers;
    8385};
    8486
     
    122124        char *my_full_jid; /* Separate copy because of case sensitivity. */
    123125        struct jabber_buddy *me;
     126};
     127
     128struct jabber_transfer
     129{
     130        /* bitlbee's handle for this transfer */
     131        file_transfer_t *ft;
     132
     133        /* the stream's private handle */
     134        gpointer streamhandle;
     135
     136        struct im_connection *ic;
     137
     138        int watch_in;
     139        int watch_out;
     140
     141        char *ini_jid;
     142        char *tgt_jid;
     143        char *iq_id;
     144        char *sid;
     145        int accepted;
     146
     147        size_t bytesread, byteswritten;
     148        int receiver_overflow;
     149        int fd;
    124150};
    125151
     
    149175
    150176/* Some supported extensions/legacy stuff */
    151 #define XMLNS_AUTH         "jabber:iq:auth"                     /* XEP-0078 */
    152 #define XMLNS_VERSION      "jabber:iq:version"                  /* XEP-0092 */
    153 #define XMLNS_TIME         "jabber:iq:time"                     /* XEP-0090 */
    154 #define XMLNS_VCARD        "vcard-temp"                         /* XEP-0054 */
    155 #define XMLNS_DELAY        "jabber:x:delay"                     /* XEP-0091 */
    156 #define XMLNS_CHATSTATES   "http://jabber.org/protocol/chatstates"  /* 0085 */
    157 #define XMLNS_DISCOVER     "http://jabber.org/protocol/disco#info"  /* 0030 */
    158 #define XMLNS_MUC          "http://jabber.org/protocol/muc"     /* XEP-0045 */
    159 #define XMLNS_MUC_USER     "http://jabber.org/protocol/muc#user"/* XEP-0045 */
     177#define XMLNS_AUTH         "jabber:iq:auth"                                      /* XEP-0078 */
     178#define XMLNS_VERSION      "jabber:iq:version"                                   /* XEP-0092 */
     179#define XMLNS_TIME         "jabber:iq:time"                                      /* XEP-0090 */
     180#define XMLNS_VCARD        "vcard-temp"                                          /* XEP-0054 */
     181#define XMLNS_DELAY        "jabber:x:delay"                                      /* XEP-0091 */
     182#define XMLNS_XDATA        "jabber:x:data"                                       /* XEP-0004 */
     183#define XMLNS_CHATSTATES   "http://jabber.org/protocol/chatstates"               /* XEP-0085 */
     184#define XMLNS_DISCOVER     "http://jabber.org/protocol/disco#info"               /* XEP-0030 */
     185#define XMLNS_MUC          "http://jabber.org/protocol/muc"                      /* XEP-0045 */
     186#define XMLNS_MUC_USER     "http://jabber.org/protocol/muc#user"                 /* XEP-0045 */
     187#define XMLNS_FEATURE      "http://jabber.org/protocol/feature-neg"              /* XEP-0020 */
     188#define XMLNS_SI           "http://jabber.org/protocol/si"                       /* XEP-0095 */
     189#define XMLNS_FILETRANSFER "http://jabber.org/protocol/si/profile/file-transfer" /* XEP-0096 */
     190#define XMLNS_BYTESTREAMS  "http://jabber.org/protocol/bytestreams"              /* XEP-0065 */
     191#define XMLNS_IBB          "http://jabber.org/protocol/ibb"                      /* XEP-0047 */
    160192
    161193/* iq.c */
     
    168200int jabber_remove_from_roster( struct im_connection *ic, char *handle );
    169201
     202/* si.c */
     203int jabber_si_handle_request( struct im_connection *ic, struct xt_node *node, struct xt_node *sinode);
     204
     205/* stream.c */
     206int jabber_bs_request( struct im_connection *ic, struct xt_node *node, struct xt_node *qnode);
     207
    170208/* message.c */
    171209xt_status jabber_pkt_message( struct xt_node *node, gpointer data );
     
    180218char *set_eval_tls( set_t *set, char *value );
    181219struct xt_node *jabber_make_packet( char *name, char *type, char *to, struct xt_node *children );
    182 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type );
     220struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type, char *err_code );
    183221void jabber_cache_add( struct im_connection *ic, struct xt_node *node, jabber_cache_event func );
    184222struct xt_node *jabber_cache_get( struct im_connection *ic, char *id );
  • protocols/jabber/jabber_util.c

    r221a273 r2c2df7d  
    9797}
    9898
    99 struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type )
     99struct xt_node *jabber_make_error_packet( struct xt_node *orig, char *err_cond, char *err_type, char *err_code )
    100100{
    101101        struct xt_node *node, *c;
     
    109109        c = xt_new_node( "error", NULL, c );
    110110        xt_add_attr( c, "type", err_type );
     111       
     112        /* Add the error code, if present */
     113        if (err_code)
     114                xt_add_attr( c, "code", err_code );
    111115       
    112116        /* To make the actual error packet, we copy the original packet and
  • protocols/nogaim.h

    r221a273 r2c2df7d  
    4343#include "proxy.h"
    4444#include "md5.h"
     45#include "ft.h"
    4546
    4647#define BUF_LEN MSG_LEN
  • root_commands.c

    r221a273 r2c2df7d  
    972972                irc_usermsg( irc, "Tried to join chat, not sure if this was successful" );
    973973                g_free( channel );
     974        }
     975}
     976
     977static void cmd_transfers( irc_t *irc, char **cmd )
     978{
     979        GSList *files = irc->file_transfers;
     980        enum { LIST, REJECT, CANCEL };
     981        int subcmd = LIST;
     982        int fid;
     983
     984        if( !files )
     985        {
     986                irc_usermsg( irc, "No pending transfers" );
     987                return;
     988        }
     989
     990        if( cmd[1] &&
     991            ( strcmp( cmd[1], "reject" ) == 0 ) )
     992        {
     993                subcmd = REJECT;
     994        }
     995        else if( cmd[1] &&
     996                 ( strcmp( cmd[1], "cancel" ) == 0 ) &&
     997                 cmd[2] &&
     998                 ( fid = atoi( cmd[2] ) ) )
     999        {
     1000                subcmd = CANCEL;
     1001        }
     1002
     1003        for( ; files; files = g_slist_next( files ) )
     1004        {
     1005                file_transfer_t *file = files->data;
     1006               
     1007                switch( subcmd ) {
     1008                case LIST:
     1009                        if ( file->status == FT_STATUS_LISTENING )
     1010                                irc_usermsg( irc,
     1011                                        "Pending file(id %d): %s (Listening...)", file->local_id, file->file_name);
     1012                        else
     1013                        {
     1014                                int kb_per_s = 0;
     1015                                time_t diff = time( NULL ) - file->started;
     1016                                if ( ( file->started > 0 ) && ( file->bytes_transferred > 0 ) )
     1017                                        kb_per_s = file->bytes_transferred / 1024 / diff;
     1018                                       
     1019                                irc_usermsg( irc,
     1020                                        "Pending file(id %d): %s (%10zd/%zd kb, %d kb/s)", file->local_id, file->file_name,
     1021                                        file->bytes_transferred/1024, file->file_size/1024, kb_per_s);
     1022                        }
     1023                        break;
     1024                case REJECT:
     1025                        if( file->status == FT_STATUS_LISTENING )
     1026                        {
     1027                                irc_usermsg( irc, "Rejecting file transfer for %s", file->file_name );
     1028                                imcb_file_canceled( file, "Denied by user" );
     1029                        }
     1030                        break;
     1031                case CANCEL:
     1032                        if( file->local_id == fid )
     1033                        {
     1034                                irc_usermsg( irc, "Canceling file transfer for %s", file->file_name );
     1035                                imcb_file_canceled( file, "Canceled by user" );
     1036                        }
     1037                        break;
     1038                }
    9741039        }
    9751040}
     
    9951060        { "qlist",          0, cmd_qlist,          0 },
    9961061        { "join_chat",      2, cmd_join_chat,      0 },
     1062        { "transfers",      0, cmd_transfers,      0 },
    9971063        { NULL }
    9981064};
Note: See TracChangeset for help on using the changeset viewer.