Exemple #1
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;
}
Exemple #2
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;
}
Exemple #3
0
gint
fetion_message_parse_sysmsg(const gchar *sipmsg, gchar **content, gchar **url)
{
	gchar *pos;
	xmlnode *root;
	xmlnode *node;

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

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

	if (!(node = xmlnode_find(root, "content"))) {
		xmlnode_free(root);
		goto sysmsg_error;
	}

	*content = xmlnode_content(node);

	if ((node = xmlnode_find(root, "url"))) {
		*url = xmlnode_content(node);

	} else {
		*url = NULL;
	}

	xmlnode_free(root);

	return HYBRID_OK;

sysmsg_error:
	hybrid_debug_error("fetion", "invalid system message");
	return HYBRID_ERROR;
}
Exemple #4
0
/**
 * Callback function for the resource bind request to process the response.
 */
static gboolean
resource_bind_cb(XmppStream *stream, xmlnode *root, gpointer user_data)
{
    gchar   *type;
    gchar   *jid;
    xmlnode *node;

    type = xmlnode_prop(root, "type");

    if (g_strcmp0(type, "result")) {
        hybrid_account_error_reason(stream->account->account,
                _("resource bind error."));
        return FALSE;
    }

    if (!(node = xmlnode_find(root, "jid"))) {
        hybrid_account_error_reason(stream->account->account,
                _("resource bind error: no jabber id returned."));
        return FALSE;
    }

    jid = xmlnode_content(node);
    xmpp_stream_set_jid(stream, jid);
    g_free(jid);

    /* request to start a session. */
    IqRequest *iq;

    iq = iq_request_create(stream, IQ_TYPE_SET);

    node = xmlnode_new_child(iq->node, "session");
    xmlnode_new_namespace(node, NULL, NS_XMPP_SESSION);

    iq_request_set_callback(iq, start_session_cb, NULL);

    if (iq_request_send(iq) != HYBRID_OK) {

        hybrid_account_error_reason(stream->account->account,
                _("start session error."));

        iq_request_destroy(iq);

        return TRUE;
    }

    iq_request_destroy(iq);

    return TRUE;
}
Exemple #5
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;
}
Exemple #6
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;
    }
}
Exemple #7
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;
}
Exemple #8
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;
}
Exemple #9
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);
}
Exemple #10
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;
    }

}
Exemple #11
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;
}
Exemple #12
0
/**
 * parse the sipc authentication response, we can get the basic
 * information and the contact list of this account.
 */
static void
parse_sipc_resp(fetion_account *ac, const gchar *body, gint len)
{
    xmlnode *root;
    xmlnode *node;
    gchar   *version;

    g_return_if_fail(ac != NULL);
    g_return_if_fail(body != NULL);
    g_return_if_fail(len != 0);

    root = xmlnode_root(body, len);

    /* login info */
    node                = xmlnode_find(root, "client");
    ac->last_login_ip   = xmlnode_prop(root, "last-login-ip");
    ac->public_ip       = xmlnode_prop(root, "public-ip");
    ac->last_login_time = xmlnode_prop(root, "last-login-time");

    /* personal info */
    node    = xmlnode_find(root, "personal");
    version = xmlnode_prop(node, "version");

    if (g_strcmp0(version, ac->personal_version) == 0) {
        /* load from disk. */
        g_free(version);

        xmlnode *personal_root;
        xmlnode *personal_node;

        if (!(personal_root = fetion_config_load_personal(ac))) {
            hybrid_debug_error("fetion", "invalid personal.xml");
            xmlnode_free(root);
            return;
        }

        if (!(personal_node = xmlnode_find(personal_root, "personal"))) {
            hybrid_debug_error("fetion", "invalid personal.xml");
            xmlnode_free(personal_root);
            xmlnode_free(root);
            return;
        }
        get_personal(ac, personal_node);
        xmlnode_free(personal_root);

    } else {
        /* update the version */
        g_free(ac->personal_version);
        ac->personal_version = version;
        /* get the personal information */
        get_personal(ac, node);
        /* save the personal information */
        fetion_config_save_personal(ac, node);
    }


    /* contact list version */
    node    = xmlnode_find(root, "contact-list");
    version = xmlnode_prop(node, "version");

    if (g_strcmp0(version, ac->contact_list_version) == 0) {
        /* load from disk. */
        g_free(version);

        xmlnode *contact_root;
        xmlnode *contact_node;

        if (!(contact_root = fetion_config_load_buddies(ac))) {
            hybrid_debug_error("fetion", "invalid buddies.xml");
            xmlnode_free(root);
            return;
        }

        if (!(contact_node = xmlnode_find(contact_root, "contact-list"))) {
            hybrid_debug_error("fetion", "invalid buddies.xml");
            xmlnode_free(contact_root);
            xmlnode_free(root);
            return;
        }

        get_contact_list(ac, contact_node);
        xmlnode_free(contact_root);

    } else {

        /* the cache is out-of-data, drop it. */
        hybrid_account_clear_buddy(ac->account);

        /* update the version */
        g_free(ac->contact_list_version);
        ac->contact_list_version = version;
        /* get the contact list */
        get_contact_list(ac, node);
        /* save the contact list */
        fetion_config_save_buddies(ac, node);
    }


    /* custom config */
    node = xmlnode_find(root, "custom-config");
    version = xmlnode_prop(node, "version");

    if (g_strcmp0(version, ac->custom_config_version) != 0) {
        g_free(ac->custom_config);
        g_free(ac->custom_config_version);
        ac->custom_config = xmlnode_content(node);
        ac->custom_config_version = version;
    }

    xmlnode_free(root);

    /*
     * OK, now we need to save the account's version information, so
     * next time we can use it to register to sipc server.
     */
    fetion_config_save_account(ac);
}
Exemple #13
0
/**
 * Parse the configuration information. We will get:
 * sipc-proxy,get-url, servers-version, parameters-version,
 * and hints-version
 */
