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 unsigned char m
= (0xFF << (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
;
337 iaddr
= &((struct sockaddr_in6
*)(void *)addr
)->sin6_addr
;
338 idest
= &((struct sockaddr_in6
*)(void *)dest
)->sin6_addr
;
342 return (comp_with_mask(iaddr
, idest
, mask
));
348 * Input - cidr ip mask, address
350 int match_ips(const char *s1
, const char *s2
)
352 struct rb_sockaddr_storage ipaddr
, maskaddr
;
354 char address
[HOSTLEN
+ 1];
356 void *ipptr
, *maskptr
;
359 rb_strlcpy(mask
, s1
, sizeof(mask
));
360 rb_strlcpy(address
, s2
, sizeof(address
));
362 len
= strrchr(mask
, '/');
372 if (strchr(mask
, ':') && strchr(address
, ':'))
378 ipptr
= &((struct sockaddr_in6
*)&ipaddr
)->sin6_addr
;
379 maskptr
= &((struct sockaddr_in6
*)&maskaddr
)->sin6_addr
;
381 else if (!strchr(mask
, ':') && !strchr(address
, ':'))
387 ipptr
= &((struct sockaddr_in
*)&ipaddr
)->sin_addr
;
388 maskptr
= &((struct sockaddr_in
*)&maskaddr
)->sin_addr
;
393 if (rb_inet_pton(aftype
, address
, ipptr
) <= 0)
395 if (rb_inet_pton(aftype
, mask
, maskptr
) <= 0)
397 if (comp_with_mask(ipptr
, maskptr
, cidrlen
))
405 * Input - mask, address
406 * Ouput - 1 = Matched 0 = Did not match
409 int match_cidr(const char *s1
, const char *s2
)
411 struct rb_sockaddr_storage ipaddr
, maskaddr
;
413 char address
[NICKLEN
+ USERLEN
+ HOSTLEN
+ 6];
417 void *ipptr
, *maskptr
;
420 rb_strlcpy(mask
, s1
, sizeof(mask
));
421 rb_strlcpy(address
, s2
, sizeof(address
));
423 ipmask
= strrchr(mask
, '@');
429 ip
= strrchr(address
, '@');
435 len
= strrchr(ipmask
, '/');
445 if (strchr(ip
, ':') && strchr(ipmask
, ':'))
451 ipptr
= &((struct sockaddr_in6
*)&ipaddr
)->sin6_addr
;
452 maskptr
= &((struct sockaddr_in6
*)&maskaddr
)->sin6_addr
;
454 else if (!strchr(ip
, ':') && !strchr(ipmask
, ':'))
460 ipptr
= &((struct sockaddr_in
*)&ipaddr
)->sin_addr
;
461 maskptr
= &((struct sockaddr_in
*)&maskaddr
)->sin_addr
;
466 if (rb_inet_pton(aftype
, ip
, ipptr
) <= 0)
468 if (rb_inet_pton(aftype
, ipmask
, maskptr
) <= 0)
470 if (comp_with_mask(ipptr
, maskptr
, cidrlen
) && match(mask
, address
))
478 * collapses a string containing multiple *'s.
480 char *collapse(char *pattern
)
482 char *p
= pattern
, *po
= pattern
;
510 * The collapse() function with support for escaping characters
512 char *collapse_esc(char *pattern
)
514 char *p
= pattern
, *po
= pattern
;
523 if (!(f
& 2) && c
== '*')
529 else if (!(f
& 2) && c
== '\\')
545 * irccmp - case insensitive comparison of two 0 terminated strings.
547 * returns 0, if s1 equal to s2
548 * <0, if s1 lexicographically less than s2
549 * >0, if s1 lexicographically greater than s2
551 int irccmp(const char *s1
, const char *s2
)
553 const unsigned char *str1
= (const unsigned char *)s1
;
554 const unsigned char *str2
= (const unsigned char *)s2
;
557 s_assert(s1
!= NULL
);
558 s_assert(s2
!= NULL
);
560 while ((res
= irctoupper(*str1
) - irctoupper(*str2
)) == 0)
570 int ircncmp(const char *s1
, const char *s2
, int n
)
572 const unsigned char *str1
= (const unsigned char *)s1
;
573 const unsigned char *str2
= (const unsigned char *)s2
;
575 s_assert(s1
!= NULL
);
576 s_assert(s2
!= NULL
);
578 while ((res
= irctoupper(*str1
) - irctoupper(*str2
)) == 0)
583 if (n
== 0 || (*str1
== '\0' && *str2
== '\0'))
589 const unsigned char irctolower_tab
[] = {
590 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
591 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
592 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
594 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
595 '*', '+', ',', '-', '.', '/',
596 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
597 ':', ';', '<', '=', '>', '?',
598 '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
599 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
600 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
602 '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
603 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
604 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
606 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
607 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
608 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
609 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
610 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
611 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
612 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
613 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
614 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
615 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
616 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
617 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
618 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
619 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
620 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
621 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
624 const unsigned char irctoupper_tab
[] = {
625 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
626 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
627 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
629 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
630 '*', '+', ',', '-', '.', '/',
631 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
632 ':', ';', '<', '=', '>', '?',
633 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
634 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
635 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
637 '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
638 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
639 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
641 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
642 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
643 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
644 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
645 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
646 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
647 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
648 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
649 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
650 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
651 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
652 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
653 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
654 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
655 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
656 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
662 * NOTE: RFC 1459 sez: anything but a ^G, comma, or space is allowed
665 unsigned int CharAttrs
[] = {
667 /* 1 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
668 /* 2 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
669 /* 3 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
670 /* 4 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
671 /* 5 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
672 /* 6 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
673 /* 7 BEL */ CNTRL_C
| NONEOS_C
,
674 /* 8 \b */ CNTRL_C
| CHAN_C
| NONEOS_C
,
675 /* 9 \t */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
,
676 /* 10 \n */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
| EOL_C
,
677 /* 11 \v */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
,
678 /* 12 \f */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
,
679 /* 13 \r */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
| EOL_C
,
680 /* 14 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
681 /* 15 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
682 /* 16 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
683 /* 17 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
684 /* 18 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
685 /* 19 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
686 /* 20 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
687 /* 21 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
688 /* 22 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
689 /* 23 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
690 /* 24 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
691 /* 25 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
692 /* 26 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
693 /* 27 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
694 /* 28 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
695 /* 29 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
696 /* 30 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
697 /* 31 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
698 /* SP */ PRINT_C
| SPACE_C
,
699 /* ! */ PRINT_C
| KWILD_C
| CHAN_C
| NONEOS_C
,
700 /* " */ PRINT_C
| CHAN_C
| NONEOS_C
,
701 /* # */ PRINT_C
| MWILD_C
| CHANPFX_C
| CHAN_C
| NONEOS_C
,
702 /* $ */ PRINT_C
| CHAN_C
| NONEOS_C
,
703 /* % */ PRINT_C
| CHAN_C
| NONEOS_C
,
704 /* & */ PRINT_C
| CHANPFX_C
| CHAN_C
| NONEOS_C
,
705 /* ' */ PRINT_C
| CHAN_C
| NONEOS_C
,
706 /* ( */ PRINT_C
| CHAN_C
| NONEOS_C
,
707 /* ) */ PRINT_C
| CHAN_C
| NONEOS_C
,
708 /* * */ PRINT_C
| KWILD_C
| MWILD_C
| CHAN_C
| NONEOS_C
,
709 /* + */ PRINT_C
| CHAN_C
| NONEOS_C
,
710 /* , */ PRINT_C
| NONEOS_C
,
711 /* - */ PRINT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
712 /* . */ PRINT_C
| KWILD_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
| SERV_C
,
713 /* / */ PRINT_C
| CHAN_C
| NONEOS_C
| HOST_C
,
714 /* 0 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
715 /* 1 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
716 /* 2 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
717 /* 3 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
718 /* 4 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
719 /* 5 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
720 /* 6 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
721 /* 7 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
722 /* 8 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
723 /* 9 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
724 /* : */ PRINT_C
| CHAN_C
| NONEOS_C
| HOST_C
,
725 /* ; */ PRINT_C
| CHAN_C
| NONEOS_C
,
726 /* < */ PRINT_C
| CHAN_C
| NONEOS_C
,
727 /* = */ PRINT_C
| CHAN_C
| NONEOS_C
,
728 /* > */ PRINT_C
| CHAN_C
| NONEOS_C
,
729 /* ? */ PRINT_C
| KWILD_C
| MWILD_C
| CHAN_C
| NONEOS_C
,
730 /* @ */ PRINT_C
| KWILD_C
| MWILD_C
| CHAN_C
| NONEOS_C
,
731 /* A */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
732 /* B */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
733 /* C */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
734 /* D */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
735 /* E */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
736 /* F */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
737 /* G */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
738 /* H */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
739 /* I */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
740 /* J */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
741 /* K */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
742 /* L */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
743 /* M */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
744 /* N */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
745 /* O */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
746 /* P */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
747 /* Q */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
748 /* R */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
749 /* S */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
750 /* T */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
751 /* U */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
752 /* V */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
753 /* W */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
754 /* X */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
755 /* Y */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
756 /* Z */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
757 /* [ */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
758 /* \ */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
759 /* ] */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
760 /* ^ */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
761 /* _ */ PRINT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
762 /* ` */ PRINT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
763 /* a */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
764 /* b */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
765 /* c */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
766 /* d */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
767 /* e */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
768 /* f */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
769 /* g */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
770 /* h */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
771 /* i */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
772 /* j */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
773 /* k */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
774 /* l */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
775 /* m */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
776 /* n */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
777 /* o */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
778 /* p */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
779 /* q */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
780 /* r */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
781 /* s */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
782 /* t */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
783 /* u */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
784 /* v */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
785 /* w */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
786 /* x */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
787 /* y */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
788 /* z */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
789 /* { */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
790 /* | */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
791 /* } */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
792 /* ~ */ PRINT_C
| ALPHA_C
| CHAN_C
| NONEOS_C
| USER_C
,
793 /* del */ CHAN_C
| NONEOS_C
,
794 /* 0x80 */ CHAN_C
| NONEOS_C
,
795 /* 0x81 */ CHAN_C
| NONEOS_C
,
796 /* 0x82 */ CHAN_C
| NONEOS_C
,
797 /* 0x83 */ CHAN_C
| NONEOS_C
,
798 /* 0x84 */ CHAN_C
| NONEOS_C
,
799 /* 0x85 */ CHAN_C
| NONEOS_C
,
800 /* 0x86 */ CHAN_C
| NONEOS_C
,
801 /* 0x87 */ CHAN_C
| NONEOS_C
,
802 /* 0x88 */ CHAN_C
| NONEOS_C
,
803 /* 0x89 */ CHAN_C
| NONEOS_C
,
804 /* 0x8A */ CHAN_C
| NONEOS_C
,
805 /* 0x8B */ CHAN_C
| NONEOS_C
,
806 /* 0x8C */ CHAN_C
| NONEOS_C
,
807 /* 0x8D */ CHAN_C
| NONEOS_C
,
808 /* 0x8E */ CHAN_C
| NONEOS_C
,
809 /* 0x8F */ CHAN_C
| NONEOS_C
,
810 /* 0x90 */ CHAN_C
| NONEOS_C
,
811 /* 0x91 */ CHAN_C
| NONEOS_C
,
812 /* 0x92 */ CHAN_C
| NONEOS_C
,
813 /* 0x93 */ CHAN_C
| NONEOS_C
,
814 /* 0x94 */ CHAN_C
| NONEOS_C
,
815 /* 0x95 */ CHAN_C
| NONEOS_C
,
816 /* 0x96 */ CHAN_C
| NONEOS_C
,
817 /* 0x97 */ CHAN_C
| NONEOS_C
,
818 /* 0x98 */ CHAN_C
| NONEOS_C
,
819 /* 0x99 */ CHAN_C
| NONEOS_C
,
820 /* 0x9A */ CHAN_C
| NONEOS_C
,
821 /* 0x9B */ CHAN_C
| NONEOS_C
,
822 /* 0x9C */ CHAN_C
| NONEOS_C
,
823 /* 0x9D */ CHAN_C
| NONEOS_C
,
824 /* 0x9E */ CHAN_C
| NONEOS_C
,
825 /* 0x9F */ CHAN_C
| NONEOS_C
,
826 /* 0xA0 */ CHAN_C
| FCHAN_C
| NONEOS_C
,
827 /* 0xA1 */ CHAN_C
| NONEOS_C
,
828 /* 0xA2 */ CHAN_C
| NONEOS_C
,
829 /* 0xA3 */ CHAN_C
| NONEOS_C
,
830 /* 0xA4 */ CHAN_C
| NONEOS_C
,
831 /* 0xA5 */ CHAN_C
| NONEOS_C
,
832 /* 0xA6 */ CHAN_C
| NONEOS_C
,
833 /* 0xA7 */ CHAN_C
| NONEOS_C
,
834 /* 0xA8 */ CHAN_C
| NONEOS_C
,
835 /* 0xA9 */ CHAN_C
| NONEOS_C
,
836 /* 0xAA */ CHAN_C
| NONEOS_C
,
837 /* 0xAB */ CHAN_C
| NONEOS_C
,
838 /* 0xAC */ CHAN_C
| NONEOS_C
,
839 /* 0xAD */ CHAN_C
| NONEOS_C
,
840 /* 0xAE */ CHAN_C
| NONEOS_C
,
841 /* 0xAF */ CHAN_C
| NONEOS_C
,
842 /* 0xB0 */ CHAN_C
| NONEOS_C
,
843 /* 0xB1 */ CHAN_C
| NONEOS_C
,
844 /* 0xB2 */ CHAN_C
| NONEOS_C
,
845 /* 0xB3 */ CHAN_C
| NONEOS_C
,
846 /* 0xB4 */ CHAN_C
| NONEOS_C
,
847 /* 0xB5 */ CHAN_C
| NONEOS_C
,
848 /* 0xB6 */ CHAN_C
| NONEOS_C
,
849 /* 0xB7 */ CHAN_C
| NONEOS_C
,
850 /* 0xB8 */ CHAN_C
| NONEOS_C
,
851 /* 0xB9 */ CHAN_C
| NONEOS_C
,
852 /* 0xBA */ CHAN_C
| NONEOS_C
,
853 /* 0xBB */ CHAN_C
| NONEOS_C
,
854 /* 0xBC */ CHAN_C
| NONEOS_C
,
855 /* 0xBD */ CHAN_C
| NONEOS_C
,
856 /* 0xBE */ CHAN_C
| NONEOS_C
,
857 /* 0xBF */ CHAN_C
| NONEOS_C
,
858 /* 0xC0 */ CHAN_C
| NONEOS_C
,
859 /* 0xC1 */ CHAN_C
| NONEOS_C
,
860 /* 0xC2 */ CHAN_C
| NONEOS_C
,
861 /* 0xC3 */ CHAN_C
| NONEOS_C
,
862 /* 0xC4 */ CHAN_C
| NONEOS_C
,
863 /* 0xC5 */ CHAN_C
| NONEOS_C
,
864 /* 0xC6 */ CHAN_C
| NONEOS_C
,
865 /* 0xC7 */ CHAN_C
| NONEOS_C
,
866 /* 0xC8 */ CHAN_C
| NONEOS_C
,
867 /* 0xC9 */ CHAN_C
| NONEOS_C
,
868 /* 0xCA */ CHAN_C
| NONEOS_C
,
869 /* 0xCB */ CHAN_C
| NONEOS_C
,
870 /* 0xCC */ CHAN_C
| NONEOS_C
,
871 /* 0xCD */ CHAN_C
| NONEOS_C
,
872 /* 0xCE */ CHAN_C
| NONEOS_C
,
873 /* 0xCF */ CHAN_C
| NONEOS_C
,
874 /* 0xD0 */ CHAN_C
| NONEOS_C
,
875 /* 0xD1 */ CHAN_C
| NONEOS_C
,
876 /* 0xD2 */ CHAN_C
| NONEOS_C
,
877 /* 0xD3 */ CHAN_C
| NONEOS_C
,
878 /* 0xD4 */ CHAN_C
| NONEOS_C
,
879 /* 0xD5 */ CHAN_C
| NONEOS_C
,
880 /* 0xD6 */ CHAN_C
| NONEOS_C
,
881 /* 0xD7 */ CHAN_C
| NONEOS_C
,
882 /* 0xD8 */ CHAN_C
| NONEOS_C
,
883 /* 0xD9 */ CHAN_C
| NONEOS_C
,
884 /* 0xDA */ CHAN_C
| NONEOS_C
,
885 /* 0xDB */ CHAN_C
| NONEOS_C
,
886 /* 0xDC */ CHAN_C
| NONEOS_C
,
887 /* 0xDD */ CHAN_C
| NONEOS_C
,
888 /* 0xDE */ CHAN_C
| NONEOS_C
,
889 /* 0xDF */ CHAN_C
| NONEOS_C
,
890 /* 0xE0 */ CHAN_C
| NONEOS_C
,
891 /* 0xE1 */ CHAN_C
| NONEOS_C
,
892 /* 0xE2 */ CHAN_C
| NONEOS_C
,
893 /* 0xE3 */ CHAN_C
| NONEOS_C
,
894 /* 0xE4 */ CHAN_C
| NONEOS_C
,
895 /* 0xE5 */ CHAN_C
| NONEOS_C
,
896 /* 0xE6 */ CHAN_C
| NONEOS_C
,
897 /* 0xE7 */ CHAN_C
| NONEOS_C
,
898 /* 0xE8 */ CHAN_C
| NONEOS_C
,
899 /* 0xE9 */ CHAN_C
| NONEOS_C
,
900 /* 0xEA */ CHAN_C
| NONEOS_C
,
901 /* 0xEB */ CHAN_C
| NONEOS_C
,
902 /* 0xEC */ CHAN_C
| NONEOS_C
,
903 /* 0xED */ CHAN_C
| NONEOS_C
,
904 /* 0xEE */ CHAN_C
| NONEOS_C
,
905 /* 0xEF */ CHAN_C
| NONEOS_C
,
906 /* 0xF0 */ CHAN_C
| NONEOS_C
,
907 /* 0xF1 */ CHAN_C
| NONEOS_C
,
908 /* 0xF2 */ CHAN_C
| NONEOS_C
,
909 /* 0xF3 */ CHAN_C
| NONEOS_C
,
910 /* 0xF4 */ CHAN_C
| NONEOS_C
,
911 /* 0xF5 */ CHAN_C
| NONEOS_C
,
912 /* 0xF6 */ CHAN_C
| NONEOS_C
,
913 /* 0xF7 */ CHAN_C
| NONEOS_C
,
914 /* 0xF8 */ CHAN_C
| NONEOS_C
,
915 /* 0xF9 */ CHAN_C
| NONEOS_C
,
916 /* 0xFA */ CHAN_C
| NONEOS_C
,
917 /* 0xFB */ CHAN_C
| NONEOS_C
,
918 /* 0xFC */ CHAN_C
| NONEOS_C
,
919 /* 0xFD */ CHAN_C
| NONEOS_C
,
920 /* 0xFE */ CHAN_C
| NONEOS_C
,
921 /* 0xFF */ CHAN_C
| NONEOS_C