]> jfr.im git - solanum.git/blob - librb/src/tools.c
check bans and quiets for cmode -n/nonmember PRIVMSG
[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 (size >= maxpara)
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 if(string == NULL || string[0] == '\0')
96 return x;
97
98 while(*xbuf == ' ') /* skip leading spaces */
99 xbuf++;
100 if(*xbuf == '\0') /* ignore all-space args */
101 return x;
102
103 do
104 {
105 if(*xbuf == ':') /* Last parameter */
106 {
107 xbuf++;
108 parv[x++] = xbuf;
109 return x;
110 }
111 else
112 {
113 parv[x++] = xbuf;
114 if((p = strchr(xbuf, ' ')) != NULL)
115 {
116 *p++ = '\0';
117 xbuf = p;
118 }
119 else
120 return x;
121 }
122 while(*xbuf == ' ')
123 xbuf++;
124 if(*xbuf == '\0')
125 return x;
126 }
127 while(x < maxpara - 1);
128
129 if(*p == ':')
130 p++;
131
132 parv[x++] = p;
133 return x;
134 }
135
136 int
137 rb_strcasecmp(const char *s1, const char *s2)
138 {
139 return strcasecmp(s1, s2);
140 }
141
142 int
143 rb_strncasecmp(const char *s1, const char *s2, size_t n)
144 {
145 return strncasecmp(s1, s2, n);
146 }
147
148 #ifndef HAVE_STRCASESTR
149 /* Fallback taken from FreeBSD. --Elizafox */
150 char *
151 rb_strcasestr(const char *s, const char *find)
152 {
153 char c, sc;
154 size_t len;
155
156 if ((c = *find++) != 0) {
157 c = tolower((unsigned char)c);
158 len = strlen(find);
159 do {
160 do {
161 if ((sc = *s++) == 0)
162 return (NULL);
163 } while ((char)tolower((unsigned char)sc) != c);
164 } while (rb_strncasecmp(s, find, len) != 0);
165 s--;
166 }
167 return ((char *)s);
168 }
169 #else
170 char *
171 rb_strcasestr(const char *s, const char *find)
172 {
173 return strcasestr(s, find);
174 }
175 #endif
176
177 #ifndef HAVE_STRLCAT
178 size_t
179 rb_strlcat(char *dest, const char *src, size_t count)
180 {
181 size_t dsize = strlen(dest);
182 size_t len = strlen(src);
183 size_t res = dsize + len;
184
185 dest += dsize;
186 count -= dsize;
187 if(len >= count)
188 len = count - 1;
189 memcpy(dest, src, len);
190 dest[len] = 0;
191 return res;
192 }
193 #else
194 size_t
195 rb_strlcat(char *dest, const char *src, size_t count)
196 {
197 return strlcat(dest, src, count);
198 }
199 #endif
200
201 #ifndef HAVE_STRLCPY
202 size_t
203 rb_strlcpy(char *dest, const char *src, size_t size)
204 {
205 size_t ret = strlen(src);
206
207 if(size)
208 {
209 size_t len = (ret >= size) ? size - 1 : ret;
210 memcpy(dest, src, len);
211 dest[len] = '\0';
212 }
213 return ret;
214 }
215 #else
216 size_t
217 rb_strlcpy(char *dest, const char *src, size_t size)
218 {
219 return strlcpy(dest, src, size);
220 }
221 #endif
222
223
224 size_t
225 rb_strnlen(const char *s, size_t count)
226 {
227 return strnlen(s, count);
228 }
229
230 /*
231 * rb_snprintf_append()
232 * appends snprintf formatted string to the end of the buffer but not
233 * exceeding len
234 */
235 int
236 rb_snprintf_append(char *str, size_t len, const char *format, ...)
237 {
238 if(len == 0)
239 return -1;
240
241 int orig_len = strlen(str);
242
243 if((int)len < orig_len)
244 {
245 str[len - 1] = '\0';
246 return len - 1;
247 }
248
249 va_list ap;
250 va_start(ap, format);
251 int append_len = vsnprintf(str + orig_len, len - orig_len, format, ap);
252 va_end(ap);
253
254 if (append_len < 0)
255 return append_len;
256
257 return (orig_len + append_len);
258 }
259
260 /*
261 * rb_snprintf_try_append()
262 * appends snprintf formatted string to the end of the buffer but not
263 * exceeding len
264 * returns -1 if there isn't enough space for the whole string to fit
265 */
266 int
267 rb_snprintf_try_append(char *str, size_t len, const char *format, ...)
268 {
269 if(len == 0)
270 return -1;
271
272 int orig_len = strlen(str);
273
274 if((int)len < orig_len) {
275 str[len - 1] = '\0';
276 return -1;
277 }
278
279 va_list ap;
280 va_start(ap, format);
281 int append_len = vsnprintf(str + orig_len, len - orig_len, format, ap);
282 va_end(ap);
283
284 if (append_len < 0)
285 return append_len;
286
287 if (orig_len + append_len > (int)(len - 1)) {
288 str[orig_len] = '\0';
289 return -1;
290 }
291
292 return (orig_len + append_len);
293 }
294
295 /* rb_basename
296 *
297 * input -
298 * output -
299 * side effects -
300 */
301 char *
302 rb_basename(const char *path)
303 {
304 const char *s;
305
306 if(!(s = strrchr(path, '/')))
307 s = path;
308 else
309 s++;
310 return rb_strdup(s);
311 }
312
313 /*
314 * rb_dirname
315 */
316
317 char *
318 rb_dirname (const char *path)
319 {
320 char *s;
321
322 s = strrchr(path, '/');
323 if(s == NULL)
324 {
325 return rb_strdup(".");
326 }
327
328 /* remove extra slashes */
329 while(s > path && *s == '/')
330 --s;
331
332 return rb_strndup(path, ((uintptr_t)s - (uintptr_t)path) + 2);
333 }
334
335
336
337 int rb_fsnprint(char *buf, size_t len, const rb_strf_t *strings)
338 {
339 size_t used = 0;
340 size_t remaining = len;
341
342 while (strings != NULL) {
343 int ret = 0;
344
345 if (strings->length != 0) {
346 remaining = strings->length;
347 if (remaining > len - used)
348 remaining = len - used;
349 }
350
351 if (remaining == 0)
352 break;
353
354 if (strings->format != NULL) {
355 if (strings->format_args != NULL) {
356 ret = vsnprintf(buf + used, remaining,
357 strings->format, *strings->format_args);
358 } else {
359 ret = rb_strlcpy(buf + used,
360 strings->format, remaining);
361 }
362 } else if (strings->func != NULL) {
363 ret = strings->func(buf + used, remaining,
364 strings->func_args);
365 }
366
367 if (ret < 0) {
368 return ret;
369 } else if ((size_t)ret > remaining - 1) {
370 used += remaining - 1;
371 } else {
372 used += ret;
373 }
374
375 if (used >= len - 1) {
376 used = len - 1;
377 break;
378 }
379
380 remaining -= ret;
381 strings = strings->next;
382 }
383
384 return used;
385 }
386
387 int rb_fsnprintf(char *buf, size_t len, const rb_strf_t *strings, const char *format, ...)
388 {
389 va_list args;
390 rb_strf_t prepend_string = { .format = format, .format_args = &args, .next = strings };
391 int ret;
392
393 va_start(args, format);
394 ret = rb_fsnprint(buf, len, &prepend_string);
395 va_end(args);
396
397 return ret;
398 }
399