ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/libio/string/string.c
Revision: 64
Committed: Mon Oct 3 22:50:22 2005 UTC (20 years, 10 months ago) by adx
Content type: text/x-csrc
File size: 15040 byte(s)
Log Message:
- removed external references from string/
- still to do : misc net comm

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

Properties

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