summaryrefslogtreecommitdiffstats
path: root/util/outmail.c
diff options
context:
space:
mode:
authorin2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2002-03-07 23:13:44 +0800
committerin2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2002-03-07 23:13:44 +0800
commitae31e19f92e717919ac8e3db9039eb38d2b89aae (patch)
treec70164d6a1852344f44b04a653ae2815043512af /util/outmail.c
downloadpttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.gz
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.bz2
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.lz
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.xz
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.zst
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.zip
Initial revision
git-svn-id: http://opensvn.csie.org/pttbbs/pttbbs/trunk/pttbbs@1 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'util/outmail.c')
-rw-r--r--util/outmail.c274
1 files changed, 274 insertions, 0 deletions
diff --git a/util/outmail.c b/util/outmail.c
new file mode 100644
index 00000000..d6b19bb4
--- /dev/null
+++ b/util/outmail.c
@@ -0,0 +1,274 @@
+/* $Id: outmail.c,v 1.1 2002/03/07 15:13:46 in2 Exp $ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/file.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include "config.h"
+#include "pttstruct.h"
+
+
+#ifdef HAVE_SETPROCTITLE
+
+#include <sys/types.h>
+#include <libutil.h>
+
+void initsetproctitle(int argc, char **argv, char **envp) {
+}
+
+#else
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+char **Argv = NULL; /* pointer to argument vector */
+char *LastArgv = NULL; /* end of argv */
+extern char **environ;
+
+void initsetproctitle(int argc, char **argv, char **envp) {
+ register int i;
+
+ /* Move the environment so setproctitle can use the space at
+ the top of memory. */
+ for(i = 0; envp[i]; i++);
+ environ = malloc(sizeof(char *) * (i + 1));
+ for(i = 0; envp[i]; i++)
+ environ[i] = strdup(envp[i]);
+ environ[i] = NULL;
+
+ /* Save start and extent of argv for setproctitle. */
+ Argv = argv;
+ if(i > 0)
+ LastArgv = envp[i - 1] + strlen(envp[i - 1]);
+ else
+ LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);
+}
+
+static void do_setproctitle(const char *cmdline) {
+ char buf[256], *p;
+ int i;
+
+ strncpy(buf, cmdline, 256);
+ buf[255] = '\0';
+ i = strlen(buf);
+ if(i > LastArgv - Argv[0] - 2) {
+ i = LastArgv - Argv[0] - 2;
+ }
+ strcpy(Argv[0], buf);
+ p = &Argv[0][i];
+ while(p < LastArgv)
+ *p++='\0';
+ Argv[1] = NULL;
+}
+
+void setproctitle(const char* format, ...) {
+ char buf[256];
+
+ va_list args;
+ va_start(args, format);
+ vsprintf(buf, format,args);
+ do_setproctitle(buf);
+ va_end(args);
+}
+#endif
+
+
+
+
+
+#define SPOOL BBSHOME "/out"
+#define INDEX SPOOL "/.DIR"
+#define NEWINDEX SPOOL "/.DIR.sending"
+#define FROM ".bbs@" MYHOSTNAME
+#define SMTPPORT 25
+
+int waitReply(int sock) {
+ char buf[256];
+
+ if(read(sock, buf, sizeof(buf)) <= 0)
+ return -1;
+ else
+ return buf[0] - '0';
+}
+
+int sendRequest(int sock, char *request) {
+ return write(sock, request, strlen(request)) < 0 ? -1 : 0;
+}
+
+int connectMailServer() {
+ int sock;
+ struct sockaddr_in addr;
+
+ if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
+ perror("socket");
+ return -1;
+ }
+
+ memset(&addr, 0, sizeof(addr));
+#ifdef FreeBSD
+ addr.sin_len = sizeof(addr);
+#endif
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(SMTPPORT);
+ addr.sin_addr.s_addr = inet_addr(RELAY_SERVER_IP);
+
+ if(connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ perror(RELAY_SERVER_IP);
+ close(sock);
+ return -1;
+ }
+
+ if(waitReply(sock) != 2) {
+ close(sock);
+ return -1;
+ }
+
+ if(sendRequest(sock, "helo " MYHOSTNAME "\n") || waitReply(sock) != 2) {
+ close(sock);
+ return -1;
+ } else
+ return sock;
+}
+
+void disconnectMailServer(int sock) {
+ sendRequest(sock, "quit\n");
+ /* drop the reply :p */
+ close(sock);
+}
+
+void doSendBody(int sock, FILE *fp, char *from, char *to, char *subject) {
+ int n;
+ char buf[2048];
+
+ n = snprintf(buf, sizeof(buf), "From: %s\nTo: %s\nSubject: %s\n\n",
+ from, to, subject);
+ write(sock, buf, n);
+
+ while(fgets(buf, sizeof(buf), fp)) {
+ if(buf[0] == '.' && buf[1] == '\n')
+ strcpy(buf, "..\n");
+ write(sock, buf, strlen(buf));
+ }
+}
+
+void doSendMail(int sock, FILE *fp, char *from, char *to, char *subject) {
+ char buf[256];
+
+ snprintf(buf, sizeof(buf), "mail from: %s\n", from);
+ if(sendRequest(sock, buf) || waitReply(sock) != 2)
+ return;
+
+ snprintf(buf, sizeof(buf), "rcpt to: %s\n", to);
+ if(sendRequest(sock, buf) || waitReply(sock) != 2)
+ return;
+
+ if(sendRequest(sock, "data\n") || waitReply(sock) != 3)
+ return;
+
+ doSendBody(sock, fp, from, to, subject);
+
+ if(sendRequest(sock, "\n.\n") || waitReply(sock) != 2)
+ return;
+}
+
+void sendMail() {
+ int fd, sock;
+ MailQueue mq;
+
+ if(access(NEWINDEX, R_OK | W_OK)) {
+ if(link(INDEX, NEWINDEX) || unlink(INDEX))
+ /* nothing to do */
+ return;
+ }
+
+ if((sock = connectMailServer()) < 0) {
+ fprintf(stderr, "connect server failed...\n");
+ return;
+ }
+
+ fd = open(NEWINDEX, O_RDONLY);
+ flock(fd, LOCK_EX);
+ while(read(fd, &mq, sizeof(mq)) > 0) {
+ FILE *fp;
+ char buf[256];
+
+ snprintf(buf, sizeof(buf), "%s%s", mq.sender, FROM);
+ if((fp = fopen(mq.filepath, "r"))) {
+ setproctitle("outmail: sending %s", mq.filepath);
+ doSendMail(sock, fp, buf, mq.rcpt, mq.subject);
+ fclose(fp);
+ unlink(mq.filepath);
+ } else {
+ perror(mq.filepath);
+ }
+ }
+ flock(fd, LOCK_UN);
+ close(fd);
+ unlink(NEWINDEX);
+
+ disconnectMailServer(sock);
+}
+
+void listQueue() {
+ int fd;
+
+ if((fd = open(INDEX, O_RDONLY)) >= 0) {
+ int counter = 0;
+ MailQueue mq;
+
+ flock(fd, LOCK_EX);
+ while(read(fd, &mq, sizeof(mq)) > 0) {
+ printf("%s:%s -> %s:%s\n", mq.filepath, mq.username, mq.rcpt,
+ mq.subject);
+ counter++;
+ }
+ flock(fd, LOCK_UN);
+ close(fd);
+ printf("\nTotal: %d mails in queue\n", counter);
+ } else {
+ perror(INDEX);
+ }
+}
+
+void usage() {
+ fprintf(stderr, "usage: outmail [-qh]\n");
+}
+
+void wakeup(int s) {
+}
+
+int main(int argc, char **argv, char **envp) {
+ int ch;
+
+ signal(SIGHUP, wakeup);
+ initsetproctitle(argc, argv, envp);
+
+ if(chdir(BBSHOME))
+ return 1;
+ while((ch = getopt(argc, argv, "qh")) != -1) {
+ switch(ch) {
+ case 'q':
+ listQueue();
+ return 0;
+ default:
+ usage();
+ return 0;
+ }
+ }
+ for(;;) {
+ sendMail();
+ setproctitle("outmail: sleeping");
+ sleep(60 * 3); /* send mail every 3 minute */
+ }
+ return 0;
+}