static gint
parse_configuration(fetion_account *ac, const gchar *cfg)
{
    xmlnode *node;
    xmlnode *root;
    gchar   *value;
    gchar   *version;
    gchar   *pos, *pos1;

    g_return_val_if_fail(cfg != NULL, 0);

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

    if (!root) {
        goto cfg_parse_err;
    }

    if ((node = xmlnode_find(root, "servers"))) {
        version = xmlnode_prop(node, "version");
        if (g_strcmp0(version, ac->cfg_server_version) != 0) {
            g_free(ac->cfg_server_version);
            ac->cfg_server_version = version;

            if (!(node = xmlnode_find(root, "sipc-proxy"))) {
                goto cfg_parse_err;
            }

            value = xmlnode_content(node);

            for (pos = value; *pos && *pos != ':'; pos ++ );

            if (*pos == '\0') {
                g_free(value);
                goto cfg_parse_err;
            }

            ac->sipc_proxy_ip = g_strndup(value, pos - value);
            ac->sipc_proxy_port = atoi(pos + 1);

            g_free(value);

            if (!(node = xmlnode_find(root, "get-uri"))) {
                goto cfg_parse_err;
            }

            value = xmlnode_content(node);

            for (pos1 = value; *pos1 && *pos1 != '/'; pos1 ++);
            if (*pos1 == '\0' || *(pos1 + 1) != '/') {
                goto cfg_parse_err;
            }

            pos1 += 2;

            for (pos = pos1; *pos && *pos != '/'; pos ++);
            if (*pos == '\0') {
                goto cfg_parse_err;
            }

            ac->portrait_host_name = g_strndup(pos1, pos - pos1);

            pos1 = pos + 1;

            for (pos = pos1; *pos && *pos != '/'; pos ++);
            if (*pos == '\0') {
                goto cfg_parse_err;
            }

            ac->portrait_host_path = g_strndup(pos1, pos - pos1);

        } else {
            g_free(version);
        }
    }

    if ((node = xmlnode_find(root, "parameters"))) {
        g_free(ac->cfg_param_version);
        ac->cfg_param_version = xmlnode_prop(node, "version");
    }

    if ((node = xmlnode_find(root, "hints"))) {
        g_free(ac->cfg_hint_version);
        ac->cfg_hint_version = xmlnode_prop(node, "version");
    }

    if ((node = xmlnode_find(root, "client"))) {
        g_free(ac->cfg_client_version);
        ac->cfg_client_version = xmlnode_prop(node, "version");
    }

    xmlnode_free(root);

    return HYBRID_OK;

cfg_parse_err:
    xmlnode_free(root);
    hybrid_debug_error("fetion", "parse cfg body");
    return HYBRID_ERROR;
}