root/src/common/core.c @ 1

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