Beispiel #1
0
/**
 * Process the iq messages.
 */
static void
xmpp_stream_process_iq(XmppStream *stream, xmlnode *node)
{
    gchar         *id;
    gint           id_int;
    GSList        *pos;
    IqTransaction *trans;
    gchar         *value;

    g_return_if_fail(stream != NULL);
    g_return_if_fail(node != NULL);

    if (!xmlnode_has_prop(node, "type") ||
        !xmlnode_has_prop(node, "id")) {
        hybrid_debug_error("xmpp", "invalid iq message.");

        return;
    }

    value = xmlnode_prop(node, "type");

    /* response to a get or set request. */
    if (g_strcmp0(value, "result") == 0 ||
        g_strcmp0(value, "error") == 0) {

        id = xmlnode_prop(node, "id");
        id_int = atoi(id);
        g_free(id);

        for (pos = stream->pending_trans; pos; pos = pos->next) {
            trans = (IqTransaction*)pos->data;

            if (trans->iq_id == id_int) {

                if (trans->callback) {
                    trans->callback(stream, node, trans->user_data);
                }

                iq_transaction_remove(stream, trans);
            }
        }

    /*
     * An entity that receives an IQ request of type "get" or "set" MUST
       reply with an IQ response of type "result" or "error".
     */
    } else if (g_strcmp0(value, "get") == 0) { /* process later. */
    } else if (g_strcmp0(value, "set") == 0) {
        xmpp_stream_process_iq_set(stream, node);
    }

    g_free(value);
}
Beispiel #2
0
/**
 * Process the roster set request.
 */
static void
xmpp_stream_process_set_roster(XmppStream *stream, xmlnode *query)
{
    xmlnode   *node;
    gchar     *value;
    XmppBuddy *buddy;

    g_return_if_fail(stream != NULL);
    g_return_if_fail(query != NULL);

    if (!(node = xmlnode_child(query))) {
        return;
    }

    while (node) {

        if (g_strcmp0(node->name, "item") != 0) {
            node = node->next;
            continue;
        }

        if (!xmlnode_has_prop(node, "jid")) {
            node = node->next;
            continue;
        }

        value = xmlnode_prop(node, "jid");
        
        if (!(buddy = xmpp_buddy_find(stream->account, value))) {
            g_free(value);
            node = node->next;
            continue;
        }
        g_free(value);

        if (xmlnode_has_prop(node, "subscription")) {
            value = xmlnode_prop(node, "subscription");
            xmpp_buddy_set_subscription(buddy, value);
            g_free(value);
        }

        if (xmlnode_has_prop(node, "name")) {
            value = xmlnode_prop(node, "name");
            xmpp_buddy_set_name(buddy, value);
            g_free(value);
        }

        node = node->next;
    }
}
Beispiel #3
0
void
hybrid_pref_set_int(const gchar *name, gint value)
{
    xmlnode *node;
    gchar   *value_string;

    g_return_if_fail(hybrid_pref != NULL);
    g_return_if_fail(hybrid_pref->root != NULL);

    if (!(node = xmlnode_find(hybrid_pref->root, name))) {

        node = xmlnode_new_child(hybrid_pref->root, name);
    }

    if (xmlnode_has_prop(node, "type")) {
        xmlnode_set_prop(node, "type", "int");

    } else {
        xmlnode_new_prop(node, "type", "int");
    }

    value_string = g_strdup_printf("%d", value);

    xmlnode_set_content(node, value_string);

    g_free(value_string);
}
Beispiel #4
0
void
hybrid_pref_set_boolean(const gchar *name, const gboolean value)
{
    xmlnode *node;

    g_return_if_fail(hybrid_pref != NULL);
    g_return_if_fail(hybrid_pref->root != NULL);

    if (!(node = xmlnode_find(hybrid_pref->root, name))) {

        node = xmlnode_new_child(hybrid_pref->root, name);

    }

    if (xmlnode_has_prop(node, "type")) {
        xmlnode_set_prop(node, "type", "bool");

    } else {
        xmlnode_new_prop(node, "type", "bool");
    }

    if (value) {
        xmlnode_set_content(node, "1");

    } else {
        xmlnode_set_content(node, "0");
    }
}
Beispiel #5
0
gchar*
hybrid_pref_get_string(const gchar *name)
{
    xmlnode *node;
    gchar   *type;
    gchar   *value;

    g_return_val_if_fail(hybrid_pref != NULL, FALSE);
    g_return_val_if_fail(hybrid_pref->root != NULL, FALSE);

    if (!(node = xmlnode_find(hybrid_pref->root, name))) {
        return NULL;
    }

    if (!xmlnode_has_prop(node, "type")) {

        hybrid_debug_info("pref", "invalid pref node.");
        
        return NULL;
    }

    type = xmlnode_prop(node, "type");

    if (g_strcmp0(type, "string") != 0) {

        hybrid_debug_error("pref",
                "string pref node with a type which is not string.");

        return NULL;
    }

    value = xmlnode_content(node);

    return value;
}
Beispiel #6
0
/**
 * Process the iq set request.
 */
