]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
unsubscribe: move the code for reusability
authorBaptiste Daroussin <bapt@FreeBSD.org>
Wed, 8 Dec 2021 09:19:28 +0000 (10:19 +0100)
committerBaptiste Daroussin <bapt@FreeBSD.org>
Wed, 8 Dec 2021 09:19:28 +0000 (10:19 +0100)
include/subscriberfuncs.h
src/mlmmj-unsub.c
src/subscriberfuncs.c

index fc63576ca31963f11c88211b7a40655b3a919712..6e7e49394b53b81705189d1066c44bcdce7bb7b4 100644 (file)
@@ -33,5 +33,6 @@ enum subtype is_subbed(struct mlmmj_list *list, const char *address, int both);
 int open_subscriber_directory(struct mlmmj_list *list, enum subtype typesub, const char **subdir);
 void change_uid(struct mlmmj_list *list);
 char *lowercase(const char *address);
+void unsubscribe(struct mlmmj_list *list, const char *address, enum subtype typesub, enum subreason reasonsub);
 
 #endif /* SUBSCRIBERFUNC_H */
index e6e6a013c12109c43610aa99c12e7b1861518b96..48827056750a5d6f3e4ad46a7534f70036d610ca 100644 (file)
@@ -217,46 +217,6 @@ static void generate_unsubconfirm(struct mlmmj_list *list, const char *subaddr,
        exit(EXIT_FAILURE);
 }
 
