diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 4 | ||||
-rw-r--r-- | src/core/ns_register.c | 40 | ||||
-rw-r--r-- | src/core/ns_resetpass.c | 80 | ||||
-rw-r--r-- | src/core/ns_sendpass.c | 43 | ||||
-rw-r--r-- | src/mail.c | 283 | ||||
-rw-r--r-- | src/mail.cpp | 151 | ||||
-rw-r--r-- | src/memoserv.c | 29 | ||||
-rw-r--r-- | src/threadengine_pthread.cpp | 24 | ||||
-rw-r--r-- | src/threadengine_win32.cpp | 24 |
9 files changed, 258 insertions, 420 deletions
diff --git a/src/Makefile b/src/Makefile index 3e66abc3d..c82f9f5b4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -9,7 +9,7 @@ INCLUDES = ../include/commands.h ../include/defs.h ../include/language.h \ ../include/messages.h ../include/services.h \ ../include/timers.h ../include/extern.h \ ../include/modules.h ../include/slist.h ../include/hashcomp.h \ - ../include/threadengine.h + ../include/threadengine.h ../include/mail.h MAKEARGS = 'CFLAGS=${CFLAGS}' 'CC=${CC}' 'ANOPELIBS=${ANOPELIBS}' \ 'LDFLAGS=${LDFLAGS}' 'INSTDIR=${INSTDIR}' 'INSTALL=${INSTALL}' \ @@ -51,7 +51,7 @@ ircd.o: ircd.c $(INCLUDES) hostserv.o: hostserv.c $(INCLUDES) language.o: language.c $(INCLUDES) log.o: log.c $(INCLUDES) -mail.o: mail.c $(INCLUDES) +mail.o: mail.cpp $(INCLUDES) main.o: main.c $(INCLUDES) memory.o: memory.c $(INCLUDES) memoserv.o: memoserv.c $(INCLUDES) diff --git a/src/core/ns_register.c b/src/core/ns_register.c index 9074f109f..89495eb57 100644 --- a/src/core/ns_register.c +++ b/src/core/ns_register.c @@ -14,7 +14,7 @@ #include "module.h" -int do_sendregmail(User *u, NickRequest *nr); +static bool SendRegmail(User *u, NickRequest *nr); class CommandNSConfirm : public Command { @@ -279,7 +279,7 @@ class CommandNSRegister : public CommandNSConfirm FOREACH_MOD(I_OnMakeNickRequest, OnMakeNickRequest(nr)); if (Config.NSEmailReg) { - if (!do_sendregmail(u, nr)) + if (SendRegmail(u, nr)) { notice_lang(Config.s_NickServ, u, NICK_ENTER_REG_CODE, email, Config.s_NickServ); Alog() << Config.s_NickServ << ": sent registration verification code to " << nr->email; @@ -337,7 +337,7 @@ class CommandNSResend : public Command notice_lang(Config.s_NickServ, u, MAIL_LATER); return MOD_CONT; } - if (!do_sendregmail(u, nr)) + if (!SendRegmail(u, nr)) { nr->lastmail = time(NULL); notice_lang(Config.s_NickServ, u, NICK_REG_RESENT, nr->email); @@ -375,6 +375,7 @@ class NSRegister : public Module ModuleManager::Attach(I_OnNickServHelp, this); } + void OnNickServHelp(User *u) { notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_REGISTER); @@ -386,33 +387,14 @@ class NSRegister : public Module } }; -/*************************************************************************/ - -int do_sendregmail(User *u, NickRequest *nr) +static bool SendRegmail(User *u, NickRequest *nr) { - MailInfo *mail = NULL; - char buf[BUFSIZE]; - - if (!nr && !u) - return -1; - snprintf(buf, sizeof(buf), getstring(NICK_REG_MAIL_SUBJECT), nr->nick); - mail = MailRegBegin(u, nr, buf, Config.s_NickServ); - if (!mail) - return -1; - fprintf(mail->pipe, "%s", getstring(NICK_REG_MAIL_HEAD)); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, getstring(NICK_REG_MAIL_LINE_1), nr->nick); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, getstring(NICK_REG_MAIL_LINE_2), Config.s_NickServ, nr->passcode.c_str()); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, "%s", getstring(NICK_REG_MAIL_LINE_3)); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, "%s", getstring(NICK_REG_MAIL_LINE_4)); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, getstring(NICK_REG_MAIL_LINE_5), Config.NetworkName); - fprintf(mail->pipe, "\n.\n"); - MailEnd(mail); - return 0; + char subject[BUFSIZE], message[BUFSIZE]; + + snprintf(subject, sizeof(subject), getstring(NICK_REG_MAIL_SUBJECT), nr->nick); + snprintf(message, sizeof(message), getstring(NICK_REG_MAIL), nr->nick, Config.NetworkName, Config.s_NickServ, nr->passcode.c_str(), Config.NetworkName); + + return Mail(u, nr, Config.s_NickServ, subject, message); } MODULE_INIT(NSRegister) diff --git a/src/core/ns_resetpass.c b/src/core/ns_resetpass.c index c47fa0308..fc904d66c 100644 --- a/src/core/ns_resetpass.c +++ b/src/core/ns_resetpass.c @@ -14,6 +14,8 @@ #include "module.h" +static bool SendResetEmail(User *u, NickAlias *na); + class CommandNSResetPass : public Command { public: @@ -33,41 +35,11 @@ class CommandNSResetPass : public Command notice_lang(Config.s_NickServ, u, NICK_X_FORBIDDEN, na->nick); else { - char buf[BUFSIZE], message[BUFSIZE]; - snprintf(buf, sizeof(buf), getstring(na, NICK_RESETPASS_SUBJECT), na->nick); - - MailInfo *mail = MailBegin(u, na->nc, buf, Config.s_NickServ); - if (!mail) - return MOD_CONT; - - char passcode[20]; - int min = 1, max = 62; - int chars[] = { - ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', - 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', - 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', - 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', - 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' - }; - - int idx; - for (idx = 0; idx < 20; ++idx) - passcode[idx] = chars[1 + static_cast<int>((static_cast<float>(max - min)) * getrandom16() / 65536.0) + min]; - passcode[idx] = '\0'; - - snprintf(message, sizeof(message), getstring(na, NICK_RESETPASS_MESSAGE), na->nick, Config.s_NickServ, passcode, Config.NetworkName); - fprintf(mail->pipe, "%s", message); - fprintf(mail->pipe, "\n.\n"); - MailEnd(mail); - - na->nc->Shrink("ns_resetpass_code"); - na->nc->Shrink("ns_resetpass_time"); - - na->nc->Extend("ns_resetpass_code", new ExtensibleItemPointerArray<char>(sstrdup(passcode))); - na->nc->Extend("ns_resetpass_time", new ExtensibleItemRegular<time_t>(time(NULL))); - - Alog() << Config.s_NickServ << ": " << u->GetMask() << " used RESETPASS on " << na->nick << " (" << na->nc->display << ")"; - notice_lang(Config.s_NickServ, u, NICK_RESETPASS_COMPLETE, na->nick); + if (SendResetEmail(u, na)) + { + Alog() << Config.s_NickServ << ": " << u->GetMask() << " used RESETPASS on " << na->nick << " (" << na->nc->display << ")"; + notice_lang(Config.s_NickServ, u, NICK_RESETPASS_COMPLETE, na->nick); + } } return MOD_CONT; @@ -110,14 +82,13 @@ class NSResetPass : public Module EventReturn OnPreCommand(User *u, const std::string &service, const ci::string &command, const std::vector<ci::string> ¶ms) { - time_t t; - char *c; - if (service == Config.s_NickServ && command == "CONFIRM" && !params.empty()) { NickAlias *na = findnick(u->nick); - if (na && na->nc->GetExtArray("ns_resetpass_code", c) && na->nc->GetExtRegular<time_t>("ns_resetpass_time", t)) + time_t t; + std::string c; + if (na && na->nc->GetExtRegular("ns_resetpass_code", c) && na->nc->GetExtRegular("ns_resetpass_time", t)) { if (t < time(NULL) - 3600) { @@ -167,4 +138,35 @@ class NSResetPass : public Module } }; +static bool SendResetEmail(User *u, NickAlias *na) +{ + char subject[BUFSIZE], message[BUFSIZE], passcode[20]; + + snprintf(subject, sizeof(subject), getstring(na, NICK_RESETPASS_SUBJECT), na->nick); + + int min = 1, max = 62; + int chars[] = { + ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', + 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', + 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' + }; + + int idx; + for (idx = 0; idx < 20; ++idx) + passcode[idx] = chars[1 + static_cast<int>((static_cast<float>(max - min)) * getrandom16() / 65536.0) + min]; + passcode[idx] = '\0'; + + snprintf(message, sizeof(message), getstring(na, NICK_RESETPASS_MESSAGE), na->nick, Config.s_NickServ, passcode, Config.NetworkName); + + na->nc->Shrink("ns_resetpass_code"); + na->nc->Shrink("ns_resetpass_time"); + + na->nc->Extend("ns_resetpass_code", new ExtensibleItemRegular<std::string>(passcode)); + na->nc->Extend("ns_resetpass_time", new ExtensibleItemRegular<time_t>(time(NULL))); + + return Mail(u, na->nc, Config.s_NickServ, subject, message); +} + MODULE_INIT(NSResetPass) diff --git a/src/core/ns_sendpass.c b/src/core/ns_sendpass.c index 0ce8f6c5c..ffa4b6ece 100644 --- a/src/core/ns_sendpass.c +++ b/src/core/ns_sendpass.c @@ -14,6 +14,8 @@ #include "module.h" +static bool SendPassMail(User *u, NickAlias *na, const std::string &pass); + class CommandNSSendPass : public Command { public: @@ -34,34 +36,14 @@ class CommandNSSendPass : public Command notice_lang(Config.s_NickServ, u, NICK_X_FORBIDDEN, na->nick); else { - char buf[BUFSIZE]; std::string tmp_pass; if (enc_decrypt(na->nc->pass,tmp_pass) == 1) { - MailInfo *mail; - - snprintf(buf, sizeof(buf), getstring(na, NICK_SENDPASS_SUBJECT), na->nick); - mail = MailBegin(u, na->nc, buf, Config.s_NickServ); - if (!mail) - return MOD_CONT; - - fprintf(mail->pipe, "%s", getstring(na, NICK_SENDPASS_HEAD)); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, getstring(na, NICK_SENDPASS_LINE_1), na->nick); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, getstring(na, NICK_SENDPASS_LINE_2), tmp_pass.c_str()); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, "%s", getstring(na, NICK_SENDPASS_LINE_3)); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, "%s", getstring(na, NICK_SENDPASS_LINE_4)); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, getstring(na, NICK_SENDPASS_LINE_5), Config.NetworkName); - fprintf(mail->pipe, "\n.\n"); - - MailEnd(mail); - - Alog() << Config.s_NickServ << ": " << u->GetMask() << " used SENDPASS on " << nick; - notice_lang(Config.s_NickServ, u, NICK_SENDPASS_OK, nick); + if (SendPassMail(u, na, tmp_pass)) + { + Alog() << Config.s_NickServ << ": " << u->GetMask() << " used SENDPASS on " << nick; + notice_lang(Config.s_NickServ, u, NICK_SENDPASS_OK, nick); + } } else notice_lang(Config.s_NickServ, u, NICK_SENDPASS_UNAVAILABLE); @@ -102,10 +84,21 @@ class NSSendPass : public Module ModuleManager::Attach(I_OnNickServHelp, this); } + void OnNickServHelp(User *u) { notice_lang(Config.s_NickServ, u, NICK_HELP_CMD_SENDPASS); } }; +static bool SendPassMail(User *u, NickAlias *na, const std::string &pass) +{ + char subject[BUFSIZE], message[BUFSIZE]; + + snprintf(subject, sizeof(subject), getstring(na, NICK_SENDPASS_SUBJECT), na->nick); + snprintf(message, sizeof(message), getstring(na, NICK_SENDPASS), na->nick, pass.c_str(), Config.NetworkName); + + return Mail(u, na->nc, Config.s_NickServ, subject, message); +} + MODULE_INIT(NSSendPass) diff --git a/src/mail.c b/src/mail.c deleted file mode 100644 index ef3d6cd4d..000000000 --- a/src/mail.c +++ /dev/null @@ -1,283 +0,0 @@ -/* Mail utility routines. - * - * (C) 2003-2010 Anope Team - * Contact us at team@anope.org - * - * Please read COPYING and README for further details. - * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. - * - * - */ - -#include "services.h" -#include "language.h" - -/*************************************************************************/ - -/** - * Begins to send a mail. Must be followed by a MailEnd call. - * Returns NULL if the call failed. Error messages are - * automatically sent to the user. - * @param u the User struct - * @param nr NickReqest Struct - * @param subject Subject of the email - * @param service Service to respond with - * @return MailInfo struct - */ -MailInfo *MailRegBegin(User * u, NickRequest * nr, char *subject, - char *service) -{ - int timeToWait = 0; - if (!u || !nr || !subject || !service) { - return NULL; - } - - if (!Config.UseMail) { - notice_lang(service, u, MAIL_DISABLED); - } else if ((time(NULL) - u->lastmail < Config.MailDelay)) { - timeToWait = Config.MailDelay - (time(NULL) - u->lastmail); - notice_lang(service, u, MAIL_DELAYED, timeToWait); - } else if (!nr->email) { - notice_lang(service, u, MAIL_INVALID, nr->nick); - } else { - MailInfo *mail; - - mail = new MailInfo; - mail->sender = u; - mail->recipient = NULL; - mail->recip = nr; - - if (!(mail->pipe = popen(Config.SendMailPath, "w"))) { - delete mail; - notice_lang(service, u, MAIL_LATER); - return NULL; - } - - fprintf(mail->pipe, "From: %s\n", Config.SendFrom); - if (Config.DontQuoteAddresses) { - fprintf(mail->pipe, "To: %s <%s>\n", nr->nick, nr->email); - } else { - fprintf(mail->pipe, "To: \"%s\" <%s>\n", nr->nick, nr->email); - } - fprintf(mail->pipe, "Subject: %s\n", subject); - return mail; - } - - return NULL; -} - -/*************************************************************************/ - -/** - * Begins to send a mail. Must be followed by a MailEnd call. - * Returns NULL if the call failed. Error messages are - * automatically sent to the user. - * @param u the User struct - * @param nc NickCore Struct - * @param subject Subject of the email - * @param service Service to respond with - * @return MailInfo struct - */ -MailInfo *MailBegin(User * u, NickCore * nc, char *subject, char *service) -{ - if (!u || !nc || !subject || !service) { - return NULL; - } - - if (!Config.UseMail) { - notice_lang(service, u, MAIL_DISABLED); - } else if (((time(NULL) - u->lastmail < Config.MailDelay) - || (time(NULL) - nc->lastmail < Config.MailDelay)) - && !(u->Account() && u->Account()->IsServicesOper())) { - notice_lang(service, u, MAIL_DELAYED, Config.MailDelay); - } else if (!nc->email) { - notice_lang(service, u, MAIL_INVALID, nc->display); - } else { - MailInfo *mail; - - mail = new MailInfo; - mail->sender = u; - mail->recipient = nc; - mail->recip = NULL; - - if (!(mail->pipe = popen(Config.SendMailPath, "w"))) { - delete mail; - notice_lang(service, u, MAIL_LATER); - return NULL; - } - - fprintf(mail->pipe, "From: %s\n", Config.SendFrom); - if (Config.DontQuoteAddresses) { - fprintf(mail->pipe, "To: %s <%s>\n", nc->display, nc->email); - } else { - fprintf(mail->pipe, "To: \"%s\" <%s>\n", nc->display, - nc->email); - } - fprintf(mail->pipe, "Subject: %s\n", subject); - - return mail; - } - - return NULL; -} - -/*************************************************************************/ - -/** - * new function to send memo mails - * @param nc NickCore Struct - * @return MailInfo struct - */ -MailInfo *MailMemoBegin(NickCore * nc) -{ - - if (!nc) - return NULL; - - if (!Config.UseMail || !nc->email) { - return NULL; - - } else { - MailInfo *mail; - - mail = new MailInfo; - mail->sender = NULL; - mail->recipient = nc; - mail->recip = NULL; - - if (!(mail->pipe = popen(Config.SendMailPath, "w"))) { - delete mail; - return NULL; - } - - fprintf(mail->pipe, "From: %s\n", Config.SendFrom); - if (Config.DontQuoteAddresses) { - fprintf(mail->pipe, "To: %s <%s>\n", nc->display, nc->email); - } else { - fprintf(mail->pipe, "To: \"%s\" <%s>\n", nc->display, - nc->email); - } - fprintf(mail->pipe, "Subject: %s\n", - getstring(MEMO_MAIL_SUBJECT)); - return mail; - } -} - -/*************************************************************************/ - -/** - * Finish to send the mail. Cleanup everything. - * @param mail MailInfo Struct - * @return void - */ -void MailEnd(MailInfo * mail) -{ - /* - param checking modified because we don't - have an user sending this mail. - Certus, 02.04.2004 */ - - if (!mail || !mail->pipe) { /* removed sender check */ - return; - } - - if (!mail->recipient && !mail->recip) { - return; - } - - pclose(mail->pipe); - - if (mail->sender) /* added sender check */ - mail->sender->lastmail = time(NULL); - - if (mail->recipient) - mail->recipient->lastmail = time(NULL); - else - mail->recip->lastmail = time(NULL); - - - delete mail; -} - -/*************************************************************************/ - -/** - * Resets the MailDelay protection. - * @param u the User struct - * @param nc NickCore Struct - * @return void - */ -void MailReset(User * u, NickCore * nc) -{ - if (u) - u->lastmail = 0; - if (nc) - nc->lastmail = 0; -} - -/*************************************************************************/ - -/** - * Checks whether we have a valid, common e-mail address. - * This is NOT entirely RFC compliant, and won't be so, because I said - * *common* cases. ;) It is very unlikely that e-mail addresses that - * are really being used will fail the check. - * - * FIXME: rewrite this a bit cleaner. - * @param email Email to Validate - * @return int - */ -int MailValidate(const char *email) -{ - int has_period = 0, len; - char copy[BUFSIZE], *domain; - - static char specials[] = - { '(', ')', '<', '>', '@', ',', ';', ':', '\\', '\"', '[', ']', - ' ' - }; - - if (!email) - return 0; - strlcpy(copy, email, sizeof(copy)); - - domain = strchr(copy, '@'); - if (!domain) - return 0; - *domain = '\0'; - domain++; - - /* Don't accept NULL copy or domain. */ - if (*copy == 0 || *domain == 0) - return 0; - - /* Check for forbidden characters in the name */ - for (unsigned int i = 0; i < strlen(copy); i++) { - - if (copy[i] <= 31 || copy[i] >= 127) - return 0; - for (unsigned int j = 0; j < 13; j++) - if (copy[i] == specials[j]) - return 0; - } - - /* Check for forbidden characters in the domain, and if it seems to be valid. */ - for (int i = 0; i < (len = strlen(domain)); i++) { - if (domain[i] <= 31 || domain[i] >= 127) - return 0; - for (unsigned int j = 0; j < 13; j++) - if (domain[i] == specials[j]) - return 0; - if (domain[i] == '.') { - if (i == 0 || i == len - 1) - return 0; - has_period = 1; - } - } - - if (!has_period) - return 0; - - return 1; -} diff --git a/src/mail.cpp b/src/mail.cpp new file mode 100644 index 000000000..9e1c60c6b --- /dev/null +++ b/src/mail.cpp @@ -0,0 +1,151 @@ +#include "services.h" +#include "language.h" + +MailThread::~MailThread() +{ + if (Success) + Alog() << "Successfully delivered mail for " << MailTo << " (" << Addr << ")"; + else + Alog() << "Error delivering mail for " << MailTo << " (" << Addr << ")"; +} + +void MailThread::Run() +{ + FILE *pipe = popen(Config.SendMailPath, "w"); + + if (!pipe) + { + return; + } + + fprintf(pipe, "From: %s\n", Config.SendFrom); + if (Config.DontQuoteAddresses) + fprintf(pipe, "To: %s <%s>\n", MailTo.c_str(), Addr.c_str()); + else + fprintf(pipe, "To: \"%s\" <%s>\n", MailTo.c_str(), Addr.c_str()); + fprintf(pipe, "Subject: %s\n", Subject.c_str()); + fprintf(pipe, "%s", Message.c_str()); + fprintf(pipe, "\n.\n"); + + pclose(pipe); + + Success = true; +} + +bool Mail(User *u, NickRequest *nr, const std::string &service, const std::string &subject, const std::string &message) +{ + if (!u || !nr || subject.empty() || service.empty() || message.empty()) + return false; + + time_t t = time(NULL); + + if (!Config.UseMail) + notice_lang(service.c_str(), u, MAIL_DISABLED); + else if (t - u->lastmail < Config.MailDelay) + notice_lang(service.c_str(), u, MAIL_DELAYED, t - u->lastmail); + else if (!nr->email) + notice_lang(service.c_str(), u, MAIL_INVALID, nr->nick); + else + { + u->lastmail = nr->lastmail = t; + threadEngine.Start(new MailThread(nr->nick, nr->email, subject, message)); + return true; + } + + return false; +} + +bool Mail(User *u, NickCore *nc, const std::string &service, const std::string &subject, const std::string &message) +{ + if (!u || !nc || subject.empty() || service.empty() || message.empty()) + return false; + + time_t t = time(NULL); + + if (!Config.UseMail) + notice_lang(service.c_str(), u, MAIL_DISABLED); + else if (t - u->lastmail < Config.MailDelay) + notice_lang(service.c_str(), u, MAIL_DELAYED, t - u->lastmail); + else if (!nc->email) + notice_lang(service.c_str(), u, MAIL_INVALID, nc->display); + else + { + u->lastmail = nc->lastmail = t; + threadEngine.Start(new MailThread(nc->display, nc->email, subject, message)); + return true; + } + + return false; +} + +bool Mail(NickCore *nc, const std::string &subject, const std::string &message) +{ + if (!Config.UseMail || !nc || !nc->email || subject.empty() || message.empty()) + return false; + + nc->lastmail = time(NULL); + threadEngine.Start(new MailThread(nc->display, nc->email, subject, message)); + + return true; +} + +/** + * Checks whether we have a valid, common e-mail address. + * This is NOT entirely RFC compliant, and won't be so, because I said + * *common* cases. ;) It is very unlikely that e-mail addresses that + * are really being used will fail the check. + * + * @param email Email to Validate + * @return bool + */ +bool MailValidate(const std::string &email) +{ + bool has_period = false; + char copy[BUFSIZE]; + + static char specials[] = { + '(', ')', '<', '>', '@', ',', ';', ':', '\\', '\"', '[', ']', ' ' + }; + + if (email.empty()) + return false; + strlcpy(copy, email.c_str(), sizeof(copy)); + + char *domain = strchr(copy, '@'); + if (!domain) + return false; + *domain++ = '\0'; + + /* Don't accept NULL copy or domain. */ + if (!*copy || !*domain) + return false; + + /* Check for forbidden characters in the name */ + for (unsigned int i = 0; i < strlen(copy); i++) + { + if (copy[i] <= 31 || copy[i] >= 127) + return false; + for (unsigned int j = 0; j < 13; j++) + if (copy[i] == specials[j]) + return false; + } + + /* Check for forbidden characters in the domain */ + for (unsigned int i = 0; i < strlen(domain); i++) + { + if (domain[i] <= 31 || domain[i] >= 127) + return false; + for (unsigned int j = 0; j < 13; j++) + if (domain[i] == specials[j]) + return false; + if (domain[i] == '.') + { + if (i == 0 || i == strlen(domain) - 1) + return false; + has_period = true; + } + } + + return has_period; +} + diff --git a/src/memoserv.c b/src/memoserv.c index 5236345f9..4ab9c76ff 100644 --- a/src/memoserv.c +++ b/src/memoserv.c @@ -18,7 +18,7 @@ /* *INDENT-OFF* */ E void moduleAddMemoServCmds(); -static void new_memo_mail(NickCore *nc, Memo *m); +static bool SendMemoMail(NickCore *nc, Memo *m); E void rsend_notify(User *u, Memo *m, const char *chan); /*************************************************************************/ @@ -300,7 +300,7 @@ void memo_send(User * u, const char *name, const char *text, int z) /* if (MSNotifyAll) */ /* let's get out the mail if set in the nickcore - certus */ if (nc->HasFlag(NI_MEMO_MAIL)) - new_memo_mail(nc, m); + SendMemoMail(nc, m); } else { Channel *c; @@ -356,32 +356,17 @@ int delmemo(MemoInfo * mi, int num) /*************************************************************************/ -static void new_memo_mail(NickCore * nc, Memo * m) +static bool SendMemoMail(NickCore *nc, Memo *m) { - MailInfo *mail = NULL; + char message[BUFSIZE]; - if (!nc || !m) - return; + snprintf(message, sizeof(message), getstring(NICK_MAIL_TEXT), nc->display, m->sender.c_str(), m->number, m->text); - mail = MailMemoBegin(nc); - if (!mail) { - return; - } - fprintf(mail->pipe, getstring(MEMO_MAIL_TEXT1), nc->display); - fprintf(mail->pipe, "\n"); - fprintf(mail->pipe, getstring(MEMO_MAIL_TEXT2), m->sender.c_str(), - m->number); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, "%s", getstring(MEMO_MAIL_TEXT3)); - fprintf(mail->pipe, "\n\n"); - fprintf(mail->pipe, "%s", m->text); - fprintf(mail->pipe, "\n"); - MailEnd(mail); - return; + return Mail(nc, getstring(MEMO_MAIL_SUBJECT), message); } - /*************************************************************************/ + /* Send receipt notification to sender. */ void rsend_notify(User * u, Memo * m, const char *chan) diff --git a/src/threadengine_pthread.cpp b/src/threadengine_pthread.cpp index 199bd0860..9d9bf160d 100644 --- a/src/threadengine_pthread.cpp +++ b/src/threadengine_pthread.cpp @@ -1,14 +1,5 @@ #include "services.h" -/** Join to the thread, sets the exit state to true - */ -void Thread::Join() -{ - SetExitState(); - pthread_join(Handle, NULL); - delete this; -} - /* Threadengine attributes used by this thread engine */ static pthread_attr_t threadengine_attr; @@ -19,6 +10,11 @@ static void *entry_point(void *parameter) { Thread *thread = static_cast<Thread *>(parameter); thread->Run(); + if (!thread->GetExitState()) + { + thread->Join(); + } + delete thread; pthread_exit(0); } @@ -39,6 +35,14 @@ ThreadEngine::~ThreadEngine() pthread_attr_destroy(&threadengine_attr); } +/** Join to the thread, sets the exit state to true + */ +void Thread::Join() +{ + SetExitState(); + pthread_join(Handle, NULL); +} + /** Start a new thread * @param thread A pointer to a newley allocated thread */ @@ -47,7 +51,7 @@ void ThreadEngine::Start(Thread *thread) if (pthread_create(&thread->Handle, &threadengine_attr, entry_point, thread)) { delete thread; - throw CoreException("Unable to create thread"); + throw CoreException("Unable to create thread: " + std::string(strerror(errno))); } } diff --git a/src/threadengine_win32.cpp b/src/threadengine_win32.cpp index d3c0303f5..5ee2f4596 100644 --- a/src/threadengine_win32.cpp +++ b/src/threadengine_win32.cpp @@ -1,14 +1,5 @@ #include "services.h" -/** Join to the thread, sets the exit state to true - */ -void Thread::Join() -{ - SetExitState(); - WaitForSingleObject(Handle, INFINITE); - delete this; -} - /** Entry point for the thread * @param paramter A Thread* cast to a void* */ @@ -16,6 +7,11 @@ static DWORD WINAPI entry_point(void *parameter) { Thread *thread = static_cast<Thread *>(parameter); thread->Run(); + if (!thread->GetExitState()) + { + thread->Join(); + } + delete thread; return 0; } @@ -31,6 +27,14 @@ ThreadEngine::~ThreadEngine() { } +/** Join to the thread, sets the exit state to true + */ +void Thread::Join() +{ + SetExitState(); + WaitForSingleObject(Handle, INFINITE); +} + /** Start a new thread * @param thread A pointer to a newley allocated thread */ @@ -41,7 +45,7 @@ void ThreadEngine::Start(Thread *thread) if (!thread->Handle) { delete thread; - throw CoreException("Unable to create thread"); + throw CoreException("Unable to create thread: " + std::string(dlerror())); } } |