예제 #1
0
void p2tgl_prpl_got_user_status (struct tgl_state *TLS, tgl_peer_id_t user, struct tgl_user_status *status) {
  
  if (status->online == 1) {
    char *name = peer_strdup_id (user);
    purple_prpl_got_user_status (tg_get_acc(TLS), name, "available", NULL);
    g_free (name);
  } else {
    char *name = peer_strdup_id (user);
    char *when;
    switch (status->online) {
    case -1:
      when = g_strdup_printf("%d", status->when);
      break;
    case -2:
      when = g_strdup_printf("recently");
      break;
    case -3:
      when = g_strdup_printf("last week");
      break;
    case -4:
      when = g_strdup_printf("last month");
      break;
    default:
      when = g_strdup ("unknown");
      break;
    }
  
    purple_prpl_got_user_status (tg_get_acc(TLS), name, "mobile", "last online", when, NULL);
  
    g_free(name);
    g_free(when);
  }
}
예제 #2
0
파일: presence.c 프로젝트: Lilitana/Pidgin
void jabber_presence_fake_to_self(JabberStream *js, PurpleStatus *status)
{
	PurpleAccount *account;
	PurplePresence *presence;
	JabberBuddy *jb;
	JabberBuddyResource *jbr;
	const char *username;
	JabberBuddyState state;
	char *msg;
	int priority;

	g_return_if_fail(js->user != NULL);

	account = purple_connection_get_account(js->gc);
	username = purple_connection_get_display_name(js->gc);
	presence = purple_account_get_presence(account);
	if (status == NULL)
		status = purple_presence_get_active_status(presence);
	purple_status_to_jabber(status, &state, &msg, &priority);

	jb = js->user_jb;

	if (state == JABBER_BUDDY_STATE_UNAVAILABLE ||
			state == JABBER_BUDDY_STATE_UNKNOWN) {
		jabber_buddy_remove_resource(jb, js->user->resource);
	} else {
		jbr = jabber_buddy_track_resource(jb, js->user->resource, priority,
				state, msg);
		jbr->idle = purple_presence_is_idle(presence) ?
				purple_presence_get_idle_time(presence) : 0;
	}

	/*
	 * While we need to track the status of this resource, the core
	 * only cares if we're on our own buddy list.
	 */
	if (purple_find_buddy(account, username)) {
		jbr = jabber_buddy_find_resource(jb, NULL);
		if (jbr) {
			purple_prpl_got_user_status(account, username,
					jabber_buddy_state_get_status_id(jbr->state),
					"priority", jbr->priority,
					jbr->status ? "message" : NULL, jbr->status,
					NULL);
			purple_prpl_got_user_idle(account, username, jbr->idle, jbr->idle);
		} else {
			purple_prpl_got_user_status(account, username, "offline",
					msg ? "message" : NULL, msg,
					NULL);
		}
	}
	g_free(msg);
}
예제 #3
0
static void query_status(PurpleConnection *gc)
{
	whatsapp_connection *wconn = purple_connection_get_protocol_data(gc);
	PurpleAccount *acc = purple_connection_get_account(gc);
	char *who;
	int status;

	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);
		}
	}
}
예제 #4
0
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);
	
}
예제 #5
0
/* Add buddy dialog */
static void plainprpl_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *buddy_group)
{
	purple_debug_info("plainprpl", "plainprpl_add_buddy_with_invite: %s\n", buddy->name);
	PurpleRequestFields *request;
	PurpleRequestFieldGroup *group;
	PurpleRequestField *field;

	group = purple_request_field_group_new(NULL);

	field = purple_request_field_string_new("addr_str", _("IP Address"), "", FALSE);
	purple_request_field_group_add_field(group, field);

	field = purple_request_field_string_new("invite_msg", _("Invite Message"), "Please allow me to add you as a contact!", FALSE);
	purple_request_field_group_add_field(group, field);

	request = purple_request_fields_new();
	purple_request_fields_add_group(request, group);

	purple_request_fields(gc, "Add Contact", "Add a new contact.",
		NULL, request,
		"OK",  G_CALLBACK(plainprpl_add_buddy_ok),
		"Cancel",  G_CALLBACK(plainprpl_add_buddy_cancel),
		NULL, NULL, NULL, (void *) buddy
	);

	purple_prpl_got_user_status(gc->account, buddy->name, PLAIN_STATUS_OFFLINE, NULL);
}
예제 #6
0
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;
}
예제 #7
0
파일: msgs.c 프로젝트: bf4/pidgin-mac
static void irc_buddy_status(char *name, struct irc_buddy *ib, struct irc_conn *irc)
{
	PurpleConnection *gc = purple_account_get_connection(irc->account);
	PurpleBuddy *buddy = purple_find_buddy(irc->account, name);

	if (!gc || !buddy)
		return;

	if (ib->online && !ib->flag) {
		purple_prpl_got_user_status(irc->account, name, "offline", NULL);
		ib->online = FALSE;
	} else if (!ib->online && ib->flag) {
		purple_prpl_got_user_status(irc->account, name, "available", NULL);
		ib->online = TRUE;
	}
}
예제 #8
0
//with invite message
static void plainprpl_add_buddy_by_contact_request(PurpleConnection *gc, const char *addr_str, const char *message)
{
	PurpleBuddy *buddy;

	/* Create the basic buddy item */
	buddy = purple_buddy_new(gc->account, addr_str, NULL);
	purple_blist_add_buddy(buddy, NULL, NULL, NULL);

	PurpleRequestFields *request;
	PurpleRequestFieldGroup *group;
	PurpleRequestField *field;

	group = purple_request_field_group_new(NULL);

	field = purple_request_field_string_new("name", _("Name"), addr_str, FALSE);
	purple_request_field_group_add_field(group, field);

	request = purple_request_fields_new();
	purple_request_fields_add_group(request, group);

	char *msg = g_strdup_printf("Add a new contact from %s. Message: %s", addr_str, message);
	purple_request_fields(gc, "Contact Request", msg,
		NULL, request,
		"OK",  G_CALLBACK(plainprpl_add_buddy_by_contact_request_ok),
		"Cancel",  G_CALLBACK(plainprpl_add_buddy_by_contact_request_cancel),
		NULL, NULL, NULL, (void *) buddy
	);
	g_free(msg);

	purple_prpl_got_user_status(gc->account, buddy->name, PLAIN_STATUS_OFFLINE, NULL);
}
예제 #9
0
/* Subtype 0x0006 */
static int
userinfo(OscarData *od, FlapConnection *conn, aim_module_t *mod, FlapFrame *frame, aim_modsnac_t *snac, ByteStream *bs)
{
	int ret = 0;
	aim_userinfo_t *userinfo, *userinfo2;
	GSList *tlvlist;
	aim_tlv_t *tlv = NULL;

	userinfo = (aim_userinfo_t *)g_malloc(sizeof(aim_userinfo_t));
	aim_info_extract(od, bs, userinfo);
	tlvlist = aim_tlvlist_read(bs);

	/* Profile will be 1 and 2 */
	userinfo->info_encoding = aim_tlv_getstr(tlvlist, 0x0001, 1);
	if ((tlv = aim_tlv_gettlv(tlvlist, 0x0002, 1))) {
		userinfo->info = (char *)g_malloc(tlv->length);
		memcpy(userinfo->info, tlv->value, tlv->length);
		userinfo->info_len = tlv->length;
	}

	/* Away message will be 3 and 4 */
	userinfo->away_encoding = aim_tlv_getstr(tlvlist, 0x0003, 1);
	if ((tlv = aim_tlv_gettlv(tlvlist, 0x0004, 1))) {
		userinfo->away = (char *)g_malloc(tlv->length);
		memcpy(userinfo->away, tlv->value, tlv->length);
		userinfo->away_len = tlv->length;
	}

	/* Caps will be 5 */
	if ((tlv = aim_tlv_gettlv(tlvlist, 0x0005, 1))) {
		ByteStream cbs;
		PurpleAccount *account = purple_connection_get_account(od->gc);
		const char *mood;

		byte_stream_init(&cbs, tlv->value, tlv->length);
		userinfo->capabilities = aim_locate_getcaps(od, &cbs, tlv->length);
		byte_stream_rewind(&cbs);
		userinfo->present = AIM_USERINFO_PRESENT_CAPABILITIES;

		mood = aim_receive_custom_icon(od, &cbs, tlv->length);
		if (mood)
			purple_prpl_got_user_status(account, userinfo->bn, "mood",
					PURPLE_MOOD_NAME, mood,
					NULL);
		else
			purple_prpl_got_user_status_deactive(account, userinfo->bn, "mood");
	}
	aim_tlvlist_free(tlvlist);

	aim_locate_adduserinfo(od, userinfo);
	userinfo2 = aim_locate_finduserinfo(od, userinfo->bn);
	aim_info_free(userinfo);
	g_free(userinfo);

	/* Show the info to the user */
	oscar_user_info_display_aim(od, userinfo2);

	return ret;
}
예제 #10
0
void update_remote_status(PurpleAccount *a, const char *friend_name, int status) {
  purple_debug_info("motmot", "updating status of %s to %d", friend_name, status);
  switch (status) {
    case ONLINE:
      purple_prpl_got_user_status(a, friend_name, NULL_STATUS_ONLINE, NULL);
      break;
    case AWAY:
    case BUSY:
      purple_prpl_got_user_status(a, friend_name, NULL_STATUS_AWAY, NULL);
      break;
    case OFFLINE:
      purple_prpl_got_user_status(a, friend_name, NULL_STATUS_OFFLINE, NULL);
      break;
    default:
      return;
  }
}
예제 #11
0
static void
pb_got_phonebook(PushBulletAccount *pba, JsonNode *node, gpointer user_data)
{
	PurpleAccount *account = pba->account;
	JsonObject *rootobj = json_node_get_object(node);
	JsonArray *phonebook = json_object_get_array_member(rootobj, "phonebook");
	gint i;
	guint len;
	gchar *device = user_data;
	PurpleGroup *pbgroup;
	
	pbgroup = purple_find_group("PushBullet");
	if (!pbgroup)
	{
		pbgroup = purple_group_new("PushBullet");
		purple_blist_add_group(pbgroup, NULL);
	}
	
	for(i = 0, len = json_array_get_length(phonebook); i < len; i++)
	{
		JsonObject *number = json_array_get_object_element(phonebook, i);
		const gchar *name = json_object_get_string_member(number, "name");
		const gchar *phone = json_object_get_string_member(number, "phone");
		const gchar *phone_type = json_object_get_string_member(number, "phone_type");
		PurpleBuddy *pbuddy;
		
		//Only handle the right 'type' of phone number. 
		//home, mobile, work, other
		if (purple_account_get_bool(account, "mobile_contacts_only", FALSE) && phone_type[0] != 'm')
			continue;
		
		pbuddy = purple_find_buddy(account, phone);
		if (!pbuddy)
		{
			pbuddy = purple_buddy_new(account, phone, name);
			purple_blist_add_buddy(pbuddy, NULL, pbgroup, NULL);
			purple_debug_info("pushbullet", "Added buddy %s %s\n", phone, name);
		}
		
		purple_prpl_got_user_status(account, phone, "mobile", NULL);
		purple_prpl_got_user_status(account, phone, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL);
	}
	
	g_free(device);
}
예제 #12
0
파일: fb_blist.c 프로젝트: bf4/pidgin-mac
static void set_buddies_offline(PurpleBuddy *buddy, GSList *online_buddies_list)
{
    if (g_slist_find(online_buddies_list, buddy) == NULL &&
            PURPLE_BUDDY_IS_ONLINE(buddy))
    {
        purple_prpl_got_user_status(buddy->account, buddy->name,
                                    purple_primitive_get_id_from_type(PURPLE_STATUS_OFFLINE),
                                    NULL);
    }
}
예제 #13
0
파일: user.c 프로젝트: Mons/libpurple-mini
void
msn_user_update(MsnUser *user)
{
	PurpleAccount *account;
	gboolean offline;

	g_return_if_fail(user != NULL);

	account = user->userlist->session->account;

	offline = (user->status == NULL);

	if (!offline) {
		purple_prpl_got_user_status(account, user->passport, user->status,
				"message", user->statusline, NULL);
	} else {
		if (user->mobile) {
			purple_prpl_got_user_status(account, user->passport, "mobile", NULL);
			purple_prpl_got_user_status(account, user->passport, "available", NULL);
		} else {
			purple_prpl_got_user_status(account, user->passport, "offline", NULL);
		}
	}

	if (!offline || !user->mobile) {
		purple_prpl_got_user_status_deactive(account, user->passport, "mobile");
	}

	if (!offline && user->extinfo && user->extinfo->media_type != CURRENT_MEDIA_UNKNOWN) {
		if (user->extinfo->media_type == CURRENT_MEDIA_MUSIC) {
			purple_prpl_got_user_status(account, user->passport, "tune",
			                            PURPLE_TUNE_ARTIST, user->extinfo->media_artist,
			                            PURPLE_TUNE_ALBUM, user->extinfo->media_album,
			                            PURPLE_TUNE_TITLE, user->extinfo->media_title,
			                            NULL);
		} else if (user->extinfo->media_type == CURRENT_MEDIA_GAMES) {
			purple_prpl_got_user_status(account, user->passport, "tune",
			                            "game", user->extinfo->media_title,
			                            NULL);
		} else if (user->extinfo->media_type == CURRENT_MEDIA_OFFICE) {
			purple_prpl_got_user_status(account, user->passport, "tune",
			                            "office", user->extinfo->media_title,
			                            NULL);
		} else {
			purple_debug_warning("msn", "Got CurrentMedia with unknown type %d.\n",
			                     user->extinfo->media_type);
		}
	} else {
		purple_prpl_got_user_status_deactive(account, user->passport, "tune");
	}

	if (user->idle)
		purple_prpl_got_user_idle(account, user->passport, TRUE, -1);
	else
		purple_prpl_got_user_idle(account, user->passport, FALSE, 0);
}
예제 #14
0
파일: buddy.c 프로젝트: dylex/pidgin
static void
silcpurple_add_buddy_pk_no(SilcPurpleBuddyRes r)
{
	char tmp[512];
	g_snprintf(tmp, sizeof(tmp), _("The %s buddy is not trusted"),
		   r->b->name);
	purple_notify_error(r->client->application, _("Add Buddy"), tmp,
			  _("You cannot receive buddy notifications until you "
			    "import his/her public key.  You can use the Get Public Key "
			    "command to get the public key."));
	purple_prpl_got_user_status(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), SILCPURPLE_STATUS_ID_OFFLINE, NULL);
}
예제 #15
0
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); */
}
예제 #16
0
void jabber_google_presence_incoming(JabberStream *js, const char *user, JabberBuddyResource *jbr)
{
	if (!js->googletalk)
		return;
	if (jbr->status && purple_str_has_prefix(jbr->status, "♫ ")) {
		purple_prpl_got_user_status(js->gc->account, user, "tune",
					    PURPLE_TUNE_TITLE, jbr->status + strlen("♫ "), NULL);
		g_free(jbr->status);
		jbr->status = NULL;
	} else {
		purple_prpl_got_user_status_deactive(js->gc->account, user, "tune");
	}
}
예제 #17
0
/* When you ask other people for authorization */
void
oscar_auth_sendrequest(PurpleConnection *gc, const char *bname, const char *msg)
{
	OscarData *od;
	PurpleAccount *account;
	PurpleBuddy *buddy;
	PurpleGroup *group;
	const char *gname;

	od = purple_connection_get_protocol_data(gc);
	account = purple_connection_get_account(gc);
	buddy = purple_find_buddy(account, bname);
	if (buddy != NULL)
		group = purple_buddy_get_group(buddy);
	else
		group = NULL;

	if (group != NULL)
	{
		gname = purple_group_get_name(group);
		purple_debug_info("oscar", "ssi: adding buddy %s to group %s\n",
				   bname, gname);
		aim_ssi_sendauthrequest(od, bname, msg ? msg : _("Please authorize me so I can add you to my buddy list."));
		if (!aim_ssi_itemlist_finditem(od->ssi.local, gname, bname, AIM_SSI_TYPE_BUDDY))
		{
			aim_ssi_addbuddy(od, bname, gname, NULL, purple_buddy_get_alias_only(buddy), NULL, NULL, TRUE);

			/* Mobile users should always be online */
			if (bname[0] == '+') {
				purple_prpl_got_user_status(account,
						purple_buddy_get_name(buddy),
						OSCAR_STATUS_ID_AVAILABLE, NULL);
				purple_prpl_got_user_status(account,
						purple_buddy_get_name(buddy),
						OSCAR_STATUS_ID_MOBILE, NULL);
			}
		}
	}
}
예제 #18
0
파일: hon.c 프로젝트: theli-ua/honpurple
void hon_parse_initiall_statuses(PurpleConnection *gc,gchar* buffer){
    guint32 status,flags;
    hon_account* hon;
    guint32 id,count = read_guint32(buffer);
    hon = gc->proto_data;
    purple_debug_info(HON_DEBUG_PREFIX, "parsing status for %d buddies\n",count);
    while (count-- > 0)
    {
        gchar* raw_gamename = NULL;
        gchar* nick,*gamename=NULL, *server=NULL,*status_id = HON_STATUS_ONLINE_S, 
            *color = NULL, *icon = NULL;
        guint32 matchid = 0;

        id = read_guint32(buffer);
        status = read_byte(buffer);
        flags = read_byte(buffer);
        color = read_string(buffer);
        icon  = read_string(buffer);
        nick = g_hash_table_lookup(hon->id2nick,GINT_TO_POINTER(id));
        if (status == HON_STATUS_INLOBBY || status == HON_STATUS_INGAME)
        {
            server = read_string(buffer);
            status_id = HON_STATUS_INGAME_S;
            raw_gamename = read_string(buffer);
            gamename = hon_strip(raw_gamename,TRUE);
            matchid = read_guint32(buffer);
        }
        if(!status)
            status_id = HON_STATUS_OFFLINE_S;
        purple_debug_info(HON_DEBUG_PREFIX, "status for %s,flags:%d,status:%d,game:%s,server:%s\n",nick,flags,status,gamename,server);
        if (nick)
            purple_prpl_got_user_status(gc->account, nick, status_id,
                HON_BUDDYID_ATTR , id,
                HON_STATUS_ATTR,status,HON_FLAGS_ATTR,flags,
                server ? HON_SERVER_ATTR : NULL,server,gamename ? HON_GAME_ATTR : NULL,gamename,NULL);
        g_free(gamename);
#ifdef MINBIF
    if (nick)
    {
        if (status == HON_STATUS_INGAME)
            status_id = g_strdup_printf("%s %s %d 0 %s",MINBIF_STATUS,
                    nick,status,raw_gamename);
        else
            status_id = g_strdup_printf("%s %s %d",MINBIF_STATUS,
                    nick,status);
        serv_got_im(gc,MINBIF_USER,status_id,PURPLE_MESSAGE_RECV,time(NULL));
        g_free(status_id);
    }
#endif
    }
}
예제 #19
0
void
pb_add_buddy_with_invite(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group, const char* message)
{
	PushBulletAccount *pba = pc->proto_data;
	const gchar *contacts_url = "https://api.pushbullet.com/v2/contacts";
	GString *postdata;
	const gchar *buddy_name;
	
	buddy_name = purple_buddy_get_name(buddy);
	if (!PB_IS_SMS(buddy_name)) {
		postdata = g_string_new(NULL);
		g_string_append_printf(postdata, "name=%s", purple_url_encode(purple_buddy_get_alias(buddy)));
		g_string_append_printf(postdata, "email=%s", purple_url_encode(buddy_name));
		
		pb_fetch_url(pba, contacts_url, postdata->str, NULL, NULL);
		
		g_string_free(postdata, TRUE);
		purple_prpl_got_user_status(pba->account, buddy_name, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL);
	} else {
		
		purple_prpl_got_user_status(pba->account, buddy_name, "mobile", NULL);
		purple_prpl_got_user_status(pba->account, buddy_name, purple_primitive_get_id_from_type(PURPLE_STATUS_AVAILABLE), NULL);
	}
}
예제 #20
0
/**
 * Set the currently playing song artist and or title.
 *
 * @param user User associated with the now playing information.
 *
 * @param new_artist New artist to set, or NULL/empty to not change artist.
 *
 * @param new_title New title to set, or NULL/empty to not change title.
 *
 * If new_artist and new_title are NULL/empty, deactivate PURPLE_STATUS_TUNE.
 *
 * This function is useful because it lets you set the artist or title
 * individually, which purple_prpl_got_user_status() doesn't do.
 */
