]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
statctrl: use file descriptors instead of manipulating memory
authorBaptiste Daroussin <bapt@FreeBSD.org>
Thu, 28 Oct 2021 08:16:54 +0000 (10:16 +0200)
committerBaptiste Daroussin <bapt@FreeBSD.org>
Thu, 28 Oct 2021 08:19:12 +0000 (10:19 +0200)
include/statctrl.h
src/listcontrol.c
src/mlmmj-maintd.c
src/mlmmj-process.c
src/mlmmj-send.c
src/mlmmj-sub.c
src/mlmmj-unsub.c
src/prepstdreply.c
src/send_digest.c
src/statctrl.c

index b48f234791334023df3f5936f8899ab7a4aa4697..fcaf40027239ee0c601509e9b0a148bd527109ce 100644 (file)
@@ -24,6 +24,8 @@
 #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 */
index 8134d0d73253980febc8297a772e3ac2bbc97086..ff34ae0255ed3e04acac495f829cbb6d555bb6c1 100644 (file)
@@ -1,4 +1,5 @@
 /* Copyright (C) 2003 Mads Martin Joergensen <mmj at mmj.dk>
+ * Copyright (C) 2021 Baptiste Daroussin <bapt@FreeBSD.org>
  *
  * $Id$
  *
@@ -132,12 +133,12 @@ int listcontrol(struct email_container *fromemails, struct mlmmj_list *list,
        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);
@@ -217,7 +218,7 @@ int listcontrol(struct email_container *fromemails, struct mlmmj_list *list,
                                " 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");
@@ -265,7 +266,7 @@ int listcontrol(struct email_container *fromemails, struct mlmmj_list *list,
                                " 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");
@@ -313,7 +314,7 @@ int listcontrol(struct email_container *fromemails, struct mlmmj_list *list,
                                " 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");
@@ -831,14 +832,14 @@ permit:
 
        /* 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) {
@@ -880,7 +881,7 @@ permit:
 
        /* 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");
index f741b929cbbe130ff6fe4129c3ef4531513be80c..16dca9f4aa1b005dd1456060206690d1e8d706e9 100644 (file)
@@ -828,7 +828,7 @@ int run_digests(struct mlmmj_list *list, const char *mlmmjsend)
        int fd, indexfd, lock;
        size_t lenbuf, lenstr;
 
-       if (statctrl(list->dir, "noarchive")) {
+       if (statctrl(list, "noarchive")) {
                return 0;
        }
        
index a874e17eb36e9171164b1336dc489372ab6db891..88797a178fceecc0cf523d5b432fd92560f08e19 100644 (file)
@@ -141,7 +141,7 @@ static void newmoderated(struct mlmmj_list *list, const char *mailfilename,
        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))
@@ -178,7 +178,7 @@ static void newmoderated(struct mlmmj_list *list, const char *mailfilename,
 
        /* 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();
@@ -672,7 +672,7 @@ int main(int argc, char **argv)
                findaddress = 1;
        }
 
-       addrtocc = !(statctrl(list.dir, "tocc"));
+       addrtocc = !(statctrl(&list, "tocc"));
 
        if(addrtocc || findaddress) {
                listaddrs = ctrlvalues(list.dir, "listaddress");
@@ -840,7 +840,7 @@ int main(int argc, char **argv)
 
                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)",
@@ -882,7 +882,7 @@ int main(int argc, char **argv)
                 * 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"
@@ -905,7 +905,7 @@ int main(int argc, char **argv)
                                        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"
@@ -942,9 +942,9 @@ int main(int argc, char **argv)
                }
        }
 
-       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;
 
@@ -975,9 +975,9 @@ int main(int argc, char **argv)
                                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);
@@ -999,13 +999,13 @@ int main(int argc, char **argv)
        }
 
        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/",
index 617ad4865a950f7026ca9ffd5591ca8868e1995b..c34c751f8ffddd4ce18d3e1352d08a46942c6172 100644 (file)
@@ -925,7 +925,7 @@ int main(int argc, char **argv)
 
        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");
@@ -972,7 +972,7 @@ int main(int argc, char **argv)
        }
 
        memmailsizestr = ctrlvalue(list.dir, "memorymailsize");
-       ctrlarchive = statctrl(list.dir, "noarchive");
+       ctrlarchive = statctrl(&list, "noarchive");
        if(memmailsizestr) {
                memmailsize = strtol(memmailsizestr, NULL, 10);
                myfree(memmailsizestr);
@@ -1029,7 +1029,7 @@ int main(int argc, char **argv)
                }
                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':",
@@ -1046,7 +1046,7 @@ int main(int argc, char **argv)
                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;
        }
 
index 0e2b03c6caac83d728105a125f82d294278b9bd8..67e381f9344b7dbb2cd0c72a8507e7c28adeac25 100644 (file)
@@ -158,7 +158,7 @@ static void moderate_sub(struct mlmmj_list *list, const char *subaddr,
        
        /* we might need to exec more than one mlmmj-send */
        
-       nosubmodmails = statctrl(list->dir,"nosubmodmails");
+       nosubmodmails = statctrl(list,"nosubmodmails");
        
        if (nosubmodmails)
                childpid = -1;
@@ -793,7 +793,7 @@ int main(int argc, char **argv)
                        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);
        }
@@ -834,7 +834,7 @@ int main(int argc, char **argv)
        }
 
        notifysub = !quiet && reasonsub != SUB_SWITCH &&
-                       statctrl(list.dir, "notifysub");
+                       statctrl(&list, "notifysub");
 
        /* Notify list owner about subscription */
        if (notifysub)
index 7841d1779e159a7a4c33b880dbea2eaff083d2f8..33cb17825ba89a9196725ce3ee33aabee6a542e8 100644 (file)
@@ -685,7 +685,7 @@ int main(int argc, char **argv)
                                        typesub, reasonsub);
        }
 
-        notifysub = !quiet && statctrl(list.dir, "notifysub");
+        notifysub = !quiet && statctrl(&list, "notifysub");
 
         /* Notify list owner about subscription */
         if (notifysub)
index c0e4e6b7b5d7b9f689737f1defb6a6a712392267..15f09a226842ef70b859c74c8d9079e39d86419c 100644 (file)
@@ -760,7 +760,7 @@ static int handle_conditional(text *txt, char **line_p, char **pos_p,
                                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)) {
index c941d0abd8981e6e904080205e78d593c8918302..8e52161d07db2127a67c1b05ed2b7bae0338d7b7 100644 (file)
@@ -401,7 +401,7 @@ errdighdrs:
                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"
index c07625e4f9895c9e9016431b5c5907790bd8e9d9..b6f578db24597814483e19e6a1d66161880206ad 100644 (file)
@@ -1,4 +1,5 @@
 /* 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);
        }