1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 5926 5927 5928 5929 5930 5931 5932 5933 5934 5935 5936 5937 5938 5939 5940 5941 5942 5943 5944 5945 5946 5947 5948 5949 5950 5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 6186 6187 6188 6189 6190 6191 6192 6193 6194 6195 6196 6197 6198 6199 6200 6201 6202 6203 6204 6205 6206 6207 6208 6209 6210 6211 6212 6213 6214 6215 6216 6217 6218 6219 6220 6221 6222 6223 6224 6225 6226 6227 6228 6229 6230 6231 6232 6233 6234 6235 6236 6237 6238 6239 6240 6241 6242 6243 6244 6245 6246 6247 6248 6249 6250 6251 6252 6253 6254 6255 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 6277 6278 6279 6280 6281 6282 6283 6284 6285 6286 6287 6288 6289 6290 6291 6292 6293 6294 6295 6296 6297 6298 6299 6300 6301 6302 6303 6304 6305 6306 6307 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 6333 6334 6335 6336 6337 6338 6339 6340 6341 6342 6343 6344 6345 6346 6347 6348 6349 6350 6351 6352 6353 6354 6355 6356 6357 6358 6359 6360 6361 6362 6363 6364 6365 6366 6367 6368 6369 6370 6371 6372 6373 6374 6375 6376 6377 6378 6379 6380 6381 6382 6383 6384 6385 6386 6387 6388 6389 6390 6391 6392 6393 6394 6395 6396 6397 6398 6399 6400 6401 6402 6403 6404 6405 6406 6407 6408 6409 6410 6411 6412 6413 6414 6415 6416 6417 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 6435 6436 6437 6438 6439 6440 6441 6442 6443 6444 6445 6446 6447 6448 6449 6450 6451 6452 6453 6454 6455 6456 6457 6458 6459 6460 6461 6462 6463 6464 6465 6466 6467 6468 6469 6470 6471 6472 6473 6474 6475 6476 6477 6478 6479 6480 6481 6482 6483 6484 6485 6486 6487 6488 6489 6490 6491 6492 6493 6494 6495 6496 6497 6498 6499 6500 6501 6502 6503 6504 6505 6506 6507 6508 6509 6510 6511 6512 6513 6514 6515 6516 6517 6518 6519 6520 6521 6522 6523 6524 6525 6526 6527 6528 6529 6530 6531 6532 6533 6534 6535 6536 6537 6538 6539 6540 6541 6542 6543 6544 6545 6546 6547 6548 6549 6550 6551 6552 6553 6554 6555 6556 6557 6558 6559 6560 6561 6562 6563 6564 6565 6566 6567 6568 6569 6570 6571 6572 6573 6574 6575 6576 6577 6578 6579 6580 6581 6582 6583 6584 6585 6586 6587 6588 6589 6590 6591 6592 6593 6594 6595 6596 6597 6598 6599 6600 6601 6602 6603 6604 6605 6606 6607 6608 6609 6610 6611 6612 6613 6614 6615 6616 6617 6618 6619 6620 6621 6622 6623 6624 6625 6626 6627 6628 6629 6630 6631 6632 6633 6634 6635 6636 6637 6638 6639 6640 6641 6642 6643 6644 6645 6646 6647 6648 6649 6650 6651 6652 6653 6654 6655 6656 6657 6658 6659 6660 6661 6662 6663 6664 6665 6666 6667 6668 6669 6670 6671 6672 6673 6674 6675 6676 6677 6678 6679 6680 6681 6682 6683 6684 6685 6686 6687 6688 6689 6690 6691 6692 6693 6694 6695 6696 6697 6698 6699 6700 6701 6702 6703 6704 6705 6706 6707 6708 6709 6710 6711 6712 6713 6714 6715 6716 6717 6718 6719 6720 6721 6722 6723 6724 6725 6726 6727 6728 6729 6730 6731 6732 6733 6734 6735 6736 6737 6738 6739 6740 6741 6742 6743 6744 6745 6746 6747 6748 6749 6750 6751 6752 6753 6754 6755 6756 6757 6758 6759 6760 6761 6762 6763 6764 6765 6766 6767 6768 6769 6770 6771 6772 6773 6774 6775 6776 6777 6778 6779 6780 6781 6782 6783 6784 6785 6786 6787 6788 6789 6790 6791 6792 6793 6794 6795 6796 6797 6798 6799 6800 6801 6802 6803 6804 6805 6806 6807 6808 6809 6810 6811 6812 6813 6814 6815 6816 6817 6818 6819 6820 6821 6822 6823 6824 6825 6826 6827 6828 6829 6830 6831 6832 6833 6834 6835 6836 6837 6838 6839 6840 6841 6842 6843 6844 6845 6846 6847 6848 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 6875 6876 6877 6878 6879 6880 6881 6882 6883 6884 6885 6886 6887 6888 6889 6890 6891 6892 6893 6894 6895 6896 6897 6898 6899 6900 6901 6902 6903 6904 6905 6906 6907 6908 6909 6910 6911 6912 6913 6914 6915 6916 6917 6918 6919 6920 6921 6922 6923 6924 6925 6926 6927 6928 6929 6930 6931 6932 6933 6934 6935 6936 6937 6938 6939 6940 6941 6942 6943 6944 6945 6946 6947 6948 6949 6950 6951 6952 6953 6954 6955 6956 6957 6958 6959 6960 6961 6962 6963 6964 6965 6966 6967 6968 6969 6970 6971 6972 6973 6974 6975 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7031 7032 7033 7034 7035 7036 7037 7038 7039 7040 7041 7042 7043 7044 7045 7046 7047 7048 7049 7050 7051 7052 7053 7054 7055 7056 7057 7058 7059 7060 7061 7062 7063 7064 7065 7066 7067 7068 7069 7070 7071 7072 7073 7074 7075 7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 7139 7140 7141 7142 7143 7144 7145 7146 7147 7148 7149 7150 7151 7152 7153 7154 7155 7156 7157 7158 7159 7160 7161 7162 7163 7164 7165 7166 7167 7168 7169 7170 7171 7172 7173 7174 7175 7176 7177 7178 7179 7180 7181 7182 7183 7184 7185 7186 7187 7188 7189 7190 7191 7192 7193 7194 7195 7196 7197 7198 7199 7200 7201 7202 7203 7204 7205 7206 7207 7208 7209 7210 7211 7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 7239 7240 7241 7242 7243 7244 7245 7246 7247 7248 7249 7250 7251 7252 7253 7254 7255 7256 7257 7258 7259 7260 7261 7262 7263 7264 7265 7266 7267 7268 7269 7270 7271 7272 7273 7274 7275 7276 7277 7278 7279 7280 7281 7282 7283 7284 7285 7286 7287 7288 7289 7290 7291 7292 7293 7294 7295 7296 7297 7298 7299 7300 7301 7302 7303 7304 7305 7306 7307 7308 7309 7310 7311 7312 7313 7314 7315 7316 7317 7318 7319 7320 7321 7322 7323 7324 7325 7326 7327 7328 7329 7330 7331 7332 7333 7334 7335 7336 7337 7338 7339 7340 7341 7342 7343 7344 7345 7346 7347 7348 7349 7350 7351 7352 7353 7354 7355 7356 7357 7358 7359 7360 7361 7362 7363 7364 7365 7366 7367 7368 7369 7370 7371 7372 7373 7374 7375 7376 7377 7378 7379 7380 7381 7382 7383 7384 7385 7386 7387 7388 7389 7390 7391 7392 7393 7394 7395 7396 7397 7398 7399 7400 7401 7402 7403 7404 7405 7406 7407 7408 7409 7410 7411 7412 7413 7414 7415 7416 7417 7418 7419 7420 7421 7422 7423 7424 7425 7426 7427 7428 7429 7430 7431 7432 7433 7434 7435 7436 7437 7438 7439 7440 7441 7442 7443 7444 7445 7446 7447 7448 7449 7450 7451 7452 7453 7454 7455 7456 7457 7458 7459 7460 7461 7462 7463 7464 7465 7466 7467 7468 7469 7470 7471 7472 7473 7474 7475 7476 7477 7478 7479 7480 7481 7482 7483 7484 7485 7486 7487 7488 7489 7490 7491 7492 7493 7494 7495 7496 7497 7498 7499 7500 7501 7502 7503 7504 7505 7506 7507 7508 7509 7510 7511 7512 7513 7514 7515 7516 7517 7518 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 7534 7535 7536 7537 7538 7539 7540 7541 7542 7543 7544 7545 7546 7547 7548 7549 7550 7551 7552 7553 7554 7555 7556 7557 7558 7559 7560 7561 7562 7563 7564 7565 7566 7567 7568 7569 7570 7571 7572 7573 7574 7575 7576 7577 7578 7579 7580 7581 7582 7583 7584 7585 7586 7587 7588 7589 7590 7591 7592 7593 7594 7595 7596 7597 7598 7599 7600 7601 7602 7603 7604 7605 7606 7607 7608 7609 7610 7611 7612 7613 7614 7615 7616 7617 7618 7619 7620 7621 7622 7623 7624 7625 7626 7627 7628 7629 7630 7631 7632 7633 7634 7635 7636 7637 7638 7639 7640 7641 7642 7643 7644 7645 7646 7647 7648 7649 7650 7651 7652 7653 7654 7655 7656 7657 7658 7659 7660 7661 7662 7663 7664 7665 7666 7667 7668 7669 7670 7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752 7753 7754 7755 7756 7757 7758 7759 7760 7761 7762 7763 7764 7765 7766 7767 7768 7769 7770 7771 7772 7773 7774 7775 7776 7777 7778 7779 7780 7781 7782 7783 7784 7785 7786 7787 7788 7789 7790 7791 7792 7793 7794 7795 7796 7797 7798 7799 7800 7801 7802 7803 7804 7805 7806 7807 7808 7809 7810 7811 7812 7813 7814 7815 7816 7817 7818 7819 7820 7821 7822 7823 7824 7825 7826 7827 7828 7829 7830 7831 7832 7833 7834 7835 7836 7837 7838 7839 7840 7841 7842 7843 7844 7845 7846 7847 7848 7849 7850 7851 7852 7853 7854 7855 7856 7857 7858 7859 7860 7861 7862 7863 7864 7865 7866 7867 7868 7869 7870 7871 7872 7873 7874 7875 7876 7877 7878 7879 7880 7881 7882 7883 7884 7885 7886 7887 7888 7889 7890 7891 7892 7893 7894 7895 7896 7897 7898 7899 7900 7901 7902 7903 7904 7905 7906 7907 7908 7909 7910 7911 7912 7913 7914 7915 7916 7917 7918 7919 7920 7921 7922 7923 7924 7925 7926 7927 7928 7929 7930 7931 7932 7933 7934 7935 7936 7937 7938 7939 7940 7941 7942 7943 7944 7945 7946 7947 7948 7949 7950 7951 7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 7966 7967 7968 7969 7970 7971 7972 7973 7974 7975 7976 7977 7978 7979 7980 7981 7982 7983 7984 7985 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221 8222 8223 8224 8225 8226 8227 8228 8229 8230 8231 8232 8233 8234 8235 8236 8237 8238 8239 8240 8241 8242 8243 8244 8245 8246 8247 8248 8249 8250 8251 8252 8253 8254 8255 8256 8257 8258 8259 8260 8261 8262 8263 8264 8265 8266 8267 8268 8269 8270 8271 8272 8273 8274 8275 8276 8277 8278 8279 8280 8281 8282 8283 8284 8285 8286 8287 8288 8289 8290 8291 8292 8293 8294 8295 8296 8297 8298 8299 8300 8301 8302 8303 8304 8305 8306 8307 8308 8309 8310 8311 8312 8313 8314 8315 8316 8317 8318 8319 8320 8321 8322 8323 8324 8325 8326 8327 8328 8329 8330 8331 8332 8333 8334 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 8355 8356 8357 8358 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 8372 8373 8374 8375 8376 8377 8378 8379 8380 8381 8382 8383 8384 8385 8386 8387 8388 8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400 8401 8402 8403 8404 8405 8406 8407 8408 8409 8410 8411 8412 8413 8414 8415 8416 8417 8418 8419 8420 8421 8422 8423 8424 8425 8426 8427 8428 8429 8430 8431 8432 8433 8434 8435 8436 8437 8438 8439 8440 8441 8442 8443 8444 8445 8446 8447 8448 8449 8450 8451 8452 8453 8454 8455 8456 8457 8458 8459 8460 8461 8462 8463 8464 8465 8466 8467 8468 8469 8470 8471 8472 8473 8474 8475 8476 8477 8478 8479 8480 8481 8482 8483 8484 8485 8486 8487 8488 8489 8490 8491 8492 8493 8494 8495 8496 8497 8498 8499 8500 8501 8502 8503 8504 8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 8532 8533 8534 8535 8536 8537 8538 8539 8540 8541 8542 8543 8544 8545 8546 8547 8548 8549 8550 8551 8552 8553 8554 8555 8556 8557 8558 8559 8560 8561 8562 8563 8564 8565 8566 8567 8568 8569 8570 8571 8572 8573 8574 8575 8576 8577 8578 8579 8580 8581 8582 8583 8584 8585 8586 8587 8588 8589 8590 8591 8592 8593 8594 8595 8596 8597 8598 8599 8600 8601 8602 8603 8604 8605 8606 8607 8608 8609 8610 8611 8612 8613 8614 8615 8616 8617 8618 8619 8620 8621 8622 8623 8624 8625 8626 8627 8628 8629 8630 8631 8632 8633 8634 8635 8636 8637 8638 8639 8640 8641 8642 8643 8644 8645 8646 8647 8648 8649 8650 8651 8652 8653 8654 8655 8656 8657 8658 8659 8660 8661 8662 8663 8664 8665 8666 8667 8668 8669 8670 8671 8672 8673 8674 8675 8676 8677 8678 8679 8680 8681 8682 8683 8684 8685 8686 8687 8688 8689 8690 8691 8692 8693 8694 8695 8696 8697 8698 8699 8700 8701 8702 8703 8704 8705 8706 8707 8708 8709 8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 8722 8723 8724 8725 8726 8727 8728 8729 8730 8731 8732 8733 8734 8735 8736 8737 8738 8739 8740 8741 8742 8743 8744 8745 8746 8747 8748 8749 8750 8751 8752 8753 8754 8755 8756 8757 8758 8759 8760 8761 8762 8763 8764 8765 8766 8767 8768 8769 8770 8771 8772 8773 8774 8775 8776 8777 8778 8779 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 8793 8794 8795 8796 8797 8798 8799 8800 8801 8802 8803 8804 8805 8806 8807 8808 8809 8810 8811 8812 8813 8814 8815 8816 8817 8818 8819 8820 8821 8822 8823 8824 8825 8826 8827 8828 8829 8830 8831 8832 8833 8834 8835 8836 8837 8838 8839 8840 8841 8842 8843 8844 8845 8846 8847 8848 8849 8850 8851 8852 8853 8854 8855 8856 8857 8858 8859 8860 8861 8862 8863 8864 8865 8866 8867 8868 8869 8870 8871 8872 8873 8874 8875 8876 8877 8878 8879 8880 8881 8882 8883 8884 8885 8886 8887 8888 8889 8890 8891 8892 8893 8894 8895 8896 8897 8898 8899 8900 8901 8902 8903 8904 8905 8906 8907 8908 8909 8910 8911 8912 8913 8914 8915 8916 8917 8918 8919 8920 8921 8922 8923 8924 8925 8926 8927 8928 8929 8930 8931 8932 8933 8934 8935 8936 8937 8938 8939 8940 8941 8942 8943 8944 8945 8946 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 8970 8971 8972 8973 8974 8975 8976 8977 8978 8979 8980 8981 8982 8983 8984 8985 8986 8987 8988 8989 8990 8991 8992 8993 8994 8995 8996 8997 8998 8999 9000 9001 9002 9003 9004 9005 9006 9007 9008 9009 9010 9011 9012 9013 9014 9015 9016 9017 9018 9019 9020 9021 9022 9023 9024 9025 9026 9027 9028 9029 9030 9031 9032 9033 9034 9035 9036 9037 9038 9039 9040 9041 9042 9043 9044 9045 9046 9047 9048 9049 9050 9051 9052 9053 9054 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065 9066 9067 9068 9069 9070 9071 9072 9073 9074 9075 9076 9077 9078 9079 9080 9081 9082 9083 9084 9085 9086 9087 9088 9089 9090 9091 9092 9093 9094 9095 9096 9097 9098 9099 9100 9101 9102 9103 9104 9105 9106 9107 9108 9109 9110 9111 9112 9113 9114 9115 9116 9117 9118 9119 9120 9121 9122 9123 9124 9125 9126 9127 9128 9129 9130 9131 9132 9133 9134 9135 9136 9137 9138 9139 9140 9141 9142 9143 9144 9145 9146 9147 9148 9149 9150 9151 9152 9153 9154 9155 9156 9157 9158 9159 9160 9161 9162 9163 9164 9165 9166 9167 9168 9169 9170 9171 9172 9173 9174 9175 9176 9177 9178 9179 9180 9181 9182 9183 9184 9185 9186 9187 9188 9189 9190 9191 9192 9193 9194 9195 9196 9197 9198 9199 9200 9201 9202 9203 9204 9205 9206 9207 9208 9209 9210 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221 9222 9223 9224 9225 9226 9227 9228 9229 9230 9231 9232 9233 9234 9235 9236 9237 9238 9239 9240 9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254 9255 9256 9257 9258 9259 9260 9261 9262 9263 9264 9265 9266 9267 9268 9269 9270 9271 9272 9273 9274 9275 9276 9277 9278 9279 9280 9281 9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 9294 9295 9296 9297 9298 9299 9300 9301 9302 9303 9304 9305 9306 9307 9308 9309 9310 9311 9312 9313 9314 9315 9316 9317 9318 9319 9320 9321 9322 9323 9324 9325 9326 9327 9328 9329 9330 9331 9332 9333 9334 9335 9336 9337 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 9358 9359 9360 9361 9362 9363 9364 9365 9366 9367 9368 9369 9370 9371 9372 9373 9374 9375 9376 9377 9378 9379 9380 9381 9382 9383 9384 9385 9386 9387 9388 9389 9390 9391 9392 9393 9394 9395 9396 9397 9398 9399 9400 9401 9402 9403 9404 9405 9406 9407 9408 9409 9410 9411 9412 9413 9414 9415 9416 9417 9418 9419 9420 9421 9422 9423 9424 9425 9426 9427 9428 9429 9430 9431 9432 9433 9434 9435 9436 9437 9438 9439 9440 9441 9442 9443 9444 9445 9446 9447 9448 9449 9450 9451 9452 9453 9454 9455 9456 9457 9458 9459 9460 9461 9462 9463 9464 9465 9466 9467 9468 9469 9470 9471 9472 9473 9474 9475 9476 9477 9478 9479 9480 9481 9482 9483 9484 9485 9486 9487 9488 9489 9490 9491 9492 9493 9494 9495 9496 9497 9498 9499 9500 9501 9502 9503 9504 9505 9506 9507 9508 9509 9510 9511 9512 9513 9514 9515 9516 9517 9518 9519 9520 9521 9522 9523 9524 9525 9526 9527 9528 9529 9530 9531 9532 9533 9534 9535 9536 9537 9538 9539 9540 9541 9542 9543 9544 9545 9546 9547 9548 9549 9550 9551 9552 9553 9554 9555 9556 9557 9558 9559 9560 9561 9562 9563 9564 9565 9566 9567 9568 9569 9570 9571 9572 9573 9574 9575 9576 9577 9578 9579 9580 9581 9582 9583 9584 9585 9586 9587 9588 9589 9590 9591 9592 9593 9594 9595 9596 9597 9598 9599 9600 9601 9602 9603 9604 9605 9606 9607 9608 9609 9610 9611 9612 9613 9614 9615 9616 9617 9618 9619 9620 9621 9622 9623 9624 9625 9626 9627 9628 9629 9630 9631 9632 9633 9634 9635 9636 9637 9638 9639 9640 9641 9642 9643 9644 9645 9646 9647 9648 9649 9650 9651 9652 9653 9654 9655 9656 9657 9658 9659 9660 9661 9662 9663 9664 9665 9666 9667 9668 9669 9670 9671 9672 9673 9674 9675 9676 9677 9678 9679 9680 9681 9682 9683 9684 9685 9686 9687 9688 9689 9690 9691 9692 9693 9694 9695 9696 9697 9698 9699 9700 9701 9702 9703 9704 9705 9706 9707 9708 9709 9710 9711 9712 9713 9714 9715 9716 9717 9718 9719 9720 9721 9722 9723 9724 9725 9726 9727 9728 9729 9730 9731 9732 9733 9734 9735 9736 9737 9738 9739 9740 9741 9742 9743 9744 9745 9746 9747 9748 9749 9750 9751 9752 9753 9754 9755 9756 9757 9758 9759 9760 9761 9762 9763 9764 9765 9766 9767 9768 9769 9770 9771 9772 9773 9774 9775 9776 9777 9778 9779 9780 9781 9782 9783 9784 9785 9786 9787 9788 9789 9790 9791 9792 9793 9794 9795 9796 9797 9798 9799 9800 9801 9802 9803 9804 9805 9806 9807 9808 9809 9810 9811 9812 9813 9814 9815 9816 9817 9818 9819 9820 9821 9822 9823 9824 9825 9826 9827 9828 9829 9830 9831 9832 9833 9834 9835 9836 9837 9838 9839 9840 9841 9842 9843 9844 9845 9846 9847 9848 9849 9850 9851 9852 9853 9854 9855 9856 9857 9858 9859 9860 9861 9862 9863 9864 9865 9866 9867 9868 9869 9870 9871 9872 9873 9874 9875 9876 9877 9878 9879 9880 9881 9882 9883 9884 9885 9886 9887 9888 9889 9890 9891 9892 9893 9894 9895 9896 9897 9898 9899 9900 9901 9902 9903 9904 9905 9906 9907 9908 9909 9910 9911 9912 9913 9914 9915 9916 9917 9918 9919 9920 9921 9922 9923 9924 9925 9926 9927 9928 9929 9930 9931 9932 9933 9934 9935 9936 9937 9938 9939 9940 9941 9942 9943 9944 9945 9946 9947 9948 9949 9950 9951 9952 9953 9954 9955 9956 9957 9958 9959 9960 9961 9962 9963 9964 9965 9966 9967 9968 9969 9970 9971 9972 9973 9974 9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990 9991 9992 9993 9994 9995 9996 9997 9998 9999 10000 10001 10002 10003 10004 10005 10006 10007 10008 10009 10010 10011 10012 10013 10014 10015 10016 10017 10018 10019 10020 10021 10022 10023 10024 10025 10026 10027 10028 10029 10030 10031 10032 10033 10034 10035 10036 10037 10038 10039 10040 10041 10042 10043 10044 10045 10046 10047 10048 10049 10050 10051 10052 10053 10054 10055 10056 10057 10058 10059 10060 10061 10062 10063 10064 10065 10066 10067 10068 10069 10070 10071 10072 10073 10074 10075 10076 10077 10078 10079 10080 10081 10082 10083 10084 10085 10086 10087 10088 10089 10090 10091 10092 10093 10094 10095 10096 10097 10098 10099 10100 10101 10102 10103 10104 10105 10106 10107 10108 10109 10110 10111 10112 10113 10114 10115 10116 10117 10118 10119 10120 10121 10122 10123 10124 10125 10126 10127 10128 10129 10130 10131 10132 10133 10134 10135 10136 10137 10138 10139 10140 10141 10142 10143 10144 10145 10146 10147 10148 10149 10150 10151 10152 10153 10154 10155 10156 10157 10158 10159 10160 10161 10162 10163 10164 10165 10166 10167 10168 10169 10170 10171 10172 10173 10174 10175 10176 10177 10178 10179 10180 10181 10182 10183 10184 10185 10186 10187 10188 10189 10190 10191 10192 10193 10194 10195 10196 10197 10198 10199 10200 10201 10202 10203 10204 10205 10206 10207 10208 10209 10210 10211 10212 10213 10214 10215 10216 10217 10218 10219 10220 10221 10222 10223 10224 10225 10226 10227 10228 10229 10230 10231 10232 10233 10234 10235 10236 10237 10238 10239 10240 10241 10242 10243 10244 10245 10246 10247 10248 10249 10250 10251 10252 10253 10254 10255 10256 10257 10258 10259 10260 10261 10262 10263 10264 10265 10266 10267 10268 10269 10270 10271 10272 10273 10274 10275 10276 10277 10278 10279 10280 10281 10282 10283 10284 10285 10286 10287 10288 10289 10290 10291 10292 10293 10294 10295 10296 10297 10298 10299 10300 10301 10302 10303 10304 10305 10306 10307 10308 10309 10310 10311 10312 10313 10314 10315 10316 10317 10318 10319 10320 10321 10322 10323 10324 10325 10326 10327 10328 10329 10330 10331 10332 10333 10334 10335 10336 10337 10338 10339 10340 10341 10342 10343 10344 10345 10346 10347 10348 10349 10350 10351 10352 10353 10354 10355 10356 10357 10358 10359 10360 10361 10362 10363 10364 10365 10366 10367 10368 10369 10370 10371 10372 10373 10374 10375 10376 10377 10378 10379 10380 10381 10382 10383 10384 10385 10386 10387 10388 10389 10390 10391 10392 10393 10394 10395 10396 10397 10398 10399 10400 10401 10402 10403 10404 10405 10406 10407 10408 10409 10410 10411 10412 10413 10414 10415 10416 10417 10418 10419 10420 10421 10422 10423 10424 10425 10426 10427 10428 10429 10430 10431 10432 10433 10434 10435 10436 10437 10438 10439 10440 10441 10442 10443 10444 10445 10446 10447 10448 10449 10450 10451 10452 10453 10454 10455 10456 10457 10458 10459 10460 10461 10462 10463 10464 10465 10466 10467 10468 10469 10470 10471 10472 10473 10474 10475 10476 10477 10478 10479 10480 10481 10482 10483 10484 10485 10486 10487 10488 10489 10490 10491 10492 10493 10494 10495 10496 10497 10498 10499 10500 10501 10502 10503 10504 10505 10506 10507 10508 10509 10510 10511 10512 10513 10514 10515 10516 10517 10518 10519 10520 10521 10522 10523 10524 10525 10526 10527 10528 10529 10530 10531 10532 10533 10534 10535 10536 10537 10538 10539 10540 10541 10542 10543 10544 10545 10546 10547 10548 10549 10550 10551 10552 10553 10554 10555 10556 10557 10558 10559 10560 10561 10562 10563 10564 10565 10566 10567 10568 10569 10570 10571 10572 10573 10574 10575 10576 10577 10578 10579 10580 10581 10582 10583 10584 10585 10586 10587 10588 10589 10590 10591 10592 10593 10594 10595 10596 10597 10598 10599 10600 10601 10602 10603 10604 10605 10606 10607 10608 10609 10610 10611 10612 10613 10614 10615 10616 10617 10618 10619 10620 10621 10622 10623 10624 10625 10626 10627 10628 10629 10630 10631 10632 10633 10634 10635 10636 10637 10638 10639 10640 10641 10642 10643 10644 10645 10646 10647 10648 10649 10650 10651 10652 10653 10654 10655 10656 10657 10658 10659 10660 10661 10662 10663 10664 10665 10666 10667 10668 10669 10670 10671 10672 10673 10674 10675 10676 10677 10678 10679 10680 10681 10682 10683 10684 10685 10686 10687 10688 10689 10690 10691 10692 10693 10694 10695 10696 10697 10698 10699 10700 10701 10702 10703 10704 10705 10706 10707 10708 10709 10710 10711 10712 10713 10714 10715 10716 10717 10718 10719 10720 10721 10722 10723 10724 10725 10726 10727 10728 10729 10730 10731 10732 10733 10734 10735 10736 10737 10738 10739 10740 10741 10742 10743 10744 10745 10746 10747 10748 10749 10750 10751 10752 10753 10754 10755 10756 10757 10758 10759 10760 10761 10762 10763 10764 10765 10766 10767 10768 10769 10770 10771 10772 10773 10774 10775 10776 10777 10778 10779 10780 10781 10782 10783 10784 10785 10786 10787 10788 10789 10790 10791 10792 10793 10794 10795 10796 10797 10798 10799 10800 10801 10802 10803 10804 10805 10806 10807 10808 10809 10810 10811 10812 10813 10814 10815 10816 10817 10818 10819 10820 10821 10822 10823 10824 10825 10826 10827 10828 10829 10830 10831 10832 10833 10834 10835 10836 10837 10838 10839 10840 10841 10842 10843 10844 10845 10846 10847 10848 10849 10850 10851 10852 10853 10854 10855 10856 10857 10858 10859 10860 10861 10862 10863 10864 10865 10866 10867 10868 10869 10870 10871 10872 10873 10874 10875 10876 10877 10878 10879 10880 10881 10882 10883 10884 10885 10886 10887 10888 10889 10890 10891 10892 10893 10894 10895 10896 10897 10898 10899 10900 10901 10902 10903 10904 10905 10906 10907 10908 10909 10910 10911 10912 10913 10914 10915 10916 10917 10918 10919 10920 10921 10922 10923 10924 10925 10926 10927 10928 10929 10930 10931 10932 10933 10934 10935 10936 10937 10938 10939 10940 10941 10942 10943 10944 10945 10946 10947 10948 10949 10950 10951 10952 10953 10954 10955 10956 10957 10958 10959 10960 10961 10962 10963 10964 10965 10966 10967 10968 10969 10970 10971 10972 10973 10974 10975 10976 10977 10978 10979 10980 10981 10982 10983 10984 10985 10986 10987 10988 10989 10990 10991 10992 10993 10994 10995 10996 10997 10998 10999 11000 11001 11002 11003 11004 11005 11006 11007 11008 11009 11010 11011 11012 11013 11014 11015 11016 11017 11018 11019 11020 11021 11022 11023 11024 11025 11026 11027 11028 11029 11030 11031 11032 11033 11034 11035 11036 11037 11038 11039 11040 11041 11042 11043 11044 11045 11046 11047 11048 11049 11050 11051 11052 11053 11054 11055 11056 11057 11058 11059 11060 11061 11062 11063 11064 11065 11066 11067 11068 11069 11070 11071 11072 11073 11074 11075 11076 11077 11078 11079 11080 11081 11082 11083 11084 11085 11086 11087 11088 11089 11090 11091 11092 11093 11094 11095 11096 11097 11098 11099 11100 11101 11102 11103 11104 11105 11106 11107 11108 11109 11110 11111 11112 11113 11114 11115 11116 11117 11118 11119 11120 11121 11122 11123 11124 11125 11126 11127 11128 11129 11130 11131 11132 11133 11134 11135 11136 11137 11138 11139 11140 11141 11142 11143 11144 11145 11146 11147 11148 11149 11150 11151 11152 11153 11154 11155 11156 11157 11158 11159 11160 11161 11162 11163 11164 11165 11166 11167 11168 11169 11170 11171 11172 11173 11174 11175 11176 11177 11178 11179 11180 11181 11182 11183 11184 11185 11186 11187 11188 11189 11190 11191 11192 11193 11194 11195 11196 11197 11198 11199 11200 11201 11202 11203 11204 11205 11206 11207 11208 11209 11210 11211 11212 11213 11214 11215 11216 11217 11218 11219 11220 11221 11222 11223 11224 11225 11226 11227 11228 11229 11230 11231 11232 11233 11234 11235 11236 11237 11238 11239 11240 11241 11242 11243 11244 11245 11246 11247 11248 11249 11250 11251 11252 11253 11254 11255 11256 11257 11258 11259 11260 11261 11262 11263 11264 11265 11266 11267 11268 11269 11270 11271 11272 11273 11274 11275 11276 11277 11278 11279 11280 11281 11282 11283 11284 11285 11286 11287 11288 11289 11290 11291 11292 11293 11294 11295 11296 11297 11298 11299 11300 11301 11302 11303 11304 11305 11306 11307 11308 11309 11310 11311 11312 11313 11314 11315 11316 11317 11318 11319 11320 11321 11322 11323 11324 11325 11326 11327 11328 11329 11330 11331 11332 11333 11334 11335 11336 11337 11338 11339 11340 11341 11342 11343 11344 11345 11346 11347 11348 11349 11350 11351 11352 11353 11354 11355 11356 11357 11358 11359 11360 11361 11362 11363 11364 11365 11366 11367 11368 11369 11370 11371 11372 11373 11374 11375 11376 11377 11378 11379 11380 11381 11382 11383 11384 11385 11386 11387 11388 11389 11390 11391 11392 11393 11394 11395 11396 11397 11398 11399 11400 11401 11402 11403 11404 11405 11406 11407 11408 11409 11410 11411 11412 11413 11414 11415 11416 11417 11418 11419 11420 11421 11422 11423 11424 11425 11426 11427 11428 11429 11430 11431 11432 11433 11434 11435 11436 11437 11438 11439 11440 11441 11442 11443 11444 11445 11446 11447 11448 11449 11450 11451 11452 11453 11454 11455 11456 11457 11458 11459 11460 11461 11462 11463 11464 11465 11466 11467 11468 11469 11470 11471 11472 11473 11474 11475 11476 11477 11478 11479 11480 11481 11482 11483 11484 11485 11486 11487 11488 11489 11490 11491 11492 11493 11494 11495 11496 11497 11498 11499 11500 11501 11502 11503 11504 11505 11506 11507 11508 11509 11510 11511 11512 11513 11514 11515 11516 11517 11518 11519 11520 11521 11522 11523 11524 11525 11526 11527 11528 11529 11530 11531 11532 11533 11534 11535 11536 11537 11538 11539 11540 11541 11542 11543 11544 11545 11546 11547 11548 11549 11550 11551 11552 11553 11554 11555 11556 11557 11558 11559 11560 11561 11562 11563 11564 11565 11566 11567 11568 11569 11570 11571 11572 11573 11574 11575 11576 11577 11578 11579 11580 11581 11582 11583 11584 11585 11586 11587 11588 11589 11590 11591 11592 11593 11594 11595 11596 11597 11598 11599 11600 11601 11602 11603 11604 11605 11606 11607 11608 11609 11610 11611 11612 11613 11614 11615 11616 11617 11618 11619 11620 11621 11622 11623 11624 11625 11626 11627 11628 11629 11630 11631 11632 11633 11634 11635 11636 11637 11638 11639 11640 11641 11642 11643 11644 11645 11646 11647 11648 11649 11650 11651 11652 11653 11654 11655 11656 11657 11658 11659 11660 11661 11662 11663 11664 11665 11666 11667 11668 11669 11670 11671 11672 11673 11674 11675 11676 11677 11678 11679 11680 11681 11682 11683 11684 11685 11686 11687 11688 11689 11690 11691 11692 11693 11694 11695 11696 11697 11698 11699 11700 11701 11702 11703 11704 11705 11706 11707 11708 11709 11710 11711 11712 11713 11714 11715 11716 11717 11718 11719 11720 11721 11722 11723 11724 11725 11726 11727 11728 11729 11730 11731 11732 11733 11734 11735 11736 11737 11738 11739 11740 11741 11742 11743 11744 11745 11746 11747 11748 11749 11750 11751 11752 11753 11754 11755 11756 11757 11758 11759 11760 11761 11762 11763 11764 11765 11766 11767 11768 11769 11770 11771 11772 11773 11774 11775 11776 11777 11778 11779 11780 11781 11782 11783 11784 11785 11786 11787 11788 11789 11790 11791 11792 11793 11794 11795 11796 11797 11798 11799 11800 11801 11802 11803 11804 11805 11806 11807 11808 11809 11810 11811 11812 11813 11814 11815 11816 11817 11818 11819 11820 11821 11822 11823 11824 11825 11826 11827 11828 11829 11830 11831 11832 11833 11834 11835 11836 11837 11838 11839 11840 11841 11842 11843 11844 11845 11846 11847 11848 11849 11850 11851 11852 11853 11854 11855 11856 11857 11858 11859 11860 11861 11862 11863 11864 11865 11866 11867 11868 11869 11870 11871 11872 11873 11874 11875 11876 11877 11878 11879 11880 11881 11882 11883 11884 11885 11886 11887 11888 11889 11890 11891 11892 11893 11894 11895 11896 11897 11898 11899 11900 11901 11902 11903 11904 11905 11906 11907 11908 11909 11910 11911 11912 11913 11914 11915 11916 11917 11918 11919 11920 11921 11922 11923 11924 11925 11926 11927 11928 11929 11930 11931 11932 11933 11934 11935 11936 11937 11938 11939 11940 11941 11942 11943 11944 11945 11946 11947 11948 11949 11950 11951 11952 11953 11954 11955 11956 11957 11958 11959 11960 11961 11962 11963 11964 11965 11966 11967 11968 11969 11970 11971 11972 11973 11974 11975 11976 11977 11978 11979 11980 11981 11982 11983 11984 11985 11986 11987 11988 11989 11990 11991 11992 11993 11994 11995 11996 11997 11998 11999 12000 12001 12002 12003 12004 12005 12006 12007 12008 12009 12010 12011 12012 12013 12014 12015 12016 12017 12018 12019 12020 12021 12022 12023 12024 12025 12026 12027 12028 12029 12030 12031 12032 12033 12034 12035 12036 12037 12038 12039 12040 12041 12042 12043 12044 12045 12046 12047 12048 12049 12050 12051 12052 12053 12054 12055 12056 12057 12058 12059 12060 12061 12062 12063 12064 12065 12066 12067 12068 12069 12070 12071 12072 12073 12074 12075 12076 12077 12078 12079 12080 12081 12082 12083 12084 12085 12086 12087 12088 12089 12090 12091 12092 12093 12094 12095 12096 12097 12098 12099 12100 12101 12102 12103 12104 12105 12106 12107 12108 12109 12110 12111 12112 12113 12114 12115 12116 12117 12118 12119 12120 12121 12122 12123 12124 12125 12126 12127 12128 12129 12130 12131 12132 12133 12134 12135 12136 12137 12138 12139 12140 12141 12142 12143 12144 12145 12146 12147 12148 12149 12150 12151 12152 12153 12154 12155 12156 12157 12158 12159 12160 12161 12162 12163 12164 12165 12166 12167 12168 12169 12170 12171 12172 12173 12174 12175 12176 12177 12178 12179 12180 12181 12182 12183 12184 12185 12186 12187 12188 12189 12190 12191 12192 12193 12194 12195 12196 12197 12198 12199 12200 12201 12202 12203 12204 12205 12206 12207 12208 12209 12210 12211 12212 12213 12214 12215 12216 12217 12218 12219 12220 12221 12222 12223 12224 12225 12226 12227 12228 12229 12230 12231 12232 12233 12234 12235 12236 12237 12238 12239 12240 12241 12242 12243 12244 12245 12246 12247 12248 12249 12250 12251 12252 12253 12254 12255 12256 12257 12258 12259 12260 12261 12262 12263 12264 12265 12266 12267 12268 12269 12270 12271 12272 12273 12274 12275 12276 12277 12278 12279 12280 12281 12282 12283 12284 12285 12286 12287 12288 12289 12290 12291 12292 12293 12294 12295 12296 12297 12298 12299 12300 12301 12302 12303 12304 12305 12306 12307 12308 12309 12310 12311 12312 12313 12314 12315 12316 12317 12318 12319 12320 12321 12322 12323 12324 12325 12326 12327 12328 12329 12330 12331 12332 12333 12334 12335 12336 12337 12338 12339 12340 12341 12342 12343 12344 12345 12346 12347 12348 12349 12350 12351 12352 12353 12354 12355 12356 12357 12358 12359 12360 12361 12362 12363 12364 12365 12366 12367 12368 12369 12370 12371 12372 12373 12374 12375 12376 12377 12378 12379 12380 12381 12382 12383 12384 12385 12386 12387 12388 12389 12390 12391 12392 12393 12394 12395 12396 12397 12398 12399 12400 12401 12402 12403 12404 12405 12406 12407 12408 12409 12410 12411 12412 12413 12414 12415 12416 12417 12418 12419 12420 12421 12422 12423 12424 12425 12426 12427 12428 12429 12430 12431 12432 12433 12434 12435 12436 12437 12438 12439 12440 12441 12442 12443 12444 12445 12446 12447 12448 12449 12450 12451 12452 12453 12454 12455 12456 12457 12458 12459 12460 12461 12462 12463 12464 12465 12466 12467 12468 12469 12470 12471 12472 12473 12474 12475 12476 12477 12478 12479 12480 12481 12482 12483 12484 12485 12486 12487 12488 12489 12490 12491 12492 12493 12494 12495 12496 12497 12498 12499 12500 12501 12502 12503 12504 12505 12506 12507 12508 12509 12510 12511 12512 12513 12514 12515 12516 12517 12518 12519 12520 12521 12522 12523 12524 12525 12526 12527 12528 12529 12530 12531 12532 12533 12534 12535 12536 12537 12538 12539 12540 12541 12542 12543 12544 12545 12546 12547 12548 12549 12550 12551 12552 12553 12554 12555 12556 12557 12558 12559 12560 12561 12562 12563 12564 12565 12566 12567 12568 12569 12570 12571 12572 12573 12574 12575 12576 12577 12578 12579 12580 12581 12582 12583 12584 12585 12586 12587 12588 12589 12590 12591 12592 12593 12594 12595 12596 12597 12598 12599 12600 12601 12602 12603 12604 12605 12606 12607 12608 12609 12610 12611 12612 12613 12614 12615 12616 12617 12618 12619 12620 12621 12622 12623 12624 12625 12626 12627 12628 12629 12630 12631 12632 12633 12634 12635 12636 12637 12638 12639 12640 12641 12642 12643 12644 12645 12646 12647 12648 12649 12650 12651 12652 12653 12654 12655 12656 12657 12658 12659 12660 12661 12662 12663 12664 12665 12666 12667 12668 12669 12670 12671 12672 12673 12674 12675 12676 12677 12678 12679 12680 12681 12682 12683 12684 12685 12686 12687 12688 12689 12690 12691 12692 12693 12694 12695 12696 12697 12698 12699 12700 12701 12702 12703 12704 12705 12706 12707 12708 12709 12710 12711 12712 12713 12714 12715 12716 12717 12718 12719 12720 12721 12722 12723 12724 12725 12726 12727 12728 12729 12730 12731 12732 12733 12734 12735 12736 12737 12738 12739 12740 12741 12742 12743 12744 12745 12746 12747 12748 12749 12750 12751 12752 12753 12754 12755 12756 12757 12758 12759 12760 12761 12762 12763 12764 12765 12766 12767 12768 12769 12770 12771 12772 12773 12774 12775 12776 12777 12778 12779 12780 12781 12782 12783 12784 12785 12786 12787 12788 12789 12790 12791 12792 12793 12794 12795 12796 12797 12798 12799 12800 12801 12802 12803 12804 12805 12806 12807 12808 12809 12810 12811 12812 12813 12814 12815 12816 12817 12818 12819 12820 12821 12822 12823 12824 12825 12826 12827 12828 12829 12830 12831 12832 12833 12834 12835 12836 12837 12838 12839 12840 12841 12842 12843 12844 12845 12846 12847 12848 12849 12850 12851 12852 12853 12854 12855 12856 12857 12858 12859 12860 12861 12862 12863 12864 12865 12866 12867 12868 12869 12870 12871 12872 12873 12874 12875 12876 12877 12878 12879 12880 12881 12882 12883 12884 12885 12886 12887 12888 12889 12890 12891 12892 12893 12894 12895 12896 12897 12898 12899 12900 12901 12902 12903 12904 12905 12906 12907 12908 12909 12910 12911 12912 12913 12914 12915 12916 12917 12918 12919 12920 12921 12922 12923 12924 12925 12926 12927 12928 12929 12930 12931 12932 12933 12934 12935 12936 12937 12938 12939 12940 12941 12942 12943 12944 12945 12946 12947 12948 12949 12950 12951 12952 12953 12954 12955 12956 12957 12958 12959 12960 12961 12962 12963 12964 12965 12966 12967 12968 12969 12970 12971 12972 12973 12974 12975 12976 12977 12978 12979 12980 12981 12982 12983 12984 12985 12986 12987 12988 12989 12990 12991 12992 12993 12994 12995 12996 12997 12998 12999 13000 13001 13002 13003 13004 13005 13006 13007 13008 13009 13010 13011 13012 13013 13014 13015 13016 13017 13018 13019 13020 13021 13022 13023 13024 13025 13026 13027 13028 13029 13030 13031 13032 13033 13034 13035 13036 13037 13038 13039 13040 13041 13042 13043 13044 13045 13046 13047 13048 13049 13050 13051 13052 13053 13054 13055 13056 13057 13058 13059 13060 13061 13062 13063 13064 13065 13066 13067 13068 13069 13070 13071 13072 13073 13074 13075 13076 13077 13078 13079 13080 13081 13082 13083 13084 13085 13086 13087 13088 13089 13090 13091 13092 13093 13094 13095 13096 13097 13098 13099 13100 13101 13102 13103 13104 13105 13106 13107 13108 13109 13110 13111 13112 13113 13114 13115 13116 13117 13118 13119 13120 13121 13122 13123 13124 13125 13126 13127 13128 13129 13130 13131 13132 13133 13134 13135 13136 13137 13138 13139 13140 13141 13142 13143 13144 13145 13146 13147 13148 13149 13150 13151 13152 13153 13154 13155 13156 13157 13158 13159 13160 13161 13162 13163 13164 13165 13166 13167 13168 13169 13170 13171 13172 13173 13174 13175 13176 13177 13178 13179 13180 13181 13182 13183 13184 13185 13186 13187 13188 13189 13190 13191 13192 13193 13194 13195 13196 13197 13198 13199 13200 13201 13202 13203 13204 13205 13206 13207 13208 13209 13210 13211 13212 13213 13214 13215 13216 13217 13218 13219 13220 13221 13222 13223 13224 13225 13226 13227 13228 13229 13230 13231 13232 13233 13234 13235 13236 13237 13238 13239 13240 13241 13242 13243 13244 13245 13246 13247 13248 13249 13250 13251 13252 13253 13254 13255 13256 13257 13258 13259 13260 13261 13262 13263 13264 13265 13266 13267 13268 13269 13270 13271 13272 13273 13274 13275 13276 13277 13278 13279 13280 13281 13282 13283 13284 13285 13286 13287 13288 13289 13290 13291 13292 13293 13294 13295 13296 13297 13298 13299 13300 13301 13302 13303 13304 13305 13306 13307 13308 13309 13310 13311 13312 13313 13314 13315 13316 13317 13318 13319 13320 13321 13322 13323 13324 13325 13326 13327 13328 13329 13330 13331 13332 13333 13334 13335 13336 13337 13338 13339 13340 13341 13342 13343 13344 13345 13346 13347 13348 13349 13350 13351 13352 13353 13354 13355 13356 13357 13358 13359 13360 13361 13362 13363 13364 13365 13366 13367 13368 13369 13370 13371 13372 13373 13374 13375 13376 13377 13378 13379 13380 13381 13382 13383 13384 13385 13386 13387 13388 13389 13390 13391 13392 13393 13394 13395 13396 13397 13398 13399 13400 13401 13402 13403 13404 13405 13406 13407 13408 13409 13410 13411 13412 13413 13414 13415 13416 13417 13418 13419 13420 13421 13422 13423 13424 13425 13426 13427 13428 13429 13430 13431 13432 13433 13434 13435 13436 13437 13438 13439 13440 13441 13442 13443 13444 13445 13446 13447 13448 13449 13450 13451 13452 13453 13454 13455 13456 13457 13458 13459 13460 13461 13462 13463 13464 13465 13466 13467 13468 13469 13470 13471 13472 13473 13474 13475 13476 13477 13478 13479 13480 13481 13482 13483 13484 13485 13486 13487 13488 13489 13490 13491 13492 13493 13494 13495 13496 13497 13498 13499 13500 13501 13502 13503 13504 13505 13506 13507 13508 13509 13510 13511 13512 13513 13514 13515 13516 13517 13518 13519 13520 13521 13522 13523 13524 13525 13526 13527 13528 13529 13530 13531 13532 13533 13534 13535 13536 13537 13538 13539 13540 13541 13542 13543 13544 13545 13546 13547 13548 13549 13550 13551 13552 13553 13554 13555 13556 13557 13558 13559 13560 13561 13562 13563 13564 13565 13566 13567 13568 13569 13570 13571 13572 13573 13574 13575 13576 13577 13578 13579 13580 13581 13582 13583 13584 13585 13586 13587 13588 13589 13590 13591 13592 13593 13594 13595 13596 13597 13598 13599 13600 13601 13602 13603 13604 13605 13606 13607 13608 13609 13610 13611 13612 13613 13614 13615 13616 13617 13618 13619 13620 13621 13622 13623 13624 13625 13626 13627 13628 13629 13630 13631 13632 13633 13634 13635 13636 13637 13638 13639 13640 13641 13642 13643 13644 13645 13646 13647 13648 13649 13650 13651 13652 13653 13654 13655 13656 13657 13658 13659 13660 13661 13662 13663 13664 13665 13666 13667 13668 13669 13670 13671 13672 13673 13674 13675 13676 13677 13678 13679 13680 13681 13682 13683 13684 13685 13686 13687 13688 13689 13690 13691 13692 13693 13694 13695 13696 13697 13698 13699 13700 13701 13702 13703 13704 13705 13706 13707 13708 13709 13710 13711 13712 13713 13714 13715 13716 13717 13718 13719 13720 13721 13722 13723 13724 13725 13726 13727 13728 13729 13730 13731 13732 13733 13734 13735 13736 13737 13738 13739 13740 13741 13742 13743 13744 13745 13746 13747 13748 13749 13750 13751 13752 13753 13754 13755 13756 13757 13758 13759 13760 13761 13762 13763 13764 13765 13766 13767 13768 13769 13770 13771 13772 13773 13774 13775 13776 13777 13778 13779 13780 13781 13782 13783 13784 13785 13786 13787 13788 13789 13790 13791 13792 13793 13794 13795 13796 13797 13798 13799 13800 13801 13802 13803 13804 13805 13806 13807 13808 13809 13810 13811 13812 13813 13814 13815 13816 13817 13818 13819 13820 13821 13822 13823 13824 13825 13826 13827 13828 13829 13830 13831 13832 13833 13834 13835 13836 13837 13838 13839 13840 13841 13842 13843 13844 13845 13846 13847 13848 13849 13850 13851 13852 13853 13854 13855 13856 13857 13858 13859 13860 13861 13862 13863 13864 13865 13866 13867 13868 13869 13870 13871 13872 13873 13874 13875 13876 13877 13878 13879 13880 13881 13882 13883 13884 13885 13886 13887 13888 13889 13890 13891 13892 13893 13894 13895 13896 13897 13898 13899 13900 13901 13902 13903 13904 13905 13906 13907 13908 13909 13910 13911 13912 13913 13914 13915 13916 13917 13918 13919 13920 13921 13922 13923 13924 13925 13926 13927 13928 13929 13930 13931 13932 13933 13934 13935 13936 13937 13938 13939 13940 13941 13942 13943 13944 13945 13946 13947 13948 13949 13950 13951 13952 13953 13954 13955 13956 13957 13958 13959 13960 13961 13962 13963 13964 13965 13966 13967 13968 13969 13970 13971 13972 13973 13974 13975 13976 13977 13978 13979 13980 13981 13982 13983 13984 13985 13986 13987 13988 13989 13990 13991 13992 13993 13994 13995 13996 13997 13998 13999 14000 14001 14002 14003 14004 14005 14006 14007 14008 14009 14010 14011 14012 14013 14014 14015 14016 14017 14018 14019 14020 14021 14022 14023 14024 14025 14026 14027 14028 14029 14030 14031 14032 14033 14034 14035 14036 14037 14038 14039 14040 14041 14042 14043 14044 14045 14046 14047 14048 14049 14050 14051 14052 14053 14054 14055 14056 14057 14058 14059 14060 14061 14062 14063 14064 14065 14066 14067 14068 14069 14070 14071 14072 14073 14074 14075 14076 14077 14078 14079 14080 14081 14082 14083 14084 14085 14086 14087 14088 14089 14090 14091 14092 14093 14094 14095 14096 14097 14098 14099 14100 14101 14102 14103 14104 14105 14106 14107 14108 14109 14110 14111 14112 14113 14114 14115 14116 14117 14118 14119 14120 14121 14122 14123 14124 14125 14126 14127 14128 14129 14130 14131 14132 14133 14134 14135 14136 14137 14138 14139 14140 14141 14142 14143 14144 14145 14146 14147 14148 14149 14150 14151 14152 14153 14154 14155 14156 14157 14158 14159 14160 14161 14162 14163 14164 14165 14166 14167 14168 14169 14170 14171 14172 14173 14174 14175 14176 14177 14178 14179 14180 14181 14182 14183 14184 14185 14186 14187 14188 14189 14190 14191 14192 14193 14194 14195 14196 14197 14198 14199 14200 14201 14202 14203 14204 14205 14206 14207 14208 14209 14210 14211 14212 14213 14214 14215 14216 14217 14218 14219 14220 14221 14222 14223 14224 14225 14226 14227 14228 14229 14230 14231 14232 14233 14234 14235 14236 14237 14238 14239 14240 14241 14242 14243 14244 14245 14246 14247 14248 14249 14250 14251 14252 14253 14254 14255 14256 14257 14258 14259 14260 14261 14262 14263 14264 14265 14266 14267 14268 14269 14270 14271 14272 14273 14274 14275 14276 14277 14278 14279 14280 14281 14282 14283 14284 14285 14286 14287 14288 14289 14290 14291 14292 14293 14294 14295 14296 14297 14298 14299 14300 14301 14302 14303 14304 14305 14306 14307 14308 14309 14310 14311 14312 14313 14314 14315 14316 14317 14318 14319 14320 14321 14322 14323 14324 14325 14326 14327 14328 14329 14330 14331 14332 14333 14334 14335 14336 14337 14338 14339 14340 14341 14342 14343 14344 14345 14346 14347 14348 14349 14350 14351 14352 14353 14354 14355 14356 14357 14358 14359 14360 14361 14362 14363 14364 14365 14366 14367 14368 14369 14370 14371 14372 14373 14374 14375 14376 14377 14378 14379 14380 14381 14382 14383 14384 14385 14386 14387 14388 14389 14390 14391 14392 14393 14394 14395 14396 14397 14398 14399 14400 14401 14402 14403 14404 14405 14406 14407 14408 14409 14410 14411 14412 14413 14414 14415 14416 14417 14418 14419 14420 14421 14422 14423 14424 14425 14426 14427 14428 14429 14430 14431 14432 14433 14434 14435 14436 14437 14438 14439 14440 14441 14442 14443 14444 14445 14446 14447 14448 14449 14450 14451 14452 14453 14454 14455 14456 14457 14458 14459 14460 14461 14462 14463 14464 14465 14466 14467 14468 14469 14470 14471 14472 14473 14474 14475 14476 14477 14478 14479 14480 14481 14482 14483 14484 14485 14486 14487 14488 14489 14490 14491 14492 14493 14494 14495 14496 14497 14498 14499 14500 14501 14502 14503 14504 14505 14506 14507 14508 14509 14510 14511 14512 14513 14514 14515 14516 14517 14518 14519 14520 14521 14522 14523 14524 14525 14526 14527 14528 14529 14530 14531 14532 14533 14534 14535 14536 14537 14538 14539 14540 14541 14542 14543 14544 14545 14546 14547 14548 14549 14550 14551 14552 14553 14554 14555 14556 14557 14558 14559 14560 14561 14562 14563 14564 14565 14566 14567 14568 14569 14570 14571 14572 14573 14574 14575 14576 14577 14578 14579 14580 14581 14582 14583 14584 14585 14586 14587 14588 14589 14590 14591 14592 14593 14594 14595 14596 14597 14598 14599 14600 14601 14602 14603 14604 14605 14606 14607 14608 14609 14610 14611 14612 14613 14614 14615 14616 14617 14618 14619 14620 14621 14622 14623 14624 14625 14626 14627 14628 14629 14630 14631 14632 14633 14634 14635 14636 14637 14638 14639 14640 14641 14642 14643 14644 14645 14646 14647 14648 14649 14650 14651 14652 14653 14654 14655 14656 14657 14658 14659 14660 14661 14662 14663 14664 14665 14666 14667 14668 14669 14670 14671 14672 14673 14674 14675 14676 14677 14678 14679 14680 14681 14682 14683 14684 14685 14686 14687 14688 14689 14690 14691 14692 14693 14694 14695 14696 14697 14698 14699 14700 14701 14702 14703 14704 14705 14706 14707 14708 14709 14710 14711 14712 14713 14714 14715 14716 14717 14718 14719 14720 14721 14722 14723 14724 14725 14726 14727 14728 14729 14730 14731 14732 14733 14734 14735 14736 14737 14738 14739 14740 14741 14742 14743 14744 14745 14746 14747 14748 14749 14750 14751 14752 14753 14754 14755 14756 14757 14758 14759 14760 14761 14762 14763 14764 14765 14766 14767 14768 14769 14770 14771 14772 14773 14774 14775 14776 14777 14778 14779 14780 14781 14782 14783 14784 14785 14786 14787 14788 14789 14790 14791 14792 14793 14794 14795 14796 14797 14798 14799 14800 14801 14802 14803 14804 14805 14806 14807 14808 14809 14810 14811 14812 14813 14814 14815 14816 14817 14818 14819 14820 14821 14822 14823 14824 14825 14826 14827 14828 14829 14830 14831 14832 14833 14834 14835 14836 14837 14838 14839 14840 14841 14842 14843 14844 14845 14846 14847 14848 14849 14850 14851 14852 14853 14854 14855 14856 14857 14858 14859 14860 14861 14862 14863 14864 14865 14866 14867 14868 14869 14870 14871 14872 14873 14874 14875 14876 14877 14878 14879 14880 14881 14882 14883 14884 14885 14886 14887 14888 14889 14890 14891 14892 14893 14894 14895 14896 14897 14898 14899 14900 14901 14902 14903 14904 14905 14906 14907 14908 14909 14910 14911 14912 14913 14914 14915 14916 14917 14918 14919 14920 14921 14922 14923 14924 14925 14926 14927 14928 14929 14930 14931 14932 14933 14934 14935 14936 14937 14938 14939 14940 14941 14942 14943 14944 14945 14946 14947 14948 14949 14950 14951 14952 14953 14954 14955 14956 14957 14958 14959 14960 14961 14962 14963 14964 14965 14966 14967 14968 14969 14970 14971 14972 14973 14974 14975 14976 14977 14978 14979 14980 14981 14982 14983 14984 14985 14986 14987 14988 14989 14990 14991 14992 14993 14994 14995 14996 14997 14998 14999 15000 15001 15002 15003 15004 15005 15006 15007 15008 15009 15010 15011 15012 15013 15014 15015 15016 15017 15018 15019 15020 15021 15022 15023 15024 15025 15026 15027 15028 15029 15030 15031 15032 15033 15034 15035 15036 15037 15038 15039 15040 15041 15042 15043 15044 15045 15046 15047 15048 15049 15050 15051 15052 15053 15054 15055 15056 15057 15058 15059 15060 15061 15062 15063 15064 15065 15066 15067 15068 15069 15070 15071 15072 15073 15074 15075 15076 15077 15078 15079 15080 15081 15082 15083 15084 15085 15086 15087 15088 15089 15090 15091 15092 15093 15094 15095 15096 15097 15098 15099 15100 15101 15102 15103 15104 15105 15106 15107 15108 15109 15110 15111 15112 15113 15114 15115 15116 15117 15118 15119 15120 15121 15122 15123 15124 15125 15126 15127 15128 15129 15130 15131 15132 15133 15134 15135 15136 15137 15138 15139 15140 15141 15142 15143 15144 15145 15146 15147 15148 15149 15150 15151 15152 15153 15154 15155 15156 15157 15158 15159 15160 15161 15162 15163 15164 15165 15166 15167 15168 15169 15170 15171 15172 15173 15174 15175 15176 15177 15178 15179 15180 15181 15182 15183 15184 15185 15186 15187 15188 15189 15190 15191 15192 15193 15194 15195 15196 15197 15198 15199 15200 15201 15202 15203 15204 15205 15206 15207 15208 15209 15210 15211 15212 15213 15214 15215 15216 15217 15218 15219 15220 15221 15222 15223 15224 15225 15226 15227 15228 15229 15230 15231 15232 15233 15234 15235 15236 15237 15238 15239 15240 15241 15242 15243 15244 15245 15246 15247 15248 15249 15250 15251 15252 15253 15254 15255 15256 15257 15258 15259 15260 15261 15262 15263 15264 15265 15266 15267 15268 15269 15270 15271 15272 15273 15274 15275 15276 15277 15278 15279 15280 15281 15282 15283 15284 15285 15286 15287 15288 15289 15290 15291 15292 15293 15294 15295 15296 15297 15298 15299 15300 15301 15302 15303 15304 15305 15306 15307 15308 15309 15310 15311 15312 15313 15314 15315 15316 15317 15318 15319 15320 15321 15322 15323 15324 15325 15326 15327 15328 15329 15330 15331 15332 15333 15334 15335 15336 15337 15338 15339 15340 15341 15342 15343 15344 15345 15346 15347 15348 15349 15350 15351 15352 15353 15354 15355 15356 15357 15358 15359 15360 15361 15362 15363 15364 15365 15366 15367 15368 15369 15370 15371 15372 15373 15374 15375 15376 15377 15378 15379 15380 15381 15382 15383 15384 15385 15386 15387 15388 15389 15390 15391 15392 15393 15394 15395 15396 15397 15398 15399 15400 15401 15402 15403 15404 15405 15406 15407 15408 15409 15410 15411 15412 15413 15414 15415 15416 15417 15418 15419 15420 15421 15422 15423 15424 15425 15426 15427 15428 15429 15430 15431 15432 15433 15434 15435 15436 15437 15438 15439 15440 15441 15442 15443 15444 15445 15446 15447 15448 15449 15450 15451 15452 15453 15454 15455 15456 15457 15458 15459 15460 15461 15462 15463 15464 15465 15466 15467 15468 15469 15470 15471 15472 15473 15474 15475 15476 15477 15478 15479 15480 15481 15482 15483 15484 15485 15486 15487 15488 15489 15490 15491 15492 15493 15494 15495 15496 15497 15498 15499 15500 15501 15502 15503 15504 15505 15506 15507 15508 15509 15510 15511 15512 15513 15514 15515 15516 15517 15518 15519 15520 15521 15522 15523 15524 15525 15526 15527 15528 15529 15530 15531 15532 15533 15534 15535 15536 15537 15538 15539 15540 15541 15542 15543 15544 15545 15546 15547 15548 15549 15550 15551 15552 15553 15554 15555 15556 15557 15558 15559 15560 15561 15562 15563 15564 15565 15566 15567 15568 15569 15570 15571 15572 15573 15574 15575 15576 15577 15578 15579 15580 15581 15582 15583 15584 15585 15586 15587 15588 15589 15590 15591 15592 15593 15594 15595 15596 15597 15598 15599 15600 15601 15602 15603 15604 15605 15606 15607 15608 15609 15610 15611 15612 15613 15614 15615 15616 15617 15618 15619 15620 15621 15622 15623 15624 15625 15626 15627 15628 15629 15630 15631 15632 15633 15634 15635 15636 15637 15638 15639 15640 15641 15642 15643 15644 15645 15646 15647 15648 15649 15650 15651 15652 15653 15654 15655 15656 15657 15658 15659 15660 15661 15662 15663 15664 15665 15666 15667 15668 15669 15670 15671 15672 15673 15674 15675 15676 15677 15678 15679 15680 15681 15682 15683 15684 15685 15686 15687 15688 15689 15690 15691 15692 15693 15694 15695 15696 15697 15698 15699 15700 15701 15702 15703 15704 15705 15706 15707 15708 15709 15710 15711 15712 15713 15714 15715 15716 15717 15718 15719 15720 15721 15722 15723 15724 15725 15726 15727 15728 15729 15730 15731 15732 15733 15734 15735 15736 15737 15738 15739 15740 15741 15742 15743 15744 15745 15746 15747 15748 15749 15750 15751 15752 15753 15754 15755 15756 15757 15758 15759 15760 15761 15762 15763 15764 15765 15766 15767 15768 15769 15770 15771 15772 15773 15774 15775 15776 15777 15778 15779 15780 15781 15782 15783 15784 15785 15786 15787 15788 15789 15790 15791 15792 15793 15794 15795 15796 15797 15798 15799 15800 15801 15802 15803 15804 15805 15806 15807 15808 15809 15810 15811 15812 15813 15814 15815 15816 15817 15818 15819 15820 15821 15822 15823 15824 15825 15826 15827 15828 15829 15830 15831 15832 15833 15834 15835 15836 15837 15838 15839 15840 15841 15842 15843 15844 15845 15846 15847 15848 15849 15850 15851 15852 15853 15854 15855 15856 15857 15858 15859 15860 15861 15862 15863 15864 15865 15866 15867 15868 15869 15870 15871 15872 15873 15874 15875 15876 15877 15878 15879 15880 15881 15882 15883 15884 15885 15886 15887 15888 15889 15890 15891 15892 15893 15894 15895 15896 15897 15898 15899 15900 15901 15902 15903 15904 15905 15906 15907 15908 15909 15910 15911 15912 15913 15914 15915 15916 15917 15918 15919 15920 15921 15922 15923 15924 15925 15926 15927 15928 15929 15930 15931 15932 15933 15934 15935 15936 15937 15938 15939 15940 15941 15942 15943 15944 15945 15946 15947 15948 15949 15950 15951 15952 15953 15954 15955 15956 15957 15958 15959 15960 15961 15962 15963 15964 15965 15966 15967 15968 15969 15970 15971 15972 15973 15974 15975 15976 15977 15978 15979 15980 15981 15982 15983 15984 15985 15986 15987 15988 15989 15990 15991 15992 15993 15994 15995 15996 15997 15998 15999 16000 16001 16002 16003 16004 16005 16006 16007 16008 16009 16010 16011 16012 16013 16014 16015 16016 16017 16018 16019 16020 16021 16022 16023 16024 16025 16026 16027 16028 16029 16030 16031 16032 16033 16034 16035 16036 16037 16038 16039 16040 16041 16042 16043 16044 16045 16046 16047 16048 16049 16050 16051 16052 16053 16054 16055 16056 16057 16058 16059 16060 16061 16062 16063 16064 16065 16066 16067 16068 16069 16070 16071 16072 16073 16074 16075 16076 16077 16078 16079 16080 16081 16082 16083 16084 16085 16086 16087 16088 16089 16090 16091 16092 16093 16094 16095 16096 16097 16098 16099 16100 16101 16102 16103 16104 16105 16106 16107 16108 16109 16110 16111 16112 16113 16114 16115 16116 16117 16118 16119 16120 16121 16122 16123 16124 16125 16126 16127 16128 16129 16130 16131 16132 16133 16134 16135 16136 16137 16138 16139 16140 16141 16142 16143 16144 16145 16146 16147 16148 16149 16150 16151 16152 16153 16154 16155 16156 16157 16158 16159 16160 16161 16162 16163 16164 16165 16166 16167 16168 16169 16170 16171 16172 16173 16174 16175 16176 16177 16178 16179 16180 16181 16182 16183 16184 16185 16186 16187 16188 16189 16190 16191 16192 16193 16194 16195 16196 16197 16198 16199 16200 16201 16202 16203 16204 16205 16206 16207 16208 16209 16210 16211 16212 16213 16214 16215 16216 16217 16218 16219 16220 16221 16222 16223 16224 16225 16226 16227 16228 16229 16230 16231 16232 16233 16234 16235 16236 16237 16238 16239 16240 16241 16242 16243 16244 16245 16246 16247 16248 16249 16250 16251 16252 16253 16254 16255 16256 16257 16258 16259 16260 16261 16262 16263 16264 16265 16266 16267 16268 16269 16270 16271 16272 16273 16274 16275 16276 16277 16278 16279 16280 16281 16282 16283 16284 16285 16286 16287 16288 16289 16290 16291 16292 16293 16294 16295 16296 16297 16298 16299 16300 16301 16302 16303 16304 16305 16306 16307 16308 16309 16310 16311 16312 16313 16314 16315 16316 16317 16318 16319 16320 16321 16322 16323 16324 16325 16326 16327 16328 16329 16330 16331 16332 16333 16334 16335 16336 16337 16338 16339 16340 16341 16342 16343 16344 16345 16346 16347 16348 16349 16350 16351 16352 16353 16354 16355 16356 16357 16358 16359 16360 16361 16362 16363 16364 16365 16366 16367 16368 16369 16370 16371 16372 16373 16374 16375 16376 16377 16378 16379 16380 16381 16382 16383 16384 16385 16386 16387 16388 16389 16390 16391 16392 16393 16394 16395 16396 16397 16398 16399 16400 16401 16402 16403 16404 16405 16406 16407 16408 16409 16410 16411 16412 16413 16414 16415 16416 16417 16418 16419 16420 16421 16422 16423 16424 16425 16426 16427 16428 16429 16430 16431 16432 16433 16434 16435 16436 16437 16438 16439 16440 16441 16442 16443 16444 16445 16446 16447 16448 16449 16450 16451 16452 16453 16454 16455 16456 16457 16458 16459 16460 16461 16462 16463 16464 16465 16466 16467 16468 16469 16470 16471 16472 16473 16474 16475 16476 16477 16478 16479 16480 16481 16482 16483 16484 16485 16486 16487 16488 16489 16490 16491 16492 16493 16494 16495 16496 16497 16498 16499 16500 16501 16502 16503 16504 16505 16506 16507 16508 16509 16510 16511 16512 16513 16514 16515 16516 16517 16518 16519 16520 16521 16522 16523 16524 16525 16526 16527 16528 16529 16530 16531 16532 16533 16534 16535 16536 16537 16538 16539 16540 16541 16542 16543 16544 16545 16546 16547 16548 16549 16550 16551 16552 16553 16554 16555 16556 16557 16558 16559 16560 16561 16562 16563 16564 16565 16566 16567 16568 16569 16570 16571 16572 16573 16574 16575 16576 16577 16578 16579 16580 16581 16582 16583 16584 16585 16586 16587 16588 16589 16590 16591 16592 16593 16594 16595 16596 16597 16598 16599 16600 16601 16602 16603 16604 16605 16606 16607 16608 16609 16610 16611 16612 16613 16614 16615 16616 16617 16618 16619 16620 16621 16622 16623 16624 16625 16626 16627 16628 16629 16630 16631 16632 16633 16634 16635 16636 16637 16638 16639 16640 16641 16642 16643 16644 16645 16646 16647 16648 16649 16650 16651 16652 16653 16654 16655 16656 16657 16658 16659 16660 16661 16662 16663 16664 16665 16666 16667 16668 16669 16670 16671 16672 16673 16674 16675 16676 16677 16678 16679 16680 16681 16682 16683 16684 16685 16686 16687 16688 16689 16690 16691 16692 16693 16694 16695 16696 16697 16698 16699 16700 16701 16702 16703 16704 16705 16706 16707 16708 16709 16710 16711 16712 16713 16714 16715 16716 16717 16718 16719 16720 16721 16722 16723 16724 16725 16726 16727 16728 16729 16730 16731 16732 16733 16734 16735 16736 16737 16738 16739 16740 16741 16742 16743 16744 16745 16746 16747 16748 16749 16750 16751 16752 16753 16754 16755 16756 16757 16758 16759 16760 16761 16762 16763 16764 16765 16766 16767 16768 16769 16770 16771 16772 16773 16774 16775 16776 16777 16778 16779 16780 16781 16782 16783 16784 16785 16786 16787 16788 16789 16790 16791 16792 16793 16794 16795 16796 16797 16798 16799 16800 16801 16802 16803 16804 16805 16806 16807 16808 16809 16810 16811 16812 16813 16814 16815 16816 16817 16818 16819 16820 16821 16822 16823 16824 16825 16826 16827 16828 16829 16830 16831 16832 16833 16834 16835 16836 16837 16838 16839 16840 16841 16842 16843 16844 16845 16846 16847 16848 16849 16850 16851 16852 16853 16854 16855 16856 16857 16858 16859 16860 16861 16862 16863 16864 16865 16866 16867 16868 16869 16870 16871 16872 16873 16874 16875 16876 16877 16878 16879 16880 16881 16882 16883 16884 16885 16886 16887 16888 16889 16890 16891 16892 16893 16894 16895 16896 16897 16898 16899 16900 16901 16902 16903 16904 16905 16906 16907 16908 16909 16910 16911 16912 16913 16914 16915 16916 16917 16918 16919 16920 16921 16922 16923 16924 16925 16926 16927 16928 16929 16930 16931 16932 16933 16934 16935 16936 16937 16938 16939 16940 16941 16942 16943 16944 16945 16946 16947 16948 16949 16950 16951 16952 16953 16954 16955 16956 16957 16958 16959 16960 16961 16962 16963 16964 16965 16966 16967 16968 16969 16970 16971 16972 16973 16974 16975 16976 16977 16978 16979 16980 16981 16982 16983 16984 16985 16986 16987 16988 16989 16990 16991 16992 16993 16994 16995 16996 16997 16998 16999 17000 17001 17002 17003 17004 17005 17006 17007 17008 17009 17010 17011 17012 17013 17014 17015 17016 17017 17018 17019 17020 17021 17022 17023 17024 17025 17026 17027 17028 17029 17030 17031 17032 17033 17034 17035 17036 17037 17038 17039 17040 17041 17042 17043 17044 17045 17046 17047 17048 17049 17050 17051 17052 17053 17054 17055 17056 17057 17058 17059 17060 17061 17062 17063 17064 17065 17066 17067 17068 17069 17070 17071 17072 17073 17074 17075 17076 17077 17078 17079 17080 17081 17082 17083 17084 17085 17086 17087 17088 17089 17090 17091 17092 17093 17094 17095 17096 17097 17098 17099 17100 17101 17102 17103 17104 17105 17106 17107 17108 17109 17110 17111 17112 17113 17114 17115 17116 17117 17118 17119 17120 17121 17122 17123 17124 17125 17126 17127 17128 17129 17130 17131 17132 17133 17134 17135 17136 17137 17138 17139 17140 17141 17142 17143 17144 17145 17146 17147 17148 17149 17150 17151 17152 17153 17154 17155 17156 17157 17158 17159 17160 17161 17162 17163 17164 17165 17166 17167 17168 17169 17170 17171 17172 17173 17174 17175 17176 17177 17178 17179 17180 17181 17182 17183 17184 17185 17186 17187 17188 17189 17190 17191 17192 17193 17194 17195 17196 17197 17198 17199 17200 17201 17202 17203 17204 17205 17206 17207 17208 17209 17210 17211 17212 17213 17214 17215 17216 17217 17218 17219 17220 17221 17222 17223 17224 17225 17226 17227 17228 17229 17230 17231 17232 17233 17234 17235 17236 17237 17238 17239 17240 17241 17242 17243 17244 17245 17246 17247 17248 17249 17250 17251 17252 17253 17254 17255 17256 17257 17258 17259 17260 17261 17262 17263 17264 17265 17266 17267 17268 17269 17270 17271 17272 17273 17274 17275 17276 17277 17278 17279 17280 17281 17282 17283 17284 17285 17286 17287 17288 17289 17290 17291 17292 17293 17294 17295 17296 17297 17298 17299 17300 17301 17302 17303 17304 17305 17306 17307 17308 17309 17310 17311 17312 17313 17314 17315 17316 17317 17318 17319 17320 17321 17322 17323 17324 17325 17326 17327 17328 17329 17330 17331 17332 17333 17334 17335 17336 17337 17338 17339 17340 17341 17342 17343 17344 17345 17346 17347 17348 17349 17350 17351 17352 17353 17354 17355 17356 17357 17358 17359 17360 17361 17362 17363 17364 17365 17366 17367 17368 17369 17370 17371 17372 17373 17374 17375 17376 17377 17378 17379 17380 17381 17382 17383 17384 17385 17386 17387 17388 17389 17390 17391 17392 17393 17394 17395 17396 17397 17398 17399 17400 17401 17402 17403 17404 17405 17406 17407 17408 17409 17410 17411 17412 17413 17414 17415 17416 17417 17418 17419 17420 17421 17422 17423 17424 17425 17426 17427 17428 17429 17430 17431 17432 17433 17434 17435 17436 17437 17438 17439 17440 17441 17442 17443 17444 17445 17446 17447 17448 17449 17450 17451 17452 17453 17454 17455 17456 17457 17458 17459 17460 17461 17462 17463 17464 17465 17466 17467 17468 17469 17470 17471 17472 17473 17474 17475 17476 17477 17478 17479 17480 17481 17482 17483 17484 17485 17486 17487 17488 17489 17490 17491 17492 17493 17494 17495 17496 17497 17498 17499 17500 17501 17502 17503 17504 17505 17506 17507 17508 17509 17510 17511 17512 17513 17514 17515 17516 17517 17518 17519 17520 17521 17522 17523 17524 17525 17526 17527 17528 17529 17530 17531 17532 17533 17534 17535 17536 17537 17538 17539 17540 17541 17542 17543 17544 17545 17546 17547 17548 17549 17550 17551 17552 17553 17554 17555 17556 17557 17558 17559 17560 17561 17562 17563 17564 17565 17566 17567 17568 17569 17570 17571 17572 17573 17574 17575 17576 17577 17578 17579 17580 17581 17582 17583 17584 17585 17586 17587 17588 17589 17590 17591 17592 17593 17594 17595 17596 17597 17598 17599 17600 17601 17602 17603 17604 17605 17606 17607 17608 17609 17610 17611 17612 17613 17614 17615 17616 17617 17618 17619 17620 17621 17622 17623 17624 17625 17626 17627 17628 17629 17630 17631 17632 17633 17634 17635 17636 17637 17638 17639 17640 17641 17642 17643 17644 17645 17646 17647 17648 17649 17650 17651 17652 17653 17654 17655 17656 17657 17658 17659 17660 17661 17662 17663 17664 17665 17666 17667 17668 17669 17670 17671 17672 17673 17674 17675 17676 17677 17678 17679 17680 17681 17682 17683 17684 17685 17686 17687 17688 17689 17690 17691 17692 17693 17694 17695 17696 17697 17698 17699 17700 17701 17702 17703 17704 17705 17706 17707 17708 17709 17710 17711 17712 17713 17714 17715 17716 17717 17718 17719 17720 17721 17722 17723 17724 17725 17726 17727 17728 17729 17730 17731 17732 17733 17734 17735 17736 17737 17738 17739 17740 17741 17742 17743 17744 17745 17746 17747 17748 17749 17750 17751 17752 17753 17754 17755 17756 17757 17758 17759 17760 17761 17762 17763 17764 17765 17766 17767 17768 17769 17770 17771 17772 17773 17774 17775 17776 17777 17778 17779 17780 17781 17782 17783 17784 17785 17786 17787 17788 17789 17790 17791 17792 17793 17794 17795 17796 17797 17798 17799 17800 17801 17802 17803 17804 17805 17806 17807 17808 17809 17810 17811 17812 17813 17814 17815 17816 17817 17818 17819 17820 17821 17822 17823 17824 17825 17826 17827 17828 17829 17830 17831 17832 17833 17834 17835 17836 17837 17838 17839 17840 17841 17842 17843 17844 17845 17846 17847 17848 17849 17850 17851 17852 17853 17854 17855 17856 17857 17858 17859 17860 17861 17862 17863 17864 17865 17866 17867 17868 17869 17870 17871 17872 17873 17874 17875 17876 17877 17878 17879 17880 17881 17882 17883 17884 17885 17886 17887 17888 17889 17890 17891 17892 17893 17894 17895 17896 17897 17898 17899 17900 17901 17902 17903 17904 17905 17906 17907 17908 17909 17910 17911 17912 17913 17914 17915 17916 17917 17918 17919 17920 17921 17922 17923 17924 17925 17926 17927 17928 17929 17930 17931 17932 17933 17934 17935 17936 17937 17938 17939 17940 17941 17942 17943 17944 17945 17946 17947 17948 17949 17950 17951 17952 17953 17954 17955 17956
|
[ [1]Contents ] [ [2]C-Kermit ] [ [3]Kermit Home ]
Supplement to Using C-Kermit, Second Edition
For C-Kermit 7.0
As of C-Kermit version: 7.0.196
This file last updated: 8 February 2000
Authors: Frank da Cruz and Christine M. Gianone
Address: The Kermit Project
Columbia University
612 West 115th Street
New York NY 10025-7799
USA
Fax: +1 (212) 662-6442
E-Mail: [4]kermit-support@columbia.edu
Web: [5]http://www.columbia.edu/kermit/
Or: [6]http://www.kermit-project.org/
Or: [7]http://www.columbia.nyc.ny.us/kermit/
_________________________________________________________________
NOTICES
This document:
Copyright 1997, 2000, Frank da Cruz and Christine M. Gianone.
All rights reserved.
Kermit 95:
Copyright 1995, 2000, Trustees of Columbia University in the
City of New York. All rights reserved.
C-Kermit:
Copyright 1985, 2000,
Trustees of Columbia University in the City of New York. All
rights reserved. See the C-Kermit [8]COPYING.TXT file or the
copyright text in the [9]ckcmai.c module for disclaimer and
permissions.
When Kerberos(TM) and/or SRP(TM) (Secure Remote Password) and/or SSL
protocol are included:
Portions Copyright 1990, Massachusetts Institute of
Technology.
Portions Copyright 1991, 1993 Regents of the University of
California.
Portions Copyright 1991, 1992, 1993, 1994, 1995 by AT&T.
Portions Copyright 1997, Stanford University.
Portions Copyright 1995-1997, Eric Young
<eay@cryptosoft.com>.
For the full text of the third-party copyright notices, see
[10]Appendix V.
_________________________________________________________________
WHAT IS IN THIS FILE
This file lists changes made to C-Kermit since the second edition of
the book [11]Using C-Kermit was published and C-Kermit 6.0 was
released in November 1996. Use this file as a supplement to the second
edition of Using C-Kermit until the third edition is published some
time in 2000. If the "most recent update" shown above is long ago,
contact Columbia University to see if there is a newer release.
For further information, also see the [12]CKCBWR.TXT ("C-Kermit
beware") file for hints, tips, tricks, restrictions, frequently asked
questions, etc, plus the system-specific "beware file", e.g.
[13]CKUBWR.TXT for UNIX, [14]CKVBWR.TXT for VMS, etc, and also any
system-specific update files such as KERMIT95.HTM for Kermit 95 (in
the DOCS\MANUAL\ subdirectory of your K95 directory).
This Web-based copy of the C-Kermit 7.0 update notes supersedes the
plain-text CKERMIT2.TXT file. All changes after 19 January 2000
appear only here in the Web version. If you need an up-to-date
plain-text copy, use your Web browser to save this page as plain
text.
_________________________________________________________________
ABOUT FILENAMES
In this document, filenames are generally shown in uppercase, but on
file systems with case-sensitive names such as UNIX, OS-9, and AOS/VS,
lowercase names are used: [15]ckubwr.txt, [16]ckermit70.txt, etc.
_________________________________________________________________
ADDITIONAL FILES
Several other files accompany this new Kermit release:
SECURITY.TXT
Discussion of Kermit's new authentication and encryption
features:
+ [17]Plain-text version
+ [18]HTML (hypertext) version
IKSD.TXT
How to install and manage an Internet Kermit Service Daemon.
+ [19]Plain-text version
+ [20]HTML (hypertext) version
Also see [21]cuiksd.htm for instructions for use.
TELNET.TXT
A thorough presentation of Kermit's new advanced Telnet
features and controls.
+ [22]Plain-text version
+ [23]HTML (hypertext) version
_________________________________________________________________
THE NEW C-KERMIT LICENSE
The C-Kermit license was rewritten for version 7.0 to grant automatic
permission to packagers of free operating-system distributions to
include C-Kermit 7.0. Examples include Linux (GNU/Linux), FreeBSD,
NetBSD, etc. The new license is in the [24]COPYING.TXT file, and is
also displayed by C-Kermit itself when you give the VERSION or
COPYRIGHT command. The new C-Kermit license does not apply to
[25]Kermit 95.
_________________________________________________________________
ACKNOWLEDGMENTS
Thanks to Jeff Altman, who joined the Kermit Project in 1995, for much
of what you see in C-Kermit 7.0, especially in the networking and
security areas, and his key role in designing and implementing the
Internet Kermit Service Daemon. And special thanks to Lucas Hart for
lots of help with the VMS version; to Peter Eichhorn for continuous
testing on the full range of HP-UX versions and for a consolidated set
of HP-UX makefile targets; and to Colin Allen, Mark Allen, Roger
Allen, Ric Anderson, William Bader, Mitch Baker, Mitchell Bass, Nelson
Beebe, Gerry Belanger, Jeff Bernsten, Mark Berryman, John Bigg, Volker
Borchert, Jonathan Boswell, Tim Boyer, Frederick Bruckman, Kenneth
Cochran, Jared Crapo, Bill Delaney, Igor Sobrado Delgado, Clarence
Dold, Joe Doupnik, John Dunlap, Max Evarts, Patrick French, Carl
Friedberg, Carl Friend, Hirofumi Fujii, Andrew Gabriel, Gabe Garza,
Boyd Gerber, David Gerber, George Gilmer, Hunter Goatley, DJ Hagberg,
Kevin Handy, Andy Harper, Randolph Herber, Sven Holstrm, Michal
Jaegermann, Graham Jenkins, Dick Jones, Terry Kennedy, Robert D Keys,
Nick Kisseberth, Igor Kovalenko, David Lane, Adam Laurie, Jeff
Liebermann, Eric Lonvick, Hoi Wan Louis, Arthur Marsh, Gregorie
Martin, Peter Mauzey, Dragan Milicic, Todd Miller, Christian Mondrup,
Daniel Morato, Dat Nguyen, Herb Peyerl, Jean-Pierre Radley, Steve
Rance, Stephen Riehm, Nigel Roles, Larry Rosenman, Jay S Rouman, David
Sanderson, John Santos, Michael Schmitz, Steven Schultz, Bob Shair,
Richard Shuford, Fred Smith, Michael Sokolov, Jim Spath, Peter Szell,
Ted T'so, Brian Tillman, Linus Torvalds, Patrick Volkerding, Martin
Vorlnder, Steve Walton, Ken Weaverling, John Weekley, Martin
Whitaker, Jim Whitby, Matt Willman, Joellen Windsor, Farrell Woods,
and many others for binaries, hosting, reviews, suggestions, advice,
bug reports, and all the rest over the 3+ year C-Kermit 7.0
development cycle. Thanks to Russ Nelson and the board of the Open
Software Initiative ([26]http://www.opensource.org) for their
cooperation in developing the new C-Kermit license and to the
proprietors of those free UNIX distributions that have incorporated
C-Kermit 7.0 for their cooperation and support, especially FreeBSD's
Jrg Wunsch.
_________________________________________________________________
NOTE TO KERMIT 95 USERS
Kermit 95 and C-Kermit share the same command and scripting language,
the same Kermit file-transfer protocol implementation, and much else
besides.
Like the book [27]Using C-Kermit, this file concentrates on the
aspects of C-Kermit that are common to all versions: UNIX, VMS,
Windows, OS/2, VOS, AOS/VS, etc. Please refer to your Kermit 95
documentation for information that is specific to Kermit 95.
C-Kermit 7.0 corresponds to Kermit 95 1.1.19.
_________________________________________________________________
C-KERMIT VERSIONS AND VERSION NUMBERS
"C-Kermit" refers to all the many programs that are compiled in whole
or in part from common C-language source code, comprising:
* A Kermit file transfer protocol module
* A command parser and script execution module
* A modem-dialing module
* A network support module
* A character-set translation module.
and several others. These "system-independent" modules are combined
with system-dependent modules for each platform to provide the
required input/output functions, and also in some cases overlaid with
an alternative user interface, such as Macintosh Kermit's
point-and-click interface, and in some cases also a terminal emulator,
as Kermit 95.
The C-Kermit version number started as 1.0, ... 3.0, 4.0, 4.1 and then
(because of confusion at the time with Berkeley UNIX 4.2), 4B, 4C, and
so on, with the specific edit number in parentheses, for example
4E(072) or 5A(188). This scheme was used through 5A(191), but now we
have gone back to the traditional numbering scheme with decimal
points: major.minor.edit; for example 7.0.196. Internal version
numbers (the \v(version) variable), however, are compatible in
C-Kermit 5A upwards.
Meanwhile, C-Kermit derivatives for some platforms (Windows,
Macintosh) might go through several releases while C-Kermit itself
remains the same. These versions have their own platform-specific
version numbers, such as Kermit 95 1.1.1, 1.1.2, and so on.
C-Kermit Version History:
1.0 1981-1982 Command-line only, 4.2 BSD UNIX only
2.0 (*) (who remembers...)
3.0 May 1984 Command-line only, supports several platforms
4.0-4.1 Feb-Apr 1985 (*) First interactive and modular version
4C(050) May 1985
4D(060) April 1986
4E(066) August 1987 Long packets
4E(068) January 1988
4E(072) January 1989
4F(095) August 1989 (*) Attribute packets
5A(188) November 1992 Scripting, TCP/IP, sliding windows (1)
5A(189) September 1993 Control-char unprefixing
5A(190) October 1994 Recovery
5A(191) April 1995 OS/2 only
6.0.192 September 1996 Intelligent dialing, autodownload, lots more (2)
6.1.193 1997-98 (*) Development only
6.1.194 June 1998 K95 only - switches, directory recursion, more
7.0.195 August 1999 IKSD + more (CU only as K95 1.1.18-CU)
7.0.196 1 January 2000 Unicode, lots more
(*) Never formally released (4.0 was a total rewrite)
(1) Using C-Kermit, 1st Edition
(2) Using C-Kermit, 2nd Edition
_________________________________________________________________
CONTENTS
I. [28]C-KERMIT DOCUMENTATION
II. [29]NEW FEATURES
(0) [30]INCOMPATIBILITIES WITH PREVIOUS RELEASES
(1) [31]PROGRAM AND FILE MANAGEMENT AND COMMANDS
1.0. [32]Bug fixes
1.1. [33]Command Continuation
1.2. [34]Editor Interface
1.3. [35]Web Browser and FTP Interface
1.4. [36]Command Editing
1.5. [37]Command Switches
1.5.1. [38]General Switch Syntax
1.5.2. [39]Order and Effect of Switches
1.5.3. [40]Distinguishing Switches from Other Fields
1.5.4. [41]Standard File Selection Switches
1.5.5. [42]Setting Preferences for Different Commands
1.6. [43]Dates and Times
1.7. [44]Partial Completion of Keywords
1.8. [45]Command Recall
1.9. [46]EXIT Messages
1.10. [47]Managing Keyboard Interruptions
1.11. [48]Taming the Wild Backslash -- Part Deux
1.11.1. [49]Background
1.11.2. [50]Kermit's Quoting Rules
1.11.3. [51]Passing DOS Filenames from Kermit to Shell Commands
1.11.4. [52]Using Variables to Hold DOS Filenames
1.11.5. [53]Passing DOS Filenames as Parameters to Macros
1.11.6. [54]Passing DOS File Names from Macro Parameters to the
DOS Shell
1.11.7. [55]Passing DOS Filenames to Kermit from the Shell
1.12. [56]Debugging
1.13. [57]Logs
1.14. [58]Automatic File-Transfer Packet Recognition at the Command Pr
ompt
1.15. [59]The TYPE Command
1.16. [60]The RESET Command
1.17. [61]The COPY and RENAME Commands
1.18. [62]The MANUAL Command
1.19. [63]String and Filename Matching Patterns
1.20. [64]Multiple Commands on One Line
1.21. [65]What Do I Have?
1.22. [66]Generalized File Input and Output
1.22.1. [67]Why Another I/O System?
1.22.2. [68]The FILE Command
1.22.3. [69]FILE Command Examples
1.22.4. [70]Channel Numbers
1.22.5. [71]FILE Command Error Codes
1.22.6. [72]File I/O Variables
1.22.7. [73]File I/O Functions
1.22.8. [74]File I/O Function Examples
1.23. [75]The EXEC Command
1.24. [76]Getting Keyword Lists with '?'
(2) [77]MAKING AND USING CONNECTIONS
2.0. [78]SET LINE and SET HOST Command Switches
2.1. [79]Dialing
2.1.1. [80]The Dial Result Message
2.1.2. [81]Long-Distance Dialing Changes
2.1.3. [82]Forcing Long-Distance Dialing
2.1.4. [83]Exchange-Specific Dialing Decisions
2.1.5. [84]Cautions about Cheapest-First Dialing
2.1.6. [85]Blind Dialing (Dialing with No Dialtone)
2.1.7. [86]Trimming the Dialing Dialog
2.1.8. [87]Controlling the Dialing Speed
2.1.9. [88]Pretesting Phone Number Conversions
2.1.10. [89]Greater Control over Partial Dialing
2.1.11. [90]New DIAL-related Variables and Functions
2.1.12. [91]Increased Flexibility of PBX Dialing
2.1.13. [92]The DIAL macro - Last-Minute Phone Number Conversions
2.1.14. [93]Automatic Tone/Pulse Dialing Selection
2.1.15. [94]Dial-Modifier Variables
2.1.16. [95]Giving Multiple Numbers to the DIAL Command
2.2. [96]Modems
2.2.1. [97]New Modem Types
2.2.2. [98]New Modem Controls
2.3. [99]TELNET and RLOGIN
2.3.0. [100]Bug Fixes
2.3.1. [101]Telnet Binary Mode Bug Adjustments
2.3.2. [102]VMS UCX Telnet Port Bug Adjustment
2.3.3. [103]Telnet New Environment Option
2.3.4. [104]Telnet Location Option
2.3.5. [105]Connecting to Raw TCP Sockets
2.3.6. [106]Incoming TCP Connections
2.4. [107]The EIGHTBIT Command
2.5. [108]The Services Directory
2.6. [109]Closing Connections
2.7. [110]Using C-Kermit with External Communication Programs
2.7.0. [111]C-Kermit over tn3270 and tn5250
2.7.1. [112]C-Kermit over Telnet
2.7.2. [113]C-Kermit over Rlogin
2.7.3. [114]C-Kermit over Serial Communication Programs
2.7.4. [115]C-Kermit over Secure Network Clients
2.7.4.1. [116]SSH
2.7.4.2. [117]SSL
2.7.4.3. [118]SRP
2.7.4.4. [119]SOCKS
2.7.4.5. [120]Kerberos and SRP
2.8. [121]Scripting Local Programs
2.9. [122]X.25 Networking
2.9.1. [123]IBM AIXLink/X.25 Network Provider Interface for AIX
2.9.2. [124]HP-UX X.25
2.10. [125]Additional Serial Port Controls
2.11. [126]Getting Access to the Dialout Device
2.12. [127]The Connection Log
2.13. [128]Automatic Connection-Specific Flow Control Selection
2.14. [129]Trapping Connection Establishment and Loss
2.15. [130]Contacting Web Servers with the HTTP Command
(3) [131]TERMINAL CONNECTION
3.1. [132]CONNECT Command Switches
3.2. [133]Triggers
3.3. [134]Transparent Printing
3.4. [135]Binary and Text Session Logs
(4) [136]FILE TRANSFER AND MANAGEMENT
4.0. [137]Bug Fixes, Minor Changes, and Clarifications
4.1. [138]File-Transfer Filename Templates
4.1.1. [139]Templates in the As-Name
4.1.2. [140]Templates on the Command Line
4.1.3. [141]Post-Transfer Renaming
4.2. [142]File-Transfer Pipes and Filters
4.2.1. [143]Introduction
4.2.1.1. [144]Terminology
4.2.1.2. [145]Notation
4.2.1.3. [146]Security
4.2.2. [147]Commands for Transferring from and to Pipes
4.2.2.1. [148]Sending from a Command
4.2.2.2. [149]Receiving to a Command
4.2.3. [150]Using File-Transfer Filters
4.2.3.1. [151]The SEND Filter
4.2.3.2. [152]The RECEIVE Filter
4.2.4. [153]Implicit Use of Pipes
4.2.5. [154]Success and Failure of Piped Commands
4.2.6. [155]Cautions about Using Pipes to Transfer Directory Trees
4.2.7. [156]Pipes and Encryption
4.2.8. [157]Commands and Functions Related to Pipes
4.2.8.1. [158]The OPEN !READ and OPEN !WRITE Commands
4.2.8.2. [159]The REDIRECT Command
4.2.8.3. [160]Receiving Mail and Print Jobs
4.2.8.4. [161]Pipe-Related Functions
4.3. [162]Automatic Per-File Text/Binary Mode Switching
4.3.1. [163]Exceptions
4.3.2. [164]Overview
4.3.3. [165]Commands
4.3.4. [166]Examples
4.4. [167]File Permissions
4.4.1. [168]When ATTRIBUTES PROTECTION is OFF
4.4.1.1. [169]Unix
4.4.1.2. [170]VMS
4.4.2. [171]When ATTRIBUTES PROTECTION is ON
4.4.2.1. [172]System-Specific Permissions
4.4.2.1.1. [173]UNIX
4.4.2.1.2. [174]VMS
4.4.2.2. [175]System-Independent Permissions
4.5. [176]File Management Commands
4.5.1. [177]The DIRECTORY Command
4.5.2. [178]The CD and BACK Commands
4.5.2.1. [179]Parsing Improvements
4.5.2.2. [180]The CDPATH
4.5.3. [181]Creating and Removing Directories
4.5.4. [182]The DELETE and PURGE Commands
4.6. [183]Starting the Remote Kermit Server Automatically
4.7. [184]File-Transfer Command Switches
4.7.1. [185]SEND Command Switches
4.7.2. [186]GET Command Switches
4.7.3. [187]RECEIVE Command Switches
4.8. [188]Minor Kermit Protocol Improvements
4.8.1. [189]Multiple Attribute Packets
4.8.2. [190]Very Short Packets
4.9. [191]Wildcard / File Group Expansion
4.9.1. [192]In UNIX C-Kermit
4.9.2. [193]In Kermit 95
4.9.3. [194]In VMS, AOS/VS, OS-9, VOS, etc.
4.10. [195]Additional Pathname Controls
4.11. [196]Recursive SEND and GET: Transferring Directory Trees
4.11.1. [197]Command-Line Options
4.11.2. [198]The SEND /RECURSIVE Command
4.11.3. [199]The GET /RECURSIVE Command
4.11.4. [200]New and Changed File Functions
4.11.5. [201]Moving Directory Trees Between Like Systems
4.11.6. [202]Moving Directory Trees Between Unlike Systems
4.12. [203]Where Did My File Go?
4.13. [204]File Output Buffer Control
4.14. [205]Improved Responsiveness
4.15. [206]Doubling and Ignoring Characters for Transparency
4.16. [207]New File-Transfer Display Formats
4.17. [208]New Transaction Log Formats
4.17.1. [209]The BRIEF Format
4.17.2. [210]The FTP Format
4.18. [211]Unprefixing NUL
4.19. [212]Clear-Channel Protocol
4.20. [213]Streaming Protocol
4.20.1. [214]Commands for Streaming
4.20.2. [215]Examples of Streaming
4.20.2.1. [216]Streaming on Socket-to-Socket Connections
4.20.2.2. [217]Streaming on Telnet Connections
4.20.2.3. [218]Streaming with Limited Packet Length
4.20.2.4. [219]Streaming on Dialup Connections
4.20.2.5. [220]Streaming on X.25 Connections
4.20.3. [221]Streaming - Preliminary Conclusions
4.21. [222]The TRANSMIT Command
4.22. [223]Coping with Faulty Kermit Implementations
4.22.1. [224]Failure to Accept Modern Negotiation Strings
4.22.2. [225]Failure to Negotiate 8th-bit Prefixing
4.22.3. [226]Corrupt Files
4.22.4. [227]Spurious Cancellations
4.22.5. [228]Spurious Refusals
4.22.6. [229]Failures during the Data Transfer Phase
4.22.7. [230]Fractured Filenames
4.22.8. [231]Bad File Dates
4.23. [232]File Transfer Recovery
4.24. [233]FILE COLLISION UPDATE Clarification
4.25. [234]Autodownload Improvements
(5) [235]CLIENT/SERVER
5.0. [236]Hints
5.1. [237]New Command-Line Options
5.2. [238]New Client Commands
5.3. [239]New Server Capabilities
5.3.1. [240]Creating and Removing Directories
5.3.2. [241]Directory Listings
5.4. [242]Syntax for Remote Filenames with Embedded Spaces
5.5. [243]Automatic Orientation Messages upon Directory Change
5.6. [244]New Server Controls
5.7. [245]Timeouts during REMOTE HOST Command Execution
(6) [246]INTERNATIONAL CHARACTER SETS
6.0. [247]ISO 8859-15 Latin Alphabet 9
6.1. [248]The HP-Roman8 Character Set
6.2. [249]Greek Character Sets
6.3. [250]Additional Latin-2 Character Sets
6.4. [251]Additional Cyrillic Character Sets
6.5. [252]Automatic Character-Set Switching
6.6. [253]Unicode
6.6.1. [254]Overview of Unicode
6.6.2. [255]UCS Byte Order
6.6.2. [256]UCS Transformation Formats
6.6.3. [257]Conformance Levels
6.6.4. [258]Relationship of Unicode with Kermit's Other Character Sets
6.6.5. [259]Kermit's Unicode Features
6.6.5.1. [260]File Transfer
6.6.5.2. [261]The TRANSLATE Command
6.6.5.3. [262]Terminal Connection
6.6.5.4. [263]The TRANSMIT Command
6.6.5.5. [264]Summary of Kermit Unicode Commands
6.7. [265]Client/Server Character-Set Switching
(7) [266]SCRIPT PROGRAMMING
7.0. [267]Bug Fixes
7.1. [268]The INPUT Command
7.1.1. [269]INPUT Timeouts
7.1.2. [270]New INPUT Controls
7.1.3. [271]INPUT with Pattern Matching
7.1.4. [272]The INPUT Match Result
7.2. [273]New or Improved Built-In Variables
7.3. [274]New or Improved Built-In Functions
7.4. [275]New IF Conditions
7.5. [276]Using More than Ten Macro Arguments
7.6. [277]Clarification of Function Call Syntax
7.7. [278]Autodownload during INPUT Command Execution
7.8. [279]Built-in Help for Functions.
7.9. [280]Variable Assignments
7.9.1. [281]Assignment Operators
7.9.2. [282]New Assignment Commands
7.10. [283]Arrays
7.10.1. [284]Array Initializers
7.10.2. [285]Turning a String into an Array of Words
7.10.3. [286]Arrays of Filenames
7.10.4. [287]Automatic Arrays
7.10.5. [288]Sorting Arrays
7.10.6. [289]Displaying Arrays
7.10.7. [290]Other Array Operations
7.10.8. [291]Hints for Using Arrays
7.10.9. [292]Do-It-Yourself Arrays
7.10.10. [293]Associative Arrays
7.11. [294]OUTPUT Command Improvements
7.12. [295]Function and Variable Diagnostics
7.13. [296]Return Value of Macros
7.14. [297]The ASSERT, FAIL, and SUCCEED Commands.
7.15. [298]Using Alarms
7.16. [299]Passing Arguments to Command Files
7.17. [300]Dialogs with Timed Responses
7.18. [301]Increased Flexibility of SWITCH Case Labels
7.19. "[302]Kerbang" Scripts
7.20. [303]IF and XIF Statement Syntax
7.20.1. [304]The IF/XIF Distinction
7.20.2. [305]Boolean Expressions (The IF/WHILE Condition)
7.21. [306]Screen Formatting and Cursor Control
7.22. [307]Evaluating Arithmetic Expressions
7.23. [308]Floating-Point Arithmetic
7.24. [309]Tracing Script Execution
7.25. [310]Compact Substring Notation
7.26. [311]New WAIT Command Options
7.26.1. [312]Waiting for Modem Signals
7.26.2. [313]Waiting for File Events
7.27. [314]Relaxed FOR and SWITCH Syntax
(8) [315]USING OTHER FILE TRANSFER PROTOCOLS
(9) [316]COMMAND-LINE OPTIONS
9.0. [317]Extended-Format Command-Line Options
9.1. [318]Command Line Personalities
9.2. [319]Built-in Help for Command Line Options
9.3. [320]New Command-Line Options
(10) [321]C-KERMIT AND G-KERMIT
III. [322]APPENDICES
III.1. [323]Character Set Tables
III.1.1. [324]The Hewlett Packard Roman8 Character Set
III.1.2. [325]Greek Character Sets
III.1.2.1. [326]The ISO 8859-7 Latin / Greek Alphabet
III.1.2.2. [327]The ELOT 927 Character Set
III.1.2.3. [328]PC Code Page 869
III.2. [329]Updated Country Codes
IV. [330]ERRATA & CORRIGENDA: Corrections to "Using C-Kermit" 2nd Edition.
V. [331]ADDITIONAL COPYRIGHT NOTICES
_________________________________________________________________
I. C-KERMIT DOCUMENTATION
The user manual for C-Kermit is:
Frank da Cruz and Christine M. Gianone, [332]Using C-Kermit, Second
Edition, Digital Press / Butterworth-Heinemann, Woburn, MA, 1997,
622 pages, ISBN 1-55558-164-1.
[333]CLICK HERE for reviews.
The present document is a supplement to Using C-Kermit 2nd Ed, not a
replacement for it.
US single-copy price: $52.95; quantity discounts available. Available
in bookstores or directly from Columbia University:
The Kermit Project
Columbia University
612 West 115th Street
New York NY 10025-7799
USA
Telephone: +1 (212) 854-3703
Fax: +1 (212) 662-6442
Domestic and overseas orders accepted. Price: US $44.95 (US, Canada,
and Mexico). Shipping: $4.00 within the USA; $15.00 to all other
countries. Orders may be paid by MasterCard or Visa, or prepaid by
check in US dollars. Add $65 bank fee for checks not drawn on a US
bank. Do not include sales tax. Inquire about quantity discounts.
You can also order by phone from the publisher, Digital Press /
[334]Butterworth-Heinemann, with MasterCard, Visa, or American
Express:
+1 800 366-2665 (Woburn, Massachusetts office for USA & Canada)
+44 1865 314627 (Oxford, England distribution centre for UK & Europe)
+61 03 9245 7111 (Melbourne, Vic, office for Australia & NZ)
+65 356-1968 (Singapore office for Asia)
+27 (31) 2683111 (Durban office for South Africa)
A [335]German-language edition of the First Edition is also available:
Frank da Cruz and Christine M. Gianone, C-Kermit - Einfhrung und
Referenz, Verlag Heinz Heise, Hannover, Germany (1994). ISBN
3-88229-023-4. Deutsch von Gisbert W. Selke. Price: DM 88,00.
Verlag Heinz Heise GmbH & Co. KG, Helstorfer Strasse 7, D-30625
Hannover. Tel. +49 (05 11) 53 52-0, Fax. +49 (05 11) 53 52-1 29.
The [336]Kermit file transfer protocol is specified in:
Frank da Cruz, Kermit, A File Transfer Protocol, Digital Press,
Bedford, MA, 1987, 379 pages, ISBN 0-932376-88-6. US single-copy
price: $39.95. Availability as above.
News and articles about Kermit software and protocol are published
periodically in the journal, [337]Kermit News. Subscriptions are free;
contact Columbia University at the address above.
Online news about Kermit is published in the
[338]comp.protocols.kermit.announce and
[339]comp.protocols.kermit.misc newsgroups.
_________________________________________________________________
II. NEW FEATURES
Support for the Bell Labs Plan 9 operating system was added to version
6.0 too late to be mentioned in the book (although it does appear on
the cover).
Specific changes and additions are grouped together by major topic,
roughly corresponding to the chapters of [340]Using C-Kermit.
_________________________________________________________________
0. INCOMPATIBILITIES WITH PREVIOUS RELEASES
1. C-Kermit 7.0 uses FAST Kermit protocol settings by default. This
includes "unprefixing" of certain control characters. Because of
this, file transfers that worked with previous releases might not
work in the new release (but it is more likely that they will
work, and much faster). If a transfer fails, you'll get a
context-sensitive hint suggesting possible causes and cures.
Usually SET PREFIXING ALL does the trick.
2. C-Kermit 7.0 transfers files in BINARY mode by default. To restore
the previous behavior, put SET FILE TYPE TEXT in your C-Kermit
initialization file.
3. No matter whether FILE TYPE is BINARY or TEXT by default, C-Kermit
7.0 now switches between text and binary mode automatically on a
per-file basis according to various criteria, including (a) which
kind of platform is on the other end of the connection (if known),
(b) the version of Kermit on the other end, and (c) the file's
name (see [341]Section 4, especially [342]4.3). To disable this
automatic switching and restore the earlier behavior, put SET
TRANSFER MODE MANUAL in your C-Kermit initialization file. To
disable automatic switching for a particular transfer, include a
/TEXT or /BINARY switch with your SEND or GET command.
4. The RESEND and REGET commands automatically switch to binary mode;
previously if RESEND or REGET were attempted when FILE TYPE was
TEXT, these commands would fail immediately, with a message
telling you they work only when the FILE TYPE is BINARY. Now they
simply do this for you. See [343]Section 4.23 for additional
(important) information.
5. SET PREFIXING CAUTIOUS and MINIMAL now both prefix linefeed (10
and 138) in case rlogin, ssh, or cu are "in the middle", since
otherwise <LF>~ might appear in Kermit packets, and this would
cause rlogin, ssh, or cu to disconnect, suspend,escape back, or
otherwise wreck the file transfer. Xon and Xoff are now always
prefixed too, even when Xon/Xoff flow control is not in effect,
since unprefixing them has proven dangerous on TCP/IP connections.
6. In UNIX, VMS, Windows, and OS/2, the DIRECTORY command is built
into C-Kermit itself rather than implemented by running an
external command or program. The built-in command might not behave
the way the platform-specific external one did, but many options
are available for customization. Of course the underlying
platform-specific command can still be accessed with "!", "@", or
"RUN" wherever the installation does not forbid. In UNIX, the "ls"
command can be accessed directly as "ls" in C-Kermit. See
[344]Section 4.5.1 for details.
7. SEND ? prints a list of switches rather than a list of filenames.
If you want to see a list of filenames, use a (system-dependent)
construction such as SEND ./? (for UNIX, Windows, or OS/2), SEND
[]? (VMS), etc. See [345]Sections 1.5 and [346]4.7.1.
8. In UNIX, OS-9, and Kermit 95, the wildcard characters in previous
versions were * and ?. In C-Kermit 7.0 they are *, ?, [, ], {, and
}, with dash used inside []'s to denote ranges and comma used
inside {} to separate list elements. If you need to include any of
these characters literally in a filename, precede each one with
backslash (\). See [347]Section 4.9.
9. SET QUIET { ON, OFF } is now on the command stack, just like SET
INPUT CASE, SET COUNT, SET MACRO ERROR, etc, as described on p.458
of [348]Using C-Kermit, 2nd Edition. This allows any macro or
command file to SET QUIET ON or OFF without worrying about saving
and restoring the global QUIET value. For example, this lets you
write a script that tries SET LINE on lots of devices until it
finds one free without spewing out loads of error messages, and
also without disturbing the global QUIET setting, whatever it was.
10. Because of the new "." operator (which introduces assignments),
macros whose names begin with "." can not be invoked "by name".
However, they still can be invoked with DO.
11. The syntax of the EVALUATE command has changed. See [349]Section
7.9.2. To restore the previous syntax, use SET EVALUATE OLD.
12. The \v(directory) variable now includes the trailing directory
separator; in previous releases it did not. This is to allow
constructions such as:
cd \v(dir)data.tmp
to work across platforms that might have different directory
notation, such as UNIX, Windows, and VMS.
13. Prior to C-Kermit 7.0, the FLOW-CONTROL setting was global and
sticky. In C-Kermit 7.0, there is an array of default flow-control
values for each kind of connection, that are applied automatically
at SET LINE/PORT/HOST time. Thus a SET FLOW command given before
SET LINE/PORT/HOST is likely to be undone. Therefore SET FLOW can
be guaranteed to have the desired effect only if given after the
SET LINE/PORT/HOST command.
14. Character-set translation works differently in the TRANSMIT
command when (a) the file character-set is not the same as the
local end of the terminal character-set, or (b) when the terminal
character-set is TRANSPARENT.
_________________________________________________________________
1. PROGRAM AND FILE MANAGEMENT AND COMMANDS
1.0. Bug Fixes
The following patches were issued to correct bugs in C-Kermit 6.0.
These are described in detail in the 6.0 PATCHES file. All of these
fixes have been incorporated in C-Kermit 6.1 (never released except as
K95 1.1.16-17) and 7.0.
0001 All UNIX C-Kermit mishandles timestamps on files before 1970
0002 Solaris 2.5++ Compilation error on Solaris 2.5 with Pro C
0003 All VMS CKERMIT.INI Fix for VMS
0004 VMS/VAX/UCX 2.0 C-Kermit 6.0 can't TELNET on VAX/VMS with UCX 2.0
0005 All C-Kermit Might Send Packets Outside Window
0006 All MOVE from SEND-LIST does not delete original files
0007 Solaris 2.5++ Higher serial speeds on Solaris 2.5
0008 All C-Kermit application file name can't contain spaces
0009 AT&T 7300 UNIXPC setuid and hardware flow-control problems
0010 Linux on Alpha Patch to make ckutio.c compile on Linux/Alpha
0011 OS-9/68000 2.4 Patch to make ck9con.c compile on OS-9/68000 2.4
0012 MW Coherent 4.2 Patches for successful build on Coherent 4.2
0013 SINIX-Y 5.43 "delay" variable conflicts with <sys/clock.h>
0014 VMS/VAX/CMU-IP Subject: Patches for VAX/VMS 5.x + CMU-IP
0015 All XECHO doesn't flush its output
0016 VMS CD and other directory operations might not work
0017 Linux 1.2.x++ Use standard POSIX interface for high serial speeds
0018 UNIX SET WILDCARD-EXPANSION SHELL dumps core
0019 All Hayes V.34 modem init string problem
0020 All READ command does not fail if file not open
0021 All Problems with long function arguments
0022 All Certain \function()s can misbehave
0023 All X MOD 0 crashes program
0024 All Internal bulletproofing for lower() function
0025 OpenBSD Real OpenBSD support for C-Kermit 6.0
0026 All Incorrect checks for macro/command-file nesting depth
0027 All ANSWER doesn't automatically CONNECT
0028 All Overzealous EXIT warning
0029 All OUTPUT doesn't echo when DUPLEX is HALF
0030 All Minor problems with REMOTE DIRECTORY/DELETE/etc
0031 All CHECK command broken
0032 All Problem with SET TRANSMIT ECHO
0033 UNIX, VMS, etc HELP SET SERVER says too much
0034 All READ and !READ too picky about line terminators
0035 All END from inside SWITCH doesn't work
0036 All Problem telnetting to multihomed hosts
0037 All Redirection failures in REMOTE xxx > file
REDIRECT was missing in many UNIX C-Kermit implementations; in version
7.0, it should be available in all of them.
_________________________________________________________________
1.1. Command Continuation
Comments that start with ";" or "#" can no longer be continued. In:
; this is a comment -
echo blah
the ECHO command will execute, rather than being taken as a
continuation of the preceding comment line. This allows easy
"commenting out" of commands from macro definitions.
However, the text of the COMMENT command can still be continued onto
subsequent lines:
comment this is a comment -
echo blah
As of version 6.0, backslash is no longer a valid continuation
character. Only hyphen should be used for command continuation. This
is to make it possible to issue commands like "cd a:\" on DOS-like
systems.
As of version 7.0:
* You can quote a final dash to prevent it from being a continuation
character:
echo foo\-
This prints "foo-". The command is not continued.
* You can enter commands such as:
echo foo - ; this is a comment
interactively and they are properly treated as continued commands.
Previously this worked only in command files.
_________________________________________________________________
1.2. Editor Interface
SET EDITOR name [ options ]
Lets you specify a text-editing program. The name can be a
fully specified pathname like /usr/local/bin/emacs19/emacs, or
it can be the name of any program in your PATH, e.g. "set
editor emacs". In VMS, it must be a DCL command like "edit",
"edit/tpu", "emacs", etc. If an environment variable EDITOR is
defined when Kermit starts, its value is the default editor.
You can also specify options to be included on the editor
command line. Returns to Kermit when the editor exits.
EDIT [ filename ]
If the EDIT command is given without a filename, then if a
previous filename had been given to an EDIT command, it is
used; if not, the editor is started without a file. If a
filename is given, the editor is started on that file, and the
filename is remembered for subsequent EDIT commands.
SHOW EDITOR
Displays the full pathname of your text editor, if any, along
with any command line options, and the file most recently
edited (and therefore the default filename for your next EDIT
command).
Related variables: \v(editor), \v(editopts), \v(editfile).
_________________________________________________________________
1.3. Web Browser and FTP Interface
C-Kermit includes an FTP command, which simply runs the FTP program;
C-Kermit does not include any built-in support for Internet File
Transfer Protocol, nor any method for interacting directly with an FTP
server. In version 7.0, however, C-Kermit lets you specify your FTP
client:
SET FTP-CLIENT [ name [ options ] ]
The name is the name of the FTP executable. In UNIX, Windows,
or OS/2, it can be the filename of any executable program in
your PATH (e.g. "ftp.exe" in Windows, "ftp" in UNIX); elsewhere
(or if you do not have a PATH definition), it must be the fully
specified pathname of the FTP program. If the name contains any
spaces, enclose it braces. Include any options after the
filename; these depend the particular ftp client.
The Web browser interface is covered in the following subsections.
_________________________________________________________________
1.3.1. Invoking your Browser from C-Kermit
BROWSE [ url ]
Starts your preferred Web browser on the URL, if one is given,
otherwise on the most recently given URL, if any. Returns to
Kermit when the browser exits.
SET BROWSER [ name [ options ] ]
Use this command to specify the name of your Web browser
program, for example: "set browser lynx". The name must be in
your PATH, or else it must be a fully specified filename; in
VMS it must be a DCL command.
SHOW BROWSER
Displays the current browser, options, and most recent URL.
Related variables: \v(browser), \v(browsopts), \v(browsurl).
Also see [350]Section 2.15: Contacting Web Servers with the HTTP
Command.
_________________________________________________________________
1.3.2. Invoking C-Kermit from your Browser
The method for doing this depends, of course, on your browser. Here
are some examples:
Netscape on UNIX (X-based)
In the Options->Applications section, set your Telnet
application to:
xterm -e /usr/local/bin/kermit/kermit -J %h %p
(replace "/usr/local/bin/kermit/kermit" by C-Kermit's actual
pathname). -J is C-Kermit's command-line option to "be like
Telnet"; %h and %p are Netscape placeholders for hostname and
port.
Lynx on UNIX
As far as we know, this can be done only at compile time. Add
the following line to the Lynx userdefs.h file before building
the Lynx binary:
#define TELNET_COMMAND "/opt/bin/kermit -J"
And then add lines like the following to the Lynx.cfg file:
DOWNLOADER:Kermit binary download:/opt/bin/kermit -i -V -s %s -a %s:TRUE
DOWNLOADER:Kermit text download:/opt/bin/kermit -s %s -a %s:TRUE
UPLOADER:Kermit binary upload:/opt/bin/kermit -i -r -a %s:TRUE
UPLOADER:Kermit text upload:/opt/bin/kermit -r -a %s:TRUE
UPLOADER:Kermit text get:/opt/bin/kermit -g %s:TRUE
UPLOADER:Kermit binary get:/opt/bin/kermit -ig %s:TRUE
But none of the above is necessary if you make C-Kermit your default
Telnet client, which you can do by making a symlink called 'telnet' to
the C-Kermit 7.0 binary. See [351]Section 9.1 for details.
_________________________________________________________________
1.4. Command Editing
Ctrl-W ("Word delete") was changed in 7.0 to delete back to the
previous non-alphanumeric, rather than all the way back to the
previous space.
_________________________________________________________________
1.5. Command Switches
As of version 7.0, C-Kermit's command parser supports a new type of
field, called a "switch". This is an optional command modifier.
1.5.1. General Switch Syntax
A switch is a keyword beginning with a slash (/). If it takes a value,
then the value is appended to it (with no intervening spaces),
separated by a colon (:) or equal sign (=). Depending on the switch,
the value may be a number, a keyword, a filename, a date/time, etc.
Examples:
send oofa.txt ; No switches
send /binary oofa.zip ; A switch without a value
send /protocol:zmodem oofa.zip ; A switch with a value (:)
send /protocol=zmodem oofa.zip ; A switch with a value (=)
send /text /delete /as-name:x.x oofa.txt ; Several switches
Like other command fields, switches are separated from other fields,
and from each other, by whitespace, as shown in the examples just
above. You can not put them together like so:
send/text/delete/as-name:x.x oofa.txt
(as you might do in VMS or DOS, or as we might once have done in
TOPS-10 or TOPS0-20, or PIP). This is primarily due to ambiguity
between "/" as switch introducer versus "/" as UNIX directory
separator; e.g. in:
send /delete/as-name:foo/text oofa.txt
Does "foo/text" mean the filename is "foo" and the transfer is to be
in text mode, or does it mean the filename is "foo/text"? Therefore we
require whitespace between switches to resolve the ambiguity. (That's
only one of several possible ambiguities -- it is also conceivable
that a file called "text" exists in the path "/delete/as-name:foo/").
In general, if a switch can take a value, but you omit it, then either
a reasonable default value is supplied, or an error message is
printed:
send /print:-Plaserwriter oofa.txt ; Value included = print options
send /print oofa.txt ; Value omitted, OK
send /mail:kermit@columbia.edu oofa.txt ; Value included = address
send /mail oofa.txt ; Not OK - address required
?Address required
Context-sensitive help (?) and completion (Esc or Tab) are available
in the normal manner:
C-Kermit> send /pr? Switch, one of the following:
/print /protocol
C-Kermit> send /pro<ESC>tocol:? File-transfer protocol,
one of the following:
kermit xmodem ymodem ymodem-g zmodem
C-Kermit> send /protocol:k<TAB>ermit
If a switch takes a value and you use completion on it, a colon (:) is
printed at the end of its name to indicate this. If it does not take a
value, a space is printed.
Also, if you type ? in a switch field, switches that take values are
shown with a trailing colon; those that don't take values are shown
without one.
_________________________________________________________________
1.5.2. Order and Effect of Switches
The order of switches should not matter, except that they are
evaluated from left to right, so if you give two switches with
opposite effects, the rightmost one is used:
send /text /binary oofa.zip ; Sends oofa.zip in binary mode.
Like other command fields, switches have no effect whatsoever until
the command is entered (by pressing the Return or Enter key). Even
then, switches affect only the command with which they are included;
they do not have global effect or side effects.
_________________________________________________________________
1.5.3. Distinguishing Switches from Other Fields
All switches are optional. A command that uses switches lets you give
any number of them, including none at all. Example:
send /binary oofa.zip
send /bin /delete oofa.zip
send /bin /as-name:mupeen.zip oofa.zip
send oofa.zip
But how does Kermit know when the first "non-switch" is given? It has
been told to look for both a switch and for something else, the data
type of the next field (filename, number, etc). In most cases, this
works well. But conflicts are not impossible. Suppose, for example, in
UNIX there was a file named "text" in the top-level directory. The
command to send it would be:
send /text
But C-Kermit would think this was the "/text" switch. To resolve the
conflict, use braces:
send {/text}
or other circumlocutions such as "send //text", "send /./text", etc.
The opposite problem can occur if you give an illegal switch that
happens to match a directory name. For example:
send /f oofa.txt
There is no "/f" switch (there are several switches that begin with
"/f", so "/f" is ambiguous). Now suppose there is an "f" directory in
the root directory; then this command would be interpreted as:
Send all the files in the "/f" directory, giving each one an
as-name of "oofa.txt".
This could be a mistake, or it could be exactly what you intended;
C-Kermit has no way of telling the difference. To avoid situations
like this, spell switches out in full until you are comfortable enough
with them to know the minimum abbreviation for each one. Hint: use ?
and completion while typing switches to obtain the necessary feedback.
_________________________________________________________________
1.5.4. Standard File Selection Switches
The following switches are used on different file-oriented commands
(such as SEND, DIRECTORY, DELETE, PURGE) to refine the selection of
files that match the given specification.
/AFTER:date-time
Select only those files having a date-time later than the one
given. See [352]Section 1.6 for date-time formats. Synonym:
/SINCE.
/NOT-AFTER:date-time
Select only those files having a date-time not later than (i.e.
earlier or equal to) the one given. Synonym: /NOT-SINCE.
/BEFORE:date-time
Select only those files having a date-time earlier than the one
given.
/NOT-BEFORE:date-time
Select only those files having a date-time not earlier than
(i.e. later or equal to) the one given.
/DOTFILES
UNIX and OS-9 only: The filespec is allowed to match files
whose names start with (dot) period. Normally these files are
not shown.
/NODOTFILES
(UNIX and OS-9 only) Don't show files whose names start with
dot (period). This is the opposite of /DOTFILES, and is the
default. Note that when a directory name starts with a period,
the directory and (in recursive operations) all its
subdirectories are skipped.
/LARGER-THAN:number
Only select files larger than the given number of bytes.
/SMALLER-THAN:number
Only select files smaller than the given number of bytes.
/EXCEPT:pattern
Specifies that any files whose names match the pattern, which
can be a regular filename, or may contain "*" and/or "?"
metacharacters (wildcards), are not to be selected. Example:
send /except:*.log *.*
sends all files in the current directory except those with a
filetype of ".log". Another:
send /except:*.~*~ *.*
sends all files except the ones that look like Kermit or EMACS
backup files (such as "oofa.txt.~17~") (of course you can also
use the /NOBACKUP switch for this).
The pattern matcher is the same one used by IF MATCH string
pattern ([353]Section 7.4), so you can test your patterns using
IF MATCH. If you need to match a literal * or ? (etc), precede
it by a backslash (\). If the pattern contains any spaces, it
must be enclosed in braces:
send /except:{Foo bar} *.*
The pattern can also be a list of up to 8 patterns. In this
case, the entire pattern must be enclosed in braces, and each
sub-pattern must also be enclosed in braces; this eliminates
the need for designating a separator character, which is likely
to also be a legal filename character on some platform or
other, and therefore a source of confusion. You may include
spaces between the subpatterns but they are not necessary. The
following two commands are equivalent:
send /except:{{ck*.o} {ck*.c}} ck*.?
send /except:{{ck*.o}{ck*.c}} ck*.?
If a pattern is to include a literal brace character, precede
it with "\". Also note the apparent conflict of this list
format and the string-list format described in [354]Section
4.9.1. In case you want to include a wildcard string-list with
braces on its outer ends as an /EXCEPT: argument, do it like
this:
send /except:{{{ckuusr.c,ckuus2.c,ckuus6.c}}} ckuus*.c
_________________________________________________________________
1.5.5. Setting Preferences for Different Commands
Certain oft-used commands offer lots of switches because different
people have different requirements or preferences. For example, some
people want to be able to delete files without having to watch a list
of the deleted files scroll past, while others want to be prompted for
permission to delete each file. Different people prefer different
directory-listing styles. And so on. Such commands can be tailored
with the SET OPTIONS command:
SET OPTIONS command [ switch [ switch [ ... ] ] ]
Sets each switch as the default for the given command,
replacing the "factory default". Of course you can also
override any defaults established by the SET OPTIONS command by
including the relevant switches in the affected command any
time you issue it.
SHOW OPTIONS
Lists the commands that allows option-setting, and the options
currently in effect, if any, for each. Switches that have
synonyms are shown under their primary name; for example. /LOG
and /VERBOSE are shown as /LIST.
Commands for which options may be set include DIRECTORY, DELETE,
PURGE, and TYPE. Examples:
SET OPTIONS DIRECTORY /PAGE /NOBACKUP /HEADING /SORT:DATE /REVERSE
SET OPTIONS DELETE /LIST /NOHEADING /NOPAGE /NOASK /NODOTFILES
SET OPTIONS TYPE /PAGE
Not necessarily all of a command's switches can be set as options. For
example, file selection switches, since these would normally be
different for each command.
Put the desired SET OPTIONS commands in your C-Kermit customization
file for each command whose default switches you want to change every
time you run C-Kermit.
_________________________________________________________________
1.6. Dates and Times
Some commands and switches take date-time values, such as:
send /after:{8-Feb-2000 10:28:01}
Various date-time formats are acceptable. The rules for the date are:
* The year must have 4 digits.
* If the year comes first, the second field is the month.
* The day, month, and year may be separated by spaces, /, -, or
underscore.
* The month may be numeric (1 = January) or spelled out or
abbreviated in English.
If the date-time string contains any spaces, it must be enclosed in
braces. Examples of legal dates:
Interpretation:
2000-Feb-8 8 February 2000
{2000 Feb 8} 8 February 2000
2000/Feb/8 8 February 2000
2000_Feb_8 8 February 2000
2000-2-8 8 February 2000
2000-02-08 8 February 2000
8-Feb-2000 8 February 2000
08-Feb-2000 8 February 2000
12/25/2000 25 December 2000
25/12/2000 25 December 2000
The last two examples show that when the year comes last, and the
month is given numerically, the order of the day and month doesn't
matter as long as the day is 13 or greater (mm/dd/yyyy is commonly
used in the USA, whereas dd/mm/yyyy is the norm in Europe). However:
08/02/2000 Is ambiguous and therefore not accepted.
If a date is given, the time is optional and defaults to 00:00:00. If
the time is given with a date, it must follow the date, separated by
space, /, -, or underscore, and with hours, minutes, and seconds
separated by colon (:). Example:
2000-Feb-8 10:28:01 Represents 8 February 2000, 10:28:01am
If a date is not given, the current date is used and a time is
required.
Time format is hh:mm:ss or hh:mm or hh in 24-hour format, or followed
by "am" or "pm" (or "AM" or "PM") to indicate morning or afternoon.
Examples of times that are acceptable:
Interpretation:
3:23:56 3:23:56am
3:23:56am 3:23:56am
3:23:56pm 3:23:56pm = 15:23:56
15:23:56 3:23:56pm = 15:23:56
3:23pm 3:23:00pm = 15:23:00
3:23PM 3:23:00pm = 15:23:00
3pm 3:00:00pm = 15:00:00
Examples of legal date-times:
send /after:{8 Feb 2000 10:28:01}
send /after:8_Feb_2000_10:28:01
send /after:8-Feb-2000/10:28:01
send /after:2000/02/08/10:28:01
send /after:2000/02/08_10:28:01
send /after:2000/02/08_10:28:01am
send /after:2000/02/08_10:28:01pm
send /after:2000/02/08_10:28pm
send /after:2000/02/08_10pm
send /after:10:00:00pm
send /after:10:00pm
send /after:10pm
send /after:22
Finally, there is a special all-numeric format you can use:
yyyymmdd hh:mm:ss
For example:
20000208 10:28:01
This is Kermit's standard date-time format (based on ISO 8601), and is
accepted (among other formats) by any command or switch that requires
a date-time, and is output by any function whose result is a calendar
date-time.
There are no optional parts to this format and it must be exactly 17
characters long, punctuated as shown (except you can substitute
underscore for space in contexts where a single "word" is required).
The time is in 24-hour format (23:00:00 is 11:00pm). This is the
format returned by \fdate(filename), so you can also use constructions
like this:
send /after:\fdate(oofa.txt)
which means "all files newer than oofa.txt".
Besides explicit dates, you can also use the any of the following
shortcuts:
TODAY
Stands for the current date at 00:00:00.
TODAY 12:34:56
Stands for the current date at the given time.
YESTERDAY
Stands for yesterday's date at 00:00:00. A time may also be
given.
TOMORROW
Stands for tomorrow's date at 00:00:00. A time may also be
given.
+ number { DAYS, WEEKS, MONTHS, YEARS } [ time ]
Is replaced by the future date indicated, relative to the
current date. If the time is omitted, 00:00:00 is used.
Examples: +3days, +2weeks, +1year, +37months.
- number { DAYS, WEEKS, MONTHS, YEARS } [ time ]
Is replaced by the past date indicated, relative to the current
date. If the time is omitted, 00:00:00 is used.
The time can be separated from the date shortcut by any of the same
separators that are allowed for explicit date-times: space, hyphen,
slash, period, or underscore. In switches and other space-delimited
fields, use non-spaces to separate date/time fields, or enclose the
date-time in braces, e.g.:
purge /before:-4days_12:00:00
purge /before:{- 4 days 12:00:00}
Of course you can also use variables:
define \%n 43
purge /before:-\%ndays_12:00:00
Shortcut names can be abbreviated to any length that still
distinguishes them from any other name that can appear in the same
context, e.g. "TOD" for today, "Y" for yesterday. Also, the special
abbreviation "wks" is accepted for WEEKS, and "yrs" for "YEARS".
(To see how to specify dates relative to a specific date, rather than
the current one, see the [355]\fmjd() function description below.)
You can check date formats with the DATE command. DATE by itself
prints the current date and time in standard format: yyyymmdd
hh:mm:ss. DATE followed by a date and/or time (including shortcuts)
converts it to standard format if it can understand it, otherwise it
prints an error message.
The following variables and functions deal with dates and times; any
function argument designated as "date-time" can be in any of the
formats described above.
\v(day)
The first three letters of the English word for the current day
of the week, e.g. "Wed".
\fday(date-time)
The first three letters of the English word for day of the week
of the given date. If a time is included, it is ignored.
Example: \fday(8 Feb 1988) = "Mon".
\v(nday)
The numeric day of the week: 0 = Sunday, 1 = Monday, ..., 6 =
Saturday.
\fnday(date-time)
The numeric day of the week for the given date. If a time is
included, it is ignored. Example: \fnday(8 Feb 1988) = "1".
\v(date)
The current date as dd mmm yyyy, e.g. "08 Feb 2000" (as in this
example, a leading zero is supplied for day-of-month less than
10).
\v(ndate)
The current date in numeric format: yyyymmdd, e.g. "20000208".
\v(time)
The current time as hh:mm:ss, e.g. "15:27:14".
\ftime(time)
The given free-format date and/or time (e.g. "3pm") returns the
time (without the date) converted to hh:mm:ss 24-hour format,
e.g. "15:00:00" (the date, if given, is ignored).
\v(ntime)
The current time as seconds since midnight, e.g. "55634".
\v(tftime)
The elapsed time of the most recent file-transfer operation in
seconds.
\v(intime)
The elapsed time for the most recent INPUT command to complete,
in milliseconds.
\fntime(time)
The given free-format date and/or time is converted to seconds
since midnight (the date, if given, is ignored). This function
replaces \ftod2secs(), which is now a synonym for \fntime().
Unlike \ftod2secs(), \fntime() allows a date to be included,
and it allows the time to be in free format (like 3pm), and it
allows the amount of time to be more than 24 hours. E.g.
\fntime(48:00:00) = 172800. Example of use:
set alarm \fntime(48:00:00) ; set alarm 48 hours from now.
\fn2time(seconds)
The given number of seconds is converted to hh:mm:ss format.
\fdate(filename)
Returns the modification date-time of the given file in
standard format: yyyymmdd hh:mm:ss.
\fcvtdate(date-time)
Converts a free-format date and/or time to Kermit standard
format: yyyymmdd hh:mm:ss. If no argument is given, returns the
current date-time in standard format. If a date is given but no
time, the converted date is returned without a time. If a time
is given with no date, the current date is supplied. Examples:
\fcvtdate(4 Jul 2000 2:21:17pm) = 20000704 14:21:17
\fcvtdate() = 20000704 14:21:17 (on 4 Jul 2000 at 2:21:17pm).
\fcvtd(4 Jul 2000) = 20000704
\fcvtd(6pm) = 20000704 18:00:00 (on 4 Jul 2000 at 6:00pm).
\fdayofyear(date-time)
\fdoy(date-time)
Converts a free-format date and/or time to yyyyddd, where ddd
is the 3-digit day of the year, and 1 January is Day 1. If a
time is included with the date, it is returned in standard
format. If a date is included but no time, the date is returned
without a time. If a time is given with no date, the time is
converted and the current date is supplied. If no argument is
given, the current date-time is returned. Synonym: \fdoy().
Examples:
\fddayofyear(4 Jul 2000 2:21:17pm) = 2000185 14:21:17
\fdoy() = 2000185 14:21:17 (on 4 Jul 2000 at 2:21:17pm).
\fdoy(4 Jul 2000) = 2000185
\fdoy(6pm) = 2000185 18:00:00 (on 4 Jul 2000 at 6:00pm).
Note: The yyyyddd day-of-year format is often erroneously referred to
as a Julian date. However, a true Julian date is a simple counting
number, the number of days since a certain fixed day in the past.
[356]See \fmjd() below.
\fdoy2date(date-time)
Converts a date or date-time in day-of-year format to a
standard format date. A yyyyddd-format date must be supplied;
time is optional. The given date is converted to yyyymmdd
format. If a time is given, it is converted to 24-hour format.
Examples:
\fdoy2date(2000185) = 20000704
\fdoy2(2000185 3pm) = 20000704 15:00:00
\fmjd(date-time)
Converts free-format date and/or time to a Modified Julian Date
(MJD), the number of days since 17 Nov 1858 00:00:00. If a time
is given, it is ignored. Examples:
\fmjd(4 Jul 2000) = 50998
\fmjd(17 Nov 1858) = 0
\fmjd(16 Nov 1858) = -1
\fmjd2date(mjd)
Converts an MJD (integer) to standard date format, yyyymmdd:
\fmjd2(50998) = 4 Jul 1998
\fmjd2(0) = 17 Nov 1858
\fmjd2(-1) = 16 Nov 1858
\fmjd2(-365) = 17 Nov 1857
MJDs are normal integers and, unlike DOYs, may be added, subtracted,
etc, with each other or with other integers, to obtain meaningful
results. For example, to find out the date 212 days ago:
echo \fmjd2date(\fmjd()-212)
Constructions such as this can be used in any command where a
date-time is required, e.g.:
send /after:\fmjd2date(\fmjd()-212)
to send all files that are not older than 212 days (this is equivalent
to "send /after:-212days").
MJDs also have other regularities not exhibited by other date formats.
For example, \fmodulus(\fmjd(any-date),7) gives the day of the week
for any date (where 4=Sun, 5=Mon, ..., 3=Sat). (However, it is easier
to use \fnday() for this purpose, and it gives the more conventional
result of 0=Sun, 1=Mon, ..., 6=Sat).
Note that if MJDs are to be compared, they must be compared
numerically (IF <, =, >) and not lexically (IF LLT, EQUAL, LGT),
whereas DOYs must be compared lexically if they include a time (which
contains ":" characters); however, if DOYs do not include a time, they
may also be compared numerically.
In any case, lexical comparison of DOYs always produces the
appropriate result, as does numeric comparison of MJDs.
The same comments apply to sorting. Also note that DOYs are fixed
length, but MJDs can vary in length. However, all MJDs between 3 April
1886 and 30 Aug 2132 are 5 decimal digits long. (MJDs become 6 digits
long on 31 Aug 2132, and 7 digits long on 13 Oct 4596).
_________________________________________________________________
1.7. Partial Completion of Keywords
Partial completion of keywords was added in C-Kermit 7.0. In prior
versions, if completion was attempted (by pressing the Esc or Tab key)
on a string that matched different keywords, you'd just get a beep.
Now Kermit completes up to the first character where the possibly
matching keywords differ and then beeps. For example:
C-Kermit> send /n<Tab>
which matches /NOT-BEFORE and /NOT-AFTER, now completes up to the
dash:
C-Kermit> send /n<Tab>ot-<Beep>
Partial completion works for filenames too (as it has for some years).
_________________________________________________________________
1.8. Command Recall
C-Kermit has had a command history buffer for some time, which could
be scrolled interactively using control characters or (in Kermit 95
only) arrow keys. Version 7.0 adds a REDO command that allows the most
recent command matching a given pattern to be re-executed:
{ REDO, RR, ^ } [ pattern ]
Search the command history list for the most recent command
that matches the given pattern, and if one is found, execute it
again.
The pattern can be a simple string (like "send"), in which case the
last SEND command is re-executed. Or it can contain wildcard
characters "*" and/or "?", which match any string and any single
character, respectively (note that "?" must be preceded by backslash
to override its normal function of giving help), and in most C-Kermit
versions may also include [] character lists and {} string lists (see
[357]Section 4.9).
The match works by appending "*" to the end of the given pattern (if
you didn't put one there yourself). Thus "redo *oofa" becomes "redo
*oofa*" and therefore matches the most recent command that contains
"oofa" anywhere within the command. If you want to inhibit the
application of the trailing "*", e.g. to force matching a string at
the end of a command, enclose the pattern in braces:
redo {*oofa}
matches the most recent command that ends with "oofa".
REDO commands themselves are not entered into the command history
list. If no pattern is given, the previous (non-REDO) command is
re-executed. The REDOne command is reinserted at the end of the
command history buffer, so the command scrollback character (Ctrl-P,
Ctrl-B, or Uparrow) can retrieve it.
Examples:
C-Kermit> echo foo
foo
C-Kermit> show alarm
(no alarm set)
C-Kermit> echo blah
blah
C-Kermit> redo ; Most recent command
blah
C-Kermit> redo s ; Most recent command starting with "s"
(no alarm set)
C-Kermit> redo echo f ; Most recent command starting with "echo f"
foo
C-Kermit> redo *foo ; Most recent command that has "foo" in it
foo
C-Kermit> <Ctrl-P> ; Scroll back
C-Kermit> echo foo ; The REDOne command is there
C-Kermit> redo {*foo} ; Most recent command that ends with "foo"
foo
C-Kermit>
Since REDO, REDIAL, and REDIRECT all start the same way, and RED is
the designated non-unique abbreviation for REDIAL, REDO must be
spelled out in full. For convenience, RR is included as an invisible
easy-to-type synonym for REDO. You can also use the "^" character for
this:
C-Kermit> ^ ; Most recent command
C-Kermit> ^ s ; Most recent command starting with "s"
C-Kermit> ^s ; Ditto (space not required after "^").
C-Kermit> ^*foo ; Most recent command that has "foo" in it.
C-Kermit> ^{*foo} ; Most recent command ends with "foo".
Unlike the manual command-history-scrolling keys, the REDO command can
be used in a script, but it's not recommended (since the command to be
REDOne might not be found, so if the REDO command fails, you can't
tell whether it was because REDO failed to find the requested command,
or because the command was found but it failed).
_________________________________________________________________
1.9. EXIT Messages
The EXIT and QUIT commands now accept an optional message to be
printed. This makes the syntax of EXIT and QUIT just like END and
STOP:
{ EXIT, QUIT, END, STOP } [ status-code [ message ] ]
where status-code is a number (0 indicating success, nonzero
indicating failure). This is handy in scripts that are never supposed
to enter interactive mode:
dial 7654321
if fail exit 1 Can't make connection - try again later.
Previously this could only be done in two steps:
dial 7654321
xif fail { echo Can't make connection - try again later, exit 1 }
A status code must be included in order to specify a message. In the
case of EXIT and QUIT, the default status code is contained in the
variable \v(exitstatus), and is set automatically by various events
(file transfer failures, etc; it can also be set explicitly with the
SET EXIT STATUS command). If you want to give an EXIT or QUIT command
with a message, but without changing the exit status from what it
normally would have been, use the \v(exitstatus) variable, e.g.:
exit \v(existatus) Goodbye from \v(cmdfile).
The EXIT status is returned to the system shell or whatever other
process invoked C-Kermit, e.g. in UNIX:
C-Kermit> exit 97 bye bye
bye bye
$ echo $?
97
$
_________________________________________________________________
1.10. Managing Keyboard Interruptions
When C-Kermit is in command or file-transfer mode (as opposed to
CONNECT mode), it can be interrupted with Ctrl-C. Version 7.0 adds the
ability to disarm the Ctrl-C interrupt:
SET COMMAND INTERRUPT { ON, OFF }
COMMAND INTERRUPT is ON by default, meaning the Ctrl-C can be
used to interrupt a command or a file transfer in progress. Use
OFF to disable these interruptions, and use it with great
caution for obvious reasons.
SET TRANSFER INTERRUPT { ON, OFF }
This can be used to disable keyboard interruption of file
transfer when C-Kermit is in local mode, or to re-enable it
after it has been disabled. This applies to the X, Z, E, and
similar keys as well as to the system interrupt character,
usually Ctrl-C. This is distinct from SET TRANSFER
CANCELLATION, which tells whether packet mode can be exited by
sending a special sequence of characters.
Several other commands can be interrupted by pressing any key while
they are active. Version 7.0 adds the ability to disable this form of
interruption also:
SET INPUT CANCELLATION { ON, OFF }
Whether an INPUT command in progress can be interrupted by
pressing a key. Normally ON. Setting INPUT CANCELLATION OFF
makes INPUT commands uninterruptible except by Ctrl-C (unless
COMMAND INTERRUPTION is also OFF).
SET SLEEP CANCELLATION { ON, OFF }
Whether a SLEEP, PAUSE, or WAIT command in progress can be
interrupted by pressing a key. Normally ON. Setting SLEEP
CANCELLATION OFF makes these commands uninterruptible except by
Ctrl-C (unless COMMAND INTERRUPTION is also OFF). Synonyms: SET
PAUSE CANCELLATION, SET WAIT CANCELLATION.
So to make certain a script is not interruptible by the user, include
these commands:
SET TRANSFER INTERRUPT OFF
SET SLEEP CANCELLATION OFF
SET INPUT CANCELLATION OFF
SET COMMAND INTERRUPTION OFF
Make sure to turn them back on afterwards if interruption is to be
re-enabled.
When a PAUSE, SLEEP, WAIT, or INPUT command is interrupted from the
keyboard, the new variable \v(kbchar) contains a copy of the (first)
character that was typed and caused the interruption, provided it was
not the command interrupt character (usually Ctrl-C). If these
commands complete successfully or time out without a keyboard
interruption, the \v(kbchar) variable is empty.
The \v(kbchar) variable (like any other variable) can be tested with:
if defined \v(kbchar) command
The command is executed if the variable is not empty.
The \v(kbchar) variable can be reset with WAIT 0 (PAUSE 0, SLEEP 0,
etc).
_________________________________________________________________
1.11. Taming The Wild Backslash -- Part Deux
[358]Using C-Kermit, 2nd Edition, contains a brief section, "Taming
the Wild Backslash", on page 48, which subsequent experience has shown
to be inadequate for Kermit users intent on writing scripts that deal
with Windows, DOS, and OS/2 filenames, in which backslash (\) is used
as the directory separator. This section fills in the blanks.
1.11.1. Background
The Kermit command language shares a certain unavoidable but annoying
characteristic with most other command languages that are capable of
string replacement, namely the necessity to "quote" certain characters
when you want them to be taken literally. This is a consequence of the
facts that:
1. One or more characters must be set aside to denote replacement,
rather than acting as literal text.
2. We have only 96 printable characters to work with in ASCII, which
is still the only universally portable character set.
3. There is no single printable character that is unused everywhere.
4. Variables are not restricted to certain contexts, as they are in
formal programming languages like C and Fortran, but can appear
anywhere at all within a command, and therefore require special
syntax.
Thus there can be conflicts. To illustrate, the standard UNIX shell
uses dollar sign ($) to introduce variables. So the shell command:
echo $TERM
displays the value of the TERM variable, e.g. vt320. But suppose you
want to display a real dollar sign:
echo The price is $10.20
This causes the shell to evaluate the variable "$1", which might or
might not exist, and substitute its value, e.g.:
The price is 0.20
(in this case the $1 variable had no value.) This is probably not what
you wanted. To force the dollar sign to be taken literally, you must
apply a "quoting rule", such as "precede a character by backslash (\)
to force the shell to take the character literally":
echo The price is \$10.20
The price is $10.20
But now suppose you want the backslash AND the dollar sign to be taken
literally:
echo The price is \\$10.20
This doesn't work, since the first backslash quotes the second one,
thereby leaving the dollar sign unquoted again:
The price is \0.20
Quoting the dollar sign requires addition of a third backslash:
echo The price is \\\$10.20
The price is \$10.20
The first backslash quotes the second one, and the third backslash
quotes the dollar sign.
Every command language -- all UNIX shells, VMS DCL, DOS Batch, AOS/VS
CLI, etc etc -- has similar rules. UNIX shell rules are probably the
most complicated, since many printable characters -- not just one --
are special there: dollar sign, single quote, double quote, backslash,
asterisk, accent grave, number sign, ampersand, question mark,
parentheses, brackets, braces, etc -- practically every
non-alphanumeric character needs some form of quoting if it is to be
taken literally. And to add to the confusion, the UNIX shell offers
many forms of quoting, and many alternative UNIX shells are available,
each using slightly different syntax.
_________________________________________________________________
1.11.2. Kermit's Quoting Rules
Kermit's basic quoting rules are simple by comparison (there are, of
course, additional syntax requirements for macro definitions, command
blocks, function calls, etc, but they are not relevant here).
The following characters are special in Kermit commands:
Backslash (\)
Introduces a variable, or the numeric representation of a
special character, or a function, or other item for
substitution. If the backslash is followed by a digit or by any
of the following characters:
x, o, d, m, s, f, v, $, %, &, :, {
this indicates a special substitution item; otherwise the
following character is to be taken literally (exceptions: \ at
end of line is taken literally; \n, \b, and \n are special
items in the OUTPUT command only).
Semicolon (;)
(Only when at the beginning of a line or preceded by at least
one space or tab) Introduces a comment.
Number sign (#)
(Only when at the beginning of a line or preceded by at least
one space or tab) Just like semicolon; introduces a comment.
Question mark (?)
(Only at the command prompt - not in command files or macros)
Requests context-sensitive help.
To force Kermit to take any of these characters literally, simply
precede it by a backslash (\).
Sounds easy! And it is, except when backslash also has a special
meaning to the underlying operating system, as it does in DOS,
Windows, and OS/2, where it serves as the directory separator in
filenames such as:
D:\K95\KEYMAPS\READ.ME
Using our rule, we would need to refer to this file in Kermit commands
as follows:
D:\\K95\\KEYMAPS\\READ.ME
But this would not be obvious to new users of Kermit software on DOS,
Windows, or OS/2, and it would be annoying to seasoned ones. Thus
MS-DOS Kermit and Kermit 95 go to rather extreme lengths to allow the
more natural notation, as in:
send d:\k95\keymaps\read.me
The reason this is tricky is that we also need to allow for variables
and other expressions introduced by backslash in the same command. For
example, suppose \%a is a variable whose value is "oofa" (without the
quotes). What does the following command do?
send d:\%a
Does it send the file named "oofa" in the current directory of the D:
disk, or does it send a file named "%a" in the root directory of the
D: disk? This is the kind of trouble we get into when we attempt to
bend the rules in the interest of user friendliness. (The answer is:
if the variable \%a has definition that is the name of an existing
file, that file is sent; if a file d:\%a exists, it is sent; otherwise
if both conditions are true, the variable takes precedence, and the
literal filename can be forced by quoting: \\%a.)
In Kermit 95 (but not MS-DOS Kermit), we also bend the rules another
way by allowing you to use forward slash (/) rather than backslash (\)
as the directory separator:
send d:/k95/keymaps/read.me
This looks more natural to UNIX users, and in fact is perfectly
acceptable to the Windows 95/98/NT and OS/2 operating systems on the
API level. BUT (there is always a "but") the Microsoft shell,
COMMAND.COM, for Windows 95/98 and NT does not allow this notation,
and therefore it can not be used in any Kermit command -- such as RUN
-- that invokes the Windows command shell AND your command shell is
COMMAND.COM or any other shell that does not allow forward slash as
directory separator (some alternative shells do allow this).
NOTE: There exists a wide variety of alternative shells from third
parties that do not have this restriction. If you are using a shell
that accepts forward slash as a directory separator, you can stop
reading right now -- UNLESS (there is always an "unless") you want
your scripts to be portable to systems that have other shells. Also
note that some Windows shells might actually REQUIRE forward
slashes (instead of backslashes) as directory separators; we do not
treat this situation below, but the treatment is obvious -- use
slash rather backslash as the directory separator.
_________________________________________________________________
1.11.3. Passing DOS Filenames from Kermit to Shell Commands
The following Kermit commands invoke the system command shell:
RUN (and its synonyms ! and @)
REDIRECT
PIPE
Each of these commands takes a shell command as an operand. These
shell commands are not, and can not be, parsed by Kermit since Kermit
does not know the syntax of shell commands, and so can't tell the
difference between a keyword, a filename, a variable, a switch, or
other item. Therefore the rules can not be bent since Kermit doesn't
know where or how to bend them. To illustrate (using the regular
Windows shell):
run c:\\windows\\command\\chkdsk.exe
works OK, but:
run c:/windows/command/chkdsk.exe
is not accepted by COMMAND.COM. But:
run c:\windows\command\chkdsk.exe
results in Kermit applying its quoting rules before sending the text
to the shell. Since "w" and "c" are not in the list of backslash-item
codes, the backslash means "take the following character literally".
Thus, by the time this filename gets to the Windows shell, it has
become:
c:windowscommandchkdsk.exe
which is probably not what you wanted. (If "w" and "c" were in the
list, the results could be even stranger.) Even more confusing is the
case where a directory or filename starts with one or more digits:
run c:\123\lotus.exe
in which "\123" is the Kermit notation for ASCII character 123, which
happens to be left brace ({), resulting in "c:{lotus.exe".
So when passing filenames to a Windows shell, always use double
backslashes as directory separators, to ensure that the shell gets
single backslashes:
run c:\\windows\\command\\chkdsk.exe
run c:\\123\\lotus.exe
Similar problems might occur with the built-in EDIT, BROWSE, and FTP
commands. These commands result in Kermit building a shell command
internally to invoke the associated helper program; the form of this
command might conflict with the form demanded by certain alternative
shells.
_________________________________________________________________
1.11.4. Using Variables to Hold DOS Filenames
Now to the next level. Suppose you want to write a script in which
filenames are parameters, and therefore are stored in variables.
Example:
define \%f c:\windows\command\chkdsk.exe
...
run \%f
Obviously this won't work for the reasons just noted; the RUN command
requires directory separators be coded as double backslashes:
define \%f c:\\windows\\command\\chkdsk.exe
...
run \%f
This will work; no surprises here. However, if you had used ASSIGN
rather than DEFINE, you might have been surprised after all; review
pages 348-349 of [359]Using C-Kermit (2nd Ed) for the difference
between DEFINE and ASSIGN.
We have said that any Kermit 95 or MS-DOS Kermit command that parses
filenames itself -- SEND, for example -- does not require double
backslashes since it knows it is parsing a filename. So since the
following works:
send c:\windows\command\chkdsk.exe
Should the following also work?
define \%f c:\windows\command\chkdsk.exe
...
send \%f
Answer: No. Why? Because \%f is evaluated "recursively", to allow for
the possibility that its definition contains further variable
references. This is true of all "backslash-percent-letter" (or -digit)
variables, and also for array references. So \%f becomes
c:\windows\command\chkdsk.exe, which becomes
c:windowscommandchkdsk.exe.
The trick here is to use the "other" kind of variable, that is
evaluated only "one level deep" rather than recursively:
define filename c:\windows\command\chkdsk.exe
...
send \m(filename)
Similarly if you want to prompt the user for a filename:
ask filename { Please type a filename: }
Please type a filename: c:\windows\command\chkdsk.exe
send \m(filename)
_________________________________________________________________
1.11.5. Passing DOS Filenames as Parameters to Macros
Suppose you want to pass a DOS filename containing backslashes as a
parameter to a Kermit macro. This raises two issues:
1. Parameters to macros are "just text" and so are fully evaluated
before they are passed to the macro.
2. Once inside the macro, the formal parameters \%1, \%2, ... \%9 are
the type of variable that is evaluated recursively.
Thus a DOS filename is ruined once in the act of parsing the macro
invocation, and again when referring to it from within the macro. To
illustrate, suppose "test" is a macro. Then in the invocation:
test c:\mydir\blah.txt
"c:mydirblah.txt" is assigned to \%1. However, if we double the
backslashes:
test c:\\mydir\\blah.txt
"c:\mydir\blah.txt" is assigned to \%1. But then when you refer to \%1
in the macro, it is evaluated recursively, resulting in
"c:mydirblah.txt". To illustrate:
define test echo \%1
test c:\mydir\blah.txt
c:mydirblah.txt
test c:\\mydir\\blah.txt
c:mydirblah.txt
test c:\\\\mydir\\\\blah.txt
c:\mydir\blah.txt
Let's address each part of the problem separately. First, inside the
macro. You can use the \fcontents() function to force a
backslash-percent variable (such as a macro argument) to be evaluated
one level deep instead of recursively, for example:
define test echo { The filename is "\fcontents(\%1)"}
test c:\mydir\blah.txt ; We don't expect this to work
The filename is "c:mydirblah.txt" ; and it doesn't.
test c:\\mydir\\blah.txt ; But this does...
The filename is "c:\mydir\blah.txt"
Thus if the filename arrives inside the macro with single backslashes,
the backslashes are preserved if you always refer to the parameter
through the \fcontents() function.
Now how to ensure that backslashes are not stripped or misinterpreted
when passing a filename to a macro? This brings us back to what we
learned in earlier sections:
1. If it is a literal filename, either double the backslashes, or (if
the filename is to be used only within Kermit itself and not
passed to a DOS shell, or it is to be passed to an alternative
shell that accepts forward slash as a directory separator), use
forward slash instead of backslash as the directory separator.
2. If it is a variable that contains a filename, make sure you use a
macro-style variable name, rather than a
backslash-percent-character name.
Examples:
define test echo \fcontents(\%1)
define filename c:\mydir\blah.txt
test c:\\mydir\\blah.txt ; Literal filename with double backslashes
c:\mydir\blah.txt
test c:/mydir/blah.txt ; Literal filename with forward slashes
c:/mydir/blah.txt
test \m(filename) ; Variable
c:\mydir\blah.txt
But what if you don't like these rules and you still want to pass a
literal filename containing single backslashes to a macro? This is
possible too, but a bit tricky: turn command quoting off before
invoking the macro, and then turn it back on inside the macro.
Example:
define test set command quoting on, echo \fcontents(\%1)
set command quoting off
test c:\mydir\blah.txt
c:\mydir\blah.txt
Upon return from the macro, command quoting is back on (since the
macro turned it on).
Obviously this trick can not be used if the filename is stored in a
variable, since it prevents the variable from being evaluated.
_________________________________________________________________
1.11.6. Passing DOS File Names from Macro Parameters to the DOS Shell
Now suppose you need to pass a DOS filename to a macro, and the macro
needs to pass it, in turn, to the Windows shell via (say) Kermit's RUN
command. This works too:
define xrun run \fcontents(\%1)
xrun c:\\windows\\command\\chkdsk.exe
(or you can use the SET COMMAND QUOTING OFF / ON technique described
above to avoid the double backslashes.) But..
xrun c:/windows/command/chkdsk.exe
does not work if the Windows shell does not recognize "/" as a
directory separator. If there is a chance that a filename might be
passed to the macro in this form, the macro will need to convert it to
a form acceptable to the shell:
define xrun run \freplace(\fcontents(\%1),/,\\)
Here we replace all occurrences (if any) of "/" in the argument with
"\" prior to issuing the RUN command. Of course, in order to specify
"\" as a literal character in the \freplace() argument list, we have
to double it.
_________________________________________________________________
1.11.7. Passing DOS Filenames to Kermit from the Shell
As noted in the manual, the \&@[] array contains Kermit's command-line
arguments. Suppose one of these arguments, say \&@[3], is a DOS
filename such as C:\FOO\BAR\BAZ\OOFA.TXT. (Note: In C-Kermit 7.0 and
K95 1.1.18 and later, command-line arguments after "=" or "--" are
also available in the top-level \%1..9 variables; see [360]Section
7.5.)
Of course you can eliminate any problems by using forward slashes
rather than backslashes in the filename, but sometimes this is not
possible, as when the Kermit command line is being generated by
another program than can only generate "native" format DOS filenames.
As noted in the manual, "\%x" variables and \&x[] arrays are always
evaluated "all the way" (recursively). If the contents of one of these
variables contains backslashes, this causes another level of
evaluation.
There is another kind of variable, which is evaluated only "one level
deep". You can use this to prevent interpretation of the backslashes
in the filenames. Example:
assign filename \fcontents(\&@[3]) ; Transfer contents
...
send \m(filename)
Or, more simply:
send \fcontents(\&@[3])
_________________________________________________________________
1.12. Debugging
The debug log is produced when you give a "log debug" command. This is
normally done at the request of the Kermit help desk, for forwarding
to the Kermit developers for analysis as a last resort in
troubleshooting problems. (Last resort because it can grow quite huge
in a very short time.) In cases where timing information is critical
to understanding a problem, you can tell C-Kermit to put a timestamp
on each debug log line by giving the command:
SET DEBUG TIMESTAMP ON
At any time before or after activating the debug log (SET DEBUG
TIMESTAMP OFF turns off timestamping). Timestamps can be turned off
and on as desired while logging. Obviously, they increase the size and
growth rate of the log significantly, and so should be used sparingly.
Timestamps are of the form hh:mm:ss.xxx, where .xxx is thousands of a
second (but is included only on platforms that include this feature).
_________________________________________________________________
1.13. Logs
In UNIX C-Kermit and in K-95, you can now direct any log to a pipe.
This not only lets you send your logs to places other than disk files,
but also lets you customize them to any desired degree.
LOG { DEBUG, PACKETS, SESSION, TRANSACTION, CONNECTION } { file, pipe
} ...
A "pipe" is the name of a command, preceded by a vertical bar.
If the pipe contains any spaces, it must be enclosed in braces.
Here are some examples for UNIX (always remember the importance of
getting the UNIX shell quoting rules right):
LOG TRANSACTIONS |lpr
This sends the transaction log to the default UNIX printer,
rather than to a file (use "lp" rather than "lpr" if
necessary).
LOG TRANSACTIONS {| myfilter > t.log}
For those who don't like the format of the transaction log, or
want to extract certain information from it; write your own
output filter.
LOG SESSION {| lpr -Plaserwriter}
This sends the session log to a specific UNIX printer, rather
than to a file. Note the braces around the pipeline. These are
required because it contains spaces.
LOG DEBUG {| tail -100 > debug.log}
This causes the debug log file to contain only the final 100
lines. Suppose C-Kermit crashes under some unpredictable
circumstances, and you need a debug log to catch it in the act.
But the debug log can grow to huge proportions very quickly,
possibly filling up the disk. Piping the debug log through
"tail" results in keeping only the last 100 lines (or other
number of your choice).
LOG DEBUG {| grep "^TELNET" > debug.log}
This one shows how to log only Telnet negotiations. Piping the
debug log through grep or egrep lets you log only specific
information, rather than everything. "man grep" for further
info.
LOG DEBUG {| gzip -c > debug.log.gz}
Creates a full debug log, but compressed by gzip to save space.
LOG PACKETS {| tr "\\01" "X" | cut -c9- > packet.log}
This one writes the regular packet log, but translates the
Ctrl-A that starts each packet to the letter "X" and removes
the s-nn-nn- notation from the beginning of each line. Note the
double backslash (normal Kermit quoting rules). "man tr" and
"man cut" for further info.
See [361]Section 2.12 for information about the new connection log.
_________________________________________________________________
1.14. Automatic File-Transfer Packet Recognition at the Command Prompt
Beginning in version 7.0, C-Kermit can recognize Kermit (and in some
cases also Zmodem) file-transfer packets while at its command prompt.
This is convenient (for example), if you escaped back from a remote
Kermit program and told the local Kermit program to send a file, but
forgot to tell the remote Kermit program to receive it (and the local
Kermit did not have the "send a Kermit receive command" feature
available). This feature is controlled by the following command:
SET COMMAND AUTODOWNLOAD { ON, OFF }
When ON, which is the default, the command parser recognizes
Kermit packets when Kermit is in remote mode. An S packet makes
it go into receive mode, an I packet makes it go into server
mode. When OFF, packet recognition is disabled and the behavior
when a packet is received at the command prompt is as it was in
C-Kermit 6.1 and earlier (namely to print an error message).
COMMAND AUTODOWNLOAD is the command-mode equivalent of TERMINAL
AUTODOWNLOAD, which is effective during CONNECT mode.
_________________________________________________________________
1.15. The TYPE Command
The TYPE command now accepts a selection of optional switches
([362]Section 1.5), and also sets several variables.
Syntax: TYPE [ switches... ] filename
Variables:
\v(ty_ln)
Line number of current line (during TYPE command; see /PREFIX)
\v(ty_lc)
Line count of file most recently TYPEd.
\v(ty_mc)
Match count of file most recently TYPEd (see /MATCH).
Switches:
/PAGE
If /PAGE is included, Kermit pauses at the end of each
screenful and issues a "more?" prompt. You may press the space
bar to view the next page (screenful), or press "q" or "n" to
return to the C-Kermit prompt. If this switch is given, it
overrides the COMMAND MORE-PROMPTING setting for this command
only. If it is not given, paging is according to COMMAND
MORE-PROMPTING.
/NOPAGE
Do not pause at the end of each screenful; show the whole file
(or all selected lines) at once. If this switch is given, it
overrides the COMMAND MORE-PROMPTING setting for this command
only. If it is not given, paging is according to COMMAND
MORE-PROMPTING.
/HEAD[:n]
Only show the first n lines of the file (where n is a number).
If n is omitted, 10 is used.
/TAIL[:n]
Only show the last n lines of the file (where n is a number).
If nis omitted, 10 is used. Note: /HEAD and /TAIL can't be
combined; if you give both switches, only the most recent one
is used.
/MATCH:pattern
Only type lines from the file that match the given pattern (see
[363]Section 4.9.1 for pattern notation). UNIX users familiar
with grep should note a significant difference: there is no
implied "*" at the beginning and end of the pattern. Thus:
TYPE /MATCH:foo Lists lines whose entire contents are "foo".
TYPE /MATCH:foo* Lists lines that start with "foo".
TYPE /MATCH:*foo Lists lines that end with "foo".
TYPE /MATCH:*foo* Lists lines that have "foo" anywhere in them.
/HEAD and /TAIL apply after /MATCH, so "type /tail:20
/match:x*" shows the last 20 lines in the file that start with
"x".
/PREFIX:string
Print the given string at the beginning of each line. The
string may be a constant, a variable, or a quoted variable. If
it's an unquoted variable, its value at the time the TYPE
command was given is used as a constant. If it is a quoted
variable, it is re-evaluated for each line; a useful variable
for this context is \v(ty_ln) (the line number of the current
line being typed). If the prefix is to include spaces, it must
be enclosed in braces. Examples:
type /prefix:{oofa.txt: } /match:*thing* oofa.txt
Prints all lines in oofa.txt that contain "thing" with
the filename itself as the prefix (similar to UNIX grep).
type /prefix:{\v(time). } oofa.txt
Prefixes each line of oofa.txt with the time at which the
TYPE command was given (one backslash)
type /prefix:{\\v(time). } oofa.txt
Prefixes each line of oofa.txt with the time at which
that line is being typed (two backslashes).
type /prefix:{\\v(ty_ln). } oofa.txt
Prefixes each line of oofa.txt with its line number.
type /prefix:{\\flpad(\\v(ty_ln),4). } oofa.txt
Same as the previous example, except the line number is
right-adjusted in a 4-column field.
/WIDTH[:n]
Truncates each line at column n (which must be a number) prior
to printing it. This option can be used for long lines when you
don't want them to wrap. If nis omitted, your current screen
width is used.
/COUNT
Counts lines and -- if /MATCH was included, matches -- but does
not print any lines from the file. The line and match count is
shown at the end, and the variables \v(ty_lc) and \v(ty_lm) are
set accordingly.
SET OPTIONS TYPE { /PAGE, /NOPAGE, /WIDTH:n }
Sets the paging default for TYPE commands, which can be
overridden in any particular TYPE command by including the
desired switch.
If a TYPE command is given with no switch, and no SET OPTIONS TYPE
selection is in effect, paging is according to your COMMAND
MORE-PROMPTING setting (SHOW COMMAND).
_________________________________________________________________
1.16. The RESET Command
The RESET command, added in 7.0, closes all open files and logs, but
does not affect the open connection (if any).
_________________________________________________________________
1.17. The COPY and RENAME Commands
As of C-Kermit 7.0, in the UNIX version only, the COPY and RENAME
commands are built in and do not call the underlying platform's COPY
or RENAME command. This allows them to work in "NOPUSH" versions and
other circumstances where it can't access system commands, and it
allows file copying and renaming to be done portably in scripts. The
characteristics of the built-in COPY or RENAME include:
* It fails if the source file is a directory or is wild or lacks
read access.
* It fails if the source file is the destination file.
* It allows the destination file to be a directory, in which case
the source file is copied (or renamed) into it with the same name.
* It overwrites an existing destination file if its permission
allows.
* It sets the new file's permission according to umask but also
carries forward the source file's execute permission bits if the
destination file did not already exist.
* It fails if interrupted by Ctrl-C.
* Upon error, it prints an appropriate message.
* It returns standardized error codes that can be tested by IF
SUCCESS / FAIL.
These commands now also accept the following switches:
/LIST (/LOG, /VERBOSE) = Print "file1 => file2 (OK)" (or error message).
/NOLIST (/NOLOG, /QUIET) = Don't print anything (except error messages).
/NOLIST is the default.
The same built-in code is used by the UNIX C-Kermit server to execute
REMOTE COPY commands (except in this case no switches are available).
The COPY command also accepts the following additional switches. When
any of these are given (and they can be used in any combination except
/SWAP and /APPEND), some of the checks listed above are relaxed, and
thus it might be possible to get into trouble in certain cases, e.g.
when the source and target files are the same file:
/APPEND = Append source file to destination file.
/SWAP-BYTES = Swap bytes (see [364]Section 6.6.5).
/FROMB64 = Decode the source file from Base64 encoding.
/TOB64 = Encode the target file in Base64.
Base64 is the encoding commonly used for enclosures in Internet email.
_________________________________________________________________
1.18. The MANUAL Command
The MANUAL command can be used to access the appropriate Kermit manual
or other manual. The general syntax is:
MANUAL [ string ]
If the string is omitted, C-Kermit asks the underlying system
to access the C-Kermit manual using whatever method is
appropriate for the system.
The specific action depends on the system. In UNIX, a "man" command is
issued; "kermit" is the default argument but other manual topics may
be specified. If the "man" command allows index or string searching,
the appropriate syntax may be included.
In Kermit 95, the MANUAL command brings up the HTML online K95 manual.
In VMS and elsewhere, "man" is simply translated to "help", with a
default argument of "kermit"; other and/or additional arguments may be
included according to the definition of the system's "help" command.
Correct operation of the "man" command in C-Kermit depends on the
appropriate man page or help topic having been installed in the right
place with the right permissions and format.
_________________________________________________________________
1.19. String and Filename Matching Patterns
A pattern is a string that includes special notation for matching
classes or sequences of characters. C-Kermit 7.0 / K95 1.1.19 supports
patterns in several places:
* Filenames ([365]Section 4.9)
* SWITCH case labels ([366]Section 7.18)
* The new IF MATCH statement ([367]Section 7.4)
* TYPE /MATCH ([368]Section 1.15)
* SET FILE TEXT-PATTERNS and BINARY-PATTERNS ([369]Section 4.3)
* The \fsearch() and \farraylook() functions ([370]Sections 7.3 and
[371]7.10.7)
* The \fpattern() function used with [M,RE]INPUT ([372]Section 7.1)
Patterns are also called wildcards, especially when used for filename
matching. C-Kermit's pattern syntax is explained in [373]Section
4.9.1, and also by the HELP WILDCARDS command.
_________________________________________________________________
1.20. Multiple Commands on One Line
As of C-Kermit 7.0, commands can be grouped together on one line by
separating the commands with commas and enclosing the list in braces.
For example:
C-Kermit> { echo One, echo Two, echo Three }
C-Kermit> do { echo One, echo Two, echo Three }
Command lists can be nested:
[ do ] { echo One, echo Two, if true { echo A, echo B}, echo Three }
and the END command works as it does in macros:
[ do ] { echo One, echo Two, if true end, echo Three }
The "one line" stricture is, of course, pliant to line-continuation
conventions, namely that lines ending in hyphen (-) or left brace ({)
are to be continued. Thus the first example can also be rendered:
[ do ] {
echo One
echo Two
echo Three
}
(the "do" is optional).
_________________________________________________________________
1.21. What Do I Have?
C-Kermit can be built for hundreds of different platforms with
practically countless configuration options. Certain commands might
not be available in certain configurations, etc. Even on the same
platform, different builds are possible: "maximum functionality",
"minimum size", "maximum performance", and so on. You can find out a
lot about the configuration of your C-Kermit program with the SHOW
FEATURES command. Of course, a lot of what it says, especially in the
bottom part, might seem like gibberish, but can be deciphered with a
Rosetta Stone (such as the C-Kermit source or the [374]ckccfg.txt
file). In any case, the output from SHOW FEATURES might easily explain
why some expected feature is missing, or some buffer is smaller than
expected. Here's a sample of the bottom section for the SunOS version:
C-Kermit 7.0.196, 1 Jan 2000
Major optional features included:
Network support (type SHOW NET for further info)
Telnet Kermit Option
Hardware flow control
External XYZMODEM protocol support
Latin-1 (West European) character-set translation
Latin-2 (East European) character-set translation
Cyrillic (Russian, Ukrainian, etc) character-set translation
Greek character-set translation
Hebrew character-set translation
Japanese character-set translation
Unicode character-set translation
Pseudoterminal control
REDIRECT command
RESEND command
Fullscreen file transfer display
Control-character unprefixing
Streaming
Autodownload
Major optional features not included:
No Kerberos(TM) authentication
No SRP(TM) (Secure Remote Password) protocol
No Secure Sockets Layer (SSL) protocol
No Transport Layer Security (TLS) protocol
No encryption
No X Windows forwarding
Host info:
Machine: sun4m
Model: (unknown)
OS: SunOS
OS Release: 4.1.3_U1
OS Version: 4
Target: sunos41gsc
GCC version: 2.7.2
Compiled Dec 31 1999 10:38:54, options:
__GNUC__ __STDC__ _POSIX_JOB_CONTROL _SC_JOB_CONTROL ARRAYREFLEN=1024 BIGBUFOK
BROWSER BSD4 CK_ANSIC CK_APC CK_AUTODL CK_CURSES CK_DNS_SRV CK_ENVIRONMENT
CK_FAST CK_LOGIN CK_MKDIR CK_NAWS CK_PCT_BAR CK_PERMS CK_RECALL CK_RTSCTS
CK_SPEED CK_TIMERS CK_TMPDIR CK_TTGWSIZ CK_TTYFD CK_WREFRESH CKEXEC
CKFLOAT=double CKGHNLHOST ckmaxfiles=64 CKMAXOPEN=64 CKMAXPATH=1023 CKREALPATH
CKREGEX CKSYSLOG CKTUNING CMDBL=32763 CMDDEP=64 CONGSPD DCMDBUF DIRENT DYNAMIC
FNFLOAT FORDEPTH=32 GFTIMER HADDRLIST HDBUUCP IFDEBUG IKS_OPTION IKSDB
IKSDCONF INBUFSIZE=32768 INPBUFSIZ=4096 MAC_MAX=16384 MACLEVEL=128 MAXDDIR=32
MAXDNUMS=4095 MAXGETPATH=128 MAXTAKE=54 MAXWLD=102400 MSENDMAX=1024 NETCMD
NETCONN NETPTY NOKVERBS NOSETBUF OBUFSIZE=32768 PARSENSE PATTERNS PIPESEND
RENAME RLOGCODE SAVEDUID SELECT SIG_V SOL_SOCKET sparc STREAMING sun SUNOS4
SYSTIMEH TCPSOCKET TIMEH TLOG TNCODE TTLEBUF TTSPDLIST UIDBUFLEN=256 UNIX
UNPREFIXZERO USE_LSTAT USE_MEMCPY VNAML=4096 WHATAMI XFRCAN Z_MAXCHAN=46
z_maxchan=46 ZXREWIND
byte order: big endian
sizeofs: int=4 long=4 short=2 char=1 char*=4 float=4 double=8
floating-point: precision=16 rounding=1
Without going into detail about what all the notation means, notice a
couple things:
* The Options section shows symbols ("macros") in effect during
compilation, together with their values (for those that have
values). The options are listed in alphabetical order to make any
particular option easier to find.
* MAXWLD is the maximum number of files that a wildcard can expand
to.
* Anything starting with "NO" is a feature (or something other than
a feature) that has been deliberately "compiled out", or omitted.
* Important items for script writers include: CMDBL=32763 (the size
of the command buffer and therefore the maximum length for a macro
or variable definition; CMDDEP=64 (the limit on recursion depth);
FORDEPTH=32 (the nesting limit on FOR loops); INBUFSIZE=32768 (the
size of the INPUT command circular buffer); MAC_MAX=16384 (the
maximum number of macros), etc.
See the [375]ckccfg.txt file for details.
_________________________________________________________________
1.22. Generalized File Input and Output
C-Kermit 7.0 adds a new generalized I/O system for stream files,
augmenting (and to some extent, overlapping with) the older OPEN,
READ, WRITE, and CLOSE commands. In the new file i/o system, which can
be used simultaneously with the old one, all commands are grouped
together under the new FILE keyword, and some related functions and
variables are added.
1.22.1. Why Another I/O System?
The well-known LOG, OPEN, READ, WRITE, and CLOSE commands have the
following restrictions:
1. Only one READ file and one WRITE file can be open at a time.
2. The READ and WRITE commands are strictly line oriented.
3. These commands can not be used with binary files.
4. They do not support read/write access or random access.
5. The syntax is a bit counterintuitive for programmers.
The new file i/o system allows multiple files to be open at once, in
any desired combination of modes (read/write/append) supported by the
operating system, for line, block (record), or character i/o, for
sequential or random access, using consistent syntax and conventions.
The new system, however, does not replace the old one, since the old
system still must be used for:
1. The session, packet, debug, transaction, and connection logs.
2. Reading and writing commands rather than files.
3. Existing scripts.
The new system works only with regular files, not with commands or
pipes or mailboxes or pseudoterminals. No special provisions are made
in the FILE commands for handling devices or network connections, nor
for preventing you from trying to open them; if the underlying
operating system treats them like regular stream disk files, the FILE
commands (except, of course SEEK, REWIND, and COUNT) might work with
them. (In C programming terms, the FILE commands are, at present,
nothing more than a front end to fopen() / fread() / fwrite() /
fclose() and friends, which are a portable API to sequential files,
but this might change in the future for platforms like VMS and VOS
that have more complicated file systems.)
Definitions:
Channel
A number assigned to a file when it is opened, by which it must
be referred to in all input/output operations.
Read/Write Pointer
The current position in an open file, expressed as the 0-based
byte count from the beginning.
_________________________________________________________________
1.22.2. The FILE Command
FILE keyword [ switches ] channel [ data ]
The keyword specifies the function: FILE OPEN, FILE READ, FILE
WRITE, FILE CLOSE, etc. For convenience (and for familiarity to
C programmers), the two-word FILE commands can be shortened to
the single words FOPEN, FREAD, FWRITE, FCLOSE, and so on.
Switches are optional, and modify or amplify the requested file
function.
As in C, Fortran, and other programming languages, open files are
referred to by "channels", integers such as 0, 1, 2, 3, and so on. A
channel number is assigned when you open a file. The number of
available channels depends on the underlying operating system, and can
be seen in the variable:
\v(f_max)
or by giving the FILE LIST (FLIST) command. Channels are discussed in
greater detail in [376]Section 1.22.4.
FILE command errors can be caught with IF FAIL after the FILE command.
In addition, the \v(f_error) variable is set to the completion code of
the command: 0 if no error, or a negative number if there was an
error. The error codes are listed in [377]Section 1.22.5.
The command to open a file is:
FILE OPEN [ switches ] variable filename
Opens a file for the type of access specified by the switches,
or for read-only access if no switches are given. Upon success,
a channel number is assigned to this file and stored in the
given variable so you can refer to the open file in subsequent
i/o commands. If the file can not be opened, the FILE OPEN
command fails. Synonym: FOPEN.
The FILE OPEN switches are:
/READ
Open the file for read access. If no switches are given, /READ
is assumed. If the file does not exist or can't be opened for
read access, the FILE OPEN command fails.
/WRITE
Allow writing. If a file of the same name already exists, it is
overwritten unless /READ or /APPEND is also included. If a file
of the given name does not exist, it is created.
/APPEND
Equivalent to /WRITE, except that if the file exists, it is not
destroyed. The read/write pointer is set to the end of the
file, so unless you change it with FILE SEEK or REWIND (see
below), the first FILE WRITE command adds to the end of the
file, preserving what was there already. If /WRITE is also
given, it is ignored.
/BINARY
Open the file in "binary" mode, rather than text mode. This
switch is meaningless (but still can be used) in UNIX. In VMS,
Windows, and OS/2, it inhibits end-of-line processing and
conversion, and so should be used for binary files and/or files
that are to be accessed in record or character mode rather than
line by line.
The variable for the channel number can be any kind of variable: the
\%x kind, a macro name, or an array element. But it must be a
variable, not a number -- C-Kermit assigns the channel number; you
can't tell it what number to use.
Example:
FILE OPEN \%c oofa.txt ; Open oofa.txt for reading.
IF FAIL exit 1 Can't open oofa.txt ; Always check to see if it worked.
ECHO oofa.txt: channel = \%c
If the file oofa.txt is opened successfully, a channel number is
assigned to the variable \%c. Here's another example using a macro
name for the channel number:
FILE OPEN channel oofa.txt ; Open oofa.txt for reading.
IF SUCCESS ECHO oofa.txt: channel = \m(channel)
Switches can be combined when it makes sense and the underlying
operating system allows it. For example, to open a file in binary mode
for reading and writing (sometimes called "update"):
FILE OPEN /READ /WRITE /BINARY \%c budget.db
Some combinations might be allowed, others not. For example /READ
/APPEND will usually not be allowed. /WRITE /APPEND is treated as
/APPEND.
A major advantage of the new system over the older one is that you can
have multiple files open at once. Suppose, for example, that you want
to open all the files in a certain directory at once:
.\%n := \ffiles(/usr/olga*,&f) ; Get file list into array.
if ( > \%n \v(f_max) ) { ; Make sure there aren't too many.
exit 1 {\v(dir): \%n = Too many files}
}
declare \&c[\%n] ; Make array for channel numbers.
for \%i 1 \%n 1 { ; Loop to open every file...
file open \&c[\%i] \&f[\%i] ; Try to open this one
if fail exit 1 Open error: \&f[\%i] ; Check for failure
}
If this loop completes successfully, the \&c[] array will contain \%n
channel numbers of open files in elements 1 through \%n.
Any file that you open with FILE OPEN stays open until Kermit exits,
or you close it explicitly. The command to close a file is:
FILE CLOSE { ALL, channel }
If a channel number is given and the channel refers to an open
file, the file is closed and the channel is freed for reuse; if
the channel does not refer to an open file, an error message is
printed and the command fails. If ALL is specified instead of a
specific channel, all files opened with FILE OPEN are closed
and if all open files were closed successfully (even if no
files were open), the command succeeds; if any open file could
not be closed, the command fails; however, all open files that
could be closed are still closed. Synonym: FCLOSE.
FILE CLOSE might fail because, for example, the disk filled up or a
quota was exceeded. Example:
fopen /write \%c new.txt ; Open new.txt for writing.
if fail exit 1 ; Check for error.
fclose \%c ; Close the file we just opened.
This creates a 0-length file called new.txt.
Note that FILE OPEN /WRITE (without /READ or /APPEND) always creates a
new file, and therefore destroys any file with the same name that
might already exist (assuming you have permission to delete it). To
avoid overwriting existing files, simply check first:
if exist new.txt exit 1 {Fatal - new.txt already exists}
fopen /write \%c new.txt
if fail ...
The next two commands give information about open files:
FILE STATUS channel
Tells the name of the file, if any, open on the given channel
and the switches it was opened with. The read/write pointer is
also shown; this is where the next read or write will occur;
"[EOF]" is shown if the current position in the open file is
the end -- i.e. the next read will fail if the file was opened
in /READ mode; the next write will add material to the end. The
current line number (0-based) is also shown if known. The FILE
STATUS command succeeds if the channel is open, and fails if
there is no open file on the given channel, or if the channel
number is invalid or out of range. Synonym: FSTATUS.
FILE LIST
Lists the channel number and name of each open file, along with
its OPEN modes (R, W, A, B, RW, etc) and its current read/write
pointer or "[EOF]" if it is at the end. Also tells the number
of files currently opened with FILE OPEN, plus the maximum
number of open files allowed by the system and the maximum
number allowed for FILE OPEN. Synonym: FLIST.
Next come the commands for reading and writing files:
FILE READ [ switches ] channel [ variable ]
Reads data from the file on the given channel number into the
variable, if one was given; if no variable was given, the
result is printed on the screen. IMPORTANT: The variable should
normally be a macro name rather than a \%x or \&x[] variable if
you want backslash characters in the file to be taken literally
(see pp.408-412 of [378]Using C-Kermit for an explanation; you
can also read into a \%x or \&x[] variable, but then you must
remember to protect future references to by \fcontents() if you
don't want C-Kermit to process any backslashes it might
contain). The desired amount of data (according to the
switches) is read from the file at the current read/write
pointer, and upon completion the read/write position is updated
to first byte after the data that was read, no matter what
switches were given. Synonym: FREAD.
FILE WRITE [ switches ] channel text
Writes the given text to the file on the given channel number.
The text, of course, can be literal text or a variable, or any
combination. If the text might contain leading or trailing
spaces, it must be enclosed in braces if you want to preserve
them. Synonym: FWRITE.
Before proceeding, a caution about the NUL character. C-Kermit is so
named because it is a Kermit program written in the C language. In C,
character strings are represented as a sequence of non-NUL bytes
terminated by a NUL byte (a byte in which all bits are 0). Thus a C
string can not contain NUL bytes; it always ends with the first NUL
byte. C-Kermit variables are implemented as C strings and therefore
can't contain NUL bytes either, so the FILE READ and FILE WRITE
commands do not handle files or strings that contain NUL bytes, except
when the /CHARACTER switch is included with the FILE READ or WRITE
command, or when /LPAD:0 or /RPAD:0 is given with the FILE WRITE
command; these switches are explained below.
Also note that Kermit can not be used read or write binary numbers in
the machine's internal format (integer or floating-point); in general,
numbers can be processed only when represented as numeric or
floating-point strings.
FILE READ switches are:
/LINE
Specifies that a line of text is to be read. A line is defined
according to the underlying operating system's text-file
format. For example, in UNIX a line is a sequence of characters
up to and including a linefeed, or the end of the file, which
ever comes first. The line terminator (if any) is removed
before assigning the text to the variable. If no switches are
included with the FILE READ command, /LINE is assumed. Normally
this switch should not be used with files opened in /BINARY
mode (but nothing prevents it either).
/SIZE:number
Specifies that the given number of bytes (characters) is to be
read. The actual number of bytes returned will be less if the
end of file is reached (or a NUL byte is encountered). For
example, if a file is 514 bytes long, FILE READ /SIZE:512
returns 512 bytes the first time and 2 bytes the second time.
FILE READ /SIZE provides a kind of "record i/o" for files that
do not necessarily contain lines. The resulting block of
characters is assigned to the variable without any editing.
Synonym: /BLOCK.
/CHARACTER
Equivalent to /SIZE:1. If FILE READ /CHAR succeeds but the
variable is empty, this indicates a NUL byte was read. Synonym:
BYTE.
FILE WRITE switches are:
/LINE
Specifies that an appropriate line terminator is to be added to
the end of the text. If no switches are included, /LINE is
assumed.
/SIZE:number
Specifies that the given number of bytes (characters) is to be
written. If the given text is longer than the requested size,
it is truncated; if is shorter, it is padded according /LPAD
and /RPAD switches. Synonym: /BLOCK.
/LPAD[:value]
If /SIZE was given, but the text is shorter than the requested
size, the text is padded on the left with sufficient copies of
the character whose ASCII value is given to write the given
length. If no value is specified, 32 (the code for Space) is
used. The value can also be 0 to write the indicated number of
NUL bytes. If /SIZE was not given, this switch is ignored.
/RPAD[:value]
Like LPAD, but pads on the right.
/CHARACTER
Specifies that one character should be written. If the text is
empty or not given, a NUL character is written; otherwise the
first character of text is given. Synonym: /BYTE.
/STRING
Specifies that the text is to be written as-is, with no
terminator added.
Here's an example in which we copy a text file line by line:
file open /read \%c oofa.txt ; Open input file
if fail exit 1 Can't open input file ; Check that it's open
file open /write \%d new.txt ; Open output file
if fail exit 1 Can't open output file ; Check
while true { ; Loop to copy lines
file read /line \%c line ; Read a line
if fail break ; Assume failure = end of file
file write /line \%d {\m(line)} ; Write the line to output file
if fail exit 1 Write failure ; Failure here is fatal
}
file close \%c ; Close the two files
file close \%d
Note that since /LINE is the default for both FILE READ and FILE
WRITE, it can be omitted as in the following example, where we also
use the short names for the FILE commands.
fopen /read \%c oofa.txt ; Open input file
if fail exit 1 Can't open input file ; Check that it's open
fopen /write \%d new.txt ; Open output file
if fail exit 1 Can't open output file ; Check
while true { ; Loop to copy lines
fread \%c line ; Read a line
if fail break ; Assume failure = end of file
fwrite \%d {\m(line)} ; Write the line to output file
if fail exit 1 Write failure ; Failure here is fatal
}
fclose \%c ; Close the two files
fclose \%d
Here's the same example using "record i/o" (the open and close
sequences are are omitted since they are the same as above). The
result is the same, but execution is much faster:
while true { ; Loop to copy blocks
fread /size:512 \%c block ; Read a block into \%a
if fail break ; Assume failure = end of file
fwrite /string \%d {\m(block)} ; Write the block to output file
if fail exit 1 Write failure ; Failure here is fatal
}
Although record i/o is faster, it should not be used in line-oriented
applications, since it returns arbitrary chunks of the file to your
script, rather than lines. In this example, FWRITE /STRING is used
rather than FWRITE /SIZE:512 to avoid the last output block being
padded beyond the original file's length.
A file can also be copied character by character, but this is much
slower than line i/o and VERY much slower than block i/o:
while true { ; Loop to copy blocks
fread /char \%c c ; Read a character into c
if fail break ; Assume failure = end of file
fwrite /char \%d {\m(c)} ; Write character to output file
if fail exit 1 Write failure ; Failure is fatal
}
Although character i/o is slow, it is the only way to process files
that contain NUL characters (i.e. bytes composed of only zero bits).
In the example above, when "fread /char \%c c" returns a NUL, the c
variable is empty. But since the FREAD /CHAR command did not fail, we
know the result was really a NUL. FWRITE /CHAR, when given an empty
variable (or no variable at all) writes a NUL. Thus the loop above
will copy any file at all (very slowly). In non-copying applications,
NULs are detected like this:
fread /char \%c c
if fail (do something)
if not def c (a NUL byte was read)
Finally some advanced file operations:
FILE FLUSH channel
For output files only: commits all previous writes to disk, in
case the computer was buffering them. Synonym: FFLUSH.
FILE COUNT [ { /BYTES, /LINES, /LIST, /NOLIST } ] channel
By default, or if the /BYTES switch is given, counts the bytes
in the file, if any, open on the given channel. If the /LINES
switch is given, counts lines in the file. If the /LIST switch
is given, the result is printed. If the /NOLIST switch is
given, the result is not printed. /QUIET is a synonym for
/NOLIST. If neither /LIST nor /NOLIST is given, the result is
printed if the command is given at top level, i.e. not from a
command file or macro. In all cases, the result of the most
recent FILE COUNT command is stored in the variable
\v(f_count). Note that FILE COUNT /LINE works (and can only
work) by reading the entire file; expect it to take some time
if the file is large. Synonym: FCOUNT.
FILE REWIND channel
Moves the read/write pointer to the beginning of the file.
Equivalent to FILE SEEK channel 0. Synonym: FREWIND.
FILE SEEK [ switches ] channel { [{+,-}]number, LAST, EOF }
Moves the read/write pointer for the file on this channel to
the given position, which may be a byte (character) number or a
line number, expressed in either absolute or relative terms.
Switches:
/BYTE
The number given is a byte number. Synonym: /CHARACTER.
/LINE
The number given is a line number.
/ABSOLUTE
The number given is absolute.
/RELATIVE
The number given is relative to the current position.
By default, or if the /BYTE switch is given, the number is a
byte number (0 = first byte). If /LINE is given, the number is
a line number (0 = first line). EOF means to move to the end of
the file. LAST means to move to the last line or character of
the file, depending on whether it's a line or character seek.
If neither the /RELATIVE nor the /ABSOLUTE switch is given,
then if a signed number is given, the motion is relative to the
current position. An expression that evaluates to a negative
number is not considered signed for this purpose; that is, a
sign (+ or -) must be included as the first character of the
number in the command itself to force a relative seek (in the
absence of /RELATIVE or /ABSOLUTE).
If the number has no sign, or if the /ABSOLUTE switch is given,
the number represents an absolute position (relative to the
beginning of the file). Subsequent FILE READs or WRITEs will
take place at the new position.
If the read/write pointer is placed after the end of the file,
a subsequent FILE READ will fail, but a FILE WRITE will succeed
(possibly creating a file with "holes"). If a FILE SEEK /BYTE
command is given, the current line becomes unknown (unless the
position is 0) and subsequent FILE SEEK /RELATIVE /LINE
commands will fail until the next non-relative FILE SEEK /LINE
command is given. Synonym: FSEEK.
An absolute FILE SEEK to a negative position fails silently, as does a
relative seek to a position before the beginning of the file.
A caution about relative SEEKs: remember that the number is relative
to the current position. Whenever you read or write, this changes the
position. In each of the following examples, assume the file open on
channel \%c is positioned at line n (the FREAD target variable is
omitted for lack of space):
{ FREAD \%c, FSEEK /LINE \%c -1, FREAD \%c } <-- Reads line n twice
{ FREAD \%c, FSEEK /LINE \%c +0, FREAD \%c } <-- Reads lines n and n+1
{ FREAD \%c, FSEEK /LINE \%c +1, FREAD \%c } <-- Reads lines n and n+2
{ FREAD \%c, FSEEK /LINE \%c -2, FREAD \%c } <-- Reads lines n and n-1
{ FREAD \%c, FSEEK /LINE \%c -3, FREAD \%c } <-- Reads lines n and n-2
Another caution: Using FSEEK and FREAD /SIZE to repeatedly read the
same disk block (e.g. when sampling a database record that is
frequently updated) might not give you updated disk blocks due to the
internal buffering and caching of the C library (this probably varies
from one platform/compiler combination to another). If necessary you
can force a fresh disk read with a close/open sequence:
FCLOS \%c
FOPEN \%c samefilename
FSEEK \%c samespot
FREAD /SIZE:howmanybytes \%c variable
_________________________________________________________________
1.22.3. FILE Command Examples
To read the last 10 lines of a text file into an array:
fopen /read \%c oofa.txt ; Open the file
if fail exit 1 Can't open oofa.txt ; Always check for failure
dcl \&a[10] ; Declare a 10-element array
fcount /line \%c ; Count lines in the file
fseek /line \%c \v(f_count)-10 ; Seek to 10 lines from the end
if fail exit 1 Can't seek ; Check for failure
for \%i 1 10 1 { fread \%c \&a[\%i] } ; Read the last 10 lines
fclose \%c ; Close the file
Note that blank lines show up as empty (undefined) array elements, for
example if you give a "show array a" command at this point. This is
normal. You can still use these elements; e.g.:
for \%i 1 10 1 { echo \%i. \&a[\%i] } ; Display the 10 lines
Here is how to read the last line of a file (already open on channel
\%c):
fseek /line \%c last ; Seek directly to last line
Alternatively:
fseek /line \%c eof ; Seek to end of file
fseek /line \%c -1 ; Seek to beginning of last line
Alternatively:
fcount /line \%c ; Count the file's lines
fseek /line \%c \v(f_count)-1 ; Seek to last line
fread \%c ; Read it
To read every other line from the file (using relative SEEK), skipping
the first line:
fopen /read \%c oofa.txt ; Open the file
while ( success ) { ; Loop through lines
fseek /line \%c +1 ; Skip a line
if success fread \%c ; Read & display a line
}
fclose \%c ; Close the file
Here is how to read the lines of a file in reverse order:
fopen /read \%c oofa.txt ; Open
if fail exit 1 ; Check
fseek /line \%c last ; Seek to last line
while success { ; Loop
fread \%c ; Read line
fseek /line \%c -2 ; Seek backwards two lines
}
fclose \%c ; Close the file
The loop works because a relative SEEK outside the file fails.
It is also possible to use block i/o to manage random-access files
with fixed-length records (as long as they don't contain NUL
characters). Suppose, for example, you have a file of "card image"
records with fixed-field information about customers, such as:
Name: Columns 1-32 (column numbers are 1-based)
Address: Columns 33-72
Balance: Columns 73-80
The records are indexed by customer number, starting with 0. There are
no line terminators separating them. Therefore the record for customer
number n starts at position nx 80 (\%n*80).
Now suppose we received a payment from customer number 173 and want to
update the balance:
.\%n = 173 ; Customer (record) number
.\%a = 12.72 ; Amount
fopen /read /write \%c customer.db ; Open the file
if fail stop 1 OPEN FAILED: \f_errmsg() ; Check
fseek /byte \%c 80*\%n ; Seek to record
fread /size:80 \%c r ; Read the record
if fail stop 1 READ FAILED: \f_errmsg() ; Check (IMPORTANT)
.\%b := \fright(\m(r),8) ; Extract the balance
.\%b := \ffpadd(\%b,\%a,2) ; Add the new payment
if fail stop 1 ARITHMETIC ERROR: \%b/\%a ; Catch bad records
.r := {\fleft(\m(r),72)\flpad(\%b,8)} ; Update the record
fseek /byte \%c 80*\%n ; Reposition to same spot
fwrite /size:80 \%c {\m(r)} ; Replace the record
if fail stop 1 WRITE FAILED: \f_errmsg() ; Check
fclose \%c ; Close the file
REMEMBER: Using FILE SEEK to move beyond the end of file can result in
a file with holes when writing; when reading, an end-of-file error
will occur -- be sure to check for it.
_________________________________________________________________
1.22.4. Channel Numbers
C-Kermit's channel numbers are integers from 0 to some
platform-dependent limit, such as 46 or 1985 (the value of \v(f_max)).
This is the limit placed by the operating system on the number of
files that may be opened by one process or user or job, minus the
standard input, output, and error files, and minus the number of files
reserved by C-Kermit for logs, OPEN READ and WRITE, and file transfer
(and maybe some command files -- the \v(f_max) number can't be exact).
Although you must include a variable in the FILE OPEN command, to
which the channel number is assigned, you don't have to use a variable
in the other FILE commands if you know what the number is -- you can
just put the number. This saves you a few keystrokes when typing
commands at the prompt:
fopen \%c oofa.txt
flist
0. /usr/olga.oofa.txt (R) 0
This tells the channel number is 0 (the number on the left is the
channel file's channel number). Of course you can also find it by
echoing the variable:
echo \%c
0
Or with "fstatus \%c". Now you can type commands like:
fread 0
to read a line from the file. Obviously, however, using digits rather
than a variable for the channel number would be poor practice in a
script.
If in commands like:
fread \%c \%a
you have trouble remembering which variable is which, note that the
channel number is, indeed, a number. Anywhere C-Kermit accepts a
number it can also accept an expression, so you can put parentheses
around the channel number to remind you it's the channel number and
not the variable into which data is to be read:
fread (\%c) \%a
Normally channel numbers are assigned sequentially as 0, 1, 2, ... up
to the limit. However, once you start closing files, there can be
holes in the sequence. New channels are assigned to fill in the holes.
Thus you can't depend on channel numbers being in any particular
sequence.
_________________________________________________________________
1.22.5. FILE Command Errors
Each FILE command sets the variable \v(f_error) to one of the
following values:
0 = No error
-1 = System error
-2 = Attempt to read after end of file
-3 = Channel not open
-4 = Channel number out of range (negative or too large)
-5 = Numeric argument (size, ...) out of range
-6 = File not found
-7 = Bad or missing filename
-8 = Too many files are already open (FILE OPEN only)
-9 = Forbidden operation (e.g. write to a read-only file)
-10 = Access denied
-11 = Illegal combination of OPEN modes (FILE OPEN only)
-12 = Buffer overflow
-13 = Current line number unknown (for relative line seeks)
-14 through -98: Reserved.
-99 = Requested operation not implemented in this version of C-Kermit
-999 = Unknown error
When \v(f_error) is -1, this means the FILE command failed because
because of a system error, in which case you can examine the following
variables:
\v(errno) = System error number.
\v(errstring) = Error message corresponding to \v(errno).
A special function is available for translating the \v(f_error) code
to an error message string:
\f_errmsg([code])
If the code is -1, returns error message of the most recent system
error; otherwise if the code is a valid \v(f_error) value, the associated
message is returned. If the code is omitted, the status message
corresponding to the current \v(f_error) value is returned.
A FILE command that fails prints the appropriate error message
automatically, except when the command is READ or SEEK and the error
is -2 (end of file); in that case, the command still fails, but does
not print a message. This allows constructions such as:
fopen \%c oofa.txt
while success { fread \%c }
fclose \%c
to work as expected, i.e. without an annoying message when the end of
file is reached.
_________________________________________________________________
1.22.6. File I/O Variables
The variables associated with the file i/o package are:
\v(f_count)
Result of the most recent FILE COUNT (FCOUNT) command.
\v(f_error)
Numeric error code of most recent FILE command (0 = no error).
\v(f_max)
Maximum number of files open simultaneously.
_________________________________________________________________
1.22.7. File I/O Functions
Some of the FILE commands can also be issued as function calls, which
makes script writing a bit more convenient, especially for C
programmers. Also, several functions are provided that do not have
command equivalents. Each of these functions takes a channel number as
the first argument. These functions do not work for OPEN { READ,
!READ, WRITE, !WRITE, and APPEND } files.
\f_status(channel)
Returns 0 if the channel is not open, otherwise a number
between 1 and 15 which is the sum of the OPEN modes:
1 = /READ
2 = /WRITE
4 = /APPEND
8 = /BINARY
The remaining functions work only for open channels. Each of these
functions can fail for the applicable reasons listed in [379]Section
1.22.5. For instructions on handling function errors, see [380]Section
7.12.
\f_pos(channel)
Returns the file's current read/write pointer (0-based). There
is no FILE command equivalent.
\f_line(channel)
Returns the file's current line number (0-based), if known,
otherwise -1. There is no FILE command equivalent. The line
number is known as long as no character or block i/o has been
done on the channel.
\f_handle(channel)
Returns the "file handle" of the file. That is, it translates
the portable C-Kermit channel number into a system-specific
file handle or number that can be passed to other programs on
the same platform. In UNIX this is a file descriptor. There is
no FILE command equivalent.
\f_eof(channel)
Returns 1 if the read/write pointer of the file on the given
channel is at the end of the file, 0 otherwise. Convenient in
WHILE statements, e.g.:
while not \f_eof(\%c) { fread \%c }
\f_getchar(channel)
Equivalent to FREAD /CHAR. Returns the character actually read.
If \f_getchar() does not fail but the return value is empty,
this means a NULL character was read.
\f_getline(channel)
Equivalent to FREAD /LINE. Returns the line actually read, but
with the line terminator stripped. If \f_getline() does not
fail but the return value is empty, this normally means an
empty line was read.
\f_getblock(channel,n)
Equivalent to FREAD /SIZE:n. Returns the block of characters
actually read. If the returned block is smaller than n, it
indicates either that the end of file was reached or a NUL
character is in the block.
\f_putchar(channel,c)
Equivalent to FWRITE /CHARACTER. Writes the character c. If c
contains more than one character, only the first is written. If
c is empty a NUL is written. Returns the number of characters
written on success, or a negative error code upon failure.
\f_putline(channel,string)
Equivalent to FWRITE /LINE. Writes the string and adds the
appropriate line termination character or sequence. If the
string is empty or omitted, an empty line is written. Returns
the number of characters written on success, or a negative
error code upon failure.
\f_putblock(channel,string)
Equivalent to FWRITE /STRING. Writes the string as given. If
the string is empty or omitted, nothing is written. Returns the
number of characters written on success, or a negative error
code upon failure.
_________________________________________________________________
1.22.8. File I/O Function Examples
fopen /read \%c oofa.txt ; Open our favorite file for reading
if failure exit 1 ; Check that it's open
while not \f_eof(\%c) { ; Loop until EOF
.line := \f_getline(\%c) ; Get a line
if success echo {\m(line)} ; Echo it
}
if not \f_eof(\%c) { ; Check reason for loop exit
exit 1 File Error: \f_errmsg() ; If not EOF say so.
}
frewind \%c ; Rewind the file
while not \f_eof(\%c) { ; Same thing but with block i/o
.block := \f_getblock(\%c,256) ; (much faster than line i/o)
if success xecho {\m(block)}
}
frewind \%c ; Rewind again
while not \f_eof(\%c) { ; Same deal but with character i/o
.c := \f_getchar(\%c) ; (much slower than line i/o)
if success xecho {\m(c)}
}
close \%c
To close all open files (equivalent to FCLOSE ALL):
for \%i 0 \v(f_max)-1 1 {
if \f_status(\%i) fclose \%i
}
_________________________________________________________________
1.23. The EXEC Command
The EXEC command is available only in UNIX.
EXEC [ /REDIRECT ] command [ arg1 [ arg2 [ ... ] ]
Runs the given command with the arguments in such a way that
the command replaces C-Kermit in memory, and C-Kermit ceases to
execute. EXEC is like RUN, except instead of returning to
C-Kermit when finished, the command returns to whatever process
invoked Kermit.
In the normal case, no files are closed, so the EXEC'd command
inherits the open files, read/write pointers, working directory,
process ID, user ID (unless command is SUID), group ID (unless command
is SGID), groups, etc. (In UNIX, the EXEC command is simply a front
end for execvp().)
If the /REDIRECT switch is included, then if a connection is open (SET
LINE or SET HOST), it becomes the standard input and output of the
EXEC'd program. If no connection is open, the /REDIRECT switch has no
effect. For example to use C-Kermit for PPP dialing in Linux:
set modem type usr ; Specify the kind of modem you have
set line /dev/ttyS1 ; Specify the device it's connected to
set speed 57600 ; and the speed
set flow rts/cts ; and flow control.
set dial retries 100 ; Try the dial sequence up to 100 times.
dial {{9-212-555-1212}{9-212-555-1213}{9-212-555-1214}{9-212-555-1215}}
if fail exit 1
for \%i 1 16 1 { ; Try up to 16 times to get login prompt
input 10 Login: ; Wait 10 sec for it to appear
if success break ; Got it - proceed...
output \13 ; Send a carriage return and try again
}
if ( > \%i 16 ) stop 1 NO LOGIN PROMPT
lineout \(myuserid) ; Send user ID
input 30 assword: ; Wait for Password prompt
if fail stop 1 NO PASSWORD PROMPT
lineout \m(mypassword) ; Send the password.
exec /redirect pppd ; Replace ourselves with pppd.
In this example we assume that the script has already set up the
myuserid and mypassword variables -- normally the password should be
prompted for, rather than stored on disk. Notice the advantages over
the well-known "chat script":
* You don't have to control the modem itself with AT commands;
Kermit's DIAL command does this for you.
* You can have Kermit automatically redial as many times as you want
until it gets a connection (if this is legal in your country).
* You can have Kermit fetch the number or numbers from a dialing
directory.
* You can have Kermit cycle through a list of phone numbers (this is
new in C-Kermit 7.0; see [381]Section 2.1.16) without having to
enter the numbers in a dialing directory.
* Dialing is location-independent; you can use the same script to
dial from different areas or countries.
* Once the connection is made, the full power of Kermit's script
language is available to manage the dialog with the terminal
server or other device that answers the phone call.
NOTE: PPP and SLIP dialing are not available in Windows 95/98/NT/2000,
whose APIs do not provide a method for an application to hand over a
connection to the PPP or SLIP driver.
_________________________________________________________________
1.24. Getting Keyword Lists with '?'
Suppose you type "te" at the C-Kermit> 6.0 prompt and then Esc or Tab
to request keyword completion. Kermit beeps, indicating that more than
one command starts with "te". But if you type '?' to see what they
are, Kermit shows only "telnet". So why the beep? Because of invisible
keywords like "telopt", "terminal", and "text". Lots of keywords are
invisible because they are either synonyms for other keywords or else
esoteric options to be used only in special circumstances, so we don't
want them cluttering up the menus.
But then there is no way for you to discover them. So in C-Kermit 7.0,
if you type '?' AFTER the beginning of a keyword field, then invisible
keywords are shown too:
C-Kermit> te<Esc><BEEP>
C-Kermit> te? Command, one of the following:
telnet telopt terminal text
C-Kermit>te
But if '?' is typed at the beginning of a field, only visible keywords
are shown, as before (so, in this example, if '?' is typed at the
C-Kermit> prompt, "telnet" is the only command shown that starts with
"te").
_________________________________________________________________
2. MAKING AND USING CONNECTIONS The SET LINE, SET HOST, and SET PORT (a
synonym for SET LINE) commands have new synonyms, in which the word SET is
replaced by the word OPEN: OPEN LINE, etc. There is no new functionality
here, but OPEN is a better verb, since SET generally takes no action, whereas
these commands actually try to open a connection. Furthermore, there is the
symmetry with CLOSE.
________________________________________________________________________
2.0. SET LINE and SET HOST Command SwitchesThe SET LINE (SET PORT) and SET
HOST commands now allow switches before the device or host name, in most
cases, and under certain circumstances, also at the end. The new syntax is
backwards compatible with the previous syntax; thus SET LINE, SET PORT, and
SET HOST commands in command files written for C-Kermit 6.0 or earlier still
work. The expanded syntax is:
{ OPEN, SET } { LINE, PORT, HOST } [ switches ] device-or-address [ switches
]
The first group of switches is:
/NETWORK-TYPE:{TCP/IP,X.25,PIPE,PTY...}
When more than one network type is available, this lets you
specify the type of network to use for this connection without
affecting your global SET NETWORK TYPE. See [382]Section 2.7
about pipes and ptys.
/USERID:[string]
This switch is equivalent to SET LOGIN USERID. If a string is
given, it sent to host during Telnet negotiations; if this
switch is given but the string is omitted, no user ID is sent
to the host. If this switch is not given, your current LOGIN
USERID (\v(userid) value), if any, is sent. Unlike most other
switches, this one is "sticky", since the value must persist
throughout the session in case the server requests the ID
string at a later time.
/CONNECT
Enter CONNECT mode immediately and automatically after the
device or connection is open. On serial devices, however, when
CARRIER-WATCH is not OFF, wait up to 1 second for the Carrier
Detect signal to appear before trying to connect, to give the
device time to react DTR, which might have been off prior to
opening the device.
/SERVER
Enter server mode immediately and automatically after the
device or connection is open. Treatment of carrier is the same
as for /CONNECT.
/WAIT
/NOWAIT
For Telnet connections only: Like SET TELNET WAIT { ON, OFF },
but applies only to this connection, and in fact applies only
when OPENing this connection (which is usually the only place
it matters). Typically you would use TELNET /NOWAIT to make a
connection to a misbehaving Telnet server that does not reply
to negotiations as required by the Telnet protocol definition.
Note: /CONNECT and /SERVER switches are not available in the RLOGIN
and TELNET commands, since these commands already include an implicit
/CONNECT and preclude automatic entry into server mode.
The /CONNECT and /SERVER switches are especially useful with "set host
*" connections. For example, suppose you want to start a Kermit server
on socket 3000 of your TCP host. Normally you would have to give the
command:
set host * 3000
and then wait for a connection to come in, and only then could you
give the SERVER command (or else define a macro to do this, and then
execute the macro). Now you can do it in one step:
set host /server * 3000
This tells C-Kermit to wait for the connection and then enter server
mode once it comes in, no matter how long it takes. Similarly, "set
host /conn *" can be used to wait for a "chat" connection to come in.
Another set of switches is available in VMS only, for use only with
SET LINE:
/SHARE
Allows the SET LINE device to be opened in shared mode.
Normally it makes no sense to open a serial device in shared
mode, but it's necessary when C-Kermit is running in an
environment such as DECIntact, that opens your job's
controlling terminal in such a way that C-Kermit can't open it
too, unless it enables SHARE privilege. Note: SHARE privilege
is required.
/NOSHARE
Requires that the SET LINE device not be in use by any other
process in order for it to be successfully opened by C-Kermit.
If neither /SHARE nor /NOSHARE is specified, /NOSHARE is used.
The second group of switches is:
/NO-TELNET-INIT
Do not send initial Telnet negotiations even if this is a
Telnet port.
/RAW-SOCKET
This is a connection to a raw TCP socket ([383]Section 2.3.5).
/RLOGIN
Use Rlogin protocol even if this is not an Rlogin port.
/TELNET
Send initial Telnet negotiations even if this is not a Telnet
port.
As of C-Kermit 7.0 and K95 1.1.19, the TELNET command includes an
implicit /TELNET switch. So if you TELNET to a non-TELNET port, Kermit
sends initial Telnet negotiations. This makes sense, since that's what
"telnet" means.
If you want to make a connection to a non-Telnet port without sending
initial Telnet negotiations, use:
set host [ /connect ] name-or-address port
or:
telnet name-or-address port /no-telnet-init
Additional switches might be added in the future; type "set host ?" or
"set line ?" to see a current list.
_________________________________________________________________
2.1. Dialing
Automatic redialing is illegal or restricted in many countries, so
until C-Kermit 7.0, it was disabled by default, i.e. until a SET DIAL
RETRIES command was given. In C-Kermit 7.0, if no SET DIAL RETRIES
command has been given, a default is picked dynamically at DIAL time
based on the calling country code, if known. At this writing, the only
country code known to have no restrictions on automatic redialing is
1. So in this case a limit of 10 is chosen; otherwise 1. If you have
not given an explicit SET DIAL RETRIES command, SHOW DIAL shows the
value as "(auto)", and then the value actually used is shown when you
give the DIAL command.
As of C-Kermit 7.0, automatic redialing is automatically canceled if
the call could not be placed because no dialtone was detected.
_________________________________________________________________
2.1.1. The Dial Result Message
If DIAL DISPLAY is not ON, the "Call complete" message now shows the
modem's call result message, for example:
Dialing: ...
Call complete: "CONNECT 31200/ARQ/V32/LAPM/V42BIS"
The exact format and contents of this message, of course, depends on
the make, model, and configuration of your modem, so use your modem
manual to interpret it. The call result message is also available in
C-Kermit's \v(dialresult) variable.
C-Kermit> echo \v(dialresult)
CONNECT 31200/ARQ/V32/LAPM/V42BIS
C-Kermit> echo Speed = \fword(\v(dialresult),2)
Speed = 31200
C-Kermit>
Suppose your modem reports the modulation speed as shown above and you
want to ensure your call is completed at (say) 24000 bps or more. You
can use a little macro to do the job:
define HSDIAL { ; High Speed DIAL
local \%s
if < \v(argc) 1 if not def \v(dialnumber) end 1 Usage: \%0 number
set dial retries 100
set dial interval 1
while true {
dial \%*
if fail end 1 DIAL failed.
asg \%s \fword(\v(dialresult),2)
if def \%s if numeric \%s if not < \%s 24000 break
}
}
(See [384]Section 7.5 about the \%* variable.)
_________________________________________________________________
2.1.2. Long-Distance Dialing Changes
Due to the glut of cell phones, pagers, fax machines, ISPs, etc, area
codes and dialing rules are changing all the time. In the North
American Numbering Plan (NANP) countries (USA, Canada, etc), area
codes are split or overlayed with increasing frequency, and 10- and
11-digit dialing is gradually becoming the norm for local calls.
Changes are occurring In Europe, too, partly for these reasons and
partly because of some new EC rules.
In France, effective 18 October 1996, all calls, even local ones, must
be dialed with an area code. French area codes are presently 1-digit
numbers, 1-6, and the long-distance dialing prefix is 0. All calls
within France are considered long distance and begin with 01, 02, ...,
06.
Effective 1 May 1997, all calls within the US state of Maryland, even
local ones, must be dialed with an area code but without the
long-distance prefix -- this is the now widely-known North American
phenomenon of "ten digit dialing". The same is happening elsewhere --
many cities in Florida adopted 10-digit dialing in 1998.
In Italy beginning 19 June 1998, all calls to fixed (as opposed to
mobile) numbers must be prefixed by 0. When calling into Italy from
outside, the 0 must follow the country code (39). Calls to cell
phones, however, must be placed without the 0. Then on 29 December
2000, the 0 will become a 4 (for calling fixed numbers) and a prefix
of 3 must used for calling mobile phones. More info at:
http://www.telecomitalia.it/npnn/.
In Spain, effective 4 April 1998, with hard cutover on 18 July 1998,
all calls within the country must be dialed with 9 digits, and all
calls from outside Spain must also be dialed with 9 digits (after the
country code, 34). The new 9-digit numbers all begin with "9". More
info at: [385]http://www.telefonica.es/cambiodenumeracion/
Several new dialing features and commands have been added in version
6.1 and 7.0 to address these changes.
C-Kermit 6.0 and Kermit 95 1.1.11 and earlier handle the French
situation via a reasonable subterfuge (setting the local area code to
a nonexistent one), but did not handle "ten-digit dialing" well at
all; the recommended technique was to change the long-distance dialing
prefix to nothing, but this defeated Kermit's "list numbers for one
name" feature when the numbers were in different locations. For
example:
set dial ld-prefix
dial onlineservice
where "onlineservice" is a dialing directory entry name corresponding
to entries that are in (say) Maryland as well as other states, would
not correctly dial the numbers not in Maryland.
A new command lets you specify a list of area codes to be considered
local, except that the area code must be dialed:
SET DIAL LC-AREA-CODES [ areacode [ areacode [ areacode [ ... ] ] ] ]
The list may include up to 32 area codes. If a number is called
whose area code is in this list, it is dialed WITHOUT the
long-distance prefix, but WITH the area code.
So in Maryland, which (last time we looked) has two area codes, 410
and 301, the setup would be:
SET DIAL LC-AREA-CODES 410 301
Example:
SET DIAL LD-PREFIX 1
SET DIAL AREA-CODE 301
SET DIAL LC-AREA-CODES 410 301 <-- Area codes in 10-digit dialing region
DIAL +1 (301) 765-4321 <-- Dials 3017654321 (local with area code)
DIAL +1 (410) 765-4321 <-- Dials 4107654321 (local with area code)
DIAL +1 (212) 765-4321 <-- Dials 12127654321 (long distance)
The SET DIAL LC-AREA-CODES command does not replace the SET DIAL
AREA-CODE command. The latter specifies the area code you are dialing
from. If the called number is in the same area code, then the area
code is dialed if it is also in the LC-AREA-CODES list, and it is not
dialed otherwise. So if "301" had not appeared in the LC-AREA-CODES
list in the previous example:
SET DIAL LD-PREFIX 1
SET DIAL AREA-CODE 301
SET DIAL LC-AREA-CODES 410 <-- Area codes in 10-digit dialing region
DIAL +1 (301) 765-4321 <-- Dials 7654321 (local)
DIAL +1 (410) 765-4321 <-- Dials 4107654321 (local with area code)
DIAL +1 (212) 765-4321 <-- Dials 12127654321 (long distance)
The new Kermit versions also add a Local Call Prefix and Local Call
Suffix, in case you have any need for it. These are added to the
beginning and of local phone numbers (i.e. numbers that are not
long-distance or international). Examples:
SET DIAL LD-PREFIX 1
SET DIAL LC-PREFIX 9
SET DIAL LC-SUFFIX *
SET DIAL LC-AREA-CODES 410 <-- Area codes in 10-digit dialing region
SET DIAL AREA-CODE 301
DIAL +1 (301) 765-4321 <-- Dials 97654321* (local)
DIAL +1 (410) 765-4321 <-- Dials 94107654321* (local with area code)
DIAL +1 (212) 765-4321 <-- Dials 12127654321 (long distance)
_________________________________________________________________
2.1.3. Forcing Long-Distance Dialing
Suppose a number is in your country and area, but for some reason you
need to dial it long-distance anyway (as is always the case in
France). There have always been various ways to handle this:
1. Temporarily set your area code to a different (or nonexistent or
impossible) one (but this required knowledge of which area codes
were nonexistent or impossible in each country).
2. Dial the number literally instead of using the portable format,
but this defeats the purpose of the portable dialing directory.
Now there is also a new command that, very simply, can force
long-distance dialing:
SET DIAL FORCE-LONG-DISTANCE { ON, OFF }
If a call is placed to a portable phone number within the same
country code as the calling number, it is dialed with the
long-distance prefix and the area code if FORCE-LONG-DISTANCE
is ON. If OFF, the regular rules and procedures apply.
Example (France):
SET DIAL COUNTRY-CODE 33
SET DIAL AREA-CODE 6
SET DIAL FORCE-LONG-DISTANCE ON
(In fact, SET DIAL COUNTRY-CODE 33 automatically sets DIAL
FORCE-LONG-DISTANCE ON...)
Example (USA, for a certain type of reverse-charge calling in which
the called number must always be fully specified):
SET DIAL PREFIX 18002666328$ ; 1-800-COLLECT
SET DIAL COUNTRY-CODE 1
SET DIAL AREA-CODE 212
SET DIAL FORCE-LONG-DISTANCE ON
Example (Toronto, where calls to exchange 976 within area code 416
must be dialed as long distance, even when you are dialing from area
code 416):
SET DIAL COUNTRY-CODE 1
SET DIAL AREA-CODE 416
SET DIAL FORCE-LONG-DISTANCE ON
DIAL +1 (416) 976-xxxx
If dialing methods were consistent and sensible, of course it would be
possible to always dial every domestic call as if it were long
distance. But in many locations this doesn't work or if it does, it
costs extra. The following macro can be used for dialing any given
number with forced long-distance format:
define LDIAL {
local \%x
set dial force-long-distance on
dial \%*
asg \%x \v(success)
set dial force-long-distance off
end \%x
}
(See [386]Section 7.5 about the \%* variable.)
_________________________________________________________________
2.1.4. Exchange-Specific Dialing Decisions
This applies mainly to the North American Numbering Plan (NANP). Refer
to the section "Alternative notations" in [387]Using C-Kermit 2nd
Edition, pages 106-107, and the story about Toronto on page 110. Using
the new LC-AREA-CODES list, we can address the problem by treating the
exchange as part of the area code:
SET DIAL LD-PREFIX 1
SET DIAL AREA-CODE 416
SET DIAL LC-AREA-CODES 905276
DIAL +1 416 765 4321 <-- 7654321 (local)
DIAL +1 905 276 4321 <-- 9052764321 (local with area code)
DIAL +1 905 528 4321 <-- 19055284321 (long distance)
The same technique can be used in Massachusetts (story at top of page
111) and in any other place where dialing to some exchanges within a
particular area code is local, but to others in the same area code is
long distance.
_________________________________________________________________
2.1.5. Cautions about Cheapest-First Dialing
Kermit does not maintain a knowledge base of telephony information; it
only provides the tools to let you enter a phone number in a standard
format and dial it correctly from any location in most cases.
In particular, Kermit does not differentiate the charging method from
the dialing method. If a call that is DIALED as long-distance (e.g.
from 212 to 718 in country code 1) is not CHARGED as long distance, we
have no way of knowing that without keeping a matrix of charging
information for every area-code combination within every country, and
any such matrix would be obsolete five minutes after it was
constructed. Thus, "cheapest-first" sorting is only as reliable as our
assumption that the charging method follows the dialing method. A good
illustration would be certain online services that have toll-free
dialup numbers which they charge you a premium (in your online service
bill) for using.
_________________________________________________________________
2.1.6. Blind Dialing (Dialing with No Dialtone)
C-Kermit's init string for Hayes-like modems generally includes an X4
command to enable as many result codes as possible, so that Kermit can
react appropriately to different failure reasons. One of the result
codes that X4 enables is "NO DIALTONE". A perhaps not obvious side
effect of enabling this result code that the modem must hear dialtone
before it will dial.
It is becoming increasingly necessary to force a modem to dial even
though it does not hear a dialtone on the phone line; for example,
with PBXs that have strange dialtones, or with phone systems in
different countries, or with ISDN phones, etc. This is called "blind
dialing".
C-Kermit 7.0 has two new commands to cope with this situation:
SET DIAL IGNORE-DIALTONE { ON, OFF }
OFF (the default) means to tell the modem to wait for dialtone
before dialing. ON means to enable "blind dialing", i.e. tell
the modem NOT to wait for dialtone before dialing. Generally
this is accomplished by sending ATX3 to the modem just prior to
dialing. SET MODEM TYPE xxx and then SHOW MODEM displays
Kermit's built-in "ignore dialtone" command.
SET DIAL COMMAND IGNORE-DIALTONE text
This lets you change the built-in ignore-dialtone command (such
as ATX3) to whatever you choose, in case the built-in one does
not work, or another command works better.
Notes:
1. The ignore-dialtone command is not sent unless SET DIAL
IGNORE-DIALTONE is ON.
2. The ATX3 command generally disables not only NO DIALTONE, but also
BUSY. So this will prevent Kermit from detecting when the line is
busy. This is a property of the modem, not of Kermit.
_________________________________________________________________
2.1.7. Trimming the Dialing Dialog
The command:
SET MODEM COMMAND action [ command ]
is used to override Kermit's built-in modem commands for each action,
for each kind of modem in its internal database. If you include a
command, this is used instead of the built-in one. If you omit the
command, this restores the original built-in command.
If you want to omit the command altogether, so Kermit doesn't send the
command at all, or wait for a response, use:
SET MODEM COMMAND action {}
That is, specify a pair of empty braces as the command, for example:
SET MODEM COMMAND ERROR-CORRECTION ON {}
_________________________________________________________________
2.1.8. Controlling the Dialing Speed
The rate at which characters are sent to the modem during dialing is
normally controlled by the built-in modem database. You might want to
override this if Kermit seems to be dialing too slowly, or it is
sending characters to the modem faster than the modem handle them. A
new command was added for this in C-Kermit 7.0:
SET DIAL PACING number
Specifies the number of milliseconds (thousandths of seconds)
to pause between each character when sending commands to the
modem during DIAL or ANSWER command execution. 0 means no pause
at all, -1 (the default) or any other negative number means to
use the value from the database. Any number greater than 0 is
the number of milliseconds to pause.
HINT: You might also need to control the rate at which the modem
generates Touch Tones during dialing, for example when sending a
numeric page. There are two ways to do this. One way is to insert
pause characters into the dialing string. For modems that use the AT
command set, the pause character is comma (,) and causes a 2-second
pause. On most modems, you can use the S8 register to change the pause
interval caused by comma in the dialing string. The other way is to
set your modem's tone generation interval, if it has a command for
that. Most AT-command-set modems use S11 for this; the value is in
milliseconds. For example on USR modems:
ATS11=200
selects an interval of 200 milliseconds to separate each dialing tone.
Hint: To add S-Register settings or other commands to your dialing
procedure, use the new SET MODEM COMMAND PREDIAL-INIT command
([388]Section 2.2.2).
_________________________________________________________________
2.1.9. Pretesting Phone Number Conversions
The LOOKUP command now accepts telephone numbers as well as
directory-entry names, for example:
LOOKUP +1 (212) 7654321
When given a phone number, LOOKUP prints the result of converting the
phone number for dialing under the current dialing rules. For example,
if my country code is 1 and my area code is 212, and I am dialing out
from a PBX whose outside-line prefix is "93,":
C-Kermit> lookup +1 (212) 7654321
+1 (212) 7654321 => 93,7654321
C-Kermit>
You can also use the \fdialconvert(phone-number) function
([389]Section 2.1.11) to do this programmatically:
C-Kermit> echo "\fdialconvert(+1 (212) 7654321)"
"93,7654321"
C-Kermit>
So the new LOOKUP behaves as follows:
LOOKUP portable-format-phone-number
Displays how the number would actually be dialed Sets FAILURE
if there was a conversion error, otherwise SUCCESS.
LOOKUP literal-format-phone-number
Displays the same literal-format-phone-number Always sets
SUCCESS.
LOOKUP dialing-directory-name
Displays all matching entries and converts portable phone
numbers. Sets SUCCESS if at least one entry was found,
otherwise FAILURE.
LOOKUP =anything
Displays "=anything" and sets SUCCESS.
There is, at present, no programmatic way to fetch numbers from the
dialing directory. This will be considered for a future release.
_________________________________________________________________
2.1.10. Greater Control over Partial Dialing
The following rules now apply to partial dialing:
* Phone number transformations based on country and area code,
application of prefixes, etc, are performed only on the first
PDIAL.
* Each PDIAL argument is looked up in the dialing directory, so it
is possible have directory entries for pieces of phone numbers or
other information.
* Suffixes are not applied automatically, since there is no way for
C-Kermit to know in which PDIAL segment you want them to be
applied.
However, the suffix that *would* have been applied, based on the
dialing rules that were invoked when processing the first PDIAL
command, is stored in the variable:
\v(dialsuffix)
which you can include in any subsequent PDIAL or DIAL commands.
Example:
pdial {\m(my_long_distance_pager_number_part_1)}
pdial {\m(my_long_distance_pager_number_part_2)}
pdial {\v(dialsuffix)}
pdial {\m(my_long_distance_pager_number_part_3)}
pdial {@\m(numeric_pager_code)#}
_________________________________________________________________
2.1.11. New DIAL-related Variables and Functions
\fdialconvert(s)
s is a phone number in either literal or portable format (not a
dialing directory entry name). The function returns the dial
string that would actually be used by the DIAL command when
dialing from the current location, after processing country
code, area code, and other SET DIAL values, and should be the
same as the result of LOOKUP when given a telephone number.
\v(dialsuffix)
Contains the suffix, if any, that was applied in the most
recent DIAL command, or the suffix that would have been applied
in the most recent PDIAL command. Use this variable to send the
dial suffix at any desired point in a PDIAL sequence.
\v(dialtype)
A number indicating the type of call that was most recently
placed. Can be used after a normal DIAL command, or after the
first PDIAL command in a PDIAL sequence. Values are:
-2: Unknown because TAPI handled the phone number translation.
-1: Unknown because some kind of error occured.
0: Internal within PBX.
1: Toll-free.
2: Local within calling area.
3: Unknown (e.g. because a literal-format phone number was given).
4: Long distance within country.
5: International
\v(dialcount)
The current value of the DIAL retry counter, for use in a DIAL
macro ([390]Section 2.1.13).
\v(d$px)
PBX Exchange (see [391]Section 2.1.12).
Other dial-related variables, already documented in [392]Using
C-Kermit (or other sections of this document, e.g. [393]Section
2.1.1), include \v(dialnumber), \v(dialstatus), etc. A convenient way
to display all of them is:
show variable dial ; hint: abbreviate "sho var dial"
This shows the values of all the variables whose names start with
"dial". Also "show variable d$" (to show the \v(d$...) variables).
_________________________________________________________________
2.1.12. Increased Flexibility of PBX Dialing
Refer to [394]Using C-Kermit, 2nd Edition, pages 107-108. Recall that
three commands are needed to configure C-Kermit for dialing from a
PBX:
SET DIAL PBX-EXCHANGE number
SET DIAL PBX-INSIDE-PREFIX number
SET DIAL PBX-OUTSIDE-PREFIX number
Unfortunately, this model does not accommodate PBXs that have more
than one exchange. For example our PBX at Columbia University (which
must handle more than 10,000 phones) has 853-xxxx and 854-xxxx
exchanges.
Beginning in C-Kermit 7.0, the SET DIAL PBX-EXCHANGE command accepts a
list of exchanges, e.g.:
SET DIAL PBX-EXCHANGE 853 854
(multiple exchanges are separated by spaces, not commas).
So now when dialing a portable-format number that has the same country
and area codes as those of your dialing location, C-Kermit compares
the exchange of the dialed number with each number in the PBX Exchange
list (rather than with a single PBX Exchange number, as it did
formerly) to determine whether this is an internal PBX number or an
external call. If it is an external call, then the PBX Outside Prefix
is applied, and then the normal dialing rules for local or
long-distance calls.
If it is an inside call, the exchange is replaced by the PBX Inside
Prefix. But if the PBX has more than one exchange, a single fixed PBX
Inside Prefix is probably not sufficient. For example, at Columbia
University, we must dial 3-xxxx for an internal call to 853-xxxx, but
4-xxxx for a call to 854-xxxx. That is, the inside prefix is the final
digit of the exchange we are dialing. For this reason, C-Kermit 7.0
provides a method to determine the inside prefix dynamically at
dialing time, consisting of a new variable and new syntax for the SET
DIAL PBX-INSIDE-PREFIX command:
\v(d$px)
This variable contains the exchange that was matched when a PBX
internal call was detected. For example, if the PBX exchange
list is "853 854" and a call is placed to +1 (212) 854-9999,
\v(d$px) is set to 854.
SET DIAL PBX-INSIDE-PREFIX \fxxx(...)
If the PBX Inside Prefix is defined to be a function, its
evaluation is deferred until dialing time. Normally, this would
be a string function having \v(d$px) as an operand. Of course,
you can still specify a constant string, as before.
So given the following setup:
SET DIAL COUNTRY-CODE 1
SET DIAL AREA-CODE 212
SET DIAL PBX-OUTSIDE-PREFIX 93,
SET DIAL PBX-EXCHANGE 853 854
SET DIAL PBX-INSIDE-PREFIX \fright(\v(d$px),1)
The following numbers give the results indicated:
Number Result
+1 (212) 854-9876 4-9876
+1 (212) 853-1234 3-1234
+1 (212) 765-4321 93,765-4321
+1 (333) 765-4321 93,1333765-4321
Furthermore, the K_PBX_XCH environment variable may now be set to a
list of exchanges to automatically initialize C-Kermit's PBX exchange
list, for example (in UNIX ksh or bash):
export K_PBX_XCH="853 854"
(Quotes required because of the space.) Of course, this variable can
also be set to a single exchange, as before:
export K_PBX_XCH=853
_________________________________________________________________
2.1.13. The DIAL macro - Last-Minute Phone Number Conversions
After a DIAL or LOOKUP command is given, a list of phone numbers is
assembled from the dialing directory (if any), with all
location-dependent conversion rules applied as described in Chapter 5
of [395]Using C-Kermit.
However, additional conversions might still be required at the last
minute based on local or ephemeral conditions. So that you can have
the final word on the exact format of the dial string, C-Kermit 7.0
lets you pass the converted string through a macro of your own design
for final processing before dialing. The relevant command is:
SET DIAL MACRO [ name ]
Specifies the name of a macro to be run on each phone number
after all built-in conversions have been applied, just before
the number is dialed. If no name is given, no macro is run. The
phone number, as it would have been dialed if there were no
dial macro, is passed to the macro.
The dial macro can do anything at all (except start a file transfer).
However, the normal use for the macro would be to modify the phone
number. For this reason the phone number is passed to the macro as
argument number 1 (\%1). To cause a modified number to be dialed, the
macro should terminate with a RETURN statement specifying a return
value. To leave the number alone, the macro should simply end.
Example:
define xxx return 10108889999$\%1
set dial macro xxx
dial xyzcorp
This defines a DIAL MACRO called xxx, which puts an access code on the
front of the number. Another example might be:
def xxx if equal "\v(modem)" "hayes-1200" return \freplace(\%1,$,{,,,,,})
set dial macro xxx
dial xyzcorp
which replaces any dollar-sign in the dial string by a series of five
commas, e.g. because this particular modem does not support the "wait
for bong" feature (remember that commas that are to be included
literally in function arguments must be enclosed in braces to
distinguish them from the commas that separate the arguments) and when
the IF condition is not satisfied, the macro does not return a value,
and so the number is not modified. Then when a DIAL command is given
referencing a dialing directory entry, "xyzcorp". The macro is
automatically applied to each matching number.
Numerous dial-, modem-, communications-, and time-related variables
are available for decision making your dial macro. Type SHOW VARIABLES
for a list. Of particular interest is the \v(dialcount) variable,
which tells how many times the DIAL command gone through its retry
loop: 1 on the first try, 2 on the second, 3 on the third, and so on,
and the \v(dialresult) and \v(dialstatus) variables.
Here are some other applications for the DIAL MACRO (from users):
* Phone numbers in the dialing directory are formatted with '-' for
readability, but some modems don't like the hyphens, so the DIAL
macro is used to remove them before dialing; e.g
0090-123-456-78-99 becomes 00901234567899: "def xxx return
\freplace(\%1,-)".
* To set some specific modem (or other) options depending on the
called customer or telephone number.
* Choosing the most appropriate provider based on (e.g.) time of
day, or cycling through a list of providers in case some providers
might be busy.
To illustrate the final item, suppose you have a choice among many
phone service providers; the provider is chosen by dialing an access
code before the number. Different providers might be better (e.g.
cheaper) for certain times of day or days of the week, or for dialing
certain locations; you can use the DIAL macro to add the access for
the most desirable provider.
Similarly, when the same number might be reached through multiple
providers, it's possible that one provider might not be able to
complete the call, but another one can. In that case, you can use the
DIAL macro to switch providers each time through the DIAL loop --
that's where the \v(dialcount) variable comes in handy.
The following command can be used to debug the DIAL macro:
SET DIAL TEST { ON, OFF }
Normally OFF, so the DIAL command actually dials. When ON, the
DIAL command performs all lookups and number conversions, and
then goes through the number list and retry loop, but instead
of actually dialing, lists the numbers it would have called if
none of the DIAL attempts succeeded (or more precisely, every
number was always busy).
_________________________________________________________________
2.1.14. Automatic Tone/Pulse Dialing Selection
SET DIAL METHOD { AUTO, DEFAULT, PULSE, TONE }
Chooses the dialing method for subsequent calls.
Prior to version 7.0, C-Kermit's DIAL METHOD was DEFAULT by default,
meaning it does not specify a dialing method to the modem, but relies
on the modem to have an appropriate default dialing method set. So,
for example, when using Hayes compatible modems, the dial string would
be something like ATD7654321, rather than ATDT7654321 or ATDP7654321.
In C-Kermit 7.0 and K95 1.1.19, the dial method can be set from the
environment variable:
K_DIAL_METHOD
when Kermit starts. The values can be TONE, PULSE, or DEFAULT, e.g.
(UNIX):
set K_DIAL_METHOD=TONE; export K_DIAL_METHOD
In the absence of a K_DIAL_METHOD definition, the new default SET DIAL
METHOD is AUTO rather than DEFAULT. When DIAL METHOD is AUTO and the
local country code is known, then if tone dialing is universally
available in the corresponding area, tone dialing is used; if dialing
from a location where pulse dialing is mandatory, pulse dialing is
used.
The "tone country" and "pulse country" lists are preloaded according
to our knowledge at the time of release. You can see their contents in
the SHOW DIAL listing. You can change the lists with:
SET DIAL TONE-COUNTRIES [ cc [ cc [ ... ] ] ]
Replaces the current TONE-COUNTRIES list with the one given.
Each cc is a country code; separate them with spaces (not
commas). Example:
set dial tone-countries 1 358 44 46 49
If no country codes are given, the current list, if any, is
removed, in which case SET DIAL METHOD AUTO is equivalent to
SET DIAL METHOD DEFAULT.
SET DIAL PULSE-COUNTRIES [ cc [ cc [ ... ] ] ]
Replaces the current PULSE-COUNTRIES list with the one give.
Syntax and operation is like SET DIAL TONE-COUNTRIES.
If the same country code appears in both lists, Pulse takes
precedence.
The SET DIAL TONE- and PULSE-COUNTRIES commands perform no
verification whatsoever on the cc's, since almost any syntax might be
legal in some settings. Furthermore, there is no facility to edit the
lists; you can only replace the whole list. However, since the only
purpose of these lists is to establish a basis for picking tone or
pulse dialing automatically, all you need to override the effect of
the list is to set a specific dialing method with SET DIAL METHOD TONE
or SET DIAL METHOD PULSE.
_________________________________________________________________
2.1.15. Dial-Modifier Variables
As of C-Kermit 7.0, dial modifiers are available in the following
variables:
\v(dm_lp) Long pause
\v(dm_sp) Short pause
\v(dm_pd) Pulse dial
\v(dm_td) Tone dial
\v(dm_wa) Wait for answer
\v(dm_wd) Wait for dialtone
\v(dm_rc) Return to command mode
You can use these in your dial strings in place of hardwired modifiers
like "@", ",", etc, for increased portability of scripts. Example:
C-Kermit>set modem type usrobotics
C-Kermit>sho variables dm
\v(dm_lp) = ,
\v(dm_sp) = /
\v(dm_pd) = P
\v(dm_td) = T
\v(dm_wa) = @
\v(dm_wd) = W
\v(dm_rc) = ;
C-Kermit>exit
_________________________________________________________________
2.1.16. Giving Multiple Numbers to the DIAL Command
Prior to C-Kermit 7.0, the only way to give a DIAL command a list of
phone numbers to try until one answers was to create a dialing
directory that had multiple entries under the same name, and then use
that entry name in the DIAL command. Now a list of numbers can be
given to the DIAL command directly in the following format:
dial {{number1}{number2}{number3}...}
This is the same list format used by SEND /EXCEPT: and other commands
that allow a list where normally a single item is given. Restrictions
on this form of the DIAL command are:
* The first two braces must be adjacent; spacing is optional
thereafter.
* Each number must be an actual number to dial, not a dialing
directory entry.
* Dialing directory entries may not contain number lists in this
format.
In all other respects, the numbers are treated as if they had been
fetched from the dialing directory; they can be in literal or portable
format, etc. Example:
dial {{7654321} {+1 (212) 5551212} { 1-212-5556789 }}
The list can be any length at all, within reason.
This feature is especially handy for use with the K95 Dialer, allowing
a list of phone numbers to be specified in the Telephone Number box
without having to set up or reference a separate dialing directory.
You can also use it to add commonly-dialed sequences as variables in
your C-Kermit customization file, e.g.:
define work {{7654321}{7654322}{7654323}}
and then:
dial {\m(work)}
(the variable name must be enclosed in braces).
Or more simply:
define work dial {{7654321}{7654322}{7654323}}
and then:
work
_________________________________________________________________
2.2. Modems
2.2.1. New Modem Types
Since C-Kermit 6.0:
atlas-newcom-33600ifxC Atlas/Newcom 33600
att-keepintouch AT&T KeepinTouch PCMCIA V.32bis Card Modem
att-1900-stu-iii AT&T Secure Data STU-III Model 1900
att-1910-stu-iii AT&T Secure Data STU-III Model 1910
bestdata Best Data
cardinal Cardinal V.34 MVP288X series.
compaq Compaq Data+Fax (e.g. in Presario)
fujitsu Fujitsu Fax/Modem Adapter
generic-high-speed Any modern error-correcting data-compressing modem
itu-t-v25ter/v250 ITU-T (CCITT) V.25ter (V.250) standard command set
megahertz-att-v34 Megahertz AT&T V.34
megahertz-xjack Megahertz X-Jack
motorola-codex Motorola Codex 326X Series
motorola-montana Motorola Montana
mt5634zpx Multitech MT5634ZPX
rockwell-v90 Rockwell V.90 56K
rolm-244pc Siemens/Rolm 244PC (AT command set)
rolm-600-series Siemens/Rolm 600 Series (AT command set)
spirit-ii QuickComm Spirit II
suprasonic SupraSonic V288+
supra-express-v90 Supra Express V.90
One of the new types, "generic-high-speed" needs a bit of explanation.
This type was added to easily handle other types that are not
explicitly covered, without going through the bother of adding a
complete user-defined modem type. This one works for modern modems
that use the AT command set, on the assumption that all the default
("factory") settings of the modem (a) are appropriate for Kermit, (b)
include error correction, data compression, and speed buffering; and
(c) are recallable with the command AT&F.
If the command to recall your modem's profile is not AT&F, use the SET
MODEM COMMAND INIT-STRING command to specify the appropriate modem
command. The default init-string is AT&F\13 (that is, AT, ampersand,
F, and then carriage return); a survey of about 20 modern modem types
shows they all support this, but they might mean different things by
it. For example, the USR Sportster or Courier needs AT&F1 (not AT&F,
which is equivalent to AT&F0, which recalls an inappropriate profile),
so for USR modems:
set modem type generic-high-speed
set modem command init AT&F1\13
Of course, USR modems already have their own built-in modem type. But
if you use this one instead, it will dial faster because it has fewer
commands to give to the modem; in that sense "&F1" is like a macro
that bundles numerous commands into a single one. See your modem
manual for details about factory profiles and commands to recall them.
WARNING: Do not use the generic-high-speed modem type in operating
systems like VMS where hardware flow control is not available, at
least not unless you change the init string from AT&F\13 to something
else that enables local Xon/Xoff or other appropriate type of flow
control.
Also see [396]Section 2.1.7 for additional hints about making dialing
go faster.
_________________________________________________________________
2.2.2. New Modem Controls
SET MODEM CAPABILITIES list
In C-Kermit 7.0, this command automatically turns MODEM
SPEED-MATCHING OFF if SB (Speed Buffering) is in the list, and
turns it ON if SB is absent.
SET MODEM COMMAND PREDIAL-INIT [ text ]
Commands to be sent to the modem just prior to dialing.
Normally none.
SET MODEM SPEAKER { ON, OFF }
Determines whether modem speaker is on or off while call is
being placed. ON by default. Note: This command does not
provide fine-grained control over when the speaker is on or
off. Normally, ON means while the call is being placed, until
the point at which carrier is successfully established. If your
modem has a different speaker option that you want to choose,
then use the SET MODEM COMMAND SPEAKER ON text command to
specify this option.
SET MODEM COMMAND SPEAKER { ON, OFF } [ text ]
Specify or override the commands to turn your modem's speaker
on and off.
SET MODEM VOLUME { LOW, MEDIUM, HIGH }
When MODEM SPEAKER is on, select volume. Note: In some modems,
especially internal ones, these commands have no effect; this
is a limitation of the particular modem, not of Kermit.
SET MODEM COMMAND VOLUME { LOW, MEDIUM, HIGH } [ text ]
Specify or override the commands to set your modem's speaker
volume.
SET MODEM COMMAND IGNORE-DIALTONE [ text ]
The command to enable blind dialing ([397]Section 2.1.6).
SET MODEM ESCAPE-CHARACTER code
Has been augmented to allow codes of 0 or less: < 0 means the
escape mechanism is disabled. = 0 means to use (restore) the
default value from the modem database. > 0 and < 128 is a
literal value to be used instead of the default one. > 127
means the escape mechanism is disabled. This affects "modem
hangup". When the escape mechanism is disabled, but SET MODEM
HANGUP-METHOD is MODEM-COMMAND, it sends the hangup command
immediately, without the <pause>+++<pause> business first. This
is useful (for example) when sending lots of numeric pages, a
process in which never we go online, and so never need to
escape back. Eliminating the unnecessary pauses and escape
sequence allows a lot more pages to be sent per unit time.
Recall that C-Kermit can dial modems to which it is connected via
TCP/IP (Telnet or Rlogin) as described on page 126 of [398]Using
C-Kermit, 2nd Ed. In this case the MODEM HANGUP-METHOD should be
MODEM-COMMAND, since RS-232 signals don't work over TCP/IP
connections. As noted in the manual, such connections are set up by
the following sequence:
set host host [ port ]
set modem type name
dial number
But this can cause complications when you use Kermit to switch between
serial and TCP/IP connections. In the following sequence:
set host name
set modem type name
set port name
the first two commands obey the rules for dialing out over Telnet.
However, the SET PORT command requires that Kermit close its current
(Telnet) connection before it can open the serial port (since Kermit
can only have one connection open at a time). But since a modem type
was set after the "set host" command was given, Kermit assumes it is a
Telnet dialout connection and so sends the modem's hangup sequence is
sent to the Telnet host. To avoid this, close the network connection
explicitly before opening the serial one:
set host name
close
set modem type name
set port name
_________________________________________________________________
2.3. TELNET and RLOGIN
For additional background, please also read the [399]TELNET.TXT file,
also available on the Web in [400]HTML format.
Cautions:
* If making a Telnet connection with C-Kermit takes a very long
time, like over a minute, whereas the system Telnet program makes
the same connection immediately, try including the /NOWAIT switch:
C-Kermit> telnet /nowait hostname
See [401]TELNET.TXT or [402]TELNET.HTM for details. If it also
takes a very long time to make a Telnet connection with system
Telnet, then the delay is most likely caused by reverse DNS
lookups when your host is not properly registered in DNS.
* When supplying numeric IP addresses to C-Kermit or to any other
application (regular Telnet, Rlogin, etc), do not include leading
0's in any fields unless you intend for those fields to be
interpreted as octal (or hex) numbers. The description of the
Internet address interpreter (the sockets library inet_addr()
routine) includes these words:
All numbers supplied as "parts" in a "." notation may be decimal,
octal, or hexadecimal, as specified in the C language (that is, a
leading 0x or 0X implies hexadecimal; otherwise, a leading 0
implies octal; otherwise, the number is interpreted as decimal).
To illustrate, 128.59.39.2 and 128.059.039.002 are not the same
host! Even though most of the fields contain non-octal digits.
Using system Telnet (not Kermit):
$ telnet 128.059.039.002
Trying 128.49.33.2 ...
Of course the same thing happens with Kermit because it uses (as
it must) the same system service for resolving network addresses
that Telnet, FTP, and all other TCP/IP applications use.
* The RLOGIN section on page 123 does not make it clear that you can
use the SET TELNET TERMINAL-TYPE command to govern the terminal
type that is reported by C-Kermit to the RLOGIN server.
* Note that the SET TCP commands described on pages 122-123 might be
absent; some platforms that support TCP/IP do not support these
particular controls.
New commands:
TELOPT { AO, AYT, BREAK, CANCEL, EC, EL, EOF, EOR, GA, IP, DMARK,
DO, DONT, NOP, SB, SE, SUSP, WILL, WONT }
This command was available previously, but supported only DO,
DONT, WILL, and WONT. Now it lets you send all the Telnet
protocol commands. Note that certain commands do not require a
response, and therefore can be used as nondestructive "probes"
to see if the Telnet session is still open; e.g.:
set host xyzcorp.com
...
telopt nop
if fail stop 1 Connection lost
SET TCP ADDRESS [ ip-address ]
Specifies the IP address of the computer that C-Kermit is
running on. Normally this is not necessary. The exception would
be if your machine has multiple network adapters (physical or
virtual) with a different address for each adapter AND you want
C-Kermit to use a specific address when making outgoing
connections or accepting incoming connections.
SET TCP DNS-SERVICE-RECORDS { ON, OFF }
Tells C-Kermit whether to try to use DNS SRV records to
determine the host and port number upon which to find an
advertised service. For example, if a host wants regular Telnet
connections redirected to some port other than 23, this feature
allows C-Kermit to ask the host which port it should use. Since
not all domain servers are set up to answer such requests, this
feature is OFF by default.
SET TCP REVERSE-DNS-LOOKUP { ON, OFF, AUTO }
Tells Kermit whether to perform a reverse DNS lookup on TCP/IP
connections. This allows Kermit to determine the actual
hostname of the host it is connected to, which is useful for
connections to host pools, and is required for Kerberos
connections to host pools and for incoming connections. If the
other host does not have a DNS entry, the reverse lookup could
take a long time (minutes) to fail, but the connection will
still be made. Turn this option OFF for speedier connections if
you do not need to know exactly which host you are connected to
and you are not using Kerberos. AUTO, the default, means the
lookup is done on hostnames, but not on numeric IP addresses.
SET TELNET WAIT-FOR-NEGOTIATIONS { ON, OFF }
Each Telnet option must be fully negotiated either On or Off
before the session can continue. This is especially true with
options that require sub-negotiations such as Authentication,
Encryption, and Kermit; for proper support of these options
Kermit must wait for the negotiations to complete. Of course,
Kermit has no way of knowing whether a reply is delayed or not
coming at all, and so will wait a minute or more for required
replies before continuing the session. If you know that
Kermit's Telnet partner will not be sending the required
replies, you can set this option of OFF to avoid the long
timeouts. Or you can instruct Kermit to REFUSE specific options
with the SET TELOPT command.
SET TELOPT [ { /CLIENT, /SERVER } ] option
{ ACCEPTED, REFUSED, REQUESTED, REQUIRED }
[ { ACCEPTED, REFUSED, REQUESTED, REQUIRED } ]
SET TELOPT lets you specify policy requirements for Kermit's
handling of Telnet option negotiations. Setting an option is
REQUIRED causes Kermit to offer the option to the peer and
disconnect if the option is refused. REQUESTED causes Kermit to
offer an option to the peer. ACCEPTED results in no offer but
Kermit will attempt to negotiate the option if it is requested.
REFUSED instructs Kermit to refuse the option if it is
requested by the peer.
Some options are negotiated in two directions and accept
separate policies for each direction; the first keyword applies
to Kermit itself, the second applies to Kermit's Telnet
partner; if the second keyword is omitted, an appropriate
(option-specific) default is applied. You can also include a
/CLIENT or /SERVER switch to indicate whether the given
policies apply when Kermit is the Telnet client or the Telnet
server; if no switch is given, the command applies to the
client.
Note that some of Kermit's Telnet partners fail to refuse
options that they do not recognize and instead do not respond
at all. In this case it is possible to use SET TELOPT to
instruct Kermit to REFUSE the option before connecting to the
problem host, thus skipping the problematic negotiation.
Use SHOW TELOPT to view current Telnet Option negotiation
settings. SHOW TELNET displays current Telnet settings.
_________________________________________________________________
2.3.0. Bug Fixes
If "set host nonexistent-host" was given (and it properly failed),
followed by certain commands like SEND, the original line and modem
type were not restored and C-Kermit thought that it still had a
network hostname; fixed in 7.0.
2.3.1. Telnet Binary Mode Bug Adjustments
SET TELNET BUG BINARY-ME-MEANS-U-TOO { ON, OFF } was added to edit 192
after the book was printed. Also SET TELNET BUG BINARY-U-MEANS-ME-TOO.
The default for both is OFF. ON should be used when communicating with
a Telnet partner (client or server) that mistakenly believes that
telling C-Kermit to enter Telnet binary mode also means that it, too,
is in binary mode, contrary to the Telnet specification, which says
that binary mode must be negotiated in each direction separately.
2.3.2. VMS UCX Telnet Port Bug Adjustment
A new command, SET TCP UCX-PORT-BUG, was added for VMS versions with
UCX (DEC TCP/IP), applying only to early versions of UCX, like 2.2 or
earlier. If you try to use VMS C-Kermit to make a Telnet connection
using a port name (like "telnet", which is used by default), the
underlying UCX getservbyname() function might return the service
number with its bytes swapped and the connection will fail. If "telnet
hostname 23" works, then your version of UCX has this bug and you can
put "set tcp ucx-port-bug on" in your CKERMIT.INI file to get around
it.
2.3.3. Telnet New Environment Option
The TELNET NEW-ENVIRONMENT option ([403]RFC 1572) is supported as 7.0.
This option allows the C-Kermit Telnet client to send certain
well-known variables to the Telnet server, including USER, PRINTER,
DISPLAY, and several others. This feature is enabled by default in
Windows and OS/2, disabled by default elsewhere. The command to enable
and disable it is:
SET TELNET ENVIRONMENT { ON, OFF }
When ON, and you Telnet to another computer, you might (or might not)
notice that the "login:" or "Username:" prompt does not appear --
that's because your username was sent ahead, in which case the remote
system might prompt you only for your password (similar to Rlogin).
Use "set telnet environment off" to defeat this feature, particularly
in scripts where the dialog must be predictable. You can also use this
command to specify or override specific well-known environment
variable values:
SET TELNET ENVIRONMENT { ACCT,DISPLAY,JOB,PRINTER,SYSTEMTYPE,USER } [ text ]
2.3.4. Telnet Location Option
The TELNET LOCATION option ([404]RFC 779) is supported in 7.0. This
option allows the C-Kermit Telnet client to send a location string to
the server if the server indicates its willingness to accept one. If
an environment variable named LOCATION exists at the time C-Kermit
starts, its value is used as the location string. If you want to
change it, use:
SET TELNET LOCATION text
If you omit the text from this command, the Telnet location feature is
disabled.
SET TELNET ENVIRONMENT DISPLAY is used to set the DISPLAY variable
that is sent to the host, as well as the the XDISPLAY location.
2.3.5. Connecting to Raw TCP Sockets
The SET HOST and TELNET commands now accept an optional switch,
/RAW-SOCKET, at the end, only if you first give a host and a port.
Example:
set host xyzcorp.com 23 /raw-socket
set host 128.49.39.2:2000 /raw-socket
telnet xyzcorp.com 3000 /raw
Without this switch, C-Kermit behaves as a Telnet client when (a) the
port is 23 or 1649, or (b) the port is not 513 and the server sent
what appeared to be Telnet negotiations -- that is, messages starting
with 0xFF (IAC). With this switch, Kermit should treat all incoming
bytes as raw data, and will not engage in any Telnet negotiations or
NVT CRLF manipulations. This allows transparent operation through
(e.g.) raw TCP ports on Cisco terminal servers, through the 'modemd'
modem server, etc.
2.3.6. Incoming TCP Connections
Accomplished via SET HOST * port, were introduced in C-Kermit 6.0, but
for UNIX only. In Version 7.0, they are also available for VMS.
_________________________________________________________________
2.4. The EIGHTBIT Command
EIGHTBIT is simply a shorthand for: SET PARITY NONE, SET TERMINAL
BYTESIZE 8, SET COMMAND BYTESIZE 8; that is, a way to set up an 8-bit
clean connection in a single command.
_________________________________________________________________
2.5. The Services Directory
Chapter 7 of [405]Using C-Kermit does not mention the ULOGIN macro,
which is used by our sample services directory, CKERMIT.KND. Unlike
UNIXLOGIN, VMSLOGIN, etc, this one is for use with systems that
require a user ID but no password. Therefore it doesn't prompt for a
password or wait for a password prompt from the remote service.
In version 7.0, the CALL macro was changed to not execute a SET MODEM
TYPE command if the given modem type was the same as the current one;
otherwise the new SET MODEM TYPE command would overwrite any
customizations that the user had made to the modem settings. Ditto for
SET LINE / SET PORT and SET SPEED.
_________________________________________________________________
2.6. Closing Connections
Until version 7.0, there was never an obvious and general way to close
a connection. If a serial connection was open, it could be closed by
"set line" or "set port" (giving no device name); if a network
connection was open, it could be closed by "set host" (no host name).
In version 7.0, a new command closes the connection in an obvious and
straightforward way, no matter what the connection type:
CLOSE [ CONNECTION ]
The CLOSE command was already present, and required an operand such as
DEBUG-LOG, WRITE-FILE, etc, and so could never be given by itself. The
new CONNECTION operand is now the default operand for CLOSE, so CLOSE
by itself closes the connection, if one is open, just as you would
expect, especially if you are a Telnet or Ftp user.
Also see the description of the new SET CLOSE-ON-DISCONNECT command in
[406]Section 2.10.
_________________________________________________________________
2.7. Using C-Kermit with External Communication Programs
C-Kermit 7.0 includes a new ability to create and conduct sessions
through other communications programs. Two methods are available:
1. Pty (pseudoterminal): The external program is run on a
"pseudoterminal", which is controlled by Kermit. This method works
with practically any external program, but it is not portable. At
this writing, it works only on some (not all) UNIX versions, and
not on any non-UNIX platforms.
2. Pipe: The external program's standard input and output are
redirected through a "pipe" controlled by Kermit. This method is
relatively portable -- it should work across all UNIX versions,
and it also works in Windows and OS/2 -- but it is effective only
when the external program actually uses standard i/o (and many
don't).
The two methods are started differently but are used the same way
thereafter.
The purpose of this feature is to let you use C-Kermit services like
file transfer, character-set translation, scripting, automatic
dialing, etc, on connections that Kermit can't otherwise make itself.
This feature is the opposite of the REDIRECT feature, in which
C-Kermit makes the connection, and redirects an external (local)
command or program over this connection. In a pty or pipe connection,
C-Kermit runs and controls a local command or program, which makes the
connection. (The same method can be used to simply to control a local
program without making a connection; see [407]Section 2.8.)
To find out if your version of Kermit includes PTY support, type "show
features" and look for NETPTY in the alphabetical list of options. For
pipes, look for NETCMD.
The commands are:
SET NETWORK TYPE PTY or SET NETWORK TYPE PIPE
SET HOST command
where command is any interactive command. If the command does
not use standard i/o, you must use SET NETWORK TYPE PTY.
Notes:
* COMMAND is an invisible synonym for PIPE.
* The command and its arguments are case-sensitive in UNIX.
The SET NETWORK TYPE, SET HOST sequence sets the given network type
for all subsequent SET HOST commands until another SET NETWORK TYPE
command is given to change it.
You can also use the new /NETWORK-TYPE:PTY or /NETWORK-TYPE:PIPE (or
simply /PIPE or /PTY) switches on the SET HOST command itself:
SET HOST /NETWORK-TYPE:PIPE command ; These two are the same
SET HOST /PIPE command
SET HOST /NETWORK-TYPE:PTY command ; Ditto
SET HOST /PTY command
These are like SET NETWORK TYPE followed by SET HOST, except they
apply only to the connection being made and do not change the global
network type setting (see [408]Section 1.5 about the difference
between switches and SET commands).
Include any command-line options with the command that might be
needed, as in this example where C-Kermit uses another copy of itself
as the communications program:
SET HOST /PIPE /CONNECT kermit -YQJ xyzcorp.com
As usual, if you include the /CONNECT switch, SET HOST enters CONNECT
mode immediately upon successful execution of the given command.
Therefore new commands are available as a shorthand for SET HOST
/CONNECT /PTY and /PIPE:
PTY [ command ]
PIPE [ command ]
The PTY and PIPE commands work like the TELNET and RLOGIN
commands: they set up the connection (in this case, using the
given command) and then enter CONNECT mode automatically (if
the PIPE or PTY command is given without a command, it
continues the current session if one is active; otherwise it
gives an error message).
The PIPE command is named after the mechanism by which C-Kermit
communicates with the command: UNIX pipes. C-Kermit's i/o is "piped"
through the given command. Here is a typical example:
PIPE rlogin -8 xyzcorp.com
This is equivalent to:
SET HOST /PIPE rlogin -8 xyzcorp.com
CONNECT
and to:
SET HOST /PIPE /CONNECT rlogin -8 xyzcorp.com
IMPORTANT:
If you are writing a script, do not use the PIPE, PTY, TELNET,
or RLOGIN command unless you really want C-Kermit to enter
CONNECT mode at that point. Normally SET HOST is used in
scripts to allow the login and other dialogs to be controlled
by the script itself, rather than by an actively participating
human at the keyboard.
Throughput of pty and pipe connections is limited by the performance
of the chosen command or program and by the interprocess communication
(IPC) method used and/or buffering capacity of the pipe or pty, which
in turn depends on the underlying operating system.
In one trial (on SunOS 4.1.3), we observed file transfer rates over an
rlogin connection proceeding at 200Kcps for downloads, but only 10Kcps
for uploads on the same connection with the same settings (similar
disparities were noted in HP-UX). Examination of the logs revealed
that a write to the pipe could take as long as 5 seconds, whereas
reads were practically instantaneous. On the other hand, using Telnet
as the external program rather than rlogin, downloads and uploads were
better matched at about 177K each.
Most external communication programs, like C-Kermit itself, have
escape characters or sequences. Normally these begin with (or consist
entirely of) a control character. You must be sure that this control
character is not "unprefixed" when uploading files, otherwise the
external program will "escape back" to its prompt, or close the
connection, or take some other unwanted action. When in CONNECT mode,
observe the program's normal interaction rules. Of course C-Kermit's
own escape character (normally Ctrl-\) is active too, unless you have
taken some action to disable it.
On PTY connections, the underlying PTY driver is not guaranteed to be
transparent to control characters -- for example, it might expand
tabs, translate carriage returns, generate signals if it sees an
interrupt character, and so on. Similar things might happen on a PIPE
connection. For this reason, if you plan to transfer files over a PTY
or PIPE connection, tell the file sender to:
SET PREFIXING ALL
This causes all control characters to be prefixed and
transmitted as printable ASCII characters.
If the external connection program is not 8-bit clean, you should
also:
SET PARITY SPACE
This causes 8-bit data to be encoded in 7 bits using single
and/or locking shifts.
And if it does not make a reliable connection (such as those made by
Telnet, Rlogin, Ssh, etc), you should:
SET STREAMING OFF
This forces C-Kermit to treat the connection as unreliable and
to engage in its normal ACK/NAK protocol for error detection
and correction, rather than "streaming" its packets, as it
normally does on a network connection ([409]Section 4.20).
In some cases, buffer sizes might be restricted, so you might also
need to reduce the Kermit packet length to fit; this is a
trial-and-error affair. For example, if transfers always fail with
4000-byte packets, try 2000. If that fails too, try 1000, and so on.
The commands are:
SET RECEIVE PACKET-LENGTH number
This tells the file receiver to tell the file sender the
longest packet length it can accept.
SET SEND PACKET-LENGTH number
This tells the file sender not to send packets longer than the
given length, even if the receiver says longer ones are OK. Of
course, if the receiver's length is shorter, the shorter length
is used.
If none of this seems to help, try falling back to the bare minimum,
lowest-common-denominator protocol settings:
ROBUST
No sliding windows, no streaming, no control-character
unprefixing, packet length 90.
And then work your way back up by trial and error to get greater
throughput.
Note that when starting a PIPE connection, and the connection program
(such as telnet or rlogin) prints some greeting or information
messages before starting the connection, these are quite likely to be
printed with a stairstep effect (linefeed without carriage return).
This is because the program is not connected with the UNIX terminal
driver; there's not much Kermit can do about it. Once the connection
is made, everything should go back to normal. This shouldn't happen on
a PTY connection because a PTY is, indeed, a terminal.
On a similar note, some connection programs (like Solaris 2.5 rlogin)
might print lots of error messages like "ioctl TIOCGETP: invalid
argument" when used through a pipe. They are annoying but usually
harmless. If you want to avoid these messages, and your shell allows
redirection of stderr, you can redirect stderr in your pipe command,
as in this example where the user's shell is bash:
PIPE rlogin xyzcorp.com 2> /dev/null
Or use PTY rather than PIPE, since PTY is available on Solaris.
_________________________________________________________________
2.7.0. C-Kermit over tn3270 and tn5250
Now you can make a connection from C-Kermit "directly" to an IBM
mainframe and transfer files with it, assuming it has Kermit-370
installed. Because tn3270 is neither 8-bit clean nor transparent to
control characters, you must give these commands:
SET PREFIXING ALL ; Prefix all control characters
SET PARITY SPACE ; Telnet connections are usually not 8-bit clean
and then:
SET HOST /PTY /CONNECT tn3270 abccorp.com
or simply:
pty tn3270 abccorp.com
SET HOST /PIPE does not work in this case, at least not for file
transfer. File transfer does work, however, with SET HOST /PTY,
provided you use the default packet length of 90 bytes; anything
longer seems to kill the session.
You can also make connections to IBM AS/400 computers if you have a
tn5250 program installed:
pty tn5250 hostname
In this case, however, file transfer is probably not in the cards
since nobody has ever succeeded in writing a Kermit program for the
AS/400. Hint:
define tn3270 {
check pty
if fail end 1 Sorry - no PTY support...
pty tn3270 \%*
}
Similarly for tn5250. Note that CHECK PTY and CHECK PIPE can be used
in macros and scripts to test whether PTY or PIPE support is
available.
_________________________________________________________________
2.7.1. C-Kermit over Telnet
Although C-Kermit includes its own Telnet implementation, you might
need to use an external Telnet program to make certain connections;
perhaps because it has access or security features not available in
C-Kermit itself. As noted above, the only precautions necessary are
usually:
SET PREFIXING ALL ; Prefix all control characters
SET PARITY SPACE ; Telnet connections might not be 8-bit clean
and then:
SET HOST /PTY (or /PIPE) /CONNECT telnet abccorp.com
or, equivalently:
PTY (or PIPE) telnet abccorp.com
_________________________________________________________________
2.7.2. C-Kermit over Rlogin
C-Kermit includes its own Rlogin client, but this can normally be used
only if you are root, since the rlogin TCP port is privileged. But
ptys and pipes let you make rlogin connections with C-Kermit through
your computer's external rlogin program, which is normally installed
as a privileged program:
SET PREFIXING ALL
and then:
SET HOST /PTY (or /PIPE) /CONNECT rlogin -8 abccorp.com
or, equivalently:
PTY (or PIPE) rlogin -8 abccorp.com
The "-8" option to rlogin enables transmission of 8-bit data. If this
is not available, then include SET PARITY SPACE if you intend to
transfer files.
Note that the normal escape sequence for rlogin is Carriage Return
followed by Tilde (~), but only when the tilde is followed by certain
other characters; the exact behavior depends on your rlogin client, so
read its documentation.
_________________________________________________________________
2.7.3. C-Kermit over Serial Communication Programs
Ptys and pipes also let you use programs that make serial connections,
such as cu or tip. For example, C-Kermit can be used through cu to
make connections that otherwise might not be allowed, e.g. because
C-Kermit is not installed with the required write permissions to the
dialout device and the UUCP lockfile directory.
Suppose your UUCP Devices file contains an entry for a serial device
tty04 to be used for direct connections, but this device is protected
against you (and Kermit when you run it). In this case you can:
SET CONTROL PREFIX ALL
PTY (or PIPE) cu -l tty04
(Similarly for dialout devices, except then you also need to include
the phone number in the "cu" command.)
As with other communication programs, watch out for cu's escape
sequence, which is the same as the rlogin program's: Carriage Return
followed by Tilde (followed by another character to specify an action,
like "." for closing the connection and exiting from cu).
_________________________________________________________________
2.7.4. C-Kermit over Secure Network Clients
DISCLAIMER: There are laws in the USA and other countries regarding
use, import, and/or export of encryption and/or decryption or other
forms of security software, algorithms, technology, and
intellectual property. The Kermit Project attempts to follow all
known statutes, and neither intends nor suggests that Kermit
software can or should be used in any way, in any location, that
circumvents any regulations, laws, treaties, covenants, or other
legitimate canons or instruments of law, international relations,
trade, ethics, or propriety.
For secure connections or connections through firewalls, C-Kermit 7.0
can be a Kerberos, SRP, and/or SOCKS client when built with the
appropriate options and libraries. But other application-level
security acronyms and methods -- SSH, SSL, SRP, TLS -- pop up at an
alarming rate and are (a) impossible to keep up with, (b) usually
mutually incompatible, and (c) have restrictions on export or
redistribution and so cannot be included in C-Kermit itself.
However, if you have a secure text-based Telnet (or other) client that
employs one of these security methods, you can use C-Kermit "through"
it via a pty or pipe.
_________________________________________________________________
2.7.4.1. SSH
C-Kermit does not and can not incorporate SSH due to licensing,
patent, and USA export law restrictions.
The UNIX SSH client does not use standard input/output, and therefore
can be used only by Kermit's PTY interface, if one is present. The
cautions about file transfer, etc, are the same as for Rlogin.
Example:
SET PREFIXING ALL
PTY ssh XYZCORP.COM
Or, for a scripted session:
SET PREFIXING ALL
SET HOST /PTY ssh XYZCORP.COM
Hint:
define ssh {
check pty
if fail end 1 Sorry - no PTY support...
pty ssh \%*
}
_________________________________________________________________
2.7.4.2. SSL
Secure Sockets Layer (SSL) is another TCP/IP security overlay, this
one designed by and for Netscape. An SSL Telnet client is available
for UNIX from the University of Queensland. More info at:
[410]http://www.psy.uq.oz.au/~ftp/Crypto/
Interoperability with C-Kermit is unknown. C-Kermit also includes its
own built-in SSL/TLS support, but it is not exportable; [411]CLICK
HERE file for details.
_________________________________________________________________
2.7.4.3. SRP
SRP(TM) is Stanford University's Secure Remote Password protocol. An
SRP Telnet client is available from Stanford:
[412]http://srp.stanford.edu/srp/
Stanford's SRP Telnet client for UNIX has been tested on SunOS and
works fine with C-Kermit, as described in [413]Section 2.7.1, e.g.
SET PREFIX ALL
PTY (or PIPE) srp-telnet xenon.stanford.edu
C-Kermit itself can be built as an SRP Telnet client on systems that
have libsrp.a installed; the C-Kermit support code, however, may not
be exported outside the USA or Canada.
_________________________________________________________________
2.7.4.4. SOCKS
C-Kermit can be built as a SOCKS-aware client on systems that have a
SOCKS library. See section 8.1.1 of the [414]ckccfg.txt file.
C-Kermit 7.0 can also be run over SOCKSified Telnet or rlogin clients
with SET NETWORK TYPE COMMAND. Suppose the Telnet program on your
system is SOCKS enabled but C-Kermit is not. Make Kermit connections
like this:
SET PREFIX ALL
PTY (or PIPE) telnet zzz.com
_________________________________________________________________
2.7.4.5. Kerberos
UNIX C-Kermit can be built with MIT Kerberos IV or V authentication
and encryption. Instructions are available in a [415]separate
document. Additional modules are required that can not be exported
from the USA to any country except Canada, by US law.
If you have Kerberos installed but you don't have a Kerberized version
of C-Kermit, you can use ktelnet as C-Kermit's external communications
program to make secure connections without giving up C-Kermit's
services:
SET PREFIX ALL
PTY (or PIPE) ktelnet cia.gov
_________________________________________________________________
2.8. Scripting Local Programs
If your version of Kermit has PTY support built in, then any
text-based program can be invoked with SET HOST /PTY or equivalent
command and controlled using the normal sequence of OUTPUT, INPUT, IF
SUCCESS commands (this is the same service that is provided by the
'expect' program, but controlled by the Kermit script language rather
than Tcl).
When PTY service is not available, then any program that uses standard
input and output can be invoked with SET HOST /PIPE.
Here's an example in which we start an external Kermit program, wait
for its prompt, give it a VERSION command, and then extract the
numeric version number from its response:
set host /pty kermit -Y
if fail stop 1 {Can't start external command}
input 10 C-Kermit>
if fail stop 1 {No C-Kermit> prompt}
output version\13
input 10 {Numeric: }
if fail stop 1 {No match for "Numeric:"}
clear input
input 10 \10
echo VERSION = "\fsubstr(\v(input),1,6)"
output exit\13
This technique could be used to control any other interactive program,
even those that do screen formatting (like Emacs or Vi), if you can
figure out the sequence of events. If your Kermit program doesn't have
PTY support, then the commands are restricted to those using standard
i/o, including certain shells, interactive text-mode "hardcopy"
editors like ex, and so on.
If you are using the PTY interface, you should be aware that it runs
the given program or command directly on the pty, without any
intervening shell to interpret metacharacters, redirectors, etc. If
you need this sort of thing, include the appropriate shell invocation
as part of your command; for example:
pty echo *
just echoes "*"; whereas:
pty ksh -c "echo *"
echoes all the filenames that ksh finds matching "*".
Similarly for redirection:
set host /pty ksh -c "cat > foo" ; Note: use shell quoting rules here
set transmit eof \4
transmit bar
And for that matter, for built-in shell commands:
set host /pty ksh -c "for i in *; do echo $i; done"
The PIPE interface, on the other hand, invokes the shell
automatically, so:
pipe echo *
prints filenames, not "*".
_________________________________________________________________
2.9. X.25 Networking
X.25 networking is documented in [416]Using C-Kermit, 2nd Edition.
When the book was published, X.25 was available only in SunOS,
Solaris, and Stratus VOS. Unlike TCP/IP, X.25 APIs are not
standardized; each vendor's X.25 libraries and services (if they have
them at all) are unique.
This section describes new additions.
_________________________________________________________________
2.9.1. IBM AIXLink/X.25 Network Provider Interface for AIX
Support for X.25 was added via IBM's Network Provider Interface (NPI),
AIXLink/X.25 1.1, to the AIX 4.x version of C-Kermit 7.0.
Unfortunately, AIXLink/X.25 is a rather bare-bones facility, lacking
in particular any form of PAD support (X.3, X.28, X.29). Thus, the AIX
version of C-Kermit, when built to include X.25 networking, has
neither a PAD command, nor a SET PAD command. The same is true for the
underlying AIX system: no PAD support. Thus it is not possible to have
an interactive shell session over an X.25 connection into an AIX
system (as far as we know), even from X.25-capable Kermit versions
(such as Solaris or VOS) that do include PAD support.
Thus the X.25 capabilities in AIX C-Kermit are limited to peer-to-peer
connections, e.g. from a C-Kermit client to a C-Kermit server. Unlike
the Solaris, SunOS, and VOS versions, the AIX version can accept
incoming X.25 connections:
set network type x.25
if fail stop 1 Sorry - no X.25 support
; Put any desired DISABLE or ENABLE or SET commands here.
set host /server *
if fail stop 1 X.25 "set host *" failed
And then access it from the client as follows:
set network type x.25
if fail stop 1 Sorry - no X.25 support
set host xxxxxxx ; Specify the X.25/X.121 address
if fail stop 1 Can't open connection
And at this point the client can use the full range of client
commands: SEND, GET, REMOTE xxx, FINISH, BYE.
The AIX version also adds two new variables:
\v(x25local_nua)
The local X.25 address.
\v(x25remote_nua)
The X.25 address of the host on the other end of the
connection.
C-Kermit's AIX X.25 client has not been tested against anything other
than a C-Kermit X.25 server on AIX. It is not known if it will
interoperate with C-Kermit servers on Solaris, SunOS, or VOS.
To make an X.25 connection from AIX C-Kermit, you must:
set x25 call-user-data xxxx
where xxxx can be any even-length string of hexadecimal digits, e.g.
123ABC.
_________________________________________________________________
2.9.2. HP-UX X.25
Although C-Kermit presently does not include built-in support for
HP-UX X.25, it can still be used to make X.25 connections as follows:
start Kermit and tell it to:
set prefixing all
set parity space
pty padem address
This should work in HP-UX 9.00 and later (see [417]Section 2.7). If
you have an earlier HP-UX version, or the PTY interface doesn't work
or isn't available, try:
set prefixing all
set parity space
pipe padem address
Failing that, use Kermit to telnet to localhost and then after logging
back in, start padem as you would normally do to connect over X.25.
_________________________________________________________________
2.10. Additional Serial Port Controls
C-Kermit 7.0 adds the following commands for greater control over
serial ports. These commands are available only in C-Kermit versions
whose underlying operating systems provide the corresponding services
(such as POSIX and UNIX System V), and even then their successful
operation depends on the capabilities of the specific device and
driver.
SET DISCONNECT { ON, OFF }
On a SET LINE or SET PORT connection with SET CARRIER ON or
AUTO, if the carrier signal drops during the connection,
indicating that the connection has been lost, and C-Kermit
notices it, this setting governs what happens next. With SET
DISCONNECT OFF, which is consistent with previous behavior, and
therefore the default, C-Kermit continues to keep the device
open and allocated. With SET DISCONNECT ON, C-Kermit
automatically closes and releases the device when it senses a
carrier on-to-off transition, thus allowing others to use it.
However, it remains the default device for i/o (DIAL, REDIAL,
INPUT, SEND, CONNECT, etc), so if a subsequent i/o command is
given, the device is reopened if it is still available. When it
has been automatically closed in this manner, SHOW
COMMUNICATIONS puts "(closed)" after its name, and in UNIX, the
lockfile disappears -- both from SHOW COMM and from the
lockfile directory itself. Synonym: SET CLOSE-ON-DISCONNECT.
SET EXIT ON-DISCONNECT { ON, OFF }
Like DISCONNECT, but makes the program exit if a connection
drops.
Note that SET CLOSE-ON-DISCONNECT and SET EXIT ON-DISCONNECT apply
only to connections that drop; they do not apply to connections that
can't be made in the first place. For example, they have no effect
when a SET LINE, SET HOST, TELNET, or DIAL command fails.
HANGUP
If [CLOSE-ON-]DISCONNECT is ON, and the HANGUP command is given
on a serial device, and the carrier signal is no longer present
after the HANGUP command, the device is closed and released.
SET PARITY HARDWARE { EVEN, ODD }
Unlike SET PARITY { EVEN, ODD, MARK, SPACE }, which selects 7
data bits plus the indicated kind of parity (to be done in
software by Kermit itself), SET PARITY HARDWARE selects 8 data
bits plus even or odd parity, to be done by the underlying
hardware, operating system, or device driver. This command is
effective only with a SET LINE or SET PORT device. That is, it
has no effect in remote mode, nor on network connections. There
is presently no method for selecting 8 data bits plus mark or
space parity. If hardware parity is in effect, the variable
\v(hwparity) is set to "even" or "odd". Note: some platforms
might also support settings of SPACE, MARK, or NONE.
SET STOP-BITS { 1, 2 }
This tells the number of 1-bits to insert after an outbound
character's data and parity bits, to separate it from the next
character. Normally 1. Choosing 2 stop bits should do no harm,
but will slow down serial transmission by approximately 10
percent. Historically, 2 stop bits were used with Teletypes (at
110 bps or below) for print-head recovery time. There is
presently no method for choosing any number of stop bits
besides 1 and 2.
SET SERIAL [ dps ]
dps stands for Data-bits, Parity, Stop-bits. This is the
notation familiar to many people for serial port configuration:
7E1, 8N1, 7O2, etc. The data bits number also becomes the
TERMINAL BYTESIZE setting. The second character is E for Even,
O for Odd, M for Mark, S for Space, or N for None. The list of
available options depends on the capabilities of the specific
platform. If dps is omitted, 8N1 is used. Type "set serial ?"
for a list of available choices. Examples:
SET SERIAL 7E1
Equivalent to SET PARITY EVEN, SET STOP-BITS 1, SET TERM
BYTE 7.
SET SERIAL 8N1
Equivalent to SET PARITY NONE, SET STOP-BITS 1, SET TERM
BYTE 8.
SET SERIAL 7E2
Equivalent to SET PARITY EVEN and SET STOP-BITS 2, SET
TERM BYTE 7.
SET SERIAL 8E2
Same as SET PARITY HARDWARE EVEN, SET STOP-BITS 2, SET
TERM BYTE 8.
SET SERIAL
Same as SET PARITY NONE and SET STOP-BITS 1, SET TERM
BYTE 8.
Notes:
* The SET SERIAL xx2 options are available only in Kermit versions
where the SET PARITY HARDWARE command is also available. (SHOW
FEATURES includes "HWPARITY" in its options list.)
* The SET SERIAL 7xx and 8N1 options affect the software parity
setting, even for network connections.
* As noted in the manual, selecting 8 data bits does not give you
8-bit terminal sessions in CONNECT mode unless you also SET
TERMINAL BYTESIZE 8. The default terminal bytesize remains 7, to
protect against the situation where the remote host is generating
parity but you don't know about it. If the terminal bytesize was 8
by default and you CONNECTed to such a host, you would see only
garbage on your screen.
* If you do not give a SET STOP-BITS or SET SET SERIAL command,
C-Kermit does not attempt to set the device's stop bits; instead,
it uses whatever setting the device uses when not given explicit
instructions about stop bits.
SHOW COMMUNICATIONS displays the current settings. Stop bits and
hardware parity are shown only for SET PORT / SET LINE (serial)
devices, since they do not apply to network connections or to remote
mode. STOP-BITS is shown as "(default)" if you have not given an
explicit SET STOP-BITS or SET SERIAL command.
The \v(serial) variable shows the SET SERIAL setting (8N1, 7E1, etc).
_________________________________________________________________
2.11. Getting Access to the Dialout Device
This section is for UNIX only; note the special words about QNX at
the end. Also see [418]Section 2.0 for SET LINE switches,
particularly the /SHARE switch for VMS only.
C-Kermit does its best to obey the UUCP lockfile conventions of each
platform (machine, operating system, OS version) where it runs, if
that platform uses UUCP.
But simply obeying the conventions is often not good enough, due to
the increasing likelihood that a particular serial device might have
more than one name (e.g. /dev/tty00 and /dev/term/00 are the same
device in Unixware 7; /dev/cua and /dev/cufa are the same device in
NeXTSTEP), plus the increasingly widespread use of symlinks for device
names, such as /dev/modem.
C-Kermit 7.0 goes to greater lengths than previous versions to
successfully interlock with other communications program (and other
instances of Kermit itself); for example, by:
* Creation of dual lockfiles whenever a symlink is used; one for the
link name and one for the real name.
* Creation of dual lockfiles in HP-UX according to HP rules.
* Creation of dual uppercase/lowercase lockfile names in SCO
UNIX/ODT/OSR5.
* The use of ttylock() in versions of AIX where it works.
* The use, wherever possible, of lockfile names based on
inode/major/minor device number rather than device name.
See the [419]ckuins.txt and [420]ckubwr.txt files for details.
QNX is almost unique among UNIX varieties in having no UUCP programs
nor UUCP-oriented dialout-device locking conventions. QNX does,
however, allow a program to get the device open count. This can not be
a reliable form of locking unless all applications do it (and they
don't), so by default, Kermit uses this information only for printing
a warning message such as:
C-Kermit>set line /dev/ser1
WARNING - "/dev/ser1" looks busy...
However, if you want to use it as a lock, you can do so with:
SET QNX-PORT-LOCK { ON, OFF }
QNX-PORT-LOCK is OFF by default; if you set in ON, C-Kermit fails to
open any dialout device when its open count indicates that another
process has it open. SHOW COMM (in QNX only) displays the setting, and
if you have a port open, it also shows the current open count (with
C-Kermit's own access always counting as 1).
_________________________________________________________________
2.12. The Connection Log
C-Kermit 7.0 adds the ability to log connections, so you can see where
you've been and have a record of calls you've made. A connection is
defined as any communications session that is begun by SET LINE, SET
PORT, DIAL, SET HOST, TELNET, or RLOGIN. Connections are not logged
unless you request it; the command is:
LOG CX [ filename [ { NEW, APPEND } ] ]
Enables logging of connections in the given file. If the
trailing { NEW, APPEND } keyword is omitted, the file is opened
for appending; i.e. new records are written to the end. If NEW
is specified, a new file is created; if a file of the same name
already existed, it is overwritten. If the filename is omitted,
CX.LOG in your home (login) directory is used (note:
uppercase). To accept all defaults, just use "log connections"
(or "l c" for short). Synonym: LOG CONNECTIONS.
CLOSE CX-LOG
This closes the connection log if it was open. (Note, the CLOSE
CONNECTION command closes the connection itself).
SHOW CX
This shows your current connection, if any, including the
elapsed time (since you opened it). Synonym: SHOW CONNECTION.
\v(cx_time)
This variable shows the elapsed time of your current
connection, or if there is no current connection, of your most
recent connection, of if there have been no connections, 0.
The connection contains one line per connection, of the form:
yyyymmdd hh:mm:ss username pid p=v [ p=v [ ... ] ]
where the timestamp (in columns 1-18) shows when the connection was
made; username is the login identity of the person who made the
connection; pid is Kermit's process ID when it made the connection.
The p's are parameters that depend on the type of connection, and the
v's are their values:
T = Connection Type (TCP, SERIAL, DIAL, DECNET, etc).
H = The name of the Host from which the connection was made.
N = Destination phone Number or Network host name or address.
D = Serial connections only: Device name.
O = Dialed calls only: Originating country code & area code if known.
E = Elapsed time in hh:mm:ss format (or hhh:mm:ss, etc).
If you always want to keep a connection log, simply add:
log connections
to your C-Kermit customization file. Note, however, that if you make a
lot of connections, your CX.LOG will grow and grow. You can handle
this by adding a "logrotate" procedure like the following to your
customization file, before the "log connections" command:
define LOGROTATE { ; Define LOGROTATE macro
local \%i \%m \%d \%n \%f MAX
def MAX 4 ; How many months to keep
if not def \%1 - ; No argument given
end 1 \%0: No filename given
if not = 1 \ffiles(\%1) - ; Exactly 1 file must match
end 1 \%0: \%1 - File not found
.\%d := \fsubstr(\fdate(\%1),1,6) ; Arg OK - get file year & month
if = \%d - ; Compare file year & month
\fsubstr(\v(ndate),1,6) - ; with current year & month
end 0 ; Same year & month - done
rename \%1 \%1.\%d ; Different - rename file
.\%n := \ffiles(\%1.*) ; How many old files
if < \%n \m(MAX) end 0 ; Not enough to rotate
.\%m := \%1.999999 ; Initial compare string
for \%i 1 \%n 1 { ; Loop thru old logs
.\%f := \fnextfile() ; Get next file name
if llt \%f \%m .\%m := \%f ; If this one older remember it
}
delete \%m ; Delete the oldest one
}
log connections ; Now open the (possibly new) log
logrotate \v(home)CX.LOG ; Run the LOGROTATE macro
As you can see, this compares the yyyymm portion of the modification
date (\fdate()) of the given file (\%1) with the current yyyymm. If
they differ, the current file has the yyyymm suffix (from its most
recent modification date) appended to its name. Then we search through
all other such files, find the oldest one, and delete it. Thus the
current log, plus the logs from the most recent four months, are kept.
This is all done automatically every time you start C-Kermit.
On multiuser systems, it is possible to keep a single, shared,
system-wide connection log, but this is not recommended since (a) it
requires you keep a publicly write-accessible logfile (a glaring
target for mischief), and (b) it would require each user to log to
that file and not disable logging. A better method for logging
connections, in UNIX at least, is syslogging (see [421]ckuins.txt
Section 15 and [422]Section 4.2 of the [423]IKSD Administration Guide
for details).
_________________________________________________________________
2.13. Automatic Connection-Specific Flow Control Selection
Beginning in C-Kermit 7.0, the appropriate flow-control method for
each connection type is kept in a table, for example:
Remote: NONE
Modem: RTS/CTS
Direct-Serial: NONE
TCPIP: NONE
The size of the table and values for each connection type can vary
from platform to platform. Type "set flow ?" for a list of available
flow-control types.
The table is used to automatically select the appropriate kind of flow
control whenever you make a connection. You can display the table
with:
SHOW FLOW-CONTROL
The defaults are as follows:
Remote:
NONE or XON/XOFF. This is because C-Kermit is not allowed to
find out what type of connection the incoming user has (*). No
kind of flow control will work on every kind of connection,
including (unexpectedly) KEEP, which we would have liked to
use, but not turning off flow control at the remote end during
file transfer on TCP/IP connections is fatal to the transfer
(except in VMS and HP-UX, where it must be set to Xon/Xoff!)
Therefore if you are dialing in to a serial port on a server
(UNIX or VMS) where C-Kermit is running, you will need to tell
C-Kermit to "set flow keep" before transferring files (assuming
the modem and port are configured correctly by the system
administrator; otherwise you'll need to give a specific kind of
flow control, e.g. "set flow xon/xoff"), so in this case
C-Kermit will not disable flow control, as it must do when you
are coming via Telnet (directly or through a terminal server,
except on VMS and HP-UX).
Modem:
This applies when you dial out with a modem. In this case, the
MODEM FLOW-CONTROL setting takes affect after the SET FLOW
setting, so it can pick the most appropriate flow control for
the combination of the particular modem and the
computer/port/driver that is dialing.
Direct-Serial:
The default here is NONE because C-Kermit has no way of knowing
what kind of flow control, if any, is or can be done by the
device at the other end of the connection. RTS/CTS would be a
bad choice here, because if the CTS signal is not asserted, the
connection will hang. And since direct connections are often
made with 3-wire cables, there is a good chance the CTS signal
will not be received.
TCPIP:
NONE, since TCP and IP provide their own flow control
transparently to the application, except in VMS, where Xon/Xoff
is the default due to the requirements of the VMS TCP/IP
products.
Other networks:
NONE, since networks should provide their flow control
transparently to the application.
(*) This is possibly the worst feature of UNIX, VMS, and other
platforms where C-Kermit runs. If C-Kermit was able to ask the
operating system what kind of connection it had to the user, it could
set up many things for you automatically.
You can modify the default-flow-control table with:
SET FLOW-CONTROL /xxx { NONE, KEEP, RTS/CTS, XON/XOFF, ... }
where "xxx" is the connection type, e.g.
SET FLOW /REMOTE NONE
SET FLOW /DIRECT RTS/CTS
If you leave out the switch, SET FLOW works as before, choosing the
flow control method to be used on the current connection:
SET FLOW XON/XOFF
Thus, whenever you make a connection with SET PORT, SET LINE, DIAL,
SET HOST, TELNET, RLOGIN, etc, an appropriate form of flow control is
selected automatically. You can override the automatic selection with
a subsequent SET FLOW command, such as SET FLOW NONE (no switch
included).
The flow control is changed automatically too when you give a SET
MODEM TYPE command. For example, suppose your operating system (say
Linux) supports hardware flow control (RTS/CTS). Now suppose you give
the following commands:
set line /dev/ttyS2 ; Automatically sets flow to NONE
set modem type usr ; Automatically sets flow to RTS/CTS
set modem type rolm ; Doesn't support RTS/CTS so now flow is XON/XOFF
IMPORTANT: This new feature tends to make the order of SET LINE/HOST
and SET FLOW commands matter, where it didn't before. For example, in
VMS:
SET FLOW KEEP
SET LINE TTA0:
the SET LINE undoes the SET FLOW KEEP command; the sequence now must
be:
SET FLOW /DIRECT KEEP
SET LINE TTA0:
or:
SET LINE TTA0:
SET FLOW KEEP
_________________________________________________________________
2.14. Trapping Connection Establishment and Loss
If you define a macro called ON_OPEN, it is executed any time that a
SET LINE, SET PORT, SET HOST, TELNET, RLOGIN or similar command
succeeds in opening a connection. The argument is the host or device
name (as shown by SHOW COMMUNICATIONS, and the same as \v(line)). This
macro can be used for all sorts of things, like automatically setting
connection- or host-specific parameters when the connection is opened.
Example:
def ON_OPEN {
switch \%1 {
:abccorp.com, set reliable off, break
:xyzcorp.com, set receive packet-length 1000, break
etc etc...
}
}
If you define a macro called ON_CLOSE, it will be executed any time
that a SET LINE, SET PORT, SET HOST, TELNET, RLOGIN or any other kind
of connection that C-Kermit has made is closed, either by the remote
or by a local CLOSE, HANGUP, or EXIT command or other local action,
such as when a new connection is opened before an old one was
explicitly closed.
As soon as C-Kermit notices the connection has been closed, the
ON_CLOSE macro is invoked at (a) the top of the command parsing loop,
or (b) when a connection is closed implicitly by a command such as SET
LINE that closes any open connection prior to making a new connection,
or (c) when C-Kermit closes an open connection in the act of exiting.
The ON_CLOSE macro was inspired by the neverending quest to unite
Kermit and SSH. In this case using the "tunnel" mechanism:
def TUNNEL { ; \%1 = host to tunnel to
local \%p
if not def \%1 stop 1
assign tunnelhost \%1 ; Make global copy
undef on_close
set macro error off
close connection ; Ignore any error
open !read tunnel start \%1
read \%p ; Get port number
if fail stop 1 Tunnel failure: \%1
close read
if fail stop 1 Tunnel failure: \%1 ; See [424]Section 4.2.8.1
assign on_close { ; Set up close handler
echo Closing tunnel: \m(tunnelhost)
!tunnel stop \m(tunnelhost)
undef on_close
}
set host localhost:\%p /telnet
if success end 0
undef on_close
stop 1 Connection failure: \%1
}
In this case, when the connection stops, we also need to shut down the
tunnel, even if it is at a later time after TUNNEL has finished
executing. This way we can escape back, reconnect, transfer files, and
so on until the connection is broken by logging out from the remote,
or by explicitly closing it, or by EXITing from C-Kermit, at which
time the tunnel is shut down.
When the connection is closed, no matter how, the ON_CLOSE macro
executes and then undefines (destroys) itself, since we don't want to
be closing tunnels in the future when we close subsequent connections.
Other such tricks can be imagined, including ending ON_CLOSE with a
STOP command to force the command stack to be peeled all the way back
to the top, for example in a deeply nested script that depends on the
connection being open:
def on_close { stop 1 CONNECTION LOST }
When C-Kermit invokes the ON_CLOSE macro, it supplies one argument
(\%1): the reason the connection was closed as a number, one of the
following:
2 - Fatal failure to negotiate a required item on a network connection.
1 - Closed by C-Kermit command.
0 - All others (normally closed by remote).
which may be used for any purpose; for example, to add a comment to
the connection log:
def on_close {
local \%m
if not open cx end 0
switch \%1 {
:0, .\%m = Closed by remote, break
:1, .\%m = Closed by me, break
:2, .\%m = Network protocol negotiation failure, break
}
if def \%m writeln cx {# \%m}
}
_________________________________________________________________
2.15. Contacting Web Servers with the HTTP Command
C-Kermit 7.0 (at this writing, the UNIX version only) supports direct
contact and interaction with Web servers via HTTP 1.0 protocol. To
make a connection, use Kermit's normal method for making a TCP/IP
connection, but specify the HTTP port:
SET HOST host http [ switches ]
where host is the IP hostname or address, and http is the name of the
TCP port for the Web server. Relevant switches include:
/RAW
Treat the connection as a transparent binary pipe. This switch
may be required if a port other than 'http' is used.
/SSL
Make an secure private connection with SSL (only if SSL support
is included in your version of Kermit). In this case the port
name might need to be https rather than http, e.g. "set host
secureserver.xyxcorp.com https /ssl".
/TLS
Make an secure private connection with TLS (only if TLS support
is included in your version of Kermit). In this case the port
name would be https rather than http.
Then you can issue an HTTP command. In most cases, the server closes
the connection when the command is complete. Example:
SET HOST www.columbia.edu http
IF FAIL EXIT 1 Can't contact server
HTTP GET kermit/index.html
At this point the connection is closed, since that's how HTTP 1.0
works. If you want to perform additional operations, you must
establish a new connection with another SET HOST command.
The HTTP command acts as a client to the Web server, except instead of
displaying the results like a Web browser would, it stores them. Any
HTTP command can (but need not) include any or all of the following
switches:
/AGENT:user-agent
Identifies the client to the server; "C-Kermit" or "Kermit-95"
by default.
/HEADER:header-line
Used for specifying any optional headers. A list of headers is
provided using braces for grouping:
/HEADER:{{tag:value}{tag:value}...}
For a listing of valid tag value and value formats see [425]RFC
1945: Hypertext Transfer Protocol -- HTTP/1.0. A maximum of
eight headers may be specified.
/USER:name
In case a page requires a username for access.
/PASSWORD:password
In case a page requires a password for access.
/ARRAY:arrayname
Tells Kermit to store the response headers in the given array,
one line per element. The array need not be declared in
advance. Example:
C-Kermit? http /array:c get kermit/index.html
C-Kermit? show array c
Dimension = 9
1. Date: Fri, 26 Nov 1999 23:12:22 GMT
2. Server: Apache/1.3.4 (Unix)
3. Last-Modified: Mon, 06 Sep 1999 22:35:58 GMT
4. ETag: "bc049-f72-37d441ce"
5. Accept-Ranges: bytes
6. Content-Length: 3954
7. Connection: close
8. Content-Type: text/html
As you can see, the header lines are like MIME e-mail header lines:
identifier, colon, value. The /ARRAY switch is the only method
available to a script to process the server responses for a POST or
PUT command.
The HTTP commands are:
HTTP [ switches ] GET remote-filename [ local-filename ]
Retrieves the named file. If a local-filename is given, the
file is stored locally under that name; otherwise it is stored
with its own name.
HTTP [ switches ] HEAD remote-filename local-filename
Like GET except without actually getting the file; instead it
gets only the headers, storing them into the given file, whose
name must be given, one line per header item, as shown above in
the /ARRAY: switch description.
HTTP [ switches ] INDEX remote-directory [ local-filename ]
Retrieves the file listing for the given server directory.
NOTE: This command is not supported by most Web servers.
HTTP [ switches ] POST [ /MIME-TYPE:type ] local-file remote-file
Used to send a response as if it were sent from a form. The
data to be posted must be read from a file.
HTTP [ switches ] PUT [ /MIME-TYPE:type ] local-file remote-file
Uploads a local file to a server file.
HTTP [ switches ] DELETE remote-filename
Instructs the server to delete the specified filename.
_________________________________________________________________
3. TERMINAL CONNECTION
3.1. CONNECT Command Switches
The following switches (see [426]Section 1.5) were added to the
CONNECT command in 7.0:
/QUIETLY
Don't print the "Connecting to..." or "Back at..." messages. CQ
is an invisible command synonym for CONNECT /QUIETLY.
/TRIGGER:string
Specify a trigger or triggers ([427]Section 3.2) effective for
this CONNECT command only, temporarily overriding any current
SET TERMINAL TRIGGER values ([428]Section 3.2).
Note: Other switches might also be available; type "connect ?" for a
list, "help connect" for a description of each.
_________________________________________________________________
3.2. Triggers
Triggers were added for UNIX, VMS, AOS/VS, and K95 in C-Kermit 7.0.
SET TERMINAL TRIGGER string
Tells C-Kermit to look for the given string during all
subsequent CONNECT sessions, and if seen, to return to command
mode automatically, as if you had escaped back manually. If the
string includes any spaces, you must enclose it in braces.
Example:
set terminal trigger {NO CARRIER}
Comparisons are made after character-set translation.
If a string is to include a literal brace character, precede it with a
backslash:
; My modem always makes this noise when the connection is lost:
set terminal trigger |||ppp\{\{\{\{UUUUUUU
If you want Kermit to look for more than one string simultaneously,
use the following syntax:
set terminal trigger {{string1}{string2}...{stringn}}
In this case, C-Kermit will return to command mode automatically if
any of the given strings is encountered. Up to 8 strings may be
specified.
If the most recent return to command mode was caused by a trigger, the
new variable, \v(trigger), shows the trigger value; otherwise
\v(trigger) is empty.
The SHOW TRIGGER command displays the SET TERMINAL TRIGGER values as
well as the \v(trigger) value.
_________________________________________________________________
3.3. Transparent Printing
As noted in the manual, C-Kermit's CONNECT command on UNIX is not a
terminal emulator, but rather a "semitransparent pipe" between the
terminal or emulator you are using to access C-Kermit, and the remote
host to which C-Kermit is connected. The "semitransparent" qualifier
is because of character-set translation as well as several actions
taken by the emulator in response to the characters or strings that
pass through it, such as APCs, Kermit packets (autodownload),
triggers, etc.
The UNIX version of C-Kermit 7.0 adds another such action: Transparent
printing, also called Controller printing (as distinct from Autoprint
or line or screen print). It is intended mainly for use on UNIX
workstation consoles (as opposed to remote logins), but with some care
can also be used when accessing C-Kermit remotely.
Transparent printing is related to APC by sharing C-Kermit's built-in
ANSI escape-sequence parser to detect "printer on" and "printer off"
sequences from the host. When the printer-on sequence is received, all
subsequent arriving characters -- including NUL, control characters,
and escape sequences -- are sent to the SET PRINTER device instead of
to your screen until the printer-off sequence is received, or you
escape back, whichever happens first. These bytes are not translated
or modified or filtered in any way by Kermit (except for possibly
stripping of the 8th bit, as noted below), but if filtering or
translation is desired, this can be accomplished by your SET PRINTER
selection (e.g. by choosing a pipeline of filters).
By default, your SET PRINTER device is your default UNIX printer, but
it can also be a file, a command, or the null device (which causes all
printer material to be discarded). See [429]Using C-Kermit, 2nd Ed.,
p.41 for details.
Transparent printing is controlled by the command:
SET TERMINAL PRINT { ON, OFF }
When ON, transparent-print sequences are obeyed, and printing
occurs on the system where C-Kermit is running. When OFF,
transparent print sequences are ignored and passed through to
your actual terminal or emulator, along with the data they
enclose. OFF is the default, for compatibility with earlier
C-Kermit releases. As noted in the manual, when the current SET
PRINTER device is a file, transparent-print material is
appended to it; the file is not overwritten.
SET TERMINAL BYTESIZE { 7, 8 }
SET PARITY { EVEN, ODD, MARK, SPACE, NONE }
If the terminal bytesize is 7, or PARITY is not NONE, the 8th
bit of each byte is stripped prior to printing.
The transparent-print escape sequences are:
<ESC>[5i
Printer On. Send all subsequent incoming bytes to the printer
without any kind of filtering, translation, or alteration.
Note: <ESC> stands for ASCII character number 27 (decimal),
Escape.
<ESC>[4i
Printer Off. Resume displaying incoming bytes on the screen.
These are the same sequences used by DEC VT100 and higher terminals
and other ANSI X3.64 and ISO 6429 compatible terminals. There is no
provision for selecting other printer-control sequences.
Restrictions:
1. You must SET TERM TRANSPARENT-PRINT ON before you can use this
feature.
2. Only the 7-bit forms of the escape sequences are supported. The
8-bit CSI C1 control is not recognized.
3. Autoprint is not supported, since this requires a full-fledged
terminal emulator with direct access to the screen.
4. The start-print and stop-print sequences pass through to the
screen (there is no way to avoid this without causing unacceptable
delays or deadlocks in CONNECT mode). Thus if your terminal or
emulator also supports transparent printing via these same
sequences, an empty file will be sent to its printer. Normally
this has no effect.
Point (4) is similar to the situation with autodownload and APC --
when you have several Kermit clients in a chain, you should take care
that these features are enabled in only one of them.
Example 1:
set printer {|lpr -Plaser} ; Specify the printer (if not default).
set term print on ; Enable transparent printing.
set term byte 8 ; Enable 8-bit characters.
connect ; Enter CONNECT mode.
Example 2:
set printer /home/users/olga/printer.log ; Send printer material to a file.
Example 3:
set printer {| grep -v ^Received | lpr} ; Filter out some lines
Then use "pcprint" or "vtprint" commands on the host to initiate
transparent print operations. See [430]Using C-Kermit, 2nd Ed., p.406
for details.
Here is a sample "pcprint" shell script for UNIX:
#!/bin/sh
echo -n '<ESC>[5i'
if [ $# -eq 0 ]; then
cat
else
cat $*
fi
echo -n '<FF><ESC>[4i'
# (end)
(Replace "<ESC>" by the actual ASCII Escape character and "<FF>" by
the ASCII Formfeed character).
If you always want transparent printing enabled, put "set term print
on" in your C-Kermit customization file (~/.mykermrc in UNIX). The
"set term bytesize" selection, however, is a property of each separate
connection.
_________________________________________________________________
3.4. Binary and Text Session Logs
C-Kermit 7.0 corrects an oversight in earlier releases, in which
binary session logs (SET SESSION-LOG BINARY) translated character sets
and performed various formatting transformations (e.g. "newline mode")
before writing characters to the session log. In C-Kermit 7.0,
binary-mode session logging writes characters as they come in, before
anything (other that parity-bit stripping) is done to them. Text-mode
session logging records the characters after processing.
_________________________________________________________________
4. FILE TRANSFER
Every file is transferred either in text mode (which implies
record-format and character-set translation) or binary mode (in which
each byte is sent literally without any kind of conversion). The mode
in which a file is transferred is controlled by (a) the default mode,
in the absence of any other indications; (b) the SET FILE TYPE
command; (c) various automatic mechanisms based on client/server
negotiations, directory information or filename patterns, etc.
The default FILE TYPE was changed from TEXT to BINARY in C-Kermit 7.0
because:
* Transferring a text file in binary mode does less damage than
transferring a binary file in text mode.
* Only binary-mode transfers can be recovered from the point of
failure.
* The automatic transfer-mode mechanisms switch to text mode on a
per-file basis anyway, so only those files that are not covered by
the automatic mechanisms are affected.
* All file transfers on the Web are done in binary mode, so people
are accustomed to it and expect it.
_________________________________________________________________
4.0. BUG FIXES, MINOR CHANGES, AND CLARIFICATIONS
4.0.0. Filenames with Spaces
Filenames that contain spaces are a major nuisance to a program like
Kermit, whose command language is line- and word-oriented, in which
words are separated by spaces and a filename is assumed to be a
"word". In general (unless noted otherwise in the description of a
particular command), there is only one way to refer to such files in
Kermit commands, and that is to enclose the name in braces:
send {this file}
Tells Kermit to send the file whose name is "this file" (two words, no
quotes). Of course, various circumlocutions are also possible, such
as:
define \%a this file
send \%a
BUT, perhaps contrary to expectation, you can't use "\32" to represent
the space:
send this\32file
does not work. Why? Because the Kermit parser, which must work on many
operating systems including Windows, has no way of knowing what you
mean by "this\32file". Do you mean a file whose name is "this file" in
the current directory? Or do you mean a file whose name is "32file" in
the "this" subdirectory of the current directory? Guessing won't do
here; Kermit must behave consistently and deterministically in all
cases on all platforms.
Note that you can't use Esc or Tab within {...} for filename
completion, or question mark to get a filename list. However, you can
include wildcards; for example:
send {* *}
sends all files whose name contains a space.
All things considered, it is best to avoid spaces in file and
directory names if you can. Also see [431]Section 5.4 on this topic.
_________________________________________________________________
4.0.1. Packet out of Window
C-Kermit 6.0 could send packets "out of window" if the window size was
greater than 1 and ACKs had arrived out of order. Fixed in 6.1.
_________________________________________________________________
4.0.2. MOVE after ADD SEND-LIST
ADD SEND-LIST followed by MOVE did not delete original files; fixed in
6.1. Carrier loss was not detected during transfer; in 7.0 C-Kermit
checks for this (but results can not be guaranteed). In any case, the
protocol will eventually time out if the connection is lost.
_________________________________________________________________
4.0.3. GET and RECEIVE As-Names
In 5A(190) through 6.0.192, the GET and RECEIVE as-name did not
properly override the RECEIVE PATHNAMES setting. In 7.0 it does.
_________________________________________________________________
4.0.4. New Brief Statistics Listing
Version 7.0 adds a /BRIEF switch to the STATISTICS command, to display
a short file-transfer statistics report. /BRIEF is now the default.
Use /VERBOSE to see the full display, which is about 25 lines long.
_________________________________________________________________
4.0.5. Improved FAST Command
The preinstalled definition of the FAST macro did not take enough
factors into account. Now it sets packet lengths and window sizes
appropriate to the configuration. Furthermore, in IRIX only, it might
restrict the SEND packet length to 4000, to work around a bug in the
IRIX Telnet server, depending on the IRIX version (see
[432]ckubwr.txt, IRIX section). To see the built-in definition of the
FAST macro, type "show macro fast". To change it, simply define it to
be whatever you want -- it's just a macro, like any other.
_________________________________________________________________
4.0.6. The SET SEND BACKUP Command
Version 7.0 adds SET SEND BACKUP { ON, OFF }. This tells whether
backup files should be sent. Backup files are the ones created by
Kermit (and EMACS, and possibly other applications) to preserve old
copies of files when creating new ones with the same name. Kermit does
this when receiving a file and its FILE COLLISION setting is BACKUP
(or RENAME, in which case it the new file gets the backup name). On
most platforms, the backup name is formed by adding:
.~n~
to the end of the filename, where "n" is a number. For example, if the
original file is oofa.txt, a backup file might be called:
oofa.txt.~1~
(or oofa.txt.~2~, etc). If you SET SEND BACKUP OFF, this tells Kermit
not to send files that have backup names. Normally, SET SEND BACKUP is
ON (as shown by SHOW PROTOCOL), and backup files are sent if their
names match the SEND file specification.
Also see PURGE, SET FILE COLLISION, SEND /NOBACKUP, DIRECTORY
/[NO]BACKUP.
_________________________________________________________________
4.0.7. The SET { SEND, RECEIVE } VERSION-NUMBERS Command
VMS Only. Normally when sending files, VMS C-Kermit strips the version
number. For example, if the file is FOO.BAR;34, the name is sent as
FOO.BAR (without the ";34"). If you want to keep version numbers on
when sending files, use SET SEND VERSION-NUMBERS ON. The effect
depends on the receiver.
Normally when receiving files, and an incoming filename includes a
VMS-style version number (such as FOO.BAR;34) VMS C-Kermit strips it
before trying to create the new file; this way the new file receives
the next highest version number in the customary manner for VMS. If
you want version numbers on incoming filenames to be used in creating
the new files, use SET RECEIVE VERSION-NUMBERS ON.
Normally these commands would be effective only when VMS C-Kermit is
exchanging files with a non-VMS Kermit program, since VMS-to-VMS
transfers use labeled mode unless you have gone out of your way to
defeat it.
Example: You want to send all versions of all files in the current
directory from a VMS C-Kermit client to a UNIX C-Kermit server. Use:
set send version-numbers on
send *.*;*
The resulting Unix files will have VMS-style version numbers as part
of their name, for example "foo.bar;1", "foo.bar;2", etc.
Now suppose you want to send these files from Unix to another VMS
system and preserve the version numbers. Again we have a Unix C-Kermit
server and VMS C-Kermit client. Give these commands to the client:
set receive version-numbers on
get *
_________________________________________________________________
4.0.8. The SET { SEND, RECEIVE } { MOVE-TO, RENAME-TO } Commands
These commands are persistent global versions of the /MOVE-TO: and
/RENAME-TO: switches of the SEND, GET, and RECEIVE commands. They
should normally be used only when setting up a dedicated
transaction-processing application, in which each file is to be moved
or renamed immediately after, and only if, it is transferred
successfully, so that (for example) an independent, concurrent process
can notice when new files appear and process them immediately without
having to guess whether they are complete.
_________________________________________________________________
4.0.9. SET FILE INCOMPLETE AUTO
SET FILE INCOMPLETE { KEEP, DISCARD }, which tells whether to keep or
discard incompletely received files, has a new option, AUTO, which is
also the default. It means KEEP the incomplete file if the transfer is
in binary mode, otherwise DISCARD it. This reduces the chances that a
subsequent recovery operation (RESEND, REGET, etc) could produce a
corrupt file, since recovery works only for binary-mode transfers.
_________________________________________________________________
4.1. FILE-TRANSFER FILENAME TEMPLATES
File-transfer filename templates allow files to be renamed
automatically by the file sender, the receiver, or both, during
transfer of groups of files.
4.1.1. Templates in the As-Name
Prior to C-Kermit 6.1 and Kermit 95 1.1.12 the only options that could
be used to affect the names of files being transferred were SET
FILENAMES { LITERAL, CONVERTED } and SET { SEND, RECEIVE } PATHNAMES {
ON, OFF }, plus the "as-name" feature of the SEND (MOVE, etc) and
RECEIVE commands.
Previously, the as-name could be used only for a single file. For
example:
SEND FOO BAR
would send the file FOO under the name BAR, but:
SEND *.TXT anything
was not allowed, since it would give the same name to each file that
was sent. When receiving:
RECEIVE FOO
would rename the first incoming file to FOO before storing it on the
disk, but subsequent files would not be renamed to FOO, since this
would result in overwriting the same file repeatedly. Instead, they
were stored under the names they arrived with.
Beginning in C-Kermit 6.1 and Kermit 95 1.1.12, it is possible to
specify as-names in SEND, RECEIVE, and related commands even for file
groups. This is accomplished by using replacement variables in the
as-name, along with optional material such character-string functions
and/or constant strings. An as-name containing replacement variables
is called a filename template.
The key to filename templates is the new variable:
\v(filename)
During file transfer it is replaced by the name of each file currently
being transferred (after transfer, it is the name of the last file
transferred).
So, for example:
send *.txt \v(filename).new
sends each file with its own name, but with ".new" appended to it. Of
course if the name already contains periods, this could confuse the
file receiver, so you can also achieve fancier effects with
constructions like:
send *.txt \freplace(\v(filename),.,_).new
which replaces all periods in the original filename by underscores,
and then appends ".new" to the result. So, for example, oofa.txt would
be sent as oofa_txt.new.
Another new variable that is useful in this regard is \v(filenumber),
which is the ordinal number of the current file in the file group, so
you can also:
send *.txt FILE\flpad(\v(filenum),2,0)
resulting in a series of files called FILE00, FILE01, FILE02, etc. (At
the end of the transfer, \v(filenum) tells the number of files that
were transferred).
If you specify a constant as-name when sending a file group:
send *.txt thisnameonly
Kermit complains and asks you to include replacement variables in the
as-name. You should generally use \v(filename) or \v(filenumber) for
this purpose, since other variables (with the possible exception of
date/time related variables) do not change from one file to the next.
But Kermit accepts any as-name at all that contains any kind of
variables for file group, even if the variable will not change. So:
send *.txt \%a
is accepted, but all files are sent with the same name (the value of
\%a, if it has one and it is constant). If the variable has no value
at all, the files are sent under their own names.
Of course, the value of \%a in the previous example need not be
constant:
define \%a FILE\flpad(\v(filenum),2,0)_at_\v(time)
send *.txt \%a
The RECEIVE command, when given without an as-name, behaves as always,
storing all incoming files under the names they arrive with, subject
to SET FILE NAME and SET RECEIVE PATHNAMES modifications ([433]Section
4.10).
However, when an as-name is given in the RECEIVE command, it is
applied to all incoming files rather than to just the first. If it
does not contain replacement variables, then the current FILE
COLLISION setting governs the result. For example:
receive foo
will result in incoming files named foo, foo.~1~, foo.~2~, and so on,
with the default FILE COLLISION setting of BACKUP. If it does contain
replacement variables, of course they are used.
When receiving files, the \v(filename) variable refers to the name
that was received in the incoming file-header packet, BEFORE any
processing by SET FILE NAMES or SET RECEIVE PATHNAMES. Since the
filenames in file-header packets are usually in uppercase, you would
need to convert them explicitly if you want them in lowercase, e.g.:
receive \flower(\v(filename)).new
_________________________________________________________________
4.1.2. Templates on the Command Line
On the command-line, use templates as shown above as the -a option
argument, bearing in mind the propensity of UNIX and perhaps other
shells to treat backslash as a shell escape character. So in UNIX (for
example):
kermit -s oofa.* -a x.\\v(filenum)
By the way, this represents a change from 6.0 and earlier releases in
which the as-name (-a argument or otherwise) was not evaluated by the
command parser. Thus, for example, in VMS (where the shell does not
care about backslashes), it was possible to:
kermit -s oofa.txt -a c:\tmp\oofa.txt
Now backslashes in the as-name must be quoted not only for the shell
(if necessary) but also for Kermit itself:
kermit -s oofa.txt -a c:\\tmp\\oofa.txt ; Kermit only
kermit -s oofa.txt -a c:\\\\tmp\\\\oofa.txt ; Shell and Kermit
You can also use the \fliteral() function for this:
kermit -s oofa.txt -a \fliteral(c:\tmp\oofa.txt) ; Kermit only
kermit -s oofa.txt -a \\fliteral(c:\\tmp\\oofa.txt) ; Shell and Kermit
_________________________________________________________________
4.1.3. Post-Transfer Renaming
Filename templates are now also useful in SET { SEND, RECEIVE }
RENAME-TO and in the /RENAME-TO: switch, that can be given to the
SEND, GET, or RECEIVE commands; this is similar to an as-name, but is
effective on a per-file basis if and only if the file was transferred
successfully.
MOVE-TO and RENAME-TO address a requirement commonly stated for
transaction processing and similar systems. Suppose, for example, a
central system "X" accepts connections from multiple clients
simultaneously; a process on X waits for a file to appear and then
processes the file. This process must have a way of knowing when the
file has been completely and successfully transferred before it starts
to process it. This can be accomplished easily using C-Kermit's SET {
SEND, RECEIVE } { MOVE-TO, RENAME-TO } command or /MOVE-TO: or
/RENAME-TO: switches, described in [434]Sections 4.7.1 through
[435]4.7.3.
Here's an example for the client side, in which files to be sent are
placed in a certain directory (/usr/olga/tosend in this example) by
another process when they are ready to go. This might be in a hospital
or big doctor's office, where medical insurance claims are entered at
a number of workstations, and then deposited in the "tosend"
directory, from which they are sent to a claims clearinghouse. We
assume the connection is already made and a Kermit server is on the
other end.
local srcdir findir ; Declare local (automatic) variables
assign srcdir /usr/olga/tosend ; Local source directory (files to send)
assign findir /usr/olga/sent ; Where to move files after they are sent
log transactions ; Keep a log of transfers
cd \m(srcdir) ; Change to the source directory
while true { ; Loop forever...
send /move-to:\m(findir) * ; Send all files
sleep 60 ; Sleep a minute
} ; Go back and do it again
Note how simple this is. Once each file is sent, it is moved so it
won't be sent again (you could also use SEND /RENAME-TO: or even SEND
/DELETE). If a transfer fails, the file is not moved and so we try
again to send it next time around. If there are no files to send, the
SEND command does nothing but a message is printed; you can avoid the
message by checking first to see if any files are in the directory:
while true { ; Loop forever...
if > \ffiles(*) 0 - ; If there are any files
send /move-to:\m(findir) * ; send them.
sleep 60 ; Sleep a minute.
} ; Go back and do it again.
It's even simpler on the server side (here again we assume the
connection is already in place):
local rcvdir findir ; Declare local (automatic) variables
assign rcvdir /usr/ivan/tmp ; Temporary receiving directory
assign findir /usr/ivan/new ; Where to move files after reception
log transactions ; Keep a log of transfers
cd \m(rcvdir) ; Change to the source directory
set receive move-to \m(findir) ; Declare move-to directory.
server ; Enter server mode.
A separate process (e.g. the medical claim-form decoder) can look for
files appearing in the /usr/ivan/new directory and process them with
every confidence that they have been completely received.
Note that the use of MOVE-TO can result in moved files overwriting one
another (the application would normally avoid this by assigning each
transaction a unique, e.g. based on customer number and claim number).
But if filename collisions are a possibility in your application,
RENAME-TO might be a better choice; you can use any variables you like
in the template to ensure uniqueness of the RENAME-TO filename; for
example:
SET RECEIVE RENAME-TO \v(filename)_\v(ndate)_\v(ntime)_\v(userid)_\v(pid)
_________________________________________________________________
4.2. FILE-TRANSFER PIPES AND FILTERS
4.2.1. INTRODUCTION
Beginning in C-Kermit 6.1 and Kermit 95 1.1.12, it is possible to send
from a command, or "pipe", as well as from a file, and to receive to a
pipe or command. In a typical example, we might want to transfer an
entire directory tree from one UNIX system to another (but without
using the methods described in [436]Sections 4.3 , [437]4.10,
[438]4.11, and [439]4.15). We could do this in multiple steps as
follows:
1. Create a tar archive of the desired directory tree
2. Compress the tar archive
3. Transfer it in binary mode to the other computer
4. Decompress it
5. Extract the directory tree from the tar archive
But this is inconvenient and it requires a temporary file, which might
be larger than we have room for.
The new pipe-transfer feature lets you do such things in a single
step, and without intermediate files.
Additional new features, also discussed here, let you specify pre- and
post- processing filters for outbound and incoming files, and give you
a way to insert the output from shell or system commands into C-Kermit
commands.
The file-transfer related features are available only with Kermit
protocol, not with any external protocols, nor with K95's built-in
XYZMODEM protocols (because XYZMODEM recovers from transmission errors
by rewinding the source file, and you can't rewind a pipe).
This section begins by discussing the simple and straightforward use
of these features in UNIX, in which pipes and input/output redirection
are a fundamental component and therefore "just work", and then goes
on to discuss their operation in Windows and OS/2, where matters are
much more complicated.
_________________________________________________________________
4.2.1.1. TERMINOLOGY
Standard Input
This is a precise technical term denoting the normal source of
input for a command or program, which is the keyboard of your
terminal by default, but which can be redirected to a file or
pipe.
Stdin
Abbreviation for Standard Input.
Standard Output
A precise technical term denoting the normal destination for
output from a command or program, which is your terminal screen
by default, but which can be redirected to a file.
Stdout
Abbreviation for Standard Output.
Stdio
Abbreviation for Standard Input / Standard Output.
I/O
Abbreviation for Input / Output.
Shell
Text-based system command processor, such as the UNIX shell,
DOS COMMAND.COM, etc.
Pipe
A mechanism by which the standard output of one program is sent
to the standard input of another.
Pipeline
A series of programs connected by pipes.
_________________________________________________________________
4.2.1.2. NOTATION
In command descriptions, "command" is replaced by a shell or system
command or pipeline. The command names specified in these commands are
interpreted by your shell, just as if you were typing them at the
shell prompt, and so if they are in your PATH, they will be found in
the expected manner. Therefore you don't have to specify complete
pathnames for commands that are programs (but it shouldn't hurt if you
do).
The normal notation for I/O redirection is as follows:
< Read Stdin from the given file.
> Send Stdout to the given file.
| Send Stdout from the command on the left to the command on the right.
Examples:
sort < foo > bar
Sorts the lines in file "foo" and writes the results to file
"bar"
grep -c "some text" *.txt | grep -v ":0" | sort | pr -3 | lpr
This is a command pipeline composed of 5 commands:
grep -c "some text" *.txt
Looks in all files whose names end with ".txt" for the string
"some text" and writes to Stdout the names of each file
followed by a colon and the number of occurrences in each.
grep -v ":0"
Prints to Stdout the lines from Stdin that do NOT contain the
string ":0", in this case, it removes the names of files that
do not contain "some text".
sort
Sorts the lines from Stdin alphabetically to Stdout.
pr -3
Arranges the lines from Stdin in three columns.
lpr
Prints its Stdin on the default printer.
Note that the Kermit features described here work only with commands
that use Stdio. If you attempt to use them with commands whose input
and output can not be redirected, Kermit will most likely get stuck.
Kermit has no way of telling how an external command works, nor what
the syntax of the shell is, so it's up to you to make sure you use
these features only with redirectable commands.
The quoting rules of your shell apply to the command. Thus in UNIX,
where C-Kermit tries to use your preferred shell for running commands,
shell "metacharacters" within commands must be escaped if they are to
be taken literally, using the methods normal for your shell. For
example, the UNIX tr (translate) command must have its arguments in
quotes:
tr "[a-z]" "[A-Z]"
otherwise the shell is likely to replace them by all filenames that
match, which is probably not what you want. This is also true when
using your shell directly, and has nothing to do with Kermit.
_________________________________________________________________
4.2.1.3. SECURITY
Some sites might not wish to allow access to system commands or
external programs from within Kermit. Such access, including all the
features described here, can be disabled in various ways:
1. When building from source code, include -DNOPUSH among the CFLAGS.
2. At runtime, give the NOPUSH command.
3. For server mode, give the DISABLE HOST command.
4. Implicit use of pipes can be disabled as described in [440]Section
4.2.4.
Note: 3 and 4 are not necessary if you have done 1 or 2.
_________________________________________________________________
4.2.2. Commands for Transferring from and to Pipes
SEND /COMMAND sends data from a command or command pipeline, and
RECEIVE /COMMENT writes data to a command or pipeline. The GET
/COMMAND command asks a server to send material, and then writes the
incoming material to a command or pipeline. These features, along with
switches (like "/COMMAND", described in [441]Section 4.7) are new to
C-Kermit 6.1. The following synonyms are also provided:
CSEND = SEND /COMMAND
CRECEIVE = RECEIVE /COMMAND
CGET = GET /COMMAND
None of these commands can be used if a SEND or RECEIVE FILTER
(respectively, [442]Section 4.2.3) is in effect, or if a NOPUSH
command ([443]Section 4.2.1.3) has been given, or if the current
protocol is not Kermit.
_________________________________________________________________
4.2.2.1. Sending from a Command
SEND /COMMAND command [ as-name ]
SEND /AS-NAME:as-name /COMMAND command
CSEND command [ as-name ]
These three forms are the same. They work like the SEND
command, but instead of sending a file, it sends the standard
output of the given command, either under the command's own
name, or else with the given as-name. If the command contains
spaces, it must be enclosed in braces. Braces should also be
used for the as-name if it contains spaces. If braces are
included around either the command or the as-name, they are
removed after parsing but before use. As with SEND, the
transfer is in text or binary mode according the current FILE
TYPE setting, unless you override the global transfer mode by
including a /TEXT or /BINARY switch. The command must require
no input.
When sending from a command or pipeline, C-Kermit has no way of
knowing in advance how much data will be sent, and so it can not send
the size to the other Kermit in the Attribute packet, and so the
receiving Kermit has no way of displaying "percent done" or a progress
bar (thermometer).
Examples that make sense in text mode (illustrated by common UNIX
commands):
SEND /COMMAND finger
CSEND finger
sends the current "finger" listing (who's logged in) under the
name "finger". The two forms "send /command" and "csend" are
equivalent; we won't bother showing them both in the rest of
the examples.
SEND /COMMAND:{finger}
CSEND {finger}
Same as previous example (braces are removed from "{finger}").
SEND /COMMAND:{ finger }
CSEND { finger }
Same as previous example, but note that the spaces are kept.
This does not prevent the shell from running the "finger"
program, but its output is sent under the name " finger " (with
a leading and trailing space).
SEND /COMMAND:finger /AS-NAME:userlist
CSEND finger userlist
sends the current finger listing under the name "userlist".
SEND /COMMAND:{finger | sort -r} /AS-NAME:userlist
CSEND {finger | sort -r} userlist
sends the current finger listing, sorted in reverse order,
under the name "userlist". The braces are needed to distinguish
the command from the as-name.
SEND /COMMAND:{finger | sort -r} /AS-NAME:{userlist}
CSEND {finger | sort -r} {userlist}
Same as previous example (braces are removed from
"{userlist}").
SEND /COMMAND:{finger | sort -r}
/AS-NAME:{\freplace(\v(filename),\32,_)}
CSEND {finger | sort -r} {\freplace(\v(filename),\32,_)}
Like the previous example, but sends the output of the command
under the name of the command, but with all spaces (\32)
replaced by underscores, so the as-name is "finger_|_sort_-r".
Examples that make sense in binary mode (three equivalent forms are
shown):
SEND /COMMAND /BINARY {tar cf - . | gzip -c} mydir.tar.gz
SEND /COMMAND /BINARY /AS-NAME:mydir.tar.gz {tar cf - . | gzip -c}
CSEND /BINARY {tar cf - . | gzip -c} mydir.tar.gz
Makes a tar archive of the current directory, compresses it
with the GNU gzip program, and sends it as "mydir.tar.gz". The
other Kermit can, of course, just store it as a file, or it can
use CRECEIVE to uncompress and dearchive it as part of the
transfer process.
When using a "pipeline" of commands in the command field, obviously,
the first command must not require any input, and the last command
should produce some output, and all intermediate commands should get
some input and produce some output.
_________________________________________________________________
4.2.2.2. Receiving to a Command
RECEIVE /COMMAND command
CRECEIVE command
This is like RECEIVE, except incoming material is written to
the standard input of the given command, in text or binary mode
according to the normal rules for file reception. Be sure to
include a redirector to a file (if the command normally writes
to standard output), or the output of the command won't go
anywhere. The command may contain spaces; braces are not
needed, but they are removed if used.
WARNING: C-Kermit has no way of knowing anything about the command, or
even whether it is a command. Thus this command will always cause
C-Kermit to enter protocol mode, as long as some text is specified in
the command field. However, if the text does not correspond to a
command, the transfer will eventually fail with a message such as
"Error writing data" or "Failure to close file".
Examples for text mode (in UNIX):
RECEIVE /COMMAND sort -r > reverse.txt
CRECEIVE sort -r > reverse.txt
The text that is received is sorted in reverse order and stored
in the file "reverse.txt". The two forms shown are equivalent.
RECEIVE /COMMAND {sort -r > reverse.txt}
CRECEIVE {sort -r > reverse.txt}
The same as the previous example; if braces are included, they
are simply removed.
RECEIVE /COMMAND {sort -r > \flower(\v(filename)).reverse}
CRECEIVE {sort -r > \flower(\v(filename)).reverse}
Same but stores result under the incoming filename, lowercased,
and with ".reverse" appended to it.
RECEIVE /COMMAND sort
CRECEIVE sort
Does nothing useful, since the output of sort has nowhere to
go.
RECEIVE /COMMAND sort -r | pr -3 | lpr -Plaserjet
CRECEIVE sort -r | pr -3 | lpr -Plaserjet
The text that is received is sorted in reverse order, arranged
into three columns, and sent to the "laserjet" printer.
Examples for binary mode:
RECEIVE /COMMAND:{gunzip -c | tar xf -}
CRECEIVE {gunzip -c | tar xf -}
Assuming the data that is received is a compressed tar archive,
uncompresses the archive and passes it to tar for extraction.
In this case the braces are needed because otherwise the final
"-" would be taken as a command continuation character (see
[444]Using C-Kermit, 2nd Edition, p.33).
GET /COMMAND remote-file command
GET /COMMAND /AS-NAME:command remote-file
CGET remote-file command
This command tells the Kermit client to send a GET request for
the given remote file to a Kermit server. Unlike GET, however,
the incoming material is written to a command, rather than to a
file. If the remote-file or the command contain spaces, they
must be enclosed in braces. The same cautions about the command
apply as for CRECEIVE.
Examples (for UNIX):
GET /COMMAND oofa.txt sort -r > oofa.new
GET /COMMAND {oofa.txt} {sort -r > oofa.new}
CGET oofa.txt sort -r > oofa.new
CGET {oofa.txt} {sort -r > oofa.new}
These four are equivalent. Each of them requests the server to
send its "oofa.txt" file, and as it arrives, it is sorted in
reverse order and written to "oofa.new".
GET /COMMAND {profile exec a} lpr
GET /COMMAND {profile exec a} {lpr}
GET /COMMAND /AS-NAME:lpr {profile exec a}
GET /COMMAND /AS-NAME:{lpr} {profile exec a}
GET /COMMAND /AS:lpr {profile exec a}
CGET {profile exec a} lpr
CGET {profile exec a} {lpr}
Here the remote filename contains spaces so it MUST be enclosed
in braces. As it arrives it is sent to the lpr program for
printing. Braces are optional around "lpr" since it contains no
spaces.
GET /COMMAND *.txt {cat >> new.txt}
GET /AS-NAME:{cat >> new.txt} /COMMAND *.txt
CGET *.txt {cat >> new.txt}
This gets all the ".txt" files from the server and concatenates
them all into a single "new.txt" file on the client.
GET /COMMAND *.txt {echo \v(filename)>>new.txt;cat>>new.txt}
CGET *.txt {echo \v(filename)>>new.txt;cat>>new.txt}
As above, but inserts each file's name before its contents.
_________________________________________________________________
4.2.3. Using File-Transfer Filters
The commands described in [445]Section 4.2.2 let you send the output
of a command, or receive data into a command. But what if you want to
specify preprocessing for files that you send, or postprocessing of
files that you receive, even when multiple files are involved? For
this you need a way to specify send and receive filters. The commands
are SET SEND FILTER and SET RECEIVE FILTER; SHOW PROTOCOL displays the
current settings.
4.2.3.1. The SEND Filter
SET SEND FILTER [ command ]
This command specifies a command to be run on any file that you
SEND (or MOVE, MSEND, etc). It also applies to files sent when
in server mode, in response to GET commands, but not to the
results of REMOTE commands like REMOTE DIRECTORY, REMOTE TYPE,
REMOTE HOST, etc. The command may be, but need not be, enclosed
in braces; if it is, the braces are stripped before use. The
output of this command is sent, rather than the file itself.
The current FILE TYPE setting (TEXT or BINARY) applies to the
output of the command. The command must contain at least one
instance of \v(filename), for which the name of the actual file
is substituted. If the command is omitted, the send filter is
removed and files are sent in the normal manner.
The SET SEND FILTER sets up a "global" filter -- that is, one that
applies to all subsequent file-sending commands until you change or
remove it. You can also specify a "local" filter to be used in a
specific file-sending command by using the /FILTER switch (see
[446]Section 1.5); for example:
SEND /FILTER:command [ other-switches ] filename
Besides \v(filename), you can include any other script programming
notation in the send filter: variable names, array references, calls
to built-in string or other functions, and so on. These are evaluated
during file transfer, NOT during parsing, and they are evaluated
separately for each file.
When the SEND or MOVE (SEND /DELETE) command is used with a send
filter, the output from the filter is sent under the file's original
name unless you specify an "as-name" or template. The Attribute packet
(if any) contains the original file's attributes (size, creation date,
etc). So (for example) if the filter changes the file's size, the
progress thermometer might be wrong. (We can't send the size of the
output from the filter, because it is not known until the transfer is
finished.) If you prefer that the size not be sent, use "set
attributes size off".
You can not use send filters with RESEND (SEND /RECOVER) or PSEND
(SEND /START).
Examples for text mode:
SET SEND FILTER sort -r \v(filename) ; Braces may be omitted
SET SEND FILTER {sort -r \v(filename)} ; Braces may be included
SEND *.txt
This sends every file in the current directory whose name ends
with ".txt" under its own name, but with its lines sorted in
reverse order.
SEND /FILTER:{sort -r \v(filename)} *.txt
Same as above, but the filter applies only to this SEND
command. Braces are required in this case.
SET SEND FILTER {sort -r \v(filename)}
SEND oofa.txt reverse.txt
Sends the oofa.txt file with its lines sorted in reverse order
under the name "reverse.txt".
SET SEND FILTER {sort -r \v(filename)}
SEND oofa.* \v(filename).reverse
Sends all the oofa.* files with their lines sorted in reverse
order; each file is sent under its own name but with ".reverse"
appended to it.
SET SEND FILTER {tr "[a-z]" "[A-Z]" < \v(filename)}
SEND *.txt
Sends all ".txt" files under their own names, but uppercasing
their contents.
Note that the SEND FILTER applies not only to files that are sent with
SEND, MOVE, MSEND, etc, but also to files sent by the C-Kermit server
in response to GET requests.
Examples for binary mode:
SET SEND FILTER {gzip -c \v(filename)}
SEND /BINARY oofa.txt oofa.txt.gz
Sends the oofa.txt file, compressed by gzip, as oofa.txt.gz.
SEND /BINARY /FILTER:{gzip -c \v(filename)} oofa.txt oofa.txt.gz
As above, but the filter applies only to this SEND command.
SET SEND FILTER {gzip -c \v(filename)}
SEND /BINARY oofa.* \fupper(\replace(\v(filename),.,_)).GZ
Sends all the oofa.* files, compressed by gzip, each under its
own name, but with the name uppercased, all periods within the
name converted to underscores, and ".GZ" appended to it. So,
for example, "oofa.txt" is sent as "OOFA_TXT.GZ".
In the gzip examples, note that the amount of data that is sent is
normally less than the original file size because gzip compresses the
file. But Kermit sends the original file size ahead in the attribute
packet anyway (unless you tell it not too). Thus the transfer will
probably appear to terminate early, e.g. when the receiver's
file-transfer display thermometer is only at 40%. If this annoys you,
tell Kermit to "set attribute length off". On the other hand, you can
use the final position of the thermometer as a measure of the
effectiveness of compression.
_________________________________________________________________
4.2.3.2. The RECEIVE Filter
SET RECEIVE FILTER [ command ]
This command specifies that the given command will be run on
any file that is received before it is written to disk. The
command may be, but need not be, enclosed in braces; if it is
the braces are stripped before use. The following two commands
are equivalent:
SET RECEIVE FILTER sort -r > \v(filename)
SET RECEIVE FILTER {sort -r > \v(filename)}
The RECEIVE filter command may contain a "\v(filename)" sequence to be
replaced by the incoming filename from the file header packet, but it
is not required. However you must use it whenever your filter would
normally write to Stdout, otherwise its output will be lost.
The RECEIVE filter command may contain one or more "\v(filename)"
sequence to be replaced by the incoming filename from the file header
packet, but it is not required. However you must use it whenever your
filter would normally write to Stdout, otherwise its output will be
lost.
RECEIVE /FILTER:command and GET /FILTER:command can also be used to
specify a filter to be used for only one file-transfer operation.
UNIX examples for text mode:
SET RECEIVE FILTER lpr
RECEIVE
All the files that are received are sent to the default UNIX
print spooler.
RECEIVE /FILTER:lpr
Same as above, except the lpr filter is used only with this
RECEIVE command.
RECEIVE lpr
This is probably not what you want; it creates a file called
lpr.
SET RECEIVE FILTER {sort -r > \v(filename)}
RECEIVE
Stores each incoming file with its lines sorted in reverse
order, under its own name.
RECEIVE /FILTER:{sort -r > \v(filename)}
As above, but the filter is used only for this RECEIVE command.
SET RECEIVE FILTER sort -r > \v(filename)
RECEIVE reverse.txt
Stores each incoming file with its lines sorted in reverse
order, under the name "reverse.txt". The actual result depends
on the FILE COLLISION setting. If it is OVERWRITE and multiple
files arrive, then each incoming file destroys the previous
one. If it is BACKUP (the default), filename conflicts are
resolve by adding "version numbers" to the filenames:
reverse.txt, reverse.txt.~1~, reverse.txt.~2~, etc.
SET RECEIVE FILTER sort -r > \v(filename)
RECEIVE \v(filename).reverse
Stores each incoming file with its lines sorted in reverse
order, under the name it arrived with, but with ".reverse"
appended to it.
SET RECEIVE FILTER sort -r > \v(filename)
RECEIVE \flower(\v(filename)).reverse
Like the previous example, but ensures that the filename is
lowercase.
Examples for binary mode:
SET RECEIVE FILTER gunzip -c > \v(filename)
RECEIVE
This receives one or more presumably compressed file and
uncompresses each one into a file having the same name it was
sent with. For example, if the file is sent with the name
OOFA.TXT.GZ, it is stored with that name, even after
decompression.
SET RECEIVE FILTER gunzip -c > \v(filename)
RECEIVE \flower(\fsubstring(\v(filename),1,\flength(\v(filename))-3))
Like the previous example, but the resulting filename has its
rightmost three characters removed from it and the remainder is
lowercased. So if the incoming filename is OOFA.TXT.GZ, it is
stored as oofa.txt after decompression.
Of course you don't want to type such long hideous commands, so we
have also introduced several new functions:
\fstripx(string[,character])
This function removes the rightmost segment of the string that
starts with the given character. If no character is given,
period (.) is used. Thus it is most conveniently used for
stripping the extension from a filename (or the decimal portion
from a floating-point number written in US/UK style). Examples:
\fstripx(OOFA.TXT.GZ) => OOFA.TXT
\fstripx(OOFA.TXT.GZ,.) => OOFA.TXT
\fstripx(OOFA.TXT.GZ,X) => OOFA.T
\fstripx(\fstripx(OOFA.TXT.GZ)) => OOFA
\fstripx($100.00) => $100
\fstripn(string,number)
Removes the rightmost number characters from the string.
Examples:
\fstripn(OOFA.TXT.GZ) => OOFA.TXT.GZ
\fstripn(OOFA.TXT.GZ,3) => OOFA.TXT
\fstripn(OOFA.TXT.GZ,7) => OOFA
\fstripb(string[,c1[,c2]])
Strips enclosing matching braces, brackets, parentheses, or
quotes from the string. The second argument, c1, specifies
which kind of enclosure to look for; if not specified, any
enclosing (), [], <>, {}, "", '', or `' are removed. If c1 is
specified and c2 is not, then if c1 is an opening brace,
bracket, or parenthesis, the matching closing one is supplied
automatically as c2. If both c1 and c2 are specified, then to
be stripped the string must begin with c1 and end with c2. If
the string is not enclosed in the indicated manner, the result
is the original string. Examples:
\fstripb("abc") => abc
\fstripb([abc]) => abc
\fstripb([abc) => [abc
\fstripb(<abc>) => abc
\fstripb(<abc>,[) => <abc>
\fstripb((abc)) => abc
\fstripb((abc),[) => (abc)
\fstripb((abc),{(}) => abc
\fstripb(+abc+) => +abc+
\fstripb(+abc+,+) => abc
\fstripb(+abc+,+,^) => +abc+
\fstripb(+abc^,+,^) => abc
\fstripb('abc') => abc
\fstripb(`abc') => abc
\fstripb(``abc'') => `abc'
\fstripb(\fstripb(``abc'')) => abc
Notice the special syntax required for including a literal
parenthesis in the argument list. As the last two examples
illustrate, \fstripb() strips only one level at at a time;
nesting can be used to strip a small fixed number of levels;
loops can be used to strip larger or indeterminate numbers of
levels.
\flop(string[,char])
Removes the leftmost segment of the string that ends with the
given character. If no character is given, period (.) is used.
Examples:
\flop(OOFA.TXT.GZ) => TXT.GZ
\flop(OOFA.TXT.GZ,.) => TXT.GZ
\flop(OOFA.TXT.GZ,X) => T.GZ
To remove the leftmost number characters, just use
\fsubstring(s,number+1). To return the rightmost number
characters, use \fright(s,number).
So the hideous example:
receive \flower(\fsubstring(\v(filename),1,\flength(\v(filename))-3))
can now be written as:
receive \flower(\fstripx(\v(filename)))
That is, the filename stripped of its extension and then lowercased.
This is not only shorter and less hideous, but also does not depend on
the length of the extension being 3.
Note that when a receive filter is in effect, this overrides your FILE
COLLISION setting, since Kermit has no way of knowing what the final
destination filename will be (because it does not know, and can not be
expected to know, the syntax of every version of every command shell
on every platform on the planet).
_________________________________________________________________
4.2.4. Implicit Use of Pipes
If you wish, C-Kermit can also examine incoming filenames to see if
they start with "!", and if so, the subsequent text is treated as a
command to read from or write to. For example, if a Kermit client is
given the following command:
get {!finger | sort}
the server on the other end, if it supports this feature, will run the
"finger" program, pipe its standard output to the "sort" program, and
send sort's standard output back to you. Similarly, if you:
send oofa.txt !sort -r > oofa.new
or, equivalently:
send oofa.txt {!sort -r > oofa.new}
or:
send /as-name:{!sort -r > oofa.new} oofa.txt
this has the receiver send the contents of the incoming oofa.txt file
to the sort program, which sorts the text in reverse order and stores
the result in oofa.new.
This use of the exclamation mark should be familiar to UNIX users as
the "bang" feature that lets you run an external application or
command from within another application.
Kermit's "bang" feature is disabled by default, since it is not
unheard for filenames to actually begin with "!". So if you want to
use this feature, you must enable it with the following command:
SET TRANSFER PIPES { ON, OFF }
ON enables the recognition of "!" notation in incoming
filenames during file transfer as an indicator that the
remaining text is the name of a command. OFF, the default,
disables this feature and uses the text as a filename in the
normal fashion. This command does NOT affect SEND /COMMAND, GET
/COMMAND, CSEND, etc.
So using a combination of CSEND (SEND /COMMAND) and the "bang"
feature, you can transfer a directory tree all in one command
(assuming the remote Kermit supports pipe transfers and has them
enabled):
CSEND {tar cf - . | gzip -c} {!gunzip -c | tar xf -}
or:
SEND /COMMAND:{tar cf - . | gzip -c} /as:{!gunzip -c | tar xf -}
Pay close attention to the syntax. Braces are needed around the
command because it contains spaces; braces are needed around the
as-name because it ends with "-". The as-name must begin with "!" or
receiving Kermit will not recognize it as a command. The CSEND command
must NOT begin with "!" unless you are running a command whose name
really does start that character.
Similarly, you have a Kermit server send a directory tree to be
unpacked on the client end:
CGET {!tar cf - . | gzip -c} {gunzip -c | tar xf -}
or:
GET /COMMAND {!tar cf - . | gzip -c} /as:{gunzip -c | tar xf -}
Notice how, in this case, the bang is required in the remote command,
to distinguish it from a filename, but not in the local command, since
by definition of CGET (or GET /COMMAND), it is known to be a command.
SEND and RECEIVE FILTERs supersede the bang feature. For example, if a
file arrives under the name "!gunzip -c | tar xf -", but the receiving
Kermit also has been given a command like:
set receive filter sort -r > \v(filename)
then the incoming data will be sorted rather than gunzipped.
Finally, if SET TRANSFER PIPES is ON (and in this case, this must be
done in your C-Kermit initialization file), you can send from a pipe
on the C-Kermit command line:
kermit -s "!finger | sort -r" -a userlist
In this case the "filename" contains spaces and so must be quoting
using your shell's quoting rules.
_________________________________________________________________
4.2.5. Success and Failure of Piped Commands
Commands or programs started by Kermit as a result of CSEND or
CRECEIVE commands, CGET, SEND /COMMAND, REDIRECT commands (see
[447]Section 4.2.8.2), implicit use of pipes, RUN commands, and so
forth, should return their exit status codes to the Kermit command
that caused them to be run, and therefore IF SUCCESS and IF FAILURE
tests after these commands should work as expected. For example:
CSEND blah < filename
should fail if there is no command called "blah" or if there is no
file called "filename". However, this is not foolproof and sometimes
C-Kermit might think a command succeeded when it failed, or vice
versa. This is most likely to happen when the highly system-dependent
methods that Kermit must use to determine a command's exit status code
do not supply the right information.
It can also happen because some commands might define success and
failure differently from what you expect, or because you are using a
pipeline composed of many commands, and one of them fails to pass
failing exit status codes up the chain. The most likely culprit is the
shell itself, which in most cases must be interposed between Kermit
and any external program to be run.
In any case, you can examine the following variable to find out the
exit status code returned to Kermit by the process most recently run
by any command that runs external commands or programs, including
CSEND, CRECEIVE, REDIRECT, RUN, etc:
\v(pexitstat)
In UNIX, Windows and OS/2, the value should be -2 if no command has
been run yet, 0 if the most recent command succeeded, -1, -3, or -4 if
there was an internal error, and a positive number returned by the
command itself if the command failed. If the number is in the range
1-127, this is the program's exit status code. If it is 128 or
greater, this is supposed to indicate that the command or program was
interrupted or terminated from outside itself.
In Windows 95 and 98, the return values of the default shell are
unreliable; various third-party shells can be used to work around this
deficiency.
In VMS, it is the actual exit status code of the command that was run.
This is an odd number if the command succeeded, and an even number if
it failed. You can see the associated message as follows:
run write sys$output f$message(\v(pexitstat))
Or, more conveniently, use the new Kermit function:
echo \ferrstring(\v(pexitstat))
which converts a system error code (number) to the corresponding
message.
_________________________________________________________________
4.2.6. Cautions about Using Pipes to Transfer Directory Trees
Although utilities such as tar and zip/unzip might be available on
different platforms (such as UNIX and Windows), this does not
necessarily mean you can use them successfully to transfer directory
trees between unlike platforms. For example:
CSEND {tar cf - . | gzip -c} {!gunzip -c | tar xf -}
when used from UNIX to Windows will have satisfactory results for
binary files, but not for text files. UNIX text files have lines
ending with Linefeed (LF) only, whereas Windows text files have lines
ending in Carriage Return and Linefeed (CRLF). Thus any text files
that were in the archive formed by the first tar command will be
unpacked by the second tar command in their original form, and will
display and print incorrectly in Windows (except in applications that
have been explicitly coded to handle UNIX-format text files). On the
other hand if you told gzip to use "text mode" to do record format
conversion (assuming there was a way to tell it, as there is with most
"zip" programs), this would destroy any binary files in the archive.
Furthermore, if the archive contains text files that are written in
languages other than English, the "special" (accented and/or
non-Roman) characters are NOT translated, and are therefore likely
show up as gibberish on the target system. For example, West European
languages are usually encoded in ISO Latin Alphabet 1 in UNIX, but in
PC code page 850 on the PC. Capital A with acute accent is code point
193 (decimal) Latin-1, but 181 in CP850. So A-acute in the UNIX file
becomes Middle Box Bottom on the PC, and similarly for all the other
special characters, and for all other languages -- Greek, Russian,
Hebrew, Japanese, etc.
So when transferring text files between unlike platforms, you should
use direct Kermit file transfers so Kermit can apply the needed
record-format and character-set transformations. Use pipelines
containing archivers like tar or zip only if all the files are binary
or the two systems use the same record format and character set for
text files.
Also see [448]Sections 4.3, [449]4.10, [450]4.11, and [451]4.15 for
how to transfer directory trees between both like and unlike systems
directly with Kermit.
_________________________________________________________________
4.2.7. Pipes and Encryption
Of course pipelines could be used for encrypted file transfers,
assuming proper precautions could be taken concerning the transmission
of the key. But there is rarely a good way to do this. To illustrate
using UNIX crypt:
csend {crypt key < filename} {!crypt key > filename}
Or, more ambitiously:
csend {tar cf - . | gzip -c | crypt key} {!crypt key | gunzip -c | tar xf -}
transmits the key in the file header packet as part of the
(clear-text) remote command, defeating the entire purpose of
encrypting the file data.
But if you are connected in terminal mode to the remote computer and
type:
creceive {crypt key > filename}
at the remote Kermit prompt, you have also transmitted the key in
clear text over the communications link.
At present, the only secure way to use CSEND and CRECEIVE with an
encryption filter is to have a human operator at both ends, so the key
does not have to be transmitted.
Theoretically it would be possible to use PGP software (Pretty Good
Privacy, by Phil Zimmerman, Phil's Pretty Good Software) to avoid key
transmission (since PGP uses separate public and private key and "lets
you communicate securely with people you've never met, with no secure
channels needed for prior exchange of keys"), but the specific method
has yet to be worked out.
HINT: See the PGP User's Guide, e.g. at:
[452]http://www.telstra.com.au/docs/PGP/
Especially the topic "Using PGP as a UNIX-Style Filter":
[453]http://www.telstra.com.au/docs/PGP/pgpdoc2/pgpdoc2_17.html
In any case, better and more convenient security options are now
available: Kerberos authentication and encryption ([454]CLICK HERE for
details) and the new ability to run C-Kermit "though" other
communication programs, described in [455]Section 2.7.
_________________________________________________________________
4.2.8. Commands and Functions Related to Pipes
4.2.8.1. The OPEN !READ and OPEN !WRITE Commands
These are described in [456]Using C-Kermit, and are generally useful
with reading output from commands that produce more than one line on
their standard output, or writing multiple lines into commands that
accept them on their standard input.
In C-Kermit 7.0 CLOSE !READ is accepted as a synonym for CLOSE READ,
and CLOSE !WRITE for CLOSE WRITE.
Testing the success and failure of these commands, however, can be a
bit tricky. Consider:
open !read lalaskjfsldkfjsldkfj
(where "lalaskjfsldkfjsldkfj" is neither a valid command nor the name
of a program or script that can be run). OPEN !READ, in UNIX at least,
translates this into execl(shellpath,shellname,"-c",command). This
means it starts your preferred shell (e.g. from the SHELL environment
variable) and asks it to execute the given command. It must be this
way, because your command can be a either an internal shell command
(which only your shell can execute) or an external command, which only
your shell knows how to find (it knows your PATH and interprets, etc).
Therefore unless OPEN !READ can't start your shell, it always
succeeds.
Continuing with the nonexistent-command example:
C-Kermit> open !read lalaskjfsldkfjsldkfj
C-Kermit> status
SUCCESS
C-Kermit> read line
C-Kermit> status
SUCCESS
C-Kermit> echo "\m(line)"
"bash: lalaskjfsldkfjsldkfj: command not found"
C-Kermit> close read
C-Kermit> status
FAILURE
C-Kermit>
In other words, the failure can not be detected on OPEN, since the
OPEN command succeeds if it can start your shell. It can't be detected
on READ, since all this does is read output from the shell, which in
this case happens to be an error message. However, failure IS detected
upon close, since this is the occasion upon which the shell gives
Kermit its exit status code.
For an illustration of this situation, see [457]Section 2.14.
_________________________________________________________________
4.2.8.2. The REDIRECT Command
A second method of I/O redirection is offered by the REDIRECT command.
This is a rather advanced and tricky feature that is presently
supported only in UNIX C-Kermit, in OS-9 C-Kermit, and in Kermit 95.
Syntax:
REDIRECT command
Runs the given command, sending its standard output to the
current communications channel (SET LINE, SET PORT, or SET HOST
connection), and reading its standard input from the same
connection. Works only in local mode -- i.e. a connection is
required -- and then only if the given command uses Standard
I/O.
Example:
redirect finger
runs the local "finger" command and sends its output over the
connection as plain text, where presumably there is a process set up
to read it. Another example:
redirect finger | sort -r
shows the use of a pipeline.
Note: REDIRECT differs from CSEND/CRECEIVE in two important ways: (1)
it does not use the Kermit protocol, and (2) it uses a bidirectional
pipe rather than a one-way pipe.
The primary use of the REDIRECT command is to run external protocols,
such as sz/rz in UNIX for ZMODEM, when they work over Standard I/O(*).
Example:
set host xyzcorp.com
(login, etc)
redirect sz oofa.zip
lets you make a Telnet connection with C-Kermit and then do a ZMODEM
transfer over it. ZMODEM protocol messages go both ways over the same
connection simultaneously.
It is possible to use C-Kermit on UNIX as your PPP dialer and then to
REDIRECT the connection to the PPP software, but C-Kermit 7.0 offers a
better approach to PPP dialing in its new EXEC command ([458]Section
1.23).
In theory, you can also redirect an interactive process. For example,
suppose you tell Kermit 95 to wait for an incoming TCP/IP connection:
set host * 3000
and then tell C-Kermit on UNIX to:
set host kermit95hostname 3000
redirect ksh
and then tell Kermit 95 to CONNECT: now you are talking to the UNIX
K-shell; you can give commands (pwd, ls, etc) and see the results. In
practice, the K-shell's terminal modes are messed up because (a) it is
not going through the Unix terminal driver, and (b) it is "smart" and
knows it is being redirected, and so acts in a decidedly inhospitable
manner (other applications like EMACS, vi, etc, simply refuse to run
if their standard i/o has been redirected).
(*) The publicly-distributed sz/rz programs do not work as clients.
However, Omen Technology does offer an up-to-date redirectable
client XYZMODEM program called crzsz.
_________________________________________________________________
4.2.8.3. Receiving Mail and Print Jobs
As of 7.0, and in UNIX only, files that are sent to C-Kermit as mail
(when the other Kermit uses a MAIL or SEND /MAIL command) or to be
printed (via REMOTE PRINT or SEND /PRINT) are now piped directly to
the mail or print program, rather than written to temporary files and
then mailed or printed and then deleted. This has the advantages of
(a) not requiring a temporary file, and (b) allowing mail to have a
proper subject in place of the filename. Temporary files were bad not
only because they required (a) space, and (b) writeability of the
current directory, but also because using them could result in wiping
out an existing file. See [459]Section 4.7 for more about SEND /MAIL
and SEND /PRINT.
_________________________________________________________________
4.2.8.4. Pipe-Related Functions
The \fcommand(command) function runs the given shell or system command
and returns the command's standard output as its value (with any
newline characters stripped from the end), unless the result is too
long, in which case it returns the empty string. The maximum length
for the result is at least 1022 bytes, and it might be longer on some
platforms. Examples (UNIX):
C-Kermit> echo "\fcommand(date)"
"Fri Apr 18 13:31:42 1997"
C-Kermit> echo "\fcommand(finger | wc -l)" ; how many users logged in?
" 83"
C-Kermit> evaluate \fcommand(finger | wc -l) * 2
166
C-Kermit> echo Welcome to \fcommand(tty) on \fcommand(date)
Welcome to /dev/ttyre on Fri Apr 18 13:31:42 1997
C-Kermit> echo "\fcommand(ls oofa.*)"
"oofa.c
oofa.h
oofa.o"
C-Kermit> cd /directory-with-thousands-of-files
C-Kermit> echo "\fcommand(ls -l)" ; This would be too long
""
C-Kermit>
If a command's output would be too long, you can use the other, more
laborious method of reading from a command: OPEN !READ command, READ
each line, CLOSE !READ.
The \frawcommand(command) function is identical to \fcommand(command),
except it does not remove trailing newline characters:
C-Kermit> echo "\frawcommand(date)"
"Fri Apr 18 13:31:42 1997
"
C-Kermit> echo "\frawcommand(ls oofa.*)"
"oofa.c
oofa.h
oofa.o
"
C-Kermit>
Use \frawcommand() if you want to retain the final line terminators,
or if the command's output is "binary". But remember that if the
result of this (or any other) function contains any NUL (ASCII code 0)
characters, the first NUL will terminate the result string because
this is how C strings work (it's "C-Kermit", remember?).
These functions are useful not only locally, but also in the
client/server arena. If you need to get the results from a system
command on the server end into a variable on the client end, just do:
[ remote ] query kermit command(date)
The result is in the local \v(query) variable; see [460]Using
C-Kermit, 2nd Ed., pp.359-360 for details.
_________________________________________________________________
4.3. Automatic Per-File Text/Binary Mode Switching
When transferring files between like systems (e.g. UNIX-to-UNIX),
binary mode can be used for all files unless character-set translation
is needed, and in fact Kermit programs of recent vintage recognize
each others' platforms and switch to binary mode automatically when it
is appropriate (e.g. DOS to OS/2, or UNIX to UNIX). (Exception:
LABELED mode is chosen for VMS-to-VMS and OS/2-to-OS/2 transfers so
complex file formats can be preserved.)
On a client/server connection between like systems, the transfer mode
is currently determined by the file sender, rather than always by the
client. If the client is sending, it controls the transfer mode. If a
GET command is sent to the server, the server sends all files in
binary mode if its TRANSFER CHARACTER-SET is TRANSPARENT; otherwise it
uses text mode for text files (according to its text-pattern list) and
binary mode for binary files. Of course, the client can control the
server's transfer character-set with the REMOTE SET TRANSFER
CHARACTER-SET command.
When transferring files between unlike systems, however, (e.g.
UNIX-to-DOS), some files (such as executable program images) must be
transferred in binary mode but others (such as plain-text files) must
be transferred in text mode so their record format and character sets
can be appropriately converted. If a binary file is transferred in
text mode, it is ruined. If a text file is transferred in binary mode,
then at the very least, its format can be incorrect; at worst it is
also corrupted because its character set was not converted (in extreme
cases the corruption is total, e.g. because one system is ASCII-based
and the other EBCDIC).
_________________________________________________________________
4.3.1. Exceptions
VMS C-Kermit, when sending files to a non-VMS system, switches to text
or binary mode automatically for each file, based on the record format
in the file's directory entry; thus the mechanisms described in this
section do not apply to VMS C-Kermit, yet the effect is the same:
automatic text/binary mode switching when VMS C-Kermit is sending
files. See the VMS Appendix of [461]Using C-Kermit for details.
Kermit versions that support LABELED or IMAGE transfer mode are
likewise not affected by this feature when one of those modes is
selected (normally used only when transferring between like systems).
Kermit versions that support file-transfer pipes and filters are not
affected by this feature when pipes or filters are used, since the
output of a pipe or filter (such as gzip) is likely to require
transfer in a different mode than the original file.
Finally, SEND /TEXT or SEND /BINARY will force files to be sent in the
indicated mode, overriding all automatic transfer-mode-choosing
mechanisms.
_________________________________________________________________
4.3.2. Overview
Suppose you give C-Kermit a command like:
SEND *.*
And suppose the pattern *.* matches a mixture of text files (such as
program source code) and binary files (such os object modules or
executable programs).
C-Kermit 6.0 and earlier (except on VMS) send all files in the same
mode: whatever you said in your most recent SET FILE TYPE command, or
else whatever mode was chosen automatically according to the rules on
page 236 of Using C-Kermit, 2nd Ed.
But when text and binary files are mixed in the same group, and the
files are being transferred to an unlike system (e.g. UNIX to IBM
Mainframe), this results in corruption of either all the text files or
all the binary files.
Stream-oriented file systems such as in UNIX and DOS do not record any
information about the file to tell us whether the file should be
transferred in binary or text mode, making it impossible to select the
transfer mode for each file in a group automatically with any
certainty.
However, we can use some fairly-well established file naming
conventions for this purpose. C-Kermit 7.0 lets you provide lists of
filename patterns that are used to separately determine the file type
for each individual file being transfered. A pattern is a string,
possibly containing the special characters "*" (asterisk, which
matches any string of zero of more characters) and/or "?" (question
mark, which matches any single character). For example "a*b" matches
all files whose names start with "a" and end with "b", such as "ab",
"arb", "ababababab", etc, but not "abba". And "a?b" matches any file
whose name starts with "a", ends with "b", and is exactly 3 characters
long.
NOTE: When typing commands at the C-Kermit prompt, you must prefix
"?" with \ to override its normal function of giving help.
(Also see [462]Section 4.9 for additional pattern-matching notations
that might be available in your version of C-Kermit.)
When you have specified filename recognition patterns, C-Kermit can
transfer the ones whose names match any of the binary-mode patterns in
binary mode, and those with names that match any of the text-mode
patterns in text mode, and those whose names match neither in the
prevailing mode you have chosen, or that was chosen automatically via
peer recognition.
_________________________________________________________________
4.3.3. Commands
SET FILE PATTERNS { ON, OFF, AUTO }
This tells Kermit whether to do per-file filename
pattern-matching to determine text or binary mode. The normal
and default setting is AUTO, which means to use pattern lists
to switch transfer mode only when it is certain that the other
Kermit program supports automatic notification of transfer mode
(via Attribute packets) on a per-file basis (this information
is obtained automatically during protocol startup negotiation).
ON means to always determine the transfer mode from the
filename and pattern list when sending files. Use OFF to
disable this feature (without resetting your pattern lists).
Also note that if you have selected LABELED file transfer (SET
FILE TYPE LABELED), this takes precedence over
filename-matching patterns and all files are sent in labeled
mode.
SET TRANSFER MODE MANUAL
Disables the use of filename patterns, no matter what the FILE
PATTERNS setting.
REMOTE SET TRANSFER MODE MANUAL
Client command to disable automatic transfer mode, and
therefore also filename patterns, in the server. Synonym:
REMOTE SET XFER MODE MANUAL.
{ GET, SEND, etc } { /BINARY, /TEXT }
Including a /BINARY or /TEXT (or, where supported, /IMAGE or
/LABELED) switch with a file-transfer command changes the
transfer mode to manual for that command only, and therefore
disables patterns that that command.
SET FILE BINARY-PATTERNS [ pattern [ pattern [ pattern ... ] ] ]
A list of zero or more patterns, separated by spaces (not
commas). Letters in a pattern are case-sensitive if the
underlying filenames are case sensitive (as in UNIX), and
case-insensitive otherwise (as in Windows). If a file's name is
matched by any pattern in the list and SET FILE PATTERNS is ON,
the file is sent in binary mode. Examples:
SET FILE BINARY-PATTERNS *.gz *.Z *.tar *.zip *.o *.so *.a *.out ; UNIX
SET FILE BINARY-PATTERNS *.EXE *.ZIP *.OBJ *.COM ; DOS or OS/2 or Windows
If a pattern contains spaces, enclose it in braces.
SET FILE TEXT-PATTERNS [ pattern [ pattern [ pattern ... ] ] ]
Like SET FILE BINARY-PATTERNS, but the patterns choose text
files rather than binary ones. Examples:
SET FILE TEXT-PATTERNS *.TXT *.KSC *.HTM* *.BAT ; DOS, Windows, OS/2
ADD BINARY-PATTERNS [ pattern [ pattern [ pattern ... ] ] ]
Adds one or more patterns to the BINARY-PATTERN list.
ADD TEXT-PATTERNS [ pattern [ pattern [ pattern ... ] ] ]
Adds one or more patterns to the TEXT-PATTERN list.
REMOVE BINARY-PATTERNS [ pattern [ pattern [ pattern ... ] ] ]
Removes one or more patterns from the BINARY-PATTERN list. The
given patterns are matched with the ones in the BINARY-PATTERNS
list with case sensitivity if the underlying file system has
case-sensitive names (as do UNIX and OS-9), otherwise with case
independence.
REMOVE TEXT-PATTERNS [ pattern [ pattern [ pattern ... ] ] ]
Removes one or more patterns from the TEXT-PATTERN list.
SHOW PATTERNS
Displays the current pattern selections.
Whenever you give a SET FILE BINARY-PATTERNS or SET FILE TEXT-PATTERNS
command, the previous list is replaced. If you give one of these
commands without a pattern list, the previous list is removed.
When patterns are active and files are being sent, text patterns (if
any) are applied first (but only if not RESENDing and not sending in
LABELED mode), then binary patterns, so if the same pattern appears in
both lists, binary mode is chosen.
_________________________________________________________________
4.3.4. Examples
Here's an example that might be used when sending files from UNIX:
set file type binary
set file text-patterns *.c *.h *.w *.txt makefile
set file binary-patterns *.o
msend makefile wermit wart ck*.[cwho] ck*.txt
Note that "wermit" and "wart" do not match any patterns so they are
sent in the prevailing mode, which is binary. Also note the use of
"makefile" as a pattern that does not contain any wildcard characters
(there is no other convention to distinguish among "wermit" and
"wart", which are binary executables, and "makefile", which is a text
file, purely by their names).
Most C-Kermit implementations have a default pattern list built in,
which includes patterns that are almost certain to succeed in picking
the right transfer mode. Others are omitted due to ambiguity. For
example ".hlp", and ".ini" are generally binary types in Windows but
text types everywhere else.
NOTE: ".doc", used for decades to denote plain-text documentation
files, now more often than not denotes a Microsoft Word Document,
so ".doc" is now considered a binary type since it does less harm
to transfer a plain-text document in binary mode than it does to
transfer an MS Word file in text mode (except when IBM mainframes
are involved!)
ANOTHER NOTE: ".com" files are binary in DOS-like operating
systems, but they are text (DCL command procedures) in VMS. VMS
C-Kermit sends .COM files in text mode; K95 sends them in binary
mode. If you download a .COM file from VMS to DOS or Windows, and
then upload it to another VMS system, be sure to use SEND /TEXT to
preserve its textness.
You can see the default pattern list by starting C-Kermit without its
initialization file (e.g. "kermit -Y") and using the SHOW PATTERNS
command. If you will be depending on this feature, be sure to examine
the list carefully in conjunction with the applications that you use.
The default pattern list does not take "backup files" into account
because (a) people usually don't want to transfer them; and (b) it
would make the pattern lists more than twice as long. For example, we
would need to include both *.txt and *.txt.~[0-9]*~ for ".txt" files,
and similarly for all the others. Instead, you can use SEND /NOBACKUP
(or SET SEND BACKUP OFF) to skip over all backup files.
Put your most commonly-used safe pattern declarations in your C-Kermit
customization file (ckermod.ini, .mykermrc, k95custom.ini, etc).
As noted, SET FILE PATTERNS is ON by default. Sometimes, however, it
is desirable, or necessary, to force files to be sent in a particular
mode, and often this must be done from the command line (e.g. when
using Kermit as a download helper in a Web browser like Lynx). The -V
command-line options is equivalent to SET FILE PATTERNS OFF and SET
TRANSFER MODE MANUAL. Example:
kermit -Vis oofa.txt
forces oofa.txt to be sent in binary mode, even though ".txt" might
match a text pattern.
_________________________________________________________________
4.4. File Permissions
"Permissions" refers to a code associated with a file that specifies
who is allowed to access it, and in what manner. For example, the
owner, the members of one or more groups, the system administrator,
and everybody else, might be allowed various combinations of Read,
Write, Append, Execute, or Listing access.
The permission code goes by different names on different platforms. In
UNIX, it might be called the filemode. In VMS, it is called the file
protection (or protection mask).
The comments in this section presently apply only to the UNIX and VMS
versions of C-Kermit, to which these features were added in version
7.0; the DOS, Windows, and OS/2 file systems embody no notions of
protection, and so MS-DOS Kermit and Kermit 95 do not send file
permissions, and ignore them when received.
The permissions for a received file are determined by a combination of
the file transfer mode (VMS-to-VMS transfers only), whether a file of
the same name exists already, whether permissions of the file are
received in the file attribute packet, and the setting of ATTRIBUTES
PROTECTION.
The default for ATTRIBUTES PROTECTION is ON. If no attributes are
received, the effect is the same as if attributes PROTECTION were OFF.
For VMS-to-VMS transfers, the default LABELED mode simply copies the
protection code from source to destination.
_________________________________________________________________
4.4.1. When ATTRIBUTES PROTECTION is OFF
If no file of the same name exists, system defaults determine the
permissions of the new file. Otherwise, the actions taken depend on
the current FILE COLLISION setting: BACKUP, OVERWRITE, RENAME, etc, as
documented in [463]Using C-Kermit. But now the new file (if it is
created at all) automatically inherits the permissions (mode bits) of
the existing file in a way that is appropriate for the platform.
4.4.1.1. Unix
All mode bits are inherited except the directory bit, since the
incoming file can not possibly be a directory. (In any case, it is not
possible to receive a file that has the same name as an existing
directory unless FILE COLLISION is set to RENAME).
4.4.1.2. VMS
Files with the same name as an existing file, transferred in modes
other than LABELED between VMS systems, inherit the protection of the
prior version.
_________________________________________________________________
4.4.2 When ATTRIBUTES PROTECTION is ON
File permissions can be conveyed as part of the file transfer process,
in accordance with the Kermit protocol definition. If the file sender
puts system-dependent and/or system-independent versions of the file
protection (permissions) into the Attribute (A) packet, the file
receiver can set the new file's permissions from them. Otherwise, the
permissions are set the same as for ATTRIBUTES PROTECTION OFF.
When the incoming A packet contains system-dependent permissions, the
file receiver checks to see if the sender has the same system ID (e.g.
both the sending and receiving systems are UNIX, or both are VMS); if
so, it decodes and uses the system-dependent permissions; otherwise it
uses the generic ones (if any) and applies them to the owner field,
setting the other fields appropriately as described in the following
sections.
Setting the incoming file's protection from the A packet is controlled
by SET ATTRIBUTES PROTECTION (or PERMISSION), which is ON by default,
and its status is displayed by SHOW ATTRIBUTES.
The main benefit of this feature is to not have to "chmod +x" an
executable file after transfer from UNIX to UNIX. Its cross-platform
benefits are less evident, perhaps to retain the status of the Unix
'x' bit on a VMS system, for subsequent transfer back to a Unix
system.
_________________________________________________________________
4.4.2.1. System-Specific Permissions
System-specific file permissions are used when the two Kermit programs
recognize each other as running on the same type of system. For
example, both are running under some form of UNIX (it doesn't matter
which UNIX variation -- HP-UX, Solaris, AIX, etc -- all use the same
scheme for file permissions); or both are running under VMS (even if
one is on an Alpha and the other on a VAX, and/or one is old and the
other is new).
4.4.2.1.1. UNIX
UNIX supports three categories of users, File Owner, Group, and World,
and three types of file access permission: Read, Write, and Execute.
Thus, a UNIX file's permissions are expressed in 9 bits.
The system-dependent permission string for UNIX is a 3-digit octal
string, the low-order 9 bits of the st_mode member of the stat struct;
we deliberately chop off the "file format" bits because they are not
permissions, nor do we convey the setuid/setgid bits, lock bit, sticky
bit, etc.
4.4.2.1.2. VMS
VMS supports four categories of users, System, File Owner, Group, and
World, and four types of file access permission: Read, Write, Execute,
and Delete. Thus, a VMS file's permissions are expressed in 16 bits.
The system-dependent protection string for VMS is a 4-digit
hexadecimal string, corresponding to the internal-format protection
word of the file (RWED for each of World,Group,Owner,System). A new
file normally gets all 16 protection bits from the original file of
the same name.
Note: VMS-to-VMS transfers take place in LABELED mode when the two
C-Kermits recognize each other's platform as VMS (unless you have
disabled LABELED-mode transfers). In this case, all of a file's
attributes are preserved in the transfer and the protection mask (and
other information) is taken from the file's internal information, and
this takes precedence over any information in the Attribute packets.
You can defeat the automatic switching into LABELED mode (if you want
to) with SET TRANSFER MODE MANUAL.
_________________________________________________________________
4.4.2.2. System-Independent Permissions
The system-independent ("generic") protection is used when the system
IDs of the two Kermit programs do not agree (e.g. one is UNIX, the
other is VMS). The generic protection attribute includes the following
permissions (not all are applicable to every file system): Read,
Write, Append, Execute, Delete, Search. The generic permissions are
derived from the owner permissions of the source file, thus, a Unix
'w' permission becomes VMS Write,Delete.
The Owner field of the new file's permissions is set from the incoming
generic protection attribute.
In UNIX, the Group and World permissions are set according to your
umask, except that execute permission is NOT set in these fields if it
was not also set in the generic protection (and consequently, is set
in the Owner field).
In VMS, the System, Group, and World permissions are set according to
the process default file permission (as shown in VMS by SHOW
PROTECTION), except that no permissions are allowed in these fields
that are not included in the generic permissions.
Note that the VMS and UNIX interpretations of Execute permission are
not identical. In UNIX, a file (binary executable, shell script, etc)
may not be executed unless it has Execute permission, and normally
files that are not intended for execution do not have Execute
permission. In VMS, Read permission implicitly supplies Execute
capability. Generally files that have Read permission also have
explicit Execute permission, but files (binary executables, DCL
command procedures) that have Read permission and not Execute
permission can still be executed.
_________________________________________________________________
4.5. File Management Commands
4.5.1. The DIRECTORY Command
Prior to C-Kermit 7.0, the DIRECTORY command always ran an external
system command (such as "ls" on UNIX) or program to product the
directory listing. This had certain advantages, mostly that you could
include system-dependent options for customized listings, e.g. on
UNIX:
dir -lt c* | more
or in VMS:
directory /size/date/protection/except=*.obj oofa.*;0
This approach, however, carries some disadvantages: C-Kermit can't
return SUCCESS or FAILURE status for (e.g.) "dir foo" according to
whether the file "foo" exists; and it runs an inferior process, which
might be a problem in some environments for resource and/or security
reasons, and won't work at all in a "nopush" environment (e.g. one in
which C-Kermit is configured to forbid access to exterior commands and
programs, e.g. in a VMS "captive account").
In C-Kermit 7.0 on VMS and UNIX, and in K95 1.1.19 and later, the
DIRECTORY command is internal to Kermit. It can be run in a "nopush"
environment and returns SUCCESS or FAILURE status appropriately. In
UNIX it prints all dates and times in a consistent way (unlike ls). In
VMS it prints precise file sizes, rather than "blocks". It offers
several formatting and other options, but it is not necessarily more
flexible than the corresponding external commands or programs (the
UNIX "ls" program, the VMS "directory" command). The syntax is:
DIRECTORY [ switch [ switch [ ... ] ] ] [ filespec ]
If no filespec is given, all files in the current directory are
listed.
Optional switches include all the standard file-selection switches
presented in [464]Section 1.5.4, plus:
/ALL
Show both regular files and directories; this is the default.
/ARRAY:x
Instead of displaying a directory listing, put the files that
would have been shown (based on the filespec and other
selection switches) in the given array. The array need not (and
should not) be predeclared; if the array already exists, it is
destroyed and reused. The array name can be a single letter,
like "a", or any fuller form, such as "&a", "\&a", "\&a[]",
etc. If the /ARRAY switch is included, the following other
switches are ignored: /BRIEF, /VERBOSE, /HEADING, /PAGE,
/ENGLISHDATE, /ISODATE, /XFERMODE, /MESSAGE, /SORT, /REVERSE,
/ASCENDING. In other words, only file selection switches are
meaningful with /ARRAY: /FILES, /DIRECTORIES, /ALL, /DOTFILES,
/NOBACKUP, /RECURSIVE, /SMALLER, /LARGER, /AFTER, /BEFORE,
/EXCEPT, etc. The resulting array has the number of files (n)
as its 0th element, and the filenames in elements 1 through n
Example:
dir /array:&a /files /nobackup /after:19990101 /larger:10000 [ab]*
show array &a
/FILES
Only show regular files.
/DIRECTORIES
Only show directories.
/BACKUP
In UNIX, OS-9, K-95, and other versions that support SET FILE
COLLISION BACKUP and create backup files by appending .~n~ to
the filename (where "n" is a number), /BACKUP means to include
these files in directory listings. This is the default.
/NOBACKUP
This is the opposite of /BACKUP: that is, do not include backup
files in the listing.
/BRIEF
List filenames only; use a compact format, as many filenames as
will fit across the screen (based on the longest name). A brief
listing is always sorted alphabetically.
/VERBOSE
List one file per line, and include date, size, and (in UNIX
only) permissions of each file. This is the opposite of /BRIEF,
and is the default.
/PAGE
Pause at the end of each screenful and give a "more?" prompt,
even if SET COMMAND MORE-PROMPTING is OFF.
/NOPAGE
Don't pause at the end of each screenful and give a "more?"
prompt, even if SET COMMAND MORE-PROMPTING is ON. If neither
/PAGE or /NOPAGE is given, paging is according to the
prevailing COMMAND MORE-PROMPTING setting (which can be
displayed with SHOW COMMAND).
/ENGLISHDATE
Show dates in dd-mmm-yyyy format; mmm is the first three
letters of the English month name.
/ISODATE
Show dates in yyyy-mm-dd format; mm is the month number, 1-12.
This is the opposite of /ENGLISHDATE, and is the default.
/HEADINGS
Print a heading before the listing and a summary at the end.
/NOHEADINGS
Don't print a heading before the listing or a summary at the
end. This is the opposite of /HEADINGS, and is the default.
/XFERMODE
Only in Kermit programs that support SET FILE PATTERNS. If this
switch is included, and the filename matches any FILE
BINARY-PATTERN ([465]Section 4.3), "(B)" is printed after the
filename; otherwise, if it matches a FILE TEXT-PATTERN, "(T)"
is printed.
/NOXFERMODE
Don't display transfer-mode indicators. This is the opposite of
/XFERMODE and is the default.
/RECURSIVE
Show files not only in the given directory, but also in its
subdirectories (if any), their subdirectories, etc.
/NORECURSIVE
Don't show files in subdirectories. This is the opposite of
/RECURSIVE, and is the default.
/MESSAGE:text
This lets you specify a short text string to be appended to the
end of each directory listing line (a space is supplied
automatically). If the text contains any spaces, enclose it in
braces, e.g. /MESSAGE:{two words}.
/NOMESSAGE
Don't append any message to the end of each directory listing
line (default).
/SORT:[{NAME,SIZE,DATE}]
Sort the listing by name, size, or date. If the /SORT switch is
given but the "sort-by" keyword is omitted, the listing is
sorted by name. /SORT:NAME /ASCENDING (alphabetic sort by name)
is the default.
/NOSORT
Don't sort the listing. Files are listed in whatever order they
are supplied by the operating system, e.g. inode order in UNIX.
/REVERSE
If the /SORT switch is given, reverse the order of the sort.
Synonym: /DESCENDING.
/ASCENDING
If the /SORT switch is given, sort the listing in normal order.
This is the opposite of /REVERSE and is the default.
Note that most of the DIRECTORY-specific switches come in pairs, in
which one member of a pair (e.g. /NOHEADINGS) is the opposite of the
other (e.g. /HEADINGS).
If you always want to use certain options, you can set them with the
SET OPTIONS DIRECTORY command ([466]Section 1.5.5). Use SHOW OPTIONS
to list the options currently in effect. To make the desired options
apply every time you run C-Kermit, put a SET OPTIONS DIRECTORY command
in your C-Kermit customization file, specifying the desired options.
Options set in this manner apply to every subsequent DIRECTORY
command. Of course, if you include switches in a DIRECTORY command,
these override any defaults, built-in or custom. Example:
DIRECTORY ; Use "factory defaults"
SET OPTIONS DIRECTORY /SORT:SIZE /REVERSE /HEADINGS ; Customize defaults
DIRECTORY ; Use customized defaults
DIR /SORT:NAME ; Override customized default SORT key
SET OPT DIR /RECURS ; Add /RECURSIVE to customized defaults
DIR /ASCEND ; Override customized default SORT order
Notes:
* Only a single sort key is supported; there is presently no way to
have multiple sort keys.
* If the /BRIEF switch is given, all other switches (except
/[NO]RECURSIVE, /[NO]DOTFILES, /DIRECTORIES, /FILES, and /ALL) are
ignored.
* /SORT:anything gives incorrect results if any files have lengths
greater than 10 digits (i.e. that are more than 9999999999 bytes
long, i.e. if they are 10GB or more in size) because the overlong
length field causes the date and name fields to be misaligned.
* /SORT:NAME is redundant in VMS since VMS returns filenames in
alphabetic order anyway.
* /SORT:NAME ignores alphabetic case on platforms where case does
not matter in filenames, but this works only for unaccented Roman
letters A-Z.
* /SORT:NAME is currently based on code values, and so works fine
for ASCII, but will probably produce unexpected results for files
with non-ASCII or 8-bit characters in their names. (Locale-based
sorting raises rather significant issues of portability, size,
performance, etc.)
* /SORT:DATE works right only for ISO-format dates, not English
ones.
* /SORT:SIZE sorts the size field lexically. On some platforms (e.g.
Windows), the size of a directory file is listed as "<DIR>" rather
than as a number; in this case, the "<DIR>" files are gathered at
the end (or beginning, depending on the sort order) of the
listing.
* /RECURSIVE is accepted but ignored in AOS/VS. Use the normal
system-specific filespec notation, e.g. "dir #.txt".
* /RECURSIVE has no affect when a full, absolute pathname is given;
e.g. "dir /recursive /tmp/foo" (where "foo" is a regular file)
only shows the "/tmp/foo" file. If you want to see all "foo" files
in the /tmp tree, do "cd /tmp" and then "dir /recursive foo".
* If a file size of -1 is shown, or date-time of 0000-00-00
00:00:00, this means the file was located, but access to
information about the file was denied to C-Kermit.
* In VMS, if FOO.DIR;1 is a directory within your current directory,
"directory foo" and "directory [.foo]" list the files in the
[.FOO] subdirectory, but "directory foo.dir" lists the directory
file itself; similarly for "*.dir" versus "[.*]", etc.
* In UNIX, if "foo" is a directory within your current directory,
"directory foo" lists the files in the foo directory. If you want
to list the foo directory file itself, put an asterisk at the end:
"dir foo*".
Hint: How to find the biggest files in a directory tree:
cd xxx ; (root of tree)
directory /sort:size /recursive /reverse /dotfiles /page
Another hint: If you often use several different directory-listing
formats, define macro shortcuts for them:
DEFINE WD DIRECTORY /SORT:DATE /REVERSE \%* ; Reverse chronological order
DEFINE SD DIRECTORY /SORT:SIZE /REVERSE \%* ; Reverse order of size
DEFINE ND DIRECTORY /SORT:NAME /ASCEND \%* ; Alphabetical by name
DEFINE DL DIR /DIR /SORT:NAME /ASCEND \%* ; Alphabetical directory list
Put these definitions in your C-Kermit customization file. Note that
"\%*" ([467]Section 7.5) in these definitions lets you include other
switches in your macro invocations, e.g.:
wd /headings *.txt
Of course you can still access your external directory listing program
by using RUN or "!", e.g. in VMS:
run directory /size/date/protection/except=*.obj oofa.*;0
or:
!dir /size/date/prot/exc=*.obj oofa.*;0
In UNIX, use "!ls" or just "ls" (which is a special synonym for
"!ls").
_________________________________________________________________
4.5.2. The CD and BACK Commands
In C-Kermit 7.0, the CD command has a new friend, the BACK command.
BACK means "CD to my previous current directory". A second BACK brings
you back to where you were before the first one; thus successive BACK
commands switch back and forth between two directories.
4.5.2.1. Parsing Improvements
The CD command, as well as other commands that parse a directory name,
were changed in 7.0 to provide all the expected functions: completion
on Tab or Esc, directory-name lists on ?, etc. Other affected commands
include SET SERVER GET-PATH, SET TEMP-DIRECTORY, SET FILE
DOWNLOAD-DIRECTORY, and SPACE. CD and REMOTE CD also now work with
logical names.
In VMS, the situation is a bit complicated since a directory name can
look like "DEV:", "[FOO.BAR]", "DEV:[FOO.BAR]", "[FOO]BAR.DIR;1", etc.
Completion and ?-help might not always work, but they do in many
cases. Examples:
cd ? Lists all subdirectories of the current directory
cd []? Ditto
cd k? Ditto, but only those starting with K
cd [foo]? Lists all subdirectories of the [FOO] directory
cd [-]? Lists all subdirectories of the superior directory
cd [--]? Lists all subdirectories of the directory 2 levels up
cd [...]? Lists all directories below the current one
cd [foo.? Does not work.
C-Kermit allows all of the following in VMS:
cd bar CD to subdirectory BAR of the current directory
cd .bar Ditto
cd [.bar] Ditto
cd bar.dir etc...
cd bar.dir;
cd bar.dir;1
cd [foo.bar]
cd bar.baz This can go more than 1 level deep...
cd dir: (where logical name DIR is defined as [FOO.BAR])
As well as the following:
cd .. Go up one level as in UNIX
cd . The current directory
cd My login directory
Note that "cd -" (go up one level) does not work as expected, because
"-" is Kermit's command continuation character. However, "cd [-]", and
"
cd {-}" have the desired effect (and so does "cd ..", which is easier
to type).
_________________________________________________________________
4.5.2.2. The CDPATH
The CD command in the UNIX, Windows, OS/2, and VMS versions of
C-Kermit, as of version 6.1 / 1.1.12, searches the CDPATH for the
given directory, if it is not absolute and if a CDPATH environment
variable is defined. Example (in UNIX ksh or bash):
$ export CDPATH=$HOME:$HOME/kermit:/tmp
Now if you give a "cd xxx" command, no matter what your current
directory is, if the "xxx" directory is not a subdirectory of your
current directory, then the xxx subdirectory of your home directory is
used or if that does not exist, then the xxx subdirectory of the
kermit subdirectory of your home directory is used or if that does not
exist, then /tmp/xxx is used. This is how the ksh "cd" command works,
and now the C-Kermit CD command works the same way.
In VMS, you can define CDPATH to be a list of directories that contain
actual directory delimiters, and/or logical names representing
directories, using commas to separate them, e.g.:
$ define cdpath [HOME],[SOMEOTHERDIR],[HOME.MISC]
$ define cdpath SYS$LOGIN:,DISK1:[HOME],DISK2:[SCRATCH.IVAN]
Example:
$ define cdpath SYS$LOGIN:,[IVAN],[OLAF],[OLGA.MISC]
$ kermit
DISK1:[OLGA] C-Kermit> cd blah
tries the BLAH subdirectory of the user's login directory, then
[OLGA.BLAH], [IVAN.BLAH], [OLAF.BLAH], and [OLGA.MISC.BLAH], in that
order, using the first one it finds, failing if it finds none.
In C-Kermit 7.0, you may also set the CDPATH from the Kermit prompt:
SET CD PATH path
Allows the CD PATH to be set from within C-Kermit.
SHOW CD shows the CD path and all other information relevant to the CD
command.
_________________________________________________________________
4.5.2.3. CD Messages
Whenever you change directory, you can have C-Kermit display a "Read
Me" file from the new directory automatically. The commands are:
SET CD MESSAGE { ON, OFF, FILE list }
ON enables this feature; OFF (the default) disables it. File
lets you specify the name of the "Read Me" file. A list of
names to look for can be given in the following format:
{{name1}{name2}{name3}{...}}
e.g.:
SET SERVER CD-MESSAGE FILE {{./.readme}{README.TXT}{READ.ME}}
The default list of CD-message files is system dependent.
SHOW CD shows your current directory, previous directory, CD path, and
CD message info.
_________________________________________________________________
4.5.3. Creating and Removing Directories
The MKDIR command now allows you to create multiple directories at
once:
C-Kermit> mkdir a/b/c/d
creates the directory a in the current directory (if it doesn't exist
already), and then creates subdirectory b in the a directory (if it
didn't exist already), and so on.
If you use MKDIR to try to create a directory that already exists,
C-Kermit will print a warning ("?Directory already exists"), but the
MKDIR command will still succeed. If you want to avoid the warning
message, use IF DIRECTORY first to check if the directory already
exists.
The RMDIR command, however, will not remove more than one directory,
nor will it remove a directory that contains any files. (There is, as
yet, no RMDIR /RECURSIVE command, although one might be added later.)
In VMS, these commands (like CD) are more forgiving of your syntax
than is the DCL command shell; "mkdir oofa" is equivalent to "mkdir
[.oofa]" and so on. Also in VMS, you'll find that C-Kermit's RMDIR
command is easier than deleting a directory in DCL, since it
automatically first gives it owner delete permission if you are the
owner.
_________________________________________________________________
4.5.4. The DELETE and PURGE Commands
The DELETE command now offers a selection of switches, and has a new
companion, the PURGE command. First, DELETE:
DELETE [ switches... ] filespec
Deletes the file or files that match the filespec, which may
contain wildcards ([468]Section 4.9).
Optional switches include the standard file-selection switches
presented in [469]Section 1.5.4, plus:
/ASK
Before deleting each file, ask permission interactively.
Answers are Yes or OK (delete the file), No (don't delete it),
or Quit (stop executing the DELETE command).
/NOASK
Don't ask permission to delete each file.
/LIST
List each file and show whether it was deleted. Synonyms: /LOG,
/VERBOSE.
/NOLIST
Don't list files while deleting them. Synonyms: /NOLOG, /QUIET.
/HEADING
Print a heading and summary line.
/NOHEADING
Don't print a heading and summary line.
/PAGE
When listing, pause at the end of each screenful and give the
"More?" prompt. If you reply "n" (no), the DELETE command
terminates.
/SIMULATE
Do everything implied by the given switches and filespec,
except do not actually delete any files. This lets you preview
which files would be deleted; implies /LIST.
Now the PURGE command:
PURGE [ switches... ] [ filespec ]
(VMS only) Runs the DCL PURGE command. Switches and filespec,
if any, are passed directly to DCL without parsing or
verification. Deletes excess versions of the given (or all)
files. The rest of this section does not apply to VMS.
PURGE [ switches... ] [ filespec ]
(UNIX only) Deletes "backup files" that match the filespec,
which may contain wildcards ([470]Section 4.9). If no filespec
is given, all backup files in the current directory are
selected (subject to modification by any switches). Do not
include backup notation in the filespec.
Explanation:
To avoid destroying preexisting files when a new file arrives that has
the same name, C-Kermit backs up the old file by appending a "backup
number" to its name. In UNIX, the backup suffix consists of a period,
a tilde, a number, and another tilde. For example, if a file called
oofa.txt exists and a new oofa.txt file arrives, the original is
renamed to oofa.txt.~1~. If another oofa.txt file arrives, the
existing one is renamed to oofa.txt.~2~. And so on. This system is
compatible with the one used by EMACS. Thus over time, if you receive
a lot of files with C-Kermit or edit them with EMACS, backup files can
build up. The new PURGE command lets you clean out accumulated backup
files:
Optional switches include the standard file-selection switches
presented in [471]Section 1.5.4, plus all the switches listed above
for the DELETE command, plus:
/KEEP:n
Retains the n most recent (highest-numbered) backup files for
each file. For example, if oofa.txt, oofa.txt.~1~,
oofa.txt.~2~, oofa.txt.~10~, oofa.txt.~12~, and oofa.txt.~100~
exist, "purge /keep:2 oofa.txt" deletes oofa.txt.~1~,
oofa.txt.~2~, and oofa.txt.~10~, and keeps oofa.txt,
oofa.txt.~12~, and oofa.txt.~100~. If /KEEP is given without a
number, one (the highest numbered) backup file is kept.
CAUTION: The PURGE command should be used only when *.~*~ files truly
are backup files. This is the case for EMACS, and it is the DEFAULT
for C-Kermit. However, if C-Kermit's FILE COLLISION has been set to
RENAME, newly received files will look like backup files. In that
case, don't use the PURGE command or you'll be removing new files
rather than old ones. (Use SHOW FILE to find the FILE COLLISION
setting.)
The PURGE command is presently available only in UNIX. The command
succeeds if it deleted any files, or if it deleted no files but there
were no errors. It fails if it deleted no files and there were errors
(i.e. deletion was attempted but failed). In VMS, backup file versions
are handled automatically by the OS, and a PURGE command can be used
at the VMS prompt to clean them up.
If you want certain switches to be supplied automatically with each
DELETE or PURGE command, you can set them with SET OPTIONS
([472]Section 1.5.5) and you can display any such settings with SHOW
OPTIONS. Of course you can override them on a per-command basis by
including switches in your PURGE or DELETE command.
Also see SET FILE COLLISION, SHOW FILE, SEND /NOBACKUP, SET SEND
BACKUP, and DIRECTORY /[NO]BACKUP.
_________________________________________________________________
4.6. Starting the Remote Kermit Server Automatically
As noted on pages 275-276 of [473]Using C-Kermit 2nd edition, you can
have Kermit send "kermit receive" commands automatically when it is in
local mode and you give a SEND or similar command, to start the remote
Kermit receiver in case it is not already started. The "kermit
receive" commands are specified by:
SET PROTOCOL KERMIT binary-receive-command text-receive-command
As of version 7.0, a Kermit protocol option has been added to send a
string to the host in advance of any Kermit packets when you give a
GET-class or REMOTE command. This will switch the remote C-Kermit into
the appropriate mode or, if the remote system is at a system command
(shell) prompt, execute the string on the remote system. The new
syntax of the SET PROTOCOL KERMIT command is:
SET PROTOCOL KERMIT [ s1 [ s2 [ s3 ] ] ]
where:
Default Meaning
s1 {kermit -ir} Remote "kermit receive in binary mode" command.
s2 {kermit -r} Remote "kermit receive in text mode" command.
s3 {kermit -x} Remote "start kermit server" command.
NOTE: If the remote Kermit is 6.0, the following are recommended for
fast startup and high-performance file transfer (see Appendix I in
[474]Using C-Kermit, second Edition, for command-line options):
s1 kermit -YQir (Kermit receive binary, skip init file, fast.)
s2 kermit -YQTr (Kermit receive text, skip init file, fast.)
s3 kermit -YQx (Kermit server, skip init file, fast.)
If the remote is C-Kermit 7.0 or later, change the -x option (enter
server mode) to -O (uppercase letter O), which means "enter server
mode for One transaction only); this way, it is not stuck in server
after the transfer. Also note that the Q is redundant in version 7.0,
since fast Kermit protocol settings are now the default.
Note that in case the C-Kermit executable is called "wermit" or
"ckermit" you can change "kermit" in the strings above to "wermit" or
"ckermit" and C-Kermit 7.0 or later will recognize these as synonyms
for "kermit", in case it is at its command prompt when one of these
strings is sent to it.
_________________________________________________________________
4.7. File-Transfer Command Switches
Over the years, various new methods of transferring a file have
accumulated, until we had, in addition to the SEND command, also MOVE
(send and then delete), MAIL (send as email), REMOTE PRINT (send to be
printed), CSEND (send the output of a command), PSEND (send a part of
a file), BSEND (send in binary mode), RESEND (resume an interrupted
SEND), etc etc. Similarly: GET, REGET, CGET, RETRIEVE, and so on.
Not only is it confusing to have different names for these commands,
many of which are not real words, but this also does not allow all
combinations, like "send a file as mail, then delete it".
In C-Kermit 7.0, the SEND, GET, and RECEIVE commands were restructured
to accept modifier switches (switches are explained in [475]Section
1.5).
_________________________________________________________________
4.7.1. SEND Command Switches
Without switches, the SEND command still works exactly as before:
send oofa.txt ; send a single file
send oofa.* ; send multiple files
send oofa.txt x.x ; send oofa.txt as x.x (tell receiver its name is x.x)
send ; send from SEND-LIST
But now the following modifier switches may be included between "send"
and the filename. Zero, one, two, or more switches may be included in
any combination that makes sense. Switch names (such as /BINARY) can
be abbreviated, just like any other keywords. Most of these switches
work only when using Kermit protocol (/TEXT and /BINARY are the
exceptions).
/AFTER:date-time
Specifies that only those files modified (or, in VMS, created)
after the given date-time (see [476]Section 1.6) are to be
sent. Examples:
send /text /after:{2-Feb-1997 10:28:30} *.txt
send /text /after:\fdate(oofa.txt) *.txt
Synonym: /SINCE.
/ARRAY:arrayname
Specifies that instead of sending a file, C-Kermit is to send
the contents of the given array. Since an array does not have a
filename, you should include an /AS-NAME switch to specify the
name under which the array is to be sent (if you do not, the
name "_array_x_" is used, where 'x' is replaced by the array
designator). See [477]section 7.10 for array-name syntax. As
noted in that section, you can also include a range to have a
segment of the array sent, rather than the whole thing; for
example: "send /array:&a[100:199]". It is strongly recommended
that you accompany the /ARRAY switch with a /TEXT or /BINARY
switch to force the desired transfer mode, since otherwise the
various automatic mechanisms might switch to binary mode when
you really wanted text, or vice versa. In text mode a line
terminator is added to the end of each array element, but not
in binary mode. For details and examples see [478]Section
7.10.11.
/AS-NAME:text
Specifies "text" as the name to send the file under. You can
also still specify the as-name as the second filename on the
SEND command line. The following two commands are equivalent:
send oofa.txt oofa.new
send /as:oofa.new oofa.txt
/BEFORE:date-time
Specifies that only those files modified (or, in VMS, created)
before the given date-time ([479]Section 1.6) are to be sent.
/BINARY
Performs this transfer in binary mode without affecting the
global transfer mode, overriding not only the FILE TYPE and
TRANSFER MODE settings, but also the FILE PATTERN setting, but
for this SEND command only. In other words, SEND /BINARY means
what it says: send the file in binary mode, regardless of any
other settings. Example:
set file type text ; Set global transfer mode to text
send /binary oofa.zip ; Send a file in binary
send oofa.txt ; This one is sent in text mode
/COMMAND
SEND /COMMAND is equivalent to CSEND ([480]Section 4.2.2) -- it
says to send the output from a command, rather than the
contents of a file. The first "filename" on the SEND command
line is interpreted as the name of a command; the second (if
any) is the as-name. Examples:
send /command {grep Sunday oofa.txt} sunday.txt
send /as-name:sunday.txt /command {grep Sunday oofa.txt}
send /bin /command {tar cf - . | gzip -c} {!gunzip -c | tar xf -}
/DELETE
Deletes the file (or each file in the group) after it has been
sent successfully (but does not delete it if it was not sent
successfully). SEND /DELETE is equivalent to MOVE. Has no
effect when used with /COMMAND. Example:
send /delete *.log
/DOTFILES
(UNIX and OS-9 only) Normally files whose names begin with "."
are skipped when matching wildcards that do not also beging
with ".". Include /DOTFILES to force these files to be included
too.
/RECURSIVE
Descend the through the directory tree when locating files to
send. Automatically sets /PATHNAMES:RELATIVE. Explained in
[481]Section 4.11 .
/EXCEPT:pattern
See [482]Section 1.5.4.
/NOBACKUP
This means to skip backup files when sending, even if they
match the SEND file specification. This is equivalent to using
SEND /EXCEPT and including *.~[0-9]*~ in the exception list (or
*.~*~ if Kermit was built without pattern-matching support; see
[483]Section 4.9.1). Including this switch is equivalent to
giving SET SEND BACKUP OFF ([484]Section 4.0.6) prior to SEND,
except its effect is local to the SEND command with which it
was given.
/NODOTFILES
The opposite of /DOTFILES (q.v.)
/FILENAMES:{CONVERTED,LITERAL}
Use this switch to override the current global SET FILE NAMES
setting for this transfer only.
/FILTER:command
This specifies a filter to pass the file through before sending
it. See the [485]section on file-transfer pipes and filters.
The /FILTER switch applies only to the file-transfer command it
is given with; it does not affect the global SEND FILTER
setting, if any.
/IMAGE
VMS: Sends in image mode. Non-VMS: same as /BINARY.
/LABELED
VMS and OS/2 only: Sends in labeled mode.
/LARGER-THAN:number
Specifies that only those files that are longer than the given
number of bytes are to be sent.
/LISTFILE:filename
Specifies that the files to be sent are listed in a file with
the given filename. The file contains one filename per line.
These filenames are not checked in any way; each filename is
taken and does not use or depend on any Kermit-specific syntax.
In particular, backslashes are not treated specially, leading
and trailing spaces are not stripped, etc. However, if a
filename contains wildcards, they are expanded. Example: If a
file named files.txt contains the following lines:
blah.txt
oofa*
x.x
(but without leading or trailing spaces), then the C-Kermit
command "send /listfile:files.txt" will send the files
blah.txt, x.x, and all files whose names start with "oofa",
assuming the files exist and are readable. The /LISTFILE
switch, can, of course, be used with other switches when it
makes sense, for example, /EXCEPT, /BINARY, /AFTER, /SMALLER,
/MOVE-TO, /DELETE, /AS-NAME with a template, etc.
/MAIL:address
Sends the file as e-mail to the given address or addresses.
"send /mail:address filename" is equivalent to "mail filename
address". You can include multiple addresses separated by
commas. Examples:
send /mail:kermit-support@columbia.edu packet.log
send /mail:cmg,fdc,jrd oofa.txt
As with any switch argument, if the address or address list
contains any spaces, you must enclose it in braces. The format
of the addresses must agree with that understood by the
mail-sending program on the receiver's computer.
/MOVE-TO:directory-name
Specifies that after each (or the only) source file is sent
successfully, and ONLY if it is sent successfully, it should be
moved to the named directory. If the directory name contains
spaces, enclose it in braces. If the directory does not exist,
it is created if possible; if it can't be created, the command
fails and an error message is printed. Example:
send /text /move-to:/users/olga/backup/ *.txt
/NOT-AFTER:date-time
Specifies that only those files modified at or before the given
date and time are to be sent.
/NOT-BEFORE:date-time
Specifies that only those files modified at or after the given
date and time are to be sent.
/PATHNAMES:{OFF,ABSOLUTE,RELATIVE}
Use this switch to override the current global SET SEND
PATHNAMES setting for this transfer only. /PATHNAMES:ABSOLUTE
or RELATIVE also sets /FILENAMES:LITERAL (also for this
transfer only) since pathnames are not sent otherwise.
/RENAME-TO:text
Specifies that after the (or each) source file is sent
successfully, and ONLY if it is sent successfully, it should be
renamed to the name given. If the name contains spaces, enclose
it in braces. If a file group is being sent, then the "text"
must contain a variable reference such as \v(filename) (see
[486]Section 4.1). Example:
send /rename-to:ok_\v(filename) *.*
This sends each file in the current directory and if it was
sent successfully, changes its name to begin with "ok_".
/SMALLER-THAN:number
Specifies that only those files that are smaller than the given
number of bytes are to be sent.
/SUBJECT:text
Subject for email. Actually, this is just a synonym for
/AS-NAME. If the text includes spaces, you must enclose it in
braces. If you don't specify a subject (or as-name), the name
of the file is used as the subject. Example:
send /mail:kermit-support@columbia.edu /subj:{As requested} packet.log
/PRINT:options
Sends the file to be printed, optionally specifying options for
the printer. Equivalent to REMOTE PRINT filename options.
Examples:
send /print oofa.txt ; No options.
send /print:/copies=3 oofa.txt ; "/copies=3" is a VMS PRINT switch.
send /print:-#3 oofa.txt ; "-#3" is a UNIX lpr switch.
/PROTOCOL:name
Uses the given protocol to send the file (Kermit, Zmodem, etc)
for this transfer without changing global protocol. Only
available in Kermit 95, UNIX, and OS-9. Example:
set protocol kermit ; Set global protocol
send /proto:zmodem /bin oofa.zip ; Send just this file with Zmodem
send oofa.txt ; This file is sent with Kermit
/QUIET
When sending in local mode, this suppresses the file-transfer
display.
/RECOVER
Used to recover from a previously interrupted transfer; SEND
/RECOVER is equivalent to RESEND. Recovery only works in binary
mode; SEND /RECOVER and RESEND include an implied /BINARY
switch. Even then, recovery will successful only if (a) the
original (interrupted) transfer was also in binary mode, or (b)
if it was in text mode, the two Kermit programs run on
platforms where text-mode transfers are not length-changing.
/STARTING:number
Starts sending the file from the given byte position. SEND
/STARTING:n filename is equivalent to PSEND filename n.
/TEXT
Performs this transfer in text mode without affecting the
global transfer mode, overriding not only the FILE TYPE and
TRANSFER MODE settings, but also the FILE PATTERN setting, for
this SEND command only. In other words, SEND /TEXT really send
the file in text mode, regardless of any other settings or
negotiations.
About mail... Refer to [487]Section 4.7.1. The same rules apply as for
file transfer. If you are mailing multiple files, you can't use an
as-name (in this case, a subject) unless it contains replacement
variables like \v(filenum). For example, if you:
send /mail:somebody@xyz.com *.txt
Then each file will arrive as a separate email message with its name
as the subject. But if you:
send /mail:somebody@xyz.com /subject:{Here is a file} *.txt
Then each file message will have the same subject, which is probably
not what you want. You can get around this with constructions like:
send /mail:somebody@xyz.com /subject:{Here is \v(filename)} *.txt
which embed the filename in the subject.
The MOVE, CSEND, MAIL, and RESEND commands now also accept the same
switches. And the switches are also operative when sending from a
SEND-LIST (see [488]Using C-Kermit, 2nd Ed, pp.191-192), so, for
example, it is now possible to SEND /PRINT or SEND /MAIL from a
SEND-LIST.
The MSEND and MMOVE commands also take switches, but not all of them.
With these commands, which take an arbitrary list of filespecs, you
can use /BINARY, /DELETE, /MAIL, /PRINT, /PROTOCOL, /QUIET, /RECOVER,
and /TEXT (and /IMAGE or /LABELED, depending on the platform). MMOVE
is equivalent to MSEND /DELETE. (If you want to send a group of files,
but in mixed transfer modes with per-file as-names, use ADD SEND-LIST
and then SEND.)
The MSEND/MMOVE switches come before the filenames, and apply to all
of them:
msend /print /text *.log oofa.txt /etc/motd
If you type any of these commands (SEND, CSEND, MSEND, etc) followed
by a question mark (?), you will see a list of the switches you can
use. If you want to see a list of filenames, you'll need to type
something like "send ./?" (UNIX, OS/2, Windows, etc), or "send []?"
(VMS), etc. Of course, you can also type pieces of a filename
(anything that does not start with "/") and then "?" to get a list of
filenames that start that way; e.g. "send x.?" still works as before.
In UNIX, where "/" is also the directory separator, there is usually
no ambiguity between a fully-specified pathname and a switch, except
when a file in the root directory has the same name as a switch (as
noted in [489]Section 1.5):
send /etc/motd ; Works as expected
send /command ; ???
The second example interprets "/command" as a switch, not a filename.
To send a file actually called "command" in the root directory, use:
send {/command}
or other system-dependent forms such as //command, /./command,
c:/command, etc, or cd to / and then "send command".
_________________________________________________________________
4.7.2. GET Command Switches
Without switches, the GET command still works about the same as
before:
get oofa.txt ; GET a single file
get oofa.* ; GET multiple files
However, the mechanism for including an "as-name" has changed.
Previously, in order to include an as-name, you were required to use
the "multiline" form of GET:
get
remote-filespec
local-name
This was because the remote filespec might contain spaces, and so
there would be no good way of telling where it ended and where the
local name began, e.g:
get profile exec a foo
But now since we can use {braces} for grouping, we don't need the
multiline GET form any more, and in fact, support for it has been
removed. If you give a GET command by itself on a line, it fails and
an error message is printed. The new form is:
GET [ switches... ] remote-name [ local-name ]
Ask the server to send the file whose name is remote-name. If
the optional local-name is given, store it locally under this
name. If the remote-name or local-name contains spaces, they
must be enclosed in braces:
get {profile exec a} foo
get oofa.txt {~/My Files/Oofa text}
If you want to give a list of remote file specifications, use the MGET
command:
MGET [ switches... ] remote-name [ remote-name [ remote-name ... ] ]
Ask the server to send the files whose names are given.
Now you can also include modifier switches between GET or MGET and the
remote-name; most of the same switches as SEND:
/AS-NAME:text
Specifies "text" as the name to store the incoming file under.
(This switch is not available for MGET.) You can also still
specify the as-name as the second filename on the GET command
line. The following two commands are equivalent:
get oofa.txt oofa.new
get /as:oofa.new oofa.txt
/BINARY
Tells the server to send the given file(s) in binary mode
without affecting the global transfer mode. Example:
set file type text ; Set global transfer mode to text
get /binary oofa.zip ; get a file in binary mode
get oofa.txt ; This one is transferred in text mode
Or, perhaps more to the point:
get /binary foo.txt ; where "*.txt" is a text-pattern
This has the expected effect only if the server is C-Kermit 7.0
or later or K95 1.1.19 or later.
/COMMAND
GET /COMMAND is equivalent to CGET ([490]Section 4.2.2) -- it
says to receive the file into the standard input of a command,
rather than saving it on disk. The /AS-NAME or the second
"filename" on the GET command line is interpreted as the name
of a command. Examples:
get /command sunday.txt {grep Sunday oofa.txt}
get /command /as-name:{grep Sunday oofa.txt} sunday.txt
get /bin /command {!gunzip -c | tar xf -} {tar cf - . | gzip -c}
/DELETE
Asks the Kermit server to delete the file (or each file in the
group) after it has been transferred successfully (but not to
delete it if it was not sent successfully). GET /DELETE is
equivalent to RETRIEVE. Example:
get /delete *.log
/EXCEPT:pattern
Specifies that any files whose names match the pattern, which
can be a regular filename, or may contain "*" and/or "?"
metacharacters, are to be refused upon arrival. To specify
multiple patterns (up to 8), use outer braces around the group,
and inner braces around each pattern:
/EXCEPT:{{pattern1}{pattern2}...}
See the description of SEND /EXCEPT in [491]Section 4.7.1 for
examples, etc. Refusal is accomplished using the Attribute
Rejection mechanism (reason "name"), which works only when
Attribute packets have been successfully negotiated.
/FILENAMES:{CONVERTED,LITERAL}
Use this switch to override the current global SET FILE NAMES
setting for this transfer only.
/FILTER:command
This specifies a filter to pass the incoming file through
before writing to disk. See the [492]section on file-transfer
pipes and filters. The /FILTER switch applies only to the
file-transfer command it is given with; it does not affect the
global RECEIVE FILTER setting, if any.
/IMAGE
VMS: Transfer in image mode. Non-VMS: same as /BINARY.
/LABELED
VMS and OS/2 only: Specifies labeled transfer mode.
/MOVE-TO:directory
This tells C-Kermit to move each file that is successfully
received to the given directory. Files that are not
successfully received are not moved. By default, files are not
moved.
/PATHNAMES:{OFF,ABSOLUTE,RELATIVE,AUTO}
Use this switch to override the current global SET RECEIVE
PATHNAMES setting for this transfer only. /PATHNAMES:ABSOLUTE
or RELATIVE also sets /FILENAMES:LITERAL (also for this
transfer only) since incoming pathnames would not be treated as
pathnames otherwise. See [493]Section 4.10.
/QUIET
When sending in local mode, this suppresses the file-transfer
display.
/RECOVER
Used to recover from a previously interrupted transfer; GET
/RECOVER is equivalent to REGET. Recovery only works in binary
mode; SEND /RECOVER and RESEND include an implied /BINARY
switch. Even then, recovery will successful only if (a) the
original (interrupted) transfer was also in binary mode, or (b)
if it was in text mode, the two Kermit programs run on
platforms where text-mode transfers are not length-changing.
/RECURSIVE
Tells the server that the GET file specification applies
recursively. This switch also automatically sets
/PATHNAMES:RELATIVE in both the server AND the client. When
used in conjunction with /DELETE, this "moves" a directory tree
from the server's computer to the client's computer (except
that only regular files are deleted from the server's computer,
not directories; thus the original directories will be left,
but will contain no files). Note that all servers that support
/RECURSIVE do not necessarily do so in combination with other
switches, such as /RECOVER. (Servers that do include C-Kermit
7.0 and later, K95 1.1.19 and later.)
/RENAME-TO:string
This tells C-Kermit to rename each file that is successfully
received to the given string. Files that are not successfully
received are not renamed. By default, files are not renamed.
The string can be a literal string, which is appropriate when
only one file is being received, or it can contain one or more
variables that are to be evaluated at the time each file is
received, such as \v(filename), \v(filenumber), \v(ntime),
\v(pid), \v(user), etc. WARNING: if you give a literal string
and more than one file arrives, each incoming file will be
given the same name (but SET FILE COLLISION BACKUP or RENAME
can be used to keep the incoming files from overwriting each
other).
/TEXT
Tells the server to perform this transfer in text mode without
affecting its global transfer mode. See /BINARY for additional
info.
The /MAIL and /PRINT options are not available (as they are for SEND),
but you can use /COMMAND to achieve the same effect, as in these UNIX
examples:
get /command oofa.txt {mail kermit@columbia.edu}
get /command oofa.txt lpr
In OS/2 or Windows, you can GET and print like this:
get oofa.txt prn
The CGET, REGET, RETRIEVE commands also accept the same switches as
GET. CGET automatically sets /COMMAND; REGET automatically sets
/RECOVER and /BINARY, and RETRIEVE automatically sets /DELETE.
_________________________________________________________________
4.7.3. RECEIVE Command Switches
Without switches, the RECEIVE command still works as before:
receive ; Receives files under their own names
receive /tmp ; Ditto, but into the /tmp directory
r ; Same as "receive"
receive foo.txt ; Receives a file and renames to foo.txt
Now you can also include modifier switches may be included between
"receive" and the as-name; most of the same switches as GET:
/AS-NAME:text
Specifies "text" as the name to store the incoming file under.
You can also still specify the as-name as a filename on the
command line. The following two commands are equivalent:
r oofa.new
r /as:oofa.new
/BINARY
Performs this transfer in binary mode without affecting the
global transfer mode. NOTE: This does not override the incoming
filetype (as it does with GET), so this switch is useful only
if ATTRIBUTE TYPE is OFF, or if the other Kermit does not send
a TYPE (text or binary) attribute. In any case, it has no
affect whatsoever on the file sender.
/COMMAND
RECEIVE /COMMAND is equivalent to CRECEIVE ([494]Section 4.2.2)
-- it says to receive the file into the standard input of a
command, rather than saving it on disk. The /AS-NAME or the
"filename" on the RECEIVE command line is interpreted as the
name of a command.
r /command {grep Sunday oofa.txt}
r /command /as-name:{grep Sunday oofa.txt}
r /bin /command {tar cf - . | gzip -c}
/EXCEPT:pattern
Specifies that any files whose names match the pattern, which
can be a regular filename, or may contain "*" and/or "?"
metacharacters, are to be refused upon arrival. To specify
multiple patterns (up to 8), use outer braces around the group,
and inner braces around each pattern:
/EXCEPT:{{pattern1}{pattern2}...}
See the description of SEND /EXCEPT in [495]Section 4.7.1 for
examples, etc. Refusal is accomplished using the Attribute
Rejection mechanism (reason "name"), which works only when
Attribute packets have been successfully negotiated.
/FILENAMES:{CONVERTED,LITERAL}
Use this switch to override the current global SET FILE NAMES
setting for this transfer only.
/FILTER:command
This specifies a filter to pass the incoming file through
before writing to disk. See the [496]section on file-transfer
pipes and filters. The /FILTER switch applies only to the
file-transfer command it is given with; it does not affect the
global RECEIVE FILTER setting, if any.
/IMAGE
VMS: Transfer in image mode. Non-VMS: same as /BINARY. See
comments under RECEIVE /BINARY.
/LABELED
VMS and OS/2 only: Specifies labeled transfer mode. See
comments under RECEIVE /BINARY.
/MOVE-TO:directory
This tells C-Kermit to move each file that is successfully
received to the given directory. Files that are not
successfully received are not moved. By default, files are not
moved.
/PATHNAMES:{ABSOLUTE,RELATIVE,OFF,AUTO}
Use this switch to override the current global SET RECEIVE
PATHNAMES setting for this transfer only. See [497]Section
4.10.
/RECURSIVE
When used with the RECEIVE command, /RECURSIVE is simply a
synonym for /PATHNAMES:RELATIVE.
/RENAME-TO:string
This tells C-Kermit to rename each file that is successfully
received to the given string. Files that are not successfully
received are not renamed. By default, files are not renamed.
The string can be a literal string, which is appropriate when
only one file is being received, or it can contain one or more
variables that are to be evaluated at the time each file is
received, such as \v(filename), \v(filenumber), \v(ntime),
\v(pid), \v(user), etc. WARNING: if you give a literal string
and more than one file arrives, each incoming file will be
given the same name (but SET FILE COLLISION BACKUP or RENAME
can be used to keep the incoming files from overwriting each
other).
/QUIET
When receiving in local mode, this suppresses the file-transfer
display.
/TEXT
Receives in text mode without affecting the global transfer
mode. See comments under RECEIVE /BINARY.
The /MAIL and /PRINT options are not available, but you can use
/COMMAND to achieve the same effect, as in these UNIX examples:
r /command {mail kermit@columbia.edu}
r /command lpr
In OS/2 or Windows, you can RECEIVE and print like this:
receive prn
The CRECEIVE command now also accepts the same switches.
_________________________________________________________________
4.8. Minor Kermit Protocol Improvements
4.8.1. Multiple Attribute Packets
C-Kermit 7.0 now sends more than one Attribute packet if a file's
attributes do not fit into a single packet of the negotiated length.
If a particular attribute (such as file creation date-time) does not
fit within the negotiated length (which will only happen when the
negotiated length is around 20 or less), that attribute is not sent at
all.
4.8.2. Very Short Packets
There are certain situations where extremely short packets must be
used; 20 or 30 bytes at most. This can happen when one or more devices
along the communication path have very small buffers and lack an
effective means of flow control. Examples are sometimes cited
involving radio modems.
When the maximum packet length is shorter than certain packets that
would be sent, those packets are either truncated or else broken up
into multiple packets. Specifically:
1. Parameter negotiation packets (I, S, and their ACKs) are truncated
to the negotiated length. Any parameters that do not fit are reset
to their default values. There is no provision in the Kermit
protocol for fragmentation and reassembly of parameter strings.
2. File header packets (containing the filename) are simply
truncated. There is no provision in the Kermit protocol for
fragmentation and reassembly of filenames.
3. Attribute packets are fragmented and reassembled as described in
4.8.1 without loss of data, except in case a field will not fit at
all in the negotiated length (the longest attribute is usually the
date and time of file creation/modification) because of the rule
that attributes may not be broken across packets.
4. Data packets and other packets are unaffected -- they can be as
short as they need to be, within reason.
_________________________________________________________________
4.9. Wildcard / File Group Expansion
"Wildcard" refers to the notation used in filenames to specify a group
of files by pattern matching.
4.9.1. In UNIX C-Kermit
Prior to C-Kermit 7.0, C-Kermit was capable of expanding wildcard
strings containing only the "metacharacters" '*' and '?':
*
Matches any sequence of zero or more characters. For example:
"ck*.c" matches all files whose names start with "ck" and end
with ".c", including "ck.c".
?
Matches any single character. For example, "ck?.c" matches all
files whose names are exactly 5 characters long and start with
"ck" and end with ".c". When typing commands at the prompt, you
must precede any question mark to be used for matching by a
backslash (\) to override the normal function of question mark,
which is providing menus and file lists.
C-Kermit 7.0 adds the additional features that users of ksh, csh, and
bash are accustomed to:
[abc]
Square brackets enclosing a list of characters matches any
single character in the list. Example: ckuusr.[ch] matches
ckuusr.c and ckuusr.h.
[a-z]
Square brackets enclosing a range of characters; the hyphen
separates the low and high elements of the range. For example,
[a-z] matches any character from a to z.
[acdm-z]
Lists and ranges may be combined. This example matches a, c, d,
or m through z.
{string1,string2,...}
Braces enclose a list of strings to be matched. For example:
ck{ufio,vcon,cmai}.c matches ckufio.c, ckvcon.c, or ckcmai.c.
The strings may themselves contain metacharacters, bracket
lists, or indeed, other lists of strings, but (when matching
filenames) they may not contain directory separators.
Thus, the metacharacters in filenames (and in any other field
that can be a pattern, such as the IF MATCH pattern, SEND or
GET exception lists, etc) are:
* ? [ {
And within braces only, comma (,) is a metacharacter.
To include a metacharacter in a pattern literally, precede it with a
backslash '\' (or two if you are passing the pattern to a macro).
Examples:
send a*b ; Send all files whose names start with 'a' and end with 'b'.
send a?b ; Ditto, but the name must be exactly three characters long.
send a[a-z]b ; Ditto, but the second character must be a lowercase letter.
send a[x\-z]b ; Ditto, except the second character must be 'x', '-', or 'y'.
send a[ghi]b ; Ditto, except the second character must be 'g', 'h', or 'i'.
send a[?*]b ; Ditto, except the second character must be '?' or '*'.
send a[\?\*]b ; Same as previous.
send *?[a-z]* ; All files with names containing at least one character
; that is followed by a lowercase letter.
Or, more practically:
send ck[cuw]*.[cwh] ; Send the UNIX C-Kermit source files.
To refer to the C-Kermit sources files and makefile all in one
filespec:
{{makefile,ck[cuw]*.[cwh]}}
(NOTE: if the entire pattern is a {stringlist}, you must enclose it it
TWO pairs of braces, since the SEND command strips the outer brace
pair, because of the "enclose in braces if the filename contains
spaces" rule).
If the makefile is called ckuker.mak:
ck[cuw]*.{[cwh],mak}
(NOTE: double braces are not needed here since the pattern does not
both begin and end with a brace.)
To add in all the C-Kermit text files:
ck[cuw]*.{[cwh],mak,txt}
All of these features can be used anywhere you would type a filename
that is allowed to contain wildcards.
When you are typing at the command prompt, an extra level of quoting
is required for the '?' character to defeat its regular function of
producing a list of files that match what you have typed so far, for
example:
send ck[cu]?
lists all the files whose names start with ckc and cku. If you quote
the question mark, it is used as a pattern-matching character, for
example:
send ck\?[ft]io.c
sends all the file and communications i/o modules for all the
platforms: ckufio.c, ckutio.c, ckvfio.c, ckvtio.c, etc.
If, however, a filename actually contains a question mark and you need
to refer to it on the command line, you must use three (3)
backslashes. For example, if the file is actually called ck?fio.c, you
would use:
send ck\\\?fio.c
Further notes on quoting:
* A single backslash is sufficient for quoting a special character
at the command prompt or in a command file. However, when passing
patterns to macros you'll need double backslashes, and when
referring to these patterns within the macro, you'll need to use
\fcontents(\%1) (see [498]Section 1.11.5). You should enclose
macro argument references in braces in case grouped arguments were
passed. Example:
define ismatch {
if match {\fcont(\%1)} {\fcont(\%2)} {
end 0 MATCH
} else {
end 1 NO MATCH
}
}
ismatch ab*yz a*\\**z ; Backslash must be doubled
ismatch {abc def xyz} *b*e*y* ; Braces must be used for grouping
* Watch out for possible conflicts between {} in filename patterns
and {} used for grouping multiple words into a single field, when
the pattern has outer braces. For example, in:
if match {abc xyz} {a* *z} echo THEY MATCH
braces must be used to group "abc xyz" into a single string.
Kermit strips off the braces before comparing the string with the
pattern. Therefore:
if match makefile {makefile,Makefile} echo THEY MATCH
does not work, but:
if match makefile {{makefile,Makefile}} echo THEY MATCH
does.
* If you use a pattern that has outer braces, like {*.txt,*.doc}, in
a field that accepts a pattern list (like SEND /EXCEPT:xxx),
you'll need to add two extra sets of outer braces:
send /except:{{{*.txt,*.doc}}} *.*
C-Kermit's new pattern matching capabilities are also used when
C-Kermit is in server mode, so now you can send requests such as:
get ck[cuw]*.[cwh]
to a C-Kermit server without having to tell it to SET WILD SHELL
first. Previously this would have required:
mget ckc*.c ckc*.w ckc*.h cku*.c cku*.w cku*.h ckw*.c ckw*.w ckw*.h
The new pattern matching features make SET WILD SHELL redundant, and
barring any objections, it will eventually be phased out. (One
possible reason for retaining it would be as an escape mechanism when
Kermit does not understand the underlying file system.)
By the way, patterns such as these are sometimes referred to as
"regular expressions", but they are not quite the same. In a true
regular expression (for example), "*" means "zero or more repetitions
of the previous item", so (for example), "([0-9]*)" would match zero
or more digits in parentheses. In Kermit (and in most shells), this
matches one digit followed by zero or more characters, within
parentheses. Here are some hints:
* Although you can't match any sequence of digits (or letters, etc),
you can match (say) 1, 2, or 3 of them in row. For example, the
following pattern matches Kermit backup files (with backup numbers
from 1 to 999):
*.~{[1-9],[1-9][0-9],[1-9][0-9][0-9]}~
* There is presently no NOT operator, so no way to match any
character or string EXCEPT the one(s) shown.
In other wildcarding news...
* You may now "send xxx" where "xxx" is a directory name, and this
will send all the files from the directory xxx, as if you had
typed "send xxx/*". You can also use the special shorthand "send
." to send all the files from the current directory.
* To easily skip over backup files (the ones whose names end like
.~22~) when sending, you can use SEND /NOBACKUP (see [499]Section
4.0.6 for details).
* When choosing Kermit to expand wildcards, rather than the shell,
you can choose whether "dot files" -- files whose names begin with
".", which are normally "invisible" -- should be matched:
SET WILD KERMIT /NO-MATCH-DOT-FILES (this is the default)
SET WILD KERMIT /MATCH-DOT-FILES (this allows matching of "." files)
or include the /DOTFILES or /NODOTFILES switch on the command you
are using, such as SEND or DIRECTORY.
* Commands such as DIRECTORY and SEND allow recursive directory
traversal. There are also new functions for this to use in
scripts. See [500]Section 4.11 for details.
When building file lists in UNIX, C-Kermit follows symbolic links.
Because of this, you might encounter any or all of the following
phenomena:
* Multiple copies of the same file; e.g. one from its real directory
and others from links to its real directory, if both the real
directory and the links to it are in the wildcard expansion list.
* A command might unexpectedly "hang" for a long time because an NFS
link might not be responding, or the directory you are looking at
contains a link to a huge directory tree (example: "directory
/recursive /etc" when /etc/spool is a symlink to /var/spool, which
is a large organization's incoming email directory, containing
tens of thousands of subdirectories).
The size of the file list that Kermit can build is limited in most
C-Kermit implementations. The limit, if any, depends on the
implementation. Use the SHOW FEATURES command and look in the
alphabetized options list for MAXWLD to see the value.
4.9.2. In Kermit 95
Kermit 95 1.1.19 and later uses the same pattern matching syntax as in
UNIX, but (as always) you will encounter numerous difficulties if you
use backslash (\) as the directory separator. In any command where K95
parses filenames itself (that is, practically any file-oriented
command except RUN), you can use forward slash (/) as the directory
separator to avoid all the nasty conflicts.
4.9.3. In VMS, AOS/VS, OS-9, VOS, etc.
Platforms other than UNIX, Windows 95/98/NT, and OS/2 have their own
filename matching capabilities that are, in general, different from
Kermit's built-in ones and in any case might conflict with them. For
example, [] encloses directory names in VMS.
Nevertheless you can still use all the pattern-matching capabilities
described in [501]Section 4.9.1 by loading a file list into an array
(e.g. with \ffiles(*,&a), see [502]Section 4.11.3) and then using IF
MATCH on the members.
_________________________________________________________________
4.10. Additional Pathname Controls
In version 6.0 and earlier, C-Kermit's SET { SEND, RECEIVE } PATHNAMES
command had only ON and OFF as options. In version 7.0, there are more
choices:
SET SEND PATHNAMES OFF
When sending a file, strip all disk/directory information from
the name. Example: "send /usr/olga/letters/oofa.txt" sends the
file as "oofa.txt". This applies to actual filenames, not to
any as-name you might specify.
SET SEND PATHNAMES RELATIVE
When sending a file, leave the pathname on as given. For
example, if your current directory is /usr/olga, "send
letters/oofa.txt" sends the file as "letters/oofa.txt", not
"/usr/olga/letters/oofa.txt" or "letters.txt".
SET SEND PATHNAMES ABSOLUTE
When sending a file, convert its name to the full, absolute
local pathname. For example, if your current directory is
/usr/olga, "send letters/oofa.txt" sends the file as
"/usr/olga/letters/oofa.txt". NOTE: Even with this setting,
device and/or node names are not included. For example, in VMS,
any node or device name is stripped; in Windows or OS/2, any
disk letter is stripped.
SET RECEIVE PATHNAMES OFF
When receiving a file, strip all disk/directory information
from the name before attempting to store it. This applies to
incoming filename, not to any as-name you might specify.
Example: If a file arrives under the name
"/usr/olga/letters/oofa.txt" it is stored simply as "oofa.txt"
in your download directory or, if no download directory has
been specified, in your current directory.
SET RECEIVE PATHNAMES RELATIVE
When receiving a file, leave the pathname on as it appears in
the incoming name, but if the incoming name appears to be
absolute, make it relative to your current or download
directory. Examples:
+ "oofa.txt" is stored as "oofa.txt".
+ "letters/oofa.txt" is stored as "letters/oofa.txt"; the
"letters" subdirectory is created if it does not already
exist.
+ "/usr/olga/letters/oofa.txt" is stored as
"usr/olga/letters/oofa.txt" in your current or download
directory, and the "usr", "usr/olga", etc, directories are
created if they do not exist.
SET RECEIVE PATHNAMES ABSOLUTE
The incoming filename is used as given. Thus it cannot be
stored unless the given path (if any) already exists or can be
created. In this case, node, device, or disk designations are
NOT stripped, since they most likely were given explicitly by
the user as an as-name, meant to be used as given.
SET RECEIVE PATHNAMES AUTO
This is the default, and means RELATIVE if the sender tells me
it is a recursive transfer, OFF otherwise.
Set FILE NAMES CONVERTED now also affects pathnames too. When
PATHNAMES are RELATIVE or ABSOLUTE and FILE NAMES are CONVERTED, the
file sender converts its native directory-name format to UNIX format,
and the file receiver converts from UNIX format to its native one;
thus UNIX format is the common intermediate representation for
directory hierarchies, as it is in the ZIP/UNZIP programs (which is
why ZIP archives are transportable among, UNIX, DOS, and VMS).
Here's an example in which a file is sent from Windows to UNIX with
relative pathnames and FILE NAMES CONVERTED:
Source name Intermediate name Destination Name
C:\K95\TMP\OOFA.TXT K95/TMP/OOFA.TXT k95/tmp/oofa.txt
In a more complicated example, we send the same file from Windows to
VMS:
Source name Intermediate name Destination Name
C:\K95\TMP\OOFA.TXT K95/TMP/OOFA.TXT [.K95.TMP]OOFA.TXT
(Note that disk letters and device designations are always stripped
when pathnames are relative).
As you can imagine, as more and more directory formats are considered,
this approach keeps matters simple: on each platform, Kermit must know
only its own local format and the common intermediate one. In most
cases, the receiver can detect which format is used automatically.
_________________________________________________________________
4.11. Recursive SEND and GET: Transferring Directory Trees
C-Kermit 7.0 in selected versions (UNIX, VMS, VOS, AOS/VS, Windows,
and OS/2 at this writing) now permits the SEND command to traverse
directories "recursively" if you ask it to; that is, to send files
from the current or specified directory and all of its subdirectories
too, and their subdirectories, etc. (Some other commands can do this
too, including DIRECTORY.)
This feature is new to UNIX, Windows, VOS, and OS/2. VMS and AOS/VS
have always included "wildcard" or "template" characters that allow
this, and in this case, recursive directory traversal could happen
behind Kermit's back, i.e. Kermit does not have to do it itself (in
VMS, the notation is "[...]" or "[directory...]"; in AOS/VS is "#").
In C-Kermit 7.0, however, SEND /RECURSIVE is supported by C-Kermit
itself for VMS.
_________________________________________________________________
4.11.1. Command-Line Options
To descend a directory tree when sending files, use the -L
command-line option to indicate that the send operation is to be
recursive, and include a name or pattern to be sent. When giving a
pattern, you should enclose it in quotes to prevent the shell from
expanding it. Examples:
$ kermit -Ls "/usr/olga/*" # send all of Olga's files in all her directories
$ kermit -Ls foo.txt # send all foo.txt files in this directory tree
$ kermit -Ls "*.txt" # send all .txt files in this directory tree
$ kermit -Ls "letters/*" # send all files in the letters directory tree
$ kermit -Ls letters # send all files in the letters directory tree
$ kermit -Ls "*" # send all files in this directory tree
$ kermit -Ls . # UNIX only: send all files in this directory tree
$ kermit -s . # UNIX only: a filename of . implies -L
If you let the shell expand wildcards, Kermit only sends files whose
names match files in the current or given directory, because the shell
replaces an unquoted wildcard expression with the list of matching
files -- and the shell does not build recursive lists. Note that the
"." notation for the tree rooted at the current directory is allowed
only in UNIX, since in Windows and OS/2, it means "*.*"
(nonrecursive).
_________________________________________________________________
4.11.2. The SEND /RECURSIVE Command
If you include the /RECURSIVE switch in a SEND (or MOVE, or similar)
command, it means to descend the current or specified directory tree
searching for files whose names match the given name or pattern. Since
this is not terribly useful unless you also include pathnames with the
outbound files, the /RECURSIVE switch also includes an implicit
/PATHNAMES:RELATIVE switch (which you can undo by including an
explicit /PATHNAMES switch after the /RECURSIVE switch).
Examples:
SEND /RECURSIVE *
Sends all of the files in the current directory and all the
files in all of its subdirectories, and all of their
subdirectories, etc, including their relative pathnames. Empty
directories are not sent.
SEND /RECURSIVE /PATHNAMES:ABSOLUTE *
Sends all of the files in the current directory and all the
files in all of its subdirectories, and all of their
subdirectories, etc, including their absolute pathnames.
SEND /RECURSIVE /PATHNAMES:OFF *
Sends all of the files in the current directory and all the
files in all of its subdirectories, and all of their
subdirectories, etc, without pathnames.
SEND /RECURSIVE /usr/olga/*
Sends all of the files in the /usr/olga directory and all the
files in all of its subdirectories, and all of their
subdirectories, etc.
SEND /RECURSIVE /usr/olga (or /usr/olga/)
Same as above. If the name is a directory name (with or without
a trailing slash), its files are sent, and those of its
subdirectories, and their subdirectories, etc (see [503]Section
4.9).
SEND /RECURSIVE /TEXT /usr/olga/*.txt
As above, but only files whose names end with ".txt" are sent,
and they are sent in text mode (as they would be by default
anyway if SET FILE PATTERNS is ON or AUTO).
SEND .
UNIX only: Send all the files in the current directory.
SEND /RECURSIVE .
UNIX only: Sends all of the files in the current directory and
all of its subdirectories, etc ([504]Section 4.9).
The /RECURSIVE switch is different from most other switches in that
its effect is immediate (but still local to the command in which it is
given), because it determines how filenames are to be parsed. For
example, "send *.txt" fails with a parse error ("No files match") if
there are no *.txt files in the current directory, but "send
/recursive *.txt" succeeds if there are ".txt" files anywhere in the
tree rooted at the current directory.
The /RECURSIVE switch also affects the file lists displayed if you
type "?" in a filename field. "send ./?" lists the regular files in
the current directory, but "send /recursive ./?" lists the entire
directory tree rooted at the current directory.
_________________________________________________________________
4.11.3. The GET /RECURSIVE Command
In a client/server setting, the client can also request a recursive
transfer with:
GET /RECURSIVE [ other switches ] remote-filespec [ local-spec ]
In which remote file specification can be a directory name, a
filename, a wildcard, or any combination. If the local-spec is not
given (and PATHNAMES are RELATIVE), incoming files and directories go
into the current local directory. If local-spec is given and is a
directory, it becomes the root of the tree into which the incoming
files and directories are placed. If local-spec has the syntax of a
directory name (e.g. in UNIX it ends with /), C-Kermit creates the
directory and then places the incoming files into it. If local-spec is
a filename (not recommended), then all incoming files are stored with
that name with collisions handled according to the FILE COLLISION
setting.
Again, the normal method for transferring directory trees uses
relative pathnames, and this is the default when the sender has been
given the /RECURSIVE switch. The action at the receiver depends on its
RECEIVE PATHNAMES setting. The default is AUTO, meaning that if the
sender tells it to expect a recursive transfer, then it should
automatically switch to relative pathnames for this transfer only;
otherwise it obeys the RECEIVE PATHNAMES setting of OFF, ABSOLUTE, or
RELATIVE.
What happens if a file arrives that has an absolute pathname, when the
receiver has been told to use only relative pathnames? As a security
precaution, in this case the receiver treats the name as if it was
relative. For example, if a file arrives as:
/usr/olga/oofa.txt
The receiver creates a "usr" subdirectory in its current directory,
and then an "olga" subdirectory under the "usr" subdirectory in which
to store the incoming file.
Suppose, however there is a sequence of directories:
/usr/olga/a/b/c/d/
in which "a" contains nothing but a subdirectory "b", which in turn
contains nothing but a subdirectory "c", which in turn contains
nothing but a subdirectory "d", which contains nothing at all. Thus
there are no files in the "/usr/olga/a/" tree, and so it is not sent,
and therefore it is not reproduced on the target computer.
_________________________________________________________________
4.11.4. New and Changed File Functions
C-Kermit 7.0 adds the following functions:
\ffiles(pattern[,&a])
This function has been changed to match only regular files in
the current or given directory, and to take an optional array
name as a second argument (explained below).
\fdirectories(pattern[,&a])
Returns the number of directories that match the given pattern.
If the pattern does not include a directory, then the search is
performed in the current directory.
\frfiles(pattern[,&a])
Returns the number of files in the current or given directory
and all of its subdirectories, and their subdirectories, etc,
that match the given pattern. Warning -- this one can take
quite some time if performed at the root of a large directory
tree.
\frdirectories(pattern[,&a])
Returns the number of directories in the current or given
directory and all of its subdirectories, and their
subdirectories, etc, that match the given pattern.
Each of these functions builds up a list of files to be returned by
the \fnextfile() function, just as \ffiles() always has done. (This
can also be done with the /ARRAY switch of the DIRECTORY command; see
[505]Sections 4.5.1 and [506]7.10).
Each of these functions can be given an array name as an optional
second argument. If an array name is supplied, the array will contain
the number of files as its 0th element, and the filenames in elements
1 through last. If the array already existed, its previous contents
are lost. For example, if the current directory contains two files,
oofa.txt and foo.bar, then "\ffiles(*,&a)" creates an array \&a[] with
a dimension of 2, containing the following elements:
\&a[0] = 2
\&a[1] = oofa.txt
\&a[2] = foo.bar
If no files match the specification given in the first argument, the
array gets a dimension of 0, which is the same as undeclaring the
array.
Note that the order in which the array is filled (and in which
\fnextfile() returns filenames) is indeterminate (but see [507]Section
7.10.5).
Here's an example that builds and prints a list of all the file whose
names end in .txt in the current directory and all its descendents:
asg \%n \frfiles(*.txt)
declare \&a[\%n]
for \%i 1 \%n 1 {
asg \&a[\%i] \fnextfile()
echo \flpad(\%i,4). "\&a[\%i]"
}
Alternatively, using the array method, and then printing the filenames
in alphabetic order (see [508]Section 7.10.3 and [509]7.10.5):
asg \%n \frfiles(*.txt,&a)
sort &a
for \%i 1 \%n 1 {
echo \flpad(\%i,4). "\&a[\%i]"
}
Or even more simply:
asg \%n \frfiles(*.txt,&a)
sort &a
show array &a
As noted elsewhere, the file lists built by \ffiles(), \frfiles(),
etc, are now "safe" in the sense that SEND and other file-related
commands can reference \fnextfile() without resetting the list:
set send pathnames relative
for \%i 1 \frfiles(*.txt) 1 {
asg \%a \fnextfile()
echo Sending \%a...
send \%a
if fail break
}
Copying to an array (as shown on p.398 of [510]Using C-Kermit 2nd Ed)
is no longer necessary.
_________________________________________________________________
4.11.5. Moving Directory Trees Between Like Systems
4.11.5.1. UNIX to UNIX
Transferring a directory tree from one computer to another replicates
the file sender's arrangement of files and directories on the file
receiver's computer. Normally this is done using relative pathnames,
since the user IDs might not be identical on the two computers. Let's
say both computers are UNIX based, running C-Kermit 7.0 or later. On
the sending computer (leaving out the connection details, etc):
C-Kermit> cd /usr/olga
C-Kermit> send /recursive .
The /RECURSIVE switch tells C-Kermit to descend through the directory
tree and to include relative pathnames on outbound filenames.
On the receiving computer:
C-Kermit> mkdir olgas-files ; Make a new directory.
C-Kermit> cd olgas-files ; CD to it.
C-Kermit> receive /recursive ; = /PATHNAMES:RELATIVE
Each Kermit program recognizes that the other is running under UNIX
and switches to binary mode and literal filenames automatically.
Directories are automatically created on the receiving system as
needed. File dates and permissions are automatically reproduced from
source to destination.
4.11.5.2. VMS to VMS
To send recursively from VMS, simply include the /RECURSIVE switch,
for example at the sender:
$ kermit
C-Kermit> cd [olga]
C-Kermit> send /recursive *.*;0
And at the receiver:
C-Kermit> cd [.olga]
C-Kermit> receive /recursive
The notation "..." within directory brackets in VMS means "this
directory and all directories below it"; the /RECURSIVE switch, when
given to the sender, implies the use of "..." in the file
specification so you don't have to include "..."; but it makes no
difference if you do:
$ kermit
C-Kermit> send /recursive [olga...]*.*;0
And at the receiver:
C-Kermit> cd [.olga]
C-Kermit> receive /recursive
In either case, since both systems recognize each other as VMS, they
switch into LABELED transfer mode automatically.
_________________________________________________________________
4.11.6. Moving Directory Trees Between Unlike Systems
There are several difficulties with recursive transfers between unlike
systems:
* File formats can be different, especially text files character
sets and record formats. This can now be handled by using SET FILE
PATTERN, SET FILE TEXT-PATTERNS, and SET FILE BINARY-PATTERNS
([511]Section 4.3).
* File naming conventions are different. For example, one system
might allow (and use) longer filenames than the other. You can
tell Kermit how to handle file names with the normal "set file
names" and "set file collision" mechanisms. Most modern Kermits
are fairly tolerant of illegal filenames and should not fail
simply because of an incoming filename; rather, it will do its
best to convert it to a recognizable and unique legal filename.
* Directory notations can be different, e.g. backslashes instead of
slashes, brackets, parentheses, spaces, etc. But this is now
handled by converting pathnames to a standard format during
transfer ([512]Section 4.10).
So now, for the first time, it is possible to send directory trees
among any combination of UNIX, DOS, Windows, OS/2, VMS, AOS/VS, etc.
Here's an example sending files from an HP-UX system (where text files
are encoded in the HP Roman8 character set) to a PC with K95 (where
text files are encoded in CP850):
Sender:
cd xxx ; CD to root of source tree
set file type binary ; Default transfer mode
set file character-set hp-roman8 ; Local character set for text files
set xfer character-set latin1 ; Transfer character set
set file patterns on ; Enable automatic file-type switching...
set file binary-patterns *.Z *.gz *.o ; based on these patterns...
set file text-patterns *.txt *.c *.h ; for binary and text files.
send /recursive * ; Send all the file in this directory tree
Receiver:
cd yyy ; CD to root of destination tree
set file character-set cp850 ; Local character set for text files
receive /pathnames:relative ; Receive with pathnames
Notes:
* Replace "xxx" and "yyy" with the desired directories.
* Replace the file character sets appropriately.
* Change the patterns as needed (or just use the built-in default
lists).
* SEND /RECURSIVE also implies /PATHNAMES:RELATIVE.
* The file sender tells the file receiver the transfer mode of each
file.
* The file sender tells the file receiver the transfer character
set.
* By default, destination file dates will be the same as on the
source.
* Many of the settings shown might already be set by default.
* See [513]Sections 4.3, [514]4.10, and [515]4.15 for additional
explanation.
If you are refreshing an existing directory on the destination
computer, use "set file collision update" or other appropriate file
collision option to handle filename collisions.
_________________________________________________________________
4.12. Where Did My File Go?
Now that Kermit can be started by clicking on desktop icons (thus
obscuring the concept of "current directory"), and can have a download
directory, and can create directories for incoming files on the fly,
etc, sometimes it is easy to lose a file after transfer. Of course, if
you keep a transaction log:
LOG TRANSACTIONS
it will record the fate and final resting place of each file. But in
case you did not keep a log, the new command:
WHERE
added in C-Kermit 7.0, gives you as much information as it has about
the location of the last files transferred, including the pathname
reported by the receiving Kermit, if any, when C-Kermit is the sender.
This information was also added to SHOW FILE in somewhat less detail.
_________________________________________________________________
4.13. File Output Buffer Control
(UNIX only). The new command SET FILE OUTPUT lets you control how
incoming files are written to disk:
SET FILE OUTPUT BUFFERED [ size ]
Chooses buffered file output; this is the default. UNIX does
its normal sort of disk buffering. The optional size specifies
Kermit's own file output buffer size, and therefore the
frequency of disk accesses (write() system calls) -- the bigger
the size, the fewer the disk accesses.
SET FILE OUTPUT UNBUFFERED [ size ]
This forces each file output write() call to actually commit
the data to disk immediately. Choosing this option will usually
slow file reception down.
SET FILE OUTPUT BLOCKING
Write() calls should not return until they are complete. This
is the normal setting, and it lets Kermit detect disk-write
errors immediately.
SET FILE OUTPUT NONBLOCKING
Write() calls should return immediately. This can speed up file
reception, but also delay the detection of disk-write errors.
Experimentation with these parameters should be harmless, and might
(or might not) have a perceptible, even dramatic, effect on
performance.
_________________________________________________________________
4.14. Improved Responsiveness
In version 7.0, C-Kermit's file-transfer protocol engine has been
tuned for additional speed and responsiveness.
* Binary-mode transfers over 8-bit connections, a very common case,
are now handled in a special way that minimizes overhead.
* SET TRANSFER CRC-CALCULATION is now OFF by default, rather than
ON. (This affects only the overall per-transfer CRC, \v(crc16),
not the per-packet CRCs)
* Connection loss during file transfer is now detected immediately
in most cases on Internet connections and on serial connections
when CARRIER-WATCH is not set to OFF.
_________________________________________________________________
4.15. Doubling and Ignoring Characters for Transparency
The following commands were added in 7.0, primarily to allow
successful file transfer through ARPAnet TACs and with Honeywell DPS6
systems, but can be used in any setting where they might be needed:
SET SEND DOUBLE-CHAR { [ char [ char [ ... ] ] ], NONE }
Tells C-Kermit to double the specified characters (use decimal
notation) in packets that it sends. For example, if you are
sending files through a device that uses @ as an escape
character, but allows you to send a single copy of @ through by
doubling it, use "set send double 64".
SET RECEIVE IGNORE-CHAR [ char [ char [ ... ] ] ]
Tells C-Kermit to ignore the specified character(s) in incoming
packets. Use this, for example, when something between the
sender and receiver is inserting linefeeds for wrapping, NULs
for padding, etc.
_________________________________________________________________
4.16. New File-Transfer Display Formats
SET TRANSFER DISPLAY { BRIEF, CRT, FULLSCREEN, NONE, SERIAL }
Selects the file-transfer display format.
BRIEF is the new one. This writes one line to the screen per file,
showing the file's name, transfer mode, size, the status of the
transfer, and when the transfer is successful, the effective data rate
in characters per second (CPS). Example:
SEND ckcfn3.o (binary) (59216 bytes): OK (0.104 sec, 570206 cps)
SEND ckcfns.o (binary) (114436 bytes): OK (0.148 sec, 772006 cps)
SEND ckcmai.c (text) (79147 bytes): OK (0.180 sec, 438543 cps)
SEND ckcmai.o (binary) (35396 bytes): OK (0.060 sec, 587494 cps)
SEND ckcnet.o (binary) (62772 bytes): REFUSED
SEND ckcpro.o (binary) (121448 bytes): OK (0.173 sec, 703928 cps)
SEND ckcpro.w (text) (63687 bytes): OK (0.141 sec, 453059 cps)
SEND makefile (text) (186636 bytes): OK (0.444 sec, 420471 cps)
SEND wermit (binary) (1064960 bytes): OK (2.207 sec, 482477 cps)
Note that transfer times are now obtained in fractional seconds,
rather than whole seconds, so the CPS figures are more accurate (the
display shows 3 decimal places, but internally the figure is generally
precise to the microsecond).
_________________________________________________________________
4.17. New Transaction Log Formats
The new command:
SET TRANSACTION-LOG { VERBOSE, FTP, BRIEF [ separator ] }
lets you choose the format of the transaction log. VERBOSE (the
default) indicates the traditional format described in the book. BRIEF
and FTP are new. This command must be given prior to the LOG
TRANSACTION command if a non-VERBOSE type is desired.
4.17.1. The BRIEF Format
BRIEF chooses a one-line per file format suitable for direct
importation into databases like Informix, Oracle, or Sybase, in which:
* Each record has 8 fields.
* Fields are separated by a non-alphanumeric separator character.
* The default separator character is comma (,).
* Any field containing the separator character is enclosed in
doublequotes.
* The final field is enclosed in doublequotes.
The fields are:
1. Date in yyyymmdd format
2. Time in hh:mm:ss format
3. Action: SEND or RECV
4. The local filename
5. The size of the file
6. The transfer mode (text, binary, image, labeled)
7. The status of the transfer: OK or FAILED
8. Additional status-dependent info, in doublequotes.
Examples:
20000208,12:08:52,RECV,/u/olga/oofa.txt,5246,text,OK,"0.284sec 18443cps"
20000208,12:09:31,SEND,/u/olga/oofa.exe,32768,binary,OK,"1.243sec 26362cps"
20000208,12:10:02,SEND,"/u/olga/a,b",10130,text,FAILED,"Refused: date"
Note how the filename is enclosed in doublequotes in the final
example, because it contains a comma.
To obtain BRIEF format, you must give the SET TRANSACTION-LOG BRIEF
command before the LOG TRANSACTIONS command. (If you give them in the
opposite order, a heading is written to the log by the LOG command.)
_________________________________________________________________
4.17.2. The FTP Format
SET TRANSACTION-LOG FTP (available only in UNIX) chooses a format that
is compatible with the WU-FTPD (Washington University FTP daemon) log,
and so can be processed by any software that processes the WU-FTPD
log. It logs only transfers in and out, both successful and failed
(but success or failure is not indicated, due to lack of a field in
the WU-FTPD log format for this purpose). Non-transfer events are not
recorded.
Unlike other logs, the FTP-format transaction log is opened in append
mode by default. This allows you to easily keep a record of all your
kermit transfers, and it also allows the same log to be shared by
multiple simultaneous Kermit processes or (permissions permitting)
users. You can, of course, force creation of a new logfile by
specifying the NEW keyword after the filename, e.g.
log transactions oofa.log new
All records in the FTP-style log are in a consistent format. The first
field is fixed-length and contains spaces; subsequent fields are
variable length, contain no spaces, and are separated by one or more
spaces. The fields are:
Timestamp
This is an asctime-style timestamp, example: "Wed Sep 16
20:19:05 1999" It is always exactly 24 characters long, and the
subfields are always in fixed positions.
Elapsed time
The whole number of seconds required to transfer the file, as a
string of decimal digits, e.g. "24".
Connection
The name of the network host to which C-Kermit is connected, or
the name of the serial device through which it has dialed (or
has a direct connection), or "/dev/tty" for transfers in remote
mode.
Bytes transferred
The number of bytes transferred, decimal digits, e.g.
"1537904".
Filename
The name of the file that was transferred, e.g.
"/pub/ftp/kermit/a/README.TXT". If the filename contains any
spaces or control characters, each such character is replaced
by an underscore ('_') character.
Mode
The letter 'b' if the file was transferred in binary mode, or
'a' if it was transferred in text (ASCII) mode.
Options
This field always contains an underscore ('_') character.
Direction
The letter 'o' if the file was transferred Out, and 'i' if the
file was transferred In.
User class
The letter 'r' indicates the file was transferred by a Real
user.
User identification
The ID of the user who transferred the file.
Server identification
The string "kermit". This distinguishes a Kermit transfer log
record from a WU-FTPD record, which contains "ftp" in this
field.
Authentication class
The digit '1' if we know the user's ID on the client system,
otherwise '0'. Currently, always '0'.
Authenticated user
If the authentication class is '1', this is the user's ID on
the client system. Otherwise it is an asterisk ('*'). Currently
it is always an asterisk.
Examples:
Thu Oct 22 17:42:48 1998 0 * 94 /usr/olga/new.x a _ i r olga kermit 0 *
Thu Oct 22 17:51:29 1998 1 * 147899 /usr/olga/test.c a _ o r olga kermit 0 *
Thu Oct 22 17:51:44 1998 1 * 235 /usr/olga/test.o b _ i r olga kermit 0 *
Fri Oct 23 12:10:25 1998 0 * 235 /usr/olga/x.ksc a _ o r olga kermit 0 *
Note that an ftp-format transaction log can also be selected on the
Kermit command line as follows:
kermit --xferfile:filespec
This is equivalent to:
SET TRANSACTION-LOG FTP
LOG TRANSACTIONS filespec APPEND
Conceivably it could be possible to have a system-wide shared Kermit
log, except that UNIX lacks any notion of an append-only file; thus
any user who could append to the log could also delete it (or alter
it). This problem could be worked around using setuid/setgid tricks,
but these would most likely interfere with the other setuid/setgid
tricks C-Kermit must use for getting at dialout devices and UUCP
logfiles.
_________________________________________________________________
4.18. Unprefixing NUL
As of 6.1.193 Alpha.10, C-Kermit can finally send and receive
file-transfer packets in which NUL (ASCII 0) is unprefixed (no more
NUL-terminated packets!). NUL is, of course, extremely prevalent in
binary files such as executables, and this has been a significant
source of packet overhead. For example, when transferring itself (the
SunOS C-Kermit executable) with minimal prefixing and 9000-byte
packets, we see:
File size: 1064960
Packet chars with 0 prefixed: 1199629 overhead = 12.65%
Packet chars with 0 unprefixed: 1062393 overhead = -0.03%
Transfer rates go up accordingly, not only because of the reduced
amount of i/o, but also because less computation is required on each
end.
_________________________________________________________________
4.19. Clear-Channel Protocol
Now that C-Kermit itself is capable of sending and receiving any byte
at all on a clear channel ([516]Section 4.18), it is, for the first
time, in a position to negotiate a clear channel with the other
Kermit, giving it permission (but not requiring it) to unprefix any
and all characters that it knows are safe. In general this means all
but the Kermit start-of-packet character (normally Ctrl-A), Carriage
Return (not only Kermit's end-of-packet character, but also treated
specially on Telnet NVT links), and IAC (255, also special to Telnet).
By default, C-Kermit will say it has a clear channel only if it has
opened a TCP socket. Since the Kermit program on the far end of a
TCP/IP connection generally does not know it has a TCP/IP connection,
it will not announce a clear channel unless it has been told to do so.
The command is:
SET CLEAR-CHANNEL { ON, OFF, AUTO }
AUTO is the default, meaning that the clear-channel status is
determined automatically from the type of connection. ON means to
announce a clear channel, OFF means not to announce it. Use SHOW
STREAMING ([517]Section 4.20) to see the current CLEAR-CHANNEL status.
Synonym: SET CLEARCHANNEL.
CLEAR-CHANNEL is also set if you start C-Kermit with the -I switch
(see [518]Section 4.20).
Whenever a clear channel is negotiated, the resulting
control-character unprefixing is "sticky"; that is, it remains in
effect after the transfer so you can use SHOW CONTROL to see what was
negotiated.
You can also see whether a clear channel was negotiated in the
STATISTICS /VERBOSE Display.
The advantage of the clear channel feature is that it can make file
transfers go faster automatically. The disadvantage would be
file-transfer failures if the channel is not truly clear, for example
if C-Kermit made a Telnet connection to a terminal server, and then
dialed out from there; or if C-Kermit made an Rlogin connection to
host and then made a Telnet connection from there to another host. If
a file transfer fails on a TCP/IP connection, use SHOW CONTROL to
check whether control characters became unprefixed as a result of
protocol negotiations, and/or SHOW STREAMING ([519]Section 4.20) to
see if "clear-channel" was negotiated. If this happened, use SET
CLEAR-CHANNEL OFF and SET PREFIXING CAUTIOUS (or whatever) to prevent
it from happening again.
_________________________________________________________________
4.20. Streaming Protocol
A new Kermit protocol option called "streaming" was added in C-Kermit
7.0. The idea is that if the two Kermit partners have a reliable
transport (such as TCP/IP or X.25) between them, then there is no need
to send ACKs for Data packets, or NAKs, since a reliable transport
will, by definition, deliver all packets in order and undamaged. On
such a connection, streaming cuts down not only on Kermit program
overhead (switching back and forth between reading and sending
packets), but also tends to make the underlying transport use itself
more efficiently (e.g. by defeating the Nagle algorithm and/or Delayed
ACK stratagem of the TCP layer). Furthermore, it allows transfers to
work smoothly on extremely slow network congestions that would
otherwise cause timeouts and retransmissions, and even failure when
the retry limit was exceeded.
The trick is knowing when we can stream:
1. If C-Kermit has opened a TCP socket or X.25 connection, it offers
stream.
2. If C-Kermit has been started with the -I (uppercase) option, or if
it has been told to SET RELIABLE ON, it offers to stream.
3. If C-Kermit is in remote mode, and has been told to SET RELIABLE
AUTO (or ON), it always offers to stream, and also always agrees
to stream, if the other Kermit offers. Unless you take explicit
actions to override the defaults, this allows the local Kermit
(the one that made the connection, and so knows whether it's
reliable) to control streaming.
(Note that an offer to stream also results in a Clear-Channel
announcement if CLEAR-CHANNEL is set to AUTO; see [520]Section 4.19.)
When BOTH Kermits offer to stream, then they stream; otherwise they
don't. Thus streaming-capable Kermit programs interoperate
automatically and transparently with nonstreaming ones. If the two
Kermits do agree to stream, you'll see the word "STREAMING" on the
fullscreen file-transfer display in the Window Slots field. You can
also find out afterwards with the STATISTICS or SHOW STREAMING
commands.
WARNING: Automatic choice of streaming is based on the assumption
of a "direct" end-to-end network connection; for example, a Telnet
or Rlogin connection from host A to host B, and transferring files
between A and B. However, if your connection has additional
components -- something "in the middle" (B) that you have made a
network connection to, which makes a separate connection to the
destination host (C), then you don't really have a reliable
connection, but C-Kermit has no way of knowing this; transferring
files between A and C will probably fail. In such cases, you'll
need to tell the *local* C-Kermit to "set reliable off" before
transferring files (it does no good to give this command to the
remote Kermit since the local one controls the RELIABLE setting).
Streaming is like using an infinite window size, with no timeouts and
no tolerance for transmission errors (since there shouldn't be any).
It relies on the underlying transport for flow control, error
correction, timeouts, and retransmission. Thus it is very suitable for
use on TCP/IP connections, especially slow or bursty ones, since
Kermit's packet timeouts won't interfere with the transfer -- each
packet takes as long to reach its destination as it takes TCP to
deliver it. If TCP can't deliver the packet within its own timeout
period (over which Kermit has no control), it signals a fatal error.
Just like FTP.
Streaming goes much faster than non-streaming when a relatively small
packet length is used, and it tends to go faster than non-streaming
with even the longest packet lengths. The Kermit window size is
irrelevant to streaming protocol, but still might affect performance
in small ways since it can result in different paths through the code.
The definition of "reliable transport" does not necessarily demand
8-bit and control-character transparency. Streaming can work with
parity and/or control-character prefixing just as well (but not as
fast) as without them; in such cases you can leave RELIABLE set to ON,
but set CLEARCHANNEL and/or PARITY appropriately.
Maximum performance -- comparable to and often exceeding FTP -- is
achieved on socket-to-socket connections (in which the considerable
overhead of the terminal driver and Telnet or Rlogin server is
eliminated) with long packets and the new "brief" file-transfer
display ([521]Section 4.16).
_________________________________________________________________
4.20.1. Commands for Streaming
SET RELIABLE { ON, OFF, AUTO }
SET RELIABLE ON tells Kermit that it has a reliable transport.
SET RELIABLE OFF tells Kermit the transport is not reliable.
SET RELIABLE AUTO tells Kermit that it should SET RELIABLE ON
whenever it makes a reliable connection (e.g. TELNET or SET
HOST on a TCP/IP or X.25 network), and when in remote mode it
should believe the transport is reliable if the other Kermit
says it is during Kermit protocol negotiation.
AUTO is the default; the Kermit program that makes the connection
knows whether it is reliable, and tells the remote Kermit.
The RELIABLE setting has several effects, including:
* It can affect the timeouts used during normal ACK/NAK protocol.
* It can affect the clear-channel announcement.
* It can affect streaming.
If you TELNET or SET HOST somewhere, this includes an implicit SET
RELIABLE ON command. The -I command-line option is equivalent to SET
RELIABLE ON.
Since SET RELIABLE ON (and -I) also implies SET CLEAR CHANNEL ON, you
might find that in certain cases you need to tell Kermit that even
though the connection is reliable, it doesn't have a clear channel
after all:
SET CLEAR-CHANNEL OFF
SET PREFIXING CAUTIOUS ; or whatever...
You can control streaming without affecting the other items with:
SET STREAMING { ON, OFF, AUTO }
AUTO is the default, meaning streaming will occur if Kermit has made a
TCP/IP connection or if RELIABLE is ON (or it was started with the -I
command line option). OFF means don't stream; ON means offer to stream
no matter what.
_________________________________________________________________
4.20.2. Examples of Streaming
Here we look at the use and behavior of streaming on several different
kinds of connections, and compare its performance with non-streaming
transfers.
4.20.2.1. Streaming on Socket-to-Socket Connections
Here we get streaming automatically when both Kermit programs are
capable of it, since they both make socket connections. For example,
on the far end:
C-Kermit> set host * 3000
C-Kermit> server
and on the near end:
C-Kermit> set host foo.bar.xyz.com 3000
(now give SEND and GET command)
All subsequent file transfers use streaming automatically.
Here are the results from 84 trials, run on a production network,
disk-to-disk, in which a 1-MB binary file (the SunOS C-Kermit Sparc
executable) was sent from a Sun Sparc-10 with SunOS 4.1.3 to an IBM
Power Server 850 with AIX 4.1, socket-to-socket, over a 10Mbps 10BaseT
Ethernet, using minimal control-character unprefixing, window sizes
from 10 to 32, and packet sizes from 1450 to 9010:
Streaming Nonstreaming
Max CPS 748955 683354
Min CPS 221522 172491
Mean CPS 646134 558680
Median CPS 678043 595874
Std Dev 101424 111493
Correlations:
CPS and window size: -0.036
CPS and packet length: 0.254
CPS and streaming: 0.382
Note that the relationship between streaming and throughput is
significantly stronger than that between CPS and window size or packet
length.
Also note that this and all other performance measurements in this
section are snapshots in time; the results could be much different at
other times when the load on the systems and/or the network is higher
or lower.
In a similar socket-to-socket trial, but this time over a wide-area
TCP/IP connection (from New York City to Logan, Utah, about 2000
miles), the following results were obtained:
Streaming Nonstreaming
Max CPS 338226 318203
Min CPS 191659 132314
Mean CPS 293744 259240
Median CPS 300845 273271
Std Dev 41914 52351
Correlations:
CPS and window size: 0.164
CPS and packet length: 0.123
CPS and streaming: 0.346
_________________________________________________________________
4.20.2.2. Streaming on Telnet Connections
In this case the local copy of Kermit is told to TELNET or SET HOST,
and so it knows it has a reliable connection and -- unless it has been
told not to -- will offer to stream, and the other Kermit program,
since it has STREAMING set to AUTO, agrees.
Since we have a reliable connection, we'll also get control-character
unprefixing automatically because of the new clear-channel protocol
([522]Section 4.19).
Any errors that occur during streaming are fatal to the transfer. The
message is "Transmission error on reliable link". Should this happen:
1. Check the remote Kermit's flow control setting (SHOW
COMMUNICATIONS). If it is NONE, change it to XON/XOFF, or vice
versa. If it is XON/XOFF (or you just changed it to XOFF/XOFF),
make sure the file sender is prefixing the XON and XOFF
characters. In the most drastic case, use "set prefix all" to
force prefixing of all control characters.
2. The remote Telnet server might chop off the 8th bit. In that case,
tell C-Kermit to "set parity space". Or, you might be able to
force the Telnet to allow eight-bit data by telling C-Kermit to
"set telopt binary request accept" -- that is, request the Telnet
server to enter binary mode, and accept binary-mode bids from the
server.
3. The remote Telnet server might have a buffering limitation. If a
and b don't cure the problem, tell the file receiver to "set
receive packet-length 1000" (or other number -- use the largest
one that works). This too, is no different from the non-streaming
case (more about this in [523]Section 4.20.2.3).
And remember you can continue interrupted binary-mode transfers where
they left off with the RESEND (= SEND /RECOVER) command.
Here are the figures for the same 84 trials between the same Sun and
IBM hosts as in 4.20.2.1, on the same network, but over a Telnet
connection rather than socket-to-socket:
Streaming Nonstreaming
Max CPS 350088 322523
Min CPS 95547 173152
Mean CPS 321372 281830
Median CPS 342604 291469
Std Dev 40503 29948
Correlations:
CPS and window size: 0.001
CPS and packet length: 0.152
CPS and streaming: 0.128
Here the effect is not as emphatic as in the socket-to-socket case,
yet on the whole streaming tends to be beneficial.
Additional measurements on HP-UX using C-Kermit 7.0 Beta.06:
Windowing Streaming
HP-UX 8->8 not tested 14Kcps
HP-UX 8->9 not tested 76Kcps
HP-UX 8->10 36Kcps 66Kcps
HP-UX 9->9 not tested 190Kcps
HP-UX 9->10 160Kcps 378Kcps
_________________________________________________________________
4.20.2.3. Streaming with Limited Packet Length
The IRIX telnet server (at least the ones observed in IRIX 5.3 and
6.2) does not allow Kermit to send packets longer than 4096 bytes.
Thus when sending from IRIX C-Kermit when it is on the remote end of a
Telnet connection, the packet length must be 4K or less. Trials in
this case (in which packet lengths range from 1450 to 4000) show a
strong advantage for streaming, which would be evident in any other
case where the packet length is restricted, and stronger the shorter
the maximum packet length.
Streaming Nonstreaming
Max CPS 426187 366870
Min CPS 407500 276517
Mean CPS 415226 339168
Median CPS 414139 343803
Std Dev 6094 25851
Correlations:
CPS and window size: 0.116
CPS and packet length: 0.241
CPS and streaming: 0.901
_________________________________________________________________
4.20.2.4. Streaming on Dialup Connections
Here "dialup" refers to a "direct" dialup connection, not a SLIP or
PPP connection, which is only a particular kind of TCP/IP connection.
Attempt this at your own risk, and then only if (a) you have
error-correcting modems, and (b) the connections between the modems
and computers are also error-free, perfectly flow-controlled, and free
of interrupt conflicts. Streaming can be used effectively and to
fairly good advantage on such connections, but remember that the
transfer is fatal if even one error is detected (also remember that
should a binary-mode transfer fail, it can be recovered from the point
of failure with RESEND).
To use streaming on an unreliable connection, you must tell both
Kermits that the connection is reliable:
kermit -I
or:
C-Kermit> set reliable on
In this case, it will probably be necessary to prefix some control
characters, for example if your connection is through a terminal
server that has an escape character. Most Cisco terminal servers, for
example, require Ctrl-^ (30, as well as its high-bit equivalent, 158)
to be prefixed. To unprefix these, you'll need to defeat the "clear
channel" feature:
C-Kermit> set reliable on
C-Kermit> set clear-channel off
C-Kermit> set prefixing none
C-Kermit> set control prefix 1 13 30 158 ; and whatever else is necessary
Dialup trials were done using fixed large window and packet sizes.
They compare uploading and downloading of two common types of files,
with and without streaming. Configuration:
HP-9000/715/33 -- 57600bps, RTS/CTS -- USR Courier V.34 --
V.34+V.42, 31200bps -- USR V.34+ Rackmount -- 57600bps, RTS/CTS --
Cisco terminal server -- Solaris 2.5.1. Packet size = 8000, Window
Size = 30, Control Character Unprefixing Minimal (but including the
Cisco escape character).
Since this is not a truly reliable connection, a few trials failed
when a bad packet was received (most likely due to UART overruns); the
failure was graceful and immediate, and the message was informative.
The results of ten successful trials uploading and downloading the two
files with and without streaming are:
Streaming..
Off On
Upload 5194 5565 txt (= C source code, 78K)
3135 3406 gz (= gzip file, compressed, 85K)
Download 5194 5565 txt
3041 3406 gz
Each CPS figure is the mean of 10 results.
A brief test was also performed on a LAT-based dialout connection from
a VAX 3100 with VMS 5.5 to a USR Courier V.34 connected to a DECserver
700 at 19200 bps. The 1-MB Sparc executable downloaded from a Sun to
the VAX at 1100cps without streaming and 1900cps with streaming, using
8000-byte packets, 30 window slots, and minimal prefixing in both
cases.
_________________________________________________________________
4.20.2.5. Streaming on X.25 Connections
We have only limited access to X.25 networks. One trial was performed
in which the 1MB Solaris 2.4 Sparc executable was transferred over a
SunLink X.25 connection; nothing is known about the actual physical
connection. With a packet length of 8000 and a window size of 30, the
file transferred at 6400 cps (using a maximum of 6 window slots). With
the same packet length, but with streaming, it transferred without
mishap at 6710 cps, about 5% faster.
_________________________________________________________________
4.20.3. Streaming - Preliminary Conclusions
The results vary with the particular connection, but are good overall.
Although numerous lower-level tricks can be used to improve
performance on specific platforms or connection methods, streaming
occurs at a high, system-independent level of the Kermit protocol and
therefore can apply to all types of platforms and (reliable)
connections transparently.
_________________________________________________________________
4.21. The TRANSMIT Command
Prior to C-Kermit 7.0, the TRANSMIT command transmitted in text or
binary mode according to SET FILE TYPE { TEXT, BINARY }. But now that
binary mode is likely to be the default for protocol transfers, it is
evident that this not also an appropriate default for TRANSMIT, since
binary-mode TRANSMIT is a rather specialized and tricky operation.
Therefore, TRANSMIT defaults to text mode always, regardless of the
FILE TYPE setting.
C-Kermit 7.0 expands the capabilities of the TRANSMIT command by
adding the following switches (see [524]Section 1.5). The new syntax
is:
TRANSMIT [ switches... ] filename
Zero or more switches may be included:
/PIPE
When /PIPE is included, "filename" is interpreted as a system
command or program whose output is to be sent. Synonym:
/COMMAND. Example:
transmit /pipe finger
You may enclose the command in braces, but you don't have to:
xmit /pipe {ls -l | sort -r +0.22 -0.32 | head}
/BINARY
Transmits the file (or pipe output) in binary mode.
/TEXT
Transmits the file (or pipe output) in line-oriented text mode.
Current FILE CHARACTER-SET and TERMINAL CHARACTER-SET
selections govern translation. Default.
/TRANSPARENT
Specifies text mode without character-set translation, no
matter what the FILE and TERMINAL CHARACTER-SET selections are.
/NOWAIT
This is equivalent to SET TRANSMIT PROMPT 0, but for this
TRANSMIT command only. Applies only to text mode; it means to
not wait for any kind of echo or turnaround character after
sending a line before sending the next line. (Normally Kermit
waits for a linefeed.)
When TRANSMIT ECHO is ON, C-Kermit tries to read back the echo of each
character that is sent. Prior to C-Kermit 7.0, 1 second was allowed
for each echo to appear; if it didn't show up in a second, the
TRANSMIT command would fail. Similarly for the TRANSMIT PROMPT
character. However, with today's congested Internet connections, etc,
more time is often needed:
SET TRANSMIT TIMEOUT number
Specifies the number of seconds to wait for an echo or the prompt
character when TRANSMIT PROMPT is nonzero; the default wait is 1
second. If you specify 0, the wait is indefinite. When a timeout
interval of 0 is specified, and a desired echo or prompt does not show
up, the TRANSMIT command will not terminate until or unless you
interrupt it with Ctrl-C; use SET TRANSMIT TIMEOUT 0 with caution.
Note: to blast a file out the communications connection without any
kind of synchronization or timeouts or other manner of checking, use:
SET TRANSMIT ECHO OFF
SET TRANSMIT PROMPT 0 (or include the /NOWAIT switch)
SET TRANSMIT PAUSE 0
TRANSMIT [ switches ] filename
In this case, text-file transmission is not-line oriented and large
blocks can be sent, resulting in a significant performance improvement
over line-at-at-time transmission. Successful operation depends (even
more than usual for the TRANSMIT command!) on a clean connection with
effective flow control.
For details on TRANSMIT and character sets, see [525]Section 6.6.5.4.
_________________________________________________________________
4.22. Coping with Faulty Kermit Implementations
Kermit protocol has been implemented in quite a few third-party
commercial, shareware, and freeware software packages, with varying
degrees of success. In most cases operation is satisfactory but slow
-- only the bare minimum subset of the protocol is available -- short
packets, no sliding windows, no attributes, etc. In other cases, the
implementation is incorrect, resulting in failures at the initial
negotiation stage or corrupted files.
C-Kermit 7.0 and Kermit 95 1.1.19 include some new defense mechanisms
to help cope with the most common situations. However, bear in mind
there is only so much we can do in such cases -- the responsibility
for fixing the problem lies with the maker of the faulty software.
_________________________________________________________________
4.22.1. Failure to Accept Modern Negotiation Strings
The published Kermit protocol specification states that new fields can
be added to the parameter negotiation string. These are to be ignored
by any Kermit implementation that does not understand them; this is
what makes the Kermit protocol extensible. Unfortunately, some Kermit
implementations become confused (or worse) when receiving a
negotiation string longer than the one they expect. You can try
working around such problems by telling Kermit to shorten its
negotiation string (and thus disable the corresponding new features):
SET SEND NEGOTIATION-STRING-MAX-LENGTH number
Try a number like 10. If that doesn't work, try 9, 8, 7, 6, and so on.
_________________________________________________________________
4.22.2. Failure to Negotiate 8th-bit Prefixing
The published Kermit protocol specification states that 8th-bit
prefixing (which allows transfer of 8-bit data over a 7-bit
connection) occurs if the file sender puts a valid prefix character
(normally "&") in the 8th-bit-prefix field of the negotiation string,
and the receiver puts either a letter "Y" or the same prefix
character. At least one faulty Kermit implementation exists that does
not accept the letter "Y". To force C-Kermit / K-95 to reply with the
other Kermit's prefix character rather than a "Y", give the following
(invisible) command:
SET Q8FLAG ON
Use SET Q8FLAG OFF to restore the normal behavior.
_________________________________________________________________
4.22.3. Corrupt Files
Refer to [526]Section 4.22.2. Some Kermit implementations mistakenly
interpret the "Y" as a prefix character. Then, whenever a letter Y
appears in the data, the Y and the character that follows it are
replaced by a garbage character. At this writing, we are not sure if
there is any solution, but try "set send negotiation-string-max-length
6" and/or "set q8flag on".
File corruption can also occur when control characters within the file
data are sent without prefixing, as at least some are by default in
C-Kermit 7.0 and K-95. Some Kermit implementations do not handle
incoming "bare" control characters. To work around, "set prefixing
all".
_________________________________________________________________
4.22.4. Spurious Cancellations
The Kermit protocol specification states that if an ACK to a Data
packet contains X in its data field, the transfer of the current file
is canceled, and if it contains a Z, the entire transfer is canceled.
At least one overzealous Kermit implementation applies this rule to
non-Data packets as well, the typical symptom being that any attempt
to transfer a file whose name begins with X or Z results in
cancellation. This is because the file receiver typically sends back
the name under which it stored the file (which might not be the same
as the name it was sent with) in the ACK to the File Header packet.
This is information only and should not cause cancellation. To work
around the problem, use:
SET F-ACK-BUG { ON, OFF }
ON tells Kermit not to send back the filename in the ACK to the file
header packet as it normally would do (OFF puts Kermit back to normal
after using ON).
A variation on the this bug occurs in an obscure Kermit program for
MUMPS: When this Kermit program sends a file called (say) FOO.BAR, it
requires that the ACK to its F packet contain exactly the same name,
FOO.BAR. However, C-Kermit likes to send back the full pathname,
causing the MUMPS Kermit to fail. SET F-ACK-BUG ON doesn't help here.
So a separate command has been added to handle this situation:
SET F-ACK-PATH { ON, OFF }
Normally it is ON (regardless of the SET SEND PATHNAMES setting). Use
SET F-ACK-PATH OFF to instruct Kermit to send back only the filename
without the path in the ACK to the F packet.
_________________________________________________________________
4.22.5. Spurious Refusals
Some Kermit implementations, notably PDP-11 Kermit 3.60 and earlier,
have bugs in their handling of Attribute packets that can cause
unwarranted refusal of incoming files, e.g. based on date or size.
This can be worked around by telling one or both of the Kermit
partners to:
SET ATTRIBUTES OFF
_________________________________________________________________
4.22.6. Failures during the Data Transfer Phase
This can be caused by control-character unprefixing ([527]Section
4.22.3 ), and fixed by:
SET PREFIXING ALL
It can also have numerous other causes, explained in Chapter 10 of
[528]Using C-Kermit: the connection is not 8-bit transparent (so use
"set parity space" or somesuch), inadequate flow control, etc. Consult
the manual.
_________________________________________________________________
4.22.7. Fractured Filenames
At least one well-known PC-based communications package negotiates
data compression, which (according to the protocol specification)
applies to both the filename and the file data, but then fails to
decompress the filename. Example: C-Kermit sends a file called
R000101.DAT (where 000101 might be non-Y2K-wise YYMMDD notation), and
the package in question stores the files as R~#0101.DAT. Workaround:
Tell C-Kermit to SET REPEAT COUNTS OFF.
_________________________________________________________________
4.22.8. Bad File Dates
At least one well-known PC-based communications package negotiates the
passing of file timestamps from sender to receiver, but when it is
sending files, it always gives them a timestamp of 1 February 1970.
Workaround: tell C-Kermit to SET ATTRIBUTE DATE OFF. You don't get the
file's real date, but you also don't get 1 Feb 1970; instead the file
gets the current date and time.
_________________________________________________________________
4.23. File Transfer Recovery
Prior to C-Kermit 7.0, RESEND (SEND /RECOVER) and REGET (GET /RECOVER)
refused to work if FILE TYPE was not BINARY or the /BINARY switch was
not included. Now these commands include an implied /BINARY switch,
meaning they set the file type to binary for the duration of the
command automatically.
In the client/server arrangement, this also forces the server into
binary mode (if it is C-Kermit 7.0 or greater, or K95 1.1.19 or
greater) so the recovery operation proceeds, just as you asked and
expected.
BUT... Just as before, the results are correct only under the
following conditions:
* If the prior interrupted transfer was also in binary mode; or:
* If the prior transfer was in text mode and the other computer was
a "like platform" (e.g. UNIX-to-UNIX, Windows-to-Windows,
DOS-to-Windows) AND there was no character-set translation (i.e.
TRANSFER CHARACTER-SET was TRANSPARENT).
Note that these circumstances are more likely to obtain in C-Kermit
7.0, in which:
* The default FILE TYPE in C-Kermit 7.0 is BINARY.
* The default FILE INCOMPLETE setting is AUTO, which means KEEP if
the transfer is in binary mode, DISCARD otherwise.
* C-Kermit 7.0, Kermit 95 1.1.17, and MS-DOS Kermit 3.15 and later
can recognize "like platforms" and switch into binary mode
automatically. Transfers between like platforms are always binary
unless character-set translation has been requested, and then is
still binary for all files whose names match a binary pattern,
unless the automatic mechanisms have been disabled (with a /TEXT
switch, or with SET TRANSFER MODE MANUAL).
* SEND /BINARY and GET /BINARY always force binary-mode transfers,
even when FILE TYPE is TEXT, even when TRANSFER MODE is AUTOMATIC,
even when PATTERNS are ON and the file's name matches a text
pattern.
But also note that the automatic client/server transfer-mode
adjustments do not work with versions of C-Kermit prior to 7.0 or K95
prior to 1.1.16.
If the prior transfer was in text mode:
* If text-mode transfers between the two platforms are
"length-changing" (as they are between UNIX -- which terminates
text lines with LF -- and DOS or Windows -- which terminates text
lines with CRLF), the recovered file will be corrupt.
* If text-mode transfers between the two platforms are not
length-changing, but character-set translation was active in the
prior transfer, the result will be a file in which the first part
has translated characters and the second part does not.
But in C-Kermit 7.0 and K95 1.1.19 and later, incompletely transferred
text files are not kept unless you change the default. But if you have
done this, and you have an incompletely transferred text file, you'll
need to:
* Transfer the whole file again in text mode, or:
* Use SEND /STARTING-AT: to recover the transfer at the correct
point; but you have to find out what that point is, as described
in the manual.
Kermit has no way of knowing whether the previous transfer was in text
or binary mode so it is your responsibility to choose the appropriate
recovery method.
If you use C-Kermit to maintain parallel directories on different
computers, using SET FILE COLLISION to transfer only those files that
changed since last time, and the files are big enough (or the
connection slow enough) to require SEND /RECOVER to resume interrupted
transfers, you should remember that SEND /RECOVER (RESEND) overrides
all FILE COLLISION settings. Therefore you should use SEND /RECOVER
(RESEND) only on the file that was interrupted, not the file group.
For example, if the original transfer was initiated with:
SEND *
and was interrupted, then after reestablishing your connection and
starting the Kermit receiver with SET FILE COLLISION UPDATE on the
remote end, use the following sequence at the sender to resume the
transfer:
SEND /RECOVER name-of-interrupted-file
and then:
SEND *
(In C-Kermit 7.0 and later, \v(filename) contains the name of the file
most recently transferred, as long you have not EXITed from Kermit or
changed directory, etc.
_________________________________________________________________
4.24. FILE COLLISION UPDATE Clarification
In UNIX, file modification dates are used when comparing the file date
with the date in the attribute packet. In VMS, however, the file
creation date is used. These two policies reflect the preferences of
the two user communities.
Also, remember that the file date/time given in the attribute packet
is the local time at the file sender. At present, no timezone
conversions are defined in or performed by the Kermit protocol. This
is primarily because this feature was designed at a time when many of
the systems where Kermit runs had no concept of timezone, and
therefore would be unable to convert (say, to/from GMT or UTC or Zulu
time).
As a consequence, some unexpected results might occur when
transferring files across timezones; e.g. commands on the target
system that are sensitive to file dates might work (UNIX "make",
backups, etc).
Timezone handling is deferred for a future release.
_________________________________________________________________
4.25. Autodownload Improvements
Refer to pages 164-165 of [529]Using C-Kermit about the hazards of
autodownload when C-Kermit is "in the middle". As of C-Kermit 7.0, no
more hazards. If C-Kermit has TERMINAL AUTODOWNLOAD ON and it detects
a packet of the current protocol type (Kermit or Zmodem), it "erases"
the visual aspect of the packet that would be seen by the terminal
(or, more to the point, the emulator, such as K95). This way, only
C-Kermit goes into RECEIVE mode, and not also the terminal emulator
through which C-Kermit is accessed. And therefore, it is no longer
necessary to SET TERMINAL AUTODOWNLOAD OFF to prevent multiple Kermits
from going into receive mode at once, but of course it is still
necessary to ensure that, when you have multiple Kermits in a chain,
that the desired one receives the autodownload.
The defaults have not been changed; Kermit 95 still has autodownload
ON by default, and C-Kermit has it OFF by default.
_________________________________________________________________
5. CLIENT/SERVER
5.0. Hints
If you use SET SERVER GET-PATH to set up your server, and the GET-PATH
does not include the server's current directory, clients can become
quite confused. For example, "remote dir oofa.txt" shows a file named
oofa.txt, but "get oofa.txt" fails. In this situation, you should
either DISABLE DIR or make your GET-PATH include the current
directory.
_________________________________________________________________
5.1. New Command-Line Options
The -G command-line option is like -g (GET), except the incoming file
is sent to standard output rather than written to disk.
The -I option ("Internet") is used to tell a remote C-Kermit program
that you are coming in via Internet Telnet or Rlogin and therefore
have a reliable connection. The -I option is equivalent to SET
RELIABLE ON and SET FLOW NONE.
The -O option ("Only One") tells C-Kermit to enter server mode but
then exit after the first client operation.
See [530]Section 9.3 for details.
_________________________________________________________________
5.2. New Client Commands
BYE and FINISH no longer try to do anything if a connection is not
active. Thus a sequence like "hangup" followed by "bye" or "finish"
will no longer get stuck in a long timeout-and-retransmission cycle,
nor will it try to open a new connection.
REMOTE EXIT
Similar to FINISH, except it ensures that the Kermit server
program exits back to the operating system or shell prompt.
(FINISH would return it to its interactive prompt if it was
started in interactive mode, and would cause it to exit if it
entered server mode via command-line option.) When C-Kermit is
to be the server, you can use { ENABLE, DISABLE } EXIT to
control the client's access to this feature.
REMOTE MKDIR directory-name
Tells the client to ask the server to create a directory with
the given name, which can be absolute or relative. The syntax
of the directory name depends on the Kermit server (see
[531]next section); in all cases, it can be in the syntax of
the system where the server is running (UNIX, VMS, DOS, etc)
but newer servers also accept UNIX syntax, no matter what the
underlying platform. The server will not execute this command
if (a) it does not understand it, (b) a DISABLE MKDIR command
has been given, or (c) a DISABLE CWD command has been given;
otherwise, the command is executed, but will fail if the
directory can not be created, in which cases most servers will
attempt to return a message giving the reason for failure. The
REMOTE MKDIR command succeeds if the remote directory is
created, or if it already exists and therefore does not need to
be created, and fails otherwise.
REMOTE RMDIR directory-name
Tells the client to ask the server to remove (delete) a
directory with the given name. The same considerations apply as
for REMOTE MKDIR.
REMOTE SET FILE INCOMPLETE { DISCARD, KEEP, AUTO }
Previously this was only available in its earlier form, REMOTE
SET INCOMPLETE (no FILE). The earlier form is still available,
but invisible. Also, AUTO was added, meaning KEEP if in binary
mode, DISCARD otherwise.
REMOTE SET TRANSFER MODE { AUTOMATIC, MANUAL }
Tells the client to ask the server to set the given
file-transfer mode. Automatic means (roughly): if the client
and the server are running on the same kind of computer (e.g.
both are on UNIX), then use binary mode automatically; if the
system types are different, use some other method to
automatically determine text or binary mode, such as filename
pattern matching. MANUAL means, in this context, obey the
client's FILE TYPE setting (TEXT or BINARY). Synonym: REMOTE
SET XFER MODE.
[ REMOTE ] QUERY KERMIT function(args...)
Prior to C-Kermit 7.0, the arguments were not evaluated
locally. Thus it was not possible to have the server run the
function with client-side variables as arguments. Now:
define \%a oofa.*
remote query kermit files(\%a) ; Client's \%a
remote query kermit files(\\%a) ; Server's \%a
[ REMOTE ] LOGIN [ user [ password ] ]
LOGIN is now a synonym for REMOTE LOGIN.
LOGOUT
This command, when given in local mode, is equivalent to REMOTE
LOGOUT. When given at the IKSD prompt, it logs out the IKSD.
When given at the C-Kermit prompt when it has no connection, it
does nothing.
Note that in C-Kermit 7.0, the REMOTE (or R) prefix is not required
for QUERY, since there is no local QUERY command. The new top-level
QUERY command does exactly what REMOTE QUERY (RQUERY) does.
All REMOTE commands now have single-word shortcuts:
Shortcut Full Form
RASG REMOTE ASSIGN
RCD REMOTE CD
RCOPY REMOTE COPY
RDEL REMOTE DELETE
RDIR REMOTE DIRECTORY
REXIT REMOTE EXIT
RHELP REMOTE HELP
RHOST REMOTE HOST
RPWD REMOTE PWD
RSET REMOTE SET
etc.
The R prefix is not applied to LOGIN because there is already an
RLOGIN command with a different meaning. It is not applied to LOGOUT
either, since LOGOUT knows what to do in each case, and for symmetry
with LOGIN.
_________________________________________________________________
5.2.1. Remote Procedure Definitions and Calls
This is nothing new, but it might not be obvious... REMOTE ASSIGN and
REMOTE QUERY may be used to achieve remote procedure execution. The
remote procedure can be defined locally or remotely.
A remote procedure call is accomplished as noted in the previous
section:
[ remote ] query kermit function-name(args...)
This invokes any function that is built in to the Kermit server, e.g.:
[ remote ] query kermit size(foo.bar)
returns the size of the remote file, foo.bar.
Now note that C-Kermit includes an \fexecute() function, allowing it
to execute any macro as if it were a built-in function. So suppose
MYMACRO is the name of a macro defined in the server. You can execute
it from the client as follows (the redundant "remote" prefix is
omitted in the remaining examples):
query kermit execute(mymacro arg1 arg2...)
The return value, if any, is the value of the RETURN command that
terminated execution of the macro, for example:
define addtwonumbers return \feval(\%1+\%2)
The client invocation would be:
query kermit execute(addtwonumbers 3 4)
7
The result ("7" in this case) is also assigned to the client's
\v(query) variable.
To execute a remote system command or command procedure (shell script,
etc) use:
query kermit command(name args...)
Finally, suppose you want the client to send a macro to the server to
be executed on the server end. This is done as follows:
remote assign macroname definition
query kermit execute(macroname arg1 arg2...)
Quoting is required if the definition contains formal parameters.
_________________________________________________________________
5.3. New Server Capabilities
5.3.1. Creating and Removing Directories
The C-Kermit 7.0 server responds to REMOTE MKDIR and REMOTE RMDIR
commands. The directory name may be in either the native format of the
server's computer, or in UNIX format. For example, a server running on
VMS with a current directory of [IVAN] can accept commands from the
client like:
remote mkdir olga ; Makes [IVAN.OLGA] (nonspecific format)
remote mkdir .olga ; Makes [IVAN.OLGA] (VMS format without brackets)
remote mkdir olga/ ; Makes [IVAN.OLGA] (UNIX relative format)
remote mkdir /ivan/olga ; Makes [IVAN.OLGA] (UNIX absolute format)
remote mkdir [ivan.olga] ; Makes [IVAN.OLGA] (VMS absolute format)
remote mkdir [.olga] ; Makes [IVAN.OLGA] (VMS relative format)
5.3.1.1. Creating Directories
If a directory name is given that contains more than one segment that
does not exist, the server attempts to create all the segments. For
example, if the client says:
REMOTE MKDIR letters/angry
a "letters" subdirectory is created in the server's current directory
if it does not already exist, and then an "angry" subdirectory is
created beneath it, if it does not already have one. This can repeated
to any reasonable depth:
REMOTE MKDIR a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/t/u/v/w/z/y/z
5.3.1.2. Removing Directories
When attempting to execute a REMOTE RMDIR, the server can remove only
a single directory, not an entire sequence or tree. The system service
that is called to remove the directory generally requires not only
that the server process has write delete access, but also that the
directory contain no files.
In the future, a REMOTE RMDIR /RECURSIVE command (and the accompanying
protocol) might be added. For now, use the equivalent REMOTE HOST
command(s), if any.
_________________________________________________________________
5.3.2. Directory Listings
Directory listings are generated by C-Kermit itself, rather than by
running the underlying system's directory command. Some control over
the listing format can be obtained with the SET OPTIONS DIRECTORY
command ([532]Section 4.5.1). The following options affect listings
sent by the server: /[NO]HEADING, /[NO]DOTFILES, and /[NO]BACKUP. In
UNIX and VMS, the listing is always sorted by filename. There is, at
present, no protocol defined for the client to request listing options
of the server; this might be added in the future.
The server's directory listings are in the following format:
Protection or permissions:
In UNIX and OS-9, this is a 10-character field, left adjusted.
In VMS it is a 22-character field, left-adjusted. In each case,
the protection / permission codes are shown in the server
platform's native format. In other operating systems, this
field is not shown.
Size in bytes:
This is always a 10-character field. The file's size is shown
as a decimal number, right adjusted in the field. If the file
is a directory and its size can not be obtained, the size is
shown as "<DIR>". Two blanks follow this field.
Date:
Always in yyyy-mm-dd hh:mm:ss numeric format, and therefore 19
characters long. If the file's date/time can't be obtained,
zeros (0) are shown for all the digits. This field is followed
by two blanks.
Filename:
This field extends to the end of the line. Filenames are shown
relative to the server's current directory. In UNIX, symbolic
links are shown as they are in an "ls -l" listing as "linkname
-> filename".
In UNIX and VMS, listings are returned by the server in alphabetical
order of filename. There are presently no other sort or selection
options.
However, since these are fixed-field listings, all fields can be used
as sort keys by external sort programs. Note, in particular, that the
format used for the date allows a normal lexical on that field to
achieve the date ordering. For example, let's assume we have a UNIX
client and a UNIX server. In this case, the server's listing has the
date in columns 22-40, and thus could be sorted by the UNIX sort
program using "sort +0.22 -0.40" or in reverse order by "sort +0.22
-0.40r".
Since the UNIX client can pipe responses to REMOTE commands through
filters, any desired sorting can be accomplished this way, for
example:
C-Kermit> remote directory | sort +0.22 -0.40
You can also sort by size:
C-Kermit> remote directory | sort +0.11 -0.19
You can use sort options to select reverse or ascending order. "man
sort" (in UNIX) for more information. And of course, you can pipe
these listings through any other filter of your choice, such as grep
to skip unwanted lines.
_________________________________________________________________
5.4. Syntax for Remote Filenames with Embedded Spaces
C-Kermit and K95, when in server mode, assume that any spaces in the
file specification in an incoming GET command are filename separators.
Thus if the client gives a command like:
get {oofa.txt oofa.bin}
or, equivalently:
mget oofa.txt oofa.bin
the server tries to send the two files, oofa.txt and oofa.bin. But
what if you want the server to send you a file named, say:
D:\HP OfficeJet 500\Images\My Pretty Picture Dot PCL
How does the server know this is supposed to be one file and not
seven? In this case, you need to the send file name to the server
enclosed in either curly braces:
{D:\HP OfficeJet 500\Images\My Pretty Picture Dot PCL}
or ASCII doublequotes:
"D:\HP OfficeJet 500\Images\My Pretty Picture Dot PCL"
The method for doing this depends on your client. If your client is
C-Kermit 7.0, any recent version of Kermit 95, or MS-DOS Kermit 3.16,
then you have to enclose the name in braces just so the client can
parse it, so to send braces or doublequotes to the server, you must
put them inside the first, outside pair of braces. And you also need
to double the backslashes to prevent them from being interpreted:
get {{D:\\HP OfficeJet 500\\Images\\My Pretty Picture Dot PCL}}
get {"D:\\HP OfficeJet 500\\Images\\My Pretty Picture Dot PCL"}
To get around the requirement to double backslashes in literal
filenames, of course you can also use:
set command quoting off
get {{D:\HP OfficeJet 500\Images\My Pretty Picture Dot PCL}}
get {"D:\HP OfficeJet 500\Images\My Pretty Picture Dot PCL"}
set command quoting on
If you are giving a "kermit" command to the UNIX shell, you have to
observe the shell's quoting rules, something like this:
kermit -ig "{D:\HP OfficeJet 500\Images\My Pretty Picture Dot PCL}"
Here, the quotes go on the outside so UNIX will pass the entire
filename, spaces, braces, and all, as a single argument to Kermit, and
the backslashes are not doubled because (a) the UNIX shell ignores
them since they are in a quoted string, and (b) Kermit ignores them
since the interactive command parser is not activated in this case.
_________________________________________________________________
5.5. Automatic Orientation Messages upon Directory Change
C-Kermit 7.0, when acting as a server, can send an orientation message
to the client whenever the server directory changes. For example, when
the client gives a REMOTE CD command, the server sends the contents of
the new directory's "Read Me" file to the client's screen. The
following commands govern this feature:
SET SERVER CD-MESSAGE FILE name
Given to the servr, allows the message-file name to be
specified at runtime. A list of names to look for can be given
in the following format:
{{name1}{name2}{name3}{...}}
e.g. SET SERVER CD-MESSAGE FILE
{{./.readme}{README.TXT}{READ.ME}}
REMOTE SET SERVER CD-MESSAGE { ON, OFF }
Given to the client, lets the client control whether the server
sends automatic CD messages.
SHOW SERVER
Given to server, includes CD-Message status.
The default CD message file name is system dependent. SHOW CD or SHOW
SERVER displays the list. Also see [533]Section 4.5.2.
_________________________________________________________________
5.6. New Server Controls
DISABLE ENABLE
Allows the server to configured such that DISABLEd features can
not be re-enabled by any means -- e.g. if the client is somehow
able to get the server into command mode. Once DISABLEd, ENABLE
can not be re-ENABLEd.
SET SERVER IDLE-TIMEOUT seconds
This was available previously in Kermit 95 only. Now it can be
used in C-Kermit also to specify a maximum number of seconds
the server is allowed to be idle before exiting server mode. 0
seconds means no idle timeout. In C-Kermit (but not K-95), SET
SERVER TIMEOUT and SET SERVER IDLE-TIMEOUT are mutually
exclusive -- you can have one or the other (or neither), but
not both. (Server timeouts are for the benefit of primitive
Kermit clients that are not capable of timing out on their own;
to our knowledge, no such clients are still in circulation.)
SET SERVER KEEPALIVE { ON, OFF }
(See next section).
_________________________________________________________________
5.7. Timeouts during REMOTE HOST Command Execution
Prior to C-Kermit 7.0, the C-Kermit server would block waiting for
output from a system command invoked via REMOTE HOST from the client.
If the system command took a long time to execute, the client would
time out and send NAK packets. If the command took too long, the
client would reach its retry limit and give up. Even if it didn't, the
NAKs would cause unnecessary retransmissions.
In version 7.0, the C-Kermit server (VMS and select()-capable UNIX
versions only), sends "keepalive packets" (empty data packets) once
per second while waiting for the system command to complete. This
procedure should be entirely transparent to the Kermit client, and
should prevent the unwanted timeouts and NAKs. When C-Kermit 7.0
itself (or K95 1.1.19) is the client, it prints dots to show the
keepalive packets.
The keepalive feature can be turned off and on with:
SET SERVER KEEPALIVE { ON, OFF }
Normally it should be on. Turn it off it if causes trouble with the
client, or if it seems to slow down the server (as it might on some
platforms under certain circumstances).
_________________________________________________________________
6. INTERNATIONAL CHARACTER SETS
Support for several new single-byte character sets was added in
C-Kermit 7.0. Unicode / ISO 10646 is not yet supported, but is a high
priority for forthcoming releases.
6.0. ISO 8859-15 Latin Alphabet 9
To accommodate the Euro currency symbol, and to correct several other
longstanding problems with ISO Latin Alphabet 1, ISO 8859-15 Latin
Alphabet 9 was issued in May 1998. It is supported by C-Kermit 7.0 as
a transfer character set, a file character set, and a terminal
character set. Translations that preserve the new characters are
available between Latin-9 and several other sets including:
PC Code Page 858 (Western European languages, similar to CP850)
Windows Code Page 1252 (Western European languages, similar to Latin-1)
Windows Code Page 1250 (Eastern European languages, similar to Latin-2)
The Latin-9 transfer character set also allows for the OE digraph
character, used primarily in French, to be preserved in transfers
involving the DEC MCS or NeXT character sets.
The Euro character is also present in the Universal Character Set,
described in [534]Section 6.6.
6.1. The HP-Roman8 Character Set
The HP-Roman8 character set is supported in C-Kermit 6.0 and later but
was omitted from Table VII-4 in the 2nd Edition of Using C-Kermit due
to lack of space. It is listed in [535]Appendix III.
6.2. Greek Character Sets
Greek character sets were added in 6.1:
SET FILE CHARACTER-SET { CP869, ELOT927, GREEK-ISO }
SET TRANSFER CHARACTER-SET { GREEK-ISO }
GREEK-ISO is ISO 8859-7, which the same as ELOT 928.
The new Greek character sets are listed in [536]Appendix III.
6.3. Additional Latin-2 Character Sets
The following have been added as FILE and TERMINAL CHARACTER-SETs:
MAZOVIA-PC
A PC code page used in Poland, equivalent to CP437, but with 18
substitutions needed for Polish.
CP1250
The Windows Latin 2 Code Page. Equivalent to ISO 8859-2, but
with different encoding.
6.4. Additional Cyrillic Character Sets
The following have been added as FILE and TERMINAL CHARACTER-SETs:
BULGARIA-PC
This is the Cyrillic PC code page used in Bulgaria, where it is
called Code Page 856. It is attributed to a company called
DATEC, Inc, but CP856 is not a proper designation, since it
refers to a Hebrew Code Page (see the IBM Registry).
CP855
This PC Code Page contains all the Cyrillic letters that are
also in ISO 8859-5, and is therefore useful for non-Russian
Cyrillic text (Ukrainian, Belorussian, etc), unlike CP866,
which has a smaller repertoire of Cyrillic letters.
CP1251
The Windows Cyrillic Code Page. Equivalent to CP855, but with
different encoding.
KOI8R
An extension to "Old KOI-8" that adds upper and lower case
Cyrillic letter Io (looks like Roman E with diaeresis) plus a
selection of box-drawing characters to columns 8 through 11,
which are vacant in original Old KOI-8. KOI8-R is used for the
Russian language. It is specified in [537]RFC 1489.
KOI8U
A similar extension of Old KOI-8, but for Ukrainian. It is
specified in [538]RFC 2319.
_________________________________________________________________
6.5. Automatic Character-Set Switching
Prior to version 7.0, C-Kermit's file character-set always had to be
set explicitly. In 7.0 and later, it is set automatically when:
1. This feature is enabled (as it is unless you disable it).
2. An incoming text-mode transfer includes a transfer-character-set
announcer and you have not previously given a SET FILE
CHARACTER-SET command. In this case, C-Kermit switches to an
appropriate file character set. For example, on an HP-UX
workstation, an incoming Latin-1 file automatically selects
HP-Roman8 for the local copy of the file; in Data General AOS/VS,
it would select DG International.
3. You give a SET TRANSFER CHARACTER-SET command without having
previously specified a FILE CHARACTER-SET. An appropriate file
character-set is chosen automatically.
In addition, when you give a SET FILE CHARACTER-SET command, the
appropriate transfer character-set is automatically chosen, to be used
when you are sending files (but this does not override the one
announced by the sender when you are receiving files).
You might not agree about what is "appropriate", so of course you can
disable or change all of the above actions.
You can disable (or re-enable) the new automatic character-set
switching feature in each direction separately:
SET RECEIVE CHARACTER-SET-SELECTION { AUTOMATIC, MANUAL }
AUTOMATIC is the default, causing the behavior described above
when an incoming file arrives. Choose MANUAL to defeat this
behavior and force your current FILE CHARACTER-SET setting to
be used, no matter what it is. Note that SET RECEIVE
CHARACTER-SET MANUAL does not disable recognition of the
incoming transfer character-set announcer, and translation from
the corresponding character-set to your current file
character-set. To disable that, use SET ATTRIBUTE CHARACTER-SET
OFF.
SET SEND CHARACTER-SET-SELECTION { AUTOMATIC, MANUAL }
Again AUTOMATIC is the default, causing the behavior described
above when you give a SET { FILE, TRANSFER } CHARACTER-SET
command. Use MANUAL to allow you to specify the transfer and
file character-sets independently.
SHOW CHARACTER-SETS
Tells settings of { SEND, RECEIVE } CHARACTER-SET-SELECTION.
Normally, however, it is more convenient to leave automatic switching
active, and change any associations that are not appropriate for your
application, area, or country. The commands are:
SHOW ASSOCIATIONS
This command lists all the associations in each direction: for
each possible transfer character-set, it lists the associated
file character-set, and vice versa. These are two separate and
independent lists.
ASSOCIATE TRANSFER-CHARACTER-SET name1 [ name2 ]
Changes the association for the transfer character-set name1 to
be the file character-set name2. If name2 is omitted, automatic
switching is disabled for this transfer character-set only.
ASSOCIATE FILE-CHARACTER-SET name1 [ name2 ]
Changes the association for the file character-set name1 to be
the transfer character-set name2. If name2 is omitted,
automatic switching is disabled for this file character-set
only.
_________________________________________________________________
6.6. UNICODE
C-Kermit 7.0 adds support for Unicode, the Universal Character Set,
for:
* File Transfer (SEND, RECEIVE, GET, etc)
* Terminal connection (CONNECT)
* Unguarded file capture (LOG SESSION)
* Unguarded file transmission (TRANSMIT)
* Local file character-set conversion (TRANSLATE)
C-Kermit is not, however, a "Unicode application" in the sense that
its commands, messages, or user interface are Unicode. Rather, it is
"Unicode aware" in its ability to handle and convert Unicode text in
the course of file transfer and terminal connection, and you can also
use Kermit to convert local files between Unicode and other character
sets. TLA's:
BMP - Base Multilingual Plane
BOM - Byte Order Mark
CJK - Chinese, Japanese, and Korean
ISO - International Standards Organization
TLA - Three-Letter Acronym
UCS - Universal Character Set
UTF - UCS Transformation Format
Unicode and ISO 10646 are the coordinated and compatible corporate and
international standards for the Universal Character Set (UCS). Unlike
single-byte and even most multibyte character sets, the UCS can
represent all characters in every existing writing system. A flat
plain-text file encoded in some form of UCS can contain any mixture of
English, Spanish, Italian, German, Hebrew, Arabic, Greek, Russian,
Armenian, Georgian, Japanese, Chinese, Korean, Vietnamese, Tibetan,
Hindi, Bengali, Tamil, Thai, Ethiopic, and so on, plus scientific and
mathematical notation, as well as texts in Runes, Ogham, Glagolitic,
and other historic scripts.
The UCS already covers these scripts and many more, but it's an
evolving standard with efforts underway to accommodate even more
languages and writing systems. Support is growing for native UCS use
on many platforms and in many applications. The goal of the framers of
the UCS is for it to replace ASCII, the ISO Latin Alphabets, ISCII,
VISCII, the Chinese, Japanese, and Korean (CJK) multibyte sets, etc,
as well as the many private character sets in use today, in other
words to become *the* Universal Character Set.
Until that time, however, conversions between existing sets and the
UCS will be necessary when moving text between platforms and
applications. Now Kermit can help.
_________________________________________________________________
6.6.1. Overview of Unicode
For a more complete picture, please visit:
[539]http://www.unicode.org/
and access the various online introductions, FAQs, technical reports,
and other information. For greater depth, order the latest version of
the published Unicode Standard. The following overview contains a
great many oversimplifications and perhaps an opinion or two.
At present, the UCS is a 16-bit (2-byte) character set, but with
provisions to grow to a 4-byte set. UCS-2 refers to the two-byte set,
also called the Base Multilingual Plane (BMP), in which each character
has 16 bits, and therefore there are 2^16 = 65536 possible characters.
The first 128 characters are the same as US ASCII (C0 control
characters and DEL included), the next 32 are the C1 control
characters of ISO 6429, and the next 96 are the Right Half of ISO
8859-1 Latin Alphabet 1. The remaining tens of thousands of characters
are arranged newly for the UCS, usually (but not always) in sections
corresponding to existing standards, such as ISO Latin/Cyrillic, often
plus additional characters not appearing in the existing standards due
to lack of space (or other reasons).
ISO 10646 allows for additional planes, e.g. for Egyptian
hieroglyphics or ancient (or other esoteric) CJK characters, but these
planes are not yet defined and so we will say nothing more about them
here, except that their use will require the 4-byte form of UCS,
called UCS-4, in some form (more about "forms" in [540]Section 6.6.2).
Unicode and ISO 10646 are constantly under revision, mainly to add new
characters. The Unicode revision is denoted by a version number, such
as 1.0, 1.1, 2.0, 3.0. The ISO 10646 standard revision is identified
by Edition (such as ISO 10646-1 1993), plus reference to any
amendments. The first versions of these standards included encodings
for Korean Hangul syllables (Jamos); these encodings were changed in
version 1.1 of Unicode and by Amendment 5 to ISO 10646-1. The Unicode
Technical Committee and the ISO acknowledge that this was a bad thing
to do, and promise never change encodings or character names again,
since this poses serious problems for conformance and data
interchange.
A UCS-2 value is customarily written like this:
U+xxxx
where "xxxx" represents four hexadecimal digits, 0-9 and A-F. For
example, U+0041 is "A", U+00C1 is A-acute, U+042F is uppercase
Cyrillic "Ya", U+FB4F is Hebrew Ligature Alef Lamed, and U+FFFD is the
special character that means "not a character".
Most characters from widely-used alphabetic writing systems such as
the West European ones, Cyrillic, Greek, Hebrew, Vietnamese, etc, are
available in "precomposed" form; for example Uppercase Latin Letter A
with Acute Accent is a single character (as it is in Latin-1).
However, the UCS also permits composition of a base character with one
or more nonspacing diacritics. This means the same character can be
represented in more than one way, which can present problems in many
application areas, including transfer and character-set conversion of
text.
Conversion from ASCII or Latin-1 to UCS-2 text is "trivial": simply
insert a NUL (0) byte before each ASCII or Latin-1 byte. Converting in
the reverse direction (provided the UCS-2 file contains only U+0000 to
U+00FF) is equally simple (if we ignore the issue of composition):
remove every second (NUL) byte. Conversion of other character sets to
and from UCS, however, requires tables or algorithms specific to each
set. Nevertheless, the relatively transparent upwards compatibility
from ASCII and Latin-1, in which a very large share of the world's
textual data is encoded, gives the UCS an entree onto existing
platforms.
But the 2-byte format and the preponderance of NUL and other control
bytes in UCS-2 text pose problems for current applications and
transmission methods. And to make matters worse, different hardware
platforms store UCS-2 characters in different byte order. Thus a UCS-2
file transferred by FTP (or accessed via NFS, etc) between two
computers with different architecture might have its bytes in the
wrong order (or worse; see [541]Section 6.6.5.1 ).
_________________________________________________________________
6.6.2. UCS Byte Order
Consider the number 1. In an 8-bit byte, this would be represented by
the following series of 0- and 1-bits:
+-----------------+
| 0 0 0 0 0 0 0 1 |
+-----------------+
Therefore in a 16-bit "word" the representation might be:
+-----------------+-----------------+
| 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 |
+-----------------+-----------------+
Now consider the number 256, which is 2 to the 8th power. The binary
representation is 100000000 (1 followed by 8 zeros). 256 would go into
a 16-bit word like this:
+-----------------+-----------------+
| 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 0 |
+-----------------+-----------------+
When a computer works this way, it is said to be Big Endian, meaning
it puts the most significant (biggest) byte first (on the "left") in a
16-bit word, and the least significant byte second (on the right).
However, some other computers have the opposite arrangement, called
Little Endian, in which 1 is:
+-----------------+-----------------+
| 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 0 |
+-----------------+-----------------+
and 256 is:
+-----------------+-----------------+
| 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 |
+-----------------+-----------------+
Computers such as Sparc, MIPS, PA-RISC, and PowerPC are Big Endian,
whereas the PC and the Alpha are Little Endian. Endianness has never
been an issue with 7- or 8-bit characters, but it is with UCS
characters. It can be a tricky business to share or transfer a UCS-2
file between two different kinds of computers.
To alleviate (but not entirely solve) the problem, UCS-2 files are
supposed to begin with the Unicode character U+FEFF, Zero-Width
No-Break Space (ZWNBS). This is a kind of "no-op" (note: any such
assertion must normally be qualified with many "but ifs" and "excepts"
which are omitted here in the interest of brevity). If the bytes are
reversed the ZWNBS becomes U+FFFE, which is not (and never will be) a
defined UCS character. U+FEFF at the beginning of a UCS file is
therefore called a Byte Order Mark, or BOM.
Any application that creates a UCS-2 (or UTF-16, or UCS-4) file should
include a BOM, and any application that reads one should test for a
BOM, and if one is found, infer the byte order from it. This is a
convention, however -- not a standard or a requirement -- and
applications vary in their ability to handle BOMs and "backwards"
UCS-2 files.
Note that a BOM is useful only at the beginning of a file. If you
append one UCS-2 file to another, and both have BOMs, the internal BOM
is no longer a BOM. And if the byte orders of the two files differ,
then either the first part or the second will be backwards. (Various
other undesirable effects might also occur, not discussed here.)
_________________________________________________________________
6.6.2. UCS Transformation Formats
UCS textual data can be modified in various ways for transmission or
storage. Any officially sanctioned method of doing this is called a
UCS Transformation Format, or UTF. One such method, called UTF-16, is
essentially identical with UCS-2 except that it designates certain
code values as "escape sequences" (called surrogate pairs) to access
characters in other planes without having to use full UCS-4. We won't
discuss UTF-16 further here, since at the moment there are no other
planes. Several other UTF's (such as UTF-1, UTF-2, and UTF-7) have
fallen into disuse and are not discussed here. The most important
transformation format today is UTF-8.
UTF-8, so called because it "serializes" UCS-2 data into a stream of
8-bit bytes, is designed to allow the UCS to work with present-day
communications gear, computers, and software. The most important
properties of UTF-8 are that byte order is constant (no byte swapping)
and all (7-bit) ASCII characters represent themselves. Therefore
conversion between ASCII and UTF-8 is no conversion at all, and
applications or platforms (such as Plan 9 from Bell Labs) that use
UTF-8 "for everything" can still run traditional ASCII-only
applications and be accessed from them. In particular, unlike UCS-2,
ASCII characters are not padded with NUL bytes. But also unlike UCS-2,
there is no transparency for Latin-1 or any other non-ASCII character
set. Every non-ASCII UCS-2 character is represented by a sequence of 2
or 3 UTF-8 bytes. Thus UTF-8 is more compact than UCS-2 for text
containing a preponderance of ABC's (or other ASCII characters), about
the same as UCS-2 for other alphabetic scripts (Cyrillic, Roman,
Greek, etc), and larger than UCS-2 for Chinese, Japanese, and Korean.
The UTF-8 uncoding of the UCS has been adopted by the Internet as the
preferred character set for new applications, and is gradually being
retrofitted into traditional applications like FTP ([542]RFC 2640).
_________________________________________________________________
6.6.3. Conformance Levels
Although the Unicode and ISO 10646 standards both describe the same
character set, these standards differ in many ways, including their
stated requirements for conformance and their classification of
conformance levels.
Kermit has always abided by ISO character-set standards, including ISO
character-set designation and invocation methods. In adapting Unicode,
therefore, we had to choose from among the available ISO designations
which, in turn, correspond with ISO 10646 conformance levels. At
present, Kermit claims the lowest conformance level, 1, meaning
(roughly) that it does not handle combining forms and it does not
handle Korean Hangul Jamos (just as, at present, it does not handle
Korean in general). Note that ISO 10646 Conformance Levels 1 and 2
sidestep the issue of the code changes for Korean Hangul by announcing
non-support for Hangul regardless of encoding.
ISO 10646 Conformance Level 1 is approximately equivalent to Unicode
Normalization Form C (described in Unicode Technical Report 15,
incorporated into Unicode 3.0).
As noted in [543]Section 6.6.2, Kermit does not claim to support
UTF-16 at the present time, hence the UCS-2 nomenclature. Kermit
treats surrogates just as if they were any other UCS-2 characters,
rather than as escapes to other planes, which means that (except when
converting between UCS-2 and UTF-8) they are translated to "error"
characters, since (a) no other planes are defined yet (and if they
were, no other character sets supported by Kermit would encode their
characters), and (b) no valid surrogate character corresponds to any
other UCS-2 character.
A minor yet significant aspect of Unicode 3.0 and some recent
perturbation of ISO 10646-1 (probably Amendment 18, "Symbols and Other
Characters") is the addition of the Euro Sign at U+20AC. As noted in
[544]Section 6.0, Kermit's "Euro compliance" includes conversion
between Latin Alphabet 9 and various PC code pages. Text can also be
converted between UCS-2 or UTF-8 and any other Euro-compliant
character set (Latin-9, CP858, CP1250, CP1252) without loss of the
Euro Sign.
_________________________________________________________________
6.6.4. Relationship of Unicode with Kermit's Other Character Sets
Kermit's character sets are divided into two groups: single-byte sets
(such as Roman, Hebrew, Cyrillic, Greek) and multibyte (various
Japanese sets). The two groups are distinct since one normally would
not expect to convert Kanji ideograms to Roman (or other) letters, or
vice versa.
Unicode character-set conversion works with both groups, but obviously
the result depends on the repertoires of the source and destination
character-sets both including the characters in the file. For example,
you can translate a Hungarian text file between Latin-2 and Unicode,
but not between (say) Unicode and Latin/Greek. By the same token you
can convert Japanese text from Shift-JIS or EUC or JIS-7 to Unicode
and back, but you can't convert the same file to (say) Latin-1 if it
contains Japanese characters.
JIS-7 is equivalent to DEC Kanji and ISO-2022-JP except that the
latter two do not support halfwidth Katakana. Kermit treats all
three of these sets the same way, i.e. as JIS-7.
As noted, Kermit presently does not handle combining diacritics, and
so will not correctly convert UCS files that use them into a
single-byte character set. For example, if a UCS file contains Latin
Capital Letter A (U+0041) followed by Combining Acute Accent (U+0301),
the result will be a two-character sequence, A followed by another
character. This is what is meant by Conformance Level 1. (The
situation grows worse with multiple diacritics, since they can occur
in any order.)
A higher level of conformance is possible, in which "canonical
equivalences" are handled via algorithms and databases, at some
(perhaps considerable) cost in performance, since a fair amount of
additional code must be executed for every character during data
transfer (database lookup, sorting of combining sequences into
canonical order, etc). This can be added in future releases if there
is a need (but in many cases, pre- and postpostprocessing might be a
better option).
Within these constraints, Kermit converts between the UCS and its
other character sets. For example, a mixture of Russian and English
(and/or Dutch, or Latin) text can bet converted between the UCS and
ISO Latin/Cyrillic or KOI-8. But since Kermit does not presently
support Arabic character-set conversion, the new availability of UCS
conversion does not mean that Kermit can convert from Arabic UCS text
to some other character set, because Kermit does not support any other
character set that includes Arabic. Ditto for Thai, Armenian,
Georgian, Tibetan, Chinese, Korean, etc. However, Kermit CAN convert
Arabic (or any other script) between UCS-2 and UTF-8.
Considering Cyrillic more carefully, note that the UCS also contains
numerous Cyrillic characters not found in any of the Cyrillic sets
(ISO Latin/Cyrillic, KOI8, CP866, etc) that Kermit supports;
characters needed for Abkhasian, Yakut, Tatar, Bashkir, Altaic, Old
Church Slavonic, etc; UCS text containing any of these historic or
"extended" Cyrillic characters can not be converted to any of Kermit's
current single-byte Cyrillic sets without loss. The situation is
similar for Greek, Hebrew, etc, and even worse for Japanese since
Unicode contains thousands of Kanjis that are lacking from the
Japanese character sets based on JIS X 0208, such as EUC-JP, JIS-7,
and Shift-JIS.
In general, when converting from UCS to a single-byte set, there is
always the possibility of data loss, just as there is when converting
from any larger set to a smaller one. For example, if a UCS file
contains Devanagari characters, these characters will be lost when
converting to (say) Latin-1, just as Roman vowels with acute accents
are lost when converting from Latin-1 (an 8-bit set) to German ISO 646
(a 7-bit set).
_________________________________________________________________
6.6.5. Kermit's Unicode Features
C-Kermit can convert between UCS-2 or UTF-8 and any of its other
character sets, and also between UCS-2 and UTF-8. When converting
between UCS-2 or UTF-8 and a non-Unicode character set (such as
Latin-1), the UCS Line Separator (LS, U+2028) and Paragraph Separator
(PS, U+2029) characters are converted to the appropriate line
terminator (CR, LF, or CRLF). When converting from a non-Unicode set
to UCS-2 or UTF-8, however, line terminators are not converted to LS
or PS. This is in accordance with the recommendations of Unicode
Technical Report #13.
When C-Kermit starts, it tests the native byte order of the computer.
You can see the result in the SHOW FEATURES or SHOW FILE display. It's
also available in the variable \v(byteorder): 0 means Big Endian, 1
means Little Endian.
When UCS-2 is involved in file transfer or translation, the following
commands tell C-Kermit what to do about byte order:
SET FILE UCS BYTE-ORDER { BIG-ENDIAN, LITTLE-ENDIAN }
This is for reading UCS-2 files that don't have a BOM, and also
for writing UCS-2 files. If this command is not given, the
machine's native byte order is used when writing UCS-2 files,
and also when reading UCS-2 files that don't have a BOM.
SET FILE UCS BOM { ON, OFF }
This setting is used when creating UCS-2 files. A BOM is added
at the beginning by default. Use OFF to not add the BOM. This
command has no affect when writing files.
COPY /SWAP-BYTES sourcefile destinationfile
Use this for fixing a UCS-2 file whose bytes are in the wrong
order.
Use SHOW FILE to display the FILE UCS settings.
Please note, again, that C-Kermit's user interface, including its
script language, is not internationalized in any way. String
comparisons, case conversion, and so on, work only for US ASCII
(comparisons for equality work with other sets, but not
lexically-greater-or-less-than or caseless comparisons; even
comparisons for equality can fail when composed characters or byte
order are involved). String functions such as \findex() and
\fsubstring() that reference byte positions do just that; they won't
work with UTF-8 text that contains any non-ASCII characters, and they
will not work with UCS-2 text at all since they use C strings
internally, which are NUL-terminated. These are just a few examples to
illustrate that neither Unicode nor any other character-set beyond
ASCII is supported at the user-interface, command, or scripting level
in this version of C-Kermit.
_________________________________________________________________
6.6.5.1. File Transfer
Kermit supports both UCS-2 and UTF-8 as file and transfer character
sets in text-mode file transfer.
To select UCS-2 or UTF-8 as a file character-set, use:
SET FILE CHARACTER-SET { UCS2, UTF8 }
If you want to send a UCS-2 text file (or save an incoming file in
UCS-2 format), tell Kermit to:
SET FILE CHARACTER-SET UCS2
and if you want to send a UTF-8 text file (or store an incoming file
in UTF-8 format), tell Kermit to:
SET FILE CHARACTER-SET UTF8
When sending UCS-2 files, Kermit determines the byte order from the
BOM, if there is one (and if there is a BOM, it is stripped, i.e. not
sent). If there is no BOM, the byte order is the one specified in the
most recent SET FILE UCS BYTE-ORDER command, if any, otherwise the
computer's native byte order is assumed. When storing incoming files
as UCS-2, the byte order is according SET FILE UCS BYTE-ORDER, if
given, otherwise the native one; a BOM is written according to SET
FILE UCS BOM.
A transfer character-set should be chosen that includes all of the
characters in the source file. So, for example, if you are sending a
UCS-2 file containing only German-language text, your transfer
character-set can be Latin-1, Latin-2, Latin-9, UCS-2, or UTF-8. But
if you are sending a file that contains a combination of Hebrew and
Greek, your transfer character-set must be UCS-2 or UTF-8 if you don't
want to lose one script or the other. Furthermore, the transfer
character-set must be one that is supported by the receiving Kermit
program. Since UCS support is new, it is possible that the other
Kermit program (if it supports character sets at all) does not support
it, but does support single-byte sets such as Latin-1, Latin/Cyrillic,
etc.
To select UCS-2 or UTF-8 as a transfer character-set, use:
SET TRANSFER CHARACTER-SET { UCS2, UTF8 }
It is up to the receiving Kermit program to convert the transfer
format to its own local format, if necessary. If it does not
understand the UTF-8 or UCS-2 transfer character-set, and your file
can not be adequately represented by any single-byte transfer
character-set (such as Latin-1 or Latin/Cyrillic) then, if UTF-8
format is acceptable on the receiving computer, use UTF-8 as the
transfer character-set, with the receiver told to "set unknown-char
keep", or with the sender told to "set attribute char off". If you
want the file to be stored in UCS-2 format at the receiver, send it it
binary mode if the source file is also UCS-2, or else use the
TRANSLATE command (next section) to convert it to UCS-2 first, then
send it in binary mode. You should not use UCS-2 as a transfer
character-set in text-mode transfers to Kermit programs that don't
support it, because they are likely to corrupt the result the same way
FTP would (see the final paragraph of this section).
When UCS-2 is the transfer character set, it always goes into Kermit
packets in Big Endian format, with no BOM. As always, the transfer
character-set is announced by the sender to the receiver. The
announcement for UCS-2 is "I162" (ISO Registration 162 = UCS-2 Level
1) and by definition it is Big Endian (the standards say that when
UCS-2 is serialized into bytes, the order must be Big Endian). The
announcement for UTF-8 is "I190" (UTF-8 Level 1).
When receiving a file whose transfer character-set is UCS-2 or UTF-8,
you must choose the appropriate file character set for the result.
There is no way Kermit can do this for you automatically, since UCS
data can be in any script at all, or any combination.
In general, UTF-8 or UCS-2 should be chosen as a transfer
character-set if the source file is also encoded in some form of UCS
and it contains more than one script. But there are other situations
where where UTF-8 or UCS-2 offer advantages. For example, suppose the
source file is on a NeXTstation and the destination file is on VMS.
Both the NeXT and the DEC Multinational character sets include the
French OE digraph, but Latin-1 does not. Therefore French words
containing this character might not arrive intact when Latin-1 is the
transfer character-set, but will with UTF-8 or UCS-2, since the UCS
includes the OE digraph (but so does Latin-9).
UCS-2 should be chosen as a transfer character-set only for Japanese
text files that contain a large preponderance of Kanji, since in this
case (and only this case) UCS-2 (two bytes per Kanji) is more
efficient than UTF-8 (three bytes per Kanji). The same will be true
for Chinese and Korean when they are supported by Kermit. UCS-2 should
never be used as a transfer character-set with a transfer partner that
does not support UCS-2 since this can cause file corruption (see last
paragraph in this section).
Note that Kermit's repeat-count compression is 100% ineffective for
UCS-2, and is also ineffective for multibyte characters in UTF-8 and
EUC-JP; this is because repeat-compression is a transport-level
mechanism that operates on a per-byte basis; it has no knowledge of
the distinction between a byte and a character.
When C-Kermit starts, it sets up associations ([545]Section 6.5) for
incoming files whose transfer character sets are UCS-2 or UTF-8
appropriately for the platform so that the file character-set for the
incoming file is UCS-2 in Windows and UTF-8 elsewhere. Otherwise,
C-Kermit does not make any default associations for UCS-2 or UTF-8,
but of course you may add or change associations to suit your needs
and preferences by including the appropriate ASSOCIATE commands in
your Kermit startup file. For example, if you are a PC user and deal
only with text written in Greek and English, you can:
ASSOCIATE TRANSFER-CHARACTER-SET UTF8 CP869
ASSOCIATE TRANSFER-CHARACTER-SET UCS2 CP869
ASSOCIATE FILE-CHARACTER-SET CP869 UTF8
Note that when file transfer involves conversion between a single-byte
character set and UCS-2 or UTF-8, the file-transfer thermometer and
estimated time left might be inaccurate, since they are based on the
source file size, not the transfer encoding. This is purely a cosmetic
issue and does not effect the final result. (And is not, strictly
speaking, a bug; Kermit protocol presently includes no method for the
sender to furnish an "estimated transfer size" to the receiver, and in
any case any such guess could be as far off as the file size, given
the many other factors that come into play, such as compression and
prefixing).
A caution about FTP and UCS-2. As noted previously, if you transfer a
UCS-2 file with FTP in binary mode between two computers with opposite
Endianness, the result will have its bytes in the wrong order.
However, if you use FTP to transfer a UCS-2 file in "ascii" (text)
mode to ANY computer, even if it is identical to yours, the result
will be corrupted because FTP's line-terminator conversions do not
account for UCS-2. The same holds when sending from a UCS-aware Kermit
program to an older Kermit program in text mode with a transfer
character-set of UCS-2. So use UCS-2 as a transfer character-set ONLY
with a UCS-2-aware Kermit partner.
_________________________________________________________________
6.6.5.2. The TRANSLATE Command
In Kermit versions that have Unicode support included, TRANSLATE now
always goes through Unicode; that is, the source set is converted to
UCS-2 and thence to the target set. This is a major improvement, since
in prior releases, C-Kermit had to pick the "most appropriate"
transfer character-set as the intermediate set, and this would result
in the loss of any characters that the source and target sets had in
common but were lacking from the intermediate set (for example the OE
digraph when translating from NeXT to DEC MCS through Latin-1). This
never happens when Unicode is the intermediate set because Unicode is
a superset of all other character sets supported by Kermit. A more
dramatic example would be translation between Cyrillic PC code page
866 and KOI8-R ([546]Section 6.4); formerly all the line- and
box-drawing characters would be lost (since ISO 8859-5 does not have
any); now the ones that these two sets have in common are preserved.
UCS-2 and UTF-8 are now both supported as source-file and
destination-file character sets by C-Kermit's TRANSLATE command, for
example:
translate oofa.txt ucs2 latin1 oofa-l1.txt
translates oofa.txt from UCS-2 to Latin-1, storing the result as
oofa-l1.txt. Similarly:
translate oofa.txt utf8 latin1 oofa-l1.txt
translate oofa.txt latin1 ucs2 oofa-ucs2.txt
translate oofa.txt latin1 utf8 oofa-utf8.txt
translate oofa.txt ucs2 utf8 oofa-utf8.txt
translate oofa.txt utf8 ucs2 oofa-ucs2.txt
Treatment of the UCS-2 BOM is exactly the same as for file transfer.
Note that if a UCS-2 source file is in the "wrong" byte order and
lacks a BOM, and you don't tell Kermit about it with SET FILE UCS
BYTE-ORDER, the result of the translation is total gibberish. Recall
that you can use COPY /SWAP-BYTES to switch the byte order of an
errant UCS-2 file (or any other file for that matter, if you can think
of a reason to). Also note that:
translate oofa.txt ucs2 ucs2 new.txt
Produces a result in the native (or SET FILE UCS) byte-order as long
as oofa.txt has a BOM.
As a side benefit of the Unicode work, the TRANSLATE command now works
for the first time also for all Japanese character sets that Kermit
supports. In other words, if you have a Japanese text file in any of
the following encodings:
EUC-JP
Shift-JIS
JIS-7
UCS-2
UTF-8
You can use the TRANSLATE command to convert to any other encoding
from the same list.
_________________________________________________________________
6.6.5.3. Terminal Connection
The CONNECT command now allows UTF-8 as a local or remote terminal
character-set:
SET TERMINAL CHARACTER-SET { ..., UTF8 } { ..., UTF8 }
SET TERMINAL REMOTE-CHARACTER-SET { ..., UTF8 }
SET TERMINAL LOCAL-CHARACTER-SET { ..., UTF8 }
(Recall that Kermit's terminal character-set has two "ends" -- the set
used on the host to which Kermit is connected, and the set used on the
local keyboard and screen.)
UCS-2 is not supported as a terminal character-set (either end) since
(a) it is not used that way anywhere to our knowledge, and (b) the
problems of Endianness and the high likelihood of loss of
synchronization make it impractical. (Telecommunications is
byte-oriented; if one byte, or any odd number of bytes, is lost
because of buffer overruns, circuit resets, etc (or likewise if a
burst of noise appears that takes the guise of an odd number of
bytes), the byte order of the subsequent data stream will be
backwards; unlike UTF-8 and traditional byte-based character sets,
UCS-2 is not "self synchronizing".)
UTF-8 does not have byte-order or synchronization problems and is
growing in popularity as a terminal character set as well as in other
application areas. It allows a single terminal session to use multiple
scripts (Roman, Cyrillic, Greek, etc) without ISO 2022 character-set
switching (which terminal emulators like Kermit 95 can handle but few
host applications understand or use), and meshes nicely with the
Unicode screen fonts that are beginning to appear.
UTF-8 was first used in Plan 9 and soon will be available in Linux. It
will probably spread from there (Unicode in some form is, of course,
also used in Windows NT, but only internally -- not for access from
outside).
To use UTF-8 or any other character set that uses 8-bit bytes in your
terminal session, be sure to tell C-Kermit to:
SET TERMINAL BYTESIZE 8
SET COMMAND BYTESIZE 8
SET PARITY NONE
(or use the shortcut command, EIGHTBIT, which does all three at once).
In a setup where your local Kermit program uses a single-byte
character set such as PC Code Page 850 and the remote host uses UTF-8:
SET TERM CHAR UTF8 CP850
or:
SET TERM REMOTE CHAR UTF8
SET TERM LOCAL CHAR CP850
all works as expected. UTF-8 text on the remote displays correctly on
your screen, and when you type CP850 characters, they are translated
to UTF-8 sequences for transmission, and the echo from the host is
translated from UTF-8 back to CP850. Telnet negotiations and
autodownload take place before any character-set translation and work
as before. The session log (if text mode was selected for it) contains
only the local terminal character-set. And so on.
Kermit merely supplies translations from UTF-8 to your local terminal
character-set (this includes treating UTF-8 Line Separator and
Paragraph separator as CRLF). However, Kermit does does not, at
present, perform "canonicalization" of composed sequences, nor does it
automatically execute bidirectionality algorithms for display of
mixed-direction text (e.g. Hebrew and English). Such presentation
issues, like all others in the terminal-host regime, are left to the
host.
By the way, C-Kermit also allows UTF-8 to be the local end of the
terminal character-set, but so far this code is not tested, since we
don't have a UTF-8 console or terminal to work with. However, it can
be stated without doubt that C-Kermit's key mapping will not work for
UTF-8 values, since (a) the key map is indexed by 8-bit byte values
and (b) C-Kermit reads keystrokes a byte at a time (these comments do
not apply to K95, which has direct access to the keyboard and can read
"wide" keycodes and uses them to index a "wide" keymap).
Restrictions: As noted, the CONNECT command does not support UCS-2 as
a REMOTE TERMINAL character-set. Neither does it support the Japanese
sets EUC-JP, JIS-7, and Shift-JIS. Support for the Japanese sets (and
possibly Chinese and Korean too) might be added in a future release.
Since the TRANSMIT command (next section) uses the same REMOTE
TERMINAL character-sets as the CONNECT command, it has the same
restrictions.
_________________________________________________________________
6.6.5.4. The TRANSMIT Command
As described in Chapter 15 of [547]Using C-Kermit and [548]Section
4.21 of this document, the TRANSMIT command can be used to upload a
file without protocol, more or less as if you were typing it on your
keyboard while connected to the host. When TRANSMITting in text mode,
the file's character set is converted to the host's unless you have
SET TERMINAL CHARACTER-SET TRANSPARENT, or you include the new
TRANSMIT switch, /TRANSPARENT.
Before C-Kermit 7.0, the file character-set was assumed to be the same
as the local end of the terminal character-set, and the TRANSMIT
command used the same translations as the CONNECT command, ignoring
the file character-set.
In C-Kermit 7.0, that assumption (a poor one to begin with) can no
longer be made, since UCS-2 can be a file character-set but not a
terminal character-set. So now the file's character-set is given by
your most recent SET FILE CHARACTER-SET command. The host's character
set is the remote end of your most recent SET TERMINAL CHARACTER-SET
command:
SET TERMINAL CHARACTER-SET remote-set [ local-set ]
or:
SET TERMINAL REMOTE-CHARACTER-SET remote-set
The TRANSMIT command converts each source-file character from the FILE
character-set to the REMOTE TERMINAL character-set, and then transmits
the translated characters according to your SET TRANSMIT preferences
(Chapter 15).
If you have SET TRANSMIT ECHO ON, and the host is echoing the
transmitted characters, the echos are converted from the remote
terminal character-set to the local terminal character-set.
[ A picture would help... ]
Confused? Let's work through an example. Suppose your local computer
is a NeXTstation, on which text files are encoded in the NeXT
character set, and that the remote computer is a Data General AViiON,
which uses the Data General International character set. Further
suppose that you are logged in to the NeXT from a VT220 terminal which
uses the DEC Multinational character set.
You need to convert the file from NeXT encoding to DG encoding and
convert the echoes from DG encoding to DEC encoding. So on the NeXT,
tell C-Kermit to:
eightbit
set file character-set next
set term character-set dg-international dec-mcs
transmit /text nextdata.txt
(This assumes you have some sort of collection process already set up
on the Data General, such as a text editor or the venerable "cat >
foo". The EIGHTBIT command is equivalent to SET TERMINAL BYTESIZE 8,
SET COMMAND BYTESIZE 8, SET PARITY NONE.)
To further complicate matters, suppose your local terminal character
set is the same as the remote one, so you don't need terminal
character-set translation, but you need to TRANSMIT a file that is in
a different character set and you want it translated to the host set.
In this case, use SET TERM CHARACTER-SET to actually specify the
character set used on each end, rather than specifying TRANSPARENT:
eightbit
set file character-set ucs2
set term character-set latin1 latin1
transmit /text ucs2data.txt
The distinction between:
SET TERMINAL CHARACTER-SET xxx yyy
(where xxx and yyy are the same set) and:
SET TERMINAL CHARACTER-SET TRANSPARENT
is new to C-Kermit 7.0, but affects only the TRANSMIT command.
The TRANSMIT command currently does nothing special with UCS-2/UTF-8
Line and Paragraph Separator characters; more experience is required
to find out how these behave in a genuine Unicode terminal-host
setting.
Restrictions: As noted, the TRANSMIT command translates from the FILE
character-set to the REMOTE TERMINAL character-set. This rules out
translations to any character set that is not supported as a REMOTE
TERMINAL character-set, such as UCS-2, EUC-JP, JIS-7, and Shift-JIS.
_________________________________________________________________
6.6.5.5. Summary of Kermit Unicode Commands
Specifying file character-set and byte order:
SET FILE CHARACTER-SET { ..., UCS2, UTF8 }
REMOTE SET FILE CHARACTER-SET { ..., UCS2, UTF8 } (See next
section)
SET FILE UCS BOM { ON, OFF }
SET FILE UCS BYTE-ORDER { BIG-ENDIAN, LITTLE-ENDIAN }
Specifying the transfer character-set:
SET TRANSFER CHARACTER-SET { ..., UCS-2, UTF-8 }
REMOTE SET TRANSFER CHARACTER-SET { ..., UCS-2, UTF-8 }
Specifying the terminal character-set:
SET TERMINAL CHARACTER-SET { ..., UTF8 } { ..., UTF8 }
SET TERMINAL REMOTE-CHARACTER-SET { ..., UTF8 }
SET TERMINAL LOCAL-CHARACTER-SET { ..., UTF8 }
Displaying settings:
SHOW FILE
SHOW TRANSFER
SHOW TERMINAL
SHOW CHARACTER-SETS
Commands that use these settings include:
SEND, RECEIVE, GET, etc.
CONNECT
TRANSMIT
LOG SESSION
Converting files:
TRANSLATE infile { ..., UCS-2, UTF-8 } { ..., UCS-2, UTF-8 }
outfile
COPY /SWAP-BYTES infile outfile
_________________________________________________________________
6.7. Client/Server Character-Set Switching
A simple mechanism has been added to allow the client to change the
server's FILE CHARACTER-SET:
REMOTE SET FILE CHARACTER-SET name
The client asks the server to change its file character-set to
the one given. The name must match one of the server's file
character-set names. For convenience, C-Kermit uses its own
file character-set keyword list for parsing this command so you
can use ? for help and Tab or Esc for completion. However,
since the server might have a different repertoire (or even use
different names for the same sets), C-Kermit accepts any string
you supply and sends it to the server. The server, if it
supports this command (C-Kermit 7.0 and K95 1.1.19 do), sets
its file character-set as requested, and also disables
automatic character-set switching ([549]Section 6.5). If the
server does not support this command or if it does not support
the given character set, the REMOTE SET FILE CHARACTER-SET
command fails.
Here's an example that sends a Japanese text file encoded in Shift-JIS
to a server using every combination of Kermit's Japanese-capable file
and transfer character sets:
dcl \&x[] = euc ucs2 utf8 ; transfer character-sets
dcl \&y[] = eu uc ut ; 2-letter abbreviations for them
dcl \&f[] = shift euc jis7 ucs2 utf8 ; file character-sets
dcl \&g[] = sj eu j7 uc ut ; 2-letter abbreviations
set file char shift-jis ; local file character-set is Shift-JIS
for \%i 1 \fdim(&x) 1 { ; for each transfer character-set...
set xfer char \&x[\%i] ; set it
for \%j 1 \fdim(&f) 1 { ; for each remote file character-set...
remote set file char \&f[\%j] ; set it
if fail exit 1 SERVER REJECTED CHARSET
send /text meibo-sj.html meibo-sj-\&y[\%i]-\&g[\%j].txt ; send the fi
le
if fail exit 1 TRANSFER FAILED
}
}
The Kermit-370 server does not support REMOTE SET FILE CHARACTER-SET,
but since it supports REMOTE KERMIT commands, you can get the same
effect with REMOTE KERMIT SET FILE CHARACTER-SET name.
_________________________________________________________________
7. SCRIPT PROGRAMMING
(Also see [550]Section 2.8, Scripting Local Programs.)
7.0. Bug Fixes
The following script programming bugs were fixed in C-Kermit 7.0:
* IF EXIST and IF DIRECTORY were fixed to properly strip braces from
around their arguments, so "if directory {C:\Program Files}", etc,
would work as expected. However, this means that if the file or
directory name is actually enclosed in braces, the braces must be
doubled.
* The READ command did not fail if the READ file wasn't open; now it
does.
* The READ command refused to read the last or only line of a file
if it did not end with a proper line terminator; now it does.
* The END command, when given from within a SWITCH statement, did
not exit from the current macro or command file; instead it just
terminated the SWITCH.
_________________________________________________________________
7.1. The INPUT Command
7.1.1. INPUT Timeouts
The description of the INPUT command on page 422 fails to mention the
following two points about the timeout (which apply to C-Kermit 6.0
and later):
1. "INPUT -1 text" (or "INPUT \%x text", where \%x is any variable
whose value is -1 or less) means "wait forever". This form of the
INPUT command fails only if it is interrupted, since it will never
time out.
2. INPUT 0 performs a nonblocking read of material that has already
arrived but has not yet been read, and succeeds immediately if the
target string is found, or fails immediately if it is not found.
The same points apply to MINPUT. REINPUT ignores its timeout
parameter.
_________________________________________________________________
7.1.2. New INPUT Controls
The following new INPUT controls were added in version 7.0:
SET INPUT AUTODOWNLOAD { ON, OFF }
Explained in [551]Section 7.7.
SET INPUT CANCELLATION { ON, OFF }
This governs whether an INPUT command can be canceled by
"pressing any key" on the keyboard. Normally it can be, in
which case the INPUT command fails immediately and \v(instatus)
is set to 2, indicating interruption. SET INPUT CANCELLATION
OFF disables keyboard cancellations; thus if the search text is
not encountered, the INPUT command will run for its entire
timeout interval. SET INPUT CANCELLATION OFF does not disable
interruption by Ctrl-C, however; every command needs an
emergency exit. (If you really want to disable interruption by
Ctrl-C, use SET COMMAND INTERRUPTION OFF.)
Also see [552]Section 7.2 for any new variables related to INPUT.
_________________________________________________________________
7.1.3. INPUT with Pattern Matching
C-Kermit 7.0 allows INPUT, MINPUT, and REINPUT targets to be a pattern
(explained in [553]Sections 1.19 and [554]4.9). This solves a
long-standing problem illustrated by the following scenario: a certain
company has a bank of TCP/IP modem servers, with hostnames server1,
server2, server3, and so on. Each server's prompt is its name,
followed by a colon (:), for example "Server72:". Without INPUT
patterns, it would be rather difficult to wait for the prompt. The
brute force approach:
minput 20 Server1: Server2: Server3: ... (enumerating each one)
is subject to failure whenever a new server is added. A more subtle
approach:
input 20 Server
if fail ...
input 2 :
is liable to false positives, e.g. "Welcome to the XYZ Corp Modem
Server. Please read the following message:"...
With patterns, you can match the prompt with "Server*:" (which doesn't
solve the "false positives" problem, but certainly is more compact
than the brute force method), or with more specific patterns such as
"Server[1-9]:" and "Server[1-9][0-9]:", or equivalently:
Server{[1-9],[1-9][0-9]}:
meaning the word "Server" followed by a single digit (1-9) or by two
digits representing a number from 1 to 99, followed by a colon.
INPUT pattern matching has been added in a way that does not interfere
with existing scripts. No new commands or switches are used. The
simple rule is: if an INPUT search target is the argument of the (new)
\fpattern() function, it is a pattern. Otherwise it is taken
literally, as before. For example:
input 5 a*b
searches for an 'a' followed by an asterisk ('*'), followed by a 'b'.
But:
input 5 \fpattern(a*b)
searches for an 'a' followed by anything at all up to and including
the first 'b'. This means that any search target to INPUT, MINPUT, or
REINPUT can be a pattern or a literal string, and in particular that
MINPUT can accommodate any mixture of patterns and literal strings.
In selecting patterns, note that:
* A leading '*' is always implied so there is no need to include
one.
* A trailing '*' is meaningless and ignored.
* A '*' by itself matches the first character that arrives.
A syntax note: If your pattern is a selection list, meaning a list of
alternatives separated by commas and enclosed in braces, then the
outer braces will be stripped by various levels of parsers, so you
must include three of each:
input 10 \fpattern({{{abc,mno,xyz}}})
Note that this is equivalent to:
minput 10 abc mno xyz
except for the setting of the \v(minput) variable.
And a caution: INPUT pattern matching has a limitation that you
probably never noticed with literal-string matching, namely that there
is a limit on the size of the match. For example, if the pattern is
"a*b", the match will succeed if the 'a' and 'b' are not separated by
more than (say) 8K bytes, but will fail if they are farther apart than
that. In such cases, it better to use two INPUTs (e.g. "input 10 a"
and then "input 100 b").
_________________________________________________________________
7.1.4. The INPUT Match Result
The result of any INPUT, MINPUT, or REINPUT command, no matter whether
the search targets are patterns or literal strings, is available in
the new \v(inmatch) variable. For example:
minput 10 cat \fpattern([dh]og)
if success echo MINPUT matched "\v(inmatch)"
This is especially useful when a pattern was matched, since it makes
the string that matched the pattern available to Kermit; there would
be no way to get it otherwise.
After an INPUT command, you can view all the INPUT-related variables
by typing "show variables in" (abbreviate as "sho var in"), which
shows the values of all built-in variables whose names start with
"in".
_________________________________________________________________
7.2. New or Improved Built-In Variables
\v(blockcheck)
Current BLOCK-CHECK setting, 1, 2, 3, or 4. 4 is the code for
BLANK-FREE-2.
\v(byteorder)
The machine's byte order: 0 = Big Endian, 1 = Little Endian.
\v(cmdbufsize)
The length of the command buffer, which is the maximum size for
a macro, a command, a variable, or anything else in C-Kermit's
script language.
\v(ctty)
The device name of C-Kermit's controlling (login) terminal.
\v(filename)
Described in [555]Sections 4.1 and [556]4.2.
\v(filenumber)
Described in [557]Sections 4.1 and [558]4.2.
\v(filespec)
As of C-Kermit 7.0, contains fully qualified filenames rather
than (usually) relative ones.
\v(return)
Now holds the END n value of the macro that most recently
returned, in case END was used rather than RETURN.
\v(editor)
Pathname of preferred text editor
\v(editopts)
Command-line options for editor
\v(editfile)
File most recently edited
\v(browser)
Pathname of preferred Web browser
\v(browsopts)
Command-line options for Web browser
\v(browsurl)
URL most recently given to Web browser
\v(dialtype)
Type of call most recently placed (see [559]Section 2.1.11).
\v(kbchar)
The character, if any, that was typed at the keyboard to to
interrupt the most recent PAUSE, SLEEP, WAIT, MSLEEP, or INPUT
command; empty if the most recent such command was not
interrupted from the keyboard.
\v(lockdir)
UNIX only - The name of the UUCP lockfile directory, if known,
otherwise "(unknown)".
\v(lockpid)
UNIX only - PID of process that owns the communication port
that you tried to open with a SET LINE command that failed
because the port was in use, otherwise empty. This variable is
set with every SET LINE command.
\v(cx_time)
If no connection (SET HOST, SET LINE, DIAL, TELNET, etc) is
active, this is 0. If a connection is active, this is the
number of seconds since the connection was made.
\v(hwparity)
If hardware parity is in effect, this variable gives its value,
such as "even" or "odd" (in which case, the \v(parity) variable
will be "none"). Otherwise this variable is empty.
\v(serial)
Current serial port settings in 8N1 format ([560]Section 2.10).
\v(errno)
In UNIX, the current value of the C runtime errno variable,
which is quite volatile (meaning that often an "interesting"
error code can be overwritten by some other library call or
system service that sets errno before you have a chance to look
at it). In VMS, the error code returned by the system or
library call that most recently failed (success codes are not
saved). Not available in other operating systems.
\v(errstring)
The UNIX or VMS system error message that corresponds to
\v(errno). Not available in all OS's. Also see
[561]\ferrstring().
\v(setlinemsg)
The error message, if any, from the most recent SET LINE, SET
PORT, SET HOST, TELNET, or other connection-making command.
This is not necessarily the same as \v(errstring) since these
commands might fail without generating a system error code, for
example (in UNIX) because a lockfile existed indicating the
device was assigned by another user.
\v(exitstatus)
The exit status C-Kermit would return if it exited now.
\v(pexitstat)
The exit status of the inferior process most recently invoked
by C-Kermit (by RUN, !, REDIRECT, SEND /COMMAND, etc). In VMS,
this code can be given to \ferrstring() to get the
corresponding error message (in UNIX, program/command return
codes are not the same as system error codes). Not available in
operating systems other than UNIX and VMS. See [562]Section
4.2.5 for details.
\v(inmatch)
The incoming string of characters, if any, that matched the
most recent INPUT, REINPUT, or MINPUT command.
\v(intime)
The number of milliseconds (thousandths of seconds) it took for
the most recent INPUT command to find its match, or -1 if no
INPUT command has been given yet. If the INPUT command timed
out, the value is approximately equal to 1000 times the INPUT
timeout. If INPUT failed for some other reason, the value is
undefined (\v(instatus) gives INPUT completion status). If your
version of C-Kermit is built without high-precision
floating-point timers, this number will always be a multiple of
1000.
\v(inwait)
The number of seconds specified as the timeout in the most
recent INPUT command.
\v(dialsuffix)
Dialing suffix for use during PDIAL sequence; see [563]Section
2.1.10.
\v(pid)
UNIX, VMS, and K95 only. C-Kermit's primary process ID,
numeric, decimal. If you want to show it in hex, use
\fn2hex(\v(pid)) If you want to show it in octal, use
\fn2octal(\v(pid)).
\v(printer)
Current printer name or SET PRINTER value.
\v(p_ctl)
Control prefix char \v(p_8bit) 8-bit prefix char (if parity not
none)
\v(p_rpt)
Repeat prefix char (if repeat compression enabled)
\v(herald)
Kermit's version herald
\v(test)
Kermit's test version, if any, or 0 if this is not a test
version. Typical values for test versions are "Alpha.03" or
"Beta.14".
\v(sendlist)
The number of entries in the SEND-LIST, 0 if none. Note:
entries do not necessarily correspond to files, since an entry
might contain wildcards. Also note that the value does not go
back to 0 after the files in the list are sent. To reset this
variable, use CLEAR SEND-LIST. The purpose of this variable is
to determine if a SEND command, when given without any
filenames, will be legal. Example:
xif \v(sendlist) { send } else { send oofa.txt }
\v(trigger)
If the most recent CONNECT session was terminated automatically
by a trigger, this variable contains the trigger value.
\v(ty_ln)
TYPE line number (during TYPE)
\v(ty_lc)
TYPE line count (after TYPE)
\v(ty_mc)
TYPE match count (after TYPE)
\v(xferstat)
Status of most recent file transfer:
-1: No transfer yet
0: Succeeded
1: Failed
\v(xfermsg)
If the most recent file transfer failed, this is the reason. If
it succeeded, \v(xfermsg) is an empty string.
\v(tftime)
Total elapsed time of most recent file transfer operation, in
seconds.
\v(textdir)
Directory that holds (or is supposed to hold) Kermit text files
such as installation instructions, release notes, update notes,
read-me files, "beware" files, etc.
\v(name)
The name with which the Kermit program was invoked, e.g.
"kermit", "wermit", "k95", "k2", etc (see [564]Section 9.1).
\v(osname)
Name of operating system on computer where C-Kermit is running,
obtained at runtime (from uname or equivalent).
\v(osversion)
Version of operating system on computer where C-Kermit is
running, obtained at runtime (from uname or equivalent).
\v(osrelease)
Release of operating system on computer where C-Kermit is
running, obtained at runtime (from uname or equivalent).
\v(model)
The specific hardware model of the computer where C-Kermit is
running, if known.
\v(math_pi)
The value of Pi (see [565]Section 7.23)
\v(math_e)
The value of e (see [566]Section 7.23)
\v(math_precision)
How many significant digits in a floating-point number.
\v(f_count)
Result of the most recent FILE COUNT (FCOUNT) command.
\v(f_error)
Numeric error code of most recent FILE command.
\v(f_max)
Maximum number of files open simultaneously.
The math constants are given in the precision of underlying computer's
floating-point arithmetic.
Note the distinction between \v(osname), \v(osversion), and
\v(platform); the latter refers to the platform for which and/or upon
which C-Kermit was built, as opposed to the one on which it is
actually running. Also note that each operating system can, and
probably will, interpret and fill in the os* variables differently, or
not at all.
The SHOW VARIABLES command now accepts a variable name, prefix, or
pattern:
show variables Shows all variables.
show variables t Shows all variables that start with "t".
show variables *ver* Shows all variables whose names contain "ver".
show variables *ver Ditto (an implied "*" is appended).
_________________________________________________________________
7.3. New or Improved Built-In Functions
The following new file-i/o functions are explained in [567]Section
1.22.
\f_status(channel) Status of file open on channel
\f_pos(channel) Read/write (byte) pointer of given file
\f_line(channel) Current line of file
\f_handle(channel) Handle of file
\f_eof(channel) Whether given file is at EOF
\f_getchar(channel) Read a char from given file
\f_getline(channel) Read a line from given file
\f_getblock(channel,n) Read a block from given file
\f_putchar(channel,c) Write a char to given file
\f_putline(channel,string) Write a line to given file
\f_putblock(channel,string) Write a block to given file
The following new date-time-related functions are explained in
[568]Section 1.6:
\fday() Returns day of week of given date
\fnday() Returns numeric day of week of given date
\ftime() Returns time portion of given date-time
\fntime() Converts time to seconds since midnight
\fn2time() Converts seconds since midnight to hh:mm:ss
\fcvtdate(date-time) Converts free-format date to yyyymmdd hh:mm:ss
\fdayofyear(date-time) Converts date to yyyyddd (day-of-year) format
\fdoy(date-time) Synonym for \fdayofyear()
\fdoy2date(dayofyear) Converts yyyyddd to yyyymmdd
\fmjd(date-time) Converts free-format date to Modified Julian Date
\fmjd2date(mjd) Converts modified Julian date to yyyymmdd
The new floating-point arithmetic functions are explained in
[569]Section 7.23. f1 and f2 are floating-point (real) numbers; d is
the number of decimal places to show:
\ffpabsolute(f1,d) Absolute value of f1
\ffpadd(f1,f2,d) f1 + f1
\ffpcosine(f1,d) Cosine of f1
\ffpdivide(f1,f2,d) f1 divided by f2
\ffpexp(f1,d) e to the f1 power
\ffpint(f1) Integer part of f1
\ffplog10(f1,d) Log base 10 of f1
\ffplogn(f1,d) Natural log of f1
\ffpmaximum(f1,f2,d) Maximum of f1 and f2
\ffpminimum(f1,f2,d) Minimum of f1 and f2
\ffpmodulus(f1,f2,d) Modulus of f1 and f2
\ffpmultiply(f1,f2,d) Product of f1 and f2
\ffpraise(f1,f2,d) Raise f1 to power f2
\ffpround(f1,d) Round f1 to d places
\ffpsine(f1,d) Sine of f1
\ffpsqrt(f1,d) Square root of f1
\ffpsubtract(f1,f2,d) f2 - f1
\ffptangent(f1,d) Tangent of f1
Integer number functions:
\fabsolute(n)
Absolute value of integer n.
\frandom(n)
Returns a random integer between 0 and n-1.
\fradix(s,n1,n2)
If the string s is an integer in radix n1, the result is the
same number expressed in radix n2, where n1 and n2 may be any
number from 2 through 36, expressed as decimal numbers, or
variables (etc) that evaluate to decimal numbers. For the
source and result, the digits of any radix, r, are the first r
characters in the sequence 0-9,a-z (case doesn't matter for the
letters). The string s may have a sign, + or -; if it starts
with a minus (-) sign, the result also has a minus sign.
The \fradix() function does not work with floating-point numbers. It
does not reveal the internal storage format of a number; for example,
\fradix(-1,10,16) is -1, not something like FFFFFFFFFF. If all three
arguments are not given, or if n1 or n2 are not numbers between 2 and
36 inclusive, or s is not a number in radix n1, an error occurs and
the empty string is returned. \fradix() also does not offer
extended-precision arithmetic; number values are limited to those
expressed as a long integer in the architecture of the underlying
computer, usually 32 or 64 bits. If you give it an argument whose
absolute value is larger than can be held in an unsigned long, the
result is -1.
The next four are shorthand functions for decimal/hexadecimal and
decimal/octal number conversion:
\fn2hex(n)
Returns the hexadecimal (base 16) representation of the integer
n. This is different from \fhexify(s), which treats its
argument as a string rather than a number. The result is always
left-padded with 0's to make its length even. Examples:
\n2hex(0) = "00" \fhexify(0) = "30"
\n2hex(255) = "ff" \fhexify(255) = "323535"
\n2hex(256) = "0100" \fhexify(256) = "323536"
\fhex2n(x)
Converts hexadecimal number x to decimal equivalent decimal
number. This is the inverse of \fn2hex(). Equivalent to
\fradix(s,16,10).
\fn2octal(n)
Returns the octal (base 8) representation of the number n.
Examples:
\n2octal(0) = "0"
\n2oct(255) = "377"
\n2oct(256) = "400"
Equivalent to \fradix(n,10,8).
\foct2n(n)
Returns the decimal representation of the given octal number,
n. The inverse of \fn2octal(). Equivalent to \fradix(n,8,10).
String functions:
\s(name[n:m])
Equivalent to \fsubstring(\m(name),n,m) ([570]Section 7.24).
\:(name[n:m])
Equivalent to \fsubstring(name,n,m) (where "name" is any
\-quantity) ([571]Section 7.24).
\fleft(s,n)
The leftmost ncharacters of string s; equivalent to
\fsubstring(s,1,n).
\fstripx(string,char)
Returns the part of the string up to the rightmost occurrence,
if any, of the given character. The default character is period
(.) Examples:
\fstripx(foo/bar,/) = "foo"
\fstripx(foo/bar/baz,/) = "foo/bar"
\fstripx(autoexec.bat,.) = "autoexec"
\fstripx(autoexec.bat) = "autoexec"
\fstripx(fstripx(foo/bar/baz,/),/) = "foo"
\flop(string,character)
Returns the portion of the string starting after the first
occurrence of the given character. The default character is
period (.) Examples:
\flop(autoexec.bat) = "bat"
\flop(baz.foo/bar) = "foo/bar"
\flop(baz.foo/bar,/) = "bar
\fstripn(string,n)
Returns the string with ncharacters removed from the end.
Example:
\fstripn(12345678,3) = "12345"
(For more discussion of \fstripx(), \fstripn(), and \flop() see
[572]Section 4.2.3).
\fb64encode(s)
Returns the Base-64 encoding of the string s.
\fb64decode(s)
Returns the decoding of the Base-64 string s. Fails if s is not
a Base-64 string, or if its length is not a multiple of 4. Note
that if any of the result bytes are null (0), the result string
stops there. There is no way to represent strings that contain
null bytes in C-Kermit (the same is true for \funhexify()).
\fword(s1,n,s2,s3)
Extracts word number nfrom string s1. By default, a "word" is
any sequence of ASCII letters or digits; nis 1-based. If nis
omitted, "1" is used. Examples:
\fword(one two three) = "one"
\fword(one two three,1) = "one"
\fword(one two three,2) = "two"
\fword(one two three,3) = "three"
and:
\fword(\v(dialresult),2) = "31200"
is "31200" if \v(dialresult) is (e.g.) "CONNECT
31200/ARQ/V32/LAPM/V42BIS".
If you include s2, this replaces the default break set. For
example, suppose you have a string \%a whose value is:
$150.00 $300.00 $39.95
and you want each dollar amount to be a word; use:
\fword(\%a,\%n,{ })
This returns dollar amount number \%n, e.g. "$300.00" for \%n =
2. "{ }" denotes a space (you must enclose it in braces,
otherwise it is squeezed out). Note that ASCII control
characters are always included in the break set; you don't have
to specify them (and you can't not specify them).
The optional s3 argument lists characters (even control
characters) that normally would be considered separators that
you want included in words. So the dollars-and-cents example
could also be handled this way:
\fword(\%a,\%n,,$.)
in other words, use the default separator list, but remove "$"
and "." from it so they will be considered part of a word.
\fsplit(s1,&a,s2,s3)
This is like \fword(), except instead of extracting and
returning a particular word from string s1, it counts the words
and optionally assigns them to the array whose identifying
letter, a-z, is given after the "&" in the second argument,
with the first word going into element 1, the second into
element 2, and so on. The rules regarding break and include
lists (s2 and s3) are exactly the same as for \fword().
\fsplit() returns the number of words that were assigned, which
is either the number of words in the string, or the dimension
of the array, whichever is less. If the array is not declared,
\fsplit() creates it and returns a number which is both the
number of words in s1 and the dimension of the new array.
Examples:
declare \&w[20] ; (Optional.)
...
read \%s ; \%s is "This is a sentence with seven words."
...
echo "\fsplit(\%s)" ; This would print "7".
echo "\fsplit(\%s,&w)" ; Ditto, and also assigns them to array \&w[].
echo "\&w[7]" ; This would print "words".
If the line contained fields that were delimited by colon (:),
you would use \fsplit(\%s,&w,:). If the fields were delimited
by comma, then you would use \fsplit(\%s,&w,{,}); in this case
the literal comma must be enclosed in braces to distinguish it
from the comma that separates function arguments. To get a word
count without loading an array, but still specify break and/or
include lists, leave the array argument empty:
echo "\fsplit(\%s,,:)" ; Use colon as the separator.
WARNINGS:
1. If you use the same array repeatedly, \fsplit() leaves any
trailing members undisturbed. For example:
dcl \&w[10]
\fsplit(1 2 3 4 5,&w) ; Sets \&w[1] thru \&w[5].
\fsplit(a b c,&w) ; Sets \&w[1]-[3] leaving [4]-[5] as they were.
2. If you allow \fsplit to create the array (by not declaring it
first), it is dimensioned to the number of elements it was
created with:
\fsplit(1 2 3,&x) ; Creates an array \&x[] with 3 elements.
\fsplit(a b c d e,&x) ; This overflows the array.
Thus if you want to use \fsplit() repeatedly on the same array,
either dimension it in advance to the maximum expected size
(and then some -- more efficient), or else destroy it after
each use (to allow for unexpectedly large arguments). Example
using a dynamic array:
fopen /read \%c some-file
if fail ...
set function error on ; See [573]Section 7.12
while true {
dcl \&w[] ; Destroy \&[w] each time thru the loop
fread /line \%c \%a
if fail break
asg \%x \fsplit(\%a,&w)
if fail ...
; (do what you want with \&w[] here...)
}
fclose \%c
\frindex(s1,s2,n)
The "n" argument to \frindex() now works consistently (in
mirror image) with the corresponding \findex() argument. In
each case, the (n-1)-most characters of s2 are ignored in the
search; for findex, this means the starting position of the
search is n (the default nis 1, and 0 is treated like 1). For
\frindex() it means the default starting point is:
length(s2) - length(s1) - n (with the same defaults for n).
\fsearch(pattern,string[,position])
Exactly like \findex(), except with a pattern (see [574]Section
7.9) rather than a literal string.
\frsearch(pattern,string[,position])
Exactly like \frindex(), except with a pattern rather than a
literal string.
File Functions:
\ffiles(), \fnextfile()
It is no longer necessary to copy the file list to an array
before use, as shown on p.398 of [575]Using C-Kermit 2nd
Edition. \ffiles() and friends now make their own safe copies
of the file list. Thus constructions like the following are now
possible:
for \%i 1 \ffiles(*.txt) 1 { send \fnextfile() }
The same is true for the new function \frfiles(),
\fdirectories(), and \frdirectories(), described in
[576]Section 4.11.3.
But note that each reference to \fnextfile() still gets you the
next file. So "if newer \fnextfile() foo.txt send \fnextfile()"
compares one file's age with that of foo.txt, and then sends an
entirely different file. If you're going to refer to the same
file more than once, assign it to a variable:
asg \%f \fnextfile()
if newer \%f foo.txt send \%f
(note: assign, not define).
Also note that \ffiles(), \frfiles(), \fdirectories(), and
\frdirectories() all now accept on optional 2nd argument: the
name of an array to load with the resulting file or directory
list, explained in [577]Section 4.11.3. So you can also load an
array with the filelist when you need to refer to the same file
more than once:
for \%i 1 \ffiles(*,&a) 1 { if newer \&a[\%i] foo.txt send \&a[\%i] }
\fpermissions(file)
Returns the platform-specific permissions string for the file,
such as "-rw-rw-r--" in UNIX or "(RWE,RWE,RE,E)" in VMS.
\fdirname(f)
Given a file specification f, this function returns the
complete pathname of directory the file is in.
Array Functions:
\fdimension(&a)
Returns the dimension declared for the array whose identifying
letter, a-z, or special character "_" or "@", is given after
the "&" in the argument. If the array is not declared, 0 is
returned. Note that when used with the macro argument vector
array, \&_[] (see [578]Section 7.5), the value of this function
is one less than \v(argc), and when used with the C-Kermit
command-line argument vector array, \&@[], it is equal to the
\v(args) variable. Examples:
echo \fdimension(&a) ; Not declared.
0
declare \&a[12] ; Now it's declared.
echo \fdim(&a)
12
\farraylook(pattern,arrayname)
Looks in the given array for the pattern and returns the index
of the first element that matches, if any, or -1 if none match.
The arrayname can include a range specifier to restrict to
search to a segment of the array, e.g.
\farraylook(*xyz*,&a[32:63]). For greater detail see
[579]Section 7.10.7.
\ftablelook(keyword,arrayname[,delimiter])
Looks in the given "table", which must be sorted, for the given
keyword. Returns the index of the table element that uniquely
matches the given keyword, or -1 if none match, or -2 if more
than 1 match. For greater detail see [580]Section 7.10.7.
Other new functions:
\fip2hex(s)
Converts a dotted decimal IP address to an 8-digit hexadecimal
number. \fip2hex(128.59.39.2) = 803b2702.
\fhex2ip(x)
Converts an 8-digit hexadecimal IP address to dotted decimal
form, e.g. \fhex2ip(803b2702) = 128.59.39.2. The inverse of
\fip2hex().
\fcommand()
\frawcommand()
These run an external command and return its output; see
[581]Section 4.2.8.4.
\fdialconvert(s)
s is a phone number in either literal or portable format (not a
dialing directory entry name). The function returns the dial
string that would actually be used when dialing from the
current location (after processing country code, area code, and
other SET DIAL values).
\ferrstring(n)
Returns the system error message associated with the (numeric)
error code n. UNIX and VMS only. Use in conjunction with
\v(errno) or \v(pexitstat). See [582]Section 4.2.5 for a usage
example. Note: This function doesn't work in Windows because
there is not a consistent error-code-to-message mapping; error
code "x" means something completely different depending on
whether it comes from the C runtime library, Winsock, a
Windows-32 API, TAPI, etc,
\fpattern(s)
Used in INPUT, REINPUT, and MINPUT commands to denote search
strings that are to be treated as patterns rather than
literally.
Also see [583]Section 7.8 on built-in help for functions.
_________________________________________________________________
7.4. New IF Conditions
IF AVAILABLE feature command
Executes the command if the given feature is available.
Presently used only to determine if specific authentication and
encryption options are available. Type "if available ?" to see
which features may be tested.
IF FLOAT f1 command
Executes command if f1 is a legal floating point number (which
includes integers). Use this to preverify arguments for the
\ffp...() floating-point arithmetic functions, e.g. "if float
\%1 echo \ffpint(\%1)".
IF == n1 n2 command
Synonym for "if =" (numeric equality). Note that as of C-Kermit
7.0, this and all other numeric comparison operators also work
for floating-point numbers.
IF != n1 n2 command
Executes the command if n1 and n2 are both numbers or variables
containing numbers and the value of n1 is not equal to the
value of n2. This is equivalent to "if not = n1 n2".
IF <= n1 n2 command
Executes the command if n1 and n2 are both numbers or variables
containing numbers and the value of n1 is less than or equal to
the value of n2. This is equivalent to "if not > n1 n2".
IF >= n1 n2 command
Executes the command if n1 and n2 are both numbers or variables
containing numbers and the value of n1 is greater than or equal
to the value of n2. Equivalent to "if not < n1 n2".
IF COMMAND word command
Executes the command if word is a built-in C-Kermit command.
Example:
if not command copy define { copy run copy \%1 \%2 }".
This defines a COPY macro that runs an external COPY command if
COPY is not already a built-in command.
IF LOCAL command
Executes the command if Kermit is in local mode, i.e. if it has
a SET LINE, SET PORT, or SET HOST (TELNET, RLOGIN, etc) device
or connection open. Does not execute the command if in remote
mode.
IF MATCH string pattern command
Executes the command if the string matches the pattern. For a
description of the syntax for the pattern, see [584]Section
4.9.1. If you want to test if the string contains pattern, use
IF \fsearch(pattern,string).
IF OPEN { DEBUG-LOG, SESSION-LOG, TRANSACTION-LOG, ... } command
Executes the command if the given file is open, fails if it is
not open. Type IF OPEN ? for a complete list of files that can
be checked (all the files that can be opened with the OPEN or
LOG commands).
IF QUIET command
Executes the command if SET QUIET is ON, and does not execute
it if SET QUIET is OFF. Example: IF NOT QUIET ECHO { This is a
message.}.
IF READABLE name
Succeeds if name is the name of an existing file or directory
that is readable.
IF WRITEABLE name
Succeeds if name is the name of an existing file or directory
that is writeable, e.g.:
if not writeable \v(lockdir) echo Please read installation instructions!
IF FLAG command
This tests a user-settable condition, which can mean anything
you like. SET FLAG ON causes subsequent IF FLAG commands to
succeed; SET FLAG OFF causes them to fail. One way to use it
would be for debugging your scripts; precede any debugging
statements with IF FLAG. Then SET FLAG on to debug your script,
SET FLAG OFF to run it without debugging. Another common use is
for causing an inner loop to cause an outer loop to exit.
IF C-KERMIT command
C-Kermit, but not Kermit 95 or MS-DOS Kermit, executes the
command.
IF K-95 command
Kermit 95, but not C-Kermit or MS-DOS Kermit, executes the
command.
IF MS-KERMIT command
MS-DOS Kermit, but not C-Kermit or Kermit 95, executes the
command.
_________________________________________________________________
7.5. Using More than Ten Macro Arguments
The \v(argc) variable now gives the actual number of arguments, even
if the number is greater than 9:
C-Kermit> define xx echo \v(argc)
C-Kermit> xx a b c d e f g h i j k l m n o p q r s t u v w x y z
27
Remember that \v(argc) includes the name of the macro itself, so it is
always at least 1, and is always 1 greater than the actual number of
arguments. As in versions 6.0 and earlier, if more than 9 arguments
are given, only the first nine are assigned to the variables \%1..\%9.
The \&_[] array, discussed on page 353 of [585]Using C-Kermit, 2nd ed,
now holds all the arguments, up to some implementation-dependent limit
(64 or greater), rather than only the first 9. To illustrate: the
following macro tells the number of arguments it was called with and
then prints them:
define show_all_args {
local \%i
echo \&_[0] - Number of arguments: \feval(\v(argc)-1)
for \%i 1 \v(argc)-1 1 { echo \flpad(\%i,3). "\&_[\%i]" }
}
Within a macro \&_[0], like \%0, contains the name of the macro.
At top level, the \&_[] array is filled as follows:
* If the first argument on the C-Kermit command line was a filename,
or C-Kermit was invoked from a "Kerbang" script ([586]Section
7.19), element 0 contains the filename, and elements 1 through
\v(argc)-1 hold the remaining command-line arguments.
* Otherwise the program name goes in element 0, and elements 1
through \v(argc)-1 hold any arguments that were included after
"--" or "="
The new \%* variable, when used within a macro, is replaced by the
text that followed the macro name in the macro invocation. If no
arguments were given, \%* is replaced by the empty string. Examples:
C-Kermit> define xx echo [\%*]
C-Kermit> define \%a oofa
C-Kermit> xx
[]
C-Kermit> xx \%a
[oofa]
C-Kermit> xx a
[a]
C-Kermit> xx a b
[a b]
C-Kermit> xx a b c
[a b c]
C-Kermit> xx a b c d e f g h i j k l m n o p q r s t u v w x y z
[a b c d e f g h i j k l m n o p q r s t u v w x y z]
Note that \%* can not be used at top level, since Kermit does not have
access to the raw command line (only to its elements separately, after
they have been processed by the shell and the C library).
C-Kermit 7.0 also adds a SHIFT command:
SHIFT [ number ]
Shifts the macro arguments (except argument 0) the given number
of places to the left and adjusts \v(argc) accordingly. The
default number is 1.
To illustrate, suppose macro XXX is invoked as follows:
xxx arg1 arg2 arg3
Then inside XXX, \%1 is "arg1", \%2 is "arg2", and \%3 is "arg3".
After a SHIFT command is given inside XXX, then \%1 is "arg2", \%2 is
"arg3", and \%3 is empty. \%0 (the name of the macro) remains
unchanged.
If more than 9 arguments were given, then arguments are shifted into
the \%1..9 variables from the argument vector array.
At top level, the SHIFT command operates on the \&_[] array and \%1..9
variables; the \&@[] array is not affected. See [587]Section 7.16 for
details.
The \%* variable is not affected by the SHIFT command.
_________________________________________________________________
7.6. Clarification of Function Call Syntax
Spaces are normally stripped from the front and back of each function
argument; to prevent this enclose the argument in braces:
\fsplit(\%a,&a,{ })
However, function calls that contain spaces can make trouble when the
function is to be used in a "word" field, since space separates words.
For example:
for \%i 1 \fsplit(\%a,&a,{ }) 1 {
echo \%i. "\&a[\%i]"
}
In most cases, the trouble can be averted by enclosing the function
reference in braces:
for \%i 1 {\fsplit(\%a,&a,{ })} 1 {
echo \%i. "\&a[\%i]"
}
or by replacing spaces with \32 (the ASCII code for space):
for \%i 1 \fsplit(\%a,&a,\32) 1 {
echo \%i. "\&a[\%i]"
}
Braces are also used in function calls to indicate grouping. For
example:
\fsubstring(abcd,2,2) = "bc"
But suppose "abcd" needed to contain a comma:
\fsubstring(ab,cd,2,2)
This would cause an error, since "cd" appears to be the second
argument, when really you want the first "2" to be the second
argument. Braces to the rescue:
\fsubstring({ab,cd},2,2) = "b,"
Similarly, leading and trailing spaces are stripped from each
argument, so:
\fsubstring( abcd ,2,2) = "bc"
but braces preserve them:
\fsubstring({ abcd },2,2) = "ab"
Given these special uses for braces, there is no way to pass literal
braces to the function itself. For example:
\fsubstring(ab{cd,2,2)
causes an error.
So if you need a function to include braces, define a variable
containing the string that has braces. Example:
define \%a ab{cd
\fsubstring(\%a,2,2) = "b{"
If the string is to start with a leading brace and end with a closing
brace, then double braces must appear around the string (which itself
is enclosed in braces):
define \%a {{{foo}}}
\fsubstring(\%a) = "{foo}"
This also works for any other kind of string:
define \%a {{ab{cd}}
echo \fsubstring(\%a) = "ab{cd"
_________________________________________________________________
7.7. Autodownload during INPUT Command Execution
As of 6.1 / 1.1.12, C-Kermit can be told to look for incoming Kermit
(or Zmodem) packets during execution of an INPUT command. By default
(for consistency with earlier releases), this is not done. You can
enable this feature with:
SET INPUT AUTODOWNLOAD ON
(and disable it again with OFF.)
One possible use for this feature is as a server mode with a time
limit:
INPUT 3600 secret-string-to-end-the-INPUT-command
In this example, any GET, SEND, or REMOTE commands received within one
hour (3600 seconds) of when the INPUT command was issued will be
executed. Here's another example, in which we want to stay open until
11:30pm, or until interrupted by seven consecutive Ctrl-C (\3)
characters:
INPUT 23:30:00 \3\3\3\3\3\3\3
The INPUT AUTODOWNLOAD setting is displayed by SHOW SCRIPTS or SHOW
INPUT.
_________________________________________________________________
7.8. Built-in Help for Functions.
Beginning in C-Kermit 7.0, you may obtain a description of the calling
conventions and return values of any built-in function, such as
\fsubstring(), with the new HELP FUNCTION command; give the function's
name without the leading "\f", e.g. "help func substring". You can use
?, completion, and abbreviation in the normal manner.
_________________________________________________________________
7.9. Variable Assignments
7.9.1. Assignment Operators
Programmers accustomed to languages such as C or Fortran might find
Kermit's method of assigning values to variables unnatural or awkward.
Beginning in C-Kermit 7.0, you can use the following alternative
notation:
.name = value is equivalent to DEFINE name value
.name := value is equivalent to ASSIGN name value
.name ::= value is equivalent to ASSIGN name \feval(value)
When the command begins with a period (.), this indicates an
assignment. The name can be a macro name, a \%{digit,letter} variable,
or an array element. There can be space(s) between "." and the name.
Examples:
.\%a = This is a string ; Same as "define \%a This is a string"
echo \%a
This is a string
.xxx = \%a ; Same as "define xxx \%a"
echo \m(xxx)
\%a
.xxx := \%a ; Same as "assign xxx \%a"
echo \m(xxx)
This is a string
declare \&a[2] ; Use with arrays...
define \%i 2
.\&a[1] = first
.\&a[\%i] = second
The following sequence illustrates the differences among three levels
of evaluation:
.\%x = 2 ; Define a variable to have a numeric value
.\%y = (3 + \%x) ; Define another variable as an arithmetic expression
.xxx = 4 * \%y ; "=" simply copies the right-hand side.
echo \m(xxx)
4 * \%y
.xxx := 4 * \%y ; ":=" evaluates the variables first, then copies.
echo \m(xxx)
4 * (3 + 2)
.xxx ::= 4 * \%y ; "::=" evaluates the expression, then copies.
echo \m(xxx)
20
You can also use this syntax to clear (undefine) a variable:
.\%a = oofa ; Define the variable
echo "\%a"
"oofa"
.\%a ; Clear the variable
echo "\%a"
""
Extra credit: Can you guess what happens below when the file "abc"
does not exist?
fopen /read \%c abc
if fail ...
_________________________________________________________________
7.9.2. New Assignment Commands
Recall the DEFINE and ASSIGN commands, and their hidden counterparts,
_DEFINE and _ASSIGN. The former take the variable name literally, the
latter evaluate the variable-name field to form the variable name
dynamically. Examples:
DEFINE \%x foo ; Sets the value of the variable \%x to "foo".
DEFINE \%a \%x ; Sets the value of the variable \%a to "\%x".
_DEFINE x_\%a \%x ; Sets the value of the variable x_foo to "\%x".
ASSIGN \%a \%x ; Sets the value of the variable \%a to the "foo".
_ASSIGN x_\%a \%x ; Sets the value of the variable x_foo to "foo".
This concept has been carried over to the remaining
variable-assignment commands: EVALUATE, INCREMENT, and DECREMENT:
EVALUATE variablename expression
Evaluates the arithmetic expression and assigns its value to
the variable whose name is given. Example: "eval \%a 1+1"
assigns "2" to \%a.
_EVALUATE metaname expression
Evaluates the arithmetic expression and assigns its value to
the variable whose name is computed from the given metaname.
Example: "eval foo<\%a>::\%1 \%2 * (\%3 + \%4)" assigns the
value of "\%2 * (\%3 + \%4)" to the variable whose name is
computed from "foo<\%a>::\%1".
INCREMENT variablename [ expression ]
Evaluates the arithmetic expression and adds its value to the
value of the variable whose name is given. Example: "increment
\%a".
_INCREMENT metaname [ expression ]
Evaluates the arithmetic expression and adds its value to the
value of the variable whose name is computed from the given
metaname. Example: "_increment Words::\%1.count[\%2]".
DECREMENT variablename [ expression ]
Evaluates the arithmetic expression and subtracts its value
from the value of the variable whose name is given.
_DECREMENT metaname [ expression ]
Evaluates the arithmetic expression and subtracts its value
from the value of the variable whose name is computed from the
given metaname.
WARNING: The syntax of the EVALUATE command has changed since C-Kermit
6.0 and K95 1.1.17. Previously, it did not include a variable name,
only an expression. To restore the old behavior, use SET EVALUATE OLD.
To return to the new behavior after restoring the old behavior, use
SET EVALUATE NEW.
NOTE: There are no analogs to the "_" commands for the operators
described in [588]Section 7.9.1; those operators can not be used to
assign values to variables whose names must be computed.
_________________________________________________________________
7.10. Arrays
C-Kermit 7.0 adds lots of new array-related features, and groups them
together under the NEW ARRAY command:
ARRAY { CLEAR, COPY, DECLARE, DESTROY, RESIZE, SHOW, SORT }
In each of the ARRAY commands, wherever an array name is expected,
"short forms" may be used. For example, all of the following are
acceptable:
array show \&a[] (or SHOW ARRAY...)
array show &a[]
array show a[]
array show &a
array show a
In addition, ranges are accepted in the ARRAY COPY, ARRAY CLEAR, ARRAY
SET, ARRAY SHOW, and ARRAY SORT commands:
array clear \&a[16] ; Clears 16 thru end
array clear &a[16] ; Ditto
array clear a[16] ; Ditto
array clear \&a[16:32] ; Clears 16 thru 32
array clear &a[16:32] ; Ditto
array clear a[16:32] ; Ditto
When using array names as function arguments, you must omit the "\"
and you must include the "&". You may optionally include empty
brackets. Examples:
\fsplit(\%a,a) ; Bad
\fsplit(\%a,\&a) ; Bad
\fsplit(\%a,&a[3]) ; Bad
\fsplit(\%a,&a) ; Good
\fsplit(\%a,&a[]) ; Good
_________________________________________________________________
7.10.1. Array Initializers
Beginning in C-Kermit 7.0, you may initialize an array -- in whole or
in part -- in its declaration:
[ ARRAY ] DECLARE array-name[size] [ = ] [ value1 [ value2 [...] ] ]
For compatibility with versions 5A and 6.0, the ARRAY keyword is
optional. DECLARE can also be spelled DCL.
Initializers are (a) optional, (b) start with element 1, (c) must be
enclosed in braces if they contain spaces, and (d) are evaluated
according to normal rules by the DECLARE command prior to assignment.
Thus the assignments made here are the same as those made by the
ASSIGN command. This allows you to initialize array elements from the
values of other variables. If you actually want to initialize an array
element to variable's name, as opposed to its value, use double
backslashes (as in "\\&a", "\\v(time)", etc).
The size (dimension) of the array is optional. If the size is omitted,
as in "\&a[]", then the array sizes itself to the number of
initializers; if there are no initializers the array is not declared
or, if it was declared previously, it is destroyed. If a size is
given, any extra elements in the initialization list are discarded and
ignored.
NOTE: Unlike in C, the list of initializers is NOT enclosed in braces.
Instead, braces are used to group multiple words together. So:
ARRAY DECLARE \&a[] = { one two three }
would create an array with two elements (0 and 1), with element 1
having the value " one two three ".
Examples:
ARRAY DECLARE \&a[16]
Declares the array \&a with 17 elements (0 through 16), in
which all elements are initially empty. If the array \&a[]
existed before, the earlier copy is destroyed.
ARRAY DECLARE &a[16]
ARRAY DECLARE a[16]
ARRAY DCL \&a[16]
ARRAY DCL &a[16]
ARRAY DCL a[16]
DECLARE \&a[16]
DECLARE &a[16]
DECLARE a[16]
DCL \&a[16]
DCL &a[16]
DCL a[16]
All of the above are the same as the first example.
ARRAY DECLARE \&a[16] = alpha beta {gamma delta}
Declares the array \&a with 17 elements (0 through 16),
initializing \&a[1] to "alpha", \&a[2] to "beta", and \&a[3] to
"gamma delta". The remaining elements are empty.
ARRAY DECLARE \&a[] = alpha beta {gamma delta}
Same as the previous example, but the array is automatically
dimensioned to 3.
ARRAY DECLARE \&a[3] = alpha beta {gamma delta} epsilon zeta
Too many initializers; only the first three are kept.
ARRAY DECLARE \&a[0]
ARRAY DECLARE \&a[]
ARRAY DECLARE &a[]
ARRAY DECLARE &a
ARRAY DECLARE a
DECLARE \&[0]
DECLARE a
DCL a
All of these are equivalent. Each destroys \&a[] if it exists.
Declaring an array with a dimension of 0 is the same as ARRAY
DESTROY arrayname.
ARRAY DECLARE \&a[] = \%1 \%2 \%3
Declares the array \&a with 3 elements (0 through 3),
initializing \&a[1] to the value of \%1, \&a[2] to the value of
\%2, and \&a[3] to the value of \%3. In this case, any
reference to one of these array elements is replaced by the
value of the corresponding \%n variable at the time the
declaration was executed (immediate evaluation; the array
element's value does not change if the initializer variable's
value changes).
ARRAY DECLARE \&a[] = \\%1 \\%2 \\%3
Declares the array \&a with 3 elements (0 through 3),
initializing \&a[1] to the string "\%1", \&a[2] to "\%2", and
\&a[3] to "\%3". In this case any reference to one of these
array elements is replaced by the CURRENT value of the
corresponding \%n variable (deferred evaluation -- the array
element's value follows the value of the initializer variable).
The equal sign (=) preceding the initializer list is optional, but is
recommended for clarity. If you need to initialize element 1 to a
literal equal sign, use two of them, separated by a space, as in this
example:
ARRAY DECLARE \&a[] = = + - * /
Remember, element 0 is not initialized by the DECLARE command. To
initialize element 0, use a regular DEFINE or ASSIGN command:
ARRAY DECLARE \&a[] one two three four five six seven eight nine
DEFINE \&a[0] zero
Finally, remember that every command level has its own local array,
\&_[], containing all the macro arguments (\%0, \%1, ...) for that
level. See [589]Section 7.5 for details.
_________________________________________________________________
7.10.2. Turning a String into an Array of Words
The \fsplit(s1,&a,s2,s3) function assigns the words of string s1 to
successive elements of the array (beginning with element 1) whose
identifying letter, a-z, is given after the "&" in the second
argument, using break and include characters given in s2 and s3. See
[590]Section 7.3 for details.
_________________________________________________________________
7.10.3. Arrays of Filenames
See [591]Section 4.11.3 for news about how \ffiles() and related
functions can assign a list of filenames to an array. To recapitulate
briefly here:
\ffiles(*,&a)
assigns all files that match the first argument to the array denoted
by the second argument. If the array has not been declared, it is
declared automatically, with exactly the number of elements needed to
hold the file list; if it was previously declared, it is destroyed and
reused. The filenames are assigned starting at array element 1.
Element 0 holds the number of files in the list.
The DIRECTORY command ([592]Section 4.5.1) can also create filename
arrays if you give it the /ARRAY: switch; this allows selection
criteria beyond whether the filename matches the given pattern.
All functions and commands that create filename arrays store the
number of filenames, n, as element 0 of the array, and the filenames
as elements 1 through n.
_________________________________________________________________
7.10.4. Automatic Arrays
In a command file or macro, you can now have local (automatic) arrays.
Just give the name followed by empty subscript brackets (no spaces
inside the brackets please) in a LOCAL command, and then declare the
array:
LOCAL \%a \&a[] oofa
ARRAY DECLARE \&a[32] = value1 value2 value3 ...
This declares the scalar variable \%a, the array \&a[], and the macro
name "oofa" to be local, and then declares the new local copy of \&a[]
with 32 elements, perhaps assigning some initial values. When C-Kermit
exits from the command file or macro containing these command, the
previous \&a[] array is restored (and if there was no \&a[] at any
higher level, this will still be true). The process can be repeated to
any level. Thus it is now safe to write scripts or macros containing
arrays without danger of interfering with global arrays of the same
name.
Just as scalars are inherited by lower command levels, so are arrays.
So, for example, if \&a[] is declared at top level, all lower levels
will see it unless they include a "local \&a[]" statement, in which
case all levels at and beneath the level where the LOCAL statement was
executed will see the local copy. This too can be repeated to any
level.
On the other hand, if you DECLARE an array at a lower command level
without also making it LOCAL, this replaces the copy that was declared
at the lowest command level above this one.
_________________________________________________________________
7.10.5. Sorting Arrays
Although arrays can be sorted using FOR loops as shown on page 383 of
Using C-Kermit, 2nd Ed., this involves quite a bit of repetitive
interpretation by the command parser, and so can be slow for large
arrays. For this reason, C-Kermit 7.0 adds a built-in SORT command:
ARRAY SORT [ switches ] array [ array2 ]
Sorts the given array in place. Sorting is strictly lexical
(string based). The array name can be given fully, e.g.
"\&a[]", or the "\" and/or "&" and/or brackets can be omitted,
e.g. "array sort \&a[]", "sort &a", "sort a". Also, a range can
be indicated in the brackets as noted in [593]Section 7.10, to
restrict the sort to a range of elements (equivalent to the
/RANGE switch, described just below), e.g. "array sort
&a[20:30]".
A second array may be specified. If it is, and if it is at least as
big as the first array, it is sorted according to the first array. For
a sample application, see [594]Section 7.10.10.
See [595]Section 1.5 for an explanation of switches. The optional
switches are:
/CASE:{ON,OFF}
/CASE:ON means that alphabetic case is significant in
comparisons; uppercase letters are sorted before lowercase
ones. /CASE:OFF means case is ignored, e.g. "A" is the same as
"a". If this switch is not given, sorting is according the
current SET CASE setting.
/KEY:n
Comparison begins at position n(1-based) in each string. If no
key is given, the entire strings are compared. Only one key can
be given. If an array element is shorter than the key value, n,
that element is considered empty for comparison purposes, and
therefore lexically less than any element at least ncharacters
long.
/NUMERIC
If this switch is included, it means sorting should be numeric,
rather than lexical. The sort key is the string starting at the
key position, skipping any leading blanks or tabs, and then as
much of the string from that point on that fits the definition
of "numeric", terminating at the first character that does not
qualify. A numeric string has an optional sign (+ or -)
followed by one or more digits, and (if your version of Kermit
was built with floating-point support; see [596]Section 7.23 )
zero or one decimal point (period). If both /CASE and /NUMERIC
are given, /NUMERIC takes precedence.
/RANGE:n[:m]
Sort elements nthrough m of the array. By default, the entire
array from element 1 to its dimensioned size is sorted, which
might produce surprising results if the array is not full; see
example in [597]Section 7.10.7. If ":m" is omitted from the
range, the dimensioned size is used. Thus, to sort an entire
array, \&a[], including its 0th element, use "sort /range:0
&a". You can also sort any desired section of an array, e.g.
"sort /range:10:20 &a" or "sort /range:\%i:\%j-1 &b". As noted
above, you can also specify a range in the array-name brackets.
If you specify a range in the array-name brackets AND with a
/RANGE switch, the ones in the brackets take precedence.
/REVERSE
Sort in reverse order. If this switch is not given, the array
is sorted in ascending order.
Remember that numeric switch arguments can be numbers, arithmetic
expressions, or variables whose values are numbers or expressions, as
illustrated in the /RANGE examples above.
A typical sorting application might be to list students' test scores
in descending order. Suppose you had the following records:
olaf 65
olga 98
ivan 83
xena 100
(and so on) stored in array \&s[] (e.g. by reading them from a file as
illustrated in [598]section 7.10.7). In these records, the student's
name is in columns 1-9 and the score in 10-12. So to rearrange the
list in descending order of score:
sort /key:10 /reverse &s
Then to list your top five students:
for \%i 1 5 1 { echo \&s[\%i] }
Or more simply (see next section):
show array a[1:5]
To illustrate the difference between a lexical and a numeric sort,
suppose you have the following records (the lines that are numbered,
starting at column 1) in array \&a[]:
Column 1 2
12345678901234567890
1. Ivan 10.0 2. Olaf 9.95 3. Olga 101.5
ARRAY SORT /KEY:10 &a[] would order them 3,1,2, but ARRAY SORT /KEY:10
/NUMERIC &a[] would order them 2,1,3.
_________________________________________________________________
7.10.6. Displaying Arrays
The SHOW ARRAY command (or ARRAY SHOW) now accepts an optional
array-name argument:
SHOW ARRAY \&a[]
(you can leave off the \, the \&, and/or the []'s if you like; "show
array a" is equivalent to "show array \&a[]"). When an array is
specified, its dimension is shown and all defined (non-empty) elements
are listed.
Example:
assign \%n \ffiles(*,&a) ; Fill an array with filenames ([599]Section 4.11.3
)
show array \&a[] ; Show the array we just read
array show \&a[] ; Same as previous
array sort \&a[] ; Sort the array
array show \&a[] ; Show it after sorting
array show \&a ; Show it again
array show &a ; Show it again
array show a ; Show it again
(The final four commands demonstrate the alternative forms that are
accepted for the array name.)
If you SHOW ARRAY without giving an array name, all defined arrays are
listed by name and dimension, but their contents are not shown.
You can also show a piece of an array by including a subscript or
range within the array brackets:
array show \&a[5] ; Shows \&a[5]
array show &a[3:8] ; Shows \&a[3] through \&a[8]
array show a[:\%n-1] ; Shows \&a[0] through \&a[\%n-1]
_________________________________________________________________
7.10.7. Other Array Operations
ARRAY DESTROY arrayname
Destroys and undeclares the named array. Subscripts or ranges
are not accepted in this command.
ARRAY COPY array1 array2
Copies the first array to the second array. If the target array
has not been declared, it is created automatically with the
same size as the first. If it has been declared, it will be
used as declared; if the source array is larger, only as much
of it as will fit is copied to the target array. Syntax for
array1 and array2 is as in ARRAY SHOW (SHOW ARRAY). Example:
.\%n := \ffiles(*,&a) ; Create and load array A with a file list.
array copy &a &b ; Copy array A to array B.
The ARRAY COPY command also lets you copy pieces of arrays by
including range specifiers, as in these examples:
ARRAY COPY \&a[4:27] \&b
This copies \&a[] elements 4-27 to \&b[] elements 1-23,
creating \&b[] if necessary or, if \&b[] is already
declared, stopping early if its size is less than 23.
ARRAY COPY \&a[4:27] \&b[12]
This copies \&a[] elements 4-27 to \&b[] elements 12-35,
creating \&b[] if necessary or, if \&b[] is already
declared, stopping early if its size is less than 35.
ARRAY COPY \&a[4:27] \&b[12:14]
This copies \&a[] elements 4-6 to \&b[] elements 12-14,
creating \&b[] if necessary or, if \&b[] is already
declared, stopping early if its size is less than 14.
ARRAY COPY \&a[17] \&b
This copies all the elements of \&a[] starting with 17
until the last to \&b[], creating \&b[] if necessary or,
if \&b[] is already declared, stopping early if \&b[] is
not big enough.
ARRAY CLEAR arrayname
Sets all the elements of the array to the empty value. You may
also include a range specifier to clear only a selected portion
of the array; for example "array clear \&a[37:214]". If the
range is out of bounds, only the part of the array that is in
bounds is cleared.
ARRAY SET arrayname [ value ]
Sets all the elements of the array to the given value. If no
value is given, the array is cleared. You may also include a
range specifier to set only a selected portion of the array;
for example "array set \&a[1:9] -1". If the range is out of
bounds, only the part of the array that is in bounds is set.
ARRAY RESIZE arrayname size
Resizes the given array. If the size is greater than the
array's current dimension, new empty elements are added to the
end. If the size is less than the current dimension, the extra
elements are discarded. Note: If you have stored the array size
in element 0, ARRAY RESIZE does not change this value.
Alternative notation: ARRAY RESIZE arrayname[size]. For a
practical example, see [600]Section 7.10.11.
\farraylook(pattern,arrayname)
This function returns the index of the first element of the
given array that matches the given pattern (for details about
pattern syntax, see [601]section 4.9). The array name can
include a range specification to restrict the search to a given
segment of the array. If no elements match the pattern, -1 is
returned.
\ftablelook(keyword,arrayname[,delimiter])
Looks in the given "table", which must be sorted, for the given
keyword. The keyword need not be spelled out in full.
Pattern-matching characters should not be included as part of
the keyword. The function returns the index of the table
element that uniquely matches the given keyword, or -1 if none
match, or -2 if more than 1 match.
A "table" is an array that is sorted in lexical order; each of its
elements may contain multiple fields, delimited by the given delimiter
character or, if no delimiter is specified, a colon (:).
The \farraylook() function does exactly what you tell it. If you give
it a pattern that does not include wildcard characters (such as *, ?,
etc), it requires an exact match. For example:
\farraylook(oofa,&a)
searches for the first element of \&a[] whose value is "oofa". But:
\farraylook(oofa*,&a)
finds the first element whose value starts with "oofa", and;
\farraylook(*oofa,&a)
finds the first element whose value ends with "oofa", and;
\farraylook(*oofa*,&a)
finds the first element whose value contains "oofa".
Here's a simple demonstration of looking up patterns in arrays:
local \&a[] \%x \%n
declare \&a[] = zero one two three four five six seven eight nine ten
while true {
.\%x = 1
.\%n = 0
ask \%a { Pattern? }
if not def \%a exit 0 Done.
while <= \%x \fdim(&a) {
.\%x := \farraylook(\%a,&a[\%x])
if ( < \%x 0 ) break
echo \flpad(\%x,3). \&a[\%x]
increment \%x
increment \%n
}
if ( < \%n 1 ) echo Pattern not found - "\%a"
}
The array need not be sorted. When a pattern is given, a search is
performed; if there is a match, the matching element's index and the
element itself are printed, and the search begins again at the next
element. Thus each matching element is printed. If none match, the
"Pattern not found" message is printed. The process repeats for as
many patterns as the user wants to type, and terminates when the user
types an empty pattern.
Now let's build a little command parser, consisting of a keyword
table, and a loop to look up the user's commands in it with
\ftablelook(). In this case the array elements have "fields" separated
by colon (:) -- a keyword and a value. Keyword tables must be sorted
if \tablelook() is to work right, so after declaring and initializing
the table array, we sort it.
local \&k[] \%a \%i \%n
array declare \&k[] = drive:9 do:8 discuss:7 live:6 spend:5 help:4 quit:0
array sort &k ; Make sure array is sorted
echo Type "help" for help. ; Print greeting & instructions
while true { ; Loop to get commands
undefine \%a
while not defined \%a { ; Get a command
ask \%a { Command? }
}
.\%n := \ftablelook(\%a,&k) ; Look up the command
switch \%n { ; Handle errors
:-1, echo Not found - "\%a" ; Doesn't match
continue
:-2, echo Ambiguous - "\%a" ; Matches too many
continue
}
switch \fword(\&k[\%n],2) { ; Dispatch according to value
:9, echo Driving..., break
:8, echo Doing..., break
:7, echo Discussing..., break
:6, echo Living..., break
:5, echo Spending..., break
:4, echo { Commands (may be abbreviated):}
for \%i 1 \fdim(&k) 1 {
echo { \%i. \fword(\&k[\%i],1) }
}
break
:0, exit 0 Bye!
:default, stop 1 Internal error
}
}
In this example, keywords are "drive", "do", "discuss", etc, and their
values are unique numbers (values need not be numbers, and there need
not be only one value -- there can be 0, 1, 2, or more of them). The
user types a command, which can be the whole word (like "help") or any
abbreviation (like "hel", "he", or just "h"). If this does not match
any keywords, \ftablelook() returns -1; if it matches more than one
(as would "d"), it returns -2. Otherwise the array index is returned,
1 or higher.
Given the array index \%n, we can get the table values as follows:
\fword(\&k[\%n],1) is the keyword (first field)
\fword(\&k[\%n],2) is the value (second field, in this case a number)
In our example, we use the value (number) as the SWITCH variable. As
noted, \fablelook() expects the array elements to contain multiple
fields separated by colon (:) (or other character that you specify,
e.g. \ftablelook(\%a,&a,^)) and when matching the keyword, ignores the
first delimiter and everything after it.
_________________________________________________________________
7.10.8. Hints for Using Arrays
C programmers are accustomed to out-of-bounds array references causing
core dumps or worse. In C-Kermit:
* A reference to an an out-of-bounds array element returns the empty
string.
* An attempt to set the value of an array element that is out of
bounds or that has not been declared simply fails.
C programmers expect an array of size nto have elements 0 through n-1.
Fortran programmers expect the same array to have elements 1 through
n. C-Kermit accommodates both styles; when you declare an array of
size n, it has n=1 elements, 0 through n, and you can use the array in
your accustomed manner, 0-based or 1-based.
However, note that C-Kermit has certain biases towards 1-based arrays:
* Assignment of file lists starts with element 1 ([602]Section
7.10.3).
* Assignment by \fsplit() starts with element 1 ([603]Section 7.3).
* Array initialization skips the 0th element. To initialize a
0-based array, use something like this:
declare \&a[3] = one two three
.\&a[0] = zero
* The ARRAY SORT command skips the 0th element unless you include
/RANGE:0
* The SHIFT command ignores element 0 of the \&_[] array.
The distinction between an array's dimensioned size and the number of
elements in the array is important when sorting. To illustrate:
declare \&a[100] ; Declare array &a with 100 elements
fopen /read \%c oofa.txt ; Open a file
if fail...
for \%i 1 \fdim(&a) 1 { ; Read the file into the array
fread \%c \&a[\%i]
if fail break
}
fclose \%c
if > \%i \fdim(&a) end 1 File has too many lines for array.
.\%n ::= \%i - 1
echo File has \%n line(s).
Let's say the file had 95 lines. This leaves elements 96-100 of the
array empty. Now suppose you sort the array and write out the result:
sort &a ; Sort the whole array
fopen /write \%o oofa.txt.sorted ; Open an output file
if fail ...
for \%i 1 \%n 1 { ; Write out 95 records
fwrite /line \%o \&a[\%i]
if fail end 1 Write error
}
close write
You might be surprised at the contents of "oofa.txt.sorted" -- five
empty elements, 96-100, floated to the top of the array in the sort,
and since your write loop only had 95 iterations, the final 5 lines of
the sorted file are lost.
Therefore, when dealing with partially filled arrays -- especially
when sorting them -- remember to specify the number of elements. A
handy way of recording an array's "true" size is to put it in the 0th
element. That way, it "travels with the array". To illustrate
(continuing the previous example at the "close read" statement):
close read
if > \%i \fdim(&a) end 1 File has too many lines for array.
.\&a[0] ::= \%i - 1 ; Assign number of lines to \&a[0].
echo File has \&a[0] line(s).
sort /range:1:\&a[0] &a
open write oofa.txt.sorted
if fail ...
for \%i 1 \&a[0] 1 {
writeln file \&a[\%j]
if fail end 1 Write error
}
close write
Note the SORT switch, /RANGE:1:\&a[0]. This keeps the sort 1-based,
and uses element 0 of the array as its size indicator.
Finally, note that even though some commands or functions might put a
size in array element 0, no built-in functions or commands depend on a
size actually being there. Thus you are perfectly free to replace the
size with something else and treat the array as 0-based.
_________________________________________________________________
7.10.9. Do-It-Yourself Arrays
Kermit's \&x[] arrays are nice because of the accompanying built-in
functionality -- ARRAY commands, built-in functions that load and
search arrays, automatic evaluation of arithmetic expressions within
the subscript brackets, and so on. Yet they also have certain
limitations:
1. Except when created by dynamic loading (e.g. by \ffiles()) they
must be declared and dimensioned in advance.
2. Indices must be numeric, positive, and in range.
3. There can be only one dimension. Matrices or other
higher-dimensioned arrays are not available.
But none of this is to say you can't invent any kind of data structure
you like. In [604]Section 7.9.2 you can see some examples. Here's
another (courtesy of Dat Thuc Nguyen), in which a pair of matrices is
created and then added: no dimensioning necessary.
.row = 4
.col = 9
; MACRO TO PRINT A MATRIX
define PMATRIX {
echo Matrix \%1:
for \%r 1 \m(row) 1 {
for \%c 1 \m(col) 1 {
xecho \flpad(\m(\%1[\%r][\%c]),4)
}
echo
}
echo
}
; CREATE MATRICES A AND B
for \%r 1 \m(row) 1 {
for \%c 1 \m(col) 1 {
_eval A[\%r][\%c] \%r + \%c
_eval B[\%r][\%c] \%r * \%c
}
}
; CREATE MATRIX C = SUM OF MATRIX A AND MATRIX B
for \%r 1 \m(row) 1 {
for \%c 1 \m(col) 1 {
_eval C[\%r][\%c] \m(A[\%r][\%c]) + \m(B[\%r][\%c])
}
}
pmatrix A ; Print Matrix A
pmatrix B ; Print Matrix B
pmatrix C ; Print Matrix C
In the example, we use matrix-like notation to create macros with
names like "A[1][1]", "B[3][7]", and so on.
_________________________________________________________________
7.10.10. Associative Arrays
An associative array is a special kind of Do-It-Yourself array. It
differs from a regular array in that its indices need not be numbers
-- they can be anything at all -- words, filenames, names of months,
any character string at all, and that it doesn't have to be (and in
fact can't be) declared. An associative array element is simply a
macro whose name ends with an index enclosed in angle brackets, for
example:
file<oofa.txt>
More formally:
basename<index>
An associative array is a collection of all associative array elements
that have the same basename. Any number of associative arrays, each
with any number of elements, can exist at the same time.
An associative array element can be assigned a value, such as "1",
just like any other macro:
define file<oofa.txt> 1 ; Give "file<oofa.txt>" the value "1".
or:
assign file<oofa.txt> \%a ; Give it the value of the variable \%a.
However, since an associative array element is a macro, it may not
have an empty (null) value, since assigning an empty value to a macro
undefines the macro.
You can refer to the value of an associative array element using the
familiar notation for macro values:
echo \m(file<oofa.txt>) ; Echo the value of "file<oofa.txt>".
Associative arrays are most useful, however, when the value of the
index is a variable. In that case, you must use the "hidden" forms of
the DEFINE or ASSIGN commands that evaluate the macro name before
making the assignment (see [605]Using C-Kermit, page 457). Example:
define \%f oofa.txt
_define file<\%f> 1
echo file<\%f> = \m(file<\%f>)
prints:
file<oofa.txt> = 1
and then:
_increment file<\%f>
echo file<\%f> = \m(file<\%f>)
prints:
file<oofa.txt> = 2
What are associative arrays good for? The classic example is "word
counts": finding the number of times each word is used in a text
without knowing in advance what the words are. Without associative
arrays, your program would have to build a table of some kind, and
every time a word was encountered, look it up in the table to find its
position and counter, or add it to the table if it wasn't found -- a
time-consuming and laborious process. Associative arrays, however, let
you use the word itself as the table index and therefore sidestep all
the table building and lookups.
Let's work through a practical example. Suppose you have a
file-transfer log in which each line is composed of a number of
blank-separated fields, and the 9th field is a filename (which happens
to be the format of certain FTP server logs, as well as of C-Kermit's
new FTP-format transaction log, described in [606]Section 4.17.2), for
example:
Wed Jul 14 09:35:31 1999 22 xx.mit.edu 13412 /pub/ftp/mm/intro.txt ....
and you want to find out how many times each file was transferred. The
following code builds an associative array, file<>, containing the
counts for each file:
local name line max \%c \%n ; Declare local variables
fopen /read \%c /var/log/ftpd.log ; Open the log file ([607]Section 1.22)
if fail exit 1 Can't open log ; Check
while true { ; Loop for each record
fread /line \%c line ; Read a line
if fail break ; Check for end of file
.name := \fword(\m(line),9,{ }) ; Get 9th field = filename (Sec 7.3)
_increment file<\m(name)> ; Increment its counter (Sec 7.9.2)
}
fclose \%c ; Close file when done.
Note that _INCREMENT (and INCREMENT, and [_]DECREMENT) treat an empty
(i.e. nonexistent) variable as having a value of 0, and therefore
creates the variable with a value of 1.
At this point, if you told Kermit to "show macro file<", it would list
the associative array. But since you don't necessarily know the names
of the files in the array, or even how many elements are in the array,
how can you use it in a script program?
The idea of creating macro names that include character-string indices
enclosed in angle brackets is perfectly arbitrary and doesn't depend
on any Kermit features that weren't already there -- we could just as
easily have used some other notation, such as "file[index]",
"file:index", or "file.index", and the code above would have worked
just as well (with the corresponding syntax adjustments). But to be
able to use an associative array in a program after the array is
built, we need a method of accessing all its elements without knowing
in advance what they are. That's where the chosen notation comes in.
First of all, any macro name that ends with "<xxx>" (where "xxx" is
any string) is case sensitive, unlike all other macro names, which are
case independent. To illustrate, "file<oofa.txt>" and "file<OOFA.TXT>"
are two distinct macros, whereas "OOFA", "Oofa", and "oofa", when used
as macro names, are all the same.
Second, the new \faaconvert() function converts an associative array
(that is, all macros with names of the form "base<index>" that have
the same "base" part) into a pair of regular arrays and returns the
number of elements:
\faaconvert(name,&a[,&b])
"name" is the name of the associative array, without the angle
brackets or index ("file" in our example).
The second argument is the name of a regular array in which to store
the indices of the associative array (filenames in our example); if an
array of this name already exists, it is destroyed unless the array is
LOCAL. The third argument is the name of another regular array in
which to store the values (the counts in our example), with the same
rules about array name collisions. If you care only about the indices
and not the values, you can omit the third argument to \faaconvert().
In any case, the associative array is converted, not copied: its
elements are moved to the specified regular arrays, so after
conversion the original associative array is gone.
As with other array-loading functions, \faaconvert() sets element 0 of
each array to the number of elements in the array.
To continue our example:
.max := 0 ; Maximum count
.\%n := \faaconvert(file,&a,&b) ; Convert
for \%i 1 \%n 1 { ; Loop through values
echo \flpad(\%i,3). \&a[\%i]: \&b[\%i] ; Echo this pair
if ( > \&b[\%i] \m(max) ) { ; Check for new maximum
.name := \&a[\%i]
.max := \&b[\%i]
}
}
echo Most popular file: \m(name), accesses: \m(max)
This lists the files and counts and then announces which file has the
highest count.
Now suppose you want to sort the array pair created from an
associative array. In our example, \&a[] contains filenames, and \&b[]
contains the associated counts. Here we take advantage of the ARRAY
SORT command's ability to sort a second array according to the first
one:
array sort /reverse /numeric &b &a ; Descending sort by count
Now to see the top five files and their counts:
echo The top 5 files are:
for \%i 1 5 1 { ; Loop through top 5 values
echo \flpad(\%i,3). \&a[\%i]: \&b[\%i] ; Echo this pair
}
_________________________________________________________________
7.10.11. Transferring Array Contents to Other Computers
The SEND /ARRAY:arrayname command ([608]Section 4.7.1) allows you to
send the contents of any array, or any contiguous segment of it, in
either text or binary mode to another computer, using Kermit protocol.
When used in conjunction with C-Kermit's other features (the array
features described in this section; the file i/o package from
[609]Section 1.22; its decision-making, pattern-matching, and string
manipulation capabilities, and so on) the possibilities are endless:
extracts of large files, remote database queries, ..., all without
recourse to system-dependent mechanisms such UNIX pipes and filters,
thus ensuring cross-platform portability of scripts that use these
features.
When sending an array in text mode, Kermit appends a line terminator
to each array element, even empty ones, and it also converts the
character set from your current FILE character-set to your current
TRANSFER character-set, if any. No conversions are made or line
terminations added in binary mode. For example, the following array:
dcl \&a[] = One Two Three Four Five Six
is sent as six lines, one word per line, in text mode, and as the bare
unterminated string "OneTwoThreeFourFiveSix" in binary mode.
You should always include a /TEXT or /BINARY switch in any SEND /ARRAY
command to force the desired transfer mode, otherwise you're likely to
be surprised by the effects described in [610]Section 4.3.
Here are some examples:
send /text /array:\&a[]
Sends the entire contents of the array \&a[] in text mode.
Since an as-name is not included, the receiver is told the
filename is _array_a_.
send /text /array:&a[]
send /text /array:a[]
send /text /array:&a
send /text /array:a
These are all equivalent to the previous example.
send /text /array:&a /as-name:foo.bar
As above, but the array is sent under the name foo.bar.
send /text /array:&a[100:199] /as:foo.bar
As above, but only the elements from 100 through 199 are sent.
In text-mode transfers, character sets are translated according to
your current settings, just as for text files. In binary mode, of
course, there is no character-set translation or other conversion of
any kind. But remember that array elements can not contain the NUL
(ASCII 0) character, since they are implemented as NUL-terminated
strings.
Here's an example that shows how to send all the lines (up to 1000 of
them) from a file animals.txt that contain the words "cat", "dog", or
"hog" (see [611]Section 4.9 about pattern matching):
declare \&a[1000]
fopen /read \%c animals.txt
if fail exit 1
.\%i = 0
while true {
fread \%c line
if fail break
if match {\m(line)} {*{cat,[dh]og}*} {
increment \%i
if ( > \%i \fdim(&a) ) break
.\&a[\%i] := \m(line)
}
}
fclose \%c
send /array:a[1:\%i] /text
Note that we are careful to send only the part of the array that was
filled, not the entire array, because there are likely to be lots of
unused elements at the end, and these would be sent as blank lines
otherwise.
This example raises an interesting question: what if we want to send
ALL the matching lines, even if there are more than 1000 of them, but
we don't know the number in advance? Clearly the problem is limited by
Kermit's (and the computer's) memory. If there are a thousand trillion
matching lines, they most likely will not fit in memory, and in this
case the only solution is to write them first to a temporary file on
mass storage and then send the temporary file and delete it
afterwards.
However, when the selection is likely to fit in memory, the
once-familiar technique of initial allocation with extents can be
used:
if match {\m(line)} {*{cat,[dh]og}*} {
increment \%i
if ( > \%i \fdim(&a) ) {
array resize a \fdim(&a)+100
if fail stop 1 MEMORY FULL
echo NEW DIMENSION: \fdim(&a)
}
.\&a[\%i] := \m(line)
}
This grows the array in chunks of 100 as needed.
_________________________________________________________________
7.11. OUTPUT Command Improvements
LINEOUT [ text ]
This command is exactly like OUTPUT, except it supplies a
carriage return at the end of the text. "lineout exit" is
exactly the same as "output exit\13".
SET OUTPUT SPECIAL-ESCAPES { ON, OFF }
This command lets you tell C-Kermit whether to process \N, \L,
and \B specially in an OUTPUT command, as distinct from other \
sequences (such as \%a, \13, \v(time), etc). Normally the
special escapes are handled. Use SET OUTPUT SPECIAL-ESCAPES OFF
to disable them.
Disabling special escapes is necessary in situations when you need to
transmit lines of data and you have no control over what is in the
lines. For example, a file oofa.txt that contains:
This is a file
It has \%a variables in it
And it has \B in it.
And it has \L in it.
And it has \N in it.
And this is the last line.
can be sent like this:
local line
set output special-escapes off
fopen /read \%c oofa.txt
if fail stop 1 Can't open oofa.txt
while success {
fread \%c line
if fail break
; Add filtering or processing commands here...
output \m(line)\13
}
_________________________________________________________________
7.12. Function and Variable Diagnostics
In C-Kermit 6.0 and earlier, the only diagnostic returned by a failing
function call was an empty value, which (a) could not be distinguished
from an empty value returned by a successful function call; (b) did
not give any indication of the cause of failure; and (c) did not cause
the enclosing statement to fail. C-Kermit 7.0 corrects these
deficiencies.
SET FUNCTION DIAGNOSTICS { ON, OFF }
when ON, allows built-in functions to return diagnostic
messages when improperly referenced, instead of an empty
string. FUNCTION DIAGNOSTICS are ON by default. When OFF,
improperly referenced functions continue to return an empty
string. This command also affects built-in variables; in this
case, an error message is returned only if the variable does
not exist. When FUNCTION DIAGNOSTICS are ON, the error message
is also printed.
For variables, the only message is:
<ERROR:NO_SUCH_VARIABLE:\v(name)>
where "name" is the name of the nonexistent variable.
For functions, the diagnostic message is:
<ERROR:message:\fname()>
where "message" is replaced by a message, and "name" is replaced by
the function name, e.g. <ERROR:ARG_NOT_NUMERIC:\fmod()>. Messages
include:
ARG_BAD_ARRAY An argument contains a malformed array reference.
ARG_BAD_DATE An argument contains a malformed date and/or time.
ARG_BAD_PHONENUM An argument contains a malformed telephone number.
ARG_BAD_VARIABLE An argument contains a malformed \%x variable.
ARG_INCOMPLETE An argument is incomplete (e.g. a broken Base64 string).
ARG_EVAL_FAILURE An argument could not be evaluated (internal error).
ARG_NOT_ARRAY An argument references an array that is not declared.
ARG_NOT_NUMERIC An argument that must be integer contains non-digits.
ARG_NOT_FLOAT An argument has bad floating-point number format.
ARG_NOT_VARIABLE An argument that must be a variable is not a variable.
ARG_OUT_OF_RANGE An argument's numeric value is too big or too small,
or an argument contains illegal characters (e.g. a hex
or Base-64 string).
ARG_TOO_LONG An argument's value is too long.
ARRAY_FAILURE Failure to create an array.
DIVIDE_BY_ZERO Execution of the function would cause division by zero.
FLOATING_POINT_OP Execution error in a floating-point operation.
FILE_NOT_FOUND Filename argument names a file that can't be found.
FILE_NOT_READABLE Filename argument is not a regular file.
FILE_NOT_ACCESSIBLE Filename argument names a file that is read-protected.
FILE_ERROR Other error with filename argument.
FILE_NOT_OPEN A file function was given a channel that is not open.
FILE_ERROR_-n A file function got error -n ([612]Section 1.22).
LOOKUP_FAILURE Error looking up function (shouldn't happen).
MALLOC_FAILURE Failure to allocate needed memory (shouldn't happen).
NAME_AMBIGUOUS The function is not uniquely identified.
MISSING_ARG A required argument is missing.
NO_SUCH_FUNCTION An argument references a function that is not defined.
NO_SUCH_MACRO An argument references a macro that is not defined.
RESULT_TOO_LONG The result of a function is too long.
UNKNOWN_FUNCTION Internal error locating function (shouldn't happen).
Examples:
assign \%m \fmod()
?<ERROR:MISSING_ARG:\fmod()>
echo "\fcontents(\%m)"
"<ERROR:MISSING_ARG:\fmod()>"
echo \fmod(3,x)
?<ERROR:ARG_NOT_NUMERIC:\fmod()>
echo \fmod(3,4-2*2)
?<ERROR:DIVIDE_BY_ZERO:\fmod()>
Notice the use of \fcontents() in echoing the value of a variable that
contains a returned error message. That's because the error message
includes the name of the variable or function that failed, so you must
use \fcontents() to prevent it from being evaluated again -- otherwise
the same error will occur.
The handling of function and variable errors is controlled by:
SET FUNCTION ERROR { ON, OFF }
Tells whether invalid function calls or variable references
should cause command errors. FUNCTION ERROR is ON by default.
When ON, and an error is diagnosed in a built-in function or
variable, the command that includes the function call or
variable reference fails. The failing command can be handled in
the normal way with IF FAILURE / IF SUCCESS, SET TAKE ERROR, or
SET MACRO ERROR.
When FUNCTION DIAGNOSTICS is OFF, there is no error message.
SHOW SCRIPTS displays the current FUNCTION DIAGNOSTICS and ERROR
settings.
_________________________________________________________________
7.13. Return Value of Macros
In C-Kermit 5A and 6.0, there are two ways to return one level from a
macro: RETURN value and END number text. When RETURN is used, the
value, which can be a number or a text string, is assigned to
\v(return). When END was used, however, \v(return) was not set.
SUCCESS/FAILURE was set according to whether the number was zero, and
the text was printed, but the actual value of the number was lost.
In C-Kermit 7.0, the END number is available in the \v(return)
variable.
_________________________________________________________________
7.14. The ASSERT, FAIL, and SUCCEED Commands.
The ASSERT command is just like the IF command, but without a command
to execute. It simply succeeds or fails, and this can be tested by a
subsequent IF SUCCESS or IF FAILURE command. Example:
ASSERT = 1 1
IF SUCCESS echo 1 = 1.
The FAIL command does nothing, but always fails. The SUCCEED command
does nothing, but always succeeds.
These commands are handy in debugging scripts when you want to induce
a failure (or success) that normally would not occur, e.g. for testing
blocks of code that normally are not executed.
_________________________________________________________________
7.15. Using Alarms
Alarms may be set in two ways:
SET ALARM number
Sets an alarm for the given number of seconds "from now", i.e.
in the future, relative to when the SET ALARM command was
given. Examples:
set alarm 60 ; 60 seconds from now
set alarm +60 ; The same as "60"
set alarm -60 ; Not legal - you can't set an alarm in the past.
set alarm 60*60 ; 60 minutes from now.
set alarm \%a+10 ; You can use variables, etc.
SET ALARM hh:mm:ss
Sets an alarm for the specified time. If the given time is
earlier than the current time, the alarm is set for the given
time in the next day. You may give the time in various formats:
set alarm 15:00:00 ; 3:00:00pm
set alarm 3:00:00pm ; 3:00:00pm
set alarm 3:00pm ; 3:00:00pm
set alarm 3pm ; 3:00:00pm
SHOW ALARM
Displays the current alarm, if any, in standard date-time
format (see [613]Section 1.6): yyyymmdd hh:mm:ss.
IF ALARM command
Executes the command if an alarm has been set and the alarm
time has passed.
IF ALARM { command-list } [ ELSE { command-list } ]
Executes the command-list if an alarm has been set and the
alarm time has passed. Otherwise, if an ELSE part is given, its
command-list is executed.
CLEAR ALARM
Clears the alarm.
Only one alarm may be set at a time.
Example: Suppose you have a script that is always running, and that
transfers files periodically, and that keeps a transaction log.
Suppose you want to start a new transaction log each day:
log transactions \v(date).log
set alarm 00:00:00 ; Set an alarm for midnight
while true { ; Main script loop
xif alarm { ; If the alarm time is past...
close transactions ; Close current log
log transactions \v(date).log ; Start new one
pause 1 ; To make sure 00:00:00 is past
set alarm 00:00:00 ; Set a new alarm
}
; put the rest of the script here...
}
Note that IF ALARM -- no matter whether it succeeds or fails -- does
NOT clear an expired alarm. Thus, once an alarm has expired, every IF
ALARM will succeed until the alarm is cleared (with the CLEAR ALARM
command) or reset with a new SET ALARM command.
_________________________________________________________________
7.16. Passing Arguments to Command Files
Beginning in version 7.0, C-Kermit accepts arguments on the TAKE
command line, for example:
C-Kermit> take oofa.ksc one two {this is three} four
This automatically sets the variables \%1 through \%9 to the
arguments, and \%0 to the name of the file, in this case:
\%0 = /usr/olga/oofa.ksc
\%1 = one
\%2 = two
\%3 = this is three
\%4 = four
and \%5..\%9 are undefined (empty). Arguments past the ninth are
available in the \&_[] argument-vector array ( [614]Section 7.5).
The variables are those at the current macro level. Thus, if the TAKE
command is executed from within a macro, the macro's arguments are
replaced by those given on the TAKE command line (but only if at least
one argument is given). The command shown above is exactly equivalent
to:
assign \%0 /usr/olga/oofa.ksc
assign \%1 one
assign \%2 two
assign \%3 this is three
assign \%4 four
assign \%5
assign \%6
assign \%7
assign \%8
assign \%9
take oofa.ksc
Remember, the variables \%0..\%9 are on the macro call stack, and
command files are independent of the macro stack. Thus, if a command
file TAKEs another command file and passes arguments to it, the
variables are changed from that point on for both files, and so forth
for all levels of nested command files without intervening macro
invocations.
It would have been possible to change C-Kermit to use the overall
command stack, rather than the macro stack, for arguments -- this
would have made TAKE work exactly like DO, which is "nicer", but it
would also have broken countless existing scripts. However, the new
SHIFT command ([615]Section 7.5) makes it possible to create an
alternative TAKE command that does indeed save and restore the
argument variables at its own level around execution of a command
file:
define mtake {
local \%f
assign \%f \fcontents(\%1)
shift
take \%f
}
C-Kermit 7.0 also supports a new, easier way to pass arguments to
scripts from the system command line:
kermit filename arg1 arg2 arg3 ...
in which arg1, arg2, arg3 (etc) are arguments for the script (whose
filename is given), and are assigned to \%1, \%2, ... \%9. The
filename is assigned to \%0. This applies equally to "Kerbang" scripts
in UNIX ([616]Section 7.19). For example, suppose you have a file
called "showargs" containing the following lines:
#!/usr/local/bin/kermit +
echo Hello from \%0
show args
exit
(except not indented, since the "#!" line must be on the left margin).
If you give this file execute permission:
chmod +x showargs
then you can run it exactly as you would run a UNIX shell script,
e.g.:
$ showargs one two three
Hello from /usr/olga/showargs
Top-level arguments (\v(argc) = 4):
\&_[0] = /usr/olga/showargs
\&_[1] = one
\&_[2] = two
\&_[3] = three
Furthermore, the \&_[] array now contains the filename, if one was
given as the first command line argument, or it is a "Kerbang" script,
in element 0.
Otherwise element 0 is program name, and elements 1 through \v(argc)-1
contain the command-line arguments, if any, that appear after "--" or
"=", if any. This array is saved and restored around macro calls;
recall that inside macros it contains the macro argument vector
(allowing you to access arguments programmatically, and to have more
than 9 of them).
At top level, notice the difference between the \&@[] and \&_[]
arrays. The former includes C-Kermit options; the latter omits them.
_________________________________________________________________
7.17. Dialogs with Timed Responses
The ASK, ASKQ, GETOK, and GETC commands (let's call them the
"ASK-class commands") let you write scripts that carry on dialogs with
the user, asking them for text, a Yes/No answer, or a character,
respectively. Prior to C-Kermit 7.0, these questions would always wait
forever for an answer. In C-Kermit 7.0, you may specify a time limit
for them with the new command:
SET ASK-TIMER number
Sets a time-limit on ASK-CLASS commands to the given number of
seconds. If the number is 0 or less, there is no time limit and
these commands wait forever for a response. Any timer that is
established by this command remains in effect for all future
ASK-class commands until another SET ASK-TIMER command is given
(e.g. with a value of 0 to disable ASK timeouts).
IF ASKTIMEOUT command
An ASK-class command that times out returns a failure status.
You can test explicitly for a timeout with:
_________________________________________________________________
7.18. Increased Flexibility of SWITCH Case Labels
Prior to C-Kermit 7.0 / K95 1.1.19, the case labels in SWITCH
statements were string constants.
Now case labels can be variables, function calls, or any mixture of
these with each other and/or with regular characters.
Furthermore, after the case label is evaluated, it is treated not as a
string constant, but as a pattern against which the SWITCH variable is
matched ([617]Section 4.9.1).
This introduces a possible incompatibility with previous releases,
since the following characters in case labels are no longer taken
literally:
\ * ? [ {
Any scripts that previously included any of these characters in case
labels must now quote them with backslash (\).
_________________________________________________________________
7.19. "Kerbang" Scripts
In UNIX only, Kermit scripts can be stored in files and run
"directly", without starting Kermit first (as noted on page 467 of the
manual), just as a shell script can be "run" as if it were a program.
This section amplifies on that idea a bit, and presents some new
aspects of version 7.0 that make it easier to write and run Kermit
scripts directly.
NOTE: On non-UNIX platforms, such as VMS or Windows, Kerbang
scripts can be run as "kermit + scriptfilename arg1 arg2 arg3 ...".
Windows 95/98/NT file associations do not allow for the passing of
parameters. In VMS, however, you can achieve the Kerbang effect by
defining a symbol, as in this example:
$ autotelnet :== "$SYS$TOOLS:KERMIT.EXE + AUTOTELNET.KSC"
and then running the script like any other command:
$ autotelnet xyzcorp.com myuserid
See [618]Section 9.3 for an explanation of the "+" symbol.
UNIX shell scripts can specify which shell should run them by
including a "shebang" line at the top, e.g.:
#!/bin/sh
(but not indented; the shebang line must be on the left margin). The
term "shebang" is a contraction of "shell" and "bang". "Bang" is a
slang word for the exclamation mark ("!"); "shebang" itself is an
American slang word used in in the phrase "the whole shebang".
We can run Kermit scripts directly too, by including a "shebang" line
that names Kermit as the "shell"; thus we call these "Kerbang"
scripts. This mechanism has been considerably simplified in C-Kermit
7.0 to facilitate C-Kermit's use a scripting tool just like any of the
UNIX shells or scripting languages. The rules are the same as for
shell scripts:
1. The first line of the Kermit script must begin with "#!"
immediately followed by the full pathname of the program that will
execute the script (in this case, C-Kermit rather than a UNIX
shell), followed by any Kermit command-line options. To suppress
execution of the C-Kermit initialization file and to make command
line arguments available to the script, the final option should be
"+":
#!/usr/local/bin/kermit +
Some users have reported that in some circumstances a space might
be necessary after the plus sign; this depends on your shell -- it
has nothing to do with Kermit. In most cases, no space is needed.
2. The file must have execute permission (granted via "chmod +x
filename").
When C-Kermit is invoked from a Kerbang script (or from the system
prompt with a "+" command-line argument, which amounts to the same
thing), the following special rules apply:
1. The C-Kermit initialization file is NOT executed automatically. If
you want it to be executed, include a TAKE command for it in the
script, e.g. "take \v(home).kermrc". (In previous releases, the
initialization file was always executed, with no way to prevent it
except for the user to include Kermit-specific command line
options which had nothing to do with the script). Many scripts
have no need for the standard Kermit initialization file, which is
quite lengthy and not only delays startup of the script, but also
spews forth numerous messages that are most likely unrelated to
the script.
2. If the initialization file is not executed, neither is your
customization file, since the initialization file is the command
file from which the customization file is TAKEn. Again, you can
include a TAKE command for the initialization file if desired, or
for the customization file by itself, or for any other file.
3. C-Kermit does not process command-line arguments at all. Instead,
it passes all words on the command line after the "+" to the
script as \%0 (the script name), \%1..\%9 (the first nine
arguments), as well as in the argument vector array \&_[]. The
variable \v(argc) is set to the total number of "words" (as passed
by the shell to Kermit) including the script name. Quoting and
grouping rules are those of the shell.
4. At any point where the script terminates, it must include an EXIT
command if you want it to exit back to the shell; otherwise
C-Kermit enters interactive prompting mode when the script
terminates. The EXIT command can include a numeric status to be
returned to the shell (0, 1, etc), plus an optional message.
Here is a simple Kerbang script that prints its arguments:
#/usr/local/bin/kermit +
echo Hello from \%0
for \%i 0 \v(argc)-1 1 {
echo \%i. "\&_[\%i]"
}
exit 0
Save this file as (say) "showargs", then give it execute permission
and run it (the \&_[] array is the same as \%0..\%9, but allows you to
refer to argument variables programmatically; see [619]Section 7.5).
(Yes, you could substitute SHOW ARGUMENTS for the loop.)
$ chmod +x showargs
$ ./showargs one "this is two" three
The script displays its arguments:
Hello from /usr/olga/showargs
0. "/usr/olga/showargs"
1. "one"
2. "this is two"
3. "three"
$
Notice that no banners or greetings are printed and that startup is
instantaneous, just like a shell script. Also notice that grouping of
arguments is determined by *shell* quoting rules, not Kermit ones,
since the command line is parsed by the shell before Kermit ever sees
it.
Of course you can put any commands at all into a Kerbang script. It
can read and write files, make connections, transfer files, anything
that Kermit can do -- because it *is* Kermit. And of course, Kerbang
scripts can also be executed from the Kermit prompt (or from another
script) with a TAKE command; the Kerbang line is ignored since it
starts with "#", which is a comment introducer to Kermit just as it is
to the UNIX shell. In VMS and other non-UNIX platforms, the Kerbang
line has no effect and can be omitted.
It might be desireable for a script to know whether it has been
invoked directly from the shell (as a Kerbang script) or by a TAKE
command given to the Kermit prompt or in a Kermit command file or
macro. This can be done as in this example:
#!/usr/local/bin/kermit +
assign \%m \fbasename(\%0)
define usage { exit 1 {usage: \%m phonenumber message} }
define apage { (definition of APAGE...) } ; (See [620]book pp.454-456)
xif equal "\%0" "\v(cmdfil)" {
if not def \%1 usage
if not def \%2 usage
apage {\%1} {\%2}
exit \v(status)
}
In a Kerbang script, \%0 and \v(cmdfile) are the same; both of them
are the name of the script. When a script is invoked by a Kermit TAKE
command, \%0 is the name of the Kermit program, but \v(cmdfile) is the
name of the script. In the example above, a macro called APAGE is
defined. If the script was invoked directly, the APAGE macro is also
executed. Otherwise, it is available for subsequent and perhaps
repeated use later in the Kermit session.
An especially handy use for Kerbang scripts is to have the
initialization file itself be one. Since the standard initialization
file is rather long and time-consuming to execute, it is often
overkill if you want to start Kermit just to transfer a file. Of
course there are command-line switches to suppress initialization-file
execution, etc, but another approach is to "run" the initialization
file when you want its features (notably the services directory), and
run C-Kermit directly when you don't. A setup like this requires that
(a) the C-Kermit initialization file is configured as a Kerbang script
(has #!/path.../kermit as first line), has execute permission, and is
in your PATH; and (b) that you don't have a .kermrc file in your login
directory.
_________________________________________________________________
7.20. IF and XIF Statement Syntax
The IF command has been improved in two significant ways in C-Kermit
7.0, described in the following subsections. All changes are backwards
compatible.
7.20.1. The IF/XIF Distinction
The distinction between IF and XIF is no longer important as of
C-Kermit 7.0. You should be able to use IF in all cases (and of
course, also XIF for backwards compatibility). In the past, IF was
used for single-command THEN parts, followed optionally by a separate
ELSE command:
IF condition command1 ; THEN part
ELSE command2 ; ELSE part
whereas XIF was required if either part had multiple commands:
XIF condition { command, command, ... } ELSE { command, command, ... }
The syntactic differences were primarily that IF / ELSE was two
commands on two separate lines, whereas XIF was one command on one
line, and that XIF allowed (and in fact required) braces around its
command lists, whereas IF did not allow them.
Furthermore, the chaining or nesting of parts and conditions was
inconsistent. For example, the IF command could be used like this:
IF condition command
ELSE IF condition command
ELSE IF condition command
ELSE IF condition command
...
but XIF could not. C-Kermit 7.0 accepts the old syntax and executes it
the same as previous versions, but also accepts a new unified and more
convenient syntax:
IF condition command-list [ ELSE command-list ]
or:
IF condition command-list
ELSE command-list
in which the ELSE part is optional, and where command-list can be a
single command (with or without braces around it) or a list of
commands enclosed in braces. Examples:
Example 1:
IF condition { command1, command2 } ELSE { command3, command4 }
Example 2 (same as Example 1):
IF condition {
command1
command2
} ELSE {
command3
command4
}
Example 3 (same as 1 and 2):
IF condition {
command1
command2
}
ELSE { command3, command4 }
Example 4 (same as 1-3):
IF condition {
command1
command2
}
ELSE {
command3
command4
}
Example 5 (ELSE can be followed by another command):
IF condition {
command1
command2
} ELSE IF condition {
command3
command4
} ELSE {
command5
command6
}
Example 5 suggests other possibilities:
IF condition {
command1
command2
} ELSE FOR variable initial final increment {
command3
command4
}
And this too is possible, except for some non-obvious quoting
considerations:
dcl \&a[6] = one two three four five six
IF < \%n 3 {
echo \\%n is too small: \%n
} ELSE FOR \\%i 1 \\%n 1 {
echo \\%i. \\&a[\\%i]
}
(The loop variable must be quoted in this context to prevent premature
evaluation.)
_________________________________________________________________
7.20.2. Boolean Expressions (The IF/WHILE Condition)
Prior to C-Kermit 7.0, the IF and WHILE commands accepted only a
single Boolean ("true or false") assertion, e.g. "if > \%m 0 command"
or "if exist filename command". There was no way to form Boolean
expressions and, in particular, nothing that approached a Boolean OR
function (AND could be simulated by concatenating IF statements: "if
condition1 if condition2..").
C-Kermit 7.0 (and K95 1.1.19) allow grouping of Boolean assertions
using parentheses and combining them using AND (or &&) and OR (or ||).
Each of these operators -- including the parentheses -- is a field and
must be set off by spaces. AND has higher precedence than OR, NOT has
higher precedence than AND, but parentheses can be used to force any
desired order of evaluation. The old syntax is still accepted.
Here are some examples:
define \%z 0 ; Define some variables
define \%n 1 ; for use in the examples.
if > \%n \%z echo \%n is greater. ; Original format - still accepted.
if ( > \%n \%z ) echo \%n is greater. ; Parentheses may be used in 7.0.
if ( > \%n \%z && not = \%z 0 ) ... ; Two assertions combined with AND.
if ( > \%n \%z and not = \%z 0 ) ... ; Same as previous ("and" = "&&").
if ( > \%n \%z || not = \%z 0 ) ... ; Two assertions combined with OR.
if ( > \%n \%z or not = \%z 0 ) ... ; Same as previous ("or" = "||").
if ( > \%n \%z || != \%z 0 ) ... ; Ditto ("!=" = "not =").
while ( 1 ) { ... } ; Just like C.
Notice the spaces around all operators including the parentheses --
these are required. The following examples show how parentheses can be
used to alter the precedence of the AND and OR operators:
if ( false || false && false || true ) ,.. ; True
if ( false || ( false && false ) || true ) ... ; Same as previous
if ( ( false || false ) && ( false || true ) ) ... ; False
Similarly for NOT:
if ( not true && false ) ... ; False (NOT binds to TRUE only)
if ( ( not true ) && false ) ... ; Same as previous
if ( not ( true && false ) ) ... ; True (NOT binds to (TRUE && FALSE))
Notes:
1. The syntax of the Boolean expression itself has not changed; each
expression begins with a keyword or token such as "EXIST", ">", or
"=", etc; operators such as "<", "=", and ">" do not go between
their operands but precede them as before; this might be called
"reverse reverse Polish notation"; it allows deterministic
on-the-fly parsing of these expressions at the C-Kermit> prompt as
well as in scripts, and allows ?-help to be given for each item
when IF or WHILE commands are typed at the prompt.
2. Parentheses are required when there is more than one Boolean
assertion.
3. Parentheses are not required, but are allowed, when there is only
one Boolean assertion.
4. Evaluation of Boolean assertions occurs left to right, but the
resulting Boolean expression is evaluated afterwards according to
the rules of precedence. All Boolean assertions are always
evaluated; there is no "early stopping" property and therefore no
question about when or if side effects will occur -- if any
Boolean assertion has side effects, they will always occur.
Constructions of arbitrary complexity are possible, within reason.
Also see [621]Section 7.4 for new IF / WHILE conditions.
_________________________________________________________________
7.21. Screen Formatting and Cursor Control
C-Kermit 7.0 adds a simple way to create formatted screens, the SCREEN
command:
SCREEN { CLEAR, CLEOL, MOVE-TO row [ column ] }
Performs screen-formatting actions. Correct operation of these
commands depends on proper terminal setup on both ends of the
connection -- mainly that the host terminal type is set to
agree with the kind of terminal or the emulation you are
viewing C-Kermit through. The UNIX version uses terminfo or
termcap (not curses); the VMS version uses SMG; K-95 uses its
built in screen manager.
SCREEN CLEAR
Moves the cursor to home position and clears the entire screen.
Synonyms: CLEAR COMMAND-SCREEN ALL (K-95 only), CLS, CLEAR
SCREEN.
SCREEN CLEOL
Clears from the current cursor position to the end of the line.
Synonym: CLEAR COMMAND-SCREEN EOL (K-95 only)
SCREEN MOVE-TO row column
Moves the cursor to the indicated row and column. The row and
column numbers are 1-based, so on a 24x80 screen the home
position is 1 1 and the lower right corner is 24 80. If a row
or column number is given that too large for what Kermit or the
operating system thinks is your screen size, the appropriate
number is substituted.
These escape sequences used by these commands depends on the platform.
In UNIX, your TERM environment variable is used to query the
terminfo/termcap database; if the query fails, ANSI/VT100 sequences
are used. In VMS, the SMG library is used, which sends sequences based
on your VMS terminal type. K95 does its own screen control. On other
platforms (such as AOS/VS, VOS, etc), screen formatting is not
supported, and the SCREEN command does nothing.
The three SCREEN actions can be used in scripts to produce menus,
formatted screens, dynamic displays, etc. Related variables include:
\v(terminal) The type terminal C-Kermit thinks you have.
\v(rows) The number of rows C-Kermit thinks your terminal has.
\v(columns) The number of columns C-Kermit thinks your terminal has.
And functions:
\fscrncurx() The current X coordinate of the cursor (K-95 only).
\fscrncury() The current Y coordinate of the cursor (K-95 only).
\fscrnstr(x,y,n) The string of length nat position (x,y) (K-95 only).
And commands:
ECHO string Writes string + CRLF at the current cursor position.
XECHO string Writes string at current cursor position; CRLF not supplied.
GETC v prompt Issues prompt, reads one character into variable v, no echo.
And special characters:
Ctrl-L At the C-Kermit> command prompt, or in a C-Kermit command,
works like Return or Enter, but also clears the screen
Example 1: A macro that prints a message \%1 at cursor position
(\%2,\%3):
define MSG {
if not def \%3 def \%3 0 ; Default column to 0
if > \v(argc) 2 screen move \%2 \%3 ; Move to given row/col (if any)
screen cleol ; Clear to end of line
if def \%1 xecho \fcontents(\%1) ; Print message (if any)
}
Example 2: A macro put the cursor on the bottom screen line, left
margin:
define BOT {
screen move \v(rows) 0
}
Example 3: A macro to center message \%1 on line \%2.
define CENTER {
if not def \%2 def \%2 1
.\%x ::= (\v(cols)-\flen(\%1))/2
msg {\%1} {\%2} {\%x}
}
Example 4: A simple menu (building on Examples 1-3):
def \%c 0 ; Menu choice variable
screen clear ; Clear the screen
center {Welcome to This Menu} 2 ; Display the menu
msg {Choices:} 4
msg { 1. File} 6
msg { 2. Edit} 7
msg { 3. Exit} 8
while ( != \%c 3 ) { ; Read and verify choice
while true { ; Keep trying till we get a good one
screen move 10 ; Move to line 10
screen cleol ; Clear this line
getc \%c {Your choice: } ; Prompt and get and echo 1 character
xecho \%c
if ( not numeric \%c ) { msg {Not numeric - "\%c"} 12, continue }
if ( >= \%c 1 && <= \%c 3 ) break
msg {Out of range - "\%c"} 12
}
switch \%c { ; Valid choice - execute it.
:1, msg {Filing... } 12, break
:2, msg {Editing...} 12, break
:3, msg {Exiting...} 12, break
}
}
echo Bye ; Exit chosen - say goodbye.
bot ; Leave cursor at screen bottom.
exit ; And exit.
Similar scripts can work over the communication connection; substitute
INPUT and OUTPUT for GETC and ECHO/XECHO.
_________________________________________________________________
7.22. Evaluating Arithmetic Expressions
A new arithmetic operator was added to the list recognized by the
EVALUATE command, the \feval() function, and which can also be used
anywhere else arithmetic expressions are accepted (numeric command
fields, array subscripts, etc):
Prefix "!"
This operator inverts the "truth value" of the number or
arithmetic expression that follows. If the value of the operand
is 0, the result is 1. If the value is nonzero, the result is
0.
Examples:
set eval old
evaluate 0
0
evaluate !0
1
evaluate !3
0
evaluate !(-3)
0
.\%a = 1
.\%b = 0
evaluate !(\%a|\%b)
0
evaluate !(\%a&\%b)
1
evaluate !(!(\%a&\%b))
0
Note the distinction between Prefix ! (invert truth value) and Suffix
! (factorial). Also the distinction between Prefix ! and Prefix ~
(which inverts all the bits in its operand). Also note that prefix
operators (!, -, and ~) can not be adjacent unless you use parentheses
to separate them, as shown in the final example above.
_________________________________________________________________
7.23. Floating-Point Arithmetic
C-Kermit 7.0 adds limited support for floating-point numbers (numbers
that have fractional parts, like 3.141592653). This support is
provided through a small repertoire of functions and in Boolean
expressions that compare numbers, but does not apply to number parsing
in general, or to expression evaluation, array subscripts, the
INCREMENT and DECREMENT commands, or in any context other than those
listed in this section.
A floating point number has an optional sign (+ or -), followed by a
series of decimal digits containing either zero or one period (.)
character, which is the decimal point. The use of comma or any other
character besides period as a decimal point is not supported.
Scientific notation is not supported either. Examples of legal
floating-point numbers:
0 Integers can be used
1 Ditto
2. A decimal point without decimal digits
3.0 A decimal point with decimal digits
3.141592653 Ditto
-4.0 A negative sign can be included
+5.0 A positive sign can be included
Examples of notations that are not accepted:
1,000,000 Separators can not be used
1.000.000 Ditto (or multiple decimal points)
6.022137E23 No scientific notation
6.62606868e-34 Ditto
12.5+6.25 No "bare" expressions
You can use IF FLOAT test a string or variable to see if it's in
acceptable floating-point format. Example:
ask \%f { Type a number: }
if not def \%f .\%f = 0.0
if not float \%f stop 1 Invalid floating-point number: "\%f"
C-Kermit's floating-point support, like its support for whole numbers
(integers), relies on the capabilities of the underlying computer.
Your computer has only a limited amount of precision for numbers,
depending on its architecture. Thus floating-point numbers that have
too many digits will not be accurate; adding a very small number to a
very large one might have no effect at all; and so on. For details,
read a text on numerical analysis. Example:
.\%a = 11111111111111111111 ; A long number
.\%b = 22222222222222222222 ; Another one
echo \ffpadd(\%a,\%b) ; Add them - the result should be all 3's
33333333333333330000.0 ; See the result
In this example, the computer has 16 digits of precision; after that,
the (low-order) digits are set to 0, since the computer doesn't know
what they really are. In fact, the computer returns random digits, but
Kermit sets all digits beyond the computer's precision to 0.
C-Kermit's floating-point functions have names of the form
"\ffpxxx(args)" ("\f" for function, "fp" for floating-point), where
"xxx" is replaced by the name of the function, such as "sqrt", and
"args" is the argument list, consisting of one or two floating-point
numbers (depending on the function), and an optional "d" argument that
says now many decimal places should be shown in the result. Example:
\ffpdiv(10,3,1) returns "3.3"
\ffpdiv(10,3,2) returns "3.33"
\ffpdiv(10,3,3) returns "3.333"
and so on, up to the precision of the computer. If the decimal-places
argument is less than zero, the fractional part of the result is
truncated:
\ffpdiv(10,3,-1) returns "3".
If the decimal-places argument is 0, or is omitted, C-Kermit returns
as many decimal places as are meaningful in the computer's
floating-point precision, truncating any extraneous trailing 0's:
\ffpdiv(10,8) returns "1.25".
\ffpdiv(10,4) returns "2.5".
\ffpdiv(10,2) returns "5.0".
\ffpdiv(10,3) returns "3.333333333333333" (for 16-digit precision).
There is no way to request that a floating-point function return a
decimal point but no decimal places. However, this is easy enough to
accomplish in other ways, for example by supplying it outside the
function call:
echo \ffpadd(\%a,\%b,-1).
Kermit's floating-point functions always round the result for the
requested number of decimal places when the "d" argument is given and
has a value greater than 0 (see the description of \ffpround() just
below).
Floating-point arguments can be constants in floating-point format or
variables whose values are floating-point numbers. If a floating-point
argument is omitted, or is a variable with no value, 0.0 is supplied
automatically. Example:
def \%x 999.999
undef \%y
echo \ffpmin(\%x,\%y)
0.0
Or equivalently:
echo \ffpmin(999.999)
0.0
The floating-point functions are:
\ffpround(f1,d)
Returns f1 rounded to d decimal places. For this function only,
d = 0 (or d omitted) has a special meaning: return the integer
part of f1 rounded according to the fractional part. Examples:
\ffpround(2.74653,-1) returns "2" (fraction truncated, no rounding).
\ffpround(2.74653,0) returns "3" (integer part is rounded).
\ffpround(2.74653) returns "3" (d omitted same as d = 0).
\ffpround(2.74653,1) returns "2.7".
\ffpround(2.74653,2) returns "2.75".
\ffpround(2.74653,3) returns "2.747".
\ffpround(2.74653,4) returns "2.7465", etc.
\ffpadd(f1,f2,d)
Returns the sum of f1 and f2.
\ffpsubtract(f1,f2,d)
Subtracts f2 from f1 and returns the result.
\ffpmultiply(f1,f2,d)
Returns the product of f1 and f2.
\ffpdivide(f1,f2,d)
If f2 is not 0, divides f1 by f2 and returns the quotient.
If f2 is 0, a DIVIDE_BY_ZERO error occurs.
\ffpraise(f1,f2,d)
If f1 = 0 and f2 <= 0, or if f1 < 0 and f2 has a fractional
part, an ARG_OUT_OF_RANGE error occurs; otherwise f1 raised to
the f2 power is returned.
\ffpsqrt(f1,d)
If f1 >= 0, returns the square root of f1; otherwise
ARG_OUT_OF_RANGE.
\ffpabsolute(f1,d)
Returns the absolute value of f1 (i.e. f1 without a sign). This
is the floating-point analog of \fabsolute(n1).
\ffpint(f1)
Returns the integer part of f1. Equivalent to \ffpround(f1,-1).
\ffpexp(f1,d)
The base of natural logarithms, e (2.718282...), raised to the
f1 power.
\ffplogn(f1,d)
The natural logarithm of f1 (the power to which e must be
raised to obtain f1).
\ffplog10(f1,d)
The base-10 logarithm of f1 (the power to which 10 must be
raised to obtain f1).
\ffpmodulus(f1,f2,d)
If f2 is not 0, the remainder after dividing f1 by f2.
If f2 is 0, a DIVIDE_BY_ZERO error occurs.
This is the floating-point analog of \fmod(n1,n2).
\ffpmaximum(f1,f2,d)
Returns the maximum of f1 and f2. This is the floating-point
analog of \fmax(n1,n2).
\ffpminimum(f1,f2,d)
Returns the minimum of f1 and f2. This is the floating-point
analog of \fmin(n1,n2).
\ffpsine(f1,d)
Returns the sine of f1 radians.
\ffpcosine(f1,d)
Returns the cosine of f1 radians.
\ffptangent(f1,d)
Returns the tangent of f1 radians.
Note that all of these functions can be used with integer arguments.
If you want an integer result, specify d = -1 (to truncate) or feed
the result to \ffpround(xxx,0) (to round).
Floating-point numbers (or variables or functions that return them)
can be used in Boolean expressions (see [622]Section 7.20.2) that
compare numbers:
= x y
!= x y
< x y
> x y
<= x y
>= x y
In these examples, x and y can be either integers or floating-point
numbers in any combination. In an arithmetic comparison of an integer
and a floating-point number, the integer is converted to
floating-point before the comparison is made. Examples:
.\%t = 3.000000000
.\%f = 3.141592653
.\%i = 3
if > \%f \%i echo Pi is greater.
if = \%t \%i echo "\%i" = "\%t".
A floating-point number can also be used in:
IF number command
where the command is executed if the number is nonzero. If the number
is floating-point, the command is not executed if the number is 0.0,
and is executed otherwise.
Floating-point numbers can be sorted using ARRAY SORT /NUMERIC (see
[623]Section 7.10.5 ).
Two floating-point constants are provided:
\v(math_pi) = Pi (3.141592653...)
\v(math_e) = e, the base of natural logarithms (2.71828...)
These are given to the computer's precision, e.g. 16 digits. This
number itself is available in a variable:
\v(math_precision)
How many significant digits in a floating-point number.
_________________________________________________________________
7.24. Tracing Script Execution
The TRACE command is handy for debugging scripts.
TRACE [ { /ON, /OFF } ] [ { ASSIGNMENTS, COMMAND-LEVEL, ALL } ]
Selects tracing of the given object.
Optional switches are /ON and /OFF. If no switch is given, /ON is
implied. The trace objects are ASSIGNMENTS, COMMAND-LEVEL, and ALL.
The default object is ALL, meaning to select all trace objects
(besides ALL). Thus TRACE by itself selects tracing of everything, as
does TRACE /ON, and TRACE /OFF turns off all tracing.
When tracing of ASSIGNMENTS is on, every time the value of any
user-defined variable or macro changes, C-Kermit prints one of the
following:
>>> name: "value"
The name of the variable or macro followed by the new value in
quotes. This includes implicit macro-parameter assignments
during macro invocation.
>>> name: (undef)
This indicates that the variable or macro has been undefined.
<<< name: "value"
For RETURN statements: the name of the macro and the return
value.
<<< name: (null)
For RETURN statements that include no value or an empty value.
When tracing of COMMAND-LEVEL is on, C-Kermit prints:
[n] +F: "name"
Whenever a command file is entered, where "n" is the command
level (0 = top); the name of the command file is shown in
quotes.
[n] +M: "name"
Whenever a macro is entered; "n" is the command level. The name
of the macro is shown in quotes.
[n] -F: "name"
Whenever a command file is reentered from below, when a macro
or command file that it has invoked has returned.
[n] -M: "name"
Whenever a macro is reentered from below.
For other debugging tools, see SHOW ARGS, SHOW STACK, SET TAKE, SET
MACRO, and of course, ECHO.
_________________________________________________________________
7.25. Compact Substring Notation
It is often desirable to extract a substring from a string which is
stored in a variable, and for this we have the \fsubstring() function,
which is used like this:
define \%a 1234567890
echo \fsubstring(\%a,3,4) ; substring from 3rd character length 4
3456
or like this with macro-named variables:
define string 1234567890
echo \fsubstring(\m(string),3,4)
3456
C-Kermit 7.0 adds a pair of alternative compact notations:
\:(variablename[start:length]) <-- Substring of variable's value
\s(macroname[start:length]) <-- Substring of macro's definition
These are exactly equivalent to using \fsubstring(), except more
compact to write and also faster since evaluation is in one step
instead of two.
The "\:()" notation can be used with any Kermit variable, that is,
almost anything that starts with a backslash:
\:(\%a[2:6]) <-- equivalent to \fsubstring(\%a,2,6)
\:(\&x[1][2:6]) <-- equivalent to \fsubstring(\&x[1],2,6)
\:(\m(foo)[2:6]) <-- equivalent to \fsubstring(\m(foo),2,6)
\:(\v(time)[2:6]) <-- equivalent to \fsubstring(\v(time),2,6)
\:(\$(TERM)[2:6]) <-- equivalent to \fsubstring(\$(TERM),2,6)
\:(ABCDEFGH[2:6]) <-- equivalent to \fsubstring(ABCDEFGH,2,6)
Whatever appears between the left parenthesis and the left bracket is
evaluated and then the indicated substring of the result is returned.
The "\s()" notation is the same, except after evaluating the variable,
the result is treated as a macro name and is looked up in the macro
table. Then the indicated substring of the macro definition is
returned. Example:
define testing abcdefghijklmnopqrstuvwxyz
define \%a testing
\s(testing[2:6]) --> bcdefg
\:(testing[2:6]) --> esting
\:(\%a[2:6]) --> esting
\s(\%a[2:6]) --> bcdefg
Note that the following two examples are equivalent:
\:(\m(foo)[2:6])
\s(foo[2:6])
The first number in the brackets is the 1-based starting position. If
it is omitted, or less than 1, it is treated as 1. If it is greater
than the length of the string, an empty string is returned.
The second number is the length of the desired substring. If the
second number is omitted, is less than 0, or would be past the end of
the string, then "through the end of the string" is assumed. If it is
0, the empty string is returned.
If the brackets are empty or omitted, the original string is returned.
The starting position and length need not be literal numbers; they can
also be variables, functions, arithmetic expressions, or even other
\s() or \:() quantities; anything that evaluates to a number, for
example:
\s(block[1025:\fhex2n(\s(block[\%b:\%n+4]))/2])
Syntactically, \m(name) and \s(name) differ only in that the sequence
[*] at the end of the name (where * is any sequence of 0 or more
characters) is treated as substring notation in \s(name), but is
considered part of the name in \m(name) (to see why, see [624]Section
7.10.9).
_________________________________________________________________
7.26. New WAIT Command Options
The WAIT command has been extended to allow waiting for different
kinds of things (formerly it only waited for modem signals). Now it
also can wait for file events.
7.26.1. Waiting for Modem Signals
The previous syntax:
WAIT time { CD, DSR, RTS, RI, ... }
has changed to:
WAIT time MODEM-SIGNALS { CD, DSR, RTS, RI, ... }
However, the previous syntax is still accepted. The behavior is the
same in either case.
_________________________________________________________________
7.26.2. Waiting for File Events
The new WAIT option:
WAIT time FILE { CREATION, DELETION, MODIFICATION } filename
lets you tell Kermit to wait the given amount of time (or until the
given time of day) for a file whose name is filename to be created,
deleted, or modified, respectively. The filename may not contain
wildcards. If the specified event does not occur within the time
limit, or if WAIT CANCELLATION is ON and you interrupt from the
keyboard before the time is up, the WAIT command fails. If the event
is MODIFICATION and the file does not exist, the command fails.
Otherwise, if the given event occurs within the time limit, the
command succeeds. Examples:
WAIT 600 FILE DELETION oofa.tmp
Wait up to 10 minutes for file oofa.tmp to disappear.
WAIT 23:59:59 FILE MOD orders.db
Wait until just before midnight for the orders.db file to be
changed.
Example: Suppose you want to have the current copy of /etc/motd on
your screen at all times, and you want to hear a bell whenever it
changes:
def \%f /etc/motd ; The file of interest.
while 1 { ; Loop forever...
cls ; Clear the screen.
echo \%f: \v(date) \v(time)... ; Print 2-line heading...
echo
if ( not exist \%f ) { ; If file doesn't exist,
echo \%f does not exist... ; print message,
wait 600 file creat \%f ; and wait for it to appear.
continue
}
beep ; Something new - beep.
type /head:\v(rows-2) \%f ; Display the file
if fail exit 1 \%f: \ferrstring() ; (checking for errors).
wait 999 file mod \%f ; Wait for it to change.
}
This notices when the file is created, deleted, or modified, and acts
only then (or when you interrupt it with); the time shown in the
heading is the time of the most recent event (including when the
program started).
See [625]Section 1.10, where the \v(kbchar) variable is explained.
This lets you modify a loop like the one above to also accept
single-character commands, which interrupt the WAIT, and dispatch
accordingly. For example:
wait 999 file mod \%f ; Wait for the file to change.
if defined \v(kbchar) { ; Interrupted from keyboard?
switch \v(kbchar) { ; Handle the keystroke...
:q, exit ; Q to Quit
:h, echo blah blah, break ; H for Help
:default, beep, continue ; Anything else beep and ignore
}
}
This lets you write event-driven applications that wait for up to
three events at once: a file or modem event, a timeout, and a
keystroke.
_________________________________________________________________
7.27. Relaxed FOR and SWITCH Syntax
For consistency with the extended IF and WHILE syntax, the FOR and
SWITCH control lists may (but need not be) enclosed in parentheses:
FOR ( \%i 1 \%n 1 ) { command-list... }
SWITCH ( \%c ) { command-list... }
In the FOR command, the increment item can be omitted if the control
list is enclosed in parentheses, in which case the increment defaults
appropriately to 1 or -1, depending on the values of the first two
variables.
As with IF, the parentheses around the FOR-command control list must
be set off by spaces (in the SWITCH command, the spaces are not
required since the SWITCH expression is a single arithmetic
expression).
Also, outer braces around the command list are supplied automatically
if you omit them, e.g.:
FOR ( \%i 1 %n 1 ) echo \%i
_________________________________________________________________
8. USING OTHER FILE TRANSFER PROTOCOLS
In C-Kermit 7.0, alternative protocols can be selected using switches.
Switches are described in [626]Section 1.5; the use of
protocol-selection switches is described in [627]Section 4.7.1.
Example:
send /binary /protocol:zmodem x.tar.gz
Note that file transfer recovery works only with Kermit and Zmodem
protocols. With Zmodem, recovery can be initiated only by the sender.
Only pre-1988 versions of the publicly-distributed sz/rz programs use
Standard I/O; those released later than that do not use Standard I/O
and therefore do not work with REDIRECT. However, Omen Technology does
offer an up-to-date redirectable version called crzsz, which must be
licensed for use:
"Unix Crz and Csz support XMODEM, YMODEM, and ZMODEM transfers when
called by dial-out programs such as Kermit and certain versions of
cu(1). They are clients designed for this use.
"Crz and Csz are Copyrighted shareware programs. Use of these
programs beyond a brief evaluation period requires registration.
Please print the "mailer.rz" file, fill out the form and return
same with your registration."
To use the crzsz programs as your external XYZMODEM programs in
C-Kermit, follow the instructions in the book, but put a "c" before
each command, e.g.:
set protocol zmodem {csz %s} {csz -a %s} crz crz crz crz
To use Zmodem protocol over Telnet or other non-transparent
connections, you might need to add the -e (Escape) option:
set protocol zmodem {csz -e %s} {csz -e -a %s} crz crz crz crz
_________________________________________________________________
9. COMMAND-LINE OPTIONS
9.0. Extended-Format Command-Line Options
Standard UNIX command line options are a single letter. C-Kermit has
run out of letters, so new options are in a new extended format:
--word[:arg]
where a keyword (rather than a single letter) specifies the function,
and if an argument is to be included, it is separated by a colon (or
equal sign). Most of the new extended-format command-line options are
only for use with the Internet Kermit Service Daemon; see the
[628]IKSD Administration Guide for details. However, several of them
are also general in nature:
--nointerrupts
Disables keyboard interrupts that are normally enabled, which
are usually Ctrl-C (to interrupt a command) and Ctrl-Z (UNIX
only, to suspend C-Kermit).
--help
Lists the extended command-line options that are available in
your version of C-Kermit. If any options seem to be missing,
that is because your copy of C-Kermit was built with
compile-time options to deselect them.
--helpfile:filename
Specifies the name of a file to be displayed if the user types
HELP (not followed by a specific command or topic), in place of
the built-in top-level help text. The file need not fit on one
screen; more-prompting is used if the file is more than one
screen long if COMMAND MORE-PROMPTING is ON, as it is by
default.
--bannerfile:filename
The name of a file containing a message to be printed after the
user logs in, in place of the normal message (Copyright notice,
"Type HELP or ? for help", "Default transfer mode is...", etc).
--cdmessage:{on,off,0,1,2}
For use in the Server-Side Server configuration; whenever the
client tells the server to change directory, the server sends
the contents of a "read me" file to the client's screen. This
feature is On by default, and operates only in client/server
mode when ON or 1. If set to 2 or higher, it also operates when
the CD command is given at the IKSD> prompt. Synonym: --cdmsg.
--cdfile:filename
When cdmessage is on, this is the name of the "read me" file to
be sent. Normally you would specify a relative (not absolute)
name, since the file is opened using the literal name you
specified, after changing to the new directory. Example:
--cdfile:READ.ME
You can also give a list of up to 8 filenames by (a) enclosing
each filename in braces, and (b) enclosing the entire list in
braces. Example:
--cdfile:{{./.readme}{READ.ME}{aaareadme.txt}{README}{read-this
-first}} When a list is given, it is searched from left to
right and the first file found is displayed. The default list
for UNIX is:
{{./.readme}{README.TXT}{READ.ME}}
_________________________________________________________________
9.1. Command Line Personalities
Beginning in version 7.0, if the C-Kermit binary is renamed to
"telnet" (or TELNET.EXE, telnet.pr, etc, depending on the platform),
it accepts the Telnet command line:
telnet [ host [ port ] ]
In Unix, you can achieve the same effect with a symlink:
cd /usr/bin
mv telnet oldtelnet
ln -ls /usr/local/bin/kermit telnet
When installed in this manner, C-Kermit always reads its
initialization file. If no host (and therefore no port) is given,
C-Kermit starts in interactive prompting mode. If a host is given as
the first command-line argument, C-Kermit makes a connection to it.
The host argument can be an IP host name or address, or the name of a
TCP/IP entry in your C-Kermit network directory.
If a port is given, it is used. If a port is not given, then if the
hostname was found in your network directory and port was also listed
there, then that port is used. Otherwise port 23 (the Telnet port) is
used.
When C-Kermit is called "telnet" and it is invoked with a hostname on
the command line, it exits automatically when the connection is
closed. While the connection is open, however, you may escape back and
forth as many times as you like, transfer files, etc.
An rlogin personality is also available, but it is less useful, at
least in UNIX and VMS, where the Rlogin TCP port is privileged.
The new variable \v(name) indicates the name with which C-Kermit was
invoked ("kermit", "wermit", "k95", "telnet", etc).
_________________________________________________________________
9.2. Built-in Help for Command Line Options
"kermit -h", given from the system prompt, lists as many command-line
options as will fit on a standard 24x80 screen. For more comprehensive
help, use the interactive HELP OPTIONS command that was added in
C-Kermit 7.0:
HELP OPTIONS
Explains how command-line options work, their syntax, etc.
HELP OPTIONS ALL
Lists all command-line options and gives brief help about each one.
HELP OPTION x
Gives brief help about option "x".
HELP EXTENDED-OPTIONS
Lists the available extended-format command-line options.
HELP EXTENDED-OPTION xxx
Gives help for the specified extended option.
_________________________________________________________________
9.3. New Command-Line Options
Command-line options added since C-Kermit 6.0 are:
+
(plus sign by itself): The next argument is the name of a
script to execute; all subsequent arguments are ignored by
C-Kermit itself, but passed to the script as top-level copies
of \%1, \%2, etc; the \&_[] is also set accordingly. \%0 and
\&_[0] become the name of the script file, rather than the
pathname of the C-Kermit program, which is its normal value.
Primarily for use in the top line of "Kerbang" scripts in UNIX
(see [629]Section 7.19). Example from UNIX command line:
$ kermit [ regular kermit args ] + filename
Sample first line of Kerbang script:
#!/usr/local/bin/kermit +
--
(two hyphens surrounded by whitespace) Equivalent to "=", for
compatibility with UNIX getopt(1,3).
-G
GET (like -g), but send the incoming file to standard output.
Example: "kermit -G oofa.txt | lpr" retrieves a file from your
local computer (providing it is running a Kermit program that
supports the autodownload feature and has it enabled) and
prints it.
-O
equivalent to -x (start up in server mode), but exits after the
first client command has been executed (mnemonic: O = Only
One). This one is handy replacing "kermit -x" in the
"automatically start Kermit on the other end" string:
set protocol kermit {kermit -ir} {kermit -r} {kermit -x}
since -x leaves the remote Kermit in server mode after the
transfer, which can be confusing, whereas -O makes it go away
automatically after the transfer.
-L
Recursive, when used in combination with -s (mnemonic: L =
Levels). In UNIX or other environments where the shell expands
wildcards itself, the -s argument, if it contains wildcards,
must be quoted to prevent this, e.g.:
kermit -L -s "*.c"
In UNIX only, "kermit -L -s ." means to send the current
directory tree. See [630]Sections 4.10 and [631]4.11 about
recursive file transfer.
-V
Equivalent to SET FILE PATTERNS OFF ([632]Section 4.3) and SET
TRANSFER MODE MANUAL. In other words, take the FILE TYPE
setting literally. For example, "kermit -VT oofa.bin" means
send the file in Text mode, no matter what its name is and no
matter whether a kindred spirit is recognized at the other end
of the connection.
-0
(digit zero) means "be 100% transparent in CONNECT mode". This
is equivalent to the following series of commands: SET PARITY
NONE, SET COMMAND BYTESIZE 8, SET TERMINAL BYTESIZE 8, SET FLOW
NONE, SET TERM ESCAPE DISABLED, SET TERM CHAR TRANSPARENT, SET
TERM AUTODOWNLOAD OFF, SET TERM APC OFF, SET TELOPT KERMIT
REFUSE REFUSE.
_________________________________________________________________
10. C-KERMIT AND G-KERMIT
Every multifunctioned and long-lived software program grows in
complexity and size over time to meet the needs and requests of its
users and the demands of the underlying technology as it changes.
Eventually users begin to notice how big the application has grown,
how much disk space it occupies, how long it takes to load, and they
start to long for the good old days when it was lean and mean. Not
long after that they begin asking for a "light" version that only does
the basics with no frills.
And so it is with C-Kermit. A "light" version of Kermit was released
(for UNIX only) in December 1999 under the GNU General Public License;
thus it is called G-Kermit (for GNU Kermit). All it does is send and
receive files, period. You can find it at:
[633]http://www.columbia.edu/kermit/gkermit.html
Where the C-Kermit 7.0 binary might be anywhere from 1 to 3 million
bytes in size, the G-Kermit binary ranges from 30K to 100K, depending
on the underlying architecture (RISC vs CISC, etc).
G-Kermit and C-Kermit may reside side-by-side on the same computer.
G-Kermit does not make connections; it does not have a script
language; it does not translate character sets. G-Kermit may be used
instead of C-Kermit when:
* It is on the remote end.
* Files are to be transferred in binary mode or in text mode without
character-set translation.
* File timestamps don't need to be preserved.
In such cases G-Kermit might be preferred since it generally starts up
faster, and yet transfers files just as fast on most (but not
necessarily all) kinds of connections; for example, it supports
streaming ([634]Section 4.20).
G-Kermit is also handy for bootstrapping. It is easier to load on a
new computer than C-Kermit -- it fits on a floppy diskette with plenty
of room to spare. Thus if you have (say) an old PC running (say) SCO
Xenix and no network connection, you can download the Xenix version of
G-Kermit to (say) a DOS or Windows PC, copy it to diskette, read the
diskette on Xenix with "dosread", and then use G-Kermit to receive
C-Kermit (which does not fit on a diskette). If diskettes aren't an
option, other bootstrapping methods are possible too -- see the
[635]G-Kermit web page for details.
_________________________________________________________________
III. APPENDICES
III.1. Character Set Tables
III.1.1. The Hewlett Packard Roman8 Character Set
dec col/row oct hex description
160 10/00 240 A0 (Undefined)
161 10/01 241 A1 A grave
162 10/02 242 A2 A circumflex
163 10/03 243 A3 E grave
164 10/04 244 A4 E circumflex
165 10/05 245 A5 E diaeresis
166 10/06 246 A6 I circumflex
167 10/07 247 A7 I diaeresis
168 10/08 250 A8 Acute accent
169 10/09 251 A9 Grave accent
170 10/10 252 AA Circumflex accent
171 10/11 253 AB Diaeresis
172 10/12 254 AC Tilde accent
173 10/13 255 AD U grave
174 10/14 256 AE U circumflex
175 10/15 257 AF Lira symbol
176 11/00 260 B0 Top bar (macron)
177 11/01 261 B1 Y acute
178 11/02 262 B2 y acute
179 11/03 263 B3 Degree Sign
180 11/04 264 B4 C cedilla
181 11/05 265 B5 c cedilla
182 11/06 266 B6 N tilde
183 11/07 267 B7 n tilde
184 11/08 270 B8 Inverted exclamation mark
185 11/09 271 B9 Inverted question mark
186 11/10 272 BA Currency symbol
187 11/11 273 BB Pound sterling symbol
188 11/12 274 BC Yen symbol
189 11/13 275 BD Paragraph
190 11/14 276 BE Florin (Guilder) symbol
191 11/15 277 BF Cent symbol
192 12/00 300 C0 a circumflex
193 12/01 301 C1 e circumflex
194 12/02 302 C2 o circumflex
195 12/03 303 C3 u circumflex
196 12/04 304 C4 a acute
197 12/05 305 C5 e acute
198 12/06 306 C6 o acute
199 12/07 307 C7 u acute
200 12/08 310 C8 a grave
201 12/09 311 C9 e grave
202 12/10 312 CA o grave
203 12/11 313 CB u grave
204 12/12 314 CC a diaeresis
205 12/13 315 CD e diaeresis
206 12/14 316 CE o diaeresis
207 12/15 317 CF u diaeresis
208 13/00 320 D0 A ring
209 13/01 321 D1 i circumflex
210 13/02 322 D2 O with stroke
211 13/03 323 D3 AE digraph
212 13/04 324 D4 a ring
213 13/05 325 D5 i acute
214 13/06 326 D6 o with stroke
215 13/07 327 D7 ae digraph
216 13/08 330 D8 A diaeresis
217 13/09 331 D9 i grave
218 13/10 332 DA O diaeresis
219 13/11 333 DB U diaeresis
220 13/12 334 DC E acute
221 13/13 335 DD i diaeresis
222 13/14 336 DE German sharp s
223 13/15 337 DF O circumflex
224 14/00 340 E0 A acute
225 14/01 341 E1 A tilde
226 14/02 342 E2 a tilde
227 14/03 343 E3 Icelandic Eth
228 14/04 344 E4 Icelandic eth
229 14/05 345 E5 I acute
230 14/06 346 E6 I grave
231 14/07 347 E7 O acute
232 14/08 350 E8 O grave
233 14/09 351 E9 O tilde
234 14/10 352 EA o tilde
235 14/11 353 EB S caron
236 14/12 354 EC s caron
237 14/13 355 ED U acute
238 14/14 356 EE Y diaeresis
239 14/15 357 EF y diaeresis
240 15/00 360 F0 Icelandic Thorn
241 15/01 361 F1 Icelandic thorn
242 15/02 362 F2 Middle dot
243 15/03 363 F3 Greek mu
244 15/04 364 F4 Pilcrow sign
245 15/05 365 F5 Fraction 3/4
246 15/06 366 F6 Long dash, horizontal bar
247 15/07 367 F7 Fraction 1/4
248 15/08 370 F8 Fraction 1/2
249 15/09 371 F9 Feminine ordinal
250 15/10 372 FA Masculine ordinal
251 15/11 373 FB Left guillemot
252 15/12 374 FC Solid box
253 15/13 375 FD Right guillemot
254 15/14 376 FE Plus or minus sign
255 15/15 377 FF (Undefined)
_________________________________________________________________
III.1.2. Greek Character Sets
III.1.2.1. The ISO 8859-7 Latin / Greek Alphabet = ELOT 928
dec col/row oct hex description
160 10/00 240 A0 No-break space
161 10/01 241 A1 Left single quotation mark
162 10/02 242 A2 right single quotation mark
163 10/03 243 A3 Pound sign
164 10/04 244 A4 (UNUSED)
165 10/05 245 A5 (UNUSED)
166 10/06 246 A6 Broken bar
167 10/07 247 A7 Paragraph sign
168 10/08 250 A8 Diaeresis (Dialytika)
169 10/09 251 A9 Copyright sign
170 10/10 252 AA (UNUSED)
171 10/11 253 AB Left angle quotation
172 10/12 254 AC Not sign
173 10/13 255 AD Soft hyphen
174 10/14 256 AE (UNUSED)
175 10/15 257 AF Horizontal bar (Parenthetiki pavla)
176 11/00 260 B0 Degree sign
177 11/01 261 B1 Plus-minus sign
178 11/02 262 B2 Superscript two
179 11/03 263 B3 Superscript three
180 11/04 264 B4 Accent (tonos)
181 11/05 265 B5 Diaeresis and accent (Dialytika and Tonos)
182 11/06 266 B6 Alpha with accent
183 11/07 267 B7 Middle dot (Ano Teleia)
184 11/08 270 B8 Epsilon with accent
185 11/09 271 B9 Eta with accent
186 11/10 272 BA Iota with accent
187 11/11 273 BB Right angle quotation
188 11/12 274 BC Omicron with accent
189 11/13 275 BD One half
190 11/14 276 BE Upsilon with accent
191 11/15 277 BF Omega with accent
192 12/00 300 C0 iota with diaeresis and accent
193 12/01 301 C1 Alpha
194 12/02 302 C2 Beta
195 12/03 303 C3 Gamma
196 12/04 304 C4 Delta
197 12/05 305 C5 Epsilon
198 12/06 306 C6 Zeta
199 12/07 307 C7 Eta
200 12/08 310 C8 Theta
201 12/09 311 C9 Iota
202 12/10 312 CA Kappa
203 12/11 313 CB Lamda
204 12/12 314 CC Mu
205 12/13 315 CD Nu
206 12/14 316 CE Ksi
207 12/15 317 CF Omicron
208 13/00 320 D0 Pi
209 13/01 321 D1 Rho
210 13/02 322 D2 (UNUSED)
211 13/03 323 D3 Sigma
212 13/04 324 D4 Tau
213 13/05 325 D5 Upsilon
214 13/06 326 D6 Phi
215 13/07 327 D7 Khi
216 13/08 330 D8 Psi
217 13/09 331 D9 Omega
218 13/10 332 DA Iota with diaeresis
219 13/11 333 DB Upsilon with diaeresis
220 13/12 334 DC alpha with accent
221 13/13 335 DD epsilon with accent
222 13/14 336 DE eta with accent
223 13/15 337 DF iota with accent
224 14/00 340 E0 upsilon with diaeresis and accent
225 14/01 341 E1 alpha
226 14/02 342 E2 beta
227 14/03 343 E3 gamma
228 14/04 344 E4 delta
229 14/05 345 E5 epsilon
230 14/06 346 E6 zeta
231 14/07 347 E7 eta
232 14/08 350 E8 theta
233 14/09 351 E9 iota
234 14/10 352 EA kappa
235 14/11 353 EB lamda
236 14/12 354 EC mu
237 14/13 355 ED nu
238 14/14 356 EE ksi
239 14/15 357 EF omicron
240 15/00 360 F0 pi
241 15/01 361 F1 rho
242 15/02 362 F2 terminal sigma
243 15/03 363 F3 sigma
244 15/04 364 F4 tau
245 15/05 365 F5 upsilon
246 15/06 366 F6 phi
247 15/07 367 F7 khi
248 15/08 370 F8 psi
249 15/09 371 F9 omega
250 15/10 372 FA iota with diaeresis
251 15/11 373 FB upsilon with diaeresis
252 15/12 374 FC omicron with diaeresis
253 15/13 375 FD upsilon with accent
254 15/14 376 FE omega with accent
255 15/15 377 FF (UNUSED)
_________________________________________________________________
III.1.2.2. The ELOT 927 Character Set
dec col/row oct hex description
32 02/00 40 20 SPACE
33 02/01 41 21 EXCLAMATION MARK
34 02/02 42 22 QUOTATION MARK
35 02/03 43 23 NUMBER SIGN
36 02/04 44 24 DOLLAR SIGN
37 02/05 45 25 PERCENT SIGN
38 02/06 46 26 AMPERSAND
39 02/07 47 27 APOSTROPHE
40 02/08 50 28 LEFT PARENTHESIS
41 02/09 51 29 RIGHT PARENTHESIS
42 02/10 52 2A ASTERISK
43 02/11 53 2B PLUS SIGN
44 02/12 54 2C COMMA
45 02/13 55 2D HYPHEN, MINUS SIGN
46 02/14 56 2E PERIOD, FULL STOP
47 02/15 57 2F SOLIDUS, SLASH
48 03/00 60 30 DIGIT ZERO
49 03/01 61 31 DIGIT ONE
50 03/02 62 32 DIGIT TWO
51 03/03 63 33 DIGIT THREE
52 03/04 64 34 DIGIT FOUR
53 03/05 65 35 DIGIT FIVE
54 03/06 66 36 DIGIT SIX
55 03/07 67 37 DIGIT SEVEN
56 03/08 70 38 DIGIT EIGHT
57 03/09 71 39 DIGIT NINE
58 03/10 72 3A COLON
59 03/11 73 3B SEMICOLON
60 03/12 74 3C LESS-THAN SIGN, LEFT ANGLE BRACKET
61 03/13 75 3D EQUALS SIGN
62 03/14 76 3E GREATER-THAN SIGN, RIGHT ANGLE BRACKET
63 03/15 77 3F QUESTION MARK
64 04/00 100 40 COMMERCIAL AT SIGN
65 04/01 101 41 CAPITAL LETTER A
66 04/02 102 42 CAPITAL LETTER B
67 04/03 103 43 CAPITAL LETTER C
68 04/04 104 44 CAPITAL LETTER D
69 04/05 105 45 CAPITAL LETTER E
70 04/06 106 46 CAPITAL LETTER F
71 04/07 107 47 CAPITAL LETTER G
72 04/08 110 48 CAPITAL LETTER H
73 04/09 111 49 CAPITAL LETTER I
74 04/10 112 4A CAPITAL LETTER J
75 04/11 113 4B CAPITAL LETTER K
76 04/12 114 4C CAPITAL LETTER L
77 04/13 115 4D CAPITAL LETTER M
78 04/14 116 4E CAPITAL LETTER N
79 04/15 117 4F CAPITAL LETTER O
80 05/00 120 50 CAPITAL LETTER P
81 05/01 121 51 CAPITAL LETTER Q
82 05/02 122 52 CAPITAL LETTER R
83 05/03 123 53 CAPITAL LETTER S
84 05/04 124 54 CAPITAL LETTER T
85 05/05 125 55 CAPITAL LETTER U
86 05/06 126 56 CAPITAL LETTER V
87 05/07 127 57 CAPITAL LETTER W
88 05/08 130 58 CAPITAL LETTER X
89 05/09 131 59 CAPITAL LETTER Y
90 05/10 132 5A CAPITAL LETTER Z
91 05/11 133 5B LEFT SQUARE BRACKET
92 05/12 134 5C REVERSE SOLIDUS, BACKSLASH
93 05/13 135 5D RIGHT SQUARE BRACKET
94 05/14 136 5E CIRCUMFLEX ACCENT
95 05/15 137 5F UNDERSCORE
96 06/00 140 60 ACCENT GRAVE
97 06/01 141 61 GREEK LETTER ALPHA
98 06/02 142 62 GREEK LETTER BETA
99 06/03 143 63 GREEK LETTER GAMMA
100 06/04 144 64 GREEK LETTER DELTA
101 06/05 145 65 GREEK LETTER EPSILON
102 06/06 146 66 GREEK LETTER ZETA
103 06/07 147 67 GREEK LETTER ETA
104 06/08 150 68 GREEK LETTER THETA
105 06/09 151 69 GREEK LETTER IOTA
106 06/10 152 6A GREEK LETTER KAPPA
107 06/11 153 6B GREEK LETTER LAMDA
108 06/12 154 6C GREEK LETTER MU
109 06/13 155 6D GREEK LETTER NU
110 06/14 156 6E GREEK LETTER KSI
111 06/15 157 6F GREEK LETTER OMICRON
112 07/00 160 70 GREEK LETTER PI
113 07/01 161 71 GREEK LETTER RHO
114 07/02 162 72 GREEK LETTER SIGMA
115 07/03 163 73 GREEK LETTER TAU
116 07/04 164 74 GREEK LETTER UPSILON
117 07/05 165 75 GREEK LETTER FI
118 07/06 166 76 GREEK LETTER XI
119 07/07 167 77 GREEK LETTER PSI
120 07/08 170 78 GREEK LETTER OMEGA
121 07/09 171 79 SPACE
122 07/10 172 7A SPACE
123 07/11 173 7B LEFT CURLY BRACKET, LEFT BRACE
124 07/12 174 7C VERTICAL LINE, VERTICAL BAR
125 07/13 175 7D RIGHT CURLY BRACKET, RIGHT BRACE
126 07/14 176 7E TILDE
127 07/15 177 7F RUBOUT, DELETE
_________________________________________________________________
III.1.2.3. PC Code Page 869
(to be filled in...)
_________________________________________________________________
III.2. Updated Country Codes
Date: Mon, 7 Apr 1997 23:23:49 EDT
From: Dave Leibold <dleibold@else.net>
Newsgroups: comp.dcom.telecom
Subject: Ex-USSR Country Codes Profile
Organization: TELECOM Digest
Ex-USSR Country Codes Profile
4 April 1997
Below is a summary of the country codes that have formed in the wake
of the USSR dissolution, along with some updated findings and reports.
Additional or corrected information on any of these nations would be
welcome (c/o dleibold@else.net).
* Kyrgyz Republic country code 996 will take effect, at least in
Canada, effective 1 May 1997, according to CRTC Telecom Order
97-464, based on Stentor Tariff Notice 433. There is no indication
whether there will be a permissive dialing period involved or for
how long such a permissive operation would remain.
* Country code 992 was reported as a recent assignment for
Tajikistan, which will be moving from country code 7 at some
unknown time.
* Uzbekistan has its own country code assignment, but I have no
information if this is in service yet or what implementation dates
have been set.
* Kazakstan does not have a known separate country code assignment
at present. It remains in country code 7 for the time being.
* Russia seems destined to keep country code 7.
* Recent news reports speak of some agreements forming between
Russia and Belarus. While there is no outright reunification yet,
there is expected to be much closer ties between the two nations.
Whether this will lead to a reunification of telephone codes
remains to be seen.
In the table, "Effective" means the date at which the country code
began service (which could vary according to the nation). "Mandatory"
means the date at which the country code 7 is invalid for calls to
that nation. There are a number of question marks since exact dates
have not been collected in all cases.
CC Nation Effective Mandatory Notes
370 Lithuania 1993? ??? Announced Jan 1993
371 Latvia 1993? ???
372 Estonia 1 Feb 1993? March 1993?
373 Moldova 1993? ??? Announced Jan 1993
374 Armenia 1 May 1995 1 July 1995 Announced Jan 1995 (ITU)
375 Belarus 16 Apr 1995 1997?
380 Ukraine 16 Apr 1995 Oct 1995?
7 Kazakstan (no known changes)
7 Russia (presumably not changing)
992 Tajikistan ??? ??? Announced 1996-7?
993 Turkmenistan 3 Jan 1997 3 Apr 1997 Canada as of 29 Nov 1996
994 Azerbaijan Sept 1994? ??? Announced 1992
995 Georgia 1994? ??? ref: Telecom Digest Oct 1994
996 Kyrgyz Republic 1 May 1997 ??? ref: Stentor Canada/CRTC
998 Uzbekistan ??? ??? Announced 1996? (ITU)
Details courtesy Toby Nixon, ITU, Stentor (Canada), CRTC (Canada),
TELECOM Digest (including information collected for the country code
listings).
_________________________________________________________________
IV. ERRATA & CORRIGENDA
The following errors in [636]Using C-Kermit, Second Edition, first
printing, have been noted.
First, some missing acknowledgements for C-Kermit 6.0: JE Jones of
Microware for help with OS-9, Nigel Roles for his help with Plan 9,
Lucas Hart for help with VMS and Digital UNIX, Igor Kovalenko for his
help with QNX. And later, to Susan Kleinmann for her help with Debian
Linux packaging; Patrick Volkerding for his help with Slackware Linux
packaging; Jim Knoble for his help with Red Hat Linux packaging; and
to dozens of others for sending individual C-Kermit binaries for
varied and diverse platforms.
Thanks to James Spath for both binaries and reporting many of the
typos noted below. Also to Dat Thuc Nguyen for spotting several typos.
PAGE REMARKS
COVER "COS" is a misprint. There is no COS. Pretend it says "SCO" or "VOS".
(This is fixed in the second printing.)
xxi Second line: Fred Smith's affiliation should be Computrition.
83 Change "commands other" to "commands as other" (1st paragraph)
87 Change "The the" to "The" (2nd paragraph)
92 "set modem-type user-defined supra" should be "set modem type ..."
95 Change "VI" to "vi" (1st paragraph)
96 Change "it it" to "it is" (1st paragraph)
97 Change "advantage a literal" to "advantage of a literal" (2nd
paragraph)
102 The call-waiting example would be better as SET DIAL PREFIX *70W
(rather than "*70,") because the former will not cause an incorrect
call to be placed with pulse dialing.
123 Third paragraph from bottom: "..otherwise if a your local username.."
should be "..otherwise your local username..".
160 Delete the "it" between "and" and "to" (2nd paragraph)
185 In "When TRANSFER DISPLAY is OFF, C-Kermit skips the display...",
"OFF" should be "NONE".
187 The last paragraph says the "A command" is ignored, should be "S".
194 Change "it known" to "it is known" (4th paragraph).
235 In C-Kermit 7.0, the syntax of the GET command changed. MGET now
must be used to get a list of files and there is no more multiline
GET command.
268 Last paragraph: "effect" should be "affect".
275 In the SET PROTOCOL KERMIT description, the following sentence is
incorrect and should be removed: 'If you omit the commands, the
default ones are restored: "kermit -ir" and "kermit -r" respectively".
The correct information is given at the bottom of page 281.
279 9th line. The decimal value of ST is 156, not 155.
295 In the stepping stones, skip ahead to Chapter 17 on p. 327.
298 Table 16-2, Portuguese entry. Column 4/00 should show section sign,
not acute accent.
316 Other languages written in the Hebrew alphabet include Karaim (a Turkic
language spoken in Lithuania and Poland), Judeo-Kurdish, and Judeo-
Georgian.
332 UNDEFINE definition, change "This just" to "This is just".
344 It might be necessary to set the modem's pulse generation rate when
sending numeric pages; most Hayes compatible modems use the S11
register for this.
350 Delete "is" from between "It" and "ceases" (4th paragraph)
351 Top - both occurrences of "print \%a" should be "echo \%a".
364 \v(input) and \v(query) out of alphabetical order.
378 In the MYSEND macro, "if not \m(rc) goto bad" should be:
"if \m(rc) goto bad" (remove the "not").
382-383 It should be stated that the loop control variable must be of the \%a
type, or else an array element; macro names can not be used for this.
383 In line 3, "\%f[\%i]" should be "\&f[\%i]".
383 In the sort example, it should be stated that the array is 1-based.
387 Change "You can list" to "You can get a list" (5th paragraph)
393 \Fverify() description. The 3rd sentence could be stated more clearly
as "If all characters in string2 are also in string1, 0 is returned."
398 Copying \ffiles() results to an array before is not required as of
C-Kermit 7.0 (see [637]Section 7.3).
403 In "(\%a + 3) * (\%b 5)", a minus sign is missing between b and 5.
407 C-Kermit 7.0 no longer supports multiline GET. Change
"get, \%1, \%2" to "get {\%1} {\%2}" or "get /as:{\%2} {\%1}".
409 READ example while loop should be:
while success { echo \m(line), read line }
409 "WRITE file" should be "WRITE keyword" (you can't put a filename there)
(The same applies to WRITE-LINE / WRITELN).
414 \Funhexify() missing from Table 18-3.
425 MINPUT definition, change 2nd "text2" to "text3".
436 Several lines are missing from the UNIXLOGIN macro listing.
After the "xif fail" block, insert:
out \%1\13 ; Send username, carriage return
inp 5 Password: ; Wait 5 sec for this prompt
if fail end 1 No password prompt
pause ; Wait a sec
out \%2\13 ; Send password
440 Change "set terminal byteszie" to "set terminal bytesize".
Change "input Password:" to "input 10 Password".
448 Franchise script: "access line" should be "access \m(line)".
453 There are two incorrectly coded IF statements in the DELIVER macro
definition. Replace both occurrences of "if > \%1 \%3 {" with
"xif > \%i \%3 {" (replace "if" by "xif" and "\%1" with "\%i").
453 "the the" (last paragraph) should be "the".
454 EOT (last paragraph) is End of Transmission, not End of Text.
457 _DEFINE definition: "name constructed" should be "name is constructed".
457 "macro for and" (last paragraph) should be "macro and".
459 Should explain that \v(user) is a legal abbreviation of \v(userid).
480 Figure II-2 is backwards; the least-significant bit is transmitted
first, then up to the highest, and the parity bit last.
534 The VMS Appendix section on Odd Record Lengths no longer applies;
C-Kermit 7.0 handles odd record lengths as well as even ones.
559 Table VIII-3, Portuguese entry. Column 4/00 should show section sign,
not acute accent.
560-563 HP-Roman8 missing from Table VII-4; there wasn't room to squeeze it in.
It is listed in section II(6).
565 "d stroke" in Table VII-5 has the wrong appearance; the stem should
be upright. The letter shown in the table is actually a lowercase
Icelandic eth, which has a curved stem.
601-604 BeBox, BeOS, Plan 9, and probably others not listed in trademarks.
604 The words "SCRIBE TEXT FORMATTER" appear at the end of the last
sentence of the first paragraph of the Colophon. They should have
been in the Index.
Index: Missing entries: SET { SEND, RECEIVE } PATHNAMES, Call waiting, ...
\F() Page 605, add also 413-414
\Fbreak 389
\Fcapitalize 390
\Fchecksum 414
\Fcrc16 414
\Fexecute 414
\Fhexify 390
\Fltrim 391
\Frepeat 392
\Fspawn 392
\Ftod2secs 399
\v() built_in Page 606, add also 361-364
\v(_line) 354, 361
\v(apcactive) 361
\v(charset) 362
\v(cpu) 362
\v(crc16) 357, 362
\v(d$xxx) add page 362
\v(dialnumber) 362
\v(dialresult) 362
\v(errno) 362
\v(errstring) 362
\v(exedir) 362
\v(inidir) 363
\v(ipaddress) 363
\v(keyboard) 363
\v(macro) 363
\v(minput) 363
\v(m_xxx) 94, 363
\v(password) 364
\v(query) 364
\v(prompt) 364
\v(speed) 356, 364
\v(startup) 364
\v(status) 364
\v(sysid) 364
\v(system) 364
\v(fsize) at lower half page 606 should read \v(tfsize)
\v(xversion) 364
BEEP Command 40
SET FLOW 62, 212
Figure II-5 on page 493. The pin assignments of the Mini Din-8
connector are not described anywhere. As noted in the text, these tend
to vary from vendor to vendor. One common arrangement is:
1. HSKout (Handshake out -- definition depends on software)
2. HSKin (Handshake in or external clock)
3. TxD-
4. Not used
5. RxD-
6. TxD+
7. Not used
8. RxD+
Note the "balanced pairs" for Receive Data (RxD) and Transmit Data
(TxD), and the utter lack of modem signals. These connectors follow
the RS-423 standard, rather than RS-232. In some arrangements, Pin 1
is used for DTR and Pin 2 for CD; in others Pin 1 is RTS and Pin 2 is
CTS.
Please send reports of other errors to the authors, as well as
suggestions for improvements, additional index entries, and any other
comments:
[638]kermit@columbia.edu
_________________________________________________________________
APPENDIX V. ADDITIONAL COPYRIGHT NOTICES
The following copyrights cover some of the source code used in the
development of C-Kermit, Kermit 95, or Kermit 95 support libraries.
/*****************************************************************************/
/* */
/* Copyright (c) 1995 by Oy Online Solutions Ltd. */
/* */
/* Distribution of this source code is strictly forbbidden. Use of this */
/* source code is granted to the University of Columbia C-Kermit project */
/* to be distributed in binary format only. Please familiarize yourself */
/* with the accompanying LICENSE.P file. */
/* */
/*****************************************************************************/
used for Xmodem, Ymodem, and Zmodem protocol in Kermit 95 (p95.dll,
p2.dll)
_________________________________________________________________
Copyright (c) 1997 Stanford University
The use of this software for revenue-generating purposes may require a
license from the owners of the underlying intellectual property.
Specifically, the SRP-3 protocol may not be used for
revenue-generating purposes without a license.
Within that constraint, permission to use, copy, modify, and
distribute this software and its documentation for any purpose is
hereby granted without fee, provided that the above copyright notices
and this permission notice appear in all copies of the software and
related documentation.
THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT
ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
SOFTWARE.
Used for Secure Remote Password (TM) protocol (SRP) in C-Kermit,
Kermit 95 (k95.exe, k2.exe, k95crypt.dll, k2crypt.dll)
_________________________________________________________________
Copyright 1990 by the Massachusetts Institute of Technology. All
Rights Reserved.
Export of this software from the United States of America may require
a specific license from the United States Government. It is the
responsibility of any person or organization contemplating export to
obtain such a license before exporting.
WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
distribute this software and its documentation for any purpose and
without fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that copyright notice and
this permission notice appear in supporting documentation, and that
the name of M.I.T. not be used in advertising or publicity pertaining
to distribution of the software without specific, written prior
permission. M.I.T. makes no representations about the suitability of
this software for any purpose. It is provided "as is" without express
or implied warranty.
Used for Telnet Authentication Option, Telnet Encryption Option, and
Kerberos (TM) authentication in C-Kermit, Kermit 95 (k95.exe, k2.exe,
k95crypt.dll, k2crypt.dll)
_________________________________________________________________
Copyright (c) 1991, 1993 The Regents of the University of California.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. All advertising materials mentioning features or use of this
software must display the following acknowledgement:
This product includes software developed by the University of
California, Berkeley and its contributors.
4. Neither the name of the University nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Used for Telnet Authentication Option, Telnet Encryption Option, and
Kerberos (TM) authentication in C-Kermit, Kermit 95 (k95.exe, k2.exe,
k95crypt.dll, k2crypt.dll)
_________________________________________________________________
Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) All rights
reserved.
This package is an DES implementation written by Eric Young
(eay@cryptsoft.com). The implementation was written so as to conform
with MIT's libdes.
This library is free for commercial and non-commercial use as long as
the following conditions are aheared to. The following conditions
apply to all code found in this distribution.
Copyright remains Eric Young's, and as such any Copyright notices in
the code are not to be removed. If this package is used in a product,
Eric Young should be given attribution as the author of that the SSL
library. This can be in the form of a textual message at program
startup or in documentation (online or textual) provided with the
package.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. All advertising materials mentioning features or use of this
software must display the following acknowledgement: This product
includes software developed by Eric Young (eay@cryptsoft.com)
THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The license and distribution terms for any publically available
version or derivative of this code cannot be changed. i.e. this code
cannot simply be copied and put under another distrubution license
[including the GNU Public License.]
The reason behind this being stated in this direct manner is past
experience in code simply being copied and the attribution removed
from it and then being distributed as part of other packages. This
implementation was a non-trivial and unpaid effort.
Used DES encryption in Kermit 95 (k95crypt.dll, k2crypt.dll)
_________________________________________________________________
* This is version 1.1 of CryptoLib
*
* The authors of this software are Jack Lacy, Don Mitchell and Matt Blaze
* Copyright (c) 1991, 1992, 1993, 1994, 1995 by AT&T.
* Permission to use, copy, and modify this software without fee
* is hereby granted, provided that this entire notice is included in
* all copies of any software which is or includes a copy or
* modification of this software and in all copies of the supporting
* documentation for such software.
*
* NOTE:
* Some of the algorithms in cryptolib may be covered by patents.
* It is the responsibility of the user to ensure that any required
* licenses are obtained.
*
*
* SOME PARTS OF CRYPTOLIB MAY BE RESTRICTED UNDER UNITED STATES EXPORT
* REGULATIONS.
*
*
* THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
* REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
* OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
Used for Big Number library in Kermit 95 (k95crypt.dll, k2crypt.dll).
[ [639]Top ] [ [640]C-Kermit ] [ [641]Kermit Home ]
_________________________________________________________________
CKERMIT70.HTM / The Kermit Project / Columbia University / 8 Feb 2000
References
1. http://www.columbia.edu/kermit/ckermit70.html#contents
2. http://www.columbia.edu/kermit/ckermit.html
3. http://www.columbia.edu/kermit/index.htm
4. mailto:kermit-support@columbia.edu
5. http://www.columbia.edu/kermit/
6. http://www.kermit-project.org/
7. http://www.columbia.nyc.ny.us/kermit/
8. ftp://kermit.columbia.edu/kermit/f/COPYING.TXT
9. ftp://kermit.columbia.edu/kermit/f/ckcmai.c
10. http://www.columbia.edu/kermit/ckermit70.html#xv
11. http://www.columbia.edu/kermit/ckb2.htm
12. ftp://kermit.columbia.edu/kermit/f/ckcbwr.txt
13. ftp://kermit.columbia.edu/kermit/f/ckubwr.txt
14. ftp://kermit.columbia.edu/kermit/f/ckvbwr.txt
15. ftp://kermit.columbia.edu/kermit/f/ckubwr.txt
16. ftp://kermit.columbia.edu/kermit/f/ckermit70.txt
17. ftp://kermit.columbia.edu/kermit/f/security.txt
18. http://www.columbia.edu/kermit/security.htm
19. ftp://kermit.columbia.edu/kermit/f/iksd.txt
20. http://www.columbia.edu/kermit/iksd.htm
21. http://www.columbia.edu/kermit/cuiksd.htm
22. ftp://kermit.columbia.edu/kermit/f/telnet.txt
23. http://www.columbia.edu/kermit/telnet.htm
24. ftp://kermit.columbia.edu/kermit/f/COPYING.TXT
25. http://www.columbia.edu/kermit/k95.html
26. http://www.opensource.org/
27. http://www.columbia.edu/kermit/ckb2.htm
28. http://www.columbia.edu/kermit/ckermit70.html#xi
29. http://www.columbia.edu/kermit/ckermit70.html#xii
30. http://www.columbia.edu/kermit/ckermit70.html#x0
31. http://www.columbia.edu/kermit/ckermit70.html#x1
32. http://www.columbia.edu/kermit/ckermit70.html#x1.0
33. http://www.columbia.edu/kermit/ckermit70.html#x1.1
34. http://www.columbia.edu/kermit/ckermit70.html#x1.2
35. http://www.columbia.edu/kermit/ckermit70.html#x1.3
36. http://www.columbia.edu/kermit/ckermit70.html#x1.4
37. http://www.columbia.edu/kermit/ckermit70.html#x1.5
38. http://www.columbia.edu/kermit/ckermit70.html#x1.5.1
39. http://www.columbia.edu/kermit/ckermit70.html#x1.5.2
40. http://www.columbia.edu/kermit/ckermit70.html#x1.5.3
41. http://www.columbia.edu/kermit/ckermit70.html#x1.5.4
42. http://www.columbia.edu/kermit/ckermit70.html#x1.5.5
43. http://www.columbia.edu/kermit/ckermit70.html#x1.6
44. http://www.columbia.edu/kermit/ckermit70.html#x1.7
45. http://www.columbia.edu/kermit/ckermit70.html#x1.8
46. http://www.columbia.edu/kermit/ckermit70.html#x1.9
47. http://www.columbia.edu/kermit/ckermit70.html#x1.10
48. http://www.columbia.edu/kermit/ckermit70.html#x1.11
49. http://www.columbia.edu/kermit/ckermit70.html#x1.11.1
50. http://www.columbia.edu/kermit/ckermit70.html#x1.11.2
51. http://www.columbia.edu/kermit/ckermit70.html#x1.11.3
52. http://www.columbia.edu/kermit/ckermit70.html#x1.11.4
53. http://www.columbia.edu/kermit/ckermit70.html#x1.11.5
54. http://www.columbia.edu/kermit/ckermit70.html#x1.11.6
55. http://www.columbia.edu/kermit/ckermit70.html#x1.11.7
56. http://www.columbia.edu/kermit/ckermit70.html#x1.12
57. http://www.columbia.edu/kermit/ckermit70.html#x1.13
58. http://www.columbia.edu/kermit/ckermit70.html#x1.14
59. http://www.columbia.edu/kermit/ckermit70.html#x1.15
60. http://www.columbia.edu/kermit/ckermit70.html#x1.16
61. http://www.columbia.edu/kermit/ckermit70.html#x1.17
62. http://www.columbia.edu/kermit/ckermit70.html#x1.18
63. http://www.columbia.edu/kermit/ckermit70.html#x1.19
64. http://www.columbia.edu/kermit/ckermit70.html#x1.20
65. http://www.columbia.edu/kermit/ckermit70.html#x1.21
66. http://www.columbia.edu/kermit/ckermit70.html#x1.22
67. http://www.columbia.edu/kermit/ckermit70.html#x1.22.1
68. http://www.columbia.edu/kermit/ckermit70.html#x1.22.2
69. http://www.columbia.edu/kermit/ckermit70.html#x1.22.3
70. http://www.columbia.edu/kermit/ckermit70.html#x1.22.4
71. http://www.columbia.edu/kermit/ckermit70.html#x1.22.5
72. http://www.columbia.edu/kermit/ckermit70.html#x1.22.6
73. http://www.columbia.edu/kermit/ckermit70.html#x1.22.7
74. http://www.columbia.edu/kermit/ckermit70.html#x1.22.8
75. http://www.columbia.edu/kermit/ckermit70.html#x1.23
76. http://www.columbia.edu/kermit/ckermit70.html#x1.24
77. http://www.columbia.edu/kermit/ckermit70.html#x2
78. http://www.columbia.edu/kermit/ckermit70.html#x2.0
79. http://www.columbia.edu/kermit/ckermit70.html#x2.1
80. http://www.columbia.edu/kermit/ckermit70.html#x2.1.1
81. http://www.columbia.edu/kermit/ckermit70.html#x2.1.2
82. http://www.columbia.edu/kermit/ckermit70.html#x2.1.3
83. http://www.columbia.edu/kermit/ckermit70.html#x2.1.4
84. http://www.columbia.edu/kermit/ckermit70.html#x2.1.5
85. http://www.columbia.edu/kermit/ckermit70.html#x2.1.6
86. http://www.columbia.edu/kermit/ckermit70.html#x2.1.7
87. http://www.columbia.edu/kermit/ckermit70.html#x2.1.8
88. http://www.columbia.edu/kermit/ckermit70.html#x2.1.9
89. http://www.columbia.edu/kermit/ckermit70.html#x2.1.10
90. http://www.columbia.edu/kermit/ckermit70.html#x2.1.11
91. http://www.columbia.edu/kermit/ckermit70.html#x2.1.12
92. http://www.columbia.edu/kermit/ckermit70.html#x2.1.13
93. http://www.columbia.edu/kermit/ckermit70.html#x2.1.14
94. http://www.columbia.edu/kermit/ckermit70.html#x2.1.15
95. http://www.columbia.edu/kermit/ckermit70.html#x2.1.16
96. http://www.columbia.edu/kermit/ckermit70.html#x2.2
97. http://www.columbia.edu/kermit/ckermit70.html#x2.2.1
98. http://www.columbia.edu/kermit/ckermit70.html#x2.2.2
99. http://www.columbia.edu/kermit/ckermit70.html#x2.3
100. http://www.columbia.edu/kermit/ckermit70.html#x2.3.0
101. http://www.columbia.edu/kermit/ckermit70.html#x2.3.1
102. http://www.columbia.edu/kermit/ckermit70.html#x2.3.2
103. http://www.columbia.edu/kermit/ckermit70.html#x2.3.3
104. http://www.columbia.edu/kermit/ckermit70.html#x2.3.4
105. http://www.columbia.edu/kermit/ckermit70.html#x2.3.5
106. http://www.columbia.edu/kermit/ckermit70.html#x2.3.6
107. http://www.columbia.edu/kermit/ckermit70.html#x2.4
108. http://www.columbia.edu/kermit/ckermit70.html#x2.5
109. http://www.columbia.edu/kermit/ckermit70.html#x2.6
110. http://www.columbia.edu/kermit/ckermit70.html#x2.7
111. http://www.columbia.edu/kermit/ckermit70.html#x2.7.0
112. http://www.columbia.edu/kermit/ckermit70.html#x2.7.1
113. http://www.columbia.edu/kermit/ckermit70.html#x2.7.2
114. http://www.columbia.edu/kermit/ckermit70.html#x2.7.3
115. http://www.columbia.edu/kermit/ckermit70.html#x2.7.4
116. http://www.columbia.edu/kermit/ckermit70.html#x2.7.4.1
117. http://www.columbia.edu/kermit/ckermit70.html#x2.7.4.2
118. http://www.columbia.edu/kermit/ckermit70.html#x2.7.4.3
119. http://www.columbia.edu/kermit/ckermit70.html#x2.7.4.4
120. http://www.columbia.edu/kermit/ckermit70.html#x2.7.4.5
121. http://www.columbia.edu/kermit/ckermit70.html#x2.8
122. http://www.columbia.edu/kermit/ckermit70.html#x2.9
123. http://www.columbia.edu/kermit/ckermit70.html#x2.9.1
124. http://www.columbia.edu/kermit/ckermit70.html#x2.9.2
125. http://www.columbia.edu/kermit/ckermit70.html#x2.10
126. http://www.columbia.edu/kermit/ckermit70.html#x2.11
127. http://www.columbia.edu/kermit/ckermit70.html#x2.12
128. http://www.columbia.edu/kermit/ckermit70.html#x2.13
129. http://www.columbia.edu/kermit/ckermit70.html#x2.14
130. http://www.columbia.edu/kermit/ckermit70.html#x2.15
131. http://www.columbia.edu/kermit/ckermit70.html#x3
132. http://www.columbia.edu/kermit/ckermit70.html#x3.1
133. http://www.columbia.edu/kermit/ckermit70.html#x3.2
134. http://www.columbia.edu/kermit/ckermit70.html#x3.3
135. http://www.columbia.edu/kermit/ckermit70.html#x3.4
136. http://www.columbia.edu/kermit/ckermit70.html#x4
137. http://www.columbia.edu/kermit/ckermit70.html#x4.0
138. http://www.columbia.edu/kermit/ckermit70.html#x4.1
139. http://www.columbia.edu/kermit/ckermit70.html#x4.1.1
140. http://www.columbia.edu/kermit/ckermit70.html#x4.1.2
141. http://www.columbia.edu/kermit/ckermit70.html#x4.1.3
142. http://www.columbia.edu/kermit/ckermit70.html#x4.2
143. http://www.columbia.edu/kermit/ckermit70.html#x4.2.1
144. http://www.columbia.edu/kermit/ckermit70.html#x4.2.1.1
145. http://www.columbia.edu/kermit/ckermit70.html#x4.2.1.2
146. http://www.columbia.edu/kermit/ckermit70.html#x4.2.1.3
147. http://www.columbia.edu/kermit/ckermit70.html#x4.2.2
148. http://www.columbia.edu/kermit/ckermit70.html#x4.2.2.1
149. http://www.columbia.edu/kermit/ckermit70.html#x4.2.2.2
150. http://www.columbia.edu/kermit/ckermit70.html#x4.2.3
151. http://www.columbia.edu/kermit/ckermit70.html#x4.2.3.1
152. http://www.columbia.edu/kermit/ckermit70.html#x4.2.3.2
153. http://www.columbia.edu/kermit/ckermit70.html#x4.2.4
154. http://www.columbia.edu/kermit/ckermit70.html#x4.2.5
155. http://www.columbia.edu/kermit/ckermit70.html#x4.2.6
156. http://www.columbia.edu/kermit/ckermit70.html#x4.2.7
157. http://www.columbia.edu/kermit/ckermit70.html#x4.2.8
158. http://www.columbia.edu/kermit/ckermit70.html#x4.2.8.1
159. http://www.columbia.edu/kermit/ckermit70.html#x4.2.8.2
160. http://www.columbia.edu/kermit/ckermit70.html#x4.2.8.3
161. http://www.columbia.edu/kermit/ckermit70.html#x4.2.8.4
162. http://www.columbia.edu/kermit/ckermit70.html#x4.3
163. http://www.columbia.edu/kermit/ckermit70.html#x4.3.1
164. http://www.columbia.edu/kermit/ckermit70.html#x4.3.2
165. http://www.columbia.edu/kermit/ckermit70.html#x4.3.3
166. http://www.columbia.edu/kermit/ckermit70.html#x4.3.4
167. http://www.columbia.edu/kermit/ckermit70.html#x4.4
168. http://www.columbia.edu/kermit/ckermit70.html#x4.4.1
169. http://www.columbia.edu/kermit/ckermit70.html#x4.4.1.1
170. http://www.columbia.edu/kermit/ckermit70.html#x4.4.1.2
171. http://www.columbia.edu/kermit/ckermit70.html#x4.4.2
172. http://www.columbia.edu/kermit/ckermit70.html#x4.4.2.1
173. http://www.columbia.edu/kermit/ckermit70.html#x4.4.2.1.1
174. http://www.columbia.edu/kermit/ckermit70.html#x4.4.2.1.2
175. http://www.columbia.edu/kermit/ckermit70.html#x4.4.2.2
176. http://www.columbia.edu/kermit/ckermit70.html#x4.5
177. http://www.columbia.edu/kermit/ckermit70.html#x4.5.1
178. http://www.columbia.edu/kermit/ckermit70.html#x4.5.2
179. http://www.columbia.edu/kermit/ckermit70.html#x4.5.2.1
180. http://www.columbia.edu/kermit/ckermit70.html#x4.5.2.2
181. http://www.columbia.edu/kermit/ckermit70.html#x4.5.3
182. http://www.columbia.edu/kermit/ckermit70.html#x4.5.4
183. http://www.columbia.edu/kermit/ckermit70.html#x4.6
184. http://www.columbia.edu/kermit/ckermit70.html#x4.7
185. http://www.columbia.edu/kermit/ckermit70.html#x4.7.1
186. http://www.columbia.edu/kermit/ckermit70.html#x4.7.2
187. http://www.columbia.edu/kermit/ckermit70.html#x4.7.3
188. http://www.columbia.edu/kermit/ckermit70.html#x4.8
189. http://www.columbia.edu/kermit/ckermit70.html#x4.8.1
190. http://www.columbia.edu/kermit/ckermit70.html#x4.8.2
191. http://www.columbia.edu/kermit/ckermit70.html#x4.9
192. http://www.columbia.edu/kermit/ckermit70.html#x4.9.1
193. http://www.columbia.edu/kermit/ckermit70.html#x4.9.2
194. http://www.columbia.edu/kermit/ckermit70.html#x4.9.3
195. http://www.columbia.edu/kermit/ckermit70.html#x4.10
196. http://www.columbia.edu/kermit/ckermit70.html#x4.11
197. http://www.columbia.edu/kermit/ckermit70.html#x4.11.1
198. http://www.columbia.edu/kermit/ckermit70.html#x4.11.2
199. http://www.columbia.edu/kermit/ckermit70.html#x4.11.3
200. http://www.columbia.edu/kermit/ckermit70.html#x4.11.4
201. http://www.columbia.edu/kermit/ckermit70.html#x4.11.5
202. http://www.columbia.edu/kermit/ckermit70.html#x4.11.6
203. http://www.columbia.edu/kermit/ckermit70.html#x4.12
204. http://www.columbia.edu/kermit/ckermit70.html#x4.13
205. http://www.columbia.edu/kermit/ckermit70.html#x4.14
206. http://www.columbia.edu/kermit/ckermit70.html#x4.15
207. http://www.columbia.edu/kermit/ckermit70.html#x4.16
208. http://www.columbia.edu/kermit/ckermit70.html#x4.17
209. http://www.columbia.edu/kermit/ckermit70.html#x4.17.1
210. http://www.columbia.edu/kermit/ckermit70.html#x4.17.2
211. http://www.columbia.edu/kermit/ckermit70.html#x4.18
212. http://www.columbia.edu/kermit/ckermit70.html#x4.19
213. http://www.columbia.edu/kermit/ckermit70.html#x4.20
214. http://www.columbia.edu/kermit/ckermit70.html#x4.20.1
215. http://www.columbia.edu/kermit/ckermit70.html#x4.20.2
216. http://www.columbia.edu/kermit/ckermit70.html#x4.20.2.1
217. http://www.columbia.edu/kermit/ckermit70.html#x4.20.2.2
218. http://www.columbia.edu/kermit/ckermit70.html#x4.20.2.3
219. http://www.columbia.edu/kermit/ckermit70.html#x4.20.2.4
220. http://www.columbia.edu/kermit/ckermit70.html#x4.20.2.5
221. http://www.columbia.edu/kermit/ckermit70.html#x4.20.3
222. http://www.columbia.edu/kermit/ckermit70.html#x4.21
223. http://www.columbia.edu/kermit/ckermit70.html#x4.22
224. http://www.columbia.edu/kermit/ckermit70.html#x4.22.1
225. http://www.columbia.edu/kermit/ckermit70.html#x4.22.2
226. http://www.columbia.edu/kermit/ckermit70.html#x4.22.3
227. http://www.columbia.edu/kermit/ckermit70.html#x4.22.4
228. http://www.columbia.edu/kermit/ckermit70.html#x4.22.5
229. http://www.columbia.edu/kermit/ckermit70.html#x4.22.6
230. http://www.columbia.edu/kermit/ckermit70.html#x4.22.7
231. http://www.columbia.edu/kermit/ckermit70.html#x4.22.8
232. http://www.columbia.edu/kermit/ckermit70.html#x4.23
233. http://www.columbia.edu/kermit/ckermit70.html#x4.24
234. http://www.columbia.edu/kermit/ckermit70.html#x4.25
235. http://www.columbia.edu/kermit/ckermit70.html#x5
236. http://www.columbia.edu/kermit/ckermit70.html#x5.0
237. http://www.columbia.edu/kermit/ckermit70.html#x5.1
238. http://www.columbia.edu/kermit/ckermit70.html#x5.2
239. http://www.columbia.edu/kermit/ckermit70.html#x5.3
240. http://www.columbia.edu/kermit/ckermit70.html#x5.3.1
241. http://www.columbia.edu/kermit/ckermit70.html#x5.3.2
242. http://www.columbia.edu/kermit/ckermit70.html#x5.4
243. http://www.columbia.edu/kermit/ckermit70.html#x5.5
244. http://www.columbia.edu/kermit/ckermit70.html#x5.6
245. http://www.columbia.edu/kermit/ckermit70.html#x5.7
246. http://www.columbia.edu/kermit/ckermit70.html#x6
247. http://www.columbia.edu/kermit/ckermit70.html#x6.0
248. http://www.columbia.edu/kermit/ckermit70.html#x6.1
249. http://www.columbia.edu/kermit/ckermit70.html#x6.2
250. http://www.columbia.edu/kermit/ckermit70.html#x6.3
251. http://www.columbia.edu/kermit/ckermit70.html#x6.4
252. http://www.columbia.edu/kermit/ckermit70.html#x6.5
253. http://www.columbia.edu/kermit/ckermit70.html#x6.6
254. http://www.columbia.edu/kermit/ckermit70.html#x6.6.1
255. http://www.columbia.edu/kermit/ckermit70.html#x6.6.2
256. http://www.columbia.edu/kermit/ckermit70.html#x6.6.2
257. http://www.columbia.edu/kermit/ckermit70.html#x6.6.3
258. http://www.columbia.edu/kermit/ckermit70.html#x6.6.4
259. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5
260. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5.1
261. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5.2
262. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5.3
263. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5.4
264. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5.5
265. http://www.columbia.edu/kermit/ckermit70.html#x6.7
266. http://www.columbia.edu/kermit/ckermit70.html#x7
267. http://www.columbia.edu/kermit/ckermit70.html#x7.0
268. http://www.columbia.edu/kermit/ckermit70.html#x7.1
269. http://www.columbia.edu/kermit/ckermit70.html#x7.1.1
270. http://www.columbia.edu/kermit/ckermit70.html#x7.1.2
271. http://www.columbia.edu/kermit/ckermit70.html#x7.1.3
272. http://www.columbia.edu/kermit/ckermit70.html#x7.1.4
273. http://www.columbia.edu/kermit/ckermit70.html#x7.2
274. http://www.columbia.edu/kermit/ckermit70.html#x7.3
275. http://www.columbia.edu/kermit/ckermit70.html#x7.4
276. http://www.columbia.edu/kermit/ckermit70.html#x7.5
277. http://www.columbia.edu/kermit/ckermit70.html#x7.6
278. http://www.columbia.edu/kermit/ckermit70.html#x7.7
279. http://www.columbia.edu/kermit/ckermit70.html#x7.8
280. http://www.columbia.edu/kermit/ckermit70.html#x7.9
281. http://www.columbia.edu/kermit/ckermit70.html#x7.9.1
282. http://www.columbia.edu/kermit/ckermit70.html#x7.9.2
283. http://www.columbia.edu/kermit/ckermit70.html#x7.10
284. http://www.columbia.edu/kermit/ckermit70.html#x7.10.1
285. http://www.columbia.edu/kermit/ckermit70.html#x7.10.2
286. http://www.columbia.edu/kermit/ckermit70.html#x7.10.3
287. http://www.columbia.edu/kermit/ckermit70.html#x7.10.4
288. http://www.columbia.edu/kermit/ckermit70.html#x7.10.5
289. http://www.columbia.edu/kermit/ckermit70.html#x7.10.6
290. http://www.columbia.edu/kermit/ckermit70.html#x7.10.7
291. http://www.columbia.edu/kermit/ckermit70.html#x7.10.8
292. http://www.columbia.edu/kermit/ckermit70.html#x7.10.9
293. http://www.columbia.edu/kermit/ckermit70.html#x7.10.10
294. http://www.columbia.edu/kermit/ckermit70.html#x7.11
295. http://www.columbia.edu/kermit/ckermit70.html#x7.12
296. http://www.columbia.edu/kermit/ckermit70.html#x7.13
297. http://www.columbia.edu/kermit/ckermit70.html#x7.14
298. http://www.columbia.edu/kermit/ckermit70.html#x7.15
299. http://www.columbia.edu/kermit/ckermit70.html#x7.16
300. http://www.columbia.edu/kermit/ckermit70.html#x7.17
301. http://www.columbia.edu/kermit/ckermit70.html#x7.18
302. http://www.columbia.edu/kermit/ckermit70.html#x7.19
303. http://www.columbia.edu/kermit/ckermit70.html#x7.20
304. http://www.columbia.edu/kermit/ckermit70.html#x7.20.1
305. http://www.columbia.edu/kermit/ckermit70.html#x7.20.2
306. http://www.columbia.edu/kermit/ckermit70.html#x7.21
307. http://www.columbia.edu/kermit/ckermit70.html#x7.22
308. http://www.columbia.edu/kermit/ckermit70.html#x7.23
309. http://www.columbia.edu/kermit/ckermit70.html#x7.24
310. http://www.columbia.edu/kermit/ckermit70.html#x7.25
311. http://www.columbia.edu/kermit/ckermit70.html#x7.26
312. http://www.columbia.edu/kermit/ckermit70.html#x7.26.1
313. http://www.columbia.edu/kermit/ckermit70.html#x7.26.2
314. http://www.columbia.edu/kermit/ckermit70.html#x7.27
315. http://www.columbia.edu/kermit/ckermit70.html#x8
316. http://www.columbia.edu/kermit/ckermit70.html#x9
317. http://www.columbia.edu/kermit/ckermit70.html#x9.0
318. http://www.columbia.edu/kermit/ckermit70.html#x9.1
319. http://www.columbia.edu/kermit/ckermit70.html#x9.2
320. http://www.columbia.edu/kermit/ckermit70.html#x9.3
321. http://www.columbia.edu/kermit/ckermit70.html#x10
322. http://www.columbia.edu/kermit/ckermit70.html#xiii
323. http://www.columbia.edu/kermit/ckermit70.html#xiii.1
324. http://www.columbia.edu/kermit/ckermit70.html#xiii.1.1
325. http://www.columbia.edu/kermit/ckermit70.html#xiii.1.2
326. http://www.columbia.edu/kermit/ckermit70.html#xiii.1.2.1
327. http://www.columbia.edu/kermit/ckermit70.html#xiii.1.2.2
328. http://www.columbia.edu/kermit/ckermit70.html#xiii.1.2.3
329. http://www.columbia.edu/kermit/ckermit70.html#xiii.2
330. http://www.columbia.edu/kermit/ckermit70.html#xiv
331. http://www.columbia.edu/kermit/ckermit70.html#xv
332. http://www.columbia.edu/kermit/ckb2.htm
333. http://www.columbia.edu/kermit/ckbreviews.html
334. http://www.bhusa.com/
335. http://www.columbia.edu/kermit/manuals.html#ckde
336. http://www.columbia.edu/kermit/manuals.html#ktb
337. http://www.columbia.edu/kermit/news.html
338. news:comp.protocols.kermit.announce
339. news:comp.protocols.kermit.misc
340. http://www.columbia.edu/kermit/ckb2.htm
341. http://www.columbia.edu/kermit/ckermit70.html#x4
342. http://www.columbia.edu/kermit/ckermit70.html#x4.3
343. http://www.columbia.edu/kermit/ckermit70.html#x4.23
344. http://www.columbia.edu/kermit/ckermit70.html#x4.5.1
345. http://www.columbia.edu/kermit/ckermit70.html#x1.5
346. http://www.columbia.edu/kermit/ckermit70.html#x4.7.1
347. http://www.columbia.edu/kermit/ckermit70.html#x4.9.
348. http://www.columbia.edu/kermit/ckb2.htm
349. http://www.columbia.edu/kermit/ckermit70.html#x7.9.2
350. http://www.columbia.edu/kermit/ckermit70.html#x2.15
351. http://www.columbia.edu/kermit/ckermit70.html#x9.1
352. http://www.columbia.edu/kermit/ckermit70.html#x1.6
353. http://www.columbia.edu/kermit/ckermit70.html#x7.4
354. http://www.columbia.edu/kermit/ckermit70.html#x4.9.1
355. http://www.columbia.edu/kermit/ckermit70.html#mjd
356. http://www.columbia.edu/kermit/ckermit70.html#mjd
357. http://www.columbia.edu/kermit/ckermit70.html#x4.9
358. http://www.columbia.edu/kermit/ckb2.htm
359. http://www.columbia.edu/kermit/ckb2.htm
360. http://www.columbia.edu/kermit/ckermit70.html#x7.5
361. http://www.columbia.edu/kermit/ckermit70.html#x2.12
362. http://www.columbia.edu/kermit/ckermit70.html#x1.5
363. http://www.columbia.edu/kermit/ckermit70.html#x4.9.1
364. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5
365. http://www.columbia.edu/kermit/ckermit70.html#x4.9
366. http://www.columbia.edu/kermit/ckermit70.html#x7.18
367. http://www.columbia.edu/kermit/ckermit70.html#x7.4
368. http://www.columbia.edu/kermit/ckermit70.html#x1.15
369. http://www.columbia.edu/kermit/ckermit70.html#x4.3
370. http://www.columbia.edu/kermit/ckermit70.html#x7.3
371. http://www.columbia.edu/kermit/ckermit70.html#x7.10.7
372. http://www.columbia.edu/kermit/ckermit70.html#x7.1
373. http://www.columbia.edu/kermit/ckermit70.html#x4.9.1
374. ftp://kermit.columbia.edu/kermit/f/ckccfg.txt
375. ftp://kermit.columbia.edu/kermit/f/ckccfg.txt
376. http://www.columbia.edu/kermit/ckermit70.html#x1.22.4
377. http://www.columbia.edu/kermit/ckermit70.html#x1.22.5
378. http://www.columbia.edu/kermit/ckb2.htm
379. http://www.columbia.edu/kermit/ckermit70.html#x1.22.5
380. http://www.columbia.edu/kermit/ckermit70.html#x7.12
381. http://www.columbia.edu/kermit/ckermit70.html#x2.1.16
382. http://www.columbia.edu/kermit/ckermit70.html#x2.7
383. http://www.columbia.edu/kermit/ckermit70.html#x2.3.5
384. http://www.columbia.edu/kermit/ckermit70.html#x7.5
385. http://www.telefonica.es/cambiodenumeracion/
386. http://www.columbia.edu/kermit/ckermit70.html#x7.5
387. http://www.columbia.edu/kermit/ckb2.htm
388. http://www.columbia.edu/kermit/ckermit70.html#x2.2.2
389. http://www.columbia.edu/kermit/ckermit70.html#x2.1.11
390. http://www.columbia.edu/kermit/ckermit70.html#x2.1.13
391. http://www.columbia.edu/kermit/ckermit70.html#x2.1.12
392. http://www.columbia.edu/kermit/ckb2.htm
393. http://www.columbia.edu/kermit/ckermit70.html#x2.1.1
394. http://www.columbia.edu/kermit/ckb2.htm
395. http://www.columbia.edu/kermit/ckb2.htm
396. http://www.columbia.edu/kermit/ckermit70.html#x2.1.7
397. http://www.columbia.edu/kermit/ckermit70.html#x2.1.6
398. http://www.columbia.edu/kermit/ckb2.htm
399. ftp://kermit.columbia.edu/kermit/f/telnet.txt
400. http://www.columbia.edu/kermit/telnet.htm
401. ftp://kermit.columbia.edu/kermit/f/telnet.txt
402. http://www.columbia.edu/kermit/telnet.htm
403. ftp://ftp.isi.edu/in-notes/rfc1572.txt
404. ftp://ftp.isi.edu/in-notes/rfc779.txt
405. http://www.columbia.edu/kermit/ckb2.htm
406. http://www.columbia.edu/kermit/ckermit70.html#x2.10
407. http://www.columbia.edu/kermit/ckermit70.html#x2.8
408. http://www.columbia.edu/kermit/ckermit70.html#x1.5
409. http://www.columbia.edu/kermit/ckermit70.html#x4.20
410. http://www.psy.uq.oz.au/~ftp/Crypto/
411. http://www.columbia.edu/kermit/security.htm
412. http://srp.stanford.edu/srp/
413. http://www.columbia.edu/kermit/ckermit70.html#x2.7.1,
414. ftp://kermit.columbia.edu/kermit/f/ckccfg.txt
415. http://www.columbia.edu/kermit/security.htm
416. http://www.columbia.edu/kermit/ckb2.htm
417. http://www.columbia.edu/kermit/ckermit70.html#x2.7
418. http://www.columbia.edu/kermit/ckermit70.html#x2.0
419. ftp://kermit.columbia.edu/kermit/f/ckuins.txt
420. ftp://kermit.columbia.edu/kermit/f/ckubwr.txt
421. ftp://kermit.columbia.edu/kermit/f/ckuins.txt
422. http://www.columbia.edu/kermit/iksd.html#x4.2
423. http://www.columbia.edu/kermit/iksd.html
424. http://www.columbia.edu/kermit/ckermit70.html#x4.2.8.1
425. ftp://ftp.isi.edu/in-notes/rfc1945.txt
426. http://www.columbia.edu/kermit/ckermit70.html#x1.5
427. http://www.columbia.edu/kermit/ckermit70.html#x3.2
428. http://www.columbia.edu/kermit/ckermit70.html#x3.2
429. http://www.columbia.edu/kermit/ckb2.htm
430. http://www.columbia.edu/kermit/ckb2.htm
431. http://www.columbia.edu/kermit/ckermit70.html#x5.4
432. ftp://kermit.columbia.edu/kermit/f/ckubwr.txt
433. http://www.columbia.edu/kermit/ckermit70.html#x4.10
434. http://www.columbia.edu/kermit/ckermit70.html#x4.7.1
435. http://www.columbia.edu/kermit/ckermit70.html#x4.7.3
436. http://www.columbia.edu/kermit/ckermit70.html#x4.3
437. http://www.columbia.edu/kermit/ckermit70.html#x4.10
438. http://www.columbia.edu/kermit/ckermit70.html#x4.11
439. http://www.columbia.edu/kermit/ckermit70.html#x4.15
440. http://www.columbia.edu/kermit/ckermit70.html#x4.2.4
441. http://www.columbia.edu/kermit/ckermit70.html#x4.7
442. http://www.columbia.edu/kermit/ckermit70.html#x4.2.3
443. http://www.columbia.edu/kermit/ckermit70.html#x4.2.1.3
444. http://www.columbia.edu/kermit/ckb2.htm
445. http://www.columbia.edu/kermit/ckermit70.html#x4.2.2
446. http://www.columbia.edu/kermit/ckermit70.html#x1.5
447. http://www.columbia.edu/kermit/ckermit70.html#x4.2.8.2
448. http://www.columbia.edu/kermit/ckermit70.html#x4.3
449. http://www.columbia.edu/kermit/ckermit70.html#x4.10
450. http://www.columbia.edu/kermit/ckermit70.html#x4.11
451. http://www.columbia.edu/kermit/ckermit70.html#x4.15
452. http://www.telstra.com.au/docs/PGP/
453. http://www.telstra.com.au/docs/PGP/pgpdoc2/pgpdoc2_17.html
454. http://www.columbia.edu/kermit/security.htm
455. http://www.columbia.edu/kermit/ckermit70.html#x2.7
456. http://www.columbia.edu/kermit/ckb2.htm
457. http://www.columbia.edu/kermit/ckermit70.html#x2.14
458. http://www.columbia.edu/kermit/ckermit70.html#x1.23
459. http://www.columbia.edu/kermit/ckermit70.html#x4.7
460. http://www.columbia.edu/kermit/ckb2.htm
461. http://www.columbia.edu/kermit/ckb2.htm
462. http://www.columbia.edu/kermit/ckermit70.html#x4.9
463. http://www.columbia.edu/kermit/ckb2.htm
464. http://www.columbia.edu/kermit/ckermit70.html#x1.5.4
465. http://www.columbia.edu/kermit/ckermit70.html#x4.3
466. http://www.columbia.edu/kermit/ckermit70.html#x1.5.5
467. http://www.columbia.edu/kermit/ckermit70.html#x7.5
468. http://www.columbia.edu/kermit/ckermit70.html#x4.9
469. http://www.columbia.edu/kermit/ckermit70.html#x1.5.4
470. http://www.columbia.edu/kermit/ckermit70.html#x4.9
471. http://www.columbia.edu/kermit/ckermit70.html#x1.5.4
472. http://www.columbia.edu/kermit/ckermit70.html#x1.5.5
473. http://www.columbia.edu/kermit/ckb2.htm
474. http://www.columbia.edu/kermit/ckb2.htm
475. http://www.columbia.edu/kermit/ckermit70.html#x1.5
476. http://www.columbia.edu/kermit/ckermit70.html#x1.6
477. http://www.columbia.edu/kermit/ckermit70.html#x7.10
478. http://www.columbia.edu/kermit/ckermit70.html#x7.10.11
479. http://www.columbia.edu/kermit/ckermit70.html#x1.6
480. http://www.columbia.edu/kermit/ckermit70.html#x4.2.2
481. http://www.columbia.edu/kermit/ckermit70.html#x4.11
482. http://www.columbia.edu/kermit/ckermit70.html#x1.5.4
483. http://www.columbia.edu/kermit/ckermit70.html#x4.9.1
484. http://www.columbia.edu/kermit/ckermit70.html#x4.0.6
485. http://www.columbia.edu/kermit/ckermit70.html#x4.2
486. http://www.columbia.edu/kermit/ckermit70.html#x4.1
487. http://www.columbia.edu/kermit/ckermit70.html#x4.7.1
488. http://www.columbia.edu/kermit/ckb2.htm
489. http://www.columbia.edu/kermit/ckermit70.html#x1.5
490. http://www.columbia.edu/kermit/ckermit70.html#x4.2.2
491. http://www.columbia.edu/kermit/ckermit70.html#x4.7.1
492. http://www.columbia.edu/kermit/ckermit70.html#x4.2
493. http://www.columbia.edu/kermit/ckermit70.html#x4.10
494. http://www.columbia.edu/kermit/ckermit70.html#x4.2.2
495. http://www.columbia.edu/kermit/ckermit70.html#x4.7.1
496. http://www.columbia.edu/kermit/ckermit70.html#x4.2
497. http://www.columbia.edu/kermit/ckermit70.html#x4.10
498. http://www.columbia.edu/kermit/ckermit70.html#x1.11.5
499. http://www.columbia.edu/kermit/ckermit70.html#x4.0.6
500. http://www.columbia.edu/kermit/ckermit70.html#x4.11
501. http://www.columbia.edu/kermit/ckermit70.html#x4.9.1
502. http://www.columbia.edu/kermit/ckermit70.html#x4.11.3
503. http://www.columbia.edu/kermit/ckermit70.html#x4.9
504. http://www.columbia.edu/kermit/ckermit70.html#x4.9
505. http://www.columbia.edu/kermit/ckermit70.html#x4.5.1
506. http://www.columbia.edu/kermit/ckermit70.html#x7.10
507. http://www.columbia.edu/kermit/ckermit70.html#x7.10.5
508. http://www.columbia.edu/kermit/ckermit70.html#x7.10.3
509. http://www.columbia.edu/kermit/ckermit70.html#x7.10.5
510. http://www.columbia.edu/kermit/ckb2.htm
511. http://www.columbia.edu/kermit/ckermit70.html#x4.3
512. http://www.columbia.edu/kermit/ckermit70.html#x4.10
513. http://www.columbia.edu/kermit/ckermit70.html#x4.3
514. http://www.columbia.edu/kermit/ckermit70.html#x4.10
515. http://www.columbia.edu/kermit/ckermit70.html#x4.15
516. http://www.columbia.edu/kermit/ckermit70.html#x4.18
517. http://www.columbia.edu/kermit/ckermit70.html#x4.20
518. http://www.columbia.edu/kermit/ckermit70.html#x4.20
519. http://www.columbia.edu/kermit/ckermit70.html#x4.20
520. http://www.columbia.edu/kermit/ckermit70.html#x4.19
521. http://www.columbia.edu/kermit/ckermit70.html#x4.16
522. http://www.columbia.edu/kermit/ckermit70.html#x4.19
523. http://www.columbia.edu/kermit/ckermit70.html#x4.20.2.3
524. http://www.columbia.edu/kermit/ckermit70.html#x1.5
525. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5.4
526. http://www.columbia.edu/kermit/ckermit70.html#x4.22.2
527. http://www.columbia.edu/kermit/ckermit70.html#x4.22.3
528. http://www.columbia.edu/kermit/ckb2.htm
529. http://www.columbia.edu/kermit/ckb2.htm
530. http://www.columbia.edu/kermit/ckermit70.html#x9.3
531. http://www.columbia.edu/kermit/ckermit70.html#x5.2.1
532. http://www.columbia.edu/kermit/ckermit70.html#x4.5.1
533. http://www.columbia.edu/kermit/ckermit70.html#x4.5.2
534. http://www.columbia.edu/kermit/ckermit70.html#x6.6
535. http://www.columbia.edu/kermit/ckermit70.html#xiii
536. http://www.columbia.edu/kermit/ckermit70.html#xiii
537. ftp://ftp.isi.edu/in-notes/rfc1489.txt
538. ftp://ftp.isi.edu/in-notes/rfc2319.txt
539. http://www.unicode.org/
540. http://www.columbia.edu/kermit/ckermit70.html#x6.6.2
541. http://www.columbia.edu/kermit/ckermit70.html#x6.6.5.1
542. ftp://ftp.isi.edu/in-notes/rfc2640.txt
543. http://www.columbia.edu/kermit/ckermit70.html#x6.6.2
544. http://www.columbia.edu/kermit/ckermit70.html#x6.0
545. http://www.columbia.edu/kermit/ckermit70.html#x6.5
546. http://www.columbia.edu/kermit/ckermit70.html#x6.4
547. http://www.columbia.edu/kermit/ckb2.htm
548. http://www.columbia.edu/kermit/ckermit70.html#x4.21
549. http://www.columbia.edu/kermit/ckermit70.html#x6.5
550. http://www.columbia.edu/kermit/ckermit70.html#x2.8
551. http://www.columbia.edu/kermit/ckermit70.html#x7.7
552. http://www.columbia.edu/kermit/ckermit70.html#x7.2
553. http://www.columbia.edu/kermit/ckermit70.html#x1.19
554. http://www.columbia.edu/kermit/ckermit70.html#x4.9
555. http://www.columbia.edu/kermit/ckermit70.html#x4.1
556. http://www.columbia.edu/kermit/ckermit70.html#x4.2
557. http://www.columbia.edu/kermit/ckermit70.html#x4.1
558. http://www.columbia.edu/kermit/ckermit70.html#x4.2
559. http://www.columbia.edu/kermit/ckermit70.html#x2.1.11
560. http://www.columbia.edu/kermit/ckermit70.html#x2.10
561. http://www.columbia.edu/kermit/ckermit70.html#ferrstring
562. http://www.columbia.edu/kermit/ckermit70.html#x4.2.5
563. http://www.columbia.edu/kermit/ckermit70.html#x2.1.10
564. http://www.columbia.edu/kermit/ckermit70.html#x9.1
565. http://www.columbia.edu/kermit/ckermit70.html#x7.23
566. http://www.columbia.edu/kermit/ckermit70.html#x7.23
567. http://www.columbia.edu/kermit/ckermit70.html#x1.22
568. http://www.columbia.edu/kermit/ckermit70.html#x1.6
569. http://www.columbia.edu/kermit/ckermit70.html#x7.23
570. http://www.columbia.edu/kermit/ckermit70.html#x7.24
571. http://www.columbia.edu/kermit/ckermit70.html#x7.24
572. http://www.columbia.edu/kermit/ckermit70.html#x4.2.3
573. http://www.columbia.edu/kermit/ckermit70.html#x7.12
574. http://www.columbia.edu/kermit/ckermit70.html#x7.9
575. http://www.columbia.edu/kermit/ckb2.htm
576. http://www.columbia.edu/kermit/ckermit70.html#x4.11.3
577. http://www.columbia.edu/kermit/ckermit70.html#x4.11.3
578. http://www.columbia.edu/kermit/ckermit70.html#x7.5
579. http://www.columbia.edu/kermit/ckermit70.html#x7.10.7
580. http://www.columbia.edu/kermit/ckermit70.html#x7.10.7
581. http://www.columbia.edu/kermit/ckermit70.html#x4.2.8.4
582. http://www.columbia.edu/kermit/ckermit70.html#x4.2.5
583. http://www.columbia.edu/kermit/ckermit70.html#x7.8
584. http://www.columbia.edu/kermit/ckermit70.html#x4.9.1
585. http://www.columbia.edu/kermit/ckb2.htm
586. http://www.columbia.edu/kermit/ckermit70.html#x7.19
587. http://www.columbia.edu/kermit/ckermit70.html#x7.16
588. http://www.columbia.edu/kermit/ckermit70.html#x7.9.1
589. http://www.columbia.edu/kermit/ckermit70.html#x7.5
590. http://www.columbia.edu/kermit/ckermit70.html#x7.3
591. http://www.columbia.edu/kermit/ckermit70.html#x4.11.3
592. http://www.columbia.edu/kermit/ckermit70.html#x4.5.1
593. http://www.columbia.edu/kermit/ckermit70.html#x7.10
594. http://www.columbia.edu/kermit/ckermit70.html#x7.10.10
595. http://www.columbia.edu/kermit/ckermit70.html#x1.5
596. http://www.columbia.edu/kermit/ckermit70.html#x7.23
597. http://www.columbia.edu/kermit/ckermit70.html#x7.10.7
598. http://www.columbia.edu/kermit/ckermit70.html#x7.10.7
599. http://www.columbia.edu/kermit/ckermit70.html#x4.11.3
600. http://www.columbia.edu/kermit/ckermit70.html#x7.10.11
601. http://www.columbia.edu/kermit/ckermit70.html#x4.9
602. http://www.columbia.edu/kermit/ckermit70.html#x7.10.3
603. http://www.columbia.edu/kermit/ckermit70.html#x7.3
604. http://www.columbia.edu/kermit/ckermit70.html#x7.9.2
605. http://www.columbia.edu/kermit/ckb2.htm
606. http://www.columbia.edu/kermit/ckermit70.html#x4.17.2
607. http://www.columbia.edu/kermit/ckermit70.html#x1.22
608. http://www.columbia.edu/kermit/ckermit70.html#x4.7.1
609. http://www.columbia.edu/kermit/ckermit70.html#x1.22
610. http://www.columbia.edu/kermit/ckermit70.html#x4.3
611. http://www.columbia.edu/kermit/ckermit70.html#x4.9
612. http://www.columbia.edu/kermit/ckermit70.html#x1.22
613. http://www.columbia.edu/kermit/ckermit70.html#x1.6
614. http://www.columbia.edu/kermit/ckermit70.html#x7.5
615. http://www.columbia.edu/kermit/ckermit70.html#x7.5
616. http://www.columbia.edu/kermit/ckermit70.html#x7.19
617. http://www.columbia.edu/kermit/ckermit70.html#x4.9.1
618. http://www.columbia.edu/kermit/ckermit70.html#x9.3
619. http://www.columbia.edu/kermit/ckermit70.html#x7.5
620. http://www.columbia.edu/kermit/ckb2.htm
621. http://www.columbia.edu/kermit/ckermit70.html#x7.4
622. http://www.columbia.edu/kermit/ckermit70.html#x7.20.2
623. http://www.columbia.edu/kermit/ckermit70.html#x7.10.5
624. http://www.columbia.edu/kermit/ckermit70.html#x7.10.9
625. http://www.columbia.edu/kermit/ckermit70.html#x1.10
626. http://www.columbia.edu/kermit/ckermit70.html#x1.5
627. http://www.columbia.edu/kermit/ckermit70.html#x4.7.1
628. http://www.columbia.edu/kermit/iksd.html
629. http://www.columbia.edu/kermit/ckermit70.html#x7.19
630. http://www.columbia.edu/kermit/ckermit70.html#x4.10
631. http://www.columbia.edu/kermit/ckermit70.html#x4.11
632. http://www.columbia.edu/kermit/ckermit70.html#x4.3
633. http://www.columbia.edu/kermit/gkermit.html
634. http://www.columbia.edu/kermit/ckermit70.html#x4.20
635. http://www.columbia.edu/kermit/gkermit.html
636. http://www.columbia.edu/kermit/ckb2.htm
637. http://www.columbia.edu/kermit/ckermit70.html#x7.3
638. mailto:kermit@columbia.edu
639. http://www.columbia.edu/kermit/ckermit70.html#top
640. http://www.columbia.edu/kermit/ckermit.html
641. http://www.columbia.edu/kermit/index.html
|