/** * This module provides a /msg HostServ request and activate functionality, along with adding the optional paramter of * +req to a hostserv List. * * get 1.5.6-r50 or later to use this module... * **/ #include "module.h" #include #define AUTHOR "Rob" #define VERSION "1.5.2" /* Memo options, if oper/setter memo's are enabled, MSMemoDelay time is used to try and * prevent silly flooding */ /* Set to 1 if you want user's to be memo'ed when a vhost is accepted / rejected */ #define SEND_USER_MEMO 1 /* Set to 1 if you want opers to be memo'ed when a new vhost is requested */ #define SEND_OPER_MEMO 0 /* Set to 1 if you want host_setters to be memo'ed when a new vhost is requested */ #define SEND_SETTERS_MEMO 0 /* Language Strings - Translate if you like, but keep the %s's there! */ #define REQUEST_TXT "[auto memo] vHost \002%s\002 requested." #define REQUEST_SYNTAX "Syntax: /msg %s REQUEST " #define REQUESTED "your vHost has been requested" #define REQUESTED_WAIT "Please wait %d seconds before requesting a new vHost" #define ACTIVATED_SYNTAX "Syntax: /msg %s ACTIVATE " #define ACTIVATED "vHost for %s has been activated" #define ACTIVATED_TXT "[auto memo] Your requested vhost has been approved." #define REJECTED_SYNTAX "Syntax: /msg %s REJECT " #define REJECTED "vHost for %s has been rejected" #define REJECTED_TXT "[auto memo] Your requested vhost has been rejected." #define REJECTED_REASON "Reason:" #define NO_REQUEST "No request for nick %s found." #define REQUEST_HELP_1 "Syntax: REQUEST vhost" #define REQUEST_HELP_2 "Request to the network admins the given vhost " #define REQUEST_HELP_3 "be activated for your nick." #define REQUEST_HELP_4 "Please be patient while we consider your request." #define REQUEST_ACT_1 "Syntax: ACTIVATE nick" #define REQUEST_ACT_2 "Activates the requested vhost for the given nick " #define REQUEST_ACT_3 "If configured, a memo informing the user will also" #define REQUEST_ACT_4 "be sent." #define REQUEST_REJ_1 "Syntax: REJECT nick [reason]" #define REQUEST_REJ_2 "Rejects the requested vhost for the given nick" #define REQUEST_REJ_3 "if configured, a memo informing the user will also" #define REQUEST_REJ_4 "be sent." #define REQUEST_WAIT_1 "Syntax: WAITING" #define REQUEST_WAIT_2 "This is provided for convenience, it is essentiaily" #define REQUEST_WAIT_3 "the same as a /msg hostserv list +req" #define REQUEST_HELP_REQ " REQUEST Requests a vhost for your nick" #define REQUEST_HELP_ACT " ACTIVATE Approve a users requested vhost" #define REQUEST_HELP_REJ " REJECT Reject a users requested vhost" #define REQUEST_HELP_WAT " WAITING Convinence command for /hs list +req" /* End of Language Section */ int hs_do_request(User * u); int hs_do_activate(User * u); int hs_do_reject(User * u); int hs_do_listOut(User * u); int hsRequestHelp(User * u); int hsActivateHelp(User * u); int hsRejectHelp(User * u); int hsWaitingHelp(User * u); void hsMainHelp(User * u); extern char *myStrGetOnlyToken(const char *str, const char dilim, int token_number); extern char *myStrSubString(const char *src, int start, int end); extern char *myStrGetTokenRemainder(const char *str, const char dilim, int token_number); extern HostCore *createHostCorelist(HostCore * next, char *nick, char *vIdent, char *vHost, char *creator, int32 tmp_time); extern HostCore *findHostCore(HostCore * head, char *nick, boolean * found); extern HostCore *insertHostCore(HostCore * head, HostCore * prev, char *nick, char *vIdent, char *vHost, char *creator, int32 tmp_time); extern HostCore *deleteHostCore(HostCore * head, HostCore * prev); extern void addHostCore(char *nick, char *vIdent, char *vhost, char *creator, int32 tmp_time); extern void memo_send(User * u, char *name, char *text, int z); extern int is_host_setter(User * u); void my_addHostRequest(char *nick, char *vIdent, char *vhost, char *creator, int32 tmp_time); int my_isvalidchar(const char c); void req_send_memos(User * u, char *vHost); void show_list(User * u); int hs_do_waiting(User * u); int ns_do_drop(User * u); HostCore *hs_request_head; int AnopeInit(int argc, char **argv) { Command *c; c = createCommand("request", hs_do_request, nick_identified, -1, -1, -1, -1, -1); moduleAddHelp(c, hsRequestHelp); moduleAddCommand(HOSTSERV, c, MOD_HEAD); c = createCommand("activate", hs_do_activate, is_host_setter, -1, -1, -1, -1, -1); moduleAddHelp(c, hsActivateHelp); moduleAddCommand(HOSTSERV, c, MOD_HEAD); c = createCommand("reject", hs_do_reject, is_host_setter, -1, -1, -1, -1, -1); moduleAddHelp(c, hsRejectHelp); moduleAddCommand(HOSTSERV, c, MOD_HEAD); c = createCommand("waiting", hs_do_waiting, is_host_setter, -1, -1, -1, -1, -1); moduleAddHelp(c, hsWaitingHelp); moduleAddCommand(HOSTSERV, c, MOD_HEAD); c = createCommand("list", hs_do_listOut, is_services_oper, -1, -1, -1, -1, -1); moduleAddCommand(HOSTSERV, c, MOD_HEAD); c = createCommand("drop", ns_do_drop, NULL, -1, -1, -1, -1, -1); moduleAddCommand(NICKSERV, c, MOD_HEAD); moduleSetHostHelp(hsMainHelp); moduleAddAuthor(AUTHOR); moduleAddVersion(VERSION); hs_request_head = NULL; alog("hs_request.so loaded"); return MOD_CONT; } void AnopeFini(void) { alog("hs_request.so un-loaded"); } int hs_do_request(User * u) { char *nick = u->nick; char *rawhostmask = strtok(NULL, " "); char *hostmask = smalloc(HOSTMAX); NickAlias *na; int32 tmp_time; char *s; char *vIdent = NULL; time_t now = time(NULL); if (!nick || !rawhostmask) { notice(s_HostServ, u->nick, REQUEST_SYNTAX, s_HostServ); return MOD_STOP; } vIdent = myStrGetOnlyToken(rawhostmask, '@', 0); /* Get the first substring, @ as delimiter */ if (vIdent) { rawhostmask = myStrGetTokenRemainder(rawhostmask, '@', 1); /* get the remaining string */ if (!rawhostmask) { notice(s_HostServ, u->nick, REQUEST_SYNTAX, s_HostServ); return MOD_STOP; } if (strlen(vIdent) > USERMAX - 1) { notice_lang(s_HostServ, u, HOST_SET_IDENTTOOLONG, USERMAX); return MOD_STOP; } else { for (s = vIdent; *s; s++) { if (!my_isvalidchar(*s)) { notice_lang(s_HostServ, u, HOST_SET_IDENT_ERROR); return MOD_STOP; } } } #ifndef HAS_VIDENT notice_lang(s_HostServ, u, HOST_NO_VIDENT); return MOD_STOP; #endif } if (strlen(rawhostmask) < HOSTMAX - 1) snprintf(hostmask, HOSTMAX - 1, "%s", rawhostmask); else { notice_lang(s_HostServ, u, HOST_SET_TOOLONG, HOSTMAX); return MOD_STOP; } if (!isValidHost(hostmask, 3)) { notice_lang(s_HostServ, u, HOST_SET_ERROR); return MOD_STOP; } tmp_time = time(NULL); if ((na = findnick(nick))) { if (SEND_OPER_MEMO || SEND_SETTERS_MEMO) { if (MSSendDelay > 0 && u && u->lastmemosend + MSSendDelay > now) { notice(s_HostServ, u->nick, REQUESTED_WAIT, MSSendDelay); u->lastmemosend = now; return MOD_STOP; } } my_addHostRequest(nick, vIdent, hostmask, u->nick, tmp_time); notice(s_HostServ, u->nick, REQUESTED); req_send_memos(u, hostmask); alog("New vHost Requested by %s", nick); } else { notice_lang(s_HostServ, u, HOST_NOREG, nick); } free(hostmask); return MOD_STOP; } void req_send_memos(User * u, char *vHost) { int i; int z = 2; char buf[BUFSIZE]; snprintf(buf, BUFSIZE, REQUEST_TXT, vHost); /* Prepare the formatted string */ if (checkDefCon(DEFCON_NO_NEW_MEMOS)) { return; } if (SEND_OPER_MEMO == 1) { for (i = 0; i < servopers.count; i++) { memo_send(u, (((NickCore *) servopers.list[i])->display), buf, z); } for (i = 0; i < servadmins.count; i++) { memo_send(u, (((NickCore *) servadmins.list[i])->display), buf, z); } for (i = 0; i < RootNumber; i++) { memo_send(u, ServicesRoots[i], buf, z); } } if (SEND_SETTERS_MEMO == 1) { for (i = 0; i < HostNumber; i++) { memo_send(u, HostSetters[i], buf, z); } } } int ns_do_drop(User * u) { HostCore *tmp; boolean found = false; NickAlias *na=NULL; na = findnick(u->nick); tmp = findHostCore(hs_request_head, u->nick, &found); if (found && na) { hs_request_head = deleteHostCore(hs_request_head, tmp); } return MOD_CONT; } int hs_do_reject(User * u) { char *nick = strtok(NULL, " "); char *reason = strtok(NULL,""); char message[512]; // Max message size HostCore *tmp, *hc; boolean found = false; int size=450; // Max size to allow the memo to be, MUST be less than sizeof(message) if (!nick) { notice(s_HostServ, u->nick, REJECTED_SYNTAX, s_HostServ); return MOD_STOP; } tmp = findHostCore(hs_request_head, nick, &found); if (found) { if (tmp == NULL) hc = hs_request_head; else hc = tmp->next; if (SEND_USER_MEMO) { if(reason) { snprintf(message,size,"%s %s %s",REJECTED_TXT,REJECTED_REASON,reason); } else { snprintf(message,size,REJECTED_TXT); } memo_send(u, hc->nick, message, 2); } hs_request_head = deleteHostCore(hs_request_head, tmp); notice(s_HostServ, u->nick, REJECTED, nick); alog("Host Request for %s rejected by %s (%s)", nick, u->nick, reason?reason:""); } else { notice(s_HostServ, u->nick, NO_REQUEST, nick); } return MOD_STOP; } int hs_do_activate(User * u) { char *nick = strtok(NULL, " "); NickAlias *na; HostCore *tmp, *hc; boolean found = false; if (!nick) { notice(s_HostServ, u->nick, ACTIVATED_SYNTAX, s_HostServ); return MOD_STOP; } if ((na = findnick(nick))) { tmp = findHostCore(hs_request_head, nick, &found); if (found) { if (tmp == NULL) hc = hs_request_head; else hc = tmp->next; addHostCore(hc->nick, hc->vIdent, hc->vHost, u->nick, time(NULL)); if (SEND_USER_MEMO) memo_send(u, hc->nick, ACTIVATED_TXT, 2); hs_request_head = deleteHostCore(hs_request_head, tmp); notice(s_HostServ, u->nick, ACTIVATED, nick); alog("Host Request for %s activated by %s", nick, u->nick); } else { notice(s_HostServ, u->nick, NO_REQUEST, nick); } } else { notice(s_HostServ, u->nick, ACTIVATED_SYNTAX, s_HostServ); } return MOD_STOP; } void my_addHostRequest(char *nick, char *vIdent, char *vhost, char *creator, int32 tmp_time) { HostCore *tmp; boolean found = false; if (hs_request_head == NULL) { hs_request_head = createHostCorelist(hs_request_head, nick, vIdent, vhost, creator, tmp_time); } else { tmp = findHostCore(hs_request_head, nick, &found); if (!found) { hs_request_head = insertHostCore(hs_request_head, tmp, nick, vIdent, vhost, creator, tmp_time); } else { hs_request_head = deleteHostCore(hs_request_head, tmp); /* delete the old entry */ my_addHostRequest(nick, vIdent, vhost, creator, tmp_time); /* recursive call to add new entry */ } } } int my_isvalidchar(const char c) { if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9')) || (c == '.') || (c == '-')) return 1; else return 0; } int hs_do_listOut(User * u) { char *key; key = moduleGetLastBuffer(); if (!key) { return MOD_CONT; } if (stricmp(key, "+req") != 0) { return MOD_CONT; } key = NULL; show_list(u); return MOD_STOP; } int hs_do_waiting(User * u) { show_list(u); return MOD_CONT; } void show_list(User * u) { struct tm *tm; char buf[BUFSIZE]; int counter = 1; int from = 0, to = 0; int display_counter = 0; HostCore *current = NULL; current = hs_request_head; while (current) { 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; } notice_lang(s_HostServ, u, HOST_LIST_FOOTER, display_counter); } int hsRequestHelp(User * u) { #ifdef REQUEST_HELP_1 notice(s_HostServ, u->nick, REQUEST_HELP_1); #endif #ifdef REQUEST_HELP_2 notice(s_HostServ, u->nick, REQUEST_HELP_2); #endif #ifdef REQUEST_HELP_3 notice(s_HostServ, u->nick, REQUEST_HELP_3); #endif #ifdef REQUEST_HELP_4 notice(s_HostServ, u->nick, REQUEST_HELP_4); #endif #ifdef REQUEST_HELP_5 notice(s_HostServ, u->nick, REQUEST_HELP_5); #endif return MOD_CONT; } int hsActivateHelp(User * u) { if (is_host_setter(u)) { #ifdef REQUEST_ACT_1 notice(s_HostServ, u->nick, REQUEST_ACT_1); #endif #ifdef REQUEST_ACT_2 notice(s_HostServ, u->nick, REQUEST_ACT_2); #endif #ifdef REQUEST_ACT_3 notice(s_HostServ, u->nick, REQUEST_ACT_3); #endif #ifdef REQUEST_ACT_4 notice(s_HostServ, u->nick, REQUEST_ACT_4); #endif #ifdef REQUEST_ACT_5 notice(s_HostServ, u->nick, REQUEST_ACT_5); #endif } else { notice_lang(s_HostServ, u, NO_HELP_AVAILABLE, "ACTIVATE"); } return MOD_CONT; } int hsRejectHelp(User * u) { if (is_host_setter(u)) { #ifdef REQUEST_REJ_1 notice(s_HostServ, u->nick, REQUEST_REJ_1); #endif #ifdef REQUEST_REJ_2 notice(s_HostServ, u->nick, REQUEST_REJ_2); #endif #ifdef REQUEST_REJ_3 notice(s_HostServ, u->nick, REQUEST_REJ_3); #endif #ifdef REQUEST_REJ_4 notice(s_HostServ, u->nick, REQUEST_REJ_4); #endif #ifdef REQUEST_REJ_5 notice(s_HostServ, u->nick, REQUEST_REJ_5); #endif } else { notice_lang(s_HostServ, u, NO_HELP_AVAILABLE, "REJECT"); } return MOD_CONT; } int hsWaitingHelp(User * u) { if (is_host_setter(u)) { #ifdef REQUEST_WAIT_1 notice(s_HostServ, u->nick, REQUEST_WAIT_1); #endif #ifdef REQUEST_WAIT_2 notice(s_HostServ, u->nick, REQUEST_WAIT_2); #endif #ifdef REQUEST_WAIT_3 notice(s_HostServ, u->nick, REQUEST_WAIT_3); #endif #ifdef REQUEST_WAIT_4 notice(s_HostServ, u->nick, REQUEST_WAIT_4); #endif #ifdef REQUEST_WAIT_5 notice(s_HostServ, u->nick, REQUEST_WAIT_5); #endif } else { notice_lang(s_HostServ, u, NO_HELP_AVAILABLE, "WAITING"); } return MOD_CONT; } void hsMainHelp(User * u) { notice(s_HostServ, u->nick, REQUEST_HELP_REQ); if (is_host_setter(u)) { notice(s_HostServ, u->nick, REQUEST_HELP_ACT); notice(s_HostServ, u->nick, REQUEST_HELP_REJ); notice(s_HostServ, u->nick, REQUEST_HELP_WAT); } } /* EOF */