⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irc-event-2.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * irc-event-2.c - IRC events -- Channel operations * * Copyright (C) 2000 Stefan Jahn <stefan@lkcc.org> * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. *  * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. *  * You should have received a copy of the GNU General Public License * along with this package; see the file COPYING.  If not, write to * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA.   * * $Id: irc-event-2.c,v 1.16 2001/05/19 23:04:57 ela Exp $ * */#if HAVE_CONFIG_H# include <config.h>#endif#if ENABLE_IRC_PROTO#define _GNU_SOURCE#include <string.h>#include <stdlib.h>#ifdef __MINGW32__# include <winsock2.h>#endif#include <libserveez.h>#include "irc-core/irc-core.h"#include "irc-proto.h"#include "irc-event.h"/* *         Command: PART *      Parameters: <channel>{,<channel>} * Numeric Replies: ERR_NEEDMOREPARAMS ERR_NOSUCHCHANNEL *                  ERR_NOTONCHANNEL */intirc_part_callback (svz_socket_t *sock, 		   irc_client_t *client, irc_request_t *request){  irc_config_t *cfg = sock->cfg;  irc_client_t *cl;  irc_channel_t *channel;  svz_socket_t *xsock;  int n;  /* do you have enough paras ? */  if (irc_check_args (sock, client, cfg, request, 1))    return 0;  /* go through all targets in the first para */  for (n = 0; n < request->targets; n++)    {      /* does the channel exist ? */      if ((channel = irc_find_channel (cfg, request->target[n].channel)) == 	  NULL)	{	  irc_printf (sock, ":%s %03d %s " ERR_NOSUCHCHANNEL_TEXT "\n",		      cfg->host, ERR_NOSUCHCHANNEL, client->nick,		      request->target[n].channel);	  return 0;	}      /* yes, look if the client is in it */      if (irc_client_in_channel (sock, client, channel) == -1)	return 0;      /* send back the PART to all channel clients */      for (n = 0; n < channel->clients; n++)	{	  cl = channel->client[n];	  xsock = cl->sock;	  irc_printf (xsock, ":%s!%s@%s PART %s :%s\n",		      client->nick, client->user, client->host, 		      channel->name, request->para[1]);	}            irc_leave_channel (cfg, client, channel);    }  return 0;}/* * This function returns no zero value if a given client matches * a given channel ban entry. */static intirc_client_banned (irc_client_t *client, irc_ban_t *ban){  /* does the nick Match ? */  if (!irc_string_regex (client->nick, ban->nick))    return 0;  /* does the user Match ? */  if (!irc_string_regex (client->user, ban->user))    return 0;  /* does the host Match ? */  if (!irc_string_regex (client->host, ban->host))    return 0;  return -1;}/* * Send the channel topic to an IRC client. */static voidirc_channel_topic (svz_socket_t *sock,		   irc_client_t *client, irc_channel_t *channel){  irc_config_t *cfg = sock->cfg;  /* send topic if there is one */  if (channel->topic)    {      irc_printf (sock, ":%s %03d %s " RPL_TOPIC_TEXT "\n",		  cfg->host, RPL_TOPIC, client->nick,		  channel->name, channel->topic);      /* send topic date and nick (this is not part of the RFC) */      irc_printf (sock, ":%s %03d %s " RPL_TOPICSET_TEXT "\n",		  cfg->host, RPL_TOPICSET, client->nick, channel->name, 		  channel->topic_by, channel->topic_since);    }  /* no topic set yet */  else    {      irc_printf (sock, ":%s %03d %s " RPL_NOTOPIC_TEXT "\n",		  cfg->host, RPL_NOTOPIC, client->nick, channel->name);    }}/* * Send a channels users to a specified client. */static voidirc_channel_users (svz_socket_t *sock,		   irc_client_t *client, 		   irc_channel_t *channel){  irc_config_t *cfg = sock->cfg;  char nicklist[MAX_MSG_LEN];  irc_client_t *cl;  int n;  /* prebuild the nicklist */  for (nicklist[0] = 0, n = 0; n < channel->clients; n++)    {      /* check if the client is visible or not */      cl = channel->client[n];      if (!(cl->flag & UMODE_INVISIBLE) &&	  irc_client_in_channel (NULL, client, channel) != -1)	{	  if (channel->cflag[n] & MODE_OPERATOR) 	    strcat (nicklist, "@");	  else if (channel->cflag[n] & MODE_VOICE) 	    strcat (nicklist, "+");	  strcat (nicklist, channel->client[n]->nick);	  strcat (nicklist, " ");	}    }  /* send channel info */  irc_printf (sock, ":%s %03d %s " RPL_NAMREPLY_TEXT "\n",	      cfg->host, RPL_NAMREPLY, client->nick,	      channel->flag & (MODE_PRIVATE | MODE_SECRET) ? '*' : '=',	      channel->name, nicklist);}/* *         Command: JOIN *      Parameters: <channel>{,<channel>} [<key>{,<key>}] * Numeric Replies: ERR_NEEDMOREPARAMS ERR_BANNEDFROMCHAN *                  ERR_INVITEONLYCHAN ERR_BADCHANNELKEY *                  ERR_CHANNELISFULL  ERR_BADCHANMASK *                  ERR_NOSUCHCHANNEL  ERR_TOOMANYCHANNELS *                  RPL_TOPIC */intirc_join_callback (svz_socket_t *sock, 		   irc_client_t *client, irc_request_t *request){  irc_config_t *cfg = sock->cfg;  irc_client_t *cl;  irc_channel_t *channel;  svz_socket_t *xsock;  char *chan;  int n, i;  /* do you have enough paras ? */  if (irc_check_args (sock, client, cfg, request, 1))    return 0;  /* go through all targets in the first para */  for (n = 0; n < request->targets; n++)    {      chan = request->target[n].channel;      /* does the channel already exists ? */      if ((channel = irc_find_channel (cfg, chan)) != NULL)	{	  /* is a key set for this channel and is the given one ok ? */	  if (channel->flag & MODE_KEY &&	      strcmp (irc_get_target (request->para[1], n), channel->key))	    {	      irc_printf (sock, 			  ":%s %03d %s " ERR_BADCHANNELKEY_TEXT "\n",			  cfg->host, ERR_BADCHANNELKEY, client->nick,			  channel->name);	      return 0;	    }	  /* invite only ? */	  if (channel->flag & MODE_INVITE)	    {	      /* find the nick in the invite list of the channel */	      for (i = 0; i < channel->invites; i++)		if (channel->invite[i] == client)		  break;	      /* not in this list ! */	      if (i == channel->invites)		{		  irc_printf (sock, 			      ":%s %03d %s " ERR_INVITEONLYCHAN_TEXT "\n",			      cfg->host, ERR_INVITEONLYCHAN, client->nick,			      channel->name);		  return 0;		}	      /* clear this invite entry */	      else		{		  if (--channel->invites != 0)		    {		      channel->invite[i] = channel->invite[channel->invites];		      channel->invite = svz_realloc (channel->invite,						     sizeof (irc_client_t *) *						     channel->invites);		    }		  else		    {		      svz_free (channel->invite);		      channel->invite = NULL;		    }		}	    }	  /* is channel full ? */	  if (channel->flag & MODE_ULIMIT && 	      channel->clients >= channel->users)	    {	      irc_printf (sock, 			  ":%s %03d %s " ERR_CHANNELISFULL_TEXT "\n",			  cfg->host, ERR_CHANNELISFULL, client->nick,			  channel->name);	      return 0;	    }	  /* is this client banned ? */	  for (i = 0; i < channel->bans; i++)	    {	      if (irc_client_banned (client, channel->ban[i]))		{		  irc_printf (sock, 			      ":%s %03d %s " ERR_BANNEDFROMCHAN_TEXT "\n",			      cfg->host, ERR_BANNEDFROMCHAN, client->nick,			      channel->name);		  return 0;		}	    }	}      /* done, do not deny this channel ! */      irc_join_channel (cfg, client, chan);      if ((channel = irc_find_channel (cfg, chan)) == NULL)	continue;      /* send back the JOIN to all channel clients */      for (i = 0; i < channel->clients; i++)	{	  cl = channel->client[i];	  xsock = cl->sock;	  irc_printf (xsock, ":%s!%s@%s JOIN :%s\n",		      client->nick, client->user, client->host, chan);	}      /* send topic */      irc_channel_topic (sock, client, channel);      /* send creation date and nick (this is not part of the RFC) */      irc_printf (sock, ":%s %03d %s " RPL_CHANCREATED_TEXT "\n",		  cfg->host, RPL_CHANCREATED, client->nick,		  channel->name, channel->since);      /* send nick list */      irc_channel_users (sock, client, channel);      irc_printf (sock, ":%s %03d %s " RPL_ENDOFNAMES_TEXT "\n",		  cfg->host, RPL_ENDOFNAMES, client->nick, channel->name);    }    return 0;}/* * Create a ban mask string by a channels ban entry. */static char *irc_ban_string (irc_ban_t *ban){  static char text[MAX_MSG_LEN] = "";  if (ban->nick)    {      strcat (text, ban->nick);      strcat (text, "!");    }  if (ban->user)    {      strcat (text, ban->user);      strcat (text, "@");    }  strcat (text, ban->host);    return text;}/* * Check if a given client is channel operator in its channel and * send an error about this if necessary. The function returns a non * zero value if the client is an operator otherwise zero. */static intirc_client_oper (svz_socket_t *sock, 		 irc_client_t *client, irc_channel_t *channel, int flag){  irc_config_t *cfg = sock->cfg;  if (!(flag & MODE_OPERATOR))    {      irc_printf (sock, ":%s %03d %s " ERR_CHANOPRIVSNEEDED_TEXT "\n",		  cfg->host, ERR_CHANOPRIVSNEEDED, 		  client->nick, channel->name);      return 0;    }  return -1;}/* * Set or unset a channel flag for a user in the channel. */static intirc_client_flag (irc_client_t *client,   /* client changing the flag */		 svz_socket_t *sock,     /* this clients connection */		 int cflag,              /* this clients flags */		 char *nick,             /* the nick the mode is for */		 irc_channel_t *channel, /* mode change for this channel */		 int flag,               /* flag to be set / unset */		 char set)               /* set / unset */{  irc_client_t *cl;  svz_socket_t *xsock;  int i, n;  unsigned l;  static char *Modes = CHANNEL_MODES;  char Mode = ' ';  /* find Mode character */  for (l = 0; l < strlen (Modes); l++)    if (flag & (1 << l))      {	Mode = Modes[l];	break;      }    if (!irc_client_oper (sock, client, channel, cflag))    return 0;  /* find nick in channel */  for (i = 0; i < channel->clients; i++)    if (!strcmp (channel->client[i]->nick, nick))      {	if (set)	  channel->cflag[i] |= flag;	else	  channel->cflag[i] &= ~flag;	break;      }  /* no such nick in channel ! */  if (i == channel->clients)    {      irc_printf (sock, "%03d " ERR_NOSUCHNICK_TEXT "\n",		  ERR_NOSUCHNICK, nick);      return 0;    }  /* propagate Mode change to channel users */  for (n = 0; n < channel->clients; n++)    {      cl = channel->client[n];      xsock = cl->sock;      irc_printf (xsock, ":%s!%s@%s MODE %s %c%c %s\n",		  client->nick, client->user, client->host, channel->name, 		  set ? '+' : '-', Mode, channel->client[i]->nick);    }  return 0;}/* * Set or unset a flag for a user by itself. */static intirc_user_flag (irc_client_t *client,   /* client changing the flag */	       svz_socket_t *sock,     /* this clients connection */	       int flag,               /* flag to be set / unset */	       char set)               /* set / unset */{  irc_config_t *cfg = sock->cfg;  unsigned l;  static char *Modes = USER_MODES;  char Mode = ' ';  /* find Mode character */  for (l = 0; l < strlen (Modes); l++)    if (flag & (1 << l))      {	Mode = Modes[l];	break;      }    /* is this client able to change the flag */  if (set)    {      if (flag & UMODE_INVISIBLE && !(client->flag & UMODE_INVISIBLE))	cfg->invisibles++;            /* this flag cannot be set by anyone ! */      if (!(flag & UMODE_OPERATOR)) 	client->flag |= flag;      else	return 0;    }  else    {      if (flag & UMODE_INVISIBLE && client->flag & UMODE_INVISIBLE)	cfg->invisibles--;      client->flag &= ~flag;    }  /* propagate Mode change to this users */  irc_printf (sock, ":%s!%s@%s MODE %s %c%c\n",	      client->nick, client->user, client->host,	      client->nick, set ? '+' : '-', Mode);    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -