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