static void
xmpp_stream_process_iq_set(XmppStream *stream, xmlnode *root)
{
    gchar   *id;
    gchar   *value;
    xmlnode *node;
    gint     count = 0;

    g_return_if_fail(stream != NULL);
    g_return_if_fail(root != NULL);

    node = xmlnode_child(root);

    for (; node; node = node->next, count ++);

    /*
     * An IQ stanza of type "get" or "set" MUST contain exactly one
     * child element, which specifies the semantics of the particular
     *  request.
     */
    if (count != 1) {
        /* TODO send error stanza. */
        return;
    }

    node = xmlnode_child(root);

    if (g_strcmp0(node->name, "query") == 0) {
        value = xmlnode_get_namespace(node);

        if (g_strcmp0(value, NS_IQ_ROSTER) == 0) {
            xmpp_stream_process_set_roster(stream, node);
        }

        g_free(value);
    }

    /* send a result response. */
    IqRequest *iq;

    iq = iq_request_create(stream, IQ_TYPE_RESULT);

    xmlnode_new_prop(iq->node, "from", stream->jid);

    if (xmlnode_has_prop(root, "id")) {

        id = xmlnode_prop(root, "id");
        xmlnode_set_prop(iq->node, "id", id);
        g_free(id);
    }

    iq_request_send(iq);
    iq_request_destroy(iq);
}
Beispiel #7
0
static gint
parse_ssi_fail_resp(fetion_account *ac, const gchar *response)
{
    xmlnode      *root;
    xmlnode      *node;
    Verification *ver;
    gchar        *pos;

    ver = fetion_verification_create();

    if (!(pos = strstr(response, "\r\n\r\n"))) {
        return HYBRID_ERROR;
    }

    pos += 4;

    root = xmlnode_root(pos, strlen(pos));

    if (!(node = xmlnode_find(root, "results"))) {
        return HYBRID_ERROR;
    }

    if (xmlnode_has_prop(node, "desc")) {
        ver->desc = xmlnode_prop(node, "desc");
    }

    if (!(node = xmlnode_find(root, "verification"))) {
        return HYBRID_ERROR;
    }

    if (xmlnode_has_prop(node, "algorithm")) {
        ver->algorithm = xmlnode_prop(node, "algorithm");
    }

    ac->verification = ver;

    return HYBRID_OK;
}
Beispiel #8
0
GSList*
hybrid_logs_read(HybridAccount *account, const gchar *id, const gchar *logname)
{
    gchar *log_path = NULL;
    gchar *log_name = NULL;
    gchar *tmp;
    GSList *list = NULL;
    xmlnode *root = NULL, *node, *child;
    HybridLogEntry *entry;

    log_path = hybrid_logs_get_path(account, id);
    log_name = g_strdup_printf("%s/%s", log_path, logname);

    root = xmlnode_root_from_file(log_name);
    if (!root) {
		hybrid_debug_error("log", "log %s read error.\n", log_name);
        goto out;
	}

    node = xmlnode_child(root);
    while (node) {
        if (!xmlnode_has_prop(node, "type"))
            goto next;

        entry = g_new0(HybridLogEntry, 1);
        tmp = xmlnode_prop(node, "type");
        if (g_strcmp0(tmp, "o")) {
            entry->is_send = 1;
        } else {
            entry->is_send = 0;
        }
        g_free(tmp);

        child = xmlnode_find(node, "t");
        entry->time = xmlnode_content(child);
        child = xmlnode_find(node, "n");
        entry->name = xmlnode_content(child);
        child = xmlnode_find(node, "c");
        entry->content = xmlnode_content(child);
        list = g_slist_append(list, entry);
next:
        node = xmlnode_next(node);
    }

out:
    free(log_path);
    free(log_name);
    xmlnode_free(root);
    return list;
}
Beispiel #9
0
gint
sip_parse_appbuddy(const gchar *sipmsg, gchar **userid,
                   gchar **sipuri, gchar **desc)
{
    gchar   *pos;
    xmlnode *root;
    xmlnode *node;

    if (!(pos = strstr(sipmsg, "\r\n\r\n"))) {
        return HYBRID_ERROR;
    }

    pos += 4;

    if (!(root = xmlnode_root(pos, strlen(pos)))) {
        return HYBRID_ERROR;
    }

    if (!(node = xmlnode_find(root, "application"))) {
        return HYBRID_ERROR;
    }

    if (xmlnode_has_prop(node, "uri") && sipuri != NULL) {
        *sipuri = xmlnode_prop(node, "uri");
    }

    if (xmlnode_has_prop(node, "user-id") && userid != NULL) {
        *userid = xmlnode_prop(node, "user-id");
    }

    if (xmlnode_has_prop(node, "desc") && desc != NULL) {
        *desc = xmlnode_prop(node, "desc");
    }

    return HYBRID_OK;
}
Beispiel #10
0
gchar*
get_province_name(const gchar *province)
{
    xmlnode *root;
    xmlnode *node;
    gchar   *name;
    gchar   *value;

    g_return_val_if_fail(province != NULL, NULL);

    if (!(root = xmlnode_root_from_file(FETION_RES_DIR"province.xml"))) {
        return NULL;
    }

    if (!(node = xmlnode_child(root)) || g_strcmp0(node->name, "Province")) {
        hybrid_debug_error("fetion",
                "get full province name");
        return NULL;
    }

    for (; node; node = xmlnode_next(node)) {

        if (!xmlnode_has_prop(node, "id")) {
            continue;
        }

        value = xmlnode_prop(node, "id");

        if (g_strcmp0(value, province) == 0) {
            name = xmlnode_content(node);

            /* found, do cleanup. */
            g_free(value);
            xmlnode_free(root);

            return name;
        }

        g_free(value);
    }

    xmlnode_free(root);

    return NULL;
}
Beispiel #11
0
gboolean
hybrid_pref_get_boolean(const gchar *name)
{
    xmlnode *node;
    gchar   *type;
    gchar   *value;

    g_return_val_if_fail(hybrid_pref != NULL, FALSE);
    g_return_val_if_fail(hybrid_pref->root != NULL, FALSE);

    if (!(node = xmlnode_find(hybrid_pref->root, name))) {
        return FALSE;
    }

    if (!xmlnode_has_prop(node, "type")) {

        hybrid_debug_info("pref", "invalid pref node.");
        
        return FALSE;
    }

    type = xmlnode_prop(node, "type");

    if (g_strcmp0(type, "bool") != 0) {

        hybrid_debug_error("pref",
                "bool pref node with a type which is not bool.");

        return FALSE;
    }

    value = xmlnode_content(node);

    if (g_strcmp0(value, "0") == 0) {

        g_free(value);
        return FALSE;

    } else {

        g_free(value);
        return TRUE;
    }
}
Beispiel #12
0
/**
 * Callback function to process the buddy's get-info response.
 */
