Mercurial > pidgin
changeset 27467:2dff07ddcc83
merge of '90da8da01d8b8fa432adae5fd697ef4bad3582b5'
and 'f5644cc4891cdcc46fafcec5127d00e48aa48e22'
author | Elliott Sales de Andrade <qulogic@pidgin.im> |
---|---|
date | Sat, 11 Jul 2009 07:02:33 +0000 |
parents | 302934aea9fb (diff) ff18653ef9f4 (current diff) |
children | ef48fb87d8d2 |
files | |
diffstat | 26 files changed, 469 insertions(+), 87 deletions(-) [+] |
line wrap: on
line diff
--- a/finch/gntconv.c Sat Jul 11 07:01:00 2009 +0000 +++ b/finch/gntconv.c Sat Jul 11 07:02:33 2009 +0000 @@ -191,10 +191,7 @@ } else { - char *escape = g_markup_escape_text((*text == '/' ? text + 1 : text), -1); - char *apos = purple_strreplace(escape, "'", "'"); - g_free(escape); - escape = apos; + char *escape = purple_markup_escape_text((*text == '/' ? text + 1 : text), -1); switch (purple_conversation_get_type(ggconv->active_conv)) { case PURPLE_CONV_TYPE_IM:
--- a/libpurple/internal.h Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/internal.h Sat Jul 11 07:02:33 2009 +0000 @@ -230,6 +230,16 @@ # endif #endif +#ifdef HAVE_CONFIG_H +#if SIZEOF_TIME_T == 4 +# define PURPLE_TIME_T_MODIFIER "lu" +#elif SIZEOF_TIME_T == 8 +# define PURPLE_TIME_T_MODIFIER "zu" +#else +#error Unknown size of time_t +#endif +#endif + #include <glib-object.h> #ifndef G_DEFINE_TYPE
--- a/libpurple/protocols/jabber/buddy.c Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/protocols/jabber/buddy.c Sat Jul 11 07:02:33 2009 +0000 @@ -2226,7 +2226,7 @@ const JabberCapsNodeExts *exts; if (!jbr->caps.info) { - purple_debug_error("jabber", + purple_debug_info("jabber", "Unable to find caps: nothing known about buddy\n"); return FALSE; }
--- a/libpurple/protocols/jabber/google.c Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/protocols/jabber/google.c Sat Jul 11 07:02:33 2009 +0000 @@ -1062,7 +1062,7 @@ js = (JabberStream*)(gc->proto_data); - if (!js || !js->server_caps & JABBER_CAP_GOOGLE_ROSTER) + if (!js || !(js->server_caps & JABBER_CAP_GOOGLE_ROSTER)) return; jb = jabber_buddy_find(js, who, TRUE); @@ -1132,7 +1132,7 @@ js = (JabberStream*)(gc->proto_data); - if (!js || !js->server_caps & JABBER_CAP_GOOGLE_ROSTER) + if (!js || !(js->server_caps & JABBER_CAP_GOOGLE_ROSTER)) return; buddies = purple_find_buddies(purple_connection_get_account(js->gc), who);
--- a/libpurple/protocols/jabber/jabber.c Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/protocols/jabber/jabber.c Sat Jul 11 07:02:33 2009 +0000 @@ -3371,6 +3371,7 @@ PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, "prpl-jabber", jabber_cmd_buzz, _("buzz: Buzz a user to get their attention"), NULL); + jabber_cmds = g_slist_prepend(jabber_cmds, GUINT_TO_POINTER(id)); } void jabber_unregister_commands(void)
--- a/libpurple/protocols/jabber/jutil.c Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/protocols/jabber/jutil.c Sat Jul 11 07:02:33 2009 +0000 @@ -64,16 +64,24 @@ if(strlen(str) > 1023) return FALSE; + /* + * TODO: An IPv6 address of the form [2001:470:1f05:d58::2] is also + * a valid XMPP domain portion. + */ c = str; while(c && *c) { gunichar ch = g_utf8_get_char(c); - if(!g_unichar_isgraph(ch)) + /* The list of characters allowed in domain names is pretty small */ + if ((ch <= 0x7F && !( (ch >= 'a' && ch <= 'z') + || (ch >= '0' && ch <= '9') + || (ch >= 'A' && ch <= 'Z') + || ch == '.' + || ch == '-' )) || (ch >= 0x80 && !g_unichar_isgraph(ch))) return FALSE; c = g_utf8_next_char(c); } - return TRUE; } @@ -103,20 +111,137 @@ JabberID* jabber_id_new(const char *str) { - char *at; - char *slash; + const char *at = NULL; + const char *slash = NULL; + const char *c; + gboolean needs_validation = FALSE; +#if 0 + gboolean node_is_required = FALSE; +#endif char *node = NULL; char *domain; JabberID *jid; - if(!str || !g_utf8_validate(str, -1, NULL)) + if (!str) + return NULL; + + for (c = str; *c != '\0'; c++) + { + switch (*c) { + case '@': + if (!slash) { + if (at) { + /* Multiple @'s in the node/domain portion, not a valid JID! */ + return NULL; + } + if (c == str) { + /* JIDs cannot start with @ */ + return NULL; + } + if (c[1] == '\0') { + /* JIDs cannot end with @ */ + return NULL; + } + at = c; + } + break; + + case '/': + if (!slash) { + if (c == str) { + /* JIDs cannot start with / */ + return NULL; + } + if (c[1] == '\0') { + /* JIDs cannot end with / */ + return NULL; + } + slash = c; + } + break; + + default: + /* characters allowed everywhere */ + if ((*c >= 'a' && *c <= 'z') + || (*c >= '0' && *c <= '9') + || (*c >= 'A' && *c <= 'Z') + || *c == '.' || *c == '-') + /* We're good */ + break; + +#if 0 + if (slash != NULL) { + /* characters allowed only in the resource */ + if (implement_me) + /* We're good */ + break; + } + + /* characters allowed only in the node */ + if (implement_me) { + /* + * Ok, this character is valid, but only if it's a part + * of the node and not the domain. But we don't know + * if "c" is a part of the node or the domain until after + * we've found the @. So set a flag for now and check + * that we found an @ later. + */ + node_is_required = TRUE; + break; + } +#endif + + /* + * Hmm, this character is a bit more exotic. Better fall + * back to using the more expensive UTF-8 compliant + * stringprep functions. + */ + needs_validation = TRUE; + break; + } + } + +#if 0 + if (node_is_required && at == NULL) + /* Found invalid characters in the domain */ + return NULL; +#endif + + if (!needs_validation) { + /* JID is made of only ASCII characters--just lowercase and return */ + jid = g_new0(JabberID, 1); + + if (at) { + jid->node = g_ascii_strdown(str, at - str); + if (slash) { + jid->domain = g_ascii_strdown(at + 1, slash - (at + 1)); + jid->resource = g_strdup(slash + 1); + } else { + jid->domain = g_ascii_strdown(at + 1, -1); + } + } else { + if (slash) { + jid->domain = g_ascii_strdown(str, slash - str); + jid->resource = g_strdup(slash + 1); + } else { + jid->domain = g_ascii_strdown(str, -1); + } + } + return jid; + } + + /* + * If we get here, there are some non-ASCII chars in the string, so + * we'll need to validate it, normalize, and finally do a full jabber + * nodeprep on the jid. + */ + + if (!g_utf8_validate(str, -1, NULL)) return NULL; jid = g_new0(JabberID, 1); - at = g_utf8_strchr(str, -1, '@'); - slash = g_utf8_strchr(str, -1, '/'); - + /* normalization */ if(at) { node = g_utf8_normalize(str, at-str, G_NORMALIZE_NFKC); if(slash) { @@ -144,6 +269,7 @@ g_free(domain); } + /* and finally the jabber nodeprep */ if(!jabber_nodeprep_validate(jid->node) || !jabber_nameprep_validate(jid->domain) || !jabber_resourceprep_validate(jid->resource)) {
--- a/libpurple/protocols/jabber/jutil.h Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/protocols/jabber/jutil.h Sat Jul 11 07:02:33 2009 +0000 @@ -45,6 +45,7 @@ gboolean jabber_is_own_account(JabberStream *js, const char *jid); gboolean jabber_nodeprep_validate(const char *); +/* TODO: This needs to be named jabber_domain_validate and handle IPv6/IDNA. */ gboolean jabber_nameprep_validate(const char *); gboolean jabber_resourceprep_validate(const char *);
--- a/libpurple/protocols/jabber/presence.c Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/protocols/jabber/presence.c Sat Jul 11 07:02:33 2009 +0000 @@ -762,6 +762,7 @@ purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(chat->conv), jid->resource, flags); } else if (g_str_equal(type, "unavailable")) { + xmlnode *x; gboolean nick_change = FALSE; gboolean kick = FALSE; gboolean is_our_resource = FALSE; /* Is the presence about us? */ @@ -784,28 +785,31 @@ is_our_resource = (0 == g_utf8_collate(jid->resource, chat->handle)); jabber_buddy_remove_resource(jb, jid->resource); - if(chat->muc) { - xmlnode *x; - for(x = xmlnode_get_child(packet, "x"); x; x = xmlnode_get_next_twin(x)) { - const char *xmlns, *nick, *code; - xmlnode *stat, *item; - if(!(xmlns = xmlnode_get_namespace(x)) || - strcmp(xmlns, "http://jabber.org/protocol/muc#user")) - continue; - if(!(stat = xmlnode_get_child(x, "status"))) - continue; - if(!(code = xmlnode_get_attrib(stat, "code"))) - continue; + + x = xmlnode_get_child_with_namespace(packet, "x", + "http://jabber.org/protocol/muc#user"); + if (chat->muc && x) { + const char *nick; + const char *code = NULL; + const char *item_jid = NULL; + xmlnode *stat; + xmlnode *item; - item = xmlnode_get_child(x, "item"); + item = xmlnode_get_child(x, "item"); + if (item) + item_jid = xmlnode_get_attrib(item, "jid"); + + stat = xmlnode_get_child(x, "status"); + + if (stat) + code = xmlnode_get_attrib(stat, "code"); + + if (code) { if(!strcmp(code, "301")) { /* XXX: we got banned */ - } else if(!strcmp(code, "303")) { - if (!item) - continue; - if(!(nick = xmlnode_get_attrib(item, "nick"))) - continue; + } else if(!strcmp(code, "303") && item && + (nick = xmlnode_get_attrib(item, "nick"))) { nick_change = TRUE; if(!strcmp(jid->resource, chat->handle)) { g_free(chat->handle); @@ -813,7 +817,8 @@ } purple_conv_chat_rename_user(PURPLE_CONV_CHAT(chat->conv), jid->resource, nick); jabber_chat_remove_handle(chat, jid->resource); - break; + /* TODO: Enable this when this is in a for-loop... + break; */ } else if(!strcmp(code, "307")) { /* Someone was kicked from the room */ xmlnode *reason = NULL, *actor = NULL; @@ -863,6 +868,21 @@ /* XXX: removed due to system shutdown */ } } + + /* + * Possibly another connected resource of our JID (see XEP-0045 + * v1.24 section 7.1.10) being disconnected. Should be + * distinguished by the item_jid. + * Also possibly works around bits of an Openfire bug. See + * #8319. + */ + if (is_our_resource && !purple_strequal(from, item_jid)) { + /* TODO: When the above is a loop, this needs to still act + * sanely for all cases (this code is a little fragile). */ + if (!kick && !nick_change) + /* Presumably, kicks and nick changes also affect us. */ + is_our_resource = FALSE; + } } if(!nick_change) { if (is_our_resource) {
--- a/libpurple/protocols/msnp9/command.c Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/protocols/msnp9/command.c Sat Jul 11 07:02:33 2009 +0000 @@ -59,7 +59,6 @@ if (cmd->params != NULL) { - char *param; int c; for (c = 0; cmd->params[c]; c++);
--- a/libpurple/protocols/oscar/clientlogin.c Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/protocols/oscar/clientlogin.c Sat Jul 11 07:02:33 2009 +0000 @@ -288,7 +288,7 @@ query_string = g_strdup_printf("a=%s" "&f=xml" "&k=%s" - "&ts=%zu" + "&ts=%" PURPLE_TIME_T_MODIFIER "&useTLS=0", oscar_auth_url_encode(token), get_client_key(od), hosttime); signature = generate_signature("GET", URL_START_OSCAR_SESSION,
--- a/libpurple/protocols/qq/buddy_opt.c Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/protocols/qq/buddy_opt.c Sat Jul 11 07:02:33 2009 +0000 @@ -1012,7 +1012,6 @@ guint16 flag1, flag2; g_return_if_fail(data != NULL && data_len >= 5); - g_return_if_fail(uid != 0); qd = (qq_data *) gc->proto_data;
--- a/libpurple/protocols/yahoo/libymsg.c Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/protocols/yahoo/libymsg.c Sat Jul 11 07:02:33 2009 +0000 @@ -1163,7 +1163,10 @@ struct yahoo_data *yd = add_req->gc->proto_data; struct yahoo_packet *pkt; char *encoded_msg = NULL; - PurpleAccount *account = purple_connection_get_account(add_req->gc); + const char *who = add_req->who; + + if (add_req->protocol == 2) + who += 4; /* Skip 'msn/' */ if (msg && *msg) encoded_msg = yahoo_string_encode(add_req->gc, msg, NULL); @@ -1171,9 +1174,10 @@ pkt = yahoo_packet_new(YAHOO_SERVICE_AUTH_REQ_15, YAHOO_STATUS_AVAILABLE, 0); - yahoo_packet_hash(pkt, "ssiiis", - 1, purple_normalize(account, purple_account_get_username(account)), - 5, add_req->who, + yahoo_packet_hash(pkt, "ssiiiis", + 1, add_req->id, + 5, who, + 241, add_req->protocol, 13, 2, 334, 0, 97, 1, @@ -1291,7 +1295,6 @@ switch (pair->key) { case 4: temp = pair->value; - add_req->who = g_strdup(pair->value); break; case 5: add_req->id = g_strdup(pair->value); @@ -3535,6 +3538,8 @@ g_free(yd->pending_chat_goto); g_strfreev(yd->profiles); + yahoo_personal_details_reset(&yd->ypd); + g_free(yd->current_list15_grp); g_free(yd); @@ -4009,9 +4014,13 @@ "Unable to request mail login token; forwarding to login screen."); purple_notify_uri(gc, yahoo_mail_url); } - } +static void +yahoo_set_userinfo_fn(PurplePluginAction *action) +{ + yahoo_set_userinfo(action->context); +} static void yahoo_show_act_id(PurplePluginAction *action) { @@ -4058,6 +4067,10 @@ GList *m = NULL; PurplePluginAction *act; + act = purple_plugin_action_new(_("Set User Info..."), + yahoo_set_userinfo_fn); + m = g_list_append(m, act); + act = purple_plugin_action_new(_("Activate ID..."), yahoo_show_act_id); m = g_list_append(m, act);
--- a/libpurple/protocols/yahoo/libymsg.h Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/protocols/yahoo/libymsg.h Sat Jul 11 07:02:33 2009 +0000 @@ -65,6 +65,9 @@ #define YAHOO_SMS_CARRIER_URL "http://lookup.msg.vip.mud.yahoo.com" +#define YAHOO_USERINFO_URL "http://address.yahoo.com/yab/us?v=XM&sync=1&tags=short&useutf8=1&noclear=1&legenc=codepage-1252" +#define YAHOOJP_USERINFO_URL "http://address.yahoo.co.jp/yab/jp?v=XM&sync=1&tags=short&useutf8=1&noclear=1&legenc=codepage-1252" + #define YAHOO_PICURL_SETTING "picture_url" #define YAHOO_PICCKSUM_SETTING "picture_checksum" #define YAHOO_PICEXPIRE_SETTING "picture_expire" @@ -147,6 +150,23 @@ struct _YchtConn; +typedef struct _YahooPersonalDetails { + char *id; + + struct { + char *first; + char *last; + char *middle; + char *nick; + } names; + + struct { + char *work; + char *home; + char *mobile; + } phone; +} YahooPersonalDetails; + struct yahoo_data { PurpleConnection *gc; int fd; @@ -157,6 +177,7 @@ GHashTable *friends; char **profiles; /* Multiple profiles can be associated with an account */ + YahooPersonalDetails ypd; /** * This is used to keep track of the IMVironment chosen
--- a/libpurple/protocols/yahoo/yahoo_aliases.c Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/protocols/yahoo/yahoo_aliases.c Sat Jul 11 07:02:33 2009 +0000 @@ -29,6 +29,7 @@ #include "blist.h" #include "debug.h" #include "util.h" +#include "request.h" #include "version.h" #include "libymsg.h" #include "yahoo_aliases.h" @@ -52,6 +53,17 @@ gchar *who; }; +void yahoo_personal_details_reset(YahooPersonalDetails *ypd) +{ + g_free(ypd->id); + g_free(ypd->names.first); + g_free(ypd->names.last); + g_free(ypd->names.middle); + g_free(ypd->names.nick); + g_free(ypd->phone.work); + g_free(ypd->phone.home); + g_free(ypd->phone.mobile); +} /************************************************************************** * Alias Fetch Functions @@ -60,8 +72,7 @@ static void yahoo_fetch_aliases_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, size_t len, const gchar *error_message) { - struct callback_data *cb = user_data; - PurpleConnection *gc = cb->gc; + PurpleConnection *gc = user_data; struct yahoo_data *yd = gc->proto_data; yd->url_datas = g_slist_remove(yd->url_datas, url_data); @@ -71,19 +82,19 @@ error_message ? " Error:" : "", error_message ? error_message : ""); } else { gchar *full_name, *nick_name; - const char *yid, *id, *fn, *ln, *nn, *alias; + const char *yid, *id, *fn, *ln, *nn, *alias, *mn; + const char *hp, *wp, *mo; YahooFriend *f; PurpleBuddy *b; xmlnode *item, *contacts; + PurpleAccount *account; + account = purple_connection_get_account(gc); /* Put our web response into a xmlnode for easy management */ contacts = xmlnode_from_str(url_text, -1); if (contacts == NULL) { purple_debug_error("yahoo", "Badly formed Alias XML\n"); - g_free(cb->who); - g_free(cb->id); - g_free(cb); return; } purple_debug_info("yahoo", "Fetched %" G_GSIZE_FORMAT @@ -97,8 +108,13 @@ fn = xmlnode_get_attrib(item, "fn"); ln = xmlnode_get_attrib(item, "ln"); nn = xmlnode_get_attrib(item, "nn"); + mn = xmlnode_get_attrib(item, "mn"); id = xmlnode_get_attrib(item, "id"); + hp = xmlnode_get_attrib(item, "hp"); + wp = xmlnode_get_attrib(item, "wp"); + mo = xmlnode_get_attrib(item, "mo"); + full_name = nick_name = NULL; alias = NULL; @@ -115,8 +131,8 @@ alias = full_name; /* If no Yahoo nickname, we can use the full_name created above */ /* Find the local buddy that matches */ - f = yahoo_friend_find(cb->gc, yid); - b = purple_find_buddy(cb->gc->account, yid); + f = yahoo_friend_find(gc, yid); + b = purple_find_buddy(account, yid); /* If we don't find a matching buddy, ignore the alias !! */ if (f != NULL && b != NULL) { @@ -125,13 +141,30 @@ /* Finally, if we received an alias, we better update the buddy list */ if (alias != NULL) { - serv_got_alias(cb->gc, yid, alias); + serv_got_alias(gc, yid, alias); purple_debug_info("yahoo", "Fetched alias '%s' (%s)\n", alias, id); } else if (buddy_alias != NULL && strcmp(buddy_alias, "") != 0) { /* Or if we have an alias that Yahoo doesn't, send it up */ - yahoo_update_alias(cb->gc, yid, buddy_alias); + yahoo_update_alias(gc, yid, buddy_alias); purple_debug_info("yahoo", "Sent updated alias '%s'\n", buddy_alias); } + } else { + /* May be the alias is for the account? */ + const char *yidn = purple_normalize(account, yid); + if (purple_strequal(yidn, purple_connection_get_display_name(gc))) { + yahoo_personal_details_reset(&yd->ypd); + + yd->ypd.id = g_strdup(id); + + yd->ypd.names.first = g_strdup(fn); + yd->ypd.names.middle = g_strdup(mn); + yd->ypd.names.last = g_strdup(ln); + yd->ypd.names.nick = g_strdup(nn); + + yd->ypd.phone.work = g_strdup(wp); + yd->ypd.phone.home = g_strdup(hp); + yd->ypd.phone.mobile = g_strdup(mo); + } } g_free(full_name); @@ -140,17 +173,12 @@ } xmlnode_free(contacts); } - - g_free(cb->who); - g_free(cb->id); - g_free(cb); } void yahoo_fetch_aliases(PurpleConnection *gc) { struct yahoo_data *yd = gc->proto_data; - struct callback_data *cb; const char *url; gchar *request, *webpage, *webaddress; PurpleUtilFetchUrlData *url_data; @@ -158,10 +186,6 @@ /* use whole URL if using HTTP Proxy */ gboolean use_whole_url = yahoo_account_use_http_proxy(gc); - /* Using callback_data so I have access to gc in the callback function */ - cb = g_new0(struct callback_data, 1); - cb->gc = gc; - /* Build all the info to make the web request */ url = yd->jp ? YAHOOJP_ALIAS_FETCH_URL : YAHOO_ALIAS_FETCH_URL; purple_url_parse(url, &webaddress, NULL, &webpage, NULL, NULL); @@ -177,7 +201,7 @@ /* We have a URL and some header information, let's connect and get some aliases */ url_data = purple_util_fetch_url_request_len_with_account(purple_connection_get_account(gc), url, use_whole_url, NULL, TRUE, request, FALSE, -1, - yahoo_fetch_aliases_cb, cb); + yahoo_fetch_aliases_cb, gc); if (url_data != NULL) yd->url_datas = g_slist_prepend(yd->url_datas, url_data); @@ -359,3 +383,104 @@ g_free(request); } + +/************************************************************************** + * User Info Update Functions + **************************************************************************/ + +static void +yahoo_set_userinfo_cb(PurpleConnection *gc, PurpleRequestFields *fields) +{ + xmlnode *node = xmlnode_new("ab"); + xmlnode *ct = xmlnode_new_child(node, "ct"); + struct yahoo_data *yd = purple_connection_get_protocol_data(gc); + PurpleAccount *account; + PurpleUtilFetchUrlData *url_data; + char *webaddress, *webpage; + char *request, *content; + int len; + int i; + char * yfields[] = { "fn", "ln", "nn", "mn", "hp", "wp", "mo", NULL }; + + account = purple_connection_get_account(gc); + + xmlnode_set_attrib(node, "k", purple_connection_get_display_name(gc)); + xmlnode_set_attrib(node, "cc", "1"); /* XXX: ? */ + + xmlnode_set_attrib(ct, "e", "1"); + xmlnode_set_attrib(ct, "yi", purple_connection_get_display_name(gc)); + xmlnode_set_attrib(ct, "id", yd->ypd.id); + xmlnode_set_attrib(ct, "pr", "0"); + + for (i = 0; yfields[i]; i++) { + const char *v = purple_request_fields_get_string(fields, yfields[i]); + xmlnode_set_attrib(ct, yfields[i], v ? v : ""); + } + + content = xmlnode_to_formatted_str(node, &len); + purple_url_parse(yd->jp ? YAHOOJP_USERINFO_URL : YAHOO_USERINFO_URL, &webaddress, NULL, &webpage, NULL, NULL); + + request = g_strdup_printf("POST %s HTTP/1.1\r\n" + "User-Agent: " YAHOO_CLIENT_USERAGENT "\r\n" + "Cookie: T=%s; path=/; domain=.yahoo.com; Y=%s;\r\n" + "Host: %s\r\n" + "Content-Length: %" G_GSIZE_FORMAT "\r\n" + "Cache-Control: no-cache\r\n\r\n" + "%s\r\n\r\n", + webpage, + yd->cookie_t, yd->cookie_y, + webaddress, + len + 4, + content); + + url_data = purple_util_fetch_url_request_len_with_account(account, webaddress, FALSE, + YAHOO_CLIENT_USERAGENT, TRUE, request, FALSE, -1, + yahoo_fetch_aliases_cb, gc); + if (url_data != NULL) + yd->url_datas = g_slist_prepend(yd->url_datas, url_data); + + g_free(webaddress); + g_free(webpage); + g_free(content); + g_free(request); + xmlnode_free(node); +} + +void yahoo_set_userinfo(PurpleConnection *gc) +{ + PurpleRequestFields *fields; + PurpleRequestFieldGroup *group; + PurpleRequestField *field; + struct yahoo_data *yd = purple_connection_get_protocol_data(gc); + int i; + struct { + char *id; + char *text; + char *value; + } yfields[] = { + {"fn", N_("First Name"), yd->ypd.names.first}, + {"ln", N_("Last Name"), yd->ypd.names.last}, + {"nn", N_("Nickname"), yd->ypd.names.nick}, + {"mn", N_("Middle Name"), yd->ypd.names.middle}, + {"hp", N_("Home Phone Number"), yd->ypd.phone.home}, + {"wp", N_("Work Phone Number"), yd->ypd.phone.work}, + {"mo", N_("Mobile Phone Number"), yd->ypd.phone.mobile}, + {NULL, NULL, NULL} + }; + + fields = purple_request_fields_new(); + group = purple_request_field_group_new(NULL); + purple_request_fields_add_group(fields, group); + + for (i = 0; yfields[i].id; i++) { + field = purple_request_field_string_new(yfields[i].id, _(yfields[i].text), + yfields[i].value, FALSE); + purple_request_field_group_add_field(group, field); + } + + purple_request_fields(gc, NULL, _("Set User Info"), NULL, fields, + _("OK"), G_CALLBACK(yahoo_set_userinfo_cb), + _("Cancel"), NULL, + purple_connection_get_account(gc), NULL, NULL, gc); +} +
--- a/libpurple/protocols/yahoo/yahoo_aliases.h Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/protocols/yahoo/yahoo_aliases.h Sat Jul 11 07:02:33 2009 +0000 @@ -35,4 +35,6 @@ void yahoo_update_alias(PurpleConnection *gc, const char *who, const char *alias); void yahoo_fetch_aliases(PurpleConnection *gc); +void yahoo_set_userinfo(PurpleConnection *gc); +void yahoo_personal_details_reset(YahooPersonalDetails *ypd);
--- a/libpurple/protocols/yahoo/yahoo_friend.h Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/protocols/yahoo/yahoo_friend.h Sat Jul 11 07:02:33 2009 +0000 @@ -56,7 +56,7 @@ YahooPresenceVisibility presence; int protocol; /* 1=LCS, 2=MSN*/ long int version_id; - gchar *alias_id; + gchar *alias_id; /* XXX: stick in a YahooPersonalDetails instead? */ YahooP2PStatus p2p_status; gboolean p2p_packet_sent; /* 0:not sent, 1=sent */ gint session_id; /* session id of friend */
--- a/libpurple/protocols/yahoo/yahoo_packet.c Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/protocols/yahoo/yahoo_packet.c Sat Jul 11 07:02:33 2009 +0000 @@ -187,7 +187,7 @@ pos = x; pkt->hash = g_slist_prepend(pkt->hash, pair); - if (purple_debug_is_verbose()) { + if (purple_debug_is_verbose() || g_getenv("PURPLE_YAHOO_DEBUG")) { char *esc; esc = g_strescape(pair->value, NULL); purple_debug_misc("yahoo", "Key: %d \tValue: %s\n", pair->key, esc);
--- a/libpurple/tests/test_jabber_jutil.c Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/tests/test_jabber_jutil.c Sat Jul 11 07:02:33 2009 +0000 @@ -68,6 +68,58 @@ } END_TEST +#define assert_valid_jid(str) { \ + JabberID *jid = jabber_id_new(str); \ + fail_if(jid == NULL, "JID '%s' is valid but jabber_id_new() rejected it", str); \ + jabber_id_free(jid); \ +} + +#define assert_invalid_jid(str) { \ + JabberID *jid = jabber_id_new(str); \ + fail_if(jid != NULL, "JID '%s' is invalid but jabber_id_new() allowed it", str); \ + jabber_id_free(jid); \ +} + +START_TEST(test_jabber_id_new) +{ + assert_valid_jid("gmail.com"); + assert_valid_jid("gmail.com/Test"); + assert_valid_jid("gmail.com/Test@"); + assert_valid_jid("gmail.com/@"); + assert_valid_jid("gmail.com/Test@alkjaweflkj"); + assert_valid_jid("mark.doliner@gmail.com"); + assert_valid_jid("mark.doliner@gmail.com/Test12345"); + assert_valid_jid("mark.doliner@gmail.com/Test@12345"); + assert_valid_jid("mark.doliner@gmail.com/Te/st@12@//345"); + assert_valid_jid("わいど@conference.jabber.org"); + assert_valid_jid("まりるーむ@conference.jabber.org"); + assert_valid_jid("mark.doliner@gmail.com/まりるーむ"); + assert_valid_jid("mark.doliner@gmail/stuff.org"); + assert_valid_jid("stuart@nödåtXäYZ.se"); + assert_valid_jid("stuart@nödåtXäYZ.se/まりるーむ"); + assert_valid_jid("mark.doliner@わいど.org"); + assert_valid_jid("nick@まつ.おおかみ.net"); + assert_valid_jid("paul@10.0.42.230/s"); +#if 0 +/* Uncomment these when jabber_domain_validate supports IPv6 addresses */ + assert_valid_jid("paul@[::1]"); /* IPv6 */ + assert_valid_jid("paul@[2001:470:1f05:d58::2]"); +#endif + + assert_invalid_jid("@gmail.com"); + assert_invalid_jid("@@gmail.com"); + assert_invalid_jid("mark.doliner@@gmail.com/Test12345"); + assert_invalid_jid("mark@doliner@gmail.com/Test12345"); + assert_invalid_jid("@gmail.com/Test@12345"); + assert_invalid_jid("/Test@12345"); + assert_invalid_jid("mark.doliner@"); + assert_invalid_jid("mark.doliner/"); + assert_invalid_jid("mark.doliner@gmail_stuff.org"); + assert_invalid_jid("mark.doliner@gmail[stuff.org"); + assert_invalid_jid("mark.doliner@gmail\\stuff.org"); +} +END_TEST + Suite * jabber_jutil_suite(void) { @@ -82,10 +134,11 @@ tcase_add_test(tc, test_get_bare_jid); suite_add_tcase(s, tc); - tc = tcase_create("Nodeprep validate"); + tc = tcase_create("JID validate"); tcase_add_test(tc, test_nodeprep_validate); tcase_add_test(tc, test_nodeprep_validate_illegal_chars); tcase_add_test(tc, test_nodeprep_validate_too_long); + tcase_add_test(tc, test_jabber_id_new); suite_add_tcase(s, tc); return s;
--- a/libpurple/tests/test_util.c Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/tests/test_util.c Sat Jul 11 07:02:33 2009 +0000 @@ -14,8 +14,7 @@ gsize sz = 0; guchar *out = purple_base16_decode("21646c726f77202c6f6c6c656800", &sz); fail_unless(sz == 14, NULL); - assert_string_equal("!dlrow ,olleh", (const char *)out); - g_free(out); + assert_string_equal_free("!dlrow ,olleh", (char *)out); } END_TEST @@ -30,8 +29,7 @@ gsize sz; guchar *out = purple_base64_decode("b3d0LXl0cm9mAA==", &sz); fail_unless(sz == 10, NULL); - assert_string_equal("owt-ytrof", (const char *)out); - g_free(out); + assert_string_equal_free("owt-ytrof", (char *)out); } END_TEST @@ -94,18 +92,15 @@ gchar *xhtml = NULL; gchar *plaintext = NULL; purple_markup_html_to_xhtml("<a>", &xhtml, &plaintext); - assert_string_equal("<a href=\"\"></a>", xhtml); - g_free(xhtml); - assert_string_equal("", plaintext); - g_free(plaintext); + assert_string_equal_free("<a href=\"\"></a>", xhtml); + assert_string_equal_free("", plaintext); } END_TEST START_TEST(test_mime_decode_field) { gchar *result = purple_mime_decode_field("=?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?="); - assert_string_equal("Keld Jørn Simonsen", result); - g_free(result); + assert_string_equal_free("Keld Jørn Simonsen", result); } END_TEST
--- a/libpurple/util.c Sat Jul 11 07:01:00 2009 +0000 +++ b/libpurple/util.c Sat Jul 11 07:02:33 2009 +0000 @@ -65,7 +65,7 @@ gboolean got_headers; gboolean has_explicit_data_len; char *webdata; - unsigned long len; + gsize len; unsigned long data_len; gssize max_len; gboolean chunked; @@ -3099,13 +3099,15 @@ { struct sockaddr addr; socklen_t namelen = sizeof(addr); + struct in_addr in; g_return_val_if_fail(fd != 0, NULL); if (getsockname(fd, &addr, &namelen)) return NULL; - return g_strdup(inet_ntoa(((struct sockaddr_in *)&addr)->sin_addr)); + in = ((struct sockaddr_in *)&addr)->sin_addr; + return g_strdup(inet_ntoa(in)); }
--- a/pidgin/plugins/gevolution/add_buddy_dialog.c Sat Jul 11 07:01:00 2009 +0000 +++ b/pidgin/plugins/gevolution/add_buddy_dialog.c Sat Jul 11 07:02:33 2009 +0000 @@ -234,6 +234,7 @@ EBook *book; gboolean status; GList *cards, *c; + GError *err = NULL; if (dialog->book != NULL) { @@ -250,10 +251,11 @@ gtk_list_store_clear(dialog->model); - if (!gevo_load_addressbook(uri, &book, NULL)) + if (!gevo_load_addressbook(uri, &book, &err)) { purple_debug_error("evolution", - "Error retrieving default addressbook\n"); + "Error retrieving default addressbook: %s\n", err->message); + g_error_free(err); return; }
--- a/pidgin/plugins/gevolution/assoc-buddy.c Sat Jul 11 07:01:00 2009 +0000 +++ b/pidgin/plugins/gevolution/assoc-buddy.c Sat Jul 11 07:02:33 2009 +0000 @@ -138,6 +138,7 @@ const char *prpl_id; gboolean status; GList *cards, *c; + GError *err = NULL; if (dialog->book != NULL) { @@ -154,10 +155,11 @@ gtk_list_store_clear(dialog->model); - if (!gevo_load_addressbook(uri, &book, NULL)) + if (!gevo_load_addressbook(uri, &book, &err)) { purple_debug_error("evolution", - "Error retrieving addressbook\n"); + "Error retrieving addressbook: %s\n", err->message); + g_error_free(err); return; }
--- a/pidgin/plugins/gevolution/eds-utils.c Sat Jul 11 07:01:00 2009 +0000 +++ b/pidgin/plugins/gevolution/eds-utils.c Sat Jul 11 07:02:33 2009 +0000 @@ -119,11 +119,13 @@ EBook *book; gboolean status; GList *cards; + GError *err = NULL; - if (!gevo_load_addressbook(uri, &book, NULL)) + if (!gevo_load_addressbook(uri, &book, &err)) { purple_debug_error("evolution", - "Error retrieving addressbook\n"); + "Error retrieving addressbook: %s\n", err->message); + g_error_free(err); return NULL; }
--- a/pidgin/plugins/gevolution/gevo-util.c Sat Jul 11 07:01:00 2009 +0000 +++ b/pidgin/plugins/gevolution/gevo-util.c Sat Jul 11 07:02:33 2009 +0000 @@ -143,11 +143,16 @@ g_return_val_if_fail(book != NULL, FALSE); if (uri == NULL) - *book = e_book_new_system_addressbook(NULL); + *book = e_book_new_system_addressbook(error); else *book = e_book_new_from_uri(uri, error); - result = e_book_open(*book, FALSE, NULL); + if (*book == NULL) + return FALSE; + + *error = NULL; + + result = e_book_open(*book, FALSE, error); if (!result && *book != NULL) {
--- a/pidgin/plugins/gevolution/gevolution.c Sat Jul 11 07:01:00 2009 +0000 +++ b/pidgin/plugins/gevolution/gevolution.c Sat Jul 11 07:02:33 2009 +0000 @@ -298,12 +298,18 @@ { PurplePlugin *plugin = (PurplePlugin *)data; EBookQuery *query; + GError *err = NULL; timer = 0; /* Maybe this is it? */ - if (!gevo_load_addressbook(NULL, &book, NULL)) + if (!gevo_load_addressbook(NULL, &book, &err)) + { + purple_debug_error("evolution", + "Error retrieving addressbook: %s\n", err->message); + g_error_free(err); return FALSE; + } query = e_book_query_any_field_contains("");
--- a/po/POTFILES.in Sat Jul 11 07:01:00 2009 +0000 +++ b/po/POTFILES.in Sat Jul 11 07:02:33 2009 +0000 @@ -176,6 +176,7 @@ libpurple/protocols/yahoo/libyahoo.c libpurple/protocols/yahoo/libyahoojp.c libpurple/protocols/yahoo/libymsg.c +libpurple/protocols/yahoo/yahoo_aliases.c libpurple/protocols/yahoo/yahoo_doodle.c libpurple/protocols/yahoo/yahoo_filexfer.c libpurple/protocols/yahoo/yahoo_packet.c