From: Baptiste Daroussin Date: Tue, 4 Jan 2022 22:03:37 +0000 (+0100) Subject: mlmmj-maintd: reduce memory manipulation X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=56589e4673dd4baf5b167ed2c06f30bd60a04bea;p=thirdparty%2Fmlmmj.git mlmmj-maintd: reduce memory manipulation --- diff --git a/src/mlmmj-maintd.c b/src/mlmmj-maintd.c index 1c68933f..a41b69a9 100644 --- a/src/mlmmj-maintd.c +++ b/src/mlmmj-maintd.c @@ -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);