diff options
author | certus certus@31f1291d-b8d6-0310-a050-a5561fc1590b <certus certus@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864> | 2004-06-12 18:23:54 +0000 |
---|---|---|
committer | certus certus@31f1291d-b8d6-0310-a050-a5561fc1590b <certus certus@31f1291d-b8d6-0310-a050-a5561fc1590b@5417fbe8-f217-4b02-8779-1006273d7864> | 2004-06-12 18:23:54 +0000 |
commit | a0211857cd029fea81aead88cd50c03ff7b1f8d3 (patch) | |
tree | 452e288ed1a36100030ff07e5dae523c0ec04826 | |
parent | d3956b71486727dafbe72550f6baec5f4108bf7b (diff) |
BUILD : 1.7.3 (191) BUGS : 91 NOTES : Fixed bug 91 and added new win32 stuff for codemastr
git-svn-id: svn://svn.anope.org/anope/trunk@191 31f1291d-b8d6-0310-a050-a5561fc1590b
git-svn-id: http://anope.svn.sourceforge.net/svnroot/anope/trunk@136 5417fbe8-f217-4b02-8779-1006273d7864
-rw-r--r-- | Changes | 1 | ||||
-rw-r--r-- | anopesmtp.c | 338 | ||||
-rw-r--r-- | config.c | 1 | ||||
-rw-r--r-- | init.c | 1 | ||||
-rw-r--r-- | lang/langtool.c | 15 | ||||
-rw-r--r-- | sockets.h | 47 | ||||
-rw-r--r-- | threads.h | 65 | ||||
-rw-r--r-- | version.log | 6 | ||||
-rw-r--r-- | version.sh.c | 215 |
9 files changed, 687 insertions, 2 deletions
@@ -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(); +} @@ -1227,6 +1227,7 @@ int read_config(int reload) if (GlobalOnCycle) { CHECK(GlobalOnCycleMessage); + CHECK(GlobalOnCycleUP); } /** @@ -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"); +} |