Serveez是一个服务器框架

源代码在线查看: irc-event-5.c

软件大小: 614 K
上传用户: NJ_WK
关键词: Serveez 服务器
下载地址: 免注册下载 普通下载 VIP

相关代码

				/*				 * irc-event-5.c - IRC events -- User-based queries				 *				 * Copyright (C) 2000 Stefan Jahn 				 *				 * 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-5.c,v 1.12 2001/05/19 23:04:57 ela Exp $				 *				 */								#if HAVE_CONFIG_H				# include 				#endif								#if ENABLE_IRC_PROTO								#define _GNU_SOURCE				#include 				#include 								#ifdef __MINGW32__				# include 				#endif								#include 				#include "irc-core/irc-core.h"				#include "irc-proto.h"				#include "irc-event.h"								/*         Command: WHOWAS				 *      Parameters:  [ []]				 * Numeric Replies: ERR_NONICKNAMEGIVEN ERR_WASNOSUCHNICK				 *                  RPL_WHOWASUSER      RPL_WHOISSERVER				 *                  RPL_ENDOFWHOWAS				 */				int				irc_whowas_callback (svz_socket_t *sock, 						     irc_client_t *client, irc_request_t *request)				{				  irc_config_t *cfg = sock->cfg;				  irc_client_history_t *cl;				  char *nick, *server;				  int n, i, found;								  /* check if there is a nick given */				  if (request->paras < 1)				    {				      irc_printf (sock, ":%s %03d %s " ERR_NONICKNAMEGIVEN_TEXT "\n",						  cfg->host, ERR_NONICKNAMEGIVEN, client->nick);				    }								  nick = request->para[0];				  n = atoi (request->para[1]);								  /* is there a server para given ? */				  if (request->paras > 2)				    {				      server = request->para[2];				    }								  /* look through the history list */				  cl = NULL;				  i = 0;				  found = 0;				  while ((cl = irc_find_nick_history (cfg, cl, nick)) != NULL && 					 (i < n || n 				    {				      found = 1;				      irc_printf (sock, ":%s %03d %s " RPL_WHOWASUSER_TEXT "\n",						  cfg->host, RPL_WHOWASUSER, client->nick,						  cl->nick, cl->user, cl->host, cl->real);				      i++;				    }				  /* did you found a nick in the history ? */				  if (found)				    {				      irc_printf (sock, ":%s %03d %s " RPL_ENDOFWHOWAS_TEXT "\n",						  cfg->host, RPL_ENDOFWHOWAS, client->nick, nick);				    }				  else				    {				      irc_printf (sock, ":%s %03d %s " ERR_WASNOSUCHNICK_TEXT "\n",						  cfg->host, ERR_WASNOSUCHNICK, client->nick, nick);				    }								  return 0;				}								/*				 * Check if a certain client is visible to another.				 */				static int				irc_client_visible (irc_config_t *cfg,     /* current server config */						    irc_client_t *client,  /* who wants to know about */						    irc_client_t *rclient) /* this client */				{				  irc_channel_t *channel;				  int n;								  /* invisible ? */				  if (rclient->flag & UMODE_INVISIBLE)				    return 0;								  /* 				   * Visible, but not in a public (no secret or private) channel ? 				   * The client is also visible if they share a channel.				   */				  for (n = 0; n < rclient->channels; n++)				    {				      channel = rclient->channel[n];								      /* public channel ? */				      if (!(channel->flag & (MODE_SECRET | MODE_PRIVATE)))					return -1;				      else					{					  /* no, but do they share it ? */					  if (irc_client_in_channel (NULL, client, channel) != -1)					    return -1;					}				    }				  return -1;				}								/*				 * Send a user WHOIS reply.				 */				static void				irc_user_info (svz_socket_t *sock,   /* the socket for the client to send */					       irc_client_t *client, /* reply client */					       irc_client_t *cl)     /* info about this client */				{				  irc_config_t *cfg = sock->cfg;				  irc_channel_t *channel;				  svz_socket_t *xsock;				  char text[MAX_MSG_LEN];				  int n, i;								  if (!irc_client_visible (cfg, client, cl)) 				    return;								  irc_printf (sock, ":%s %03d %s " RPL_WHOISUSER_TEXT "\n",					      cfg->host, RPL_WHOISUSER, client->nick,					      cl->nick, cl->user, cl->host, cl->real);					  				  irc_printf (sock, ":%s %03d %s " RPL_WHOISSERVER_TEXT "\n",					      cfg->host, RPL_WHOISSERVER, client->nick,					      cl->nick, cl->server, cfg->info);					  				  /* operator ? */				  if (cl->flag & UMODE_OPERATOR)				    irc_printf (sock, ":%s %03d %s " RPL_WHOISOPERATOR_TEXT "\n",						cfg->host, RPL_WHOISOPERATOR, client->nick, cl->nick);					  				  /* idle seconds */				  xsock = cl->sock;				  irc_printf (sock, ":%s %03d %s " RPL_WHOISIDLE_TEXT "\n",					      cfg->host, RPL_WHOISIDLE, client->nick,					      cl->nick, time (NULL) - xsock->last_send, cl->since);								  /* build channel list */				  for (text[0] = 0, i = 0; i < cl->channels; i++)				    {				      channel = cl->channel[i];				      n = irc_client_in_channel (NULL, cl, channel);				      if (channel->cflag[n] & MODE_OPERATOR)					strcat (text, "@");				      else if (channel->cflag[n] & MODE_VOICE)					strcat (text, "+");				      strcat (text, cl->channel[i]->name);				      strcat (text, " ");				    }								  /* send channel list */				  irc_printf (sock, ":%s %03d %s " RPL_WHOISCHANNELS_TEXT "\n",					      cfg->host, RPL_WHOISCHANNELS, client->nick, cl->nick, text);				}								/*				 *         Command: WHOIS				 *      Parameters: [] [,[,...]]				 * Numeric Replies: ERR_NOSUCHSERVER   ERR_NONICKNAMEGIVEN				 *                  RPL_WHOISUSER      RPL_WHOISCHANNELS				 *                  RPL_WHOISCHANNELS  RPL_WHOISSERVER				 *                  RPL_AWAY           RPL_WHOISOPERATOR				 *                  RPL_WHOISIDLE      ERR_NOSUCHNICK				 *                  RPL_ENDOFWHOIS				 */				int				irc_whois_callback (svz_socket_t *sock, 						    irc_client_t *client, irc_request_t *request)				{				  irc_config_t *cfg = sock->cfg;				  irc_client_t **cl, *rclient;				  char *nick, *chan;				  int n;								  /* enough paras ? */				  if (irc_check_args (sock, client, cfg, request, 1))				    return 0;								  /* server Mask ? */				  if (irc_string_regex (cfg->host, request->para[0]))				    irc_parse_target (request, 1);								  /* go through all targets */				  for (n = 0; n < request->targets; n++)				    {				      nick = request->target[n].nick;				      chan = request->target[n].channel;								      /* nick Mask ? */				      if (strstr (nick, "*") || strstr (nick, "?"))					{					  if ((cl = irc_regex_nick (cfg, nick)) != NULL)					    {					      for (n = 0; cl[n]; n++)						{						  /* is this client away ? */						  if (irc_client_absent (cl[n], client))						    continue;						  irc_user_info (sock, client, cl[n]);						}					      svz_free (cl);					    }					}				      /* is target a plain nick ? */				      else if ((rclient = irc_find_nick (cfg, nick)) != NULL)					{					  /* is this client away ? */					  if (irc_client_absent (rclient, client)) 					    continue;					  irc_user_info (sock, client, rclient);					}								      irc_printf (sock, ":%s %03d %s " RPL_ENDOFWHOIS_TEXT "\n",						  cfg->host, RPL_ENDOFWHOIS, client->nick, nick);				    }				  return 0;				}								/*				 * Send a single WHO reply.				 */				static void				irc_client_info (svz_socket_t *sock,     /* this client's socket */						 irc_client_t *client,   /* this client */						 irc_client_t *cl,       /* reply this client's info */						 irc_channel_t *channel) /* channel 'cl' is in */				{				  irc_config_t *cfg = sock->cfg;				  char text[MAX_MSG_LEN];				  char *flag = "";				  int n;								  n = irc_client_in_channel (NULL, cl, channel);				  if (channel->cflag[n] & MODE_OPERATOR)				    flag = "@";				  else if (channel->cflag[n] & MODE_VOICE)				    flag = "+";								  sprintf (text, RPL_WHOREPLY_TEXT,					   channel->name, cl->user, cl->host, cl->server, cl->nick, 					   cl->flag & UMODE_AWAY ? 'G' : 'H',					   cl->flag & UMODE_OPERATOR ? "*" : "", flag, 0, cl->real);				  				  irc_printf (sock, ":%s %03d %s %s\n",					      cfg->host, RPL_WHOREPLY, client->nick, text);				}								/* 				 *         Command: WHO				 *      Parameters: [ []]				 * Numeric Replies: ERR_NOSUCHSERVER				 *                  RPL_WHOREPLY     RPL_ENDOFWHO				 */				int				irc_who_callback (svz_socket_t *sock, 						  irc_client_t *client, irc_request_t *request)				{				  irc_config_t *cfg = sock->cfg;				  irc_client_t **cl, *xcl;				  irc_channel_t **channel, *xch;				  char *name;				  int n, i;								  if (!request->paras)				    name = "*";				  else				    name = request->para[0];								  /* find all Matching channels */				  if ((channel = irc_regex_channel (cfg, name)) != NULL)				    {				      for (i = 0; channel[i]; i++)					{					  for (n = 0; n < channel[i]->clients; n++)					    {					      xcl = channel[i]->client[n];					      irc_client_info (sock, client, xcl, channel[i]);					    }					}				      irc_printf (sock, ":%s %03d %s " RPL_ENDOFWHO_TEXT "\n",						  cfg->host, RPL_ENDOFWHO, client->nick, name);				      svz_free (channel);				      return 0;				    }				  				  /* find all Matching nicks */				  if ((cl = irc_regex_nick (cfg, name)) != NULL)				    {				      for (i = 0; cl[i]; i++)					{					  for (n = 0; n < cl[i]->channels; n++)					    {					      xch = cl[i]->channel[n];					      irc_client_info (sock, client, cl[i], xch);					    }					}				      irc_printf (sock, ":%s %03d %s " RPL_ENDOFWHO_TEXT "\n",						  cfg->host, RPL_ENDOFWHO, client->nick, name);				      svz_free (cl);				    }								  return 0;				}								#else /* not ENABLE_IRC_PROTO */								int irc_event_5_dummy; /* Shut up compiler warnings. */								#endif /* not ENABLE_IRC_PROTO */							

相关资源