From b0ec2ddc833a2026d4e23c600c00624725bceb4f Mon Sep 17 00:00:00 2001
From: Pablo Rincon <pablo.rincon.crespo@gmail.com>
Date: Wed, 20 Jan 2010 18:25:03 +0100
Subject: [PATCH] fmemopen wrapper added (fix compilation problems on macosx and freebsd)

---
 src/Makefile.am                  |    1 +
 src/util-classification-config.c |   13 ++--
 src/util-fmemopen.c              |  127 ++++++++++++++++++++++++++++++++++++++
 src/util-fmemopen.h              |   30 +++++++++
 4 files changed, 165 insertions(+), 6 deletions(-)
 create mode 100644 src/util-fmemopen.c
 create mode 100644 src/util-fmemopen.h

diff --git a/src/Makefile.am b/src/Makefile.am
index ad4daa5..0b64d56 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -71,6 +71,7 @@ detect-sid.c detect-sid.h \
 detect-priority.c detect-priority.h \
 detect-rev.c detect-rev.h \
 detect-classtype.c detect-classtype.h \
+util-fmemopen.c util-fmemopen.h \
 detect-reference.c detect-reference.h \
 detect-tag.c detect-tag.h \
 detect-threshold.c detect-threshold.h \
diff --git a/src/util-classification-config.c b/src/util-classification-config.c
index 48c5e22..37b99c1 100644
--- a/src/util-classification-config.c
+++ b/src/util-classification-config.c
@@ -12,6 +12,7 @@
 #include "util-unittest.h"
 #include "util-error.h"
 #include "util-debug.h"
