comparison src/protocols/oscar/oscar.c @ 4617:858979ab3867

[gaim-migrate @ 4908] Big Changes: -Rewrote some of the perl stuff so perl scripts can change a few of their parameters -Receiving a file with AIM over oscar works pretty well Now, the "nitty gritty": Very minor change to prefs.c: In the plugins details tab, I changed "URL" to "Web Site." I was just going to fix the tabbing, but silvestrij suggested changing it to "Web site," and I thought that sounded good. I think it fits better, too. I dunno, maybe that's just me. "Get Capabilities" has stopped working for some reason. I'm just going to blame AOL. It's really not important anyway, and some people wanted it taken off. It is now #ifdef 0'ed out. I'll remove it completely if it continues to no longer function. I took out a few plugin_event calls from oscar.c and put them in core code. "event_error" should be, uh, "evented" when there is an error signing on. Hopefully no one was using this. It's really pretty useless. The parameter is now the reason for not being able to connect rather than the archaic toc error code. I screwed around with how perl functions are called some. There was way the hell too much malloc'ing going on here. I think all in all it's an improvement, though I'm still not a big fan of how changes to parameters propagate to the actual memory. I really think it would be nice if the perl stuff was made into a C plugin. It's just so much cleaner. Especially if someone wanted to write, say, a python or tcl interpreter. That's how xchat2 does it. I just think that would be really slick. Like butter. Or ice. Very unlike Velcro. I added a "Change Password" Protocol Action for ICQ over oscar. This was really pretty easy. I'd like to thank my housemate Andrew for complaining a lot that having to use Windows ICQ to change his password was a pain. I rewrote a lot of the oscar file transfer stuff to use Christian's new xfer interface. This involved moving a few functions from ft.c to im.c, where they belong. I also removed all the #if 0'ed getfile functions. I'll be rewritting them soonish. Receiving a file should work perfectly, aside from maybe a small memleak when stuff is canceled. Sending a file is currently disabled. No ETA on when I'll have that working. I renamed pretty much all of the functions in im.c so they have kind of a scheme now. They should all be aim_im_bleh, since "im" is the family name. There comes a time when you must break the crap out of any clients that might be using libfaim in order to make stuff cleaner. Maybe. I got rid of the snac destructor stuff for now. I'll probably add it back later. I wasn't entirely comfortable with how it was done. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Wed, 26 Feb 2003 05:01:37 +0000
parents 5fcb44d771d2
children a964972cb361
comparison
equal deleted inserted replaced
4616:767093a2ddaf 4617:858979ab3867
23 #ifdef HAVE_CONFIG_H 23 #ifdef HAVE_CONFIG_H
24 #include <config.h> 24 #include <config.h>
25 #endif 25 #endif
26 26
27 #include <sys/types.h> 27 #include <sys/types.h>
28 /*this must happen before sys/socket.h or freebsd won't compile*/ 28 /* this must happen before sys/socket.h or freebsd won't compile */
29 29
30 #ifndef _WIN32 30 #ifndef _WIN32
31 #include <netdb.h> 31 #include <netdb.h>
32 #include <netinet/in.h> 32 #include <netinet/in.h>
33 #include <arpa/inet.h> 33 #include <arpa/inet.h>
89 /* For win32 compatability */ 89 /* For win32 compatability */
90 G_MODULE_IMPORT GSList *connections; 90 G_MODULE_IMPORT GSList *connections;
91 G_MODULE_IMPORT int report_idle; 91 G_MODULE_IMPORT int report_idle;
92 G_MODULE_IMPORT GSList *groups; 92 G_MODULE_IMPORT GSList *groups;
93 93
94 static int caps_aim = AIM_CAPS_CHAT | AIM_CAPS_BUDDYICON | 94 static int caps_aim = AIM_CAPS_CHAT | AIM_CAPS_BUDDYICON | AIM_CAPS_IMIMAGE | AIM_CAPS_SENDFILE;
95 AIM_CAPS_IMIMAGE | AIM_CAPS_SENDFILE;
96 95
97 /* Set AIM caps, because Gaim can still do them over ICQ and 96 /* Set AIM caps, because Gaim can still do them over ICQ and
98 * Winicq doesn't mind. */ 97 * Winicq doesn't mind. */
99 static int caps_icq = AIM_CAPS_BUDDYICON | AIM_CAPS_IMIMAGE | AIM_CAPS_SENDFILE; 98 static int caps_icq = AIM_CAPS_BUDDYICON | AIM_CAPS_IMIMAGE | AIM_CAPS_SENDFILE;
100 /* static int caps_icq = AIM_CAPS_ICQ; */ 99 /* static int caps_icq = AIM_CAPS_ICQ; */
176 char *sn; 175 char *sn;
177 char ip[64]; 176 char ip[64];
178 fu8_t cookie[8]; 177 fu8_t cookie[8];
179 }; 178 };
180 179
181 #if 0 180 /* BBB */
182 struct oscar_file_transfer { 181 struct oscar_xfer_data {
183 enum { OFT_SENDFILE_IN, OFT_SENDFILE_OUT } type; 182 fu8_t cookie[8];
183 fu16_t modtime;
184 fu16_t checksum;
184 aim_conn_t *conn; 185 aim_conn_t *conn;
185 struct file_transfer *xfer; 186 struct gaim_xfer *xfer;
186 char *sn; 187 struct gaim_connection *gc;
187 char ip[64];
188 fu16_t port;
189 fu8_t cookie[8];
190 int totsize;
191 int filesdone;
192 int totfiles;
193 int watcher;
194 }; 188 };
195 #endif
196 189
197 struct icon_req { 190 struct icon_req {
198 char *user; 191 char *user;
199 time_t timestamp; 192 time_t timestamp;
200 unsigned long length; 193 unsigned long length;
286 } 279 }
287 280
288 return c; 281 return c;
289 } 282 }
290 283
284 /* XXX - I really don't like forward declarations */
285 static void oscar_callback(gpointer data, gint source, GaimInputCondition condition);
286
287 /* BBB */
288 /*
289 * This little area in oscar.c is the nexus of file transfer code,
290 * so I wrote a little explanation of what happens. I am such a
291 * ninja.
292 *
293 * The series of events for a file send is:
294 * -Create xfer and call gaim_xfer_request (this happens in oscar_ask_sendfile)
295 * -User chooses a file and oscar_xfer_init is called. It establishs a
296 * listening socket, then asks the remote user to connect to us (and
297 * gives them the file name, port, IP, etc.)
298 * -They connect to us and we send them an AIM_CB_OFT_PROMPT (this happens
299 * in oscar_sendfile_established)
300 * -They send us an AIM_CB_OFT_ACK and then we start sending data
301 * -When we finish, they send us an AIM_CB_OFT_DONE and they close the
302 * connection.
303 * -We get drunk because file transfer kicks ass.
304 *
305 * The series of events for a file receive is:
306 * -Create xfer and call gaim_xfer request (this happens in incomingim_chan2)
307 * -Gaim user selects file to name and location to save file to and
308 * oscar_xfer_init is called
309 * -It connects to the remote user using the IP they gave us earlier
310 * -After connecting, they send us an AIM_CB_OFT_PROMPT. In reply, we send
311 * them an AIM_CB_OFT_ACK.
312 * -They begin to send us lots of raw data.
313 * -When they finish sending data we send an AIM_CB_OFT_DONE and then close
314 * the connectionn.
315 */
316 static void oscar_sendfile_connected(gpointer data, gint source, GaimInputCondition condition);
317 static int oscar_sendfile_established(aim_session_t *, aim_frame_t *, ...);
318 static int oscar_sendfile_prompt(aim_session_t *, aim_frame_t *, ...);
319 static int oscar_sendfile_ack(aim_session_t *, aim_frame_t *, ...);
320 static int oscar_sendfile_done(aim_session_t *, aim_frame_t *, ...);
321
322 /* XXX - This function is pretty ugly */
323 static void
324 oscar_xfer_init(struct gaim_xfer *xfer)
325 {
326 struct gaim_connection *gc;
327 struct oscar_data *od;
328 struct oscar_xfer_data *xfer_data;
329 debug_printf("in oscar_xfer_init\n");
330
331 if (!(xfer_data = xfer->data))
332 return;
333 if (!(gc = xfer_data->gc))
334 return;
335 if (!(od = gc->proto_data))
336 return;
337
338 if (gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) {
339 xfer->filename = g_path_get_basename(xfer->local_filename);
340 if (xfer->local_port) {
341 int i;
342 char ip[4];
343 gchar **ipsplit = g_strsplit(xfer->local_ip, ".", 4);
344 for (i=0; ipsplit[i]; i++)
345 ip[i] = atoi(ipsplit[i]);
346 g_strfreev(ipsplit);
347 xfer_data->conn = aim_sendfile_listen(od->sess, xfer_data->cookie, ip, xfer->local_port);
348 if (!xfer_data->conn) {
349 /*
350 * Try a few random ports. Maybe we need a
351 * way to tell libfaim to listen for multiple
352 * connections on one listener socket.
353 */
354 for (i=0; (i<5 && !xfer_data->conn); i++) {
355 xfer->local_port = (rand() % (65535-1024)) + 1024;
356 xfer_data->conn = aim_sendfile_listen(od->sess, xfer_data->cookie, ip, xfer->local_port);
357 }
358 }
359 if (xfer_data->conn) {
360 xfer->watcher = gaim_input_add(xfer_data->conn->fd, GAIM_INPUT_READ, oscar_callback, xfer_data->conn);
361 aim_im_sendch2_sendfile_ask(od->sess, xfer_data->cookie, xfer->who, ip, xfer->local_port, xfer->filename, 1, xfer->size);
362 aim_conn_addhandler(od->sess, xfer_data->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_ESTABLISHED, oscar_sendfile_established, 0);
363 /* Calculate a checksum thingy. This is ugly.
364 if ((fd = open(xfer->local_filename, O_RDONLY))) {
365 int bytes;
366 char buf[1024];
367 xfer_data->checksum = 0xffff0000;
368 while ((bytes = aim_recv(fd, buf, 1024)) > 0)
369 xfer_data->checksum = aim_oft_checksum(buf, bytes, xfer_data->checksum);
370 close(fd);
371 } */
372 } else {
373 do_error_dialog(_("File Transfer Aborted"), _("Unable to establish listener socket."), GAIM_ERROR);
374 /* XXX - The below line causes a crash because the transfer is canceled before the "Ok" callback on the file selection thing exists, I think */
375 /* gaim_xfer_cancel(xfer); */
376 }
377 } else {
378 /* gaim_xfer_cancel(xfer); */
379 }
380 } else if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) {
381 if (xfer->remote_ip && xfer->remote_port) {
382 xfer_data->conn = aim_newconn(od->sess, AIM_CONN_TYPE_RENDEZVOUS, NULL);
383 if (xfer_data->conn) {
384 xfer_data->conn->subtype = AIM_CONN_SUBTYPE_OFT_SENDFILE;
385 aim_conn_addhandler(od->sess, xfer_data->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_PROMPT, oscar_sendfile_prompt, 0);
386 xfer_data->conn->fd = xfer->fd = proxy_connect(xfer->remote_ip, xfer->remote_port, oscar_sendfile_connected, xfer);
387 if (xfer->fd == -1) {
388 do_error_dialog(_("File Transfer Aborted"), _("Unable to establish file descriptor."), GAIM_ERROR);
389 /* gaim_xfer_cancel? */
390 }
391 } else {
392 do_error_dialog(_("File Transfer Aborted"), _("Unable to create new connection."), GAIM_ERROR);
393 /* gaim_xfer_cancel? */
394 /* Try a different port? Ask them to connect to us? */
395 }
396 } else {
397 /* I have a feeling this would crash */
398 /* gaim_xfer_cancel(xfer); */
399 }
400 }
401 }
402
403 static void
404 oscar_xfer_start(struct gaim_xfer *xfer)
405 {
406 /* struct gaim_connection *gc;
407 struct oscar_data *od;
408 struct oscar_xfer_data *xfer_data;
409
410 if (!(xfer_data = xfer->data))
411 return;
412 if (!(gc = xfer_data->gc))
413 return;
414 if (!(od = gc->proto_data))
415 return;
416
417 od = xfer_data->od;
418 */
419 debug_printf("AAA - in oscar_xfer_start\n");
420
421 /* I'm pretty sure we don't need to do jack here. Nor Jill. */
422 }
423
424 static void
425 oscar_xfer_end(struct gaim_xfer *xfer)
426 {
427 struct gaim_connection *gc;
428 struct oscar_data *od;
429 struct oscar_xfer_data *xfer_data;
430 debug_printf("AAA - in oscar_xfer_end\n");
431
432 if (!(xfer_data = xfer->data))
433 return;
434
435 if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE)
436 aim_oft_sendheader(xfer_data->conn->sessv, xfer_data->conn, AIM_CB_OFT_DONE, xfer_data->cookie, xfer->filename, 1, 1, xfer->size, xfer->size, xfer_data->modtime, xfer_data->checksum, 0x21);
437
438 if ((gc = xfer_data->gc)) {
439 if ((od = gc->proto_data))
440 od->file_transfers = g_slist_remove(od->file_transfers, xfer);
441 }
442
443 g_free(xfer_data);
444 xfer->data = NULL;
445 }
446
447 static void
448 oscar_xfer_cancel(struct gaim_xfer *xfer)
449 {
450 struct gaim_connection *gc;
451 struct oscar_data *od;
452 struct oscar_xfer_data *xfer_data;
453 aim_conn_t *conn;
454 debug_printf("AAA - in oscar_xfer_cancel\n");
455
456 if (!(xfer_data = xfer->data))
457 return;
458
459 if ((conn = xfer_data->conn)) {
460 aim_session_t *sess;
461 if ((sess = conn->sessv))
462 if (xfer_data->cookie && xfer->who)
463 aim_im_sendch2_sendfile_cancel(sess, xfer_data->cookie, xfer->who, AIM_CAPS_SENDFILE);
464 }
465
466 if ((gc = xfer_data->gc))
467 if ((od = gc->proto_data))
468 od->file_transfers = g_slist_remove(od->file_transfers, xfer);
469
470 g_free(xfer_data);
471 xfer->data = NULL;
472 }
473
474 static void
475 oscar_xfer_ack(struct gaim_xfer *xfer, const char *buffer, size_t size)
476 {
477 struct oscar_xfer_data *xfer_data;
478
479 if (!(xfer_data = xfer->data))
480 return;
481
482 aim_oft_checksum(buffer, size, xfer_data->checksum);
483 }
484
485 static struct gaim_xfer *
486 oscar_find_xfer_by_cookie(GSList *fts, const char *ck)
487 {
488 struct gaim_xfer *xfer;
489 struct oscar_xfer_data *data;
490
491 while (fts) {
492 xfer = fts->data;
493 data = xfer->data;
494
495 if (data && !strcmp(data->cookie, ck))
496 return xfer;
497
498 fts = g_slist_next(fts);
499 }
500
501 return NULL;
502 }
503
504 static struct gaim_xfer *
505 oscar_find_xfer_by_conn(GSList *fts, aim_conn_t *conn)
506 {
507 struct gaim_xfer *xfer;
508 struct oscar_xfer_data *data;
509
510 while (fts) {
511 xfer = fts->data;
512 data = xfer->data;
513
514 if (data && (conn == data->conn))
515 return xfer;
516
517 fts = g_slist_next(fts);
518 }
519
520 return NULL;
521 }
522
291 #if 0 523 #if 0
292 /* XXX there must be a better way than this.... -- wtm */ 524 /* XXX there must be a better way than this.... -- wtm */
293 static struct oscar_file_transfer *find_oft_by_conn(struct gaim_connection *gc, 525 static struct oscar_file_transfer *find_oft_by_conn(struct gaim_connection *gc, aim_conn_t *conn) {
294 aim_conn_t *conn) {
295 GSList *g = ((struct oscar_data *)gc->proto_data)->file_transfers; 526 GSList *g = ((struct oscar_data *)gc->proto_data)->file_transfers;
296 struct oscar_file_transfer *f = NULL; 527 struct oscar_file_transfer *f = NULL;
297 528
298 while (g) { 529 while (g) {
299 f = (struct oscar_file_transfer *)g->data; 530 f = (struct oscar_file_transfer *)g->data;
304 } 535 }
305 536
306 return f; 537 return f;
307 } 538 }
308 539
309 static struct oscar_file_transfer *find_oft_by_xfer(struct gaim_connection *gc, 540 static struct oscar_file_transfer *find_oft_by_xfer(struct gaim_connection *gc, struct file_transfer *xfer) {
310 struct file_transfer *xfer) {
311 GSList *g = ((struct oscar_data *)gc->proto_data)->file_transfers; 541 GSList *g = ((struct oscar_data *)gc->proto_data)->file_transfers;
312 struct oscar_file_transfer *f = NULL; 542 struct oscar_file_transfer *f = NULL;
313 543
314 while (g) { 544 while (g) {
315 f = (struct oscar_file_transfer *)g->data; 545 f = (struct oscar_file_transfer *)g->data;
316 if (f->xfer == xfer) 546 if (f->xfer == xfer)
317 break;
318 g = g->next;
319 f = NULL;
320 }
321
322 return f;
323 }
324
325 static struct oscar_file_transfer *find_oft_by_cookie(struct gaim_connection *gc,
326 const char *cookie) {
327 GSList *g = ((struct oscar_data *)gc->proto_data)->file_transfers;
328 struct oscar_file_transfer *f = NULL;
329
330 while (g) {
331 f = (struct oscar_file_transfer *)g->data;
332 if (!strncmp(f->cookie, cookie, 8))
333 break; 547 break;
334 g = g->next; 548 g = g->next;
335 f = NULL; 549 f = NULL;
336 } 550 }
337 551
390 static int gaim_ssi_authrequest (aim_session_t *, aim_frame_t *, ...); 604 static int gaim_ssi_authrequest (aim_session_t *, aim_frame_t *, ...);
391 static int gaim_ssi_authreply (aim_session_t *, aim_frame_t *, ...); 605 static int gaim_ssi_authreply (aim_session_t *, aim_frame_t *, ...);
392 static int gaim_ssi_gotadded (aim_session_t *, aim_frame_t *, ...); 606 static int gaim_ssi_gotadded (aim_session_t *, aim_frame_t *, ...);
393 #endif 607 #endif
394 608
395 static int gaim_directim_initiate(aim_session_t *, aim_frame_t *, ...); 609 static int gaim_odc_initiate (aim_session_t *, aim_frame_t *, ...);
396 static int gaim_directim_incoming(aim_session_t *, aim_frame_t *, ...); 610 static int gaim_odc_incoming (aim_session_t *, aim_frame_t *, ...);
397 static int gaim_directim_typing (aim_session_t *, aim_frame_t *, ...); 611 static int gaim_odc_typing (aim_session_t *, aim_frame_t *, ...);
398 static int gaim_update_ui (aim_session_t *, aim_frame_t *, ...); 612 static int gaim_update_ui (aim_session_t *, aim_frame_t *, ...);
399
400 #if 0
401 static int oscar_file_transfer_do(aim_session_t *, aim_frame_t *, ...);
402 static void oscar_file_transfer_disconnect(aim_session_t *,
403 aim_conn_t *);
404 static void oscar_file_transfer_cancel(struct gaim_connection *,
405 struct file_transfer *);
406 static int oscar_sendfile_request(aim_session_t *sess,
407 struct oscar_file_transfer *oft);
408 static int oscar_sendfile_timeout(aim_session_t *sess, aim_frame_t *fr, ...);
409 #endif
410 613
411 static fu32_t check_encoding(const char *utf8); 614 static fu32_t check_encoding(const char *utf8);
412 static fu32_t parse_encoding(const char *enc); 615 static fu32_t parse_encoding(const char *enc);
413 616
414 static char *msgerrreason[] = { 617 static char *msgerrreason[] = {
438 N_("Queue full"), 641 N_("Queue full"),
439 N_("Not while on AOL") 642 N_("Not while on AOL")
440 }; 643 };
441 static int msgerrreasonlen = 25; 644 static int msgerrreasonlen = 25;
442 645
443 #if 0 646 static void gaim_odc_disconnect(aim_session_t *sess, aim_conn_t *conn) {
444 /*
445 * This is called to clean up whenever a file transfer is no longer in progress,
446 * whether because it finished sucessfully, it was canceled, or there was an error.
447 */
448 static void oscar_file_transfer_disconnect(aim_session_t *sess, aim_conn_t *conn) {
449 struct gaim_connection *gc = sess->aux_data;
450 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
451 struct oscar_file_transfer *oft = find_oft_by_conn(gc,
452 conn);
453
454 od->file_transfers = g_slist_remove(od->file_transfers, oft);
455
456 if (oft->watcher) {
457 gaim_input_remove(oft->watcher);
458 oft->watcher = 0;
459 }
460
461 aim_conn_kill(sess, &conn);
462
463 g_free(oft->sn);
464 g_free(oft);
465 }
466 #endif
467
468 static void gaim_directim_disconnect(aim_session_t *sess, aim_conn_t *conn) {
469 struct gaim_connection *gc = sess->aux_data; 647 struct gaim_connection *gc = sess->aux_data;
470 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 648 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
471 struct gaim_conversation *cnv; 649 struct gaim_conversation *cnv;
472 struct direct_im *dim; 650 struct direct_im *dim;
473 char *sn; 651 char *sn;
474 char buf[256]; 652 char buf[256];
475 653
476 sn = g_strdup(aim_directim_getsn(conn)); 654 sn = g_strdup(aim_odc_getsn(conn));
477 655
478 debug_printf("%s disconnected Direct IM.\n", sn); 656 debug_printf("%s disconnected Direct IM.\n", sn);
479 657
480 dim = find_direct_im(od, sn); 658 dim = find_direct_im(od, sn);
481 od->direct_ims = g_slist_remove(od->direct_ims, dim); 659 od->direct_ims = g_slist_remove(od->direct_ims, dim);
495 g_free(sn); 673 g_free(sn);
496 674
497 return; 675 return;
498 } 676 }
499 677
500 static void oscar_callback(gpointer data, gint source, 678 static void oscar_callback(gpointer data, gint source, GaimInputCondition condition) {
501 GaimInputCondition condition) {
502 aim_conn_t *conn = (aim_conn_t *)data; 679 aim_conn_t *conn = (aim_conn_t *)data;
503 aim_session_t *sess = aim_conn_getsess(conn); 680 aim_session_t *sess = aim_conn_getsess(conn);
504 struct gaim_connection *gc = sess ? sess->aux_data : NULL; 681 struct gaim_connection *gc = sess ? sess->aux_data : NULL;
505 struct oscar_data *odata; 682 struct oscar_data *od;
506 683
507 if (!gc) { 684 if (!gc) {
508 /* gc is null. we return, else we seg SIGSEG on next line. */ 685 /* gc is null. we return, else we seg SIGSEG on next line. */
509 debug_printf("oscar callback for closed connection (1).\n"); 686 debug_printf("oscar callback for closed connection (1).\n");
510 return; 687 return;
511 } 688 }
512 689
513 odata = (struct oscar_data *)gc->proto_data; 690 od = (struct oscar_data *)gc->proto_data;
514 691
515 if (!g_slist_find(connections, gc)) { 692 if (!g_slist_find(connections, gc)) {
516 /* oh boy. this is probably bad. i guess the only thing we 693 /* oh boy. this is probably bad. i guess the only thing we
517 * can really do is return? */ 694 * can really do is return? */
518 debug_printf("oscar callback for closed connection (2).\n"); 695 debug_printf("oscar callback for closed connection (2).\n");
519 return; 696 return;
520 } 697 }
521 698
522 if (condition & GAIM_INPUT_READ) { 699 if (condition & GAIM_INPUT_READ) {
523 if (conn->type == AIM_CONN_TYPE_RENDEZVOUS_OUT) { 700 if (conn->type == AIM_CONN_TYPE_LISTENER) {
524 debug_printf("got information on rendezvous\n"); 701 debug_printf("got information on rendezvous listener\n");
525 if (aim_handlerendconnect(odata->sess, conn) < 0) { 702 if (aim_handlerendconnect(od->sess, conn) < 0) {
526 debug_printf("connection error (rend)\n"); 703 debug_printf("connection error (rendezvous listener)\n");
527 aim_conn_kill(odata->sess, &conn); 704 aim_conn_kill(od->sess, &conn);
528 } 705 }
529 } else { 706 } else {
530 if (aim_get_command(odata->sess, conn) >= 0) { 707 if (aim_get_command(od->sess, conn) >= 0) {
531 aim_rxdispatch(odata->sess); 708 aim_rxdispatch(od->sess);
532 if (odata->killme) 709 if (od->killme)
533 signoff(gc); 710 signoff(gc);
534 } else { 711 } else {
535 if ((conn->type == AIM_CONN_TYPE_BOS) || 712 if ((conn->type == AIM_CONN_TYPE_BOS) ||
536 !(aim_getconn_type(odata->sess, AIM_CONN_TYPE_BOS))) { 713 !(aim_getconn_type(od->sess, AIM_CONN_TYPE_BOS))) {
537 debug_printf("major connection error\n"); 714 debug_printf("major connection error\n");
538 hide_login_progress_error(gc, _("Disconnected.")); 715 hide_login_progress_error(gc, _("Disconnected."));
539 signoff(gc); 716 signoff(gc);
540 } else if (conn->type == AIM_CONN_TYPE_CHAT) { 717 } else if (conn->type == AIM_CONN_TYPE_CHAT) {
541 struct chat_connection *c = find_oscar_chat_by_conn(gc, conn); 718 struct chat_connection *c = find_oscar_chat_by_conn(gc, conn);
544 c->conn = NULL; 721 c->conn = NULL;
545 if (c->inpa > 0) 722 if (c->inpa > 0)
546 gaim_input_remove(c->inpa); 723 gaim_input_remove(c->inpa);
547 c->inpa = 0; 724 c->inpa = 0;
548 c->fd = -1; 725 c->fd = -1;
549 aim_conn_kill(odata->sess, &conn); 726 aim_conn_kill(od->sess, &conn);
550 snprintf(buf, sizeof(buf), _("You have been disconnected from chat room %s."), c->name); 727 snprintf(buf, sizeof(buf), _("You have been disconnected from chat room %s."), c->name);
551 do_error_dialog(buf, NULL, GAIM_ERROR); 728 do_error_dialog(buf, NULL, GAIM_ERROR);
552 } else if (conn->type == AIM_CONN_TYPE_CHATNAV) { 729 } else if (conn->type == AIM_CONN_TYPE_CHATNAV) {
553 if (odata->cnpa > 0) 730 if (od->cnpa > 0)
554 gaim_input_remove(odata->cnpa); 731 gaim_input_remove(od->cnpa);
555 odata->cnpa = 0; 732 od->cnpa = 0;
556 debug_printf("removing chatnav input watcher\n"); 733 debug_printf("removing chatnav input watcher\n");
557 while (odata->create_rooms) { 734 while (od->create_rooms) {
558 struct create_room *cr = odata->create_rooms->data; 735 struct create_room *cr = od->create_rooms->data;
559 g_free(cr->name); 736 g_free(cr->name);
560 odata->create_rooms = 737 od->create_rooms =
561 g_slist_remove(odata->create_rooms, cr); 738 g_slist_remove(od->create_rooms, cr);
562 g_free(cr); 739 g_free(cr);
563 do_error_dialog(_("Chat is currently unavailable"), NULL, GAIM_ERROR); 740 do_error_dialog(_("Chat is currently unavailable"), NULL, GAIM_ERROR);
564 } 741 }
565 aim_conn_kill(odata->sess, &conn); 742 aim_conn_kill(od->sess, &conn);
566 } else if (conn->type == AIM_CONN_TYPE_AUTH) { 743 } else if (conn->type == AIM_CONN_TYPE_AUTH) {
567 if (odata->paspa > 0) 744 if (od->paspa > 0)
568 gaim_input_remove(odata->paspa); 745 gaim_input_remove(od->paspa);
569 odata->paspa = 0; 746 od->paspa = 0;
570 debug_printf("removing authconn input watcher\n"); 747 debug_printf("removing authconn input watcher\n");
571 aim_conn_kill(odata->sess, &conn); 748 aim_conn_kill(od->sess, &conn);
572 } else if (conn->type == AIM_CONN_TYPE_EMAIL) { 749 } else if (conn->type == AIM_CONN_TYPE_EMAIL) {
573 if (odata->emlpa > 0) 750 if (od->emlpa > 0)
574 gaim_input_remove(odata->emlpa); 751 gaim_input_remove(od->emlpa);
575 odata->emlpa = 0; 752 od->emlpa = 0;
576 debug_printf("removing email input watcher\n"); 753 debug_printf("removing email input watcher\n");
577 aim_conn_kill(odata->sess, &conn); 754 aim_conn_kill(od->sess, &conn);
578 } else if (conn->type == AIM_CONN_TYPE_RENDEZVOUS) { 755 } else if (conn->type == AIM_CONN_TYPE_RENDEZVOUS) {
579 if (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM) 756 if (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM)
580 gaim_directim_disconnect(odata->sess, conn); 757 gaim_odc_disconnect(od->sess, conn);
581 else if (conn->subtype == AIM_CONN_SUBTYPE_OFT_SENDFILE) { 758 aim_conn_kill(od->sess, &conn);
582 #if 0
583 struct oscar_file_transfer *oft = find_oft_by_conn(gc, conn);
584 if (oft) {
585 transfer_abort(oft->xfer, _("Buddy canceled transfer"));
586 }
587 oscar_file_transfer_disconnect(odata->sess, conn);
588 #endif
589 }
590 else {
591 debug_printf("No handler for rendezvous disconnect (%d).\n",
592 source);
593 }
594 aim_conn_kill(odata->sess, &conn);
595 } else { 759 } else {
596 debug_printf("holy crap! generic connection error! %hu\n", 760 debug_printf("holy crap! generic connection error! %hu\n",
597 conn->type); 761 conn->type);
598 aim_conn_kill(odata->sess, &conn); 762 aim_conn_kill(od->sess, &conn);
599 } 763 }
600 } 764 }
601 } 765 }
602 } 766 }
603 } 767 }
618 } 782 }
619 783
620 static void oscar_login_connect(gpointer data, gint source, GaimInputCondition cond) 784 static void oscar_login_connect(gpointer data, gint source, GaimInputCondition cond)
621 { 785 {
622 struct gaim_connection *gc = data; 786 struct gaim_connection *gc = data;
623 struct oscar_data *odata; 787 struct oscar_data *od;
624 aim_session_t *sess; 788 aim_session_t *sess;
625 aim_conn_t *conn; 789 aim_conn_t *conn;
626 790
627 if (!g_slist_find(connections, gc)) { 791 if (!g_slist_find(connections, gc)) {
628 close(source); 792 close(source);
629 return; 793 return;
630 } 794 }
631 795
632 odata = gc->proto_data; 796 od = gc->proto_data;
633 sess = odata->sess; 797 sess = od->sess;
634 conn = aim_getconn_type_all(sess, AIM_CONN_TYPE_AUTH); 798 conn = aim_getconn_type_all(sess, AIM_CONN_TYPE_AUTH);
635 799
636 conn->fd = source; 800 conn->fd = source;
637 801
638 if (source < 0) { 802 if (source < 0) {
640 signoff(gc); 804 signoff(gc);
641 return; 805 return;
642 } 806 }
643 807
644 aim_conn_completeconnect(sess, conn); 808 aim_conn_completeconnect(sess, conn);
645 gc->inpa = gaim_input_add(conn->fd, GAIM_INPUT_READ, 809 gc->inpa = gaim_input_add(conn->fd, GAIM_INPUT_READ, oscar_callback, conn);
646 oscar_callback, conn);
647 debug_printf("Password sent, waiting for response\n"); 810 debug_printf("Password sent, waiting for response\n");
648 } 811 }
649 812
650 static void oscar_login(struct gaim_account *account) { 813 static void oscar_login(struct gaim_account *account) {
651 aim_session_t *sess; 814 aim_session_t *sess;
652 aim_conn_t *conn; 815 aim_conn_t *conn;
653 char buf[256]; 816 char buf[256];
654 struct gaim_connection *gc = new_gaim_conn(account); 817 struct gaim_connection *gc = new_gaim_conn(account);
655 struct oscar_data *odata = gc->proto_data = g_new0(struct oscar_data, 1); 818 struct oscar_data *od = gc->proto_data = g_new0(struct oscar_data, 1);
656 819
657 if (isdigit(*account->username)) { 820 if (isdigit(*account->username)) {
658 odata->icq = TRUE; 821 od->icq = TRUE;
659 gc->password[8] = 0; 822 gc->password[8] = 0;
660 } else { 823 } else {
661 gc->flags |= OPT_CONN_HTML; 824 gc->flags |= OPT_CONN_HTML;
662 gc->flags |= OPT_CONN_AUTO_RESP; 825 gc->flags |= OPT_CONN_AUTO_RESP;
663 } 826 }
664 odata->supports_tn = g_hash_table_new(g_str_hash, g_str_equal); 827 od->supports_tn = g_hash_table_new(g_str_hash, g_str_equal);
665 828
666 sess = g_new0(aim_session_t, 1); 829 sess = g_new0(aim_session_t, 1);
667 830
668 aim_session_init(sess, AIM_SESS_FLAGS_NONBLOCKCONNECT, 0); 831 aim_session_init(sess, AIM_SESS_FLAGS_NONBLOCKCONNECT, 0);
669 aim_setdebuggingcb(sess, oscar_debug); 832 aim_setdebuggingcb(sess, oscar_debug);
670 833
671 /* we need an immediate queue because we don't use a while-loop to 834 /* we need an immediate queue because we don't use a while-loop to
672 * see if things need to be sent. */ 835 * see if things need to be sent. */
673 aim_tx_setenqueue(sess, AIM_TX_IMMEDIATE, NULL); 836 aim_tx_setenqueue(sess, AIM_TX_IMMEDIATE, NULL);
674 odata->sess = sess; 837 od->sess = sess;
675 sess->aux_data = gc; 838 sess->aux_data = gc;
676 839
677 conn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, NULL); 840 conn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, NULL);
678 if (conn == NULL) { 841 if (conn == NULL) {
679 debug_printf("internal connection error\n"); 842 debug_printf("internal connection error\n");
700 } 863 }
701 aim_request_login(sess, conn, gc->username); 864 aim_request_login(sess, conn, gc->username);
702 } 865 }
703 866
704 static void oscar_close(struct gaim_connection *gc) { 867 static void oscar_close(struct gaim_connection *gc) {
705 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; 868 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
706 869
707 while (odata->oscar_chats) { 870 while (od->oscar_chats) {
708 struct chat_connection *n = odata->oscar_chats->data; 871 struct chat_connection *n = od->oscar_chats->data;
709 if (n->inpa > 0) 872 if (n->inpa > 0)
710 gaim_input_remove(n->inpa); 873 gaim_input_remove(n->inpa);
711 g_free(n->name); 874 g_free(n->name);
712 g_free(n->show); 875 g_free(n->show);
713 odata->oscar_chats = g_slist_remove(odata->oscar_chats, n); 876 od->oscar_chats = g_slist_remove(od->oscar_chats, n);
714 g_free(n); 877 g_free(n);
715 } 878 }
716 while (odata->direct_ims) { 879 while (od->direct_ims) {
717 struct direct_im *n = odata->direct_ims->data; 880 struct direct_im *n = od->direct_ims->data;
718 if (n->watcher > 0) 881 if (n->watcher > 0)
719 gaim_input_remove(n->watcher); 882 gaim_input_remove(n->watcher);
720 odata->direct_ims = g_slist_remove(odata->direct_ims, n); 883 od->direct_ims = g_slist_remove(od->direct_ims, n);
721 g_free(n); 884 g_free(n);
722 } 885 }
723 886
724 #if 0 887 /* BBB */
725 while (odata->file_transfers) { 888 while (od->file_transfers) {
726 struct oscar_file_transfer *n = odata->file_transfers->data; 889 struct gaim_xfer *xfer;
727 if (n->watcher > 0) 890 xfer = (struct gaim_xfer *)od->file_transfers->data;
728 gaim_input_remove(n->watcher); 891 gaim_xfer_destroy(xfer);
729 odata->file_transfers = g_slist_remove(odata->file_transfers, n); 892 }
893
894 while (od->hasicons) {
895 struct icon_req *n = od->hasicons->data;
896 g_free(n->user);
897 od->hasicons = g_slist_remove(od->hasicons, n);
730 g_free(n); 898 g_free(n);
731 } 899 }
732 #endif 900 g_hash_table_destroy(od->supports_tn);
733 901 while (od->evilhack) {
734 while (odata->hasicons) { 902 g_free(od->evilhack->data);
735 struct icon_req *n = odata->hasicons->data; 903 od->evilhack = g_slist_remove(od->evilhack, od->evilhack->data);
736 g_free(n->user); 904 }
737 odata->hasicons = g_slist_remove(odata->hasicons, n); 905 while (od->create_rooms) {
738 g_free(n); 906 struct create_room *cr = od->create_rooms->data;
739 }
740 g_hash_table_destroy(odata->supports_tn);
741 while (odata->evilhack) {
742 g_free(odata->evilhack->data);
743 odata->evilhack = g_slist_remove(odata->evilhack, odata->evilhack->data);
744 }
745 while (odata->create_rooms) {
746 struct create_room *cr = odata->create_rooms->data;
747 g_free(cr->name); 907 g_free(cr->name);
748 odata->create_rooms = g_slist_remove(odata->create_rooms, cr); 908 od->create_rooms = g_slist_remove(od->create_rooms, cr);
749 g_free(cr); 909 g_free(cr);
750 } 910 }
751 if (odata->email) 911 if (od->email)
752 g_free(odata->email); 912 g_free(od->email);
753 if (odata->newp) 913 if (od->newp)
754 g_free(odata->newp); 914 g_free(od->newp);
755 if (odata->oldp) 915 if (od->oldp)
756 g_free(odata->oldp); 916 g_free(od->oldp);
757 if (gc->inpa > 0) 917 if (gc->inpa > 0)
758 gaim_input_remove(gc->inpa); 918 gaim_input_remove(gc->inpa);
759 if (odata->cnpa > 0) 919 if (od->cnpa > 0)
760 gaim_input_remove(odata->cnpa); 920 gaim_input_remove(od->cnpa);
761 if (odata->paspa > 0) 921 if (od->paspa > 0)
762 gaim_input_remove(odata->paspa); 922 gaim_input_remove(od->paspa);
763 if (odata->emlpa > 0) 923 if (od->emlpa > 0)
764 gaim_input_remove(odata->emlpa); 924 gaim_input_remove(od->emlpa);
765 aim_session_kill(odata->sess); 925 aim_session_kill(od->sess);
766 g_free(odata->sess); 926 g_free(od->sess);
767 odata->sess = NULL; 927 od->sess = NULL;
768 g_free(gc->proto_data); 928 g_free(gc->proto_data);
769 gc->proto_data = NULL; 929 gc->proto_data = NULL;
770 debug_printf("Signed off.\n"); 930 debug_printf("Signed off.\n");
771 } 931 }
772 932
773 static void oscar_bos_connect(gpointer data, gint source, GaimInputCondition cond) { 933 static void oscar_bos_connect(gpointer data, gint source, GaimInputCondition cond) {
774 struct gaim_connection *gc = data; 934 struct gaim_connection *gc = data;
775 struct oscar_data *odata; 935 struct oscar_data *od;
776 aim_session_t *sess; 936 aim_session_t *sess;
777 aim_conn_t *bosconn; 937 aim_conn_t *bosconn;
778 938
779 if (!g_slist_find(connections, gc)) { 939 if (!g_slist_find(connections, gc)) {
780 close(source); 940 close(source);
781 return; 941 return;
782 } 942 }
783 943
784 odata = gc->proto_data; 944 od = gc->proto_data;
785 sess = odata->sess; 945 sess = od->sess;
786 bosconn = odata->conn; 946 bosconn = od->conn;
787 bosconn->fd = source; 947 bosconn->fd = source;
788 948
789 if (source < 0) { 949 if (source < 0) {
790 hide_login_progress(gc, _("Could Not Connect")); 950 hide_login_progress(gc, _("Could Not Connect"));
791 signoff(gc); 951 signoff(gc);
792 return; 952 return;
793 } 953 }
794 954
795 aim_conn_completeconnect(sess, bosconn); 955 aim_conn_completeconnect(sess, bosconn);
796 gc->inpa = gaim_input_add(bosconn->fd, GAIM_INPUT_READ, 956 gc->inpa = gaim_input_add(bosconn->fd, GAIM_INPUT_READ, oscar_callback, bosconn);
797 oscar_callback, bosconn);
798 set_login_progress(gc, 4, _("Connection established, cookie sent")); 957 set_login_progress(gc, 4, _("Connection established, cookie sent"));
799 } 958 }
800 959
801 #if 0 960 /* BBB */
802 static void oscar_ask_send_file(struct gaim_connection *gc, char *destsn) { 961 static void oscar_ask_sendfile(struct gaim_connection *gc, char *destsn) {
803 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 962 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
804 963
805 struct oscar_file_transfer *oft = g_new0(struct oscar_file_transfer, 964 /* You want to send a file to someone else, you're so generous */
806 1); 965 struct gaim_xfer *xfer;
807 966 struct oscar_xfer_data *xfer_data;
808 oft->type = OFT_SENDFILE_OUT; 967
809 oft->sn = g_strdup(destsn); 968 /* Create the oscar-specific data */
810 969 xfer_data = g_malloc0(sizeof(struct oscar_xfer_data));
811 od->file_transfers = g_slist_append(od->file_transfers, oft); 970 xfer_data->gc = gc;
812 971
813 oft->xfer = transfer_out_add(gc, oft->sn); 972 /* Build the file transfer handle */
814 } 973 xfer = gaim_xfer_new(gc->account, GAIM_XFER_SEND, destsn);
815 #endif 974 xfer_data->xfer = xfer;
975 xfer->data = xfer_data;
976
977 /* Set the info about the incoming file */
978 if (od) {
979 /* XXX - Create core gaim functions for getting ip and getting port from an fd */
980 aim_session_t *sess;
981 aim_conn_t *conn;
982 struct sockaddr addr;
983 socklen_t namelen = sizeof(addr);
984 if ((sess = od->sess) && (conn = aim_conn_findbygroup(sess, 0x0004)))
985 if (!getsockname(conn->fd, &addr, &namelen))
986 xfer->local_ip = g_strdup(inet_ntoa(((struct sockaddr_in *)&addr)->sin_addr));
987 }
988 xfer->local_port = 5190;
989
990 /* Setup our I/O op functions */
991 gaim_xfer_set_init_fnc(xfer, oscar_xfer_init);
992 gaim_xfer_set_start_fnc(xfer, oscar_xfer_start);
993 gaim_xfer_set_end_fnc(xfer, oscar_xfer_end);
994 gaim_xfer_set_cancel_fnc(xfer, oscar_xfer_cancel);
995
996 /* Keep track of this transfer for later */
997 od->file_transfers = g_slist_append(od->file_transfers, xfer);
998
999 /* Now perform the request */
1000 gaim_xfer_request(xfer);
1001 }
816 1002
817 static int gaim_parse_auth_resp(aim_session_t *sess, aim_frame_t *fr, ...) { 1003 static int gaim_parse_auth_resp(aim_session_t *sess, aim_frame_t *fr, ...) {
818 va_list ap; 1004 va_list ap;
819 struct aim_authresp_info *info; 1005 struct aim_authresp_info *info;
820 int i, rc; 1006 int i, rc;
838 char buf[256]; 1024 char buf[256];
839 switch (info->errorcode) { 1025 switch (info->errorcode) {
840 case 0x05: 1026 case 0x05:
841 /* Incorrect nick/password */ 1027 /* Incorrect nick/password */
842 hide_login_progress(gc, _("Incorrect nickname or password.")); 1028 hide_login_progress(gc, _("Incorrect nickname or password."));
843 plugin_event(event_error, (void *)980, 0, 0, 0);
844 break; 1029 break;
845 case 0x11: 1030 case 0x11:
846 /* Suspended account */ 1031 /* Suspended account */
847 hide_login_progress(gc, _("Your account is currently suspended.")); 1032 hide_login_progress(gc, _("Your account is currently suspended."));
848 break; 1033 break;
851 hide_login_progress(gc, _("The AOL Instant Messenger service is temporarily unavailable.")); 1036 hide_login_progress(gc, _("The AOL Instant Messenger service is temporarily unavailable."));
852 break; 1037 break;
853 case 0x18: 1038 case 0x18:
854 /* connecting too frequently */ 1039 /* connecting too frequently */
855 hide_login_progress(gc, _("You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer.")); 1040 hide_login_progress(gc, _("You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer."));
856 plugin_event(event_error, (void *)983, 0, 0, 0);
857 break; 1041 break;
858 case 0x1c: 1042 case 0x1c:
859 /* client too old */ 1043 /* client too old */
860 g_snprintf(buf, sizeof(buf), _("The client version you are using is too old. Please upgrade at %s"), WEBSITE); 1044 g_snprintf(buf, sizeof(buf), _("The client version you are using is too old. Please upgrade at %s"), WEBSITE);
861 hide_login_progress(gc, buf); 1045 hide_login_progress(gc, buf);
862 plugin_event(event_error, (void *)989, 0, 0, 0);
863 break; 1046 break;
864 default: 1047 default:
865 hide_login_progress(gc, _("Authentication Failed")); 1048 hide_login_progress(gc, _("Authentication Failed"));
866 break; 1049 break;
867 } 1050 }
930 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTHREQ, gaim_ssi_authrequest, 0); 1113 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTHREQ, gaim_ssi_authrequest, 0);
931 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTHREP, gaim_ssi_authreply, 0); 1114 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTHREP, gaim_ssi_authreply, 0);
932 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_ADDED, gaim_ssi_gotadded, 0); 1115 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_ADDED, gaim_ssi_gotadded, 0);
933 #endif 1116 #endif
934 1117
935 #if 0
936 aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_MSGTIMEOUT, oscar_sendfile_timeout, 0);
937 #endif
938
939 ((struct oscar_data *)gc->proto_data)->conn = bosconn; 1118 ((struct oscar_data *)gc->proto_data)->conn = bosconn;
940 for (i = 0; i < (int)strlen(info->bosip); i++) { 1119 for (i = 0; i < (int)strlen(info->bosip); i++) {
941 if (info->bosip[i] == ':') { 1120 if (info->bosip[i] == ':') {
942 port = atoi(&(info->bosip[i+1])); 1121 port = atoi(&(info->bosip[i+1]));
943 break; 1122 break;
1109 1288
1110 static int gaim_parse_login(aim_session_t *sess, aim_frame_t *fr, ...) { 1289 static int gaim_parse_login(aim_session_t *sess, aim_frame_t *fr, ...) {
1111 char *key; 1290 char *key;
1112 va_list ap; 1291 va_list ap;
1113 struct gaim_connection *gc = sess->aux_data; 1292 struct gaim_connection *gc = sess->aux_data;
1114 struct oscar_data *odata = gc->proto_data; 1293 struct oscar_data *od = gc->proto_data;
1115 1294
1116 va_start(ap, fr); 1295 va_start(ap, fr);
1117 key = va_arg(ap, char *); 1296 key = va_arg(ap, char *);
1118 va_end(ap); 1297 va_end(ap);
1119 1298
1120 if (odata->icq) { 1299 if (od->icq) {
1121 struct client_info_s info = CLIENTINFO_ICQ_KNOWNGOOD; 1300 struct client_info_s info = CLIENTINFO_ICQ_KNOWNGOOD;
1122 aim_send_login(sess, fr->conn, gc->username, gc->password, &info, key); 1301 aim_send_login(sess, fr->conn, gc->username, gc->password, &info, key);
1123 } else { 1302 } else {
1124 #if 0 1303 #if 0
1125 struct client_info_s info = {"gaim", 4, 1, 2010, "us", "en", 0x0004, 0x0000, 0x04b}; 1304 struct client_info_s info = {"gaim", 4, 1, 2010, "us", "en", 0x0004, 0x0000, 0x04b};
1175 return 1; 1354 return 1;
1176 } 1355 }
1177 1356
1178 static void oscar_chatnav_connect(gpointer data, gint source, GaimInputCondition cond) { 1357 static void oscar_chatnav_connect(gpointer data, gint source, GaimInputCondition cond) {
1179 struct gaim_connection *gc = data; 1358 struct gaim_connection *gc = data;
1180 struct oscar_data *odata; 1359 struct oscar_data *od;
1181 aim_session_t *sess; 1360 aim_session_t *sess;
1182 aim_conn_t *tstconn; 1361 aim_conn_t *tstconn;
1183 1362
1184 if (!g_slist_find(connections, gc)) { 1363 if (!g_slist_find(connections, gc)) {
1185 close(source); 1364 close(source);
1186 return; 1365 return;
1187 } 1366 }
1188 1367
1189 odata = gc->proto_data; 1368 od = gc->proto_data;
1190 sess = odata->sess; 1369 sess = od->sess;
1191 tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_CHATNAV); 1370 tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_CHATNAV);
1192 tstconn->fd = source; 1371 tstconn->fd = source;
1193 1372
1194 if (source < 0) { 1373 if (source < 0) {
1195 aim_conn_kill(sess, &tstconn); 1374 aim_conn_kill(sess, &tstconn);
1196 debug_printf("unable to connect to chatnav server\n"); 1375 debug_printf("unable to connect to chatnav server\n");
1197 return; 1376 return;
1198 } 1377 }
1199 1378
1200 aim_conn_completeconnect(sess, tstconn); 1379 aim_conn_completeconnect(sess, tstconn);
1201 odata->cnpa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, 1380 od->cnpa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, oscar_callback, tstconn);
1202 oscar_callback, tstconn);
1203 debug_printf("chatnav: connected\n"); 1381 debug_printf("chatnav: connected\n");
1204 } 1382 }
1205 1383
1206 static void oscar_auth_connect(gpointer data, gint source, GaimInputCondition cond) 1384 static void oscar_auth_connect(gpointer data, gint source, GaimInputCondition cond)
1207 { 1385 {
1208 struct gaim_connection *gc = data; 1386 struct gaim_connection *gc = data;
1209 struct oscar_data *odata; 1387 struct oscar_data *od;
1210 aim_session_t *sess; 1388 aim_session_t *sess;
1211 aim_conn_t *tstconn; 1389 aim_conn_t *tstconn;
1212 1390
1213 if (!g_slist_find(connections, gc)) { 1391 if (!g_slist_find(connections, gc)) {
1214 close(source); 1392 close(source);
1215 return; 1393 return;
1216 } 1394 }
1217 1395
1218 odata = gc->proto_data; 1396 od = gc->proto_data;
1219 sess = odata->sess; 1397 sess = od->sess;
1220 tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_AUTH); 1398 tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_AUTH);
1221 tstconn->fd = source; 1399 tstconn->fd = source;
1222 1400
1223 if (source < 0) { 1401 if (source < 0) {
1224 aim_conn_kill(sess, &tstconn); 1402 aim_conn_kill(sess, &tstconn);
1225 debug_printf("unable to connect to authorizer\n"); 1403 debug_printf("unable to connect to authorizer\n");
1226 return; 1404 return;
1227 } 1405 }
1228 1406
1229 aim_conn_completeconnect(sess, tstconn); 1407 aim_conn_completeconnect(sess, tstconn);
1230 odata->paspa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, 1408 od->paspa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, oscar_callback, tstconn);
1231 oscar_callback, tstconn);
1232 debug_printf("chatnav: connected\n"); 1409 debug_printf("chatnav: connected\n");
1233 } 1410 }
1234 1411
1235 static void oscar_chat_connect(gpointer data, gint source, GaimInputCondition cond) 1412 static void oscar_chat_connect(gpointer data, gint source, GaimInputCondition cond)
1236 { 1413 {
1237 struct chat_connection *ccon = data; 1414 struct chat_connection *ccon = data;
1238 struct gaim_connection *gc = ccon->gc; 1415 struct gaim_connection *gc = ccon->gc;
1239 struct oscar_data *odata; 1416 struct oscar_data *od;
1240 aim_session_t *sess; 1417 aim_session_t *sess;
1241 aim_conn_t *tstconn; 1418 aim_conn_t *tstconn;
1242 1419
1243 if (!g_slist_find(connections, gc)) { 1420 if (!g_slist_find(connections, gc)) {
1244 close(source); 1421 close(source);
1246 g_free(ccon->name); 1423 g_free(ccon->name);
1247 g_free(ccon); 1424 g_free(ccon);
1248 return; 1425 return;
1249 } 1426 }
1250 1427
1251 odata = gc->proto_data; 1428 od = gc->proto_data;
1252 sess = odata->sess; 1429 sess = od->sess;
1253 tstconn = ccon->conn; 1430 tstconn = ccon->conn;
1254 tstconn->fd = source; 1431 tstconn->fd = source;
1255 1432
1256 if (source < 0) { 1433 if (source < 0) {
1257 aim_conn_kill(sess, &tstconn); 1434 aim_conn_kill(sess, &tstconn);
1260 g_free(ccon); 1437 g_free(ccon);
1261 return; 1438 return;
1262 } 1439 }
1263 1440
1264 aim_conn_completeconnect(sess, ccon->conn); 1441 aim_conn_completeconnect(sess, ccon->conn);
1265 ccon->inpa = gaim_input_add(tstconn->fd, 1442 ccon->inpa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, oscar_callback, tstconn);
1266 GAIM_INPUT_READ, 1443 od->oscar_chats = g_slist_append(od->oscar_chats, ccon);
1267 oscar_callback, tstconn);
1268 odata->oscar_chats = g_slist_append(odata->oscar_chats, ccon);
1269 } 1444 }
1270 1445
1271 static void oscar_email_connect(gpointer data, gint source, GaimInputCondition cond) { 1446 static void oscar_email_connect(gpointer data, gint source, GaimInputCondition cond) {
1272 struct gaim_connection *gc = data; 1447 struct gaim_connection *gc = data;
1273 struct oscar_data *odata; 1448 struct oscar_data *od;
1274 aim_session_t *sess; 1449 aim_session_t *sess;
1275 aim_conn_t *tstconn; 1450 aim_conn_t *tstconn;
1276 1451
1277 if (!g_slist_find(connections, gc)) { 1452 if (!g_slist_find(connections, gc)) {
1278 close(source); 1453 close(source);
1279 return; 1454 return;
1280 } 1455 }
1281 1456
1282 odata = gc->proto_data; 1457 od = gc->proto_data;
1283 sess = odata->sess; 1458 sess = od->sess;
1284 tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_EMAIL); 1459 tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_EMAIL);
1285 tstconn->fd = source; 1460 tstconn->fd = source;
1286 1461
1287 if (source < 0) { 1462 if (source < 0) {
1288 aim_conn_kill(sess, &tstconn); 1463 aim_conn_kill(sess, &tstconn);
1289 debug_printf("unable to connect to email server\n"); 1464 debug_printf("unable to connect to email server\n");
1290 return; 1465 return;
1291 } 1466 }
1292 1467
1293 aim_conn_completeconnect(sess, tstconn); 1468 aim_conn_completeconnect(sess, tstconn);
1294 odata->emlpa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, oscar_callback, tstconn); 1469 od->emlpa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, oscar_callback, tstconn);
1295 debug_printf("email: connected\n"); 1470 debug_printf("email: connected\n");
1296 } 1471 }
1297 1472
1298 /* Hrmph. I don't know how to make this look better. --mid */ 1473 /* Hrmph. I don't know how to make this look better. --mid */
1299 static int gaim_handle_redirect(aim_session_t *sess, aim_frame_t *fr, ...) { 1474 static int gaim_handle_redirect(aim_session_t *sess, aim_frame_t *fr, ...) {
1505 1680
1506 g_free(d->sn); 1681 g_free(d->sn);
1507 g_free(d); 1682 g_free(d);
1508 } 1683 }
1509 1684
1510 static void oscar_directim_callback(gpointer data, gint source, GaimInputCondition condition) { 1685 static void oscar_odc_callback(gpointer data, gint source, GaimInputCondition condition) {
1511 struct direct_im *dim = data; 1686 struct direct_im *dim = data;
1512 struct gaim_connection *gc = dim->gc; 1687 struct gaim_connection *gc = dim->gc;
1513 struct oscar_data *od = gc->proto_data; 1688 struct oscar_data *od = gc->proto_data;
1514 struct gaim_conversation *cnv; 1689 struct gaim_conversation *cnv;
1515 char buf[256]; 1690 char buf[256];
1537 dim->connected = TRUE; 1712 dim->connected = TRUE;
1538 gaim_conversation_write(cnv, NULL, buf, -1, WFLAG_SYSTEM, time(NULL)); 1713 gaim_conversation_write(cnv, NULL, buf, -1, WFLAG_SYSTEM, time(NULL));
1539 } 1714 }
1540 od->direct_ims = g_slist_append(od->direct_ims, dim); 1715 od->direct_ims = g_slist_append(od->direct_ims, dim);
1541 1716
1542 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, 1717 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, oscar_callback, dim->conn);
1543 oscar_callback, dim->conn); 1718 }
1544 } 1719
1545 1720 /* BBB */
1546 #if 0
1547 /* 1721 /*
1548 * This is called every time we are finished sending a file and the receiving buddy 1722 * This is called after a remote AIM user has connected to us. We
1549 * has sent back an acknowledgement; we start the next file or tear down the 1723 * want to do some voodoo with the socket file descriptors, add a
1550 * connection as appropriate. 1724 * callback or two, and then send the AIM_CB_OFT_PROMPT.
1551 */ 1725 */
1552 static int oscar_sendfile_out_done(aim_session_t *sess, aim_frame_t *fr, ...) { 1726 static int oscar_sendfile_established(aim_session_t *sess, aim_frame_t *fr, ...) {
1553 struct gaim_connection *gc = sess->aux_data;
1554 va_list ap;
1555 aim_conn_t *conn;
1556 const char *cook;
1557 struct oscar_file_transfer *oft;
1558
1559 va_start(ap, fr);
1560 conn = va_arg(ap, aim_conn_t *);
1561 cook = va_arg(ap, const char *);
1562 va_end(ap);
1563
1564 oft = find_oft_by_cookie(gc, cook);
1565 if (oft->filesdone == oft->totfiles)
1566 oscar_file_transfer_disconnect(sess, conn);
1567 else
1568 /* Send header for next file */
1569 oscar_sendfile_request(sess, oft);
1570
1571 return 0;
1572 }
1573
1574 /* Called once for each file before sending the raw data. */
1575 static int oscar_sendfile_request(aim_session_t *sess,
1576 struct oscar_file_transfer *oft) {
1577 char *name;
1578 int size;
1579
1580 transfer_get_file_info(oft->xfer, &size, &name);
1581 /* AAA convert the name to UCS-2 if necessary, and pass the encoding to the call below */
1582 aim_oft_sendfile_request(sess, oft->conn, name, oft->filesdone,
1583 oft->totfiles, size, oft->totsize);
1584
1585 return 0;
1586 }
1587
1588 /*
1589 * This is called when sending a file and a direct connection has been set up with
1590 * the buddy; we can now transmit the appropriate headers describing the transfer.
1591 */
1592 static int oscar_sendfile_accepted(aim_session_t *sess, aim_frame_t *fr, ...) {
1593 struct gaim_connection *gc = sess->aux_data; 1727 struct gaim_connection *gc = sess->aux_data;
1594 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 1728 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
1595 struct oscar_file_transfer *oft; 1729 struct gaim_xfer *xfer;
1730 struct oscar_xfer_data *xfer_data;
1596 va_list ap; 1731 va_list ap;
1597 aim_conn_t *conn, *listenerconn; 1732 aim_conn_t *conn, *listenerconn;
1733 debug_printf("AAA - in oscar_sendfile_established\n");
1598 1734
1599 va_start(ap, fr); 1735 va_start(ap, fr);
1600 conn = va_arg(ap, aim_conn_t *); 1736 conn = va_arg(ap, aim_conn_t *);
1601 listenerconn = va_arg(ap, aim_conn_t *); 1737 listenerconn = va_arg(ap, aim_conn_t *);
1602 va_end(ap); 1738 va_end(ap);
1603 1739
1604 oft = find_oft_by_conn(gc, listenerconn); 1740 if (!(xfer = oscar_find_xfer_by_conn(od->file_transfers, listenerconn)))
1605 oft->conn = conn; 1741 return 1;
1742
1743 if (!(xfer_data = xfer->data))
1744 return 1;
1745
1606 /* Stop watching listener conn; watch transfer conn instead */ 1746 /* Stop watching listener conn; watch transfer conn instead */
1607 gaim_input_remove(oft->watcher); 1747 gaim_input_remove(xfer->watcher);
1608 aim_conn_kill(sess, &listenerconn); 1748 aim_conn_kill(sess, &listenerconn);
1609 1749
1610 aim_conn_addhandler(od->sess, oft->conn, AIM_CB_FAM_OFT, 1750 xfer_data->conn = conn;
1611 AIM_CB_OFT_SENDFILEFILESEND, 1751 xfer->fd = xfer_data->conn->fd;
1612 oscar_file_transfer_do, 1752
1613 0); 1753 aim_conn_addhandler(sess, xfer_data->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_ACK, oscar_sendfile_ack, 0);
1614 aim_conn_addhandler(sess, conn, 1754 aim_conn_addhandler(sess, xfer_data->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DONE, oscar_sendfile_done, 0);
1615 AIM_CB_FAM_OFT, 1755 xfer->watcher = gaim_input_add(xfer_data->conn->fd, GAIM_INPUT_READ, oscar_callback, xfer_data->conn);
1616 AIM_CB_OFT_SENDFILECOMPLETE, 1756
1617 oscar_sendfile_out_done, 1757 /* Inform the other user that we are connected and ready to transfer */
1618 0); 1758 aim_oft_sendheader(sess, xfer_data->conn, AIM_CB_OFT_PROMPT, NULL, xfer->filename, 0, 1, xfer->size, xfer->size, time(NULL), xfer_data->checksum, 0x02);
1619 oft->watcher = gaim_input_add(oft->conn->fd, GAIM_INPUT_READ,
1620 oscar_callback, oft->conn);
1621
1622 oscar_sendfile_request(sess, oft);
1623 1759
1624 return 0; 1760 return 0;
1625 } 1761 }
1626 1762
1627 /* 1763 /*
1628 * This is called when we requested to send a file to a buddy, but he or she didn't 1764 * This is the gaim callback passed to proxy_connect when connecting to another AIM
1629 * respond; we need to clean up. 1765 * user in order to transfer a file.
1630 */ 1766 */
1631 static int oscar_sendfile_timeout(aim_session_t *sess, aim_frame_t *fr, ...) { 1767 static void oscar_sendfile_connected(gpointer data, gint source, GaimInputCondition condition) {
1768 struct gaim_connection *gc;
1769 struct gaim_xfer *xfer;
1770 struct oscar_xfer_data *xfer_data;
1771 debug_printf("AAA - in oscar_sendfile_connected\n");
1772
1773 if (!(xfer = data))
1774 return;
1775 if (!(xfer_data = xfer->data))
1776 return;
1777 if (!(gc = xfer_data->gc))
1778 return;
1779 if (source < 0)
1780 return;
1781
1782 xfer->fd = source;
1783 xfer_data->conn->fd = source;
1784
1785 aim_conn_completeconnect(xfer_data->conn->sessv, xfer_data->conn);
1786 xfer->watcher = gaim_input_add(xfer->fd, GAIM_INPUT_READ, oscar_callback, xfer_data->conn);
1787
1788 /* Inform the other user that we are connected and ready to transfer */
1789 aim_im_sendch2_sendfile_accept(xfer_data->conn->sessv, xfer_data->cookie, xfer->who, AIM_CAPS_SENDFILE);
1790
1791 return;
1792 }
1793
1794 /*
1795 * This is called when a buddy sends us some file info. This happens when they
1796 * are sending a file to you, and you have just established a connection to them.
1797 * You should send them the exactly same info except use the real cookie. We also
1798 * get like totally ready to like, receive the file, kay?
1799 */
1800 static int oscar_sendfile_prompt(aim_session_t *sess, aim_frame_t *fr, ...) {
1632 struct gaim_connection *gc = sess->aux_data; 1801 struct gaim_connection *gc = sess->aux_data;
1802 struct oscar_data *od = gc->proto_data;
1803 struct gaim_xfer *xfer;
1804 struct oscar_xfer_data *xfer_data;
1633 va_list ap; 1805 va_list ap;
1634 struct oscar_file_transfer *oft; 1806 aim_conn_t *conn;
1635 char *cookie; 1807 fu8_t *cookie;
1636 aim_conn_t *bosconn; 1808 struct aim_fileheader_t *fh;
1809 debug_printf("AAA - in oscar_sendfile_prompt\n");
1637 1810
1638 va_start(ap, fr); 1811 va_start(ap, fr);
1639 bosconn = va_arg(ap, aim_conn_t *); 1812 conn = va_arg(ap, aim_conn_t *);
1640 cookie = va_arg(ap, char *); 1813 cookie = va_arg(ap, fu8_t *);
1814 fh = va_arg(ap, struct aim_fileheader_t *);
1641 va_end(ap); 1815 va_end(ap);
1642 1816
1643 if ((oft = find_oft_by_cookie(gc, cookie))) { 1817 if (!(xfer = oscar_find_xfer_by_conn(od->file_transfers, conn)))
1644 aim_canceltransfer(sess, bosconn, oft->cookie, 1818 return 1;
1645 oft->sn, AIM_CAPS_SENDFILE); 1819
1646 1820 if (!(xfer_data = xfer->data))
1647 transfer_abort(oft->xfer, _("Transfer timed out")); 1821 return 1;
1648 oscar_file_transfer_disconnect(sess, oft->conn); 1822
1649 } 1823 /* Jot down some data we'll need later */
1650 1824 xfer_data->modtime = fh->modtime;
1651 return 1; /* success */ 1825 xfer_data->checksum = fh->checksum;
1652 } 1826
1653 1827 /* We want to stop listening with a normal thingy */
1654 /* Called once at the beginning of an outgoing transfer session. */ 1828 gaim_input_remove(xfer->watcher);
1655 static void oscar_file_transfer_out(struct gaim_connection *gc, 1829 xfer->watcher = 0;
1656 struct file_transfer *xfer, const char *name, int totfiles, 1830
1657 int totsize) { 1831 /* XXX - convert the name from UTF-8 to UCS-2 if necessary, and pass the encoding to the call below */
1658 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 1832 aim_oft_sendheader(xfer_data->conn->sessv, xfer_data->conn, AIM_CB_OFT_ACK, xfer_data->cookie, xfer->filename, 0, 1, xfer->size, xfer->size, fh->modtime, fh->checksum, 0x02);
1659 struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); 1833 gaim_xfer_start(xfer, xfer->fd, NULL, 0);
1660 1834
1661 oft->xfer = xfer; 1835 return 0;
1662 oft->totsize = totsize;
1663 oft->totfiles = totfiles;
1664 oft->filesdone = 0;
1665
1666 oft->conn = aim_sendfile_initiate(od->sess, oft->sn,
1667 name, totfiles, oft->totsize, oft->cookie);
1668 if (!oft->conn) {
1669 do_error_dialog(_("Couldn't open listener to send file"),
1670 _("File transfer aborted"),
1671 GAIM_ERROR);
1672 return;
1673 }
1674
1675 aim_conn_addhandler(od->sess, oft->conn, AIM_CB_FAM_OFT,
1676 AIM_CB_OFT_SENDFILEINITIATE,
1677 oscar_sendfile_accepted,
1678 0);
1679 oft->watcher = gaim_input_add(oft->conn->fd, GAIM_INPUT_READ,
1680 oscar_callback, oft->conn);
1681 } 1836 }
1682 1837
1683 /* 1838 /*
1684 * This is called after a chunk of data has been sent out or received; it is used 1839 * We are sending a file to someone else. They have just acknowledged are
1685 * to update the checksum. 1840 * prompt, so we want to start sending data like there's no tomorrow.
1686 */ 1841 */
1687 static void oscar_file_transfer_data_chunk(struct gaim_connection *gc, 1842 static int oscar_sendfile_ack(aim_session_t *sess, aim_frame_t *fr, ...) {
1688 struct file_transfer *xfer, const char *buf, int len) 1843 struct gaim_connection *gc = sess->aux_data;
1689 { 1844 struct oscar_data *od = gc->proto_data;
1690 struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); 1845 struct gaim_xfer *xfer;
1691 aim_session_t *sess = aim_conn_getsess(oft->conn); 1846 va_list ap;
1692 1847 aim_conn_t *conn;
1693 if (oft->type == OFT_SENDFILE_IN) 1848 fu8_t *cookie;
1694 aim_update_checksum(sess, oft->conn, buf, len); 1849 struct aim_fileheader_t *fh;
1695 } 1850 debug_printf("AAA - in oscar_sendfile_ack\n");
1696 1851
1697 /* Called once at the beginning of an incoming transfer session. */ 1852 va_start(ap, fr);
1698 static void oscar_file_transfer_in(struct gaim_connection *gc, 1853 conn = va_arg(ap, aim_conn_t *);
1699 struct file_transfer *xfer, int offset) { 1854 cookie = va_arg(ap, fu8_t *);
1700 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 1855 fh = va_arg(ap, struct aim_fileheader_t *);
1701 struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); 1856 va_end(ap);
1702 1857
1703 oft->xfer = xfer; 1858 if (!(xfer = oscar_find_xfer_by_cookie(od->file_transfers, cookie)))
1704 oft->conn = aim_accepttransfer(od->sess, od->conn, oft->sn, 1859 return 1;
1705 oft->cookie, oft->ip, 1860
1706 oft->port, 1861 gaim_xfer_start(xfer, xfer->fd, NULL, 0);
1707 AIM_CAPS_SENDFILE); 1862
1708 if (!oft->conn) { 1863 return 0;
1709 /* XXX implement reverse connections for receiving from behind a firewall */
1710 char *buf = g_strdup_printf("Couldn't connect to remote host");
1711 do_error_dialog(buf, NULL, GAIM_ERROR);
1712 g_free(buf);
1713 return;
1714 }
1715
1716 aim_conn_addhandler(od->sess, oft->conn, AIM_CB_FAM_OFT,
1717 AIM_CB_OFT_SENDFILEFILEREQ, oscar_file_transfer_do,
1718 0);
1719
1720 oft->watcher = gaim_input_add(oft->conn->fd, GAIM_INPUT_READ,
1721 oscar_callback, oft->conn);
1722 } 1864 }
1723 1865
1724 /* 1866 /*
1725 * This is called when the user began a file transfer, but subsequently canceled. 1867 * We just sent a file to someone. They said they got it and everything,
1868 * so we can close our direct connection and what not.
1726 */ 1869 */
1727 static void oscar_file_transfer_cancel(struct gaim_connection *gc, struct file_transfer *xfer) { 1870 static int oscar_sendfile_done(aim_session_t *sess, aim_frame_t *fr, ...) {
1728 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 1871 struct gaim_connection *gc = sess->aux_data;
1729 struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer); 1872 struct oscar_data *od = gc->proto_data;
1730 1873 struct gaim_xfer *xfer;
1731 if (oft->type == OFT_SENDFILE_IN) 1874 va_list ap;
1732 aim_denytransfer(od->sess, oft->sn, oft->cookie, 1875 aim_conn_t *conn;
1733 AIM_TRANSFER_DENY_DECLINE); 1876 fu8_t *cookie;
1734 1877 struct aim_fileheader_t *fh;
1735 od->file_transfers = g_slist_remove(od->file_transfers, oft); 1878 debug_printf("AAA - in oscar_sendfile_done\n");
1736 aim_conn_kill(od->sess, &oft->conn); 1879
1737 g_free(oft->sn); 1880 va_start(ap, fr);
1738 g_free(oft); 1881 conn = va_arg(ap, aim_conn_t *);
1739 } 1882 cookie = va_arg(ap, fu8_t *);
1740 #endif 1883 fh = va_arg(ap, struct aim_fileheader_t *);
1884 va_end(ap);
1885
1886 if (!(xfer = oscar_find_xfer_by_conn(od->file_transfers, conn)))
1887 return 1;
1888
1889 gaim_xfer_set_completed(xfer, TRUE);
1890 gaim_xfer_end(xfer);
1891
1892 return 0;
1893 }
1741 1894
1742 static void accept_direct_im(struct ask_direct *d) { 1895 static void accept_direct_im(struct ask_direct *d) {
1743 struct gaim_connection *gc = d->gc; 1896 struct gaim_connection *gc = d->gc;
1744 struct oscar_data *od; 1897 struct oscar_data *od;
1745 struct direct_im *dim; 1898 struct direct_im *dim;
1761 } 1914 }
1762 dim = g_new0(struct direct_im, 1); 1915 dim = g_new0(struct direct_im, 1);
1763 dim->gc = d->gc; 1916 dim->gc = d->gc;
1764 g_snprintf(dim->name, sizeof dim->name, "%s", d->sn); 1917 g_snprintf(dim->name, sizeof dim->name, "%s", d->sn);
1765 1918
1766 dim->conn = aim_directim_connect(od->sess, d->sn, NULL, d->cookie); 1919 dim->conn = aim_odc_connect(od->sess, d->sn, NULL, d->cookie);
1767 if (!dim->conn) { 1920 if (!dim->conn) {
1768 g_free(dim); 1921 g_free(dim);
1769 cancel_direct_im(d); 1922 cancel_direct_im(d);
1770 return; 1923 return;
1771 } 1924 }
1772 1925
1773 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, 1926 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING,
1774 gaim_directim_incoming, 0); 1927 gaim_odc_incoming, 0);
1775 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, 1928 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING,
1776 gaim_directim_typing, 0); 1929 gaim_odc_typing, 0);
1777 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_IMAGETRANSFER, 1930 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_IMAGETRANSFER,
1778 gaim_update_ui, 0); 1931 gaim_update_ui, 0);
1779 for (i = 0; i < (int)strlen(d->ip); i++) { 1932 for (i = 0; i < (int)strlen(d->ip); i++) {
1780 if (d->ip[i] == ':') { 1933 if (d->ip[i] == ':') {
1781 port = atoi(&(d->ip[i+1])); 1934 port = atoi(&(d->ip[i+1]));
1782 break; 1935 break;
1783 } 1936 }
1784 } 1937 }
1785 host = g_strndup(d->ip, i); 1938 host = g_strndup(d->ip, i);
1786 dim->conn->status |= AIM_CONN_STATUS_INPROGRESS; 1939 dim->conn->status |= AIM_CONN_STATUS_INPROGRESS;
1787 rc = proxy_connect(host, port, oscar_directim_callback, dim); 1940 rc = proxy_connect(host, port, oscar_odc_callback, dim);
1788 g_free(host); 1941 g_free(host);
1789 if (rc < 0) { 1942 if (rc < 0) {
1790 aim_conn_kill(od->sess, &dim->conn); 1943 aim_conn_kill(od->sess, &dim->conn);
1791 g_free(dim); 1944 g_free(dim);
1792 cancel_direct_im(d); 1945 cancel_direct_im(d);
1842 char *buf = g_malloc(st.st_size); 1995 char *buf = g_malloc(st.st_size);
1843 file = fopen(gc->account->iconfile, "rb"); 1996 file = fopen(gc->account->iconfile, "rb");
1844 if (file) { 1997 if (file) {
1845 int len = fread(buf, 1, st.st_size, file); 1998 int len = fread(buf, 1, st.st_size, file);
1846 debug_printf("Sending buddy icon to %s (%d bytes, %lu reported)\n", 1999 debug_printf("Sending buddy icon to %s (%d bytes, %lu reported)\n",
1847 userinfo->sn, len, st.st_size); 2000 userinfo->sn, len, st.st_size);
1848 aim_send_icon(sess, userinfo->sn, buf, st.st_size, 2001 aim_im_sendch2_icon(sess, userinfo->sn, buf, st.st_size,
1849 st.st_mtime, aim_iconsum(buf, st.st_size)); 2002 st.st_mtime, aimutil_iconsum(buf, st.st_size));
1850 fclose(file); 2003 fclose(file);
1851 } else 2004 } else
1852 debug_printf("Can't open buddy icon file!\n"); 2005 debug_printf("Can't open buddy icon file!\n");
1853 g_free(buf); 2006 g_free(buf);
1854 } else 2007 } else
1910 return 1; 2063 return 1;
1911 } 2064 }
1912 2065
1913 static int incomingim_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args) { 2066 static int incomingim_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args) {
1914 struct gaim_connection *gc = sess->aux_data; 2067 struct gaim_connection *gc = sess->aux_data;
2068 struct oscar_data *od = gc->proto_data;
1915 2069
1916 if (!args) 2070 if (!args)
1917 return 0; 2071 return 0;
1918 2072
1919 debug_printf("rendezvous status %hu (%s)\n", args->status, userinfo->sn); 2073 debug_printf("rendezvous with %s, status is %hu\n", userinfo->sn, args->status);
1920
1921 if (args->status == AIM_RENDEZVOUS_CANCEL) {
1922 #if 0
1923 struct oscar_file_transfer *oft;
1924 if (!args->cookie)
1925 return 1;
1926 oft = find_oft_by_cookie(gc, args->cookie);
1927 if (oft) {
1928 transfer_abort(oft->xfer, _("Buddy canceled transfer"));
1929 oscar_file_transfer_disconnect(sess, oft->conn);
1930 }
1931 return 0;
1932 #endif
1933 }
1934 else if (args->status == AIM_RENDEZVOUS_ACCEPT) {
1935 #if 0
1936 /* The user accepted our transfer request, but we don't
1937 * really need to do anything yet.
1938 * -- wtm
1939 */
1940 return 0;
1941 #endif
1942 }
1943 else if (args->status != AIM_RENDEZVOUS_PROPOSE) {
1944 debug_printf("unknown rendezvous status\n");
1945 return 1;
1946 }
1947 2074
1948 if (args->reqclass & AIM_CAPS_CHAT) { 2075 if (args->reqclass & AIM_CAPS_CHAT) {
1949 char *name; 2076 char *name;
1950 int *exch; 2077 int *exch;
1951 GList *m = NULL; 2078 GList *m = NULL;
1963 (char *)args->msg, 2090 (char *)args->msg,
1964 m); 2091 m);
1965 if (name) 2092 if (name)
1966 g_free(name); 2093 g_free(name);
1967 } else if (args->reqclass & AIM_CAPS_SENDFILE) { 2094 } else if (args->reqclass & AIM_CAPS_SENDFILE) {
1968 #if 0 2095 /* BBB */
1969 struct oscar_file_transfer *oft; 2096 if (args->status == AIM_RENDEZVOUS_PROPOSE) {
1970 struct oscar_data *od = gc->proto_data; 2097 /* Someone wants to send a file (or files) to us */
1971 char *tmp; 2098 struct gaim_xfer *xfer;
1972 2099 struct oscar_xfer_data *xfer_data;
1973 if (!args->cookie || !args->verifiedip || !args->port || 2100
1974 !args->info.sendfile.filename || !args->info.sendfile.totsize || 2101 /* XXX - Should do something with args->clientip or args->clientip2 */
1975 !args->info.sendfile.totfiles || !args->reqclass) 2102 if (!args->cookie || !args->verifiedip || !args->port ||
1976 return 1; 2103 !args->info.sendfile.filename || !args->info.sendfile.totsize ||
1977 if ((oft = find_oft_by_cookie(sess->aux_data, args->cookie))) 2104 !args->info.sendfile.totfiles || !args->reqclass)
1978 { 2105 return 1;
1979 /* This is a request for a reverse connection, 2106
1980 * which is used by newer clients when for some 2107 if (args->info.sendfile.subtype == AIM_OFT_SUBTYPE_SEND_DIR) {
1981 * reason they are unable to connect to our listener 2108 /* last char of the ft req is a star, they are sending us a
1982 * (e.g. they are behind a firewall). 2109 * directory -- remove the star and trailing slash so we dont save
2110 * directories that look like 'dirname\*' -- arl */
2111 char *tmp = strrchr(args->info.sendfile.filename, '\\');
2112 if (tmp && (tmp[1] == '*')) {
2113 tmp[0] = '\0';
2114 }
2115 }
2116
2117 /* Setup the oscar-specific transfer xfer_data */
2118 xfer_data = g_malloc0(sizeof(struct oscar_xfer_data));
2119 xfer_data->gc = gc;
2120 memcpy(xfer_data->cookie, args->cookie, 8);
2121
2122 /* Build the file transfer handle */
2123 xfer = gaim_xfer_new(gc->account, GAIM_XFER_RECEIVE, userinfo->sn);
2124 xfer_data->xfer = xfer;
2125 xfer->data = xfer_data;
2126
2127 /* Set the info about the incoming file */
2128 gaim_xfer_set_filename(xfer, args->info.sendfile.filename);
2129 gaim_xfer_set_size(xfer, args->info.sendfile.totsize);
2130 /* XXX - xfer->remote_ip = g_strdup(args->verifiedip); */
2131 xfer->remote_ip = g_strdup(args->clientip2);
2132 xfer->remote_port = args->port;
2133
2134 /* Setup our I/O op functions */
2135 gaim_xfer_set_init_fnc(xfer, oscar_xfer_init);
2136 gaim_xfer_set_start_fnc(xfer, oscar_xfer_start);
2137 gaim_xfer_set_end_fnc(xfer, oscar_xfer_end);
2138 gaim_xfer_set_cancel_fnc(xfer, oscar_xfer_cancel);
2139 gaim_xfer_set_ack_fnc(xfer, oscar_xfer_ack);
2140
2141 /*
2142 * XXX - Should do something with args->msg, args->encoding, and args->language
2143 * probably make it apply to all ch2 messages.
1983 */ 2144 */
1984 if (oft->type != OFT_SENDFILE_OUT) 2145
1985 return -1; 2146 /* Keep track of this transfer for later */
1986 2147 od->file_transfers = g_slist_append(od->file_transfers, xfer);
1987 /* It seems that Trillian sends some weird 2148
1988 * packets. Sanity check. 2149 /* Now perform the request */
2150 gaim_xfer_request(xfer);
2151 } else if (args->status == AIM_RENDEZVOUS_CANCEL) {
2152 /* The other user wants to cancel a file transfer */
2153 struct gaim_xfer *xfer;
2154 debug_printf("AAA - File transfer canceled by remote user\n");
2155 if ((xfer = oscar_find_xfer_by_cookie(od->file_transfers, args->cookie)))
2156 gaim_xfer_cancel(xfer);
2157 } else if (args->status == AIM_RENDEZVOUS_ACCEPT) {
2158 /*
2159 * This gets sent by the receiver of a file
2160 * as they connect directly to us. If we don't
2161 * get this, then maybe a third party connected
2162 * to us, and we shouldn't send them anything.
1989 */ 2163 */
1990 if (!args->verifiedip) 2164 } else {
1991 return -1; 2165 debug_printf("unknown rendezvous status!\n");
1992 2166 }
1993 /* This connection isn't used for anything, since
1994 * we're using a reverse connection instead.
1995 */
1996 gaim_input_remove(oft->watcher);
1997 aim_conn_kill(sess, &oft->conn);
1998
1999 debug_printf("sendfile: doing reverse connection to %s:%hu\n", args->verifiedip, args->port);
2000
2001 oft->conn = aim_accepttransfer(sess, od->conn,
2002 userinfo->sn,
2003 args->cookie, args->verifiedip,
2004 args->port,
2005 AIM_CAPS_SENDFILE);
2006
2007 /* XXX: this is a bit of a hack: ideally
2008 * we should wait on GAIM_INPUT_WRITE. -- wtm
2009 */
2010 aim_conn_completeconnect(sess, oft->conn);
2011
2012 oscar_sendfile_request(sess, oft);
2013
2014 aim_conn_addhandler(sess, oft->conn,
2015 AIM_CB_FAM_OFT,
2016 AIM_CB_OFT_SENDFILECOMPLETE,
2017 oscar_sendfile_out_done,
2018 0);
2019 aim_conn_addhandler(sess, oft->conn,
2020 AIM_CB_FAM_OFT,
2021 AIM_CB_OFT_SENDFILEFILESEND,
2022 oscar_file_transfer_do,
2023 0);
2024 oft->watcher = gaim_input_add(oft->conn->fd,
2025 GAIM_INPUT_READ, oscar_callback,
2026 oft->conn);
2027 return 0;
2028 }
2029
2030 /* Someone wants to send a file (or files) to us */
2031 debug_printf("%s (%s) requests to send a file to %s\n",
2032 userinfo->sn, args->verifiedip, gc->username);
2033
2034 oft = g_new0(struct oscar_file_transfer, 1);
2035
2036 oft->type = OFT_SENDFILE_IN;
2037 oft->sn = g_strdup(userinfo->sn);
2038 strncpy(oft->ip, args->verifiedip, sizeof(oft->ip));
2039 oft->port = args->port;
2040 memcpy(oft->cookie, args->cookie, 8);
2041
2042 od->file_transfers = g_slist_append(od->file_transfers, oft);
2043
2044 /* last char of the ft req is a star, they are sending us a
2045 * directory -- remove the star and trailing slash so we dont save
2046 * directories that look like 'dirname\*' -- arl */
2047 tmp = strrchr(args->info.sendfile.filename, '\\');
2048 if (tmp && (tmp[1] == '*')) {
2049 tmp[0] = '\0';
2050 }
2051
2052 oft->xfer = transfer_in_add(gc, userinfo->sn,
2053 args->info.sendfile.filename,
2054 args->info.sendfile.totsize,
2055 args->info.sendfile.totfiles,
2056 args->msg);
2057 #endif
2058 } else if (args->reqclass & AIM_CAPS_GETFILE) { 2167 } else if (args->reqclass & AIM_CAPS_GETFILE) {
2059 } else if (args->reqclass & AIM_CAPS_VOICE) { 2168 } else if (args->reqclass & AIM_CAPS_VOICE) {
2060 } else if (args->reqclass & AIM_CAPS_BUDDYICON) { 2169 } else if (args->reqclass & AIM_CAPS_BUDDYICON) {
2061 set_icon_data(gc, normalize(userinfo->sn), args->info.icon.icon, 2170 set_icon_data(gc, normalize(userinfo->sn), args->info.icon.icon,
2062 args->info.icon.length); 2171 args->info.icon.length);
2153 #ifdef NOSSI 2262 #ifdef NOSSI
2154 struct buddy *buddy; 2263 struct buddy *buddy;
2155 gchar message; 2264 gchar message;
2156 message = 0; 2265 message = 0;
2157 buddy = find_buddy(gc->account, data->name); 2266 buddy = find_buddy(gc->account, data->name);
2158 aim_send_im_ch4(od->sess, data->name, AIM_ICQMSG_AUTHGRANTED, &message); 2267 aim_im_sendch4(od->sess, data->name, AIM_ICQMSG_AUTHGRANTED, &message);
2159 show_got_added(gc, NULL, data->name, (buddy ? get_buddy_alias_only(buddy) : NULL), NULL); 2268 show_got_added(gc, NULL, data->name, (buddy ? get_buddy_alias_only(buddy) : NULL), NULL);
2160 #else 2269 #else
2161 aim_ssi_sendauthreply(od->sess, od->conn, data->name, 0x01, NULL); 2270 aim_ssi_sendauthreply(od->sess, od->conn, data->name, 0x01, NULL);
2162 #endif 2271 #endif
2163 } 2272 }
2170 struct gaim_connection *gc = data->gc; 2279 struct gaim_connection *gc = data->gc;
2171 2280
2172 if (g_slist_find(connections, gc)) { 2281 if (g_slist_find(connections, gc)) {
2173 struct oscar_data *od = gc->proto_data; 2282 struct oscar_data *od = gc->proto_data;
2174 #ifdef NOSSI 2283 #ifdef NOSSI
2175 aim_send_im_ch4(od->sess, data->name, AIM_ICQMSG_AUTHDENIED, msg ? msg : _("No reason given.")); 2284 aim_im_sendch4(od->sess, data->name, AIM_ICQMSG_AUTHDENIED, msg ? msg : _("No reason given."));
2176 #else 2285 #else
2177 aim_ssi_sendauthreply(od->sess, od->conn, data->name, 0x00, msg ? msg : _("No reason given.")); 2286 aim_ssi_sendauthreply(od->sess, od->conn, data->name, 0x00, msg ? msg : _("No reason given."));
2178 #endif 2287 #endif
2179 } 2288 }
2180 } 2289 }
2476 return g_strdup_printf(_("Online")); 2585 return g_strdup_printf(_("Online"));
2477 } 2586 }
2478 2587
2479 static int gaim_parse_clientauto_ch2(aim_session_t *sess, const char *who, fu16_t reason, const char *cookie) { 2588 static int gaim_parse_clientauto_ch2(aim_session_t *sess, const char *who, fu16_t reason, const char *cookie) {
2480 struct gaim_connection *gc = sess->aux_data; 2589 struct gaim_connection *gc = sess->aux_data;
2481 2590 struct oscar_data *od = gc->proto_data;
2591
2592 /* BBB */
2482 switch (reason) { 2593 switch (reason) {
2483 case 3: { /* Decline sendfile. */ 2594 case 3: { /* Decline sendfile. */
2484 #if 0 2595 struct gaim_xfer *xfer;
2485 struct oscar_file_transfer *oft = find_oft_by_cookie(gc, cookie); 2596 debug_printf("AAA - Other user declined file transfer\n");
2486 2597 if ((xfer = oscar_find_xfer_by_cookie(od->file_transfers, cookie)))
2487 if (oft) { 2598 gaim_xfer_cancel(xfer);
2488 char *buf = g_strdup_printf(_("%s has declined to receive a file from %s.\n"),
2489 who, gc->username);
2490 transfer_abort(oft->xfer, buf);
2491 g_free(buf);
2492 oscar_file_transfer_disconnect(sess, oft->conn);
2493 }
2494 #endif
2495 } break; 2599 } break;
2496 2600
2497 default: { 2601 default: {
2498 debug_printf("Received an unknown rendezvous client auto-response from %s. Type 0x%04hx\n", who, reason); 2602 debug_printf("Received an unknown rendezvous client auto-response from %s. Type 0x%04hx\n", who, reason);
2499 } 2603 }
2596 2700
2597 return 1; 2701 return 1;
2598 } 2702 }
2599 2703
2600 static int gaim_parse_msgerr(aim_session_t *sess, aim_frame_t *fr, ...) { 2704 static int gaim_parse_msgerr(aim_session_t *sess, aim_frame_t *fr, ...) {
2705 #if 0
2706 struct gaim_connection *gc = sess->aux_data;
2707 struct oscar_data *od = gc->proto_data;
2708 struct gaim_xfer *xfer;
2709 #endif
2601 va_list ap; 2710 va_list ap;
2602 char *data;
2603 fu16_t reason; 2711 fu16_t reason;
2604 char buf[1024]; 2712 char *data, *buf;
2605 struct gaim_connection *gc = sess->aux_data;
2606
2607 #if 0
2608 struct oscar_file_transfer *oft;
2609 #endif
2610 2713
2611 va_start(ap, fr); 2714 va_start(ap, fr);
2612 reason = (fu16_t) va_arg(ap, unsigned int); 2715 reason = (fu16_t)va_arg(ap, unsigned int);
2613 data = va_arg(ap, char *); 2716 data = va_arg(ap, char *);
2614 va_end(ap); 2717 va_end(ap);
2615 2718
2719 debug_printf("Message error with data %s and reason %hu\n", data, reason);
2720
2721 /* BBB */
2616 #if 0 2722 #if 0
2617 /* If this was a file transfer request, data is a cookie. */ 2723 /* If this was a file transfer request, data is a cookie */
2618 if ((oft = find_oft_by_cookie(gc, data))) { 2724 if ((xfer = oscar_find_xfer_by_cookie(od->file_transfers, data))) {
2619 transfer_abort(oft->xfer, 2725 gaim_xfer_cancel(xfer);
2620 (reason < msgerrreasonlen) ? gettext(msgerrreason[reason]) : _("No reason given."));
2621
2622 oscar_file_transfer_disconnect(sess, oft->conn);
2623 return 1; 2726 return 1;
2624 } 2727 }
2625 #endif 2728 #endif
2626 2729
2627 /* Data is assumed to be the destination sn. */ 2730 /* Data is assumed to be the destination sn */
2628 snprintf(buf, sizeof(buf), _("Your message to %s did not get sent:"), data); 2731 buf = g_strdup_printf(_("Your message to %s did not get sent:"), data);
2629 do_error_dialog(buf, (reason < msgerrreasonlen) ? gettext(msgerrreason[reason]) : _("No reason given."), GAIM_ERROR); 2732 do_error_dialog(buf, (reason < msgerrreasonlen) ? gettext(msgerrreason[reason]) : _("No reason given."), GAIM_ERROR);
2733 g_free(buf);
2630 2734
2631 return 1; 2735 return 1;
2632 } 2736 }
2633 2737
2634 static int gaim_parse_mtn(aim_session_t *sess, aim_frame_t *fr, ...) { 2738 static int gaim_parse_mtn(aim_session_t *sess, aim_frame_t *fr, ...) {
2905 3009
2906 static int gaim_chatnav_info(aim_session_t *sess, aim_frame_t *fr, ...) { 3010 static int gaim_chatnav_info(aim_session_t *sess, aim_frame_t *fr, ...) {
2907 va_list ap; 3011 va_list ap;
2908 fu16_t type; 3012 fu16_t type;
2909 struct gaim_connection *gc = sess->aux_data; 3013 struct gaim_connection *gc = sess->aux_data;
2910 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; 3014 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
2911 3015
2912 va_start(ap, fr); 3016 va_start(ap, fr);
2913 type = (fu16_t) va_arg(ap, unsigned int); 3017 type = (fu16_t) va_arg(ap, unsigned int);
2914 3018
2915 switch(type) { 3019 switch(type) {
2925 debug_printf("chat info: Chat Rights:\n"); 3029 debug_printf("chat info: Chat Rights:\n");
2926 debug_printf("chat info: \tMax Concurrent Rooms: %hhd\n", maxrooms); 3030 debug_printf("chat info: \tMax Concurrent Rooms: %hhd\n", maxrooms);
2927 debug_printf("chat info: \tExchange List: (%d total)\n", exchangecount); 3031 debug_printf("chat info: \tExchange List: (%d total)\n", exchangecount);
2928 for (i = 0; i < exchangecount; i++) 3032 for (i = 0; i < exchangecount; i++)
2929 debug_printf("chat info: \t\t%hu %s\n", exchanges[i].number, exchanges[i].name ? exchanges[i].name : ""); 3033 debug_printf("chat info: \t\t%hu %s\n", exchanges[i].number, exchanges[i].name ? exchanges[i].name : "");
2930 while (odata->create_rooms) { 3034 while (od->create_rooms) {
2931 struct create_room *cr = odata->create_rooms->data; 3035 struct create_room *cr = od->create_rooms->data;
2932 debug_printf("creating room %s\n", cr->name); 3036 debug_printf("creating room %s\n", cr->name);
2933 aim_chatnav_createroom(sess, fr->conn, cr->name, cr->exchange); 3037 aim_chatnav_createroom(sess, fr->conn, cr->name, cr->exchange);
2934 g_free(cr->name); 3038 g_free(cr->name);
2935 odata->create_rooms = g_slist_remove(odata->create_rooms, cr); 3039 od->create_rooms = g_slist_remove(od->create_rooms, cr);
2936 g_free(cr); 3040 g_free(cr);
2937 } 3041 }
2938 } 3042 }
2939 break; 3043 break;
2940 case 0x0008: { 3044 case 0x0008: {
2959 fqcn, 3063 fqcn,
2960 exchange, instance, flags, 3064 exchange, instance, flags,
2961 createtime, 3065 createtime,
2962 maxmsglen, maxoccupancy, createperms, unknown, 3066 maxmsglen, maxoccupancy, createperms, unknown,
2963 name, ck); 3067 name, ck);
2964 aim_chat_join(odata->sess, odata->conn, exchange, ck, instance); 3068 aim_chat_join(od->sess, od->conn, exchange, ck, instance);
2965 } 3069 }
2966 break; 3070 break;
2967 default: 3071 default:
2968 debug_printf("chatnav info: unknown type (%04hx)\n", type); 3072 debug_printf("chatnav info: unknown type (%04hx)\n", type);
2969 break; 3073 break;
3082 emailinfo = va_arg(ap, struct aim_emailinfo *); 3186 emailinfo = va_arg(ap, struct aim_emailinfo *);
3083 havenewmail = va_arg(ap, int); 3187 havenewmail = va_arg(ap, int);
3084 va_end(ap); 3188 va_end(ap);
3085 3189
3086 if (emailinfo) { 3190 if (emailinfo) {
3087 debug_printf("Got email info. domain is %s, webmail is %s, new email: %hhu, number new: %hu, flag is %hu, havenewmail is %d\n", emailinfo->domain, emailinfo->url, emailinfo->unread, emailinfo->nummsgs, emailinfo->flag, havenewmail);
3088 if (emailinfo->unread) { 3191 if (emailinfo->unread) {
3089 if (havenewmail) 3192 if (havenewmail)
3090 connection_has_mail(gc, emailinfo->nummsgs ? emailinfo->nummsgs : -1, NULL, NULL, emailinfo->url); 3193 connection_has_mail(gc, emailinfo->nummsgs ? emailinfo->nummsgs : -1, NULL, NULL, emailinfo->url);
3091 } else 3194 } else
3092 connection_has_mail(gc, 0, NULL, NULL, emailinfo->url); 3195 connection_has_mail(gc, 0, NULL, NULL, emailinfo->url);
3205 aim_ssi_reqdata(sess, fr->conn, sess->ssi.timestamp, sess->ssi.numitems); 3308 aim_ssi_reqdata(sess, fr->conn, sess->ssi.timestamp, sess->ssi.numitems);
3206 #endif 3309 #endif
3207 3310
3208 aim_bos_reqlocaterights(sess, fr->conn); 3311 aim_bos_reqlocaterights(sess, fr->conn);
3209 aim_bos_reqbuddyrights(sess, fr->conn); 3312 aim_bos_reqbuddyrights(sess, fr->conn);
3210 aim_reqicbmparams(sess); 3313 aim_im_reqparams(sess);
3211 aim_bos_reqrights(sess, fr->conn); 3314 aim_bos_reqrights(sess, fr->conn);
3212 3315
3213 #ifdef NOSSI 3316 #ifdef NOSSI
3214 aim_bos_setgroupperm(sess, fr->conn, AIM_FLAG_ALLUSERS); 3317 aim_bos_setgroupperm(sess, fr->conn, AIM_FLAG_ALLUSERS);
3215 aim_bos_setprivacyflags(sess, fr->conn, AIM_PRIVFLAGS_ALLOWIDLE | AIM_PRIVFLAGS_ALLOWMEMBERSINCE); 3318 aim_bos_setprivacyflags(sess, fr->conn, AIM_PRIVFLAGS_ALLOWIDLE | AIM_PRIVFLAGS_ALLOWMEMBERSINCE);
3280 /* Maybe senderwarn and recverwarn should be user preferences... */ 3383 /* Maybe senderwarn and recverwarn should be user preferences... */
3281 params->flags = 0x0000000b; 3384 params->flags = 0x0000000b;
3282 params->maxmsglen = 8000; 3385 params->maxmsglen = 8000;
3283 params->minmsginterval = 0; 3386 params->minmsginterval = 0;
3284 3387
3285 aim_seticbmparam(sess, params); 3388 aim_im_setparams(sess, params);
3286 3389
3287 return 1; 3390 return 1;
3288 } 3391 }
3289 3392
3290 static int gaim_parse_locaterights(aim_session_t *sess, aim_frame_t *fr, ...) 3393 static int gaim_parse_locaterights(aim_session_t *sess, aim_frame_t *fr, ...)
3291 { 3394 {
3292 va_list ap; 3395 va_list ap;
3293 fu16_t maxsiglen; 3396 fu16_t maxsiglen;
3294 struct gaim_connection *gc = sess->aux_data; 3397 struct gaim_connection *gc = sess->aux_data;
3295 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; 3398 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
3296 char *unicode; 3399 char *unicode;
3297 int unicode_len; 3400 int unicode_len;
3298 fu32_t flags; 3401 fu32_t flags;
3299 3402
3300 va_start(ap, fr); 3403 va_start(ap, fr);
3301 maxsiglen = (fu16_t) va_arg(ap, int); 3404 maxsiglen = (fu16_t) va_arg(ap, int);
3302 va_end(ap); 3405 va_end(ap);
3303 3406
3304 debug_printf("locate rights: max sig len = %d\n", maxsiglen); 3407 debug_printf("locate rights: max sig len = %d\n", maxsiglen);
3305 3408
3306 odata->rights.maxsiglen = odata->rights.maxawaymsglen = (guint)maxsiglen; 3409 od->rights.maxsiglen = od->rights.maxawaymsglen = (guint)maxsiglen;
3307 3410
3308 if (odata->icq) 3411 if (od->icq)
3309 aim_bos_setprofile(sess, fr->conn, NULL, NULL, 0, NULL, NULL, 0, caps_icq); 3412 aim_bos_setprofile(sess, fr->conn, NULL, NULL, 0, NULL, NULL, 0, caps_icq);
3310 else { 3413 else {
3311 flags = check_encoding (gc->account->user_info); 3414 flags = check_encoding (gc->account->user_info);
3312 3415
3313 if (flags == 0) { 3416 if (flags == 0) {
3327 3430
3328 static int gaim_parse_buddyrights(aim_session_t *sess, aim_frame_t *fr, ...) { 3431 static int gaim_parse_buddyrights(aim_session_t *sess, aim_frame_t *fr, ...) {
3329 va_list ap; 3432 va_list ap;
3330 fu16_t maxbuddies, maxwatchers; 3433 fu16_t maxbuddies, maxwatchers;
3331 struct gaim_connection *gc = sess->aux_data; 3434 struct gaim_connection *gc = sess->aux_data;
3332 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; 3435 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
3333 3436
3334 va_start(ap, fr); 3437 va_start(ap, fr);
3335 maxbuddies = (fu16_t) va_arg(ap, unsigned int); 3438 maxbuddies = (fu16_t) va_arg(ap, unsigned int);
3336 maxwatchers = (fu16_t) va_arg(ap, unsigned int); 3439 maxwatchers = (fu16_t) va_arg(ap, unsigned int);
3337 va_end(ap); 3440 va_end(ap);
3338 3441
3339 debug_printf("buddy list rights: Max buddies = %hu / Max watchers = %hu\n", maxbuddies, maxwatchers); 3442 debug_printf("buddy list rights: Max buddies = %hu / Max watchers = %hu\n", maxbuddies, maxwatchers);
3340 3443
3341 odata->rights.maxbuddies = (guint)maxbuddies; 3444 od->rights.maxbuddies = (guint)maxbuddies;
3342 odata->rights.maxwatchers = (guint)maxwatchers; 3445 od->rights.maxwatchers = (guint)maxwatchers;
3343 3446
3344 return 1; 3447 return 1;
3345 } 3448 }
3346 3449
3347 static int gaim_bosrights(aim_session_t *sess, aim_frame_t *fr, ...) { 3450 static int gaim_bosrights(aim_session_t *sess, aim_frame_t *fr, ...) {
3348 fu16_t maxpermits, maxdenies; 3451 fu16_t maxpermits, maxdenies;
3349 va_list ap; 3452 va_list ap;
3350 struct gaim_connection *gc = sess->aux_data; 3453 struct gaim_connection *gc = sess->aux_data;
3351 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; 3454 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
3352 3455
3353 va_start(ap, fr); 3456 va_start(ap, fr);
3354 maxpermits = (fu16_t) va_arg(ap, unsigned int); 3457 maxpermits = (fu16_t) va_arg(ap, unsigned int);
3355 maxdenies = (fu16_t) va_arg(ap, unsigned int); 3458 maxdenies = (fu16_t) va_arg(ap, unsigned int);
3356 va_end(ap); 3459 va_end(ap);
3357 3460
3358 debug_printf("BOS rights: Max permit = %hu / Max deny = %hu\n", maxpermits, maxdenies); 3461 debug_printf("BOS rights: Max permit = %hu / Max deny = %hu\n", maxpermits, maxdenies);
3359 3462
3360 odata->rights.maxpermits = (guint)maxpermits; 3463 od->rights.maxpermits = (guint)maxpermits;
3361 odata->rights.maxdenies = (guint)maxdenies; 3464 od->rights.maxdenies = (guint)maxdenies;
3362 3465
3363 account_online(gc); 3466 account_online(gc);
3364 serv_finish_login(gc); 3467 serv_finish_login(gc);
3365 3468
3366 debug_printf("buddy list loaded\n"); 3469 debug_printf("buddy list loaded\n");
3367 3470
3368 aim_clientready(sess, fr->conn); 3471 aim_clientready(sess, fr->conn);
3369 3472
3370 /* AAA - Should call aim_bos_setidle with 0x0000 */ 3473 /* XXX - Should call aim_bos_setidle with 0x0000 */
3371 3474
3372 /* AAA - Should only call reqofflinemsgs when using ICQ? */ 3475 /* XXX - Should only call reqofflinemsgs when using ICQ? */
3373 aim_icq_reqofflinemsgs(sess); 3476 aim_icq_reqofflinemsgs(sess);
3374 3477
3375 aim_reqservice(sess, fr->conn, AIM_CONN_TYPE_CHATNAV); 3478 aim_reqservice(sess, fr->conn, AIM_CONN_TYPE_CHATNAV);
3376 if (sess->authinfo->email) 3479 if (sess->authinfo->email)
3377 aim_reqservice(sess, fr->conn, AIM_CONN_TYPE_EMAIL); 3480 aim_reqservice(sess, fr->conn, AIM_CONN_TYPE_EMAIL);
3417 gchar who[16]; 3520 gchar who[16];
3418 3521
3419 va_start(ap, fr); 3522 va_start(ap, fr);
3420 info = va_arg(ap, struct aim_icq_info *); 3523 info = va_arg(ap, struct aim_icq_info *);
3421 va_end(ap); 3524 va_end(ap);
3525
3526 if (!info || !info->uin)
3527 return 1;
3422 3528
3423 g_snprintf(who, sizeof(who), "%lu", info->uin); 3529 g_snprintf(who, sizeof(who), "%lu", info->uin);
3424 buf = g_strdup_printf("<b>UIN:</b> %s<br>", who); 3530 buf = g_strdup_printf("<b>UIN:</b> %s<br>", who);
3425 if (info->nick) { 3531 if (info->nick) {
3426 tmp = buf; 3532 tmp = buf;
3481 gchar who[16]; 3587 gchar who[16];
3482 3588
3483 va_start(ap, fr); 3589 va_start(ap, fr);
3484 info = va_arg(ap, struct aim_icq_info *); 3590 info = va_arg(ap, struct aim_icq_info *);
3485 va_end(ap); 3591 va_end(ap);
3592
3593 if (!info || !info->uin)
3594 return 1;
3486 3595
3487 g_snprintf(who, sizeof(who), "%lu", info->uin); 3596 g_snprintf(who, sizeof(who), "%lu", info->uin);
3488 buf = g_strdup_printf("<b>UIN:</b> %s<br>", who); 3597 buf = g_strdup_printf("<b>UIN:</b> %s<br>", who);
3489 if (info->nick) { 3598 if (info->nick) {
3490 tmp = buf; 3599 tmp = buf;
3673 3782
3674 return 1; 3783 return 1;
3675 } 3784 }
3676 3785
3677 static void oscar_keepalive(struct gaim_connection *gc) { 3786 static void oscar_keepalive(struct gaim_connection *gc) {
3678 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; 3787 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
3679 aim_flap_nop(odata->sess, odata->conn); 3788 aim_flap_nop(od->sess, od->conn);
3680 } 3789 }
3681 3790
3682 static int oscar_send_typing(struct gaim_connection *gc, char *name, int typing) { 3791 static int oscar_send_typing(struct gaim_connection *gc, char *name, int typing) {
3683 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; 3792 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
3684 struct direct_im *dim = find_direct_im(odata, name); 3793 struct direct_im *dim = find_direct_im(od, name);
3685 if (dim) 3794 if (dim)
3686 aim_send_typing(odata->sess, dim->conn, typing); 3795 aim_odc_send_typing(od->sess, dim->conn, typing);
3687 else { 3796 else {
3688 if (g_hash_table_lookup(odata->supports_tn, normalize(name))) { 3797 if (g_hash_table_lookup(od->supports_tn, normalize(name))) {
3689 if (typing == TYPING) 3798 if (typing == TYPING)
3690 aim_mtn_send(odata->sess, 0x0001, name, 0x0002); 3799 aim_im_sendmtn(od->sess, 0x0001, name, 0x0002);
3691 else if (typing == TYPED) 3800 else if (typing == TYPED)
3692 aim_mtn_send(odata->sess, 0x0001, name, 0x0001); 3801 aim_im_sendmtn(od->sess, 0x0001, name, 0x0001);
3693 else 3802 else
3694 aim_mtn_send(odata->sess, 0x0001, name, 0x0000); 3803 aim_im_sendmtn(od->sess, 0x0001, name, 0x0000);
3695 } 3804 }
3696 } 3805 }
3697 return 0; 3806 return 0;
3698 } 3807 }
3699 static void oscar_ask_direct_im(struct gaim_connection *gc, char *name); 3808 static void oscar_ask_direct_im(struct gaim_connection *gc, char *name);
3700 3809
3701 static int oscar_send_im(struct gaim_connection *gc, char *name, char *message, int len, int imflags) { 3810 static int oscar_send_im(struct gaim_connection *gc, char *name, char *message, int len, int imflags) {
3702 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; 3811 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
3703 struct direct_im *dim = find_direct_im(odata, name); 3812 struct direct_im *dim = find_direct_im(od, name);
3704 int ret = 0; 3813 int ret = 0;
3705 GError *err = NULL; 3814 GError *err = NULL;
3706 3815
3707 if (dim) { 3816 if (dim) {
3708 if (dim->connected) { /* If we're not connected yet, send through server */ 3817 if (dim->connected) { /* If we're not connected yet, send through server */
3709 /* AAA - The last parameter below is the encoding. Let Paco-Paco do something with it. */ 3818 /* XXX - The last parameter below is the encoding. Let Paco-Paco do something with it. */
3710 ret = aim_send_im_direct(odata->sess, dim->conn, message, len == -1 ? strlen(message) : len, 0); 3819 ret = aim_odc_send_im(od->sess, dim->conn, message, len == -1 ? strlen(message) : len, 0);
3711 if (ret == 0) 3820 if (ret == 0)
3712 return 1; 3821 return 1;
3713 else return ret; 3822 else return ret;
3714 } 3823 }
3715 debug_printf("Direct IM pending, but not connected; sending through server\n"); 3824 debug_printf("Direct IM pending, but not connected; sending through server\n");
3717 /* Trying to send an IM image outside of a direct connection. */ 3826 /* Trying to send an IM image outside of a direct connection. */
3718 oscar_ask_direct_im(gc, name); 3827 oscar_ask_direct_im(gc, name);
3719 return -ENOTCONN; 3828 return -ENOTCONN;
3720 } 3829 }
3721 if (imflags & IM_FLAG_AWAY) { 3830 if (imflags & IM_FLAG_AWAY) {
3722 ret = aim_send_im(odata->sess, name, AIM_IMFLAGS_AWAY, message); 3831 ret = aim_im_sendch1(od->sess, name, AIM_IMFLAGS_AWAY, message);
3723 } else { 3832 } else {
3724 struct aim_sendimext_args args; 3833 struct aim_sendimext_args args;
3725 GSList *h = odata->hasicons; 3834 GSList *h = od->hasicons;
3726 struct icon_req *ir = NULL; 3835 struct icon_req *ir = NULL;
3727 char *who = normalize(name); 3836 char *who = normalize(name);
3728 struct stat st; 3837 struct stat st;
3729 int len; 3838 int len;
3730 3839
3731 args.flags = AIM_IMFLAGS_ACK | AIM_IMFLAGS_CUSTOMFEATURES; 3840 args.flags = AIM_IMFLAGS_ACK | AIM_IMFLAGS_CUSTOMFEATURES;
3732 if (odata->icq) 3841 if (od->icq)
3733 args.flags |= AIM_IMFLAGS_OFFLINE; 3842 args.flags |= AIM_IMFLAGS_OFFLINE;
3734 3843
3735 args.features = gaim_features; 3844 args.features = gaim_features;
3736 args.featureslen = sizeof(gaim_features); 3845 args.featureslen = sizeof(gaim_features);
3737 3846
3752 if (file) { 3861 if (file) {
3753 char *buf = g_malloc(st.st_size); 3862 char *buf = g_malloc(st.st_size);
3754 fread(buf, 1, st.st_size, file); 3863 fread(buf, 1, st.st_size, file);
3755 3864
3756 args.iconlen = st.st_size; 3865 args.iconlen = st.st_size;
3757 args.iconsum = aim_iconsum(buf, st.st_size); 3866 args.iconsum = aimutil_iconsum(buf, st.st_size);
3758 args.iconstamp = st.st_mtime; 3867 args.iconstamp = st.st_mtime;
3759 3868
3760 args.flags |= AIM_IMFLAGS_HASICON; 3869 args.flags |= AIM_IMFLAGS_HASICON;
3761 debug_printf("Claiming to have an icon.\n"); 3870 debug_printf("Claiming to have an icon.\n");
3762 3871
3794 } else { 3903 } else {
3795 args.msg = message; 3904 args.msg = message;
3796 } 3905 }
3797 args.msglen = len; 3906 args.msglen = len;
3798 3907
3799 ret = aim_send_im_ext(odata->sess, &args); 3908 ret = aim_im_sendch1_ext(od->sess, &args);
3800 } 3909 }
3801 if (ret >= 0) 3910 if (ret >= 0)
3802 return 1; 3911 return 1;
3803 return ret; 3912 return ret;
3804 } 3913 }
3805 3914
3806 static void oscar_get_info(struct gaim_connection *g, char *name) { 3915 static void oscar_get_info(struct gaim_connection *g, char *name) {
3807 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 3916 struct oscar_data *od = (struct oscar_data *)g->proto_data;
3808 if (odata->icq) 3917 if (od->icq)
3809 aim_icq_getsimpleinfo(odata->sess, name); 3918 aim_icq_getsimpleinfo(od->sess, name);
3810 else 3919 else
3811 /* people want the away message on the top, so we get the away message 3920 /* people want the away message on the top, so we get the away message
3812 * first and then get the regular info, since it's too difficult to 3921 * first and then get the regular info, since it's too difficult to
3813 * insert in the middle. i hate people. */ 3922 * insert in the middle. i hate people. */
3814 aim_getinfo(odata->sess, odata->conn, name, AIM_GETINFO_AWAYMESSAGE); 3923 aim_getinfo(od->sess, od->conn, name, AIM_GETINFO_AWAYMESSAGE);
3815 } 3924 }
3816 3925
3817 static void oscar_get_away(struct gaim_connection *g, char *who) { 3926 static void oscar_get_away(struct gaim_connection *g, char *who) {
3818 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 3927 struct oscar_data *od = (struct oscar_data *)g->proto_data;
3819 if (odata->icq) { 3928 if (od->icq) {
3820 struct buddy *budlight = find_buddy(g->account, who); 3929 struct buddy *budlight = find_buddy(g->account, who);
3821 if (budlight) 3930 if (budlight)
3822 if ((budlight->uc & 0xffff0000) >> 16) 3931 if ((budlight->uc & 0xffff0000) >> 16)
3823 if (budlight->caps & AIM_CAPS_ICQSERVERRELAY) 3932 if (budlight->caps & AIM_CAPS_ICQSERVERRELAY)
3824 aim_send_im_ch2_geticqmessage(odata->sess, who, (budlight->uc & 0xffff0000) >> 16); 3933 aim_im_sendch2_geticqaway(od->sess, who, (budlight->uc & 0xffff0000) >> 16);
3825 else 3934 else
3826 debug_printf("Error: Remote client does not support retrieval of status messages.\n"); 3935 debug_printf("Error: Remote client does not support retrieval of status messages.\n");
3827 else 3936 else
3828 debug_printf("Error: The user %s has no status message, therefore not requesting.\n", who); 3937 debug_printf("Error: The user %s has no status message, therefore not requesting.\n", who);
3829 else 3938 else
3830 debug_printf("Error: Could not find %s in local contact list, therefore unable to request status message.\n", who); 3939 debug_printf("Error: Could not find %s in local contact list, therefore unable to request status message.\n", who);
3831 } else 3940 } else
3832 aim_getinfo(odata->sess, odata->conn, who, AIM_GETINFO_GENERALINFO); 3941 aim_getinfo(od->sess, od->conn, who, AIM_GETINFO_GENERALINFO);
3833 } 3942 }
3834 3943
3944 #if 0
3835 static void oscar_get_caps(struct gaim_connection *g, char *name) { 3945 static void oscar_get_caps(struct gaim_connection *g, char *name) {
3836 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 3946 struct oscar_data *od = (struct oscar_data *)g->proto_data;
3837 aim_getinfo(odata->sess, odata->conn, name, AIM_GETINFO_CAPABILITIES); 3947 aim_getinfo(od->sess, od->conn, name, AIM_GETINFO_CAPABILITIES);
3838 } 3948 }
3949 #endif
3839 3950
3840 static void oscar_set_dir(struct gaim_connection *g, const char *first, const char *middle, const char *last, 3951 static void oscar_set_dir(struct gaim_connection *g, const char *first, const char *middle, const char *last,
3841 const char *maiden, const char *city, const char *state, const char *country, int web) { 3952 const char *maiden, const char *city, const char *state, const char *country, int web) {
3842 /* AAA: some of these things are wrong, but i'm lazy */ 3953 /* XXX - some of these things are wrong, but i'm lazy */
3843 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 3954 struct oscar_data *od = (struct oscar_data *)g->proto_data;
3844 aim_setdirectoryinfo(odata->sess, odata->conn, first, middle, last, 3955 aim_setdirectoryinfo(od->sess, od->conn, first, middle, last,
3845 maiden, NULL, NULL, city, state, NULL, 0, web); 3956 maiden, NULL, NULL, city, state, NULL, 0, web);
3846 } 3957 }
3847 3958
3848 3959
3849 static void oscar_set_idle(struct gaim_connection *g, int time) { 3960 static void oscar_set_idle(struct gaim_connection *g, int time) {
3850 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 3961 struct oscar_data *od = (struct oscar_data *)g->proto_data;
3851 aim_bos_setidle(odata->sess, odata->conn, time); 3962 aim_bos_setidle(od->sess, od->conn, time);
3852 } 3963 }
3853 3964
3854 static void oscar_set_info(struct gaim_connection *g, char *info) { 3965 static void oscar_set_info(struct gaim_connection *g, char *info) {
3855 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 3966 struct oscar_data *od = (struct oscar_data *)g->proto_data;
3856 gchar *inforeal, *unicode; 3967 gchar *inforeal, *unicode;
3857 fu32_t flags; 3968 fu32_t flags;
3858 int unicode_len; 3969 int unicode_len;
3859 3970
3860 if (odata->rights.maxsiglen == 0) 3971 if (od->rights.maxsiglen == 0)
3861 do_error_dialog(_("Unable to set AIM profile."), 3972 do_error_dialog(_("Unable to set AIM profile."),
3862 _("You have probably requested to set your profile before the login procedure completed. " 3973 _("You have probably requested to set your profile before the login procedure completed. "
3863 "Your profile remains unset; try setting it again when you are fully connected."), GAIM_ERROR); 3974 "Your profile remains unset; try setting it again when you are fully connected."), GAIM_ERROR);
3864 3975
3865 if (strlen(info) > odata->rights.maxsiglen) { 3976 if (strlen(info) > od->rights.maxsiglen) {
3866 gchar *errstr; 3977 gchar *errstr;
3867 3978
3868 errstr = g_strdup_printf(_("The maximum profile length of %d bytes has been exceeded. " 3979 errstr = g_strdup_printf(_("The maximum profile length of %d bytes has been exceeded. "
3869 "Gaim has truncated and set it."), odata->rights.maxsiglen); 3980 "Gaim has truncated and set it."), od->rights.maxsiglen);
3870 do_error_dialog("Profile too long.", errstr, GAIM_WARNING); 3981 do_error_dialog("Profile too long.", errstr, GAIM_WARNING);
3871 3982
3872 g_free(errstr); 3983 g_free(errstr);
3873 } 3984 }
3874 3985
3875 inforeal = g_strndup(info, odata->rights.maxsiglen); 3986 inforeal = g_strndup(info, od->rights.maxsiglen);
3876 3987
3877 if (odata->icq) 3988 if (od->icq)
3878 aim_bos_setprofile(odata->sess, odata->conn, NULL, NULL, 0, NULL, NULL, 0, caps_icq); 3989 aim_bos_setprofile(od->sess, od->conn, NULL, NULL, 0, NULL, NULL, 0, caps_icq);
3879 else { 3990 else {
3880 flags = check_encoding(inforeal); 3991 flags = check_encoding(inforeal);
3881 3992
3882 if (flags == 0) { 3993 if (flags == 0) {
3883 aim_bos_setprofile(odata->sess, odata->conn, "us-ascii", inforeal, strlen (inforeal), 3994 aim_bos_setprofile(od->sess, od->conn, "us-ascii", inforeal, strlen (inforeal),
3884 NULL, NULL, 0, caps_aim); 3995 NULL, NULL, 0, caps_aim);
3885 } else { 3996 } else {
3886 unicode = g_convert (inforeal, strlen(inforeal), "UCS-2BE", "UTF-8", NULL, 3997 unicode = g_convert (inforeal, strlen(inforeal), "UCS-2BE", "UTF-8", NULL,
3887 &unicode_len, NULL); 3998 &unicode_len, NULL);
3888 aim_bos_setprofile(odata->sess, odata->conn, "unicode-2-0", unicode, unicode_len, 3999 aim_bos_setprofile(od->sess, od->conn, "unicode-2-0", unicode, unicode_len,
3889 NULL, NULL, 0, caps_aim); 4000 NULL, NULL, 0, caps_aim);
3890 g_free(unicode); 4001 g_free(unicode);
3891 } 4002 }
3892 } 4003 }
3893 g_free(inforeal); 4004 g_free(inforeal);
4003 4114
4004 return; 4115 return;
4005 } 4116 }
4006 4117
4007 static void oscar_warn(struct gaim_connection *gc, char *name, int anon) { 4118 static void oscar_warn(struct gaim_connection *gc, char *name, int anon) {
4008 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; 4119 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
4009 aim_send_warning(odata->sess, odata->conn, name, anon ? AIM_WARN_ANON : 0); 4120 aim_im_warn(od->sess, od->conn, name, anon ? AIM_WARN_ANON : 0);
4010 } 4121 }
4011 4122
4012 static void oscar_dir_search(struct gaim_connection *gc, const char *first, const char *middle, const char *last, 4123 static void oscar_dir_search(struct gaim_connection *gc, const char *first, const char *middle, const char *last,
4013 const char *maiden, const char *city, const char *state, const char *country, const char *email) { 4124 const char *maiden, const char *city, const char *state, const char *country, const char *email) {
4014 struct oscar_data *odata = (struct oscar_data *)gc->proto_data; 4125 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
4015 if (strlen(email)) 4126 if (strlen(email))
4016 aim_usersearch_address(odata->sess, odata->conn, email); 4127 aim_usersearch_address(od->sess, od->conn, email);
4017 } 4128 }
4018 4129
4019 static void oscar_add_buddy(struct gaim_connection *gc, const char *name) { 4130 static void oscar_add_buddy(struct gaim_connection *gc, const char *name) {
4020 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 4131 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
4021 #ifdef NOSSI 4132 #ifdef NOSSI
4137 maxitems = va_arg(ap, fu16_t *); 4248 maxitems = va_arg(ap, fu16_t *);
4138 va_end(ap); 4249 va_end(ap);
4139 4250
4140 debug_printf("ssi rights:"); 4251 debug_printf("ssi rights:");
4141 for (i=0; i<numtypes; i++) 4252 for (i=0; i<numtypes; i++)
4142 debug_printf(" max type 0x%04x = %hx, ", i, maxitems[i]); 4253 debug_printf(" max type 0x%04x=%hd,", i, maxitems[i]);
4143 debug_printf("\n"); 4254 debug_printf("\n");
4144 4255
4145 if (numtypes >= 0) 4256 if (numtypes >= 0)
4146 od->rights.maxbuddies = maxitems[0]; 4257 od->rights.maxbuddies = maxitems[0];
4147 if (numtypes >= 1) 4258 if (numtypes >= 1)
4157 static int gaim_ssi_parselist(aim_session_t *sess, aim_frame_t *fr, ...) { 4268 static int gaim_ssi_parselist(aim_session_t *sess, aim_frame_t *fr, ...) {
4158 struct gaim_connection *gc = sess->aux_data; 4269 struct gaim_connection *gc = sess->aux_data;
4159 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 4270 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
4160 struct aim_ssi_item *curitem; 4271 struct aim_ssi_item *curitem;
4161 int tmp; 4272 int tmp;
4162 /* AAA - use these? 4273 /* XXX - use these?
4163 va_list ap; 4274 va_list ap;
4164 4275
4165 va_start(ap, fr); 4276 va_start(ap, fr);
4166 fmtver = (fu16_t)va_arg(ap, int); 4277 fmtver = (fu16_t)va_arg(ap, int);
4167 numitems = (fu16_t)va_arg(ap, int); 4278 numitems = (fu16_t)va_arg(ap, int);
4508 4619
4509 return m; 4620 return m;
4510 } 4621 }
4511 4622
4512 static void oscar_join_chat(struct gaim_connection *g, GList *data) { 4623 static void oscar_join_chat(struct gaim_connection *g, GList *data) {
4513 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 4624 struct oscar_data *od = (struct oscar_data *)g->proto_data;
4514 aim_conn_t *cur; 4625 aim_conn_t *cur;
4515 char *name; 4626 char *name;
4516 int *exchange; 4627 int *exchange;
4517 4628
4518 if (!data || !data->next) 4629 if (!data || !data->next)
4520 4631
4521 name = data->data; 4632 name = data->data;
4522 exchange = data->next->data; 4633 exchange = data->next->data;
4523 4634
4524 debug_printf("Attempting to join chat room %s.\n", name); 4635 debug_printf("Attempting to join chat room %s.\n", name);
4525 if ((cur = aim_getconn_type(odata->sess, AIM_CONN_TYPE_CHATNAV))) { 4636 if ((cur = aim_getconn_type(od->sess, AIM_CONN_TYPE_CHATNAV))) {
4526 debug_printf("chatnav exists, creating room\n"); 4637 debug_printf("chatnav exists, creating room\n");
4527 aim_chatnav_createroom(odata->sess, cur, name, *exchange); 4638 aim_chatnav_createroom(od->sess, cur, name, *exchange);
4528 } else { 4639 } else {
4529 /* this gets tricky */ 4640 /* this gets tricky */
4530 struct create_room *cr = g_new0(struct create_room, 1); 4641 struct create_room *cr = g_new0(struct create_room, 1);
4531 debug_printf("chatnav does not exist, opening chatnav\n"); 4642 debug_printf("chatnav does not exist, opening chatnav\n");
4532 cr->exchange = *exchange; 4643 cr->exchange = *exchange;
4533 cr->name = g_strdup(name); 4644 cr->name = g_strdup(name);
4534 odata->create_rooms = g_slist_append(odata->create_rooms, cr); 4645 od->create_rooms = g_slist_append(od->create_rooms, cr);
4535 aim_reqservice(odata->sess, odata->conn, AIM_CONN_TYPE_CHATNAV); 4646 aim_reqservice(od->sess, od->conn, AIM_CONN_TYPE_CHATNAV);
4536 } 4647 }
4537 } 4648 }
4538 4649
4539 static void oscar_chat_invite(struct gaim_connection *g, int id, const char *message, const char *name) { 4650 static void oscar_chat_invite(struct gaim_connection *g, int id, const char *message, const char *name) {
4540 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 4651 struct oscar_data *od = (struct oscar_data *)g->proto_data;
4541 struct chat_connection *ccon = find_oscar_chat(g, id); 4652 struct chat_connection *ccon = find_oscar_chat(g, id);
4542 4653
4543 if (!ccon) 4654 if (!ccon)
4544 return; 4655 return;
4545 4656
4546 aim_chat_invite(odata->sess, odata->conn, name, message ? message : "", 4657 aim_chat_invite(od->sess, od->conn, name, message ? message : "",
4547 ccon->exchange, ccon->name, 0x0); 4658 ccon->exchange, ccon->name, 0x0);
4548 } 4659 }
4549 4660
4550 static void oscar_chat_leave(struct gaim_connection *g, int id) { 4661 static void oscar_chat_leave(struct gaim_connection *g, int id) {
4551 struct oscar_data *odata = g ? (struct oscar_data *)g->proto_data : NULL; 4662 struct oscar_data *od = g ? (struct oscar_data *)g->proto_data : NULL;
4552 GSList *bcs = g->buddy_chats; 4663 GSList *bcs = g->buddy_chats;
4553 struct gaim_conversation *b = NULL; 4664 struct gaim_conversation *b = NULL;
4554 struct chat_connection *c = NULL; 4665 struct chat_connection *c = NULL;
4555 int count = 0; 4666 int count = 0;
4556 4667
4568 4679
4569 debug_printf("Attempting to leave room %s (currently in %d rooms)\n", b->name, count); 4680 debug_printf("Attempting to leave room %s (currently in %d rooms)\n", b->name, count);
4570 4681
4571 c = find_oscar_chat(g, gaim_chat_get_id(GAIM_CHAT(b))); 4682 c = find_oscar_chat(g, gaim_chat_get_id(GAIM_CHAT(b)));
4572 if (c != NULL) { 4683 if (c != NULL) {
4573 if (odata) 4684 if (od)
4574 odata->oscar_chats = g_slist_remove(odata->oscar_chats, c); 4685 od->oscar_chats = g_slist_remove(od->oscar_chats, c);
4575 if (c->inpa > 0) 4686 if (c->inpa > 0)
4576 gaim_input_remove(c->inpa); 4687 gaim_input_remove(c->inpa);
4577 if (g && odata->sess) 4688 if (g && od->sess)
4578 aim_conn_kill(odata->sess, &c->conn); 4689 aim_conn_kill(od->sess, &c->conn);
4579 g_free(c->name); 4690 g_free(c->name);
4580 g_free(c->show); 4691 g_free(c->show);
4581 g_free(c); 4692 g_free(c);
4582 } 4693 }
4583 /* we do this because with Oscar it doesn't tell us we left */ 4694 /* we do this because with Oscar it doesn't tell us we left */
4584 serv_got_chat_left(g, gaim_chat_get_id(GAIM_CHAT(b))); 4695 serv_got_chat_left(g, gaim_chat_get_id(GAIM_CHAT(b)));
4585 } 4696 }
4586 4697
4587 static int oscar_chat_send(struct gaim_connection *g, int id, char *message) { 4698 static int oscar_chat_send(struct gaim_connection *g, int id, char *message) {
4588 struct oscar_data *odata = (struct oscar_data *)g->proto_data; 4699 struct oscar_data *od = (struct oscar_data *)g->proto_data;
4589 GSList *bcs = g->buddy_chats; 4700 GSList *bcs = g->buddy_chats;
4590 struct gaim_conversation *b = NULL; 4701 struct gaim_conversation *b = NULL;
4591 struct chat_connection *c = NULL; 4702 struct chat_connection *c = NULL;
4592 char *buf, *buf2; 4703 char *buf, *buf2;
4593 int i, j; 4704 int i, j;
4600 b = NULL; 4711 b = NULL;
4601 } 4712 }
4602 if (!b) 4713 if (!b)
4603 return -EINVAL; 4714 return -EINVAL;
4604 4715
4605 bcs = odata->oscar_chats; 4716 bcs = od->oscar_chats;
4606 while (bcs) { 4717 while (bcs) {
4607 c = (struct chat_connection *)bcs->data; 4718 c = (struct chat_connection *)bcs->data;
4608 if (b == c->cnv) 4719 if (b == c->cnv)
4609 break; 4720 break;
4610 bcs = bcs->next; 4721 bcs = bcs->next;
4634 g_free(buf2); 4745 g_free(buf2);
4635 return -E2BIG; 4746 return -E2BIG;
4636 } 4747 }
4637 g_free(buf2); 4748 g_free(buf2);
4638 4749
4639 aim_chat_send_im(odata->sess, c->conn, 0, buf, strlen(buf)); 4750 aim_chat_send_im(od->sess, c->conn, 0, buf, strlen(buf));
4640 g_free(buf); 4751 g_free(buf);
4641 return 0; 4752 return 0;
4642 } 4753 }
4643 4754
4644 static char **oscar_list_icon(int uc) { 4755 static char **oscar_list_icon(int uc) {
4675 if (uc & UC_NORMAL) 4786 if (uc & UC_NORMAL)
4676 return (char **)free_icon_xpm; 4787 return (char **)free_icon_xpm;
4677 return NULL; 4788 return NULL;
4678 } 4789 }
4679 4790
4680 #if 0
4681 /* 4791 /*
4682 * This is called after the raw data for a file has been transferred (whether 4792 * We have just established a socket with the other dude, so set up some handlers.
4683 * we are sending or receiving), but there are other files remaining.
4684 */ 4793 */
4685 void oscar_file_transfer_nextfile(struct gaim_connection *gc, 4794 static int gaim_odc_initiate(aim_session_t *sess, aim_frame_t *fr, ...) {
4686 struct file_transfer *xfer) {
4687 struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer);
4688 aim_conn_t *conn = oft->conn;
4689 aim_session_t *sess = aim_conn_getsess(conn);
4690
4691 oft->filesdone++;
4692 oft->watcher = gaim_input_add(conn->fd, GAIM_INPUT_READ,
4693 oscar_callback, conn);
4694
4695 /* If this is an incoming sendfile transfer, we send an OK
4696 * message to the sender; if this is an outgoing sendfile, we
4697 * will get an OK from the receiver that will be handled in
4698 * oscar_sendfile_out_done(), so we don't need to do anything
4699 * yet.
4700 */
4701
4702 if (oft->type == OFT_SENDFILE_IN)
4703 aim_oft_end(sess, conn);
4704 }
4705
4706 /*
4707 * This is called after the raw data for a file has been transferred (whether
4708 * we are sending or receiving), and it is the last file in the set, so we
4709 * can tear down the connection.
4710 */
4711 void oscar_file_transfer_done(struct gaim_connection *gc,
4712 struct file_transfer *xfer) {
4713 struct oscar_file_transfer *oft = find_oft_by_xfer(gc, xfer);
4714 aim_conn_t *conn = oft->conn;
4715 aim_session_t *sess = aim_conn_getsess(conn);
4716
4717 oft->filesdone++;
4718 if (oft->type == OFT_SENDFILE_IN) {
4719 aim_oft_end(sess, conn);
4720 oscar_file_transfer_disconnect(sess, conn);
4721 }
4722 else if (oft->type == OFT_SENDFILE_OUT) {
4723 /* Wait for response before closing connection. */
4724 oft->watcher = gaim_input_add(conn->fd, GAIM_INPUT_READ,
4725 oscar_callback, conn);
4726 }
4727 }
4728
4729 /*
4730 * This is called when there is raw data ready to be sent or received; all the
4731 * protocol details have been taken care of.
4732 */
4733 static int oscar_file_transfer_do(aim_session_t *sess, aim_frame_t *fr, ...) {
4734 struct gaim_connection *gc = sess->aux_data;
4735 va_list ap;
4736 aim_conn_t *conn;
4737 struct oscar_file_transfer *oft;
4738 struct aim_fileheader_t *fh;
4739 int err;
4740
4741 va_start(ap, fr);
4742 conn = va_arg(ap, aim_conn_t *);
4743 fh = va_arg(ap, struct aim_fileheader_t *);
4744 va_end(ap);
4745
4746 oft = find_oft_by_conn(gc, conn);
4747
4748 /* Don't use the regular input handler for the raw data. */
4749 gaim_input_remove(oft->watcher);
4750 oft->watcher = 0;
4751
4752 if (oft->type == OFT_SENDFILE_IN) {
4753 /* AAA convert fh->name from UCS-2 to UTF-8 if (fh->nencode == 0x0002) */
4754 err = transfer_in_do(oft->xfer, conn->fd, fh->name, fh->size);
4755 }
4756 else {
4757 err = transfer_out_do(oft->xfer, conn->fd, fh->nrecvd);
4758 }
4759
4760 if (err) {
4761 /* There was an error; cancel the transfer. */
4762 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
4763 aim_conn_t *bosconn = od->conn;
4764 aim_canceltransfer(sess, bosconn, oft->cookie,
4765 oft->sn, AIM_CAPS_SENDFILE);
4766 oscar_file_transfer_disconnect(sess, oft->conn);
4767 }
4768
4769 return 0;
4770 }
4771 #endif
4772
4773 static int gaim_directim_initiate(aim_session_t *sess, aim_frame_t *fr, ...) {
4774 va_list ap;
4775 struct gaim_connection *gc = sess->aux_data; 4795 struct gaim_connection *gc = sess->aux_data;
4776 struct oscar_data *od = (struct oscar_data *)gc->proto_data; 4796 struct oscar_data *od = (struct oscar_data *)gc->proto_data;
4777 aim_conn_t *newconn, *listenerconn;
4778 struct gaim_conversation *cnv; 4797 struct gaim_conversation *cnv;
4779 struct direct_im *dim; 4798 struct direct_im *dim;
4780 char buf[256]; 4799 char buf[256];
4781 char *sn; 4800 char *sn;
4801 va_list ap;
4802 aim_conn_t *newconn, *listenerconn;
4782 4803
4783 va_start(ap, fr); 4804 va_start(ap, fr);
4784 newconn = va_arg(ap, aim_conn_t *); 4805 newconn = va_arg(ap, aim_conn_t *);
4785 listenerconn = va_arg(ap, aim_conn_t *); 4806 listenerconn = va_arg(ap, aim_conn_t *);
4786 va_end(ap); 4807 va_end(ap);
4787 4808
4788 aim_conn_close(listenerconn); 4809 aim_conn_close(listenerconn);
4789 aim_conn_kill(sess, &listenerconn); 4810 aim_conn_kill(sess, &listenerconn);
4790 4811
4791 sn = g_strdup(aim_directim_getsn(newconn)); 4812 sn = g_strdup(aim_odc_getsn(newconn));
4792 4813
4793 debug_printf("DirectIM: initiate success to %s\n", sn); 4814 debug_printf("DirectIM: initiate success to %s\n", sn);
4794 dim = find_direct_im(od, sn); 4815 dim = find_direct_im(od, sn);
4795 4816
4796 if (!(cnv = gaim_find_conversation(sn))) 4817 if (!(cnv = gaim_find_conversation(sn)))
4797 cnv = gaim_conversation_new(GAIM_CONV_IM, dim->gc->account, sn); 4818 cnv = gaim_conversation_new(GAIM_CONV_IM, dim->gc->account, sn);
4798 gaim_input_remove(dim->watcher); 4819 gaim_input_remove(dim->watcher);
4799 dim->conn = newconn; 4820 dim->conn = newconn;
4800 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, 4821 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, oscar_callback, dim->conn);
4801 oscar_callback, dim->conn);
4802 dim->connected = TRUE; 4822 dim->connected = TRUE;
4803 g_snprintf(buf, sizeof buf, _("Direct IM with %s established"), sn); 4823 g_snprintf(buf, sizeof buf, _("Direct IM with %s established"), sn);
4804 g_free(sn); 4824 g_free(sn);
4805 gaim_conversation_write(cnv, NULL, buf, -1, WFLAG_SYSTEM, time(NULL)); 4825 gaim_conversation_write(cnv, NULL, buf, -1, WFLAG_SYSTEM, time(NULL));
4806 4826
4807 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, 4827 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, gaim_odc_incoming, 0);
4808 gaim_directim_incoming, 0); 4828 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, gaim_odc_typing, 0);
4809 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, 4829 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_IMAGETRANSFER, gaim_update_ui, 0);
4810 gaim_directim_typing, 0); 4830
4811 aim_conn_addhandler(sess, newconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_IMAGETRANSFER,
4812 gaim_update_ui, 0);
4813 return 1; 4831 return 1;
4814 } 4832 }
4815 4833
4816 static int gaim_update_ui(aim_session_t *sess, aim_frame_t *fr, ...) { 4834 static int gaim_update_ui(aim_session_t *sess, aim_frame_t *fr, ...) {
4817 va_list ap; 4835 va_list ap;
4842 oscar_callback, dim->conn); 4860 oscar_callback, dim->conn);
4843 4861
4844 return 1; 4862 return 1;
4845 } 4863 }
4846 4864
4847 static int gaim_directim_incoming(aim_session_t *sess, aim_frame_t *fr, ...) { 4865 static int gaim_odc_incoming(aim_session_t *sess, aim_frame_t *fr, ...) {
4848 va_list ap; 4866 va_list ap;
4849 char *msg, *sn; 4867 char *msg, *sn;
4850 int len, encoding; 4868 int len, encoding;
4851 struct gaim_connection *gc = sess->aux_data; 4869 struct gaim_connection *gc = sess->aux_data;
4852 4870
4857 encoding = va_arg(ap, int); 4875 encoding = va_arg(ap, int);
4858 va_end(ap); 4876 va_end(ap);
4859 4877
4860 debug_printf("Got DirectIM message from %s\n", sn); 4878 debug_printf("Got DirectIM message from %s\n", sn);
4861 4879
4862 /* AAA - I imagine Paco-Paco will want to do some voodoo with the encoding here */ 4880 /* XXX - I imagine Paco-Paco will want to do some voodoo with the encoding here */
4863 serv_got_im(gc, sn, msg, 0, time(NULL), len); 4881 serv_got_im(gc, sn, msg, 0, time(NULL), len);
4864 4882
4865 return 1; 4883 return 1;
4866 } 4884 }
4867 4885
4868 static int gaim_directim_typing(aim_session_t *sess, aim_frame_t *fr, ...) { 4886 static int gaim_odc_typing(aim_session_t *sess, aim_frame_t *fr, ...) {
4869 va_list ap; 4887 va_list ap;
4870 char *sn; 4888 char *sn;
4871 int typing; 4889 int typing;
4872 struct gaim_connection *gc = sess->aux_data; 4890 struct gaim_connection *gc = sess->aux_data;
4873 4891
4921 } 4939 }
4922 dim = g_new0(struct direct_im, 1); 4940 dim = g_new0(struct direct_im, 1);
4923 dim->gc = gc; 4941 dim->gc = gc;
4924 g_snprintf(dim->name, sizeof dim->name, "%s", data->who); 4942 g_snprintf(dim->name, sizeof dim->name, "%s", data->who);
4925 4943
4926 dim->conn = aim_directim_initiate(od->sess, data->who); 4944 dim->conn = aim_odc_initiate(od->sess, data->who);
4927 if (dim->conn != NULL) { 4945 if (dim->conn != NULL) {
4928 od->direct_ims = g_slist_append(od->direct_ims, dim); 4946 od->direct_ims = g_slist_append(od->direct_ims, dim);
4929 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, 4947 dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ,
4930 oscar_callback, dim->conn); 4948 oscar_callback, dim->conn);
4931 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINITIATE, 4949 aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIM_ESTABLISHED,
4932 gaim_directim_initiate, 0); 4950 gaim_odc_initiate, 0);
4933 } else { 4951 } else {
4934 do_error_dialog(_("Unable to open Direct IM"), NULL, GAIM_ERROR); 4952 do_error_dialog(_("Unable to open Direct IM"), NULL, GAIM_ERROR);
4935 g_free(dim); 4953 g_free(dim);
4936 } 4954 }
4937 4955
4953 if (od->icq) { 4971 if (od->icq) {
4954 struct buddy *budlight = find_buddy(gc->account, who); 4972 struct buddy *budlight = find_buddy(gc->account, who);
4955 if (budlight) 4973 if (budlight)
4956 if ((budlight->uc >> 16) & (AIM_ICQ_STATE_AWAY || AIM_ICQ_STATE_DND || AIM_ICQ_STATE_OUT || AIM_ICQ_STATE_BUSY || AIM_ICQ_STATE_CHAT)) 4974 if ((budlight->uc >> 16) & (AIM_ICQ_STATE_AWAY || AIM_ICQ_STATE_DND || AIM_ICQ_STATE_OUT || AIM_ICQ_STATE_BUSY || AIM_ICQ_STATE_CHAT))
4957 if (budlight->caps & AIM_CAPS_ICQSERVERRELAY) 4975 if (budlight->caps & AIM_CAPS_ICQSERVERRELAY)
4958 aim_send_im_ch2_geticqmessage(od->sess, who, (budlight->uc & 0xffff0000) >> 16); 4976 aim_im_sendch2_geticqaway(od->sess, who, (budlight->uc & 0xffff0000) >> 16);
4959 else { 4977 else {
4960 char *state_msg = gaim_icq_status((budlight->uc & 0xffff0000) >> 16); 4978 char *state_msg = gaim_icq_status((budlight->uc & 0xffff0000) >> 16);
4961 char *dialog_msg = g_strdup_printf(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<HR><I>Remote client does not support sending status messages.</I><BR>"), who, state_msg); 4979 char *dialog_msg = g_strdup_printf(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<HR><I>Remote client does not support sending status messages.</I><BR>"), who, state_msg);
4962 g_show_info_text(gc, who, 2, dialog_msg, NULL); 4980 g_show_info_text(gc, who, 2, dialog_msg, NULL);
4963 free(state_msg); 4981 free(state_msg);
5132 pbm = g_new0(struct proto_buddy_menu, 1); 5150 pbm = g_new0(struct proto_buddy_menu, 1);
5133 pbm->label = _("Direct IM"); 5151 pbm->label = _("Direct IM");
5134 pbm->callback = oscar_ask_direct_im; 5152 pbm->callback = oscar_ask_direct_im;
5135 pbm->gc = gc; 5153 pbm->gc = gc;
5136 m = g_list_append(m, pbm); 5154 m = g_list_append(m, pbm);
5137
5138 #if 0 5155 #if 0
5139 pbm = g_new0(struct proto_buddy_menu, 1); 5156 pbm = g_new0(struct proto_buddy_menu, 1);
5140 pbm->label = _("Send File"); 5157 pbm->label = _("Send File");
5141 pbm->callback = oscar_ask_send_file; 5158 pbm->callback = oscar_ask_sendfile;
5142 pbm->gc = gc; 5159 pbm->gc = gc;
5143 m = g_list_append(m, pbm); 5160 m = g_list_append(m, pbm);
5144 #endif 5161 #endif
5145 } 5162 }
5146 } 5163 }
5147 5164
5165 #if 0
5148 pbm = g_new0(struct proto_buddy_menu, 1); 5166 pbm = g_new0(struct proto_buddy_menu, 1);
5149 pbm->label = _("Get Capabilities"); 5167 pbm->label = _("Get Capabilities");
5150 pbm->callback = oscar_get_caps; 5168 pbm->callback = oscar_get_caps;
5151 pbm->gc = gc; 5169 pbm->gc = gc;
5152 m = g_list_append(m, pbm); 5170 m = g_list_append(m, pbm);
5171 #endif
5153 5172
5154 return m; 5173 return m;
5155 } 5174 }
5156 5175
5157 static GList *oscar_edit_buddy_menu(struct gaim_connection *gc, char *who) 5176 static GList *oscar_edit_buddy_menu(struct gaim_connection *gc, char *who)
5304 pam->label = _("Set User Info"); 5323 pam->label = _("Set User Info");
5305 pam->callback = show_set_info; 5324 pam->callback = show_set_info;
5306 pam->gc = gc; 5325 pam->gc = gc;
5307 m = g_list_append(m, pam); 5326 m = g_list_append(m, pam);
5308 5327
5309 if (od->sess->authinfo->regstatus == 0x0003) { 5328 if ((od->sess->authinfo->regstatus == 0x0003) || (od->icq)) {
5310 /* AIM actions */
5311 m = g_list_append(m, NULL);
5312
5313 pam = g_new0(struct proto_actions_menu, 1); 5329 pam = g_new0(struct proto_actions_menu, 1);
5314 pam->label = _("Change Password"); 5330 pam->label = _("Change Password");
5315 pam->callback = show_change_passwd; 5331 pam->callback = show_change_passwd;
5316 pam->gc = gc; 5332 pam->gc = gc;
5317 m = g_list_append(m, pam); 5333 m = g_list_append(m, pam);
5334 }
5335
5336 if (od->sess->authinfo->chpassurl) {
5337 pam = g_new0(struct proto_actions_menu, 1);
5338 pam->label = _("Change Password (URL)");
5339 pam->callback = oscar_show_chpassurl;
5340 pam->gc = gc;
5341 m = g_list_append(m, pam);
5342 }
5343
5344 if (od->sess->authinfo->regstatus == 0x0003) {
5345 /* AIM actions */
5346 m = g_list_append(m, NULL);
5318 5347
5319 pam = g_new0(struct proto_actions_menu, 1); 5348 pam = g_new0(struct proto_actions_menu, 1);
5320 pam->label = _("Format Screenname"); 5349 pam->label = _("Format Screenname");
5321 pam->callback = oscar_show_format_screenname; 5350 pam->callback = oscar_show_format_screenname;
5322 pam->gc = gc; 5351 pam->gc = gc;
5337 pam = g_new0(struct proto_actions_menu, 1); 5366 pam = g_new0(struct proto_actions_menu, 1);
5338 pam->label = _("Change Current Registered Address"); 5367 pam->label = _("Change Current Registered Address");
5339 pam->callback = oscar_show_change_email; 5368 pam->callback = oscar_show_change_email;
5340 pam->gc = gc; 5369 pam->gc = gc;
5341 m = g_list_append(m, pam); 5370 m = g_list_append(m, pam);
5342 } else if (od->sess->authinfo->chpassurl) {
5343 pam = g_new0(struct proto_actions_menu, 1);
5344 pam->label = _("Change Password");
5345 pam->callback = oscar_show_chpassurl;
5346 pam->gc = gc;
5347 m = g_list_append(m, pam);
5348 } 5371 }
5349 5372
5350 m = g_list_append(m, NULL); 5373 m = g_list_append(m, NULL);
5351 5374
5352 pam = g_new0(struct proto_actions_menu, 1); 5375 pam = g_new0(struct proto_actions_menu, 1);
5373 } 5396 }
5374 5397
5375 static void oscar_change_passwd(struct gaim_connection *gc, const char *old, const char *new) 5398 static void oscar_change_passwd(struct gaim_connection *gc, const char *old, const char *new)
5376 { 5399 {
5377 struct oscar_data *od = gc->proto_data; 5400 struct oscar_data *od = gc->proto_data;
5378 if (!aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH)) { 5401
5379 od->chpass = TRUE; 5402 if (od->icq) {
5380 od->oldp = g_strdup(old); 5403 aim_icq_changepasswd(od->sess, new);
5381 od->newp = g_strdup(new);
5382 aim_reqservice(od->sess, od->conn, AIM_CONN_TYPE_AUTH);
5383 } else { 5404 } else {
5384 aim_admin_changepasswd(od->sess, aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH), 5405 aim_conn_t *conn = aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH);
5385 new, old); 5406 if (conn) {
5407 aim_admin_changepasswd(od->sess, conn, new, old);
5408 } else {
5409 od->chpass = TRUE;
5410 od->oldp = g_strdup(old);
5411 od->newp = g_strdup(new);
5412 aim_reqservice(od->sess, od->conn, AIM_CONN_TYPE_AUTH);
5413 }
5386 } 5414 }
5387 } 5415 }
5388 5416
5389 static void oscar_convo_closed(struct gaim_connection *gc, char *who) 5417 static void oscar_convo_closed(struct gaim_connection *gc, char *who)
5390 { 5418 {
5495 ret->add_deny = oscar_add_deny; 5523 ret->add_deny = oscar_add_deny;
5496 ret->rem_permit = oscar_rem_permit; 5524 ret->rem_permit = oscar_rem_permit;
5497 ret->rem_deny = oscar_rem_deny; 5525 ret->rem_deny = oscar_rem_deny;
5498 ret->set_permit_deny = oscar_set_permit_deny; 5526 ret->set_permit_deny = oscar_set_permit_deny;
5499 5527
5500 #if 0
5501 ret->file_transfer_cancel = oscar_file_transfer_cancel;
5502 ret->file_transfer_in = oscar_file_transfer_in;
5503 ret->file_transfer_out = oscar_file_transfer_out;
5504 ret->file_transfer_data_chunk = oscar_file_transfer_data_chunk;
5505 ret->file_transfer_nextfile = oscar_file_transfer_nextfile;
5506 ret->file_transfer_done = oscar_file_transfer_done;
5507 #endif
5508
5509 ret->warn = oscar_warn; 5528 ret->warn = oscar_warn;
5510 ret->chat_info = oscar_chat_info; 5529 ret->chat_info = oscar_chat_info;
5511 ret->join_chat = oscar_join_chat; 5530 ret->join_chat = oscar_join_chat;
5512 ret->chat_invite = oscar_chat_invite; 5531 ret->chat_invite = oscar_chat_invite;
5513 ret->chat_leave = oscar_chat_leave; 5532 ret->chat_leave = oscar_chat_leave;