static gboolean
buddy_get_info_cb(XmppStream *stream, xmlnode *root, XmppBuddy *buddy)
{
    xmlnode *node;
    gchar   *type;
    gchar   *photo_bin;
    guchar  *photo;
    gint     photo_len;

    if (xmlnode_has_prop(root, "type")) {
        type = xmlnode_prop(root, "type");

        if (g_strcmp0(type, "result") != 0) {

            hybrid_debug_error("xmpp", "get buddy info error.");
            g_free(type);

            return FALSE;
        }

        g_free(type);
    }

    if ((node = xmlnode_find(root, "PHOTO"))) {

        if ((node = xmlnode_find(root, "BINVAL"))) {

            photo_bin = xmlnode_content(node);

            /* decode the base64-encoded photo string. */
            photo = hybrid_base64_decode(photo_bin, &photo_len);

            /* set icon for the buddy. */
            hybrid_blist_set_buddy_icon(buddy->buddy, photo,
                                    photo_len, buddy->photo);
            g_free(photo_bin);
            g_free(photo);
        }
    }

    return TRUE;
}
Beispiel #13
0
void
hybrid_pref_set_string(const gchar *name, const gchar *value)
{
    xmlnode *node;

    g_return_if_fail(hybrid_pref != NULL);
    g_return_if_fail(hybrid_pref->root != NULL);

    if (!(node = xmlnode_find(hybrid_pref->root, name))) {

        node = xmlnode_new_child(hybrid_pref->root, name);
    }

    if (xmlnode_has_prop(node, "type")) {
        xmlnode_set_prop(node, "type", "string");

    } else {
        xmlnode_new_prop(node, "type", "string");
    }

    xmlnode_set_content(node, value);
}
Beispiel #14
0
gint
hybrid_pref_get_int(const gchar *name)
{
    xmlnode *node;
    gchar   *type;
    gchar   *value;
    gint     value_int;

    g_return_val_if_fail(hybrid_pref != NULL, FALSE);
    g_return_val_if_fail(hybrid_pref->root != NULL, FALSE);

    if (!(node = xmlnode_find(hybrid_pref->root, name))) {
        return -1;
    }

    if (!xmlnode_has_prop(node, "type")) {

        hybrid_debug_info("pref", "invalid pref node.");
        
        return -1;
    }

    type = xmlnode_prop(node, "type");

    if (g_strcmp0(type, "int") != 0) {

        hybrid_debug_error("pref",
                "integer pref node with a type which is not int.");

        return -1;
    }

    value = xmlnode_content(node);
    value_int = atoi(value);
    g_free(value);

    return value_int;
}
Beispiel #15
0
static gboolean
ping_cb(XmppStream *stream, xmlnode *node, gpointer user_data)
{
    gchar *value;

    if (xmlnode_has_prop(node, "type")) {
        value = xmlnode_prop(node, "type");

        if (g_strcmp0(value, "result") != 0) {

            hybrid_debug_error("xmpp", "ping xmpp server refused.");

            hybrid_account_error_reason(stream->account->account,
                    _("Connection Closed."));
        }
    }

    if (stream->keepalive_source) {
        g_source_remove(stream->keepalive_source);
        stream->keepalive_source = 0;
    }

    return FALSE;
}
Beispiel #16
0
static void
xmpp_stream_process_presence(XmppStream *stream, xmlnode *root)
{
    xmlnode   *node;
    XmppBuddy *buddy;
    gchar     *value;
    gchar     *full_jid;
    gchar     *bare_jid;
    gchar     *show;
    gchar     *status;
    gchar     *photo;

    if (!xmlnode_has_prop(root, "from")) {
        hybrid_debug_error("xmpp", "invalid presence.");
        return;
    }

    full_jid = xmlnode_prop(root, "from");
    bare_jid = get_bare_jid(full_jid);

    if (xmlnode_has_prop(root, "type")) {

        value = xmlnode_prop(root, "type");
        if (g_strcmp0(value, "unavailable") == 0) {

            if (!(buddy = xmpp_buddy_find(stream->account, bare_jid))) {
                goto presence_over;
            }

            xmpp_buddy_set_show(buddy, full_jid, value);
            g_free(value);
            goto presence_over;

        } else if (g_strcmp0(value, "subscribed") == 0) {
            
            hybrid_message_box_show(HYBRID_MESSAGE_INFO, 
                    "(<b>%s</b>) has accepted your request.", bare_jid);
            g_free(value);
            goto presence_over;

        } else if (g_strcmp0(value, "subscribe") == 0) {

            hybrid_buddy_request_window_create(stream->account->account,
                    full_jid, NULL);
            g_free(value);
            goto presence_over;
        }

        g_free(value);
    }

    if (!(buddy = xmpp_buddy_find(stream->account, bare_jid))) {
        goto presence_over;
    }

    /*
     * If the presence message doesn't have a <show> label,
     * then it means the current status of the buddy is 'avaiable'.
     */
    if ((node = xmlnode_find(root, "show"))) {

        show = xmlnode_content(node);
        xmpp_buddy_set_show(buddy, full_jid, show);
        g_free(show);

    } else {
        xmpp_buddy_set_show(buddy, full_jid, "avaiable");
    }

    if ((node = xmlnode_find(root, "status"))) {

        status = xmlnode_content(node);
        xmpp_buddy_set_status(buddy, full_jid, status);
        g_free(status);

    } 
    /*
     * Check whether it has a photo label, then we can
     * determine whether to fetch the buddy's photo.
     */
    if ((node = xmlnode_find(root, "photo"))) {

        photo = xmlnode_content(node);

        if (g_strcmp0(photo, buddy->photo) != 0) {

            xmpp_buddy_set_photo(buddy, photo);
            xmpp_buddy_get_info(stream, buddy->jid,
                    (trans_callback)buddy_get_info_cb, buddy);
        }

        g_free(photo);
    }
    
presence_over:
    g_free(full_jid);
    g_free(bare_jid);
}
Beispiel #17
0
static gint
buddy_add_cb(fetion_account *account, const gchar *sipmsg,
			fetion_transaction *trans)
{
	gint code;
	gchar *pos;
	gchar *value;
	gchar *name;
	fetion_buddy *buddy;
	HybridGroup *group;
	HybridBuddy *bd;
	xmlnode *root;
	xmlnode *node;

	hybrid_debug_info("fetion", "add buddy, recv:\n%s", sipmsg);

	if ((code = fetion_sip_get_code(sipmsg)) != 200) {

		hybrid_message_box_show(HYBRID_MESSAGE_WARNING,
				"Add buddy error. Server response with %d", code);

		return HYBRID_ERROR;
	}

	if (!(pos = strstr(sipmsg, "\r\n\r\n"))) {
		goto add_buddy_unknown_err;
	}

	pos += 4;

	if (!(root = xmlnode_root(pos, strlen(pos)))) {
		goto add_buddy_unknown_err;
	}

	if (!(node = xmlnode_find(root, "buddy"))) {

		xmlnode_free(root);

		goto add_buddy_unknown_err;
	}

	if (xmlnode_has_prop(node, "status-code")) {
		
		value = xmlnode_prop(node, "status-code");

		code = atoi(value);

		g_free(value);

		if (code == 200) {
			goto add_buddy_ok;
		}

		xmlnode_free(node);

		if (code == 521) {

			hybrid_message_box_show(HYBRID_MESSAGE_WARNING,
					"The buddy has already been in your buddy list,\n"
					"Please don't add it duplicately.");

			return HYBRID_ERROR;
		}

		if (code == 404) {

			hybrid_message_box_show(HYBRID_MESSAGE_WARNING,
					"The buddy you try to add doesn't exist.");

			return HYBRID_ERROR;
		}

		if (code == 486) {
			
			hybrid_message_box_show(HYBRID_MESSAGE_WARNING,
					"You have reached the daily limit of adding buddies,\n"
					"please try another day.");

			return HYBRID_ERROR;
		}

		goto add_buddy_unknown_err;
	}

add_buddy_ok:

	if (!xmlnode_has_prop(node, "user-id") ||
		!xmlnode_has_prop(node, "local-name") ||
		!xmlnode_has_prop(node, "uri") ||
		!xmlnode_has_prop(node, "buddy-lists")) {

		xmlnode_free(root);

		goto add_buddy_unknown_err;
	}

	buddy = fetion_buddy_create();

	buddy->userid    = xmlnode_prop(node, "user-id");
	buddy->localname = xmlnode_prop(node, "local-name");
	buddy->sipuri    = xmlnode_prop(node, "uri");
	buddy->groups    = xmlnode_prop(node, "buddy-lists");

	xmlnode_free(root);

	account->buddies = g_slist_append(account->buddies, buddy);

	if (!(group = hybrid_blist_find_group(account->account, buddy->groups))) {
		fetion_buddy_destroy(buddy);
		account->buddies = g_slist_remove(account->buddies, buddy);

		goto add_buddy_unknown_err;
	}

	if (buddy->localname && *(buddy->localname) == '\0') {
		name = get_sid_from_sipuri(buddy->sipuri);

	} else {
		name = g_strdup(buddy->localname);
	}

	bd = hybrid_blist_add_buddy(account->account, group, buddy->userid, name);
	hybrid_blist_set_buddy_status(bd, FALSE);

	g_free(name);

	return HYBRID_OK;

add_buddy_unknown_err:
	hybrid_message_box_show(HYBRID_MESSAGE_WARNING,
			"Add buddy error. Unknown reason.");
	
	return HYBRID_ERROR;
}
Beispiel #18
0
static gint
handle_request_cb(fetion_account *account, const gchar *sipmsg,
			fetion_transaction *trans)
{
	gchar *pos;
	gchar *value;
	fetion_buddy *buddy;
	xmlnode *root;
	xmlnode *node;
	HybridGroup *group;
	HybridBuddy *bd;
	gchar *name;

	if (!(pos = strstr(sipmsg, "\r\n\r\n"))) {
		return HYBRID_ERROR;
	}

	pos += 4;

	if (!(root = xmlnode_root(pos, strlen(pos)))) {
		return HYBRID_ERROR;
	}

	if (!(node = xmlnode_find(root, "buddy"))) {
		return HYBRID_ERROR;
	}

	if (!xmlnode_has_prop(node, "uri") ||
		!xmlnode_has_prop(node, "user-id")) {
		return HYBRID_ERROR;
	}

	buddy = fetion_buddy_create();
	buddy->sipuri = xmlnode_prop(node, "uri");
	buddy->userid = xmlnode_prop(node, "user-id");
	buddy->sid = get_sid_from_sipuri(buddy->sipuri);

	account->buddies = g_slist_append(account->buddies, buddy);

	if (xmlnode_has_prop(node, "local-name")) {
		buddy->localname = xmlnode_prop(node, "localname");
	}

	if (xmlnode_has_prop(node, "buddy-lists")) {
		buddy->groups = xmlnode_prop(node, "buddy-lists");

	} else {
		buddy->groups = "0";
	}

	if (xmlnode_has_prop(node, "relation-status")) {
		value = xmlnode_prop(node, "relation-status");
		buddy->status = atoi(value);
		g_free(value);

	} else {
		buddy->status = 0;
	}

	if (!(group = hybrid_blist_find_group(account->account, buddy->groups))) {
		account->buddies = g_slist_remove(account->buddies, buddy);
		fetion_buddy_destroy(buddy);
		return HYBRID_ERROR;
	}

	if (buddy->localname && *(buddy->localname) == '\0') {
		name = get_sid_from_sipuri(buddy->sipuri);

	} else {
		name = g_strdup(buddy->localname);
	}

	bd = hybrid_blist_add_buddy(account->account, group, buddy->userid, name);
	hybrid_blist_set_buddy_status(bd, buddy->status == 1 ? TRUE: FALSE);

	g_free(name);

	return HYBRID_OK;
}
Beispiel #19
0
/**
 * Get the contact list from the xmlnode with name 'contact-list',
 * note that this node can either be a child node of the sipc
 * response xml message , or a child node of the local xml file.
 */
