comparison libpurple/protocols/gg/gg.c @ 32819:2c6510167895 default tip

propagate from branch 'im.pidgin.pidgin.2.x.y' (head 3315c5dfbd0ad16511bdcf865e5b07c02d07df24) to branch 'im.pidgin.pidgin' (head cbd1eda6bcbf0565ae7766396bb8f6f419cb6a9a)
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Sat, 02 Jun 2012 02:30:49 +0000
parents f07501af8bae
children
comparison
equal deleted inserted replaced
32818:01ff09d4a463 32819:2c6510167895
37 #include "debug.h" 37 #include "debug.h"
38 #include "util.h" 38 #include "util.h"
39 #include "request.h" 39 #include "request.h"
40 #include "xmlnode.h" 40 #include "xmlnode.h"
41 41
42 #include <libgadu.h>
43
44 #include "gg.h" 42 #include "gg.h"
45 #include "confer.h" 43 #include "confer.h"
46 #include "search.h" 44 #include "search.h"
47 #include "buddylist.h" 45 #include "buddylist.h"
48 #include "gg-utils.h" 46 #include "gg-utils.h"
47
48 #ifdef _WIN32
49 # include "win32-resolver.h"
50 #endif
49 51
50 static PurplePlugin *my_protocol = NULL; 52 static PurplePlugin *my_protocol = NULL;
51 53
52 /* Prototypes */ 54 /* Prototypes */
53 static void ggp_set_status(PurpleAccount *account, PurpleStatus *status); 55 static void ggp_set_status(PurpleAccount *account, PurpleStatus *status);
95 } 97 }
96 98
97 static void ggp_async_token_handler(gpointer _gc, gint fd, PurpleInputCondition cond) 99 static void ggp_async_token_handler(gpointer _gc, gint fd, PurpleInputCondition cond)
98 { 100 {
99 PurpleConnection *gc = _gc; 101 PurpleConnection *gc = _gc;
100 GGPInfo *info = gc->proto_data; 102 GGPInfo *info = purple_connection_get_protocol_data(gc);
101 GGPToken *token = info->token; 103 GGPToken *token = info->token;
102 GGPTokenCallback cb; 104 GGPTokenCallback cb;
103 105
104 struct gg_token *t = NULL; 106 struct gg_token *t = NULL;
105 107
168 account = purple_connection_get_account(gc); 170 account = purple_connection_get_account(gc);
169 171
170 if (ggp_setup_proxy(account) == -1) 172 if (ggp_setup_proxy(account) == -1)
171 return; 173 return;
172 174
173 info = gc->proto_data; 175 info = purple_connection_get_protocol_data(gc);
174 176
175 if ((req = gg_token(1)) == NULL) { 177 if ((req = gg_token(1)) == NULL) {
176 purple_notify_error(account, 178 purple_notify_error(account,
177 _("Token Error"), 179 _("Token Error"),
178 _("Unable to fetch the token.\n"), NULL); 180 _("Unable to fetch the token.\n"), NULL);
197 * @param Current action handler. 199 * @param Current action handler.
198 */ 200 */
199 static void ggp_action_buddylist_get(PurplePluginAction *action) 201 static void ggp_action_buddylist_get(PurplePluginAction *action)
200 { 202 {
201 PurpleConnection *gc = (PurpleConnection *)action->context; 203 PurpleConnection *gc = (PurpleConnection *)action->context;
202 GGPInfo *info = gc->proto_data; 204 GGPInfo *info = purple_connection_get_protocol_data(gc);
203 205
204 purple_debug_info("gg", "Downloading...\n"); 206 purple_debug_info("gg", "Downloading...\n");
205 207
206 gg_userlist_request(info->session, GG_USERLIST_GET, NULL); 208 gg_userlist_request(info->session, GG_USERLIST_GET, NULL);
207 } 209 }
212 * @param action Current action handler. 214 * @param action Current action handler.
213 */ 215 */
214 static void ggp_action_buddylist_put(PurplePluginAction *action) 216 static void ggp_action_buddylist_put(PurplePluginAction *action)
215 { 217 {
216 PurpleConnection *gc = (PurpleConnection *)action->context; 218 PurpleConnection *gc = (PurpleConnection *)action->context;
217 GGPInfo *info = gc->proto_data; 219 GGPInfo *info = purple_connection_get_protocol_data(gc);
218 220
219 char *buddylist = ggp_buddylist_dump(purple_connection_get_account(gc)); 221 char *buddylist = ggp_buddylist_dump(purple_connection_get_account(gc));
220 222
221 purple_debug_info("gg", "Uploading...\n"); 223 purple_debug_info("gg", "Uploading...\n");
222 224
233 * @param action Current action handler. 235 * @param action Current action handler.
234 */ 236 */
235 static void ggp_action_buddylist_delete(PurplePluginAction *action) 237 static void ggp_action_buddylist_delete(PurplePluginAction *action)
236 { 238 {
237 PurpleConnection *gc = (PurpleConnection *)action->context; 239 PurpleConnection *gc = (PurpleConnection *)action->context;
238 GGPInfo *info = gc->proto_data; 240 GGPInfo *info = purple_connection_get_protocol_data(gc);
239 241
240 purple_debug_info("gg", "Deleting...\n"); 242 purple_debug_info("gg", "Deleting...\n");
241 243
242 gg_userlist_request(info->session, GG_USERLIST_PUT, NULL); 244 gg_userlist_request(info->session, GG_USERLIST_PUT, NULL);
243 } 245 }
332 334
333 static void ggp_callback_register_account_ok(PurpleConnection *gc, 335 static void ggp_callback_register_account_ok(PurpleConnection *gc,
334 PurpleRequestFields *fields) 336 PurpleRequestFields *fields)
335 { 337 {
336 PurpleAccount *account; 338 PurpleAccount *account;
337 GGPInfo *info = gc->proto_data; 339 GGPInfo *info = purple_connection_get_protocol_data(gc);
338 struct gg_http *h = NULL; 340 struct gg_http *h = NULL;
339 struct gg_pubdir *s; 341 struct gg_pubdir *s;
340 uin_t uin; 342 uin_t uin;
341 gchar *email, *p1, *p2, *t; 343 gchar *email, *p1, *p2, *t;
342 GGPToken *token = info->token; 344 GGPToken *token = info->token;
352 354
353 account = purple_connection_get_account(gc); 355 account = purple_connection_get_account(gc);
354 356
355 if (email == NULL || p1 == NULL || p2 == NULL || t == NULL || 357 if (email == NULL || p1 == NULL || p2 == NULL || t == NULL ||
356 *email == '\0' || *p1 == '\0' || *p2 == '\0' || *t == '\0') { 358 *email == '\0' || *p1 == '\0' || *p2 == '\0' || *t == '\0') {
357 purple_connection_error_reason (gc, 359 purple_connection_error (gc,
358 PURPLE_CONNECTION_ERROR_OTHER_ERROR, 360 PURPLE_CONNECTION_ERROR_OTHER_ERROR,
359 _("You must fill in all registration fields")); 361 _("You must fill in all registration fields"));
360 goto exit_err; 362 goto exit_err;
361 } 363 }
362 364
363 if (g_utf8_collate(p1, p2) != 0) { 365 if (g_utf8_collate(p1, p2) != 0) {
364 purple_connection_error_reason (gc, 366 purple_connection_error (gc,
365 PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, 367 PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
366 _("Passwords do not match")); 368 _("Passwords do not match"));
367 goto exit_err; 369 goto exit_err;
368 } 370 }
369 371
370 purple_debug_info("gg", "register_account_ok: token_id = %s; t = %s\n", 372 purple_debug_info("gg", "register_account_ok: token_id = %s; t = %s\n",
371 token->id, t); 373 token->id, t);
372 h = gg_register3(email, p1, token->id, t, 0); 374 h = gg_register3(email, p1, token->id, t, 0);
373 if (h == NULL || !(s = h->data) || !s->success) { 375 if (h == NULL || !(s = h->data) || !s->success) {
374 purple_connection_error_reason (gc, 376 purple_connection_error (gc,
375 PURPLE_CONNECTION_ERROR_OTHER_ERROR, 377 PURPLE_CONNECTION_ERROR_OTHER_ERROR,
376 _("Unable to register new account. An unknown error occurred.")); 378 _("Unable to register new account. An unknown error occurred."));
377 goto exit_err; 379 goto exit_err;
378 } 380 }
379 381
387 purple_account_set_password(account, p1); 389 purple_account_set_password(account, p1);
388 390
389 purple_notify_info(NULL, _("New Gadu-Gadu Account Registered"), 391 purple_notify_info(NULL, _("New Gadu-Gadu Account Registered"),
390 _("Registration completed successfully!"), NULL); 392 _("Registration completed successfully!"), NULL);
391 393
392 if(account->registration_cb) 394 purple_account_register_completed(account, TRUE);
393 (account->registration_cb)(account, TRUE, account->registration_cb_user_data); 395
394 /* TODO: the currently open Accounts Window will not be updated withthe 396 /* TODO: the currently open Accounts Window will not be updated withthe
395 * new username and etc, we need to somehow have it refresh at this 397 * new username and etc, we need to somehow have it refresh at this
396 * point 398 * point
397 */ 399 */
398 400
399 /* Need to disconnect or actually log in. For now, we disconnect. */ 401 /* Need to disconnect or actually log in. For now, we disconnect. */
400 purple_account_disconnect(account); 402 purple_account_disconnect(account);
401 403
402 exit_err: 404 exit_err:
403 if(account->registration_cb) 405 purple_account_register_completed(account, FALSE);
404 (account->registration_cb)(account, FALSE, account->registration_cb_user_data);
405 406
406 gg_register_free(h); 407 gg_register_free(h);
407 g_free(email); 408 g_free(email);
408 g_free(p1); 409 g_free(p1);
409 g_free(p2); 410 g_free(p2);
413 } 414 }
414 415
415 static void ggp_callback_register_account_cancel(PurpleConnection *gc, 416 static void ggp_callback_register_account_cancel(PurpleConnection *gc,
416 PurpleRequestFields *fields) 417 PurpleRequestFields *fields)
417 { 418 {
418 GGPInfo *info = gc->proto_data; 419 GGPInfo *info = purple_connection_get_protocol_data(gc);
419 GGPToken *token = info->token; 420 GGPToken *token = info->token;
420 421
421 purple_account_disconnect(gc->account); 422 purple_account_disconnect(purple_connection_get_account(gc));
422 423
423 g_free(token->id); 424 g_free(token->id);
424 g_free(token->data); 425 g_free(token->data);
425 g_free(token); 426 g_free(token);
426 427
431 PurpleAccount *account; 432 PurpleAccount *account;
432 PurpleRequestFields *fields; 433 PurpleRequestFields *fields;
433 PurpleRequestFieldGroup *group; 434 PurpleRequestFieldGroup *group;
434 PurpleRequestField *field; 435 PurpleRequestField *field;
435 436
436 GGPInfo *info = gc->proto_data; 437 GGPInfo *info = purple_connection_get_protocol_data(gc);
437 GGPToken *token = info->token; 438 GGPToken *token = info->token;
438 439
439 440
440 account = purple_connection_get_account(gc); 441 account = purple_connection_get_account(gc);
441 442
481 482
482 /* ----- PUBLIC DIRECTORY SEARCH ---------------------------------------- */ 483 /* ----- PUBLIC DIRECTORY SEARCH ---------------------------------------- */
483 484
484 static void ggp_callback_show_next(PurpleConnection *gc, GList *row, gpointer user_data) 485 static void ggp_callback_show_next(PurpleConnection *gc, GList *row, gpointer user_data)
485 { 486 {
486 GGPInfo *info = gc->proto_data; 487 GGPInfo *info = purple_connection_get_protocol_data(gc);
487 GGPSearchForm *form = user_data; 488 GGPSearchForm *form = user_data;
488 guint32 seq; 489 guint32 seq;
489 490
490 form->page_number++; 491 form->page_number++;
491 492
518 purple_conversation_present(conv); 519 purple_conversation_present(conv);
519 } 520 }
520 521
521 static void ggp_callback_find_buddies(PurpleConnection *gc, PurpleRequestFields *fields) 522 static void ggp_callback_find_buddies(PurpleConnection *gc, PurpleRequestFields *fields)
522 { 523 {
523 GGPInfo *info = gc->proto_data; 524 GGPInfo *info = purple_connection_get_protocol_data(gc);
524 GGPSearchForm *form; 525 GGPSearchForm *form;
525 guint32 seq; 526 guint32 seq;
526 527
527 form = ggp_search_form_new(GGP_SEARCH_TYPE_FULL); 528 form = ggp_search_form_new(GGP_SEARCH_TYPE_FULL);
528 529
614 _("Cancel"), NULL, 615 _("Cancel"), NULL,
615 purple_connection_get_account(gc), NULL, NULL, 616 purple_connection_get_account(gc), NULL, NULL,
616 gc); 617 gc);
617 } 618 }
618 619
619 /* ----- CHANGE PASSWORD ------------------------------------------------ */ 620 /* ----- CHANGE PASSWORD ---------------------------------------------------- */
620 621
621 static void ggp_callback_change_passwd_ok(PurpleConnection *gc, PurpleRequestFields *fields) 622 typedef struct
622 { 623 {
624 guint inpa;
625 struct gg_http *http_req;
626 gchar *new_password;
623 PurpleAccount *account; 627 PurpleAccount *account;
624 GGPInfo *info = gc->proto_data; 628 } ggp_change_passwd_request;
629
630 static void ggp_callback_change_passwd_handler(gpointer _req, gint fd,
631 PurpleInputCondition cond)
632 {
633 ggp_change_passwd_request *req = _req;
634 const char *messagesTitle =
635 _("Change password for the Gadu-Gadu account");
636
637 purple_input_remove(req->inpa);
638
639 if (gg_change_passwd_watch_fd(req->http_req) == -1 ||
640 req->http_req->state == GG_STATE_ERROR)
641 goto exit_error;
642
643 if (req->http_req->state != GG_STATE_DONE)
644 {
645 req->inpa = ggp_http_input_add(req->http_req,
646 ggp_callback_change_passwd_handler, req);
647 return;
648 }
649
650 if (req->http_req->data != NULL &&
651 ((struct gg_pubdir*)req->http_req->data)->success == 1)
652 {
653 purple_account_set_password(req->account, req->new_password);
654 purple_notify_info(req->account, messagesTitle,
655 _("Password was changed successfully!"), NULL);
656 goto exit_cleanup;
657 }
658
659 exit_error:
660 purple_notify_error(req->account, messagesTitle,
661 _("Unable to change password. Error occurred.\n"), NULL);
662
663 exit_cleanup:
664 gg_change_passwd_free(req->http_req);
665 g_free(req->new_password);
666 g_free(req);
667 }
668
669 static void ggp_callback_change_passwd_ok(PurpleConnection *gc,
670 PurpleRequestFields *fields)
671 {
672 PurpleAccount *account;
673 GGPInfo *info = purple_connection_get_protocol_data(gc);
625 struct gg_http *h; 674 struct gg_http *h;
626 gchar *cur, *p1, *p2, *t; 675 gchar *cur, *p1, *p2, *t, *mail;
627 676 const char *messagesTitle =
628 cur = charset_convert( 677 _("Change password for the Gadu-Gadu account");
629 purple_request_fields_get_string(fields, "password_cur"), 678
630 "UTF-8", "CP1250"); 679 cur = g_strdup(purple_request_fields_get_string(fields,
631 p1 = charset_convert( 680 "password_cur"));
632 purple_request_fields_get_string(fields, "password1"), 681 p1 = g_strdup(purple_request_fields_get_string(fields, "password1"));
633 "UTF-8", "CP1250"); 682 p2 = g_strdup(purple_request_fields_get_string(fields, "password2"));
634 p2 = charset_convert( 683 t = g_strdup(purple_request_fields_get_string(fields, "token"));
635 purple_request_fields_get_string(fields, "password2"), 684 mail = g_strdup(purple_request_fields_get_string(fields, "email"));
636 "UTF-8", "CP1250");
637 t = charset_convert(
638 purple_request_fields_get_string(fields, "token"),
639 "UTF-8", "CP1250");
640 685
641 account = purple_connection_get_account(gc); 686 account = purple_connection_get_account(gc);
642 687
643 if (cur == NULL || p1 == NULL || p2 == NULL || t == NULL || 688 if (cur == NULL || p1 == NULL || p2 == NULL || t == NULL ||
644 *cur == '\0' || *p1 == '\0' || *p2 == '\0' || *t == '\0') { 689 mail == NULL || *cur == '\0' || *p1 == '\0' || *p2 == '\0' ||
645 purple_notify_error(account, NULL, _("Fill in the fields."), NULL); 690 *t == '\0' || *mail == '\0') {
691 purple_notify_error(account, messagesTitle,
692 _("Fill in the fields."), NULL);
646 goto exit_err; 693 goto exit_err;
647 } 694 }
648 695
649 if (g_utf8_collate(p1, p2) != 0) { 696 if (g_utf8_collate(p1, p2) != 0) {
650 purple_notify_error(account, NULL, 697 purple_notify_error(account, messagesTitle,
651 _("New passwords do not match."), NULL); 698 _("New passwords do not match."), NULL);
652 goto exit_err; 699 goto exit_err;
653 } 700 }
654 701
655 if (g_utf8_collate(cur, purple_account_get_password(account)) != 0) { 702 if (strlen(p1) > 15) {
656 purple_notify_error(account, NULL, 703 purple_notify_error(account, messagesTitle,
657 _("Your current password is different from the one that you specified."), 704 _("New password should be at most 15 characters long."),
658 NULL); 705 NULL);
659 goto exit_err; 706 goto exit_err;
660 } 707 }
661 708
662 purple_debug_info("gg", "Changing password\n"); 709 if (g_utf8_collate(cur, purple_account_get_password(account)) != 0) {
663 710 purple_notify_error(account, messagesTitle,
664 /* XXX: this email should be a pref... */ 711 _("Your current password is different from the one that"
665 h = gg_change_passwd4(ggp_get_uin(account), 712 " you specified."), NULL);
666 "user@example.net", purple_account_get_password(account), 713 goto exit_err;
667 p1, info->token->id, t, 0); 714 }
668 715
669 if (h == NULL) { 716 if (!purple_email_is_valid(mail)) {
670 purple_notify_error(account, NULL, 717 purple_notify_error(account, messagesTitle,
718 _("Invalid email address"), NULL);
719 goto exit_err;
720 }
721
722 purple_debug_info("gg", "Changing password with email \"%s\"...\n",
723 mail);
724
725 h = gg_change_passwd4(ggp_get_uin(account), mail,
726 purple_account_get_password(account), p1, info->token->id, t,
727 1);
728
729 if (h == NULL)
730 purple_notify_error(account, messagesTitle,
671 _("Unable to change password. Error occurred.\n"), 731 _("Unable to change password. Error occurred.\n"),
672 NULL); 732 NULL);
673 goto exit_err; 733 else
674 } 734 {
675 735 ggp_change_passwd_request *req =
676 purple_account_set_password(account, p1); 736 g_new(ggp_change_passwd_request, 1);
677 737 req->http_req = h;
678 gg_change_passwd_free(h); 738 req->new_password = g_strdup(p1);
679 739 req->account = account;
680 purple_notify_info(account, _("Change password for the Gadu-Gadu account"), 740
681 _("Password was changed successfully!"), NULL); 741 req->inpa = ggp_http_input_add(h,
682 742 ggp_callback_change_passwd_handler, req);
743 }
744
683 exit_err: 745 exit_err:
684 g_free(cur); 746 g_free(cur);
685 g_free(p1); 747 g_free(p1);
686 g_free(p2); 748 g_free(p2);
687 g_free(t); 749 g_free(t);
750 g_free(mail);
688 g_free(info->token->id); 751 g_free(info->token->id);
689 g_free(info->token->data); 752 g_free(info->token->data);
690 g_free(info->token); 753 g_free(info->token);
691 } 754 }
692 755
694 { 757 {
695 PurpleRequestFields *fields; 758 PurpleRequestFields *fields;
696 PurpleRequestFieldGroup *group; 759 PurpleRequestFieldGroup *group;
697 PurpleRequestField *field; 760 PurpleRequestField *field;
698 761
699 GGPInfo *info = gc->proto_data; 762 GGPInfo *info = purple_connection_get_protocol_data(gc);
700 GGPToken *token = info->token; 763 GGPToken *token = info->token;
701 764
702 char *msg; 765 char *msg;
703
704 766
705 fields = purple_request_fields_new(); 767 fields = purple_request_fields_new();
706 group = purple_request_field_group_new(NULL); 768 group = purple_request_field_group_new(NULL);
707 purple_request_fields_add_group(fields, group); 769 purple_request_fields_add_group(fields, group);
708 770
719 field = purple_request_field_string_new("password2", 781 field = purple_request_field_string_new("password2",
720 _("Password (retype)"), "", FALSE); 782 _("Password (retype)"), "", FALSE);
721 purple_request_field_string_set_masked(field, TRUE); 783 purple_request_field_string_set_masked(field, TRUE);
722 purple_request_field_group_add_field(group, field); 784 purple_request_field_group_add_field(group, field);
723 785
786 field = purple_request_field_string_new("email",
787 _("Email Address"), "", FALSE);
788 purple_request_field_string_set_masked(field, FALSE);
789 purple_request_field_group_add_field(group, field);
790
724 field = purple_request_field_string_new("token", 791 field = purple_request_field_string_new("token",
725 _("Enter current token"), "", FALSE); 792 _("Enter current token"), "", FALSE);
726 purple_request_field_string_set_masked(field, FALSE); 793 purple_request_field_string_set_masked(field, FALSE);
727 purple_request_field_group_add_field(group, field); 794 purple_request_field_group_add_field(group, field);
728 795
730 field = purple_request_field_image_new("token_img", 797 field = purple_request_field_image_new("token_img",
731 _("Current token"), token->data, token->size); 798 _("Current token"), token->data, token->size);
732 purple_request_field_group_add_field(group, field); 799 purple_request_field_group_add_field(group, field);
733 800
734 msg = g_strdup_printf("%s %d", 801 msg = g_strdup_printf("%s %d",
735 _("Please, enter your current password and your new password for UIN: "), 802 _("Please, enter your current password and your new password "
736 ggp_get_uin(purple_connection_get_account(gc))); 803 "for UIN: "), ggp_get_uin(purple_connection_get_account(gc)));
737 804
738 purple_request_fields(gc, 805 purple_request_fields(gc,
739 _("Change Gadu-Gadu Password"), 806 _("Change Gadu-Gadu Password"),
740 _("Change Gadu-Gadu Password"), 807 _("Change Gadu-Gadu Password"),
741 msg, 808 msg,
756 823
757 /* ----- CHANGE STATUS BROADCASTING ------------------------------------------------ */ 824 /* ----- CHANGE STATUS BROADCASTING ------------------------------------------------ */
758 825
759 static void ggp_action_change_status_broadcasting_ok(PurpleConnection *gc, PurpleRequestFields *fields) 826 static void ggp_action_change_status_broadcasting_ok(PurpleConnection *gc, PurpleRequestFields *fields)
760 { 827 {
761 GGPInfo *info = gc->proto_data; 828 GGPInfo *info = purple_connection_get_protocol_data(gc);
762 int selected_field; 829 int selected_field;
763 PurpleAccount *account = purple_connection_get_account(gc); 830 PurpleAccount *account = purple_connection_get_account(gc);
764 PurpleStatus *status; 831 PurpleStatus *status;
765 832
766 selected_field = purple_request_fields_get_choice(fields, "status_broadcasting"); 833 selected_field = purple_request_fields_get_choice(fields, "status_broadcasting");
776 } 843 }
777 844
778 static void ggp_action_change_status_broadcasting(PurplePluginAction *action) 845 static void ggp_action_change_status_broadcasting(PurplePluginAction *action)
779 { 846 {
780 PurpleConnection *gc = (PurpleConnection *)action->context; 847 PurpleConnection *gc = (PurpleConnection *)action->context;
781 GGPInfo *info = gc->proto_data; 848 GGPInfo *info = purple_connection_get_protocol_data(gc);
782 849
783 PurpleRequestFields *fields; 850 PurpleRequestFields *fields;
784 PurpleRequestFieldGroup *group; 851 PurpleRequestFieldGroup *group;
785 PurpleRequestField *field; 852 PurpleRequestField *field;
786 853
846 GList *l; 913 GList *l;
847 gchar *msg; 914 gchar *msg;
848 915
849 buddy = (PurpleBuddy *)node; 916 buddy = (PurpleBuddy *)node;
850 gc = purple_account_get_connection(purple_buddy_get_account(buddy)); 917 gc = purple_account_get_connection(purple_buddy_get_account(buddy));
851 info = gc->proto_data; 918 info = purple_connection_get_protocol_data(gc);
852 919
853 fields = purple_request_fields_new(); 920 fields = purple_request_fields_new();
854 group = purple_request_field_group_new(NULL); 921 group = purple_request_field_group_new(NULL);
855 purple_request_fields_add_group(fields, group); 922 purple_request_fields_add_group(fields, group);
856 923
857 field = purple_request_field_list_new("name", "Chat name"); 924 field = purple_request_field_list_new("name", "Chat name");
858 for (l = info->chats; l != NULL; l = l->next) { 925 for (l = info->chats; l != NULL; l = l->next) {
859 GGPChat *chat = l->data; 926 GGPChat *chat = l->data;
860 purple_request_field_list_add(field, chat->name, chat->name); 927 purple_request_field_list_add_icon(field, chat->name, NULL, chat->name);
861 } 928 }
862 purple_request_field_group_add_field(group, field); 929 purple_request_field_group_add_field(group, field);
863 930
864 msg = g_strdup_printf(_("Select a chat for buddy: %s"), 931 msg = g_strdup_printf(_("Select a chat for buddy: %s"),
865 purple_buddy_get_alias(buddy)); 932 purple_buddy_get_alias(buddy));
877 944
878 /* ----- BLOCK BUDDIES -------------------------------------------------- */ 945 /* ----- BLOCK BUDDIES -------------------------------------------------- */
879 946
880 static void ggp_add_deny(PurpleConnection *gc, const char *who) 947 static void ggp_add_deny(PurpleConnection *gc, const char *who)
881 { 948 {
882 GGPInfo *info = gc->proto_data; 949 GGPInfo *info = purple_connection_get_protocol_data(gc);
883 uin_t uin = ggp_str_to_uin(who); 950 uin_t uin = ggp_str_to_uin(who);
884 951
885 purple_debug_info("gg", "ggp_add_deny: %u\n", uin); 952 purple_debug_info("gg", "ggp_add_deny: %u\n", uin);
886 953
887 gg_remove_notify_ex(info->session, uin, GG_USER_NORMAL); 954 gg_remove_notify_ex(info->session, uin, GG_USER_NORMAL);
888 gg_add_notify_ex(info->session, uin, GG_USER_BLOCKED); 955 gg_add_notify_ex(info->session, uin, GG_USER_BLOCKED);
889 } 956 }
890 957
891 static void ggp_rem_deny(PurpleConnection *gc, const char *who) 958 static void ggp_rem_deny(PurpleConnection *gc, const char *who)
892 { 959 {
893 GGPInfo *info = gc->proto_data; 960 GGPInfo *info = purple_connection_get_protocol_data(gc);
894 uin_t uin = ggp_str_to_uin(who); 961 uin_t uin = ggp_str_to_uin(who);
895 962
896 purple_debug_info("gg", "ggp_rem_deny: %u\n", uin); 963 purple_debug_info("gg", "ggp_rem_deny: %u\n", uin);
897 964
898 gg_remove_notify_ex(info->session, uin, GG_USER_BLOCKED); 965 gg_remove_notify_ex(info->session, uin, GG_USER_BLOCKED);
1022 data->uin = g_strdup(uin); 1089 data->uin = g_strdup(uin);
1023 data->avatar_url = g_strdup(bigavatar); 1090 data->avatar_url = g_strdup(bigavatar);
1024 1091
1025 purple_debug_info("gg", "gg_get_avatar_url_cb: " 1092 purple_debug_info("gg", "gg_get_avatar_url_cb: "
1026 "requesting avatar for %s\n", uin); 1093 "requesting avatar for %s\n", uin);
1027 url_data = purple_util_fetch_url_request_len_with_account(account, 1094 /* FIXME: This should be cancelled somewhere if not needed. */
1095 url_data = purple_util_fetch_url_request(account,
1028 bigavatar, TRUE, "Mozilla/4.0 (compatible; MSIE 5.0)", 1096 bigavatar, TRUE, "Mozilla/4.0 (compatible; MSIE 5.0)",
1029 FALSE, NULL, FALSE, -1, gg_fetch_avatar_cb, data); 1097 FALSE, NULL, FALSE, -1, gg_fetch_avatar_cb, data);
1030 } 1098 }
1031 } 1099 }
1032 } 1100 }
1050 1118
1051 purple_debug_info("gg", "ggp_update_buddy_avatar(gc, %u)\n", uin); 1119 purple_debug_info("gg", "ggp_update_buddy_avatar(gc, %u)\n", uin);
1052 1120
1053 avatarurl = g_strdup_printf("http://api.gadu-gadu.pl/avatars/%u/0.xml", uin); 1121 avatarurl = g_strdup_printf("http://api.gadu-gadu.pl/avatars/%u/0.xml", uin);
1054 1122
1055 url_data = purple_util_fetch_url_request_len_with_account( 1123 /* FIXME: This should be cancelled somewhere if not needed. */
1124 url_data = purple_util_fetch_url_request(
1056 purple_connection_get_account(gc), avatarurl, TRUE, 1125 purple_connection_get_account(gc), avatarurl, TRUE,
1057 "Mozilla/4.0 (compatible; MSIE 5.5)", FALSE, NULL, FALSE, -1, 1126 "Mozilla/4.0 (compatible; MSIE 5.5)", FALSE, NULL, FALSE, -1,
1058 gg_get_avatar_url_cb, gc); 1127 gg_get_avatar_url_cb, gc);
1059 1128
1060 g_free(avatarurl); 1129 g_free(avatarurl);
1084 case GG_STATUS_NOT_AVAIL_DESCR: 1153 case GG_STATUS_NOT_AVAIL_DESCR:
1085 st = purple_primitive_get_id_from_type(PURPLE_STATUS_OFFLINE); 1154 st = purple_primitive_get_id_from_type(PURPLE_STATUS_OFFLINE);
1086 break; 1155 break;
1087 case GG_STATUS_FFC: 1156 case GG_STATUS_FFC:
1088 case GG_STATUS_FFC_DESCR: 1157 case GG_STATUS_FFC_DESCR:
1089 st = purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE); 1158 st = "freeforchat";
1090 break; 1159 break;
1091 case GG_STATUS_AVAIL: 1160 case GG_STATUS_AVAIL:
1092 case GG_STATUS_AVAIL_DESCR: 1161 case GG_STATUS_AVAIL_DESCR:
1093 st = purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE); 1162 st = purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE);
1094 break; 1163 break;
1095 case GG_STATUS_BUSY: 1164 case GG_STATUS_BUSY:
1096 case GG_STATUS_BUSY_DESCR: 1165 case GG_STATUS_BUSY_DESCR:
1097 st = purple_primitive_get_id_from_type(PURPLE_STATUS_AWAY); 1166 st = purple_primitive_get_id_from_type(PURPLE_STATUS_AWAY);
1167 break;
1168 case GG_STATUS_INVISIBLE:
1169 case GG_STATUS_INVISIBLE_DESCR:
1170 st = purple_primitive_get_id_from_type(PURPLE_STATUS_INVISIBLE);
1098 break; 1171 break;
1099 case GG_STATUS_DND: 1172 case GG_STATUS_DND:
1100 case GG_STATUS_DND_DESCR: 1173 case GG_STATUS_DND_DESCR:
1101 st = purple_primitive_get_id_from_type(PURPLE_STATUS_UNAVAILABLE); 1174 st = purple_primitive_get_id_from_type(PURPLE_STATUS_UNAVAILABLE);
1102 break; 1175 break;
1192 1265
1193 user_info = purple_notify_user_info_new(); 1266 user_info = purple_notify_user_info_new();
1194 1267
1195 val = ggp_search_get_result(req, 0, GG_PUBDIR50_STATUS); 1268 val = ggp_search_get_result(req, 0, GG_PUBDIR50_STATUS);
1196 /* XXX: Use of ggp_str_to_uin() is an ugly hack! */ 1269 /* XXX: Use of ggp_str_to_uin() is an ugly hack! */
1197 purple_notify_user_info_add_pair(user_info, _("Status"), ggp_status_by_id(ggp_str_to_uin(val))); 1270 purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), ggp_status_by_id(ggp_str_to_uin(val)));
1198 g_free(val); 1271 g_free(val);
1199 1272
1200 who = ggp_search_get_result(req, 0, GG_PUBDIR50_UIN); 1273 who = ggp_search_get_result(req, 0, GG_PUBDIR50_UIN);
1201 purple_notify_user_info_add_pair(user_info, _("UIN"), who); 1274 /* TODO: Check whether it's correct to call add_pair_html,
1275 or if we should be using add_pair_plaintext */
1276 purple_notify_user_info_add_pair_html(user_info, _("UIN"), who);
1202 1277
1203 val = ggp_search_get_result(req, 0, GG_PUBDIR50_FIRSTNAME); 1278 val = ggp_search_get_result(req, 0, GG_PUBDIR50_FIRSTNAME);
1204 purple_notify_user_info_add_pair(user_info, _("First Name"), val); 1279 /* TODO: Check whether it's correct to call add_pair_html,
1280 or if we should be using add_pair_plaintext */
1281 purple_notify_user_info_add_pair_html(user_info, _("First Name"), val);
1205 g_free(val); 1282 g_free(val);
1206 1283
1207 val = ggp_search_get_result(req, 0, GG_PUBDIR50_NICKNAME); 1284 val = ggp_search_get_result(req, 0, GG_PUBDIR50_NICKNAME);
1208 purple_notify_user_info_add_pair(user_info, _("Nickname"), val); 1285 /* TODO: Check whether it's correct to call add_pair_html,
1286 or if we should be using add_pair_plaintext */
1287 purple_notify_user_info_add_pair_html(user_info, _("Nickname"), val);
1209 g_free(val); 1288 g_free(val);
1210 1289
1211 val = ggp_search_get_result(req, 0, GG_PUBDIR50_CITY); 1290 val = ggp_search_get_result(req, 0, GG_PUBDIR50_CITY);
1212 purple_notify_user_info_add_pair(user_info, _("City"), val); 1291 /* TODO: Check whether it's correct to call add_pair_html,
1292 or if we should be using add_pair_plaintext */
1293 purple_notify_user_info_add_pair_html(user_info, _("City"), val);
1213 g_free(val); 1294 g_free(val);
1214 1295
1215 val = ggp_search_get_result(req, 0, GG_PUBDIR50_BIRTHYEAR); 1296 val = ggp_search_get_result(req, 0, GG_PUBDIR50_BIRTHYEAR);
1216 if (strncmp(val, "0", 1)) { 1297 if (strncmp(val, "0", 1)) {
1217 purple_notify_user_info_add_pair(user_info, _("Birth Year"), val); 1298 /* TODO: Check whether it's correct to call add_pair_html,
1299 or if we should be using add_pair_plaintext */
1300 purple_notify_user_info_add_pair_html(user_info, _("Birth Year"), val);
1218 } 1301 }
1219 g_free(val); 1302 g_free(val);
1220 1303
1221 /* 1304 /*
1222 * Include a status message, if exists and buddy is in the blist. 1305 * Include a status message, if exists and buddy is in the blist.
1223 */ 1306 */
1224 buddy = purple_find_buddy(purple_connection_get_account(gc), who); 1307 buddy = purple_find_buddy(purple_connection_get_account(gc), who);
1225 if (NULL != buddy) { 1308 if (NULL != buddy) {
1226 PurpleStatus *status; 1309 PurpleStatus *status;
1227 const char *msg; 1310 const char *msg;
1228 char *text;
1229 1311
1230 status = purple_presence_get_active_status(purple_buddy_get_presence(buddy)); 1312 status = purple_presence_get_active_status(purple_buddy_get_presence(buddy));
1231 msg = purple_status_get_attr_string(status, "message"); 1313 msg = purple_status_get_attr_string(status, "message");
1232 1314
1233 if (msg != NULL) { 1315 if (msg != NULL) {
1234 text = g_markup_escape_text(msg, -1); 1316 purple_notify_user_info_add_pair_plaintext(user_info, _("Message"), msg);
1235 purple_notify_user_info_add_pair(user_info, _("Message"), text);
1236 g_free(text);
1237 } 1317 }
1238 } 1318 }
1239 1319
1240 purple_notify_userinfo(gc, who, user_info, ggp_sr_close_cb, form); 1320 purple_notify_userinfo(gc, who, user_info, ggp_sr_close_cb, form);
1241 g_free(who); 1321 g_free(who);
1340 } 1420 }
1341 } 1421 }
1342 1422
1343 static void ggp_pubdir_reply_handler(PurpleConnection *gc, gg_pubdir50_t req) 1423 static void ggp_pubdir_reply_handler(PurpleConnection *gc, gg_pubdir50_t req)
1344 { 1424 {
1345 GGPInfo *info = gc->proto_data; 1425 GGPInfo *info = purple_connection_get_protocol_data(gc);
1346 GGPSearchForm *form; 1426 GGPSearchForm *form;
1347 int res_count; 1427 int res_count;
1348 guint32 seq; 1428 guint32 seq;
1349 1429
1350 seq = gg_pubdir50_seq(req); 1430 seq = gg_pubdir50_seq(req);
1382 } 1462 }
1383 1463
1384 static void ggp_recv_image_handler(PurpleConnection *gc, const struct gg_event *ev) 1464 static void ggp_recv_image_handler(PurpleConnection *gc, const struct gg_event *ev)
1385 { 1465 {
1386 gint imgid = 0; 1466 gint imgid = 0;
1387 GGPInfo *info = gc->proto_data; 1467 GGPInfo *info = purple_connection_get_protocol_data(gc);
1388 GList *entry = g_list_first(info->pending_richtext_messages); 1468 GList *entry = g_list_first(info->pending_richtext_messages);
1389 gchar *handlerid = g_strdup_printf("IMGID_HANDLER-%i", ev->event.image_reply.crc32); 1469 gchar *handlerid = g_strdup_printf("IMGID_HANDLER-%i", ev->event.image_reply.crc32);
1390 1470
1391 imgid = purple_imgstore_add_with_id( 1471 imgid = purple_imgstore_add_with_id(
1392 g_memdup(ev->event.image_reply.image, ev->event.image_reply.size), 1472 g_memdup(ev->event.image_reply.image, ev->event.image_reply.size),
1430 * 1510 *
1431 * Image receiving, some code borrowed from Kadu http://www.kadu.net 1511 * Image receiving, some code borrowed from Kadu http://www.kadu.net
1432 */ 1512 */
1433 static void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event *ev) 1513 static void ggp_recv_message_handler(PurpleConnection *gc, const struct gg_event *ev)
1434 { 1514 {
1435 GGPInfo *info = gc->proto_data; 1515 GGPInfo *info = purple_connection_get_protocol_data(gc);
1436 PurpleConversation *conv; 1516 PurpleConversation *conv;
1437 gchar *from; 1517 gchar *from;
1438 gchar *msg; 1518 gchar *msg;
1439 gchar *tmp; 1519 gchar *tmp;
1520 time_t mtime;
1440 1521
1441 if (ev->event.msg.message == NULL) 1522 if (ev->event.msg.message == NULL)
1442 { 1523 {
1443 purple_debug_warning("gg", "ggp_recv_message_handler: NULL as message pointer\n"); 1524 purple_debug_warning("gg", "ggp_recv_message_handler: NULL as message pointer\n");
1444 return; 1525 return;
1563 1644
1564 purple_debug_info("gg", "ggp_recv_message_handler: msg from (%s): %s (class = %d; rcpt_count = %d)\n", 1645 purple_debug_info("gg", "ggp_recv_message_handler: msg from (%s): %s (class = %d; rcpt_count = %d)\n",
1565 from, msg, ev->event.msg.msgclass, 1646 from, msg, ev->event.msg.msgclass,
1566 ev->event.msg.recipients_count); 1647 ev->event.msg.recipients_count);
1567 1648
1649 if (ev->event.msg.msgclass & GG_CLASS_QUEUED)
1650 mtime = ev->event.msg.time;
1651 else
1652 mtime = time(NULL);
1653
1568 if (ev->event.msg.recipients_count == 0) { 1654 if (ev->event.msg.recipients_count == 0) {
1569 serv_got_im(gc, from, msg, 0, ev->event.msg.time); 1655 serv_got_im(gc, from, msg, 0, mtime);
1570 } else { 1656 } else {
1571 const char *chat_name; 1657 const char *chat_name;
1572 int chat_id; 1658 int chat_id;
1573 char *buddy_name; 1659 char *buddy_name;
1574 1660
1590 conv = ggp_confer_find_by_name(gc, chat_name); 1676 conv = ggp_confer_find_by_name(gc, chat_name);
1591 chat_id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)); 1677 chat_id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv));
1592 1678
1593 buddy_name = ggp_buddy_get_name(gc, ev->event.msg.sender); 1679 buddy_name = ggp_buddy_get_name(gc, ev->event.msg.sender);
1594 serv_got_chat_in(gc, chat_id, buddy_name, 1680 serv_got_chat_in(gc, chat_id, buddy_name,
1595 PURPLE_MESSAGE_RECV, msg, ev->event.msg.time); 1681 PURPLE_MESSAGE_RECV, msg, mtime);
1596 g_free(buddy_name); 1682 g_free(buddy_name);
1597 } 1683 }
1598 g_free(msg); 1684 g_free(msg);
1599 g_free(from); 1685 g_free(from);
1600 } 1686 }
1601 1687
1602 static void ggp_send_image_handler(PurpleConnection *gc, const struct gg_event *ev) 1688 static void ggp_send_image_handler(PurpleConnection *gc, const struct gg_event *ev)
1603 { 1689 {
1604 GGPInfo *info = gc->proto_data; 1690 GGPInfo *info = purple_connection_get_protocol_data(gc);
1605 PurpleStoredImage *image; 1691 PurpleStoredImage *image;
1606 gint imgid = GPOINTER_TO_INT(g_hash_table_lookup(info->pending_images, GINT_TO_POINTER(ev->event.image_request.crc32))); 1692 gint imgid = GPOINTER_TO_INT(g_hash_table_lookup(info->pending_images, GINT_TO_POINTER(ev->event.image_request.crc32)));
1607 1693
1608 purple_debug_info("gg", "ggp_send_image_handler: image request received, crc32: %u, imgid: %d\n", ev->event.image_request.crc32, imgid); 1694 purple_debug_info("gg", "ggp_send_image_handler: image request received, crc32: %u, imgid: %d\n", ev->event.image_request.crc32, imgid);
1609 1695
1705 } 1791 }
1706 1792
1707 static void ggp_callback_recv(gpointer _gc, gint fd, PurpleInputCondition cond) 1793 static void ggp_callback_recv(gpointer _gc, gint fd, PurpleInputCondition cond)
1708 { 1794 {
1709 PurpleConnection *gc = _gc; 1795 PurpleConnection *gc = _gc;
1710 GGPInfo *info = gc->proto_data; 1796 GGPInfo *info = purple_connection_get_protocol_data(gc);
1711 struct gg_event *ev; 1797 struct gg_event *ev;
1712 int i; 1798 int i;
1713 1799
1714 if (!(ev = gg_watch_fd(info->session))) { 1800 if (!(ev = gg_watch_fd(info->session))) {
1715 purple_debug_error("gg", 1801 purple_debug_error("gg",
1716 "ggp_callback_recv: gg_watch_fd failed -- CRITICAL!\n"); 1802 "ggp_callback_recv: gg_watch_fd failed -- CRITICAL!\n");
1717 purple_connection_error_reason (gc, 1803 purple_connection_error (gc,
1718 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 1804 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
1719 _("Unable to read from socket")); 1805 _("Unable to read from socket"));
1720 return; 1806 return;
1721 } 1807 }
1722 1808
1840 GGPInfo *info; 1926 GGPInfo *info;
1841 struct gg_event *ev; 1927 struct gg_event *ev;
1842 1928
1843 g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc)); 1929 g_return_if_fail(PURPLE_CONNECTION_IS_VALID(gc));
1844 1930
1845 info = gc->proto_data; 1931 info = purple_connection_get_protocol_data(gc);
1846 1932
1847 purple_debug_info("gg", "login_handler: session: check = %d; state = %d;\n", 1933 purple_debug_info("gg", "login_handler: session: check = %d; state = %d;\n",
1848 info->session->check, info->session->state); 1934 info->session->check, info->session->state);
1849 1935
1850 switch (info->session->state) { 1936 switch (info->session->state) {
1878 break; 1964 break;
1879 } 1965 }
1880 1966
1881 if (!(ev = gg_watch_fd(info->session))) { 1967 if (!(ev = gg_watch_fd(info->session))) {
1882 purple_debug_error("gg", "login_handler: gg_watch_fd failed!\n"); 1968 purple_debug_error("gg", "login_handler: gg_watch_fd failed!\n");
1883 purple_connection_error_reason (gc, 1969 purple_connection_error (gc,
1884 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 1970 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
1885 _("Unable to read from socket")); 1971 _("Unable to read from socket"));
1886 return; 1972 return;
1887 } 1973 }
1888 purple_debug_info("gg", "login_handler: session->fd = %d\n", info->session->fd); 1974 purple_debug_info("gg", "login_handler: session->fd = %d\n", info->session->fd);
1889 purple_debug_info("gg", "login_handler: session: check = %d; state = %d;\n", 1975 purple_debug_info("gg", "login_handler: session: check = %d; state = %d;\n",
1890 info->session->check, info->session->state); 1976 info->session->check, info->session->state);
1891 1977
1892 purple_input_remove(gc->inpa); 1978 purple_input_remove(info->inpa);
1979 info->inpa = 0;
1893 1980
1894 /** XXX I think that this shouldn't be done if ev->type is GG_EVENT_CONN_FAILED or GG_EVENT_CONN_SUCCESS -datallah */ 1981 /** XXX I think that this shouldn't be done if ev->type is GG_EVENT_CONN_FAILED or GG_EVENT_CONN_SUCCESS -datallah */
1895 if (info->session->fd >= 0) 1982 if (info->session->fd >= 0)
1896 gc->inpa = purple_input_add(info->session->fd, 1983 info->inpa = purple_input_add(info->session->fd,
1897 (info->session->check == 1) ? PURPLE_INPUT_WRITE : 1984 (info->session->check == 1) ? PURPLE_INPUT_WRITE :
1898 PURPLE_INPUT_READ, 1985 PURPLE_INPUT_READ,
1899 ggp_async_login_handler, gc); 1986 ggp_async_login_handler, gc);
1900 1987
1901 switch (ev->type) { 1988 switch (ev->type) {
1904 purple_debug_info("gg", "GG_EVENT_NONE\n"); 1991 purple_debug_info("gg", "GG_EVENT_NONE\n");
1905 break; 1992 break;
1906 case GG_EVENT_CONN_SUCCESS: 1993 case GG_EVENT_CONN_SUCCESS:
1907 { 1994 {
1908 purple_debug_info("gg", "GG_EVENT_CONN_SUCCESS\n"); 1995 purple_debug_info("gg", "GG_EVENT_CONN_SUCCESS\n");
1909 purple_input_remove(gc->inpa); 1996 purple_input_remove(info->inpa);
1910 gc->inpa = purple_input_add(info->session->fd, 1997 info->inpa = purple_input_add(info->session->fd,
1911 PURPLE_INPUT_READ, 1998 PURPLE_INPUT_READ,
1912 ggp_callback_recv, gc); 1999 ggp_callback_recv, gc);
1913 2000
1914 ggp_buddylist_send(gc); 2001 ggp_buddylist_send(gc);
1915 purple_connection_update_progress(gc, _("Connected"), 1, 2); 2002 purple_connection_update_progress(gc, _("Connected"), 1, 2);
1916 purple_connection_set_state(gc, PURPLE_CONNECTED); 2003 purple_connection_set_state(gc, PURPLE_CONNECTED);
1917 } 2004 }
1918 break; 2005 break;
1919 case GG_EVENT_CONN_FAILED: 2006 case GG_EVENT_CONN_FAILED:
1920 purple_input_remove(gc->inpa); 2007 purple_input_remove(info->inpa);
1921 gc->inpa = 0; 2008 info->inpa = 0;
1922 purple_connection_error_reason (gc, 2009 purple_debug_info("gg", "Connection failure: %d\n",
1923 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 2010 ev->event.failure);
1924 _("Connection failed")); 2011 switch (ev->event.failure) {
2012 case GG_FAILURE_RESOLVING:
2013 purple_connection_error(gc,
2014 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
2015 _("Unable to resolve "
2016 "hostname"));
2017 break;
2018 case GG_FAILURE_PASSWORD:
2019 purple_connection_error(gc,
2020 PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
2021 _("Incorrect password"));
2022 break;
2023 case GG_FAILURE_TLS:
2024 purple_connection_error(gc,
2025 PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR,
2026 _("SSL Connection Failed"));
2027 break;
2028 case GG_FAILURE_INTRUDER:
2029 purple_connection_error(gc,
2030 PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED,
2031 _("Your account has been "
2032 "disabled because too many "
2033 "incorrect passwords were "
2034 "entered"));
2035 break;
2036 case GG_FAILURE_UNAVAILABLE:
2037 purple_connection_error(gc,
2038 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
2039 _("Service temporarily "
2040 "unavailable"));
2041 break;
2042 case GG_FAILURE_PROXY:
2043 purple_connection_error(gc,
2044 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
2045 _("Error connecting to proxy "
2046 "server"));
2047 break;
2048 case GG_FAILURE_HUB:
2049 purple_connection_error(gc,
2050 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
2051 _("Error connecting to master "
2052 "server"));
2053 break;
2054 default:
2055 purple_connection_error(gc,
2056 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
2057 _("Connection failed"));
2058 }
1925 break; 2059 break;
1926 case GG_EVENT_MSG: 2060 case GG_EVENT_MSG:
1927 if (ev->event.msg.sender == 0) 2061 if (ev->event.msg.sender == 0)
2062 {
2063 if (ev->event.msg.message == NULL)
2064 break;
2065
1928 /* system messages are mostly ads */ 2066 /* system messages are mostly ads */
1929 purple_debug_info("gg", "System message:\n%s\n", 2067 purple_debug_info("gg", "System message:\n%s\n",
1930 ev->event.msg.message); 2068 ev->event.msg.message);
2069 }
1931 else 2070 else
1932 purple_debug_warning("gg", "GG_EVENT_MSG: message from user %u " 2071 purple_debug_warning("gg", "GG_EVENT_MSG: message from user %u "
1933 "unexpected while connecting:\n%s\n", 2072 "unexpected while connecting:\n%s\n",
1934 ev->event.msg.sender, 2073 ev->event.msg.sender,
1935 ev->event.msg.message); 2074 ev->event.msg.message);
1949 static const char *ggp_list_icon(PurpleAccount *account, PurpleBuddy *buddy) 2088 static const char *ggp_list_icon(PurpleAccount *account, PurpleBuddy *buddy)
1950 { 2089 {
1951 return "gadu-gadu"; 2090 return "gadu-gadu";
1952 } 2091 }
1953 2092
2093 static const char *ggp_normalize(const PurpleAccount *account, const char *who)
2094 {
2095 static char normalized[21]; /* maximum unsigned long long int size */
2096
2097 uin_t uin = ggp_str_to_uin(who);
2098 if (uin <= 0)
2099 return NULL;
2100
2101 g_snprintf(normalized, sizeof(normalized), "%u", uin);
2102
2103 return normalized;
2104 }
2105
1954 static char *ggp_status_text(PurpleBuddy *b) 2106 static char *ggp_status_text(PurpleBuddy *b)
1955 { 2107 {
1956 PurpleStatus *status; 2108 PurpleStatus *status;
1957 const char *msg; 2109 const char *msg;
1958 char *text; 2110 char *text;
1973 } 2125 }
1974 2126
1975 static void ggp_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full) 2127 static void ggp_tooltip_text(PurpleBuddy *b, PurpleNotifyUserInfo *user_info, gboolean full)
1976 { 2128 {
1977 PurpleStatus *status; 2129 PurpleStatus *status;
1978 char *text, *tmp; 2130 char *tmp;
1979 const char *msg, *name, *alias; 2131 const char *msg, *name, *alias;
1980 2132
1981 g_return_if_fail(b != NULL); 2133 g_return_if_fail(b != NULL);
1982 2134
1983 status = purple_presence_get_active_status(purple_buddy_get_presence(b)); 2135 status = purple_presence_get_active_status(purple_buddy_get_presence(b));
1984 msg = purple_status_get_attr_string(status, "message"); 2136 msg = purple_status_get_attr_string(status, "message");
1985 name = purple_status_get_name(status); 2137 name = purple_status_get_name(status);
1986 alias = purple_buddy_get_alias(b); 2138 alias = purple_buddy_get_alias(b);
1987 2139
1988 purple_notify_user_info_add_pair (user_info, _("Alias"), alias); 2140 purple_notify_user_info_add_pair_plaintext(user_info, _("Alias"), alias);
1989 2141
1990 if (msg != NULL) { 2142 if (msg != NULL) {
1991 text = g_markup_escape_text(msg, -1);
1992 if (PURPLE_BUDDY_IS_ONLINE(b)) { 2143 if (PURPLE_BUDDY_IS_ONLINE(b)) {
1993 tmp = g_strdup_printf("%s: %s", name, text); 2144 tmp = g_strdup_printf("%s: %s", name, msg);
1994 purple_notify_user_info_add_pair(user_info, _("Status"), tmp); 2145 purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), tmp);
1995 g_free(tmp); 2146 g_free(tmp);
1996 } else { 2147 } else {
1997 purple_notify_user_info_add_pair(user_info, _("Message"), text); 2148 purple_notify_user_info_add_pair_plaintext(user_info, _("Message"), msg);
1998 } 2149 }
1999 g_free(text);
2000 /* We don't want to duplicate 'Status: Offline'. */ 2150 /* We don't want to duplicate 'Status: Offline'. */
2001 } else if (PURPLE_BUDDY_IS_ONLINE(b)) { 2151 } else if (PURPLE_BUDDY_IS_ONLINE(b)) {
2002 purple_notify_user_info_add_pair(user_info, _("Status"), name); 2152 purple_notify_user_info_add_pair_plaintext(user_info, _("Status"), name);
2003 } 2153 }
2004 } 2154 }
2005 2155
2006 static GList *ggp_status_types(PurpleAccount *account) 2156 static GList *ggp_status_types(PurpleAccount *account)
2007 { 2157 {
2008 PurpleStatusType *type; 2158 PurpleStatusType *type;
2009 GList *types = NULL; 2159 GList *types = NULL;
2010 2160
2011 type = purple_status_type_new_with_attrs( 2161 type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
2012 PURPLE_STATUS_AVAILABLE, NULL, NULL, TRUE, TRUE, FALSE, 2162 NULL, NULL, TRUE, TRUE, FALSE,
2013 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), 2163 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
2014 NULL); 2164 NULL);
2015 types = g_list_append(types, type); 2165 types = g_list_append(types, type);
2016 2166
2017 /* 2167 /*
2018 * Without this selecting Invisible as own status doesn't 2168 * New status for GG 8.0: PoGGadaj ze mna (chatty).
2019 * work. It's not used and not needed to show status of buddies. 2169 * NOTE: at this time, this is used only to set our own status.
2020 */ 2170 */
2021 type = purple_status_type_new_with_attrs( 2171 type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE,
2022 PURPLE_STATUS_INVISIBLE, NULL, NULL, TRUE, TRUE, FALSE, 2172 "freeforchat", _("Chatty"), TRUE, TRUE, FALSE,
2023 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), 2173 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
2024 NULL); 2174 NULL);
2025 types = g_list_append(types, type); 2175 types = g_list_append(types, type);
2026 2176
2027 type = purple_status_type_new_with_attrs( 2177 type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY,
2028 PURPLE_STATUS_AWAY, NULL, NULL, TRUE, TRUE, FALSE, 2178 NULL, NULL, TRUE, TRUE, FALSE,
2029 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), 2179 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
2030 NULL); 2180 NULL);
2031 types = g_list_append(types, type); 2181 types = g_list_append(types, type);
2032 2182
2033 /* 2183 /*
2034 * New statuses for GG 8.0 like PoGGadaj ze mna (not yet because 2184 * New status for GG 8.0: Nie przeszkadzac (do not disturb).
2035 * libpurple can't support Chatty status) and Nie przeszkadzac
2036 */ 2185 */
2037 type = purple_status_type_new_with_attrs( 2186 type = purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE,
2038 PURPLE_STATUS_UNAVAILABLE, NULL, NULL, TRUE, TRUE, FALSE, 2187 NULL, NULL, TRUE, TRUE, FALSE,
2039 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), 2188 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
2040 NULL); 2189 NULL);
2190 types = g_list_append(types, type);
2191
2192 /*
2193 * It's used on buddy list if and only if it's showing our own
2194 * (invisible) status.
2195 */
2196 type = purple_status_type_new_with_attrs(PURPLE_STATUS_INVISIBLE,
2197 NULL, NULL, TRUE, TRUE, FALSE,
2198 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
2199 NULL);
2041 types = g_list_append(types, type); 2200 types = g_list_append(types, type);
2042 2201
2043 /* 2202 /*
2044 * This status is necessary to display guys who are blocking *us*. 2203 * This status is necessary to display guys who are blocking *us*.
2045 */ 2204 */
2046 type = purple_status_type_new_with_attrs( 2205 type = purple_status_type_new_with_attrs(PURPLE_STATUS_INVISIBLE,
2047 PURPLE_STATUS_INVISIBLE, "blocked", _("Blocked"), TRUE, FALSE, FALSE, 2206 "blocked", _("Blocked"), TRUE, FALSE, FALSE,
2048 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), NULL); 2207 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
2208 NULL);
2049 types = g_list_append(types, type); 2209 types = g_list_append(types, type);
2050 2210
2051 type = purple_status_type_new_with_attrs( 2211 type = purple_status_type_new_with_attrs(PURPLE_STATUS_OFFLINE,
2052 PURPLE_STATUS_OFFLINE, NULL, NULL, TRUE, TRUE, FALSE, 2212 NULL, NULL, TRUE, TRUE, FALSE,
2053 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), 2213 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING),
2054 NULL); 2214 NULL);
2055 types = g_list_append(types, type); 2215 types = g_list_append(types, type);
2056 2216
2057 return types; 2217 return types;
2058 } 2218 }
2059 2219
2060 static GList *ggp_blist_node_menu(PurpleBlistNode *node) 2220 static GList *ggp_blist_node_menu(PurpleBlistNode *node)
2061 { 2221 {
2062 PurpleMenuAction *act; 2222 PurpleMenuAction *act;
2063 GList *m = NULL; 2223 GList *m = NULL;
2064 PurpleAccount *account; 2224 PurpleAccount *account;
2225 PurpleConnection *gc;
2065 GGPInfo *info; 2226 GGPInfo *info;
2066 2227
2067 if (!PURPLE_BLIST_NODE_IS_BUDDY(node)) 2228 if (!PURPLE_BLIST_NODE_IS_BUDDY(node))
2068 return NULL; 2229 return NULL;
2069 2230
2070 account = purple_buddy_get_account((PurpleBuddy *) node); 2231 account = purple_buddy_get_account((PurpleBuddy *) node);
2071 info = purple_account_get_connection(account)->proto_data; 2232 gc = purple_account_get_connection(account);
2233 info = purple_connection_get_protocol_data(gc);
2072 if (info->chats) { 2234 if (info->chats) {
2073 act = purple_menu_action_new(_("Add to chat"), 2235 act = purple_menu_action_new(_("Add to chat"),
2074 PURPLE_CALLBACK(ggp_bmenu_add_to_chat), 2236 PURPLE_CALLBACK(ggp_bmenu_add_to_chat),
2075 NULL, NULL); 2237 NULL, NULL);
2076 m = g_list_append(m, act); 2238 m = g_list_append(m, act);
2118 info->searches = ggp_search_new(); 2280 info->searches = ggp_search_new();
2119 info->pending_richtext_messages = NULL; 2281 info->pending_richtext_messages = NULL;
2120 info->pending_images = g_hash_table_new(g_direct_hash, g_direct_equal); 2282 info->pending_images = g_hash_table_new(g_direct_hash, g_direct_equal);
2121 info->status_broadcasting = purple_account_get_bool(account, "status_broadcasting", TRUE); 2283 info->status_broadcasting = purple_account_get_bool(account, "status_broadcasting", TRUE);
2122 2284
2123 gc->proto_data = info; 2285 purple_connection_set_protocol_data(gc, info);
2124 2286
2125 glp->uin = ggp_get_uin(account); 2287 glp->uin = ggp_get_uin(account);
2126 glp->password = (char *)purple_account_get_password(account); 2288 glp->password = charset_convert(purple_account_get_password(account),
2289 "UTF-8", "CP1250");
2290
2291 if (glp->uin == 0) {
2292 purple_connection_error(gc,
2293 PURPLE_CONNECTION_ERROR_INVALID_USERNAME,
2294 _("The username specified is invalid."));
2295 g_free(glp);
2296 return;
2297 }
2298
2127 glp->image_size = 255; 2299 glp->image_size = 255;
2300 glp->status_flags = GG_STATUS_FLAG_UNKNOWN;
2301
2302 if (purple_account_get_bool(account, "show_links_from_strangers", 1))
2303 glp->status_flags |= GG_STATUS_FLAG_SPAM;
2128 2304
2129 presence = purple_account_get_presence(account); 2305 presence = purple_account_get_presence(account);
2130 status = purple_presence_get_active_status(presence); 2306 status = purple_presence_get_active_status(presence);
2131 2307
2132 glp->encoding = GG_ENCODING_UTF8; 2308 glp->encoding = GG_ENCODING_UTF8;
2134 |GG_FEATURE_TYPING_NOTIFICATION); 2310 |GG_FEATURE_TYPING_NOTIFICATION);
2135 2311
2136 glp->async = 1; 2312 glp->async = 1;
2137 glp->status = ggp_to_gg_status(status, &glp->status_descr); 2313 glp->status = ggp_to_gg_status(status, &glp->status_descr);
2138 2314
2139 encryption_type = purple_account_get_string(account, "encryption", "none"); 2315 encryption_type = purple_account_get_string(account, "encryption",
2140 purple_debug_info("gg", "Requested encryption type: %s\n", encryption_type); 2316 "opportunistic_tls");
2317 purple_debug_info("gg", "Requested encryption type: %s\n",
2318 encryption_type);
2141 if (strcmp(encryption_type, "opportunistic_tls") == 0) 2319 if (strcmp(encryption_type, "opportunistic_tls") == 0)
2142 glp->tls = 1; 2320 glp->tls = GG_SSL_ENABLED;
2143 else 2321 else if (strcmp(encryption_type, "require_tls") == 0) {
2144 glp->tls = 0; 2322 if (gg_libgadu_check_feature(GG_LIBGADU_FEATURE_SSL))
2145 purple_debug_info("gg", "TLS enabled: %d\n", glp->tls); 2323 glp->tls = GG_SSL_REQUIRED;
2324 else {
2325 purple_connection_error(gc,
2326 PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
2327 _("SSL support unavailable"));
2328 g_free(glp);
2329 return;
2330 }
2331 }
2332 else /* encryption_type == "none" */
2333 glp->tls = GG_SSL_DISABLED;
2334 purple_debug_info("gg", "TLS mode: %d\n", glp->tls);
2146 2335
2147 if (!info->status_broadcasting) 2336 if (!info->status_broadcasting)
2148 glp->status = glp->status|GG_STATUS_FRIENDS_MASK; 2337 glp->status = glp->status|GG_STATUS_FRIENDS_MASK;
2149 2338
2150 address = purple_account_get_string(account, "gg_server", ""); 2339 address = purple_account_get_string(account, "gg_server", "");
2155 purple_debug_info("gg", "Using gg server given by user (%s)\n", address); 2344 purple_debug_info("gg", "Using gg server given by user (%s)\n", address);
2156 2345
2157 if (addr == NULL) { 2346 if (addr == NULL) {
2158 gchar *tmp = g_strdup_printf(_("Unable to resolve hostname '%s': %s"), 2347 gchar *tmp = g_strdup_printf(_("Unable to resolve hostname '%s': %s"),
2159 address, g_strerror(errno)); 2348 address, g_strerror(errno));
2160 purple_connection_error_reason(gc, 2349 purple_connection_error(gc,
2161 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, /* should this be a settings error? */ 2350 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, /* should this be a settings error? */
2162 tmp); 2351 tmp);
2163 g_free(tmp); 2352 g_free(tmp);
2164 return; 2353 return;
2165 } 2354 }
2170 purple_debug_info("gg", "Trying to retrieve address from gg appmsg service\n"); 2359 purple_debug_info("gg", "Trying to retrieve address from gg appmsg service\n");
2171 2360
2172 info->session = gg_login(glp); 2361 info->session = gg_login(glp);
2173 purple_connection_update_progress(gc, _("Connecting"), 0, 2); 2362 purple_connection_update_progress(gc, _("Connecting"), 0, 2);
2174 if (info->session == NULL) { 2363 if (info->session == NULL) {
2175 purple_connection_error_reason (gc, 2364 purple_connection_error (gc,
2176 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 2365 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
2177 _("Connection failed")); 2366 _("Connection failed"));
2178 g_free(glp); 2367 g_free(glp);
2179 return; 2368 return;
2180 } 2369 }
2181 gc->inpa = purple_input_add(info->session->fd, PURPLE_INPUT_READ, 2370 info->inpa = purple_input_add(info->session->fd, PURPLE_INPUT_READ,
2182 ggp_async_login_handler, gc); 2371 ggp_async_login_handler, gc);
2183 } 2372 }
2184 2373
2185 static void ggp_close(PurpleConnection *gc) 2374 static void ggp_close(PurpleConnection *gc)
2186 { 2375 {
2376 PurpleAccount *account;
2377 GGPInfo *info;;
2187 2378
2188 if (gc == NULL) { 2379 if (gc == NULL) {
2189 purple_debug_info("gg", "gc == NULL\n"); 2380 purple_debug_info("gg", "gc == NULL\n");
2190 return; 2381 return;
2191 } 2382 }
2192 2383
2193 if (gc->proto_data) { 2384 account = purple_connection_get_account(gc);
2194 PurpleAccount *account = purple_connection_get_account(gc); 2385 info = purple_connection_get_protocol_data(gc);
2195 PurpleStatus *status; 2386
2196 GGPInfo *info = gc->proto_data; 2387 if (info) {
2197 2388 PurpleStatus *status = purple_account_get_active_status(account);
2198 status = purple_account_get_active_status(account);
2199 2389
2200 if (info->session != NULL) { 2390 if (info->session != NULL) {
2201 ggp_set_status(account, status); 2391 ggp_set_status(account, status);
2202 gg_logoff(info->session); 2392 gg_logoff(info->session);
2203 gg_free_session(info->session); 2393 gg_free_session(info->session);
2211 purple_notify_close_with_handle(gc); 2401 purple_notify_close_with_handle(gc);
2212 2402
2213 ggp_search_destroy(info->searches); 2403 ggp_search_destroy(info->searches);
2214 g_list_free(info->pending_richtext_messages); 2404 g_list_free(info->pending_richtext_messages);
2215 g_hash_table_destroy(info->pending_images); 2405 g_hash_table_destroy(info->pending_images);
2406
2407 if (info->inpa > 0)
2408 purple_input_remove(info->inpa);
2409
2410 purple_connection_set_protocol_data(gc, NULL);
2216 g_free(info); 2411 g_free(info);
2217 gc->proto_data = NULL; 2412 }
2218 }
2219
2220 if (gc->inpa > 0)
2221 purple_input_remove(gc->inpa);
2222 2413
2223 purple_debug_info("gg", "Connection closed.\n"); 2414 purple_debug_info("gg", "Connection closed.\n");
2224 } 2415 }
2225 2416
2226 static int ggp_send_im(PurpleConnection *gc, const char *who, const char *msg, 2417 static int ggp_send_im(PurpleConnection *gc, const char *who, const char *msg,
2227 PurpleMessageFlags flags) 2418 PurpleMessageFlags flags)
2228 { 2419 {
2229 GGPInfo *info = gc->proto_data; 2420 GGPInfo *info = purple_connection_get_protocol_data(gc);
2230 char *tmp, *plain; 2421 char *tmp, *plain;
2231 int ret = 1; 2422 int ret = 1;
2232 unsigned char format[1024]; 2423 unsigned char format[1024];
2233 unsigned int format_length = sizeof(struct gg_msg_richtext); 2424 unsigned int format_length = sizeof(struct gg_msg_richtext);
2234 gint pos = 0; 2425 gint pos = 0;
2342 return ret; 2533 return ret;
2343 } 2534 }
2344 2535
2345 static unsigned int ggp_send_typing(PurpleConnection *gc, const char *name, PurpleTypingState state) 2536 static unsigned int ggp_send_typing(PurpleConnection *gc, const char *name, PurpleTypingState state)
2346 { 2537 {
2538 GGPInfo *info = purple_connection_get_protocol_data(gc);
2347 int dummy_length; // we don't send real length of typed message 2539 int dummy_length; // we don't send real length of typed message
2348 2540
2349 if (state == PURPLE_TYPED) // not supported 2541 if (state == PURPLE_TYPED) // not supported
2350 return 1; 2542 return 1;
2351 2543
2353 dummy_length = (int)g_random_int(); 2545 dummy_length = (int)g_random_int();
2354 else // PURPLE_NOT_TYPING 2546 else // PURPLE_NOT_TYPING
2355 dummy_length = 0; 2547 dummy_length = 0;
2356 2548
2357 gg_typing_notification( 2549 gg_typing_notification(
2358 ((GGPInfo*)gc->proto_data)->session, 2550 info->session,
2359 ggp_str_to_uin(name), 2551 ggp_str_to_uin(name),
2360 dummy_length); 2552 dummy_length);
2361 2553
2362 return 1; // wait 1 second before another notification 2554 return 1; // wait 1 second before another notification
2363 } 2555 }
2364 2556
2365 static void ggp_get_info(PurpleConnection *gc, const char *name) 2557 static void ggp_get_info(PurpleConnection *gc, const char *name)
2366 { 2558 {
2367 GGPInfo *info = gc->proto_data; 2559 GGPInfo *info = purple_connection_get_protocol_data(gc);
2368 GGPSearchForm *form; 2560 GGPSearchForm *form;
2369 guint32 seq; 2561 guint32 seq;
2370 2562
2371 form = ggp_search_form_new(GGP_SEARCH_TYPE_INFO); 2563 form = ggp_search_form_new(GGP_SEARCH_TYPE_INFO);
2372 2564
2390 status_id); 2582 status_id);
2391 2583
2392 if (strcmp(status_id, "available") == 0) { 2584 if (strcmp(status_id, "available") == 0) {
2393 new_status = GG_STATUS_AVAIL; 2585 new_status = GG_STATUS_AVAIL;
2394 new_status_descr = GG_STATUS_AVAIL_DESCR; 2586 new_status_descr = GG_STATUS_AVAIL_DESCR;
2587 } else if (strcmp(status_id, "freeforchat") == 0) {
2588 new_status = GG_STATUS_FFC;
2589 new_status_descr = GG_STATUS_FFC_DESCR;
2395 } else if (strcmp(status_id, "away") == 0) { 2590 } else if (strcmp(status_id, "away") == 0) {
2396 new_status = GG_STATUS_BUSY; 2591 new_status = GG_STATUS_BUSY;
2397 new_status_descr = GG_STATUS_BUSY_DESCR; 2592 new_status_descr = GG_STATUS_BUSY_DESCR;
2398 } else if (strcmp(status_id, "unavailable") == 0) { 2593 } else if (strcmp(status_id, "unavailable") == 0) {
2399 new_status = GG_STATUS_DND; 2594 new_status = GG_STATUS_DND;
2438 2633
2439 if (!purple_status_is_active(status)) 2634 if (!purple_status_is_active(status))
2440 return; 2635 return;
2441 2636
2442 gc = purple_account_get_connection(account); 2637 gc = purple_account_get_connection(account);
2443 info = gc->proto_data; 2638 info = purple_connection_get_protocol_data(gc);
2444 2639
2445 new_status = ggp_to_gg_status(status, &new_msg); 2640 new_status = ggp_to_gg_status(status, &new_msg);
2446 2641
2447 if (!info->status_broadcasting) 2642 if (!info->status_broadcasting)
2448 new_status = new_status|GG_STATUS_FRIENDS_MASK; 2643 new_status = new_status|GG_STATUS_FRIENDS_MASK;
2456 2651
2457 ggp_status_fake_to_self(account); 2652 ggp_status_fake_to_self(account);
2458 2653
2459 } 2654 }
2460 2655
2461 static void ggp_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group) 2656 static void ggp_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group, const char *message)
2462 { 2657 {
2463 PurpleAccount *account; 2658 PurpleAccount *account;
2464 GGPInfo *info = gc->proto_data; 2659 GGPInfo *info = purple_connection_get_protocol_data(gc);
2465 const gchar *name = purple_buddy_get_name(buddy); 2660 const gchar *name = purple_buddy_get_name(buddy);
2466 2661
2467 gg_add_notify(info->session, ggp_str_to_uin(name)); 2662 gg_add_notify(info->session, ggp_str_to_uin(name));
2468 2663
2469 account = purple_connection_get_account(gc); 2664 account = purple_connection_get_account(gc);
2473 } 2668 }
2474 2669
2475 static void ggp_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy, 2670 static void ggp_remove_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
2476 PurpleGroup *group) 2671 PurpleGroup *group)
2477 { 2672 {
2478 GGPInfo *info = gc->proto_data; 2673 GGPInfo *info = purple_connection_get_protocol_data(gc);
2479 2674
2480 gg_remove_notify(info->session, ggp_str_to_uin(purple_buddy_get_name(buddy))); 2675 gg_remove_notify(info->session, ggp_str_to_uin(purple_buddy_get_name(buddy)));
2481 } 2676 }
2482 2677
2483 static void ggp_join_chat(PurpleConnection *gc, GHashTable *data) 2678 static void ggp_join_chat(PurpleConnection *gc, GHashTable *data)
2484 { 2679 {
2485 GGPInfo *info = gc->proto_data; 2680 GGPInfo *info = purple_connection_get_protocol_data(gc);
2486 GGPChat *chat; 2681 GGPChat *chat;
2487 char *chat_name; 2682 char *chat_name;
2488 GList *l; 2683 GList *l;
2489 PurpleConversation *conv; 2684 PurpleConversation *conv;
2490 PurpleAccount *account = purple_connection_get_account(gc); 2685 PurpleAccount *account = purple_connection_get_account(gc);
2518 } 2713 }
2519 2714
2520 static int ggp_chat_send(PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags) 2715 static int ggp_chat_send(PurpleConnection *gc, int id, const char *message, PurpleMessageFlags flags)
2521 { 2716 {
2522 PurpleConversation *conv; 2717 PurpleConversation *conv;
2523 GGPInfo *info = gc->proto_data; 2718 GGPInfo *info = purple_connection_get_protocol_data(gc);
2524 GGPChat *chat = NULL; 2719 GGPChat *chat = NULL;
2525 GList *l; 2720 GList *l;
2526 /* char *msg, *plain; */ 2721 /* char *msg, *plain; */
2527 gchar *msg; 2722 gchar *msg;
2528 uin_t *uins; 2723 uin_t *uins;
2532 return -EINVAL; 2727 return -EINVAL;
2533 2728
2534 for (l = info->chats; l != NULL; l = l->next) { 2729 for (l = info->chats; l != NULL; l = l->next) {
2535 chat = l->data; 2730 chat = l->data;
2536 2731
2537 if (g_utf8_collate(chat->name, conv->name) == 0) { 2732 if (g_utf8_collate(chat->name, purple_conversation_get_name(conv)) == 0) {
2538 break; 2733 break;
2539 } 2734 }
2540 2735
2541 chat = NULL; 2736 chat = NULL;
2542 } 2737 }
2573 return 0; 2768 return 0;
2574 } 2769 }
2575 2770
2576 static void ggp_keepalive(PurpleConnection *gc) 2771 static void ggp_keepalive(PurpleConnection *gc)
2577 { 2772 {
2578 GGPInfo *info = gc->proto_data; 2773 GGPInfo *info = purple_connection_get_protocol_data(gc);
2579 2774
2580 /* purple_debug_info("gg", "Keeping connection alive....\n"); */ 2775 /* purple_debug_info("gg", "Keeping connection alive....\n"); */
2581 2776
2582 if (gg_ping(info->session) < 0) { 2777 if (gg_ping(info->session) < 0) {
2583 purple_debug_info("gg", "Not connected to the server " 2778 purple_debug_info("gg", "Not connected to the server "
2584 "or gg_session is not correct\n"); 2779 "or gg_session is not correct\n");
2585 purple_connection_error_reason (gc, 2780 purple_connection_error (gc,
2586 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, 2781 PURPLE_CONNECTION_ERROR_NETWORK_ERROR,
2587 _("Not connected to the server")); 2782 _("Not connected to the server"));
2588 } 2783 }
2589 } 2784 }
2590 2785
2597 2792
2598 static GList *ggp_actions(PurplePlugin *plugin, gpointer context) 2793 static GList *ggp_actions(PurplePlugin *plugin, gpointer context)
2599 { 2794 {
2600 GList *m = NULL; 2795 GList *m = NULL;
2601 PurplePluginAction *act; 2796 PurplePluginAction *act;
2797
2798 act = purple_plugin_action_new(_("Change password..."),
2799 ggp_change_passwd);
2800 m = g_list_append(m, act);
2602 2801
2603 act = purple_plugin_action_new(_("Find buddies..."), 2802 act = purple_plugin_action_new(_("Find buddies..."),
2604 ggp_find_buddies); 2803 ggp_find_buddies);
2605 m = g_list_append(m, act); 2804 m = g_list_append(m, act);
2606 2805
2607 m = g_list_append(m, NULL); 2806 act = purple_plugin_action_new(_("Change status broadcasting"),
2608 2807 ggp_action_change_status_broadcasting);
2609 act = purple_plugin_action_new(_("Change password..."),
2610 ggp_change_passwd);
2611 m = g_list_append(m, act); 2808 m = g_list_append(m, act);
2612 2809
2613 m = g_list_append(m, NULL); 2810 m = g_list_append(m, NULL);
2614 2811
2615 act = purple_plugin_action_new(_("Upload buddylist to Server"), 2812 act = purple_plugin_action_new(_("Upload buddylist to Server"),
2630 2827
2631 act = purple_plugin_action_new(_("Load buddylist from file..."), 2828 act = purple_plugin_action_new(_("Load buddylist from file..."),
2632 ggp_action_buddylist_load); 2829 ggp_action_buddylist_load);
2633 m = g_list_append(m, act); 2830 m = g_list_append(m, act);
2634 2831
2635 act = purple_plugin_action_new(_("Change status broadcasting"),
2636 ggp_action_change_status_broadcasting);
2637 m = g_list_append(m, act);
2638
2639 return m; 2832 return m;
2640 } 2833 }
2641 2834
2642 static gboolean ggp_offline_message(const PurpleBuddy *buddy) 2835 static gboolean ggp_offline_message(const PurpleBuddy *buddy)
2643 { 2836 {
2644 return TRUE; 2837 return TRUE;
2645 } 2838 }
2646 2839
2647 static PurplePluginProtocolInfo prpl_info = 2840 static PurplePluginProtocolInfo prpl_info =
2648 { 2841 {
2842 sizeof(PurplePluginProtocolInfo), /* struct_size */
2649 OPT_PROTO_REGISTER_NOSCREENNAME | OPT_PROTO_IM_IMAGE, 2843 OPT_PROTO_REGISTER_NOSCREENNAME | OPT_PROTO_IM_IMAGE,
2650 NULL, /* user_splits */ 2844 NULL, /* user_splits */
2651 NULL, /* protocol_options */ 2845 NULL, /* protocol_options */
2652 {"png", 32, 32, 96, 96, 0, PURPLE_ICON_SCALE_DISPLAY}, /* icon_spec */ 2846 {"png", 32, 32, 96, 96, 0, PURPLE_ICON_SCALE_DISPLAY}, /* icon_spec */
2653 ggp_list_icon, /* list_icon */ 2847 ggp_list_icon, /* list_icon */
2684 NULL, /* chat_whisper */ 2878 NULL, /* chat_whisper */
2685 ggp_chat_send, /* chat_send */ 2879 ggp_chat_send, /* chat_send */
2686 ggp_keepalive, /* keepalive */ 2880 ggp_keepalive, /* keepalive */
2687 ggp_register_user, /* register_user */ 2881 ggp_register_user, /* register_user */
2688 NULL, /* get_cb_info */ 2882 NULL, /* get_cb_info */
2689 NULL, /* get_cb_away */
2690 NULL, /* alias_buddy */ 2883 NULL, /* alias_buddy */
2691 NULL, /* group_buddy */ 2884 NULL, /* group_buddy */
2692 NULL, /* rename_group */ 2885 NULL, /* rename_group */
2693 NULL, /* buddy_free */ 2886 NULL, /* buddy_free */
2694 NULL, /* convo_closed */ 2887 NULL, /* convo_closed */
2695 NULL, /* normalize */ 2888 ggp_normalize, /* normalize */
2696 NULL, /* set_buddy_icon */ 2889 NULL, /* set_buddy_icon */
2697 NULL, /* remove_group */ 2890 NULL, /* remove_group */
2698 NULL, /* get_cb_real_name */ 2891 NULL, /* get_cb_real_name */
2699 NULL, /* set_chat_topic */ 2892 NULL, /* set_chat_topic */
2700 NULL, /* find_blist_chat */ 2893 NULL, /* find_blist_chat */
2709 NULL, /* send_raw */ 2902 NULL, /* send_raw */
2710 NULL, /* roomlist_room_serialize */ 2903 NULL, /* roomlist_room_serialize */
2711 NULL, /* unregister_user */ 2904 NULL, /* unregister_user */
2712 NULL, /* send_attention */ 2905 NULL, /* send_attention */
2713 NULL, /* get_attention_types */ 2906 NULL, /* get_attention_types */
2714 sizeof(PurplePluginProtocolInfo), /* struct_size */
2715 NULL, /* get_account_text_table */ 2907 NULL, /* get_account_text_table */
2716 NULL, /* initiate_media */ 2908 NULL, /* initiate_media */
2717 NULL, /* can_do_media */ 2909 NULL, /* can_do_media */
2718 NULL, /* get_moods */ 2910 NULL, /* get_moods */
2719 NULL, /* set_public_alias */ 2911 NULL, /* set_public_alias */
2720 NULL, /* get_public_alias */ 2912 NULL /* get_public_alias */
2721 NULL, /* add_buddy_with_invite */
2722 NULL /* add_buddies_with_invite */
2723 }; 2913 };
2724 2914
2725 static PurplePluginInfo info = { 2915 static PurplePluginInfo info = {
2726 PURPLE_PLUGIN_MAGIC, /* magic */ 2916 PURPLE_PLUGIN_MAGIC, /* magic */
2727 PURPLE_MAJOR_VERSION, /* major_version */ 2917 PURPLE_MAJOR_VERSION, /* major_version */
2783 static void init_plugin(PurplePlugin *plugin) 2973 static void init_plugin(PurplePlugin *plugin)
2784 { 2974 {
2785 PurpleAccountOption *option; 2975 PurpleAccountOption *option;
2786 GList *encryption_options = NULL; 2976 GList *encryption_options = NULL;
2787 2977
2788 option = purple_account_option_string_new(_("Nickname"),
2789 "nick", _("Gadu-Gadu User"));
2790 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
2791 option);
2792
2793 option = purple_account_option_string_new(_("GG server"), 2978 option = purple_account_option_string_new(_("GG server"),
2794 "gg_server", ""); 2979 "gg_server", "");
2795 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, 2980 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
2796 option); 2981 option);
2797 2982
2800 kvp->key = g_strdup((desc)); \ 2985 kvp->key = g_strdup((desc)); \
2801 kvp->value = g_strdup((v)); \ 2986 kvp->value = g_strdup((v)); \
2802 list = g_list_append(list, kvp); \ 2987 list = g_list_append(list, kvp); \
2803 } 2988 }
2804 2989
2805 ADD_VALUE(encryption_options, _("Don't use encryption"), "none");
2806 ADD_VALUE(encryption_options, _("Use encryption if available"), 2990 ADD_VALUE(encryption_options, _("Use encryption if available"),
2807 "opportunistic_tls"); 2991 "opportunistic_tls");
2808 #if 0
2809 /* TODO */
2810 ADD_VALUE(encryption_options, _("Require encryption"), "require_tls"); 2992 ADD_VALUE(encryption_options, _("Require encryption"), "require_tls");
2811 #endif 2993 ADD_VALUE(encryption_options, _("Don't use encryption"), "none");
2812 2994
2813 option = purple_account_option_list_new(_("Connection security"), 2995 option = purple_account_option_list_new(_("Connection security"),
2814 "encryption", encryption_options); 2996 "encryption", encryption_options);
2815 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, 2997 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
2816 option); 2998 option);
2817 2999
3000 option = purple_account_option_bool_new(_("Show links from strangers"),
3001 "show_links_from_strangers", 1);
3002 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
3003 option);
3004
2818 my_protocol = plugin; 3005 my_protocol = plugin;
2819 3006
2820 gg_debug_handler = purple_gg_debug_handler; 3007 gg_debug_handler = purple_gg_debug_handler;
3008
3009 #ifdef _WIN32
3010 gg_global_set_custom_resolver(ggp_resolver_win32thread_start,
3011 ggp_resolver_win32thread_cleanup);
3012 #endif
2821 } 3013 }
2822 3014
2823 PURPLE_INIT_PLUGIN(gg, init_plugin, info); 3015 PURPLE_INIT_PLUGIN(gg, init_plugin, info);
2824 3016
2825 /* vim: set ts=8 sts=0 sw=8 noet: */ 3017 /* vim: set ts=8 sts=0 sw=8 noet: */