# HG changeset patch
# User Richard Laager
# Date 1190995030 0
# Node ID 5440eed4ec7ea7a41b18b0ebf6f620897c2e90a1
# Parent c320bc7b138320a2ad6376d50de0217ce5738616
applied changes from efedefa70ee1d6f7f4dd39afe5db10c7e5bfe64c
through afa2cfc77d5df43359af0e531c44167cf94d7d06
diff -r c320bc7b1383 -r 5440eed4ec7e libpurple/protocols/myspace/markup.c
--- a/libpurple/protocols/myspace/markup.c Fri Sep 28 15:56:31 2007 +0000
+++ b/libpurple/protocols/myspace/markup.c Fri Sep 28 15:57:10 2007 +0000
@@ -1,691 +1,691 @@
-/* MySpaceIM Protocol Plugin - markup
- *
- * Copyright (C) 2007, Jeff Connelly
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
-
-#include "myspace.h"
-
-typedef void (*MSIM_XMLNODE_CONVERT)(MsimSession *, xmlnode *, gchar **, gchar **);
-
-/* Internal functions */
-
-static guint msim_point_to_purple_size(MsimSession *session, guint point);
-static guint msim_purple_size_to_point(MsimSession *session, guint size);
-static guint msim_height_to_point(MsimSession *session, guint height);
-static guint msim_point_to_height(MsimSession *session, guint point);
-
-static void msim_markup_tag_to_html(MsimSession *, xmlnode *root, gchar **begin, gchar **end);
-static void html_tag_to_msim_markup(MsimSession *, xmlnode *root, gchar **begin, gchar **end);
-static gchar *msim_convert_xml(MsimSession *, const gchar *raw, MSIM_XMLNODE_CONVERT f);
-static gchar *msim_convert_smileys_to_markup(gchar *before);
-static double msim_round(double round);
-
-
-/* Globals */
-
-/* The names in in emoticon_names (for ) map to corresponding
- * entries in emoticon_symbols (for the ASCII representation of the emoticon).
- *
- * Multiple emoticon symbols in Pidgin can map to one name. List the
- * canonical form, as inserted by the "Smile!" dialog, first. For example,
- * :) comes before :-), because although both are recognized as 'happy',
- * the first is inserted by the smiley button (first symbol in theme).
- *
- * Note that symbols are case-sensitive in Pidgin -- :-X is not :-x. */
-static struct MSIM_EMOTICON
-{
- gchar *name;
- gchar *symbol;
-} msim_emoticons[] = {
- /* Unfortunately, this list duplicates much of the file
- * pidgin/pidgin/pixmaps/emotes/default/22/default.theme.in, because
- * that file is part of Pidgin, but we're part of libpurple.
- */
- { "bigsmile", ":D" },
- { "bigsmile", ":-D" },
- { "devil", "}:)" },
- { "frazzled", ":Z" },
- { "geek", "B)" },
- { "googles", "%)" },
- { "growl", ":E" },
- { "laugh", ":))" }, /* Must be before ':)' */
- { "happy", ":)" },
- { "happy", ":-)" },
- { "happi", ":)" },
- { "heart", ":X" },
- { "mohawk", "-:" },
- { "mad", "X(" },
- { "messed", "X)" },
- { "nerd", "Q)" },
- { "oops", ":G" },
- { "pirate", "P)" },
- { "scared", ":O" },
- { "sidefrown", ":{" },
- { "sinister", ":B" },
- { "smirk", ":," },
- { "straight", ":|" },
- { "tongue", ":P" },
- { "tongue", ":p" },
- { "tongy", ":P" },
- { "upset", "B|" },
- { "wink", ";-)" },
- { "wink", ";)" },
- { "winc", ";)" },
- { "worried", ":[" },
- { "kiss", ":x" },
- { NULL, NULL }
-};
-
-
-
-/* Indexes of this array + 1 map HTML font size to scale of normal font size. *
- * Based on _point_sizes from libpurple/gtkimhtml.c
- * 1 2 3 4 5 6 7 */
-static gdouble _font_scale[] = { .85, .95, 1, 1.2, 1.44, 1.728, 2.0736 };
-
-#define MAX_FONT_SIZE 7 /* Purple maximum font size */
-#define POINTS_PER_INCH 72 /* How many pt's in an inch */
-
-/* Text formatting bits for */
-#define MSIM_TEXT_BOLD 1
-#define MSIM_TEXT_ITALIC 2
-#define MSIM_TEXT_UNDERLINE 4
-
-/* Default baseline size of purple's fonts, in points. What is size 3 in points.
- * _font_scale specifies scaling factor relative to this point size. Note this
- * is only the default; it is configurable in account options. */
-#define MSIM_BASE_FONT_POINT_SIZE 8
-
-/* Default display's DPI. 96 is common but it can differ. Also configurable
- * in account options. */
-#define MSIM_DEFAULT_DPI 96
-
-
-/* round is part of C99, but sometimes is unavailable before then.
- * Based on http://forums.belution.com/en/cpp/000/050/13.shtml
- */
-double msim_round(double value)
-{
- if (value < 0) {
- return -(floor(-value + 0.5));
- } else {
- return floor( value + 0.5);
- }
-}
-
-
-/** Convert typographical font point size to HTML font size.
- * Based on libpurple/gtkimhtml.c */
-static guint
-msim_point_to_purple_size(MsimSession *session, guint point)
-{
- guint size, this_point, base;
- gdouble scale;
-
- base = purple_account_get_int(session->account, "base_font_size", MSIM_BASE_FONT_POINT_SIZE);
-
- for (size = 0;
- size < sizeof(_font_scale) / sizeof(_font_scale[0]);
- ++size) {
- scale = _font_scale[CLAMP(size, 1, MAX_FONT_SIZE) - 1];
- this_point = (guint)msim_round(scale * base);
-
- if (this_point >= point) {
- purple_debug_info("msim", "msim_point_to_purple_size: %d pt -> size=%d\n",
- point, size);
- return size;
- }
- }
-
- /* No HTML font size was this big; return largest possible. */
- return this_point;
-}
-
-/** Convert HTML font size to point size. */
-static guint
-msim_purple_size_to_point(MsimSession *session, guint size)
-{
- gdouble scale;
- guint point;
- guint base;
-
- scale = _font_scale[CLAMP(size, 1, MAX_FONT_SIZE) - 1];
-
- base = purple_account_get_int(session->account, "base_font_size", MSIM_BASE_FONT_POINT_SIZE);
-
- point = (guint)msim_round(scale * base);
-
- purple_debug_info("msim", "msim_purple_size_to_point: size=%d -> %d pt\n",
- size, point);
-
- return point;
-}
-
-/** Convert a msim markup font pixel height to the more usual point size, for incoming messages. */
-static guint
-msim_height_to_point(MsimSession *session, guint height)
-{
- guint dpi;
-
- dpi = purple_account_get_int(session->account, "port", MSIM_DEFAULT_DPI);
-
- return (guint)msim_round((POINTS_PER_INCH * 1. / dpi) * height);
-
- /* See also: libpurple/protocols/bonjour/jabber.c
- * _font_size_ichat_to_purple */
-}
-
-/** Convert point size to msim pixel height font size specification, for outgoing messages. */
-static guint
-msim_point_to_height(MsimSession *session, guint point)
-{
- guint dpi;
-
- dpi = purple_account_get_int(session->account, "port", MSIM_DEFAULT_DPI);
-
- return (guint)msim_round((dpi * 1. / POINTS_PER_INCH) * point);
-}
-
-/** Convert the msim markup (font) tag into HTML. */
-static void
-msim_markup_f_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
-{
- const gchar *face, *height_str, *decor_str;
- GString *gs_end, *gs_begin;
- guint decor, height;
-
- face = xmlnode_get_attrib(root, "f");
- height_str = xmlnode_get_attrib(root, "h");
- decor_str = xmlnode_get_attrib(root, "s");
-
- if (height_str) {
- height = atol(height_str);
- } else {
- height = 12;
- }
-
- if (decor_str) {
- decor = atol(decor_str);
- } else {
- decor = 0;
- }
-
- gs_begin = g_string_new("");
- /* TODO: get font size working */
- if (height && !face) {
- g_string_printf(gs_begin, "",
- msim_point_to_purple_size(session, msim_height_to_point(session, height)));
- } else if (height && face) {
- g_string_printf(gs_begin, "", face,
- msim_point_to_purple_size(session, msim_height_to_point(session, height)));
- } else {
- g_string_printf(gs_begin, "");
- }
-
- /* No support for font-size CSS? */
- /* g_string_printf(gs_begin, "", face,
- msim_height_to_point(height)); */
-
- gs_end = g_string_new("");
-
- if (decor & MSIM_TEXT_BOLD) {
- g_string_append(gs_begin, "");
- g_string_prepend(gs_end, "");
- }
-
- if (decor & MSIM_TEXT_ITALIC) {
- g_string_append(gs_begin, "");
- g_string_append(gs_end, "");
- }
-
- if (decor & MSIM_TEXT_UNDERLINE) {
- g_string_append(gs_begin, "");
- g_string_append(gs_end, "");
- }
-
-
- *begin = gs_begin->str;
- *end = gs_end->str;
-}
-
-/** Convert a msim markup color to a color suitable for libpurple.
- *
- * @param msim Either a color name, or an rgb(x,y,z) code.
- *
- * @return A new string, either a color name or #rrggbb code. Must g_free().
- */
-static char *
-msim_color_to_purple(const char *msim)
-{
- guint red, green, blue;
-
- if (!msim) {
- return g_strdup("black");
- }
-
- if (sscanf(msim, "rgb(%d,%d,%d)", &red, &green, &blue) != 3) {
- /* Color name. */
- return g_strdup(msim);
- }
- /* TODO: rgba (alpha). */
-
- return g_strdup_printf("#%.2x%.2x%.2x", red, green, blue);
-}
-
-/** Convert the msim markup (anchor) tag into HTML. */
-static void
-msim_markup_a_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
-{
- const gchar *href;
-
- href = xmlnode_get_attrib(root, "h");
- if (!href) {
- href = "";
- }
-
- *begin = g_strdup_printf("%s", href, href);
- *end = g_strdup("");
-}
-
-/** Convert the msim markup (paragraph) tag into HTML. */
-static void
-msim_markup_p_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
-{
- /* Just pass through unchanged.
- *
- * Note: attributes currently aren't passed, if there are any. */
- *begin = g_strdup("
");
- *end = g_strdup("
");
-}
-
-/** Convert the msim markup tag (text color) into HTML. TODO: Test */
-static void
-msim_markup_c_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
-{
- const gchar *color;
- gchar *purple_color;
-
- color = xmlnode_get_attrib(root, "v");
- if (!color) {
- purple_debug_info("msim", "msim_markup_c_to_html: tag w/o v attr\n");
- *begin = g_strdup("");
- *end = g_strdup("");
- /* TODO: log as unrecognized */
- return;
- }
-
- purple_color = msim_color_to_purple(color);
-
- *begin = g_strdup_printf("", purple_color);
-
- g_free(purple_color);
-
- /* *begin = g_strdup_printf("", color); */
- *end = g_strdup("");
-}
-
-/** Convert the msim markup tag (background color) into HTML. TODO: Test */
-static void
-msim_markup_b_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
-{
- const gchar *color;
- gchar *purple_color;
-
- color = xmlnode_get_attrib(root, "v");
- if (!color) {
- *begin = g_strdup("");
- *end = g_strdup("");
- purple_debug_info("msim", "msim_markup_b_to_html: w/o v attr\n");
- /* TODO: log as unrecognized. */
- return;
- }
-
- purple_color = msim_color_to_purple(color);
-
- /* TODO: find out how to set background color. */
- *begin = g_strdup_printf("",
- purple_color);
- g_free(purple_color);
-
- *end = g_strdup("
");
-}
-
-/** Convert the msim markup tag (emoticon image) into HTML. */
-static void
-msim_markup_i_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
-{
- const gchar *name;
- guint i;
- struct MSIM_EMOTICON *emote;
-
- name = xmlnode_get_attrib(root, "n");
- if (!name) {
- purple_debug_info("msim", "msim_markup_i_to_html: w/o n\n");
- *begin = g_strdup("");
- *end = g_strdup("");
- /* TODO: log as unrecognized */
- return;
- }
-
- /* Find and use canonical form of smiley symbol. */
- for (i = 0; (emote = &msim_emoticons[i]) && emote->name != NULL; ++i) {
- if (g_str_equal(name, emote->name)) {
- *begin = g_strdup(emote->symbol);
- *end = g_strdup("");
- return;
- }
- }
-
- /* Couldn't find it, sorry. Try to degrade gracefully. */
- *begin = g_strdup_printf("**%s**", name);
- *end = g_strdup("");
-}
-
-/** Convert an individual msim markup tag to HTML. */
-static void
-msim_markup_tag_to_html(MsimSession *session, xmlnode *root, gchar **begin,
- gchar **end)
-{
- if (g_str_equal(root->name, "f")) {
- msim_markup_f_to_html(session, root, begin, end);
- } else if (g_str_equal(root->name, "a")) {
- msim_markup_a_to_html(session, root, begin, end);
- } else if (g_str_equal(root->name, "p")) {
- msim_markup_p_to_html(session, root, begin, end);
- } else if (g_str_equal(root->name, "c")) {
- msim_markup_c_to_html(session, root, begin, end);
- } else if (g_str_equal(root->name, "b")) {
- msim_markup_b_to_html(session, root, begin, end);
- } else if (g_str_equal(root->name, "i")) {
- msim_markup_i_to_html(session, root, begin, end);
- } else {
- purple_debug_info("msim", "msim_markup_tag_to_html: "
- "unknown tag name=%s, ignoring",
- (root && root->name) ? root->name : "(NULL)");
- *begin = g_strdup("");
- *end = g_strdup("");
- }
-}
-
-/** Convert an individual HTML tag to msim markup. */
-static void
-html_tag_to_msim_markup(MsimSession *session, xmlnode *root, gchar **begin,
- gchar **end)
-{
- /* TODO: Coalesce nested tags into one tag!
- * Currently, the 's' value will be overwritten when b/i/u is nested
- * within another one, and only the inner-most formatting will be
- * applied to the text. */
- if (!purple_utf8_strcasecmp(root->name, "root")) {
- *begin = g_strdup("");
- *end = g_strdup("");
- } else if (!purple_utf8_strcasecmp(root->name, "b")) {
- *begin = g_strdup_printf("", MSIM_TEXT_BOLD);
- *end = g_strdup("");
- } else if (!purple_utf8_strcasecmp(root->name, "i")) {
- *begin = g_strdup_printf("", MSIM_TEXT_ITALIC);
- *end = g_strdup("");
- } else if (!purple_utf8_strcasecmp(root->name, "u")) {
- *begin = g_strdup_printf("", MSIM_TEXT_UNDERLINE);
- *end = g_strdup("");
- } else if (!purple_utf8_strcasecmp(root->name, "a")) {
- const gchar *href, *link_text;
-
- href = xmlnode_get_attrib(root, "href");
-
- if (!href) {
- href = xmlnode_get_attrib(root, "HREF");
- }
-
- link_text = xmlnode_get_data(root);
-
- if (href) {
- if (g_str_equal(link_text, href)) {
- /* Purple gives us: URL
- * Translate to
- * Displayed as text of URL with link to URL
- */
- *begin = g_strdup_printf("", href);
- } else {
- /* But if we get: text
- * Translate to: text:
- *
- * Because official client only supports self-closed
- * tags; you can't change the link text.
- */
- *begin = g_strdup_printf("%s: ", link_text, href);
- }
- } else {
- *begin = g_strdup("");
- }
-
- /* Sorry, kid. MySpace doesn't support you within tags. */
- xmlnode_free(root->child);
- root->child = NULL;
-
- *end = g_strdup("");
- } else if (!purple_utf8_strcasecmp(root->name, "font")) {
- const gchar *size;
- const gchar *face;
-
- size = xmlnode_get_attrib(root, "size");
- face = xmlnode_get_attrib(root, "face");
-
- if (face && size) {
- *begin = g_strdup_printf("", face,
- msim_point_to_height(session,
- msim_purple_size_to_point(session, atoi(size))));
- } else if (face) {
- *begin = g_strdup_printf("", face);
- } else if (size) {
- *begin = g_strdup_printf("",
- msim_point_to_height(session,
- msim_purple_size_to_point(session, atoi(size))));
- } else {
- *begin = g_strdup("");
- }
-
- *end = g_strdup("");
-
- /* TODO: color (bg uses ), emoticons */
- } else {
- *begin = g_strdup_printf("[%s]", root->name);
- *end = g_strdup_printf("[/%s]", root->name);
- }
-}
-
-/** Convert an xmlnode of msim markup or HTML to an HTML string or msim markup.
- *
- * @param f Function to convert tags.
- *
- * @return An HTML string. Caller frees.
- */
-static gchar *
-msim_convert_xmlnode(MsimSession *session, xmlnode *root, MSIM_XMLNODE_CONVERT f)
-{
- xmlnode *node;
- gchar *begin, *inner, *end;
- GString *final;
-
- if (!root || !root->name) {
- return g_strdup("");
- }
-
- purple_debug_info("msim", "msim_convert_xmlnode: got root=%s\n",
- root->name);
-
- begin = inner = end = NULL;
-
- final = g_string_new("");
-
- f(session, root, &begin, &end);
-
- g_string_append(final, begin);
-
- /* Loop over all child nodes. */
- for (node = root->child; node != NULL; node = node->next) {
- switch (node->type) {
- case XMLNODE_TYPE_ATTRIB:
- /* Attributes handled above. */
- break;
-
- case XMLNODE_TYPE_TAG:
- /* A tag or tag with attributes. Recursively descend. */
- inner = msim_convert_xmlnode(session, node, f);
- g_return_val_if_fail(inner != NULL, NULL);
-
- purple_debug_info("msim", " ** node name=%s\n",
- (node && node->name) ? node->name : "(NULL)");
- break;
-
- case XMLNODE_TYPE_DATA:
- /* Literal text. */
- inner = g_new0(char, node->data_sz + 1);
- strncpy(inner, node->data, node->data_sz);
- inner[node->data_sz] = 0;
-
- purple_debug_info("msim", " ** node data=%s\n",
- inner ? inner : "(NULL)");
- break;
-
- default:
- purple_debug_info("msim",
- "msim_convert_xmlnode: strange node\n");
- inner = g_strdup("");
- }
-
- if (inner) {
- g_string_append(final, inner);
- }
- }
-
- /* TODO: Note that msim counts each piece of text enclosed by as
- * a paragraph and will display each on its own line. You actually have
- * to _nest_ tags to intersperse different text in one paragraph!
- * Comment out this line below to see. */
- g_string_append(final, end);
-
- purple_debug_info("msim", "msim_markup_xmlnode_to_gtkhtml: RETURNING %s\n",
- (final && final->str) ? final->str : "(NULL)");
-
- return final->str;
-}
-
-/** Convert XML to something based on MSIM_XMLNODE_CONVERT. */
-static gchar *
-msim_convert_xml(MsimSession *session, const gchar *raw, MSIM_XMLNODE_CONVERT f)
-{
- xmlnode *root;
- gchar *str;
- gchar *enclosed_raw;
-
- g_return_val_if_fail(raw != NULL, NULL);
-
- /* Enclose text in one root tag, to try to make it valid XML for parsing. */
- enclosed_raw = g_strconcat("", raw, "", NULL);
-
- root = xmlnode_from_str(enclosed_raw, -1);
-
- if (!root) {
- purple_debug_info("msim", "msim_markup_to_html: couldn't parse "
- "%s as XML, returning raw: %s\n", enclosed_raw, raw);
- /* TODO: msim_unrecognized */
- g_free(enclosed_raw);
- return g_strdup(raw);
- }
-
- g_free(enclosed_raw);
-
- str = msim_convert_xmlnode(session, root, f);
- g_return_val_if_fail(str != NULL, NULL);
- purple_debug_info("msim", "msim_markup_to_html: returning %s\n", str);
-
- xmlnode_free(root);
-
- return str;
-}
-
-/** Convert plaintext smileys to markup tags.
- *
- * @param before Original text with ASCII smileys. Will be freed.
- * @return A new string with tags, if applicable. Must be g_free()'d.
- */
-static gchar *
-msim_convert_smileys_to_markup(gchar *before)
-{
- gchar *old, *new, *replacement;
- guint i;
- struct MSIM_EMOTICON *emote;
-
- old = before;
- new = NULL;
-
- for (i = 0; (emote = &msim_emoticons[i]) && emote->name != NULL; ++i) {
- gchar *name, *symbol;
-
- name = emote->name;
- symbol = emote->symbol;
-
- replacement = g_strdup_printf("", name);
-
- purple_debug_info("msim", "msim_convert_smileys_to_markup: %s->%s\n",
- symbol ? symbol : "(NULL)",
- replacement ? replacement : "(NULL)");
- new = purple_strreplace(old, symbol, replacement);
-
- g_free(replacement);
- g_free(old);
-
- old = new;
- }
-
- return new;
-}
-
-
-/** High-level function to convert MySpaceIM markup to Purple (HTML) markup.
- *
- * @return Purple markup string, must be g_free()'d. */
-gchar *
-msim_markup_to_html(MsimSession *session, const gchar *raw)
-{
- return msim_convert_xml(session, raw,
- (MSIM_XMLNODE_CONVERT)(msim_markup_tag_to_html));
-}
-
-/** High-level function to convert Purple (HTML) to MySpaceIM markup.
- *
- * TODO: consider using purple_markup_html_to_xhtml() to make valid XML.
- *
- * @return HTML markup string, must be g_free()'d. */
-gchar *
-html_to_msim_markup(MsimSession *session, const gchar *raw)
-{
- gchar *markup;
-
- markup = msim_convert_xml(session, raw,
- (MSIM_XMLNODE_CONVERT)(html_tag_to_msim_markup));
-
- if (purple_account_get_bool(session->account, "emoticons", TRUE)) {
- /* Frees markup and allocates a new one. */
- markup = msim_convert_smileys_to_markup(markup);
- }
-
- return markup;
-}
-
-
+/* MySpaceIM Protocol Plugin - markup
+ *
+ * Copyright (C) 2007, Jeff Connelly
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include "myspace.h"
+
+typedef void (*MSIM_XMLNODE_CONVERT)(MsimSession *, xmlnode *, gchar **, gchar **);
+
+/* Internal functions */
+
+static guint msim_point_to_purple_size(MsimSession *session, guint point);
+static guint msim_purple_size_to_point(MsimSession *session, guint size);
+static guint msim_height_to_point(MsimSession *session, guint height);
+static guint msim_point_to_height(MsimSession *session, guint point);
+
+static void msim_markup_tag_to_html(MsimSession *, xmlnode *root, gchar **begin, gchar **end);
+static void html_tag_to_msim_markup(MsimSession *, xmlnode *root, gchar **begin, gchar **end);
+static gchar *msim_convert_xml(MsimSession *, const gchar *raw, MSIM_XMLNODE_CONVERT f);
+static gchar *msim_convert_smileys_to_markup(gchar *before);
+static double msim_round(double round);
+
+
+/* Globals */
+
+/* The names in in emoticon_names (for ) map to corresponding
+ * entries in emoticon_symbols (for the ASCII representation of the emoticon).
+ *
+ * Multiple emoticon symbols in Pidgin can map to one name. List the
+ * canonical form, as inserted by the "Smile!" dialog, first. For example,
+ * :) comes before :-), because although both are recognized as 'happy',
+ * the first is inserted by the smiley button (first symbol in theme).
+ *
+ * Note that symbols are case-sensitive in Pidgin -- :-X is not :-x. */
+static struct MSIM_EMOTICON
+{
+ gchar *name;
+ gchar *symbol;
+} msim_emoticons[] = {
+ /* Unfortunately, this list duplicates much of the file
+ * pidgin/pidgin/pixmaps/emotes/default/22/default.theme.in, because
+ * that file is part of Pidgin, but we're part of libpurple.
+ */
+ { "bigsmile", ":D" },
+ { "bigsmile", ":-D" },
+ { "devil", "}:)" },
+ { "frazzled", ":Z" },
+ { "geek", "B)" },
+ { "googles", "%)" },
+ { "growl", ":E" },
+ { "laugh", ":))" }, /* Must be before ':)' */
+ { "happy", ":)" },
+ { "happy", ":-)" },
+ { "happi", ":)" },
+ { "heart", ":X" },
+ { "mohawk", "-:" },
+ { "mad", "X(" },
+ { "messed", "X)" },
+ { "nerd", "Q)" },
+ { "oops", ":G" },
+ { "pirate", "P)" },
+ { "scared", ":O" },
+ { "sidefrown", ":{" },
+ { "sinister", ":B" },
+ { "smirk", ":," },
+ { "straight", ":|" },
+ { "tongue", ":P" },
+ { "tongue", ":p" },
+ { "tongy", ":P" },
+ { "upset", "B|" },
+ { "wink", ";-)" },
+ { "wink", ";)" },
+ { "winc", ";)" },
+ { "worried", ":[" },
+ { "kiss", ":x" },
+ { NULL, NULL }
+};
+
+
+
+/* Indexes of this array + 1 map HTML font size to scale of normal font size. *
+ * Based on _point_sizes from libpurple/gtkimhtml.c
+ * 1 2 3 4 5 6 7 */
+static gdouble _font_scale[] = { .85, .95, 1, 1.2, 1.44, 1.728, 2.0736 };
+
+#define MAX_FONT_SIZE 7 /* Purple maximum font size */
+#define POINTS_PER_INCH 72 /* How many pt's in an inch */
+
+/* Text formatting bits for */
+#define MSIM_TEXT_BOLD 1
+#define MSIM_TEXT_ITALIC 2
+#define MSIM_TEXT_UNDERLINE 4
+
+/* Default baseline size of purple's fonts, in points. What is size 3 in points.
+ * _font_scale specifies scaling factor relative to this point size. Note this
+ * is only the default; it is configurable in account options. */
+#define MSIM_BASE_FONT_POINT_SIZE 8
+
+/* Default display's DPI. 96 is common but it can differ. Also configurable
+ * in account options. */
+#define MSIM_DEFAULT_DPI 96
+
+
+/* round is part of C99, but sometimes is unavailable before then.
+ * Based on http://forums.belution.com/en/cpp/000/050/13.shtml
+ */
+double msim_round(double value)
+{
+ if (value < 0) {
+ return -(floor(-value + 0.5));
+ } else {
+ return floor( value + 0.5);
+ }
+}
+
+
+/** Convert typographical font point size to HTML font size.
+ * Based on libpurple/gtkimhtml.c */
+static guint
+msim_point_to_purple_size(MsimSession *session, guint point)
+{
+ guint size, this_point, base;
+ gdouble scale;
+
+ base = purple_account_get_int(session->account, "base_font_size", MSIM_BASE_FONT_POINT_SIZE);
+
+ for (size = 0;
+ size < sizeof(_font_scale) / sizeof(_font_scale[0]);
+ ++size) {
+ scale = _font_scale[CLAMP(size, 1, MAX_FONT_SIZE) - 1];
+ this_point = (guint)msim_round(scale * base);
+
+ if (this_point >= point) {
+ purple_debug_info("msim", "msim_point_to_purple_size: %d pt -> size=%d\n",
+ point, size);
+ return size;
+ }
+ }
+
+ /* No HTML font size was this big; return largest possible. */
+ return this_point;
+}
+
+/** Convert HTML font size to point size. */
+static guint
+msim_purple_size_to_point(MsimSession *session, guint size)
+{
+ gdouble scale;
+ guint point;
+ guint base;
+
+ scale = _font_scale[CLAMP(size, 1, MAX_FONT_SIZE) - 1];
+
+ base = purple_account_get_int(session->account, "base_font_size", MSIM_BASE_FONT_POINT_SIZE);
+
+ point = (guint)msim_round(scale * base);
+
+ purple_debug_info("msim", "msim_purple_size_to_point: size=%d -> %d pt\n",
+ size, point);
+
+ return point;
+}
+
+/** Convert a msim markup font pixel height to the more usual point size, for incoming messages. */
+static guint
+msim_height_to_point(MsimSession *session, guint height)
+{
+ guint dpi;
+
+ dpi = purple_account_get_int(session->account, "port", MSIM_DEFAULT_DPI);
+
+ return (guint)msim_round((POINTS_PER_INCH * 1. / dpi) * height);
+
+ /* See also: libpurple/protocols/bonjour/jabber.c
+ * _font_size_ichat_to_purple */
+}
+
+/** Convert point size to msim pixel height font size specification, for outgoing messages. */
+static guint
+msim_point_to_height(MsimSession *session, guint point)
+{
+ guint dpi;
+
+ dpi = purple_account_get_int(session->account, "port", MSIM_DEFAULT_DPI);
+
+ return (guint)msim_round((dpi * 1. / POINTS_PER_INCH) * point);
+}
+
+/** Convert the msim markup (font) tag into HTML. */
+static void
+msim_markup_f_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
+{
+ const gchar *face, *height_str, *decor_str;
+ GString *gs_end, *gs_begin;
+ guint decor, height;
+
+ face = xmlnode_get_attrib(root, "f");
+ height_str = xmlnode_get_attrib(root, "h");
+ decor_str = xmlnode_get_attrib(root, "s");
+
+ if (height_str) {
+ height = atol(height_str);
+ } else {
+ height = 12;
+ }
+
+ if (decor_str) {
+ decor = atol(decor_str);
+ } else {
+ decor = 0;
+ }
+
+ gs_begin = g_string_new("");
+ /* TODO: get font size working */
+ if (height && !face) {
+ g_string_printf(gs_begin, "",
+ msim_point_to_purple_size(session, msim_height_to_point(session, height)));
+ } else if (height && face) {
+ g_string_printf(gs_begin, "", face,
+ msim_point_to_purple_size(session, msim_height_to_point(session, height)));
+ } else {
+ g_string_printf(gs_begin, "");
+ }
+
+ /* No support for font-size CSS? */
+ /* g_string_printf(gs_begin, "", face,
+ msim_height_to_point(height)); */
+
+ gs_end = g_string_new("");
+
+ if (decor & MSIM_TEXT_BOLD) {
+ g_string_append(gs_begin, "");
+ g_string_prepend(gs_end, "");
+ }
+
+ if (decor & MSIM_TEXT_ITALIC) {
+ g_string_append(gs_begin, "");
+ g_string_append(gs_end, "");
+ }
+
+ if (decor & MSIM_TEXT_UNDERLINE) {
+ g_string_append(gs_begin, "");
+ g_string_append(gs_end, "");
+ }
+
+
+ *begin = g_string_free(gs_begin, FALSE);
+ *end = g_string_free(gs_end, FALSE);
+}
+
+/** Convert a msim markup color to a color suitable for libpurple.
+ *
+ * @param msim Either a color name, or an rgb(x,y,z) code.
+ *
+ * @return A new string, either a color name or #rrggbb code. Must g_free().
+ */
+static char *
+msim_color_to_purple(const char *msim)
+{
+ guint red, green, blue;
+
+ if (!msim) {
+ return g_strdup("black");
+ }
+
+ if (sscanf(msim, "rgb(%d,%d,%d)", &red, &green, &blue) != 3) {
+ /* Color name. */
+ return g_strdup(msim);
+ }
+ /* TODO: rgba (alpha). */
+
+ return g_strdup_printf("#%.2x%.2x%.2x", red, green, blue);
+}
+
+/** Convert the msim markup (anchor) tag into HTML. */
+static void
+msim_markup_a_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
+{
+ const gchar *href;
+
+ href = xmlnode_get_attrib(root, "h");
+ if (!href) {
+ href = "";
+ }
+
+ *begin = g_strdup_printf("%s", href, href);
+ *end = g_strdup("");
+}
+
+/** Convert the msim markup (paragraph) tag into HTML. */
+static void
+msim_markup_p_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
+{
+ /* Just pass through unchanged.
+ *
+ * Note: attributes currently aren't passed, if there are any. */
+ *begin = g_strdup("
");
+ *end = g_strdup("
");
+}
+
+/** Convert the msim markup tag (text color) into HTML. TODO: Test */
+static void
+msim_markup_c_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
+{
+ const gchar *color;
+ gchar *purple_color;
+
+ color = xmlnode_get_attrib(root, "v");
+ if (!color) {
+ purple_debug_info("msim", "msim_markup_c_to_html: tag w/o v attr\n");
+ *begin = g_strdup("");
+ *end = g_strdup("");
+ /* TODO: log as unrecognized */
+ return;
+ }
+
+ purple_color = msim_color_to_purple(color);
+
+ *begin = g_strdup_printf("", purple_color);
+
+ g_free(purple_color);
+
+ /* *begin = g_strdup_printf("", color); */
+ *end = g_strdup("");
+}
+
+/** Convert the msim markup tag (background color) into HTML. TODO: Test */
+static void
+msim_markup_b_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
+{
+ const gchar *color;
+ gchar *purple_color;
+
+ color = xmlnode_get_attrib(root, "v");
+ if (!color) {
+ *begin = g_strdup("");
+ *end = g_strdup("");
+ purple_debug_info("msim", "msim_markup_b_to_html: w/o v attr\n");
+ /* TODO: log as unrecognized. */
+ return;
+ }
+
+ purple_color = msim_color_to_purple(color);
+
+ /* TODO: find out how to set background color. */
+ *begin = g_strdup_printf("",
+ purple_color);
+ g_free(purple_color);
+
+ *end = g_strdup("");
+}
+
+/** Convert the msim markup tag (emoticon image) into HTML. */
+static void
+msim_markup_i_to_html(MsimSession *session, xmlnode *root, gchar **begin, gchar **end)
+{
+ const gchar *name;
+ guint i;
+ struct MSIM_EMOTICON *emote;
+
+ name = xmlnode_get_attrib(root, "n");
+ if (!name) {
+ purple_debug_info("msim", "msim_markup_i_to_html: w/o n\n");
+ *begin = g_strdup("");
+ *end = g_strdup("");
+ /* TODO: log as unrecognized */
+ return;
+ }
+
+ /* Find and use canonical form of smiley symbol. */
+ for (i = 0; (emote = &msim_emoticons[i]) && emote->name != NULL; ++i) {
+ if (g_str_equal(name, emote->name)) {
+ *begin = g_strdup(emote->symbol);
+ *end = g_strdup("");
+ return;
+ }
+ }
+
+ /* Couldn't find it, sorry. Try to degrade gracefully. */
+ *begin = g_strdup_printf("**%s**", name);
+ *end = g_strdup("");
+}
+
+/** Convert an individual msim markup tag to HTML. */
+static void
+msim_markup_tag_to_html(MsimSession *session, xmlnode *root, gchar **begin,
+ gchar **end)
+{
+ if (g_str_equal(root->name, "f")) {
+ msim_markup_f_to_html(session, root, begin, end);
+ } else if (g_str_equal(root->name, "a")) {
+ msim_markup_a_to_html(session, root, begin, end);
+ } else if (g_str_equal(root->name, "p")) {
+ msim_markup_p_to_html(session, root, begin, end);
+ } else if (g_str_equal(root->name, "c")) {
+ msim_markup_c_to_html(session, root, begin, end);
+ } else if (g_str_equal(root->name, "b")) {
+ msim_markup_b_to_html(session, root, begin, end);
+ } else if (g_str_equal(root->name, "i")) {
+ msim_markup_i_to_html(session, root, begin, end);
+ } else {
+ purple_debug_info("msim", "msim_markup_tag_to_html: "
+ "unknown tag name=%s, ignoring",
+ (root && root->name) ? root->name : "(NULL)");
+ *begin = g_strdup("");
+ *end = g_strdup("");
+ }
+}
+
+/** Convert an individual HTML tag to msim markup. */
+static void
+html_tag_to_msim_markup(MsimSession *session, xmlnode *root, gchar **begin,
+ gchar **end)
+{
+ /* TODO: Coalesce nested tags into one tag!
+ * Currently, the 's' value will be overwritten when b/i/u is nested
+ * within another one, and only the inner-most formatting will be
+ * applied to the text. */
+ if (!purple_utf8_strcasecmp(root->name, "root")) {
+ *begin = g_strdup("");
+ *end = g_strdup("");
+ } else if (!purple_utf8_strcasecmp(root->name, "b")) {
+ *begin = g_strdup_printf("", MSIM_TEXT_BOLD);
+ *end = g_strdup("");
+ } else if (!purple_utf8_strcasecmp(root->name, "i")) {
+ *begin = g_strdup_printf("", MSIM_TEXT_ITALIC);
+ *end = g_strdup("");
+ } else if (!purple_utf8_strcasecmp(root->name, "u")) {
+ *begin = g_strdup_printf("", MSIM_TEXT_UNDERLINE);
+ *end = g_strdup("");
+ } else if (!purple_utf8_strcasecmp(root->name, "a")) {
+ const gchar *href, *link_text;
+
+ href = xmlnode_get_attrib(root, "href");
+
+ if (!href) {
+ href = xmlnode_get_attrib(root, "HREF");
+ }
+
+ link_text = xmlnode_get_data(root);
+
+ if (href) {
+ if (g_str_equal(link_text, href)) {
+ /* Purple gives us: URL
+ * Translate to
+ * Displayed as text of URL with link to URL
+ */
+ *begin = g_strdup_printf("", href);
+ } else {
+ /* But if we get: text
+ * Translate to: text:
+ *
+ * Because official client only supports self-closed
+ * tags; you can't change the link text.
+ */
+ *begin = g_strdup_printf("%s: ", link_text, href);
+ }
+ } else {
+ *begin = g_strdup("");
+ }
+
+ /* Sorry, kid. MySpace doesn't support you within tags. */
+ xmlnode_free(root->child);
+ root->child = NULL;
+
+ *end = g_strdup("");
+ } else if (!purple_utf8_strcasecmp(root->name, "font")) {
+ const gchar *size;
+ const gchar *face;
+
+ size = xmlnode_get_attrib(root, "size");
+ face = xmlnode_get_attrib(root, "face");
+
+ if (face && size) {
+ *begin = g_strdup_printf("", face,
+ msim_point_to_height(session,
+ msim_purple_size_to_point(session, atoi(size))));
+ } else if (face) {
+ *begin = g_strdup_printf("", face);
+ } else if (size) {
+ *begin = g_strdup_printf("",
+ msim_point_to_height(session,
+ msim_purple_size_to_point(session, atoi(size))));
+ } else {
+ *begin = g_strdup("");
+ }
+
+ *end = g_strdup("");
+
+ /* TODO: color (bg uses ), emoticons */
+ } else {
+ *begin = g_strdup_printf("[%s]", root->name);
+ *end = g_strdup_printf("[/%s]", root->name);
+ }
+}
+
+/** Convert an xmlnode of msim markup or HTML to an HTML string or msim markup.
+ *
+ * @param f Function to convert tags.
+ *
+ * @return An HTML string. Caller frees.
+ */
+static gchar *
+msim_convert_xmlnode(MsimSession *session, xmlnode *root, MSIM_XMLNODE_CONVERT f)
+{
+ xmlnode *node;
+ gchar *begin, *inner, *end;
+ GString *final;
+
+ if (!root || !root->name) {
+ return g_strdup("");
+ }
+
+ purple_debug_info("msim", "msim_convert_xmlnode: got root=%s\n",
+ root->name);
+
+ begin = inner = end = NULL;
+
+ final = g_string_new("");
+
+ f(session, root, &begin, &end);
+
+ g_string_append(final, begin);
+
+ /* Loop over all child nodes. */
+ for (node = root->child; node != NULL; node = node->next) {
+ switch (node->type) {
+ case XMLNODE_TYPE_ATTRIB:
+ /* Attributes handled above. */
+ break;
+
+ case XMLNODE_TYPE_TAG:
+ /* A tag or tag with attributes. Recursively descend. */
+ inner = msim_convert_xmlnode(session, node, f);
+ g_return_val_if_fail(inner != NULL, NULL);
+
+ purple_debug_info("msim", " ** node name=%s\n",
+ (node && node->name) ? node->name : "(NULL)");
+ break;
+
+ case XMLNODE_TYPE_DATA:
+ /* Literal text. */
+ inner = g_new0(char, node->data_sz + 1);
+ strncpy(inner, node->data, node->data_sz);
+ inner[node->data_sz] = 0;
+
+ purple_debug_info("msim", " ** node data=%s\n",
+ inner ? inner : "(NULL)");
+ break;
+
+ default:
+ purple_debug_info("msim",
+ "msim_convert_xmlnode: strange node\n");
+ inner = g_strdup("");
+ }
+
+ if (inner) {
+ g_string_append(final, inner);
+ }
+ }
+
+ /* TODO: Note that msim counts each piece of text enclosed by as
+ * a paragraph and will display each on its own line. You actually have
+ * to _nest_ tags to intersperse different text in one paragraph!
+ * Comment out this line below to see. */
+ g_string_append(final, end);
+
+ purple_debug_info("msim", "msim_markup_xmlnode_to_gtkhtml: RETURNING %s\n",
+ (final && final->str) ? final->str : "(NULL)");
+
+ return g_string_free(final, FALSE);
+}
+
+/** Convert XML to something based on MSIM_XMLNODE_CONVERT. */
+static gchar *
+msim_convert_xml(MsimSession *session, const gchar *raw, MSIM_XMLNODE_CONVERT f)
+{
+ xmlnode *root;
+ gchar *str;
+ gchar *enclosed_raw;
+
+ g_return_val_if_fail(raw != NULL, NULL);
+
+ /* Enclose text in one root tag, to try to make it valid XML for parsing. */
+ enclosed_raw = g_strconcat("", raw, "", NULL);
+
+ root = xmlnode_from_str(enclosed_raw, -1);
+
+ if (!root) {
+ purple_debug_info("msim", "msim_markup_to_html: couldn't parse "
+ "%s as XML, returning raw: %s\n", enclosed_raw, raw);
+ /* TODO: msim_unrecognized */
+ g_free(enclosed_raw);
+ return g_strdup(raw);
+ }
+
+ g_free(enclosed_raw);
+
+ str = msim_convert_xmlnode(session, root, f);
+ g_return_val_if_fail(str != NULL, NULL);
+ purple_debug_info("msim", "msim_markup_to_html: returning %s\n", str);
+
+ xmlnode_free(root);
+
+ return str;
+}
+
+/** Convert plaintext smileys to markup tags.
+ *
+ * @param before Original text with ASCII smileys. Will be freed.
+ * @return A new string with tags, if applicable. Must be g_free()'d.
+ */
+static gchar *
+msim_convert_smileys_to_markup(gchar *before)
+{
+ gchar *old, *new, *replacement;
+ guint i;
+ struct MSIM_EMOTICON *emote;
+
+ old = before;
+ new = NULL;
+
+ for (i = 0; (emote = &msim_emoticons[i]) && emote->name != NULL; ++i) {
+ gchar *name, *symbol;
+
+ name = emote->name;
+ symbol = emote->symbol;
+
+ replacement = g_strdup_printf("", name);
+
+ purple_debug_info("msim", "msim_convert_smileys_to_markup: %s->%s\n",
+ symbol ? symbol : "(NULL)",
+ replacement ? replacement : "(NULL)");
+ new = purple_strreplace(old, symbol, replacement);
+
+ g_free(replacement);
+ g_free(old);
+
+ old = new;
+ }
+
+ return new;
+}
+
+
+/** High-level function to convert MySpaceIM markup to Purple (HTML) markup.
+ *
+ * @return Purple markup string, must be g_free()'d. */
+gchar *
+msim_markup_to_html(MsimSession *session, const gchar *raw)
+{
+ return msim_convert_xml(session, raw,
+ (MSIM_XMLNODE_CONVERT)(msim_markup_tag_to_html));
+}
+
+/** High-level function to convert Purple (HTML) to MySpaceIM markup.
+ *
+ * TODO: consider using purple_markup_html_to_xhtml() to make valid XML.
+ *
+ * @return HTML markup string, must be g_free()'d. */
+gchar *
+html_to_msim_markup(MsimSession *session, const gchar *raw)
+{
+ gchar *markup;
+
+ markup = msim_convert_xml(session, raw,
+ (MSIM_XMLNODE_CONVERT)(html_tag_to_msim_markup));
+
+ if (purple_account_get_bool(session->account, "emoticons", TRUE)) {
+ /* Frees markup and allocates a new one. */
+ markup = msim_convert_smileys_to_markup(markup);
+ }
+
+ return markup;
+}
+
+
diff -r c320bc7b1383 -r 5440eed4ec7e libpurple/protocols/myspace/message.c
--- a/libpurple/protocols/myspace/message.c Fri Sep 28 15:56:31 2007 +0000
+++ b/libpurple/protocols/myspace/message.c Fri Sep 28 15:57:10 2007 +0000
@@ -80,7 +80,7 @@
purple_debug_info("msim", "msim_escape: msg=%s, ret=%s\n", msg, gs->str);
#endif
- return gs->str;
+ return g_string_free(gs, FALSE);
}
/**
@@ -120,7 +120,7 @@
purple_debug_info("msim", "msim_unescape: msg=%s, ret=%s\n", msg, gs->str);
#endif
- return gs->str;
+ return g_string_free(gs, FALSE);
}
/** Create a new MsimMessage.
@@ -691,7 +691,7 @@
++i;
}
- string = gs->str;
+ string = g_string_free(gs, FALSE);
break;
default:
@@ -798,7 +798,7 @@
g_string_append(gs, "|");
}
- return gs->str;
+ return g_string_free(gs, FALSE);
default:
purple_debug_info("msim", "field %s, unknown type %d\n",
@@ -1337,9 +1337,7 @@
gs = (GString *)elem->data;
/* Duplicate data, so caller can g_free() it. */
- *binary_data = g_new0(char, gs->len);
- memcpy(*binary_data, gs->str, gs->len);
-
+ *binary_data = g_memdup(gs->str, gs->len);
*binary_length = gs->len;
return TRUE;
diff -r c320bc7b1383 -r 5440eed4ec7e libpurple/protocols/myspace/myspace.c
--- a/libpurple/protocols/myspace/myspace.c Fri Sep 28 15:56:31 2007 +0000
+++ b/libpurple/protocols/myspace/myspace.c Fri Sep 28 15:57:10 2007 +0000
@@ -43,7 +43,7 @@
static int msim_send_really_raw(PurpleConnection *gc, const char *buf, int total_bytes);
static gboolean msim_login_challenge(MsimSession *session, MsimMessage *msg);
-static const gchar *msim_compute_login_response(const gchar nonce[2 * NONCE_SIZE], const gchar *email, const gchar *password, guint *response_len);
+static gchar *msim_compute_login_response(const gchar nonce[2 * NONCE_SIZE], const gchar *email, const gchar *password, guint *response_len);
static gboolean msim_incoming_bm_record_cv(MsimSession *session, MsimMessage *msg);
static gboolean msim_incoming_bm(MsimSession *session, MsimMessage *msg);
@@ -331,10 +331,11 @@
msim_login_challenge(MsimSession *session, MsimMessage *msg)
{
PurpleAccount *account;
- const gchar *response;
+ gchar *response;
guint response_len;
gchar *nc;
gsize nc_len;
+ gboolean ret;
g_return_val_if_fail(MSIM_SESSION_VALID(session), FALSE);
g_return_val_if_fail(msg != NULL, FALSE);
@@ -362,11 +363,11 @@
g_free(nc);
- return msim_send(session,
+ ret = msim_send(session,
"login2", MSIM_TYPE_INTEGER, MSIM_AUTH_ALGORITHM,
/* This is actually user's email address. */
"username", MSIM_TYPE_STRING, g_strdup(account->username),
- /* GString and gchar * response will be freed in msim_msg_free() in msim_send(). */
+ /* GString will be freed in msim_msg_free() in msim_send(). */
"response", MSIM_TYPE_BINARY, g_string_new_len(response, response_len),
"clientver", MSIM_TYPE_INTEGER, MSIM_CLIENT_VERSION,
"langid", MSIM_TYPE_INTEGER, MSIM_LANGUAGE_ID_ENGLISH,
@@ -375,6 +376,10 @@
"status", MSIM_TYPE_INTEGER, 100,
"id", MSIM_TYPE_INTEGER, 1,
NULL);
+
+ g_free(response);
+
+ return ret;
}
/**
@@ -388,7 +393,7 @@
* @return Binary login challenge response, ready to send to the server.
* Must be g_free()'d when finished. NULL if error.
*/
-static const gchar *
+static gchar *
msim_compute_login_response(const gchar nonce[2 * NONCE_SIZE],
const gchar *email, const gchar *password, guint *response_len)
{
@@ -486,6 +491,7 @@
data_len, data_out, &data_out_len);
purple_cipher_context_destroy(rc4);
+ /* TODO: Never assert in a protocol plugin! */
g_assert(data_out_len == data_len);
#ifdef MSIM_DEBUG_LOGIN_CHALLENGE
@@ -494,7 +500,7 @@
*response_len = data_out_len;
- return (const gchar *)data_out;
+ return (gchar *)data_out;
}
/**
@@ -1295,7 +1301,6 @@
msim_check_inbox_cb(MsimSession *session, MsimMessage *reply, gpointer data)
{
MsimMessage *body;
- GString *notification;
guint old_inbox_status;
guint i, n;
const gchar *froms[5], *tos[5], *urls[5], *subjects[5];
@@ -1329,8 +1334,6 @@
body = msim_msg_get_dictionary(reply, "body");
g_return_if_fail(body != NULL);
- notification = g_string_new("");
-
old_inbox_status = session->inbox_status;
n = 0;
@@ -3004,7 +3007,7 @@
msg = msim_msg_new(NULL); /* Create a new, empty message. */
/* Append some new elements. */
- msg = msim_msg_append(msg, "bx", MSIM_TYPE_BINARY, g_string_new_len(g_strdup("XXX"), 3));
+ msg = msim_msg_append(msg, "bx", MSIM_TYPE_BINARY, g_string_new_len("XXX", 3));
msg = msim_msg_append(msg, "k1", MSIM_TYPE_STRING, g_strdup("v1"));
msg = msim_msg_append(msg, "k1", MSIM_TYPE_INTEGER, GUINT_TO_POINTER(42));
msg = msim_msg_append(msg, "k1", MSIM_TYPE_STRING, g_strdup("v43"));