server.c
上传用户:tany51
上传日期:2013-06-12
资源大小:1397k
文件大小:49k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.  * Copyright (C) 1998,1999  Mark Baysinger (mbaysing@ucsd.edu)
  3.  * Copyright (C) 1998,1999,2000,2001  Ross Combs (rocombs@cs.nmsu.edu)
  4.  * Copyright (C) 2000,2001  Marco Ziech (mmz@gmx.net)
  5.  *
  6.  * This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License
  8.  * as published by the Free Software Foundation; either version 2
  9.  * of the License, or (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  */
  20. #define SERVER_INTERNAL_ACCESS
  21. #include "common/setup_before.h"
  22. #include <stdio.h>
  23. #ifdef WIN32
  24. # include <conio.h> /* for kbhit() and getch() */
  25. #endif
  26. #ifdef HAVE_STDDEF_H
  27. # include <stddef.h>
  28. #else
  29. # ifndef NULL
  30. #  define NULL ((void *)0)
  31. # endif
  32. #endif
  33. #ifdef STDC_HEADERS
  34. # include <stdlib.h>
  35. #else
  36. # ifdef HAVE_MALLOC_H
  37. #  include <malloc.h>
  38. # endif
  39. #endif
  40. #ifdef HAVE_UNISTD_H
  41. # include <unistd.h>
  42. #endif
  43. #ifdef HAVE_FCNTL_H
  44. # include <fcntl.h>
  45. #else
  46. # ifdef HAVE_SYS_FILE_H
  47. #  include <sys/file.h>
  48. # endif
  49. #endif
  50. #ifdef HAVE_STRING_H
  51. # include <string.h>
  52. #else
  53. # ifdef HAVE_STRINGS_H
  54. #  include <strings.h>
  55. # endif
  56. # ifdef HAVE_MEMORY_H
  57. #  include <memory.h>
  58. # endif
  59. #endif
  60. #include "compat/memset.h"
  61. #include <errno.h>
  62. #include "compat/strerror.h"
  63. #ifdef TIME_WITH_SYS_TIME
  64. # include <sys/time.h>
  65. # include <time.h>
  66. #else
  67. # ifdef HAVE_SYS_TIME_H
  68. #  include <sys/time.h>
  69. # else
  70. #  include <time.h>
  71. # endif
  72. #endif
  73. #include "compat/difftime.h"
  74. #ifdef HAVE_SYS_TYPES_H
  75. # include <sys/types.h>
  76. #endif
  77. #ifdef DO_POSIXSIG
  78. # include <signal.h>
  79. # include "compat/signal.h"
  80. #endif
  81. #ifdef HAVE_SYS_SOCKET_H
  82. # include <sys/socket.h>
  83. #endif
  84. #include "compat/socket.h"
  85. #ifdef HAVE_SYS_PARAM_H
  86. # include <sys/param.h>
  87. #endif
  88. #ifdef HAVE_NETINET_IN_H
  89. # include <netinet/in.h>
  90. #endif
  91. #include "compat/netinet_in.h"
  92. #ifdef HAVE_ARPA_INET_H
  93. # include <arpa/inet.h>
  94. #endif
  95. #ifdef HAVE_NETDB_H
  96. # include <netdb.h>
  97. #endif
  98. #include "compat/inet_ntoa.h"
  99. #include "compat/psock.h"
  100. #include "common/packet.h"
  101. #include "connection.h"
  102. #include "common/hexdump.h"
  103. #include "common/eventlog.h"
  104. #include "message.h"
  105. #include "common/queue.h"
  106. #include "handle_auth.h"
  107. #include "handle_bnet.h"
  108. #include "handle_bot.h"
  109. #include "handle_telnet.h"
  110. #include "handle_file.h"
  111. #include "handle_init.h"
  112. #include "handle_d2cs.h"
  113. #include "handle_irc.h"
  114. #include "handle_udp.h"
  115. #include "common/network.h"
  116. #include "prefs.h"
  117. #include "account.h"
  118. #include "common/tracker.h"
  119. #include "common/list.h"
  120. #include "adbanner.h"
  121. #include "timer.h"
  122. #include "common/addr.h"
  123. #include "common/util.h"
  124. #include "common/rlimit.h"
  125. #include "ipban.h"
  126. #include "helpfile.h"
  127. #include "gametrans.h"
  128. #include "autoupdate.h"
  129. #include "versioncheck.h"
  130. #include "realm.h"
  131. #include "channel.h"
  132. #include "game.h"
  133. #include "anongame.h"
  134. #include "server.h"
  135. #include "command_groups.h"
  136. #ifdef WIN32
  137. # include "win32/service.h"
  138. #endif
  139. // aaron
  140. #include "ladder.h"
  141. #include "output.h"
  142. #include "alias_command.h"
  143. #include "anongame_infos.h"
  144. #include "news.h"
  145. #include "common/fdwatch.h"
  146. #include "clan.h"
  147. #include "w3trans.h"
  148. #include "tournament.h"
  149. #include "common/setup_after.h"
  150. extern FILE * hexstrm; /* from main.c */
  151. extern int g_ServiceStatus;
  152. #ifdef DO_POSIXSIG
  153. static void quit_sig_handle(int unused);
  154. static void restart_sig_handle(int unused);
  155. static void save_sig_handle(int unused);
  156. #ifdef HAVE_SETITIMER
  157. static void timer_sig_handle(int unused);
  158. #endif
  159. #endif
  160. #ifdef USE_CHECK_ALLOC
  161. static void memstat_sig_handle(int unused);
  162. #endif
  163. time_t now;
  164. static time_t starttime;
  165. static time_t curr_exittime;
  166. static volatile time_t sigexittime=0;
  167. static volatile int do_restart=0;
  168. static volatile int do_save=0;
  169. static volatile int got_epipe=0;
  170. #ifdef USE_CHECK_ALLOC
  171. static volatile int do_report_usage=0;
  172. #endif
  173. static char const * server_name=NULL;
  174. extern void server_quit_delay(unsigned int delay)
  175. {
  176.     if (delay)
  177. sigexittime = time(NULL)+(time_t)delay;
  178.     else
  179. sigexittime = 0;
  180. }
  181. extern void server_quit_wraper(void)
  182. {
  183.     if (sigexittime)
  184. sigexittime -= prefs_get_shutdown_decr();
  185.     else
  186. sigexittime = time(NULL)+(time_t)prefs_get_shutdown_delay();
  187. }
  188. extern void server_restart_wraper(void){
  189.     do_restart = 1;
  190. }
  191. extern void server_save_wraper(void){
  192.     do_save = 1;
  193. }
  194. #ifdef DO_POSIXSIG
  195. static void quit_sig_handle(int unused)
  196. {
  197.     server_quit_wraper();
  198. }
  199. static void restart_sig_handle(int unused)
  200. {
  201.     do_restart = 1;
  202. }
  203. static void save_sig_handle(int unused)
  204. {
  205.     do_save = 1;
  206. }
  207. static void pipe_sig_handle(int unused)
  208. {
  209.     got_epipe = 1;
  210. }
  211. #ifdef HAVE_SETITIMER
  212. static void timer_sig_handle(int unused)
  213. {
  214.     time(&now);
  215. }
  216. #endif
  217. #endif
  218. #ifdef USE_CHECK_ALLOC
  219. static void memstat_sig_handle(int unused)
  220. {
  221.     do_report_usage = 1;
  222. }
  223. #endif
  224. extern unsigned int server_get_uptime(void)
  225. {
  226.     return (unsigned int)difftime(time(NULL),starttime);
  227. }
  228. extern unsigned int server_get_starttime(void)
  229. {
  230.     return (unsigned int)starttime;
  231. }
  232. static char const * laddr_type_get_str(t_laddr_type laddr_type)
  233. {
  234.     switch (laddr_type)
  235.     {
  236.     case laddr_type_bnet:
  237. return "bnet";
  238. case laddr_type_w3route:
  239. return "w3route";
  240.     case laddr_type_irc:
  241. return "irc";
  242.     case laddr_type_telnet:
  243. return "telnet";
  244.     default:
  245. return "UNKNOWN";
  246.     }
  247. }
  248. static int handle_accept(void *data, t_fdwatch_type rw);
  249. static int handle_tcp(void *data, t_fdwatch_type rw);
  250. static int handle_udp(void *data, t_fdwatch_type rw);
  251. static int sd_accept(t_addr const * curr_laddr, t_laddr_info const * laddr_info, int ssocket, int usocket)
  252. {
  253.     char               tempa[32];
  254.     int                csocket;
  255.     struct sockaddr_in caddr;
  256.     psock_t_socklen    caddr_len;
  257.     unsigned int       raddr;
  258.     unsigned short     rport;
  259.     
  260.     /* dont accept new connections while shutdowning */
  261.     if (curr_exittime) {
  262. if ((csocket = psock_accept(ssocket, NULL, NULL)) > 0) {
  263.     psock_shutdown(csocket,PSOCK_SHUT_RDWR);
  264.     psock_close(csocket);
  265. }
  266. return 0;
  267.     }
  268.     if (!addr_get_addr_str(curr_laddr,tempa,sizeof(tempa)))
  269. strcpy(tempa,"x.x.x.x:x");
  270.     
  271.     /* accept the connection */
  272.     memset(&caddr,0,sizeof(caddr)); /* not sure if this is needed... modern systems are ok anyway */
  273.     caddr_len = sizeof(caddr);
  274.     if ((csocket = psock_accept(ssocket,(struct sockaddr *)&caddr,&caddr_len))<0)
  275.     {
  276. /* BSD, POSIX error for aborted connections, SYSV often uses EAGAIN or EPROTO */
  277. if (
  278. #ifdef PSOCK_EWOULDBLOCK
  279.     psock_errno()==PSOCK_EWOULDBLOCK ||
  280. #endif
  281. #ifdef PSOCK_ECONNABORTED
  282.     psock_errno()==PSOCK_ECONNABORTED ||
  283. #endif
  284. #ifdef PSOCK_EPROTO
  285.     psock_errno()==PSOCK_EPROTO ||
  286. #endif
  287.     0)
  288.     eventlog(eventlog_level_error,"sd_accept","client aborted connection on %s (psock_accept: %s)",tempa,strerror(psock_errno()));
  289. else /* EAGAIN can mean out of resources _or_ connection aborted :( */
  290.     if (
  291. #ifdef PSOCK_EINTR
  292. psock_errno()!=PSOCK_EINTR &&
  293. #endif
  294. 1)
  295. eventlog(eventlog_level_error,"sd_accept","could not accept new connection on %s (psock_accept: %s)",tempa,strerror(psock_errno()));
  296. return -1;
  297.     }
  298.     if (csocket >= fdw_maxfd)       /* This check is a bit too strict (csocket is probably
  299.                                      * greater than the number of connections) but this makes
  300.                                      * life easier later.
  301.                                      */
  302.     {
  303. eventlog(eventlog_level_error,"sd_accept","csocket is beyond range allowed by get_socket_limit() (%d>=%d)",csocket,fdw_maxfd);
  304. psock_close(csocket);
  305. return -1;
  306.     }
  307.     if (ipbanlist_check(inet_ntoa(caddr.sin_addr))!=0)
  308.     {
  309. eventlog(eventlog_level_error,"sd_accept","[%d] connection from banned address %s denied (closing connection)",csocket,inet_ntoa(caddr.sin_addr));
  310. psock_close(csocket);
  311. return -1;
  312.     }
  313.     if ((prefs_get_max_conns_per_IP()!=0) && 
  314. (connlist_count_connections(ntohl(caddr.sin_addr.s_addr)) > prefs_get_max_conns_per_IP()))
  315.     {
  316. eventlog(eventlog_level_error,__FUNCTION__,"[%d] too many connections from address %s (closing connection)",csocket,inet_ntoa(caddr.sin_addr));
  317. psock_close(csocket);
  318. return -1;
  319.     }
  320.     
  321.     eventlog(eventlog_level_info,"sd_accept","[%d] accepted connection from %s on %s",csocket,addr_num_to_addr_str(ntohl(caddr.sin_addr.s_addr),ntohs(caddr.sin_port)),tempa);
  322.     
  323.     if (prefs_get_use_keepalive())
  324.     {
  325. int val=1;
  326. if (psock_setsockopt(csocket,PSOCK_SOL_SOCKET,PSOCK_SO_KEEPALIVE,&val,(psock_t_socklen)sizeof(val))<0)
  327.     eventlog(eventlog_level_error,"sd_accept","[%d] could not set socket option SO_KEEPALIVE (psock_setsockopt: %s)",csocket,strerror(psock_errno()));
  328. /* not a fatal error */
  329.     }
  330.     
  331.     {
  332. struct sockaddr_in rsaddr;
  333. psock_t_socklen    rlen;
  334. memset(&rsaddr,0,sizeof(rsaddr)); /* not sure if this is needed... modern systems are ok anyway */
  335. rlen = sizeof(rsaddr);
  336. if (psock_getsockname(csocket,(struct sockaddr *)&rsaddr,&rlen)<0)
  337. {
  338.     eventlog(eventlog_level_error,"sd_accept","[%d] unable to determine real local port (psock_getsockname: %s)",csocket,strerror(psock_errno()));
  339.     /* not a fatal error */
  340.     raddr = addr_get_ip(curr_laddr);
  341.     rport = addr_get_port(curr_laddr);
  342. }
  343. else
  344. {
  345.     if (rsaddr.sin_family!=PSOCK_AF_INET)
  346.     {
  347. eventlog(eventlog_level_error,"sd_accept","local address returned with bad address family %d",(int)rsaddr.sin_family);
  348. /* not a fatal error */
  349. raddr = addr_get_ip(curr_laddr);
  350. rport = addr_get_port(curr_laddr);
  351.     }
  352.     else
  353.     {
  354. raddr = ntohl(rsaddr.sin_addr.s_addr);
  355. rport = ntohs(rsaddr.sin_port);
  356.     }
  357. }
  358.     }
  359.     
  360.     if (psock_ctl(csocket,PSOCK_NONBLOCK)<0)
  361.     {
  362. eventlog(eventlog_level_error,"sd_accept","[%d] could not set TCP socket to non-blocking mode (closing connection) (psock_ctl: %s)",csocket,strerror(psock_errno()));
  363. psock_close(csocket);
  364. return -1;
  365.     }
  366.     
  367.     {
  368. t_connection * c;
  369. if (!(c = conn_create(csocket,usocket,raddr,rport,addr_get_ip(curr_laddr),addr_get_port(curr_laddr),ntohl(caddr.sin_addr.s_addr),ntohs(caddr.sin_port))))
  370. {
  371.     eventlog(eventlog_level_error,"sd_accept","[%d] unable to create new connection (closing connection)",csocket);
  372.     psock_close(csocket);
  373.     return -1;
  374. }
  375. eventlog(eventlog_level_debug,"sd_accept","[%d] client connected to a %s listening address",csocket,laddr_type_get_str(laddr_info->type));
  376. fdwatch_add_fd(csocket, fdwatch_type_read, handle_tcp, c);
  377. switch (laddr_info->type)
  378. {
  379. case laddr_type_irc:
  380.     conn_set_class(c,conn_class_irc);
  381.     conn_set_state(c,conn_state_connected);
  382.     break;
  383. case laddr_type_w3route:
  384. conn_set_class(c,conn_class_w3route);
  385. conn_set_state(c,conn_state_connected);
  386. break;
  387. case laddr_type_telnet:
  388.     conn_set_class(c,conn_class_telnet);
  389.     conn_set_state(c,conn_state_connected);
  390.     break;
  391. case laddr_type_bnet:
  392. default:
  393.     /* We have to wait for an initial "magic" byte on bnet connections to
  394.              * tell us exactly what connection class we are dealing with.
  395.              */
  396.     break;
  397. }
  398.     }
  399.     return 0;
  400. }
  401. static int sd_udpinput(t_addr * const curr_laddr, t_laddr_info const * laddr_info, int ssocket, int usocket)
  402. {
  403.     int             err;
  404.     psock_t_socklen errlen;
  405.     t_packet *      upacket;
  406.     
  407.     err = 0;
  408.     errlen = sizeof(err);
  409.     if (psock_getsockopt(usocket,PSOCK_SOL_SOCKET,PSOCK_SO_ERROR,&err,&errlen)<0)
  410.     {
  411.         eventlog(eventlog_level_error,"sd_udpinput","[%d] unable to read socket error (psock_getsockopt: %s)",usocket,strerror(psock_errno()));
  412. return -1;
  413.     }
  414.     if (errlen && err) /* if it was an error, there is no packet to read */
  415.     {
  416. eventlog(eventlog_level_error,"sd_udpinput","[%d] async UDP socket error notification (psock_getsockopt: %s)",usocket,strerror(err));
  417. return -1;
  418.     }
  419.     if (!(upacket = packet_create(packet_class_udp)))
  420.     {
  421. eventlog(eventlog_level_error,"sd_udpinput","could not allocate raw packet for input");
  422. return -1;
  423.     }
  424.     
  425.     {
  426. struct sockaddr_in fromaddr;
  427. psock_t_socklen    fromlen;
  428. int                len;
  429. fromlen = sizeof(fromaddr);
  430. if ((len = psock_recvfrom(usocket,packet_get_raw_data_build(upacket,0),MAX_PACKET_SIZE,0,(struct sockaddr *)&fromaddr,&fromlen))<0)
  431. {
  432.     if (
  433. #ifdef PSOCK_EINTR
  434. psock_errno()!=PSOCK_EINTR &&
  435. #endif
  436. #ifdef PSOCK_EAGAIN
  437. psock_errno()!=PSOCK_EAGAIN &&
  438. #endif
  439. #ifdef PSOCK_EWOULDBLOCK
  440. psock_errno()!=PSOCK_EWOULDBLOCK &&
  441. #endif
  442. #ifdef PSOCK_ECONNRESET
  443. psock_errno()!=PSOCK_ECONNRESET && // this is a win2k/winxp issue
  444. // their socket implementation returns this value
  445. // although it shouldn't
  446. #endif
  447. 1)
  448. eventlog(eventlog_level_error,"sd_udpinput","could not recv UDP datagram (psock_recvfrom: %s)",strerror(psock_errno()));
  449.     packet_del_ref(upacket);
  450.     return -1;
  451. }
  452. if (fromaddr.sin_family!=PSOCK_AF_INET)
  453. {
  454.     eventlog(eventlog_level_error,"sd_udpinput","got UDP datagram with bad address family %d",(int)fromaddr.sin_family);
  455.     packet_del_ref(upacket);
  456.     return -1;
  457. }
  458. packet_set_size(upacket,len);
  459. if (hexstrm)
  460. {
  461.     char tempa[32];
  462.     
  463.     if (!addr_get_addr_str(curr_laddr,tempa,sizeof(tempa)))
  464. strcpy(tempa,"x.x.x.x:x");
  465.     fprintf(hexstrm,"%d: recv class=%s[0x%02x] type=%s[0x%04x] from=%s to=%s length=%un",
  466.     usocket,
  467.     packet_get_class_str(upacket),(unsigned int)packet_get_class(upacket),
  468.     packet_get_type_str(upacket,packet_dir_from_client),packet_get_type(upacket),
  469.     addr_num_to_addr_str(ntohl(fromaddr.sin_addr.s_addr),ntohs(fromaddr.sin_port)),
  470.     tempa,
  471.     packet_get_size(upacket));
  472.     hexdump(hexstrm,packet_get_raw_data(upacket,0),packet_get_size(upacket));
  473. }
  474. handle_udp_packet(usocket,ntohl(fromaddr.sin_addr.s_addr),ntohs(fromaddr.sin_port),upacket);
  475. packet_del_ref(upacket);
  476.     }
  477.     
  478.     return 0;
  479. }
  480. static int sd_tcpinput(t_connection * c)
  481. {
  482.     unsigned int currsize;
  483.     t_packet *   packet;
  484.     int  csocket = conn_get_socket(c);
  485.     
  486.     currsize = conn_get_in_size(c);
  487.     if (!queue_get_length((t_queue const * const *)conn_get_in_queue(c)))
  488.     {
  489. switch (conn_get_class(c))
  490. {
  491. case conn_class_init:
  492.     if (!(packet = packet_create(packet_class_init)))
  493.     {
  494. eventlog(eventlog_level_error,"sd_tcpinput","could not allocate init packet for input");
  495. return -1;
  496.     }
  497.     break;
  498.          case conn_class_d2cs_bnetd:
  499.             if (!(packet = packet_create(packet_class_d2cs_bnetd)))
  500.             {
  501.                 eventlog(eventlog_level_error,"server_process","could not allocate d2cs_bnetd packet");
  502.                 return -1;
  503.             }
  504.             break;
  505. case conn_class_bnet:
  506.     if (!(packet = packet_create(packet_class_bnet)))
  507.     {
  508. eventlog(eventlog_level_error,"sd_tcpinput","could not allocate bnet packet for input");
  509. return -1;
  510.     }
  511.     break;
  512. case conn_class_file:
  513.     switch(conn_get_state(c)) {
  514. case conn_state_pending_raw:
  515.     if (!(packet = packet_create(packet_class_raw)))
  516.     {
  517. eventlog(eventlog_level_error,"sd_tcpinput","could not allocate raw packet for input");
  518. return -1;
  519.     }
  520.     packet_set_size(packet, sizeof(t_client_war3113_file_req));
  521.     break;
  522. default:
  523.     if (!(packet = packet_create(packet_class_file)))
  524.     {
  525. eventlog(eventlog_level_error,"sd_tcpinput","could not allocate file packet for input");
  526. return -1;
  527.     }
  528.     break;
  529.     }
  530.     break;
  531. case conn_class_defer:
  532. case conn_class_bot:
  533. case conn_class_irc:
  534. case conn_class_telnet:
  535.     if (!(packet = packet_create(packet_class_raw)))
  536.     {
  537. eventlog(eventlog_level_error,"sd_tcpinput","could not allocate raw packet for input");
  538. return -1;
  539.     }
  540.     packet_set_size(packet,1); /* start by only reading one char */
  541.     break;
  542. case conn_class_auth:
  543.     if (!(packet = packet_create(packet_class_auth)))
  544.     {
  545. eventlog(eventlog_level_error,"sd_tcpinput","could not allocate auth packet for input");
  546. return -1;
  547.     }
  548.     break;
  549. case conn_class_w3route:
  550.     if (!(packet = packet_create(packet_class_w3route)))
  551.     {
  552. eventlog(eventlog_level_error,"sd_tcpinput","could not allocate w3route packet for input");
  553. return -1;
  554.     }
  555.     break;
  556. default:
  557.     eventlog(eventlog_level_error,"sd_tcpinput","[%d] connection has bad class (closing connection)",conn_get_socket(c));
  558.     // [quetzal] 20020808 - marking connection as "destroyed", memory will be freed later
  559. conn_set_state(c, conn_state_destroy);
  560.     return -2;
  561. }
  562. conn_push_inqueue(c,packet);
  563. packet_del_ref(packet);
  564. if (!queue_get_length((t_queue const * const *)conn_get_in_queue(c)))
  565.     return -1; /* push failed */
  566. currsize = 0;
  567.     }
  568.     
  569.     packet = conn_peek_inqueue(c);
  570.     switch (net_recv_packet(csocket,packet,&currsize))
  571.     {
  572.     case -1:
  573. eventlog(eventlog_level_debug,"sd_tcpinput","[%d] read FAILED (closing connection)",conn_get_socket(c));
  574. // [quetzal] 20020808 - marking connection as "destroyed", memory will be freed later
  575. conn_set_state(c, conn_state_destroy);
  576. return -2;
  577.     case 0: /* still working on it */
  578. /* eventlog(eventlog_level_debug,"sd_tcpinput","[%d] still reading "%s" packet (%u of %u bytes so far)",conn_get_socket(c),packet_get_class_str(packet),conn_get_in_size(c),packet_get_size(packet)); */
  579. conn_set_in_size(c,currsize);
  580. break;
  581.     case 1: /* done reading */
  582. switch (conn_get_class(c))
  583. {
  584. case conn_class_defer:
  585.     {
  586. unsigned char const * const temp=packet_get_raw_data_const(packet,0);
  587. eventlog(eventlog_level_debug,"sd_tcpinput","[%d] got first packet byte %02x",conn_get_socket(c),(unsigned int)temp[0]);
  588. if (temp[0]==(unsigned char)0xff) /* HACK: thankfully all bnet packet types end with ff */
  589. {
  590.     conn_set_class(c,conn_class_bnet);
  591.     conn_set_in_size(c,currsize);
  592.     packet_set_class(packet,packet_class_bnet);
  593.     eventlog(eventlog_level_debug,"sd_tcpinput","[%d] defered connection class is bnet",conn_get_socket(c));
  594. } else {
  595.     conn_set_class(c,conn_class_auth);
  596.     conn_set_in_size(c,currsize);
  597.     packet_set_class(packet,packet_class_auth);
  598.     eventlog(eventlog_level_debug,"sd_tcpinput","[%d] defered connection class is auth",conn_get_socket(c));
  599. }
  600.     }
  601.     break;
  602. case conn_class_bot:
  603. case conn_class_telnet:
  604.     if (currsize<MAX_PACKET_SIZE) /* if we overflow, we can't wait for the end of the line.
  605.      handle_*_packet() should take care of it */
  606.     {
  607. char const * const temp=packet_get_raw_data_const(packet,0);
  608. if ((temp[currsize-1]=='03')||(temp[currsize-1]=='04')) {
  609.     /* we have to ignore these special characters, since 
  610.      * some bots even send them after login (eg. UltimateBot)
  611.      */
  612.     currsize--;
  613.     break;  
  614. }
  615. if (temp[currsize-1]!='r' && temp[currsize-1]!='n')
  616. {
  617.     conn_set_in_size(c,currsize);
  618.     packet_set_size(packet,currsize+1);
  619.     break; /* no end of line, get another char */
  620. }
  621.     }
  622.     /* got a complete line or overflow... fall through */
  623. default:
  624.     packet = conn_pull_inqueue(c);
  625.     if (hexstrm)
  626.     {
  627. fprintf(hexstrm,"%d: recv class=%s[0x%02x] type=%s[0x%04x] length=%un",
  628. csocket,
  629. packet_get_class_str(packet),(unsigned int)packet_get_class(packet),
  630. packet_get_type_str(packet,packet_dir_from_client),packet_get_type(packet),
  631. packet_get_size(packet));
  632. hexdump(hexstrm,packet_get_raw_data_const(packet,0),packet_get_size(packet));
  633.     }
  634.     
  635.     if (conn_get_class(c)==conn_class_bot ||
  636. conn_get_class(c)==conn_class_telnet) /* NUL terminate the line to make life easier */
  637.     {
  638. char * const temp=packet_get_raw_data(packet,0);
  639. if (temp[currsize-1]=='r' || temp[currsize-1]=='n')
  640.     temp[currsize-1] = ''; /* have to do it here instead of above so everything
  641. is intact for the hexdump */
  642.     }
  643.     
  644.     {
  645. int ret;
  646. switch (conn_get_class(c))
  647. {
  648. case conn_class_init:
  649.     ret = handle_init_packet(c,packet);
  650.     break;
  651. case conn_class_bnet:
  652.     ret = handle_bnet_packet(c,packet);
  653.     break;
  654. case conn_class_d2cs_bnetd:
  655. ret = handle_d2cs_packet(c,packet);
  656. break;
  657. case conn_class_bot:
  658.     ret = handle_bot_packet(c,packet);
  659.     break;
  660. case conn_class_telnet:
  661.     ret = handle_telnet_packet(c,packet);
  662.     break;
  663. case conn_class_file:
  664.     ret = handle_file_packet(c,packet);
  665.     break;
  666. case conn_class_auth:
  667.     ret = handle_auth_packet(c,packet);
  668.     break;
  669. case conn_class_irc:
  670.     ret = handle_irc_packet(c,packet);
  671.     break;
  672. case conn_class_w3route:
  673.     ret = handle_w3route_packet(c,packet);
  674.     break;
  675. default:
  676.     eventlog(eventlog_level_error,"sd_tcpinput","[%d] bad packet class %d (closing connection)",conn_get_socket(c),(int)packet_get_class(packet));
  677.     ret = -1;
  678. }
  679. packet_del_ref(packet);
  680. if (ret<0)
  681. {
  682. // [quetzal] 20020808 - marking connection as "destroyed", memory will be freed later
  683. conn_set_state(c, conn_state_destroy);
  684.     return -2;
  685. }
  686.     }
  687.     
  688.     conn_set_in_size(c,0);
  689. }
  690.     }
  691.     
  692.     return 0;
  693. }
  694. static int sd_tcpoutput(t_connection * c)
  695. {
  696.     unsigned int currsize;
  697.     unsigned int totsize;
  698.     t_packet *   packet;
  699.     int  csocket = conn_get_socket(c);
  700.     
  701.     totsize = 0;
  702.     for (;;)
  703.     {
  704. currsize = conn_get_out_size(c);
  705.         if ((packet = conn_peek_outqueue(c)) == NULL)
  706.             return -2;
  707. switch (net_send_packet(csocket,packet,&currsize)) /* avoid warning */
  708. {
  709. case -1:
  710. // [quetzal] 20020808 - marking connection as "destroyed", memory will be freed later
  711. conn_set_state(c, conn_state_destroy);
  712.     return -2;
  713.     
  714. case 0: /* still working on it */
  715.     conn_set_out_size(c,currsize);
  716.     return 0; /* bail out */
  717.     
  718. case 1: /* done sending */
  719.     if (hexstrm)
  720.     {
  721. fprintf(hexstrm,"%d: send class=%s[0x%02x] type=%s[0x%04x] length=%un",
  722. csocket,
  723. packet_get_class_str(packet),(unsigned int)packet_get_class(packet),
  724. packet_get_type_str(packet,packet_dir_from_server),packet_get_type(packet),
  725. packet_get_size(packet));
  726. hexdump(hexstrm,packet_get_raw_data(packet,0),packet_get_size(packet));
  727.     }
  728.     packet = conn_pull_outqueue(c);
  729.     packet_del_ref(packet);
  730.     conn_set_out_size(c,0);
  731.     
  732.     /* stop at about 2KB (or until out of packets or EWOULDBLOCK) */
  733.     if (totsize>2048 || queue_get_length((t_queue const * const *)conn_get_out_queue(c))<1)
  734. return 0;
  735.     totsize += currsize;
  736.     break;
  737. }
  738.     }
  739.     
  740.     /* not reached */
  741. }
  742. extern void server_set_name(void)
  743. {
  744.     char temp[250];
  745.     char const * sn;
  746. #ifdef HAVE_GETHOSTBYNAME
  747.     struct hostent *   hp;
  748. #endif
  749.     if (server_name) {
  750. free((void *)server_name); /* avoid warning */
  751. server_name = NULL;
  752.     }
  753.     
  754.     sn = prefs_get_servername();
  755.     if ((!sn)||(sn[0]=='')) {
  756.      if (gethostname(temp,sizeof(temp))<0) {
  757. #ifdef WIN32
  758.     sprintf(temp,"localhost");
  759. #else
  760.     eventlog(eventlog_level_error,"server_set_name","could not get hostname: %s",strerror(errno));
  761.     return;
  762. #endif
  763.      }
  764. #ifdef HAVE_GETHOSTBYNAME
  765.      hp = gethostbyname(temp);
  766.      if (!hp || !hp->h_name) {
  767. #endif
  768.          server_name = strdup(temp);
  769. #ifdef HAVE_GETHOSTBYNAME
  770.      } else {
  771.     int i=0;
  772.     if (strchr(hp->h_name,'.'))
  773.      /* Default name is already a FQDN */
  774.      server_name = strdup(hp->h_name);
  775.     /* ... if not we have to examine the aliases */
  776.     while (!server_name && hp->h_aliases && hp->h_aliases[i]) {
  777. if (strchr(hp->h_aliases[i],'.'))
  778.     server_name = strdup(hp->h_aliases[i]);
  779.      i++;
  780.     }
  781.     if (!server_name)
  782. /* Fall back to default name which might not be a FQDN */
  783.           server_name = strdup(hp->h_name);
  784.      }
  785. #endif
  786.     } else {
  787. server_name = strdup(sn);
  788.     }
  789.     eventlog(eventlog_level_info,"server_set_name","set servername to "%s"",server_name);
  790. }
  791. extern char const * server_get_name(void)
  792. {
  793.     if (!server_name)
  794.      return "(null)"; /* avoid crashes */
  795.     else
  796.      return server_name;
  797. }
  798. extern void server_clear_name(void)
  799. {
  800.     if (server_name) {
  801. free((void *)server_name); /* avoid warning */
  802.         server_name = NULL;
  803.     }
  804. }
  805. static void _server_setup_listensock(t_addrlist *laddrs)
  806. {
  807.     t_elem const *  acurr;
  808.     t_addr *        curr_laddr;
  809.     t_laddr_info *  laddr_info;
  810.     LIST_TRAVERSE_CONST(laddrs,acurr)
  811.     {
  812. curr_laddr = elem_get_data(acurr);
  813. if (!(laddr_info = addr_get_data(curr_laddr).p))
  814. {
  815.     eventlog(eventlog_level_error,"server_process","NULL address info");
  816.     continue;
  817. }
  818. if (laddr_info->ssocket!=-1) fdwatch_add_fd(laddr_info->ssocket, fdwatch_type_read, handle_accept, curr_laddr);
  819. if (laddr_info->usocket!=-1) fdwatch_add_fd(laddr_info->usocket, fdwatch_type_read, handle_udp, curr_laddr);
  820.     }
  821. }
  822. static int handle_accept(void *data, t_fdwatch_type rw)
  823. {
  824.     t_laddr_info *laddr_info = addr_get_data((t_addr *)data).p;
  825.     return sd_accept((t_addr *)data, laddr_info, laddr_info->ssocket, laddr_info->usocket);
  826. }
  827. static int handle_udp(void *data, t_fdwatch_type rw)
  828. {
  829.     t_laddr_info *laddr_info = addr_get_data((t_addr *)data).p;
  830.     return sd_udpinput((t_addr *)data, laddr_info, laddr_info->ssocket, laddr_info->usocket);
  831. }
  832. static int handle_tcp(void *data, t_fdwatch_type rw)
  833. {
  834.     switch(rw) {
  835. case fdwatch_type_read: return sd_tcpinput((t_connection *)data);
  836. case fdwatch_type_write: return sd_tcpoutput((t_connection *)data);
  837. default:
  838.     return -1;
  839.     }
  840. }
  841. extern int server_process(void)
  842. {
  843.     t_addrlist *    laddrs;
  844.     t_addr *        curr_laddr;
  845.     t_addr_data     laddr_data;
  846.     t_laddr_info *  laddr_info;
  847.     time_t          prev_exittime, prev_savetime, track_time;
  848.     time_t          war3_ladder_updatetime;
  849.     time_t          output_updatetime;
  850.     int             syncdelta;
  851.     t_connection *  c;
  852.     t_elem const *  acurr;
  853.     t_elem const *  ccurr;
  854. #ifdef DO_POSIXSIG
  855.     sigset_t        block_set;
  856.     sigset_t        save_set;
  857. #endif
  858.     unsigned int    count;
  859.     
  860.     if (psock_init()<0)
  861.     {
  862. eventlog(eventlog_level_error,"server_process","could not initialize socket functions");
  863. return -1;
  864.     }
  865.     
  866.     /* Start with the Battle.net address list */
  867.     if (!(laddrs = addrlist_create(prefs_get_bnetdserv_addrs(),INADDR_ANY,BNETD_SERV_PORT)))
  868.     {
  869. eventlog(eventlog_level_error,"server_process","could not create %s server address list from "%s"",laddr_type_get_str(laddr_type_bnet),prefs_get_bnetdserv_addrs());
  870. return -1;
  871.     }
  872.     /* Mark all these laddrs for being classic Battle.net service */
  873.     LIST_TRAVERSE_CONST(laddrs,acurr)
  874.     {
  875. curr_laddr = elem_get_data(acurr);
  876. if (addr_get_data(curr_laddr).p)
  877.     continue;
  878. if (!(laddr_info = malloc(sizeof(t_laddr_info))))
  879. {
  880.     eventlog(eventlog_level_error,"server_process","could not create %s address info (malloc: %s)",laddr_type_get_str(laddr_type_bnet),strerror(psock_errno()));
  881.     goto error_addr_list;
  882. }
  883.         laddr_info->usocket = -1;
  884.         laddr_info->ssocket = -1;
  885.         laddr_info->type = laddr_type_bnet;
  886. laddr_data.p = laddr_info;
  887.         if (addr_set_data(curr_laddr,laddr_data)<0)
  888. {
  889.     eventlog(eventlog_level_error,"server_process","could not set address data");
  890.     if (laddr_info->usocket!=-1)
  891.     {
  892. psock_close(laddr_info->usocket);
  893. laddr_info->usocket = -1;
  894.     }
  895.     if (laddr_info->ssocket!=-1)
  896.     {
  897. psock_close(laddr_info->ssocket);
  898. laddr_info->ssocket = -1;
  899.     }
  900.     goto error_poll;
  901. }
  902.     }
  903.     
  904.     /* Append list of addresses to listen for IRC connections */
  905.     if (addrlist_append(laddrs,prefs_get_irc_addrs(),INADDR_ANY,BNETD_IRC_PORT)<0)
  906.     {
  907. eventlog(eventlog_level_error,"server_process","could not create %s server address list from "%s"",laddr_type_get_str(laddr_type_irc),prefs_get_irc_addrs());
  908. goto error_addr_list;
  909.     }
  910.     /* Mark all new laddrs for being IRC service */
  911.     LIST_TRAVERSE_CONST(laddrs,acurr)
  912.     { 
  913. curr_laddr = elem_get_data(acurr);
  914. if (addr_get_data(curr_laddr).p)
  915.     continue;
  916. if (!(laddr_info = malloc(sizeof(t_laddr_info))))
  917. {
  918.     eventlog(eventlog_level_error,"server_process","could not create %s address info (malloc: %s)",laddr_type_get_str(laddr_type_irc),strerror(psock_errno()));
  919.     goto error_addr_list;
  920. }
  921.         laddr_info->usocket = -1;
  922.         laddr_info->ssocket = -1;
  923.         laddr_info->type = laddr_type_irc;
  924. laddr_data.p = laddr_info;
  925. if (addr_set_data(curr_laddr,laddr_data)<0)
  926. {
  927.     eventlog(eventlog_level_error,"server_process","could not set address data");
  928.     if (laddr_info->usocket!=-1)
  929.     {
  930. psock_close(laddr_info->usocket);
  931. laddr_info->usocket = -1;
  932.     }
  933.     if (laddr_info->ssocket!=-1)
  934.     {
  935. psock_close(laddr_info->ssocket);
  936. laddr_info->ssocket = -1;
  937.     }
  938.     goto error_poll;
  939. }
  940.     }
  941.     /* Append list of addresses to listen for W3ROUTE connections */
  942.     if (addrlist_append(laddrs,prefs_get_w3route_addr(),INADDR_ANY,BNETD_W3ROUTE_PORT)<0)
  943.     {
  944. eventlog(eventlog_level_error,"server_process","could not create %s server address list from "%s"",laddr_type_get_str(laddr_type_w3route),prefs_get_w3route_addr());
  945. goto error_addr_list;
  946.     }
  947.     /* Mark all new laddrs for being W3ROUTE service */
  948.     LIST_TRAVERSE_CONST(laddrs,acurr)
  949.     { 
  950. curr_laddr = elem_get_data(acurr);
  951. if (addr_get_data(curr_laddr).p)
  952.     continue;
  953. if (!(laddr_info = malloc(sizeof(t_laddr_info))))
  954. {
  955.     eventlog(eventlog_level_error,"server_process","could not create %s address info (malloc: %s)",laddr_type_get_str(laddr_type_w3route),strerror(psock_errno()));
  956.     goto error_addr_list;
  957. }
  958.         laddr_info->usocket = -1;
  959.         laddr_info->ssocket = -1;
  960.         laddr_info->type = laddr_type_w3route;
  961. laddr_data.p = laddr_info;
  962. if (addr_set_data(curr_laddr,laddr_data)<0)
  963. {
  964.     eventlog(eventlog_level_error,"server_process","could not set address data");
  965.     if (laddr_info->usocket!=-1)
  966.     {
  967. psock_close(laddr_info->usocket);
  968. laddr_info->usocket = -1;
  969.     }
  970.     if (laddr_info->ssocket!=-1)
  971.     {
  972. psock_close(laddr_info->ssocket);
  973. laddr_info->ssocket = -1;
  974.     }
  975.     goto error_poll;
  976. }
  977.     }
  978.     
  979.     /* Append list of addresses to listen for telnet connections */
  980.     if (addrlist_append(laddrs,prefs_get_telnet_addrs(),INADDR_ANY,BNETD_TELNET_PORT)<0)
  981.     {
  982. eventlog(eventlog_level_error,"server_process","could not create %s server address list from "%s"",laddr_type_get_str(laddr_type_telnet),prefs_get_telnet_addrs());
  983. goto error_addr_list;
  984.     }
  985.     /* Mark all new laddrs for being telnet service */
  986.     LIST_TRAVERSE_CONST(laddrs,acurr)
  987.     { 
  988. curr_laddr = elem_get_data(acurr);
  989. if (addr_get_data(curr_laddr).p)
  990.     continue;
  991. if (!(laddr_info = malloc(sizeof(t_laddr_info))))
  992. {
  993.     eventlog(eventlog_level_error,"server_process","could not create %s address info (malloc: %s)",laddr_type_get_str(laddr_type_telnet),strerror(psock_errno()));
  994.     goto error_addr_list;
  995. }
  996.         laddr_info->usocket = -1;
  997.         laddr_info->ssocket = -1;
  998.         laddr_info->type = laddr_type_telnet;
  999. laddr_data.p = laddr_info;
  1000. if (addr_set_data(curr_laddr,laddr_data)<0)
  1001. {
  1002.     eventlog(eventlog_level_error,"server_process","could not set address data");
  1003.     if (laddr_info->usocket!=-1)
  1004.     {
  1005. psock_close(laddr_info->usocket);
  1006. laddr_info->usocket = -1;
  1007.     }
  1008.     if (laddr_info->ssocket!=-1)
  1009.     {
  1010. psock_close(laddr_info->ssocket);
  1011. laddr_info->ssocket = -1;
  1012.     }
  1013.     goto error_poll;
  1014. }
  1015.     }
  1016.     
  1017.     if (fdwatch_init()) {
  1018. eventlog(eventlog_level_error, __FUNCTION__, "could not initilized fdwatch layer");
  1019. goto error_poll;
  1020.     }
  1021.     LIST_TRAVERSE_CONST(laddrs,acurr)
  1022.     {
  1023. curr_laddr = elem_get_data(acurr);
  1024. if (!(laddr_info = addr_get_data(curr_laddr).p))
  1025. {
  1026.     eventlog(eventlog_level_error,"server_process","NULL address info");
  1027.     goto error_poll;
  1028. }
  1029. if ((laddr_info->ssocket = psock_socket(PSOCK_PF_INET,PSOCK_SOCK_STREAM,PSOCK_IPPROTO_TCP))<0)
  1030. {
  1031.     eventlog(eventlog_level_error,"server_process","could not create a %s listening socket (psock_socket: %s)",laddr_type_get_str(laddr_info->type),strerror(psock_errno()));
  1032.     goto error_poll;
  1033. }
  1034. if (laddr_info->ssocket >= fdw_maxfd)
  1035. {
  1036.     eventlog(eventlog_level_error,"server_process","%s TCP socket is beyond range allowed by FD_SETSIZE for select() (%d>=%d)",laddr_type_get_str(laddr_info->type),laddr_info->ssocket,fdw_maxfd);
  1037.     psock_close(laddr_info->ssocket);
  1038.     laddr_info->ssocket = -1;
  1039.     goto error_poll;
  1040. }
  1041. if (laddr_info->type==laddr_type_bnet)
  1042. {
  1043.     if ((laddr_info->usocket = psock_socket(PSOCK_PF_INET,PSOCK_SOCK_DGRAM,PSOCK_IPPROTO_UDP))<0)
  1044.     {
  1045. eventlog(eventlog_level_error,"server_process","could not create UDP socket (psock_socket: %s)",strerror(psock_errno()));
  1046. psock_close(laddr_info->ssocket);
  1047. laddr_info->ssocket = -1;
  1048. goto error_poll;
  1049.     }
  1050.     if (laddr_info->usocket >= fdw_maxfd)
  1051.     {
  1052. eventlog(eventlog_level_error,"server_process","%s UDP socket is beyond range allowed by FD_SETSIZE for select() (%d>=%d)",laddr_type_get_str(laddr_info->type),laddr_info->usocket,fdw_maxfd);
  1053. psock_close(laddr_info->usocket);
  1054. laddr_info->usocket = -1;
  1055. psock_close(laddr_info->ssocket);
  1056. laddr_info->ssocket = -1;
  1057. goto error_poll;
  1058.     }
  1059. }
  1060. {
  1061.     int val;
  1062.     
  1063.     if (laddr_info->ssocket!=-1)
  1064.     {
  1065. val = 1;
  1066. if (psock_setsockopt(laddr_info->ssocket,PSOCK_SOL_SOCKET,PSOCK_SO_REUSEADDR,&val,(psock_t_socklen)sizeof(int))<0)
  1067.     eventlog(eventlog_level_error,"server_process","could not set option SO_REUSEADDR on %s socket %d (psock_setsockopt: %s)",laddr_type_get_str(laddr_info->type),laddr_info->usocket,strerror(psock_errno()));
  1068. /* not a fatal error... */
  1069.     }
  1070.     
  1071.     if (laddr_info->usocket!=-1)
  1072.     {
  1073. val = 1;
  1074. if (psock_setsockopt(laddr_info->usocket,PSOCK_SOL_SOCKET,PSOCK_SO_REUSEADDR,&val,(psock_t_socklen)sizeof(int))<0)
  1075.     eventlog(eventlog_level_error,"server_process","could not set option SO_REUSEADDR on %s socket %d (psock_setsockopt: %s)",laddr_type_get_str(laddr_info->type),laddr_info->usocket,strerror(psock_errno()));
  1076. /* not a fatal error... */
  1077.     }
  1078. }
  1079. {
  1080.     char               tempa[32];
  1081.     struct sockaddr_in saddr;
  1082.     
  1083.     if (laddr_info->ssocket!=-1)
  1084.     {
  1085. memset(&saddr,0,sizeof(saddr));
  1086. saddr.sin_family = PSOCK_AF_INET;
  1087. saddr.sin_port = htons(addr_get_port(curr_laddr));
  1088. saddr.sin_addr.s_addr = htonl(addr_get_ip(curr_laddr));
  1089. if (psock_bind(laddr_info->ssocket,(struct sockaddr *)&saddr,(psock_t_socklen)sizeof(saddr))<0)
  1090. {
  1091.     if (!addr_get_addr_str(curr_laddr,tempa,sizeof(tempa)))
  1092. strcpy(tempa,"x.x.x.x:x");
  1093.     eventlog(eventlog_level_error,"server_process","could not bind %s socket to address %s TCP (psock_bind: %s)",laddr_type_get_str(laddr_info->type),tempa,strerror(psock_errno()));
  1094.     goto error_poll;
  1095. }
  1096.     }
  1097.     
  1098.     if (laddr_info->usocket!=-1)
  1099.     {
  1100. memset(&saddr,0,sizeof(saddr));
  1101. saddr.sin_family = PSOCK_AF_INET;
  1102. saddr.sin_port = htons(addr_get_port(curr_laddr));
  1103. saddr.sin_addr.s_addr = htonl(addr_get_ip(curr_laddr));
  1104. if (psock_bind(laddr_info->usocket,(struct sockaddr *)&saddr,(psock_t_socklen)sizeof(saddr))<0)
  1105. {
  1106.     if (!addr_get_addr_str(curr_laddr,tempa,sizeof(tempa)))
  1107. strcpy(tempa,"x.x.x.x:x");
  1108.     eventlog(eventlog_level_error,"server_process","could not bind %s socket to address %s UDP (psock_bind: %s)",laddr_type_get_str(laddr_info->type),tempa,strerror(psock_errno()));
  1109.     goto error_poll;
  1110. }
  1111.     }
  1112.     
  1113.     if (laddr_info->ssocket!=-1)
  1114.     {
  1115. /* tell socket to listen for connections */
  1116. if (psock_listen(laddr_info->ssocket,LISTEN_QUEUE)<0)
  1117. {
  1118.     eventlog(eventlog_level_error,"server_process","could not set %s socket %d to listen (psock_listen: %s)",laddr_type_get_str(laddr_info->type),laddr_info->ssocket,strerror(psock_errno()));
  1119.     goto error_poll;
  1120. }
  1121.     }
  1122.     
  1123.     if (!addr_get_addr_str(curr_laddr,tempa,sizeof(tempa)))
  1124. strcpy(tempa,"x.x.x.x:x");
  1125.     eventlog(eventlog_level_info,"server_process","listening for %s connections on %s TCP",laddr_type_get_str(laddr_info->type),tempa);
  1126. }
  1127. if (laddr_info->ssocket!=-1)
  1128.     if (psock_ctl(laddr_info->ssocket,PSOCK_NONBLOCK)<0)
  1129. eventlog(eventlog_level_error,"server_process","could not set %s TCP listen socket to non-blocking mode (psock_ctl: %s)",laddr_type_get_str(laddr_info->type),strerror(psock_errno()));
  1130. if (laddr_info->usocket!=-1)
  1131.     if (psock_ctl(laddr_info->usocket,PSOCK_NONBLOCK)<0)
  1132. eventlog(eventlog_level_error,"server_process","could not set %s UDP socket to non-blocking mode (psock_ctl: %s)",laddr_type_get_str(laddr_info->type),strerror(psock_errno()));
  1133.     }
  1134.     
  1135.     /* setup signal handlers */
  1136.     prev_exittime = sigexittime;
  1137.     
  1138. #ifdef DO_POSIXSIG
  1139.     if (sigemptyset(&save_set)<0)
  1140.     {
  1141. eventlog(eventlog_level_error,"server_process","could not initialize signal set (sigemptyset: %s)",strerror(errno));
  1142. goto error_poll;
  1143.     }
  1144.     if (sigemptyset(&block_set)<0)
  1145.     {
  1146. eventlog(eventlog_level_error,"server_process","could not initialize signal set (sigemptyset: %s)",strerror(errno));
  1147. goto error_poll;
  1148.     }
  1149.     if (sigaddset(&block_set,SIGINT)<0)
  1150.     {
  1151. eventlog(eventlog_level_error,"server_process","could not add signal to set (sigemptyset: %s)",strerror(errno));
  1152. goto error_poll;
  1153.     }
  1154.     if (sigaddset(&block_set,SIGHUP)<0)
  1155.     {
  1156. eventlog(eventlog_level_error,"server_process","could not add signal to set (sigemptyset: %s)",strerror(errno));
  1157. goto error_poll;
  1158.     }
  1159.     if (sigaddset(&block_set,SIGTERM)<0)
  1160.     {
  1161. eventlog(eventlog_level_error,"server_process","could not add signal to set (sigemptyset: %s)",strerror(errno));
  1162. goto error_poll;
  1163.     }
  1164.     if (sigaddset(&block_set,SIGUSR1)<0)
  1165.     {
  1166. eventlog(eventlog_level_error,"server_process","could not add signal to set (sigemptyset: %s)",strerror(errno));
  1167. goto error_poll;
  1168.     }
  1169.     if (sigaddset(&block_set,SIGUSR2)<0)
  1170.     {
  1171. eventlog(eventlog_level_error,"server_process","could not add signal to set (sigemptyset: %s)",strerror(errno));
  1172. goto error_poll;
  1173.     }
  1174.     if (sigaddset(&block_set,SIGALRM)<0)
  1175.     {
  1176. eventlog(eventlog_level_error,"server_process","could not add signal to set (sigemptyset: %s)",strerror(errno));
  1177. goto error_poll;
  1178.     }
  1179.     
  1180.     {
  1181. struct sigaction quit_action;
  1182. struct sigaction restart_action;
  1183. struct sigaction save_action;
  1184. struct sigaction pipe_action;
  1185. # ifdef USE_CHECK_ALLOC
  1186. struct sigaction memstat_action;
  1187. # endif
  1188. #ifdef HAVE_SETITIMER
  1189. struct sigaction timer_action;
  1190. #endif
  1191. quit_action.sa_handler = quit_sig_handle;
  1192. if (sigemptyset(&quit_action.sa_mask)<0)
  1193.     eventlog(eventlog_level_error,"server_process","could not initialize signal set (sigemptyset: %s)",strerror(errno));
  1194. quit_action.sa_flags = SA_RESTART;
  1195. restart_action.sa_handler = restart_sig_handle;
  1196. if (sigemptyset(&restart_action.sa_mask)<0)
  1197.     eventlog(eventlog_level_error,"server_process","could not initialize signal set (sigemptyset: %s)",strerror(errno));
  1198. restart_action.sa_flags = SA_RESTART;
  1199. save_action.sa_handler = save_sig_handle;
  1200. if (sigemptyset(&save_action.sa_mask)<0)
  1201.     eventlog(eventlog_level_error,"server_process","could not initialize signal set (sigemptyset: %s)",strerror(errno));
  1202. save_action.sa_flags = SA_RESTART;
  1203. # ifdef USE_CHECK_ALLOC
  1204. memstat_action.sa_handler = memstat_sig_handle;
  1205. if (sigemptyset(&memstat_action.sa_mask)<0)
  1206.     eventlog(eventlog_level_error,"server_process","could not initialize signal set (sigemptyset: %s)",strerror(errno));
  1207. memstat_action.sa_flags = SA_RESTART;
  1208. # endif
  1209. pipe_action.sa_handler = pipe_sig_handle;
  1210. if (sigemptyset(&pipe_action.sa_mask)<0)
  1211.     eventlog(eventlog_level_error,"server_process","could not initialize signal set (sigemptyset: %s)",strerror(errno));
  1212. pipe_action.sa_flags = SA_RESTART;
  1213. #ifdef HAVE_SETITIMER
  1214. timer_action.sa_handler = timer_sig_handle;
  1215. if (sigemptyset(&timer_action.sa_mask)<0)
  1216.     eventlog(eventlog_level_error,"server_process","could not initialize signal set (sigemptyset: %s)",strerror(errno));
  1217. timer_action.sa_flags = SA_RESTART;
  1218. #endif /* HAVE_SETITIMER */
  1219. if (sigaction(SIGINT,&quit_action,NULL)<0) /* control-c */
  1220.     eventlog(eventlog_level_error,"server_process","could not set SIGINT signal handler (sigaction: %s)",strerror(errno));
  1221. if (sigaction(SIGHUP,&restart_action,NULL)<0)
  1222.     eventlog(eventlog_level_error,"server_process","could not set SIGHUP signal handler (sigaction: %s)",strerror(errno));
  1223. if (sigaction(SIGTERM,&quit_action,NULL)<0)
  1224.     eventlog(eventlog_level_error,"server_process","could not set SIGTERM signal handler (sigaction: %s)",strerror(errno));
  1225. if (sigaction(SIGUSR1,&save_action,NULL)<0)
  1226.     eventlog(eventlog_level_error,"server_process","could not set SIGUSR1 signal handler (sigaction: %s)",strerror(errno));
  1227. # ifdef USE_CHECK_ALLOC
  1228. if (sigaction(SIGUSR2,&memstat_action,NULL)<0)
  1229.     eventlog(eventlog_level_error,"server_process","could not set SIGUSR2 signal handler (sigaction: %s)",strerror(errno));
  1230. # endif
  1231. if (sigaction(SIGPIPE,&pipe_action,NULL)<0)
  1232.     eventlog(eventlog_level_error,"server_process","could not set SIGPIPE signal handler (sigaction: %s)",strerror(errno));
  1233. #ifdef HAVE_SETITIMER
  1234. /* setup asynchronus timestamp update timer */
  1235. if (sigaction(SIGALRM,&timer_action,NULL)<0)
  1236.     eventlog(eventlog_level_error,"server_process","could not set SIGALRM signal handler (sigaction: %s)",strerror(errno));
  1237. {
  1238.     struct itimerval it;
  1239.     it.it_interval.tv_sec = BNETD_JIFFIES / 1000;
  1240.     it.it_interval.tv_usec = BNETD_JIFFIES % 1000;
  1241.     it.it_value.tv_sec = BNETD_JIFFIES / 1000;
  1242.     it.it_value.tv_usec = BNETD_JIFFIES % 1000;
  1243.     if (setitimer(ITIMER_REAL, &it, NULL)) {
  1244. eventlog(eventlog_level_fatal, __FUNCTION__, "failed to set timers (setitimer(): %s)", strerror(errno));
  1245. goto error_poll;
  1246.     }
  1247. }
  1248. #endif
  1249.     }
  1250. #endif
  1251.     /* setup listening sockets */
  1252.     _server_setup_listensock(laddrs);
  1253.     syncdelta = prefs_get_user_sync_timer();
  1254.     track_time = time(NULL)-prefs_get_track();
  1255.     starttime=prev_savetime = time(NULL);
  1256.     war3_ladder_updatetime  = time(NULL)-prefs_get_war3_ladder_update_secs();
  1257.     output_updatetime = time(NULL)-prefs_get_output_update_secs();
  1258.     count = 0;
  1259.     
  1260.     for (;;)
  1261.     {
  1262. #ifdef WIN32
  1263. # ifndef WIN32_GUI
  1264. if (kbhit() && getch()=='q')
  1265.     server_quit_wraper();
  1266. # endif
  1267. if (g_ServiceStatus == 0) server_quit_wraper();
  1268. while (g_ServiceStatus == 2) Sleep(1000);
  1269. #endif
  1270. #ifdef DO_POSIXSIG
  1271. if (sigprocmask(SIG_SETMASK,&save_set,NULL)<0)
  1272.     eventlog(eventlog_level_error,"server_process","could not unblock signals");
  1273. /* receive signals here */
  1274. if (sigprocmask(SIG_SETMASK,&block_set,NULL)<0)
  1275.     eventlog(eventlog_level_error,"server_process","could not block signals");
  1276. #else
  1277. #endif
  1278. if (got_epipe)
  1279. {
  1280.     got_epipe = 0;
  1281.     eventlog(eventlog_level_info,"server_process","handled SIGPIPE");
  1282. }
  1283. #if !defined(DO_POSIXSIG) || !defined(HAVE_SETITIMER)
  1284. /* if no DO_POSIXSIG or no HAVE_SETITIMER so we must read timestamp each loop */
  1285. time(&now);
  1286. #endif
  1287. curr_exittime = sigexittime;
  1288. if (curr_exittime && (curr_exittime<=now || connlist_get_length()<1))
  1289. {
  1290.     eventlog(eventlog_level_info,"server_process","the server is shutting down (%d connections left)",connlist_get_length());
  1291.          clanlist_save();
  1292.     accountlist_save(0, NULL);
  1293.     break;
  1294. }
  1295. if (prev_exittime!=curr_exittime)
  1296. {
  1297.     t_message *  message;
  1298.     char const * tstr;
  1299.     
  1300.     if (curr_exittime!=0)
  1301.     {
  1302. char text[29+256+2+32+24+1]; /* "The ... in " + time + " (" num + " connection ...)." + NUL */
  1303.         
  1304. tstr = seconds_to_timestr(curr_exittime-now);
  1305. sprintf(text,"The server will shut down in %s (%d connections remaining).",tstr,connlist_get_length());
  1306.          if ((message = message_create(message_type_error,NULL,NULL,text)))
  1307. {
  1308.     message_send_all(message);
  1309.     message_destroy(message);
  1310. }
  1311. eventlog(eventlog_level_info,"server_process","the server will shut down in %s (%d connections remaining)",tstr,connlist_get_length());
  1312.     }
  1313.     else
  1314.     {
  1315. if ((message = message_create(message_type_error,NULL,NULL,"Server shutdown has been canceled.")))
  1316. {
  1317.     message_send_all(message);
  1318.     message_destroy(message);
  1319. }
  1320. eventlog(eventlog_level_info,"server_process","server shutdown canceled");
  1321.     }
  1322. }
  1323. prev_exittime = curr_exittime;
  1324. if (syncdelta && prev_savetime+(time_t)syncdelta<=now)
  1325. {
  1326.     if (syncdelta > 0) { /* do this stuff only first step of save */
  1327.      clanlist_save();
  1328.          gamelist_check_voidgame();
  1329.     }
  1330.     accountlist_save(prefs_get_user_sync_timer(), &syncdelta);
  1331.     prev_savetime = now;
  1332. }
  1333. if (prefs_get_track() && track_time+(time_t)prefs_get_track()<=now)
  1334. {
  1335.     track_time = now;
  1336.     tracker_send_report(laddrs);
  1337. }
  1338. if (prefs_get_war3_ladder_update_secs() && war3_ladder_updatetime+(time_t)prefs_get_war3_ladder_update_secs()<=now)
  1339. {
  1340.            war3_ladder_updatetime = now;
  1341.        ladders_write_to_file();
  1342. }
  1343. if (prefs_get_output_update_secs() && output_updatetime+(time_t)prefs_get_output_update_secs()<=now)
  1344. {
  1345.            output_updatetime = now;
  1346.    output_write_to_file();
  1347. }
  1348. if (do_save)
  1349. {
  1350.     eventlog(eventlog_level_info,"server_process","saving accounts due to signal");
  1351.          clanlist_save();
  1352.     accountlist_save(0, NULL);
  1353.     do_save = 0;
  1354. }
  1355. if (do_restart)
  1356. {
  1357.     eventlog(eventlog_level_info,"server_process","reading configuration files");
  1358.     if (preffile)
  1359.     {
  1360.          if (prefs_load(preffile)<0)
  1361.     eventlog(eventlog_level_error,"server_process","could not parse configuration file");
  1362.     }
  1363.     else
  1364. if (prefs_load(BNETD_DEFAULT_CONF_FILE)<0)
  1365.     eventlog(eventlog_level_error,"server_process","using default configuration");
  1366.     
  1367.     if (eventlog_open(prefs_get_logfile())<0)
  1368. eventlog(eventlog_level_error,"server_process","could not use the file "%s" for the eventlog",prefs_get_logfile());
  1369.     /* FIXME: load new network settings */
  1370.     /* reload server name */
  1371.     server_set_name();
  1372.     
  1373.     accountlist_load_default(); /* FIXME: free old one */
  1374.     /* Dizzy: disabled for the moment, lets see who really needs it, 
  1375.     also it can be the cause for a lot of problems
  1376.     accountlist_reload(); */
  1377.     
  1378.     channellist_reload();
  1379.             realmlist_destroy();
  1380.             if (realmlist_create(prefs_get_realmfile())<0)
  1381.         eventlog(eventlog_level_error,"main","could not load realm list");
  1382.     autoupdate_unload();
  1383.     if (autoupdate_load(prefs_get_mpqfile())<0)
  1384.       eventlog(eventlog_level_error,"main","could not load autoupdate list");
  1385.     news_unload();
  1386.     if (news_load(prefs_get_newsfile())<0)
  1387. eventlog(eventlog_level_error,__FUNCTION__,"could not load news list");
  1388.     versioncheck_unload();
  1389.     if (versioncheck_load(prefs_get_versioncheck_file())<0)
  1390.       eventlog(eventlog_level_error,"main","could not load versioncheck list");
  1391.          
  1392.     if (ipbanlist_destroy()<0)
  1393. eventlog(eventlog_level_error,"server_process","could not unload old IP ban list");
  1394.             if (ipbanlist_create()<0)
  1395.                 eventlog(eventlog_level_error,"server_process","could not create new IP ban list");
  1396.     if (ipbanlist_load(prefs_get_ipbanfile())<0)
  1397. eventlog(eventlog_level_error,"server_process","could not load new IP ban list");
  1398.     
  1399.     helpfile_unload();
  1400.     if (helpfile_init(prefs_get_helpfile())<0)
  1401. eventlog(eventlog_level_error,"server_process","could not load the helpfile");
  1402.     
  1403.     if (adbannerlist_destroy()<0)
  1404. eventlog(eventlog_level_error,"server_process","could not unload old adbanner list");
  1405.     if (adbannerlist_create(prefs_get_adfile())<0)
  1406. eventlog(eventlog_level_error,"server_process","could not load new adbanner list");
  1407.     
  1408.     if (gametrans_unload()<0)
  1409. eventlog(eventlog_level_error,"server_process","could not unload old gametrans list");
  1410.     if (gametrans_load(prefs_get_transfile())<0)
  1411. eventlog(eventlog_level_error,"server_process","could not load new gametrans list");
  1412.     ladder_reload_conf();
  1413.     
  1414.     if (prefs_get_track())
  1415. tracker_set_servers(prefs_get_trackserv_addrs());
  1416.     if (command_groups_reload(prefs_get_command_groups_file())<0)
  1417. eventlog(eventlog_level_error,"server_process","could not load new command_groups list");
  1418.     aliasfile_unload();
  1419.     aliasfile_load(prefs_get_aliasfile());
  1420.     
  1421.     if(w3trans_reload(prefs_get_w3trans_file())<0)
  1422. eventlog(eventlog_level_error,__FUNCTION__,"could not reload w3trans list");
  1423.     tournament_reload(prefs_get_tournament_file());
  1424.     anongame_infos_unload();
  1425.     anongame_infos_load(prefs_get_anongame_infos_file());
  1426.     
  1427.     syncdelta = prefs_get_user_sync_timer();
  1428.     
  1429.     eventlog(eventlog_level_info,"server_process","done reconfiguring");
  1430.     
  1431.     do_restart = 0;
  1432. }
  1433. #ifdef USE_CHECK_ALLOC
  1434. if (do_report_usage)
  1435. {
  1436.     check_report_usage();
  1437.     do_report_usage = 0;
  1438. }
  1439. #endif
  1440. count += BNETD_POLL_INTERVAL;
  1441. if (count>=1000) /* only check timers once a second */
  1442. {
  1443.     timerlist_check_timers(now);
  1444.     count = 0;
  1445. }
  1446. /* no need to populate the fdwatch structures as they are populated on the fly 
  1447.  * by sd_accept, conn_push_outqueue, conn_pull_outqueue, conn_destory */
  1448. /* find which sockets need servicing */
  1449. switch (fdwatch(BNETD_POLL_INTERVAL))
  1450. {
  1451. case -1: /* error */
  1452.     if (
  1453. #ifdef PSOCK_EINTR
  1454. /* FIXME: psock_select() uses psock_errno() instead of errno */
  1455. errno!=PSOCK_EINTR &&
  1456. #endif
  1457. 1)
  1458.         eventlog(eventlog_level_error,"server_process","fdwatch() failed (errno: %s)",strerror(errno));
  1459. case 0: /* timeout... no sockets need checking */
  1460.     continue;
  1461. }
  1462. /* cycle through the ready sockets and handle them */
  1463. fdwatch_handle();
  1464. /* reap dead connections */
  1465. connlist_reap();
  1466.     }
  1467.     
  1468.     /* cleanup for server shutdown */
  1469.     
  1470.     LIST_TRAVERSE_CONST(connlist(),ccurr)
  1471.     {
  1472. c = elem_get_data(ccurr);
  1473. conn_destroy(c);
  1474.     }
  1475.     
  1476.     fdwatch_close();
  1477.     LIST_TRAVERSE_CONST(laddrs,acurr)
  1478.     {
  1479. curr_laddr = elem_get_data(acurr);
  1480. if ((laddr_info = addr_get_data(curr_laddr).p))
  1481. {
  1482.     if (laddr_info->usocket!=-1)
  1483. psock_close(laddr_info->usocket);
  1484.     if (laddr_info->ssocket!=-1)
  1485. psock_close(laddr_info->ssocket);
  1486.     free(laddr_info);
  1487. }
  1488.     }
  1489.     addrlist_destroy(laddrs);
  1490.     
  1491.     return 0;
  1492.     
  1493.     /************************************************************************/
  1494.     
  1495.     /* error cleanup */
  1496.     
  1497. error_poll:
  1498.     
  1499. error_addr_list:
  1500.     LIST_TRAVERSE_CONST(laddrs,acurr)
  1501.     {
  1502. curr_laddr = elem_get_data(acurr);
  1503. if ((laddr_info = addr_get_data(curr_laddr).p))
  1504. {
  1505.     if (laddr_info->usocket!=-1)
  1506. psock_close(laddr_info->usocket);
  1507.     if (laddr_info->ssocket!=-1)
  1508. psock_close(laddr_info->ssocket);
  1509.     free(laddr_info);
  1510. }
  1511.     }
  1512.     addrlist_destroy(laddrs);
  1513.     return -1;
  1514. }