ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.3/src/irc_string.c
Revision: 1045
Committed: Tue Jan 26 12:58:42 2010 UTC (14 years, 2 months ago) by michael
Content type: text/x-csrc
File size: 14072 byte(s)
Log Message:
- contrib/spy_links_notice.c: do not show additional arguments supplied to the
  LINKS command in spy notices. new behaviour is to simply show the command sent
  by the client, which exactly behaves like all other contributed spy modules.
- remove clean_string()

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

Properties

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