From 7e70c57aa9767c3130fa0a85e77cd0a67df22180 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Thu, 25 Aug 2005 19:06:47 +0000 Subject: Support embedded nulls in email data. --- ChangeLog | 3 +++ common/compat.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ common/compat.h | 8 +++++++ common/smtppass.c | 18 ++++++++++---- configure.in | 5 ++-- 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 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 #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 */ +#define _GNU_SOURCE + #include #include #include @@ -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 . 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 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 -- cgit v1.2.3