]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
mlmmj-maintd: reduce memory manipulation
authorBaptiste Daroussin <bapt@FreeBSD.org>
Tue, 4 Jan 2022 22:03:37 +0000 (23:03 +0100)
committerBaptiste Daroussin <bapt@FreeBSD.org>
Tue, 4 Jan 2022 22:03:37 +0000 (23:03 +0100)
src/mlmmj-maintd.c

index 1c68933f47895b83c5001d83d9292c33dbbe7d4d..a41b69a9d1696df6bfaac4d46b61ed92e0382212 100644 (file)
@@ -290,22 +290,24 @@ int resend_requeue(struct mlmmj_list *list, const char *mlmmjsend)
 {
        DIR *queuedir;
        struct dirent *dp;
-       char *dirname = concatstr(2, list->dir, "/requeue/");
        char *archivefilename, *subfilename, *subnewname;
        struct stat st;
        pid_t childpid, pid;
        time_t t;
-       int status, fromrequeuedir;
+       int status, fromrequeuedir, dirfd;
 
-       if(chdir(dirname) < 0) {
-               log_error(LOG_ARGS, "Could not chdir(%s)", dirname);
-               free(dirname);
+       dirfd = openat(list->fd, "requeue", O_DIRECTORY);
+       if (dirfd == -1) {
+               log_error(LOG_ARGS, "Could not open(%s/requeue)", list->dir);
+               return 1;
+       }
+       if (fchdir(dirfd) < 0) {
+               log_error(LOG_ARGS, "Could not chdir(%s/requeue)", list->dir);
                return 1;
        }
                
-       if((queuedir = opendir(dirname)) == NULL) {
-               log_error(LOG_ARGS, "Could not opendir(%s)", dirname);
-               free(dirname);
+       if ((queuedir = fdopendir(dirfd)) == NULL) {
+               log_error(LOG_ARGS, "Could not opendir(%s/requeue)", list->dir);
                return 1;
        }
        
@@ -314,7 +316,7 @@ int resend_requeue(struct mlmmj_list *list, const char *mlmmjsend)
                        (strcmp(dp->d_name, ".") == 0))
                                continue;
 
-               if(stat(dp->d_name, &st) < 0) {
+               if(fstatat(dirfd, dp->d_name, &st, 0) < 0) {
                        log_error(LOG_ARGS, "Could not stat(%s)",dp->d_name);
                        continue;
                }
@@ -328,8 +330,8 @@ int resend_requeue(struct mlmmj_list *list, const char *mlmmjsend)
                        if(rmdir(dp->d_name) == 0)
                                continue;
 
-               archivefilename = concatstr(3, list->dir, "/archive/",
-                                               dp->d_name);
+               xasprintf(&archivefilename, "%s/archive/%s", list->dir,
+                   dp->d_name);
 
                /* Explicitly initialize for each mail we examine */
                fromrequeuedir = 0;
@@ -344,15 +346,16 @@ int resend_requeue(struct mlmmj_list *list, const char *mlmmjsend)
                        /* If the list is set not to archive we want to look
                         * in /requeue/ for a mailfile
                         */
-                       archivefilename = concatstr(4, list->dir, "/requeue/",
-                                                       dp->d_name, "/mailfile");
+                       xasprintf(&archivefilename, "%s/requeue/%s/mailfile",
+                           list->dir, dp->d_name);
                        if(stat(archivefilename, &st) < 0) {
                                free(archivefilename);
                                continue;
                        }
                        fromrequeuedir = 1;
                }
-               subfilename = concatstr(3, dirname, dp->d_name, "/subscribers");
+               xasprintf(&subfilename, "%s/requeue/%s/subscribers", list->dir,
+                   dp->d_name);
                if(stat(subfilename, &st) < 0) {
                        if (fromrequeuedir)
                                unlink(archivefilename);
@@ -361,8 +364,7 @@ int resend_requeue(struct mlmmj_list *list, const char *mlmmjsend)
                        continue;
                }
 
-               subnewname = concatstr(2, subfilename, ".resending");
-
+               xasprintf(&subnewname, "%s.resending", subfilename);
                if(rename(subfilename, subnewname) < 0) {
                        log_error(LOG_ARGS, "Could not rename(%s, %s)",
                                                subfilename, subnewname);
@@ -405,35 +407,34 @@ int resend_requeue(struct mlmmj_list *list, const char *mlmmjsend)
 
        closedir(queuedir);
 
-       free(dirname);
-
        return 0;
 }
 
 int clean_nolongerbouncing(struct mlmmj_list *list)
 {
        DIR *bouncedir;
-       char *dirname = concatstr(2, list->dir, "/bounce/");
        char *filename, *probetimestr, *s;
        int probefd;
        time_t probetime, t;
        struct dirent *dp;
        struct stat st;
        const char *errstr;
-       
-       if(chdir(dirname) < 0) {
-               log_error(LOG_ARGS, "Could not chdir(%s)", dirname);
-               free(dirname);
+       int dirfd;
+
+       dirfd = openat(list->fd, "bounce", O_DIRECTORY);
+       if (dirfd == -1) {
+               log_error(LOG_ARGS, "Could not open(%s/requeue)", list->dir);
                return 1;
        }
-               
-       if((bouncedir = opendir(dirname)) == NULL) {
-               log_error(LOG_ARGS, "Could not opendir(%s)", dirname);
-               free(dirname);
+       if (fchdir(dirfd) < 0) {
+               log_error(LOG_ARGS, "Could not chdir(%s/requeue)", list->dir);
                return 1;
        }
 
-       free(dirname);
+       if((bouncedir = fdopendir(dirfd)) == NULL) {
+               log_error(LOG_ARGS, "Could not opendir(%s/requeue)", list->dir);
+               return 1;
+       }
 
        while((dp = readdir(bouncedir)) != NULL) {
                if((strcmp(dp->d_name, "..") == 0) ||
@@ -444,14 +445,14 @@ int clean_nolongerbouncing(struct mlmmj_list *list)
 
                s = strrchr(filename, '-');
                if(s && (strcmp(s, "-probe") == 0)) {
-                       if(stat(filename, &st) < 0) {
+                       if(fstatat(dirfd, filename, &st, 0) < 0) {
                                log_error(LOG_ARGS, "Could not stat(%s)",
                                          filename);
                                free(filename);
                                continue;
                        }
 
-                       probefd = open(filename, O_RDONLY);
+                       probefd = openat(dirfd, filename, O_RDONLY);
                        if(probefd < 0) {
                                free(filename);
                                continue;
@@ -467,12 +468,12 @@ int clean_nolongerbouncing(struct mlmmj_list *list)
                        free(probetimestr);
                        t = time(NULL);
                        if(t - probetime > WAITPROBE) {
-                               unlink(filename);
+                               unlinkat(dirfd, filename, 0);
                                /* remove -probe onwards from filename */
                                *s = '\0';
-                               unlink(filename);
-                               s = concatstr(2, filename, ".lastmsg");
-                               unlink(s);
+                               unlinkat(dirfd, filename, 0);
+                               xasprintf(&s, "%s.lastmsg", filename);
+                               unlinkat(dirfd, s, 0);
                                free(s);
                        }
                }
@@ -487,26 +488,24 @@ int clean_nolongerbouncing(struct mlmmj_list *list)
 int probe_bouncers(struct mlmmj_list *list, const char *mlmmjbounce)
 {
        DIR *bouncedir;
-       char *dirname = concatstr(2, list->dir, "/bounce/");
        char *probefile, *s;
        struct dirent *dp;
        struct stat st;
        pid_t pid, childpid;
        int status;
-       
-       if(chdir(dirname) < 0) {
-               log_error(LOG_ARGS, "Could not chdir(%s)", dirname);
-               free(dirname);
+       int dirfd = openat(list->fd, "bounce", O_DIRECTORY);
+       if (dirfd == -1) {
+               log_error(LOG_ARGS, "Could not chdir(%s/bounce)", list->dir);
                return 1;
        }
-               
-       if((bouncedir = opendir(dirname)) == NULL) {
-               log_error(LOG_ARGS, "Could not opendir(%s)", dirname);
-               free(dirname);
+       if(fchdir(dirfd) < 0) {
+               log_error(LOG_ARGS, "Could not chdir(%s/bounce)", list->dir);
+               return 1;
+       }
+       if((bouncedir = fdopendir(dirfd)) == NULL) {
+               log_error(LOG_ARGS, "Could not opendir(%s/bounce)", list->dir);
                return 1;
        }
-
-       free(dirname);
 
        while((dp = readdir(bouncedir)) != NULL) {
                if((strcmp(dp->d_name, "..") == 0) ||
@@ -521,15 +520,15 @@ int probe_bouncers(struct mlmmj_list *list, const char *mlmmjbounce)
                if(s && (strcmp(s, ".lastmsg") == 0))
                        continue;
                        
-               if(stat(dp->d_name, &st) < 0) {
+               if(fstatat(dirfd, dp->d_name, &st, 0) < 0) {
                        log_error(LOG_ARGS, "Could not stat(%s)", dp->d_name);
                        continue;
                }
                
-               probefile = concatstr(2, dp->d_name, "-probe");
-               
+               xasprintf(&probefile, "%s-probe", dp->d_name);
+
                /* Skip files which already have a probe out */
-               if(stat(probefile, &st) == 0) {
+               if(fstatat(dirfd, probefile, &st, 0) == 0) {
                        free(probefile);
                        continue;
                }
@@ -566,27 +565,26 @@ int probe_bouncers(struct mlmmj_list *list, const char *mlmmjbounce)
 int unsub_bouncers(struct mlmmj_list *list)
 {
        DIR *bouncedir;
-       char *dirname = concatstr(2, list->dir, "/bounce/");
        char *probefile, *address, *a, *firstbounce, *bouncedata;
        struct dirent *dp;
        struct stat st;
        int fd;
        time_t bouncetime, t, bouncelife = 0;
        const char *errstr;
-       
-       if(chdir(dirname) < 0) {
-               log_error(LOG_ARGS, "Could not chdir(%s)", dirname);
-               free(dirname);
+
+       int dirfd = openat(list->fd, "bounce", O_DIRECTORY);
+       if (dirfd == -1) {
+               log_error(LOG_ARGS, "Could not chdir(%s/bounce)", list->dir);
                return 1;
        }
-               
-       if((bouncedir = opendir(dirname)) == NULL) {
-               log_error(LOG_ARGS, "Could not opendir(%s)", dirname);
-               free(dirname);
+       if(fchdir(dirfd) < 0) {
+               log_error(LOG_ARGS, "Could not chdir(%s/bounce)", list->dir);
+               return 1;
+       }
+       if((bouncedir = fdopendir(dirfd)) == NULL) {
+               log_error(LOG_ARGS, "Could not opendir(%s/bounce)", list->dir);
                return 1;
        }
-
-       free(dirname);
 
        bouncelife = ctrltimet(list, "bouncelife");
        if (bouncelife == 0)
@@ -605,15 +603,14 @@ int unsub_bouncers(struct mlmmj_list *list)
                if(a && (strcmp(a, ".lastmsg") == 0))
                        continue;
                
-               if(stat(dp->d_name, &st) < 0) {
+               if(fstatat(dirfd, dp->d_name, &st, 0) < 0) {
                        log_error(LOG_ARGS, "Could not stat(%s)", dp->d_name);
                        continue;
                }
-               
-               probefile = concatstr(2, dp->d_name, "-probe");
-               
+               xasprintf(&probefile, "%s-probe", dp->d_name);
+
                /* Skip files which already have a probe out */
-               if(stat(probefile, &st) == 0) {
+               if(fstatat(dirfd, probefile, &st, 0) == 0) {
                        free(probefile);
                        continue;
                }
@@ -622,7 +619,7 @@ int unsub_bouncers(struct mlmmj_list *list)
                /* Get the first line of the bounce file to check if it's
                 * been bouncing for long enough
                 */
-               fd = open(dp->d_name, O_RDONLY);
+               fd = openat(dirfd, dp->d_name, O_RDONLY);
                if(fd < 0) {
                        log_error(LOG_ARGS, "Could not open %s", dp->d_name);
                        continue;
@@ -673,9 +670,9 @@ int unsub_bouncers(struct mlmmj_list *list)
                        " %s", address, bouncedata);
                free(address);
                free(bouncedata);
-               unlink(dp->d_name);
-               a = concatstr(2, dp->d_name, ".lastmsg");
-               unlink(a);
+               unlinkat(dirfd, dp->d_name, 0);
+               xasprintf(&a, "%s.lastmsg", dp->d_name);
+               unlinkat(dirfd, a, 0);
                free(a);
        }
        closedir(bouncedir);