00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "services.h"
00016 #include "pseudo.h"
00017 int servernum = 0;
00018
00019 extern void moduleAddMsgs(void);
00020 extern void moduleAddIRCDMsgs(void);
00021
00022
00023
00024 void introduce_user(const char *user)
00025 {
00026
00027
00028 #define LTSIZE 20
00029 static int lasttimes[LTSIZE];
00030 if (lasttimes[0] >= time(NULL) - 3)
00031 fatal("introduce_user() loop detected");
00032 memmove(lasttimes, lasttimes + 1, sizeof(lasttimes) - sizeof(int));
00033 lasttimes[LTSIZE - 1] = time(NULL);
00034 #undef LTSIZE
00035
00036
00037 if (!user || stricmp(user, s_NickServ) == 0) {
00038 anope_cmd_nick(s_NickServ, desc_NickServ, ircd->nickservmode);
00039 }
00040
00041
00042 if (!user || stricmp(user, s_ChanServ) == 0) {
00043 anope_cmd_nick(s_ChanServ, desc_ChanServ, ircd->chanservmode);
00044 }
00045 if (s_HostServ && ircd->vhost
00046 && (!user || stricmp(user, s_HostServ) == 0)) {
00047 anope_cmd_nick(s_HostServ, desc_HostServ, ircd->hostservmode);
00048 }
00049
00050 if (!user || stricmp(user, s_MemoServ) == 0) {
00051 anope_cmd_nick(s_MemoServ, desc_MemoServ, ircd->memoservmode);
00052 }
00053
00054 if (s_BotServ && (!user || stricmp(user, s_BotServ) == 0)) {
00055 anope_cmd_nick(s_BotServ, desc_BotServ, ircd->botservmode);
00056 }
00057
00058 if (!user || stricmp(user, s_HelpServ) == 0) {
00059 anope_cmd_nick(s_HelpServ, desc_HelpServ, ircd->helpservmode);
00060 }
00061
00062 if (!user || stricmp(user, s_OperServ) == 0) {
00063 anope_cmd_nick(s_OperServ, desc_OperServ, ircd->operservmode);
00064 }
00065
00066 if (s_DevNull && (!user || stricmp(user, s_DevNull) == 0)) {
00067 anope_cmd_nick(s_DevNull, desc_DevNull, ircd->devnullmode);
00068 }
00069
00070 if (!user || stricmp(user, s_GlobalNoticer) == 0) {
00071 anope_cmd_nick(s_GlobalNoticer, desc_GlobalNoticer,
00072 ircd->globalmode);
00073 }
00074
00075
00076 if (s_NickServAlias && (!user || stricmp(user, s_NickServAlias) == 0)) {
00077 anope_cmd_nick(s_NickServAlias, desc_NickServAlias,
00078 ircd->nickservaliasmode);
00079 }
00080
00081 if (s_ChanServAlias && (!user || stricmp(user, s_ChanServAlias) == 0)) {
00082 anope_cmd_nick(s_ChanServAlias, desc_ChanServAlias,
00083 ircd->chanservaliasmode);
00084 }
00085
00086 if (s_MemoServAlias && (!user || stricmp(user, s_MemoServAlias) == 0)) {
00087 anope_cmd_nick(s_MemoServAlias, desc_MemoServAlias,
00088 ircd->memoservaliasmode);
00089 }
00090
00091 if (s_BotServAlias && (!user || stricmp(user, s_BotServAlias) == 0)) {
00092 anope_cmd_nick(s_BotServAlias, desc_BotServAlias,
00093 ircd->botservaliasmode);
00094 }
00095
00096 if (s_HelpServAlias && (!user || stricmp(user, s_HelpServAlias) == 0)) {
00097 anope_cmd_nick(s_HelpServAlias, desc_HelpServAlias,
00098 ircd->helpservaliasmode);
00099 }
00100
00101 if (s_OperServAlias && (!user || stricmp(user, s_OperServAlias) == 0)) {
00102 anope_cmd_nick(s_OperServAlias, desc_OperServAlias,
00103 ircd->operservaliasmode);
00104 }
00105
00106 if (s_DevNullAlias && (!user || stricmp(user, s_DevNullAlias) == 0)) {
00107 anope_cmd_nick(s_DevNullAlias, desc_DevNullAlias,
00108 ircd->devnullvaliasmode);
00109 }
00110 if (s_HostServAlias && ircd->vhost
00111 && (!user || stricmp(user, s_HostServAlias) == 0)) {
00112 anope_cmd_nick(s_HostServAlias, desc_HostServAlias,
00113 ircd->hostservaliasmode);
00114 }
00115 if (s_GlobalNoticerAlias
00116 && (!user || stricmp(user, s_GlobalNoticerAlias) == 0)) {
00117 anope_cmd_nick(s_GlobalNoticerAlias, desc_GlobalNoticerAlias,
00118 ircd->globalaliasmode);
00119 }
00120
00121
00122 if (s_BotServ) {
00123 BotInfo *bi;
00124 int i;
00125
00126 for (i = 0; i < 256; i++)
00127 for (bi = botlists[i]; bi; bi = bi->next) {
00128
00129 if (!user || !stricmp(user, bi->nick))
00130 anope_cmd_bot_nick(bi->nick, bi->user, bi->host,
00131 bi->real, ircd->botserv_bot_mode);
00132 }
00133 }
00134 }
00135
00136
00137
00138
00139
00140
00141
00142 static int set_group(void)
00143 {
00144 #if defined(RUNGROUP) && defined(HAVE_SETGRENT)
00145 struct group *gr;
00146
00147 setgrent();
00148 while ((gr = getgrent()) != NULL) {
00149 if (strcmp(gr->gr_name, RUNGROUP) == 0)
00150 break;
00151 }
00152 endgrent();
00153 if (gr) {
00154 setgid(gr->gr_gid);
00155 return 0;
00156 } else {
00157 alog("Unknown group `%s'\n", RUNGROUP);
00158 return -1;
00159 }
00160 #else
00161 return 0;
00162 #endif
00163 }
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173 static int parse_dir_options(int ac, char **av)
00174 {
00175 int i;
00176 char *s;
00177
00178 for (i = 1; i < ac; i++) {
00179 s = av[i];
00180 if (*s == '-') {
00181 s++;
00182 if (strcmp(s, "dir") == 0) {
00183 if (++i >= ac) {
00184 fprintf(stderr, "-dir requires a parameter\n");
00185 return -1;
00186 }
00187 services_dir = av[i];
00188 } else if (strcmp(s, "log") == 0) {
00189 if (++i >= ac) {
00190 fprintf(stderr, "-log requires a parameter\n");
00191 return -1;
00192 }
00193 log_filename = av[i];
00194 } else if (strcmp(s, "version") == 0) {
00195 fprintf(stdout, "Anope-%s %s -- %s\n", version_number,
00196 version_flags, version_build);
00197 exit(EXIT_SUCCESS);
00198 }
00199 }
00200 }
00201 return 0;
00202 }
00203
00204
00205
00206
00207
00208
00209
00210 static int parse_options(int ac, char **av)
00211 {
00212 int i;
00213 char *s, *t;
00214
00215 for (i = 1; i < ac; i++) {
00216 s = av[i];
00217 if (*s == '-') {
00218 s++;
00219 if (strcmp(s, "remote") == 0) {
00220 if (++i >= ac) {
00221 fprintf(stderr, "-remote requires hostname[:port]\n");
00222 return -1;
00223 }
00224 s = av[i];
00225 t = strchr(s, ':');
00226 if (t) {
00227 int portnum;
00228 *t++ = 0;
00229 portnum = atoi(t);
00230 if ((portnum > 0) && (portnum < 65535))
00231 RemotePort = portnum;
00232 else {
00233 fprintf(stderr,
00234 "-remote: Port numbers must be in the range 1..65535. Using default.\n");
00235 return -1;
00236 }
00237 }
00238 RemoteServer = s;
00239 } else if (strcmp(s, "local") == 0) {
00240 if (++i >= ac) {
00241 fprintf(stderr,
00242 "-local requires hostname or [hostname]:[port]\n");
00243 return -1;
00244 }
00245 s = av[i];
00246 t = strchr(s, ':');
00247 if (t) {
00248 int portnum;
00249 *t++ = 0;
00250 portnum = atoi(t);
00251 if ((portnum >= 0) && (portnum < 65535))
00252 LocalPort = portnum;
00253 else {
00254 fprintf(stderr,
00255 "-local: Port numbers must be in the range 1..65535 or 0. Using default.\n");
00256 return -1;
00257 }
00258 }
00259 LocalHost = s;
00260 } else if (strcmp(s, "name") == 0) {
00261 if (++i >= ac) {
00262 fprintf(stderr, "-name requires a parameter\n");
00263 return -1;
00264 }
00265 ServerName = av[i];
00266 } else if (strcmp(s, "desc") == 0) {
00267 if (++i >= ac) {
00268 fprintf(stderr, "-desc requires a parameter\n");
00269 return -1;
00270 }
00271 ServerDesc = av[i];
00272 } else if (strcmp(s, "user") == 0) {
00273 if (++i >= ac) {
00274 fprintf(stderr, "-user requires a parameter\n");
00275 return -1;
00276 }
00277 ServiceUser = av[i];
00278 } else if (strcmp(s, "host") == 0) {
00279 if (++i >= ac) {
00280 fprintf(stderr, "-host requires a parameter\n");
00281 return -1;
00282 }
00283 ServiceHost = av[i];
00284 } else if (strcmp(s, "dir") == 0) {
00285
00286 i++;
00287 } else if (strcmp(s, "log") == 0) {
00288
00289 i++;
00290 } else if (strcmp(s, "update") == 0) {
00291 if (++i >= ac) {
00292 fprintf(stderr, "-update requires a parameter\n");
00293 return -1;
00294 }
00295 s = av[i];
00296 if (atoi(s) <= 0) {
00297 fprintf(stderr,
00298 "-update: number of seconds must be positive");
00299 return -1;
00300 } else
00301 UpdateTimeout = atol(s);
00302 } else if (strcmp(s, "expire") == 0) {
00303 if (++i >= ac) {
00304 fprintf(stderr, "-expire requires a parameter\n");
00305 return -1;
00306 }
00307 s = av[i];
00308 if (atoi(s) <= 0) {
00309 fprintf(stderr,
00310 "-expire: number of seconds must be positive");
00311 return -1;
00312 } else
00313 ExpireTimeout = atol(s);
00314 } else if (strcmp(s, "debug") == 0) {
00315 debug++;
00316 } else if (strcmp(s, "readonly") == 0) {
00317 readonly = 1;
00318 skeleton = 0;
00319 } else if (strcmp(s, "skeleton") == 0) {
00320 readonly = 0;
00321 skeleton = 1;
00322 } else if (strcmp(s, "nofork") == 0) {
00323 nofork = 1;
00324 } else if (strcmp(s, "logchan") == 0) {
00325 logchan = 1;
00326 } else if (strcmp(s, "forceload") == 0) {
00327 forceload = 1;
00328 } else if (strcmp(s, "nothird") == 0) {
00329 nothird = 1;
00330 } else if (strcmp(s, "protocoldebug") == 0) {
00331 protocoldebug = 1;
00332 } else if (strcmp(s, "support") == 0) {
00333 nofork = 1;
00334 debug++;
00335 nothird = 1;
00336 } else if (!strcmp(s, "noexpire")) {
00337 noexpire = 1;
00338 } else if (!strcmp(s, "help")) {
00339 fprintf(stdout, "Anope-%s %s -- %s\n", version_number,
00340 version_flags, version_build);
00341 fprintf(stdout,
00342 "Anope IRC Services (http://www.anope.org)\n");
00343 fprintf(stdout, "Usage ./services [options] ...\n");
00344 fprintf(stdout,
00345 "-remote -remote hostname[:port]\n");
00346 fprintf(stdout, "-local -local hostname[:port]\n");
00347 fprintf(stdout, "-name -name servername\n");
00348 fprintf(stdout, "-desc -desc serverdesc\n");
00349 fprintf(stdout, "-user -user serviceuser\n");
00350 fprintf(stdout, "-host -host servicehost\n");
00351 fprintf(stdout,
00352 "-update -update updatetime(secs)\n");
00353 fprintf(stdout,
00354 "-expire -expire expiretime(secs)\n");
00355 fprintf(stdout, "-debug -debug\n");
00356 fprintf(stdout, "-nofork -nofork\n");
00357 fprintf(stdout, "-logchan -logchan channelname\n");
00358 fprintf(stdout, "-skeleton -skeleton\n");
00359 fprintf(stdout, "-forceload -forceload\n");
00360 fprintf(stdout, "-nothird -nothird\n");
00361 fprintf(stdout, "-support -support\n");
00362 fprintf(stdout, "-readonly -readonly\n");
00363 fprintf(stdout, "-noexpire -noexpire\n");
00364 fprintf(stdout, "-version -version\n");
00365 fprintf(stdout, "-help -help\n");
00366 fprintf(stdout, "-log -log logfilename\n");
00367 fprintf(stdout,
00368 "-dir -dir servicesdirectory\n\n");
00369 fprintf(stdout,
00370 "Further support is available from http://www.anope.org\n");
00371 fprintf(stdout,
00372 "Or visit US on IRC at irc.anope.org #anope\n");
00373 exit(EXIT_SUCCESS);
00374 } else {
00375 fprintf(stderr, "Unknown option -%s\n", s);
00376 return -1;
00377 }
00378 } else {
00379 fprintf(stderr, "Non-option arguments not allowed\n");
00380 return -1;
00381 }
00382 }
00383 return 0;
00384 }
00385
00386
00387
00388
00389
00390 static void remove_pidfile(void)
00391 {
00392 remove(PIDFilename);
00393 }
00394
00395
00396
00397
00398
00399 static void write_pidfile(void)
00400 {
00401 FILE *pidfile;
00402
00403 pidfile = fopen(PIDFilename, "w");
00404 if (pidfile) {
00405 fprintf(pidfile, "%d\n", (int) getpid());
00406 fclose(pidfile);
00407 atexit(remove_pidfile);
00408 } else {
00409 log_perror("Warning: cannot write to PID file %s", PIDFilename);
00410 }
00411 }
00412
00413
00414
00415
00416
00417 int openlog_failed = 0, openlog_errno = 0;
00418
00419 int init_primary(int ac, char **av)
00420 {
00421 int started_from_term = isatty(0) && isatty(1) && isatty(2);
00422
00423
00424 #if defined(DEFUMASK) && HAVE_UMASK
00425 umask(DEFUMASK);
00426 #endif
00427 if (set_group() < 0)
00428 return -1;
00429
00430
00431 parse_dir_options(ac, av);
00432
00433
00434 if (chdir(services_dir) < 0) {
00435 fprintf(stderr, "chdir(%s): %s\n", services_dir, strerror(errno));
00436 return -1;
00437 }
00438
00439
00440 if (open_log() < 0) {
00441 openlog_errno = errno;
00442 if (started_from_term) {
00443 fprintf(stderr, "Warning: unable to open log file %s: %s\n",
00444 log_filename, strerror(errno));
00445 } else {
00446 openlog_failed = 1;
00447 }
00448 }
00449
00450
00451 if (!read_config(0)) {
00452 return -1;
00453 }
00454
00455
00456 if (protocol_module_init()) {
00457 return -1;
00458 }
00459
00460
00461 if (encryption_module_init()) {
00462 return -1;
00463 }
00464 return 0;
00465 }
00466
00467 int init_secondary(int ac, char **av)
00468 {
00469 int i;
00470 int started_from_term = isatty(0) && isatty(1) && isatty(2);
00471
00472
00473 moduleAddMsgs();
00474
00475
00476 parse_options(ac, av);
00477
00478
00479 if (DefConLevel) {
00480 int defconCount;
00481 for (defconCount = 1; defconCount <= 5; defconCount++) {
00482 if (!defconParseModeString(DefConChanModes)) {
00483 fprintf(stderr,
00484 "services.conf: The given DefConChanModes mode string was incorrect (see log for exact errors)\n");
00485 return -1;
00486 }
00487 }
00488 }
00489 #ifndef _WIN32
00490 if (!nofork) {
00491 if ((i = fork()) < 0) {
00492 perror("fork()");
00493 return -1;
00494 } else if (i != 0) {
00495 exit(0);
00496 }
00497 if (started_from_term) {
00498 close(0);
00499 close(1);
00500 close(2);
00501 }
00502 if (setpgid(0, 0) < 0) {
00503 perror("setpgid()");
00504 return -1;
00505 }
00506 }
00507 #else
00508
00509 {
00510 WSADATA wsa;
00511 if (WSAStartup(MAKEWORD(1, 1), &wsa)) {
00512 alog("Failed to initialized WinSock library");
00513 return -1;
00514 }
00515 }
00516 if (!SupportedWindowsVersion()) {
00517
00518 char *winver = GetWindowsVersion();
00519
00520 alog("%s is not a supported version of Windows", winver);
00521
00522 free(winver);
00523
00524 return -1;
00525
00526 }
00527 if (!nofork) {
00528 alog("Launching Anope into the background");
00529 FreeConsole();
00530 }
00531 #endif
00532
00533
00534 write_pidfile();
00535
00536
00537 if (debug || readonly || skeleton) {
00538 alog("Anope %s (ircd protocol: %s) starting up (options:%s%s%s)",
00539 version_number, version_protocol,
00540 debug ? " debug" : "", readonly ? " readonly" : "",
00541 skeleton ? " skeleton" : "");
00542 } else {
00543 alog("Anope %s (ircd protocol: %s) starting up",
00544 version_number, version_protocol);
00545 }
00546 start_time = time(NULL);
00547
00548
00549
00550
00551 if (readonly)
00552 close_log();
00553
00554
00555
00556
00557
00558 #ifndef _WIN32
00559 #if defined(NSIG)
00560 for (i = 1; i <= NSIG - 1; i++) {
00561 #else
00562 for (i = 1; i <= 31; i++) {
00563 #endif
00564 signal(i, SIG_IGN);
00565 }
00566 #else
00567
00568 signal(SIGILL, SIG_IGN);
00569 signal(SIGBREAK, SIG_IGN);
00570 signal(SIGABRT, SIG_IGN);
00571 #endif
00572
00573 signal(SIGINT, sighandler);
00574 signal(SIGTERM, sighandler);
00575 #ifndef _WIN32
00576 signal(SIGQUIT, sighandler);
00577 #endif
00578 if (!DumpCore) {
00579 signal(SIGSEGV, sighandler);
00580 #ifndef _WIN32
00581 signal(SIGBUS, sighandler);
00582 signal(SIGTRAP, sighandler);
00583 #endif
00584 } else {
00585 signal(SIGSEGV, SIG_DFL);
00586 #ifndef _WIN32
00587 signal(SIGBUS, sighandler);
00588 signal(SIGTRAP, sighandler);
00589 #endif
00590 }
00591 #ifndef _WIN32
00592 signal(SIGQUIT, sighandler);
00593 signal(SIGHUP, sighandler);
00594 signal(SIGUSR2, sighandler);
00595 #endif
00596
00597 #ifdef SIGIOT
00598 signal(SIGIOT, sighandler);
00599 #endif
00600 signal(SIGFPE, sighandler);
00601
00602 #ifndef _WIN32
00603 signal(SIGUSR1, sighandler);
00604 #endif
00605
00606
00607 lang_init();
00608 if (debug)
00609 alog("debug: Loaded languages");
00610
00611
00612
00613 ns_init();
00614 cs_init();
00615 ms_init();
00616 bs_init();
00617 os_init();
00618 hostserv_init();
00619 helpserv_init();
00620
00621 #ifdef USE_RDB
00622 if (!rdb_init()) {
00623 if (UseRDB) {
00624 UseRDB = 0;
00625 alog("Error: Disabling UseRDB due to errors with SQL");
00626 }
00627 } else {
00628 if (MysqlSecure && UseRDB) {
00629 UseRDB = 0;
00630 alog("Error: MySQL password are encrypted using method in MysqlSecure disabling UseRDB");
00631 }
00632 }
00633 #endif
00634
00635
00636 modules_init();
00637
00638
00639 rand_init();
00640 add_entropy_userkeys();
00641
00642
00643 #ifdef USE_RDB
00644 if (UseRDB)
00645 rdb_load_dbases();
00646
00647 if (!UseRDB) {
00648 #endif
00649 if (!skeleton) {
00650 load_ns_dbase();
00651 if (debug)
00652 alog("debug: Loaded %s database (1/%d)", s_NickServ,
00653 (PreNickDBName ? 8 : 7));
00654 if (s_HostServ) {
00655 load_hs_dbase();
00656 if (debug)
00657 alog("debug: Loaded %s database (2/%d)", s_HostServ,
00658 (PreNickDBName ? 8 : 7));
00659 }
00660 if (s_BotServ) {
00661 load_bs_dbase();
00662 if (debug)
00663 alog("debug: Loaded %s database (3/%d)", s_BotServ,
00664 (PreNickDBName ? 8 : 7));
00665 } else if (debug)
00666 alog("debug: BotServ database (3/%d) not loaded because BotServ is disabled", (PreNickDBName ? 8 : 7));
00667 load_cs_dbase();
00668 if (debug)
00669 alog("debug: Loaded %s database (4/%d)", s_ChanServ,
00670 (PreNickDBName ? 8 : 7));
00671 }
00672 load_os_dbase();
00673 if (debug)
00674 alog("debug: Loaded %s database (5/%d)", s_OperServ,
00675 (PreNickDBName ? 8 : 7));
00676 load_news();
00677 if (debug)
00678 alog("debug: Loaded news database (6/%d)",
00679 (PreNickDBName ? 8 : 7));
00680 load_exceptions();
00681 if (debug)
00682 alog("debug: Loaded exception database (7/%d)",
00683 (PreNickDBName ? 8 : 7));
00684 if (PreNickDBName) {
00685 load_ns_req_db();
00686 if (debug)
00687 alog("debug: Loaded PreNick database (8/8)");
00688 }
00689 #ifdef USE_RDB
00690 }
00691 #endif
00692 alog("Databases loaded");
00693
00694
00695 #ifdef USE_RDB
00696 if (!UseRDB) {
00697
00698
00699
00700 #endif
00701 alog("Info: Reflecting database records.");
00702 save_databases();
00703 #ifdef USE_RDB
00704 } else {
00705 alog("Info: Not reflecting database records.");
00706 }
00707 #endif
00708 send_event(EVENT_CONNECT, 1, EVENT_START);
00709
00710
00711 servsock = conn(RemoteServer, RemotePort, LocalHost, LocalPort);
00712 if (servsock < 0 && RemoteServer2) {
00713 servsock = conn(RemoteServer2, RemotePort2, LocalHost, LocalPort);
00714 if (servsock < 0 && RemoteServer3) {
00715 servsock =
00716 conn(RemoteServer3, RemotePort3, LocalHost, LocalPort);
00717 if (servsock < 0) {
00718 fatal_perror("Can't connect to server");
00719 } else {
00720 servernum = 3;
00721 alog("Connected to Server %d (%s:%d)", servernum,
00722 RemoteServer3, RemotePort3);
00723 }
00724 } else {
00725 if (servsock < 0) {
00726 fatal_perror("Can't connect to server");
00727 }
00728 servernum = 2;
00729 alog("Connected to Server %d (%s:%d)", servernum,
00730 RemoteServer2, RemotePort2);
00731 }
00732 } else {
00733 if (servsock < 0) {
00734 fatal_perror("Can't connect to server");
00735 }
00736 servernum = 1;
00737 alog("Connected to Server %d (%s:%d)", servernum, RemoteServer,
00738 RemotePort);
00739 }
00740
00741 anope_cmd_connect(servernum);
00742 send_event(EVENT_CONNECT, 1, EVENT_STOP);
00743
00744 sgets2(inbuf, sizeof(inbuf), servsock);
00745 if (strnicmp(inbuf, "ERROR", 5) == 0) {
00746
00747
00748 disconn(servsock);
00749 servsock = -1;
00750 fatal("Remote server returned: %s", inbuf);
00751 }
00752
00753
00754 if (openlog_failed) {
00755 anope_cmd_global(NULL, "Warning: couldn't open logfile: %s",
00756 strerror(openlog_errno));
00757 }
00758
00759
00760 introduce_user(NULL);
00761
00762
00763 if (logchan && ircd->join2msg) {
00764
00765 anope_cmd_join(s_GlobalNoticer, LogChannel, time(NULL));
00766 }
00767
00768 anope_cmd_eob();
00769
00774 modules_delayed_init();
00775
00776
00777 return 0;
00778 }
00779
00780