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 /* Reorder runs of [?*] in mask to the form ``**...??...'' */
109 match_arrange_stars(char *mask
)
113 for (char *p
= mask
; *p
!= '\0'; p
++)
118 if (swap
== NULL
) break;
123 if (swap
== NULL
) swap
= p
;
132 /** Check a mask against a mask.
133 * This test checks using traditional IRC wildcards only: '*' means
134 * match zero or more characters of any type; '?' means match exactly
135 * one character of any type.
136 * The difference between mask_match() and match() is that in mask_match()
137 * a '?' in mask does not match a '*' in name.
139 * @param[in] mask Existing wildcard-containing mask.
140 * @param[in] name New wildcard-containing mask.
141 * @return 1 if \a name is equal to or more specific than \a mask, 0 otherwise.
143 int mask_match(const char *mask_
, const char *name
)
145 static char mask
[BUFSIZE
];
146 const char *m
= mask
, *n
= name
;
147 const char *m_tmp
= mask
, *n_tmp
= name
;
151 s_assert(mask_
!= NULL
);
152 s_assert(name
!= NULL
);
154 len
= rb_strlcpy(mask
, mask_
, sizeof mask
);
155 s_assert(len
< sizeof mask
);
156 (void) len
; /* for NDEBUG */
158 match_arrange_stars(mask
);
175 for (star_p
= 0;; m
++)
181 /* changed for mask_match() */
182 while (star_p
&& *n
== '*') n
++;
183 if (*n
== '*' || !*n
)
197 for (n_tmp
= n
; *n
&& irctolower(*n
) != irctolower(*m
); n
++);
200 /* and fall through */
203 return (*m
!= '\0' ? 0 : 1);
204 if (irctolower(*m
) != irctolower(*n
))
214 #define MATCH_MAX_CALLS 512 /* ACK! This dies when it's less that this
215 and we have long lines to parse */
216 /** Check a string against a mask.
217 * This test checks using extended wildcards: '*' means match zero
218 * or more characters of any type; '?' means match exactly one
219 * character of any type; '#' means match exactly one character that
220 * is a number; '@' means match exactly one character that is a
221 * letter; '\s' means match a space.
223 * This function supports escaping, so that a wildcard may be matched
226 * @param[in] mask Wildcard-containing mask.
227 * @param[in] name String to check against \a mask.
228 * @return Zero if \a mask matches \a name, non-zero if no match.
231 match_esc(const char *mask
, const char *name
)
233 const unsigned char *m
= (const unsigned char *)mask
;
234 const unsigned char *n
= (const unsigned char *)name
;
235 const unsigned char *ma
= (const unsigned char *)mask
;
236 const unsigned char *na
= (const unsigned char *)name
;
242 s_assert(mask
!= NULL
);
243 s_assert(name
!= NULL
);
248 /* if the mask is "*", it matches everything */
249 if((*m
== '*') && (*(m
+ 1) == '\0'))
252 while(calls
++ < MATCH_MAX_CALLS
)
258 if(*m
== '\\' && !quote
)
264 if(!quote
&& *m
== '*')
267 * XXX - shouldn't need to spin here, the mask should have been
268 * collapsed before match is called
280 /* This means it is an invalid mask -A1kmm. */
294 for(m
--; (m
> (const unsigned char *)mask
) && (*m
== '?'); m
--)
297 if(*m
== '*' && (m
> (const unsigned char *)mask
))
307 * XXX - shouldn't need to spin here, the mask should have been
308 * collapsed before match is called
318 match1
= *m
== 's' ? *n
== ' ' : irctolower(*m
) == irctolower(*n
);
322 match1
= IsLetter(*n
);
324 match1
= IsDigit(*n
);
326 match1
= irctolower(*m
) == irctolower(*n
);
345 int comp_with_mask(void *addr
, void *dest
, unsigned int mask
)
347 if (memcmp(addr
, dest
, mask
/ 8) == 0)
350 unsigned char m
= (0xFF << (8 - (mask
% 8)));
351 if (mask
% 8 == 0 || (((unsigned char *) addr
)[n
] & m
) == (((unsigned char *) dest
)[n
] & m
))
359 int comp_with_mask_sock(struct sockaddr
*addr
, struct sockaddr
*dest
, unsigned int mask
)
364 if (addr
->sa_family
== AF_INET
)
366 iaddr
= &((struct sockaddr_in
*)(void *)addr
)->sin_addr
;
367 idest
= &((struct sockaddr_in
*)(void *)dest
)->sin_addr
;
371 iaddr
= &((struct sockaddr_in6
*)(void *)addr
)->sin6_addr
;
372 idest
= &((struct sockaddr_in6
*)(void *)dest
)->sin6_addr
;
376 return (comp_with_mask(iaddr
, idest
, mask
));
382 * Input - cidr ip mask, address
384 int match_ips(const char *s1
, const char *s2
)
386 struct rb_sockaddr_storage ipaddr
, maskaddr
;
388 char address
[HOSTLEN
+ 1];
390 void *ipptr
, *maskptr
;
393 rb_strlcpy(mask
, s1
, sizeof(mask
));
394 rb_strlcpy(address
, s2
, sizeof(address
));
396 len
= strrchr(mask
, '/');
406 if (strchr(mask
, ':') && strchr(address
, ':'))
412 ipptr
= &((struct sockaddr_in6
*)&ipaddr
)->sin6_addr
;
413 maskptr
= &((struct sockaddr_in6
*)&maskaddr
)->sin6_addr
;
415 else if (!strchr(mask
, ':') && !strchr(address
, ':'))
421 ipptr
= &((struct sockaddr_in
*)&ipaddr
)->sin_addr
;
422 maskptr
= &((struct sockaddr_in
*)&maskaddr
)->sin_addr
;
427 if (rb_inet_pton(aftype
, address
, ipptr
) <= 0)
429 if (rb_inet_pton(aftype
, mask
, maskptr
) <= 0)
431 if (comp_with_mask(ipptr
, maskptr
, cidrlen
))
439 * Input - mask, address
440 * Ouput - 1 = Matched 0 = Did not match
443 int match_cidr(const char *s1
, const char *s2
)
445 struct rb_sockaddr_storage ipaddr
, maskaddr
;
447 char address
[NICKLEN
+ USERLEN
+ HOSTLEN
+ 6];
451 void *ipptr
, *maskptr
;
454 rb_strlcpy(mask
, s1
, sizeof(mask
));
455 rb_strlcpy(address
, s2
, sizeof(address
));
457 ipmask
= strrchr(mask
, '@');
463 ip
= strrchr(address
, '@');
469 len
= strrchr(ipmask
, '/');
479 if (strchr(ip
, ':') && strchr(ipmask
, ':'))
485 ipptr
= &((struct sockaddr_in6
*)&ipaddr
)->sin6_addr
;
486 maskptr
= &((struct sockaddr_in6
*)&maskaddr
)->sin6_addr
;
488 else if (!strchr(ip
, ':') && !strchr(ipmask
, ':'))
494 ipptr
= &((struct sockaddr_in
*)&ipaddr
)->sin_addr
;
495 maskptr
= &((struct sockaddr_in
*)&maskaddr
)->sin_addr
;
500 if (rb_inet_pton(aftype
, ip
, ipptr
) <= 0)
502 if (rb_inet_pton(aftype
, ipmask
, maskptr
) <= 0)
504 if (comp_with_mask(ipptr
, maskptr
, cidrlen
) && match(mask
, address
))
512 * collapses a string containing multiple *'s.
514 char *collapse(char *pattern
)
516 char *p
= pattern
, *po
= pattern
;
544 * The collapse() function with support for escaping characters
546 char *collapse_esc(char *pattern
)
548 char *p
= pattern
, *po
= pattern
;
557 if (!(f
& 2) && c
== '*')
563 else if (!(f
& 2) && c
== '\\')
579 * irccmp - case insensitive comparison of two 0 terminated strings.
581 * returns 0, if s1 equal to s2
582 * <0, if s1 lexicographically less than s2
583 * >0, if s1 lexicographically greater than s2
585 int irccmp(const char *s1
, const char *s2
)
587 const unsigned char *str1
= (const unsigned char *)s1
;
588 const unsigned char *str2
= (const unsigned char *)s2
;
591 s_assert(s1
!= NULL
);
592 s_assert(s2
!= NULL
);
594 while ((res
= irctoupper(*str1
) - irctoupper(*str2
)) == 0)
604 int ircncmp(const char *s1
, const char *s2
, int n
)
606 const unsigned char *str1
= (const unsigned char *)s1
;
607 const unsigned char *str2
= (const unsigned char *)s2
;
609 s_assert(s1
!= NULL
);
610 s_assert(s2
!= NULL
);
612 while ((res
= irctoupper(*str1
) - irctoupper(*str2
)) == 0)
617 if (n
== 0 || (*str1
== '\0' && *str2
== '\0'))
623 void matchset_for_client(struct Client
*who
, struct matchset
*m
)
628 struct sockaddr_in ip4
;
630 sprintf(m
->host
[hostn
++], "%s!%s@%s", who
->name
, who
->username
, who
->host
);
634 sprintf(m
->ip
[ipn
++], "%s!%s@%s", who
->name
, who
->username
, who
->sockhost
);
637 if (who
->localClient
->mangledhost
!= NULL
)
639 /* if host mangling mode enabled, also check their real host */
640 if (!strcmp(who
->host
, who
->localClient
->mangledhost
))
642 sprintf(m
->host
[hostn
++], "%s!%s@%s", who
->name
, who
->username
, who
->orighost
);
644 /* if host mangling mode not enabled and no other spoof,
645 * also check the mangled form of their host */
646 else if (!IsDynSpoof(who
))
648 sprintf(m
->host
[hostn
++], "%s!%s@%s", who
->name
, who
->username
, who
->localClient
->mangledhost
);
651 if (!IsIPSpoof(who
) && GET_SS_FAMILY(&who
->localClient
->ip
) == AF_INET6
&&
652 rb_ipv4_from_ipv6((const struct sockaddr_in6
*)&who
->localClient
->ip
, &ip4
))
654 int n
= sprintf(m
->ip
[ipn
++], "%s!%s@", who
->name
, who
->username
);
655 rb_inet_ntop_sock((struct sockaddr
*)&ip4
,
656 m
->ip
[ipn
] + n
, sizeof m
->ip
[ipn
] - n
);
659 for (int i
= hostn
; i
< ARRAY_SIZE(m
->host
); i
++)
661 m
->host
[i
][0] = '\0';
663 for (int i
= ipn
; i
< ARRAY_SIZE(m
->ip
); i
++)
669 bool client_matches_mask(struct Client
*who
, const char *mask
)
671 static struct matchset ms
;
672 matchset_for_client(who
, &ms
);
673 return matches_mask(&ms
, mask
);
676 bool matches_mask(const struct matchset
*m
, const char *mask
)
678 for (int i
= 0; i
< ARRAY_SIZE(m
->host
); i
++)
680 if (m
->host
[i
][0] == '\0')
682 if (match(mask
, m
->host
[i
]))
685 for (int i
= 0; i
< ARRAY_SIZE(m
->ip
); i
++)
687 if (m
->ip
[i
][0] == '\0')
689 if (match(mask
, m
->ip
[i
]))
691 if (match_cidr(mask
, m
->ip
[i
]))
697 const unsigned char irctolower_tab
[] = {
698 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
699 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
700 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
702 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
703 '*', '+', ',', '-', '.', '/',
704 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
705 ':', ';', '<', '=', '>', '?',
706 '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
707 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
708 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
710 '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
711 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
712 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
714 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
715 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
716 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
717 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
718 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
719 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
720 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
721 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
722 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
723 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
724 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
725 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
726 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
727 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
728 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
729 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
732 const unsigned char irctoupper_tab
[] = {
733 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
734 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
735 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
737 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
738 '*', '+', ',', '-', '.', '/',
739 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
740 ':', ';', '<', '=', '>', '?',
741 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
742 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
743 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
745 '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
746 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
747 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
749 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
750 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
751 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
752 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
753 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
754 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
755 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
756 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
757 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
758 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
759 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
760 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
761 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
762 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
763 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
764 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
770 * NOTE: RFC 1459 sez: anything but a ^G, comma, or space is allowed
773 unsigned int CharAttrs
[] = {
775 /* 1 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
776 /* 2 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
777 /* 3 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
778 /* 4 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
779 /* 5 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
780 /* 6 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
781 /* 7 BEL */ CNTRL_C
| NONEOS_C
,
782 /* 8 \b */ CNTRL_C
| CHAN_C
| NONEOS_C
,
783 /* 9 \t */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
,
784 /* 10 \n */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
| EOL_C
,
785 /* 11 \v */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
,
786 /* 12 \f */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
,
787 /* 13 \r */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
| EOL_C
,
788 /* 14 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
789 /* 15 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
790 /* 16 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
791 /* 17 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
792 /* 18 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
793 /* 19 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
794 /* 20 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
795 /* 21 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
796 /* 22 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
797 /* 23 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
798 /* 24 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
799 /* 25 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
800 /* 26 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
801 /* 27 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
802 /* 28 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
803 /* 29 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
804 /* 30 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
805 /* 31 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
806 /* SP */ PRINT_C
| SPACE_C
,
807 /* ! */ PRINT_C
| KWILD_C
| CHAN_C
| NONEOS_C
,
808 /* " */ PRINT_C
| CHAN_C
| NONEOS_C
,
809 /* # */ PRINT_C
| MWILD_C
| CHANPFX_C
| CHAN_C
| NONEOS_C
,
810 /* $ */ PRINT_C
| CHAN_C
| NONEOS_C
,
811 /* % */ PRINT_C
| CHAN_C
| NONEOS_C
,
812 /* & */ PRINT_C
| CHANPFX_C
| CHAN_C
| NONEOS_C
,
813 /* ' */ PRINT_C
| CHAN_C
| NONEOS_C
,
814 /* ( */ PRINT_C
| CHAN_C
| NONEOS_C
,
815 /* ) */ PRINT_C
| CHAN_C
| NONEOS_C
,
816 /* * */ PRINT_C
| KWILD_C
| MWILD_C
| CHAN_C
| NONEOS_C
,
817 /* + */ PRINT_C
| CHAN_C
| NONEOS_C
,
818 /* , */ PRINT_C
| NONEOS_C
,
819 /* - */ PRINT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
820 /* . */ PRINT_C
| KWILD_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
| SERV_C
,
821 /* / */ PRINT_C
| CHAN_C
| NONEOS_C
| HOST_C
,
822 /* 0 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
823 /* 1 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
824 /* 2 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
825 /* 3 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
826 /* 4 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
827 /* 5 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
828 /* 6 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
829 /* 7 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
830 /* 8 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
831 /* 9 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
832 /* : */ PRINT_C
| CHAN_C
| NONEOS_C
| HOST_C
,
833 /* ; */ PRINT_C
| CHAN_C
| NONEOS_C
,
834 /* < */ PRINT_C
| CHAN_C
| NONEOS_C
,
835 /* = */ PRINT_C
| CHAN_C
| NONEOS_C
,
836 /* > */ PRINT_C
| CHAN_C
| NONEOS_C
,
837 /* ? */ PRINT_C
| KWILD_C
| MWILD_C
| CHAN_C
| NONEOS_C
,
838 /* @ */ PRINT_C
| KWILD_C
| MWILD_C
| CHAN_C
| NONEOS_C
,
839 /* A */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
840 /* B */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
841 /* C */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
842 /* D */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
843 /* E */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
844 /* F */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
845 /* G */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
846 /* H */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
847 /* I */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
848 /* J */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
849 /* K */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
850 /* L */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
851 /* M */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
852 /* N */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
853 /* O */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
854 /* P */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
855 /* Q */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
856 /* R */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
857 /* S */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
858 /* T */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
859 /* U */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
860 /* V */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
861 /* W */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
862 /* X */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
863 /* Y */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
864 /* Z */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
865 /* [ */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
866 /* \ */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
867 /* ] */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
868 /* ^ */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
869 /* _ */ PRINT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
870 /* ` */ PRINT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
871 /* a */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
872 /* b */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
873 /* c */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
874 /* d */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
875 /* e */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
876 /* f */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
877 /* g */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
878 /* h */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
879 /* i */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
880 /* j */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
881 /* k */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
882 /* l */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
883 /* m */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
884 /* n */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
885 /* o */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
886 /* p */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
887 /* q */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
888 /* r */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
889 /* s */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
890 /* t */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
891 /* u */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
892 /* v */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
893 /* w */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
894 /* x */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
895 /* y */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
896 /* z */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
897 /* { */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
898 /* | */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
899 /* } */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
900 /* ~ */ PRINT_C
| ALPHA_C
| CHAN_C
| NONEOS_C
| USER_C
,
901 /* del */ CHAN_C
| NONEOS_C
,
902 /* 0x80 */ CHAN_C
| NONEOS_C
,
903 /* 0x81 */ CHAN_C
| NONEOS_C
,
904 /* 0x82 */ CHAN_C
| NONEOS_C
,
905 /* 0x83 */ CHAN_C
| NONEOS_C
,
906 /* 0x84 */ CHAN_C
| NONEOS_C
,
907 /* 0x85 */ CHAN_C
| NONEOS_C
,
908 /* 0x86 */ CHAN_C
| NONEOS_C
,
909 /* 0x87 */ CHAN_C
| NONEOS_C
,
910 /* 0x88 */ CHAN_C
| NONEOS_C
,
911 /* 0x89 */ CHAN_C
| NONEOS_C
,
912 /* 0x8A */ CHAN_C
| NONEOS_C
,
913 /* 0x8B */ CHAN_C
| NONEOS_C
,
914 /* 0x8C */ CHAN_C
| NONEOS_C
,
915 /* 0x8D */ CHAN_C
| NONEOS_C
,
916 /* 0x8E */ CHAN_C
| NONEOS_C
,
917 /* 0x8F */ CHAN_C
| NONEOS_C
,
918 /* 0x90 */ CHAN_C
| NONEOS_C
,
919 /* 0x91 */ CHAN_C
| NONEOS_C
,
920 /* 0x92 */ CHAN_C
| NONEOS_C
,
921 /* 0x93 */ CHAN_C
| NONEOS_C
,
922 /* 0x94 */ CHAN_C
| NONEOS_C
,
923 /* 0x95 */ CHAN_C
| NONEOS_C
,
924 /* 0x96 */ CHAN_C
| NONEOS_C
,
925 /* 0x97 */ CHAN_C
| NONEOS_C
,
926 /* 0x98 */ CHAN_C
| NONEOS_C
,
927 /* 0x99 */ CHAN_C
| NONEOS_C
,
928 /* 0x9A */ CHAN_C
| NONEOS_C
,
929 /* 0x9B */ CHAN_C
| NONEOS_C
,
930 /* 0x9C */ CHAN_C
| NONEOS_C
,
931 /* 0x9D */ CHAN_C
| NONEOS_C
,
932 /* 0x9E */ CHAN_C
| NONEOS_C
,
933 /* 0x9F */ CHAN_C
| NONEOS_C
,
934 /* 0xA0 */ CHAN_C
| FCHAN_C
| NONEOS_C
,
935 /* 0xA1 */ CHAN_C
| NONEOS_C
,
936 /* 0xA2 */ CHAN_C
| NONEOS_C
,
937 /* 0xA3 */ CHAN_C
| NONEOS_C
,
938 /* 0xA4 */ CHAN_C
| NONEOS_C
,
939 /* 0xA5 */ CHAN_C
| NONEOS_C
,
940 /* 0xA6 */ CHAN_C
| NONEOS_C
,
941 /* 0xA7 */ CHAN_C
| NONEOS_C
,
942 /* 0xA8 */ CHAN_C
| NONEOS_C
,
943 /* 0xA9 */ CHAN_C
| NONEOS_C
,
944 /* 0xAA */ CHAN_C
| NONEOS_C
,
945 /* 0xAB */ CHAN_C
| NONEOS_C
,
946 /* 0xAC */ CHAN_C
| NONEOS_C
,
947 /* 0xAD */ CHAN_C
| NONEOS_C
,
948 /* 0xAE */ CHAN_C
| NONEOS_C
,
949 /* 0xAF */ CHAN_C
| NONEOS_C
,
950 /* 0xB0 */ CHAN_C
| NONEOS_C
,
951 /* 0xB1 */ CHAN_C
| NONEOS_C
,
952 /* 0xB2 */ CHAN_C
| NONEOS_C
,
953 /* 0xB3 */ CHAN_C
| NONEOS_C
,
954 /* 0xB4 */ CHAN_C
| NONEOS_C
,
955 /* 0xB5 */ CHAN_C
| NONEOS_C
,
956 /* 0xB6 */ CHAN_C
| NONEOS_C
,
957 /* 0xB7 */ CHAN_C
| NONEOS_C
,
958 /* 0xB8 */ CHAN_C
| NONEOS_C
,
959 /* 0xB9 */ CHAN_C
| NONEOS_C
,
960 /* 0xBA */ CHAN_C
| NONEOS_C
,
961 /* 0xBB */ CHAN_C
| NONEOS_C
,
962 /* 0xBC */ CHAN_C
| NONEOS_C
,
963 /* 0xBD */ CHAN_C
| NONEOS_C
,
964 /* 0xBE */ CHAN_C
| NONEOS_C
,
965 /* 0xBF */ CHAN_C
| NONEOS_C
,
966 /* 0xC0 */ CHAN_C
| NONEOS_C
,
967 /* 0xC1 */ CHAN_C
| NONEOS_C
,
968 /* 0xC2 */ CHAN_C
| NONEOS_C
,
969 /* 0xC3 */ CHAN_C
| NONEOS_C
,
970 /* 0xC4 */ CHAN_C
| NONEOS_C
,
971 /* 0xC5 */ CHAN_C
| NONEOS_C
,
972 /* 0xC6 */ CHAN_C
| NONEOS_C
,
973 /* 0xC7 */ CHAN_C
| NONEOS_C
,
974 /* 0xC8 */ CHAN_C
| NONEOS_C
,
975 /* 0xC9 */ CHAN_C
| NONEOS_C
,
976 /* 0xCA */ CHAN_C
| NONEOS_C
,
977 /* 0xCB */ CHAN_C
| NONEOS_C
,
978 /* 0xCC */ CHAN_C
| NONEOS_C
,
979 /* 0xCD */ CHAN_C
| NONEOS_C
,
980 /* 0xCE */ CHAN_C
| NONEOS_C
,
981 /* 0xCF */ CHAN_C
| NONEOS_C
,
982 /* 0xD0 */ CHAN_C
| NONEOS_C
,
983 /* 0xD1 */ CHAN_C
| NONEOS_C
,
984 /* 0xD2 */ CHAN_C
| NONEOS_C
,
985 /* 0xD3 */ CHAN_C
| NONEOS_C
,
986 /* 0xD4 */ CHAN_C
| NONEOS_C
,
987 /* 0xD5 */ CHAN_C
| NONEOS_C
,
988 /* 0xD6 */ CHAN_C
| NONEOS_C
,
989 /* 0xD7 */ CHAN_C
| NONEOS_C
,
990 /* 0xD8 */ CHAN_C
| NONEOS_C
,
991 /* 0xD9 */ CHAN_C
| NONEOS_C
,
992 /* 0xDA */ CHAN_C
| NONEOS_C
,
993 /* 0xDB */ CHAN_C
| NONEOS_C
,
994 /* 0xDC */ CHAN_C
| NONEOS_C
,
995 /* 0xDD */ CHAN_C
| NONEOS_C
,
996 /* 0xDE */ CHAN_C
| NONEOS_C
,
997 /* 0xDF */ CHAN_C
| NONEOS_C
,
998 /* 0xE0 */ CHAN_C
| NONEOS_C
,
999 /* 0xE1 */ CHAN_C
| NONEOS_C
,
1000 /* 0xE2 */ CHAN_C
| NONEOS_C
,
1001 /* 0xE3 */ CHAN_C
| NONEOS_C
,
1002 /* 0xE4 */ CHAN_C
| NONEOS_C
,
1003 /* 0xE5 */ CHAN_C
| NONEOS_C
,
1004 /* 0xE6 */ CHAN_C
| NONEOS_C
,
1005 /* 0xE7 */ CHAN_C
| NONEOS_C
,
1006 /* 0xE8 */ CHAN_C
| NONEOS_C
,
1007 /* 0xE9 */ CHAN_C
| NONEOS_C
,
1008 /* 0xEA */ CHAN_C
| NONEOS_C
,
1009 /* 0xEB */ CHAN_C
| NONEOS_C
,
1010 /* 0xEC */ CHAN_C
| NONEOS_C
,
1011 /* 0xED */ CHAN_C
| NONEOS_C
,
1012 /* 0xEE */ CHAN_C
| NONEOS_C
,
1013 /* 0xEF */ CHAN_C
| NONEOS_C
,
1014 /* 0xF0 */ CHAN_C
| NONEOS_C
,
1015 /* 0xF1 */ CHAN_C
| NONEOS_C
,
1016 /* 0xF2 */ CHAN_C
| NONEOS_C
,
1017 /* 0xF3 */ CHAN_C
| NONEOS_C
,
1018 /* 0xF4 */ CHAN_C
| NONEOS_C
,
1019 /* 0xF5 */ CHAN_C
| NONEOS_C
,
1020 /* 0xF6 */ CHAN_C
| NONEOS_C
,
1021 /* 0xF7 */ CHAN_C
| NONEOS_C
,
1022 /* 0xF8 */ CHAN_C
| NONEOS_C
,
1023 /* 0xF9 */ CHAN_C
| NONEOS_C
,
1024 /* 0xFA */ CHAN_C
| NONEOS_C
,
1025 /* 0xFB */ CHAN_C
| NONEOS_C
,
1026 /* 0xFC */ CHAN_C
| NONEOS_C
,
1027 /* 0xFD */ CHAN_C
| NONEOS_C
,
1028 /* 0xFE */ CHAN_C
| NONEOS_C
,
1029 /* 0xFF */ CHAN_C
| NONEOS_C