All pastes #1402369 Raw Edit

Miscellany

public text v1 · immutable
#1402369 ·published 2009-04-24 23:02 UTC
rendered paste body
/**
 * -----------------------------------------------------------------------------
 * Name        : hs_nethost
 * Author      : Viper  <Viper@Absurd-IRC.net>
 * 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"
#include <stdlib.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$";
char *rand_num = "$rand$";

/* 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) {
	srand(time(NULL));
	int32 tmp_time = time(NULL);
	NickAlias *na;
	char *cust_host, *vIdent, *vHost;
	char randcrap[7];
	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);
	sprintf(randcrap, "%i", rand() % 1000000);
	cust_host = str_replace(rand_num, randcrap, 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);
	free(randcrap);
	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 */