1.4.0-a2
o Fix a crash with forged probe emails
o mlmmj-send does not need anymore absolute path
+ o Use copy_file_range if available
+ o Use arc4random_uniform if available
1.4.0-a1
o Add a test suite
o Modernize code (dprintf, posix_spawn, asprintf, getline, daemon, ...)
AC_FUNC_MALLOC
AC_CHECK_FUNCS([ftruncate memset socket strerror strncasecmp snprintf fcntl])
AC_CHECK_FUNCS([nanosleep time strftime syslog regcomp regexec])
-AC_CHECK_FUNCS([arc4random_uniform])
+AC_CHECK_FUNCS([arc4random_uniform copy_file_range])
PKG_CHECK_MODULES([ATF], [atf-c])
AC_CONFIG_FILES([Makefile])
-/* Copyright (C) 2004 Mads Martin Joergensen <mmj at mmj dot dk>
- *
- * $Id$
+/*
+ * Copyright (C) 2004 Mads Martin Joergensen <mmj at mmj dot dk>
+ * Copyright (C) 2023 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 <sys/types.h>
-#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
+#include <stdbool.h>
-#include "wrappers.h"
+#include "config.h"
#define DUMPBUF 4096
-int dumpfd2fd(int infd, int outfd)
+static int
+_copy_file(int from, int to)
{
- size_t n;
char buf[DUMPBUF];
+ ssize_t r, wresid, w = 0;
+ char *bufp;
+ r = read(from, buf, DUMPBUF);
+ if (r < 0)
+ return (r);
+ for (bufp = buf, wresid = r; ; bufp += w, wresid -= w) {
+ w = write(to, bufp, wresid);
+ if (w <= 0)
+ break;
+ if (w >= (ssize_t) wresid)
+ break;
+ }
+ return (w < 0 ? w : r);
+}
+
+int dumpfd2fd(int from, int to)
+{
+#ifdef HAVE_COPY_FILE_RANGE2
+ bool cfr = true;
+#endif
+ int r;
- while((n = read(infd, &buf, sizeof(buf))) != 0) {
- if(n < 0) {
- if(errno == EINTR)
- continue;
- else
- return -1; /* Caller can check errno */
+ do {
+#ifdef HAVE_COPY_FILE_RANGE2
+ if (cfr) {
+ r = copy_file_range(from, NULL, to, NULL, SSIZE_MAX, 0);
+ if (r < 0 && errno == EINVAL) {
+ printf("la\n");
+ /* probably a non seekable FD */
+ cfr = false;
+ }
}
- if(writen(outfd, &buf, n) < 0)
- return -1; /* Caller can check errno */
- }
-
- return 0;
+ if (!cfr) {
+#endif
+ r = _copy_file(from, to);
+#ifdef HAVE_COPY_FILE_RANGE2
+ }
+#endif
+ } while (r > 0);
+
+ return (r);
}
* IN THE SOFTWARE.
*/
+#include <sys/fcntl.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
ATF_TC_WITHOUT_HEAD(statctrl);
ATF_TC_WITHOUT_HEAD(is_subbed_in);
ATF_TC_WITHOUT_HEAD(getaddrsfromfile);
+ATF_TC_WITHOUT_HEAD(dumpfd2fd);
#ifndef NELEM
#define NELEM(array) (sizeof(array) / sizeof((array)[0]))
fclose(fp);
}
+ATF_TC_BODY(dumpfd2fd, tc)
+{
+ FILE *plop = fopen("from", "w");
+ fprintf(plop, "bla\n");
+ fclose(plop);
+
+ int from = open("from", O_RDONLY);
+ int to = open("to.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644);
+
+ ATF_REQUIRE_EQ_MSG(dumpfd2fd(from, to), 0, "Invalid simple copy");
+ close(from);
+ close(to);
+
+ if (!atf_utils_compare_file("to.txt", "bla\n")) {
+ atf_utils_cat_file("to.txt", "");
+ atf_tc_fail("Unexpected output");
+ }
+
+ /* non seekable */
+ int shm = shm_open("/tmp/myshm", O_RDWR | O_CREAT, 0644);
+ ftruncate(shm, strlen("bla\n"));
+ dprintf(shm, "bla\n");
+ from = shm_open("/tmp/myshm", O_RDONLY, 0644);
+ to = open("tobla.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644);
+ int ret = dumpfd2fd(from, to);
+ ATF_REQUIRE_EQ_MSG(ret, 0, "Invalid simple copy %d", ret);
+ if (!atf_utils_compare_file("tobla.txt", "bla\n")) {
+ atf_utils_cat_file("tobla.txt", ">>");
+ atf_tc_fail("Unexpected output");
+ }
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, random_int);
ATF_TP_ADD_TC(tp, statctrl);
ATF_TP_ADD_TC(tp, is_subbed_in);
ATF_TP_ADD_TC(tp, getaddrsfromfile);
+ ATF_TP_ADD_TC(tp, dumpfd2fd);
return (atf_no_error());
}