diff options
author | Stef Walter <stef@memberwebs.com> | 2005-08-25 19:06:47 +0000 |
---|---|---|
committer | Stef Walter <stef@memberwebs.com> | 2005-08-25 19:06:47 +0000 |
commit | a861a0200b526ec48a0eebc9abaededa04b72318 (patch) | |
tree | a023a6b182febf07b87f552c4056240ac6ee754c /common/compat.c | |
parent | 9d2890bf108060d61081c2dc34962bd55978decc (diff) |
Support embedded nulls in email data.
Diffstat (limited to 'common/compat.c')
-rw-r--r-- | common/compat.c | 71 |
1 files changed, 71 insertions, 0 deletions
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> |