static void buddytimezone_submitfields_cb(PurpleRequestFields * fields, PurpleBlistNode * data) { PurpleBlistNode *node; PurpleRequestField *list; /* timezone stuff */ purple_debug(PURPLE_DEBUG_INFO, PLUGIN_STATIC_NAME, "buddytimezone_submitfields_cb(%p,%p)\n", fields, data); switch (data->type) { case PURPLE_BLIST_BUDDY_NODE: node = (PurpleBlistNode *) purple_buddy_get_contact((PurpleBuddy *) data); break; case PURPLE_BLIST_CONTACT_NODE: case PURPLE_BLIST_GROUP_NODE: /* code handles either case */ node = data; break; case PURPLE_BLIST_CHAT_NODE: case PURPLE_BLIST_OTHER_NODE: default: /* Not applicable */ return; } list = purple_request_fields_get_field(fields, CONTROL_NAME); if (ui_ops != NULL && ui_ops->get_timezone_menu_selection != NULL) { const char *seldata = ui_ops->get_timezone_menu_selection(list->ui_data); if (seldata == NULL) purple_blist_node_remove_setting(node, SETTING_NAME); else purple_blist_node_set_string(node, SETTING_NAME, seldata); } else { const GList *sellist; void *seldata = NULL; sellist = purple_request_field_list_get_selected(list); if (sellist) seldata = purple_request_field_list_get_data(list, sellist->data); /* Otherwise, it's fixed value and this means deletion */ if (seldata == TIMEZONE_FLAG) purple_blist_node_set_string(node, SETTING_NAME, sellist->data); else if (seldata == DISABLED_FLAG) purple_blist_node_set_string(node, SETTING_NAME, "none"); else purple_blist_node_remove_setting(node, SETTING_NAME); } }
static void plainprpl_add_buddy_by_contact_request_ok(void *ptr, PurpleRequestFields *fields) { PurpleBuddy *buddy = (PurpleBuddy *) ptr; PurpleAccount *account = buddy->account; plain_plugin_state *pstate; plain_buddy_state *bstate; char *addr_str; const char *name; IP addr; name = purple_request_fields_get_string(fields, "name"); //invite_msg = purple_request_fields_get_string(fields, "invite_msg"); if (name == NULL && strlen(name) == 0) { purple_notify_error(ptr, "Invalid Name", _("Name was empty."), _("You need to enter a name.")); purple_blist_remove_buddy(buddy); } else { addr_str = g_strdup(buddy->name); purple_blist_node_set_string(PURPLE_BLIST_NODE(buddy), "addr_str", addr_str); assert(purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy), "addr_str") != NULL); purple_blist_rename_buddy(buddy, name); g_free(addr_str); pstate = purple_connection_get_protocol_data(buddy->account->gc); bstate = add_buddy_sdata(buddy, pstate); assert(addr_parse_full(&addr, addr_str, PLAIN_DEFAULT_PORT_STR, pstate->sockaf) == 0); addr_parse_full(&addr, addr_str, PLAIN_DEFAULT_PORT_STR, pstate->sockaf); memcpy(&bstate->addr, &addr, sizeof(IP)); purple_prpl_got_user_status(account, buddy->name, PLAIN_STATUS_ONLINE, NULL); } pstate->block_unknown = FALSE; }
void translate_receiving_chat_msg_cb(const gchar *original_phrase, const gchar *translated_phrase, const gchar *detected_language, gpointer userdata) { struct TranslateConvMessage *convmsg = userdata; PurpleChat *chat; gchar *html_text; const gchar *stored_lang = ""; const gchar *language_name = NULL; gchar *message; if (detected_language) { chat = purple_blist_find_chat(convmsg->account, convmsg->conv->name); stored_lang = purple_blist_node_get_string((PurpleBlistNode *)chat, DEST_LANG_SETTING); purple_blist_node_set_string((PurpleBlistNode *)chat, DEST_LANG_SETTING, detected_language); language_name = get_language_name(detected_language); if (language_name != NULL) { message = g_strdup_printf("Now translating to %s (auto-detected)", language_name); purple_conversation_write(convmsg->conv, NULL, message, PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG, time(NULL)); g_free(message); } } html_text = purple_strdup_withhtml(translated_phrase); purple_conversation_write(convmsg->conv, convmsg->sender, html_text, convmsg->flags, time(NULL)); g_free(html_text); g_free(convmsg->sender); g_free(convmsg); }
static void translate_action_blist_cb(PurpleBlistNode *node, PurpleKeyValuePair *pair) { PurpleConversation *conv = NULL; gchar *message; PurpleChat *chat; PurpleContact *contact; PurpleBuddy *buddy; if (pair == NULL) purple_blist_node_set_string(node, DEST_LANG_SETTING, NULL); else purple_blist_node_set_string(node, DEST_LANG_SETTING, pair->key); switch(node->type) { case PURPLE_BLIST_CHAT_NODE: chat = (PurpleChat *) node; conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, purple_chat_get_name(chat), chat->account); break; case PURPLE_BLIST_CONTACT_NODE: contact = (PurpleContact *) node; node = (PurpleBlistNode *)purple_contact_get_priority_buddy(contact); //fallthrough intentional case PURPLE_BLIST_BUDDY_NODE: buddy = (PurpleBuddy *) node; conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)); break; default: break; } if (conv != NULL && pair != NULL) { message = g_strdup_printf("Now translating to %s", (const gchar *)pair->value); purple_conversation_write(conv, NULL, message, PURPLE_MESSAGE_SYSTEM | PURPLE_MESSAGE_NO_LOG, time(NULL)); g_free(message); } }
void lh_util_add_buddy(const gchar *group, PurpleGroup *purple_group, const gchar *buddy, const gchar *alias, PurpleAccount *account, const gchar *buddynotes, gint signed_on, gint signed_off, gint lastseen, gint last_seen, const gchar *gf_theme, const gchar *icon_file, gchar *lastsaid) { PurpleBuddy *purple_buddy = NULL; PurpleBlistNode *node = NULL; purple_buddy = purple_buddy_new(account, buddy, alias); node = (PurpleBlistNode *)purple_buddy; purple_blist_add_buddy(purple_buddy, NULL, purple_group, NULL); #if PURPLE_VERSION_CHECK(3,0,0) purple_account_add_buddy(account, purple_buddy, NULL); #else purple_account_add_buddy(account, purple_buddy); #endif if(buddynotes) purple_blist_node_set_string(node, "notes", buddynotes); if(signed_on) purple_blist_node_set_int(node, "signedon", signed_on); if(signed_off) purple_blist_node_set_int(node, "signedoff", signed_off); if(lastseen) purple_blist_node_set_int(node, "lastseen", lastseen); if(last_seen) purple_blist_node_set_int(node, "last_seen", last_seen); if(gf_theme) purple_blist_node_set_string(node, "guifications-theme", gf_theme); if(icon_file) purple_blist_node_set_string(node, "buddy_icon", icon_file); if(lastsaid) purple_blist_node_set_string(node, "lastsaid", lastsaid); purple_debug_info("listhandler: import", "group: %s\tbuddy: %s\talias: %s\thas been added to the list\n", group, buddy, alias ? alias : "NULL"); return; }
void rc_push_contact(PurpleAccount *acct, const char * buddyname) { PurpleGroup * grp = purple_find_group(GROUP_NAME); if (!grp) { trace("Group %s Not Found. Create one.", GROUP_NAME); grp = purple_group_new(GROUP_NAME); } PurpleBuddy * buddy; // if we can find it in 'Recent Contacts', skip if ((buddy = purple_find_buddy_in_group(acct, buddyname, grp)) != NULL) { trace("Buddy %s is already in %s", buddyname, GROUP_NAME); purple_blist_add_buddy(buddy, NULL, grp, NULL); return; } buddy = purple_find_buddy(acct, buddyname); if (!buddy) { trace("Buddy %s Not Found. You SUCK!", buddyname); return; } PurpleBlistNode * node = PURPLE_BLIST_NODE(buddy); // back up group info PurpleGroup * orig_grp = purple_buddy_get_group(buddy); purple_blist_node_set_string(node, NODE_GROUP_KEY, orig_grp->name); // back up offline info gboolean offline = purple_blist_node_get_bool(node, NODE_OFFLINE_KEY); purple_blist_node_set_bool(node, NODE_ORIG_OFFLINE_KEY, offline); purple_blist_node_set_bool(node, NODE_OFFLINE_KEY, TRUE); // Add to Recent Contacts Group trace(">>>>>>> Add %s", buddyname); purple_blist_add_buddy(buddy, NULL, grp, NULL); // Clean up old group if needed rc_pop_contacts(grp); }
Contact *QuetzalContactsFactory::addContact(const QString &id, const QVariantMap &data) { QByteArray group = data.value(QLatin1String("group")).toString().toUtf8(); if (group.isEmpty()) { // For compatibility with other implementations // Looks like libpurple doesn't support multiple groups // Or does it at some unknown way group = data.value(QLatin1String("tags")).toStringList().value(0).toUtf8(); } QString name = data.value(QLatin1String("name")).toString(); const char *groupName = group.isEmpty() ? "Buddies" : group.constData(); PurpleGroup *pg = purple_find_group(groupName); if (!pg) { pg = purple_group_new(groupName); purple_blist_add_group(pg, quetzal_blist_get_last_sibling(purple_blist_get_root())); } PurpleContact *pc = purple_contact_new(); purple_blist_add_contact(pc, pg, quetzal_blist_get_last_child(PURPLE_BLIST_NODE(pg))); PurpleBuddy *buddy = purple_buddy_new(m_account->purple(), id.toUtf8().constData(), name.toUtf8().constData()); PurpleBlistNode *node = PURPLE_BLIST_NODE(buddy); purple_blist_add_buddy(buddy, pc, pg, quetzal_blist_get_last_child(PURPLE_BLIST_NODE(pc))); QMapIterator<QString, QVariant> it(data.value(QLatin1String("quetzal_settings")).toMap()); while (it.hasNext()) { it.next(); QByteArray key = it.key().toUtf8(); QVariant::Type type = it.value().type(); if (type == QVariant::Bool) { purple_blist_node_set_bool(node, key.constData(), it.value().toBool()); } else if (type == QVariant::Int || type == QVariant::UInt || type == QVariant::LongLong || type == QVariant::ULongLong) { purple_blist_node_set_int(node, key.constData(), it.value().toInt()); } else { purple_blist_node_set_string(node, key.constData(), it.value().toString().toUtf8()); } } QuetzalContact *contact = reinterpret_cast<QuetzalContact*>(node->ui_data); contact->update(buddy); return contact; }
static PurpleBuddy* spin_sync_buddy(SpinData* spin, GSList* buddies,const gchar* id, const gchar* name,guint online, const gchar* away,const gchar* photo) { PurpleAccount* account = purple_connection_get_account(spin->gc); /* gchar* lower_name = g_utf8_strdown(name,-1); */ PurpleBuddy* buddy = spin_find_buddy_in_list(buddies,id); if(!buddy) { purple_debug_info("spin","adding buddy: %s\n",/*lower_*/name); buddy = purple_buddy_new(account,/*lower_*/name,NULL); purple_blist_add_buddy(buddy,NULL,NULL,NULL); purple_blist_node_set_string(&buddy->node,"spin-id",id); } /* purple_normalize here? */ if(g_strcmp0(purple_buddy_get_name(buddy),name) != 0) { spin_notify_nick_changed(spin,purple_buddy_get_name(buddy),name); purple_blist_rename_buddy(buddy,name); } spin_sync_photo(spin,buddy,photo); /* do not set status if we got a status after the HTTP request */ if(g_hash_table_lookup(spin->updated_status_list, purple_normalize(account,name))) return buddy; if(online && *away) purple_prpl_got_user_status(account,/*lower_*/name,"away", "message",away,NULL); else if(online) purple_prpl_got_user_status(account,/*lower_*/name,"available",NULL); else purple_prpl_got_user_status(account,/*lower_*/name,"offline",NULL); return buddy; /* g_free(lower_name); */ }
static void plainprpl_add_buddy_ok(void *ptr, PurpleRequestFields *fields) { PurpleBuddy *buddy; PurpleConnection *gc; plain_plugin_state *pstate; plain_buddy_state *bstate; const char *addr_str; //const char* invite_msg; purple_debug_info("plainprpl", "plainprpl_add_buddy_ok\n"); buddy = (PurpleBuddy *) ptr; gc = purple_account_get_connection(buddy->account); addr_str = purple_request_fields_get_string(fields, "addr_str"); //invite_msg = purple_request_fields_get_string(fields, "invite_msg"); if (addr_str == NULL || strlen(addr_str) == 0) { purple_notify_error(ptr, "Invalid Address", _("The address was empty."), _("You need to enter a host name or an IP address.")); purple_blist_remove_buddy(buddy); } else { /* Finalize buddy creation */ purple_debug_info("plainprpl", "Add buddy %s\n", buddy->name); purple_blist_node_set_string(PURPLE_BLIST_NODE(buddy), "addr_str", addr_str); assert(purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy), "addr_str") != NULL); pstate = purple_connection_get_protocol_data(gc); bstate = add_buddy_sdata(buddy, pstate); pstate->time_next = 0; //handle now purple_prpl_got_user_status(buddy->account, buddy->name, PLAIN_STATUS_OFFLINE, NULL); /* if (invite_msg) { plainprpl_send_im(gc, buddy->name, invite_msg, 0); }*/ } }
static void plainprpl_change_address_ok(void *ptr, PurpleRequestFields *fields) { PurpleBuddy *buddy; plain_buddy_state *bstate; plain_plugin_state *pstate; PurpleRequestField *field; buddy = (PurpleBuddy *) ptr; bstate = purple_buddy_get_protocol_data(buddy); pstate = purple_connection_get_protocol_data(buddy->account->gc); field = purple_request_fields_get_field(fields, "addr_str"); const char *addr_str = purple_request_field_string_get_value(field); purple_blist_node_set_string(PURPLE_BLIST_NODE(buddy), "addr_str", addr_str); //resolve address again bstate->state = BUDDY_STATE_RESOLVE; bstate->state_step = 0; bstate->state_next = 0; bstate->time_recv = 0; bstate->time_send = 0; //handle now pstate->time_next = 0; }
static void tgp_info_update_photo_id (PurpleBlistNode *node, long long photo) { char *llid = g_strdup_printf ("%" G_GINT64_FORMAT, (gint64) photo); debug ("tgp_info_update_photo_id %s", llid); purple_blist_node_set_string (node, TGP_INFO_PHOTO_ID, llid); g_free (llid); }
PurpleStoredImage * purple_buddy_icons_node_set_custom_icon(PurpleBlistNode *node, guchar *icon_data, size_t icon_len) { char *old_icon; PurpleStoredImage *old_img; PurpleStoredImage *img = NULL; g_return_val_if_fail(node != NULL, NULL); if (!PURPLE_BLIST_NODE_IS_CONTACT(node) && !PURPLE_BLIST_NODE_IS_CHAT(node) && !PURPLE_BLIST_NODE_IS_GROUP(node)) { return NULL; } old_img = g_hash_table_lookup(pointer_icon_cache, node); if (icon_data != NULL && icon_len > 0) { img = purple_buddy_icon_data_new(icon_data, icon_len, NULL); } old_icon = g_strdup(purple_blist_node_get_string(node, "custom_buddy_icon")); if (img && purple_buddy_icons_is_caching()) { const char *filename = purple_imgstore_get_filename(img); purple_blist_node_set_string(node, "custom_buddy_icon", filename); ref_filename(filename); } else { purple_blist_node_remove_setting(node, "custom_buddy_icon"); } unref_filename(old_icon); if (img) g_hash_table_insert(pointer_icon_cache, node, img); else g_hash_table_remove(pointer_icon_cache, node); if (PURPLE_BLIST_NODE_IS_CONTACT(node)) { PurpleBlistNode *child; for (child = purple_blist_node_get_first_child(node); child; child = purple_blist_node_get_sibling_next(child)) { PurpleBuddy *buddy; PurpleConversation *conv; if (!PURPLE_BLIST_NODE_IS_BUDDY(child)) continue; buddy = (PurpleBuddy *)child; conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, purple_buddy_get_name(buddy), purple_buddy_get_account(buddy)); if (conv) purple_conversation_update(conv, PURPLE_CONV_UPDATE_ICON); /* Is this call necessary anymore? Can the buddies * themselves need updating when the custom buddy * icon changes? */ purple_blist_update_node_icon((PurpleBlistNode*)buddy); } } else if (PURPLE_BLIST_NODE_IS_CHAT(node)) { PurpleConversation *conv = NULL; conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_CHAT, purple_chat_get_name((PurpleChat*)node), purple_chat_get_account((PurpleChat*)node)); if (conv) { purple_conversation_update(conv, PURPLE_CONV_UPDATE_ICON); } } purple_blist_update_node_icon(node); if (old_img) { purple_imgstore_unref(old_img); } else if (old_icon) { /* The old icon may not have been loaded into memory. In that * case, we'll need to uncache the filename. The filenames * are ref-counted, so this is safe. */ purple_buddy_icon_data_uncache_file(old_icon); } g_free(old_icon); return img; }
void purple_buddy_icon_update(PurpleBuddyIcon *icon) { PurpleConversation *conv; PurpleAccount *account; const char *username; PurpleBuddyIcon *icon_to_set; GSList *buddies; g_return_if_fail(icon != NULL); account = purple_buddy_icon_get_account(icon); username = purple_buddy_icon_get_username(icon); /* If no data exists (icon->img == NULL), then call the functions below * with NULL to unset the icon. They will then unref the icon and it should * be destroyed. The only way it wouldn't be destroyed is if someone * else is holding a reference to it, in which case they can kill * the icon when they realize it has no data. */ icon_to_set = icon->img ? icon : NULL; /* Ensure that icon remains valid throughout */ purple_buddy_icon_ref(icon); buddies = purple_find_buddies(account, username); while (buddies != NULL) { PurpleBuddy *buddy = (PurpleBuddy *)buddies->data; char *old_icon; purple_buddy_set_icon(buddy, icon_to_set); old_icon = g_strdup(purple_blist_node_get_string((PurpleBlistNode *)buddy, "buddy_icon")); if (icon->img && purple_buddy_icons_is_caching()) { const char *filename = purple_imgstore_get_filename(icon->img); purple_blist_node_set_string((PurpleBlistNode *)buddy, "buddy_icon", filename); if (icon->checksum && *icon->checksum) { purple_blist_node_set_string((PurpleBlistNode *)buddy, "icon_checksum", icon->checksum); } else { purple_blist_node_remove_setting((PurpleBlistNode *)buddy, "icon_checksum"); } ref_filename(filename); } else if (!icon->img) { purple_blist_node_remove_setting((PurpleBlistNode *)buddy, "buddy_icon"); purple_blist_node_remove_setting((PurpleBlistNode *)buddy, "icon_checksum"); } unref_filename(old_icon); g_free(old_icon); buddies = g_slist_delete_link(buddies, buddies); } conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, username, account); if (conv != NULL) purple_conv_im_set_icon(PURPLE_CONV_IM(conv), icon_to_set); /* icon's refcount was incremented above */ purple_buddy_icon_unref(icon); }
static void migrate_buddy_icon(PurpleBlistNode *node, const char *setting_name, const char *dirname, const char *filename) { char *path; if (filename[0] != '/') { path = g_build_filename(dirname, filename, NULL); if (g_file_test(path, G_FILE_TEST_EXISTS)) { g_free(path); return; } g_free(path); path = g_build_filename(old_icons_dir, filename, NULL); } else path = g_strdup(filename); if (g_file_test(path, G_FILE_TEST_EXISTS)) { guchar *icon_data; size_t icon_len; FILE *file; char *new_filename; if (!read_icon_file(path, &icon_data, &icon_len)) { g_free(path); delete_buddy_icon_settings(node, setting_name); return; } if (icon_data == NULL || icon_len <= 0) { /* This really applies to the icon_len check. * icon_data should never be NULL if * read_icon_file() returns TRUE. */ purple_debug_error("buddyicon", "Empty buddy icon file: %s\n", path); delete_buddy_icon_settings(node, setting_name); g_free(path); return; } g_free(path); new_filename = purple_util_get_image_filename(icon_data, icon_len); if (new_filename == NULL) { purple_debug_error("buddyicon", "New icon filename is NULL. This should never happen! " "The old filename was: %s\n", path); delete_buddy_icon_settings(node, setting_name); g_return_if_reached(); } path = g_build_filename(dirname, new_filename, NULL); if ((file = g_fopen(path, "wb")) != NULL) { if (!fwrite(icon_data, icon_len, 1, file)) { purple_debug_error("buddyicon", "Error writing %s: %s\n", path, g_strerror(errno)); } else purple_debug_info("buddyicon", "Wrote migrated cache file: %s\n", path); fclose(file); } else { purple_debug_error("buddyicon", "Unable to create file %s: %s\n", path, g_strerror(errno)); g_free(new_filename); g_free(path); delete_buddy_icon_settings(node, setting_name); return; } g_free(path); purple_blist_node_set_string(node, setting_name, new_filename); ref_filename(new_filename); g_free(new_filename); if (purple_strequal(setting_name, "buddy_icon")) { const char *hash; hash = purple_blist_node_get_string(node, "avatar_hash"); if (hash != NULL) { purple_blist_node_set_string(node, "icon_checksum", hash); purple_blist_node_remove_setting(node, "avatar_hash"); } } } else { purple_debug_error("buddyicon", "Old icon file doesn't exist: %s\n", path); delete_buddy_icon_settings(node, setting_name); g_free(path); } }
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 && purple_strequal(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 (purple_strequal(type, "image/jpeg") || purple_strequal(type, "image/gif") || purple_strequal(type, "image/bmp") || purple_strequal(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); }