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