From 47f7944541ac5f62c616af85e1afe57fb0041b94 Mon Sep 17 00:00:00 2001 From: Baptiste Daroussin Date: Thu, 21 Oct 2021 15:57:50 +0200 Subject: [PATCH] mlmmj-list: use filedescriptor instead of string manipulation --- src/mlmmj-list.c | 75 +++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 39 deletions(-) diff --git a/src/mlmmj-list.c b/src/mlmmj-list.c index 767b1429..de7db548 100644 --- a/src/mlmmj-list.c +++ b/src/mlmmj-list.c @@ -32,9 +32,6 @@ #include #include "mlmmj.h" -#include "memory.h" -#include "strgen.h" -#include "log_error.h" static void print_help(const char *prg) { @@ -52,19 +49,19 @@ static void print_help(const char *prg) exit(EXIT_SUCCESS); } -int dumpcount(const char *filename, int *count) +static int +dumpcount(int fd, int *count) { - int fd; char *start, *next, *cur; struct stat st; size_t len; - if((fd = open(filename, O_RDONLY)) < 0) - return -1; + if (fd == -1) + return (-1); + + if (fstat(fd, &st) < 0) + return (-1); - if(stat(filename, &st) < 0) - return -1; - if(!S_ISREG(st.st_mode)) return -1; @@ -98,11 +95,12 @@ int dumpcount(const char *filename, int *count) int main(int argc, char **argv) { int opt, ret, count = 0, docount = 0; - char *listdir = NULL, *fileiter = NULL, *tmp; - char *subddir, *subdir, *subfile = NULL; + char *listdir = NULL; + char *subdir, *subfile = NULL; DIR *dirp; struct dirent *dp; enum subtype typesub = SUB_NORMAL; + int fd, listfd, dirfd = -1; while ((opt = getopt(argc, argv, "cdhmnosVL:")) != -1) { switch(opt) { @@ -120,14 +118,14 @@ int main(int argc, char **argv) break; case 'm': typesub = SUB_FILE; - subfile = "/control/moderators"; + subfile = "control/moderators"; break; case 'n': typesub = SUB_NOMAIL; break; case 'o': typesub = SUB_FILE; - subfile = "/control/owner"; + subfile = "control/owner"; break; case 'V': print_version(argv[0]); @@ -144,32 +142,41 @@ int main(int argc, char **argv) "%s -h for help\n", argv[0]); exit(EXIT_FAILURE); } + listfd = open(listdir, O_DIRECTORY); + if (listfd == -1) { + fprintf(stderr, "Unable to open '%s' directory\n", listdir); + exit(EXIT_FAILURE); + } switch(typesub) { default: case SUB_NORMAL: - subddir = "/subscribers.d/"; + subdir = "subscribers.d/"; break; case SUB_DIGEST: - subddir = "/digesters.d/"; + subdir = "digesters.d/"; break; case SUB_NOMAIL: - subddir = "/nomailsubs.d/"; + subdir = "nomailsubs.d/"; break; case SUB_FILE: - subddir = NULL; + subdir = NULL; break; } - - if(subddir) - subdir = concatstr(2, listdir, subddir); - else - subdir = NULL; if(subdir) { - dirp = opendir(subdir); + if ((dirfd = openat(listfd, subdir, O_DIRECTORY)) == -1) { + fprintf(stderr, "Count not open(%s/%s);\n", listdir, + subdir); + exit(EXIT_FAILURE); + } + } + + if (dirfd != -1) { + dirp = fdopendir(dirfd); if(dirp == NULL) { - fprintf(stderr, "Could not opendir(%s);\n", subdir); + fprintf(stderr, "Could not opendir(%s/%s);\n", listdir, + subdir); exit(EXIT_FAILURE); } while((dp = readdir(dirp)) != NULL) { @@ -177,23 +184,13 @@ int main(int argc, char **argv) (strcmp(dp->d_name, ".") == 0)) continue; - fileiter = concatstr(2, subdir, dp->d_name); - - if(docount) - dumpcount(fileiter, &count); - else - ret = dumpcount(fileiter, NULL); - - myfree(fileiter); + fd = openat(dirfd, dp->d_name, O_RDONLY); + dumpcount(fd, docount ? &count : NULL); } - myfree(subdir); closedir(dirp); } else { - tmp = concatstr(2, listdir, subfile); - if(docount) - dumpcount(tmp, &count); - else - dumpcount(tmp, NULL); + fd = openat(listfd, subfile, O_RDONLY); + dumpcount(fd, docount ? &count : NULL); } if(docount) -- 2.47.3