mirror of
https://github.com/anope/anope.git
synced 2026-06-12 19:14:47 +02:00
811ce26663
git-svn-id: svn://svn.anope.org/anope/trunk@4 31f1291d-b8d6-0310-a050-a5561fc1590b git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@2 5417fbe8-f217-4b02-8779-1006273d7864
1109 lines
32 KiB
C
1109 lines
32 KiB
C
/* HostServ functions
|
|
*
|
|
* (C) 2003 Anope Team
|
|
* Contact us at info@anope.org
|
|
*
|
|
* Please read COPYING and README for furhter details.
|
|
*
|
|
* Based on the original code of Epona by Lara.
|
|
* Based on the original code of Services by Andy Church.
|
|
*
|
|
* $Id$
|
|
*
|
|
*/
|
|
|
|
/*************************************************************************/
|
|
#include "services.h"
|
|
#include "pseudo.h"
|
|
|
|
#define HOST_VERSION 3
|
|
#define HASH(nick) ((tolower((nick)[0])&31)<<5 | (tolower((nick)[1])&31))
|
|
|
|
void load_hs_dbase_v1(dbFILE * f);
|
|
void load_hs_dbase_v2(dbFILE * f);
|
|
void load_hs_dbase_v3(dbFILE * f);
|
|
|
|
static int guestnum; /* Current guest number */
|
|
HostCore *head = NULL; /* head of the HostCore list */
|
|
HostCore *createHostCorelist(HostCore * next, char *nick, char *vIdent,
|
|
char *vHost, char *creator, int32 tmp_time);
|
|
HostCore *findHostCore(HostCore * head, char *nick, boolean * found);
|
|
HostCore *insertHostCore(HostCore * head, HostCore * prev, char *nick,
|
|
char *vIdent, char *vHost, char *creator,
|
|
int32 tmp_time);
|
|
HostCore *deleteHostCore(HostCore * head, HostCore * prev);
|
|
void delHostCore(char *nick);
|
|
|
|
static void send_on(char *nick, char *vIdent, char *vhost);
|
|
static void send_off(User * u);
|
|
|
|
char *getvIdent(char *nick);
|
|
char *getvHost(char *nick);
|
|
|
|
int is_host_setter(User * u);
|
|
int is_host_remover(User * u);
|
|
|
|
static int do_help(User * u);
|
|
static int do_set(User * u);
|
|
static int do_on(User * u);
|
|
int do_on_id(User * u);
|
|
static void set_lastmask(User * u);
|
|
static int do_off(User * u);
|
|
static int do_del(User * u);
|
|
static int do_group(User * u);
|
|
static int listOut(User * u);
|
|
int do_hs_sync(NickCore * nc, char *vIdent, char *hostmask, char *creator,
|
|
time_t time);
|
|
int do_setall(User * u);
|
|
int do_delall(User * u);
|
|
void moduleAddHostServCmds(void);
|
|
/*************************************************************************/
|
|
void moduleAddHostServCmds(void)
|
|
{
|
|
Command *c;
|
|
c = createCommand("HELP", do_help, NULL, -1, -1, -1, -1, -1);
|
|
addCoreCommand(HOSTSERV, c);
|
|
c = createCommand("SET", do_set, is_host_setter, HOST_HELP_SET, -1, -1,
|
|
-1, -1);
|
|
addCoreCommand(HOSTSERV, c);
|
|
c = createCommand("GROUP", do_group, NULL, HOST_HELP_GROUP, -1, -1, -1,
|
|
-1);
|
|
addCoreCommand(HOSTSERV, c);
|
|
c = createCommand("SETALL", do_setall, is_host_setter,
|
|
HOST_HELP_SETALL, -1, -1, -1, -1);
|
|
addCoreCommand(HOSTSERV, c);
|
|
c = createCommand("DELALL", do_delall, is_host_remover,
|
|
HOST_HELP_DELALL, -1, -1, -1, -1);
|
|
addCoreCommand(HOSTSERV, c);
|
|
c = createCommand("ON", do_on, NULL, HOST_HELP_ON, -1, -1, -1, -1);
|
|
addCoreCommand(HOSTSERV, c);
|
|
c = createCommand("OFF", do_off, NULL, HOST_HELP_OFF, -1, -1, -1, -1);
|
|
addCoreCommand(HOSTSERV, c);
|
|
c = createCommand("DEL", do_del, is_host_remover, HOST_HELP_DEL, -1,
|
|
-1, -1, -1);
|
|
addCoreCommand(HOSTSERV, c);
|
|
c = createCommand("LIST", listOut, is_services_oper, HOST_HELP_LIST,
|
|
-1, -1, -1, -1);
|
|
addCoreCommand(HOSTSERV, c);
|
|
}
|
|
|
|
/*************************************************************************/
|
|
|
|
/*************************************************************************/
|
|
/* HostServ initialization. */
|
|
void hostserv_init(void)
|
|
{
|
|
moduleAddHostServCmds();
|
|
guestnum = time(NULL);
|
|
while (guestnum > 9999999)
|
|
guestnum -= 10000000;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
/* Main HostServ routine. */
|
|
void hostserv(User * u, char *buf)
|
|
{
|
|
char *cmd, *s;
|
|
|
|
cmd = strtok(buf, " ");
|
|
|
|
if (!cmd) {
|
|
return;
|
|
} else if (stricmp(cmd, "\1PING") == 0) {
|
|
if (!(s = strtok(NULL, "")))
|
|
s = "\1";
|
|
notice(s_HostServ, u->nick, "\1PING %s", s);
|
|
} else if (skeleton) {
|
|
notice_lang(s_HostServ, u, SERVICE_OFFLINE, s_HostServ);
|
|
} else {
|
|
#ifdef HAS_VHOST
|
|
mod_run_cmd(s_HostServ, u, HOSTSERV, cmd);
|
|
#else
|
|
notice_lang(s_HostServ, u, SERVICE_OFFLINE, s_HostServ);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/*************************************************************************/
|
|
/* Start of Linked List routines */
|
|
/*************************************************************************/
|
|
HostCore *createHostCorelist(HostCore * next, char *nick, char *vIdent,
|
|
char *vHost, char *creator, int32 tmp_time)
|
|
{
|
|
|
|
next = malloc(sizeof(HostCore));
|
|
if (next == NULL) {
|
|
wallops(s_HostServ,
|
|
"Unable to allocate memory to create the vHost LL, problems i sense..");
|
|
} else {
|
|
next->nick = malloc(sizeof(char) * strlen(nick) + 1);
|
|
next->vHost = malloc(sizeof(char) * strlen(vHost) + 1);
|
|
next->creator = malloc(sizeof(char) * strlen(creator) + 1);
|
|
if (vIdent)
|
|
next->vIdent = malloc(sizeof(char) * strlen(vIdent) + 1);
|
|
if ((next->nick == NULL) || (next->vHost == NULL)
|
|
|| (next->creator == NULL)) {
|
|
wallops(s_HostServ,
|
|
"Unable to allocate memory to create the vHost LL, problems i sense..");
|
|
return NULL;
|
|
}
|
|
strcpy(next->nick, nick);
|
|
strcpy(next->vHost, vHost);
|
|
strcpy(next->creator, creator);
|
|
if (vIdent) {
|
|
if ((next->vIdent == NULL)) {
|
|
wallops(s_HostServ,
|
|
"Unable to allocate memory to create the vHost LL, problems i sense..");
|
|
return NULL;
|
|
}
|
|
strcpy(next->vIdent, vIdent);
|
|
} else {
|
|
next->vIdent = NULL;
|
|
}
|
|
next->time = tmp_time;
|
|
next->next = NULL;
|
|
return next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
/**
|
|
* Returns either NULL for the head, or the location of the *PREVIOUS*
|
|
* record, this is where we need to insert etc..
|
|
*
|
|
* -rob
|
|
**/
|
|
HostCore *findHostCore(HostCore * head, char *nick, boolean * found)
|
|
{
|
|
|
|
HostCore *previous, *current;
|
|
|
|
*found = false;
|
|
current = head;
|
|
previous = current;
|
|
|
|
while (current != NULL) {
|
|
if (stricmp(nick, current->nick) == 0) {
|
|
*found = true;
|
|
break;
|
|
} else if (stricmp(nick, current->nick) < 0) {
|
|
/* we know were not gonna find it now.... */
|
|
break;
|
|
} else {
|
|
previous = current;
|
|
current = current->next;
|
|
}
|
|
}
|
|
if (current == head) {
|
|
return NULL;
|
|
} else {
|
|
return previous;
|
|
}
|
|
}
|
|
|
|
/*************************************************************************/
|
|
HostCore *insertHostCore(HostCore * head, HostCore * prev, char *nick,
|
|
char *vIdent, char *vHost, char *creator,
|
|
int32 tmp_time)
|
|
{
|
|
|
|
HostCore *newCore, *tmp;
|
|
|
|
newCore = malloc(sizeof(HostCore));
|
|
if (newCore == NULL) {
|
|
wallops(s_HostServ,
|
|
"Unable to allocate memory to insert into the vHost LL, problems i sense..");
|
|
return NULL;
|
|
} else {
|
|
newCore->nick = malloc(sizeof(char) * strlen(nick) + 1);
|
|
newCore->vHost = malloc(sizeof(char) * strlen(vHost) + 1);
|
|
newCore->creator = malloc(sizeof(char) * strlen(creator) + 1);
|
|
if (vIdent)
|
|
newCore->vIdent = malloc(sizeof(char) * strlen(vIdent) + 1);
|
|
if ((newCore->nick == NULL) || (newCore->vHost == NULL)
|
|
|| (newCore->creator == NULL)) {
|
|
wallops(s_HostServ,
|
|
"Unable to allocate memory to create the vHost LL, problems i sense..");
|
|
return NULL;
|
|
}
|
|
strcpy(newCore->nick, nick);
|
|
strcpy(newCore->vHost, vHost);
|
|
strcpy(newCore->creator, creator);
|
|
if (vIdent) {
|
|
if ((newCore->vIdent == NULL)) {
|
|
wallops(s_HostServ,
|
|
"Unable to allocate memory to create the vHost LL, problems i sense..");
|
|
return NULL;
|
|
}
|
|
strcpy(newCore->vIdent, vIdent);
|
|
} else {
|
|
newCore->vIdent = NULL;
|
|
}
|
|
newCore->time = tmp_time;
|
|
if (prev == NULL) {
|
|
tmp = head;
|
|
head = newCore;
|
|
newCore->next = tmp;
|
|
} else {
|
|
tmp = prev->next;
|
|
prev->next = newCore;
|
|
newCore->next = tmp;
|
|
}
|
|
}
|
|
return head;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
HostCore *deleteHostCore(HostCore * head, HostCore * prev)
|
|
{
|
|
|
|
HostCore *tmp;
|
|
|
|
if (prev == NULL) {
|
|
tmp = head;
|
|
head = head->next;
|
|
} else {
|
|
tmp = prev->next;
|
|
prev->next = tmp->next;
|
|
}
|
|
free(tmp->vHost);
|
|
free(tmp->nick);
|
|
free(tmp->creator);
|
|
if (tmp->vIdent) {
|
|
free(tmp->vIdent);
|
|
}
|
|
free(tmp);
|
|
return head;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
void addHostCore(char *nick, char *vIdent, char *vhost, char *creator,
|
|
int32 tmp_time)
|
|
{
|
|
HostCore *tmp;
|
|
boolean found = false;
|
|
|
|
if (head == NULL) {
|
|
head =
|
|
createHostCorelist(head, nick, vIdent, vhost, creator,
|
|
tmp_time);
|
|
} else {
|
|
tmp = findHostCore(head, nick, &found);
|
|
if (!found) {
|
|
head =
|
|
insertHostCore(head, tmp, nick, vIdent, vhost, creator,
|
|
tmp_time);
|
|
} else {
|
|
head = deleteHostCore(head, tmp); /* delete the old entry */
|
|
addHostCore(nick, vIdent, vhost, creator, tmp_time); /* recursive call to add new entry */
|
|
}
|
|
}
|
|
}
|
|
|
|
/*************************************************************************/
|
|
char *getvHost(char *nick)
|
|
{
|
|
HostCore *tmp;
|
|
boolean found = false;
|
|
tmp = findHostCore(head, nick, &found);
|
|
if (found) {
|
|
if (tmp == NULL)
|
|
return head->vHost;
|
|
else
|
|
return tmp->next->vHost;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
char *getvIdent(char *nick)
|
|
{
|
|
HostCore *tmp;
|
|
boolean found = false;
|
|
tmp = findHostCore(head, nick, &found);
|
|
if (found) {
|
|
if (tmp == NULL)
|
|
return head->vIdent;
|
|
else
|
|
return tmp->next->vIdent;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
int listOut(User * u)
|
|
{
|
|
char *key = strtok(NULL, "");
|
|
struct tm *tm;
|
|
char buf[BUFSIZE];
|
|
int counter = 1;
|
|
int from = 0, to = 0;
|
|
char *tmp = NULL;
|
|
char *s = NULL;
|
|
int display_counter = 0;
|
|
|
|
HostCore *current;
|
|
|
|
current = head;
|
|
if (current == NULL)
|
|
notice_lang(s_HostServ, u, HOST_EMPTY);
|
|
else {
|
|
/**
|
|
* Do a check for a range here, then in the next loop
|
|
* we'll only display what has been requested..
|
|
**/
|
|
if (key) {
|
|
if (key[0] == '#') {
|
|
tmp = myStrGetOnlyToken((key + 1), '-', 0); /* Read FROM out */
|
|
if (!tmp) {
|
|
return MOD_CONT;
|
|
}
|
|
for (s = tmp; *s; s++) {
|
|
if (!isdigit(*s)) {
|
|
return MOD_CONT;
|
|
}
|
|
}
|
|
from = atoi(tmp);
|
|
tmp = myStrGetTokenRemainder(key, '-', 1); /* Read TO out */
|
|
if (!tmp) {
|
|
return MOD_CONT;
|
|
}
|
|
for (s = tmp; *s; s++) {
|
|
if (!isdigit(*s)) {
|
|
return MOD_CONT;
|
|
}
|
|
}
|
|
to = atoi(tmp);
|
|
key = NULL;
|
|
}
|
|
}
|
|
|
|
while (current != NULL) {
|
|
if (key) {
|
|
if (((match_wild_nocase(key, current->nick))
|
|
|| (match_wild_nocase(key, current->vHost)))
|
|
&& (display_counter < NSListMax)) {
|
|
display_counter++;
|
|
tm = localtime(¤t->time);
|
|
strftime(buf, sizeof(buf),
|
|
getstring(NULL,
|
|
STRFTIME_DATE_TIME_FORMAT), tm);
|
|
if (current->vIdent) {
|
|
notice_lang(s_HostServ, u, HOST_IDENT_ENTRY,
|
|
counter, current->nick,
|
|
current->vIdent, current->vHost,
|
|
current->creator, buf);
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_ENTRY, counter,
|
|
current->nick, current->vHost,
|
|
current->creator, buf);
|
|
}
|
|
}
|
|
} else {
|
|
/**
|
|
* List the host if its in the display range, and not more
|
|
* than NSListMax records have been displayed...
|
|
**/
|
|
if ((((counter >= from) && (counter <= to))
|
|
|| ((from == 0) && (to == 0)))
|
|
&& (display_counter < NSListMax)) {
|
|
display_counter++;
|
|
tm = localtime(¤t->time);
|
|
strftime(buf, sizeof(buf),
|
|
getstring(NULL, STRFTIME_DATE_TIME_FORMAT),
|
|
tm);
|
|
if (current->vIdent) {
|
|
notice_lang(s_HostServ, u, HOST_IDENT_ENTRY,
|
|
counter, current->nick,
|
|
current->vIdent, current->vHost,
|
|
current->creator, buf);
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_ENTRY, counter,
|
|
current->nick, current->vHost,
|
|
current->creator, buf);
|
|
}
|
|
}
|
|
}
|
|
counter++;
|
|
current = current->next;
|
|
}
|
|
if (key) {
|
|
notice_lang(s_HostServ, u, HOST_LIST_KEY_FOOTER, key,
|
|
display_counter);
|
|
} else {
|
|
if (from != 0) {
|
|
notice_lang(s_HostServ, u, HOST_LIST_RANGE_FOOTER, from,
|
|
to);
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_LIST_FOOTER,
|
|
display_counter);
|
|
}
|
|
}
|
|
}
|
|
return MOD_CONT;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
void delHostCore(char *nick)
|
|
{
|
|
#ifdef USE_RDB
|
|
static char clause[128];
|
|
#endif
|
|
HostCore *tmp;
|
|
boolean found = false;
|
|
tmp = findHostCore(head, nick, &found);
|
|
if (found) {
|
|
head = deleteHostCore(head, tmp);
|
|
|
|
#ifdef USE_RDB
|
|
/* Reflect this change in the database right away. */
|
|
if (rdb_open()) {
|
|
|
|
snprintf(clause, sizeof(clause), "nick='%s'", nick);
|
|
rdb_scrub_table("anope_hs_core", clause);
|
|
rdb_close();
|
|
}
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*************************************************************************/
|
|
/* End of Linked List routines */
|
|
/*************************************************************************/
|
|
/*************************************************************************/
|
|
/* Start of Load/Save routines */
|
|
/*************************************************************************/
|
|
#define SAFE(x) do { \
|
|
if ((x) < 0) { \
|
|
if (!forceload) \
|
|
fatal("Read error on %s", HostDBName); \
|
|
failed = 1; \
|
|
break; \
|
|
} \
|
|
} while (0)
|
|
|
|
void load_hs_dbase(void)
|
|
{
|
|
dbFILE *f;
|
|
int ver;
|
|
|
|
if (!(f = open_db(s_HostServ, HostDBName, "r", HOST_VERSION))) {
|
|
return;
|
|
}
|
|
ver = get_file_version(f);
|
|
|
|
if (ver == 1) {
|
|
load_hs_dbase_v1(f);
|
|
} else if (ver == 2) {
|
|
load_hs_dbase_v2(f);
|
|
} else if (ver == 3) {
|
|
load_hs_dbase_v3(f);
|
|
}
|
|
close_db(f);
|
|
}
|
|
|
|
void load_hs_dbase_v1(dbFILE * f)
|
|
{
|
|
int c;
|
|
int failed = 0;
|
|
int32 tmp;
|
|
|
|
char *nick;
|
|
char *vHost;
|
|
|
|
tmp = time(NULL);
|
|
|
|
alog("Attempting to load V1 HS Database");
|
|
while (!failed && (c = getc_db(f)) == 1) {
|
|
|
|
if (c == 1) {
|
|
SAFE(read_string(&nick, f));
|
|
SAFE(read_string(&vHost, f));
|
|
addHostCore(nick, NULL, vHost, "Unknown", tmp); /* could get a speed increase by not searching the list */
|
|
free(nick); /* as we know the db is in alphabetical order... */
|
|
free(vHost);
|
|
} else {
|
|
fatal("Invalid format in %s %d", HostDBName, c);
|
|
}
|
|
}
|
|
}
|
|
|
|
void load_hs_dbase_v2(dbFILE * f)
|
|
{
|
|
int c;
|
|
int failed = 0;
|
|
|
|
char *nick;
|
|
char *vHost;
|
|
char *creator;
|
|
int32 time;
|
|
|
|
alog("Attempting to load V2 HS Database");
|
|
while (!failed && (c = getc_db(f)) == 1) {
|
|
|
|
if (c == 1) {
|
|
SAFE(read_string(&nick, f));
|
|
SAFE(read_string(&vHost, f));
|
|
SAFE(read_string(&creator, f));
|
|
SAFE(read_int32(&time, f));
|
|
addHostCore(nick, NULL, vHost, creator, time); /* could get a speed increase by not searching the list */
|
|
free(nick); /* as we know the db is in alphabetical order... */
|
|
free(vHost);
|
|
free(creator);
|
|
} else {
|
|
fatal("Invalid format in %s %d", HostDBName, c);
|
|
}
|
|
}
|
|
}
|
|
|
|
void load_hs_dbase_v3(dbFILE * f)
|
|
{
|
|
int c;
|
|
int failed = 0;
|
|
|
|
char *nick;
|
|
char *vHost;
|
|
char *creator;
|
|
char *vIdent;
|
|
int32 time;
|
|
|
|
alog("Attempting to load V3 HS Database");
|
|
while (!failed && (c = getc_db(f)) == 1) {
|
|
if (c == 1) {
|
|
SAFE(read_string(&nick, f));
|
|
SAFE(read_string(&vIdent, f));
|
|
SAFE(read_string(&vHost, f));
|
|
SAFE(read_string(&creator, f));
|
|
SAFE(read_int32(&time, f));
|
|
addHostCore(nick, vIdent, vHost, creator, time); /* could get a speed increase by not searching the list */
|
|
free(nick); /* as we know the db is in alphabetical order... */
|
|
free(vHost);
|
|
free(creator);
|
|
free(vIdent);
|
|
} else {
|
|
fatal("Invalid format in %s %d", HostDBName, c);
|
|
}
|
|
}
|
|
}
|
|
|
|
#undef SAFE
|
|
/*************************************************************************/
|
|
#define SAFE(x) do { \
|
|
if ((x) < 0) { \
|
|
restore_db(f); \
|
|
log_perror("Write error on %s", HostDBName); \
|
|
if (time(NULL) - lastwarn > WarningTimeout) { \
|
|
wallops(NULL, "Write error on %s: %s", HostDBName, \
|
|
strerror(errno)); \
|
|
lastwarn = time(NULL); \
|
|
} \
|
|
return; \
|
|
} \
|
|
} while (0)
|
|
|
|
void save_hs_dbase(void)
|
|
{
|
|
dbFILE *f;
|
|
static time_t lastwarn = 0;
|
|
HostCore *current;
|
|
|
|
if (!(f = open_db(s_HostServ, HostDBName, "w", HOST_VERSION)))
|
|
return;
|
|
|
|
current = head;
|
|
while (current != NULL) {
|
|
SAFE(write_int8(1, f));
|
|
SAFE(write_string(current->nick, f));
|
|
SAFE(write_string(current->vIdent, f));
|
|
SAFE(write_string(current->vHost, f));
|
|
SAFE(write_string(current->creator, f));
|
|
SAFE(write_int32(current->time, f));
|
|
current = current->next;
|
|
}
|
|
SAFE(write_int8(0, f));
|
|
close_db(f);
|
|
|
|
}
|
|
|
|
#undef SAFE
|
|
|
|
void save_hs_rdb_dbase(void)
|
|
{
|
|
#ifdef USE_RDB
|
|
HostCore *current;
|
|
|
|
if (!rdb_open())
|
|
return;
|
|
|
|
rdb_clear_table("anope_hs_core");
|
|
|
|
current = head;
|
|
while (current != NULL) {
|
|
rdb_save_hs_core(current);
|
|
current = current->next;
|
|
}
|
|
rdb_close();
|
|
#endif
|
|
}
|
|
|
|
/*************************************************************************/
|
|
/* End of Load/Save Functions */
|
|
/*************************************************************************/
|
|
/*************************************************************************/
|
|
/* Start of Generic Functions */
|
|
/*************************************************************************/
|
|
int do_setall(User * u)
|
|
{
|
|
|
|
char *nick = strtok(NULL, " ");
|
|
char *rawhostmask = strtok(NULL, " ");
|
|
char *hostmask = smalloc(HOSTMAX);
|
|
|
|
NickAlias *na;
|
|
int32 tmp_time;
|
|
char *s;
|
|
|
|
char *vIdent = NULL;
|
|
|
|
if (!nick || !rawhostmask) {
|
|
notice_lang(s_HostServ, u, HOST_SETALL_SYNTAX, s_HostServ);
|
|
return MOD_CONT;
|
|
}
|
|
|
|
vIdent = myStrGetOnlyToken(rawhostmask, '@', 0); /* Get the first substring, @ as delimiter */
|
|
if (vIdent) {
|
|
rawhostmask = myStrGetTokenRemainder(rawhostmask, '@', 1); /* get the remaining string */
|
|
if (!rawhostmask) {
|
|
notice_lang(s_HostServ, u, HOST_SETALL_SYNTAX, s_HostServ);
|
|
return MOD_CONT;
|
|
}
|
|
if (strlen(vIdent) > USERMAX - 1) {
|
|
notice_lang(s_HostServ, u, HOST_SET_IDENTTOOLONG, USERMAX);
|
|
return MOD_CONT;
|
|
} else {
|
|
for (s = vIdent; *s; s++) {
|
|
if (!isvalidchar(*s)) {
|
|
notice_lang(s_HostServ, u, HOST_SET_IDENT_ERROR);
|
|
return MOD_CONT;
|
|
}
|
|
}
|
|
}
|
|
#ifndef HAS_VIDENT
|
|
notice_lang(s_HostServ, u, HOST_NO_VIDENT);
|
|
return MOD_CONT;
|
|
#endif
|
|
}
|
|
|
|
if (strlen(rawhostmask) < HOSTMAX - 1)
|
|
snprintf(hostmask, HOSTMAX - 1, "%s", rawhostmask);
|
|
else {
|
|
notice_lang(s_HostServ, u, HOST_SET_TOOLONG, HOSTMAX);
|
|
return MOD_CONT;
|
|
}
|
|
|
|
if (!isValidHost(hostmask, 3)) {
|
|
notice_lang(s_HostServ, u, HOST_SET_ERROR);
|
|
return MOD_CONT;
|
|
}
|
|
|
|
tmp_time = time(NULL);
|
|
|
|
if ((na = findnick(nick))) {
|
|
alog("vHost for all nicks in group \002%s\002 set to \002%s\002 by oper \002%s\002", nick, hostmask, u->nick);
|
|
do_hs_sync(na->nc, vIdent, hostmask, u->nick, tmp_time);
|
|
if (vIdent) {
|
|
notice_lang(s_HostServ, u, HOST_IDENT_SETALL, nick, vIdent,
|
|
hostmask);
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_SETALL, nick, hostmask);
|
|
}
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_NOREG, nick);
|
|
}
|
|
|
|
free(hostmask);
|
|
return MOD_CONT;
|
|
}
|
|
|
|
int do_delall(User * u)
|
|
{
|
|
int i;
|
|
char *nick = strtok(NULL, " ");
|
|
NickAlias *na;
|
|
NickCore *nc;
|
|
if (!nick) {
|
|
notice_lang(s_HostServ, u, HOST_DELALL_SYNTAX, s_HostServ);
|
|
return MOD_CONT;
|
|
}
|
|
if ((na = findnick(nick))) {
|
|
nc = na->nc;
|
|
for (i = 0; i < nc->aliases.count; i++) {
|
|
na = nc->aliases.list[i];
|
|
delHostCore(na->nick);
|
|
}
|
|
alog("vHosts for all nicks in group \002%s\002 deleted by oper \002%s\002", nc->display, u->nick);
|
|
notice_lang(s_HostServ, u, HOST_DELALL, nc->display);
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_NOREG, nick);
|
|
}
|
|
return MOD_CONT;
|
|
}
|
|
|
|
int do_hs_sync(NickCore * nc, char *vIdent, char *hostmask, char *creator,
|
|
time_t time)
|
|
{
|
|
int i;
|
|
NickAlias *na;
|
|
|
|
for (i = 0; i < nc->aliases.count; i++) {
|
|
na = nc->aliases.list[i];
|
|
addHostCore(na->nick, vIdent, hostmask, creator, time);
|
|
}
|
|
return MOD_CONT;
|
|
}
|
|
|
|
static int do_group(User * u)
|
|
{
|
|
NickAlias *na;
|
|
HostCore *tmp;
|
|
char *vHost = NULL;
|
|
char *vIdent = NULL;
|
|
char *creator = NULL;
|
|
time_t time;
|
|
boolean found = false;
|
|
|
|
if ((na = findnick(u->nick))) {
|
|
if (na->status & NS_IDENTIFIED) {
|
|
tmp = findHostCore(head, u->nick, &found);
|
|
if (found) {
|
|
if (tmp == NULL) {
|
|
tmp = head; /* incase first in list */
|
|
} else if (tmp->next) { /* we dont want the previous entry were not inserting! */
|
|
tmp = tmp->next; /* jump to the next */
|
|
}
|
|
|
|
vHost = sstrdup(tmp->vHost);
|
|
if (tmp->vIdent)
|
|
vIdent = sstrdup(tmp->vIdent);
|
|
creator = sstrdup(tmp->creator);
|
|
time = tmp->time;
|
|
|
|
do_hs_sync(na->nc, vIdent, vHost, creator, time);
|
|
if (tmp->vIdent) {
|
|
notice_lang(s_HostServ, u, HOST_IDENT_GROUP,
|
|
na->nc->display, vIdent, vHost);
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_GROUP, na->nc->display,
|
|
vHost);
|
|
}
|
|
free(vHost);
|
|
if (vIdent)
|
|
free(vIdent);
|
|
free(creator);
|
|
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_NOT_ASSIGNED);
|
|
}
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_ID);
|
|
}
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_NOT_REGED);
|
|
}
|
|
return MOD_CONT;
|
|
}
|
|
|
|
static int do_help(User * u)
|
|
{
|
|
char *cmd = strtok(NULL, "");
|
|
|
|
if (!cmd) {
|
|
notice_help(s_HostServ, u, HOST_HELP, s_HostServ);
|
|
if ((is_services_oper(u)) || (is_host_setter(u)))
|
|
notice_help(s_HostServ, u, HOST_OPER_HELP);
|
|
if (is_services_admin(u))
|
|
notice_help(s_HostServ, u, HOST_ADMIN_HELP);
|
|
moduleDisplayHelp(6, u);
|
|
} else {
|
|
mod_help_cmd(s_HostServ, u, HOSTSERV, cmd);
|
|
}
|
|
return MOD_CONT;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
int do_set(User * u)
|
|
{
|
|
char *nick = strtok(NULL, " ");
|
|
char *rawhostmask = strtok(NULL, " ");
|
|
char *hostmask = smalloc(HOSTMAX);
|
|
|
|
NickAlias *na;
|
|
int32 tmp_time;
|
|
char *s;
|
|
|
|
char *vIdent = NULL;
|
|
|
|
if (!nick || !rawhostmask) {
|
|
notice_lang(s_HostServ, u, HOST_SET_SYNTAX, s_HostServ);
|
|
return MOD_CONT;
|
|
}
|
|
|
|
vIdent = myStrGetOnlyToken(rawhostmask, '@', 0); /* Get the first substring, @ as delimiter */
|
|
if (vIdent) {
|
|
rawhostmask = myStrGetTokenRemainder(rawhostmask, '@', 1); /* get the remaining string */
|
|
if (!rawhostmask) {
|
|
notice_lang(s_HostServ, u, HOST_SET_SYNTAX, s_HostServ);
|
|
return MOD_CONT;
|
|
}
|
|
if (strlen(vIdent) > USERMAX - 1) {
|
|
notice_lang(s_HostServ, u, HOST_SET_IDENTTOOLONG, USERMAX);
|
|
return MOD_CONT;
|
|
} else {
|
|
for (s = vIdent; *s; s++) {
|
|
if (!isvalidchar(*s)) {
|
|
notice_lang(s_HostServ, u, HOST_SET_IDENT_ERROR);
|
|
return MOD_CONT;
|
|
}
|
|
}
|
|
}
|
|
#ifndef HAS_VIDENT
|
|
notice_lang(s_HostServ, u, HOST_NO_VIDENT);
|
|
return MOD_CONT;
|
|
#endif
|
|
}
|
|
if (strlen(rawhostmask) < HOSTMAX - 1)
|
|
snprintf(hostmask, HOSTMAX - 1, "%s", rawhostmask);
|
|
else {
|
|
notice_lang(s_HostServ, u, HOST_SET_TOOLONG, HOSTMAX);
|
|
return MOD_CONT;
|
|
}
|
|
|
|
if (!isValidHost(hostmask, 3)) {
|
|
notice_lang(s_HostServ, u, HOST_SET_ERROR);
|
|
return MOD_CONT;
|
|
}
|
|
|
|
|
|
tmp_time = time(NULL);
|
|
|
|
if ((na = findnick(nick))) {
|
|
alog("vHost for user \002%s\002 set to \002%s\002 by oper \002%s\002", nick, hostmask, u->nick);
|
|
addHostCore(nick, vIdent, hostmask, u->nick, tmp_time);
|
|
if (vIdent) {
|
|
notice_lang(s_HostServ, u, HOST_IDENT_SET, nick, vIdent,
|
|
hostmask);
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_SET, nick, hostmask);
|
|
}
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_NOREG, nick);
|
|
}
|
|
free(hostmask);
|
|
return MOD_CONT;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
int do_on(User * u)
|
|
{
|
|
NickAlias *na;
|
|
char *vHost;
|
|
char *vIdent = NULL;
|
|
if ((na = findnick(u->nick))) {
|
|
if (na->status & NS_IDENTIFIED) {
|
|
vHost = getvHost(u->nick);
|
|
vIdent = getvIdent(u->nick);
|
|
if (vHost == NULL) {
|
|
notice_lang(s_HostServ, u, HOST_NOT_ASSIGNED);
|
|
} else {
|
|
if (vIdent) {
|
|
notice_lang(s_HostServ, u, HOST_IDENT_ACTIVATED,
|
|
vIdent, vHost);
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_ACTIVATED, vHost);
|
|
}
|
|
send_on(u->nick, vIdent, vHost);
|
|
#ifdef HAS_VHOST
|
|
u->vhost = sstrdup(vHost);
|
|
#endif
|
|
#ifdef HAS_VIDENT
|
|
if (vIdent)
|
|
u->vident = sstrdup(vIdent);
|
|
#endif
|
|
set_lastmask(u);
|
|
}
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_ID);
|
|
}
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_NOT_REGED);
|
|
}
|
|
return MOD_CONT;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
int do_on_id(User * u)
|
|
{ /* we've assumed that the user exists etc.. */
|
|
char *vHost; /* as were only gonna call this from nsid routine */
|
|
char *vIdent;
|
|
vHost = getvHost(u->nick);
|
|
vIdent = getvIdent(u->nick);
|
|
if (vHost != NULL) {
|
|
if (vIdent) {
|
|
notice_lang(s_HostServ, u, HOST_IDENT_ACTIVATED, vIdent,
|
|
vHost);
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_ACTIVATED, vHost);
|
|
}
|
|
send_on(u->nick, vIdent, vHost);
|
|
#ifdef HAS_VHOST
|
|
u->vhost = sstrdup(vHost);
|
|
#endif
|
|
#ifdef HAS_VIDENT
|
|
if (vIdent)
|
|
u->vident = sstrdup(vIdent);
|
|
#endif
|
|
set_lastmask(u);
|
|
}
|
|
return MOD_CONT;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
int do_del(User * u)
|
|
{
|
|
NickAlias *na;
|
|
char *nick = strtok(NULL, " ");
|
|
if (nick) {
|
|
if ((na = findnick(nick))) {
|
|
alog("vHost for user \002%s\002 deleted by oper \002%s\002",
|
|
nick, u->nick);
|
|
delHostCore(nick);
|
|
notice_lang(s_HostServ, u, HOST_DEL, nick);
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_NOREG, nick);
|
|
}
|
|
} else {
|
|
notice_lang(s_HostServ, u, HOST_DEL_SYNTAX, s_HostServ);
|
|
}
|
|
return MOD_CONT;
|
|
}
|
|
|
|
/*************************************************************************/
|
|
int do_off(User * u)
|
|
{
|
|
/* put any generic code here... :) */
|
|
send_off(u);
|
|
return MOD_CONT;
|
|
}
|
|
|
|
int is_host_setter(User * u)
|
|
{
|
|
int i, j;
|
|
NickAlias *na;
|
|
|
|
if (is_services_oper(u)) {
|
|
return 1;
|
|
}
|
|
if (!nick_identified(u)) {
|
|
return 0;
|
|
}
|
|
|
|
/* Look through all user's aliases (0000412) */
|
|
for (i = 0; i < u->na->nc->aliases.count; i++) {
|
|
na = u->na->nc->aliases.list[i];
|
|
for (j = 0; j < HostNumber; j++) {
|
|
if (stricmp(HostSetters[j], na->nick) == 0) {
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int is_host_remover(User * u)
|
|
{
|
|
return is_host_setter(u); /* only here incase we want to split them up later */
|
|
}
|
|
|
|
/*
|
|
* Sets the last_usermak properly. Using virtual ident and/or host
|
|
*/
|
|
void set_lastmask(User * u)
|
|
{
|
|
if (u->na->last_usermask)
|
|
free(u->na->last_usermask);
|
|
|
|
u->na->last_usermask =
|
|
smalloc(strlen(GetIdent(u)) + strlen(GetHost(u)) + 2);
|
|
sprintf(u->na->last_usermask, "%s@%s", GetIdent(u), GetHost(u));
|
|
|
|
}
|
|
|
|
/*************************************************************************/
|
|
/* End of Generic Functions */
|
|
/*************************************************************************/
|
|
/*************************************************************************/
|
|
/* Start of Server Functions */
|
|
/*************************************************************************/
|
|
void send_on(char *nick, char *vIdent, char *vhost)
|
|
{
|
|
#ifdef IRC_UNREAL
|
|
if (vIdent) {
|
|
send_cmd(ServerName, "CHGIDENT %s %s", nick, vIdent);
|
|
}
|
|
send_cmd(ServerName, "CHGHOST %s %s", nick, vhost);
|
|
#endif
|
|
#ifdef IRC_VIAGRA
|
|
if (vIdent) {
|
|
send_cmd(NULL, "CHGIDENT %s %s", nick, vIdent);
|
|
}
|
|
send_cmd(NULL, "SVSMODE %s +x", nick);
|
|
send_cmd(NULL, "SVSCHGHOST %s %s", nick, vhost);
|
|
#endif
|
|
#ifdef IRC_ULTIMATE
|
|
if (vIdent) {
|
|
send_cmd(ServerName, "CHGIDENT %s %s", nick, vIdent);
|
|
}
|
|
send_cmd(s_HostServ, "SVSMODE %s +x", nick);
|
|
send_cmd(ServerName, "CHGHOST %s %s", nick, vhost);
|
|
#endif
|
|
#ifdef IRC_ULTIMATE3
|
|
send_cmd(s_HostServ, "SVSMODE %s +x", nick);
|
|
send_cmd(ServerName, "SETHOST %s %s", nick, vhost);
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
/*************************************************************************/
|
|
void send_off(User * u)
|
|
{
|
|
#ifdef IRC_UNREAL
|
|
send_cmd(s_HostServ, "SVSMODE %s -xt", u->nick);
|
|
notice_lang(s_HostServ, u, HOST_OFF_UNREAL, u->nick);
|
|
/*
|
|
* tell them to type /mode nick +x to get their original
|
|
* host cloaking back
|
|
*/
|
|
#endif
|
|
#ifdef IRC_VIAGRA
|
|
send_cmd(NULL, "SVSMODE %s -x", u->nick);
|
|
notice_lang(s_HostServ, u, HOST_OFF_UNREAL, u->nick);
|
|
#endif
|
|
#ifdef IRC_ULTIMATE
|
|
/* UltimateIRCd 2.x does not allow users to control +x */
|
|
#endif
|
|
#ifdef IRC_ULTIMATE3
|
|
send_cmd(s_HostServ, "SVSMODE %s -x", u->nick);
|
|
notice_lang(s_HostServ, u, HOST_OFF_UNREAL, u->nick);
|
|
#endif
|
|
|
|
}
|
|
|
|
/*************************************************************************/
|
|
/* End of Server Functions */
|
|
/*************************************************************************/
|