static void om_login(PurpleAccount *account) { PurpleBuddy *bud; OmegleAccount *oma; //make sure there's an Omegle buddy on the buddy list bud = purple_find_buddy(account, "omegle"); if (bud == NULL) { bud = purple_buddy_new(account, "omegle", "Omegle"); purple_blist_add_buddy(bud, NULL, NULL, NULL); } purple_prpl_got_user_status(account, "omegle", purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL); oma = g_new0(OmegleAccount, 1); oma->account = account; oma->pc = purple_account_get_connection(account); oma->cookie_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); oma->hostname_ip_cache = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); account->gc->proto_data = oma; //No such thing as a login purple_connection_set_state(purple_account_get_connection(account), PURPLE_CONNECTED); }
static void skypeweb_login_did_auth(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message) { gchar *refresh_token; SkypeWebAccount *sa = user_data; if (url_text == NULL) { url_text = url_data->webdata; len = url_data->data_len; } refresh_token = skypeweb_string_get_chunk(url_text, len, "=\"skypetoken\" value=\"", "\""); if (refresh_token == NULL) { purple_debug_info("skypeweb", "login response was %s\r\n", url_text); purple_connection_error(sa->pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Failed getting Skype Token")); return; } sa->skype_token = refresh_token; skypeweb_update_cookies(sa, url_text); purple_connection_set_state(sa->pc, PURPLE_CONNECTED); skypeweb_do_all_the_things(sa); }
void skypeweb_do_all_the_things(SkypeWebAccount *sa) { if (!sa->username) { skypeweb_get_self_details(sa); } else if (sa->registration_token) { skypeweb_get_self_details(sa); if (sa->authcheck_timeout) purple_timeout_remove(sa->authcheck_timeout); skypeweb_check_authrequests(sa); sa->authcheck_timeout = purple_timeout_add_seconds(120, (GSourceFunc)skypeweb_check_authrequests, sa); purple_connection_set_state(sa->pc, PURPLE_CONNECTION_CONNECTED); skypeweb_get_friend_list(sa); skypeweb_poll(sa); skype_web_get_offline_history(sa); skypeweb_set_status(sa->account, purple_account_get_active_status(sa->account)); } else { //Too soon! skypeweb_get_registration_token(sa); } }
void msn_session_finish_login(MsnSession *session) { PurpleAccount *account; PurpleConnection *gc; PurpleImage *img; if (!session->logged_in) { account = session->account; gc = purple_account_get_connection(account); img = purple_buddy_icons_find_account_icon(session->account); /* TODO: Do we really want to call this if img is NULL? */ msn_user_set_buddy_icon(session->user, img); if (img != NULL) g_object_unref(img); session->logged_in = TRUE; purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED); /* Sync users */ msn_session_sync_users(session); } /* TODO: Send this when updating status instead? */ msn_notification_send_uux_endpointdata(session); msn_notification_send_uux_private_endpointdata(session); msn_change_status(session); }
static void fb_login(PurpleAccount *account) { FacebookAccount *fba; gchar *postdata, *encoded_username, *encoded_password, *encoded_charset_test; const gchar* const *languages; const gchar *locale; /* Create account and initialize state */ fba = g_new0(FacebookAccount, 1); fba->account = account; fba->pc = purple_account_get_connection(account); fba->uid = -1; fba->last_messages_download_time = time(NULL) - 60; /* 60 secs is a safe buffer */ fba->cookie_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); fba->hostname_ip_cache = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); fba->sent_messages_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); fba->auth_buddies = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); g_hash_table_replace(fba->cookie_table, g_strdup("test_cookie"), g_strdup("1")); account->gc->proto_data = fba; /* Error localized in libpurple jabber.c */ if (!purple_ssl_is_supported()) { purple_connection_error_reason (purple_account_get_connection(account), PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT, _("Server requires TLS/SSL for login. No TLS/SSL support found.")); return; } purple_connection_set_state(fba->pc, PURPLE_CONNECTING); purple_connection_update_progress(fba->pc, _("Connecting"), 1, 3); encoded_username = g_strdup(purple_url_encode( purple_account_get_username(fba->account))); encoded_password = g_strdup(purple_url_encode( purple_account_get_password(fba->account))); encoded_charset_test = g_strdup(purple_url_encode("€,´,€,´,水,Д,Є")); languages = g_get_language_names(); locale = languages[0]; if (locale == NULL || g_str_equal(locale, "C")) locale = "en_US"; g_hash_table_replace(fba->cookie_table, g_strdup("lsd"), g_strdup("abcde")); postdata = g_strdup_printf( "charset_test=%s&locale=%s&email=%s&pass=%s&pass_placeHolder=Password&persistent=1&login=Login&charset_test=%s&lsd=abcde", encoded_charset_test, locale, encoded_username, encoded_password, encoded_charset_test); g_free(encoded_username); g_free(encoded_password); g_free(encoded_charset_test); fb_post_or_get(fba, FB_METHOD_POST | FB_METHOD_SSL, "login.facebook.com", "/login.php?login_attempt=1&_fb_noscript=1", postdata, fb_login_cb, NULL, FALSE); g_free(postdata); }
void hangouts_auth_get_session_cookies_got_cb(PurpleHttpConnection *http_conn, PurpleHttpResponse *response, gpointer user_data) { HangoutsAccount *ha = user_data; guint64 last_event_timestamp; gchar *sapisid_cookie = purple_http_cookie_jar_get(ha->cookie_jar, "SAPISID"); if (sapisid_cookie == NULL) { purple_connection_error(ha->pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("SAPISID Cookie not received")); return; } //Restore the last_event_timestamp before it gets overridden by new events last_event_timestamp = purple_account_get_int(ha->account, "last_event_timestamp_high", 0); if (last_event_timestamp != 0) { last_event_timestamp = (last_event_timestamp << 32) | ((guint64) purple_account_get_int(ha->account, "last_event_timestamp_low", 0) & 0xFFFFFFFF); ha->last_event_timestamp = last_event_timestamp; } // SOUND THE TRUMPETS hangouts_fetch_channel_sid(ha); purple_connection_set_state(ha->pc, PURPLE_CONNECTION_CONNECTED); //TODO trigger event instead hangouts_get_self_info(ha); hangouts_get_conversation_list(ha); g_free(sapisid_cookie); }
void msn_session_finish_login(MsnSession *session) { PurpleAccount *account; PurpleConnection *gc; PurpleStoredImage *img; if (!session->logged_in) { account = session->account; gc = purple_account_get_connection(account); img = purple_buddy_icons_find_account_icon(session->account); /* TODO: Do we really want to call this if img is NULL? */ msn_user_set_buddy_icon(session->user, img); if (img != NULL) purple_imgstore_unref(img); session->logged_in = TRUE; purple_connection_set_state(gc, PURPLE_CONNECTED); /* Sync users */ msn_session_sync_users(session); } msn_change_status(session); }
static void np_login(PurpleAccount *account) { PurpleConnection *gc; NPSession *session; PurplePresence *presence; const char *host; gboolean http_method = FALSE; int port; purple_debug_warning("np","\n===> %p ",account); purple_debug_warning("np","account->alias = %s\n",account->alias); purple_debug_warning("np","account->username = %s\n",account->username); purple_debug_warning("np","account->password = %s\n",account->password); purple_debug_warning("np","account->user_info = %s\n",account->user_info); g_return_if_fail(account != NULL); session = np_session_new(account); gc = purple_account_get_connection(account); g_return_if_fail(gc != NULL); const char *http_server = purple_account_get_string(session->account, "http_method_server", NP_HTTPCONN_SERVER); purple_debug_info("np", "http_server: %s",http_server); purple_connection_set_state(gc, PURPLE_CONNECTING); purple_connection_update_progress(gc, _("Connecting"), 1, 3); np_http_login0(session, np_http_login0_cb); return; /* host = purple_account_get_string(account, "server", NP_IM_SERVER); port = purple_account_get_int(account, "port", NP_IM_PORT); session = np_session_new(account); purple_debug_warning("np","=====> session : %p ",session); gc = purple_account_get_connection(account); g_return_if_fail(gc != NULL); gc->proto_data = session; gc->flags |= PURPLE_CONNECTION_HTML | PURPLE_CONNECTION_NO_BGCOLOR | PURPLE_CONNECTION_AUTO_RESP; np_session_set_login_step(session, NP_LOGIN_STEP_START); presence = purple_account_get_presence(account); if (!np_session_connect(session, host, port, http_method)) purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect")); */ }
void skypeweb_begin_oauth_login(SkypeWebAccount *sa) { const gchar *login_url = "https://" SKYPEWEB_LOGIN_HOST "/login/oauth/microsoft?client_id=578134&redirect_uri=https%3A%2F%2Fweb.skype.com"; purple_util_fetch_url_request(sa->account, login_url, TRUE, NULL, FALSE, NULL, TRUE, 524288, skypeweb_login_got_ppft, sa); purple_connection_set_state(sa->pc, PURPLE_CONNECTION_CONNECTING); purple_connection_update_progress(sa->pc, _("Connecting"), 1, 4); }
void _purple_connection_new_unregister(PurpleAccount *account, const char *password, PurpleAccountUnregistrationCb cb, void *user_data) { /* Lots of copy/pasted code to avoid API changes. You might want to integrate that into the previous function when posssible. */ PurpleConnection *gc; PurplePlugin *prpl; PurplePluginProtocolInfo *prpl_info; g_return_if_fail(account != NULL); prpl = purple_find_prpl(purple_account_get_protocol_id(account)); if (prpl != NULL) prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(prpl); else { gchar *message; message = g_strdup_printf(_("Missing protocol plugin for %s"), purple_account_get_username(account)); purple_notify_error(NULL, _("Unregistration Error"), message, NULL); g_free(message); return; } if (!purple_account_is_disconnected(account)) { prpl_info->unregister_user(account, cb, user_data); return; } if (((password == NULL) || (*password == '\0')) && !(prpl_info->options & OPT_PROTO_NO_PASSWORD) && !(prpl_info->options & OPT_PROTO_PASSWORD_OPTIONAL)) { purple_debug_error("connection", "Cannot connect to account %s without " "a password.\n", purple_account_get_username(account)); return; } gc = g_new0(PurpleConnection, 1); PURPLE_DBUS_REGISTER_POINTER(gc, PurpleConnection); gc->prpl = prpl; if ((password != NULL) && (*password != '\0')) gc->password = g_strdup(password); purple_connection_set_account(gc, account); purple_connection_set_state(gc, PURPLE_CONNECTING); connections = g_list_append(connections, gc); purple_account_set_connection(account, gc); purple_signal_emit(purple_connections_get_handle(), "signing-on", gc); purple_debug_info("connection", "Unregistering. gc = %p\n", gc); prpl_info->unregister_user(account, cb, user_data); }
static void stress_login(PurpleAccount *account) { PurpleConnection *pc = NULL; PurpleGroup *g = NULL; gint n_buddies = 0, i = 0, interval = 0, maxevents = 0; /* build our possible events from the account settings */ add_event("trigger_signon", STRESS_EVENT_SIGN_ON, STRESS_EVENT_SIGN_OFF); add_event("trigger_idle", STRESS_EVENT_IDLE, STRESS_EVENT_UNIDLE); add_event("trigger_away", STRESS_EVENT_AWAY, STRESS_EVENT_BACK); add_event("trigger_typing", STRESS_EVENT_TYPING, STRESS_EVENT_STOPPED_TYPING); add_event("send_messages", STRESS_EVENT_SEND_MESSAGE, -1); nevents = g_list_length(events); /* get our connection and set it as online */ pc = purple_account_get_connection(account); purple_connection_set_state(pc, PURPLE_CONNECTED); /* grab the account settings we need for buddies */ n_buddies = purple_account_get_int(account, "nbuddies", 50); maxevents = purple_account_get_int(account, "maxevents", 100); interval = (guint)purple_account_get_int(account, "interval", 500); message_min = purple_account_get_int(account, "message_min", 16); message_max = purple_account_get_int(account, "message_max", 128); g = purple_group_new("prpl-stress"); for(i = 0; i < n_buddies; i++) { PurpleBuddy *b = NULL; StressBuddy *sb = NULL; gchar *name = NULL; /* create the buddy and it's name */ name = g_strdup_printf("stress-%04x", i); b = purple_buddy_new(account, name, NULL); g_free(name); /* add our data to the buddy */ sb = g_new0(StressBuddy, 1); sb->buddy = b; sb->maxevents = maxevents; purple_buddy_set_protocol_data(b, sb); /* add the buddy to our list and the purple blist */ buddies = g_list_prepend(buddies, sb); purple_blist_add_buddy(b, NULL, g, NULL); /* add our event timer to the buddy */ sb->timer_id = g_timeout_add(interval, stress_event_cb, sb); } }
static void campfire_login(PurpleAccount * account) { /*don't really login (it's stateless), but init the CampfireConn */ PurpleConnection *gc = purple_account_get_connection(account); const char *username = purple_account_get_username(account); CampfireConn *conn; char *pos; PurpleCmdFlag f = PURPLE_CMD_FLAG_CHAT | PURPLE_CMD_FLAG_PRPL_ONLY; gchar *prpl_id = "prpl-analog_g-campfire"; /* analog_g = developer.pidgin.im Trac username */ conn = g_new0(CampfireConn, 1); purple_debug_info("campfire", "num_xaction_malloc:%d: num_xaction_free:%d\n", conn->num_xaction_malloc, conn->num_xaction_free); conn->gc = gc; conn->account = account; /* Find the last '@'; usernames can have '@' in them. */ pos = strrchr(username, '@'); conn->hostname = g_strdup(pos+1); pos[0] = 0; purple_connection_set_display_name(gc, username); pos[0] = '@'; purple_debug_info("campfire", "username: %s\n", username); purple_debug_info("campfire", "hostname: %s\n", conn->hostname); gc->proto_data = conn; /*register campfire commands */ purple_cmd_register(CAMPFIRE_CMD_ME, "s", PURPLE_CMD_P_PRPL, f, prpl_id, campfire_parse_cmd, "me <action to perform>: Perform an action.", conn); purple_cmd_register(CAMPFIRE_CMD_TOPIC, "s", PURPLE_CMD_P_PRPL, f | PURPLE_CMD_FLAG_ALLOW_WRONG_ARGS, prpl_id, campfire_parse_cmd, "topic <new topic>: Change the room topic.", conn); purple_cmd_register(CAMPFIRE_CMD_ROOM, "s", PURPLE_CMD_P_PRPL, f, prpl_id, campfire_parse_cmd, "room <new room name>: Change the room name (admin only).", conn); purple_cmd_register(CAMPFIRE_CMD_PLAY, "w", PURPLE_CMD_P_PRPL, f, prpl_id, campfire_parse_cmd, "play <sound>: Play a sound (trombone, rimshot, crickets, live).", conn); purple_connection_set_state(gc, PURPLE_CONNECTED); }
static void tgprpl_login (PurpleAccount * acct) { debug ("tgprpl_login()\n"); PurpleConnection *gc = purple_account_get_connection(acct); char const *username = purple_account_get_username(acct); struct tgl_state *TLS = tgl_state_alloc (); const char *dir = config_dir; struct passwd *pw = getpwuid(getuid()); size_t len = strlen (dir) + strlen (pw->pw_dir) + 2 + strlen (username); TLS->base_path = malloc (len); snprintf (TLS->base_path, len, "%s/%s/%s", pw->pw_dir, dir, username); debug ("base configuration path: '%s'", TLS->base_path); g_mkdir_with_parents(TLS->base_path, 0700); len += strlen ("/downloads"); char *ddir = malloc (len); sprintf (ddir, "%s/downloads", TLS->base_path); tgl_set_download_directory (TLS, ddir); g_mkdir_with_parents(ddir, 0700); free (ddir); tgl_set_verbosity (TLS, 4); tgl_set_rsa_key (TLS, pk_path); // create handle to store additional info for libpurple in // the new telegram instance telegram_conn *conn = g_new0(telegram_conn, 1); conn->TLS = TLS; conn->gc = gc; conn->pa = acct; conn->new_messages = g_queue_new (); conn->joining_chats = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); purple_connection_set_protocol_data (gc, conn); tgl_set_ev_base (TLS, conn); tgl_set_net_methods (TLS, &tgp_conn_methods); tgl_set_timer_methods (TLS, &tgp_timers); tgl_set_callback (TLS, &tgp_callback); tgl_register_app_id (TLS, TGP_APP_ID, TGP_APP_HASH); tgl_init (TLS); purple_connection_set_state (conn->gc, PURPLE_CONNECTING); telegram_login (TLS); }
static void irc_connected(struct irc_conn *irc, const char *nick) { PurpleConnection *gc; PurpleStatus *status; PurpleBlistNode *gnode, *cnode, *bnode; if ((gc = purple_account_get_connection(irc->account)) == NULL || PURPLE_CONNECTION_IS_CONNECTED(gc)) return; purple_connection_set_display_name(gc, nick); purple_connection_set_state(gc, PURPLE_CONNECTED); /* If we're away then set our away message */ status = purple_account_get_active_status(irc->account); if (!purple_status_get_type(status) != PURPLE_STATUS_AVAILABLE) { PurplePluginProtocolInfo *prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(gc->prpl); prpl_info->set_status(irc->account, status); } /* this used to be in the core, but it's not now */ for (gnode = purple_get_blist()->root; gnode; gnode = gnode->next) { if(!PURPLE_BLIST_NODE_IS_GROUP(gnode)) continue; for(cnode = gnode->child; cnode; cnode = cnode->next) { if(!PURPLE_BLIST_NODE_IS_CONTACT(cnode)) continue; for(bnode = cnode->child; bnode; bnode = bnode->next) { PurpleBuddy *b; if(!PURPLE_BLIST_NODE_IS_BUDDY(bnode)) continue; b = (PurpleBuddy *)bnode; if(b->account == gc->account) { struct irc_buddy *ib = g_new0(struct irc_buddy, 1); ib->name = g_strdup(b->name); g_hash_table_insert(irc->buddies, ib->name, ib); } } } } irc_blist_timeout(irc); if (!irc->timer) irc->timer = purple_timeout_add_seconds(45, (GSourceFunc)irc_blist_timeout, (gpointer)irc); }
void msn_session_finish_login(MsnSession *session) { PurpleAccount *account; PurpleConnection *gc; PurpleStoredImage *img; const char *passport; if (session->logged_in) { /* We are probably here because of a mid-session notification server XFR * We must send a CHG now, otherwise the servers default to invisible, * and prevent things happening, like sending IMs */ msn_change_status(session); return; } account = session->account; gc = purple_account_get_connection(account); img = purple_buddy_icons_find_account_icon(session->account); msn_user_set_buddy_icon(session->user, img); purple_imgstore_unref(img); session->logged_in = TRUE; msn_change_status(session); purple_connection_set_state(gc, PURPLE_CONNECTED); /* Sync users */ msn_session_sync_users(session); /* It seems that some accounts that haven't accessed hotmail for a while * and @msn.com accounts don't automatically get the initial email * notification so we always request it on login */ passport = purple_normalize(account, purple_account_get_username(account)); if ((strstr(passport, "@hotmail.") != NULL) || (strstr(passport, "@msn.com") != NULL)) { msn_cmdproc_send(session->notification->cmdproc, "URL", "%s", "INBOX"); } }
void msn_session_finish_login (MsnSession *session) { PurpleAccount *account; PurpleStoredImage *img; if (session->logged_in) return; account = msn_session_get_user_data (session); #ifdef HAVE_LIBPURPLE sync_users (session); #endif img = purple_buddy_icons_find_account_icon (account); { struct pn_buffer *image; if (img) image = pn_buffer_new_memdup ((const gpointer) purple_imgstore_get_data (img), purple_imgstore_get_size (img)); else image = NULL; pn_contact_set_buddy_icon (session->user, image); } purple_imgstore_unref (img); session->logged_in = TRUE; /** @todo move this to msn.c */ pn_update_status (session); pn_update_personal_message (session); pn_timeout_tune_status (session); { PurpleConnection *connection; connection = purple_account_get_connection (account); purple_connection_set_state (connection, PURPLE_CONNECTED); } pn_contactlist_check_pending (session->contactlist); }
static void pb_login(PurpleAccount *account) { PushBulletAccount *pba; PurpleConnection *pc; const gchar *password; pc = purple_account_get_connection(account); pba = g_new0(PushBulletAccount, 1); pba->account = account; pba->pc = pc; pba->sent_messages_hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); pc->proto_data = pba; password = purple_account_get_password(account); if (password && *password) { pba->access_token = g_strdup(password); } else { pb_oauth_request_access_token(account); purple_connection_error_reason(pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Access Token required")); return; } if(pba->access_token) { purple_connection_set_state(pc, PURPLE_CONNECTED); pb_start_socket(pba); if (purple_account_get_string(account, "main_sms_device", NULL) != NULL) { pba->main_sms_device = g_strdup(purple_account_get_string(account, "main_sms_device", NULL)); pb_get_phonebook(pba, pba->main_sms_device); } pb_get_everything(pba); return; } }
static void nullprpl_login(PurpleAccount *acct) { PurpleConnection *gc = purple_account_get_connection(acct); GList *offline_messages; purple_debug_info("nullprpl", "logging in %s\n", purple_account_get_username(acct)); purple_connection_update_progress(gc, _("Connecting"), 0, /* which connection step this is */ 2); /* total number of steps */ purple_connection_update_progress(gc, _("Connected"), 1, /* which connection step this is */ 2); /* total number of steps */ purple_connection_set_state(gc, PURPLE_CONNECTION_CONNECTED); /* tell purple about everyone on our buddy list who's connected */ foreach_nullprpl_gc(discover_status, gc, NULL); /* notify other nullprpl accounts */ foreach_nullprpl_gc(report_status_change, gc, NULL); /* fetch stored offline messages */ purple_debug_info("nullprpl", "checking for offline messages for %s\n", purple_account_get_username(acct)); offline_messages = g_hash_table_lookup(goffline_messages, purple_account_get_username(acct)); while (offline_messages) { GOfflineMessage *message = (GOfflineMessage *)offline_messages->data; purple_debug_info("nullprpl", "delivering offline message to %s: %s\n", purple_account_get_username(acct), message->message); purple_serv_got_im(gc, message->from, message->message, message->flags, message->mtime); offline_messages = g_list_next(offline_messages); g_free(message->from); g_free(message->message); g_free(message); } g_list_free(offline_messages); g_hash_table_remove(goffline_messages, purple_account_get_username(acct)); }
void on_ready (struct tgl_state *TLS) { debug ("on_ready().\n"); telegram_conn *conn = TLS->ev_base; purple_connection_set_state(conn->gc, PURPLE_CONNECTED); purple_connection_set_display_name(conn->gc, purple_account_get_username(conn->pa)); purple_blist_add_account(conn->pa); tggroup = purple_find_group("Telegram"); if (tggroup == NULL) { debug ("PurpleGroup = NULL, creating"); tggroup = purple_group_new ("Telegram"); purple_blist_add_group (tggroup, NULL); } debug ("seq = %d, pts = %d\n", TLS->seq, TLS->pts); tgl_do_get_difference (TLS, 0, 0, 0); tgl_do_get_dialog_list (TLS, 0, 0); tgl_do_update_contact_list (TLS, 0, 0); conn->timer = purple_timeout_add (5000, queries_timerfunc, conn); }
void msn_session_finish_login(MsnSession *session) { PurpleAccount *account; PurpleConnection *gc; PurpleStoredImage *img; const char *passport; if (session->logged_in) return; account = session->account; gc = purple_account_get_connection(account); img = purple_buddy_icons_find_account_icon(session->account); msn_user_set_buddy_icon(session->user, img); purple_imgstore_unref(img); session->logged_in = TRUE; msn_change_status(session); purple_connection_set_state(gc, PURPLE_CONNECTED); /* Sync users */ msn_session_sync_users(session); /* It seems that some accounts that haven't accessed hotmail for a while * and @msn.com accounts don't automatically get the initial email * notification so we always request it on login */ passport = purple_normalize(account, purple_account_get_username(account)); if ((strstr(passport, "@hotmail.") != NULL) || (strstr(passport, "@msn.com") != NULL)) { msn_cmdproc_send(session->notification->cmdproc, "URL", "%s", "INBOX"); } }
static void waprpl_process_incoming_events(PurpleConnection * gc) { whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); PurpleAccount *acc = purple_connection_get_account(gc); switch (waAPI_loginstatus(wconn->waAPI)) { case 0: purple_connection_update_progress(gc, "Connecting", 0, 4); break; case 1: purple_connection_update_progress(gc, "Sending authorization", 1, 4); break; case 2: purple_connection_update_progress(gc, "Awaiting response", 2, 4); break; case 3: purple_connection_update_progress(gc, "Connection established", 3, 4); purple_connection_set_state(gc, PURPLE_CONNECTED); if (!wconn->connected) waprpl_insert_contacts(gc); wconn->connected = 1; PurpleAccount *account = purple_connection_get_account(gc); PurpleStatus *status = purple_account_get_active_status(account); waprpl_set_status(account, status); break; default: break; }; /* Groups update */ if (waAPI_getgroupsupdated(wconn->waAPI)) { /* Delete/update the chats that are in our list */ PurpleBlistNode *node; for (node = purple_blist_get_root(); node; node = purple_blist_node_next(node, FALSE)) { if (!PURPLE_BLIST_NODE_IS_CHAT(node)) continue; PurpleChat *ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) != acc) continue; GHashTable *hasht = purple_chat_get_components(ch); char *grid = g_hash_table_lookup(hasht, "id"); char *glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist, ",", 0); if (str_array_find(gplist, grid) >= 0) { /* The group is in the system, update the fields */ char *sub, *own; waAPI_getgroupinfo(wconn->waAPI, grid, &sub, &own, 0); g_hash_table_replace(hasht, g_strdup("subject"), g_strdup(sub)); g_hash_table_replace(hasht, g_strdup("owner"), g_strdup(own)); purple_blist_alias_chat(ch, g_strdup(sub)); } else { /* The group was deleted */ PurpleChat *del = (PurpleChat *) node; node = purple_blist_node_next(node, FALSE); purple_blist_remove_chat(del); } g_strfreev(gplist); } /* Add new groups */ char *glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist, ",", 0); gchar **p; for (p = gplist; *p; p++) { gchar *gpid = *p; PurpleChat *ch = blist_find_chat_by_id(gc, gpid); if (!ch) { char *sub, *own; waAPI_getgroupinfo(wconn->waAPI, gpid, &sub, &own, 0); purple_debug_info("waprpl", "New group found %s %s\n", gpid, sub); GHashTable *htable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); g_hash_table_insert(htable, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(htable, g_strdup("id"), g_strdup(gpid)); g_hash_table_insert(htable, g_strdup("owner"), g_strdup(own)); ch = purple_chat_new(acc, sub, htable); purple_blist_add_chat(ch, NULL, NULL); } /* Now update the open conversation that may exist */ char *id = g_hash_table_lookup(purple_chat_get_components(ch), "id"); int prplid = chatid_to_convo(id); PurpleConversation *conv = purple_find_chat(gc, prplid); char *subject, *owner, *part; if (conv && waAPI_getgroupinfo(wconn->waAPI, id, &subject, &owner, &part)) conv_add_participants(conv, part, owner); } g_strfreev(gplist); } /* Incoming messages. */ for (;;) { int r = waAPI_querynext(wconn->waAPI); if (r < 0) break; switch (r) { case 0: query_chat_message(gc); break; case 1: query_chat_image(gc); break; case 2: query_chat_location(gc); break; case 3: query_chat_sound(gc); break; case 4: query_chat_video(gc); break; default: /* Unsupported message type. */ break; }; } /* Status changes, typing notices and profile pictures. */ query_status(gc); query_typing(gc); query_icon(gc); }
guint8 qq_proc_login_cmds(PurpleConnection *gc, guint16 cmd, guint16 seq, guint8 *rcved, gint rcved_len, guint32 update_class, guintptr ship_value) { qq_data *qd; guint8 *data = NULL; gint data_len = 0; guint ret_8 = QQ_LOGIN_REPLY_ERR; g_return_val_if_fail (gc != NULL && gc->proto_data != NULL, QQ_LOGIN_REPLY_ERR); qd = (qq_data *) gc->proto_data; g_return_val_if_fail(rcved_len > 0, QQ_LOGIN_REPLY_ERR); data = g_newa(guint8, rcved_len); switch (cmd) { case QQ_CMD_TOUCH_SERVER: case QQ_CMD_CAPTCHA: data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.random_key); break; case QQ_CMD_AUTH: data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.random_key); if (data_len >= 0) { purple_debug_warning("QQ", "Decrypt login packet by random_key, %d bytes\n", data_len); } else { data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.keys[4]); if (data_len >= 0) { purple_debug_warning("QQ", "Decrypt login packet by auth_key1, %d bytes\n", data_len); } } break; case QQ_CMD_VERIFY_DE: data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.keys[0]); break; case QQ_CMD_VERIFY_E5: data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.keys[1]); break; case QQ_CMD_VERIFY_E3: data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.keys[3]); break; case QQ_CMD_LOGIN: data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.keys[2]); if (data_len >= 0) { purple_debug_info("QQ", "Decrypt login packet by Key0_VerifyE5\n"); } else { /* network condition may has changed. please sign in again. */ data_len = qq_decrypt(data, rcved, rcved_len, qd->ld.keys[0]); if (data_len >= 0) { purple_debug_info("QQ", "Decrypt login packet rarely by Key2_Auth\n"); } } break; case QQ_CMD_LOGIN_E9: case QQ_CMD_LOGIN_EA: case QQ_CMD_LOGIN_GETLIST: case QQ_CMD_LOGIN_ED: case QQ_CMD_LOGIN_EC: default: data_len = qq_decrypt(data, rcved, rcved_len, qd->session_key); break; } if (data_len < 0) { purple_debug_warning("QQ", "Can not decrypt login cmd, [%05d], 0x%04X %s, len %d\n", seq, cmd, qq_get_cmd_desc(cmd), rcved_len); qq_show_packet("Can not decrypted", rcved, rcved_len); purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_ENCRYPTION_ERROR, _("Unable to decrypt login reply")); return QQ_LOGIN_REPLY_ERR; } switch (cmd) { case QQ_CMD_TOUCH_SERVER: ret_8 = qq_process_touch_server(gc, data, data_len); if ( ret_8 == QQ_LOGIN_REPLY_OK) { qq_request_captcha(gc); } else if ( ret_8 == QQ_TOUCH_REPLY_REDIRECT) { return QQ_TOUCH_REPLY_REDIRECT; } break; case QQ_CMD_CAPTCHA: ret_8 = qq_process_captcha(gc, data, data_len); if (ret_8 == QQ_LOGIN_REPLY_OK) { qq_request_auth(gc); } else if (ret_8 == QQ_LOGIN_REPLY_NEXT_CAPTCHA) { qq_request_captcha_next(gc); } else if (ret_8 == QQ_LOGIN_REPLY_CAPTCHA_DLG) { qq_captcha_input_dialog(gc, &(qd->captcha)); g_free(qd->captcha.token); g_free(qd->captcha.data); memset(&qd->captcha, 0, sizeof(qd->captcha)); } break; case QQ_CMD_AUTH: ret_8 = qq_process_auth(gc, data, data_len); if (ret_8 == QQ_LOGIN_REPLY_DE) { qq_request_verify_DE(gc); } else if (ret_8 == QQ_LOGIN_REPLY_OK) { qq_request_verify_E5(gc); } else return ret_8; break; case QQ_CMD_VERIFY_DE: ret_8 = qq_process_verify_DE(gc, data, data_len); if (ret_8 != QQ_LOGIN_REPLY_OK) { return ret_8; } qq_request_verify_E5(gc); break; case QQ_CMD_VERIFY_E5: ret_8 = qq_process_verify_E5(gc, data, data_len); if (ret_8 != QQ_LOGIN_REPLY_OK) { return ret_8; } qq_request_verify_E3(gc); break; case QQ_CMD_VERIFY_E3: ret_8 = qq_process_verify_E3(gc, data, data_len); if (ret_8 != QQ_LOGIN_REPLY_OK) { return ret_8; } qq_request_login(gc); break; case QQ_CMD_LOGIN: ret_8 = qq_process_login(gc, data, data_len); if ( ret_8 == QQ_TOUCH_REPLY_REDIRECT) { qq_request_touch_server(gc); return QQ_LOGIN_REPLY_OK; } if (ret_8 == QQ_LOGIN_REPLY_OK) { qq_request_login_E9(gc); } else { return ret_8; } break; case QQ_CMD_LOGIN_E9: qq_request_login_EA(gc); break; case QQ_CMD_LOGIN_EA: qq_request_login_getlist(gc, 0x0001); break; case QQ_CMD_LOGIN_GETLIST: ret_8 = qq_process_login_getlist(gc, data, data_len); if (ret_8 == QQ_LOGIN_REPLY_OK) { qq_request_login_ED(gc); } break; case QQ_CMD_LOGIN_EC: break; case QQ_CMD_LOGIN_ED: qq_request_login_EC(gc); purple_connection_update_progress(gc, _("Logging in"), QQ_CONNECT_STEPS - 1, QQ_CONNECT_STEPS); purple_debug_info("QQ", "Login replies OK; everything is fine\n"); purple_connection_set_state(gc, PURPLE_CONNECTED); qd->is_login = TRUE; /* must be defined after sev_finish_login */ /* is_login, but we have packets before login */ qq_trans_process_remained(gc); qq_update_all(gc, 0); break; default: process_unknown_cmd(gc, _("Unknown LOGIN CMD"), data, data_len, cmd, seq); return QQ_LOGIN_REPLY_ERR; } return QQ_LOGIN_REPLY_OK; }
static void plainprpl_login(PurpleAccount *account) { PurpleConnection *gc = purple_account_get_connection(account); purple_debug_info("plainprpl", "logging in %s\n", account->username); purple_connection_update_progress(gc, _("Connecting"), 0, 2); purple_connection_update_progress(gc, _("Connected"), 1, 2); purple_connection_set_state(gc, PURPLE_CONNECTED); /* Setup plugin data */ plain_plugin_state *pstate = g_new0(plain_plugin_state, 1); /* General account data */ const char *listen_af = purple_account_get_string(account, "listen_af", NULL); const char *listen_port = purple_account_get_string(account, "listen_port", NULL); //check port if (listen_port == NULL || atoi(listen_port) < 1 || atoi(listen_port) >= 65535) { listen_port = PLAIN_DEFAULT_PORT_STR; purple_account_set_string(account, "listen_port", listen_port); } //check protocol if (listen_af == NULL || (strcmp(listen_af, "ipv4") && strcmp(listen_af, "ipv6"))) { listen_af = "ipv4"; purple_account_set_string(account, "listen_port", listen_af); } /* Select the address to listen on */ const char *listen_addr = (strcmp(listen_af, "ipv4") == 0) ? "0.0.0.0" : "::1"; pstate->sockaf = str_to_af(listen_af); pstate->sockfd = net_bind("plainprpl", listen_addr, listen_port, NULL, IPPROTO_UDP, pstate->sockaf); if (pstate->sockfd < 0) { purple_debug_info("plainprpl", "Failed to bind to %s\n", listen_addr); g_free(pstate); //TODO: diable plugin return; } else { purple_debug_info("plainprpl", "Bind to %s\n", listen_addr); } pstate->receive_timer = purple_timeout_add(80, plain_receive, gc); purple_connection_set_protocol_data(gc, pstate); /* Attach buddy data to each buddy */ GSList *list = purple_find_buddies(account, NULL); purple_debug_info("plainprpl", "Buddies to load: %d\n", g_slist_length(list)); GSList *iter = list; while (iter) { PurpleBuddy *buddy = iter->data; //purple_debug_info("plainprpl", "#plainprpl_login: attach custom data to buddy: %s\n", buddy->name); assert(purple_buddy_get_protocol_data(buddy) == NULL); const char *addr_str = purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy), "addr_str"); if (addr_str != NULL && strlen(addr_str)) { add_buddy_sdata(buddy, pstate); } else { purple_debug_info("plainprpl", "Empty address for buddy: %s\n", buddy->name); } /* Set offline by default */ purple_prpl_got_user_status(account, buddy->name, PLAIN_STATUS_OFFLINE, NULL); iter = iter->next; } g_slist_free(list); /* Call the on_login script - if it is set */ const char *on_login = purple_account_get_string(account, "on_login", NULL); exec_process(on_login, NULL, NULL, gc, NULL); }
static void nap_callback(gpointer data, gint source, PurpleInputCondition condition) { PurpleConnection *gc = data; struct nap_data *ndata = gc->proto_data; PurpleAccount *account = NULL; PurpleConversation *c = NULL; PurpleNotifyUserInfo *pnui = NULL; gchar *buf = NULL, *buf2 = NULL, *buf3 = NULL, **res = NULL; unsigned short header[2] = { 0 , 0 }; int len = 0; int command = 0; int i; account = purple_connection_get_account(gc); if (read(source, (void*)header, 4) != 4) { purple_connection_error(gc, _("Unable to read header from server")); return; } len = header[0]; command = header[1]; buf = (gchar *)g_malloc((len + 1) * sizeof(gchar)); buf[len] = '\0'; i = 0; do { int tmp = read(source, buf + i, len - i); if (tmp <= 0) { g_free(buf); buf = g_strdup_printf(_("Unable to read message from server: %s. Command is %hd, length is %hd."), strerror(errno), len, command); purple_connection_error(gc, buf); g_free(buf); return; } i += tmp; } while (i != len); purple_debug(PURPLE_DEBUG_MISC, "napster", "R %3hd: %s\n", command, buf); switch (command) { case 000: /* MSG_SERVER_ERROR */ purple_notify_error(gc, NULL, buf, NULL); purple_input_remove(gc->inpa); gc->inpa = 0; close(source); purple_connection_error(gc, _("Unknown server error.")); break; case 003: /* MSG_SERVER_EMAIL */ purple_debug(PURPLE_DEBUG_MISC, "napster", "Registered with e-mail address: %s\n", buf); ndata->email = g_strdup(buf); /* Our signon is complete */ purple_connection_set_state(gc, PURPLE_CONNECTED); /* Send the server our buddy list */ nap_send_buddylist(gc); break; case 201: /* MSG_SERVER_SEARCH_RESULT */ res = g_strsplit(buf, " ", 0); purple_prpl_got_user_status(account, res[0], "available", NULL); g_strfreev(res); break; case 202: /* MSG_SERVER_SEARCH_END */ purple_prpl_got_user_status(account, buf, "offline", NULL); break; case 205: /* MSG_CLIENT_PRIVMSG */ res = g_strsplit(buf, " ", 2); buf2 = g_markup_escape_text(res[1], -1); serv_got_im(gc, res[0], buf2, 0, time(NULL)); g_free(buf2); g_strfreev(res); break; case 209: /* MSG_SERVER_USER_SIGNON */ /* USERNAME SPEED */ res = g_strsplit(buf, " ", 2); purple_prpl_got_user_status(account, res[0], "available", NULL); g_strfreev(res); break; case 210: /* MSG_SERVER_USER_SIGNOFF */ /* USERNAME SPEED */ res = g_strsplit(buf, " ", 2); purple_prpl_got_user_status(account, res[0], "offline", NULL); g_strfreev(res); break; case 214: /* MSG_SERVER_STATS */ res = g_strsplit(buf, " ", 3); buf2 = g_strdup_printf(_("users: %s, files: %s, size: %sGB"), res[0], res[1], res[2]); serv_got_im(gc, "server", buf2, 0, time(NULL)); g_free(buf2); g_strfreev(res); break; case 301: /* MSG_SERVER_HOTLIST_ACK */ /* Our buddy was added successfully */ break; case 302: /* MSG_SERVER_HOTLIST_ERROR */ buf2 = g_strdup_printf(_("Unable to add \"%s\" to your Napster hotlist"), buf); purple_notify_error(gc, NULL, buf2, NULL); g_free(buf2); break; case 316: /* MSG_SERVER_DISCONNECTING */ /* we have been kicked off =^( */ purple_connection_error(gc, _("You were disconnected from the server.")); break; case 401: /* MSG_CLIENT_PART */ c = nap_find_chat(gc, buf); if (c) serv_got_chat_left(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c))); break; case 403: /* MSG_SERVER_PUBLIC */ res = g_strsplit(buf, " ", 3); c = nap_find_chat(gc, res[0]); if (c) serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)), res[1], 0, res[2], time((time_t)NULL)); g_strfreev(res); break; case 404: /* MSG_SERVER_NOSUCH */ /* abused by opennap servers to broadcast stuff */ buf2 = g_markup_escape_text(buf, -1); serv_got_im(gc, "server", buf2, 0, time(NULL)); g_free(buf2); break; case 405: /* MSG_SERVER_JOIN_ACK */ c = nap_find_chat(gc, buf); if (!c) serv_got_joined_chat(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(c)), buf); break; case 407: /* MSG_SERVER_PART */ res = g_strsplit(buf, " ", 0); c = nap_find_chat(gc, res[0]); purple_conv_chat_remove_user(PURPLE_CONV_CHAT(c), res[1], NULL); g_strfreev(res); break; case 406: /* MSG_SERVER_JOIN */ case 408: /* MSG_SERVER_CHANNEL_USER_LIST */ res = g_strsplit(buf, " ", 4); c = nap_find_chat(gc, res[0]); purple_conv_chat_add_user(PURPLE_CONV_CHAT(c), res[1], NULL, PURPLE_CBFLAGS_NONE, TRUE); g_strfreev(res); break; case 409: /* MSG_SERVER_CHANNEL_USER_LIST_END */ break; case 410: /* MSG_SERVER_TOPIC */ /* display the topic in the channel */ res = g_strsplit(buf, " ", 2); c = nap_find_chat(gc, res[0]); purple_conv_chat_set_topic(PURPLE_CONV_CHAT(c), res[0], res[1]); g_strfreev(res); break; case 603: /* MSG_CLIENT_WHOIS */ buf2 = g_strdup_printf(_("%s requested your information"), buf); serv_got_im(gc, "server", buf2, 0, time(NULL)); g_free(buf2); break; case 604: /* MSG_SERVER_WHOIS_RESPONSE */ /* XXX - Format is: "Elite" 37 " " "Active" 0 0 0 0 "purple 0.63cvs" 0 0 192.168.1.41 32798 0 unknown flounder */ res = g_strsplit(buf, " ", 2); /* res[0] == username */ pnui = purple_notify_user_info_new(); purple_notify_user_info_add_pair(pnui, _("Napster User Info:"), res[1]); purple_notify_userinfo(gc, res[0], pnui, NULL, NULL); g_strfreev(res); break; case 621: case 622: /* MSG_CLIENT_MOTD */ /* also replaces MSG_SERVER_MOTD, so we should display it */ buf2 = g_markup_escape_text(buf, -1); serv_got_im(gc, "motd", buf2, 0, time(NULL)); g_free(buf2); break; case 627: /* MSG_CLIENT_WALLOP */ /* abused by opennap server maintainers to broadcast stuff */ buf2 = g_markup_escape_text(buf, -1); serv_got_im(gc, "wallop", buf2, 0, time(NULL)); g_free(buf2); break; case 628: /* MSG_CLIENT_ANNOUNCE */ buf2 = g_markup_escape_text(buf, -1); serv_got_im(gc, "announce", buf2, 0, time(NULL)); g_free(buf); break; case 748: /* MSG_SERVER_GHOST */ /* Looks like someone logged in as us! =-O */ purple_connection_error(gc, _("You have signed on from another location.")); break; case 751: /* MSG_CLIENT_PING */ buf2 = g_strdup_printf(_("%s requested a PING"), buf); serv_got_im(gc, "server", buf2, 0, time(NULL)); g_free(buf2); /* send back a pong */ /* MSG_CLIENT_PONG */ nap_write_packet(gc, 752, "%s", buf); break; case 752: /* MSG_CLIENT_PONG */ buf2 = g_strdup_printf("Received pong from %s", buf); purple_notify_info(gc, NULL, buf2, NULL); g_free(buf2); break; case 824: /* MSG_CLIENT_EMOTE */ res = g_strsplit(buf, " ", 3); buf2 = g_strndup(res[2]+1, strlen(res[2]) - 2); /* chomp off the surround quotes */ buf3 = g_strdup_printf("/me %s", buf2); g_free(buf2); if ((c = nap_find_chat(gc, res[0]))) { purple_conv_chat_write(PURPLE_CONV_CHAT(c), res[1], buf3, PURPLE_MESSAGE_NICK, time(NULL)); } g_free(buf3); g_strfreev(res); break; default: purple_debug(PURPLE_DEBUG_MISC, "napster", "Unknown packet %hd: %s\n", command, buf); break; } g_free(buf); }
/* Packet parsers */ int hon_parse_packet(PurpleConnection *gc, gchar* buffer,int packet_length){ GString* hexdump; hon_account *hon = gc->proto_data; guint16 packet_id = read_guint16(buffer); hon->gotPacket = TRUE; #if _DEBUG hexdump = g_string_new(NULL); hexdump_g_string_append(hexdump,"",buffer,packet_length - 2); purple_debug_info(HON_DEBUG_PREFIX, "packet:\nid:%X(%d)\nlength:%d\ndata:\n%s\n",packet_id,packet_id,packet_length, hexdump->str); g_string_free(hexdump,TRUE); #endif switch (packet_id) { case 0: return 0; case HON_SC_AUTH_ACCEPTED/*0x1C00*/: /* logged on ! */ purple_connection_update_progress(gc, _("Connected"), 3, /* which connection step this is */ 4); /* total number of steps */ purple_connection_set_state(gc, PURPLE_CONNECTED); break; case HON_SC_PING/*0x01*/: hon_send_pong(gc); purple_debug_info(HON_DEBUG_PREFIX, "server ping, sending pong\n"); break; case HON_SC_CHANNEL_MSG/*0x03*/: hon_parse_chat_message(gc,buffer); break; case HON_SC_CHANGED_CHANNEL/*0x04*/: hon_parse_chat_entering(gc,buffer); break; case HON_SC_JOINED_CHANNEL/*0x05*/: hon_parse_chat_join(gc,buffer); break; case HON_SC_LEFT_CHANNEL/*0x06*/: hon_parse_chat_leave(gc,buffer); break; case HON_SC_WHISPER/*0x08*/: hon_parse_pm_whisper(gc,buffer,TRUE); break; case HON_SC_WHISPER_FAILED/*0x09*/: hon_parse_whisper_failed(gc,buffer); break; case HON_SC_INITIAL_STATUS/*0x0B*/: hon_parse_initiall_statuses(gc,buffer); break; case HON_SC_UPDATE_STATUS/*0x0C*/: hon_parse_user_status(gc,buffer); break; case HON_SC_CLAN_MESSAGE/*0x13*/: hon_parse_clan_message(gc,buffer); break; case HON_SC_PM/*0x1C*/: hon_parse_pm_whisper(gc,buffer,FALSE); break; case HON_SC_PM_FAILED/*0x1D*/: hon_parse_pm_failed(gc,buffer); break; case HON_SC_WHISPER_BUDDIES/*0x20*/: hon_parse_pm_whisper(gc,buffer,3); break; case HON_SC_MAX_CHANNELS/*0x21*/: hon_parse_max_channels(gc,buffer); break; case HON_SC_USER_INFO_NO_EXIST/*0x2b*/: case HON_SC_USER_INFO_OFFLINE/*0x2c*/: case HON_SC_USER_INFO_ONLINE/*0x2d*/: case HON_SC_USER_INFO_IN_GAME/*0x2e*/: hon_parse_userinfo(gc,buffer,packet_id); break; case HON_SC_CHANNEL_UPDATE: hon_parse_channel_update(gc,buffer); break; case HON_SC_UPDATE_TOPIC/*0x30*/: hon_parse_chat_topic(gc,buffer); break; case HON_SC_CHANNEL_KICK/*0x31*/: hon_parse_channel_kick(gc,buffer); break; case HON_SC_CHANNEL_BAN/*0x32*/: case HON_SC_CHANNEL_UNBAN/*0x33*/: hon_parse_channel_ban_unban(gc,buffer,packet_id); break; case HON_SC_CHANNEL_BANNED/*0x34*/: hon_parse_channel_banned(gc,buffer); break; case HON_SC_CHANNEL_SILENCED/*0x35*/: hon_parse_channel_silenced(gc,buffer); break; case HON_SC_CHANNEL_SILENCE_LIFTED/*0x36*/: hon_parse_channel_silence_lifted(gc,buffer); break; case HON_SC_CHANNEL_SILENCE_PLACED/*0x37*/: hon_parse_channel_silence_placed(gc,buffer); break; case HON_SC_CHANNEL_PROMOTE/*0x3A*/: case HON_SC_CHANNEL_DEMOTE/*0x3A*/: hon_parse_channel_promote_demote(gc,buffer,packet_id); break; case HON_SC_MESSAGE_ALL/*0x39*/: hon_parse_global_notification(gc,buffer); break; case HON_SC_CHANNEL_AUTH_ENABLE: case HON_SC_CHANNEL_AUTH_DISABLE: hon_parse_channel_auth_enable_disable(gc,buffer,packet_id); break; case HON_SC_CHANNEL_AUTH_ADD: case HON_SC_CHANNEL_AUTH_DELETE: case HON_SC_CHANNEL_ADD_AUTH_FAIL: case HON_SC_CHANNEL_DEL_AUTH_FAIL: hon_parse_channel_auth_add_delete(gc,buffer,packet_id); break; case HON_SC_CHANNEL_AUTH_LIST: hon_parse_channel_auth_list(gc,buffer); break; case HON_SC_CHANNEL_PASSWORD_CHANGED/*0x43*/: hon_parse_channel_password_changed(gc,buffer); break; case HON_SC_JOIN_CHANNEL_PASSWORD/*0x46*/: hon_parse_join_channel_password(gc,buffer); break; case HON_SC_CHANNEL_EMOTE/*0x65*/: case HON_SC_CHANNEL_ROLL/*0x64*/: hon_parse_emote_roll(gc,buffer,packet_id); break; case 0x18: read_string(buffer); break; case HON_SC_TOTAL_ONLINE: //read_guint32(buffer); packet_length = read_guint32(buffer); purple_debug_info(HON_DEBUG_PREFIX, "total online : %d\n",packet_length); break; case HON_SC_REQUEST_NOTIFICATION/*0xB2*/: hon_parse_request(gc,buffer); break; case HON_SC_NOTIFICATION/*0xB4*/: hon_parse_notification(gc,buffer); break; case HON_SC_TMM_INVITE/*0xC0D*/: hon_parse_tmm_invite(gc,buffer); break; default: hexdump = g_string_new(NULL); hexdump_g_string_append(hexdump,"",(guint8*)buffer,packet_length - sizeof(packet_id)); purple_debug_info(HON_DEBUG_PREFIX, "unknown packet:\nid:%X(%d)\nlength:%d\ndata:\n%s\n",packet_id,packet_id,packet_length, hexdump->str); g_string_free(hexdump,TRUE); break; } return 1; }
void sipe_backend_connection_completed(struct sipe_core_public *sipe_public) { purple_connection_set_state(sipe_public->backend_private->gc, PURPLE_CONNECTED); }
/** * purplemot_login - Login for an account. Establishes a connection * to the discovery server and initializes * * @param acct The account to be logged in */ static void purplemot_login(PurpleAccount *acct) { char **userparts; struct pm_account *account; int port; const char *username = purple_account_get_username(acct); PurpleConnection *gc = purple_account_get_connection(acct); GList *offline_messages; purple_debug_info("purplemot", "logging in %s\n", acct->username); // TODO(carl): initialize motmot here? if (strpbrk(username, " \t\v\r\n") != NULL) { purple_connection_error_reason (gc, PURPLE_CONNECTION_ERROR_INVALID_SETTINGS, _("Motmot server may not contain whitespace")); return; } gc->proto_data = account = g_new0(struct pm_account, 1); account->pa = acct; userparts = g_strsplit(username, "@", 2); purple_connection_set_display_name(gc, userparts[0]); account->server_host = g_strdup(userparts[1]); g_strfreev(userparts); port = purple_account_get_int(acct, "disc_port", DEFAULT_PORT); purple_connection_update_progress(gc, _("Connecting"), 0, /* which connection step this is */ 2); /* total number of steps */ purple_debug_info("motmot", "connecting to discovery server"); rpc_connect(account); purple_connection_update_progress(gc, _("Connected"), 1, /* which connection step this is */ 2); /* total number of steps */ purple_connection_set_state(gc, PURPLE_CONNECTED); /* fetch stored offline messages */ purple_debug_info("purplemot", "checking for offline messages for %s\n", acct->username); offline_messages = g_hash_table_lookup(goffline_messages, acct->username); while (offline_messages) { GOfflineMessage *message = (GOfflineMessage *)offline_messages->data; purple_debug_info("purplemot", "delivering offline message to %s: %s\n", acct->username, message->message); serv_got_im(gc, message->from, message->message, message->flags, message->mtime); offline_messages = g_list_next(offline_messages); g_free(message->from); g_free(message->message); g_free(message); } g_list_free(offline_messages); g_hash_table_remove(goffline_messages, &acct->username); }
static void fb_login_cb(FacebookAccount *fba, gchar *response, gsize len, gpointer userdata) { gchar *user_cookie; const gchar *persist_data_start; gchar *persist_data; const gchar *session_start; gchar *session; gchar *captcha_url; const gchar *extra_challenge_params; gchar *extra_challenge; if (len && g_strstr_len(response, len, "captcha")) { purple_debug_info("facebook", "captcha page: %s\n", response); purple_connection_update_progress(fba->pc, _("Handling Captcha"), 2, 4); persist_data_start = "<input type=\"hidden\" id=\"captcha_persist_data\" name=\"captcha_persist_data\" value=\""; persist_data = g_strstr_len(response, len, persist_data_start); if (persist_data) { persist_data += strlen(persist_data_start); fba->persist_data = g_strndup(persist_data, strchr(persist_data, '"') - persist_data); } session_start = "<input type=\"hidden\" id=\"captcha_session\" name=\"captcha_session\" value=\""; session = g_strstr_len(response, len, session_start); if (session) { session += strlen(session_start); fba->captcha_session = g_strndup(session, strchr(session, '"') - session); } extra_challenge_params = "<input type=\"hidden\" id=\"extra_challenge_params\" name=\"extra_challenge_params\" value=\""; extra_challenge = g_strstr_len(response, len, extra_challenge_params); if (extra_challenge) { extra_challenge += strlen(extra_challenge_params); fba->extra_challenge = g_strndup(extra_challenge, strchr(extra_challenge, '"') - extra_challenge); extra_challenge = purple_unescape_html(fba->extra_challenge); g_free(fba->extra_challenge); fba->extra_challenge = extra_challenge; } if (!fba->extra_challenge || !fba->persist_data || !fba->captcha_session) { purple_debug_info("facebook", "captcha response: %s\n", response); g_free(fba->extra_challenge); g_free(fba->persist_data); g_free(fba->captcha_session); fba->extra_challenge = NULL; fba->persist_data = NULL; fba->captcha_session = NULL; purple_connection_error_reason(fba->pc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, "Could not authenticate captcha. Logging into the Facebook website may fix this."); return; } captcha_url = g_strdup_printf("/challenge?k=" FACEBOOK_CAPTCHA_SITE "&%s", fba->extra_challenge?fba->extra_challenge:""); fb_post_or_get(fba, FB_METHOD_GET | FB_METHOD_SSL, "api-secure.recaptcha.net", captcha_url, NULL, fb_login_captcha_cb, NULL, FALSE); g_free(captcha_url); return; } purple_connection_update_progress(fba->pc, _("Authenticating"), 2, 3); /* Look for our uid */ user_cookie = g_hash_table_lookup(fba->cookie_table, "c_user"); if (user_cookie == NULL) { /* * Server didn't set the c_user cookie, so we must have given * them a bad username or password */ purple_connection_error_reason(fba->pc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("Incorrect username or password.")); return; } fba->uid = atoll(user_cookie); purple_debug_info("facebook", "uid %" G_GINT64_FORMAT "\n", fba->uid); /* ok, we're logged in now! */ purple_connection_set_state(fba->pc, PURPLE_CONNECTED); /* This will kick off our long-poll message retrieval loop */ fb_get_post_form_id(fba); fb_check_friend_requests(fba); /* periodically check for people adding you to their facebook friend list */ fba->friend_request_timer = purple_timeout_add_seconds(60 * 5, fb_check_friend_requests, fba); /* periodically check for new notifications */ fba->notifications_timer = purple_timeout_add_seconds(60, (GSourceFunc)fb_get_notifications_feed, fba); /* Periodically check for new messages. NOTE: This MUST exist, * regardless of other other mechanisms for checking messages. This * is because the code needs a failsafe checker in case other one of * the other retrieval mechanisms dies due to a bad request, etc. * Without such a failsafe, a user will receive no messages, which is * one of hardest bugs to debug and get reports about. Hence, the * importance of this loop. * That said, there is room for tweaking this loop and possibly even * setting it such that it is the primary or only message checker. * The key is that the method must NEVER die until logout. */ fba->perpetual_messages_timer = purple_timeout_add_seconds(15, (GSourceFunc)fb_get_messages_failsafe, fba); /* init blist subsystem */ fb_blist_init(fba); /* init conversation subsystem */ fb_conversation_init(fba); }
static void waprpl_process_incoming_events(PurpleConnection * gc) { whatsapp_connection *wconn = purple_connection_get_protocol_data(gc); PurpleAccount *acc = purple_connection_get_account(gc); switch (waAPI_loginstatus(wconn->waAPI)) { case 0: purple_connection_update_progress(gc, "Connecting", 0, 4); break; case 1: purple_connection_update_progress(gc, "Sending authorization", 1, 4); break; case 2: purple_connection_update_progress(gc, "Awaiting response", 2, 4); break; case 3: purple_connection_update_progress(gc, "Connection established", 3, 4); purple_connection_set_state(gc, PURPLE_CONNECTED); if (!wconn->connected) waprpl_insert_contacts(gc); wconn->connected = 1; PurpleAccount *account = purple_connection_get_account(gc); PurpleStatus *status = purple_account_get_active_status(account); waprpl_set_status(account, status); break; default: break; }; char *msg, *who, *prev, *url, *author; int status; int size; double lat, lng; unsigned long timestamp; /* Incoming messages */ while (1) { int r = waAPI_querynext(wconn->waAPI); switch (r) { case 0: if (waAPI_querychat(wconn->waAPI, &who, &msg, &author, ×tamp)) { purple_debug_info(WHATSAPP_ID, "Got chat message from %s: %s\n", who, msg); conv_add_message(gc, who, msg, author, timestamp); } break; case 1: if (waAPI_querychatimage(wconn->waAPI, &who, &prev, &size, &url, &author, ×tamp)) { purple_debug_info(WHATSAPP_ID, "Got image from %s: %s\n", who, url); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); char *msg = g_strdup_printf("<a href=\"%s\"><img id=\"%u\"></a><br/><a href=\"%s\">%s</a>", url, imgid, url, url); conv_add_message(gc, who, msg, author, timestamp); g_free(msg); } break; case 2: if (waAPI_querychatlocation(wconn->waAPI, &who, &prev, &size, &lat, &lng, &author, ×tamp)) { purple_debug_info(WHATSAPP_ID, "Got geomessage from: %s Coordinates (%f %f)\n", who, (float)lat, (float)lng); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); char *msg = g_strdup_printf("<a href=\"http://openstreetmap.org/?lat=%f&lon=%f&zoom=16\"><img src=\"%u\"></a>", lat, lng, imgid); conv_add_message(gc, who, msg, author, timestamp); g_free(msg); } break; case 3: if (waAPI_querychatsound(wconn->waAPI, &who, &url, &author, ×tamp)) { purple_debug_info(WHATSAPP_ID, "Got chat sound from %s: %s\n", who, url); char *msg = g_strdup_printf("<a href=\"%s\">%s</a>", url, url); conv_add_message(gc, who, msg, author, timestamp); g_free(msg); } break; default: break; }; if (r < 0) break; } /* User status change */ while (waAPI_querystatus(wconn->waAPI, &who, &status)) { if (status == 1) { purple_prpl_got_user_status(acc, who, "available", "message", "", NULL); } else { purple_prpl_got_user_status(acc, who, "unavailable", "message", "", NULL); } } /* User typing info notify */ while (waAPI_querytyping(wconn->waAPI, &who, &status)) { if (status == 1) { purple_debug_info(WHATSAPP_ID, "%s is typing\n", who); serv_got_typing(gc, who, 0, PURPLE_TYPING); } else { purple_debug_info(WHATSAPP_ID, "%s is not typing\n", who); serv_got_typing(gc, who, 0, PURPLE_NOT_TYPING); serv_got_typing_stopped(gc, who); } } /* User profile picture */ char *icon, *hash; int len; while (waAPI_queryicon(wconn->waAPI, &who, &icon, &len, &hash)) { purple_buddy_icons_set_for_user(acc, who, g_memdup(icon, len), len, hash); } /* Groups update */ if (waAPI_getgroupsupdated(wconn->waAPI)) { /* Delete/update the chats that are in our list */ PurpleBlistNode *node; for (node = purple_blist_get_root(); node; node = purple_blist_node_next(node, FALSE)) { if (!PURPLE_BLIST_NODE_IS_CHAT(node)) continue; PurpleChat *ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) != acc) continue; GHashTable *hasht = purple_chat_get_components(ch); char *grid = g_hash_table_lookup(hasht, "id"); char *glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist, ",", 0); if (str_array_find(gplist, grid) >= 0) { /* The group is in the system, update the fields */ char *sub, *own; waAPI_getgroupinfo(wconn->waAPI, grid, &sub, &own, 0); g_hash_table_insert(hasht, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(hasht, g_strdup("owner"), g_strdup(own)); } else { /* The group was deleted */ PurpleChat *del = (PurpleChat *) node; node = purple_blist_node_next(node, FALSE); purple_blist_remove_chat(del); } g_strfreev(gplist); } /* Add new groups */ char *glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist, ",", 0); gchar **p; for (p = gplist; *p; p++) { gchar *gpid = *p; PurpleChat *ch = blist_find_chat_by_id(gc, gpid); if (!ch) { char *sub, *own; waAPI_getgroupinfo(wconn->waAPI, gpid, &sub, &own, 0); purple_debug_info("waprpl", "New group found %s %s\n", gpid, sub); GHashTable *htable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); g_hash_table_insert(htable, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(htable, g_strdup("id"), g_strdup(gpid)); g_hash_table_insert(htable, g_strdup("owner"), g_strdup(own)); ch = purple_chat_new(acc, sub, htable); purple_blist_add_chat(ch, NULL, NULL); } /* Now update the open conversation that may exist */ char *id = g_hash_table_lookup(purple_chat_get_components(ch), "id"); int prplid = chatid_to_convo(id); PurpleConversation *conv = purple_find_chat(gc, prplid); char *subject, *owner, *part; if (conv && waAPI_getgroupinfo(wconn->waAPI, id, &subject, &owner, &part)) conv_add_participants(conv, part, owner); } g_strfreev(gplist); } }
static void waprpl_process_incoming_events(PurpleConnection *gc) { whatsapp_connection * wconn = purple_connection_get_protocol_data(gc); PurpleAccount * acc = purple_connection_get_account(gc); switch (waAPI_loginstatus(wconn->waAPI)) { case 0: purple_connection_update_progress(gc, "Connecting", 0, 4); break; case 1: purple_connection_update_progress(gc, "Sending auth", 1, 4); break; case 2: purple_connection_update_progress(gc, "Waiting response", 2, 4); break; case 3: purple_connection_update_progress(gc, "Connected", 3, 4); purple_connection_set_state(gc, PURPLE_CONNECTED); if (!wconn->connected) waprpl_insert_contacts(gc); wconn->connected = 1; break; default: break; }; char * msg, * who, * prev, * url, *author; int status; int size; double lat,lng; // Incoming messages while (waAPI_querychat(wconn->waAPI, &who, &msg, &author)) { purple_debug_info(WHATSAPP_ID, "Got chat message from %s: %s\n", who,msg); if (isgroup(who)) { // Search fot the combo PurpleBlistNode* node = purple_blist_get_root(); GHashTable* hasht = NULL; while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleChat * ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == acc) { hasht = purple_chat_get_components(ch); if (strcmp(g_hash_table_lookup(hasht, "id"),who) == 0) { break; } } } node = purple_blist_node_next(node,FALSE); } int convo_id = chatid_to_convo(who); PurpleConversation *convo = purple_find_chat(gc, convo_id); // Create a window if it's not open yet if (!convo) waprpl_chat_join(gc,hasht); if (convo != NULL) { serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)), author, PURPLE_MESSAGE_RECV, msg, time(NULL)); }else{ printf("Received group message but could not find the group! %s\n",msg); } }else{ // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, msg, PURPLE_MESSAGE_RECV, time(NULL)); } } while (waAPI_querychatimage(wconn->waAPI, &who, &prev, &size, &url)) { printf("Got chat image %s %s\n",who,url); purple_debug_info(WHATSAPP_ID, "Got image from %s: %s\n", who,url); // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, g_strdup_printf("<a href=\"%s\"><img id=\"%u\"></a>",url,imgid), PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_IMAGES, time(NULL)); } while (waAPI_querychatlocation(wconn->waAPI, &who, &prev, &size, &lat, &lng)) { purple_debug_info(WHATSAPP_ID, "Got geomessage from: %s Coordinates (%f %f)\n", who,(float)lat,(float)lng); // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); int imgid = purple_imgstore_add_with_id(g_memdup(prev, size), size, NULL); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, g_strdup_printf("<a href=\"http://openstreetmap.org/?lat=%f&lon=%f&zoom=16\"><img src=\"%u\"></a>",lat,lng,imgid), PURPLE_MESSAGE_RECV | PURPLE_MESSAGE_IMAGES, time(NULL)); } while (waAPI_querychatsound(wconn->waAPI, &who, &url)) { purple_debug_info(WHATSAPP_ID, "Got chat sound from %s: %s\n", who,url); // Search fot the combo PurpleConversation *convo = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, who, acc); if (!convo) convo = purple_conversation_new(PURPLE_CONV_TYPE_IM, acc, who); serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_IM(convo)), who, PURPLE_MESSAGE_RECV, msg, time(NULL)); purple_conv_im_write(PURPLE_CONV_IM(convo), who, g_strdup_printf("<a href=\"%s\">%s</a>",url,url), PURPLE_MESSAGE_RECV , time(NULL)); } // User status change while (waAPI_querystatus(wconn->waAPI, &who, &status)) { if (status == 1) { purple_prpl_got_user_status(acc, who, "available", "message","", NULL); } else { purple_prpl_got_user_status(acc, who, "unavailable", "message","", NULL); } } // User typing info notify while (waAPI_querytyping(wconn->waAPI, &who, &status)) { if (status == 1) { serv_got_typing(gc,who,0,PURPLE_TYPING); } else { serv_got_typing_stopped(gc,who); } } // User profile picture char * icon, * hash; int len; while (waAPI_queryicon(wconn->waAPI, &who, &icon, &len, &hash)) { purple_buddy_icons_set_for_user(acc,who, g_memdup(icon,len),len, hash); } // Groups update if (waAPI_getgroupsupdated(wconn->waAPI)) { // Delete/update the chats that are in our list PurpleBlistNode* node = purple_blist_get_root(); while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleChat * ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == acc) { int found = 0; GHashTable *hasht = purple_chat_get_components(ch); char * grid = g_hash_table_lookup(hasht, "id"); char * glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist,",",0); while (*gplist) { if (strcmp(*gplist,grid) == 0) { // The group is in the system, update the fields char *id,*sub,*own; waAPI_getgroupinfo(wconn->waAPI, *gplist, &sub, &own, 0); g_hash_table_insert(hasht, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(hasht, g_strdup("owner"), g_strdup(own)); found = 1; break; } gplist++; } // The group was deleted if (!found) { PurpleBlistNode* del = node; node = purple_blist_node_next(node,FALSE); purple_blist_remove_chat(del); } } } node = purple_blist_node_next(node,FALSE); } // Add new groups char * glist = waAPI_getgroups(wconn->waAPI); gchar **gplist = g_strsplit(glist,",",0); while (*gplist) { int found = 0; PurpleBlistNode* node = purple_blist_get_root(); PurpleChat * ch; while (node != 0) { if (PURPLE_BLIST_NODE_IS_CHAT(node)) { ch = PURPLE_CHAT(node); if (purple_chat_get_account(ch) == acc) { char * grid = g_hash_table_lookup(purple_chat_get_components(ch), "id"); if (strcmp(*gplist,grid) == 0) { found = 1; break; } } } node = purple_blist_node_next(node,FALSE); } if (!found) { char *sub,*own; waAPI_getgroupinfo(wconn->waAPI, *gplist, &sub, &own, 0); purple_debug_info("waprpl", "New group found %s %s\n", *gplist,sub); GHashTable * htable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); g_hash_table_insert(htable, g_strdup("subject"), g_strdup(sub)); g_hash_table_insert(htable, g_strdup("id"), g_strdup(*gplist)); g_hash_table_insert(htable, g_strdup("owner"), g_strdup(own)); ch = purple_chat_new(acc,sub,htable); purple_blist_add_chat(ch,NULL,NULL); } // Now update the open conversation that may exist char * id = g_hash_table_lookup(purple_chat_get_components(ch), "id"); int prplid = chatid_to_convo(id); PurpleConversation * conv = purple_find_chat(gc, prplid); if (conv) { char *subject, *owner, *part; if (!waAPI_getgroupinfo(wconn->waAPI, id, &subject, &owner, &part)) return; purple_conv_chat_clear_users(purple_conversation_get_chat_data(conv)); gchar **plist = g_strsplit(part,",",0); while (*plist) { purple_conv_chat_add_user (purple_conversation_get_chat_data(conv), *plist,"",PURPLE_CBFLAGS_NONE | (!strcmp(owner,*plist) ? PURPLE_CBFLAGS_FOUNDER : 0),FALSE); plist++; } } gplist++; } } }