]> jfr.im git - irc/rqf/shadowircd.git/blame - src/irc_string.c
strlcpy -> rb_strlcpy
[irc/rqf/shadowircd.git] / src / irc_string.c
CommitLineData
212380e3 1/*
2 * ircd-ratbox: A slightly useful ircd.
3 * irc_string.c: IRC string functions.
4 *
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2002-2005 ircd-ratbox development team
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
22 * USA
23 *
24 * $Id: irc_string.c 678 2006-02-03 20:25:01Z jilles $
25 */
26
27#include "stdinc.h"
28#include "sprintf_irc.h"
212380e3 29#include "irc_string.h"
30#include "client.h"
212380e3 31#include "setup.h"
32
33#ifndef INADDRSZ
34#define INADDRSZ 4
35#endif
36
2c2e0aa9 37#ifdef RB_IPV6
212380e3 38#ifndef IN6ADDRSZ
39#define IN6ADDRSZ 16
40#endif
41#endif
42
43#ifndef INT16SZ
44#define INT16SZ 2
45#endif
46/*
47 * myctime - This is like standard ctime()-function, but it zaps away
48 * the newline from the end of that string. Also, it takes
49 * the time value as parameter, instead of pointer to it.
50 * Note that it is necessary to copy the string to alternate
51 * buffer (who knows how ctime() implements it, maybe it statically
52 * has newline there and never 'refreshes' it -- zapping that
53 * might break things in other places...)
54 *
55 *
56 * Thu Nov 24 18:22:48 1986
57 */
58const char *
59myctime(time_t value)
60{
61 static char buf[32];
62 char *p;
63
64 strcpy(buf, ctime(&value));
65 if((p = strchr(buf, '\n')) != NULL)
66 *p = '\0';
67 return buf;
68}
69
70
71/*
72 * clean_string - clean up a string possibly containing garbage
73 *
74 * *sigh* Before the kiddies find this new and exciting way of
75 * annoying opers, lets clean up what is sent to local opers
76 * -Dianora
77 */
78char *
79clean_string(char *dest, const unsigned char *src, size_t len)
80{
81 char *d = dest;
82 s_assert(0 != dest);
83 s_assert(0 != src);
84
85 if(dest == NULL || src == NULL)
86 return NULL;
87
88 len -= 3; /* allow for worst case, '^A\0' */
89
90 while(*src && (len > 0))
91 {
92 if(*src & 0x80) /* if high bit is set */
93 {
94 *d++ = '.';
95 --len;
96 }
97 else if(!IsPrint(*src)) /* if NOT printable */
98 {
99 *d++ = '^';
100 --len;
101 *d++ = 0x40 + *src; /* turn it into a printable */
102 }
103 else
104 *d++ = *src;
105 ++src;
106 --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 * NOTE: jdc: I have a gut feeling there's a faster way to do this.
118 */
119char *
120strip_tabs(char *dest, const unsigned char *src, size_t len)
121{
122 char *d = dest;
123 /* Sanity check; we don't want anything nasty... */
124 s_assert(0 != dest);
125 s_assert(0 != src);
126
127 if(dest == NULL || src == NULL)
128 return NULL;
129
130 while(*src && (len > 0))
131 {
132 if(*src == '\t')
133 {
134 *d++ = ' '; /* Translate the tab into a space */
135 }
136 else
137 {
138 *d++ = *src; /* Copy src to dst */
139 }
140 ++src;
141 --len;
142 }
143 *d = '\0'; /* Null terminate, thanks and goodbye */
144 return dest;
145}
146
147/*
148 * strtoken - walk through a string of tokens, using a set of separators
149 * argv 9/90
150 *
151 */
152char *
153strtoken(char **save, char *str, const char *fs)
154{
155 char *pos = *save; /* keep last position across calls */
156 char *tmp;
157
158 if(str)
159 pos = str; /* new string scan */
160
161 while(pos && *pos && strchr(fs, *pos) != NULL)
162 ++pos; /* skip leading separators */
163
164 if(!pos || !*pos)
165 return (pos = *save = NULL); /* string contains only sep's */
166
167 tmp = pos; /* now, keep position of the token */
168
169 while(*pos && strchr(fs, *pos) == NULL)
170 ++pos; /* skip content of the token */
171
172 if(*pos)
173 *pos++ = '\0'; /* remove first sep after the token */
174 else
175 pos = NULL; /* end of string */
176
177 *save = pos;
178 return tmp;
179}
180
181static const char base64_table[] =
182 { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
183 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
184 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
185 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
186 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0'
187 };
188
189static const char base64_pad = '=';
190
191static const short base64_reverse_table[256] = {
192 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
193 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
194 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
195 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
196 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
197 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
198 -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
199 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
200 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
201 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
202 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
203 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
204 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
205 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
206 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
207 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
208};
209
212380e3 210/*
211 * From: Thomas Helvey <tomh@inxpress.net>
212 */
213static const char *IpQuadTab[] = {
214 "0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
215 "10", "11", "12", "13", "14", "15", "16", "17", "18", "19",
216 "20", "21", "22", "23", "24", "25", "26", "27", "28", "29",
217 "30", "31", "32", "33", "34", "35", "36", "37", "38", "39",
218 "40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
219 "50", "51", "52", "53", "54", "55", "56", "57", "58", "59",
220 "60", "61", "62", "63", "64", "65", "66", "67", "68", "69",
221 "70", "71", "72", "73", "74", "75", "76", "77", "78", "79",
222 "80", "81", "82", "83", "84", "85", "86", "87", "88", "89",
223 "90", "91", "92", "93", "94", "95", "96", "97", "98", "99",
224 "100", "101", "102", "103", "104", "105", "106", "107", "108", "109",
225 "110", "111", "112", "113", "114", "115", "116", "117", "118", "119",
226 "120", "121", "122", "123", "124", "125", "126", "127", "128", "129",
227 "130", "131", "132", "133", "134", "135", "136", "137", "138", "139",
228 "140", "141", "142", "143", "144", "145", "146", "147", "148", "149",
229 "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
230 "160", "161", "162", "163", "164", "165", "166", "167", "168", "169",
231 "170", "171", "172", "173", "174", "175", "176", "177", "178", "179",
232 "180", "181", "182", "183", "184", "185", "186", "187", "188", "189",
233 "190", "191", "192", "193", "194", "195", "196", "197", "198", "199",
234 "200", "201", "202", "203", "204", "205", "206", "207", "208", "209",
235 "210", "211", "212", "213", "214", "215", "216", "217", "218", "219",
236 "220", "221", "222", "223", "224", "225", "226", "227", "228", "229",
237 "230", "231", "232", "233", "234", "235", "236", "237", "238", "239",
238 "240", "241", "242", "243", "244", "245", "246", "247", "248", "249",
239 "250", "251", "252", "253", "254", "255"
240};
241
242/*
243 * inetntoa - in_addr to string
244 * changed name to remove collision possibility and
245 * so behaviour is guaranteed to take a pointer arg.
246 * -avalon 23/11/92
247 * inet_ntoa -- returned the dotted notation of a given
248 * internet number
249 * argv 11/90).
250 * inet_ntoa -- its broken on some Ultrix/Dynix too. -avalon
251 */
252
253const char *
254inetntoa(const char *in)
255{
256 static char buf[16];
257 char *bufptr = buf;
258 const unsigned char *a = (const unsigned char *) in;
259 const char *n;
260
261 n = IpQuadTab[*a++];
262 while(*n)
263 *bufptr++ = *n++;
264 *bufptr++ = '.';
265 n = IpQuadTab[*a++];
266 while(*n)
267 *bufptr++ = *n++;
268 *bufptr++ = '.';
269 n = IpQuadTab[*a++];
270 while(*n)
271 *bufptr++ = *n++;
272 *bufptr++ = '.';
273 n = IpQuadTab[*a];
274 while(*n)
275 *bufptr++ = *n++;
276 *bufptr = '\0';
277 return buf;
278}
279
280/*
281 * Copyright (c) 1996-1999 by Internet Software Consortium.
282 *
283 * Permission to use, copy, modify, and distribute this software for any
284 * purpose with or without fee is hereby granted, provided that the above
285 * copyright notice and this permission notice appear in all copies.
286 *
287 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
288 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
289 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
290 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
291 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
292 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
293 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
294 * SOFTWARE.
295 */
296
38e6acdd 297#define SPRINTF(x) ((size_t)rb_sprintf x)
212380e3 298
299/*
300 * WARNING: Don't even consider trying to compile this on a system where
301 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
302 */
303
304static const char *inet_ntop4(const u_char * src, char *dst, unsigned int size);
2c2e0aa9 305#ifdef RB_IPV6
212380e3 306static const char *inet_ntop6(const u_char * src, char *dst, unsigned int size);
307#endif
308
309/* const char *
310 * inet_ntop4(src, dst, size)
311 * format an IPv4 address
312 * return:
313 * `dst' (as a const)
314 * notes:
315 * (1) uses no statics
316 * (2) takes a u_char* not an in_addr as input
317 * author:
318 * Paul Vixie, 1996.
319 */
320static const char *
321inet_ntop4(const unsigned char *src, char *dst, unsigned int size)
322{
323 if(size < 16)
324 return NULL;
325 return strcpy(dst, inetntoa((const char *) src));
326}
327
328/* const char *
329 * inet_ntop6(src, dst, size)
330 * convert IPv6 binary address into presentation (printable) format
331 * author:
332 * Paul Vixie, 1996.
333 */
2c2e0aa9 334#ifdef RB_IPV6
212380e3 335static const char *
336inet_ntop6(const unsigned char *src, char *dst, unsigned int size)
337{
338 /*
339 * Note that int32_t and int16_t need only be "at least" large enough
340 * to contain a value of the specified size. On some systems, like
341 * Crays, there is no such thing as an integer variable with 16 bits.
342 * Keep this in mind if you think this function should have been coded
343 * to use pointer overlays. All the world's not a VAX.
344 */
345 char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
346 struct
347 {
348 int base, len;
349 }
350 best, cur;
351 u_int words[IN6ADDRSZ / INT16SZ];
352 int i;
353
354 /*
355 * Preprocess:
356 * Copy the input (bytewise) array into a wordwise array.
357 * Find the longest run of 0x00's in src[] for :: shorthanding.
358 */
359 memset(words, '\0', sizeof words);
360 for(i = 0; i < IN6ADDRSZ; i += 2)
361 words[i / 2] = (src[i] << 8) | src[i + 1];
362 best.base = -1;
363 cur.base = -1;
364 for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
365 {
366 if(words[i] == 0)
367 {
368 if(cur.base == -1)
369 cur.base = i, cur.len = 1;
370 else
371 cur.len++;
372 }
373 else
374 {
375 if(cur.base != -1)
376 {
377 if(best.base == -1 || cur.len > best.len)
378 best = cur;
379 cur.base = -1;
380 }
381 }
382 }
383 if(cur.base != -1)
384 {
385 if(best.base == -1 || cur.len > best.len)
386 best = cur;
387 }
388 if(best.base != -1 && best.len < 2)
389 best.base = -1;
390
391 /*
392 * Format the result.
393 */
394 tp = tmp;
395 for(i = 0; i < (IN6ADDRSZ / INT16SZ); i++)
396 {
397 /* Are we inside the best run of 0x00's? */
398 if(best.base != -1 && i >= best.base && i < (best.base + best.len))
399 {
400 if(i == best.base)
401 {
402 if(i == 0)
403 *tp++ = '0';
404 *tp++ = ':';
405 }
406 continue;
407 }
408 /* Are we following an initial run of 0x00s or any real hex? */
409 if(i != 0)
410 *tp++ = ':';
411 /* Is this address an encapsulated IPv4? */
412 if(i == 6 && best.base == 0 &&
413 (best.len == 6 || (best.len == 5 && words[5] == 0xffff)))
414 {
415 if(!inet_ntop4(src + 12, tp, sizeof tmp - (tp - tmp)))
416 return (NULL);
417 tp += strlen(tp);
418 break;
419 }
420 tp += SPRINTF((tp, "%x", words[i]));
421 }
422 /* Was it a trailing run of 0x00's? */
423 if(best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ))
424 *tp++ = ':';
425 *tp++ = '\0';
426
427 /*
428 * Check for overflow, copy, and we're done.
429 */
430
431 if((unsigned int) (tp - tmp) > size)
432 {
433 return (NULL);
434 }
435 return strcpy(dst, tmp);
436}
437#endif
438
439int
440inetpton_sock(const char *src, struct sockaddr *dst)
441{
442 if(inetpton(AF_INET, src, &((struct sockaddr_in *) dst)->sin_addr))
443 {
444 ((struct sockaddr_in *) dst)->sin_port = 0;
445 ((struct sockaddr_in *) dst)->sin_family = AF_INET;
3ea5fee7 446 SET_SS_LEN((struct rb_sockaddr_storage *) dst, sizeof(struct sockaddr_in));
212380e3 447 return 1;
448 }
2c2e0aa9 449#ifdef RB_IPV6
212380e3 450 else if(inetpton(AF_INET6, src, &((struct sockaddr_in6 *) dst)->sin6_addr))
451 {
452 ((struct sockaddr_in6 *) dst)->sin6_port = 0;
453 ((struct sockaddr_in6 *) dst)->sin6_family = AF_INET6;
3ea5fee7 454 SET_SS_LEN((struct rb_sockaddr_storage *) dst, sizeof(struct sockaddr_in6));
212380e3 455 return 1;
456 }
457#endif
458 return 0;
459}
460
461const char *
462inetntop_sock(struct sockaddr *src, char *dst, unsigned int size)
463{
464 switch (src->sa_family)
465 {
466 case AF_INET:
467 return (inetntop(AF_INET, &((struct sockaddr_in *) src)->sin_addr, dst, size));
468 break;
2c2e0aa9 469#ifdef RB_IPV6
212380e3 470 case AF_INET6:
471 return (inetntop(AF_INET6, &((struct sockaddr_in6 *) src)->sin6_addr, dst, size));
472 break;
473#endif
474 default:
475 return NULL;
476 break;
477 }
478}
479
480/* char *
481 * inetntop(af, src, dst, size)
482 * convert a network format address to presentation format.
483 * return:
484 * pointer to presentation format address (`dst'), or NULL (see errno).
485 * author:
486 * Paul Vixie, 1996.
487 */
488const char *
489inetntop(int af, const void *src, char *dst, unsigned int size)
490{
491 switch (af)
492 {
493 case AF_INET:
494 return (inet_ntop4(src, dst, size));
2c2e0aa9 495#ifdef RB_IPV6
212380e3 496 case AF_INET6:
497 if(IN6_IS_ADDR_V4MAPPED((const struct in6_addr *) src) ||
498 IN6_IS_ADDR_V4COMPAT((const struct in6_addr *) src))
499 return (inet_ntop4
500 ((const unsigned char *)
501 &((const struct in6_addr *) src)->s6_addr[12], dst, size));
502 else
503 return (inet_ntop6(src, dst, size));
504
505
506#endif
507 default:
508 return (NULL);
509 }
510 /* NOTREACHED */
511}
512
513/*
514 * WARNING: Don't even consider trying to compile this on a system where
515 * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
516 */
517
518/* int
519 * inetpton(af, src, dst)
520 * convert from presentation format (which usually means ASCII printable)
521 * to network format (which is usually some kind of binary format).
522 * return:
523 * 1 if the address was valid for the specified address family
524 * 0 if the address wasn't valid (`dst' is untouched in this case)
525 * -1 if some other error occurred (`dst' is untouched in this case, too)
526 * author:
527 * Paul Vixie, 1996.
528 */
529
530/* int
531 * inet_pton4(src, dst)
532 * like inet_aton() but without all the hexadecimal and shorthand.
533 * return:
534 * 1 if `src' is a valid dotted quad, else 0.
535 * notice:
536 * does not touch `dst' unless it's returning 1.
537 * author:
538 * Paul Vixie, 1996.
539 */
540static int
541inet_pton4(src, dst)
542 const char *src;
543 u_char *dst;
544{
545 int saw_digit, octets, ch;
546 u_char tmp[INADDRSZ], *tp;
547
548 saw_digit = 0;
549 octets = 0;
550 *(tp = tmp) = 0;
551 while((ch = *src++) != '\0')
552 {
553
554 if(ch >= '0' && ch <= '9')
555 {
556 u_int new = *tp * 10 + (ch - '0');
557
558 if(new > 255)
559 return (0);
560 *tp = new;
561 if(!saw_digit)
562 {
563 if(++octets > 4)
564 return (0);
565 saw_digit = 1;
566 }
567 }
568 else if(ch == '.' && saw_digit)
569 {
570 if(octets == 4)
571 return (0);
572 *++tp = 0;
573 saw_digit = 0;
574 }
575 else
576 return (0);
577 }
578 if(octets < 4)
579 return (0);
580 memcpy(dst, tmp, INADDRSZ);
581 return (1);
582}
583
2c2e0aa9 584#ifdef RB_IPV6
212380e3 585/* int
586 * inet_pton6(src, dst)
587 * convert presentation level address to network order binary form.
588 * return:
589 * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
590 * notice:
591 * (1) does not touch `dst' unless it's returning 1.
592 * (2) :: in a full address is silently ignored.
593 * credit:
594 * inspired by Mark Andrews.
595 * author:
596 * Paul Vixie, 1996.
597 */
598
599static int
600inet_pton6(src, dst)
601 const char *src;
602 u_char *dst;
603{
604 static const char xdigits[] = "0123456789abcdef";
605 u_char tmp[IN6ADDRSZ], *tp, *endp, *colonp;
606 const char *curtok;
607 int ch, saw_xdigit;
608 u_int val;
609
610 tp = memset(tmp, '\0', IN6ADDRSZ);
611 endp = tp + IN6ADDRSZ;
612 colonp = NULL;
613 /* Leading :: requires some special handling. */
614 if(*src == ':')
615 if(*++src != ':')
616 return (0);
617 curtok = src;
618 saw_xdigit = 0;
619 val = 0;
620 while((ch = tolower(*src++)) != '\0')
621 {
622 const char *pch;
623
624 pch = strchr(xdigits, ch);
625 if(pch != NULL)
626 {
627 val <<= 4;
628 val |= (pch - xdigits);
629 if(val > 0xffff)
630 return (0);
631 saw_xdigit = 1;
632 continue;
633 }
634 if(ch == ':')
635 {
636 curtok = src;
637 if(!saw_xdigit)
638 {
639 if(colonp)
640 return (0);
641 colonp = tp;
642 continue;
643 }
644 else if(*src == '\0')
645 {
646 return (0);
647 }
648 if(tp + INT16SZ > endp)
649 return (0);
650 *tp++ = (u_char) (val >> 8) & 0xff;
651 *tp++ = (u_char) val & 0xff;
652 saw_xdigit = 0;
653 val = 0;
654 continue;
655 }
656 if(*src != '\0' && ch == '.')
657 {
658 if(((tp + INADDRSZ) <= endp) && inet_pton4(curtok, tp) > 0)
659 {
660 tp += INADDRSZ;
661 saw_xdigit = 0;
662 break; /* '\0' was seen by inet_pton4(). */
663 }
664 }
665 else
666 continue;
667 return (0);
668 }
669 if(saw_xdigit)
670 {
671 if(tp + INT16SZ > endp)
672 return (0);
673 *tp++ = (u_char) (val >> 8) & 0xff;
674 *tp++ = (u_char) val & 0xff;
675 }
676 if(colonp != NULL)
677 {
678 /*
679 * Since some memmove()'s erroneously fail to handle
680 * overlapping regions, we'll do the shift by hand.
681 */
682 const int n = tp - colonp;
683 int i;
684
685 if(tp == endp)
686 return (0);
687 for(i = 1; i <= n; i++)
688 {
689 endp[-i] = colonp[n - i];
690 colonp[n - i] = 0;
691 }
692 tp = endp;
693 }
694 if(tp != endp)
695 return (0);
696 memcpy(dst, tmp, IN6ADDRSZ);
697 return (1);
698}
699#endif
700int
701inetpton(af, src, dst)
702 int af;
703 const char *src;
704 void *dst;
705{
706 switch (af)
707 {
708 case AF_INET:
709 return (inet_pton4(src, dst));
2c2e0aa9 710#ifdef RB_IPV6
212380e3 711 case AF_INET6:
712 /* Somebody might have passed as an IPv4 address this is sick but it works */
713 if(inet_pton4(src, dst))
714 {
715 char tmp[HOSTIPLEN];
38e6acdd 716 rb_sprintf(tmp, "::ffff:%s", src);
212380e3 717 return (inet_pton6(tmp, dst));
718 }
719 else
720 return (inet_pton6(src, dst));
721#endif
722 default:
723 return (-1);
724 }
725 /* NOTREACHED */
726}
727
728/*
729 * strlcat and strlcpy were ripped from openssh 2.5.1p2
730 * They had the following Copyright info:
731 *
732 *
733 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
734 * All rights reserved.
735 *
736 * Redistribution and use in source and binary forms, with or without
737 * modification, are permitted provided that the following conditions
738 * are met:
739 * 1. Redistributions of source code must retain the above copyright
740 * notice, this list of conditions and the following disclaimer.
741 * 2. Redistributions in binary form must reproduce the above copyright
742 * notice, this list of conditions and the following disclaimer in the
743 * documentation and/or other materials provided with the distribution.
744 * 3. The name of the author may not be used to endorse or promote products
745 * derived from this software without specific prior written permission.
746 *
747 * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
748 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
749 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
750 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
751 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
752 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
753 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
754 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
755 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
756 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
757 */
758
759
760
761#ifndef HAVE_STRLCAT
762size_t
763strlcat(char *dst, const char *src, size_t siz)
764{
765 char *d = dst;
766 const char *s = src;
767 size_t n = siz, dlen;
768
769 while(n-- != 0 && *d != '\0')
770 d++;
771 dlen = d - dst;
772 n = siz - dlen;
773
774 if(n == 0)
775 return (dlen + strlen(s));
776 while(*s != '\0')
777 {
778 if(n != 1)
779 {
780 *d++ = *s;
781 n--;
782 }
783 s++;
784 }
785 *d = '\0';
786 return (dlen + (s - src)); /* count does not include NUL */
787}
788#endif
789
212380e3 790char *
791strip_colour(char *string)
792{
793 char *c = string;
794 char *c2 = string;
795 char *last_non_space = NULL;
796 /* c is source, c2 is target */
797 for(; c && *c; c++)
798 switch (*c)
799 {
800 case 3:
801 if(isdigit(c[1]))
802 {
803 c++;
804 if(isdigit(c[1]))
805 c++;
806 if(c[1] == ',' && isdigit(c[2]))
807 {
808 c += 2;
809 if(isdigit(c[1]))
810 c++;
811 }
812 }
813 break;
814 case 2:
815 case 6:
816 case 7:
817 case 22:
818 case 23:
819 case 27:
820 case 31:
821 break;
822 case 32:
823 *c2++ = *c;
824 break;
825 default:
826 *c2++ = *c;
827 last_non_space = c2;
828 break;
829 }
830 *c2 = '\0';
831 if(last_non_space)
832 *last_non_space = '\0';
833 return string;
834}