1 /*
2 * Portions copyright 2002, 2003 Richard Laager.
3 * Copyright (c) 1996, 1997, 1998, 1999, Marc Horowitz. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Marc Horowitz.
17 * 4. The name of the author may not be used to endorse or promote
18 * products derived from this software without specific prior written
19 * permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY MARC HOROWITZ ``AS IS'' AND ANY EXPRESS
22 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL MARC HOROWITZ BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #ifdef HAVE_CONFIG_H
35 #include "config.h"
36 #endif
37
38 const char rcsid_util_c[] =
39 "$Id: util.c,v 1.4 2003/03/01 19:43:12 rlaager Exp $";
40
41 #if HAVE_SYS_TYPES_H
42 #include <sys/types.h>
43 #endif
44
45 #if HAVE_CTYPE_H
46 #include <ctype.h>
47 #endif
48
49 #if HAVE_ERRNO_H
50 #include <errno.h>
51 #endif
52
53 #if HAVE_STDIO_H
54 #include <stdio.h>
55 #endif
56
57 #if HAVE_STDLIB_H
58 #include <stdlib.h>
59 #endif
60
61 #if HAVE_STRING_H
62 #include <string.h>
63 #endif
64
65 #include "util.h"
66
67 #if HAVE_MMAP
68
69 #if HAVE_SYS_MMAN_H
70 #include <sys/mman.h>
71 #endif
72
73 #if HAVE_SYS_STAT_H
74 #include <sys/stat.h>
75 #endif
76
77 #if HAVE_UNISTD_H
78 #include <unistd.h>
79 #endif
80
81 #endif /* HAVE_MMAP */
82
83 const unsigned char zeros[1024]; /* globals are initialized to zero */
84
85 void
xbuffer_alloc(xbuffer * xb)86 xbuffer_alloc (xbuffer * xb)
87 {
88 xb->alloclen = 0;
89 xb->len = 0;
90 xb->buf = NULL;
91 }
92
93 void
xbuffer_free(xbuffer * xb)94 xbuffer_free (xbuffer * xb)
95 {
96 if (xb->buf)
97 {
98 free (xb->buf);
99 xb->alloclen = 0;
100 xb->len = 0;
101 xb->buf = NULL;
102 }
103 }
104
105 int
xbuffer_append(xbuffer * xb,const unsigned char * data,long len)106 xbuffer_append (xbuffer * xb, const unsigned char *data, long len)
107 {
108 if (len == 0)
109 return (1);
110
111 if (xb->alloclen < (xb->len + len))
112 {
113 if (xb->alloclen == 0)
114 {
115 xb->alloclen = (len > 512) ? len : 512;
116
117 if ((xb->buf = (unsigned char *) malloc (xb->alloclen)) == NULL)
118 return (0);
119 }
120 else
121 {
122 unsigned char *tmp;
123
124 xb->alloclen = (((xb->alloclen * 3 / 2) > (xb->alloclen + len)) ?
125 xb->alloclen * 3 / 2 : xb->alloclen + len);
126
127 if ((tmp =
128 (unsigned char *) realloc (xb->buf, xb->alloclen)) == NULL)
129 return (0);
130
131 xb->buf = tmp;
132 }
133 }
134
135 memcpy ((void *) (xb->buf + xb->len), (const void *) data, (size_t) len);
136
137 xb->len += len;
138
139 return (1);
140 }
141
142 int
xbuffer_append_str(xbuffer * xb,const char * data)143 xbuffer_append_str (xbuffer * xb, const char *data)
144 {
145 return (xbuffer_append (xb, (unsigned char *) data, (long) strlen (data)));
146 }
147
148 int
xfilecontents_get(xfilecontents * xfc,FILE * f)149 xfilecontents_get (xfilecontents * xfc, FILE * f)
150 {
151 #if HAVE_MMAP
152 int fd;
153 struct stat fst;
154 #endif
155 unsigned char buf[1024];
156 int cnt;
157
158 xbuffer_alloc (&(xfc->xb));
159
160 #if HAVE_MMAP
161 fd = fileno (f);
162
163 if (fstat (fd, &fst))
164 return (0);
165
166 xfc->len = fst.st_size;
167
168 xfc->buf = (unsigned char *) mmap (0, xfc->len, PROT_READ, MAP_SHARED,
169 fd, 0);
170
171 if (xfc->buf != ((void *) -1))
172 {
173 xfc->mmapped = 1;
174
175 #if HAVE_MADVISE && defined(MADV_SEQUENTIAL)
176 madvise ((char *) xfc->buf, xfc->len, MADV_SEQUENTIAL);
177 /* ignore the error. some systems don't support all the kinds of
178 advice, and there's nothing to do, anyway. */
179 #endif
180
181 return (1);
182 }
183
184 if ((errno != ENODEV) && (errno != EINVAL))
185 {
186 xbuffer_free (&(xfc->xb));
187 return (0);
188 }
189 #endif
190
191 while (!feof (f))
192 {
193 cnt = fread ((void *) buf, 1, sizeof (buf), f);
194
195 if (cnt)
196 if (!xbuffer_append (&(xfc->xb), buf, cnt))
197 {
198 xbuffer_free (&(xfc->xb));
199 return (0);
200 }
201
202 if (cnt < 1024)
203 break;
204 }
205
206 if (ferror (f))
207 {
208 xbuffer_free (&(xfc->xb));
209 return (0);
210 }
211
212 xfc->len = xfc->xb.len;
213 xfc->buf = xfc->xb.buf;
214
215 #if HAVE_MMAP
216 xfc->mmapped = 0;
217 #endif
218 return (1);
219 }
220
221 void
xfilecontents_free(xfilecontents * xfc)222 xfilecontents_free (xfilecontents * xfc)
223 {
224 #if HAVE_MMAP
225 if (xfc->mmapped)
226 munmap ((char *) xfc->buf, xfc->len);
227 #endif
228 xbuffer_free (&(xfc->xb));
229 }
230
231 char *
my_strdup(const char * s)232 my_strdup (const char *s)
233 {
234 char *ns;
235
236 if ((ns = (char *) malloc (strlen (s) + 1)) == NULL)
237 return (NULL);
238
239 strcpy (ns, s);
240
241 return (ns);
242 }
243
244 int
my_strncasecmp(const char * s1,const char * s2,int n)245 my_strncasecmp (const char *s1, const char *s2, int n)
246 {
247 int tmp;
248
249 for (; n && *s1 && *s2; n--, s1++, s2++)
250 {
251 if (*s1 == *s2)
252 continue;
253 if ((tmp = (tolower (*s1) - tolower (*s2))) != 0)
254 return (tmp);
255 }
256
257 return (0);
258 }
259
260 void *
my_memmem(const void * mem,const void * s,size_t memn,size_t mems)261 my_memmem (const void *mem, const void *s, size_t memn, size_t mems)
262 {
263 const char *cmem = (const char *) mem;
264 const char *cs = (const char *) s;
265
266 char *cptr;
267
268 for (cptr = (char *) memchr (mem, (int) cs[0], memn);
269 cptr;
270 cptr = (char *) memchr (((void *) (cptr + 1)), (int) cs[0],
271 memn - (cptr + 1 - cmem)))
272 {
273 if ((memn - (cptr - cmem)) < mems)
274 return (NULL);
275 if (memcmp (cptr, cs, mems) == 0)
276 break;
277 }
278
279 return ((void *) cptr);
280 }
281
282 void *
my_memcasemem(const void * mem,const void * s,size_t memn,size_t mems)283 my_memcasemem (const void *mem, const void *s, size_t memn, size_t mems)
284 {
285 const char *cmem = (const char *) mem;
286 const char *cs = (const char *) s;
287
288 char *cptr;
289
290 for (cptr = (char *) memchr (mem, toupper ((int) cs[0]), memn);
291 cptr;
292 cptr = (char *) memchr (((void *) (cptr + 1)), toupper ((int) cs[0]),
293 memn - (cptr + 1 - cmem)))
294 {
295 if ((memn - (cptr - cmem)) < mems)
296 return (NULL);
297 if (my_strncasecmp (cptr, cs, mems) == 0)
298 break;
299 }
300
301 if (!cptr && isalpha ((int) cs[0]))
302 {
303 for (cptr = (char *) memchr (mem, (int) tolower ((int) cs[0]), memn);
304 cptr;
305 cptr =
306 (char *) memchr (((void *) (cptr + 1)), tolower ((int) cs[0]),
307 memn - (cptr + 1 - cmem)))
308 {
309 if ((memn - (cptr - cmem)) < mems)
310 return (NULL);
311 if (my_strncasecmp (cptr, cs, mems) == 0)
312 break;
313 }
314 }
315
316 return ((void *) cptr);
317 }
318
319 void *
my_memstr(const void * mem,const char * s,size_t n)320 my_memstr (const void *mem, const char *s, size_t n)
321 {
322 return (my_memmem (mem, (const void *) s, n, strlen (s)));
323 }
324