Ejemplo n.º 1
0
void *Accounts::request_authorize(PurpleAccount *account,
    const char *remote_user, const char *id, const char *alias,
    const char *message, gboolean on_list,
    PurpleAccountRequestAuthorizationCb authorize_cb,
    PurpleAccountRequestAuthorizationCb deny_cb,
    void *user_data)
{
  if (message && !*message)
    message = NULL;

  char *ins = NULL;
  if (alias)
    ins = g_strdup_printf(" (%s)", alias);

  const char *name = id;
  if (!name)
    name = purple_account_get_name_for_display(account);

  char *buf = g_strdup_printf(
      _("%s%s wants to add you (%s) to his or her buddy list%s%s"),
      remote_user, ins ? ins : "" , name, message ? ":\n" : ".",
      message ? message  : "");

  if (ins)
    g_free(ins);

  void *ui_handle;
  /* TODO Provide more information about the user that requested the
   * authorization. */
  if (on_list)
    ui_handle = purple_request_action(NULL, _("Authorize buddy?"), buf, NULL,
        PURPLE_DEFAULT_ACTION_NONE, account, remote_user, NULL, user_data, 2,
        _("Authorize"), authorize_cb, _("Deny"), deny_cb);
  else {
    AuthAndAdd *aa = new AuthAndAdd(authorize_cb, deny_cb, user_data,
        remote_user, alias, account);

    ui_handle = purple_request_action(NULL, _("Authorize buddy?"), buf, NULL,
        PURPLE_DEFAULT_ACTION_NONE, account, remote_user, NULL, aa, 2,
        _("Authorize"), authorize_and_add_cb_, _("Deny"), deny_no_add_cb_);
  }
  g_free(buf);

  // this is ugly
  CppConsUI::FreeWindow *win
    = reinterpret_cast<CppConsUI::FreeWindow*>(ui_handle);
  win->signal_close.connect(sigc::mem_fun(this,
        &Accounts::OnRequestAuthorizeClose));

  return ui_handle;
}
Ejemplo n.º 2
0
/* when you are added by a person, QQ server will send sys message */
static void server_buddy_added(PurpleConnection *gc, gchar *from, gchar *to,
		guint8 *data, gint data_len)
{
	PurpleAccount *account = purple_connection_get_account(gc);
	PurpleBuddy *buddy;
	guint32 uid;
	qq_buddy_req *add_req;
	gchar *who;
	gchar *primary;

	g_return_if_fail(from != NULL && to != NULL);

	uid = strtoul(from, NULL, 10);
	who = uid_to_purple_name(uid);

	buddy = purple_find_buddy(account, who);
	if (buddy != NULL) {
		purple_account_notify_added(account, from, to, NULL, NULL);
	}

	add_req = g_new0(qq_buddy_req, 1);
	add_req->gc = gc;
	add_req->uid = uid;	/* only need to get value */
	primary = g_strdup_printf(_("You have been added by %s"), from);
	purple_request_action(gc, NULL, primary,
			_("Would you like to add him?"),
			PURPLE_DEFAULT_ACTION_NONE,
			purple_connection_get_account(gc), who, NULL,
			add_req, 2,
			_("Add"), G_CALLBACK(add_buddy_no_auth_cb),
			_("Cancel"), G_CALLBACK(buddy_req_cancel_cb));

	g_free(who);
	g_free(primary);
}
Ejemplo n.º 3
0
Archivo: pk.c Proyecto: Lilitana/Pidgin
static void silcpurple_verify_ask(const char *entity,
				  const char *fingerprint,
				  const char *babbleprint,
				  PublicKeyVerify verify)
{
	PurpleConnection *gc = verify->client->application;
	char tmp[256], tmp2[256];

	if (verify->changed) {
		g_snprintf(tmp, sizeof(tmp),
			   _("Received %s's public key. Your local copy does not match this "
			     "key. Would you still like to accept this public key?"),
			   entity);
	} else {
		g_snprintf(tmp, sizeof(tmp),
			   _("Received %s's public key. Would you like to accept this "
			     "public key?"), entity);
	}
	g_snprintf(tmp2, sizeof(tmp2),
		   _("Fingerprint and babbleprint for the %s key are:\n\n"
		     "%s\n%s\n"), entity, fingerprint, babbleprint);

	purple_request_action(gc, _("Verify Public Key"), tmp, tmp2,
			      PURPLE_DEFAULT_ACTION_NONE,
			      purple_connection_get_account(gc), entity, NULL, verify, 3,
			      _("Yes"), G_CALLBACK(silcpurple_verify_cb),
			      _("No"), G_CALLBACK(silcpurple_verify_cb),
			      _("_View..."), G_CALLBACK(silcpurple_verify_details));
}
Ejemplo n.º 4
0
Archivo: buddy.c Proyecto: dylex/pidgin
void silcpurple_buddy_keyagr_request(SilcClient client,
				   SilcClientConnection conn,
				   SilcClientEntry client_entry,
				   const char *hostname, SilcUInt16 port)
{
	char tmp[128], tmp2[128];
	SilcPurpleKeyAgrAsk a;
	PurpleConnection *gc = client->application;

	g_snprintf(tmp, sizeof(tmp),
		   _("Key agreement request received from %s. Would you like to "
		     "perform the key agreement?"), client_entry->nickname);
	if (hostname)
		g_snprintf(tmp2, sizeof(tmp2),
			   _("The remote user is waiting key agreement on:\n"
			     "Remote host: %s\nRemote port: %d"), hostname, port);

	a = silc_calloc(1, sizeof(*a));
	if (!a)
		return;
	a->client = client;
	a->conn = conn;
	a->client_id = *client_entry->id;
	if (hostname)
		a->hostname = strdup(hostname);
	a->port = port;

	purple_request_action(client->application, _("Key Agreement Request"), tmp,
			    hostname ? tmp2 : NULL, 1, gc->account, client_entry->nickname,
				NULL, a, 2, _("Yes"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb),
			    _("No"), G_CALLBACK(silcpurple_buddy_keyagr_request_cb));
}
Ejemplo n.º 5
0
Archivo: wb.c Proyecto: bf4/pidgin-mac
static void
silcpurple_wb_request(SilcClient client, const unsigned char *message,
		      SilcUInt32 message_len, SilcClientEntry sender,
		      SilcChannelEntry channel)
{
	char tmp[256];
	SilcPurpleWbRequest req;
	PurpleConnection *gc;
	SilcPurple sg;

	gc = client->application;
	sg = gc->proto_data;

	/* Open whiteboard automatically if requested */
	if (purple_account_get_bool(sg->account, "open-wb", FALSE)) {
		PurpleWhiteboard *wb;

		if (!channel)
			wb = silcpurple_wb_init(sg, sender);
		else
			wb = silcpurple_wb_init_ch(sg, channel);

		silcpurple_wb_parse(wb->proto_data, wb,
				    (unsigned char *)message,
				    message_len);
		return;
	}

	/* Close any previous unaccepted requests */
	purple_request_close_with_handle(sender);

	if (!channel) {
		g_snprintf(tmp, sizeof(tmp),
			   _("%s sent message to whiteboard. Would you like "
			     "to open the whiteboard?"), sender->nickname);
	} else {
		g_snprintf(tmp, sizeof(tmp),
			   _("%s sent message to whiteboard on %s channel. "
			     "Would you like to open the whiteboard?"),
			   sender->nickname, channel->channel_name);
	}

	req = silc_calloc(1, sizeof(*req));
	if (!req)
		return;
	req->message = silc_memdup(message, message_len);
	req->message_len = message_len;
	req->sender = sender;
	req->channel = channel;
	req->sg = sg;

	purple_request_action(gc, _("Whiteboard"), tmp, NULL, 1,
				sg->account, sender->nickname, NULL, req, 2,
			    _("Yes"), G_CALLBACK(silcpurple_wb_request_cb),
			    _("No"), G_CALLBACK(silcpurple_wb_request_cb));
}
Ejemplo n.º 6
0
void GeneralMenu::openRequestActionTest(CppConsUI::Button& /*activator*/)
{
  purple_request_action(NULL, "Title", "Primary", "Secondary", 1, NULL,
      NULL, NULL, this, 3,
      "Action 0", G_CALLBACK(action_cb_),
      "Action 1", NULL,
      "Action 2", G_CALLBACK(action_cb_));

  close();
}
Ejemplo n.º 7
0
static void log_delete_log_cb(GtkWidget *menuitem, gpointer *data)
{
	PidginLogViewer *lv = data[0];
	PurpleLog *log = data[1];
	const char *time = log_get_date(log);
	const char *name;
	char *tmp;
	gpointer *data2;

	if (log->type == PURPLE_LOG_IM)
	{
		PurpleBuddy *buddy = purple_find_buddy(log->account, log->name);
		if (buddy != NULL)
			name = purple_buddy_get_contact_alias(buddy);
		else
			name = log->name;

		tmp = g_strdup_printf(_("Are you sure you want to permanently delete the log of the "
		                        "conversation with %s which started at %s?"), name, time);
	}
	else if (log->type == PURPLE_LOG_CHAT)
	{
		PurpleChat *chat = purple_blist_find_chat(log->account, log->name);
		if (chat != NULL)
			name = purple_chat_get_name(chat);
		else
			name = log->name;

		tmp = g_strdup_printf(_("Are you sure you want to permanently delete the log of the "
		                        "conversation in %s which started at %s?"), name, time);
	}
	else if (log->type == PURPLE_LOG_SYSTEM)
	{
		tmp = g_strdup_printf(_("Are you sure you want to permanently delete the system log "
		                        "which started at %s?"), time);
	}
	else
		g_return_if_reached();

	/* The only way to free data in all cases is to tie it to the menuitem with
	 * g_object_set_data_full().  But, since we need to get some data down to
	 * delete_log_cb() to delete the log from the log viewer after the file is
	 * deleted, we have to allocate a new data array and make sure it gets freed
	 * either way. */
	data2 = g_new(gpointer, 3);
	data2[0] = lv->treestore;
	data2[1] = data[3]; /* iter */
	data2[2] = log;
	purple_request_action(lv, NULL, _("Delete Log?"), tmp, 0,
						NULL, NULL, NULL,
						data2, 2,
						_("Delete"), delete_log_cb,
						_("Cancel"), delete_log_cleanup_cb);
	g_free(tmp);
}
Ejemplo n.º 8
0
void Accounts::request_add(PurpleAccount *account, const char *remote_user,
    const char *id, const char *alias, const char *message)
{
  AddUserData *data = new AddUserData(account, remote_user, alias);
  char *buf = MakeInfo(account, remote_user, id, alias, message);
  purple_request_action(NULL, NULL, _("Add buddy to your list?"), buf,
      PURPLE_DEFAULT_ACTION_NONE, account, remote_user, NULL, data, 2,
      _("Add"), G_CALLBACK(add_user_cb_), _("Cancel"),
      G_CALLBACK(add_user_cancel_cb_));
  g_free(buf);
}
Ejemplo n.º 9
0
Archivo: buddy.c Proyecto: dylex/pidgin
static void
silcpurple_add_buddy_ask_pk(SilcPurpleBuddyRes r)
{
	char tmp[512];
	g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not present in the network"),
		   r->b->name);
	purple_request_action(r->client->application, _("Add Buddy"), tmp,
			    _("To add the buddy you must import his/her public key. "
			      "Press Import to import a public key."), 0,
				  purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), NULL, r, 2,
			    _("Cancel"), G_CALLBACK(silcpurple_add_buddy_ask_pk_cb),
			    _("_Import..."), G_CALLBACK(silcpurple_add_buddy_ask_pk_cb));
}
Ejemplo n.º 10
0
void qq_room_quit(PurpleConnection *gc, guint32 room_id)
{
	qq_room_req *add_req;

	add_req = g_new0(qq_room_req, 1);
	add_req->gc = gc;
	add_req->id = room_id;

	purple_request_action(gc, _("QQ Qun Operation"),
			    _("Quit Qun"),
			    _("Note, if you are the creator, \nthis operation will eventually remove this Qun."),
			    1,
				purple_connection_get_account(gc), NULL, NULL,
			    add_req, 2, _("Cancel"),
			    G_CALLBACK(room_join_cancel_cb),
			    _("Continue"), G_CALLBACK(group_quit_cb));
}
Ejemplo n.º 11
0
void
msn_show_sync_issue(MsnSession *session, const char *passport,
					const char *group_name)
{
	PurpleConnection *gc;
	PurpleAccount *account;
	MsnAddRemData *data;
	char *msg, *reason;

	account = session->account;
	gc = purple_account_get_connection(account);

	data        = g_new0(MsnAddRemData, 1);
	data->who   = g_strdup(passport);
	data->group = g_strdup(group_name);
	data->gc    = gc;

	msg = g_strdup_printf(_("Buddy list synchronization issue in %s (%s)"),
						  purple_account_get_username(account),
						  purple_account_get_protocol_name(account));

	if (group_name != NULL)
	{
		reason = g_strdup_printf(_("%s on the local list is "
								   "inside the group \"%s\" but not on "
								   "the server list. "
								   "Do you want this buddy to be added?"),
								 passport, group_name);
	}
	else
	{
		reason = g_strdup_printf(_("%s is on the local list but "
								   "not on the server list. "
								   "Do you want this buddy to be added?"),
								 passport);
	}

	purple_request_action(gc, NULL, msg, reason, PURPLE_DEFAULT_ACTION_NONE, 
						purple_connection_get_account(gc), data->who, NULL,
						data, 2,
						_("Yes"), G_CALLBACK(msn_add_cb),
						_("No"), G_CALLBACK(msn_rem_cb));

	g_free(reason);
	g_free(msg);
}
Ejemplo n.º 12
0
static void
ask_before_delete(GntWidget *button, gpointer null)
{
	char *ask;
	PurpleSavedStatus *saved;

	g_return_if_fail(statuses.tree != NULL);

	saved = gnt_tree_get_selection_data(GNT_TREE(statuses.tree));
	ask = g_strdup_printf(_("Are you sure you want to delete \"%s\""),
			purple_savedstatus_get_title(saved));

	purple_request_action(saved, _("Delete Status"), ask, NULL, 0,
			NULL, NULL, NULL,
			saved, 2,
			_("Delete"), really_delete_status,
			_("Cancel"), NULL);
	g_free(ask);
}
Ejemplo n.º 13
0
static void
pounces_manager_delete_cb(GntButton *button, gpointer user_data)
{
	PouncesManager *dialog = user_data;
	PurplePounce *pounce;
	PurpleAccount *account;
	const char *pouncer, *pouncee;
	char *buf;

	pounce = (PurplePounce *)gnt_tree_get_selection_data(GNT_TREE(dialog->tree));
	if (pounce == NULL)
		return;

	account = purple_pounce_get_pouncer(pounce);
	pouncer = purple_account_get_username(account);
	pouncee = purple_pounce_get_pouncee(pounce);
	buf = g_strdup_printf(_("Are you sure you want to delete the pounce on %s for %s?"), pouncee, pouncer);
	purple_request_action(pounce, NULL, buf, NULL, 0,
						account, pouncee, NULL,
						pounce, 2,
						_("Delete"), pounces_manager_delete_confirm_cb,
						_("Cancel"), NULL);
	g_free(buf);
}
Ejemplo n.º 14
0
/**
 * Someone else wants to establish a peer connection with us.
 */
