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

📄 irc-proto.c

📁 Serveez是一个服务器框架
💻 C
📖 第 1 页 / 共 2 页
字号:
  /* go through all channels */  while (client->channels)    {      channel = client->channel[0];      /* tell all clients in the channel about disconnecting */      for (i = 0; i < channel->clients; i++)	{	  if (channel->client[i] == client)	    continue;	  	  cl = channel->client[i];	  xsock = cl->sock;	  irc_printf (xsock, ":%s!%s@%s QUIT :%s\n",		      client->nick, client->user, client->host, reason);	}	        /* delete this client of channel */      irc_leave_channel (cfg, client, channel);    }  /* send last error Message */  sock->flags &= ~SOCK_FLAG_KILLED;  irc_printf (sock, "ERROR :" IRC_CLOSING_LINK "\n", client->host, reason);  sock->flags |= SOCK_FLAG_KILLED;  /* delete this client */  irc_delete_client (cfg, client);  sock->data = NULL;  return 0;}/* * This function is the default callback if the connection of * an IRC client gets lost. */intirc_disconnect (svz_socket_t *sock){  irc_config_t *cfg = sock->cfg;  irc_client_t *client = sock->data;    /* is it a valid IRC connection ? */  if (client)    {      irc_leave_all_channels (cfg, client, IRC_CONNECTION_LOST);    }  return 0;}/* * This is the idle callback for serveez. Here the IRC server could * send a PING to a IRC client. */intirc_idle (svz_socket_t *sock){  irc_config_t *cfg = sock->cfg;  irc_client_t *client = sock->data;  if (!client->registered)    {      if (irc_register_client (sock, client, cfg))	return -1;      sock->idle_counter = 1;      return 0;    }  /*    * Shutdown this connection if the client did not respond   * within a certain period of time.   */  if (client->ping > 0)    {      return -1;    }  /*   * Ping a client connection if necessary.   */  if ((time (NULL) - sock->last_recv) >= IRC_PING_INTERVAL)    {      irc_printf (sock, "PING %s\n", cfg->host);      client->ping++;    }  sock->idle_counter = IRC_PING_INTERVAL;  return 0;}/* * This structures field contains all the callback routines necessary * to react like an IRC server. The actual routines are defined in the * irc-event.h and implemented in the irc-event-?.c files. */irc_callback_t irc_callback[] ={  { 0, "OPER",     irc_oper_callback     },  { 0, "INFO",     irc_info_callback     },  { 0, "KILL",     irc_kill_callback     },  { 0, "ERROR",    irc_error_callback    },  { 0, "WHOWAS",   irc_whowas_callback   },  { 0, "ADMIN",    irc_admin_callback    },  { 0, "TIME",     irc_time_callback     },  { 0, "LUSERS",   irc_lusers_callback   },  { 0, "STATS",    irc_stats_callback    },  { 0, "PING",     irc_ping_callback     },  { 0, "PONG",     irc_pong_callback     },  { 0, "VERSION",  irc_version_callback  },  { 0, "KICK",     irc_kick_callback     },  { 0, "AWAY",     irc_away_callback     },  { 0, "WHO",      irc_who_callback      },  { 0, "WHOIS",    irc_whois_callback    },  { 0, "MOTD",     irc_motd_callback     },  { 0, "INVITE",   irc_invite_callback   },  { 0, "LIST",     irc_list_callback     },  { 0, "NAMES",    irc_names_callback    },  { 0, "NOTICE",   irc_note_callback     },  { 0, "TOPIC",    irc_topic_callback    },  { 0, "MODE",     irc_mode_callback     },  { 0, "PRIVMSG",  irc_priv_callback     },  { 0, "USERHOST", irc_userhost_callback },  { 0, "ISON",     irc_ison_callback     },  { 0, "USERS",    irc_users_callback    },  { 0, "PART",     irc_part_callback     },  { 0, "QUIT",     irc_quit_callback     },  { 0, "JOIN",     irc_join_callback     },  { 0, "PASS",     irc_pass_callback     },  { 0, "USER",     irc_user_callback     },  { 0, "NICK",     irc_nick_callback     },  { 0, NULL,       NULL                  }};intirc_handle_request (svz_socket_t *sock, char *request, int len){  irc_config_t *cfg = sock->cfg;  irc_client_t *client = sock->data;  int n;  irc_parse_request (request, len);  /*    * FIXME: server handling not yet done.    * Should be alike: get irc client by message prefix, otherwise special   *                  server request handling   */  if (sock->userflags & IRC_FLAG_SERVER)    return 0;  for (n = 0; irc_callback[n].request; n++)    {      if (!svz_strcasecmp (irc_callback[n].request, irc_request.request))	{	  irc_callback[n].count++;	  client->recv_bytes += len;	  client->recv_packets++;	  return irc_callback[n].func (sock, client, &irc_request);	}    }  irc_printf (sock, ":%s %03d %s " ERR_UNKNOWNCOMMAND_TEXT "\n",	      cfg->host, ERR_UNKNOWNCOMMAND, 	      client->nick ? client->nick : "", irc_request.request);  return 0;}/* * Delete a channel from the channel list. Returns -1 if there was no * appropriate channel. */static intirc_delete_channel (irc_config_t *cfg, irc_channel_t *channel){  int n;  if (svz_hash_contains (cfg->channels, channel))    {      /* svz_free() all the channel ban entries */      for (n = 0; n < channel->bans; n++)	irc_destroy_ban (channel->ban[n]);      if (channel->ban)	svz_free (channel->ban);      svz_hash_delete (cfg->channels, channel->name);            if (channel->topic)	svz_free (channel->topic);      if (channel->topic_by)	svz_free (channel->topic_by);      if (channel->key)	svz_free (channel->key);      if (channel->invite)	svz_free (channel->invite);      svz_free (channel->by);      svz_free (channel->name);      svz_free (channel);      return 0;    }  return -1;}/* * Find a channel within the current channel list. Return NULL if * the channel has not been found. */irc_channel_t *irc_find_channel (irc_config_t *cfg, char *channel){  irc_channel_t *chan;  chan = svz_hash_get (cfg->channels, channel);  return chan;}/* * Find all matching channels in the current channel list. Return NULL if * no channel has not been found. You MUST svz_free() this list if non-NULL. * The delivered array is NULL terminated. */irc_channel_t **irc_regex_channel (irc_config_t *cfg, char *regex){  irc_channel_t **channel, **fchannel;  int n, found, size;  if ((channel = (irc_channel_t **) svz_hash_values (cfg->channels)) != NULL)    {      size = svz_hash_size (cfg->channels);      fchannel = svz_malloc (sizeof (irc_channel_t *) * (size + 1));      for (found = n = 0; n < size; n++)	{	  if (irc_string_regex (channel[n]->name, regex))	    {	      fchannel[found++] = channel[n];	    }	}      svz_hash_xfree (channel);      /* return NULL if there is not channel */      if (!found)	{	  svz_free (fchannel);	  return NULL;	}      fchannel[found++] = NULL;      fchannel = svz_realloc (fchannel, sizeof (irc_channel_t *) * found);      return fchannel;    }  return NULL;}/* * Add a new channel to the channel list. */static irc_channel_t *irc_add_channel (irc_config_t *cfg, char *name){  irc_channel_t *channel;  if (irc_find_channel (cfg, name))    return NULL;  channel = svz_malloc (sizeof (irc_channel_t));  memset (channel, 0, sizeof (irc_channel_t));  channel->name = svz_strdup (name);  svz_hash_put (cfg->channels, name, channel);  return channel;}/* * Add a client to the client history list. */voidirc_add_client_history (irc_config_t *cfg, irc_client_t *cl){  irc_client_history_t *client;  client = svz_malloc (sizeof (irc_client_history_t));  client->nick = svz_strdup (cl->nick);  client->user = svz_strdup (cl->user);  client->host = svz_strdup (cl->host);  client->real = svz_strdup (cl->real);  client->next = cfg->history;  cfg->history = client;}/* * Find a nick in the history client list. Return NULL if * no nick has not been found. Otherwise the first client found within * the history list. */irc_client_history_t *irc_find_nick_history (irc_config_t *cfg, 		       irc_client_history_t *cl, char *nick){  irc_client_history_t *client;  client = cl ? cl->next : cfg->history;  for (; client; client = client->next)    {      if (!irc_string_equal (client->nick, nick))	{	  return client;	}    }  return NULL;}/* * Delete all the client history. */voidirc_delete_client_history (irc_config_t *cfg){  irc_client_history_t *client;  irc_client_history_t *old;  for (client = cfg->history; client; client = old)    {      old = client->next;      svz_free (client->nick);      svz_free (client->user);      svz_free (client->host);      svz_free (client->real);      svz_free (client);    }  cfg->history = NULL;}/* * Delete a client from the client list. Returns -1 if there was no * appropriate client. */intirc_delete_client (irc_config_t *cfg, irc_client_t *client){  int ret = 0;  if (client->nick)    {      /* put this client into the history list */      irc_add_client_history (cfg, client);      if (svz_hash_delete (cfg->clients, client->nick) == NULL)	ret = -1;      svz_free (client->nick);    }  /* free all client properties */  if (client->real)    svz_free (client->real);  if (client->user)    svz_free (client->user);  if (client->host)    svz_free (client->host);  if (client->server)    svz_free (client->server);  if (client->channel)    svz_free (client->channel);  if (client->pass)    svz_free (client->pass);  if (client->away)    svz_free (client->away);  svz_free (client);  cfg->users--;  return ret;}/* * Find a user@host within the current client list. Return NULL if * no client has not been found. */irc_client_t *irc_find_userhost (irc_config_t *cfg, char *user, char *host){  irc_client_t **client;  irc_client_t *fclient;  int n;  if ((client = (irc_client_t **) svz_hash_values (cfg->clients)) != NULL)    {      for (n = 0; n < svz_hash_size (cfg->clients); n++)	{	  if (!strcmp (client[n]->user, user) && 	      !strcmp (client[n]->host, host))	    {	      fclient = client[n];	      svz_hash_xfree (client);	      return fclient;	    }	}      svz_hash_xfree (client);    }  return NULL;}/* * Find a nick within the current client list. Return NULL if * the nick has not been found. */irc_client_t *irc_find_nick (irc_config_t *cfg, char *nick){  irc_client_t *client;  if ((client = svz_hash_get (cfg->clients, nick)) != NULL)    {      return client;    }  return NULL;}/* * Find all matching nicks in the current client list. Return NULL if * no nick has not been found. You MUST svz_free() this array if it is * non-NULL. The delivered clients are NULL terminated. */irc_client_t **irc_regex_nick (irc_config_t *cfg, char *regex){  irc_client_t **client, **fclient;  int n, found, size;  if ((client = (irc_client_t **) svz_hash_values (cfg->clients)) != NULL)    {      size = svz_hash_size (cfg->clients);      fclient = svz_malloc (sizeof (irc_client_t *) * (size + 1));      for (found = n = 0; n < size; n++)	{	  if (irc_string_regex (client[n]->nick, regex))	    {	      fclient[found++] = client[n];	    }	}      svz_hash_xfree (client);      /* return NULL if there is not client */      if (!found)	{	  svz_free (fclient);	  return NULL;	}      fclient[found++] = NULL;      fclient = svz_realloc (fclient, sizeof (irc_client_t *) * found);      return fclient;    }  return NULL;}/* * Add a new client to the client list. */irc_client_t *irc_add_client (irc_config_t *cfg, irc_client_t *client){  if (irc_find_nick (cfg, client->nick))    return NULL;  svz_hash_put (cfg->clients, client->nick, client);  return client;}/* * Create a new IRC client structure. This will be stored within the * miscellaneous data field in the socket structure (sock->data). */irc_client_t *irc_create_client (irc_config_t *cfg){  irc_client_t *client;  client = svz_malloc (sizeof (irc_client_t));  memset (client, 0, sizeof (irc_client_t));  cfg->users++;  return client;}/* * Print a formatted string to the socket SOCK. */intirc_printf (svz_socket_t *sock, const char *fmt, ...){  va_list args;  static char buffer[VSNPRINTF_BUF_SIZE];  unsigned len;  if (sock->flags & SOCK_FLAG_KILLED)    return 0;  va_start (args, fmt);  len = svz_vsnprintf (buffer, VSNPRINTF_BUF_SIZE, fmt, args);  va_end (args);  /* Just to be sure... */  if (len > sizeof (buffer))    len = sizeof (buffer);  if ((len = svz_sock_write (sock, buffer, len)) != 0)    {      sock->flags |= SOCK_FLAG_KILLED;    }  return len;}int have_irc = 1;#else /* ENABLE_IRC_PROTO */int have_irc = 0;            /* Shut up compiler, remember for runtime */#endif /* ENABLE_IRC_PROTO */

⌨️ 快捷键说明

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