Пример #1
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);
}
Пример #2
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;
}
Пример #3
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;
    }
}
Пример #4
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;
}
Пример #5
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;
}
Пример #6
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;
}
Пример #7
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;
}
Пример #8
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;
    }
}