From: Baptiste Daroussin Date: Tue, 2 Nov 2021 13:28:18 +0000 (+0100) Subject: cleanup: rewrite index file handling X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=abf8fedb1ee53a5d47a30d9a0a8d86f0042b0b2e;p=thirdparty%2Fmlmmj.git cleanup: rewrite index file handling Use openat to avoid memory manipulation Use a safe strtoim function to convert from int --- diff --git a/include/incindexfile.h b/include/incindexfile.h index 1d28a484..797b0152 100644 --- a/include/incindexfile.h +++ b/include/incindexfile.h @@ -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 index 00000000..6daf0191 --- /dev/null +++ b/include/utils.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2021 Baptiste Daroussin + * + * 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 diff --git a/src/Makefile.am b/src/Makefile.am index 9b187f03..38ad22b8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/incindexfile.c b/src/incindexfile.c index b439460c..855c34b6 100644 --- a/src/incindexfile.c +++ b/src/incindexfile.c @@ -1,6 +1,6 @@ -/* Copyright (C) 2002, 2003 Mads Martin Joergensen - * - * $Id$ +/* + * Copyright (C) 2002, 2003 Mads Martin Joergensen + * Copyright (C) 2021 Baptiste Daroussin * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -21,9 +21,12 @@ * IN THE SOFTWARE. */ +#include + #include #include #include +#include #include #include #include @@ -37,50 +40,43 @@ #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 '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); } diff --git a/src/mlmmj-send.c b/src/mlmmj-send.c index f43a9184..83c6724f 100644 --- a/src/mlmmj-send.c +++ b/src/mlmmj-send.c @@ -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 index 00000000..02cdc15c --- /dev/null +++ b/src/utils.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2021 Baptiste Daroussin + * + * 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 +#include +#include +#include + +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); +}