- Timestamp:
- 2007-12-04T00:53:04Z (17 years ago)
- Branches:
- master
- Children:
- 08135df
- Parents:
- 2c2df7d (diff), dce3903 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- protocols
- Files:
-
- 1 added
- 1 deleted
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
protocols/ft.h
r2c2df7d rfa30fa5 27 27 #define _FT_H 28 28 29 /* 30 * One buffer is needed for each transfer. The receiver stores a message 31 * in it and gives it to the sender. The sender will stall the receiver 32 * till the buffer has been sent out. 33 */ 34 #define FT_BUFFER_SIZE 2048 35 29 36 typedef enum { 30 37 FT_STATUS_LISTENING = 1, 31 FT_STATUS_TRANSFER ING = 2,38 FT_STATUS_TRANSFERRING = 2, 32 39 FT_STATUS_FINISHED = 4, 33 FT_STATUS_CANCELED = 8 40 FT_STATUS_CANCELED = 8, 41 FT_STATUS_CONNECTING = 16 34 42 } file_status_t; 35 43 … … 61 69 */ 62 70 typedef struct file_transfer { 71 72 /* Are we sending something? */ 73 int sending; 74 63 75 /* 64 76 * The current status of this file transfer. … … 126 138 127 139 /* 128 * If set, called when the transfer queue is running empty and 129 * more data can be added. 140 * called by the sending side to indicate that it is writable. 141 * The callee should check if data is available and call the 142 * function(as seen below) if that is the case. 130 143 */ 131 void (*out_of_data) ( struct file_transfer *file ); 144 gboolean (*write_request) ( struct file_transfer *file ); 145 146 /* 147 * When sending files, protocols register this function to receive data. 148 * This should only be called once after write_request is called. The caller 149 * should not read more data until write_request is called again. This technique 150 * avoids buffering. 151 */ 152 gboolean (*write) (struct file_transfer *file, char *buffer, unsigned int len ); 153 154 /* The send buffer associated with this transfer. 155 * Since receivers always wait for a write_request call one is enough. 156 */ 157 char buffer[FT_BUFFER_SIZE]; 132 158 133 159 } file_transfer_t; … … 144 170 void imcb_file_canceled( file_transfer_t *file, char *reason ); 145 171 146 /* 147 * The given buffer is queued for transfer and MUST NOT be freed by the caller. 148 * When the method returns false the caller should not invoke this method again 149 * until out_of_data has been called. 150 */ 151 gboolean imcb_file_write( file_transfer_t *file, gpointer data, size_t data_size ); 152 172 gboolean imcb_file_recv_start( file_transfer_t *ft ); 153 173 #endif -
protocols/jabber/Makefile
r2c2df7d rfa30fa5 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 xmltree.o si.o s tream.o12 objects = conference.o io.o iq.o jabber.o jabber_util.o message.o presence.o sasl.o xmltree.o si.o s5bytestream.o 13 13 14 14 CFLAGS += -Wall -
protocols/jabber/iq.c
r2c2df7d rfa30fa5 168 168 { 169 169 /* Bytestream Request (stage 2 of file transfer) */ 170 return jabber_bs_re quest( ic, node, c );170 return jabber_bs_recv_request( ic, node, c ); 171 171 } else 172 172 { -
protocols/jabber/jabber.c
r2c2df7d rfa30fa5 502 502 ret->send_typing = jabber_send_typing; 503 503 ret->handle_cmp = g_strcasecmp; 504 ret->transfer_request = jabber_si_transfer_request; 504 505 505 506 register_protocol( ret ); -
protocols/jabber/jabber.h
r2c2df7d rfa30fa5 146 146 147 147 size_t bytesread, byteswritten; 148 int receiver_overflow;149 148 int fd; 149 struct sockaddr_storage saddr; 150 150 }; 151 151 … … 201 201 202 202 /* si.c */ 203 int jabber_si_handle_request( struct im_connection *ic, struct xt_node *node, struct xt_node *sinode); 204 205 /* stream.c */ 206 int jabber_bs_request( struct im_connection *ic, struct xt_node *node, struct xt_node *qnode); 203 int jabber_si_handle_request( struct im_connection *ic, struct xt_node *node, struct xt_node *sinode ); 204 void jabber_si_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who ); 205 void jabber_si_free_transfer( file_transfer_t *ft); 206 207 /* s5bytestream.c */ 208 int jabber_bs_recv_request( struct im_connection *ic, struct xt_node *node, struct xt_node *qnode); 209 gboolean jabber_bs_send_start( struct jabber_transfer *tf ); 210 gboolean jabber_bs_send_write( file_transfer_t *ft, char *buffer, unsigned int len ); 207 211 208 212 /* message.c */ -
protocols/jabber/jabber_util.c
r2c2df7d rfa30fa5 265 265 new = g_new( char, len + 1 ); 266 266 for( i = 0; i < len; i ++ ) 267 { 268 /* don't normalize the resource */ 269 if( orig[i] == '/' ) 270 break; 267 271 new[i] = tolower( orig[i] ); 272 } 273 for( ; i < len; i ++ ) 274 new[i] = orig[i]; 268 275 269 276 new[i] = 0; -
protocols/jabber/si.c
r2c2df7d rfa30fa5 26 26 27 27 void jabber_si_answer_request( file_transfer_t *ft ); 28 29 /* imcb callback */ 28 int jabber_si_send_request(struct im_connection *ic, char *who, struct jabber_transfer *tf ); 29 30 /* file_transfer free() callback */ 30 31 void jabber_si_free_transfer( file_transfer_t *ft) 31 32 { … … 50 51 } 51 52 52 /* imcbcallback */53 /* file_transfer finished() callback */ 53 54 void jabber_si_finished( file_transfer_t *ft ) 54 55 { … … 58 59 } 59 60 60 /* imcbcallback */61 /* file_transfer canceled() callback */ 61 62 void jabber_si_canceled( file_transfer_t *ft, char *reason ) 62 63 { … … 76 77 xt_free_node( reply ); 77 78 79 } 80 81 void jabber_si_transfer_request( struct im_connection *ic, file_transfer_t *ft, char *who ) 82 { 83 struct jabber_transfer *tf; 84 struct jabber_data *jd = ic->proto_data; 85 86 imcb_log( ic, "Trying to send %s(%zd bytes) to %s", ft->file_name, ft->file_size, who ); 87 88 tf = g_new0( struct jabber_transfer, 1 ); 89 90 tf->ic = ic; 91 tf->ft = ft; 92 tf->ft->data = tf; 93 tf->ft->free = jabber_si_free_transfer; 94 tf->ft->finished = jabber_si_finished; 95 ft->write = jabber_bs_send_write; 96 97 jd->filetransfers = g_slist_prepend( jd->filetransfers, tf ); 98 99 jabber_si_send_request( ic, who, tf ); 100 101 imcb_file_recv_start( ft ); 78 102 } 79 103 … … 136 160 break; 137 161 } 162 163 if ( !requestok ) 164 imcb_log( ic, "WARNING: Unsupported file transfer request from %s", ini_jid); 138 165 } 139 166 … … 160 187 161 188 *s = '/'; 162 } else 163 imcb_log( ic, "WARNING: Unsupported file transfer request from %s", ini_jid); 189 } 164 190 165 191 if ( !requestok ) … … 198 224 199 225 /* 200 * imc bcalled the accept callback which probably means that the user accepted this file transfer.226 * imc called the accept callback which probably means that the user accepted this file transfer. 201 227 * We send our response to the initiator. 202 228 * In the next step, the initiator will send us a request for the given stream type. … … 245 271 xt_free_node( reply ); 246 272 } 273 274 static xt_status jabber_si_handle_response(struct im_connection *ic, struct xt_node *node, struct xt_node *orig ) 275 { 276 struct xt_node *c, *d; 277 char *ini_jid, *tgt_jid, *iq_id; 278 GSList *tflist; 279 struct jabber_transfer *tf=NULL; 280 struct jabber_data *jd = ic->proto_data; 281 282 if( !( tgt_jid = xt_find_attr( node, "from" ) ) || 283 !( ini_jid = xt_find_attr( node, "to" ) ) ) 284 { 285 imcb_log( ic, "Invalid SI response from=%s to=%s", tgt_jid, ini_jid ); 286 return XT_HANDLED; 287 } 288 289 /* All this means we expect something like this: ( I think ) 290 * <iq from=... to=... id=...> 291 * <si xmlns=si> 292 * [ <file xmlns=ft/> ] <-- not neccessary 293 * <feature xmlns=feature> 294 * <x xmlns=xdata type=submit> 295 * <field var=stream-method> 296 * <value> 297 */ 298 if( !( tgt_jid = xt_find_attr( node, "from" ) ) || 299 !( ini_jid = xt_find_attr( node, "to" ) ) || 300 !( iq_id = xt_find_attr( node, "id" ) ) || 301 !( c = xt_find_node( node->children, "si" ) ) || 302 !( strcmp( xt_find_attr( c, "xmlns" ), XMLNS_SI ) == 0 ) || 303 /* !( d = xt_find_node( c->children, "file" ) ) || 304 !( strcmp( xt_find_attr( d, "xmlns" ), XMLNS_FILETRANSFER ) == 0 ) || */ 305 !( d = xt_find_node( c->children, "feature" ) ) || 306 !( strcmp( xt_find_attr( d, "xmlns" ), XMLNS_FEATURE ) == 0 ) || 307 !( d = xt_find_node( d->children, "x" ) ) || 308 !( strcmp( xt_find_attr( d, "xmlns" ), XMLNS_XDATA ) == 0 ) || 309 !( strcmp( xt_find_attr( d, "type" ), "submit" ) == 0 ) || 310 !( d = xt_find_node( d->children, "field" ) ) || 311 !( strcmp( xt_find_attr( d, "var" ), "stream-method" ) == 0 ) || 312 !( d = xt_find_node( d->children, "value" ) ) ) 313 { 314 imcb_log( ic, "WARNING: Received incomplete Stream Initiation response" ); 315 return XT_HANDLED; 316 } 317 318 if( !( strcmp( d->text, XMLNS_BYTESTREAMS ) == 0 ) ) { 319 /* since we should only have advertised what we can do and the peer should 320 * only have chosen what we offered, this should never happen */ 321 imcb_log( ic, "WARNING: Received invalid Stream Initiation response, method %s", d->text ); 322 323 return XT_HANDLED; 324 } 325 326 /* Let's see if we can find out what this bytestream should be for... */ 327 328 for( tflist = jd->filetransfers ; tflist; tflist = g_slist_next(tflist) ) 329 { 330 struct jabber_transfer *tft = tflist->data; 331 if( ( strcmp( tft->iq_id, iq_id ) == 0 ) ) 332 { 333 tf = tft; 334 break; 335 } 336 } 337 338 if (!tf) 339 { 340 imcb_log( ic, "WARNING: Received bytestream request from %s that doesn't match an SI request", ini_jid ); 341 return XT_HANDLED; 342 } 343 344 tf->ini_jid = g_strdup( ini_jid ); 345 tf->tgt_jid = g_strdup( tgt_jid ); 346 347 imcb_log( ic, "File %s: %s accepted the transfer!", tf->ft->file_name, tgt_jid ); 348 349 jabber_bs_send_start( tf ); 350 351 return XT_HANDLED; 352 } 353 354 int jabber_si_send_request(struct im_connection *ic, char *who, struct jabber_transfer *tf ) 355 { 356 struct xt_node *node, *sinode; 357 struct jabber_buddy *bud; 358 359 /* who knows how many bits the future holds :) */ 360 char filesizestr[ 1 + ( int ) ( 0.301029995663981198f * sizeof( size_t ) * 8 ) ]; 361 362 const char *methods[] = 363 { 364 XMLNS_BYTESTREAMS, 365 //XMLNS_IBB, 366 NULL 367 }; 368 const char **m; 369 char *s; 370 371 /* Maybe we should hash this? */ 372 tf->sid = g_strdup_printf( "BitlBeeJabberSID%d", tf->ft->local_id ); 373 374 if( ( s = strchr( who, '=' ) ) && jabber_chat_by_name( ic, s + 1 ) ) 375 bud = jabber_buddy_by_ext_jid( ic, who, 0 ); 376 else 377 bud = jabber_buddy_by_jid( ic, who, 0 ); 378 379 /* start with the SI tag */ 380 sinode = xt_new_node( "si", NULL, NULL ); 381 xt_add_attr( sinode, "xmlns", XMLNS_SI ); 382 xt_add_attr( sinode, "profile", XMLNS_FILETRANSFER ); 383 xt_add_attr( sinode, "id", tf->sid ); 384 385 /* if( mimetype ) 386 xt_add_attr( node, "mime-type", mimetype ); */ 387 388 /* now the file tag */ 389 /* if( desc ) 390 node = xt_new_node( "desc", descr, NULL ); */ 391 node = xt_new_node( "range", NULL, NULL ); 392 393 sprintf( filesizestr, "%zd", tf->ft->file_size ); 394 node = xt_new_node( "file", NULL, node ); 395 xt_add_attr( node, "xmlns", XMLNS_FILETRANSFER ); 396 xt_add_attr( node, "name", tf->ft->file_name ); 397 xt_add_attr( node, "size", filesizestr ); 398 /* if (hash) 399 xt_add_attr( node, "hash", hash ); 400 if (date) 401 xt_add_attr( node, "date", date ); */ 402 403 xt_add_child( sinode, node ); 404 405 /* and finally the feature tag */ 406 node = xt_new_node( "field", NULL, NULL ); 407 xt_add_attr( node, "var", "stream-method" ); 408 xt_add_attr( node, "type", "list-single" ); 409 410 for ( m = methods ; *m ; m ++ ) 411 xt_add_child( node, xt_new_node( "option", NULL, xt_new_node( "value", (char *)*m, NULL ) ) ); 412 413 node = xt_new_node( "x", NULL, node ); 414 xt_add_attr( node, "xmlns", XMLNS_XDATA ); 415 xt_add_attr( node, "type", "form" ); 416 417 node = xt_new_node( "feature", NULL, node ); 418 xt_add_attr( node, "xmlns", XMLNS_FEATURE ); 419 420 xt_add_child( sinode, node ); 421 422 /* and we are there... */ 423 node = jabber_make_packet( "iq", "set", bud ? bud->full_jid : who, sinode ); 424 jabber_cache_add( ic, node, jabber_si_handle_response ); 425 tf->iq_id = g_strdup( xt_find_attr( node, "id" ) ); 426 427 return jabber_write_packet( ic, node ); 428 } -
protocols/nogaim.h
r2c2df7d rfa30fa5 229 229 * - Most protocols will just want to set this to g_strcasecmp().*/ 230 230 int (* handle_cmp) (const char *who1, const char *who2); 231 232 /* Incoming transfer request */ 233 void (* transfer_request) (struct im_connection *, file_transfer_t *ft, char *handle ); 231 234 }; 232 235
Note: See TracChangeset
for help on using the changeset viewer.