/* * Return a linked list that contains elements according to specified set * operation (setop). If there aren't options, return NULL. */ stringList * setOperationOptions(char *a, char *b, int setop, bool withvalue, bool changed) { stringList *first, *second; stringList *ret = NULL; stringListCell *headitem = NULL; logNoise("options: set operation %d", setop); /* if a is NULL, there is neither intersection nor complement (except) */ if (a == NULL) return NULL; /* if b is NULL, there isn't intersection */ if (setop == PGQ_INTERSECT && b == NULL) return NULL; first = buildStringList(a); second = buildStringList(b); if (setop == PGQ_INTERSECT) headitem = intersectWithSortedLists(first->head, second->head, withvalue, changed); else if (setop == PGQ_SETDIFFERENCE) headitem = setDifferenceWithSortedLists(first->head, second->head, withvalue); else logError("set operation not supported"); /* build a linked list */ if (headitem) { stringListCell *p; ret = (stringList *) malloc(sizeof(stringList)); /* linked list head */ ret->head = headitem; /* find linked list tail */ p = headitem; while (p->next) p = p->next; ret->tail = p; } /* free temporary lists */ if (first) freeStringList(first); if (second) freeStringList(second); return ret; }
int read_config(int reload) { FILE *config; int linenum = 0, retval = 1; char buf[1024], *s; int defconCount = 0; if (reload) { int i, n; /* Reset all the reloadable settings */ for (n = 0; n < lenof(directives); n++) { Directive *d = &directives[n]; for (i = 0; i < MAXPARAMS && d->params[i].type != PARAM_NONE; i++) { if (!(d->params[i].flags & PARAM_RELOAD)) continue; if (d->params[i].type == PARAM_SET || d->params[i].type == PARAM_INT || d->params[i].type == PARAM_POSINT || d->params[i].type == PARAM_TIME) { *(int *) d->params[i].ptr = 0; } else if (d->params[i].type == PARAM_STRING) { if (*(char **) d->params[i].ptr) free(*(char **) d->params[i].ptr); (*(char **) d->params[i].ptr) = NULL; } } } } config = fopen(SERVICES_CONF, "r"); if (!config) { #ifndef NOT_MAIN log_perror("Can't open " SERVICES_CONF); if (!nofork && isatty(2)) { #endif if (!reload) perror("Can't open " SERVICES_CONF); else alog("Can't open %s", SERVICES_CONF); #ifndef NOT_MAIN } #endif return 0; } while (fgets(buf, sizeof(buf), config)) { linenum++; if (*buf == '#' || *buf == '\r' || *buf == '\n') continue; if (!parse(buf, linenum, reload)) retval = 0; } fclose(config); if (!reload) { CHECK(RemoteServer); CHECK(ServerName); CHECK(ServerDesc); if (RemoteServer3) CHECK(RemoteServer2); if (LocalHost && RemoteServer) { if ((!stricmp(LocalHost, RemoteServer)) && LocalPort == RemotePort) { printf ("\n*** LocalAddress and RemoteServer are set to use the same IP address\n" "*** (%s) and port (%d). This would have resulted in errors.\n" "*** Change the LocalAddress to bind to another port.\n", RemoteServer, LocalPort); retval = 0; } } if (NickLen == 0) { alog("You have not defined the NickLen configuration directive. It is strongly"); alog("advised that you do configure this correctly in your services.conf"); NickLen = NICKMAX - 1; } else if ((NickLen < 1) || (NickLen >= NICKMAX)) { alog("NickLen has an invalid value; setting to %d", (NICKMAX - 1)); NickLen = NICKMAX - 1; } } CHECK(IRCDModule); CHECK(EncModule); CHECK(NetworkName); if (!reload) { CHEK2(temp_userhost, ServiceUser); CHEK2(s_NickServ, NickServName); CHEK2(s_ChanServ, ChanServName); CHEK2(s_MemoServ, MemoServName); CHEK2(s_HelpServ, HelpServName); CHEK2(s_OperServ, OperServName); CHEK2(s_GlobalNoticer, GlobalName); CHEK2(PIDFilename, PIDFile); } if (s_ChanServAlias) { if (!stricmp(s_ChanServ, s_ChanServAlias)) { printf ("\n*** ChanServ and ChanServ Alias are the same, this will cause errors\n"); retval = 0; } } if (s_NickServAlias) { if (!stricmp(s_NickServ, s_NickServAlias)) { printf ("\n*** NickServ and NickServ Alias are the same, this will cause errors\n"); retval = 0; } } if (s_OperServAlias) { if (!stricmp(s_OperServ, s_OperServAlias)) { printf ("\n*** OperServ and OperServ Alias are the same, this will cause errors\n"); retval = 0; } } if (s_MemoServAlias) { if (!stricmp(s_MemoServ, s_MemoServAlias)) { printf ("\n*** MemoServ and MemoServ Alias are the same, this will cause errors\n"); retval = 0; } } if (s_HelpServAlias) { if (!stricmp(s_HelpServ, s_HelpServAlias)) { printf ("\n*** HelpServ and HelpServ Alias are the same, this will cause errors\n"); retval = 0; } } if (s_GlobalNoticerAlias) { if (!stricmp(s_GlobalNoticer, s_GlobalNoticerAlias)) { printf ("\n*** GlobalNoticer and GlobalNoticer Alias are the same, this will cause errors\n"); retval = 0; } } CHEK2(MOTDFilename, MOTDFile); if (!reload) { CHEK2(NickDBName, NickServDB); CHEK2(ChanDBName, ChanServDB); CHEK2(OperDBName, OperServDB); CHEK2(NewsDBName, NewsDB); CHEK2(ExceptionDBName, ExceptionDB); } CHECK(UpdateTimeout); CHECK(ExpireTimeout); CHECK(ReadTimeout); CHECK(WarningTimeout); CHECK(TimeoutCheck); CHECK(NSAccessMax); CHEK2(temp_nsuserhost, NSEnforcerUser); CHECK(NSReleaseTimeout); CHECK(NSListMax); CHECK(CSAccessMax); CHECK(CSAutokickMax); CHECK(CSAutokickReason); CHECK(CSInhabit); CHECK(CSListMax); CHECK(ServicesRoot); CHECK(AutokillExpiry); CHECK(ChankillExpiry); CHECK(SGLineExpiry); CHECK(SQLineExpiry); CHECK(SZLineExpiry); if (!reload) { if (temp_userhost) { if (!(s = strchr(temp_userhost, '@'))) { error(0, "Missing `@' for ServiceUser"); } else { *s++ = 0; ServiceUser = temp_userhost; ServiceHost = s; } } } if (temp_nsuserhost) { if (!(s = strchr(temp_nsuserhost, '@'))) { NSEnforcerUser = temp_nsuserhost; NSEnforcerHost = ServiceHost; } else { *s++ = 0; NSEnforcerUser = temp_nsuserhost; NSEnforcerHost = s; } } if (!NSDefNone && !NSDefKill && !NSDefKillQuick && !NSDefSecure && !NSDefPrivate && !NSDefHideEmail && !NSDefHideUsermask && !NSDefHideQuit && !NSDefMemoSignon && !NSDefMemoReceive) { NSDefSecure = 1; NSDefMemoSignon = 1; NSDefMemoReceive = 1; } NSDefFlags = 0; if (!NSDefNone) { if (NSDefKill) NSDefFlags |= NI_KILLPROTECT; if (NSDefKillQuick) NSDefFlags |= NI_KILL_QUICK; if (NSDefSecure) NSDefFlags |= NI_SECURE; if (NSDefPrivate) NSDefFlags |= NI_PRIVATE; if (NSDefMsg) { if (!UsePrivmsg) alog("NSDefMsg can only be used when UsePrivmsg is set - unsetting NSDefMsg"); else NSDefFlags |= NI_MSG; } if (NSDefHideEmail) NSDefFlags |= NI_HIDE_EMAIL; if (NSDefHideUsermask) NSDefFlags |= NI_HIDE_MASK; if (NSDefHideQuit) NSDefFlags |= NI_HIDE_QUIT; if (NSDefMemoSignon) NSDefFlags |= NI_MEMO_SIGNON; if (NSDefMemoReceive) NSDefFlags |= NI_MEMO_RECEIVE; if (!NSDefAutoop) NSDefFlags |= NI_AUTOOP; } if (!ServicesRoot) { error(0, "You must define the 'ServicesRoot' configuration directive"); error(0, "in your services.conf file. This is a required setting that"); error(0, "defines the main Administrative nick(s) Anope will obey."); retval = 0; } CHECK(NSGuestNickPrefix); /* Add safety check */ if (NSGuestNickPrefix && (strlen(NSGuestNickPrefix) > 21)) { error(0, "Value of NSGuestNickPrefix must be between 1 and 21"); retval = 0; } CHECK(NSDefLanguage); if (NSDefLanguage) { NSDefLanguage--; if (NSDefLanguage < 0 || NSDefLanguage >= NUM_LANGS) { error(0, "Value of NSDefLanguage must be between 1 and %d", USED_LANGS); retval = 0; } } if (!NewsCount) { NewsCount = 3; } if (reload) { if ((NSDefLanguage = langlist[NSDefLanguage]) < 0) NSDefLanguage = DEF_LANGUAGE; } if (CSDefBantype < 0 || CSDefBantype > 3) { error(0, "Value of CSDefBantype must be between 0 and 3 included"); retval = 0; } if (!MysqlRetries || !MysqlRetryGap) { MysqlRetries = 5; MysqlRetryGap = 1; } else if (((MysqlRetries * MysqlRetryGap) > 60) || ((MysqlRetries * MysqlRetryGap) < 1)) { error(0, "MysqlRetries * MysqlRetryGap must be between 1 and 60, using standard values."); MysqlRetries = 5; MysqlRetryGap = 1; } if (!CSDefNone && !CSDefKeepTopic && !CSDefTopicLock && !CSDefPrivate && !CSDefRestricted && !CSDefSecure && !CSDefSecureOps && !CSDefSecureFounder && !CSDefSignKick && !CSDefSignKickLevel && !CSDefOpNotice) { CSDefKeepTopic = 1; CSDefSecure = 1; CSDefSecureFounder = 1; CSDefSignKick = 1; } CSDefFlags = 0; if (!CSDefNone) { if (CSDefKeepTopic) CSDefFlags |= CI_KEEPTOPIC; if (CSDefTopicLock) CSDefFlags |= CI_TOPICLOCK; if (CSDefPrivate) CSDefFlags |= CI_PRIVATE; if (CSDefRestricted) CSDefFlags |= CI_RESTRICTED; if (CSDefSecure) CSDefFlags |= CI_SECURE; if (CSDefSecureOps) CSDefFlags |= CI_SECUREOPS; if (CSDefSecureFounder) CSDefFlags |= CI_SECUREFOUNDER; if (CSDefSignKick) CSDefFlags |= CI_SIGNKICK; if (CSDefSignKickLevel) CSDefFlags |= CI_SIGNKICK_LEVEL; if (CSDefOpNotice) CSDefFlags |= CI_OPNOTICE; if (CSDefXOP) CSDefFlags |= CI_XOP; if (CSDefPeace) CSDefFlags |= CI_PEACE; } BSDefFlags = 0; if (BSDefDontKickOps) BSDefFlags |= BS_DONTKICKOPS; if (BSDefDontKickVoices) BSDefFlags |= BS_DONTKICKVOICES; if (BSDefGreet) BSDefFlags |= BS_GREET; if (BSDefFantasy) BSDefFlags |= BS_FANTASY; if (BSDefSymbiosis) BSDefFlags |= BS_SYMBIOSIS; /* Services Root building */ if (ServicesRoot && !reload) { /* Check to prevent segmentation fault if it's missing */ while( RootNumber ) free(ServicesRoots[--RootNumber]); s = strtok(ServicesRoot, " "); do { if (s) { RootNumber++; ServicesRoots = srealloc(ServicesRoots, sizeof(char *) * RootNumber); ServicesRoots[RootNumber - 1] = sstrdup(s); } } while ((s = strtok(NULL, " "))); } if (!RootNumber) { error(0, "No ServicesRoot defined"); retval = 0; } /* Ulines */ if (UlineServers) { while( NumUlines ) free(Ulines[--NumUlines]); s = strtok(UlineServers, " "); do { if (s) { NumUlines++; Ulines = srealloc(Ulines, sizeof(char *) * NumUlines); Ulines[NumUlines - 1] = sstrdup(s); } } while ((s = strtok(NULL, " "))); } /* Host Setters building... :P */ while( HostNumber ) free(HostSetters[--HostNumber]); Anope_Free(HostSetters); HostSetters = buildStringList(HostSetter, &HostNumber); /* Modules Autoload building... :P */ while( ModulesNumber ) free(ModulesAutoload[--ModulesNumber]); Anope_Free(ModulesAutoload); ModulesAutoload = buildStringList(Modules, &ModulesNumber); while( ModulesDelayedNumber ) free(ModulesDelayedAutoload[--ModulesDelayedNumber]); Anope_Free(ModulesDelayedAutoload); ModulesDelayedAutoload = buildStringList(ModulesDelayed, &ModulesDelayedNumber); while( HostServCoreNumber ) free(HostServCoreModules[--HostServCoreNumber]); Anope_Free(HostServCoreModules); HostServCoreModules = buildStringList(HostCoreModules, &HostServCoreNumber); while( MemoServCoreNumber ) free(MemoServCoreModules[--MemoServCoreNumber]); Anope_Free(MemoServCoreModules); MemoServCoreModules = buildStringList(MemoCoreModules, &MemoServCoreNumber); while( HelpServCoreNumber ) free(HelpServCoreModules[--HelpServCoreNumber]); Anope_Free(HelpServCoreModules); HelpServCoreModules = buildStringList(HelpCoreModules, &HelpServCoreNumber); while( BotServCoreNumber ) free(BotServCoreModules[--BotServCoreNumber]); Anope_Free(BotServCoreModules); BotServCoreModules = buildStringList(BotCoreModules, &BotServCoreNumber); while( OperServCoreNumber ) free(OperServCoreModules[--OperServCoreNumber]); Anope_Free(OperServCoreModules); OperServCoreModules = buildStringList(OperCoreModules, &OperServCoreNumber); while( ChanServCoreNumber ) free(ChanServCoreModules[--ChanServCoreNumber]); Anope_Free(ChanServCoreModules); ChanServCoreModules = buildStringList(ChanCoreModules, &ChanServCoreNumber); while( NickServCoreNumber ) free(NickServCoreModules[--NickServCoreNumber]); Anope_Free(NickServCoreModules); NickServCoreModules = buildStringList(NickCoreModules, &NickServCoreNumber); if (LimitSessions) { CHECK(DefSessionLimit); CHECK(MaxSessionLimit); CHECK(ExceptionExpiry); if (MaxSessionKill && !SessionAutoKillExpiry) SessionAutoKillExpiry = 30 * 60; /* 30 minutes */ } if (s_BotServ) { CHEK2(BotDBName, BotServDB); CHECK(BSBadWordsMax); CHECK(BSMinUsers); CHECK(BSKeepData); if (s_BotServAlias) { if (!stricmp(s_BotServ, s_BotServAlias)) { printf ("\n*** BotServ and BotServ Alias are the same, this will cause errors\n"); retval = 0; } } if (!BSFantasyCharacter) BSFantasyCharacter = sstrdup("!"); if (BSFantasyCharacter && (strlen(BSFantasyCharacter) > 1)) { printf ("*** BSFantasyCharacter is more than 1 character long. Only the first\n" "*** character ('%c') will be used. The others will be ignored.\n", *BSFantasyCharacter); } } if (s_HostServ) { CHEK2(s_HostServ, HostServName); CHEK2(HostDBName, HostServDB); if (s_HostServAlias) { if (!stricmp(s_HostServ, s_HostServAlias)) { printf ("\n*** HostServ and HostServ Alias are the same, this will cause errors\n"); retval = 0; } } } if (UseMail) { CHECK(SendMailPath); CHECK(SendFrom); } if (GlobalOnCycle) { if (!GlobalOnCycleMessage && !GlobalOnCycleUP) { alog("GlobalOnCycleMessage and GlobalOnCycleUP are not defined; disabling GlobalOnCycle"); GlobalOnCycle = 0; } } /* Check the user keys */ if ((UserKey1 == UserKey2) || (UserKey1 == UserKey3) || (UserKey3 == UserKey2)) alog("Every UserKey must be different. It's for YOUR safety! Remember that!"); /** * Check all DEFCON dependiencies... **/ if (DefConLevel) { CHECK(DefCon1); CHECK(DefCon2); CHECK(DefCon3); CHECK(DefCon4); DefCon5 = 0; /* ALWAYS have defcon 5 as normal operation */ /* Build DefCon's */ DefCon[0] = 0; DefCon[1] = DefCon1; DefCon[2] = DefCon2; DefCon[3] = DefCon3; DefCon[4] = DefCon4; DefCon[5] = DefCon5; for (defconCount = 1; defconCount <= 5; defconCount++) { /* Check any defcon needed settings */ if (DefCon[defconCount] & DEFCON_REDUCE_SESSION) { CHECK(DefConSessionLimit); } if (DefCon[defconCount] & DEFCON_AKILL_NEW_CLIENTS) { CHECK(DefConAKILL); CHECK(DefConAkillReason); } if (DefCon[defconCount] & DEFCON_FORCE_CHAN_MODES) { CHECK(DefConChanModes); } } if (GlobalOnDefconMore) CHECK(DefconMessage); } /** * If they try to enable any email registration option, * make sure they have everything else they need too... * * rob **/ if (NSEmailReg) { CHEK2(PreNickDBName, PreNickServDB); CHECK(NSEmailReg); CHECK(NSRExpire); CHECK(UseMail); CHECK(NSForceEmail); } else { Anope_Free(PreNickDBName); PreNickDBName = NULL; NSRExpire = 0; } if (!retval) { printf ("\n*** Support resources: Read through the services.conf self-contained \n*** documentation. Read the documentation files found in the 'docs' \n*** folder. Visit our portal located at http://www.anope.org/. Join \n*** our support channel on /server irc.anope.org channel #anope.\n\n"); } return retval; }