ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/libio/string/string.c
Revision: 89
Committed: Thu Oct 6 21:22:58 2005 UTC (20 years, 10 months ago) by adx
Content type: text/x-csrc
File size: 15116 byte(s)
Log Message:
- added dynamically extensible conf parser (compiles ok); enough to start
  modularising general{} -> general.c, auth{} -> auth.c and so on.

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     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, cur;
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 adx 89
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