ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/libio/string/string.c
Revision: 175
Committed: Fri Oct 21 23:57:03 2005 UTC (20 years, 9 months ago) by michael
Content type: text/x-csrc
File size: 15138 byte(s)
Log Message:
- Fixed typo ...

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

Properties

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