Пример #1
0
/**
 * Add entries to channel invite, ban and exception lists.
 *
 * @param what Can be 'I' for invite, 'b' for ban, and 'e' for exception list.
 * @param Prefix The originator of the command.
 * @param Client The sender of the command.
 * @param Channel The channel of which the list should be modified.
 * @param Pattern The pattern to add to the list.
 * @return CONNECTED or DISCONNECTED.
 */
static bool
Add_To_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel,
	    const char *Pattern)
{
	char mask[MASK_LEN];
	struct list_head *list = NULL;
	long int current_count;

	assert(Client != NULL);
	assert(Channel != NULL);
	assert(Pattern != NULL);
	assert(what == 'I' || what == 'b' || what == 'e');

	Lists_MakeMask(Pattern, mask, sizeof(mask));
	current_count = Lists_Count(Channel_GetListInvites(Channel))
			+ Lists_Count(Channel_GetListExcepts(Channel))
			+ Lists_Count(Channel_GetListBans(Channel));

	switch(what) {
		case 'I':
			list = Channel_GetListInvites(Channel);
			break;
		case 'b':
			list = Channel_GetListBans(Channel);
			break;
		case 'e':
			list = Channel_GetListExcepts(Channel);
			break;
	}

	if (Lists_CheckDupeMask(list, mask))
		return CONNECTED;
	if (Client_Type(Client) == CLIENT_USER &&
	    current_count >= MAX_HNDL_CHANNEL_LISTS)
		return IRC_WriteErrClient(Client, ERR_LISTFULL_MSG,
					  Client_ID(Client),
					  Channel_Name(Channel), mask,
					  MAX_HNDL_CHANNEL_LISTS);

	switch (what) {
		case 'I':
			if (!Channel_AddInvite(Channel, mask, false, Client_ID(Client)))
				return CONNECTED;
			break;
		case 'b':
			if (!Channel_AddBan(Channel, mask, Client_ID(Client)))
				return CONNECTED;
			break;
		case 'e':
			if (!Channel_AddExcept(Channel, mask, Client_ID(Client)))
				return CONNECTED;
			break;
	}
	return Send_ListChange(true, what, Prefix, Client, Channel, mask);
}
Пример #2
0
/**
 * Delete entries from channel invite, ban and exception lists.
 *
 * @param what Can be 'I' for invite, 'b' for ban, and 'e' for exception list.
 * @param Prefix The originator of the command.
 * @param Client The sender of the command.
 * @param Channel The channel of which the list should be modified.
 * @param Pattern The pattern to add to the list.
 * @return CONNECTED or DISCONNECTED.
 */
static bool
Del_From_List(char what, CLIENT *Prefix, CLIENT *Client, CHANNEL *Channel,
	      const char *Pattern)
{
	char mask[MASK_LEN];
	struct list_head *list = NULL;

	assert(Client != NULL);
	assert(Channel != NULL);
	assert(Pattern != NULL);
	assert(what == 'I' || what == 'b' || what == 'e');

	Lists_MakeMask(Pattern, mask, sizeof(mask));

	switch (what) {
		case 'I':
			list = Channel_GetListInvites(Channel);
			break;
		case 'b':
			list = Channel_GetListBans(Channel);
			break;
		case 'e':
			list = Channel_GetListExcepts(Channel);
			break;
	}

	if (!Lists_CheckDupeMask(list, mask))
		return CONNECTED;
	Lists_Del(list, mask);

	return Send_ListChange(false, what, Prefix, Client, Channel, mask);
}
Пример #3
0
GLOBAL bool
Channel_AddExcept(CHANNEL *c, const char *mask, const char *who )
{
	struct list_head *h = Channel_GetListExcepts(c);
	LogDebug("Adding \"%s\" to \"%s\" exception list", mask, Channel_Name(c));
	return Lists_Add(h, mask, time(NULL), who, false);
}
Пример #4
0
/**
 * Synchronize invite, ban, except, and G-Line lists between servers.
 *
 * @param Client New server.
 * @return CONNECTED or DISCONNECTED.
 */
