diff options
Diffstat (limited to 'protocols/jabber/si.c')
-rw-r--r-- | protocols/jabber/si.c | 552 |
1 files changed, 278 insertions, 274 deletions
diff --git a/protocols/jabber/si.c b/protocols/jabber/si.c index f3060fff..cb2487bc 100644 --- a/protocols/jabber/si.c +++ b/protocols/jabber/si.c @@ -24,147 +24,156 @@ #include "jabber.h" #include "sha1.h" -void jabber_si_answer_request( file_transfer_t *ft ); -int jabber_si_send_request(struct im_connection *ic, char *who, struct jabber_transfer *tf ); +void jabber_si_answer_request(file_transfer_t *ft); +int jabber_si_send_request(struct im_connection *ic, char *who, struct jabber_transfer *tf); /* file_transfer free() callback */ -void jabber_si_free_transfer( file_transfer_t *ft) +void jabber_si_free_transfer(file_transfer_t *ft) { struct jabber_transfer *tf = ft->data; struct jabber_data *jd = tf->ic->proto_data; - if ( tf->watch_in ) - { - b_event_remove( tf->watch_in ); + if (tf->watch_in) { + b_event_remove(tf->watch_in); tf->watch_in = 0; } - jd->filetransfers = g_slist_remove( jd->filetransfers, tf ); + jd->filetransfers = g_slist_remove(jd->filetransfers, tf); - if( tf->fd != -1 ) - { - closesocket( tf->fd ); + if (tf->fd != -1) { + closesocket(tf->fd); tf->fd = -1; } - if( tf->disco_timeout ) - b_event_remove( tf->disco_timeout ); - - g_free( tf->ini_jid ); - g_free( tf->tgt_jid ); - g_free( tf->iq_id ); - g_free( tf->sid ); - g_free( tf ); + if (tf->disco_timeout) { + b_event_remove(tf->disco_timeout); + } + + g_free(tf->ini_jid); + g_free(tf->tgt_jid); + g_free(tf->iq_id); + g_free(tf->sid); + g_free(tf); } /* file_transfer canceled() callback */ -void jabber_si_canceled( file_transfer_t *ft, char *reason ) +void jabber_si_canceled(file_transfer_t *ft, char *reason) { struct jabber_transfer *tf = ft->data; struct xt_node *reply, *iqnode; - if( tf->accepted ) + if (tf->accepted) { return; - - iqnode = jabber_make_packet( "iq", "error", tf->ini_jid, NULL ); - xt_add_attr( iqnode, "id", tf->iq_id ); - reply = jabber_make_error_packet( iqnode, "forbidden", "cancel", "403" ); - xt_free_node( iqnode ); - - if( !jabber_write_packet( tf->ic, reply ) ) - imcb_log( tf->ic, "WARNING: Error generating reply to file transfer request" ); - xt_free_node( reply ); + } + + iqnode = jabber_make_packet("iq", "error", tf->ini_jid, NULL); + xt_add_attr(iqnode, "id", tf->iq_id); + reply = jabber_make_error_packet(iqnode, "forbidden", "cancel", "403"); + xt_free_node(iqnode); + + if (!jabber_write_packet(tf->ic, reply)) { + imcb_log(tf->ic, "WARNING: Error generating reply to file transfer request"); + } + xt_free_node(reply); } -int jabber_si_check_features( struct jabber_transfer *tf, GSList *features ) { +int jabber_si_check_features(struct jabber_transfer *tf, GSList *features) +{ int foundft = FALSE, foundbt = FALSE, foundsi = FALSE; - while ( features ) - { - if( !strcmp( features->data, XMLNS_FILETRANSFER ) ) + while (features) { + if (!strcmp(features->data, XMLNS_FILETRANSFER)) { foundft = TRUE; - if( !strcmp( features->data, XMLNS_BYTESTREAMS ) ) + } + if (!strcmp(features->data, XMLNS_BYTESTREAMS)) { foundbt = TRUE; - if( !strcmp( features->data, XMLNS_SI ) ) + } + if (!strcmp(features->data, XMLNS_SI)) { foundsi = TRUE; + } features = g_slist_next(features); } - if( !foundft ) - imcb_file_canceled( tf->ic, tf->ft, "Buddy's client doesn't feature file transfers" ); - else if( !foundbt ) - imcb_file_canceled( tf->ic, tf->ft, "Buddy's client doesn't feature byte streams (required)" ); - else if( !foundsi ) - imcb_file_canceled( tf->ic, tf->ft, "Buddy's client doesn't feature stream initiation (required)" ); - + if (!foundft) { + imcb_file_canceled(tf->ic, tf->ft, "Buddy's client doesn't feature file transfers"); + } else if (!foundbt) { + imcb_file_canceled(tf->ic, tf->ft, "Buddy's client doesn't feature byte streams (required)"); + } else if (!foundsi) { + imcb_file_canceled(tf->ic, tf->ft, "Buddy's client doesn't feature stream initiation (required)"); + } + return foundft && foundbt && foundsi; } -void jabber_si_transfer_start( struct jabber_transfer *tf ) { +void jabber_si_transfer_start(struct jabber_transfer *tf) +{ - if( !jabber_si_check_features( tf, tf->bud->features ) ) + if (!jabber_si_check_features(tf, tf->bud->features)) { return; - + } + /* send the request to our buddy */ - jabber_si_send_request( tf->ic, tf->bud->full_jid, tf ); + jabber_si_send_request(tf->ic, tf->bud->full_jid, tf); /* and start the receive logic */ - imcb_file_recv_start( tf->ic, tf->ft ); + imcb_file_recv_start(tf->ic, tf->ft); } -gboolean jabber_si_waitfor_disco( gpointer data, gint fd, b_input_condition cond ) +gboolean jabber_si_waitfor_disco(gpointer data, gint fd, b_input_condition cond) { struct jabber_transfer *tf = data; struct jabber_data *jd = tf->ic->proto_data; tf->disco_timeout_fired++; - if( tf->bud->features && jd->have_streamhosts==1 ) { + if (tf->bud->features && jd->have_streamhosts == 1) { tf->disco_timeout = 0; - jabber_si_transfer_start( tf ); + jabber_si_transfer_start(tf); return FALSE; } /* 8 seconds should be enough for server and buddy to respond */ - if ( tf->disco_timeout_fired < 16 ) + if (tf->disco_timeout_fired < 16) { return TRUE; - - if( !tf->bud->features && jd->have_streamhosts!=1 ) - imcb_log( tf->ic, "Couldn't get buddy's features nor discover all services of the server" ); - else if( !tf->bud->features ) - imcb_log( tf->ic, "Couldn't get buddy's features" ); - else - imcb_log( tf->ic, "Couldn't discover some of the server's services" ); - + } + + if (!tf->bud->features && jd->have_streamhosts != 1) { + imcb_log(tf->ic, "Couldn't get buddy's features nor discover all services of the server"); + } else if (!tf->bud->features) { + imcb_log(tf->ic, "Couldn't get buddy's features"); + } else { + imcb_log(tf->ic, "Couldn't discover some of the server's services"); + } + tf->disco_timeout = 0; - jabber_si_transfer_start( tf ); + jabber_si_transfer_start(tf); return FALSE; } -void jabber_si_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who ) +void jabber_si_transfer_request(struct im_connection *ic, file_transfer_t *ft, char *who) { struct jabber_transfer *tf; struct jabber_data *jd = ic->proto_data; struct jabber_buddy *bud; char *server = jd->server, *s; - if( ( s = strchr( who, '=' ) ) && jabber_chat_by_jid( ic, s + 1 ) ) - bud = jabber_buddy_by_ext_jid( ic, who, 0 ); - else - bud = jabber_buddy_by_jid( ic, who, 0 ); + if ((s = strchr(who, '=')) && jabber_chat_by_jid(ic, s + 1)) { + bud = jabber_buddy_by_ext_jid(ic, who, 0); + } else { + bud = jabber_buddy_by_jid(ic, who, 0); + } - if( bud == NULL ) - { - imcb_file_canceled( ic, ft, "Couldn't find buddy (BUG?)" ); + if (bud == NULL) { + imcb_file_canceled(ic, ft, "Couldn't find buddy (BUG?)"); return; } - - imcb_log( ic, "Trying to send %s(%zd bytes) to %s", ft->file_name, ft->file_size, who ); - tf = g_new0( struct jabber_transfer, 1 ); + imcb_log(ic, "Trying to send %s(%zd bytes) to %s", ft->file_name, ft->file_size, who); + + tf = g_new0(struct jabber_transfer, 1); tf->ic = ic; tf->ft = ft; @@ -174,27 +183,30 @@ void jabber_si_transfer_request( struct im_connection *ic, file_transfer_t *ft, tf->bud = bud; ft->write = jabber_bs_send_write; - jd->filetransfers = g_slist_prepend( jd->filetransfers, tf ); + jd->filetransfers = g_slist_prepend(jd->filetransfers, tf); /* query buddy's features and server's streaming proxies if neccessary */ - if( !tf->bud->features ) - jabber_iq_query_features( ic, bud->full_jid ); + if (!tf->bud->features) { + jabber_iq_query_features(ic, bud->full_jid); + } /* If <auto> is not set don't check for proxies */ - if( ( jd->have_streamhosts!=1 ) && ( jd->streamhosts==NULL ) && - ( strstr( set_getstr( &ic->acc->set, "proxy" ), "<auto>" ) != NULL ) ) { + if ((jd->have_streamhosts != 1) && (jd->streamhosts == NULL) && + (strstr(set_getstr(&ic->acc->set, "proxy"), "<auto>") != NULL)) { jd->have_streamhosts = 0; - jabber_iq_query_server( ic, server, XMLNS_DISCO_ITEMS ); - } else if ( jd->streamhosts!=NULL ) + jabber_iq_query_server(ic, server, XMLNS_DISCO_ITEMS); + } else if (jd->streamhosts != NULL) { jd->have_streamhosts = 1; + } - /* if we had to do a query, wait for the result. + /* if we had to do a query, wait for the result. * Otherwise fire away. */ - if( !tf->bud->features || jd->have_streamhosts!=1 ) - tf->disco_timeout = b_timeout_add( 500, jabber_si_waitfor_disco, tf ); - else - jabber_si_transfer_start( tf ); + if (!tf->bud->features || jd->have_streamhosts != 1) { + tf->disco_timeout = b_timeout_add(500, jabber_si_waitfor_disco, tf); + } else { + jabber_si_transfer_start(tf); + } } /* @@ -204,7 +216,7 @@ void jabber_si_transfer_request( struct im_connection *ic, file_transfer_t *ft, * We choose a stream type from the options given by the initiator. * Then we wait for imcb to call the accept or cancel callbacks. */ -int jabber_si_handle_request( struct im_connection *ic, struct xt_node *node, struct xt_node *sinode) +int jabber_si_handle_request(struct im_connection *ic, struct xt_node *node, struct xt_node *sinode) { struct xt_node *c, *d, *reply; char *sid, *ini_jid, *tgt_jid, *iq_id, *s, *ext_jid, *size_s; @@ -215,107 +227,100 @@ int jabber_si_handle_request( struct im_connection *ic, struct xt_node *node, st struct jabber_transfer *tf; struct jabber_data *jd = ic->proto_data; file_transfer_t *ft; - + /* All this means we expect something like this: ( I think ) * <iq from=... to=... id=...> - * <si id=id xmlns=si profile=ft> - * <file xmlns=ft/> - * <feature xmlns=feature> - * <x xmlns=xdata type=submit> - * <field var=stream-method> + * <si id=id xmlns=si profile=ft> + * <file xmlns=ft/> + * <feature xmlns=feature> + * <x xmlns=xdata type=submit> + * <field var=stream-method> * */ - if( !( ini_jid = xt_find_attr( node, "from" ) ) || - !( tgt_jid = xt_find_attr( node, "to" ) ) || - !( iq_id = xt_find_attr( node, "id" ) ) || - !( sid = xt_find_attr( sinode, "id" ) ) || - !( cmp = xt_find_attr( sinode, "profile" ) ) || - !( 0 == strcmp( cmp, XMLNS_FILETRANSFER ) ) || - !( d = xt_find_node( sinode->children, "file" ) ) || - !( cmp = xt_find_attr( d, "xmlns" ) ) || - !( 0 == strcmp( cmp, XMLNS_FILETRANSFER ) ) || - !( name = xt_find_attr( d, "name" ) ) || - !( size_s = xt_find_attr( d, "size" ) ) || - !( 1 == sscanf( size_s, "%zd", &size ) ) || - !( d = xt_find_node( sinode->children, "feature" ) ) || - !( cmp = xt_find_attr( d, "xmlns" ) ) || - !( 0 == strcmp( cmp, XMLNS_FEATURE ) ) || - !( d = xt_find_node( d->children, "x" ) ) || - !( cmp = xt_find_attr( d, "xmlns" ) ) || - !( 0 == strcmp( cmp, XMLNS_XDATA ) ) || - !( cmp = xt_find_attr( d, "type" ) ) || - !( 0 == strcmp( cmp, "form" ) ) || - !( d = xt_find_node( d->children, "field" ) ) || - !( cmp = xt_find_attr( d, "var" ) ) || - !( 0 == strcmp( cmp, "stream-method" ) ) ) - { - imcb_log( ic, "WARNING: Received incomplete Stream Initiation request" ); - } - else - { + if (!(ini_jid = xt_find_attr(node, "from")) || + !(tgt_jid = xt_find_attr(node, "to")) || + !(iq_id = xt_find_attr(node, "id")) || + !(sid = xt_find_attr(sinode, "id")) || + !(cmp = xt_find_attr(sinode, "profile")) || + !(0 == strcmp(cmp, XMLNS_FILETRANSFER)) || + !(d = xt_find_node(sinode->children, "file")) || + !(cmp = xt_find_attr(d, "xmlns")) || + !(0 == strcmp(cmp, XMLNS_FILETRANSFER)) || + !(name = xt_find_attr(d, "name")) || + !(size_s = xt_find_attr(d, "size")) || + !(1 == sscanf(size_s, "%zd", &size)) || + !(d = xt_find_node(sinode->children, "feature")) || + !(cmp = xt_find_attr(d, "xmlns")) || + !(0 == strcmp(cmp, XMLNS_FEATURE)) || + !(d = xt_find_node(d->children, "x")) || + !(cmp = xt_find_attr(d, "xmlns")) || + !(0 == strcmp(cmp, XMLNS_XDATA)) || + !(cmp = xt_find_attr(d, "type")) || + !(0 == strcmp(cmp, "form")) || + !(d = xt_find_node(d->children, "field")) || + !(cmp = xt_find_attr(d, "var")) || + !(0 == strcmp(cmp, "stream-method"))) { + imcb_log(ic, "WARNING: Received incomplete Stream Initiation request"); + } else { /* Check if we support one of the options */ c = d->children; - while( ( c = xt_find_node( c, "option" ) ) ) - if( ( d = xt_find_node( c->children, "value" ) ) && - ( d->text != NULL ) && - ( strcmp( d->text, XMLNS_BYTESTREAMS ) == 0 ) ) - { + while ((c = xt_find_node(c, "option"))) { + if ((d = xt_find_node(c->children, "value")) && + (d->text != NULL) && + (strcmp(d->text, XMLNS_BYTESTREAMS) == 0)) { requestok = TRUE; break; - } - else - { + } else { c = c->next; } + } - if ( !requestok ) - imcb_log( ic, "WARNING: Unsupported file transfer request from %s", ini_jid); + if (!requestok) { + imcb_log(ic, "WARNING: Unsupported file transfer request from %s", ini_jid); + } } - - if( requestok ) - { + + if (requestok) { /* Figure out who the transfer should come frome... */ ext_jid = ini_jid; - if( ( s = strchr( ini_jid, '/' ) ) ) - { - if( ( bud = jabber_buddy_by_jid( ic, ini_jid, GET_BUDDY_EXACT ) ) ) - { - bud->last_msg = time( NULL ); + if ((s = strchr(ini_jid, '/'))) { + if ((bud = jabber_buddy_by_jid(ic, ini_jid, GET_BUDDY_EXACT))) { + bud->last_msg = time(NULL); ext_jid = bud->ext_jid ? : bud->bare_jid; - } - else + } else { *s = 0; /* We need to generate a bare JID now. */ + } } - if( !( ft = imcb_file_send_start( ic, ext_jid, name, size ) ) ) - { - imcb_log( ic, "WARNING: Error handling transfer request from %s", ini_jid); + if (!(ft = imcb_file_send_start(ic, ext_jid, name, size))) { + imcb_log(ic, "WARNING: Error handling transfer request from %s", ini_jid); requestok = FALSE; } - if( s ) + if (s) { *s = '/'; + } } - - if( !requestok ) - { - reply = jabber_make_error_packet( node, "item-not-found", "cancel", NULL ); - if (!jabber_write_packet( ic, reply )) - imcb_log( ic, "WARNING: Error generating reply to file transfer request" ); - xt_free_node( reply ); + + if (!requestok) { + reply = jabber_make_error_packet(node, "item-not-found", "cancel", NULL); + if (!jabber_write_packet(ic, reply)) { + imcb_log(ic, "WARNING: Error generating reply to file transfer request"); + } + xt_free_node(reply); return XT_HANDLED; } /* Request is fine. */ - tf = g_new0( struct jabber_transfer, 1 ); + tf = g_new0(struct jabber_transfer, 1); - tf->ini_jid = g_strdup( ini_jid ); - tf->tgt_jid = g_strdup( tgt_jid ); - tf->iq_id = g_strdup( iq_id ); - tf->sid = g_strdup( sid ); + tf->ini_jid = g_strdup(ini_jid); + tf->tgt_jid = g_strdup(tgt_jid); + tf->iq_id = g_strdup(iq_id); + tf->sid = g_strdup(sid); tf->ic = ic; tf->ft = ft; tf->fd = -1; @@ -324,7 +329,7 @@ int jabber_si_handle_request( struct im_connection *ic, struct xt_node *node, st tf->ft->free = jabber_si_free_transfer; tf->ft->canceled = jabber_si_canceled; - jd->filetransfers = g_slist_prepend( jd->filetransfers, tf ); + jd->filetransfers = g_slist_prepend(jd->filetransfers, tf); return XT_HANDLED; } @@ -335,204 +340,203 @@ int jabber_si_handle_request( struct im_connection *ic, struct xt_node *node, st * In the next step, the initiator will send us a request for the given stream type. * (currently that can only be a SOCKS5 bytestream) */ -void jabber_si_answer_request( file_transfer_t *ft ) { +void jabber_si_answer_request(file_transfer_t *ft) +{ struct jabber_transfer *tf = ft->data; struct xt_node *node, *sinode, *reply; /* generate response, start with the SI tag */ - sinode = xt_new_node( "si", NULL, NULL ); - xt_add_attr( sinode, "xmlns", XMLNS_SI ); - xt_add_attr( sinode, "profile", XMLNS_FILETRANSFER ); - xt_add_attr( sinode, "id", tf->sid ); + sinode = xt_new_node("si", NULL, NULL); + xt_add_attr(sinode, "xmlns", XMLNS_SI); + xt_add_attr(sinode, "profile", XMLNS_FILETRANSFER); + xt_add_attr(sinode, "id", tf->sid); /* now the file tag */ - node = xt_new_node( "file", NULL, NULL ); - xt_add_attr( node, "xmlns", XMLNS_FILETRANSFER ); + node = xt_new_node("file", NULL, NULL); + xt_add_attr(node, "xmlns", XMLNS_FILETRANSFER); - xt_add_child( sinode, node ); + xt_add_child(sinode, node); /* and finally the feature tag */ - node = xt_new_node( "field", NULL, NULL ); - xt_add_attr( node, "var", "stream-method" ); - xt_add_attr( node, "type", "list-single" ); + node = xt_new_node("field", NULL, NULL); + xt_add_attr(node, "var", "stream-method"); + xt_add_attr(node, "type", "list-single"); /* Currently all we can do. One could also implement in-band (IBB) */ - xt_add_child( node, xt_new_node( "value", XMLNS_BYTESTREAMS, NULL ) ); + xt_add_child(node, xt_new_node("value", XMLNS_BYTESTREAMS, NULL)); - node = xt_new_node( "x", NULL, node ); - xt_add_attr( node, "xmlns", XMLNS_XDATA ); - xt_add_attr( node, "type", "submit" ); + node = xt_new_node("x", NULL, node); + xt_add_attr(node, "xmlns", XMLNS_XDATA); + xt_add_attr(node, "type", "submit"); - node = xt_new_node( "feature", NULL, node ); - xt_add_attr( node, "xmlns", XMLNS_FEATURE ); + node = xt_new_node("feature", NULL, node); + xt_add_attr(node, "xmlns", XMLNS_FEATURE); - xt_add_child( sinode, node ); + xt_add_child(sinode, node); - reply = jabber_make_packet( "iq", "result", tf->ini_jid, sinode ); - xt_add_attr( reply, "id", tf->iq_id ); - - if( !jabber_write_packet( tf->ic, reply ) ) - imcb_log( tf->ic, "WARNING: Error generating reply to file transfer request" ); - else + reply = jabber_make_packet("iq", "result", tf->ini_jid, sinode); + xt_add_attr(reply, "id", tf->iq_id); + + if (!jabber_write_packet(tf->ic, reply)) { + imcb_log(tf->ic, "WARNING: Error generating reply to file transfer request"); + } else { tf->accepted = TRUE; - xt_free_node( reply ); + } + xt_free_node(reply); } -static xt_status jabber_si_handle_response(struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) +static xt_status jabber_si_handle_response(struct im_connection *ic, struct xt_node *node, struct xt_node *orig) { struct xt_node *c, *d; char *ini_jid = NULL, *tgt_jid, *iq_id, *cmp; GSList *tflist; - struct jabber_transfer *tf=NULL; + struct jabber_transfer *tf = NULL; struct jabber_data *jd = ic->proto_data; - if( !( tgt_jid = xt_find_attr( node, "from" ) ) || - !( ini_jid = xt_find_attr( node, "to" ) ) ) - { - imcb_log( ic, "Invalid SI response from=%s to=%s", tgt_jid, ini_jid ); + if (!(tgt_jid = xt_find_attr(node, "from")) || + !(ini_jid = xt_find_attr(node, "to"))) { + imcb_log(ic, "Invalid SI response from=%s to=%s", tgt_jid, ini_jid); return XT_HANDLED; } - + /* All this means we expect something like this: ( I think ) * <iq from=... to=... id=...> - * <si xmlns=si> - * [ <file xmlns=ft/> ] <-- not neccessary - * <feature xmlns=feature> - * <x xmlns=xdata type=submit> - * <field var=stream-method> - * <value> + * <si xmlns=si> + * [ <file xmlns=ft/> ] <-- not neccessary + * <feature xmlns=feature> + * <x xmlns=xdata type=submit> + * <field var=stream-method> + * <value> */ - if( !( tgt_jid = xt_find_attr( node, "from" ) ) || - !( ini_jid = xt_find_attr( node, "to" ) ) || - !( iq_id = xt_find_attr( node, "id" ) ) || - !( c = xt_find_node( node->children, "si" ) ) || - !( cmp = xt_find_attr( c, "xmlns" ) ) || - !( strcmp( cmp, XMLNS_SI ) == 0 ) || - !( d = xt_find_node( c->children, "feature" ) ) || - !( cmp = xt_find_attr( d, "xmlns" ) ) || - !( strcmp( cmp, XMLNS_FEATURE ) == 0 ) || - !( d = xt_find_node( d->children, "x" ) ) || - !( cmp = xt_find_attr( d, "xmlns" ) ) || - !( strcmp( cmp, XMLNS_XDATA ) == 0 ) || - !( cmp = xt_find_attr( d, "type" ) ) || - !( strcmp( cmp, "submit" ) == 0 ) || - !( d = xt_find_node( d->children, "field" ) ) || - !( cmp = xt_find_attr( d, "var" ) ) || - !( strcmp( cmp, "stream-method" ) == 0 ) || - !( d = xt_find_node( d->children, "value" ) ) ) - { - imcb_log( ic, "WARNING: Received incomplete Stream Initiation response" ); + if (!(tgt_jid = xt_find_attr(node, "from")) || + !(ini_jid = xt_find_attr(node, "to")) || + !(iq_id = xt_find_attr(node, "id")) || + !(c = xt_find_node(node->children, "si")) || + !(cmp = xt_find_attr(c, "xmlns")) || + !(strcmp(cmp, XMLNS_SI) == 0) || + !(d = xt_find_node(c->children, "feature")) || + !(cmp = xt_find_attr(d, "xmlns")) || + !(strcmp(cmp, XMLNS_FEATURE) == 0) || + !(d = xt_find_node(d->children, "x")) || + !(cmp = xt_find_attr(d, "xmlns")) || + !(strcmp(cmp, XMLNS_XDATA) == 0) || + !(cmp = xt_find_attr(d, "type")) || + !(strcmp(cmp, "submit") == 0) || + !(d = xt_find_node(d->children, "field")) || + !(cmp = xt_find_attr(d, "var")) || + !(strcmp(cmp, "stream-method") == 0) || + !(d = xt_find_node(d->children, "value"))) { + imcb_log(ic, "WARNING: Received incomplete Stream Initiation response"); return XT_HANDLED; } - if( !( strcmp( d->text, XMLNS_BYTESTREAMS ) == 0 ) ) { + if (!(strcmp(d->text, XMLNS_BYTESTREAMS) == 0)) { /* since we should only have advertised what we can do and the peer should * only have chosen what we offered, this should never happen */ - imcb_log( ic, "WARNING: Received invalid Stream Initiation response, method %s", d->text ); - + imcb_log(ic, "WARNING: Received invalid Stream Initiation response, method %s", d->text); + return XT_HANDLED; } - + /* Let's see if we can find out what this bytestream should be for... */ - for( tflist = jd->filetransfers ; tflist; tflist = g_slist_next(tflist) ) - { + for (tflist = jd->filetransfers; tflist; tflist = g_slist_next(tflist)) { struct jabber_transfer *tft = tflist->data; - if( ( strcmp( tft->iq_id, iq_id ) == 0 ) ) - { - tf = tft; + if ((strcmp(tft->iq_id, iq_id) == 0)) { + tf = tft; break; } } - if (!tf) - { - imcb_log( ic, "WARNING: Received bytestream request from %s that doesn't match an SI request", ini_jid ); + if (!tf) { + imcb_log(ic, "WARNING: Received bytestream request from %s that doesn't match an SI request", ini_jid); return XT_HANDLED; } - tf->ini_jid = g_strdup( ini_jid ); - tf->tgt_jid = g_strdup( tgt_jid ); + tf->ini_jid = g_strdup(ini_jid); + tf->tgt_jid = g_strdup(tgt_jid); - imcb_log( ic, "File %s: %s accepted the transfer!", tf->ft->file_name, tgt_jid ); + imcb_log(ic, "File %s: %s accepted the transfer!", tf->ft->file_name, tgt_jid); - jabber_bs_send_start( tf ); + jabber_bs_send_start(tf); return XT_HANDLED; } -int jabber_si_send_request(struct im_connection *ic, char *who, struct jabber_transfer *tf ) +int jabber_si_send_request(struct im_connection *ic, char *who, struct jabber_transfer *tf) { struct xt_node *node, *sinode; struct jabber_buddy *bud; /* who knows how many bits the future holds :) */ - char filesizestr[ 1 + ( int ) ( 0.301029995663981198f * sizeof( size_t ) * 8 ) ]; + char filesizestr[ 1 + ( int ) (0.301029995663981198f * sizeof(size_t) * 8) ]; - const char *methods[] = - { + const char *methods[] = + { XMLNS_BYTESTREAMS, //XMLNS_IBB, - NULL + NULL }; const char **m; char *s; /* Maybe we should hash this? */ - tf->sid = g_strdup_printf( "BitlBeeJabberSID%d", tf->ft->local_id ); - - if( ( s = strchr( who, '=' ) ) && jabber_chat_by_jid( ic, s + 1 ) ) - bud = jabber_buddy_by_ext_jid( ic, who, 0 ); - else - bud = jabber_buddy_by_jid( ic, who, 0 ); + tf->sid = g_strdup_printf("BitlBeeJabberSID%d", tf->ft->local_id); + + if ((s = strchr(who, '=')) && jabber_chat_by_jid(ic, s + 1)) { + bud = jabber_buddy_by_ext_jid(ic, who, 0); + } else { + bud = jabber_buddy_by_jid(ic, who, 0); + } /* start with the SI tag */ - sinode = xt_new_node( "si", NULL, NULL ); - xt_add_attr( sinode, "xmlns", XMLNS_SI ); - xt_add_attr( sinode, "profile", XMLNS_FILETRANSFER ); - xt_add_attr( sinode, "id", tf->sid ); + sinode = xt_new_node("si", NULL, NULL); + xt_add_attr(sinode, "xmlns", XMLNS_SI); + xt_add_attr(sinode, "profile", XMLNS_FILETRANSFER); + xt_add_attr(sinode, "id", tf->sid); -/* if( mimetype ) - xt_add_attr( node, "mime-type", mimetype ); */ +/* if( mimetype ) + xt_add_attr( node, "mime-type", mimetype ); */ /* now the file tag */ /* if( desc ) - node = xt_new_node( "desc", descr, NULL ); */ - node = xt_new_node( "range", NULL, NULL ); - - sprintf( filesizestr, "%zd", tf->ft->file_size ); - node = xt_new_node( "file", NULL, node ); - xt_add_attr( node, "xmlns", XMLNS_FILETRANSFER ); - xt_add_attr( node, "name", tf->ft->file_name ); - xt_add_attr( node, "size", filesizestr ); + node = xt_new_node( "desc", descr, NULL ); */ + node = xt_new_node("range", NULL, NULL); + + sprintf(filesizestr, "%zd", tf->ft->file_size); + node = xt_new_node("file", NULL, node); + xt_add_attr(node, "xmlns", XMLNS_FILETRANSFER); + xt_add_attr(node, "name", tf->ft->file_name); + xt_add_attr(node, "size", filesizestr); /* if (hash) - xt_add_attr( node, "hash", hash ); - if (date) - xt_add_attr( node, "date", date ); */ + xt_add_attr( node, "hash", hash ); + if (date) + xt_add_attr( node, "date", date ); */ - xt_add_child( sinode, node ); + xt_add_child(sinode, node); /* and finally the feature tag */ - node = xt_new_node( "field", NULL, NULL ); - xt_add_attr( node, "var", "stream-method" ); - xt_add_attr( node, "type", "list-single" ); + node = xt_new_node("field", NULL, NULL); + xt_add_attr(node, "var", "stream-method"); + xt_add_attr(node, "type", "list-single"); - for ( m = methods ; *m ; m ++ ) - xt_add_child( node, xt_new_node( "option", NULL, xt_new_node( "value", (char *)*m, NULL ) ) ); + for (m = methods; *m; m++) { + xt_add_child(node, xt_new_node("option", NULL, xt_new_node("value", (char *) *m, NULL))); + } - node = xt_new_node( "x", NULL, node ); - xt_add_attr( node, "xmlns", XMLNS_XDATA ); - xt_add_attr( node, "type", "form" ); + node = xt_new_node("x", NULL, node); + xt_add_attr(node, "xmlns", XMLNS_XDATA); + xt_add_attr(node, "type", "form"); - node = xt_new_node( "feature", NULL, node ); - xt_add_attr( node, "xmlns", XMLNS_FEATURE ); + node = xt_new_node("feature", NULL, node); + xt_add_attr(node, "xmlns", XMLNS_FEATURE); - xt_add_child( sinode, node ); + xt_add_child(sinode, node); /* and we are there... */ - node = jabber_make_packet( "iq", "set", bud ? bud->full_jid : who, sinode ); - jabber_cache_add( ic, node, jabber_si_handle_response ); - tf->iq_id = g_strdup( xt_find_attr( node, "id" ) ); - - return jabber_write_packet( ic, node ); + node = jabber_make_packet("iq", "set", bud ? bud->full_jid : who, sinode); + jabber_cache_add(ic, node, jabber_si_handle_response); + tf->iq_id = g_strdup(xt_find_attr(node, "id")); + + return jabber_write_packet(ic, node); } |