ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/src/irc_string.c
Revision: 593
Committed: Fri May 12 05:47:32 2006 UTC (19 years, 3 months ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-7.2/src/irc_string.c
File size: 14916 byte(s)
Log Message:
- Backported RKLINE fix so the user and host portion of a banmask don't get
  cut off after 10 and 63 chars, respectively.
  A split_nuh() rewrite was required for this.
- Removed now unused xstrldup() function

File Contents

# Content
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 #ifndef HAVE_BASENAME
242
243 /* basename()
244 *
245 * input - i.e. "/usr/local/ircd/modules/m_whois.so"
246 * output - i.e. "m_whois.so"
247 * side effects - this will be overwritten on subsequent calls
248 */
249 char *
250 basename(char *path)
251 {
252 char *s;
253
254 if ((s = strrchr(path, '/')) == NULL)
255 s = path;
256 else
257 s++;
258
259 return s;
260 }
261
262 #endif /* !HAVE_BASENAME */
263
264 /*
265 * Copyright (c) 1996-1999 by Internet Software Consortium.
266 *
267 * Permission to use, copy, modify, and distribute this software for any
268 * purpose with or without fee is hereby granted, provided that the above
269 * copyright notice and this permission notice appear in all copies.
270 *
271 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
272 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
273 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
274 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
275 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
276 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
277 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
278 * SOFTWARE.
279 */
280
281 #define SPRINTF(x) ((size_t)ircsprintf x)
282
283 /*
284 * WARNING: Don't even consider trying to compile this on a system where
285 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
286 */
287
288 static const char *inet_ntop4(const unsigned char *src, char *dst, unsigned int size);
289 #ifdef IPV6
290 static const char *inet_ntop6(const unsigned char *src, char *dst, unsigned int size);
291 #endif
292
293 /* const char *
294 * inet_ntop4(src, dst, size)
295 * format an IPv4 address
296 * return:
297 * `dst' (as a const)
298 * notes:
299 * (1) uses no statics
300 * (2) takes a unsigned char* not an in_addr as input
301 * author:
302 * Paul Vixie, 1996.
303 */
304 static const char *
305 inet_ntop4(const unsigned char *src, char *dst, unsigned int size)
306 {
307 if (size < 16)
308 return NULL;
309
310 return strcpy(dst, inetntoa((const char *)src));
311 }
312
313 /* const char *
314 * inet_ntop6(src, dst, size)
315 * convert IPv6 binary address into presentation (printable) format
316 * author:
317 * Paul Vixie, 1996.
318 */
319 #ifdef IPV6
320 static const char *
321 inet_ntop6(const unsigned char *src, char *dst, unsigned int size)
322 {
323 /*
324 * Note that int32_t and int16_t need only be "at least" large enough
325 * to contain a value of the specified size. On some systems, like
326 * Crays, there is no such thing as an integer variable with 16 bits.
327 * Keep this in mind if you think this function should have been coded
328 * to use pointer overlays. All the world's not a VAX.
329 */
330 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
331 struct { int base, len; } best = {0,0}, cur = {0,0};
332 unsigned int words[IN6ADDRSZ / INT16SZ];
333 int i;
334
335 /*
336 * Preprocess:
337 * Copy the input (bytewise) array into a wordwise array.
338 * Find the longest run of 0x00's in src[] for :: shorthanding.
339 */
340 memset(words, '\0', sizeof words);
341 for (i = 0; i < IN6ADDRSZ; i += 2)
342 words[i / 2] = (src[i] << 8) | src[i + 1];
343 best.base = -1;
344 cur.base = -1;
345 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
346 if (words[i] == 0) {
347 if (cur.base == -1)
348 cur.base = i, cur.len = 1;
349 else
350 cur.len++;
351 } else {
352 if (cur.base != -1) {
353 if (best.base == -1 || cur.len > best.len)
354 best = cur;
355 cur.base = -1;
356 }
357 }
358 }
359 if (cur.base != -1) {
360 if (best.base == -1 || cur.len > best.len)
361 best = cur;
362 }
363 if (best.base != -1 && best.len < 2)
364 best.base = -1;
365
366 /*
367 * Format the result.
368 */
369 tp = tmp;
370 for (i = 0; i < (IN6ADDRSZ / INT16SZ); i++) {
371 /* Are we inside the best run of 0x00's? */
372 if (best.base != -1 && i >= best.base &&
373 i < (best.base + best.len)) {
374 if (i == best.base)
375 *tp++ = ':';
376 continue;
377 }
378 /* Are we following an initial run of 0x00s or any real hex? */
379 if (i != 0)
380 *tp++ = ':';
381 /* Is this address an encapsulated IPv4? */
382 if (i == 6 && best.base == 0 &&
383 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
384 if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
385 return (NULL);
386 tp += strlen(tp);
387 break;
388 }
389 tp += SPRINTF((tp, "%x", words[i]));
390 }
391 /* Was it a trailing run of 0x00's? */
392 if (best.base != -1 && (best.base + best.len) ==
393 (IN6ADDRSZ / INT16SZ))
394 *tp++ = ':';
395 *tp++ = '\0';
396
397 /*
398 * Check for overflow, copy, and we're done.
399 */
400
401 assert (tp - tmp >= 0);
402
403 if ((unsigned int)(tp - tmp) > size) {
404 return (NULL);
405 }
406 return strcpy(dst, tmp);
407 }
408 #endif
409
410 /* char *
411 * inetntop(af, src, dst, size)
412 * convert a network format address to presentation format.
413 * return:
414 * pointer to presentation format address (`dst'), or NULL (see errno).
415 * author:
416 * Paul Vixie, 1996.
417 */
418 const char *
419 inetntop(int af, const void *src, char *dst, unsigned int size)
420 {
421 switch (af)
422 {
423 case AF_INET:
424 return inet_ntop4(src, dst, size);
425 #ifdef IPV6
426 case AF_INET6:
427 if (IN6_IS_ADDR_V4MAPPED((const struct in6_addr *)src) ||
428 IN6_IS_ADDR_V4COMPAT((const struct in6_addr *)src))
429 return inet_ntop4((unsigned char *)&((const struct in6_addr *)src)->s6_addr[12], dst, size);
430 else
431 return inet_ntop6(src, dst, size);
432 #endif
433 default:
434 return NULL;
435 }
436 /* NOTREACHED */
437 }
438
439 /*
440 * strlcat and strlcpy were ripped from openssh 2.5.1p2
441 * They had the following Copyright info:
442 *
443 *
444 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
445 * All rights reserved.
446 *
447 * Redistribution and use in source and binary forms, with or without
448 * modification, are permitted provided that the following conditions
449 * are met:
450 * 1. Redistributions of source code must retain the above copyright
451 * notice, this list of conditions and the following disclaimer.
452 * 2. Redistributions in binary form must reproduce the above copyright
453 * notice, this list of conditions and the following disclaimer in the
454 * documentation and/or other materials provided with the distribution.
455 * 3. The name of the author may not be used to endorse or promote products
456 * derived from this software without specific prior written permission.
457 *
458 * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
459 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
460 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
461 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
462 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
463 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
464 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
465 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
466 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
467 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
468 */
469
470 #ifndef HAVE_STRLCAT
471 size_t
472 strlcat(char *dst, const char *src, size_t siz)
473 {
474 char *d = dst;
475 const char *s = src;
476 size_t n = siz, dlen;
477
478 while (n-- != 0 && *d != '\0')
479 d++;
480
481 dlen = d - dst;
482 n = siz - dlen;
483
484 if (n == 0)
485 return(dlen + strlen(s));
486
487 while (*s != '\0')
488 {
489 if (n != 1)
490 {
491 *d++ = *s;
492 n--;
493 }
494
495 s++;
496 }
497
498 *d = '\0';
499 return dlen + (s - src); /* count does not include NUL */
500 }
501 #endif
502
503 #ifndef HAVE_STRLCPY
504 size_t
505 strlcpy(char *dst, const char *src, size_t siz)
506 {
507 char *d = dst;
508 const char *s = src;
509 size_t n = siz;
510
511 /* Copy as many bytes as will fit */
512 if (n != 0 && --n != 0)
513 {
514 do
515 {
516 if ((*d++ = *s++) == 0)
517 break;
518 } while (--n != 0);
519 }
520
521 /* Not enough room in dst, add NUL and traverse rest of src */
522 if (n == 0)
523 {
524 if (siz != 0)
525 *d = '\0'; /* NUL-terminate dst */
526 while (*s++)
527 ;
528 }
529
530 return s - src - 1; /* count does not include NUL */
531 }
532 #endif
533
534 pcre *
535 ircd_pcre_compile(const char *pattern, const char **errptr)
536 {
537 int erroroffset = 0;
538 int options = PCRE_EXTRA;
539
540 assert(pattern);
541
542 return pcre_compile(pattern, options, errptr, &erroroffset, NULL);
543 }
544
545 int
546 ircd_pcre_exec(const pcre *code, const char *subject)
547 {
548 assert(code && subject);
549
550 return pcre_exec(code, NULL, subject, strlen(subject), 0, 0, NULL, 0) < 0;
551 }

Properties

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