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

📄 server.c

📁 打魔兽战网的都知道他是什么
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (C) 1998,1999  Mark Baysinger (mbaysing@ucsd.edu) * Copyright (C) 1998,1999,2000,2001  Ross Combs (rocombs@cs.nmsu.edu) * Copyright (C) 2000,2001  Marco Ziech (mmz@gmx.net) * * This program 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 * of the License, or (at your option) any later version. * * This program 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 program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. */#define SERVER_INTERNAL_ACCESS#include "common/setup_before.h"#include <stdio.h>#ifdef WIN32# include <conio.h> /* for kbhit() and getch() */#endif#ifdef HAVE_STDDEF_H# include <stddef.h>#else# ifndef NULL#  define NULL ((void *)0)# endif#endif#ifdef STDC_HEADERS# include <stdlib.h>#else# ifdef HAVE_MALLOC_H#  include <malloc.h># endif#endif#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#ifdef HAVE_FCNTL_H# include <fcntl.h>#else# ifdef HAVE_SYS_FILE_H#  include <sys/file.h># endif#endif#ifdef HAVE_STRING_H# include <string.h>#else# ifdef HAVE_STRINGS_H#  include <strings.h># endif# ifdef HAVE_MEMORY_H#  include <memory.h># endif#endif#include "compat/memset.h"#include <errno.h>#include "compat/strerror.h"#ifdef TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# ifdef HAVE_SYS_TIME_H#  include <sys/time.h># else#  include <time.h># endif#endif#include "compat/difftime.h"#ifdef HAVE_SYS_TYPES_H# include <sys/types.h>#endif#ifdef DO_POSIXSIG# include <signal.h># include "compat/signal.h"#endif#ifdef HAVE_SYS_SOCKET_H# include <sys/socket.h>#endif#include "compat/socket.h"#ifdef HAVE_SYS_PARAM_H# include <sys/param.h>#endif#ifdef HAVE_NETINET_IN_H# include <netinet/in.h>#endif#include "compat/netinet_in.h"#ifdef HAVE_ARPA_INET_H# include <arpa/inet.h>#endif#ifdef HAVE_NETDB_H# include <netdb.h>#endif#include "compat/inet_ntoa.h"#include "compat/psock.h"#include "common/packet.h"#include "connection.h"#include "common/hexdump.h"#include "common/eventlog.h"#include "message.h"#include "handle_bnet.h"#include "handle_bot.h"#include "handle_telnet.h"#include "handle_file.h"#include "handle_init.h"#include "handle_d2cs.h"#include "handle_irc.h"#include "handle_udp.h"#include "common/network.h"#include "prefs.h"#include "account.h"#include "common/tracker.h"#include "common/list.h"#include "adbanner.h"#include "timer.h"#include "common/addr.h"#include "common/util.h"#include "common/rlimit.h"#include "ipban.h"#include "helpfile.h"#include "autoupdate.h"#include "versioncheck.h"#include "realm.h"#include "channel.h"#include "game.h"#include "anongame.h"#include "server.h"#include "command_groups.h"#ifdef WIN32# include "win32/service.h"#endif#include "ladder.h"#include "output.h"#include "alias_command.h"#include "anongame_infos.h"#include "news.h"#include "common/fdwatch.h"#include "clan.h"#include "common/trans.h"#include "common/xalloc.h"#include "tournament.h"#include <ctype.h>#include "topic.h"#include "attrlayer.h"#include "cmdline.h"#include "common/setup_after.h"extern FILE * hexstrm; /* from main.c */extern int g_ServiceStatus;#ifdef DO_POSIXSIGstatic void quit_sig_handle(int unused);static void restart_sig_handle(int unused);static void save_sig_handle(int unused);#ifdef HAVE_SETITIMERstatic void timer_sig_handle(int unused);#endif#endiftime_t now;static time_t starttime;static time_t curr_exittime;static volatile time_t sigexittime=0;static volatile int do_restart=0;static volatile int do_save=0;static volatile int got_epipe=0;static char const * server_hostname=NULL;extern void server_quit_delay(int delay){    /* getting negative delay is ok too because it will force immediate     * shutdown */    if (delay)	sigexittime = time(NULL)+delay;    else	sigexittime = 0;}extern void server_quit_wraper(void){    if (sigexittime)	sigexittime -= prefs_get_shutdown_decr();    else	sigexittime = time(NULL)+(time_t)prefs_get_shutdown_delay();}extern void server_restart_wraper(void){    do_restart = 1;}extern void server_save_wraper(void){    do_save = 1;}#ifdef DO_POSIXSIGstatic void quit_sig_handle(int unused){    server_quit_wraper();}static void restart_sig_handle(int unused){    do_restart = 1;}static void save_sig_handle(int unused){    do_save = 1;}static void pipe_sig_handle(int unused){    got_epipe = 1;}#ifdef HAVE_SETITIMERstatic void timer_sig_handle(int unused){    time(&now);}#endifstatic void forced_quit_sig_handle(int unused){    server_quit_delay(-1);	/* programs shutdown 1 second before now */}#endifextern unsigned int server_get_uptime(void){    return (unsigned int)difftime(time(NULL),starttime);}extern unsigned int server_get_starttime(void){    return (unsigned int)starttime;}static char const * laddr_type_get_str(t_laddr_type laddr_type){    switch (laddr_type)    {    case laddr_type_bnet:	return "bnet";	case laddr_type_w3route:	return "w3route";    case laddr_type_irc:	return "irc";    case laddr_type_wol:	return "wol";    case laddr_type_telnet:	return "telnet";    default:	return "UNKNOWN";    }}static int handle_accept(void *data, t_fdwatch_type rw);static int handle_tcp(void *data, t_fdwatch_type rw);static int handle_udp(void *data, t_fdwatch_type rw);static int sd_accept(t_addr const * curr_laddr, t_laddr_info const * laddr_info, int ssocket, int usocket){    char               tempa[32];    int                csocket;    struct sockaddr_in caddr;    psock_t_socklen    caddr_len;    unsigned int       raddr;    unsigned short     rport;    if (!addr_get_addr_str(curr_laddr,tempa,sizeof(tempa)))	strcpy(tempa,"x.x.x.x:x");        /* accept the connection */    memset(&caddr,0,sizeof(caddr)); /* not sure if this is needed... modern systems are ok anyway */    caddr_len = sizeof(caddr);    if ((csocket = psock_accept(ssocket,(struct sockaddr *)&caddr,&caddr_len))<0)    {	/* BSD, POSIX error for aborted connections, SYSV often uses EAGAIN or EPROTO */	if (#ifdef PSOCK_EWOULDBLOCK	    psock_errno()==PSOCK_EWOULDBLOCK ||#endif#ifdef PSOCK_ECONNABORTED	    psock_errno()==PSOCK_ECONNABORTED ||#endif#ifdef PSOCK_EPROTO	    psock_errno()==PSOCK_EPROTO ||#endif	    0)	    eventlog(eventlog_level_error,__FUNCTION__,"client aborted connection on %s (psock_accept: %s)",tempa,pstrerror(psock_errno()));	else /* EAGAIN can mean out of resources _or_ connection aborted :( */	    if (#ifdef PSOCK_EINTR		psock_errno()!=PSOCK_EINTR &&#endif		1)		eventlog(eventlog_level_error,__FUNCTION__,"could not accept new connection on %s (psock_accept: %s)",tempa,pstrerror(psock_errno()));	return -1;    }    /* dont accept new connections while shutdowning */    if (curr_exittime) {	psock_shutdown(csocket,PSOCK_SHUT_RDWR);	psock_close(csocket);	return 0;    }    if (ipbanlist_check(inet_ntoa(caddr.sin_addr))!=0)    {	eventlog(eventlog_level_info,__FUNCTION__,"[%d] connection from banned address %s denied (closing connection)",csocket,inet_ntoa(caddr.sin_addr));	psock_close(csocket);	return -1;    }    if ((prefs_get_max_conns_per_IP()!=0) && 	(connlist_count_connections(ntohl(caddr.sin_addr.s_addr)) > prefs_get_max_conns_per_IP()))    {	eventlog(eventlog_level_error,__FUNCTION__,"[%d] too many connections from address %s (closing connection)",csocket,inet_ntoa(caddr.sin_addr));	psock_close(csocket);	return -1;    }        eventlog(eventlog_level_info,__FUNCTION__,"[%d] accepted connection from %s on %s",csocket,addr_num_to_addr_str(ntohl(caddr.sin_addr.s_addr),ntohs(caddr.sin_port)),tempa);        if (prefs_get_use_keepalive())    {	int val=1;		if (psock_setsockopt(csocket,PSOCK_SOL_SOCKET,PSOCK_SO_KEEPALIVE,&val,(psock_t_socklen)sizeof(val))<0)	    eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not set socket option SO_KEEPALIVE (psock_setsockopt: %s)",csocket,pstrerror(psock_errno()));	/* not a fatal error */    }        {	struct sockaddr_in rsaddr;	psock_t_socklen    rlen;		memset(&rsaddr,0,sizeof(rsaddr)); /* not sure if this is needed... modern systems are ok anyway */	rlen = sizeof(rsaddr);	if (psock_getsockname(csocket,(struct sockaddr *)&rsaddr,&rlen)<0)	{	    eventlog(eventlog_level_error,__FUNCTION__,"[%d] unable to determine real local port (psock_getsockname: %s)",csocket,pstrerror(psock_errno()));	    /* not a fatal error */	    raddr = addr_get_ip(curr_laddr);	    rport = addr_get_port(curr_laddr);	}	else	{	    if (rsaddr.sin_family!=PSOCK_AF_INET)	    {		eventlog(eventlog_level_error,__FUNCTION__,"local address returned with bad address family %d",(int)rsaddr.sin_family);		/* not a fatal error */		raddr = addr_get_ip(curr_laddr);		rport = addr_get_port(curr_laddr);	    }	    else	    {		raddr = ntohl(rsaddr.sin_addr.s_addr);		rport = ntohs(rsaddr.sin_port);	    }	}    }        if (psock_ctl(csocket,PSOCK_NONBLOCK)<0)    {	eventlog(eventlog_level_error,__FUNCTION__,"[%d] could not set TCP socket to non-blocking mode (closing connection) (psock_ctl: %s)",csocket,pstrerror(psock_errno()));	psock_close(csocket);	return -1;    }        {	t_connection * c;

⌨️ 快捷键说明

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