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.
19 * $Id: match.c 3532 2007-07-14 13:32:18Z jilles $
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.
37 * Originally by Douglas A Lewis (dalewis@acsu.buffalo.edu)
38 * Rewritten by Timothy Vogelsang (netski), net@astrolink.org
41 /** Check a string against a mask.
42 * This test checks using traditional IRC wildcards only: '*' means
43 * match zero or more characters of any type; '?' means match exactly
44 * one character of any type.
46 * @param[in] mask Wildcard-containing mask.
47 * @param[in] name String to check against \a mask.
48 * @return Zero if \a mask matches \a name, non-zero if no match.
50 int match(const char *mask
, const char *name
)
52 const char *m
= mask
, *n
= name
;
53 const char *m_tmp
= mask
, *n_tmp
= name
;
56 s_assert(mask
!= NULL
);
57 s_assert(name
!= NULL
);
74 for (star_p
= 0;; m
++)
93 for (n_tmp
= n
; *n
&& ToLower(*n
) != ToLower(*m
); n
++);
96 /* and fall through */
99 return (*m
!= '\0' ? 0 : 1);
100 if (ToLower(*m
) != ToLower(*n
))
109 /** Check a mask against a mask.
110 * This test checks using traditional IRC wildcards only: '*' means
111 * match zero or more characters of any type; '?' means match exactly
112 * one character of any type.
113 * The difference between mask_match() and match() is that in mask_match()
114 * a '?' in mask does not match a '*' in name.
116 * @param[in] mask Existing wildcard-containing mask.
117 * @param[in] name New wildcard-containing mask.
118 * @return 1 if \a name is equal to or more specific than \a mask, 0 otherwise.
120 int mask_match(const char *mask
, const char *name
)
122 const char *m
= mask
, *n
= name
;
123 const char *m_tmp
= mask
, *n_tmp
= name
;
126 s_assert(mask
!= NULL
);
127 s_assert(name
!= NULL
);
144 for (star_p
= 0;; m
++)
150 /* changed for mask_match() */
151 if (*n
== '*' || !*n
)
165 for (n_tmp
= n
; *n
&& ToLower(*n
) != ToLower(*m
); n
++);
168 /* and fall through */
171 return (*m
!= '\0' ? 0 : 1);
172 if (ToLower(*m
) != ToLower(*n
))
182 #define MATCH_MAX_CALLS 512 /* ACK! This dies when it's less that this
183 and we have long lines to parse */
184 /** Check a string against a mask.
185 * This test checks using extended wildcards: '*' means match zero
186 * or more characters of any type; '?' means match exactly one
187 * character of any type; '#' means match exactly one character that
188 * is a number; '@' means match exactly one character that is a
189 * letter; '\s' means match a space.
191 * This function supports escaping, so that a wildcard may be matched
194 * @param[in] mask Wildcard-containing mask.
195 * @param[in] name String to check against \a mask.
196 * @return Zero if \a mask matches \a name, non-zero if no match.
199 match_esc(const char *mask
, const char *name
)
201 const unsigned char *m
= (const unsigned char *)mask
;
202 const unsigned char *n
= (const unsigned char *)name
;
203 const unsigned char *ma
= (const unsigned char *)mask
;
204 const unsigned char *na
= (const unsigned char *)name
;
210 s_assert(mask
!= NULL
);
211 s_assert(name
!= NULL
);
216 /* if the mask is "*", it matches everything */
217 if((*m
== '*') && (*(m
+ 1) == '\0'))
220 while(calls
++ < MATCH_MAX_CALLS
)
226 if(*m
== '\\' && !quote
)
232 if(!quote
&& *m
== '*')
235 * XXX - shouldn't need to spin here, the mask should have been
236 * collapsed before match is called
248 /* This means it is an invalid mask -A1kmm. */
262 for(m
--; (m
> (const unsigned char *)mask
) && (*m
== '?'); m
--)
265 if(*m
== '*' && (m
> (const unsigned char *)mask
))
275 * XXX - shouldn't need to spin here, the mask should have been
276 * collapsed before match is called
286 match1
= *m
== 's' ? *n
== ' ' : ToLower(*m
) == ToLower(*n
);
290 match1
= IsLetter(*n
);
292 match1
= IsDigit(*n
);
294 match1
= ToLower(*m
) == ToLower(*n
);
313 int comp_with_mask(void *addr
, void *dest
, u_int mask
)
315 if (memcmp(addr
, dest
, mask
/ 8) == 0)
318 int m
= ((-1) << (8 - (mask
% 8)));
319 if (mask
% 8 == 0 || (((u_char
*) addr
)[n
] & m
) == (((u_char
*) dest
)[n
] & m
))
327 int comp_with_mask_sock(struct sockaddr
*addr
, struct sockaddr
*dest
, u_int mask
)
332 if (addr
->sa_family
== AF_INET
)
334 iaddr
= &((struct sockaddr_in
*)(void *)addr
)->sin_addr
;
335 idest
= &((struct sockaddr_in
*)(void *)dest
)->sin_addr
;
340 iaddr
= &((struct sockaddr_in6
*)(void *)addr
)->sin6_addr
;
341 idest
= &((struct sockaddr_in6
*)(void *)dest
)->sin6_addr
;
346 return (comp_with_mask(iaddr
, idest
, mask
));
352 * Input - cidr ip mask, address
354 int match_ips(const char *s1
, const char *s2
)
356 struct rb_sockaddr_storage ipaddr
, maskaddr
;
358 char address
[HOSTLEN
+ 1];
360 void *ipptr
, *maskptr
;
366 len
= strrchr(mask
, '/');
377 if (strchr(mask
, ':') && strchr(address
, ':'))
383 ipptr
= &((struct sockaddr_in6
*)&ipaddr
)->sin6_addr
;
384 maskptr
= &((struct sockaddr_in6
*)&maskaddr
)->sin6_addr
;
388 if (!strchr(mask
, ':') && !strchr(address
, ':'))
394 ipptr
= &((struct sockaddr_in
*)&ipaddr
)->sin_addr
;
395 maskptr
= &((struct sockaddr_in
*)&maskaddr
)->sin_addr
;
400 if (rb_inet_pton(aftype
, address
, ipptr
) <= 0)
402 if (rb_inet_pton(aftype
, mask
, maskptr
) <= 0)
404 if (comp_with_mask(ipptr
, maskptr
, cidrlen
))
412 * Input - mask, address
413 * Ouput - 1 = Matched 0 = Did not match
416 int match_cidr(const char *s1
, const char *s2
)
418 struct rb_sockaddr_storage ipaddr
, maskaddr
;
420 char address
[NICKLEN
+ USERLEN
+ HOSTLEN
+ 6];
424 void *ipptr
, *maskptr
;
430 ipmask
= strrchr(mask
, '@');
436 ip
= strrchr(address
, '@');
442 len
= strrchr(ipmask
, '/');
453 if (strchr(ip
, ':') && strchr(ipmask
, ':'))
459 ipptr
= &((struct sockaddr_in6
*)&ipaddr
)->sin6_addr
;
460 maskptr
= &((struct sockaddr_in6
*)&maskaddr
)->sin6_addr
;
464 if (!strchr(ip
, ':') && !strchr(ipmask
, ':'))
470 ipptr
= &((struct sockaddr_in
*)&ipaddr
)->sin_addr
;
471 maskptr
= &((struct sockaddr_in
*)&maskaddr
)->sin_addr
;
476 if (rb_inet_pton(aftype
, ip
, ipptr
) <= 0)
478 if (rb_inet_pton(aftype
, ipmask
, maskptr
) <= 0)
480 if (comp_with_mask(ipptr
, maskptr
, cidrlen
) && match(mask
, address
))
488 * collapses a string containing multiple *'s.
490 char *collapse(char *pattern
)
492 char *p
= pattern
, *po
= pattern
;
520 * The collapse() function with support for escaping characters
522 char *collapse_esc(char *pattern
)
524 char *p
= pattern
, *po
= pattern
;
533 if (!(f
& 2) && c
== '*')
539 else if (!(f
& 2) && c
== '\\')
555 * irccmp - case insensitive comparison of two 0 terminated strings.
557 * returns 0, if s1 equal to s2
558 * <0, if s1 lexicographically less than s2
559 * >0, if s1 lexicographically greater than s2
561 int irccmp(const char *s1
, const char *s2
)
563 const unsigned char *str1
= (const unsigned char *)s1
;
564 const unsigned char *str2
= (const unsigned char *)s2
;
567 s_assert(s1
!= NULL
);
568 s_assert(s2
!= NULL
);
570 while ((res
= ToUpper(*str1
) - ToUpper(*str2
)) == 0)
580 int ircncmp(const char *s1
, const char *s2
, int n
)
582 const unsigned char *str1
= (const unsigned char *)s1
;
583 const unsigned char *str2
= (const unsigned char *)s2
;
585 s_assert(s1
!= NULL
);
586 s_assert(s2
!= NULL
);
588 while ((res
= ToUpper(*str1
) - ToUpper(*str2
)) == 0)
593 if (n
== 0 || (*str1
== '\0' && *str2
== '\0'))
599 const unsigned char ToLowerTab
[] = {
600 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
601 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
602 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
604 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
605 '*', '+', ',', '-', '.', '/',
606 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
607 ':', ';', '<', '=', '>', '?',
608 '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
609 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
610 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
612 '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
613 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
614 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
616 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
617 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
618 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
619 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
620 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
621 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
622 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
623 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
624 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
625 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
626 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
627 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
628 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
629 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
630 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
631 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
634 const unsigned char ToUpperTab
[] = {
635 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
636 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
637 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
639 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
640 '*', '+', ',', '-', '.', '/',
641 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
642 ':', ';', '<', '=', '>', '?',
643 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
644 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
645 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
647 '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
648 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
649 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
651 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
652 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
653 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
654 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
655 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
656 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
657 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
658 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
659 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
660 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
661 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
662 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
663 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
664 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
665 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
666 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
672 * NOTE: RFC 1459 sez: anything but a ^G, comma, or space is allowed
675 const unsigned int CharAttrs
[] = {
677 /* 1 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
678 /* 2 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
679 /* 3 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
680 /* 4 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
681 /* 5 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
682 /* 6 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
683 /* 7 BEL */ CNTRL_C
| NONEOS_C
,
684 /* 8 \b */ CNTRL_C
| CHAN_C
| NONEOS_C
,
685 /* 9 \t */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
,
686 /* 10 \n */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
| EOL_C
,
687 /* 11 \v */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
,
688 /* 12 \f */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
,
689 /* 13 \r */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
| EOL_C
,
690 /* 14 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
691 /* 15 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
692 /* 16 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
693 /* 17 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
694 /* 18 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
695 /* 19 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
696 /* 20 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
697 /* 21 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
698 /* 22 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
699 /* 23 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
700 /* 24 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
701 /* 25 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
702 /* 26 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
703 /* 27 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
704 /* 28 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
705 /* 29 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
706 /* 30 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
707 /* 31 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
708 /* SP */ PRINT_C
| SPACE_C
,
709 /* ! */ PRINT_C
| KWILD_C
| CHAN_C
| NONEOS_C
,
710 /* " */ PRINT_C
| CHAN_C
| NONEOS_C
,
711 /* # */ PRINT_C
| MWILD_C
| CHANPFX_C
| CHAN_C
| NONEOS_C
,
712 /* $ */ PRINT_C
| CHAN_C
| NONEOS_C
,
713 /* % */ PRINT_C
| CHAN_C
| NONEOS_C
,
714 /* & */ PRINT_C
| CHANPFX_C
| CHAN_C
| NONEOS_C
,
715 /* ' */ PRINT_C
| CHAN_C
| NONEOS_C
,
716 /* ( */ PRINT_C
| CHAN_C
| NONEOS_C
,
717 /* ) */ PRINT_C
| CHAN_C
| NONEOS_C
,
718 /* * */ PRINT_C
| KWILD_C
| MWILD_C
| CHAN_C
| NONEOS_C
,
719 /* + */ PRINT_C
| CHAN_C
| NONEOS_C
,
720 /* , */ PRINT_C
| NONEOS_C
,
721 /* - */ PRINT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
722 /* . */ PRINT_C
| KWILD_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
| SERV_C
,
723 /* / */ PRINT_C
| CHAN_C
| NONEOS_C
| HOST_C
,
724 /* 0 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
725 /* 1 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
726 /* 2 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
727 /* 3 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
728 /* 4 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
729 /* 5 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
730 /* 6 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
731 /* 7 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
732 /* 8 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
733 /* 9 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
734 /* : */ PRINT_C
| CHAN_C
| NONEOS_C
| HOST_C
,
735 /* ; */ PRINT_C
| CHAN_C
| NONEOS_C
,
736 /* < */ PRINT_C
| CHAN_C
| NONEOS_C
,
737 /* = */ PRINT_C
| CHAN_C
| NONEOS_C
,
738 /* > */ PRINT_C
| CHAN_C
| NONEOS_C
,
739 /* ? */ PRINT_C
| KWILD_C
| MWILD_C
| CHAN_C
| NONEOS_C
,
740 /* @ */ PRINT_C
| KWILD_C
| MWILD_C
| CHAN_C
| NONEOS_C
,
741 /* A */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
742 /* B */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
743 /* C */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
744 /* D */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
745 /* E */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
746 /* F */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
747 /* G */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
748 /* H */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
749 /* I */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
750 /* J */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
751 /* K */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
752 /* L */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
753 /* M */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
754 /* N */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
755 /* O */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
756 /* P */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
757 /* Q */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
758 /* R */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
759 /* S */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
760 /* T */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
761 /* U */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
762 /* V */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
763 /* W */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
764 /* X */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
765 /* Y */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
766 /* Z */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_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
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
770 /* ^ */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
771 /* _ */ PRINT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
772 /* ` */ PRINT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
773 /* a */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
774 /* b */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
775 /* c */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
776 /* d */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
777 /* e */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
778 /* f */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
779 /* g */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
780 /* h */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
781 /* i */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
782 /* j */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
783 /* k */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
784 /* l */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
785 /* m */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
786 /* n */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
787 /* o */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
788 /* p */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
789 /* q */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
790 /* r */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
791 /* s */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
792 /* t */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
793 /* u */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
794 /* v */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
795 /* w */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
796 /* x */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
797 /* y */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
798 /* z */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
799 /* { */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
800 /* | */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
801 /* } */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
802 /* ~ */ PRINT_C
| ALPHA_C
| CHAN_C
| NONEOS_C
| USER_C
,
803 /* del */ CHAN_C
| NONEOS_C
,
804 /* 0x80 */ CHAN_C
| NONEOS_C
,
805 /* 0x81 */ CHAN_C
| NONEOS_C
,
806 /* 0x82 */ CHAN_C
| NONEOS_C
,
807 /* 0x83 */ CHAN_C
| NONEOS_C
,
808 /* 0x84 */ CHAN_C
| NONEOS_C
,
809 /* 0x85 */ CHAN_C
| NONEOS_C
,
810 /* 0x86 */ CHAN_C
| NONEOS_C
,
811 /* 0x87 */ CHAN_C
| NONEOS_C
,
812 /* 0x88 */ CHAN_C
| NONEOS_C
,
813 /* 0x89 */ CHAN_C
| NONEOS_C
,
814 /* 0x8A */ CHAN_C
| NONEOS_C
,
815 /* 0x8B */ CHAN_C
| NONEOS_C
,
816 /* 0x8C */ CHAN_C
| NONEOS_C
,
817 /* 0x8D */ CHAN_C
| NONEOS_C
,
818 /* 0x8E */ CHAN_C
| NONEOS_C
,
819 /* 0x8F */ CHAN_C
| NONEOS_C
,
820 /* 0x90 */ CHAN_C
| NONEOS_C
,
821 /* 0x91 */ CHAN_C
| NONEOS_C
,
822 /* 0x92 */ CHAN_C
| NONEOS_C
,
823 /* 0x93 */ CHAN_C
| NONEOS_C
,
824 /* 0x94 */ CHAN_C
| NONEOS_C
,
825 /* 0x95 */ CHAN_C
| NONEOS_C
,
826 /* 0x96 */ CHAN_C
| NONEOS_C
,
827 /* 0x97 */ CHAN_C
| NONEOS_C
,
828 /* 0x98 */ CHAN_C
| NONEOS_C
,
829 /* 0x99 */ CHAN_C
| NONEOS_C
,
830 /* 0x9A */ CHAN_C
| NONEOS_C
,
831 /* 0x9B */ CHAN_C
| NONEOS_C
,
832 /* 0x9C */ CHAN_C
| NONEOS_C
,
833 /* 0x9D */ CHAN_C
| NONEOS_C
,
834 /* 0x9E */ CHAN_C
| NONEOS_C
,
835 /* 0x9F */ CHAN_C
| NONEOS_C
,
836 /* 0xA0 */ CHAN_C
| FCHAN_C
| NONEOS_C
,
837 /* 0xA1 */ CHAN_C
| NONEOS_C
,
838 /* 0xA2 */ CHAN_C
| NONEOS_C
,
839 /* 0xA3 */ CHAN_C
| NONEOS_C
,
840 /* 0xA4 */ CHAN_C
| NONEOS_C
,
841 /* 0xA5 */ CHAN_C
| NONEOS_C
,
842 /* 0xA6 */ CHAN_C
| NONEOS_C
,
843 /* 0xA7 */ CHAN_C
| NONEOS_C
,
844 /* 0xA8 */ CHAN_C
| NONEOS_C
,
845 /* 0xA9 */ CHAN_C
| NONEOS_C
,
846 /* 0xAA */ CHAN_C
| NONEOS_C
,
847 /* 0xAB */ CHAN_C
| NONEOS_C
,
848 /* 0xAC */ CHAN_C
| NONEOS_C
,
849 /* 0xAD */ CHAN_C
| NONEOS_C
,
850 /* 0xAE */ CHAN_C
| NONEOS_C
,
851 /* 0xAF */ CHAN_C
| NONEOS_C
,
852 /* 0xB0 */ CHAN_C
| NONEOS_C
,
853 /* 0xB1 */ CHAN_C
| NONEOS_C
,
854 /* 0xB2 */ CHAN_C
| NONEOS_C
,
855 /* 0xB3 */ CHAN_C
| NONEOS_C
,
856 /* 0xB4 */ CHAN_C
| NONEOS_C
,
857 /* 0xB5 */ CHAN_C
| NONEOS_C
,
858 /* 0xB6 */ CHAN_C
| NONEOS_C
,
859 /* 0xB7 */ CHAN_C
| NONEOS_C
,
860 /* 0xB8 */ CHAN_C
| NONEOS_C
,
861 /* 0xB9 */ CHAN_C
| NONEOS_C
,
862 /* 0xBA */ CHAN_C
| NONEOS_C
,
863 /* 0xBB */ CHAN_C
| NONEOS_C
,
864 /* 0xBC */ CHAN_C
| NONEOS_C
,
865 /* 0xBD */ CHAN_C
| NONEOS_C
,
866 /* 0xBE */ CHAN_C
| NONEOS_C
,
867 /* 0xBF */ CHAN_C
| NONEOS_C
,
868 /* 0xC0 */ CHAN_C
| NONEOS_C
,
869 /* 0xC1 */ CHAN_C
| NONEOS_C
,
870 /* 0xC2 */ CHAN_C
| NONEOS_C
,
871 /* 0xC3 */ CHAN_C
| NONEOS_C
,
872 /* 0xC4 */ CHAN_C
| NONEOS_C
,
873 /* 0xC5 */ CHAN_C
| NONEOS_C
,
874 /* 0xC6 */ CHAN_C
| NONEOS_C
,
875 /* 0xC7 */ CHAN_C
| NONEOS_C
,
876 /* 0xC8 */ CHAN_C
| NONEOS_C
,
877 /* 0xC9 */ CHAN_C
| NONEOS_C
,
878 /* 0xCA */ CHAN_C
| NONEOS_C
,
879 /* 0xCB */ CHAN_C
| NONEOS_C
,
880 /* 0xCC */ CHAN_C
| NONEOS_C
,
881 /* 0xCD */ CHAN_C
| NONEOS_C
,
882 /* 0xCE */ CHAN_C
| NONEOS_C
,
883 /* 0xCF */ CHAN_C
| NONEOS_C
,
884 /* 0xD0 */ CHAN_C
| NONEOS_C
,
885 /* 0xD1 */ CHAN_C
| NONEOS_C
,
886 /* 0xD2 */ CHAN_C
| NONEOS_C
,
887 /* 0xD3 */ CHAN_C
| NONEOS_C
,
888 /* 0xD4 */ CHAN_C
| NONEOS_C
,
889 /* 0xD5 */ CHAN_C
| NONEOS_C
,
890 /* 0xD6 */ CHAN_C
| NONEOS_C
,
891 /* 0xD7 */ CHAN_C
| NONEOS_C
,
892 /* 0xD8 */ CHAN_C
| NONEOS_C
,
893 /* 0xD9 */ CHAN_C
| NONEOS_C
,
894 /* 0xDA */ CHAN_C
| NONEOS_C
,
895 /* 0xDB */ CHAN_C
| NONEOS_C
,
896 /* 0xDC */ CHAN_C
| NONEOS_C
,
897 /* 0xDD */ CHAN_C
| NONEOS_C
,
898 /* 0xDE */ CHAN_C
| NONEOS_C
,
899 /* 0xDF */ CHAN_C
| NONEOS_C
,
900 /* 0xE0 */ CHAN_C
| NONEOS_C
,
901 /* 0xE1 */ CHAN_C
| NONEOS_C
,
902 /* 0xE2 */ CHAN_C
| NONEOS_C
,
903 /* 0xE3 */ CHAN_C
| NONEOS_C
,
904 /* 0xE4 */ CHAN_C
| NONEOS_C
,
905 /* 0xE5 */ CHAN_C
| NONEOS_C
,
906 /* 0xE6 */ CHAN_C
| NONEOS_C
,
907 /* 0xE7 */ CHAN_C
| NONEOS_C
,
908 /* 0xE8 */ CHAN_C
| NONEOS_C
,
909 /* 0xE9 */ CHAN_C
| NONEOS_C
,
910 /* 0xEA */ CHAN_C
| NONEOS_C
,
911 /* 0xEB */ CHAN_C
| NONEOS_C
,
912 /* 0xEC */ CHAN_C
| NONEOS_C
,
913 /* 0xED */ CHAN_C
| NONEOS_C
,
914 /* 0xEE */ CHAN_C
| NONEOS_C
,
915 /* 0xEF */ CHAN_C
| NONEOS_C
,
916 /* 0xF0 */ CHAN_C
| NONEOS_C
,
917 /* 0xF1 */ CHAN_C
| NONEOS_C
,
918 /* 0xF2 */ CHAN_C
| NONEOS_C
,
919 /* 0xF3 */ CHAN_C
| NONEOS_C
,
920 /* 0xF4 */ CHAN_C
| NONEOS_C
,
921 /* 0xF5 */ CHAN_C
| NONEOS_C
,
922 /* 0xF6 */ CHAN_C
| NONEOS_C
,
923 /* 0xF7 */ CHAN_C
| NONEOS_C
,
924 /* 0xF8 */ CHAN_C
| NONEOS_C
,
925 /* 0xF9 */ CHAN_C
| NONEOS_C
,
926 /* 0xFA */ CHAN_C
| NONEOS_C
,
927 /* 0xFB */ CHAN_C
| NONEOS_C
,
928 /* 0xFC */ CHAN_C
| NONEOS_C
,
929 /* 0xFD */ CHAN_C
| NONEOS_C
,
930 /* 0xFE */ CHAN_C
| NONEOS_C
,
931 /* 0xFF */ CHAN_C
| NONEOS_C