static void msim_set_artist_or_title(MsimUser *user, const char *new_artist, const char *new_title)
{
    PurplePresence *presence;
    const char *prev_artist, *prev_title;

    if (user->buddy == NULL)
        /* User not on buddy list so nothing to do */
        return;

    prev_artist = NULL;
    prev_title = NULL;

    if (new_artist && !*new_artist)
        new_artist = NULL;
    if (new_title && !*new_title)
        new_title = NULL;

    if (!new_artist && !new_title) {
        purple_prpl_got_user_status_deactive(user->buddy->account, user->buddy->name, "tune");
        return;
    }

    presence = purple_buddy_get_presence(user->buddy);

    if (purple_presence_is_status_primitive_active(presence, PURPLE_STATUS_TUNE)) {
        PurpleStatus *status;

        status = purple_presence_get_status(presence, "tune");
        prev_title = purple_status_get_attr_string(status, PURPLE_TUNE_TITLE);
        prev_artist = purple_status_get_attr_string(status, PURPLE_TUNE_ARTIST);
    }

    if (!new_artist)
        new_artist = prev_artist;

    if (!new_title)
        new_title = prev_title;

    purple_prpl_got_user_status(user->buddy->account, user->buddy->name, "tune",
                                PURPLE_TUNE_TITLE, new_title,
                                PURPLE_TUNE_ARTIST, new_artist,
                                NULL);
}
예제 #21
0
static void jabber_mood_cb(JabberStream *js, const char *from, PurpleXmlNode *items) {
	/* it doesn't make sense to have more than one item here, so let's just pick the first one */
	PurpleXmlNode *item = purple_xmlnode_get_child(items, "item");
	const char *newmood = NULL;
	char *moodtext = NULL;
	JabberBuddy *buddy = jabber_buddy_find(js, from, FALSE);
	PurpleXmlNode *moodinfo, *mood;
	/* ignore the mood of people not on our buddy list */
	if (!buddy || !item)
		return;

	mood = purple_xmlnode_get_child_with_namespace(item, "mood", "http://jabber.org/protocol/mood");
	if (!mood)
		return;
	for (moodinfo = mood->child; moodinfo; moodinfo = moodinfo->next) {
		if (moodinfo->type == PURPLE_XMLNODE_TYPE_TAG) {
			if (!strcmp(moodinfo->name, "text")) {
				if (!moodtext) /* only pick the first one */
					moodtext = purple_xmlnode_get_data(moodinfo);
			} else {
				const PurpleMood *target_mood;

				/* verify that the mood is known (valid) */
				target_mood = find_mood_by_name(moodinfo->name);
				newmood = target_mood ? target_mood->mood : NULL;
			}

		}
		if (newmood != NULL && moodtext != NULL)
			break;
	}
	if (newmood != NULL) {
		purple_prpl_got_user_status(purple_connection_get_account(js->gc), from, "mood",
				PURPLE_MOOD_NAME, newmood,
				PURPLE_MOOD_COMMENT, moodtext,
				NULL);
	} else {
		purple_prpl_got_user_status_deactive(purple_connection_get_account(js->gc), from, "mood");
	}
	g_free(moodtext);
}
예제 #22
0
void jabber_roster_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
		PurpleGroup *group)
{
	JabberStream *js = gc->proto_data;
	char *who;
	JabberBuddy *jb;
	JabberBuddyResource *jbr;
	char *my_bare_jid;

	if(!js->roster_parsed)
		return;

	if(!(who = jabber_get_bare_jid(buddy->name)))
		return;

	jb = jabber_buddy_find(js, buddy->name, FALSE);

	jabber_roster_update(js, who, NULL);

	my_bare_jid = g_strdup_printf("%s@%s", js->user->node, js->user->domain);
	if(!strcmp(who, my_bare_jid)) {
		PurplePresence *gpresence;
		PurpleStatus *status;

		gpresence = purple_account_get_presence(js->gc->account);
		status = purple_presence_get_active_status(gpresence);
		jabber_presence_fake_to_self(js, status);
	} else if(!jb || !(jb->subscription & JABBER_SUB_TO)) {
		jabber_presence_subscription_set(js, who, "subscribe");
	} else if((jbr =jabber_buddy_find_resource(jb, NULL))) {
		purple_prpl_got_user_status(gc->account, who,
				jabber_buddy_state_get_status_id(jbr->state),
				"priority", jbr->priority, jbr->status ? "message" : NULL, jbr->status, NULL);
	}

	g_free(my_bare_jid);
	g_free(who);
}
예제 #23
0
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);
		}*/
	}
}
예제 #24
0
static void discover_status(PurpleConnection *from, PurpleConnection *to,
                            gpointer userdata) {
  const char *from_username = purple_account_get_username(purple_connection_get_account(from));
  const char *to_username = purple_account_get_username(purple_connection_get_account(to));

  if (purple_blist_find_buddy(purple_connection_get_account(from), to_username)) {
    PurpleStatus *status = purple_account_get_active_status(purple_connection_get_account(to));
    const char *status_id = purple_status_get_id(status);
    const char *message = purple_status_get_attr_string(status, "message");

    if (!strcmp(status_id, NULL_STATUS_ONLINE) ||
        !strcmp(status_id, NULL_STATUS_AWAY) ||
        !strcmp(status_id, NULL_STATUS_OFFLINE)) {
      purple_debug_info("nullprpl", "%s sees that %s is %s: %s\n",
                        from_username, to_username, status_id, message);
      purple_prpl_got_user_status(purple_connection_get_account(from), to_username, status_id,
                                  (message) ? "message" : NULL, message, NULL);
    } else {
      purple_debug_error("nullprpl",
                         "%s's buddy %s has an unknown status: %s, %s",
                         from_username, to_username, status_id, message);
    }
  }
}
예제 #25
0
파일: irc.c 프로젝트: dylex/pidgin
static void irc_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy, PurpleGroup *group)
{
	struct irc_conn *irc = (struct irc_conn *)gc->proto_data;
	struct irc_buddy *ib;
	const char *bname = purple_buddy_get_name(buddy);

	ib = g_hash_table_lookup(irc->buddies, bname);
	if (ib != NULL) {
		ib->ref++;
		purple_prpl_got_user_status(irc->account, bname,
				ib->online ? "available" : "offline", NULL);
	} else {
		ib = g_new0(struct irc_buddy, 1);
		ib->name = g_strdup(bname);
		ib->ref = 1;
		g_hash_table_replace(irc->buddies, ib->name, ib);
	}

	/* if the timer isn't set, this is during signon, so we don't want to flood
	 * ourself off with ISON's, so we don't, but after that we want to know when
	 * someone's online asap */
	if (irc->timer)
		irc_ison_one(irc, ib);
}
예제 #26
0
파일: f_buddy.c 프로젝트: lichengjie/fetion
gboolean
GetContactList_cb(struct fetion_account_data *sip, struct sipmsg *msg,
		  struct transaction *tc)
{
	xmlnode *item, *group, *isc;
	const gchar *name_group, *group_id;
	PurpleBuddy *b;
	PurpleGroup *g = NULL;
	struct fetion_buddy *bs;
	struct group_attr *g_attr;
	gint len = msg->bodylen;

