Import from http://svn.freenode.net/ircd-seven/private/beu/seven (r196).
[seven-1.x.git] / src / match.c
blob0ccd833e0f31de5d0b99c718c3fb7ef064a02a9a
1 /************************************************************************
2 * IRC - Internet Relay Chat, src/match.c
3 * Copyright (C) 1990 Jarkko Oikarinen
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.
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.
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.
19 * $Id: match.c 75 2006-09-23 21:30:52Z beu $
22 #include "stdinc.h"
23 #include "config.h"
24 #include "client.h"
25 #include "ircd.h"
26 #include "irc_string.h"
29 * Compare if a given string (name) matches the given
30 * mask (which can contain wild cards: '*' - match any
31 * number of chars, '?' - match any single character.
33 * return 1, if match
34 * 0, if no match
36 * Originally by Douglas A Lewis (dalewis@acsu.buffalo.edu)
37 * Rewritten by Timothy Vogelsang (netski), net@astrolink.org
40 /** Check a string against a mask.
41 * This test checks using traditional IRC wildcards only: '*' means
42 * match zero or more characters of any type; '?' means match exactly
43 * one character of any type.
45 * @param[in] mask Wildcard-containing mask.
46 * @param[in] name String to check against \a mask.
47 * @return Zero if \a mask matches \a name, non-zero if no match.
49 int match(const char *mask, const char *name)
51 const char *m = mask, *n = name;
52 const char *m_tmp = mask, *n_tmp = name;
53 int star_p;
55 s_assert(mask != NULL);
56 s_assert(name != NULL);
58 for (;;)
60 switch (*m)
62 case '\0':
63 if (!*n)
64 return 1;
65 backtrack:
66 if (m_tmp == mask)
67 return 0;
68 m = m_tmp;
69 n = ++n_tmp;
70 break;
71 case '*':
72 case '?':
73 for (star_p = 0;; m++)
75 if (*m == '*')
76 star_p = 1;
77 else if (*m == '?')
79 if (!*n++)
80 goto backtrack;
82 else
83 break;
85 if (star_p)
87 if (!*m)
88 return 1;
89 else
91 m_tmp = m;
92 for (n_tmp = n; *n && ToLower(*n) != ToLower(*m); n++);
95 /* and fall through */
96 default:
97 if (!*n)
98 return (*m != '\0' ? 0 : 1);
99 if (ToLower(*m) != ToLower(*n))
100 goto backtrack;
101 m++;
102 n++;
103 break;
108 /** Check a string against a mask.
109 * This test checks using traditional IRC wildcards only: '*' means
110 * match zero or more characters of any type; '?' means match exactly
111 * one character of any type; '#' means match exactly one character
112 * that is a number.
114 * This function supports escaping, so that a wildcard may be matched
115 * exactly.
117 * @param[in] mask Wildcard-containing mask.
118 * @param[in] name String to check against \a mask.
119 * @return Zero if \a mask matches \a name, non-zero if no match.
121 int match_esc(const char *mask, const char *name)
123 const char *m = mask, *n = name;
124 const char *m_tmp = mask, *n_tmp = name;
125 int star_p;
127 s_assert(mask != NULL);
128 s_assert(name != NULL);
130 for (;;)
132 switch (*m)
134 case '\0':
135 if (!*n)
136 return 1;
137 backtrack:
138 if (m_tmp == mask)
139 return 0;
140 m = m_tmp;
141 n = ++n_tmp;
142 break;
143 case '\\':
144 m++;
145 /* allow escaping to force capitalization */
146 if (*m++ != *n++)
147 goto backtrack;
148 break;
149 case '*':
150 case '?':
151 for (star_p = 0;; m++)
153 if (*m == '*')
154 star_p = 1;
155 else if (*m == '?')
157 if (!*n++)
158 goto backtrack;
160 else
161 break;
163 if (star_p)
165 if (!*m)
166 return 1;
167 else if (*m == '\\')
169 m_tmp = ++m;
170 if (!*m)
171 return 0;
172 for (n_tmp = n; *n && *n != *m; n++);
174 else if (*m == '#')
176 m_tmp = m;
177 for (n_tmp = n; *n && !IsDigit(*n); n++);
179 else if (*m == '@')
181 m_tmp = m;
182 for (n_tmp = n; *n && !IsLetter(*n); n++);
184 else
186 m_tmp = m;
187 for (n_tmp = n; *n && ToLower(*n) != ToLower(*m); n++);
190 /* and fall through */
191 default:
192 if (!*n)
193 return (*m != '\0' ? 0 : 1);
194 if (*m == '#')
196 if (!IsDigit(*n))
197 goto backtrack;
199 else if (*m == '@')
201 if (!IsLetter(*n))
202 goto backtrack;
204 else if (ToLower(*m) != ToLower(*n))
205 goto backtrack;
206 m++;
207 n++;
208 break;
213 int comp_with_mask(void *addr, void *dest, u_int mask)
215 if (memcmp(addr, dest, mask / 8) == 0)
217 int n = mask / 8;
218 int m = ((-1) << (8 - (mask % 8)));
219 if (mask % 8 == 0 || (((u_char *) addr)[n] & m) == (((u_char *) dest)[n] & m))
221 return (1);
224 return (0);
227 int comp_with_mask_sock(struct sockaddr *addr, struct sockaddr *dest, u_int mask)
229 void *iaddr = NULL;
230 void *idest = NULL;
232 if (addr->sa_family == AF_INET)
234 iaddr = &((struct sockaddr_in *)addr)->sin_addr;
235 idest = &((struct sockaddr_in *)dest)->sin_addr;
237 #ifdef IPV6
238 else
240 iaddr = &((struct sockaddr_in6 *)addr)->sin6_addr;
241 idest = &((struct sockaddr_in6 *)dest)->sin6_addr;
244 #endif
246 return (comp_with_mask(iaddr, idest, mask));
250 * match_ips()
252 * Input - cidr ip mask, address
254 int match_ips(const char *s1, const char *s2)
256 struct irc_sockaddr_storage ipaddr, maskaddr;
257 char mask[BUFSIZE];
258 char address[HOSTLEN + 1];
259 char *len;
260 void *ipptr, *maskptr;
261 int cidrlen, aftype;
263 strcpy(mask, s1);
264 strcpy(address, s2);
266 len = strrchr(mask, '/');
267 if (len == NULL)
268 return 0;
270 *len++ = '\0';
272 cidrlen = atoi(len);
273 if (cidrlen == 0)
274 return 0;
276 #ifdef IPV6
277 if (strchr(mask, ':') && strchr(address, ':'))
279 aftype = AF_INET6;
280 ipptr = &((struct sockaddr_in6 *)&ipaddr)->sin6_addr;
281 maskptr = &((struct sockaddr_in6 *)&maskaddr)->sin6_addr;
283 else
284 #endif
285 if (!strchr(mask, ':') && !strchr(address, ':'))
287 aftype = AF_INET;
288 ipptr = &((struct sockaddr_in *)&ipaddr)->sin_addr;
289 maskptr = &((struct sockaddr_in *)&maskaddr)->sin_addr;
291 else
292 return 0;
294 inetpton(aftype, address, ipptr);
295 inetpton(aftype, mask, maskptr);
296 if (comp_with_mask(ipptr, maskptr, cidrlen))
297 return 1;
298 else
299 return 0;
302 /* match_cidr()
304 * Input - mask, address
305 * Ouput - 1 = Matched 0 = Did not match
308 int match_cidr(const char *s1, const char *s2)
310 struct irc_sockaddr_storage ipaddr, maskaddr;
311 char mask[BUFSIZE];
312 char address[NICKLEN + USERLEN + HOSTLEN + 6];
313 char *ipmask;
314 char *ip;
315 char *len;
316 void *ipptr, *maskptr;
317 int cidrlen, aftype;
319 strcpy(mask, s1);
320 strcpy(address, s2);
322 ipmask = strrchr(mask, '@');
323 if (ipmask == NULL)
324 return 0;
326 *ipmask++ = '\0';
328 ip = strrchr(address, '@');
329 if (ip == NULL)
330 return 0;
331 *ip++ = '\0';
334 len = strrchr(ipmask, '/');
335 if (len == NULL)
336 return 0;
338 *len++ = '\0';
340 cidrlen = atoi(len);
341 if (cidrlen == 0)
342 return 0;
344 #ifdef IPV6
345 if (strchr(ip, ':') && strchr(ipmask, ':'))
347 aftype = AF_INET6;
348 ipptr = &((struct sockaddr_in6 *)&ipaddr)->sin6_addr;
349 maskptr = &((struct sockaddr_in6 *)&maskaddr)->sin6_addr;
351 else
352 #endif
353 if (!strchr(ip, ':') && !strchr(ipmask, ':'))
355 aftype = AF_INET;
356 ipptr = &((struct sockaddr_in *)&ipaddr)->sin_addr;
357 maskptr = &((struct sockaddr_in *)&maskaddr)->sin_addr;
359 else
360 return 0;
362 inetpton(aftype, ip, ipptr);
363 inetpton(aftype, ipmask, maskptr);
364 if (comp_with_mask(ipptr, maskptr, cidrlen) && match(mask, address))
365 return 1;
366 else
367 return 0;
370 /* collapse()
372 * collapses a string containing multiple *'s.
374 char *collapse(char *pattern)
376 char *p = pattern, *po = pattern;
377 char c;
378 int f = 0;
380 if (p == NULL)
381 return NULL;
383 while ((c = *p++))
385 if (c == '*')
387 if (!(f & 1))
388 *po++ = '*';
389 f |= 1;
391 else
393 *po++ = c;
394 f &= ~1;
397 *po++ = 0;
399 return pattern;
402 /* collapse_esc()
404 * The collapse() function with support for escaping characters
406 char *collapse_esc(char *pattern)
408 char *p = pattern, *po = pattern;
409 char c;
410 int f = 0;
412 if (p == NULL)
413 return NULL;
415 while ((c = *p++))
417 if (!(f & 2) && c == '*')
419 if (!(f & 1))
420 *po++ = '*';
421 f |= 1;
423 else if (!(f & 2) && c == '\\')
425 *po++ = '\\';
426 f |= 2;
428 else
430 *po++ = c;
431 f &= ~3;
434 *po++ = 0;
435 return pattern;
439 * irccmp - case insensitive comparison of two 0 terminated strings.
441 * returns 0, if s1 equal to s2
442 * <0, if s1 lexicographically less than s2
443 * >0, if s1 lexicographically greater than s2
445 int irccmp(const char *s1, const char *s2)
447 const unsigned char *str1 = (const unsigned char *)s1;
448 const unsigned char *str2 = (const unsigned char *)s2;
449 int res;
451 s_assert(s1 != NULL);
452 s_assert(s2 != NULL);
454 while ((res = ToUpper(*str1) - ToUpper(*str2)) == 0)
456 if (*str1 == '\0')
457 return 0;
458 str1++;
459 str2++;
461 return (res);
464 int ircncmp(const char *s1, const char *s2, int n)
466 const unsigned char *str1 = (const unsigned char *)s1;
467 const unsigned char *str2 = (const unsigned char *)s2;
468 int res;
469 s_assert(s1 != NULL);
470 s_assert(s2 != NULL);
472 while ((res = ToUpper(*str1) - ToUpper(*str2)) == 0)
474 str1++;
475 str2++;
476 n--;
477 if (n == 0 || (*str1 == '\0' && *str2 == '\0'))
478 return 0;
480 return (res);
483 const unsigned char ToLowerTab[] = {
484 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
485 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
486 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
487 0x1e, 0x1f,
488 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
489 '*', '+', ',', '-', '.', '/',
490 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
491 ':', ';', '<', '=', '>', '?',
492 '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
493 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
494 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
495 '_',
496 '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
497 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
498 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
499 0x7f,
500 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
501 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
502 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
503 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
504 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
505 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
506 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
507 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
508 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
509 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
510 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
511 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
512 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
513 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
514 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
515 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
518 const unsigned char ToUpperTab[] = {
519 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
520 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
521 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
522 0x1e, 0x1f,
523 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
524 '*', '+', ',', '-', '.', '/',
525 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
526 ':', ';', '<', '=', '>', '?',
527 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
528 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
529 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
530 0x5f,
531 '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
532 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
533 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
534 0x7f,
535 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
536 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
537 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
538 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
539 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
540 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
541 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
542 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
543 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
544 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
545 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
546 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
547 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
548 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
549 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
550 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
554 * CharAttrs table
556 * NOTE: RFC 1459 sez: anything but a ^G, comma, or space is allowed
557 * for channel names
559 const unsigned int CharAttrs[] = {
560 /* 0 */ CNTRL_C,
561 /* 1 */ CNTRL_C | CHAN_C | NONEOS_C,
562 /* 2 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
563 /* 3 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
564 /* 4 */ CNTRL_C | CHAN_C | NONEOS_C,
565 /* 5 */ CNTRL_C | CHAN_C | NONEOS_C,
566 /* 6 */ CNTRL_C | CHAN_C | NONEOS_C,
567 /* 7 BEL */ CNTRL_C | NONEOS_C,
568 /* 8 \b */ CNTRL_C | CHAN_C | NONEOS_C,
569 /* 9 \t */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C,
570 /* 10 \n */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C | EOL_C,
571 /* 11 \v */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C,
572 /* 12 \f */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C,
573 /* 13 \r */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C | EOL_C,
574 /* 14 */ CNTRL_C | CHAN_C | NONEOS_C,
575 /* 15 */ CNTRL_C | CHAN_C | NONEOS_C,
576 /* 16 */ CNTRL_C | CHAN_C | NONEOS_C,
577 /* 17 */ CNTRL_C | CHAN_C | NONEOS_C,
578 /* 18 */ CNTRL_C | CHAN_C | NONEOS_C,
579 /* 19 */ CNTRL_C | CHAN_C | NONEOS_C,
580 /* 20 */ CNTRL_C | CHAN_C | NONEOS_C,
581 /* 21 */ CNTRL_C | CHAN_C | NONEOS_C,
582 /* 22 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
583 /* 23 */ CNTRL_C | CHAN_C | NONEOS_C,
584 /* 24 */ CNTRL_C | CHAN_C | NONEOS_C,
585 /* 25 */ CNTRL_C | CHAN_C | NONEOS_C,
586 /* 26 */ CNTRL_C | CHAN_C | NONEOS_C,
587 /* 27 */ CNTRL_C | CHAN_C | NONEOS_C,
588 /* 28 */ CNTRL_C | CHAN_C | NONEOS_C,
589 /* 29 */ CNTRL_C | CHAN_C | NONEOS_C,
590 /* 30 */ CNTRL_C | CHAN_C | NONEOS_C,
591 /* 31 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
592 /* SP */ PRINT_C | SPACE_C,
593 /* ! */ PRINT_C | KWILD_C | CHAN_C | NONEOS_C,
594 /* " */ PRINT_C | CHAN_C | NONEOS_C,
595 /* # */ PRINT_C | MWILD_C | CHANPFX_C | CHAN_C | NONEOS_C,
596 /* $ */ PRINT_C | CHAN_C | NONEOS_C | USER_C,
597 /* % */ PRINT_C | CHAN_C | NONEOS_C,
598 /* & */ PRINT_C | CHANPFX_C | CHAN_C | NONEOS_C,
599 /* ' */ PRINT_C | CHAN_C | NONEOS_C,
600 /* ( */ PRINT_C | CHAN_C | NONEOS_C,
601 /* ) */ PRINT_C | CHAN_C | NONEOS_C,
602 /* * */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C | SERV_C,
603 /* + */ PRINT_C | CHAN_C | NONEOS_C,
604 /* , */ PRINT_C | NONEOS_C,
605 /* - */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
606 /* . */ PRINT_C | KWILD_C | CHAN_C | NONEOS_C | USER_C | HOST_C | SERV_C,
607 /* / */ PRINT_C | CHAN_C | NONEOS_C | HOST_C,
608 /* 0 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
609 /* 1 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
610 /* 2 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
611 /* 3 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
612 /* 4 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
613 /* 5 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
614 /* 6 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
615 /* 7 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
616 /* 8 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
617 /* 9 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
618 /* : */ PRINT_C | CHAN_C | NONEOS_C | HOST_C,
619 /* ; */ PRINT_C | CHAN_C | NONEOS_C,
620 /* < */ PRINT_C | CHAN_C | NONEOS_C,
621 /* = */ PRINT_C | CHAN_C | NONEOS_C,
622 /* > */ PRINT_C | CHAN_C | NONEOS_C,
623 /* ? */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C,
624 /* @ */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C,
625 /* A */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
626 /* B */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
627 /* C */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
628 /* D */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
629 /* E */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
630 /* F */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
631 /* G */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
632 /* H */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
633 /* I */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
634 /* J */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
635 /* K */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
636 /* L */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
637 /* M */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
638 /* N */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
639 /* O */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
640 /* P */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
641 /* Q */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
642 /* R */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
643 /* S */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
644 /* T */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
645 /* U */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
646 /* V */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
647 /* W */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
648 /* X */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
649 /* Y */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
650 /* Z */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
651 /* [ */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
652 /* \ */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
653 /* ] */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
654 /* ^ */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
655 /* _ */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
656 /* ` */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
657 /* a */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
658 /* b */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
659 /* c */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
660 /* d */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
661 /* e */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
662 /* f */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
663 /* g */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
664 /* h */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
665 /* i */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
666 /* j */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
667 /* k */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
668 /* l */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
669 /* m */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
670 /* n */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
671 /* o */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
672 /* p */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
673 /* q */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
674 /* r */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
675 /* s */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
676 /* t */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
677 /* u */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
678 /* v */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
679 /* w */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
680 /* x */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
681 /* y */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
682 /* z */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
683 /* { */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
684 /* | */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
685 /* } */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
686 /* ~ */ PRINT_C | ALPHA_C | CHAN_C | NONEOS_C | USER_C,
687 /* del */ CHAN_C | NONEOS_C,
688 /* 0x80 */ CHAN_C | NONEOS_C,
689 /* 0x81 */ CHAN_C | NONEOS_C,
690 /* 0x82 */ CHAN_C | NONEOS_C,
691 /* 0x83 */ CHAN_C | NONEOS_C,
692 /* 0x84 */ CHAN_C | NONEOS_C,
693 /* 0x85 */ CHAN_C | NONEOS_C,
694 /* 0x86 */ CHAN_C | NONEOS_C,
695 /* 0x87 */ CHAN_C | NONEOS_C,
696 /* 0x88 */ CHAN_C | NONEOS_C,
697 /* 0x89 */ CHAN_C | NONEOS_C,
698 /* 0x8A */ CHAN_C | NONEOS_C,
699 /* 0x8B */ CHAN_C | NONEOS_C,
700 /* 0x8C */ CHAN_C | NONEOS_C,
701 /* 0x8D */ CHAN_C | NONEOS_C,
702 /* 0x8E */ CHAN_C | NONEOS_C,
703 /* 0x8F */ CHAN_C | NONEOS_C,
704 /* 0x90 */ CHAN_C | NONEOS_C,
705 /* 0x91 */ CHAN_C | NONEOS_C,
706 /* 0x92 */ CHAN_C | NONEOS_C,
707 /* 0x93 */ CHAN_C | NONEOS_C,
708 /* 0x94 */ CHAN_C | NONEOS_C,
709 /* 0x95 */ CHAN_C | NONEOS_C,
710 /* 0x96 */ CHAN_C | NONEOS_C,
711 /* 0x97 */ CHAN_C | NONEOS_C,
712 /* 0x98 */ CHAN_C | NONEOS_C,
713 /* 0x99 */ CHAN_C | NONEOS_C,
714 /* 0x9A */ CHAN_C | NONEOS_C,
715 /* 0x9B */ CHAN_C | NONEOS_C,
716 /* 0x9C */ CHAN_C | NONEOS_C,
717 /* 0x9D */ CHAN_C | NONEOS_C,
718 /* 0x9E */ CHAN_C | NONEOS_C,
719 /* 0x9F */ CHAN_C | NONEOS_C,
720 /* 0xA0 */ CHAN_C | FCHAN_C | NONEOS_C,
721 /* 0xA1 */ CHAN_C | NONEOS_C,
722 /* 0xA2 */ CHAN_C | NONEOS_C,
723 /* 0xA3 */ CHAN_C | NONEOS_C,
724 /* 0xA4 */ CHAN_C | NONEOS_C,
725 /* 0xA5 */ CHAN_C | NONEOS_C,
726 /* 0xA6 */ CHAN_C | NONEOS_C,
727 /* 0xA7 */ CHAN_C | NONEOS_C,
728 /* 0xA8 */ CHAN_C | NONEOS_C,
729 /* 0xA9 */ CHAN_C | NONEOS_C,
730 /* 0xAA */ CHAN_C | NONEOS_C,
731 /* 0xAB */ CHAN_C | NONEOS_C,
732 /* 0xAC */ CHAN_C | NONEOS_C,
733 /* 0xAD */ CHAN_C | NONEOS_C,
734 /* 0xAE */ CHAN_C | NONEOS_C,
735 /* 0xAF */ CHAN_C | NONEOS_C,
736 /* 0xB0 */ CHAN_C | NONEOS_C,
737 /* 0xB1 */ CHAN_C | NONEOS_C,
738 /* 0xB2 */ CHAN_C | NONEOS_C,
739 /* 0xB3 */ CHAN_C | NONEOS_C,
740 /* 0xB4 */ CHAN_C | NONEOS_C,
741 /* 0xB5 */ CHAN_C | NONEOS_C,
742 /* 0xB6 */ CHAN_C | NONEOS_C,
743 /* 0xB7 */ CHAN_C | NONEOS_C,
744 /* 0xB8 */ CHAN_C | NONEOS_C,
745 /* 0xB9 */ CHAN_C | NONEOS_C,
746 /* 0xBA */ CHAN_C | NONEOS_C,
747 /* 0xBB */ CHAN_C | NONEOS_C,
748 /* 0xBC */ CHAN_C | NONEOS_C,
749 /* 0xBD */ CHAN_C | NONEOS_C,
750 /* 0xBE */ CHAN_C | NONEOS_C,
751 /* 0xBF */ CHAN_C | NONEOS_C,
752 /* 0xC0 */ CHAN_C | NONEOS_C,
753 /* 0xC1 */ CHAN_C | NONEOS_C,
754 /* 0xC2 */ CHAN_C | NONEOS_C,
755 /* 0xC3 */ CHAN_C | NONEOS_C,
756 /* 0xC4 */ CHAN_C | NONEOS_C,
757 /* 0xC5 */ CHAN_C | NONEOS_C,
758 /* 0xC6 */ CHAN_C | NONEOS_C,
759 /* 0xC7 */ CHAN_C | NONEOS_C,
760 /* 0xC8 */ CHAN_C | NONEOS_C,
761 /* 0xC9 */ CHAN_C | NONEOS_C,
762 /* 0xCA */ CHAN_C | NONEOS_C,
763 /* 0xCB */ CHAN_C | NONEOS_C,
764 /* 0xCC */ CHAN_C | NONEOS_C,
765 /* 0xCD */ CHAN_C | NONEOS_C,
766 /* 0xCE */ CHAN_C | NONEOS_C,
767 /* 0xCF */ CHAN_C | NONEOS_C,
768 /* 0xD0 */ CHAN_C | NONEOS_C,
769 /* 0xD1 */ CHAN_C | NONEOS_C,
770 /* 0xD2 */ CHAN_C | NONEOS_C,
771 /* 0xD3 */ CHAN_C | NONEOS_C,
772 /* 0xD4 */ CHAN_C | NONEOS_C,
773 /* 0xD5 */ CHAN_C | NONEOS_C,
774 /* 0xD6 */ CHAN_C | NONEOS_C,
775 /* 0xD7 */ CHAN_C | NONEOS_C,
776 /* 0xD8 */ CHAN_C | NONEOS_C,
777 /* 0xD9 */ CHAN_C | NONEOS_C,
778 /* 0xDA */ CHAN_C | NONEOS_C,
779 /* 0xDB */ CHAN_C | NONEOS_C,
780 /* 0xDC */ CHAN_C | NONEOS_C,
781 /* 0xDD */ CHAN_C | NONEOS_C,
782 /* 0xDE */ CHAN_C | NONEOS_C,
783 /* 0xDF */ CHAN_C | NONEOS_C,
784 /* 0xE0 */ CHAN_C | NONEOS_C,
785 /* 0xE1 */ CHAN_C | NONEOS_C,
786 /* 0xE2 */ CHAN_C | NONEOS_C,
787 /* 0xE3 */ CHAN_C | NONEOS_C,
788 /* 0xE4 */ CHAN_C | NONEOS_C,
789 /* 0xE5 */ CHAN_C | NONEOS_C,
790 /* 0xE6 */ CHAN_C | NONEOS_C,
791 /* 0xE7 */ CHAN_C | NONEOS_C,
792 /* 0xE8 */ CHAN_C | NONEOS_C,
793 /* 0xE9 */ CHAN_C | NONEOS_C,
794 /* 0xEA */ CHAN_C | NONEOS_C,
795 /* 0xEB */ CHAN_C | NONEOS_C,
796 /* 0xEC */ CHAN_C | NONEOS_C,
797 /* 0xED */ CHAN_C | NONEOS_C,
798 /* 0xEE */ CHAN_C | NONEOS_C,
799 /* 0xEF */ CHAN_C | NONEOS_C,
800 /* 0xF0 */ CHAN_C | NONEOS_C,
801 /* 0xF1 */ CHAN_C | NONEOS_C,
802 /* 0xF2 */ CHAN_C | NONEOS_C,
803 /* 0xF3 */ CHAN_C | NONEOS_C,
804 /* 0xF4 */ CHAN_C | NONEOS_C,
805 /* 0xF5 */ CHAN_C | NONEOS_C,
806 /* 0xF6 */ CHAN_C | NONEOS_C,
807 /* 0xF7 */ CHAN_C | NONEOS_C,
808 /* 0xF8 */ CHAN_C | NONEOS_C,
809 /* 0xF9 */ CHAN_C | NONEOS_C,
810 /* 0xFA */ CHAN_C | NONEOS_C,
811 /* 0xFB */ CHAN_C | NONEOS_C,
812 /* 0xFC */ CHAN_C | NONEOS_C,
813 /* 0xFD */ CHAN_C | NONEOS_C,
814 /* 0xFE */ CHAN_C | NONEOS_C,
815 /* 0xFF */ CHAN_C | NONEOS_C