]> jfr.im git - solanum.git/blob - librb/src/tools.c
whoops, fix a typo
[solanum.git] / librb / src / tools.c
1 /*
2 * ircd-ratbox: A slightly useful ircd.
3 * tools.c: Various functions needed here and there.
4 *
5 * Copyright (C) 1996-2002 Hybrid Development Team
6 * Copyright (C) 2002-2005 ircd-ratbox development team
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 * USA
22 *
23 *
24 * Here is the original header:
25 *
26 * Useful stuff, ripped from places ..
27 * adrian chadd <adrian@creative.net.au>
28 *
29 * The TOOLS_C define builds versions of the functions in tools.h
30 * so that they end up in the resulting object files. If its not
31 * defined, tools.h will build inlined versions of the functions
32 * on supported compilers
33 */
34
35 #define _GNU_SOURCE 1
36 #include <librb_config.h>
37 #include <rb_lib.h>
38 #include <rb_tools.h>
39
40
41 /*
42 * init_rb_dlink_nodes
43 *
44 */
45 static rb_bh *dnode_heap;
46 void
47 rb_init_rb_dlink_nodes(size_t dh_size)
48 {
49
50 dnode_heap = rb_bh_create(sizeof(rb_dlink_node), dh_size, "librb_dnode_heap");
51 if(dnode_heap == NULL)
52 rb_outofmemory();
53 }
54
55 /*
56 * make_rb_dlink_node
57 *
58 * inputs - NONE
59 * output - pointer to new rb_dlink_node
60 * side effects - NONE
61 */
62 rb_dlink_node *
63 rb_make_rb_dlink_node(void)
64 {
65 return (rb_bh_alloc(dnode_heap));
66 }
67
68 /*
69 * free_rb_dlink_node
70 *
71 * inputs - pointer to rb_dlink_node
72 * output - NONE
73 * side effects - free given rb_dlink_node
74 */
75 void
76 rb_free_rb_dlink_node(rb_dlink_node *ptr)
77 {
78 assert(ptr != NULL);
79 rb_bh_free(dnode_heap, ptr);
80 }
81
82 /* rb_string_to_array()
83 * Changes a given buffer into an array of parameters.
84 * Taken from ircd-ratbox.
85 *
86 * inputs - string to parse, array to put in
87 * outputs - number of parameters
88 */
89 int
90 rb_string_to_array(char *string, char **parv, int maxpara)
91 {
92 char *p, *xbuf = string;
93 int x = 0;
94
95 parv[x] = NULL;
96
97 if(string == NULL || string[0] == '\0')
98 return x;
99
100 while(*xbuf == ' ') /* skip leading spaces */
101 xbuf++;
102 if(*xbuf == '\0') /* ignore all-space args */
103 return x;
104
105 do
106 {
107 if(*xbuf == ':') /* Last parameter */
108 {
109 xbuf++;
110 parv[x++] = xbuf;
111 parv[x] = NULL;
112 return x;
113 }
114 else
115 {
116 parv[x++] = xbuf;
117 parv[x] = NULL;
118 if((p = strchr(xbuf, ' ')) != NULL)
119 {
120 *p++ = '\0';
121 xbuf = p;
122 }
123 else
124 return x;
125 }
126 while(*xbuf == ' ')
127 xbuf++;
128 if(*xbuf == '\0')
129 return x;
130 }
131 while(x < maxpara - 1);
132
133 if(*p == ':')
134 p++;
135
136 parv[x++] = p;
137 parv[x] = NULL;
138 return x;
139 }
140
141 #ifndef HAVE_STRCASECMP
142 #ifndef _WIN32
143 /* Fallback taken from FreeBSD. --Elizafox */
144 int
145 rb_strcasecmp(const char *s1, const char *s2)
146 {
147 const unsigned char *us1 = (const unsigned char *)s1,
148 const unsigned char *us2 = (const unsigned char *)s2;
149
150 while (tolower(*us1) == tolower(*us2++))
151 {
152 if (*us1++ == '\0')
153 return 0;
154 }
155
156 return (tolower(*us1) - tolower(*--us2));
157 }
158 #else /* _WIN32 */
159 int
160 rb_strcasecmp(const char *s1, const char *s2)
161 {
162 return stricmp(s1, s2);
163 }
164 #endif /* _WIN32 */
165 #else /* HAVE_STRCASECMP */
166 int
167 rb_strcasecmp(const char *s1, const char *s2)
168 {
169 return strcasecmp(s1, s2);
170 }
171 #endif
172
173 #ifndef HAVE_STRNCASECMP
174 #ifndef _WIN32
175 /* Fallback taken from FreeBSD. --Elizafox */
176 int
177 strncasecmp(const char *s1, const char *s2, size_t n)
178 {
179 if (n != 0)
180 {
181 const unsigned char *us1 = (const unsigned char *)s1;
182 const unsigned char *us2 = (const unsigned char *)s2;
183
184 do
185 {
186 if (tolower(*us1) != tolower(*us2++))
187 return (tolower(*us1) - tolower(*--us2));
188 if (*us1++ == '\0')
189 break;
190 } while (--n != 0);
191 }
192 return 0;
193 }
194 #else /* _WIN32 */
195 int
196 rb_strncasecmp(const char *s1, const char *s2, size_t n)
197 {
198 return strnicmp(s1, s2, n);
199 }
200 #endif /* _WIN32 */
201 #else /* HAVE_STRNCASECMP */
202 int
203 rb_strncasecmp(const char *s1, const char *s2, size_t n)
204 {
205 return strncasecmp(s1, s2, n);
206 }
207 #endif
208
209 #ifndef HAVE_STRCASESTR
210 /* Fallback taken from FreeBSD. --Elizafox */
211 char *
212 rb_strcasestr(const char *s, const char *find)
213 {
214 char c, sc;
215 size_t len;
216
217 if ((c = *find++) != 0) {
218 c = tolower((unsigned char)c);
219 len = strlen(find);
220 do {
221 do {
222 if ((sc = *s++) == 0)
223 return (NULL);
224 } while ((char)tolower((unsigned char)sc) != c);
225 } while (rb_strncasecmp(s, find, len) != 0);
226 s--;
227 }
228 return ((char *)s);
229 }
230 #else
231 char *
232 rb_strcasestr(const char *s, const char *find)
233 {
234 return strcasestr(s, find);
235 }
236 #endif
237
238 #ifndef HAVE_STRLCAT
239 size_t
240 rb_strlcat(char *dest, const char *src, size_t count)
241 {
242 size_t dsize = strlen(dest);
243 size_t len = strlen(src);
244 size_t res = dsize + len;
245
246 dest += dsize;
247 count -= dsize;
248 if(len >= count)
249 len = count - 1;
250 memcpy(dest, src, len);
251 dest[len] = 0;
252 return res;
253 }
254 #else
255 size_t
256 rb_strlcat(char *dest, const char *src, size_t count)
257 {
258 return strlcat(dest, src, count);
259 }
260 #endif
261
262 #ifndef HAVE_STRLCPY
263 size_t
264 rb_strlcpy(char *dest, const char *src, size_t size)
265 {
266 size_t ret = strlen(src);
267
268 if(size)
269 {
270 size_t len = (ret >= size) ? size - 1 : ret;
271 memcpy(dest, src, len);
272 dest[len] = '\0';
273 }
274 return ret;
275 }
276 #else
277 size_t
278 rb_strlcpy(char *dest, const char *src, size_t size)
279 {
280 return strlcpy(dest, src, size);
281 }
282 #endif
283
284
285 #ifndef HAVE_STRNLEN
286 size_t
287 rb_strnlen(const char *s, size_t count)
288 {
289 const char *sc;
290 for(sc = s; count-- && *sc != '\0'; ++sc)
291 ;
292 return sc - s;
293 }
294 #else
295 size_t
296 rb_strnlen(const char *s, size_t count)
297 {
298 return strnlen(s, count);
299 }
300 #endif
301
302 /*
303 * rb_snprintf_append()
304 * appends snprintf formatted string to the end of the buffer but not
305 * exceeding len
306 */
307 int
308 rb_snprintf_append(char *str, size_t len, const char *format, ...)
309 {
310 if(len == 0)
311 return 0;
312
313 size_t x = strlen(str);
314
315 if(len < x)
316 {
317 str[len - 1] = '\0';
318 return (int)len - 1;
319 }
320
321 va_list ap;
322 va_start(ap, format);
323 int y = (vsnprintf(str + x, len - x, format, ap) + (int)x);
324 va_end(ap);
325
326 return (y);
327 }
328
329 /* rb_basename
330 *
331 * input -
332 * output -
333 * side effects -
334 */
335 char *
336 rb_basename(const char *path)
337 {
338 const char *s;
339
340 if(!(s = strrchr(path, '/')))
341 s = path;
342 else
343 s++;
344 return rb_strdup(s);
345 }
346
347 /*
348 * rb_dirname
349 */
350
351 char *
352 rb_dirname (const char *path)
353 {
354 char *s;
355
356 s = strrchr(path, '/');
357 if(s == NULL)
358 {
359 return rb_strdup(".");
360 }
361
362 /* remove extra slashes */
363 while(s > path && *s == '/')
364 --s;
365
366 return rb_strndup(path, ((uintptr_t)s - (uintptr_t)path) + 2);
367 }
368
369 size_t rb_zstring_serialized(rb_zstring_t *zs, void **buf, size_t *buflen)
370 {
371 uint8_t *p;
372 size_t alloclen = sizeof(uint16_t) + zs->len;
373
374 p = rb_malloc(sizeof(alloclen));
375 memcpy(p, &zs->len, sizeof(uint16_t));
376 p += sizeof(uint16_t);
377 memcpy(p, zs->data, zs->len);
378 return alloclen;
379 }
380
381 size_t rb_zstring_deserialize(rb_zstring_t *zs, void *buf)
382 {
383 uint8_t *p = (uint8_t *)buf;
384
385 memcpy(&zs->len, p, sizeof(uint16_t));
386 p += sizeof(uint16_t);
387 if(zs->len == 0)
388 {
389 zs->data = NULL;
390 return sizeof(uint16_t);
391 }
392 zs->data = rb_malloc(zs->len);
393 memcpy(zs->data, p, zs->len);
394 return zs->len + sizeof(uint16_t);
395 }
396
397 void rb_zstring_free(rb_zstring_t *zs)
398 {
399 rb_free(zs->data);
400 rb_free(zs);
401
402 }
403
404 rb_zstring_t *rb_zstring_alloc(void)
405 {
406 rb_zstring_t *zs = rb_malloc(sizeof(rb_zstring_t));
407 return zs;
408 }
409
410 rb_zstring_t *rb_zstring_from_c_len(const char *buf, size_t len)
411 {
412 rb_zstring_t *zs;
413
414 if(len > UINT16_MAX-1)
415 return NULL;
416
417 zs = rb_zstring_alloc();
418 zs->alloclen = zs->len = (uint16_t)len;
419 zs->alloclen = (uint16_t)len;
420 if(zs->alloclen < 128)
421 zs->alloclen = 128;
422 zs->data = rb_malloc(zs->alloclen);
423 memcpy(zs->data, buf, zs->len);
424 return(zs);
425 }
426
427 rb_zstring_t *rb_zstring_from_c(const char *buf)
428 {
429 return rb_zstring_from_c_len(buf, strlen(buf));
430 }
431
432 size_t rb_zstring_len(rb_zstring_t *zs)
433 {
434 return zs->len;
435 }
436
437 void rb_zstring_append_from_zstring(rb_zstring_t *dst_zs, rb_zstring_t *src_zs)
438 {
439 void *ep;
440 size_t nlen = dst_zs->len + src_zs->len;
441
442 if(nlen > dst_zs->alloclen)
443 {
444 dst_zs->alloclen += src_zs->len + 64;
445 dst_zs->data = rb_realloc(dst_zs->data, dst_zs->alloclen);
446 }
447
448 ep = dst_zs->data + dst_zs->len;
449 memcpy(ep, src_zs->data, src_zs->len);
450 }
451
452 void rb_zstring_append_from_c(rb_zstring_t *zs, const char *buf, size_t len)
453 {
454 void *ep;
455 size_t nlen = zs->len + len;
456
457 if(nlen > zs->alloclen)
458 {
459 zs->alloclen += len + 64;
460 zs->data = rb_realloc(zs->data, zs->alloclen);
461 }
462 ep = zs->data + zs->len;
463 zs->len += len;
464 memcpy(ep, buf, len);
465 }
466
467 char *rb_zstring_to_c(rb_zstring_t *zs, char *buf, size_t len)
468 {
469 size_t cpylen;
470 if(len < zs->len)
471 cpylen = len - 1;
472 else
473 cpylen = zs->len;
474 buf[cpylen] = '\0';
475 memcpy(buf, zs->data, cpylen);
476 return buf;
477 }
478
479
480 char *rb_zstring_to_c_alloc(rb_zstring_t *zs)
481 {
482 char *p;
483 p = rb_malloc(zs->len+1);
484 memcpy(p, zs->data, zs->len);
485 return p;
486 }
487
488 size_t rb_zstring_to_ptr(rb_zstring_t *zs, void **ptr)
489 {
490 *ptr = (void *)zs->data;
491 return zs->len;
492 }