Initial import
[ratbox-ambernet.git] / src / match.c
blob9d39f1b3d1cc5c409213b2dc23af48aaba4c8294
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 23029 2006-09-05 15:17:49Z androsyn $
22 #include "stdinc.h"
23 #include "config.h"
24 #include "client.h"
25 #include "ircd.h"
26 #include "irc_string.h"
28 /* match()
30 * Compare if a given string (name) matches the given
31 * mask (which can contain wild cards: '*' - match any
32 * number of chars, '?' - match any single character.
34 * return 1, if match
35 * 0, if no match
37 * Originally by Douglas A Lewis (dalewis@acsu.buffalo.edu)
39 #define MATCH_MAX_CALLS 512 /* ACK! This dies when it's less that this
40 and we have long lines to parse */
41 int
42 match(const char *mask, const char *name)
44 const unsigned char *m = (const unsigned char *) mask;
45 const unsigned char *n = (const unsigned char *) name;
46 const unsigned char *ma = (const unsigned char *) mask;
47 const unsigned char *na = (const unsigned char *) name;
48 int wild = 0;
49 int calls = 0;
51 s_assert(mask != NULL);
52 s_assert(name != NULL);
54 if(!mask || !name)
55 return 0;
57 /* if the mask is "*", it matches everything */
58 if((*m == '*') && (*(m+1) == '\0'))
59 return 1;
61 while (calls++ < MATCH_MAX_CALLS)
63 if(*m == '*')
66 * XXX - shouldn't need to spin here, the mask should have been
67 * collapsed before match is called
69 while (*m == '*')
70 m++;
71 wild = 1;
72 ma = m;
73 na = n;
76 if(!*m)
78 if(!*n)
79 return 1;
80 for (m--; (m > (const unsigned char *) mask) && (*m == '?'); m--)
82 if(*m == '*' && (m > (const unsigned char *) mask))
83 return 1;
84 if(!wild)
85 return 0;
86 m = ma;
87 n = ++na;
89 else if(!*n)
92 * XXX - shouldn't need to spin here, the mask should have been
93 * collapsed before match is called
95 while (*m == '*')
96 m++;
97 return (*m == 0);
99 if(ToLower(*m) != ToLower(*n) && *m != '?')
101 if(!wild)
102 return 0;
103 m = ma;
104 n = ++na;
106 else
108 if(*m)
109 m++;
110 if(*n)
111 n++;
114 return 0;
117 /* match_esc()
119 * The match() function with support for escaping characters such
120 * as '*', '?', '#' and '@'
123 match_esc(const char *mask, const char *name)
125 const unsigned char *m = (const unsigned char *) mask;
126 const unsigned char *n = (const unsigned char *) name;
127 const unsigned char *ma = (const unsigned char *) mask;
128 const unsigned char *na = (const unsigned char *) name;
129 int wild = 0;
130 int calls = 0;
131 int quote = 0;
133 s_assert(mask != NULL);
134 s_assert(name != NULL);
136 if(!mask || !name)
137 return 0;
139 /* if the mask is "*", it matches everything */
140 if((*m == '*') && (*(m+1) == '\0'))
141 return 1;
143 while (calls++ < MATCH_MAX_CALLS)
145 if(quote)
146 quote++;
147 if(quote == 3)
148 quote = 0;
149 if(*m == '\\' && !quote)
151 m++;
152 quote = 1;
153 continue;
155 if(!quote && *m == '*')
158 * XXX - shouldn't need to spin here, the mask should have been
159 * collapsed before match is called
161 while (*m == '*')
162 m++;
164 wild = 1;
165 ma = m;
166 na = n;
168 if(*m == '\\')
170 m++;
171 /* This means it is an invalid mask -A1kmm. */
172 if(!*m)
173 return 0;
174 quote++;
175 continue;
180 if(!*m)
182 if(!*n)
183 return 1;
184 if(quote)
185 return 0;
186 for (m--; (m > (const unsigned char *) mask) && (*m == '?'); m--);;
188 if(*m == '*' && (m > (const unsigned char *) mask))
189 return 1;
190 if(!wild)
191 return 0;
192 m = ma;
193 n = ++na;
195 else if(!*n)
198 * XXX - shouldn't need to spin here, the mask should have been
199 * collapsed before match is called
201 if(quote)
202 return 0;
203 while (*m == '*')
204 m++;
205 return (*m == 0);
208 if((!quote && ((*m == '?') || (*m == '@' && IsLetter(*n)) || (*m == '#' && IsDigit(*n)))) ||
209 (ToLower(*m) == ToLower(*n) && (quote || (*m != '@' && *m != '#'))))
211 if(*m)
212 m++;
213 if(*n)
214 n++;
216 else
218 if(!wild)
219 return 0;
220 m = ma;
221 n = ++na;
224 return 0;
228 comp_with_mask(void *addr, void *dest, uint mask)
230 if(memcmp(addr, dest, mask / 8) == 0)
232 int n = mask / 8;
233 int m = ((-1) << (8 - (mask % 8)));
234 if(mask % 8 == 0 || (((u_char *) addr)[n] & m) == (((u_char *) dest)[n] & m))
236 return (1);
239 return (0);
243 comp_with_mask_sock(struct sockaddr *addr, struct sockaddr *dest, uint mask)
245 void *iaddr = NULL;
246 void *idest = NULL;
248 if(addr->sa_family == AF_INET)
250 iaddr = &((struct sockaddr_in *)addr)->sin_addr;
251 idest = &((struct sockaddr_in *)dest)->sin_addr;
253 #ifdef IPV6
254 else
256 iaddr = &((struct sockaddr_in6 *)addr)->sin6_addr;
257 idest = &((struct sockaddr_in6 *)dest)->sin6_addr;
260 #endif
262 return(comp_with_mask(iaddr, idest, mask));
266 * match_ips()
268 * Input - cidr ip mask, address
271 match_ips(const char *s1, const char *s2)
273 struct irc_sockaddr_storage ipaddr, maskaddr;
274 char mask[BUFSIZE];
275 char address[HOSTLEN + 1];
276 char *len;
277 void *ipptr, *maskptr;
278 int cidrlen, aftype;
280 strcpy(mask, s1);
281 strcpy(address, s2);
283 len = strrchr(mask, '/');
284 if(len == NULL)
285 return 0;
287 *len++ = '\0';
289 cidrlen = atoi(len);
290 if(cidrlen == 0)
291 return 0;
293 #ifdef IPV6
294 if(strchr(mask, ':') && strchr(address, ':'))
296 aftype = AF_INET6;
297 ipptr = &((struct sockaddr_in6 *)&ipaddr)->sin6_addr;
298 maskptr = &((struct sockaddr_in6 *)&maskaddr)->sin6_addr;
300 else
301 #endif
302 if(!strchr(mask, ':') && !strchr(address, ':'))
304 aftype = AF_INET;
305 ipptr = &((struct sockaddr_in *)&ipaddr)->sin_addr;
306 maskptr = &((struct sockaddr_in *)&maskaddr)->sin_addr;
308 else
309 return 0;
311 inetpton(aftype, address, ipptr);
312 inetpton(aftype, mask, maskptr);
313 if(comp_with_mask(ipptr, maskptr, cidrlen))
314 return 1;
315 else
316 return 0;
320 /* match_cidr()
321 * Matches cidr channel bans in *@host form
322 * Input - mask, address
323 * Ouput - 1 = Matched 0 = Did not match
327 match_cidr(const char *s1, const char *s2)
329 struct irc_sockaddr_storage ipaddr, maskaddr;
330 char mask[BUFSIZE];
331 char address[NICKLEN + USERLEN + HOSTLEN + 6];
332 char *ipmask;
333 char *ip;
334 char *len;
335 void *ipptr, *maskptr;
336 int cidrlen, aftype;
338 strcpy(mask, s1);
339 strcpy(address, s2);
341 ipmask = strrchr(mask, '@');
342 if(ipmask == NULL)
343 return 0;
345 *ipmask++ = '\0';
347 ip = strrchr(address, '@');
348 if(ip == NULL)
349 return 0;
350 *ip++ = '\0';
353 len = strrchr(ipmask, '/');
354 if(len == NULL)
355 return 0;
357 *len++ = '\0';
359 cidrlen = atoi(len);
360 if(cidrlen == 0)
361 return 0;
363 #ifdef IPV6
364 if(strchr(ip, ':') && strchr(ipmask, ':'))
366 aftype = AF_INET6;
367 ipptr = &((struct sockaddr_in6 *)&ipaddr)->sin6_addr;
368 maskptr = &((struct sockaddr_in6 *)&maskaddr)->sin6_addr;
370 else
371 #endif
372 if(!strchr(ip, ':') && !strchr(ipmask, ':'))
374 aftype = AF_INET;
375 ipptr = &((struct sockaddr_in *)&ipaddr)->sin_addr;
376 maskptr = &((struct sockaddr_in *)&maskaddr)->sin_addr;
378 else
379 return 0;
381 inetpton(aftype, ip, ipptr);
382 inetpton(aftype, ipmask, maskptr);
383 if(comp_with_mask(ipptr, maskptr, cidrlen) && match(mask, address))
384 return 1;
385 else
386 return 0;
389 /* collapse()
391 * collapses a string containing multiple *'s.
393 char *
394 collapse(char *pattern)
396 char *p = pattern, *po = pattern;
397 char c;
398 int f = 0;
400 if(p == NULL)
401 return NULL;
403 while ((c = *p++))
405 if(c == '*')
407 if(!(f & 1))
408 *po++ = '*';
409 f |= 1;
411 else
413 *po++ = c;
414 f &= ~1;
417 *po++ = 0;
419 return pattern;
422 /* collapse_esc()
424 * The collapse() function with support for escaping characters
426 char *
427 collapse_esc(char *pattern)
429 char *p = pattern, *po = pattern;
430 char c;
431 int f = 0;
433 if(p == NULL)
434 return NULL;
436 while ((c = *p++))
438 if(!(f & 2) && c == '*')
440 if(!(f & 1))
441 *po++ = '*';
442 f |= 1;
444 else if(!(f & 2) && c == '\\')
446 *po++ = '\\';
447 f |= 2;
449 else
451 *po++ = c;
452 f &= ~3;
455 *po++ = 0;
456 return pattern;
460 * irccmp - case insensitive comparison of two 0 terminated strings.
462 * returns 0, if s1 equal to s2
463 * <0, if s1 lexicographically less than s2
464 * >0, if s1 lexicographically greater than s2
467 irccmp(const char *s1, const char *s2)
469 const unsigned char *str1 = (const unsigned char *) s1;
470 const unsigned char *str2 = (const unsigned char *) s2;
471 int res;
473 s_assert(s1 != NULL);
474 s_assert(s2 != NULL);
476 while ((res = ToUpper(*str1) - ToUpper(*str2)) == 0)
478 if(*str1 == '\0')
479 return 0;
480 str1++;
481 str2++;
483 return (res);
487 ircncmp(const char *s1, const char *s2, int n)
489 const unsigned char *str1 = (const unsigned char *) s1;
490 const unsigned char *str2 = (const unsigned char *) s2;
491 int res;
492 s_assert(s1 != NULL);
493 s_assert(s2 != NULL);
495 while ((res = ToUpper(*str1) - ToUpper(*str2)) == 0)
497 str1++;
498 str2++;
499 n--;
500 if(n == 0 || (*str1 == '\0' && *str2 == '\0'))
501 return 0;
503 return (res);
506 const unsigned char ToLowerTab[] = {
507 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
508 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
509 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
510 0x1e, 0x1f,
511 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
512 '*', '+', ',', '-', '.', '/',
513 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
514 ':', ';', '<', '=', '>', '?',
515 '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
516 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
517 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
518 '_',
519 '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
520 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
521 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
522 0x7f,
523 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
524 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
525 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
526 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
527 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
528 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
529 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
530 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
531 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
532 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
533 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
534 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
535 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
536 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
537 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
538 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
541 const unsigned char ToUpperTab[] = {
542 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
543 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
544 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
545 0x1e, 0x1f,
546 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
547 '*', '+', ',', '-', '.', '/',
548 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
549 ':', ';', '<', '=', '>', '?',
550 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
551 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
552 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
553 0x5f,
554 '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
555 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
556 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
557 0x7f,
558 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
559 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
560 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
561 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
562 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
563 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
564 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
565 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
566 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
567 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
568 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
569 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
570 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
571 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
572 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
573 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
577 * CharAttrs table
579 * NOTE: RFC 1459 sez: anything but a ^G, comma, or space is allowed
580 * for channel names
582 const unsigned int CharAttrs[] = {
583 /* 0 */ CNTRL_C,
584 /* 1 */ CNTRL_C | CHAN_C | NONEOS_C,
585 /* 2 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
586 /* 3 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
587 /* 4 */ CNTRL_C | CHAN_C | NONEOS_C,
588 /* 5 */ CNTRL_C | CHAN_C | NONEOS_C,
589 /* 6 */ CNTRL_C | CHAN_C | NONEOS_C,
590 /* 7 BEL */ CNTRL_C | NONEOS_C,
591 /* 8 \b */ CNTRL_C | CHAN_C | NONEOS_C,
592 /* 9 \t */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C,
593 /* 10 \n */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C | EOL_C,
594 /* 11 \v */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C,
595 /* 12 \f */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C,
596 /* 13 \r */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C | EOL_C,
597 /* 14 */ CNTRL_C | CHAN_C | NONEOS_C,
598 /* 15 */ CNTRL_C | CHAN_C | NONEOS_C,
599 /* 16 */ CNTRL_C | CHAN_C | NONEOS_C,
600 /* 17 */ CNTRL_C | CHAN_C | NONEOS_C,
601 /* 18 */ CNTRL_C | CHAN_C | NONEOS_C,
602 /* 19 */ CNTRL_C | CHAN_C | NONEOS_C,
603 /* 20 */ CNTRL_C | CHAN_C | NONEOS_C,
604 /* 21 */ CNTRL_C | CHAN_C | NONEOS_C,
605 /* 22 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
606 /* 23 */ CNTRL_C | CHAN_C | NONEOS_C,
607 /* 24 */ CNTRL_C | CHAN_C | NONEOS_C,
608 /* 25 */ CNTRL_C | CHAN_C | NONEOS_C,
609 /* 26 */ CNTRL_C | CHAN_C | NONEOS_C,
610 /* 27 */ CNTRL_C | CHAN_C | NONEOS_C,
611 /* 28 */ CNTRL_C | CHAN_C | NONEOS_C,
612 /* 29 */ CNTRL_C | CHAN_C | NONEOS_C,
613 /* 30 */ CNTRL_C | CHAN_C | NONEOS_C,
614 /* 31 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
615 /* SP */ PRINT_C | SPACE_C,
616 /* ! */ PRINT_C | KWILD_C | CHAN_C | NONEOS_C,
617 /* " */ PRINT_C | CHAN_C | NONEOS_C,
618 /* # */ PRINT_C | MWILD_C | CHANPFX_C | CHAN_C | NONEOS_C,
619 /* $ */ PRINT_C | CHAN_C | NONEOS_C | USER_C,
620 /* % */ PRINT_C | CHAN_C | NONEOS_C,
621 /* & */ PRINT_C | CHANPFX_C | CHAN_C | NONEOS_C,
622 /* ' */ PRINT_C | CHAN_C | NONEOS_C,
623 /* ( */ PRINT_C | CHAN_C | NONEOS_C,
624 /* ) */ PRINT_C | CHAN_C | NONEOS_C,
625 /* * */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C | SERV_C,
626 /* + */ PRINT_C | CHAN_C | NONEOS_C,
627 /* , */ PRINT_C | NONEOS_C,
628 /* - */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
629 /* . */ PRINT_C | KWILD_C | CHAN_C | NONEOS_C | USER_C | HOST_C | SERV_C,
630 /* / */ PRINT_C | KWILD_C | CHAN_C | NONEOS_C,
631 /* 0 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
632 /* 1 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
633 /* 2 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
634 /* 3 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
635 /* 4 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
636 /* 5 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
637 /* 6 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
638 /* 7 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
639 /* 8 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
640 /* 9 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
641 /* : */ PRINT_C | CHAN_C | NONEOS_C | HOST_C,
642 /* ; */ PRINT_C | CHAN_C | NONEOS_C,
643 /* < */ PRINT_C | CHAN_C | NONEOS_C,
644 /* = */ PRINT_C | CHAN_C | NONEOS_C,
645 /* > */ PRINT_C | CHAN_C | NONEOS_C,
646 /* ? */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C,
647 /* @ */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C,
648 /* A */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
649 /* B */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
650 /* C */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
651 /* D */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
652 /* E */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
653 /* F */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
654 /* G */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
655 /* H */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
656 /* I */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
657 /* J */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
658 /* K */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
659 /* L */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
660 /* M */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
661 /* N */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
662 /* O */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
663 /* P */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
664 /* Q */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
665 /* R */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
666 /* S */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
667 /* T */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
668 /* U */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
669 /* V */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
670 /* W */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
671 /* X */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
672 /* Y */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
673 /* Z */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
674 /* [ */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
675 /* \ */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
676 /* ] */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
677 /* ^ */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
678 /* _ */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
679 /* ` */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
680 /* a */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
681 /* b */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
682 /* c */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
683 /* d */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
684 /* e */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
685 /* f */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
686 /* g */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
687 /* h */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
688 /* i */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
689 /* j */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
690 /* k */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
691 /* l */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
692 /* m */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
693 /* n */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
694 /* o */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
695 /* p */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
696 /* q */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
697 /* r */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
698 /* s */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
699 /* t */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
700 /* u */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
701 /* v */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
702 /* w */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
703 /* x */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
704 /* y */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
705 /* z */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
706 /* { */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
707 /* | */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
708 /* } */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
709 /* ~ */ PRINT_C | ALPHA_C | CHAN_C | NONEOS_C | USER_C,
710 /* del */ CHAN_C | NONEOS_C,
711 /* 0x80 */ CHAN_C | NONEOS_C,
712 /* 0x81 */ CHAN_C | NONEOS_C,
713 /* 0x82 */ CHAN_C | NONEOS_C,
714 /* 0x83 */ CHAN_C | NONEOS_C,
715 /* 0x84 */ CHAN_C | NONEOS_C,
716 /* 0x85 */ CHAN_C | NONEOS_C,
717 /* 0x86 */ CHAN_C | NONEOS_C,
718 /* 0x87 */ CHAN_C | NONEOS_C,
719 /* 0x88 */ CHAN_C | NONEOS_C,
720 /* 0x89 */ CHAN_C | NONEOS_C,
721 /* 0x8A */ CHAN_C | NONEOS_C,
722 /* 0x8B */ CHAN_C | NONEOS_C,
723 /* 0x8C */ CHAN_C | NONEOS_C,
724 /* 0x8D */ CHAN_C | NONEOS_C,
725 /* 0x8E */ CHAN_C | NONEOS_C,
726 /* 0x8F */ CHAN_C | NONEOS_C,
727 /* 0x90 */ CHAN_C | NONEOS_C,
728 /* 0x91 */ CHAN_C | NONEOS_C,
729 /* 0x92 */ CHAN_C | NONEOS_C,
730 /* 0x93 */ CHAN_C | NONEOS_C,
731 /* 0x94 */ CHAN_C | NONEOS_C,
732 /* 0x95 */ CHAN_C | NONEOS_C,
733 /* 0x96 */ CHAN_C | NONEOS_C,
734 /* 0x97 */ CHAN_C | NONEOS_C,
735 /* 0x98 */ CHAN_C | NONEOS_C,
736 /* 0x99 */ CHAN_C | NONEOS_C,
737 /* 0x9A */ CHAN_C | NONEOS_C,
738 /* 0x9B */ CHAN_C | NONEOS_C,
739 /* 0x9C */ CHAN_C | NONEOS_C,
740 /* 0x9D */ CHAN_C | NONEOS_C,
741 /* 0x9E */ CHAN_C | NONEOS_C,
742 /* 0x9F */ CHAN_C | NONEOS_C,
743 /* 0xA0 */ CHAN_C | FCHAN_C | NONEOS_C,
744 /* 0xA1 */ CHAN_C | NONEOS_C,
745 /* 0xA2 */ CHAN_C | NONEOS_C,
746 /* 0xA3 */ CHAN_C | NONEOS_C,
747 /* 0xA4 */ CHAN_C | NONEOS_C,
748 /* 0xA5 */ CHAN_C | NONEOS_C,
749 /* 0xA6 */ CHAN_C | NONEOS_C,
750 /* 0xA7 */ CHAN_C | NONEOS_C,
751 /* 0xA8 */ CHAN_C | NONEOS_C,
752 /* 0xA9 */ CHAN_C | NONEOS_C,
753 /* 0xAA */ CHAN_C | NONEOS_C,
754 /* 0xAB */ CHAN_C | NONEOS_C,
755 /* 0xAC */ CHAN_C | NONEOS_C,
756 /* 0xAD */ CHAN_C | NONEOS_C,
757 /* 0xAE */ CHAN_C | NONEOS_C,
758 /* 0xAF */ CHAN_C | NONEOS_C,
759 /* 0xB0 */ CHAN_C | NONEOS_C,
760 /* 0xB1 */ CHAN_C | NONEOS_C,
761 /* 0xB2 */ CHAN_C | NONEOS_C,
762 /* 0xB3 */ CHAN_C | NONEOS_C,
763 /* 0xB4 */ CHAN_C | NONEOS_C,
764 /* 0xB5 */ CHAN_C | NONEOS_C,
765 /* 0xB6 */ CHAN_C | NONEOS_C,
766 /* 0xB7 */ CHAN_C | NONEOS_C,
767 /* 0xB8 */ CHAN_C | NONEOS_C,
768 /* 0xB9 */ CHAN_C | NONEOS_C,
769 /* 0xBA */ CHAN_C | NONEOS_C,
770 /* 0xBB */ CHAN_C | NONEOS_C,
771 /* 0xBC */ CHAN_C | NONEOS_C,
772 /* 0xBD */ CHAN_C | NONEOS_C,
773 /* 0xBE */ CHAN_C | NONEOS_C,
774 /* 0xBF */ CHAN_C | NONEOS_C,
775 /* 0xC0 */ CHAN_C | NONEOS_C,
776 /* 0xC1 */ CHAN_C | NONEOS_C,
777 /* 0xC2 */ CHAN_C | NONEOS_C,
778 /* 0xC3 */ CHAN_C | NONEOS_C,
779 /* 0xC4 */ CHAN_C | NONEOS_C,
780 /* 0xC5 */ CHAN_C | NONEOS_C,
781 /* 0xC6 */ CHAN_C | NONEOS_C,
782 /* 0xC7 */ CHAN_C | NONEOS_C,
783 /* 0xC8 */ CHAN_C | NONEOS_C,
784 /* 0xC9 */ CHAN_C | NONEOS_C,
785 /* 0xCA */ CHAN_C | NONEOS_C,
786 /* 0xCB */ CHAN_C | NONEOS_C,
787 /* 0xCC */ CHAN_C | NONEOS_C,
788 /* 0xCD */ CHAN_C | NONEOS_C,
789 /* 0xCE */ CHAN_C | NONEOS_C,
790 /* 0xCF */ CHAN_C | NONEOS_C,
791 /* 0xD0 */ CHAN_C | NONEOS_C,
792 /* 0xD1 */ CHAN_C | NONEOS_C,
793 /* 0xD2 */ CHAN_C | NONEOS_C,
794 /* 0xD3 */ CHAN_C | NONEOS_C,
795 /* 0xD4 */ CHAN_C | NONEOS_C,
796 /* 0xD5 */ CHAN_C | NONEOS_C,
797 /* 0xD6 */ CHAN_C | NONEOS_C,
798 /* 0xD7 */ CHAN_C | NONEOS_C,
799 /* 0xD8 */ CHAN_C | NONEOS_C,
800 /* 0xD9 */ CHAN_C | NONEOS_C,
801 /* 0xDA */ CHAN_C | NONEOS_C,
802 /* 0xDB */ CHAN_C | NONEOS_C,
803 /* 0xDC */ CHAN_C | NONEOS_C,
804 /* 0xDD */ CHAN_C | NONEOS_C,
805 /* 0xDE */ CHAN_C | NONEOS_C,
806 /* 0xDF */ CHAN_C | NONEOS_C,
807 /* 0xE0 */ CHAN_C | NONEOS_C,
808 /* 0xE1 */ CHAN_C | NONEOS_C,
809 /* 0xE2 */ CHAN_C | NONEOS_C,
810 /* 0xE3 */ CHAN_C | NONEOS_C,
811 /* 0xE4 */ CHAN_C | NONEOS_C,
812 /* 0xE5 */ CHAN_C | NONEOS_C,
813 /* 0xE6 */ CHAN_C | NONEOS_C,
814 /* 0xE7 */ CHAN_C | NONEOS_C,
815 /* 0xE8 */ CHAN_C | NONEOS_C,
816 /* 0xE9 */ CHAN_C | NONEOS_C,
817 /* 0xEA */ CHAN_C | NONEOS_C,
818 /* 0xEB */ CHAN_C | NONEOS_C,
819 /* 0xEC */ CHAN_C | NONEOS_C,
820 /* 0xED */ CHAN_C | NONEOS_C,
821 /* 0xEE */ CHAN_C | NONEOS_C,
822 /* 0xEF */ CHAN_C | NONEOS_C,
823 /* 0xF0 */ CHAN_C | NONEOS_C,
824 /* 0xF1 */ CHAN_C | NONEOS_C,
825 /* 0xF2 */ CHAN_C | NONEOS_C,
826 /* 0xF3 */ CHAN_C | NONEOS_C,
827 /* 0xF4 */ CHAN_C | NONEOS_C,
828 /* 0xF5 */ CHAN_C | NONEOS_C,
829 /* 0xF6 */ CHAN_C | NONEOS_C,
830 /* 0xF7 */ CHAN_C | NONEOS_C,
831 /* 0xF8 */ CHAN_C | NONEOS_C,
832 /* 0xF9 */ CHAN_C | NONEOS_C,
833 /* 0xFA */ CHAN_C | NONEOS_C,
834 /* 0xFB */ CHAN_C | NONEOS_C,
835 /* 0xFC */ CHAN_C | NONEOS_C,
836 /* 0xFD */ CHAN_C | NONEOS_C,
837 /* 0xFE */ CHAN_C | NONEOS_C,
838 /* 0xFF */ CHAN_C | NONEOS_C