fgms 0.11.8
The
FlightGear MultiPlayer Server
project
main.cxx
Go to the documentation of this file.
1 /**
2  * @file main.cxx
3  * @author Oliver Schroeder
4  * @brief Main Program
5  *
6  */
7 
8 //
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License as
11 // published by the Free Software Foundation; either version 2 of the
12 // License, or (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, U$
22 //
23 // Copyright (C) 2006 Oliver Schroeder
24 //
25 
26 //////////////////////////////////////////////////////////////////////
27 //
28 // main program
29 //
30 //////////////////////////////////////////////////////////////////////
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34 
35 #include <cstdlib>
36 #ifndef _MSC_VER
37 #include <sys/wait.h>
38 #endif
39 #include <signal.h>
40 #include "fg_server.hxx"
41 #include "fg_config.hxx"
42 #include "daemon.hxx"
43 #include "fg_util.hxx"
44 
45 using namespace std;
46 
47 /** @brief The running ::FG_SERVER server process */
49 
50 /** @brief Flag whether instance is a Daemon */
51 extern bool RunAsDaemon;
52 extern bool AddCLI;
53 #ifdef _MSC_VER
54 #define M_IS_DIR _S_IFDIR
55 #else // !_MSC_VER
56 #define M_IS_DIR S_IFDIR
57 /** @brief An instance of ::cDaemon */
58 extern cDaemon Myself;
59 #endif
60 
61 /** @brief Must have a config file, with server name */
62 static bool bHadConfig = false;
63 
64 /** @def DEF_CONF_FILE
65  * @brief The default config file to load unless overriden on \ref command_line
66  */
67 #ifndef DEF_CONF_FILE
68 #define DEF_CONF_FILE "fgms.conf"
69 #endif
70 
71 /** @def SYSCONFDIR
72  * @brief The default config directory
73  */
74 #ifndef SYSCONFDIR
75 #define SYSCONFDIR "/usr/etc"
76 #endif
77 
78 #ifndef DEF_LOG_LEVEL
79 #define DEF_LOG_LEVEL SG_INFO
80 #endif
81 #ifndef DEF_LOG_CLASS
82 #ifdef _MSC_VER
83 #define DEF_LOG_CLASS (SG_FGMS|SG_FGTRACKER|SG_CONSOLE)
84 #else
85 #define DEF_LOG_CLASS (SG_FGMS|SG_FGTRACKER)
86 #endif
87 #endif
88 
91 
92 //////////////////////////////////////////////////////////////////////
93 /**
94  * @brief Print a help screen for command line parameters, see \ref command_line
95  */
96 void
98 {
99  cout << "fgms: version " << VERSION << ", compiled on " << __DATE__ << ", at " << __TIME__ << endl;
100  cout << "\n"
101  "options are:\n"
102  "-h print this help screen\n"
103  "-a PORT listen to PORT for telnet\n"
104  "-c config read 'config' as configuration file\n"
105  "-p PORT listen to PORT\n"
106  "-t TTL Time a client is active while not sending packets\n"
107  "-o OOR nautical miles two players must be apart to be out of reach\n"
108  "-l LOGFILE Log to LOGFILE\n"
109  "-v LEVEL verbosity (loglevel) in range 0 (few) and 4 (much). 5 to disable. (def=" << curr_priority << ")\n"
110  "-d do _not_ run as a daemon (stay in foreground)\n"
111  "-D do run as a daemon\n"
112  "\n"
113  "the default is to run as a daemon, which can be overridden in the\n"
114  "config file.\n"
115  "\n";
116  exit ( 0 );
117 } // PrintHelp ()
118 //////////////////////////////////////////////////////////////////////
119 
120 #ifdef _MSC_VER
121 // kludge for getopt() for WIN32
122 static char* optarg;
123 static int curr_arg = 0;
124 int getopt ( int argcount, char* argvars[], char* args )
125 {
126  size_t len = strlen ( args );
127  size_t i;
128  int c = 0;
129  if ( curr_arg == 0 )
130  {
131  curr_arg = 1;
132  }
133  if ( curr_arg < argcount )
134  {
135  char* arg = argvars[curr_arg];
136  if ( *arg == '-' )
137  {
138  arg++;
139  c = *arg; // get first char
140  for ( i = 0; i < len; i++ )
141  {
142  if ( c == args[i] )
143  {
144  // found
145  if ( args[i+1] == ':' )
146  {
147  // fill in following
148  curr_arg++;
149  optarg = argvars[curr_arg];
150  }
151  break;
152  }
153  }
154  curr_arg++;
155  return c;
156  }
157  else
158  {
159  return '-';
160  }
161  }
162  return -1;
163 }
164 #endif // _MSC_VER
165 
166 //////////////////////////////////////////////////////////////////////
167 /**
168  * @brief Read a config file and set internal variables accordingly
169  * @param ConfigName Path of config file to load
170  * @retval int -- todo--
171  */
172 bool
173 ProcessConfig ( const string& ConfigName )
174 {
175  FG_CONFIG Config;
176  string Val;
177  int E;
178  if ( bHadConfig ) // we already have a config, so ignore
179  {
180  return ( true );
181  }
182  if ( Config.Read ( ConfigName ) )
183  {
184  // bHadConfig = true;
186  "Could not read config file '" << ConfigName
187  << "' => using defaults");
188  return ( false );
189  }
190  cout << "processing " << ConfigName << endl;
191  Servant.ConfigFile = ConfigName;
192  Val = Config.Get ( "server.name" );
193  if ( Val != "" )
194  {
195  Servant.SetServerName ( Val );
196  bHadConfig = true; // got a serve name - minimum
197  }
198  Val = Config.Get ( "server.address" );
199  if ( Val != "" )
200  {
201  Servant.SetBindAddress ( Val );
202  }
203  Val = Config.Get ( "server.port" );
204  if ( Val != "" )
205  {
206  Servant.SetDataPort ( StrToNum<int> ( Val.c_str (), E ) );
207  if ( E )
208  {
209  SG_LOG ( SG_SYSTEMS, SG_ALERT, "invalid value for DataPort: '" << optarg << "'" );
210  exit ( 1 );
211  }
212  }
213  Val = Config.Get ( "server.telnet_port" );
214  if ( Val != "" )
215  {
216  Servant.SetTelnetPort ( StrToNum<int> ( Val.c_str (), E ) );
217  if ( E )
218  {
219  SG_LOG ( SG_SYSTEMS, SG_ALERT, "invalid value for TelnetPort: '" << optarg << "'" );
220  exit ( 1 );
221  }
222  }
223  Val = Config.Get ( "server.admin_cli" );
224  if ( Val != "" )
225  {
226  if ( ( Val == "on" ) || ( Val == "true" ) )
227  {
228  AddCLI = true;
229  }
230  else if ( ( Val == "off" ) || ( Val == "false" ) )
231  {
232  AddCLI = false;
233  }
234  else
235  {
236  SG_LOG ( SG_SYSTEMS, SG_ALERT, "unknown value for 'server.admin_cli'!" << " in file " << ConfigName );
237  }
238  }
239 
240  Val = Config.Get ( "server.admin_port" );
241  if ( Val != "" )
242  {
243  Servant.SetAdminPort ( StrToNum<int> ( Val.c_str (), E ) );
244  if ( E )
245  {
246  SG_LOG ( SG_SYSTEMS, SG_ALERT, "invalid value for AdminPort: '" << optarg << "'" );
247  exit ( 1 );
248  }
249  }
250  Val = Config.Get ( "server.admin_user" );
251  if ( Val != "" )
252  {
253  Servant.SetAdminUser ( Val );
254  }
255  Val = Config.Get ( "server.admin_pass" );
256  if ( Val != "" )
257  {
258  Servant.SetAdminPass ( Val );
259  }
260  Val = Config.Get ( "server.admin_enable" );
261  if ( Val != "" )
262  {
263  Servant.SetAdminEnable ( Val );
264  }
265  Val = Config.Get ( "server.out_of_reach" );
266  if ( Val != "" )
267  {
268  Servant.SetOutOfReach ( StrToNum<int> ( Val.c_str (), E ) );
269  if ( E )
270  {
271  SG_LOG ( SG_SYSTEMS, SG_ALERT, "invalid value for OutOfReach: '" << optarg << "'" );
272  exit ( 1 );
273  }
274  }
275  Val = Config.Get ( "server.playerexpires" );
276  if ( Val != "" )
277  {
278  Servant.SetPlayerExpires ( StrToNum<int> ( Val.c_str (), E ) );
279  if ( E )
280  {
281  SG_LOG ( SG_SYSTEMS, SG_ALERT, "invalid value for Expire: '" << optarg << "'" );
282  exit ( 1 );
283  }
284  }
285  Val = Config.Get ( "server.logfile" );
286  if ( Val != "" )
287  {
288  Servant.SetLogfile ( Val );
289  }
290  Val = Config.Get ( "server.daemon" );
291  if ( Val != "" )
292  {
293  if ( ( Val == "on" ) || ( Val == "true" ) )
294  {
295  RunAsDaemon = true;
296  }
297  else if ( ( Val == "off" ) || ( Val == "false" ) )
298  {
299  RunAsDaemon = false;
300  }
301  else
302  {
303  SG_LOG ( SG_SYSTEMS, SG_ALERT, "unknown value for 'server.daemon'!" << " in file " << ConfigName );
304  }
305  }
306  Val = Config.Get ( "server.tracked" );
307  if ( Val != "" )
308  {
309  string Server;
310  int Port;
311  bool tracked;
312  if ( Val == "true" )
313  {
314  tracked = true;
315  }
316  else
317  {
318  tracked = false;
319  }
320  Server = Config.Get ( "server.tracking_server" );
321  Val = Config.Get ( "server.tracking_port" );
322  Port = StrToNum<int> ( Val.c_str (), E );
323  if ( E )
324  {
325  SG_LOG ( SG_SYSTEMS, SG_ALERT, "invalid value for tracking_port: '" << Val << "'" );
326  exit ( 1 );
327  }
328  if ( tracked && ( Servant.AddTracker ( Server, Port, tracked ) != FG_SERVER::SUCCESS ) ) // set master m_IsTracked
329  {
330  SG_LOG ( SG_SYSTEMS, SG_ALERT, "Failed to get IPC msg queue ID! error " << errno );
331  exit ( 1 ); // do NOT continue if a requested 'tracker' FAILED
332  }
333  }
334  Val = Config.Get ( "server.is_hub" );
335  if ( Val != "" )
336  {
337  if ( Val == "true" )
338  {
339  Servant.SetHub ( true );
340  }
341  else
342  {
343  Servant.SetHub ( false );
344  }
345  }
346  //////////////////////////////////////////////////
347  // read the list of relays
348  //////////////////////////////////////////////////
349  bool MoreToRead = true;
350  string Section = "relay";
351  string Var;
352  string Server = "";
353  int Port = 0;
354  if ( ! Config.SetSection ( Section ) )
355  {
356  MoreToRead = false;
357  }
358  while ( MoreToRead )
359  {
360  Var = Config.GetName ();
361  Val = Config.GetValue();
362  if ( Var == "relay.host" )
363  {
364  Server = Val;
365  }
366  if ( Var == "relay.port" )
367  {
368  Port = StrToNum<int> ( Val.c_str(), E );
369  if ( E )
370  {
371  SG_LOG ( SG_SYSTEMS, SG_ALERT, "invalid value for RelayPort: '" << Val << "'" );
372  exit ( 1 );
373  }
374  }
375  if ( ( Server != "" ) && ( Port != 0 ) )
376  {
377  Servant.AddRelay ( Server, Port );
378  Server = "";
379  Port = 0;
380  }
381  if ( Config.SecNext () == 0 )
382  {
383  MoreToRead = false;
384  }
385  }
386  //////////////////////////////////////////////////
387  // read the list of crossfeeds
388  //////////////////////////////////////////////////
389  MoreToRead = true;
390  Section = "crossfeed";
391  Var = "";
392  Server = "";
393  Port = 0;
394  if ( ! Config.SetSection ( Section ) )
395  {
396  MoreToRead = false;
397  }
398  while ( MoreToRead )
399  {
400  Var = Config.GetName ();
401  Val = Config.GetValue();
402  if ( Var == "crossfeed.host" )
403  {
404  Server = Val;
405  }
406  if ( Var == "crossfeed.port" )
407  {
408  Port = StrToNum<int> ( Val.c_str(), E );
409  if ( E )
410  {
411  SG_LOG ( SG_SYSTEMS, SG_ALERT, "invalid value for crossfeed.port: '" << Val << "'" );
412  exit ( 1 );
413  }
414  }
415  if ( ( Server != "" ) && ( Port != 0 ) )
416  {
417  Servant.AddCrossfeed ( Server, Port );
418  Server = "";
419  Port = 0;
420  }
421  if ( Config.SecNext () == 0 )
422  {
423  MoreToRead = false;
424  }
425  }
426  //////////////////////////////////////////////////
427  // read the list of blacklisted IPs
428  //////////////////////////////////////////////////
429  MoreToRead = true;
430  Section = "blacklist";
431  Var = "";
432  Val = "";
433  if ( ! Config.SetSection ( Section ) )
434  {
435  MoreToRead = false;
436  }
437  while ( MoreToRead )
438  {
439  Var = Config.GetName ();
440  Val = Config.GetValue();
441  if ( Var == "blacklist" )
442  {
443  Servant.AddBlacklist ( Val.c_str(), "static config entry", 0 );
444  }
445  if ( Config.SecNext () == 0 )
446  {
447  MoreToRead = false;
448  }
449  }
450  //////////////////////////////////////////////////
451  return ( true );
452 } // ProcessConfig ( const string& ConfigName )
453 
454 //////////////////////////////////////////////////////////////////////
455 /**
456  * @brief Parse commandline parameters
457  * @param argcount
458  * @param argvars
459  * @retval int 1 on success
460  */
461 int
462 ParseParams ( int argcount, char* argvars[] )
463 {
464  int m;
465  int E;
466  while ( ( m=getopt ( argcount,argvars,"a:b:c:dDhl:o:p:t:v:" ) ) != -1 )
467  {
468  switch ( m )
469  {
470  case 'h':
471  cerr << endl;
472  cerr << "syntax: " << argvars[0] << " options" << endl;
473  PrintHelp ();
474  break; // never reached
475  case 'a':
476  Servant.SetTelnetPort ( StrToNum<int> ( optarg, E ) );
477  if ( E )
478  {
479  cerr << "invalid value for TelnetPort: '" << optarg << "'" << endl;
480  exit ( 1 );
481  }
482  break;
483  case 'b':
484  Servant.SetAdminPort ( StrToNum<int> ( optarg, E ) );
485  if ( E )
486  {
487  cerr << "invalid value for AdminPort: '" << optarg << "'" << endl;
488  exit ( 1 );
489  }
490  break;
491  case 'c':
492  ProcessConfig ( optarg );
493  break;
494  case 'p':
495  Servant.SetDataPort ( StrToNum<int> ( optarg, E ) );
496  if ( E )
497  {
498  cerr << "invalid value for DataPort: '"
499  << optarg << "'" << endl;
500  exit ( 1 );
501  }
502  break;
503  case 'o':
504  Servant.SetOutOfReach ( StrToNum<int> ( optarg, E ) );
505  if ( E )
506  {
507  cerr << "invalid value for OutOfReach: '"
508  << optarg << "'" << endl;
509  exit ( 1 );
510  }
511  break;
512  case 'v':
513  curr_priority = (sgDebugPriority) StrToNum<int> ( optarg, E );
514  Servant.SetLog ( curr_class, curr_priority );
515  if ( E )
516  {
517  cerr << "invalid value for Loglevel: '"
518  << optarg << "'" << endl;
519  exit ( 1 );
520  }
521  break;
522  case 't':
523  Servant.SetPlayerExpires ( StrToNum<int> ( optarg, E ) );
524  if ( E )
525  {
526  cerr << "invalid value for expire: '"
527  << optarg << "'" << endl;
528  exit ( 1 );
529  }
530  break;
531  case 'l':
532  Servant.SetLogfile ( optarg );
533  break;
534  case 'd':
535  RunAsDaemon = false;
536  break;
537  case 'D':
538  RunAsDaemon = true;
539  break;
540  default:
541  cerr << endl << endl;
542  PrintHelp ();
543  exit ( 1 );
544  } // switch ()
545  } // while ()
546  return ( 1 ); // success
547 } // ParseParams()
548 
549 //////////////////////////////////////////////////////////////////////
550 /**
551  * @brief (re)Read config files
552  * @param ReInit True to reinitialize
553  */
554 int
555 ReadConfigs ( bool ReInit = false )
556 {
557  string Path;
558 #ifndef _MSC_VER
559  Path = SYSCONFDIR;
560  Path += "/" DEF_CONF_FILE; // fgms.conf
561  if ( ProcessConfig ( Path ) == true )
562  {
563  return 1;
564  }
565  Path = getenv ( "HOME" );
566 #else
567  char* cp = getenv ( "HOME" );
568  if ( cp )
569  {
570  Path = cp;
571  }
572  else
573  {
574  cp = getenv ( "USERPROFILE" ); // XP=C:\Documents and Settings<name>, Win7=C:\Users<user>
575  if ( cp )
576  {
577  Path = cp;
578  }
579  }
580 #endif
581  if ( Path != "" )
582  {
583  Path += "/" DEF_CONF_FILE;
584  if ( ProcessConfig ( Path ) )
585  {
586  return 1;
587  }
588  }
589  if ( ProcessConfig ( DEF_CONF_FILE ) )
590  {
591  return 1;
592  }
593  return 0;
594 } // ReadConfigs ()
595 
596 
597 
598 //////////////////////////////////////////////////////////////////////
599 /**
600  * @brief If we receive a SIGHUP, reinit application
601  * @param SigType int with signal type
602  */
603 void SigHUPHandler ( int SigType )
604 {
605  Servant.PrepareInit();
606  bHadConfig = false;
607  if (Servant.ConfigFile == "")
608  {
609  if ( !ReadConfigs ( true ) )
610  {
611  SG_LOG ( SG_SYSTEMS, SG_ALERT, "received HUP signal, but read config file failed!" );
612  exit ( 1 );
613  }
614  }
615  else
616  {
617  if ( ProcessConfig ( Servant.ConfigFile ) == false )
618  {
619  SG_LOG ( SG_SYSTEMS, SG_ALERT, "received HUP signal, but read config file failed!" );
620  exit ( 1 );
621  }
622  }
623  if ( Servant.Init () != 0 )
624  {
625  SG_LOG ( SG_SYSTEMS, SG_ALERT, "received HUP signal, but reinit failed!" );
626  exit ( 1 );
627  }
628 #ifndef _MSC_VER
629  signal ( SigType, SigHUPHandler );
630 #endif
631 } // SigHUPHandler ()
632 //////////////////////////////////////////////////////////////////////
633 
634 //////////////////////////////////////////////////////////////////////
635 /**
636  * @brief MAIN routine
637  * @param argc
638  * @param argv*[]
639  */
640 int
641 main ( int argc, char* argv[] )
642 {
643  int I;
644 #ifndef _MSC_VER
645  signal ( SIGHUP, SigHUPHandler );
646 #endif
647  ParseParams ( argc, argv );
648  ReadConfigs ();
649  if ( !bHadConfig )
650  {
651  SG_LOG ( SG_SYSTEMS, SG_ALERT, "No configuration file '" << DEF_CONF_FILE << "' found!" );
652  exit ( 1 );
653  }
654 #ifndef _MSC_VER
655  if ( RunAsDaemon )
656  {
657  Myself.Daemonize ();
658  }
659 #endif
660  I = Servant.Init ();
661  if ( I != 0 )
662  {
663  Servant.CloseTracker();
664  return ( I );
665  }
666  SG_CONSOLE ( SG_SYSTEMS, SG_ALERT, "Main server started!" );
667  I = Servant.Loop();
668  Servant.CloseTracker();
669  Servant.Done();
670  return ( I );
671 } // main()
672 //////////////////////////////////////////////////////////////////////
673 
Simple config file parser.
Definition: fg_config.hxx:46
void PrintHelp()
Print a help screen for command line parameters, see command_line.
Definition: main.cxx:97
void SetAdminPort(int Port)
Set listening port for admin connections.
Definition: fg_server.cxx:1760
sgDebugClass curr_class
Definition: main.cxx:90
string ConfigFile
Definition: fg_server.hxx:125
cDaemon Myself
An instance of cDaemon.
Definition: fg_server.cxx:56
bool AddCLI
Definition: fg_server.cxx:60
void CloseTracker()
Cleanly closes the tracker.
Definition: fg_server.cxx:2087
int Read(const std::string &ConfigName)
Read in the config file.
Definition: fg_config.cxx:42
void SetLogfile(const std::string &LogfileName)
Set the logfile.
Definition: fg_server.cxx:1860
int AddTracker(const string &Server, int Port, bool IsTracked)
Add a tracking server.
Definition: fg_server.cxx:914
void SetLog(int Facility, int Priority)
Set the default loglevel.
Definition: fg_server.cxx:1845
void Done()
Close sockets, logfile etc.
Definition: fg_server.cxx:1924
int main(int argc, char *argv[])
MAIN routine.
Definition: main.cxx:641
#define DEF_CONF_FILE
The default config file to load unless overriden on command_line.
Definition: main.cxx:68
void AddRelay(const string &Server, int Port)
Insert a new relay server into internal list.
Definition: fg_server.cxx:825
sgDebugPriority
Define the possible logging priorities (and their order).
Definition: debug_types.h:24
static bool bHadConfig
Must have a config file, with server name.
Definition: main.cxx:62
static char E[48]
Definition: crypt-win.c:146
#define SG_LOG(C, P, M)
Definition: logstream.hxx:412
#define DEF_LOG_CLASS
Definition: main.cxx:85
int SecNext()
Set internal pointer to next variable in a section.
Definition: fg_config.cxx:205
void SetTelnetPort(int Port)
Set listening port for telnets.
Definition: fg_server.cxx:1743
#define SYSCONFDIR
The default config directory.
Definition: main.cxx:75
void SetAdminUser(string User)
Set User for admin connections.
Definition: fg_server.cxx:1777
bool RunAsDaemon
Flag whether instance is a Daemon.
Definition: fg_server.cxx:59
bool ProcessConfig(const string &ConfigName)
Read a config file and set internal variables accordingly.
Definition: main.cxx:173
int Loop()
Main loop of the server.
Definition: fg_server.cxx:1576
std::string GetValue()
Returns the current variable's value.
Definition: fg_config.cxx:159
FG_SERVER Servant
The running FG_SERVER server process.
Definition: main.cxx:48
int SetSection(const std::string &SecName)
Set internal pointer to the first variable of a section.
Definition: fg_config.cxx:179
int ParseParams(int argcount, char *argvars[])
Parse commandline parameters.
Definition: main.cxx:462
std::string GetName()
Returns the complete name of the current variable.
Definition: fg_config.cxx:141
void SetOutOfReach(int OutOfReach)
Set nautical miles two players must be apart to be out of reach.
Definition: fg_server.cxx:1831
Very possible impending problem.
Definition: debug_types.h:38
sgDebugClass
Define the possible classes/categories of logging messages.
Definition: debug_types.h:8
static int Daemonize()
Installs the signal-handler and makes ourself a daemon.
Definition: daemon.cxx:168
void SetAdminEnable(string Enable)
Set enable password for admin connections.
Definition: fg_server.cxx:1803
void AddBlacklist(const string &DottedIP, const string &Reason, time_t Timeout=10)
Add an IP to the blacklist.
Definition: fg_server.cxx:933
void SigHUPHandler(int SigType)
If we receive a SIGHUP, reinit application.
Definition: main.cxx:603
Implement everything necessary to become a daemon.
Definition: daemon.hxx:43
void SetServerName(const std::string &ServerName)
Set the server name.
Definition: fg_server.cxx:1896
void SetHub(bool IamHUB)
Set if we are running as a Hubserver.
Definition: fg_server.cxx:1882
void PrepareInit()
Do anything necessary to (re-) init the server used to handle kill -HUP.
Definition: fg_server.cxx:506
int Init()
Basic initialization.
Definition: fg_server.cxx:290
void AddCrossfeed(const string &Server, int Port)
Insert a new crossfeed server into internal list.
Definition: fg_server.cxx:881
std::string Get(const std::string &VarName)
Find a variable in the internal list and return its value.
Definition: fg_config.cxx:81
The Main fgms Class.
Definition: fg_server.hxx:55
void SetAdminPass(string Pass)
Set Password for admin connections.
Definition: fg_server.cxx:1790
#define DEF_LOG_LEVEL
Definition: main.cxx:79
sgDebugPriority curr_priority
Definition: main.cxx:89
void SetBindAddress(const std::string &BindAddress)
Set the address this server listens on.
Definition: fg_server.cxx:1910
int ReadConfigs(bool ReInit=false)
(re)Read config files
Definition: main.cxx:555
void SetPlayerExpires(int Seconds)
Set time in seconds. if no packet arrives from a client within this time, the connection is dropped...
Definition: fg_server.cxx:1817
void SetDataPort(int Port)
Set listening port for incoming clients.
Definition: fg_server.cxx:1725