core.c 8.9 KB

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