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 void matchset_for_client(struct Client
*who
, struct matchset
*m
)
594 struct sockaddr_in ip4
;
596 sprintf(m
->host
[hostn
++], "%s!%s@%s", who
->name
, who
->username
, who
->host
);
597 sprintf(m
->ip
[ipn
++], "%s!%s@%s", who
->name
, who
->username
, who
->sockhost
);
598 if (who
->localClient
->mangledhost
!= NULL
)
600 /* if host mangling mode enabled, also check their real host */
601 if (!strcmp(who
->host
, who
->localClient
->mangledhost
))
603 sprintf(m
->host
[hostn
++], "%s!%s@%s", who
->name
, who
->username
, who
->orighost
);
605 /* if host mangling mode not enabled and no other spoof,
606 * also check the mangled form of their host */
607 else if (!IsDynSpoof(who
))
609 sprintf(m
->host
[hostn
++], "%s!%s@%s", who
->name
, who
->username
, who
->localClient
->mangledhost
);
612 if (GET_SS_FAMILY(&who
->localClient
->ip
) == AF_INET6
&&
613 rb_ipv4_from_ipv6((const struct sockaddr_in6
*)&who
->localClient
->ip
, &ip4
))
615 int n
= sprintf(m
->ip
[ipn
++], "%s!%s@", who
->name
, who
->username
);
616 rb_inet_ntop_sock((struct sockaddr
*)&ip4
,
617 m
->ip
[ipn
] + n
, sizeof m
->ip
[ipn
] - n
);
620 for (int i
= hostn
; i
< ARRAY_SIZE(m
->host
); i
++)
622 m
->host
[i
][0] = '\0';
624 for (int i
= ipn
; i
< ARRAY_SIZE(m
->ip
); i
++)
630 bool client_matches_mask(struct Client
*who
, const char *mask
)
632 static struct matchset ms
;
633 matchset_for_client(who
, &ms
);
634 return matches_mask(&ms
, mask
);
637 bool matches_mask(const struct matchset
*m
, const char *mask
)
639 for (int i
= 0; i
< ARRAY_SIZE(m
->host
); i
++)
641 if (m
->host
[i
][0] == '\0')
643 if (match(mask
, m
->host
[i
]))
646 for (int i
= 0; i
< ARRAY_SIZE(m
->ip
); i
++)
648 if (m
->ip
[i
][0] == '\0')
650 if (match(mask
, m
->ip
[i
]))
652 if (match_cidr(mask
, m
->ip
[i
]))
658 const unsigned char irctolower_tab
[] = {
659 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
660 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
661 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
663 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
664 '*', '+', ',', '-', '.', '/',
665 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
666 ':', ';', '<', '=', '>', '?',
667 '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
668 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
669 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
671 '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
672 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
673 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
675 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
676 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
677 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
678 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
679 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
680 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
681 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
682 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
683 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
684 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
685 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
686 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
687 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
688 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
689 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
690 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
693 const unsigned char irctoupper_tab
[] = {
694 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
695 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
696 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
698 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
699 '*', '+', ',', '-', '.', '/',
700 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
701 ':', ';', '<', '=', '>', '?',
702 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
703 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
704 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
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 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
711 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
712 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
713 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
714 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
715 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
716 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
717 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
718 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
719 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
720 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
721 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
722 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
723 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
724 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
725 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
731 * NOTE: RFC 1459 sez: anything but a ^G, comma, or space is allowed
734 unsigned int CharAttrs
[] = {
736 /* 1 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
737 /* 2 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
738 /* 3 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
739 /* 4 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
740 /* 5 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
741 /* 6 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
742 /* 7 BEL */ CNTRL_C
| NONEOS_C
,
743 /* 8 \b */ CNTRL_C
| CHAN_C
| NONEOS_C
,
744 /* 9 \t */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
,
745 /* 10 \n */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
| EOL_C
,
746 /* 11 \v */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
,
747 /* 12 \f */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
,
748 /* 13 \r */ CNTRL_C
| SPACE_C
| CHAN_C
| NONEOS_C
| EOL_C
,
749 /* 14 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
750 /* 15 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
751 /* 16 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
752 /* 17 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
753 /* 18 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
754 /* 19 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
755 /* 20 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
756 /* 21 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
757 /* 22 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
758 /* 23 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
759 /* 24 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
760 /* 25 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
761 /* 26 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
762 /* 27 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
763 /* 28 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
764 /* 29 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
765 /* 30 */ CNTRL_C
| CHAN_C
| NONEOS_C
,
766 /* 31 */ CNTRL_C
| CHAN_C
| FCHAN_C
| NONEOS_C
,
767 /* SP */ PRINT_C
| SPACE_C
,
768 /* ! */ PRINT_C
| KWILD_C
| CHAN_C
| NONEOS_C
,
769 /* " */ PRINT_C
| CHAN_C
| NONEOS_C
,
770 /* # */ PRINT_C
| MWILD_C
| CHANPFX_C
| CHAN_C
| NONEOS_C
,
771 /* $ */ PRINT_C
| CHAN_C
| NONEOS_C
,
772 /* % */ PRINT_C
| CHAN_C
| NONEOS_C
,
773 /* & */ PRINT_C
| CHANPFX_C
| CHAN_C
| NONEOS_C
,
774 /* ' */ PRINT_C
| CHAN_C
| NONEOS_C
,
775 /* ( */ PRINT_C
| CHAN_C
| NONEOS_C
,
776 /* ) */ PRINT_C
| CHAN_C
| NONEOS_C
,
777 /* * */ PRINT_C
| KWILD_C
| MWILD_C
| CHAN_C
| NONEOS_C
,
778 /* + */ PRINT_C
| CHAN_C
| NONEOS_C
,
779 /* , */ PRINT_C
| NONEOS_C
,
780 /* - */ PRINT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
781 /* . */ PRINT_C
| KWILD_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
| SERV_C
,
782 /* / */ PRINT_C
| CHAN_C
| NONEOS_C
| HOST_C
,
783 /* 0 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
784 /* 1 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
785 /* 2 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
786 /* 3 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
787 /* 4 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
788 /* 5 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
789 /* 6 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
790 /* 7 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
791 /* 8 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
792 /* 9 */ PRINT_C
| DIGIT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
793 /* : */ PRINT_C
| CHAN_C
| NONEOS_C
| HOST_C
,
794 /* ; */ PRINT_C
| CHAN_C
| NONEOS_C
,
795 /* < */ PRINT_C
| CHAN_C
| NONEOS_C
,
796 /* = */ PRINT_C
| CHAN_C
| NONEOS_C
,
797 /* > */ PRINT_C
| CHAN_C
| NONEOS_C
,
798 /* ? */ PRINT_C
| KWILD_C
| MWILD_C
| CHAN_C
| NONEOS_C
,
799 /* @ */ PRINT_C
| KWILD_C
| MWILD_C
| CHAN_C
| NONEOS_C
,
800 /* A */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
801 /* B */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
802 /* C */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
803 /* D */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
804 /* E */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
805 /* F */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
806 /* G */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
807 /* H */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
808 /* I */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
809 /* J */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
810 /* K */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
811 /* L */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
812 /* M */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
813 /* N */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
814 /* O */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
815 /* P */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
816 /* Q */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
817 /* R */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
818 /* S */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
819 /* T */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
820 /* U */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
821 /* V */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
822 /* W */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
823 /* X */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
824 /* Y */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
825 /* Z */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
826 /* [ */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
827 /* \ */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
828 /* ] */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
829 /* ^ */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
830 /* _ */ PRINT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
831 /* ` */ PRINT_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
832 /* a */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
833 /* b */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
834 /* c */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
835 /* d */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
836 /* e */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
837 /* f */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
838 /* g */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
839 /* h */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
840 /* i */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
841 /* j */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
842 /* k */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
843 /* l */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
844 /* m */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
845 /* n */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
846 /* o */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
847 /* p */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
848 /* q */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
849 /* r */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
850 /* s */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
851 /* t */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
852 /* u */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
853 /* v */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
854 /* w */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
855 /* x */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
856 /* y */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
857 /* z */ PRINT_C
| ALPHA_C
| LET_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
| HOST_C
,
858 /* { */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
859 /* | */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
860 /* } */ PRINT_C
| ALPHA_C
| NICK_C
| CHAN_C
| NONEOS_C
| USER_C
,
861 /* ~ */ PRINT_C
| ALPHA_C
| CHAN_C
| NONEOS_C
| USER_C
,
862 /* del */ CHAN_C
| NONEOS_C
,
863 /* 0x80 */ CHAN_C
| NONEOS_C
,
864 /* 0x81 */ CHAN_C
| NONEOS_C
,
865 /* 0x82 */ CHAN_C
| NONEOS_C
,
866 /* 0x83 */ CHAN_C
| NONEOS_C
,
867 /* 0x84 */ CHAN_C
| NONEOS_C
,
868 /* 0x85 */ CHAN_C
| NONEOS_C
,
869 /* 0x86 */ CHAN_C
| NONEOS_C
,
870 /* 0x87 */ CHAN_C
| NONEOS_C
,
871 /* 0x88 */ CHAN_C
| NONEOS_C
,
872 /* 0x89 */ CHAN_C
| NONEOS_C
,
873 /* 0x8A */ CHAN_C
| NONEOS_C
,
874 /* 0x8B */ CHAN_C
| NONEOS_C
,
875 /* 0x8C */ CHAN_C
| NONEOS_C
,
876 /* 0x8D */ CHAN_C
| NONEOS_C
,
877 /* 0x8E */ CHAN_C
| NONEOS_C
,
878 /* 0x8F */ CHAN_C
| NONEOS_C
,
879 /* 0x90 */ CHAN_C
| NONEOS_C
,
880 /* 0x91 */ CHAN_C
| NONEOS_C
,
881 /* 0x92 */ CHAN_C
| NONEOS_C
,
882 /* 0x93 */ CHAN_C
| NONEOS_C
,
883 /* 0x94 */ CHAN_C
| NONEOS_C
,
884 /* 0x95 */ CHAN_C
| NONEOS_C
,
885 /* 0x96 */ CHAN_C
| NONEOS_C
,
886 /* 0x97 */ CHAN_C
| NONEOS_C
,
887 /* 0x98 */ CHAN_C
| NONEOS_C
,
888 /* 0x99 */ CHAN_C
| NONEOS_C
,
889 /* 0x9A */ CHAN_C
| NONEOS_C
,
890 /* 0x9B */ CHAN_C
| NONEOS_C
,
891 /* 0x9C */ CHAN_C
| NONEOS_C
,
892 /* 0x9D */ CHAN_C
| NONEOS_C
,
893 /* 0x9E */ CHAN_C
| NONEOS_C
,
894 /* 0x9F */ CHAN_C
| NONEOS_C
,
895 /* 0xA0 */ CHAN_C
| FCHAN_C
| NONEOS_C
,
896 /* 0xA1 */ CHAN_C
| NONEOS_C
,
897 /* 0xA2 */ CHAN_C
| NONEOS_C
,
898 /* 0xA3 */ CHAN_C
| NONEOS_C
,
899 /* 0xA4 */ CHAN_C
| NONEOS_C
,
900 /* 0xA5 */ CHAN_C
| NONEOS_C
,
901 /* 0xA6 */ CHAN_C
| NONEOS_C
,
902 /* 0xA7 */ CHAN_C
| NONEOS_C
,
903 /* 0xA8 */ CHAN_C
| NONEOS_C
,
904 /* 0xA9 */ CHAN_C
| NONEOS_C
,
905 /* 0xAA */ CHAN_C
| NONEOS_C
,
906 /* 0xAB */ CHAN_C
| NONEOS_C
,
907 /* 0xAC */ CHAN_C
| NONEOS_C
,
908 /* 0xAD */ CHAN_C
| NONEOS_C
,
909 /* 0xAE */ CHAN_C
| NONEOS_C
,
910 /* 0xAF */ CHAN_C
| NONEOS_C
,
911 /* 0xB0 */ CHAN_C
| NONEOS_C
,
912 /* 0xB1 */ CHAN_C
| NONEOS_C
,
913 /* 0xB2 */ CHAN_C
| NONEOS_C
,
914 /* 0xB3 */ CHAN_C
| NONEOS_C
,
915 /* 0xB4 */ CHAN_C
| NONEOS_C
,
916 /* 0xB5 */ CHAN_C
| NONEOS_C
,
917 /* 0xB6 */ CHAN_C
| NONEOS_C
,
918 /* 0xB7 */ CHAN_C
| NONEOS_C
,
919 /* 0xB8 */ CHAN_C
| NONEOS_C
,
920 /* 0xB9 */ CHAN_C
| NONEOS_C
,
921 /* 0xBA */ CHAN_C
| NONEOS_C
,
922 /* 0xBB */ CHAN_C
| NONEOS_C
,
923 /* 0xBC */ CHAN_C
| NONEOS_C
,
924 /* 0xBD */ CHAN_C
| NONEOS_C
,
925 /* 0xBE */ CHAN_C
| NONEOS_C
,
926 /* 0xBF */ CHAN_C
| NONEOS_C
,
927 /* 0xC0 */ CHAN_C
| NONEOS_C
,
928 /* 0xC1 */ CHAN_C
| NONEOS_C
,
929 /* 0xC2 */ CHAN_C
| NONEOS_C
,
930 /* 0xC3 */ CHAN_C
| NONEOS_C
,
931 /* 0xC4 */ CHAN_C
| NONEOS_C
,
932 /* 0xC5 */ CHAN_C
| NONEOS_C
,
933 /* 0xC6 */ CHAN_C
| NONEOS_C
,
934 /* 0xC7 */ CHAN_C
| NONEOS_C
,
935 /* 0xC8 */ CHAN_C
| NONEOS_C
,
936 /* 0xC9 */ CHAN_C
| NONEOS_C
,
937 /* 0xCA */ CHAN_C
| NONEOS_C
,
938 /* 0xCB */ CHAN_C
| NONEOS_C
,
939 /* 0xCC */ CHAN_C
| NONEOS_C
,
940 /* 0xCD */ CHAN_C
| NONEOS_C
,
941 /* 0xCE */ CHAN_C
| NONEOS_C
,
942 /* 0xCF */ CHAN_C
| NONEOS_C
,
943 /* 0xD0 */ CHAN_C
| NONEOS_C
,
944 /* 0xD1 */ CHAN_C
| NONEOS_C
,
945 /* 0xD2 */ CHAN_C
| NONEOS_C
,
946 /* 0xD3 */ CHAN_C
| NONEOS_C
,
947 /* 0xD4 */ CHAN_C
| NONEOS_C
,
948 /* 0xD5 */ CHAN_C
| NONEOS_C
,
949 /* 0xD6 */ CHAN_C
| NONEOS_C
,
950 /* 0xD7 */ CHAN_C
| NONEOS_C
,
951 /* 0xD8 */ CHAN_C
| NONEOS_C
,
952 /* 0xD9 */ CHAN_C
| NONEOS_C
,
953 /* 0xDA */ CHAN_C
| NONEOS_C
,
954 /* 0xDB */ CHAN_C
| NONEOS_C
,
955 /* 0xDC */ CHAN_C
| NONEOS_C
,
956 /* 0xDD */ CHAN_C
| NONEOS_C
,
957 /* 0xDE */ CHAN_C
| NONEOS_C
,
958 /* 0xDF */ CHAN_C
| NONEOS_C
,
959 /* 0xE0 */ CHAN_C
| NONEOS_C
,
960 /* 0xE1 */ CHAN_C
| NONEOS_C
,
961 /* 0xE2 */ CHAN_C
| NONEOS_C
,
962 /* 0xE3 */ CHAN_C
| NONEOS_C
,
963 /* 0xE4 */ CHAN_C
| NONEOS_C
,
964 /* 0xE5 */ CHAN_C
| NONEOS_C
,
965 /* 0xE6 */ CHAN_C
| NONEOS_C
,
966 /* 0xE7 */ CHAN_C
| NONEOS_C
,
967 /* 0xE8 */ CHAN_C
| NONEOS_C
,
968 /* 0xE9 */ CHAN_C
| NONEOS_C
,
969 /* 0xEA */ CHAN_C
| NONEOS_C
,
970 /* 0xEB */ CHAN_C
| NONEOS_C
,
971 /* 0xEC */ CHAN_C
| NONEOS_C
,
972 /* 0xED */ CHAN_C
| NONEOS_C
,
973 /* 0xEE */ CHAN_C
| NONEOS_C
,
974 /* 0xEF */ CHAN_C
| NONEOS_C
,
975 /* 0xF0 */ CHAN_C
| NONEOS_C
,
976 /* 0xF1 */ CHAN_C
| NONEOS_C
,
977 /* 0xF2 */ CHAN_C
| NONEOS_C
,
978 /* 0xF3 */ CHAN_C
| NONEOS_C
,
979 /* 0xF4 */ CHAN_C
| NONEOS_C
,
980 /* 0xF5 */ CHAN_C
| NONEOS_C
,
981 /* 0xF6 */ CHAN_C
| NONEOS_C
,
982 /* 0xF7 */ CHAN_C
| NONEOS_C
,
983 /* 0xF8 */ CHAN_C
| NONEOS_C
,
984 /* 0xF9 */ CHAN_C
| NONEOS_C
,
985 /* 0xFA */ CHAN_C
| NONEOS_C
,
986 /* 0xFB */ CHAN_C
| NONEOS_C
,
987 /* 0xFC */ CHAN_C
| NONEOS_C
,
988 /* 0xFD */ CHAN_C
| NONEOS_C
,
989 /* 0xFE */ CHAN_C
| NONEOS_C
,
990 /* 0xFF */ CHAN_C
| NONEOS_C