+#include "util-fmemopen.h"
 
 /* Regex to parse the classtype argument from a Signature.  The first substring
  * holds the classtype name, the second substring holds the classtype the
@@ -471,9 +472,9 @@ void SCClassConfGenerateValidDummyClassConfigFD01(void)
         "config classification: unknown,Unknown are we,3\n"
         "config classification: bad-unknown,We think it's bad, 2\n";
 
-    fd = fmemopen((void *)buffer, strlen(buffer), "r");
+    fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
     if (fd == NULL)
-        SCLogDebug("Error with fmemopen() called by Classifiation Config test code");
+        SCLogDebug("Error with SCFmemopen() called by Classifiation Config test code");
 
     return;
 }
@@ -495,9 +496,9 @@ void SCClassConfGenerateInValidDummyClassConfigFD02(void)
         "config classification: policy-violation,Potential Corporate "
         "config classification: bamboola,Unknown Traffic,3\n";
 
-    fd = fmemopen((void *)buffer, strlen(buffer), "r");
+    fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
     if (fd == NULL)
-        SCLogDebug("Error with fmemopen() called by Classifiation Config test code");
+        SCLogDebug("Error with SCFmemopen() called by Classifiation Config test code");
 
     return;
 }
@@ -516,9 +517,9 @@ void SCClassConfGenerateInValidDummyClassConfigFD03(void)
         "config classification: _badunknown,Potentially Bad Traffic, 2\n"
         "config classification: misc-activity,Misc activity,-1\n";
 
-    fd = fmemopen((void *)buffer, strlen(buffer), "r");
+    fd = SCFmemopen((void *)buffer, strlen(buffer), "r");
     if (fd == NULL)
-        SCLogDebug("Error with fmemopen() called by Classifiation Config test code");
+        SCLogDebug("Error with SCFmemopen() called by Classifiation Config test code");
 
     return;
 }
diff --git a/src/util-fmemopen.c b/src/util-fmemopen.c
new file mode 100644
index 0000000..a1b08e1
--- /dev/null
+++ b/src/util-fmemopen.c
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2009 Open Information Security Foundation
+ *
+ * \author Pablo Rincon Crespo <pablo.rincon.crespo@gmail.com>
+ *         Based on FMem.c of Alexandre Flori (2008/10/17 AF)
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util-fmemopen.h"
+
+#ifdef OS_DARWIN
+#define USE_FMEM_WRAPPER 1
+#endif
+
+#ifdef OS_FREEBSD
+#define USE_FMEM_WRAPPER 1
+#endif
+
+#ifdef USE_FMEM_WRAPPER
+
+/**
+ * \brief Seek the mem file from offset and whence
+ * \param handler pointer to the memfile
+ * \param osffset number of bytes to move from whence
+ * \param whence SEEK_SET, SEEK_CUR, SEEK_END
+ * \retval pos the position by the last operation, -1 if sizes are out of bounds
+ */
+static fpos_t SeekFn(void *handler, fpos_t offset, int whence) {
+    size_t pos = 0;
+    fmem_t *mem = handler;
+
+    switch (whence) {
+        case SEEK_SET:
+            if (offset > 0 && (size_t)offset <= mem->size)
+                return mem->pos = offset;
+        break;
+        case SEEK_CUR:
+            if (mem->pos + offset <= mem->size)
+                return mem->pos = offset;
+        break;
+        case SEEK_END:
+            /* must be negative */
+            if (mem->size + offset <= mem->size)
+                return pos = mem->size + offset;
+        break;
+    }
+
+    return -1;
+}
+
+/**
+ * \brief Read from the buffer looking for the available memory limits
+ * \param handler pointer to the memfile
+ * \param buf buffer to read from the handler
+ * \param number of bytes to read
+ * \retval count , the number of bytes read
+ */
+static int ReadFn(void *handler, char *buf, int size) {
+    size_t count = 0;
+    fmem_t *mem = handler;
+    size_t available = mem->size - mem->pos;
+
+    if (size < 0) return - 1;
+
+    if ((size_t)size > available)
+        size = available;
+
+    while (count < (size_t)size)
+        buf[count++] = mem->buffer[mem->pos++];
+
+    return count;
+}
+
+/**
+ * \brief Write into the buffer looking for the available memory limits
+ * \param handler pointer to the memfile
+ * \param buf buffer to write in the handler
+ * \param number of bytes to write
+ * \retval count , the number of bytes writen
+ */
+static int WriteFn(void *handler, const char *buf, int size) {
+    size_t count = 0;
+    fmem_t *mem = handler;
+    size_t available = mem->size - mem->pos;
+
+    if (size < 0) return - 1;
+
+    if ((size_t)size > available)
+        size = available;
+
+    while (count < (size_t)size)
+        mem->buffer[mem->pos++] = buf[count++];
+
+    return count;
+}
+
+/**
+ * \brief close the mem file handler
+ * \param handler pointer to the memfile
+ * \retval 0 on succesful
+ */
+static int CloseFn(void *handler) {
+    free (handler);
+    return 0;
+}
+
+/**
+ * \brief portable version of SCFmemopen for OS X / BSD built on top of funopen()
+ * \param buffer that holds the file content
+ * \param size of the file buffer
+ * \param mode mode of the file to open
+ * \retval pointer to the file; NULL if something is wrong
+ */
+FILE *SCFmemopen(void *buf, size_t size, const char *mode) {
+    fmem_t *mem = (fmem_t *) malloc(sizeof(fmem_t));
+
+    memset(mem, 0, sizeof(fmem_t));
+    mem->size = size, mem->buffer = buf;
+
+    return funopen(mem, ReadFn, WriteFn, SeekFn, CloseFn);
+}
+
+#endif
diff --git a/src/util-fmemopen.h b/src/util-fmemopen.h
new file mode 100644
index 0000000..06533a1
--- /dev/null
+++ b/src/util-fmemopen.h
@@ -0,0 +1,30 @@
+#ifndef __FMEMOPEN_H__
+#define __FMEMOPEN_H__
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Include this file only for OSX / BSD compilations */
+#ifdef OS_DARWIN
+#define USE_FMEM_WRAPPER 1
+#endif
+
+#ifdef OS_FREEBSD
+#define USE_FMEM_WRAPPER 1
+#endif
+
+#ifdef USE_FMEM_WRAPPER
+struct fmem {
+    size_t pos;
+    size_t size;
+    char *buffer;
+};
+typedef struct fmem fmem_t;
+
+FILE *SCFmemopen(void *, size_t, const char *);
+#else
+/* Else use the normal fmemopen */
+#define SCFmemopen fmemopen
+#endif
+
+#endif /* __FMEMOPEN_H__ */
-- 
1.6.5

