]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
mlmmj-sub: convert subscription to file descriptor
authorBaptiste Daroussin <bapt@FreeBSD.org>
Thu, 28 Oct 2021 09:16:12 +0000 (11:16 +0200)
committerBaptiste Daroussin <bapt@FreeBSD.org>
Thu, 28 Oct 2021 09:24:12 +0000 (11:24 +0200)
While use O_EXCL for locking directly at open() time

src/mlmmj-sub.c

index 67e381f9344b7dbb2cd0c72a8507e7c28adeac25..6f6d483c79fe7c35e9a134ee14ec258b41c1cda6 100644 (file)
@@ -26,6 +26,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
+#include <err.h>
 #include <syslog.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -519,28 +520,31 @@ static void generate_subscribed(struct mlmmj_list *list, const char *subaddr,
 static void subscribe_type(struct mlmmj_list *list,
                char *address, char *mlmmjsend,
                enum subtype typesub, enum subreason reasonsub) {
-       char *subfilename = NULL;
        char chstr[2], *subdir;
-       char *subddirname = NULL, *sublockname;
-       int groupwritable = 0, sublock, sublockfd, lock, subfilefd;
+       char *sublockname = NULL;
+       int groupwritable = 0, sublockfd,  subfilefd;
        struct stat st;
        size_t len;
+       int subdirfd = -1;
 
        switch(typesub) {
                default:
                case SUB_NORMAL:
-                       subdir = "/subscribers.d/";
+                       subdir = "subscribers.d";
                        break;
                case SUB_DIGEST:
-                       subdir = "/digesters.d/";
+                       subdir = "digesters.d";
                        break;
                case SUB_NOMAIL:
-                       subdir = "/nomailsubs.d/";
+                       subdir = "nomailsubs.d";
                        break;
        }
 
-       subddirname = concatstr(2, list->dir, subdir);
-       if (stat(subddirname, &st) == 0) {
+       subdirfd = openat(list->fd, subdir, O_DIRECTORY|O_CLOEXEC);
+       if (subdirfd == -1)
+               err(EXIT_FAILURE, "Unable to open %s/%s", list->dir, subdir);
+
+       if (fstat(subdirfd, &st) == 0) {
                if(st.st_mode & S_IWGRP) {
                        groupwritable = S_IRGRP|S_IWGRP;
                        umask(S_IWOTH);
@@ -550,40 +554,26 @@ static void subscribe_type(struct mlmmj_list *list,
 
        chstr[0] = address[0];
        chstr[1] = '\0';
-       
-       subfilename = concatstr(3, list->dir, subdir, chstr);
 
-       sublockname = concatstr(5, list->dir, subdir, ".", chstr, ".lock");
-       sublockfd = open(sublockname, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
-       if(sublockfd < 0) {
-               log_error(LOG_ARGS, "Error opening lock file %s",
-                               sublockname);
-               myfree(sublockname);
-               exit(EXIT_FAILURE);
+       subfilefd = openat(subdirfd, chstr, O_RDWR|O_CREAT, S_IRUSR | S_IWUSR);
+       if (subfilefd == -1) {
+               log_error(LOG_ARGS, "Error opening %s/%s/%s", list->dir, subdir, chstr);
+               err(EXIT_FAILURE, "Error opening %s/%s/%s");
        }
 
-       sublock = myexcllock(sublockfd);
-       if(sublock < 0) {
-               log_error(LOG_ARGS, "Error locking '%s' file",
-                               sublockname);
+       myasprintf(&sublockname, ".%s.lock", chstr);
+       sublockfd = openat(subdirfd, sublockname, O_RDWR | O_CREAT | O_EXLOCK, S_IRUSR | S_IWUSR);
+       if(sublockfd < 0) {
+               log_error(LOG_ARGS, "Error opening lock file %s%s%s", list->dir,
+               subdir, sublockname);
                myfree(sublockname);
-               close(sublockfd);
                exit(EXIT_FAILURE);
        }
 
-       subfilefd = open(subfilename, O_RDWR|O_CREAT,
+       subfilefd = openat(subdirfd, chstr, O_RDWR|O_CREAT|O_EXLOCK,
                                S_IRUSR|S_IWUSR|groupwritable);
        if(subfilefd == -1) {
-               log_error(LOG_ARGS, "Could not open '%s'", subfilename);
-               myfree(sublockname);
-               exit(EXIT_FAILURE);
-       }
-
-       lock = myexcllock(subfilefd);
-       if(lock) {
-               log_error(LOG_ARGS, "Error locking subscriber file");
-               close(subfilefd);
-               close(sublockfd);
+               log_error(LOG_ARGS, "Could not open '%s/%s/%s'", list->dir, chstr);
                myfree(sublockname);
                exit(EXIT_FAILURE);
        }
@@ -595,7 +585,7 @@ static void subscribe_type(struct mlmmj_list *list,
        address[len] = 0;
        close(subfilefd);
        close(sublockfd);
-       unlink(sublockname);
+       unlinkat(subdirfd, sublockname, 0);
        myfree(sublockname);
 }