ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/libio/string/string.c
Revision: 71
Committed: Tue Oct 4 18:05:45 2005 UTC (20 years, 10 months ago) by knight
Content type: text/x-csrc
File size: 14927 byte(s)
Log Message:
- svn:keywords *smacks adx*

File Contents

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

Properties

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