fixed ssl.c bug when ssl backend returns IO_BLOCKED but IO engine doesn't get informe...
[ircu2.10.12-pk.git] / ircd / ircd_string.c
1 /*
2  * IRC - Internet Relay Chat, ircd/ircd_string.c
3  * Copyright (C) 1999 Thomas Helvey
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 1, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /** @file
20  * @brief Implementation of string operations.
21  * @version $Id: ircd_string.c 1872 2008-03-20 23:58:27Z entrope $
22  */
23 #include "config.h"
24
25 #include "ircd_string.h"
26 #include "ircd_defs.h"
27 #include "ircd_chattr.h"
28 #include "ircd_log.h"
29 #include "res.h"
30
31 /* #include <assert.h> -- Now using assert in ircd_log.h */
32 #include <string.h>
33 #include <sys/types.h>
34 #include <netinet/in.h>
35
36 /*
37  * include the character attribute tables here
38  */
39 #include "chattr.tab.c"
40
41 /** Check whether \a str contains wildcard characters.
42  * @param[in] str String that might contain wildcards.
43  * @return Non-zero if \a str contains naked (non-escaped) wildcards,
44  * zero if there are none or if they are all escaped.
45  */
46 int string_has_wildcards(const char* str)
47 {
48   assert(0 != str);
49   for ( ; *str; ++str) {
50     if ('\\' == *str) {
51       if ('\0' == *++str)
52         break;
53     }
54     else if ('*' == *str || '?' == *str)
55       return 1;
56   }
57   return 0;
58 }
59
60 /** Split a string on certain delimiters.
61  * This is a reentrant version of normal strtok().  The first call for
62  * a particular input string must use a non-NULL \a str; *save will be
63  * initialized based on that.  Later calls must use a NULL \a str;
64  * *save will be updated.
65  * @param[in,out] save Pointer to a position indicator.
66  * @param[in] str Pointer to the input string, or NULL to continue.
67  * @param[in] fs String that lists token delimiters.
68  * @return Next token in input string, or NULL if no tokens remain.
69  */
70 char* ircd_strtok(char **save, char *str, char *fs)
71 {
72   char *pos = *save;            /* keep last position across calls */
73   char *tmp;
74
75   if (str)
76     pos = str;                  /* new string scan */
77
78   while (pos && *pos && strchr(fs, *pos) != NULL)
79     pos++;                      /* skip leading separators */
80
81   if (!pos || !*pos)
82     return (pos = *save = NULL);        /* string contains only sep's */
83
84   tmp = pos;                    /* now, keep position of the token */
85
86   while (*pos && strchr(fs, *pos) == NULL)
87     pos++;                      /* skip content of the token */
88
89   if (*pos)
90     *pos++ = '\0';              /* remove first sep after the token */
91   else
92     pos = NULL;                 /* end of string */
93
94   *save = pos;
95   return (tmp);
96 }
97
98 /** Rewrite a comma-delimited list of items to remove duplicates.
99  * @param[in,out] buffer Comma-delimited list.
100  * @return The input buffer \a buffer.
101  */
102 char* canonize(char* buffer)
103 {
104   static char cbuf[BUFSIZE];
105   char*       s;
106   char*       t;
107   char*       cp = cbuf;
108   int         l = 0;
109   char*       p = NULL;
110   char*       p2;
111
112   *cp = '\0';
113
114   for (s = ircd_strtok(&p, buffer, ","); s; s = ircd_strtok(&p, NULL, ","))
115   {
116     if (l)
117     {
118       p2 = NULL;
119       for (t = ircd_strtok(&p2, cbuf, ","); t; t = ircd_strtok(&p2, NULL, ","))
120         if (0 == ircd_strcmp(s, t))
121           break;
122         else if (p2)
123           p2[-1] = ',';
124     }
125     else
126       t = NULL;
127     if (!t)
128     {
129       if (l)
130         *(cp - 1) = ',';
131       else
132         l = 1;
133       strcpy(cp, s);
134       if (p)
135         cp += (p - s);
136     }
137     else if (p2)
138       p2[-1] = ',';
139   }
140   return cbuf;
141 }
142
143 /** Copy one string to another, not to exceed a certain length.
144  * @param[in] s1 Output buffer.
145  * @param[in] s2 Source buffer.
146  * @param[in] n Maximum number of bytes to write, plus one.
147  * @return The original input buffer \a s1.
148  */
149 char* ircd_strncpy(char* s1, const char* s2, size_t n)
150 {
151   char* endp = s1 + n;
152   char* s = s1;
153
154   assert(0 != s1);
155   assert(0 != s2);
156
157   while (s < endp && (*s++ = *s2++))
158     ;
159   if (s == endp)
160     *s = '\0';
161   return s1;
162 }
163
164
165 #ifndef FORCEINLINE
166 NTL_HDR_strChattr { NTL_SRC_strChattr }
167 NTL_HDR_strCasediff { NTL_SRC_strCasediff }
168 #endif /* !FORCEINLINE */
169
170 /*
171  * Other functions visible externally
172  */
173
174 /** Case insensitive string comparison.
175  * @param[in] a First string to compare.
176  * @param[in] b Second string to compare.
177  * @return Less than, equal to, or greater than zero if \a a is lexicographically less than, equal to, or greater than \a b.
178  */
179 int ircd_strcmp(const char *a, const char *b)
180 {
181   const char* ra = a;
182   const char* rb = b;
183   while (ToLower(*ra) == ToLower(*rb)) {
184     if (!*ra++)
185       return 0;
186     else
187       ++rb;
188   }
189   return (ToLower(*ra) - ToLower(*rb));
190 }
191
192 /** Case insensitive comparison of the starts of two strings.
193  * @param[in] a First string to compare.
194  * @param[in] b Second string to compare.
195  * @param[in] n Maximum number of characters to compare.
196  * @return Less than, equal to, or greater than zero if \a a is
197  * lexicographically less than, equal to, or greater than \a b.
198  */
199 int ircd_strncmp(const char *a, const char *b, size_t n)
200 {
201   const char* ra = a;
202   const char* rb = b;
203   int left = n;
204   if (!left--)
205     return 0;
206   while (ToLower(*ra) == ToLower(*rb)) {
207     if (!*ra++ || !left--)
208       return 0;
209     else
210       ++rb;
211   }
212   return (ToLower(*ra) - ToLower(*rb));
213 }
214
215 /** Fill a vector of distinct names from a delimited input list.
216  * Empty tokens (when \a token occurs at the start or end of \a list,
217  * or when \a token occurs adjacent to itself) are ignored.  When
218  * \a size tokens have been written to \a vector, the rest of the
219  * string is ignored.
220  * Unlike token_vector(), if a token repeats an earlier token, it is
221  * skipped.
222  * @param[in,out] names Input buffer.
223  * @param[in] token Delimiter used to split \a list.
224  * @param[out] vector Output vector.
225  * @param[in] size Maximum number of elements to put in \a vector.
226  * @return Number of elements written to \a vector.
227  */
228 int unique_name_vector(char* names, char token, char** vector, int size)
229 {
230   int   i;
231   int   count = 0;
232   char* start = names;
233   char* end;
234
235   assert(0 != names);
236   assert(0 != vector);
237   assert(0 < size);
238
239   /*
240    * ignore spurious tokens
241    */
242   while (token == *start)
243     ++start;
244
245   for (end = strchr(start, token); end; end = strchr(start, token)) {
246     *end++ = '\0';
247     /*
248      * ignore spurious tokens
249      */
250     while (token == *end)
251       ++end;
252     for (i = 0; i < count; ++i) {
253       if (0 == ircd_strcmp(vector[i], start))
254         break;
255     }
256     if (i == count) {
257       vector[count++] = start;
258       if (count == size)
259         return count;
260     }
261     start = end;
262   }
263   if (*start) {
264     for (i = 0; i < count; ++i)
265       if (0 == ircd_strcmp(vector[i], start))
266         return count;
267     vector[count++] = start;
268   }
269   return count;
270 }
271
272 /** Fill a vector of tokens from a delimited input list.
273  * Empty tokens (when \a token occurs at the start or end of \a list,
274  * or when \a token occurs adjacent to itself) are ignored.  When
275  * \a size tokens have been written to \a vector, the rest of the
276  * string is ignored.
277  * @param[in,out] names Input buffer.
278  * @param[in] token Delimiter used to split \a list.
279  * @param[out] vector Output vector.
280  * @param[in] size Maximum number of elements to put in \a vector.
281  * @return Number of elements written to \a vector.
282  */
283 int token_vector(char* names, char token, char** vector, int size)
284 {
285   int   count = 0;
286   char* start = names;
287   char* end;
288
289   assert(0 != names);
290   assert(0 != vector);
291   assert(1 < size);
292
293   vector[count++] = start;
294   for (end = strchr(start, token); end; end = strchr(start, token)) {
295     *end++ = '\0';
296     start = end;
297     if (*start) {
298       vector[count++] = start;
299       if (count < size)
300         continue;
301     }
302     break;
303   }
304   return count;
305 }
306
307 /** Copy all or part of the hostname in a string to another string.
308  * If \a userhost contains an '\@', the remaining portion is used;
309  * otherwise, the whole \a userhost is used.
310  * @param[out] buf Output buffer.
311  * @param[in] userhost user\@hostname or hostname string.
312  * @param[in] len Maximum number of bytes to write to \a host.
313  * @return The output buffer \a buf.
314  */
315 char* host_from_uh(char* buf, const char* userhost, size_t len)
316 {
317   const char* s;
318
319   assert(0 != buf);
320   assert(0 != userhost);
321
322   if ((s = strchr(userhost, '@')))
323     ++s;
324   else
325     s = userhost;
326   ircd_strncpy(buf, s, len);
327   buf[len] = '\0';
328   return buf;
329 }
330
331 /*
332  * this new faster inet_ntoa was ripped from:
333  * From: Thomas Helvey <tomh@inxpress.net>
334  */
335 /** Array of text strings for dotted quads. */
336 static const char* IpQuadTab[] =
337 {
338     "0",   "1",   "2",   "3",   "4",   "5",   "6",   "7",   "8",   "9",
339    "10",  "11",  "12",  "13",  "14",  "15",  "16",  "17",  "18",  "19",
340    "20",  "21",  "22",  "23",  "24",  "25",  "26",  "27",  "28",  "29",
341    "30",  "31",  "32",  "33",  "34",  "35",  "36",  "37",  "38",  "39",
342    "40",  "41",  "42",  "43",  "44",  "45",  "46",  "47",  "48",  "49",
343    "50",  "51",  "52",  "53",  "54",  "55",  "56",  "57",  "58",  "59",
344    "60",  "61",  "62",  "63",  "64",  "65",  "66",  "67",  "68",  "69",
345    "70",  "71",  "72",  "73",  "74",  "75",  "76",  "77",  "78",  "79",
346    "80",  "81",  "82",  "83",  "84",  "85",  "86",  "87",  "88",  "89",
347    "90",  "91",  "92",  "93",  "94",  "95",  "96",  "97",  "98",  "99",
348   "100", "101", "102", "103", "104", "105", "106", "107", "108", "109",
349   "110", "111", "112", "113", "114", "115", "116", "117", "118", "119",
350   "120", "121", "122", "123", "124", "125", "126", "127", "128", "129",
351   "130", "131", "132", "133", "134", "135", "136", "137", "138", "139",
352   "140", "141", "142", "143", "144", "145", "146", "147", "148", "149",
353   "150", "151", "152", "153", "154", "155", "156", "157", "158", "159",
354   "160", "161", "162", "163", "164", "165", "166", "167", "168", "169",
355   "170", "171", "172", "173", "174", "175", "176", "177", "178", "179",
356   "180", "181", "182", "183", "184", "185", "186", "187", "188", "189",
357   "190", "191", "192", "193", "194", "195", "196", "197", "198", "199",
358   "200", "201", "202", "203", "204", "205", "206", "207", "208", "209",
359   "210", "211", "212", "213", "214", "215", "216", "217", "218", "219",
360   "220", "221", "222", "223", "224", "225", "226", "227", "228", "229",
361   "230", "231", "232", "233", "234", "235", "236", "237", "238", "239",
362   "240", "241", "242", "243", "244", "245", "246", "247", "248", "249",
363   "250", "251", "252", "253", "254", "255"
364 };
365
366 /** Convert an IP address to printable ASCII form.
367  * This is generally deprecated in favor of ircd_ntoa_r().
368  * @param[in] in Address to convert.
369  * @return Pointer to a static buffer containing the readable form.
370  */
371 const char* ircd_ntoa(const struct irc_in_addr* in)
372 {
373   static char buf[SOCKIPLEN];
374   return ircd_ntoa_r(buf, in);
375 }
376
377 /** Convert an IP address to printable ASCII form.
378  * @param[out] buf Output buffer to write to.
379  * @param[in] in Address to format.
380  * @return Pointer to the output buffer \a buf.
381  */
382 const char* ircd_ntoa_r(char* buf, const struct irc_in_addr* in)
383 {
384     assert(buf != NULL);
385     assert(in != NULL);
386
387     if (irc_in_addr_is_ipv4(in)) {
388       unsigned int pos, len;
389       unsigned char *pch;
390
391       pch = (unsigned char*)&in->in6_16[6];
392       len = strlen(IpQuadTab[*pch]);
393       memcpy(buf, IpQuadTab[*pch++], len);
394       pos = len;
395       buf[pos++] = '.';
396       len = strlen(IpQuadTab[*pch]);
397       memcpy(buf+pos, IpQuadTab[*pch++], len);
398       pos += len;
399       buf[pos++] = '.';
400       len = strlen(IpQuadTab[*pch]);
401       memcpy(buf+pos, IpQuadTab[*pch++], len);
402       pos += len;
403       buf[pos++] = '.';
404       len = strlen(IpQuadTab[*pch]);
405       memcpy(buf+pos, IpQuadTab[*pch++], len);
406       buf[pos + len] = '\0';
407       return buf;
408     } else {
409       static const char hexdigits[] = "0123456789abcdef";
410       unsigned int pos, part, max_start, max_zeros, curr_zeros, ii;
411
412       /* Find longest run of zeros. */
413       for (max_start = ii = 1, max_zeros = curr_zeros = 0; ii < 8; ++ii) {
414         if (!in->in6_16[ii])
415           curr_zeros++;
416         else if (curr_zeros > max_zeros) {
417           max_start = ii - curr_zeros;
418           max_zeros = curr_zeros;
419           curr_zeros = 0;
420         }
421       }
422       if (curr_zeros > max_zeros) {
423         max_start = ii - curr_zeros;
424         max_zeros = curr_zeros;
425       }
426
427       /* Print out address. */
428 /** Append \a CH to the output buffer. */
429 #define APPEND(CH) do { buf[pos++] = (CH); } while (0)
430       for (pos = ii = 0; (ii < 8); ++ii) {
431         if ((max_zeros > 0) && (ii == max_start)) {
432           APPEND(':');
433           ii += max_zeros - 1;
434           continue;
435         }
436         part = ntohs(in->in6_16[ii]);
437         if (part >= 0x1000)
438           APPEND(hexdigits[part >> 12]);
439         if (part >= 0x100)
440           APPEND(hexdigits[(part >> 8) & 15]);
441         if (part >= 0x10)
442           APPEND(hexdigits[(part >> 4) & 15]);
443         APPEND(hexdigits[part & 15]);
444         if (ii < 7)
445           APPEND(':');
446       }
447 #undef APPEND
448
449       /* Nul terminate and return number of characters used. */
450       buf[pos++] = '\0';
451       return buf;
452     }
453 }
454
455 /** Attempt to parse an IPv4 address into a network-endian form.
456  * @param[in] input Input string.
457  * @param[out] output Network-endian representation of the address.
458  * @param[out] pbits Number of bits found in pbits.
459  * @return Number of characters used from \a input, or 0 if the parse failed.
460  */
461 static unsigned int
462 ircd_aton_ip4(const char *input, unsigned int *output, unsigned char *pbits)
463 {
464   unsigned int dots = 0, pos = 0, part = 0, ip = 0, bits;
465
466   /* Intentionally no support for bizarre IPv4 formats (plain
467    * integers, octal or hex components) -- only vanilla dotted
468    * decimal quads.
469    */
470   if (input[0] == '.')
471     return 0;
472   bits = 32;
473   while (1) switch (input[pos]) {
474   case '\0':
475     if (dots < 3)
476       return 0;
477   out:
478     ip |= part << (24 - 8 * dots);
479     *output = htonl(ip);
480     if (pbits)
481       *pbits = bits;
482     return pos;
483   case '.':
484     if (++dots > 3)
485       return 0;
486     if (input[++pos] == '.')
487       return 0;
488     ip |= part << (32 - 8 * dots);
489     part = 0;
490     if (input[pos] == '*') {
491       while (input[++pos] == '*' || input[pos] == '.') ;
492       if (input[pos] != '\0')
493         return 0;
494       if (pbits)
495         *pbits = dots * 8;
496       *output = htonl(ip);
497       return pos;
498     }
499     break;
500   case '/':
501     if (!pbits || !IsDigit(input[pos + 1]))
502       return 0;
503     for (bits = 0; IsDigit(input[++pos]); )
504       bits = bits * 10 + input[pos] - '0';
505     if (bits > 32)
506       return 0;
507     goto out;
508   case '0': case '1': case '2': case '3': case '4':
509   case '5': case '6': case '7': case '8': case '9':
510     part = part * 10 + input[pos++] - '0';
511     if (part > 255)
512       return 0;
513     break;
514   default:
515     return 0;
516   }
517 }
518
519 /** Parse a numeric IPv4 or IPv6 address into an irc_in_addr.
520  * @param[in] input Input buffer.
521  * @param[out] ip Receives parsed IP address.
522  * @param[out] pbits If non-NULL, receives number of bits specified in address mask.
523  * @return Number of characters used from \a input, or 0 if the
524  * address was unparseable or malformed.
525  */
526 int
527 ipmask_parse(const char *input, struct irc_in_addr *ip, unsigned char *pbits)
528 {
529   char *colon;
530   char *dot;
531
532   assert(ip);
533   assert(input);
534   memset(ip, 0, sizeof(*ip));
535   colon = strchr(input, ':');
536   dot = strchr(input, '.');
537
538   if (colon && (!dot || (dot > colon))) {
539     unsigned int part = 0, pos = 0, ii = 0, colon = 8;
540     const char *part_start = NULL;
541
542     /* Parse IPv6, possibly like ::127.0.0.1.
543      * This is pretty straightforward; the only trick is borrowed
544      * from Paul Vixie (BIND): when it sees a "::" continue as if
545      * it were a single ":", but note where it happened, and fill
546      * with zeros afterward.
547      */
548     if (input[pos] == ':') {
549       if ((input[pos+1] != ':') || (input[pos+2] == ':'))
550         return 0;
551       colon = 0;
552       pos += 2;
553       part_start = input + pos;
554     }
555     while (ii < 8) switch (input[pos]) {
556       unsigned char chval;
557     case '0': case '1': case '2': case '3': case '4':
558     case '5': case '6': case '7': case '8': case '9':
559       chval = input[pos] - '0';
560     use_chval:
561       part = (part << 4) | chval;
562       if (part > 0xffff)
563         return 0;
564       pos++;
565       break;
566     case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
567       chval = input[pos] - 'A' + 10;
568       goto use_chval;
569     case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
570       chval = input[pos] - 'a' + 10;
571       goto use_chval;
572     case ':':
573       part_start = input + ++pos;
574       if (input[pos] == '.')
575         return 0;
576       ip->in6_16[ii++] = htons(part);
577       part = 0;
578       if (input[pos] == ':') {
579         if (colon < 8)
580           return 0;
581         colon = ii;
582         pos++;
583       }
584       break;
585     case '.': {
586       uint32_t ip4;
587       unsigned int len;
588       len = ircd_aton_ip4(part_start, &ip4, pbits);
589       if (!len || (ii > 6))
590         return 0;
591       ip->in6_16[ii++] = htons(ntohl(ip4) >> 16);
592       ip->in6_16[ii++] = htons(ntohl(ip4) & 65535);
593       if (pbits)
594         *pbits += 96;
595       pos = part_start + len - input;
596       goto finish;
597     }
598     case '/':
599       if (!pbits || !IsDigit(input[pos + 1]))
600         return 0;
601       ip->in6_16[ii++] = htons(part);
602       for (part = 0; IsDigit(input[++pos]); )
603         part = part * 10 + input[pos] - '0';
604       if (part > 128)
605         return 0;
606       *pbits = part;
607       goto finish;
608     case '*':
609       while (input[++pos] == '*' || input[pos] == ':') ;
610       if (input[pos] != '\0' || colon < 8)
611         return 0;
612       if (pbits)
613         *pbits = ii * 16;
614       return pos;
615     case '\0':
616       ip->in6_16[ii++] = htons(part);
617       if (colon == 8 && ii < 8)
618         return 0;
619       if (pbits)
620         *pbits = 128;
621       goto finish;
622     default:
623       return 0;
624     }
625   finish:
626     if (colon < 8) {
627       unsigned int jj;
628       /* Shift stuff after "::" up and fill middle with zeros. */
629       for (jj = 0; jj < ii - colon; jj++)
630         ip->in6_16[7 - jj] = ip->in6_16[ii - jj - 1];
631       for (jj = 0; jj < 8 - ii; jj++)
632         ip->in6_16[colon + jj] = 0;
633     }
634     return pos;
635   } else if (dot || strchr(input, '/')) {
636     unsigned int addr;
637     int len = ircd_aton_ip4(input, &addr, pbits);
638     if (len) {
639       ip->in6_16[5] = htons(65535);
640       ip->in6_16[6] = htons(ntohl(addr) >> 16);
641       ip->in6_16[7] = htons(ntohl(addr) & 65535);
642       if (pbits)
643         *pbits += 96;
644     }
645     return len;
646   } else if (input[0] == '*') {
647     unsigned int pos = 0;
648     while (input[++pos] == '*') ;
649     if (input[pos] != '\0')
650       return 0;
651     if (pbits)
652       *pbits = 0;
653     return pos;
654   } else return 0; /* parse failed */
655 }