#define PREPSTDREPLY_H
#include <stdbool.h>
+#include <stdio.h>
#include "mlmmj.h"
struct text;
rewind_function rew, get_function get, void * state);
char *get_processed_text_line(text *txt, bool headers, struct ml *ml);
bool prepstdreply_to(text *txt, struct ml *ml,
- const char *from, const char *to, const char *replyto, int tofd, const char *messageid);
+ const char *from, const char *to, const char *replyto, FILE *tof, const char *messageid);
char *prepstdreply(text *txt, struct ml *ml,
const char *from, const char *to, const char *replyto);
void close_text(text *txt);
#pragma once
+#include <stdio.h>
+
#include "mlmmj.h"
void send_list(struct ml *ml, const char *emailaddr) __dead2;
void rewind_subs_list(void *state);
const char *get_sub(void *state);
void finish_subs_list(struct subs_list_state *s);
-void print_subs(int fd, struct subs_list_state *s);
+void print_subs(FILE *f, struct subs_list_state *s);
#ifndef WRAPPERS_H
#define WRAPPERS_H
+#include <stdio.h>
#include <sys/types.h>
ssize_t readn(int fd, void *vptr, size_t n);
int random_int(void);
int dumpfd2fd(int infd, int outfd);
int copy_file(int infd, int outfd, size_t bufsiz);
-int process_headers_fd(int infd, int outfd,const char *from);
+int process_headers(int infd, FILE *outf, const char *from);
#endif /* WRAPPERS_H */
if(!hdrsadded &&
( strncasecmp(hdrline, "mime", 4) == 0)) {
if(hdrfd >= 0) {
- fflush(outf);
- if(process_headers_fd(hdrfd,outfd,posteraddr ? posteraddr : "") < 0) {
+ if(process_headers(hdrfd,outf,posteraddr ? posteraddr : "") < 0) {
log_error(LOG_ARGS, "Could not "
"add extra headers");
free(unfolded);
if(!hdrsadded ) {
if(hdrfd >= 0) {
- fflush(outf);
- if(process_headers_fd(hdrfd,outfd,posteraddr ? posteraddr : "") < 0) {
+ if(process_headers(hdrfd,outf,posteraddr ? posteraddr : "") < 0) {
log_error(LOG_ARGS, "Could not "
"add extra headers");
tll_free_and_free(allunfoldeds, free);
return (r);
}
-int process_headers_fd(int infd, int outfd, const char *from)
+int process_headers(int infd, FILE *outf, const char *from)
{
char *line = NULL, *p, *to_be_subst, *new_line;
size_t linecap = 0;
- int r, dupfd;
+ int dupfd;
FILE *f;
dupfd = dup(infd);
*to_be_subst = '\0';
to_be_subst += 12;
xasprintf(&new_line, "%s%s%s", p, from, to_be_subst);
- if ((r = dprintf(outfd, "%s", new_line)) < 0) {
+ if (fprintf(outf, "%s", new_line) < 0) {
log_error(LOG_ARGS, "Could not write headers");
free(new_line);
free(line);
fclose(f);
- return r;
+ return -1;
}
free(new_line);
} else {
- if ((r = dprintf(outfd, "%s", p)) < 0) {
+ if (fprintf(outf, "%s", p) < 0) {
log_error(LOG_ARGS, "Could not write headers");
free(line);
fclose(f);
- return r;
+ return -1;
}
}
}
else
ct[24] = '\0';
- va_start(ap, fmt);
- if (dprintf(fd, "%s ", ct) < 0)
- log_error(LOG_ARGS, "Could not write to %s", basename);
- if (vdprintf(fd, fmt, ap) <0)
- log_error(LOG_ARGS, "Could not write to %s", basename);
- if (dprintf(fd, "\n") < 0)
- log_error(LOG_ARGS, "Could not write to %s", basename);
- va_end(ap);
-
- close(fd);
+ {
+ FILE *f = fdopen(fd, "a");
+ if (f == NULL) {
+ close(fd);
+ return -1;
+ }
+ va_start(ap, fmt);
+ if (fprintf(f, "%s ", ct) < 0)
+ log_error(LOG_ARGS, "Could not write to %s", basename);
+ else if (vfprintf(f, fmt, ap) < 0)
+ log_error(LOG_ARGS, "Could not write to %s", basename);
+ else if (fprintf(f, "\n") < 0)
+ log_error(LOG_ARGS, "Could not write to %s", basename);
+ va_end(ap);
+ fclose(f);
+ }
return 0;
}
bool
prepstdreply_to(text *txt, struct ml *ml, const char *from, const char *to,
- const char *replyto, int tofd, const char *msgid)
+ const char *replyto, FILE *tof, const char *msgid)
{
bool ret = false;
char *tmp, *line;
size_t len;
char *headers[10] = { NULL }; /* relies on NULL to flag end */
- for (i=0; i<6; i++) {
+ for (i=0; i<6; i++) {
tmp = xstrdup("randomN");
tmp[6] = '0' + i;
char *str = random_str();
if (*line == ' ' || *line == '\t') {
/* line beginning with linear whitespace is a
continuation of previous header line */
- if(dprintf(tofd, "%s\n", line) < 0) {
+ if(fprintf(tof, "%s\n", line) < 0) {
log_error(LOG_ARGS, "Could not write std mail");
free(line);
goto freeandreturn;
xasprintf(&line, "Subject: %s", tmp);
free(tmp);
}
- if(dprintf(tofd, "%s\n", line) < 0) {
+ if(fprintf(tof, "%s\n", line) < 0) {
log_error(LOG_ARGS, "Could not write std mail");
free(line);
goto freeandreturn;
}
for (i=0; headers[i] != NULL; i++) {
- if(dprintf(tofd, "%s\n", headers[i]) < 0) {
+ if(fprintf(tof, "%s\n", headers[i]) < 0) {
log_error(LOG_ARGS, "Could not write std mail");
if (line)
free(line);
}
/* end the headers */
- if(dprintf(tofd, "\n") < 0) {
+ if(fprintf(tof, "\n") < 0) {
log_error(LOG_ARGS, "Could not write std mail");
if (line)
free(line);
line = get_processed_text_line(txt, false, ml);
}
while(line) {
- if(dprintf(tofd, "%s\n", line) < 0) {
+ if(fprintf(tof, "%s\n", line) < 0) {
log_error(LOG_ARGS, "Could not write std mail");
goto freeandreturn;
}
line = get_processed_text_line(txt, false, ml);
}
- fsync(tofd);
- close(tofd);
-
ret = true;
freeandreturn:
char *prepstdreply(text *txt, struct ml *ml, const char *from, const char *to, const char *replyto)
{
int outfd;
+ FILE *outf;
char *tmp, *retstr = NULL;
outfd = open(retstr, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
} while ((outfd < 0) && (errno == EEXIST));
-
+
if(outfd < 0) {
log_error(LOG_ARGS, "Could not open std mail %s", retstr);
free(retstr);
close_text(txt);
return NULL;
}
- if (!prepstdreply_to(txt, ml, from, to, replyto, outfd, NULL)) {
+ outf = fdopen(outfd, "w");
+ if (outf == NULL) {
close(outfd);
unlink(retstr);
free(retstr);
close_text(txt);
+ return NULL;
+ }
+ if (!prepstdreply_to(txt, ml, from, to, replyto, outf, NULL)) {
+ fclose(outf);
+ unlink(retstr);
+ free(retstr);
+ close_text(txt);
return (NULL);
}
+ fclose(outf);
return (retstr);
}
char *tmp, *queuename = NULL, *archivename, *subject = NULL, *line = NULL;
char *boundary = NULL;
thread_list_state *tls;
+ FILE *f = NULL;
if (addr) {
errno = 0;
free(tmp);
}
- if (dprintf(fd, "From: %s%shelp@%s"
+ {
+ int dupfd = dup(fd);
+ if (dupfd == -1) goto cleanup;
+ f = fdopen(dupfd, "w");
+ if (f == NULL) { close(dupfd); goto cleanup; }
+ }
+
+ if (fprintf(f, "From: %s%shelp@%s"
"\nMIME-Version: 1.0"
"\nContent-Type: multipart/" DIGESTMIMETYPE "; "
"boundary=%s"
}
if (hdrfd >= 0) {
+ fflush(f);
if (dumpfd2fd(hdrfd, fd) < 0) {
log_error(LOG_ARGS, "Could not write digest headers "
"to '%s'", queuename);
hdrfd = -1;
}
- if (dprintf(fd, "\n") < 0) {
+ if (fprintf(f, "\n") < 0) {
log_error(LOG_ARGS, "Could not write digest headers to '%s'",
queuename);
goto cleanup;
}
if (txt != NULL && !statctrl(ml->ctrlfd, "nodigesttext")) {
- if (dprintf(fd, "\n--%s"
+ if (fprintf(f, "\n--%s"
"\nContent-Type: text/plain; charset=UTF-8"
"\nContent-Transfer-Encoding: 8bit"
"\n\n", boundary) < 0) {
for (;;) {
line = get_processed_text_line(txt, false, ml);
if (line == NULL) break;
- if (dprintf(fd, "%s\n", line) < 0) {
+ if (fprintf(f, "%s\n", line) < 0) {
log_error(LOG_ARGS, "Could not write"
" std mail");
break;
if (archivefd < 0)
continue;
- if (dprintf(fd, "\n--%s"
+ if (fprintf(f, "\n--%s"
"\nContent-Type: message/rfc822"
"\nContent-Disposition: inline; filename=\"%s_%s.eml\"\n\n",
boundary, ml->name, buf) < 0) {
goto cleanup;
}
+ fflush(f);
if (dumpfd2fd(archivefd, fd) < 0) {
log_error(LOG_ARGS, "Could not write digest part %d "
"to '%s'", i, queuename);
archivefd = -1;
}
- if (dprintf(fd, "\n--%s--\n", boundary) < 0) {
+ if (fprintf(f, "\n--%s--\n", boundary) < 0) {
log_error(LOG_ARGS, "Could not write digest end to '%s'",
queuename);
goto cleanup;
}
+ fclose(f);
+ f = NULL;
close(fd);
fd = -1;
retval = 0;
cleanup:
+ if (f != NULL)
+ fclose(f);
if (fd >= 0) {
close(fd);
unlink(queuename);
}
-void print_subs(int fd, struct subs_list_state *s)
+void print_subs(FILE *f, struct subs_list_state *s)
{
const char *sub;
rewind_subs_list(s);
while ((sub = get_sub(s)) != NULL)
- dprintf(fd, "%s\n", sub);
+ fprintf(f, "%s\n", sub);
}
/* DEPRECATED */
/* Add lists manually if they weren't encountered in the list text */
if (!normalsls->used && !digestsls->used && !nomailsls->used) {
+ FILE *f;
fd = open(queuefilename, O_WRONLY|O_APPEND);
if(fd < 0) {
log_error(LOG_ARGS, "Could not open sub list mail");
exit(EXIT_FAILURE);
}
- print_subs(fd, normalsls);
- dprintf(fd, "\n-- \n");
- print_subs(fd, nomailsls);
- dprintf(fd, "\n-- \n");
- print_subs(fd, digestsls);
- dprintf(fd, "\n-- \nend of output\n");
- close(fd);
+ f = fdopen(fd, "a");
+ if(f == NULL) {
+ close(fd);
+ log_error(LOG_ARGS, "Could not fdopen sub list mail");
+ exit(EXIT_FAILURE);
+ }
+ print_subs(f, normalsls);
+ fprintf(f, "\n-- \n");
+ print_subs(f, nomailsls);
+ fprintf(f, "\n-- \n");
+ print_subs(f, digestsls);
+ fprintf(f, "\n-- \nend of output\n");
+ fclose(f);
}
finish_subs_list(normalsls);
* we write the failing address to ensure the potential good
* ones will be tried first when mlmmj-maintd sends out mails
* that have been requeued. addrcount was so far we were */
- if (addrs != NULL) {
- tll_foreach(*addrs, it) {
- dprintf(addrfd, "%s\n", it->item);
+ {
+ FILE *addrf = fdopen(addrfd, "a");
+ if (addrf == NULL) {
+ close(addrfd);
+ return (false);
}
+ if (addrs != NULL) {
+ tll_foreach(*addrs, it) {
+ fprintf(addrf, "%s\n", it->item);
+ }
+ }
+ if (addr != NULL)
+ fprintf(addrf, "%s\n", addr);
+ fclose(addrf);
}
- if (addr != NULL)
- dprintf(addrfd, "%s\n", addr);
- close(addrfd);
return (true);
}
ATF_TC_WITHOUT_HEAD(dumpfd2fd);
ATF_TC_WITHOUT_HEAD(dumpfd2fd_large);
ATF_TC_WITHOUT_HEAD(dumpfd2fd_empty);
-ATF_TC_WITHOUT_HEAD(process_headers_fd_test);
+ATF_TC_WITHOUT_HEAD(process_headers_test);
ATF_TC_WITHOUT_HEAD(copy_file);
ATF_TC_WITHOUT_HEAD(copy_file_1);
ATF_TC_WITHOUT_HEAD(copy_file_2);
ATF_REQUIRE_EQ(st.st_size, 0);
}
-ATF_TC_BODY(process_headers_fd_test, tc)
+ATF_TC_BODY(process_headers_test, tc)
{
- int infd, outfd;
+ int infd;
+ FILE *outf;
/* Simple header passthrough */
atf_utils_create_file("hdr_in", "X-Custom: value\n\n");
infd = open("hdr_in", O_RDONLY);
- outfd = open("hdr_out", O_WRONLY|O_CREAT|O_TRUNC, 0644);
- ATF_REQUIRE_EQ(process_headers_fd(infd, outfd, "sender@test"), 0);
+ outf = fopen("hdr_out", "w");
+ ATF_REQUIRE(outf != NULL);
+ ATF_REQUIRE_EQ(process_headers(infd, outf, "sender@test"), 0);
close(infd);
- close(outfd);
+ fclose(outf);
if (!atf_utils_compare_file("hdr_out", "X-Custom: value\n")) {
atf_utils_cat_file("hdr_out", ">");
atf_tc_fail("Simple header passthrough failed");
/* $posteraddr$ substitution */
atf_utils_create_file("hdr_in2", "Reply-To: $posteraddr$\n\n");
infd = open("hdr_in2", O_RDONLY);
- outfd = open("hdr_out2", O_WRONLY|O_CREAT|O_TRUNC, 0644);
- ATF_REQUIRE_EQ(process_headers_fd(infd, outfd, "bob@example.com"), 0);
+ outf = fopen("hdr_out2", "w");
+ ATF_REQUIRE(outf != NULL);
+ ATF_REQUIRE_EQ(process_headers(infd, outf, "bob@example.com"), 0);
close(infd);
- close(outfd);
+ fclose(outf);
if (!atf_utils_compare_file("hdr_out2", "Reply-To: bob@example.com\n")) {
atf_utils_cat_file("hdr_out2", ">");
atf_tc_fail("$posteraddr$ substitution failed");
atf_utils_create_file("hdr_in3",
"X-Original-From: $posteraddr$\nX-List: mylist\n\n");
infd = open("hdr_in3", O_RDONLY);
- outfd = open("hdr_out3", O_WRONLY|O_CREAT|O_TRUNC, 0644);
- ATF_REQUIRE_EQ(process_headers_fd(infd, outfd, "alice@test.org"), 0);
+ outf = fopen("hdr_out3", "w");
+ ATF_REQUIRE(outf != NULL);
+ ATF_REQUIRE_EQ(process_headers(infd, outf, "alice@test.org"), 0);
close(infd);
- close(outfd);
+ fclose(outf);
if (!atf_utils_compare_file("hdr_out3",
"X-Original-From: alice@test.org\nX-List: mylist\n")) {
atf_utils_cat_file("hdr_out3", ">");
/* Empty input */
atf_utils_create_file("hdr_in4", "");
infd = open("hdr_in4", O_RDONLY);
- outfd = open("hdr_out4", O_WRONLY|O_CREAT|O_TRUNC, 0644);
- ATF_REQUIRE_EQ(process_headers_fd(infd, outfd, "test@test"), 0);
+ outf = fopen("hdr_out4", "w");
+ ATF_REQUIRE(outf != NULL);
+ ATF_REQUIRE_EQ(process_headers(infd, outf, "test@test"), 0);
close(infd);
- close(outfd);
+ fclose(outf);
struct stat st;
ATF_REQUIRE_EQ(stat("hdr_out4", &st), 0);
ATF_REQUIRE_EQ(st.st_size, 0);
int fd = open("intext", O_RDONLY);
text *txt = open_text_fd(fd);
ATF_REQUIRE(txt != NULL);
- int tofd = open("totext", O_CREAT|O_WRONLY, 0644);
+ FILE *tof = fopen("totext", "w");
+ ATF_REQUIRE(tof != NULL);
init_ml(true);
ml_init(&ml);
ml.dir = "list";
ATF_REQUIRE(ml_open(&ml, false));
- ATF_REQUIRE(prepstdreply_to(txt, &ml, "me@fqdn.org", "to@plop.org", NULL, tofd, "Message-Id: <fake>"));
+ ATF_REQUIRE(prepstdreply_to(txt, &ml, "me@fqdn.org", "to@plop.org", NULL, tof, "Message-Id: <fake>"));
close_text(txt);
- fsync(tofd);
- close(tofd);
+ fclose(tof);
close(fd);
if (!atf_utils_compare_file("totext", "From: me@fqdn.org\n"
"To: to@plop.org\n"
int fd = open("intext", O_RDONLY);
text *txt = open_text_fd(fd);
ATF_REQUIRE(txt != NULL);
- int tofd = open("totext", O_CREAT|O_WRONLY, 0644);
+ FILE *tof = fopen("totext", "w");
+ ATF_REQUIRE(tof != NULL);
init_ml(true);
ml_init(&ml);
ml.dir = "list";
ATF_REQUIRE(ml_open(&ml, false));
register_default_unformatted(txt, &ml);
- ATF_REQUIRE(prepstdreply_to(txt, &ml, "me@fqdn.org", "to@plop.org", "bla@me.org", tofd, "Message-Id: <fake>"));
+ ATF_REQUIRE(prepstdreply_to(txt, &ml, "me@fqdn.org", "to@plop.org", "bla@me.org", tof, "Message-Id: <fake>"));
close_text(txt);
- fsync(tofd);
- close(tofd);
+ fclose(tof);
close(fd);
if (!atf_utils_compare_file("totext", "Subject: huhu\n"
"From: me@fqdn.org\n"
ATF_REQUIRE_STREQ(get_sub(s), "auser2");
ATF_REQUIRE(get_sub(s) == NULL);
finish_subs_list(NULL);
- int fd = open("output", O_WRONLY|O_CREAT, 0644);
- print_subs(fd, s);
- close(fd);
+ {
+ FILE *f = fopen("output", "w");
+ ATF_REQUIRE(f != NULL);
+ print_subs(f, s);
+ fclose(f);
+ }
if (!atf_utils_compare_file("output", "auser1\nauser2\n")) {
atf_utils_cat_file("output", "");
atf_tc_fail("Unexpected output, expected");
ATF_TP_ADD_TC(tp, dumpfd2fd);
ATF_TP_ADD_TC(tp, dumpfd2fd_large);
ATF_TP_ADD_TC(tp, dumpfd2fd_empty);
- ATF_TP_ADD_TC(tp, process_headers_fd_test);
+ ATF_TP_ADD_TC(tp, process_headers_test);
ATF_TP_ADD_TC(tp, copy_file);
ATF_TP_ADD_TC(tp, copy_file_1);
ATF_TP_ADD_TC(tp, copy_file_2);