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 */
51FILE *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
73typedef 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 */
86static 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 */
118static int ReadFn(void *handler, char *buf, int size)
119{
120 int 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 (available < INT_MAX && size > (int)available) {
128 size = (int)available;
129 } else {
130 is_eof = 1;
131 }
132
133 while (count < 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 */
149static int WriteFn(void *handler, const char *buf, int size)
150{
151 int count = 0;
152 SCFmem *mem = handler;
153 size_t available = mem->size - mem->pos;
154
155 if (size < 0) return - 1;
156
157 if (available < INT_MAX && size > (int)available)
158 size = (int)available;
159
160 while (count < 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 */
171static 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 */
184FILE *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 */
#define SCFmemopen
#define SCFree(p)
Definition util-mem.h:61
#define SCCalloc(nm, sz)
Definition util-mem.h:53
uint64_t offset