#ifndef STATCTRL_H
#define STATCTRL_H
-int statctrl(const char *listdir, const char *ctrlstr);
+#include "mlmmj.h"
+
+int statctrl(struct mlmmj_list *list, const char *ctrlstr);
#endif /* STATCTRL_H */
/* Copyright (C) 2003 Mads Martin Joergensen <mmj at mmj.dk>
+ * Copyright (C) 2021 Baptiste Daroussin <bapt@FreeBSD.org>
*
* $Id$
*
char *queuefilename;
/* A closed list doesn't allow subscribtion and unsubscription */
- closedlist = statctrl(list->dir, "closedlist");
+ closedlist = statctrl(list, "closedlist");
/* A closed list "sub" only dissallows subscription, not unsub. */
- closedlistsub = statctrl(list->dir, "closedlistsub");
+ closedlistsub = statctrl(list, "closedlistsub");
- nosubconfirm = statctrl(list->dir, "nosubconfirm");
+ nosubconfirm = statctrl(list, "nosubconfirm");
#if 0
log_error(LOG_ARGS, "controlstr = [%s]\n", controlstr);
" Ignoring mail");
return -1;
}
- if (statctrl(list->dir, "nodigestsub")) {
+ if (statctrl(list, "nodigestsub")) {
errno = 0;
log_error(LOG_ARGS, "A subscribe-digest request was"
" denied");
" Ignoring mail");
return -1;
}
- if (statctrl(list->dir, "nonomailsub")) {
+ if (statctrl(list, "nonomailsub")) {
errno = 0;
log_error(LOG_ARGS, "A subscribe-nomail request was"
" denied");
" Ignoring mail");
return -1;
}
- if (statctrl(list->dir, "nodigestsub")) {
+ if (statctrl(list, "nodigestsub")) {
errno = 0;
log_error(LOG_ARGS, "A subscribe-both request was"
" denied");
/* listname+get-INDEX@domain.tld */
case CTRL_GET:
- noget = statctrl(list->dir, "noget");
+ noget = statctrl(list, "noget");
if(noget) {
errno = 0;
log_error(LOG_ARGS, "A get request was sent to a list"
" with the noget option set. Ignoring mail");
return -1;
}
- subonlyget = statctrl(list->dir, "subonlyget");
+ subonlyget = statctrl(list, "subonlyget");
if(subonlyget) {
if(is_subbed(list->dir, fromemails->emaillist[0], 0) ==
SUB_NONE) {
/* listname+list@domain.tld */
case CTRL_LIST:
- if(statctrl(list->dir, "nolistsubsemail"))
+ if(statctrl(list, "nolistsubsemail"))
return -1;
owner_idx = -1;
owners = ctrlvalues(list->dir, "owner");
int fd, indexfd, lock;
size_t lenbuf, lenstr;
- if (statctrl(list->dir, "noarchive")) {
+ if (statctrl(list, "noarchive")) {
return 0;
}
printf("mailfilename = [%s], mailbasename = [%s]\n", mailfilename,
mailbasename);
#endif
- if(statctrl(list->dir, "ifmodsendonlymodmoderate"))
+ if(statctrl(list, "ifmodsendonlymodmoderate"))
efromismod = efromsender;
if(!is_moderator(list->dir, efromismod, &moderators))
/* we might need to exec more than one mlmmj-send */
- notifymod = !efromismod && statctrl(list->dir,"notifymod");
+ notifymod = !efromismod && statctrl(list,"notifymod");
if (notifymod) {
childpid = fork();
findaddress = 1;
}
- addrtocc = !(statctrl(list.dir, "tocc"));
+ addrtocc = !(statctrl(&list, "tocc"));
if(addrtocc || findaddress) {
listaddrs = ctrlvalues(list.dir, "listaddress");
if(st.st_size > maxmailsize) {
- if (statctrl(list.dir, "nomaxmailsizedenymails")) {
+ if (statctrl(&list, "nomaxmailsizedenymails")) {
errno = 0;
log_error(LOG_ARGS, "Discarding %s due to"
" size limit (%d bytes too big)",
* discard and exit. Also don't in case of it being turned off
*/
if ((strcasecmp(list.addr, posteraddr) == 0) ||
- statctrl(list.dir, "notoccdenymails")) {
+ statctrl(&list, "notoccdenymails")) {
log_error(LOG_ARGS, "Discarding %s because list"
" address was not in To: or Cc:,"
" and From: was the list or"
posteraddr, list.dir);
if (accret == DENY) {
if ((strcasecmp(list.addr, posteraddr) == 0) ||
- statctrl(list.dir, "noaccessdenymails")) {
+ statctrl(&list, "noaccessdenymails")) {
log_error(LOG_ARGS, "Discarding %s because"
" it was denied by an access"
" rule, and From: was the list"
}
}
- subonlypost = statctrl(list.dir, "subonlypost");
- modonlypost = statctrl(list.dir, "modonlypost");
- modnonsubposts = statctrl(list.dir, "modnonsubposts");
+ subonlypost = statctrl(&list, "subonlypost");
+ modonlypost = statctrl(&list, "modonlypost");
+ modnonsubposts = statctrl(&list, "modnonsubposts");
/* modnonsubposts implies subonlypost if modonlypost is not set */
if (modnonsubposts && !modonlypost) subonlypost = 1;
modreason = MODNONMODPOSTS;
} else {
if((subonlypost &&
- statctrl(list.dir, "nosubonlydenymails")) ||
+ statctrl(&list, "nosubonlydenymails")) ||
(modonlypost &&
- statctrl(list.dir, "nomodonlydenymails"))) {
+ statctrl(&list, "nomodonlydenymails"))) {
log_error(LOG_ARGS, "Discarding %s because"
" no{sub|mod}onlydenymails was set",
mailfile);
}
if(!send && !moderated) {
- if(statctrl(list.dir, "moderated")) {
+ if(statctrl(&list, "moderated")) {
moderated = 1;
modreason = MODERATED;
}
}
- notmetoo = statctrl(list.dir, "notmetoo");
+ notmetoo = statctrl(&list, "notmetoo");
if(moderated) {
mqueuename = concatstr(3, list.dir, "/moderation/",
verp = ctrlvalue(list.dir, "verp");
if(verp == NULL)
- if(statctrl(list.dir, "verp") == 1)
+ if(statctrl(&list, "verp") == 1)
verp = mystrdup("");
maxverprecipsstr = ctrlvalue(list.dir, "maxverprecips");
}
memmailsizestr = ctrlvalue(list.dir, "memorymailsize");
- ctrlarchive = statctrl(list.dir, "noarchive");
+ ctrlarchive = statctrl(&list, "noarchive");
if(memmailsizestr) {
memmailsize = strtol(memmailsizestr, NULL, 10);
myfree(memmailsizestr);
}
break;
case '3':
- addtohdr = statctrl(list.dir, "addtohdr");
+ addtohdr = statctrl(&list, "addtohdr");
case '4': /* sending mails to subfile */
if((subfd = open(subfilename, O_RDONLY)) < 0) {
log_error(LOG_ARGS, "Could not open '%s':",
bounceaddr = bounce_from_adr(to_addr, archivefilename, &list);
break;
default: /* normal list mail -- now handled when forking */
- addtohdr = statctrl(list.dir, "addtohdr");
+ addtohdr = statctrl(&list, "addtohdr");
break;
}
/* we might need to exec more than one mlmmj-send */
- nosubmodmails = statctrl(list->dir,"nosubmodmails");
+ nosubmodmails = statctrl(list,"nosubmodmails");
if (nosubmodmails)
childpid = -1;
address, mlmmjsend, typesub, reasonsub);
if(modstr == NULL && subbed == SUB_NONE && !force &&
- statctrl(list.dir, "submod")) {
+ statctrl(&list, "submod")) {
moderate_sub(&list,
address, mlmmjsend, typesub, reasonsub);
}
}
notifysub = !quiet && reasonsub != SUB_SWITCH &&
- statctrl(list.dir, "notifysub");
+ statctrl(&list, "notifysub");
/* Notify list owner about subscription */
if (notifysub)
typesub, reasonsub);
}
- notifysub = !quiet && statctrl(list.dir, "notifysub");
+ notifysub = !quiet && statctrl(&list, "notifysub");
/* Notify list owner about subscription */
if (notifysub)
if (strcasecmp(token, txt->type) == 0)
matches = 1;
} else if (tgt == CONTROL) {
- if (statctrl(list->dir, token))
+ if (statctrl(list, token))
matches = 1;
}
if ((matches && !neg) || (!matches && neg)) {
return -1;
}
- if ((txt != NULL) && !statctrl(list->dir, "nodigesttext")) {
+ if ((txt != NULL) && !statctrl(list, "nodigesttext")) {
tmp = concatstr(3, "\n--", boundary,
"\nContent-Type: text/plain; charset=UTF-8"
/* Copyright (C) 2004 Mads Martin Joergensen <mmj at mmj.dk>
+ * Copyright (C) 2021 Baptiste Daroussin <bapt@FreeBSD.org>
*
* $Id$
*
#include <stdlib.h>
#include <errno.h>
+#include <err.h>
#include <string.h>
#include <unistd.h>
+#include <fcntl.h>
-#include "strgen.h"
+#include "mlmmj.h"
#include "statctrl.h"
#include "log_error.h"
-int statctrl(const char *listdir, const char *ctrlstr)
+int statctrl(struct mlmmj_list *list, const char *ctrlstr)
{
- char *filename = concatstr(3, listdir, "/control/", ctrlstr);
-
- if (access(filename, F_OK) == -1) {
+ if (list->controlfd == -1)
+ list->controlfd = openat(list->fd, "control", O_DIRECTORY|O_CLOEXEC);
+ if (list->controlfd == -1) {
+ log_error(LOG_ARGS, "Unable to open %s/control", list->dir);
+ errx(EXIT_FAILURE, "Unable to open %s/control", list->dir);
+ }
+
+ if (faccessat(list->controlfd, ctrlstr, F_OK, 0) == -1) {
if(errno == ENOENT)
return 0;
log_error(LOG_ARGS, "Could not stat %s/control/%s. "
- "Bailing out.", listdir, ctrlstr);
+ "Bailing out.", list->dir, ctrlstr);
exit(EXIT_FAILURE);
}