summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam <Adam@anope.org>2010-10-31 20:47:34 -0400
committerAdam <Adam@anope.org>2010-10-31 20:47:34 -0400
commite3f368f67b95438f39c0f459505af0e19ad364ad (patch)
tree0eba7020e2c95ef631049d97669ee4e7adffc239
parent2170823059c176a79efd5e99fcfa53524c2d5536 (diff)
Fixed replacing %R's in email messages and fixed anopesmtp to really work
-rw-r--r--docs/TOOLS8
-rw-r--r--src/language.cpp9
-rw-r--r--src/tools/CMakeLists.txt5
-rw-r--r--src/tools/anopesmtp.cpp258
-rw-r--r--src/tools/smtp.h112
-rw-r--r--src/users.cpp5
6 files changed, 139 insertions, 258 deletions
diff --git a/docs/TOOLS b/docs/TOOLS
index 0b2b2ec32..0771f0671 100644
--- a/docs/TOOLS
+++ b/docs/TOOLS
@@ -8,16 +8,16 @@ Anope Bundled Tools
The SMTP client can be used instead of sendmail for use with Anope's mail
options. To use the SMTP client instead of sendmail, find the line in your
- services configuration file (services.conf) that defines SendMailPath. On
+ services configuration file (services.conf) that defines sendmailpath. On
that line, change the path to your services installation directory, then
followed by "tools/anopesmtp" and the IP address of a valid SMTP server. It
should look like this:
- SendMailPath "/home/anope/services/tools/anopesmtp 127.0.0.1"
+ sendmailpath = "/home/anope/services/tools/anopesmtp 127.0.0.1"
If the SMTP client doesn't send mail, or if there's an other problem with
- it, you can compile it in debug mode. To do this, open smtp.h, and look
- for "smtp_debug" near the bottom. Change this from 0 to 1 and recompile
+ it, you can compile it in debug mode. To do this, open anopesmtp.cpp, and look
+ for "smtp_debug" near the top. Change this from 0 to 1 and recompile
the code. This should generate a log file of what happened when it tried
to connect to the SMTP server.
diff --git a/src/language.cpp b/src/language.cpp
index 000b4d103..91b959e3a 100644
--- a/src/language.cpp
+++ b/src/language.cpp
@@ -102,7 +102,14 @@ const Anope::string GetString(const char *domain, Anope::string language, const
setlocale(LC_ALL, "");
#endif
- return ret ? ret : "";
+ Anope::string translated = ret ? ret : "";
+
+ if (Config->UseStrictPrivMsg)
+ translated = translated.replace_all_cs("%R", "/");
+ else
+ translated = translated.replace_all_cs("%R", "/msg ");
+
+ return translated;
}
#else
const Anope::string GetString(const char *domain, const Anope::string &language, const Anope::string &string)
diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt
index 00f3151dd..386591c42 100644
--- a/src/tools/CMakeLists.txt
+++ b/src/tools/CMakeLists.txt
@@ -15,11 +15,6 @@ foreach(SRC ${TOOLS_SRCS})
calculate_depends(${SRC} SKIP)
# Only continue if this file isn't skipped
if(NOT SKIP)
- # For anoptsmtp, we also want base.cpp and hashcomp.cpp included, so we force it into the sources
- if(SRC STREQUAL anopesmtp.cpp)
- set(SRC ${SRC} ${Anope_SOURCE_DIR}/src/base.cpp)
- set(SRC ${SRC} ${Anope_SOURCE_DIR}/src/hashcomp.cpp)
- endif(SRC STREQUAL anopesmtp.cpp)
# Generate the executable and set its linker flags, also set it to depend on the main Anope executable to be built beforehand
add_executable(${EXE} ${SRC})
set_target_properties(${EXE} PROPERTIES LINKER_LANGUAGE CXX LINK_FLAGS "${LDFLAGS}")
diff --git a/src/tools/anopesmtp.cpp b/src/tools/anopesmtp.cpp
index aedbee725..78e0759ac 100644
--- a/src/tools/anopesmtp.cpp
+++ b/src/tools/anopesmtp.cpp
@@ -12,89 +12,104 @@
* *nix port by Trystan Scott Lee <trystan@nomadirc.net>
*/
-#include "smtp.h"
+#include "sysconf.h"
-static FILE *logfile;
-static int curday = 0;
-
-/*************************************************************************/
-
-static int get_logname(std::string &name, struct tm *tm = NULL)
-{
- char timestamp[32];
-
- if (!tm)
- {
- time_t t = time(NULL);
- tm = localtime(&t);
- }
+/* Some Linux boxes (or maybe glibc includes) require this for the
+ * prototype of strsignal(). */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
- strftime(timestamp, sizeof(timestamp), "%Y%m%d", tm);
- name = std::string("logs/anopesmtp.") + timestamp;
- curday = tm->tm_yday;
+#include <string>
+#include <vector>
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <cerrno>
+#include <iostream>
+#include <fstream>
+
+#ifndef _WIN32
+# include <unistd.h>
+# include <netdb.h>
+# include <netinet/in.h>
+# include <sys/socket.h>
+# include <arpa/inet.h>
+# include <sys/time.h>
+#else
+# include <winsock.h>
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
- return 1;
-}
+#include <sys/types.h>
+
+#ifdef _AIX
+extern int strcasecmp(const char *, const char *);
+extern int strncasecmp(const char *, const char *, size_t);
+# if 0 /* These break on some AIX boxes (4.3.1 reported). */
+extern int socket(int, int, int);
+extern int connect(int, struct sockaddr *, int);
+# endif
+#endif /* _AIX */
+
+/* Some SUN fixs */
+#ifdef __sun
+/* Solaris specific code, types that do not exist in Solaris'
+ * * sys/types.h
+ * **/
+# ifndef INADDR_NONE
+# define INADDR_NONE (-1)
+# endif
+#endif
/*************************************************************************/
-/* Close the log file. */
-
-void close_log()
-{
- if (!logfile)
- return;
- fclose(logfile);
- logfile = NULL;
-}
-
-/*************************************************************************/
+#ifdef _WIN32
+typedef SOCKET ano_socket_t;
+#define ano_sockclose(fd) closesocket(fd)
+#define ano_sockread(fd, buf, len) recv(fd, buf, len, 0)
+#define ano_sockwrite(fd, buf, len) send(fd, buf, len, 0)
+#else
+typedef int ano_socket_t;
+#define ano_sockclose(fd) close(fd)
+#define ano_sockread(fd, buf, len) read(fd, buf, len)
+#define ano_sockwrite(fd, buf, len) write(fd, buf, len)
+#define SOCKET_ERROR -1
+#endif
-static void remove_log()
+/* Data structures */
+struct smtp_message
{
- time_t t = time(NULL);
- t -= 2592000; // 30 days ago
- struct tm *tm = localtime(&t);
+ std::vector<std::string> smtp_headers;
+ std::vector<std::string> smtp_body;
+ std::string from;
+ std::string to;
+ ano_socket_t sock;
+};
- std::string name;
- if (!get_logname(name, tm))
- return;
- unlink(name.c_str());
-}
-/*************************************************************************/
+/* set this to 1 if you want to get a log otherwise it runs silent */
+int smtp_debug = 0;
-/* Open the log file. Return -1 if the log file could not be opened, else
- * return 0. */
+struct smtp_message smail;
-int open_log()
+static const char *get_logname(struct tm *tm = NULL)
{
- if (logfile)
- return 0;
-
- std::string name;
- if (!get_logname(name))
- return 0;
- logfile = fopen(name.c_str(), "w");
- return logfile ? 0 : -1;
-}
-
-/*************************************************************************/
-
-static void checkday()
-{
- time_t t = time(NULL);
- struct tm *tm = localtime(&t);
+ char timestamp[32];
- if (curday != tm->tm_yday)
+ if (!tm)
{
- close_log();
- remove_log();
- open_log();
+ time_t t = time(NULL);
+ tm = localtime(&t);
}
-}
-/*************************************************************************/
+ strftime(timestamp, sizeof(timestamp), "%Y%m%d", tm);
+ std::string name = std::string("logs/anopesmtp.") + timestamp;
+ return name.c_str();
+}
/* Log stuff to the log file with a datestamp. Note that errno is
* preserved by this routine and log_perror().
@@ -102,14 +117,13 @@ static void checkday()
void alog(const char *fmt, ...)
{
- int errno_save = errno;
-
- if (!smtp_debug)
+ if (!smtp_debug || !fmt)
return;
- checkday();
+ std::fstream file;
+ file.open(get_logname(), std::ios_base::out);
- if (!fmt)
+ if (!file.is_open())
return;
va_list args;
@@ -120,22 +134,21 @@ void alog(const char *fmt, ...)
char buf[256];
strftime(buf, sizeof(buf) - 1, "[%b %d %H:%M:%S %Y] ", tm);
- if (logfile)
- {
- fputs(buf, logfile);
- vfprintf(logfile, fmt, args);
- fputc('\n', logfile);
- }
+ file << buf;
+ vsnprintf(buf, sizeof(buf), fmt, args);
+ file << buf << std::endl;
+ va_end(args);
va_end(args);
- errno = errno_save;
+
+ file.close();
}
/*************************************************************************/
/* Remove a trailing \r\n */
-ci::string strip(const ci::string &buf)
+std::string strip(const std::string &buf)
{
- ci::string newbuf = buf;
+ std::string newbuf = buf;
char c = newbuf[newbuf.size() - 1];
while (c == '\n' || c == '\r')
{
@@ -148,14 +161,14 @@ ci::string strip(const ci::string &buf)
/*************************************************************************/
/* Is the buffer a header? */
-bool smtp_is_header(const ci::string &buf)
+bool smtp_is_header(const std::string &buf)
{
size_t tmp = buf.find(' ');
- if (tmp == ci::string::npos)
+ if (tmp == std::string::npos)
return false;
- if (buf[tmp + 1] == ':')
+ if (tmp > 0 && buf[tmp - 1] == ':')
return true;
return false;
}
@@ -163,12 +176,12 @@ bool smtp_is_header(const ci::string &buf)
/*************************************************************************/
/* Parse a header into a name and value */
-void smtp_parse_header(const ci::string &buf, ci::string &header, ci::string &value)
+void smtp_parse_header(const std::string &buf, std::string &header, std::string &value)
{
- ci::string newbuf = strip(buf);
+ std::string newbuf = strip(buf);
size_t space = newbuf.find(' ');
- if (space != ci::string::npos)
+ if (space != std::string::npos)
{
header = newbuf.substr(0, space);
value = newbuf.substr(space + 1);
@@ -183,7 +196,7 @@ void smtp_parse_header(const ci::string &buf, ci::string &header, ci::string &va
/*************************************************************************/
/* Have we reached the end of input? */
-bool smtp_is_end(const ci::string &buf)
+bool smtp_is_end(const std::string &buf)
{
if (buf[0] == '.')
if (buf[1] == '\r' || buf[1] == '\n')
@@ -195,14 +208,14 @@ bool smtp_is_end(const ci::string &buf)
/*************************************************************************/
/* Set who the email is to */
-void smtp_set_to(const ci::string &to)
+void smtp_set_to(const std::string &to)
{
- mail.to = to;
- size_t c = mail.to.rfind('<');
- if (c != ci::string::npos && c + 1 < mail.to.size())
+ smail.to = to;
+ size_t c = smail.to.rfind('<');
+ if (c != std::string::npos && c + 1 < smail.to.size())
{
- mail.to = mail.to.substr(c + 1);
- mail.to.erase(mail.to.end() - 1);
+ smail.to = smail.to.substr(c + 1);
+ smail.to.erase(smail.to.end() - 1);
}
}
@@ -213,7 +226,7 @@ int smtp_connect(const char *host, unsigned short port)
{
struct sockaddr_in addr;
- if ((mail.sock = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR)
+ if ((smail.sock = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR)
return 0;
if ((addr.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE)
@@ -225,9 +238,9 @@ int smtp_connect(const char *host, unsigned short port)
}
addr.sin_family = AF_INET;
addr.sin_port = htons(port ? port : 25);
- if (connect(mail.sock, reinterpret_cast<struct sockaddr *>(&addr), sizeof(struct sockaddr_in)) == SOCKET_ERROR)
+ if (connect(smail.sock, reinterpret_cast<struct sockaddr *>(&addr), sizeof(struct sockaddr_in)) == SOCKET_ERROR)
{
- ano_sockclose(mail.sock);
+ ano_sockclose(smail.sock);
return 0;
}
@@ -239,12 +252,12 @@ int smtp_connect(const char *host, unsigned short port)
/* Send a line of text */
int smtp_send(const char *text)
{
- int result = ano_sockwrite(mail.sock, text, strlen(text));
+ int result = ano_sockwrite(smail.sock, text, strlen(text));
alog("SMTP: sent %s",text);
if (result == SOCKET_ERROR)
- ano_sockclose(mail.sock);
+ ano_sockclose(smail.sock);
return result;
}
@@ -257,10 +270,10 @@ int smtp_read(char *buf, int len)
int result;
memset(buf, 0, len);
- result = ano_sockread(mail.sock, buf, len);
+ result = ano_sockread(smail.sock, buf, len);
if (result == SOCKET_ERROR)
- ano_sockclose(mail.sock);
+ ano_sockclose(smail.sock);
return result;
}
@@ -272,10 +285,10 @@ int smtp_get_code(const std::string &text)
{
size_t tmp = text.find(' ');
- if (tmp == ci::string::npos)
+ if (tmp == std::string::npos)
return 0;
- return atol(text.c_str());
+ return atol(text.substr(0, tmp).c_str());
}
/*************************************************************************/
@@ -317,7 +330,7 @@ int smtp_send_email()
}
strcpy(buf, "MAIL FROM: <");
- strcat(buf, mail.from.c_str());
+ strcat(buf, smail.from.c_str());
strcat(buf, ">\r\n");
if (!smtp_send(buf))
@@ -337,7 +350,7 @@ int smtp_send_email()
return 0;
strcpy(buf, "RCPT TO: <");
- strcat(buf, mail.to.c_str());
+ strcat(buf, smail.to.c_str());
strcat(buf, ">\r\n");
if (!smtp_send(buf))
@@ -378,7 +391,7 @@ int smtp_send_email()
return 0;
}
- for (std::vector<ci::string>::const_iterator it = mail.smtp_headers.begin(), it_end = mail.smtp_headers.end(); it != it_end; ++it)
+ for (std::vector<std::string>::const_iterator it = smail.smtp_headers.begin(), it_end = smail.smtp_headers.end(); it != it_end; ++it)
if (!smtp_send(it->c_str()))
{
alog("SMTP: error writting to socket");
@@ -392,7 +405,7 @@ int smtp_send_email()
}
bool skip_done = false;
- for (std::vector<ci::string>::const_iterator it = mail.smtp_body.begin(), it_end = mail.smtp_body.end(); it != it_end; ++it)
+ for (std::vector<std::string>::const_iterator it = smail.smtp_body.begin(), it_end = smail.smtp_body.end(); it != it_end; ++it)
if (skip_done)
{
if (!smtp_send(it->c_str()))
@@ -418,19 +431,7 @@ int smtp_send_email()
void smtp_disconnect()
{
smtp_send("QUIT\r\n");
- ano_sockclose(mail.sock);
-}
-
-/*************************************************************************/
-
-void mail_cleanup()
-{
- mail.from.clear();
- mail.to.clear();
-
- mail.smtp_headers.clear();
-
- mail.smtp_body.clear();
+ ano_sockclose(smail.sock);
}
/*************************************************************************/
@@ -461,8 +462,6 @@ int main(int argc, char *argv[])
else
alog("SMTP: server %s port %d",server,port);
- memset(&mail, 0, sizeof(mail));
-
/* The WSAStartup function initiates use of WS2_32.DLL by a process. */
/* guessing we can skip it under *nix */
#ifdef _WIN32
@@ -477,15 +476,15 @@ int main(int argc, char *argv[])
{
if (smtp_is_header(buf) && !headers_done)
{
- mail.smtp_headers.push_back(strip(buf) + "\r\n");
- ci::string header, value;
+ smail.smtp_headers.push_back(strip(buf) + "\r\n");
+ std::string header, value;
smtp_parse_header(buf, header, value);
- if (header == "from")
+ if (header == "From:")
{
alog("SMTP: from: %s", value.c_str());
- mail.from = value;
+ smail.from = value;
}
- else if (header == "to")
+ else if (header == "To:")
{
alog("SMTP: to: %s", value.c_str());
smtp_set_to(value);
@@ -495,27 +494,24 @@ int main(int argc, char *argv[])
else
{
headers_done = true;
- mail.smtp_body.push_back(strip(buf) + "\r\n");
+ smail.smtp_body.push_back(strip(buf) + "\r\n");
}
}
else
- mail.smtp_body.push_back(strip(buf) + "\r\n");
+ smail.smtp_body.push_back(strip(buf) + "\r\n");
}
if (!smtp_connect(server, port))
{
alog("SMTP: failed to connect to %s:%d", server, port);
- mail_cleanup();
return 0;
}
if (!smtp_send_email())
{
alog("SMTP: error during sending of mail");
- mail_cleanup();
return 0;
}
smtp_disconnect();
- mail_cleanup();
return 1;
}
diff --git a/src/tools/smtp.h b/src/tools/smtp.h
deleted file mode 100644
index b7c9ef249..000000000
--- a/src/tools/smtp.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * (C) 2003-2010 Anope Team
- * Contact us at team@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.
- */
-
-#ifndef SMTP_H
-#define SMTP_H
-
-#include "sysconf.h"
-#include "hashcomp.h"
-
-/*************************************************************************/
-
-/* Some Linux boxes (or maybe glibc includes) require this for the
- * prototype of strsignal(). */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
-
-#include <string>
-#include <vector>
-#include <cstdarg>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <ctime>
-#include <cerrno>
-
-/* Windows does not have:
- * unistd.h, grp.h,
- * netdb.h, netinet/in.h,
- * sys/socket.h, sys/time.h
- * Windows requires:
- * winsock.h
- * -- codemastr
- */
-
-#ifndef _WIN32
-# include <unistd.h>
-#endif
-
-#ifndef _WIN32
-# include <netdb.h>
-# include <netinet/in.h>
-# include <sys/socket.h>
-# include <arpa/inet.h>
-#else
-# include <winsock.h>
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-#endif
-
-#include <sys/types.h>
-
-#ifndef _WIN32
-# include <sys/time.h>
-#endif
-
-#ifdef _AIX
-extern int strcasecmp(const char *, const char *);
-extern int strncasecmp(const char *, const char *, size_t);
-# if 0 /* These break on some AIX boxes (4.3.1 reported). */
-extern int socket(int, int, int);
-extern int connect(int, struct sockaddr *, int);
-# endif
-#endif /* _AIX */
-
-/* Some SUN fixs */
-#ifdef __sun
-/* Solaris specific code, types that do not exist in Solaris'
- * * sys/types.h
- * **/
-# ifndef INADDR_NONE
-# define INADDR_NONE (-1)
-# endif
-#endif
-
-/*************************************************************************/
-
-#ifdef _WIN32
-typedef SOCKET ano_socket_t;
-#define ano_sockclose(fd) closesocket(fd)
-#define ano_sockread(fd, buf, len) recv(fd, buf, len, 0)
-#define ano_sockwrite(fd, buf, len) send(fd, buf, len, 0)
-#else
-typedef int ano_socket_t;
-#define ano_sockclose(fd) close(fd)
-#define ano_sockread(fd, buf, len) read(fd, buf, len)
-#define ano_sockwrite(fd, buf, len) write(fd, buf, len)
-#define SOCKET_ERROR -1
-#endif
-
-/* Data structures */
-struct smtp_message
-{
- std::vector<ci::string> smtp_headers;
- std::vector<ci::string> smtp_body;
- ci::string from, to;
- ano_socket_t sock;
-};
-
-struct smtp_message mail;
-
-/* set this to 1 if you want to get a log otherwise it runs silent */
-int smtp_debug = 0;
-
-#endif /* SMTP_H */
diff --git a/src/users.cpp b/src/users.cpp
index 6ab771ec1..12502efae 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -253,11 +253,6 @@ void User::SendMessage(BotInfo *source, LanguageString message, ...) const
Anope::string m = GetString(this, message);
- if (Config->UseStrictPrivMsg)
- m = m.replace_all_cs("%R", "/");
- else
- m = m.replace_all_cs("%R", "/msg ");
-
m = m.replace_all_cs("%S", source->nick);
if (m.length() >= 4096)