suricata
util-fmemopen.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2010 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Pablo Rincon Crespo <pablo.rincon.crespo@gmail.com>
22  * Based on FMem.c of Alexandre Flori (2008/10/17 AF)
23  */
24 
25 #include "suricata-common.h"
26 #include "util-fmemopen.h"
27 
28 #ifdef OS_DARWIN
29 #define USE_FMEM_WRAPPER 1
30 #endif
31 
32 #ifdef OS_FREEBSD
33 #define USE_FMEM_WRAPPER 1
34 #endif
35 
36 #ifdef __OpenBSD__
37 #define USE_FMEM_WRAPPER 1
38 #endif
39 
40 #ifdef USE_FMEM_WRAPPER
41 
42 #ifdef OS_WIN32
43 
44 /**
45  * \brief portable version of SCFmemopen for Windows works on top of real temp files
46  * \param buffer that holds the file content
47  * \param size of the file buffer
48  * \param mode mode of the file to open
49  * \retval pointer to the file; NULL if something is wrong
50  */
51 FILE *SCFmemopen(void *buf, size_t size, const char *mode)
52 {
53  char temppath[MAX_PATH - 13];
54  if (0 == GetTempPath(sizeof(temppath), temppath))
55  return NULL;
56 
57  char filename[MAX_PATH + 1];
58  if (0 == GetTempFileName(temppath, "SC", 0, filename))
59  return NULL;
60 
61  FILE *f = fopen(filename, "wb");
62  if (NULL == f)
63  return NULL;
64 
65  fwrite(buf, size, 1, f);
66  fclose(f);
67 
68  return fopen(filename, mode);
69 }
70 
71 #else
72 
73 typedef struct SCFmem_ {
74  size_t pos;
75  size_t size;
76  char *buffer;
77 } SCFmem;
78 
79 /**
80  * \brief Seek the mem file from offset and whence
81  * \param handler pointer to the memfile
82  * \param offset number of bytes to move from whence
83  * \param whence SEEK_SET, SEEK_CUR, SEEK_END
84  * \retval pos the position by the last operation, -1 if sizes are out of bounds
85  */
86 static fpos_t SeekFn(void *handler, fpos_t offset, int whence)
87 {
88  size_t pos = 0;
89  SCFmem *mem = handler;
90 
91  switch (whence) {
92  case SEEK_SET:
93  if (offset >= 0 && (size_t)offset <= mem->size) {
94  return mem->pos = offset;
95  }
96  break;
97  case SEEK_CUR:
98  if (mem->pos + offset <= mem->size)
99  return mem->pos += offset;
100  break;
101  case SEEK_END:
102  /* must be negative */
103  if (mem->size + offset <= mem->size)
104  return pos = mem->size + offset;
105  break;
106  }
107 
108  return -1;
109 }
110 
111 /**
112  * \brief Read from the buffer looking for the available memory limits
113  * \param handler pointer to the memfile
114  * \param buf buffer to read from the handler
115  * \param number of bytes to read
116  * \retval count , the number of bytes read
117  */
118 static int ReadFn(void *handler, char *buf, int size)
119 {
120  size_t count = 0;
121  SCFmem *mem = handler;
122  size_t available = mem->size - mem->pos;
123  int is_eof = 0;
124 
125  if (size < 0) return - 1;
126 
127  if ((size_t)size > available) {
128  size = available;
129  } else {
130  is_eof = 1;
131  }
132 
133  while (count < (size_t)size)
134  buf[count++] = mem->buffer[mem->pos++];
135 
136  if (is_eof == 1)
137  return 0;
138 
139  return count;
140 }
141 
142 /**
143  * \brief Write into the buffer looking for the available memory limits
144  * \param handler pointer to the memfile
145  * \param buf buffer to write in the handler
146  * \param number of bytes to write
147  * \retval count , the number of bytes written
148  */
149 static int WriteFn(void *handler, const char *buf, int size)
150 {
151  size_t count = 0;
152  SCFmem *mem = handler;
153  size_t available = mem->size - mem->pos;
154 
155  if (size < 0) return - 1;
156 
157  if ((size_t)size > available)
158  size = available;
159 
160  while (count < (size_t)size)
161  mem->buffer[mem->pos++] = buf[count++];
162 
163  return count;
164 }
165 
166 /**
167  * \brief close the mem file handler
168  * \param handler pointer to the memfile
169  * \retval 0 on succesful
170  */
171 static int CloseFn(void *handler)
172 {
173  SCFree(handler);
174  return 0;
175 }
176 
177 /**
178  * \brief portable version of SCFmemopen for OS X / BSD built on top of funopen()
179  * \param buffer that holds the file content
180  * \param size of the file buffer
181  * \param mode mode of the file to open
182  * \retval pointer to the file; NULL if something is wrong
183  */
184 FILE *SCFmemopen(void *buf, size_t size, const char *mode)
185 {
186  SCFmem *mem = (SCFmem *)SCCalloc(1, sizeof(SCFmem));
187  if (mem == NULL)
188  return NULL;
189 
190  mem->size = size, mem->buffer = buf;
191 
192  return funopen(mem, ReadFn, WriteFn, SeekFn, CloseFn);
193 }
194 
195 #endif /* OS_WIN32 */
196 
197 #endif /* USE_FMEM_WRAPPER */
offset
uint64_t offset
Definition: util-streaming-buffer.h:0
util-fmemopen.h
SCFmemopen
#define SCFmemopen
Definition: util-fmemopen.h:52
suricata-common.h
SCFree
#define SCFree(p)
Definition: util-mem.h:61
SCCalloc
#define SCCalloc(nm, sz)
Definition: util-mem.h:53