-static ssize_t unsubscribe(int subreadfd, int subwritefd, const char *address)
-{
-       off_t suboff = find_subscriber(subreadfd, address);
-       struct stat st;
-       char *inmap;
-       size_t len = strlen(address) + 1; /* + 1 for the '\n' */
-       ssize_t writeres = 0, written = 0;
-       
-       if(suboff == -1)
-               return -1; /* Did not find subscriber */
-
-       if(fstat(subreadfd, &st) < 0) {
-               log_error(LOG_ARGS, "Could not stat subreadfd");
-               return -1;
-       }
-
-       if((inmap = mmap(0, st.st_size, PROT_READ, MAP_SHARED,
-                      subreadfd, 0)) == MAP_FAILED) {
-               log_error(LOG_ARGS, "Could not mmap subreadfd");
-               return -1;
-       }
-
-       if(suboff > 0) {
-               writeres = dprintf(subwritefd, "%.*s", (int)suboff, inmap);
-               if(writeres < 0)
-                       return -1;
-       }
-       written += writeres;
-       
-       writeres = dprintf(subwritefd, "%.*s", (int)(st.st_size - len - suboff),
-                       inmap + len + suboff);
-       if(writeres < 0)
-               return -1;
-
-       written += writeres;
-
-       munmap(inmap, st.st_size);
-
-       return written;
-}
 
 static void print_help(const char *prg)
 {
@@ -308,112 +268,6 @@ static void generate_notsubscribed(struct mlmmj_list *list, const char *subaddr,
        exit(EXIT_FAILURE);
 }
 
-static void unsubscribe_type(struct mlmmj_list *list,
-               char *address,
-               enum subtype typesub, enum subreason reasonsub) {
-       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;
-
-       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 = fdopendir(subdirfd)) == NULL) {
-               log_error(LOG_ARGS, "Could not opendir(%s/%s)",
-                   list->dir, subdir);
-               exit(EXIT_FAILURE);
-       }
-
-       while((dp = readdir(subddir)) != NULL) {
-               if(!strcmp(dp->d_name, "."))
-                       continue;
-               if(!strcmp(dp->d_name, ".."))
-                       continue;
-
-               subread = openat(subdirfd, dp->d_name, O_RDWR|O_EXLOCK);
-               if(subread == -1)
-                       continue;
-
-               suboff = find_subscriber(subread, address);
-               if(suboff == -1) {
-                       close(subread);
-                       continue;
-               }
-
-               /* create a .name.lock file and aquire the lock */
-               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/%s/%s",
-                           list->dir, subdir, sublockname);
-                       myfree(sublockname);
-                       continue;
-               }
-
-               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/%s/%s'",
-                           list->dir, subdir, subwritename);
-                       close(subread);
-                       close(sublockfd);
-                       myfree(subwritename);
-                       myfree(sublockname);
-                       continue;
-               }
-
-               unsubres = unsubscribe(subread, subwrite, address);
-               if(unsubres < 0) {
-                       close(subread);
-                       close(subwrite);
-                       close(sublockfd);
-                       unlink(subwritename);
-                       myfree(subwritename);
-                       myfree(sublockname);
-                       continue;
-               }
-
-               if(unsubres > 0) {
-                       if(renameat(subdirfd, subwritename, subdirfd, dp->d_name) < 0) {
-                               log_error(LOG_ARGS,
-                                       "Could not rename '%s' to '%s'",
-                                       subwritename, dp->d_name);
-                               close(subread);
-                               close(subwrite);
-                               myfree(subwritename);
-                               continue;
-                       }
-               } else { /* unsubres == 0, no subscribers left */
-                       unlinkat(subdirfd, subwritename, 0);
-               }
-
-               close(subread);
-               close(subwrite);
-               close(sublockfd);
-               myfree(subwritename);
-               unlinkat(subdirfd, sublockname, 0);
-               myfree(sublockname);
-
-        }
-
-       closedir(subddir);
-}
-
 int main(int argc, char **argv)
 {
        int opt;
@@ -543,11 +397,11 @@ int main(int argc, char **argv)
                generate_unsubconfirm(&list, address, typesub, reasonsub);
 
        if (typesub == SUB_ALL) {
-               unsubscribe_type(&list, address, SUB_NORMAL, reasonsub);
-               unsubscribe_type(&list, address, SUB_DIGEST, reasonsub);
-               unsubscribe_type(&list, address, SUB_NOMAIL, reasonsub);
+               unsubscribe(&list, address, SUB_NORMAL, reasonsub);
+               unsubscribe(&list, address, SUB_DIGEST, reasonsub);
+               unsubscribe(&list, address, SUB_NOMAIL, reasonsub);
        } else {
-               unsubscribe_type(&list, address, typesub, reasonsub);
+               unsubscribe(&list, address, typesub, reasonsub);
        }
 
        if(confirmunsub) {
index 8f2709edf1f7901303a0cda80b070bbe0fa472c0..89198d95045d68663cfa95da63d242fc92ec4f65 100644 (file)
@@ -237,3 +237,151 @@ lowercase(const char *address)
        return (loweraddress);
 }
 
+static ssize_t
+real_unsubscribe(int subreadfd, int subwritefd, const char *address)
+{
+       off_t suboff = find_subscriber(subreadfd, address);
+       struct stat st;
+       char *inmap;
+       size_t len = strlen(address) + 1; /* + 1 for the '\n' */
+       ssize_t writeres = 0, written = 0;
+       
+       if(suboff == -1)
+               return -1; /* Did not find subscriber */
+
+       if(fstat(subreadfd, &st) < 0) {
+               log_error(LOG_ARGS, "Could not stat subreadfd");
+               return -1;
+       }
+
+       if((inmap = mmap(0, st.st_size, PROT_READ, MAP_SHARED,
+                      subreadfd, 0)) == MAP_FAILED) {
+               log_error(LOG_ARGS, "Could not mmap subreadfd");
+               return -1;
+       }
+
+       if(suboff > 0) {
+               writeres = dprintf(subwritefd, "%.*s", (int)suboff, inmap);
+               if(writeres < 0)
+                       return -1;
+       }
+       written += writeres;
+       
+       writeres = dprintf(subwritefd, "%.*s", (int)(st.st_size - len - suboff),
+                       inmap + len + suboff);
+       if(writeres < 0)
+               return -1;
+
+       written += writeres;
+
+       munmap(inmap, st.st_size);
+
+       return written;
+}
+void
+unsubscribe(struct mlmmj_list *list, const char *address, enum subtype typesub,
+    enum subreason reasonsub)
+{
+
+       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;
+
+       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 = fdopendir(subdirfd)) == NULL) {
+               log_error(LOG_ARGS, "Could not opendir(%s/%s)",
+                   list->dir, subdir);
+               exit(EXIT_FAILURE);
+       }
+
+       while((dp = readdir(subddir)) != NULL) {
+               if(!strcmp(dp->d_name, "."))
+                       continue;
+               if(!strcmp(dp->d_name, ".."))
+                       continue;
+
+               subread = openat(subdirfd, dp->d_name, O_RDWR|O_EXLOCK);
+               if(subread == -1)
+                       continue;
+
+               suboff = find_subscriber(subread, address);
+               if(suboff == -1) {
+                       close(subread);
+                       continue;
+               }
+
+               /* create a .name.lock file and aquire the lock */
+               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/%s/%s",
+                           list->dir, subdir, sublockname);
+                       myfree(sublockname);
+                       continue;
+               }
+
+               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/%s/%s'",
+                           list->dir, subdir, subwritename);
+                       close(subread);
+                       close(sublockfd);
+                       myfree(subwritename);
+                       myfree(sublockname);
+                       continue;
+               }
+
+               unsubres = real_unsubscribe(subread, subwrite, address);
+               if(unsubres < 0) {
+                       close(subread);
+                       close(subwrite);
+                       close(sublockfd);
+                       unlink(subwritename);
+                       myfree(subwritename);
+                       myfree(sublockname);
+                       continue;
+               }
+
+               if(unsubres > 0) {
+                       if(renameat(subdirfd, subwritename, subdirfd, dp->d_name) < 0) {
+                               log_error(LOG_ARGS,
+                                       "Could not rename '%s' to '%s'",
+                                       subwritename, dp->d_name);
+                               close(subread);
+                               close(subwrite);
+                               myfree(subwritename);
+                               continue;
+                       }
+               } else { /* unsubres == 0, no subscribers left */
+                       unlinkat(subdirfd, subwritename, 0);
+               }
+
+               close(subread);
+               close(subwrite);
+               close(sublockfd);
+               myfree(subwritename);
+               unlinkat(subdirfd, sublockname, 0);
+               myfree(sublockname);
+
+        }
+
+       closedir(subddir);
+}