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

📄 irc-config.c

📁 Serveez是一个服务器框架
💻 C
字号:
/* * irc-config.c - IRC server configuration routines * * 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-config.c,v 1.14 2001/05/19 23:04:57 ela Exp $ * */#if HAVE_CONFIG_H# include <config.h>#endif#if ENABLE_IRC_PROTO#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#ifdef __MINGW32__# include <winsock2.h>#endif#include <libserveez.h>#include "irc-proto.h"#include "irc-server.h"#include "irc-config.h"/* * This routine will parse all of the x-lines of the IRC server * configuration and store the information within the appropriate * lists. */#define MAX_TMP_ARRAY  4#define MAX_TMP_STRLEN 256#define PARSE_TILL_AT(str) \  p = str; \  while (*p && *p != '@') p++; \  if (*p) { *p = '\0'; p++; }voidirc_parse_config_lines (irc_config_t *cfg){  int n;  irc_class_t *class;  irc_user_t *user;  irc_oper_t *oper;  irc_kill_t *kill;  char *line, *p;  char *tmp[MAX_TMP_ARRAY];    /* reserve some buffer space */  for (n = 0; n < MAX_TMP_ARRAY; n++)    tmp[n] = svz_malloc (MAX_TMP_STRLEN);  /* parse connection classes */  svz_array_foreach (cfg->YLine, line, n)    {      class = svz_malloc (sizeof (irc_class_t));      if (5 != irc_parse_line (line, "Y:%d:%d:%d:%d:%d",			       &class->nr, &class->ping_freq, 			       &class->connect_freq, &class->max_links, 			       &class->sendq_size))	{	  svz_log (LOG_ERROR, "irc: invalid Y line: %s\n", line);	  svz_free (class);	}      else	{	  class->links = 0;	  class->line = line;	  class->next = cfg->classes;	  cfg->classes = class;	}    }  /* parse user authorization lines */  svz_array_foreach (cfg->ILine, line, n)    {      user = svz_malloc (sizeof (irc_user_t));      if (5 != irc_parse_line (line, "I:%s:%s:%s:%s:%d",			       tmp[0], tmp[1], tmp[2], tmp[3], 			       &user->class))	{	  svz_log (LOG_ERROR, "irc: invalid I line: %s\n", line);	  svz_free (user);	}      else	{	  user->line = line;	  PARSE_TILL_AT (tmp[0]);	  user->user_ip = svz_strdup (tmp[0]);	  user->ip = svz_strdup (p);	  user->password = svz_strdup (tmp[1]);	  PARSE_TILL_AT (tmp[2]);	  user->user_host = svz_strdup (tmp[2]);	  user->host = svz_strdup (p);	  if (!user->password)	    user->password = svz_strdup (tmp[3]);	  user->next = cfg->user_auth;	  cfg->user_auth = user;	}    }  /* parse operator authorization lines (local and network wide) */  svz_array_foreach (cfg->OLine, line, n)    {      oper = svz_malloc (sizeof (irc_oper_t));      if (4 != irc_parse_line (line, "O:%s:%s:%s::%d",			       tmp[0], tmp[1], tmp[2], &oper->class))	{	  svz_log (LOG_ERROR, "irc: invalid O line: %s\n", line);	  svz_free (oper);	}      else	{	  oper->line = line;	  PARSE_TILL_AT (tmp[0]);	  oper->user = svz_strdup (tmp[0]);	  oper->host = svz_strdup (p);	  oper->password = svz_strdup (tmp[1]);	  oper->nick = svz_strdup (tmp[2]);	  oper->local = 0;	  oper->next = cfg->operator_auth;	  cfg->operator_auth = oper;	}    }  svz_array_foreach (cfg->oLine, line, n)    {      oper = svz_malloc (sizeof (irc_oper_t));      if (4 != irc_parse_line (line, "O:%s:%s:%s::%d",			       tmp[0], tmp[1], tmp[2], &oper->class))	{	  svz_log (LOG_ERROR, "irc: invalid o line: %s\n", line);	  svz_free (oper);	}      else	{	  oper->line = line;	  PARSE_TILL_AT (tmp[0]);	  oper->user = svz_strdup (tmp[0]);	  oper->host = svz_strdup (p);	  oper->password = svz_strdup (tmp[1]);	  oper->nick = svz_strdup (tmp[2]);	  oper->local = 1;	  oper->next = cfg->operator_auth;	  cfg->operator_auth = oper;	}    }  /* parse banned clients */  svz_array_foreach (cfg->KLine, line, n)    {      kill = svz_malloc (sizeof (irc_kill_t));      if (4 != irc_parse_line (line, "O:%s:%d-%d:%s",			       tmp[0], &kill->start, &kill->end, tmp[1]))	{	  svz_log (LOG_ERROR, "irc: invalid K line: %s\n", line);	  svz_free (kill);	}      else	{	  kill->line = line;	  kill->host = svz_strdup (tmp[0]);	  kill->user = svz_strdup (tmp[1]);	  kill->next = cfg->banned;	  cfg->banned = kill;	}    }  /* free the previously allocated buffer space */  for (n = 0; n < MAX_TMP_ARRAY; n++)    svz_free (tmp[n]);}/* * Free all the stuff reserved in the routine above. */voidirc_free_config_lines (irc_config_t *cfg){  irc_user_t *user;  irc_class_t *class;  irc_oper_t *oper;  irc_kill_t *kill;  /* free connection classes */  while ((class = cfg->classes) != NULL)    {      cfg->classes = class->next;      svz_free (class);    }  /* free user authorization list */  while ((user = cfg->user_auth) != NULL)    {      cfg->user_auth = user->next;      if (user->user_ip)	svz_free (user->user_ip);      if (user->ip)	svz_free (user->ip);      if (user->user_host)	svz_free (user->user_host);      if (user->host)	svz_free (user->host);      if (user->password)	svz_free (user->password);      svz_free (user);    }  /* free operator authorization list */  while ((oper = cfg->operator_auth) != NULL)    {      cfg->operator_auth = oper->next;      if (oper->nick)	svz_free (oper->nick);      if (oper->user)	svz_free (oper->user);      if (oper->host)	svz_free (oper->host);      if (oper->password)	svz_free (oper->password);      svz_free (oper);    }  /* free banned user list */  while ((kill = cfg->banned) != NULL)    {      cfg->banned = kill->next;      if (kill->user)	svz_free (kill->user);      if (kill->host)	svz_free (kill->host);      svz_free (kill);    }}/* * The following routine checks whether it is still possible to connect * via a given connection class number. It returns zero on success or if * there no such connection class, otherwise non-zero. */static intirc_check_class (irc_config_t *cfg, int class_nr){  irc_class_t *class;    for (class = cfg->classes; class; class = class->next)    {      if (class->nr == class_nr)	{	  if (class->links++ < class->max_links)	    return 0;	  else	    {#if ENABLE_DEBUG	      svz_log (LOG_DEBUG, "irc: %d/%d links reached in class %d\n",		       class->links, class->max_links, class->nr);#endif	      return -1;	    }	}    }  return 0;}/* * This functions goes through all the K lines to check whether a given * client is unwanted. Return non-zero if so. */static intirc_client_killed (irc_client_t *client, irc_config_t *cfg){  irc_kill_t *kill;  time_t t;  struct tm *tm;  int ts;  for (kill = cfg->banned; kill; kill = kill->next)    {      if (irc_string_regex (client->user, kill->user) &&	  irc_string_regex (client->host, kill->host))	{	  t = time (NULL);	  tm = localtime (&t);	  ts = (tm->tm_hour + 1) * 100 + tm->tm_min;	  if (ts >= kill->start && ts <= kill->end)	    {#if ENABLE_DEBUG	      svz_log (LOG_DEBUG, "irc: %s@%s is K lined: %s\n",		       client->user, client->host, kill->line);	      return -1;#endif	    }	}    }  return 0;}/* * This routine checks whether a given client is wanted to connect. * If it is not return zero, otherwise non-zero. */intirc_client_valid (irc_client_t *client, irc_config_t *cfg){  irc_user_t *user;  /* first we check whether this client is within the K lines */  if (irc_client_killed (client, cfg))    {      irc_printf (client->sock, "%s %03d %s " ERR_YOUREBANNEDCREEP_TEXT "\n",		  cfg->host, ERR_YOUREBANNEDCREEP, client->nick);      return 0;    }  /* have a look at the user authorization list (I lines) */  for (user = cfg->user_auth; user; user = user->next)    {      if ((irc_string_regex (client->user, user->user_ip) &&	   irc_string_regex (svz_inet_ntoa (client->sock->remote_addr), 			     user->ip)) ||	  (irc_string_regex (client->user, user->user_host) &&	   irc_string_regex (client->host, user->host)))	{	  /* test the given password for that I line */	  if (user->password)	    {#if ENABLE_CRYPT && HAVE_CRYPT	      if (strcmp (crypt (client->pass, user->password), 			  user->password))#else	      if (strcmp (client->pass, user->password))#endif		{		  irc_printf (client->sock, ":%s %03d %s " 			      ERR_PASSWDMISMATCH_TEXT "\n",			      cfg->host, ERR_PASSWDMISMATCH, client->nick);		  return 0;		}	    }	  /* now we have a look at the connection classes */	  if (irc_check_class (cfg, user->class))	    continue;	  #if ENABLE_DEBUG	  svz_log (LOG_DEBUG, "irc: valid client: %s\n", user->line);#endif	  return 1;	}    }#if ENABLE_DEBUG  svz_log (LOG_DEBUG, "irc: not a valid client (%s@%s)\n",	   client->user, client->host);#endif  return 0;}/* * The following function performs a check for the given client  * being able to get IRC operator. Return NULL on errors. */intirc_oper_valid (irc_client_t *client, irc_config_t *cfg){  irc_oper_t *oper;  for (oper = cfg->operator_auth; oper; oper = oper->next)    {      if (irc_string_regex (client->user, oper->user) &&	  irc_string_regex (client->host, oper->host) &&	  irc_string_regex (client->nick, oper->nick) &&#if ENABLE_CRYPT && HAVE_CRYPT	  !strcmp (crypt (client->pass, oper->password), oper->password))#else	  !strcmp (client->pass, oper->password))#endif	{#if ENABLE_DEBUG	  svz_log (LOG_DEBUG, "irc: valid operator: %s\n", oper->line);#endif	  return -1;	}    }#if ENABLE_DEBUG  svz_log (LOG_DEBUG, "irc: not a valid operator (%s@%s)\n",	   client->user, client->host);#endif  return 0;}#else /* ENABLE_IRC_PROTO */int irc_config_dummy; /* Shut up compiler. */#endif /* ENABLE_IRC_PROTO */

⌨️ 快捷键说明

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