diff options
Diffstat (limited to 'hostserv.c')
-rw-r--r-- | hostserv.c | 1108 |
1 files changed, 1108 insertions, 0 deletions
diff --git a/hostserv.c b/hostserv.c new file mode 100644 index 000000000..71a29cbc9 --- /dev/null +++ b/hostserv.c @@ -0,0 +1,1108 @@ +/* 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: hostserv.c,v 1.53 2004/02/15 22:40:46 dane Exp $ + * + */ + +/*************************************************************************/ +#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 */ +/*************************************************************************/ |