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

📄 irc-server.c

📁 Serveez是一个服务器框架
💻 C
字号:
/* * irc-server.c - IRC server connection 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-server.c,v 1.25 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 <errno.h>#ifdef __MINGW32__# include <winsock2.h>#endif#ifndef __MINGW32__# include <sys/types.h># include <sys/socket.h># include <netinet/in.h># include <netdb.h># include <arpa/inet.h>#endif#include "libserveez.h"#include "irc-proto.h"#include "irc-event.h"#include "irc-server.h"#define DEFAULT_PORT 6667irc_server_t *irc_server_list;  /* server list root */#define MAX_HOST_LEN 256#define MAX_PASS_LEN 256#define MAX_NAME_LEN 256/* * Parse one of the config lines in the IRC configuration. * This function has exactly the same syntax as sscanf() but * recognizes only %s and %d for string and integers. Strings * will be parsed until the next character in the format string. */intirc_parse_line (char *line, char *fmt, ...){  va_list args;  int *i;  char *s;  int ret;  va_start (args, fmt);  ret = 0;  while (*fmt && *line)    {      /* next arg */      if (*fmt == '%')	{	  /* check if this is a valid format identifier */	  if (!*++fmt)	    break;	  /* a decimal */	  if (*fmt == 'd')	    {	      i = va_arg (args, int *);	      *i = 0;	      fmt++;	      while (*line && *line >= '0' && *line <= '9')		{		  *i *= 10;		  *i += (*line - '0');		  line++;		}	    }	  /* a string */	  else if (*fmt == 's')	    {	      s = va_arg (args, char *);	      fmt++;	      while (*line && *line != *fmt)		{		  *s++ = *line++;		}	      *s = 0;	    }	  ret++;	}      /* not an arg */      else if (*fmt != *line)	{	  break;	}      if (*fmt)	fmt++;      if (*line)	line++;    }  va_end (args);  return ret;}/* * This will be called if a DNS lookup for a remote irc server has * been done. Here we connect to this server then. Return non-zero on * errors. */intirc_connect_server (char *ip, irc_server_t *server){  irc_config_t *cfg = server->cfg;  svz_socket_t *sock;  irc_client_t **cl;  irc_channel_t **ch;  char nicklist[MAX_MSG_LEN];  int n, i;  /* check if dns lookup was successful */  if (!ip)    {      svz_log (LOG_ERROR, "irc: cannot connect to %s\n", server->realhost);      return -1;    }    /* try connecting */  server->addr = inet_addr (ip);  if ((sock = svz_tcp_connect (server->addr, server->port)) == NULL)    {      return -1;    }  svz_log (LOG_NOTICE, "irc: connecting to %s\n", server->realhost);  sock->data = server;  sock->cfg = cfg;  server->id = sock->id;  server->connected = 1;  sock->userflags |= IRC_FLAG_SERVER;  sock->check_request = irc_check_request;  /* send initial requests introducing this server */#ifndef ENABLE_TIMESTAMP  irc_printf (sock, "PASS %s\n", server->pass);#else /* ENABLE_TIMESTAMP */  irc_printf (sock, "PASS %s %s\n", server->pass, TS_PASS);#endif /* ENABLE_TIMESTAMP */  irc_printf (sock, "SERVER %s 1 :%s\n", cfg->host, cfg->info);#if ENABLE_TIMESTAMP  irc_printf (sock, "SVINFO %d %d %d :%d\n",	      TS_CURRENT, TS_MIN, 0, time (NULL) + cfg->tsdelta);#endif /* ENABLE_TIMESTAMP */  /* now propagate user information to this server */  if ((cl = (irc_client_t **) svz_hash_values (cfg->clients)) != NULL)    {      for (n = 0; n < svz_hash_size (cfg->clients); n++)	{#if ENABLE_TIMESTAMP	  irc_printf (sock, "NICK %s %d %d %s %s %s %s :%s\n",		      cl[n]->nick, cl[n]->hopcount, cl[n]->since, 		      irc_client_flag_string (cl[n]), 		      cl[n]->user, cl[n]->host, cl[n]->server, "EFNet?");#else /* not ENABLE_TIMESTAMP */	  irc_printf (sock, "NICK %s\n", cl[n]->nick);	  irc_printf (sock, "USER %s %s %s %s\n", 		      cl[n]->user, cl[n]->host, cl[n]->server, cl[n]->real);	  irc_printf (sock, "MODE %s %s\n", 		      cl[n]->nick, irc_client_flag_string (cl[n]));#endif /* not ENABLE_TIMESTAMP */	}      svz_hash_xfree (cl);    }  /* propagate all channel information to the server */  if ((ch = (irc_channel_t **) svz_hash_values (cfg->channels)) != NULL)    {      for (i = 0; i < svz_hash_size (cfg->channels); i++)	{#if ENABLE_TIMESTAMP	  /* create nick list */	  for (nicklist[0] = 0, n = 0; n < ch[n]->clients; n++)	    {	      if (ch[i]->cflag[n] & MODE_OPERATOR)		strcat (nicklist, "@");	      else if (ch[i]->cflag[n] & MODE_VOICE)		strcat (nicklist, "+");	      strcat (nicklist, ch[i]->client[n]->nick);	      strcat (nicklist, " ");	    }	}      /* propagate one channel in one request */      irc_printf (sock, "SJOIN %d %s %s :%s\n",		  ch[i]->since, ch[i]->name, irc_channel_flag_string (ch[i]),		  nicklist);#else /* not ENABLE_TIMESTAMP */      for (n = 0; n < ch[i]->clients; n++)	{	  irc_printf (sock, ":%s JOIN %s\n", 		      ch[i]->client[n], ch[i]->name);	}      irc_printf (sock, "MODE %s %s\n", 		  ch[i]->name, irc_channel_flag_string (ch[i]));#endif /* not ENABLE_TIMESTAMP */      svz_hash_xfree (ch);    }    return 0;}/* * Add an IRC server to the server list. */static irc_server_t *irc_add_server (irc_config_t *cfg, irc_server_t *server){  server->next = cfg->servers;  cfg->servers = server;      return cfg->servers;}/* * Go through all C lines in the IRC server configuration * and resolve all hosts. */voidirc_connect_servers (irc_config_t *cfg){  char realhost[MAX_HOST_LEN];  char pass[MAX_PASS_LEN];  char host[MAX_NAME_LEN];  int class, port;  irc_server_t *ircserver;  char *cline;  int n;  /* any C lines at all ? */  if (!cfg->CLine)    return;  /* go through all C lines */  svz_array_foreach (cfg->CLine, cline, n)    {      /* scan the actual C line */      irc_parse_line (cline, "C:%s:%s:%s:%d:%d", 		      realhost, pass, host, &port, &class);            /* create new IRC server structure */      ircserver = svz_malloc (sizeof (irc_server_t));      ircserver->port = htons ((unsigned short) port);      ircserver->class = class;      ircserver->id = -1;      ircserver->realhost = svz_malloc (strlen (realhost) + 1);      strcpy (ircserver->realhost, realhost);      ircserver->host = svz_malloc (strlen (host) + 1);      strcpy (ircserver->host, host);      ircserver->pass = svz_malloc (strlen (pass) + 1);      strcpy (ircserver->pass, pass);      ircserver->cfg = cfg;      ircserver->next = NULL;      ircserver->connected = 0;      ircserver->connect = 1;      /* add this server to the server list */      svz_log (LOG_NOTICE, "irc: enqueuing %s\n", ircserver->realhost);      irc_add_server (cfg, ircserver);      svz_coserver_dns (realhost, irc_connect_server, ircserver, NULL);    }}/* * Delete an IRC server of the current list. */static voidirc_del_server (irc_config_t *cfg, irc_server_t *server){  irc_server_t *srv;  irc_server_t *prev;  prev = srv = cfg->servers;  while (srv)    {      if (srv == server)	{	  svz_free (server->realhost);	  svz_free (server->host);	  svz_free (server->pass);	  if (prev == srv)	    cfg->servers = server->next;	  else	    prev->next = server->next;	  svz_free (server);	  return;	}      prev = srv;      srv = srv->next;    }}/* * Delete all IRC servers. */voidirc_delete_servers (irc_config_t *cfg){  while (cfg->servers)    {      irc_del_server (cfg, cfg->servers);    }}/* * Count the amount of currently connected IRC servers. */intirc_count_servers (irc_config_t *cfg){  irc_server_t *server;  int n = 0;    for (server = cfg->servers; server; server = server->next)    {      if (server->connected)	n++;    }  return n;}/* * Find an IRC server in the current list. */irc_server_t *irc_find_server (void){  return NULL;}#else /* not ENABLE_IRC_PROTO */int irc_server_dummy; /* Shut up compiler. */#endif /* ENABLE_IRC_PROTO */

⌨️ 快捷键说明

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