gint xmpp_message_send(XmppStream *stream, const gchar *text, const gchar *to) { xmlnode *root; xmlnode *node; gchar *xml_string; g_return_val_if_fail(stream != NULL, HYBRID_ERROR); g_return_val_if_fail(text != NULL, HYBRID_ERROR); g_return_val_if_fail(to != NULL, HYBRID_ERROR); root = xmlnode_create("message"); xmlnode_new_prop(root, "from", stream->jid); xmlnode_new_prop(root, "to", to); xmlnode_new_prop(root, "type", "chat"); node = xmlnode_new_child(root, "body"); xmlnode_set_content(node, text); xml_string = xmlnode_to_string(root); xmlnode_free(root); hybrid_debug_info("xmpp", "send message to %s:\n%s", to, xml_string); if (hybrid_ssl_write(stream->ssl, xml_string, strlen(xml_string)) == -1) { hybrid_debug_error("xmpp", "send message to %s failed\n", to); g_free(xml_string); return HYBRID_ERROR; } g_free(xml_string); return HYBRID_OK; }
/** * Create the initiate stream string, we'll get: * * <stream:stream xmlns="jabber:client" * xmlns:stream="http://etherx.jabber.org/streams" * version="1.0" to="gmail.com"> */ static gchar* create_initiate_stream(XmppStream *stream) { xmlnode *node; gchar *version; gchar *res; node = xmlnode_create("stream:stream"); xmlnode_new_prop(node, "to", stream->account->to); xmlnode_new_namespace(node, NULL, "jabber:client"); xmlnode_new_namespace(node, "stream", "http://etherx.jabber.org/streams"); version = g_strdup_printf("%d.%d", stream->major_version, stream->miner_version); xmlnode_new_prop(node, "version", version); g_free(version); res = xmlnode_to_string(node); xmpp_strip_end_label(res); xmlnode_free(node); return res; }
gint hybrid_logs_write(HybridLogs *log, const gchar *name, const gchar *msg, gboolean sendout) { xmlnode *time_node; xmlnode *name_node; xmlnode *cont_node; xmlnode *node; time_t now; const gchar *body; struct tm *local_time; gchar time_str[128]; g_return_val_if_fail(log != NULL, HYBRID_ERROR); g_return_val_if_fail(name != NULL, HYBRID_ERROR); now = time(NULL); local_time = localtime(&now); /* log file doesn't exist, we create one. */ if (!log->root) { body = "<root></root>"; log->root = xmlnode_root(body, strlen(body)); } node = xmlnode_new_child(log->root, "m"); if (sendout) { xmlnode_new_prop(node, "type", "o"); } else { xmlnode_new_prop(node, "type", "i"); } time_node = xmlnode_new_child(node, "t"); memset(time_str, 0, sizeof(time_str)); strftime(time_str, sizeof(time_str) - 1, "%H:%M:%S", local_time); xmlnode_set_content(time_node, time_str); name_node = xmlnode_new_child(node, "n"); xmlnode_set_content(name_node, name); cont_node = xmlnode_new_child(node, "c"); xmlnode_set_content(cont_node, msg); xmlnode_save_file(log->root, log->log_path); return HYBRID_OK; }
gint xmpp_message_send_typing(XmppStream *stream, const gchar *to, HybridInputState state) { xmlnode *root; xmlnode *node; gchar *xml_string; g_return_val_if_fail(stream != NULL, HYBRID_ERROR); g_return_val_if_fail(to != NULL, HYBRID_ERROR); root = xmlnode_create("message"); xmlnode_new_prop(root, "from", stream->jid); xmlnode_new_prop(root, "to", to); xmlnode_new_prop(root, "type", "chat"); switch (state) { case INPUT_STATE_TYPING: node = xmlnode_new_child(root, "composing"); break; case INPUT_STATE_ACTIVE: node = xmlnode_new_child(root, "active"); break; case INPUT_STATE_PAUSED: node = xmlnode_new_child(root, "paused"); break; default: node = NULL; break; } if (node) { xmlnode_new_namespace(node, NULL, NS_CHANGESTATES); } xml_string = xmlnode_to_string(root); xmlnode_free(root); hybrid_debug_info("xmpp", "send message to %s:\n%s", to, xml_string); if (hybrid_ssl_write(stream->ssl, xml_string, strlen(xml_string)) == -1) { hybrid_debug_error("xmpp", "send message to %s failed\n", to); g_free(xml_string); return HYBRID_ERROR; } g_free(xml_string); return HYBRID_OK; }
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"); } }
/** * Request the roster from the server. */ static void xmpp_stream_get_roster(XmppStream *stream) { xmlnode *node; IqRequest *iq; g_return_if_fail(stream != NULL); xmpp_stream_iqid_increase(stream); iq = iq_request_create(stream, IQ_TYPE_GET); iq_request_set_callback(iq, request_roster_cb, NULL); node = xmlnode_new_child(iq->node, "query"); xmlnode_new_namespace(node, NULL, NS_IQ_ROSTER); #if 0 xmlnode_new_namespace(node, "gr", NS_GOOGLE_ROSTER); xmlnode_new_prop(node, "gr:ext", "2"); #endif if (iq_request_send(iq) != HYBRID_OK) { hybrid_account_error_reason( stream->account->account, "request roster error."); iq_request_destroy(iq); return; } iq_request_destroy(iq); }
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); }
static gchar* generate_handle_request_body(const gchar *sipuri, const gchar *userid, const gchar *alias, const gchar *groupid, gboolean accept) { xmlnode *root; xmlnode *node; gchar *res; root = xmlnode_create("args"); node = xmlnode_new_child(root, "contacts"); node = xmlnode_new_child(node, "buddies"); node = xmlnode_new_child(node, "buddy"); xmlnode_new_prop(node, "user-id", userid); xmlnode_new_prop(node, "uri", sipuri); xmlnode_new_prop(node, "result", accept ? "1": "0"); xmlnode_new_prop(node, "buddy-lists", groupid); xmlnode_new_prop(node, "expose-mobile-no", "1"); xmlnode_new_prop(node, "expose-name", "1"); xmlnode_new_prop(node, "local-name", alias); res = xmlnode_to_string(root); xmlnode_free(root); return res; }
/** * 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); }
static gchar* generate_subscribe_body(void) { xmlnode *root; xmlnode *node; gchar *body; gchar xml_raw[] = "<args></args>"; root = xmlnode_root(xml_raw, strlen(xml_raw)); node = xmlnode_new_child(root, "subscription"); xmlnode_new_prop(node, "self", "v4default;mail-count"); xmlnode_new_prop(node, "buddy", "v4default"); xmlnode_new_prop(node, "version", "0"); body = xmlnode_to_string(root); xmlnode_free(root); return body; }
static gchar* generate_rename_buddy_body(const gchar *userid, const gchar *name) { const gchar *body; xmlnode *root; xmlnode *node; gchar *res; body = "<args></args>"; root = xmlnode_root(body, strlen(body)); node = xmlnode_new_child(root, "contacts"); node = xmlnode_new_child(node, "contact"); xmlnode_new_prop(node, "user-id", userid); xmlnode_new_prop(node, "local-name", name); res = xmlnode_to_string(root); xmlnode_free(root); return res; }
/** * Generate the xml body of the cfg-downloading request. We will get * the following output: * * <config> * <user mobile-no="152********"/> * <client type="PC" version="4.3.0980" platform="W5.1"/> * <servers version="0"/> * <parameters version="0"/> * <hints version="0"/> * </config> */ static gchar* generate_configuration_body(fetion_account *ac) { xmlnode *root; xmlnode *node; gchar root_node[] = "<config></config>"; gchar *res; g_return_val_if_fail(ac != NULL, NULL); root = xmlnode_root(root_node, strlen(root_node)); node = xmlnode_new_child(root, "user"); if (ac->mobileno && *(ac->mobileno) != '\0') { xmlnode_new_prop(node, "mobile-no", ac->mobileno); } else { xmlnode_new_prop(node, "sid", ac->sid); } node = xmlnode_new_child(root, "client"); xmlnode_new_prop(node, "type", "HYBRID"); xmlnode_new_prop(node, "version", PROTO_VERSION); xmlnode_new_prop(node, "platform", "W5.1"); node = xmlnode_new_child(root, "servers"); xmlnode_new_prop(node, "version", ac->cfg_server_version); node = xmlnode_new_child(root, "parameters"); xmlnode_new_prop(node, "version", ac->cfg_param_version); node = xmlnode_new_child(root, "hints"); xmlnode_new_prop(node, "version", ac->cfg_hint_version); res = xmlnode_to_string(root); xmlnode_free(root); return res; }
static gchar* generate_get_info_body(const gchar *userid) { xmlnode *root; xmlnode *node; gchar *res; gchar body[] = "<args></args>"; root = xmlnode_root(body, strlen(body)); node = xmlnode_new_child(root, "contact"); xmlnode_new_prop(node, "user-id", userid); res = xmlnode_to_string(root); xmlnode_free(root); return res; }
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); }
static gchar* generate_buddy_add_body(const gchar *no, const gchar *groupid, const gchar *localname, const gchar *desc) { const gchar *body; gchar *sipuri; xmlnode *root; xmlnode *node; gchar *res; body = "<args></args>"; root = xmlnode_root(body, strlen(body)); node = xmlnode_new_child(root, "contacts"); node = xmlnode_new_child(node, "buddies"); node = xmlnode_new_child(node, "buddy"); if (strlen(no) < 11) { sipuri = g_strdup_printf("sip:%s", no); } else { sipuri = g_strdup_printf("tel:%s", no); } xmlnode_new_prop(node, "uri", sipuri); xmlnode_new_prop(node, "local-name", localname); xmlnode_new_prop(node, "buddy-lists", groupid); xmlnode_new_prop(node, "desc", desc); xmlnode_new_prop(node, "expose-mobile-no", "1"); xmlnode_new_prop(node, "expose-name", "1"); xmlnode_new_prop(node, "addbuddy-phrase-id", "0"); g_free(sipuri); res = xmlnode_to_string(root); xmlnode_free(root); return res; }
static gchar* generate_invite_buddy_body(const gchar *sipuri) { const gchar *body; xmlnode *root; xmlnode *node; gchar *res; g_return_val_if_fail(sipuri != NULL, NULL); body = "<args></args>"; root = xmlnode_root(body, strlen(body)); node = xmlnode_new_child(root, "contacts"); node = xmlnode_new_child(node, "contact"); xmlnode_new_prop(node, "uri", sipuri); res = xmlnode_to_string(root); xmlnode_free(root); return res; }
gint hybrid_logs_write(HybridLogs *log, const gchar *name, const gchar *msg, gboolean sendout) { xmlnode *head_node; xmlnode *body_node; xmlnode *time_node; xmlnode *font_node; xmlnode *name_node; xmlnode *cont_node; xmlnode *node; time_t now; const gchar *body; gchar *title; gchar *content; struct tm *local_time; gchar time_str[128]; g_return_val_if_fail(log != NULL, HYBRID_ERROR); g_return_val_if_fail(name != NULL, HYBRID_ERROR); now = time(NULL); local_time = localtime(&now); /* log file doesn't exist, we create one. */ if (!log->root) { body = "<html></html>"; title = g_strdup_printf(_("Conversation with %s (%s) at %d-%d-%d"), name, log->id, local_time->tm_year + 1900, local_time->tm_mon, local_time->tm_mday); log->root = xmlnode_root(body, strlen(body)); head_node = xmlnode_new_child(log->root, "head"); node = xmlnode_new_child(head_node, "meta"); xmlnode_new_prop(node, "http-equiv", "content-type"); xmlnode_new_prop(node, "content", "text/html; charset=UTF-8"); node = xmlnode_new_child(head_node, "title"); xmlnode_set_content(node, title); node = xmlnode_new_child(log->root, "body"); node = xmlnode_new_child(node, "h3"); xmlnode_set_content(node, title); g_free(title); } if (!(body_node = xmlnode_find(log->root, "body"))) { hybrid_debug_error("logs", "invalid log file."); g_free(title); return HYBRID_ERROR; } node = xmlnode_new_child(body_node, "span"); font_node = xmlnode_new_child(node, "font"); if (sendout) { xmlnode_new_prop(font_node, "color", "#16569E"); } else { xmlnode_new_prop(font_node, "color", "#A82F2F"); } time_node = xmlnode_new_child(font_node, "font"); xmlnode_new_prop(time_node, "size", "2"); memset(time_str, 0, sizeof(time_str)); strftime(time_str, sizeof(time_str) - 1, "(%H:%M:%S) ", local_time); xmlnode_set_content(time_node, time_str); content = g_strdup_printf("%s: ", name); name_node = xmlnode_new_child(font_node, "b"); xmlnode_set_content(name_node, content); g_free(content); cont_node = xmlnode_new_child(node, "font"); xmlnode_set_content(cont_node, msg); xmlnode_new_child(node, "br"); xmlnode_save_file(log->root, log->log_path); return HYBRID_OK; }
/** * Start sasl authentication. */ static void xmpp_stream_startsasl(XmppStream *stream) { guchar *auth; gchar *auth_encoded; gchar *xml_string; gint username_len; gint password_len; xmlnode *node; g_return_if_fail(stream != NULL); hybrid_debug_info("xmpp", "start sasl authentication."); hybrid_account_set_connection_string(stream->account->account, "Start sasl authentication."); xmpp_stream_set_state(stream, XMPP_STATE_SASL_AUTHENTICATING); /* * construct the authentication string to be base64 encoded, * which is in form of '\0 + username + \0 + password ' */ username_len = strlen(stream->account->username); password_len = strlen(stream->account->password); auth = g_malloc0(username_len + password_len + 2); auth[0] = '\0'; memcpy(auth + 1, stream->account->username, username_len); auth[username_len + 1] = '\0'; memcpy(auth + 2 + username_len, stream->account->password, password_len); auth_encoded = hybrid_base64_encode(auth, username_len + password_len + 2); g_free(auth); /* construct the xml string, which is in form of: * * <auth xmlns="urn:ietf:params:xml:ns:xmpp-sasl" * mechanism="PLAIN">encoded sasl string</auth> */ node = xmlnode_create("auth"); xmlnode_new_namespace(node, NULL, NS_XMPP_SASL); xmlnode_new_namespace(node, "ga", "http://www.google.com/talk/protocol/auth"); xmlnode_new_prop(node, "ga:client-uses-full-bind-result", "true"); xmlnode_new_prop(node, "mechanism", "PLAIN"); xmlnode_set_content(node, auth_encoded); g_free(auth_encoded); xml_string = xmlnode_to_string(node); xmlnode_free(node); hybrid_debug_info("xmpp", "sasl send:\n%s", xml_string); if (hybrid_ssl_write(stream->ssl, xml_string, strlen(xml_string)) == -1) { hybrid_account_error_reason(stream->account->account, "SASL authentication error."); return; } g_free(xml_string); }
/** * Generate the sipc authentication request message body. */ static gchar* generate_auth_body(fetion_account *ac) { gchar root_raw[] = "<args></args>"; xmlnode *node; xmlnode *subnode; gchar *res; xmlnode *root = xmlnode_root(root_raw, strlen(root_raw)); node = xmlnode_new_child(root, "device"); xmlnode_new_prop(node, "machine-code", "001676C0E351"); node = xmlnode_new_child(root, "caps"); xmlnode_new_prop(node, "value", "1ff"); node = xmlnode_new_child(root, "events"); xmlnode_new_prop(node, "value", "7f"); node = xmlnode_new_child(root, "user-info"); xmlnode_new_prop(node, "mobile-no", ac->mobileno); xmlnode_new_prop(node, "user-id", ac->userid); subnode = xmlnode_new_child(node, "personal"); xmlnode_new_prop(subnode, "version", ac->personal_version); xmlnode_new_prop(subnode, "attributes", "v4default"); subnode = xmlnode_new_child(node, "custom-config"); xmlnode_new_prop(subnode, "version", ac->custom_config_version); subnode = xmlnode_new_child(node, "contact-list"); xmlnode_new_prop(subnode, "version", ac->contact_list_version); xmlnode_new_prop(subnode, "buddy-attributes", "v4default"); node = xmlnode_new_child(root, "presence"); subnode = xmlnode_new_child(node, "basic"); xmlnode_new_prop(subnode, "value", "0"); xmlnode_new_prop(subnode, "desc", ""); res = xmlnode_to_string(root); xmlnode_free(root); return res; }