ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/irc_string.c
Revision: 978
Committed: Sun Aug 9 09:47:58 2009 UTC (16 years ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid-7.2/src/irc_string.c
File size: 14894 byte(s)
Log Message:
- avoid using native basename() since some implementations may or may not modify passed data

File Contents

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

Properties

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