	purple_debug(PURPLE_DEBUG_MISC, "fetion",
		     "in process GetContactList response response: %d\n",
		     msg->response);
	switch (msg->response) {
	case 200:

		/*Convert the contact from XML to Purple Buddies */
		isc = xmlnode_from_str(msg->body, len);
		purple_debug_info("fetion:", "after xmlnode to str\n");
		group = xmlnode_get_child(isc, "contacts/buddy-lists");
		g_return_val_if_fail(group != NULL, FALSE);

		/* ToDo. Find for all groups */
		sip->GetContactFlag = 1;
		for ((group = xmlnode_get_child(group, "buddy-list")); group;
		     group = xmlnode_get_next_twin(group)) {
			purple_debug_info("fetion:", "buddy-list\n");
			name_group = xmlnode_get_attrib(group, "name");
			group_id = xmlnode_get_attrib(group, "id");
			g_return_val_if_fail(name_group != NULL, FALSE);
			purple_debug_info("fetion", "name_group->%s\n",
					  name_group);
			g = purple_find_group(name_group);
			if (!g) {
				g = purple_group_new(name_group);
			}
			g_attr = g_new0(struct group_attr, 1);
			g_attr->name = g_strdup(name_group);
			g_attr->id = g_strdup(group_id);
			g_hash_table_insert(sip->group, g_attr->id, g_attr);
			g_hash_table_insert(sip->group2id, g_attr->name,
					    g_attr);
		}

		group = xmlnode_get_child(isc, "contacts/buddies");
		g_return_val_if_fail(group != NULL, FALSE);

		for (item = xmlnode_get_child(group, "buddy"); item;
		     item = xmlnode_get_next_twin(item)) {
			const gchar *uri, *name;
			char *buddy_name;
			const gchar *g_id;
			uri = xmlnode_get_attrib(item, "uri");
			name = xmlnode_get_attrib(item, "local-name");
			g_id = xmlnode_get_attrib(item, "buddy-lists");

			buddy_name = g_strdup_printf("%s", uri);
			if ((g_id == NULL) || (*g_id == '\0')
			    || strlen(g_id) > 1) {
				g = purple_find_group("未分组");
				if (!g)
					g = purple_group_new("未分组");
			} else {
				g_attr = g_hash_table_lookup(sip->group, g_id);
				g_return_val_if_fail(g_attr != NULL, FALSE);
				g = purple_find_group(g_attr->name);

				if (!g)
					g = purple_group_new(g_attr->name);
			}

			b = purple_find_buddy(sip->account, buddy_name);
			if (!b) {
				b = purple_buddy_new(sip->account, buddy_name,
						     NULL);
			}
			g_free(buddy_name);

			purple_blist_add_buddy(b, NULL, g, NULL);
			if (name != NULL && *name != '\0')
				purple_blist_alias_buddy(b, name);
			bs = g_new0(struct fetion_buddy, 1);
			bs->name = g_strdup(b->name);
			g_hash_table_insert(sip->buddies, bs->name, bs);

			purple_prpl_got_user_status(sip->account, uri, "mobile",
						    NULL);

		}
		group = xmlnode_get_child(isc, "contacts/mobile-buddies");
		g_return_val_if_fail(group != NULL, FALSE);

		for (item = xmlnode_get_child(group, "mobile-buddy"); item;
		     item = xmlnode_get_next_twin(item)) {
			const gchar *uri, *name;
			gchar *buddy_name;
			const gchar *g_id;
			uri = xmlnode_get_attrib(item, "uri");
			name = xmlnode_get_attrib(item, "local-name");
			g_id = xmlnode_get_attrib(item, "buddy-lists");

			buddy_name = g_strdup_printf("%s", uri);
			if ((g_id == NULL) || (*g_id == '\0')
			    || strlen(g_id) > 1) {
				g = purple_find_group("未分组");
				if (!g)
					g = purple_group_new("未分组");
			} else {
				g_attr = g_hash_table_lookup(sip->group, g_id);
				//g_return_val_if_fail(g_attr!=NULL,FALSE);
				if (g_attr == NULL)
					continue;
				g = purple_find_group(g_attr->name);
				if (!g)
					g = purple_group_new(g_attr->name);
			}

			b = purple_find_buddy(sip->account, buddy_name);
			if (!b) {
				b = purple_buddy_new(sip->account, buddy_name,
						     uri);
			}
			g_free(buddy_name);

			purple_blist_add_buddy(b, NULL, g, NULL);
			if (name != NULL && *name != '\0')
				purple_blist_alias_buddy(b, name);
			else
				purple_blist_alias_buddy(b, uri);
			bs = g_new0(struct fetion_buddy, 1);
			bs->name = g_strdup(b->name);
			g_hash_table_insert(sip->buddies, bs->name, bs);
			purple_prpl_got_user_status(sip->account, uri, "mobile",
						    NULL);
		}

		fetion_subscribe_exp(sip, NULL);
		//Add youself

		b = purple_find_buddy(sip->account, sip->uri);
		if (!b) {
			b = purple_buddy_new(sip->account, sip->uri, NULL);
		}

		purple_blist_add_buddy(b, NULL, g, NULL);
		purple_blist_alias_buddy(b, "轰炸自己");
		bs = g_new0(struct fetion_buddy, 1);
		bs->name = g_strdup(b->name);
		g_hash_table_insert(sip->buddies, bs->name, bs);

		purple_prpl_got_user_status(sip->account, sip->uri, "mobile",
					    NULL);

		xmlnode_free(isc);

		break;
	default:
		GetContactList(sip);
		break;
	}

