static gboolean stress_event_cb(gpointer data) { StressBuddy *sb = (StressBuddy *)data; PurpleAccount *account = purple_buddy_get_account(sb->buddy); PurpleStatus *status = NULL; gint event = rand() % nevents; const gchar *name = purple_buddy_get_name(sb->buddy), *sevent = NULL; gchar *msg = NULL; /* increment our event counter */ sb->nevents++; event = GPOINTER_TO_INT(g_list_nth_data(events, event)); switch(event) { case STRESS_EVENT_SIGN_ON: sevent = "signon"; break; case STRESS_EVENT_SIGN_OFF: sevent = "signoff"; break; case STRESS_EVENT_IDLE: sevent = "idle"; break; case STRESS_EVENT_UNIDLE: sevent = "unidle"; break; case STRESS_EVENT_AWAY: sevent = "away"; break; case STRESS_EVENT_BACK: sevent = "back"; break; case STRESS_EVENT_TYPING: sevent = "typing"; break; case STRESS_EVENT_STOPPED_TYPING: sevent = "stopped typing"; break; case STRESS_EVENT_SEND_MESSAGE: sevent = "message"; break; } purple_debug_info("stress", "firing '%s' for '%s' (event %d of %d)\n", sevent, name, sb->nevents, sb->maxevents); switch(event) { case STRESS_EVENT_SIGN_ON: case STRESS_EVENT_BACK: purple_prpl_got_user_status(account, name, "available", NULL); break; case STRESS_EVENT_SIGN_OFF: purple_prpl_got_user_status(account, name, "offline", NULL); break; case STRESS_EVENT_IDLE: purple_prpl_got_user_idle(account, name, TRUE, 0); break; case STRESS_EVENT_UNIDLE: purple_prpl_got_user_idle(account, name, FALSE, 0); break; case STRESS_EVENT_AWAY: purple_prpl_got_user_status(account, name, "away", NULL); break; case STRESS_EVENT_SEND_MESSAGE: stress_send_im(account, sb->buddy, name); break; } msg = g_strdup_printf("event %d of %d", sb->nevents, sb->maxevents); status = purple_presence_get_active_status(sb->buddy->presence); purple_status_set_attr_string(status, "message", msg); g_free(msg); if(sb->maxevents > 0 && sb->nevents >= sb->maxevents) { purple_prpl_got_user_status(account, name, "available", "message", _("Done"), NULL); purple_prpl_got_user_idle(account, name, FALSE, 0); stress_close_convs(account, name); return FALSE; } return TRUE; }
static void add_purple_buddy_to_groups(JabberStream *js, const char *jid, const char *alias, GSList *groups) { GSList *buddies, *l; PurpleAccount *account = purple_connection_get_account(js->gc); buddies = purple_find_buddies(js->gc->account, jid); if(!groups) { if(!buddies) groups = g_slist_append(groups, g_strdup(_("Buddies"))); else { /* TODO: What should we do here? Removing the local buddies * is wrong, but so is letting the group state get out of sync with * the server. */ g_slist_free(buddies); return; } } while(buddies) { PurpleBuddy *b = buddies->data; PurpleGroup *g = purple_buddy_get_group(b); buddies = g_slist_delete_link(buddies, buddies); /* XMPP groups are case-sensitive, but libpurple groups are * case-insensitive. We treat a buddy in both "Friends" and "friends" * as only being in one group, but if we push changes about the buddy * to the server, the buddy will be dropped from one of the groups. * Not optimal, but better than the alternative, I think. */ if((l = g_slist_find_custom(groups, purple_group_get_name(g), (GCompareFunc)purple_utf8_strcasecmp))) { /* The buddy is already on the local list. Update info. */ const char *servernick, *balias; /* Previously stored serverside / buddy-supplied alias */ if((servernick = purple_blist_node_get_string((PurpleBlistNode*)b, "servernick"))) serv_got_alias(js->gc, jid, servernick); /* Alias from our roster retrieval */ balias = purple_buddy_get_local_buddy_alias(b); if(alias && !purple_strequal(alias, balias)) purple_serv_got_private_alias(js->gc, jid, alias); g_free(l->data); groups = g_slist_delete_link(groups, l); } else { /* This buddy isn't in the group on the server anymore */ purple_debug_info("jabber", "jabber_roster_parse(): Removing %s " "from group '%s' on the local list\n", purple_buddy_get_name(b), purple_group_get_name(g)); purple_blist_remove_buddy(b); } } if (groups) { char *tmp = roster_groups_join(groups); purple_debug_info("jabber", "jabber_roster_parse(): Adding %s to " "groups: %s\n", jid, tmp); g_free(tmp); } while(groups) { PurpleGroup *g = purple_find_group(groups->data); PurpleBuddy *b = purple_buddy_new(account, jid, alias); if(!g) { g = purple_group_new(groups->data); purple_blist_add_group(g, NULL); } purple_blist_add_buddy(b, NULL, g, NULL); purple_blist_alias_buddy(b, alias); g_free(groups->data); groups = g_slist_delete_link(groups, groups); } g_slist_free(buddies); }
/************************************************************************** * Buddy List subsystem signal callbacks **************************************************************************/ static void buddy_status_changed_cb(PurpleBuddy *buddy, PurpleStatus *old_status, PurpleStatus *status) { char *status_name, *old_status_name, *status_msg; char* buddy_nick, *buddy_name, *icon_path, *growl_msg; PurpleBuddyIcon* icon; int len, hack_ms; PurpleAccount* account; DEBUG_MSG("buddy_status_changed_cb\n"); g_return_if_fail( buddy != NULL ); account = purple_buddy_get_account(buddy); g_return_if_fail( is_allowed(account) ); status_name = (char *)purple_status_get_name(status); old_status_name = (char *)purple_status_get_name(old_status); buddy_nick = (char*)purple_buddy_get_alias(buddy); buddy_name = (char*)purple_buddy_get_name(buddy); icon = purple_buddy_get_icon(buddy); icon_path = (char*)purple_buddy_icon_get_full_path(icon); status_msg = custom_get_buddy_status_text(buddy); if( status_msg == NULL ) status_msg = ""; special_entries(status_msg); strip_tags(status_msg); //hack to hide spam when signing on to account hack_ms = purple_prefs_get_int("/plugins/core/pidgin-gntp/hack_ms"); GList *node = buddy_status_is_new(buddy, status_msg); if( GetTickCount() - start_tick_im < hack_ms) return; if( node != NULL ) { DEBUG_MSG("status node received\n"); struct buddy_status* node_status = node->data; free(node_status->status); char* the_status = malloc( s_strlen(status_msg)+1 ); strcpy(the_status, status_msg); node_status->status = the_status; if(status_msg[0] == 0) { len = s_strlen(buddy_nick) + s_strlen(buddy_name) + 25; growl_msg = malloc( len ); g_snprintf(growl_msg, len, "status message removed\n%s\n%s",buddy_nick, buddy_name ); gntp_notify("buddy-change-msg", icon_path, "Status Message Changed", growl_msg, NULL); free(growl_msg); } else { len = s_strlen(buddy_nick) + s_strlen(buddy_name) + s_strlen(status_msg)+5; growl_msg = malloc( len ); g_snprintf(growl_msg, len, "\"%s\"\n%s\n%s", status_msg, buddy_nick, buddy_name ); gntp_notify("buddy-change-msg", icon_path, "Status Changed", growl_msg, NULL); free(growl_msg); } } if( strcmp(status_name, old_status_name) == 0) return; len = s_strlen(buddy_nick) + s_strlen(buddy_name) + s_strlen(status_name) + 3; growl_msg = malloc( len ); g_snprintf(growl_msg, len, "%s\n%s\n%s", status_name, buddy_nick, buddy_name ); gntp_notify("buddy-change-status", icon_path, "Status Changed", growl_msg, NULL); free(growl_msg); }
static void silcpurple_add_buddy_save(bool success, void *context) { SilcPurpleBuddyRes r = context; PurpleBuddy *b = r->b; SilcClient client = r->client; SilcClientEntry client_entry; SilcAttributePayload attr; SilcAttribute attribute; SilcVCardStruct vcard; SilcAttributeObjMime message, extension; #ifdef SILC_ATTRIBUTE_USER_ICON SilcAttributeObjMime usericon; #endif SilcAttributeObjPk serverpk, usersign, serversign; gboolean usign_success = TRUE, ssign_success = TRUE; char filename[512], filename2[512], *fingerprint = NULL, *tmp; SilcUInt32 len; int i; if (!success) { /* The user did not trust the public key. */ silcpurple_add_buddy_pk_no(r); silc_free(r); return; } if (r->offline) { /* User is offline. Associate the imported public key with this user. */ fingerprint = silc_hash_fingerprint(NULL, r->offline_pk, r->offline_pk_len); for (i = 0; i < strlen(fingerprint); i++) if (fingerprint[i] == ' ') fingerprint[i] = '_'; g_snprintf(filename, sizeof(filename) - 1, "%s" G_DIR_SEPARATOR_S "clientkeys" G_DIR_SEPARATOR_S "clientkey_%s.pub", silcpurple_silcdir(), fingerprint); purple_blist_node_set_string((PurpleBlistNode *)b, "public-key", filename); purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_OFFLINE, NULL); silc_free(fingerprint); silc_free(r->offline_pk); silc_free(r); return; } /* Get the client entry. */ client_entry = silc_client_get_client_by_id(r->client, r->conn, &r->client_id); if (!client_entry) { silc_free(r); return; } memset(&vcard, 0, sizeof(vcard)); memset(&message, 0, sizeof(message)); memset(&extension, 0, sizeof(extension)); #ifdef SILC_ATTRIBUTE_USER_ICON memset(&usericon, 0, sizeof(usericon)); #endif memset(&serverpk, 0, sizeof(serverpk)); memset(&usersign, 0, sizeof(usersign)); memset(&serversign, 0, sizeof(serversign)); /* Now that we have the public key and we trust it now we save the attributes of the buddy and update its status. */ if (client_entry->attrs) { silc_dlist_start(client_entry->attrs); while ((attr = silc_dlist_get(client_entry->attrs)) != SILC_LIST_END) { attribute = silc_attribute_get_attribute(attr); switch (attribute) { case SILC_ATTRIBUTE_USER_INFO: if (!silc_attribute_get_object(attr, (void *)&vcard, sizeof(vcard))) continue; break; case SILC_ATTRIBUTE_STATUS_MESSAGE: if (!silc_attribute_get_object(attr, (void *)&message, sizeof(message))) continue; break; case SILC_ATTRIBUTE_EXTENSION: if (!silc_attribute_get_object(attr, (void *)&extension, sizeof(extension))) continue; break; #ifdef SILC_ATTRIBUTE_USER_ICON case SILC_ATTRIBUTE_USER_ICON: if (!silc_attribute_get_object(attr, (void *)&usericon, sizeof(usericon))) continue; break; #endif case SILC_ATTRIBUTE_SERVER_PUBLIC_KEY: if (serverpk.type) continue; if (!silc_attribute_get_object(attr, (void *)&serverpk, sizeof(serverpk))) continue; break; case SILC_ATTRIBUTE_USER_DIGITAL_SIGNATURE: if (usersign.data) continue; if (!silc_attribute_get_object(attr, (void *)&usersign, sizeof(usersign))) continue; break; case SILC_ATTRIBUTE_SERVER_DIGITAL_SIGNATURE: if (serversign.data) continue; if (!silc_attribute_get_object(attr, (void *)&serversign, sizeof(serversign))) continue; break; default: break; } } } /* Verify the attribute signatures */ if (usersign.data) { SilcPKCS pkcs; unsigned char *verifyd; SilcUInt32 verify_len; silc_pkcs_alloc((unsigned char*)"rsa", &pkcs); verifyd = silc_attribute_get_verify_data(client_entry->attrs, FALSE, &verify_len); if (verifyd && silc_pkcs_public_key_set(pkcs, client_entry->public_key)){ if (!silc_pkcs_verify_with_hash(pkcs, client->sha1hash, usersign.data, usersign.data_len, verifyd, verify_len)) usign_success = FALSE; } silc_free(verifyd); } if (serversign.data && !strcmp(serverpk.type, "silc-rsa")) { SilcPublicKey public_key; SilcPKCS pkcs; unsigned char *verifyd; SilcUInt32 verify_len; if (silc_pkcs_public_key_decode(serverpk.data, serverpk.data_len, &public_key)) { silc_pkcs_alloc((unsigned char *)"rsa", &pkcs); verifyd = silc_attribute_get_verify_data(client_entry->attrs, TRUE, &verify_len); if (verifyd && silc_pkcs_public_key_set(pkcs, public_key)) { if (!silc_pkcs_verify_with_hash(pkcs, client->sha1hash, serversign.data, serversign.data_len, verifyd, verify_len)) ssign_success = FALSE; } silc_pkcs_public_key_free(public_key); silc_free(verifyd); } } fingerprint = silc_fingerprint(client_entry->fingerprint, client_entry->fingerprint_len); for (i = 0; i < strlen(fingerprint); i++) if (fingerprint[i] == ' ') fingerprint[i] = '_'; if (usign_success || ssign_success) { struct passwd *pw; struct stat st; memset(filename2, 0, sizeof(filename2)); /* Filename for dir */ tmp = fingerprint + strlen(fingerprint) - 9; g_snprintf(filename, sizeof(filename) - 1, "%s" G_DIR_SEPARATOR_S "friends" G_DIR_SEPARATOR_S "%s", silcpurple_silcdir(), tmp); pw = getpwuid(getuid()); if (!pw) return; /* Create dir if it doesn't exist */ if ((g_stat(filename, &st)) == -1) { if (errno == ENOENT) { if (pw->pw_uid == geteuid()) { int ret = g_mkdir(filename, 0755); if (ret < 0) return; } } } /* Save VCard */ g_snprintf(filename2, sizeof(filename2) - 1, "%s" G_DIR_SEPARATOR_S "vcard", filename); if (vcard.full_name) { tmp = (char *)silc_vcard_encode(&vcard, &len); silc_file_writefile(filename2, tmp, len); silc_free(tmp); } /* Save status message */ if (message.mime) { memset(filename2, 0, sizeof(filename2)); g_snprintf(filename2, sizeof(filename2) - 1, "%s" G_DIR_SEPARATOR_S "status_message.mime", filename); silc_file_writefile(filename2, (char *)message.mime, message.mime_len); } /* Save extension data */ if (extension.mime) { memset(filename2, 0, sizeof(filename2)); g_snprintf(filename2, sizeof(filename2) - 1, "%s" G_DIR_SEPARATOR_S "extension.mime", filename); silc_file_writefile(filename2, (char *)extension.mime, extension.mime_len); } #ifdef SILC_ATTRIBUTE_USER_ICON /* Save user icon */ if (usericon.mime) { SilcMime m = silc_mime_decode(usericon.mime, usericon.mime_len); if (m) { const char *type = silc_mime_get_field(m, "Content-Type"); if (!strcmp(type, "image/jpeg") || !strcmp(type, "image/gif") || !strcmp(type, "image/bmp") || !strcmp(type, "image/png")) { const unsigned char *data; SilcUInt32 data_len; data = silc_mime_get_data(m, &data_len); if (data) { /* TODO: Check if SILC gives us something to use as the checksum instead */ purple_buddy_icons_set_for_user(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), g_memdup(data, data_len), data_len, NULL); } } silc_mime_free(m); } } #endif } /* Save the public key path to buddy properties, as it is used to identify the buddy in the network (and not the nickname). */ memset(filename, 0, sizeof(filename)); g_snprintf(filename, sizeof(filename) - 1, "%s" G_DIR_SEPARATOR_S "clientkeys" G_DIR_SEPARATOR_S "clientkey_%s.pub", silcpurple_silcdir(), fingerprint); purple_blist_node_set_string((PurpleBlistNode *)b, "public-key", filename); /* Update online status */ purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_AVAILABLE, NULL); /* Finally, start watching this user so we receive its status changes from the server */ g_snprintf(filename2, sizeof(filename2) - 1, "+%s", filename); silc_client_command_call(r->client, r->conn, NULL, "WATCH", "-pubkey", filename2, NULL); silc_free(fingerprint); silc_free(r); }
/** * Append user information to a PurpleNotifyUserInfo, given an MsimUser. * Used by msim_tooltip_text() and msim_get_info_cb() to show a user's profile. */ void msim_append_user_info(MsimSession *session, PurpleNotifyUserInfo *user_info, MsimUser *user, gboolean full) { PurplePresence *presence; gchar *str; guint cv; /* Useful to identify the account the tooltip refers to. * Other prpls show this. */ if (user->username) { purple_notify_user_info_add_pair(user_info, _("User"), user->username); } /* a/s/l...the vitals */ if (user->age) { char age[16]; g_snprintf(age, sizeof(age), "%d", user->age); purple_notify_user_info_add_pair(user_info, _("Age"), age); } if (user->gender && *user->gender) { purple_notify_user_info_add_pair(user_info, _("Gender"), user->gender); } if (user->location && *user->location) { purple_notify_user_info_add_pair(user_info, _("Location"), user->location); } /* Other information */ if (user->headline && *user->headline) { purple_notify_user_info_add_pair(user_info, _("Headline"), user->headline); } if (user->buddy != NULL) { presence = purple_buddy_get_presence(user->buddy); if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_TUNE)) { PurpleStatus *status; const char *artist, *title; status = purple_presence_get_status(presence, "tune"); title = purple_status_get_attr_string(status, PURPLE_TUNE_TITLE); artist = purple_status_get_attr_string(status, PURPLE_TUNE_ARTIST); str = msim_format_now_playing(artist, title); if (str && *str) { purple_notify_user_info_add_pair(user_info, _("Song"), str); } g_free(str); } } /* Note: total friends only available if looked up by uid, not username. */ if (user->total_friends) { char friends[16]; g_snprintf(friends, sizeof(friends), "%d", user->total_friends); purple_notify_user_info_add_pair(user_info, _("Total Friends"), friends); } if (full) { /* Client information */ char *client = NULL; str = user->client_info; cv = user->client_cv; if (str && cv != 0) { client = g_strdup_printf("%s (build %d)", str, cv); } else if (str) { client = g_strdup(str); } else if (cv) { client = g_strdup_printf("Build %d", cv); } if (client && *client) purple_notify_user_info_add_pair(user_info, _("Client Version"), client); g_free(client); } if (full && user->id) { /* TODO: link to username, if available */ char *profile; purple_notify_user_info_add_section_break(user_info); if (user->buddy != NULL) profile = g_strdup_printf("<a href=\"http://myspace.com/%s\">%s</a>", purple_buddy_get_name(user->buddy), _("View web profile")); else profile = g_strdup_printf("<a href=\"http://myspace.com/%d\">%s</a>", user->id, _("View web profile")); purple_notify_user_info_add_pair(user_info, NULL, profile); g_free(profile); } }
void skypeweb_auth_reject_cb(gpointer sender) { PurpleBuddy *buddy = sender; SkypeWebAccount *sa; gchar *url = NULL; sa = purple_connection_get_protocol_data(purple_account_get_connection(purple_buddy_get_account(buddy))); url = g_strdup_printf("/users/self/contacts/auth-request/%s/decline", purple_url_encode(purple_buddy_get_name(buddy))); skypeweb_post_or_get(sa, SKYPEWEB_METHOD_PUT | SKYPEWEB_METHOD_SSL, SKYPEWEB_CONTACTS_HOST, url, NULL, NULL, NULL, TRUE); g_free(url); }
static void got_buddy_list_cb(FacebookAccount *fba, gchar *data, gsize data_len, gpointer userdata) { GSList *buddies_list; GSList *online_buddies_list = NULL; PurpleBuddy *buddy; FacebookBuddy *fbuddy; gchar *uid; gchar *name; gchar *status_text; gchar *status_time_text; gchar *buddy_icon_url; gboolean idle; guint32 error_number; gchar *search_start; gchar *search_tmp; gchar *tmp; gchar *largest_buddy_search_point = NULL; PurpleGroup *fb_group = NULL; gboolean current_buddy_online = FALSE; purple_debug_info("facebook", "parsing buddy list\n"); purple_debug_misc("facebook", "buddy list\n%s\n", data); if (fba == NULL) return; if (data == NULL) { purple_connection_error_reason(fba->pc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Could not retrieve buddy list")); return; } /* Check if the facebook group already exists (fixes #13) */ fb_group = purple_find_group("Facebook"); /* if logged out, this comes up */ /* for (;;);{"error":1357001,"errorSummary":"Not Logged In", "errorDescription":"You must be logged in to do that.", "payload":null,"bootload":[{"name":"js\/common.js.pkg.php", "type":"js","src":"http:\/\/static.ak.fbcdn.net\/rsrc.php\/pkg\/59\ /98561\/js\/common.js.pkg.php"}]} */ tmp = g_strstr_len(data, data_len, "\"error\":"); if (tmp != NULL) { tmp += 9; tmp = g_strndup(tmp, strchr(tmp, ',')-tmp); error_number = atoi(tmp); g_free(tmp); if (error_number) { /* error :( */ tmp = g_strstr_len(data, data_len, "\"errorDescription\":"); tmp += 20; tmp = g_strndup(tmp, strchr(tmp, '"')-tmp); /* TODO: Use purple_connection_error_reason() */ purple_connection_error(fba->pc, tmp); g_free(tmp); return; } } /* look for "userInfos":{ ... }, */ search_start = strstr(data, "\"userInfos\":{"); if (search_start == NULL) return; search_start += 13; while (*search_start != '}' && (search_start - data < data_len)) { tmp = strchr(search_start, ':'); uid = g_strndup(search_start+1, tmp-search_start-2); /* purple_debug_misc("facebook", "uid: %s\n", uid); */ search_start += strlen(uid) + 2; search_tmp = strstr(search_start, "\"name\":") + 8; if (search_tmp > largest_buddy_search_point) largest_buddy_search_point = search_tmp; search_tmp = g_strndup(search_tmp, strchr(search_tmp, '"')-search_tmp); name = fb_convert_unicode(search_tmp); g_free(search_tmp); /* purple_debug_misc("facebook", "name: %s\n", name); */ /* try updating the alias, just in case it was removed locally */ serv_got_alias(fba->pc, uid, name); /* look for "uid":{"i":_____} */ tmp = g_strdup_printf("\"%s\":{\"i\":", uid); search_tmp = g_strstr_len(data, data_len, tmp); if (search_tmp != NULL) { search_tmp += strlen(tmp); if (search_tmp > largest_buddy_search_point) largest_buddy_search_point = search_tmp; search_tmp = g_strndup(search_tmp, strchr(search_tmp, '}')-search_tmp); /* purple_debug_misc("facebook", "buddy idle: %s\n", search_tmp); */ buddy = purple_find_buddy(fba->account, uid); idle = g_str_equal(search_tmp, "true"); g_free(search_tmp); current_buddy_online = TRUE; } else { /* if we're here, the buddy's info has been sent, but they're not actually online */ current_buddy_online = FALSE; idle = FALSE; } g_free(tmp); /* Set the buddy status text and time */ search_tmp = strstr(search_start, "\"status\":"); if (search_tmp != NULL && *(search_tmp + 9) == '"') { search_tmp += 10; if (search_tmp > largest_buddy_search_point) largest_buddy_search_point = strstr(search_tmp, ",\"statusTime"); search_tmp = g_strndup(search_tmp, strstr(search_tmp, ",\"statusTime")-1-search_tmp); status_text = fb_convert_unicode(search_tmp); g_free(search_tmp); } else { status_text = NULL; } /* is this us? */ if (atoi(uid) == fba->uid) { purple_connection_set_display_name(fba->pc, name); /* set our last known status so that we don't re-set it */ if (status_text && !fba->last_status_message) fba->last_status_message = g_strdup(status_text); /* check that we don't want to show ourselves */ if (purple_account_get_bool(fba->account, "facebook_hide_self", TRUE)) { g_free(status_text); g_free(name); g_free(uid); /* Move pointer to the end of the buddy entry */ search_start = strchr(largest_buddy_search_point, '}') + 1; while (*search_start == ',' && (search_start - data < data_len)) search_start++; /* go on to the next buddy */ continue; } else { current_buddy_online = TRUE; } } /* Is this a new buddy? */ buddy = purple_find_buddy(fba->account, uid); if (buddy == NULL) { buddy = purple_buddy_new(fba->account, uid, NULL); if (fb_group == NULL) { fb_group = purple_group_new("Facebook"); purple_blist_add_group(fb_group, NULL); } purple_blist_add_buddy(buddy, NULL, fb_group, NULL); } serv_got_alias(fba->pc, uid, name); purple_presence_set_idle(purple_buddy_get_presence(buddy), idle, 0); /* Set the FacebookBuddy structure */ if (buddy->proto_data == NULL) { fbuddy = g_new0(FacebookBuddy, 1); fbuddy->buddy = buddy; fbuddy->fba = fba; fbuddy->uid = atoi(uid); fbuddy->name = g_strdup(name); /* load the old buddy icon from the account settings */ tmp = g_strdup_printf("buddy_icon_%d_cache", fbuddy->uid); fbuddy->thumb_url = g_strdup(purple_account_get_string(fba->account, tmp, "")); g_free(tmp); buddy->proto_data = fbuddy; } else { fbuddy = buddy->proto_data; } g_free(uid); g_free(name); if (status_text != NULL) { tmp = fb_strdup_withhtml(status_text); g_free(status_text); status_text = tmp; /* purple_debug_misc("facebook", "status: %s\n", status_text); */ search_tmp = strstr(search_start, "\"statusTimeRel\":") + 17; if (search_tmp > largest_buddy_search_point) largest_buddy_search_point = strchr(search_tmp, '"'); search_tmp = g_strndup(search_tmp, strchr(search_tmp, '"')-search_tmp); status_time_text = fb_convert_unicode(search_tmp); g_free(search_tmp); if (g_str_equal(status_time_text, "ull,")) { g_free(status_time_text); status_time_text = NULL; } g_free(fbuddy->status_rel_time); if (status_time_text != NULL) { fbuddy->status_rel_time = fb_strdup_withhtml(status_time_text); g_free(status_time_text); /* purple_debug_misc("facebook", "status time: %s\n", fbuddy->status_rel_time); */ } else { fbuddy->status_rel_time = NULL; } /* if the buddy status has changed, update the contact list */ if (fbuddy->status == NULL || !g_str_equal(fbuddy->status, status_text)) { tmp = fbuddy->status; fbuddy->status = status_text; g_free(tmp); if (current_buddy_online) purple_prpl_got_user_status(fba->account, buddy->name, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL); } else { g_free(status_text); } } else { if (fbuddy->status != NULL) { g_free(fbuddy->status); fbuddy->status = NULL; if (current_buddy_online) { /* update the status in the contact list */ purple_prpl_got_user_status(fba->account, buddy->name, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL); } } } /* Set the buddy icon (if it hasn't changed) */ search_tmp = strstr(search_start, "\"thumbSrc\":") + 12; if (search_tmp > largest_buddy_search_point) largest_buddy_search_point = search_tmp; buddy_icon_url = g_strndup(search_tmp, strchr(search_tmp, '"')-search_tmp); if (fbuddy->thumb_url == NULL || !g_str_equal(fbuddy->thumb_url, buddy_icon_url)) { g_free(fbuddy->thumb_url); fbuddy->thumb_url = g_strdup(buddy_icon_url); /* Save the buddy icon so that they don't all need to be reloaded at startup */ tmp = g_strdup_printf("buddy_icon_%d_cache", fbuddy->uid); purple_account_set_string(fba->account, tmp, buddy_icon_url); g_free(tmp); /* Turn the \/ into / */ tmp = g_strcompress(buddy_icon_url); /* small icon at http://profile.ak.facebook.com/profile6/1845/74/q800753867_2878.jpg */ /* bigger icon at http://profile.ak.facebook.com/profile6/1845/74/n800753867_2878.jpg */ search_tmp = strstr(tmp, "/q"); if (search_tmp) *(search_tmp + 1) = 'n'; if (g_str_equal(tmp, "http://static.ak.fbcdn.net/pics/q_silhouette.gif")) /* User has no icon */ purple_buddy_icons_set_for_user(fba->account, purple_buddy_get_name(buddy), NULL, 0, NULL); else /* Fetch their icon */ fb_post_or_get(fba, FB_METHOD_GET, "profile.ak.facebook.com", tmp + strlen("http://profile.ak.facebook.com"), NULL, buddy_icon_cb, g_strdup(purple_buddy_get_name(buddy)), FALSE); g_free(tmp); } g_free(buddy_icon_url); if (current_buddy_online) { /* Add buddy to the list of online buddies */ online_buddies_list = g_slist_append(online_buddies_list, buddy); /* Update the display of the buddy in the buddy list and make the user online */ if (!PURPLE_BUDDY_IS_ONLINE(buddy)) purple_prpl_got_user_status(fba->account, buddy->name, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL); } /* Move pointer after any user configurable data */ search_start = search_tmp; /* Move pointer to the end of the buddy entry */ search_start = strchr(largest_buddy_search_point, '}') + 1; while (*search_start == ',' && (search_start - data < data_len)) search_start++; } buddies_list = purple_find_buddies(fba->account, NULL); if (buddies_list != NULL) { g_slist_foreach(buddies_list, (GFunc)set_buddies_offline, online_buddies_list); g_slist_free(buddies_list); } g_slist_free(online_buddies_list); }