static gfire_game_configuration *gfire_game_configuration_create_from_xml(xmlnode *p_node) { xmlnode *command_node = xmlnode_get_child(p_node, "command"); if(!command_node) return NULL; gfire_game_configuration *ret = g_malloc0(sizeof(gfire_game_configuration)); if(xmlnode_get_attrib(p_node, "id")) sscanf(xmlnode_get_attrib(p_node, "id"), "%u", &ret->game_id); xmlnode *cur_node = xmlnode_get_child(command_node, "detect"); if(cur_node) ret->detect_file = xmlnode_get_data_unescaped(cur_node); cur_node = xmlnode_get_child(command_node, "launch"); if(cur_node) ret->launch_file = xmlnode_get_data_unescaped(cur_node); cur_node = xmlnode_get_child(command_node, "prefix"); if(cur_node) ret->launch_prefix = xmlnode_get_data_unescaped(cur_node); return ret; }
/** * 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; }
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 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 gfire_game_detection_set *gfire_game_detection_set_create_from_xml(xmlnode *p_node) { gfire_game_detection_set *ret = g_malloc0(sizeof(gfire_game_detection_set)); gchar *tmp = NULL; // Enable server detection xmlnode *cur_node = xmlnode_get_child(p_node, "server_detection"); if(cur_node) { tmp = xmlnode_get_data_unescaped(cur_node); if(tmp) { if(!g_utf8_collate(tmp, "enabled")) ret->detect_server = TRUE; g_free(tmp); } } // Excluded ports cur_node = xmlnode_get_child(p_node, "server_excluded_ports"); if(cur_node) { tmp = xmlnode_get_data_unescaped(cur_node); if(tmp) { gchar **parray = g_strsplit(tmp, ";", -1); if(parray) { int i; for(i = 0; i < g_strv_length(parray); i++) { if(parray[i][0] == 0) continue; guint16 *port = g_malloc0(sizeof(guint16)); sscanf(parray[i], "%hu", port); ret->excluded_ports = g_list_append(ret->excluded_ports, port); } g_strfreev(parray); } g_free(tmp); } } // Broadcast ports cur_node = xmlnode_get_child(p_node, "server_broadcast_ports"); if(cur_node) { tmp = xmlnode_get_data_unescaped(cur_node); if(tmp) { gchar **parray = g_strsplit(tmp, ";", -1); if(parray) { int i; for(i = 0; i < g_strv_length(parray); i++) { if(parray[i][0] == 0) continue; ret->server_broadcast_ports = g_list_append(ret->server_broadcast_ports, g_strdup(parray[i])); } g_strfreev(parray); } g_free(tmp); } } // Server game name cur_node = xmlnode_get_child(p_node, "server_game_name"); if(cur_node) { ret->server_game_name = xmlnode_get_data_unescaped(cur_node); } // Server status type cur_node = xmlnode_get_child(p_node, "server_status_type"); if(cur_node) { ret->server_status_type = xmlnode_get_data_unescaped(cur_node); } // Launch PW args cur_node = xmlnode_get_child(p_node, "launch_password_args"); if(cur_node) { ret->password_args = xmlnode_get_data_unescaped(cur_node); } // Launch network args cur_node = xmlnode_get_child(p_node, "launch_network_args"); if(cur_node) { ret->network_args = xmlnode_get_data_unescaped(cur_node); } // Launch args cur_node = xmlnode_get_child(p_node, "launch_args"); if(cur_node) { ret->launch_args = xmlnode_get_data_unescaped(cur_node); } // Arguments cur_node = xmlnode_get_child(p_node, "arguments"); if(cur_node) { // Invalid args if(xmlnode_get_attrib(cur_node, "invalid")) { gchar **args = g_strsplit(xmlnode_get_attrib(cur_node, "invalid"), ";", -1); if(args) { int i; for(i = 0; i < g_strv_length(args); i++) { if(args[i][0] == 0) continue; ret->invalid_args = g_list_append(ret->invalid_args, g_strdup(args[i])); } g_strfreev(args); } } // Required args if(xmlnode_get_attrib(cur_node, "required")) { gchar **args = g_strsplit(xmlnode_get_attrib(cur_node, "required"), ";", -1); if(args) { int i; for(i = 0; i < g_strv_length(args); i++) { if(args[i][0] == 0) continue; ret->required_args = g_list_append(ret->required_args, g_strdup(args[i])); } g_strfreev(args); } } } // External cur_node = xmlnode_get_child(p_node, "external"); if(cur_node) { ret->external = TRUE; // Detection URL if(xmlnode_get_attrib(cur_node, "url")) { ret->detect_url = g_strdup(xmlnode_get_attrib(cur_node, "url")); } // Launch URL if(xmlnode_get_attrib(cur_node, "launchurl")) { ret->launch_url = g_strdup(xmlnode_get_attrib(cur_node, "launchurl")); } } return ret; }
static void purple_fbapi_request_fetch_cb(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message) { PurpleFbApiCall *apicall; xmlnode *response; PurpleConnectionError error = PURPLE_CONNECTION_ERROR_OTHER_ERROR; char *error_message2 = NULL; apicall = user_data; if (error_message != NULL) { /* Request failed */ if (apicall->attempt_number < MAX_CONNECTION_ATTEMPTS) { /* Retry! */ apicall->url_data = purple_util_fetch_url_request(API_URL, TRUE, NULL, FALSE, apicall->request, FALSE, purple_fbapi_request_fetch_cb, apicall); apicall->attempt_number++; return; } response = NULL; error_message2 = g_strdup(error_message); error = PURPLE_CONNECTION_ERROR_NETWORK_ERROR; } else if (url_text != NULL && len > 0) { /* Parse the response as XML */ response = xmlnode_from_str(url_text, len); if (response == NULL) { gchar *salvaged; if (g_utf8_validate(url_text, len, NULL)) { salvaged = g_strdup(url_text); } else { /* Facebook responded with invalid UTF-8. Bastards. */ purple_debug_error("fbapi", "Response is not valid UTF-8\n"); salvaged = purple_utf8_salvage(url_text); } purple_fbapi_xml_salvage(salvaged); response = xmlnode_from_str(salvaged, -1); g_free(salvaged); } if (response == NULL) { purple_debug_error("fbapi", "Could not parse response as XML: %*s\n", (int)len, url_text); error_message2 = g_strdup(_("Invalid response from server")); } else if (g_str_equal(response->name, "error_response")) { /* * The response is an error message, in the standard format * for errors from API calls. */ xmlnode *tmp; char *tmpstr; tmp = xmlnode_get_child(response, "error_code"); if (tmp != NULL) { tmpstr = xmlnode_get_data_unescaped(tmp); if (tmpstr != NULL && strcmp(tmpstr, "293") == 0) { error_message2 = g_strdup(_("Need chat permission")); error = PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED; } g_free(tmpstr); } if (error_message2 == NULL) { error = PURPLE_CONNECTION_ERROR_OTHER_ERROR; tmp = xmlnode_get_child(response, "error_msg"); if (tmp != NULL) error_message2 = xmlnode_get_data_unescaped(tmp); } if (error_message2 == NULL) error_message2 = g_strdup(_("Unknown")); } else { error_message2 = NULL; } } else { /* Response body was empty */ response = NULL; error_message2 = NULL; } if (apicall->attempt_number > 1 || error_message2 != NULL) purple_debug_error("fbapi", "Request '%s' %s after %u attempts: %s\n", apicall->request, error_message == NULL ? "succeeded" : "failed", apicall->attempt_number, error_message2); /* * The request either succeeded or failed the maximum number of * times. In either case, pass control off to the callback * function and let them decide what to do. */ apicall->callback(apicall, apicall->user_data, response, error, error_message2); apicall->url_data = NULL; purple_fbapi_request_destroy(apicall); xmlnode_free(response); g_free(error_message2); }