Mercurial > pidgin.yaz
comparison libpurple/protocols/gg/gg.c @ 32827:4a34689eeb33 default tip
merged from im.pidgin.pidgin
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Sat, 19 Nov 2011 14:42:54 +0900 |
parents | cb486df263ef |
children |
comparison
equal
deleted
inserted
replaced
32692:0f94ec89f0bc | 32827:4a34689eeb33 |
---|---|
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); |
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); |
416 PurpleRequestFields *fields) | 417 PurpleRequestFields *fields) |
417 { | 418 { |
418 GGPInfo *info = purple_connection_get_protocol_data(gc); | 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 |
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 |
623 { | |
624 guint inpa; | |
625 struct gg_http *http_req; | |
626 gchar *new_password; | |
627 PurpleAccount *account; | |
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) | |
622 { | 671 { |
623 PurpleAccount *account; | 672 PurpleAccount *account; |
624 GGPInfo *info = purple_connection_get_protocol_data(gc); | 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 |
698 | 761 |
699 GGPInfo *info = purple_connection_get_protocol_data(gc); | 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, |
1084 case GG_STATUS_NOT_AVAIL_DESCR: | 1151 case GG_STATUS_NOT_AVAIL_DESCR: |
1085 st = purple_primitive_get_id_from_type(PURPLE_STATUS_OFFLINE); | 1152 st = purple_primitive_get_id_from_type(PURPLE_STATUS_OFFLINE); |
1086 break; | 1153 break; |
1087 case GG_STATUS_FFC: | 1154 case GG_STATUS_FFC: |
1088 case GG_STATUS_FFC_DESCR: | 1155 case GG_STATUS_FFC_DESCR: |
1089 st = purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE); | 1156 st = "freeforchat"; |
1090 break; | 1157 break; |
1091 case GG_STATUS_AVAIL: | 1158 case GG_STATUS_AVAIL: |
1092 case GG_STATUS_AVAIL_DESCR: | 1159 case GG_STATUS_AVAIL_DESCR: |
1093 st = purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE); | 1160 st = purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE); |
1094 break; | 1161 break; |
1095 case GG_STATUS_BUSY: | 1162 case GG_STATUS_BUSY: |
1096 case GG_STATUS_BUSY_DESCR: | 1163 case GG_STATUS_BUSY_DESCR: |
1097 st = purple_primitive_get_id_from_type(PURPLE_STATUS_AWAY); | 1164 st = purple_primitive_get_id_from_type(PURPLE_STATUS_AWAY); |
1165 break; | |
1166 case GG_STATUS_INVISIBLE: | |
1167 case GG_STATUS_INVISIBLE_DESCR: | |
1168 st = purple_primitive_get_id_from_type(PURPLE_STATUS_INVISIBLE); | |
1098 break; | 1169 break; |
1099 case GG_STATUS_DND: | 1170 case GG_STATUS_DND: |
1100 case GG_STATUS_DND_DESCR: | 1171 case GG_STATUS_DND_DESCR: |
1101 st = purple_primitive_get_id_from_type(PURPLE_STATUS_UNAVAILABLE); | 1172 st = purple_primitive_get_id_from_type(PURPLE_STATUS_UNAVAILABLE); |
1102 break; | 1173 break; |
1442 GGPInfo *info = purple_connection_get_protocol_data(gc); | 1513 GGPInfo *info = purple_connection_get_protocol_data(gc); |
1443 PurpleConversation *conv; | 1514 PurpleConversation *conv; |
1444 gchar *from; | 1515 gchar *from; |
1445 gchar *msg; | 1516 gchar *msg; |
1446 gchar *tmp; | 1517 gchar *tmp; |
1518 time_t mtime; | |
1447 | 1519 |
1448 if (ev->event.msg.message == NULL) | 1520 if (ev->event.msg.message == NULL) |
1449 { | 1521 { |
1450 purple_debug_warning("gg", "ggp_recv_message_handler: NULL as message pointer\n"); | 1522 purple_debug_warning("gg", "ggp_recv_message_handler: NULL as message pointer\n"); |
1451 return; | 1523 return; |
1570 | 1642 |
1571 purple_debug_info("gg", "ggp_recv_message_handler: msg from (%s): %s (class = %d; rcpt_count = %d)\n", | 1643 purple_debug_info("gg", "ggp_recv_message_handler: msg from (%s): %s (class = %d; rcpt_count = %d)\n", |
1572 from, msg, ev->event.msg.msgclass, | 1644 from, msg, ev->event.msg.msgclass, |
1573 ev->event.msg.recipients_count); | 1645 ev->event.msg.recipients_count); |
1574 | 1646 |
1647 if (ev->event.msg.msgclass & GG_CLASS_QUEUED) | |
1648 mtime = ev->event.msg.time; | |
1649 else | |
1650 mtime = time(NULL); | |
1651 | |
1575 if (ev->event.msg.recipients_count == 0) { | 1652 if (ev->event.msg.recipients_count == 0) { |
1576 serv_got_im(gc, from, msg, 0, ev->event.msg.time); | 1653 serv_got_im(gc, from, msg, 0, mtime); |
1577 } else { | 1654 } else { |
1578 const char *chat_name; | 1655 const char *chat_name; |
1579 int chat_id; | 1656 int chat_id; |
1580 char *buddy_name; | 1657 char *buddy_name; |
1581 | 1658 |
1597 conv = ggp_confer_find_by_name(gc, chat_name); | 1674 conv = ggp_confer_find_by_name(gc, chat_name); |
1598 chat_id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)); | 1675 chat_id = purple_conv_chat_get_id(PURPLE_CONV_CHAT(conv)); |
1599 | 1676 |
1600 buddy_name = ggp_buddy_get_name(gc, ev->event.msg.sender); | 1677 buddy_name = ggp_buddy_get_name(gc, ev->event.msg.sender); |
1601 serv_got_chat_in(gc, chat_id, buddy_name, | 1678 serv_got_chat_in(gc, chat_id, buddy_name, |
1602 PURPLE_MESSAGE_RECV, msg, ev->event.msg.time); | 1679 PURPLE_MESSAGE_RECV, msg, mtime); |
1603 g_free(buddy_name); | 1680 g_free(buddy_name); |
1604 } | 1681 } |
1605 g_free(msg); | 1682 g_free(msg); |
1606 g_free(from); | 1683 g_free(from); |
1607 } | 1684 } |
1894 } | 1971 } |
1895 purple_debug_info("gg", "login_handler: session->fd = %d\n", info->session->fd); | 1972 purple_debug_info("gg", "login_handler: session->fd = %d\n", info->session->fd); |
1896 purple_debug_info("gg", "login_handler: session: check = %d; state = %d;\n", | 1973 purple_debug_info("gg", "login_handler: session: check = %d; state = %d;\n", |
1897 info->session->check, info->session->state); | 1974 info->session->check, info->session->state); |
1898 | 1975 |
1899 purple_input_remove(gc->inpa); | 1976 purple_input_remove(info->inpa); |
1977 info->inpa = 0; | |
1900 | 1978 |
1901 /** XXX I think that this shouldn't be done if ev->type is GG_EVENT_CONN_FAILED or GG_EVENT_CONN_SUCCESS -datallah */ | 1979 /** XXX I think that this shouldn't be done if ev->type is GG_EVENT_CONN_FAILED or GG_EVENT_CONN_SUCCESS -datallah */ |
1902 if (info->session->fd >= 0) | 1980 if (info->session->fd >= 0) |
1903 gc->inpa = purple_input_add(info->session->fd, | 1981 info->inpa = purple_input_add(info->session->fd, |
1904 (info->session->check == 1) ? PURPLE_INPUT_WRITE : | 1982 (info->session->check == 1) ? PURPLE_INPUT_WRITE : |
1905 PURPLE_INPUT_READ, | 1983 PURPLE_INPUT_READ, |
1906 ggp_async_login_handler, gc); | 1984 ggp_async_login_handler, gc); |
1907 | 1985 |
1908 switch (ev->type) { | 1986 switch (ev->type) { |
1911 purple_debug_info("gg", "GG_EVENT_NONE\n"); | 1989 purple_debug_info("gg", "GG_EVENT_NONE\n"); |
1912 break; | 1990 break; |
1913 case GG_EVENT_CONN_SUCCESS: | 1991 case GG_EVENT_CONN_SUCCESS: |
1914 { | 1992 { |
1915 purple_debug_info("gg", "GG_EVENT_CONN_SUCCESS\n"); | 1993 purple_debug_info("gg", "GG_EVENT_CONN_SUCCESS\n"); |
1916 purple_input_remove(gc->inpa); | 1994 purple_input_remove(info->inpa); |
1917 gc->inpa = purple_input_add(info->session->fd, | 1995 info->inpa = purple_input_add(info->session->fd, |
1918 PURPLE_INPUT_READ, | 1996 PURPLE_INPUT_READ, |
1919 ggp_callback_recv, gc); | 1997 ggp_callback_recv, gc); |
1920 | 1998 |
1921 ggp_buddylist_send(gc); | 1999 ggp_buddylist_send(gc); |
1922 purple_connection_update_progress(gc, _("Connected"), 1, 2); | 2000 purple_connection_update_progress(gc, _("Connected"), 1, 2); |
1923 purple_connection_set_state(gc, PURPLE_CONNECTED); | 2001 purple_connection_set_state(gc, PURPLE_CONNECTED); |
1924 } | 2002 } |
1925 break; | 2003 break; |
1926 case GG_EVENT_CONN_FAILED: | 2004 case GG_EVENT_CONN_FAILED: |
1927 purple_input_remove(gc->inpa); | 2005 purple_input_remove(info->inpa); |
1928 gc->inpa = 0; | 2006 info->inpa = 0; |
1929 purple_connection_error (gc, | 2007 purple_debug_info("gg", "Connection failure: %d\n", |
1930 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | 2008 ev->event.failure); |
1931 _("Connection failed")); | 2009 switch (ev->event.failure) { |
2010 case GG_FAILURE_RESOLVING: | |
2011 purple_connection_error(gc, | |
2012 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
2013 _("Unable to resolve " | |
2014 "hostname")); | |
2015 break; | |
2016 case GG_FAILURE_PASSWORD: | |
2017 purple_connection_error(gc, | |
2018 PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, | |
2019 _("Incorrect password")); | |
2020 break; | |
2021 case GG_FAILURE_TLS: | |
2022 purple_connection_error(gc, | |
2023 PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR, | |
2024 _("SSL Connection Failed")); | |
2025 break; | |
2026 case GG_FAILURE_INTRUDER: | |
2027 purple_connection_error(gc, | |
2028 PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, | |
2029 _("Your account has been " | |
2030 "disabled because too many " | |
2031 "incorrect passwords were " | |
2032 "entered")); | |
2033 break; | |
2034 case GG_FAILURE_UNAVAILABLE: | |
2035 purple_connection_error(gc, | |
2036 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
2037 _("Service temporarily " | |
2038 "unavailable")); | |
2039 break; | |
2040 case GG_FAILURE_PROXY: | |
2041 purple_connection_error(gc, | |
2042 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
2043 _("Error connecting to proxy " | |
2044 "server")); | |
2045 break; | |
2046 case GG_FAILURE_HUB: | |
2047 purple_connection_error(gc, | |
2048 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
2049 _("Error connecting to master " | |
2050 "server")); | |
2051 break; | |
2052 default: | |
2053 purple_connection_error(gc, | |
2054 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | |
2055 _("Connection failed")); | |
2056 } | |
1932 break; | 2057 break; |
1933 case GG_EVENT_MSG: | 2058 case GG_EVENT_MSG: |
1934 if (ev->event.msg.sender == 0) | 2059 if (ev->event.msg.sender == 0) |
2060 { | |
2061 if (ev->event.msg.message == NULL) | |
2062 break; | |
2063 | |
1935 /* system messages are mostly ads */ | 2064 /* system messages are mostly ads */ |
1936 purple_debug_info("gg", "System message:\n%s\n", | 2065 purple_debug_info("gg", "System message:\n%s\n", |
1937 ev->event.msg.message); | 2066 ev->event.msg.message); |
2067 } | |
1938 else | 2068 else |
1939 purple_debug_warning("gg", "GG_EVENT_MSG: message from user %u " | 2069 purple_debug_warning("gg", "GG_EVENT_MSG: message from user %u " |
1940 "unexpected while connecting:\n%s\n", | 2070 "unexpected while connecting:\n%s\n", |
1941 ev->event.msg.sender, | 2071 ev->event.msg.sender, |
1942 ev->event.msg.message); | 2072 ev->event.msg.message); |
1954 /* ---------------------------------------------------------------------- */ | 2084 /* ---------------------------------------------------------------------- */ |
1955 | 2085 |
1956 static const char *ggp_list_icon(PurpleAccount *account, PurpleBuddy *buddy) | 2086 static const char *ggp_list_icon(PurpleAccount *account, PurpleBuddy *buddy) |
1957 { | 2087 { |
1958 return "gadu-gadu"; | 2088 return "gadu-gadu"; |
2089 } | |
2090 | |
2091 static const char *ggp_normalize(const PurpleAccount *account, const char *who) | |
2092 { | |
2093 static char normalized[21]; /* maximum unsigned long long int size */ | |
2094 | |
2095 uin_t uin = ggp_str_to_uin(who); | |
2096 if (uin <= 0) | |
2097 return NULL; | |
2098 | |
2099 g_snprintf(normalized, sizeof(normalized), "%u", uin); | |
2100 | |
2101 return normalized; | |
1959 } | 2102 } |
1960 | 2103 |
1961 static char *ggp_status_text(PurpleBuddy *b) | 2104 static char *ggp_status_text(PurpleBuddy *b) |
1962 { | 2105 { |
1963 PurpleStatus *status; | 2106 PurpleStatus *status; |
2011 static GList *ggp_status_types(PurpleAccount *account) | 2154 static GList *ggp_status_types(PurpleAccount *account) |
2012 { | 2155 { |
2013 PurpleStatusType *type; | 2156 PurpleStatusType *type; |
2014 GList *types = NULL; | 2157 GList *types = NULL; |
2015 | 2158 |
2016 type = purple_status_type_new_with_attrs( | 2159 type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, |
2017 PURPLE_STATUS_AVAILABLE, NULL, NULL, TRUE, TRUE, FALSE, | 2160 NULL, NULL, TRUE, TRUE, FALSE, |
2018 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), | 2161 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), |
2019 NULL); | 2162 NULL); |
2020 types = g_list_append(types, type); | 2163 types = g_list_append(types, type); |
2021 | 2164 |
2022 /* | 2165 /* |
2023 * Without this selecting Invisible as own status doesn't | 2166 * New status for GG 8.0: PoGGadaj ze mna (chatty). |
2024 * work. It's not used and not needed to show status of buddies. | 2167 * NOTE: at this time, this is used only to set our own status. |
2025 */ | 2168 */ |
2026 type = purple_status_type_new_with_attrs( | 2169 type = purple_status_type_new_with_attrs(PURPLE_STATUS_AVAILABLE, |
2027 PURPLE_STATUS_INVISIBLE, NULL, NULL, TRUE, TRUE, FALSE, | 2170 "freeforchat", _("Chatty"), TRUE, TRUE, FALSE, |
2028 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), | 2171 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), |
2029 NULL); | 2172 NULL); |
2030 types = g_list_append(types, type); | 2173 types = g_list_append(types, type); |
2031 | 2174 |
2032 type = purple_status_type_new_with_attrs( | 2175 type = purple_status_type_new_with_attrs(PURPLE_STATUS_AWAY, |
2033 PURPLE_STATUS_AWAY, NULL, NULL, TRUE, TRUE, FALSE, | 2176 NULL, NULL, TRUE, TRUE, FALSE, |
2034 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), | 2177 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), |
2035 NULL); | 2178 NULL); |
2036 types = g_list_append(types, type); | 2179 types = g_list_append(types, type); |
2037 | 2180 |
2038 /* | 2181 /* |
2039 * New statuses for GG 8.0 like PoGGadaj ze mna (not yet because | 2182 * New status for GG 8.0: Nie przeszkadzac (do not disturb). |
2040 * libpurple can't support Chatty status) and Nie przeszkadzac | |
2041 */ | 2183 */ |
2042 type = purple_status_type_new_with_attrs( | 2184 type = purple_status_type_new_with_attrs(PURPLE_STATUS_UNAVAILABLE, |
2043 PURPLE_STATUS_UNAVAILABLE, NULL, NULL, TRUE, TRUE, FALSE, | 2185 NULL, NULL, TRUE, TRUE, FALSE, |
2044 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), | 2186 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), |
2045 NULL); | 2187 NULL); |
2188 types = g_list_append(types, type); | |
2189 | |
2190 /* | |
2191 * It's used on buddy list if and only if it's showing our own | |
2192 * (invisible) status. | |
2193 */ | |
2194 type = purple_status_type_new_with_attrs(PURPLE_STATUS_INVISIBLE, | |
2195 NULL, NULL, TRUE, TRUE, FALSE, | |
2196 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), | |
2197 NULL); | |
2046 types = g_list_append(types, type); | 2198 types = g_list_append(types, type); |
2047 | 2199 |
2048 /* | 2200 /* |
2049 * This status is necessary to display guys who are blocking *us*. | 2201 * This status is necessary to display guys who are blocking *us*. |
2050 */ | 2202 */ |
2051 type = purple_status_type_new_with_attrs( | 2203 type = purple_status_type_new_with_attrs(PURPLE_STATUS_INVISIBLE, |
2052 PURPLE_STATUS_INVISIBLE, "blocked", _("Blocked"), TRUE, FALSE, FALSE, | 2204 "blocked", _("Blocked"), TRUE, FALSE, FALSE, |
2053 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), NULL); | 2205 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), |
2206 NULL); | |
2054 types = g_list_append(types, type); | 2207 types = g_list_append(types, type); |
2055 | 2208 |
2056 type = purple_status_type_new_with_attrs( | 2209 type = purple_status_type_new_with_attrs(PURPLE_STATUS_OFFLINE, |
2057 PURPLE_STATUS_OFFLINE, NULL, NULL, TRUE, TRUE, FALSE, | 2210 NULL, NULL, TRUE, TRUE, FALSE, |
2058 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), | 2211 "message", _("Message"), purple_value_new(PURPLE_TYPE_STRING), |
2059 NULL); | 2212 NULL); |
2060 types = g_list_append(types, type); | 2213 types = g_list_append(types, type); |
2061 | 2214 |
2062 return types; | 2215 return types; |
2063 } | 2216 } |
2064 | 2217 |
2128 info->status_broadcasting = purple_account_get_bool(account, "status_broadcasting", TRUE); | 2281 info->status_broadcasting = purple_account_get_bool(account, "status_broadcasting", TRUE); |
2129 | 2282 |
2130 purple_connection_set_protocol_data(gc, info); | 2283 purple_connection_set_protocol_data(gc, info); |
2131 | 2284 |
2132 glp->uin = ggp_get_uin(account); | 2285 glp->uin = ggp_get_uin(account); |
2133 glp->password = (char *)purple_account_get_password(account); | 2286 glp->password = charset_convert(purple_account_get_password(account), |
2287 "UTF-8", "CP1250"); | |
2288 | |
2289 if (glp->uin == 0) { | |
2290 purple_connection_error(gc, | |
2291 PURPLE_CONNECTION_ERROR_INVALID_USERNAME, | |
2292 _("The username specified is invalid.")); | |
2293 g_free(glp); | |
2294 return; | |
2295 } | |
2296 | |
2134 glp->image_size = 255; | 2297 glp->image_size = 255; |
2298 glp->status_flags = GG_STATUS_FLAG_UNKNOWN; | |
2299 | |
2300 if (purple_account_get_bool(account, "show_links_from_strangers", 1)) | |
2301 glp->status_flags |= GG_STATUS_FLAG_SPAM; | |
2135 | 2302 |
2136 presence = purple_account_get_presence(account); | 2303 presence = purple_account_get_presence(account); |
2137 status = purple_presence_get_active_status(presence); | 2304 status = purple_presence_get_active_status(presence); |
2138 | 2305 |
2139 glp->encoding = GG_ENCODING_UTF8; | 2306 glp->encoding = GG_ENCODING_UTF8; |
2141 |GG_FEATURE_TYPING_NOTIFICATION); | 2308 |GG_FEATURE_TYPING_NOTIFICATION); |
2142 | 2309 |
2143 glp->async = 1; | 2310 glp->async = 1; |
2144 glp->status = ggp_to_gg_status(status, &glp->status_descr); | 2311 glp->status = ggp_to_gg_status(status, &glp->status_descr); |
2145 | 2312 |
2146 encryption_type = purple_account_get_string(account, "encryption", "none"); | 2313 encryption_type = purple_account_get_string(account, "encryption", |
2147 purple_debug_info("gg", "Requested encryption type: %s\n", encryption_type); | 2314 "opportunistic_tls"); |
2315 purple_debug_info("gg", "Requested encryption type: %s\n", | |
2316 encryption_type); | |
2148 if (strcmp(encryption_type, "opportunistic_tls") == 0) | 2317 if (strcmp(encryption_type, "opportunistic_tls") == 0) |
2149 glp->tls = 1; | 2318 glp->tls = GG_SSL_ENABLED; |
2150 else | 2319 else if (strcmp(encryption_type, "require_tls") == 0) { |
2151 glp->tls = 0; | 2320 if (gg_libgadu_check_feature(GG_LIBGADU_FEATURE_SSL)) |
2152 purple_debug_info("gg", "TLS enabled: %d\n", glp->tls); | 2321 glp->tls = GG_SSL_REQUIRED; |
2322 else { | |
2323 purple_connection_error(gc, | |
2324 PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, | |
2325 _("SSL support unavailable")); | |
2326 g_free(glp); | |
2327 return; | |
2328 } | |
2329 } | |
2330 else /* encryption_type == "none" */ | |
2331 glp->tls = GG_SSL_DISABLED; | |
2332 purple_debug_info("gg", "TLS mode: %d\n", glp->tls); | |
2153 | 2333 |
2154 if (!info->status_broadcasting) | 2334 if (!info->status_broadcasting) |
2155 glp->status = glp->status|GG_STATUS_FRIENDS_MASK; | 2335 glp->status = glp->status|GG_STATUS_FRIENDS_MASK; |
2156 | 2336 |
2157 address = purple_account_get_string(account, "gg_server", ""); | 2337 address = purple_account_get_string(account, "gg_server", ""); |
2183 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, | 2363 PURPLE_CONNECTION_ERROR_NETWORK_ERROR, |
2184 _("Connection failed")); | 2364 _("Connection failed")); |
2185 g_free(glp); | 2365 g_free(glp); |
2186 return; | 2366 return; |
2187 } | 2367 } |
2188 gc->inpa = purple_input_add(info->session->fd, PURPLE_INPUT_READ, | 2368 info->inpa = purple_input_add(info->session->fd, PURPLE_INPUT_READ, |
2189 ggp_async_login_handler, gc); | 2369 ggp_async_login_handler, gc); |
2190 } | 2370 } |
2191 | 2371 |
2192 static void ggp_close(PurpleConnection *gc) | 2372 static void ggp_close(PurpleConnection *gc) |
2193 { | 2373 { |
2219 purple_notify_close_with_handle(gc); | 2399 purple_notify_close_with_handle(gc); |
2220 | 2400 |
2221 ggp_search_destroy(info->searches); | 2401 ggp_search_destroy(info->searches); |
2222 g_list_free(info->pending_richtext_messages); | 2402 g_list_free(info->pending_richtext_messages); |
2223 g_hash_table_destroy(info->pending_images); | 2403 g_hash_table_destroy(info->pending_images); |
2404 | |
2405 if (info->inpa > 0) | |
2406 purple_input_remove(info->inpa); | |
2407 | |
2408 purple_connection_set_protocol_data(gc, NULL); | |
2224 g_free(info); | 2409 g_free(info); |
2225 purple_connection_set_protocol_data(gc, NULL); | 2410 } |
2226 } | |
2227 | |
2228 if (gc->inpa > 0) | |
2229 purple_input_remove(gc->inpa); | |
2230 | 2411 |
2231 purple_debug_info("gg", "Connection closed.\n"); | 2412 purple_debug_info("gg", "Connection closed.\n"); |
2232 } | 2413 } |
2233 | 2414 |
2234 static int ggp_send_im(PurpleConnection *gc, const char *who, const char *msg, | 2415 static int ggp_send_im(PurpleConnection *gc, const char *who, const char *msg, |
2399 status_id); | 2580 status_id); |
2400 | 2581 |
2401 if (strcmp(status_id, "available") == 0) { | 2582 if (strcmp(status_id, "available") == 0) { |
2402 new_status = GG_STATUS_AVAIL; | 2583 new_status = GG_STATUS_AVAIL; |
2403 new_status_descr = GG_STATUS_AVAIL_DESCR; | 2584 new_status_descr = GG_STATUS_AVAIL_DESCR; |
2585 } else if (strcmp(status_id, "freeforchat") == 0) { | |
2586 new_status = GG_STATUS_FFC; | |
2587 new_status_descr = GG_STATUS_FFC_DESCR; | |
2404 } else if (strcmp(status_id, "away") == 0) { | 2588 } else if (strcmp(status_id, "away") == 0) { |
2405 new_status = GG_STATUS_BUSY; | 2589 new_status = GG_STATUS_BUSY; |
2406 new_status_descr = GG_STATUS_BUSY_DESCR; | 2590 new_status_descr = GG_STATUS_BUSY_DESCR; |
2407 } else if (strcmp(status_id, "unavailable") == 0) { | 2591 } else if (strcmp(status_id, "unavailable") == 0) { |
2408 new_status = GG_STATUS_DND; | 2592 new_status = GG_STATUS_DND; |
2541 return -EINVAL; | 2725 return -EINVAL; |
2542 | 2726 |
2543 for (l = info->chats; l != NULL; l = l->next) { | 2727 for (l = info->chats; l != NULL; l = l->next) { |
2544 chat = l->data; | 2728 chat = l->data; |
2545 | 2729 |
2546 if (g_utf8_collate(chat->name, conv->name) == 0) { | 2730 if (g_utf8_collate(chat->name, purple_conversation_get_name(conv)) == 0) { |
2547 break; | 2731 break; |
2548 } | 2732 } |
2549 | 2733 |
2550 chat = NULL; | 2734 chat = NULL; |
2551 } | 2735 } |
2607 static GList *ggp_actions(PurplePlugin *plugin, gpointer context) | 2791 static GList *ggp_actions(PurplePlugin *plugin, gpointer context) |
2608 { | 2792 { |
2609 GList *m = NULL; | 2793 GList *m = NULL; |
2610 PurplePluginAction *act; | 2794 PurplePluginAction *act; |
2611 | 2795 |
2796 act = purple_plugin_action_new(_("Change password..."), | |
2797 ggp_change_passwd); | |
2798 m = g_list_append(m, act); | |
2799 | |
2612 act = purple_plugin_action_new(_("Find buddies..."), | 2800 act = purple_plugin_action_new(_("Find buddies..."), |
2613 ggp_find_buddies); | 2801 ggp_find_buddies); |
2614 m = g_list_append(m, act); | 2802 m = g_list_append(m, act); |
2615 | 2803 |
2616 m = g_list_append(m, NULL); | 2804 act = purple_plugin_action_new(_("Change status broadcasting"), |
2617 | 2805 ggp_action_change_status_broadcasting); |
2618 act = purple_plugin_action_new(_("Change password..."), | |
2619 ggp_change_passwd); | |
2620 m = g_list_append(m, act); | 2806 m = g_list_append(m, act); |
2621 | 2807 |
2622 m = g_list_append(m, NULL); | 2808 m = g_list_append(m, NULL); |
2623 | 2809 |
2624 act = purple_plugin_action_new(_("Upload buddylist to Server"), | 2810 act = purple_plugin_action_new(_("Upload buddylist to Server"), |
2639 | 2825 |
2640 act = purple_plugin_action_new(_("Load buddylist from file..."), | 2826 act = purple_plugin_action_new(_("Load buddylist from file..."), |
2641 ggp_action_buddylist_load); | 2827 ggp_action_buddylist_load); |
2642 m = g_list_append(m, act); | 2828 m = g_list_append(m, act); |
2643 | 2829 |
2644 act = purple_plugin_action_new(_("Change status broadcasting"), | |
2645 ggp_action_change_status_broadcasting); | |
2646 m = g_list_append(m, act); | |
2647 | |
2648 return m; | 2830 return m; |
2649 } | 2831 } |
2650 | 2832 |
2651 static gboolean ggp_offline_message(const PurpleBuddy *buddy) | 2833 static gboolean ggp_offline_message(const PurpleBuddy *buddy) |
2652 { | 2834 { |
2699 NULL, /* alias_buddy */ | 2881 NULL, /* alias_buddy */ |
2700 NULL, /* group_buddy */ | 2882 NULL, /* group_buddy */ |
2701 NULL, /* rename_group */ | 2883 NULL, /* rename_group */ |
2702 NULL, /* buddy_free */ | 2884 NULL, /* buddy_free */ |
2703 NULL, /* convo_closed */ | 2885 NULL, /* convo_closed */ |
2704 NULL, /* normalize */ | 2886 ggp_normalize, /* normalize */ |
2705 NULL, /* set_buddy_icon */ | 2887 NULL, /* set_buddy_icon */ |
2706 NULL, /* remove_group */ | 2888 NULL, /* remove_group */ |
2707 NULL, /* get_cb_real_name */ | 2889 NULL, /* get_cb_real_name */ |
2708 NULL, /* set_chat_topic */ | 2890 NULL, /* set_chat_topic */ |
2709 NULL, /* find_blist_chat */ | 2891 NULL, /* find_blist_chat */ |
2789 static void init_plugin(PurplePlugin *plugin) | 2971 static void init_plugin(PurplePlugin *plugin) |
2790 { | 2972 { |
2791 PurpleAccountOption *option; | 2973 PurpleAccountOption *option; |
2792 GList *encryption_options = NULL; | 2974 GList *encryption_options = NULL; |
2793 | 2975 |
2794 option = purple_account_option_string_new(_("Nickname"), | |
2795 "nick", _("Gadu-Gadu User")); | |
2796 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, | |
2797 option); | |
2798 | |
2799 option = purple_account_option_string_new(_("GG server"), | 2976 option = purple_account_option_string_new(_("GG server"), |
2800 "gg_server", ""); | 2977 "gg_server", ""); |
2801 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, | 2978 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, |
2802 option); | 2979 option); |
2803 | 2980 |
2806 kvp->key = g_strdup((desc)); \ | 2983 kvp->key = g_strdup((desc)); \ |
2807 kvp->value = g_strdup((v)); \ | 2984 kvp->value = g_strdup((v)); \ |
2808 list = g_list_append(list, kvp); \ | 2985 list = g_list_append(list, kvp); \ |
2809 } | 2986 } |
2810 | 2987 |
2811 ADD_VALUE(encryption_options, _("Don't use encryption"), "none"); | |
2812 ADD_VALUE(encryption_options, _("Use encryption if available"), | 2988 ADD_VALUE(encryption_options, _("Use encryption if available"), |
2813 "opportunistic_tls"); | 2989 "opportunistic_tls"); |
2814 #if 0 | |
2815 /* TODO */ | |
2816 ADD_VALUE(encryption_options, _("Require encryption"), "require_tls"); | 2990 ADD_VALUE(encryption_options, _("Require encryption"), "require_tls"); |
2817 #endif | 2991 ADD_VALUE(encryption_options, _("Don't use encryption"), "none"); |
2818 | 2992 |
2819 option = purple_account_option_list_new(_("Connection security"), | 2993 option = purple_account_option_list_new(_("Connection security"), |
2820 "encryption", encryption_options); | 2994 "encryption", encryption_options); |
2821 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, | 2995 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, |
2822 option); | 2996 option); |
2823 | 2997 |
2998 option = purple_account_option_bool_new(_("Show links from strangers"), | |
2999 "show_links_from_strangers", 1); | |
3000 prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, | |
3001 option); | |
3002 | |
2824 my_protocol = plugin; | 3003 my_protocol = plugin; |
2825 | 3004 |
2826 gg_debug_handler = purple_gg_debug_handler; | 3005 gg_debug_handler = purple_gg_debug_handler; |
3006 | |
3007 #ifdef _WIN32 | |
3008 gg_global_set_custom_resolver(ggp_resolver_win32thread_start, | |
3009 ggp_resolver_win32thread_cleanup); | |
3010 #endif | |
2827 } | 3011 } |
2828 | 3012 |
2829 PURPLE_INIT_PLUGIN(gg, init_plugin, info); | 3013 PURPLE_INIT_PLUGIN(gg, init_plugin, info); |
2830 | 3014 |
2831 /* vim: set ts=8 sts=0 sw=8 noet: */ | 3015 /* vim: set ts=8 sts=0 sw=8 noet: */ |