| [ Home ] [ Kermit 95 ] [ C-kermit ] [ Scripts ] [ Current ] [ New ] [ FAQ ] [ Support ] |
As of C-Kermit version: 7.0.196
This file created: 8 February 2000
This file last updated:
Wed Aug 13 12:44:43 2008
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: kermit-support@columbia.edu
Web: http://www.columbia.edu/kermit/
Or: http://www.kermit-project.org/
Or: http://www.columbia.nyc.ny.us/kermit/
For the full text of the third-party copyright notices, see Appendix V.
For further information, also see the CKCBWR.TXT ("C-Kermit beware") file for hints, tips, tricks, restrictions, frequently asked questions, etc, plus the system-specific "beware file", e.g. CKUBWR.TXT for UNIX, 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.
Several other files accompany this new Kermit release:
Like the book 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.
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
I. C-KERMIT DOCUMENTATION
II. NEW FEATURES
(0) INCOMPATIBILITIES WITH PREVIOUS RELEASES
(1) PROGRAM AND FILE MANAGEMENT AND COMMANDS
1.0. Bug fixes
1.1. Command Continuation
1.2. Editor Interface
1.3. Web Browser and FTP Interface
1.4. Command Editing
1.5. Command Switches
1.5.1. General Switch Syntax
1.5.2. Order and Effect of Switches
1.5.3. Distinguishing Switches from Other Fields
1.5.4. Standard File Selection Switches
1.5.5. Setting Preferences for Different Commands
1.6. Dates and Times
1.7. Partial Completion of Keywords
1.8. Command Recall
1.9. EXIT Messages
1.10. Managing Keyboard Interruptions
1.11. Taming the Wild Backslash -- Part Deux
1.11.1. Background
1.11.2. Kermit's Quoting Rules
1.11.3. Passing DOS Filenames from Kermit to Shell Commands
1.11.4. Using Variables to Hold DOS Filenames
1.11.5. Passing DOS Filenames as Parameters to Macros
1.11.6. Passing DOS File Names from Macro Parameters to the DOS Shell
1.11.7. Passing DOS Filenames to Kermit from the Shell
1.12. Debugging
1.13. Logs
1.14. Automatic File-Transfer Packet Recognition at the Command Prompt
1.15. The TYPE Command
1.16. The RESET Command
1.17. The COPY and RENAME Commands
1.18. The MANUAL Command
1.19. String and Filename Matching Patterns
1.20. Multiple Commands on One Line
1.21. What Do I Have?
1.22. Generalized File Input and Output
1.22.1. Why Another I/O System?
1.22.2. The FILE Command
1.22.3. FILE Command Examples
1.22.4. Channel Numbers
1.22.5. FILE Command Error Codes
1.22.6. File I/O Variables
1.22.7. File I/O Functions
1.22.8. File I/O Function Examples
1.23. The EXEC Command
1.24. Getting Keyword Lists with '?'
(2) MAKING AND USING CONNECTIONS
2.0. SET LINE and SET HOST Command Switches
2.1. Dialing
2.1.1. The Dial Result Message
2.1.2. Long-Distance Dialing Changes
2.1.3. Forcing Long-Distance Dialing
2.1.4. Exchange-Specific Dialing Decisions
2.1.5. Cautions about Cheapest-First Dialing
2.1.6. Blind Dialing (Dialing with No Dialtone)
2.1.7. Trimming the Dialing Dialog
2.1.8. Controlling the Dialing Speed
2.1.9. Pretesting Phone Number Conversions
2.1.10. Greater Control over Partial Dialing
2.1.11. New DIAL-related Variables and Functions
2.1.12. Increased Flexibility of PBX Dialing
2.1.13. The DIAL macro - Last-Minute Phone Number Conversions
2.1.14. Automatic Tone/Pulse Dialing Selection
2.1.15. Dial-Modifier Variables
2.1.16. Giving Multiple Numbers to the DIAL Command
2.2. Modems
2.2.1. New Modem Types
2.2.2. New Modem Controls
2.3. TELNET and RLOGIN
2.3.0. Bug Fixes
2.3.1. Telnet Binary Mode Bug Adjustments
2.3.2. VMS UCX Telnet Port Bug Adjustment
2.3.3. Telnet New Environment Option
2.3.4. Telnet Location Option
2.3.5. Connecting to Raw TCP Sockets
2.3.6. Incoming TCP Connections
2.4. The EIGHTBIT Command
2.5. The Services Directory
2.6. Closing Connections
2.7. Using C-Kermit with External Communication Programs
2.7.0. C-Kermit over tn3270 and tn5250
2.7.1. C-Kermit over Telnet
2.7.2. C-Kermit over Rlogin
2.7.3. C-Kermit over Serial Communication Programs
2.7.4. C-Kermit over Secure Network Clients
2.7.4.1. SSH
2.7.4.2. SSL
2.7.4.3. SRP
2.7.4.4. SOCKS
2.7.4.5. Kerberos and SRP
2.8. Scripting Local Programs
2.9. X.25 Networking
2.9.1. IBM AIXLink/X.25 Network Provider Interface for AIX
2.9.2. HP-UX X.25
2.10. Additional Serial Port Controls
2.11. Getting Access to the Dialout Device
2.12. The Connection Log
2.13. Automatic Connection-Specific Flow Control Selection
2.14. Trapping Connection Establishment and Loss
2.15. Contacting Web Servers with the HTTP Command
(3) TERMINAL CONNECTION
3.1. CONNECT Command Switches
3.2. Triggers
3.3. Transparent Printing
3.4. Binary and Text Session Logs
(4) FILE TRANSFER AND MANAGEMENT
4.0. Bug Fixes, Minor Changes, and Clarifications
4.1. File-Transfer Filename Templates
4.1.1. Templates in the As-Name
4.1.2. Templates on the Command Line
4.1.3. Post-Transfer Renaming
4.2. File-Transfer Pipes and Filters
4.2.1. Introduction
4.2.1.1. Terminology
4.2.1.2. Notation
4.2.1.3. Security
4.2.2. Commands for Transferring from and to Pipes
4.2.2.1. Sending from a Command
4.2.2.2. Receiving to a Command
4.2.3. Using File-Transfer Filters
4.2.3.1. The SEND Filter
4.2.3.2. The RECEIVE Filter
4.2.4. Implicit Use of Pipes
4.2.5. Success and Failure of Piped Commands
4.2.6. Cautions about Using Pipes to Transfer Directory Trees
4.2.7. Pipes and Encryption
4.2.8. Commands and Functions Related to Pipes
4.2.8.1. The OPEN !READ and OPEN !WRITE Commands
4.2.8.2. The REDIRECT Command
4.2.8.3. Receiving Mail and Print Jobs
4.2.8.4. Pipe-Related Functions
4.3. Automatic Per-File Text/Binary Mode Switching
4.3.1. Exceptions
4.3.2. Overview
4.3.3. Commands
4.3.4. Examples
4.4. File Permissions
4.4.1. When ATTRIBUTES PROTECTION is OFF
4.4.1.1. Unix
4.4.1.2. VMS
4.4.2. When ATTRIBUTES PROTECTION is ON
4.4.2.1. System-Specific Permissions
4.4.2.1.1. UNIX
4.4.2.1.2. VMS
4.4.2.2. System-Independent Permissions
4.5. File Management Commands
4.5.1. The DIRECTORY Command
4.5.2. The CD and BACK Commands
4.5.2.1. Parsing Improvements
4.5.2.2. The CDPATH
4.5.3. Creating and Removing Directories
4.5.4. The DELETE and PURGE Commands
4.6. Starting the Remote Kermit Server Automatically
4.7. File-Transfer Command Switches
4.7.1. SEND Command Switches
4.7.2. GET Command Switches
4.7.3. RECEIVE Command Switches
4.8. Minor Kermit Protocol Improvements
4.8.1. Multiple Attribute Packets
4.8.2. Very Short Packets
4.9. Wildcard / File Group Expansion
4.9.1. In UNIX C-Kermit
4.9.2. In Kermit 95
4.9.3. In VMS, AOS/VS, OS-9, VOS, etc.
4.10. Additional Pathname Controls
4.11. Recursive SEND and GET: Transferring Directory Trees
4.11.1. Command-Line Options
4.11.2. The SEND /RECURSIVE Command
4.11.3. The GET /RECURSIVE Command
4.11.4. New and Changed File Functions
4.11.5. Moving Directory Trees Between Like Systems
4.11.6. Moving Directory Trees Between Unlike Systems
4.12. Where Did My File Go?
4.13. File Output Buffer Control
4.14. Improved Responsiveness
4.15. Doubling and Ignoring Characters for Transparency
4.16. New File-Transfer Display Formats
4.17. New Transaction Log Formats
4.17.1. The BRIEF Format
4.17.2. The FTP Format
4.18. Unprefixing NUL
4.19. Clear-Channel Protocol
4.20. Streaming Protocol
4.20.1. Commands for Streaming
4.20.2. Examples of Streaming
4.20.2.1. Streaming on Socket-to-Socket Connections
4.20.2.2. Streaming on Telnet Connections
4.20.2.3. Streaming with Limited Packet Length
4.20.2.4. Streaming on Dialup Connections
4.20.2.5. Streaming on X.25 Connections
4.20.3. Streaming - Preliminary Conclusions
4.21. The TRANSMIT Command
4.22. Coping with Faulty Kermit Implementations
4.22.1. Failure to Accept Modern Negotiation Strings
4.22.2. Failure to Negotiate 8th-bit Prefixing
4.22.3. Corrupt Files
4.22.4. Spurious Cancellations
4.22.5. Spurious Refusals
4.22.6. Failures during the Data Transfer Phase
4.22.7. Fractured Filenames
4.22.8. Bad File Dates
4.23. File Transfer Recovery
4.24. FILE COLLISION UPDATE Clarification
4.25. Autodownload Improvements
(5) CLIENT/SERVER
5.0. Hints
5.1. New Command-Line Options
5.2. New Client Commands
5.3. New Server Capabilities
5.3.1. Creating and Removing Directories
5.3.2. Directory Listings
5.4. Syntax for Remote Filenames with Embedded Spaces
5.5. Automatic Orientation Messages upon Directory Change
5.6. New Server Controls
5.7. Timeouts during REMOTE HOST Command Execution
(6) INTERNATIONAL CHARACTER SETS
6.0. ISO 8859-15 Latin Alphabet 9
6.1. The HP-Roman8 Character Set
6.2. Greek Character Sets
6.3. Additional Latin-2 Character Sets
6.4. Additional Cyrillic Character Sets
6.5. Automatic Character-Set Switching
6.6. Unicode
6.6.1. Overview of Unicode
6.6.2. UCS Byte Order
6.6.2. UCS Transformation Formats
6.6.3. Conformance Levels
6.6.4. Relationship of Unicode with Kermit's Other Character Sets
6.6.5. Kermit's Unicode Features
6.6.5.1. File Transfer
6.6.5.2. The TRANSLATE Command
6.6.5.3. Terminal Connection
6.6.5.4. The TRANSMIT Command
6.6.5.5. Summary of Kermit Unicode Commands
6.7. Client/Server Character-Set Switching
(7) SCRIPT PROGRAMMING
7.0. Bug Fixes
7.1. The INPUT Command
7.1.1. INPUT Timeouts
7.1.2. New INPUT Controls
7.1.3. INPUT with Pattern Matching
7.1.4. The INPUT Match Result
7.2. New or Improved Built-In Variables
7.3. New or Improved Built-In Functions
7.4. New IF Conditions
7.5. Using More than Ten Macro Arguments
7.6. Clarification of Function Call Syntax
7.7. Autodownload during INPUT Command Execution
7.8. Built-in Help for Functions.
7.9. Variable Assignments
7.9.1. Assignment Operators
7.9.2. New Assignment Commands
7.10. Arrays
7.10.1. Array Initializers
7.10.2. Turning a String into an Array of Words
7.10.3. Arrays of Filenames
7.10.4. Automatic Arrays
7.10.5. Sorting Arrays
7.10.6. Displaying Arrays
7.10.7. Other Array Operations
7.10.8. Hints for Using Arrays
7.10.9. Do-It-Yourself Arrays
7.10.10. Associative Arrays
7.11. OUTPUT Command Improvements
7.12. Function and Variable Diagnostics
7.13. Return Value of Macros
7.14. The ASSERT, FAIL, and SUCCEED Commands.
7.15. Using Alarms
7.16. Passing Arguments to Command Files
7.17. Dialogs with Timed Responses
7.18. Increased Flexibility of SWITCH Case Labels
7.19. "Kerbang" Scripts
7.20. IF and XIF Statement Syntax
7.20.1. The IF/XIF Distinction
7.20.2. Boolean Expressions (The IF/WHILE Condition)
7.21. Screen Formatting and Cursor Control
7.22. Evaluating Arithmetic Expressions
7.23. Floating-Point Arithmetic
7.24. Tracing Script Execution
7.25. Compact Substring Notation
7.26. New WAIT Command Options
7.26.1. Waiting for Modem Signals
7.26.2. Waiting for File Events
7.27. Relaxed FOR and SWITCH Syntax
(8) USING OTHER FILE TRANSFER PROTOCOLS
(9) COMMAND-LINE OPTIONS
9.0. Extended-Format Command-Line Options
9.1. Command Line Personalities
9.2. Built-in Help for Command Line Options
9.3. New Command-Line Options
(10) C-KERMIT AND G-KERMIT
III. APPENDICES
III.1. Character Set Tables
III.1.1. The Hewlett Packard Roman8 Character Set
III.1.2. Greek Character Sets
III.1.2.1. The ISO 8859-7 Latin / Greek Alphabet
III.1.2.2. The ELOT 927 Character Set
III.1.2.3. PC Code Page 869
III.2. Updated Country Codes
IV. ERRATA & CORRIGENDA: Corrections to "Using C-Kermit" 2nd Edition.
V. ADDITIONAL COPYRIGHT NOTICES
Frank da Cruz and Christine M. Gianone, Using C-Kermit, Second Edition, Digital Press / Butterworth-Heinemann, Woburn, MA, 1997, 622 pages, ISBN 1-55558-164-1.
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 / 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 German-language edition of the First Edition is also available:
Frank da Cruz and Christine M. Gianone, C-Kermit - Einführung 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 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, Kermit News. Subscriptions are free; contact Columbia University at the address above.
Online news about Kermit is published in the comp.protocols.kermit.announce and comp.protocols.kermit.misc newsgroups.
Specific changes and additions are grouped together by major topic, roughly corresponding to the chapters of Using C-Kermit.
cd \v(dir)data.tmp
to work across platforms that might have different directory notation, such as UNIX, Windows, and VMS.
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.
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:
echo foo\-
This prints "foo-". The command is not continued.
echo foo - ; this is a comment
interactively and they are properly treated as continued commands. Previously this worked only in command files.
Related variables: \v(editor), \v(editopts), \v(editfile).
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:
The Web browser interface is covered in the following subsections.
Related variables: \v(browser), \v(browsopts), \v(browsurl).
Also see Section 2.15: Contacting Web Servers with the HTTP Command.
The method for doing this depends, of course, on your browser. Here are some examples:
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.
#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
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.
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.
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.
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.
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.
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 (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 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
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.
send /after:{8-Feb-2000 10:28:01}
Various date-time formats are acceptable. The rules for the date are:
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:
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 \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.
set alarm \fntime(48:00:00) ; set alarm 48 hours from now.
\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).
\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. See \fmjd() below.
\fdoy2date(2000185) = 20000704 \fdoy2(2000185 3pm) = 20000704 15:00:00
\fmjd(4 Jul 2000) = 50998 \fmjd(17 Nov 1858) = 0 \fmjd(16 Nov 1858) = -1
\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).
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).
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 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).
{ 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 $
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:
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).
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.
The following characters are special in Kermit commands:
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).
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.
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.
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 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)
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:
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.
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.
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])
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).
Here are some examples for UNIX (always remember the importance of getting the UNIX shell quoting rules right):
See Section 2.12 for information about the new connection log.
COMMAND AUTODOWNLOAD is the command-mode equivalent of TERMINAL AUTODOWNLOAD, which is effective during CONNECT mode.
Syntax: TYPE [ switches... ] filename
Variables:
Switches:
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".
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).
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 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.
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.
Patterns are also called wildcards, especially when used for filename matching. C-Kermit's pattern syntax is explained in Section 4.9.1, and also by the HELP WILDCARDS command.
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).
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:
See the ckccfg.txt file for details.
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:
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:
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 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 Section 1.22.5.
The command to open a file is:
The FILE OPEN switches are:
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 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:
Next come the commands for reading and writing files:
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:
FILE WRITE switches are:
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:
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
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.
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.
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 = /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 Section 1.22.5. For instructions on handling function errors, see Section 7.12.
while not \f_eof(\%c) { fread \%c }
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
}
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":
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").
{ OPEN, SET } { LINE, PORT, HOST } [ switches ] device-or-address [ switches ]
The first group of switches is:
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:
The second group of switches is:
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.
As of C-Kermit 7.0, automatic redialing is automatically canceled if the call could not be placed because no dialtone was detected.
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 Section 7.5 about the \%* variable.)
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: 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:
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)
Now there is also a new command that, very simply, can force long-distance dialing:
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 Section 7.5 about the \%* variable.)
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.
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.
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:
Notes:
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 {}
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 (Section 2.2.2).
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 (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:
There is, at present, no programmatic way to fetch numbers from the dialing directory. This will be considered for a future release.
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: 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
Other dial-related variables, already documented in Using C-Kermit (or other sections of this document, e.g. 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).
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:
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
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:
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):
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:
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 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.
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.
\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
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:
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
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 Section 2.1.7 for additional hints about making dialing go faster.
Recall that C-Kermit can dial modems to which it is connected via TCP/IP (Telnet or Rlogin) as described on page 126 of 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
Cautions:
C-Kermit> telnet /nowait hostname
See TELNET.TXT or 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.
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.
New commands:
set host xyzcorp.com ... telopt nop if fail stop 1 Connection lost
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.
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 ]
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.
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.
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.
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 Section 2.10.
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 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:
Notes:
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 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
IMPORTANT: In Unix, wildcards and redirectors are interpreted by the shell. If you want to run a program with (say) SET HOST /PTY with its i/o redirected or with wildcard file arguments, you will need to invoke the shell too. Example:
SET HOST /PTY {sh -c "crypt < foo.x"} SET HOST /PTY {sh -c "grep somestring *.txt"}
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:
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
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:
If the external connection program is not 8-bit clean, you should also:
And if it does not make a reliable connection (such as those made by Telnet, Rlogin, Ssh, etc), you should:
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:
If none of this seems to help, try falling back to the bare minimum, lowest-common-denominator protocol settings:
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.
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.
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
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.
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).
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.
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 \%*
}
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; CLICK HERE file for details.
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 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.
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
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
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 "*".
This section describes new additions.
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:
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.
set prefixing all set parity space pty padem address
This should work in HP-UX 9.00 and later (see 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.
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.
Notes:
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).
This section is for UNIX only; note the special words about QNX at the end. Also see 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:
See the ckuins.txt and 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).
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 ckuins.txt Section 15 and Section 4.2 of the IKSD Administration Guide for details).
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:
(*) 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
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 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}
}
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:
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:
/HEADER:{{tag:value}{tag:value}...}
For a listing of valid tag value and value formats see RFC 1945: Hypertext Transfer Protocol -- HTTP/1.0. A maximum of eight headers may be specified.
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:
Note: Other switches might also be available; type "connect ?" for a list, "help connect" for a description of each.
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.
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 Using C-Kermit, 2nd Ed., p.41 for details.
Transparent printing is controlled by the command:
The transparent-print escape sequences are:
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:
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 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.
The default FILE TYPE was changed from TEXT to BINARY in C-Kermit 7.0 because:
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 Section 5.4 on this topic.
.~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.
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 *
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 (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
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
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 Sections 4.7.1 through 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)
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.
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:
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.
Note: 3 and 4 are not necessary if you have done 1 or 2.
CSEND = SEND /COMMAND CRECEIVE = RECEIVE /COMMAND CGET = GET /COMMAND
None of these commands can be used if a SEND or RECEIVE FILTER (respectively, Section 4.2.3) is in effect, or if a NOPUSH command (Section 4.2.1.3) has been given, or if the current protocol is not Kermit.
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):
Examples that make sense in binary mode (three equivalent forms are shown):
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.
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):
Examples for binary mode:
Examples (for UNIX):
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 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:
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:
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.
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:
Examples for binary mode:
Of course you don't want to type such long hideous commands, so we have also introduced several new functions:
\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(OOFA.TXT.GZ) => OOFA.TXT.GZ \fstripn(OOFA.TXT.GZ,3) => OOFA.TXT \fstripn(OOFA.TXT.GZ,7) => OOFA
\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(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).
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:
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.
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.
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 Sections 4.3, 4.10, 4.11, and 4.15 for how to transfer directory trees between both like and unlike systems directly with Kermit.
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:
http://www.telstra.com.au/docs/PGP/
Especially the topic "Using PGP as a UNIX-Style Filter":
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 (CLICK HERE for details) and the new ability to run C-Kermit "though" other communication programs, described in Section 2.7.
These are described in 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 Section 2.14.
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 (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.
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 Using C-Kermit, 2nd Ed., pp.359-360 for details.
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).
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.
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 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.
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 *.TXT *.KSC *.HTM* *.BAT ; DOS, Windows, OS/2
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.
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.
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.
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.
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.
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.
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.
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 Section 1.5.4, plus:
dir /array:&a /files /nobackup /after:19990101 /larger:10000 [ab]* show array &a
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 (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:
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 "\%*" (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").
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 <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).
$ 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:
SHOW CD shows the CD path and all other information relevant to the CD command.
{{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.
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.
Optional switches include the standard file-selection switches presented in Section 1.5.4, plus:
Now the PURGE command:
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 Section 1.5.4, plus all the switches listed above for the DELETE command, plus:
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 (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.
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 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.
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 Section 1.5).
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).
send /text /after:{2-Feb-1997 10:28:30} *.txt
send /text /after:\fdate(oofa.txt) *.txt
Synonym: /SINCE.
send oofa.txt oofa.new send /as:oofa.new oofa.txt
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
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 -}
send /delete *.log
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.
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.
send /text /move-to:/users/olga/backup/ *.txt
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_".
send /mail:kermit-support@columbia.edu /subj:{As requested} packet.log
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.
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
About mail... Refer to 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 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 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".
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 {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:
Now you can also include modifier switches between GET or MGET and the remote-name; most of the same switches as SEND:
get oofa.txt oofa.new get /as:oofa.new oofa.txt
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.
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}
get /delete *.log
/EXCEPT:{{pattern1}{pattern2}...}
See the description of SEND /EXCEPT in 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.
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.
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:
r oofa.new r /as:oofa.new
r /command {grep Sunday oofa.txt}
r /command /as-name:{grep Sunday oofa.txt}
r /bin /command {tar cf - . | gzip -c}
/EXCEPT:{{pattern1}{pattern2}...}
See the description of SEND /EXCEPT in 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.
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.
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:
C-Kermit 7.0 adds the additional features that users of ksh, csh, and bash are accustomed to:
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:
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
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.
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:
*.~{[1-9],[1-9][0-9],[1-9][0-9][0-9]}~
In other wildcarding news...
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.
When building file lists in UNIX, C-Kermit follows symbolic links. Because of this, you might encounter any or all of the following phenomena:
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.
Nevertheless you can still use all the pattern-matching capabilities described in Section 4.9.1 by loading a file list into an array (e.g. with \ffiles(*,&a), see Section 4.11.3) and then using IF MATCH on the members.
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.
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.
$ 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).
Examples:
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.
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.
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 Sections 4.5.1 and 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 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 Section 7.10.3 and 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 Using C-Kermit 2nd Ed) is no longer necessary.
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.
$ 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.
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:
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.
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.
Experimentation with these parameters should be harmless, and might (or might not) have a perceptible, even dramatic, effect on performance.
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).
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.
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.)
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:
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.
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.
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 (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 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 (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.
The trick is knowing when we can stream:
(Note that an offer to stream also results in a Clear-Channel announcement if CLEAR-CHANNEL is set to AUTO; see 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 (Section 4.16).
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:
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.
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
Since we have a reliable connection, we'll also get control-character unprefixing automatically because of the new clear-channel protocol (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:
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
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
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.
C-Kermit 7.0 expands the capabilities of the TRANSMIT command by adding the following switches (see Section 1.5). The new syntax is:
TRANSMIT [ switches... ] filename
Zero or more switches may be included:
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}
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:
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 Section 6.6.5.4.
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.
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.
SET Q8FLAG ON
Use SET Q8FLAG OFF to restore the normal behavior.
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".
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.
SET ATTRIBUTES OFF
SET PREFIXING ALL
It can also have numerous other causes, explained in Chapter 10 of Using C-Kermit: the connection is not 8-bit transparent (so use "set parity space" or somesuch), inadequate flow control, etc. Consult the manual.
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:
Note that these circumstances are more likely to obtain in C-Kermit 7.0, in which:
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:
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:
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.
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 not work (UNIX "make", backups, etc).
Timezone handling is deferred for a future release.
The defaults have not been changed; Kermit 95 still has autodownload ON by default, and C-Kermit has it OFF by default.
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 Section 9.3 for details.
define \%a oofa.* remote query kermit files(\%a) ; Client's \%a remote query kermit files(\\%a) ; Server's \%a
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.
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.
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)
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
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.
The server's directory listings are in the following format:
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.
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.
{{name1}{name2}{name3}{...}}
e.g. SET SERVER CD-MESSAGE FILE {{./.readme}{README.TXT}{READ.ME}}
The default CD message file name is system dependent. SHOW CD or SHOW SERVER displays the list. Also see Section 4.5.2.
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).
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 Section 6.6.
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 Appendix III.
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:
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:
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