void
peer_connection_got_proposition(OscarData *od, const gchar *bn, const gchar *message, IcbmArgsCh2 *args)
{
	PurpleConnection *gc;
	PurpleAccount *account;
	PeerConnection *conn;
	gchar *buf;

	gc = od->gc;
	account = purple_connection_get_account(gc);

	/*
	 * If we have a connection with this same cookie then they are
	 * probably just telling us they weren't able to connect to us
	 * and we should try connecting to them, instead.  Or they want
	 * to go through a proxy.
	 */
	conn = peer_connection_find_by_cookie(od, bn, args->cookie);
	if ((conn != NULL) && (conn->type == args->type))
	{
		purple_debug_info("oscar", "Remote user wants to try a "
				"different connection method\n");
		g_free(conn->proxyip);
		g_free(conn->clientip);
		g_free(conn->verifiedip);
		if (args->use_proxy)
			conn->proxyip = g_strdup(args->proxyip);
		else
			conn->proxyip = NULL;
		conn->verifiedip = g_strdup(args->verifiedip);
		conn->clientip = g_strdup(args->clientip);
		conn->port = args->port;
		conn->use_proxy |= args->use_proxy;
		conn->lastrequestnumber++;
		peer_connection_trynext(conn);
		return;
	}

	/* If this is a direct IM, then close any existing session */
	if (args->type == OSCAR_CAPABILITY_DIRECTIM)
	{
		conn = peer_connection_find_by_type(od, bn, args->type);
		if (conn != NULL)
		{
			/* Close the old direct IM and start a new one */
			purple_debug_info("oscar", "Received new direct IM request "
				"from %s.  Destroying old connection.\n", bn);
			peer_connection_destroy(conn, OSCAR_DISCONNECT_REMOTE_CLOSED, NULL);
		}
	}

	/* Check for proper arguments */
	if (args->type == OSCAR_CAPABILITY_SENDFILE)
	{
		if ((args->info.sendfile.filename == NULL) ||
			(args->info.sendfile.totsize == 0) ||
			(args->info.sendfile.totfiles == 0))
		{
			purple_debug_warning("oscar",
					"%s tried to send you a file with incomplete "
					"information.\n", bn);
			return;
		}
	}

	conn = peer_connection_new(od, args->type, bn);
	memcpy(conn->cookie, args->cookie, 8);
	if (args->use_proxy)
		conn->proxyip = g_strdup(args->proxyip);
	conn->clientip = g_strdup(args->clientip);
	conn->verifiedip = g_strdup(args->verifiedip);
	conn->port = args->port;
	conn->use_proxy |= args->use_proxy;
	conn->lastrequestnumber++;

	if (args->type == OSCAR_CAPABILITY_DIRECTIM)
	{
		buf = g_strdup_printf(_("%s has just asked to directly connect to %s"),
				bn, purple_account_get_username(account));

		purple_request_action(conn, NULL, buf,
						_("This requires a direct connection between "
						  "the two computers and is necessary for IM "
						  "Images.  Because your IP address will be "
						  "revealed, this may be considered a privacy "
						  "risk."),
						PURPLE_DEFAULT_ACTION_NONE,
						account, bn, NULL,
						conn, 2,
						_("C_onnect"), G_CALLBACK(peer_connection_got_proposition_yes_cb),
						_("Cancel"), G_CALLBACK(peer_connection_got_proposition_no_cb));
	}
	else if (args->type == OSCAR_CAPABILITY_SENDFILE)
	{
		gchar *filename;

		conn->xfer = purple_xfer_new(account, PURPLE_XFER_RECEIVE, bn);
		if (conn->xfer)
		{
			conn->xfer->data = conn;
			purple_xfer_ref(conn->xfer);
			purple_xfer_set_size(conn->xfer, args->info.sendfile.totsize);

			/* Set the file name */
			if (g_utf8_validate(args->info.sendfile.filename, -1, NULL))
				filename = g_strdup(args->info.sendfile.filename);
			else
				filename = purple_utf8_salvage(args->info.sendfile.filename);

			if (args->info.sendfile.subtype == AIM_OFT_SUBTYPE_SEND_DIR)
			{
				/*
				 * If they are sending us a directory then the last character
				 * of the file name will be an asterisk.  We don't want to
				 * save stuff to a directory named "*" so we remove the
				 * asterisk from the file name.
				 */
				char *tmp = strrchr(filename, '\\');
				if ((tmp != NULL) && (tmp[1] == '*'))
					tmp[0] = '\0';
			}
			purple_xfer_set_filename(conn->xfer, filename);
			g_free(filename);

			/*
			 * Set the message, unless this is the dummy message from an
			 * ICQ client or an empty message from an AIM client.
			 * TODO: Maybe we should strip HTML and then see if strlen>0?
			 */
			if ((message != NULL) &&
				(g_ascii_strncasecmp(message, "<ICQ_COOL_FT>", 13) != 0) &&
				(g_ascii_strcasecmp(message, "<HTML>") != 0))
			{
				purple_xfer_set_message(conn->xfer, message);
			}

			/* Setup our I/O op functions */
			purple_xfer_set_init_fnc(conn->xfer, peer_oft_recvcb_init);
			purple_xfer_set_end_fnc(conn->xfer, peer_oft_recvcb_end);
			purple_xfer_set_request_denied_fnc(conn->xfer, peer_oft_cb_generic_cancel);
			purple_xfer_set_cancel_recv_fnc(conn->xfer, peer_oft_cb_generic_cancel);
			purple_xfer_set_ack_fnc(conn->xfer, peer_oft_recvcb_ack_recv);

			/* Now perform the request */
			purple_xfer_request(conn->xfer);
		}
	}
}
Ejemplo n.º 15
0
static gboolean
handle_presence_chat(JabberStream *js, JabberPresence *presence, xmlnode *packet)
{
	static int i = 1;
	PurpleConvChatBuddyFlags flags = PURPLE_CBFLAGS_NONE;
	JabberChat *chat = presence->chat;

	if (presence->state == JABBER_BUDDY_STATE_ERROR) {
		char *title, *msg = jabber_parse_error(js, packet, NULL);

		if (!chat->conv) {
			title = g_strdup_printf(_("Error joining chat %s"), presence->from);
			purple_serv_got_join_chat_failed(js->gc, chat->components);
		} else {
			title = g_strdup_printf(_("Error in chat %s"), presence->from);
			if (g_hash_table_size(chat->members) == 0)
				serv_got_chat_left(js->gc, chat->id);
		}
		purple_notify_error(js->gc, title, title, msg);
		g_free(title);
		g_free(msg);

		if (g_hash_table_size(chat->members) == 0)
			/* Only destroy the chat if the error happened while joining */
			jabber_chat_destroy(chat);
		return FALSE;
	}

	if (presence->type == JABBER_PRESENCE_AVAILABLE) {
		const char *jid = NULL;
		const char *affiliation = NULL;
		const char *role = NULL;
		gboolean is_our_resource = FALSE; /* Is the presence about us? */
		JabberBuddyResource *jbr;

		/*
		 * XEP-0045 mandates the presence to include a resource (which is
		 * treated as the chat nick). Some non-compliant servers allow
		 * joining without a nick.
		 */
		if (!presence->jid_from->resource)
			return FALSE;

		if (presence->chat_info.item) {
			jid = xmlnode_get_attrib(presence->chat_info.item, "jid");
			affiliation = xmlnode_get_attrib(presence->chat_info.item, "affiliation");
			role = xmlnode_get_attrib(presence->chat_info.item, "role");
		}

		if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(110)) ||
				g_str_equal(presence->jid_from->resource, chat->handle) ||
				purple_strequal(presence->to, jid))
			is_our_resource = TRUE;

		if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(201))) {
			chat->config_dialog_type = PURPLE_REQUEST_ACTION;
			chat->config_dialog_handle =
				purple_request_action(js->gc,
						_("Create New Room"),
						_("Create New Room"),
						_("You are creating a new room.  Would"
							" you like to configure it, or"
							" accept the default settings?"),
						/* Default Action */ 1,
						purple_connection_get_account(js->gc), NULL, chat->conv,
						chat, 2,
						_("_Configure Room"), G_CALLBACK(jabber_chat_request_room_configure),
						_("_Accept Defaults"), G_CALLBACK(jabber_chat_create_instant_room));
		}

		if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(210))) {
			/* server rewrote room-nick */
			g_free(chat->handle);
			chat->handle = g_strdup(presence->jid_from->resource);
		}

		if (purple_strequal(affiliation, "owner"))
			flags |= PURPLE_CBFLAGS_FOUNDER;
		if (role) {
			if (g_str_equal(role, "moderator"))
				flags |= PURPLE_CBFLAGS_OP;
			else if (g_str_equal(role, "participant"))
				flags |= PURPLE_CBFLAGS_VOICE;
		}

		if(!chat->conv) {
			char *room_jid = g_strdup_printf("%s@%s", presence->jid_from->node, presence->jid_from->domain);
			chat->id = i++;
			chat->conv = serv_got_joined_chat(js->gc, chat->id, room_jid);
			purple_conv_chat_set_nick(PURPLE_CONV_CHAT(chat->conv), chat->handle);

			jabber_chat_disco_traffic(chat);
			g_free(room_jid);
		}

		jbr = jabber_buddy_track_resource(presence->jb, presence->jid_from->resource, presence->priority, presence->state, presence->status);
		jbr->commands_fetched = TRUE;

		jabber_chat_track_handle(chat, presence->jid_from->resource, jid, affiliation, role);

		if(!jabber_chat_find_buddy(chat->conv, presence->jid_from->resource))
			purple_conv_chat_add_user(PURPLE_CONV_CHAT(chat->conv), presence->jid_from->resource,
					jid, flags, chat->joined > 0 && ((!presence->delayed) || (presence->sent > chat->joined)));
		else
			purple_conv_chat_user_set_flags(PURPLE_CONV_CHAT(chat->conv), presence->jid_from->resource,
					flags);

		if (is_our_resource && chat->joined == 0)
			chat->joined = time(NULL);

	} else if (presence->type == JABBER_PRESENCE_UNAVAILABLE) {
		gboolean nick_change = FALSE;
		gboolean kick = FALSE;
		gboolean is_our_resource = FALSE; /* Is the presence about us? */

		const char *jid = NULL;

		/* If the chat nick is invalid, we haven't yet joined, or we've
		 * already left (it was probably us leaving after we closed the
		 * chat), we don't care.
		 */
		if (!presence->jid_from->resource || !chat->conv || chat->left) {
			if (chat->left &&
					presence->jid_from->resource && chat->handle && !strcmp(presence->jid_from->resource, chat->handle))
				jabber_chat_destroy(chat);
			return FALSE;
		}

		is_our_resource = g_str_equal(presence->jid_from->resource, chat->handle);

		jabber_buddy_remove_resource(presence->jb, presence->jid_from->resource);

		if (presence->chat_info.item)
			jid = xmlnode_get_attrib(presence->chat_info.item, "jid");

		if (chat->muc) {
			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(110))) {
				is_our_resource = TRUE;
				chat->joined = 0;
			}

			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(301))) {
				/* XXX: We got banned.  YAY! (No GIR, that's bad) */
			}


			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(303))) {
				const char *nick = NULL;
				if (presence->chat_info.item)
					nick = xmlnode_get_attrib(presence->chat_info.item, "nick");

				/* nick change */
				if (!nick) {
					purple_debug_warning("jabber", "Chat presence indicating a nick change, but no new nickname!\n");
				} else {
					nick_change = TRUE;

					if (g_str_equal(presence->jid_from->resource, chat->handle)) {
						/* Changing our own nickname */
						g_free(chat->handle);
						/* TODO: This should be resourceprep'd */
						chat->handle = g_strdup(nick);
					}

					purple_conv_chat_rename_user(PURPLE_CONV_CHAT(chat->conv),
					                             presence->jid_from->resource,
					                             nick);
					jabber_chat_remove_handle(chat,
					                          presence->jid_from->resource);
				}
			}

			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(307))) {
				/* Someone was kicked from the room */
				const char *actor = NULL;
				char *reason = NULL;
				char *tmp;

				kick = TRUE;

				if (presence->chat_info.item) {
					xmlnode *node;

					node = xmlnode_get_child(presence->chat_info.item, "actor");
					if (node)
						actor = xmlnode_get_attrib(node, "jid");
					node = xmlnode_get_child(presence->chat_info.item, "reason");
					if (node)
						reason = xmlnode_get_data(node);
				}

				if (reason == NULL)
					reason = g_strdup(_("No reason"));

				if (is_our_resource) {
					if (actor)
						tmp = g_strdup_printf(_("You have been kicked by %s: (%s)"),
								actor, reason);
					else
						tmp = g_strdup_printf(_("You have been kicked: (%s)"),
								reason);
				} else {
					if (actor)
						tmp = g_strdup_printf(_("Kicked by %s (%s)"),
								actor, reason);
					else
						tmp = g_strdup_printf(_("Kicked (%s)"),
								reason);
				}

				g_free(presence->status);
				presence->status = tmp;

				g_free(reason);
			}

			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(321))) {
				/* XXX: removed due to an affiliation change */
			}

			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(322))) {
				/* XXX: removed because room is now members-only */
			}

			if (g_slist_find(presence->chat_info.codes, GINT_TO_POINTER(332))) {
				/* XXX: removed due to system shutdown */
			}
		}

		/*
		 * Possibly another connected resource of our JID (see XEP-0045
		 * v1.24 section 7.1.10) being disconnected. Should be
		 * distinguished by the item_jid.
		 * Also possibly works around bits of an Openfire bug. See
		 * #8319.
		 */
		if (is_our_resource && jid && !purple_strequal(presence->to, jid)) {
			/* TODO: When the above is a loop, this needs to still act
			 * sanely for all cases (this code is a little fragile). */
			if (!kick && !nick_change)
				/* Presumably, kicks and nick changes also affect us. */
				is_our_resource = FALSE;
		}

		if(!nick_change) {
			if (is_our_resource) {
				if (kick)
					purple_conv_chat_write(PURPLE_CONV_CHAT(chat->conv), presence->jid_from->resource,
							presence->status, PURPLE_MESSAGE_SYSTEM, time(NULL));

				serv_got_chat_left(js->gc, chat->id);
				jabber_chat_destroy(chat);
			} else {
				purple_conv_chat_remove_user(PURPLE_CONV_CHAT(chat->conv), presence->jid_from->resource,
						presence->status);
				jabber_chat_remove_handle(chat, presence->jid_from->resource);
			}
		}
	}

	return TRUE;
}
Ejemplo n.º 16
0
void silcpurple_show_public_key(SilcPurple sg,
				const char *name, SilcPublicKey public_key,
				GCallback callback, void *context)
{
	SilcPublicKeyIdentifier ident;
	SilcSILCPublicKey silc_pubkey;
	char *fingerprint, *babbleprint;
	unsigned char *pk;
	SilcUInt32 pk_len, key_len = 0;
	GString *s;

	/* We support showing only SILC public keys for now */
	if (silc_pkcs_get_type(public_key) != SILC_PKCS_SILC)
	  return;

	silc_pubkey = silc_pkcs_get_context(SILC_PKCS_SILC, public_key);
	ident = &silc_pubkey->identifier;
	key_len = silc_pkcs_public_key_get_len(public_key);

	pk = silc_pkcs_public_key_encode(public_key, &pk_len);
	if (!pk)
	  return;
	fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
	babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
	if (!fingerprint || !babbleprint)
	  return;

	s = g_string_new("");
	if (ident->realname)
		/* Hint for translators: Please check the tabulator width here and in
		   the next strings (short strings: 2 tabs, longer strings 1 tab,
		   sum: 3 tabs or 24 characters) */
		g_string_append_printf(s, _("Real Name: \t%s\n"), ident->realname);
	if (ident->username)
		g_string_append_printf(s, _("User Name: \t%s\n"), ident->username);
	if (ident->email)
		g_string_append_printf(s, _("Email: \t\t%s\n"), ident->email);
	if (ident->host)
		g_string_append_printf(s, _("Host Name: \t%s\n"), ident->host);
	if (ident->org)
		g_string_append_printf(s, _("Organization: \t%s\n"), ident->org);
	if (ident->country)
		g_string_append_printf(s, _("Country: \t%s\n"), ident->country);
	g_string_append_printf(s, _("Algorithm: \t%s\n"), silc_pubkey->pkcs->name);
	g_string_append_printf(s, _("Key Length: \t%d bits\n"), (int)key_len);
	if (ident->version)
	  g_string_append_printf(s, _("Version: \t%s\n"), ident->version);
	g_string_append_printf(s, "\n");
	g_string_append_printf(s, _("Public Key Fingerprint:\n%s\n\n"), fingerprint);
	g_string_append_printf(s, _("Public Key Babbleprint:\n%s"), babbleprint);

	purple_request_action(sg->gc, _("Public Key Information"),
			      _("Public Key Information"),
			      s->str, 0, purple_connection_get_account(sg->gc),
			      NULL, NULL, context, 1, _("Close"), callback);

	g_string_free(s, TRUE);
	silc_free(fingerprint);
	silc_free(babbleprint);
	silc_free(pk);
}