/** Convert XML to something based on MSIM_XMLNODE_CONVERT. */ static gchar * msim_convert_xml(MsimSession *session, const gchar *raw, MSIM_XMLNODE_CONVERT f) { xmlnode *root; GString *str; gchar *enclosed_raw; g_return_val_if_fail(raw != NULL, NULL); /* Enclose text in one root tag, to try to make it valid XML for parsing. */ enclosed_raw = g_strconcat("<root>", raw, "</root>", NULL); root = xmlnode_from_str(enclosed_raw, -1); if (!root) { purple_debug_warning("msim", "msim_markup_to_html: couldn't parse " "%s as XML, returning raw: %s\n", enclosed_raw, raw); /* TODO: msim_unrecognized */ g_free(enclosed_raw); return g_strdup(raw); } g_free(enclosed_raw); str = g_string_new(NULL); msim_convert_xmlnode(session, str, root, f, 0); xmlnode_free(root); purple_debug_info("msim", "msim_markup_to_html: returning %s\n", str->str); return g_string_free(str, FALSE); }
static void shinima_message_links_foreach(gchar **message, void(*foreach_func)(xmlnode*, const gchar*, gchar**, gboolean*, gpointer), gboolean *_changed, gpointer *user_data) { xmlnode *root, *a; gboolean *changed = (_changed != NULL) ? changed : g_malloc(sizeof(gboolean)); g_return_if_fail(foreach_func != NULL); root = xmlnode_from_str(*message, -1); for(a=xmlnode_get_child(root, "a"); a; a=xmlnode_get_next_twin(a)) { const gchar *href = xmlnode_get_attrib(a, "href"); if(href) foreach_func(a, href, message, changed, user_data); } if(changed) { g_free(*message); *message = xmlnode_to_str(root, NULL); } if(_changed == NULL) g_free(changed); xmlnode_free(root); }
xmlnode* coincoin_xmlparse(gchar* response, gsize len) { gchar* utf8 = strutf8(response, len); xmlnode* node = xmlnode_from_str(utf8, len); g_free(utf8); return node; }
static char* format_message(char *sender, char *message) { GString* format_message = g_string_new(""); xmlnode* message_node = xmlnode_from_str(message, -1); /* raw */ if ( !message_node || !( strcmp(message_node->name, "html")==0 || strcmp(message_node->name, "body")==0 )) { g_string_printf(format_message, "%s: %s", sender, message); return g_string_free(format_message, FALSE); } xmlnode* body_node = (strcmp(message_node->name, "body")) ? xmlnode_get_child(message_node, "body") : message_node; char* message_content = xmlnode_get_content(body_node); g_string_printf(format_message, "%s: %s", sender, message_content); g_free(message_content); xmlnode_free(message_node); return g_string_free(format_message, FALSE); }
/* Post to get the OIM Metadata */ static void msn_oim_get_metadata(MsnOim *oim) { msn_oim_make_request(oim, FALSE, MSN_OIM_GET_METADATA_ACTION, MSN_OIM_RETRIEVE_HOST, MSN_OIM_RETRIEVE_URL, xmlnode_from_str(MSN_OIM_GET_METADATA_TEMPLATE, -1), msn_oim_get_metadata_cb, oim); }
static gchar *twitter_xml_text_parse_error(const gchar * response) { xmlnode *response_node; if (response && (response_node = xmlnode_from_str(response, strlen(response)))) { gchar *message = twitter_xml_node_parse_error(response_node); xmlnode_free(response_node); return message; } return NULL; }
void twitter_send_request_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *server_error_message) { TwitterSendRequestData *request_data = user_data; const gchar *error_message = NULL; gchar *error_node_text = NULL; xmlnode *response_node = NULL; TwitterRequestErrorType error_type = TWITTER_REQUEST_ERROR_NONE; purple_debug_info("twitter", "Response: %s\n", url_text); if (server_error_message) { error_type = TWITTER_REQUEST_ERROR_SERVER; error_message = server_error_message; } else { response_node = xmlnode_from_str(url_text, len); if (!response_node) { error_type = TWITTER_REQUEST_ERROR_INVALID_XML; error_message = url_text; } else { xmlnode *error_node; if ((error_node = xmlnode_get_child(response_node, "error")) != NULL) { error_type = TWITTER_REQUEST_ERROR_TWITTER_GENERAL; error_node_text = xmlnode_get_data(error_node); error_message = error_node_text; } } } if (error_type != TWITTER_REQUEST_ERROR_NONE) { TwitterRequestErrorData *error_data = g_new0(TwitterRequestErrorData, 1); error_data->type = error_type; error_data->message = error_message; //error_data->response_node = response_node; if (request_data->error_func) request_data->error_func(request_data->account, error_data, request_data->user_data); g_free(error_data); } else { if (request_data->success_func) request_data->success_func(request_data->account, response_node, request_data->user_data); } if (response_node != NULL) xmlnode_free(response_node); if (error_node_text != NULL) g_free(error_node_text); g_free(request_data); }
static void entry_changed_cb(GtkTextBuffer *buffer, void *data) { char *xmlstr, *str; GtkTextIter iter; int wrapped_lines; int lines; GdkRectangle oneline; int height; int pad_top, pad_inside, pad_bottom; GtkTextIter start, end; xmlnode *node; wrapped_lines = 1; gtk_text_buffer_get_start_iter(buffer, &iter); gtk_text_view_get_iter_location(GTK_TEXT_VIEW(console->entry), &iter, &oneline); while (gtk_text_view_forward_display_line(GTK_TEXT_VIEW(console->entry), &iter)) wrapped_lines++; lines = gtk_text_buffer_get_line_count(buffer); /* Show a maximum of 64 lines */ lines = MIN(lines, 6); wrapped_lines = MIN(wrapped_lines, 6); pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(console->entry)); pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(console->entry)); pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(console->entry)); height = (oneline.height + pad_top + pad_bottom) * lines; height += (oneline.height + pad_inside) * (wrapped_lines - lines); gtk_widget_set_size_request(console->sw, -1, height + 6); gtk_text_buffer_get_start_iter(buffer, &start); gtk_text_buffer_get_end_iter(buffer, &end); str = gtk_text_buffer_get_text(buffer, &start, &end, FALSE); if (!str) return; xmlstr = g_strdup_printf("<xml>%s</xml>", str); node = xmlnode_from_str(xmlstr, -1); if (node) { gtk_imhtml_clear_formatting(GTK_IMHTML(console->entry)); } else { gtk_imhtml_toggle_background(GTK_IMHTML(console->entry), "#ffcece"); } g_free(str); g_free(xmlstr); if (node) xmlnode_free(node); }
gboolean AddBuddy_cb(struct fetion_account_data *sip, struct sipmsg *msg, struct transaction *tc) { xmlnode *root,*item; const gchar *uri, *name ,*group_id; struct group_attr *g_attr; gchar *buddy_name; PurpleBuddy *b; PurpleGroup *g = NULL; struct fetion_buddy *bs; if(msg->response != 522) { root = xmlnode_from_str(msg->body, msg->bodylen); item = xmlnode_get_child(root,"contacts/buddies/buddy"); g_return_val_if_fail(item!=NULL,FALSE); uri = xmlnode_get_attrib(item, "uri"); name = xmlnode_get_attrib(item, "local-name"); group_id = xmlnode_get_attrib(item, "buddy-lists"); buddy_name = g_strdup_printf("%s", uri); g_attr = g_hash_table_lookup(sip->group,group_id); if(g_attr==NULL) { g = purple_find_group("未分组"); if(!g) g = purple_group_new("未分组"); } else { g = purple_find_group(g_attr->name); if(!g) g = purple_group_new(g_attr->name); } b = purple_find_buddy(sip->account, buddy_name); if(!b){ b = purple_buddy_new(sip->account, buddy_name, NULL); } g_free(buddy_name); purple_blist_add_buddy(b, NULL, g, NULL); if(name!=NULL && *name!='\0') purple_blist_alias_buddy(b, name); bs = g_new0(struct fetion_buddy, 1); bs->name = g_strdup(b->name); g_hash_table_insert(sip->buddies, bs->name, bs); fetion_subscribe_exp(sip,bs); }
/*when connect, do the SOAP Style windows Live ID authentication */ void msn_nexus_connect(MsnNexus *nexus) { MsnSession *session = nexus->session; const char *username; const char *password; char *password_xml; GString *domains; char *request; int i; MsnSoapMessage *soap; purple_debug_info("msn", "Starting Windows Live ID authentication\n"); msn_session_set_login_step(session, MSN_LOGIN_STEP_GET_COOKIE); username = purple_account_get_username(session->account); password = purple_connection_get_password(session->account->gc); if (g_utf8_strlen(password, -1) > 16) { /* max byte size for 16 utf8 characters is 64 + 1 for the null */ gchar truncated[65]; g_utf8_strncpy(truncated, password, 16); password_xml = g_markup_escape_text(truncated, -1); } else { password_xml = g_markup_escape_text(password, -1); } purple_debug_info("msn", "Logging on %s, with policy '%s', nonce '%s'\n", username, nexus->policy, nexus->nonce); domains = g_string_new(NULL); for (i = 0; i < nexus->token_len; i++) { g_string_append_printf(domains, MSN_SSO_RST_TEMPLATE, i+1, ticket_domains[i][SSO_VALID_TICKET_DOMAIN], ticket_domains[i][SSO_VALID_TICKET_POLICY] != NULL ? ticket_domains[i][SSO_VALID_TICKET_POLICY] : nexus->policy); } request = g_strdup_printf(MSN_SSO_TEMPLATE, username, password_xml, domains->str); g_free(password_xml); g_string_free(domains, TRUE); soap = msn_soap_message_new(NULL, xmlnode_from_str(request, -1)); g_free(request); msn_soap_message_send(session, soap, MSN_SSO_SERVER, SSO_POST_URL, TRUE, nexus_got_response_cb, nexus); }
/*Post to get the Offline Instant Message*/ static void msn_oim_post_single_get_msg(MsnOim *oim, MsnOimRecvData *data) { char *soap_body; purple_debug_info("msn", "Get single OIM Message\n"); soap_body = g_strdup_printf(MSN_OIM_GET_TEMPLATE, data->msg_id); msn_oim_make_request(oim, FALSE, MSN_OIM_GET_SOAP_ACTION, MSN_OIM_RETRIEVE_HOST, MSN_OIM_RETRIEVE_URL, xmlnode_from_str(soap_body, -1), msn_oim_get_read_cb, data); g_free(soap_body); }
/* parse the oim XML data * and post it to the soap server to get the Offline Message * */ void msn_parse_oim_msg(MsnOim *oim,const char *xmlmsg) { xmlnode *node; purple_debug_info("msn", "%s\n", xmlmsg); if (!strcmp(xmlmsg, "too-large")) { /* Too many OIM's to send via NS, so we need to request them via SOAP. */ msn_oim_get_metadata(oim); } else { node = xmlnode_from_str(xmlmsg, -1); msn_parse_oim_xml(oim, node); xmlnode_free(node); } }
/*Post to get the Offline Instant Message*/ static void msn_oim_post_delete_msg(MsnOimRecvData *rdata) { MsnOim *oim = rdata->oim; char *msgid = rdata->msg_id; char *soap_body; purple_debug_info("msn", "Delete single OIM Message {%s}\n",msgid); soap_body = g_strdup_printf(MSN_OIM_DEL_TEMPLATE, msgid); msn_oim_make_request(oim, FALSE, MSN_OIM_DEL_SOAP_ACTION, MSN_OIM_RETRIEVE_HOST, MSN_OIM_RETRIEVE_URL, xmlnode_from_str(soap_body, -1), msn_oim_delete_read_cb, rdata); g_free(soap_body); }
static void lastfm_ws_fetch(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message) { trace("Fetched %d bytes of data %s", len, error_message ? error_message : ""); if (url_text) { trace("%s", url_text); xmlnode *response = xmlnode_from_str(url_text, -1); if (response) { xmlnode *recenttracks = xmlnode_get_child(response, "recenttracks"); if (recenttracks) { xmlnode *track = xmlnode_get_child(recenttracks, "track"); if (track) { const char *nowplaying = xmlnode_get_attrib(track, "nowplaying"); data_from_node(track, "name", lastfm_ws_ti.track); data_from_node(track, "album", lastfm_ws_ti.album); data_from_node(track, "artist", lastfm_ws_ti.artist); if (nowplaying) { lastfm_ws_ti.status = PLAYER_STATUS_PLAYING; } else { lastfm_ws_ti.status = PLAYER_STATUS_STOPPED; } lastfm_ws_ti.player = "Last.fm"; } } xmlnode_free(response); } else { trace("Last.fm response was badly formed XML"); } } }
static void twitter_xml_request_success_cb(TwitterRequestor * r, const gchar * response, gpointer user_data) { TwitterSendXmlRequestData *request_data = user_data; const gchar *error_message = NULL; gchar *error_node_text = NULL; xmlnode *response_node = NULL; TwitterRequestErrorType error_type = TWITTER_REQUEST_ERROR_NONE; response_node = xmlnode_from_str(response, strlen(response)); if (!response_node) { purple_debug_error(purple_account_get_protocol_id(r->account), "Response error: invalid xml\n"); error_type = TWITTER_REQUEST_ERROR_INVALID_XML; error_message = response; } else { if ((error_message = twitter_xml_node_parse_error(response_node))) { error_type = TWITTER_REQUEST_ERROR_TWITTER_GENERAL; error_message = error_node_text; purple_debug_error(purple_account_get_protocol_id(r->account), "Response error: Twitter error %s\n", error_message); } } if (error_type != TWITTER_REQUEST_ERROR_NONE) { /* Turns out this wasn't really a success. We got a twitter error instead of an HTTP error * So go through the error cycle */ TwitterRequestErrorData *error_data = g_new0(TwitterRequestErrorData, 1); error_data->type = error_type; error_data->message = error_message; twitter_requestor_on_error(r, error_data, request_data->error_func, request_data->user_data); g_free(error_data); } else { purple_debug_info(purple_account_get_protocol_id(r->account), "Valid response, calling success func\n"); if (request_data->success_func) request_data->success_func(r, response_node, request_data->user_data); } if (response_node != NULL) xmlnode_free(response_node); if (error_node_text != NULL) g_free(error_node_text); g_free(request_data); }
/*post send single message request to oim server*/ void msn_oim_send_msg(MsnOim *oim) { MsnOimSendReq *oim_request; char *soap_body; char *msg_body; g_return_if_fail(oim != NULL); oim_request = g_queue_peek_head(oim->send_queue); g_return_if_fail(oim_request != NULL); purple_debug_info("msn", "Sending OIM: %s\n", oim_request->oim_msg); /* if we got the challenge lock key, we compute it * else we go for the SOAP fault and resend it. */ if (oim->challenge == NULL){ purple_debug_info("msn", "No lock key challenge, waiting for SOAP Fault and Resend\n"); } msg_body = msn_oim_msg_to_str(oim, oim_request->oim_msg); soap_body = g_strdup_printf(MSN_OIM_SEND_TEMPLATE, oim_request->from_member, oim_request->friendname, oim_request->to_member, MSNP15_WLM_PRODUCT_ID, oim->challenge ? oim->challenge : "", oim->send_seq, msg_body); msn_oim_make_request(oim, TRUE, MSN_OIM_SEND_SOAP_ACTION, MSN_OIM_SEND_HOST, MSN_OIM_SEND_URL, xmlnode_from_str(soap_body, -1), msn_oim_send_read_cb, oim); /*increase the offline Sequence control*/ if (oim->challenge != NULL) { oim->send_seq++; } g_free(msg_body); g_free(soap_body); }
static void xmlnode_sent_cb(PurpleConnection *gc, char **packet, gpointer null) { char *str; char *formatted; xmlnode *node; if (!console || console->gc != gc) return; node = xmlnode_from_str(*packet, -1); if (!node) return; str = xmlnode_to_pretty_str(node, NULL, 0); formatted = g_strdup_printf("<body bgcolor='#dcecc4'><pre>%s</pre></body>", str); gtk_imhtml_append_text(GTK_IMHTML(console->imhtml), formatted, 0); g_free(formatted); g_free(str); xmlnode_free(node); }
void GetBuddyInfo_cb(struct fetion_account_data *sip, struct sipmsg *msg, struct transaction *tc) { xmlnode *root, *son, *item; const gchar *uri, *name; const gchar *nickname, *gender; const gchar *impresa, *birthday; PurpleNotifyUserInfo *user_info; purple_debug_info("fetion:", "GetBuddyInfo_cb[%s]", msg->body); root = xmlnode_from_str(msg->body, msg->bodylen); item = xmlnode_get_child(root, "contacts/contact"); g_return_if_fail(item != NULL); uri = xmlnode_get_attrib(item, "uri"); item = xmlnode_get_child(item, "personal"); g_return_if_fail(item != NULL); nickname = xmlnode_get_attrib(item, "nickname"); impresa = xmlnode_get_attrib(item, "impresa"); gender = xmlnode_get_attrib(item, "gender"); purple_debug(PURPLE_DEBUG_MISC, "fetion", "get info \n"); user_info = purple_notify_user_info_new(); purple_notify_user_info_add_pair(user_info, "昵称", nickname); //purple_notify_user_info_add_pair(user_info,"手机号码",mobileno); //purple_notify_user_info_add_pair(user_info,"飞信号码",uri); //purple_notify_user_info_add_section_header(user_info, _("General")); if ((gender != NULL) && (gender[0] == '1')) purple_notify_user_info_add_pair(user_info, "性别", "男"); else purple_notify_user_info_add_pair(user_info, "性别", "女"); purple_notify_user_info_add_pair(user_info, "心情短语", impresa); purple_notify_userinfo(sip->gc, uri, user_info, NULL, NULL); purple_notify_user_info_destroy(user_info); xmlnode_free(root); }
static void http_received_cb(const char *data, int len, PurpleBOSHConnection *conn) { if (conn->failed_connections) /* We've got some data, so reset the number of failed connections */ conn->failed_connections = 0; if (conn->receive_cb) { xmlnode *node = xmlnode_from_str(data, len); purple_debug_info("jabber", "RecvBOSH %s(%d): %s\n", conn->ssl ? "(ssl)" : "", len, data); if (node) { conn->receive_cb(conn, node); xmlnode_free(node); } else { purple_debug_warning("jabber", "BOSH: Received invalid XML\n"); } } else { g_return_if_reached(); } }
void RetriveSysCfg_cb(gpointer sodata, gint source, const gchar * error_message) { gchar buf[10240]; gchar *cur, *tail; gchar *msg_server, *ssic_server, *por_server, *upload_server; gchar *cfg_size = NULL; gchar *cfg_filename = NULL; struct fetion_account_data *sip = sodata; gint len, rcv_len; xmlnode *root, *son_node, *item; memset(buf, 0, 10240); rcv_len = read(source, buf, 10240); if (rcv_len > 0) { if ((cur = strstr(buf, "\r\n\r\n"))) { if (strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) != 0) purple_connection_error_reason(sip->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _ ("Invalid Password or Mobileno")); cfg_size = get_token(buf, "Content-Length: ", "\r\n"); if (cfg_size == NULL) return; cur += 4; sip->SysCfg.size = atoi(cfg_size); sip->SysCfg.buf = g_malloc(sip->SysCfg.size); len = rcv_len - (cur - buf); sip->SysCfg.rcv_len = len; memcpy((sip->SysCfg.buf), cur, len); } else { cur = sip->SysCfg.buf + sip->SysCfg.rcv_len; if ((sip->SysCfg.rcv_len) + rcv_len > (sip->SysCfg.size)) memcpy(cur, buf, (sip->SysCfg.size) - (sip->SysCfg.rcv_len)); else memcpy(cur, buf, rcv_len); sip->SysCfg.rcv_len += rcv_len; } } else { purple_input_remove(sip->SysCfg.inpa); if (sip->mobileno != NULL) cfg_filename = g_strdup_printf("%s-SysCfg.xml", sip->mobileno); else if (sip->username != NULL) cfg_filename = g_strdup_printf("%s-SysCfg.xml", sip->username); else cfg_filename = g_strdup_printf("SysCfg.xml"); root = xmlnode_from_str(sip->SysCfg.buf, sip->SysCfg.size); g_return_if_fail(root != NULL); son_node = xmlnode_get_child(root, "servers"); if (son_node == NULL) { LoginToSsiPortal(sip); //fixme return; } purple_debug_info("fetion", "systemconfig:after servers[%s]", sip->SysCfg.buf); item = xmlnode_get_child(son_node, "sipc-proxy"); g_return_if_fail(item != NULL); msg_server = g_strdup(xmlnode_get_data(item)); item = xmlnode_get_child(son_node, "ssi-app-sign-in"); g_return_if_fail(item != NULL); ssic_server = g_strdup(xmlnode_get_data(item)); item = xmlnode_get_child(root, "http-applications/get-portrait"); g_return_if_fail(item != NULL); por_server = g_strdup(xmlnode_get_data(item)); item = xmlnode_get_child(root, "http-applications/set-portrait"); g_return_if_fail(item != NULL); upload_server = g_strdup(xmlnode_get_data(item)); cur = strstr(msg_server, ":"); *cur = '\0'; cur++; sip->MsgServer = g_strdup(msg_server); sip->MsgPort = atoi(cur); cur = strstr(ssic_server, "/ssiportal"); *cur = '\0'; cur = ssic_server + 8; sip->SsicServer = g_strdup(cur); cur = strstr(por_server, "/HDS"); *cur = '\0'; tail = cur + 1; cur = por_server + 7; sip->PortraitServer = g_strdup(cur); cur = strstr(por_server, "/"); *cur = '\0'; sip->PortraitPrefix = g_strdup(tail); cur = strstr(upload_server, "/HDS"); *cur = '\0'; tail = cur + 1; cur = upload_server + 7; sip->UploadServer = g_strdup(cur); cur = strstr(upload_server, "/"); *cur = '\0'; sip->UploadPrefix = g_strdup(tail); LoginToSsiPortal(sip); purple_util_write_data_to_file(cfg_filename, sip->SysCfg.buf, sip->SysCfg.size); g_free(msg_server); g_free(ssic_server); g_free(por_server); g_free(upload_server); } }
gboolean read_cookie(gpointer sodata, PurpleSslConnection * source, gint con) { gchar buf[10240]; gchar *cur = NULL; gchar *end = NULL; const gchar *uri = NULL; xmlnode *isc, *item; gint len, rcv_len; PurpleSslConnection *gsc; struct fetion_account_data *sip; sip = sodata; purple_debug_info("fetion:", "read cookie\n"); gsc = (PurpleSslConnection *) source; rcv_len = purple_ssl_read(gsc, buf, 10240); if (rcv_len > 0) { buf[rcv_len] = '\0'; purple_debug_info("fetion:", "read_cookie:%s\n", buf); cur = strstr(buf, "Cookie: ssic="); if (cur != NULL) { cur += 13; end = strstr(cur, ";"); sip->ssic = g_strndup(cur, end - cur); purple_debug_info("fetion:", "read_cookie:[%s]\n", sip->ssic); // end=purple_url_encode(sip->ssic); // purple_debug_info("fetion:","read_cookie:[%s]\n",end); } if ((cur = strstr(buf, "\r\n\r\n"))) { if (((strncmp(buf, "HTTP/1.1 200 OK\r\n", 17) != 0) && (strncmp(buf, "HTTP/1.1 100 Continue\r\n", 23) != 0))) { purple_connection_error_reason(sip->gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _ ("Invalid Password or Mobileno")); return FALSE; } cur += 4; len = strlen(cur); isc = xmlnode_from_str(cur, len); g_return_val_if_fail(isc != NULL, FALSE); item = xmlnode_get_child(isc, "user"); g_return_val_if_fail(item != NULL, FALSE); uri = xmlnode_get_attrib(item, "uri"); g_return_val_if_fail(uri != NULL, FALSE); sip->uri = g_strdup(uri); cur = strstr(uri, "@"); g_return_val_if_fail(cur != NULL, FALSE); *cur = '\0'; sip->username = g_strdup_printf("%s", uri + 4); purple_debug_info("fetion:", "cookie[%s]\n", sip->username); purple_timeout_remove(sip->registertimeout); srvresolved(sip); xmlnode_free(isc); purple_ssl_close(gsc); return TRUE; } } purple_ssl_close(gsc); return FALSE; }
gboolean GetContactList_cb(struct fetion_account_data *sip, struct sipmsg *msg, struct transaction *tc) { xmlnode *item, *group, *isc; const gchar *name_group, *group_id; PurpleBuddy *b; PurpleGroup *g = NULL; struct fetion_buddy *bs; struct group_attr *g_attr; gint len = msg->bodylen; purple_debug(PURPLE_DEBUG_MISC, "fetion", "in process GetContactList response response: %d\n", msg->response); switch (msg->response) { case 200: /*Convert the contact from XML to Purple Buddies */ isc = xmlnode_from_str(msg->body, len); purple_debug_info("fetion:", "after xmlnode to str\n"); group = xmlnode_get_child(isc, "contacts/buddy-lists"); g_return_val_if_fail(group != NULL, FALSE); /* ToDo. Find for all groups */ sip->GetContactFlag = 1; for ((group = xmlnode_get_child(group, "buddy-list")); group; group = xmlnode_get_next_twin(group)) { purple_debug_info("fetion:", "buddy-list\n"); name_group = xmlnode_get_attrib(group, "name"); group_id = xmlnode_get_attrib(group, "id"); g_return_val_if_fail(name_group != NULL, FALSE); purple_debug_info("fetion", "name_group->%s\n", name_group); g = purple_find_group(name_group); if (!g) { g = purple_group_new(name_group); } g_attr = g_new0(struct group_attr, 1); g_attr->name = g_strdup(name_group); g_attr->id = g_strdup(group_id); g_hash_table_insert(sip->group, g_attr->id, g_attr); g_hash_table_insert(sip->group2id, g_attr->name, g_attr); } group = xmlnode_get_child(isc, "contacts/buddies"); g_return_val_if_fail(group != NULL, FALSE); for (item = xmlnode_get_child(group, "buddy"); item; item = xmlnode_get_next_twin(item)) { const gchar *uri, *name; char *buddy_name; const gchar *g_id; uri = xmlnode_get_attrib(item, "uri"); name = xmlnode_get_attrib(item, "local-name"); g_id = xmlnode_get_attrib(item, "buddy-lists"); buddy_name = g_strdup_printf("%s", uri); if ((g_id == NULL) || (*g_id == '\0') || strlen(g_id) > 1) { g = purple_find_group("未分组"); if (!g) g = purple_group_new("未分组"); } else { g_attr = g_hash_table_lookup(sip->group, g_id); g_return_val_if_fail(g_attr != NULL, FALSE); g = purple_find_group(g_attr->name); if (!g) g = purple_group_new(g_attr->name); } b = purple_find_buddy(sip->account, buddy_name); if (!b) { b = purple_buddy_new(sip->account, buddy_name, NULL); } g_free(buddy_name); purple_blist_add_buddy(b, NULL, g, NULL); if (name != NULL && *name != '\0') purple_blist_alias_buddy(b, name); bs = g_new0(struct fetion_buddy, 1); bs->name = g_strdup(b->name); g_hash_table_insert(sip->buddies, bs->name, bs); purple_prpl_got_user_status(sip->account, uri, "mobile", NULL); } group = xmlnode_get_child(isc, "contacts/mobile-buddies"); g_return_val_if_fail(group != NULL, FALSE); for (item = xmlnode_get_child(group, "mobile-buddy"); item; item = xmlnode_get_next_twin(item)) { const gchar *uri, *name; gchar *buddy_name; const gchar *g_id; uri = xmlnode_get_attrib(item, "uri"); name = xmlnode_get_attrib(item, "local-name"); g_id = xmlnode_get_attrib(item, "buddy-lists"); buddy_name = g_strdup_printf("%s", uri); if ((g_id == NULL) || (*g_id == '\0') || strlen(g_id) > 1) { g = purple_find_group("未分组"); if (!g) g = purple_group_new("未分组"); } else { g_attr = g_hash_table_lookup(sip->group, g_id); //g_return_val_if_fail(g_attr!=NULL,FALSE); if (g_attr == NULL) continue; g = purple_find_group(g_attr->name); if (!g) g = purple_group_new(g_attr->name); } b = purple_find_buddy(sip->account, buddy_name); if (!b) { b = purple_buddy_new(sip->account, buddy_name, uri); } g_free(buddy_name); purple_blist_add_buddy(b, NULL, g, NULL); if (name != NULL && *name != '\0') purple_blist_alias_buddy(b, name); else purple_blist_alias_buddy(b, uri); bs = g_new0(struct fetion_buddy, 1); bs->name = g_strdup(b->name); g_hash_table_insert(sip->buddies, bs->name, bs); purple_prpl_got_user_status(sip->account, uri, "mobile", NULL); } fetion_subscribe_exp(sip, NULL); //Add youself b = purple_find_buddy(sip->account, sip->uri); if (!b) { b = purple_buddy_new(sip->account, sip->uri, NULL); } purple_blist_add_buddy(b, NULL, g, NULL); purple_blist_alias_buddy(b, "轰炸自己"); bs = g_new0(struct fetion_buddy, 1); bs->name = g_strdup(b->name); g_hash_table_insert(sip->buddies, bs->name, bs); purple_prpl_got_user_status(sip->account, sip->uri, "mobile", NULL); xmlnode_free(isc); break; default: GetContactList(sip); break; } return TRUE; }
static void msn_soap_process(MsnSoapConnection *conn) { gboolean handled = FALSE; char *cursor; char *linebreak; cursor = conn->buf->str + conn->handled_len; if (!conn->headers_done) { while ((linebreak = strstr(cursor, "\r\n")) != NULL) { conn->handled_len = linebreak - conn->buf->str + 2; if (conn->response_code == 0) { if (sscanf(cursor, "HTTP/1.1 %d", &conn->response_code) != 1) { /* something horribly wrong */ purple_ssl_close(conn->ssl); conn->ssl = NULL; handled = TRUE; break; } else if (conn->response_code == 503 && conn->session->login_step < MSN_LOGIN_STEP_END) { msn_soap_connection_sanitize(conn, TRUE); msn_session_set_error(conn->session, MSN_ERROR_SERV_UNAVAILABLE, NULL); return; } } else if (cursor == linebreak) { /* blank line */ conn->headers_done = TRUE; cursor = conn->buf->str + conn->handled_len; break; } else { char *line = g_strndup(cursor, linebreak - cursor); char *sep = strstr(line, ": "); char *key = line; char *value; if (sep == NULL) { purple_debug_info("soap", "ignoring malformed line: %s\n", line); g_free(line); goto loop_end; } value = sep + 2; *sep = '\0'; msn_soap_message_add_header(conn->message, key, value); if ((conn->response_code == 301 || conn->response_code == 300) && strcmp(key, "Location") == 0) { msn_soap_handle_redirect(conn, value); handled = TRUE; g_free(line); break; } else if (conn->response_code == 401 && strcmp(key, "WWW-Authenticate") == 0) { char *error = strstr(value, "cbtxt="); if (error) { error += strlen("cbtxt="); } msn_soap_connection_sanitize(conn, TRUE); msn_session_set_error(conn->session, MSN_ERROR_AUTH, error ? purple_url_decode(error) : NULL); g_free(line); return; } else if (strcmp(key, "Content-Length") == 0) { if (sscanf(value, "%" G_GSIZE_FORMAT, &(conn->body_len)) != 1) purple_debug_error("soap", "Unable to parse Content-Length\n"); } else if (strcmp(key, "Connection") == 0) { if (strcmp(value, "close") == 0) { conn->close_when_done = TRUE; } } g_free(line); } loop_end: cursor = conn->buf->str + conn->handled_len; } } if (!handled && conn->headers_done) { if (conn->buf->len - conn->handled_len >= conn->body_len) { xmlnode *node = xmlnode_from_str(cursor, conn->body_len); if (node == NULL) { purple_debug_info("soap", "Malformed SOAP response: %s\n", cursor); } else { MsnSoapMessage *message = conn->message; conn->message = NULL; message->xml = node; if (!msn_soap_handle_body(conn, message)) { return; } } msn_soap_connection_handle_next(conn); } return; } if (handled) { msn_soap_connection_handle_next(conn); } }
void msn_nexus_update_token(MsnNexus *nexus, int id, GSourceFunc cb, gpointer data) { MsnSession *session = nexus->session; MsnNexusUpdateData *ud; MsnNexusUpdateCallback *update; PurpleCipherContext *sha1; PurpleCipherContext *hmac; char *key; guchar digest[20]; struct tm *tm; time_t now; char *now_str; char *timestamp; char *timestamp_b64; char *domain; char *domain_b64; char *signedinfo; gint32 nonce[6]; int i; char *nonce_b64; char *signature_b64; guchar signature[20]; char *request; MsnSoapMessage *soap; update = g_new0(MsnNexusUpdateCallback, 1); update->cb = cb; update->data = data; if (nexus->tokens[id].updates != NULL) { /* Update already in progress. Just add to list and return. */ purple_debug_info("msn", "Ticket update for user '%s' on domain '%s' in progress. Adding request to queue.\n", purple_account_get_username(session->account), ticket_domains[id][SSO_VALID_TICKET_DOMAIN]); nexus->tokens[id].updates = g_slist_prepend(nexus->tokens[id].updates, update); return; } else { purple_debug_info("msn", "Updating ticket for user '%s' on domain '%s'\n", purple_account_get_username(session->account), ticket_domains[id][SSO_VALID_TICKET_DOMAIN]); nexus->tokens[id].updates = g_slist_prepend(nexus->tokens[id].updates, update); } ud = g_new0(MsnNexusUpdateData, 1); ud->nexus = nexus; ud->id = id; sha1 = purple_cipher_context_new_by_name("sha1", NULL); domain = g_strdup_printf(MSN_SSO_RST_TEMPLATE, id, ticket_domains[id][SSO_VALID_TICKET_DOMAIN], ticket_domains[id][SSO_VALID_TICKET_POLICY] != NULL ? ticket_domains[id][SSO_VALID_TICKET_POLICY] : nexus->policy); purple_cipher_context_append(sha1, (guchar *)domain, strlen(domain)); purple_cipher_context_digest(sha1, 20, digest, NULL); domain_b64 = purple_base64_encode(digest, 20); now = time(NULL); tm = gmtime(&now); now_str = g_strdup(purple_utf8_strftime("%Y-%m-%dT%H:%M:%SZ", tm)); now += 5*60; tm = gmtime(&now); timestamp = g_strdup_printf(MSN_SSO_TIMESTAMP_TEMPLATE, now_str, purple_utf8_strftime("%Y-%m-%dT%H:%M:%SZ", tm)); purple_cipher_context_reset(sha1, NULL); purple_cipher_context_append(sha1, (guchar *)timestamp, strlen(timestamp)); purple_cipher_context_digest(sha1, 20, digest, NULL); timestamp_b64 = purple_base64_encode(digest, 20); g_free(now_str); purple_cipher_context_destroy(sha1); signedinfo = g_strdup_printf(MSN_SSO_SIGNEDINFO_TEMPLATE, id, domain_b64, timestamp_b64); for (i = 0; i < 6; i++) nonce[i] = rand(); nonce_b64 = purple_base64_encode((guchar *)&nonce, sizeof(nonce)); key = rps_create_key(nexus->secret, 24, (char *)nonce, sizeof(nonce)); hmac = purple_cipher_context_new_by_name("hmac", NULL); purple_cipher_context_set_option(hmac, "hash", "sha1"); purple_cipher_context_set_key_with_len(hmac, (guchar *)key, 24); purple_cipher_context_append(hmac, (guchar *)signedinfo, strlen(signedinfo)); purple_cipher_context_digest(hmac, 20, signature, NULL); purple_cipher_context_destroy(hmac); signature_b64 = purple_base64_encode(signature, 20); request = g_strdup_printf(MSN_SSO_TOKEN_UPDATE_TEMPLATE, nexus->cipher, nonce_b64, timestamp, signedinfo, signature_b64, domain); g_free(nonce_b64); g_free(domain_b64); g_free(timestamp_b64); g_free(timestamp); g_free(key); g_free(signature_b64); g_free(signedinfo); g_free(domain); soap = msn_soap_message_new(NULL, xmlnode_from_str(request, -1)); g_free(request); msn_soap_message_send(session, soap, MSN_SSO_SERVER, SSO_POST_URL, TRUE, nexus_got_update_cb, ud); }
static void nexus_got_update_cb(MsnSoapMessage *req, MsnSoapMessage *resp, gpointer data) { MsnNexusUpdateData *ud = data; MsnNexus *nexus = ud->nexus; char iv[8] = {0,0,0,0,0,0,0,0}; xmlnode *enckey; char *tmp; char *nonce; gsize len; char *key; GSList *updates; #if 0 char *decrypted_pp; #endif char *decrypted_data; if (resp == NULL) return; purple_debug_info("msn", "Got Update Response for %s.\n", ticket_domains[ud->id][SSO_VALID_TICKET_DOMAIN]); enckey = xmlnode_get_child(resp->xml, "Header/Security/DerivedKeyToken"); while (enckey) { if (g_str_equal(xmlnode_get_attrib(enckey, "Id"), "EncKey")) break; enckey = xmlnode_get_next_twin(enckey); } if (!enckey) { purple_debug_error("msn", "Invalid response in token update.\n"); return; } tmp = xmlnode_get_data(xmlnode_get_child(enckey, "Nonce")); nonce = (char *)purple_base64_decode(tmp, &len); key = rps_create_key(nexus->secret, 24, nonce, len); g_free(tmp); g_free(nonce); #if 0 /* Don't know what this is for yet */ tmp = xmlnode_get_data(xmlnode_get_child(resp->xml, "Header/EncryptedPP/EncryptedData/CipherData/CipherValue")); if (tmp) { decrypted_pp = des3_cbc(key, iv, tmp, len, TRUE); g_free(tmp); purple_debug_info("msn", "Got Response Header EncryptedPP: %s\n", decrypted_pp); g_free(decrypted_pp); } #endif tmp = xmlnode_get_data(xmlnode_get_child(resp->xml, "Body/EncryptedData/CipherData/CipherValue")); if (tmp) { char *unescaped; xmlnode *rstresponse; unescaped = (char *)purple_base64_decode(tmp, &len); g_free(tmp); decrypted_data = des3_cbc(key, iv, unescaped, len, TRUE); g_free(unescaped); purple_debug_info("msn", "Got Response Body EncryptedData: %s\n", decrypted_data); rstresponse = xmlnode_from_str(decrypted_data, -1); if (g_str_equal(rstresponse->name, "RequestSecurityTokenResponse")) nexus_parse_token(nexus, ud->id, rstresponse); else nexus_parse_collection(nexus, ud->id, rstresponse); g_free(decrypted_data); } updates = nexus->tokens[ud->id].updates; nexus->tokens[ud->id].updates = NULL; while (updates != NULL) { MsnNexusUpdateCallback *update = updates->data; if (update->cb) purple_timeout_add(0, update->cb, update->data); g_free(update); updates = g_slist_delete_link(updates, updates); } g_free(ud); g_free(key); }
static void fb_got_notifications_cb(FacebookAccount *fba, gchar *url_text, gsize len, gpointer userdata) { gchar *salvaged; time_t last_fetch_time; time_t time_of_message; time_t newest_message = 0; xmlnode *channel;//VOXOX - CJC - 2009.07.06 xmlnode *rss_root;//VOXOX - CJC - 2009.07.06 xmlnode *item;//VOXOX - CJC - 2009.07.06 xmlnode *link;//VOXOX - CJC - 2009.07.06 xmlnode *title;//VOXOX - CJC - 2009.07.06 gchar *tmp; gchar month_string[4], weekday[4]; guint year, month, day, hour, minute, second; long timezone; gchar *subject, *url; month_string[3] = weekday[3] = '\0'; year = month = day = hour = minute = second = 0; if (!url_text || !len) return; last_fetch_time = purple_account_get_int(fba->account, "facebook_notifications_last_fetch", 0); /* purple_debug_info("facebook", "last fetch time: %zu\n", last_fetch_time); */ salvaged = purple_utf8_salvage(url_text); rss_root = xmlnode_from_str(salvaged, -1); g_free(salvaged); if (rss_root == NULL) { purple_debug_error("facebook", "Could not load RSS file\n"); return; } channel = xmlnode_get_child(rss_root, "channel"); if (channel == NULL) { purple_debug_warning("facebook", "Invalid RSS feed\n"); xmlnode_free(rss_root); return; } item = xmlnode_get_child(channel, "item"); if (item == NULL) { purple_debug_info("facebook", "No new notifications\n"); } for (; item != NULL; item = xmlnode_get_next_twin(item)) { xmlnode *pubDate = xmlnode_get_child(item, "pubDate"); if (!pubDate) continue; tmp = xmlnode_get_data_unescaped(pubDate); /* rss times are in Thu, 19 Jun 2008 15:51:25 -1100 format */ sscanf(tmp, "%3s, %2u %3s %4u %2u:%2u:%2u %5ld", (char*)&weekday, &day, (char*)&month_string, &year, &hour, &minute, &second, &timezone); if (g_str_equal(month_string, "Jan")) month = 0; else if (g_str_equal(month_string, "Feb")) month = 1; else if (g_str_equal(month_string, "Mar")) month = 2; else if (g_str_equal(month_string, "Apr")) month = 3; else if (g_str_equal(month_string, "May")) month = 4; else if (g_str_equal(month_string, "Jun")) month = 5; else if (g_str_equal(month_string, "Jul")) month = 6; else if (g_str_equal(month_string, "Aug")) month = 7; else if (g_str_equal(month_string, "Sep")) month = 8; else if (g_str_equal(month_string, "Oct")) month = 9; else if (g_str_equal(month_string, "Nov")) month = 10; else if (g_str_equal(month_string, "Dec")) month = 11; g_free(tmp); /* try using pidgin's functions */ tmp = g_strdup_printf("%04u%02u%02uT%02u%02u%02u%05ld", year, month, day, hour, minute, second, timezone); time_of_message = purple_str_to_time(tmp, FALSE, NULL, NULL, NULL); g_free(tmp); if (time_of_message <= 0) { /* there's no cross-platform, portable way of converting string to time which doesn't need a new version of glib, so just cheat */ time_of_message = second + 60*minute + 3600*hour + 86400*day + 2592000*month + 31536000*(year-1970); } if (time_of_message > newest_message) { /* we'll keep the newest message to save */ newest_message = time_of_message; } if (time_of_message <= last_fetch_time) { /* fortunatly, rss messages are ordered from newest to oldest */ /* so if this message is older than the last one, ignore rest */ break; } link = xmlnode_get_child(item, "link"); if (link) { url = xmlnode_get_data_unescaped(link); } else { url = g_strdup(""); } title = xmlnode_get_child(item, "title"); if (title) { subject = xmlnode_get_data_unescaped(title); } else { subject = g_strdup(""); } purple_notify_email(fba->pc, subject, NULL, fba->account->username, url, NULL, NULL); g_free(subject); g_free(url); } xmlnode_free(rss_root); if (newest_message > last_fetch_time) { /* update the last fetched time if we had newer messages */ purple_account_set_int(fba->account, "facebook_notifications_last_fetch", newest_message); } }
static gboolean parse_start_oscar_session_response(PurpleConnection *gc, const gchar *response, gsize response_len, char **host, unsigned short *port, char **cookie, char **tls_certname) { xmlnode *response_node, *tmp_node, *data_node; xmlnode *host_node = NULL, *port_node = NULL, *cookie_node = NULL, *tls_node = NULL; gboolean use_tls; char *tmp; guint code; use_tls = purple_account_get_bool(purple_connection_get_account(gc), "use_ssl", OSCAR_DEFAULT_USE_SSL); /* Parse the response as XML */ response_node = xmlnode_from_str(response, response_len); if (response_node == NULL) { char *msg; purple_debug_error("oscar", "startOSCARSession could not parse " "response as XML: %s\n", response); /* Note to translators: %s in this string is a URL */ msg = generate_error_message(response_node, URL_START_OSCAR_SESSION); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); return FALSE; } /* Grab the necessary XML nodes */ tmp_node = xmlnode_get_child(response_node, "statusCode"); data_node = xmlnode_get_child(response_node, "data"); if (data_node != NULL) { host_node = xmlnode_get_child(data_node, "host"); port_node = xmlnode_get_child(data_node, "port"); cookie_node = xmlnode_get_child(data_node, "cookie"); tls_node = xmlnode_get_child(data_node, "tlsCertName"); } /* Make sure we have a status code */ if (tmp_node == NULL || (tmp = xmlnode_get_data_unescaped(tmp_node)) == NULL) { char *msg; purple_debug_error("oscar", "startOSCARSession response was " "missing statusCode: %s\n", response); msg = generate_error_message(response_node, URL_START_OSCAR_SESSION); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); xmlnode_free(response_node); return FALSE; } /* Make sure the status code was 200 */ code = atoi(tmp); if (code != 200) { xmlnode *status_detail_node; guint status_detail = 0; status_detail_node = xmlnode_get_child(response_node, "statusDetailCode"); if (status_detail_node) { gchar *data = xmlnode_get_data(status_detail_node); if (data) { status_detail = atoi(data); g_free(data); } } purple_debug_error("oscar", "startOSCARSession response statusCode " "was %s: %s\n", tmp, response); if ((code == 401 && status_detail != 1014) || code == 607) purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("You have been connecting and disconnecting too " "frequently. Wait ten minutes and try again. If " "you continue to try, you will need to wait even " "longer.")); else { char *msg; msg = generate_error_message(response_node, URL_START_OSCAR_SESSION); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, msg); g_free(msg); } g_free(tmp); xmlnode_free(response_node); return FALSE; } g_free(tmp); /* Make sure we have everything else */ if (data_node == NULL || host_node == NULL || port_node == NULL || cookie_node == NULL || (use_tls && tls_node == NULL)) { char *msg; purple_debug_error("oscar", "startOSCARSession response was missing " "something: %s\n", response); msg = generate_error_message(response_node, URL_START_OSCAR_SESSION); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); xmlnode_free(response_node); return FALSE; } /* Extract data from the XML */ *host = xmlnode_get_data_unescaped(host_node); tmp = xmlnode_get_data_unescaped(port_node); *cookie = xmlnode_get_data_unescaped(cookie_node); if (use_tls) *tls_certname = xmlnode_get_data_unescaped(tls_node); if (*host == NULL || **host == '\0' || tmp == NULL || *tmp == '\0' || *cookie == NULL || **cookie == '\0' || (use_tls && (*tls_certname == NULL || **tls_certname == '\0'))) { char *msg; purple_debug_error("oscar", "startOSCARSession response was missing " "something: %s\n", response); msg = generate_error_message(response_node, URL_START_OSCAR_SESSION); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); g_free(*host); g_free(tmp); g_free(*cookie); xmlnode_free(response_node); return FALSE; } *port = atoi(tmp); g_free(tmp); return TRUE; }
static gchar* purple_upnp_parse_description_response(const gchar* httpResponse, gsize len, const gchar* httpURL, const gchar* serviceType) { gchar *xmlRoot, *baseURL, *controlURL, *service; xmlnode *xmlRootNode, *serviceTypeNode, *controlURLNode, *baseURLNode; char *tmp; /* make sure we have a valid http response */ if(g_strstr_len(httpResponse, len, HTTP_OK) == NULL) { purple_debug_error("upnp", "parse_description_response(): Failed In HTTP_OK\n"); return NULL; } /* find the root of the xml document */ if((xmlRoot = g_strstr_len(httpResponse, len, "<root")) == NULL) { purple_debug_error("upnp", "parse_description_response(): Failed finding root\n"); return NULL; } /* create the xml root node */ if((xmlRootNode = xmlnode_from_str(xmlRoot, len - (xmlRoot - httpResponse))) == NULL) { purple_debug_error("upnp", "parse_description_response(): Could not parse xml root node\n"); return NULL; } /* get the baseURL of the device */ if((baseURLNode = xmlnode_get_child(xmlRootNode, "URLBase")) != NULL) { baseURL = xmlnode_get_data(baseURLNode); } else { baseURL = g_strdup(httpURL); } /* get the serviceType child that has the service type as its data */ /* get urn:schemas-upnp-org:device:InternetGatewayDevice:1 and its devicelist */ serviceTypeNode = xmlnode_get_child(xmlRootNode, "device"); while(!purple_upnp_compare_device(serviceTypeNode, "urn:schemas-upnp-org:device:InternetGatewayDevice:1") && serviceTypeNode != NULL) { serviceTypeNode = xmlnode_get_next_twin(serviceTypeNode); } if(serviceTypeNode == NULL) { purple_debug_error("upnp", "parse_description_response(): could not get serviceTypeNode 1\n"); g_free(baseURL); xmlnode_free(xmlRootNode); return NULL; } serviceTypeNode = xmlnode_get_child(serviceTypeNode, "deviceList"); if(serviceTypeNode == NULL) { purple_debug_error("upnp", "parse_description_response(): could not get serviceTypeNode 2\n"); g_free(baseURL); xmlnode_free(xmlRootNode); return NULL; } /* get urn:schemas-upnp-org:device:WANDevice:1 and its devicelist */ serviceTypeNode = xmlnode_get_child(serviceTypeNode, "device"); while(!purple_upnp_compare_device(serviceTypeNode, "urn:schemas-upnp-org:device:WANDevice:1") && serviceTypeNode != NULL) { serviceTypeNode = xmlnode_get_next_twin(serviceTypeNode); } if(serviceTypeNode == NULL) { purple_debug_error("upnp", "parse_description_response(): could not get serviceTypeNode 3\n"); g_free(baseURL); xmlnode_free(xmlRootNode); return NULL; } serviceTypeNode = xmlnode_get_child(serviceTypeNode, "deviceList"); if(serviceTypeNode == NULL) { purple_debug_error("upnp", "parse_description_response(): could not get serviceTypeNode 4\n"); g_free(baseURL); xmlnode_free(xmlRootNode); return NULL; } /* get urn:schemas-upnp-org:device:WANConnectionDevice:1 and its servicelist */ serviceTypeNode = xmlnode_get_child(serviceTypeNode, "device"); while(serviceTypeNode && !purple_upnp_compare_device(serviceTypeNode, "urn:schemas-upnp-org:device:WANConnectionDevice:1")) { serviceTypeNode = xmlnode_get_next_twin(serviceTypeNode); } if(serviceTypeNode == NULL) { purple_debug_error("upnp", "parse_description_response(): could not get serviceTypeNode 5\n"); g_free(baseURL); xmlnode_free(xmlRootNode); return NULL; } serviceTypeNode = xmlnode_get_child(serviceTypeNode, "serviceList"); if(serviceTypeNode == NULL) { purple_debug_error("upnp", "parse_description_response(): could not get serviceTypeNode 6\n"); g_free(baseURL); xmlnode_free(xmlRootNode); return NULL; } /* get the serviceType variable passed to this function */ service = g_strdup_printf(SEARCH_REQUEST_DEVICE, serviceType); serviceTypeNode = xmlnode_get_child(serviceTypeNode, "service"); while(!purple_upnp_compare_service(serviceTypeNode, service) && serviceTypeNode != NULL) { serviceTypeNode = xmlnode_get_next_twin(serviceTypeNode); } g_free(service); if(serviceTypeNode == NULL) { purple_debug_error("upnp", "parse_description_response(): could not get serviceTypeNode 7\n"); g_free(baseURL); xmlnode_free(xmlRootNode); return NULL; } /* get the controlURL of the service */ if((controlURLNode = xmlnode_get_child(serviceTypeNode, "controlURL")) == NULL) { purple_debug_error("upnp", "parse_description_response(): Could not find controlURL\n"); g_free(baseURL); xmlnode_free(xmlRootNode); return NULL; } tmp = xmlnode_get_data(controlURLNode); if(baseURL && !purple_str_has_prefix(tmp, "http://") && !purple_str_has_prefix(tmp, "HTTP://")) { /* Handle absolute paths in a relative URL. This probably * belongs in util.c. */ if (tmp[0] == '/') { size_t length; const char *path, *start = strstr(baseURL, "://"); start = start ? start + 3 : baseURL; path = strchr(start, '/'); length = path ? path - baseURL : strlen(baseURL); controlURL = g_strdup_printf("%.*s%s", (int)length, baseURL, tmp); } else { controlURL = g_strdup_printf("%s%s", baseURL, tmp); } g_free(tmp); }else{ controlURL = tmp; } g_free(baseURL); xmlnode_free(xmlRootNode); return controlURL; }
void AddMobileBuddy(struct fetion_account_data *sip, struct sipmsg *msg, struct transaction *tc) { gint xml_len; xmlnode *root, *son, *item; gchar *body; const gchar *uri, *name, *group_id; struct group_attr *g_attr = NULL; gchar *buddy_name; PurpleBuddy *b; PurpleGroup *g = NULL; struct fetion_buddy *bs; struct sipmsg *old = NULL; const gchar *real_name; real_name = purple_account_get_string(sip->account, "realname", sip->username); if (!real_name || strlen(real_name) < 1) { real_name = sip->username; } g_return_if_fail(tc->msg != NULL); old = tc->msg; g_return_if_fail(old != NULL); purple_debug_info("fetion:", "AddMobileBuddy:oldmsg[%s]", old->body); root = xmlnode_from_str(old->body, old->bodylen); item = xmlnode_get_child(root, "contacts/buddies/buddy"); g_return_if_fail(item != NULL); uri = xmlnode_get_attrib(item, "uri"); name = xmlnode_get_attrib(item, "local-name"); group_id = xmlnode_get_attrib(item, "buddy-lists"); buddy_name = g_strdup_printf("%s", uri); g_attr = g_hash_table_lookup(sip->group, group_id); g_return_if_fail(g_attr != NULL); g = purple_find_group(g_attr->name); if (!g) g = purple_group_new(g_attr->name); b = purple_find_buddy(sip->account, buddy_name); if (!b) { b = purple_buddy_new(sip->account, buddy_name, NULL); } purple_blist_add_buddy(b, NULL, g, NULL); if (name != NULL && *name != '\0') purple_blist_alias_buddy(b, name); bs = g_new0(struct fetion_buddy, 1); bs->name = g_strdup(b->name); g_hash_table_insert(sip->buddies, bs->name, bs); xmlnode_free(root); root = xmlnode_new("args"); g_return_if_fail(root != NULL); son = xmlnode_new_child(root, "contacts"); g_return_if_fail(son != NULL); son = xmlnode_new_child(son, "mobile-buddies"); g_return_if_fail(son != NULL); item = xmlnode_new_child(son, "mobile-buddy"); g_return_if_fail(item != NULL); xmlnode_set_attrib(item, "expose-mobile-no", "1"); xmlnode_set_attrib(item, "expose-name", "1"); xmlnode_set_attrib(item, "invite", "1"); xmlnode_set_attrib(item, "uri", buddy_name); xmlnode_set_attrib(item, "buddy-lists", "1"); //xmlnode_set_attrib(item,"desc",sip->mobileno); xmlnode_set_attrib(item, "desc", real_name); body = g_strdup_printf("%s",xmlnode_to_str(root, &xml_len)); purple_debug_info("fetion:", "add_buddy:body=[%s]", body); send_sip_request(sip->gc, "S", "", "", "N: AddMobileBuddy\r\n", body, NULL, (TransCallback) AddMobileBuddy_cb); g_free(buddy_name); xmlnode_free(root); g_free(body); }
/** * This function parses the given response from a clientLogin request * and extracts the useful information. * * @param gc The PurpleConnection. If the response data does * not indicate then purple_connection_error_reason() * will be called to close this connection. * @param response The response data from the clientLogin request. * @param response_len The length of the above response, or -1 if * @response is NUL terminated. * @param token If parsing was successful then this will be set to * a newly allocated string containing the token. The * caller should g_free this string when it is finished * with it. On failure this value will be untouched. * @param secret If parsing was successful then this will be set to * a newly allocated string containing the secret. The * caller should g_free this string when it is finished * with it. On failure this value will be untouched. * @param hosttime If parsing was successful then this will be set to * the time on the OpenAuth Server in seconds since the * Unix epoch. On failure this value will be untouched. * * @return TRUE if the request was successful and we were able to * extract all info we need. Otherwise FALSE. */ static gboolean parse_client_login_response(PurpleConnection *gc, const gchar *response, gsize response_len, char **token, char **secret, time_t *hosttime) { xmlnode *response_node, *tmp_node, *data_node; xmlnode *secret_node = NULL, *hosttime_node = NULL, *token_node = NULL, *tokena_node = NULL; char *tmp; /* Parse the response as XML */ response_node = xmlnode_from_str(response, response_len); if (response_node == NULL) { char *msg; purple_debug_error("oscar", "clientLogin could not parse " "response as XML: %s\n", response); msg = generate_error_message(response_node, URL_CLIENT_LOGIN); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); return FALSE; } /* Grab the necessary XML nodes */ tmp_node = xmlnode_get_child(response_node, "statusCode"); data_node = xmlnode_get_child(response_node, "data"); if (data_node != NULL) { secret_node = xmlnode_get_child(data_node, "sessionSecret"); hosttime_node = xmlnode_get_child(data_node, "hostTime"); token_node = xmlnode_get_child(data_node, "token"); if (token_node != NULL) tokena_node = xmlnode_get_child(token_node, "a"); } /* Make sure we have a status code */ if (tmp_node == NULL || (tmp = xmlnode_get_data_unescaped(tmp_node)) == NULL) { char *msg; purple_debug_error("oscar", "clientLogin response was " "missing statusCode: %s\n", response); msg = generate_error_message(response_node, URL_CLIENT_LOGIN); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); xmlnode_free(response_node); return FALSE; } /* Make sure the status code was 200 */ if (strcmp(tmp, "200") != 0) { int status_code, status_detail_code = 0; status_code = atoi(tmp); g_free(tmp); tmp_node = xmlnode_get_child(response_node, "statusDetailCode"); if (tmp_node != NULL && (tmp = xmlnode_get_data_unescaped(tmp_node)) != NULL) { status_detail_code = atoi(tmp); g_free(tmp); } purple_debug_error("oscar", "clientLogin response statusCode " "was %d (%d): %s\n", status_code, status_detail_code, response); if (status_code == 330 && status_detail_code == 3011) { PurpleAccount *account = purple_connection_get_account(gc); if (!purple_account_get_remember_password(account)) purple_account_set_password(account, NULL); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Incorrect password")); } else if (status_code == 330 && status_detail_code == 3015) { purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Server requested that you fill out a CAPTCHA in order to " "sign in, but this client does not currently support CAPTCHAs.")); } else if (status_code == 401 && status_detail_code == 3019) { purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, _("AOL does not allow your screen name to authenticate here")); } else { char *msg; msg = generate_error_message(response_node, URL_CLIENT_LOGIN); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, msg); g_free(msg); } xmlnode_free(response_node); return FALSE; } g_free(tmp); /* Make sure we have everything else */ if (data_node == NULL || secret_node == NULL || token_node == NULL || tokena_node == NULL) { char *msg; purple_debug_error("oscar", "clientLogin response was missing " "something: %s\n", response); msg = generate_error_message(response_node, URL_CLIENT_LOGIN); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); xmlnode_free(response_node); return FALSE; } /* Extract data from the XML */ *token = xmlnode_get_data_unescaped(tokena_node); *secret = xmlnode_get_data_unescaped(secret_node); tmp = xmlnode_get_data_unescaped(hosttime_node); if (*token == NULL || **token == '\0' || *secret == NULL || **secret == '\0' || tmp == NULL || *tmp == '\0') { char *msg; purple_debug_error("oscar", "clientLogin response was missing " "something: %s\n", response); msg = generate_error_message(response_node, URL_CLIENT_LOGIN); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, msg); g_free(msg); g_free(*token); g_free(*secret); g_free(tmp); xmlnode_free(response_node); return FALSE; } *hosttime = strtol(tmp, NULL, 10); g_free(tmp); xmlnode_free(response_node); return TRUE; }