1/* 2 * otpcode.c -- 3 * 4 * Implements and registers conversion from and to OTP's english words. 5 * 6 * 7 * Copyright (c) 1999 Marshall Rose (mrose@dbc.mtview.ca.us) 8 * All rights reserved. 9 * 10 * Permission is hereby granted, without written agreement and without 11 * license or royalty fees, to use, copy, modify, and distribute this 12 * software and its documentation for any purpose, provided that the 13 * above copyright notice and the following two paragraphs appear in 14 * all copies of this software. 15 * 16 * IN NO EVENT SHALL I LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, 17 * INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS 18 * SOFTWARE AND ITS DOCUMENTATION, EVEN IF I HAVE BEEN ADVISED OF THE 19 * POSSIBILITY OF SUCH DAMAGE. 20 * 21 * I SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND 24 * I HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 25 * ENHANCEMENTS, OR MODIFICATIONS. 26 * 27 * CVS: $Id: otpcode.c,v 1.7 2009/05/07 04:57:27 andreas_kupries Exp $ 28 */ 29 30#include <ctype.h> 31#include "transformInt.h" 32 33/* 34 * Converter description 35 * --------------------- 36 * 37 * Reference: 38 * RFC 2289 39 * 40 * Encoding: 41 * Each sequence of 64-bits is converted to OTP's 6 english words. 42 * For ease of readability, a newline is written after each 6 words. 43 * 44 * Decoding: 45 * Each 6 word sequence is converted to 64-bits. 46 */ 47 48 49/* 50 * Declarations of internal procedures. 51 */ 52 53static Trf_ControlBlock CreateEncoder _ANSI_ARGS_ ((ClientData writeClientData, 54 Trf_WriteProc *fun, 55 Trf_Options optInfo, 56 Tcl_Interp* interp, 57 ClientData clientData)); 58static void DeleteEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, 59 ClientData clientData)); 60static int Encode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, 61 unsigned int character, 62 Tcl_Interp* interp, 63 ClientData clientData)); 64static int EncodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, 65 unsigned char* buffer, int bufLen, 66 Tcl_Interp* interp, 67 ClientData clientData)); 68static int FlushEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, 69 Tcl_Interp* interp, 70 ClientData clientData)); 71static void ClearEncoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, 72 ClientData clientData)); 73 74static Trf_ControlBlock CreateDecoder _ANSI_ARGS_ ((ClientData writeClientData, 75 Trf_WriteProc *fun, 76 Trf_Options optInfo, 77 Tcl_Interp* interp, 78 ClientData clientData)); 79static void DeleteDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, 80 ClientData clientData)); 81static int Decode _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, 82 unsigned int character, 83 Tcl_Interp* interp, 84 ClientData clientData)); 85static int DecodeBuffer _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, 86 unsigned char* buffer, int bufLen, 87 Tcl_Interp* interp, 88 ClientData clientData)); 89static int FlushDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, 90 Tcl_Interp* interp, 91 ClientData clientData)); 92static void ClearDecoder _ANSI_ARGS_ ((Trf_ControlBlock ctrlBlock, 93 ClientData clientData)); 94 95 96/* 97 * Converter definition. 98 */ 99 100static Trf_TypeDefinition convDefinition = 101{ 102 "otp_words", 103 NULL, /* clientData not used by conversions. */ 104 NULL, /* set later by TrfInit_OTP_WORDS, THREAD: serialize initialization */ 105 { 106 CreateEncoder, 107 DeleteEncoder, 108 Encode, 109 EncodeBuffer, 110 FlushEncoder, 111 ClearEncoder, 112 NULL /* no MaxRead */ 113 }, { 114 CreateDecoder, 115 DeleteDecoder, 116 Decode, 117 DecodeBuffer, 118 FlushDecoder, 119 ClearDecoder, 120 NULL /* no MaxRead */ 121 }, 122 TRF_UNSEEKABLE 123}; 124 125/* 126 * Definition of the control blocks for en- and decoder. 127 */ 128 129typedef struct _EncoderControl_ { 130 Trf_WriteProc* write; 131 ClientData writeClientData; 132 133 /* add conversion specific items here (otp_words encode) */ 134 135 int charCount; 136 unsigned char buf[8]; 137 138} EncoderControl; 139 140 141typedef struct _DecoderControl_ { 142 Trf_WriteProc* write; 143 ClientData writeClientData; 144 145 /* add conversion specific items here (otp_words decode) */ 146 147 int charCount; 148 int wordCount; 149 char words[6][5]; 150 151} DecoderControl; 152 153 154/* taken from RFC 2289... */ 155 156static unsigned long extract _ANSI_ARGS_ ((char *s, 157 int start, 158 int length)); 159static void insert _ANSI_ARGS_ ((char *s, 160 int x, 161 int start, 162 int length)); 163static int wsrch _ANSI_ARGS_ ((char *w, 164 int low, 165 int high)); 166 167/* Dictionary for integer-word translations */ 168static char Wp[2048][4] = { /* THREADING: constant, read-only => safe */ 169"A", 170"ABE", 171"ACE", 172"ACT", 173"AD", 174"ADA", 175"ADD", 176"AGO", 177"AID", 178"AIM", 179"AIR", 180"ALL", 181"ALP", 182"AM", 183"AMY", 184"AN", 185"ANA", 186"AND", 187"ANN", 188"ANT", 189"ANY", 190"APE", 191"APS", 192"APT", 193"ARC", 194"ARE", 195"ARK", 196"ARM", 197"ART", 198"AS", 199"ASH", 200"ASK", 201"AT", 202"ATE", 203"AUG", 204"AUK", 205"AVE", 206"AWE", 207"AWK", 208"AWL", 209"AWN", 210"AX", 211"AYE", 212"BAD", 213"BAG", 214"BAH", 215"BAM", 216"BAN", 217"BAR", 218"BAT", 219"BAY", 220"BE", 221"BED", 222"BEE", 223"BEG", 224"BEN", 225"BET", 226"BEY", 227"BIB", 228"BID", 229"BIG", 230"BIN", 231"BIT", 232"BOB", 233"BOG", 234"BON", 235"BOO", 236"BOP", 237"BOW", 238"BOY", 239"BUB", 240"BUD", 241"BUG", 242"BUM", 243"BUN", 244"BUS", 245"BUT", 246"BUY", 247"BY", 248"BYE", 249"CAB", 250"CAL", 251"CAM", 252"CAN", 253"CAP", 254"CAR", 255"CAT", 256"CAW", 257"COD", 258"COG", 259"COL", 260"CON", 261"COO", 262"COP", 263"COT", 264"COW", 265"COY", 266"CRY", 267"CUB", 268"CUE", 269"CUP", 270"CUR", 271"CUT", 272"DAB", 273"DAD", 274"DAM", 275"DAN", 276"DAR", 277"DAY", 278"DEE", 279"DEL", 280"DEN", 281"DES", 282"DEW", 283"DID", 284"DIE", 285"DIG", 286"DIN", 287"DIP", 288"DO", 289"DOE", 290"DOG", 291"DON", 292"DOT", 293"DOW", 294"DRY", 295"DUB", 296"DUD", 297"DUE", 298"DUG", 299"DUN", 300"EAR", 301"EAT", 302"ED", 303"EEL", 304"EGG", 305"EGO", 306"ELI", 307"ELK", 308"ELM", 309"ELY", 310"EM", 311"END", 312"EST", 313"ETC", 314"EVA", 315"EVE", 316"EWE", 317"EYE", 318"FAD", 319"FAN", 320"FAR", 321"FAT", 322"FAY", 323"FED", 324"FEE", 325"FEW", 326"FIB", 327"FIG", 328"FIN", 329"FIR", 330"FIT", 331"FLO", 332"FLY", 333"FOE", 334"FOG", 335"FOR", 336"FRY", 337"FUM", 338"FUN", 339"FUR", 340"GAB", 341"GAD", 342"GAG", 343"GAL", 344"GAM", 345"GAP", 346"GAS", 347"GAY", 348"GEE", 349"GEL", 350"GEM", 351"GET", 352"GIG", 353"GIL", 354"GIN", 355"GO", 356"GOT", 357"GUM", 358"GUN", 359"GUS", 360"GUT", 361"GUY", 362"GYM", 363"GYP", 364"HA", 365"HAD", 366"HAL", 367"HAM", 368"HAN", 369"HAP", 370"HAS", 371"HAT", 372"HAW", 373"HAY", 374"HE", 375"HEM", 376"HEN", 377"HER", 378"HEW", 379"HEY", 380"HI", 381"HID", 382"HIM", 383"HIP", 384"HIS", 385"HIT", 386"HO", 387"HOB", 388"HOC", 389"HOE", 390"HOG", 391"HOP", 392"HOT", 393"HOW", 394"HUB", 395"HUE", 396"HUG", 397"HUH", 398"HUM", 399"HUT", 400"I", 401"ICY", 402"IDA", 403"IF", 404"IKE", 405"ILL", 406"INK", 407"INN", 408"IO", 409"ION", 410"IQ", 411"IRA", 412"IRE", 413"IRK", 414"IS", 415"IT", 416"ITS", 417"IVY", 418"JAB", 419"JAG", 420"JAM", 421"JAN", 422"JAR", 423"JAW", 424"JAY", 425"JET", 426"JIG", 427"JIM", 428"JO", 429"JOB", 430"JOE", 431"JOG", 432"JOT", 433"JOY", 434"JUG", 435"JUT", 436"KAY", 437"KEG", 438"KEN", 439"KEY", 440"KID", 441"KIM", 442"KIN", 443"KIT", 444"LA", 445"LAB", 446"LAC", 447"LAD", 448"LAG", 449"LAM", 450"LAP", 451"LAW", 452"LAY", 453"LEA", 454"LED", 455"LEE", 456"LEG", 457"LEN", 458"LEO", 459"LET", 460"LEW", 461"LID", 462"LIE", 463"LIN", 464"LIP", 465"LIT", 466"LO", 467"LOB", 468"LOG", 469"LOP", 470"LOS", 471"LOT", 472"LOU", 473"LOW", 474"LOY", 475"LUG", 476"LYE", 477"MA", 478"MAC", 479"MAD", 480"MAE", 481"MAN", 482"MAO", 483"MAP", 484"MAT", 485"MAW", 486"MAY", 487"ME", 488"MEG", 489"MEL", 490"MEN", 491"MET", 492"MEW", 493"MID", 494"MIN", 495"MIT", 496"MOB", 497"MOD", 498"MOE", 499"MOO", 500"MOP", 501"MOS", 502"MOT", 503"MOW", 504"MUD", 505"MUG", 506"MUM", 507"MY", 508"NAB", 509"NAG", 510"NAN", 511"NAP", 512"NAT", 513"NAY", 514"NE", 515"NED", 516"NEE", 517"NET", 518"NEW", 519"NIB", 520"NIL", 521"NIP", 522"NIT", 523"NO", 524"NOB", 525"NOD", 526"NON", 527"NOR", 528"NOT", 529"NOV", 530"NOW", 531"NU", 532"NUN", 533"NUT", 534"O", 535"OAF", 536"OAK", 537"OAR", 538"OAT", 539"ODD", 540"ODE", 541"OF", 542"OFF", 543"OFT", 544"OH", 545"OIL", 546"OK", 547"OLD", 548"ON", 549"ONE", 550"OR", 551"ORB", 552"ORE", 553"ORR", 554"OS", 555"OTT", 556"OUR", 557"OUT", 558"OVA", 559"OW", 560"OWE", 561"OWL", 562"OWN", 563"OX", 564"PA", 565"PAD", 566"PAL", 567"PAM", 568"PAN", 569"PAP", 570"PAR", 571"PAT", 572"PAW", 573"PAY", 574"PEA", 575"PEG", 576"PEN", 577"PEP", 578"PER", 579"PET", 580"PEW", 581"PHI", 582"PI", 583"PIE", 584"PIN", 585"PIT", 586"PLY", 587"PO", 588"POD", 589"POE", 590"POP", 591"POT", 592"POW", 593"PRO", 594"PRY", 595"PUB", 596"PUG", 597"PUN", 598"PUP", 599"PUT", 600"QUO", 601"RAG", 602"RAM", 603"RAN", 604"RAP", 605"RAT", 606"RAW", 607"RAY", 608"REB", 609"RED", 610"REP", 611"RET", 612"RIB", 613"RID", 614"RIG", 615"RIM", 616"RIO", 617"RIP", 618"ROB", 619"ROD", 620"ROE", 621"RON", 622"ROT", 623"ROW", 624"ROY", 625"RUB", 626"RUE", 627"RUG", 628"RUM", 629"RUN", 630"RYE", 631"SAC", 632"SAD", 633"SAG", 634"SAL", 635"SAM", 636"SAN", 637"SAP", 638"SAT", 639"SAW", 640"SAY", 641"SEA", 642"SEC", 643"SEE", 644"SEN", 645"SET", 646"SEW", 647"SHE", 648"SHY", 649"SIN", 650"SIP", 651"SIR", 652"SIS", 653"SIT", 654"SKI", 655"SKY", 656"SLY", 657"SO", 658"SOB", 659"SOD", 660"SON", 661"SOP", 662"SOW", 663"SOY", 664"SPA", 665"SPY", 666"SUB", 667"SUD", 668"SUE", 669"SUM", 670"SUN", 671"SUP", 672"TAB", 673"TAD", 674"TAG", 675"TAN", 676"TAP", 677"TAR", 678"TEA", 679"TED", 680"TEE", 681"TEN", 682"THE", 683"THY", 684"TIC", 685"TIE", 686"TIM", 687"TIN", 688"TIP", 689"TO", 690"TOE", 691"TOG", 692"TOM", 693"TON", 694"TOO", 695"TOP", 696"TOW", 697"TOY", 698"TRY", 699"TUB", 700"TUG", 701"TUM", 702"TUN", 703"TWO", 704"UN", 705"UP", 706"US", 707"USE", 708"VAN", 709"VAT", 710"VET", 711"VIE", 712"WAD", 713"WAG", 714"WAR", 715"WAS", 716"WAY", 717"WE", 718"WEB", 719"WED", 720"WEE", 721"WET", 722"WHO", 723"WHY", 724"WIN", 725"WIT", 726"WOK", 727"WON", 728"WOO", 729"WOW", 730"WRY", 731"WU", 732"YAM", 733"YAP", 734"YAW", 735"YE", 736"YEA", 737"YES", 738"YET", 739"YOU", 740"ABED", 741"ABEL", 742"ABET", 743"ABLE", 744"ABUT", 745"ACHE", 746"ACID", 747"ACME", 748"ACRE", 749"ACTA", 750"ACTS", 751"ADAM", 752"ADDS", 753"ADEN", 754"AFAR", 755"AFRO", 756"AGEE", 757"AHEM", 758"AHOY", 759"AIDA", 760"AIDE", 761"AIDS", 762"AIRY", 763"AJAR", 764"AKIN", 765"ALAN", 766"ALEC", 767"ALGA", 768"ALIA", 769"ALLY", 770"ALMA", 771"ALOE", 772"ALSO", 773"ALTO", 774"ALUM", 775"ALVA", 776"AMEN", 777"AMES", 778"AMID", 779"AMMO", 780"AMOK", 781"AMOS", 782"AMRA", 783"ANDY", 784"ANEW", 785"ANNA", 786"ANNE", 787"ANTE", 788"ANTI", 789"AQUA", 790"ARAB", 791"ARCH", 792"AREA", 793"ARGO", 794"ARID", 795"ARMY", 796"ARTS", 797"ARTY", 798"ASIA", 799"ASKS", 800"ATOM", 801"AUNT", 802"AURA", 803"AUTO", 804"AVER", 805"AVID", 806"AVIS", 807"AVON", 808"AVOW", 809"AWAY", 810"AWRY", 811"BABE", 812"BABY", 813"BACH", 814"BACK", 815"BADE", 816"BAIL", 817"BAIT", 818"BAKE", 819"BALD", 820"BALE", 821"BALI", 822"BALK", 823"BALL", 824"BALM", 825"BAND", 826"BANE", 827"BANG", 828"BANK", 829"BARB", 830"BARD", 831"BARE", 832"BARK", 833"BARN", 834"BARR", 835"BASE", 836"BASH", 837"BASK", 838"BASS", 839"BATE", 840"BATH", 841"BAWD", 842"BAWL", 843"BEAD", 844"BEAK", 845"BEAM", 846"BEAN", 847"BEAR", 848"BEAT", 849"BEAU", 850"BECK", 851"BEEF", 852"BEEN", 853"BEER", 854"BEET", 855"BELA", 856"BELL", 857"BELT", 858"BEND", 859"BENT", 860"BERG", 861"BERN", 862"BERT", 863"BESS", 864"BEST", 865"BETA", 866"BETH", 867"BHOY", 868"BIAS", 869"BIDE", 870"BIEN", 871"BILE", 872"BILK", 873"BILL", 874"BIND", 875"BING", 876"BIRD", 877"BITE", 878"BITS", 879"BLAB", 880"BLAT", 881"BLED", 882"BLEW", 883"BLOB", 884"BLOC", 885"BLOT", 886"BLOW", 887"BLUE", 888"BLUM", 889"BLUR", 890"BOAR", 891"BOAT", 892"BOCA", 893"BOCK", 894"BODE", 895"BODY", 896"BOGY", 897"BOHR", 898"BOIL", 899"BOLD", 900"BOLO", 901"BOLT", 902"BOMB", 903"BONA", 904"BOND", 905"BONE", 906"BONG", 907"BONN", 908"BONY", 909"BOOK", 910"BOOM", 911"BOON", 912"BOOT", 913"BORE", 914"BORG", 915"BORN", 916"BOSE", 917"BOSS", 918"BOTH", 919"BOUT", 920"BOWL", 921"BOYD", 922"BRAD", 923"BRAE", 924"BRAG", 925"BRAN", 926"BRAY", 927"BRED", 928"BREW", 929"BRIG", 930"BRIM", 931"BROW", 932"BUCK", 933"BUDD", 934"BUFF", 935"BULB", 936"BULK", 937"BULL", 938"BUNK", 939"BUNT", 940"BUOY", 941"BURG", 942"BURL", 943"BURN", 944"BURR", 945"BURT", 946"BURY", 947"BUSH", 948"BUSS", 949"BUST", 950"BUSY", 951"BYTE", 952"CADY", 953"CAFE", 954"CAGE", 955"CAIN", 956"CAKE", 957"CALF", 958"CALL", 959"CALM", 960"CAME", 961"CANE", 962"CANT", 963"CARD", 964"CARE", 965"CARL", 966"CARR", 967"CART", 968"CASE", 969"CASH", 970"CASK", 971"CAST", 972"CAVE", 973"CEIL", 974"CELL", 975"CENT", 976"CERN", 977"CHAD", 978"CHAR", 979"CHAT", 980"CHAW", 981"CHEF", 982"CHEN", 983"CHEW", 984"CHIC", 985"CHIN", 986"CHOU", 987"CHOW", 988"CHUB", 989"CHUG", 990"CHUM", 991"CITE", 992"CITY", 993"CLAD", 994"CLAM", 995"CLAN", 996"CLAW", 997"CLAY", 998"CLOD", 999"CLOG", 1000"CLOT", 1001"CLUB", 1002"CLUE", 1003"COAL", 1004"COAT", 1005"COCA", 1006"COCK", 1007"COCO", 1008"CODA", 1009"CODE", 1010"CODY", 1011"COED", 1012"COIL", 1013"COIN", 1014"COKE", 1015"COLA", 1016"COLD", 1017"COLT", 1018"COMA", 1019"COMB", 1020"COME", 1021"COOK", 1022"COOL", 1023"COON", 1024"COOT", 1025"CORD", 1026"CORE", 1027"CORK", 1028"CORN", 1029"COST", 1030"COVE", 1031"COWL", 1032"CRAB", 1033"CRAG", 1034"CRAM", 1035"CRAY", 1036"CREW", 1037"CRIB", 1038"CROW", 1039"CRUD", 1040"CUBA", 1041"CUBE", 1042"CUFF", 1043"CULL", 1044"CULT", 1045"CUNY", 1046"CURB", 1047"CURD", 1048"CURE", 1049"CURL", 1050"CURT", 1051"CUTS", 1052"DADE", 1053"DALE", 1054"DAME", 1055"DANA", 1056"DANE", 1057"DANG", 1058"DANK", 1059"DARE", 1060"DARK", 1061"DARN", 1062"DART", 1063"DASH", 1064"DATA", 1065"DATE", 1066"DAVE", 1067"DAVY", 1068"DAWN", 1069"DAYS", 1070"DEAD", 1071"DEAF", 1072"DEAL", 1073"DEAN", 1074"DEAR", 1075"DEBT", 1076"DECK", 1077"DEED", 1078"DEEM", 1079"DEER", 1080"DEFT", 1081"DEFY", 1082"DELL", 1083"DENT", 1084"DENY", 1085"DESK", 1086"DIAL", 1087"DICE", 1088"DIED", 1089"DIET", 1090"DIME", 1091"DINE", 1092"DING", 1093"DINT", 1094"DIRE", 1095"DIRT", 1096"DISC", 1097"DISH", 1098"DISK", 1099"DIVE", 1100"DOCK", 1101"DOES", 1102"DOLE", 1103"DOLL", 1104"DOLT", 1105"DOME", 1106"DONE", 1107"DOOM", 1108"DOOR", 1109"DORA", 1110"DOSE", 1111"DOTE", 1112"DOUG", 1113"DOUR", 1114"DOVE", 1115"DOWN", 1116"DRAB", 1117"DRAG", 1118"DRAM", 1119"DRAW", 1120"DREW", 1121"DRUB", 1122"DRUG", 1123"DRUM", 1124"DUAL", 1125"DUCK", 1126"DUCT", 1127"DUEL", 1128"DUET", 1129"DUKE", 1130"DULL", 1131"DUMB", 1132"DUNE", 1133"DUNK", 1134"DUSK", 1135"DUST", 1136"DUTY", 1137"EACH", 1138"EARL", 1139"EARN", 1140"EASE", 1141"EAST", 1142"EASY", 1143"EBEN", 1144"ECHO", 1145"EDDY", 1146"EDEN", 1147"EDGE", 1148"EDGY", 1149"EDIT", 1150"EDNA", 1151"EGAN", 1152"ELAN", 1153"ELBA", 1154"ELLA", 1155"ELSE", 1156"EMIL", 1157"EMIT", 1158"EMMA", 1159"ENDS", 1160"ERIC", 1161"EROS", 1162"EVEN", 1163"EVER", 1164"EVIL", 1165"EYED", 1166"FACE", 1167"FACT", 1168"FADE", 1169"FAIL", 1170"FAIN", 1171"FAIR", 1172"FAKE", 1173"FALL", 1174"FAME", 1175"FANG", 1176"FARM", 1177"FAST", 1178"FATE", 1179"FAWN", 1180"FEAR", 1181"FEAT", 1182"FEED", 1183"FEEL", 1184"FEET", 1185"FELL", 1186"FELT", 1187"FEND", 1188"FERN", 1189"FEST", 1190"FEUD", 1191"FIEF", 1192"FIGS", 1193"FILE", 1194"FILL", 1195"FILM", 1196"FIND", 1197"FINE", 1198"FINK", 1199"FIRE", 1200"FIRM", 1201"FISH", 1202"FISK", 1203"FIST", 1204"FITS", 1205"FIVE", 1206"FLAG", 1207"FLAK", 1208"FLAM", 1209"FLAT", 1210"FLAW", 1211"FLEA", 1212"FLED", 1213"FLEW", 1214"FLIT", 1215"FLOC", 1216"FLOG", 1217"FLOW", 1218"FLUB", 1219"FLUE", 1220"FOAL", 1221"FOAM", 1222"FOGY", 1223"FOIL", 1224"FOLD", 1225"FOLK", 1226"FOND", 1227"FONT", 1228"FOOD", 1229"FOOL", 1230"FOOT", 1231"FORD", 1232"FORE", 1233"FORK", 1234"FORM", 1235"FORT", 1236"FOSS", 1237"FOUL", 1238"FOUR", 1239"FOWL", 1240"FRAU", 1241"FRAY", 1242"FRED", 1243"FREE", 1244"FRET", 1245"FREY", 1246"FROG", 1247"FROM", 1248"FUEL", 1249"FULL", 1250"FUME", 1251"FUND", 1252"FUNK", 1253"FURY", 1254"FUSE", 1255"FUSS", 1256"GAFF", 1257"GAGE", 1258"GAIL", 1259"GAIN", 1260"GAIT", 1261"GALA", 1262"GALE", 1263"GALL", 1264"GALT", 1265"GAME", 1266"GANG", 1267"GARB", 1268"GARY", 1269"GASH", 1270"GATE", 1271"GAUL", 1272"GAUR", 1273"GAVE", 1274"GAWK", 1275"GEAR", 1276"GELD", 1277"GENE", 1278"GENT", 1279"GERM", 1280"GETS", 1281"GIBE", 1282"GIFT", 1283"GILD", 1284"GILL", 1285"GILT", 1286"GINA", 1287"GIRD", 1288"GIRL", 1289"GIST", 1290"GIVE", 1291"GLAD", 1292"GLEE", 1293"GLEN", 1294"GLIB", 1295"GLOB", 1296"GLOM", 1297"GLOW", 1298"GLUE", 1299"GLUM", 1300"GLUT", 1301"GOAD", 1302"GOAL", 1303"GOAT", 1304"GOER", 1305"GOES", 1306"GOLD", 1307"GOLF", 1308"GONE", 1309"GONG", 1310"GOOD", 1311"GOOF", 1312"GORE", 1313"GORY", 1314"GOSH", 1315"GOUT", 1316"GOWN", 1317"GRAB", 1318"GRAD", 1319"GRAY", 1320"GREG", 1321"GREW", 1322"GREY", 1323"GRID", 1324"GRIM", 1325"GRIN", 1326"GRIT", 1327"GROW", 1328"GRUB", 1329"GULF", 1330"GULL", 1331"GUNK", 1332"GURU", 1333"GUSH", 1334"GUST", 1335"GWEN", 1336"GWYN", 1337"HAAG", 1338"HAAS", 1339"HACK", 1340"HAIL", 1341"HAIR", 1342"HALE", 1343"HALF", 1344"HALL", 1345"HALO", 1346"HALT", 1347"HAND", 1348"HANG", 1349"HANK", 1350"HANS", 1351"HARD", 1352"HARK", 1353"HARM", 1354"HART", 1355"HASH", 1356"HAST", 1357"HATE", 1358"HATH", 1359"HAUL", 1360"HAVE", 1361"HAWK", 1362"HAYS", 1363"HEAD", 1364"HEAL", 1365"HEAR", 1366"HEAT", 1367"HEBE", 1368"HECK", 1369"HEED", 1370"HEEL", 1371"HEFT", 1372"HELD", 1373"HELL", 1374"HELM", 1375"HERB", 1376"HERD", 1377"HERE", 1378"HERO", 1379"HERS", 1380"HESS", 1381"HEWN", 1382"HICK", 1383"HIDE", 1384"HIGH", 1385"HIKE", 1386"HILL", 1387"HILT", 1388"HIND", 1389"HINT", 1390"HIRE", 1391"HISS", 1392"HIVE", 1393"HOBO", 1394"HOCK", 1395"HOFF", 1396"HOLD", 1397"HOLE", 1398"HOLM", 1399"HOLT", 1400"HOME", 1401"HONE", 1402"HONK", 1403"HOOD", 1404"HOOF", 1405"HOOK", 1406"HOOT", 1407"HORN", 1408"HOSE", 1409"HOST", 1410"HOUR", 1411"HOVE", 1412"HOWE", 1413"HOWL", 1414"HOYT", 1415"HUCK", 1416"HUED", 1417"HUFF", 1418"HUGE", 1419"HUGH", 1420"HUGO", 1421"HULK", 1422"HULL", 1423"HUNK", 1424"HUNT", 1425"HURD", 1426"HURL", 1427"HURT", 1428"HUSH", 1429"HYDE", 1430"HYMN", 1431"IBIS", 1432"ICON", 1433"IDEA", 1434"IDLE", 1435"IFFY", 1436"INCA", 1437"INCH", 1438"INTO", 1439"IONS", 1440"IOTA", 1441"IOWA", 1442"IRIS", 1443"IRMA", 1444"IRON", 1445"ISLE", 1446"ITCH", 1447"ITEM", 1448"IVAN", 1449"JACK", 1450"JADE", 1451"JAIL", 1452"JAKE", 1453"JANE", 1454"JAVA", 1455"JEAN", 1456"JEFF", 1457"JERK", 1458"JESS", 1459"JEST", 1460"JIBE", 1461"JILL", 1462"JILT", 1463"JIVE", 1464"JOAN", 1465"JOBS", 1466"JOCK", 1467"JOEL", 1468"JOEY", 1469"JOHN", 1470"JOIN", 1471"JOKE", 1472"JOLT", 1473"JOVE", 1474"JUDD", 1475"JUDE", 1476"JUDO", 1477"JUDY", 1478"JUJU", 1479"JUKE", 1480"JULY", 1481"JUNE", 1482"JUNK", 1483"JUNO", 1484"JURY", 1485"JUST", 1486"JUTE", 1487"KAHN", 1488"KALE", 1489"KANE", 1490"KANT", 1491"KARL", 1492"KATE", 1493"KEEL", 1494"KEEN", 1495"KENO", 1496"KENT", 1497"KERN", 1498"KERR", 1499"KEYS", 1500"KICK", 1501"KILL", 1502"KIND", 1503"KING", 1504"KIRK", 1505"KISS", 1506"KITE", 1507"KLAN", 1508"KNEE", 1509"KNEW", 1510"KNIT", 1511"KNOB", 1512"KNOT", 1513"KNOW", 1514"KOCH", 1515"KONG", 1516"KUDO", 1517"KURD", 1518"KURT", 1519"KYLE", 1520"LACE", 1521"LACK", 1522"LACY", 1523"LADY", 1524"LAID", 1525"LAIN", 1526"LAIR", 1527"LAKE", 1528"LAMB", 1529"LAME", 1530"LAND", 1531"LANE", 1532"LANG", 1533"LARD", 1534"LARK", 1535"LASS", 1536"LAST", 1537"LATE", 1538"LAUD", 1539"LAVA", 1540"LAWN", 1541"LAWS", 1542"LAYS", 1543"LEAD", 1544"LEAF", 1545"LEAK", 1546"LEAN", 1547"LEAR", 1548"LEEK", 1549"LEER", 1550"LEFT", 1551"LEND", 1552"LENS", 1553"LENT", 1554"LEON", 1555"LESK", 1556"LESS", 1557"LEST", 1558"LETS", 1559"LIAR", 1560"LICE", 1561"LICK", 1562"LIED", 1563"LIEN", 1564"LIES", 1565"LIEU", 1566"LIFE", 1567"LIFT", 1568"LIKE", 1569"LILA", 1570"LILT", 1571"LILY", 1572"LIMA", 1573"LIMB", 1574"LIME", 1575"LIND", 1576"LINE", 1577"LINK", 1578"LINT", 1579"LION", 1580"LISA", 1581"LIST", 1582"LIVE", 1583"LOAD", 1584"LOAF", 1585"LOAM", 1586"LOAN", 1587"LOCK", 1588"LOFT", 1589"LOGE", 1590"LOIS", 1591"LOLA", 1592"LONE", 1593"LONG", 1594"LOOK", 1595"LOON", 1596"LOOT", 1597"LORD", 1598"LORE", 1599"LOSE", 1600"LOSS", 1601"LOST", 1602"LOUD", 1603"LOVE", 1604"LOWE", 1605"LUCK", 1606"LUCY", 1607"LUGE", 1608"LUKE", 1609"LULU", 1610"LUND", 1611"LUNG", 1612"LURA", 1613"LURE", 1614"LURK", 1615"LUSH", 1616"LUST", 1617"LYLE", 1618"LYNN", 1619"LYON", 1620"LYRA", 1621"MACE", 1622"MADE", 1623"MAGI", 1624"MAID", 1625"MAIL", 1626"MAIN", 1627"MAKE", 1628"MALE", 1629"MALI", 1630"MALL", 1631"MALT", 1632"MANA", 1633"MANN", 1634"MANY", 1635"MARC", 1636"MARE", 1637"MARK", 1638"MARS", 1639"MART", 1640"MARY", 1641"MASH", 1642"MASK", 1643"MASS", 1644"MAST", 1645"MATE", 1646"MATH", 1647"MAUL", 1648"MAYO", 1649"MEAD", 1650"MEAL", 1651"MEAN", 1652"MEAT", 1653"MEEK", 1654"MEET", 1655"MELD", 1656"MELT", 1657"MEMO", 1658"MEND", 1659"MENU", 1660"MERT", 1661"MESH", 1662"MESS", 1663"MICE", 1664"MIKE", 1665"MILD", 1666"MILE", 1667"MILK", 1668"MILL", 1669"MILT", 1670"MIMI", 1671"MIND", 1672"MINE", 1673"MINI", 1674"MINK", 1675"MINT", 1676"MIRE", 1677"MISS", 1678"MIST", 1679"MITE", 1680"MITT", 1681"MOAN", 1682"MOAT", 1683"MOCK", 1684"MODE", 1685"MOLD", 1686"MOLE", 1687"MOLL", 1688"MOLT", 1689"MONA", 1690"MONK", 1691"MONT", 1692"MOOD", 1693"MOON", 1694"MOOR", 1695"MOOT", 1696"MORE", 1697"MORN", 1698"MORT", 1699"MOSS", 1700"MOST", 1701"MOTH", 1702"MOVE", 1703"MUCH", 1704"MUCK", 1705"MUDD", 1706"MUFF", 1707"MULE", 1708"MULL", 1709"MURK", 1710"MUSH", 1711"MUST", 1712"MUTE", 1713"MUTT", 1714"MYRA", 1715"MYTH", 1716"NAGY", 1717"NAIL", 1718"NAIR", 1719"NAME", 1720"NARY", 1721"NASH", 1722"NAVE", 1723"NAVY", 1724"NEAL", 1725"NEAR", 1726"NEAT", 1727"NECK", 1728"NEED", 1729"NEIL", 1730"NELL", 1731"NEON", 1732"NERO", 1733"NESS", 1734"NEST", 1735"NEWS", 1736"NEWT", 1737"NIBS", 1738"NICE", 1739"NICK", 1740"NILE", 1741"NINA", 1742"NINE", 1743"NOAH", 1744"NODE", 1745"NOEL", 1746"NOLL", 1747"NONE", 1748"NOOK", 1749"NOON", 1750"NORM", 1751"NOSE", 1752"NOTE", 1753"NOUN", 1754"NOVA", 1755"NUDE", 1756"NULL", 1757"NUMB", 1758"OATH", 1759"OBEY", 1760"OBOE", 1761"ODIN", 1762"OHIO", 1763"OILY", 1764"OINT", 1765"OKAY", 1766"OLAF", 1767"OLDY", 1768"OLGA", 1769"OLIN", 1770"OMAN", 1771"OMEN", 1772"OMIT", 1773"ONCE", 1774"ONES", 1775"ONLY", 1776"ONTO", 1777"ONUS", 1778"ORAL", 1779"ORGY", 1780"OSLO", 1781"OTIS", 1782"OTTO", 1783"OUCH", 1784"OUST", 1785"OUTS", 1786"OVAL", 1787"OVEN", 1788"OVER", 1789"OWLY", 1790"OWNS", 1791"QUAD", 1792"QUIT", 1793"QUOD", 1794"RACE", 1795"RACK", 1796"RACY", 1797"RAFT", 1798"RAGE", 1799"RAID", 1800"RAIL", 1801"RAIN", 1802"RAKE", 1803"RANK", 1804"RANT", 1805"RARE", 1806"RASH", 1807"RATE", 1808"RAVE", 1809"RAYS", 1810"READ", 1811"REAL", 1812"REAM", 1813"REAR", 1814"RECK", 1815"REED", 1816"REEF", 1817"REEK", 1818"REEL", 1819"REID", 1820"REIN", 1821"RENA", 1822"REND", 1823"RENT", 1824"REST", 1825"RICE", 1826"RICH", 1827"RICK", 1828"RIDE", 1829"RIFT", 1830"RILL", 1831"RIME", 1832"RING", 1833"RINK", 1834"RISE", 1835"RISK", 1836"RITE", 1837"ROAD", 1838"ROAM", 1839"ROAR", 1840"ROBE", 1841"ROCK", 1842"RODE", 1843"ROIL", 1844"ROLL", 1845"ROME", 1846"ROOD", 1847"ROOF", 1848"ROOK", 1849"ROOM", 1850"ROOT", 1851"ROSA", 1852"ROSE", 1853"ROSS", 1854"ROSY", 1855"ROTH", 1856"ROUT", 1857"ROVE", 1858"ROWE", 1859"ROWS", 1860"RUBE", 1861"RUBY", 1862"RUDE", 1863"RUDY", 1864"RUIN", 1865"RULE", 1866"RUNG", 1867"RUNS", 1868"RUNT", 1869"RUSE", 1870"RUSH", 1871"RUSK", 1872"RUSS", 1873"RUST", 1874"RUTH", 1875"SACK", 1876"SAFE", 1877"SAGE", 1878"SAID", 1879"SAIL", 1880"SALE", 1881"SALK", 1882"SALT", 1883"SAME", 1884"SAND", 1885"SANE", 1886"SANG", 1887"SANK", 1888"SARA", 1889"SAUL", 1890"SAVE", 1891"SAYS", 1892"SCAN", 1893"SCAR", 1894"SCAT", 1895"SCOT", 1896"SEAL", 1897"SEAM", 1898"SEAR", 1899"SEAT", 1900"SEED", 1901"SEEK", 1902"SEEM", 1903"SEEN", 1904"SEES", 1905"SELF", 1906"SELL", 1907"SEND", 1908"SENT", 1909"SETS", 1910"SEWN", 1911"SHAG", 1912"SHAM", 1913"SHAW", 1914"SHAY", 1915"SHED", 1916"SHIM", 1917"SHIN", 1918"SHOD", 1919"SHOE", 1920"SHOT", 1921"SHOW", 1922"SHUN", 1923"SHUT", 1924"SICK", 1925"SIDE", 1926"SIFT", 1927"SIGH", 1928"SIGN", 1929"SILK", 1930"SILL", 1931"SILO", 1932"SILT", 1933"SINE", 1934"SING", 1935"SINK", 1936"SIRE", 1937"SITE", 1938"SITS", 1939"SITU", 1940"SKAT", 1941"SKEW", 1942"SKID", 1943"SKIM", 1944"SKIN", 1945"SKIT", 1946"SLAB", 1947"SLAM", 1948"SLAT", 1949"SLAY", 1950"SLED", 1951"SLEW", 1952"SLID", 1953"SLIM", 1954"SLIT", 1955"SLOB", 1956"SLOG", 1957"SLOT", 1958"SLOW", 1959"SLUG", 1960"SLUM", 1961"SLUR", 1962"SMOG", 1963"SMUG", 1964"SNAG", 1965"SNOB", 1966"SNOW", 1967"SNUB", 1968"SNUG", 1969"SOAK", 1970"SOAR", 1971"SOCK", 1972"SODA", 1973"SOFA", 1974"SOFT", 1975"SOIL", 1976"SOLD", 1977"SOME", 1978"SONG", 1979"SOON", 1980"SOOT", 1981"SORE", 1982"SORT", 1983"SOUL", 1984"SOUR", 1985"SOWN", 1986"STAB", 1987"STAG", 1988"STAN", 1989"STAR", 1990"STAY", 1991"STEM", 1992"STEW", 1993"STIR", 1994"STOW", 1995"STUB", 1996"STUN", 1997"SUCH", 1998"SUDS", 1999"SUIT", 2000"SULK", 2001"SUMS", 2002"SUNG", 2003"SUNK", 2004"SURE", 2005"SURF", 2006"SWAB", 2007"SWAG", 2008"SWAM", 2009"SWAN", 2010"SWAT", 2011"SWAY", 2012"SWIM", 2013"SWUM", 2014"TACK", 2015"TACT", 2016"TAIL", 2017"TAKE", 2018"TALE", 2019"TALK", 2020"TALL", 2021"TANK", 2022"TASK", 2023"TATE", 2024"TAUT", 2025"TEAL", 2026"TEAM", 2027"TEAR", 2028"TECH", 2029"TEEM", 2030"TEEN", 2031"TEET", 2032"TELL", 2033"TEND", 2034"TENT", 2035"TERM", 2036"TERN", 2037"TESS", 2038"TEST", 2039"THAN", 2040"THAT", 2041"THEE", 2042"THEM", 2043"THEN", 2044"THEY", 2045"THIN", 2046"THIS", 2047"THUD", 2048"THUG", 2049"TICK", 2050"TIDE", 2051"TIDY", 2052"TIED", 2053"TIER", 2054"TILE", 2055"TILL", 2056"TILT", 2057"TIME", 2058"TINA", 2059"TINE", 2060"TINT", 2061"TINY", 2062"TIRE", 2063"TOAD", 2064"TOGO", 2065"TOIL", 2066"TOLD", 2067"TOLL", 2068"TONE", 2069"TONG", 2070"TONY", 2071"TOOK", 2072"TOOL", 2073"TOOT", 2074"TORE", 2075"TORN", 2076"TOTE", 2077"TOUR", 2078"TOUT", 2079"TOWN", 2080"TRAG", 2081"TRAM", 2082"TRAY", 2083"TREE", 2084"TREK", 2085"TRIG", 2086"TRIM", 2087"TRIO", 2088"TROD", 2089"TROT", 2090"TROY", 2091"TRUE", 2092"TUBA", 2093"TUBE", 2094"TUCK", 2095"TUFT", 2096"TUNA", 2097"TUNE", 2098"TUNG", 2099"TURF", 2100"TURN", 2101"TUSK", 2102"TWIG", 2103"TWIN", 2104"TWIT", 2105"ULAN", 2106"UNIT", 2107"URGE", 2108"USED", 2109"USER", 2110"USES", 2111"UTAH", 2112"VAIL", 2113"VAIN", 2114"VALE", 2115"VARY", 2116"VASE", 2117"VAST", 2118"VEAL", 2119"VEDA", 2120"VEIL", 2121"VEIN", 2122"VEND", 2123"VENT", 2124"VERB", 2125"VERY", 2126"VETO", 2127"VICE", 2128"VIEW", 2129"VINE", 2130"VISE", 2131"VOID", 2132"VOLT", 2133"VOTE", 2134"WACK", 2135"WADE", 2136"WAGE", 2137"WAIL", 2138"WAIT", 2139"WAKE", 2140"WALE", 2141"WALK", 2142"WALL", 2143"WALT", 2144"WAND", 2145"WANE", 2146"WANG", 2147"WANT", 2148"WARD", 2149"WARM", 2150"WARN", 2151"WART", 2152"WASH", 2153"WAST", 2154"WATS", 2155"WATT", 2156"WAVE", 2157"WAVY", 2158"WAYS", 2159"WEAK", 2160"WEAL", 2161"WEAN", 2162"WEAR", 2163"WEED", 2164"WEEK", 2165"WEIR", 2166"WELD", 2167"WELL", 2168"WELT", 2169"WENT", 2170"WERE", 2171"WERT", 2172"WEST", 2173"WHAM", 2174"WHAT", 2175"WHEE", 2176"WHEN", 2177"WHET", 2178"WHOA", 2179"WHOM", 2180"WICK", 2181"WIFE", 2182"WILD", 2183"WILL", 2184"WIND", 2185"WINE", 2186"WING", 2187"WINK", 2188"WINO", 2189"WIRE", 2190"WISE", 2191"WISH", 2192"WITH", 2193"WOLF", 2194"WONT", 2195"WOOD", 2196"WOOL", 2197"WORD", 2198"WORE", 2199"WORK", 2200"WORM", 2201"WORN", 2202"WOVE", 2203"WRIT", 2204"WYNN", 2205"YALE", 2206"YANG", 2207"YANK", 2208"YARD", 2209"YARN", 2210"YAWL", 2211"YAWN", 2212"YEAH", 2213"YEAR", 2214"YELL", 2215"YOGA", 2216"YOKE" 2217}; 2218 2219 2220 2221 2222/* 2223 *------------------------------------------------------* 2224 * 2225 * TrfInit_OTP_WORDS -- 2226 * 2227 * ------------------------------------------------* 2228 * Register the conversion implemented in this file. 2229 * ------------------------------------------------* 2230 * 2231 * Sideeffects: 2232 * As of 'Trf_Register'. 2233 * 2234 * Result: 2235 * A standard Tcl error code. 2236 * 2237 *------------------------------------------------------* 2238 */ 2239 2240int 2241TrfInit_OTP_WORDS (interp) 2242Tcl_Interp* interp; 2243{ 2244 TrfLock; /* THREADING: serialize initialization */ 2245 convDefinition.options = Trf_ConverterOptions (); 2246 TrfUnlock; 2247 2248 return Trf_Register (interp, &convDefinition); 2249} 2250 2251/* 2252 *------------------------------------------------------* 2253 * 2254 * CreateEncoder -- 2255 * 2256 * ------------------------------------------------* 2257 * Allocate and initialize the control block of a 2258 * data encoder. 2259 * ------------------------------------------------* 2260 * 2261 * Sideeffects: 2262 * Allocates memory. 2263 * 2264 * Result: 2265 * An opaque reference to the control block. 2266 * 2267 *------------------------------------------------------* 2268 */ 2269 2270static Trf_ControlBlock 2271CreateEncoder (writeClientData, fun, optInfo, interp, clientData) 2272ClientData writeClientData; 2273Trf_WriteProc *fun; 2274Trf_Options optInfo; 2275Tcl_Interp* interp; 2276ClientData clientData; 2277{ 2278 EncoderControl* c; 2279 2280 c = (EncoderControl*) ckalloc (sizeof (EncoderControl)); 2281 c->write = fun; 2282 c->writeClientData = writeClientData; 2283 2284 /* initialize conversion specific items here (otp_words encode) */ 2285 2286 ClearEncoder ((Trf_ControlBlock) c, clientData); 2287 2288 return ((ClientData) c); 2289} 2290 2291/* 2292 *------------------------------------------------------* 2293 * 2294 * DeleteEncoder -- 2295 * 2296 * ------------------------------------------------* 2297 * Destroy the control block of an encoder. 2298 * ------------------------------------------------* 2299 * 2300 * Sideeffects: 2301 * Releases the memory allocated by 'CreateEncoder' 2302 * 2303 * Result: 2304 * None. 2305 * 2306 *------------------------------------------------------* 2307 */ 2308 2309static void 2310DeleteEncoder (ctrlBlock, clientData) 2311Trf_ControlBlock ctrlBlock; 2312ClientData clientData; 2313{ 2314 EncoderControl* c = (EncoderControl*) ctrlBlock; 2315 2316 /* release conversion specific items here (otp_words encode) */ 2317 2318 ckfree ((char*) c); 2319} 2320 2321/* 2322 *------------------------------------------------------* 2323 * 2324 * Encode -- 2325 * 2326 * ------------------------------------------------* 2327 * Encode the given character and write the result. 2328 * ------------------------------------------------* 2329 * 2330 * Sideeffects: 2331 * As of the called WriteFun. 2332 * 2333 * Result: 2334 * Generated bytes implicitly via WriteFun. 2335 * A standard Tcl error code. 2336 * 2337 *------------------------------------------------------* 2338 */ 2339 2340static int 2341Encode (ctrlBlock, character, interp, clientData) 2342Trf_ControlBlock ctrlBlock; 2343unsigned int character; 2344Tcl_Interp* interp; 2345ClientData clientData; 2346{ 2347 EncoderControl* c = (EncoderControl*) ctrlBlock; 2348 2349 /* execute conversion specific code here (otp_words encode) */ 2350 2351 if (c -> charCount == 8) { 2352 int i = FlushEncoder (ctrlBlock, interp, clientData); 2353 2354 if (i == TCL_OK) 2355 i = c -> write (c -> writeClientData, (unsigned char*) "\n", 1, interp); 2356 2357 if (i != TCL_OK) 2358 return i; 2359 } 2360 2361 c -> buf[c -> charCount++] = character; 2362 2363 return TCL_OK; 2364} 2365 2366/* 2367 *------------------------------------------------------* 2368 * 2369 * EncodeBuffer -- 2370 * 2371 * ------------------------------------------------* 2372 * Encode the given buffer and write the result. 2373 * ------------------------------------------------* 2374 * 2375 * Sideeffects: 2376 * As of the called WriteFun. 2377 * 2378 * Result: 2379 * Generated bytes implicitly via WriteFun. 2380 * A standard Tcl error code. 2381 * 2382 *------------------------------------------------------* 2383 */ 2384 2385static int 2386EncodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) 2387Trf_ControlBlock ctrlBlock; 2388unsigned char* buffer; 2389int bufLen; 2390Tcl_Interp* interp; 2391ClientData clientData; 2392{ 2393 /* EncoderControl* c = (EncoderControl*) ctrlBlock; unused */ 2394 /* execute conversion specific code here (otp_words encode) */ 2395 2396 int i = TCL_OK; 2397 2398 while (bufLen-- > 0) { 2399 if ((i = Encode (ctrlBlock, *buffer++ & 0xff, interp, clientData)) 2400 != TCL_OK) 2401 break; 2402 } 2403 2404 return i; 2405} 2406 2407/* 2408 *------------------------------------------------------* 2409 * 2410 * FlushEncoder -- 2411 * 2412 * ------------------------------------------------* 2413 * Encode an incomplete character sequence (if possible). 2414 * ------------------------------------------------* 2415 * 2416 * Sideeffects: 2417 * As of the called WriteFun. 2418 * 2419 * Result: 2420 * Generated bytes implicitly via WriteFun. 2421 * A standard Tcl error code. 2422 * 2423 *------------------------------------------------------* 2424 */ 2425 2426static int 2427FlushEncoder (ctrlBlock, interp, clientData) 2428Trf_ControlBlock ctrlBlock; 2429Tcl_Interp* interp; 2430ClientData clientData; 2431{ 2432 EncoderControl* c = (EncoderControl*) ctrlBlock; 2433 2434 /* execute conversion specific code here (otp_words encode) */ 2435 2436 int i, p; 2437 char cp[10]; 2438 2439 switch (c -> charCount) { 2440 case 8: 2441 break; 2442 2443 case 0: 2444 return TCL_OK; 2445 2446 default: 2447 if (interp) { 2448 Tcl_ResetResult (interp); 2449 Tcl_AppendResult (interp, 2450 "input string must be a multiple of 64-bits", 2451 (char *) NULL); 2452 } 2453 return TCL_ERROR; 2454 } 2455 2456 memset (cp, '\0', sizeof cp); 2457 memcpy (cp, c -> buf, sizeof c -> buf); 2458 2459 for (p = 0, i = 0; i < 64; i += 2) 2460 p += extract (cp, i, 2); 2461 2462 cp[sizeof c -> buf] = (char) (p << 6); 2463 2464 for (p = 0; p <= 55; p += 11) { 2465 char *w = &Wp[extract (cp, p, 11)][0]; 2466 char buf[5]; 2467 2468 memset (buf, '\0', sizeof buf); 2469 2470 for (i = 0; i < 4; i++) { 2471 buf[i] = *w++; 2472 } 2473 2474 i = c -> write (c -> writeClientData, (unsigned char*) buf, strlen (buf), 2475 interp); 2476 if ((i == TCL_OK) && (p != 55)) 2477 i = c -> write (c -> writeClientData, (unsigned char*) " ", 1, interp); 2478 if (i != TCL_OK) 2479 return i; 2480 } 2481 2482 ClearEncoder (ctrlBlock, clientData); 2483 2484 return TCL_OK; 2485} 2486 2487/* 2488 *------------------------------------------------------* 2489 * 2490 * ClearEncoder -- 2491 * 2492 * ------------------------------------------------* 2493 * Discard an incomplete character sequence. 2494 * ------------------------------------------------* 2495 * 2496 * Sideeffects: 2497 * See above. 2498 * 2499 * Result: 2500 * None. 2501 * 2502 *------------------------------------------------------* 2503 */ 2504 2505static void 2506ClearEncoder (ctrlBlock, clientData) 2507Trf_ControlBlock ctrlBlock; 2508ClientData clientData; 2509{ 2510 EncoderControl* c = (EncoderControl*) ctrlBlock; 2511 2512 /* execute conversion specific code here (otp_words encode) */ 2513 2514 c -> charCount = 0; 2515 memset (c -> buf, '\0', sizeof c -> buf); 2516} 2517 2518/* 2519 *------------------------------------------------------* 2520 * 2521 * CreateDecoder -- 2522 * 2523 * ------------------------------------------------* 2524 * Allocate and initialize the control block of a 2525 * data decoder. 2526 * ------------------------------------------------* 2527 * 2528 * Sideeffects: 2529 * Allocates memory. 2530 * 2531 * Result: 2532 * An opaque reference to the control block. 2533 * 2534 *------------------------------------------------------* 2535 */ 2536 2537static Trf_ControlBlock 2538CreateDecoder (writeClientData, fun, optInfo, interp, clientData) 2539ClientData writeClientData; 2540Trf_WriteProc *fun; 2541Trf_Options optInfo; 2542Tcl_Interp* interp; 2543ClientData clientData; 2544{ 2545 DecoderControl* c; 2546 2547 c = (DecoderControl*) ckalloc (sizeof (DecoderControl)); 2548 c->write = fun; 2549 c->writeClientData = writeClientData; 2550 2551 /* initialize conversion specific items here (otp_words decode) */ 2552 2553 ClearDecoder ((Trf_ControlBlock) c, clientData); 2554 2555 return ((ClientData) c); 2556} 2557 2558/* 2559 *------------------------------------------------------* 2560 * 2561 * DeleteDecoder -- 2562 * 2563 * ------------------------------------------------* 2564 * Destroy the control block of an decoder. 2565 * ------------------------------------------------* 2566 * 2567 * Sideeffects: 2568 * Releases the memory allocated by 'CreateDecoder' 2569 * 2570 * Result: 2571 * None. 2572 * 2573 *------------------------------------------------------* 2574 */ 2575 2576static void 2577DeleteDecoder (ctrlBlock, clientData) 2578Trf_ControlBlock ctrlBlock; 2579ClientData clientData; 2580{ 2581 DecoderControl* c = (DecoderControl*) ctrlBlock; 2582 2583 /* release conversion specific items here (otp_words decode) */ 2584 2585 ckfree ((char*) c); 2586} 2587 2588/* 2589 *------------------------------------------------------* 2590 * 2591 * Decode -- 2592 * 2593 * ------------------------------------------------* 2594 * Decode the given character and write the result. 2595 * ------------------------------------------------* 2596 * 2597 * Sideeffects: 2598 * As of the called WriteFun. 2599 * 2600 * Result: 2601 * Generated bytes implicitly via WriteFun. 2602 * A standard Tcl error code. 2603 * 2604 *------------------------------------------------------* 2605 */ 2606 2607static int 2608Decode (ctrlBlock, character, interp, clientData) 2609Trf_ControlBlock ctrlBlock; 2610unsigned int character; 2611Tcl_Interp* interp; 2612ClientData clientData; 2613{ 2614 DecoderControl* c = (DecoderControl*) ctrlBlock; 2615 2616 /* execute conversion specific code here (otp_words decode) */ 2617 2618 char x = character & 0xff; 2619 char *cp; 2620 2621 if (c -> wordCount == 6) { 2622 int i = FlushDecoder (ctrlBlock, interp, clientData); 2623 2624 if (i != TCL_OK) 2625 return i; 2626 } 2627 2628 if (!isascii (x)) { 2629 if (interp) { 2630 Tcl_ResetResult (interp); 2631 Tcl_AppendResult (interp, "invalid character", (char *) NULL); 2632 } 2633 return TCL_ERROR; 2634 } 2635 2636 switch (x) { 2637 case ' ': /* fall through */ 2638 case '\t': /* fall through */ 2639 case '\n': /* fall through */ 2640 case ',': 2641 if (c -> charCount == 0) { 2642 if (interp) { 2643 Tcl_ResetResult (interp); 2644 Tcl_AppendResult (interp, "empty word", (char *) NULL); 2645 } 2646 return TCL_ERROR; 2647 } 2648 c -> charCount = 0; 2649 c -> wordCount++; 2650 return TCL_OK; 2651 2652 default: 2653 if (c -> charCount == 4) { 2654 if (interp) { 2655 Tcl_ResetResult (interp); 2656 Tcl_AppendResult (interp, "word too long", (char *) NULL); 2657 } 2658 return TCL_ERROR; 2659 } 2660 if (islower (x)) { 2661 x = toupper (x); 2662 } 2663 break; 2664 } 2665 2666 switch (x) { 2667 case '5': 2668 x = 'S'; 2669 break; 2670 2671 case '1': 2672 x = 'L'; 2673 break; 2674 2675 case '0': 2676 x = 'O'; 2677 break; 2678 } 2679 2680 cp = &(c -> words[c -> wordCount][0]); 2681 cp[c -> charCount++] = x; 2682 cp[c -> charCount] = '\0'; 2683 2684 return TCL_OK; 2685} 2686 2687/* 2688 *------------------------------------------------------* 2689 * 2690 * DecodeBuffer -- 2691 * 2692 * ------------------------------------------------* 2693 * Decode the given buffer and write the result. 2694 * ------------------------------------------------* 2695 * 2696 * Sideeffects: 2697 * As of the called WriteFun. 2698 * 2699 * Result: 2700 * Generated bytes implicitly via WriteFun. 2701 * A standard Tcl error code. 2702 * 2703 *------------------------------------------------------* 2704 */ 2705 2706static int 2707DecodeBuffer (ctrlBlock, buffer, bufLen, interp, clientData) 2708Trf_ControlBlock ctrlBlock; 2709unsigned char* buffer; 2710int bufLen; 2711Tcl_Interp* interp; 2712ClientData clientData; 2713{ 2714 /* DecoderControl* c = (DecoderControl*) ctrlBlock; unused */ 2715 /* execute conversion specific code here (otp_words decode) */ 2716 2717 int i = TCL_OK; 2718 2719 while (bufLen-- > 0) { 2720 if ((i = Decode (ctrlBlock, *buffer++ & 0xff, interp, clientData)) 2721 != TCL_OK) 2722 break; 2723 } 2724 2725 return i; 2726} 2727 2728/* 2729 *------------------------------------------------------* 2730 * 2731 * FlushDecoder -- 2732 * 2733 * ------------------------------------------------* 2734 * Decode an incomplete character sequence (if possible). 2735 * ------------------------------------------------* 2736 * 2737 * Sideeffects: 2738 * As of the called WriteFun. 2739 * 2740 * Result: 2741 * Generated bytes implicitly via WriteFun. 2742 * A standard Tcl error code. 2743 * 2744 *------------------------------------------------------* 2745 */ 2746 2747static int 2748FlushDecoder (ctrlBlock, interp, clientData) 2749Trf_ControlBlock ctrlBlock; 2750Tcl_Interp* interp; 2751ClientData clientData; 2752{ 2753 DecoderControl* c = (DecoderControl*) ctrlBlock; 2754 2755 /* execute conversion specific code here (otp_words decode) */ 2756 2757 int i; 2758 unsigned long p; 2759 char b[9]; 2760 2761 if ((c -> wordCount == 5) && (c -> charCount > 0)) 2762 c -> wordCount = 6; 2763 2764 switch (c -> wordCount) { 2765 case 6: 2766 break; 2767 2768 case 0: 2769 if (c -> charCount == 0) 2770 return TCL_OK; 2771 /* else fall through... */ 2772 default: 2773 if (interp) { 2774 Tcl_ResetResult (interp); 2775 Tcl_AppendResult (interp, "too few words", (char *) NULL); 2776 } 2777 return TCL_ERROR; 2778 } 2779 2780 memset (b, '\0', sizeof b); 2781 for (c -> wordCount = 0, p = 0; 2782 c -> wordCount < 6; 2783 c -> wordCount++, p += 11) { 2784 int lo, hi; 2785 int v; 2786 char *w = &c -> words[c -> wordCount][0]; 2787 2788 if (strlen (w) < 4) 2789 lo = 0, hi = 570; 2790 else 2791 lo = 571, hi = 2047; 2792 if ((v = wsrch (w, lo, hi)) < 0) { 2793 if (interp) { 2794 Tcl_ResetResult (interp); 2795 Tcl_AppendResult (interp, "unknown word \"", w, "\"", 2796 (char *) NULL); 2797 } 2798 return TCL_ERROR; 2799 } 2800 insert (b, v, p, 11); 2801 } 2802 2803 for (p = 0, i = 0; i < 64; i += 2) 2804 p += extract (b, i, 2); 2805 2806 if ((p & 0x03) != extract (b, 64, 2)) { 2807 if (interp) { 2808 Tcl_ResetResult (interp); 2809 Tcl_AppendResult (interp, "parity error", (char *) NULL); 2810 } 2811 return TCL_ERROR; 2812 } 2813 2814 i = c -> write (c -> writeClientData, (unsigned char*) b, 8, interp); 2815 if (i != TCL_OK) 2816 return i; 2817 2818 ClearDecoder (ctrlBlock, clientData); 2819 2820 return TCL_OK; 2821} 2822 2823/* 2824 *------------------------------------------------------* 2825 * 2826 * ClearDecoder -- 2827 * 2828 * ------------------------------------------------* 2829 * Discard an incomplete character sequence. 2830 * ------------------------------------------------* 2831 * 2832 * Sideeffects: 2833 * See above. 2834 * 2835 * Result: 2836 * None. 2837 * 2838 *------------------------------------------------------* 2839 */ 2840 2841static void 2842ClearDecoder (ctrlBlock, clientData) 2843Trf_ControlBlock ctrlBlock; 2844ClientData clientData; 2845{ 2846 DecoderControl* c = (DecoderControl*) ctrlBlock; 2847 2848 /* execute conversion specific code here (otp_words decode) */ 2849 2850 c -> charCount = 0; 2851 c -> wordCount = 0; 2852 memset (c -> words, '\0', sizeof c -> words); 2853} 2854 2855 2856/* subroutines taken from the module put.c in the original Bellcore reference 2857 distribution */ 2858 2859 2860/* Dictionary binary search */ 2861static int 2862wsrch(w,low,high) 2863char *w; 2864int low, high; 2865{ 2866 int i,j; 2867 2868 for(;;) { 2869 i = (low + high)/2; 2870 if((j = strncmp(w,Wp[i],4)) == 0) 2871 return i; /* Found it */ 2872 if(high == low+1){ 2873 /* Avoid effects of integer truncation in /2 */ 2874 if(strncmp(w,Wp[high],4) == 0) 2875 return high; 2876 else 2877 return -1; 2878 } 2879 if(low >= high) 2880 return -1; /* I don't *think* this can happen...*/ 2881 if(j < 0) 2882 high = i; /* Search lower half */ 2883 else 2884 low = i; /* Search upper half */ 2885 } 2886} 2887 2888static void 2889insert(s, x, start, length) 2890char *s; 2891int x; 2892int start, length; 2893{ 2894 unsigned char cl; 2895 unsigned char cc; 2896 unsigned char cr; 2897 unsigned long y; 2898 int shift; 2899 2900 assert(length <= 11); 2901 assert(start >= 0); 2902 assert(length >= 0); 2903 assert(start +length <= 66); 2904 2905 shift = ((8 -(( start + length) % 8))%8); 2906 y = (long) (x << shift); 2907 cl = (unsigned char) ((y >> 16) & 0xff); 2908 cc = (unsigned char) ((y >> 8) & 0xff); 2909 cr = (unsigned char) (y & 0xff); 2910 if(shift + length > 16) { 2911 s[start /8] |= cl; 2912 s[start/8 +1] |= cc; 2913 s[start/8 +2] |= cr; 2914 } else if(shift +length > 8) { 2915 s[start/8] |= cc; 2916 s[start/8 + 1] |= cr; 2917 } else { 2918 s[start/8] |= cr; 2919 } 2920} 2921 2922/* Extract 'length' bits from the char array 's' starting with bit 'start' */ 2923static unsigned long 2924extract(s, start, length) 2925char *s; 2926int start, length; 2927{ 2928 unsigned char cl; 2929 unsigned char cc; 2930 unsigned char cr; 2931 unsigned long x; 2932 2933 assert(length <= 11); 2934 assert(start >= 0); 2935 assert(length >= 0); 2936 assert(start +length <= 66); 2937 2938 cl = s[start/8]; 2939 cc = s[start/8 +1]; 2940 cr = s[start/8 +2]; 2941 x = ((long)(cl<<8 | cc) <<8 | cr) ; 2942 x = x >> (24 - (length + (start %8))); 2943 x =( x & (0xffff >> (16-length) ) ); 2944 return(x); 2945} 2946 2947