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: */