1    | /***************************************
2    |   $Revision: 1.5 $
3    | 
4    |   Example code: Determine which keys to look for.
5    |   
6    |   This is based on the C code that was reversed engineered from existing Perl
7    |   code.  (~ottrey/which_table/which_table.c)
8    | 
9    |   ******************/ /******************
10   |   Copyright (c) 1999                              RIPE NCC
11   |  
12   |   All Rights Reserved
13   |   
14   |   Permission to use, copy, modify, and distribute this software and its
15   |   documentation for any purpose and without fee is hereby granted,
16   |   provided that the above copyright notice appear in all copies and that
17   |   both that copyright notice and this permission notice appear in
18   |   supporting documentation, and that the name of the author not be
19   |   used in advertising or publicity pertaining to distribution of the
20   |   software without specific, written prior permission.
21   |   
22   |   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
23   |   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
24   |   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
25   |   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
26   |   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
27   |   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28   |   ***************************************/
29   | #include <stdio.h>
30   | #include <strings.h>
31   | #include <libgen.h>
32   | #include "isnic.h"
33   | #include "bitmask.h"
34   | #include "which_keytypes.h"
35   | 
36   | 
37   | #define DOMAINNAME "^[ ]*[a-zA-Z0-9--]*(\\.[a-zA-Z0-9--]+)*[ ]*$"
38   | 
39   | #define LEN_MIN 0
40   | #define LEN_MAX 32
41   | 
42   | #define NETLEN 16
43   | #define NETQUADS 4
44   | #define NETQUAD_MIN 0
45   | #define NETQUAD_MAX 255
46   | 
47   | #define ASNUM_MIN 1
48   | #define ASNUM_MAX 65535
49   | #define ASNUM_NUMOFFSET 2   /* XXX - (This is really kludgy!) Offset to the number bit of ASNUM */
50   | 
51   | #define VALIDIP6 "^[0-9A-F]{1,4}(:[0-9A-F]{1,4}){7}$"
52   | /*
53   |   XXX Why doesn't this work?
54   | #define NET "^([0-9]{1,3}.){4}$"
55   | */
56   | #define NET "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"
57   | 
58   | #define ASNUM "^AS[1-9]+[0-9]*$"
59   | 
60   | #define NETNAME "^[A-Z][A-Z0-9-]*$"
61   | 
62   | #define MAINTAINER "^[A-Z][A-Z0-9-]*$"
63   | 
64   | #define LIMERICK "^LIM-[A-Z0-9-]+$"
65   | 
66   | #define KEYCERT "^PGPKEY-[0-9A-F]{8}$"
67   | 
68   | #define ASMACRO "^AS-[A-Z]+$"
69   | 
70   | #define ROUTESETNAME "^RS-[A-Z0-9-]*$"
71   | 
72   | #define ASSETNAME "^AS-[A-Z0-9-]*$"
73   | 
74   | #define AUTONICPREFIXREGULAR "^AUTO-"
75   | 
76   | /*
77   |   XXX This seems to be the same as the Perl code.  But I don't see where a " " is allowed for.
78   |   I.e. Perl -> ^[a-zA-Z][\w\-\.\'\|\`]*$
79   |   Does \w include [ ;:,?/}{()+*#] ?
80   | #define NAME_B "^[a-zA-Z][a-zA-Z_0-9.'|`-]*$"
81   | */
82   | #define NAME_B "^[a-zA-Z][a-zA-Z_0-9.'|`;:,?/}{()+*#&-]*$"
83   | 
84   | #define PHONE_A "^[ ]*[+][0-9 ]*[(]{0,1}[0-9 -]+[)]{0,1}[0-9 -]*(ext\\.){0,1}[0-9 ]*$"
85   | 
86   | #define VALIDIP4PREFIX
87   | 
88   | #define EMAIL "^[a-zA-Z0-9--]*@[a-zA-Z0-9--]*(\\.[a-zA-Z0-9--]+)*$"
89   | 
90   | 
91   | /*+ Keytype strings +*/
92   | char * const Keytypes[] = {
93   |         "name",
94   |         "nichdl",
95   |         "email",
96   |         "maint",
97   |         "pgpkey",
98   |         "iprange",
99   |         "ip6range",
100  |         "netname",
101  |         "asnum",
102  |         "assetname",
103  |         "routesetname",
104  |         "domname",
105  |         "hostname",
106  |         "limerickname",
107  |         NULL
108  | }; /* Keytypes[] */
109  | 
110  | /*+ Peerword strings +*/
111  | const char * Peerword[] = {
112  |                "EGP",
113  |                "BGP",
114  |                "BGP4",
115  |                "IDRP",
116  |                "IGP",
117  |                "HELLO",
118  |                "IGRP",
119  |                "EIGRP",
120  |                "OSPF",
121  |                "ISIS",
122  |                "RIP",
123  |                "RIP2",
124  |                "OTHER",
125  |                ""
126  | }; /* Peerword[] */
127  | 
128  | static int matching(char *string, char left_c, char right_c) { 
129  |   int result;
130  | 
131  |   int i;
132  |   int length;
133  |   int count=0;
134  | 
135  |   length = strlen(string);
136  | 
137  |   for(i=0; i < length; i++) {
138  | /*
139  |     switch ((int)string[i]) {
140  |       case left_c:
141  |       break;
142  | 
143  |       case right_c:
144  |         count--;
145  |       break;
146  | 
147  |       default:
148  |     }
149  | */
150  |     if (string[i] == left_c) {
151  |       count++;
152  |     }
153  |     if (string[i] == right_c) {
154  |       count--;
155  |     }
156  |   }
157  | 
158  |   if (count == 0) {
159  |     /* Matching characters */
160  |     result=1;
161  |   }
162  |   else {
163  |     /* Non-matching characters */
164  |     result=0;
165  |   }
166  | 
167  |   return result;
168  | 
169  | } /* matching() */
170  | 
171  | 
172  | static int perform_regex_test(const char *pattern, char *string) {
173  |   char *return_value;
174  |   int match;
175  | 
176  |   char *re;
177  | 
178  |   re = regcmp(pattern, (char*)0);
179  |   if (regex(re, string) == NULL) {
180  |     match = 0;
181  |   }
182  |   else {
183  |     match = 1;
184  |   }
185  | 
186  |   free(re);
187  | 
188  |   return match;
189  | 
190  | }
191  | 
192  | static int isipv6prefix_a(char *string) {
193  | /*
194  |   printf("isipv6prefix\n");
195  | */
196  |   int result='-';
197  | 
198  |   result = perform_regex_test(VALIDIP6, string);
199  | 
200  |   return result;
201  | }
202  | 
203  | static int isipv6prefix(char *string) {
204  | /*
205  |   printf("isipv6prefix\n");
206  | */
207  |   int result='-';
208  | 
209  |   return result;
210  | }
211  | 
212  | static int islen(char *string) {
213  |   /*
214  |   printf("islen\n");
215  | */
216  |   int result='-';
217  |   int length;
218  | 
219  |   length = strlen(string);
220  | 
221  |   if ((length <= LEN_MAX) && (length >= LEN_MIN)) {
222  |     /* A valid length */
223  |     result=1;
224  |   }
225  |   else if (length < 0) {
226  |     /* An invalid length */
227  |     result=-1;
228  |   }
229  |   else {
230  |     /* An invalid length */
231  |     result=0;
232  |   }
233  | 
234  |   return result;
235  | }
236  | 
237  | static int isnet(char *string) {
238  |   /*
239  |   printf("isnet\n");
240  | */
241  |   int result='-';
242  |   char tmp_string[NETLEN];
243  |   int quad_value;
244  |   char *quad_value_str;
245  | 
246  |   /* First check if the string is in quad form */
247  |   result = perform_regex_test(NET, string);
248  | 
249  |   /* Then check if the quad values are between NETQUAD_MIN and NETQUAD_MAX */
250  |   if (result == 1) {
251  |     strncpy(tmp_string, string, NETLEN);
252  |     quad_value_str = strtok(tmp_string, ".");
253  |     while (quad_value_str != NULL) {
254  |       quad_value = atoi(quad_value_str);
255  |       if ((quad_value < NETQUAD_MIN) || (quad_value > NETQUAD_MAX)) {
256  |         /* an invalid value */
257  |         result=0;
258  |         break;
259  |       }
260  |       quad_value_str = strtok(NULL, ".");
261  |     }
262  |   }
263  | 
264  |   return result;
265  | }
266  | 
267  | static int isasnum(char *string) {
268  |   /*
269  |   printf("isasnum\n");
270  | */
271  |   int result='-';
272  |   int as_value;
273  | 
274  |   /* First check if the string matches an ASNUM */
275  |   result = perform_regex_test(ASNUM, string);
276  | 
277  |   /* Then check if the value is between ASNUM_MIN and ASNUM_MAX */
278  |   if (result == 1) {
279  |     as_value = atoi(string+ASNUM_NUMOFFSET);
280  |     if ((as_value < ASNUM_MIN) || (as_value > ASNUM_MAX)) {
281  |       /* an invalid value */
282  |       result=0;
283  |     }
284  |   }
285  |   
286  |   return result;
287  | }
288  | 
289  | static int isnetname(char *string) {
290  |   /*
291  |   printf("isnetname\n");
292  | */
293  |   int result='-';
294  | 
295  |   result = perform_regex_test(NETNAME, string);
296  | 
297  |   return result;
298  | }
299  | 
300  | static int ismaintainer(char *string) {
301  |   /*
302  |   printf("ismaintainer\n");
303  | */
304  |   int result='-';
305  | 
306  |   result = perform_regex_test(MAINTAINER, string);
307  | 
308  |   return result;
309  | }
310  | 
311  | static int islimerick(char *string) {
312  |   /*
313  |   printf("islimerick\n");
314  | */
315  |   int result='-';
316  | 
317  |   result = perform_regex_test(LIMERICK, string);
318  | 
319  |   return result;
320  | }
321  | 
322  | /*******************************************************
323  |     # the problem is as follows:
324  |     #
325  |     # we can never find out which NIC handles are possible on the
326  |     # globe since we don't know that they exist
327  |     #
328  |     # we want to solve this with once with DNS :
329  |     #
330  |     # RIPE.registries.int     CNAME whois.ripe.net
331  |     # InterNIC.registries.int CNAME whois.internic.net
332  |     # and so on...
333  | 
334  |     #
335  |     # 1) it first does a basic syntax check
336  |     #
337  |     #    notes:
338  |     #
339  |     #    - catches InterNIC handles
340  |     #    - catches the JP|JP-JP APNIC exceptions
341  |     #    - limits the number of initials to three with a good reason:
342  |     #      we have a much better chance to find syntax errors like:
343  |     #      RIPE-DK13 and other problems like this
344  |     #
345  |     # 2) checks for valid suffixes
346  |     #    - all 'source:' attribute values from sites that we mirror
347  |     #      are allowed
348  |     #    - country codes are allowed for APNIC compatibility
349  |     #    - APNIC AP|CC-AU exceptions are handled correctly
350  |     #    - -ORG organization InterNIC handles
351  |     #    - -ARIN ARIN handles
352  |     #    - -ORG-ARIN ARIN handles
353  | ********************************************************/
354  | static int isnichandle_joao(char *nichdl) {
355  | 
356  |   char *regexp, *match;
357  |   char ret[1024];
358  |   char *suffix;
359  | 
360  |   int i;
361  | 
362  | /* set ret to the empty string *.
363  |   ret[0]='\0';
364  | /** Return if there are any lower case characters */
365  | 
366  |   regexp = regcmp("[a-z]",(char *)0);
367  |   match = regex(regexp,nichdl);
368  |   free(regexp);
369  |   if (match) return 0;
370  | 
371  | /* 
372  |   # Japanese NIC handles
373  |   #
374  |   # leading zeros in the number part *are* allowed
375  |   #
376  |   # e.g. AB021JP AB199JP-JP
377  |   #
378  | */
379  |   regexp = regcmp("[A-Z]{2}[0-9]{3}JP(-JP){0,1}",(char *)0);
380  |   match =  regex(regexp,nichdl);
381  |   free(regexp);
382  |   if (match) return 1;
383  | 
384  | /*
385  |   # Standard NIC handles
386  |   #
387  |   # leading zeros in the number part are *not* allowed
388  |   #
389  |   # InterNIC - TBQ, IP4
390  |   # RIPE format - AB1-RIPE
391  |   # APNIC use two letter country code suffix
392  |   # Austraila have used -1-AU, -2-AU, -CC-AU suffix.
393  |   # Internic used -ORG suffix
394  |   # ARIN use -ARIN suffix
395  |   # ARIN also use -ORG-ARIN suffix
396  |   #
397  | */
398  |   regexp = regcmp("^[A-Z]{2,4}([1-9][0-9]{0,5}){0,1}((-[^ ]+){0,1})$0$",(char *)0);
399  |   match =  regex(regexp,nichdl,ret);
400  | 
401  |   free(regexp);
402  | 
403  |   if (match == NULL) {
404  |     return 0;
405  |   } else {
406  |     if (ret[0] == '\0') {
407  |       return 1;
408  |     } else {
409  | /*   strip leading '-' */
410  |       suffix = ret+1;
411  | /* suffix of local sources */
412  |       for (i=0;i<=NUM_NICPOSTFIX;i++) {
413  |         if ( !strcmp(suffix,nicpostfix[i]) ) {
414  |           return 1;
415  |         }
416  |       }
417  | /* country codes */
418  |       for (i=0;i<NUM_COUNTRIES;i++) {
419  |         if ( !strcmp(suffix,countries[i]) ) {
420  |           return 1;
421  |         }
422  |       }
423  | /* special suffix */
424  |       for (i=0;i<NUM_SPECIAL;i++) {
425  |         if ( !strcmp(suffix,special[i]) ) {
426  |           return 1;
427  |         }
428  |       }
429  |     }
430  |   }
431  |   return 0;
432  | } /* isnichandle_joao() */
433  | 
434  | 
435  | static int isnichandle(char *string) {
436  |   return isnichandle_joao(string);
437  | }
438  | 
439  | static int isaskeyword(char *string) {
440  |   /*
441  |   printf("isaskeyword\n");
442  | */
443  |   int result='-';
444  | 
445  |   return result;
446  | }
447  | 
448  | static int isasmacro(char *string) {
449  |   /*
450  |   printf("isasmacro\n");
451  | */
452  |   int result='-';
453  | 
454  |   result = perform_regex_test(ASMACRO, string);
455  | 
456  |   return result;
457  | }
458  | 
459  | static int isclnskeyword(char *string) {
460  |   /*
461  |   printf("isclnskeyword\n");
462  | */
463  |   int result='-';
464  | 
465  |   return result;
466  | }
467  | 
468  | static int ispeerkeyword(char *string) {
469  |   /*
470  |   printf("ispeerkeyword\n");
471  | */
472  |   int result='-';
473  |   int i;
474  | 
475  |   result=0;
476  |   for (i=0; Peerword[i] != ""; i++) {
477  |     if ( strcmp(Peerword[i], string) == 0 ) {
478  |       result=1;
479  |       break;
480  |     }
481  |   }
482  | 
483  |   return result;
484  | }
485  | 
486  | static int isnetlist(char *string) {
487  |   /*
488  |   printf("isnetlist\n");
489  | */
490  |   int result='-';
491  | 
492  |   return result;
493  | }
494  | 
495  | static int iscommunity(char *string) {
496  |   /*
497  |   printf("iscommunity\n");
498  | */
499  |   int result='-';
500  | 
501  |   return result;
502  | }
503  | 
504  | static int isaspref(char *string) {
505  |   /*
506  |   printf("isaspref\n");
507  | */
508  |   int result='-';
509  | 
510  |   return result;
511  | }
512  | 
513  | static int isnetnum(char *string) {
514  |   /*
515  |   printf("isnetnum\n");
516  | */
517  |   int result='-';
518  | 
519  |   /* XXX - I don't see the difference between isnet and isnetnum */
520  |   result=isnet(string);
521  | 
522  |   return result;
523  | }
524  | 
525  | static int isipaddr(char *string) {
526  |   /*
527  |   printf("isipaddr\n");
528  | */
529  |   int result='-';
530  | 
531  |   return result;
532  | }
533  | 
534  | static int ismask(char *string) {
535  |   /*
536  |   printf("ismask\n");
537  | */
538  |   int result='-';
539  | 
540  |   return result;
541  | }
542  | 
543  | static int isclnsprefix(char *string) {
544  |   /*
545  |   printf("isclnsprefix\n");
546  | */
547  |   int result='-';
548  | 
549  |   return result;
550  | }
551  | 
552  | static int issubdomname(char *string) {
553  |   /*
554  |   printf("issubdomname\n");
555  | */
556  |   int result='-';
557  | 
558  |   result = perform_regex_test(DOMAINNAME, string);
559  | 
560  |   return result;
561  | }
562  | 
563  | static int isdomname(char *string) {
564  |   /*
565  |   printf("isdomname\n");
566  | */
567  |   int result='-';
568  | 
569  |   result = perform_regex_test(DOMAINNAME, string);
570  | 
571  |   return result;
572  | }
573  | 
574  | /*
575  |  I split the isname up into isname_a & isname_b.  And created isname_ab to join them together.
576  |   - So I can test it properly.  -ottrey
577  |  */
578  | static int isname_a(char *string) {
579  |   /*
580  |   printf("isname_a\n");
581  | */
582  |   int result='-';
583  | 
584  |   result = perform_regex_test(AUTONICPREFIXREGULAR, string);
585  | 
586  |   return result;
587  | }
588  | 
589  | static int isname_b(char *string) {
590  |   /*
591  |   printf("isname_b\n");
592  | */
593  |   int result='-';
594  | 
595  |   result = perform_regex_test(NAME_B, string);
596  | 
597  |   return result;
598  | }
599  | 
600  | static int isname_ab(char *string) {
601  |   /*
602  |   printf("isname_ab\n");
603  | */
604  |   int result='-';
605  | 
606  |   /* Note: the different logic here because I use 0 to be a match and 1 to not be a match.
607  |      The Perl code uses the opposite. - ottrey */
608  |   result = !(isname_a(string) && !isname_b(string));
609  | 
610  |   return result;
611  | }
612  | 
613  | static int isname(char *string) {
614  |   /*
615  |   printf("isname\n");
616  | */
617  |   int result='-';
618  | 
619  |   return result;
620  | }
621  | 
622  | static int isphone_a(char *string) {
623  |   /*
624  |   printf("isphone_a\n");
625  | */
626  |   int result='-';
627  | 
628  |   result = perform_regex_test(PHONE_A, string);
629  |   
630  |   return result;
631  | }
632  | static int isphone_b(char *string) {
633  |   /*
634  |   printf("isphone_b\n");
635  | */
636  |   int result='-';
637  | 
638  |   result = isparen(string);
639  | 
640  |   return result;
641  | }
642  | static int isphone_ab(char *string) {
643  |   /*
644  |   printf("isphone_ab\n");
645  | */
646  |   int result='-';
647  | 
648  |   /* Note: the different logic here because I use 0 to be a match and 1 to not be a match.
649  |      The Perl code uses the opposite. - ottrey */
650  |   result = !(!isphone_a(string) && !isphone_b(string));
651  | 
652  |   return result;
653  | }
654  | static int isphone(char *string) {
655  |   /*
656  |   printf("isphone\n");
657  | */
658  |   int result='-';
659  | 
660  |   return result;
661  | }
662  | 
663  | static int isemail(char *string) {
664  |   /*
665  |   printf("isemail\n");
666  | */
667  |   int result='-';
668  | 
669  |   result = perform_regex_test(EMAIL, string);
670  |   
671  |   return result;
672  | }
673  | 
674  | static int isbrace(char *string) {
675  |   /*
676  |   printf("isbrace\n");
677  | */
678  |   int result='-';
679  | 
680  |   result=matching(string, '{', '}');
681  | 
682  |   return result;
683  | }
684  | 
685  | static int isparen(char *string) {
686  |   /*
687  |   printf("isparen\n");
688  | */
689  |   int result='-';
690  | 
691  |   result=matching(string, '(', ')');
692  | 
693  |   return result;
694  | }
695  | 
696  | 
697  | 
698  | 
699  | 
700  | 
701  | 
702  | 
703  | 
704  | 
705  | 
706  | 
707  | 
708  | /* ****** The new bunch  ******* */
709  | static int wk_is_name(char *key) {
710  | 
711  |   /* Everything matches to name */
712  |   return 1;
713  | 
714  | } /* wk_is_name() */
715  | 
716  | static int wk_is_nichdl(char *key) {
717  | 
718  |   return isnichandle(key);
719  | 
720  | } /* wk_is_nichdl() */
721  | 
722  | static int wk_is_email(char *key) {
723  | 
724  |   return isemail(key);
725  | 
726  | } /* wk_is_email() */
727  | 
728  | static int wk_is_maint(char *key) {
729  | 
730  |   return ismaintainer(key);
731  | 
732  | } /* wk_is_maint() */
733  | 
734  | static int wk_is_keycert(char *key) {
735  |   int result=1;
736  | 
737  |   result = perform_regex_test(KEYCERT, key);
738  | 
739  |   return result;
740  | 
741  | } /* wk_is_pgpkey() */
742  | 
743  | static int wk_is_iprange(char *key) {
744  |   int result=1;
745  | 
746  |   /* XXX This is not very strict - but will cut out a lot of invalids */
747  |   /* XXX And has been given a bad name and does a few things. */
748  |   /* XXX This needs work. */
749  | #define IPRANGE "^[0-9./ -]*$"
750  |   result = perform_regex_test(IPRANGE, key);
751  | 
752  |   return result;
753  | 
754  | } /* wk_is_iprange() */
755  | 
756  | static int wk_is_ip6range(char *key) {
757  | 
758  |   return isipv6prefix_a(key);
759  | 
760  | } /* wk_is_ip6range() */
761  | 
762  | static int wk_is_netname(char *key) {
763  |   
764  |   return isnetname(key);
765  | 
766  | } /* wk_is_netname() */
767  | 
768  | static int wk_is_asnum(char *key) {
769  | 
770  |   return isasnum(key);
771  | 
772  | } /* wk_is_asnum() */
773  | 
774  | static int wk_is_assetname(char *key) {
775  |   int result=1;
776  | 
777  |   result = perform_regex_test(ASSETNAME, key);
778  | 
779  |   return result;
780  | 
781  | } /* wk_is_assetname() */
782  | 
783  | static int wk_is_routesetname(char *key) {
784  |   int result=1;
785  | 
786  |   result = perform_regex_test(ROUTESETNAME, key);
787  | 
788  |   return result;
789  | 
790  | } /* wk_is_routesetname() */
791  | 
792  | static int wk_is_domname(char *key) {
793  | 
794  |   return isdomname(key);
795  | 
796  | } /* wk_is_domname() */
797  | 
798  | static int wk_is_hostname(char *key) {
799  | 
800  |   /* XXX Why is there a hostname & a domainname? */
801  |   /* Answer - hostname can be a domainname or an IP */
802  |   return (isdomname(key) || wk_is_iprange(key));
803  | 
804  | } /* wk_is_hostname() */
805  | 
806  | static int wk_is_limerickname(char *key) {
807  | 
808  |   return islimerick(key);
809  | 
810  | } /* wk_is_limerickname() */
811  | 
812  | 
813  | /* WK_to_string() */
814  | /*++++++++++++++++++++++++++++++++++++++
815  |   Convert the which keytypes bitmap into a string.
816  | 
817  |   mask_t wk The which keytypes mask to be converted.
818  | 
819  |   More:
820  |   +html+ <PRE>
821  |   Authors:
822  |         ottrey
823  |   +html+ </PRE><DL COMPACT>
824  |   +html+ <DT>Online References:
825  |   +html+ <DD><UL>
826  |   +html+ </UL></DL>
827  | 
828  |   ++++++++++++++++++++++++++++++++++++++*/
829  | char *WK_to_string(mask_t wk) {
830  | 
831  |   return MA_to_string(wk, Keytypes, 1, 0);
832  | 
833  | } /* WK_to_string() */
834  | 
835  | 
836  | /* WK_new() */
837  | /*++++++++++++++++++++++++++++++++++++++
838  |   Create a new which keytypes bitmap.
839  | 
840  |   char *key The key to be examined.
841  | 
842  |   More:
843  |   +html+ <PRE>
844  |   Authors:
845  |         ottrey
846  |   +html+ </PRE><DL COMPACT>
847  |   +html+ <DT>Online References:
848  |   +html+ <DD><UL>
849  |   +html+ </UL></DL>
850  | 
851  |   ++++++++++++++++++++++++++++++++++++++*/
852  | mask_t WK_new(char *key) {
853  |   mask_t wk; 
854  | 
855  |   wk = MA_new(MA_END);
856  | 
857  |   MA_set(&wk, WK_NAME,         wk_is_name(key));
858  |   MA_set(&wk, WK_NICHDL,       wk_is_nichdl(key));
859  |   MA_set(&wk, WK_EMAIL,        wk_is_email(key));
860  |   MA_set(&wk, WK_MAINT,        wk_is_maint(key));
861  |   MA_set(&wk, WK_KEYCERT,      wk_is_keycert(key));
862  |   MA_set(&wk, WK_IPRANGE,      wk_is_iprange(key));
863  |   MA_set(&wk, WK_IP6RANGE,     wk_is_ip6range(key));
864  |   MA_set(&wk, WK_NETNAME,      wk_is_netname(key));
865  |   MA_set(&wk, WK_ASNUM,        wk_is_asnum(key));
866  |   MA_set(&wk, WK_ASSETNAME,    wk_is_assetname(key));
867  |   MA_set(&wk, WK_ROUTESETNAME, wk_is_routesetname(key));
868  |   MA_set(&wk, WK_DOMNAME,      wk_is_domname(key));
869  |   MA_set(&wk, WK_HOSTNAME,     wk_is_hostname(key));
870  |   MA_set(&wk, WK_LIMERICKNAME, wk_is_limerickname(key));
871  | 
872  |   return wk;
873  | 
874  | } /* WK_new() */