register_unformatted(txt, "moderators", "%moderators%"); /* DEPRECATED */
register_formatted(txt, "moderators",
rewind_memory_lines, get_memory_line, mls);
- register_originalmail(txt, mailfilename);
+ int fd = open(mailfilename, O_RDONLY);
+ register_originalmail(txt, fd);
+ close(fd);
queuefilename = prepstdreply(txt, list, "$listowner$", to, replyto, false);
MY_ASSERT(queuefilename);
close_text(txt);
register_unformatted(txt, "moderators", "%moderators%"); /* DEPRECATED */
register_formatted(txt, "moderators",
rewind_memory_lines, get_memory_line, mls);
- register_originalmail(txt, mailfilename);
+ int fd2 = open(mailfilename, O_RDONLY);
+ register_originalmail(txt, fd2);
+ close(fd2);
q = prepqstdreply(txt, list, "$listowner$", efromsender, NULL);
MY_ASSERT(q);
close_text(txt);
static void
send_denymail(struct mlmmj_list *list, const char *cause, const char *subcause,
char *causestr, const char *posteraddr, const char *subject,
- char *donemailname, const char *mailfile)
+ struct queuedmail *done, const char *mailfile)
{
char *fromaddr;
text *txt;
register_unformatted(txt, "posteraddr", posteraddr);
if (causestr != NULL)
register_unformatted(txt, cause, causestr);
- register_originalmail(txt, donemailname);
+ register_originalmail(txt, done->fd);
q = prepqstdreply(txt, list, "$listowner$", posteraddr, NULL);
MY_ASSERT(q);
close_text(txt);
- unlink(donemailname);
+ unlinkat(list->queuefd, done->name, 0);
unlink(mailfile);
- free(donemailname);
+ queuedmail_free(q);
free(causestr);
memset(&mh, 0, sizeof(mh));
mh.to = posteraddr;
{
int i, j, opt, noprocess = 0, moderated = 0, send = 0;
enum modreason modreason;
- int hdrfd, footfd, rawmailfd, donemailfd, omitfd;
+ int hdrfd, footfd, rawmailfd, omitfd;
int addrtocc, intocc = 0, findaddress = 0;
int maxmailsize = 0;
int notmetoo = 0;
int subonlypost = 0, modonlypost = 0, modnonsubposts = 0, foundaddr = 0;
- char *mailfile = NULL, *donemailname = NULL;
+ char *mailfile = NULL, *donemailname;
char *randomstr = NULL, *mqueuename, *omitfilename;
char *mlmmjsend, *mlmmjsub, *mlmmjunsub, *mlmmjbounce;
char *bindir, *subjectprefix, *discardname;
struct strlist *delheaders = NULL;
struct strlist allheaders;
struct strlist *listaddrs = NULL;
+ struct queuedmail *q;
struct mailhdr readhdrs[] = {
{ "From:", 0, NULL },
{ "To:", 0, NULL },
}
}
- do {
- free(donemailname);
- free(randomstr);
- randomstr = random_str();
- xasprintf(&donemailname, "%s/queue/%s", list.dir, randomstr);
-
- donemailfd = open(donemailname, O_RDWR|O_CREAT|O_EXCL,
- S_IRUSR|S_IWUSR);
-
- } while ((donemailfd < 0) && (errno == EEXIST));
-
- if(donemailfd < 0) {
- log_error(LOG_ARGS, "could not create %s", donemailname);
- free(donemailname);
+ q = queuedmail_new(&list);
+ if (q == NULL) {
+ log_error(LOG_ARGS, "could not create queued mail");
exit(EXIT_FAILURE);
}
#if 0
log_error(LOG_ARGS, "donemailname = [%s]\n", donemailname);
#endif
if((rawmailfd = open(mailfile, O_RDONLY)) < 0) {
- unlink(donemailname);
- free(donemailname);
+ unlinkat(list.queuefd, q->name, 0);
log_error(LOG_ARGS, "could not open() input mail file");
exit(EXIT_FAILURE);
}
subjectprefix = ctrlvalue(&list, "prefix");
- if(do_all_the_voodoo_here(rawmailfd, donemailfd, hdrfd, footfd,
+ if(do_all_the_voodoo_here(rawmailfd, q->fd, hdrfd, footfd,
delheaders, readhdrs,
&allheaders, subjectprefix) < 0) {
log_error(LOG_ARGS, "Error in do_all_the_voodoo_here");
free(delheaders->strs);
close(rawmailfd);
- close(donemailfd);
+ queuedmail_free(q);
if(hdrfd >= 0)
close(hdrfd);
log_error(LOG_ARGS, "fromemails.emaillist[%d] = %s\n",
i, fromemails.emaillist[i]);
rename(mailfile, discardname);
- unlink(donemailname);
- free(donemailname);
+ unlinkat(list.queuefd, q->name, 0);
free(discardname);
free(randomstr);
/* TODO: free emailstructs */
if (!subject) subject = xstrdup("");
if(recipextra) {
+ char *donemailname;
+ xasprintf(&donemailname, "%s/queue/%s", list.dir, q->name);
xasprintf(&owner, "%s/control/owner", list.dir);
if(owner && strcmp(recipextra, "owner") == 0) {
/* Why is this here, and not in listcontrol() ?
"input mail file");
exit(EXIT_FAILURE);
}
- if((donemailfd = open(donemailname,
- O_WRONLY|O_TRUNC)) < 0) {
- log_error(LOG_ARGS, "could not open() "
- "output mail file");
- exit(EXIT_FAILURE);
- }
- if(do_all_the_voodoo_here(rawmailfd, donemailfd, -1,
+ if(do_all_the_voodoo_here(rawmailfd, q->fd, -1,
-1, delheaders,
NULL, &allheaders, NULL) < 0) {
log_error(LOG_ARGS, "do_all_the_voodoo_here");
free(delheaders->strs[i]);
free(delheaders->strs);
close(rawmailfd);
- close(donemailfd);
+ queuedmail_free(q);
unlink(mailfile);
log_oper(list.dir, OPLOGFNAME, "mlmmj-process: sending"
" mail from %s to owner",
maxmailsizestr = ctrlvalue(&list, "maxmailsize");
if(maxmailsizestr) {
maxmailsize = atol(maxmailsizestr);
- if(stat(donemailname, &st) < 0) {
- log_error(LOG_ARGS, "stat(%s,..) failed", donemailname);
+ if(fstat(q->fd, &st) < 0) {
+ log_error(LOG_ARGS, "stat(%s/queue/%s,..) failed",
+ list.dir, q->name);
exit(EXIT_FAILURE);
}
if (statctrl(&list, "nomaxmailsizedenymails")) {
errno = 0;
- log_error(LOG_ARGS, "Discarding %s due to"
+ log_error(LOG_ARGS, "Discarding %s/queue/%s due to"
" size limit (%d bytes too big)",
- donemailname, (st.st_size - maxmailsize));
- unlink(donemailname);
+ list.dir, q->name, (st.st_size - maxmailsize));
+ unlinkat(list.queuefd, q->name, 0);
unlink(mailfile);
- free(donemailname);
free(maxmailsizestr);
exit(EXIT_SUCCESS);
}
send_denymail(&list, "maxmailsize", "maxmailsize",
- maxmailsizestr, posteraddr, subject, donemailname, mailfile);
+ maxmailsizestr, posteraddr, subject, q, mailfile);
}
}
log_error(LOG_ARGS, "Discarding %s due to missing envelope"
" from address", mailfile);
rename(mailfile, discardname);
- unlink(donemailname);
- free(donemailname);
+ unlinkat(list.queuefd, q->name, 0);
+ queuedmail_free(q);
free(discardname);
free(randomstr);
/* TODO: free emailstructs */
" and From: was the list or"
" notoccdenymails was set",
mailfile);
- unlink(donemailname);
- free(donemailname);
+ unlinkat(list.queuefd, q->name, 0);
+ queuedmail_free(q);
exit(EXIT_SUCCESS);
}
send_denymail(&list, "tocc", "notintocc", NULL,
- posteraddr, subject, donemailname, mailfile);
+ posteraddr, subject, q, mailfile);
}
access_rules = ctrlvalues(&list, "access");
" address or noaccessdenymails"
" was set",
mailfile);
- unlink(donemailname);
- free(donemailname);
+ unlinkat(list.queuefd, q->name, 0);
+ queuedmail_free(q);
exit(EXIT_SUCCESS);
}
send_denymail(&list, "access", "access",
- NULL, posteraddr, subject, donemailname, mailfile);
+ NULL, posteraddr, subject, q, mailfile);
} else if (accret == MODERATE) {
moderated = 1;
modreason = ACCESS;
} else if (accret == DISCARD) {
- xasprintf(&discardname, "%s/queue/discarded/%s",
- list.dir, randomstr);
+ xasprintf(&discardname, "/discarded/%s", randomstr);
free(randomstr);
- if(rename(donemailname, discardname) < 0) {
+ if(renameat(list.queuefd, q->name,
+ list.queuefd, discardname) < 0) {
log_error(LOG_ARGS, "could not rename(%s,%s)",
- donemailname, discardname);
- free(donemailname);
+ q->name, discardname);
+ queuedmail_free(q);
free(discardname);
exit(EXIT_FAILURE);
}
- free(donemailname);
+ queuedmail_free(q);
free(discardname);
exit(EXIT_SUCCESS);
} else if (accret == SEND) {
" there are sender restrictions but"
" From: was the list address",
mailfile);
- unlink(donemailname);
- free(donemailname);
+ unlinkat(list.queuefd, q->name, 0);
+ queuedmail_free(q);
exit(EXIT_SUCCESS);
}
if(subonlypost) {
log_error(LOG_ARGS, "Discarding %s because"
" no{sub|mod}onlydenymails was set",
mailfile);
- unlink(donemailname);
- free(donemailname);
+ unlinkat(list.queuefd, q->name, 0);
+ queuedmail_free(q);
exit(EXIT_SUCCESS);
}
if (subonlypost) {
send_denymail(&list, "subonlypost",
- "subonlypost", NULL, posteraddr, subject, donemailname,
+ "subonlypost", NULL, posteraddr, subject, q,
mailfile);
} else if (modonlypost) {
send_denymail(&list, "modonlypost",
- NULL, NULL, posteraddr, subject, donemailname,
+ NULL, NULL, posteraddr, subject, q,
mailfile);
}
}
notmetoo = statctrl(&list, "notmetoo");
if(moderated) {
- xasprintf(&mqueuename, "%s/moderation/%s", list.dir, randomstr);
+ xasprintf(&mqueuename, "moderation/%s", randomstr);
free(randomstr);
- if(rename(donemailname, mqueuename) < 0) {
+ if(renameat(list.queuefd, q->name, list.fd, mqueuename) < 0) {
log_error(LOG_ARGS, "could not rename(%s,%s)",
- donemailname, mqueuename);
- free(donemailname);
+ q->name, mqueuename);
+ queuedmail_free(q);
free(mqueuename);
exit(EXIT_FAILURE);
}
- free(donemailname);
+ queuedmail_free(q);
if (notmetoo) {
xasprintf(&omitfilename, "%s.omit", mqueuename);
- omitfd = open(omitfilename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
+ omitfd = openat(list.fd, omitfilename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
if (omitfd < 0) {
log_error(LOG_ARGS, "could not open %s",
- omitfilename);
+ omitfilename);
free(mqueuename);
free(omitfilename);
exit(EXIT_FAILURE);
free(randomstr);
if(noprocess) {
- free(donemailname);
+ queuedmail_free(q);
/* XXX: toemails and ccemails etc. have to be free() */
exit(EXIT_SUCCESS);
}
- if (notmetoo)
+ xasprintf(&donemailname, "%s/queue/%s", list.dir, q->name);
+
+ if (notmetoo) {
execlp(mlmmjsend, mlmmjsend,
"-L", list.dir,
"-o", posteraddr,
"-m", donemailname, (char *)NULL);
- else
+ } else {
execlp(mlmmjsend, mlmmjsend,
"-L", list.dir,
"-m", donemailname, (char *)NULL);
+ }
log_error(LOG_ARGS, "execlp() of '%s' failed", mlmmjsend);
return EXIT_FAILURE;
int send_digest(struct mlmmj_list *list, int firstindex, int lastindex,
int issue, const char *addr, const char *mlmmjsend)
{
- int i, fd, archivefd, status, hdrfd, r;
+ int i, archivefd, status, hdrfd, r;
size_t len;
text * txt;
char buf[100];
- char *tmp, *queuename = NULL, *archivename, *subject = NULL, *line = NULL;
+ char *tmp, *archivename, *subject = NULL, *line = NULL;
char *boundary;
pid_t childpid, pid;
thread_list_state * tls;
+ struct queuedmail *q;
if (addr) {
errno = 0;
if (firstindex > lastindex)
return -1;
-
- do {
- tmp = random_str();
- free(queuename);
- xasprintf(&queuename, "queue/%s", tmp);
- free(tmp);
- fd = openat(list->fd, queuename, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR);
- } while ((fd < 0) && (errno == EEXIST));
- if (fd < 0) {
- log_error(LOG_ARGS, "Could not open digest queue file '%s'",
- queuename);
- free(queuename);
+ q = queuedmail_new(list);
+ if (q == NULL) {
+ log_error(LOG_ARGS, "Could not open digest queue file");
return -1;
}
free(tmp);
}
- r = dprintf(fd, "From: %s%shelp@%s"
+ r = dprintf(q->fd, "From: %s%shelp@%s"
"\nMIME-Version: 1.0"
"\nContent-Type: multipart/" DIGESTMIMETYPE "; "
"boundary=%s"
if (r < 0)
goto errdighdrs;
- if(hdrfd >= 0 && dumpfd2fd(hdrfd, fd) < 0) {
+ if(hdrfd >= 0 && dumpfd2fd(hdrfd, q->fd) < 0) {
goto errdighdrs;
}
close(hdrfd);
hdrfd = -1;
- if (dprintf(fd, "\n") < 0) {
+ if (dprintf(q->fd, "\n") < 0) {
errdighdrs:
- log_error(LOG_ARGS, "Could not write digest headers to '%s'",
- queuename);
- close(fd);
- unlink(queuename);
+ log_error(LOG_ARGS, "Could not write digest headers to "
+ "'%s/queue%s'", list->dir, q->name);
+ unlinkat(list->queuefd, q->name, 0);
+ queuedmail_free(q);
free(boundary);
- free(queuename);
if (txt != NULL) {
close_text(txt);
free(line);
if ((txt != NULL) && !statctrl(list, "nodigesttext")) {
- if (dprintf(fd, "\n--%s"
+ if (dprintf(q->fd, "\n--%s"
"\nContent-Type: text/plain; charset=UTF-8"
"\nContent-Transfer-Encoding: 8bit"
"\n\n", boundary) == -1) {
log_error(LOG_ARGS, "Could not write digest text/plain"
- " part headers to '%s'", queuename);
- close(fd);
- unlink(queuename);
+ " part headers to '%s/queue/%s'",
+ list->dir, q->name);
+ unlinkat(list->queuefd, q->name, 0);
+ queuedmail_free(q);
free(boundary);
- free(queuename);
if (txt != NULL) {
close_text(txt);
free(line);
if (line == NULL) break;
len = strlen(line);
line[len] = '\n';
- if(dprintf(fd, "%s", line) < 0) {
+ if(dprintf(q->fd, "%s", line) < 0) {
free(line);
log_error(LOG_ARGS, "Could not write"
" std mail");
if (archivefd < 0)
continue;
- if (dprintf(fd, "\n--%s"
+ if (dprintf(q->fd, "\n--%s"
"\nContent-Type: message/rfc822"
"\nContent-Disposition: inline; filename=\"%s_%d.eml\"",
boundary, list->name, i) == -1) {
log_error(LOG_ARGS, "Could not write digest part "
"headers for archive index %d to "
- "'%s'", i, queuename);
- close(fd);
+ "'%s/%s'", i, list->dir, q->name);
+ unlinkat(list->queuefd, q->name, 0);
+ queuedmail_free(q);
close(archivefd);
- unlink(queuename);
free(boundary);
- free(queuename);
return -1;
}
- if (dumpfd2fd(archivefd, fd) < 0) {
+ if (dumpfd2fd(archivefd, q->fd) < 0) {
log_error(LOG_ARGS, "Could not write digest part %d "
- "to '%s'", i,
- queuename);
- close(fd);
+ "to '%s/queue/%s'", i, list->dir,
+ q->name);
+ unlinkat(list->queuefd, q->name, 0);
+ queuedmail_free(q);
close(archivefd);
- unlink(queuename);
free(boundary);
- free(queuename);
return -1;
}
close(archivefd);
}
- if (dprintf(fd, "\n--%s--\n", boundary) == -1) {
- log_error(LOG_ARGS, "Could not write digest end to '%s'",
- queuename);
- close(fd);
- unlink(queuename);
+ if (dprintf(q->fd, "\n--%s--\n", boundary) == -1) {
+ log_error(LOG_ARGS, "Could not write digest end to '%s/queue/%s'",
+ list->dir, q->name);
+ unlinkat(list->queuefd, q->name, 0);
+ queuedmail_free(q);
free(boundary);
- free(queuename);
return -1;
}
- close(fd);
+ char *queuename;
+ xasprintf(&queuename, "%s/queue/%s", list->dir, q->name);
+ queuedmail_free(q);
free(boundary);
childpid = fork();