/[svn]/ircd-hybrid-7.2/src/irc_string.c
ViewVC logotype

Contents of /ircd-hybrid-7.2/src/irc_string.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 978 - (show annotations)
Sun Aug 9 09:47:58 2009 UTC (10 years, 4 months ago) by michael
File MIME type: text/x-chdr
File size: 14894 byte(s)
- avoid using native basename() since some implementations may or may not modify passed data

1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * irc_string.c: IRC string functions.
4 *
5 * Copyright (C) 2002 by the past and present ircd coders, and others.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 *
22 * $Id$
23 */
24
25 #include "stdinc.h"
26 #include "tools.h"
27 #include "pcre.h"
28 #include "irc_string.h"
29 #include "sprintf_irc.h"
30 #include "client.h"
31 #include "list.h"
32 #include "memory.h"
33
34 #ifndef INADDRSZ
35 #define INADDRSZ 4
36 #endif
37
38 #ifndef IN6ADDRSZ
39 #define IN6ADDRSZ 16
40 #endif
41
42 #ifndef INT16SZ
43 #define INT16SZ 2
44 #endif
45
46
47 /*
48 * myctime - This is like standard ctime()-function, but it zaps away
49 * the newline from the end of that string. Also, it takes
50 * the time value as parameter, instead of pointer to it.
51 * Note that it is necessary to copy the string to alternate
52 * buffer (who knows how ctime() implements it, maybe it statically
53 * has newline there and never 'refreshes' it -- zapping that
54 * might break things in other places...)
55 *
56 *
57 * Thu Nov 24 18:22:48 1986
58 */
59 const char *
60 myctime(time_t value)
61 {
62 static char buf[32];
63 char *p;
64
65 strcpy(buf, ctime(&value));
66
67 if ((p = strchr(buf, '\n')) != NULL)
68 *p = '\0';
69 return buf;
70 }
71
72 /*
73 * clean_string - clean up a string possibly containing garbage
74 *
75 * *sigh* Before the kiddies find this new and exciting way of
76 * annoying opers, lets clean up what is sent to local opers
77 * -Dianora
78 */
79 char *
80 clean_string(char* dest, const unsigned char* src, size_t len)
81 {
82 char* d = dest;
83 assert(0 != dest);
84 assert(0 != src);
85
86 if(dest == NULL || src == NULL)
87 return NULL;
88
89 len -= 3; /* allow for worst case, '^A\0' */
90
91 while (*src && (len > 0))
92 {
93 if (*src & 0x80) /* if high bit is set */
94 {
95 *d++ = '.';
96 --len;
97 }
98 else if (!IsPrint(*src)) /* if NOT printable */
99 {
100 *d++ = '^';
101 --len;
102 *d++ = 0x40 + *src; /* turn it into a printable */
103 }
104 else
105 *d++ = *src;
106 ++src, --len;
107 }
108 *d = '\0';
109 return dest;
110 }
111
112 /*
113 * strip_tabs(dst, src, length)
114 *
115 * Copies src to dst, while converting all \t (tabs) into spaces.
116 */
117 void
118 strip_tabs(char *dest, const char *src, size_t len)
119 {
120 char *d = dest;
121
122 /* Sanity check; we don't want anything nasty... */
123 assert(dest != NULL);
124 assert(src != NULL);
125 assert(len > 0);
126
127 for (; --len && *src; ++src)
128 *d++ = *src == '\t' ? ' ' : *src;
129
130 *d = '\0'; /* NUL terminate, thanks and goodbye */
131 }
132
133 /*
134 * strtoken - walk through a string of tokens, using a set of separators
135 * argv 9/90
136 *
137 */
138 #ifndef HAVE_STRTOK_R
139
140 char *
141 strtoken(char** save, char* str, const char* fs)
142 {
143 char* pos = *save; /* keep last position across calls */
144 char* tmp;
145
146 if (str)
147 pos = str; /* new string scan */
148
149 while (pos && *pos && strchr(fs, *pos) != NULL)
150 ++pos; /* skip leading separators */
151
152 if (!pos || !*pos)
153 return (pos = *save = NULL); /* string contains only sep's */
154
155 tmp = pos; /* now, keep position of the token */
156
157 while (*pos && strchr(fs, *pos) == NULL)
158 ++pos; /* skip content of the token */
159
160 if (*pos)
161 *pos++ = '\0'; /* remove first sep after the token */
162 else
163 pos = NULL; /* end of string */
164
165 *save = pos;
166 return tmp;
167 }
168
169 #endif /* !HAVE_STRTOK_R */
170
171 /*
172 * From: Thomas Helvey <tomh@inxpress.net>
173 */
174 static const char *IpQuadTab[] =
175 {
176 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
177 "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
178 "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
179 "30", "31", "32", "33", "34", "35", "36", "37", "38", "39",
180 "40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
181 "50", "51", "52", "53", "54", "55", "56", "57", "58", "59",
182 "60", "61", "62", "63", "64", "65", "66", "67", "68", "69",
183 "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
184 "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
185 "90", "91", "92", "93", "94", "95", "96", "97", "98", "99",
186 "100", "101", "102", "103", "104", "105", "106", "107", "108", "109",
187 "110", "111", "112", "113", "114", "115", "116", "117", "118", "119",
188 "120", "121", "122", "123", "124", "125", "126", "127", "128", "129",
189 "130", "131", "132", "133", "134", "135", "136", "137", "138", "139",
190 "140", "141", "142", "143", "144", "145", "146", "147", "148", "149",
191 "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
192 "160", "161", "162", "163", "164", "165", "166", "167", "168", "169",
193 "170", "171", "172", "173", "174", "175", "176", "177", "178", "179",
194 "180", "181", "182", "183", "184", "185", "186", "187", "188", "189",
195 "190", "191", "192", "193", "194", "195", "196", "197", "198", "199",
196 "200", "201", "202", "203", "204", "205", "206", "207", "208", "209",
197 "210", "211", "212", "213", "214", "215", "216", "217", "218", "219",
198 "220", "221", "222", "223", "224", "225", "226", "227", "228", "229",
199 "230", "231", "232", "233", "234", "235", "236", "237", "238", "239",
200 "240", "241", "242", "243", "244", "245", "246", "247", "248", "249",
201 "250", "251", "252", "253", "254", "255"
202 };
203
204 /*
205 * inetntoa - in_addr to string
206 * changed name to remove collision possibility and
207 * so behaviour is guaranteed to take a pointer arg.
208 * -avalon 23/11/92
209 * inet_ntoa -- returned the dotted notation of a given
210 * internet number
211 * argv 11/90).
212 * inet_ntoa -- its broken on some Ultrix/Dynix too. -avalon
213 */
214 const char *
215 inetntoa(const char *in)
216 {
217 static char buf[16];
218 char *bufptr = buf;
219 const unsigned char *a = (const unsigned char *)in;
220 const char *n;
221
222 n = IpQuadTab[ *a++ ];
223 while (*n)
224 *bufptr++ = *n++;
225 *bufptr++ = '.';
226 n = IpQuadTab[ *a++ ];
227 while (*n)
228 *bufptr++ = *n++;
229 *bufptr++ = '.';
230 n = IpQuadTab[ *a++ ];
231 while (*n)
232 *bufptr++ = *n++;
233 *bufptr++ = '.';
234 n = IpQuadTab[ *a ];
235 while (*n)
236 *bufptr++ = *n++;
237 *bufptr = '\0';
238 return buf;
239 }
240
241 /* libio_basename()
242 *
243 * input - i.e. "/usr/local/ircd/modules/m_whois.so"
244 * output - i.e. "m_whois.so"
245 * side effects - this will be overwritten on subsequent calls
246 */
247 const char *
248 libio_basename(const char *path)
249 {
250 const char *s;
251
252 if ((s = strrchr(path, '/')) == NULL)
253 s = path;
254 else
255 s++;
256
257 return s;
258 }
259
260 /*
261 * Copyright (c) 1996-1999 by Internet Software Consortium.
262 *
263 * Permission to use, copy, modify, and distribute this software for any
264 * purpose with or without fee is hereby granted, provided that the above
265 * copyright notice and this permission notice appear in all copies.
266 *
267 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
268 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
269 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
270 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
271 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
272 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
273 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
274 * SOFTWARE.
275 */
276
277 #define SPRINTF(x) ((size_t)ircsprintf x)
278
279 /*
280 * WARNING: Don't even consider trying to compile this on a system where
281 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
282 */
283
284 static const char *inet_ntop4(const unsigned char *src, char *dst, unsigned int size);
285 #ifdef IPV6
286 static const char *inet_ntop6(const unsigned char *src, char *dst, unsigned int size);
287 #endif
288
289 /* const char *
290 * inet_ntop4(src, dst, size)
291 * format an IPv4 address
292 * return:
293 * `dst' (as a const)
294 * notes:
295 * (1) uses no statics
296 * (2) takes a unsigned char* not an in_addr as input
297 * author:
298 * Paul Vixie, 1996.
299 */
300 static const char *
301 inet_ntop4(const unsigned char *src, char *dst, unsigned int size)
302 {
303 if (size < 16)
304 return NULL;
305
306 return strcpy(dst, inetntoa((const char *)src));
307 }
308
309 /* const char *
310 * inet_ntop6(src, dst, size)
311 * convert IPv6 binary address into presentation (printable) format
312 * author:
313 * Paul Vixie, 1996.
314 */
315 #ifdef IPV6
316 static const char *
317 inet_ntop6(const unsigned char *src, char *dst, unsigned int size)
318 {
319 /*
320 * Note that int32_t and int16_t need only be "at least" large enough
321 * to contain a value of the specified size. On some systems, like
322 * Crays, there is no such thing as an integer variable with 16 bits.
323 * Keep this in mind if you think this function should have been coded
324 * to use pointer overlays. All the world's not a VAX.
325 */
326 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
327 struct { int base, len; } best = {0,0}, cur = {0,0};
328 unsigned int words[IN6ADDRSZ / INT16SZ];
329 int i;
330
331 /*
332 * Preprocess:
333 * Copy the input (bytewise) array into a wordwise array.
334 * Find the longest run of 0x00's in src[] for :: shorthanding.
335 */
336 memset(words, '\0', sizeof words);
337 for (i = 0; i < IN6ADDRSZ; i += 2)
338 words[i / 2] = (src[i] << 8) | src[i + 1];
339 best.base = -1;
340 cur.base = -1;
341 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
342 if (words[i] == 0) {
343 if (cur.base == -1)
344 cur.base = i, cur.len = 1;
345 else
346 cur.len++;
347 } else {
348 if (cur.base != -1) {
349 if (best.base == -1 || cur.len > best.len)
350 best = cur;
351 cur.base = -1;
352 }
353 }
354 }
355 if (cur.base != -1) {
356 if (best.base == -1 || cur.len > best.len)
357 best = cur;
358 }
359 if (best.base != -1 && best.len < 2)
360 best.base = -1;
361
362 /*
363 * Format the result.
364 */
365 tp = tmp;
366 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
367 /* Are we inside the best run of 0x00's? */
368 if (best.base != -1 && i >= best.base &&
369 i < (best.base + best.len)) {
370 if (i == best.base)
371 *tp++ = ':';
372 continue;
373 }
374 /* Are we following an initial run of 0x00s or any real hex? */
375 if (i != 0)
376 *tp++ = ':';
377 /* Is this address an encapsulated IPv4? */
378 if (i == 6 && best.base == 0 &&
379 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
380 if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
381 return (NULL);
382 tp += strlen(tp);
383 break;
384 }
385 tp += SPRINTF((tp, "%x", words[i]));
386 }
387 /* Was it a trailing run of 0x00's? */
388 if (best.base != -1 && (best.base + best.len) ==
389 (IN6ADDRSZ / INT16SZ))
390 *tp++ = ':';
391 *tp++ = '\0';
392
393 /*
394 * Check for overflow, copy, and we're done.
395 */
396
397 assert (tp - tmp >= 0);
398
399 if ((unsigned int)(tp - tmp) > size) {
400 return (NULL);
401 }
402 return strcpy(dst, tmp);
403 }
404 #endif
405
406 /* char *
407 * inetntop(af, src, dst, size)
408 * convert a network format address to presentation format.
409 * return:
410 * pointer to presentation format address (`dst'), or NULL (see errno).
411 * author:
412 * Paul Vixie, 1996.
413 */
414 const char *
415 inetntop(int af, const void *src, char *dst, unsigned int size)
416 {
417 switch (af)
418 {
419 case AF_INET:
420 return inet_ntop4(src, dst, size);
421 #ifdef IPV6
422 case AF_INET6:
423 if (IN6_IS_ADDR_V4MAPPED((const struct in6_addr *)src) ||
424 IN6_IS_ADDR_V4COMPAT((const struct in6_addr *)src))
425 return inet_ntop4((unsigned char *)&((const struct in6_addr *)src)->s6_addr[12], dst, size);
426 else
427 return inet_ntop6(src, dst, size);
428 #endif
429 default:
430 return NULL;
431 }
432 /* NOTREACHED */
433 }
434
435 /*
436 * strlcat and strlcpy were ripped from openssh 2.5.1p2
437 * They had the following Copyright info:
438 *
439 *
440 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
441 * All rights reserved.
442 *
443 * Redistribution and use in source and binary forms, with or without
444 * modification, are permitted provided that the following conditions
445 * are met:
446 * 1. Redistributions of source code must retain the above copyright
447 * notice, this list of conditions and the following disclaimer.
448 * 2. Redistributions in binary form must reproduce the above copyright
449 * notice, this list of conditions and the following disclaimer in the
450 * documentation and/or other materials provided with the distribution.
451 * 3. The name of the author may not be used to endorse or promote products
452 * derived from this software without specific prior written permission.
453 *
454 * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
455 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
456 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
457 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
458 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
459 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
460 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
461 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
462 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
463 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
464 */
465
466 #ifndef HAVE_STRLCAT
467 size_t
468 strlcat(char *dst, const char *src, size_t siz)
469 {
470 char *d = dst;
471 const char *s = src;
472 size_t n = siz, dlen;
473
474 while (n-- != 0 && *d != '\0')
475 d++;
476
477 dlen = d - dst;
478 n = siz - dlen;
479
480 if (n == 0)
481 return(dlen + strlen(s));
482
483 while (*s != '\0')
484 {
485 if (n != 1)
486 {
487 *d++ = *s;
488 n--;
489 }
490
491 s++;
492 }
493
494 *d = '\0';
495 return dlen + (s - src); /* count does not include NUL */
496 }
497 #endif
498
499 #ifndef HAVE_STRLCPY
500 size_t
501 strlcpy(char *dst, const char *src, size_t siz)
502 {
503 char *d = dst;
504 const char *s = src;
505 size_t n = siz;
506
507 /* Copy as many bytes as will fit */
508 if (n != 0 && --n != 0)
509 {
510 do
511 {
512 if ((*d++ = *s++) == 0)
513 break;
514 } while (--n != 0);
515 }
516
517 /* Not enough room in dst, add NUL and traverse rest of src */
518 if (n == 0)
519 {
520 if (siz != 0)
521 *d = '\0'; /* NUL-terminate dst */
522 while (*s++)
523 ;
524 }
525
526 return s - src - 1; /* count does not include NUL */
527 }
528 #endif
529
530 pcre *
531 ircd_pcre_compile(const char *pattern, const char **errptr)
532 {
533 int erroroffset = 0;
534 int options = PCRE_EXTRA;
535
536 assert(pattern);
537
538 return pcre_compile(pattern, options, errptr, &erroroffset, NULL);
539 }
540
541 int
542 ircd_pcre_exec(const pcre *code, const char *subject)
543 {
544 assert(code && subject);
545
546 return pcre_exec(code, NULL, subject, strlen(subject), 0, 0, NULL, 0) < 0;
547 }

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.26