]> jfr.im git - solanum.git/blame - ircd/match.c
librb mbedTLS: der_pubkey is used out of scope
[solanum.git] / ircd / match.c
CommitLineData
212380e3
AC
1/************************************************************************
2 * IRC - Internet Relay Chat, src/match.c
3 * Copyright (C) 1990 Jarkko Oikarinen
4 *
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)
8 * any later version.
9 *
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.
14 *
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.
18 *
212380e3
AC
19 */
20#include "stdinc.h"
9b8e9eb3 21#include "defaults.h"
212380e3
AC
22#include "client.h"
23#include "ircd.h"
4562c604 24#include "match.h"
dfeba655 25#include "s_conf.h"
77d3d2db 26#include "s_assert.h"
212380e3
AC
27
28/*
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.
32 *
33 * return 1, if match
34 * 0, if no match
35 *
36 * Originally by Douglas A Lewis (dalewis@acsu.buffalo.edu)
37 * Rewritten by Timothy Vogelsang (netski), net@astrolink.org
38 */
39
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.
44 *
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.
48 */
49int match(const char *mask, const char *name)
50{
51 const char *m = mask, *n = name;
52 const char *m_tmp = mask, *n_tmp = name;
53 int star_p;
54
55 s_assert(mask != NULL);
56 s_assert(name != NULL);
57
58 for (;;)
59 {
60 switch (*m)
61 {
62 case '\0':
63 if (!*n)
64 return 1;
65 backtrack:
66 if (m_tmp == mask)
67 return 0;
68 m = m_tmp;
69 n = ++n_tmp;
70 break;
71 case '*':
72 case '?':
73 for (star_p = 0;; m++)
74 {
75 if (*m == '*')
76 star_p = 1;
77 else if (*m == '?')
78 {
79 if (!*n++)
80 goto backtrack;
81 }
82 else
83 break;
84 }
85 if (star_p)
86 {
87 if (!*m)
88 return 1;
89 else
90 {
91 m_tmp = m;
7e6b5384 92 for (n_tmp = n; *n && irctolower(*n) != irctolower(*m); n++);
212380e3
AC
93 }
94 }
95 /* and fall through */
96 default:
97 if (!*n)
98 return (*m != '\0' ? 0 : 1);
7e6b5384 99 if (irctolower(*m) != irctolower(*n))
212380e3
AC
100 goto backtrack;
101 m++;
102 n++;
103 break;
104 }
105 }
106}
107
c1f9603b 108/* Reorder runs of [?*] in mask to the form ``**...??...'' */
57fbf053
EK
109void
110match_arrange_stars(char *mask)
111{
112 char *swap = NULL;
113
114 for (char *p = mask; *p != '\0'; p++)
115 {
116 switch (*p)
117 {
118 case '*':
119 if (swap == NULL) break;
120 *swap++ = '*';
121 *p = '?';
122 break;
123 case '?':
124 if (swap == NULL) swap = p;
125 break;
126 default:
127 swap = NULL;
128 break;
129 }
130 }
131}
132
df251055
JT
133/** Check a mask against a mask.
134 * This test checks using traditional IRC wildcards only: '*' means
135 * match zero or more characters of any type; '?' means match exactly
136 * one character of any type.
137 * The difference between mask_match() and match() is that in mask_match()
138 * a '?' in mask does not match a '*' in name.
139 *
140 * @param[in] mask Existing wildcard-containing mask.
141 * @param[in] name New wildcard-containing mask.
142 * @return 1 if \a name is equal to or more specific than \a mask, 0 otherwise.
143 */
57fbf053 144int mask_match(const char *mask_, const char *name)
df251055 145{
57fbf053 146 static char mask[BUFSIZE];
df251055
JT
147 const char *m = mask, *n = name;
148 const char *m_tmp = mask, *n_tmp = name;
77410390 149 size_t len;
df251055
JT
150 int star_p;
151
57fbf053 152 s_assert(mask_ != NULL);
df251055
JT
153 s_assert(name != NULL);
154
77410390
EK
155 len = rb_strlcpy(mask, mask_, sizeof mask);
156 s_assert(len < sizeof mask);
157 (void) len; /* for NDEBUG */
158
57fbf053
EK
159 match_arrange_stars(mask);
160
df251055
JT
161 for (;;)
162 {
163 switch (*m)
164 {
165 case '\0':
166 if (!*n)
167 return 1;
168 backtrack:
169 if (m_tmp == mask)
170 return 0;
171 m = m_tmp;
172 n = ++n_tmp;
173 break;
174 case '*':
175 case '?':
176 for (star_p = 0;; m++)
177 {
178 if (*m == '*')
179 star_p = 1;
180 else if (*m == '?')
181 {
182 /* changed for mask_match() */
57fbf053 183 while (star_p && *n == '*') n++;
df251055
JT
184 if (*n == '*' || !*n)
185 goto backtrack;
186 n++;
187 }
188 else
189 break;
190 }
191 if (star_p)
192 {
193 if (!*m)
194 return 1;
195 else
196 {
197 m_tmp = m;
7e6b5384 198 for (n_tmp = n; *n && irctolower(*n) != irctolower(*m); n++);
df251055
JT
199 }
200 }
201 /* and fall through */
202 default:
203 if (!*n)
204 return (*m != '\0' ? 0 : 1);
7e6b5384 205 if (irctolower(*m) != irctolower(*n))
df251055
JT
206 goto backtrack;
207 m++;
208 n++;
209 break;
210 }
211 }
212}
213
214
7eecdd68
JT
215#define MATCH_MAX_CALLS 512 /* ACK! This dies when it's less that this
216 and we have long lines to parse */
212380e3 217/** Check a string against a mask.
7eecdd68
JT
218 * This test checks using extended wildcards: '*' means match zero
219 * or more characters of any type; '?' means match exactly one
220 * character of any type; '#' means match exactly one character that
221 * is a number; '@' means match exactly one character that is a
222 * letter; '\s' means match a space.
212380e3 223 *
55abcbb2 224 * This function supports escaping, so that a wildcard may be matched
212380e3
AC
225 * exactly.
226 *
227 * @param[in] mask Wildcard-containing mask.
228 * @param[in] name String to check against \a mask.
229 * @return Zero if \a mask matches \a name, non-zero if no match.
230 */
7eecdd68
JT
231int
232match_esc(const char *mask, const char *name)
212380e3 233{
7eecdd68
JT
234 const unsigned char *m = (const unsigned char *)mask;
235 const unsigned char *n = (const unsigned char *)name;
236 const unsigned char *ma = (const unsigned char *)mask;
237 const unsigned char *na = (const unsigned char *)name;
238 int wild = 0;
239 int calls = 0;
240 int quote = 0;
241 int match1 = 0;
212380e3
AC
242
243 s_assert(mask != NULL);
244 s_assert(name != NULL);
245
7eecdd68
JT
246 if(!mask || !name)
247 return 0;
248
249 /* if the mask is "*", it matches everything */
250 if((*m == '*') && (*(m + 1) == '\0'))
251 return 1;
252
253 while(calls++ < MATCH_MAX_CALLS)
212380e3 254 {
7eecdd68
JT
255 if(quote)
256 quote++;
257 if(quote == 3)
258 quote = 0;
259 if(*m == '\\' && !quote)
212380e3 260 {
7eecdd68
JT
261 m++;
262 quote = 1;
263 continue;
264 }
265 if(!quote && *m == '*')
266 {
267 /*
268 * XXX - shouldn't need to spin here, the mask should have been
269 * collapsed before match is called
270 */
271 while(*m == '*')
272 m++;
273
274 wild = 1;
275 ma = m;
276 na = n;
277
278 if(*m == '\\')
279 {
280 m++;
281 /* This means it is an invalid mask -A1kmm. */
282 if(!*m)
283 return 0;
284 quote++;
285 continue;
286 }
287 }
288
289 if(!*m)
290 {
291 if(!*n)
292 return 1;
293 if(quote)
294 return 0;
5ef68b13
JT
295 for(m--; (m > (const unsigned char *)mask) && (*m == '?'); m--)
296 ;
7eecdd68
JT
297
298 if(*m == '*' && (m > (const unsigned char *)mask))
299 return 1;
300 if(!wild)
301 return 0;
302 m = ma;
303 n = ++na;
304 }
305 else if(!*n)
306 {
307 /*
308 * XXX - shouldn't need to spin here, the mask should have been
309 * collapsed before match is called
310 */
311 if(quote)
312 return 0;
313 while(*m == '*')
314 m++;
315 return (*m == 0);
316 }
317
318 if(quote)
7e6b5384 319 match1 = *m == 's' ? *n == ' ' : irctolower(*m) == irctolower(*n);
7eecdd68
JT
320 else if(*m == '?')
321 match1 = 1;
322 else if(*m == '@')
323 match1 = IsLetter(*n);
324 else if(*m == '#')
325 match1 = IsDigit(*n);
326 else
7e6b5384 327 match1 = irctolower(*m) == irctolower(*n);
7eecdd68
JT
328 if(match1)
329 {
330 if(*m)
331 m++;
332 if(*n)
333 n++;
334 }
335 else
336 {
337 if(!wild)
338 return 0;
339 m = ma;
340 n = ++na;
212380e3
AC
341 }
342 }
7eecdd68 343 return 0;
212380e3
AC
344}
345
4b11f391 346int comp_with_mask(void *addr, void *dest, unsigned int mask)
212380e3
AC
347{
348 if (memcmp(addr, dest, mask / 8) == 0)
349 {
350 int n = mask / 8;
d8f0b5d7 351 unsigned char m = (0xFF << (8 - (mask % 8)));
4b11f391 352 if (mask % 8 == 0 || (((unsigned char *) addr)[n] & m) == (((unsigned char *) dest)[n] & m))
212380e3
AC
353 {
354 return (1);
355 }
356 }
357 return (0);
358}
359
4b11f391 360int comp_with_mask_sock(struct sockaddr *addr, struct sockaddr *dest, unsigned int mask)
212380e3
AC
361{
362 void *iaddr = NULL;
363 void *idest = NULL;
364
365 if (addr->sa_family == AF_INET)
366 {
29c92cf9
JB
367 iaddr = &((struct sockaddr_in *)(void *)addr)->sin_addr;
368 idest = &((struct sockaddr_in *)(void *)dest)->sin_addr;
212380e3 369 }
212380e3
AC
370 else
371 {
29c92cf9
JB
372 iaddr = &((struct sockaddr_in6 *)(void *)addr)->sin6_addr;
373 idest = &((struct sockaddr_in6 *)(void *)dest)->sin6_addr;
212380e3
AC
374
375 }
212380e3
AC
376
377 return (comp_with_mask(iaddr, idest, mask));
378}
379
380/*
381 * match_ips()
382 *
383 * Input - cidr ip mask, address
384 */
385int match_ips(const char *s1, const char *s2)
386{
e7046ee5 387 struct rb_sockaddr_storage ipaddr, maskaddr;
212380e3
AC
388 char mask[BUFSIZE];
389 char address[HOSTLEN + 1];
390 char *len;
391 void *ipptr, *maskptr;
392 int cidrlen, aftype;
393
4d5a902f
AJ
394 rb_strlcpy(mask, s1, sizeof(mask));
395 rb_strlcpy(address, s2, sizeof(address));
212380e3
AC
396
397 len = strrchr(mask, '/');
398 if (len == NULL)
399 return 0;
400
401 *len++ = '\0';
402
403 cidrlen = atoi(len);
441da2f2 404 if (cidrlen <= 0)
212380e3
AC
405 return 0;
406
212380e3
AC
407 if (strchr(mask, ':') && strchr(address, ':'))
408 {
441da2f2
JT
409 if (cidrlen > 128)
410 return 0;
411
212380e3
AC
412 aftype = AF_INET6;
413 ipptr = &((struct sockaddr_in6 *)&ipaddr)->sin6_addr;
414 maskptr = &((struct sockaddr_in6 *)&maskaddr)->sin6_addr;
415 }
de293496 416 else if (!strchr(mask, ':') && !strchr(address, ':'))
212380e3 417 {
441da2f2
JT
418 if (cidrlen > 32)
419 return 0;
420
212380e3
AC
421 aftype = AF_INET;
422 ipptr = &((struct sockaddr_in *)&ipaddr)->sin_addr;
423 maskptr = &((struct sockaddr_in *)&maskaddr)->sin_addr;
424 }
425 else
426 return 0;
427
83e5941c
JT
428 if (rb_inet_pton(aftype, address, ipptr) <= 0)
429 return 0;
430 if (rb_inet_pton(aftype, mask, maskptr) <= 0)
431 return 0;
212380e3
AC
432 if (comp_with_mask(ipptr, maskptr, cidrlen))
433 return 1;
434 else
435 return 0;
436}
437
438/* match_cidr()
439 *
440 * Input - mask, address
441 * Ouput - 1 = Matched 0 = Did not match
442 */
443
444int match_cidr(const char *s1, const char *s2)
445{
e7046ee5 446 struct rb_sockaddr_storage ipaddr, maskaddr;
212380e3
AC
447 char mask[BUFSIZE];
448 char address[NICKLEN + USERLEN + HOSTLEN + 6];
449 char *ipmask;
450 char *ip;
451 char *len;
452 void *ipptr, *maskptr;
453 int cidrlen, aftype;
454
4d5a902f
AJ
455 rb_strlcpy(mask, s1, sizeof(mask));
456 rb_strlcpy(address, s2, sizeof(address));
212380e3
AC
457
458 ipmask = strrchr(mask, '@');
459 if (ipmask == NULL)
460 return 0;
461
462 *ipmask++ = '\0';
463
464 ip = strrchr(address, '@');
465 if (ip == NULL)
466 return 0;
467 *ip++ = '\0';
468
469
470 len = strrchr(ipmask, '/');
471 if (len == NULL)
472 return 0;
473
474 *len++ = '\0';
475
476 cidrlen = atoi(len);
4dbd5e07 477 if (cidrlen <= 0)
212380e3
AC
478 return 0;
479
212380e3
AC
480 if (strchr(ip, ':') && strchr(ipmask, ':'))
481 {
4dbd5e07
JT
482 if (cidrlen > 128)
483 return 0;
484
212380e3
AC
485 aftype = AF_INET6;
486 ipptr = &((struct sockaddr_in6 *)&ipaddr)->sin6_addr;
487 maskptr = &((struct sockaddr_in6 *)&maskaddr)->sin6_addr;
488 }
de293496 489 else if (!strchr(ip, ':') && !strchr(ipmask, ':'))
212380e3 490 {
4dbd5e07
JT
491 if (cidrlen > 32)
492 return 0;
493
212380e3
AC
494 aftype = AF_INET;
495 ipptr = &((struct sockaddr_in *)&ipaddr)->sin_addr;
496 maskptr = &((struct sockaddr_in *)&maskaddr)->sin_addr;
497 }
498 else
499 return 0;
500
83e5941c
JT
501 if (rb_inet_pton(aftype, ip, ipptr) <= 0)
502 return 0;
503 if (rb_inet_pton(aftype, ipmask, maskptr) <= 0)
504 return 0;
212380e3
AC
505 if (comp_with_mask(ipptr, maskptr, cidrlen) && match(mask, address))
506 return 1;
507 else
508 return 0;
509}
510
511/* collapse()
512 *
513 * collapses a string containing multiple *'s.
514 */
515char *collapse(char *pattern)
516{
517 char *p = pattern, *po = pattern;
518 char c;
519 int f = 0;
520
521 if (p == NULL)
522 return NULL;
523
524 while ((c = *p++))
525 {
526 if (c == '*')
527 {
528 if (!(f & 1))
529 *po++ = '*';
530 f |= 1;
531 }
532 else
533 {
534 *po++ = c;
535 f &= ~1;
536 }
537 }
538 *po++ = 0;
539
540 return pattern;
541}
542
543/* collapse_esc()
544 *
545 * The collapse() function with support for escaping characters
546 */
547char *collapse_esc(char *pattern)
548{
549 char *p = pattern, *po = pattern;
550 char c;
551 int f = 0;
552
553 if (p == NULL)
554 return NULL;
555
556 while ((c = *p++))
557 {
558 if (!(f & 2) && c == '*')
559 {
560 if (!(f & 1))
561 *po++ = '*';
562 f |= 1;
563 }
564 else if (!(f & 2) && c == '\\')
565 {
566 *po++ = '\\';
567 f |= 2;
568 }
569 else
570 {
571 *po++ = c;
572 f &= ~3;
573 }
574 }
575 *po++ = 0;
576 return pattern;
577}
578
579/*
580 * irccmp - case insensitive comparison of two 0 terminated strings.
581 *
582 * returns 0, if s1 equal to s2
583 * <0, if s1 lexicographically less than s2
584 * >0, if s1 lexicographically greater than s2
585 */
586int irccmp(const char *s1, const char *s2)
587{
588 const unsigned char *str1 = (const unsigned char *)s1;
589 const unsigned char *str2 = (const unsigned char *)s2;
590 int res;
591
592 s_assert(s1 != NULL);
593 s_assert(s2 != NULL);
594
7e6b5384 595 while ((res = irctoupper(*str1) - irctoupper(*str2)) == 0)
212380e3
AC
596 {
597 if (*str1 == '\0')
598 return 0;
599 str1++;
600 str2++;
601 }
602 return (res);
603}
604
605int ircncmp(const char *s1, const char *s2, int n)
606{
607 const unsigned char *str1 = (const unsigned char *)s1;
608 const unsigned char *str2 = (const unsigned char *)s2;
609 int res;
610 s_assert(s1 != NULL);
611 s_assert(s2 != NULL);
612
7e6b5384 613 while ((res = irctoupper(*str1) - irctoupper(*str2)) == 0)
212380e3
AC
614 {
615 str1++;
616 str2++;
617 n--;
618 if (n == 0 || (*str1 == '\0' && *str2 == '\0'))
619 return 0;
620 }
621 return (res);
622}
623
a7d4a0ab
EK
624void matchset_for_client(struct Client *who, struct matchset *m)
625{
dfeba655 626 bool hide_ip = IsIPSpoof(who) || (!ConfigChannel.ip_bans_through_vhost && IsDynSpoof(who));
a7d4a0ab
EK
627 unsigned hostn = 0;
628 unsigned ipn = 0;
629
630 struct sockaddr_in ip4;
631
632 sprintf(m->host[hostn++], "%s!%s@%s", who->name, who->username, who->host);
55ed78da 633
dfeba655 634 if (!hide_ip)
55ed78da
EK
635 {
636 sprintf(m->ip[ipn++], "%s!%s@%s", who->name, who->username, who->sockhost);
637 }
638
a7d4a0ab
EK
639 if (who->localClient->mangledhost != NULL)
640 {
641 /* if host mangling mode enabled, also check their real host */
642 if (!strcmp(who->host, who->localClient->mangledhost))
643 {
644 sprintf(m->host[hostn++], "%s!%s@%s", who->name, who->username, who->orighost);
645 }
646 /* if host mangling mode not enabled and no other spoof,
647 * also check the mangled form of their host */
648 else if (!IsDynSpoof(who))
649 {
650 sprintf(m->host[hostn++], "%s!%s@%s", who->name, who->username, who->localClient->mangledhost);
651 }
652 }
dfeba655 653 if (!hide_ip && GET_SS_FAMILY(&who->localClient->ip) == AF_INET6 &&
a7d4a0ab
EK
654 rb_ipv4_from_ipv6((const struct sockaddr_in6 *)&who->localClient->ip, &ip4))
655 {
656 int n = sprintf(m->ip[ipn++], "%s!%s@", who->name, who->username);
657 rb_inet_ntop_sock((struct sockaddr *)&ip4,
658 m->ip[ipn] + n, sizeof m->ip[ipn] - n);
659 }
660
661 for (int i = hostn; i < ARRAY_SIZE(m->host); i++)
662 {
663 m->host[i][0] = '\0';
664 }
665 for (int i = ipn; i < ARRAY_SIZE(m->ip); i++)
666 {
667 m->ip[i][0] = '\0';
668 }
669}
670
671bool client_matches_mask(struct Client *who, const char *mask)
672{
673 static struct matchset ms;
674 matchset_for_client(who, &ms);
675 return matches_mask(&ms, mask);
676}
677
678bool matches_mask(const struct matchset *m, const char *mask)
679{
680 for (int i = 0; i < ARRAY_SIZE(m->host); i++)
681 {
682 if (m->host[i][0] == '\0')
683 break;
684 if (match(mask, m->host[i]))
685 return true;
686 }
687 for (int i = 0; i < ARRAY_SIZE(m->ip); i++)
688 {
689 if (m->ip[i][0] == '\0')
690 break;
691 if (match(mask, m->ip[i]))
692 return true;
693 if (match_cidr(mask, m->ip[i]))
694 return true;
695 }
696 return false;
697}
698
7e6b5384 699const unsigned char irctolower_tab[] = {
212380e3
AC
700 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
701 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
702 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
703 0x1e, 0x1f,
704 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
705 '*', '+', ',', '-', '.', '/',
706 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
707 ':', ';', '<', '=', '>', '?',
708 '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
709 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
710 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
711 '_',
712 '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
713 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
714 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
715 0x7f,
716 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
717 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
718 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
719 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
720 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
721 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
722 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
723 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
724 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
725 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
726 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
727 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
728 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
729 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
730 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
731 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
732};
733
7e6b5384 734const unsigned char irctoupper_tab[] = {
212380e3
AC
735 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
736 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
737 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
738 0x1e, 0x1f,
739 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
740 '*', '+', ',', '-', '.', '/',
741 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
742 ':', ';', '<', '=', '>', '?',
743 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
744 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
745 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
746 0x5f,
747 '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
748 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
749 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
750 0x7f,
751 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
752 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
753 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
754 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
755 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
756 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
757 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
758 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
759 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
760 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
761 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
762 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
763 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
764 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
765 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
766 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
767};
768
769/*
770 * CharAttrs table
771 *
772 * NOTE: RFC 1459 sez: anything but a ^G, comma, or space is allowed
773 * for channel names
774 */
f3b84221 775unsigned int CharAttrs[] = {
212380e3
AC
776/* 0 */ CNTRL_C,
777/* 1 */ CNTRL_C | CHAN_C | NONEOS_C,
778/* 2 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
779/* 3 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
780/* 4 */ CNTRL_C | CHAN_C | NONEOS_C,
781/* 5 */ CNTRL_C | CHAN_C | NONEOS_C,
782/* 6 */ CNTRL_C | CHAN_C | NONEOS_C,
783/* 7 BEL */ CNTRL_C | NONEOS_C,
784/* 8 \b */ CNTRL_C | CHAN_C | NONEOS_C,
785/* 9 \t */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C,
786/* 10 \n */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C | EOL_C,
787/* 11 \v */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C,
788/* 12 \f */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C,
789/* 13 \r */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C | EOL_C,
790/* 14 */ CNTRL_C | CHAN_C | NONEOS_C,
791/* 15 */ CNTRL_C | CHAN_C | NONEOS_C,
792/* 16 */ CNTRL_C | CHAN_C | NONEOS_C,
793/* 17 */ CNTRL_C | CHAN_C | NONEOS_C,
794/* 18 */ CNTRL_C | CHAN_C | NONEOS_C,
795/* 19 */ CNTRL_C | CHAN_C | NONEOS_C,
796/* 20 */ CNTRL_C | CHAN_C | NONEOS_C,
797/* 21 */ CNTRL_C | CHAN_C | NONEOS_C,
798/* 22 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
799/* 23 */ CNTRL_C | CHAN_C | NONEOS_C,
800/* 24 */ CNTRL_C | CHAN_C | NONEOS_C,
801/* 25 */ CNTRL_C | CHAN_C | NONEOS_C,
802/* 26 */ CNTRL_C | CHAN_C | NONEOS_C,
803/* 27 */ CNTRL_C | CHAN_C | NONEOS_C,
804/* 28 */ CNTRL_C | CHAN_C | NONEOS_C,
b19d3c51 805/* 29 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
212380e3
AC
806/* 30 */ CNTRL_C | CHAN_C | NONEOS_C,
807/* 31 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
808/* SP */ PRINT_C | SPACE_C,
809/* ! */ PRINT_C | KWILD_C | CHAN_C | NONEOS_C,
810/* " */ PRINT_C | CHAN_C | NONEOS_C,
811/* # */ PRINT_C | MWILD_C | CHANPFX_C | CHAN_C | NONEOS_C,
f2edb2be 812/* $ */ PRINT_C | CHAN_C | NONEOS_C,
212380e3
AC
813/* % */ PRINT_C | CHAN_C | NONEOS_C,
814/* & */ PRINT_C | CHANPFX_C | CHAN_C | NONEOS_C,
815/* ' */ PRINT_C | CHAN_C | NONEOS_C,
816/* ( */ PRINT_C | CHAN_C | NONEOS_C,
817/* ) */ PRINT_C | CHAN_C | NONEOS_C,
e5d9ca18 818/* * */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C,
212380e3
AC
819/* + */ PRINT_C | CHAN_C | NONEOS_C,
820/* , */ PRINT_C | NONEOS_C,
821/* - */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
822/* . */ PRINT_C | KWILD_C | CHAN_C | NONEOS_C | USER_C | HOST_C | SERV_C,
9a180ae3 823/* / */ PRINT_C | CHAN_C | NONEOS_C | HOST_C,
212380e3
AC
824/* 0 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
825/* 1 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
826/* 2 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
827/* 3 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
828/* 4 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
829/* 5 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
830/* 6 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
831/* 7 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
832/* 8 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
833/* 9 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
834/* : */ PRINT_C | CHAN_C | NONEOS_C | HOST_C,
835/* ; */ PRINT_C | CHAN_C | NONEOS_C,
836/* < */ PRINT_C | CHAN_C | NONEOS_C,
837/* = */ PRINT_C | CHAN_C | NONEOS_C,
838/* > */ PRINT_C | CHAN_C | NONEOS_C,
839/* ? */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C,
840/* @ */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C,
841/* A */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
842/* B */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
843/* C */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
844/* D */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
845/* E */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
846/* F */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
847/* G */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
848/* H */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
849/* I */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
850/* J */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
851/* K */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
852/* L */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
853/* M */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
854/* N */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
855/* O */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
856/* P */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
857/* Q */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
858/* R */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
859/* S */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
860/* T */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
861/* U */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
862/* V */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
863/* W */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
864/* X */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
865/* Y */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
866/* Z */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_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 | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
870/* ^ */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
871/* _ */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
872/* ` */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
873/* a */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
874/* b */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
875/* c */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
876/* d */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
877/* e */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
878/* f */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
879/* g */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
880/* h */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
881/* i */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
882/* j */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
883/* k */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
884/* l */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
885/* m */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
886/* n */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
887/* o */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
888/* p */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
889/* q */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
890/* r */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
891/* s */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
892/* t */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
893/* u */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
894/* v */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
895/* w */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
896/* x */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
897/* y */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
898/* z */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
899/* { */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
900/* | */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
901/* } */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
902/* ~ */ PRINT_C | ALPHA_C | CHAN_C | NONEOS_C | USER_C,
903/* del */ CHAN_C | NONEOS_C,
904/* 0x80 */ CHAN_C | NONEOS_C,
905/* 0x81 */ CHAN_C | NONEOS_C,
906/* 0x82 */ CHAN_C | NONEOS_C,
907/* 0x83 */ CHAN_C | NONEOS_C,
908/* 0x84 */ CHAN_C | NONEOS_C,
909/* 0x85 */ CHAN_C | NONEOS_C,
910/* 0x86 */ CHAN_C | NONEOS_C,
911/* 0x87 */ CHAN_C | NONEOS_C,
912/* 0x88 */ CHAN_C | NONEOS_C,
913/* 0x89 */ CHAN_C | NONEOS_C,
914/* 0x8A */ CHAN_C | NONEOS_C,
915/* 0x8B */ CHAN_C | NONEOS_C,
916/* 0x8C */ CHAN_C | NONEOS_C,
917/* 0x8D */ CHAN_C | NONEOS_C,
918/* 0x8E */ CHAN_C | NONEOS_C,
919/* 0x8F */ CHAN_C | NONEOS_C,
920/* 0x90 */ CHAN_C | NONEOS_C,
921/* 0x91 */ CHAN_C | NONEOS_C,
922/* 0x92 */ CHAN_C | NONEOS_C,
923/* 0x93 */ CHAN_C | NONEOS_C,
924/* 0x94 */ CHAN_C | NONEOS_C,
925/* 0x95 */ CHAN_C | NONEOS_C,
926/* 0x96 */ CHAN_C | NONEOS_C,
927/* 0x97 */ CHAN_C | NONEOS_C,
928/* 0x98 */ CHAN_C | NONEOS_C,
929/* 0x99 */ CHAN_C | NONEOS_C,
930/* 0x9A */ CHAN_C | NONEOS_C,
931/* 0x9B */ CHAN_C | NONEOS_C,
932/* 0x9C */ CHAN_C | NONEOS_C,
933/* 0x9D */ CHAN_C | NONEOS_C,
934/* 0x9E */ CHAN_C | NONEOS_C,
935/* 0x9F */ CHAN_C | NONEOS_C,
936/* 0xA0 */ CHAN_C | FCHAN_C | NONEOS_C,
937/* 0xA1 */ CHAN_C | NONEOS_C,
938/* 0xA2 */ CHAN_C | NONEOS_C,
939/* 0xA3 */ CHAN_C | NONEOS_C,
940/* 0xA4 */ CHAN_C | NONEOS_C,
941/* 0xA5 */ CHAN_C | NONEOS_C,
942/* 0xA6 */ CHAN_C | NONEOS_C,
943/* 0xA7 */ CHAN_C | NONEOS_C,
944/* 0xA8 */ CHAN_C | NONEOS_C,
945/* 0xA9 */ CHAN_C | NONEOS_C,
946/* 0xAA */ CHAN_C | NONEOS_C,
947/* 0xAB */ CHAN_C | NONEOS_C,
948/* 0xAC */ CHAN_C | NONEOS_C,
949/* 0xAD */ CHAN_C | NONEOS_C,
950/* 0xAE */ CHAN_C | NONEOS_C,
951/* 0xAF */ CHAN_C | NONEOS_C,
952/* 0xB0 */ CHAN_C | NONEOS_C,
953/* 0xB1 */ CHAN_C | NONEOS_C,
954/* 0xB2 */ CHAN_C | NONEOS_C,
955/* 0xB3 */ CHAN_C | NONEOS_C,
956/* 0xB4 */ CHAN_C | NONEOS_C,
957/* 0xB5 */ CHAN_C | NONEOS_C,
958/* 0xB6 */ CHAN_C | NONEOS_C,
959/* 0xB7 */ CHAN_C | NONEOS_C,
960/* 0xB8 */ CHAN_C | NONEOS_C,
961/* 0xB9 */ CHAN_C | NONEOS_C,
962/* 0xBA */ CHAN_C | NONEOS_C,
963/* 0xBB */ CHAN_C | NONEOS_C,
964/* 0xBC */ CHAN_C | NONEOS_C,
965/* 0xBD */ CHAN_C | NONEOS_C,
966/* 0xBE */ CHAN_C | NONEOS_C,
967/* 0xBF */ CHAN_C | NONEOS_C,
968/* 0xC0 */ CHAN_C | NONEOS_C,
969/* 0xC1 */ CHAN_C | NONEOS_C,
970/* 0xC2 */ CHAN_C | NONEOS_C,
971/* 0xC3 */ CHAN_C | NONEOS_C,
972/* 0xC4 */ CHAN_C | NONEOS_C,
973/* 0xC5 */ CHAN_C | NONEOS_C,
974/* 0xC6 */ CHAN_C | NONEOS_C,
975/* 0xC7 */ CHAN_C | NONEOS_C,
976/* 0xC8 */ CHAN_C | NONEOS_C,
977/* 0xC9 */ CHAN_C | NONEOS_C,
978/* 0xCA */ CHAN_C | NONEOS_C,
979/* 0xCB */ CHAN_C | NONEOS_C,
980/* 0xCC */ CHAN_C | NONEOS_C,
981/* 0xCD */ CHAN_C | NONEOS_C,
982/* 0xCE */ CHAN_C | NONEOS_C,
983/* 0xCF */ CHAN_C | NONEOS_C,
984/* 0xD0 */ CHAN_C | NONEOS_C,
985/* 0xD1 */ CHAN_C | NONEOS_C,
986/* 0xD2 */ CHAN_C | NONEOS_C,
987/* 0xD3 */ CHAN_C | NONEOS_C,
988/* 0xD4 */ CHAN_C | NONEOS_C,
989/* 0xD5 */ CHAN_C | NONEOS_C,
990/* 0xD6 */ CHAN_C | NONEOS_C,
991/* 0xD7 */ CHAN_C | NONEOS_C,
992/* 0xD8 */ CHAN_C | NONEOS_C,
993/* 0xD9 */ CHAN_C | NONEOS_C,
994/* 0xDA */ CHAN_C | NONEOS_C,
995/* 0xDB */ CHAN_C | NONEOS_C,
996/* 0xDC */ CHAN_C | NONEOS_C,
997/* 0xDD */ CHAN_C | NONEOS_C,
998/* 0xDE */ CHAN_C | NONEOS_C,
999/* 0xDF */ CHAN_C | NONEOS_C,
1000/* 0xE0 */ CHAN_C | NONEOS_C,
1001/* 0xE1 */ CHAN_C | NONEOS_C,
1002/* 0xE2 */ CHAN_C | NONEOS_C,
1003/* 0xE3 */ CHAN_C | NONEOS_C,
1004/* 0xE4 */ CHAN_C | NONEOS_C,
1005/* 0xE5 */ CHAN_C | NONEOS_C,
1006/* 0xE6 */ CHAN_C | NONEOS_C,
1007/* 0xE7 */ CHAN_C | NONEOS_C,
1008/* 0xE8 */ CHAN_C | NONEOS_C,
1009/* 0xE9 */ CHAN_C | NONEOS_C,
1010/* 0xEA */ CHAN_C | NONEOS_C,
1011/* 0xEB */ CHAN_C | NONEOS_C,
1012/* 0xEC */ CHAN_C | NONEOS_C,
1013/* 0xED */ CHAN_C | NONEOS_C,
1014/* 0xEE */ CHAN_C | NONEOS_C,
1015/* 0xEF */ CHAN_C | NONEOS_C,
1016/* 0xF0 */ CHAN_C | NONEOS_C,
1017/* 0xF1 */ CHAN_C | NONEOS_C,
1018/* 0xF2 */ CHAN_C | NONEOS_C,
1019/* 0xF3 */ CHAN_C | NONEOS_C,
1020/* 0xF4 */ CHAN_C | NONEOS_C,
1021/* 0xF5 */ CHAN_C | NONEOS_C,
1022/* 0xF6 */ CHAN_C | NONEOS_C,
1023/* 0xF7 */ CHAN_C | NONEOS_C,
1024/* 0xF8 */ CHAN_C | NONEOS_C,
1025/* 0xF9 */ CHAN_C | NONEOS_C,
1026/* 0xFA */ CHAN_C | NONEOS_C,
1027/* 0xFB */ CHAN_C | NONEOS_C,
1028/* 0xFC */ CHAN_C | NONEOS_C,
1029/* 0xFD */ CHAN_C | NONEOS_C,
1030/* 0xFE */ CHAN_C | NONEOS_C,
1031/* 0xFF */ CHAN_C | NONEOS_C
1032};