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

📄 irc-event-2.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Set or unset a channel flag. */static intirc_channel_flag (irc_client_t *client,   /* client changing the flag */		  svz_socket_t *sock,     /* this clients connection */		  int cflag,              /* this clients flags */		  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 n;  unsigned l;  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;  if (set)    channel->flag |= flag;  else    channel->flag &= ~flag;  /* 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\n",		  client->nick, client->user, client->host, channel->name, 		  set ? '+' : '-', Mode);    }  return 0;}/* * Destroy and svz_free() a given ban entry. */voidirc_destroy_ban (irc_ban_t *ban){  if (ban->nick)    svz_free (ban->nick);  if (ban->user)    svz_free (ban->user);  svz_free (ban->host);  svz_free (ban->by);  svz_free (ban);}/* * This function creates a ban entry. */static irc_ban_t *irc_create_ban (irc_client_t *client, char *request, int len){  irc_ban_t *ban;  char *p, *tmp;  int n, size = 0;  /* reserve and initialize buffer space */  ban = svz_malloc (sizeof (irc_ban_t));  memset (ban, 0, sizeof (irc_ban_t));  tmp = svz_malloc (MAX_MSG_LEN);  memset (tmp, 0, MAX_MSG_LEN);  ban->since = time (NULL);  sprintf (tmp, "%s!%s@%s", client->nick, client->user, client->host);  ban->by = svz_strdup (tmp);  p = request;  n = 0;  while (size < len && *p != '!' && *p != '@')    {      tmp[n++] = *p++;      size++;    }  /* nick has been parsed */  if (*p == '!')    {      tmp[n] = '\0';      ban->nick = svz_strdup (tmp);      p++;      size++;      n = 0;      while (size < len && *p != '@')	{	  tmp[n++] = *p++;	  size++;	}      /* user parsed */      if (*p == '@')	{	  tmp[n] = '\0';	  ban->user = svz_strdup (tmp);	  p++;	  size++;	  n = 0;	  while (size < len)	    {	      tmp[n++] = *p++;	      size++;	    }	  tmp[n] = '\0';	  ban->host = svz_strdup (tmp);	}    }  /* here user parsed without nick */  else if (*p == '@')    {      tmp[n] = '\0';      ban->user = svz_strdup (tmp);      p++;      size++;      n = 0;      while (size < len)	{	  tmp[n++] = *p++;	  size++;	}      tmp[n] = '\0';      ban->host = svz_strdup (tmp);    }  /* parsed just a host without user and nick */  else    {      tmp[n] = '\0';      ban->host = svz_strdup (tmp);    }  svz_free (tmp);  return ban;}/* * Set or unset a channel specific flag to a given argument. */static intirc_channel_arg (irc_client_t *client,   /* client changing the flag */		 svz_socket_t *sock,     /* this clients connection */		 int cflag,              /* this clients flags */		 irc_channel_t *channel, /* mode change for this channel */		 int flag,               /* flag to be set / unset */		 char *arg,              /* the arg */		 char set)               /* set / unset */{  irc_config_t *cfg = sock->cfg;  irc_client_t *cl;  svz_socket_t *xsock;  int n;  unsigned l;  char *Modes = CHANNEL_MODES;  char Mode = ' ';  /* enough paras ? */  if (set && arg[0] == 0)    {      irc_printf (sock, ":%s %03d %s " ERR_NEEDMOREPARAMS_TEXT "\n",		  cfg->host, ERR_NEEDMOREPARAMS, client->nick, "MODE");      return 0;    }  /* 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;  /* set / unset the actual flag */  if (set)     {      switch (flag)	{	case MODE_KEY:	  /* key is set before... */	  if (channel->flag & flag)	    {	      irc_printf (sock, ":%s %03d %s " ERR_KEYSET_TEXT "\n",			  cfg->host, ERR_KEYSET, client->nick, channel->name);	      return 0;	    }	  if (channel->key)	    svz_free (channel->key);	  channel->key = svz_strdup (arg);	  channel->flag |= flag;	  break;	case MODE_ULIMIT:	  channel->users = atoi (arg);	  channel->flag |= flag;	  break;	case MODE_BAN:	  n = channel->bans;	  channel->ban = svz_realloc (channel->ban, 				      sizeof (irc_ban_t *) * (n + 1));	  channel->ban[n] = irc_create_ban (client, arg, strlen (arg));	  channel->bans++;	  break;	}    }  /* unset flag */  else    {      /* look if you can delete a ban */      if (flag & MODE_BAN)	{	  for (n = 0; n < channel->bans; n++)	    {	      if (!strcmp (arg, irc_ban_string (channel->ban[n])))		{		  irc_destroy_ban (channel->ban[n]);		  if (--channel->bans != 0)		    {		      channel->ban[n] = channel->ban[channel->bans];		      channel->ban = svz_realloc (channel->ban,						  sizeof (irc_ban_t *) *						  channel->bans);		    }		  else		    {		      svz_free (channel->ban);		      channel->ban = NULL;		    }		  break;		}	    }	}      else	{	  channel->flag &= ~flag;	}    }  /* 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%s\n",		  client->nick, client->user, client->host,		  channel->name, 		  set ? '+' : '-', Mode, set ? " " : "", set ? arg : "");    }  return 0;}/* * Get a mode string by user modes. */char *irc_client_flag_string (irc_client_t *client){  static char Mode[MAX_MSG_LEN];  static char *Modes = USER_MODES;  unsigned n, i;  memset (Mode, 0, MAX_MSG_LEN);  Mode[0] = '+';  for (i = n = 0; n < strlen (Modes); n++)    {      if (client->flag & (1 << n))	Mode[++i] = Modes[n];    }  return Mode;}/* * Get a flag string by a channels modes. */char *irc_channel_flag_string (irc_channel_t *channel){  static char Mode[MAX_MODE_LEN];  static char arg[MAX_MODE_LEN];  static char *Modes = CHANNEL_MODES;  unsigned n, i;  memset (Mode, 0, MAX_MODE_LEN);  Mode[0] = '+';  /* go through all possible Mode flags (characters) */  for (i = n = 0; n < strlen (Modes); n++)    {      if (channel->flag & (1 << n))	Mode[++i] = Modes[n];    }  /* add flag para if necessary */  if (channel->flag & MODE_ULIMIT)    {      sprintf (arg, " %d", channel->users);      strcat (Mode, arg);    }  return Mode;}/*  *         Command: MODE *   Channel modes: *      Parameters: <channel> {[+|-]|o|p|s|i|t|n|b|v} [<limit>] [<user>] *                  [<ban mask>] *      User modes: *      Parameters: <nickname> {[+|-]|i|w|s|o} * Numeric Replies: ERR_NEEDMOREPARAMS   RPL_CHANNELMODEIS *                  ERR_CHANOPRIVSNEEDED ERR_NOSUCHNICK *                  ERR_NOTONCHANNEL     ERR_KEYSET *                  RPL_BANLIST          RPL_ENDOFBANLIST *                  ERR_UNKNOWNMODE      ERR_NOSUCHCHANNEL *                  ERR_USERSDONTMATCH   RPL_UMODEIS *                  ERR_UMODEUNKNOWNFLAG */#define FLAG_SET   1#define FLAG_UNSET 0intirc_mode_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;  char *chan, *nick, *req;  char flag;  int cflag;  int n, para;  /* enough paras, but at least one ? */  if (irc_check_args (sock, client, cfg, request, 1))    return 0;  chan = nick = request->para[0];  /* is target channel ? */  if ((channel = irc_find_channel (cfg, chan)) != NULL)    {      /* this is a request only ? */      if (request->paras < 2)	{	  irc_printf (sock, ":%s %03d %s " RPL_CHANNELMODEIS_TEXT "\n", 		      cfg->host, RPL_CHANNELMODEIS, client->nick, 		      channel->name, irc_channel_flag_string (channel));	  return 0;	}      /* find client in the channel first */      if ((n = irc_client_in_channel (sock, client, channel)) == -1)	return 0;      cflag = channel->cflag[n];      /* go through all the Mode string and current arg is # 2 */      req = request->para[1];       para = 2;      flag = FLAG_SET;      while (*req)	{	  switch (*req)	    {	    case '+':	      flag = FLAG_SET;	      break;	    case '-':	      flag = FLAG_UNSET;	      break;	      /* set or get ban Mask */	    case 'b':	      /* if no args, then reply the bans */	      if (para >= request->paras)		{		  for (n = 0; n < channel->bans; n++)		    {		      irc_printf (sock, ":%s %03d %s " RPL_BANLIST_TEXT "\n", 				  cfg->host,				  RPL_BANLIST, client->nick, channel->name,				  irc_ban_string (channel->ban[n]),				  channel->ban[n]->by,				  channel->ban[n]->since);		    }		  irc_printf (sock, ":%s %03d %s " RPL_ENDOFBANLIST_TEXT "\n", 			      cfg->host, RPL_ENDOFBANLIST, client->nick, 			      channel->name);		}	      /* yes there are args, so set or unset the ban */	      else		{		  irc_channel_arg (client, sock, cflag, channel, MODE_BAN, 				   request->para[para], flag);		  para++;		}	      break;	      /* channel operator flag */	    case 'o':	      irc_client_flag (client, sock, cflag, request->para[para],			       channel, MODE_OPERATOR, flag);	      para++;	      break;	      /* voice flag for this channel */	    case 'v':	      irc_client_flag (client, sock, cflag, request->para[para],			       channel, MODE_VOICE, flag);	      para++;	      break;	      /* private flag of this channel */	    case 'p':	      irc_channel_flag (client, sock, cflag, 				channel, MODE_PRIVATE, flag);	      break;	      /* secret flag */	    case 's':	      irc_channel_flag (client, sock, cflag, 				channel, MODE_SECRET, flag);	      break;	      /* invite only flag */	    case 'i':	      irc_channel_flag (client, sock, cflag, 				channel, MODE_INVITE, flag);	      break;	      /* topic setable by operator only */	    case 't':	      irc_channel_flag (client, sock, cflag, 				channel, MODE_TOPIC, flag);	      break;	      /* no Message of outside flag */	    case 'n':	      irc_channel_flag (client, sock, cflag, 				channel, MODE_MESSAGE, flag);	      break;	      /* Moderated channel */	    case 'm':	      irc_channel_flag (client, sock, cflag, 				channel, MODE_MODERATE, flag);	      break;	      /* set the users limitation flag (taking one arg) */	    case 'l':	      irc_channel_arg (client, sock, cflag, channel, MODE_ULIMIT, 			       request->para[para], flag);	      if (flag)		para++;	      break;	      /* set a key for this channel */	    case 'k':	      irc_channel_arg (client, sock, cflag, channel, MODE_KEY, 			       request->para[para], flag);	      if (flag)		para++;	      break;	      /* unknown Mode flag */	    default:	      irc_printf (sock, ":%s %03d %s " ERR_UNKNOWNMODE_TEXT "\n",

⌨️ 快捷键说明

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