/** * ----------------------------------------------------------------------------- * Name : hs_nethost * Author : Viper * Date : 12/05/2008 * Last update : 29/05/2008 * Version : 2.1 * ----------------------------------------------------------------------------- * Tested : Anope-1.7.21 + UnrealIRCd 3.2.6 * Requires : Anope-1.7.21 * ----------------------------------------------------------------------------- * This module will automatically set a default vhost upon registration, supporting * customization based upon the user's nickname. * * This module is based on a fork of hs_nethost 1.2 by Trystan Scott Lee when that * module was no longer supported. Most code however has been rewritten to make use * of the events system and allow for better customization of the NetworkHost. * Credit also goes to the original author Certus, and Strike, the author of hs_autohost. * * This module is published under GPLv2. * ----------------------------------------------------------------------------- * Translations: *** Does not currently apply *** * * - English and Dutch Languages provided and maintained by myself. * * ----------------------------------------------------------------------------- * * Changelog: * * 2.1 Fixed segfault crash occuring when no vIdent is set. * * 2.0 Added support for more customizable network vhosts. * Added windows support. * Re-wrote most code and re-releasing module under my name. * Module forked off hs_nethost 1.2 by Trystan. * * ----------------------------------------------------------------------------- **/ /** * Configuration directives that should be copy-pasted to services.conf # NetworkHost [REQUIRED by hs_nethost] # Module: hs_nethost # # When set this vHost (and vIdent) will automatically be set for users # when they register a new nick with NickServ. # Note that no ident must be given. # # Some variables may be used for further customization: # "$nick$" will be replaced by the nickname that was just registered and # can be used multiple times in both the ident and host portion. # $network$ will be replaced by the configured NetworkName. # # Note that only letters and numbers are allowed to be used in the NetworkHost. # # Some examples are: #NetworkHost "$nick$@users.network.net" #NetworkHost "$nick$.users.network.net" #NetworkHost "$nick$@$nick$.users.network.net" #NetworkHost "$nick$.users.$network$" #NetworkHost "$nick$@$nick$.users.$network$" NetworkHost "$nick$@users.$network$" * **/ /* ------------------------------------------------------------------------------- */ #include "module.h" /*------------------------------Configuration Block----------------------------*/ /** * Undefining this will make you lose all support for hs_nethost! * * This module checks whether unsupported modules are enabled/loaded in anope and * whether the anope version meets minimum requirements to load. * If an incompatible module is found, hs_nethost will either unload or disable * itself (ex: os_raw), or continue in unsupported mode (ex: ircd_init). * * These measures have been added to protect users against themselves and prevent * the author of this module from being confronted with support queries about situations that * would not occor during normal use (for example when using RAW). * * If you undef this directive, these checks will be disabled, however you WILL LOSE ALL SUPPORT!!! * If you use the module in unsupported module ayways (because of a conflicting 3rd party module * for example) this may also be desirable. * * To undefine this replace "#define" by "#undef" or simply comment the line out. * Note that you may need to delete hs_nethost.o and .so (*nix) to force a recompile. **/ #define SUPPORTED /*-------------------------End of Configuration Block--------------------------*/ #define AUTHOR "Viper" #define VERSION "2.1" /* Language defines - not currently being used.. */ #define LANG_NUM_STRINGS 0 #define LANG_ 0 /* Constants */ char *rep_nick = "$nick$"; char *rep_network = "$network$"; /* Variables */ char *NetworkHost; int Enabled; int supported; /* Functions */ int set_vhost(int argc, char **argv); void vident_check(char *s); void vhost_check(char *s); char *str_replace(char *replace_target, char *replace_with, char *source); int check_load(void); void update_version(void); int load_config(void); int reload_config(int argc, char **argv); void add_languages(void); /* ------------------------------------------------------------------------------- */ /** * Create the command, and tell anope about it. * @param argc Argument count * @param argv Argument list * @return MOD_CONT to allow the module, MOD_STOP to stop it **/ int AnopeInit(int argc, char **argv) { EvtHook *hook; Enabled = 1; alog("[\002hs_nethost\002] Loading module..."); moduleAddAuthor(AUTHOR); /* This one is not needed, but the modules site requires it... */ moduleAddVersion(VERSION); #ifdef SUPPORTED if (!moduleMinVersion(1,7,21,1341)) { alog("[\002hs_nethost\002] Your version of Anope isn't supported. Please update to a newer release."); return MOD_STOP; } supported = 1; #else supported = -1; #endif check_load(); if (!Enabled) return MOD_STOP; /* Hook to some events.. */ hook = createEventHook(EVENT_NICK_REGISTERED, set_vhost); if (moduleAddEventHook(hook) != MOD_ERR_OK) { alog("[\002hs_nethost\002] Can't hook to EVENT_NICK_REGISTERED event"); return MOD_STOP; } hook = createEventHook(EVENT_GROUP, set_vhost); if (moduleAddEventHook(hook) != MOD_ERR_OK) { alog("[\002hs_nethost\002] Can't hook to EVENT_GROUP event"); return MOD_STOP; } hook = createEventHook(EVENT_RELOAD, reload_config); if (moduleAddEventHook(hook) != MOD_ERR_OK) { alog("[\002hs_nethost\002] Can't hook to EVENT_RELOAD event"); return MOD_STOP; } if (!load_config()) { alog("[\002hs_nethost\002] NetworkHost is not set in the config. (This is fatal)"); return MOD_STOP; } update_version(); alog("[\002hs_nethost\002] Module loaded successfully..."); return MOD_CONT; } void AnopeFini(void) { alog("[\002hs_nethost\002] Unloading module..."); if (NetworkHost) free(NetworkHost); } /* ------------------------------------------------------------------------------- */ int set_vhost(int argc, char **argv) { int32 tmp_time = time(NULL); NickAlias *na; char *cust_host, *vIdent, *vHost; if (!Enabled) return MOD_CONT; if (argc != 1) return MOD_CONT; if (!NetworkHost) return MOD_CONT; if (!(na = findnick(argv[0]))) return MOD_CONT; /* Create the customized host for the user.. */ cust_host = strdup(NetworkHost); cust_host = str_replace(rep_nick, na->nick, cust_host); cust_host = str_replace(rep_network, NetworkName, cust_host); vIdent = myStrGetOnlyToken(cust_host, '@', 0); if (!vIdent) vHost = strdup(cust_host); else vHost = myStrGetTokenRemainder(cust_host, '@', 1); /* Make sure ident and host are valid */ if (vIdent) vident_check(vIdent); vhost_check(vHost); /* Create the new vhost... */ alog("[hs_nethost] Automatically setting vhost for nick %s (%s).", na->nick, cust_host); addHostCore(na->nick, vIdent, vHost, s_HostServ, tmp_time); if (na->u) { notice_lang(s_HostServ, na->u, HOST_SET, s_HostServ, cust_host); /* Make sure the vhost is also set. */ if (nick_identified(na->u)) do_on_id(na->u); } free(cust_host); free(vHost); if (vIdent) free(vIdent); return MOD_CONT; } /* ------------------------------------------------------------------------------- */ /** * Replaces non-letters and non-numbers by _s. **/ void vident_check(char *s) { register int c; while ((c = *s)) { if (!isalnum(c)) *s = '_'; s++; } return; } /** * Replaces non-letters and non-numbers by .s. **/ void vhost_check(char *s) { register int c; while ((c = *s)) { if (!isalnum(c)) *s = '.'; s++; } return; } /** * This will replace all occurances of replace_target by replace_with in the source string. * Returns pointer to the new string. * * Note that all passed strings should be terminated. **/ char *str_replace(char *replace_target, char *replace_with, char *source) { char *ret, *tmp; int diff, length; if (!replace_target || !replace_with || !source) return NULL; diff = strlen(replace_with) - strlen(replace_target); ret = strdup(source); while ((tmp = strstr(ret, replace_target))) { length = strlen(ret); if (diff > 0) { ret = (char *) realloc(ret, sizeof(char) * (length + diff) + 1); memmove(tmp + strlen(replace_with), tmp + strlen(replace_target), sizeof(char) * (strlen(tmp) - strlen(replace_target)) +1); } memcpy(tmp, replace_with, strlen(replace_with)); if (diff < 0) { memmove(tmp + strlen(replace_with), tmp + strlen(replace_target), sizeof(char) * (strlen(tmp) - strlen(replace_target)) +1); ret = (char *) realloc(ret, sizeof(char) * (length + diff) + 1); } /* Make sure the array is null terminated */ memset(ret + (length + diff), 0, 1); } return ret; } /* ------------------------------------------------------------------------------- */ int check_load(void) { #ifdef SUPPORTED if (!DisableRaw || findModule("os_raw")) { alog("[\002hs_nethost\002] RAW has NOT been disabled! (This is fatal!)"); Enabled = 0; return MOD_STOP; } if (supported) { if (findModule("bs_logchanmon")) { alog("[\002hs_nethost\002] This module is unsupported in combination with bs_logchanmon."); supported = 0; } else if (findModule("ircd_gameserv")) { alog("[\002hs_nethost\002] This module is unsupported in combination with ircd_gameserv."); supported = 0; } else if (findModule("ircd_init")) { alog("[\002hs_nethost\002] This module is unsupported in combination with ircd_init."); supported = 0; } else if (findModule("cs_join")) { alog("[\002hs_nethost\002] This module is unsupported in combination with cs_join."); supported = 0; } } else alog("[\002hs_nethost\002] Module operating in unsupported mode!"); #endif return MOD_CONT; } void update_version(void) { Module *m; char tmp[BUFSIZE]; if (mod_current_module) m = mod_current_module; else m = findModule("hs_nethost"); snprintf(tmp, BUFSIZE, "%s [%s]", VERSION, (((Enabled))?((supported >= 0)?((supported == 0)?"u":"S"):"U"):"D")); if (m->version) free(m->version); m->version = sstrdup(tmp); } /* ------------------------------------------------------------------------------- */ /** * (Re)Load the configuration directives **/ int load_config(void) { int i; Directive confvalues[][1] = { {{"NetworkHost", {{PARAM_STRING, PARAM_RELOAD, &NetworkHost}}}}, }; if (NetworkHost) free(NetworkHost); NetworkHost = NULL; for (i = 0; i < 1; i++) moduleGetConfigDirective(confvalues[i]); if (NetworkHost) { alog("[hs_nethost] NetworkHost set to %s", NetworkHost); return 1; } else { alog("[hs_nethost] NetworkHost NOT Set, please set NetworkHost in the services.conf"); return 0; } } /** * Upon /os reload call the routines for reloading the configuration directives **/ int reload_config(int argc, char **argv) { if (!Enabled) return MOD_CONT; if (argc >= 1) { if (!stricmp(argv[0], EVENT_START)) { alog("[hs_nethost]: Reloading configuration directives..."); load_config(); } } if (check_load() != MOD_CONT) { update_version(); } return MOD_CONT; } /* ------------------------------------------------------------------------------- */ /** * At this stage, this is not being used.. **/ void add_languages(void) { char *langtable_en_us[] = { "", }; char *langtable_nl[] = { "", }; moduleInsertLanguage(LANG_EN_US, LANG_NUM_STRINGS, langtable_en_us); moduleInsertLanguage(LANG_NL, LANG_NUM_STRINGS, langtable_nl); } /* EOF */