core.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. // Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  2. // For more information, see LICENCE in the main folder
  3. #include "../common/mmo.h"
  4. #include "../common/version.h"
  5. #include "../common/showmsg.h"
  6. #include "../common/malloc.h"
  7. #include "core.h"
  8. #ifndef MINICORE
  9. #include "../common/db.h"
  10. #include "../common/socket.h"
  11. #include "../common/timer.h"
  12. #include "../common/plugins.h"
  13. #endif
  14. #ifndef _WIN32
  15. #include "svnversion.h"
  16. #endif
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <signal.h>
  20. #include <string.h>
  21. #ifndef _WIN32
  22. #include <unistd.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. #ifndef SVNVERSION
  30. static char eA_svn_version[10] = "";
  31. #endif
  32. #ifndef MINICORE // minimalist Core
  33. // Added by Gabuzomeu
  34. //
  35. // This is an implementation of signal() using sigaction() for portability.
  36. // (sigaction() is POSIX; signal() is not.) Taken from Stevens' _Advanced
  37. // Programming in the UNIX Environment_.
  38. //
  39. #ifdef WIN32 // windows don't have SIGPIPE
  40. #define SIGPIPE SIGINT
  41. #endif
  42. #ifndef POSIX
  43. #define compat_signal(signo, func) signal(signo, func)
  44. #else
  45. sigfunc *compat_signal(int signo, sigfunc *func)
  46. {
  47. struct sigaction sact, oact;
  48. sact.sa_handler = func;
  49. sigemptyset(&sact.sa_mask);
  50. sact.sa_flags = 0;
  51. #ifdef SA_INTERRUPT
  52. sact.sa_flags |= SA_INTERRUPT; /* SunOS */
  53. #endif
  54. if (sigaction(signo, &sact, &oact) < 0)
  55. return (SIG_ERR);
  56. return (oact.sa_handler);
  57. }
  58. #endif
  59. /*======================================
  60. * CORE : Signal Sub Function
  61. *--------------------------------------*/
  62. static void sig_proc(int sn)
  63. {
  64. static int is_called = 0;
  65. switch (sn) {
  66. case SIGINT:
  67. case SIGTERM:
  68. if (++is_called > 3)
  69. exit(EXIT_SUCCESS);
  70. runflag = 0;
  71. break;
  72. case SIGSEGV:
  73. case SIGFPE:
  74. do_abort();
  75. // Pass the signal to the system's default handler
  76. compat_signal(sn, SIG_DFL);
  77. raise(sn);
  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. //ShowInfo ("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. #ifndef _DEBUG // need unhandled exceptions to debug on Windows
  96. compat_signal(SIGSEGV, sig_proc);
  97. compat_signal(SIGFPE, sig_proc);
  98. #endif
  99. #ifndef _WIN32
  100. compat_signal(SIGILL, SIG_DFL);
  101. compat_signal(SIGXFSZ, sig_proc);
  102. compat_signal(SIGPIPE, sig_proc);
  103. compat_signal(SIGBUS, SIG_DFL);
  104. compat_signal(SIGTRAP, SIG_DFL);
  105. #endif
  106. }
  107. #endif
  108. #ifdef SVNVERSION
  109. #define xstringify(x) stringify(x)
  110. #define stringify(x) #x
  111. const char *get_svn_revision(void)
  112. {
  113. return xstringify(SVNVERSION);
  114. }
  115. #else// not SVNVERSION
  116. const char* get_svn_revision(void)
  117. {
  118. FILE *fp;
  119. if(*eA_svn_version)
  120. return eA_svn_version;
  121. if ((fp = fopen(".svn/entries", "r")) != NULL)
  122. {
  123. char line[1024];
  124. int rev;
  125. // Check the version
  126. if (fgets(line, sizeof(line), fp))
  127. {
  128. if(!ISDIGIT(line[0]))
  129. {
  130. // XML File format
  131. while (fgets(line,sizeof(line),fp))
  132. if (strstr(line,"revision=")) break;
  133. if (sscanf(line," %*[^\"]\"%d%*[^\n]", &rev) == 1) {
  134. snprintf(eA_svn_version, sizeof(eA_svn_version), "%d", rev);
  135. }
  136. }
  137. else
  138. {
  139. // Bin File format
  140. fgets(line, sizeof(line), fp); // Get the name
  141. fgets(line, sizeof(line), fp); // Get the entries kind
  142. if(fgets(line, sizeof(line), fp)) // Get the rev numver
  143. {
  144. snprintf(eA_svn_version, sizeof(eA_svn_version), "%d", atoi(line));
  145. }
  146. }
  147. }
  148. fclose(fp);
  149. }
  150. if(!(*eA_svn_version))
  151. snprintf(eA_svn_version, sizeof(eA_svn_version), "Unknown");
  152. return eA_svn_version;
  153. }
  154. #endif
  155. /*======================================
  156. * CORE : Display title
  157. *--------------------------------------*/
  158. static void display_title(void)
  159. {
  160. //ClearScreen(); // clear screen and go up/left (0, 0 position in text)
  161. ShowMessage("\n");
  162. ShowMessage(""CL_WTBL" (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)"CL_CLL""CL_NORMAL"\n");
  163. ShowMessage(""CL_XXBL" ("CL_BT_YELLOW" eAthena Development Team presents "CL_XXBL")"CL_CLL""CL_NORMAL"\n");
  164. ShowMessage(""CL_XXBL" ("CL_BOLD" ______ __ __ "CL_XXBL")"CL_CLL""CL_NORMAL"\n");
  165. ShowMessage(""CL_XXBL" ("CL_BOLD" /\\ _ \\/\\ \\__/\\ \\ "CL_XXBL")"CL_CLL""CL_NORMAL"\n");
  166. ShowMessage(""CL_XXBL" ("CL_BOLD" __\\ \\ \\_\\ \\ \\ ,_\\ \\ \\___ __ ___ __ "CL_XXBL")"CL_CLL""CL_NORMAL"\n");
  167. ShowMessage(""CL_XXBL" ("CL_BOLD" /'__`\\ \\ __ \\ \\ \\/\\ \\ _ `\\ /'__`\\/' _ `\\ /'__`\\ "CL_XXBL")"CL_CLL""CL_NORMAL"\n");
  168. ShowMessage(""CL_XXBL" ("CL_BOLD" /\\ __/\\ \\ \\/\\ \\ \\ \\_\\ \\ \\ \\ \\/\\ __//\\ \\/\\ \\/\\ \\_\\.\\_ "CL_XXBL")"CL_CLL""CL_NORMAL"\n");
  169. ShowMessage(""CL_XXBL" ("CL_BOLD" \\ \\____\\\\ \\_\\ \\_\\ \\__\\\\ \\_\\ \\_\\ \\____\\ \\_\\ \\_\\ \\__/.\\_\\ "CL_XXBL")"CL_CLL""CL_NORMAL"\n");
  170. ShowMessage(""CL_XXBL" ("CL_BOLD" \\/____/ \\/_/\\/_/\\/__/ \\/_/\\/_/\\/____/\\/_/\\/_/\\/__/\\/_/ "CL_XXBL")"CL_CLL""CL_NORMAL"\n");
  171. ShowMessage(""CL_XXBL" ("CL_BOLD" _ _ _ _ _ _ _ _ _ _ _ _ _ "CL_XXBL")"CL_CLL""CL_NORMAL"\n");
  172. ShowMessage(""CL_XXBL" ("CL_BOLD" / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ / \\ "CL_XXBL")"CL_CLL""CL_NORMAL"\n");
  173. 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");
  174. ShowMessage(""CL_XXBL" ("CL_BOLD" \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ "CL_XXBL")"CL_CLL""CL_NORMAL"\n");
  175. ShowMessage(""CL_XXBL" ("CL_BOLD" "CL_XXBL")"CL_CLL""CL_NORMAL"\n");
  176. ShowMessage(""CL_WTBL" (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)"CL_CLL""CL_NORMAL"\n\n");
  177. ShowInfo("SVN Revision: '"CL_WHITE"%s"CL_RESET"'.\n", get_svn_revision());
  178. }
  179. // Warning if logged in as superuser (root)
  180. void usercheck(void)
  181. {
  182. #ifndef _WIN32
  183. if ((getuid() == 0) && (getgid() == 0)) {
  184. ShowWarning ("You are running eAthena as the root superuser.\n");
  185. ShowWarning ("It is unnecessary and unsafe to run eAthena with root privileges.\n");
  186. sleep(3);
  187. }
  188. #endif
  189. }
  190. /*======================================
  191. * CORE : MAINROUTINE
  192. *--------------------------------------*/
  193. int main (int argc, char **argv)
  194. {
  195. {// initialize program arguments
  196. char *p1 = SERVER_NAME = argv[0];
  197. char *p2 = p1;
  198. while ((p1 = strchr(p2, '/')) != NULL || (p1 = strchr(p2, '\\')) != NULL)
  199. {
  200. SERVER_NAME = ++p1;
  201. p2 = p1;
  202. }
  203. arg_c = argc;
  204. arg_v = argv;
  205. }
  206. malloc_init();// needed for Show* in display_title() [FlavioJS]
  207. #ifdef MINICORE // minimalist Core
  208. display_title();
  209. usercheck();
  210. do_init(argc,argv);
  211. do_final();
  212. #else// not MINICORE
  213. set_server_type();
  214. display_title();
  215. usercheck();
  216. db_init();
  217. signals_init();
  218. timer_init();
  219. socket_init();
  220. plugins_init();
  221. do_init(argc,argv);
  222. plugin_event_trigger(EVENT_ATHENA_INIT);
  223. {// Main runtime cycle
  224. int next;
  225. while (runflag) {
  226. next = do_timer(gettick_nocache());
  227. do_sockets(next);
  228. }
  229. }
  230. plugin_event_trigger(EVENT_ATHENA_FINAL);
  231. do_final();
  232. timer_final();
  233. plugins_final();
  234. socket_final();
  235. db_final();
  236. #endif
  237. malloc_final();
  238. return 0;
  239. }
  240. #ifdef BCHECK
  241. unsigned int __invalid_size_argument_for_IOC;
  242. #endif