static sd_dhcp_client *client_stop(sd_dhcp_client *client, int error) { assert_return(client, NULL); if (error < 0) log_dhcp_client(client, "STOPPED: %s", strerror(-error)); else { switch(error) { case DHCP_EVENT_STOP: log_dhcp_client(client, "STOPPED"); break; case DHCP_EVENT_NO_LEASE: log_dhcp_client(client, "STOPPED: No lease"); break; default: log_dhcp_client(client, "STOPPED: Unknown reason"); break; } } client = client_notify(client, error); if (client) client_initialize(client); return client; }
static int client_stop(sd_dhcp_client *client, int error) { assert_return(client, -EINVAL); client->receive_message = sd_event_source_unref(client->receive_message); if (client->fd >= 0) close_nointr_nofail(client->fd); client->fd = -1; client->timeout_resend = sd_event_source_unref(client->timeout_resend); client->timeout_t1 = sd_event_source_unref(client->timeout_t1); client->timeout_t2 = sd_event_source_unref(client->timeout_t2); client->timeout_expire = sd_event_source_unref(client->timeout_expire); client->attempt = 1; client_notify(client, error); client->start_time = 0; client->secs = 0; client->state = DHCP_STATE_INIT; if (client->lease) client->lease = sd_dhcp_lease_unref(client->lease); log_dhcp_client(client, "STOPPED"); return 0; }
static sd_dhcp_client *client_stop(sd_dhcp_client *client, int error) { assert_return(client, NULL); log_dhcp_client(client, "STOPPED: %s", strerror(-error)); client = client_notify(client, error); if (client) client_initialize(client); return client; }
static int client_timeout_expire(sd_event_source *s, uint64_t usec, void *userdata) { sd_dhcp_client *client = userdata; log_dhcp_client(client, "EXPIRED"); client = client_notify(client, DHCP_EVENT_EXPIRED); /* lease was lost, start over if not freed or stopped in callback */ if (client && client->state != DHCP_STATE_STOPPED) { client_initialize(client); client_start(client); } return 0; }
bool facebook_client::home( ) { handle_entry( "home" ); http::response resp = flap( FACEBOOK_REQUEST_HOME ); // Process result data validate_response(&resp); switch ( resp.code ) { case HTTP_CODE_OK: { if ( resp.data.find( "id=\"navAccountName\"" ) != std::string::npos ) { // Backup for old fb version // Get real_name this->self_.real_name = utils::text::remove_html( utils::text::special_expressions_decode( utils::text::source_get_value( &resp.data, 2, " id=\"navAccountName\">", "</a" ) ) ); DBWriteContactSettingUTF8String(NULL,parent->m_szModuleName,FACEBOOK_KEY_NAME,this->self_.real_name.c_str()); DBWriteContactSettingUTF8String(NULL,parent->m_szModuleName,FACEBOOK_KEY_NICK,this->self_.real_name.c_str()); parent->Log(" Got self real name: %s", this->self_.real_name.c_str()); } else if ( resp.data.find("id=\"pageNav\"") != std::string::npos ) { // Get real_name this->self_.real_name = utils::text::remove_html( utils::text::special_expressions_decode( utils::text::source_get_value( &resp.data, 3, " class=\"headerTinymanName\"", ">", "</a" ) ) ); DBWriteContactSettingUTF8String(NULL,parent->m_szModuleName,FACEBOOK_KEY_NAME,this->self_.real_name.c_str()); DBWriteContactSettingUTF8String(NULL,parent->m_szModuleName,FACEBOOK_KEY_NICK,this->self_.real_name.c_str()); parent->Log(" Got self real name: %s", this->self_.real_name.c_str()); } else { client_notify(TranslateT("Something happened to Facebook. Maybe there was some major update so you should wait for an update.")); return handle_error( "home", FORCE_DISCONNECT ); } // Get avatar std::string avatar = utils::text::source_get_value( &resp.data, 3, "class=\\\"fbxWelcomeBoxImg", "src=\\\"", "\\\"" ); if (avatar.empty()) avatar = utils::text::source_get_value( &resp.data, 3, "class=\"fbxWelcomeBoxImg", "src=\"", "\"" ); this->self_.image_url = utils::text::trim( utils::text::special_expressions_decode( avatar ) ); parent->Log(" Got self avatar: %s", this->self_.image_url.c_str()); parent->CheckAvatarChange(NULL, this->self_.image_url); // Get post_form_id this->post_form_id_ = utils::text::source_get_value( &resp.data, 3, "name=\"post_form_id\"", "value=\"", "\"" ); parent->Log(" Got self post form id: %s", this->post_form_id_.c_str()); // Get dtsg this->dtsg_ = utils::text::source_get_value( &resp.data, 3, "name=\"fb_dtsg\"", "value=\"", "\"" ); parent->Log(" Got self dtsg: %s", this->dtsg_.c_str()); // Get logout hash this->logout_hash_ = utils::text::source_get_value( &resp.data, 2, "<input type=\"hidden\" autocomplete=\"off\" name=\"h\" value=\"", "\"" ); parent->Log(" Got self logout hash: %s", this->logout_hash_.c_str()); // TODO: DIrectly get that friend requests // Get friend requests count and notify it std::string str_count = utils::text::source_get_value( &resp.data, 2, "<span id=\"requestsCountValue\">", "</span>" ); if ( str_count.length() && str_count != std::string( "0" ) ) { std::string message = Translate("Got new friend requests: ") + str_count; TCHAR* tmessage = mir_a2t(message.c_str()); parent->NotifyEvent( parent->m_tszUserName, tmessage, NULL, FACEBOOK_EVENT_OTHER, TEXT(FACEBOOK_URL_REQUESTS) ); mir_free( tmessage ); } if (!DBGetContactSettingByte(NULL,parent->m_szModuleName,FACEBOOK_KEY_PARSE_MESSAGES, DEFAULT_PARSE_MESSAGES)) { str_count = utils::text::source_get_value( &resp.data, 2, "<span id=\"messagesCountValue\">", "</span>" ); if ( str_count.length() && str_count != std::string( "0" ) ) { std::string message = Translate("Got new messages: ") + str_count; TCHAR* tmessage = mir_a2t(message.c_str()); parent->NotifyEvent( parent->m_tszUserName, tmessage, NULL, FACEBOOK_EVENT_OTHER, TEXT(FACEBOOK_URL_MESSAGES) ); mir_free( tmessage ); } } str_count = utils::text::source_get_value( &resp.data, 2, "<span id=\"notificationsCountValue\">", "</span>" ); if ( str_count.length() && str_count != std::string( "0" ) ) { // Parse notifications directly to popups ForkThread( &FacebookProto::ProcessNotifications, this->parent, NULL ); } if (DBGetContactSettingByte(NULL, parent->m_szModuleName, FACEBOOK_KEY_ENABLE_GROUPCHATS, DEFAULT_ENABLE_GROUPCHATS)) { // Get group chats std::string favorites = utils::text::source_get_value( &resp.data, 2, "<div id=\"leftCol\"", "<div id=\"contentCol\"" ); std::string::size_type pos = 0; while ((pos = favorites.find("href=\"/groups/",pos)) != std::string::npos) { pos += 14; std::string item = favorites.substr(pos, favorites.find("</a>", pos) - pos); std::string id = item.substr(0, item.find("/")); if (!id.empty()) { std::string name = utils::text::source_get_value( &item, 3, "class=\"linkWrap", ">", "</div>" ); name = utils::text::special_expressions_decode(utils::text::slashu_to_utf8( name ) ); parent->Log(" Got new group chat: %s (id: %s)", name.c_str(), id.c_str()); if (!name.empty()) parent->AddChat(id.c_str(), name.c_str()); } } } return handle_success( "home" ); } case HTTP_CODE_FOUND: // Work-around for replica_down, f**king hell what's that? parent->Log(" REPLICA_DOWN is back in force!"); return this->home(); default: return handle_error( "home", FORCE_DISCONNECT ); } }
bool facebook_client::login(const std::string &username,const std::string &password) { handle_entry( "login" ); username_ = username; password_ = password; // Access homepage to get initial cookies flap( FACEBOOK_REQUEST_HOME, NULL ); // Prepare login data std::string data = "charset_test=%e2%82%ac%2c%c2%b4%2c%e2%82%ac%2c%c2%b4%2c%e6%b0%b4%2c%d0%94%2c%d0%84&locale=en&email="; data += utils::url::encode( username ); data += "&pass="******"&pass_placeHolder=Password&login=Login&persistent=1"; // Send validation http::response resp = flap( FACEBOOK_REQUEST_LOGIN, &data ); // Process result data validate_response(&resp); if ( resp.code == HTTP_CODE_FOUND && resp.headers.find("Location") != resp.headers.end() ) { // Check whether some Facebook things are required if ( resp.headers["Location"].find("help.php") != std::string::npos ) { client_notify( TranslateT("Login error: Some Facebook things are required.") ); parent->Log(" ! ! Login error: Some Facebook things are required."); // return handle_error( "login", FORCE_DISCONNECT ); } // Check whether setting Machine name is required if ( resp.headers["Location"].find("/checkpoint/") != std::string::npos ) { resp = flap( FACEBOOK_REQUEST_SETUP_MACHINE ); std::string inner_data = "machine_name=MirandaIM&submit[Save%20Device]=Save%20Device"; inner_data += "&post_form_id="; inner_data += utils::text::source_get_value(&resp.data, 3, "name=\"post_form_id\"", "value=\"", "\"" ); inner_data += "&lsd="; inner_data += utils::text::source_get_value(&resp.data, 3, "name=\"lsd\"", "value=\"", "\"" ); inner_data += "&nh="; inner_data += utils::text::source_get_value(&resp.data, 3, "name=\"nh\"", "value=\"", "\"" ); resp = flap( FACEBOOK_REQUEST_SETUP_MACHINE, &inner_data ); validate_response(&resp); } } if ( resp.code == HTTP_CODE_FOUND && resp.headers.find("Location") != resp.headers.end() ) { // Check whether HTTPS connection is required and we don't have enabled it if (!this->https_) { if ( resp.headers["Location"].find("https://") != std::string::npos ) { client_notify(TranslateT("Your account requires HTTPS connection. Activating.")); DBWriteContactSettingByte(NULL, parent->m_szModuleName, FACEBOOK_KEY_FORCE_HTTPS, 1); this->https_ = true; } } } // Check for Device ID if ( cookies["datr"].length() ) DBWriteContactSettingString( NULL, parent->m_szModuleName, FACEBOOK_KEY_DEVICE_ID, cookies["datr"].c_str() ); switch ( resp.code ) { case HTTP_CODE_FAKE_DISCONNECTED: { // When is error only because timeout, try login once more if ( handle_error( "login" ) ) return login(username, password); else return false; } case HTTP_CODE_OK: // OK page returned, but that is regular login page we don't want in fact { // Check whether captcha code is required if ( resp.data.find("id=\"captcha\"") != std::string::npos ) { client_notify( TranslateT("Login error: Captcha code is required. Bad login credentials?") ); parent->Log(" ! ! Login error: Captcha code is required."); return handle_error( "login", FORCE_DISCONNECT ); } // Get error message std::string error_str = utils::text::trim( utils::text::special_expressions_decode( utils::text::remove_html( utils::text::edit_html( utils::text::source_get_value( &resp.data, 2, "id=\"standard_error\">", "</h2>" ) ) ) ) ); if ( !error_str.length() ) error_str = Translate("Unknown login error"); parent->Log(" ! ! Login error: %s", error_str.c_str()); std::string message = Translate("Login error: ") + error_str; TCHAR* tmessage = mir_a2t(message.c_str()); client_notify( tmessage ); mir_free( tmessage ); } case HTTP_CODE_FORBIDDEN: // Forbidden case HTTP_CODE_NOT_FOUND: // Not Found default: return handle_error( "login", FORCE_DISCONNECT ); case HTTP_CODE_FOUND: // Found and redirected to Home, Logged in, everything is OK if ( cookies.find("c_user") != cookies.end() ) { this->self_.user_id = cookies.find("c_user")->second; DBWriteContactSettingString(NULL,parent->m_szModuleName,FACEBOOK_KEY_ID,this->self_.user_id.c_str()); parent->Log(" Got self user id: %s", this->self_.user_id.c_str()); return handle_success( "login" ); } else { client_notify(TranslateT("Login error, probably bad login credentials.")); parent->Log(" ! ! Login error, probably bad login credentials."); return handle_error( "login", FORCE_DISCONNECT ); } } }
bool facebook_client::send_message( std::string message_recipient, std::string message_text, std::string *error_text, bool use_inbox ) { handle_entry( "send_message" ); http::response resp; if (parent->isInvisible() || use_inbox) { // Use inbox send message when invisible std::string data = "action=send&body="; data += utils::url::encode( message_text ); data += "&recipients[0]="; data += message_recipient; data += "&lsd=&fb_dtsg="; data += ( dtsg_.length( ) ) ? dtsg_ : "0"; data += "&post_form_id="; data += ( post_form_id_.length( ) ) ? post_form_id_ : "0"; resp = flap( FACEBOOK_REQUEST_ASYNC, &data ); } else { // Use standard send message std::string data = "msg_text="; data += utils::url::encode( message_text ); data += "&msg_id="; data += utils::time::mili_timestamp( ); data += "%3A"; data += utils::time::unix_timestamp( ); data += "&to="; data += message_recipient; data += "&__user="******"&client_time="; data += utils::time::mili_timestamp( ); data += "&pvs_time&fb_dtsg="; data += ( dtsg_.length( ) ) ? dtsg_ : "0"; data += "&to_offline=false&to_idle=false&lsd&post_form_id_source=AsyncRequest&num_tabs=1"; data += "&window_id=0&sidebar_launched=false&sidebar_enabled=false&sidebar_capable=false&sidebar_should_show=false&sidebar_visible=false"; data += "&post_form_id="; data += ( post_form_id_.length( ) ) ? post_form_id_ : "0"; resp = flap( FACEBOOK_REQUEST_MESSAGE_SEND, &data ); } validate_response(&resp); *error_text = resp.error_text; switch ( resp.error_number ) { case 0: // Everything is OK break; //case 1356002: // You are offline - wtf?? case 1356003: // Contact is offline { HANDLE hContact = parent->ContactIDToHContact( message_recipient ); if (hContact != NULL) DBWriteContactSettingWord(hContact,parent->m_szModuleName,"Status",ID_STATUS_OFFLINE); return false; } break; case 1356026: // Contact has alternative client { client_notify(TranslateT("Need confirmation for sending messages to other clients.\nOpen facebook website and try to send message to this contact again!")); /* post na url http://www.facebook.com/ajax/chat/post_application_settings.php?__a=1 enable_and_send Povolit a odeslat to_send AQCoweMPeszBoKpd4iahcOyhmh0kiTYIhv1b5wCtuBiD0AaPVZIdEp3Pf5JMBmQ-9wf0ju-xdi-VRuk0ERk_I7XzI5dVJCs6-B0FExTZhspD-4-kTZLmZI-_M6fIuF2328yMyT3R3UEUmMV8P9MHcZwu-_pS3mOhsaHf6rIVcQ2rocSqLKi03wLKCfg0m8VsptPADWpOI-UNcIo-xl1PAoC1yVnL2wEXEtnF1qI_xFcmlJZ40AOONfIF_LS_lBrGYA-oCWLUK-GLHtQAHjO8aDeNXDU8Jk7Z_ES-_oAHee2PVLHcG_ACHXpasE7Iu3XFLMrdN2hjM96AjPRIf0Vk8gBZzfW_lUspakZmXxMI7iSNQE8lourK_6B3Z1s4UHxDZCNXYuc9gh70nm_xnaxnF9K1bR00s4MltnFjUT_3ypThzA __d 1 post_form_id c73ebd9d94b7449c40e6965410fcdcf6 fb_dtsg Tb-T9 lsd post_form_id_source AsyncRequest */ return false; } break; default: // Other error return false; } switch ( resp.code ) { case HTTP_CODE_OK: return handle_success( "send_message" ); case HTTP_CODE_FAKE_ERROR: case HTTP_CODE_FAKE_DISCONNECTED: default: *error_text = Translate("Timeout when sending message."); handle_error( "send_message" ); return false; } }
static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, int len) { int r = 0, notify_event = 0; assert(client); assert(client->event); assert(message); if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) { log_dhcp_client(client, "not a DHCP message: ignoring"); return 0; } if (message->op != BOOTREPLY) { log_dhcp_client(client, "not a BOOTREPLY message: ignoring"); return 0; } if (be32toh(message->xid) != client->xid) { log_dhcp_client(client, "received xid (%u) does not match " "expected (%u): ignoring", be32toh(message->xid), client->xid); return 0; } if (message->htype != ARPHRD_ETHER || message->hlen != ETHER_ADDR_LEN) { log_dhcp_client(client, "not an ethernet packet"); return 0; } if (memcmp(&message->chaddr[0], &client->client_id.mac_addr, ETH_ALEN)) { log_dhcp_client(client, "received chaddr does not match " "expected: ignoring"); return 0; } switch (client->state) { case DHCP_STATE_SELECTING: r = client_handle_offer(client, message, len); if (r >= 0) { client->timeout_resend = sd_event_source_unref(client->timeout_resend); client->state = DHCP_STATE_REQUESTING; client->attempt = 1; r = sd_event_add_time(client->event, &client->timeout_resend, CLOCK_MONOTONIC, 0, 0, client_timeout_resend, client); if (r < 0) goto error; r = sd_event_source_set_priority(client->timeout_resend, client->event_priority); if (r < 0) goto error; } else if (r == -ENOMSG) /* invalid message, let's ignore it */ return 0; break; case DHCP_STATE_REBOOTING: case DHCP_STATE_REQUESTING: case DHCP_STATE_RENEWING: case DHCP_STATE_REBINDING: r = client_handle_ack(client, message, len); if (r == DHCP_EVENT_NO_LEASE) { client->timeout_resend = sd_event_source_unref(client->timeout_resend); if (client->state == DHCP_STATE_REBOOTING) { r = client_initialize(client); if (r < 0) goto error; r = client_start(client); if (r < 0) goto error; log_dhcp_client(client, "REBOOTED"); } goto error; } else if (r >= 0) { client->timeout_resend = sd_event_source_unref(client->timeout_resend); if (IN_SET(client->state, DHCP_STATE_REQUESTING, DHCP_STATE_REBOOTING)) notify_event = DHCP_EVENT_IP_ACQUIRE; else if (r != DHCP_EVENT_IP_ACQUIRE) notify_event = r; client->state = DHCP_STATE_BOUND; client->attempt = 1; client->last_addr = client->lease->address; r = client_set_lease_timeouts(client); if (r < 0) goto error; if (notify_event) { client = client_notify(client, notify_event); if (!client || client->state == DHCP_STATE_STOPPED) return 0; } client->receive_message = sd_event_source_unref(client->receive_message); client->fd = asynchronous_close(client->fd); } else if (r == -ENOMSG) /* invalid message, let's ignore it */ return 0; break; case DHCP_STATE_INIT: case DHCP_STATE_INIT_REBOOT: case DHCP_STATE_BOUND: break; case DHCP_STATE_STOPPED: r = -EINVAL; goto error; } error: if (r < 0 || r == DHCP_EVENT_NO_LEASE) client_stop(client, r); return r; }
bool facebook_client::home() { handle_entry("home"); // get fb_dtsg http::response resp = flap(REQUEST_DTSG); // Check whether HTTPS connection is required and we don't have it enabled if (!this->https_ && resp.headers["Location"].find("https://") != std::string::npos) { client_notify(TranslateT("Your account requires HTTPS connection. Activating.")); parent->setByte(FACEBOOK_KEY_FORCE_HTTPS, 1); this->https_ = true; return home(); } this->dtsg_ = utils::text::source_get_value(&resp.data, 3, "name=\"fb_dtsg\"", "value=\"", "\""); parent->debugLogA(" Got self dtsg: %s", this->dtsg_.c_str()); if (this->dtsg_.empty()) return false; resp = flap(REQUEST_HOME); switch (resp.code) { case HTTP_CODE_OK: { // Get real name this->self_.real_name = utils::text::source_get_value(&resp.data, 2, "<strong class=\"profileName\">", "</strong>"); // Try to get name again, if we've got some some weird version of Facebook if (this->self_.real_name.empty()) this->self_.real_name = utils::text::source_get_value(&resp.data, 4, "id=\"root", "<strong", ">", "</strong>"); // Get and strip optional nickname std::string::size_type pos = this->self_.real_name.find("<span class=\"alternate_name\">"); if (pos != std::string::npos) { this->self_.nick = utils::text::source_get_value(&this->self_.real_name, 2, "<span class=\"alternate_name\">(", ")</span>"); parent->debugLogA(" Got self nick name: %s", this->self_.nick.c_str()); this->self_.real_name = this->self_.real_name.substr(0, pos - 1); } parent->debugLogA(" Got self real name: %s", this->self_.real_name.c_str()); if (this->self_.real_name.empty()) { client_notify(TranslateT("Something happened to Facebook. Maybe there was some major update so you should wait for an update.")); return handle_error("home", FORCE_QUIT); } // Save name and nickname parent->SaveName(NULL, &this->self_); // Get avatar this->self_.image_url = utils::text::source_get_value(&resp.data, 3, "class=\"l\"", "<img src=\"", "\""); parent->debugLogA(" Got self avatar: %s", this->self_.image_url.c_str()); parent->CheckAvatarChange(NULL, this->self_.image_url); // Get logout hash this->logout_hash_ = utils::text::source_get_value2(&resp.data, "/logout.php?h=", "&\""); parent->debugLogA(" Got self logout hash: %s", this->logout_hash_.c_str()); return handle_success("home"); } case HTTP_CODE_FOUND: // Work-around for replica_down, f**king hell what's that? parent->debugLogA(" REPLICA_DOWN is back in force!"); return this->home(); default: return handle_error("home", FORCE_QUIT); } }
bool facebook_client::login(const char *username, const char *password) { handle_entry("login"); username_ = username; password_ = password; if (cookies.empty()) { // Set device ID ptrA device( parent->getStringA(FACEBOOK_KEY_DEVICE_ID)); if (device != NULL) cookies["datr"] = device; // Get initial cookies flap(REQUEST_HOME); } // Prepare login data std::string data = "persistent=1"; data += "&email=" + utils::url::encode(username); data += "&pass="******"&locale=" + std::string(locale); // Send validation http::response resp = flap(REQUEST_LOGIN, &data); // Save Device ID if (!cookies["datr"].empty()) parent->setString(FACEBOOK_KEY_DEVICE_ID, cookies["datr"].c_str()); if (resp.code == HTTP_CODE_FOUND && resp.headers.find("Location") != resp.headers.end()) { // Check for invalid requests if (resp.headers["Location"].find("invalid_request.php") != std::string::npos) { client_notify(TranslateT("Login error: Invalid request.")); parent->debugLogA(" ! ! Login error: Invalid request."); return handle_error("login", FORCE_QUIT); } // Check whether some Facebook things are required if (resp.headers["Location"].find("help.php") != std::string::npos) { client_notify(TranslateT("Login error: Some Facebook things are required.")); parent->debugLogA(" ! ! Login error: Some Facebook things are required."); // return handle_error("login", FORCE_QUIT); } // Check whether setting Machine name is required if (resp.headers["Location"].find("/checkpoint/") != std::string::npos) { resp = flap(REQUEST_SETUP_MACHINE, NULL, NULL, REQUEST_GET); if (resp.data.find("login_approvals_no_phones") != std::string::npos) { // Code approval - but no phones in account loginError(parent, utils::text::source_get_value(&resp.data, 4, "login_approvals_no_phones", "<div", ">", "</div>")); return handle_error("login", FORCE_QUIT); } std::string inner_data; if (resp.data.find("name=\"submit[Continue]\"") != std::string::npos) { // Check if we need to approve also last unapproved device if (resp.data.find("name=\"name_action_selected\"") == std::string::npos) { // 1) Continue inner_data = "submit[Continue]=Continue"; inner_data += "&nh=" + utils::text::source_get_value(&resp.data, 3, "name=\"nh\"", "value=\"", "\""); inner_data += "&fb_dtsg=" + utils::text::source_get_value(&resp.data, 3, "name=\"fb_dtsg\"", "value=\"", "\""); resp = flap(REQUEST_SETUP_MACHINE, &inner_data); // 2) Approve last unknown login // inner_data = "submit[I%20don't%20recognize]=I%20don't%20recognize"; // Don't recognize - this will force to change account password inner_data = "submit[This%20is%20Okay]=This%20is%20Okay"; // Recognize inner_data += "&nh=" + utils::text::source_get_value(&resp.data, 3, "name=\"nh\"", "value=\"", "\""); inner_data += "&fb_dtsg=" + utils::text::source_get_value(&resp.data, 3, "name=\"fb_dtsg\"", "value=\"", "\""); resp = flap(REQUEST_SETUP_MACHINE, &inner_data); // 3) Save last device inner_data = "submit[Continue]=Continue"; inner_data += "&nh=" + utils::text::source_get_value(&resp.data, 3, "name=\"nh\"", "value=\"", "\""); inner_data += "&fb_dtsg=" + utils::text::source_get_value(&resp.data, 3, "name=\"fb_dtsg\"", "value=\"", "\""); inner_data += "&name_action_selected=save_device"; // Save device - or "dont_save" resp = flap(REQUEST_SETUP_MACHINE, &inner_data); } // Save this actual device inner_data = "submit[Continue]=Continue"; inner_data += "&nh=" + utils::text::source_get_value(&resp.data, 3, "name=\"nh\"", "value=\"", "\""); inner_data += "&fb_dtsg=" + utils::text::source_get_value(&resp.data, 3, "name=\"fb_dtsg\"", "value=\"", "\""); inner_data += "&name_action_selected=save_device"; // Save device - or "dont_save" resp = flap(REQUEST_SETUP_MACHINE, &inner_data); } // Save actual machine name // inner_data = "machine_name=Miranda%20NG&submit[Don't%20Save]=Don't%20Save"; // Don't save inner_data = "machine_name=Miranda%20NG&submit[Save%20Device]=Save%20Device"; // Save inner_data += "&lsd=" + utils::text::source_get_value(&resp.data, 3, "name=\"lsd\"", "value=\"", "\""); inner_data += "&nh=" + utils::text::source_get_value(&resp.data, 3, "name=\"nh\"", "value=\"", "\""); inner_data += "&fb_dtsg=" + utils::text::source_get_value(&resp.data, 3, "name=\"fb_dtsg\"", "value=\"", "\""); resp = flap(REQUEST_SETUP_MACHINE, &inner_data); } } switch (resp.code) { case HTTP_CODE_FAKE_DISCONNECTED: { // When is error only because timeout, try login once more if (handle_error("login")) return login(username, password); else return handle_error("login", FORCE_QUIT); } case HTTP_CODE_OK: // OK page returned, but that is regular login page we don't want in fact { // Check whether captcha code is required if (resp.data.find("id=\"captcha\"") != std::string::npos) { client_notify(TranslateT("Login error: Captcha code is required. Bad login credentials?")); parent->debugLogA(" ! ! Login error: Captcha code is required."); return handle_error("login", FORCE_QUIT); } // Get and notify error message loginError(parent, utils::text::source_get_value(&resp.data, 4, "login_error_box", "<div", ">", "</div>")); } case HTTP_CODE_FORBIDDEN: // Forbidden case HTTP_CODE_NOT_FOUND: // Not Found default: return handle_error("login", FORCE_QUIT); case HTTP_CODE_FOUND: // Found and redirected to Home, Logged in, everything is OK { if (cookies.find("c_user") != cookies.end()) { this->self_.user_id = cookies.find("c_user")->second; parent->setString(FACEBOOK_KEY_ID, this->self_.user_id.c_str()); parent->debugLogA(" Got self user id: %s", this->self_.user_id.c_str()); return handle_success("login"); } else { client_notify(TranslateT("Login error, probably bad login credentials.")); parent->debugLogA(" ! ! Login error, probably bad login credentials."); return handle_error("login", FORCE_QUIT); } } } }
http::response facebook_client::flap(RequestType request_type, std::string* request_data, std::string* request_get_data, int method) { NETLIBHTTPREQUEST nlhr = {sizeof(NETLIBHTTPREQUEST)}; nlhr.requestType = !method ? choose_method(request_type) : method; std::string url = choose_proto(request_type); url.append(choose_server(request_type, request_data, request_get_data)); url.append(choose_action(request_type, request_data, request_get_data)); nlhr.szUrl = (char*)url.c_str(); nlhr.flags = NLHRF_HTTP11 | choose_security_level(request_type); nlhr.headers = get_request_headers(nlhr.requestType, &nlhr.headersCount); #ifdef _DEBUG nlhr.flags |= NLHRF_DUMPASTEXT; #else nlhr.flags |= NLHRF_NODUMP; #endif switch (request_type) { case REQUEST_MESSAGES_RECEIVE: nlhr.timeout = 1000 * 65; break; default: nlhr.timeout = 1000 * 20; break; } if (request_data != NULL) { nlhr.pData = (char*)(*request_data).c_str(); nlhr.dataLength = (int)request_data->length(); } parent->debugLogA("@@@@@ Sending request to '%s'", nlhr.szUrl); switch (request_type) { case REQUEST_LOGIN: nlhr.nlc = NULL; break; case REQUEST_MESSAGES_RECEIVE: nlhr.nlc = hMsgCon; nlhr.flags |= NLHRF_PERSISTENT; break; default: WaitForSingleObject(fcb_conn_lock_, INFINITE); nlhr.nlc = hFcbCon; nlhr.flags |= NLHRF_PERSISTENT; break; } NETLIBHTTPREQUEST* pnlhr = (NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION, (WPARAM)handle_, (LPARAM)&nlhr); mir_free(nlhr.headers[3].szValue); mir_free(nlhr.headers); http::response resp; switch (request_type) { case REQUEST_LOGIN: case REQUEST_SETUP_MACHINE: break; case REQUEST_MESSAGES_RECEIVE: hMsgCon = pnlhr ? pnlhr->nlc : NULL; break; default: ReleaseMutex(fcb_conn_lock_); hFcbCon = pnlhr ? pnlhr->nlc : NULL; break; } if (pnlhr != NULL) { parent->debugLogA("@@@@@ Got response with code %d", pnlhr->resultCode); store_headers(&resp, pnlhr->headers, pnlhr->headersCount); resp.code = pnlhr->resultCode; resp.data = pnlhr->pData ? pnlhr->pData : ""; CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT, 0, (LPARAM)pnlhr); } else { parent->debugLogA("!!!!! No response from server (time-out)"); resp.code = HTTP_CODE_FAKE_DISCONNECTED; // Better to have something set explicitely as this value is compaired in all communication requests } // Get Facebook's error message if (resp.code == HTTP_CODE_OK) { std::string::size_type pos = resp.data.find("\"error\":"); if (pos != std::string::npos) { pos += 8; int error_num = atoi(resp.data.substr(pos, resp.data.find(",", pos) - pos).c_str()); if (error_num != 0) { std::string error = ""; pos = resp.data.find("\"errorDescription\":\"", pos); if (pos != std::string::npos) { pos += 20; error = resp.data.substr(pos, resp.data.find("\"", pos) - pos); error = utils::text::trim(utils::text::special_expressions_decode(utils::text::slashu_to_utf8(error))); error = ptrA( mir_utf8decodeA(error.c_str())); } std::string title = ""; pos = resp.data.find("\"errorSummary\":\"", pos); if (pos != std::string::npos) { pos += 16; title = resp.data.substr(pos, resp.data.find("\"", pos) - pos); title = utils::text::trim(utils::text::special_expressions_decode(utils::text::slashu_to_utf8(title))); title = ptrA( mir_utf8decodeA(title.c_str())); } bool silent = resp.data.find("\"silentError\":1") != std::string::npos; resp.error_number = error_num; resp.error_text = error; resp.error_title = title; resp.code = HTTP_CODE_FAKE_ERROR; parent->debugLogA(" ! ! Received Facebook error: %d -- %s", error_num, error.c_str()); if (notify_errors(request_type) && !silent) client_notify(_A2T(error.c_str())); } } } return resp; }
bool facebook_client::send_message(MCONTACT hContact, std::string message_recipient, std::string message_text, std::string *error_text, MessageMethod method) { ScopedLock s(send_message_lock_); handle_entry("send_message"); http::response resp; switch (method) { case MESSAGE_INBOX: { parent->debugLogA(" > Sending message through INBOX"); std::string data = "action=send"; data += "&body=" + utils::url::encode(message_text); data += "&recipients[0]=" + message_recipient; data += "&__user="******"&__a=1"; data += "&fb_dtsg=" + (!dtsg_.empty() ? dtsg_ : "0"); data += "&phstamp=0"; resp = flap(REQUEST_MESSAGE_SEND2, &data); break; } case MESSAGE_MERCURY: { parent->debugLogA(" > Sending message through CHAT"); std::string data = "message_batch[0][action_type]=ma-type:user-generated-message"; data += "&message_batch[0][thread_id]"; data += "&message_batch[0][author]=fbid:" + this->self_.user_id; data += "&message_batch[0][author_email]"; data += "&message_batch[0][coordinates]"; data += "&message_batch[0][timestamp]=" + utils::time::mili_timestamp(); data += "&message_batch[0][timestamp_absolute]"; data += "&message_batch[0][timestamp_relative]"; data += "&message_batch[0][is_unread]=false"; data += "&message_batch[0][is_cleared]=false"; data += "&message_batch[0][is_forward]=false"; data += "&message_batch[0][spoof_warning]=false"; data += "&message_batch[0][source]=source:chat:web"; data += "&message_batch[0][source_tags][0]=source:chat"; data += "&message_batch[0][body]=" + utils::url::encode(message_text); data += "&message_batch[0][has_attachment]=false"; data += "&message_batch[0][html_body]=false"; data += "&message_batch[0][specific_to_list][0]=fbid:" + message_recipient; data += "&message_batch[0][specific_to_list][1]=fbid:" + this->self_.user_id; data += "&message_batch[0][status]=0"; data += "&message_batch[0][message_id]"; data += "&message_batch[0][client_thread_id]=user:"******"&client=mercury"; data += "&fb_dtsg=" + (!dtsg_.empty() ? dtsg_ : "0"); data += "&__user="******"&__a=1"; data += "&phstamp=0"; resp = flap(REQUEST_MESSAGE_SEND, &data); break; } case MESSAGE_TID: { parent->debugLogA(" > Sending message through MERCURY (TID)"); std::string data = "message_batch[0][action_type]=ma-type:user-generated-message"; data += "&message_batch[0][thread_id]=" + message_recipient; data += "&message_batch[0][author]=fbid:" + this->self_.user_id; data += "&message_batch[0][timestamp]=" + utils::time::mili_timestamp(); data += "&message_batch[0][timestamp_absolute]="; data += "&message_batch[0][timestamp_relative]="; data += "&message_batch[0][is_unread]=false"; data += "&message_batch[0][is_cleared]=false"; data += "&message_batch[0][is_forward]=false"; data += "&message_batch[0][source]=source:chat:web"; data += "&message_batch[0][body]=" + utils::url::encode(message_text); data += "&message_batch[0][has_attachment]=false"; data += "&message_batch[0][is_html]=false"; data += "&message_batch[0][message_id]="; data += "&fb_dtsg=" + (!dtsg_.empty() ? dtsg_ : "0"); data += "&__user="******"&phstamp=0"; resp = flap(REQUEST_MESSAGE_SEND, &data); break; } case MESSAGE_ASYNC: { parent->debugLogA(" > Sending message through ASYNC"); std::string data = "action=send"; data += "&body=" + utils::url::encode(message_text); data += "&recipients[0]=" + message_recipient; data += "&lsd="; data += "&fb_dtsg=" + (!dtsg_.empty() ? dtsg_ : "0"); resp = flap(REQUEST_ASYNC, &data); break; } } *error_text = resp.error_text; switch (resp.error_number) { case 0: // Everything is OK { // Remember this message id std::string mid = utils::text::source_get_value(&resp.data, 2, "\"message_id\":\"", "\""); parent->setString(hContact, FACEBOOK_KEY_MESSAGE_ID, mid.c_str()); messages_ignore.insert(std::make_pair(mid, false)); } break; //case 1356002: // You are offline - wtf?? case 1356003: // Contact is offline { MCONTACT hContact = parent->ContactIDToHContact(message_recipient); if (hContact != NULL) parent->setWord(hContact, "Status", ID_STATUS_OFFLINE); return false; } break; case 1356026: // Contact has alternative client { client_notify(TranslateT("Need confirmation for sending messages to other clients.\nOpen Facebook website and try to send message to this contact again!")); return false; } break; default: // Other error parent->debugLogA(" !!! Send message error #%d: %s", resp.error_number, resp.error_text); return false; } switch (resp.code) { case HTTP_CODE_OK: return handle_success("send_message"); case HTTP_CODE_FAKE_ERROR: case HTTP_CODE_FAKE_DISCONNECTED: default: *error_text = Translate("Timeout when sending message."); handle_error("send_message"); return false; } }