Example #1
0
/*Post the Offline Instant Message to User Conversation*/
static void
msn_oim_report_to_user(MsnOimRecvData *rdata, const char *msg_str)
{
	MsnMessage *message;
	const char *date;
	const char *from;
	const char *boundary;
	char *decode_msg = NULL;
	gsize body_len;
	char **tokens;
	char *passport = NULL;
	time_t stamp;

	message = msn_message_new(MSN_MSG_UNKNOWN);

	msn_message_parse_payload(message, msg_str, strlen(msg_str),
	                          MSG_OIM_LINE_DEM, MSG_OIM_BODY_DEM);
	purple_debug_info("msn", "oim body:{%s}\n", message->body);

	boundary = msn_message_get_attr(message, "boundary");

	if (boundary != NULL) {
		char *bounds;
		char **part;

		bounds = g_strdup_printf("--%s" MSG_OIM_LINE_DEM, boundary);
		tokens = g_strsplit(message->body, bounds, 0);

		/* tokens+1 to skip the "This is a multipart message..." text */
		for (part = tokens+1; *part != NULL; part++) {
			MsnMessage *multipart;
			const char *type;
			multipart = msn_message_new(MSN_MSG_UNKNOWN);
			msn_message_parse_payload(multipart, *part, strlen(*part),
			                          MSG_OIM_LINE_DEM, MSG_OIM_BODY_DEM);

			type = msn_message_get_content_type(multipart);
			if (type && !strcmp(type, "text/plain")) {
				decode_msg = (char *)purple_base64_decode(multipart->body, &body_len);
				msn_message_destroy(multipart);
				break;
			}
			msn_message_destroy(multipart);
		}

		g_strfreev(tokens);
		g_free(bounds);

		if (decode_msg == NULL) {
			purple_debug_error("msn", "Couldn't find text/plain OIM message.\n");
			msn_message_destroy(message);
			return;
		}
	} else {
		decode_msg = (char *)purple_base64_decode(message->body, &body_len);
	}

	from = msn_message_get_attr(message, "X-OIM-originatingSource");

	/* Match number to user's mobile number, FROM is a phone number
	   if the other side pages you using your phone number */
	if (from && !strncmp(from, "tel:+", 5)) {
		MsnUser *user =	msn_userlist_find_user_with_mobile_phone(
				rdata->oim->session->userlist, from + 4);

		if (user && user->passport)
			passport = g_strdup(user->passport);
	}

	if (passport == NULL) {
		char *start, *end;

		from = msn_message_get_attr(message, "From");

		tokens = g_strsplit(from, " ", 2);
		if (tokens[1] != NULL)
			from = (const char *)tokens[1];

		start = strchr(from, '<');
		if (start != NULL) {
			start++;
			end = strchr(from, '>');
			if (end != NULL)
				passport = g_strndup(start, end - start);
		}
		if (passport == NULL)
			passport = g_strdup(_("Unknown"));

		g_strfreev(tokens);
	}

	date = msn_message_get_attr(message, "Date");
	stamp = msn_oim_parse_timestamp(date);
	purple_debug_info("msn", "oim Date:{%s},passport{%s}\n",
	                  date, passport);

	serv_got_im(rdata->oim->session->account->gc, passport, decode_msg, 0,
	            stamp);

	/*Now get the oim message ID from the oim_list.
	 * and append to read list to prepare for deleting the Offline Message when sign out
	 */
	msn_oim_post_delete_msg(rdata);

	g_free(passport);
	g_free(decode_msg);
	msn_message_destroy(message);
}
Example #2
0
/*Post the Offline Instant Message to User Conversation*/
static void
msn_oim_report_to_user(MsnOimRecvData *rdata, const char *msg_str)
{
    MsnMessage *message;
    const char *date;
    const char *from;
    const char *boundary;
    char *decode_msg = NULL, *clean_msg = NULL;
    gsize body_len;
    char **tokens;
    char *passport = NULL;
    time_t stamp;
    const char *charset = NULL;

    message = msn_message_new(MSN_MSG_UNKNOWN);

    msn_message_parse_payload(message, msg_str, strlen(msg_str),
                              MSG_OIM_LINE_DEM, MSG_OIM_BODY_DEM);
    purple_debug_info("msn", "oim body:{%s}\n", message->body);

    boundary = msn_message_get_header_value(message, "boundary");

    if (boundary != NULL) {
        char *bounds;
        char **part;

        bounds = g_strdup_printf("--%s" MSG_OIM_LINE_DEM, boundary);
        tokens = g_strsplit(message->body, bounds, 0);

        /* tokens+1 to skip the "This is a multipart message..." text */
        for (part = tokens+1; *part != NULL; part++) {
            MsnMessage *multipart;
            const char *type;
            multipart = msn_message_new(MSN_MSG_UNKNOWN);
            msn_message_parse_payload(multipart, *part, strlen(*part),
                                      MSG_OIM_LINE_DEM, MSG_OIM_BODY_DEM);

            type = msn_message_get_content_type(multipart);
            if (type && !strcmp(type, "text/plain")) {
                decode_msg = (char *)purple_base64_decode(multipart->body, &body_len);
                charset = msn_message_get_charset(multipart);

                msn_message_unref(multipart);
                break;
            }
            msn_message_unref(multipart);
        }

        g_strfreev(tokens);
        g_free(bounds);

        if (decode_msg == NULL) {
            purple_debug_error("msn", "Couldn't find text/plain OIM message.\n");
            msn_message_unref(message);
            return;
        }
    } else {
        decode_msg = (char *)purple_base64_decode(message->body, &body_len);
        charset = msn_message_get_charset(message);
    }

    if (charset && !((g_ascii_strncasecmp(charset, "UTF-8", 5) == 0) || (g_ascii_strncasecmp(charset, "UTF8", 4) == 0))) {
        clean_msg = g_convert(decode_msg, body_len, "UTF-8", charset, NULL, NULL, NULL);

        if (!clean_msg) {
            char *clean = purple_utf8_salvage(decode_msg);

            purple_debug_error("msn", "Failed to convert charset from %s to UTF-8 for OIM message: %s\n", charset, clean);

            clean_msg = g_strdup_printf(_("%s (There was an error receiving this message. "
                                          "Converting the encoding from %s to UTF-8 failed.)"),
                                        clean, charset);
            g_free(clean);
        }

        g_free(decode_msg);

    } else if (!g_utf8_validate(decode_msg, body_len, NULL)) {
        char *clean = purple_utf8_salvage(decode_msg);

        purple_debug_error("msn", "Received an OIM message that is not UTF-8,"
                           " and no encoding specified: %s\n", clean);

        if (charset) {
            clean_msg = g_strdup_printf(_("%s (There was an error receiving this message."
                                          " The charset was %s, but it was not valid UTF-8.)"),
                                        clean, charset);
        } else {
            clean_msg = g_strdup_printf(_("%s (There was an error receiving this message."
                                          " The charset was missing, but it was not valid UTF-8.)"),
                                        clean);
        }

        g_free(clean);
        g_free(decode_msg);

    } else {
        clean_msg = decode_msg;
    }

    from = msn_message_get_header_value(message, "X-OIM-originatingSource");

    /* Match number to user's mobile number, FROM is a phone number
       if the other side pages you using your phone number */
    if (from && !strncmp(from, "tel:+", 5)) {
        MsnUser *user =	msn_userlist_find_user_with_mobile_phone(
                            rdata->oim->session->userlist, from + 4);

        if (user && user->passport)
            passport = g_strdup(user->passport);
    }

    if (passport == NULL) {
        char *start, *end;

        from = msn_message_get_header_value(message, "From");

        tokens = g_strsplit(from, " ", 2);
        if (tokens[1] != NULL)
            from = (const char *)tokens[1];

        start = strchr(from, '<');
        if (start != NULL) {
            start++;
            end = strchr(from, '>');
            if (end != NULL)
                passport = g_strndup(start, end - start);
        }
        if (passport == NULL)
            passport = g_strdup(_("Unknown"));

        g_strfreev(tokens);
    }

    date = msn_message_get_header_value(message, "Date");
    stamp = msn_oim_parse_timestamp(date);
    purple_debug_info("msn", "oim Date:{%s},passport{%s}\n",
                      date, passport);

    purple_serv_got_im(purple_account_get_connection(rdata->oim->session->account), passport, clean_msg, 0,
                       stamp);

    /*Now get the oim message ID from the oim_list.
     * and append to read list to prepare for deleting the Offline Message when sign out
     */
    msn_oim_post_delete_msg(rdata);

    g_free(passport);
    g_free(clean_msg);
    msn_message_unref(message);
}