]> jfr.im git - solanum.git/blame - ircd/match.c
Add .travis.yml
[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 *
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 190 *
55abcbb2 191 * This function supports escaping, so that a wildcard may be matched
212380e3
AC
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;
5ef68b13
JT
262 for(m--; (m > (const unsigned char *)mask) && (*m == '?'); m--)
263 ;
7eecdd68
JT
264
265 if(*m == '*' && (m > (const unsigned char *)mask))
266 return 1;
267 if(!wild)
268 return 0;
269 m = ma;
270 n = ++na;
271 }
272 else if(!*n)
273 {
274 /*
275 * XXX - shouldn't need to spin here, the mask should have been
276 * collapsed before match is called
277 */
278 if(quote)
279 return 0;
280 while(*m == '*')
281 m++;
282 return (*m == 0);
283 }
284
285 if(quote)
286 match1 = *m == 's' ? *n == ' ' : ToLower(*m) == ToLower(*n);
287 else if(*m == '?')
288 match1 = 1;
289 else if(*m == '@')
290 match1 = IsLetter(*n);
291 else if(*m == '#')
292 match1 = IsDigit(*n);
293 else
294 match1 = ToLower(*m) == ToLower(*n);
295 if(match1)
296 {
297 if(*m)
298 m++;
299 if(*n)
300 n++;
301 }
302 else
303 {
304 if(!wild)
305 return 0;
306 m = ma;
307 n = ++na;
212380e3
AC
308 }
309 }
7eecdd68 310 return 0;
212380e3
AC
311}
312
313int comp_with_mask(void *addr, void *dest, u_int mask)
314{
315 if (memcmp(addr, dest, mask / 8) == 0)
316 {
317 int n = mask / 8;
318 int m = ((-1) << (8 - (mask % 8)));
319 if (mask % 8 == 0 || (((u_char *) addr)[n] & m) == (((u_char *) dest)[n] & m))
320 {
321 return (1);
322 }
323 }
324 return (0);
325}
326
327int comp_with_mask_sock(struct sockaddr *addr, struct sockaddr *dest, u_int mask)
328{
329 void *iaddr = NULL;
330 void *idest = NULL;
331
332 if (addr->sa_family == AF_INET)
333 {
29c92cf9
JB
334 iaddr = &((struct sockaddr_in *)(void *)addr)->sin_addr;
335 idest = &((struct sockaddr_in *)(void *)dest)->sin_addr;
212380e3 336 }
ccda6e3f 337#ifdef RB_IPV6
212380e3
AC
338 else
339 {
29c92cf9
JB
340 iaddr = &((struct sockaddr_in6 *)(void *)addr)->sin6_addr;
341 idest = &((struct sockaddr_in6 *)(void *)dest)->sin6_addr;
212380e3
AC
342
343 }
344#endif
345
346 return (comp_with_mask(iaddr, idest, mask));
347}
348
349/*
350 * match_ips()
351 *
352 * Input - cidr ip mask, address
353 */
354int match_ips(const char *s1, const char *s2)
355{
e7046ee5 356 struct rb_sockaddr_storage ipaddr, maskaddr;
212380e3
AC
357 char mask[BUFSIZE];
358 char address[HOSTLEN + 1];
359 char *len;
360 void *ipptr, *maskptr;
361 int cidrlen, aftype;
362
363 strcpy(mask, s1);
364 strcpy(address, s2);
365
366 len = strrchr(mask, '/');
367 if (len == NULL)
368 return 0;
369
370 *len++ = '\0';
371
372 cidrlen = atoi(len);
441da2f2 373 if (cidrlen <= 0)
212380e3
AC
374 return 0;
375
ccda6e3f 376#ifdef RB_IPV6
212380e3
AC
377 if (strchr(mask, ':') && strchr(address, ':'))
378 {
441da2f2
JT
379 if (cidrlen > 128)
380 return 0;
381
212380e3
AC
382 aftype = AF_INET6;
383 ipptr = &((struct sockaddr_in6 *)&ipaddr)->sin6_addr;
384 maskptr = &((struct sockaddr_in6 *)&maskaddr)->sin6_addr;
385 }
386 else
387#endif
388 if (!strchr(mask, ':') && !strchr(address, ':'))
389 {
441da2f2
JT
390 if (cidrlen > 32)
391 return 0;
392
212380e3
AC
393 aftype = AF_INET;
394 ipptr = &((struct sockaddr_in *)&ipaddr)->sin_addr;
395 maskptr = &((struct sockaddr_in *)&maskaddr)->sin_addr;
396 }
397 else
398 return 0;
399
83e5941c
JT
400 if (rb_inet_pton(aftype, address, ipptr) <= 0)
401 return 0;
402 if (rb_inet_pton(aftype, mask, maskptr) <= 0)
403 return 0;
212380e3
AC
404 if (comp_with_mask(ipptr, maskptr, cidrlen))
405 return 1;
406 else
407 return 0;
408}
409
410/* match_cidr()
411 *
412 * Input - mask, address
413 * Ouput - 1 = Matched 0 = Did not match
414 */
415
416int match_cidr(const char *s1, const char *s2)
417{
e7046ee5 418 struct rb_sockaddr_storage ipaddr, maskaddr;
212380e3
AC
419 char mask[BUFSIZE];
420 char address[NICKLEN + USERLEN + HOSTLEN + 6];
421 char *ipmask;
422 char *ip;
423 char *len;
424 void *ipptr, *maskptr;
425 int cidrlen, aftype;
426
427 strcpy(mask, s1);
428 strcpy(address, s2);
429
430 ipmask = strrchr(mask, '@');
431 if (ipmask == NULL)
432 return 0;
433
434 *ipmask++ = '\0';
435
436 ip = strrchr(address, '@');
437 if (ip == NULL)
438 return 0;
439 *ip++ = '\0';
440
441
442 len = strrchr(ipmask, '/');
443 if (len == NULL)
444 return 0;
445
446 *len++ = '\0';
447
448 cidrlen = atoi(len);
4dbd5e07 449 if (cidrlen <= 0)
212380e3
AC
450 return 0;
451
ccda6e3f 452#ifdef RB_IPV6
212380e3
AC
453 if (strchr(ip, ':') && strchr(ipmask, ':'))
454 {
4dbd5e07
JT
455 if (cidrlen > 128)
456 return 0;
457
212380e3
AC
458 aftype = AF_INET6;
459 ipptr = &((struct sockaddr_in6 *)&ipaddr)->sin6_addr;
460 maskptr = &((struct sockaddr_in6 *)&maskaddr)->sin6_addr;
461 }
462 else
463#endif
464 if (!strchr(ip, ':') && !strchr(ipmask, ':'))
465 {
4dbd5e07
JT
466 if (cidrlen > 32)
467 return 0;
468
212380e3
AC
469 aftype = AF_INET;
470 ipptr = &((struct sockaddr_in *)&ipaddr)->sin_addr;
471 maskptr = &((struct sockaddr_in *)&maskaddr)->sin_addr;
472 }
473 else
474 return 0;
475
83e5941c
JT
476 if (rb_inet_pton(aftype, ip, ipptr) <= 0)
477 return 0;
478 if (rb_inet_pton(aftype, ipmask, maskptr) <= 0)
479 return 0;
212380e3
AC
480 if (comp_with_mask(ipptr, maskptr, cidrlen) && match(mask, address))
481 return 1;
482 else
483 return 0;
484}
485
486/* collapse()
487 *
488 * collapses a string containing multiple *'s.
489 */
490char *collapse(char *pattern)
491{
492 char *p = pattern, *po = pattern;
493 char c;
494 int f = 0;
495
496 if (p == NULL)
497 return NULL;
498
499 while ((c = *p++))
500 {
501 if (c == '*')
502 {
503 if (!(f & 1))
504 *po++ = '*';
505 f |= 1;
506 }
507 else
508 {
509 *po++ = c;
510 f &= ~1;
511 }
512 }
513 *po++ = 0;
514
515 return pattern;
516}
517
518/* collapse_esc()
519 *
520 * The collapse() function with support for escaping characters
521 */
522char *collapse_esc(char *pattern)
523{
524 char *p = pattern, *po = pattern;
525 char c;
526 int f = 0;
527
528 if (p == NULL)
529 return NULL;
530
531 while ((c = *p++))
532 {
533 if (!(f & 2) && c == '*')
534 {
535 if (!(f & 1))
536 *po++ = '*';
537 f |= 1;
538 }
539 else if (!(f & 2) && c == '\\')
540 {
541 *po++ = '\\';
542 f |= 2;
543 }
544 else
545 {
546 *po++ = c;
547 f &= ~3;
548 }
549 }
550 *po++ = 0;
551 return pattern;
552}
553
554/*
555 * irccmp - case insensitive comparison of two 0 terminated strings.
556 *
557 * returns 0, if s1 equal to s2
558 * <0, if s1 lexicographically less than s2
559 * >0, if s1 lexicographically greater than s2
560 */
561int irccmp(const char *s1, const char *s2)
562{
563 const unsigned char *str1 = (const unsigned char *)s1;
564 const unsigned char *str2 = (const unsigned char *)s2;
565 int res;
566
567 s_assert(s1 != NULL);
568 s_assert(s2 != NULL);
569
570 while ((res = ToUpper(*str1) - ToUpper(*str2)) == 0)
571 {
572 if (*str1 == '\0')
573 return 0;
574 str1++;
575 str2++;
576 }
577 return (res);
578}
579
580int ircncmp(const char *s1, const char *s2, int n)
581{
582 const unsigned char *str1 = (const unsigned char *)s1;
583 const unsigned char *str2 = (const unsigned char *)s2;
584 int res;
585 s_assert(s1 != NULL);
586 s_assert(s2 != NULL);
587
588 while ((res = ToUpper(*str1) - ToUpper(*str2)) == 0)
589 {
590 str1++;
591 str2++;
592 n--;
593 if (n == 0 || (*str1 == '\0' && *str2 == '\0'))
594 return 0;
595 }
596 return (res);
597}
598
599const unsigned char ToLowerTab[] = {
600 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
601 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
602 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
603 0x1e, 0x1f,
604 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
605 '*', '+', ',', '-', '.', '/',
606 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
607 ':', ';', '<', '=', '>', '?',
608 '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
609 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
610 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
611 '_',
612 '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
613 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
614 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
615 0x7f,
616 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
617 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
618 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
619 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
620 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
621 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
622 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
623 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
624 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
625 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
626 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
627 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
628 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
629 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
630 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
631 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
632};
633
634const unsigned char ToUpperTab[] = {
635 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
636 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
637 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
638 0x1e, 0x1f,
639 ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
640 '*', '+', ',', '-', '.', '/',
641 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
642 ':', ';', '<', '=', '>', '?',
643 '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
644 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
645 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
646 0x5f,
647 '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
648 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
649 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
650 0x7f,
651 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
652 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
653 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
654 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
655 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
656 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
657 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
658 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
659 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
660 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
661 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
662 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
663 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
664 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
665 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
666 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
667};
668
669/*
670 * CharAttrs table
671 *
672 * NOTE: RFC 1459 sez: anything but a ^G, comma, or space is allowed
673 * for channel names
674 */
675const unsigned int CharAttrs[] = {
676/* 0 */ CNTRL_C,
677/* 1 */ CNTRL_C | CHAN_C | NONEOS_C,
678/* 2 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
679/* 3 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
680/* 4 */ CNTRL_C | CHAN_C | NONEOS_C,
681/* 5 */ CNTRL_C | CHAN_C | NONEOS_C,
682/* 6 */ CNTRL_C | CHAN_C | NONEOS_C,
683/* 7 BEL */ CNTRL_C | NONEOS_C,
684/* 8 \b */ CNTRL_C | CHAN_C | NONEOS_C,
685/* 9 \t */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C,
686/* 10 \n */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C | EOL_C,
687/* 11 \v */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C,
688/* 12 \f */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C,
689/* 13 \r */ CNTRL_C | SPACE_C | CHAN_C | NONEOS_C | EOL_C,
690/* 14 */ CNTRL_C | CHAN_C | NONEOS_C,
691/* 15 */ CNTRL_C | CHAN_C | NONEOS_C,
692/* 16 */ CNTRL_C | CHAN_C | NONEOS_C,
693/* 17 */ CNTRL_C | CHAN_C | NONEOS_C,
694/* 18 */ CNTRL_C | CHAN_C | NONEOS_C,
695/* 19 */ CNTRL_C | CHAN_C | NONEOS_C,
696/* 20 */ CNTRL_C | CHAN_C | NONEOS_C,
697/* 21 */ CNTRL_C | CHAN_C | NONEOS_C,
698/* 22 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
699/* 23 */ CNTRL_C | CHAN_C | NONEOS_C,
700/* 24 */ CNTRL_C | CHAN_C | NONEOS_C,
701/* 25 */ CNTRL_C | CHAN_C | NONEOS_C,
702/* 26 */ CNTRL_C | CHAN_C | NONEOS_C,
703/* 27 */ CNTRL_C | CHAN_C | NONEOS_C,
704/* 28 */ CNTRL_C | CHAN_C | NONEOS_C,
b19d3c51 705/* 29 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
212380e3
AC
706/* 30 */ CNTRL_C | CHAN_C | NONEOS_C,
707/* 31 */ CNTRL_C | CHAN_C | FCHAN_C | NONEOS_C,
708/* SP */ PRINT_C | SPACE_C,
709/* ! */ PRINT_C | KWILD_C | CHAN_C | NONEOS_C,
710/* " */ PRINT_C | CHAN_C | NONEOS_C,
711/* # */ PRINT_C | MWILD_C | CHANPFX_C | CHAN_C | NONEOS_C,
f2edb2be 712/* $ */ PRINT_C | CHAN_C | NONEOS_C,
212380e3
AC
713/* % */ PRINT_C | CHAN_C | NONEOS_C,
714/* & */ PRINT_C | CHANPFX_C | CHAN_C | NONEOS_C,
715/* ' */ PRINT_C | CHAN_C | NONEOS_C,
716/* ( */ PRINT_C | CHAN_C | NONEOS_C,
717/* ) */ PRINT_C | CHAN_C | NONEOS_C,
e5d9ca18 718/* * */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C,
212380e3
AC
719/* + */ PRINT_C | CHAN_C | NONEOS_C,
720/* , */ PRINT_C | NONEOS_C,
721/* - */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
722/* . */ PRINT_C | KWILD_C | CHAN_C | NONEOS_C | USER_C | HOST_C | SERV_C,
9a180ae3 723/* / */ PRINT_C | CHAN_C | NONEOS_C | HOST_C,
212380e3
AC
724/* 0 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
725/* 1 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
726/* 2 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
727/* 3 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
728/* 4 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
729/* 5 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
730/* 6 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
731/* 7 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
732/* 8 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
733/* 9 */ PRINT_C | DIGIT_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
734/* : */ PRINT_C | CHAN_C | NONEOS_C | HOST_C,
735/* ; */ PRINT_C | CHAN_C | NONEOS_C,
736/* < */ PRINT_C | CHAN_C | NONEOS_C,
737/* = */ PRINT_C | CHAN_C | NONEOS_C,
738/* > */ PRINT_C | CHAN_C | NONEOS_C,
739/* ? */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C,
740/* @ */ PRINT_C | KWILD_C | MWILD_C | CHAN_C | NONEOS_C,
741/* A */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
742/* B */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
743/* C */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
744/* D */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
745/* E */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
746/* F */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
747/* G */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
748/* H */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
749/* I */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
750/* J */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
751/* K */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
752/* L */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
753/* M */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
754/* N */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
755/* O */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
756/* P */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
757/* Q */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
758/* R */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
759/* S */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
760/* T */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
761/* U */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
762/* V */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
763/* W */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
764/* X */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
765/* Y */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
766/* Z */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
767/* [ */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
768/* \ */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
769/* ] */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
770/* ^ */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
771/* _ */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
772/* ` */ PRINT_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
773/* a */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
774/* b */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
775/* c */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
776/* d */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
777/* e */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
778/* f */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
779/* g */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
780/* h */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
781/* i */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
782/* j */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
783/* k */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
784/* l */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
785/* m */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
786/* n */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
787/* o */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
788/* p */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
789/* q */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
790/* r */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
791/* s */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
792/* t */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
793/* u */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
794/* v */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
795/* w */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
796/* x */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
797/* y */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
798/* z */ PRINT_C | ALPHA_C | LET_C | NICK_C | CHAN_C | NONEOS_C | USER_C | HOST_C,
799/* { */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
800/* | */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
801/* } */ PRINT_C | ALPHA_C | NICK_C | CHAN_C | NONEOS_C | USER_C,
802/* ~ */ PRINT_C | ALPHA_C | CHAN_C | NONEOS_C | USER_C,
803/* del */ CHAN_C | NONEOS_C,
804/* 0x80 */ CHAN_C | NONEOS_C,
805/* 0x81 */ CHAN_C | NONEOS_C,
806/* 0x82 */ CHAN_C | NONEOS_C,
807/* 0x83 */ CHAN_C | NONEOS_C,
808/* 0x84 */ CHAN_C | NONEOS_C,
809/* 0x85 */ CHAN_C | NONEOS_C,
810/* 0x86 */ CHAN_C | NONEOS_C,
811/* 0x87 */ CHAN_C | NONEOS_C,
812/* 0x88 */ CHAN_C | NONEOS_C,
813/* 0x89 */ CHAN_C | NONEOS_C,
814/* 0x8A */ CHAN_C | NONEOS_C,
815/* 0x8B */ CHAN_C | NONEOS_C,
816/* 0x8C */ CHAN_C | NONEOS_C,
817/* 0x8D */ CHAN_C | NONEOS_C,
818/* 0x8E */ CHAN_C | NONEOS_C,
819/* 0x8F */ CHAN_C | NONEOS_C,
820/* 0x90 */ CHAN_C | NONEOS_C,
821/* 0x91 */ CHAN_C | NONEOS_C,
822/* 0x92 */ CHAN_C | NONEOS_C,
823/* 0x93 */ CHAN_C | NONEOS_C,
824/* 0x94 */ CHAN_C | NONEOS_C,
825/* 0x95 */ CHAN_C | NONEOS_C,
826/* 0x96 */ CHAN_C | NONEOS_C,
827/* 0x97 */ CHAN_C | NONEOS_C,
828/* 0x98 */ CHAN_C | NONEOS_C,
829/* 0x99 */ CHAN_C | NONEOS_C,
830/* 0x9A */ CHAN_C | NONEOS_C,
831/* 0x9B */ CHAN_C | NONEOS_C,
832/* 0x9C */ CHAN_C | NONEOS_C,
833/* 0x9D */ CHAN_C | NONEOS_C,
834/* 0x9E */ CHAN_C | NONEOS_C,
835/* 0x9F */ CHAN_C | NONEOS_C,
836/* 0xA0 */ CHAN_C | FCHAN_C | NONEOS_C,
837/* 0xA1 */ CHAN_C | NONEOS_C,
838/* 0xA2 */ CHAN_C | NONEOS_C,
839/* 0xA3 */ CHAN_C | NONEOS_C,
840/* 0xA4 */ CHAN_C | NONEOS_C,
841/* 0xA5 */ CHAN_C | NONEOS_C,
842/* 0xA6 */ CHAN_C | NONEOS_C,
843/* 0xA7 */ CHAN_C | NONEOS_C,
844/* 0xA8 */ CHAN_C | NONEOS_C,
845/* 0xA9 */ CHAN_C | NONEOS_C,
846/* 0xAA */ CHAN_C | NONEOS_C,
847/* 0xAB */ CHAN_C | NONEOS_C,
848/* 0xAC */ CHAN_C | NONEOS_C,
849/* 0xAD */ CHAN_C | NONEOS_C,
850/* 0xAE */ CHAN_C | NONEOS_C,
851/* 0xAF */ CHAN_C | NONEOS_C,
852/* 0xB0 */ CHAN_C | NONEOS_C,
853/* 0xB1 */ CHAN_C | NONEOS_C,
854/* 0xB2 */ CHAN_C | NONEOS_C,
855/* 0xB3 */ CHAN_C | NONEOS_C,
856/* 0xB4 */ CHAN_C | NONEOS_C,
857/* 0xB5 */ CHAN_C | NONEOS_C,
858/* 0xB6 */ CHAN_C | NONEOS_C,
859/* 0xB7 */ CHAN_C | NONEOS_C,
860/* 0xB8 */ CHAN_C | NONEOS_C,
861/* 0xB9 */ CHAN_C | NONEOS_C,
862/* 0xBA */ CHAN_C | NONEOS_C,
863/* 0xBB */ CHAN_C | NONEOS_C,
864/* 0xBC */ CHAN_C | NONEOS_C,
865/* 0xBD */ CHAN_C | NONEOS_C,
866/* 0xBE */ CHAN_C | NONEOS_C,
867/* 0xBF */ CHAN_C | NONEOS_C,
868/* 0xC0 */ CHAN_C | NONEOS_C,
869/* 0xC1 */ CHAN_C | NONEOS_C,
870/* 0xC2 */ CHAN_C | NONEOS_C,
871/* 0xC3 */ CHAN_C | NONEOS_C,
872/* 0xC4 */ CHAN_C | NONEOS_C,
873/* 0xC5 */ CHAN_C | NONEOS_C,
874/* 0xC6 */ CHAN_C | NONEOS_C,
875/* 0xC7 */ CHAN_C | NONEOS_C,
876/* 0xC8 */ CHAN_C | NONEOS_C,
877/* 0xC9 */ CHAN_C | NONEOS_C,
878/* 0xCA */ CHAN_C | NONEOS_C,
879/* 0xCB */ CHAN_C | NONEOS_C,
880/* 0xCC */ CHAN_C | NONEOS_C,
881/* 0xCD */ CHAN_C | NONEOS_C,
882/* 0xCE */ CHAN_C | NONEOS_C,
883/* 0xCF */ CHAN_C | NONEOS_C,
884/* 0xD0 */ CHAN_C | NONEOS_C,
885/* 0xD1 */ CHAN_C | NONEOS_C,
886/* 0xD2 */ CHAN_C | NONEOS_C,
887/* 0xD3 */ CHAN_C | NONEOS_C,
888/* 0xD4 */ CHAN_C | NONEOS_C,
889/* 0xD5 */ CHAN_C | NONEOS_C,
890/* 0xD6 */ CHAN_C | NONEOS_C,
891/* 0xD7 */ CHAN_C | NONEOS_C,
892/* 0xD8 */ CHAN_C | NONEOS_C,
893/* 0xD9 */ CHAN_C | NONEOS_C,
894/* 0xDA */ CHAN_C | NONEOS_C,
895/* 0xDB */ CHAN_C | NONEOS_C,
896/* 0xDC */ CHAN_C | NONEOS_C,
897/* 0xDD */ CHAN_C | NONEOS_C,
898/* 0xDE */ CHAN_C | NONEOS_C,
899/* 0xDF */ CHAN_C | NONEOS_C,
900/* 0xE0 */ CHAN_C | NONEOS_C,
901/* 0xE1 */ CHAN_C | NONEOS_C,
902/* 0xE2 */ CHAN_C | NONEOS_C,
903/* 0xE3 */ CHAN_C | NONEOS_C,
904/* 0xE4 */ CHAN_C | NONEOS_C,
905/* 0xE5 */ CHAN_C | NONEOS_C,
906/* 0xE6 */ CHAN_C | NONEOS_C,
907/* 0xE7 */ CHAN_C | NONEOS_C,
908/* 0xE8 */ CHAN_C | NONEOS_C,
909/* 0xE9 */ CHAN_C | NONEOS_C,
910/* 0xEA */ CHAN_C | NONEOS_C,
911/* 0xEB */ CHAN_C | NONEOS_C,
912/* 0xEC */ CHAN_C | NONEOS_C,
913/* 0xED */ CHAN_C | NONEOS_C,
914/* 0xEE */ CHAN_C | NONEOS_C,
915/* 0xEF */ CHAN_C | NONEOS_C,
916/* 0xF0 */ CHAN_C | NONEOS_C,
917/* 0xF1 */ CHAN_C | NONEOS_C,
918/* 0xF2 */ CHAN_C | NONEOS_C,
919/* 0xF3 */ CHAN_C | NONEOS_C,
920/* 0xF4 */ CHAN_C | NONEOS_C,
921/* 0xF5 */ CHAN_C | NONEOS_C,
922/* 0xF6 */ CHAN_C | NONEOS_C,
923/* 0xF7 */ CHAN_C | NONEOS_C,
924/* 0xF8 */ CHAN_C | NONEOS_C,
925/* 0xF9 */ CHAN_C | NONEOS_C,
926/* 0xFA */ CHAN_C | NONEOS_C,
927/* 0xFB */ CHAN_C | NONEOS_C,
928/* 0xFC */ CHAN_C | NONEOS_C,
929/* 0xFD */ CHAN_C | NONEOS_C,
930/* 0xFE */ CHAN_C | NONEOS_C,
931/* 0xFF */ CHAN_C | NONEOS_C
932};