]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
Rewrite find_subscriber using getline(3) instead of mmap
authorBaptiste Daroussin <bapt@FreeBSD.org>
Wed, 28 Dec 2022 15:42:12 +0000 (16:42 +0100)
committerBaptiste Daroussin <bapt@FreeBSD.org>
Wed, 28 Dec 2022 15:44:07 +0000 (16:44 +0100)
It simplifies greatly the code

include/subscriberfuncs.h
src/subscriberfuncs.c
tests/mlmmj.c

index a81b5a69c0bf20fe284567640570609295eba543..ef7f5d0481048f8c08dc065128b4493caef5a575 100644 (file)
@@ -26,7 +26,7 @@
 
 #include <stdbool.h>
 
-off_t find_subscriber(int fd, const char *address);
+bool find_subscriber(int fd, const char *address);
 int is_subbed_in(int fd, const char *subddirname, const char *address);
 enum subtype is_subbed(int listfd, const char *address, bool both);
 
index 798960b38e9f622b1e595805fc097ed2ca2c9cd1..13a9d09bba19bbe830628b2a1bdfaecc9a8753dd 100644 (file)
@@ -1,6 +1,6 @@
-/* Copyright (C) 2003 Mads Martin Joergensen <mmj at mmj.dk>
- *
- * $Id$
+/*
+ * Copyright (C) 2003 Mads Martin Joergensen <mmj at mmj.dk>
+ * Copyright (C) 2022 Baptiste Daroussin <bapt@FreeBSD.org>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to
  */
 
 #include <stdio.h>
-#include <string.h>
-#include <ctype.h>
 #include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <unistd.h>
 #include <dirent.h>
 #include <fcntl.h>
 
 #include "mlmmj.h"
 #include "subscriberfuncs.h"
-#include "mygetline.h"
 #include "log_error.h"
-#include "wrappers.h"
+#include "chomp.h"
 
 char *subtype_strs[] = {
        "normal",
@@ -57,64 +50,35 @@ char * subreason_strs[] = {
        "switch"
 };
 
-off_t find_subscriber(int fd, const char *address)
+bool
+find_subscriber(int fd, const char *address)
 {
-       char *start, *cur, *next;
-       struct stat st;
-       size_t len;
-
-       if(fstat(fd, &st) < 0) {
-               log_error(LOG_ARGS, "Could not stat fd");
-               return (off_t)-1;
-       }
-
-       /* No need to check in 0-size file */
-       if(st.st_size == 0)
-               return (off_t)-1;
-
-       if(!S_ISREG(st.st_mode)) {
-               log_error(LOG_ARGS, "Non regular file in subscribers.d/");
-               return (off_t)-1;
-       }
-
-       if((start = mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) ==
-                       MAP_FAILED) {
-               log_error(LOG_ARGS, "Could not mmap fd");
-               return (off_t)-1;
-       }
-       
-       for(next = cur = start; next < start + st.st_size; next++) {
-               if(*next == '\n') {
-                       len = next - cur;
-                       if((strlen(address) == len) &&
-                          (strncasecmp(address, cur, len) == 0)) {
-                               munmap(start, st.st_size);
-                               return (off_t)(cur - start);
-                       }
-                       cur = next + 1;
-               }
-       }
-       
-       if(next > cur) {
-               len = next - cur;
-               if((strlen(address) == len) &&
-                  (strncasecmp(address, cur, len) == 0)) {
-                       munmap(start, st.st_size);
-                       return (off_t)(cur - start);
+       FILE *f;
+       char *line = NULL;
+       size_t linecap = 0;
+       ssize_t linelen;
+       bool ret = false;
+
+       f = fdopen(fd, "r");
+       while ((linelen = getline(&line, &linecap, f)) > 0) {
+               chomp(line);
+               if (strcasecmp(address, line) == 0) {
+                       ret = true;
+                       break;
                }
        }
-       
-       munmap(start, st.st_size);
-       return (off_t)-1;
+       free(line);
+       fclose(f);
+       return (ret);;
 }
 
 int
 is_subbed_in(int dirfd, const char *subdirname, const char *address)
 {
-       int retval = 0, subread;
-       off_t suboff;
+       int subread;
        DIR *subddir;
        struct dirent *dp;
+       bool ret = false;
 
        if((subddir = fdopendir(dirfd)) == NULL) {
                log_error(LOG_ARGS, "Could not opendir(%s)", subdirname);
@@ -134,19 +98,13 @@ is_subbed_in(int dirfd, const char *subdirname, const char *address)
                        continue;
                }
 
-               suboff = find_subscriber(subread, address);
-               close(subread);
-
-               if(suboff == -1) {
-                       continue;
-               } else {
-                       retval = 1;
+               ret = find_subscriber(subread, address);
+               if (ret)
                        break;
-               }
        }
        closedir(subddir);
 
-       return retval;
+       return ret;
 }
 
 enum subtype
index 8d4b9d57a80264a18b8ff2d40be8400cca438a89..3ffe42f15b4abd83a185ecd8ee55ae83f10832e7 100644 (file)
@@ -53,6 +53,7 @@
 #include "getlistdelim.h"
 #include "getlistaddr.h"
 #include "statctrl.h"
+#include "subscriberfuncs.h"
 
 ATF_TC_WITHOUT_HEAD(random_int);
 ATF_TC_WITHOUT_HEAD(chomp);
@@ -103,6 +104,7 @@ ATF_TC_WITHOUT_HEAD(send_mail_8);
 ATF_TC_WITHOUT_HEAD(getlistdelim);
 ATF_TC_WITHOUT_HEAD(getlistaddr);
 ATF_TC_WITHOUT_HEAD(statctrl);
+ATF_TC_WITHOUT_HEAD(is_subbed_in);
 
 #ifndef NELEM
 #define NELEM(array)    (sizeof(array) / sizeof((array)[0]))
@@ -1620,6 +1622,17 @@ ATF_TC_BODY(statctrl, tc)
        ATF_REQUIRE_EQ(statctrl(fd, "test"), true);
 }
 
+ATF_TC_BODY(is_subbed_in, tc)
+{
+       pid_t p;
+
+       p = atf_utils_fork();
+       if (p == 0) {
+               is_subbed_in(-1, "plop", "meh");
+       }
+       atf_utils_wait(p, EXIT_FAILURE, "", "");
+}
+
 ATF_TP_ADD_TCS(tp)
 {
        ATF_TP_ADD_TC(tp, random_int);
@@ -1671,6 +1684,7 @@ ATF_TP_ADD_TCS(tp)
        ATF_TP_ADD_TC(tp, getlistdelim);
        ATF_TP_ADD_TC(tp, getlistaddr);
        ATF_TP_ADD_TC(tp, statctrl);
+       ATF_TP_ADD_TC(tp, is_subbed_in);
 
        return (atf_no_error());
 }