core.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  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/mmo.h"
  13. #include "../common/version.h"
  14. #include "../common/showmsg.h"
  15. #include "../common/malloc.h"
  16. #ifndef MINICORE
  17. #include "../common/db.h"
  18. #include "../common/socket.h"
  19. #include "../common/timer.h"
  20. #include "../common/plugins.h"
  21. #endif
  22. #ifndef _WIN32
  23. #include "svnversion.h"
  24. #endif
  25. int runflag = 1;
  26. int arg_c = 0;
  27. char **arg_v = NULL;
  28. char *SERVER_NAME = NULL;
  29. char SERVER_TYPE = ATHENA_SERVER_NONE;
  30. #ifndef SVNVERSION
  31. static char eA_svn_version[10];
  32. #endif
  33. #ifndef MINICORE // minimalist Core
  34. // Added by Gabuzomeu
  35. //
  36. // This is an implementation of signal() using sigaction() for portability.
  37. // (sigaction() is POSIX; signal() is not.) Taken from Stevens' _Advanced
  38. // Programming in the UNIX Environment_.
  39. //
  40. #ifdef WIN32 // windows don't have SIGPIPE
  41. #define SIGPIPE SIGINT
  42. #endif
  43. #ifndef POSIX
  44. #define compat_signal(signo, func) signal(signo, func)
  45. #else
  46. sigfunc *compat_signal(int signo, sigfunc *func)
  47. {
  48. struct sigaction sact, oact;
  49. sact.sa_handler = func;
  50. sigemptyset(&sact.sa_mask);
  51. sact.sa_flags = 0;
  52. #ifdef SA_INTERRUPT
  53. sact.sa_flags |= SA_INTERRUPT; /* SunOS */
  54. #endif
  55. if (sigaction(signo, &sact, &oact) < 0)
  56. return (SIG_ERR);
  57. return (oact.sa_handler);
  58. }
  59. #endif
  60. /*======================================
  61. * CORE : Signal Sub Function
  62. *--------------------------------------
  63. */
  64. static void sig_proc(int sn)
  65. {
  66. static int is_called = 0;
  67. switch (sn) {
  68. case SIGINT:
  69. case SIGTERM:
  70. if (++is_called > 3)
  71. exit(0);
  72. runflag = 0;
  73. break;
  74. case SIGSEGV:
  75. case SIGFPE:
  76. do_abort();
  77. // Pass the signal to the system's default handler
  78. compat_signal(sn, SIG_DFL);
  79. raise(sn);
  80. break;
  81. #ifndef _WIN32
  82. case SIGXFSZ:
  83. // ignore and allow it to set errno to EFBIG
  84. ShowWarning ("Max file size reached!\n");
  85. //run_flag = 0; // should we quit?
  86. break;
  87. case SIGPIPE:
  88. ShowMessage ("Broken pipe found... closing socket\n"); // set to eof in socket.c
  89. break; // does nothing here
  90. #endif
  91. }
  92. }
  93. void signals_init (void)
  94. {
  95. compat_signal(SIGTERM, sig_proc);
  96. compat_signal(SIGINT, sig_proc);
  97. #ifndef _DEBUG // need unhandled exceptions to debug on Windows
  98. compat_signal(SIGSEGV, sig_proc);
  99. compat_signal(SIGFPE, sig_proc);
  100. #endif
  101. #ifndef _WIN32
  102. compat_signal(SIGILL, SIG_DFL);
  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// not SVNVERSION
  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. //ClearScreen(); // clear screen and go up/left (0, 0 position in text)
  164. ShowMessage("\n");
  165. ShowMessage(""CL_WTBL" (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)"CL_CLL""CL_NORMAL"\n"); // white writing (37) on blue background (44), \033[K clean until end of file
  166. ShowMessage(""CL_XXBL" ("CL_BT_YELLOW" (c)2005 eAthena Development Team presents "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // yellow writing (33)
  167. ShowMessage(""CL_XXBL" ("CL_BOLD" ______ __ __ "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // 1: bold char, 0: normal char
  168. 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
  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" /'__`\\ \\ __ \\ \\ \\/\\ \\ _ `\\ /'__`\\/' _ `\\ /'__`\\ "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // 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" ( 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
  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" "CL_XXBL")"CL_CLL""CL_NORMAL"\n"); // yellow writing (33)
  179. ShowMessage(""CL_WTBL" (=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=)"CL_CLL""CL_NORMAL"\n\n"); // reset color
  180. ShowInfo("SVN Revision: '"CL_WHITE"%s"CL_RESET"'.\n", get_svn_revision());
  181. }
  182. // Warning if logged in as superuser (root)
  183. void usercheck(void)
  184. {
  185. #ifndef _WIN32
  186. if ((getuid() == 0) && (getgid() == 0)) {
  187. ShowWarning ("You are running eAthena as the root superuser.\n");
  188. ShowWarning ("It is unnecessary and unsafe to run eAthena with root privileges.\n");
  189. sleep(3);
  190. }
  191. #endif
  192. }
  193. /*======================================
  194. * CORE : MAINROUTINE
  195. *--------------------------------------
  196. */
  197. int main (int argc, char **argv)
  198. {
  199. {// initialize program arguments
  200. char *p1 = SERVER_NAME = argv[0];
  201. char *p2 = p1;
  202. while ((p1 = strchr(p2, '/')) != NULL || (p1 = strchr(p2, '\\')) != NULL)
  203. {
  204. SERVER_NAME = ++p1;
  205. p2 = p1;
  206. }
  207. arg_c = argc;
  208. arg_v = argv;
  209. #ifndef SVNVERSION
  210. *eA_svn_version = '\0';
  211. #endif
  212. }
  213. malloc_init();// needed for Show* in display_title() [FlavioJS]
  214. #ifdef MINICORE // minimalist Core
  215. display_title();
  216. usercheck();
  217. do_init(argc,argv);
  218. do_final();
  219. #else// not MINICORE
  220. set_server_type();
  221. display_title();
  222. usercheck();
  223. db_init();
  224. signals_init();
  225. timer_init();
  226. socket_init();
  227. plugins_init();
  228. do_init(argc,argv);
  229. plugin_event_trigger(EVENT_ATHENA_INIT);
  230. {// Main runtime cycle
  231. int next;
  232. while (runflag) {
  233. next = do_timer(gettick_nocache());
  234. do_sendrecv(next);
  235. do_parsepacket();
  236. }
  237. }
  238. plugin_event_trigger(EVENT_ATHENA_FINAL);
  239. do_final();
  240. timer_final();
  241. plugins_final();
  242. socket_final();
  243. db_final();
  244. #endif
  245. malloc_final();
  246. return 0;
  247. }
  248. #ifdef BCHECK
  249. unsigned int __invalid_size_argument_for_IOC;
  250. #endif