summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2005-08-25 19:06:47 +0000
committerStef Walter <stef@memberwebs.com>2005-08-25 19:06:47 +0000
commit7e70c57aa9767c3130fa0a85e77cd0a67df22180 (patch)
tree8c86a7a84784c30e5ffacd4e8fcb2197a305e4e5
parent0bdb946715088c6d66f936ed05d18a51d86f16e9 (diff)
Support embedded nulls in email data.
-rw-r--r--ChangeLog3
-rw-r--r--common/compat.c71
-rw-r--r--common/compat.h8
-rw-r--r--common/smtppass.c18
-rw-r--r--configure.in5
5 files changed, 99 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 051509d..3718ce0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+1.5.1 [???]
+ - Support embedded NULLs in email data.
+
1.5 [2005-07-31]
- Handle condition of server refusing data transfers more gracefully.
- Less chatty when setting timeouts fail
diff --git a/common/compat.c b/common/compat.c
index 23a73d0..1f1736b 100644
--- a/common/compat.c
+++ b/common/compat.c
@@ -254,6 +254,77 @@ int daemon(int nochdir, int noclose)
#endif
+#ifndef HAVE_GETLINE
+
+ssize_t getline(char** lineptr, size_t* n, FILE* stream)
+{
+ return getdelim(lineptr, n, '\n', stream);
+}
+
+#endif
+
+#ifndef HAVE_GETDELIM
+
+ssize_t getdelim(char** lineptr, size_t* n, int delim, FILE* stream)
+{
+ size_t written = 0;
+ int allocated, ch;
+ char* p;
+
+ if(!n || !lineptr || !stream)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* Track whether we allocated this or not */
+ allocated = !(*lineptr);
+
+ for(;;)
+ {
+ if(!*lineptr)
+ *n = 0;
+
+ /* Reallocate if we need more space */
+ if(written == *n - 1)
+ {
+ *n = *n ? 256 : *n * 2;
+ if(!(p = (char*)realloc(*lineptr, *n)))
+ {
+ if(allocated && *lineptr)
+ free(*lineptr);
+ errno = ENOMEM;
+ return -1;
+ }
+ *lineptr = p;
+ }
+
+ while(written < *n - 1)
+ {
+ ch = fgetc(stream);
+
+ if(ferror(stream))
+ {
+ if(allocated && *lineptr)
+ free(*lineptr);
+ return -1;
+ }
+
+ if(ch != EOF)
+ (*lineptr)[written++] = ch;
+
+ /* Done, null terminate, return */
+ if(ch == EOF || ch == delim)
+ {
+ (*lineptr)[written] = 0;
+ return written ? written : -1;
+ }
+ }
+ }
+}
+
+#endif
+
#ifndef HAVE_ERR_H
#include <stdlib.h>
diff --git a/common/compat.h b/common/compat.h
index b772f63..addf815 100644
--- a/common/compat.h
+++ b/common/compat.h
@@ -91,6 +91,14 @@ int setenv(const char* name, const char* value, int overwrite);
int daemon(int nochdir, int noclose);
#endif
+#ifndef HAVE_GETLINE
+ssize_t getline(char** lineptr, size_t* n, FILE* stream);
+#endif
+
+#ifndef HAVE_GETDELIM
+ssize_t getdelim(char** lineptr, size_t* n, int delim, FILE* stream);
+#endif
+
#ifdef HAVE_ERR_H
#include <err.h>
#else
diff --git a/common/smtppass.c b/common/smtppass.c
index 0ea9ca5..e94f95e 100644
--- a/common/smtppass.c
+++ b/common/smtppass.c
@@ -38,6 +38,8 @@
* Olivier Beyssac <ob@r14.freenix.org>
*/
+#define _GNU_SOURCE
+
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
@@ -1478,15 +1480,21 @@ int sp_done_data(spctx_t* ctx)
FILE* file = 0;
int had_header = 0;
int ret = 0;
- char line[SP_LINE_LENGTH];
+ char *line;
char header[MAX_HEADER_LENGTH];
- size_t header_len;
+ size_t header_len, line_len;
+ ssize_t rc;
ASSERT(ctx->cachename[0]); /* Must still be around */
ASSERT(!ctx->cachefile); /* File must be closed */
memset(header, 0, sizeof(header));
+ /* Alloc line buffer */
+ line_len = SP_LINE_LENGTH;
+ if((line = (char *)malloc(line_len)) == NULL)
+ RETURN(-1);
+
/* Open the file */
file = fopen(ctx->cachename, "r");
if(file == NULL)
@@ -1528,7 +1536,7 @@ int sp_done_data(spctx_t* ctx)
}
/* Transfer actual file data */
- while(fgets(line, SP_LINE_LENGTH, file) != NULL)
+ while((rc = getline(&line, &line_len, file)) != -1)
{
/*
* If the line is <CRLF>.<CRLF> we need to change it so that
@@ -1555,7 +1563,7 @@ int sp_done_data(spctx_t* ctx)
}
}
- if(spio_write_data_raw(ctx, &(ctx->server), line, strlen(line)) == -1)
+ if(spio_write_data_raw(ctx, &(ctx->server), line, rc) == -1)
RETURN(-1);
}
@@ -1580,6 +1588,8 @@ int sp_done_data(spctx_t* ctx)
cleanup:
+ if(line)
+ free(line);
if(file)
fclose(file); /* read-only so no error check */
diff --git a/configure.in b/configure.in
index 92552d8..f0d5845 100644
--- a/configure.in
+++ b/configure.in
@@ -36,8 +36,8 @@ dnl Nate Nielsen <nielsen@memberwebs.com>
dnl
dnl Process this file with autoconf to produce a configure script.
-AC_INIT(clamsmtp, 1.5, nielsen@memberwebs.com)
-AM_INIT_AUTOMAKE(clamsmtp, 1.5)
+AC_INIT(clamsmtp, 1.5.90, nielsen@memberwebs.com)
+AM_INIT_AUTOMAKE(clamsmtp, 1.5.90)
LDFLAGS="$LDFLAGS -L/usr/local/lib"
CFLAGS="$CFLAGS -I/usr/local/include"
@@ -107,6 +107,7 @@ AC_CHECK_GLOBAL(__argv)
AC_CHECK_FUNCS([memset strerror malloc realloc getopt strchr tolower getaddrinfo], ,
[echo "ERROR: Required function missing"; exit 1])
AC_CHECK_FUNCS([strlwr strlcat strlcpy strncat strncpy setenv daemon])
+AC_CHECK_FUNCS([getline getdelim])
# Have to resolve this for the path below
if test "${prefix}" = "NONE"; then