	return TRUE;
}
예제 #27
0
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);
}
예제 #28
0
static gboolean plain_receive(gpointer data)
{
	purple_debug_info("plainprpl", "plain_receive called\n");

	char msgbuf[MAX_MESSAGE_SIZE];
	int msgbuf_len;
	IP addr;
	const char *status;
	PurpleConnection *gc;
	PurpleAccount *account;
	PurpleBuddy *buddy;
	plain_plugin_state *pstate;
	plain_buddy_state *bstate;

	/* Get time in seconds since 1970 */
	time_t now = time(NULL);

	gc = (PurpleConnection *) data;
	account = purple_connection_get_account(gc);
	pstate = purple_connection_get_protocol_data(gc);

	/* Check if we need to ping any buddy */
	ping_buddies(gc, now);

	msgbuf_len = sizeof(msgbuf);
	buddy = receive_msg(pstate, &addr, msgbuf, &msgbuf_len);

	/* Nothing to receive or error */
	if (msgbuf_len <= 0) {
		return TRUE;
	}

	if (!g_utf8_validate(msgbuf, -1, NULL)) {
		purple_debug_info("plainprpl", "Received invalid UTF8 message from %s - ignore.\n", str_addr(&addr));
		return TRUE;
	}

	/* We got a message and identified the sender */
	purple_debug_info("plainprpl", "Received message from %s (%d Bytes): %s\n", str_addr(&addr), strlen(msgbuf), msgbuf);

	/* We got a message from a source we don't know */
	gboolean allow_unknown = purple_account_get_bool(account, "allow_unknown", FALSE);
	if (buddy == NULL) {
		purple_debug_info("plainprpl", "Packet from unknown buddy from address %s.\n", str_addr(&addr));

		if (allow_unknown && !pstate->block_unknown) {
			//temporary disable the setting
			pstate->block_unknown = TRUE;
			plainprpl_add_buddy_by_contact_request(gc, str_addr(&addr), msgbuf);
		}
		return TRUE;
	}

	bstate = purple_buddy_get_protocol_data(buddy);
	if (bstate == NULL) {
		purple_debug_info("plainprpl", "bstate of buddy %s is NULL.\n", buddy->name);
		return TRUE;
	}

	status = PLAIN_STATUS_ONLINE;

	if (strcmp(msgbuf, "/ping") == 0) {
		/* Received a ping from a buddy */
		if ((bstate->time_recv + 5) < now) {
			/* Send pong at most every 5 seconds */
			send_msg(pstate, bstate, "/pong");
		} else {
			/* Ignore ping */
		}
	} else if (strcmp(msgbuf, "/pong") == 0) {
		/* Nothing to do */
	} else if (strcmp(msgbuf, "/bye") == 0) {
		status = PLAIN_STATUS_OFFLINE;
	} else if (msgbuf[0] != '/') {
		/* Display message */
		serv_got_im(gc, bstate->name, msgbuf, PURPLE_MESSAGE_RECV, now);
	} else {
		/* Unknown command - ignore */
	}

	bstate->time_recv = now;

	/* Set buddy status to online */
	purple_prpl_got_user_status(account, bstate->name, status, NULL);

	return TRUE; //continue loop
}
예제 #29
0
/* Ping buddies a ping every 5 minutes if there is no traffic */
void ping_buddies(PurpleConnection *gc, time_t now)
{
	PurpleBuddy *buddy;
	PurpleAccount *account;
	plain_buddy_state *bstate;
	plain_plugin_state *pstate;
	time_t time_next;
	GSList *iter;

	account = purple_connection_get_account(gc);
	pstate = purple_connection_get_protocol_data(gc);

	if(pstate->time_next > now) {
		return;
	}

	time_next = now + (60*5); //max time we wait for another round
	const char *on_lookup = purple_account_get_string(account, "on_lookup", NULL);

	iter = pstate->all_buddies;
	while (iter) {
		buddy = iter->data;
		bstate = purple_buddy_get_protocol_data(buddy);

		//uninitialized buddy
		if(bstate == NULL) {
			purple_debug_info("plainprpl", "Buddy %s has no state set.\n", buddy->name);
			goto next;
		}

		//printf("Do ping_buddies for %s\n", buddy->name);

		int state = bstate->state;
		int state_step = bstate->state_step;
		time_t state_next = bstate->state_next;

		if(state == BUDDY_STATE_RESOLVE) {
			const char *addr_str = purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy), "addr_str");
			if(exec_process(on_lookup, addr_str, on_lookup_handle, gc, buddy) == 0) {
				/* Script was called - wait for answer some other time */
				purple_debug_info("plainprpl", "Lookup by SCRIPT succeded. Start to ping %s\n", str_addr(&bstate->addr));
				state = BUDDY_STATE_PING;
				state_step = 1;
				state_next = now + 1;
			} else if(addr_parse_full(&bstate->addr, addr_str, PLAIN_DEFAULT_PORT_STR, pstate->sockaf) == 0) {
				purple_debug_info("plainprpl", "Lookup by DNS succeded (%s). Start to ping %s\n", addr_str, str_addr(&bstate->addr));
				//switch to ping state
				state = BUDDY_STATE_PING;
				state_step = 1;
				state_next = now + 1;
			} else {
				if(state_step == 0) {
					state_step = 4;
				} else if(state_step < (5*60)) {
					state_step *= 2;
				}

				purple_debug_info("plainprpl", "Resolve failed. Try again in %d seconds.\n", state_step);
				state_next = now + state_step;
			}
		} else if(state == BUDDY_STATE_PING) {
			//send ping
			if(bstate->time_recv < (now - (5*60))) {
				if(state_step < (5*60)) {
					state_step *= 2;
					state_next = now + state_step;

					send_msg(pstate, bstate, "/ping");

					/* Set buddy status to online */
					purple_prpl_got_user_status(account, bstate->name, PLAIN_STATUS_OFFLINE, NULL);
				} else {
					state = BUDDY_STATE_RESOLVE;
					state_step = 1;
					state_next = now + 1;
				}
			} else {
				state_step = 1;
				state_next = now + (5*60);
			}
		} else {
			purple_debug_info("plainprpl", "Invalid state: %d\n", state);
		}

		bstate->state = state;
		bstate->state_step = state_step;
		bstate->state_next = state_next;

		/* Get next time we need to do something here */
		if (state_next < time_next) {
			time_next = state_next;
		}

