Пример #1
0
bool BuddyListNode::lessOrEqualByBuddySort(PurpleBuddy *left,
    PurpleBuddy *right) const
{
  BuddyList::BuddySortMode mode = BUDDYLIST->getBuddySortMode();
  int a, b;

  switch (mode) {
    case BuddyList::BUDDY_SORT_BY_NAME:
      break;
    case BuddyList::BUDDY_SORT_BY_STATUS:
      a = getBuddyStatusWeight(left);
      b = getBuddyStatusWeight(right);
      if (a != b)
        return a > b;
      break;
    case BuddyList::BUDDY_SORT_BY_ACTIVITY:
      {
        BuddyListNode *bnode_left = reinterpret_cast<BuddyListNode*>(
            purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(left)));
        BuddyListNode *bnode_right = reinterpret_cast<BuddyListNode*>(
            purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(right)));
        a = bnode_left->last_activity;
        b = bnode_right->last_activity;
        if (a != b)
          return a > b;
      }
      break;
  }
  return g_utf8_collate(purple_buddy_get_alias(left),
      purple_buddy_get_alias(right)) <= 0;
}
Пример #2
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;
}
void rc_pop_contacts(PurpleGroup * grp)
{
  if (!grp) return;

  PurpleBlistNode * gnode = PURPLE_BLIST_NODE(grp);
  PurpleBlistNode * n = NULL;
  PurpleBuddy * b = NULL;
  int total;
  gboolean offline;

  //XXX group->totalsize is unreliable!!!

  for (n=gnode->child, total=0; n!=NULL; total++, n=n->next);
  trace("Total Group Count %d", total);

  while (total > g_size) {

    n = gnode->child;

    if (PURPLE_BLIST_NODE_IS_CONTACT(n)) {
      trace("Child Contact : %s", (PURPLE_CONTACT(n)->priority->name));
      b = PURPLE_CONTACT(n)->priority;
    } else if (PURPLE_BLIST_NODE_IS_BUDDY(n)) {
      trace("Child Buddy : %s", (PURPLE_BUDDY(n)->name));
      b = PURPLE_BUDDY(n);
    }

    n = PURPLE_BLIST_NODE(b);
    const char *name = purple_blist_node_get_string(n, NODE_GROUP_KEY);
    if (!name) {  // if cannot find orig group name, put back to Buddies
      trace("ERROR!!! cannot find original group name"); 
      name = "Buddies"; 
    }
    PurpleGroup * g = purple_find_group(name);
    if (!g) {
      trace("Group %s Not Found. Create one.", name);
      g = purple_group_new(name);
    }
    trace("<<<<<<< Remove %s", b->name);

    offline = purple_blist_node_get_bool(n, NODE_ORIG_OFFLINE_KEY);
    purple_blist_node_set_bool(n, NODE_OFFLINE_KEY, offline);
    purple_blist_add_buddy(b, NULL, g, NULL);

    total--;
  }
  
}
Пример #4
0
void BuddyListContact::ContactContextMenu::removeResponseHandler(
    CppConsUI::MessageDialog& /*activator*/,
    CppConsUI::AbstractDialog::ResponseType response)
{
  if (response != CppConsUI::AbstractDialog::RESPONSE_OK)
    return;

  // based on gtkdialogs.c:pidgin_dialogs_remove_contact_cb()
  PurpleContact *contact = parent_contact->getPurpleContact();
  PurpleBlistNode *cnode = PURPLE_BLIST_NODE(contact);
  PurpleGroup *group = purple_contact_get_group(contact);

  for (PurpleBlistNode *bnode = purple_blist_node_get_first_child(cnode);
      bnode; bnode = purple_blist_node_get_sibling_next(bnode)) {
    PurpleBuddy *buddy = PURPLE_BUDDY(bnode);
    PurpleAccount *account = purple_buddy_get_account(buddy);
    if (purple_account_is_connected(account))
      purple_account_remove_buddy(account, buddy, group);
  }

  /* Close the context menu before the contact is deleted because its deletion
   * can lead to destruction of this object. */
  close();

  purple_blist_remove_contact(contact);
}
Пример #5
0
static void plainprpl_get_info(PurpleConnection *gc, const char *buddy_name)
{
	PurpleBuddy *buddy;
	plain_buddy_state *bstate;
	PurpleNotifyUserInfo *info;
	const char *addr_str;

	buddy = purple_find_buddy(gc->account, buddy_name);
	bstate = purple_buddy_get_protocol_data(buddy);
	info = purple_notify_user_info_new();

	if (bstate) {

		PurplePresence *presence = purple_buddy_get_presence(buddy);
		PurpleStatus *status = purple_presence_get_active_status(presence);
		const char *status_name = purple_status_get_name(status);

		purple_notify_user_info_add_pair(info, "Status", status_name);
		addr_str = purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy), "addr_str");
		purple_notify_user_info_add_pair(info, "Address", addr_str);
		if (bstate->state == BUDDY_STATE_RESOLVE) {
			/* The IP address has not been resolved yet */
			purple_notify_user_info_add_pair(info, "Resolved", "Unknown");
		} else {
			purple_notify_user_info_add_pair(info, "Resolved", str_addr(&bstate->addr));
		}
		purple_notify_user_info_add_pair(info, "Last Seen", str_time(bstate->time_recv));
	} else {
		purple_notify_user_info_add_pair(info, "Info", "Missing Data");
	}

	/* Show a buddy's user info in a nice dialog box */
	purple_notify_userinfo(gc, buddy_name, info, NULL, NULL);
}
Пример #6
0
void
purple_events_ui_menu_add(PurpleBlistNode *node, GList **menu, PurpleEventsContext *context)
{
    PurpleBlistNode *group = NULL;

    node = _purple_events_ui_get_good_node(node);
    if ( ( node == NULL ) || ( ( purple_blist_node_get_flags(node) & PURPLE_BLIST_NODE_FLAG_NO_SAVE ) > 0 ) )
        return;

    if ( PURPLE_BLIST_NODE_IS_CONTACT(node) )
        group = PURPLE_BLIST_NODE(purple_buddy_get_group(purple_contact_get_priority_buddy(PURPLE_CONTACT(node))));


    gint current = purple_blist_node_get_int(node, "events");
    GList *actions = NULL;
    PurpleMenuAction *action = NULL;

    const gchar *label = "";
    if ( current != 0 )
    {
        if ( PURPLE_BLIST_NODE_IS_GROUP(node) || ( purple_blist_node_get_int(group, "events") == 0 ) )
            label = _("Use global settings");
        else
            label = _("Use group settings");
        action = purple_menu_action_new(label, (PurpleCallback)_purple_events_ui_reset_setting, NULL, NULL);
        actions = g_list_prepend(actions, action);
    }
    if ( current >= 0 )
    {
        action = purple_menu_action_new(_("Disable all events"), (PurpleCallback)_purple_events_ui_disable_all_events, NULL, NULL);
        actions = g_list_prepend(actions, action);
    }

    action = purple_menu_action_new(_("Select events"), (PurpleCallback)_purple_events_ui_events_selection_dialog, context, NULL);
    actions = g_list_prepend(actions, action);

    switch ( current )
    {
    case -1:
        label = _("Current events: all disabled");
    break;
    case 0:
        if ( PURPLE_BLIST_NODE_IS_GROUP(node) || ( purple_blist_node_get_int(group, "events") == 0 ) )
            label = _("Current events: global settings");
        else
            label = _("Current events: group settings");
    break;
    case 1:
        label = _("Current events: selection");
    break;
    }
    actions = g_list_prepend(actions, NULL);
    action = purple_menu_action_new(label, NULL, NULL, NULL);
    actions = g_list_prepend(actions, action);

    *menu = g_list_append(*menu, NULL);
    action = purple_menu_action_new(_("Events"), NULL, NULL, actions);
    *menu = g_list_append(*menu, action);
}
Пример #7
0
void BuddyListContact::onActivate(Button& activator)
{
  PurpleBuddy *buddy = purple_contact_get_priority_buddy(contact);
  BuddyListNode *bnode = reinterpret_cast<BuddyListNode*>(
      purple_blist_node_get_ui_data(PURPLE_BLIST_NODE(buddy)));
  if (bnode)
    bnode->onActivate(activator);
}
Пример #8
0
void BuddyListGroup::GroupContextMenu::onMoveAfter(Button& /*activator*/,
    PurpleGroup *group)
{
  PurpleGroup *moved_group = parent_group->getPurpleGroup();
  close();

  purple_blist_add_group(moved_group, PURPLE_BLIST_NODE(group));
}
Пример #9
0
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;
}
Пример #10
0
static PurpleBlistNode *
_purple_events_ui_get_good_node(PurpleBlistNode *node)
{
    if ( PURPLE_BLIST_NODE_IS_CONTACT(node) )
        return node;

    if ( PURPLE_BLIST_NODE_IS_BUDDY(node) )
        return PURPLE_BLIST_NODE(purple_buddy_get_contact(PURPLE_BUDDY(node)));

    if ( PURPLE_BLIST_NODE_IS_GROUP(node) )
        return node;

    return NULL;
}
Пример #11
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);
		}*/
	}
}
Пример #12
0
/* Get method for GObject properties */
static void
purple_blist_node_get_property(GObject *obj, guint param_id, GValue *value,
		GParamSpec *pspec)
{
	PurpleBlistNode *node = PURPLE_BLIST_NODE(obj);

	switch (param_id) {
		case BLNODE_PROP_TRANSIENT:
			g_value_set_boolean(value, purple_blist_node_is_transient(node));
			break;
		default:
			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
			break;
	}
}
Пример #13
0
static gpointer on_offline_find_parent(PurpleBlistNode *node)
{
	gpointer ret = NULL;

	if (PURPLE_IS_CONTACT(node)) {
		node = PURPLE_BLIST_NODE(purple_contact_get_priority_buddy(PURPLE_CONTACT(node)));
		ret = PURPLE_BUDDY_IS_ONLINE(PURPLE_BUDDY(node)) ? online : offline;
	} else if (PURPLE_IS_BUDDY(node)) {
		ret = purple_blist_node_get_parent(node);
		finch_blist_manager_add_node(ret);
	} else if (PURPLE_IS_CHAT(node)) {
		ret = online;
	}

	return ret;
}
Пример #14
0
static void ggp_roster_set_synchronized(PurpleConnection *gc,
	PurpleBuddy *buddy, gboolean synchronized)
{
	ggp_roster_session_data *rdata = ggp_roster_get_rdata(gc);
	uin_t uin = ggp_str_to_uin(purple_buddy_get_name(buddy));
	ggp_roster_change *change;

	purple_blist_node_set_bool(PURPLE_BLIST_NODE(buddy),
		GGP_ROSTER_SYNC_SETT, synchronized);
	if (!synchronized) {
		change = g_new0(ggp_roster_change, 1);
		change->type = GGP_ROSTER_CHANGE_CONTACT_UPDATE;
		change->data.uin = uin;
		rdata->pending_updates =
			g_list_append(rdata->pending_updates, change);
	}
}
Пример #15
0
void BuddyListGroup::GroupContextMenu::removeResponseHandler(
    CppConsUI::MessageDialog& /*activator*/,
    CppConsUI::AbstractDialog::ResponseType response)
{
  if (response != CppConsUI::AbstractDialog::RESPONSE_OK)
    return;

  // based on gtkdialogs.c:pidgin_dialogs_remove_group_cb()
  PurpleGroup *group = parent_group->getPurpleGroup();
  PurpleBlistNode *cnode = purple_blist_node_get_first_child(
      PURPLE_BLIST_NODE(group));
  while (cnode) {
    if (PURPLE_BLIST_NODE_IS_CONTACT(cnode)) {
      PurpleBlistNode *bnode = purple_blist_node_get_first_child(cnode);
      cnode = purple_blist_node_get_sibling_next(cnode);
      while (bnode)
        if (PURPLE_BLIST_NODE_IS_BUDDY(bnode)) {
          PurpleBuddy *buddy = PURPLE_BUDDY(bnode);
          PurpleAccount *account = purple_buddy_get_account(buddy);
          bnode = purple_blist_node_get_sibling_next(bnode);
          if (purple_account_is_connected(account)) {
            purple_account_remove_buddy(account, buddy, group);
            purple_blist_remove_buddy(buddy);
          }
        }
        else
          bnode = purple_blist_node_get_sibling_next(bnode);
    }
    else if (PURPLE_BLIST_NODE_IS_CHAT(cnode)) {
      PurpleChat *chat = PURPLE_CHAT(cnode);
      cnode = purple_blist_node_get_sibling_next(cnode);
      purple_blist_remove_chat(chat);
    }
    else
      cnode = purple_blist_node_get_sibling_next(cnode);
  }

  /* Close the context menu before the group is deleted because its deletion
   * can lead to destruction of this object. */
  close();

  purple_blist_remove_group(group);
}
Пример #16
0
/* Receive message and identify buddy */
PurpleBuddy *receive_msg(plain_plugin_state *pstate, IP *addr_ret, char buf[], int *buf_length)
{
	char addrbuf[FULL_ADDSTRLEN+1];
	PurpleBuddy *buddy;
	plain_buddy_state *bstate;
	GSList *iter;
	socklen_t addrlen;
	IP addr;
	int n;

	addrlen = sizeof(IP);
	n = recvfrom(pstate->sockfd, buf, *buf_length, 0, (struct sockaddr *) &addr, &addrlen);
	if (n < 0 || n > *buf_length) {
		buf[0] = '\0';
		*buf_length = 0;
		return NULL;
	} else {
		buf[n] = '\0';
		*buf_length = n;
	}

	memcpy(addr_ret, &addr, sizeof(IP));

	iter = pstate->all_buddies;
	while (iter) {
		buddy = iter->data;
		bstate = purple_buddy_get_protocol_data(buddy);
		const char *addr_str = purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy), "addr_str");

		//printf("buddy: %s, addr: %s (addr_str: %s)\n", bstate->name, str_addr(&bstate->addr, addrbuf), addr_str);

		if(addr_equal(&bstate->addr, &addr)) {
			/* Found buddy by address */
			return buddy;
		}

		iter = iter->next;
	}

	/* No buddy found */
	return NULL;
}
Пример #17
0
void PurpleLine::tooltip_text(PurpleBuddy *buddy, PurpleNotifyUserInfo *user_info, gboolean full) {
    purple_notify_user_info_add_pair_plaintext(user_info,
        "Name", purple_buddy_get_alias(buddy));

    //purple_notify_user_info_add_pair_plaintext(user_info,
    //    "User ID", purple_buddy_get_name(buddy));

    if (purple_blist_node_get_bool(PURPLE_BLIST_NODE(buddy), "official_account"))
        purple_notify_user_info_add_pair_plaintext(user_info, "Official account", "Yes");

    if (PURPLE_BLIST_NODE_HAS_FLAG(buddy, PURPLE_BLIST_NODE_FLAG_NO_SAVE)) {
        // This breaks?
        //purple_notify_user_info_add_section_break(user_info);

        purple_notify_user_info_add_pair_plaintext(user_info,
            "Temporary",
            "You are currently in a conversation with this contact, "
                "but they are not on your friend list.");
    }
}
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);
}
Пример #19
0
static gpointer
nested_group_find_parent(PurpleBlistNode *node)
{
	char *name;
	PurpleGroup *group;
	char *sep;
	PurpleBlistNode *ret, *parent;
	GntTree *tree;

	if (!PURPLE_IS_GROUP(node))
		return default_manager->find_parent(node);

	group = PURPLE_GROUP(node);
	name = g_strdup(purple_group_get_name(group));
	if (!(sep = strchr(name, '/'))) {
		g_free(name);
		return default_manager->find_parent(node);
	}

	tree = finch_blist_get_tree();
	parent = NULL;

	while (sep) {
		*sep = 0;
		if (*(sep + 1) && (ret = PURPLE_BLIST_NODE(purple_blist_find_group(name)))) {
			finch_blist_manager_add_node(ret);
			parent = ret;
		} else if (!(ret = g_hash_table_lookup(groups, name))) {
			ret = g_object_new(FINCH_TYPE_GROUPING_NODE, NULL);
			g_hash_table_insert(groups, g_strdup(name), ret);
			gnt_tree_add_row_last(tree, ret,
					gnt_tree_create_row(tree, name), parent);
			parent = ret;
		}
		*sep = '/';
		sep = strchr(sep + 1, '/');
	}

	g_free(name);
	return ret;
}
Пример #20
0
static void plainprpl_change_address(PurpleBlistNode *node, gpointer userdata)
{
	PurpleBuddy *buddy;
	plain_buddy_state *bstate;

	char *request_str;
	const char *addr_str;

	PurpleRequestFields *fields;
	PurpleRequestFieldGroup *group;
	PurpleRequestField *field;

	fields = purple_request_fields_new();
	group = purple_request_field_group_new(NULL);
	purple_request_fields_add_group(fields, group);

	buddy = (PurpleBuddy *) node;
	bstate = purple_buddy_get_protocol_data(buddy);

	if (bstate) {
		addr_str = purple_blist_node_get_string(PURPLE_BLIST_NODE(buddy), "addr_str");
		field = purple_request_field_string_new("addr_str", _("Address"), addr_str, FALSE);
		purple_request_field_string_set_masked(field, FALSE);
		purple_request_field_group_add_field(group, field);

		request_str = g_strdup_printf("Address to reach buddy '%s'.", buddy->name);
		purple_request_fields(buddy->account, "Change Address",
			request_str,
			NULL, fields,
			_("OK"), G_CALLBACK(plainprpl_change_address_ok),
			_("Cancel"), G_CALLBACK(plainprpl_change_address_cancel),
			NULL, NULL, NULL, (void *) buddy
		);
		g_free(request_str);
	} else {
		purple_debug_info("plainprpl", "Buddy %s has no bstate set.\n", buddy->name);
	}
}
Пример #21
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;
}
Пример #22
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);
}
Пример #23
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));
}
Пример #24
0
static void
file_recv_request_cb(PurpleXfer *xfer, gpointer handle)
{
	PurpleAccount *account;
	PurpleBlistNode *node;
	const char *pref;
	char *filename;
	char *dirname;

    int accept_setting;

	account = xfer->account;
	node = PURPLE_BLIST_NODE(purple_find_buddy(account, xfer->who));

	/* If person is on buddy list, use the buddy setting; otherwise, use the
	   stranger setting. */
	if (node) {
		node = purple_blist_node_get_parent(node);
		g_return_if_fail(PURPLE_BLIST_NODE_IS_CONTACT(node));
		accept_setting = purple_blist_node_get_int(node, "autoaccept");
	} else {
		accept_setting = purple_prefs_get_int(PREF_STRANGER);
	}

	switch (accept_setting)
	{
		case FT_ASK:
			break;
		case FT_ACCEPT:
            pref = purple_prefs_get_string(PREF_PATH);
			if (ensure_path_exists(pref))
			{
				int count = 1;
				const char *escape;
				gchar **name_and_ext;
				const gchar *name;
				gchar *ext;

				if (purple_prefs_get_bool(PREF_NEWDIR))
					dirname = g_build_filename(pref, purple_normalize(account, xfer->who), NULL);
				else
					dirname = g_build_filename(pref, NULL);

				if (!ensure_path_exists(dirname))
				{
					g_free(dirname);
					break;
				}

				/* Escape filename (if escaping is turned on) */
				if (purple_prefs_get_bool(PREF_ESCAPE)) {
					escape = purple_escape_filename(xfer->filename);
				} else {
					escape = xfer->filename;
				}
				filename = g_build_filename(dirname, escape, NULL);

				/* Split at the first dot, to avoid uniquifying "foo.tar.gz" to "foo.tar-2.gz" */
				name_and_ext = g_strsplit(escape, ".", 2);
				name = name_and_ext[0];
				g_return_if_fail(name != NULL);
				if (name_and_ext[1] != NULL) {
					/* g_strsplit does not include the separator in each chunk. */
					ext = g_strdup_printf(".%s", name_and_ext[1]);
				} else {
					ext = g_strdup("");
				}

				/* Make sure the file doesn't exist. Do we want some better checking than this? */
				/* FIXME: There is a race here: if the newly uniquified file name gets created between
				 *        this g_file_test and the transfer starting, the file created in the meantime
				 *        will be clobbered. But it's not at all straightforward to fix.
				 */
				while (g_file_test(filename, G_FILE_TEST_EXISTS)) {
					char *file = g_strdup_printf("%s-%d%s", name, count++, ext);
					g_free(filename);
					filename = g_build_filename(dirname, file, NULL);
					g_free(file);
				}

				purple_xfer_request_accepted(xfer, filename);

				g_strfreev(name_and_ext);
				g_free(ext);
				g_free(dirname);
				g_free(filename);
			}

			purple_signal_connect(purple_xfers_get_handle(), "file-recv-complete", handle,
								PURPLE_CALLBACK(auto_accept_complete_cb), xfer);
			break;
		case FT_REJECT:
			xfer->status = PURPLE_XFER_STATUS_CANCEL_LOCAL;
			break;
	}
}
Пример #25
0
void Notify::UserInfoDialog::update(PurpleConnection *gc, const char *who,
    PurpleNotifyUserInfo *user_info)
{
  treeview->clear();
  CppConsUI::TreeView::NodeReference parent;
  CppConsUI::Button *button;

  // local information
  PurpleAccount *account = purple_connection_get_account(gc);
  PurpleBuddy *buddy = purple_find_buddy(account, who);
  if (buddy) {
    /* Note that we should always be able to find the specified buddy, unless
     * something goes very wrong. */
    button = new CppConsUI::TreeView::ToggleCollapseButton(
        _("Local information"));
    parent = treeview->appendNode(treeview->getRootNode(), *button);

    button = new CppConsUI::Button(CppConsUI::Button::FLAG_VALUE,
        _("Alias"), purple_buddy_get_alias(buddy));
    treeview->appendNode(parent, *button);

    time_t saved_time;
    struct tm local_time;
    const char *formatted_time;

    // last_seen
    if (PURPLE_BUDDY_IS_ONLINE(buddy))
      formatted_time = _("Now");
    else {
      saved_time = static_cast<time_t>(purple_blist_node_get_int(
            PURPLE_BLIST_NODE(buddy), "last_seen"));
      if (saved_time && localtime_r(&saved_time, &local_time))
        formatted_time = purple_date_format_long(&local_time);
      else
        formatted_time = _("Unknown");
    }
    button = new CppConsUI::Button(CppConsUI::Button::FLAG_VALUE,
        _("Last seen"), formatted_time);
    treeview->appendNode(parent, *button);

    // last_activity
    saved_time = static_cast<time_t>(purple_blist_node_get_int(
          PURPLE_BLIST_NODE(buddy), "last_activity"));
    if (saved_time && localtime_r(&saved_time, &local_time))
      formatted_time = purple_date_format_long(&local_time);
    else
      formatted_time = _("Unknown");
    button = new CppConsUI::Button(CppConsUI::Button::FLAG_VALUE,
        _("Last activity"), formatted_time);
    treeview->appendNode(parent, *button);
  }

  // remote information
  button = new CppConsUI::TreeView::ToggleCollapseButton(
      _("Remote information"));
  parent = treeview->appendNode(treeview->getRootNode(), *button);
  CppConsUI::TreeView::NodeReference subparent = parent;
  for (GList *i = purple_notify_user_info_get_entries(user_info); i;
      i = i->next) {
    PurpleNotifyUserInfoEntry *entry
      = reinterpret_cast<PurpleNotifyUserInfoEntry*>(i->data);
    PurpleNotifyUserInfoEntryType type
      = purple_notify_user_info_entry_get_type(entry);

    const char *label = purple_notify_user_info_entry_get_label(entry);
    if (!label)
      continue;
    const char *value = purple_notify_user_info_entry_get_value(entry);
    char *nohtml = purple_markup_strip_html(value);
    switch (type) {
      case PURPLE_NOTIFY_USER_INFO_ENTRY_PAIR:
        button = new CppConsUI::Button(
            nohtml ? CppConsUI::Button::FLAG_VALUE : 0, label, nohtml);
        treeview->appendNode(subparent, *button);
        break;
      case PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK:
        // ignore section breaks
        break;
      case PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER:
        button = new CppConsUI::TreeView::ToggleCollapseButton(label);
        subparent = treeview->appendNode(parent, *button);
        break;
      default:
        LOG->error(_("Unhandled userinfo entry type '%d'."), type);
        break;
    }
    g_free(nohtml);
  }

  treeview->grabFocus();
}
Пример #26
0
static gboolean ggp_roster_is_synchronized(PurpleBuddy *buddy)
{
	gboolean ret = purple_blist_node_get_bool(PURPLE_BLIST_NODE(buddy),
		GGP_ROSTER_SYNC_SETT);
	return ret;
}