summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changes1
-rw-r--r--anopesmtp.c338
-rw-r--r--config.c1
-rw-r--r--init.c1
-rw-r--r--lang/langtool.c15
-rw-r--r--sockets.h47
-rw-r--r--threads.h65
-rw-r--r--version.log6
-rw-r--r--version.sh.c215
9 files changed, 687 insertions, 2 deletions
diff --git a/Changes b/Changes
index d881d14b6..fa5c2bb12 100644
--- a/Changes
+++ b/Changes
@@ -9,6 +9,7 @@ Provided by Anope Dev. <dev@anope.org> - 2004
05/24 A New NSNickTracking directive to provide nick tracking. [ #71]
05/21 A Auto enforce upon AKICK addition. [ #63]
05/21 A New file docs/OLDCHANGES contains all change history. [ #65]
+06/12 F We check now for GlobalOnCyleUP if GlobalOnCycle is enabled. [ #91]
06/12 F We check now for valid arguments in ModuleAddData(). [ #90]
06/12 F Unified kill_user function to handle all ircd protocols. [#101]
06/10 F Added check to see if MysqlUser and MysqlName were not null. [ #92]
diff --git a/anopesmtp.c b/anopesmtp.c
new file mode 100644
index 000000000..bc0e65f59
--- /dev/null
+++ b/anopesmtp.c
@@ -0,0 +1,338 @@
+/* smtp stuff handler for win32.
+ *
+ * (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.
+ *
+ * Written by Dominick Meglio <codemastr@unrealircd.com>
+ *
+ */
+
+#include <winsock.h>
+#include <stdio.h>
+
+/* Data structures */
+struct smtp_header {
+ char *header;
+ struct smtp_header *next;
+};
+
+struct smtp_body_line {
+ char *line;
+ struct smtp_body_line *next;
+};
+
+struct smtp_message {
+ struct smtp_header *smtp_headers, *smtp_headers_tail;
+ struct smtp_body_line *smtp_body, *smtp_body_tail;
+ char *from;
+ char *to;
+ SOCKET sock;
+};
+
+struct smtp_message mail;
+
+/* Remove a trailing \r\n */
+char *strip(char *buf)
+{
+ char *c;
+ if ((c = strchr(buf, '\n')))
+ *c = 0;
+ if ((c = strchr(buf, '\r')))
+ *c = 0;
+ return buf;
+}
+
+/* Convert a trailing \n to \r\n
+ * The caller must free the allocated memory
+ */
+char *lftocrlf(char *buf)
+{
+ char *result = malloc(strlen(buf) + 2);
+ strip(buf);
+ strcpy(result, buf);
+ strcat(result, "\r\n");
+ return result;
+}
+
+/* Add a header to the list */
+void smtp_add_header(char *header)
+{
+ struct smtp_header *head = malloc(sizeof(struct smtp_header));
+
+ head->header = lftocrlf(header);
+ head->next = NULL;
+
+ if (!mail.smtp_headers)
+ mail.smtp_headers = head;
+ if (mail.smtp_headers_tail)
+ mail.smtp_headers_tail->next = head;
+ mail.smtp_headers_tail = head;
+}
+
+/* Is the buffer a header? */
+int smtp_is_header(char *buf)
+{
+ char *tmp = strchr(buf, ' ');
+
+ if (!tmp)
+ return 0;
+
+ if (*(tmp - 1) == ':')
+ return 1;
+ return 0;
+}
+
+/* Parse a header into a name and value */
+void smtp_parse_header(char *buf, char **header, char **value)
+{
+ strip(buf);
+
+ *header = strtok(buf, " ");
+ *value = strtok(NULL, "");
+ if (*header)
+ (*header)[strlen(*header) - 1] = 0;
+}
+
+/* Have we reached the end of input? */
+int smtp_is_end(char *buf)
+{
+ if (*buf == '.')
+ if (*(buf + 1) == '\r' || *(buf + 1) == '\n')
+ return 1;
+
+ return 0;
+}
+
+/* Set who the email is from */
+void smtp_set_from(char *from)
+{
+ mail.from = strdup(from);
+}
+
+/* Set who the email is to */
+void smtp_set_to(char *to)
+{
+ char *c;
+
+ if ((c = strrchr(to, '<')) && *(c + 1)) {
+ to = c + 1;
+ to[strlen(to) - 1] = 0;
+ }
+ mail.to = strdup(to);
+}
+
+/* Add a line of body text */
+void smtp_add_body_line(char *line)
+{
+ struct smtp_body_line *body = malloc(sizeof(struct smtp_body_line));
+
+ body->line = lftocrlf(line);
+ body->next = NULL;
+
+ if (!mail.smtp_body)
+ mail.smtp_body = body;
+ if (mail.smtp_body_tail)
+ mail.smtp_body_tail->next = body;
+ mail.smtp_body_tail = body;
+}
+
+/* Establish a connection to the SMTP server */
+int smtp_connect(char *host, unsigned short port)
+{
+ struct sockaddr_in addr;
+
+ if ((mail.sock = socket(AF_INET, SOCK_STREAM, 0)) == SOCKET_ERROR)
+ return 0;
+
+ if ((addr.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) {
+ struct hostent *hent;
+ if (!(hent = gethostbyname(host)))
+ return 0;
+ memcpy(&addr.sin_addr, hent->h_addr, hent->h_length);
+ }
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(port ? port : 25);
+ if (connect
+ (mail.sock, (struct sockaddr *) &addr,
+ sizeof(struct sockaddr_in)) == SOCKET_ERROR) {
+ closesocket(mail.sock);
+ return 0;
+ }
+
+ return 1;
+}
+
+/* Send a line of text */
+int smtp_send(char *text)
+{
+ int result = send(mail.sock, text, strlen(text), 0);
+
+ if (result == SOCKET_ERROR)
+ closesocket(mail.sock);
+
+ return result;
+}
+
+/* Read a line of text */
+int smtp_read(char *buf, int len)
+{
+ int result;
+
+ memset(buf, 0, len);
+ result = recv(mail.sock, buf, len, 0);
+
+ if (result == SOCKET_ERROR)
+ closesocket(mail.sock);
+
+ return result;
+}
+
+/* Retrieve a response code */
+int smtp_get_code(char *text)
+{
+ char *tmp = strtok(text, " ");
+
+ if (!tmp)
+ return 0;
+
+ return atol(tmp);
+}
+
+/* Send the email */
+int smtp_send_email()
+{
+ char buf[1024];
+ struct smtp_header *head;
+ struct smtp_body_line *body;
+
+ if (!smtp_read(buf, 1024))
+ return 0;
+
+ if (smtp_get_code(buf) != 220)
+ return 0;
+
+ if (!smtp_send("HELO anope\r\n"))
+ return 0;
+
+ if (!smtp_read(buf, 1024))
+ return 0;
+
+ if (smtp_get_code(buf) != 250)
+ return 0;
+
+ strcpy(buf, "MAIL FROM: <");
+ strcat(buf, mail.from);
+ strcat(buf, ">\r\n");
+
+ if (!smtp_send(buf))
+ return 0;
+
+ if (!smtp_read(buf, 1024))
+ return 0;
+
+ if (smtp_get_code(buf) != 250)
+ return 0;
+
+ strcpy(buf, "RCPT TO: <");
+ strcat(buf, mail.to);
+ strcat(buf, ">\r\n");
+
+ if (!smtp_send(buf))
+ return 0;
+
+ if (!smtp_read(buf, 1024))
+ return 0;
+
+ if (smtp_get_code(buf) != 250)
+ return 0;
+
+
+ if (!smtp_send("DATA\r\n"))
+ return 0;
+
+ if (!smtp_read(buf, 1024))
+ return 0;
+
+ if (smtp_get_code(buf) != 354)
+ return 0;
+
+ for (head = mail.smtp_headers; head; head = head->next) {
+ if (!smtp_send(head->header))
+ return 0;
+ }
+
+ if (!smtp_send("\r\n"))
+ return 0;
+
+ for (body = mail.smtp_body; body; body = body->next) {
+ if (!smtp_send(body->line))
+ return 0;
+ }
+
+ if (!smtp_send("\r\n.\r\n"))
+ return 0;
+
+ return 1;
+}
+
+void smtp_disconnect()
+{
+ smtp_send("QUIT\r\n");
+ closesocket(mail.sock);
+}
+
+int main(int argc, char *argv[])
+{
+ char buf[8192];
+ struct smtp_body_line *b;
+ struct smtp_header *h;
+ int headers_done = 0;
+ WSADATA wsa;
+ char *server, *aport;
+ short port;
+
+
+ if (argc == 1)
+ return 0;
+
+ server = strtok(argv[1], ":");
+ if ((aport = strtok(NULL, "")))
+ port = atoi(aport);
+ else
+ port = 25;
+
+
+ memset(&mail, 0, sizeof(mail));
+
+ if (WSAStartup(MAKEWORD(1, 1), &wsa) != 0)
+ return 0;
+
+ /* Read the message and parse it */
+ while (fgets(buf, 8192, stdin)) {
+ if (smtp_is_header(buf) && !headers_done) {
+ char *header, *value;
+ smtp_add_header(buf);
+ smtp_parse_header(buf, &header, &value);
+ if (!stricmp(header, "from"))
+ smtp_set_from(value);
+ else if (!stricmp(header, "to"))
+ smtp_set_to(value);
+ } else if (smtp_is_end(buf))
+ break;
+ else {
+ headers_done = 1;
+ smtp_add_body_line(buf);
+ }
+ }
+
+ if (!smtp_connect(server, port))
+ return 0;
+ if (!smtp_send_email())
+ return 0;
+ smtp_disconnect();
+}
diff --git a/config.c b/config.c
index c52179d9c..75a0cc30d 100644
--- a/config.c
+++ b/config.c
@@ -1227,6 +1227,7 @@ int read_config(int reload)
if (GlobalOnCycle) {
CHECK(GlobalOnCycleMessage);
+ CHECK(GlobalOnCycleUP);
}
/**
diff --git a/init.c b/init.c
index 6a72641ea..6448affba 100644
--- a/init.c
+++ b/init.c
@@ -26,7 +26,6 @@ extern void moduleAddMsgs(void);
#if defined(IRC_HYBRID)
# define NICK(nick,name,modes) \
do { \
- kill_user(NULL, (nick), "Nick used by Services"); \
send_cmd(NULL, "NICK %s 1 %ld %s %s %s %s :%s", (nick), time(NULL), (modes), \
ServiceUser, ServiceHost, ServerName, (name)); \
} while (0)
diff --git a/lang/langtool.c b/lang/langtool.c
index 3175118e0..54956e396 100644
--- a/lang/langtool.c
+++ b/lang/langtool.c
@@ -1,3 +1,18 @@
+/* Language stuff generator for win32.
+ *
+ * (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.
+ *
+ * Written by Dominick Meglio <codemastr@unrealircd.com>
+ *
+ */
+
+
/* Needed due to Windows lack of a decent interpreter */
#include <string.h>
diff --git a/sockets.h b/sockets.h
new file mode 100644
index 000000000..e5ae27c58
--- /dev/null
+++ b/sockets.h
@@ -0,0 +1,47 @@
+/*
+ *
+ * (C) 2004 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.
+ *
+ *
+ */
+
+#ifndef SOCKETS_H
+#define SOCKETS_H
+
+#ifdef _WIN32
+typedef SOCKET ano_socket_t;
+#define ano_sockread(fd, buf, len) recv(fd, buf, len, 0)
+#define ano_sockwrite(fd, buf, len) send(fd, buf, len, 0)
+#define ano_sockclose(fd) closesocket(fd)
+#define ano_sockgeterr() WSAGetLastError()
+#define ano_sockseterr(err) WSASetLastError(err)
+/* ano_sockstrerror in sockutil.c */
+/* ano_socksetnonb in sockutil.c */
+#define ano_sockerrnonb(err) (err == WSAEINPROGRESS || err == WSAEWOULDBLOCK)
+#define SOCKERR_EBADF WSAENOTSOCK
+#define SOCKERR_EINTR WSAEINTR
+#define SOCKERR_EINVAL WSAEINVAL
+#define SOCKERR_EINPROGRESS WSAEINPROGRESS
+#else
+typedef int ano_socket_t;
+#define ano_sockread(fd, buf, len) read(fd, buf, len)
+#define ano_sockwrite(fd, buf, len) write(fd, buf, len)
+#define ano_sockclose(fd) close(fd)
+#define ano_sockgeterr() errno
+#define ano_sockseterr(err) errno = err
+#define ano_sockstrerror(err) strerror(err)
+#define ano_socksetnonb(fd) fcntl(fd, F_SETFL, O_NONBLOCK)
+#define ano_sockerrnonb(err) (err == EINPROGRESS)
+#define SOCKERR_EBADF EBADF
+#define SOCKERR_EINTR EINTR
+#define SOCKERR_EINVAL EINVAL
+#define SOCKERR_EINPROGRESS EINPROGRESS
+#endif
+
+#endif
diff --git a/threads.h b/threads.h
new file mode 100644
index 000000000..b78e6a106
--- /dev/null
+++ b/threads.h
@@ -0,0 +1,65 @@
+/*
+ *
+ * (C) 2004 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.
+ *
+ *
+ */
+
+#ifndef THREADS_H
+#define THREADS_H
+
+#ifdef _WIN32
+typedef long ano_thread_t;
+typedef HANDLE ano_mutex_t;
+typedef HANDLE ano_cond_t;
+typedef unsigned (__stdcall *ano_thread_start) (void *);
+typedef struct
+{
+ ano_thread_start func;
+ void *arg;
+} ano_cleanup_t;
+
+extern ano_thread_start __declspec(thread) cleanup_func;
+
+#define ano_thread_create(thread,start,arg) !_beginthreadex(NULL, 0, (ano_thread_start)start, arg, 0, &thread)
+#define ano_thread_self() GetCurrentThreadId()
+#define ano_thread_detach(thread) 0
+#define ano_mutex_lock(mutex) WaitForSingleObject(mutex, INFINITE)
+#define ano_mutex_unlock(mutex) ReleaseMutex(mutex)
+
+/* ano_cond_wait is in compat.c */
+#define ano_cond_signal(cond) SetEvent(cond)
+
+/* very minimalistic implementation */
+#define ano_cleanup_push(func, arg) cleanup_func = (ano_thread_start)func
+#define ano_cleanup_pop(execute) cleanup_func(NULL)
+#else
+typedef pthread_t ano_thread_t;
+typedef ano_mutex_t pthread_mutex_t;
+typedef ano_cond_t pthread_cond_t;
+typedef void *(*ano_thread_start) (void *);
+
+#define ano_thread_create(thread,start,arg) pthread_create(&thread, NULL, (void *)start, arg)
+#define ano_thread_self() pthread_self()
+#define ano_thread_detach(thread) pthread_detach(thread)
+
+#define ano_mutex_lock(mutex) pthread_mutex_lock(&mutex)
+#define ano_mutex_unlock(mutex) pthread_mutex_unlock(&mutex)
+
+#define ano_cond_wait(cond, mutex) pthread_cond_wait(&cond, &mutex)
+#define ano_cond_signal(cond) pthread_cond_signal(&cond)
+
+#define ano_cleanup_push(func, arg) pthread_cleanup_push(func, arg)
+#define ano_cleanup_pop(execute) pthread_cleanup_pop(execute)
+
+#define ano_thread_cancel(thread) pthread_cancel(thread)
+
+#endif
+
+#endif
diff --git a/version.log b/version.log
index 07168a89d..fd9617510 100644
--- a/version.log
+++ b/version.log
@@ -8,10 +8,14 @@
VERSION_MAJOR="1"
VERSION_MINOR="7"
VERSION_PATCH="3"
-VERSION_BUILD="190"
+VERSION_BUILD="191"
# $Log$
#
+# BUILD : 1.7.3 (191)
+# BUGS : 91
+# NOTES : Fixed bug 91 and added new win32 stuff for codemastr
+#
# BUILD : 1.7.3 (190)
# BUGS : 90
# NOTES : We check now for valid arguments in ModuleAddData().
diff --git a/version.sh.c b/version.sh.c
new file mode 100644
index 000000000..f08d3b460
--- /dev/null
+++ b/version.sh.c
@@ -0,0 +1,215 @@
+/* version file handler for win32.
+ *
+ * (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.
+ *
+ * Written by Dominick Meglio <codemastr@unrealircd.com>
+ *
+ */
+
+/* Needed due to Windows lack of a decent interpreter */
+
+#include <stdio.h>
+#include <string.h>
+
+#define CTRL "version.log"
+
+long version_major, version_minor, version_patch, version_build, build;
+char *version_extra;
+char version[1024];
+
+
+void load_ctrl(FILE *);
+long get_value(char *);
+char *get_value_str(char *);
+char *strip(char *);
+void parse_version(FILE *);
+void write_version(FILE *);
+void parse_line(FILE *, char *);
+
+int main()
+{
+ FILE *fd = fopen(CTRL, "r");
+
+
+ if (!fd) {
+ fprintf(stderr, "Error: Unable to find control file: " CTRL "\n");
+ exit(0);
+ }
+
+ load_ctrl(fd);
+ fclose(fd);
+
+ _snprintf(version, 1024, "%d.%d.%d%s", version_major, version_minor,
+ version_patch, version_extra ? version_extra : "");
+
+
+ fd = fopen("version.h", "r");
+
+ if (fd) {
+ parse_version(fd);
+ fclose(fd);
+ } else
+ build = 1;
+
+
+ fd = fopen("version.h", "w");
+ write_version(fd);
+ fclose(fd);
+}
+
+void load_ctrl(FILE * fd)
+{
+ char buf[512];
+ while (fgets(buf, 511, fd)) {
+ char *var;
+
+ strip(buf);
+
+ var = strtok(buf, "=");
+ if (!var)
+ continue;
+ if (!strcmp(var, "VERSION_MAJOR"))
+ version_major = get_value(strtok(NULL, ""));
+ else if (!strcmp(var, "VERSION_MINOR"))
+ version_minor = get_value(strtok(NULL, ""));
+ else if (!strcmp(var, "VERSION_PATCH"))
+ version_patch = get_value(strtok(NULL, ""));
+ else if (!strcmp(var, "VERSION_BUILD"))
+ version_build = get_value(strtok(NULL, ""));
+ else if (!strcmp(var, "VERSION_EXTRA"))
+ version_extra = get_value_str(strtok(NULL, ""));
+
+ }
+}
+
+char *strip(char *str)
+{
+ char *c;
+ if ((c = strchr(str, '\n')))
+ *c = 0;
+ if ((c = strchr(str, '\r')))
+ *c = 0;
+ return str;
+}
+
+long get_value(char *string)
+{
+ return atol(get_value_str(string));
+}
+
+char *get_value_str(char *string)
+{
+ int len;
+
+ if (*string == '"')
+ string++;
+
+ len = strlen(string);
+
+ if (string[len - 1] == '"')
+ string[len - 1] = 0;
+ if (!*string)
+ return NULL;
+ return string;
+}
+
+void parse_version(FILE * fd)
+{
+ char buf[1024];
+
+ while (fgets(buf, 1023, fd)) {
+ char *para1;
+
+ strip(buf);
+ para1 = strtok(buf, " \t");
+
+ if (!para1)
+ continue;
+
+ if (!strcmp(para1, "#define")) {
+ char *para2 = strtok(NULL, " \t");
+
+ if (!para2)
+ continue;
+
+ if (!strcmp(para2, "BUILD")) {
+ char *value = strtok(NULL, "");
+ build = get_value(value);
+ build++;
+ return;
+ }
+ }
+ }
+ build = 1;
+}
+
+void write_version(FILE * fd)
+{
+ FILE *fdin = fopen("version.sh", "r");
+ char buf[1024];
+ short until_eof = 0;
+
+ while (fgets(buf, 1023, fdin)) {
+ strip(buf);
+
+ if (until_eof)
+ if (!strcmp(buf, "EOF"))
+ break;
+ else
+ parse_line(fd, buf);
+
+ if (!strcmp(buf, "cat >version.h <<EOF"))
+ until_eof = 1;
+ }
+
+}
+
+void parse_line(FILE * fd, char *line)
+{
+ char *c;
+ for (c = line; *c; c++) {
+ /* It's a variable, find out which */
+ if (*c == '$') {
+ char *var, *varbegin;
+
+ if (*(c + 1))
+ c++;
+ else
+ continue;
+ for (var = varbegin = c; var; var++) {
+ if (!isalnum(*var) && *var != '_')
+ break;
+ }
+ if (var != varbegin) {
+ char tmp = *var;
+
+ *var = 0;
+ if (!strcmp(varbegin, "VERSION_MAJOR"))
+ fprintf(fd, "%d", version_major);
+ else if (!strcmp(varbegin, "VERSION_MINOR"))
+ fprintf(fd, "%d", version_minor);
+ else if (!strcmp(varbegin, "VERSION_PATCH"))
+ fprintf(fd, "%d", version_patch);
+ else if (!strcmp(varbegin, "VERSION_EXTRA")) {
+ if (version_extra)
+ fprintf(fd, "%s", version_extra);
+ } else if (!strcmp(varbegin, "VERSION_BUILD"))
+ fprintf(fd, "%d", version_build);
+ else if (!strcmp(varbegin, "BUILD"))
+ fprintf(fd, "%d", build);
+ else if (!strcmp(varbegin, "VERSION"))
+ fprintf(fd, "%s", version);
+ fputc(tmp, fd);
+ }
+ c = var;
+ } else
+ fputc(*c, fd);
+ }
+ fprintf(fd, "\r\n");
+}