next:
		iter = iter->next;
	}

	pstate->time_next = time_next;
	purple_debug_info("plainprpl", "Next iteration in %d seconds.\n", (int)(time_next - now));
}
예제 #30
0
파일: roster.c 프로젝트: psunkari/spicebird
void jabber_roster_add_buddy(PurpleConnection *gc, PurpleBuddy *buddy,
		PurpleGroup *group)
{
	JabberStream *js = gc->proto_data;
	char *who;
	JabberID *jid;
	JabberBuddy *jb;
	JabberBuddyResource *jbr;
	const char *name;

	/* If we haven't received the roster yet, ignore any adds */
	if (js->state != JABBER_STREAM_CONNECTED)
		return;

	name = purple_buddy_get_name(buddy);
	jid = jabber_id_new(name);
	if (jid == NULL) {
		/* TODO: Remove the buddy from the list? */
		return;
	}

	/* Adding a chat room or a chat buddy to the roster is *not* supported. */
	if (jid->node && jabber_chat_find(js, jid->node, jid->domain) != NULL) {
		/*
		 * This is the same thing Bonjour does. If it causes problems, move
		 * it to an idle callback.
		 */
		purple_debug_warning("jabber", "Cowardly refusing to add a MUC user "
		                     "to your buddy list and removing the buddy. "
		                     "Buddies can only be added by real (non-MUC) "
		                     "JID\n");
		purple_blist_remove_buddy(buddy);
		jabber_id_free(jid);
		return;
	}

	who = jabber_id_get_bare_jid(jid);
	if (jid->resource != NULL) {
		/*
		 * If the buddy name added contains a resource, strip that off and
		 * rename the buddy.
		 */
		purple_blist_rename_buddy(buddy, who);
	}

	jb = jabber_buddy_find(js, who, FALSE);

	purple_debug_info("jabber", "jabber_roster_add_buddy(): Adding %s\n", who);

	jabber_roster_update(js, who, NULL);

	if (jb == js->user_jb) {
		jabber_presence_fake_to_self(js, NULL);
	} else if(!jb || !(jb->subscription & JABBER_SUB_TO)) {
		jabber_presence_subscription_set(js, who, "subscribe");
	} else if((jbr =jabber_buddy_find_resource(jb, NULL))) {
		purple_prpl_got_user_status(gc->account, who,
				jabber_buddy_state_get_status_id(jbr->state),
				"priority", jbr->priority, jbr->status ? "message" : NULL, jbr->status, NULL);
	}

	g_free(who);
}