From: Baptiste Daroussin Date: Thu, 28 Oct 2021 11:53:27 +0000 (+0200) Subject: mlmmj-unsub: convert to use filedescriptors X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a6a7fc03d78d203e6b9b4f218d482176e08ee188;p=thirdparty%2Fmlmmj.git mlmmj-unsub: convert to use filedescriptors While here, use O_EXLOCK to obtain the lock --- diff --git a/src/mlmmj-unsub.c b/src/mlmmj-unsub.c index 33cb1782..8f35f7d7 100644 --- a/src/mlmmj-unsub.c +++ b/src/mlmmj-unsub.c @@ -155,7 +155,7 @@ static void generate_unsubconfirm(struct mlmmj_list *list, const char *subaddr, confirmfilename = concatstr(3, list->dir, "/unsubconf/", randomstr); - subconffd = open(confirmfilename, O_RDWR|O_CREAT|O_EXCL, + subconffd = open(confirmfilename, O_RDWR|O_CREAT|O_EXLOCK, S_IRUSR|S_IWUSR); } while ((subconffd < 0) && (errno == EEXIST)); @@ -320,123 +320,67 @@ static void generate_notsubscribed(struct mlmmj_list *list, const char *subaddr, static void unsubscribe_type(struct mlmmj_list *list, char *address, char *mlmmjsend, enum subtype typesub, enum subreason reasonsub) { - char *subdir, *subddirname, *sublockname; - char *subreadname = NULL, *subwritename; - int subread, subwrite, rlock, wlock; - int sublock, sublockfd; + const char *subdir; + char *sublockname; + char *subwritename; + int subread, subwrite, sublockfd; int groupwritable = 0; int unsubres; struct stat st; DIR *subddir; struct dirent *dp; off_t suboff; + int subdirfd; - switch(typesub) { - default: - case SUB_NORMAL: - subdir = "/subscribers.d/"; - break; - case SUB_DIGEST: - subdir = "/digesters.d/"; - break; - case SUB_NOMAIL: - subdir = "/nomailsubs.d/"; - break; - } - - subddirname = concatstr(2, list->dir, subdir); - if (stat(subddirname, &st) == 0) { + subdirfd = open_subscriber_directory(list, typesub, &subdir); + if (fstat(subdirfd, &st) == 0) { if(st.st_mode & S_IWGRP) { groupwritable = S_IRGRP|S_IWGRP; umask(S_IWOTH); } } - if((subddir = opendir(subddirname)) == NULL) { - log_error(LOG_ARGS, "Could not opendir(%s)", - subddirname); - myfree(subddirname); + if((subddir = fdopendir(subdirfd)) == NULL) { + log_error(LOG_ARGS, "Could not opendir(%s/%s)", + list->dir, subdir); exit(EXIT_FAILURE); } - myfree(subddirname); - while((dp = readdir(subddir)) != NULL) { if(!strcmp(dp->d_name, ".")) continue; if(!strcmp(dp->d_name, "..")) continue; - - subreadname = concatstr(3, list->dir, subdir, dp->d_name); - subread = open(subreadname, O_RDWR); - if(subread == -1) { - myfree(subreadname); + subread = openat(subdirfd, dp->d_name, O_RDWR|O_EXLOCK); + if(subread == -1) continue; - } suboff = find_subscriber(subread, address); if(suboff == -1) { close(subread); - myfree(subreadname); continue; } /* create a .name.lock file and aquire the lock */ - sublockname = concatstr(5, list->dir, subdir, ".", dp->d_name, - ".lock"); - sublockfd = open(sublockname, O_RDWR | O_CREAT, + myasprintf(&sublockname, ".%s.lock", dp->d_name); + sublockfd = open(sublockname, O_RDWR | O_CREAT | O_EXLOCK, S_IRUSR | S_IWUSR); - if(sublockfd < 0) { - log_error(LOG_ARGS, "Error opening lock file %s", - sublockname); + if (sublockfd < 0) { + log_error(LOG_ARGS, "Error opening lock file %s/%s/%s", + list->dir, subdir, sublockname); myfree(sublockname); continue; } - sublock = myexcllock(sublockfd); - if(sublock < 0) { - log_error(LOG_ARGS, "Error locking '%s' file", - sublockname); - myfree(sublockname); - close(sublockfd); - continue; - } - - rlock = myexcllock(subread); - if(rlock < 0) { - log_error(LOG_ARGS, "Error locking '%s' file", - subreadname); - close(subread); - close(sublockfd); - myfree(subreadname); - myfree(sublockname); - continue; - } - - subwritename = concatstr(2, subreadname, ".new"); - - subwrite = open(subwritename, O_RDWR | O_CREAT | O_TRUNC, + myasprintf(&subwritename, "%s.new", dp->d_name); + subwrite = openat(subdirfd, subwritename, O_RDWR | O_CREAT | O_TRUNC | O_EXLOCK, S_IRUSR | S_IWUSR | groupwritable); if(subwrite == -1){ - log_error(LOG_ARGS, "Could not open '%s'", - subwritename); - close(subread); - close(sublockfd); - myfree(subreadname); - myfree(subwritename); - myfree(sublockname); - continue; - } - - wlock = myexcllock(subwrite); - if(wlock < 0) { - log_error(LOG_ARGS, "Error locking '%s'", - subwritename); + log_error(LOG_ARGS, "Could not open '%s/%s/%s'", + list->dir, subdir, subwritename); close(subread); - close(subwrite); close(sublockfd); - myfree(subreadname); myfree(subwritename); myfree(sublockname); continue; @@ -448,34 +392,30 @@ static void unsubscribe_type(struct mlmmj_list *list, close(subwrite); close(sublockfd); unlink(subwritename); - myfree(subreadname); myfree(subwritename); myfree(sublockname); continue; } if(unsubres > 0) { - if(rename(subwritename, subreadname) < 0) { + if(renameat(subdirfd, subwritename, subdirfd, dp->d_name) < 0) { log_error(LOG_ARGS, "Could not rename '%s' to '%s'", - subwritename, subreadname); + subwritename, dp->d_name); close(subread); close(subwrite); - myfree(subreadname); myfree(subwritename); continue; } } else { /* unsubres == 0, no subscribers left */ - unlink(subwritename); - unlink(subreadname); + unlinkat(subdirfd, subwritename, 0); } close(subread); close(subwrite); close(sublockfd); - myfree(subreadname); myfree(subwritename); - unlink(sublockname); + unlinkat(subdirfd, sublockname, 0); myfree(sublockname); }