static bool
Synchronize_Lists(CLIENT * Client)
{
	CHANNEL *c;
	struct list_head *head;
	struct list_elem *elem;
	time_t t;

	assert(Client != NULL);

	/* g-lines */
	head = Class_GetList(CLASS_GLINE);
	elem = Lists_GetFirst(head);
	while (elem) {
		t = Lists_GetValidity(elem) - time(NULL);
		if (!IRC_WriteStrClient(Client, "GLINE %s %ld :%s",
					Lists_GetMask(elem),
					t > 0 ? (long)t : 0,
					Lists_GetReason(elem)))
			return DISCONNECTED;
		elem = Lists_GetNext(elem);
	}

	c = Channel_First();
	while (c) {
		if (!Send_List(Client, c, Channel_GetListExcepts(c), 'e'))
			return DISCONNECTED;
		if (!Send_List(Client, c, Channel_GetListBans(c), 'b'))
			return DISCONNECTED;
		if (!Send_List(Client, c, Channel_GetListInvites(c), 'I'))
			return DISCONNECTED;
		c = Channel_Next(c);
	}
	return CONNECTED;
}
Пример #5
0
GLOBAL bool
Channel_ShowExcepts( CLIENT *Client, CHANNEL *Channel )
{
	struct list_head *h;

	assert( Channel != NULL );

	h = Channel_GetListExcepts(Channel);
	return ShowChannelList(h, Client, Channel, RPL_EXCEPTLIST_MSG,
			       RPL_ENDOFEXCEPTLIST_MSG);
}
Пример #6
0
/**
 * Check weather a local client is allowed to join an already existing
 * channel or not.
 *
 * @param Client	Client that sent the JOIN command
 * @param chan		Channel to check
 * @param channame	Name of the channel
 * @param key		Provided channel key (or NULL)
 * @returns		true if client is allowed to join, false otherwise
 */
static bool
join_allowed(CLIENT *Client, CHANNEL *chan, const char *channame,
	     const char *key)
{
	bool is_invited, is_banned, is_exception;

	/* Allow IRC operators to overwrite channel limits */
	if (Client_HasMode(Client, 'o'))
		return true;

	is_banned = Lists_Check(Channel_GetListBans(chan), Client);
	is_exception = Lists_Check(Channel_GetListExcepts(chan), Client);
	is_invited = Lists_Check(Channel_GetListInvites(chan), Client);

	if (is_banned && !is_invited && !is_exception) {
		/* Client is banned from channel (and not on invite list) */
		IRC_WriteErrClient(Client, ERR_BANNEDFROMCHAN_MSG,
				   Client_ID(Client), channame);
		return false;
	}

	if (Channel_HasMode(chan, 'i') && !is_invited) {
		/* Channel is "invite-only" and client is not on invite list */
		IRC_WriteErrClient(Client, ERR_INVITEONLYCHAN_MSG,
				   Client_ID(Client), channame);
		return false;
	}

	if (!Channel_CheckKey(chan, Client, key ? key : "")) {
		/* Channel is protected by a channel key and the client
		 * didn't specify the correct one */
		IRC_WriteErrClient(Client, ERR_BADCHANNELKEY_MSG,
				   Client_ID(Client), channame);
		return false;
	}

	if (Channel_HasMode(chan, 'l') &&
	    (Channel_MaxUsers(chan) <= Channel_MemberCount(chan))) {
		/* There are more clints joined to this channel than allowed */
		IRC_WriteErrClient(Client, ERR_CHANNELISFULL_MSG,
				   Client_ID(Client), channame);
		return false;
	}

	if (Channel_HasMode(chan, 'z') && !Conn_UsesSSL(Client_Conn(Client))) {
		/* Only "secure" clients are allowed, but clients doesn't
		 * use SSL encryption */
		IRC_WriteErrClient(Client, ERR_SECURECHANNEL_MSG,
				   Client_ID(Client), channame);
		return false;
	}

	if (Channel_HasMode(chan, 'O') && !Client_HasMode(Client, 'o')) {
		/* Only IRC operators are allowed! */
		IRC_WriteErrClient(Client, ERR_OPONLYCHANNEL_MSG,
				   Client_ID(Client), channame);
		return false;
	}

	if (Channel_HasMode(chan, 'R') && !Client_HasMode(Client, 'R')) {
		/* Only registered users are allowed! */
		IRC_WriteErrClient(Client, ERR_REGONLYCHANNEL_MSG,
				   Client_ID(Client), channame);
		return false;
	}

	return true;
} /* join_allowed */