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)
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.
28 * Compare if a given string (name) matches the given
29 * mask (which can contain wild cards: '*' - match any
30 * number of chars, '?' - match any single character.
35 * Originally by Douglas A Lewis (dalewis@acsu.buffalo.edu)
36 * Rewritten by Timothy Vogelsang (netski), net@astrolink.org
39 /** Check a string against a mask.
40 * This test checks using traditional IRC wildcards only: '*' means
41 * match zero or more characters of any type; '?' means match exactly
42 * one character of any type.
44 * @param[in] mask Wildcard-containing mask.
45 * @param[in] name String to check against \a mask.
46 * @return Zero if \a mask matches \a name, non-zero if no match.
48 int match(const char *mask
, const char *name
)
50 const char *m
= mask
, *n
= name
;
51 const char *m_tmp
= mask
, *n_tmp
= name
;
54 s_assert(mask
!= NULL
);
55 s_assert(name
!= NULL
);
72 for (star_p
= 0;; m
++)
91 for (n_tmp
= n
; *n
&& irctolower(*n
) != irctolower(*m
); n
++);
94 /* and fall through */
97 return (*m
!= '\0' ? 0 : 1);
98 if (irctolower(*m
) != irctolower(*n
))
107 /** Check a mask against a mask.
108 * This test checks using traditional IRC wildcards only: '*' means
109 * match zero or more characters of any type; '?' means match exactly
110 * one character of any type.
111 * The difference between mask_match() and match() is that in mask_match()
112 * a '?' in mask does not match a '*' in name.
114 * @param[in] mask Existing wildcard-containing mask.
115 * @param[in] name New wildcard-containing mask.
116 * @return 1 if \a name is equal to or more specific than \a mask, 0 otherwise.
118 int mask_match(const char *mask
, const char *name
)
120 const char *m
= mask
, *n
= name
;
121 const char *m_tmp
= mask
, *n_tmp
= name
;
124 s_assert(mask
!= NULL
);
125 s_assert(name
!= NULL
);
142 for (star_p
= 0;; m
++)
148 /* changed for mask_match() */
149 if (*n
== '*' || !*n
)
163 for (n_tmp
= n
; *n
&& irctolower(*n
) != irctolower(*m
); n
++);
166 /* and fall through */
169 return (*m
!= '\0' ? 0 : 1);
170 if (irctolower(*m
) != irctolower(*n
))
180 #define MATCH_MAX_CALLS 512 /* ACK! This dies when it's less that this
181 and we have long lines to parse */
182 /** Check a string against a mask.
183 * This test checks using extended wildcards: '*' means match zero
184 * or more characters of any type; '?' means match exactly one
185 * character of any type; '#' means match exactly one character that
186 * is a number; '@' means match exactly one character that is a
187 * letter; '\s' means match a space.
189 * This function supports escaping, so that a wildcard may be matched
192 * @param[in] mask Wildcard-containing mask.
193 * @param[in] name String to check against \a mask.
194 * @return Zero if \a mask matches \a name, non-zero if no match.
197 match_esc(const char *mask
, const char *name
)
199 const unsigned char *m
= (const unsigned char *)mask
;
200 const unsigned char *n
= (const unsigned char *)name
;
201 const unsigned char *ma
= (const unsigned char *)mask
;
202 const unsigned char *na
= (const unsigned char *)name
;
208 s_assert(mask
!= NULL
);
209 s_assert(name
!= NULL
);
214 /* if the mask is "*", it matches everything */
215 if((*m
== '*') && (*(m
+ 1) == '\0'))
218 while(calls
++ < MATCH_MAX_CALLS
)
224 if(*m
== '\\' && !quote
)
230 if(!quote
&& *m
== '*')
233 * XXX - shouldn't need to spin here, the mask should have been
234 * collapsed before match is called
246 /* This means it is an invalid mask -A1kmm. */
260 for(m
--; (m
> (const unsigned char *)mask
) && (*m
== '?'); m
--)
263 if(*m
== '*' && (m
> (const unsigned char *)mask
))
273 * XXX - shouldn't need to spin here, the mask should have been
274 * collapsed before match is called
284 match1
= *m
== 's' ? *n
== ' ' : irctolower(*m
) == irctolower(*n
);
288 match1
= IsLetter(*n
);
290 match1
= IsDigit(*n
);
292 match1
= irctolower(*m
) == irctolower(*n
);
311 int comp_with_mask(void *addr
, void *dest
, unsigned int mask
)
313 if (memcmp(addr
, dest
, mask
/ 8) == 0)
316 int m
= ((-1) << (8 - (mask
% 8)));
317 if (mask
% 8 == 0 || (((unsigned char *) addr
)[n
] & m
) == (((unsigned char *) dest
)[n
] & m
))
325 int comp_with_mask_sock(struct sockaddr
*addr
, struct sockaddr
*dest
, unsigned int mask
)
330 if (addr
->sa_family
== AF_INET
)
332 iaddr
= &((struct sockaddr_in
*)(void *)addr
)->sin_addr
;
333 idest
= &((struct sockaddr_in
*)(void *)dest
)->sin_addr
;
338 iaddr
= &((struct sockaddr_in6
*)(void *)addr
)->sin6_addr
;
339 idest
= &((struct sockaddr_in6
*)(void *)dest
)->sin6_addr
;
344 return (comp_with_mask(iaddr
, idest
, mask
));
350 * Input - cidr ip mask, address
352 int match_ips(const char *s1
, const char *s2
)
354 struct rb_sockaddr_storage ipaddr
, maskaddr
;
356 char address
[HOSTLEN
+ 1];
358 void *ipptr
, *maskptr
;
361 rb_strlcpy(mask
, s1
, sizeof(mask
));
362 rb_strlcpy(address
, s2
, sizeof(address
));
364 len
= strrchr(mask
, '/');
375 if (strchr(mask
, ':') && strchr(address
, ':'))
381 ipptr
= &((struct sockaddr_in6
*)&ipaddr
)->sin6_addr
;
382 maskptr
= &((struct sockaddr_in6
*)&maskaddr
)->sin6_addr
;
386 if (!strchr(mask
, ':') && !strchr(address
, ':'))
392 ipptr
= &((struct sockaddr_in
*)&ipaddr
)->sin_addr
;
393 maskptr
= &((struct sockaddr_in
*)&maskaddr
)->sin_addr
;
398 if (rb_inet_pton(aftype
, address
, ipptr
) <= 0)
400 if (rb_inet_pton(aftype
, mask
, maskptr
) <= 0)
402 if (comp_with_mask(ipptr
, maskptr
, cidrlen
))
410 * Input - mask, address
411 * Ouput - 1 = Matched 0 = Did not match
414 int match_cidr(const char *s1
, const char *s2
)
416 struct rb_sockaddr_storage ipaddr
, maskaddr
;
418 char address
[NICKLEN
+ USERLEN
+ HOSTLEN
+ 6];
422 void *ipptr
, *maskptr
;
425 rb_strlcpy(mask
, s1
, sizeof(mask
));
426 rb_strlcpy(address
, s2
, sizeof(address
));
428 ipmask
= strrchr(mask
, '@');
434 ip
= strrchr(address
, '@');
440 len
= strrchr(ipmask
, '/');
451 if (strchr(ip
, ':') && strchr(ipmask
, ':'))
457 ipptr
= &((struct sockaddr_in6
*)&ipaddr
)->sin6_addr
;
458 maskptr
= &((struct sockaddr_in6
*)&maskaddr
)->sin6_addr
;
462 if (!strchr(ip
, ':') && !strchr(ipmask
, ':'))
468 ipptr
= &((struct sockaddr_in
*)&ipaddr
)->sin_addr
;
469 maskptr
= &((struct sockaddr_in
*)&maskaddr
)->sin_addr
;
474 if (rb_inet_pton(aftype
, ip
, ipptr
) <= 0)
476 if (rb_inet_pton(aftype
, ipmask
, maskptr
) <= 0)
478 if (comp_with_mask(ipptr
, maskptr
, cidrlen
) && match(mask
, address
))
486 * collapses a string containing multiple *'s.
488 char *collapse(char *pattern
)
490 char *p
= pattern
, *po
= pattern
;
518 * The collapse() function with support for escaping characters
520 char *collapse_esc(char *pattern
)
522 char *p
= pattern
, *po
= pattern
;
531 if (!(f
& 2) && c
== '*')
537 else if (!(f
& 2) && c
== '\\')
553 * irccmp - case insensitive comparison of two 0 terminated strings.
555 * returns 0, if s1 equal to s2
556 * <0, if s1 lexicographically less than s2
557 * >0, if s1 lexicographically greater than s2
559 int irccmp(const char *s1
, const char *s2
)
561 const unsigned char *str1
= (const unsigned char *)s1
;
562 const unsigned char *str2
= (const unsigned char *)s2
;
565 s_assert(s1
!= NULL
);
566 s_assert(s2
!= NULL
);
568 while ((res
= irctoupper(*str1
) - irctoupper(*str2
)) == 0)
578 int ircncmp(const char *s1
, const char *s2
, int n
)
580 const unsigned char *str1
= (const unsigned char *)s1
;
581 const unsigned char *str2
= (const unsigned char *)s2
;
583 s_assert(s1
!= NULL
);
584 s_assert(s2
!= NULL
);
586 while ((res
= irctoupper(*str1
) - irctoupper(*str2
)) == 0)
591 if (n
== 0 || (*str1
== '\0' && *str2
== '\0'))
597 const unsigned char irctolower_tab
[] = {
598 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
599 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
600 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
602 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
603 '*', '+', ',', '-', '.', '/',
604 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
605 ':', ';', '<', '=', '>', '?',
606 '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
607 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
608 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
610 '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
611 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
612 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
614 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
615 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
616 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
617 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
618 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
619 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
620 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
621 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
622 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
623 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
624 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
625 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
626 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
627 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
628 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
629 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
632 const unsigned char irctoupper_tab
[] = {
633 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
634 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
635 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
637 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
638 '*', '+', ',', '-', '.', '/',
639 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
640 ':', ';', '<', '=', '>', '?',
641 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
642 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
643 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
645 '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
646 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
647 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
649 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
650 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
651 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
652 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
653 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
654 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
655 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
656 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
657 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
658 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
659 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
660 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
661 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
662 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
663 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
664 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
670 * NOTE: RFC 1459 sez: anything but a ^G, comma, or space is allowed
673 const unsigned int CharAttrs
[] = {
675 /* 1 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
676 /* 2 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
677 /* 3 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
678 /* 4 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
679 /* 5 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
680 /* 6 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
681 /* 7 BEL */ CNTRL_C
| NONEOS_C
,
682 /* 8 \b */ CNTRL_C
| CHAN_C
| NONEOS_C
,
683 /* 9 \t */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
,
684 /* 10 \n */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
| EOL_C
,
685 /* 11 \v */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
,
686 /* 12 \f */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
,
687 /* 13 \r */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
| EOL_C
,
688 /* 14 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
689 /* 15 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
690 /* 16 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
691 /* 17 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
692 /* 18 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
693 /* 19 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
694 /* 20 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
695 /* 21 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
696 /* 22 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
697 /* 23 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
698 /* 24 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
699 /* 25 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
700 /* 26 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
701 /* 27 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
702 /* 28 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
703 /* 29 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
704 /* 30 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
705 /* 31 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
706 /* SP */ PRINT_C
| SPACE_C
,
707 /* ! */ PRINT_C
| KWILD_C
| CHAN_C
| NONEOS_C
,
708 /* " */ PRINT_C
| CHAN_C
| NONEOS_C
,
709 /* # */ PRINT_C
| MWILD_C
| CHANPFX_C
| CHAN_C
| NONEOS_C
,
710 /* $ */ PRINT_C
| CHAN_C
| NONEOS_C
,
711 /* % */ PRINT_C
| CHAN_C
| NONEOS_C
,
712 /* & */ PRINT_C
| CHANPFX_C
| CHAN_C
| NONEOS_C
,
713 /* ' */ PRINT_C
| CHAN_C
| NONEOS_C
,
714 /* ( */ PRINT_C
| CHAN_C
| NONEOS_C
,
715 /* ) */ PRINT_C
| CHAN_C
| NONEOS_C
,
716 /* * */ PRINT_C
| KWILD_C
| MWILD_C
| CHAN_C
| NONEOS_C
,
717 /* + */ PRINT_C
| CHAN_C
| NONEOS_C
,
718 /* , */ PRINT_C
| NONEOS_C
,
719 /* - */ PRINT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
720 /* . */ PRINT_C
| KWILD_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
| SERV_C
,
721 /* / */ PRINT_C
| CHAN_C
| NONEOS_C
| HOST_C
,
722 /* 0 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
723 /* 1 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
724 /* 2 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
725 /* 3 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
726 /* 4 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
727 /* 5 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
728 /* 6 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
729 /* 7 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
730 /* 8 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
731 /* 9 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
732 /* : */ PRINT_C
| CHAN_C
| NONEOS_C
| HOST_C
,
733 /* ; */ PRINT_C
| CHAN_C
| NONEOS_C
,
734 /* < */ PRINT_C
| CHAN_C
| NONEOS_C
,
735 /* = */ PRINT_C
| CHAN_C
| NONEOS_C
,
736 /* > */ PRINT_C
| CHAN_C
| NONEOS_C
,
737 /* ? */ PRINT_C
| KWILD_C
| MWILD_C
| CHAN_C
| NONEOS_C
,
738 /* @ */ PRINT_C
| KWILD_C
| MWILD_C
| CHAN_C
| NONEOS_C
,
739 /* A */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
740 /* B */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
741 /* C */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
742 /* D */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
743 /* E */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
744 /* F */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
745 /* G */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
746 /* H */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
747 /* I */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
748 /* J */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
749 /* K */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
750 /* L */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
751 /* M */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
752 /* N */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
753 /* O */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
754 /* P */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
755 /* Q */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
756 /* R */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
757 /* S */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
758 /* T */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
759 /* U */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
760 /* V */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
761 /* W */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
762 /* X */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
763 /* Y */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
764 /* Z */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
765 /* [ */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
766 /* \ */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
767 /* ] */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
768 /* ^ */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
769 /* _ */ PRINT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
770 /* ` */ PRINT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
771 /* a */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
772 /* b */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
773 /* c */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
774 /* d */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
775 /* e */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
776 /* f */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
777 /* g */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
778 /* h */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
779 /* i */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
780 /* j */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
781 /* k */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
782 /* l */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
783 /* m */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
784 /* n */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
785 /* o */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
786 /* p */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
787 /* q */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
788 /* r */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
789 /* s */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
790 /* t */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
791 /* u */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
792 /* v */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
793 /* w */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
794 /* x */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
795 /* y */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
796 /* z */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
797 /* { */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
798 /* | */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
799 /* } */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
800 /* ~ */ PRINT_C
| ALPHA_C
| CHAN_C
| NONEOS_C
| USER_C
,
801 /* del */ CHAN_C
| NONEOS_C
,
802 /* 0x80 */ CHAN_C
| NONEOS_C
,
803 /* 0x81 */ CHAN_C
| NONEOS_C
,
804 /* 0x82 */ CHAN_C
| NONEOS_C
,
805 /* 0x83 */ CHAN_C
| NONEOS_C
,
806 /* 0x84 */ CHAN_C
| NONEOS_C
,
807 /* 0x85 */ CHAN_C
| NONEOS_C
,
808 /* 0x86 */ CHAN_C
| NONEOS_C
,
809 /* 0x87 */ CHAN_C
| NONEOS_C
,
810 /* 0x88 */ CHAN_C
| NONEOS_C
,
811 /* 0x89 */ CHAN_C
| NONEOS_C
,
812 /* 0x8A */ CHAN_C
| NONEOS_C
,
813 /* 0x8B */ CHAN_C
| NONEOS_C
,
814 /* 0x8C */ CHAN_C
| NONEOS_C
,
815 /* 0x8D */ CHAN_C
| NONEOS_C
,
816 /* 0x8E */ CHAN_C
| NONEOS_C
,
817 /* 0x8F */ CHAN_C
| NONEOS_C
,
818 /* 0x90 */ CHAN_C
| NONEOS_C
,
819 /* 0x91 */ CHAN_C
| NONEOS_C
,
820 /* 0x92 */ CHAN_C
| NONEOS_C
,
821 /* 0x93 */ CHAN_C
| NONEOS_C
,
822 /* 0x94 */ CHAN_C
| NONEOS_C
,
823 /* 0x95 */ CHAN_C
| NONEOS_C
,
824 /* 0x96 */ CHAN_C
| NONEOS_C
,
825 /* 0x97 */ CHAN_C
| NONEOS_C
,
826 /* 0x98 */ CHAN_C
| NONEOS_C
,
827 /* 0x99 */ CHAN_C
| NONEOS_C
,
828 /* 0x9A */ CHAN_C
| NONEOS_C
,
829 /* 0x9B */ CHAN_C
| NONEOS_C
,
830 /* 0x9C */ CHAN_C
| NONEOS_C
,
831 /* 0x9D */ CHAN_C
| NONEOS_C
,
832 /* 0x9E */ CHAN_C
| NONEOS_C
,
833 /* 0x9F */ CHAN_C
| NONEOS_C
,
834 /* 0xA0 */ CHAN_C
| FCHAN_C
| NONEOS_C
,
835 /* 0xA1 */ CHAN_C
| NONEOS_C
,
836 /* 0xA2 */ CHAN_C
| NONEOS_C
,
837 /* 0xA3 */ CHAN_C
| NONEOS_C
,
838 /* 0xA4 */ CHAN_C
| NONEOS_C
,
839 /* 0xA5 */ CHAN_C
| NONEOS_C
,
840 /* 0xA6 */ CHAN_C
| NONEOS_C
,
841 /* 0xA7 */ CHAN_C
| NONEOS_C
,
842 /* 0xA8 */ CHAN_C
| NONEOS_C
,
843 /* 0xA9 */ CHAN_C
| NONEOS_C
,
844 /* 0xAA */ CHAN_C
| NONEOS_C
,
845 /* 0xAB */ CHAN_C
| NONEOS_C
,
846 /* 0xAC */ CHAN_C
| NONEOS_C
,
847 /* 0xAD */ CHAN_C
| NONEOS_C
,
848 /* 0xAE */ CHAN_C
| NONEOS_C
,
849 /* 0xAF */ CHAN_C
| NONEOS_C
,
850 /* 0xB0 */ CHAN_C
| NONEOS_C
,
851 /* 0xB1 */ CHAN_C
| NONEOS_C
,
852 /* 0xB2 */ CHAN_C
| NONEOS_C
,
853 /* 0xB3 */ CHAN_C
| NONEOS_C
,
854 /* 0xB4 */ CHAN_C
| NONEOS_C
,
855 /* 0xB5 */ CHAN_C
| NONEOS_C
,
856 /* 0xB6 */ CHAN_C
| NONEOS_C
,
857 /* 0xB7 */ CHAN_C
| NONEOS_C
,
858 /* 0xB8 */ CHAN_C
| NONEOS_C
,
859 /* 0xB9 */ CHAN_C
| NONEOS_C
,
860 /* 0xBA */ CHAN_C
| NONEOS_C
,
861 /* 0xBB */ CHAN_C
| NONEOS_C
,
862 /* 0xBC */ CHAN_C
| NONEOS_C
,
863 /* 0xBD */ CHAN_C
| NONEOS_C
,
864 /* 0xBE */ CHAN_C
| NONEOS_C
,
865 /* 0xBF */ CHAN_C
| NONEOS_C
,
866 /* 0xC0 */ CHAN_C
| NONEOS_C
,
867 /* 0xC1 */ CHAN_C
| NONEOS_C
,
868 /* 0xC2 */ CHAN_C
| NONEOS_C
,
869 /* 0xC3 */ CHAN_C
| NONEOS_C
,
870 /* 0xC4 */ CHAN_C
| NONEOS_C
,
871 /* 0xC5 */ CHAN_C
| NONEOS_C
,
872 /* 0xC6 */ CHAN_C
| NONEOS_C
,
873 /* 0xC7 */ CHAN_C
| NONEOS_C
,
874 /* 0xC8 */ CHAN_C
| NONEOS_C
,
875 /* 0xC9 */ CHAN_C
| NONEOS_C
,
876 /* 0xCA */ CHAN_C
| NONEOS_C
,
877 /* 0xCB */ CHAN_C
| NONEOS_C
,
878 /* 0xCC */ CHAN_C
| NONEOS_C
,
879 /* 0xCD */ CHAN_C
| NONEOS_C
,
880 /* 0xCE */ CHAN_C
| NONEOS_C
,
881 /* 0xCF */ CHAN_C
| NONEOS_C
,
882 /* 0xD0 */ CHAN_C
| NONEOS_C
,
883 /* 0xD1 */ CHAN_C
| NONEOS_C
,
884 /* 0xD2 */ CHAN_C
| NONEOS_C
,
885 /* 0xD3 */ CHAN_C
| NONEOS_C
,
886 /* 0xD4 */ CHAN_C
| NONEOS_C
,
887 /* 0xD5 */ CHAN_C
| NONEOS_C
,
888 /* 0xD6 */ CHAN_C
| NONEOS_C
,
889 /* 0xD7 */ CHAN_C
| NONEOS_C
,
890 /* 0xD8 */ CHAN_C
| NONEOS_C
,
891 /* 0xD9 */ CHAN_C
| NONEOS_C
,
892 /* 0xDA */ CHAN_C
| NONEOS_C
,
893 /* 0xDB */ CHAN_C
| NONEOS_C
,
894 /* 0xDC */ CHAN_C
| NONEOS_C
,
895 /* 0xDD */ CHAN_C
| NONEOS_C
,
896 /* 0xDE */ CHAN_C
| NONEOS_C
,
897 /* 0xDF */ CHAN_C
| NONEOS_C
,
898 /* 0xE0 */ CHAN_C
| NONEOS_C
,
899 /* 0xE1 */ CHAN_C
| NONEOS_C
,
900 /* 0xE2 */ CHAN_C
| NONEOS_C
,
901 /* 0xE3 */ CHAN_C
| NONEOS_C
,
902 /* 0xE4 */ CHAN_C
| NONEOS_C
,
903 /* 0xE5 */ CHAN_C
| NONEOS_C
,
904 /* 0xE6 */ CHAN_C
| NONEOS_C
,
905 /* 0xE7 */ CHAN_C
| NONEOS_C
,
906 /* 0xE8 */ CHAN_C
| NONEOS_C
,
907 /* 0xE9 */ CHAN_C
| NONEOS_C
,
908 /* 0xEA */ CHAN_C
| NONEOS_C
,
909 /* 0xEB */ CHAN_C
| NONEOS_C
,
910 /* 0xEC */ CHAN_C
| NONEOS_C
,
911 /* 0xED */ CHAN_C
| NONEOS_C
,
912 /* 0xEE */ CHAN_C
| NONEOS_C
,
913 /* 0xEF */ CHAN_C
| NONEOS_C
,
914 /* 0xF0 */ CHAN_C
| NONEOS_C
,
915 /* 0xF1 */ CHAN_C
| NONEOS_C
,
916 /* 0xF2 */ CHAN_C
| NONEOS_C
,
917 /* 0xF3 */ CHAN_C
| NONEOS_C
,
918 /* 0xF4 */ CHAN_C
| NONEOS_C
,
919 /* 0xF5 */ CHAN_C
| NONEOS_C
,
920 /* 0xF6 */ CHAN_C
| NONEOS_C
,
921 /* 0xF7 */ CHAN_C
| NONEOS_C
,
922 /* 0xF8 */ CHAN_C
| NONEOS_C
,
923 /* 0xF9 */ CHAN_C
| NONEOS_C
,
924 /* 0xFA */ CHAN_C
| NONEOS_C
,
925 /* 0xFB */ CHAN_C
| NONEOS_C
,
926 /* 0xFC */ CHAN_C
| NONEOS_C
,
927 /* 0xFD */ CHAN_C
| NONEOS_C
,
928 /* 0xFE */ CHAN_C
| NONEOS_C
,
929 /* 0xFF */ CHAN_C
| NONEOS_C