]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
cleanup: rewrite index file handling
authorBaptiste Daroussin <bapt@FreeBSD.org>
Tue, 2 Nov 2021 13:28:18 +0000 (14:28 +0100)
committerBaptiste Daroussin <bapt@FreeBSD.org>
Wed, 3 Nov 2021 13:10:28 +0000 (14:10 +0100)
Use openat to avoid memory manipulation
Use a safe strtoim function to convert from int

include/incindexfile.h
include/utils.h [new file with mode: 0644]
src/Makefile.am
src/incindexfile.c
src/mlmmj-send.c
src/utils.c [new file with mode: 0644]

index 1d28a4846b51fc6ddf768b2fa0982501a6c463e4..797b0152befdab941617390382fae2e2f3d4c907 100644 (file)
@@ -24,6 +24,8 @@
 #ifndef INCINDEXFILE_H
 #define INCINDEXFILE_H
 
-int incindexfile(const char *listdir);
+#include "mlmmj.h"
+
+int incindexfile(struct mlmmj_list *list);
 
 #endif /* INCINDEXFILE_H */
diff --git a/include/utils.h b/include/utils.h
new file mode 100644 (file)
index 0000000..6daf019
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2021 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
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef MLMMJ_UTILS_H
+#define MLMMJ_UTILS_H
+
+intmax_t strtoim(const char *, intmax_t, intmax_t, const char **);
+
+#endif
index 9b187f030294f853c91a4e97154c31c8a43444d0..38ad22b87bababf88a32636a0b063c8b9540964d 100644 (file)
@@ -12,7 +12,7 @@ bin_SCRIPTS = mlmmj-make-ml
 EXTRA_DIST = mlmmj-make-ml
 
 mlmmj_send_SOURCES = mlmmj.c mlmmj-send.c  mail-functions.c itoa.c chomp.c \
-                     incindexfile.c checkwait_smtpreply.c  \
+                     incindexfile.c checkwait_smtpreply.c  utils.c \
                     mylocking.c init_sockfd.c strgen.c random-int.c \
                     print-version.c log_error.c mygetline.c memory.c \
                     controls.c getaddrsfromfd.c readn.c \
@@ -23,7 +23,7 @@ mlmmj_receive_SOURCES = mlmmj-receive.c  random-int.c strgen.c \
                        log_oper.c mylocking.c readn.c
 
 mlmmj_process_SOURCES = mlmmj.c mlmmj-process.c  find_email_adr.c \
-                       incindexfile.c itoa.c  chomp.c \
+                       incindexfile.c itoa.c  chomp.c utils.c \
                        mylocking.c listcontrol.c random-int.c strgen.c \
                        print-version.c send_help.c prepstdreply.c \
                        do_all_the_voodoo_here.c mygetline.c gethdrline.c \
index b439460cfe7f11836327f4d1af01e46353fd12b8..855c34b623f6eb84a5151739515c6fa6447f750b 100644 (file)
@@ -1,6 +1,6 @@
-/* Copyright (C) 2002, 2003 Mads Martin Joergensen <mmj at mmj.dk>
- *
- * $Id$
+/*
+ * Copyright (C) 2002, 2003 Mads Martin Joergensen <mmj at mmj.dk>
+ * Copyright (C) 2021 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
  * IN THE SOFTWARE.
  */
 
+#include <sys/limits.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include "log_error.h"
 #include "strgen.h"
 #include "memory.h"
+#include "utils.h"
 
-#define INTBUF_SIZE 32
-
-int incindexfile(const char *listdir)
+int incindexfile(struct mlmmj_list *list)
 {
-       int fd, lock;
-       long int index = 0;
-       char intbuf[INTBUF_SIZE] = "uninitialized";
-       size_t i;
-       char *indexfilename;
-
-       indexfilename = concatstr(2, listdir, "/index");
-       fd = open(indexfilename, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
+       int fd;
+       int index = 0;
+       FILE *fp;
+       char *line = NULL;
+       size_t linecap = 0;
+       const char *errstr;
 
+       fd = openat(list->fd, "index", O_RDWR|O_CREAT|O_EXLOCK|O_CLOEXEC, S_IRUSR|S_IWUSR);
        if(fd == -1) {
-               myfree(indexfilename);
                log_error(LOG_ARGS, "Error opening index file");
                return 0;
        }
 
-       lock = myexcllock(fd);
-       
-       if(lock) {
-               myfree(indexfilename);
-               log_error(LOG_ARGS, "Error locking index file");
+       fp = fdopen(fd, "r");
+       if (fp == NULL) {
+               log_error(LOG_ARGS, "Error fdopening index file");
                close(fd);
                return 0;
        }
 
-       readn(fd, intbuf, INTBUF_SIZE);
-       for(i=0; i<sizeof(intbuf); i++) {
-               if(intbuf[i] < '0' || intbuf[i] > '9') {
-                       intbuf[i] = '\0';
-                       break;
-               }
+       index = 0;
+       if (getline(&line, &linecap, fp) > 0) {
+               /* eliminate everything which is not a number */
+               line[strspn(line, "0123456789")] = '\0';
+               index = strtoim(line, 0, INT_MAX, &errstr);
+               myfree(line);
+               if (errstr != NULL)
+                       log_error(LOG_ARGS, "Error reading index file: invalid line: %s", line);
        }
-       index = atol(intbuf);
        index++;
-       itoa(index, intbuf);
        lseek(fd, 0, SEEK_SET);
-       dprintf(fd, "%s", intbuf);
-
-       close(fd); /* Lock is also released */
-       myfree(indexfilename);
+       fprintf(fp, "%d\n", index);
+       fclose(fp); /* Lock is also released */
 
-       return index;
+       return (index);
 }
index f43a918449d0802835dda200104e43e7681015e4..83c6724f5d6f975395bd4313c8c859044c3f1e7d 100644 (file)
@@ -1048,7 +1048,7 @@ int main(int argc, char **argv)
 
        /* initialize the archive filename */
        if(archive) {
-               mindex = incindexfile(list.dir);
+               mindex = incindexfile(&list);
                len = strlen(list.dir) + 9 + 20;
                archivefilename = mymalloc(len);
                snprintf(archivefilename, len, "%s/archive/%d", list.dir,
diff --git a/src/utils.c b/src/utils.c
new file mode 100644 (file)
index 0000000..02cdc15
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2021 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
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <errno.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdlib.h>
+
+intmax_t
+strtoim(const char *np, intmax_t minval, intmax_t maxval, const char **errpp)
+{
+       char *endp;
+       intmax_t ret;
+
+       *errpp = NULL;
+       if (minval > maxval) {
+               errno = EINVAL;
+               *errpp = "invalid";
+               return (0);
+       }
+       errno = 0;
+       ret = strtoimax(np, &endp, 10);
+       if (endp == np || *endp != '\0') {
+               errno = EINVAL;
+               *errpp = "invalid";
+               return (0);
+       }
+       if (ret < minval) {
+               errno = ERANGE;
+               *errpp = "too small";
+               return (0);
+       }
+       if (errno == ERANGE || ret > maxval) {
+               errno = ERANGE;
+               *errpp = "too large";
+               return (0);
+       }
+       return (ret);
+}