core.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #ifndef _WIN32
  6. #include <unistd.h>
  7. #endif
  8. #include <signal.h>
  9. #include <string.h>
  10. #include "core.h"
  11. #include "../common/db.h"
  12. #include "../common/mmo.h"
  13. #include "../common/malloc.h"
  14. #include "../common/socket.h"
  15. #include "../common/timer.h"
  16. #include "../common/graph.h"
  17. #include "../common/grfio.h"
  18. #include "../common/plugins.h"
  19. #include "../common/version.h"
  20. #include "../common/showmsg.h"
  21. #ifndef _WIN32
  22. #include "svnversion.h"
  23. #endif
  24. int runflag = 1;
  25. int arg_c = 0;
  26. char **arg_v = NULL;
  27. char *SERVER_NAME = NULL;
  28. char SERVER_TYPE = ATHENA_SERVER_NONE;
  29. static void (*term_func)(void) = NULL;
  30. /*======================================
  31. * CORE : Set function
  32. *--------------------------------------
  33. */
  34. void set_termfunc(void (*termfunc)(void))
  35. {
  36. term_func = termfunc;
  37. }
  38. #ifndef MINICORE // minimalist Core
  39. // Added by Gabuzomeu
  40. //
  41. // This is an implementation of signal() using sigaction() for portability.
  42. // (sigaction() is POSIX; signal() is not.) Taken from Stevens' _Advanced
  43. // Programming in the UNIX Environment_.
  44. //
  45. #ifdef WIN32 // windows don't have SIGPIPE
  46. #define SIGPIPE SIGINT
  47. #endif
  48. #ifndef POSIX
  49. #define compat_signal(signo, func) signal(signo, func)
  50. #else
  51. sigfunc *compat_signal(int signo, sigfunc *func)
  52. {
  53. struct sigaction sact, oact;
  54. sact.sa_handler = func;
  55. sigemptyset(&sact.sa_mask);
  56. sact.sa_flags = 0;
  57. #ifdef SA_INTERRUPT
  58. sact.sa_flags |= SA_INTERRUPT; /* SunOS */
  59. #endif
  60. if (sigaction(signo, &sact, &oact) < 0)
  61. return (SIG_ERR);
  62. return (oact.sa_handler);
  63. }
  64. #endif
  65. /*======================================
  66. * CORE : Signal Sub Function
  67. *--------------------------------------
  68. */
  69. static void sig_proc(int sn)
  70. {
  71. static int is_called = 0;
  72. switch (sn) {
  73. case SIGINT:
  74. case SIGTERM:
  75. if (++is_called > 3)
  76. exit(0);
  77. runflag = 0;
  78. break;
  79. #ifndef _WIN32
  80. case SIGXFSZ:
  81. // ignore and allow it to set errno to EFBIG
  82. ShowWarning ("Max file size reached!\n");
  83. //run_flag = 0; // should we quit?
  84. break;
  85. case SIGPIPE:
  86. ShowMessage ("Broken pipe found... closing socket\n"); // set to eof in socket.c
  87. break; // does nothing here
  88. #endif
  89. }
  90. }
  91. void signals_init (void)
  92. {
  93. compat_signal(SIGTERM, sig_proc);
  94. compat_signal(SIGINT, sig_proc);
  95. // Signal to create coredumps by system when necessary (crash)
  96. compat_signal(SIGSEGV, SIG_DFL);
  97. compat_signal(SIGFPE, SIG_DFL);
  98. compat_signal(SIGILL, SIG_DFL);
  99. #ifndef _WIN32
  100. compat_signal(SIGXFSZ, sig_proc);
  101. compat_signal(SIGPIPE, sig_proc);
  102. compat_signal(SIGBUS, SIG_DFL);
  103. compat_signal(SIGTRAP, SIG_DFL);
  104. #endif
  105. }
  106. #endif
  107. #ifdef SVNVERSION
  108. #define xstringify(x) stringify(x)
  109. #define stringify(x) #x
  110. const char *get_svn_revision(void)
  111. {
  112. return xstringify(SVNVERSION);
  113. }
  114. #else
  115. const char* get_svn_revision(void)
  116. {
  117. static char version[10];
  118. FILE *fp;
  119. if ((fp = fopen(".svn/entries", "r")) != NULL) {
  120. char line[1024];
  121. int rev;
  122. while (fgets(line,1023,fp))
  123. if (strstr(line,"revision=")) break;
  124. fclose(fp);
  125. if (sscanf(line," %*[^\"]\"%d%*[^\n]", &rev) == 1) {
  126. sprintf(version, "%d", rev);
  127. return version;
  128. }
  129. }
  130. // if getting revision has failed
  131. return "Unknown";
  132. }
  133. #endif
  134. /*======================================
  135. * CORE : Display title
  136. *--------------------------------------
  137. */
  138. static void display_title(void)
  139. {
  140. //The clearscreeen is usually more of an annoyance than anything else... [Skotlex]
  141. // ClearScreen(); // clear screen and go up/left (0, 0 position in text)
  142. ShowMessage("\n");
  143. ShowMessage(""CL_WTBL" (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)"CL_CLL""CL_NORMAL"\n"); // white writing (37) on blue background (44), \033[K clean until end of file
  144. ShowMessage(""CL_XXBL" ("CL_BT_YELLOW" (c)2005 eAthena Development Team presents "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // yellow writing (33)
  145. ShowMessage(""CL_XXBL" ("CL_BOLD" ______ __ __ "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // 1: bold char, 0: normal char
  146. ShowMessage(""CL_XXBL" ("CL_BOLD" /\\ _ \\/\\ \\__/\\ \\ v%2d.%02d.%02d "CL_XXBL")"CL_CLL""CL_NORMAL"\n", ATHENA_MAJOR_VERSION, ATHENA_MINOR_VERSION, ATHENA_REVISION); // 1: bold char, 0: normal char
  147. ShowMessage(""CL_XXBL" ("CL_BOLD" __\\ \\ \\_\\ \\ \\ ,_\\ \\ \\___ __ ___ __ "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // 1: bold char, 0: normal char
  148. ShowMessage(""CL_XXBL" ("CL_BOLD" /'__`\\ \\ __ \\ \\ \\/\\ \\ _ `\\ /'__`\\/' _ `\\ /'__`\\ "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // 1: bold char, 0: normal char
  149. ShowMessage(""CL_XXBL" ("CL_BOLD" /\\ __/\\ \\ \\/\\ \\ \\ \\_\\ \\ \\ \\ \\/\\ __//\\ \\/\\ \\/\\ \\_\\.\\_ "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // 1: bold char, 0: normal char
  150. ShowMessage(""CL_XXBL" ("CL_BOLD" \\ \\____\\\\ \\_\\ \\_\\ \\__\\\\ \\_\\ \\_\\ \\____\\ \\_\\ \\_\\ \\__/.\\_\\ "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // 1: bold char, 0: normal char
  151. ShowMessage(""CL_XXBL" ("CL_BOLD" \\/____/ \\/_/\\/_/\\/__/ \\/_/\\/_/\\/____/\\/_/\\/_/\\/__/\\/_/ "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // 1: bold char, 0: normal char
  152. ShowMessage(""CL_XXBL" ("CL_BOLD" _ _ _ _ _ _ _ _ _ _ _ _ _ "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // 1: bold char, 0: normal char
  153. ShowMessage(""CL_XXBL" ("CL_BOLD" / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // 1: bold char, 0: normal char
  154. ShowMessage(""CL_XXBL" ("CL_BOLD" ( e | n | g | l | i | s | h ) ( A | t | h | e | n | a ) "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // 1: bold char, 0: normal char
  155. ShowMessage(""CL_XXBL" ("CL_BOLD" \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // 1: bold char, 0: normal char
  156. ShowMessage(""CL_XXBL" ("CL_BOLD" "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // yellow writing (33)
  157. ShowMessage(""CL_XXBL" ("CL_BT_YELLOW" Advanced Fusion Maps (c) 2003-2005 The Fusion Project "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // yellow writing (33)
  158. ShowMessage(""CL_WTBL" (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)"CL_CLL""CL_NORMAL"\n\n"); // reset color
  159. ShowInfo("SVN Revision: '"CL_WHITE"%s"CL_RESET"'.\n", get_svn_revision());
  160. }
  161. // Warning if logged in as superuser (root)
  162. void usercheck(void){
  163. #ifndef _WIN32
  164. if ((getuid() == 0) && (getgid() == 0)) {
  165. ShowWarning ("You are running eAthena as the root superuser.\n");
  166. ShowWarning ("It is unnecessary and unsafe to run eAthena with root privileges.\n");
  167. sleep(3);
  168. }
  169. #endif
  170. }
  171. /*======================================
  172. * CORE : MAINROUTINE
  173. *--------------------------------------
  174. */
  175. #ifndef MINICORE // minimalist Core
  176. int main (int argc, char **argv)
  177. {
  178. int next;
  179. // initialise program arguments
  180. {
  181. char *p = SERVER_NAME = argv[0];
  182. while ((p = strchr(p, '/')) != NULL)
  183. SERVER_NAME = ++p;
  184. arg_c = argc;
  185. arg_v = argv;
  186. }
  187. set_server_type();
  188. display_title();
  189. usercheck();
  190. malloc_init(); /* 一番最初に実行する必要がある */
  191. db_init();
  192. signals_init();
  193. timer_init();
  194. socket_init();
  195. plugins_init();
  196. do_init(argc,argv);
  197. graph_init();
  198. plugin_event_trigger("Athena_Init");
  199. while (runflag) {
  200. next = do_timer(gettick_nocache());
  201. do_sendrecv(next);
  202. #ifndef TURBO
  203. do_parsepacket();
  204. #endif
  205. }
  206. plugin_event_trigger("Athena_Final");
  207. graph_final();
  208. do_final();
  209. timer_final();
  210. plugins_final();
  211. socket_final();
  212. db_final();
  213. malloc_final();
  214. return 0;
  215. }
  216. #else
  217. int main (int argc, char **argv)
  218. {
  219. // initialise program arguments
  220. {
  221. char *p = SERVER_NAME = argv[0];
  222. while ((p = strchr(p, '/')) != NULL)
  223. SERVER_NAME = ++p;
  224. arg_c = argc;
  225. arg_v = argv;
  226. }
  227. display_title();
  228. usercheck();
  229. do_init(argc,argv);
  230. do_final();
  231. return 0;
  232. }
  233. #endif
  234. #ifdef BCHECK
  235. unsigned int __invalid_size_argument_for_IOC;
  236. #endif