static void
get_contact_list(fetion_account *ac, xmlnode *contact_node)
{
    gchar        *temp;
    gchar        *temp1;
    xmlnode      *node;
    fetion_group *group;
    fetion_buddy *buddy;
    gboolean      has_ungroup = FALSE;

    g_return_if_fail(ac != NULL);
    g_return_if_fail(contact_node != NULL);

    /* group list */
    node = xmlnode_find(contact_node, "buddy-lists");
    node = xmlnode_child(node);

    while (node) {
        temp  = xmlnode_prop(node, "name");
        temp1 = xmlnode_prop(node, "id");

        group      = fetion_group_create(atoi(temp1), temp);
        ac->groups = g_slist_append(ac->groups, group);

        g_free(temp);
        g_free(temp1);

        node = node->next;
    }

    /* contact list  */
    node = xmlnode_find(contact_node, "buddies");
    node = xmlnode_child(node);

    while (node) {
        buddy            = fetion_buddy_create();
        buddy->userid    = xmlnode_prop(node, "i");
        buddy->sipuri    = xmlnode_prop(node, "u");
        buddy->localname = xmlnode_prop(node, "n");
        buddy->groups    = xmlnode_prop(node, "l");
        buddy->sid       = get_sid_from_sipuri(buddy->sipuri);

        if (xmlnode_has_prop(node, "r")) {

            temp = xmlnode_prop(node, "r");
            buddy->status = atoi(temp);
            g_free(temp);

        } else {
            buddy->status = 0;
        }

        ac->buddies = g_slist_append(ac->buddies, buddy);

        /* ungrouped */
        if (*(buddy->groups) == '\0' || buddy->groups[0] == '0') {
            g_free(buddy->groups);
            buddy->groups = g_strdup("0");

            if (!has_ungroup) { /**< add an "ungroup" group */
                group      = fetion_group_create(0, _("Ungrouped"));
                ac->groups = g_slist_append(ac->groups, group);

                has_ungroup = TRUE;
            }
        }

        node = node->next;
    }
}
Beispiel #20
0
static gboolean
pic_read_cb(gint sk, gpointer user_data)
{
    gint     n, len;
    gchar    sipmsg[BUF_LENGTH];
    gchar   *code, *pos;
    guchar  *pic;
    gint     piclen;
    xmlnode *root;
    xmlnode *node;

    fetion_account *ac = (fetion_account*)user_data;

    len    = ac->buffer ? strlen(ac->buffer) : 0;

    if((n = recv(sk, sipmsg, strlen(sipmsg), 0)) == -1) {
        return -1;
    }

    sipmsg[n] = 0;

    if(n == 0) {
           g_source_remove(ac->source);
        ac->source = 0;
        close(sk);

        if(! ac->buffer) {
            return 0;
        }

        hybrid_debug_info("fetion", "read message resp:\n%s", ac->buffer);

        if (200 != hybrid_get_http_code(ac->buffer)) {
            goto read_pic_err;
        }

        if(!(pos = strstr(ac->buffer, "\r\n\r\n"))) {
            goto read_pic_err;
        }

        pos += 4;

        if (!(root = xmlnode_root(pos, strlen(pos)))) {
            goto read_pic_err;
        }

        if (!(node = xmlnode_find(root, "pic-certificate"))) {
            xmlnode_free(root);
            goto read_pic_err;
        }

        if (!xmlnode_has_prop(node, "id") || !xmlnode_has_prop(node, "pic")) {
            xmlnode_free(root);
            goto read_pic_err;
        }

        ac->verification->guid = xmlnode_prop(node, "id");
        code                   = xmlnode_prop(node, "pic");

        pic = hybrid_base64_decode(code, &piclen);

        hybrid_confirm_window_create(ac->account, pic, piclen,
                                     pic_code_ok_cb, pic_code_cancel_cb, ac);

        g_free(code);
        g_free(pic);
        xmlnode_free(root);
        g_free(ac->buffer);
        ac->buffer = (gchar*)0;

        return FALSE;
    }

    ac->buffer = (gchar*)realloc(ac->buffer, len + n + 1);
    memcpy(ac->buffer + len, sipmsg, n + 1);

    return TRUE;

 read_pic_err:
    hybrid_debug_error("fetion", "read pic code error.");

    g_free(ac->buffer);
    ac->buffer = (gchar *)0;

    hybrid_account_error_reason(ac->account, _("read pic code error."));
    return FALSE;
}
Beispiel #21
0
static void
xmpp_stream_process_message(XmppStream *stream, xmlnode *root)
{
    gchar         *value;
    gchar         *bare_jid;
    xmlnode       *node;
    HybridAccount *account;

    g_return_if_fail(stream != NULL);
    g_return_if_fail(root != NULL);

    account = stream->account->account;

    if (!xmlnode_has_prop(root, "type")) {
        hybrid_debug_error("xmpp", 
                "invalid message received without a type property.");
        return;
    }

    value = xmlnode_prop(root, "type");

    if (g_strcmp0(value, "chat") != 0) {

        hybrid_debug_error("xmpp", "unsupported message type.");
        g_free(value);

        return;
    }

    g_free(value);

    if (!xmlnode_has_prop(root, "from")) {
        
        hybrid_debug_error("xmpp", "invalid message without a from property.");
        return;
    }

    value = xmlnode_prop(root, "from");
    bare_jid = get_bare_jid(value);
    g_free(value);

    if ((node = xmlnode_find(root, "composing"))) {
        hybrid_conv_got_inputing(account, bare_jid, FALSE);
    }

    if ((node = xmlnode_find(root, "active"))) {
        hybrid_conv_clear_inputing(account, bare_jid);
    }

    if ((node = xmlnode_find(root, "paused"))) {
        hybrid_conv_stop_inputing(account, bare_jid);
    }

    if ((node = xmlnode_find(root, "body"))) {

        value = xmlnode_content(node);
        hybrid_conv_got_message(account, bare_jid, value, time(NULL));
        g_free(value);

        return;
    }

}
Beispiel #22
0
gchar*
get_city_name(const gchar *province, const gchar *city)
{
    xmlnode *root;
    xmlnode *node;
    gchar   *name;
    gchar   *value;

    if (!(root = xmlnode_root_from_file(FETION_RES_DIR"city.xml"))) {
        return NULL;
    }

    if (!(node = xmlnode_child(root)) || g_strcmp0(node->name, "Province")) {
        hybrid_debug_error("fetion",
                "get full city name");
        return NULL;
    }

    for (; node; node = xmlnode_next(node)) {

        if (!xmlnode_has_prop(node, "id")) {
            continue;
        }

        value = xmlnode_prop(node, "id");

        if (g_strcmp0(value, province) == 0) {
            /* found, do cleanup. */
            g_free(value);

            goto province_found;
        }

        g_free(value);

    }

    xmlnode_free(root);

    return NULL;

province_found:

    if (!(node = xmlnode_child(node)) || g_strcmp0(node->name, "City")) {
        hybrid_debug_error("fetion",
                "get full city name");
        xmlnode_free(root);

        return NULL;
    }

    for (; node; node = xmlnode_next(node)) {

        if (!xmlnode_has_prop(node, "id")) {
            continue;
        }

        value = xmlnode_prop(node, "id");

        if (g_strcmp0(value, city) == 0) {

            name= xmlnode_content(node);

            /* found, do cleanup. */
            g_free(value);
            xmlnode_free(root);

            return name;
        }

        g_free(value);

    }

    xmlnode_free(root);

    return NULL;
}
Beispiel #23
0
GSList*
sip_parse_sync(fetion_account *account, const gchar *sipmsg)
{
    gchar        *pos;
    gchar        *action;
    gchar        *userid;
    gchar        *status;
    xmlnode      *root;
    xmlnode      *node;
    fetion_buddy *buddy;
    GSList       *list = NULL;

    if (!(pos = strstr(sipmsg, "\r\n\r\n"))) {
        goto sync_info_err;
    }

    pos += 4;

    if (!(root = xmlnode_root(pos, strlen(pos)))) {
        goto sync_info_err;
    }

    if (!(node = xmlnode_find(root, "buddies"))) {

        xmlnode_free(root);

        return list;
    }

    node = xmlnode_child(node);

    while (node) {
        if (!xmlnode_has_prop(node, "action")) {
            goto next;
        }

        action = xmlnode_prop(node, "action");

        if (g_strcmp0(action, "update") == 0) {
            
            if (!xmlnode_has_prop(node, "user-id") ||
                !xmlnode_has_prop(node, "relation-status")) {

                g_free(action);

                goto next;
            }

            userid = xmlnode_prop(node, "user-id");
            status = xmlnode_prop(node, "relation-status");

            if (!(buddy = fetion_buddy_find_by_userid(account, userid))) {

                g_free(action);
                g_free(userid);
                g_free(status);

                goto next;
            }

            buddy->status = atoi(status);

            list = g_slist_append(list, buddy);

            g_free(status);
            g_free(userid);
        }

        g_free(action);
next:
        node = xmlnode_next(node);
    }

    return list;

sync_info_err:
    hybrid_debug_error("fetion", "invalid sync info");

    return list;
}
Beispiel #24
0
GSList*
sip_parse_presence(fetion_account *ac, const gchar *sipmsg)
{
    gchar        *pos;
    gchar        *temp;
    xmlnode      *root;
    xmlnode      *node;
    xmlnode      *pnode;
    GSList       *list = NULL;
    fetion_buddy *buddy;

    if (!(pos = strstr(sipmsg, "\r\n\r\n"))) {
        return list;
    }

    pos += 4;

    root = xmlnode_root(pos, strlen(pos));
    node = xmlnode_find(root, "contacts");
    node = xmlnode_child(node);

    while (node) {

        temp = xmlnode_prop(node, "id");

        if (!(buddy = fetion_buddy_find_by_userid(ac, temp))) {
            /* Maybe yourself's presence, we just ignore it. */
            g_free(temp);
            node = node->next;
            continue;
        }

        g_free(temp);

        list = g_slist_append(list, buddy);

        if ((pnode = xmlnode_find(node, "p"))) {

            if (xmlnode_has_prop(pnode, "m")) {
                temp = xmlnode_prop(pnode, "m");
                g_free(buddy->mobileno);
                buddy->mobileno = g_strdup(temp);
                g_free(temp);
            }

            if (xmlnode_has_prop(pnode, "n")) {
                temp = xmlnode_prop(pnode, "n");
                g_free(buddy->nickname);
                buddy->nickname = g_strdup(temp);
                g_free(temp);
            }

            if (xmlnode_has_prop(pnode, "i")) {
                temp = xmlnode_prop(pnode, "i");
                g_free(buddy->mood_phrase);
                buddy->mood_phrase = g_strdup(temp);
                g_free(temp);
            }

            if (xmlnode_has_prop(pnode, "c")) {
                temp = xmlnode_prop(pnode, "c");
                g_free(buddy->carrier);
                buddy->carrier = g_strdup(temp);
                g_free(temp);
            }

            if (xmlnode_has_prop(pnode, "p")) {
                temp = xmlnode_prop(pnode, "p");
                g_free(buddy->portrait_crc);

                if (*temp == '\0') {
                    g_free(temp);
                    temp = g_strdup("0");
                }
                buddy->portrait_crc = temp;
            } else {
                g_free(buddy->portrait_crc);
                buddy->portrait_crc = g_strdup("0");
            }

            if (xmlnode_has_prop(pnode, "cs")) {
                temp = xmlnode_prop(pnode, "cs");
                buddy->carrier_status = atoi(temp);
                g_free(temp);
            }
        }

        if ((pnode = xmlnode_find(node, "pr"))) {
            
            if (xmlnode_has_prop(pnode, "b")) {
                temp = xmlnode_prop(pnode, "b");
                buddy->state = atoi(temp);
                g_free(temp);
            }
        }

        node = node->next;
    }

    xmlnode_free(root);

    return list;
}
Beispiel #25
0
fetion_buddy*
fetion_buddy_parse_info(fetion_account *ac, 
		const gchar *userid, const gchar *sipmsg)
{
	xmlnode *root;
	xmlnode *node;
	gchar *pos;
	gchar *temp;
	gchar *value;
	fetion_buddy *buddy;
	gint code;

	code = fetion_sip_get_code(sipmsg);

	if (code != 200) {
		hybrid_debug_error("fetion", "get information with code:%d", code);
		return NULL;
	}

	if (!(pos = strstr(sipmsg, "\r\n\r\n"))) {
		goto get_info_error;
	}

	pos += 4;

	if (!(root = xmlnode_root(pos, strlen(pos)))) {
		goto get_info_error;
	}

	if (!(node = xmlnode_find(root, "contact"))) {
		xmlnode_free(root);
		goto get_info_error;
	}

	if (!(buddy = fetion_buddy_find_by_userid(ac, userid))) {
		xmlnode_free(root);
		goto get_info_error;
	}

	if (xmlnode_has_prop(node, "sid")) {
		value = xmlnode_prop(node, "sid");
		g_free(buddy->sid);
		buddy->sid = g_strdup(value);
		g_free(value);
	}

	if (xmlnode_has_prop(node, "mobile-no")) {
		value = xmlnode_prop(node, "mobile-no");
		g_free(buddy->mobileno);
		buddy->mobileno = g_strdup(value);
		g_free(value);
	}

	if (xmlnode_has_prop(node, "impresa")) {
		value = xmlnode_prop(node, "impresa");
		g_free(buddy->mood_phrase);
		buddy->mood_phrase = g_strdup(value);
		g_free(value);
	}

	if (xmlnode_has_prop(node, "nickname")) {
		value = xmlnode_prop(node, "nickname");
		g_free(buddy->nickname);
		buddy->nickname = g_strdup(value);
		g_free(value);
	}

	if (xmlnode_has_prop(node, "gender")) {
		value = xmlnode_prop(node, "gender");
		buddy->gender = atoi(value);
		g_free(value);
	}

	if (xmlnode_has_prop(node, "carrier-region")) {
		value = xmlnode_prop(node, "carrier-region");

		for (pos = value; *pos && *pos != '.'; pos ++);
		g_free(buddy->country);
		buddy->country = g_strndup(value, pos - value);

		for (pos ++, temp = pos; *pos && *pos != '.'; pos ++);
		g_free(buddy->province);
		buddy->province = g_strndup(temp, pos - temp);

		for (pos ++, temp = pos; *pos && *pos != '.'; pos ++);
		g_free(buddy->city);
		buddy->city = g_strndup(temp, pos - temp);

	}

	xmlnode_free(node);

	return buddy;

get_info_error:
	hybrid_debug_error("fetion", "invalid get-info response");
	return NULL;
}