summaryrefslogtreecommitdiff
path: root/common/compat.c
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 /common/compat.c
parent0bdb946715088c6d66f936ed05d18a51d86f16e9 (diff)
Support embedded nulls in email data.
Diffstat (limited to 'common/compat.c')
-rw-r--r--common/compat.c71
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>