const char *replyto, int mailfd,
const char *listdir, const char *mlmmjbounce);
int send_mail_many(int sockfd, const char *from, const char *replyto,
- int mailfd, FILE *subfile, const char *listaddr,
+ int mailfd, int subfd, const char *listaddr,
const char *archivefilename, const char *listdir,
const char *mlmmjbounce);
int initsmtp(int *sockfd, const char *relayhost);
#include "wrappers.h"
-#define DUMPBUF 1024
+#define DUMPBUF 4096
int dumpfd2fd(int infd, int outfd)
{
snprintf(mail_from, len, "MAIL FROM: <%s>\r\n", from_addr);
len = strlen(mail_from);
-#ifdef MLMMJ_DEBUG
+#if 0
fprintf(stderr, "\nwrite_mail_from, mail_from = [%s]\n", mail_from);
#endif
bytes_written = writen(sockfd, mail_from, len);
snprintf(rcpt_to, len, "RCPT TO: <%s>\r\n", rcpt_addr);
len = strlen(rcpt_to);
-#ifdef MLMMJ_DEBUG
+#if 0
fprintf(stderr, "\nwrite_rcpt_to, rcpt_to = [%s]\n", rcpt_to);
#endif
bytes_written = writen(sockfd, rcpt_to, len);
/* keep writing chunks of line (max WRITE_BUFSIZE) */
for(;;) {
bufp = buf+1;
- errno = 0; /* We must reset errno, otherwise we can't
- * determine if we hit EOF or an error
- * occurred */
- if(read(fd, bufp, WRITE_BUFSIZE) < 0) {
+
+ len = read(fd, bufp, WRITE_BUFSIZE);
+
+ if(len == 0)
+ return 0;
+
+ if(len < 0) {
if (errno == EINTR) {
- errno = 0;
continue;
} else {
return errno;
}
/* fix newlines */
- len = strlen(bufp);
if((len > 0) && (bufp[len-1] == '\n')) {
bufp[len-1] = '\r';
bufp[len] = '\n';
full_line = 0;
}
-#ifdef MLMMJ_DEBUG
+#if 0
fprintf(stderr, "write_mailbody_from_file = [%s]\n", bufp);
#endif
bytes_written = writen(sockfd, bufp, len);
#include "strgen.h"
#include "log_error.h"
#include "mygetline.h"
+#include "wrappers.h"
char *bounce_from_adr(const char *recipient, const char *listadr,
const char *mailfilename)
}
int send_mail_many(int sockfd, const char *from, const char *replyto,
- int mailfd, FILE *subfile, const char *listaddr,
+ int mailfd, int subfd, const char *listaddr,
const char *archivefilename, const char *listdir,
const char *mlmmjbounce)
{
- int sendres = 0;
+ int sendres = 0, addrfd;
char *bounceaddr, *addr, *index, *dirname, *addrfilename;
- FILE *addrfile;
+ size_t len;
- while((addr = myfgetline(subfile))) {
+ while((addr = mygetline(subfd))) {
chomp(addr);
if(from)
sendres = send_mail(sockfd, from, addr, replyto,
}
addrfilename = concatstr(2, dirname, "/subscribers");
free(dirname);
- addrfile = fopen(addrfilename, "a");
- if(addrfile == NULL) {
+ addrfd = open(addrfilename, O_WRONLY|O_CREAT|O_APPEND,
+ S_IRUSR|S_IWUSR);
+ if(addrfd < 0) {
log_error(LOG_ARGS, "Could not write to %s",
addrfilename);
free(addrfilename);
return 1;
} else { /* dump the remaining addresses */
do {
- if(fputs(addr, addrfile) < 0)
+ /* Dirty hack to add newline. */
+ len = strlen(addr);
+ addr[len] = '\n';
+ if(writen(addrfd, addr, len+1) < 0)
log_error(LOG_ARGS,
"Could not add [%s] "
"to requeue address "
"file.", addr);
- fputc('\n', addrfile);
free(addr);
- addr = myfgetline(subfile);
+ addr = mygetline(subfd);
} while(addr);
}
free(addr);
free(addrfilename);
- fclose(addrfile);
+ close(addrfd);
return 1;
}
int main(int argc, char **argv)
{
size_t len = 0;
- int sockfd = 0, mailfd = 0, opt, mindex;
+ int sockfd = 0, mailfd = 0, opt, mindex, subfd, tmpfd;
int deletewhensent = 1, sendres, archive = 1;
char *listaddr, *mailfilename = NULL, *subfilename = NULL;
char *replyto = NULL, *bounceaddr = NULL, *to_addr = NULL;
char *listctrl = NULL, *subddirname = NULL, *listdir = NULL;
char *mlmmjbounce = NULL, *bindir;
DIR *subddir;
- FILE *subfile = NULL, *tmpfile;
struct dirent *dp;
log_set_name(argv[0]);
break;
case '2': /* Moderators */
subfilename = concatstr(2, listdir, "/moderators");
- if((subfile = fopen(subfilename, "r")) == NULL) {
+ if((subfd = open(subfilename, O_RDONLY)) < 0) {
log_error(LOG_ARGS, "Could not open '%s':",
subfilename);
free(subfilename);
}
break;
case '3': /* resending earlier failed mails */
- if((subfile = fopen(subfilename, "r")) == NULL) {
+ if((subfd = open(subfilename, O_RDONLY)) < 0) {
log_error(LOG_ARGS, "Could not open '%s':",
subfilename);
exit(EXIT_FAILURE);
deletewhensent = 0;
/* dump date we want when resending */
tmpstr = concatstr(2, mailfilename, ".mailfrom");
- tmpfile = fopen(tmpstr, "w");
+ tmpfd = open(tmpstr, O_WRONLY|O_CREAT|O_TRUNC,
+ S_IRUSR|S_IWUSR);
free(tmpstr);
- fputs(bounceaddr, tmpfile);
- fclose(tmpfile);
+ if(tmpfd >= 0) {
+ writen(tmpfd, to_addr, strlen(to_addr));
+ fsync(tmpfd);
+ }
+ close(tmpfd);
tmpstr = concatstr(2, mailfilename, ".reciptto");
- tmpfile = fopen(tmpstr, "w");
+ tmpfd = open(tmpstr, O_WRONLY|O_CREAT|O_TRUNC,
+ S_IRUSR|S_IWUSR);
free(tmpstr);
- fputs(to_addr, tmpfile);
- fclose(tmpfile);
+ if(tmpfd >= 0) {
+ writen(tmpfd, bounceaddr, strlen(bounceaddr));
+ fsync(tmpfd);
+ }
+ close(tmpfd);
if(replyto) {
tmpstr = concatstr(2, mailfilename,
".reply-to");
- tmpfile = fopen(tmpstr, "w");
+ tmpfd = open(tmpstr, O_WRONLY|O_CREAT|O_TRUNC,
+ S_IRUSR|S_IWUSR);
free(tmpstr);
- fputs(replyto, tmpfile);
- fclose(tmpfile);
+ if(tmpfd >= 0) {
+ writen(tmpfd, replyto,
+ strlen(replyto));
+ fsync(tmpfd);
+ }
+ close(tmpfd);
}
}
break;
case '2': /* Moderators */
initsmtp(&sockfd, relayhost);
- if(send_mail_many(sockfd, bounceaddr, NULL, mailfd, subfile,
+ if(send_mail_many(sockfd, bounceaddr, NULL, mailfd, subfd,
NULL, NULL, listdir, NULL))
close(sockfd);
else
break;
case '3': /* resending earlier failed mails */
initsmtp(&sockfd, relayhost);
- if(send_mail_many(sockfd, NULL, NULL, mailfd, subfile,
+ if(send_mail_many(sockfd, NULL, NULL, mailfd, subfd,
listaddr, mailfilename, listdir, mlmmjbounce))
close(sockfd);
else
continue;
subfilename = concatstr(3, listdir, "/subscribers.d/",
dp->d_name);
- if((subfile = fopen(subfilename, "r")) == NULL) {
+ if((subfd = open(subfilename, O_RDONLY)) < 0) {
log_error(LOG_ARGS, "Could not open '%s'",
subfilename);
free(subfilename);
initsmtp(&sockfd, relayhost);
sendres = send_mail_many(sockfd, NULL, NULL, mailfd,
- subfile, listaddr, archivefilename,
+ subfd, listaddr, archivefilename,
listdir, mlmmjbounce);
if (sendres) {
/* If send_mail_many() failed we close the
} else {
endsmtp(&sockfd);
}
- fclose(subfile);
+ close(subfd);
}
closedir(subddir);
break;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <strings.h>
#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include "mlmmj.h"
#include "send_help.h"
#include "find_email_adr.h"
#include "getlistaddr.h"
#include "log_error.h"
+#include "chomp.h"
+#include "wrappers.h"
+#include "mygetline.h"
void send_help(const char *listdir, const char *emailaddr,
const char *mlmmjsend)
{
- FILE *helpfile, *queuefile;
- char buf[READ_BUFSIZE];
- char *listaddr, *bufres, *helpaddr, *fromaddr, *fromstr, *tostr;
- char *subjectstr, *helpfilename, *queuefilename, *listname;
- char *randomstr, *listfqdn;
- size_t len;
+ int helpfd, queuefd;
+ char *listaddr, *buf, *fromaddr;
+ char *helpfilename, *queuefilename, *listname;
+ char *randomstr, *listfqdn, *s1;
listaddr = getlistaddr(listdir);
+ chomp(listaddr);
helpfilename = concatstr(2, listdir, "/text/listhelp");
- if((helpfile = fopen(helpfilename, "r")) == NULL) {
+ if((helpfd = open(helpfilename, O_RDONLY)) < 0) {
log_error(LOG_ARGS, "Could not open text/help");
free(helpfilename);
exit(EXIT_FAILURE);
randomstr = random_str();
queuefilename = concatstr(3, listdir, "/queue/", randomstr);
- printf("%s\n", queuefilename);
- if((queuefile = fopen(queuefilename, "w")) == NULL) {
+ queuefd = open(queuefilename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
+ if(queuefd < 0) {
log_error(LOG_ARGS, "Could not open '%s'", queuefilename);
free(queuefilename);
free(randomstr);
}
free(randomstr);
- len = strlen(listname) + strlen(listfqdn) + strlen("+help@") + 1;
- helpaddr = malloc(len);
- snprintf(helpaddr, len, "%s+help@%s", listname, listfqdn);
+ fromaddr = concatstr(3, listname, "+bounces-help@", listfqdn);
- len += strlen("+bounces");
- fromaddr = malloc(len);
- snprintf(fromaddr, len, "%s+bounces-help@%s", listname, listfqdn);
+ s1 = concatstr(11, "From: ", listname, "+owner@", listfqdn, "\n"
+ "To: ", emailaddr, "\n", "Subject: Help for ",
+ listaddr, "\n\n");
- fromstr = headerstr("From: ", helpaddr);
- fputs(fromstr, queuefile);
- free(helpaddr);
-
- tostr = headerstr("To: ", emailaddr);
- fputs(tostr, queuefile);
+ if(writen(queuefd, s1, strlen(s1)) < 0) {
+ log_error(LOG_ARGS, "Could not write help mail");
+ exit(EXIT_FAILURE);
+ }
- subjectstr = headerstr("Subject: Help for ", listaddr);
- fputs(subjectstr, queuefile);
- fputc('\n', queuefile);
+ free(s1);
- while((bufres = fgets(buf, READ_BUFSIZE, helpfile))) {
+ while((buf = mygetline(helpfd)) != NULL) {
if(strncmp(buf, "*UNSUBADDR*", 11) == 0) {
- fputs(listname, queuefile);
- fputs("+unsubscribe@", queuefile);
- fputs(listfqdn, queuefile);
- }
- else if(strncmp(buf, "*SUBADDR*", 9) == 0) {
- fputs(listname, queuefile);
- fputs("+subscribe@", queuefile);
- fputs(listfqdn, queuefile);
+ s1 = concatstr(3, listname, "+unsubscribe@", listfqdn);
+ if(writen(queuefd, s1, strlen(s1)) < 0) {
+ log_error(LOG_ARGS,
+ "Could not write help mail");
+ exit(EXIT_FAILURE);
+ }
+ free(s1);
+ } else if(strncmp(buf, "*SUBADDR*", 9) == 0) {
+ s1 = concatstr(3, listname, "+subscribe@", listfqdn);
+ if(writen(queuefd, s1, strlen(s1)) < 0) {
+ log_error(LOG_ARGS,
+ "Could not write help mail");
+ exit(EXIT_FAILURE);
+ }
+ free(s1);
+ } else if(strncmp(buf, "*HLPADDR*", 9) == 0) {
+ s1 = concatstr(3, listname, "+help@", listfqdn);
+ if(writen(queuefd, s1, strlen(s1)) < 0) {
+ log_error(LOG_ARGS,
+ "Could not write help mail");
+ exit(EXIT_FAILURE);
+ }
+ free(s1);
+ } else if(writen(queuefd, buf, strlen(buf)) < 0) {
+ log_error(LOG_ARGS,
+ "Could not write help mail");
+ exit(EXIT_FAILURE);
}
- else if(strncmp(buf, "*HLPADDR*", 9) == 0) {
- fputs(listname, queuefile);
- fputs("+help@", queuefile);
- fputs(listfqdn, queuefile);
- } else
- fputs(buf, queuefile);
+ free(buf);
}
- free(tostr);
- free(subjectstr);
free(listname);
free(listfqdn);
- fclose(helpfile);
- fclose(queuefile);
+ close(helpfd);
+ close(queuefd);
execlp(mlmmjsend, mlmmjsend,
"-l", "1",