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