+++ /dev/null
-/* C K C F T P -- FTP Client for C-Kermit */
-
-char *ckftpv = "FTP Client, 8.0.226, 7 Jan 2004";
-
-/*
- Authors:
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
- Frank da Cruz <fdc@columbia.edu>,
- The Kermit Project, Columbia University.
-
- Copyright (C) 2000, 2004,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-
- Portions of conditionally included code Copyright Regents of the
- University of California and The Stanford SRP Authentication Project;
- see notices below.
-*/
-
-/*
- Pending...
-
- . Implement recursive NLST downloads by trying to CD to each filename.
- If it works, it's a directory; if not, it's a file -- GET it. But
- that won't work with servers like wu-ftpd that don't send directory
- names. Recursion with MLSD is done.
-
- . Make syslog entries for session? Files?
-
- . Messages are printed to stdout and stderr in random fashion. We should
- either print everything to stdout, or else be systematic about when
- to use stderr.
-
- . Implement mail (MAIL, MLFL, MSOM, etc) if any servers support it.
-
- . Adapt to VMS. Big job because of its record-oriented file system.
- RMS programmer required. There are probably also some VMS TCP/IP
- product-specific wrinkles, e.g. attribute preservation in VMS-to-VMS
- transfers using special options for Multinet or other FTP servers
- (find out about STRU VMS).
-*/
-
-/*
- Quick FTP command reference:
-
- RFC765 (1980) and earlier:
- MODE S(tream), B(lock), C(ompressed)
- STRU F(ILE), R(ECORD), P(AGE)
- TYPE A(SCII) <format>, E(BCDIC) <format>, I(MAGE), L(OCAL) <bytesize>
- PORT - Port
- PASV - Passive mode
- USER - User
- PASS - Password
- ACCT - Account
- CWD - Change Working Directory
- REIN - Logout but not disconnect
- QUIT - Bye
- RETR - Retreive
- STOR - Store
- APPE - Append
- ALLO - Allocate
- REST - Restart
- RNFR - Rename from
- RNTO - Rename to
- ABOR - Cancel
- DELE - Delete
- LIST - Directory
- NLST - Name List
- SITE - Site parameters or commands
- STAT - Status
- HELP - Help
- NOOP - Noop
-
- RFC959 (1985):
- CDUP - Change to Parent Directory
- SMNT - Structure Mount
- STOU - Store Unique
- RMD - Remove Directory
- MKD - Make Directory
- PWD - Print Directory
- SYST - System
-
- RFC2389 (1998):
- FEAT - List Features (done)
- OPTS - Send options (done)
-
- RFC2640 (1999):
- LANG - Specify language for messages (not done)
-
- Pending (Internet Drafts):
- SIZE - File size (done)
- MDTM - File modification date-time (done)
- MLST - File name and attribute list (single file) (not done)
- MLSD - File list with attributes (multiple files) (done)
- MAIL, MLFL, MSOM - mail delivery (not done)
-
- Alphabetical syntax list:
- ABOR <CRLF>
- ACCT <SP> <account-information> <CRLF>
- ALLO <SP> <decimal-integer> [<SP> R <SP> <decimal-integer>] <CRLF>
- APPE <SP> <pathname> <CRLF>
- CDUP <CRLF>
- CWD <SP> <pathname> <CRLF>
- DELE <SP> <pathname> <CRLF>
- FEAT <CRLF>
- HELP [<SP> <string>] <CRLF>
- LANG [<SP> <language-tag> ] <CRLF>
- LIST [<SP> <pathname>] <CRLF>
- MKD <SP> <pathname> <CRLF>
- MLSD [<SP> <pathname>] <CRLF>
- MLST [<SP> <pathname>] <CRLF>
- MODE <SP> <mode-code> <CRLF>
- NLST [<SP> <pathname-or-wildcard>] <CRLF>
- NOOP <CRLF>
- OPTS <SP> <commandname> [ <SP> <command-options> ] <CRLF>
- PASS <SP> <password> <CRLF>
- PASV <CRLF>
- PORT <SP> <host-port> <CRLF>
- PWD <CRLF>
- QUIT <CRLF>
- REIN <CRLF>
- REST <SP> <marker> <CRLF>
- RETR <SP> <pathname> <CRLF>
- RMD <SP> <pathname> <CRLF>
- RNFR <SP> <pathname> <CRLF>
- RNTO <SP> <pathname> <CRLF>
- SITE <SP> <string> <CRLF>
- SIZE <SP> <pathname> <CRLF>
- SMNT <SP> <pathname> <CRLF>
- STAT [<SP> <pathname>] <CRLF>
- STOR <SP> <pathname> <CRLF>
- STOU <CRLF>
- STRU <SP> <structure-code> <CRLF>
- SYST <CRLF>
- TYPE <SP> <type-code> <CRLF>
- USER <SP> <username> <CRLF>
-*/
-#include "ckcsym.h" /* Standard includes */
-#include "ckcdeb.h"
-
-#ifndef NOFTP /* NOFTP = no FTP */
-#ifndef SYSFTP /* SYSFTP = use external ftp client */
-#ifdef TCPSOCKET /* Build only if TCP/IP included */
-#define CKCFTP_C
-
-/* Note: much of the following duplicates what was done in ckcdeb.h */
-/* but let's not mess with it unless it causes trouble. */
-
-#ifdef CK_ANSIC
-#include <stdarg.h>
-#else /* CK_ANSIC */
-#include <varargs.h>
-#endif /* CK_ANSIC */
-#include <signal.h>
-#ifdef OS2
-#ifdef OS2ONLY
-#include <os2.h>
-#endif /* OS2ONLY */
-#include "ckowin.h"
-#include "ckocon.h"
-#endif /* OS2 */
-#ifndef ZILOG
-#ifdef NT
-#include <setjmpex.h>
-#ifdef NTSIG
-extern int TlsIndex;
-#endif /* NTSIG */
-#else /* NT */
-#include <setjmp.h>
-#endif /* NT */
-#else
-#include <setret.h>
-#endif /* ZILOG */
-#include "ckcsig.h"
-#include <sys/stat.h>
-#include <ctype.h>
-#include <errno.h>
-#ifndef NOTIMEH
-#include <time.h>
-#endif /* NOTIMEH */
-#ifndef EPIPE
-#define EPIPE 32 /* Broken pipe error */
-#endif /* EPIPE */
-
-/* Kermit includes */
-
-#include "ckcasc.h"
-#include "ckcker.h"
-#include "ckucmd.h"
-#include "ckuusr.h"
-#include "ckcnet.h" /* Includes ckctel.h */
-#include "ckctel.h" /* (then why include it again?) */
-#include "ckcxla.h"
-
-/*
- How to get the struct timeval definition so we can call select(). The
- xxTIMEH symbols are defined in ckcdeb.h, overridden in various makefile
- targets. The problem is: maybe we have already included some header file
- that defined struct timeval, and maybe we didn't. If we did, we don't want
- to include another header file that defines it again or the compilation will
- fail. If we didn't, we have to include the header file where it's defined.
- But in some cases even that won't work because of strict POSIX constraints
- or somesuch, or because this introduces other conflicts (e.g. struct tm
- multiply defined), in which case we have to define it ourselves, but this
- can work only if we didn't already encounter a definition.
-*/
-#ifndef DCLTIMEVAL
-#ifdef SV68R3V6
-#define DCLTIMEVAL
-#else
-#ifdef SCO234
-#define DCLTIMEVAL
-#endif /* SCO234 */
-#endif /* SV68R3V6 */
-#endif /* DCLTIMEVAL */
-
-#ifdef DCLTIMEVAL
-/* Also maybe in some places the elements must be unsigned... */
-struct timeval {
- long tv_sec;
- long tv_usec;
-};
-#ifdef COMMENT
-/* Currently we don't use this... */
-struct timezone {
- int tz_minuteswest;
- int tz_dsttime;
-};
-#endif /* COMMENT */
-#else /* !DCLTIMEVAL */
-#ifndef NOSYSTIMEH
-#ifdef SYSTIMEH
-#include <sys/time.h>
-#endif /* SYSTIMEH */
-#endif /* NOSYSTIMEH */
-#ifndef NOSYSTIMEBH
-#ifdef SYSTIMEBH
-#include <sys/timeb.h>
-#endif /* SYSTIMEBH */
-#endif /* NOSYSTIMEBH */
-#endif /* DCLTIMEVAL */
-
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif /* HAVE_STDLIB_H */
-
-#ifndef NOSETTIME
-#ifdef COMMENT
-/* This section moved to ckcdeb.h */
-#ifdef POSIX
-#define UTIMEH
-#else
-#ifdef HPUX9
-#define UTIMEH
-#else
-#ifdef OS2
-#define SYSUTIMEH
-#endif /* OS2 */
-#endif /* HPUX9 */
-#endif /* POSIX */
-#endif /* COMMENT */
-
-#ifdef SYSUTIMEH
-#include <sys/utime.h>
-#else
-#ifdef UTIMEH
-#include <utime.h>
-#define SYSUTIMEH
-#endif /* UTIMEH */
-#endif /* SYSUTIMEH */
-#endif /* NOSETTIME */
-
-#ifndef SCO_OSR504
-#ifdef SELECT_H
-#include <sys/select.h>
-#endif /* SELECT_H */
-#endif /* SCO_OSR504 */
-
-/* select() dialects... */
-
-#ifdef UNIX
-#define BSDSELECT /* BSD select() syntax/semantics */
-#else
-#ifdef OS2 /* OS/2 or Win32 */
-#ifdef NT
-#define BSDSELECT
-#else /* NT */
-#define IBMSELECT
-#endif /* NT */
-#endif /* OS2 */
-#endif /* UNIX */
-
-/* Other select() peculiarities */
-
-#ifdef HPUX
-#ifndef HPUX10 /* HP-UX 9.xx and earlier */
-#ifndef HPUX1100
-/* The three interior args to select() are (int *) rather than (fd_set *) */
-#ifndef INTSELECT
-#define INTSELECT
-#endif /* INTSELECT */
-#endif /* HPUX1100 */
-#endif /* HPUX10 */
-#endif /* HPUX */
-
-#ifdef CK_SOCKS /* SOCKS Internet relay package */
-#ifdef CK_SOCKS5 /* SOCKS 5 */
-#define accept SOCKSaccept
-#define bind SOCKSbind
-#define connect SOCKSconnect
-#define getsockname SOCKSgetsockname
-#define listen SOCKSlisten
-#else /* Not SOCKS 5 */
-#define accept Raccept
-#define bind Rbind
-#define connect Rconnect
-#define getsockname Rgetsockname
-#define listen Rlisten
-#endif /* CK_SOCKS5 */
-#endif /* CK_SOCKS */
-
-#ifndef NOHTTP
-extern char * tcp_http_proxy; /* Name[:port] of http proxy server */
-extern int tcp_http_proxy_errno;
-extern char * tcp_http_proxy_user;
-extern char * tcp_http_proxy_pwd;
-extern char * tcp_http_proxy_agent;
-#define HTTPCPYL 1024
-static char proxyhost[HTTPCPYL];
-#endif /* NOHTTP */
-int ssl_ftp_proxy = 0; /* FTP over SSL/TLS Proxy Server */
-
-/* Feature selection */
-
-#ifndef USE_SHUTDOWN
-/*
- We don't use shutdown() because (a) we always call it just before close()
- so it's redundant and unnecessary, and (b) it introduces a long pause on
- some platforms like SV/68 R3.
-*/
-/* #define USE_SHUTDOWN */
-#endif /* USE_SHUTDOWN */
-
-#ifndef NORESEND
-#ifndef NORESTART /* Restart / recover */
-#ifndef FTP_RESTART
-#define FTP_RESTART
-#endif /* FTP_RESTART */
-#endif /* NORESTART */
-#endif /* NORESEND */
-
-#ifndef NOUPDATE /* Update mode */
-#ifndef DOUPDATE
-#define DOUPDATE
-#endif /* DOUPDATE */
-#endif /* NOUPDATE */
-
-#ifndef UNICODE /* Unicode required */
-#ifndef NOCSETS /* for charset translation */
-#define NOCSETS
-#endif /* NOCSETS */
-#endif /* UNICODE */
-
-#ifndef OS2
-#ifndef HAVE_MSECS /* Millisecond timer */
-#ifdef UNIX
-#ifdef GFTIMER
-#define HAVE_MSECS
-#endif /* GFTIMER */
-#endif /* UNIX */
-#endif /* HAVE_MSECS */
-#endif /* OS2 */
-
-#ifdef PIPESEND /* PUT from pipe */
-#ifndef PUTPIPE
-#define PUTPIPE
-#endif /* PUTPIPE */
-#endif /* PIPESEND */
-
-#ifndef NOSPL /* PUT from array */
-#ifndef PUTARRAY
-#define PUTARRAY
-#endif /* PUTARRAY */
-#endif /* NOSPL */
-
-/* Security... */
-
-#ifdef CK_SRP
-#define FTP_SRP
-#endif /* CK_SRP */
-
-#ifdef CK_KERBEROS
-#ifdef KRB4
-/*
- There is a conflict between the Key Schedule formats used internally
- within the standalone MIT KRB4 library and that used by Eric Young
- in OpenSSL and his standalone DES library. Therefore, KRB4 FTP AUTH
- cannot be supported when either of those two packages are used.
-*/
-#ifdef KRB524
-#define FTP_KRB4
-#else /* KRB524 */
-#ifndef CK_SSL
-#ifndef LIBDES
-#define FTP_KRB4
-#endif /* LIBDES */
-#endif /* CK_SSL */
-#endif /* KRB524 */
-#endif /* KRB4 */
-#ifdef KRB5
-#ifndef HEIMDAL
-#define FTP_GSSAPI
-#endif /* HEIMDAL */
-#endif /* KRB5 */
-#endif /* CK_KERBEROS */
-
-/* FTP_SECURITY is defined if any of the above is selected */
-#ifndef FTP_SECURITY
-#ifdef FTP_GSSAPI
-#define FTP_SECURITY
-#else
-#ifdef FTP_KRB4
-#define FTP_SECURITY
-#else
-#ifdef FTP_SRP
-#define FTP_SECURITY
-#else
-#ifdef CK_SSL
-#define FTP_SECURITY
-#endif /* CK_SSL */
-#endif /* FTP_SRP */
-#endif /* FTP_KRB4 */
-#endif /* FTP_GSSAPI */
-#endif /* FTP_SECURITY */
-
-#ifdef CK_DES
-#ifdef CK_SSL
-#ifndef LIBDES
-#define LIBDES
-#endif /* LIBDES */
-#endif /* CK_SSL */
-#endif /* CK_DES */
-
-#ifdef CRYPT_DLL
-#ifndef LIBDES
-#define LIBDES
-#endif /* LIBDES */
-#endif /* CRYPT_DLL */
-
-#ifdef FTP_KRB4
-#define des_cblock Block
-#define des_key_schedule Schedule
-#ifdef KRB524
-#ifdef NT
-#define _WINDOWS
-#endif /* NT */
-#include "kerberosIV/krb.h"
-#else /* KRB524 */
-#ifdef SOLARIS
-#ifndef sun
-/* For some reason lost in history the Makefile Solaris targets have -Usun */
-#define sun
-#endif /* sun */
-#endif /* SOLARIS */
-#include "krb.h"
-#define krb_get_err_text_entry krb_get_err_text
-#endif /* KRB524 */
-#endif /* FTP_KRB4 */
-
-#ifdef CK_SSL
-#ifdef FTP_KRB4
-#ifndef HEADER_DES_H
-#define HEADER_DES_H
-#endif /* HEADER_DES_H */
-#endif /* FTP_KRB4 */
-#include "ck_ssl.h"
-#endif /* CK_SSL */
-
-#ifdef FTP_SRP
-#ifdef HAVE_PWD_H
-#include "pwd.h"
-#endif /* HAVE_PWD_H */
-#include "t_pwd.h"
-#include "t_client.h"
-#include "krypto.h"
-#endif /* FTP_SRP */
-
-#ifdef FTP_GSSAPI
-#include <gssapi/gssapi.h>
-/*
- Need to include the krb5 file, because we're doing manual fallback
- from the v2 mech to the v1 mech. Once there's real negotiation,
- we can be generic again.
-*/
-#include <gssapi/gssapi_generic.h>
-#include <gssapi/gssapi_krb5.h>
-static gss_ctx_id_t gcontext;
-#endif /* FTP_GSSAPI */
-
-#ifdef OS2
-#ifdef FTP_SRP
-#define MAP_KRYPTO
-#ifdef SRPDLL
-#define MAP_SRP
-#endif /* SRPDLL */
-#endif /* FTP_SRP */
-#ifdef FTP_KRB4
-#define MAP_KRB4
-#ifdef CK_ENCRYPTION
-#define MAP_DES
-#endif /* CK_ENCRYPTION */
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
-#define MAP_GSSAPI
-#define GSS_OIDS
-#endif /* FTP_GSSAPI */
-#include "ckoath.h"
-
-extern int k95stdout, wherex[], wherey[];
-extern unsigned char colorcmd;
-#endif /* OS2 */
-
-#ifdef FTP_KRB4
-static char ftp_realm[REALM_SZ + 1];
-static KTEXT_ST ftp_tkt;
-#ifdef OS2
-static LEASH_CREDENTIALS ftp_cred;
-#else /* OS2 */
-static CREDENTIALS ftp_cred;
-#endif /* OS2 */
-static MSG_DAT ftp_msg_data;
-static des_key_schedule ftp_sched;
-static int foo[4] = {99,99,99,99};
-#endif /* FTP_KRB4 */
-
-/* getreply() function codes */
-
-#define GRF_AUTH 1 /* Reply to AUTH command */
-#define GRF_FEAT 2 /* Reply to FEAT command */
-
-/* Operational definitions */
-
-#define DEF_VBM 0 /* Default verbose mode */
-/* #define SETVBM */ /* (see getreply) */
-
-#define URL_ONEFILE /* GET, not MGET, for FTP URL */
-
-#define FTP_BUFSIZ 10240 /* Max size for FTP cmds & replies */
-#define SRVNAMLEN 32 /* Max length for server type name */
-#define PWDSIZ 256
-#define PASSBUFSIZ 256
-#define PROMPTSIZ 256
-
-#ifndef MGETMAX /* Max operands for MGET command */
-#define MGETMAX 1000
-#endif /* MGETMAX */
-
-#ifdef FTP_SRP
-#define FUDGE_FACTOR 100
-#endif /* FTP_SRP */
-
-/*
- Amount of growth from cleartext to ciphertext. krb_mk_priv adds this
- number bytes. Must be defined for each auth type.
- GSSAPI appears to add 52 bytes, but I'm not sure it is a constant--hartmans
- 3DES requires 56 bytes. Lets use 96 just to be sure.
-*/
-#ifdef FTP_GSSAPI
-#ifndef FUDGE_FACTOR
-#define FUDGE_FACTOR 96
-#endif /* FUDGE_FACTOR */
-#endif /* FTP_GSSAPI */
-
-#ifdef FTP_KRB4
-#ifndef FUDGE_FACTOR
-#define FUDGE_FACTOR 32
-#endif /* FUDGE_FACTOR */
-#endif /* FTP_KRB4 */
-
-#ifndef FUDGE_FACTOR /* In case no auth types define it */
-#define FUDGE_FACTOR 0
-#endif /* FUDGE_FACTOR */
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif /* MAXHOSTNAMELEN */
-#define MAX_DNS_NAMELEN (15*(MAXHOSTNAMELEN + 1)+1)
-
-/* Fascist compiler toadying */
-
-#ifndef SENDARG2TYPE
-#ifdef COMMENT /* Might be needed here and there */
-#define SENDARG2TYPE const char *
-#else
-#define SENDARG2TYPE char *
-#endif /* COMMENT */
-#endif /* SENDARG2TYPE */
-
-/* Common text messages */
-
-static char *nocx = "?No FTP control connection\n";
-
-static char *fncnam[] = {
- "rename", "overwrite", "backup", "append", "discard", "ask", "update",
- "dates-differ", ""
-};
-
-/* Macro definitions */
-
-/* Used to speed up text-mode PUTs */
-#define zzout(fd,c) \
-((fd<0)?(-1):((nout>=ucbufsiz)?(zzsend(fd,c)):(ucbuf[nout++]=c)))
-
-#define CHECKCONN() if(!connected){printf(nocx);return(-9);}
-
-/* Externals */
-
-#ifdef CK_URL
-extern struct urldata g_url;
-#endif /* CK_URL */
-
-#ifdef DYNAMIC
-extern char *zinbuffer, *zoutbuffer; /* Regular Kermit file i/o */
-#else
-extern char zinbuffer[], zoutbuffer[];
-#endif /* DYNAMIC */
-extern char *zinptr, *zoutptr;
-extern int zincnt, zoutcnt, zobufsize, fncact;
-
-#ifdef CK_TMPDIR
-extern int f_tmpdir; /* Directory changed temporarily */
-extern char savdir[]; /* For saving current directory */
-extern char * dldir;
-#endif /* CK_TMPDIR */
-
-extern char * rfspec, * sfspec, * srfspec, * rrfspec; /* For WHERE command */
-
-extern xx_strp xxstring;
-extern struct keytab onoff[], txtbin[], rpathtab[];
-extern int nrpathtab, xfiletype, patterns, gnferror, moving, what, pktnum;
-extern int success, nfils, sndsrc, quiet, nopush, recursive, inserver, binary;
-extern int filepeek, nscanfile, fsecs, xferstat, xfermode, lastxfer, tsecs;
-extern int backgrd, spackets, rpackets, spktl, rpktl, xaskmore, cmd_rows;
-extern int nolinks, msgflg, keep;
-extern long fsize, ffc, tfc, filcnt, xfsecs, tfcps, cps, oldcps;
-#ifdef GFTIMER
-extern CKFLOAT fptsecs, fpfsecs, fpxfsecs;
-#else
-extern long xfsecs;
-#endif /* GFTIMER */
-
-extern char filnam[], * filefile, myhost[];
-extern char * snd_move, * rcv_move, * snd_rename, * rcv_rename;
-extern int g_skipbup, skipbup, sendmode;
-extern int g_displa, fdispla, displa;
-
-#ifdef LOCUS
-extern int locus, autolocus;
-#endif /* LOCUS */
-
-#ifndef NOCSETS
-extern int nfilc, dcset7, dcset8, fileorder;
-extern struct csinfo fcsinfo[];
-extern struct keytab fcstab[];
-extern int fcharset;
-#endif /* NOCSETS */
-
-extern char sndbefore[], sndafter[], *sndexcept[]; /* Selection criteria */
-extern char sndnbefore[], sndnafter[], *rcvexcept[];
-extern CHAR feol;
-extern long sendstart, sndsmaller, sndlarger, rs_len;
-
-extern char * remdest;
-extern int remfile, remappd, rempipe;
-
-#ifndef NOSPL
-extern int cmd_quoting;
-#ifdef PUTARRAY
-extern int sndxlo, sndxhi, sndxin;
-extern char sndxnam[];
-extern char **a_ptr[]; /* Array pointers */
-extern int a_dim[]; /* Array dimensions */
-#endif /* PUTARRAY */
-#endif /* NOSPL */
-
-#ifndef NOMSEND /* MPUT and ADD SEND-LIST lists */
-extern char *msfiles[];
-extern int filesinlist;
-extern struct filelist * filehead;
-extern struct filelist * filetail;
-extern struct filelist * filenext;
-extern int addlist;
-extern char fspec[]; /* Most recent filespec */
-extern int fspeclen; /* Length of fspec[] buffer */
-#endif /* NOMSEND */
-
-extern int pipesend;
-#ifdef PIPESEND
-extern char * sndfilter, * rcvfilter;
-#endif /* PIPESEND */
-
-#ifdef CKROOT
-extern int ckrooterr;
-#endif /* CKROOT */
-
-#ifdef KRB4
-extern int krb4_autoget;
-_PROTOTYP(char * ck_krb4_realmofhost,(char *));
-#endif /* KRB4 */
-
-#ifdef KRB5
-extern int krb5_autoget;
-extern int krb5_d_no_addresses;
-_PROTOTYP(char * ck_krb5_realmofhost,(char *));
-#endif /* KRB5 */
-
-#ifdef DCMDBUF
-extern char *atmbuf; /* Atom buffer (malloc'd) */
-extern char *cmdbuf; /* Command buffer (malloc'd) */
-extern char *line; /* Big string buffer #1 */
-extern char *tmpbuf; /* Big string buffer #2 */
-#else
-extern char atmbuf[]; /* The same, but static */
-extern char cmdbuf[];
-extern char line[];
-extern char tmpbuf[];
-#endif /* DCMDBUF */
-
-extern char * cmarg, * cmarg2, ** cmlist; /* For setting up file lists */
-
-/* Public variables declared here */
-
-#ifdef NOXFER
-int ftpget = 1; /* GET/PUT/REMOTE orientation FTP */
-#else
-int ftpget = 2; /* GET/PUT/REMOTE orientation AUTO */
-#endif /* NOXFER */
-int ftpcode = -1; /* Last FTP response code */
-int ftp_cmdlin = 0; /* FTP invoked from command line */
-int ftp_fai = 0; /* FTP failure count */
-int ftp_deb = 0; /* FTP debugging */
-int ftp_dis = -1; /* FTP display style */
-int ftp_log = 1; /* FTP Auto-login */
-int sav_log = -1;
-int ftp_action = 0; /* FTP action from command line */
-int ftp_dates = 1; /* Set file dates from server */
-
-char ftp_reply_str[FTP_BUFSIZ] = ""; /* Last line of previous reply */
-char ftp_srvtyp[SRVNAMLEN] = { NUL, NUL }; /* Server's system type */
-char ftp_user_host[MAX_DNS_NAMELEN]= ""; /* FTP hostname specified by user */
-char * ftp_host = NULL; /* FTP hostname */
-char * ftp_logname = NULL; /* FTP username */
-char * ftp_rdir = NULL; /* Remote directory from cmdline */
-char * ftp_apw = NULL; /* Anonymous password */
-
-/* Definitions and typedefs needed for prototypes */
-
-#define sig_t my_sig_t
-#define sigtype SIGTYP
-typedef sigtype (*sig_t)();
-
-/* Static global variables */
-
-static char ftpsndbuf[FTP_BUFSIZ+64];
-
-static char * fts_sto = NULL;
-
-static int ftpsndret = 0;
-static struct _ftpsnd {
- sig_t oldintr, oldintp;
- int reply;
- int incs,
- outcs;
- char * cmd, * local, * remote;
- int bytes;
- int restart;
- int xlate;
- char * lmode;
-} ftpsnd;
-
-/*
- This is just a first stab -- these strings should match how the
- corresponding FTP servers identify themselves.
-*/
-#ifdef UNIX
-static char * myostype = "UNIX";
-#else
-#ifdef VMS
-/* not yet... */
-static char * myostype = "VMS";
-#else
-#ifdef OS2
-#ifdef NT
-static char * myostype = "WIN32";
-#else
-static char * myostype = "OS/2";
-#endif /* NT */
-#else
-static char * myostype = "UNSUPPORTED";
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* UNIX */
-
-static int noinit = 0; /* Don't send REST, STRU, MODE */
-static int alike = 0; /* Client/server like platforms */
-static int local = 1; /* Shadows Kermit global 'local' */
-static int dout = -1; /* Data connection file descriptor */
-static int dpyactive = 0; /* Data transfer is active */
-static int globaldin = -1; /* Data connection f.d. */
-static int out2screen = 0; /* GET output is to screen */
-static int forcetype = 0; /* Force text or binary mode */
-static int cancelfile = 0; /* File canceled */
-static int cancelgroup = 0; /* Group canceled */
-static int anonymous = 0; /* Logging in as anonymous */
-static int loggedin = 0; /* Logged in (or not) */
-static int puterror = 0; /* What to do on PUT error */
-static int geterror = 0; /* What to do on GET error */
-static int rfrc = 0; /* remote_files() return code */
-static int okrestart = 0; /* Server understands REST */
-static int printlines = 0; /* getreply()should print data lines */
-static int haveurl = 0; /* Invoked by command-line FTP URL */
-static int mdtmok = 1; /* Server supports MDTM */
-static int sizeok = 1;
-static int featok = 1;
-static int mlstok = 1;
-static int stouarg = 1;
-static int typesent = 0;
-static int havesigint = 0;
-static long havetype = 0;
-static long havesize = -1L;
-static char * havemdtm = NULL;
-static int mgetmethod = 0; /* NLST or MLSD */
-static int mgetforced = 0;
-
-static int i, /* j, k, */ x, y, z; /* Volatile temporaries */
-static int c0, c1; /* Temp variables for characters */
-
-static char putpath[CKMAXPATH+1] = { NUL, NUL };
-static char asnambuf[CKMAXPATH+1] = { NUL, NUL };
-
-#define RFNBUFSIZ 4096 /* Remote filename buffer size */
-
-static unsigned int maxbuf = 0, actualbuf = 0;
-static CHAR *ucbuf = NULL;
-static int ucbufsiz = 0;
-static unsigned int nout = 0; /* Number of chars in ucbuf */
-
-static jmp_buf recvcancel;
-static jmp_buf sendcancel;
-static jmp_buf ptcancel;
-static jmp_buf jcancel;
-static int ptabflg = 0;
-
-/* Protection level symbols */
-
-#define FPL_CLR 1 /* Clear */
-#define FPL_SAF 2 /* Safe */
-#define FPL_PRV 3 /* Private */
-#define FPL_CON 4 /* Confidential */
-
-/* Symbols for file types returned by MLST/MLSD */
-
-#define FTYP_FILE 1 /* Regular file */
-#define FTYP_DIR 2 /* Directory */
-#define FTYP_CDIR 3 /* Current directory */
-#define FTYP_PDIR 4 /* Parent directory */
-
-/* File type symbols keyed to the file-type symbols from ckcker.h */
-
-#define FTT_ASC XYFT_T /* ASCII (text) */
-#define FTT_BIN XYFT_B /* Binary (image) */
-#define FTT_TEN XYFT_X /* TENEX (TOPS-20) */
-
-/* Server feature table - sfttab[0] > 0 means server supports FEAT and OPTS */
-
-static int sfttab[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
-
-#define SFT_AUTH 1 /* FTP server feature codes */
-#define SFT_LANG 2
-#define SFT_MDTM 3
-#define SFT_MLST 4
-#define SFT_PBSZ 5
-#define SFT_PROT 6
-#define SFT_REST 7
-#define SFT_SIZE 8
-#define SFT_TVFS 9
-#define SFT_UTF8 10
-
-#define CNV_AUTO 2 /* FTP filename conversion */
-#define CNV_CNV 1
-#define CNV_LIT 0
-
-/* SET FTP values */
-
-static int /* SET FTP values... */
- ftp_aut = 1, /* Auto-authentication */
-#ifdef FTP_SECURITY
- ftp_cry = 1, /* Auto-encryption */
- ftp_cfw = 0, /* Credential forwarding */
-#endif /* FTP_SECURITY */
- ftp_cpl = FPL_CLR, /* Command protection level */
- ftp_dpl = FPL_CLR, /* Data protection level */
-#ifdef FTP_PROXY
- ftp_prx = 0, /* Use proxy */
-#endif /* FTP_PROXY */
- sav_psv = -1, /* For saving passive mode */
- ftp_psv = 1, /* Passive mode */
- ftp_spc = 1, /* Send port commands */
- ftp_typ = FTT_ASC, /* Type */
- get_auto = 1, /* Automatic type switching for GET */
- tenex = 0, /* Type is Tenex */
- ftp_usn = 0, /* Unique server names */
- ftp_prm = 0, /* Permissions */
- ftp_cnv = CNV_AUTO, /* Filename conversion (2 = auto) */
- ftp_vbm = DEF_VBM, /* Verbose mode */
- ftp_vbx = DEF_VBM, /* Sticky version of same */
- ftp_err = 0, /* Error action */
- ftp_fnc = -1; /* Filename collision action */
-
-#ifdef CK_SSL
-static int ftp_bug_use_ssl_v2 = 0; /* use SSLv2 for AUTH SSL */
-#endif /* CK_SSL */
-
-static int
-#ifdef NOCSETS
- ftp_csr = -1, /* Remote (server) character set */
-#else
- ftp_csr = FC_UTF8,
-#endif /* NOCSETS */
- ftp_xla = 0; /* Character-set translation on/off */
-int
- ftp_csx = -1, /* Remote charset currently in use */
- ftp_csl = -1; /* Local charset currently in use */
-
-static int g_ftp_typ = FTT_ASC; /* For saving and restoring ftp_typ */
-
-char * ftp_nml = NULL; /* /NAMELIST */
-char * ftp_tmp = NULL; /* Temporary string */
-static char * ftp_acc = NULL; /* Account string */
-static char * auth_type = NULL; /* Authentication type */
-static char * srv_renam = NULL; /* Server-rename string */
-FILE * fp_nml = NULL; /* Namelist file pointer */
-
-static int csocket = -1; /* Control socket */
-static int connected = 0; /* Connected to FTP server */
-static short ftp_port = 0; /* FTP port */
-#ifdef FTPHOST
-static int hostcmd = 0; /* Has HOST command been sent */
-#endif /* FTPHOST */
-static int form, mode, stru, bytesize, curtype = FTT_ASC;
-static char bytename[8];
-
-/* For parsing replies to FTP server command */
-static char *reply_parse, reply_buf[FTP_BUFSIZ], *reply_ptr;
-
-#ifdef FTP_PROXY
-static int proxy, unix_proxy
-#endif /* FTP_PROXY */
-
-static char pasv[64]; /* Passive-mode port */
-static int passivemode = 0;
-static int sendport = 0;
-static int servertype = 0; /* FTP server's OS type */
-
-static int testing = 0;
-static char ftpcmdbuf[FTP_BUFSIZ];
-
-/* Macro definitions */
-
-#define UC(b) ckitoa(((int)b)&0xff)
-#define nz(x) ((x) == 0 ? 1 : (x))
-
-/* Command tables and definitions */
-
-#define FTP_ACC 1 /* FTP command keyword codes */
-#define FTP_APP 2
-#define FTP_CWD 3
-#define FTP_CHM 4
-#define FTP_CLS 5
-#define FTP_DEL 6
-#define FTP_DIR 7
-#define FTP_GET 8
-#define FTP_IDL 9
-#define FTP_MDE 10
-#define FTP_MDI 11
-#define FTP_MGE 12
-#define FTP_MKD 13
-#define FTP_MOD 14
-#define FTP_MPU 15
-#define FTP_OPN 16
-#define FTP_PUT 17
-#define FTP_PWD 18
-#define FTP_RGE 19
-#define FTP_REN 20
-#define FTP_RES 21
-#define FTP_HLP 22
-#define FTP_RMD 23
-#define FTP_STA 24
-#define FTP_SIT 25
-#define FTP_SIZ 26
-#define FTP_SYS 27
-#define FTP_UMA 28
-#define FTP_GUP 29
-#define FTP_USR 30
-#define FTP_QUO 31
-#define FTP_TYP 32
-#define FTP_FEA 33
-#define FTP_OPT 34
-#define FTP_CHK 35
-#define FTP_VDI 36
-#define FTP_ENA 37
-#define FTP_DIS 38
-
-struct keytab gprtab[] = { /* GET-PUT-REMOTE keywords */
- { "auto", 2, 0 },
- { "ftp", 1, 0 },
- { "kermit", 0, 0 }
-};
-
-static struct keytab qorp[] = { /* QUIT or PROCEED keywords */
- { "proceed", 0, 0 }, /* 0 = proceed */
- { "quit", 1, 0 } /* 1 = quit */
-};
-
-static struct keytab ftpcmdtab[] = { /* FTP command table */
- { "account", FTP_ACC, 0 },
- { "append", FTP_APP, 0 },
- { "bye", FTP_CLS, 0 },
- { "cd", FTP_CWD, 0 },
- { "cdup", FTP_GUP, 0 },
- { "check", FTP_CHK, 0 },
- { "chmod", FTP_CHM, 0 },
- { "close", FTP_CLS, 0 },
- { "cwd", FTP_CWD, CM_INV },
- { "delete", FTP_MDE, 0 },
- { "directory", FTP_DIR, 0 },
- { "disable", FTP_DIS, 0 },
- { "enable", FTP_ENA, 0 },
- { "features", FTP_FEA, 0 },
- { "get", FTP_GET, 0 },
- { "help", FTP_HLP, 0 },
- { "idle", FTP_IDL, 0 },
- { "login", FTP_USR, CM_INV },
- { "mdelete", FTP_MDE, CM_INV },
- { "mget", FTP_MGE, 0 },
- { "mkdir", FTP_MKD, 0 },
- { "modtime", FTP_MOD, 0 },
- { "mput", FTP_MPU, 0 },
- { "open", FTP_OPN, 0 },
- { "opt", FTP_OPT, CM_INV|CM_ABR },
- { "opts", FTP_OPT, CM_INV },
- { "options", FTP_OPT, 0 },
- { "put", FTP_PUT, 0 },
- { "pwd", FTP_PWD, 0 },
- { "quit", FTP_CLS, CM_INV },
- { "quote", FTP_QUO, 0 },
- { "reget", FTP_RGE, 0 },
- { "rename", FTP_REN, 0 },
- { "reset", FTP_RES, 0 },
- { "rmdir", FTP_RMD, 0 },
- { "send", FTP_PUT, CM_INV },
- { "site", FTP_SIT, 0 },
- { "size", FTP_SIZ, 0 },
- { "status", FTP_STA, 0 },
- { "system", FTP_SYS, 0 },
- { "type", FTP_TYP, 0 },
- { "umask", FTP_UMA, 0 },
- { "up", FTP_GUP, CM_INV },
- { "user", FTP_USR, 0 },
- { "vdirectory",FTP_VDI, 0 },
- { "", 0, 0 }
-};
-static int nftpcmd = (sizeof(ftpcmdtab) / sizeof(struct keytab)) - 1;
-
-#define OPN_ANO 1 /* FTP OPEN switch codes */
-#define OPN_PSW 2
-#define OPN_USR 3
-#define OPN_ACC 4
-#define OPN_ACT 5
-#define OPN_PSV 6
-#define OPN_TLS 7
-#define OPN_NIN 8
-#define OPN_NOL 9
-
-#ifdef FTP_SECURITY
-#ifdef CK_SSL
-#define USETLSTAB
-static struct keytab tlstab[] = { /* FTP SSL/TLS switches */
- { "/ssl", OPN_TLS, 0 },
- { "/tls", OPN_TLS, 0 },
- { "", 0, 0 }
-};
-static int ntlstab = (sizeof(tlstab) / sizeof(struct keytab)) - 1;
-#endif /* CK_SSL */
-#endif /* FTP_SECURITY */
-
-static struct keytab ftpswitab[] = { /* FTP command switches */
- { "/account", OPN_ACC, CM_ARG },
- { "/active", OPN_ACT, 0 },
- { "/anonymous", OPN_ANO, 0 },
- { "/noinit", OPN_NIN, 0 },
- { "/nologin", OPN_NOL, 0 },
- { "/passive", OPN_PSV, 0 },
- { "/password", OPN_PSW, CM_ARG },
- { "/user", OPN_USR, CM_ARG },
- { "", 0, 0 }
-};
-static int nftpswi = (sizeof(ftpswitab) / sizeof(struct keytab)) - 1;
-
-/* FTP { ENABLE, DISABLE } items */
-
-#define ENA_FEAT 1
-#define ENA_MDTM 2
-#define ENA_MLST 3
-#define ENA_SIZE 4
-#define ENA_AUTH 5
-
-static struct keytab ftpenatab[] = {
- { "AUTH", ENA_AUTH, 0 },
- { "FEAT", ENA_FEAT, 0 },
- { "MDTM", ENA_MDTM, 0 },
- { "ML", ENA_MLST, CM_INV|CM_ABR },
- { "MLS", ENA_MLST, CM_INV|CM_ABR },
- { "MLSD", ENA_MLST, CM_INV },
- { "MLST", ENA_MLST, 0 },
- { "SIZE", ENA_SIZE, 0 },
- { "", 0, 0 }
-};
-static int nftpena = (sizeof(ftpenatab) / sizeof(struct keytab)) - 1;
-
-/* SET FTP command keyword indices */
-
-#define FTS_AUT 1 /* Autoauthentication */
-#define FTS_CRY 2 /* Encryption */
-#define FTS_LOG 3 /* Autologin */
-#define FTS_CPL 4 /* Command protection level */
-#define FTS_CFW 5 /* Credentials forwarding */
-#define FTS_DPL 6 /* Data protection level */
-#define FTS_DBG 7 /* Debugging */
-#define FTS_PSV 8 /* Passive mode */
-#define FTS_SPC 9 /* Send port commands */
-#define FTS_TYP 10 /* (file) Type */
-#define FTS_USN 11 /* Unique server names (for files) */
-#define FTS_VBM 12 /* Verbose mode */
-#define FTS_ATP 13 /* Authentication type */
-#define FTS_CNV 14 /* Filename conversion */
-#define FTS_TST 15 /* Test (progress) messages */
-#define FTS_PRM 16 /* (file) Permissions */
-#define FTS_XLA 17 /* Charset translation */
-#define FTS_CSR 18 /* Server charset */
-#define FTS_ERR 19 /* Error action */
-#define FTS_FNC 20 /* Collision */
-#define FTS_SRP 21 /* SRP options */
-#define FTS_GFT 22 /* GET automatic file-type switching */
-#define FTS_DAT 23 /* Set file dates */
-#define FTS_STO 24 /* Server time offset */
-#define FTS_APW 25 /* Anonymous password */
-#define FTS_DIS 26 /* File-transfer display style */
-#define FTS_BUG 27 /* Bug(s) */
-
-/* FTP BUGS */
-
-#define FTB_SV2 1 /* use SSLv2 */
-
-static struct keytab ftpbugtab[] = {
- { "use-ssl-v2", FTB_SV2, 0 }
-};
-static int nftpbug = (sizeof(ftpbugtab) / sizeof(struct keytab));
-
-/* FTP PUT options (mutually exclusive, not a bitmask) */
-
-#define PUT_UPD 1 /* Update */
-#define PUT_RES 2 /* Restart */
-#define PUT_SIM 4 /* Simulation */
-#define PUT_DIF 8 /* Dates Differ */
-
-static struct keytab ftpcolxtab[] = { /* SET FTP COLLISION options */
-#ifndef MAC
- { "append", XYFX_A, 0 }, /* append to old file */
-#endif /* MAC */
-#ifdef COMMENT
- { "ask", XYFX_Q, 0 }, /* ask what to do (not implemented) */
-#endif
- { "backup", XYFX_B, 0 }, /* rename old file */
-#ifndef MAC
- { "dates-differ", XYFX_M, 0 }, /* accept if dates differ */
- { "discard", XYFX_D, 0 }, /* don't accept new file */
- { "no-supersede", XYFX_D, CM_INV }, /* ditto (MSK compatibility) */
-#endif /* MAC */
- { "overwrite", XYFX_X, 0 }, /* overwrite the old file */
- { "rename", XYFX_R, 0 }, /* rename the incoming file */
-#ifndef MAC /* This crashes Mac Kermit. */
- { "update", XYFX_U, 0 }, /* replace if newer */
-#endif /* MAC */
- { "", 0, 0 }
-};
-static int nftpcolx = (sizeof(ftpcolxtab) / sizeof(struct keytab)) - 1;
-
-
-#ifdef FTP_SECURITY
-/* FTP authentication options */
-
-#define FTA_AUTO 0 /* Auto */
-#define FTA_SRP 1 /* SRP */
-#define FTA_GK5 2 /* Kerberos 5 */
-#define FTA_K4 3 /* Kerberos 4 */
-#define FTA_SSL 4 /* SSL */
-#define FTA_TLS 5 /* TLS */
-
-/* FTP authentication types */
-
-#define FTPATYPS 8
-static int ftp_auth_type[FTPATYPS] = {
-#ifdef FTP_GSSAPI
- FTA_GK5, /* GSSAPI Kerberos 5 */
-#endif /* FTP_GK5 */
-#ifdef FTP_SRP
- FTA_SRP, /* SRP */
-#endif /* FTP_SRP */
-#ifdef FTP_KRB4
- FTA_K4, /* Kerberos 4 */
-#endif /* FTP_KRB4 */
-#ifdef CK_SSL
- FTA_TLS, /* TLS */
- FTA_SSL, /* SSL */
-#endif /* CK_SSL */
- 0
-};
-
-static struct keytab ftpauth[] = { /* SET FTP AUTHTYPE cmd table */
- { "automatic", FTA_AUTO, CM_INV },
-#ifdef FTP_GSSAPI
- { "gssapi-krb5", FTA_GK5, 0 },
-#endif /* FTP_GSSAPI */
-#ifdef FTP_KRB4
- { "k4", FTA_K4, CM_INV },
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- { "k5", FTA_GK5, CM_INV },
-#endif /* FTP_GSSAPI */
-#ifdef FTP_KRB4
- { "kerberos4", FTA_K4, 0 },
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- { "kerberos5", FTA_GK5, CM_INV },
-#endif /* FTP_GSSAPI */
-#ifdef FTP_KRB4
- { "kerberos_iv",FTA_K4, CM_INV },
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- { "kerberos_v", FTA_GK5, CM_INV },
-#endif /* FTP_GSSAPI */
-#ifdef FTP_KRB4
- { "krb4", FTA_K4, CM_INV },
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- { "krb5", FTA_GK5, CM_INV },
-#endif /* FTP_GSSAPI */
-#ifdef FTP_SRP
- { "srp", FTA_SRP, 0 },
-#endif /* FTP_SRP */
-#ifdef CK_SSL
- { "ssl", FTA_SSL, 0 },
- { "tls", FTA_TLS, 0 },
-#endif /* CK_SSL */
- { "", 0, 0 }
-};
-static int nftpauth = (sizeof(ftpauth) / sizeof(struct keytab)) - 1;
-
-#ifdef FTP_SRP
-#define SRP_CIPHER 1
-#define SRP_HASH 2
-static struct keytab ftpsrp[] = { /* SET FTP SRP command table */
- { "cipher", SRP_CIPHER, 0 },
- { "hash", SRP_HASH, 0 },
- { "", 0, 0 }
-};
-static int nftpsrp = (sizeof(ftpsrp) / sizeof(struct keytab)) - 1;
-#endif /* FTP_SRP */
-#endif /* FTP_SECURITY */
-
-static struct keytab ftpset[] = { /* SET FTP commmand table */
- { "anonymous-password", FTS_APW, 0 },
-#ifdef FTP_SECURITY
- { "authtype", FTS_ATP, 0 },
- { "autoauthentication", FTS_AUT, 0 },
- { "autoencryption", FTS_CRY, 0 },
-#endif /* FTP_SECURITY */
- { "autologin", FTS_LOG, 0 },
- { "bug", FTS_BUG, 0 },
-#ifndef NOCSETS
- { "character-set-translation",FTS_XLA, 0 },
-#endif /* NOCSETS */
- { "collision", FTS_FNC, 0 },
-#ifdef FTP_SECURITY
- { "command-protection-level", FTS_CPL, 0 },
- { "cpl", FTS_CPL, CM_INV },
- { "credential-forwarding", FTS_CFW, 0 },
- { "da", FTS_DAT, CM_INV|CM_ABR },
- { "data-protection-level", FTS_DPL, 0 },
-#endif /* FTP_SECURITY */
- { "dates", FTS_DAT, 0 },
- { "debug", FTS_DBG, 0 },
- { "display", FTS_DIS, 0 },
-#ifdef FTP_SECURITY
- { "dpl", FTS_DPL, CM_INV },
-#endif /* FTP_SECURITY */
- { "error-action", FTS_ERR, 0 },
- { "filenames", FTS_CNV, 0 },
- { "get-filetype-switching", FTS_GFT, 0 },
- { "passive-mode", FTS_PSV, 0 },
- { "pasv", FTS_PSV, CM_INV },
- { "permissions", FTS_PRM, 0 },
- { "progress-messages", FTS_TST, 0 },
- { "send-port-commands", FTS_SPC, 0 },
-#ifndef NOCSETS
- { "server-character-set", FTS_CSR, 0 },
-#endif /* NOCSETS */
- { "server-time-offset", FTS_STO, 0 },
-#ifdef FTP_SRP
- { "srp", FTS_SRP, 0 },
-#else
- { "srp", FTS_SRP, CM_INV },
-#endif /* FTP_SRP */
- { "type", FTS_TYP, 0 },
- { "unique-server-names", FTS_USN, 0 },
- { "verbose-mode", FTS_VBM, 0 },
- { "", 0, 0 }
-};
-static int nftpset = (sizeof(ftpset) / sizeof(struct keytab)) - 1;
-
-/*
- GET and PUT switches are approximately the same as Kermit GET and SEND,
- and use the same SND_xxx definitions, but hijack a couple for FTP use.
- Don't just make up new ones, since the number of SND_xxx options must be
- known in advance for the switch-parsing arrays.
-*/
-#define SND_USN SND_PRO /* /UNIQUE instead of /PROTOCOL */
-#define SND_PRM SND_PIP /* /PERMISSIONS instead of /PIPES */
-#define SND_TEN SND_CAL /* /TENEX instead of /CALIBRATE */
-
-static struct keytab putswi[] = { /* FTP PUT switch table */
- { "/after", SND_AFT, CM_ARG },
-#ifdef PUTARRAY
- { "/array", SND_ARR, CM_ARG },
-#endif /* PUTARRAY */
- { "/as", SND_ASN, CM_ARG|CM_INV|CM_ABR },
- { "/as-name", SND_ASN, CM_ARG },
- { "/ascii", SND_TXT, CM_INV },
- { "/b", SND_BIN, CM_INV|CM_ABR },
- { "/before", SND_BEF, CM_ARG },
- { "/binary", SND_BIN, 0 },
-#ifdef PUTPIPE
- { "/command", SND_CMD, CM_PSH },
-#endif /* PUTPIPE */
-#ifdef COMMENT
-/* This works but it's dangerous */
-#ifdef DOUPDATE
- { "/dates-differ", SND_DIF, CM_INV },
-#endif /* DOUPDATE */
-#endif /* COMMENT */
- { "/delete", SND_DEL, 0 },
-#ifdef UNIXOROSK
- { "/dotfiles", SND_DOT, 0 },
-#endif /* UNIXOROSK */
- { "/error-action", SND_ERR, CM_ARG },
- { "/except", SND_EXC, CM_ARG },
- { "/filenames", SND_NAM, CM_ARG },
-#ifdef PIPESEND
-#ifndef NOSPL
- { "/filter", SND_FLT, CM_ARG|CM_PSH },
-#endif /* NOSPL */
-#endif /* PIPESEND */
-#ifdef CKSYMLINK
- { "/followlinks", SND_LNK, 0 },
-#endif /* CKSYMLINK */
-#ifdef VMS
- { "/image", SND_IMG, 0 },
-#else
- { "/image", SND_BIN, CM_INV },
-#endif /* VMS */
- { "/larger-than", SND_LAR, CM_ARG },
- { "/listfile", SND_FIL, CM_ARG },
-#ifndef NOCSETS
- { "/local-character-set", SND_CSL, CM_ARG },
-#endif /* NOCSETS */
-#ifdef CK_TMPDIR
- { "/move-to", SND_MOV, CM_ARG },
-#endif /* CK_TMPDIR */
- { "/nobackupfiles", SND_NOB, 0 },
-#ifdef UNIXOROSK
- { "/nodotfiles", SND_NOD, 0 },
-#endif /* UNIXOROSK */
-#ifdef CKSYMLINK
- { "/nofollowlinks", SND_NLK, 0 },
-#endif /* CKSYMLINK */
-
- { "/not-after", SND_NAF, CM_ARG },
- { "/not-before", SND_NBE, CM_ARG },
-#ifdef UNIX
- { "/permissions", SND_PRM, CM_ARG },
-#else
- { "/permissions", SND_PRM, CM_ARG|CM_INV },
-#endif /* UNIX */
- { "/quiet", SND_SHH, 0 },
-#ifdef FTP_RESTART
- { "/recover", SND_RES, 0 },
-#endif /* FTP_RESTART */
-#ifdef RECURSIVE
- { "/recursive", SND_REC, 0 },
-#endif /* RECURSIVE */
- { "/rename-to", SND_REN, CM_ARG },
-#ifdef FTP_RESTART
- { "/restart", SND_RES, CM_INV },
-#endif /* FTP_RESTART */
-#ifndef NOCSETS
- { "/server-character-set", SND_CSR, CM_ARG },
-#endif /* NOCSETS */
- { "/server-rename-to", SND_SRN, CM_ARG },
- { "/simulate", SND_SIM, 0 },
- { "/since", SND_AFT, CM_INV|CM_ARG },
- { "/smaller-than", SND_SMA, CM_ARG },
-#ifdef COMMENT
- { "/starting-at", SND_STA, CM_ARG },
-#endif /* COMMENT */
-#ifdef RECURSIVE
- { "/subdirectories", SND_REC, CM_INV },
-#endif /* RECURSIVE */
- { "/tenex", SND_TEN, 0 },
- { "/text", SND_TXT, 0 },
-#ifndef NOCSETS
- { "/transparent", SND_XPA, 0 },
-#endif /* NOCSETS */
- { "/type", SND_TYP, CM_ARG },
-#ifdef DOUPDATE
- { "/update", SND_UPD, 0 },
-#endif /* DOUPDATE */
- { "/unique-server-names", SND_USN, 0 },
- { "", 0, 0 }
-};
-static int nputswi = (sizeof(putswi) / sizeof(struct keytab)) - 1;
-
-static struct keytab getswi[] = { /* FTP [M]GET switch table */
- { "/after", SND_AFT, CM_INV },
- { "/as", SND_ASN, CM_ARG|CM_INV|CM_ABR },
- { "/as-name", SND_ASN, CM_ARG },
- { "/ascii", SND_TXT, CM_INV },
- { "/before", SND_BEF, CM_INV },
- { "/binary", SND_BIN, 0 },
- { "/collision", SND_COL, CM_ARG },
-#ifdef PUTPIPE
- { "/command", SND_CMD, CM_PSH },
-#endif /* PUTPIPE */
- { "/delete", SND_DEL, 0 },
- { "/error-action", SND_ERR, CM_ARG },
- { "/except", SND_EXC, CM_ARG },
- { "/filenames", SND_NAM, CM_ARG },
-#ifdef PIPESEND
-#ifndef NOSPL
- { "/filter", SND_FLT, CM_ARG|CM_PSH },
-#endif /* NOSPL */
-#endif /* PIPESEND */
-#ifdef VMS
- { "/image", SND_IMG, 0 },
-#else
- { "/image", SND_BIN, CM_INV },
-#endif /* VMS */
- { "/larger-than", SND_LAR, CM_ARG },
- { "/listfile", SND_FIL, CM_ARG },
-#ifndef NOCSETS
- { "/local-character-set", SND_CSL, CM_ARG },
-#endif /* NOCSETS */
- { "/match", SND_PAT, CM_ARG },
- { "/ml", SND_MLS, CM_INV|CM_ABR },
- { "/mls", SND_MLS, CM_INV|CM_ABR },
- { "/mlsd", SND_MLS, 0 },
- { "/mlst", SND_MLS, CM_INV },
-#ifdef CK_TMPDIR
- { "/move-to", SND_MOV, CM_ARG },
-#endif /* CK_TMPDIR */
- { "/namelist", SND_NML, CM_ARG },
- { "/nlst", SND_NLS, 0 },
- { "/nobackupfiles", SND_NOB, 0 },
- { "/nodotfiles", SND_NOD, 0 },
-#ifdef DOUPDATE
- { "/dates-differ", SND_DIF, CM_INV },
-#endif /* DOUPDATE */
- { "/not-after", SND_NAF, CM_INV },
- { "/not-before", SND_NBE, CM_INV },
- { "/permissions", SND_PRM, CM_INV },
- { "/quiet", SND_SHH, 0 },
-#ifdef FTP_RESTART
- { "/recover", SND_RES, 0 },
-#endif /* FTP_RESTART */
-#ifdef RECURSIVE
- { "/recursive", SND_REC, 0 },
-#endif /* RECURSIVE */
- { "/rename-to", SND_REN, CM_ARG },
-#ifdef FTP_RESTART
- { "/restart", SND_RES, CM_INV },
-#endif /* FTP_RESTART */
-#ifndef NOCSETS
- { "/server-character-set", SND_CSR, CM_ARG },
-#endif /* NOCSETS */
- { "/server-rename-to", SND_SRN, CM_ARG },
- { "/smaller-than", SND_SMA, CM_ARG },
-#ifdef RECURSIVE
- { "/subdirectories", SND_REC, CM_INV },
-#endif /* RECURSIVE */
- { "/text", SND_TXT, 0 },
- { "/tenex", SND_TEN, 0 },
-#ifndef NOCSETS
- { "/transparent", SND_XPA, 0 },
-#endif /* NOCSETS */
- { "/to-screen", SND_MAI, 0 },
-#ifdef DOUPDATE
- { "/update", SND_UPD, CM_INV },
-#endif /* DOUPDATE */
- { "", 0, 0 }
-};
-static int ngetswi = (sizeof(getswi) / sizeof(struct keytab)) - 1;
-
-static struct keytab delswi[] = { /* FTP [M]DELETE switch table */
- { "/error-action", SND_ERR, CM_ARG },
- { "/except", SND_EXC, CM_ARG },
- { "/filenames", SND_NAM, CM_ARG },
- { "/larger-than", SND_LAR, CM_ARG },
- { "/nobackupfiles", SND_NOB, 0 },
-#ifdef UNIXOROSK
- { "/nodotfiles", SND_NOD, 0 },
-#endif /* UNIXOROSK */
- { "/quiet", SND_SHH, 0 },
-#ifdef RECURSIVE
- { "/recursive", SND_REC, 0 },
-#endif /* RECURSIVE */
- { "/smaller-than", SND_SMA, CM_ARG },
-#ifdef RECURSIVE
- { "/subdirectories", SND_REC, CM_INV },
-#endif /* RECURSIVE */
- { "", 0, 0 }
-};
-static int ndelswi = (sizeof(delswi) / sizeof(struct keytab)) - 1;
-
-static struct keytab fntab[] = { /* Filename conversion keyword table */
- { "automatic", 2, CNV_AUTO },
- { "converted", 1, CNV_CNV },
- { "literal", 0, CNV_LIT }
-};
-static int nfntab = (sizeof(fntab) / sizeof(struct keytab));
-
-static struct keytab ftptyp[] = { /* SET FTP TYPE table */
- { "ascii", FTT_ASC, 0 },
- { "binary", FTT_BIN, 0 },
- { "tenex", FTT_TEN, 0 },
- { "text", FTT_ASC, CM_INV },
- { "", 0, 0 }
-};
-static int nftptyp = (sizeof(ftptyp) / sizeof(struct keytab)) - 1;
-
-#ifdef FTP_SECURITY
-static struct keytab ftppro[] = { /* SET FTP PROTECTION-LEVEL table */
- { "clear", FPL_CLR, 0 },
- { "confidential", FPL_CON, 0 },
- { "private", FPL_PRV, 0 },
- { "safe", FPL_SAF, 0 },
- { "", 0, 0 }
-};
-static int nftppro = (sizeof(ftppro) / sizeof(struct keytab)) - 1;
-#endif /* FTP_SECURITY */
-
-/* Definitions for FTP from RFC765. */
-
-/* Reply codes */
-
-#define REPLY_PRELIM 1 /* Positive preliminary */
-#define REPLY_COMPLETE 2 /* Positive completion */
-#define REPLY_CONTINUE 3 /* Positive intermediate */
-#define REPLY_TRANSIENT 4 /* Transient negative completion */
-#define REPLY_ERROR 5 /* Permanent negative completion */
-#define REPLY_SECURE 6 /* Security encoded message */
-
-/* Form codes and names */
-
-#define FORM_N 1 /* Non-print */
-#define FORM_T 2 /* Telnet format effectors */
-#define FORM_C 3 /* Carriage control (ASA) */
-
-/* Structure codes and names */
-
-#define STRU_F 1 /* File (no record structure) */
-#define STRU_R 2 /* Record structure */
-#define STRU_P 3 /* Page structure */
-
-/* Mode types and names */
-
-#define MODE_S 1 /* Stream */
-#define MODE_B 2 /* Block */
-#define MODE_C 3 /* Compressed */
-
-/* Protection levels and names */
-
-#define PROT_C 1 /* Clear */
-#define PROT_S 2 /* Safe */
-#define PROT_P 3 /* Private */
-#define PROT_E 4 /* Confidential */
-
-#ifdef COMMENT /* Not used */
-#ifdef FTP_NAMES
-char *strunames[] = {"0", "File", "Record", "Page" };
-char *formnames[] = {"0", "Nonprint", "Telnet", "Carriage-control" };
-char *modenames[] = {"0", "Stream", "Block", "Compressed" };
-char *levelnames[] = {"0", "Clear", "Safe", "Private", "Confidential" };
-#endif /* FTP_NAMES */
-
-/* Record Tokens */
-
-#define REC_ESC '\377' /* Record-mode Escape */
-#define REC_EOR '\001' /* Record-mode End-of-Record */
-#define REC_EOF '\002' /* Record-mode End-of-File */
-
-/* Block Header */
-
-#define BLK_EOR 0x80 /* Block is End-of-Record */
-#define BLK_EOF 0x40 /* Block is End-of-File */
-#define BLK_REPLY_ERRORS 0x20 /* Block might have errors */
-#define BLK_RESTART 0x10 /* Block is Restart Marker */
-#define BLK_BYTECOUNT 2 /* Bytes in this block */
-#endif /* COMMENT */
-
-#define RADIX_ENCODE 0 /* radix_encode() function codes */
-#define RADIX_DECODE 1
-
-/*
- The default setpbsz() value in the Unix FTP client is 1<<20 (1MB). This
- results in a serious performance degradation due to the increased number
- of page faults and the inability to overlap encrypt/decrypt, file i/o, and
- network i/o. So instead we set the value to 1<<13 (8K), about half the size
- of the typical TCP window. Maybe we should add a command to allow the value
- to be changed.
-*/
-#define DEFAULT_PBSZ 1<<13
-
-/* Prototypes */
-
-_PROTOTYP(int remtxt, (char **) );
-_PROTOTYP(char * gskreason, (int) );
-_PROTOTYP(static int ftpclose,(void));
-_PROTOTYP(static int zzsend, (int, CHAR));
-_PROTOTYP(static int getreply,(int,int,int,int,int));
-_PROTOTYP(static int radix_encode,(CHAR[], CHAR[], int, int *, int));
-_PROTOTYP(static int setpbsz,(unsigned int));
-_PROTOTYP(static int recvrequest,(char *,char *,char *,char *,
- int,int,char *,int,int,int));
-_PROTOTYP(static int ftpcmd,(char *,char *,int,int,int));
-_PROTOTYP(static int fts_cpl,(int));
-_PROTOTYP(static int fts_dpl,(int));
-#ifdef FTP_SECURITY
-_PROTOTYP(static int ftp_auth, (void));
-#endif /* FTP_SECURITY */
-_PROTOTYP(static int ftp_user, (char *, char *, char *));
-_PROTOTYP(static int ftp_login, (char *));
-_PROTOTYP(static int ftp_reset, (void));
-_PROTOTYP(static int ftp_rename, (char *, char *));
-_PROTOTYP(static int ftp_umask, (char *));
-_PROTOTYP(static int secure_flush, (int));
-#ifdef COMMENT
-_PROTOTYP(static int secure_putc, (char, int));
-#endif /* COMMENT */
-_PROTOTYP(static int secure_write, (int, CHAR *, unsigned int));
-_PROTOTYP(static int scommand, (char *));
-_PROTOTYP(static int secure_putbuf, (int, CHAR *, unsigned int));
-_PROTOTYP(static int secure_getc, (int, int));
-_PROTOTYP(static int secure_getbyte, (int, int));
-_PROTOTYP(static int secure_read, (int, char *, int));
-_PROTOTYP(static int initconn, (void));
-_PROTOTYP(static int dataconn, (char *));
-_PROTOTYP(static int setprotbuf,(unsigned int));
-_PROTOTYP(static int sendrequest, (char *, char *, char *, int,int,int,int));
-
-_PROTOTYP(static char * radix_error,(int));
-_PROTOTYP(static char * ftp_hookup,(char *, int, int));
-_PROTOTYP(static CHAR * remote_files, (int, CHAR *, CHAR *, int));
-
-_PROTOTYP(static VOID mlsreset, (void));
-_PROTOTYP(static VOID secure_error, (char *fmt, ...));
-_PROTOTYP(static VOID lostpeer, (void));
-_PROTOTYP(static VOID cancel_remote, (int));
-_PROTOTYP(static VOID changetype, (int, int));
-
-_PROTOTYP(static sigtype cmdcancel, (int));
-
-#ifdef FTP_SRP
-_PROTOTYP(static int srp_reset, ());
-_PROTOTYP(static int srp_ftp_auth, (char *,char *,char *));
-_PROTOTYP(static int srp_put, (CHAR *, CHAR **, int, int *));
-_PROTOTYP(static int srp_get, (CHAR **, CHAR **, int *, int *));
-_PROTOTYP(static int srp_encode, (int, CHAR *, CHAR *, unsigned int));
-_PROTOTYP(static int srp_decode, (int, CHAR *, CHAR *, unsigned int));
-_PROTOTYP(static int srp_selcipher, (char *));
-_PROTOTYP(static int srp_selhash, (char *));
-#endif /* FTP_SRP */
-
-#ifdef FTP_GSSAPI
-_PROTOTYP(static void user_gss_error,(OM_uint32, OM_uint32,char *));
-#endif /* FTP_GSSAPI */
-
-/* D O F T P A R G -- Do an FTP command-line argument. */
-
-#ifdef FTP_SECURITY
-#ifndef NOICP
-#define FT_NOGSS 1
-#define FT_NOK4 2
-#define FT_NOSRP 3
-#define FT_NOSSL 4
-#define FT_NOTLS 5
-#define FT_CERTFI 6
-#define FT_OKCERT 7
-#define FT_DEBUG 8
-#define FT_KEY 9
-#define FT_SECURE 10
-#define FT_VERIFY 11
-
-static struct keytab ftpztab[] = {
- { "!gss", FT_NOGSS, 0 },
- { "!krb4", FT_NOK4, 0 },
- { "!srp", FT_NOSRP, 0 },
- { "!ssl", FT_NOSSL, 0 },
- { "!tls", FT_NOTLS, 0 },
- { "cert", FT_CERTFI, CM_ARG },
- { "certsok", FT_OKCERT, 0 },
- { "debug", FT_DEBUG, 0 },
- { "key", FT_KEY, CM_ARG },
- { "nogss", FT_NOGSS, 0 },
- { "nokrb4", FT_NOK4, 0 },
- { "nosrp", FT_NOSRP, 0 },
- { "nossl", FT_NOSSL, 0 },
- { "notls", FT_NOTLS, 0 },
-#ifdef COMMENT
- { "secure", FT_SECURE, 0 },
-#endif /* COMMENT */
- { "verify", FT_VERIFY, CM_ARG },
- { "", 0, 0 }
-};
-static int nftpztab = sizeof(ftpztab) / sizeof(struct keytab) - 1;
-
-/*
- The following cipher and hash tables should be replaced with
- dynamicly created versions based upon the linked library.
-*/
-#define SRP_BLOWFISH_ECB 1
-#define SRP_BLOWFISH_CBC 2
-#define SRP_BLOWFISH_CFB64 3
-#define SRP_BLOWFISH_OFB64 4
-#define SRP_CAST5_ECB 5
-#define SRP_CAST5_CBC 6
-#define SRP_CAST5_CFB64 7
-#define SRP_CAST5_OFB64 8
-#define SRP_DES_ECB 9
-#define SRP_DES_CBC 10
-#define SRP_DES_CFB64 11
-#define SRP_DES_OFB64 12
-#define SRP_DES3_ECB 13
-#define SRP_DES3_CBC 14
-#define SRP_DES3_CFB64 15
-#define SRP_DES3_OFB64 16
-
-static struct keytab ciphertab[] = {
- { "blowfish_ecb", SRP_BLOWFISH_ECB, 0 },
- { "blowfish_cbc", SRP_BLOWFISH_CBC, 0 },
- { "blowfish_cfb64", SRP_BLOWFISH_CFB64, 0 },
- { "blowfish_ofb64", SRP_BLOWFISH_OFB64, 0 },
- { "cast5_ecb", SRP_CAST5_ECB, 0 },
- { "cast5_cbc", SRP_CAST5_CBC, 0 },
- { "cast5_cfb64", SRP_CAST5_CFB64, 0 },
- { "cast5_ofb64", SRP_CAST5_OFB64, 0 },
- { "des_ecb", SRP_DES_ECB, 0 },
- { "des_cbc", SRP_DES_CBC, 0 },
- { "des_cfb64", SRP_DES_CFB64, 0 },
- { "des_ofb64", SRP_DES_OFB64, 0 },
- { "des3_ecb", SRP_DES3_ECB, 0 },
- { "des3_cbc", SRP_DES3_CBC, 0 },
- { "des3_cfb64", SRP_DES3_CFB64, 0 },
- { "des3_ofb64", SRP_DES3_OFB64, 0 },
- { "none", 0, 0 },
- { "", 0, 0 }
-};
-static int nciphertab = sizeof(ciphertab) / sizeof(struct keytab) - 1;
-
-#define SRP_MD5 1
-#define SRP_SHA 2
-static struct keytab hashtab[] = {
- { "md5", SRP_MD5, 0 },
- { "none", 0, 0 },
- { "sha", SRP_SHA, 0 },
- { "", 0, 0 }
-};
-static int nhashtab = sizeof(hashtab) / sizeof(struct keytab) - 1;
-#endif /* NOICP */
-#endif /* FTP_SECURITY */
-
-static char *
-strval(s1,s2) char * s1, * s2; {
- if (!s1) s1 = "";
- if (!s2) s2 = "";
- return(*s1 ? s1 : (*s2 ? s2 : "(none)"));
-}
-
-#ifndef NOCSETS
-static char * rfnptr = NULL;
-static int rfnlen = 0;
-static char rfnbuf[RFNBUFSIZ]; /* Remote filename translate buffer */
-static char * xgnbp = NULL;
-
-static int
-strgetc() { /* Helper function for xgnbyte() */
- int c;
- if (!xgnbp)
- return(-1);
- if (!*xgnbp)
- return(-1);
- c = (unsigned) *xgnbp++;
- return(((unsigned) c) & 0xff);
-}
-
-static int /* Helper function for xpnbyte() */
-#ifdef CK_ANSIC
-strputc(char c)
-#else
-strputc(c) char c;
-#endif /* CK_ANSIC */
-{
- rfnlen = rfnptr - rfnbuf;
- if (rfnlen >= (RFNBUFSIZ - 1))
- return(-1);
- *rfnptr++ = c;
- *rfnptr = NUL;
- return(0);
-}
-
-static int
-#ifdef CK_ANSIC
-xprintc(char c)
-#else
-xprintc(c) char c;
-#endif /* CK_ANSIC */
-{
- printf("%c",c);
- return(0);
-}
-
-static VOID
-bytswap(c0,c1) int * c0, * c1; {
- int t;
- t = *c0;
- *c0 = *c1;
- *c1 = t;
-}
-#endif /* NOCSETS */
-
-#ifdef CKLOGDIAL
-char ftplogbuf[CXLOGBUFL] = { NUL, NUL }; /* Connection Log */
-int ftplogactive = 0;
-long ftplogprev = 0L;
-
-VOID
-ftplogend() {
- extern int dialog;
- extern char diafil[];
- long d1, d2, t1, t2;
- char buf[32], * p;
-
- debug(F111,"ftp cx log active",ckitoa(dialog),ftplogactive);
- debug(F110,"ftp cx log buf",ftplogbuf,0);
-
- if (!ftplogactive || !ftplogbuf[0]) /* No active record */
- return;
-
- ftplogactive = 0; /* Record is not active */
-
- d1 = mjd((char *)ftplogbuf); /* Get start date of this session */
- ckstrncpy(buf,ckdate(),31); /* Get current date */
- d2 = mjd(buf); /* Convert them to mjds */
- p = ftplogbuf; /* Get start time */
- p[11] = NUL;
- p[14] = NUL; /* Convert to seconds */
- t1 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
- p[11] = ':';
- p[14] = ':';
- p = buf; /* Get end time */
- p[11] = NUL;
- p[14] = NUL;
- t2 = atol(p+9) * 3600L + atol(p+12) * 60L + atol(p+15);
- t2 = ((d2 - d1) * 86400L) + (t2 - t1); /* Compute elapsed time */
- if (t2 > -1L) {
- ftplogprev = t2;
- p = hhmmss(t2);
- strncat(ftplogbuf,"E=",CXLOGBUFL); /* Append to log record */
- strncat(ftplogbuf,p,CXLOGBUFL);
- } else
- ftplogprev = 0L;
- debug(F101,"ftp cx log dialog","",dialog);
- if (dialog) { /* If logging */
- int x;
- x = diaopn(diafil,1,1); /* Open log in append mode */
- if (x > 0) {
- debug(F101,"ftp cx log open","",x);
- x = zsoutl(ZDIFIL,ftplogbuf); /* Write the record */
- debug(F101,"ftp cx log write","",x);
- x = zclose(ZDIFIL); /* Close the log */
- debug(F101,"ftp cx log close","",x);
- }
- }
-}
-
-VOID
-dologftp() {
- ftplogend(); /* Previous session not closed out? */
- ftplogprev = 0L;
- ftplogactive = 1; /* Record is active */
-
- ckmakxmsg(ftplogbuf,CXLOGBUFL,
- ckdate()," ",strval(ftp_logname,NULL)," ",ckgetpid(),
- " T=FTP N=", strval(ftp_host,NULL)," H=",myhost," ",NULL,NULL);
- debug(F110,"ftp cx log begin",ftplogbuf,0);
-}
-#endif /* CKLOGDIAL */
-
-static char * dummy[2] = { NULL, NULL };
-
-static struct keytab modetab[] = {
- { "active", 0, 0 },
- { "passive", 1, 0 }
-};
-
-#ifndef NOCMDL
-int /* Called from ckuusy.c */
-#ifdef CK_ANSIC
-doftparg(char c)
-#else
-doftparg(c) char c;
-#endif /* CK_ANSIC */
-/* doftparg */ {
- int x, z;
- char *xp;
- extern char **xargv, *xarg0;
- extern int xargc, stayflg, haveftpuid;
- extern char uidbuf[];
-
- xp = *xargv+1; /* Pointer for bundled args */
- while (c) {
- if (ckstrchr("MuDPkcHzm",c)) { /* Options that take arguments */
- if (*(xp+1)) {
- fatal("?Invalid argument bundling");
- }
- xargv++, xargc--;
- if ((xargc < 1) || (**xargv == '-')) {
- fatal("?Required argument missing");
- }
- }
- switch (c) { /* Big switch on arg */
- case 'h': /* help */
- printf("C-Kermit's FTP client command-line personality. Usage:\n");
- printf(" %s [ options ] host [ port ] [-pg files ]\n\n",xarg0);
- printf("Options:\n");
- printf(" -h = help (this message)\n");
- printf(" -m mode = \"passive\" (default) or \"active\"\n");
- printf(" -u name = username for autologin (or -M)\n");
- printf(" -P password = password for autologin (RISKY)\n");
- printf(" -A = autologin anonymously\n");
- printf(" -D directory = cd after autologin\n");
- printf(" -b = force binary mode\n");
- printf(" -a = force text (\"ascii\") mode (or -T)\n");
- printf(" -d = debug (double to add timestamps)\n");
- printf(" -n = no autologin\n");
- printf(" -v = verbose (default)\n");
- printf(" -q = quiet\n");
- printf(" -S = Stay (issue command prompt when done)\n");
- printf(" -Y = do not execute Kermit init file\n");
- printf(" -p files = files to put after autologin (or -s)\n");
- printf(" -g files = files to get after autologin\n");
- printf(" -R = recursive (for use with -p)\n");
-
-#ifdef FTP_SECURITY
- printf("\nSecurity options:\n");
- printf(" -k realm = Kerberos 4 realm\n");
- printf(" -f = Kerboros 5 credentials forwarding\n");
- printf(" -x = autoencryption mode\n");
- printf(" -c cipher = SRP cipher type\n");
- printf(" -H hash = SRP encryption hash\n");
- printf(" -z option = Security options\n");
-#endif /* FTP_SECURITY */
-
- printf("\n-p or -g, if given, should be last. Example:\n");
- printf(" ftp -A kermit.columbia.edu -D kermit -ag TESTFILE\n");
-
- doexit(GOOD_EXIT,-1);
- break;
-
- case 'R': /* Recursive */
- recursive = 1;
- break;
-
- case 'd': /* Debug */
-#ifdef DEBUG
- if (deblog) {
- extern int debtim;
- debtim = 1;
- } else {
- deblog = debopn("debug.log",0);
- debok = 1;
- }
-#endif /* DEBUG */
- /* fall thru on purpose */
-
- case 't': /* Trace */
- ftp_deb++;
- break;
-
- case 'n': /* No autologin */
- ftp_log = 0;
- break;
-
- case 'i': /* No prompt */
- case 'v': /* Verbose */
- break; /* (ignored) */
-
- case 'q': /* Quiet */
- quiet = 1;
- break;
-
- case 'S': /* Stay */
- stayflg = 1;
- break;
-
- case 'M':
- case 'u': /* My User Name */
- if ((int)strlen(*xargv) > 63) {
- fatal("username too long");
- }
- ckstrncpy(uidbuf,*xargv,UIDBUFLEN);
- haveftpuid = 1;
- break;
-
- case 'A':
- ckstrncpy(uidbuf,"anonymous",UIDBUFLEN);
- haveftpuid = 1;
- break;
-
- case 'T': /* Text */
- case 'a': /* "ascii" */
- case 'b': /* Binary */
- binary = (c == 'b') ? FTT_BIN : FTT_ASC;
- xfermode = XMODE_M;
- filepeek = 0;
- patterns = 0;
- break;
-
- case 'g': /* Get */
- case 'p': /* Put */
- case 's': { /* Send (= Put) */
- int havefiles, rc;
- if (ftp_action) {
- fatal("Only one FTP action at a time please");
- }
- if (*(xp+1)) {
- fatal("invalid argument bundling after -s");
- }
- nfils = 0; /* Initialize file counter */
- havefiles = 0; /* Assume nothing to send */
- cmlist = xargv + 1; /* Remember this pointer */
-
- while (++xargv, --xargc > 0) { /* Traverse the list */
- if (c == 'g') {
- havefiles++;
- nfils++;
- continue;
- }
-#ifdef RECURSIVE
- if (!strcmp(*xargv,".")) {
- havefiles = 1;
- nfils++;
- recursive = 1;
- } else
-#endif /* RECURSIVE */
- if ((rc = zchki(*xargv)) > -1 || (rc == -2)) {
- if (rc != -2)
- havefiles = 1;
- nfils++;
- } else if (iswild(*xargv) && nzxpand(*xargv,0) > 0) {
- havefiles = 1;
- nfils++;
- }
- }
- xargc++, xargv--; /* Adjust argv/argc */
- if (!havefiles) {
- if (c == 'g') {
- fatal("No files to put");
- } else {
- fatal("No files to get");
- }
- }
- ftp_action = c;
- break;
- }
- case 'D': /* Directory */
- makestr(&ftp_rdir,*xargv);
- break;
-
- case 'm': /* Mode (Active/Passive */
- ftp_psv = lookup(modetab,*xargv,2,NULL);
- if (ftp_psv < 0) fatal("Invalid mode");
- break;
-
- case 'P':
- makestr(&ftp_tmp,*xargv); /* You-Know-What */
- break;
-
- case 'Y': /* No initialization file */
- break; /* (already done in prescan) */
-
-#ifdef CK_URL
- case 'U': { /* URL */
- /* These are set by urlparse() - any not set are NULL */
- if (g_url.hos) {
-/*
- Kermit has accepted host:port notation since many years before URLs were
- invented. Unfortunately, URLs conflict with this notation. Thus "ftp
- host:449" looks like a URL and results in service = host and host = 449.
- Here we try to catch this situation transparently to the user.
-*/
- if (ckstrcmp(g_url.svc,"ftp",-1,0)
-#ifdef CK_SSL
- && ckstrcmp(g_url.svc,"ftps",-1,0)
-#endif /* CK_SSL */
- ) {
- if (!g_url.usr &&
- !g_url.psw &&
- !g_url.por &&
- !g_url.pth) {
- g_url.por = g_url.hos;
- g_url.hos = g_url.svc;
- g_url.svc = "ftp";
- } else {
- ckmakmsg(tmpbuf,TMPBUFSIZ,"Non-FTP URL: service=",
- g_url.svc," host=",g_url.hos);
- fatal(tmpbuf);
- }
- }
- makestr(&ftp_host,g_url.hos);
- if (g_url.usr) {
- haveftpuid = 1;
- ckstrncpy(uidbuf,g_url.usr,UIDBUFLEN);
- makestr(&ftp_logname,uidbuf);
- }
- if (g_url.psw) {
- makestr(&ftp_tmp,g_url.psw);
- }
- if (g_url.pth) {
- if (!g_url.usr) {
- haveftpuid = 1;
- ckstrncpy(uidbuf,"anonymous",UIDBUFLEN);
- makestr(&ftp_logname,uidbuf);
- }
- if (ftp_action) {
- fatal("Only one FTP action at a time please");
- }
- if (!stayflg)
- quiet = 1;
- nfils = 1;
- dummy[0] = g_url.pth;
- cmlist = dummy;
- ftp_action = 'g';
- }
- xp = NULL;
- haveurl = 1;
- }
- break;
- }
-#endif /* CK_URL */
-
-#ifdef FTP_SECURITY
- case 'k': { /* K4 Realm */
-#ifdef FTP_KRB4
- ckstrncpy(ftp_realm,*xargv, REALM_SZ);
-#endif /* FTP_KRB4 */
- if (ftp_deb) printf("K4 Realm = [%s]\n",*xargv);
- break;
- }
- case 'f': {
-#ifdef FTP_GSSAPI
- ftp_cfw = 1;
- if (ftp_deb) printf("K5 Credentials Forwarding\n");
-#else /* FTP_GSSAPI */
- printf("K5 Credentials Forwarding not supported\n");
-#endif /* FTP_GSSAPI */
- break;
- }
- case 'x': {
- ftp_cry = 1;
- if (ftp_deb) printf("Autoencryption\n");
- break;
- }
- case 'c': { /* Cipher */
-#ifdef FTP_SRP
- if (!srp_selcipher(*xargv)) {
- if (ftp_deb) printf("SRP cipher type: \"%s\"\n",*xargv);
- } else
- printf("?Invalid SRP cipher type: \"%s\"\n",*xargv);
-#else /* FTP_SRP */
- printf("?SRP not supported\n");
-#endif /* FTP_SRP */
- break;
- }
- case 'H': {
-#ifdef FTP_SRP
- if (!srp_selhash(*xargv)) {
- if (ftp_deb) printf("SRP hash type: \"%s\"\n",*xargv);
- } else
- printf("?Invalid SRP hash type: \"%s\"\n",*xargv);
-#else /* FTP_SRP */
- printf("?SRP not supported\n");
-#endif /* FTP_SRP */
- break;
- }
- case 'z': {
- /* *xargv contains a value of the form tag=value */
- /* we need to lookup the tag and save the value */
- char * p = NULL, * q = NULL;
- makestr(&p,*xargv);
- y = ckindex("=",p,0,0,1);
- if (y > 0)
- p[y-1] = '\0';
- x = lookup(ftpztab,p,nftpztab,&z);
- if (x < 0) {
- printf("?Invalid security option: \"%s\"\n",p);
- } else {
- if (ftp_deb)
- printf("Security option: \"%s",p);
- if (ftpztab[z].flgs & CM_ARG) {
- if (y <= 0)
- fatal("?Missing required value");
- q = &p[y];
- if (!*q)
- fatal("?Missing required value");
- if (ftp_deb)
- printf("=%s\"",q);
- }
- switch (ftpztab[z].kwval) { /* -z options w/args */
- case FT_NOGSS:
-#ifdef FTP_GSSAPI
- for (z = 0; z < FTPATYPS && ftp_auth_type[z]; z++) {
- if (ftp_auth_type[z] == FTA_GK5) {
- for (y = z;
- y < (FTPATYPS-1) && ftp_auth_type[y];
- y++
- )
- ftp_auth_type[y] = ftp_auth_type[y+1];
- ftp_auth_type[FTPATYPS-1] = 0;
- break;
- }
- }
-#endif /* FTP_GSSAPI */
- break;
- case FT_NOK4:
-#ifdef FTP_KRB4
- for (z = 0; z < FTPATYPS && ftp_auth_type[z]; z++) {
- if (ftp_auth_type[z] == FTA_K4) {
- for (y = z;
- y < (FTPATYPS-1) && ftp_auth_type[y];
- y++
- )
- ftp_auth_type[y] = ftp_auth_type[y+1];
- ftp_auth_type[FTPATYPS-1] = 0;
- break;
- }
- }
-#endif /* FTP_KRB4 */
- break;
- case FT_NOSRP:
-#ifdef FTP_SRP
- for (z = 0; z < FTPATYPS && ftp_auth_type[z]; z++) {
- if (ftp_auth_type[z] == FTA_SRP) {
- for (y = z;
- y < (FTPATYPS-1) && ftp_auth_type[y];
- y++
- )
- ftp_auth_type[y] = ftp_auth_type[y+1];
- ftp_auth_type[FTPATYPS-1] = 0;
- break;
- }
- }
-#endif /* FTP_SRP */
- break;
- case FT_NOSSL:
-#ifdef CK_SSL
- for (z = 0; z < FTPATYPS && ftp_auth_type[z]; z++) {
- if (ftp_auth_type[z] == FTA_SSL) {
- for (y = z;
- y < (FTPATYPS-1) && ftp_auth_type[y];
- y++
- )
- ftp_auth_type[y] = ftp_auth_type[y+1];
- ftp_auth_type[FTPATYPS-1] = 0;
- break;
- }
- }
-#endif /* CK_SSL */
- break;
- case FT_NOTLS:
-#ifdef CK_SSL
- for (z = 0; z < FTPATYPS && ftp_auth_type[z]; z++) {
- if (ftp_auth_type[z] == FTA_TLS) {
- for (y = z;
- y < (FTPATYPS-1) && ftp_auth_type[y];
- y++
- )
- ftp_auth_type[y] = ftp_auth_type[y+1];
- ftp_auth_type[FTPATYPS-1] = 0;
- break;
- }
- }
-#endif /* CK_SSL */
- break;
- case FT_CERTFI:
-#ifdef CK_SSL
- makestr(&ssl_rsa_cert_file,q);
-#endif /* CK_SSL */
- break;
- case FT_OKCERT:
-#ifdef CK_SSL
- ssl_certsok_flag = 1;
-#endif /* CK_SSL */
- break;
- case FT_DEBUG:
-#ifdef DEBUG
- if (deblog) {
- extern int debtim;
- debtim = 1;
- } else {
- deblog = debopn("debug.log",0);
- }
-#endif /* DEBUG */
- break;
- case FT_KEY:
-#ifdef CK_SSL
- makestr(&ssl_rsa_key_file,q);
-#endif /* CK_SSL */
- break;
- case FT_SECURE:
- /* no equivalent */
- break;
- case FT_VERIFY:
-#ifdef CK_SSL
- if (!rdigits(q))
- printf("?Bad number: %s\n",q);
- ssl_verify_flag = atoi(q);
-#endif /* CK_SSL */
- break;
- }
- }
- if (ftp_deb) printf("\"\n");
- free(p);
- break;
- }
-#endif /* FTP_SECURITY */
-
- default:
- fatal2(*xargv,
- "unknown command-line option, type \"ftp -h\" for help"
- );
- }
- if (!xp) break;
- c = *++xp; /* See if options are bundled */
- }
- return(0);
-}
-#endif /* NOCMDL */
-
-int
-ftpisconnected() {
- return(connected);
-}
-
-int
-ftpisloggedin() {
- return(connected ? loggedin : 0);
-}
-
-int
-ftpissecure() {
- return((ftp_dpl == FPL_CLR && !ssl_ftp_proxy) ? 0 : 1);
-}
-
-static VOID
-ftscreen(n, c, z, s) int n; char c; long z; char * s; {
- if (displa && fdispla && !backgrd && !quiet && !out2screen) {
- if (!dpyactive) {
- ckscreen(SCR_PT,'S',0L,"");
- dpyactive = 1;
- }
- ckscreen(n,c,z,s);
- }
-}
-
-#ifndef OS2
-/* g m s t i m e r -- Millisecond timer */
-
-long
-gmstimer() {
-#ifdef HAVE_MSECS
- /* For those versions of ztime() that also set global ztmsec. */
- char *p = NULL;
- long z;
- ztime(&p);
- if (!p) return(0L);
- if (!*p) return(0L);
- z = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
- return(z * 1000 + ztmsec);
-#else
- return((long)time(NULL) * 1000L);
-#endif /* HAVE_MSECS */
-}
-#endif /* OS2 */
-
-/* d o s e t f t p -- The SET FTP command */
-
-int
-dosetftp() {
- int cx;
- if ((cx = cmkey(ftpset,nftpset,"","",xxstring)) < 0) /* Set what? */
- return(cx);
- switch (cx) {
-
- case FTS_FNC: /* Filename collision action */
- if ((x = cmkey(ftpcolxtab,nftpcolx,"","",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- ftp_fnc = x;
- return(1);
-
- case FTS_CNV: /* Filename conversion */
- if ((x = cmkey(fntab,nfntab,"","automatic",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- ftp_cnv = x;
- return(1);
-
- case FTS_DBG: /* Debug messages */
- return(seton(&ftp_deb));
-
- case FTS_LOG: /* Auto-login */
- return(seton(&ftp_log));
-
- case FTS_PSV: /* Passive mode */
- return(dosetftppsv());
-
- case FTS_SPC: /* Send port commands */
- x = seton(&ftp_spc);
- if (x > 0) sendport = ftp_spc;
- return(x);
-
- case FTS_TYP: /* Type */
- if ((x = cmkey(ftptyp,nftptyp,"","",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
- ftp_typ = x;
- g_ftp_typ = x;
- tenex = (ftp_typ == FTT_TEN);
- return(1);
-
- case FTS_USN: /* Unique server names */
- return(seton(&ftp_usn));
-
- case FTS_VBM: /* Verbose mode */
- if ((x = seton(&ftp_vbm)) < 0) /* Per-command copy */
- return(x);
- ftp_vbx = ftp_vbm; /* Global sticky copy */
- return(x);
-
- case FTS_TST: /* "if (testing)" messages */
- return(seton(&testing));
-
- case FTS_PRM: /* Send permissions */
- return(setonaut(&ftp_prm));
-
- case FTS_AUT: /* Auto-authentication */
- return(seton(&ftp_aut));
-
- case FTS_ERR: /* Error action */
- if ((x = cmkey(qorp,2,"","",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- ftp_err = x;
- return(success = 1);
-
-#ifndef NOCSETS
- case FTS_XLA: /* Translation */
- return(seton(&ftp_xla));
-
- case FTS_CSR: /* Server charset */
- if ((x = cmkey(fcstab,nfilc,"character-set","utf8",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- ftp_csr = x;
- ftp_xla = 1; /* Also enable translation */
- return(success = 1);
-#endif /* NOCSETS */
-
- case FTS_GFT:
- return(seton(&get_auto)); /* GET-filetype-switching */
-
- case FTS_DAT:
- return(seton(&ftp_dates)); /* Set file dates */
-
- case FTS_STO: { /* Server time offset */
- char * s, * p = NULL;
- int k;
- if ((x = cmfld("[+-]hh[:mm[:ss]]","+0",&s,xxstring)) < 0)
- return(x);
- if (!strcmp(s,"+0")) {
- s = NULL;
- } else if ((x = delta2sec(s,&k)) < 0) { /* Check format */
- printf("?Invalid time offset\n");
- return(-9);
- }
- makestr(&p,s); /* Make a safe copy the string */
- if ((x = cmcfm()) < 0) { /* Get confirmation */
- if (p)
- makestr(&p,NULL);
- return(x);
- }
- fts_sto = p; /* Confirmed - set the string. */
- return(success = 1);
- }
- case FTS_APW: {
- char * s;
- if ((x = cmtxt("Text", "", &s, xxstring)) < 0)
- return(x);
- makestr(&ftp_apw, *s ? s : NULL);
- return(success = 1);
- }
-
- case FTS_BUG: {
- if ((x = cmkey(ftpbugtab,nftpbug,"","",xxstring)) < 0)
- return(x);
- switch (x) {
-#ifdef CK_SSL
- case FTB_SV2:
- return seton(&ftp_bug_use_ssl_v2);
-#endif /* CK_SSL */
- default:
- return(-2);
- }
- }
-
-#ifdef FTP_SECURITY
- case FTS_CRY: /* Auto-encryption */
- return(seton(&ftp_cry));
-
- case FTS_CFW: /* Credential-forwarding */
- return(seton(&ftp_cfw));
-
- case FTS_CPL: /* Command protection level */
- if ((x = cmkey(ftppro,nftppro,"","",xxstring)) < 0) return(x);
- if ((y = cmcfm()) < 0) return(y);
- success = fts_cpl(x);
- return(success);
-
- case FTS_DPL: /* Data protection level */
- if ((x = cmkey(ftppro,nftppro,"","",xxstring)) < 0) return(x);
- if ((y = cmcfm()) < 0) return(y);
- success = fts_dpl(x);
- return(success);
-
- case FTS_ATP: { /* FTP Auth Type */
- int i, j, atypes[8];
-
- for (i = 0; i < 8; i++) {
- if ((y = cmkey(ftpauth,nftpauth,"",
- (i == 0) ? "automatic" : "",
- xxstring)) < 0) {
- if (y == -3)
- break;
- return(y);
- }
- if (i > 0 && (y == FTA_AUTO)) {
- printf("?Choice may only be used in first position.\r\n");
- return(-9);
- }
- for (j = 0; j < i; j++) {
- if (atypes[j] == y) {
- printf("\r\n?Choice has already been used.\r\n");
- return(-9);
- }
- }
- atypes[i] = y;
- if (y == FTA_AUTO) {
- i++;
- break;
- }
- }
- if (i < 8)
- atypes[i] = 0;
- if ((z = cmcfm()) < 0)
- return(z);
- if (atypes[0] == FTA_AUTO) {
- i = 0;
-#ifdef FTP_GSSAPI
- ftp_auth_type[i++] = FTA_GK5;
-#endif /* FTP_GSSAPI */
-#ifdef FTP_SRP
- ftp_auth_type[i++] = FTA_SRP;
-#endif /* FTP_SRP */
-#ifdef FTP_KRB4
- ftp_auth_type[i++] = FTA_K4;
-#endif /* FTP_KRB4 */
-#ifdef CK_SSL
- ftp_auth_type[i++] = FTA_TLS;
- ftp_auth_type[i++] = FTA_SSL;
-#endif /* CK_SSL */
- ftp_auth_type[i] = 0;
- } else {
- for (i = 0; i < 8; i++)
- ftp_auth_type[i] = atypes[i];
- }
- return(success = 1);
- }
-
- case FTS_SRP:
-#ifdef FTP_SRP
- if ((x = cmkey(ftpsrp,nftpsrp,"","",xxstring)) < 0)
- return(x);
- switch (x) {
- case SRP_CIPHER:
- if ((x = cmkey(ciphertab,nciphertab,"","",xxstring)) < 0)
- return(x);
- if ((z = cmcfm()) < 0)
- return(z);
- success = !srp_selcipher(ciphertab[x].kwd);
- return(success);
- case SRP_HASH:
- if ((x = cmkey(hashtab,nhashtab,"","",xxstring)) < 0)
- return(x);
- if ((z = cmcfm()) < 0)
- return(z);
- success = !srp_selhash(hashtab[x].kwd);
- return(success = 1);
- default:
- if ((z = cmcfm()) < 0)
- return(z);
- return(-2);
- }
-#else /* FTP_SRP */
- if ((z = cmcfm()) < 0)
- return(z);
- return(-2);
-#endif /* FTP_SRP */
-#endif /* FTP_SECURITY */
-
- case FTS_DIS:
- doxdis(2); /* 2 == ftp */
- return(success = 1);
-
- default:
- return(-2);
- }
-}
-
-int
-ftpbye() {
- int x;
- if (!connected)
- return(1);
- if (testing)
- printf(" ftp closing %s...\n",ftp_host);
- x = ftpclose();
- return((x > -1) ? 1 : 0);
-}
-
-/* o p e n f t p -- Parse FTP hostname & port and open */
-
-static int
-openftp(s,opn_tls) char * s; int opn_tls; {
- char c, * p, * hostname = NULL, *hostsave = NULL, * service = NULL;
- int i, n, havehost = 0, getval = 0, rc = -9, opn_psv = -1, nologin = 0;
- int haveuser = 0;
- struct FDB sw, fl, cm;
- extern int nnetdir; /* Network services directory */
- extern int nhcount; /* Lookup result */
- extern char *nh_p[]; /* Network directory entry pointers */
- extern char *nh_p2[]; /* Network directory entry nettype */
-
- if (!s) return(-2);
- if (!*s) return(-2);
-
- makestr(&hostname,s);
- hostsave = hostname;
- makestr(&ftp_logname,NULL);
- anonymous = 0;
- noinit = 0;
-
- debug(F110,"ftp open",hostname,0);
-
- if (sav_psv > -1) { /* Restore prevailing active/passive */
- ftp_psv = sav_psv; /* selection in case it was */
- sav_psv = -1; /* temporarily overriden by a switch */
- }
- if (sav_log > -1) { /* Ditto for autologin */
- ftp_log = sav_log;
- sav_log = -1;
- }
- cmfdbi(&sw, /* Switches */
- _CMKEY,
- "Service name or port;\n or switch",
- "", /* default */
- "", /* addtl string data */
- nftpswi, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: none */
- xxstring, /* Processing function */
- ftpswitab, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* A host name or address */
- _CMFLD, /* fcode */
- "", /* help */
- "xYzBoo", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- &cm
- );
- cmfdbi(&cm, /* Command confirmation */
- _CMCFM,
- "",
- "",
- "",
- 0,
- 0,
- NULL,
- NULL,
- NULL
- );
-
- for (n = 0;; n++) {
- rc = cmfdb(&sw); /* Parse a service name or a switch */
- if (rc < 0)
- goto xopenftp;
-
- if (cmresult.fcode == _CMCFM) { /* Done? */
- break;
- } else if (cmresult.fcode == _CMFLD) { /* Port */
- if (ckstrcmp("xYzBoo",cmresult.sresult,-1,1))
- makestr(&service,cmresult.sresult);
- else
- makestr(&service,opn_tls?"ftps":"ftp");
- } else if (cmresult.fcode == _CMKEY) { /* Have a switch */
- c = cmgbrk(); /* get break character */
- getval = (c == ':' || c == '=');
- rc = -9;
- if (getval && !(cmresult.kflags & CM_ARG)) {
- printf("?This switch does not take arguments\n");
- goto xopenftp;
- }
- if (!getval && (cmresult.kflags & CM_ARG)) {
- printf("?This switch requires an argument\n");
- goto xopenftp;
- }
- switch (cmresult.nresult) { /* Switch */
- case OPN_ANO: /* /ANONYMOUS */
- anonymous++;
- nologin = 0;
- break;
- case OPN_NIN: /* /NOINIT */
- noinit++;
- break;
- case OPN_NOL: /* /NOLOGIN */
- nologin++;
- anonymous = 0;
- makestr(&ftp_logname,NULL);
- break;
- case OPN_PSW: /* /PASSWORD */
- if (!anonymous) /* Don't log real passwords */
- debok = 0;
- rc = cmfld("Password for FTP server","",&p,xxstring);
- if (rc == -3) {
- makestr(&ftp_tmp,NULL);
- } else if (rc < 0) {
- goto xopenftp;
- } else {
- makestr(&ftp_tmp,brstrip(p));
- nologin = 0;
- }
- break;
- case OPN_USR: /* /USER */
- rc = cmfld("Username for FTP server","",&p,xxstring);
- if (rc == -3) {
- makestr(&ftp_logname,NULL);
- } else if (rc < 0) {
- goto xopenftp;
- } else {
- nologin = 0;
- anonymous = 0;
- haveuser = 1;
- makestr(&ftp_logname,brstrip(p));
- }
- break;
- case OPN_ACC:
- rc = cmfld("Account for FTP server","",&p,xxstring);
- if (rc == -3) {
- makestr(&ftp_acc,NULL);
- } else if (rc < 0) {
- goto xopenftp;
- } else {
- makestr(&ftp_acc,brstrip(p));
- }
- break;
- case OPN_ACT:
- opn_psv = 0;
- break;
- case OPN_PSV:
- opn_psv = 1;
- break;
- case OPN_TLS:
- opn_tls = 1;
- break;
- default:
- break;
- }
- }
- if (n == 0) { /* After first time through */
- cmfdbi(&sw, /* accept only switches */
- _CMKEY,
- "\nCarriage return to confirm to command, or switch",
- "",
- "",
- nftpswi,
- 4,
- xxstring,
- ftpswitab,
- &cm
- );
- }
- }
-#ifdef COMMENT
- debug(F100,"ftp openftp while exit","",0);
- rc = cmcfm();
- debug(F101,"ftp openftp cmcfm rc","",rc);
- if (rc < 0)
- goto xopenftp;
-#endif /* COMMENT */
-
- if (opn_psv > -1) { /* /PASSIVE or /ACTIVE switch given */
- sav_psv = ftp_psv;
- ftp_psv = opn_psv;
- }
- if (nologin || haveuser) { /* /NOLOGIN or /USER switch given */
- sav_log = ftp_log;
- ftp_log = haveuser ? 1 : 0;
- }
- if (*hostname == '=') { /* Bypass directory lookup */
- hostname++; /* if hostname starts with '=' */
- havehost++;
- } else if (isdigit(*hostname)) { /* or if it starts with a digit */
- havehost++;
- }
- if (!service)
- makestr(&service,opn_tls?"ftps":"ftp");
-
-#ifndef NODIAL
- if (!havehost && nnetdir > 0) { /* If there is a networks directory */
- lunet(hostname); /* Look up the name */
- debug(F111,"ftp openftp lunet",hostname,nhcount);
- if (nhcount == 0) {
- if (testing)
- printf(" ftp open trying \"%s %s\"...\n",hostname,service);
- success = ftpopen(hostname,service,opn_tls);
- debug(F101,"ftp openftp A ftpopen success","",success);
- rc = success;
- } else {
- int found = 0;
- for (i = 0; i < nhcount; i++) {
- if (nh_p2[i]) /* If network type specified */
- if (ckstrcmp(nh_p2[i],"tcp/ip",strlen(nh_p2[i]),0))
- continue;
- found++;
- makestr(&hostname,nh_p[i]);
- debug(F111,"ftpopen lunet substitution",hostname,i);
- if (testing)
- printf(" ftp open trying \"%s %s\"...\n",hostname,service);
- success = ftpopen(hostname,service,opn_tls);
- debug(F101,"ftp openftp B ftpopen success","",success);
- rc = success;
- if (success)
- break;
- }
- if (!found) { /* E.g. if no network types match */
- if (testing)
- printf(" ftp open trying \"%s %s\"...\n",hostname,service);
- success = ftpopen(hostname,service,opn_tls);
- debug(F101,"ftp openftp C ftpopen success","",success);
- rc = success;
- }
- }
- } else {
-#endif /* NODIAL */
- if (testing)
- printf(" ftp open trying \"%s %s\"...\n",hostname,service);
- success = ftpopen(hostname,service,opn_tls);
- debug(F111,"ftp openftp D ftpopen success",hostname,success);
- debug(F111,"ftp openftp D ftpopen connected",hostname,connected);
- rc = success;
-#ifndef NODIAL
- }
-#endif /* NODIAL */
-
- xopenftp:
- debug(F101,"ftp openftp xopenftp rc","",rc);
- if (hostsave) free(hostsave);
- if (service) free(service);
- if (rc < 0 && ftp_logname) {
- free(ftp_logname);
- ftp_logname = NULL;
- }
- if (ftp_tmp) {
- free(ftp_tmp);
- ftp_tmp = NULL;
- }
- return(rc);
-}
-
-int
-doftpacct() {
- int x;
- char * s;
- if ((x = cmtxt("Remote account", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- makestr(&ftp_acc,brstrip(s));
- if (testing)
- printf(" ftp account: \"%s\"\n",ftp_acc);
- success = (ftpcmd("ACCT",ftp_acc,-1,-1,ftp_vbm) == REPLY_COMPLETE);
- return(success);
-}
-
-int
-doftpusr() { /* Log in as USER */
- int x;
- char *s, * acct = "";
-
- debok = 0; /* Don't log */
- if ((x = cmfld("Remote username or ID","",&s,xxstring)) < 0)
- return(x);
- ckstrncpy(line,brstrip(s),LINBUFSIZ); /* brstrip: 15 Jan 2003 */
- if ((x = cmfld("Remote password","",&s,xxstring)) < 0)
- if (x != -3)
- return(x);
- ckstrncpy(tmpbuf,brstrip(s),TMPBUFSIZ);
- if ((x = cmtxt("Remote account\n or Enter or CR to confirm the command",
- "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- if (*s) {
- x = strlen(tmpbuf);
- if (x > 0) {
- acct = &tmpbuf[x+2];
- ckstrncpy(acct,brstrip(s),TMPBUFSIZ - x - 2);
- }
- }
- if (testing)
- printf(" ftp user \"%s\" password \"%s\"...\n",line,tmpbuf);
- success = ftp_user(line,tmpbuf,acct);
-#ifdef CKLOGDIAL
- dologftp();
-#endif /* CKLOGDIAL */
- return(success);
-}
-
-/* DO (various FTP commands)... */
-
-int
-doftptyp(type) int type; { /* TYPE */
- CHECKCONN();
- ftp_typ = type;
- changetype(ftp_typ,ftp_vbm);
- return(1);
-}
-
-static int
-doftpxmkd(s,vbm) char * s; int vbm; { /* MKDIR action */
- int lcs = -1, rcs = -1;
-#ifndef NOCSETS
- if (ftp_xla) {
- lcs = ftp_csl;
- if (lcs < 0) lcs = fcharset;
- rcs = ftp_csx;
- if (rcs < 0) rcs = ftp_csr;
- }
-#endif /* NOCSETS */
- debug(F110,"ftp doftpmkd",s,0);
- if (ftpcmd("MKD",s,lcs,rcs,vbm) == REPLY_COMPLETE)
- return(success = 1);
- if (ftpcode == 500 || ftpcode == 502) {
- if (!quiet)
- printf("MKD command not recognized, trying XMKD\n");
- if (ftpcmd("XMKD",s,lcs,rcs,vbm) == REPLY_COMPLETE)
- return(success = 1);
- }
- return(success = 0);
-}
-
-static int
-doftpmkd() { /* MKDIR parse */
- int x;
- char * s;
- if ((x = cmtxt("Remote directory name", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if (testing)
- printf(" ftp mkdir \"%s\"...\n",line);
- return(success = doftpxmkd(line,-1));
-}
-
-static int
-doftprmd() { /* RMDIR */
- int x, lcs = -1, rcs = -1;
- char * s;
- if ((x = cmtxt("Remote directory", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if (testing)
- printf(" ftp rmdir \"%s\"...\n",line);
-#ifndef NOCSETS
- if (ftp_xla) {
- lcs = ftp_csl;
- if (lcs < 0) lcs = fcharset;
- rcs = ftp_csx;
- if (rcs < 0) rcs = ftp_csr;
- }
-#endif /* NOCSETS */
- if (ftpcmd("RMD",line,lcs,rcs,ftp_vbm) == REPLY_COMPLETE)
- return(success = 1);
- if (ftpcode == 500 || ftpcode == 502) {
- if (!quiet)
- printf("RMD command not recognized, trying XMKD\n");
- success = (ftpcmd("XRMD",line,lcs,rcs,ftp_vbm) == REPLY_COMPLETE);
- } else
- success = 0;
- return(success);
-}
-
-static int
-doftpren() { /* RENAME */
- int x;
- char * s;
- if ((x = cmfld("Remote filename","",&s,xxstring)) < 0)
- return(x);
- ckstrncpy(line,s,LINBUFSIZ);
- if ((x = cmfld("New name for remote file","",&s,xxstring)) < 0)
- return(x);
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- if ((x = cmcfm()) < 0)
- return(x);
- CHECKCONN();
- if (testing)
- printf(" ftp rename \"%s\" (to) \"%s\"...\n",line,tmpbuf);
- success = ftp_rename(line,tmpbuf);
- return(success);
-}
-
-int
-doftpres() { /* RESET (log out without close) */
- int x;
- if ((x = cmcfm()) < 0)
- return(x);
- CHECKCONN();
- if (testing)
- printf(" ftp reset...\n");
- return(success = ftp_reset());
-}
-
-static int
-doftpxhlp() { /* HELP */
- int x;
- char * s;
- if ((x = cmtxt("Command name", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if (testing)
- printf(" ftp help \"%s\"...\n",line);
- /* No need to translate -- all FTP commands are ASCII */
- return(success = (ftpcmd("HELP",line,0,0,1) == REPLY_COMPLETE));
-}
-
-static int
-doftpdir(cx) int cx; { /* [V]DIRECTORY */
- int x, lcs = 0, rcs = 0, xlate = 0;
- char * p, * s, * m = "";
- if (cx == FTP_VDI) {
- switch (servertype) {
- case SYS_VMS:
- case SYS_DOS:
- case SYS_TOPS10:
- case SYS_TOPS20:
- m = "*.*";
- break;
- default:
- m = "*";
- }
- }
- if ((x = cmtxt("Remote filespec",m,&s,xxstring)) < 0)
- return(x);
- if ((x = remtxt(&s)) < 0)
- return(x);
-#ifdef NOCSETS
- xlate = 0;
-#else
- xlate = ftp_xla;
-#endif /* NOCSETS */
- line[0] = NUL;
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- CHECKCONN();
-
-#ifndef NOCSETS
- if (xlate) { /* SET FTP CHARACTER-SET-TRANSLATION */
- lcs = ftp_csl; /* Local charset */
- if (lcs < 0) lcs = fcharset;
- if (lcs < 0) xlate = 0;
- }
- if (xlate) { /* Still ON? */
- rcs = ftp_csx; /* Remote (Server) charset */
- if (rcs < 0) rcs = ftp_csr;
- if (rcs < 0) xlate = 0;
- }
-#endif /* NOCSETS */
-
- if (testing) {
- p = s;
- if (!p) p = "";
- if (*p)
- printf("Directory of files %s at %s:\n", line, ftp_host);
- else
- printf("Directory of files at %s:\n", ftp_host);
- }
- debug(F111,"doftpdir",s,cx);
-
- if (cx == FTP_DIR) {
- /* Translation of line[] is done inside recvrequest() */
- /* when it calls ftpcmd(). */
- return(success =
- (recvrequest("LIST","-",s,"wb",0,0,NULL,xlate,lcs,rcs) == 0));
- }
- success = 1; /* VDIR - one file at a time... */
- p = (char *)remote_files(1,(CHAR *)s,NULL,0); /* Get the file list */
- cancelgroup = 0;
- if (!ftp_vbm && !quiet)
- printlines = 1;
- while (p && !cancelfile && !cancelgroup) { /* STAT one file */
- if (ftpcmd("STAT",p,lcs,rcs,ftp_vbm) < 0) {
- success = 0;
- break;
- }
- p = (char *)remote_files(0,NULL,NULL,0); /* Get next file */
- debug(F110,"ftp vdir file",s,0);
- }
- return(success);
-}
-
-static int
-doftppwd() { /* PWD */
- int x, lcs = -1, rcs = -1;
-#ifndef NOCSETS
- if (ftp_xla) {
- lcs = ftp_csl;
- if (lcs < 0) lcs = fcharset;
- rcs = ftp_csx;
- if (rcs < 0) rcs = ftp_csr;
- }
-#endif /* NOCSETS */
- if ((x = cmcfm()) < 0)
- return(x);
- CHECKCONN();
- if (ftpcmd("PWD",NULL,lcs,rcs,1) == REPLY_COMPLETE) {
- success = 1;
- } else if (ftpcode == 500 || ftpcode == 502) {
- if (ftp_deb)
- printf("PWD command not recognized, trying XPWD\n");
- success = (ftpcmd("XPWD",NULL,lcs,rcs,1) == REPLY_COMPLETE);
- }
- return(success);
-}
-
-static int
-doftpcwd(s,vbm) char * s; int vbm; { /* CD (CWD) */
- int lcs = -1, rcs = -1;
-#ifndef NOCSETS
- if (ftp_xla) {
- lcs = ftp_csl;
- if (lcs < 0) lcs = fcharset;
- rcs = ftp_csx;
- if (rcs < 0) rcs = ftp_csr;
- }
-#endif /* NOCSETS */
-
- debug(F110,"ftp doftpcwd",s,0);
- if (ftpcmd("CWD",s,lcs,rcs,vbm) == REPLY_COMPLETE)
- return(success = 1);
- if (ftpcode == 500 || ftpcode == 502) {
- if (!quiet)
- printf("CWD command not recognized, trying XCWD\n");
- if (ftpcmd("XCWD",s,lcs,rcs,vbm) == REPLY_COMPLETE)
- return(success = 1);
- }
- return(success = 0);
-}
-
-static int
-doftpcdup() { /* CDUP */
- debug(F100,"ftp doftpcdup","",0);
- if (ftpcmd("CDUP",NULL,0,0,1) == REPLY_COMPLETE)
- return(success = 1);
- if (ftpcode == 500 || ftpcode == 502) {
- if (!quiet)
- printf("CDUP command not recognized, trying XCUP\n");
- if (ftpcmd("XCUP",NULL,0,0,1) == REPLY_COMPLETE)
- return(success = 1);
- }
- return(success = 0);
-}
-
-/* s y n c d i r -- Synchronizes client & server directories */
-
-/* Used with recursive PUTs; Returns 0 on failure, 1 on success */
-
-static int cdlevel = 0, cdsimlvl = 0;
-
-static int
-syncdir(local,sim) char * local; int sim; {
- char buf[CKMAXPATH+1];
- char tmp[CKMAXPATH+1];
- char msgbuf[CKMAXPATH+64];
- char c, * p = local, * s = buf, * q = buf;
- int i, k = 0, done = 0, itsadir = 0, saveq;
-
- debug(F110,"ftp syncdir local (new)",local,0);
- debug(F110,"ftp syncdir putpath (old)",putpath,0);
-
- itsadir = isdir(local);
- saveq = quiet;
-
- while ((*s = *p)) { /* Copy the argument filename */
- if (++k == CKMAXPATH) /* so we can poke it. */
- return(-1);
- if (*s == '/') /* Pointer to rightmost dirsep */
- q = s;
- s++;
- p++;
- }
- if (!itsadir)
- *q = NUL; /* Keep just the path part */
-
- debug(F110,"ftp syncdir buf",buf,0);
- if (!strcmp(buf,putpath)) { /* Same as for previous file? */
- if (itsadir) { /* It's a directory? */
- if (doftpcwd(local,0)) { /* Try to CD to it */
- doftpcdup(); /* Worked - CD back up */
- } else if (sim) { /* Simulating... */
- if (fdispla == XYFD_B) {
- printf("WOULD CREATE DIRECTORY %s\n",local);
- } else if (fdispla) {
- ckmakmsg(msgbuf,CKMAXPATH,
- "WOULD CREATE DIRECTORY",local,NULL,NULL);
- ftscreen(SCR_ST,ST_MSG,0l,msgbuf);
- }
- /* See note above */
- return(0);
- } else if (!doftpxmkd(local,0)) { /* Can't CD - try to create */
- return(0);
- } else {
- if (fdispla == XYFD_B) {
- printf("CREATED DIRECTORY %s\n",local);
- } else if (fdispla) {
- ckmakmsg(msgbuf,CKMAXPATH+64,
- "CREATED DIRECTORY ",local,NULL,NULL);
- ftscreen(SCR_ST,ST_MSG,0l,msgbuf);
- }
- }
- }
- debug(F110,"ftp syncdir no change",buf,0);
- return(1); /* Yes, done. */
- }
- ckstrncpy(tmp,buf,CKMAXPATH+1); /* Make a safe (pre-poked) copy */
- debug(F110,"ftp syncdir new path",buf,0); /* for later (see end) */
-
- p = buf; /* New */
- s = putpath; /* Old */
-
- debug(F110,"ftp syncdir A p",p,0);
- debug(F110,"ftp syncdir A s",s,0);
-
- while (*p != NUL && *s != NUL && *p == *s) p++,s++;
-
- if (*s == '/' && !*p) s++; /* Don't count initial slash */
-
- debug(F110,"ftp syncdir B p",p,0);
- debug(F110,"ftp syncdir B s",s,0);
-
- /* p and s now point to the leftmost spot where they differ */
-
- if (*s) { /* We have to back up */
- k = 1; /* How many levels */
- while ((c = *s++)) { /* Count dirseps */
- if (c == '/' && *s)
- k++;
- }
- for (i = 0; i < k; i++) { /* Do that many CDUPs */
- debug(F111,"ftp syncdir up",p,i+1);
- if (sim && cdsimlvl) {
- cdsimlvl--;
- } else {
- if (!doftpcdup()) {
- quiet = saveq;
- return(0);
- }
- }
- cdlevel--;
- }
- if (!*p) /* If we don't have to go down */
- goto xcwd; /* we're done. */
- }
- while (p > buf && *p && *p != '/') /* If in middle of segment */
- p--; /* back up to beginning */
- if (*p == '/') /* and terminate there */
- p++;
-
- s = p; /* Point to start of new down path. */
- while (1) { /* Loop through characters. */
- if (*s == '/' || !*s) { /* Have a segment. */
- if (!*s) /* If end of string, */
- done++; /* after this segment we're done. */
- else
- *s = NUL; /* NUL out the separator. */
- if (*p) { /* If segment is not empty */
- debug(F110,"ftp syncdir down segment",p,0);
- if (!doftpcwd(p,0)) { /* Try to CD to it */
- if (sim) {
- if (fdispla == XYFD_B) {
- printf("WOULD CREATE DIRECTORY %s\n",local);
- } else if (fdispla) {
- ckmakmsg(msgbuf,CKMAXPATH,"WOULD CREATE DIRECTORY",
- local,NULL,NULL);
- ftscreen(SCR_ST,ST_MSG,0l,msgbuf);
- }
- cdsimlvl++;
- } else {
- if (!doftpxmkd(p,0)) { /* Can't CD - try to create */
-/*
- Suppose we are executing SEND /RECURSIVE. Locally we have a directory
- FOO but the remote has a regular file with the same name. We can't CD
- to it, can't MKDIR it either. There's no way out but to fail and let
- the user handle the problem.
-*/
- quiet = saveq;
- return(0);
- }
- if (fdispla == XYFD_B) {
- printf("CREATED DIRECTORY %s\n",p);
- } else if (fdispla) {
- ckmakmsg(msgbuf,CKMAXPATH,
- "CREATED DIRECTORY ",p,NULL,NULL);
- ftscreen(SCR_ST,ST_MSG,0l,msgbuf);
- }
- if (!doftpcwd(p,0)) { /* Try again to CD */
- quiet = saveq;
- return(0);
- }
- }
- }
- cdlevel++;
- }
- if (done) /* Quit if no next segment */
- break;
- p = s+1; /* Point to next segment */
- }
- s++; /* Point to next source char */
- }
-
- xcwd:
- ckstrncpy(putpath,tmp,CKMAXPATH+1); /* All OK - make this the new path */
- quiet = saveq;
- return(1);
-}
-
-#ifdef DOUPDATE
-#ifdef DEBUG
-static VOID
-dbtime(s,xx) char * s; struct tm * xx; { /* Write struct tm to debug log */
- if (deblog) {
- debug(F111,"ftp year ",s,xx->tm_year);
- debug(F111,"ftp month",s,xx->tm_mon);
- debug(F111,"ftp day ",s,xx->tm_mday);
- debug(F111,"ftp hour ",s,xx->tm_hour);
- debug(F111,"ftp min ",s,xx->tm_min);
- debug(F111,"ftp sec ",s,xx->tm_sec);
- }
-}
-#endif /* DEBUG */
-
-/* t m c o m p a r e -- Compare two struct tm's */
-
-/* Like strcmp() but for struct tm's */
-/* Returns -1 if xx < yy, 0 if they are equal, 1 if xx > yy */
-
-static int
-tmcompare(xx,yy) struct tm * xx, * yy; {
-
- if (xx->tm_year < yy->tm_year) /* First year less than second */
- return(-1);
- if (xx->tm_year > yy->tm_year) /* First year greater than second */
- return(1);
-
- /* Years are equal so compare months */
-
- if (xx->tm_mon < yy->tm_mon) /* And so on... */
- return(-1);
- if (xx->tm_mon > yy->tm_mon)
- return(1);
-
- if (xx->tm_mday < yy->tm_mday)
- return(-1);
- if (xx->tm_mday > yy->tm_mday)
- return(1);
-
- if (xx->tm_hour < yy->tm_hour)
- return(-1);
- if (xx->tm_hour > yy->tm_hour)
- return(1);
-
- if (xx->tm_min < yy->tm_min)
- return(-1);
- if (xx->tm_min > yy->tm_min)
- return(1);
-
- if (xx->tm_sec < yy->tm_sec)
- return(-1);
- if (xx->tm_sec > yy->tm_sec)
- return(1);
-
- return(0);
-}
-#endif /* DOUPDATE */
-
-#ifndef HAVE_TIMEGM /* For platforms that do not have timegm() */
-static CONST int MONTHDAYS[] = { /* Number of days in each month. */
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
-};
-
-/* Macro for whether a given year is a leap year. */
-#define ISLEAP(year) \
-(((year) % 4) == 0 && (((year) % 100) != 0 || ((year) % 400) == 0))
-#endif /* HAVE_TIMEGM */
-
-/* m k u t i m e -- Like mktime() but argument is already UTC */
-
-static time_t
-#ifdef CK_ANSIC
-mkutime(struct tm * tm)
-#else
-mkutime(tm) struct tm * tm;
-#endif /* CK_ANSIC */
-/* mkutime */ {
-#ifdef HAVE_TIMEGM
- return(timegm(tm)); /* Have system service, use it. */
-#else
-/*
- Contributed by Russ Allbery (rra@stanford.edu), used by permission.
- Given a struct tm representing a calendar time in UTC, convert it to
- seconds since epoch. Returns (time_t) -1 if the time is not
- convertable. Note that this function does not canonicalize the provided
- struct tm, nor does it allow out-of-range values or years before 1970.
- Result should be identical with timegm().
-*/
- time_t result = 0;
- int i;
- /*
- We do allow some ill-formed dates, but we don't do anything special
- with them and our callers really shouldn't pass them to us. Do
- explicitly disallow the ones that would cause invalid array accesses
- or other algorithm problems.
- */
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"mkutime tm_mon","",tm->tm_mon);
- debug(F101,"mkutime tm_year","",tm->tm_year);
- }
-#endif /* DEBUG */
- if (tm->tm_mon < 0 || tm->tm_mon > 11 || tm->tm_year < 70)
- return((time_t) -1);
-
- /* Convert to time_t. */
- for (i = 1970; i < tm->tm_year + 1900; i++)
- result += 365 + ISLEAP(i);
- for (i = 0; i < tm->tm_mon; i++)
- result += MONTHDAYS[i];
- if (tm->tm_mon > 1 && ISLEAP(tm->tm_year + 1900))
- result++;
- result = 24 * (result + tm->tm_mday - 1) + tm->tm_hour;
- result = 60 * result + tm->tm_min;
- result = 60 * result + tm->tm_sec;
- debug(F101,"mkutime result","",result);
- return(result);
-#endif /* HAVE_TIMEGM */
-}
-
-
-/*
- s e t m o d t i m e -- Set file modification time.
-
- f = char * filename;
- t = time_t date/time to set (Secs since 19700101 0:00:00 UTC, NOT local)
-
- UNIX-specific; isolates mainline code from hideous #ifdefs.
- Returns:
- 0 on success,
- -1 on error.
-
-*/
-static int
-#ifdef CK_ANSIC
-setmodtime(char * f, time_t t)
-#else
-setmodtime(f,t) char * f; time_t t;
-#endif /* CK_ANSIC */
-/* setmodtime */ {
-#ifdef NT
- struct _stat sb;
-#else /* NT */
- struct stat sb;
-#endif /* NT */
- int x, rc = 0;
-#ifdef BSD44
- struct timeval tp[2];
-#else
-#ifdef V7
- struct utimbuf {
- time_t timep[2];
- } tp;
-#else
-#ifdef SYSUTIMEH
-#ifdef NT
- struct _utimbuf tp;
-#else /* NT */
- struct utimbuf tp;
-#endif /* NT */
-#else
- struct utimbuf {
- time_t atime;
- time_t mtime;
- } tp;
-#endif /* SYSUTIMEH */
-#endif /* V7 */
-#endif /* BSD44 */
-
- if (stat(f,&sb) < 0) {
- debug(F111,"setmodtime stat failure",f,errno);
- return(-1);
- }
-#ifdef BSD44
- tp[0].tv_sec = sb.st_atime; /* Access time first */
- tp[1].tv_sec = t; /* Update time second */
- debug(F111,"setmodtime BSD44",f,t);
-#else
-#ifdef V7
- tp.timep[0] = t; /* Set modif. time to creation date */
- tp.timep[1] = sb.st_atime; /* Don't change the access time */
- debug(F111,"setmodtime V7",f,t);
-#else
-#ifdef SYSUTIMEH
- tp.modtime = t; /* Set modif. time to creation date */
- tp.actime = sb.st_atime; /* Don't change the access time */
- debug(F111,"setmodtime SYSUTIMEH",f,t);
-#else
- tp.mtime = t; /* Set modif. time to creation date */
- tp.atime = sb.st_atime; /* Don't change the access time */
- debug(F111,"setmodtime (other)",f,t);
-#endif /* SYSUTIMEH */
-#endif /* V7 */
-#endif /* BSD44 */
-
- /* Try to set the file date */
-
-#ifdef BSD44
- x = utimes(f,tp);
- debug(F111,"setmodtime utimes()","BSD44",x);
-#else
-#ifdef IRIX65
- {
- /*
- The following produces the nonsensical warning:
- Argument of type "const struct utimbuf *" is incompatible with
- parameter of type "const struct utimbuf *". If you can make it
- go away, be my guest.
- */
- const struct utimbuf * t2 = &tp;
- x = utime(f,t2);
- }
-#else
- x = utime(f,&tp);
- debug(F111,"setmodtime utime()","other",x);
-#endif /* IRIX65 */
-#endif /* BSD44 */
- if (x)
- rc = -1;
-
- debug(F101,"setmodtime result","",rc);
- return(rc);
-}
-
-
-/*
- c h k m o d t i m e -- Check/Set file modification time.
-
- fc = function code:
- 0 = Check; returns:
- -1 on error,
- 0 if local older than remote,
- 1 if modtimes are equal,
- 2 if local newer than remote.
- 1 = Set (local file's modtime from remote's); returns:
- -1 on error,
- 0 on success.
-*/
-static int
-chkmodtime(local,remote,fc) char * local, * remote; int fc; {
-#ifdef NT
- struct _stat statbuf;
-#else /* NT */
- struct stat statbuf;
-#endif /* NT */
- struct tm * tmlocal = NULL;
- struct tm tmremote;
- int rc = 0, havedate = 0, lcs = -1, rcs = -1, flag = 0;
- char * s, timebuf[64];
-
- debug(F111,"chkmodtime",local,mdtmok);
- if (!mdtmok) /* Server supports MDTM? */
- return(-1); /* No don't bother. */
-
-#ifndef NOCSETS
- if (ftp_xla) {
- lcs = ftp_csl;
- if (lcs < 0) lcs = fcharset;
- rcs = ftp_csx;
- if (rcs < 0) rcs = ftp_csr;
- }
-#endif /* NOCSETS */
-
- if (fc == 0) {
- rc = stat(local,&statbuf);
- if (rc == 0) { /* Get local file's mod time */
- tmlocal = gmtime(&statbuf.st_mtime); /* Convert to struct tm */
-#ifdef DEBUG
- if (tmlocal) {
- dbtime(local,tmlocal);
- }
-#endif /* DEBUG */
- }
- }
- /* Get remote file's mod time as yyyymmddhhmmss */
-
- if (havemdtm) { /* Already got it from MLSD? */
- s = havemdtm;
- flag++;
- } else if (ftpcmd("MDTM",remote,lcs,rcs,0) == REPLY_COMPLETE) {
- char c;
- bzero((char *)&tmremote, sizeof(struct tm));
- s = ftp_reply_str;
- while ((c = *s++)) { /* Skip past response code */
- if (c == SP) {
- flag++;
- break;
- }
- }
- }
- if (flag) {
- debug(F111,"ftp chkmodtime string",s,flag);
- if (fts_sto) { /* User gave server time offset? */
- char * p;
- debug(F110,"ftp chkmodtime offset",fts_sto,0);
- ckmakmsg(timebuf,64,s," ",fts_sto,NULL); /* Build delta time */
- if ((p = cmcvtdate(timebuf,1))) { /* Apply delta time */
- ckstrncpy(timebuf,p,64); /* Convert to MDTM format */
- timebuf[8] = timebuf[9]; /* h */
- timebuf[9] = timebuf[10]; /* h */
- timebuf[10] = timebuf[12]; /* m */
- timebuf[11] = timebuf[13]; /* m */
- timebuf[12] = timebuf[12]; /* s */
- timebuf[13] = timebuf[13]; /* s */
- timebuf[14] = NUL;
- s = timebuf;
- debug(F110,"ftp chkmodtime adjust",s,0);
- }
- }
- if (flag) { /* Convert to struct tm */
- char * pat;
- int y2kbug = 0; /* Seen in Kerberos 4 FTP servers */
- if (!ckstrcmp(s,"191",3,0)) {
- pat = "%05d%02d%02d%02d%02d%02d";
- y2kbug++;
- debug(F110,"ftp chkmodtime Y2K BUG detected",s,0);
- } else {
- pat = "%04d%02d%02d%02d%02d%02d";
- }
- if (sscanf(s, /* Parse into struct tm */
- pat,
- &(tmremote.tm_year),
- &(tmremote.tm_mon),
- &(tmremote.tm_mday),
- &(tmremote.tm_hour),
- &(tmremote.tm_min),
- &(tmremote.tm_sec)
- ) == 6) {
- tmremote.tm_year -= (y2kbug ? 19000 : 1900);
- debug(F101,"ftp chkmodtime year","",tmremote.tm_year);
- tmremote.tm_mon--;
-
-#ifdef DEBUG
- debug(F100,"SERVER TIME FOLLOWS:","",0);
- dbtime(remote,&tmremote);
-#endif /* DEBUG */
-
- if (havedate > -1)
- havedate = 1;
- }
- }
- } else { /* Failed */
- debug(F101,"ftp chkmodtime ftpcode","",ftpcode);
- if (ftpcode == 500 || /* Command unrecognized */
- ftpcode == 502 || /* Command not implemented */
- ftpcode == 202) /* Command superfluous */
- mdtmok = 0; /* Don't ask this server again */
- return(-1);
- }
- if (fc == 0) { /* Compare */
- if (havedate == 1) { /* Only if we have both file dates */
- /*
- Compare with local file's time. We don't use
- clock time (time_t) here in case of signed/unsigned
- confusion, etc.
- */
- int xx;
-#ifdef COMMENT
-#ifdef DEBUG
- if (deblog) {
- dbtime("LOCAL",tmlocal);
- dbtime("REMOT",&tmremote);
- }
-#endif /* DEBUG */
-#endif /* COMMENT */
- xx = tmcompare(tmlocal,&tmremote);
- debug(F101,"chkmodtime tmcompare","",xx);
- return(xx + 1);
- }
- } else if (ftp_dates) { /* Set */
- /*
- Here we must convert struct tm to time_t
- without applying timezone conversion, for which
- there is no portable API. The method is hidden
- in mkutime(), defined above.
- */
- time_t utc;
- utc = mkutime(&tmremote);
- debug(F111,"ftp chkmodtime mkutime",remote,utc);
- if (utc != (time_t)-1)
- return(setmodtime(local,utc));
- }
- return(-1);
-}
-
-/* getfile() returns: -1 on error, 0 if file received, 1 if file skipped */
-
-static int
-getfile(remote,local,recover,append,pipename,xlate,fcs,rcs)
- char * local, * remote, * pipename; int recover, append, xlate, fcs, rcs;
-/* getfile */ {
- int rc = -1;
- ULONG t0, t1;
-
-#ifdef GFTIMER
- CKFLOAT sec;
-#else
- int sec = 0;
-#endif /* GFTIMER */
- char fullname[CKMAXPATH+1];
-
- debug(F110,"ftp getfile remote A",remote,0);
- debug(F110,"ftp getfile local A",local,0);
- debug(F110,"ftp getfile pipename",pipename,0);
- if (!remote) remote = "";
-
-#ifdef PATTERNS
- /* Automatic type switching? */
- if (xfermode == XMODE_A && patterns && get_auto && !forcetype) {
- int x;
- x = matchname(remote,0,servertype);
- debug(F111,"ftp getfile matchname",remote,x);
- switch (x) {
- case 0: ftp_typ = FTT_ASC; break;
- case 1: ftp_typ = tenex ? FTT_TEN : FTT_BIN; break;
- default: if (g_ftp_typ > -1) ftp_typ = g_ftp_typ;
- }
- changetype(ftp_typ,ftp_vbm);
- binary = ftp_typ; /* For file-transfer display */
- }
-#endif /* PATTERNS */
-
-#ifndef NOCSETS
- ftp_csx = -1; /* For file-transfer display */
- ftp_csl = -1; /* ... */
-
- if (rcs > -1) /* -1 means no translation */
- if (ftp_typ == FTT_ASC) /* File type is "ascii"? */
- if (fcs < 0) /* File charset not forced? */
- fcs = fcharset; /* use prevailing FILE CHARACTER-SET */
- if (fcs > -1 && rcs > -1) { /* Set up translation functions */
- debug(F110,"ftp getfile","initxlate",0);
- initxlate(rcs,fcs); /* NB: opposite order of PUT */
- ftp_csx = rcs;
- ftp_csl = fcs;
- } else
- xlate = 0;
-#endif /* NOCSETS */
-
- if (!pipename && (!local || !local[0]))
- local = remote;
-
- out2screen = !strcmp(local,"-");
-
- fullname[0] = NUL;
- if (pipename) {
- ckstrncpy(fullname,pipename,CKMAXPATH+1);
- } else {
- zfnqfp(local,CKMAXPATH,fullname);
- if (!fullname[0])
- ckstrncpy(fullname,local,CKMAXPATH+1);
- }
- if (!out2screen && displa && fdispla) { /* Screen */
- ftscreen(SCR_FN,'F',(long)pktnum,remote);
- ftscreen(SCR_AN,0,0L,fullname);
- ftscreen(SCR_FS,0,fsize,"");
- }
- tlog(F110,ftp_typ ? "ftp get BINARY:" : "ftp get TEXT:", remote, 0);
- tlog(F110," as",fullname,0);
- debug(F111,"ftp getfile size",remote,fsize);
- debug(F111,"ftp getfile local",local,out2screen);
-
- ckstrncpy(filnam, pipename ? remote : local, CKMAXPATH);
-
- t0 = gmstimer(); /* Start time */
- debug(F111,"ftp getfile t0",remote,t0); /* ^^^ */
- rc = recvrequest("RETR",
- local,
- remote,
- append ? "ab" : "wb",
- 0,
- recover,
- pipename,
- xlate,
- fcs,
- rcs
- );
- t1 = gmstimer(); /* End time */
- debug(F111,"ftp getfile t1",remote,t1);
- debug(F111,"ftp getfile sec",remote,(t1-t0)/1000);
-#ifdef GFTIMER
- sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */
- fpxfsecs = sec; /* (for doxlog()) */
-#else
- sec = (t1 - t0) / 1000;
- xfsecs = (int)sec;
-#endif /* GFTIMER */
- debug(F111,"ftp recvrequest rc",remote,rc);
- if (cancelfile || cancelgroup) {
- debug(F111,"ftp get canceled",ckitoa(cancelfile),cancelgroup);
- ftscreen(SCR_ST,ST_INT,0l,"");
- } else if (rc > 0) {
- debug(F111,"ftp get skipped",ckitoa(cancelfile),cancelgroup);
- ftscreen(SCR_ST,ST_SKIP,0l,cmarg);
- } else if (rc < 0) {
- switch (ftpcode) {
- case -4: /* Network error */
- case -2: /* File error */
- ftscreen(SCR_ST,ST_MSG,0l,ck_errstr());
- break;
- case -3:
- ftscreen(SCR_ST,ST_MSG,0l,"Failure to make data connection");
- break;
- case -1:
- ftscreen(SCR_ST,ST_INT,0l,""); /* (should be covered above) */
- break;
- default:
- ftscreen(SCR_ST,ST_MSG,0l,&ftp_reply_str[4]);
- }
- } else { /* Tudo bem */
- ftscreen(SCR_PT,'Z',0L,"");
- if (rc == 0) {
- ftscreen(SCR_ST,ST_OK,0L,""); /* For screen */
- makestr(&rrfspec,remote); /* For WHERE command */
- makestr(&rfspec,fullname);
- }
- }
- if (ftp_dates) /* If FTP DATES ON... */
- if (!pipename && !out2screen) /* and it's a real file */
- if (rc < 1 && rc != -3) /* and it wasn't skipped */
- if (connected) /* and we still have a connection */
- if (zchki(local) > -1) { /* and the file wasn't discarded */
- chkmodtime(local,remote,1); /* set local file date */
- debug(F110,"ftp get set date",local,0);
- }
- filcnt++; /* Used by \v(filenum) */
-#ifdef TLOG
- if (tralog) {
- if (rc > 0) {
- tlog(F100," recovery skipped","",0);
- } else if (rc == 0) {
- tlog(F101," complete, size", "", fsize);
- } else if (cancelfile) {
- tlog(F100," canceled by user","",0);
- } else {
- tlog(F110," failed:",ftp_reply_str,0);
- }
- if (!tlogfmt)
- doxlog(what,local,fsize,ftp_typ,rc,"");
- }
-#endif /* TLOG */
- return(rc);
-}
-
-/* putfile() returns: -1 on error, >0 if file not selected, 0 on success. */
-/* Positive return value is Skip Reason, SKP_xxx, from ckcker.h. */
-
-static int
-putfile(cx,
- local,remote,force,moving,mvto,rnto,srvrn,x_cnv,x_usn,xft,prm,fcs,rcs,flg)
- char * local, * remote, * mvto, *rnto, *srvrn;
- int cx, force, moving, x_cnv, x_usn, xft, fcs, rcs, flg;
-
-/* putfile */ {
-
- char asname[CKMAXPATH+1];
- char fullname[CKMAXPATH+1];
- int k = -1, x = 0, y = 0, o = -1, rc = 0, nc = 0;
- int xlate = 0, restart = 0, mt = -1;
- char * s = NULL, * cmd = NULL;
- ULONG t0 = 0, t1 = 0; /* Times for stats */
- int ofcs = 0, orcs = 0;
-
-#ifdef GFTIMER
- CKFLOAT sec = 0.0;
-#else
- int sec = 0;
-#endif /* GFTIMER */
- debug(F111,"ftp putfile flg",local,flg);
- debug(F110,"ftp putfile srv_renam",srvrn,0);
- debug(F101,"ftp putfile fcs","",fcs);
- debug(F101,"ftp putfile rcs","",rcs);
-
- ofcs = fcs; /* Save charset args */
- orcs = rcs;
-
- sendstart = 0L;
- restart = flg & PUT_RES;
- if (!remote)
- remote = "";
-
- /* FTP protocol command to send to server */
- cmd = (cx == FTP_APP) ? "APPE" : (x_usn ? "STOU" : "STOR");
-
- if (x_cnv == SET_AUTO) { /* Name conversion is auto */
- if (alike) { /* If server & client are alike */
- nc = 0; /* no conversion */
- } else { /* If they are different */
- if (servertype == SYS_UNIX || servertype == SYS_WIN32)
- nc = -1; /* only minimal conversions needed */
- else /* otherwise */
- nc = 1; /* full conversion */
- }
- } else /* Not auto - do what user said */
- nc = x_cnv;
-
- /* If Transfer Mode is Automatic, determine file type */
- if (xfermode == XMODE_A && filepeek && !pipesend) {
- if (isdir(local)) { /* If it's a directory */
- k = FT_BIN; /* skip the file scan */
- } else {
- debug(F110,"FTP PUT calling scanfile",local,0);
- k = scanfile(local,&o,nscanfile); /* Scan the file */
- }
- debug(F111,"FTP PUT scanfile",local,k);
- if (k > -1 && !forcetype) {
- ftp_typ = (k == FT_BIN) ? 1 : 0;
- if (xft > -1 && ftp_typ != xft) {
- if (flg & PUT_SIM)
- tlog(F110,"ftp put SKIP (Type):", local, 0);
- return(SKP_TYP);
- }
- if (ftp_typ == 1 && tenex) /* User said TENEX? */
- ftp_typ = FTT_TEN;
- }
- }
-#ifndef NOCSETS
- ftp_csx = -1; /* For file-transfer display */
- ftp_csl = -1; /* ... */
-
- if (rcs > -1) { /* -1 means no translation */
- if (ftp_typ == 0) { /* File type is "ascii"? */
- if (fcs < 0) { /* File charset not forced? */
- if (k < 0) { /* If we didn't scan */
- fcs = fcharset; /* use prevailing FILE CHARACTER-SET */
- } else { /* If we did scan, use scan result */
- switch (k) {
- case FT_TEXT: /* Unknown text */
- fcs = fcharset;
- break;
- case FT_7BIT: /* 7-bit text */
- fcs = dcset7;
- break;
- case FT_8BIT: /* 8-bit text */
- fcs = dcset8;
- break;
- case FT_UTF8: /* UTF-8 */
- fcs = FC_UTF8;
- break;
- case FT_UCS2: /* UCS-2 */
- fcs = FC_UCS2;
- if (o > -1) /* Input file byte order */
- fileorder = o;
- break;
- default:
- rcs = -1;
- }
- }
- }
- }
- }
- if (fcs > -1 && rcs > -1) { /* Set up translation functions */
- debug(F110,"ftp putfile","initxlate",0);
- initxlate(fcs,rcs);
- debug(F111,"ftp putfile rcs",fcsinfo[rcs].keyword,rcs);
- xlate = 1;
- ftp_csx = rcs;
- ftp_csl = fcs;
- }
-#endif /* NOCSETS */
-
- binary = ftp_typ; /* For file-transfer display */
- asname[0] = NUL;
-
- if (recursive) { /* If sending recursively, */
- if (!syncdir(local,flg & PUT_SIM)) /* synchronize directories. */
- return(-1); /* Don't PUT if it fails. */
- else if (isdir(local)) /* It's a directory */
- return(0); /* Don't send it! */
- }
- if (*remote) { /* If an as-name template was given */
-#ifndef NOSPL
- if (cmd_quoting) { /* and COMMAND QUOTING is ON */
- y = CKMAXPATH; /* evaluate it for this file */
- s = asname;
- zzstring(remote,&s,&y);
- } else
-#endif /* NOSPL */
- ckstrncpy(asname,remote,CKMAXPATH); /* (or take it literally) */
- } else { /* No as-name */
- nzltor(local,asname,nc,0,CKMAXPATH); /* use local name strip path */
- debug(F110,"FTP PUT nzltor",asname,0);
- }
- /* Preliminary messages and log entries */
-
- fullname[0] = NUL;
- zfnqfp(local,CKMAXPATH,fullname);
- if (!fullname[0]) ckstrncpy(fullname,local,CKMAXPATH+1);
- fullname[CKMAXPATH] = NUL;
-
- if (displa && fdispla) { /* Screen */
- ftscreen(SCR_FN,'F',(long)pktnum,local);
- ftscreen(SCR_AN,0,0L,asname);
- ftscreen(SCR_FS,0,fsize,"");
- }
-#ifdef DOUPDATE
- if (flg & (PUT_UPD|PUT_DIF)) { /* Date-checking modes... */
- mt = chkmodtime(fullname,asname,0);
- debug(F111,"ftp putfile chkmodtime",asname,mt);
- if (mt == 0 && ((flg & PUT_DIF) == 0)) { /* Local is older */
- tlog(F110,"ftp put /update SKIP (Older modtime): ",fullname,0);
- ftscreen(SCR_ST,ST_SKIP,SKP_DAT,fullname); /* Skip this one */
- filcnt++;
- return(SKP_DAT);
- } else if (mt == 1) { /* Times are equal */
- tlog(F110,"ftp put /update SKIP (Equal modtime): ",fullname,0);
- ftscreen(SCR_ST,ST_SKIP,SKP_EQU,fullname); /* Skip it */
- filcnt++;
- return(SKP_DAT);
- }
- /* Local file is newer */
- tlog(F110,ftp_typ ? "ftp put /update BINARY:" :
- "ftp put /update TEXT:", fullname, 0);
- } else if (flg & PUT_RES) {
- tlog(F110,ftp_typ ? "ftp put /recover BINARY:" :
- "ftp put /recover TEXT:", fullname, 0);
- } else {
- tlog(F110,ftp_typ ? "ftp put BINARY:" : "ftp put TEXT:", fullname, 0);
- }
-#else
- tlog(F110,ftp_typ ? "ftp put BINARY:" : "ftp put TEXT:", fullname, 0);
-#endif /* DOUPDATE */
- tlog(F110," as",asname,0);
-
-#ifndef NOCSETS
- if (xlate) {
- debug(F111,"ftp putfile fcs",fcsinfo[fcs].keyword,fcs);
- tlog(F110," file character set:",fcsinfo[fcs].keyword,0);
- tlog(F110," server character set:",fcsinfo[rcs].keyword,0);
- } else if (!ftp_typ) {
- tlog(F110," character sets:","no conversion",0);
- fcs = ofcs; /* Binary file but we still must */
- rcs = orcs; /* translate its name */
- }
-#endif /* NOCSETS */
-
- /* PUT THE FILE */
-
- t0 = gmstimer(); /* Start time */
- if (flg & PUT_SIM) { /* rc > 0 is a skip reason code */
- if (flg & (PUT_UPD|PUT_DIF)) { /* (see SKP_xxx in ckcker.h) */
- rc = (mt < 0) ? /* Update mode... */
- SKP_XNX : /* Remote file doesn't exist */
- SKP_XUP; /* Remote file is older */
- } else {
- rc = SKP_SIM; /* "Would be sent", period. */
- }
- } else {
- rc = sendrequest(cmd,local,asname,xlate,fcs,rcs,restart);
- }
- t1 = gmstimer(); /* End time */
- filcnt++; /* File number */
-
-#ifdef GFTIMER
- sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */
- fpxfsecs = sec; /* (for doxlog()) */
-#else
- sec = (t1 - t0) / 1000;
- xfsecs = (int)sec;
-#endif /* GFTIMER */
-
- debug(F111,"ftp sendrequest rc",local,rc);
-
- if (cancelfile || cancelgroup) {
- debug(F111,"ftp put canceled",ckitoa(cancelfile),cancelgroup);
- ftscreen(SCR_ST,ST_INT,0l,"");
- } else if (rc > 0) {
- debug(F101,"ftp put skipped",local,rc);
- ftscreen(SCR_ST,ST_SKIP,rc,fullname);
- } else if (rc < 0) {
- debug(F111,"ftp put error",local,ftpcode);
- ftscreen(SCR_ST,ST_MSG,0L,&ftp_reply_str[4]);
- } else {
- debug(F111,"ftp put not canceled",ckitoa(displa),fdispla);
- ftscreen(SCR_PT,'Z',0L,"");
- debug(F111,"ftp put ST_OK",local,rc);
- ftscreen(SCR_ST,ST_OK,0L,"");
- debug(F110,"ftp put old sfspec",sfspec,0);
- makestr(&sfspec,fullname); /* For WHERE command */
- debug(F110,"ftp put new sfspec",sfspec,0);
- debug(F110,"ftp put old srfspec",srfspec,0);
- makestr(&srfspec,asname);
- debug(F110,"ftp put new srfspec",srfspec,0);
- }
-
- /* Final log entries */
-
-#ifdef TLOG
- if (tralog) {
- if (rc > 0) {
- if (rc == SKP_XNX)
- tlog(F100," /simulate: WOULD BE SENT:","no remote file",0);
- else if (rc == SKP_XUP)
- tlog(F100," /simulate: WOULD BE SENT:","remote file older",0);
- else if (rc == SKP_SIM)
- tlog(F100," /simulate: WOULD BE SENT","",0);
- else
- tlog(F110," skipped:",gskreason(rc),0);
- } else if (rc == 0) {
- tlog(F101," complete, size", "", fsize);
- } else if (cancelfile) {
- tlog(F100," canceled by user","",0);
- } else {
- tlog(F110," failed:",ftp_reply_str,0);
- }
- if (!tlogfmt)
- doxlog(what,local,fsize,ftp_typ,rc,"");
- }
-#endif /* TLOG */
-
- if (rc < 0) /* PUT did not succeed */
- return(-1); /* so done. */
-
- if (flg & PUT_SIM) /* Simulating, skip the rest. */
- return(SKP_SIM);
-
-#ifdef UNIX
- /* Set permissions too? */
-
- if (prm) { /* Change permissions? */
- s = zgperm(local); /* Get perms of local file */
- if (!s) s = "";
- x = strlen(s);
- if (x > 3) s += (x - 3);
- if (rdigits(s)) {
- ckmakmsg(ftpcmdbuf,FTP_BUFSIZ,s," ",asname,NULL);
- x =
- ftpcmd("SITE CHMOD",ftpcmdbuf,fcs,rcs,ftp_vbm) == REPLY_COMPLETE;
- tlog(F110, x ? " chmod" : " chmod failed",
- s,
- 0
- );
- if (!x)
- return(-1);
- }
- }
-#endif /* UNIX */
-
- /* Disposition of source file */
-
- if (moving) {
- x = zdelet(local);
- tlog(F110, (x > -1) ?
- " deleted" : " failed to delete",
- local,
- 0
- );
- if (x < 0)
- return(-1);
- } else if (mvto) {
- x = zrename(local,mvto);
- tlog(F110, (x > -1) ?
- " moved source to" : " failed to move source to",
- mvto,
- 0
- );
- if (x < 0)
- return(-1);
- /* ftscreen(SCR_ST,ST_MSG,0L,mvto); */
-
- } else if (rnto) {
- char * s = rnto;
-#ifndef NOSPL
- int y; /* Pass it thru the evaluator */
- extern int cmd_quoting; /* for \v(filename) */
- if (cmd_quoting) { /* But only if cmd_quoting is on */
- y = CKMAXPATH;
- s = (char *)asname;
- zzstring(rnto,&s,&y);
- s = (char *)asname;
- }
-#endif /* NOSPL */
- if (s) if (*s) {
- int x;
- x = zrename(local,s);
- tlog(F110, (x > -1) ?
- " renamed source file to" :
- " failed to rename source file to",
- s,
- 0
- );
- if (x < 0)
- return(-1);
- /* ftscreen(SCR_ST,ST_MSG,0L,s); */
- }
- }
-
- /* Disposition of destination file */
-
- if (srvrn) { /* /SERVER-RENAME: */
- char * s = srvrn;
-#ifndef NOSPL
- int y; /* Pass it thru the evaluator */
- extern int cmd_quoting; /* for \v(filename) */
- debug(F111,"ftp putfile srvrn",s,1);
-
- if (cmd_quoting) { /* But only if cmd_quoting is on */
- y = CKMAXPATH;
- s = (char *)fullname; /* We can recycle this buffer now */
- zzstring(srvrn,&s,&y);
- s = (char *)fullname;
- }
-#endif /* NOSPL */
- debug(F111,"ftp putfile srvrn",s,2);
- if (s) if (*s) {
- int x;
- x = ftp_rename(asname,s);
- debug(F111,"ftp putfile ftp_rename",asname,x);
- tlog(F110, (x > 0) ?
- " renamed destination file to" :
- " failed to rename destination file to",
- s,
- 0
- );
- if (x < 1)
- return(-1);
- }
- }
- return(0);
-}
-
-/* xxout must only be used for ASCII transfers */
-static int
-#ifdef CK_ANSIC
-xxout(char c)
-#else
-xxout(c) char c;
-#endif /* CK_ANSIC */
-{
-#ifndef OS2
-#ifndef VMS
-#ifndef MAC
-#ifndef OSK
- /* For Unix, DG, Stratus, Amiga, Gemdos, other */
- if (c == '\012') {
- if (zzout(dout,(CHAR)'\015') < 0)
- return(-1);
- ftpsnd.bytes++;
- }
-#else /* OSK */
- if (c == '\015') {
- c = '\012';
- if (zzout(dout,(CHAR)'\015') < 0)
- return(-1);
- ftpsnd.bytes++;
- }
-#endif /* OSK */
-#else /* MAC */
- if (c == '\015') {
- c = '\012';
- if (zzout(dout,(CHAR)'\015') < 0)
- return(-1);
- ftpsnd.bytes++;
- }
-#endif /* MAC */
-#endif /* VMS */
-#endif /* OS2 */
- if (zzout(dout,(CHAR)c) < 0)
- return(-1);
- ftpsnd.bytes++;
- return(0);
-}
-
-static int
-#ifdef CK_ANSIC
-scrnout(char c)
-#else
-scrnout(c) char c;
-#endif /* CK_ANSIC */
-{
- return(putchar(c));
-}
-
-static int
-#ifdef CK_ANSIC
-pipeout(char c)
-#else
-pipeout(c) char c;
-#endif /* CK_ANSIC */
-{
- return(zmchout(c));
-}
-
-static int
-ispathsep(c) int c; {
- switch (servertype) {
- case SYS_VMS:
- case SYS_TOPS10:
- case SYS_TOPS20:
- return(((c == ']') || (c == '>') || (c == ':')) ? 1 : 0);
- case SYS_OS2:
- case SYS_WIN32:
- case SYS_DOS:
- return(((c == '\\') || (c == '/') || (c == ':')) ? 1 : 0);
- case SYS_VOS:
- return((c == '>') ? 1 : 0);
- default:
- return((c == '/') ? 1 : 0);
- }
-}
-
-static int
-iscanceled() {
-#ifdef CK_CURSES
- extern int ck_repaint();
-#endif /* CK_CURSES */
- int x, rc = 0;
- char c = 0;
- if (cancelfile)
- return(1);
- x = conchk(); /* Any chars waiting at console? */
- if (x-- > 0) { /* Yes... */
- c = coninc(5); /* Get one */
- switch (c) {
- case 032: /* Ctrl-X or X */
- case 'z':
- case 'Z': cancelgroup++; /* fall thru on purpose */
- case 030: /* Ctrl-Z or Z */
- case 'x':
- case 'X': cancelfile++; rc++; break;
-#ifdef CK_CURSES
- case 'L':
- case 'l':
- case 014: /* Ctrl-L or L or Ctrl-W */
- case 027:
- ck_repaint(); /* Refresh screen */
-#endif /* CK_CURSES */
- }
- }
- while (x-- > 0) /* Soak up any rest */
- c = coninc(1);
- return(rc);
-}
-
-/* zzsend - used by buffered output macros. */
-
-static int
-#ifdef CK_ANSIC
-zzsend(int fd, CHAR c)
-#else
-zzsend(fd,c) int fd; CHAR c;
-#endif /* CK_ANSIC */
-{
- int rc;
-
- debug(F101,"zzsend ucbufsiz","",ucbufsiz);
- debug(F101,"zzsend nout","",nout);
- debug(F111,"zzsend","secure?",ftpissecure());
-
- if (iscanceled()) /* Check for cancellation */
- return(-9);
- rc = (!ftpissecure()) ?
- send(fd, (SENDARG2TYPE)ucbuf, nout, 0) :
- secure_putbuf(fd, ucbuf, nout);
- ucbuf[nout] = NUL;
- nout = 0;
- ucbuf[nout++] = c;
- spackets++;
- pktnum++;
- if (rc > -1 && fdispla != XYFD_B) {
- spktl = nout;
- ftscreen(SCR_PT,'D',spackets,NULL);
- }
- return(rc);
-}
-
-/* c m d l i n p u t -- Command-line PUT */
-
-int
-cmdlinput(stay) int stay; {
- int x, rc = 0, done = 0, good = 0, status = 0;
- ULONG t0, t1; /* Times for stats */
-#ifdef GFTIMER
- CKFLOAT sec;
-#else
- int sec = 0;
-#endif /* GFTIMER */
-
- if (quiet) { /* -q really means quiet */
- displa = 0;
- fdispla = 0;
- } else {
- displa = 1;
- fdispla = XYFD_B;
- }
- testing = 0;
- out2screen = 0;
- dpyactive = 0;
- what = W_FTP|W_SEND;
-
-#ifndef NOSPL
- cmd_quoting = 0;
-#endif /* NOSPL */
- sndsrc = nfils;
-
- t0 = gmstimer(); /* Record starting time */
-
- while (!done && !cancelgroup) { /* Loop for all files */
-
- cancelfile = 0;
- x = gnfile(); /* Get next file from list(s) */
- if (x == 0) /* (see gnfile() comments...) */
- x = gnferror;
-
- switch (x) {
- case 1: /* File to send */
- rc = putfile(FTP_PUT, /* Function (PUT, APPEND) */
- filnam, /* Local file to send */
- filnam, /* Remote name for file */
- forcetype, /* Text/binary mode forced */
- 0, /* Not moving */
- NULL, /* No move-to */
- NULL, /* No rename-to */
- NULL, /* No server-rename */
- ftp_cnv, /* Filename conversion */
- 0, /* Unique-server-names */
- -1, /* All file types */
- 0, /* No permissions */
- -1, /* No character sets */
- -1, /* No character sets */
- 0 /* No update or restart */
- );
- if (rc > -1) {
- good++;
- status = 1;
- }
- if (cancelfile) {
- continue; /* Or break? */
- }
- if (rc < 0) {
- ftp_fai++;
- }
- continue; /* Or break? */
-
- case 0: /* No more files, done */
- done++;
- continue;
-
- case -2:
- case -1:
- printf("?%s: file not found - \"%s\"\n",
- puterror ? "Fatal" : "Warning",
- filnam
- );
- continue; /* or break? */
- case -3:
- printf("?Warning access denied - \"%s\"\n", filnam);
- continue; /* or break? */
- case -5:
- printf("?Too many files match\n");
- done++;
- break;
- case -6:
- if (good < 1)
- printf("?No files selected\n");
- done++;
- break;
- default:
- printf("?getnextfile() - unknown failure\n");
- done++;
- }
- }
- if (status > 0) {
- if (cancelgroup)
- status = 0;
- else if (cancelfile && good < 1)
- status = 0;
- }
- success = status;
- x = success;
- if (x > -1) {
- lastxfer = W_FTP|W_SEND;
- xferstat = success;
- }
- t1 = gmstimer(); /* End time */
-#ifdef GFTIMER
- sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */
- if (!sec) sec = 0.001;
- fptsecs = sec;
-#else
- sec = (t1 - t0) / 1000;
- if (!sec) sec = 1;
-#endif /* GFTIMER */
- tfcps = (long) (tfc / sec);
- tsecs = (int)sec;
- lastxfer = W_FTP|W_SEND;
- xferstat = success;
- if (dpyactive)
- ftscreen(SCR_TC,0,0L,"");
-
- if (!stay)
- doexit(success ? GOOD_EXIT : BAD_EXIT, -1);
- return(success);
-}
-
-
-/* d o f t p p u t -- Parse and execute PUT, MPUT, and APPEND */
-
-int
-#ifdef CK_ANSIC
-doftpput(int cx, int who) /* who == 1 for ftp, 0 for kermit */
-#else
-doftpput(cx,who) int cx, who;
-#endif /* CK_ANSIC */
-{
- struct FDB sf, fl, sw, cm;
- int n, rc, confirmed = 0, wild = 0, getval = 0, mput = 0, done = 0;
- int x_cnv = 0, x_usn = 0, x_prm = 0, putflags = 0, status = 0, good = 0;
- char * s, * s2;
-
- int x_csl, x_csr = -1; /* Local and remote charsets */
- int x_xla = 0;
- int x_recurse = 0;
- char c, * p; /* Workers */
-#ifdef PUTARRAY
- int range[2]; /* Array range */
- char ** ap = NULL; /* Array pointer */
- int arrayx = -1; /* Array index */
-#endif /* PUTARRAY */
- ULONG t0 = 0L, t1 = 0L; /* Times for stats */
-#ifdef GFTIMER
- CKFLOAT sec;
-#else
- int sec = 0;
-#endif /* GFTIMER */
-
- struct stringint { /* Temporary array for switch values */
- char * sval;
- int ival;
- } pv[SND_MAX+1];
-
- success = 0; /* Assume failure */
- forcetype = 0; /* No /TEXT or /BINARY given yet */
- out2screen = 0; /* Not outputting file to screen */
- putflags = 0; /* PUT options */
- x_cnv = ftp_cnv; /* Filename conversion */
- x_usn = ftp_usn; /* Unique server names */
- x_prm = ftp_prm; /* Permissions */
- if (x_prm == SET_AUTO) /* Permissions AUTO */
- x_prm = alike;
-
-#ifndef NOCSETS
- x_csr = ftp_csr; /* Inherit global server charset */
- x_csl = ftp_csl;
- if (x_csl < 0)
- x_csl = fcharset;
- x_xla = ftp_xla;
-#endif /* NOCSETS */
-
- makestr(&filefile,NULL); /* No filename list file yet. */
- makestr(&srv_renam,NULL); /* Clear /SERVER-RENAME: */
- makestr(&snd_rename,NULL); /* PUT /RENAME */
- makestr(&snd_move,NULL); /* PUT /MOVE */
- putpath[0] = NUL; /* Initialize for syncdir(). */
- puterror = ftp_err; /* Inherit global error action. */
- what = W_SEND|W_FTP; /* What we're doing (sending w/FTP) */
- asnambuf[0] = NUL; /* Clear as-name buffer */
-
- if (g_ftp_typ > -1) { /* Restore TYPE if saved */
- ftp_typ = g_ftp_typ;
- /* g_ftp_typ = -1; */
- }
- for (i = 0; i <= SND_MAX; i++) { /* Initialize switch values */
- pv[i].sval = NULL; /* to null pointers */
- pv[i].ival = -1; /* and -1 int values */
- }
- if (who == 0) { /* Called with unprefixed command */
- switch (cx) {
- case XXRSEN: pv[SND_RES].ival = 1; break;
- case XXCSEN: pv[SND_CMD].ival = 1; break;
- case XXMOVE: pv[SND_DEL].ival = 1; break;
- case XXMMOVE: pv[SND_DEL].ival = 1; /* fall thru */
- case XXMSE: mput++; break;
- }
- } else {
- if (cx == FTP_MPU)
- mput++;
- }
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "Filename, or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nputswi, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- putswi, /* Keyword table */
- &sf /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* 3rd FDB - local filespec */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- &cm
- );
- cmfdbi(&cm, /* 4th FDB - Confirmation */
- _CMCFM, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- NULL,
- NULL,
- NULL
- );
-
- again:
- cmfdbi(&sf, /* 2nd FDB - file to send */
- _CMIFI, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- /* 0 = parse files, 1 = parse files or dirs, 2 = skip symlinks */
- nolinks | x_recurse, /* addtl numeric data 1 */
- 0, /* dirflg 0 means "not dirs only" */
- xxstring,
- NULL,
-#ifdef COMMENT
- mput ? &cm : &fl
-#else
- &fl
-#endif /* COMMENT */
- );
-
- while (1) { /* Parse zero or more switches */
- x = cmfdb(&sw); /* Parse something */
- debug(F101,"ftp put cmfdb A","",x);
- debug(F101,"ftp put fcode A","",cmresult.fcode);
- if (x < 0) /* Error */
- goto xputx; /* or reparse needed */
- if (cmresult.fcode != _CMKEY) /* Break out of loop if not a switch */
- break;
- c = cmgbrk(); /* Get break character */
- getval = (c == ':' || c == '='); /* to see how they ended the switch */
- if (getval && !(cmresult.kflags & CM_ARG)) {
- printf("?This switch does not take arguments\n");
- x = -9;
- goto xputx;
- }
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- x = -9;
- goto xputx;
- }
- n = cmresult.nresult; /* Numeric result = switch value */
- debug(F101,"ftp put switch","",n);
-
- switch (n) { /* Process the switch */
- case SND_AFT: /* Send /AFTER:date-time */
- case SND_BEF: /* Send /BEFORE:date-time */
- case SND_NAF: /* Send /NOT-AFTER:date-time */
- case SND_NBE: /* Send /NOT-BEFORE:date-time */
- if (!getval) break;
- if ((x = cmdate("File date-time","",&s,0,xxstring)) < 0) {
- if (x == -3) {
- printf("?Date-time required\n");
- x = -9;
- }
- goto xputx;
- }
- pv[n].ival = 1;
- makestr(&(pv[n].sval),s);
- break;
-
- case SND_ASN: /* /AS-NAME: */
- debug(F101,"ftp put /as-name getval","",getval);
- if (!getval) break;
- if ((x = cmfld("Name to send under","",&s,NULL)) < 0) {
- if (x == -3) {
- printf("?name required\n");
- x = -9;
- }
- goto xputx;
- }
- makestr(&(pv[n].sval),brstrip(s));
- debug(F110,"ftp put /as-name 1",pv[n].sval,0);
- if (pv[n].sval) pv[n].ival = 1;
- break;
-
-#ifdef PUTARRAY
- case SND_ARR: /* /ARRAY */
- if (!getval) break;
- ap = NULL;
- if ((x = cmfld("Array name (a single letter will do)",
- "",
- &s,
- NULL
- )) < 0) {
- if (x == -3)
- break;
- else
- return(x);
- }
- if ((x = arraybounds(s,&(range[0]),&(range[1]))) < 0) {
- printf("?Bad array: %s\n",s);
- return(-9);
- }
- if (!(ap = a_ptr[x])) {
- printf("?No such array: %s\n",s);
- return(-9);
- }
- pv[n].ival = 1;
- pv[SND_CMD].ival = 0; /* Undo any conflicting ones... */
- pv[SND_RES].ival = 0;
- pv[SND_FIL].ival = 0;
- arrayx = x;
- break;
-#endif /* PUTARRAY */
-
- case SND_BIN: /* /BINARY */
- case SND_TXT: /* /TEXT or /ASCII */
- case SND_TEN: /* /TENEX */
- pv[SND_BIN].ival = 0;
- pv[SND_TXT].ival = 0;
- pv[SND_TEN].ival = 0;
- pv[n].ival = 1;
- break;
-
-#ifdef PUTPIPE
- case SND_CMD: /* These take no args */
- if (nopush) {
- printf("?Sorry, system command access is disabled\n");
- x = -9;
- goto xputx;
- }
-#ifdef PIPESEND
- else if (sndfilter) {
- printf("?Sorry, no PUT /COMMAND when SEND FILTER selected\n");
- x = -9;
- goto xputx;
- }
-#endif /* PIPESEND */
- sw.hlpmsg = "Command, or switch"; /* Change help message */
- pv[n].ival = 1; /* Just set the flag */
- pv[SND_ARR].ival = 0;
- break;
-#endif /* PUTPIPE */
-
-#ifdef CKSYMLINK
- case SND_LNK:
- nolinks = 0;
- goto again; /* Because CMIFI params changed... */
- case SND_NLK:
- nolinks = 2;
- goto again;
-#endif /* CKSYMLINK */
-
-#ifdef FTP_RESTART
- case SND_RES: /* /RECOVER (resend) */
- pv[SND_ARR].ival = 0; /* fall thru on purpose... */
-#endif /* FTP_RESTART */
-
- case SND_NOB:
- case SND_DEL: /* /DELETE */
- case SND_SHH: /* /QUIET */
- case SND_UPD: /* /UPDATE */
- case SND_SIM: /* /UPDATE */
- case SND_USN: /* /UNIQUE */
- pv[n].ival = 1; /* Just set the flag */
- break;
-
- case SND_REC: /* /RECURSIVE */
- recursive = 2; /* Must be set before cmifi() */
- x_recurse = 1;
- goto again; /* Because CMIFI params changed... */
- break;
-
-#ifdef UNIXOROSK
- case SND_DOT: /* /DOTFILES */
- matchdot = 1;
- break;
- case SND_NOD: /* /NODOTFILES */
- matchdot = 0;
- break;
-#endif /* UNIXOROSK */
-
- case SND_ERR: /* /ERROR-ACTION */
- if ((x = cmkey(qorp,2,"","",xxstring)) < 0)
- goto xputx;
- pv[n].ival = x;
- break;
-
- case SND_EXC: /* Excludes */
- if (!getval) break;
- if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Pattern required\n");
- x = -9;
- }
- goto xputx;
- }
- if (s) if (!*s) s = NULL;
- makestr(&(pv[n].sval),s);
- if (pv[n].sval)
- pv[n].ival = 1;
- break;
-
- case SND_PRM: /* /PERMISSIONS */
- if (!getval)
- x = 1;
- else if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
- goto xputx;
- pv[SND_PRM].ival = x;
- break;
-
-#ifdef PIPESEND
- case SND_FLT: /* /FILTER */
- debug(F101,"ftp put /filter getval","",getval);
- if (!getval) break;
- if ((x = cmfld("Filter program to send through","",&s,NULL)) < 0) {
- if (x == -3)
- s = "";
- else
- goto xputx;
- }
- if (*s) s = brstrip(s);
- y = strlen(s);
- for (x = 0; x < y; x++) { /* Make sure they included "\v(...)" */
- if (s[x] != '\\') continue;
- if (s[x+1] == 'v') break;
- }
- if (x == y) {
- printf(
- "?Filter must contain a replacement variable for filename.\n"
- );
- x = -9;
- goto xputx;
- }
- if (s) if (!*s) s = NULL;
- makestr(&(pv[n].sval),s);
- if (pv[n].sval)
- pv[n].ival = 1;
- break;
-#endif /* PIPESEND */
-
- case SND_NAM: /* /FILENAMES */
- if (!getval) break;
- if ((x = cmkey(fntab,nfntab,"","automatic",xxstring)) < 0)
- goto xputx;
- debug(F101,"ftp put /filenames","",x);
- pv[n].ival = x;
- break;
-
- case SND_SMA: /* Smaller / larger than */
- case SND_LAR:
- if (!getval) break;
- if ((x = cmnum("Size in bytes","0",10,&y,xxstring)) < 0)
- goto xputx;
- pv[n].ival = y;
- break;
-
- case SND_FIL: /* Name of file containing filenames */
- if (!getval) break;
- if ((x = cmifi("Name of file containing list of filenames",
- "",&s,&y,xxstring)) < 0) {
- if (x == -3) {
- printf("?Filename required\n");
- x = -9;
- }
- goto xputx;
- } else if (y && iswild(s)) {
- printf("?Wildcards not allowed\n");
- x = -9;
- goto xputx;
- }
- if (s) if (!*s) s = NULL;
- makestr(&(pv[n].sval),s);
- if (pv[n].sval) {
- pv[n].ival = 1;
- pv[SND_ARR].ival = 0;
- } else {
- pv[n].ival = 0;
- }
- mput = 0;
- break;
-
- case SND_MOV: /* MOVE after */
- case SND_REN: /* RENAME after */
- case SND_SRN: { /* SERVER-RENAME after */
- char * m = "";
- switch (n) {
- case SND_MOV:
- m = "device and/or directory for source file after sending";
- break;
- case SND_REN:
- m = "new name for source file after sending";
- break;
- case SND_SRN:
- m = "new name for destination file after sending";
- break;
- }
- if (!getval) break;
- if ((x = cmfld(m, "", &s, n == SND_MOV ? xxstring : NULL)) < 0) {
- if (x == -3) {
- printf("%s\n", n == SND_MOV ?
- "?Destination required" :
- "?New name required"
- );
- x = -9;
- }
- goto xputx;
- }
- if (s) if (!*s) s = NULL;
- makestr(&(pv[n].sval),s ? brstrip(s) : NULL);
- pv[n].ival = (pv[n].sval) ? 1 : 0;
- break;
- }
- case SND_STA: /* Starting position (= PSEND) */
- if (!getval) break;
- if ((x = cmnum("0-based position","0",10,&y,xxstring)) < 0)
- goto xputx;
- pv[n].ival = y;
- break;
-
- case SND_TYP: /* /TYPE */
- if (!getval) break;
- if ((x = cmkey(txtbin,3,"","all",xxstring)) < 0)
- goto xputx;
- pv[n].ival = (x == 2) ? -1 : x;
- break;
-
-#ifndef NOCSETS
- case SND_CSL: /* Local character set */
- case SND_CSR: /* Remote (server) charset */
- if ((x = cmkey(fcstab,nfilc,"","",xxstring)) < 0) {
- return((x == -3) ? -2 : x);
- }
- if (n == SND_CSL)
- x_csl = x;
- else
- x_csr = x;
- x_xla = 1; /* Overrides global OFF setting */
- break;
-
- case SND_XPA: /* Transparent */
- x_xla = 0;
- x_csr = -1;
- x_csl = -1;
- break;
-#endif /* NOCSETS */
- }
- }
-#ifdef PIPESEND
- if (pv[SND_RES].ival > 0) { /* /RECOVER */
- if (sndfilter || pv[SND_FLT].ival > 0) {
- printf("?Sorry, no /RECOVER or /START if SEND FILTER selected\n");
- x = -9;
- goto xputx;
- }
- if (sfttab[0] > 0 && sfttab[SFT_REST] == 0)
- printf("WARNING: Server says it doesn't support REST.\n");
- }
-#endif /* PIPESEND */
-
- cmarg = "";
- cmarg2 = asnambuf;
- line[0] = NUL;
- s = line;
- wild = 0;
-
- switch (cmresult.fcode) { /* How did we get out of switch loop */
- case _CMIFI: /* Input filename */
- if (pv[SND_FIL].ival > 0) {
- printf("?You may not give a PUT filespec and a /LISTFILE\n");
- x = -9;
- goto xputx;
- }
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Name */
- if (pv[SND_ARR].ival > 0)
- ckstrncpy(asnambuf,line,CKMAXPATH);
- else
- wild = cmresult.nresult; /* Wild flag */
- debug(F111,"ftp put wild",line,wild);
- if (!wild && !recursive && !mput)
- nolinks = 0;
- break;
- case _CMFLD: /* Field */
- /* Only allowed with /COMMAND and /ARRAY */
- if (pv[SND_FIL].ival > 0) {
- printf("?You may not give a PUT filespec and a /LISTFILE\n");
- x = -9;
- goto xputx;
- }
- /* For MPUT it's OK to have filespecs that don't match any files */
- if (mput)
- break;
- if (pv[SND_CMD].ival < 1 && pv[SND_ARR].ival < 1) {
-#ifdef CKROOT
- if (ckrooterr)
- printf("?Off limits: %s\n",cmresult.sresult);
- else
-#endif /* CKROOT */
- printf("?%s - \"%s\"\n",
- iswild(cmresult.sresult) ?
- "No files match" : "File not found",
- cmresult.sresult
- );
- x = -9;
- goto xputx;
- }
- ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
- if (pv[SND_ARR].ival > 0)
- ckstrncpy(asnambuf,line,CKMAXPATH);
- break;
- case _CMCFM: /* Confirmation */
- confirmed = 1;
- break;
- default:
- printf("?Unexpected function code: %d\n",cmresult.fcode);
- x = -9;
- goto xputx;
- }
- debug(F110,"ftp put string",s,0);
- debug(F101,"ftp put confirmed","",confirmed);
-
- /* Save and change protocol and transfer mode */
- /* Global values are restored in main parse loop */
-
- g_displa = fdispla;
- if (ftp_dis > -1)
- fdispla = ftp_dis;
- g_skipbup = skipbup;
-
- if (pv[SND_NOB].ival > -1) { /* /NOBACKUP (skip backup file) */
- g_skipbup = skipbup;
- skipbup = 1;
- }
- if (pv[SND_TYP].ival > -1) { /* /TYPE */
- xfiletype = pv[SND_TYP].ival;
- if (xfiletype == 2)
- xfiletype = -1;
- }
- if (pv[SND_BIN].ival > 0) { /* /BINARY really means binary... */
- forcetype = 1; /* So skip file scan */
- ftp_typ = FTT_BIN; /* Set binary */
- } else if (pv[SND_TXT].ival > 0) { /* Similarly for /TEXT... */
- forcetype = 1;
- ftp_typ = FTT_ASC;
- } else if (pv[SND_TEN].ival > 0) { /* and /TENEX*/
- forcetype = 1;
- ftp_typ = FTT_TEN;
- } else if (ftp_cmdlin && xfermode == XMODE_M) {
- forcetype = 1;
- ftp_typ = binary;
- g_ftp_typ = binary;
- }
-
-#ifdef PIPESEND
- if (pv[SND_CMD].ival > 0) { /* /COMMAND - strip any braces */
- debug(F110,"PUT /COMMAND before stripping",s,0);
- s = brstrip(s);
- debug(F110,"PUT /COMMAND after stripping",s,0);
- if (!*s) {
- printf("?Sorry, a command to send from is required\n");
- x = -9;
- goto xputx;
- }
- cmarg = s;
- }
-#endif /* PIPESEND */
-
-/* Set up /MOVE and /RENAME */
-
- if (pv[SND_DEL].ival > 0 &&
- (pv[SND_MOV].ival > 0 || pv[SND_REN].ival > 0)) {
- printf("?Sorry, /DELETE conflicts with /MOVE or /RENAME\n");
- x = -9;
- goto xputx;
- }
-#ifdef CK_TMPDIR
- if (pv[SND_MOV].ival > 0) {
- int len;
- char * p = pv[SND_MOV].sval;
- len = strlen(p);
- if (!isdir(p)) { /* Check directory */
-#ifdef CK_MKDIR
- char * s = NULL;
- s = (char *)malloc(len + 4);
- if (s) {
- strcpy(s,p); /* safe */
-#ifdef datageneral
- if (s[len-1] != ':') { s[len++] = ':'; s[len] = NUL; }
-#else
- if (s[len-1] != '/') { s[len++] = '/'; s[len] = NUL; }
-#endif /* datageneral */
- s[len++] = 'X';
- s[len] = NUL;
-#ifdef NOMKDIR
- x = -1;
-#else
- x = zmkdir(s);
-#endif /* NOMKDIR */
- free(s);
- if (x < 0) {
- printf("?Can't create \"%s\"\n",p);
- x = -9;
- goto xputx;
- }
- }
-#else
- printf("?Directory \"%s\" not found\n",p);
- x = -9;
- goto xputx;
-#endif /* CK_MKDIR */
- }
- makestr(&snd_move,p);
- }
-#endif /* CK_TMPDIR */
-
- if (pv[SND_REN].ival > 0) { /* /RENAME */
- char * p = pv[SND_REN].sval;
- if (!p) p = "";
- if (!*p) {
- printf("?New name required for /RENAME\n");
- x = -9;
- goto xputx;
- }
- p = brstrip(p);
-#ifndef NOSPL
- /* If name given is wild, rename string must contain variables */
- if (wild) {
- char * s = tmpbuf;
- x = TMPBUFSIZ;
- zzstring(p,&s,&x);
- if (!strcmp(tmpbuf,p)) {
- printf(
- "?/RENAME for file group must contain variables such as \\v(filename)\n"
- );
- x = -9;
- goto xputx;
- }
- }
-#endif /* NOSPL */
- makestr(&snd_rename,p);
- debug(F110,"FTP snd_rename",snd_rename,0);
- }
- if (pv[SND_SRN].ival > 0) { /* /SERVER-RENAME */
- char * p = pv[SND_SRN].sval;
- if (!p) p = "";
- if (!*p) {
- printf("?New name required for /SERVER-RENAME\n");
- x = -9;
- goto xputx;
- }
- p = brstrip(p);
-#ifndef NOSPL
- if (wild) {
- char * s = tmpbuf;
- x = TMPBUFSIZ;
- zzstring(p,&s,&x);
- if (!strcmp(tmpbuf,p)) {
- printf(
-"?/SERVER-RENAME for file group must contain variables such as \\v(filename)\n"
- );
- x = -9;
- goto xputx;
- }
- }
-#endif /* NOSPL */
- makestr(&srv_renam,p);
- debug(F110,"ftp put srv_renam",srv_renam,0);
- }
- if (!confirmed) { /* CR not typed yet, get more fields */
- char * lp;
- if (mput) { /* MPUT or MMOVE */
- nfils = 0; /* We already have the first one */
-#ifndef NOMSEND
- if (cmresult.fcode == _CMIFI) {
- /* First filespec is valid */
- msfiles[nfils++] = line; /* Store pointer */
- lp = line + (int)strlen(line) + 1; /* Point past it */
- debug(F111,"ftp put mput",msfiles[nfils-1],nfils-1);
- } else {
- /* First filespec matches no files */
- debug(F110,"ftp put mput skipping first filespec",
- cmresult.sresult,
- 0
- );
- lp = line;
- }
- /* Parse a filespec, a "field", or confirmation */
-
- cmfdbi(&sf, /* 1st FDB - file to send */
- _CMIFI, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- nolinks | x_recurse, /* addtl numeric data 1 */
- 0, /* dirflg 0 means "not dirs only" */
- xxstring,
- NULL,
- &fl
- );
- cmfdbi(&fl, /* 2nd FDB - local filespec */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- &cm
- );
- cmfdbi(&cm, /* 3rd FDB - Confirmation */
- _CMCFM, /* fcode */
- "",
- "",
- "",
- 0,
- 0,
- NULL,
- NULL,
- NULL
- );
-
- while (!confirmed) { /* Get more filenames */
- x = cmfdb(&sf); /* Parse something */
- debug(F101,"ftp put cmfdb B","",x);
- debug(F101,"ftp put fcode B","",cmresult.fcode);
- if (x < 0) /* Error */
- goto xputx; /* or reparse needed */
- switch (cmresult.fcode) {
- case _CMCFM: /* End of command */
- confirmed++;
- if (nfils < 1) {
- debug(F100,"ftp put mput no files match","",0);
- printf("?No files match MPUT list\n");
- x = -9;
- goto xputx;
- }
- break;
- case _CMFLD: /* No match */
- debug(F110,"ftp put mput skipping",cmresult.sresult,0);
- continue;
- case _CMIFI: /* Good match */
- s = cmresult.sresult;
- msfiles[nfils++] = lp; /* Got one, count, point to it, */
- p = lp; /* remember pointer, */
- while ((*lp++ = *s++)) /* and copy it into buffer */
- if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
- printf("?MPUT list too long\n");
- line[0] = NUL;
- x = -9;
- goto xputx;
- }
- debug(F111,"ftp put mput adding",msfiles[nfils-1],nfils-1);
- if (nfils == 1) /* Take care of \v(filespec) */
- fspec[0] = NUL;
-#ifdef ZFNQFP
- zfnqfp(p,TMPBUFSIZ,tmpbuf);
- p = tmpbuf;
-#endif /* ZFNQFP */
- if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) {
- strcat(fspec,p); /* safe */
- strcat(fspec," "); /* safe */
- } else {
-#ifdef COMMENT
- printf("WARNING - \\v(filespec) buffer overflow\n");
-#else
- debug(F101,"doxput filespec buffer overflow","",0);
-#endif /* COMMENT */
- }
- }
- }
-#endif /* NOMSEND */
- } else { /* Regular PUT */
- nfils = -1;
- if ((x = cmtxt(wild ?
-"\nOptional as-name template containing replacement variables \
-like \\v(filename)" :
- "Optional name to send it with",
- "",&p,NULL)) < 0)
- goto xputx;
-
- if (p) if (!*p) p = NULL;
- p = brstrip(p);
-
- if (p && *p) {
- makestr(&(pv[SND_ASN].sval),p);
- if (pv[SND_ASN].sval)
- pv[SND_ASN].ival = 1;
- debug(F110,"ftp put /as-name 2",pv[SND_ASN].sval,0);
- }
- }
- }
- /* Set cmarg2 from as-name, however we got it. */
-
- CHECKCONN();
- if (pv[SND_ASN].ival > 0 && pv[SND_ASN].sval && !asnambuf[0]) {
- char * p;
- p = brstrip(pv[SND_ASN].sval);
- ckstrncpy(asnambuf,p,CKMAXPATH+1);
- }
- debug(F110,"ftp put asnambuf",asnambuf,0);
-
- if (pv[SND_FIL].ival > 0) {
- if (confirmed) {
- if (zopeni(ZMFILE,pv[SND_FIL].sval) < 1) {
- debug(F110,"ftp put can't open",pv[SND_FIL].sval,0);
- printf("?Failure to open %s\n",pv[SND_FIL].sval);
- x = -9;
- goto xputx;
- }
- makestr(&filefile,pv[SND_FIL].sval); /* Open, remember name */
- debug(F110,"ftp PUT /LISTFILE opened",filefile,0);
- wild = 1;
- }
- }
- if (confirmed && !line[0] && !filefile) {
-#ifndef NOMSEND
- if (filehead) { /* OK if we have a SEND-LIST */
- nfils = filesinlist;
- sndsrc = nfils; /* Like MSEND */
- addlist = 1; /* But using a different list... */
- filenext = filehead;
- goto doput;
- }
-#endif /* NOMSEND */
- printf("?Filename required but not given\n");
- x = -9;
- goto xputx;
- }
-#ifndef NOMSEND
- addlist = 0; /* Don't use SEND-LIST. */
-#endif /* NOMSEND */
-
- if (mput) { /* MPUT (rather than PUT) */
-#ifndef NOMSEND
- cmlist = msfiles; /* List of filespecs */
- sndsrc = nfils; /* rather filespec and as-name */
-#endif /* NOMSEND */
- pipesend = 0;
- } else if (filefile) { /* File contains list of filenames */
- s = "";
- cmarg = "";
- line[0] = NUL;
- nfils = 1;
- sndsrc = 1;
-
- } else if (pv[SND_ARR].ival < 1 && pv[SND_CMD].ival < 1) {
-
- /* Not MSEND, MMOVE, /LIST, or /ARRAY */
- nfils = sndsrc = -1;
- if (!wild) {
- y = zchki(s);
- if (y < 0) {
- printf("?Read access denied - \"%s\"\n", s);
- x = -9;
- goto xputx;
- }
- }
- if (s != line) /* We might already have done this. */
- ckstrncpy(line,s,LINBUFSIZ); /* Copy of string just parsed. */
-#ifdef DEBUG
- else
- debug(F110,"doxput line=s",line,0);
-#endif /* DEBUG */
- cmarg = line; /* File to send */
- }
-#ifndef NOMSEND
- zfnqfp(cmarg,fspeclen,fspec); /* Get full name */
-#endif /* NOMSEND */
-
- if (!mput) { /* For all but MPUT... */
-#ifdef PIPESEND
- if (pv[SND_CMD].ival > 0) /* /COMMAND sets pipesend flag */
- pipesend = 1;
- debug(F101,"ftp put /COMMAND pipesend","",pipesend);
- if (pipesend && filefile) {
- printf("?Invalid switch combination\n");
- x = -9;
- goto xputx;
- }
-#endif /* PIPESEND */
-
-#ifndef NOSPL
- /* If as-name given and filespec is wild, as-name must contain variables */
- if ((wild || mput) && asnambuf[0]) {
- char * s = tmpbuf;
- x = TMPBUFSIZ;
- zzstring(asnambuf,&s,&x);
- if (!strcmp(tmpbuf,asnambuf)) {
- printf(
- "?As-name for file group must contain variables such as \\v(filename)\n"
- );
- x = -9;
- goto xputx;
- }
- }
-#endif /* NOSPL */
- }
-
- doput:
-
- if (pv[SND_SHH].ival > 0) { /* SEND /QUIET... */
- fdispla = 0;
- debug(F101,"ftp put display","",fdispla);
- } else {
- displa = 1;
- if (ftp_deb)
- fdispla = XYFD_B;
- }
-
-#ifdef PUTARRAY /* SEND /ARRAY... */
- if (pv[SND_ARR].ival > 0) {
- if (!ap) { x = -2; goto xputx; } /* (shouldn't happen) */
- if (range[0] == -1) /* If low end of range not specified */
- range[0] = 1; /* default to 1 */
- if (range[1] == -1) /* If high not specified */
- range[1] = a_dim[arrayx]; /* default to size of array */
- if ((range[0] < 0) || /* Check range */
- (range[0] > a_dim[arrayx]) ||
- (range[1] < range[0]) ||
- (range[1] > a_dim[arrayx])) {
- printf("?Bad array range - [%d:%d]\n",range[0],range[1]);
- x = -9;
- goto xputx;
- }
- sndarray = ap; /* Array pointer */
- sndxin = arrayx; /* Array index */
- sndxlo = range[0]; /* Array range */
- sndxhi = range[1];
- sndxnam[7] = (char)((sndxin == 1) ? 64 : sndxin + ARRAYBASE);
- if (!asnambuf[0])
- ckstrncpy(asnambuf,sndxnam,CKMAXPATH);
- cmarg = "";
- }
-#endif /* PUTARRAY */
-
- moving = 0;
-
- if (pv[SND_ARR].ival < 1) { /* File selection & disposition... */
- if (pv[SND_DEL].ival > 0) /* /DELETE was specified */
- moving = 1;
- if (pv[SND_AFT].ival > 0) /* Copy SEND criteria */
- ckstrncpy(sndafter,pv[SND_AFT].sval,19);
- if (pv[SND_BEF].ival > 0)
- ckstrncpy(sndbefore,pv[SND_BEF].sval,19);
- if (pv[SND_NAF].ival > 0)
- ckstrncpy(sndnafter,pv[SND_NAF].sval,19);
- if (pv[SND_NBE].ival > 0)
- ckstrncpy(sndnbefore,pv[SND_NBE].sval,19);
- if (pv[SND_EXC].ival > 0)
- makelist(pv[SND_EXC].sval,sndexcept,NSNDEXCEPT);
- if (pv[SND_SMA].ival > -1)
- sndsmaller = pv[SND_SMA].ival;
- if (pv[SND_LAR].ival > -1)
- sndlarger = pv[SND_LAR].ival;
- if (pv[SND_NAM].ival > -1)
- x_cnv = pv[SND_NAM].ival;
- if (pv[SND_USN].ival > -1)
- x_usn = pv[SND_USN].ival;
- if (pv[SND_ERR].ival > -1)
- puterror = pv[SND_ERR].ival;
-
-#ifdef DOUPDATE
- if (pv[SND_UPD].ival > 0) {
- if (x_usn) {
- printf("?Conflicting switches: /UPDATE /UNIQUE\n");
- x = -9;
- goto xputx;
- }
- putflags |= PUT_UPD;
- ftp_dates |= 2;
- }
-#ifdef COMMENT
- /* This works but it's useless, maybe dangerous */
- if (pv[SND_DIF].ival > 0) {
- if (x_usn) {
- printf("?Conflicting switches: /DATES-DIFFER /UNIQUE\n");
- x = -9;
- goto xputx;
- }
- putflags |= PUT_DIF;
- ftp_dates |= 2;
- }
-#endif /* COMMENT */
-#endif /* DOUPDATE */
-
- if (pv[SND_SIM].ival > 0)
- putflags |= PUT_SIM;
-
- if (pv[SND_PRM].ival > -1) {
-#ifdef UNIX
- if (x_usn) {
- printf("?Conflicting switches: /PERMISSIONS /UNIQUE\n");
- x = -9;
- goto xputx;
- }
- x_prm = pv[SND_PRM].ival;
-#else /* UNIX */
- printf("?/PERMISSIONS switch is not supported\n");
-#endif /* UNIX */
- }
-#ifdef FTP_RESTART
- if (pv[SND_RES].ival > 0) {
- if (!sizeok) {
- printf("?PUT /RESTART can't be used because SIZE disabled.\n");
- x = -9;
- goto xputx;
- }
- if (x_usn || putflags) {
- printf("?Conflicting switches: /RECOVER %s\n",
- x_usn && putflags ? "/UNIQUE /UPDATE" :
- (x_usn ? "/UNIQUE" : "/UPDATE")
- );
- x = -9;
- goto xputx;
- }
-#ifndef NOCSETS
- if (x_xla &&
- (x_csl == FC_UCS2 ||
- x_csl == FC_UTF8 ||
- x_csr == FC_UCS2 ||
- x_csr == FC_UTF8)) {
- printf("?/RECOVER can not be used with Unicode translation\n");
- x = -9;
- goto xputx;
- }
-#endif /* NOCSETS */
- putflags = PUT_RES;
- }
-#endif /* FTP_RESTART */
- }
- debug(F101,"ftp PUT restart","",putflags & PUT_RES);
- debug(F101,"ftp PUT update","",putflags & PUT_UPD);
-
-#ifdef PIPESEND
- if (pv[SND_FLT].ival > 0) { /* Have SEND FILTER? */
- if (!pv[SND_FLT].sval) {
- sndfilter = NULL;
- } else {
- sndfilter = (char *) malloc((int) strlen(pv[SND_FLT].sval) + 1);
- if (sndfilter) strcpy(sndfilter,pv[SND_FLT].sval); /* safe */
- }
- debug(F110,"ftp put /FILTER", sndfilter, 0);
- }
- if (sndfilter || pipesend) /* No /UPDATE or /RESTART */
- if (putflags) /* with pipes or filters */
- putflags = 0;
-#endif /* PIPESEND */
-
- tfc = 0L; /* Initialize stats and counters */
- filcnt = 0;
- pktnum = 0;
- spackets = 0L;
-
- if (wild) /* (is this necessary?) */
- cx = FTP_MPU;
-
- t0 = gmstimer(); /* Record starting time */
-
- done = 0; /* Loop control */
- cancelgroup = 0;
-
- cdlevel = 0;
- cdsimlvl = 0;
- while (!done && !cancelgroup) { /* Loop for all files */
- /* or until canceled. */
-#ifdef FTP_PROXY
- /*
- If we are using a proxy, we don't use the local file list;
- instead we use the list on the remote machine which we want
- sent to someone else, and we use remglob() to get the names.
- But in that case we shouldn't even be executing this routine;
- see ftp_mput().
- */
-#endif /* FTP_PROXY */
-
- cancelfile = 0;
- x = gnfile(); /* Get next file from list(s) */
-
- if (x == 0) /* (see gnfile() comments...) */
- x = gnferror;
- debug(F111,"FTP PUT gnfile",filnam,x);
-
- switch (x) {
- case 1: /* File to send */
- s2 = asnambuf;
-#ifndef NOSPL
- if (asnambuf[0]) { /* As-name */
- int n; char *p; /* to be evaluated... */
- n = TMPBUFSIZ;
- p = tmpbuf;
- zzstring(asnambuf,&p,&n);
- s2 = tmpbuf;
- debug(F110,"ftp put asname",s2,0);
- }
-#endif /* NOSPL */
- rc = putfile(cx, /* Function (PUT, APPEND) */
- filnam, s2, /* Name to send, as-name */
- forcetype, moving, /* Parameters from switches... */
- snd_move, snd_rename, srv_renam,
- x_cnv, x_usn, xfiletype, x_prm,
-#ifndef NOCSETS
- x_csl, (!x_xla ? -1 : x_csr),
-#else
- -1, -1,
-#endif /* NOCSETS */
- putflags
- );
- debug(F111,"ftp put putfile rc",filnam,rc);
- debug(F111,"ftp put putfile cancelfile",filnam,cancelfile);
- debug(F111,"ftp put putfile cancelgroup",filnam,cancelgroup);
- if (rc > -1) {
- good++;
- status = 1;
- }
- if (cancelfile)
- continue;
- if (rc < 0) {
- ftp_fai++;
- if (puterror) {
- status = 0;
- printf("?Fatal upload error: %s\n",filnam);
- done++;
- }
- }
- continue;
- case 0: /* No more files, done */
- done++;
- continue;
- case -1:
- printf("?%s: file not found - \"%s\"\n",
- puterror ? "Fatal" : "Warning",
- filnam
- );
- if (puterror) {
- status = 0;
- done++;
- break;
- }
- continue;
- case -2:
- if (puterror) {
- printf("?Fatal: file not found - \"%s\"\n", filnam);
- status = 0;
- done++;
- break;
- }
- continue; /* Not readable, keep going */
- case -3:
- if (puterror) {
- printf("?Fatal: Read access denied - \"%s\"\n", filnam);
- status = 0;
- done++;
- break;
- }
- printf("?Warning access denied - \"%s\"\n", filnam);
- continue;
-#ifdef COMMENT
- case -4: /* Canceled */
- done++;
- break;
-#endif /* COMMENT */
- case -5:
- printf("?Too many files match\n");
- done++;
- break;
- case -6:
- if (good < 1)
- printf("?No files selected\n");
- done++;
- break;
- default:
- printf("?getnextfile() - unknown failure\n");
- done++;
- }
- }
- if (cdlevel > 0) {
- while (cdlevel--) {
- if (cdsimlvl) {
- cdsimlvl--;
- } else if (!doftpcdup())
- break;
- }
- }
- if (status > 0) {
- if (cancelgroup)
- status = 0;
- else if (cancelfile && good < 1)
- status = 0;
- }
- success = status;
- x = success;
-
- xputx:
- if (x > -1) {
-#ifdef GFTIMER
- t1 = gmstimer(); /* End time */
- sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */
- if (!sec) sec = 0.001;
- fptsecs = sec;
-#else
- sec = (t1 - t0) / 1000;
- if (!sec) sec = 1;
-#endif /* GFTIMER */
- tfcps = (long) (tfc / sec);
- tsecs = (int)sec;
- lastxfer = W_FTP|W_SEND;
- xferstat = success;
- if (dpyactive)
- ftscreen(SCR_TC,0,0L,"");
- }
- for (i = 0; i <= SND_MAX; i++) { /* Free malloc'd memory */
- if (pv[i].sval)
- free(pv[i].sval);
- }
- ftreset(); /* Undo switch effects */
- dpyactive = 0;
- return(x);
-}
-
-
-static char ** mgetlist = NULL; /* For MGET */
-static int mgetn = 0, mgetx = 0;
-static char xtmpbuf[4096];
-
-/*
- c m d l i n g e t
-
- Get files specified by -g command-line option.
- File list is set up in cmlist[] by ckuusy.c; nfils is length of list.
-*/
-int
-cmdlinget(stay) int stay; {
- int i, x, rc = 0, done = 0, good = 0, status = 0, append = 0;
- int lcs = -1, rcs = -1, xlate = 0;
- int first = 1;
- int mget = 1;
- int nc;
- char * s, * s2, * s3;
- ULONG t0, t1; /* Times for stats */
-#ifdef GFTIMER
- CKFLOAT sec;
-#else
- int sec = 0;
-#endif /* GFTIMER */
-
- if (quiet) { /* -q really means quiet */
- displa = 0;
- fdispla = 0;
- } else {
- displa = 1;
- fdispla = XYFD_B;
- }
- testing = 0;
- dpyactive = 0;
- out2screen = 0;
- what = W_FTP|W_RECV;
- mgetmethod = 0;
- mgetforced = 0;
-
- havetype = 0;
- havesize = -1L;
- makestr(&havemdtm,NULL);
-
- if (ftp_fnc < 0)
- ftp_fnc = fncact;
-
-#ifndef NOSPL
- cmd_quoting = 0;
-#endif /* NOSPL */
- debug(F101,"ftp cmdlinget nfils","",nfils);
-
- if (ftp_cnv == CNV_AUTO) { /* Name conversion is auto */
- if (alike) { /* If server & client are alike */
- nc = 0; /* no conversion */
- } else { /* If they are different */
- if (servertype == SYS_UNIX || servertype == SYS_WIN32)
- nc = -1; /* only minimal conversions needed */
- else /* otherwise */
- nc = 1; /* full conversion */
- }
- } else /* Not auto - do what user said */
- nc = ftp_cnv;
-
- if (nfils < 1)
- doexit(BAD_EXIT,-1);
-
- t0 = gmstimer(); /* Starting time for this batch */
-
-#ifndef NOCSETS
- if (xlate) { /* SET FTP CHARACTER-SET-TRANSLATION */
- lcs = ftp_csl; /* Local charset */
- if (lcs < 0) lcs = fcharset;
- if (lcs < 0) xlate = 0;
- }
- if (xlate) { /* Still ON? */
- rcs = ftp_csx; /* Remote (Server) charset */
- if (rcs < 0) rcs = ftp_csr;
- if (rcs < 0) xlate = 0;
- }
-#endif /* NOCSETS */
- /*
- If we have only one file and it is a directory, then we ask for a
- listing of its contents, rather than retrieving the directory file
- itself. This is what (e.g.) Netscape does.
- */
- if (nfils == 1) {
- if (doftpcwd((char *)cmlist[mgetx],-1)) {
- /* If we can CD to it, it must be a directory */
- if (recursive) {
- cmlist[mgetx] = "*";
- } else {
- status =
- (recvrequest("LIST","-","","wb",0,0,NULL,xlate,lcs,rcs)==0);
- done = 1;
- }
- }
- }
-/*
- The following is to work around UNIX servers which, when given a command
- like "NLST path/blah" (not wild) returns the basename without the path.
-*/
- if (!done && servertype == SYS_UNIX && nfils == 1) {
- mget = iswild(cmlist[mgetx]);
- }
- if (!mget && !done) { /* Invoked by command-line FTP URL */
- if (ftp_deb)
- printf("DOING GET...\n");
- done++;
- cancelfile = 0; /* This file not canceled yet */
- s = cmlist[mgetx];
- rc = 0; /* Initial return code */
- fsize = -1L;
- if (sizeok) {
- x = ftpcmd("SIZE",s,lcs,rcs,ftp_vbm); /* Get remote file's size */
- if (x == REPLY_COMPLETE)
- fsize = atol(&ftp_reply_str[4]);
- }
- ckstrncpy(filnam,s,CKMAXPATH); /* For \v(filename) */
- debug(F111,"ftp cmdlinget filnam",filnam,fsize);
-
- nzrtol(s,tmpbuf,nc,0,CKMAXPATH); /* Strip path and maybe convert */
- s2 = tmpbuf;
-
- /* If local file already exists, take collision action */
-
- x = zchki(s2);
- if (x > -1) {
- switch (ftp_fnc) {
- case XYFX_A: /* Append */
- append = 1;
- break;
- case XYFX_R: /* Rename */
- case XYFX_B: { /* Backup */
- char * p = NULL;
- int x = -1;
- znewn(s2,&p); /* Make unique name */
- debug(F110,"ftp cmdlinget znewn",p,0);
- if (ftp_fnc == XYFX_B) { /* Backup existing file */
- x = zrename(s2,p);
- debug(F111,"ftp cmdlinget backup zrename",p,x);
- } else { /* Rename incoming file */
- x = ckstrncpy(tmpbuf,p,CKMAXPATH+1);
- s2 = tmpbuf;
- debug(F111,"ftp cmdlinget rename incoming",p,x);
- }
- if (x < 0) {
- printf("?Backup/Rename failed\n");
- return(success = 0);
- }
- break;
- }
- case XYFX_D: /* Discard */
- ftscreen(SCR_FN,'F',0L,s);
- ftscreen(SCR_ST,ST_SKIP,SKP_NAM,s);
- tlog(F100," refused: name","",0);
- debug(F110,"ftp cmdlinget skip name",s2,0);
- goto xclget;
-
- case XYFX_X: /* Overwrite */
- case XYFX_U: /* Update (already handled above) */
- case XYFX_M: /* ditto */
- break;
- }
- }
- rc = getfile(s, /* Remote name */
- s2, /* Local name */
- 0, /* Recover/Restart */
- append, /* Append */
- NULL, /* Pipename */
- 0, /* Translate charsets */
- -1, /* File charset (none) */
- -1 /* Server charset (none) */
- );
- debug(F111,"ftp cmdlinget rc",s,rc);
- debug(F111,"ftp cmdlinget cancelfile",s,cancelfile);
- debug(F111,"ftp cmdlinget cancelgroup",s,cancelgroup);
-
- if (rc < 0 && haveurl && s[0] == '/') /* URL failed - try again */
- rc = getfile(&s[1], /* Remote name without leading '/' */
- s2, /* Local name */
- 0, /* Recover/Restart */
- append, /* Append */
- NULL, /* Pipename */
- 0, /* Translate charsets */
- -1, /* File charset (none) */
- -1 /* Server charset (none) */
- );
- if (rc > -1) {
- good++;
- status = 1;
- }
- if (cancelfile)
- goto xclget;
- if (rc < 0) {
- ftp_fai++;
- if (geterror) {
- status = 0;
- done++;
- }
- }
- }
- if (ftp_deb && !done)
- printf("DOING MGET...\n");
- while (!done && !cancelgroup) {
- cancelfile = 0; /* This file not canceled yet */
- s = (char *)remote_files(first,(CHAR *)cmlist[mgetx],NULL,0);
- if (!s) s = "";
- if (!*s) {
- first = 1;
- mgetx++;
- if (mgetx < nfils)
- s = (char *)remote_files(first,(CHAR *)cmlist[mgetx],NULL,0);
- else
- s = NULL;
- debug(F111,"ftp cmdlinget remote_files B",s,0);
- if (!s) {
- done = 1;
- break;
- }
- }
- /*
- The semantics of NLST are ill-defined. Suppose we have just sent
- NLST /path/[a-z]*. Most servers send back names like /path/foo,
- /path/bar, etc. But some send back only foo and bar, and subsequent
- RETR commands based on the pathless names are not going to work.
- */
- if (servertype == SYS_UNIX && !ckstrchr(s,'/')) {
- if ((s3 = ckstrrchr(cmlist[mgetx],'/'))) {
- int len, left = 4096;
- char * tmp = xtmpbuf;
- len = s3 - cmlist[mgetx] + 1;
- ckstrncpy(tmp,cmlist[mgetx],left);
- tmp += len;
- left -= len;
- ckstrncpy(tmp,s,left);
- s = xtmpbuf;
- debug(F111,"ftp cmdlinget remote_files X",s,0);
- }
- }
- first = 0; /* Not first any more */
-
- debug(F111,"ftp cmdlinget havetype",s,havetype);
- if (havetype > 0 && havetype != FTYP_FILE) { /* Server says not file */
- debug(F110,"ftp cmdlinget not-a-file",s,0);
- continue;
- }
- rc = 0; /* Initial return code */
- if (havesize > -1L) { /* Already have file size? */
- fsize = havesize;
- } else { /* No - must ask server */
- /*
- Prior to sending the NLST command we necessarily put the
- server into ASCII mode. We must now put it back into the
- the requested mode so the upcoming SIZE command returns
- right kind of size; this is especially important for
- GET /RECOVER; otherwise the server returns the "ASCII" size
- of the file, rather than its true size.
- */
- changetype(ftp_typ,0); /* Change to requested type */
- fsize = -1L;
- if (sizeok) {
- x = ftpcmd("SIZE",s,lcs,rcs,ftp_vbm);
- if (x == REPLY_COMPLETE)
- fsize = atol(&ftp_reply_str[4]);
- }
- }
- ckstrncpy(filnam,s,CKMAXPATH); /* For \v(filename) */
- debug(F111,"ftp cmdlinget filnam",filnam,fsize);
-
- nzrtol(s,tmpbuf,nc,0,CKMAXPATH); /* Strip path and maybe convert */
- s2 = tmpbuf;
-
- /* If local file already exists, take collision action */
-
- x = zchki(s2);
- if (x > -1) {
- switch (ftp_fnc) {
- case XYFX_A: /* Append */
- append = 1;
- break;
- case XYFX_R: /* Rename */
- case XYFX_B: { /* Backup */
- char * p = NULL;
- int x = -1;
- znewn(s2,&p); /* Make unique name */
- debug(F110,"ftp cmdlinget znewn",p,0);
- if (ftp_fnc == XYFX_B) { /* Backup existing file */
- x = zrename(s2,p);
- debug(F111,"ftp cmdlinget backup zrename",p,x);
- } else { /* Rename incoming file */
- x = ckstrncpy(tmpbuf,p,CKMAXPATH+1);
- s2 = tmpbuf;
- debug(F111,"ftp cmdlinget rename incoming",p,x);
- }
- if (x < 0) {
- printf("?Backup/Rename failed\n");
- return(success = 0);
- }
- break;
- }
- case XYFX_D: /* Discard */
- ftscreen(SCR_FN,'F',0L,s);
- ftscreen(SCR_ST,ST_SKIP,SKP_NAM,s);
- tlog(F100," refused: name","",0);
- debug(F110,"ftp cmdlinget skip name",s2,0);
- continue;
- case XYFX_X: /* Overwrite */
- case XYFX_U: /* Update (already handled above) */
- case XYFX_M: /* ditto */
- break;
- }
- }
- /* ^^^ ADD CHARSET STUFF HERE ^^^ */
- rc = getfile(s, /* Remote name */
- s2, /* Local name */
- 0, /* Recover/Restart */
- append, /* Append */
- NULL, /* Pipename */
- 0, /* Translate charsets */
- -1, /* File charset (none) */
- -1 /* Server charset (none) */
- );
- debug(F111,"ftp cmdlinget rc",s,rc);
- debug(F111,"ftp cmdlinget cancelfile",s,cancelfile);
- debug(F111,"ftp cmdlinget cancelgroup",s,cancelgroup);
-
- if (rc > -1) {
- good++;
- status = 1;
- }
- if (cancelfile)
- continue;
- if (rc < 0) {
- ftp_fai++;
- if (geterror) {
- status = 0;
- done++;
- }
- }
- }
-
- xclget:
- if (cancelgroup)
- mlsreset();
- if (status > 0) {
- if (cancelgroup)
- status = 0;
- else if (cancelfile && good < 1)
- status = 0;
- }
- success = status;
-
-#ifdef GFTIMER
- t1 = gmstimer(); /* End time */
- sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */
- if (!sec) sec = 0.001;
- fptsecs = sec;
-#else
- sec = (t1 - t0) / 1000;
- if (!sec) sec = 1;
-#endif /* GFTIMER */
-
- tfcps = (long) (tfc / sec);
- tsecs = (int)sec;
- lastxfer = W_FTP|W_RECV;
- xferstat = success;
- if (dpyactive)
- ftscreen(SCR_TC,0,0L,"");
- if (!stay)
- doexit(success ? GOOD_EXIT : BAD_EXIT, -1);
- return(success);
-}
-
-/* d o f t p g e t -- Parse and execute GET, MGET, MDELETE, ... */
-
-/*
- Note: if we wanted to implement /AFTER:, /BEFORE:, etc, we could use
- zstrdat() to convert to UTC-based time_t. But it doesn't make sense from
- the user-interface perspective, since the server's directory listings show
- its own local times and since we don't know what timezone it's in, there's
- no way to reconcile our local times with the server's.
-*/
-int
-doftpget(cx,who) int cx, who; { /* who == 1 for ftp, 0 for kermit */
- struct FDB fl, sw, cm;
- int i, n, rc, getval = 0, mget = 0, done = 0, pipesave = 0;
- int x_cnv = 0, x_prm = 0, restart = 0, status = 0, good = 0;
- int x_fnc = 0, first = 0, skipthis = 0, append = 0, selected = 0;
- int renaming = 0, mdel = 0, listfile = 0, updating = 0, getone = 0;
- int moving = 0, deleting = 0, toscreen = 0, haspath = 0;
- int gotsize = 0;
- int matchdot = 0;
- long getlarger = -1, getsmaller = -1;
- char * msg, * s, * s2, * nam, * pipename = NULL, * pn = NULL;
- char * src = "", * local = "";
- char * pat = "";
-
- int x_csl = -1, x_csr = -1; /* Local and remote charsets */
- int x_xla = 0;
- char c; /* Worker char */
- ULONG t0 = 0L, t1; /* Times for stats */
-#ifdef GFTIMER
- CKFLOAT sec;
-#else
- int sec = 0;
-#endif /* GFTIMER */
-
- struct stringint { /* Temporary array for switch values */
- char * sval;
- int ival;
- } pv[SND_MAX+1];
-
- success = 0; /* Assume failure */
- forcetype = 0; /* No /TEXT or /BINARY given yet */
- restart = 0; /* No restart yet */
- out2screen = 0; /* No TO-SCREEN switch given yet */
- mgetmethod = 0; /* No NLST or MLSD switch yet */
- mgetforced = 0;
-
- g_displa = fdispla;
- if (ftp_dis > -1)
- fdispla = ftp_dis;
-
- x_cnv = ftp_cnv; /* Filename conversion */
- if (x_cnv == CNV_AUTO) { /* Name conversion is auto */
- if (alike) { /* If server & client are alike */
- x_cnv = 0; /* no conversion */
- } else { /* If they are different */
- if (servertype == SYS_UNIX || servertype == SYS_WIN32)
- x_cnv = -1; /* only minimal conversions needed */
- else /* otherwise */
- x_cnv = 1; /* full conversion */
- }
- } else /* Not auto - do what user said */
- x_cnv = ftp_cnv;
-
- x_prm = ftp_prm; /* Permissions */
- if (x_prm == SET_AUTO) /* Permissions AUTO */
- x_prm = alike;
-
-#ifndef NOCSETS
- x_csr = ftp_csr; /* Inherit global server charset */
- x_csl = ftp_csl; /* Inherit global local charset */
- if (x_csl < 0) /* If none, use current */
- x_csl = fcharset; /* file character-set. */
- x_xla = ftp_xla; /* Translation On/Off */
-#endif /* NOCSETS */
-
- geterror = ftp_err; /* Inherit global error action. */
- asnambuf[0] = NUL; /* No as-name yet. */
- pipesave = pipesend;
- pipesend = 0;
-
- havetype = 0;
- havesize = -1L;
- makestr(&havemdtm,NULL);
-
- if (g_ftp_typ > -1) { /* Restore TYPE if saved */
- ftp_typ = g_ftp_typ;
- /* g_ftp_typ = -1; */
- }
- for (i = 0; i <= SND_MAX; i++) { /* Initialize switch values */
- pv[i].sval = NULL; /* to null pointers */
- pv[i].ival = -1; /* and -1 int values */
- }
- zclose(ZMFILE); /* In case it was left open */
-
- x_fnc = ftp_fnc > -1 ? ftp_fnc : fncact; /* Filename collision action */
-
- if (fp_nml) { /* Reset /NAMELIST */
- if (fp_nml != stdout)
- fclose(fp_nml);
- fp_nml = NULL;
- }
- makestr(&ftp_nml,NULL);
-
- /* Initialize list of remote filespecs */
-
- if (!mgetlist) {
- mgetlist = (char **)malloc(MGETMAX * sizeof(char *));
- if (!mgetlist) {
- printf("?Memory allocation failure - MGET list\n");
- return(-9);
- }
- for (i = 0; i < MGETMAX; i++)
- mgetlist[i] = NULL;
- }
- mgetn = 0; /* Number of mget arguments */
- mgetx = 0; /* Current arg */
-
- if (who == 0) { /* Called with unprefixed command */
- if (cx == XXGET || cx == XXREGET || cx == XXRETR)
- getone++;
- switch (cx) {
- case XXREGET: pv[SND_RES].ival = 1; break;
- case XXRETR: pv[SND_DEL].ival = 1; break;
- case XXGET:
- case XXMGET: mget++; break;
- }
- } else { /* FTP command */
- if (cx == FTP_GET || cx == FTP_RGE)
- getone++;
- switch (cx) {
- case FTP_DEL: /* (fall thru on purpose) */
- case FTP_MDE: mdel++; /* (ditto) */
- case FTP_GET: /* (ditto) */
- case FTP_MGE: mget++; break;
- case FTP_RGE: pv[SND_RES].ival = 1; break;
- }
- }
- cmfdbi(&sw, /* First FDB - command switches */
- _CMKEY, /* fcode */
- "Remote filename;\n or switch", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- mdel ? ndelswi : ngetswi, /* addtl numeric data 1: tbl size */
- 4, /* addtl numeric data 2: 4 = cmswi */
- xxstring, /* Processing function */
- mdel ? delswi : getswi, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* 2nd FDB - remote filename */
- _CMFLD, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- &cm
- );
- cmfdbi(&cm, /* 3rd FDB - Confirmation */
- _CMCFM, /* fcode */
- "", /* hlpmsg */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- NULL,
- NULL,
- NULL
- );
-
- while (1) { /* Parse 0 or more switches */
- x = cmfdb(&sw); /* Parse something */
- debug(F101,"ftp get cmfdb","",x);
- if (x < 0) /* Error */
- goto xgetx; /* or reparse needed */
- if (cmresult.fcode != _CMKEY) /* Break out of loop if not a switch */
- break;
- c = cmgbrk(); /* Get break character */
- getval = (c == ':' || c == '='); /* to see how they ended the switch */
- if (getval && !(cmresult.kflags & CM_ARG)) {
- printf("?This switch does not take arguments\n");
- x = -9;
- goto xgetx;
- }
- n = cmresult.nresult; /* Numeric result = switch value */
- debug(F101,"ftp get switch","",n);
-
- if (!getval && (cmgkwflgs() & CM_ARG)) {
- printf("?This switch requires an argument\n");
- x = -9;
- goto xgetx;
- }
- switch (n) { /* Process the switch */
- case SND_ASN: /* /AS-NAME: */
- debug(F101,"ftp get /as-name getval","",getval);
- if (!getval) break;
- if ((x = cmfld("Name to store it under","",&s,NULL)) < 0) {
- if (x == -3) {
- printf("?name required\n");
- x = -9;
- }
- goto xgetx;
- }
- s = brstrip(s);
- if (!*s) s = NULL;
- makestr(&(pv[n].sval),s);
- pv[n].ival = 1;
- break;
-
- case SND_BIN: /* /BINARY */
- case SND_TXT: /* /TEXT or /ASCII */
- case SND_TEN: /* /TENEX */
- pv[SND_BIN].ival = 0;
- pv[SND_TXT].ival = 0;
- pv[SND_TEN].ival = 0;
- pv[n].ival = 1;
- break;
-
-#ifdef PUTPIPE
- case SND_CMD: /* These take no args */
- if (nopush) {
- printf("?Sorry, system command access is disabled\n");
- x = -9;
- goto xgetx;
- }
-#ifdef PIPESEND
- else if (rcvfilter) {
- printf("?Sorry, no PUT /COMMAND when SEND FILTER selected\n");
- x = -9;
- goto xgetx;
- }
-#endif /* PIPESEND */
- sw.hlpmsg = "Command, or switch"; /* Change help message */
- pv[n].ival = 1; /* Just set the flag */
- pv[SND_ARR].ival = 0;
- break;
-#endif /* PUTPIPE */
-
- case SND_SHH: /* /QUIET */
- case SND_RES: /* /RECOVER (reget) */
- case SND_NOB: /* /NOBACKUPFILES */
- case SND_DEL: /* /DELETE */
- case SND_UPD: /* /UPDATE */
- case SND_USN: /* /UNIQUE */
- case SND_NOD: /* /NODOTFILES */
- case SND_REC: /* /RECOVER */
- case SND_MAI: /* /TO-SCREEN */
- pv[n].ival = 1; /* Just set the flag */
- break;
-
- case SND_DIF: /* /DATES-DIFFER */
- pv[SND_COL].ival = XYFX_M; /* Now it's a collision option */
- pv[n].ival = 1;
- break;
-
- case SND_COL: /* /COLLISION: */
- if ((x = cmkey(ftpcolxtab,nftpcolx,"","",xxstring)) < 0)
- goto xgetx;
- if (x == XYFX_M)
- pv[SND_DIF].ival = 1; /* (phase this out) */
- pv[n].ival = x; /* this should be sufficient */
- break;
-
- case SND_ERR: /* /ERROR-ACTION */
- if ((x = cmkey(qorp,2,"","",xxstring)) < 0)
- goto xgetx;
- pv[n].ival = x;
- break;
-
- case SND_EXC: /* Exception list */
- if (!getval) break;
- if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
- if (x == -3) {
- printf("?Pattern required\n");
- x = -9;
- }
- goto xgetx;
- }
- if (s) if (!*s) s = NULL;
- makestr(&(pv[n].sval),s);
- if (pv[n].sval)
- pv[n].ival = 1;
- break;
-
-#ifdef PIPESEND
- case SND_FLT:
- debug(F101,"ftp get /filter getval","",getval);
- if (!getval) break;
- if ((x = cmfld("Filter program to send through","",&s,NULL)) < 0) {
- if (x == -3)
- s = "";
- else
- goto xgetx;
- }
- s = brstrip(s);
- if (pv[SND_MAI].ival < 1) {
- y = strlen(s);
- /* Make sure they included "\v(...)" */
- for (x = 0; x < y; x++) {
- if (s[x] != '\\') continue;
- if (s[x+1] == 'v') break;
- }
- if (x == y) {
- printf(
- "?Filter must contain a replacement variable for filename.\n"
- );
- x = -9;
- goto xgetx;
- }
- }
- if (*s) {
- pv[n].ival = 1;
- makestr(&(pv[n].sval),s);
- } else {
- pv[n].ival = 0;
- makestr(&(pv[n].sval),NULL);
- }
- break;
-#endif /* PIPESEND */
-
- case SND_NAM:
- if (!getval) break;
- if ((x = cmkey(fntab,nfntab,"","automatic",xxstring)) < 0)
- goto xgetx;
- debug(F101,"ftp get /filenames","",x);
- pv[n].ival = x;
- break;
-
- case SND_SMA: /* Smaller / larger than */
- case SND_LAR:
- if (!getval) break;
- if ((x = cmnum("Size in bytes","0",10,&y,xxstring)) < 0)
- goto xgetx;
- pv[n].ival = y;
- break;
-
- case SND_FIL: /* Name of file containing filnames */
- if (!getval) break;
- if ((x = cmifi("Name of file containing list of filenames",
- "",&s,&y,xxstring)) < 0) {
- if (x == -3) {
- printf("?Filename required\n");
- x = -9;
- }
- goto xgetx;
- } else if (y && iswild(s)) {
- printf("?Wildcards not allowed BBB\n");
- x = -9;
- goto xgetx;
- }
- if (s) if (!*s) s = NULL;
- makestr(&(pv[n].sval),s);
- if (pv[n].sval)
- pv[n].ival = 1;
- break;
-
- case SND_MOV: /* MOVE after */
- case SND_REN: /* RENAME after */
- case SND_SRN: { /* SERVER-RENAME */
- char * m = "";
- switch (n) {
- case SND_MOV:
- m =
- "Device and/or directory for incoming file after reception";
- break;
- case SND_REN:
- m = "New name for incoming file after reception";
- break;
- case SND_SRN:
- m = "New name for source file on server after reception";
- break;
- }
- if (!getval) break;
- if ((x = cmfld(m, "", &s, n == SND_MOV ? xxstring : NULL)) < 0) {
- if (x == -3) {
- printf("%s\n", n == SND_MOV ?
- "?Destination required" :
- "?New name required"
- );
- x = -9;
- }
- goto xgetx;
- }
- makestr(&(pv[n].sval),*s ? brstrip(s) : NULL);
- pv[n].ival = (pv[n].sval) ? 1 : 0;
- break;
- }
-#ifndef NOCSETS
- case SND_CSL: /* Local character set */
- case SND_CSR: /* Remote (server) charset */
- if ((x = cmkey(fcstab,nfilc,"","",xxstring)) < 0)
- return((x == -3) ? -2 : x);
- if (n == SND_CSL)
- x_csl = x;
- else
- x_csr = x;
- x_xla = 1; /* Overrides global OFF setting */
- break;
-
- case SND_XPA: /* Transparent */
- x_xla = 0;
- x_csr = -1;
- x_csl = -1;
- break;
-#endif /* NOCSETS */
-
- case SND_NML:
- if ((x = cmofi("Local filename","-",&s,xxstring)) < 0)
- goto xgetx;
- makestr(&ftp_nml,s);
- break;
-
- case SND_PAT: /* /PATTERN: */
- if (!getval) break;
- if ((x = cmfld("Pattern","*", &s, xxstring)) < 0)
- goto xgetx;
- makestr(&(pv[n].sval),*s ? brstrip(s) : NULL);
- pv[n].ival = (pv[n].sval) ? 1 : 0;
- break;
-
- case SND_NLS: /* /NLST */
- pv[n].ival = 1; /* Use NLST */
- pv[SND_MLS].ival = 0; /* Don't use MLSD */
- break;
-
- case SND_MLS: /* /MLSD */
- pv[n].ival = 1; /* Use MLSD */
- pv[SND_NLS].ival = 0; /* Don't use NLST */
- break;
-
- default: /* /AFTER, /PERMISSIONS, etc... */
- printf("?Sorry, \"%s\" works only with [M]PUT\n",atmbuf);
- x = -9;
- goto xgetx;
- }
- }
- line[0] = NUL;
- cmarg = line;
- cmarg2 = asnambuf;
- s = line;
-/*
- For GET, we want to parse an optional as-name, like with PUT.
- For MGET, we must parse a list of names, and then send NLST or MLSD
- commands for each name separately.
-*/
- switch (cmresult.fcode) { /* How did we get out of switch loop */
- case _CMFLD: /* Field */
- if (!getone) {
- s = brstrip(cmresult.sresult);
- makestr(&(mgetlist[mgetn++]),s);
- while ((x = cmfld("Remote filename","",&s,xxstring)) != -3) {
- if (x < 0)
- goto xgetx;
- makestr(&(mgetlist[mgetn++]),brstrip(s));
- if (mgetn >= MGETMAX) {
- printf("?Too many items in MGET list\n");
- goto xgetx;
- }
- }
- if ((x = cmcfm()) < 0)
- goto xgetx;
- } else {
- s = brstrip(cmresult.sresult);
- ckstrncpy(line,s,LINBUFSIZ);
- if ((x = cmfld("Name to store it under","",&s,xxstring)) < 0)
- if (x != -3)
- goto xgetx;
- s = brstrip(s);
- ckstrncpy(asnambuf,s,CKMAXPATH+1);
- if ((x = cmcfm()) < 0)
- goto xgetx;
- }
- break;
- case _CMCFM: /* Confirmation */
- break;
- default:
- printf("?Unexpected function code: %d\n",cmresult.fcode);
- x = -9;
- goto xgetx;
- }
- if (pv[SND_REC].ival > 0) /* /RECURSIVE */
- recursive = 2;
-
- if (pv[SND_BIN].ival > 0) { /* /BINARY really means binary... */
- forcetype = 1; /* So skip the name-pattern match */
- ftp_typ = XYFT_B; /* Set binary */
- } else if (pv[SND_TXT].ival > 0) { /* Similarly for /TEXT... */
- forcetype = 1;
- ftp_typ = XYFT_T;
- } else if (pv[SND_TEN].ival > 0) { /* and /TENEX*/
- forcetype = 1;
- ftp_typ = FTT_TEN;
- } else if (ftp_cmdlin && xfermode == XMODE_M) {
- forcetype = 1;
- ftp_typ = binary;
- g_ftp_typ = binary;
- }
- if (pv[SND_ASN].ival > 0 && pv[SND_ASN].sval && !asnambuf[0]) {
- char * p;
- p = brstrip(pv[SND_ASN].sval); /* As-name */
- ckstrncpy(asnambuf,p,CKMAXPATH+1);
- }
- debug(F110,"ftp get asnambuf",asnambuf,0);
-
-#ifdef PIPESEND
- if (pv[SND_CMD].ival > 0) { /* /COMMAND - strip any braces */
- char * p;
- p = asnambuf;
- debug(F110,"GET /COMMAND before stripping",p,0);
- p = brstrip(p);
- debug(F110,"GET /COMMAND after stripping",p,0);
- if (!*p) {
- printf("?Sorry, a command to write to is required\n");
- x = -9;
- goto xgetx;
- }
- pipename = p;
- pipesend = 1;
- }
-#endif /* PIPESEND */
-
-/* Set up /MOVE and /RENAME */
-
- if (pv[SND_DEL].ival > 0 &&
- (pv[SND_MOV].ival > 0 || pv[SND_REN].ival > 0)) {
- printf("?Sorry, /DELETE conflicts with /MOVE or /RENAME\n");
- x = -9;
- goto xgetx;
- }
-#ifdef CK_TMPDIR
- if (pv[SND_MOV].ival > 0 && pv[SND_MOV].sval) {
- int len;
- char * p = pv[SND_MOV].sval;
- len = strlen(p);
- if (!isdir(p)) { /* Check directory */
-#ifdef CK_MKDIR
- char * s = NULL;
- s = (char *)malloc(len + 4);
- if (s) {
- strcpy(s,p); /* safe */
-#ifdef datageneral
- if (s[len-1] != ':') { s[len++] = ':'; s[len] = NUL; }
-#else
- if (s[len-1] != '/') { s[len++] = '/'; s[len] = NUL; }
-#endif /* datageneral */
- s[len++] = 'X';
- s[len] = NUL;
-#ifdef NOMKDIR
- x = -1;
-#else
- x = zmkdir(s);
-#endif /* NOMKDIR */
- free(s);
- if (x < 0) {
- printf("?Can't create \"%s\"\n",p);
- x = -9;
- goto xgetx;
- }
- }
-#else
- printf("?Directory \"%s\" not found\n",p);
- x = -9;
- goto xgetx;
-#endif /* CK_MKDIR */
- }
- makestr(&rcv_move,p);
- moving = 1;
- }
-#endif /* CK_TMPDIR */
-
- if (pv[SND_REN].ival > 0) { /* /RENAME */
- char * p = pv[SND_REN].sval;
- if (!p) p = "";
- if (!*p) {
- printf("?New name required for /RENAME\n");
- x = -9;
- goto xgetx;
- }
- p = brstrip(p);
-#ifndef NOSPL
- /* If name given is wild, rename string must contain variables */
- if (mget && !getone) {
- char * s = tmpbuf;
- x = TMPBUFSIZ;
- zzstring(p,&s,&x);
- if (!strcmp(tmpbuf,p)) {
- printf(
- "?/RENAME for file group must contain variables such as \\v(filename)\n"
- );
- x = -9;
- goto xgetx;
- }
- }
-#endif /* NOSPL */
- renaming = 1;
- makestr(&rcv_rename,p);
- debug(F110,"FTP rcv_rename",rcv_rename,0);
- }
- if (!cmarg[0] && mgetn == 0 && getone && pv[SND_FIL].ival < 1) {
- printf("?Filename required but not given\n");
- x = -9;
- goto xgetx;
- } else if ((cmarg[0] || mgetn > 0) && pv[SND_FIL].ival > 0) {
- printf("?You can't give both /LISTFILE and a remote filename\n");
- x = -9;
- goto xgetx;
- }
- CHECKCONN(); /* Check connection */
-
- if (pv[SND_COL].ival > -1)
- x_fnc = pv[SND_COL].ival;
-
-#ifndef NOSPL
- /* If as-name given for MGET, as-name must contain variables */
- if (mget && !getone && asnambuf[0] && x_fnc != XYFX_A) {
- char * s = tmpbuf;
- x = TMPBUFSIZ;
- zzstring(asnambuf,&s,&x);
- if (!strcmp(tmpbuf,asnambuf)) {
- printf(
- "?As-name for MGET must contain variables such as \\v(filename)\n"
- );
- x = -9;
- goto xgetx;
- }
- }
-#endif /* NOSPL */
-
-/* doget: */
-
- if (pv[SND_SHH].ival > 0 || ftp_nml) { /* GET /QUIET... */
- fdispla = 0;
- } else {
- displa = 1;
- if (mdel || ftp_deb)
- fdispla = XYFD_B;
- }
- deleting = 0;
- if (pv[SND_DEL].ival > 0) /* /DELETE was specified */
- deleting = 1;
- if (pv[SND_EXC].ival > 0)
- makelist(pv[SND_EXC].sval,rcvexcept,NSNDEXCEPT);
- if (pv[SND_SMA].ival > -1)
- getsmaller = pv[SND_SMA].ival;
- if (pv[SND_LAR].ival > -1)
- getlarger = pv[SND_LAR].ival;
- if (pv[SND_NAM].ival > -1)
- x_cnv = pv[SND_NAM].ival;
- if (pv[SND_ERR].ival > -1)
- geterror = pv[SND_ERR].ival;
- if (pv[SND_MAI].ival > -1)
- toscreen = 1;
-
- if (pv[SND_NLS].ival > 0) { /* Force NLST or MLSD? */
- mgetmethod = SND_NLS;
- mgetforced = 1;
- } else if (pv[SND_MLS].ival > 0) {
- mgetmethod = SND_MLS;
- mgetforced = 1;
- }
-
-#ifdef FTP_RESTART
- if (pv[SND_RES].ival > 0) {
- if (!ftp_typ) {
- printf("?Sorry, GET /RECOVER requires binary mode\n");
- x = -9;
- goto xgetx;
-#ifdef COMMENT
- /* Not true - the fact that the initial REST fails does not mean */
- /* it will fail here. */
- } else if (!okrestart) {
- printf("WARNING: Server might not support restart...\n");
-#endif /* COMMENT */
- }
- restart = 1;
- }
-#endif /* FTP_RESTART */
-
-#ifdef PIPESEND
- if (pv[SND_FLT].ival > 0) { /* Have SEND FILTER? */
- if (pipesend) {
- printf("?Switch conflict: /FILTER and /COMMAND\n");
- x = -9;
- goto xgetx;
- }
- makestr(&rcvfilter,pv[SND_FLT].sval);
- debug(F110,"ftp get /FILTER", rcvfilter, 0);
- }
- if (rcvfilter || pipesend) { /* /RESTART */
-#ifdef FTP_RESTART
- if (restart) { /* with pipes or filters */
- printf("?Switch conflict: /FILTER or /COMMAND and /RECOVER\n");
- x = -9;
- goto xgetx;
- }
-#endif /* FTP_RESTART */
- if (pv[SND_UPD].ival > 0 || x_fnc == XYFX_M || x_fnc == XYFX_U) {
- printf(
- "?Switch conflict: /FILTER or /COMMAND and Date Checking\n");
- x = -9;
- goto xgetx;
- }
- }
-#endif /* PIPESEND */
-
- tfc = 0L; /* Initialize stats and counters */
- filcnt = 0;
- pktnum = 0;
- rpackets = 0L;
-
- if (pv[SND_FIL].ival > 0) {
- if (zopeni(ZMFILE,pv[SND_FIL].sval) < 1) {
- debug(F111,"ftp get can't open listfile",pv[SND_FIL].sval,errno);
- printf("?Failure to open listfile - \"%s\"\n",pv[SND_FIL].sval);
- x = -9;
- goto xgetx;
- }
- if (zsinl(ZMFILE,tmpbuf,CKMAXPATH) < 0) { /* Read a line */
- zclose(ZMFILE); /* Failed */
- debug(F110,"ftp get listfile EOF",pv[SND_FIL].sval,0);
- printf("?Empty listfile - \"%s\"\n",pv[SND_FIL].sval);
- x = -9;
- goto xgetx;
- }
- listfile = 1;
- debug(F110,"ftp get listfile first",tmpbuf,0);
- makestr(&(mgetlist[0]),tmpbuf);
- }
- t0 = gmstimer(); /* Record starting time */
-
- updating = 0; /* Checking dates? */
- if (pv[SND_UPD].ival > 0 || (!mdel && x_fnc == XYFX_U))
- updating = 1;
- if (pv[SND_DIF].ival > 0 || x_fnc == XYFX_M)
- updating = 2;
- if (updating) /* These switches force FTP DATES ON */
- ftp_dates |= 2;
-
- what = mdel ? W_FTP|W_FT_DELE : W_RECV|W_FTP; /* What we're doing */
-
- cancelgroup = 0; /* Group not canceled yet */
- if (!(xfermode == XMODE_A && patterns && get_auto && !forcetype))
- changetype(ftp_typ,0); /* Change to requested type */
- binary = ftp_typ; /* For file-transfer display */
- first = 1; /* For MGET list */
- done = 0; /* Loop control */
-
-#ifdef CK_TMPDIR
- if (dldir && !f_tmpdir) { /* If they have a download directory */
- if ((s = zgtdir())) { /* Get current directory */
- if (zchdir(dldir)) { /* Change to download directory */
- ckstrncpy(savdir,s,TMPDIRLEN);
- f_tmpdir = 1; /* Remember that we did this */
- }
- }
- }
-#endif /* CK_TMPDIR */
-
- if (ftp_nml) { /* /NAMELIST */
- debug(F110,"ftp GET ftp_nml",ftp_nml,0);
- if (ftp_nml[0] == '-' && ftp_nml[1] == 0)
- fp_nml = stdout;
- else
- fp_nml = fopen(ftp_nml, "wb");
- if (!fp_nml) {
- printf("?%s: %s\n",ftp_nml,ck_errstr());
- goto xgetx;
- }
- }
- while (!done && !cancelgroup) { /* Loop for all files */
- /* or until canceled. */
-#ifdef FTP_PROXY
- /* do something here if proxy */
-#endif /* FTP_PROXY */
-
- rs_len = 0L; /* REGET position */
- cancelfile = 0; /* This file not canceled yet */
- haspath = 0; /* Recalculate this each time thru */
-
- if (getone) { /* GET */
- char * p;
- s = line;
- src = line; /* Server name */
- done = 1;
- debug(F111,"ftp get file",s,0);
- } else if (mget) { /* MGET */
- src = mgetlist[mgetx];
- debug(F111,"ftp mget remote_files A",src,first);
- s = (char *)remote_files(first,
- (CHAR *)mgetlist[mgetx],
- (CHAR *)pv[SND_PAT].sval,
- 0
- );
- debug(F110,"ftp mget remote_files B",s,0);
- if (!s) s = "";
- if (!*s) {
- first = 1;
- if (listfile) { /* Names from listfile */
- again:
- tmpbuf[0] = NUL;
- while (!tmpbuf[0]) {
- if (zsinl(ZMFILE,tmpbuf,CKMAXPATH) < 0) {
- zclose(ZMFILE);
- debug(F110,"ftp get listfile EOF",
- pv[SND_FIL].sval,0);
- makestr(&(mgetlist[0]),NULL);
- s = NULL;
- done = 1;
- break;
- }
- }
- if (done)
- continue;
-
- makestr(&(mgetlist[0]),tmpbuf);
- debug(F110,"ftp get listfile next",tmpbuf,0);
- s = (char *)remote_files(first,
- (CHAR *)mgetlist[0],
- (CHAR *)pv[SND_PAT].sval,
- 0
- );
- debug(F110,"ftp mget remote_files C",s,0);
- if (!s) {
- ftscreen(SCR_FN,'F',0L,s);
- ftscreen(SCR_ST,ST_MSG,0L,"File not found");
- tlog(F110,"ftp get file not found:",s,0);
- goto again;
- }
- } else { /* Names from command line */
- mgetx++;
- if (mgetx < mgetn)
- s = (char *)remote_files(first,
- (CHAR *)mgetlist[mgetx],
- (CHAR *)pv[SND_PAT].sval,
- 0
- );
- else
- s = NULL;
- if (!s) mgetx++;
- debug(F111,"ftp mget remote_files D",s,mgetx);
- }
- if (!s) {
- if (!first || mgetx >= mgetn) {
- done = 1;
- break;
- } else if (geterror) {
- status = 0;
- done = 1;
- break;
- } else {
- continue;
- }
- }
- }
- }
- debug(F111,"ftp mget remote_files E",s,0);
- /*
- The semantics of NLST are ill-defined. Suppose we have just sent
- NLST /path/[a-z]*. Most servers send back names like /path/foo,
- /path/bar, etc. But some send back only foo and bar, and subsequent
- RETR commands based on the pathless names are not going to work.
- */
- if (servertype == SYS_UNIX && !ckstrchr(s,'/')) {
- char * s3;
- if ((s3 = ckstrrchr(mgetlist[mgetx],'/'))) {
- int len, left = 4096;
- char * tmp = xtmpbuf;
- len = s3 - mgetlist[mgetx] + 1;
- ckstrncpy(tmp,mgetlist[mgetx],left);
- tmp += len;
- left -= len;
- ckstrncpy(tmp,s,left);
- s = xtmpbuf;
- debug(F111,"ftp mget remote_files F",s,0);
- }
- }
- first = 0;
- skipthis = 0; /* File selection... */
- msg = "";
- nam = s; /* Filename (without path) */
- rc = 0; /* Initial return code */
- s2 = "";
-
- if (!getone && !skipthis) { /* For MGET and MDELETE... */
- char c, * p = s;
- int srvpath = 0;
- int usrpath = 0;
- int i, k = 0;
-
- debug(F111,"ftp mget havetype",s,havetype);
- if (havetype > 0 && havetype != FTYP_FILE) {
- /* Server says it's not file... */
- debug(F110,"ftp mget not-a-file",s,0);
- continue;
- }
-/*
- Explanation: Some ftp servers (such as wu-ftpd) return a recursive list.
- But if the client did not ask for a recursive list, we have to ignore any
- server files that include a pathname that extends beyond any path that
- was included in the user's request.
-
- User's filespec is blah or path/blah (or other non-UNIX syntax). We need to
- get the user's path segment. Then, for each incoming file, if it begins
- with the same path segment, we must strip it (point past it).
-*/
- src = mgetlist[mgetx]; /* In case it moved! */
- if (src) {
- for (i = 0; src[i]; i++) { /* Find rightmost path separator */
- if (ispathsep(src[i])) /* in user's pathname */
- k = i + 1;
- }
- } else {
- src = "";
- }
- usrpath = k; /* User path segment length */
- debug(F111,"ftp get usrpath",src,usrpath);
-
- p = s; /* Server filename */
- while ((c = *p++)) { /* Look for path in server filename */
- if (ispathsep(c)) {
- /* haspath++; */
- nam = p; /* Pathless name (for ckmatch) */
- srvpath = p - s; /* Server path segment length */
- }
- }
- debug(F111,"ftp get srvpath",s,srvpath);
-
- if (usrpath == 0) {
-/*
- Here we handle the case where the user said "mget foo" where foo is a
- directory name, and the server is sending back names like "foo/file1",
- "foo/file2", etc. This is a nasty trick but it's necessary because the
- user can't compensate by typing "mget foo/" because then the server is
- likely to send back "foo//file1, foo//file2" etc, and we still won't
- get a match...
-*/
- int srclen = 0, srvlen = 0;
- if (src) srclen = strlen(src);
- if (s) srvlen = strlen(s);
- if (src && (srvlen > srclen)) {
- if (!strncmp(src,s,srclen) && ispathsep(s[srclen])) {
- char * tmpsrc = NULL;
- tmpsrc = (char *)malloc(srclen + 2);
- strncpy(tmpsrc,src,srclen);
- tmpsrc[srclen] = s[srclen];
- tmpsrc[srclen+1] = NUL;
- free(mgetlist[mgetx]);
- mgetlist[mgetx] = tmpsrc;
- tmpsrc = NULL;
- src = mgetlist[mgetx];
- usrpath = srclen+1;
- }
- }
- }
-/*
- If as-name not given and server filename includes path that matches
- the pathname from the user's file specification, we must trim the common
- path prefix from the server's name when constructing the local name.
-*/
- if (src && /* Wed Sep 25 17:27:48 2002 */
- !asnambuf[0] &&
- !recursive && /* Thu Sep 19 16:11:59 2002 */
- (srvpath > 0) &&
- !strncmp(src,s,usrpath)) {
- s2 = s + usrpath; /* Local name skips past remote path */
- }
-#ifdef COMMENT
- /* This doesn't work if the path prefix contains wildcards! */
- haspath = (srvpath > usrpath);
-#else
- { /* Count path segments instead */
- int x1 = 0, x2 = 0;
- char *p;
- for (p = s; *p; p++)
- if (ispathsep(*p)) x1++;
- for (p = src; *p; p++) {
- if (ispathsep(*p)) x2++;
- }
- haspath = recursive ? x1 || x2 : x1 > x2;
- debug(F111,"ftp get server path segments",s,x1);
- debug(F111,"ftp get user path segments",src,x2);
- }
-
-#endif /* COMMENT */
- debug(F111,"ftp get haspath",s+usrpath,haspath);
-
- if (haspath) { /* Server file has path segments? */
- if (!recursive) { /* [M]GET /RECURSIVE? */
-/*
- We did not ask for a recursive listing, but the server is sending us one
- anyway (as wu-ftpd is wont to do). We get here if the current filename
- includes a path segment beyond any path segment we asked for in our
- non-recursive [M]GET command. We MUST skip this file.
-*/
- debug(F111,"ftp get skipping because of path",s,0);
- continue;
- }
- }
- } else if (getone && !skipthis) { /* GET (not MGET) */
- char * p = nam;
- while ((c = *p++)) { /* Handle path in local name */
- if (ispathsep(c)) {
- if (recursive) { /* If recursive, keep it */
- haspath = 1;
- break;
- } else { /* Otherwise lose it. */
- nam = p;
- }
- }
- }
- s2 = nam;
- }
- if (!*nam) /* Name without path */
- nam = s;
-
- if (!skipthis && pv[SND_NOD].ival > 0) { /* /NODOTFILES */
- if (nam[0] == '.')
- continue;
- }
- if (!skipthis && rcvexcept[0]) { /* /EXCEPT: list */
- int xx;
- for (i = 0; i < NSNDEXCEPT; i++) {
- if (!rcvexcept[i]) {
- break;
- }
- xx = ckmatch(rcvexcept[i], nam, servertype == SYS_UNIX, 1);
- debug(F111,"ftp mget /except match",rcvexcept[i],xx);
- if (xx) {
- tlog(F100," refused: exception list","",0);
- msg = "Refused: Exception List";
- skipthis++;
- break;
- }
- }
- }
- if (!skipthis && pv[SND_NOB].ival > 0) { /* /NOBACKUPFILES */
- if (ckmatch(
-#ifdef CKREGEX
- "*.~[0-9]*~"
-#else
- "*.~*~"
-#endif /* CKREGEX */
- ,nam,0,1) > 0)
- continue;
- }
- if (!x_xla) { /* If translation is off */
- x_csl = -2; /* unset the charsets */
- x_csr = -2;
- }
- ckstrncpy(filnam,s,CKMAXPATH); /* For \v(filename) */
- if (!*s2) /* Local name */
- s2 = asnambuf; /* As-name */
-
- if (!*s2) /* Sat Nov 16 19:19:39 2002 */
- s2 = recursive ? s : nam; /* Fri Jan 10 13:15:19 2003 */
-
- debug(F110,"ftp get filnam ",s,0);
- debug(F110,"ftp get asname A",s2,0);
-
- /* Receiving to real file */
- if (!pipesend &&
-#ifdef PIPESEND
- !rcvfilter &&
-#endif /* PIPESEND */
- !toscreen) {
-#ifndef NOSPL
- /* Do this here so we can decide whether to skip */
- if (cmd_quoting && !skipthis && asnambuf[0]) {
- int n; char *p;
- n = TMPBUFSIZ;
- p = tmpbuf;
- zzstring(asnambuf,&p,&n);
- s2 = tmpbuf;
- debug(F111,"ftp get asname B",s2,updating);
- }
-#endif /* NOSPL */
-
- local = *s2 ? s2 : s;
-
- if (!skipthis && x_fnc == XYFX_D) { /* File Collision = Discard */
- int x;
- x = zchki(local);
- debug(F111,"ftp get DISCARD zchki",local,x);
- if (x > -1) {
- skipthis++;
- debug(F110,"ftp get skip name",local,0);
- tlog(F100," refused: name","",0);
- msg = "Refused: Name";
- }
- }
-
-#ifdef DOUPDATE
- if (!skipthis && updating) { /* If updating and not yet skipping */
- if (zchki(local) > -1) {
- x = chkmodtime(local,s,0);
-#ifdef DEBUG
- if (deblog) {
- if (updating == 2)
- debug(F111,"ftp get /dates-diff chkmodtime",local,x);
- else
- debug(F111,"ftp get /update chkmodtime",local,x);
- }
-#endif /* DEBUG */
- if ((updating == 1 && x > 0) || /* /UPDATE */
- (updating == 2 && x == 1)) { /* /DATES-DIFFER */
- skipthis++;
- tlog(F100," refused: date","",0);
- msg = "Refused: Date";
- debug(F110,"ftp get skip date",local,0);
- }
- }
- }
-#endif /* DOUPDATE */
- }
- /* Initialize file size to -1 in case server doesn't understand */
- /* SIZE command, so xxscreen() will know we don't know the size */
-
- fsize = -1L;
-
- /* Ask for size now only if we need it for selection */
- /* because if you're going thru a list 100,000 files to select */
- /* a small subset, 100,000 SIZE commands can take hours... */
-
- gotsize = 0;
- if (!mdel && !skipthis && /* Don't need size for DELE... */
- (getsmaller > -1L || getlarger > -1L)) {
- if (havesize > -1L) { /* Already have file size? */
- fsize = havesize;
- gotsize = 1;
- } else { /* No - must ask server */
- /*
- Prior to sending the NLST command we necessarily put the
- server into ASCII mode. We must now put it back into the
- the requested mode so the upcoming SIZE command returns
- right kind of size; this is especially important for
- GET /RECOVER; otherwise the server returns the "ASCII" size
- of the file, rather than its true size.
- */
- changetype(ftp_typ,0); /* Change to requested type */
- fsize = -1L;
- if (sizeok) {
- x = ftpcmd("SIZE",s,x_csl,x_csr,ftp_vbm);
- if (x == REPLY_COMPLETE) {
- fsize = atol(&ftp_reply_str[4]);
- gotsize = 1;
- }
- }
- }
- if (gotsize) {
- if (getsmaller > -1L && fsize >= getsmaller)
- skipthis++;
- if (getlarger > -1L && fsize <= getlarger)
- skipthis++;
- if (skipthis) {
- debug(F111,"ftp get skip size",s,fsize);
- tlog(F100," refused: size","",0);
- msg = "Refused: Size";
- }
-#ifdef COMMENT
- } else if (getone) {
- /* SIZE can fail for many reasons. Does the file exist? */
- x = ftpcmd("NLST",s,x_csl,x_csr,ftp_vbm);
- if (x != REPLY_COMPLETE) {
- printf(">>> FILE NOT FOUND: %s\n",s);
- break;
- }
-#endif /* COMMENT */
- }
- }
- if (skipthis) { /* Skipping this file? */
- ftscreen(SCR_FN,'F',0L,s);
- if (msg)
- ftscreen(SCR_ST,ST_ERR,0L,msg);
- else
- ftscreen(SCR_ST,ST_SKIP,0L,s);
- continue;
- }
- if (fp_nml) { /* /NAMELIST only - no transfer */
- fprintf(fp_nml,"%s\n",s);
- continue;
- }
- if (recursive && haspath && !pipesend
-#ifdef PIPESEND
- && !rcvfilter
-#endif /* PIPESEND */
- ) {
- int x;
-
-#ifdef NOMKDIR
- x = -1;
-#else
- x = zmkdir(s); /* Try to make the directory */
-#endif /* NOMKDIR */
-
- if (x < 0) {
- rc = -1; /* Failure is fatal */
- if (geterror) {
- status = 0;
- ftscreen(SCR_EM,0,0L,"Directory creation failure");
- break;
- }
- }
- }
-
- /* Not skipping */
-
- selected++; /* Count this file as selected */
- pn = NULL;
-
- if (!gotsize && !mdel) { /* Didn't get size yet */
- if (havesize > -1L) { /* Already have file size? */
- fsize = havesize;
- gotsize = 1;
- } else { /* No - must ask server */
- fsize = -1L;
- if (sizeok) {
- x = ftpcmd("SIZE",s,x_csl,x_csr,ftp_vbm);
- if (x == REPLY_COMPLETE) {
- fsize = atol(&ftp_reply_str[4]);
- gotsize = 1;
- }
- }
- }
- }
- if (mdel) { /* [M]DELETE */
- if (displa && !ftp_vbm)
- printf(" %s...",s);
- rc =
- (ftpcmd("DELE",s,x_csl,x_csr,ftp_vbm) == REPLY_COMPLETE) ? 1 : -1;
- if (rc > -1) {
- tlog(F110,"ftp mdelete",s,0);
- if (displa && !ftp_vbm)
- printf("OK\n");
- } else {
- tlog(F110,"ftp mdelete failed:",s,0);
- if (displa)
- printf("Failed\n");
- }
-#ifndef NOSPL
-#ifdef PIPESEND
- } else if (rcvfilter) { /* [M]GET with filter */
- int n; char * p;
- n = CKMAXPATH;
- p = tmpbuf; /* Safe - no asname with filter */
- zzstring(rcvfilter,&p,&n);
- if (n > -1)
- pn = tmpbuf;
- debug(F111,"ftp get rcvfilter",pn,n);
-#endif /* PIPESEND */
-#endif /* NOSPL */
- if (toscreen) s2 = "-";
- } else if (pipesend) { /* [M]GET /COMMAND */
- int n; char * p;
- n = CKMAXPATH;
- p = tmpbuf; /* Safe - no asname with filter */
- zzstring(pipename,&p,&n);
- if (n > -1)
- pn = tmpbuf;
- debug(F111,"ftp get pipename",pipename,n);
- if (toscreen) s2 = "-";
- } else { /* [M]GET with no pipes or filters */
- debug(F111,"ftp get s2 A",s2,x_cnv);
- if (toscreen) {
- s2 = "-"; /* (hokey convention for stdout) */
- } else if (!*s2) { /* No asname? */
- if (x_cnv) { /* If converting */
- nzrtol(s,tmpbuf,x_cnv,1,CKMAXPATH); /* convert */
- s2 = tmpbuf;
- debug(F110,"ftp get nzrtol",s2,0);
- } else /* otherwise */
- s2 = s; /* use incoming file's name */
- }
- debug(F110,"ftp get s2 B",s2,0);
-
- /* If local file already exists, take collision action */
-
- if (!pipesend &&
-#ifdef PIPESEND
- !rcvfilter &&
-#endif /* PIPESEND */
- !toscreen) {
- x = zchki(s2);
- debug(F111,"ftp get zchki",s2,x);
- debug(F111,"ftp get x_fnc",s2,x_fnc);
-
- if (x > -1 && !restart) {
- int x = -1;
- char * newname = NULL;
-
- switch (x_fnc) {
- case XYFX_A: /* Append */
- append = 1;
- break;
- case XYFX_R: /* Rename */
- case XYFX_B: /* Backup */
- znewn(s2,&newname); /* Make unique name */
- debug(F110,"ftp get znewn",newname,0);
- if (x_fnc == XYFX_B) { /* Backup existing file */
- x = zrename(s2,newname);
- debug(F111,"ftp get backup zrename",newname,x);
- } else { /* Rename incoming file */
- x = ckstrncpy(tmpbuf,newname,CKMAXPATH+1);
- s2 = tmpbuf;
- debug(F111,"ftp get rename incoming",newname,x);
- }
- if (x < 0) {
- ftscreen(SCR_EM,0,0L,"Backup/Rename failed");
- x = 0;
- goto xgetx;
- }
- break;
- case XYFX_D: /* Discard (already handled above) */
- case XYFX_U: /* Update (ditto) */
- case XYFX_M: /* Update (ditto) */
- case XYFX_X: /* Overwrite */
- break;
- }
- }
- }
- }
- if (!mdel) {
-#ifdef PIPESEND
- debug(F111,"ftp get pn",pn,rcvfilter ? 1 : 0);
-#endif /* PIPESEND */
- if (pipesend && !toscreen)
- s2 = NULL;
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"ftp get x_xla","",x_xla);
- debug(F101,"ftp get x_csl","",x_csl);
- debug(F101,"ftp get x_csr","",x_csr);
- debug(F101,"ftp get append","",append);
- }
-#endif /* DEBUG */
-
- rc = getfile(s,s2,restart,append,pn,x_xla,x_csl,x_csr);
-
-#ifdef DEBUG
- if (deblog) {
- debug(F111,"ftp get rc",s,rc);
- debug(F111,"ftp get cancelfile",s,cancelfile);
- debug(F111,"ftp get cancelgroup",s,cancelgroup);
- debug(F111,"ftp get renaming",s,renaming);
- }
-#endif /* DEBUG */
- }
- if (rc > -1) {
- good++;
- status = 1;
- if (!cancelfile) {
- if (deleting) { /* GET /DELETE (source file) */
- rc =
- (ftpcmd("DELE",s,x_csl,x_csr,ftp_vbm) == REPLY_COMPLETE)
- ? 1 : -1;
- tlog(F110, (rc > -1) ?
- " deleted" : " failed to delete", s, 0);
- } else if (renaming && rcv_rename && !toscreen) {
- char *p; /* Rename downloaded file */
-#ifndef NOSPL
- char tmpbuf[CKMAXPATH+1];
- int n;
- n = CKMAXPATH;
- p = tmpbuf;
- debug(F111,"ftp get /rename",rcv_rename,0);
- zzstring(rcv_rename,&p,&n);
- debug(F111,"ftp get /rename",rcv_rename,0);
- p = tmpbuf;
-#else
- p = rcv_rename;
-#endif /* NOSPL */
- rc = (zrename(s2,p) < 0) ? -1 : 1;
- debug(F111,"doftpget /RENAME zrename",p,rc);
- tlog(F110, (rc > -1) ?
- " renamed to" :
- " failed to rename to",
- p,
- 0
- );
- } else if (moving && rcv_move && !toscreen) {
- char *p; /* Move downloaded file */
-#ifndef NOSPL
- char tmpbuf[CKMAXPATH+1];
- int n;
- n = TMPBUFSIZ;
- p = tmpbuf;
- debug(F111,"ftp get /move-to",rcv_move,0);
- zzstring(rcv_move,&p,&n);
- p = tmpbuf;
-#else
- p = rcv_move;
-#endif /* NOSPL */
- debug(F111,"ftp get /move-to",p,0);
- rc = (zrename(s2,p) < 0) ? -1 : 1;
- debug(F111,"doftpget /MOVE zrename",p,rc);
- tlog(F110, (rc > -1) ?
- " moved to" : " failed to move to", p, 0);
- }
- if (pv[SND_SRN].ival > 0 && pv[SND_SRN].sval) {
- char * s = pv[SND_SRN].sval;
- char * srvrn = pv[SND_SRN].sval;
- char tmpbuf[CKMAXPATH+1];
-#ifndef NOSPL
- int y; /* Pass it thru the evaluator */
- extern int cmd_quoting; /* for \v(filename) */
- debug(F111,"ftp get srv_renam",s,1);
-
- if (cmd_quoting) {
- y = CKMAXPATH;
- s = (char *)tmpbuf;
- zzstring(srvrn,&s,&y);
- s = (char *)tmpbuf;
- }
-#endif /* NOSPL */
- debug(F111,"ftp get srv_renam",s,1);
- if (s) if (*s) {
- int x;
- x = ftp_rename(s2,s);
- debug(F111,"ftp get ftp_rename",s2,x);
- tlog(F110, (x > 0) ?
- " renamed source file to" :
- " failed to rename source file to",
- s,
- 0
- );
- if (x < 1)
- return(-1);
- }
- }
- }
- }
- if (cancelfile)
- continue;
- if (rc < 0) {
- ftp_fai++;
- if (geterror) {
- status = 0;
- ftscreen(SCR_EM,0,0L,"Fatal download error");
- done++;
- }
- }
- }
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"ftp get status","",status);
- debug(F101,"ftp get cancelgroup","",cancelgroup);
- debug(F101,"ftp get cancelfile","",cancelfile);
- debug(F101,"ftp get selected","",selected);
- debug(F101,"ftp get good","",good);
- }
-#endif /* DEBUG */
-
- if (selected == 0) { /* No files met selection criteria */
- status = 1; /* which is a kind of success. */
- } else if (status > 0) { /* Some files were selected */
- if (cancelgroup) /* but MGET was canceled */
- status = 0; /* so MGET failed */
- else if (cancelfile && good < 1) /* If file was canceled */
- status = 0; /* MGET failed if it got no files */
- }
- success = status;
- x = success;
- debug(F101,"ftp get success","",success);
-
- xgetx:
- pipesend = pipesave; /* Restore global pipe selection */
- if (fp_nml) { /* Close /NAMELIST */
- if (fp_nml != stdout)
- fclose(fp_nml);
- fp_nml = NULL;
- }
- if (x > -1) { /* Download successful */
-#ifdef GFTIMER
- t1 = gmstimer(); /* End time */
- sec = (CKFLOAT)((CKFLOAT)(t1 - t0) / 1000.0); /* Stats */
- if (!sec) sec = 0.001;
- fptsecs = sec;
-#else
- sec = (t1 - t0) / 1000;
- if (!sec) sec = 1;
-#endif /* GFTIMER */
- tfcps = (long) (tfc / sec);
- tsecs = (int)sec;
- lastxfer = W_FTP|W_RECV;
- xferstat = success;
- }
- if (dpyactive)
- ftscreen(SCR_TC,0,0L,"");
-#ifdef CK_TMPDIR
- if (f_tmpdir) { /* If we changed to download dir */
- zchdir((char *) savdir); /* Go back where we came from */
- f_tmpdir = 0;
- }
-#endif /* CK_TMPDIR */
-
- for (i = 0; i <= SND_MAX; i++) { /* Free malloc'd memory */
- if (pv[i].sval)
- free(pv[i].sval);
- }
- for (i = 0; i < mgetn; i++) /* MGET list too */
- makestr(&(mgetlist[i]),NULL);
-
- if (cancelgroup) /* Clear temp-file stack */
- mlsreset();
-
- ftreset(); /* Undo switch effects */
- dpyactive = 0;
- return(x);
-}
-
-static struct keytab ftprmt[] = {
- { "cd", XZCWD, 0 },
- { "cdup", XZCDU, 0 },
- { "cwd", XZCWD, CM_INV },
- { "delete", XZDEL, 0 },
- { "directory", XZDIR, 0 },
- { "exit", XZXIT, 0 },
- { "help", XZHLP, 0 },
- { "login", XZLGI, 0 },
- { "logout", XZLGO, 0 },
- { "mkdir", XZMKD, 0 },
- { "pwd", XZPWD, 0 },
- { "rename", XZREN, 0 },
- { "rmdir", XZRMD, 0 },
- { "type", XZTYP, 0 },
- { "", 0, 0 }
-};
-static int nftprmt = (sizeof(ftprmt) / sizeof(struct keytab)) - 1;
-
-int
-doftpsite() { /* Send a SITE command */
- int reply;
- char * s;
- int lcs = -1, rcs = -1;
-#ifndef NOCSETS
- if (ftp_xla) {
- lcs = ftp_csl;
- if (lcs < 0) lcs = fcharset;
- rcs = ftp_csx;
- if (rcs < 0) rcs = ftp_csr;
- }
-#endif /* NOCSETS */
- if ((x = cmtxt("Command", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if (testing) printf(" ftp site \"%s\"...\n",line);
- if ((reply = ftpcmd("SITE",line,lcs,rcs,ftp_vbm)) == REPLY_PRELIM) {
- do {
- reply = getreply(0,lcs,rcs,ftp_vbm,0);
- } while (reply == REPLY_PRELIM);
- }
- return(success = (reply == REPLY_COMPLETE));
-}
-
-
-int
-dosetftppsv() { /* Passive mode */
- x = seton(&ftp_psv);
- if (x > 0) passivemode = ftp_psv;
- return(x);
-}
-
-/* d o f t p r m t -- Parse and execute REMOTE commands */
-
-int
-doftprmt(cx,who) int cx, who; { /* who == 1 for ftp, 0 for kermit */
- /* cx == 0 means REMOTE */
- /* cx != 0 is a XZxxx value */
- char * s;
-
- if (who != 0)
- return(0);
-
- if (cx == 0) {
- if ((x = cmkey(ftprmt,nftprmt,"","",xxstring)) < 0)
- return(x);
- cx = x;
- }
- switch (cx) {
- case XZCDU: /* CDUP */
- if ((x = cmcfm()) < 0) return(x);
- return(doftpcdup());
-
- case XZCWD: /* RCD */
- if ((x = cmtxt("Remote directory", "", &s, xxstring)) < 0)
- return(x);
- ckstrncpy(line,s,LINBUFSIZ);
- return(doftpcwd((char *)line,1));
- case XZPWD: /* RPWD */
- return(doftppwd());
- case XZDEL: /* RDEL */
- return(doftpget(FTP_MDE,1));
- case XZDIR: /* RDIR */
- return(doftpdir(FTP_DIR));
- case XZHLP: /* RHELP */
- return(doftpxhlp());
- case XZMKD: /* RMKDIR */
- return(doftpmkd());
- case XZREN: /* RRENAME */
- return(doftpren());
- case XZRMD: /* RRMDIR */
- return(doftprmd());
- case XZLGO: /* LOGOUT */
- return(doftpres());
- case XZXIT: /* EXIT */
- return(ftpbye());
- }
- printf("?Not usable with FTP - \"%s\"\n", atmbuf);
- return(-9);
-}
-
-int
-doxftp() { /* Command parser for built-in FTP */
- int cx, n;
- struct FDB kw, fl;
- char * s;
- int usetls = 0;
- int lcs = -1, rcs = -1;
-
-#ifndef NOCSETS
- if (ftp_xla) {
- lcs = ftp_csl;
- if (lcs < 0) lcs = fcharset;
- rcs = ftp_csx;
- if (rcs < 0) rcs = ftp_csr;
- }
-#endif /* NOCSETS */
-
- if (inserver) /* FTP not allowed in IKSD. */
- return(-2);
-
- if (g_ftp_typ > -1) { /* Restore TYPE if saved */
- ftp_typ = g_ftp_typ;
- /* g_ftp_typ = -1; */
- }
-#ifdef COMMENT
-/*
- We'll set the collision action locally in doftpget() based on whether
- ftp_fnc was ever set to a value. if not, we'll use the fncact value.
-*/
- if (ftp_fnc < 0) /* Inherit global collision action */
- ftp_fnc = fncact; /* if none specified for FTP */
-#endif /* COMMENT */
-
- /* Restore global verbose mode */
- if (ftp_deb)
- ftp_vbm = 1;
- else if (quiet)
- ftp_vbm = 0;
- else
- ftp_vbm = ftp_vbx;
-
- ftp_dates &= 1; /* Undo any previous /UPDATE switch */
-
- dpyactive = 0; /* Reset global transfer-active flag */
- printlines = 0; /* Reset printlines */
-
- if (fp_nml) { /* Reset /NAMELIST */
- if (fp_nml != stdout)
- fclose(fp_nml);
- fp_nml = NULL;
- }
- makestr(&ftp_nml,NULL);
-
- cmfdbi(&kw, /* First FDB - commands */
- _CMKEY, /* fcode */
- "Hostname; or FTP command", /* help */
- "", /* default */
- "", /* addtl string data */
- nftpcmd, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2: none */
- xxstring, /* Processing function */
- ftpcmdtab, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* A host name or address */
- _CMFLD, /* fcode */
- "Hostname or address", /* help */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
- x = cmfdb(&kw); /* Parse a hostname or a keyword */
- if (x == -3) {
- printf("?ftp what? \"help ftp\" for hints\n");
- return(-9);
- }
- if (x < 0)
- return(x);
- if (cmresult.fcode == _CMFLD) { /* If hostname */
- return(openftp(cmresult.sresult,0)); /* go open the connection */
- } else {
- cx = cmresult.nresult;
- }
- switch (cx) {
- case FTP_ACC: /* ACCOUNT */
- if ((x = cmtxt("Remote account", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- makestr(&ftp_acc,s);
- if (testing)
- printf(" ftp account: \"%s\"\n",ftp_acc);
- success = (ftpcmd("ACCT",ftp_acc,-1,-1,ftp_vbm) == REPLY_COMPLETE);
- return(success);
-
- case FTP_GUP: /* Go UP */
- if ((x = cmcfm()) < 0) return(x);
- CHECKCONN();
- if (testing) printf(" ftp cd: \"(up)\"\n");
- return(success = doftpcdup());
-
- case FTP_CWD: /* CD */
- if ((x = cmtxt("Remote directory", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if (testing)
- printf(" ftp cd: \"%s\"\n", line);
- return(success = doftpcwd(line,1));
-
- case FTP_CHM: /* CHMOD */
- if ((x = cmfld("Permissions or protection code","",&s,xxstring)) < 0)
- return(x);
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- if ((x = cmtxt("Remote filename", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckmakmsg(ftpcmdbuf,FTP_BUFSIZ,tmpbuf," ",s,NULL);
- if (testing)
- printf(" ftp chmod: %s\n",ftpcmdbuf);
- success =
- (ftpcmd("SITE CHMOD",ftpcmdbuf,lcs,rcs,ftp_vbm) == REPLY_COMPLETE);
- return(success);
-
- case FTP_CLS: /* CLOSE FTP connection */
- if ((y = cmcfm()) < 0)
- return(y);
- CHECKCONN();
- if (testing)
- printf(" ftp closing...\n");
- ftpclose();
- return(success = 1);
-
- case FTP_DIR: /* DIRECTORY of remote files */
- case FTP_VDI:
- return(doftpdir(cx));
-
- case FTP_GET: /* GET a remote file */
- case FTP_RGE: /* REGET */
- case FTP_MGE: /* MGET */
- case FTP_MDE: /* MDELETE */
- return(doftpget(cx,1));
-
- case FTP_IDL: /* IDLE */
- if ((x = cmnum("Number of seconds","-1",10,&z,xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0)
- return(y);
- CHECKCONN();
- if (z < 0) { /* Display idle timeout */
- if (testing)
- printf(" ftp query idle timeout...\n");
- success = (ftpcmd("SITE IDLE",NULL,0,0,1) == REPLY_COMPLETE);
- } else { /* Set idle timeout */
- if (testing)
- printf(" ftp idle timeout set: %d...\n",z);
- success =
- (ftpcmd("SITE IDLE",ckitoa(z),0,0,1) == REPLY_COMPLETE);
- }
- return(success);
-
- case FTP_MKD: /* MKDIR */
- return(doftpmkd());
-
- case FTP_MOD: /* MODTIME */
- if ((x = cmtxt("Remote filename", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if (testing)
- printf(" ftp modtime \"%s\"...\n",line);
- success = 0;
- if (ftpcmd("MDTM",line,lcs,rcs,ftp_vbm) == REPLY_COMPLETE) {
- success = 1;
- mdtmok = 1;
- if (!quiet) {
- int flag = 0;
- char c, * s;
- struct tm tmremote;
-
- bzero((char *)&tmremote, sizeof(struct tm));
- s = ftp_reply_str;
- while ((c = *s++)) {
- if (c == SP) {
- flag++;
- break;
- }
- }
- if (flag) {
- if (sscanf(s, "%04d%02d%02d%02d%02d%02d",
- &tmremote.tm_year,
- &tmremote.tm_mon,
- &tmremote.tm_mday,
- &tmremote.tm_hour,
- &tmremote.tm_min,
- &tmremote.tm_sec
- ) == 6) {
- printf(" %s %04d-%02d-%02d %02d:%02d:%02d GMT\n",
- line,
- tmremote.tm_year,
- tmremote.tm_mon,
- tmremote.tm_mday,
- tmremote.tm_hour,
- tmremote.tm_min,
- tmremote.tm_sec
- );
- } else {
- success = 0;
- }
- }
- }
- }
- return(success);
-
- case FTP_OPN: /* OPEN connection */
-#ifdef COMMENT
- x = cmfld("IP hostname or address","",&s,xxstring);
- if (x < 0) {
- success = 0;
- return(x);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- return(openftp(s,0));
-#else
- { /* OPEN connection */
- char name[TTNAMLEN+1], *p;
- extern int network;
- extern char ttname[];
- if (network) /* If we have a current connection */
- ckstrncpy(name,ttname,LINBUFSIZ); /* get the host name */
- else
- *name = '\0'; /* as default host */
- for (p = name; *p; p++) /* Remove ":service" from end. */
- if (*p == ':') { *p = '\0'; break; }
-#ifndef USETLSTAB
- x = cmfld("IP hostname or address",name,&s,xxstring);
-#else
- cmfdbi(&kw, /* First FDB - commands */
- _CMKEY, /* fcode */
- "Hostname or switch", /* help */
- "", /* default */
- "", /* addtl string data */
- ntlstab, /* addtl numeric data 1: tbl size */
- 0, /* addtl numeric data 2: none */
- xxstring, /* Processing function */
- tlstab, /* Keyword table */
- &fl /* Pointer to next FDB */
- );
- cmfdbi(&fl, /* A host name or address */
- _CMFLD, /* fcode */
- "Hostname or address", /* help */
- "", /* default */
- "", /* addtl string data */
- 0, /* addtl numeric data 1 */
- 0, /* addtl numeric data 2 */
- xxstring,
- NULL,
- NULL
- );
-
- for (n = 0;; n++) {
- x = cmfdb(&kw); /* Parse a hostname or a keyword */
- if (x == -3) {
- printf("?ftp open what? \"help ftp\" for hints\n");
- return(-9);
- }
- if (x < 0)
- break;
- if (cmresult.fcode == _CMFLD) { /* Hostname */
- s = cmresult.sresult;
- break;
- } else if (cmresult.nresult == OPN_TLS) {
- usetls = 1;
- }
- }
-#endif /* USETLSTAB */
- if (x < 0) {
- success = 0;
- return(x);
- }
- ckstrncpy(line,s,LINBUFSIZ);
- s = line;
- return(openftp(s,usetls));
- }
-#endif /* COMMENT */
-
- case FTP_PUT: /* PUT */
- case FTP_MPU: /* MPUT */
- case FTP_APP: /* APPEND */
- return(doftpput(cx,1));
-
- case FTP_PWD: /* PWD */
- x = doftppwd();
- if (x > -1) success = x;
- return(x);
-
- case FTP_REN: /* RENAME */
- return(doftpren());
-
- case FTP_RES: /* RESET */
- return(doftpres());
-
- case FTP_HLP: /* (remote) HELP */
- return(doftpxhlp());
-
- case FTP_RMD: /* RMDIR */
- return(doftprmd());
-
- case FTP_STA: /* STATUS */
- if ((x = cmtxt("Command", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if (testing) printf(" ftp status \"%s\"...\n",line);
- success = (ftpcmd("STAT",line,lcs,rcs,1) == REPLY_COMPLETE);
- return(success);
-
- case FTP_SIT: { /* SITE */
- return(doftpsite());
- }
-
- case FTP_SIZ: /* (ask for) SIZE */
- if ((x = cmtxt("Remote filename", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if (testing)
- printf(" ftp size \"%s\"...\n",line);
- success = (ftpcmd("SIZE",line,lcs,rcs,1) == REPLY_COMPLETE);
- if (success)
- sizeok = 1;
- return(success);
-
- case FTP_SYS: /* Ask for server's SYSTEM type */
- if ((x = cmcfm()) < 0) return(x);
- CHECKCONN();
- if (testing)
- printf(" ftp system...\n");
- success = (ftpcmd("SYST",NULL,0,0,1) == REPLY_COMPLETE);
- return(success);
-
- case FTP_UMA: /* Set/query UMASK */
- if ((x = cmfld("Umask to set or nothing to query","",&s,xxstring)) < 0)
- if (x != -3)
- return(x);
- ckstrncpy(tmpbuf,s,TMPBUFSIZ);
- if ((x = cmcfm()) < 0) return(x);
- CHECKCONN();
- if (testing) {
- if (tmpbuf[0])
- printf(" ftp umask \"%s\"...\n",tmpbuf);
- else
- printf(" ftp query umask...\n");
- }
- success = ftp_umask(tmpbuf);
- return(success);
-
- case FTP_USR:
- return(doftpusr());
-
- case FTP_QUO:
- if ((x = cmtxt("FTP protocol command", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- success = (ftpcmd(s,NULL,0,0,ftp_vbm) == REPLY_COMPLETE);
- return(success);
-
- case FTP_TYP: /* Type */
- if ((x = cmkey(ftptyp,nftptyp,"","",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
- CHECKCONN();
- ftp_typ = x;
- g_ftp_typ = x;
- tenex = (ftp_typ == FTT_TEN);
- changetype(ftp_typ,ftp_vbm);
- return(1);
-
- case FTP_CHK: /* Check if remote file(s) exist(s) */
- if ((x = cmtxt("remote filename", "", &s, xxstring)) < 0)
- return(x);
- CHECKCONN();
- success = remote_files(1,(CHAR *)s,NULL,0) ? 1 : 0;
- return(success);
-
- case FTP_FEA: /* RFC2389 */
- if ((y = cmcfm()) < 0)
- return(y);
- CHECKCONN();
- success = (ftpcmd("FEAT",NULL,0,0,1) == REPLY_COMPLETE);
- if (success) {
- if (sfttab[0] > 0) {
- ftp_aut = sfttab[SFT_AUTH];
- sizeok = sfttab[SFT_SIZE];
- mdtmok = sfttab[SFT_MDTM];
- mlstok = sfttab[SFT_MLST];
- }
- }
- return(success);
-
- case FTP_OPT: /* RFC2389 */
- /* Perhaps this should be a keyword list... */
- if ((x = cmfld("FTP command","",&s,xxstring)) < 0)
- return(x);
- CHECKCONN();
- ckstrncpy(line,s,LINBUFSIZ);
- if ((x = cmtxt("Options for this command", "", &s, xxstring)) < 0)
- return(x);
- success = (ftpcmd("OPTS",line,lcs,rcs,ftp_vbm) == REPLY_COMPLETE);
- return(success);
-
- case FTP_ENA: /* FTP ENABLE */
- case FTP_DIS: /* FTP DISABLE */
- if ((x = cmkey(ftpenatab,nftpena,"","",xxstring)) < 0)
- return(x);
- if ((y = cmcfm()) < 0) return(y);
- switch (x) {
- case ENA_AUTH: /* OK to use autoauthentication */
- ftp_aut = (cx == FTP_ENA) ? 1 : 0;
- sfttab[SFT_AUTH] = ftp_aut;
- break;
- case ENA_FEAT: /* OK to send FEAT command */
- featok = (cx == FTP_ENA) ? 1 : 0;
- break;
- case ENA_MLST: /* OK to use MLST/MLSD */
- mlstok = (cx == FTP_ENA) ? 1 : 0;
- sfttab[SFT_MLST] = mlstok;
- break;
- case ENA_MDTM: /* OK to use MDTM */
- mdtmok = (cx == FTP_ENA) ? 1 : 0;
- sfttab[SFT_MDTM] = mdtmok;
- break;
- case ENA_SIZE: /* OK to use SIZE */
- sizeok = (cx == FTP_ENA) ? 1 : 0;
- sfttab[SFT_SIZE] = sizeok;
- break;
- }
- return(success = 1);
- }
- return(-2);
-}
-
-#ifndef NOSHOW
-static char *
-shopl(x) int x; {
- switch (x) {
- case FPL_CLR: return("clear");
- case FPL_PRV: return("private");
- case FPL_SAF: return("safe");
- case 0: return("(not set)");
- default: return("(unknown)");
- }
-}
-
-int
-shoftp(brief) {
- char * s = "?";
- int n, x;
-
- if (g_ftp_typ > -1) { /* Restore TYPE if saved */
- ftp_typ = g_ftp_typ;
- /* g_ftp_typ = -1; */
- }
- printf("\n");
- printf("FTP connection: %s\n",connected ?
- ftp_host :
- "(none)"
- );
- n = 2;
- if (connected) {
- n++;
- printf("FTP server type: %s\n",
- ftp_srvtyp[0] ? ftp_srvtyp : "(unknown)");
- }
- if (loggedin)
- printf("Logged in as: %s\n",
- strval(ftp_logname,"(unknown)"));
- else
- printf("Not logged in\n");
- n++;
- if (brief) return(0);
-
- printf("\nSET FTP values:\n\n");
- n += 3;
-
- printf(" ftp anonymous-password: %s\n",
- ftp_apw ? ftp_apw : "(default)"
- );
- printf(" ftp auto-login: %s\n",showoff(ftp_log));
- printf(" ftp auto-authentication: %s\n",showoff(ftp_aut));
- switch (ftp_typ) {
- case FTT_ASC: s = "text"; break;
- case FTT_BIN: s = "binary"; break;
- case FTT_TEN: s = "tenex"; break;
- }
- printf(" ftp type: %s\n",s);
- printf(" ftp get-filetype-switching: %s\n",showoff(get_auto));
- printf(" ftp dates: %s\n",showoff(ftp_dates));
- printf(" ftp error-action: %s\n",ftp_err ? "quit":"proceed");
- printf(" ftp filenames: %s\n",
- ftp_cnv == CNV_AUTO ? "auto" : (ftp_cnv ? "converted" : "literal")
- );
- printf(" ftp debug %s\n",showoff(ftp_deb));
-
- printf(" ftp passive-mode: %s\n",showoff(ftp_psv));
- printf(" ftp permissions: %s\n",showooa(ftp_prm));
- printf(" ftp verbose-mode: %s\n",showoff(ftp_vbx));
- printf(" ftp send-port-commands: %s\n",showoff(ftp_psv));
- printf(" ftp unique-server-names: %s\n",showoff(ftp_usn));
-#ifdef COMMENT
- /* See note in doxftp() */
- if (ftp_fnc < 0)
- ftp_fnc = fncact;
-#endif /* COMMENT */
- printf(" ftp collision: %s\n",
- fncnam[ftp_fnc > -1 ? ftp_fnc : fncact]);
- printf(" ftp server-time-offset: %s\n",
- fts_sto ? fts_sto : "(none)");
- n += 15;
-
-#ifndef NOCSETS
- printf(" ftp character-set-translation: %s\n",showoff(ftp_xla));
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
-
- printf(" ftp server-character-set: %s\n",fcsinfo[ftp_csr].keyword);
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
-
- printf(" file character-set: %s\n",fcsinfo[fcharset].keyword);
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
-#endif /* NOCSETS */
-
- x = ftp_dis;
- if (x < 0)
- x = fdispla;
- switch (x) {
- case XYFD_N: s = "none"; break;
- case XYFD_R: s = "serial"; break;
- case XYFD_C: s = "fullscreen"; break;
- case XYFD_S: s = "crt"; break;
- case XYFD_B: s = "brief"; break;
- }
- printf(" ftp display: %s\n",s);
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
-
- if (mlstok || featok || mdtmok || sizeok || ftp_aut) {
- printf(" enabled: ");
- if (ftp_aut) printf(" AUTH");
- if (featok) printf(" FEAT");
- if (mdtmok) printf(" MDTM");
- if (mlstok) printf(" MLST");
- if (sizeok) printf(" SIZE");
- printf("\n");
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
- }
- if (!mlstok || !featok || !mdtmok || !sizeok || !ftp_aut) {
- printf(" disabled: ");
- if (!ftp_aut) printf(" AUTH");
- if (!featok) printf(" FEAT");
- if (!mdtmok) printf(" MDTM");
- if (!mlstok) printf(" MLST");
- if (!sizeok) printf(" SIZE");
- printf("\n");
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
- }
- switch (ftpget) {
- case 0: s = "kermit"; break;
- case 1: s = "ftp"; break;
- case 2: s = "auto"; break;
- default: s = "?";
- }
- printf(" get-put-remote: %s\n",s);
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
-
- printf("\n");
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
-
-#ifdef FTP_SECURITY
- printf("Available security methods: ");
-#ifdef FTP_GSSAPI
- printf("GSSAPI ");
-#endif /* FTP_GSSAPI */
-#ifdef FTP_KRB4
- printf("Kerberos4 ");
-#endif /* FTP_KRB4 */
-#ifdef FTP_SRP
- printf("SRP ");
-#endif /* FTP_SRP */
-#ifdef FTP_SSL
- printf("SSL ");
-#endif /* FTP_SSL */
-
- n++;
- printf("\n\n");
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
- printf(" ftp authtype: %s\n",strval(auth_type,NULL));
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
- printf(" ftp auto-encryption: %s\n",showoff(ftp_cry));
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
- printf(" ftp credential-forwarding: %s\n",showoff(ftp_cfw));
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
- printf(" ftp command-protection-level: %s\n",shopl(ftp_cpl));
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
- printf(" ftp data-protection-level: %s\n",shopl(ftp_dpl));
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
- printf(" ftp secure proxy: %s\n",shopl(ssl_ftp_proxy));
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
-#else
- printf("Available security methods: (none)\n");
- if (++ n > cmd_rows-3) { if (!askmore()) return 0; else n = 0; }
-#endif /* FTP_SECURITY */
-
- if (n <= cmd_rows - 3)
- printf("\n");
- return(0);
-}
-#endif /* NOSHOW */
-
-#ifndef NOHELP
-/* FTP HELP text strings */
-
-static char * fhs_ftp[] = {
- "Syntax: FTP subcommand [ operands ]",
- " Makes an FTP connection, or sends a command to the FTP server.",
- " To see a list of available FTP subcommands, type \"ftp ?\".",
- " and then use HELP FTP xxx to get help about subcommand xxx.",
- " Also see HELP SET FTP, HELP SET GET-PUT-REMOTE, and HELP FIREWALL.",
- ""
-};
-
-static char * fhs_acc[] = { /* ACCOUNT */
- "Syntax: FTP ACCOUNT text",
- " Sends an account designator to an FTP server that needs one.",
- " Most FTP servers do not use accounts; some use them for other",
- " other purposes, such as disk-access passwords.",
- ""
-};
-static char * fhs_app[] = { /* APPEND */
- "Syntax: FTP APPEND filname",
- " Equivalent to [ FTP ] PUT /APPEND. See HELP FTP PUT.",
- ""
-};
-static char * fhs_cls[] = { /* BYE, CLOSE */
- "Syntax: [ FTP ] BYE",
- " Logs out from the FTP server and closes the FTP connection.",
- " Also see HELP SET GET-PUT-REMOTE. Synonym: [ FTP ] CLOSE.",
- ""
-};
-static char * fhs_cwd[] = { /* CD, CWD */
- "Syntax: [ FTP ] CD directory",
- " Asks the FTP server to change to the given directory.",
- " Also see HELP SET GET-PUT-REMOTE. Synonyms: [ FTP ] CWD, RCD, RCWD.",
- ""
-};
-static char * fhs_gup[] = { /* CDUP, UP */
- "Syntax: FTP CDUP",
- " Asks the FTP server to change to the parent directory of its current",
- " directory. Also see HELP SET GET-PUT-REMOTE. Synonym: FTP UP.",
- ""
-};
-static char * fhs_chm[] = { /* CHMOD */
- "Syntax: FTP CHMOD filename permissions",
- " Asks the FTP server to change the permissions, protection, or mode of",
- " the given file. The given permissions must be in the syntax of the",
- " the server's file system, e.g. an octal number for UNIX. Also see",
- " FTP PUT /PERMISSIONS",
- ""
-};
-static char * fhs_mde[] = { /* DELETE */
- "Syntax: FTP DELETE [ switches ] filespec",
- " Asks the FTP server to delete the given file or files.",
- " Synonym: MDELETE (Kermit makes no distinction between single and",
- " multiple file deletion). Optional switches:",
- " ",
- " /ERROR-ACTION:{PROCEED,QUIT}",
- " /EXCEPT:pattern",
- " /FILENAMES:{AUTO,CONVERTED,LITERAL}",
- " /LARGER-THAN:number",
-#ifdef UNIXOROSK
- " /NODOTFILES",
-#endif /* UNIXOROSK */
- " /QUIET",
-#ifdef RECURSIVE
- " /RECURSIVE (depends on server)",
- " /SUBDIRECTORIES",
-#endif /* RECURSIVE */
- " /SMALLER-THAN:number",
- ""
-};
-static char * fhs_dir[] = { /* DIRECTORY */
- "Syntax: FTP DIRECTORY [ filespec ]",
- " Asks the server to send a directory listing of the files that match",
- " the given filespec, or if none is given, all the files in its current",
- " directory. The filespec, including any wildcards, must be in the",
- " syntax of the server's file system. Also see HELP SET GET-PUT-REMOTE.",
- " Synonym: RDIRECTORY.",
- ""
-};
-static char * fhs_vdi[] = { /* VDIRECTORY */
- "Syntax: FTP VDIRECTORY [ filespec ]",
- " Asks the server to send a directory listing of the files that match",
- " the given filespec, or if none is given, all the files in its current",
- " directory. VDIRECTORY is needed for getting verbose directory",
- " listings from certain FTP servers, such as on TOPS-20. Try it if",
- " FTP DIRECTORY lists only filenames without details.",
- ""
-};
-static char * fhs_fea[] = { /* FEATURES */
- "Syntax: FTP FEATURES",
- " Asks the FTP server to list its special features. Most FTP servers",
- " do not recognize this command.",
- ""
-};
-static char * fhs_mge[] = { /* MGET */
- "Syntax: [ FTP ] MGET [ options ] filespec [ filespec [ filespec ... ] ]",
- " Download a single file or multiple files. Asks the FTP server to send",
- " the given file or files. Also see FTP GET. Optional switches:",
- " ",
- " /AS-NAME:text",
- " Name under which to store incoming file.",
- " Pattern required for for multiple files.",
- " /BINARY", /* /IMAGE */
- " Force binary mode. Synonym: /IMAGE.",
- " /COLLISION:{BACKUP,RENAME,UPDATE,DISCARD,APPEND,OVERWRITE}",
- " What to do if an incoming file has the same name as an existing file.",
-
-#ifdef PUTPIPE
- " /COMMAND",
- " Specifies that the as-name is a command to which the incoming file",
- " is to be piped as standard input.",
-#endif /* PUTPIPE */
-
-#ifdef DOUPDATE
- " /DATES-DIFFER",
- " Download only those files whose modification date-times differ from",
- " those of the corresponding local files, or that do not already",
- " exist on the local computer.",
-#endif /* DOUPDATE */
-
- " /DELETE",
- " Specifies that each file is to be deleted from the server after,",
- " and only if, it is successfully downloaded.",
- " /ERROR-ACTION:{PROCEED,QUIT}",
- " When downloading a group of files, what to do upon failure to",
- " transfer a file: quit or proceed to the next one.",
- " /EXCEPT:pattern",
- " Exception list: don't download any files that match this pattern.",
- " See HELP WILDCARD for pattern syntax.",
- " /FILENAMES:{AUTOMATIC,CONVERTED,LITERAL}",
- " Whether to convert incoming filenames to local syntax.",
-#ifdef PIPESEND
-#ifndef NOSPL
- " /FILTER:command",
- " Pass incoming files through the given command.",
-#endif /* NOSPL */
-#endif /* PIPESEND */
- " /LARGER-THAN:number",
- " Only download files that are larger than the given number of bytes.",
- " /LISTFILE:filename",
- " Obtain the list of files to download from the given file.",
-#ifndef NOCSETS
- " /LOCAL-CHARACTER-SET:name",
- " When downloading in text mode and character-set conversion is",
- " desired, this specifies the target set.",
-#endif /* NOCSETS */
- " /MATCH:pattern",
- " Specifies a pattern to be used to select filenames locally from the",
- " server's list.",
- " /MLSD",
- " Forces sending of MLSD (rather than NLST) to get the file list.",
-#ifdef CK_TMPDIR
- " /MOVE-TO:directory",
- " Each file that is downloaded is to be moved to the given local",
- " directory immediately after, and only if, it has been received",
- " successfully.",
-#endif /* CK_TMPDIR */
- " /NAMELIST:filename",
- " Instead of downloading the files, stores the list of files that",
- " would be downloaded in the given local file, one filename per line.",
- " /NLST",
- " Forces sending of NLST (rather than MLSD) to get the file list.",
- " /NOBACKUPFILES",
- " Don't download any files whose names end with .~<number>~.",
- " /NODOTFILES",
- " Don't download any files whose names begin with period (.).",
- " /QUIET",
- " Suppress the file-transfer display.",
-#ifdef FTP_RESTART
- " /RECOVER", /* /RESTART */
- " Resume a download that was previously interrupted from the point of",
- " failure. Works only in binary mode. Not supported by all servers.",
- " Synonym: /RESTART.",
-#endif /* FTP_RESTART */
-#ifdef RECURSIVE
- " /RECURSIVE", /* /SUBDIRECTORIES */
- " Create subdirectories automatically if the server sends files",
- " recursively and includes pathnames (most don't).",
-#endif /* RECURSIVE */
- " /RENAME-TO:text",
- " Each file that is downloaded is to be renamed as indicated just,",
- " after, and only if, it has arrived successfully.",
-#ifndef NOCSETS
- " /SERVER-CHARACTER-SET:name",
- " When downloading in text mode and character-set conversion is desired"
-, " this specifies the original file's character set on the server.",
-#endif /* NOCSETS */
- " /SERVER-RENAME:text",
- " Each server source file is to be renamed on the server as indicated",
- " immediately after, but only if, it has arrived succesfully.",
- " /SMALLER-THAN:number",
- " Download only those files smaller than the given number of bytes.",
- " /TEXT", /* /ASCII */
- " Force text mode. Synonym: /ASCII.",
- " /TENEX",
- " Force TENEX (TOPS-20) mode (see HELP SET FTP TYPE).",
-#ifndef NOCSETS
- " /TRANSPARENT",
- " When downloading in text mode, do not convert chracter-sets.",
-#endif /* NOCSETS */
- " /TO-SCREEN",
- " The downloaded file is to be displayed on the screen.",
-#ifdef DOUPDATE
- " /UPDATE",
- " Equivalent to /COLLISION:UPDATE. Download only those files that are",
- " newer than than their local counterparts, or that do not exist on",
- " the local computer.",
-#endif /* DOUPDATE */
- ""
-};
-static char * fhs_hlp[] = { /* HELP */
- "Syntax: FTP HELP [ command [ subcommand... ] ]",
- " Asks the FTP server for help about the given command. First use",
- " FTP HELP by itself to get a list of commands, then use HELP FTP xxx",
- " to get help for command \"xxx\". Synonyms: REMOTE HELP, RHELP.",
- ""
-};
-static char * fhs_idl[] = { /* IDLE */
- "Syntax: FTP IDLE [ number ]",
- " If given without a number, this asks the FTP server to tell its",
- " current idle-time limit. If given with a number, it asks the server",
- " to change its idle-time limit to the given number of seconds.",
- ""
-};
-static char * fhs_usr[] = { /* USER, LOGIN */
- "Syntax: FTP USER username [ password [ account ] ]",
- " Log in to the FTP server. To be used when connected but not yet",
- " logged in, e.g. when SET FTP AUTOLOGIN is OFF or autologin failed.",
- " If you omit the password, and one is required by the server, you are",
- " prompted for it. If you omit the account, no account is sent.",
- " Synonym: FTP LOGIN.",
- ""
-};
-static char * fhs_get[] = { /* GET */
- "Syntax: [ FTP ] GET [ options ] filename [ as-name ]",
- " Download a single file. Asks the FTP server to send the given file.",
- " The optional as-name is the name to store it under when it arrives;",
- " if omitted, the file is stored with the name it arrived with, as",
- " modified according to the FTP FILENAMES setting or /FILENAMES: switch",
- " value. Aside from the file list and as-name, syntax and options are",
- " the same as for FTP MGET, which is used for downloading multiple files."
-, ""
-};
-static char * fhs_mkd[] = { /* MKDIR */
- "Syntax: FTP MKDIR directory",
- " Asks the FTP server to create a directory with the given name,",
- " which must be in the syntax of the server's file system. Synonyms:",
- " REMOTE MKDIR, RMKDIR.",
- ""
-};
-static char * fhs_mod[] = { /* MODTIME */
- "Syntax: FTP MODTIME filename",
- " Asks the FTP server to send the modification time of the given file,",
- " to be displayed on the screen. The date-time format is all numeric:",
- " yyyymmddhhmmssxxx... (where xxx... is 0 or more digits indicating",
- " fractions of seconds).",
- ""
-};
-static char * fhs_mpu[] = { /* MPUT */
- "Syntax: [ FTP ] MPUT [ switches ] filespec [ filespec [ filespec ... ] ]",
- " Uploads files. Sends the given file or files to the FTP server.",
- " Also see FTP PUT. Optional switches are:",
- " ",
- " /AFTER:date-time",
- " Uploads only those files newer than the given date-time.",
- " HELP DATE for info about date-time formats. Synonym: /SINCE.",
-#ifdef PUTARRAY
- " /ARRAY:array-designator",
- " Tells Kermit to upload the contents of the given array, rather than",
- " a file.",
-#endif /* PUTARRAY */
- " /AS-NAME:text",
- " Name under which to send files.",
- " Pattern required for for multiple files.",
- " /BEFORE:date-time",
- " Upload only those files older than the given date-time.",
- " /BINARY",
- " Force binary mode. Synonym: /IMAGE.",
-#ifdef PUTPIPE
- " /COMMAND",
- " Specifies that the filespec is a command whose standard output is",
- " to be sent.",
-#endif /* PUTPIPE */
-
-#ifdef COMMENT
-#ifdef DOUPDATE
- " /DATES-DIFFER",
- " Upload only those files whose modification date-times differ from",
- " those on the server, or that don't exist on the server at all.",
-#endif /* DOUPDATE */
-#endif /* COMMENT */
-
- " /DELETE",
- " Specifies that each source file is to be deleted after, and only if,",
- " it is successfully uploaded.",
- " /DOTFILES",
- " Include files whose names begin with period (.).",
- " /ERROR-ACTION:{PROCEED,QUIT}",
- " When uploading a group of files, what to do upon failure to",
- " transfer a file: quit or proceed to the next one.",
- " /EXCEPT:pattern",
- " Exception list: don't upload any files that match this pattern.",
- " See HELP WILDCARD for pattern syntax.",
- " /FILENAMES:{AUTOMATIC,CONVERTED,LITERAL}",
- " Whether to convert outbound filenames to common syntax.",
-#ifdef PIPESEND
-#ifndef NOSPL
- " /FILTER:command",
- " Pass outbound files through the given command.",
-#endif /* NOSPL */
-#endif /* PIPESEND */
-#ifdef CKSYMLINK
- " /FOLLOWINKS",
- " Send files that are pointed to by symbolic links.",
- " /NOFOLLOWINKS",
- " Skip over symbolic links (default).",
-#endif /* CKSYMLINK */
- " /LARGER-THAN:number",
- " Only upload files that are larger than the given number of bytes.",
- " /LISTFILE:filename",
- " Obtain the list of files to upload from the given file.",
-#ifndef NOCSETS
- " /LOCAL-CHARACTER-SET:name",
- " When uploading in text mode and character-set conversion is",
- " desired, this specifies the source-file character set.",
-#endif /* NOCSETS */
-#ifdef CK_TMPDIR
- " /MOVE-TO:directory",
- " Each source file that is uploaded is to be moved to the given local",
- " directory when, and only if, the transfer is successful.",
-#endif /* CK_TMPDIR */
- " /NOBACKUPFILES",
- " Don't upload any files whose names end with .~<number>~.",
-#ifdef UNIXOROSK
- " /NODOTFILES",
- " Don't upload any files whose names begin with period (.).",
-#endif /* UNIXOROSK */
- " /NOT-AFTER:date-time",
- " Upload only files that are not newer than the given date-time",
- " /NOT-BEFORE:date-time",
- " Upload only files that are not older than the given date-time",
-#ifdef UNIX
- " /PERMISSIONS",
- " Ask the server to set the permissions of each file it receives",
- " according to the source file's permissions.",
-#endif /* UNIX */
- " /QUIET",
- " Suppress the file-transfer display.",
-#ifdef FTP_RESTART
- " /RECOVER",
- " Resume an upload that was previously interrupted from the point of",
- " failure. Synonym: /RESTART.",
-#endif /* FTP_RESTART */
-#ifdef RECURSIVE
- " /RECURSIVE",
- " Send files from the given directory and all the directories beneath",
- " it. Synonym: /SUBDIRECTORIES.",
-#endif /* RECURSIVE */
- " /RENAME-TO:text",
- " Each source file that is uploaded is to be renamed on the local",
- " local computer as indicated when and only if, the transfer completes",
- " successfully.",
-#ifndef NOCSETS
- " /SERVER-CHARACTER-SET:name",
- " When uploading in text mode and character-set conversion is desired,",
- " this specifies the character set to which the file should be",
- " converted for storage on the server.",
-#endif /* NOCSETS */
- " /SERVER-RENAME:text",
- " Each file that is uploaded is to be renamed as indicated on the",
- " server after, and only if, if arrives successfully.",
- " /SIMULATE",
- " Show which files would be sent without actually sending them.",
- " /SMALLER-THAN:number",
- " Upload only those files smaller than the given number of bytes.",
- " /TEXT",
- " Force text mode. Synonym: /ASCII.",
- " /TENEX",
- " Force TENEX (TOPS-20) mode (see HELP SET FTP TYPE).",
-#ifndef NOCSETS
- " /TRANSPARENT",
- " When uploading in text mode, do not convert chracter-sets.",
-#endif /* NOCSETS */
- " /TYPE:{TEXT,BINARY}",
- " Upload only files of the given type.",
-#ifdef DOUPDATE
- " /UPDATE",
- " If a file of the same name exists on the server, upload only if",
- " the local file is newer.",
-#endif /* DOUPDATE */
- " /UNIQUE-SERVER-NAMES",
- " Ask the server to compute new names for any incoming file that has",
- " the same name as an existing file.",
- ""
-};
-static char * fhs_opn[] = { /* OPEN */
-#ifdef CK_SSL
- "Syntax: FTP [ OPEN ] [ { /SSL, /TLS } ] hostname [ port ] [ switches ]",
- " Opens a connection to the FTP server on the given host. The default",
- " TCP port is 21 (990 if SSL/TLS is used), but a different port number",
- " can be supplied if necessary. Optional switches are:",
-#else /* CK_SSL */
- "Syntax: FTP [ OPEN ] hostname [ port ] [ switches ]",
- " Opens a connection to the FTP server on the given host. The default",
- " TCP port is 21, but a different port number can be supplied if",
- " necessary. Optional switches are:",
-#endif /* CK_SSL */
- " ",
- " /ANONYMOUS",
- " Logs you in anonymously.",
- " /USER:text",
- " Supplies the given text as your username.",
- " /PASSWORD:text",
- " Supplies the given text as your password. If you include a username",
- " but omit this switch and the server requires a password, you are",
- " prompted for it.",
- " /ACCOUNT:text",
- " Supplies the given text as your account, if required by the server.",
- " /ACTIVE",
- " Forces an active (rather than passive) connection.",
- " /PASSIVE",
- " Forces a passive (rather than active) connection.",
- " /NOINIT",
- " Inhibits sending initial REST, STRU, and MODE commands, which are",
- " well-known standard commands, but to which some servers react badly.",
- " /NOLOGIN",
- " Inhibits autologin for this connection only.",
- ""
-};
-static char * fhs_opt[] = { /* OPTS, OPTIONS */
- "Syntax: FTP OPTIONS",
- " Asks the FTP server to list its current options. Advanced, new,",
- " not supported by most FTP servers.",
- ""
-};
-static char * fhs_put[] = { /* PUT, SEND */
- "Syntax: [ FTP ] PUT [ switches ] filespec [ as-name ]",
- " Like FTP MPUT, but only one filespec is allowed, and if it is followed",
- " by an additional field, this is interpreted as the name under which",
- " to send the file or files. See HELP FTP MPUT.",
- ""
-};
-static char * fhs_pwd[] = { /* PWD */
- "Syntax: FTP PWD",
- " Asks the FTP server to reveal its current working directory.",
- " Synonyms: REMOTE PWD, RPWD.",
- ""
-};
-static char * fhs_quo[] = { /* QUOTE */
- "Syntax: FTP QUOTE text",
- " Sends an FTP protocol command to the FTP server. Use this command",
- " for sending commands that Kermit might not support.",
- ""
-};
-static char * fhs_rge[] = { /* REGET */
- "Syntax: FTP REGET",
- " Synonym for FTP GET /RECOVER.",
- ""
-};
-static char * fhs_ren[] = { /* RENAME */
- "Syntax: FTP RENAME name1 name1",
- " Asks the FTP server to change the name of the file whose name is name1",
- " and which resides in the FTP server's file system, to name2. Works",
- " only for single files; wildcards are not accepted.",
- ""
-};
-static char * fhs_res[] = { /* RESET */
- "Syntax: FTP RESET",
- " Asks the server to log out your session, terminating your access",
- " rights, without closing the connection.",
- ""
-};
-static char * fhs_rmd[] = { /* RMDIR */
- "Syntax: FTP RMDIR directory",
- " Asks the FTP server to remove the directory whose name is given.",
- " This usually requires the directory to be empty. Synonyms: REMOTE",
- " RMDIR, RRMDIR.",
- ""
-};
-static char * fhs_sit[] = { /* SITE */
- "Syntax: FTP SITE text",
- " Sends a site-specific command to the FTP server.",
- ""
-};
-static char * fhs_siz[] = { /* SIZE */
- "Syntax: FTP SIZE filename",
- " Asks the FTP server to send a numeric string representing the size",
- " of the given file.",
- ""
-};
-static char * fhs_sta[] = { /* STATUS */
- "Syntax: FTP STATUS [ filename ]",
- " Asks the FTP server to report its status. If a filename is given,",
- " the FTP server should report details about the file.",
- ""
-};
-static char * fhs_sys[] = { /* SYSTEM */
- "Syntax: FTP SYSTEM",
- " Asks the FTP server to report its operating system type.",
- ""
-};
-static char * fhs_typ[] = { /* TYPE */
- "Syntax: FTP TYPE { TEXT, BINARY, TENEX }",
- " Puts the client and server in the indicated transfer mode.",
- " ASCII is a synonym for TEXT. TENEX is used only for uploading 8-bit",
- " binary files to a 36-bit platforms such as TENEX or TOPS-20 and/or",
- " downloading files from TENEX or TOPS-20 that have been uploaded in",
- " TENEX mode.",
- ""
-};
-static char * fhs_uma[] = { /* UMASK */
- "Syntax: FTP UMASK number",
- " Asks the FTP server to set its file creation mode mask. Applies",
- " only (or mainly) to UNIX-based FTP servers.",
- ""
-};
-static char * fhs_chk[] = { /* CHECK */
- "Syntax: FTP CHECK remote-filespec",
- " Asks the FTP server if the given file or files exist. If the",
- " remote-filespec contains wildcards, this command fails if no server",
- " files match, and succeeds if at least one file matches. If the",
- " remote-filespec does not contain wildcards, this command succeeds if",
- " the given file exists and fails if it does not.",
- ""
-};
-static char * fhs_ena[] = { /* ENABLE */
- "Syntax: FTP ENABLE { AUTH, FEAT, MDTM, MLST, SIZE }",
- " Enables the use of the given FTP protocol command in case it has been",
- " disabled (but this is no guarantee that the FTP server understands it)."
-,
- " Use SHOW FTP to see which of these commands is enabled and disabled.",
- " Also see FTP DISABLE.",
- ""
-};
-static char * fhs_dis[] = { /* DISABLE */
- "Syntax: FTP DISABLE { AUTH, FEAT, MDTM, MLST, SIZE }",
- " Disables the use of the given FTP protocol command.",
- " Also see FTP ENABLE.",
- ""
-};
-
-#endif /* NOHELP */
-
-int
-doftphlp() {
- int cx;
- if ((cx = cmkey(ftpcmdtab,nftpcmd,"","",xxstring)) < 0)
- if (cx != -3)
- return(cx);
- if ((x = cmcfm()) < 0)
- return(x);
-
-#ifdef NOHELP
- printf("Sorry, no help available\n");
-#else
- switch (cx) {
- case -3:
- return(hmsga(fhs_ftp));
- case FTP_ACC: /* ACCOUNT */
- return(hmsga(fhs_acc));
- case FTP_APP: /* APPEND */
- return(hmsga(fhs_app));
- case FTP_CLS: /* BYE, CLOSE */
- return(hmsga(fhs_cls));
- case FTP_CWD: /* CD, CWD */
- return(hmsga(fhs_cwd));
- case FTP_GUP: /* CDUP, UP */
- return(hmsga(fhs_gup));
- case FTP_CHM: /* CHMOD */
- return(hmsga(fhs_chm));
- case FTP_MDE: /* DELETE, MDELETE */
- return(hmsga(fhs_mde));
- case FTP_DIR: /* DIRECTORY */
- return(hmsga(fhs_dir));
- case FTP_VDI: /* VDIRECTORY */
- return(hmsga(fhs_vdi));
- case FTP_FEA: /* FEATURES */
- return(hmsga(fhs_fea));
- case FTP_GET: /* GET */
- return(hmsga(fhs_get));
- case FTP_HLP: /* HELP */
- return(hmsga(fhs_hlp));
- case FTP_IDL: /* IDLE */
- return(hmsga(fhs_idl));
- case FTP_USR: /* USER, LOGIN */
- return(hmsga(fhs_usr));
- case FTP_MGE: /* MGET */
- return(hmsga(fhs_mge));
- case FTP_MKD: /* MKDIR */
- return(hmsga(fhs_mkd));
- case FTP_MOD: /* MODTIME */
- return(hmsga(fhs_mod));
- case FTP_MPU: /* MPUT */
- return(hmsga(fhs_mpu));
- case FTP_OPN: /* OPEN */
- return(hmsga(fhs_opn));
- case FTP_OPT: /* OPTS, OPTIONS */
- return(hmsga(fhs_opt));
- case FTP_PUT: /* PUT, SEND */
- return(hmsga(fhs_put));
- case FTP_PWD: /* PWD */
- return(hmsga(fhs_pwd));
- case FTP_QUO: /* QUOTE */
- return(hmsga(fhs_quo));
- case FTP_RGE: /* REGET */
- return(hmsga(fhs_rge));
- case FTP_REN: /* RENAME */
- return(hmsga(fhs_ren));
- case FTP_RES: /* RESET */
- return(hmsga(fhs_res));
- case FTP_RMD: /* RMDIR */
- return(hmsga(fhs_rmd));
- case FTP_SIT: /* SITE */
- return(hmsga(fhs_sit));
- case FTP_SIZ: /* SIZE */
- return(hmsga(fhs_siz));
- case FTP_STA: /* STATUS */
- return(hmsga(fhs_sta));
- case FTP_SYS: /* SYSTEM */
- return(hmsga(fhs_sys));
- case FTP_TYP: /* TYPE */
- return(hmsga(fhs_typ));
- case FTP_UMA: /* UMASK */
- return(hmsga(fhs_uma));
- case FTP_CHK: /* CHECK */
- return(hmsga(fhs_chk));
- case FTP_ENA:
- return(hmsga(fhs_ena));
- case FTP_DIS:
- return(hmsga(fhs_dis));
- default:
- printf("Sorry, help available for this command.\n");
- break;
- }
-#endif /* NOHELP */
- return(success = 0);
-}
-
-int
-dosetftphlp() {
- int cx;
- if ((cx = cmkey(ftpset,nftpset,"","",xxstring)) < 0)
- if (cx != -3)
- return(cx);
- if (cx != -3)
- ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ);
- if ((x = cmcfm()) < 0)
- return(x);
-
-#ifdef NOHELP
- printf("Sorry, no help available\n");
-#else
- switch (cx) {
- case -3:
- printf("\nSyntax: SET FTP parameter value\n");
- printf(" Type \"help set ftp ?\" for a list of parameters.\n");
- printf(" Type \"help set ftp xxx\" for information about setting\n");
- printf(" parameter xxx. Type \"show ftp\" for current values.\n\n");
- return(0);
-
- case FTS_BUG:
- printf("\nSyntax: SET FTP BUG <name> {ON, OFF}\n");
- printf(
- " Activates a workaround for the named bug in the FTP server.\n");
- printf(" Type SET FTP BUG ? for a list of names.\n");
- printf(" For each bug, the default is OFF\n\n");
- return(0);
-
-#ifdef FTP_SECURITY
- case FTS_ATP: /* "authtype" */
- printf("\nSyntax: SET FTP AUTHTYPE list\n");
- printf(" Specifies an ordered list of authentication methods to be\n"
- );
- printf(" when FTP AUTOAUTHENTICATION is ON. The default list is:\n");
- printf(" GSSAPI-KRB5, SRP, KERBEROS_V4, TLS, SSL.\n\n");
- return(0);
-
- case FTS_AUT: /* "autoauthentication" */
- printf("\nSyntax:SET FTP AUTOAUTHENTICATION { ON, OFF }\n");
- printf(" Tells whether authentication should be negotiated by the\n");
- printf(" FTP OPEN command. Default is ON.\n\n");
- break;
-
- case FTS_CRY: /* "autoencryption" */
- printf("\nSET FTP AUTOENCRYPTION { ON, OFF }\n");
- printf(" Tells whether encryption (privacy) should be negotiated\n");
- printf(" by the FTP OPEN command. Default is ON.\n\n");
- break;
-#endif /* FTP_SECURITY */
-
- case FTS_LOG: /* "autologin" */
- printf("\nSET FTP AUTOLOGIN { ON, OFF }\n");
- printf(" Tells Kermit whether to try to log you in automatically\n");
- printf(" as part of the connection process.\n\n");
- break;
-
- case FTS_DIS:
- printf("\nSET FTP DISPLAY { BRIEF, FULLSCREEN, CRT, ... }\n");
- printf(" Chooses the file-transfer display style for FTP.\n");
- printf(" Like SET TRANSFER DISPLAY but applies only to FTP.\n\n");
- break;
-
-#ifndef NOCSETS
- case FTS_XLA: /* "character-set-translation" */
- printf("\nSET FTP CHARACTER-SET-TRANSLATION { ON, OFF }\n");
- printf(" Whether to translate character sets when transferring\n");
- printf(" text files with FTP. OFF by default.\n\n");
- break;
-
-#endif /* NOCSETS */
- case FTS_FNC: /* "collision" */
- printf("\n");
- printf(
-"Syntax: SET FTP COLLISION { BACKUP,RENAME,UPDATE,DISCARD,APPEND,OVERWRITE }\n"
- );
- printf(" Tells what do when an incoming file has the same name as\n");
- printf(" an existing file when downloading with FTP.\n\n");
- break;
-
-#ifdef FTP_SECURITY
- case FTS_CPL: /* "command-protection-level" */
- printf("\n");
- printf(
-"Syntax: SET FTP COMMAND-PROTECTION-LEVEL { CLEAR,CONFIDENTIAL,PRIVATE,SAFE }"
- );
- printf("\n");
- printf(
-" Tells what level of protection is applied to the FTP command channel.\n\n");
- break;
- case FTS_CFW: /* "credential-forwarding" */
- printf("\nSyntax: SET FTP CREDENTIAL-FORWARDING { ON, OFF }\n");
- printf(" Tells whether end-user credentials are to be forwarded\n");
- printf(" to the server if supported by the authentication method\n");
- printf(" (GSSAPI-KRB5 only).\n\n");
- break;
- case FTS_DPL: /* "data-protection-level" */
- printf("\n");
- printf(
-"Syntax: SET FTP DATA-PROTECTION-LEVEL { CLEAR,CONFIDENTIAL,PRIVATE,SAFE }"
- );
- printf("\n");
- printf(
-" Tells what level of protection is applied to the FTP data channel.\n\n");
- break;
-#endif /* FTP_SECURITY */
-
- case FTS_DBG: /* "debug" */
- printf("\nSyntax: SET FTP DEBUG { ON, OFF }\n");
- printf(" Whether to print FTP protocol messages.\n\n");
- return(0);
-
- case FTS_ERR: /* "error-action" */
- printf("\nSyntax: SET FTP ERROR-ACTION { QUIT, PROCEED }\n");
- printf(" What to do when an error occurs when transferring a group\n")
- ;
- printf(" of files: quit and fail, or proceed to the next file.\n\n");
- return(0);
-
- case FTS_CNV: /* "filenames" */
- printf("\nSyntax: SET FTP FILENAMES { AUTO, CONVERTED, LITERAL }\n");
- printf(" What to do with filenames: convert them, take and use them\n"
- );
- printf(" literally; or choose what to do automatically based on the\n"
- );
- printf(" OS type of the server. The default is AUTO.\n\n");
- return(0);
-
- case FTS_PSV: /* "passive-mode" */
- printf("\nSyntax: SET FTP PASSIVE-MODE { ON, OFF }\n");
- printf(" Whether to use passive mode, which helps to get through\n");
- printf(" firewalls. ON by default.\n\n");
- return(0);
-
- case FTS_PRM: /* "permissions" */
- printf("\nSyntax: SET FTP PERMISSIONS { AUTO, ON, OFF }\n");
- printf(" Whether to try to send file permissions when uploading.\n");
- printf(" OFF by default. AUTO means only if client and server\n");
- printf(" have the same OS type.\n\n");
- return(0);
-
- case FTS_TST: /* "progress-messages" */
- printf("\nSyntax: SET FTP PROGRESS-MESSAGES { ON, OFF }\n");
- printf(" Whether Kermit should print locally-generated feedback\n");
- printf(" messages for each non-file-transfer command.");
- printf(" ON by default.\n\n");
- return(0);
-
- case FTS_SPC: /* "send-port-commands" */
- printf("\nSyntax: SET FTP SEND-PORT-COMMANDS { ON, OFF }\n");
- printf(" Whether Kermit should send a new PORT command for each");
- printf(" task.\n\n");
- return(0);
-
-#ifndef NOCSETS
- case FTS_CSR: /* "server-character-set" */
- printf("\nSyntax: SET FTP SERVER-CHARACTER-SET name\n");
- printf(" The name of the character set used for text files on the\n");
- printf(" server. Enter a name of '?' for a menu.\n\n");
- return(0);
-#endif /* NOCSETS */
-
- case FTS_STO: /* "server-time-offset */
- printf(
-"\nSyntax: SET FTP SERVER-TIME-OFFSET +hh[:mm[:ss]] or -hh[:mm[:ss]]\n");
- printf(
-" Specifies an offset to apply to the server's file timestamps.\n");
- printf(
-" Use this to correct for misconfigured server time or timezone.\n");
- printf(
-" Format: must begin with + or - sign. Hours must be given; minutes\n");
- printf(
-" and seconds are optional: +4 = +4:00 = +4:00:00 (add 4 hours).\n\n");
- return(0);
-
- case FTS_TYP: /* "type" */
- printf("\nSyntax: SET FTP TYPE { TEXT, BINARY, TENEX }\n");
- printf(" Establishes the default transfer mode.\n");
- printf(" TENEX is used for uploading 8-bit binary files to 36-bit\n");
- printf(" platforms such as TENEX and TOPS-20 and for downloading\n");
- printf(" them again.\n\n");
- return(0);
-
-#ifdef PATTERNS
- case FTS_GFT:
- printf("\nSyntax: SET FTP GET-FILETYPE-SWITCHING { ON, OFF }\n");
- printf(" Tells whether GET and MGET should automatically switch\n");
- printf(" the appropriate file type, TEXT, BINARY, or TENEX, by\n");
- printf(" matching the name of each incoming file with its list of\n");
- printf(" FILE TEXT-PATTERNS and FILE BINARY-PATTERNS. ON by\n");
- printf(" default. SHOW PATTERNS displays the current pattern\n");
- printf(" list. HELP SET FILE to see how to change it.\n");
- break;
-#endif /* PATTERNS */
-
- case FTS_USN: /* "unique-server-names" */
- printf("\nSyntax: SET FTP UNIQUE-SERVER-NAMES { ON, OFF }\n");
- printf(" Tells whether to ask the server to create unique names\n");
- printf(" for any uploaded file that has the same name as an\n");
- printf(" existing file. Default is OFF.\n\n");
- return(0);
-
- case FTS_VBM: /* "verbose-mode" */
- printf("\nSyntax: SET FTP VERBOSE-MODE { ON, OFF }\n");
- printf(" Whether to display all responses from the FTP server.\n");
- printf(" OFF by default.\n\n");
- return(0);
-
- case FTS_DAT:
- printf("\nSyntax: SET FTP DATES { ON, OFF }\n");
- printf(" Whether to set date of incoming files from the file date\n");
- printf(" on the server. ON by default. Note: there is no way to\n")
- ;
- printf(" set the date on files uploaded to the server. Also note\n");
- printf(" that not all servers support this feature.\n\n");
- return(0);
-
- case FTS_APW:
- printf("\nSyntax: SET FTP ANONYMOUS-PASSWORD [ text ]\n");
- printf(" Password to supply automatically on anonymous FTP\n");
- printf(" connections instead of the default user@host.\n");
- printf(" Omit optional text to restore default.\n\n");
- return(0);
-
- default:
- printf("Sorry, help not available for \"set ftp %s\"\n",tmpbuf);
- }
-#endif /* NOHELP */
- return(0);
-}
-
-#ifndef L_SET
-#define L_SET 0
-#endif /* L_SET */
-#ifndef L_INCR
-#define L_INCR 1
-#endif /* L_INCR */
-
-#ifdef FTP_SRP
-char srp_user[BUFSIZ]; /* where is BUFSIZ defined? */
-char *srp_pass;
-char *srp_acct;
-#endif /* FTP_SRP */
-
-static int kerror; /* Needed for all auth types */
-
-static struct sockaddr_in hisctladdr;
-static struct sockaddr_in hisdataaddr;
-static struct sockaddr_in data_addr;
-static int data = -1;
-static int ptflag = 0;
-static struct sockaddr_in myctladdr;
-
-#ifdef COMMENT
-#ifndef OS2
-UID_T getuid();
-#endif /* OS2 */
-#endif /* COMMENT */
-
-
-static int cpend = 0; /* No pending replies */
-
-#ifdef CK_SSL
-extern SSL *ssl_ftp_con;
-extern SSL_CTX *ssl_ftp_ctx;
-extern SSL *ssl_ftp_data_con;
-extern int ssl_ftp_active_flag;
-extern int ssl_ftp_data_active_flag;
-#endif /* CK_SSL */
-
-/* f t p c m d -- Send a command to the FTP server */
-/*
- Call with:
- char * cmd: The command to send.
- char * arg: The argument (e.g. a filename).
- int lcs: The local character set index.
- int rcs: The remote (server) character set index.
- int vbm: Verbose mode:
- 0 = force verbosity off
- >0 = force verbosity on
-
- If arg is given (not NULL or empty) and lcs != rcs and both are > -1,
- and neither lcs or rcs is UCS-2, the arg is translated from the local
- character set to the remote one before sending the result to the server.
-
- Returns:
- 0 on failure with ftpcode = -1
- >= 0 on success (getreply() result) with ftpcode = 0.
-*/
-static char xcmdbuf[RFNBUFSIZ];
-
-static int
-ftpcmd(cmd,arg,lcs,rcs,vbm) char * cmd, * arg; int lcs, rcs, vbm; {
- char * s = NULL;
- int r = 0, x = 0, fc = 0, len = 0, cmdlen = 0, q = -1;
- sig_t oldintr;
-
- if (ftp_deb) /* DEBUG */
- vbm = 1;
- else if (quiet || dpyactive) /* QUIET or File Transfer Active */
- vbm = 0;
- else if (vbm < 0) /* VERBOSE */
- vbm = ftp_vbm;
-
- cancelfile = 0;
- if (!cmd) cmd = "";
- if (!arg) arg = "";
- cmdlen = (int)strlen(cmd);
- len = cmdlen + (int)strlen(arg) + 1;
-
- if (ftp_deb /* && !dpyactive */ ) {
-#ifdef FTP_PROXY
- if (ftp_prx) printf("%s ", ftp_host);
-#endif /* FTP_PROXY */
- printf("---> ");
- if (!anonymous && strcmp("PASS",cmd) == 0)
- printf("PASS XXXX");
- else
- printf("%s %s",cmd,arg);
- printf("\n");
- }
- /* bzero(xcmdbuf,RFNBUFSIZ); */
- ckmakmsg(xcmdbuf,RFNBUFSIZ, cmd, *arg ? " " : "", arg, NULL);
-
-#ifdef DEBUG
- if (deblog) {
- debug(F110,"ftpcmd cmd",cmd,0);
- debug(F110,"ftpcmd arg",arg,0);
- debug(F101,"ftpcmd lcs","",lcs);
- debug(F101,"ftpcmd rcs","",rcs);
- }
-#endif /* DEBUG */
-
- if (csocket == -1) {
- perror("No control connection for command");
- ftpcode = -1;
- return(0);
- }
- havesigint = 0;
- oldintr = signal(SIGINT, cmdcancel);
-
-#ifndef NOCSETS
- if (*arg && /* If an arg was given */
- lcs > -1 && /* and a local charset */
- rcs > -1 && /* and a remote charset */
- lcs != rcs && /* and the two are not the same */
- lcs != FC_UCS2 && /* and neither one is UCS-2 */
- rcs != FC_UCS2 /* ... */
- ) {
- initxlate(lcs,rcs); /* Translate arg from lcs to rcs */
- xgnbp = arg; /* Global pointer to input string */
- rfnptr = rfnbuf; /* Global pointer to output buffer */
-
- while (1) {
- if ((c0 = xgnbyte(FC_UCS2,lcs,strgetc)) < 0) break;
- if (xpnbyte(c0,TC_UCS2,rcs,strputc) < 0) break;
- }
- /*
- We have to copy here instead of translating directly into
- xcmdbuf[] so strputc() can check length. Alternatively we could
- write yet another xpnbyte() output function.
- */
- if ((int)strlen(rfnbuf) > (RFNBUFSIZ - (cmdlen+1))) {
- printf("?FTP command too long: %s + arg\n",cmd);
- ftpcode = -1;
- return(0);
- }
- x = ckstrncpy(&xcmdbuf[cmdlen+1], rfnbuf, RFNBUFSIZ - (cmdlen+1));
- }
-#endif /* NOCSETS */
-
- s = xcmdbuf; /* Command to send to server */
-
-#ifdef DEBUG
- if (deblog) { /* Log it */
- if (!anonymous && !ckstrcmp(s,"PASS ",5,0)) {
- /* But don't log passwords */
- debug(F110,"FTP SENT ","PASS XXXX",0);
- } else {
- debug(F110,"FTP SENT ",s,0);
- }
- }
-#endif /* DEBUG */
-
-#ifdef CK_ENCRYPTION
- again:
-#endif /* CK_ENCRYPTION */
- if (scommand(s) == 0) { /* Send it. */
- signal(SIGINT, oldintr);
- return(0);
- }
- cpend = 1;
- x = !strcmp(cmd,"QUIT"); /* Is it the QUIT command? */
- if (x) /* In case we're interrupted */
- connected = 0; /* while waiting for the reply... */
-
- fc = 0; /* Function code for getreply() */
- if (!strncmp(cmd,"AUTH ",5) /* Must parse AUTH reply */
-#ifdef FTPHOST
- && strncmp(cmd, "HOST ",5)
-#endif /* FTPHOST */
- ) {
- fc = GRF_AUTH;
- } else if (!ckstrcmp(cmd,"FEAT",-1,0)) { /* Must parse FEAT reply */
- fc = GRF_FEAT; /* But FEAT not widely understood */
- if (!ftp_deb) /* So suppress error messages */
- vbm = 9;
- }
- r = getreply(x, /* Expect connection to close */
- lcs,rcs, /* Charsets */
- vbm, /* Verbosity */
- fc /* Function code */
- );
- if (q > -1)
- quiet = q;
-
-#ifdef CK_ENCRYPTION
- if (ftpcode == 533 && ftp_cpl == FPL_PRV) {
- fprintf(stderr,
- "ENC command not supported at server; retrying under MIC...\n");
- ftp_cpl = FPL_SAF;
- goto again;
- }
-#endif /* CK_ENCRYPTION */
-#ifdef COMMENT
- if (cancelfile && oldintr != SIG_IGN)
- (*oldintr)(SIGINT);
-#endif /* COMMENT */
- signal(SIGINT, oldintr);
- return(r);
-}
-
-static VOID
-lostpeer() {
- debug(F100,"lostpeer","",0);
- if (connected) {
- if (csocket != -1) {
-#ifdef CK_SSL
- if (ssl_ftp_active_flag) {
- SSL_shutdown(ssl_ftp_con);
- SSL_free(ssl_ftp_con);
- ssl_ftp_proxy = 0;
- ssl_ftp_active_flag = 0;
- ssl_ftp_con = NULL;
- }
-#endif /* CK_SSL */
-#ifdef TCPIPLIB
- socket_close(csocket);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(csocket, 1+1);
-#endif /* USE_SHUTDOWN */
- close(csocket);
-#endif /* TCPIPLIB */
- csocket = -1;
- }
- if (data != -1) {
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- SSL_shutdown(ssl_ftp_data_con);
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_active_flag = 0;
- ssl_ftp_data_con = NULL;
- }
-#endif /* CK_SSL */
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = -1;
- }
- connected = 0;
- anonymous = 0;
- loggedin = 0;
- auth_type = NULL;
- ftp_cpl = ftp_dpl = FPL_CLR;
-#ifdef CKLOGDIAL
- ftplogend();
-#endif /* CKLOGDIAL */
-
-#ifdef LOCUS
- if (autolocus) /* Auotomatic locus switching... */
- setlocus(1,1); /* Switch locus to local. */
-#endif /* LOCUS */
-#ifdef OS2
- DialerSend(OPT_KERMIT_HANGUP, 0);
-#endif /* OS2 */
- }
-#ifdef FTP_PROXY
- pswitch(1);
- if (connected) {
- if (csocket != -1) {
-#ifdef TCPIPLIB
- socket_close(csocket);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(csocket, 1+1);
-#endif /* USE_SHUTDOWN */
- close(csocket);
-#endif /* TCPIPLIB */
- csocket = -1;
- }
- connected = 0;
- anonymous = 0;
- loggedin = 0;
- auth_type = NULL;
- ftp_cpl = ftp_dpl = FPL_CLR;
- }
- proxflag = 0;
- pswitch(0);
-#endif /* FTP_PROXY */
-}
-
-int
-ftpisopen() {
- return(connected);
-}
-
-static int
-ftpclose() {
- extern int quitting;
- if (!connected)
- return(0);
- if (!ftp_vbm && !quiet) printlines = 1;
- ftpcmd("QUIT",NULL,0,0,ftp_vbm);
- if (csocket) {
-#ifdef CK_SSL
- if (ssl_ftp_active_flag) {
- SSL_shutdown(ssl_ftp_con);
- SSL_free(ssl_ftp_con);
- ssl_ftp_proxy = 0;
- ssl_ftp_active_flag = 0;
- ssl_ftp_con = NULL;
- }
-#endif /* CK_SSL */
-#ifdef TCPIPLIB
- socket_close(csocket);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(csocket, 1+1);
-#endif /* USE_SHUTDOWN */
- close(csocket);
-#endif /* TCPIPLIB */
- }
- csocket = -1;
- connected = 0;
- anonymous = 0;
- loggedin = 0;
- mdtmok = 1;
- sizeok = 1;
- featok = 1;
- stouarg = 1;
- typesent = 0;
- data = -1;
- globaldin = -1;
-#ifdef FTP_PROXY
- if (!proxy)
- macnum = 0;
-#endif /* FTP_PROXY */
- auth_type = NULL;
- ftp_dpl = FPL_CLR;
-#ifdef CKLOGDIAL
- ftplogend();
-#endif /* CKLOGDIAL */
-#ifdef LOCUS
- /* Unprefixed file management commands are executed locally */
- if (autolocus && !ftp_cmdlin && !quitting) {
- setlocus(1,1);
- }
-#endif /* LOCUS */
-#ifdef OS2
- DialerSend(OPT_KERMIT_HANGUP, 0);
-#endif /* OS2 */
- return(0);
-}
-
-int
-ftpopen(remote, service, use_tls) char * remote, * service; int use_tls; {
- char * host;
-
- if (connected) {
- printf("?Already connected to %s, use FTP CLOSE first.\n", ftp_host);
- ftpcode = -1;
- return(0);
- }
-#ifdef FTPHOST
- hostcmd = 0;
-#endif /* FTPHOST */
- alike = 0;
- ftp_srvtyp[0] = NUL;
- if (!service) service = "";
- if (!*service) service = use_tls ? "ftps" : "ftp";
-
- if (!isdigit(service[0])) {
- struct servent *destsp;
- destsp = getservbyname(service, "tcp");
- if (!destsp) {
- if (!ckstrcmp(service,"ftp",-1,0)) {
- ftp_port = 21;
- } else if (!ckstrcmp(service,"ftps",-1,0)) {
- ftp_port = 990;
- } else {
- printf("?Bad port name - \"%s\"\n", service);
- ftpcode = -1;
- return(0);
- }
- } else {
- ftp_port = destsp->s_port;
- ftp_port = ntohs(ftp_port);
- }
- } else
- ftp_port = atoi(service);
- if (ftp_port <= 0) {
- printf("?Bad port name - \"%s\"\n", service);
- ftpcode = -1;
- return(0);
- }
- host = ftp_hookup(remote, ftp_port, use_tls);
- if (host) {
- ckstrncpy(ftp_user_host,remote,MAX_DNS_NAMELEN);
- connected = 1; /* Set FTP defaults */
- ftp_cpl = ftp_dpl = FPL_CLR;
- curtype = FTT_ASC; /* Server uses ASCII mode */
- form = FORM_N;
- mode = MODE_S;
- stru = STRU_F;
- strcpy(bytename, "8");
- bytesize = 8;
-
-#ifdef FTP_SECURITY
- if (ftp_aut) {
- if (ftp_auth()) {
- if (ftp_cry
-#ifdef OS2
- && ck_crypt_is_installed()
-#endif /* OS2 */
- ) {
- if (!quiet)
- printf("FTP Command channel is Private (encrypted)\n");
- ftp_cpl = FPL_PRV;
- if (setpbsz(DEFAULT_PBSZ) < 0) {
- /* a failure here is most likely caused by a mixup */
- /* in the session key used by client and server */
- printf("?Protection buffer size negotiation failed\n");
- return(0);
- }
- if (ftpcmd("PROT P",NULL,0,0,ftp_vbm) == REPLY_COMPLETE) {
- if (!quiet)
- printf("FTP Data channel is Private (encrypted)\n");
- ftp_dpl = FPL_PRV;
- } else
- printf("?Unable to enable encryption on data channel\n");
- } else {
- ftp_cpl = FPL_SAF;
- }
- }
- if (!connected)
- goto fail;
- }
-#endif /* FTP_SECURITY */
- if (ftp_log) /* ^^^ */
- ftp_login(remote);
-
- if (!connected)
- goto fail;
-
-#ifdef CKLOGDIAL
- dologftp();
-#endif /* CKLOGDIAL */
-#ifdef OS2
- DialerSend(OPT_KERMIT_CONNECT, 0);
-#endif /* OS2 */
- passivemode = ftp_psv;
- sendport = ftp_spc;
- mdtmok = 1;
- sizeok = 1;
- stouarg = 1;
- typesent = 0;
-
- if (ucbuf == NULL) {
- actualbuf = DEFAULT_PBSZ;
- while (actualbuf && (ucbuf = (CHAR *)malloc(actualbuf)) == NULL)
- actualbuf >>= 2;
- }
- if (!maxbuf)
- ucbufsiz = actualbuf - FUDGE_FACTOR;
- debug(F101,"ftpopen ucbufsiz","",ucbufsiz);
- return(1);
- }
- fail:
- printf("?Can't FTP connect to %s:%s\n",remote,service);
- ftpcode = -1;
- return(0);
-}
-
-#ifdef CK_SSL
-int
-ssl_auth() {
- int i;
- char* p;
-
- if (ssl_debug_flag) {
- fprintf(stderr,"SSL DEBUG ACTIVE\n");
- fflush(stderr);
- /* for the moment I want the output on screen */
- }
- if (ssl_ftp_data_con != NULL) {
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_con = NULL;
- }
- if (ssl_ftp_con != NULL) {
- SSL_free(ssl_ftp_con);
- ssl_ftp_con=NULL;
- }
- if (ssl_ftp_ctx != NULL) {
- SSL_CTX_free(ssl_ftp_ctx);
- ssl_ftp_ctx = NULL;
- }
-
- /* The SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
- * was added to OpenSSL 0.9.6e and 0.9.7. It does not exist in previous
- * versions
- */
-#ifndef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
-#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0L
-#endif
- if (auth_type && !strcmp(auth_type,"TLS")) {
- ssl_ftp_ctx=SSL_CTX_new(SSLv3_client_method());
- if (!ssl_ftp_ctx)
- return(0);
- SSL_CTX_set_options(ssl_ftp_ctx,
- SSL_OP_SINGLE_DH_USE|SSL_OP_EPHEMERAL_RSA
- );
- } else {
- ssl_ftp_ctx = SSL_CTX_new(ftp_bug_use_ssl_v2 ? SSLv23_client_method() :
- SSLv3_client_method());
- if (!ssl_ftp_ctx)
- return(0);
- SSL_CTX_set_options(ssl_ftp_ctx,
- (ftp_bug_use_ssl_v2 ? 0 : SSL_OP_NO_SSLv2)|
- SSL_OP_SINGLE_DH_USE|SSL_OP_EPHEMERAL_RSA
- );
- }
- SSL_CTX_set_default_passwd_cb(ssl_ftp_ctx,
- (pem_password_cb *)ssl_passwd_callback);
- SSL_CTX_set_info_callback(ssl_ftp_ctx,ssl_client_info_callback);
- SSL_CTX_set_session_cache_mode(ssl_ftp_ctx,SSL_SESS_CACHE_CLIENT);
-
-#ifdef OS2
-#ifdef NT
- /* The defaults in the SSL crypto library are not appropriate for OS/2 */
- {
- char path[CKMAXPATH];
- extern char exedir[];
-
- ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL);
- if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,NULL,path) == 0) {
- debug(F110,"ftp ssl_auth unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-dir: %s\r\n",path);
- }
-
- ckmakmsg(path,CKMAXPATH,
- (char *)GetAppData(1),"kermit 95/certs",NULL,NULL);
- if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,NULL,path) == 0) {
- debug(F110,"ftp ssl_auth unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-dir: %s\r\n",path);
- }
-
- ckmakmsg(path,CKMAXPATH,
- (char *)GetAppData(0),"kermit 95/certs",NULL,NULL);
- if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,NULL,path) == 0) {
- debug(F110,"ftp ssl_auth unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-dir: %s\r\n",path);
- }
-
- ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL);
- if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,path,NULL) == 0) {
- debug(F110,"ftp ssl_auth unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-file: %s\r\n",path);
- }
-
- ckmakmsg(path,CKMAXPATH,(char *)GetAppData(1),
- "kermit 95/ca_certs.pem",NULL,NULL);
- if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,path,NULL) == 0) {
- debug(F110,"ftp ssl_auth unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-file: %s\r\n",path);
- }
-
- ckmakmsg(path,CKMAXPATH,(char *)GetAppData(0),
- "kermit 95/ca_certs.pem",NULL,NULL);
- if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,path,NULL) == 0) {
- debug(F110,"ftp ssl_auth unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-file: %s\r\n",path);
- }
- }
-#else /* NT */
- /* The defaults in the SSL crypto library are not appropriate for OS/2 */
- {
-
- char path[CKMAXPATH];
- extern char exedir[];
-
- ckmakmsg(path,CKMAXPATH,exedir,"certs",NULL,NULL);
- if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,NULL,path) == 0) {
- debug(F110,"ftp ssl_auth unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-dir: %s\r\n",path);
- }
- ckmakmsg(path,CKMAXPATH,exedir,"ca_certs.pem",NULL,NULL);
- if (SSL_CTX_load_verify_locations(ssl_ftp_ctx,path,NULL) == 0) {
- debug(F110,"ftp ssl_auth unable to load path",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load verify-file: %s\r\n",path);
- }
- }
-#endif /* NT */
-#else /* OS2 */
- SSL_CTX_set_default_verify_paths(ssl_ftp_ctx);
-#endif /* OS2 */
-
- if (ssl_verify_file &&
- SSL_CTX_load_verify_locations(ssl_ftp_ctx,ssl_verify_file,NULL) == 0) {
- debug(F110,
- "ftp ssl auth unable to load ssl_verify_file",
- ssl_verify_file,
- 0
- );
- if (ssl_debug_flag)
- printf("?Unable to load verify-file: %s\r\n",ssl_verify_file);
- }
- if (ssl_verify_dir &&
- SSL_CTX_load_verify_locations(ssl_ftp_ctx,NULL,ssl_verify_dir) == 0) {
- debug(F110,
- "ftp ssl auth unable to load ssl_verify_dir",
- ssl_verify_dir,
- 0
- );
- if (ssl_debug_flag)
- printf("?Unable to load verify-dir: %s\r\n",ssl_verify_dir);
- }
-
- /* set up the new CRL Store */
- crl_store = (X509_STORE *)X509_STORE_new();
- if (crl_store) {
-#ifdef OS2
- char path[CKMAXPATH];
- extern char exedir[];
-
- ckmakmsg(path,CKMAXPATH,exedir,"crls",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,NULL,path) == 0) {
- debug(F110,"ftp ssl auth unable to load dir",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-dir: %s\r\n",path);
- }
-#ifdef NT
- ckmakmsg(path,CKMAXPATH,
- (char *)GetAppData(1),"kermit 95/crls",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,NULL,path) == 0) {
- debug(F110,"ftp ssl auth unable to load dir",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-dir: %s\r\n",path);
- }
- ckmakmsg(path,CKMAXPATH,
- (char *)GetAppData(0),"kermit 95/crls",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,NULL,path) == 0) {
- debug(F110,"ftp ssl auth unable to load dir",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-dir: %s\r\n",path);
- }
-#endif /* NT */
-
- ckmakmsg(path,CKMAXPATH,exedir,"ca_crls.pem",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,path,NULL) == 0) {
- debug(F110,"ftp ssl auth unable to load file",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-file: %s\r\n",path);
- }
-#ifdef NT
- ckmakmsg(path,CKMAXPATH,(char *)GetAppData(1),
- "kermit 95/ca_crls.pem",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,path,NULL) == 0) {
- debug(F110,"ftp ssl auth unable to load file",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-file: %s\r\n",path);
- }
- ckmakmsg(path,CKMAXPATH,(char *)GetAppData(0),
- "kermit 95/ca_crls.pem",NULL,NULL);
- if (X509_STORE_load_locations(crl_store,path,NULL) == 0) {
- debug(F110,"ftp ssl auth unable to load file",path,0);
- if (ssl_debug_flag)
- printf("?Unable to load crl-file: %s\r\n",path);
- }
-#endif /* NT */
-#endif /* OS2 */
-
- if (ssl_crl_file || ssl_crl_dir) {
- if (ssl_crl_file &&
- X509_STORE_load_locations(crl_store,ssl_crl_file,NULL) == 0) {
- debug(F110,
- "ftp ssl auth unable to load ssl_crl_file",
- ssl_crl_file,
- 0
- );
- if (ssl_debug_flag)
- printf("?Unable to load crl-file: %s\r\n",ssl_crl_file);
- }
- if (ssl_crl_dir &&
- X509_STORE_load_locations(crl_store,NULL,ssl_crl_dir) == 0) {
- debug(F110,
- "ftp ssl auth unable to load ssl_crl_dir",
- ssl_crl_dir,
- 0
- );
- if (ssl_debug_flag)
- printf("?Unable to load crl-dir: %s\r\n",ssl_crl_dir);
- }
- } else {
- X509_STORE_set_default_paths(crl_store);
- }
- }
- SSL_CTX_set_verify(ssl_ftp_ctx,ssl_verify_flag,
- ssl_client_verify_callback);
- ssl_verify_depth = -1;
- ssl_ftp_con=(SSL *)SSL_new(ssl_ftp_ctx);
- tls_load_certs(ssl_ftp_ctx,ssl_ftp_con,0);
- SSL_set_fd(ssl_ftp_con,csocket);
- SSL_set_verify(ssl_ftp_con,ssl_verify_flag,NULL);
- if (ssl_cipher_list) {
- SSL_set_cipher_list(ssl_ftp_con,ssl_cipher_list);
- } else {
- char * p;
- if (p = getenv("SSL_CIPHER")) {
- SSL_set_cipher_list(ssl_ftp_con,p);
- } else {
- SSL_set_cipher_list(ssl_ftp_con,DEFAULT_CIPHER_LIST);
- }
- }
- if (ssl_debug_flag) {
- fprintf(stderr,"=>START SSL/TLS connect on COMMAND\n");
- fflush(stderr);
- }
- if (SSL_connect(ssl_ftp_con) <= 0) {
- static char errbuf[1024];
- ckmakmsg(errbuf,1024,"ftp: SSL/TLS connect COMMAND error: ",
- ERR_error_string(ERR_get_error(),NULL),NULL,NULL);
- fprintf(stderr,"%s\n", errbuf);
- fflush(stderr);
- ssl_ftp_active_flag=0;
- SSL_free(ssl_ftp_con);
- ssl_ftp_con = NULL;
- } else {
- ssl_ftp_active_flag = 1;
-
- if (!ssl_certsok_flag && !tls_is_krb5(1)) {
- char *subject = ssl_get_subject_name(ssl_ftp_con);
-
- if (!subject) {
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
- debug(F110,"ssl_auth","[SSL - FAILED]",0);
- return(ssl_ftp_active_flag = 0);
- } else {
- if (uq_ok("Warning: Server didn't provide a certificate\n",
- "Continue? (Y/N)",3,NULL,0) <= 0) {
- debug(F110, "ssl_auth","[SSL - FAILED]",0);
- return(ssl_ftp_active_flag = 0);
- }
- }
- } else if (ssl_check_server_name(ssl_ftp_con, ftp_user_host)) {
- debug(F110,"ssl_auth","[SSL - FAILED]",0);
- return(ssl_ftp_active_flag = 0);
- }
- }
- debug(F110,"ssl_auth","[SSL - OK]",0);
- ssl_display_connect_details(ssl_ftp_con,0,ssl_verbose_flag);
- }
- if (ssl_debug_flag) {
- fprintf(stderr,"=>DONE SSL/TLS connect on COMMAND\n");
- fflush(stderr);
- }
- return(ssl_ftp_active_flag);
-}
-#endif /* CK_SSL */
-
-static sigtype
-cmdcancel(sig) int sig; {
-#ifdef OS2
- /* In Unix we "chain" to trap(), which prints this */
- printf("^C...\n");
-#endif /* OS2 */
- debug(F100,"ftp cmdcancel caught SIGINT ","",0);
- fflush(stdout);
- secure_getc(0,1); /* Initialize net input buffers */
- cancelfile++;
- cancelgroup++;
- mlsreset();
-#ifndef OS2
-#ifdef FTP_PROXY
- if (ptflag) /* proxy... */
- longjmp(ptcancel,1);
-#endif /* FTP_PROXY */
- debug(F100,"ftp cmdcancel chain to trap()...","",0);
- trap(SIGINT);
- /* NOTREACHED */
- debug(F100,"ftp cmdcancel return from trap()...","",0);
-#else
- debug(F100,"ftp cmdcancel PostCtrlCSem()...","",0);
- PostCtrlCSem();
-#endif /* OS2 */
-}
-
-static int
-#ifdef CK_ANSIC
-scommand(char * s) /* Was secure_command() */
-#else
-scommand(s) char * s;
-#endif /* CK_ANSIC */
-{
- int length = 0, len2;
- char in[FTP_BUFSIZ], out[FTP_BUFSIZ];
-#ifdef CK_SSL
- if (ssl_ftp_active_flag) {
- int error, rc;
- length = strlen(s) + 2;
- length = ckmakmsg(out,FTP_BUFSIZ,s,"\r\n",NULL,NULL);
- rc = SSL_write(ssl_ftp_con,out,length);
- error = SSL_get_error(ssl_ftp_con,rc);
- switch (error) {
- case SSL_ERROR_NONE:
- return(1);
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_SYSCALL:
-#ifdef NT
- {
- int gle = GetLastError();
- }
-#endif /* NT */
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- lostpeer();
- }
- return(0);
- }
-#endif /* CK_SSL */
-
- if (auth_type && ftp_cpl != FPL_CLR) {
-#ifdef FTP_SRP
- if (ck_srp_is_installed() && (strcmp(auth_type,"SRP") == 0))
- if ((length = srp_encode(ftp_cpl == FPL_PRV,
- (CHAR *)s,
- (CHAR *)out,
- strlen(s))) < 0) {
- fprintf(stderr, "SRP failed to encode message\n");
- return(0);
- }
-#endif /* FTP_SRP */
-#ifdef FTP_KRB4
- if (ck_krb4_is_installed() &&
- (strcmp(auth_type, "KERBEROS_V4") == 0)) {
- if (ftp_cpl == FPL_PRV) {
- length =
- krb_mk_priv((CHAR *)s, (CHAR *)out,
- strlen(s), ftp_sched,
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &myctladdr, &hisctladdr);
- } else {
- length =
- krb_mk_safe((CHAR *)s,
- (CHAR *)out,
- strlen(s),
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &myctladdr, &hisctladdr);
- }
- if (length == -1) {
- fprintf(stderr, "krb_mk_%s failed for KERBEROS_V4\n",
- ftp_cpl == FPL_PRV ? "priv" : "safe");
- return(0);
- }
- }
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- /* Scommand (based on level) */
- if (ck_gssapi_is_installed() && (strcmp(auth_type, "GSSAPI") == 0)) {
- gss_buffer_desc in_buf, out_buf;
- OM_uint32 maj_stat, min_stat;
- int conf_state;
- in_buf.value = s;
- in_buf.length = strlen(s) + 1;
- maj_stat = gss_seal(&min_stat, gcontext,
- (ftp_cpl==FPL_PRV), /* private */
- GSS_C_QOP_DEFAULT,
- &in_buf, &conf_state,
- &out_buf);
- if (maj_stat != GSS_S_COMPLETE) { /* Generally need to deal */
- user_gss_error(maj_stat, min_stat,
- (ftp_cpl==FPL_PRV)?
- "gss_seal ENC didn't complete":
- "gss_seal MIC didn't complete");
- } else if ((ftp_cpl == FPL_PRV) && !conf_state) {
- fprintf(stderr, "GSSAPI didn't encrypt message");
- } else {
- if (ftp_deb)
- fprintf(stderr, "sealed (%s) %d bytes\n",
- ftp_cpl==FPL_PRV?"ENC":"MIC",
- out_buf.length);
- memcpy(out, out_buf.value,
- length=out_buf.length);
- gss_release_buffer(&min_stat, &out_buf);
- }
- }
-#endif /* FTP_GSSAPI */
- /* Other auth types go here ... */
-
- len2 = FTP_BUFSIZ;
- if ((kerror = radix_encode((CHAR *)out, (CHAR *)in,
- length, &len2, RADIX_ENCODE))
- ) {
- fprintf(stderr,"Couldn't base 64 encode command (%s)\n",
- radix_error(kerror));
- return(0);
- }
- if (ftp_deb)
- fprintf(stderr, "scommand(%s)\nencoding %d bytes\n", s, length);
- len2 = ckmakmsg(out,
- FTP_BUFSIZ,
- ftp_cpl == FPL_PRV ? "ENC " : "MIC ",
- in,
- "\r\n",
- NULL
- );
- send(csocket,(SENDARG2TYPE)out,len2,0);
- } else {
- char out[FTP_BUFSIZ];
- int len = ckmakmsg(out,FTP_BUFSIZ,s,"\r\n",NULL,NULL);
- send(csocket,(SENDARG2TYPE)out,len,0);
- }
- return(1);
-}
-
-static int
-mygetc() {
- static char inbuf[4096];
- static int bp = 0, ep = 0;
- int rc;
-
- if (bp == ep) {
- bp = ep = 0;
-#ifdef CK_SSL
- if (ssl_ftp_active_flag) {
- int error;
- rc = SSL_read(ssl_ftp_con,inbuf,4096);
- error = SSL_get_error(ssl_ftp_con,rc);
- switch (error) {
- case SSL_ERROR_NONE:
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- return(0);
- case SSL_ERROR_SYSCALL:
- if (rc == 0) { /* EOF */
- break;
- } else {
-#ifdef NT
- int gle = GetLastError();
-#endif /* NT */
- break;
- }
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- break;
- }
- } else
-#endif /* CK_SSL */
- rc = recv(csocket,(char *)inbuf,4096,0);
- if (rc <= 0)
- return(EOF);
- ep = rc;
- }
- return(inbuf[bp++]);
-}
-
-/* x l a t e c -- Translate a character */
-/*
- Call with:
- fc = Function code: 0 = translate, 1 = initialize.
- c = Character (as int).
- incs = Index of charset to translate from.
- outcs = Index of charset to translate to.
-
- Returns:
- 0: OK
- -1: Error
-*/
-static int
-xlatec(fc,c,incs,outcs) int fc, c, incs, outcs; {
-#ifdef NOCSETS
- return(c);
-#else
- static char buf[128];
- static int cx;
- int c0, c1;
-
- if (fc == 1) { /* Initialize */
- cx = 0; /* Catch-up buffer write index */
- xgnbp = buf; /* Catch-up buffer read pointer */
- buf[0] = NUL; /* Buffer is empty */
- return(0);
- }
- if (cx >= 127) { /* Catch-up buffer full */
- debug(F100,"xlatec overflow","",0); /* (shouldn't happen) */
- printf("?Translation buffer overflow\n");
- return(-1);
- }
- /* Add char to buffer. */
- /* The buffer won't grow unless incs is a multibyte set, e.g. UTF-8. */
-
- debug(F000,"xlatec buf",ckitoa(cx),c);
- buf[cx++] = c;
- buf[cx] = NUL;
-
- while ((c0 = xgnbyte(FC_UCS2,incs,strgetc)) > -1) {
- if (xpnbyte(c0,TC_UCS2,outcs,NULL) < 0) /* (NULL was xprintc) */
- return(-1);
- }
- /* If we're caught up, reinitialize the buffer */
- return((cx == (xgnbp - buf)) ? xlatec(1,0,0,0) : 0);
-#endif /* NOCSETS */
-}
-
-
-/* p a r s e f e a t */
-
-/* Note: for convenience we align keyword values with table indices */
-/* If you need to insert a new keyword, adjust the SFT_xxx definitions */
-
-static struct keytab feattab[] = {
- { "$$$$", 0, 0 }, /* Dummy for sfttab[0] */
- { "AUTH", SFT_AUTH, 0 },
- { "LANG", SFT_LANG, 0 },
- { "MDTM", SFT_MDTM, 0 },
- { "MLST", SFT_MLST, 0 },
- { "PBSZ", SFT_PBSZ, 0 },
- { "PROT", SFT_PROT, 0 },
- { "REST", SFT_REST, 0 },
- { "SIZE", SFT_SIZE, 0 },
- { "TVFS", SFT_TVFS, 0 },
- { "UTF8", SFT_UTF8, 0 }
-};
-static int nfeattab = (sizeof(feattab) / sizeof(struct keytab));
-
-#define FACT_CSET 1
-#define FACT_CREA 2
-#define FACT_LANG 3
-#define FACT_MTYP 4
-#define FACT_MDTM 5
-#define FACT_PERM 6
-#define FACT_SIZE 7
-#define FACT_TYPE 8
-#define FACT_UNIQ 9
-
-static struct keytab facttab[] = {
- { "CHARSET", FACT_CSET, 0 },
- { "CREATE", FACT_CREA, 0 },
- { "LANG", FACT_LANG, 0 },
- { "MEDIA-TYPE", FACT_MTYP, 0 },
- { "MODIFY", FACT_MDTM, 0 },
- { "PERM", FACT_PERM, 0 },
- { "SIZE", FACT_SIZE, 0 },
- { "TYPE", FACT_TYPE, 0 },
- { "UNIQUE", FACT_UNIQ, 0 }
-};
-static int nfacttab = (sizeof(facttab) / sizeof(struct keytab));
-
-static struct keytab ftyptab[] = {
- { "CDIR", FTYP_CDIR, 0 },
- { "DIR", FTYP_DIR, 0 },
- { "FILE", FTYP_FILE, 0 },
- { "PDIR", FTYP_PDIR, 0 }
-};
-static int nftyptab = (sizeof(ftyptab) / sizeof(struct keytab));
-
-static VOID
-parsefeat(s) char * s; { /* Parse a FEATURE response */
- char kwbuf[8];
- int i, x;
- if (!s) return;
- if (!*s) return;
- while (*s < '!')
- s++;
- for (i = 0; i < 4; i++) {
- if (s[i] < '!')
- break;
- kwbuf[i] = s[i];
- }
- if (s[i] && s[i] != SP)
- return;
- kwbuf[i] = NUL;
- /* xlookup requires a full (but case independent) match */
- i = xlookup(feattab,kwbuf,nfeattab,&x);
- debug(F111,"ftp parsefeat",s,i);
- if (i < 0 || i > 15)
- return;
-
- switch (i) {
- case SFT_MDTM: /* Controlled by ENABLE/DISABLE */
- sfttab[i] = mdtmok;
- if (mdtmok) sfttab[0]++;
- break;
- case SFT_MLST: /* ditto */
- sfttab[i] = mlstok;
- if (mlstok) sfttab[0]++;
- break;
- case SFT_SIZE: /* ditto */
- sfttab[i] = sizeok;
- if (sizeok) sfttab[0]++;
- break;
- case SFT_AUTH: /* ditto */
- sfttab[i] = ftp_aut;
- if (ftp_aut) sfttab[0]++;
- break;
- default: /* Others */
- sfttab[0]++;
- sfttab[i]++;
- }
-}
-
-static char *
-parsefacts(s) char * s; { /* Parse MLS[DT] File Facts */
- char * p;
- int i, j, x;
- if (!s) return(NULL);
- if (!*s) return(NULL);
-
- /* Maybe we should make a copy of s so we can poke it... */
-
- while ((p = ckstrchr(s,'='))) {
- *p = NUL; /* s points to fact */
- i = xlookup(facttab,s,nfacttab,&x);
- debug(F111,"ftp parsefact fact",s,i);
- *p = '=';
- s = p+1; /* Now s points to arg */
- p = ckstrchr(s,';');
- if (!p)
- p = ckstrchr(s,SP);
- if (!p) {
- debug(F110,"ftp parsefact end-of-val search fail",s,0);
- break;
- }
- *p = NUL;
- debug(F110,"ftp parsefact valu",s,0);
- switch (i) {
- case FACT_CSET: /* Ignore these for now */
- case FACT_CREA:
- case FACT_LANG:
- case FACT_PERM:
- case FACT_MTYP:
- case FACT_UNIQ:
- break;
- case FACT_MDTM: /* Modtime */
- makestr(&havemdtm,s);
- debug(F110,"ftp parsefact mdtm",havemdtm,0);
- break;
- case FACT_SIZE: /* Size */
- havesize = atol(s);
- debug(F101,"ftp parsefact size","",havesize);
- break;
- case FACT_TYPE: /* Type */
- j = xlookup(ftyptab,s,nftyptab,NULL);
- debug(F111,"ftp parsefact type",s,j);
- havetype = (j < 1) ? 0 : j;
- break;
- }
- *p = ';';
- s = p+1; /* s points next fact or name */
- }
- while (*s == SP) /* Skip past spaces. */
- s++;
- if (!*s) /* Make sure we still have a name */
- s = NULL;
- debug(F110,"ftp parsefact name",s,0);
- return(s);
-}
-
-/* g e t r e p l y -- (to an FTP command sent to server) */
-
-/* vbm = 1 (verbose); 0 (quiet except for error messages); 9 (super quiet) */
-
-static int
-getreply(expecteof,lcs,rcs,vbm,fc) int expecteof, lcs, rcs, vbm, fc; {
- /* lcs, rcs, vbm parameters as in ftpcmd() */
- register int i, c, n;
- register int dig;
- register char *cp;
- int xlate = 0;
- int count = 0;
- int auth = 0;
- int originalcode = 0, continuation = 0;
- sig_t oldintr;
- int pflag = 0;
- char *pt = pasv;
- char ibuf[FTP_BUFSIZ], obuf[FTP_BUFSIZ]; /* (these are pretty big...) */
- int safe = 0;
- int xquiet = 0;
-
- auth = (fc == GRF_AUTH);
-
-#ifndef NOCSETS
- debug(F101,"ftp getreply lcs","",lcs);
- debug(F101,"ftp getreply rcs","",rcs);
- if (lcs > -1 && rcs > -1 && lcs != rcs) {
- xlate = 1;
- initxlate(rcs,lcs);
- xlatec(1,0,rcs,lcs);
- }
-#endif /* NOCSETS */
- debug(F101,"ftp getreply fc","",fc);
-
- if (quiet)
- xquiet = 1;
- if (vbm == 9) {
- xquiet = 1;
- vbm = 0;
- }
- if (ftp_deb) /* DEBUG */
- vbm = 1;
- else if (quiet || dpyactive) /* QUIET or File Transfer Active */
- vbm = 0;
- else if (vbm < 0) /* VERBOSE */
- vbm = ftp_vbm;
-
- ibuf[0] = '\0';
- if (reply_parse)
- reply_ptr = reply_buf;
- havesigint = 0;
- oldintr = signal(SIGINT, cmdcancel);
- for (count = 0;; count++) {
- obuf[0] = '\0';
- dig = n = ftpcode = i = 0;
- cp = ftp_reply_str;
- while ((c = ibuf[0] ? ibuf[i++] : mygetc()) != '\n') {
- if (c == IAC) { /* Handle telnet commands */
- switch (c = mygetc()) {
- case WILL:
- case WONT:
- c = mygetc();
- obuf[0] = IAC;
- obuf[1] = DONT;
- obuf[2] = c;
- obuf[3] = NUL;
-#ifdef CK_SSL
- if (ssl_ftp_active_flag) {
- int error, rc;
- rc = SSL_write(ssl_ftp_con,obuf,3);
- error = SSL_get_error(ssl_ftp_con,rc);
- switch (error) {
- case SSL_ERROR_NONE:
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- return(0);
- case SSL_ERROR_SYSCALL:
- if (rc == 0) { /* EOF */
- break;
- } else {
-#ifdef NT
- int gle = GetLastError();
-#endif /* NT */
- break;
- }
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- break;
- }
- } else
-#endif /* CK_SSL */
- send(csocket,(SENDARG2TYPE)obuf,3,0);
- break;
- case DO:
- case DONT:
- c = mygetc();
- obuf[0] = IAC;
- obuf[1] = WONT;
- obuf[2] = c;
- obuf[3] = NUL;
-#ifdef CK_SSL
- if (ssl_ftp_active_flag) {
- int error, rc;
- rc = SSL_write(ssl_ftp_con,obuf,3);
- error = SSL_get_error(ssl_ftp_con,rc);
- switch (error) {
- case SSL_ERROR_NONE:
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- signal(SIGINT,oldintr);
- return(0);
- case SSL_ERROR_SYSCALL:
- if (rc == 0) { /* EOF */
- break;
- } else {
-#ifdef NT
- int gle = GetLastError();
-#endif /* NT */
- break;
- }
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- break;
- }
- } else
-#endif /* CK_SSL */
- send(csocket,(SENDARG2TYPE)obuf,3,0);
- break;
- default:
- break;
- }
- continue;
- }
- dig++;
- if (c == EOF) {
- if (expecteof) {
- signal(SIGINT,oldintr);
- ftpcode = 221;
- debug(F101,"ftp getreply EOF","",ftpcode);
- return(0);
- }
- lostpeer();
- if (!xquiet) {
- if (ftp_deb)
- printf("421 ");
- printf(
- "Service not available, connection closed by server\n");
- fflush(stdout);
- }
- signal(SIGINT,oldintr);
- ftpcode = 421;
- debug(F101,"ftp getreply EOF","",ftpcode);
- return(4);
- }
- if (n == 0) { /* First digit */
- n = c; /* Save it */
- }
- if (auth_type &&
-#ifdef CK_SSL
- !ssl_ftp_active_flag &&
-#endif /* CK_SSL */
- !ibuf[0] && (n == '6' || continuation)) {
- if (c != '\r' && dig > 4)
- obuf[i++] = c;
- } else {
- if (auth_type &&
-#ifdef CK_SSL
- !ssl_ftp_active_flag &&
-#endif /* CK_SSL */
- !ibuf[0] && dig == 1 && vbm)
- printf("Unauthenticated reply received from server:\n");
- if (reply_parse) {
- *reply_ptr++ = c;
- *reply_ptr = NUL;
- }
- if ((!dpyactive || ftp_deb) && /* Don't mess up xfer display */
- ftp_cmdlin < 2) {
- if ((c != '\r') &&
- (ftp_deb || ((vbm || (!auth && n == '5')) &&
- (dig > 4 || ( dig <= 4 && !isdigit(c) && ftpcode == 0
- )))))
- {
-#ifdef FTP_PROXY
- if (ftp_prx && (dig == 1 || (dig == 5 && vbm == 0)))
- printf("%s:",ftp_host);
-#endif /* FTP_PROXY */
-
- if (!xquiet) {
-#ifdef NOCSETS
- printf("%c",c);
-#else
- if (xlate) {
- xlatec(0,c,rcs,lcs);
- } else {
- printf("%c",c);
- }
-#endif /* NOCSETS */
- }
- }
- }
- }
- if (auth_type &&
-#ifdef CK_SSL
- !ssl_ftp_active_flag &&
-#endif /* CK_SSL */
- !ibuf[0] && n != '6')
- continue;
- if (dig < 4 && isdigit(c))
- ftpcode = ftpcode * 10 + (c - '0');
- if (!pflag && ftpcode == 227)
- pflag = 1;
- if (dig > 4 && pflag == 1 && isdigit(c))
- pflag = 2;
- if (pflag == 2) {
- if (c != '\r' && c != ')')
- *pt++ = c;
- else {
- *pt = '\0';
- pflag = 3;
- }
- }
- if (dig == 4 && c == '-' && n != '6') {
- if (continuation)
- ftpcode = 0;
- continuation++;
- }
- if (cp < &ftp_reply_str[FTP_BUFSIZ - 1]) {
- *cp++ = c;
- *cp = NUL;
- }
- }
- if (deblog ||
-#ifdef COMMENT
-/*
- Sometimes we need to print the server reply. printlines is nonzero for any
- command where the results are sent back on the control connection rather
- than the data connection, e.g. STAT. In the TOPS-20 case, each file line
- has ftpcode 213. But if you do this with a UNIX server, it sends "213-Start
- STAT", <line with ftpcode == 0>, "213-End" or somesuch. So when printlines
- is nonzero, we want the 213 lines from TOPS-20 and we DON'T want the 213
- lines from UNIX. Further experimentation needed with other servers. Of
- course RFC959 is mute as to the format of the server reply.
-
- 'printlines' is also true for PWD and BYE.
-*/
- (printlines && ((ftpcode == 0) || (servertype == SYS_TOPS20)))
-#else
-/* No, we can't be that clever -- it breaks other things like RPWD... */
- (printlines &&
- (ftpcode != 631 && ftpcode != 632 && ftpcode != 633))
-#endif /* COMMENT */
- ) {
- char * q = cp;
- char *r = ftp_reply_str;
- *q-- = NUL; /* NUL-terminate */
- while (*q < '!' && q > r) /* Strip CR, etc */
- *q-- = NUL;
- if (!ftp_deb && printlines) { /* If printing */
- if (ftpcode != 0) /* strip ftpcode if any */
- r += 4;
-#ifdef NOCSETS
- printf("%s\n",r); /* and print */
-#else
- if (!xlate) {
- printf("%s\n",r);
- } else { /* Translating */
- xgnbp = r; /* Set up strgetc() */
- while ((c0 = xgnbyte(FC_UCS2,rcs,strgetc)) > -1) {
- if (xpnbyte(c0,TC_UCS2,lcs,NULL) < 0) { /* (xprintc) */
- signal(SIGINT,oldintr);
- return(-1);
- }
- }
- printf("\n");
- }
-#endif /* NOCSETS */
- }
- }
- debug(F110,"FTP RCVD ",ftp_reply_str,0);
-
- if (fc == GRF_FEAT) { /* Parsing FEAT command response? */
- if (count == 0 && n == '2') {
- int i; /* (Re)-init server FEATure table */
- debug(F100,"ftp getreply clearing feature table","",0);
- for (i = 0; i < 16; i++)
- sfttab[i] = 0;
- } else {
- parsefeat((char *)ftp_reply_str);
- }
- }
- if (auth_type &&
-#ifdef CK_SSL
- !ssl_ftp_active_flag &&
-#endif /* CK_SSL */
- !ibuf[0] && n != '6') {
- signal(SIGINT,oldintr);
- return(getreply(expecteof,lcs,rcs,vbm,auth));
- }
- ibuf[0] = obuf[i] = '\0';
- if (ftpcode && n == '6')
- if (ftpcode != 631 && ftpcode != 632 && ftpcode != 633) {
- printf("Unknown reply: %d %s\n", ftpcode, obuf);
- n = '5';
- } else safe = (ftpcode == 631);
- if (obuf[0] /* if there is a string to decode */
-#ifdef CK_SSL
- && !ssl_ftp_active_flag /* and not SSL/TLS */
-#endif /* CK_SSL */
- ) {
- if (!auth_type) {
- printf("Cannot decode reply:\n%d %s\n", ftpcode, obuf);
- n = '5';
- }
-#ifndef CK_ENCRYPTION
- else if (ftpcode == 632) {
- printf("Cannot decrypt %d reply: %s\n", ftpcode, obuf);
- n = '5';
- }
-#endif /* CK_ENCRYPTION */
-#ifdef NOCONFIDENTIAL
- else if (ftpcode == 633) {
- printf("Cannot decrypt %d reply: %s\n", ftpcode, obuf);
- n = '5';
- }
-#endif /* NOCONFIDENTIAL */
- else {
- int len = FTP_BUFSIZ;
- if ((kerror = radix_encode((CHAR *)obuf,
- (CHAR *)ibuf,
- 0,
- &len,
- RADIX_DECODE))
- ) {
- printf("Can't decode base 64 reply %d (%s)\n\"%s\"\n",
- ftpcode, radix_error(kerror), obuf);
- n = '5';
- }
-#ifdef FTP_SRP
- else if (strcmp(auth_type, "SRP") == 0) {
- int outlen;
- outlen = srp_decode(!safe, (CHAR *)ibuf,
- (CHAR *) ibuf, len);
- if (outlen < 0) {
- printf("Warning: %d reply %s!\n",
- ftpcode, safe ? "modified" : "garbled");
- n = '5';
- } else {
- ckstrncpy(&ibuf[outlen], "\r\n",FTP_BUFSIZ-outlen);
- if (ftp_deb)
- printf("%c:", safe ? 'S' : 'P');
- continue;
- }
- }
-#endif /* FTP_SRP */
-#ifdef FTP_KRB4
- else if (strcmp(auth_type, "KERBEROS_V4") == 0) {
- if (safe) {
- kerror = krb_rd_safe((CHAR *)ibuf, len,
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &hisctladdr,
- &myctladdr,
- &ftp_msg_data
- );
- } else {
- kerror = krb_rd_priv((CHAR *)ibuf, len,
- ftp_sched,
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &hisctladdr,
- &myctladdr,
- &ftp_msg_data
- );
- }
- if (kerror != KSUCCESS) {
- printf("%d reply %s! (krb_rd_%s: %s)\n", ftpcode,
- safe ? "modified" : "garbled",
- safe ? "safe" : "priv",
- krb_get_err_text(kerror));
- n = '5';
- } else if (ftp_msg_data.app_length >= FTP_BUFSIZ - 3) {
- kerror = KFAILURE;
- n = '5';
- printf("reply data too large for buffer\n");
- } else {
- if (ftp_deb)
- printf("%c:", safe ? 'S' : 'P');
- memcpy(ibuf,ftp_msg_data.app_data,
- ftp_msg_data.app_length);
- ckstrncpy(&ibuf[ftp_msg_data.app_length], "\r\n",
- FTP_BUFSIZ - ftp_msg_data.app_length);
- continue;
- }
- }
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- else if (strcmp(auth_type, "GSSAPI") == 0) {
- gss_buffer_desc xmit_buf, msg_buf;
- OM_uint32 maj_stat, min_stat;
- int conf_state;
- xmit_buf.value = ibuf;
- xmit_buf.length = len;
- /* decrypt/verify the message */
- conf_state = safe;
- maj_stat = gss_unseal(&min_stat, gcontext,
- &xmit_buf, &msg_buf,
- &conf_state, NULL);
- if (maj_stat != GSS_S_COMPLETE) {
- user_gss_error(maj_stat, min_stat,
- "failed unsealing reply");
- n = '5';
- } else {
- memcpy(ibuf, msg_buf.value, msg_buf.length);
- ckstrncpy(&ibuf[msg_buf.length], "\r\n",
- FTP_BUFSIZ-msg_buf.length);
- gss_release_buffer(&min_stat,&msg_buf);
- if (ftp_deb)
- printf("%c:", safe ? 'S' : 'P');
- continue;
- }
- }
-#endif /* FTP_GSSAPI */
- /* Other auth types go here... */
- }
- } else if ((!dpyactive || ftp_deb) && ftp_cmdlin < 2 &&
- !xquiet && (vbm || (!auth && (n == '4' || n == '5')))) {
-#ifdef NOCSETS
- printf("%c",c);
-#else
- if (xlate) {
- xlatec(0,c,rcs,lcs);
- } else {
- printf("%c",c);
- }
-#endif /* NOCSETS */
- fflush (stdout);
- }
- if (continuation && ftpcode != originalcode) {
- if (originalcode == 0)
- originalcode = ftpcode;
- continue;
- }
- *cp = '\0';
- if (n != '1')
- cpend = 0;
- signal(SIGINT,oldintr);
- if (ftpcode == 421 || originalcode == 421) {
- lostpeer();
- if (!xquiet && !ftp_deb)
- printf("%s\n",reply_buf);
- }
- if ((cancelfile != 0) &&
-#ifndef ULTRIX3
- /* Ultrix 3.0 cc objects violently to this clause */
- (oldintr != cmdcancel) &&
-#endif /* ULTRIX3 */
- (oldintr != SIG_IGN)) {
- if (oldintr)
- (*oldintr)(SIGINT);
- }
- if (reply_parse) {
- *reply_ptr = '\0';
- if ((reply_ptr = ckstrstr(reply_buf, reply_parse))) {
- reply_parse = reply_ptr + strlen(reply_parse);
- if ((reply_ptr = ckstrpbrk(reply_parse, " \r")))
- *reply_ptr = '\0';
- } else
- reply_parse = reply_ptr;
- }
- while (*cp < '!' && cp > ftp_reply_str) /* Remove trailing junk */
- *cp-- = NUL;
- debug(F111,"ftp getreply",ftp_reply_str,n - '0');
- return(n - '0');
- } /* for (;;) */
-}
-
-#ifdef BSDSELECT
-static int
-#ifdef CK_ANSIC
-empty(fd_set * mask, int sec)
-#else
-empty(mask, sec) fd_set * mask; int sec;
-#endif /* CK_ANSIC */
-{
- struct timeval t;
- t.tv_sec = (long) sec;
- t.tv_usec = 0L;
- debug(F100,"ftp empty calling select...","",0);
-#ifdef INTSELECT
- x = select(32, (int *)mask, NULL, NULL, &t);
-#else
- x = select(32, mask, (fd_set *) 0, (fd_set *) 0, &t);
-#endif /* INTSELECT */
- debug(F101,"ftp empty select","",x);
- return(x);
-}
-#else /* BSDSELECT */
-#ifdef IBMSELECT
-static int
-empty(mask, cnt, sec) int * mask, sec;
- int cnt;
-{
- return(select(mask,cnt,0,0,sec*1000));
-}
-#endif /* IBMSELECT */
-#endif /* BSDSELECT */
-
-static sigtype
-cancelsend(sig) int sig; {
- havesigint++;
- cancelgroup++;
- cancelfile = 0;
- printf(" Canceled...\n");
- secure_getc(0,1); /* Initialize net input buffers */
- debug(F100,"ftp cancelsend caught SIGINT ","",0);
- fflush(stdout);
-#ifndef OS2
- longjmp(sendcancel, 1);
-#else
- PostCtrlCSem();
-#endif /* OS2 */
-}
-
-static VOID
-#ifdef CK_ANSIC
-secure_error(char *fmt, ...)
-#else
-/* VARARGS1 */
-secure_error(fmt, p1, p2, p3, p4, p5)
- char *fmt; int p1, p2, p3, p4, p5;
-#endif /* CK_ANSIC */
-{
-#ifdef CK_ANSIC
- va_list ap;
-
- va_start(ap, fmt);
- vfprintf(stderr, fmt, ap);
- va_end(ap);
-#else
- fprintf(stderr, fmt, p1, p2, p3, p4, p5);
-#endif
- fprintf(stderr, "\n");
-}
-
-/*
- * Internal form of settype; changes current type in use with server
- * without changing our notion of the type for data transfers.
- * Used to change to and from ascii for listings.
- */
-static VOID
-changetype(newtype, show) int newtype, show; {
- int rc;
- char * s;
-
- if ((newtype == curtype) && typesent++)
- return;
- switch (newtype) {
- case FTT_ASC:
- s = "A";
- break;
- case FTT_BIN:
- s = "I";
- break;
- case FTT_TEN:
- s = "L 8";
- break;
- default:
- s = "I";
- break;
- }
- rc = ftpcmd("TYPE",s,-1,-1,show);
- if (rc == REPLY_COMPLETE)
- curtype = newtype;
-}
-
-/* PUT a file. Returns -1 on error, 0 on success, 1 if file skipped */
-
-static VOID
-#ifdef CK_ANSIC
-doftpsend(void * threadinfo)
-#else
-doftpsend(threadinfo) VOID * threadinfo;
-#endif
-{
-#ifdef NTSIG
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "doftpsend called with threadinfo block","", 0);
- } else debug(F100, "doftpsend - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
-
- if (initconn()) {
-#ifndef NOHTTP
- int y = -1;
- debug(F101,"doftpsend","tcp_http_proxy",tcp_http_proxy);
-
- /* If the connection failed and we are using an HTTP Proxy
- * and the reason for the failure was an authentication
- * error, then we need to give the user to ability to
- * enter a username and password, just like a browser.
- *
- * I tried to do all of this within the netopen() call
- * but it is much too much work.
- */
- while (y != 0 && tcp_http_proxy != NULL ) {
-
- if (tcp_http_proxy_errno == 401 ||
- tcp_http_proxy_errno == 407 ) {
- char uid[UIDBUFLEN];
- char pwd[PWDSIZ];
- struct txtbox tb[2];
- int ok;
-
- tb[0].t_buf = uid;
- tb[0].t_len = UIDBUFLEN;
- tb[0].t_lbl = "Proxy Userid: ";
- tb[0].t_dflt = NULL;
- tb[0].t_echo = 1;
- tb[1].t_buf = pwd;
- tb[1].t_len = 256;
- tb[1].t_lbl = "Proxy Passphrase: ";
- tb[1].t_dflt = NULL;
- tb[1].t_echo = 2;
-
- ok = uq_mtxt("Proxy Server Authentication Required\n",
- NULL, 2, tb);
- if (ok && uid[0]) {
- char * proxy_user, * proxy_pwd;
-
- proxy_user = tcp_http_proxy_user;
- proxy_pwd = tcp_http_proxy_pwd;
-
- tcp_http_proxy_user = uid;
- tcp_http_proxy_pwd = pwd;
-
- y = initconn();
-
- debug(F101,"doftpsend","initconn",y);
- memset(pwd,0,PWDSIZ);
- tcp_http_proxy_user = proxy_user;
- tcp_http_proxy_pwd = proxy_pwd;
- } else
- break;
- } else
- break;
- }
-
- if ( y != 0 ) {
-#endif /* NOHTTP */
- signal(SIGINT, ftpsnd.oldintr);
-#ifdef SIGPIPE
- if (ftpsnd.oldintp)
- signal(SIGPIPE, ftpsnd.oldintp);
-#endif /* SIGPIPE */
- ftpcode = -1;
- zclose(ZIFILE);
- ftpsndret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
-#ifndef NOHTTP
- }
-#endif /* NOHTTP */
- }
- ftpsndret = 0;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
-}
-
-static VOID
-#ifdef CK_ANSIC
-failftpsend(void * threadinfo)
-#else
-failftpsend(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
-#ifdef NTSIG
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "docmdfile called with threadinfo block","", 0);
- } else debug(F100, "docmdfile - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
-
- while (cpend) {
- ftpsnd.reply = getreply(0,ftpsnd.incs,ftpsnd.outcs,ftp_vbm,0);
- debug(F111,"ftp sendrequest getreply","null command",ftpsnd.reply);
- }
- if (data >= 0) {
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- SSL_shutdown(ssl_ftp_data_con);
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_active_flag = 0;
- ssl_ftp_data_con = NULL;
- }
-#endif /* CK_SSL */
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = -1;
- }
- if (ftpsnd.oldintr)
- signal(SIGINT,ftpsnd.oldintr);
-#ifdef SIGPIPE
- if (ftpsnd.oldintp)
- signal(SIGPIPE,ftpsnd.oldintp);
-#endif /* SIGPIPE */
- ftpcode = -1;
-#ifndef OS2
- /* TEST ME IN K95 */
- if (havesigint) {
- havesigint = 0;
- debug(F100,"ftp failftpsend chain to trap()...","",0);
- if (ftpsnd.oldintr != SIG_IGN)
- (*ftpsnd.oldintr)(SIGINT);
- /* NOTREACHED (I hope!) */
- debug(F100,"ftp failftpsend return from trap()...","",0);
- }
-#endif /* OS2 */
-}
-
-static VOID
-#ifdef CK_ANSIC
-failftpsend2(void * threadinfo)
-#else
-failftpsend2(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
-#ifdef NTSIG
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "docmdfile called with threadinfo block","", 0);
- } else debug(F100, "docmdfile - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
-
- debug(F101,"ftp sendrequest canceled","",ftpsnd.bytes);
- tfc += ffc;
-#ifdef GFTIMER
- fpfsecs = gftimer();
-#endif /* GFTIMER */
- zclose(ZIFILE);
-#ifdef PIPESEND
- if (sndfilter)
- pipesend = 0;
-#endif /* PIPESEND */
- signal(SIGINT, ftpsnd.oldintr);
-#ifdef SIGPIPE
- if (ftpsnd.oldintp)
- signal(SIGPIPE, ftpsnd.oldintp);
-#endif /* SIGPIPE */
- if (!cpend) {
- ftpcode = -1;
- ftpsndret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- if (data >= 0) {
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- SSL_shutdown(ssl_ftp_data_con);
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_active_flag = 0;
- ssl_ftp_data_con = NULL;
- }
-#endif /* CK_SSL */
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = -1;
- }
- if (dout) {
-#ifdef TCPIPLIB
- socket_close(dout);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(dout, 1+1);
-#endif /* USE_SHUTDOWN */
- close(dout);
-#endif /* TCPIPLIB */
- }
- ftpsnd.reply = getreply(0,ftpsnd.incs,ftpsnd.outcs,ftp_vbm,0);
- ftpcode = -1;
- ftpsndret = -1;
-
-#ifndef OS2
- /* TEST ME IN K95 */
- if (havesigint) {
- havesigint = 0;
- debug(F100,"ftp failftpsend2 chain to trap()...","",0);
- if (ftpsnd.oldintr != SIG_IGN)
- (*ftpsnd.oldintr)(SIGINT);
- /* NOTREACHED (I hope!) */
- debug(F100,"ftp failftpsend2 return from trap()...","",0);
- }
-#endif /* OS2 */
-}
-
-static VOID
-#ifdef CK_ANSIC
-doftpsend2(void * threadinfo)
-#else
-doftpsend2(threadinfo) VOID * threadinfo;
-#endif
-{
- register int c, d = 0;
- int n, t, x, notafile, unique = 0;
- char *buf, *bufp;
-
-#ifdef NTSIG
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "doftpsend2 called with threadinfo block","", 0);
- } else debug(F100, "doftpsend2 - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
-
- buf = ftpsndbuf; /* (not on stack) */
-
- unique = strcmp(ftpsnd.cmd,"STOU") ? 0 : 1;
- notafile = sndarray || pipesend;
-
-#ifdef FTP_RESTART
- if (ftpsnd.restart && ((curtype == FTT_BIN) || (alike > 0))) {
- char * p;
- changetype(FTT_BIN,0); /* Change to binary */
-
- /* Ask for remote file's size */
- x = ftpcmd("SIZE",ftpsnd.remote,ftpsnd.incs,ftpsnd.outcs,ftp_vbm);
-
- if (x == REPLY_COMPLETE) { /* Have ftpsnd.reply */
- p = &ftp_reply_str[4]; /* Parse it */
- while (isdigit(*p)) {
- sendstart = sendstart * 10 + (int)(*p - '0');
- p++;
- }
- if (*p && *p != CR) { /* Bad number */
- debug(F110,"doftpsend2 bad size",ftp_reply_str,0);
- sendstart = 0L;
- } else if (sendstart > fsize) { /* Remote file bigger than local */
- debug(F110,"doftpsend2 big size",ckltoa(fsize),sendstart);
- sendstart = 0L;
- }
- /* Local is newer */
- debug(F111,"doftpsend2 size",ftpsnd.remote,sendstart);
- if (chkmodtime(ftpsnd.local,ftpsnd.remote,0) == 2) {
- debug(F110,"doftpsend2 date mismatch",ftp_reply_str,0);
- sendstart = 0L; /* Send the whole file */
- }
- }
- changetype(ftp_typ,0); /* Change back to appropriate type */
- if (sendstart > 0L) { /* Still restarting? */
- if (sendstart == fsize) { /* Same size - no need to send */
- debug(F111,"doftpsend2 /restart SKIP",fsize,sendstart);
- zclose(ZIFILE);
- ftpsndret = SKP_RES;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- errno = 0; /* Restart needed, seek to the spot */
- if (zfseek((long)sendstart) < 0) {
- debug(F111,"doftpsend2 zfseek fails",
- ftpsnd.local,sendstart);
- fprintf(stderr, "FSEEK: %s: %s\n", ftpsnd.local, ck_errstr());
- sendstart = 0;
- zclose(ZIFILE);
- ftpsndret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
-#ifdef COMMENT
- debug(F111,"doftpsend2 zfseek ok",ftpsnd.local,sendstart);
- x = ftpcmd("REST",ckltoa(sendstart),-1,-1,ftp_vbm);
- if (x != REPLY_CONTINUE) {
- sendstart = 0;
- zclose(ZIFILE);
- ftpsndret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- } else {
- ftpsnd.cmd = "STOR";
- }
-#else
- sendmode = SM_RESEND;
- ftpsnd.cmd = "APPE";
-#endif /* COMMENT */
- /* sendstart = 0L; */
- }
- }
-#endif /* FTP_RESTART */
-
- if (unique && !stouarg) /* If we know STOU accepts no arg */
- ftpsnd.remote = NULL; /* don't include one. */
-
- x = ftpcmd(ftpsnd.cmd, ftpsnd.remote, ftpsnd.incs, ftpsnd.outcs, ftp_vbm);
- debug(F111,"doftpsend2 ftpcode",ftpsnd.cmd,ftpcode);
-
- if (x != REPLY_PRELIM && unique) {
- /*
- RFC959 says STOU does not take an argument. But every FTP server
- I've encountered but one accepts the arg and constructs the unique
- name from it, which is better than making up a totally random name
- for the file, which is what RFC959 calls for. Especially because
- there is no way for the client to find out the name chosen by the
- server. So we try STOU with the argument first, which works with
- most servers, and if it fails we retry it without the arg, for
- the benefit of the one picky server that is not "liberal in what
- it accepts" UNLESS the first STOU got a 502 code ("not implemented")
- which means STOU is not accepted, period.
- */
- if ((x == 5) && stouarg && (ftpcode != 502)) {
- x = ftpcmd(ftpsnd.cmd,NULL,ftpsnd.incs,ftpsnd.outcs,ftp_vbm);
- if (x == REPLY_PRELIM) /* If accepted */
- stouarg = 0; /* flag no STOU arg for this server */
- }
- }
- if (x != REPLY_PRELIM) {
- signal(SIGINT, ftpsnd.oldintr);
-#ifdef SIGPIPE
- if (ftpsnd.oldintp)
- signal(SIGPIPE, ftpsnd.oldintp);
-#endif /* SIGPIPE */
- zclose(ZIFILE);
-#ifdef PIPESEND
- if (sndfilter)
- pipesend = 0;
-#endif /* PIPESEND */
- ftpsndret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- dout = dataconn(ftpsnd.lmode); /* Get data connection */
- if (dout == -1) {
- failftpsend2(threadinfo);
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- /* Initialize per-file stats */
- ffc = 0L; /* Character counter */
- cps = oldcps = 0L; /* Thruput */
-#ifdef GFTIMER
- rftimer(); /* reset f.p. timer */
-#endif /* GFTIMER */
-
-#ifdef SIGPIPE
- ftpsnd.oldintp = signal(SIGPIPE, SIG_IGN);
-#endif /* SIGPIPE */
- switch (curtype) {
- case FTT_BIN: /* Binary mode */
- case FTT_TEN:
- errno = d = 0;
- while ((n = zxin(ZIFILE,buf,FTP_BUFSIZ - 1)) > 0 && !cancelfile) {
- ftpsnd.bytes += n;
- ffc += n;
- debug(F111,"doftpsend2 zxin",ckltoa(n),ffc);
- hexdump("doftpsend2 zxin",buf,16);
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- for (bufp = buf; n > 0; n -= d, bufp += d) {
- if ((d = SSL_write(ssl_ftp_data_con, bufp, n)) <= 0)
- break;
- spackets++;
- pktnum++;
- if (fdispla != XYFD_B) {
- spktl = d;
- ftscreen(SCR_PT,'D',spackets,NULL);
- }
- }
- } else {
-#endif /* CK_SSL */
- for (bufp = buf; n > 0; n -= d, bufp += d) {
- if (((d = secure_write(dout, (CHAR *)bufp, n)) <= 0)
- || iscanceled())
- break;
- spackets++;
- pktnum++;
- if (fdispla != XYFD_B) {
- spktl = d;
- ftscreen(SCR_PT,'D',spackets,NULL);
- }
- }
-#ifdef CK_SSL
- }
-#endif /* CK_SSL */
- if (d <= 0)
- break;
- }
- if (n < 0)
- fprintf(stderr, "local: %s: %s\n", ftpsnd.local, ck_errstr());
- if (d < 0 || (d = secure_flush(dout)) < 0) {
- if (d == -1 && errno && errno != EPIPE)
- perror("netout");
- ftpsnd.bytes = -1;
- }
- break;
-
- case FTT_ASC: /* Text mode */
-#ifndef NOCSETS
- if (ftpsnd.xlate) { /* With translation */
- initxlate(ftpsnd.incs,ftpsnd.outcs);
- while (!cancelfile) {
- if ((c0 = xgnbyte(FC_UCS2,ftpsnd.incs,NULL)) < 0) break;
- if ((x = xpnbyte(c0,TC_UCS2,ftpsnd.outcs,xxout)) < 0) break;
- }
- } else {
-#endif /* NOCSETS */
- /* Text mode, no translation */
- while (((c = zminchar()) > -1) && !cancelfile) {
- ffc++;
- if (xxout(c) < 0)
- break;
- }
- d = 0;
-#ifndef NOCSETS
- }
-#endif /* NOCSETS */
- if (dout == -1 || (d = secure_flush(dout)) < 0) {
- if (d == -1 && errno && errno != EPIPE)
- perror("netout");
- ftpsnd.bytes = -1;
- }
- break;
- }
- tfc += ffc; /* Total file chars */
-#ifdef GFTIMER
- fpfsecs = gftimer();
-#endif /* GFTIMER */
- zclose(ZIFILE); /* Close input file */
-#ifdef PIPESEND
- if (sndfilter) /* Undo this (it's per file) */
- pipesend = 0;
-#endif /* PIPESEND */
-
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- SSL_shutdown(ssl_ftp_data_con);
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_active_flag = 0;
- ssl_ftp_data_con = NULL;
- }
-#endif /* CK_SSL */
-
-#ifdef TCPIPLIB
- socket_close(dout); /* Close data connection */
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(dout, 1+1);
-#endif /* USE_SHUTDOWN */
- close(dout);
-#endif /* TCPIPLIB */
- ftpsnd.reply = getreply(0,ftpsnd.incs,ftpsnd.outcs,ftp_vbm,0);
- signal(SIGINT, ftpsnd.oldintr); /* Put back interrupts */
-#ifdef SIGPIPE
- if (ftpsnd.oldintp)
- signal(SIGPIPE, ftpsnd.oldintp);
-#endif /* SIGPIPE */
- if (ftpsnd.reply == REPLY_TRANSIENT || ftpsnd.reply == REPLY_ERROR) {
- debug(F101,"doftpsend2 ftpsnd.reply","",ftpsnd.reply);
- ftpsndret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- } else if (cancelfile) {
- debug(F101,"doftpsend2 canceled","",ftpsnd.bytes);
- ftpsndret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- debug(F101,"doftpsend2 ok","",ftpsnd.bytes);
- ftpsndret = 0;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
-}
-
-static int
-sendrequest(cmd, local, remote, xlate, incs, outcs, restart)
- char *cmd, *local, *remote; int xlate, incs, outcs, restart;
-{
- if (!remote) remote = ""; /* Check args */
- if (!*remote) remote = local;
- if (!local) local = "";
- if (!*local) return(-1);
- if (!cmd) cmd = "";
- if (!*cmd) cmd = "STOR";
-
- debug(F111,"ftp sendrequest restart",local,restart);
-
- nout = 0; /* Init output buffer count */
- ftpsnd.bytes = 0; /* File input byte count */
- dout = -1;
-
-#ifdef FTP_PROXY
- if (proxy) {
- proxtrans(cmd, local, remote, !strcmp(cmd,"STOU"));
- return(0);
- }
-#endif /* FTP_PROXY */
-
- changetype(ftp_typ,0); /* Change type for this file */
-
- ftpsnd.oldintr = NULL; /* Set up interrupt handler */
- ftpsnd.oldintp = NULL;
- ftpsnd.restart = restart;
- ftpsnd.xlate = xlate;
- ftpsnd.lmode = "wb";
-
-#ifdef PIPESEND /* Use Kermit API for file i/o... */
- if (sndfilter) {
- char * p = NULL, * q;
-#ifndef NOSPL
- int n = CKMAXPATH;
- if (cmd_quoting && (p = (char *) malloc(n + 1))) {
- q = p;
- debug(F110,"sendrequest pipesend filter",sndfilter,0);
- zzstring(sndfilter,&p,&n);
- debug(F111,"sendrequest pipename",q,n);
- if (n <= 0) {
- printf("?Sorry, send filter + filename too long, %d max.\n",
- CKMAXPATH
- );
- free(q);
- return(-1);
- }
- ckstrncpy(filnam,q,CKMAXPATH+1);
- free(q);
- local = filnam;
- }
-#endif /* NOSPL */
- }
-
- if (sndfilter) /* If sending thru a filter */
- pipesend = 1; /* set this for open and i/o */
-#endif /* PIPESEND */
-
- if (openi(local) == 0) /* Try to open the input file */
- return(-1);
-
- ftpsndret = 0;
- ftpsnd.incs = incs;
- ftpsnd.outcs = outcs;
- ftpsnd.cmd = cmd;
- ftpsnd.local = local;
- ftpsnd.remote = remote;
- ftpsnd.oldintr = signal(SIGINT, cancelsend);
- havesigint = 0;
-
- if (cc_execute(ckjaddr(sendcancel), doftpsend, failftpsend) < 0)
- return(-1);
- if (ftpsndret < 0)
- return(-1);
- if (cc_execute(ckjaddr(sendcancel), doftpsend2, failftpsend2) < 0)
- return(-1);
-
- return(ftpsndret);
-}
-
-static sigtype
-cancelrecv(sig) int sig; {
- havesigint++;
- cancelfile = 0;
- cancelgroup++;
- secure_getc(0,1); /* Initialize net input buffers */
- printf(" Canceling...\n");
- debug(F100,"ftp cancelrecv caught SIGINT","",0);
- fflush(stdout);
- if (fp_nml) {
- if (fp_nml != stdout)
- fclose(fp_nml);
- fp_nml = NULL;
- }
-#ifndef OS2
- longjmp(recvcancel, 1);
-#else
- PostCtrlCSem();
-#endif /* OS2 */
-}
-
-/* Argumentless front-end for secure_getc() */
-
-static int
-netgetc() {
- return(secure_getc(globaldin,0));
-}
-
-/* Returns -1 on failure, 0 on success, 1 if file skipped */
-
-/*
- Sets ftpcode < 0 on failure if failure reason is not server reply code:
- -1: interrupted by user.
- -2: error opening or writing output file (reason in errno).
- -3: failure to make data connection.
- -4: network read error (reason in errno).
-*/
-
-struct xx_ftprecv {
- int reply;
- int fcs;
- int rcs;
- int recover;
- int xlate;
- int din;
- int is_retr;
- sig_t oldintr, oldintp;
- char * cmd;
- char * local;
- char * remote;
- char * lmode;
- char * pipename;
- int tcrflag;
- long localsize;
-};
-static struct xx_ftprecv ftprecv;
-
-static int ftprecvret = 0;
-
-static VOID
-#ifdef CK_ANSIC
-failftprecv(VOID * threadinfo)
-#else
-failftprecv(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
-#ifdef NTSIG
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "docmdfile called with threadinfo block","", 0);
- } else debug(F100, "docmdfile - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
-
- while (cpend) {
- ftprecv.reply = getreply(0,ftprecv.fcs,ftprecv.rcs,ftp_vbm,0);
- }
- if (data >= 0) {
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- SSL_shutdown(ssl_ftp_data_con);
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_active_flag = 0;
- ssl_ftp_data_con = NULL;
- }
-#endif /* CK_SSL */
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = -1;
- }
- if (ftprecv.oldintr)
- signal(SIGINT, ftprecv.oldintr);
- ftpcode = -1;
- ftprecvret = -1;
-
-#ifndef OS2
- /* TEST ME IN K95 */
- if (havesigint) {
- havesigint = 0;
- debug(F100,"ftp failftprecv chain to trap()...","",0);
- if (ftprecv.oldintr != SIG_IGN)
- (*ftprecv.oldintr)(SIGINT);
- /* NOTREACHED (I hope!) */
- debug(F100,"ftp failftprecv return from trap()...","",0);
- }
-#endif /* OS2 */
- return;
-}
-
-static VOID
-#ifdef CK_ANSIC
-doftprecv(VOID * threadinfo)
-#else
-doftprecv(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
-#ifdef NTSIG
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "docmdfile called with threadinfo block","", 0);
- } else debug(F100, "docmdfile - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
-
-#ifndef COMMENT
- if (!out2screen && !ftprecv.pipename) {
- int x;
- char * local;
- local = ftprecv.local;
- x = zchko(local);
- if (x < 0) {
- if ((!dpyactive || ftp_deb))
- fprintf(stderr,
- "Temporary file %s: %s\n", ftprecv.local, ck_errstr());
- signal(SIGINT, ftprecv.oldintr);
- ftpcode = -2;
- ftprecvret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- }
-#endif /* COMMENT */
- changetype((!ftprecv.is_retr) ? FTT_ASC : ftp_typ, 0);
- if (initconn()) { /* Initialize the data connection */
- signal(SIGINT, ftprecv.oldintr);
- ftpcode = -1;
- ftprecvret = -3;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- secure_getc(0,1); /* Initialize net input buffers */
- ftprecvret = 0;
-
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
-}
-
-static VOID
-#ifdef CK_ANSIC
-failftprecv2(VOID * threadinfo)
-#else
-failftprecv2(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
-#ifdef NTSIG
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "docmdfile called with threadinfo block","", 0);
- } else debug(F100, "docmdfile - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
-
- /* Cancel using RFC959 recommended IP,SYNC sequence */
-
- debug(F100,"ftp recvrequest CANCEL","",0);
-#ifdef GFTIMER
- fpfsecs = gftimer();
-#endif /* GFTIMER */
-#ifdef SIGPIPE
- if (ftprecv.oldintp)
- signal(SIGPIPE, ftprecv.oldintr);
-#endif /* SIGPIPE */
- signal(SIGINT, SIG_IGN);
- if (!cpend) {
- ftpcode = -1;
- signal(SIGINT, ftprecv.oldintr);
- ftprecvret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- cancel_remote(ftprecv.din);
- if (ftpcode > -1)
- ftpcode = -1;
- if (data >= 0) {
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- SSL_shutdown(ssl_ftp_data_con);
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_active_flag = 0;
- ssl_ftp_data_con = NULL;
- }
-#endif /* CK_SSL */
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = -1;
- }
- if (!out2screen) {
- int x = 0;
- debug(F111,"ftp failrecv2 zclose",ftprecv.local,keep);
- zclose(ZOFILE);
- switch (keep) { /* which is... */
- case SET_AUTO: /* AUTO */
- if (curtype == FTT_ASC) /* Delete file if TYPE A. */
- x = 1;
- break;
- case SET_OFF: /* DISCARD */
- x = 1; /* Delete file, period. */
- break;
- default: /* KEEP */
- break;
- }
- if (x) {
- x = zdelet(ftprecv.local);
- debug(F111,"ftp failrecv2 delete incomplete",ftprecv.local,x);
- }
- }
- if (ftprecv.din) {
-#ifdef TCPIPLIB
- socket_close(ftprecv.din);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(ftprecv.din, 1+1);
-#endif /* USE_SHUTDOWN */
- close(ftprecv.din);
-#endif /* TCPIPLIB */
- }
- signal(SIGINT, ftprecv.oldintr);
- ftprecvret = -1;
-
- if (havesigint) {
- havesigint = 0;
- debug(F100,"FTP failftprecv2 chain to trap()...","",0);
-#ifdef OS2
- debug(F100,"FTP failftprecv2 PostCtrlCSem()...","",0);
- PostCtrlCSem();
-#else /* OS2 */
- if (ftprecv.oldintr != SIG_IGN)
- (*ftprecv.oldintr)(SIGINT);
- /* NOTREACHED (I hope!) */
- debug(F100,"ftp failftprecv2 return from trap()...","",0);
-#endif /* OS2 */
- }
-}
-
-static VOID
-#ifdef CK_ANSIC
-doftprecv2(VOID * threadinfo)
-#else
-doftprecv2(threadinfo) VOID * threadinfo;
-#endif /* CK_ANSIC */
-{
- register int c, d;
- long bytes = 0L;
- int bare_lfs = 0;
- int blksize = 0;
- ULONG start = 0L, stop;
- char * p;
- static char * rcvbuf = NULL;
- static int rcvbufsiz = 0;
-#ifdef CK_URL
- char newname[CKMAXPATH+1]; /* For file dialog */
-#endif /* CK_URL */
- extern int adl_ask;
-
- ftprecv.din = -1;
-#ifdef NTSIG
- if (threadinfo) { /* Thread local storage... */
- TlsSetValue(TlsIndex,threadinfo);
- debug(F100, "docmdfile called with threadinfo block","", 0);
- } else debug(F100, "docmdfile - threadinfo is NULL", "", 0);
-#endif /* NTSIG */
-#ifdef CK_LOGIN
-#ifdef IKSD
-#ifdef NT
- if (inserver)
- setntcreds();
-#endif /* NT */
-#endif /* IKSD */
-#endif /* CK_LOGIN */
-
- if (ftprecv.recover) { /* Initiate recovery */
- x = ftpcmd("REST",ckltoa(ftprecv.localsize),-1,-1,ftp_vbm);
- debug(F111,"ftp reply","REST",x);
- if (x == REPLY_CONTINUE) {
- ftprecv.lmode = "ab";
- rs_len = ftprecv.localsize;
- } else {
- ftprecv.recover = 0;
- }
- }
- /* IMPORTANT: No FTP commands can come between REST and RETR! */
-
- debug(F111,"ftp recvrequest recover E",ftprecv.remote,ftprecv.recover);
-
- /* Send the command and get reply */
- debug(F110,"ftp recvrequest cmd",ftprecv.cmd,0);
- debug(F110,"ftp recvrequest remote",ftprecv.remote,0);
-
- if (ftpcmd(ftprecv.cmd,ftprecv.remote,ftprecv.fcs,ftprecv.rcs,ftp_vbm)
- != REPLY_PRELIM) {
- signal(SIGINT, ftprecv.oldintr); /* Bad reply, fail. */
- ftprecvret = -1; /* ftpcode is set by ftpcmd() */
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- ftprecv.din = dataconn("r"); /* Good reply, open data connection */
- globaldin = ftprecv.din; /* Global copy of file descriptor */
- if (ftprecv.din == -1) { /* Check for failure */
- ftpcode = -3; /* Code for no data connection */
- ftprecvret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
-#ifdef CK_URL
- /* In K95 GUI put up a file box */
- if (haveurl && g_url.pth && adl_ask ) { /* Downloading from a URL */
- int x;
- char * preface =
-"\r\nIncoming file from FTP server...\r\n\
-Please confirm output file specification or supply an alternative:";
-
- x = uq_file(preface, /* K95 GUI: Put up file box. */
- NULL,
- 4,
- NULL,
- ftprecv.local ? ftprecv.local : ftprecv.remote,
- newname,
- CKMAXPATH+1
- );
- if (x > 0) {
- ftprecv.local = newname; /* Substitute user's file name */
- if (x == 2) /* And append if user said to */
- ftprecv.lmode = "ab";
- }
- }
-#endif /* CK_URL */
- x = 1; /* Output file open OK? */
- if (ftprecv.pipename) { /* Command */
- x = zxcmd(ZOFILE,ftprecv.pipename);
- debug(F111,"ftp recvrequest zxcmd",ftprecv.pipename,x);
- } else if (!out2screen) { /* File */
- struct filinfo xx;
- xx.bs = 0; xx.cs = 0; xx.rl = 0; xx.org = 0; xx.cc = 0;
- xx.typ = 0; xx.os_specific = NUL; xx.lblopts = 0;
- /* Append or New */
- xx.dsp = !strcmp(ftprecv.lmode,"ab") ? XYFZ_A : XYFZ_N;
- x = zopeno(ZOFILE,ftprecv.local,NULL,&xx);
- debug(F111,"ftp recvrequest zopeno",ftprecv.local,x);
- }
- if (x < 1) { /* Failure to open output file */
- if ((!dpyactive || ftp_deb))
- fprintf(stderr, "local(2): %s: %s\n", ftprecv.local, ck_errstr());
- ftprecvret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- blksize = FTP_BUFSIZ; /* Allocate input buffer */
-
- debug(F101,"ftp recvrequest blksize","",blksize);
- debug(F101,"ftp recvrequest rcvbufsiz","",rcvbufsiz);
-
- if (rcvbufsiz < blksize) { /* if necessary */
- if (rcvbuf) {
- free(rcvbuf);
- rcvbuf = NULL;
- }
- rcvbuf = (char *)malloc((unsigned)blksize);
- if (!rcvbuf) {
- debug(F100,"ftp get rcvbuf malloc failed","",0);
- ftpcode = -2;
-#ifdef ENOMEM
- errno = ENOMEM;
-#endif /* ENOMEM */
- if ((!dpyactive || ftp_deb))
- perror("malloc");
- rcvbufsiz = 0;
- ftprecvret = -1;
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- debug(F101,"ftp get rcvbuf malloc ok","",blksize);
- rcvbufsiz = blksize;
- }
- debug(F111,"ftp get rcvbufsiz",ftprecv.local,rcvbufsiz);
-
- ffc = 0L; /* Character counter */
- cps = oldcps = 0L; /* Thruput */
- start = gmstimer(); /* Start time (msecs) */
-#ifdef GFTIMER
- rftimer(); /* Start time (float) */
-#endif /* GFTIMER */
-
- debug(F111,"ftp get type",ftprecv.local,curtype);
- debug(F101,"ftp recvrequest ftp_dpl","",ftp_dpl);
- switch (curtype) {
- case FTT_BIN: /* Binary mode */
- case FTT_TEN: /* TENEX mode */
- d = 0;
- while (1) {
- errno = 0;
- c = secure_read(ftprecv.din, rcvbuf, rcvbufsiz);
- if (cancelfile) {
- failftprecv2(threadinfo);
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- if (c < 1)
- break;
-#ifdef printf /* (What if it isn't?) */
- if (out2screen && !ftprecv.pipename) {
- int i;
- for (i = 0; i < c; i++)
- printf("%c",rcvbuf[i]);
- } else
-#endif /* printf */
- {
- register int i;
- i = 0;
- errno = 0;
- while (i < c) {
- if (zmchout(rcvbuf[i++]) < 0) {
- d = i;
- break;
- }
- }
- }
- bytes += c;
- ffc += c;
- }
- if (c < 0) {
- debug(F111,"ftp recvrequest errno",ckitoa(c),errno);
- if (c == -1 && errno != EPIPE)
- if ((!dpyactive || ftp_deb))
- perror("netin");
- bytes = -1;
- ftpcode = -4;
- }
- if (d < c) {
- ftpcode = -2;
- if ((!dpyactive || ftp_deb)) {
- char * p;
- p = ftprecv.local ? ftprecv.local : ftprecv.pipename;
- if (d < 0)
- fprintf(stderr,
- "local(3): %s: %s\n", ftprecv.local, ck_errstr());
- else
- fprintf(stderr,
- "%s: short write\n", ftprecv.local);
- }
- }
- break;
-
- case FTT_ASC: /* Text mode */
- debug(F101,"ftp recvrequest TYPE A xlate","",ftprecv.xlate);
-#ifndef NOCSETS
- if (ftprecv.xlate) {
- int t;
-#ifdef CK_ANSIC
- int (*fn)(char);
-#else
- int (*fn)();
-#endif /* CK_ANSIC */
- debug(F110,"ftp recvrequest (data)","initxlate",0);
- initxlate(ftprecv.rcs,ftprecv.fcs); /* (From,To) */
- if (ftprecv.pipename) {
- fn = pipeout;
- debug(F110,"ftp recvrequest ASCII","pipeout",0);
- } else {
- fn = out2screen ? scrnout : putfil;
- debug(F110,"ftp recvrequest ASCII",
- out2screen ? "scrnout" : "putfil",0);
- }
- while (1) {
- /* Get byte from net */
- c0 = xgnbyte(FC_UCS2,ftprecv.rcs,netgetc);
- if (cancelfile) {
- failftprecv2(threadinfo);
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- if (c0 < 0)
- break;
- /* Second byte from net */
- c1 = xgnbyte(FC_UCS2,ftprecv.rcs,netgetc);
- if (cancelfile) {
- failftprecv2(threadinfo);
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- if (c1 < 0)
- break;
-#ifdef COMMENT
- /* K95: Check whether we need this */
- if (fileorder > 0) /* Little Endian */
- bytswap(&c0,&c1); /* swap bytes*/
-#endif /* COMMENT */
-
-#ifdef OS2
- if ( out2screen && /* we're translating to UCS-2 */
- !k95stdout && !inserver) /* for the real screen... */
- {
- union {
- USHORT ucs2;
- UCHAR bytes[2];
- } output;
-
- output.bytes[0] = c1;
- output.bytes[1] = c0;
-
- VscrnWrtUCS2StrAtt(VCMD,
- &output.ucs2,
- 1,
- wherey[VCMD],
- wherex[VCMD],
- &colorcmd
- );
-
- } else
-#endif /* OS2 */
- {
- if ((x = xpnbyte(c0,TC_UCS2,ftprecv.fcs,fn)) < 0) break;
- if ((x = xpnbyte(c1,TC_UCS2,ftprecv.fcs,fn)) < 0) break;
- }
- }
- } else {
-#endif /* NOCSETS */
- while (1) {
- c = secure_getc(ftprecv.din,0);
- if (cancelfile) {
- failftprecv2(threadinfo);
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- if (c < 0 || c == EOF)
- break;
-#ifdef UNIX
- /* Record format conversion for Unix */
- /* SKIP THIS FOR WINDOWS! */
- if (c == '\n')
- bare_lfs++;
- while (c == '\r') {
- bytes++;
- if ((c = secure_getc(ftprecv.din,0)) != '\n' ||
- ftprecv.tcrflag) {
- if (cancelfile) {
- failftprecv2(threadinfo);
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
- return;
- }
- if (c < 0 || c == EOF)
- goto break2;
- if (c == '\0') {
- bytes++;
- goto contin2;
- }
- }
- }
- if (c < 0)
- break;
-#endif /* UNX */
-
- if (out2screen && !ftprecv.pipename)
-#ifdef printf
- printf("%c",(char)c);
-#else
- putchar((char)c);
-#endif /* printf */
- else
- if ((d = zmchout(c)) < 0)
- break;
- bytes++;
- ffc++;
- contin2:
- ;
- }
- break2:
- if (bare_lfs && (!dpyactive || ftp_deb)) {
- printf("WARNING! %d bare linefeeds received in ASCII mode\n",
- bare_lfs);
- printf("File might not have transferred correctly.\n");
- }
- if (ftprecv.din == -1) {
- bytes = -1;
- }
- if (c == -2)
- bytes = -1;
- break;
-#ifndef NOCSETS
- }
-#endif /* NOCSETS */
- }
- if (ftprecv.pipename || !out2screen) {
- zclose(ZOFILE); /* Close the file */
- debug(F111,"doftprecv2 zclose ftpcode",ftprecv.local,ftpcode);
- if (ftpcode < 0) { /* If download failed */
- int x = 0;
- switch (keep) { /* which is... */
- case SET_AUTO: /* AUTO */
- if (curtype == FTT_ASC) /* Delete file if TYPE A. */
- x = 1;
- break;
- case SET_OFF: /* DISCARD */
- x = 1; /* Delete file, period. */
- break;
- default: /* KEEP */
- break;
- }
- if (x) {
- x = zdelet(ftprecv.local);
- debug(F111,"ftp get delete incomplete",ftprecv.local,x);
- }
- }
- }
- signal(SIGINT, ftprecv.oldintr);
-#ifdef SIGPIPE
- if (ftprecv.oldintp)
- signal(SIGPIPE, ftprecv.oldintp);
-#endif /* SIGPIPE */
- stop = gmstimer();
-#ifdef GFTIMER
- fpfsecs = gftimer();
-#endif /* GFTIMER */
- tfc += ffc;
-
-#ifdef TCPIPLIB
- socket_close(ftprecv.din);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(ftprecv.din, 1+1);
-#endif /* USE_SHUTDOWN */
- close(ftprecv.din);
-#endif /* TCPIPLIB */
- ftprecv.reply = getreply(0,ftprecv.fcs,ftprecv.rcs,ftp_vbm,0);
- ftprecvret = ((ftpcode < 0 || ftprecv.reply == REPLY_TRANSIENT ||
- ftprecv.reply == REPLY_ERROR) ? -1 : 0);
-#ifdef NTSIG
- ckThreadEnd(threadinfo);
-#endif /* NTSIG */
-}
-
-static int
-recvrequest(cmd, local, remote, lmode, printnames, recover, pipename,
- xlate, fcs, rcs)
- char *cmd, *local, *remote, *lmode, *pipename;
- int printnames, recover, xlate, fcs, rcs;
-{
-#ifdef NT
- struct _stat stbuf;
-#else /* NT */
- struct stat stbuf;
-#endif /* NT */
-
-#ifdef DEBUG
- if (deblog) {
- debug(F111,"ftp recvrequest cmd",cmd,recover);
- debug(F110,"ftp recvrequest local ",local,0);
- debug(F111,"ftp recvrequest remote",remote,ftp_typ);
- debug(F110,"ftp recvrequest pipename ",pipename,0);
- debug(F101,"ftp recvrequest xlate","",xlate);
- debug(F101,"ftp recvrequest fcs","",fcs);
- debug(F101,"ftp recvrequest rcs","",rcs);
- }
-#endif /* DEBUG */
-
- ftprecv.localsize = 0L;
-
- if (remfile) { /* See remcfm(), remtxt() */
- if (rempipe) {
- pipename = remdest;
- } else {
- local = remdest;
- if (remappd) lmode = "ab";
- }
- }
- out2screen = 0;
- if (!cmd) cmd = ""; /* Core dump prevention */
- if (!remote) remote = "";
- if (!lmode) lmode = "";
-
- if (pipename) { /* No recovery for pipes. */
- recover = 0;
- if (!local)
- local = pipename;
- } else {
- if (!local) /* Output to screen? */
- local = "-";
- out2screen = !strcmp(local,"-");
- }
- debug(F101,"ftp recvrequest out2screen","",out2screen);
-
-#ifdef OS2
- if ( ftp_xla && out2screen && !k95stdout && !inserver )
- fcs = FC_UCS2;
-#endif /* OS2 */
-
- if (out2screen) /* No recovery to screen */
- recover = 0;
- if (!ftp_typ) /* No recovery in text mode */
- recover = 0;
- ftprecv.is_retr = (strcmp(cmd, "RETR") == 0);
-
- if (!ftprecv.is_retr) /* No recovery except for RETRieve */
- recover = 0;
-
-#ifdef COMMENT
- if (!out2screen && !pipename && ftprecv.is_retr) { /* To real file */
- if (recursive && ckstrchr(local,'/')) {
-
- }
- }
-#endif /* COMMENT */
-
- ftprecv.localsize = 0L; /* Local file size */
- rs_len = 0L; /* Recovery point */
-
- debug(F101,"ftp recvrequest recover","",recover);
- if (recover) { /* Recovering... */
- if (stat(local, &stbuf) < 0) { /* Can't stat local file */
- debug(F101,"ftp recvrequest recover stat failed","",errno);
- recover = 0; /* So cancel recovery */
- } else { /* Have local file info */
- ftprecv.localsize = stbuf.st_size; /* Get size */
- /* Remote file smaller than local */
- if (fsize < ftprecv.localsize) {
- debug(F101,"ftp recvrequest recover remote smaller","",fsize);
- recover = 0; /* Recovery can't work */
- } else if (fsize == ftprecv.localsize) { /* Sizes are equal */
- debug(F111,"ftp recvrequest recover equal size",
- remote,ftprecv.localsize);
- return(1);
- }
-#ifdef COMMENT
-/*
- The problem here is that the original partial file never got its date
- set, either because FTP DATES was OFF, or because the partial file was
- downloaded by some other program that doesn't set local file dates, or
- because Kermit only sets the file's date when the download was complete
- and successful. In all these cases, the local file has a later time
- than the remote.
-*/
- if (recover) { /* Remote is bigger */
- x = chkmodtime(local,remote,0); /* Check file dates */
- debug(F111,"ftp recvrequest chkmodtime",remote,x);
- if (x != 1) /* Dates must be equal! */
- recover = 0; /* If not, get whole file */
- }
-#endif /* COMMENT */
- }
- debug(F111,"ftp recvrequest recover",remote,recover);
- }
-
-#ifdef FTP_PROXY
- if (proxy && ftprecv.is_retr)
- return(proxtrans(cmd, local ? local : remote, remote));
-#endif /* FTP_PROXY */
-
- ftprecv.tcrflag = (feol != CR) && ftprecv.is_retr;
-
- ftprecv.reply = 0;
- ftprecv.fcs = fcs;
- ftprecv.rcs = rcs;
- ftprecv.recover = recover;
- ftprecv.xlate = xlate;
- ftprecv.cmd = cmd;
- ftprecv.local = local;
- ftprecv.remote = remote;
- ftprecv.lmode = lmode;
- ftprecv.pipename = pipename;
- ftprecv.oldintp = NULL;
- ftpcode = 0;
-
- havesigint = 0;
- ftprecv.oldintr = signal(SIGINT, cancelrecv);
- if (cc_execute(ckjaddr(recvcancel), doftprecv, failftprecv) < 0)
- return -1;
- if (ftprecvret < 0)
- return -1;
-
- if (cc_execute(ckjaddr(recvcancel), doftprecv2, failftprecv2) < 0)
- return -1;
- return ftprecvret;
-}
-
-/*
- * Need to start a listen on the data channel before we send the command,
- * otherwise the server's connect may fail.
- */
-static int
-initconn() {
- register char *p, *a;
- int result, tmpno = 0;
- int on = 1;
- GSOCKNAME_T len;
-
-#ifndef NO_PASSIVE_MODE
- int a1,a2,a3,a4,p1,p2;
-
- if (passivemode) {
- data = socket(AF_INET, SOCK_STREAM, 0);
- globaldin = data;
- if (data < 0) {
- perror("ftp: socket");
- return(-1);
- }
- if (ftpcmd("PASV",NULL,0,0,ftp_vbm) != REPLY_COMPLETE) {
- printf("Passive mode refused\n");
- passivemode = 0;
- return(initconn());
- }
-/*
- Now we have a string of comma-separated one-byte unsigned integer values,
- The first four are the an IP address. The fifth is the MSB of the port
- number, the sixth is the LSB. From that we can make a sockaddr_in.
-*/
- if (sscanf(pasv,"%d,%d,%d,%d,%d,%d",&a1,&a2,&a3,&a4,&p1,&p2) != 6) {
- printf("Passive mode address scan failure\n");
- return(-1);
- };
-#ifndef NOHTTP
- if (tcp_http_proxy) {
-#ifdef OS2
- char * agent = "Kermit 95"; /* Default user agent */
-#else
- char * agent = "C-Kermit";
-#endif /* OS2 */
- register struct hostent *hp = 0;
- struct servent *destsp;
- char host[512], *p, *q;
-#ifdef IP_TOS
-#ifdef IPTOS_THROUGHPUT
- int tos;
-#endif /* IPTOS_THROUGHPUT */
-#endif /* IP_TOS */
- int s;
-#ifdef DEBUG
- extern int debtim;
- int xdebtim;
- xdebtim = debtim;
- debtim = 1;
-#endif /* DEBUG */
-
- ckmakxmsg(proxyhost,HTTPCPYL,ckuitoa(a1),".",ckuitoa(a2),
- ".",ckuitoa(a3),".",ckuitoa(a4),":",ckuitoa((p1<<8)|p2),
- NULL,NULL,NULL
- );
- memset((char *)&hisctladdr, 0, sizeof (hisctladdr));
- for (p = tcp_http_proxy, q=host; *p != '\0' && *p != ':'; p++, q++)
- *q = *p;
- *q = '\0';
-
- hisctladdr.sin_addr.s_addr = inet_addr(host);
- if (hisctladdr.sin_addr.s_addr != -1) {
- debug(F110,"initconn A",host,0);
- hisctladdr.sin_family = AF_INET;
- } else {
- debug(F110,"initconn B",host,0);
- hp = gethostbyname(host);
-#ifdef HADDRLIST
- hp = ck_copyhostent(hp); /* make safe copy that won't change */
-#endif /* HADDRLIST */
- if (hp == NULL) {
- fprintf(stderr, "ftp: %s: Unknown host\n", host);
- ftpcode = -1;
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
- return(0);
- }
- hisctladdr.sin_family = hp->h_addrtype;
-#ifdef HADDRLIST
- memcpy((char *)&hisctladdr.sin_addr, hp->h_addr_list[0],
- sizeof(hisctladdr.sin_addr));
-#else /* HADDRLIST */
- memcpy((char *)&hisctladdr.sin_addr, hp->h_addr,
- sizeof(hisctladdr.sin_addr));
-#endif /* HADDRLIST */
- }
- data = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
- debug(F101,"initconn socket","",data);
- if (data < 0) {
- perror("ftp: socket");
- ftpcode = -1;
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
- return(0);
- }
- if (*p == ':')
- p++;
- else
- p = "http";
-
- destsp = getservbyname(p,"tcp");
- if (destsp)
- hisctladdr.sin_port = destsp->s_port;
- else if (p)
- hisctladdr.sin_port = htons(atoi(p));
- else
- hisctladdr.sin_port = htons(80);
- errno = 0;
-#ifdef HADDRLIST
- debug(F100,"initconn HADDRLIST","",0);
- while
-#else
- debug(F100,"initconn no HADDRLIST","",0);
- if
-#endif /* HADDRLIST */
- (connect(data, (struct sockaddr *)&hisctladdr,
- sizeof (hisctladdr)) < 0) {
- debug(F101,"initconn connect failed","",errno);
-#ifdef HADDRLIST
- if (hp && hp->h_addr_list[1]) {
- int oerrno = errno;
-
- fprintf(stderr,
- "ftp: connect to address %s: ",
- inet_ntoa(hisctladdr.sin_addr)
- );
- errno = oerrno;
- perror((char *)0);
- hp->h_addr_list++;
- memcpy((char *)&hisctladdr.sin_addr,
- hp->h_addr_list[0],
- sizeof(hisctladdr.sin_addr));
- fprintf(stdout, "Trying %s...\n",
- inet_ntoa(hisctladdr.sin_addr));
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
- close(data);
-#endif /* TCPIPLIB */
- data = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
- if (data < 0) {
- perror("ftp: socket");
- ftpcode = -1;
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
- return(0);
- }
- continue;
- }
-#endif /* HADDRLIST */
- perror("ftp: connect");
- ftpcode = -1;
- goto bad;
- }
- if (http_connect(data,
- tcp_http_proxy_agent ?
- tcp_http_proxy_agent :
- agent,
- NULL,
- tcp_http_proxy_user,
- tcp_http_proxy_pwd,
- 0,
- proxyhost
- ) < 0) {
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
- close(data);
-#endif /* TCPIPLIB */
- perror("ftp: connect");
- ftpcode = -1;
- goto bad;
- }
- } else
-#endif /* NOHTTP */
- {
- data_addr.sin_family = AF_INET;
- data_addr.sin_addr.s_addr = htonl((a1<<24)|(a2<<16)|(a3<<8)|a4);
- data_addr.sin_port = htons((p1<<8)|p2);
-
- if (connect(data,
- (struct sockaddr *)&data_addr,
- sizeof(data_addr)) < 0
- ) {
- perror("ftp: connect");
- return(-1);
- }
- }
- debug(F100,"initconn connect ok","",0);
-#ifdef IP_TOS
-#ifdef IPTOS_THROUGHPUT
- on = IPTOS_THROUGHPUT;
- if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
- perror("ftp: setsockopt TOS (ignored)");
-#endif /* IPTOS_THROUGHPUT */
-#endif /* IP_TOS */
- memcpy(&hisdataaddr,&data_addr,sizeof(struct sockaddr_in));
- return(0);
- }
-#endif /* NO_PASSIVE_MODE */
-
- noport:
- memcpy(&data_addr,&myctladdr,sizeof(struct sockaddr_in));
- if (sendport)
- data_addr.sin_port = 0; /* let system pick one */
- if (data != -1) {
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- }
- data = socket(AF_INET, SOCK_STREAM, 0);
- globaldin = data;
- if (data < 0) {
- perror("ftp: socket");
- if (tmpno)
- sendport = 1;
- return(-1);
- }
- if (!sendport) {
- if (setsockopt(data,
- SOL_SOCKET,
- SO_REUSEADDR,
- (char *)&on,
- sizeof (on)
- ) < 0
- ) {
- perror("ftp: setsockopt (reuse address)");
- goto bad;
- }
- }
- if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) {
- perror("ftp: bind");
- goto bad;
- }
- len = sizeof (data_addr);
- if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) {
- perror("ftp: getsockname");
- goto bad;
- }
- if (listen(data, 1) < 0) {
- perror("ftp: listen");
- goto bad;
- }
- if (sendport) {
- a = (char *)&data_addr.sin_addr;
- p = (char *)&data_addr.sin_port;
- ckmakxmsg(ftpcmdbuf,FTP_BUFSIZ,"PORT ",
- UC(a[0]),",",UC(a[1]),",", UC(a[2]),",", UC(a[3]),",",
- UC(p[0]),",", UC(p[1]));
- result = ftpcmd(ftpcmdbuf,NULL,0,0,ftp_vbm);
- if (result == REPLY_ERROR && sendport) {
- sendport = 0;
- tmpno = 1;
- goto noport;
- }
- return(result != REPLY_COMPLETE);
- }
- if (tmpno)
- sendport = 1;
-#ifdef IP_TOS
-#ifdef IPTOS_THROUGHPUT
- on = IPTOS_THROUGHPUT;
- if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
- perror("ftp: setsockopt TOS (ignored)");
-#endif
-#endif
- return(0);
- bad:
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = data;
- if (tmpno)
- sendport = 1;
- return(-1);
-}
-
-#ifdef CK_SSL
-static int
-ssl_dataconn() {
- if (ssl_ftp_data_con!=NULL) { /* Do SSL */
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_con=NULL;
- }
- ssl_ftp_data_con=(SSL *)SSL_new(ssl_ftp_ctx);
-
- SSL_set_fd(ssl_ftp_data_con,data);
- SSL_set_verify(ssl_ftp_data_con,ssl_verify_flag,NULL);
-
- SSL_copy_session_id(ssl_ftp_data_con,ssl_ftp_con);
-
- if (ssl_debug_flag) {
- fprintf(stderr,"=>START SSL connect on DATA\n");
- fflush(stderr);
- }
- if (SSL_connect(ssl_ftp_data_con) <= 0) {
- static char errbuf[1024];
- ckmakmsg(errbuf,1024,"ftp: SSL_connect DATA error: ",
- ERR_error_string(ERR_get_error(),NULL),NULL,NULL);
- fprintf(stderr,"%s\n", errbuf);
- fflush(stderr);
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = data;
- return(-1);
- } else {
- ssl_ftp_data_active_flag=1;
-
- if (!ssl_certsok_flag && !tls_is_krb5(2)) {
- char *subject = ssl_get_subject_name(ssl_ftp_data_con);
-
- if (!subject) {
- if (ssl_verify_flag & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
- debug(F110,"dataconn","[SSL _- FAILED]",0);
-
- ssl_ftp_data_active_flag = 0;
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = data;
- return(-1);
- } else {
- if (!out2screen && displa && fdispla) {
- ftscreen(SCR_TC,0,0L,"Display canceled");
- /* fdispla = XYFD_B; */
- }
-
- if (uq_ok(
- "Warning: Server didn't provide a certificate on data connection\n",
- "Continue with file transfer? (Y/N)",
- 3,NULL,0) <= 0) {
- debug(F110, "dataconn","[SSL - FAILED]",0);
- ssl_ftp_data_active_flag = 0;
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = data;
- return(-1);
- }
- }
- } else {
- if (!out2screen && displa && fdispla == XYFD_C) {
- ftscreen(SCR_TC,0,0L,"Display canceled");
- /* fdispla = XYFD_B; */
- }
-
- if (ssl_check_server_name(ssl_ftp_data_con,ftp_user_host)) {
- debug(F110,"dataconn","[SSL - FAILED]",0);
- ssl_ftp_data_active_flag = 0;
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = data;
- return(-1);
- }
- }
- }
- debug(F110,"dataconn","[SSL - OK]",0);
-#ifdef COMMENT
- /* This messes up the full screen file transfer display */
- ssl_display_connect_details(ssl_ftp_con,0,ssl_verbose_flag);
-#endif /* COMMENT */
- }
- if (ssl_debug_flag) {
- fprintf(stderr,"=>DONE SSL connect on DATA\n");
- fflush(stderr);
- }
- return(data);
-}
-#endif /* CK_SSL */
-
-static int
-dataconn(lmode) char *lmode; {
- int s;
-#ifdef IP_TOS
- int tos;
-#endif /* IP_TOS */
-#ifdef UCX50
- static u_int fromlen;
-#else
- static SOCKOPT_T fromlen;
-#endif /* UCX50 */
-
- fromlen = sizeof(hisdataaddr);
-
-#ifndef NO_PASSIVE_MODE
- if (passivemode) {
-#ifdef CK_SSL
- ssl_ftp_data_active_flag=0;
- if (ssl_ftp_active_flag &&
- (ssl_ftp_proxy || ftp_dpl == FPL_PRV))
- return(ssl_dataconn());
-#endif /* CK_SSL */
- return(data);
- }
-#endif /* NO_PASSIVE_MODE */
-
- s = accept(data, (struct sockaddr *) &hisdataaddr, &fromlen);
- if (s < 0) {
- perror("ftp: accept");
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = data;
- return(-1);
- }
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = s;
- globaldin = data;
-#ifdef IP_TOS
-#ifdef IPTOS_THROUGHPUT
- tos = IPTOS_THROUGHPUT;
- if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
- perror("ftp: setsockopt TOS (ignored)");
-#endif /* IPTOS_THROUGHPUT */
-#endif /* IP_TOS */
-
-#ifdef CK_SSL
- ssl_ftp_data_active_flag=0;
- if (ssl_ftp_active_flag &&
- (ssl_ftp_proxy || ftp_dpl == FPL_PRV))
- return(ssl_dataconn());
-#endif /* CK_SSL */
- return(data);
-}
-
-#ifdef FTP_PROXY
-static sigtype
-pscancel(sig) int sig; {
- cancelfile++;
-}
-
-static VOID
-pswitch(flag) int flag; {
- extern int proxy;
- sig_t oldintr;
- static struct comvars {
- int connect;
- char name[MAXHOSTNAMELEN];
- struct sockaddr_in mctl;
- struct sockaddr_in hctl;
- FILE *in;
- FILE *out;
- int tpe;
- int curtpe;
- int cpnd;
- int sunqe;
- int runqe;
- int mcse;
- int ntflg;
- char nti[17];
- char nto[17];
- int mapflg;
- char mi[CKMAXPATH];
- char mo[CKMAXPATH];
- char *authtype;
- int clvl;
- int dlvl;
-#ifdef FTP_KRB4
- des_cblock session;
- des_key_schedule ftp_sched;
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- gss_ctx_id_t gcontext;
-#endif /* GSSAPI */
- } proxstruct, tmpstruct;
- struct comvars *ip, *op;
-
- cancelfile = 0;
- oldintr = signal(SIGINT, pscancel);
- if (flag) {
- if (proxy)
- return;
- ip = &tmpstruct;
- op = &proxstruct;
- proxy++;
- } else {
- if (!proxy)
- return;
- ip = &proxstruct;
- op = &tmpstruct;
- proxy = 0;
- }
- ip->connect = connected;
- connected = op->connect;
- if (ftp_host) {
- strncpy(ip->name, ftp_host, MAXHOSTNAMELEN - 1);
- ip->name[MAXHOSTNAMELEN - 1] = '\0';
- ip->name[strlen(ip->name)] = '\0';
- } else
- ip->name[0] = 0;
- ftp_host = op->name;
- ip->hctl = hisctladdr;
- hisctladdr = op->hctl;
- ip->mctl = myctladdr;
- myctladdr = op->mctl;
- ip->in = csocket;
- csocket = op->in;
- ip->out = csocket;
- csocket = op->out;
- ip->tpe = ftp_typ;
- ftp_typ = op->tpe;
- ip->curtpe = curtype;
- curtype = op->curtpe;
- ip->cpnd = cpend;
- cpend = op->cpnd;
- ip->sunqe = ftp_usn;
- ftp_usn = op->sunqe;
- ip->mcse = mcase;
- mcase = op->mcse;
- ip->ntflg = ntflag;
- ntflag = op->ntflg;
- strncpy(ip->nti, ntin, 16);
- (ip->nti)[strlen(ip->nti)] = '\0';
- strcpy(ntin, op->nti);
- strncpy(ip->nto, ntout, 16);
- (ip->nto)[strlen(ip->nto)] = '\0';
- strcpy(ntout, op->nto);
- ip->mapflg = mapflag;
- mapflag = op->mapflg;
- strncpy(ip->mi, mapin, CKMAXPATH - 1);
- (ip->mi)[strlen(ip->mi)] = '\0';
- strcpy(mapin, op->mi);
- strncpy(ip->mo, mapout, CKMAXPATH - 1);
- (ip->mo)[strlen(ip->mo)] = '\0';
- strcpy(mapout, op->mo);
- ip->authtype = auth_type;
- auth_type = op->authtype;
- ip->clvl = ftp_cpl;
- ftp_cpl = op->clvl;
- ip->dlvl = ftp_dpl;
- ftp_dpl = op->dlvl;
- if (!ftp_cpl)
- ftp_cpl = FPL_CLR;
- if (!ftp_dpl)
- ftp_dpl = FPL_CLR;
-#ifdef FTP_KRB4
- memcpy(ip->session, ftp_cred.session, sizeof(ftp_cred.session));
- memcpy(ftp_cred.session, op->session, sizeof(ftp_cred.session));
- memcpy(ip->schedule, ftp_sched, sizeof(ftp_sched));
- memcpy(ftp_sched, op->schedule, sizeof(ftp_sched));
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- ip->gcontext = gcontext;
- gcontext = op->gcontext;
-#endif /* GSSAPI */
- signal(SIGINT, oldintr);
- if (cancelfile) {
- cancelfile = 0;
- debug(F101,"pswitch cancelfile B","",cancelfile);
- (*oldintr)(SIGINT);
- }
-}
-
-static sigtype
-cancelpt(sig) int sig; {
- printf("\n");
- fflush(stdout);
- ptabflg++;
- cancelfile = 0;
-#ifndef OS2
- longjmp(ptcancel, 1);
-#else
- PostCtrlCSem();
-#endif /* OS2 */
-}
-
-void
-proxtrans(cmd, local, remote, unique) char *cmd, *local, *remote; int unique; {
- sig_t oldintr;
- int secndflag = 0, prox_type, nfnd;
- char *cmd2;
-#ifdef BSDSELECT
- fd_set mask;
-#endif /* BSDSELECT */
- sigtype cancelpt();
-
- if (strcmp(cmd, "RETR"))
- cmd2 = "RETR";
- else
- cmd2 = unique ? "STOU" : "STOR";
- if ((prox_type = type) == 0) {
- if (servertype == SYS_UNIX && unix_proxy)
- prox_type = FTT_BIN;
- else
- prox_type = FTT_ASC;
- }
- if (curtype != prox_type)
- changetype(prox_type, 1);
- if (ftpcmd("PASV",NULL,0,0,ftp_vbm) != REPLY_COMPLETE) {
- printf("Proxy server does not support third party transfers.\n");
- return;
- }
- pswitch(0);
- if (!connected) {
- printf("No primary connection\n");
- pswitch(1);
- ftpcode = -1;
- return;
- }
- if (curtype != prox_type)
- changetype(prox_type, 1);
-
- if (ftpcmd("PORT",pasv,-1,-1,ftp_vbm) != REPLY_COMPLETE) {
- pswitch(1);
- return;
- }
-
- /* Replace with calls to cc_execute() */
- if (setjmp(ptcancel))
- goto cancel;
- oldintr = signal(SIGINT, cancelpt);
- if (ftpcmd(cmd,remote,-1,-1,ftp_vbm) != PRELIM) {
- signal(SIGINT, oldintr);
- pswitch(1);
- return;
- }
- sleep(2000);
- pswitch(1);
- secndflag++;
- if (ftpcmd(cmd2,local,-1,-1,ftp_vbm) != PRELIM)
- goto cancel;
- ptflag++;
- getreply(0,-1,-1,ftp_vbm,0);
- pswitch(0);
- getreply(0,-1,-1,ftp_vbm,0);
- signal(SIGINT, oldintr);
- pswitch(1);
- ptflag = 0;
- return;
-
- cancel:
- signal(SIGINT, SIG_IGN);
- ptflag = 0;
- if (strcmp(cmd, "RETR") && !proxy)
- pswitch(1);
- else if (!strcmp(cmd, "RETR") && proxy)
- pswitch(0);
- if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */
- if (ftpcmd(cmd2,local,-1,-1,ftp_vbm) != PRELIM) {
- pswitch(0);
- if (cpend)
- cancel_remote(0);
- }
- pswitch(1);
- if (ptabflg)
- ftpcode = -1;
- signal(SIGINT, oldintr);
- return;
- }
- if (cpend)
- cancel_remote(0);
- pswitch(!proxy);
- if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */
- if (ftpcmd(cmd2,local,-1,-1,ftp_vbm) != PRELIM) {
- pswitch(0);
- if (cpend)
- cancel_remote(0);
- pswitch(1);
- if (ptabflg)
- ftpcode = -1;
- signal(SIGINT, oldintr);
- return;
- }
- }
- if (cpend)
- cancel_remote(0);
- pswitch(!proxy);
- if (cpend) {
-#ifdef BSDSELECT
- FD_ZERO(&mask);
- FD_SET(csocket, &mask);
- if ((nfnd = empty(&mask, 10)) <= 0) {
- if (nfnd < 0) {
- perror("cancel");
- }
- if (ptabflg)
- ftpcode = -1;
- lostpeer();
- }
-#else /* BSDSELECT */
-#ifdef IBMSELECT
- if ((nfnd = empty(&csocket, 1, 10)) <= 0) {
- if (nfnd < 0) {
- perror("cancel");
- }
- if (ptabflg)
- ftpcode = -1;
- lostpeer();
- }
-#endif /* IBMSELECT */
-#endif /* BSDSELECT */
- getreply(0,-1,-1,ftp_vbm,0);
- getreply(0,-1,-1,ftp_vbm,0);
- }
- if (proxy)
- pswitch(0);
- pswitch(1);
- if (ptabflg)
- ftpcode = -1;
- signal(SIGINT, oldintr);
-}
-#endif /* FTP_PROXY */
-
-#ifdef FTP_SECURITY
-#ifdef FTP_GSSAPI
-
-struct {
- CONST gss_OID_desc * CONST * mech_type;
- char *service_name;
-} gss_trials[] = {
- { &gss_mech_krb5, "ftp" },
- { &gss_mech_krb5, "host" },
-};
-
-int n_gss_trials = sizeof(gss_trials)/sizeof(gss_trials[0]);
-#endif /* FTP_GSSAPI */
-
-static int
-ftp_auth() {
- extern int setsafe();
- int j = 0, n;
-#ifdef FTP_KRB4
- char *service, inst[INST_SZ];
- ULONG cksum;
- ULONG checksum = (ULONG) getpid();
- CHAR out_buf[FTP_BUFSIZ];
- int i;
-#else /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- CHAR out_buf[FTP_BUFSIZ];
- int i;
-#endif /* FTP_GSSAPI */
-#endif /* FTP_KRB4 */
-
- if (ssl_ftp_proxy) /* Do not allow AUTH over SSL proxy */
- return(0);
-
- if (auth_type)
- return(1); /* auth already succeeded */
-
- /* Try each auth type as specified by the end user */
- for (j = 0; j < 8 && ftp_auth_type[j] != 0; j++) {
-#ifdef FTP_GSSAPI
- if (ftp_auth_type[j] == FTA_GK5 && ck_gssapi_is_installed()) {
- n = ftpcmd("AUTH GSSAPI",NULL,0,0,ftp_vbm);
- if (n == REPLY_CONTINUE) {
- OM_uint32 maj_stat, min_stat;
- gss_name_t target_name;
- gss_buffer_desc send_tok, recv_tok, *token_ptr;
- char stbuf[FTP_BUFSIZ];
- int comcode, trial;
- struct gss_channel_bindings_struct chan;
- char * realm = NULL;
- char tgt[256];
-
- chan.initiator_addrtype = GSS_C_AF_INET; /* OM_uint32 */
- chan.initiator_address.length = 4;
- chan.initiator_address.value = &myctladdr.sin_addr.s_addr;
- chan.acceptor_addrtype = GSS_C_AF_INET; /* OM_uint32 */
- chan.acceptor_address.length = 4;
- chan.acceptor_address.value = &hisctladdr.sin_addr.s_addr;
- chan.application_data.length = 0;
- chan.application_data.value = 0;
-
- if (!quiet)
- printf("GSSAPI accepted as authentication type\n");
-
- realm = ck_krb5_realmofhost(ftp_user_host);
- if (realm) {
- ckmakmsg(tgt,sizeof(tgt),"krbtgt/",realm,"@",realm);
- debug(F110,"ftp_auth(GSSAPI) TGT",tgt,0);
- if ( krb5_autoget &&
- !((ck_krb5_tkt_isvalid(NULL,tgt) > 0) ||
- (ck_krb5_is_tgt_valid() > 0)) )
- ck_krb5_autoget_TGT(realm);
- }
-
- /* Blob from gss-client */
- for (trial = 0; trial < n_gss_trials; trial++) {
- /* ftp@hostname first, the host@hostname */
- /* the V5 GSSAPI binding canonicalizes this for us... */
- ckmakmsg(stbuf,FTP_BUFSIZ,
- gss_trials[trial].service_name,
- "@",
- ftp_user_host,
- NULL
- );
- if (ftp_deb)
- fprintf(stderr,
- "Authenticating to <%s>...\n", stbuf);
- send_tok.value = stbuf;
- send_tok.length = strlen(stbuf);
- maj_stat = gss_import_name(&min_stat, &send_tok,
- gss_nt_service_name,
- &target_name
- );
- if (maj_stat != GSS_S_COMPLETE) {
- user_gss_error(maj_stat, min_stat, "parsing name");
- secure_error("name parsed <%s>\n", stbuf);
- continue;
- }
- token_ptr = GSS_C_NO_BUFFER;
- gcontext = GSS_C_NO_CONTEXT; /* structure copy */
-
- do {
- if (ftp_deb)
- fprintf(stderr, "calling gss_init_sec_context\n");
- maj_stat =
- gss_init_sec_context(&min_stat,
- GSS_C_NO_CREDENTIAL,
- &gcontext,
- target_name,
- (gss_OID) *
- gss_trials[trial].mech_type,
- GSS_C_MUTUAL_FLAG |
- GSS_C_REPLAY_FLAG |
- (ftp_cfw ?
- GSS_C_DELEG_FLAG : 0),
- 0,
- /* channel bindings */
- (krb5_d_no_addresses ?
- GSS_C_NO_CHANNEL_BINDINGS :
- &chan),
- token_ptr,
- NULL, /* ignore mech type */
- &send_tok,
- NULL, /* ignore ret_flags */
- NULL
- ); /* ignore time_rec */
-
- if (maj_stat != GSS_S_COMPLETE &&
- maj_stat != GSS_S_CONTINUE_NEEDED) {
- if (trial == n_gss_trials-1)
- user_gss_error(maj_stat,
- min_stat,
- "initializing context"
- );
- gss_release_name(&min_stat, &target_name);
- /* maybe we missed on the service name */
- goto outer_loop;
- }
- if (send_tok.length != 0) {
- int len;
- reply_parse = "ADAT="; /* for ftpcmd() later */
- len = FTP_BUFSIZ;
- kerror =
- radix_encode(send_tok.value,
- out_buf,
- send_tok.length,
- &len,
- RADIX_ENCODE
- );
- if (kerror) {
- fprintf(stderr,
- "Base 64 encoding failed: %s\n",
- radix_error(kerror)
- );
- goto gss_complete_loop;
- }
- comcode = ftpcmd("ADAT",out_buf,-1,-1,0);
- if (comcode != REPLY_COMPLETE
- && comcode != REPLY_CONTINUE /* (335) */
- ) {
- if (trial == n_gss_trials-1) {
- fprintf(stderr, "GSSAPI ADAT failed\n");
- /* force out of loop */
- maj_stat = GSS_S_FAILURE;
- }
- /*
- Backoff to the v1 gssapi is still possible.
- Send a new AUTH command. If that fails,
- terminate the loop.
- */
- if (ftpcmd("AUTH GSSAPI",NULL,0,0,ftp_vbm)
- != REPLY_CONTINUE) {
- fprintf(stderr,
- "GSSAPI ADAT failed, AUTH restart failed\n");
- /* force out of loop */
- maj_stat = GSS_S_FAILURE;
- }
- goto outer_loop;
- }
- if (!reply_parse) {
- fprintf(stderr,
- "No authentication data received from server\n");
- if (maj_stat == GSS_S_COMPLETE) {
- fprintf(stderr,
- "...but no more was needed\n");
- goto gss_complete_loop;
- } else {
- user_gss_error(maj_stat,
- min_stat,
- "no reply, huh?"
- );
- goto gss_complete_loop;
- }
- }
- len = FTP_BUFSIZ;
- kerror = radix_encode(reply_parse,out_buf,i,&len,
- RADIX_DECODE);
- if (kerror) {
- fprintf(stderr,
- "Base 64 decoding failed: %s\n",
- radix_error(kerror));
- goto gss_complete_loop;
- }
-
- /* everything worked */
- token_ptr = &recv_tok;
- recv_tok.value = out_buf;
- recv_tok.length = len;
- continue;
-
- /* get out of loop clean */
- gss_complete_loop:
- trial = n_gss_trials-1;
- gss_release_buffer(&min_stat, &send_tok);
- gss_release_name(&min_stat, &target_name);
- goto outer_loop;
- }
- } while (maj_stat == GSS_S_CONTINUE_NEEDED);
-
- outer_loop:
- if (maj_stat == GSS_S_COMPLETE)
- break;
- }
- if (maj_stat == GSS_S_COMPLETE) {
- printf("GSSAPI authentication succeeded\n");
- reply_parse = NULL;
- auth_type = "GSSAPI";
- return(1);
- } else {
- fprintf(stderr, "GSSAPI authentication failed\n");
- reply_parse = NULL;
- }
- } else {
- if (ftp_deb)
- fprintf(stderr, "GSSAPI rejected as an authentication type\n");
- if (ftpcode == 500 || ftpcode == 502)
- return(0);
- }
- }
-#endif /* FTP_GSSAPI */
-#ifdef FTP_SRP
- if (ftp_auth_type[j] == FTA_SRP && ck_srp_is_installed()) {
- if (srp_ftp_auth(ftp_user_host,NULL,NULL))
- return(1);
- else if (ftpcode == 500 || ftpcode == 502)
- return(0);
- }
-#endif /* FTP_SRP */
-#ifdef FTP_KRB4
- if (ftp_auth_type[j] == FTA_K4 && ck_krb4_is_installed()) {
- n = ftpcmd("AUTH KERBEROS_V4",NULL,0,0,ftp_vbm);
- if (n == REPLY_CONTINUE) {
- char tgt[4*REALM_SZ+1];
- int rc;
-
- if (!quiet)
- printf("KERBEROS_V4 accepted as authentication type\n");
- ckstrncpy(inst, (char *) krb_get_phost(ftp_user_host),INST_SZ);
- ckstrncpy(ftp_realm,
- (char *)ck_krb4_realmofhost(ftp_user_host),
- REALM_SZ
- );
-
- ckmakmsg(tgt,sizeof(tgt),"krbtgt.",ftp_realm,"@",ftp_realm);
- rc = ck_krb4_tkt_isvalid(tgt);
-
- if (rc <= 0 && krb4_autoget)
- ck_krb4_autoget_TGT(ftp_realm);
-
- service = "ftp";
- kerror = krb_mk_req(&ftp_tkt,service,inst,ftp_realm,checksum);
- if (kerror == KDC_PR_UNKNOWN) {
- service = "rcmd";
- kerror = krb_mk_req(&ftp_tkt,
- service,
- inst,
- ftp_realm,
- checksum
- );
- }
- if (kerror)
- fprintf(stderr, "Kerberos V4 krb_mk_req failed: %s\n",
- krb_get_err_text(kerror));
- if (!kerror) {
- kerror = krb_get_cred(service, inst, ftp_realm,&ftp_cred);
- if (kerror)
- fprintf(stderr, "Kerberos V4 krb_get_cred failed: %s\n",
- krb_get_err_text(kerror));
- }
- if (!kerror) {
- int rc;
- rc = des_key_sched(ftp_cred.session, ftp_sched);
- if (rc == -1) {
- printf("?Invalid DES key specified in credentials\r\n");
- debug(F110,"ftp_auth",
- "invalid DES Key specified in credentials",0);
- } else if ( rc == -2 ) {
- printf("?Weak DES key specified in credentials\r\n");
- debug(F110,"ftp_auth",
- "weak DES Key specified in credentials",0);
- } else if ( rc != 0 ) {
- printf("?DES Key Schedule not set by credentials\r\n");
- debug(F110,"ftp_auth",
- "DES Key Schedule not set by credentials",0);
- }
- reply_parse = "ADAT=";
- i = FTP_BUFSIZ;
- kerror = radix_encode(ftp_tkt.dat, out_buf, ftp_tkt.length,
- &i, RADIX_ENCODE);
- if (kerror) {
- fprintf(stderr, "Base 64 encoding failed: %s\n",
- radix_error(kerror));
- goto krb4_err;
- }
- if (i > FTP_BUFSIZ - 6)
- printf("?ADAT data too long\n");
- if (ftpcmd("ADAT",out_buf,-1,-1,0) !=
- REPLY_COMPLETE) {
- fprintf(stderr, "Kerberos V4 authentication failed\n");
- goto krb4_err;
- }
- if (!reply_parse) {
- fprintf(stderr,
- "No authentication data received from server\n");
- goto krb4_err;
- }
- i = sizeof(out_buf);
- kerror =
- radix_encode(reply_parse, out_buf, 0, &i, RADIX_DECODE);
- if (kerror) {
- fprintf(stderr, "Base 64 decoding failed: %s\n",
- radix_error(kerror));
- goto krb4_err;
- }
- kerror = krb_rd_safe(out_buf, i,
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &hisctladdr,
- &myctladdr,
- &ftp_msg_data
- );
- if (kerror) {
- fprintf(stderr, "Kerberos V4 krb_rd_safe failed: %s\n",
- krb_get_err_text(kerror));
- goto krb4_err;
- }
-
- /* fetch the (modified) checksum */
- memcpy(&cksum, ftp_msg_data.app_data, sizeof(cksum));
- if (ntohl(cksum) == checksum + 1) {
- if (ftp_vbm)
- printf("Kerberos V4 authentication succeeded\n");
- reply_parse = NULL;
- auth_type = "KERBEROS_V4";
- return(1);
- } else
- fprintf(stderr,
- "Kerberos V4 mutual authentication failed\n");
- krb4_err:
- reply_parse = NULL;
- }
- } else {
- if (ftp_deb)
- fprintf(stderr,
- "KERBEROS_V4 rejected as an authentication type\n");
- if (ftpcode == 500 || ftpcode == 502)
- return(0);
- }
- }
-#endif /* FTP_KRB4 */
-#ifdef CK_SSL
- if (ftp_auth_type[j] == FTA_TLS && ck_ssleay_is_installed()) {
-#ifdef FTPHOST
- if (!hostcmd) {
- ftpcmd("HOST",ftp_user_host,0,0,0);
- hostcmd = 1;
- }
-#endif /* FTPHOST */
- n = ftpcmd("AUTH TLS",NULL,0,0,ftp_vbm);
- if (n != REPLY_COMPLETE)
- n = ftpcmd("AUTH TLS-P",NULL,0,0,ftp_vbm);
- if (n == REPLY_COMPLETE) {
- if (!quiet)
- printf("TLS accepted as authentication type\n");
-
- auth_type = "TLS";
- ssl_auth();
- if (ssl_ftp_active_flag ) {
- ftp_dpl = FPL_CLR;
- ftp_cpl = FPL_PRV;
- return(1);
- } else {
- fprintf(stderr,"TLS authentication failed\n");
- auth_type = NULL;
-#ifdef TCPIPLIB
- socket_close(csocket);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(csocket, 1+1);
-#endif /* USE_SHUTDOWN */
- close(csocket);
-#endif /* TCPIPLIB */
- csocket = -1;
- if (ftp_hookup(ftp_user_host,ftp_port,0) == NULL)
- return(0);
- }
- } else {
- if (ftp_deb)
- fprintf(stderr,"TLS rejected as an authentication type\n");
- if (ftpcode == 500 || ftpcode == 502)
- return(0);
- }
- }
- if (ftp_auth_type[j] == FTA_SSL && ck_ssleay_is_installed()) {
-#ifdef FTPHOST
- if (!hostcmd) {
- ftpcmd("HOST",ftp_user_host,0,0,0);
- hostcmd = 1;
- }
-#endif /* FTPHOST */
- n = ftpcmd("AUTH SSL",NULL,0,0,ftp_vbm);
- if (n == REPLY_CONTINUE || n == REPLY_COMPLETE) {
- if (!quiet)
- printf("SSL accepted as authentication type\n");
- auth_type = "SSL";
- ssl_auth();
- if (ssl_ftp_active_flag) {
- ftp_dpl = FPL_PRV;
- ftp_cpl = FPL_PRV;
- setprotbuf(1<<20);
- return(1);
- } else {
- fprintf(stderr,"SSL authentication failed\n");
- auth_type = NULL;
-#ifdef TCPIPLIB
- socket_close(csocket);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(csocket, 1+1);
-#endif /* USE_SHUTDOWN */
- close(csocket);
-#endif /* TCPIPLIB */
- csocket = -1;
- if (ftp_hookup(ftp_user_host,ftp_port,0) == NULL)
- return(0);
- }
- } else {
- if (ftp_deb)
- fprintf(stderr, "SSL rejected as an authentication type\n");
- if (ftpcode == 500 || ftpcode == 502)
- return(0);
- }
- }
-#endif /* CK_SSL */
- /* Other auth types go here ... */
- } /* for (j;;) */
- return(0);
-}
-#endif /* FTP_SECURITY */
-
-static int
-#ifdef CK_ANSIC
-setprotbuf(unsigned int size)
-#else
-setprotbuf(size) unsigned int size;
-#endif /* CK_ANSIC */
-/* setprotbuf */ {
- if (ucbuf)
- free(ucbuf);
- ucbuf = NULL;
- ucbufsiz = 0;
- actualbuf = size;
- while ((ucbuf = (CHAR *)malloc(actualbuf)) == NULL) {
- if (actualbuf)
- actualbuf /= 2;
- else
- return(0);
- }
- ucbufsiz = actualbuf - FUDGE_FACTOR;
- debug(F101,"setprotbuf ucbufsiz","",ucbufsiz);
- if (ucbufsiz < 128) {
- printf("WARNING: tiny ucbufsiz: %d\n",ucbufsiz);
- } else if (ucbufsiz < 0) {
- printf("ERROR: ucbuf allocation failure\n");
- return(-1);
- }
- maxbuf = actualbuf;
- return(1);
-}
-
-static int
-#ifdef CK_ANSIC
-setpbsz(unsigned int size)
-#else
-setpbsz(size) unsigned int size;
-#endif /* CK_ANSIC */
-/* setpbsz */ {
- if (!setprotbuf(size)) {
- perror("?Error while trying to malloc PROT buffer:");
-#ifdef FTP_SRP
- srp_reset();
-#endif /* FTP_SRP */
- ftpclose();
- return(-1);
- }
- reply_parse = "PBSZ=";
- ckmakmsg(ftpcmdbuf,FTP_BUFSIZ,"PBSZ ",
-#ifdef CK_SSL
- ssl_ftp_active_flag ? "0" :
-#endif /* CK_SSL */
- ckuitoa(actualbuf),NULL,NULL);
- if (ftpcmd(ftpcmdbuf,NULL,0,0,0) != REPLY_COMPLETE) {
- if (connected) {
- printf("?Unable to negotiate PROT buffer size with FTP server\n");
- ftpclose();
- }
- return(-1);
- }
- if (reply_parse) {
- if ((maxbuf = (unsigned int) atol(reply_parse)) > actualbuf)
- maxbuf = actualbuf;
- } else
- maxbuf = actualbuf;
- ucbufsiz = maxbuf - FUDGE_FACTOR;
- debug(F101,"setpbsz ucbufsiz","",ucbufsiz);
- reply_parse = NULL;
- return(0);
-}
-
-static VOID
-cancel_remote(din) int din; {
- CHAR buf[FTP_BUFSIZ];
- int x, nfnd;
-#ifdef BSDSELECT
- fd_set mask;
-#endif /* BSDSELECT */
-#ifdef IBMSELECT
- int fds[2], fdcnt = 0;
-#endif /* IBMSELECT */
-#ifdef DEBUG
- extern int debtim;
- int xdebtim;
- xdebtim = debtim;
- debtim = 1;
-#endif /* DEBUG */
- debug(F100,"ftp cancel_remote entry","",0);
-#ifdef CK_SSL
- if (ssl_ftp_active_flag) {
- /*
- * Send Telnet IP, Telnet DM but do so inline and within the
- * TLS channel
- */
- int count, error;
-
- buf[0] = IAC;
- buf[1] = TN_IP;
- buf[2] = IAC;
- buf[3] = TN_DM;
- buf[4] = NUL;
-
- count = SSL_write(ssl_ftp_con, buf, 4);
- debug(F111,"ftp cancel_remote","SSL_write(IAC IP IAC DM)",count);
- error = SSL_get_error(ssl_ftp_con,count);
- debug(F111,"ftp cancel_remote","SSL_get_error()",error);
- switch (error) {
- case SSL_ERROR_NONE:
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_SYSCALL:
-#ifdef NT
- {
- int gle = GetLastError();
- }
-#endif /* NT */
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- lostpeer();
- return;
- }
- } else
-#endif /* CK_SSL */
- {
- /*
- * send IAC in urgent mode instead of DM because 4.3BSD places oob mark
- * after urgent byte rather than before as is protocol now.
- */
- buf[0] = IAC;
- buf[1] = TN_IP;
- buf[2] = IAC;
- buf[3] = NUL;
- if ((x = send(csocket, (SENDARG2TYPE)buf, 3, MSG_OOB)) != 3)
- perror("cancel");
- debug(F101,"ftp cancel_remote send 1","",x);
- buf[0] = TN_DM;
- x = send(csocket,(SENDARG2TYPE)buf,1,0);
- debug(F101,"ftp cancel_remote send 2","",x);
- }
- x = scommand("ABOR");
- debug(F101,"ftp cancel_remote scommand","",x);
-#ifdef BSDSELECT
- FD_ZERO(&mask);
- FD_SET(csocket, &mask);
- if (din) {
- FD_SET(din, &mask);
- }
- nfnd = empty(&mask, 10);
- debug(F101,"ftp cancel_remote empty","",nfnd);
- if ((nfnd) <= 0) {
- if (nfnd < 0) {
- perror("cancel");
- }
-#ifdef FTP_PROXY
- if (ptabflg)
- ftpcode = -1;
-#endif /* FTP_PROXY */
- lostpeer();
- }
- debug(F110,"ftp cancel_remote","D",0);
- if (din && FD_ISSET(din, &mask)) {
- /* Security: No threat associated with this read. */
- /* But you can't simply read the TLS data stream */
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- int count, error;
- while ((count = SSL_read(ssl_ftp_data_con, buf, FTP_BUFSIZ)) > 0)
- /* LOOP */ ;
- } else
-#endif /* CK_SSL */
- {
- while (recv(din, (SENDARG2TYPE)buf, FTP_BUFSIZ,0) > 0)
- /* LOOP */ ;
- }
- }
- debug(F110,"ftp cancel_remote","E",0);
-#else /* BSDSELECT */
-#ifdef IBMSELECT
- fds[0] = csocket;
- fdcnt++;
- if (din) {
- fds[1] = din;
- fdcnt++;
- }
- nfnd = empty(fds, fdcnt, 10);
- debug(F101,"ftp cancel_remote empty","",nfnd);
- if ((nfnd) <= 0) {
- if (nfnd < 0) {
- perror("cancel");
- }
-#ifdef FTP_PROXY
- if (ptabflg)
- ftpcode = -1;
-#endif /* FTP_PROXY */
- lostpeer();
- }
- debug(F110,"ftp cancel_remote","D",0);
- if (din && select(&din, 1,0,0,1) ) {
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- int count, error;
- while ((count = SSL_read(ssl_ftp_data_con, buf, FTP_BUFSIZ)) > 0)
- /* LOOP */ ;
- } else
-#endif /* CK_SSL */
- {
- while (recv(din, (SENDARG2TYPE)buf, FTP_BUFSIZ,0) > 0)
- /* LOOP */ ;
- }
- }
- debug(F110,"ftp cancel_remote","E",0);
-#else /* IBMSELECT */
- Some form of select is required.
-#endif /* IBMSELECT */
-#endif /* BSDSELECT */
- if (getreply(0,-1,-1,ftp_vbm,0) == REPLY_ERROR && ftpcode == 552) {
- debug(F110,"ftp cancel_remote","F",0);
- /* 552 needed for NIC style cancel */
- getreply(0,-1,-1,ftp_vbm,0);
- debug(F110,"ftp cancel_remote","G",0);
- }
- debug(F110,"ftp cancel_remote","H",0);
- getreply(0,-1,-1,ftp_vbm,0);
- debug(F110,"ftp cancel_remote","I",0);
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
-}
-
-static int
-fts_dpl(x) int x; {
- if (!auth_type
-#ifdef OS2
- || !ck_crypt_is_installed()
-#endif /* OS2 */
- ) {
- switch ( x ) {
- case FPL_PRV:
- printf("?Cannot set protection level to PRIVATE\n");
- return(0);
- case FPL_SAF:
- printf("?Cannot set protection level to SAFE\n");
- return(0);
- }
- ftp_dpl = x;
- return(1);
- }
-
-#ifdef CK_SSL
- if (x == FPL_SAF &&
- (!strcmp(auth_type,"SSL") || !strcmp(auth_type,"TLS"))) {
- printf("Cannot set protection level to safe\n");
- return(0);
- }
-#endif /* CK_SSL */
- /* Start with a PBSZ of 1 meg */
- if (x != FPL_CLR) {
- if (setpbsz(DEFAULT_PBSZ) < 0)
- return(0);
- }
- y = ftpcmd(x == FPL_CLR ? "PROT C" :
- (x == FPL_SAF ? "PROT S" : "PROT P"), NULL, 0, 0,ftp_vbm);
- if (y == REPLY_COMPLETE) {
- ftp_dpl = x;
- return(1);
- }
- return(0);
-}
-
-static int
-fts_cpl(x) int x; {
- if (!auth_type
-#ifdef OS2
- || !ck_crypt_is_installed()
-#endif /* OS2 */
- ) {
- switch ( x ) {
- case FPL_PRV:
- printf("?Cannot set protection level to PRIVATE\n");
- return(0);
- case FPL_SAF:
- printf("?Cannot set protection level to SAFE\n");
- return(0);
- }
- ftp_cpl = x;
- return(1);
- }
- if (x == FPL_CLR) {
- y = ftpcmd("CCC",NULL,0,0,ftp_vbm);
- if (y == REPLY_COMPLETE) {
- ftp_cpl = x;
- return(1);
- }
- return(0);
- }
- ftp_cpl = x;
- return(1);
-}
-
-#ifdef FTP_GSSAPI
-static VOID
-user_gss_error(maj_stat, min_stat, s)
- OM_uint32 maj_stat, min_stat;
- char *s;
-{
- /* a lot of work just to report the error */
- OM_uint32 gmaj_stat, gmin_stat, msg_ctx;
- gss_buffer_desc msg;
- msg_ctx = 0;
- while (!msg_ctx) {
- gmaj_stat = gss_display_status(&gmin_stat, maj_stat,
- GSS_C_GSS_CODE,
- GSS_C_NULL_OID,
- &msg_ctx,
- &msg
- );
- if ((gmaj_stat == GSS_S_COMPLETE)||
- (gmaj_stat == GSS_S_CONTINUE_NEEDED)) {
- fprintf(stderr, "GSSAPI error major: %s\n",
- (char*)msg.value);
- gss_release_buffer(&gmin_stat, &msg);
- }
- if (gmaj_stat != GSS_S_CONTINUE_NEEDED)
- break;
- }
- msg_ctx = 0;
- while (!msg_ctx) {
- gmaj_stat = gss_display_status(&gmin_stat, min_stat,
- GSS_C_MECH_CODE,
- GSS_C_NULL_OID,
- &msg_ctx,
- &msg
- );
- if ((gmaj_stat == GSS_S_COMPLETE)||
- (gmaj_stat == GSS_S_CONTINUE_NEEDED)) {
- fprintf(stderr, "GSSAPI error minor: %s\n", (char*)msg.value);
- gss_release_buffer(&gmin_stat, &msg);
- }
- if (gmaj_stat != GSS_S_CONTINUE_NEEDED)
- break;
- }
- fprintf(stderr, "GSSAPI error: %s\n", s);
-}
-#endif /* FTP_GSSAPI */
-
-#ifndef NOMHHOST
-#ifdef datageneral
-#define NOMHHOST
-#else
-#ifdef HPUX5WINTCP
-#define NOMHHOST
-#endif /* HPUX5WINTCP */
-#endif /* datageneral */
-#endif /* NOMHHOST */
-
-#ifdef INADDRX
-static struct in_addr inaddrx;
-#endif /* INADDRX */
-
-static char *
-ftp_hookup(host, port, tls) char * host; int port; int tls; {
- register struct hostent *hp = 0;
-#ifdef IP_TOS
-#ifdef IPTOS_THROUGHPUT
- int tos;
-#endif /* IPTOS_THROUGHPUT */
-#endif /* IP_TOS */
- int s;
- GSOCKNAME_T len;
- static char hostnamebuf[MAXHOSTNAMELEN];
- char hostname[MAXHOSTNAMELEN] /* , *p, *q */ ;
- int cport;
-#ifdef DEBUG
- extern int debtim;
- int xdebtim;
- xdebtim = debtim;
- debtim = 1;
-#endif /* DEBUG */
-
-#ifndef NOHTTP
- if (tcp_http_proxy) {
- struct servent *destsp;
- char *p, *q;
-
- ckmakmsg(proxyhost,HTTPCPYL,host,":",ckuitoa(port),NULL);
- for (p = tcp_http_proxy, q = hostname;
- *p != '\0' && *p != ':';
- p++, q++
- )
- *q = *p;
- *q = '\0';
-
- if (*p == ':')
- p++;
- else
- p = "http";
-
- destsp = getservbyname(p,"tcp");
- if (destsp)
- cport = ntohs(destsp->s_port);
- else if (p) {
- cport = atoi(p);
- } else
- cport = 80;
- } else
-#endif /* NOHTTP */
- {
- ckstrncpy(hostname,host,MAXHOSTNAMELEN);
- cport = port;
- }
- memset((char *)&hisctladdr, 0, sizeof (hisctladdr));
- hisctladdr.sin_addr.s_addr = inet_addr(host);
- if (hisctladdr.sin_addr.s_addr != -1) {
- debug(F110,"ftp hookup A",hostname,0);
- hisctladdr.sin_family = AF_INET;
- ckstrncpy(hostnamebuf, hostname, MAXHOSTNAMELEN);
- } else {
- debug(F110,"ftp hookup B",hostname,0);
- hp = gethostbyname(hostname);
-#ifdef HADDRLIST
- hp = ck_copyhostent(hp); /* make safe copy that won't change */
-#endif /* HADDRLIST */
- if (hp == NULL) {
- fprintf(stderr, "ftp: %s: Unknown host\n", host);
- ftpcode = -1;
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
- return((char *) 0);
- }
- hisctladdr.sin_family = hp->h_addrtype;
-#ifdef HADDRLIST
- memcpy((char *)&hisctladdr.sin_addr, hp->h_addr_list[0],
- sizeof(hisctladdr.sin_addr));
-#else /* HADDRLIST */
- memcpy((char *)&hisctladdr.sin_addr, hp->h_addr,
- sizeof(hisctladdr.sin_addr));
-#endif /* HADDRLIST */
- ckstrncpy(hostnamebuf, hp->h_name, MAXHOSTNAMELEN);
- }
- debug(F110,"ftp hookup C",hostnamebuf,0);
- ftp_host = hostnamebuf;
- s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
- debug(F101,"ftp hookup socket","",s);
- if (s < 0) {
- perror("ftp: socket");
- ftpcode = -1;
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
- return(0);
- }
- hisctladdr.sin_port = htons(cport);
- errno = 0;
-#ifdef HADDRLIST
- debug(F100,"ftp hookup HADDRLIST","",0);
- while
-#else
- debug(F100,"ftp hookup no HADDRLIST","",0);
- if
-#endif /* HADDRLIST */
- (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {
- debug(F101,"ftp hookup connect failed","",errno);
-#ifdef HADDRLIST
- if (hp && hp->h_addr_list[1]) {
- int oerrno = errno;
-
- fprintf(stderr, "ftp: connect to address %s: ",
- inet_ntoa(hisctladdr.sin_addr));
- errno = oerrno;
- perror((char *) 0);
- hp->h_addr_list++;
- memcpy((char *)&hisctladdr.sin_addr,
- hp->h_addr_list[0],
- sizeof(hisctladdr.sin_addr));
- fprintf(stdout, "Trying %s...\n",
- inet_ntoa(hisctladdr.sin_addr));
-#ifdef TCPIPLIB
- socket_close(s);
-#else /* TCPIPLIB */
- close(s);
-#endif /* TCPIPLIB */
- s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
- if (s < 0) {
- perror("ftp: socket");
- ftpcode = -1;
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
- return(0);
- }
- continue;
- }
-#endif /* HADDRLIST */
- perror("ftp: connect");
- ftpcode = -1;
- goto bad;
- }
- debug(F100,"ftp hookup connect ok","",0);
-
- len = sizeof (myctladdr);
- errno = 0;
- if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
- debug(F101,"ftp hookup getsockname failed","",errno);
- perror("ftp: getsockname");
- ftpcode = -1;
- goto bad;
- }
- debug(F100,"ftp hookup getsockname ok","",0);
-
-#ifndef NOHTTP
- if (tcp_http_proxy) {
-#ifdef OS2
- char * agent = "Kermit 95"; /* Default user agent */
-#else
- char * agent = "C-Kermit";
-#endif /* OS2 */
-
- if (http_connect(s,agent,NULL,
- tcp_http_proxy_user,
- tcp_http_proxy_pwd,
- 0,
- proxyhost
- ) < 0) {
- char * foo = NULL;
-#ifdef TCPIPLIB
- socket_close(s);
-#else /* TCPIPLIB */
- close(s);
-#endif /* TCPIPLIB */
-
- while (foo == NULL && tcp_http_proxy != NULL ) {
-
- if (tcp_http_proxy_errno == 401 ||
- tcp_http_proxy_errno == 407 ) {
- char uid[UIDBUFLEN];
- char pwd[PWDSIZ];
- struct txtbox tb[2];
- int ok;
-
- tb[0].t_buf = uid;
- tb[0].t_len = UIDBUFLEN;
- tb[0].t_lbl = "Proxy Userid: ";
- tb[0].t_dflt = NULL;
- tb[0].t_echo = 1;
- tb[1].t_buf = pwd;
- tb[1].t_len = 256;
- tb[1].t_lbl = "Proxy Passphrase: ";
- tb[1].t_dflt = NULL;
- tb[1].t_echo = 2;
-
- ok = uq_mtxt("Proxy Server Authentication Required\n",
- NULL, 2, tb);
-
- if (ok && uid[0]) {
- char * proxy_user, * proxy_pwd;
-
- proxy_user = tcp_http_proxy_user;
- proxy_pwd = tcp_http_proxy_pwd;
-
- tcp_http_proxy_user = uid;
- tcp_http_proxy_pwd = pwd;
-
- foo = ftp_hookup(host, port, 0);
-
- debug(F110,"ftp_hookup()",foo,0);
- memset(pwd,0,PWDSIZ);
- tcp_http_proxy_user = proxy_user;
- tcp_http_proxy_pwd = proxy_pwd;
- } else
- break;
- } else
- break;
- }
- if (foo != NULL)
- return(foo);
- perror("ftp: connect");
- ftpcode = -1;
- goto bad;
- }
- ckstrncpy(hostnamebuf, proxyhost, MAXHOSTNAMELEN);
- }
-#endif /* NOHTTP */
-
- csocket = s;
-
-#ifdef CK_SSL
- if (tls) {
- /* FTP over SSL
- * If the connection is over an SSL proxy then the
- * auth_type will be NULL. However, I'm not sure
- * whether we should protect the data channel in
- * that case or not.
- */
-
- debug(F100,"ftp hookup use_tls","",0);
- if (!ssl_auth()) {
- debug(F100,"ftp hookup ssl_auth failed","",0);
- auth_type = NULL;
- ftpcode = -1;
- csocket = -1;
- goto bad;
- }
- ssl_ftp_proxy = 1;
- }
-#endif /* CK_SSL */
-
-#ifdef IP_TOS
-#ifdef IPTOS_LOWDELAY
- tos = IPTOS_LOWDELAY;
- if (setsockopt(csocket, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
- perror("ftp: setsockopt TOS (ignored)");
-#endif
-#endif
- if (!quiet)
- printf("Connected to %s.\n", host);
-
- /* Read greeting from server */
- if (getreply(0,ftp_csl,ftp_csr,ftp_vbm,0) > 2) {
- debug(F100,"ftp hookup bad reply","",0);
-#ifdef TCPIPLIB
- socket_close(csocket);
-#else /* TCPIPLIB */
- close(csocket);
-#endif /* TCPIPLIB */
- ftpcode = -1;
- goto bad;
- }
-#ifdef SO_OOBINLINE
- {
- int on = 1;
- errno = 0;
- if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on,
- sizeof(on)) < 0) {
- perror("ftp: setsockopt");
- debug(F101,"ftp hookup setsockopt failed","",errno);
- }
-#ifdef DEBUG
- else
- debug(F100,"ftp hookup setsockopt ok","",0);
-#endif /* DEBUG */
- }
-#endif /* SO_OOBINLINE */
-
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
- return(ftp_host);
-
- bad:
- debug(F100,"ftp hookup bad","",0);
-#ifdef TCPIPLIB
- socket_close(s);
-#else /* TCPIPLIB */
- close(s);
-#endif /* TCPIPLIB */
-#ifdef DEBUG
- debtim = xdebtim;
-#endif /* DEBUG */
- csocket = -1;
- return((char *)0);
-}
-
-static VOID
-ftp_init() {
- int i, n;
-
- /* The purpose of the initial REST 0 is not clear, but other FTP */
- /* clients do it. In any case, failure of this command is not a */
- /* reliable indication that the server does not support Restart. */
-
- okrestart = 0;
- if (!noinit) {
- n = ftpcmd("REST 0",NULL,0,0,0);
- if (n == REPLY_COMPLETE)
- okrestart = 1;
-#ifdef COMMENT
- else if (ftp_deb)
- printf("WARNING: Unable to restore file pointer.\n");
-#endif /* COMMENT */
- }
- n = ftpcmd("SYST",NULL,0,0,0); /* Get server system type */
- if (n == REPLY_COMPLETE) {
- register char *cp, c = NUL;
- cp = ckstrchr(ftp_reply_str+4,' '); /* Get first word of reply */
- if (cp == NULL)
- cp = ckstrchr(ftp_reply_str+4,'\r');
- if (cp) {
- if (cp[-1] == '.')
- cp--;
- c = *cp; /* Save this char */
- *cp = '\0'; /* Replace it with NUL */
- }
- if (!quiet)
- printf("Remote system type is %s.\n",ftp_reply_str+4);
- ckstrncpy(ftp_srvtyp,ftp_reply_str+4,SRVNAMLEN);
- if (cp) /* Put back saved char */
- *cp = c;
- }
- alike = !ckstrcmp(ftp_srvtyp,myostype,-1,0);
-
- if (!ckstrcmp(ftp_srvtyp,"UNIX",-1,0)) servertype = SYS_UNIX;
- else if (!ckstrcmp(ftp_srvtyp,"WIN32",-1,0)) servertype = SYS_WIN32;
- else if (!ckstrcmp(ftp_srvtyp,"OS/2",-1,0)) servertype = SYS_WIN32;
- else if (!ckstrcmp(ftp_srvtyp,"VMS",-1,0)) servertype = SYS_VMS;
- else if (!ckstrcmp(ftp_srvtyp,"DOS",-1,0)) servertype = SYS_DOS;
- else if (!ckstrcmp(ftp_srvtyp,"TOPS20",-1,0)) servertype = SYS_TOPS20;
- else if (!ckstrcmp(ftp_srvtyp,"TOPS10",-1,0)) servertype = SYS_TOPS10;
-
-#ifdef FTP_PROXY
- unix_proxy = 0;
- if (servertype == SYS_UNIX && proxy) unix_proxy = 1;
-#endif /* FTP_PROXY */
-
- if (ftp_cmdlin && xfermode == XMODE_M)
- ftp_typ = binary; /* Type given on command line */
- else /* Otherwise set it automatically */
- ftp_typ = alike ? FTT_BIN : FTT_ASC;
- changetype(ftp_typ,0); /* Change to this type */
- g_ftp_typ = ftp_typ; /* Make it the global type */
- if (!quiet)
- printf("Default transfer mode is %s\n",
- ftp_typ ? "BINARY" : "TEXT (\"ASCII\")"
- );
- for (i = 0; i < 16; i++) /* Init server FEATure table */
- sfttab[i] = 0;
- if (!noinit) {
- n = ftpcmd("MODE S",NULL,0,0,0); /* We always send in Stream mode */
-#ifdef COMMENT
- if (n != REPLY_COMPLETE)
- printf("WARNING: Server does not accept MODE S(TREAM)\n");
-#endif /* COMMENT */
- n = ftpcmd("STRU F",NULL,0,0,0); /* STRU File (not Record or Page) */
-#ifdef COMMENT
- if (n != REPLY_COMPLETE)
- printf("WARNING: Server does not accept STRU F(ILE)\n");
-#endif /* COMMENT */
- if (featok) {
- n = ftpcmd("FEAT",NULL,0,0,0); /* Ask server about features */
- if (n == REPLY_COMPLETE) {
- debug(F101,"ftp_init FEAT","",sfttab[0]);
- if (deblog || ftp_deb) {
- int i;
- for (i = 1; i < 16 && i < nfeattab; i++) {
- debug(F111,"ftp_init FEAT",feattab[i].kwd,sfttab[i]);
- if (ftp_deb)
- printf(" Server %s %s\n",
- sfttab[i] ? "supports" : "does not support",
- feattab[i].kwd
- );
- }
- /* Deal with disabled MLST opts here if necessary */
- /* But why would it be? */
- }
- }
- }
- }
-}
-
-static int
-ftp_login(host) char * host; { /* (also called from ckuusy.c) */
- static char ftppass[PASSBUFSIZ]="";
- char tmp[PASSBUFSIZ];
- char *user = NULL, *pass = NULL, *acct = NULL;
- int n, aflag = 0;
- extern char uidbuf[];
- extern char pwbuf[];
- extern int pwflg, pwcrypt;
-
- debug(F111,"ftp_login",ftp_logname,ftp_log);
-
- if (!ckstrcmp(ftp_logname,"anonymous",-1,0))
- anonymous = 1;
- if (!ckstrcmp(ftp_logname,"ftp",-1,0))
- anonymous = 1;
-
-#ifdef FTP_SRP
- if (auth_type && !strcmp(auth_type, "SRP")) {
- user = srp_user;
- pass = srp_pass;
- acct = srp_acct;
- } else
-#endif /* FTP_SRP */
- if (anonymous) {
- user = "anonymous";
- if (ftp_tmp) { /* They gave a password */
- pass = ftp_tmp;
- } else if (ftp_apw) { /* SET FTP ANONYMOUS-PASSWORD */
- pass = ftp_apw;
- } else { /* Supply user@host */
- ckmakmsg(tmp,PASSBUFSIZ,whoami(),"@",myhost,NULL);
- pass = tmp;
- }
- debug(F110,"ftp anonymous",pass,0);
- } else {
-#ifdef USE_RUSERPASS
- if (ruserpass(host, &user, &pass, &acct) < 0) {
- ftpcode = -1;
- return(0);
- }
-#endif /* USE_RUSERPASS */
- if (ftp_logname) {
- user = ftp_logname;
- pass = ftp_tmp;
- } else if (uidbuf[0] && (ftp_tmp || pwbuf[0] && pwflg)) {
- user = uidbuf;
- if (ftp_tmp) {
- pass = ftp_tmp;
- } else if (pwbuf[0] && pwflg) {
- ckstrncpy(ftppass,pwbuf,PASSBUFSIZ);
-#ifdef OS2
- if ( pwcrypt )
- ck_encrypt((char *)ftppass);
-#endif /* OS2 */
- pass = ftppass;
- }
- }
- acct = ftp_acc;
- while (user == NULL) {
- char *myname, prompt[PROMPTSIZ];
- int ok;
-
- myname = whoami();
- if (myname)
- ckmakxmsg(prompt,PROMPTSIZ," Name (",host,":",myname,"): ",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- else
- ckmakmsg(prompt,PROMPTSIZ," Name (",host,"): ",NULL);
- tmp[0] = '\0';
-
- ok = uq_txt(NULL,prompt,1,NULL,tmp,PASSBUFSIZ,NULL,
- DEFAULT_UQ_TIMEOUT);
- if (!ok || *tmp == '\0')
- user = myname;
- else
- user = brstrip(tmp);
- }
- }
- n = ftpcmd("USER",user,-1,-1,ftp_vbm);
- if (n == REPLY_COMPLETE) {
- /* determine if we need to send a dummy password */
- if (ftpcmd("PWD",NULL,0,0,0) != REPLY_COMPLETE)
- ftpcmd("PASS dummy",NULL,0,0,1);
- } else if (n == REPLY_CONTINUE) {
-#ifdef CK_ENCRYPTION
- int oldftp_cpl;
-#endif /* CK_ENCRYPTION */
-
- if (pass == NULL) {
- int ok;
- setint();
- ok = uq_txt(NULL," Password: ",2,NULL,ftppass,PASSBUFSIZ,NULL,
- DEFAULT_UQ_TIMEOUT);
- if (ok)
- pass = brstrip(ftppass);
- }
-
-#ifdef CK_ENCRYPTION
- oldftp_cpl = ftp_cpl;
- ftp_cpl = FPL_PRV;
-#endif /* CK_ENCRYPTION */
- n = ftpcmd("PASS",pass,-1,-1,1);
- if (!anonymous && pass) {
- char * p = pass;
- while (*p++) *(p-1) = NUL;
- makestr(&ftp_tmp,NULL);
- }
-#ifdef CK_ENCRYPTION
- /* level may have changed */
- if (ftp_cpl == FPL_PRV)
- ftp_cpl = oldftp_cpl;
-#endif /* CK_ENCRYPTION */
- }
- if (n == REPLY_CONTINUE) {
- aflag++;
- if (acct == NULL) {
- static char ftpacct[80];
- int ok;
- setint();
- ok = uq_txt(NULL," Account: ",2,NULL,ftpacct,80,NULL,
- DEFAULT_UQ_TIMEOUT);
- if (ok)
- acct = brstrip(ftpacct);
- }
- n = ftpcmd("ACCT",acct,-1,-1,ftp_vbm);
- }
- if (n != REPLY_COMPLETE) {
- fprintf(stderr, "FTP login failed.\n");
- if (haveurl)
- doexit(BAD_EXIT,-1);
- return(0);
- }
- if (!aflag && acct != NULL) {
- ftpcmd("ACCT",acct,-1,-1,ftp_vbm);
- }
- makestr(&ftp_logname,user);
- loggedin = 1;
-#ifdef LOCUS
- /* Unprefixed file management commands go to server */
- if (autolocus && !ftp_cmdlin) {
- setlocus(0,1);
- }
-#endif /* LOCUS */
- ftp_init();
-
- if (anonymous && !quiet) {
- printf(" Logged in as anonymous (%s)\n",pass);
- memset(pass, 0, strlen(pass));
- }
- if (ftp_rdir) {
- if (doftpcwd(ftp_rdir,-1) < 1)
- doexit(BAD_EXIT,-1);
- }
-
-#ifdef FTP_PROXY
- if (proxy)
- return(1);
-#endif /* FTP_PROXY */
- return(1);
-}
-
-static int
-ftp_reset() {
- int rc;
-#ifdef BSDSELECT
- int nfnd = 1;
- fd_set mask;
- FD_ZERO(&mask);
- while (nfnd > 0) {
- FD_SET(csocket, &mask);
- if ((nfnd = empty(&mask,0)) < 0) {
- perror("reset");
- ftpcode = -1;
- lostpeer();
- return(0);
- } else if (nfnd) {
- getreply(0,-1,-1,ftp_vbm,0);
- }
- }
-#else /* BSDSELECT */
-#ifdef IBMSELECT
- int nfnd = 1;
- while (nfnd > 0) {
- if ((nfnd = empty(&csocket,1,0)) < 0) {
- perror("reset");
- ftpcode = -1;
- lostpeer();
- return(0);
- } else if (nfnd) {
- getreply(0,-1,-1,ftp_vbm,0);
- }
- }
-#endif /* IBMSELECT */
-#endif /* BSDSELECT */
- rc = (ftpcmd("REIN",NULL,0,0,ftp_vbm) == REPLY_COMPLETE);
- if (rc > 0)
- loggedin = 0;
- return(rc);
-}
-
-static int
-ftp_rename(from, to) char * from, * to; {
- int lcs = -1, rcs = -1;
-#ifndef NOCSETS
- if (ftp_xla) {
- lcs = ftp_csl;
- if (lcs < 0) lcs = fcharset;
- rcs = ftp_csx;
- if (rcs < 0) rcs = ftp_csr;
- }
-#endif /* NOCSETS */
- if (ftpcmd("RNFR",from,lcs,rcs,ftp_vbm) == REPLY_CONTINUE) {
- return(ftpcmd("RNTO",to,lcs,rcs,ftp_vbm) == REPLY_COMPLETE);
- }
- return(0); /* Failure */
-}
-
-static int
-ftp_umask(mask) char * mask; {
- int rc;
- rc = (ftpcmd("SITE UMASK",mask,-1,-1,1) == REPLY_COMPLETE);
- return(rc);
-}
-
-static int
-ftp_user(user,pass,acct) char * user, * pass, * acct; {
- int n = 0, aflag = 0;
- char pwd[PWDSIZ];
-
- if (!auth_type && ftp_aut) {
-#ifdef FTP_SRP
- if (ck_srp_is_installed()) {
- if (srp_ftp_auth( NULL, user, pass)) {
- makestr(&pass,srp_pass);
- }
- }
-#endif /* FTP_SRP */
- }
- n = ftpcmd("USER",user,-1,-1,ftp_vbm);
- if (n == REPLY_COMPLETE)
- n = ftpcmd("PASS dummy",NULL,0,0,1);
- else if (n == REPLY_CONTINUE) {
-#ifdef CK_ENCRYPTION
- int oldftp_cpl;
-#endif /* CK_ENCRYPTION */
- if (pass == NULL || !pass[0]) {
- int ok;
- pwd[0] = '\0';
- setint();
- ok = uq_txt(NULL," Password: ",2,NULL,pwd,PWDSIZ,NULL,
- DEFAULT_UQ_TIMEOUT);
- if (ok)
- pass = brstrip(pwd);
- }
-
-#ifdef CK_ENCRYPTION
- if ((oldftp_cpl = ftp_cpl) == PROT_S)
- ftp_cpl = PROT_P;
-#endif /* CK_ENCRYPTION */
- n = ftpcmd("PASS",pass,-1,-1,1);
- memset(pass, 0, strlen(pass));
-#ifdef CK_ENCRYPTION
- /* level may have changed */
- if (ftp_cpl == PROT_P)
- ftp_cpl = oldftp_cpl;
-#endif /* CK_ENCRYPTION */
- }
- if (n == REPLY_CONTINUE) {
- if (acct == NULL || !acct[0]) {
- int ok;
- pwd[0] = '\0';
- setint();
- ok = uq_txt(NULL," Account: ",2,NULL,pwd,PWDSIZ,NULL,
- DEFAULT_UQ_TIMEOUT);
- if (ok)
- acct = pwd;
- }
- n = ftpcmd("ACCT",acct,-1,-1,ftp_vbm);
- aflag++;
- }
- if (n != REPLY_COMPLETE) {
- printf("Login failed.\n");
- return(0);
- }
- if (!aflag && acct != NULL && acct[0]) {
- n = ftpcmd("ACCT",acct,-1,-1,ftp_vbm);
- }
- if (n == REPLY_COMPLETE) {
- makestr(&ftp_logname,user);
- loggedin = 1;
- ftp_init();
- return(1);
- }
- return(0);
-}
-
-char *
-ftp_authtype() {
- if (!connected)
- return("NULL");
- return(auth_type ? auth_type : "NULL");
-}
-
-char *
-ftp_cpl_mode() {
- switch (ftp_cpl) {
- case FPL_CLR:
- return("clear");
- case FPL_SAF:
- return("safe");
- case FPL_PRV:
- return("private");
- case FPL_CON:
- return("confidential");
- default:
- return("(error)");
- }
-}
-
-char *
-ftp_dpl_mode() {
- switch (ftp_dpl) {
- case FPL_CLR:
- return("clear");
- case FPL_SAF:
- return("safe");
- case FPL_PRV:
- return("private");
- case FPL_CON:
- return("confidential");
- default:
- return("(error)");
- }
-}
-
-
-/* remote_files() */
-/*
- Returns next remote filename on success;
- NULL on error or no more files with global rfrc set to:
- -1: Bad argument
- -2: Server error response to NLST, e.g. file not found
- -3: No more files
- -9: Internal error
-*/
-#define FTPNAMBUFLEN CKMAXPATH+1024
-
-/* Check: ckmaxfiles CKMAXOPEN */
-
-#define MLSDEPTH 128 /* Stack of open temp files */
-static int mlsdepth = 0; /* Temp file stack depth */
-static FILE * tmpfilptr[MLSDEPTH+1] = { NULL, NULL }; /* Temp file pointers */
-static char * tmpfilnam[MLSDEPTH+1] = { NULL, NULL }; /* Temp file names */
-
-static VOID
-mlsreset() { /* Reset MGET temp-file stack */
- int i;
- for (i = 0; i <= mlsdepth; i++) {
- if (tmpfilptr[i]) {
- fclose(tmpfilptr[i]);
- tmpfilptr[i] = NULL;
- if (tmpfilnam[i]) {
-#ifdef OS2
- unlink(tmpfilnam[i]);
-#endif /* OS2 */
- free(tmpfilnam[i]);
- }
- }
- }
- mlsdepth = 0;
-}
-
-static CHAR *
-#ifdef CK_ANSIC
-remote_files(int new_query, CHAR * arg, CHAR * pattern, int proxy_switch)
-#else /* CK_ANSIC */
-remote_files(new_query, arg, pattern, proxy_switch)
- int new_query;
- CHAR * arg; /* That we send to the server */
- CHAR * pattern; /* That we use locally */
- int proxy_switch;
-#endif /* CK_ANSIC */
-/* remote_files */ {
- static CHAR buf[FTPNAMBUFLEN];
- CHAR *cp, *whicharg;
- char * cdto = NULL;
- char * p;
- int i, x, forced = 0;
- int lcs = 0, rcs = 0, xlate = 0;
-
- debug(F101,"ftp remote_files new_query","",new_query);
- debug(F110,"ftp remote_files arg",arg,0);
- debug(F110,"ftp remote_files pattern",pattern,0);
-
- rfrc = -1;
- if (pattern) /* Treat empty pattern same as NULL */
- if (!*pattern)
- pattern = NULL;
- if (arg) /* Ditto for arg */
- if (!*arg)
- arg = NULL;
-
- again:
-
- if (new_query) {
- if (tmpfilptr[mlsdepth]) {
- fclose(tmpfilptr[mlsdepth]);
- tmpfilptr[mlsdepth] = NULL;
-#ifdef OS2
- if (!ftp_deb && !deblog)
- unlink(tmpfilnam[mlsdepth]);
-#endif /* OS2 */
- }
- }
- if (tmpfilptr[mlsdepth] == NULL) {
- extern char * tempdir;
- char * p;
- debug(F110,"ftp remote_files tempdir",tempdir,0);
- if (tempdir) {
- p = tempdir;
- } else {
-#ifdef OS2
-#ifdef NT
- p = getenv("K95TMP");
-#else
- p = getenv("K2TMP");
-#endif /* NT */
- if (!p)
-#endif /* OS2 */
- p = getenv("CK_TMP");
- if (!p)
- p = getenv("TMPDIR");
- if (!p) p = getenv("TEMP");
- if (!p) p = getenv("TMP");
-#ifdef OS2ORUNIX
- if (p) {
- int len = strlen(p);
- if (p[len-1] != '/'
-#ifdef OS2
- && p[len-1] != '\\'
-#endif /* OS2 */
- ) {
- static char foo[CKMAXPATH];
- ckstrncpy(foo,p,CKMAXPATH);
- ckstrncat(foo,"/",CKMAXPATH);
- p = foo;
- }
- } else
-#else /* OS2ORUNIX */
- if (!p)
-#endif /* OS2ORUNIX */
-#ifdef UNIX /* Systems that have a standard */
- p = "/tmp/"; /* temporary directory... */
-#else
-#ifdef datageneral
- p = ":TMP:";
-#else
- p = "";
-#endif /* datageneral */
-#endif /* UNIX */
- }
- debug(F110,"ftp remote_files p",p,0);
-
- /* Get temp file */
-
- if ((tmpfilnam[mlsdepth] = (char *)malloc(CKMAXPATH+1))) {
- ckmakmsg((char *)tmpfilnam[mlsdepth],
- CKMAXPATH+1,p,"ckXXXXXX",NULL,NULL);
- } else {
- printf("?Malloc failure: remote_files()\n");
- return(NULL);
- }
-
-#ifdef NT
- {
- char * tmpfil = mktemp((char *)tmpfilnam[mlsdepth]);
- if ( tmpfil )
- ckstrncpy(tmpfilnam[mlsdepth],tmpfil,CKMAXPATH+1);
- }
-#else /* NT */
-#ifdef MKTEMP
-#ifdef MKSTEMP
- x = mkstemp((char *)tmpfilnam[mlsdepth]);
- if (x > -1) close(x); /* We just want the name. */
-#else
- mktemp((char *)tmpfilnam[mlsdepth]);
-#endif /* MKSTEMP */
- /* if no mktmpnam() the name will just be "ckXXXXXX"... */
-#endif /* MKTEMP */
-#endif /* NT */
-
- debug(F111,"ftp remote_files tmpfilnam[mlsdepth]",
- tmpfilnam[mlsdepth],mlsdepth);
-
-#ifdef FTP_PROXY
- if (proxy_switch) {
- pswitch(!proxy);
- }
-#endif /* FTP_PROXY */
-
- debug(F101,"ftp remote_files ftp_xla","",ftp_xla);
- debug(F101,"ftp remote_files ftp_csl","",ftp_csl);
- debug(F101,"ftp remote_files ftp_csr","",ftp_csr);
-
-#ifndef NOCSETS
- xlate = ftp_xla; /* SET FTP CHARACTER-SET-TRANSLATION */
- if (xlate) { /* ON? */
- lcs = ftp_csl; /* Local charset */
- if (lcs < 0) lcs = fcharset;
- if (lcs < 0) xlate = 0;
- }
- if (xlate) { /* Still ON? */
- rcs = ftp_csx; /* Remote (Server) charset */
- if (rcs < 0) rcs = ftp_csr;
- if (rcs < 0) xlate = 0;
- }
-#endif /* NOCSETS */
-
- forced = mgetforced; /* MGET method forced? */
- if (!forced || !mgetmethod) /* Not forced... */
- mgetmethod = (sfttab[0] && sfttab[SFT_MLST]) ? /* so pick one */
- SND_MLS :
- SND_NLS;
-/*
- User's Command: Result:
- mget /nlst NLST (NULL)
- mget /nlst foo NLST foo
- mget /nlst *.txt NLST *.txt
- mget /nlst /match:*.txt NLST (NULL)
- mget /nlst /match:*.txt foo NLST foo
- mget /mlsd MLSD (NULL)
- mget /mlsd foo MLSD foo
- mget /mlsd *.txt MLSD (NULL)
- mget /mlsd /match:*.txt MLSD (NULL)
- mget /mlsd /match:*.txt foo MLSD foo
-*/
- x = -1;
- while (x < 0) {
- if (pattern) { /* Don't simplify this! */
- whicharg = arg;
- } else if (mgetmethod == SND_MLS) {
- if (arg)
- whicharg = iswild((char *)arg) ? NULL : arg;
- else
- whicharg = NULL;
- } else {
- whicharg = arg;
- }
- debug(F110,"ftp remote_files mgetmethod",
- mgetmethod == SND_MLS ? "MLSD" : "NLST", 0);
- debug(F110,"ftp remote_files whicharg",whicharg,0);
-
- x = recvrequest((mgetmethod == SND_MLS) ? "MLSD" : "NLST",
- (char *)tmpfilnam[mlsdepth],
- (char *)whicharg,
- "wb",
- 0,
- 0,
- NULL,
- xlate,
- lcs,
- rcs
- );
- if (x < 0) { /* Chosen method wasn't accepted */
- if (forced) {
- if (ftpcode > 500 && ftpcode < 505 && !quiet)
- printf("?%s: Not supported by server\n",
- mgetmethod == SND_MLS ? "MLSD" : "NLST"
- );
- rfrc = -2; /* Fail */
- return(NULL);
- }
- /* Not forced - if MLSD failed, try NLST */
- if (mgetmethod == SND_MLS) { /* Server lied about MLST */
- sfttab[SFT_MLST] = 0; /* So disable it */
- mlstok = 0; /* and */
- mgetmethod = SND_NLS; /* try NLST */
- continue;
- }
- rfrc = -2;
- return(NULL);
- }
- }
-#ifdef FTP_PROXY
- if (proxy_switch) {
- pswitch(!proxy);
- }
-#endif /* FTP_PROXY */
- tmpfilptr[mlsdepth] = fopen((char *)tmpfilnam[mlsdepth], "r");
-#ifndef OS2
- if (tmpfilptr[mlsdepth]) {
- if (!ftp_deb && !deblog)
- unlink(tmpfilnam[mlsdepth]);
- }
-#endif /* OS2 */
- notemp:
- if (!tmpfilptr[mlsdepth]) {
- debug(F110,"ftp remote_files open fail",tmpfilnam[mlsdepth],0);
- if ((!dpyactive || ftp_deb))
- printf("?Can't find list of remote files, oops\n");
- rfrc = -9;
- return(NULL);
- }
- if (ftp_deb)
- printf("LISTFILE: %s\n",tmpfilnam[mlsdepth]);
- }
- buf[0] = NUL;
- buf[FTPNAMBUFLEN-1] = NUL;
- buf[FTPNAMBUFLEN-2] = NUL;
-
- /* We have to redo all this because the first time was only for */
- /* for getting the file list, now it's for getting each file */
-
- if (arg && mgetmethod == SND_MLS) { /* MLSD */
- if (!pattern && iswild((char *)arg)) {
- pattern = arg; /* Wild arg is really a pattern */
- if (pattern)
- if (!*pattern)
- pattern = NULL;
- arg = NULL; /* and not an arg */
- }
- if (new_query) { /* Initial query? */
- cdto = (char *)arg; /* (nonwild) arg given? */
- if (cdto)
- if (!*cdto)
- cdto = NULL;
- if (cdto) /* If so, then CD to it */
- doftpcwd(cdto,0);
- }
- }
- new_query = 0;
-
- if (fgets((char *)buf, FTPNAMBUFLEN, tmpfilptr[mlsdepth]) == NULL) {
- fclose(tmpfilptr[mlsdepth]);
- tmpfilptr[mlsdepth] = NULL;
-
-#ifdef OS2
- if (!ftp_deb && !deblog)
- unlink(tmpfilnam[mlsdepth]);
-#endif /* OS2 */
- if (ftp_deb && !deblog) {
- printf("(Temporary file %s NOT deleted)\n",
- (char *)tmpfilnam[mlsdepth]);
- }
- if (mlsdepth <= 0) { /* EOF at depth 0 */
- rfrc = -3; /* means we're done */
- return(NULL);
- }
- printf("POPPING(%d)...\n",mlsdepth-1);
- if (tmpfilnam[mlsdepth]) free(tmpfilnam[mlsdepth]);
- mlsdepth--;
- doftpcdup();
- zchdir(".."); /* <-- Not portable */
- goto again;
- }
- if (buf[FTPNAMBUFLEN-1]) {
- printf("?BUFFER OVERFLOW -- FTP NLST or MLSD string longer than %d\n",
- FTPNAMBUFLEN
- );
- debug(F101,"remote_files buffer overrun","",FTPNAMBUFLEN);
- return(NULL);
- }
- /* debug(F110,"ftp remote_files buf 1",buf,0); */
- if ((cp = (CHAR *)ckstrchr((char *)buf,'\n')) != NULL)
- *cp = '\0';
- if ((cp = (CHAR *)ckstrchr((char *)buf,'\r')) != NULL)
- *cp = '\0';
- debug(F110,"ftp remote_files buf",buf,0);
- rfrc = 0;
-
- if (ftp_deb)
- printf("[%s]\n",(char *)buf);
-
- havesize = -1L; /* Initialize file facts... */
- havetype = -0;
- makestr(&havemdtm,NULL);
- p = (char *)buf;
-
- if (mgetmethod == SND_NLS) { /* NLST... */
- if (pattern) {
- if (!ckmatch((char *)pattern,p,(servertype == SYS_UNIX),1))
- goto again;
- }
- } else { /* MLSD... */
- p = parsefacts((char *)buf);
- switch (havetype) {
- case FTYP_FILE: /* File: Get it if it matches */
- if (pattern) {
- if (!ckmatch((char *)pattern,p,(servertype == SYS_UNIX),1))
- goto again;
- }
- break;
- case FTYP_CDIR: /* Current directory */
- case FTYP_PDIR: /* Parent directory */
- goto again; /* Skip */
- case FTYP_DIR: /* (Sub)Directory */
- if (!recursive) /* If not /RECURSIVE */
- goto again; /* Skip */
- if (mlsdepth < MLSDEPTH) {
- char * p2 = NULL;
- mlsdepth++;
- printf("RECURSING [%s](%d)...\n",p,mlsdepth);
- if (doftpcwd(p,0) > 0) {
- int x;
- if (!ckstrchr(p,'/')) {
- /* zmkdir() needs dirsep */
- if ((p2 = (char *)malloc((int)strlen(p) + 2))) {
- strcpy(p2,p); /* SAFE */
- strcat(p2,"/"); /* SAFE */
- p = p2;
- }
- }
-#ifdef NOMKDIR
- x = -1;
-#else
- x = zmkdir(p);
-#endif /* NOMKDIR */
- if (x > -1) {
- zchdir(p);
- p = (char *)remote_files(1,arg,pattern,0);
- if (p2) free(p2);
- } else {
- printf("?mkdir failed: [%s] Depth=%d\n",
- p,
- mlsdepth
- );
- mlsreset();
- if (p2) free(p2);
- return(NULL);
- }
- } else {
- printf("?CWD failed: [%s] Depth=%d\n",p,mlsdepth);
- mlsreset();
- return(NULL);
- }
- } else {
- printf("MAX DIRECTORY STACK DEPTH EXCEEDED: %d\n",
- mlsdepth
- );
- mlsreset();
- return(NULL);
- }
- }
- }
-
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"remote_files havesize","",havesize);
- debug(F101,"remote_files havetype","",havetype);
- debug(F110,"remote_files havemdtm",havemdtm,0);
- debug(F110,"remote_files name",p,0);
- }
-#endif /* DEBUG */
- return((CHAR *)p);
-}
-
-/* N O T P O R T A B L E !!! */
-
-#if (SIZEOF_SHORT == 4)
-typedef unsigned short ftp_uint32;
-typedef short ftp_int32;
-#else
-#if (SIZEOF_INT == 4)
-typedef unsigned int ftp_uint32;
-typedef int ftp_int32;
-#else
-#if (SIZEOF_LONG == 4)
-typedef ULONG ftp_uint32;
-typedef long ftp_int32;
-#endif
-#endif
-#endif
-
-/* Perhaps use these in general, certainly use them for GSSAPI */
-
-#ifndef looping_write
-#define ftp_int32 int
-#define ftp_uint32 unsigned int
-static int
-looping_write(fd, buf, len)
- int fd;
- register CONST char *buf;
- int len;
-{
- int cc;
- register int wrlen = len;
- do {
- cc = send(fd, (SENDARG2TYPE)buf, wrlen, 0);
- if (cc < 0) {
- if (errno == EINTR)
- continue;
- return(cc);
- } else {
- buf += cc;
- wrlen -= cc;
- }
- } while (wrlen > 0);
- return(len);
-}
-#endif
-#ifndef looping_read
-static int
-looping_read(fd, buf, len)
- int fd;
- register char *buf;
- register int len;
-{
- int cc, len2 = 0;
-
- do {
- cc = recv(fd, (char *)buf, len,0);
- if (cc < 0) {
- if (errno == EINTR)
- continue;
- return(cc); /* errno is already set */
- } else if (cc == 0) {
- return(len2);
- } else {
- buf += cc;
- len2 += cc;
- len -= cc;
- }
- } while (len > 0);
- return(len2);
-}
-#endif /* looping_read */
-
-#define ERR -2
-
-#ifdef COMMENT
-static
-secure_putbyte(fd, c) int fd; CHAR c; {
- int ret;
-
- ucbuf[nout++] = c;
- if (nout == (maxbuf ? maxbuf : actualbuf) - FUDGE_FACTOR) {
- nout = 0;
- if (!ftpissecure())
- ret = send(fd, (SENDARG2TYPE)ucbuf,
- (maxbuf ? maxbuf : actualbuf) - FUDGE_FACTOR, 0);
- else
- ret = secure_putbuf(fd,
- ucbuf,
- (maxbuf ? maxbuf : actualbuf) - FUDGE_FACTOR
- );
- return(ret?ret:c);
- }
- return(c);
-}
-#endif /* COMMENT */
-
-/* returns:
- * 0 on success
- * -1 on error (errno set)
- * -2 on security error
- */
-static int
-secure_flush(fd) int fd; {
- int rc = 0;
- int len = 0;
-
- if (nout > 0) {
- len = nout;
- if (!ftpissecure()) {
- rc = send(fd, (SENDARG2TYPE)ucbuf, nout, 0);
- nout = 0;
- goto xflush;
- } else {
- rc = secure_putbuf(fd, ucbuf, nout);
- if (rc)
- goto xflush;
- }
- }
- rc = (!ftpissecure()) ? 0 : secure_putbuf(fd, (CHAR *)"", nout = 0);
-
- xflush:
- if (rc > -1 && len > 0 && fdispla != XYFD_B) {
- spackets++;
- spktl = len;
- ftscreen(SCR_PT,'D',spackets,NULL);
- }
- return(rc);
-}
-
-#ifdef COMMENT /* (not used) */
-/* returns:
- * c>=0 on success
- * -1 on error
- * -2 on security error
- */
-static int
-#ifdef CK_ANSIC
-secure_putc(char c, int fd)
-#else
-secure_putc(c, fd) char c; int fd;
-#endif /* CK_ANSIC */
-/* secure_putc */ {
- return(secure_putbyte(fd, (CHAR) c));
-}
-#endif /* COMMENT */
-
-/* returns:
- * nbyte on success
- * -1 on error (errno set)
- * -2 on security error
- */
-static int
-#ifdef CK_ANSIC
-secure_write(int fd, CHAR * buf, unsigned int nbyte)
-#else
-secure_write(fd, buf, nbyte)
- int fd;
- CHAR * buf;
- unsigned int nbyte;
-#endif /* CK_ANSIC */
-{
- int ret;
-
- if (!ftpissecure()) {
- if (nout > 0) {
- if ((ret = send(fd, (SENDARG2TYPE)ucbuf, nout, 0)) < 0)
- return(ret);
- nout = 0;
- }
- return(send(fd,(SENDARG2TYPE)buf,nbyte,0));
- } else {
- int ucbuflen = (maxbuf ? maxbuf : actualbuf) - FUDGE_FACTOR;
- int bsent = 0;
-
- while (bsent < nbyte) {
- int b2cp = ((nbyte - bsent) > (ucbuflen - nout) ?
- (ucbuflen - nout) : (nbyte - bsent));
-#ifdef DEBUG
- if (deblog) {
- debug(F101,"secure_write ucbuflen","",ucbuflen);
- debug(F101,"secure_write ucbufsiz","",ucbufsiz);
- debug(F101,"secure_write bsent","",bsent);
- debug(F101,"secure_write b2cp","",b2cp);
- }
-#endif /* DEBUG */
- memcpy(&ucbuf[nout],&buf[bsent],b2cp);
- nout += b2cp;
- bsent += b2cp;
-
- if (nout == ucbuflen) {
- nout = 0;
- ret = secure_putbuf(fd, ucbuf, ucbuflen);
- if (ret < 0)
- return(ret);
- }
- }
- return(bsent);
- }
-}
-
-/* returns:
- * 0 on success
- * -1 on error (errno set)
- * -2 on security error
- */
-static int
-#ifdef CK_ANSIC
-secure_putbuf(int fd, CHAR * buf, unsigned int nbyte)
-#else
-secure_putbuf(fd, buf, nbyte) int fd; CHAR * buf; unsigned int nbyte;
-#endif /* CK_ANSIC */
-{
- static char *outbuf = NULL; /* output ciphertext */
-#ifdef FTP_SECURITY
- static unsigned int bufsize = 0; /* size of outbuf */
-#endif /* FTP_SECURITY */
- ftp_int32 length = 0;
- ftp_uint32 net_len = 0;
-
- /* Other auth types go here ... */
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- int count, error;
-
- /* there is no need to send an empty buffer when using SSL/TLS */
- if ( nbyte == 0 )
- return(0);
-
- count = SSL_write(ssl_ftp_data_con, buf, nbyte);
- error = SSL_get_error(ssl_ftp_data_con,count);
- switch (error) {
- case SSL_ERROR_NONE:
- return(0);
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_SYSCALL:
-#ifdef NT
- {
- int gle = GetLastError();
- if (gle == 0)
- return(0);
- debug(F111,"secure_putbuf","SSL_ERROR_SYSCALL",gle);
- }
-#endif /* NT */
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- SSL_shutdown(ssl_ftp_data_con);
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_active_flag = 0;
- ssl_ftp_data_con = NULL;
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = data;
- return(-1);
- }
- return(-1);
- }
-#endif /* CK_SSL */
-
-#ifdef FTP_SRP
- if (ck_srp_is_installed() && (strcmp(auth_type, "SRP") == 0)) {
- if (bufsize < nbyte + FUDGE_FACTOR) {
- if (outbuf?
- (outbuf = realloc(outbuf, (unsigned) (nbyte + FUDGE_FACTOR))):
- (outbuf = malloc((unsigned) (nbyte + FUDGE_FACTOR)))) {
- bufsize = nbyte + FUDGE_FACTOR;
- } else {
- bufsize = 0;
- secure_error("%s (in malloc of PROT buffer)", ck_errstr());
- return(ERR);
- }
- }
- if ((length =
- srp_encode(ftp_dpl == FPL_PRV,
- (CHAR *) buf,
- (CHAR *) outbuf,
- nbyte
- )
- ) < 0) {
- secure_error ("srp_encode failed");
- return ERR;
- }
- }
-#endif /* FTP_SRP */
-#ifdef FTP_KRB4
- if (ck_krb4_is_installed() && (strcmp(auth_type, "KERBEROS_V4") == 0)) {
- struct sockaddr_in myaddr, hisaddr;
- GSOCKNAME_T len;
- len = sizeof(myaddr);
- if (getsockname(fd, (struct sockaddr*)&myaddr, &len) < 0) {
- secure_error("secure_putbuf: getsockname failed");
- return(ERR);
- }
- len = sizeof(hisaddr);
- if (getpeername(fd, (struct sockaddr*)&hisaddr, &len) < 0) {
- secure_error("secure_putbuf: getpeername failed");
- return(ERR);
- }
- if (bufsize < nbyte + FUDGE_FACTOR) {
- if (outbuf ?
- (outbuf = realloc(outbuf, (unsigned) (nbyte + FUDGE_FACTOR))):
- (outbuf = malloc((unsigned) (nbyte + FUDGE_FACTOR)))) {
- bufsize = nbyte + FUDGE_FACTOR;
- } else {
- bufsize = 0;
- secure_error("%s (in malloc of PROT buffer)", ck_errstr());
- return(ERR);
- }
- }
- if (ftp_dpl == FPL_PRV) {
- length = krb_mk_priv(buf, (CHAR *) outbuf, nbyte,
- ftp_sched,
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &myaddr,
- &hisaddr
- );
- } else {
- length = krb_mk_safe(buf, (CHAR *) outbuf, nbyte,
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &myaddr,
- &hisaddr
- );
- }
- if (length == -1) {
- secure_error("krb_mk_%s failed for KERBEROS_V4",
- ftp_dpl == FPL_PRV ? "priv" : "safe");
- return(ERR);
- }
- }
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- if (ck_gssapi_is_installed() && (strcmp(auth_type, "GSSAPI") == 0)) {
- gss_buffer_desc in_buf, out_buf;
- OM_uint32 maj_stat, min_stat;
- int conf_state;
-
- in_buf.value = buf;
- in_buf.length = nbyte;
- maj_stat = gss_seal(&min_stat, gcontext,
- (ftp_dpl == FPL_PRV), /* confidential */
- GSS_C_QOP_DEFAULT,
- &in_buf,
- &conf_state,
- &out_buf
- );
- if (maj_stat != GSS_S_COMPLETE) {
- /* generally need to deal */
- /* ie. should loop, but for now just fail */
- user_gss_error(maj_stat, min_stat,
- ftp_dpl == FPL_PRV?
- "GSSAPI seal failed":
- "GSSAPI sign failed");
- return(ERR);
- }
- if (bufsize < out_buf.length) {
- if (outbuf ?
- (outbuf = realloc(outbuf, (unsigned) out_buf.length)):
- (outbuf = malloc((unsigned) out_buf.length))) {
- bufsize = out_buf.length;
- } else {
- bufsize = 0;
- secure_error("%s (in malloc of PROT buffer)",
- ck_errstr());
- return(ERR);
- }
- }
- memcpy(outbuf, out_buf.value, length=out_buf.length);
- gss_release_buffer(&min_stat, &out_buf);
- }
-#endif /* FTP_GSSAPI */
- net_len = htonl((ULONG) length);
- if (looping_write(fd, (char *)&net_len, 4) == -1)
- return(-1);
- if (looping_write(fd, outbuf, length) != length)
- return(-1);
- return(0);
-}
-
-/* fc = 0 means to get a byte; nonzero means to initialize buffer pointers */
-
-static int
-secure_getbyte(fd,fc) int fd,fc; {
- /* number of chars in ucbuf, pointer into ucbuf */
- static unsigned int nin = 0, bufp = 0;
- int kerror;
- ftp_uint32 length;
-
- if (fc) {
- nin = bufp = 0;
- ucbuf[0] = NUL;
- return(0);
- }
- if (nin == 0) {
- if (iscanceled())
- return(-9);
-#ifdef CK_SSL
- if (ssl_ftp_data_active_flag) {
- int count, error;
- count = SSL_read(ssl_ftp_data_con, ucbuf, ucbufsiz);
- error = SSL_get_error(ssl_ftp_data_con,count);
- switch (error) {
- case SSL_ERROR_NONE:
- nin = bufp = count;
- rpackets++;
- pktnum++;
- if (fdispla != XYFD_B) {
- rpktl = count;
- ftscreen(SCR_PT,'D',rpackets,NULL);
- }
- break;
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_SYSCALL:
-#ifdef NT
- {
- int gle = GetLastError();
- }
-#endif /* NT */
- case SSL_ERROR_WANT_X509_LOOKUP:
- case SSL_ERROR_SSL:
- case SSL_ERROR_ZERO_RETURN:
- default:
- nin = bufp = count = 0;
- SSL_shutdown(ssl_ftp_data_con);
- SSL_free(ssl_ftp_data_con);
- ssl_ftp_data_active_flag = 0;
- ssl_ftp_data_con = NULL;
-#ifdef TCPIPLIB
- socket_close(data);
-#else /* TCPIPLIB */
-#ifdef USE_SHUTDOWN
- shutdown(data, 1+1);
-#endif /* USE_SHUTDOWN */
- close(data);
-#endif /* TCPIPLIB */
- data = -1;
- globaldin = data;
- break;
- }
- } else
-#endif /* CK_SSL */
- {
- kerror = looping_read(fd, (char *)&length, sizeof(length));
- if (kerror != sizeof(length)) {
- secure_error("Couldn't read PROT buffer length: %d/%s",
- kerror,
- kerror == -1 ? ck_errstr()
- : "premature EOF"
- );
- return(ERR);
- }
- debug(F101,"secure_getbyte length","",length);
- debug(F101,"secure_getbyte ntohl(length)","",ntohl(length));
-
- length = (ULONG) ntohl(length);
- if (length > maxbuf) {
- secure_error("Length (%d) of PROT buffer > PBSZ=%u",
- length,
- maxbuf
- );
- return(ERR);
- }
- if ((kerror = looping_read(fd, ucbuf, length)) != length) {
- secure_error("Couldn't read %u byte PROT buffer: %s",
- length,
- kerror == -1 ? ck_errstr() : "premature EOF"
- );
- return(ERR);
- }
-
- /* Other auth types go here ... */
-#ifdef FTP_SRP
- if (strcmp(auth_type, "SRP") == 0) {
- if ((nin = bufp = srp_decode (ftp_dpl == FPL_PRV,
- (CHAR *) ucbuf,
- ucbuf,
- length
- )
- ) == -1) {
- secure_error ("srp_encode failed" );
- return ERR;
- }
- }
-#endif /* FTP_SRP */
-#ifdef FTP_KRB4
- if (strcmp(auth_type, "KERBEROS_V4") == 0) {
- struct sockaddr_in myaddr, hisaddr;
- GSOCKNAME_T len;
- len = sizeof(myaddr);
- if (getsockname(fd, (struct sockaddr*)&myaddr, &len) < 0) {
- secure_error("secure_putbuf: getsockname failed");
- return(ERR);
- }
- len = sizeof(hisaddr);
- if (getpeername(fd, (struct sockaddr*)&hisaddr, &len) < 0) {
- secure_error("secure_putbuf: getpeername failed");
- return(ERR);
- }
- if (ftp_dpl) {
- kerror = krb_rd_priv(ucbuf, length, ftp_sched,
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &hisaddr, &myaddr, &ftp_msg_data);
- } else {
- kerror = krb_rd_safe(ucbuf, length,
-#ifdef KRB524
- ftp_cred.session,
-#else /* KRB524 */
- &ftp_cred.session,
-#endif /* KRB524 */
- &hisaddr, &myaddr, &ftp_msg_data);
- }
- if (kerror) {
- secure_error("krb_rd_%s failed for KERBEROS_V4 (%s)",
- ftp_dpl == FPL_PRV ? "priv" : "safe",
- krb_get_err_text(kerror));
- return(ERR);
- }
- memcpy(ucbuf,ftp_msg_data.app_data,ftp_msg_data.app_length);
- nin = bufp = ftp_msg_data.app_length;
- }
-#endif /* FTP_KRB4 */
-#ifdef FTP_GSSAPI
- if (strcmp(auth_type, "GSSAPI") == 0) {
- gss_buffer_desc xmit_buf, msg_buf;
- OM_uint32 maj_stat, min_stat;
- int conf_state;
-
- xmit_buf.value = ucbuf;
- xmit_buf.length = length;
- conf_state = (ftp_dpl == FPL_PRV);
- /* decrypt/verify the message */
- maj_stat = gss_unseal(&min_stat, gcontext, &xmit_buf,
- &msg_buf, &conf_state, NULL);
- if (maj_stat != GSS_S_COMPLETE) {
- user_gss_error(maj_stat, min_stat,
- (ftp_dpl == FPL_PRV)?
- "failed unsealing ENC message":
- "failed unsealing MIC message");
- return ERR;
- }
- memcpy(ucbuf, msg_buf.value, nin = bufp = msg_buf.length);
- gss_release_buffer(&min_stat, &msg_buf);
- }
-#endif /* FTP_GSSAPI */
- /* Other auth types go here ... */
-
- /* Update file transfer display */
- rpackets++;
- pktnum++;
- if (fdispla != XYFD_B) {
- rpktl = nin;
- ftscreen(SCR_PT,'D',rpackets,NULL);
- }
- }
- }
- if (nin == 0)
- return(EOF);
- else
- return(ucbuf[bufp - nin--]);
-}
-
-/* secure_getc(fd,fc)
- * Call with:
- * fd = file descriptor for connection.
- * fc = 0 to get a character, fc != 0 to initialize buffer pointers.
- * Returns:
- * c>=0 on success (character value)
- * -1 on EOF
- * -2 on security error
- */
-static int
-secure_getc(fd,fc) int fd,fc; { /* file descriptor, function code */
- if (!ftpissecure()) {
- static unsigned int nin = 0, bufp = 0;
- if (fc) {
- nin = bufp = 0;
- ucbuf[0] = NUL;
- return(0);
- }
- if (nin == 0) {
- if (iscanceled())
- return(-9);
- nin = bufp = recv(fd,(char *)ucbuf,actualbuf,0);
- if (nin <= 0) {
- debug(F111,"secure_getc recv errno",ckitoa(nin),errno);
- debug(F101,"secure_getc returns EOF","",EOF);
- nin = bufp = 0;
- return(EOF);
- }
- debug(F101,"ftp secure_getc recv","",nin);
- hexdump("ftp secure_getc recv",ucbuf,16);
- rpackets++;
- pktnum++;
- if (fdispla != XYFD_B) {
- rpktl = nin;
- ftscreen(SCR_PT,'D',rpackets,NULL);
- }
- }
- return(ucbuf[bufp - nin--]);
- } else
- return(secure_getbyte(fd,fc));
-}
-
-/* returns:
- * n>0 on success (n == # of bytes read)
- * 0 on EOF
- * -1 on error (errno set), only for FPL_CLR
- * -2 on security error
- */
-static int
-secure_read(fd, buf, nbyte) int fd; char *buf; int nbyte; {
- static int c = 0;
- int i;
-
- debug(F101,"secure_read bytes requested","",nbyte);
- if (c == EOF)
- return(c = 0);
- for (i = 0; nbyte > 0; nbyte--) {
- c = secure_getc(fd,0);
- switch (c) {
- case -9: /* Canceled from keyboard */
- debug(F101,"ftp secure_read interrupted","",c);
- return(0);
- case ERR:
- debug(F101,"ftp secure_read error","",c);
- return(c);
- case EOF:
- debug(F101,"ftp secure_read EOF","",c);
- if (!i)
- c = 0;
- return(i);
- default:
- buf[i++] = c;
- }
- }
- return(i);
-}
-
-#ifdef USE_RUSERPASS
-/* BEGIN_RUSERPASS
- *
- * Copyright (c) 1985 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef lint
-static char sccsid[] = "@(#)ruserpass.c 5.3 (Berkeley) 3/1/91";
-#endif /* not lint */
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-char * renvlook();
-static FILE * cfile;
-
-#define DEFAULT 1
-#define LOGIN 2
-#define PASSWD 3
-#define ACCOUNT 4
-#define MACDEF 5
-#define ID 10
-#define MACH 11
-
-static char tokval[100];
-
-static struct toktab {
- char *tokstr;
- int tval;
-} toktab[]= {
- "default", DEFAULT,
- "login", LOGIN,
- "password", PASSWD,
- "passwd", PASSWD,
- "account", ACCOUNT,
- "machine", MACH,
- "macdef", MACDEF,
- 0, 0
-};
-
-static int
-token() {
- char *cp;
- int c;
- struct toktab *t;
-
- if (feof(cfile))
- return(0);
- while ((c = getc(cfile)) != EOF &&
- (c == '\n' || c == '\t' || c == ' ' || c == ','))
- continue;
- if (c == EOF)
- return(0);
- cp = tokval;
- if (c == '"') {
- while ((c = getc(cfile)) != EOF && c != '"') {
- if (c == '\\')
- c = getc(cfile);
- *cp++ = c;
- }
- } else {
- *cp++ = c;
- while ((c = getc(cfile)) != EOF
- && c != '\n' && c != '\t' && c != ' ' && c != ',') {
- if (c == '\\')
- c = getc(cfile);
- *cp++ = c;
- }
- }
- *cp = 0;
- if (tokval[0] == 0)
- return(0);
- for (t = toktab; t->tokstr; t++)
- if (!strcmp(t->tokstr, tokval))
- return(t->tval);
- return(ID);
-}
-
-ruserpass(host, aname, apass, aacct)
- char *host, **aname, **apass, **aacct;
-{
- char *hdir, buf[FTP_BUFSIZ], *tmp;
- char myname[MAXHOSTNAMELEN], *mydomain;
- int t, i, c, usedefault = 0;
-#ifdef NT
- struct _stat stb;
-#else /* NT */
- struct stat stb;
-#endif /* NT */
-
- hdir = getenv("HOME");
- if (hdir == NULL)
- hdir = ".";
- ckmakmsg(buf,FTP_BUFSIZ,hdir,"/.netrc",NULL,NULL);
- cfile = fopen(buf, "r");
- if (cfile == NULL) {
- if (errno != ENOENT)
- perror(buf);
- return(0);
- }
- if (gethostname(myname, MAXHOSTNAMELEN) < 0)
- myname[0] = '\0';
- if ((mydomain = ckstrchr(myname, '.')) == NULL)
- mydomain = "";
-
- next:
- while ((t = token())) switch(t) {
-
- case DEFAULT:
- usedefault = 1;
- /* FALL THROUGH */
-
- case MACH:
- if (!usedefault) {
- if (token() != ID)
- continue;
- /*
- * Allow match either for user's input host name
- * or official hostname. Also allow match of
- * incompletely-specified host in local domain.
- */
- if (ckstrcmp(host, tokval,-1,1) == 0)
- goto match;
- if (ckstrcmp(ftp_host, tokval,-1,0) == 0)
- goto match;
- if ((tmp = ckstrchr(ftp_host, '.')) != NULL &&
- ckstrcmp(tmp, mydomain,-1,1) == 0 &&
- ckstrcmp(ftp_host, tokval, tmp-ftp_host,0) == 0 &&
- tokval[tmp - ftp_host] == '\0')
- goto match;
- if ((tmp = ckstrchr(host, '.')) != NULL &&
- ckstrcmp(tmp, mydomain,-1,1) == 0 &&
- ckstrcmp(host, tokval, tmp - host, 0) == 0 &&
- tokval[tmp - host] == '\0')
- goto match;
- continue;
- }
-
- match:
- while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
-
- case LOGIN:
- if (token())
- if (*aname == 0) {
- *aname = malloc((unsigned) strlen(tokval) + 1);
- strcpy(*aname, tokval); /* safe */
- } else {
- if (strcmp(*aname, tokval))
- goto next;
- }
- break;
- case PASSWD:
- if (strcmp(*aname, "anonymous") &&
- fstat(fileno(cfile), &stb) >= 0 &&
- (stb.st_mode & 077) != 0) {
- fprintf(stderr, "Error - .netrc file not correct mode.\n");
- fprintf(stderr, "Remove password or correct mode.\n");
- goto bad;
- }
- if (token() && *apass == 0) {
- *apass = malloc((unsigned) strlen(tokval) + 1);
- strcpy(*apass, tokval); /* safe */
- }
- break;
- case ACCOUNT:
- if (fstat(fileno(cfile), &stb) >= 0
- && (stb.st_mode & 077) != 0) {
- fprintf(stderr, "Error - .netrc file not correct mode.\n");
- fprintf(stderr, "Remove account or correct mode.\n");
- goto bad;
- }
- if (token() && *aacct == 0) {
- *aacct = malloc((unsigned) strlen(tokval) + 1);
- strcpy(*aacct, tokval); /* safe */
- }
- break;
-
- default:
- fprintf(stderr, "Unknown .netrc keyword %s\n", tokval);
- break;
- }
- goto done;
- }
-
- done:
- fclose(cfile);
- return(0);
-
- bad:
- fclose(cfile);
- return(-1);
-}
-#endif /* USE_RUSERPASS */
-
-static char *radixN =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-static char pad = '=';
-
-static int
-radix_encode(inbuf, outbuf, inlen, outlen, decode)
- CHAR inbuf[], outbuf[];
- int inlen, *outlen, decode;
-{
- int i, j, D = 0;
- char *p;
- CHAR c = NUL;
-
- if (decode) {
- for (i = 0, j = 0; inbuf[i] && inbuf[i] != pad; i++) {
- if ((p = ckstrchr(radixN, inbuf[i])) == NULL)
- return(1);
- D = p - radixN;
- switch (i&3) {
- case 0:
- outbuf[j] = D<<2;
- break;
- case 1:
- outbuf[j++] |= D>>4;
- outbuf[j] = (D&15)<<4;
- break;
- case 2:
- outbuf[j++] |= D>>2;
- outbuf[j] = (D&3)<<6;
- break;
- case 3:
- outbuf[j++] |= D;
- }
- if (j == *outlen)
- return(4);
- }
- switch (i&3) {
- case 1: return(3);
- case 2: if (D&15) return(3);
- if (strcmp((char *)&inbuf[i], "==")) return(2);
- break;
- case 3: if (D&3) return(3);
- if (strcmp((char *)&inbuf[i], "=")) return(2);
- }
- *outlen = j;
- } else {
- for (i = 0, j = 0; i < inlen; i++) {
- switch (i%3) {
- case 0:
- outbuf[j++] = radixN[inbuf[i]>>2];
- c = (inbuf[i]&3)<<4;
- break;
- case 1:
- outbuf[j++] = radixN[c|inbuf[i]>>4];
- c = (inbuf[i]&15)<<2;
- break;
- case 2:
- outbuf[j++] = radixN[c|inbuf[i]>>6];
- outbuf[j++] = radixN[inbuf[i]&63];
- c = 0;
- }
- if (j == *outlen)
- return(4);
- }
- if (i%3) outbuf[j++] = radixN[c];
- switch (i%3) {
- case 1: outbuf[j++] = pad;
- case 2: outbuf[j++] = pad;
- }
- outbuf[*outlen = j] = '\0';
- }
- return(0);
-}
-
-static char *
-radix_error(e) int e;
-{
- switch (e) {
- case 0: return("Success");
- case 1: return("Bad character in encoding");
- case 2: return("Encoding not properly padded");
- case 3: return("Decoded # of bits not a multiple of 8");
- case 4: return("Output buffer too small");
- default: return("Unknown error");
- }
-}
-/* END_RUSERPASS */
-
-#ifdef FTP_SRP
-/*---------------------------------------------------------------------------+
- | |
- | Package: srpftp |
- | Author: Eugene Jhong |
- | |
- +---------------------------------------------------------------------------*/
-
-/*
- * Copyright (c) 1997-1999 The Stanford SRP Authentication Project
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL STANFORD BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
- * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
- * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- * In addition, the following conditions apply:
- *
- * 1. Any software that incorporates the SRP authentication technology
- * must display the following acknowlegment:
- * "This product uses the 'Secure Remote Password' cryptographic
- * authentication system developed by Tom Wu (tjw@CS.Stanford.EDU)."
- *
- * 2. Any software that incorporates all or part of the SRP distribution
- * itself must also display the following acknowledgment:
- * "This product includes software developed by Tom Wu and Eugene
- * Jhong for the SRP Distribution (http://srp.stanford.edu/srp/)."
- *
- * 3. Redistributions in source or binary form must retain an intact copy
- * of this copyright notice and list of conditions.
- */
-
-#define SRP_PROT_VERSION 1
-
-#ifdef CK_ENCRYPTION
-#define SRP_DEFAULT_CIPHER CIPHER_ID_CAST5_CBC
-#else
-#define SRP_DEFAULT_CIPHER CIPHER_ID_NONE
-#endif /* CK_ENCRYPTION */
-
-#define SRP_DEFAULT_HASH HASH_ID_SHA
-
-CHAR srp_pref_cipher = CIPHER_ID_DES3_ECB;
-CHAR srp_pref_hash = HASH_ID_SHA;
-
-static struct t_client *tc = NULL;
-static CHAR *skey = NULL;
-static krypto_context *incrypt = NULL;
-static krypto_context *outcrypt = NULL;
-
-typedef unsigned int srp_uint32;
-
-/*--------------------------------------------------------------+
- | srp_selcipher: select cipher |
- +--------------------------------------------------------------*/
-static int
-srp_selcipher (cname) char *cname; {
- cipher_desc *cd;
-
- if (!(cd = cipher_getdescbyname (cname))) {
- int i;
- CHAR *list = cipher_getlist ();
-
- fprintf (stderr, "ftp: supported ciphers:\n\n");
- for (i = 0; i < strlen (list); i++)
- fprintf (stderr, " %s\n", (cipher_getdescbyid(list[i]))->name);
- fprintf (stderr, "\n");
- return -1;
- }
- srp_pref_cipher = cd->id;
- return 0;
-}
-
-/*--------------------------------------------------------------+
- | srp_selhash: select hash |
- +--------------------------------------------------------------*/
-static int
-srp_selhash (hname) char *hname; {
- hash_desc *hd;
-
- if (!(hd = hash_getdescbyname (hname))) {
- int i;
- CHAR *list = hash_getlist ();
-
- fprintf (stderr, "ftp: supported hash functions:\n\n");
- for (i = 0; i < strlen (list); i++)
- fprintf (stderr, " %s\n", (hash_getdescbyid(list[i]))->name);
- fprintf (stderr, "\n");
- return -1;
- }
- srp_pref_hash = hd->id;
- return 0;
-}
-
-/*--------------------------------------------------------------+
- | srp_userpass: get username and password |
- +--------------------------------------------------------------*/
-static int
-srp_userpass (host) char *host; {
- char tmp[BUFSIZ], prompt[PROMPTSIZ];
- char *user;
-
- user = NULL;
-#ifdef USE_RUSERPASS
- ruserpass (host, &user, &srp_pass, &srp_acct);
-#endif /* USE_RUSERPASS */
-
- while (user == NULL) {
- char *myname;
- int ok;
-
- myname = whoami();
- if (!myname) myname = "";
- if (myname[0])
- ckmakxmsg(prompt,PROMPTSIZ," Name (",host,":",myname,"): ",
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- else
- ckmakmsg(prompt,PROMPTSIZ," Name (",host,"): ",NULL);
- tmp[0] = '\0';
- ok = uq_txt(NULL,prompt,1,NULL,tmp,BUFSIZ,NULL,
- DEFAULT_UQ_TIMEOUT);
- if (!ok || *tmp == '\0')
- user = myname;
- else
- user = brstrip(tmp);
- }
- ckstrncpy (srp_user, user,BUFSIZ);
- return(0);
-}
-
-/*--------------------------------------------------------------+
- | srp_reset: reset srp information |
- +--------------------------------------------------------------*/
-static int
-srp_reset () {
- if (tc) { t_clientclose (tc); tc = NULL; }
- if (incrypt) { krypto_delete (incrypt); incrypt = NULL; }
- if (outcrypt) { krypto_delete (outcrypt); outcrypt = NULL; }
- return(0);
-}
-
-/*--------------------------------------------------------------+
- | srp_ftp_auth: perform srp authentication |
- +--------------------------------------------------------------*/
-static int
-srp_ftp_auth(host, user, pass)
- char *host;
- char *user;
- char *pass;
-{
- struct t_num *wp;
- struct t_num N;
- struct t_num g;
- struct t_num s;
- struct t_num yp;
- CHAR buf[FTP_BUFSIZ];
- CHAR tmp[FTP_BUFSIZ];
- CHAR *bp, *cp;
- int n, e, clen, blen, len, i;
- CHAR cid = 0;
- CHAR hid = 0;
-
- srp_pass = srp_acct = 0;
-
- n = ftpcmd("AUTH SRP",NULL,0,0,ftp_vbm);
- if (n != REPLY_CONTINUE) {
- if (ftp_deb)
- fprintf(stderr, "SRP rejected as an authentication type\n");
- return(0);
- } else { /* Send protocol version */
- CHAR vers[4];
- memset (vers, 0, 4);
- vers[3] = SRP_PROT_VERSION;
- if (!quiet)
- printf ("SRP accepted as authentication type.\n");
- bp = tmp; blen = 0;
- srp_put (vers, &bp, 4, &blen);
- len = FTP_BUFSIZ;
- if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE))
- goto encode_error;
- reply_parse = "ADAT=";
- n = ftpcmd("ADAT",buf,-1,-1,0);
- }
- if (n == REPLY_CONTINUE) { /* Get protocol version */
- bp = buf;
- if (!reply_parse)
- goto data_error;
- blen = FTP_BUFSIZ;
- if (e = radix_encode(reply_parse, bp, 0, &blen, RADIX_DECODE))
- goto decode_error;
- if (srp_get (&bp, &cp, &blen, &clen) != 4)
- goto data_error;
-
- if (host) { /* Get username/password if needed */
- srp_userpass (host);
- } else {
- ckstrncpy (srp_user, user, BUFSIZ);
- srp_pass = pass;
- }
- bp = tmp; blen = 0; /* Send username */
- srp_put (srp_user, &bp, strlen (srp_user), &blen);
- len = FTP_BUFSIZ;
- if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE))
- goto encode_error;
- reply_parse = "ADAT=";
- n = ftpcmd("ADAT",buf,-1,-1,0);
- }
- if (n == REPLY_CONTINUE) { /* Get N, g and s */
- bp = buf;
- if (!reply_parse)
- goto data_error;
- blen = FTP_BUFSIZ;
- if (e = radix_encode (reply_parse, bp, 0, &blen, RADIX_DECODE))
- goto decode_error;
- if (srp_get (&bp, &(N.data), &blen, &(N.len)) < 0)
- goto data_error;
- if (srp_get (&bp, &(g.data), &blen, &(g.len)) < 0)
- goto data_error;
- if (srp_get (&bp, &(s.data), &blen, &(s.len)) < 0)
- goto data_error;
- if ((tc = t_clientopen (srp_user, &N, &g, &s)) == NULL) {
- fprintf (stderr, "Unable to open SRP client structure.\n");
- goto bad;
- }
- wp = t_clientgenexp (tc); /* Send wp */
- bp = tmp; blen = 0;
- srp_put (wp->data, &bp, wp->len, &blen);
- len = FTP_BUFSIZ;
- if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE))
- goto encode_error;
- reply_parse = "ADAT=";
- n = ftpcmd("ADAT",buf,-1,-1,0);
- }
- if (n == REPLY_CONTINUE) { /* Get yp */
- bp = buf;
- if (!reply_parse)
- goto data_error;
- blen = FTP_BUFSIZ;
- if (e = radix_encode (reply_parse, bp, 0, &blen, RADIX_DECODE))
- goto decode_error;
- if (srp_get (&bp, &(yp.data), &blen, &(yp.len)) < 0)
- goto data_error;
- if (!srp_pass) {
- static char ftppass[PASSBUFSIZ];
- int ok;
- setint();
- ok = uq_txt(NULL," SRP Password: ",2,NULL,ftppass,PASSBUFSIZ,NULL,
- DEFAULT_UQ_TIMEOUT);
- if (ok)
- srp_pass = brstrip(ftppass);
- }
- t_clientpasswd (tc, srp_pass);
- memset (srp_pass, 0, strlen (srp_pass));
- skey = t_clientgetkey (tc, &yp); /* Send response */
- bp = tmp; blen = 0;
- srp_put (t_clientresponse (tc), &bp, 20, &blen);
- len = FTP_BUFSIZ;
- if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE))
- goto encode_error;
- reply_parse = "ADAT=";
- n = ftpcmd("ADAT",buf,-1,-1,0);
- }
- if (n == REPLY_CONTINUE) { /* Get response */
- bp = buf;
- if (!reply_parse)
- goto data_error;
- blen = FTP_BUFSIZ;
- if (e = radix_encode (reply_parse, bp, 0, &blen, RADIX_DECODE))
- goto encode_error;
- if (srp_get (&bp, &cp, &blen, &clen) != 20)
- goto data_error;
- if (t_clientverify (tc, cp)) {
- fprintf (stderr, "WARNING: bad response to client challenge.\n");
- goto bad;
- }
- bp = tmp; blen = 0; /* Send nothing */
- srp_put ("\0", &bp, 1, &blen);
- len = FTP_BUFSIZ;
- if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE))
- goto encode_error;
- reply_parse = "ADAT=";
- n = ftpcmd("ADAT",buf,-1,-1,0);
- }
- if (n == REPLY_CONTINUE) { /* Get cipher & hash lists, seqnum */
- CHAR seqnum[4];
- CHAR *clist;
- CHAR *hlist;
- CHAR *p1;
- int clist_len, hlist_len;
- bp = buf;
- if (!reply_parse)
- goto data_error;
- blen = FTP_BUFSIZ;
- if (e = radix_encode (reply_parse, bp, 0, &blen, RADIX_DECODE))
- goto encode_error;
- if (srp_get (&bp, &clist, &blen, &clist_len) < 0)
- goto data_error;
- if (srp_get (&bp, &hlist, &blen, &hlist_len) < 0)
- goto data_error;
- if (srp_get (&bp, &cp, &blen, &clen) != 4)
- goto data_error;
- memcpy (seqnum, cp, 4);
- if (cipher_supported (clist, srp_pref_cipher)) /* Choose cipher */
- cid = srp_pref_cipher;
- if (!cid && cipher_supported (clist, SRP_DEFAULT_CIPHER))
- cid = SRP_DEFAULT_CIPHER;
- if (!cid) {
- CHAR *loclist = cipher_getlist ();
- for (i = 0; i < strlen (loclist); i++)
- if (cipher_supported (clist, loclist[i])) {
- cid = loclist[i];
- break;
- }
- }
- if (!cid) {
- fprintf (stderr, "Unable to agree on cipher.\n");
- goto bad;
- }
- /* Choose hash */
-
- if (srp_pref_hash && hash_supported (hlist, srp_pref_hash))
- hid = srp_pref_hash;
-
- if (!hid && hash_supported (hlist, SRP_DEFAULT_HASH))
- hid = SRP_DEFAULT_HASH;
-
- if (!hid) {
- CHAR *loclist = hash_getlist ();
- for (i = 0; i < strlen (loclist); i++)
- if (hash_supported (hlist, loclist[i])) {
- hid = loclist[i];
- break;
- }
- }
- if (!hid) {
- fprintf (stderr, "Unable to agree on hash.\n");
- goto bad;
- }
- /* Set incrypt */
-
- if (!(incrypt = krypto_new (cid, hid, skey, 20, NULL, 0, seqnum,
- KRYPTO_DECODE)))
- goto bad;
-
- /* Generate random number for outkey and outseqnum */
-
- t_random (seqnum, 4);
-
- /* Send cid, hid, outkey, outseqnum */
-
- bp = tmp; blen = 0;
- srp_put (&cid, &bp, 1, &blen);
- srp_put (&hid, &bp, 1, &blen);
- srp_put (seqnum, &bp, 4, &blen);
- len = FTP_BUFSIZ;
- if (e = radix_encode (tmp, buf, blen, &len, RADIX_ENCODE))
- goto encode_error;
- reply_parse = "ADAT=";
- n = ftpcmd("ADAT",buf,-1,-1,0);
-
- /* Set outcrypt */
-
- if (!(outcrypt = krypto_new (cid, hid, skey+20, 20, NULL, 0, seqnum,
- KRYPTO_ENCODE)))
- goto bad;
-
- t_clientclose (tc);
- tc = NULL;
- }
- if (n != REPLY_COMPLETE)
- goto bad;
-
- if (ftp_vbm) {
- if (ftp_deb)
- printf("\n");
- printf ("SRP authentication succeeded.\n");
- printf ("Using cipher %s and hash function %s.\n",
- (cipher_getdescbyid(cid))->name,
- (hash_getdescbyid(hid))->name
- );
- }
- reply_parse = NULL;
- auth_type = "SRP";
- return(1);
-
- encode_error:
- fprintf (stderr, "Base 64 encoding failed: %s.\n", radix_error (e));
- goto bad;
-
- decode_error:
- fprintf (stderr, "Base 64 decoding failed: %s.\n", radix_error (e));
- goto bad;
-
- data_error:
- fprintf (stderr, "Unable to unmarshal authentication data.\n");
- goto bad;
-
- bad:
- fprintf (stderr, "SRP authentication failed, trying regular login.\n");
- reply_parse = NULL;
- return(0);
-}
-
-/*--------------------------------------------------------------+
- | srp_put: put item to send buffer |
- +--------------------------------------------------------------*/
-static int
-srp_put (in, out, inlen, outlen)
- CHAR *in;
- CHAR **out;
- int inlen;
- int *outlen;
-{
- srp_uint32 net_len;
-
- net_len = htonl (inlen);
- memcpy (*out, &net_len, 4);
-
- *out += 4; *outlen += 4;
-
- memcpy (*out, in, inlen);
-
- *out += inlen; *outlen += inlen;
- return(0);
-}
-
-/*--------------------------------------------------------------+
- | srp_get: get item from receive buffer |
- +--------------------------------------------------------------*/
-static int
-srp_get (in, out, inlen, outlen)
- CHAR **in;
- CHAR **out;
- int *inlen;
- int *outlen;
-{
- srp_uint32 net_len;
-
- if (*inlen < 4) return -1;
-
- memcpy (&net_len, *in, 4); *inlen -= 4; *in += 4;
- *outlen = ntohl (net_len);
-
- if (*inlen < *outlen) return -1;
-
- *out = *in; *inlen -= *outlen; *in += *outlen;
-
- return *outlen;
-}
-
-/*--------------------------------------------------------------+
- | srp_encode: encode control message |
- +--------------------------------------------------------------*/
-static int
-srp_encode (private, in, out, len)
- int private;
- CHAR *in;
- CHAR *out;
- unsigned len;
-{
- if (private)
- return krypto_msg_priv (outcrypt, in, out, len);
- else
- return krypto_msg_safe (outcrypt, in, out, len);
-}
-
-/*--------------------------------------------------------------+
- | srp_decode: decode control message |
- +--------------------------------------------------------------*/
-static int
-srp_decode (private, in, out, len)
- int private;
- CHAR *in;
- CHAR *out;
- unsigned len;
-{
- if (private)
- return krypto_msg_priv (incrypt, in, out, len);
- else
- return krypto_msg_safe (incrypt, in, out, len);
-}
-
-#endif /* FTP_SRP */
-
-
-
-#ifdef NOT_USED
-/*
- The following code is from the Unix FTP client. Be sure to
- make sure that the functionality is not lost. Especially
- the Proxy stuff even though we have not yet implemented it.
-*/
-
-/* Send multiple files */
-
-static int
-ftp_mput(argc, argv) int argc; char **argv; {
- register int i;
- sig_t oldintr;
- int ointer;
- char *tp;
- sigtype mcancel();
-
- if (argc < 2 && !another(&argc, &argv, "local-files")) {
- printf("usage: %s local-files\n", argv[0]);
- ftpcode = -1;
- return;
- }
- mname = argv[0];
- mflag = 1;
- oldintr = signal(SIGINT, mcancel);
-
- /* Replace with calls to cc_execute() */
- setjmp(jcancel);
-#ifdef FTP_PROXY
- if (proxy) {
- char *cp, *tp2, tmpbuf[CKMAXPATH];
-
- while ((cp = remglob(argv,0)) != NULL) {
- if (*cp == 0) {
- mflag = 0;
- continue;
- }
- if (mflag && confirm(argv[0], cp)) {
- tp = cp;
- if (mcase) {
- while (*tp && !islower(*tp)) {
- tp++;
- }
- if (!*tp) {
- tp = cp;
- tp2 = tmpbuf;
- while ((*tp2 = *tp) != 0) {
- if (isupper(*tp2)) {
- *tp2 = 'a' + *tp2 - 'A';
- }
- tp++;
- tp2++;
- }
- }
- tp = tmpbuf;
- }
- if (ntflag) {
- tp = dotrans(tp);
- }
- if (mapflag) {
- tp = domap(tp);
- }
- sendrequest((sunique) ? "STOU" : "STOR", cp, tp, 0, -1, -1, 0);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with","mput")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- }
- signal(SIGINT, oldintr);
- mflag = 0;
- return;
- }
-#endif /* FTP_PROXY */
- for (i = 1; i < argc; i++) {
- register char **cpp, **gargs;
-
- if (mflag && confirm(argv[0], argv[i])) {
- tp = argv[i];
- sendrequest((ftp_usn) ? "STOU" : "STOR", argv[i], tp, 0,-1,-1, 0);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with","mput")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- continue;
-
- gargs = ftpglob(argv[i]);
- if (globerr != NULL) {
- printf("%s\n", globerr);
- if (gargs) {
- blkfree(gargs);
- free((char *)gargs);
- }
- continue;
- }
- for (cpp = gargs; cpp && *cpp != NULL; cpp++) {
- if (mflag && confirm(argv[0], *cpp)) {
- tp = *cpp;
- sendrequest((sunique) ? "STOU":"STOR", *cpp, tp, 0, -1, -1, 0);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with","mput")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- }
- if (gargs != NULL) {
- blkfree(gargs);
- free((char *)gargs);
- }
- }
- signal(SIGINT, oldintr);
- mflag = 0;
-}
-
-/* Get multiple files */
-
-static int
-ftp_mget(argc, argv) int argc; char **argv; {
- int rc = -1;
- sig_t oldintr;
- int ointer;
- char *cp, *tp, *tp2, tmpbuf[CKMAXPATH];
- sigtype mcancel();
-
- if (argc < 2 && !another(&argc, &argv, "remote-files")) {
- printf("usage: %s remote-files\n", argv[0]);
- ftpcode = -1;
- return(-1);
- }
- mname = argv[0];
- mflag = 1;
- oldintr = signal(SIGINT,mcancel);
- /* Replace with calls to cc_execute() */
- setjmp(jcancel);
- while ((cp = remglob(argv,proxy)) != NULL) {
- if (*cp == '\0') {
- mflag = 0;
- continue;
- }
- if (mflag && confirm(argv[0], cp)) {
- tp = cp;
- if (mcase) {
- while (*tp && !islower(*tp)) {
- tp++;
- }
- if (!*tp) {
- tp = cp;
- tp2 = tmpbuf;
- while ((*tp2 = *tp) != 0) {
- if (isupper(*tp2)) {
- *tp2 = 'a' + *tp2 - 'A';
- }
- tp++;
- tp2++;
- }
- }
- tp = tmpbuf;
- }
- rc = (recvrequest("RETR", tp, cp, "wb",
- tp != cp || !interactive) == 0,0,NULL,0,0,0);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with","mget")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- }
- signal(SIGINT,oldintr);
- mflag = 0;
- return(rc);
-}
-
-/* Delete multiple files */
-
-static int
-mdelete(argc, argv) int argc; char **argv; {
- sig_t oldintr;
- int ointer;
- char *cp;
- sigtype mcancel();
-
- if (argc < 2 && !another(&argc, &argv, "remote-files")) {
- printf("usage: %s remote-files\n", argv[0]);
- ftpcode = -1;
- return(-1);
- }
- mname = argv[0];
- mflag = 1;
- oldintr = signal(SIGINT, mcancel);
- /* Replace with calls to cc_execute() */
- setjmp(jcancel);
- while ((cp = remglob(argv,0)) != NULL) {
- if (*cp == '\0') {
- mflag = 0;
- continue;
- }
- if (mflag && confirm(argv[0], cp)) {
- rc = (ftpcmd("DELE",cp,-1,-1,ftp_vbm) == REPLY_COMPLETE);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with", "mdelete")) {
- mflag++;
- }
- interactive = ointer;
- }
- }
- }
- signal(SIGINT, oldintr);
- mflag = 0;
- return(rc);
-}
-
-/* Get a directory listing of multiple remote files */
-
-static int
-mls(argc, argv) int argc; char **argv; {
- sig_t oldintr;
- int ointer, i;
- char *cmd, mode[1], *dest;
- sigtype mcancel();
- int rc = -1;
-
- if (argc < 2 && !another(&argc, &argv, "remote-files"))
- goto usage;
- if (argc < 3 && !another(&argc, &argv, "local-file")) {
- usage:
- printf("usage: %s remote-files local-file\n", argv[0]);
- ftpcode = -1;
- return(-1);
- }
- dest = argv[argc - 1];
- argv[argc - 1] = NULL;
- if (strcmp(dest, "-") && *dest != '|')
- if (!globulize(&dest) ||
- !confirm("output to local-file:", dest)) {
- ftpcode = -1;
- return(-1);
- }
- cmd = argv[0][1] == 'l' ? "NLST" : "LIST";
- mname = argv[0];
- mflag = 1;
- oldintr = signal(SIGINT, mcancel);
- /* Replace with calls to cc_execute() */
- setjmp(jcancel);
- for (i = 1; mflag && i < argc-1; ++i) {
- *mode = (i == 1) ? 'w' : 'a';
- rc = recvrequest(cmd, dest, argv[i], mode, 0,0,NULL,0,0,0);
- if (!mflag && fromatty) {
- ointer = interactive;
- interactive = 1;
- if (confirm("Continue with", argv[0])) {
- mflag ++;
- }
- interactive = ointer;
- }
- }
- signal(SIGINT, oldintr);
- mflag = 0;
- return(rc);
-}
-
-static char *
-remglob(argv,doswitch) char *argv[]; int doswitch; {
- char temp[16];
- static char buf[CKMAXPATH];
- static FILE *ftemp = NULL;
- static char **args;
- int oldhash;
- char *cp, *mode;
-
- if (!mflag) {
- if (!doglob) {
- args = NULL;
- } else {
- if (ftemp) {
- (void) fclose(ftemp);
- ftemp = NULL;
- }
- }
- return(NULL);
- }
- if (!doglob) {
- if (args == NULL)
- args = argv;
- if ((cp = *++args) == NULL)
- args = NULL;
- return(cp);
- }
- if (ftemp == NULL) {
- (void) strcpy(temp, _PATH_TMP);
-#ifdef MKTEMP
-#ifndef MKSTEMP
- (void) mktemp(temp);
-#endif /* MKSTEMP */
-#endif /* MKTEMP */
- verbose = 0;
- oldhash = hash, hash = 0;
-#ifdef FTP_PROXY
- if (doswitch) {
- pswitch(!proxy);
- }
-#endif /* FTP_PROXY */
- for (mode = "wb"; *++argv != NULL; mode = "ab")
- recvrequest ("NLST", temp, *argv, mode, 0);
-#ifdef FTP_PROXY
- if (doswitch) {
- pswitch(!proxy);
- }
-#endif /* FTP_PROXY */
- hash = oldhash;
- ftemp = fopen(temp, "r");
- unlink(temp);
- if (ftemp == NULL && (!dpyactive || ftp_deb)) {
- printf("Can't find list of remote files, oops\n");
- return(NULL);
- }
- }
- if (fgets(buf, CKMAXPATH, ftemp) == NULL) {
- fclose(ftemp), ftemp = NULL;
- return(NULL);
- }
- if ((cp = ckstrchr(buf,'\n')) != NULL)
- *cp = '\0';
- return(buf);
-}
-#endif /* NOT_USED */
-#endif /* TCPSOCKET (top of file) */
-#endif /* SYSFTP (top of file) */
-#endif /* NOFTP (top of file) */
+++ /dev/null
-char *protv = /* -*-C-*- */
-"C-Kermit Protocol Module 8.0.158, 11 Sep 2002";
-
-int kactive = 0; /* Kermit protocol is active */
-
-#define PKTZEROHACK
-
-/* C K C P R O -- C-Kermit Protocol Module, in Wart preprocessor notation. */
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2004,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-#ifndef NOXFER
-#include "ckcsym.h"
-#include "ckcdeb.h"
-#include "ckcasc.h"
-#include "ckcker.h"
-#ifdef OS2
-#ifndef NT
-#define INCL_NOPM
-#define INCL_VIO /* Needed for ckocon.h */
-#include <os2.h>
-#undef COMMENT
-#endif /* NT */
-#include "ckocon.h"
-#endif /* OS2 */
-
-/*
- Note -- This file may also be preprocessed by the UNIX Lex program, but
- you must indent the above #include statements before using Lex, and then
- restore them to the left margin in the resulting C program before compilation.
- Also, the invocation of the "wart()" function below must be replaced by an
- invocation of the "yylex()" function. It might also be necessary to remove
- comments in the (%)(%)...(%)(%) section.
-*/
-
-/* State definitions for Wart (or Lex) */
-%states ipkt rfile rattr rdpkt ssinit ssfile ssattr ssdata sseof sseot
-%states serve generic get rgen ssopkt ropkt
-
-_PROTOTYP(static VOID xxproto,(void));
-_PROTOTYP(static VOID wheremsg,(void));
-_PROTOTYP(int wart,(void));
-_PROTOTYP(static int sgetinit,(int,int));
-_PROTOTYP(int sndspace,(int));
-
-/* External C-Kermit variable declarations */
- extern char *versio, *srvtxt, *cmarg, *cmarg2, **cmlist, *rf_err;
- extern char * rfspec, * sfspec, * srfspec, * rrfspec;
- extern char * prfspec, * psfspec, * psrfspec, * prrfspec;
- extern char *cdmsgfile[];
- extern char * snd_move, * snd_rename, * srimsg;
- extern char filnam[], ofilnam[], fspec[], ttname[], ofn1[];
- extern CHAR sstate, *srvptr, *data;
- extern int timint, rtimo, nfils, hcflg, xflg, flow, mdmtyp, network;
- extern int oopts, omode, oname, opath, nopush, isguest, xcmdsrc, rcdactive;
- extern int rejection, moving, fncact, bye_active, urserver, fatalio;
- extern int protocol, prefixing, filcnt, carrier, fnspath, interrupted;
- extern int recursive, inserver, nzxopts, idletmo, srvidl, xfrint;
- extern struct ck_p ptab[];
- extern int remfile, rempipe, xferstat, filestatus, wearealike, fackpath;
- extern int patterns, filepeek, gnferror;
- extern char * remdest;
-
-#ifdef PKTZEROHACK
-#define PKTZEROLEN 32
-static char ipktack[PKTZEROLEN];
-static int ipktlen = 0;
-#endif /* PKTZEROHACK */
-
-static int s_timint = -1; /* For saving timeout value */
-static int myjob = 0;
-static int havefs = 0;
-#ifdef CK_LOGIN
-static int logtries = 0;
-#endif /* CK_LOGIN */
-
-static int cancel = 0;
-int fackbug = 0;
-
-#ifdef STREAMING
-extern int streaming, streamok;
-
-static VOID
-streamon() {
- if (streamok) {
- debug(F100,"streamon","",0);
- streaming = 1;
- timint = 0; /* No timeouts while streaming. */
- }
-}
-
-#ifdef COMMENT /* (not used) */
-static VOID
-streamoff() {
- if (streaming) {
- debug(F100,"streamoff","",0);
- streaming = 0;
- timint = s_timint; /* Restore timeout */
- }
-}
-#endif /* COMMENT */
-#else /* STREAMING */
-#define streamon()
-#define streamoff()
-#endif /* STREAMING */
-
-#ifndef NOSPL
-_PROTOTYP( int addmac, (char *, char *) );
-_PROTOTYP( int zzstring, (char *, char **, int *) );
-#endif /* NOSPL */
-#ifndef NOICP
-_PROTOTYP( int cmdsrc, (void) );
-#endif /* NOICP */
-
-#ifndef NOSERVER
- extern char * x_user, * x_passwd, * x_acct;
- extern int x_login, x_logged;
-#endif /* NOSERVER */
-
-#include "ckcnet.h"
-
-#ifdef TNCODE
- extern int ttnproto; /* Network protocol */
-#endif /* TNCODE */
-
-#ifdef CK_SPEED
- extern short ctlp[]; /* Control-character prefix table */
-#endif /* CK_SPEED */
-
-#ifdef TNCODE
- extern int tn_b_nlm, tn_b_xfer, tn_nlm;
-#ifdef CK_ENCRYPTION
- extern int tn_no_encrypt_xfer;
-#endif /* CK_ENCRYPTION */
-#endif /* TNCODE */
-
-#ifdef TCPSOCKET
-#ifndef NOLISTEN
- extern int tcpsrfd;
-#endif /* NOLISTEN */
-#endif /* TCPSOCKET */
-
- extern int cxseen, czseen, server, srvdis, local, displa, bctu, bctr, bctl;
- extern int quiet, tsecs, parity, backgrd, nakstate, atcapu, wslotn, winlo;
- extern int wslots, success, xitsta, rprintf, discard, cdtimo, keep, fdispla;
- extern int timef, stdinf, rscapu, sendmode, epktflg, epktrcvd, epktsent;
- extern int binary, fncnv;
- extern long speed, ffc, crc16, calibrate, dest;
-#ifdef COMMENT
- extern char *TYPCMD, *DIRCMD, *DIRCM2;
-#endif /* COMMENT */
-#ifndef OS2
- extern char *SPACMD, *SPACM2, *WHOCMD;
-#endif /* OS2 */
- extern CHAR *rdatap;
- extern struct zattr iattr;
-
-#ifdef VMS
- extern int batch;
-#endif /* VMS */
-
-#ifdef GFTIMER
- extern CKFLOAT fptsecs;
-#endif /* GFTIMER */
-
- extern CHAR *srvcmd;
- extern CHAR *epktmsg;
-
-#ifdef CK_TMPDIR
-extern int f_tmpdir; /* Directory changed temporarily */
-extern char savdir[]; /* For saving current directory */
-extern char * dldir;
-#endif /* CK_TMPDIR */
-
- extern int query; /* Query-active flag */
-#ifndef NOSPL
- extern int cmdlvl;
- char querybuf[QBUFL+1] = { NUL, NUL }; /* QUERY response buffer */
- char *qbufp = querybuf; /* Pointer to it */
- int qbufn = 0; /* Length of data in it */
-#else
- extern int tlevel;
-#endif /* NOSPL */
-
-#ifndef NOICP
- extern int escape;
-#endif /* NOICP */
-/*
- If the following flag is nonzero when the protocol module is entered,
- then server mode persists for exactly one transaction, rather than
- looping until BYE or FINISH is received.
-*/
-extern int justone;
-
-static int r_save = -1;
-static int p_save = -1;
-
-/* Function to let remote-mode user know where their file(s) went */
-
-int whereflg = 1; /* Unset with SET XFER REPORT */
-
-static VOID
-wheremsg() {
- extern int quiet, filrej;
- int n;
- n = filcnt - filrej;
- debug(F101,"wheremsg n","",n);
-
- debug(F110,"wheremsg prfspec",prfspec,0);
- debug(F110,"wheremsg rfspec",rfspec,0);
- debug(F110,"wheremsg psfspec",psfspec,0);
- debug(F110,"wheremsg sfspec",sfspec,0);
-
- debug(F110,"wheremsg prrfspec",prrfspec,0);
- debug(F110,"wheremsg rrfspec",rrfspec,0);
- debug(F110,"wheremsg psrfspec",psrfspec,0);
- debug(F110,"wheremsg srfspec",srfspec,0);
-
- if (!quiet && !local) {
- if (n == 1) {
- switch (myjob) {
- case 's':
- if (sfspec) {
- printf(" SENT: [%s]",sfspec);
- if (srfspec)
- printf(" To: [%s]",srfspec);
- printf(" (%s)\n", success ? "OK" : "FAILED");
- }
- break;
- case 'r':
- case 'v':
- if (rrfspec) {
- printf(" RCVD: [%s]",rrfspec);
- if (rfspec)
- printf(" To: [%s]",rfspec);
- printf(" (%s)\n", success ? "OK" : "FAILED");
- }
- }
- } else if (n > 1) {
- switch (myjob) {
- case 's':
- if (sfspec) {
- printf(" SENT: (%d files)",n);
- if (srfspec)
- printf(" Last: [%s]",srfspec);
- printf(" (%s)\n", success ? "OK" : "FAILED");
- }
- break;
- case 'r':
- case 'v':
- if (rrfspec) {
- printf(" RCVD: (%d files)",n);
- if (rfspec)
- printf(" Last: [%s]",rfspec);
- printf(" (%s)\n", success ? "OK" : "FAILED");
- }
- }
- } else if (n == 0) {
- if (myjob == 's')
- printf(" SENT: (0 files) \n");
- else if (myjob == 'r' || myjob == 'v')
- printf(" RCVD: (0 files) \n");
- }
- }
-}
-
-static VOID
-rdebug() {
- if (server)
- debug(F111,"RESUME","server=1",justone);
- else
- debug(F111,"RESUME","server=0",justone);
-}
-
-/* Flags for the ENABLE and DISABLE commands */
-extern int
- en_cpy, en_cwd, en_del, en_dir, en_fin, en_get, en_bye, en_mai, en_pri,
- en_hos, en_ren, en_sen, en_spa, en_set, en_typ, en_who, en_ret, en_xit,
- en_mkd, en_rmd;
-#ifndef NOSPL
-extern int en_asg, en_que;
-#endif /* NOSPL */
-extern int what, lastxfer;
-
-/* Global variables declared here */
-
- int whatru = 0; /* What are you. */
- int whatru2 = 0; /* What are you, cont'd. */
-
-/* Local variables */
-
- static char vstate = 0; /* Saved State */
- static char vcmd = 0; /* Saved Command */
- static int reget = 0; /* Flag for executing REGET */
- static int retrieve = 0; /* Flag for executing RETRIEVE */
- static int opkt = 0; /* Send Extended GET packet */
-
- static int x; /* General-purpose integer */
- static char *s; /* General-purpose string pointer */
-
-/* Macros - Note, BEGIN is predefined by Wart (and Lex) as "state = ", */
-/* BEGIN is NOT a GOTO! */
-#define TINIT if (tinit(1) < 0) return(-9)
-#define SERVE { TINIT; resetc(); nakstate=1; what=W_NOTHING; cmarg2=""; \
-sendmode=SM_SEND; havefs=0; recursive=r_save; fnspath=p_save; BEGIN serve; }
-#define RESUME { rdebug(); if (!server) { wheremsg(); return(0); } else \
-if (justone) { justone=0; wheremsg(); return(0); } else { SERVE; } }
-
-#ifdef GFTIMER
-#define QUIT x=quiet; quiet=1; clsif(); clsof(1); tsecs=gtimer(); \
- fptsecs=gftimer(); quiet=x; return(success)
-#else
-#define QUIT x=quiet; quiet=1; clsif(); clsof(1); tsecs=gtimer(); quiet=x; \
- return(success)
-#endif /* GFTIMER */
-
-/*
- By late 1999, the big switch() statement generated from the following state
- table began choking even gcc, so here we extract the code from the larger
- states into static routines to reduce the size of the cases and the
- switch() overall. The routines follow the state table; the prototypes are
- here. Each of these routines simply contains the text from the
- corresponding case, but with return(-1) added in appropriate places; see
- instructions after the state table switcher.
-*/
-static int rc; /* Return code for these routines */
-static int rcv_s_pkt(); /* Received an S packet */
-static int rcv_firstdata(); /* Received first Data packet */
-static int rcv_shortreply(); /* Short reply to a REMOTE command */
-static int srv_query(); /* Server answers an query */
-static int srv_copy(); /* Server executes REMOTE COPY */
-static int srv_rename(); /* Server executes REMOTE RENAME */
-static int srv_login(); /* Server executes REMOTE LOGIN */
-static int srv_timeout(); /* Server times out */
-
-%%
-
-/*
- Protocol entry points, one for each start state (sstate).
- The lowercase letters are internal "inputs" from the user interface.
- NOTE: The start state letters that appear on the left margin immediately
- below can NOT be used as packet types OR as G-packet subcodes.
-*/
-
-s { TINIT; /* Send file(s) */
- if (sinit() > 0) BEGIN ssinit;
- else RESUME; }
-
-v { TINIT; nakstate = 1; BEGIN get; } /* Receive file(s) */
-
-r { /* Client sends a GET command */
- TINIT;
- vstate = get;
- reget = 0;
- retrieve = 0;
- opkt = 0;
- vcmd = 0;
-#ifdef PKTZEROHACK
- ipktack[0] = NUL;
-#endif /* PKTZEROHACK */
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
-
-h { /* Client sends a RETRIEVE command */
- TINIT;
- vstate = get;
- reget = 0;
- retrieve = 1;
- opkt = 0;
- vcmd = 0;
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
-j { /* Client sends a REGET command */
- TINIT;
- vstate = get;
- reget = 1;
- retrieve = 0;
- opkt = 0;
- vcmd = 0;
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
-o { /* Client sends Extended GET Packet */
- TINIT;
- vstate = get;
- reget = oopts & GOPT_RES;
- retrieve = oopts & GOPT_DEL;
- opkt = 1;
- vcmd = 0;
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
-c { /* Client sends a Host command */
- TINIT;
- vstate = rgen;
- vcmd = 'C';
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
-k { TINIT; /* Client sends a Kermit command */
- vstate = rgen;
- vcmd = 'K';
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
-g { /* Client sends a REMOTE command */
- TINIT;
- vstate = rgen;
- vcmd = 'G';
- if (sipkt('I') >= 0)
- BEGIN ipkt;
- else
- RESUME;
-}
-x { /* Enter server mode */
- int x;
- x = justone;
- if (!ENABLED(en_del)) { /* If DELETE is disabled */
- if (fncact == XYFX_B || /* undo any file collision action */
- fncact == XYFX_U || /* that could result in deletion or */
- fncact == XYFX_A || /* modification of existing files. */
- fncact == XYFX_X) {
-#ifndef NOICP
- extern int g_fncact;
- g_fncact = fncact; /* Save current setting */
-#endif /* NOICP */
- fncact = XYFX_R; /* Change to RENAME */
- debug(F101,"server DELETE disabled so fncact RENAME","",fncact);
- }
- }
- SERVE; /* tinit() clears justone... */
- justone = x;
-#ifdef IKSDB
- if (ikdbopen) slotstate(what, "SERVER", "", "");
-#endif /* IKSDB */
-}
-
-a {
- int b1 = 0, b2 = 0;
- if (!data) TINIT; /* "ABEND" -- Tell other side. */
-#ifndef pdp11
- if (epktflg) { /* If because of E-PACKET command */
- b1 = bctl; b2 = bctu; /* Save block check type */
- bctl = bctu = 1; /* set it to 1 */
- }
-#endif /* pdp11 */
- errpkt((CHAR *)"User cancelled"); /* Send the packet */
-#ifndef pdp11
- if (epktflg) { /* Restore the block check */
- epktflg = 0;
- bctl = b1; bctu = b2;
- }
-#endif /* pdp11 */
- success = 0;
- return(0); /* Return from protocol. */
-}
-
-/*
- Dynamic states: <current-states>input-character { action }
- nakstate != 0 means we're in a receiving state, in which we send ACKs & NAKs.
-*/
-
-<rgen,get,serve,ropkt>S { /* Receive Send-Init packet. */
- rc = rcv_s_pkt();
- cancel = 0; /* Reset cancellation counter */
- debug(F101,"rcv_s_pkt","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
-
-/* States in which we get replies back from commands sent to a server. */
-/* Complicated because direction of protocol changes, packet number */
-/* stays at zero through I-G-S sequence, and complicated even more by */
-/* sliding windows buffer allocation. */
-
-<ipkt>Y { /* Get ack for I-packet */
- int x = 0;
-#ifdef PKTZEROHACK
- ckstrncpy(ipktack,(char *)rdatap,PKTZEROLEN); /* Save a copy of the ACK */
- ipktlen = strlen(ipktack);
-#endif /* PKTZEROHACK */
- spar(rdatap); /* Set parameters */
- cancel = 0;
- winlo = 0; /* Set window-low back to zero */
- debug(F101,"<ipkt>Y winlo","",winlo);
- urserver = 1; /* So I know I'm talking to a server */
- if (vcmd) { /* If sending a generic command */
- if (tinit(0) < 0) return(-9); /* Initialize many things */
- x = scmd(vcmd,(CHAR *)cmarg); /* Do that */
- if (x >= 0) x = 0; /* (because of O-Packet) */
- debug(F101,"proto G packet scmd","",x);
- vcmd = 0; /* and then un-remember it. */
- } else if (vstate == get) {
- debug(F101,"REGET sstate","",sstate);
- x = srinit(reget, retrieve, opkt); /* GET or REGET, etc */
- }
- if (x < 0) { /* If command was too long */
- if (!srimsg)
- srimsg = "Error sending string";
- errpkt((CHAR *)srimsg); /* cancel both sides. */
- success = 0;
- RESUME;
- } else if (x > 0) { /* Need to send more O-Packets */
- BEGIN ssopkt;
- } else {
- rtimer(); /* Reset the elapsed seconds timer. */
-#ifdef GFTIMER
- rftimer();
-#endif /* GFTIMER */
- winlo = 0; /* Window back to 0, again. */
- debug(F101,"<ipkt>Y vstate","",vstate);
- nakstate = 1; /* Can send NAKs from here. */
- BEGIN vstate; /* Switch to desired state */
- }
-}
-
-<ssopkt>Y { /* Got ACK to O-Packet */
- debug(F100,"CPCPRO <ssopkt>Y","",0);
- x = sopkt();
- debug(F101,"CPCPRO <ssopkt>Y x","",x);
- if (x < 0) { /* If error */
- errpkt((CHAR *)srimsg); /* cancel both sides. */
- success = 0;
- RESUME;
- } else if (x == 0) { /* This was the last O-Packet */
- rtimer(); /* Reset the elapsed seconds timer. */
-#ifdef GFTIMER
- rftimer();
-#endif /* GFTIMER */
- winlo = 0; /* Window back to 0, again. */
- debug(F101,"<ssopkt>Y winlo","",winlo);
- nakstate = 1; /* Can send NAKs from here. */
- BEGIN vstate; /* Switch to desired state */
- }
- debug(F101,"CPCPRO <ssopkt>Y not changing state","",x);
-}
-
-<ipkt>E { /* Ignore Error reply to I packet */
- int x = 0;
- winlo = 0; /* Set window-low back to zero */
- debug(F101,"<ipkt>E winlo","",winlo);
- if (vcmd) { /* In case other Kermit doesn't */
- if (tinit(0) < 0) return(-9);
- x = scmd(vcmd,(CHAR *)cmarg); /* understand I-packets. */
- if (x >= 0) x = 0; /* (because of O-Packet) */
- vcmd = 0; /* Otherwise act as above... */
- } else if (vstate == get) x = srinit(reget, retrieve, opkt);
- if (x < 0) { /* If command was too long */
- errpkt((CHAR *)srimsg); /* cancel both sides. */
- success = 0;
- RESUME;
- } else if (x > 0) { /* Need to send more O-Packets */
- BEGIN ssopkt;
- } else {
- freerpkt(winlo); /* Discard the Error packet. */
- debug(F101,"<ipkt>E winlo","",winlo);
- winlo = 0; /* Back to packet 0 again. */
- nakstate = 1; /* Can send NAKs from here. */
- BEGIN vstate;
- }
-}
-
-<get>Y { /* Resend of previous I-pkt ACK, same seq number */
- freerpkt(0); /* Free the ACK's receive buffer */
- resend(0); /* Send the GET packet again. */
-}
-
-/* States in which we're being a server */
-
-<serve,get>I { /* Get I-packet */
-#ifndef NOSERVER
- spar(rdatap); /* Set parameters from it */
- ack1(rpar()); /* Respond with our own parameters */
-#ifdef COMMENT
- pktinit(); /* Reinitialize packet numbers */
-#else
-#ifdef COMMENT
- /* This can't be right - it undoes the stuff we just negotiated */
- x = justone;
- tinit(1); /* Reinitialize EVERYTHING */
- justone = x; /* But this... */
-#else
- tinit(0); /* Initialize most things */
-#endif /* COMMENT */
-#endif /* COMMENT */
-#endif /* NOSERVER */
- cancel = 0; /* Reset cancellation counter */
-}
-
-<serve>R { /* GET */
-#ifndef NOSERVER
- if (x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- SERVE;
- } else if (sgetinit(0,0) < 0) {
- RESUME;
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "GET", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- }
-#endif /* NOSERVER */
-}
-
-<serve>H { /* GET /DELETE (RETRIEVE) */
-#ifndef NOSERVER
- if (x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- RESUME;
- } else if (!ENABLED(en_del)) {
- errpkt((CHAR *)"Deleting files is disabled");
- RESUME;
- } else if (sgetinit(0,0) < 0) {
- RESUME;
- } else {
- moving = 1;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "GET /DELETE", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- }
-#endif /* NOSERVER */
-}
-
-<serve>V { /* GET /RECURSIVE */
-#ifndef NOSERVER
- recursive = 1; /* Set these before sgetinit() */
- if (fnspath == PATH_OFF)
- fnspath = PATH_REL; /* Don't worry, they will be */
- if (x_login && !x_logged) { /* reset next time through. */
- errpkt((CHAR *)"Login required");
- RESUME;
- } else if (sgetinit(0,0) < 0) {
- RESUME;
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "GET /RECURSIVE", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- }
-#endif /* NOSERVER */
-}
-
-<serve>W { /* GET /RECURSIVE /DELETE */
-#ifndef NOSERVER
- recursive = 1; /* Set these before sgetinit() */
- if (fnspath == PATH_OFF)
- fnspath = PATH_REL; /* Don't worry, they will be */
- moving = 1; /* reset next time through. */
- if (x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- RESUME;
- } else if (!ENABLED(en_del)) {
- errpkt((CHAR *)"Deleting files is disabled");
- RESUME;
- } else if (sgetinit(0,0) < 0) {
- RESUME;
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR,1,"server",
- "GET /RECURSIVE /DELETE",(char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- }
-#endif /* NOSERVER */
-}
-
-<serve>J { /* GET /RECOVER (REGET) */
-#ifndef NOSERVER
- if (x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- SERVE;
- } else if (sgetinit(1,0) < 0) {
- RESUME;
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "GET /RECOVER", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- }
-#endif /* NOSERVER */
-}
-
-<serve>O { /* Extended GET */
-#ifndef NOSERVER
- if (x_login && !x_logged) { /* (any combination of options) */
- errpkt((CHAR *)"Login required");
- SERVE;
- } else if ((x = sgetinit(0,1)) < 0) {
- debug(F101,"CKCPRO <serve>O sgetinit fail","",x);
- RESUME;
- } else if (x == 0) {
- debug(F101,"CKCPRO <serve>O sgetinit done","",x);
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "EXTENDED GET", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- } else { /* Otherwise stay in this state */
- debug(F101,"CKCPRO <serve>O sgetinit TBC","",x);
- ack();
- BEGIN ropkt;
- }
-#endif /* NOSERVER */
-}
-
-<ropkt>O {
-#ifndef NOSERVER
- if (x_login && !x_logged) { /* (any combination of options) */
- errpkt((CHAR *)"Login required");
- SERVE;
- } else if ((x = sgetinit(0,1)) < 0) {
- debug(F101,"CKCPRO <ropkt>O sgetinit fail","",x);
- RESUME;
- } else if (x == 0) {
- debug(F101,"CKCPRO <ropkt>O sgetinit done","",x);
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "EXTENDED GET", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit;
- } else { /* Otherwise stay in this state */
- debug(F101,"CKCPRO <ropkt>O sgetinit TBC","",x);
- ack();
- }
-#endif /* NOSERVER */
-}
-
-<serve>G { /* Generic server command */
-#ifndef NOSERVER
- srvptr = srvcmd; /* Point to command buffer */
- decode(rdatap,putsrv,0); /* Decode packet data into it */
- putsrv(NUL); /* Insert a couple nulls */
- putsrv(NUL); /* for termination */
- if (srvcmd[0]) {
- sstate = srvcmd[0]; /* Set requested start state */
- if (x_login && !x_logged && /* Login required? */
- /* Login, Logout, and Help are allowed when not logged in */
- sstate != 'I' && sstate != 'L' && sstate != 'H') {
- errpkt((CHAR *)"Login required");
- SERVE;
- } else {
- nakstate = 0; /* Now I'm the sender. */
- what = W_REMO; /* Doing a REMOTE command. */
-#ifdef STREAMING
- if (!streaming)
-#endif /* STREAMING */
- if (timint < 1)
- timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
- binary = XYFT_T; /* Switch to text mode */
- BEGIN generic; /* Switch to generic command state */
- }
- } else {
- errpkt((CHAR *)"Badly formed server command"); /* report error */
- RESUME; /* & go back to server command wait */
- }
-#endif /* NOSERVER */
-}
-
-<serve>C { /* Receive Host command */
-#ifndef NOSERVER
- if (x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- SERVE;
- } else if (!ENABLED(en_hos)) {
- errpkt((CHAR *)"REMOTE HOST disabled");
- RESUME;
- } else if (nopush) {
- errpkt((CHAR *)"HOST commands not available");
- RESUME;
- } else {
- srvptr = srvcmd; /* Point to command buffer */
- decode(rdatap,putsrv,0); /* Decode command packet into it */
- putsrv(NUL); /* Null-terminate */
- nakstate = 0; /* Now sending, not receiving */
- binary = XYFT_T; /* Switch to text mode */
- if (syscmd((char *)srvcmd,"")) { /* Try to execute the command */
- what = W_REMO; /* Doing a REMOTE command. */
-#ifdef STREAMING
- if (!streaming)
-#endif /* STREAMING */
- if (timint < 1)
- timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE HOST", (char *)srvcmd);
-#endif /* CKSYSLOG */
- BEGIN ssinit; /* If OK, send back its output */
- } else { /* Otherwise */
- errpkt((CHAR *)"Can't do system command"); /* report error */
- RESUME; /* & go back to server command wait */
- }
- }
-#endif /* NOSERVER */
-}
-
-<serve>q { /* Interrupted or connection lost */
- rc = srv_timeout();
- debug(F101,"srv_timeout","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
-
-<serve>N { /* Server got a NAK in command-wait */
-#ifndef NOSERVER
- errpkt((CHAR *)"Did you say RECEIVE instead of GET?");
- RESUME;
-#endif /* NOSERVER */
-}
-
-<serve>. { /* Any other command in this state */
-#ifndef NOSERVER
- if (c != ('E' - SP) && c != ('Y' - SP)) /* except E and Y packets. */
- errpkt((CHAR *)"Unimplemented server function");
- /* If we answer an E with an E, we get an infinite loop. */
- /* A Y (ACK) can show up here if we sent back a short-form reply to */
- /* a G packet and it was echoed. ACKs can be safely ignored here. */
- RESUME; /* Go back to server command wait. */
-#endif /* NOSERVER */
-}
-
-<generic>I { /* Login/Out */
- rc = srv_login();
- debug(F101,"<generic>I srv_login","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
-
-<generic>C { /* Got REMOTE CD command */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE CD", (char *)srvcmd);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_cwd)) {
- errpkt((CHAR *)"REMOTE CD disabled");
- RESUME;
- } else {
- char * p = NULL;
- x = cwd((char *)(srvcmd+1)); /* Try to change directory */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE CD", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!x) { /* Failed */
- errpkt((CHAR *)"Can't change directory");
- RESUME; /* Back to server command wait */
- } else if (x == 2) { /* User wants message */
- if (!ENABLED(en_typ)) { /* Messages (REMOTE TYPE) disabled? */
- errpkt((CHAR *)"REMOTE TYPE disabled");
- RESUME;
- } else { /* TYPE is enabled */
- int i;
- for (i = 0; i < 8; i++) {
- if (zchki(cdmsgfile[i]) > -1) {
- break;
- }
- }
- binary = XYFT_T; /* Use text mode for this. */
- if (i < 8 && sndtype(cdmsgfile[i])) { /* Have readme file? */
- BEGIN ssinit; /* OK */
- } else { /* not OK */
- p = zgtdir();
- if (!p) p = "";
- success = (*p) ? 1 : 0;
- ack1((CHAR *)p); /* ACK with new directory name */
- success = 1;
- RESUME; /* wait for next server command */
- }
- }
- } else { /* User doesn't want message */
- p =zgtdir();
- if (!p) p = "";
- success = (*p) ? 1 : 0;
- ack1((CHAR *)p);
- success = 1;
- RESUME; /* Wait for next server command */
- }
- }
-#endif /* NOSERVER */
-}
-
-<generic>A { /* Got REMOTE PWD command */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE PWD", NULL);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_cwd)) {
- errpkt((CHAR *)"REMOTE CD disabled");
- RESUME;
- } else {
- if (encstr((CHAR *)zgtdir()) > -1) { /* Encode current directory */
- ack1(data); /* If it fits, send it back in ACK */
- success = 1;
- } else { /* Failed */
- ack(); /* Send empty ACK */
- success = 0; /* and indicate failure locally */
- }
- RESUME; /* Back to server command wait */
- }
-#endif /* NOSERVER */
-}
-
-<generic>D { /* REMOTE DIRECTORY command */
-#ifndef NOSERVER
- char *n2;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE DIRECTORY", (char *)srvcmd);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_dir)) { /* If DIR is disabled, */
- errpkt((CHAR *)"REMOTE DIRECTORY disabled"); /* refuse. */
- RESUME;
- } else { /* DIR is enabled. */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE DIR", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_cwd)) { /* But CWD is disabled */
- zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
- if (strcmp((char *)(srvcmd+2),n2)) { /* so refuse. */
- errpkt((CHAR *)"Access denied");
- RESUME; /* Remember, this is not a goto! */
- }
- }
- if (state == generic) { /* It's OK to go ahead. */
-#ifdef COMMENT
- n2 = (*(srvcmd+2)) ? DIRCMD : DIRCM2;
- if (syscmd(n2,(char *)(srvcmd+2))) /* If it can be done */
-#else
- int x;
- if ((x = snddir((char*)(srvcmd+2))) > 0)
-#endif /* COMMENT */
- {
- BEGIN ssinit; /* send the results back; */
- } else { /* otherwise */
- if (x < 0)
- errpkt((CHAR *)"No files match");
- else
- errpkt((CHAR *)"Can't list directory");
- RESUME; /* return to server command wait */
- }
- }
- }
-#endif /* NOSERVER */
-}
-
-<generic>E { /* REMOTE DELETE (Erase) */
-#ifndef NOSERVER
- char *n2;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE DELETE", (char *)srvcmd);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_del)) {
- errpkt((CHAR *)"REMOTE DELETE disabled");
- RESUME;
- } else { /* DELETE is enabled */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE DELETE", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_cwd)) { /* but CWD is disabled */
- zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
- if (strcmp((char *)(srvcmd+2),n2)) { /* so refuse. */
- errpkt((CHAR *)"Access denied");
- RESUME; /* Remember, this is not a goto! */
- }
- } else if (isdir((char *)(srvcmd+2))) { /* A directory name? */
- errpkt((CHAR *)"It's a directory");
- RESUME;
- }
- if (state == generic) { /* It's OK to go ahead. */
- int x;
- if ((x = snddel((char*)(srvcmd+2))) > 0) {
- BEGIN ssinit; /* If OK send results back */
- } else { /* otherwise */
- if (x < 0)
- errpkt((CHAR *)"File not found"); /* report failure */
- else
- errpkt((CHAR *)"DELETE failed");
- RESUME; /* & return to server command wait */
- }
- }
- }
-#endif /* NOSERVER */
-}
-
-<generic>F { /* FINISH */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "FINISH", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"SERVER FINISH", "", "");
-#endif /* IKSDB */
- if (!ENABLED(en_fin)) {
- errpkt((CHAR *)"FINISH disabled");
- RESUME;
- } else {
- ack(); /* Acknowledge */
- xxscreen(SCR_TC,0,0L,""); /* Display */
- success = 1;
- return(0); /* Done */
- }
-#endif /* NOSERVER */
-}
-
-<generic>X { /* EXIT */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE EXIT", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE EXIT", "", "");
-#endif /* IKSDB */
- if (!ENABLED(en_xit)) {
- errpkt((CHAR *)"EXIT disabled");
- RESUME;
- } else {
- ack(); /* Acknowledge */
- xxscreen(SCR_TC,0,0L,""); /* Display */
- doexit(GOOD_EXIT,xitsta);
- }
-#endif /* NOSERVER */
-}
-
-<generic>L { /* BYE (Logout) */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "BYE", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"SERVER BYE", "", "");
-#endif /* IKSDB */
- if (!ENABLED(en_bye)) {
- errpkt((CHAR *)"BYE disabled");
- RESUME;
- } else {
- ack(); /* Acknowledge */
- success = 1;
- msleep(750); /* Give the ACK time to get out */
- if (local)
- ttres(); /* Reset the terminal */
- xxscreen(SCR_TC,0,0L,""); /* Display */
- doclean(1); /* Clean up files, etc */
-#ifdef DEBUG
- debug(F100,"C-Kermit BYE - Loggin out...","",0);
- zclose(ZDFILE);
-#endif /* DEBUG */
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver)
- ckxlogout();
- else
-#endif /* CK_LOGIN */
-#endif /* IKSD */
-#ifdef TCPSOCKET
-#ifndef NOLISTEN
- if (network && tcpsrfd > 0 && !inserver)
- doexit(GOOD_EXIT,xitsta);
- else
-#endif /* NOLISTEN */
-#endif /* TCPSOCKET */
- return(zkself()); /* Try to log self out */
- }
-#endif /* NOSERVER */
-}
-
-<generic>H { /* REMOTE HELP */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE HELP", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE HELP", "", "");
-#endif /* IKSDB */
-#ifndef NOSERVER
- if (sndhlp(NULL)) {
- BEGIN ssinit; /* try to send it */
- } else { /* If not ok, */
- errpkt((CHAR *)"Can't send help"); /* send error message instead */
- RESUME; /* and return to server command wait */
- }
-#endif /* NOSERVER */
-}
-
-<generic>R { /* REMOTE RENAME */
- rc = srv_rename();
- debug(F101,"srv_rename","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
-
-<generic>K { /* REMOTE COPY */
- rc = srv_copy();
- debug(F101,"srv_copy","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
-
-<generic>S { /* REMOTE SET */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE SET", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifndef NOSERVER
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE SET", (char *)(srvcmd+1), "");
-#endif /* IKSDB */
- if (!ENABLED(en_set)) {
- errpkt((CHAR *)"REMOTE SET disabled");
- RESUME;
- } else {
- if (remset((char *)(srvcmd+1))) { /* Try to do what they ask */
- success = 1;
- ack(); /* If OK, then acknowledge */
- } else /* Otherwise */
- errpkt((CHAR *)"Unknown REMOTE SET parameter"); /* give error msg */
- RESUME; /* Return to server command wait */
- }
-#endif /* NOSERVER */
-}
-
-<generic>T { /* REMOTE TYPE */
-#ifndef NOSERVER
- char *n2;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE TYPE", (char *)srvcmd);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_typ)) {
- errpkt((CHAR *)"REMOTE TYPE disabled");
- RESUME;
- } else {
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE TYPE", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_cwd)) { /* If CWD disabled */
- zstrip((char *)(srvcmd+2),&n2); /* and they included a pathname, */
- if (strcmp((char *)(srvcmd+2),n2)) { /* refuse. */
- errpkt((CHAR *)"Access denied");
- RESUME; /* Remember, this is not a goto! */
- }
- }
- if (state == generic) { /* It's OK to go ahead. */
- binary = XYFT_T; /* Use text mode for this. */
- if ( /* (RESUME didn't change state) */
-#ifdef COMMENT
- syscmd(TYPCMD,(char *)(srvcmd+2)) /* Old way */
-#else
- sndtype((char *)(srvcmd+2)) /* New way */
-#endif /* COMMENT */
- )
- BEGIN ssinit; /* OK */
- else { /* not OK */
- errpkt((CHAR *)"Can't type file"); /* give error message */
- RESUME; /* wait for next server command */
- }
- }
- }
-#endif /* NOSERVER */
-}
-
-<generic>m { /* REMOTE MKDIR */
-#ifndef NOSERVER
-#ifdef CK_MKDIR
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE MKDIR", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE MKDIR", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_mkd)) {
- errpkt((CHAR *)"REMOTE MKDIR disabled");
- RESUME;
- } else if (!ENABLED(en_cwd)) { /* If CWD disabled */
- errpkt((CHAR *)"Directory access restricted");
- RESUME; /* Remember, this is not a goto! */
- }
- if (state == generic) { /* OK to go ahead. */
- char *p = NULL;
- x = ckmkdir(0,(char *)(srvcmd+2),&p,0,1); /* Make the directory */
- if (!p) p = "";
- if (x > -1) {
- encstr((CHAR *)p); /* OK - encode the name */
- ack1(data); /* Send short-form response */
- success = 1;
- RESUME;
- } else { /* not OK */
- if (!*p) p = "Directory creation failure";
- errpkt((CHAR *)p); /* give error message */
- RESUME; /* Wait for next server command */
- }
- }
-#else
- errpkt((CHAR *)"REMOTE MKDIR not available");
- RESUME;
-#endif /* CK_MKDIR */
-#endif /* NOSERVER */
-}
-
-<generic>d { /* REMOTE RMDIR */
-#ifndef NOSERVER
-#ifdef CK_MKDIR
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE RMDIR", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE RMDIR", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_rmd)) {
- errpkt((CHAR *)"REMOTE RMDIR disabled");
- RESUME;
- } else if (!ENABLED(en_cwd)) { /* If CWD disabled */
- errpkt((CHAR *)"Directory access restricted");
- RESUME; /* Remember, this is not a goto! */
- }
- if (state == generic) { /* OK to go ahead. */
- char *p = NULL;
- x = ckmkdir(1,(char *)(srvcmd+2),&p,0,1);
- if (!p) p = "";
- if (x > -1) {
- encstr((CHAR *)p); /* OK - encode the name */
- ack1(data); /* Send short-form response */
- success = 1;
- RESUME;
- } else { /* not OK */
- if (!*p) p = "Directory removal failure";
- errpkt((CHAR *)p); /* give error message */
- RESUME; /* Wait for next server command */
- }
- }
-#else
- errpkt((CHAR *)"REMOTE RMDIR not available");
- RESUME;
-#endif /* CK_MKDIR */
-#endif /* NOSERVER */
-}
-
-<generic>U { /* REMOTE SPACE */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE SPACE", (char *)srvcmd);
-#endif /* CKSYSLOG */
- if (!ENABLED(en_spa)) {
- errpkt((CHAR *)"REMOTE SPACE disabled");
- RESUME;
- } else {
- x = srvcmd[1]; /* Get area to check */
- x = ((x == NUL) || (x == SP)
-#ifdef OS2
- || (x == '!') || (srvcmd[3] == ':')
-#endif /* OS2 */
- );
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,
- "REMOTE SPACE",
- (x ? "" : (char *)srvcmd),
- ""
- );
-#endif /* IKSDB */
- if (!x && !ENABLED(en_cwd)) { /* CWD disabled */
- errpkt((CHAR *)"Access denied"); /* and non-default area given, */
- RESUME; /* refuse. */
- } else {
-#ifdef OS2
-_PROTOTYP(int sndspace,(int));
- if (sndspace(x ? toupper(srvcmd[2]) : 0)) {
- BEGIN ssinit; /* send the report. */
- } else { /* If not ok, */
- errpkt((CHAR *)"Can't send space"); /* send error message */
- RESUME; /* and return to server command wait */
- }
-#else
- if (nopush)
- x = 0;
- else
- x = (x ? syscmd(SPACMD,"") : syscmd(SPACM2,(char *)(srvcmd+2)));
- if (x) { /* If we got the info */
- BEGIN ssinit; /* send it */
- } else { /* otherwise */
- errpkt((CHAR *)"Can't check space"); /* send error message */
- RESUME; /* and await next server command */
- }
-#endif /* OS2 */
- }
- }
-#endif /* NOSERVER */
-}
-
-<generic>W { /* REMOTE WHO */
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE WHO", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE WHO", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- if (!ENABLED(en_who)) {
- errpkt((CHAR *)"REMOTE WHO disabled");
- RESUME;
- } else {
-#ifdef OS2
-_PROTOTYP(int sndwho,(char *));
- if (sndwho((char *)(srvcmd+2))) {
- BEGIN ssinit; /* try to send it */
- } else { /* If not ok, */
- errpkt((CHAR *)"Can't do who command"); /* send error msg */
- RESUME; /* and return to server command wait */
- }
-#else
- if (syscmd(WHOCMD,(char *)(srvcmd+2))) {
- BEGIN ssinit;
- } else {
- errpkt((CHAR *)"Can't do who command");
- RESUME;
- }
-#endif /* OS2 */
- }
-#endif /* NOSERVER */
-}
-
-<generic>V { /* Variable query or set */
- rc = srv_query();
- debug(F101,"srv_query","",rc);
- if (rc > -1) return(rc);
-}
-
-<generic>q { /* Interrupted or connection lost */
-#ifndef NOSERVER
- if (fatalio) { /* Connection lost */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL);
-#endif /* CKSYSLOG */
- success = 0;
- xitsta |= (what & W_KERMIT);
- QUIT;
- } else if (interrupted) {
- if (!ENABLED(en_fin)) { /* Ctrl-C typed */
- errpkt((CHAR *)"QUIT disabled");
- RESUME;
- } else {
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL);
-#endif /* CKSYSLOG */
- success = 0;
- xitsta |= (what & W_KERMIT);
- QUIT;
- }
- } else { /* Shouldn't happen */
- debug(F100,"SERVER (generic) GOT UNEXPECTED 'q'","",0);
- QUIT;
- }
-#endif /* NOSERVER */
-}
-
-<generic>. { /* Anything else in this state... */
-#ifndef NOSERVER
- errpkt((CHAR *)"Unimplemented REMOTE command"); /* Complain */
- RESUME; /* and return to server command wait */
-#endif /* NOSERVER */
-}
-
-<rgen>q { /* Sent BYE and connection broken */
- if (bye_active && ttchk() < 0) {
- msleep(500);
- bye_active = 0;
- ttclos(0); /* Close our end of the connection */
- clsof(0);
- return(success = 1);
- } else { /* Other generic command */
- return(success = 0); /* or connection not broken */
- }
-}
-
-<rgen>Y { /* Short-Form reply */
- rc = rcv_shortreply();
- debug(F101,"<rgen>Y rcv_shortreply","",rc);
- if (rc > -1) return(rc);
-}
-
-<rgen,rfile>F { /* File header */
- /* char *n2; */
- extern int rsn;
- debug(F101,"<rfile>F winlo 1","",winlo);
- xflg = 0; /* Not screen data */
- if (!czseen)
- cancel = 0; /* Reset cancellation counter */
-#ifdef CALIBRATE
- if (dest == DEST_N)
- calibrate = 1;
-#endif /* CALIBRATE */
- if (!rcvfil(filnam)) { /* Figure out local filename */
- errpkt((CHAR *)rf_err); /* Trouble */
- RESUME;
- } else { /* Real file, OK to receive */
- char * fnp;
- debug(F111,"<rfile>F winlo 2",fspec,winlo);
- if (filcnt == 1) /* rcvfil set this to 1 for 1st file */
- crc16 = 0L; /* Clear file CRC */
- fnp = fspec; /* This is the full path */
- if (server && !ENABLED(en_cwd) || /* if DISABLE CD */
- !fackpath /* or F-ACK-PATH OFF */
- ) {
- zstrip(fspec,&fnp); /* don't send back full path */
- }
- encstr((CHAR *)fnp);
- if (fackbug)
- ack();
- else
- ack1(data); /* Send it back in ACK */
- initattr(&iattr); /* Clear file attribute structure */
- streamon();
- if (window(wslotn) < 0) { /* Allocate negotiated window slots */
- errpkt((CHAR *)"Can't open window");
- RESUME;
- }
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,
- server ? "SERVER" : "",
- "RECEIVE",
- fspec
- );
-#endif /* IKSDB */
- BEGIN rattr; /* Now expect Attribute packets */
- }
-}
-
-<rgen,rfile>X { /* X-packet instead of file header */
- xflg = 1; /* Screen data */
- if (!czseen)
- cancel = 0; /* Reset cancellation counter */
- ack(); /* Acknowledge the X-packet */
- initattr(&iattr); /* Initialize attribute structure */
- streamon();
- if (window(wslotn) < 0) { /* allocate negotiated window slots */
- errpkt((CHAR *)"Can't open window");
- RESUME;
- }
-#ifndef NOSPL
- if (query) { /* If this is the response to */
- qbufp = querybuf; /* a query that we sent, initialize */
- qbufn = 0; /* the response buffer */
- querybuf[0] = NUL;
- }
-#endif /* NOSPL */
- what = W_REMO; /* we're doing a REMOTE command */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,
- server ? "SERVER" : "",
- "RECEIVE",
- fspec
- );
-#endif /* IKSDB */
- BEGIN rattr; /* Expect Attribute packets */
-}
-
-<rattr>A { /* Attribute packet */
- if (gattr(rdatap,&iattr) == 0) { /* Read into attribute structure */
-#ifdef CK_RESEND
- ack1((CHAR *)iattr.reply.val); /* Reply with data */
-#else
- ack(); /* If OK, acknowledge */
-#endif /* CK_RESEND */
- } else { /* Otherwise */
- extern long fsize;
- char *r;
- r = getreason(iattr.reply.val);
- ack1((CHAR *)iattr.reply.val); /* refuse to accept the file */
- xxscreen(SCR_ST,ST_REFU,0L,r); /* reason */
-#ifdef TLOG
- if (tralog && !tlogfmt)
- doxlog(what,filnam,fsize,binary,1,r);
-#endif /* TLOG */
- }
-}
-
-<rattr>D { /* First data packet */
- debug(F100,"<rattr> D firstdata","",0);
- rc = rcv_firstdata();
- debug(F101,"rcv_firstdata rc","",rc);
- if (rc > -1) return(rc); /* (see below) */
-}
-
-<rfile>B { /* EOT, no more files */
- ack(); /* Acknowledge the B packet */
- reot(); /* Do EOT things */
-#ifdef CK_TMPDIR
-/* If we were cd'd temporarily to another device or directory ... */
- if (f_tmpdir) {
- int x;
- x = zchdir((char *) savdir); /* ... restore previous directory */
- f_tmpdir = 0; /* and remember we did it. */
- debug(F111,"ckcpro.w B tmpdir restoring",savdir,x);
- }
-#endif /* CK_TMPDIR */
- RESUME; /* and quit */
-}
-
-<rdpkt>D { /* Got Data packet */
- debug(F101,"<rdpkt>D cxseen","",cxseen);
- debug(F101,"<rdpkt>D czseen","",czseen);
- if (cxseen || czseen || discard) { /* If file or group interruption */
- CHAR * msg;
- msg = czseen ? (CHAR *)"Z" : (CHAR *)"X";
-#ifdef STREAMING
- if (streaming) { /* Need to cancel */
- debug(F111,"<rdpkt>D streaming cancel",msg,cancel);
- if (cancel++ == 0) { /* Only do this once */
- ack1(msg); /* Put "X" or "Z" in ACK */
- } else if (czseen) {
- errpkt((CHAR *)"User canceled");
- RESUME;
- } else {
- fastack();
- }
- } else
-#endif /* STREAMING */
- ack1(msg);
- } else { /* No interruption */
- int rc, qf;
-#ifndef NOSPL
- qf = query;
-#else
- qf = 0;
-#endif /* NOSPL */
-#ifdef CKTUNING
- rc = (binary && !parity) ?
- bdecode(rdatap,putfil):
- decode(rdatap, qf ? puttrm : putfil, 1);
-#else
- rc = decode(rdatap, qf ? puttrm : putfil, 1);
-#endif /* CKTUNING */
- if (rc < 0) {
- discard = (keep == 0 || (keep == SET_AUTO && binary != XYFT_T));
- errpkt((CHAR *)"Error writing data"); /* If failure, */
- RESUME;
- } else /* Data written OK, send ACK */
-#ifdef STREAMING
- if (streaming)
- fastack();
- else
-#endif /* STREAMING */
- ack();
- }
-}
-
-<rattr>Z { /* EOF immediately after A-Packet. */
- rf_err = "Can't create file";
- timint = s_timint;
- if (discard) { /* Discarding a real file... */
- x = 1;
- } else if (xflg) { /* If screen data */
- if (remfile) { /* redirected to file */
- if (rempipe) /* or pipe */
- x = openc(ZOFILE,remdest); /* Pipe: start command */
- else
- x = opena(remdest,&iattr); /* File: open with attributes */
- } else { /* otherwise */
- x = opent(&iattr); /* "open" the screen */
- }
-#ifdef CALIBRATE
- } else if (calibrate) { /* If calibration run */
- x = ckopenx(&iattr); /* do this */
-#endif /* CALIBRATE */
- } else { /* otherwise */
- x = opena(filnam,&iattr); /* open the file, with attributes */
- if (x == -17) { /* REGET skipped because same size */
- discard = 1;
- rejection = 1;
- }
- }
- if (!x || reof(filnam, &iattr) < 0) { /* Close output file */
- errpkt((CHAR *) rf_err); /* If problem, send error msg */
- RESUME; /* and quit */
- } else { /* otherwise */
- if (x == -17)
- xxscreen(SCR_ST,ST_SKIP,SKP_RES,"");
- ack(); /* acknowledge the EOF packet */
- BEGIN rfile; /* and await another file */
- }
-}
-
-<rdpkt>q { /* Ctrl-C or connection loss. */
- timint = s_timint;
- window(1); /* Set window size back to 1... */
- cxseen = 1;
- x = clsof(1); /* Close file */
- return(success = 0); /* Failed */
-}
-
-<rdpkt>Z { /* End Of File (EOF) Packet */
-/* wslots = 1; */ /* (don't set) Window size back to 1 */
-#ifndef COHERENT /* Coherent compiler blows up on this switch() statement. */
- x = reof(filnam, &iattr); /* Handle the EOF packet */
- switch (x) { /* reof() sets the success flag */
- case -5: /* Handle problems */
- errpkt((CHAR *)"RENAME failed"); /* Fatal */
- RESUME;
- break;
- case -4:
- errpkt((CHAR *)"MOVE failed"); /* Fatal */
- RESUME;
- break;
- case -3: /* If problem, send error msg */
- errpkt((CHAR *)"Can't print file"); /* Fatal */
- RESUME;
- break;
- case -2:
- errpkt((CHAR *)"Can't mail file"); /* Fatal */
- RESUME;
- break;
- case 2: /* Not fatal */
- case 3:
- xxscreen(SCR_EM,0,0L,"Receiver can't delete temp file");
- RESUME;
- break;
- default:
- if (x < 0) { /* Fatal */
- errpkt((CHAR *)"Can't close file");
- RESUME;
- } else { /* Success */
-#ifndef NOSPL
- if (query) /* Query reponses generally */
- conoll(""); /* don't have line terminators */
-#endif /* NOSPL */
- if (czseen) { /* Batch canceled? */
- if (cancel++ == 0) { /* If we haven't tried this yet */
- ack1((CHAR *)"Z"); /* Try it once */
- } else { /* Otherwise */
- errpkt((CHAR *)"User canceled"); /* quite with Error */
- RESUME;
- }
- } else
- ack(); /* Acknowledge the EOF packet */
- BEGIN rfile; /* and await another file */
- }
- }
-#else
- if (reof(filnam, &iattr) < 0) { /* Close the file */
- errpkt((CHAR *)"Error at end of file");
- RESUME;
- } else { /* reof() sets success flag */
- ack();
- BEGIN rfile;
- }
-#endif /* COHERENT */
-}
-
-<ssinit>Y { /* ACK for Send-Init */
- spar(rdatap); /* set parameters from it */
- cancel = 0;
- bctu = bctr; /* switch to agreed-upon block check */
- bctl = (bctu == 4) ? 2 : bctu; /* Set block-check length */
-#ifdef CK_RESEND
- if ((sendmode == SM_RESEND) && (!atcapu || !rscapu)) { /* RESEND */
- errpkt((CHAR *) "RESEND capabilities not negotiated");
- RESUME;
- } else {
-#endif /* CK_RESEND */
- what = W_SEND; /* Remember we're sending */
- lastxfer = W_SEND;
- x = sfile(xflg); /* Send X or F header packet */
- cancel = 0; /* Reset cancellation counter */
- if (x) { /* If the packet was sent OK */
- if (!xflg && filcnt == 1) /* and it's a real file */
- crc16 = 0L; /* Clear the file CRC */
- resetc(); /* reset per-transaction counters */
- rtimer(); /* reset timers */
-#ifdef GFTIMER
- rftimer();
-#endif /* GFTIMER */
- streamon(); /* turn on streaming */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,
- (server ? "SERVER" : ""),
- "SEND",
- filnam
- );
-#endif /* IKSDB */
- BEGIN ssfile; /* and switch to receive-file state */
- } else { /* otherwise send error msg & quit */
- s = xflg ? "Can't execute command" : (char *)epktmsg;
- if (!*s) s = "Can't open file";
- errpkt((CHAR *)s);
- RESUME;
- }
-#ifdef CK_RESEND
- }
-#endif /* CK_RESEND */
-}
-
-/*
- These states are necessary to handle the case where we get a server command
- packet (R, G, or C) reply with an S packet, but the client retransmits the
- command packet. The input() function doesn't catch this because the packet
- number is still zero.
-*/
-<ssinit>R { /* R packet was retransmitted. */
- xsinit(); /* Resend packet 0 */
-}
-
-<ssinit>G { /* Same deal if G packet comes again */
- xsinit();
-}
-
-/* should probably add cases for O, W, V, H, J, ... */
-
-<ssinit>C { /* Same deal if C packet comes again */
- xsinit();
-}
-
-<ssfile>Y { /* ACK for F or X packet */
- srvptr = srvcmd; /* Point to string buffer */
- decode(rdatap,putsrv,0); /* Decode data field, if any */
- putsrv(NUL); /* Terminate with null */
- ffc = 0L; /* Reset file byte counter */
- debug(F101,"<ssfile>Y cxseen","",cxseen);
- if (*srvcmd) { /* If remote name was recorded */
- if (sendmode != SM_RESEND) {
- if (fdispla == XYFD_C || fdispla == XYFD_S)
- xxscreen(SCR_AN,0,0L,(char *)srvcmd);
- tlog(F110," remote name:",(char *) srvcmd,0L);
- makestr(&psrfspec,(char *)srvcmd);
- }
- }
- if (cxseen||czseen) { /* Interrupted? */
- debug(F101,"<ssfile>Y canceling","",0);
- x = clsif(); /* Close input file */
- sxeof(1); /* Send EOF(D) */
- BEGIN sseof; /* and switch to EOF state. */
- } else if (atcapu) { /* If attributes are to be used */
- if (sattr(xflg | stdinf, 1) < 0) { /* send them */
- errpkt((CHAR *)"Can't send attributes"); /* if problem, say so */
- RESUME; /* and quit */
- } else BEGIN ssattr; /* if ok, switch to attribute state */
- } else { /* Attributes not negotiated */
- if (window(wslotn) < 0) { /* Open window */
- errpkt((CHAR *)"Can't open window");
- RESUME;
- } else if ((x = sdata()) == -2) { /* Send first data packet data */
- window(1); /* Connection lost, reset window */
- x = clsif(); /* Close input file */
- return(success = 0); /* Return failure */
- } else if (x == -9) { /* User interrupted */
- errpkt((CHAR *)"User cancelled"); /* Send Error packet */
- window(1); /* Set window size back to 1... */
- timint = s_timint; /* Restore timeout */
- return(success = 0); /* Failed */
- } else if (x < 0) { /* EOF (empty file) or interrupted */
- window(1); /* put window size back to 1, */
- debug(F101,"<ssfile>Y cxseen","",cxseen);
- x = clsif(); /* If not ok, close input file, */
- if (x < 0) /* treating failure as interruption */
- cxseen = 1; /* Send EOF packet */
- seof(cxseen||czseen);
- BEGIN sseof; /* and switch to EOF state. */
- } else { /* First data sent OK */
- BEGIN ssdata; /* All ok, switch to send-data state */
- }
- }
-}
-
-<ssattr>Y { /* Got ACK to A packet */
- ffc = 0L; /* Reset file byte counter */
- debug(F101,"<ssattr>Y cxseen","",cxseen);
- if (cxseen||czseen) { /* Interrupted? */
- debug(F101,"<sattr>Y canceling","",0);
- x = clsif(); /* Close input file */
- sxeof(1); /* Send EOF(D) */
- BEGIN sseof; /* and switch to EOF state. */
- } else if (rsattr(rdatap) < 0) { /* Was the file refused? */
- discard = 1; /* Set the discard flag */
- clsif(); /* Close the file */
- sxeof(1); /* send EOF with "discard" code */
- BEGIN sseof; /* switch to send-EOF state */
- } else if ((x = sattr(xflg | stdinf, 0)) < 0) { /* Send more? */
- errpkt((CHAR *)"Can't send attributes"); /* Trouble... */
- RESUME;
- } else if (x == 0) { /* No more to send so now the data */
- if (window(wslotn) < 0) { /* Allocate negotiated window slots */
- errpkt((CHAR *)"Can't open window");
- RESUME;
- }
- if ((x = sdata()) == -2) { /* File accepted, send first data */
- window(1); /* Connection broken */
- x = clsif(); /* Close file */
- return(success = 0); /* Return failure */
- } else if (x == -9) { /* User interrupted */
- errpkt((CHAR *)"User cancelled"); /* Send Error packet */
- window(1); /* Set window size back to 1... */
- timint = s_timint; /* Restore timeout */
- return(success = 0); /* Failed */
- } else if (x < 0) { /* If data was not sent */
- window(1); /* put window size back to 1, */
- debug(F101,"<ssattr>Y cxseen","",cxseen);
- if (clsif() < 0) /* Close input file */
- cxseen = 1; /* Send EOF packet */
- seof(cxseen||czseen);
- BEGIN sseof; /* and switch to EOF state. */
- } else {
- BEGIN ssdata; /* All ok, switch to send-data state */
- }
- }
-}
-
-<ssdata>q { /* Ctrl-C or connection loss. */
- window(1); /* Set window size back to 1... */
- cxseen = 1; /* To indicate interruption */
- x = clsif(); /* Close file */
- return(success = 0); /* Failed */
-}
-
-<ssdata>Y { /* Got ACK to Data packet */
- canned(rdatap); /* Check if file transfer cancelled */
- debug(F111,"<ssdata>Y cxseen",rdatap,cxseen);
- debug(F111,"<ssdata>Y czseen",rdatap,czseen);
- if ((x = sdata()) == -2) { /* Try to send next data */
- window(1); /* Connection lost, reset window */
- x = clsif(); /* Close file */
- return(success = 0); /* Failed */
- } else if (x == -9) { /* User interrupted */
- errpkt((CHAR *)"User cancelled"); /* Send Error packet */
- window(1); /* Set window size back to 1... */
- timint = s_timint; /* Restore original timeout */
- return(success = 0); /* Failed */
- } else if (x < 0) { /* EOF - finished sending data */
- debug(F101,"<ssdata>Y cxseen","",cxseen);
- window(1); /* Set window size back to 1... */
- if (clsif() < 0) /* Close input file */
- cxseen = 1; /* Send EOF packet */
- debug(F101,"<ssdata>Y CALLING SEOF()","",cxseen);
- seof(cxseen||czseen);
- BEGIN sseof; /* and enter send-eof state */
- }
- /* NOTE: If x == 0 it means we're draining: see sdata()! */
-}
-
-<sseof>Y { /* Got ACK to EOF */
- int g, xdiscard;
- canned(rdatap); /* Check if file transfer cancelled */
- debug(F111,"<sseof>Y cxseen",rdatap,cxseen);
- debug(F111,"<sseof>Y czseen",rdatap,czseen);
- debug(F111,"<sseof>Y discard",rdatap,discard);
- xdiscard = discard;
- discard = 0;
- success = (cxseen == 0 && czseen == 0); /* Transfer status... */
- debug(F101,"<sseof>Y success","",success);
- if (success && rejection > 0) /* If rejected, succeed if */
- if (rejection != '#' && /* reason was date */
- rejection != 1 && rejection != '?') /* or name; */
- success = 0; /* fail otherwise. */
- cxseen = 0; /* This goes back to zero. */
- if (success) { /* Only if transfer succeeded... */
- xxscreen(SCR_ST,ST_OK,0L,"");
- if (!xdiscard) {
- makestr(&sfspec,psfspec); /* Record filenames for WHERE */
- makestr(&srfspec,psrfspec);
- }
- if (moving) { /* If MOVE'ing */
- x = zdelet(filnam); /* Try to delete the source file */
-#ifdef TLOG
- if (tralog) {
- if (x > -1) {
- tlog(F110," deleted",filnam,0);
- } else {
- tlog(F110," delete failed:",ck_errstr(),0);
- }
- }
-#endif /* TLOG */
- } else if (snd_move) { /* Or move it */
- int x;
- x = zrename(filnam,snd_move);
-#ifdef TLOG
- if (tralog) {
- if (x > -1) {
- tlog(F110," moved to ",snd_move,0);
- } else {
- tlog(F110," move failed:",ck_errstr(),0);
- }
- }
-#endif /* TLOG */
- } else if (snd_rename) { /* Or rename it */
- char *s = snd_rename; /* Renaming string */
-#ifndef NOSPL
- int y; /* Pass it thru the evaluator */
- extern int cmd_quoting; /* for \v(filename) */
- if (cmd_quoting) { /* But only if cmd_quoting is on */
- y = MAXRP;
- s = (char *)srvcmd;
- zzstring(snd_rename,&s,&y);
- s = (char *)srvcmd;
- }
-#endif /* NOSPL */
- if (s) if (*s) {
- int x;
- x = zrename(filnam,s);
-#ifdef TLOG
- if (tralog) {
- if (x > -1) {
- tlog(F110," renamed to",s,0);
- } else {
- tlog(F110," rename failed:",ck_errstr(),0);
- }
- }
-#endif /* TLOG */
-#ifdef COMMENT
- *s = NUL;
-#endif /* COMMENT */
- }
- }
- }
- if (czseen) { /* Check group interruption flag */
- g = 0; /* No more files if interrupted */
- } else { /* Otherwise... */
-#ifdef COMMENT
- /* This code makes any open error fatal to a file-group transfer. */
- g = gnfile();
- debug(F111,"<sseof>Y gnfile",filnam,g);
- if (g > 0) { /* Any more files to send? */
- if (sfile(xflg)) /* Yes, try to send next file header */
- BEGIN ssfile; /* if ok, enter send-file state */
- else { /* otherwise */
- s = xflg ? "Can't execute command" : (char *)epktmsg;
- if (!*s) s = "Can't open file";
- errpkt((CHAR *)s); /* send error message */
- RESUME; /* and quit */
- }
- } else { /* No next file */
- tsecs = gtimer(); /* get statistics timers */
-#ifdef GFTIMER
- fptsecs = gftimer();
-#endif /* GFTIMER */
- seot(); /* send EOT packet */
- BEGIN sseot; /* enter send-eot state */
- }
-#else /* COMMENT */
- while (1) { /* Keep trying... */
- g = gnfile(); /* Get next file */
- debug(F111,"<sseof>Y gnfile",filnam,g);
- if (g == 0 && gnferror == 0) /* No more, stop trying */
- break;
- if (g > 0) { /* Have one */
- if (sfile(xflg)) { /* Try to open and send F packet */
- BEGIN ssfile; /* If OK, enter send-file state */
- break; /* and break out of loop. */
- }
- } /* Otherwise keep trying to get one we can send... */
- }
- }
- if (g == 0) {
- debug(F101,"<sseof>Y no more files","",czseen);
- tsecs = gtimer(); /* Get statistics timers */
-#ifdef GFTIMER
- fptsecs = gftimer();
-#endif /* GFTIMER */
- seot(); /* Send EOT packet */
- BEGIN sseot; /* Enter send-eot state */
- }
-#endif /* COMMENT */
-}
-
-<sseot>Y { /* Got ACK to EOT */
- debug(F101,"sseot justone","",justone);
- RESUME; /* All done, just quit */
-}
-
-E { /* Got Error packet, in any state */
- char *s = "";
- window(1); /* Close window */
- timint = s_timint; /* Restore original timeout */
- if (*epktmsg) /* Message from Error packet */
- s = (char *)epktmsg;
- if (!*s) { /* If not there then maybe here */
- s = (char *)rdatap;
- ckstrncpy((char *)epktmsg,(char *)rdatap,PKTMSGLEN);
- }
- if (!*s) /* Hopefully we'll never see this. */
- s = "Unknown error";
- success = 0; /* For IF SUCCESS/FAIL. */
- debug(F101,"ckcpro.w justone at E pkt","",justone);
-
- success = 0; /* Transfer failed */
- xferstat = success; /* Remember transfer status */
- if (!epktsent) {
- x = quiet; quiet = 1; /* Close files silently, */
- epktrcvd = 1; /* Prevent messages from clsof() */
- clsif();
- clsof(1); /* discarding any output file. */
- ermsg(s); /* Issue the message (calls screen). */
- quiet = x; /* Restore quiet state */
- }
- tstats(); /* Get stats */
-/*
- If we are executing commands from a command file or macro, let the command
- file or macro decide whether to exit, based on SET { TAKE, MACRO } ERROR.
-*/
- if (
-#ifndef NOICP
- !xcmdsrc &&
-#endif /* NOICP */
- backgrd && !server)
- fatal("Protocol error");
- xitsta |= (what & W_KERMIT); /* Save this for doexit(). */
-#ifdef CK_TMPDIR
-/* If we were cd'd temporarily to another device or directory ... */
- if (f_tmpdir) {
- int x;
- x = zchdir((char *) savdir); /* ... restore previous directory */
- f_tmpdir = 0; /* and remember we did it. */
- debug(F111,"ckcpro.w E tmpdir restored",savdir,x);
- }
-#endif /* CK_TMPDIR */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"ERROR", (char *)epktmsg, "");
-#endif /* IKSDB */
- RESUME;
-}
-
-q { success = 0; QUIT; } /* Ctrl-C or connection loss. */
-
-. { /* Anything not accounted for above */
- errpkt((CHAR *)"Unexpected packet type"); /* Give error message */
- window(1);
- xitsta |= (what & W_KERMIT); /* Save this for doexit(). */
- RESUME; /* and quit */
-}
-
-%%
-
-/*
- From here down to proto() are routines that were moved out of the state
- table switcher because the resulting switch() had become too large.
- To move the contents of a state-table case to a routine:
- 1. Add a prototype to the list above the state table switcher.
- 2. Make a routine with an appropriate name, returning int.
- 3. Move the code into it.
- 4. Put a call to the new routine in the former spot:
- rc = name_of_routine();
- if (rc > -1) return(rc);
- 5. Add "return(-1);" after every RESUME, SERVE, or BEGIN macro and
- at the end if the code is open-ended.
-*/
-static int
-rcv_firstdata() {
- extern int dispos;
- debug(F101,"rcv_firstdata","",dispos);
-
- if (discard) { /* if we're discarding the file */
- ack1((CHAR *)"X"); /* just ack the data like this. */
- cancel++; /* and count it */
- BEGIN rdpkt; /* and wait for more data packets. */
- return(-1);
- } else { /* Not discarding. */
- rf_err = "Can't open file";
- if (xflg) { /* If screen data */
- if (remfile) { /* redirected to file */
- if (rempipe) /* or pipe */
- x = openc(ZOFILE,remdest); /* Pipe: start command */
- else
- x = opena(remdest,&iattr); /* File: open with attributes */
- } else { /* otherwise */
- x = opent(&iattr); /* "open" the screen */
- }
- } else { /* otherwise */
-#ifdef CALIBRATE
- if (calibrate) { /* If calibration run */
- x = ckopenx(&iattr); /* open nothing */
-#ifdef STREAMING
- if (streaming) /* Streaming */
- fastack(); /* ACK without ACKing. */
- else
-#endif /* STREAMING */
- ack(); /* Send real ACK */
- BEGIN rdpkt; /* Proceed to next state */
- return(-1);
- } else
-#endif /* CALIBRATE */
-#ifdef UNIX
-/*
- In UNIX we can pipe the file data into the mail program, which is to be
- preferred to writing it out to a temp file and then mailing it afterwards.
- This depends rather heavily on all UNIXes having a mail command that
- accepts '-s "subject"' on the command line. MAILCMD (e.g. mail, Mail, mailx)
- is defined in ckufio.c.
-*/
- if (dispos == 'M') { /* Mail... */
- char *s;
- char * tmp = NULL;
- int n = 0;
- extern char *MAILCMD;
- s = iattr.disp.val + 1;
- n = (int)strlen(MAILCMD) + /* Mail command */
- (int)strlen(s) + /* address */
- (int)strlen(ofilnam) + 32; /* subject */
- if (tmp = (char *)malloc(n)) {
- ckmakxmsg(tmp,n,
- MAILCMD," -s \"",ofilnam,"\" ",s,
- NULL,NULL,NULL,NULL,NULL,NULL,NULL);
- debug(F111,"rcv_firsdata mail",tmp,(int)strlen(tmp));
- x = openc(ZOFILE,(char *)tmp);
- free(tmp);
- } else
- x = 0;
- } else if (dispos == 'P') { /* Ditto for print */
- char * tmp = NULL;
- int n;
- extern char *PRINTCMD;
- n = (int)strlen(PRINTCMD) + (int)strlen(iattr.disp.val+1) + 4;
- if (tmp = (char *)malloc(n)) {
- sprintf(tmp, /* safe (prechecked) */
- "%s %s", PRINTCMD, iattr.disp.val + 1);
- x = openc(ZOFILE,(char *)tmp);
- free(tmp);
- } else
- x = 0;
- } else
-#endif /* UNIX */
- x = opena(filnam,&iattr); /* open the file, with attributes */
- }
- if (x) { /* If file was opened ok */
- int rc, qf;
-#ifndef NOSPL
- qf = query;
-#else
- qf = 0;
-#endif /* NOSPL */
-
-#ifdef CKTUNING
- rc = (binary && !parity) ?
- bdecode(rdatap,putfil):
- decode(rdatap, qf ? puttrm : putfil, 1);
-#else
- rc = decode(rdatap, qf ? puttrm : putfil, 1);
-#endif /* CKTUNING */
- if (rc < 0) {
- errpkt((CHAR *)"Error writing data");
- RESUME;
- return(-1);
- }
-#ifdef STREAMING
- if (streaming) /* Streaming was negotiated */
- fastack(); /* ACK without ACKing. */
- else
-#endif /* STREAMING */
- ack(); /* acknowledge it */
- BEGIN rdpkt; /* and switch to receive-data state */
- return(-1);
- } else { /* otherwise */
- errpkt((CHAR *) rf_err); /* send error packet */
- RESUME; /* and quit. */
- return(-1);
- }
- }
-}
-
-static int
-rcv_shortreply() {
-#ifdef PKTZEROHACK
- success = 0;
- debug(F111,"rcv_shortreply",rdatap,ipktlen);
- if (ipktack[0] && !strncmp(ipktack,(char *)rdatap,ipktlen)) {
- /* No it's the ACK to the I packet again */
- x = scmd(vcmd,(CHAR *)cmarg); /* So send the REMOTE command again */
- /* Maybe this should be resend() */
- debug(F110,"IPKTZEROHACK",ipktack,x);
- if (x < 0) {
- errpkt((CHAR *)srimsg);
- RESUME;
- return(-1);
- }
- } else {
- ipktack[0] = NUL;
-#endif /* PKTZEROHACK */
- urserver = 1;
-#ifndef NOSERVER
-#ifndef NOSPL
- if (query) { /* If to query, */
- qbufp = querybuf; /* initialize query response buffer */
- qbufn = 0;
- querybuf[0] = NUL;
- }
-#endif /* NOSPL */
- x = 1;
- if (remfile) { /* Response redirected to file */
- rf_err = "Can't open file";
- if (rempipe) /* or pipe */
- x =
-#ifndef NOPUSH
- zxcmd(ZOFILE,remdest) /* Pipe: Start command */
-#else
- 0
-#endif /* NOPUSH */
- ;
- else
- x = opena(remdest,&iattr); /* File: Open with attributes */
- debug(F111,"rcv_shortreply remfile",remdest,x);
- } else {
- x = opent(&iattr); /* "open" the screen */
- }
- if (x) { /* If file was opened ok */
- if (decode(rdatap,
-#ifndef NOSPL
- (query || !remfile) ? puttrm :
-#else
- !remfile ? puttrm :
-#endif /* NOSPL */
- zputfil, 1) < 0) { /* Note: zputfil, not putfil. */
- errpkt((CHAR *)"Error writing data");
- RESUME;
- return(-1);
- } else {
- if (rdatap) /* If we had data */
- if (*rdatap) /* add a line terminator */
- if (remfile) { /* to file */
- zsoutl(ZOFILE,"");
- } else { /* or to screen. */
-#ifndef NOICP
- if (!query || !xcmdsrc)
-#endif /* NOICP */
- if (!(quiet && rcdactive))
- conoll("");
- }
- if (bye_active && network) { /* I sent BYE or REMOTE LOGOUT */
- msleep(500); /* command and got the ACK... */
- bye_active = 0;
- ttclos(0);
- }
- clsof(0);
- if (!epktsent && !epktrcvd) /* If no error packet... */
- success = 1; /* success. */
- RESUME;
- return(-1);
- }
- } else { /* File not opened OK */
- errpkt((CHAR *) rf_err); /* send error message */
- RESUME; /* and quit. */
- return(-1);
- }
-#endif /* NOSERVER */
-#ifdef PKTZEROHACK
- }
-#endif /* PKTZEROHACK */
- debug(F101,"rcv_shortreply fallthru","",success);
- return(-1);
-}
-
-
-static int
-srv_query() {
-#ifndef NOSERVER
-#ifndef NOSPL
- char c;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE QUERY", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE QUERY", (char *)(srvcmd+2), "");
-#endif /* IKSDB */
- c = *(srvcmd+2); /* Q = Query, S = Set */
- if (c == 'Q') { /* Query */
- if (!ENABLED(en_que)) { /* Security */
- errpkt((CHAR *)"REMOTE QUERY disabled");
- RESUME;
- return(-1);
- } else { /* Query allowed */
- int n; char *p, *q;
- qbufp = querybuf; /* Wipe out old stuff */
- qbufn = 0;
- querybuf[0] = NUL;
- p = (char *) srvcmd + 3; /* Pointer for making wrapper */
- n = strlen((char *)srvcmd); /* Position of end */
- c = *(srvcmd+4); /* Which type of variable */
-
- if (*(srvcmd+6) == CMDQ) { /* Starts with command quote? */
- p = (char *) srvcmd + 6; /* Take it literally */
- if (*p == CMDQ) p++;
- } else { /* They played by the rules */
- if (c == 'K') { /* Kermit variable */
- int k;
- k = (int) strlen(p);
- if (k > 0 && p[k-1] == ')') {
- p = (char *)(srvcmd + 4);
- *(srvcmd+4) = CMDQ;
- *(srvcmd+5) = 'f'; /* Function, so make it \f...() */
- } else {
- *(srvcmd+3) = CMDQ; /* Stuff wrapping into buffer */
- *(srvcmd+4) = 'v'; /* Variable, so make it \v(...) */
- *(srvcmd+5) = '('; /* around variable name */
- *(srvcmd+n) = ')';
- *(srvcmd+n+1) = NUL;
- }
- } else {
- *(srvcmd+3) = CMDQ; /* Stuff wrapping into buffer */
- *(srvcmd+4) = 'v'; /* Variable, so make it \v(...) */
- *(srvcmd+5) = '('; /* around variable name */
- *(srvcmd+n) = ')';
- *(srvcmd+n+1) = NUL;
- if (c == 'S') { /* System variable */
- *(srvcmd+4) = '$'; /* so it's \$(...) */
- } else if (c == 'G') { /* Non-\ Global variable */
- *(srvcmd+4) = 'm'; /* so wrap it in \m(...) */
- }
- }
- } /* Now evaluate it */
- n = QBUFL; /* Max length */
- q = querybuf; /* Where to put it */
- if (zzstring(p,&q,&n) < 0) {
- errpkt((n > 0) ? (CHAR *)"Can't get value"
- : (CHAR *)"Value too long"
- );
- RESUME;
- return(-1);
- } else {
- if (encstr((CHAR *)querybuf) > -1) { /* Encode it */
- ack1(data); /* If it fits, send it back in ACK */
- success = 1;
- RESUME;
- return(-1);
- } else if (sndstring(querybuf)) { /* Long form response */
- BEGIN ssinit;
- return(-1);
- } else { /* sndhlp() fails */
- errpkt((CHAR *)"Can't send value");
- RESUME;
- return(-1);
- }
- }
- }
- } else if (c == 'S') { /* Set (assign) */
- if (!ENABLED(en_asg)) { /* Security */
- errpkt((CHAR *)"REMOTE ASSIGN disabled");
- RESUME;
- return(-1);
- } else { /* OK */
- int n;
- n = xunchar(*(srvcmd+3)); /* Length of name */
- n = 3 + n + 1; /* Position of length of value */
- *(srvcmd+n) = NUL; /* Don't need it */
- if (addmac((char *)(srvcmd+4),(char *)(srvcmd+n+1)) < 0)
- errpkt((CHAR *)"REMOTE ASSIGN failed");
- else {
- ack();
- success = 1;
- }
- RESUME;
- return(-1);
- }
- } else {
- errpkt((CHAR *)"Badly formed server command");
- RESUME;
- return(-1);
- }
-#else
- errpkt((CHAR *)"Variable query/set not available");
- RESUME;
- return(-1);
-#endif /* NOSPL */
-#endif /* NOSERVER */
-}
-
-static int
-srv_copy() {
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE COPY", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef ZCOPY
- if (!ENABLED(en_cpy)) {
- errpkt((CHAR *)"REMOTE COPY disabled");
- RESUME;
- return(-1);
- } else {
- char *str1, *str2, f1[256], f2[256];
- int len1, len2;
- len1 = xunchar(srvcmd[1]); /* Separate the parameters */
- len2 = xunchar(srvcmd[2+len1]);
- strncpy(f1,(char *)(srvcmd+2),len1);
- f1[len1] = NUL;
- strncpy(f2,(char *)(srvcmd+3+len1),len2);
- f2[len2] = NUL;
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE COPY", f1, f2);
-#endif /* IKSDB */
- if (!ENABLED(en_cwd)) { /* If CWD is disabled */
- zstrip(f1,&str1); /* and they included a pathname, */
- zstrip(f2,&str2);
- if (strcmp(f1,str1) || strcmp(f2,str2)) { /* Refuse. */
- errpkt((CHAR *)"Access denied");
- RESUME; /* Remember, this is not a goto! */
- return(-1);
- }
- }
- if (state == generic) { /* It's OK to go ahead. */
- if (zcopy(f1,f2)) { /* Try */
- errpkt((CHAR *)"Can't copy file"); /* give error message */
- } else {
- success = 1;
- ack();
- }
- RESUME; /* wait for next server command */
- return(-1);
- }
- }
- return(-1);
-#else /* no ZCOPY */
- errpkt((CHAR *)"REMOTE COPY not available"); /* give error message */
- RESUME; /* wait for next server command */
- return(-1);
-#endif /* ZCOPY */
-#endif /* NOSERVER */
-}
-
-static int
-srv_rename() {
-#ifndef NOSERVER
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE RENAME", (char *)srvcmd);
-#endif /* CKSYSLOG */
-#ifdef ZRENAME
- if (!ENABLED(en_ren)) {
- errpkt((CHAR *)"REMOTE RENAME disabled");
- RESUME;
- return(-1);
- } else { /* RENAME is enabled */
- char *str1, *str2, f1[256], f2[256];
- int len1, len2;
- len1 = xunchar(srvcmd[1]); /* Separate the parameters */
- len2 = xunchar(srvcmd[2+len1]);
- strncpy(f1,(char *)(srvcmd+2),len1);
- f1[len1] = NUL;
- strncpy(f2,(char *)(srvcmd+3+len1),len2);
- f2[len2] = NUL;
- len2 = xunchar(srvcmd[2+len1]);
- strncpy(f1,(char *)(srvcmd+2),len1);
- f1[len1] = NUL;
- strncpy(f2,(char *)(srvcmd+3+len1),len2);
- f2[len2] = NUL;
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE RENAME", f1, f2);
-#endif /* IKSDB */
- if (!ENABLED(en_cwd)) { /* If CWD is disabled */
- zstrip(f1,&str1); /* and they included a pathname, */
- zstrip(f2,&str2);
- if ( strcmp(f1,str1) || strcmp(f2,str2) ) { /* refuse. */
- errpkt((CHAR *)"Access denied");
- RESUME; /* Remember, this is not a goto! */
- return(-1);
- }
- }
- if (state == generic) { /* It's OK to go ahead. */
- if (zrename(f1,f2)) { /* Try */
- errpkt((CHAR *)"Can't rename file"); /* Give error msg */
- } else {
- success = 1;
- ack();
- }
- RESUME; /* Wait for next server command */
- return(-1);
- }
- }
- return(-1);
-#else /* no ZRENAME */
- /* Give error message */
- errpkt((CHAR *)"REMOTE RENAME not available");
- RESUME; /* Wait for next server command */
- return(-1);
-#endif /* ZRENAME */
-#endif /* NOSERVER */
-}
-
-static int
-srv_login() {
-#ifndef NOSERVER
- char f1[LOGINLEN+1], f2[LOGINLEN+1], f3[LOGINLEN+1];
- CHAR *p;
- int len, i;
-
- debug(F101,"REMOTE LOGIN x_login","",x_login);
- debug(F101,"REMOTE LOGIN x_logged","",x_logged);
-
- f1[0] = NUL; f2[0] = NUL; f3[0] = NUL;
- len = 0;
- if (srvcmd[1]) /* First length field */
- len = xunchar(srvcmd[1]); /* Separate the parameters */
-
- if (x_login) { /* Login required */
- if (x_logged) { /* And already logged in */
- if (len > 0) { /* Logging in again */
- errpkt((CHAR *)"Already logged in.");
- } else { /* Logging out */
- debug(F101,"REMOTE LOGOUT","",x_logged);
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE LOGOUT", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"REMOTE LOGOUT", "", "");
-#endif /* IKSDB */
- tlog(F110,"Logged out",x_user,0);
- ack1((CHAR *)"Logged out");
- success = 1;
- msleep(500);
-#ifdef CK_LOGIN
- x_logged = 0;
-#ifdef IKSD
- if (inserver)
- ckxlogout();
-#endif /* IKSD */
-#endif /* CK_LOGIN */
- }
- } else { /* Not logged in yet */
- debug(F101,"REMOTE LOGIN len","",len);
- if (len > 0) { /* Have username */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "REMOTE LOGIN", NULL);
-#endif /* CKSYSLOG */
- if (len > LOGINLEN) {
- errpkt((CHAR *)"Username too long");
- }
- p = srvcmd + 2; /* Point to it */
- for (i = 0; i < len; i++) /* Copy it */
- f1[i] = p[i];
- f1[len] = NUL; /* Terminate it */
- p += len; /* Point to next length field */
- if (*p) { /* If we have one */
- len = xunchar(*p++); /* decode it */
- if (len > 0 && len <= LOGINLEN) {
- for (i = 0; i < len; i++) /* Same deal for password */
- f2[i] = p[i];
- f2[len] = NUL;
- p += len; /* And account */
- if (*p) {
- len = xunchar(*p++);
- if (len > 0 && len <= LOGINLEN) {
- for (i = 0; i < len; i++)
- f3[i] = p[i]; /* Set but never used */
- f3[len] = NUL; /* (because account not used) */
- }
- }
- }
- }
- debug(F101,"REMOTE LOGIN 1","",x_logged);
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver) { /* Log in to system for real */
- x_logged = ckxlogin((CHAR *)f1,(CHAR *)f2,NULL,0);
- debug(F101,"REMOTE LOGIN 2","",x_logged);
- if (x_logged) { /* Count attempts */
- logtries = 0;
- justone = 1;
- } else {
- logtries++;
- sleep(logtries);
- }
- } else
-#endif /* CK_LOGIN */
-#endif /* IKSD */
- if (x_user && x_passwd) { /* User and password must match */
- if (!strcmp(x_user,f1)) /* SET SERVER LOGIN */
- if (!strcmp(x_passwd,f2))
- x_logged = 1;
- debug(F101,"REMOTE LOGIN 3","",x_logged);
- } else if (x_user) { /* Only username given, no password */
- if (!strcmp(x_user,f1)) /* so only username must match */
- x_logged = 1;
- debug(F101,"REMOTE LOGIN 4","",x_logged);
- }
-#ifdef CK_LOGIN
- else {
- x_logged = ckxlogin((CHAR *)f1,(CHAR *)f2,NULL,0);
- debug(F101,"REMOTE LOGIN 5","",x_logged);
- }
-#endif /* CK_LOGIN */
- if (x_logged) { /* Logged in? */
- tlog(F110,"Logged in", x_user, 0);
- if (isguest)
- ack1((CHAR *)"Logged in as guest - restrictions apply");
- else
- ack1((CHAR *)"Logged in");
- success = 1;
- } else {
- tlog(F110,"Login failed", f1, 0);
- errpkt((CHAR *)"Access denied.");
-#ifdef IKSD
-#ifdef CK_LOGIN
- if (inserver && logtries > 2)
- ckxlogout();
-#endif /* CK_LOGIN */
-#endif /* IKSD */
- }
- } else { /* LOGOUT */
- errpkt((CHAR *)"Logout ignored");
- }
- }
- } else { /* Login not required */
- if (len > 0)
- errpkt((CHAR *)"Login ignored.");
- else
- errpkt((CHAR *)"Logout ignored.");
- }
-#endif /* NOSERVER */
- RESUME;
- return(-1);
-}
-
-static int
-srv_timeout() {
- /* K95 does this its own way */
- if (idletmo) {
-#ifdef IKSD
- if (inserver) {
- printf("\r\nIKSD IDLE TIMEOUT: %d sec\r\n", srvidl);
- doexit(GOOD_EXIT,xitsta);
- }
-#endif /* IKSD */
- idletmo = 0;
- printf("\r\nSERVER IDLE TIMEOUT: %d sec\r\n", srvidl);
- xitsta |= (what & W_KERMIT);
- QUIT;
- }
-#ifndef NOSERVER
- else if (fatalio) { /* Connection lost */
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "Connection lost", NULL);
-#endif /* CKSYSLOG */
-#ifdef IKSDB
- if (ikdbopen) slotstate(what,"SERVER DISCONNECT",(char *)srvcmd, "");
-#endif /* IKSDB */
- xitsta |= what;
- QUIT;
- } else if (interrupted) { /* Interrupted by hand */
- if (!ENABLED(en_fin)) {
- errpkt((CHAR *)"QUIT disabled");
- RESUME;
- return(-1);
- } else {
- if (what == W_SEND || what == W_RECV || what == W_REMO) {
- success = 0;
-#ifdef CKSYSLOG
- if (ckxsyslog >= SYSLG_PR && ckxlogging)
- cksyslog(SYSLG_PR, 1, "server", "Interrupted", NULL);
-#endif /* CKSYSLOG */
- } else if (what == W_NOTHING && filcnt == 0) {
- success = 1;
- } /* Otherwise leave success alone */
- xitsta |= (what & W_KERMIT);
- QUIT;
- }
- } else { /* Shouldn't happen */
- debug(F100,"SERVER (top) GOT UNEXPECTED 'q'","",0);
- QUIT;
- }
-#endif /* NOSERVER */
-}
-
-static int
-rcv_s_pkt() {
-#ifndef NOSERVER
- if (state == rgen)
- urserver = 1;
- if (/* state == serve && */ x_login && !x_logged) {
- errpkt((CHAR *)"Login required");
- SERVE;
- } else
-#endif /* NOSERVER */
- if (state == serve && !ENABLED(en_sen)) { /* Not in server mode */
- errpkt((CHAR *)"SEND disabled"); /* when SEND is disabled. */
- RESUME;
- return(-1);
- } else { /* OK to go ahead. */
-#ifdef CK_TMPDIR
- if (dldir && !f_tmpdir) { /* If they have a download directory */
- debug(F110,"receive download dir",dldir,0);
- if (s = zgtdir()) { /* Get current directory */
- debug(F110,"receive current dir",s,0);
- if (zchdir(dldir)) { /* Change to download directory */
- debug(F100,"receive zchdir ok","",0);
- ckstrncpy(savdir,s,TMPDIRLEN);
- f_tmpdir = 1; /* Remember that we did this */
- } else
- debug(F100,"receive zchdir failed","",0);
- }
- }
-#endif /* CK_TMPDIR */
- nakstate = 1; /* Can send NAKs from here. */
- rinit(rdatap); /* Set parameters */
- bctu = bctr; /* Switch to agreed-upon block check */
- bctl = (bctu == 4) ? 2 : bctu; /* Set block-check length */
- what = W_RECV; /* Remember we're receiving */
- lastxfer = W_RECV;
- resetc(); /* Reset counters */
- rtimer(); /* Reset timer */
-#ifdef GFTIMER
- rftimer();
-#endif /* GFTIMER */
- streamon();
- BEGIN rfile; /* Go into receive-file state */
- }
- return(-1);
-}
-
-
-/* END OF ROUTINES MOVED OUT OF STATE MACHINE */
-
-
-/* P R O T O -- Protocol entry function */
-
-static int is_tn = 0; /* It's a Telnet connection */
-
-#ifdef CK_SPEED
-int f_ctlp = 0; /* Control-character prefix table */
-#ifdef COMMENT
-short s_ctlp[256];
-#endif /* COMMENT */
-#endif /* CK_SPEED */
-
-/*
- This is simply a wrapper for the real protocol function just below,
- that saves any items that might be changed automatically by protocol
- negotiations and then restores them upon exit from protocol mode.
-*/
-VOID
-proto() {
- extern int b_save, f_save, c_save, ss_save, slostart, reliable, urclear;
-#ifndef NOCSETS
- extern int fcharset, fcs_save, tcharset, tcs_save;
-#endif /* NOCSETS */
-
-#ifdef PIPESEND
- extern int pipesend;
-#endif /* PIPESEND */
-#ifndef NOLOCAL
-#ifdef OS2
- extern int cursorena[], cursor_save, term_io;
- extern BYTE vmode;
- extern int display_demo;
- int term_io_save;
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifdef TNCODE
- int _u_bin=0, _me_bin = 0;
-#ifdef IKS_OPTION
- int /* _u_start=0, */ _me_start = 0;
-#endif /* IKS_OPTION */
-#endif /* TNCODE */
-#ifdef PATTERNS
- int pa_save;
- int i;
-#endif /* PATTERNS */
- int scan_save;
-
-#ifdef PATTERNS
- pa_save = patterns;
-#endif /* PATTERNS */
- scan_save = filepeek;
-
- myjob = sstate;
-
-#ifdef CK_LOGIN
- if (isguest) { /* If user is anonymous */
- en_pri = 0; /* disable printing */
- en_mai = 0; /* and disable email */
- en_del = 0; /* and file deletion */
- }
-#endif /* CK_LOGIN */
-
-#ifndef NOLOCAL
-#ifdef OS2
- cursor_save = cursorena[vmode];
- cursorena[vmode] = 0;
- term_io_save = term_io;
- term_io = 0;
-#endif /* OS2 */
-#endif /* NOLOCAL */
- b_save = binary; /* SET FILE TYPE */
- f_save = fncnv; /* SET FILE NAMES */
- c_save = bctr;
- p_save = fnspath;
- r_save = recursive;
- s_timint = timint;
- ss_save = slostart;
-#ifndef NOCSETS
- fcs_save = fcharset;
- tcs_save = tcharset;
-#endif /* NOCSETS */
-
-#ifdef COMMENT
-/* Don't do this because then user can never find out what happened. */
-#ifdef CK_SPEED
- for (i = 0; i < 256; i++)
- s_ctlp[i] = ctlp[i];
- f_ctlp = 1;
-#endif /* CK_SPEED */
-#endif /* COMMENT */
- if (reliable == SET_ON)
- slostart = 0;
- is_tn = (!local && sstelnet)
-#ifdef TNCODE
- || (local && network && ttnproto == NP_TELNET)
-#endif /* TNCODE */
- ;
-#ifdef TNCODE
- if (is_tn) {
- if (tn_b_xfer && !(sstelnet || inserver)) {
- /* Save the current state of Telnet Binary */
- _u_bin = TELOPT_U(TELOPT_BINARY);
- _me_bin = TELOPT_ME(TELOPT_BINARY);
-
- /* If either direction is not Binary attempt to negotiate it */
- if (!_u_bin && TELOPT_U_MODE(TELOPT_BINARY) != TN_NG_RF) {
- tn_sopt(DO,TELOPT_BINARY);
- TELOPT_UNANSWERED_DO(TELOPT_BINARY) = 1;
- }
- if (!_me_bin && TELOPT_ME_MODE(TELOPT_BINARY) != TN_NG_RF) {
- tn_sopt(WILL,TELOPT_BINARY);
- TELOPT_UNANSWERED_WILL(TELOPT_BINARY) = 1;
- }
- if (!(_me_bin && _u_bin))
- tn_wait("proto set binary mode");
- }
-#ifdef IKS_OPTION
-#ifdef CK_XYZ
- if (protocol != PROTO_K) { /* Non-Kermit protocol selected */
- if (TELOPT_U(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start) {
- iks_wait(KERMIT_REQ_STOP,0); /* Stop the other Server */
- /* _u_start = 1; */
- }
- if (TELOPT_ME(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
- tn_siks(KERMIT_STOP); /* I'm not servering */
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0;
- _me_start = 1;
- }
- } else
-#endif /* CK_XYZ */
- if (sstate == 'x' || sstate == 'v') { /* Responding to a request */
- if (!inserver && TELOPT_U(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.u_start) {
- iks_wait(KERMIT_REQ_STOP,0); /* Stop the other Server */
- /* _u_start = 1; */
- }
- if (TELOPT_ME(TELOPT_KERMIT) &&
- !TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
- tn_siks(KERMIT_START); /* Send Kermit-Server Start */
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 1;
- }
- } else { /* Initiating a request */
- if (TELOPT_ME(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
- tn_siks(KERMIT_STOP); /* I'm not servering */
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0;
- _me_start = 1;
- }
- if (TELOPT_U(TELOPT_KERMIT) &&
- !TELOPT_SB(TELOPT_KERMIT).kermit.u_start) {
- /* Send Req-Server-Start */
- if (!iks_wait(KERMIT_REQ_START,0)) {
- if (sstate != 's') {
- success = 0; /* Other Kermit refused to serve */
- if (local)
- printf("A Kermit Server is not available\r\n");
- debug(F110,"proto()",
- "A Kermit Server is not available",0);
- tlog(F110,"IKS client/server failure",
- "A Kermit Server is not available",0);
- goto xxprotox;
- }
- }
- }
- }
-#endif /* IKS_OPTION */
-#ifdef CK_ENCRYPTION
- if (tn_no_encrypt_xfer && !(sstelnet || inserver)) {
- ck_tn_enc_stop();
- }
-#endif /* CK_ENCRYPTION */
- }
-#endif /* TNCODE */
-
- if (!xfrint) connoi();
- xxproto(); /* Call the real protocol function */
-
-#ifdef IKS_OPTION
- xxprotox:
-#endif /* IKS_OPTION */
- xferstat = success; /* Remember transfer status */
- kactive = 0;
-
-#ifdef TNCODE
-#ifdef CK_ENCRYPTION
- if (tn_no_encrypt_xfer && !(sstelnet || inserver)) {
- ck_tn_enc_start();
- }
-#endif /* CK_ENCRYPTION */
-#ifdef IKS_OPTION
- if (TELOPT_ME(TELOPT_KERMIT) &&
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start && !_me_start) {
- tn_siks(KERMIT_STOP); /* Server is stopped */
- TELOPT_SB(TELOPT_KERMIT).kermit.me_start = 0;
- }
-#endif /* IKS_OPTION */
- if (is_tn && tn_b_xfer && !(sstelnet || inserver)) {
- /* if we negotiated Binary mode try to reset it */
- if (!_u_bin) {
- /* Check to see if the state changed during the transfer */
- if (TELOPT_U(TELOPT_BINARY)) {
- tn_sopt(DONT,TELOPT_BINARY);
- TELOPT_UNANSWERED_DONT(TELOPT_BINARY) = 1;
- } else
- _u_bin = 1; /* So we don't call tn_wait() */
- }
- if (!_me_bin) {
- /* Check to see if the state changed during the transfer */
- if (TELOPT_ME(TELOPT_BINARY)) {
- tn_sopt(WONT,TELOPT_BINARY);
- TELOPT_UNANSWERED_WONT(TELOPT_BINARY) = 1;
- } else
- _me_bin = 1; /* So we don't call tn_wait() */
- }
- if (!(_me_bin && _u_bin))
- tn_wait("proto reset binary mode");
- }
-#endif /* TNCODE */
-
-#ifdef PATTERNS
- patterns = pa_save;
-#endif /* PATTERNS */
- filepeek = scan_save;
-
-#ifdef STREAMING
- streaming = 0;
- /* streamok = 0; */
-#endif /* STREAMING */
-#ifdef COMMENT
-#ifdef CK_SPEED
- for (i = 0; i < 256; i++)
- ctlp[i] = s_ctlp[i];
- f_ctlp = 0;
-#endif /* CK_SPEED */
-#endif /* COMMENT */
- urclear = 0;
- if (!success) {
- xitsta |= (what & W_KERMIT);
- tlog(F110," failed:",(char *)epktmsg,0);
- }
- debug(F111,"proto xferstat",epktmsg,xferstat);
- slostart = ss_save;
- if (s_timint > -1) { /* Because of REMOTE SET */
- timint = s_timint;
- s_timint = -1;
- }
- recursive = r_save;
- fnspath = p_save;
- if (c_save > -1) { /* Because of REMOTE SET */
- bctr = c_save;
- c_save = -1;
- }
- fncnv = f_save;
- binary = b_save;
-#ifdef PIPESEND
- pipesend = 0; /* Next time might not be pipesend */
-#endif /* PIPESEND */
-#ifndef NOLOCAL
-#ifdef OS2
- cursorena[vmode] = cursor_save;
- term_io = term_io_save;
- display_demo = 1;
-#endif /* OS2 */
-#endif /* NOLOCAL */
-}
-
-static VOID
-xxproto() {
- int x;
- long lx;
-#ifdef CK_XYZ
-#ifdef XYZ_INTERNAL
-_PROTOTYP( int pxyz, (int) );
-#endif /* XYZ_INTERNAL */
-#endif /* CK_XYZ */
-
- char xss[2]; /* String representation of sstate */
- xss[0] = sstate;
- xss[1] = NUL;
- s_timint = timint;
-
- debug(F101,"xxproto entry justone","",justone);
- success = 0;
-
- retrieve = 0; /* Reset these ... */
- reget = 0;
- opkt = 0;
-
- if (local && ttchk() < 0) { /* Giving BYE or FIN */
- if (bye_active) { /* but there is no connection */
- ttclos(0);
- success = 1;
- return;
- }
- /* Ditto for any REMOTE command */
- if (sstate == 'g' && cmarg ) {
- if (*cmarg == 'L' || *cmarg == 'F' || *cmarg == 'X')
- success = 1;
- else
- printf("?No connection\r\n");
- return;
- }
- }
-
-/* Set up the communication line for file transfer. */
-/* NOTE: All of the xxscreen() calls prior to the wart() invocation */
-/* could just as easily be printf's or, for that matter, hints. */
-
- if (local && (speed < 0L) && (network == 0)) {
- xxscreen(SCR_EM,0,0L,"Sorry, you must 'set speed' first");
- return;
- }
- x = -1;
- if (ttopen(ttname,&x,mdmtyp,cdtimo) < 0) {
- debug(F111,"failed: proto ttopen local",ttname,local);
- xxscreen(SCR_EM,0,0L,"Can't open line");
- return;
- }
- if (x > -1) local = x;
- debug(F111,"proto ttopen local",ttname,local);
-
- lx = (local && !network) ? speed : -1;
-#ifdef NETCONN
-#ifdef CK_SPEED
- if (is_tn) {
- ctlp[(unsigned)255] = ctlp[CR] = 1;
- if (parity == 'e' || parity == 'm') ctlp[127] = 1;
- if (flow == FLO_XONX) { /* Also watch out for Xon/Xoff */
- ctlp[17] = ctlp[19] = 1;
- ctlp[17+128] = ctlp[19+128] = 1;
- }
- }
-#endif /* CK_SPEED */
-#endif /* NETCONN */
- if (ttpkt(lx,flow,parity) < 0) { /* Put line in packet mode, */
- xxscreen(SCR_EM,0,0L,"Can't condition line");
- return;
- }
- if (local && !network && carrier != CAR_OFF) {
- int x; /* Serial connection */
- x = ttgmdm(); /* with carrier checking */
- if (x > -1) {
- if (!(x & BM_DCD)) {
- debug(F101,"proto ttgmdm","",0);
- xxscreen(SCR_EM,0,0L,"Carrier required but not detected");
- return;
- }
- }
- }
- /* Send remote side's "receive" or "server" startup string, if any */
- if (local && ckindex((char *)xss,"srgcjhk",0,0,1)) {
- char *s = NULL;
- if (
-#ifdef IKS_OPTION
- /* Don't send auto-blah string if we know other side is serving */
- !TELOPT_U(TELOPT_KERMIT) ||
- !TELOPT_SB(TELOPT_KERMIT).kermit.u_start
-#else
- 1
-#endif /* IKS_OPTION */
- ) {
- if (sstate == 's') { /* Sending file(s) */
- s = binary ? ptab[protocol].h_b_init : ptab[protocol].h_t_init;
- } else if (protocol == PROTO_K) { /* Command for server */
- s = ptab[protocol].h_x_init;
- }
- }
-#ifdef CK_SPEED
-#ifndef UNPREFIXZERO
- if (protocol == PROTO_K) /* Because of C-strings... */
- ctlp[0] = 1;
-#endif /* UNPREFIXZERO */
-#endif /* CK_SPEED */
- if (s) if (*s) { /* If we have a command to send... */
- char tmpbuf[356];
- int tmpbufsiz = 356;
- int stuff = -1, stuff2 = -1, len = 0;
- extern int tnlm;
- if (sstate == 's') { /* Sending file(s) */
-#ifdef CK_XYZ
- if (protocol == PROTO_X) {
- char * s2;
- s2 = cmarg2[0] ? cmarg2 : cmarg;
- if ((int)strlen(s) + (int)strlen(s2) + 4 < 356)
- sprintf(tmpbuf, s, s2);
- else
- tmpbuf[0] = NUL;
- } else {
-#endif /* CK_XYZ */
- ckmakmsg(tmpbuf, 356, s, NULL, NULL, NULL);
-#ifdef CK_XYZ
- }
-#endif /* CK_XYZ */
- } else { /* Command for server */
- ckstrncpy(tmpbuf,s,356);
- }
- ckstrncat(tmpbuf, "\015",sizeof(tmpbuf));
- if (tnlm) /* TERMINAL NEWLINE ON */
- stuff = LF; /* Stuff LF */
-#ifdef TNCODE
- /* TELNET NEWLINE MODE */
- if (is_tn) {
- switch (TELOPT_ME(TELOPT_BINARY) ? tn_b_nlm : tn_nlm) {
- case TNL_CR:
- break;
- case TNL_CRNUL:
- break;
- case TNL_CRLF:
- stuff2 = stuff;
- stuff = LF;
- break;
- }
- }
-#endif /* TNCODE */
-
-#ifdef NETCONN
-#ifdef TCPSOCKET
-#ifdef RLOGCODE
- if (network && ttnproto == NP_RLOGIN) {
- switch (tn_b_nlm) { /* Always BINARY */
- case TNL_CR:
- break;
- case TNL_CRNUL:
- stuff2 = stuff;
- stuff = NUL;
- break;
- case TNL_CRLF:
- stuff2 = stuff;
- stuff = LF;
- break;
- }
- }
-#endif /* RLOGCODE */
-#endif /* TCPSOCKET */
-#endif /* NETCONN */
-
- len = strlen(tmpbuf);
- if (stuff >= 0 && len < tmpbufsiz - 1) {
- tmpbuf[len++] = stuff;
- if (stuff2 >= 0 && len < tmpbufsiz - 1)
- tmpbuf[len++] = stuff2;
- tmpbuf[len] = NUL;
- }
- ttol((CHAR *)tmpbuf,len);
- if (protocol == PROTO_K) /* Give remote Kermit time to start */
- msleep(400);
- }
- }
-
-#ifdef CK_XYZ
- if (protocol != PROTO_K) { /* Non-Kermit protocol selected */
- char tmpbuf[356];
- int tmpbufsiz = 356;
- char * s = "";
-
-#ifdef CK_TMPDIR
- if (sstate == 'v') { /* If receiving and... */
- if (dldir && !f_tmpdir) { /* if they have a download directory */
- if (s = zgtdir()) { /* Get current directory */
- if (zchdir(dldir)) { /* Change to download directory */
- ckstrncpy(savdir,s,TMPDIRLEN);
- f_tmpdir = 1; /* Remember that we did this */
- }
- }
- }
- }
-#endif /* CK_TMPDIR */
-
-#ifdef XYZ_INTERNAL /* Internal */
- success = !pxyz(sstate);
-#else
-#ifdef CK_REDIR /* External */
- switch (sstate) {
- case 's': /* 'Tis better to SEND... */
- s = binary ? ptab[protocol].p_b_scmd : ptab[protocol].p_t_scmd;
- break;
- case 'v': /* ... than RECEIVE */
- s = binary ? ptab[protocol].p_b_rcmd : ptab[protocol].p_t_rcmd;
- break;
- }
- if (!s) s = "";
- if (*s) {
- if (sstate == 's') {
- if ((int)strlen(s) + (int)strlen(fspec) < tmpbufsiz) {
- sprintf(tmpbuf,s,fspec); /* safe (prechecked) */
- tlog(F110,"Sending",fspec,0L);
- }
- } else {
- if ((int)strlen(s) + (int)strlen(cmarg2) < tmpbufsiz) {
- sprintf(tmpbuf,s,cmarg2); /* safe (prechecked) */
- tlog(F110,"Receiving",cmarg2,0L);
- }
- }
- tlog(F110," via external protocol:",tmpbuf,0);
- debug(F110,"ckcpro ttruncmd",tmpbuf,0);
- success = ttruncmd(tmpbuf);
- tlog(F110," status:",success ? "OK" : "FAILED", 0);
- } else {
- printf("?Sorry, no external protocol defined for %s\r\n",
- ptab[protocol].p_name
- );
- }
-#else
- printf(
-"Sorry, only Kermit protocol is supported in this version of Kermit\n"
- );
-#endif /* CK_REDIR */
-#endif /* XYZ_INTERNAL */
- return;
- }
-#endif /* CK_XYZ */
-
-#ifdef NTSIGX
- conraw();
- connoi();
-#else
- if (!local)
- connoi(); /* No console interrupts if remote */
-#endif /* NTSIG */
-
- kactive = 1;
- if (sstate == 'x') { /* If entering server mode, */
- extern int howcalled;
- server = 1; /* set flag, */
- debug(F101,"server backgrd","",backgrd);
- debug(F101,"server quiet","",quiet);
- debug(F100,"SHOULD NOT SEE THIS IF IN BACKGROUND!","",0);
- if (howcalled == I_AM_SSHSUB) { /* and issue appropriate message. */
- ttol((CHAR *)"KERMIT READY TO SERVE...\015\012",26);
- } else if (!local) {
- if (!quiet && !backgrd
-#ifdef IKS_OPTION
- && !TELOPT_ME(TELOPT_KERMIT) /* User was told by negotiation */
-#endif /* IKS_OPTION */
- ) {
- conoll(srvtxt);
- conoll("KERMIT READY TO SERVE...");
- }
- } else {
- conol("Entering server mode on ");
- conoll(ttname);
- conoll("Type Ctrl-C to quit.");
- if (srvdis) intmsg(-1L);
-#ifdef TCPSOCKET
-#ifndef NOLISTEN
- if (network && tcpsrfd > 0)
- ttol((CHAR *)"KERMIT READY TO SERVE...\015\012",26);
-#endif /* NOLISTEN */
-#endif /* TCPSOCKET */
- }
- } else
- server = 0;
-#ifdef VMS
- if (!quiet && !backgrd) /* So message doesn't overwrite prompt */
- conoll("");
- if (local) conres(); /* So Ctrl-C will work */
-#endif /* VMS */
-/*
- If in remote mode, not shushed, not in background, and at top command level,
- issue a helpful message telling what to do...
-*/
- if (!local && !quiet && !backgrd) {
- if (sstate == 'v') {
- conoll("Return to your local Kermit and give a SEND command.");
- conoll("");
- conoll("KERMIT READY TO RECEIVE...");
- } else if (sstate == 's') {
- conoll("Return to your local Kermit and give a RECEIVE command.");
- conoll("");
- conoll("KERMIT READY TO SEND...");
- } else if ( sstate == 'g' || sstate == 'r' || sstate == 'h' ||
- sstate == 'j' || sstate == 'c' ) {
- conoll("Return to your local Kermit and give a SERVER command.");
- conoll("");
- conoll((sstate == 'r' || sstate == 'j' || sstate == 'h') ?
- "KERMIT READY TO GET..." :
- "KERMIT READY TO SEND SERVER COMMAND...");
- }
- }
-#ifdef COMMENT
- if (!local) sleep(1);
-#endif /* COMMENT */
-/*
- The 'wart()' function is generated by the wart program. It gets a
- character from the input() routine and then based on that character and
- the current state, selects the appropriate action, according to the state
- table above, which is transformed by the wart program into a big case
- statement. The function is active for one transaction.
-*/
- rtimer(); /* Reset elapsed-time timer */
-#ifdef GFTIMER
- rftimer();
-#endif /* GFTIMER */
- resetc(); /* & other per-transaction counters. */
-
- debug(F101,"proto calling wart, justone","",justone);
-
- wart(); /* Enter the state table switcher. */
-/*
- Note: the following is necessary in case we have just done a remote-mode
- file transfer, in which case the controlling terminal modes have been
- changed by ttpkt(). In particular, special characters like Ctrl-C and
- Ctrl-\ might have been turned off (see ttpkt). So this call to ttres() is
- essential. IMPORTANT: restore interrupt handlers first, otherwise any
- terminal interrupts that occur before this is done in the normal place
- later will cause a crash.
-*/
-#ifdef OS2
- ttres(); /* Reset the communication device */
-#else
- if (!local) {
- setint(); /* Arm interrupt handlers FIRST */
- msleep(500);
- ttres(); /* Then restore terminal. */
- }
-#endif /* OS2 */
- xxscreen(SCR_TC,0,0L,""); /* Transaction complete */
- x = quiet;
- quiet=1;
- clsif(); /* Failsafe in case we missed */
- clsof(1); /* a case in the state machine. */
- quiet = x;
-
- if (server) { /* Back from packet protocol. */
- if (!quiet && !backgrd
-#ifdef IKSD
- && !inserver
-#endif /* IKSD */
- ) { /* Give appropriate message */
- conoll("");
- conoll("C-Kermit server done");
- }
- server = 0; /* Not a server any more */
- }
-}
-
-/* S G E T I N I T -- Handle incoming GET-Class packets */
-
-/*
- Returns:
- -1: On error
- 0: GET packet processed OK - ready to Send.
- 1: Extended GET processed OK - wait for another.
-*/
-static int
-sgetinit(reget,xget) int reget, xget; { /* Server end of GET command */
- char * fs = NULL; /* Pointer to filespec */
- int i, n, done = 0;
-#ifdef PIPESEND
- extern int usepipes, pipesend;
-#endif /* PIPESEND */
- extern int nolinks;
-
- if (!ENABLED(en_get)) { /* Only if not disabled! */
- errpkt((CHAR *)"GET disabled");
- return(-1);
- }
-
- /* OK to proceed */
-
- nolinks = recursive;
- filcnt = 0;
-
-#ifdef WHATAMI
- /* If they are alike this was already done in whoarewe() */
- debug(F101,"sgetinit whatru","",whatru);
- if (whatru & WMI_FLAG) { /* Did we get WHATAMI info? */
- debug(F101,"sgetinit binary (1)","",binary);
-#ifdef VMS
- if (binary != XYFT_I && binary != XYFT_L)
-#else
-#ifdef OS2
- if (binary != XYFT_L)
-#endif /* OS2 */
-#endif /* VMS */
- binary = (whatru & WMI_FMODE) ? /* Yes, set file type */
- XYFT_B : XYFT_T; /* automatically */
- debug(F101,"sgetinit binary (2)","",binary);
- if (!wearealike)
- fncnv = (whatru & WMI_FNAME) ? 1 : 0; /* And name conversion */
- }
-#endif /* WHATAMI */
-
- fs = (char *)srvcmd;
- srvptr = srvcmd; /* Point to server command buffer */
- decode(rdatap,putsrv,0); /* Decode the GET command into it */
- /* Accept multiple filespecs */
- cmarg2 = ""; /* Don't use cmarg2 */
- cmarg = ""; /* Don't use cmarg */
-
- done = 1; /* Only 1 packet needed... */
- if (xget) { /* Special decoding for Extended GET */
- char L, next, c; /* PLV items */
- int len, val; /* More PLV items */
- char * p = (char *)srvcmd; /* String to decode */
-
- done = 0; /* Maybe more packets needed */
- fs = NULL; /* We don't know the filespec yet */
- c = *p++; /* Get first parameter */
-
- while (c) { /* For all parameters... */
- debug(F000,"sgetinit c","",c);
- L = *p++; /* Get length */
- if (L >= SP) /* Decode length */
- len = xunchar(L);
- else if (c == '@') { /* Allow missing EOP length field */
- len = 0;
- } else {
- len = (xunchar(*p++) * 95);
- len += xunchar(*p++);
- }
- debug(F101,"sgetinit len","",len);
- next = *(p+len); /* Get next parameter */
- *(p+len) = NUL; /* Zero it out to terminal value */
- debug(F110,"sgetinit p",p,0);
- switch (c) { /* Do the parameter */
- case 'O': /* GET Options */
- val = atoi(p); /* Convert to int */
- debug(F101,"sgetinit O val","",val);
- if (val & GOPT_DEL) moving = 1;
- if (val & GOPT_RES) reget = 1;
- if (val & GOPT_REC) {
- recursive = 1;
- nolinks = 2;
- if (fnspath == PATH_OFF)
- fnspath = PATH_REL;
- }
- break;
- case 'M': /* Transfer Mode */
- val = atoi(p);
- debug(F101,"sgetinit M val","",val);
- if (val < 1)
- break;
- patterns = 0; /* Takes precedence over patterns */
- filepeek = 0; /* and FILE SCAN */
- if (val == GMOD_TXT) binary = XYFT_T; /* Text */
- if (val == GMOD_BIN) binary = XYFT_B; /* Binary */
- if (val == GMOD_LBL) binary = XYFT_L; /* Labeled */
- break;
- case 'F': /* Filename */
- fs = p;
- debug(F110,"sgetinit filename",fs,0);
- break;
- case '@': /* End Of Parameters */
- done = 1;
- debug(F100,"sgetinit EOP","",0);
- break;
- default:
- errpkt((CHAR *)"Unknown GET Parameter");
- debug(F100,"sgetinit unknown parameter","",0);
- return(-1);
- }
- p += (len + 1);
- c = next;
- }
- }
- if (!fs) fs = ""; /* A filename is required */
- if (*fs) {
- havefs = 1;
- n = 0; /* Check for quoted name */
- if ((n = strlen(fs)) > 1) {
- /* Note: this does not allow for multiple quoted names */
- if ((fs[0] == '{' && fs[n-1] == '}') ||
- (fs[0] == '"' && fs[n-1] == '"')) {
- fs[n-1] = '\0';
- fs++;
- debug(F111,"sgetinit unquoted filename",fs,n);
- } else
- n = 0; /* This means no quoting */
- }
-
-#ifdef PIPESEND
- debug(F111,"sgetinit",fs,usepipes);
- if (usepipes && ENABLED(en_hos) && *fs == '!') {
- cmarg = fs + 1; /* Point past the bang */
- *fs = NUL;
- nfils = -1;
- pipesend = 1;
- debug(F111,"sgetinit pipesend",cmarg,pipesend);
- }
- if (!pipesend) { /* If it's not a pipe */
-#endif /* PIPESEND */
- if (n == 0) { /* If the name was not quoted */
-#ifndef NOMSEND
- nfils = fnparse(fs); /* Allow it to be a list of names */
- debug(F111,"sgetinit A",fs,nfils);
-#ifdef COMMENT
-/* This doesn't work if a GET-PATH is set. */
- if (nfils == 1 && !iswild(fs)) { /* Single file */
- char * m;
- if ((x = zchki(fs)) < 0) { /* Check if it's sendable */
- switch (x) {
- case -1: m = "File not found"; break;
- case -2: m = "Not a regular file"; break;
- case -3: m = "Read access denied"; break;
- }
- errpkt((CHAR *)m);
- return(-1);
- }
- }
-#endif /* COMMENT */
- } else { /* If it was quoted */
-#endif /* NOMSEND */
- nzxopts = 0;
-#ifdef UNIXOROSK
- if (matchdot) nzxopts |= ZX_MATCHDOT;
-#endif /* UNIXOROSK */
- if (recursive) nzxopts |= ZX_RECURSE;
- /* Treat as a single filespec */
- nfils = 0 - nzxpand(fs,nzxopts);
- debug(F111,"sgetinit B",fs,nfils);
- cmarg = fs;
- }
-#ifdef PIPESEND
- }
-#endif /* PIPESEND */
- }
- if (!done) { /* Need more O packets... */
- debug(F100,"sgetinit O-Packet TBC","",0); /* To Be Continued */
- return(1);
- }
- debug(F100,"sgetinit O-Packet done - havefs","",havefs);
- if (!havefs) { /* Done - make sure we have filename */
- errpkt((CHAR *)"GET without filename");
- return(-1);
- }
- freerpkt(winlo);
- winlo = 0; /* Back to packet 0 again. */
- debug(F101,"sgetinit winlo","",winlo);
- nakstate = 0; /* Now I'm the sender! */
- if (reget) sendmode = SM_RESEND;
- if (sinit() > 0) { /* Send Send-Init */
-#ifdef STREAMING
- if (!streaming)
-#endif /* STREAMING */
- timint = chktimo(rtimo,timef); /* Switch to per-packet timer */
- return(0); /* If successful, switch state */
- } else return(-1); /* Else back to server command wait */
-}
-
-#else /* NOXFER */
-
-#include "ckcdeb.h"
-
-VOID
-proto() {
- extern int success;
- success = 0;
-}
-#endif /* NOXFER */
+++ /dev/null
-
- C-Kermit 8.0 Update Notes
-
- [ [1]Contents ] [ [2]C-Kermit ] [ [3]Kermit Home ]
-
- Second Supplement to Using C-Kermit, Second Edition
-
-For C-Kermit 8.0
-
- As of C-Kermit version: 8.0.211
- Date of C-Kermit release: 10 April 2003
- This file last updated: Sat Apr 10 16:36:11 2004
-
- * IF YOU ARE READING A PLAIN-TEXT version of this document, note
- that it is a plain-text dump of a Web page. You can visit the
- original (and possibly more up-to-date) Web page here:
- [4]http://www.columbia.edu/kermit/ckermit80.html
- * If you are reading the HTML version of this file with a GUI Web
- browser, the features added since C-Kermit 8.0.201 are shown in
- red if your browser and monitor permit. Features that were new to
- versions 8.0.200 and 201 are in black.
-
-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: [5]kermit-support@columbia.edu
-Web: [6]http://www.columbia.edu/kermit/
-Or: [7]http://www.kermit-project.org/
-Or: [8]http://www.columbia.nyc.ny.us/kermit/
- _________________________________________________________________
-
- NOTICES
-
- This document:
- Copyright © 1997, 2002, Frank da Cruz and Christine M. Gianone.
- All rights reserved.
-
- Kermit 95:
- Copyright © 1995, 2002, Trustees of Columbia University in the
- City of New York. All rights reserved.
-
- C-Kermit:
- Copyright © 1985, 2002,
- Trustees of Columbia University in the City of New York. All
- rights reserved. See the C-Kermit [9]COPYING.TXT file or the
- copyright text in the [10]ckcmai.c module for disclaimer and
- permissions.
-
- When Kerberos(TM) and/or SRP(TM) (Secure Remote Password) and/or
- SSL/TLS protocol are included:
- Portions Copyright © 1990, Massachusetts Institute of
- Technology.
- Portions Copyright © 1991, 1993 Regents of the University of
- California.
- Portions Copyright © 1991, 1992, 1993, 1994, 1995 by AT&T.
- Portions Copyright © 1997, Stanford University.
- Portions Copyright © 1995-1997, Eric Young
- <eay@cryptosoft.com>.
-
- For the full text of the third-party copyright notices, see
- [11]Appendix V.
- _________________________________________________________________
-
- WHAT IS IN THIS FILE
-
- This file lists changes made to C-Kermit since version 7.0 was
- released in January 2000. Use this file as a supplement to:
-
- * The second edition of [12]Using C-Kermit; and:
- * The [13]C-Kermit 7.0 Update Notes. Also available in plain-text
- form as [14]ckermit70.txt.
-
- until the third edition of Using C-Kermit is published. We apologize
- for the scattered documentation and will consolidate it when we are
- able.
- _________________________________________________________________
-
- ADDITIONAL FILES Several other files accompany this new Kermit
- release:
-
- [15]ckututor.html
- C-Kermit Tutorial (for Unix). Also distributed in Nroff form as
- [16]ckuker.nr, the Unix C-Kermit manual page.
-
- [17]security.htm
- Discussion of Kermit's new authentication and encryption
- features, updated for C-Kermit 8.0.
-
- [18]telnet.htm
- Detailed documentation of Kermit's Telnet client, updated for
- C-Kermit 8.0.
-
- [19]ftpscripts.html
- Tutorial: Writing FTP automation scripts
-
- [20]ckcbwr.html
- Platform-independent C-Kermit hints and tips. Also distributed
- in plain text form as [21]ckcbwr.txt
-
- [22]ckubwr.html
- Unix-specific C-Kermit hints and tips. Also distributed in
- plain text form as [23]ckubwr.txt.
-
- [24]ckvbwr.html
- VMS-specific C-Kermit hints and tips. Also distributed in plain
- text form as [25]ckvbwr.txt.
-
- [26]ckuins.html
- Unix C-Kermit installation instructions. Also distributed in
- plain text form as [27]ckuins.txt.
-
- [28]ckvins.html
- VMS C-Kermit installation instructions. Also distributed in
- plain text form as [29]ckvins.txt.
-
- [30]ckccfg.html
- Compile-time configuration options. Also distributed in plain
- text form as [31]ckccfg.txt.
-
- [32]ckcplm.html
- C-Kermit Program Logic Manual. Also distributed in plain text
- form as [33]ckcplm.txt.
-
- [34]iksd.html
- Internet Kermit Service Aministrators Guide for Unix.
-
- [35]skermit.html
- C-Kermit as an SSH Subsystem (SFTP server replacement).
-
- [ [36]Top ] [ [37]C-Kermit ] [ [38]Kermit Home ]
- __________________________________________________________________________
-
-CONTENTS
-
- [39]0. WHAT'S NEW
- [40]1. FIXES SINCE VERSION 7.0.196
- [41]2. SSH AND HTTP
- [42]2.1. SSH Connections
- [43]2.2. HTTP Connections
- [44]2.2.1. HTTP Command Switches
- [45]2.2.2. HTTP Action Commands
- [46]2.2.3. HTTP Headers
- [47]2.2.4. Secure HTTP Connections
- [48]2.2.5. HTTP Variables
- [49]2.2.6. The HTTP Command-Line Personality
- [50]3. THE BUILT-IN FTP CLIENT
- [51]3.1. Making and Managing FTP Connections
- [52]3.1.1. Kermit Command-Line Options for FTP
- [53]3.1.2. The FTP Command-Line Personality
- [54]3.1.3. The FTP URL Interpreter
- [55]3.1.4. Interactive FTP Session Establishment
- [56]3.2. Making Secure FTP Connections
- [57]3.3. Setting FTP Preferences
- [58]3.4. Managing Directories and Files
- [59]3.5. Uploading Files With FTP
- [60]3.5.1. FTP PUT Switches
- [61]3.5.2. Update Mode
- [62]3.5.3. Recovery
- [63]3.6. Downloading Files With FTP
- [64]3.6.1. FTP GET Switches
- [65]3.6.2. Filename Collisions
- [66]3.6.3. Recovery
- [67]3.7. Translating Character Sets
- [68]3.7.1. Character Sets and Uploading
- [69]3.7.2. Character Sets and Downloading
- [70]3.8. FTP Command Shortcuts
- [71]3.9. Dual Sessions
- [72]3.10. Automating FTP Sessions
- [73]3.10.1. FTP-Specific Variables and Functions
- [74]3.10.2. Examples
- [75]3.10.3. Automating Secure FTP Connections
- [76]3.11. Advanced FTP Protocol Features [77]4. FILE SCANNING
- [78]5. FILE AND DIRECTORY NAMES CONTAINING SPACES
- [79]6. OTHER COMMAND PARSING IMPROVEMENTS
- [80]6.1. Grouping Macro Arguments
- [81]6.2. Directory and File Name Completion
- [82]6.3. Passing Arguments to Command Files
- [83]6.4. More-Prompting
- [84]6.5. Commas in Macro Definitions
- [85]6.6. Arrow Keys
- [86]7. NEW COMMANDS AND SWITCHES
- [87]8. SCRIPTING IMPROVEMENTS
- [88]8.1. Performance and Debugging
- [89]8.2. Using Macros as Numeric Variables
- [90]8.3. New IF Conditions
- [91]8.4. The ON_UNKNOWN_COMMAND and ON_CD Macros
- [92]8.5. The SHOW MACRO Command
- [93]8.6. Arrays
- [94]8.7. New or Improved Built-in Variables and Functions
- [95]8.8. The RETURN and END Commands
- [96]8.9. UNDEFINing Groups of Variables
- [97]8.10. The INPUT and MINPUT Commands
- [98]8.11. Learned Scripts
- [99]8.12. Pattern Matching
- [100]8.13. Dates and Times
- [101]8.14. Trapping Keyboard Interruption
- [102]9. S-EXPRESSIONS
- [103]9.1. What is an S-Expression?
- [104]9.2. Integer and Floating-Point-Arithmetic
- [105]9.3. How to Use S-Expressions
- [106]9.4. Summary of Built-in Constants and Operators
- [107]9.5. Variables
- [108]9.6. Assignments and Scope
- [109]9.7. Conditional Expressions
- [110]9.8. Extensibility
- [111]9.9. Examples
- [112]9.10. Differences from Algebraic Notation
- [113]9.11.Differences from Lisp
- [114]10. FILE TRANSFER
- [115]11. MODEMS AND DIALING
- [116]12. TERMINAL CONNECTION
- [117]13. CHARACTER SETS
- [118]14. DIALOUT FROM TELNET TERMINAL SERVERS
- [119]15. COPING WITH BROKEN KERMIT PARTNERS
- [120]16. NEW COMMAND-LINE OPTIONS
- [121]17. LOGS
-
- [ [122]Top ] [ [123]C-Kermit ] [ [124]Kermit Home ]
- __________________________________________________________________________
-
-0. WHAT'S NEW
-
- The Initialization and Customization Files
- C-Kermit 8.0 now supports specification of the initialization
- file name (path) in an environment variable, CKERMIT_INI. It
- also relies far less than before on the initialization for
- functioning. See [125]Section 5 of the Unix C-Kermit
- [126]installation instructions for details. As of version
- 8.0.201, C-Kermit also executes your customization file (if you
- have one) even if the initialization file was not found.
- Previously, the customization file was executed by a TAKE
- command in the initialization file (and it still is, if an
- initialization is found).
-
- Incompatible Changes
- As always, we do our best to avoid changes that break existing
- scripts. However, C-Kermit 8.0 does include a rather pervasive
- syntax change that might alter the behavior of scripts that
- depend on the previous behavior. As described in [127]Section
- 5, C-Kermit now accepts doublequotes in most contexts where you
- previously had to use braces to group multiple words into a
- single field, or to force inclusion of leading or trailing
- blanks. Most noticeably, in C-Kermit 7.0 and earlier:
-
- echo {this is a string}
-
- would print:
-
- this is a string
-
- whereas:
-
- echo "this is a string"
-
- printed:
-
- "this is a string"
-
- In C-Kermit 8.0, both print:
-
- this is a string
-
- To force the doublequotes to be treated as part of the string,
- use either of the following forms:
-
- echo {"this is a string"}
- echo ""this is a string""
-
- Similarly, to force braces to be treated as part of the string:
-
- echo "{this is a string}"
- echo {{this is a string}}
-
- Other incompatibilities:
-
- 1. Using the SET HOST command to make HTTP connections is no
- longer supported. Instead, use the new HTTP OPEN command,
- described in [128]Section 2.2.
-
- C-Kermit 7.1 Alpha.01 (8 December 2000)
-
- Its major new features are those listed in the [129]Table of
- Contents: the FTP client, file scanning, command parsing and
- scripting improvements, S-Expressions, and support for the
- Telnet Com Port Option, plus wider availability of the
- Kerberos, SSL/TLS, and SRP security options for secure Internet
- connections.
-
- C-Kermit 7.1.199 Alpha.02 (4 January 2001)
-
- + C-Kermit now accepts [130]FTP, TELNET, and IKSD URLs as its
- first command-line argument.
- + Character-set translation added to the FTP client for
- [131]filenames.
- + Optional [132]setting of date of incoming files by FTP [M]GET
- from the server date.
- + [133]FTP CHECK filename added to let FTP client check the
- existence of a file on the server.
- + [134]FTP GET /NAMELIST:filename added to get list of server
- filenames into a local file.
- + [135]FTP [M]PUT /SERVER-RENAME:template added to make server
- rename a file as indicated by the template after it has
- arrived completely.
- + FTP [M]GET /SERVER-RENAME:template added to make server
- rename a file as indicated by the template after it has been
- sent completely.
- + FTP [136]VDIRECTORY added for getting verbose directory
- listings from TOPS-20.
- + [137]FTP TYPE TENEX added for transferring 8-bit binary files
- with PDP-10s.
- + Added [138]automatic text/binary mode switching for FTP
- [M]GET, based on filename patterns (e.g. *.zip, *.gz, *.exe
- are binary; *.txt, *.c are text).
- + [139]SET SEND I-PACKETS OFF added for coping with Kermit
- servers that do not support I packets.
- + A new option was added to [140]\fword() and \fsplit() for
- parsing comma-separated lists that might contain empty
- elements.
- + Bug fixes including:
- o {} or "" could not be used as expected to represent the
- empty string.
- o ,- on a line by itself in a macro definition caused
- subsequent statements to be skipped.
- o FTP [M]GET didn't work right if path segments were
- included in the filespec.
- o FTP MGET, if interrupted, did not clear its file list.
- o Various problems with FTP PUT /AS-NAME that nobody
- noticed.
- o Some FTP messages and displays interfered with each
- other.
- o Parsing of YESTERDAY, TODAY, and TOMORROW in date-time
- fields was broken.
- o Automatic old-to-new dialing directory format conversion
- was broken on VMS.
- o Various source-code portability problems fixed.
- + Improvement of various HELP and SHOW messages.
-
- C-Kermit 7.1.199 Alpha.04 (1 April 2001)
-
- + Big changes:
- o Changed default modem type from NONE to GENERIC.
- o Generic dialing now sends no init string at all.
- o Changed default terminal bytesize from 7 to 8.
- + New features:
- o SET SESSION-LOG TIMESTAMPED-TEXT for timestamped session
- log.
- + New modem types:
- o Conexant modem family
- o Lucent VENUS chipset
- o PCTel V.90 chipset
- o Zoom V.90
- o Zoom V.92
- + FTP client:
- o FTP OPEN /PASSIVE and /ACTIVE switches added.
- o Now works with servers that that don't include path in
- NLST response.
- o Fixed SEND /RECURSIVE not to follow symlinks (UNIX).
- o SET FTP VERBOSE-MODE default is now OFF instead of ON.
- + Kermit protocol:
- o Fixed what I hope is the last "Receive window full"
- error.
- o SET PREFIXING or SET CONTROL PREFIX now automatically
- sets CLEARCHANNEL OFF.
- o Fixed incorrect report of number of files transferred at
- end of transfer.
- o Fixed SEND /RECURSIVE not to follow symlinks (UNIX).
- + UNIX:
- o HTTP and shadow passwords enabled for SCO 5.0.6.
- o Even with SET FILENAMES CONVERTED, spaces were still
- accepted in incoming filenames; now they are converted
- to underscores.
- o Added support for compile-time mktemp()/mkstemp()
- selection.
- + VMS:
- o Session-log format for scripted sessions fixed.
- + Scripting:
- o Fixed \frdir() not to follow symlinks (UNIX).
- o Fixed \fday() not to dump core for dates prior to 17 Mar
- 1858.
- + General:
- o "Closing blah..." message upon exit could not be
- surpressed.
- o Added /PAGE and /NOPAGE to DELETE switches.
- o Added GO response for DELETE /ASK (delete all the rest
- without asking).
- o Added GO response to "more?" prompt (for multi-page
- screen output).
- o Updated HELP texts.
-
- C-Kermit 7.1.199 Beta.01 (10 May 2001)
-
- + FTP client verbosity adjustments.
- + Bug with generic modem dialing pausing several secs fixed.
- + SET HOST /USER:, SET LOGIN USERID, etc, fixed when given no
- user ID.
- + A couple \v(dm_blah) dial modifier variables added.
- + "--version" command-line switch added.
- + Fixed NetBSD serial-port DTR handling.
- + Lots of syntax cleanups for Flexelint and gcc -Wall.
- + Fixed modem-type aliases to not take precedence over real
- names.
- + Fixed funny treatment of doublequotes by ECHO command.
- + Enabled SET SESSION-LOG for VMS and other non-UNIX platorms.
- + Fixed changing direction in command history buffer.
- + Fixed handling of IKSD URLs.
- + Made sure DELETE prints a message if it got any errors.
-
- C-Kermit 8.0.200 Beta.02 (28 June 2001)
-
- + Major version number increased from 7 to 8.
- + [141]SSH command.
- + More-consistent Kermit protocol defaults.
- + CONNECT idle timeout and action selection.
- + CONNECT status variable.
- + A way to allocate more space for filename lists.
- + Pseudoterminal handler fixed for late-model Linuxes.
- + Command-line option -dd for timestamped debug log.
- + Download directory now works for external protocols too.
- + GREP /COUNT:variable.
- + SET ATTRIBUTE RECORD-FORMAT { OFF, ON }.
- + Bug fixes.
-
- C-Kermit 8.0.200 Beta.03 (9 Sep 2001)
-
- + [142]HTTP 1.1 connections and scripting
- + [143]ON_CTRLC macro for trapping Ctrl-C in scripts
- + [144]Date-time parsing improvements, timezones, comparison,
- arithmetic
- + [145]Pattern-matching improvements
- + FTP improvements
- + SET EXIT HANGUP { ON, OFF }
- + SET FILE EOF { CTRL-Z, LENGTH }
- + ASK[Q] /TIMEOUT
- + Bug fixes
- + New platforms
-
- C-Kermit 8.0.200 Beta.04 (16 Nov 2001)
-
- + [146]New Unix man page
- + [147]New Unix installation instructions
- + SET TELOPT policies are now enforced on non-Telnet ports if
- the server begins Telnet negotiations.
- + SET TERMINAL IDLE-ACTION { TELNET-NOP, TELNET-AYT }.
- + UUCP lockfile creation race condition fixed.
- + Dialout, modem signals, hangup, hardware flow control, etc,
- tested extensively on many platforms, numerous problems
- fixed.
- + Improved hints when dialing fails.
- + SET STOP-BITS 2 can now be given without SET FLOW HARDWARE.
- + Major improvements in RFC 2217 Telnet Com-Port Control.
- + Improved ability to REDIAL a modem server port.
- + kermit -h now shows the command name in the usage usage
- string.
- + kermit -h now shows ALL command-line options.
- + kermit -s blah, where blah is a symlink, now works.
- + --noperms command-line option = SET ATTRIBUTE PERMISSIONS
- OFF.
- + HTTP and HTTPS URLs now supported on the command line.
- + An http command-line personality is now available.
- + Initialization file streamlined to load faster, anachronisms
- removed.
- + Updated NEWS, INTRO, HELP text, SHOW commands. In particular,
- see SHOW COMM, HELP SET LINE, HELP WAIT.
- + Date/time arithmetic routines converted from floating-point
- to integer arithmetic (internally) for greater accuracy and
- portability.
- + Quoted strings containing commas no longer break macro
- execution.
- + Dynamic Kermit file-transfer timeouts are now much more
- aggressive.
- + New "hot keys" to turn debug.log on/off during file transfer.
- + Improved hints when file transfer fails.
- + FTP CD orientation messages are now printed.
- + -R now accepted on the FTP command line to request Recursion.
- + -m allows Active or Passive mode to be chosen on the FTP
- command line.
- + -dd on the FTP command line creates a timestamped debug.log.
- + FTP command-line security options filled in.
- + Improved automatic text/binary mode switching for MGET.
- + Removed spurious error messages that sometimes occur during
- MGET.
- + DIRECTORY, GREP, TYPE, HEAD, and TAIL now have a /OUTPUT:file
- option.
- + TYPE /NUMBER adds line numbers.
- + CAT = TYPE /NOPAGE; MORE = TYPE /PAGE.
- + GETOK ?-help fixed.
- + \v(timestamp) (= "\v(ndate) \v(time)")
- + \v(hour) (hour of the day, 0-23)
- + \funix2dospath() converts a UNIX path (/) to a DOS one (\).
- + \fdos2unixpath() converts a DOS (Windows, OS/2) path to a
- UNIX one.
- + \fkeywordval() parses name=value pair, allows macro keyword
- parameters.
- + We now make every attempt to not write passwords to the
- debug.log.
- + New Certficate Authority certificates file, includes the
- Kermit Project at Columbia University so you can access our
- IKSD securely.
- + Secure targets improved and better documented in Unix
- makefile.
- + All Linux (libc and glibc) builds consolidated under "make
- linux".
- + HP-UX makefile targets now have consistent names.
- + New aix50 and aix51 targets added.
-
- C-Kermit 8.0.200 Final (12 Dec 2001)
-
- + Remote/local-mode confusion on some platforms introduced in
- Beta.04, fixed.
- + Many of the makefile targets adjusted, new ones added.
- + New "make install" target should please most people.
- + New command: SHOW IKSD.
- + FTP over TLS.
- + Last-minute touchups to text messages, HELP text, etc.
- + Enable modem-signal reading for SCO OSR5 and Unixware 7.
- + Special superfast TRANSMIT /BINARY /NOECHO /NOWAIT mode
- added.
- + Fixed PBX dialing in unmarked-area-code case.
- + Improved SHOW COMMUNICATIONS tells lockfile directory,
- typical dialout device name.
- + Some FTP OPEN command parsing problems fixed.
- + Some errors in date arithmetic fixed.
- + New command: SET TERMINAL AUTODOWNLOAD { ..., ERROR { STOP,
- CONTINUE } }
- + New command: HELP FIREWALL.
- + SET MODEM HANGUP-METHOD DTR added as synomym for RS232-SIGNAL
- + Support for secure URL protocols added: telnets:, ftps:,
- https:.
-
- C-Kermit 8.0.201 (8 Feb 2002)
-
- + Installability as an [148]SSH v2 Subsystem.
- + [149]SET LOCUS command.
- + [150]L-versions of CD, DIR, DELETE, MKDIR, etc, to force
- local execution.
- + [151]USER and ACCOUNT added as synonyms for FTP USER and FTP
- ACCOUNT.
- + [152]SHOW VARIABLES now accepts a list of variables.
- + Rudimentary support for [153]Caller ID when receiving phone
- calls.
- + Up/Down [154]Arrow-key navigation of command history buffer.
- + [155]Automatic execution of customization file if init file
- is missing.
-
- C-Kermit 8.0.206 Beta.01 (11 Oct 2002)
-
- New commands:
-
- o ORIENTATION lists location-related variables and their
- values.
- o KCD changes to special directories by their symbolic
- names ("kcd ?" for a list).
- o SET CD HOME path to specify home directory for CD and
- KCD commands.
- o CONTINUE given at top level is equivalent to END --
- handy when PROMPT'ed out of a script, to continue the
- script.
-
- New switches or operands for existing commands:
-
- o GETOK /TIMEOUT
- o ASK, ASKQ, GETOK /QUIET (suppresses error message on
- timeout)
- o COPY /APPEND now allows concatenating multiple source
- files into one dest file.
- o SET TCP { HTTP-PROXY, SOCKS-SERVER } /USER, /PASSWORD.
- o DIRECTORY command now accepts multiple filespecs, e.g.
- "dir a b c".
-
- SET QUIET ON now also applies to:
-
- o SET HOST connection progress messages.
- o "Press the X or E key to cancel" file-transfer message.
- o REMOTE CD response.
- o REMOTE LOGIN response.
-
- Improvements and new features:
-
- o Numerous FTP client fixes and new features, listed
- below.
- o C-Kermit, when in remote mode at the end of a file
- transfer, now prints a one-line "where" message. Control
- with SET TRANSFER REPORT.
- o Unix makefile "install" target now creates an UNINSTALL
- script.
- o Improved operation and performance on RFC 2217 Telnet
- connections.
- o Improved CONNECT (interactive terminal connection)
- performance.
- o HELP text updated for many commands.
-
- New or fixed makefile targets:
-
- o Solaris 9 (several variations)
- o Concurrent PowerMAX
- o Mac OS X 10.2
- o FreeBSD 1.0
- o FreeBSD 4.6, 5.0
- o AIX 5.2, 5.3
-
- Bugs fixed (general):
-
- o Failure to run in VMS Batch fixed.
- o LDIRECTORY fixed to run Kermit's built-in DIRECTORY
- command rather than an external one.
- o Fixed Solaris and other SVORPOSIX builds to find out
- their full hostnames rather than just the "uname -n"
- name.
- o Fixed some problems matching strings that start with
- ".".
- o Fixed some problems matching pattern that contain
- {a,b,c} lists.
- o Fixed erroneous reporting of text-mode reception as
- binary when sender did not report the file size
- (cosmetic only).
- o Many problems with SWITCH statements fixed.
- o Fixed SET OPTIONS DIRECTORY /DOTFILES to work for server
- too.
- o Fixed DELETE to print an error message if the file was
- not found.
- o Fixed SET CONTROL UNPREFIX ALL and SET PREFIXING NONE to
- do the same thing.
- o Fixed bugs executing macros from within the ON_EXIT
- macro.
- o \fday() and \fnday() fixed for dates prior to 17 Nov
- 1858.
- o Serial speed-changing bug in Linux fixed.
- o "Unbalanced braces" script parsing errors when using
- \{number} fixed.
- o "if defined \v(name)" fixed to behave as described in
- the book.
- o Fixed Problems caused by LOCAL variables whose names are
- left substrings of macro names.
- o The INPUT command was fixed to honor the PARITY setting.
- o Fixed bug with COPY to existing file that is longer than
- source file.
- o REINPUT command failed to strip braces/quotes around its
- target string.
- o Network directory lookups didn't work for SSH
- connections.
- o REMOTE SET { FILE, TRANSFER } CHARACTER-SET fixed.
- o Closed some holes whereby an incompletely received file
- was not deleted when SET FILE INCOMPLETE is DISCARD,
- e.g. when the Kermit is hung up upon.
- o SET XFER CHARACTER-SET TRANSPARENT fixed to do the same
- as SET XFER TRANSLATION OFF.
- o SET HOST PTY (e.g. SSH) connection fixed to pass along
- window-size changes.
- o C-Kermit search path for TAKE files was accidentally
- disabled.
-
- FTP client bugs fixed:
-
- o Character set translation was broken on little-endian
- (e.g. PC) architectures.
- o FTP PUT /SERVER-RENAME:, /RENAME-TO:, /MOVE-TO: switches
- were sticky.
- o Make SET TRANSFER MODE MANUAL apply to FTP.
- o Make SET FILE INCOMPLETE { KEEP, DISCARD } apply to FTP.
- o FTP MGET /UPDATE handled equal times incorrectly.
- o FTP MGET /RECOVER fixed to ignore file dates, use only
- size.
- o FTP MGET /RECOVER sometimes downloaded files it didn't
- need to.
- o FTP downloads with TRANSFER DISPLAY BRIEF could give
- misleading error messages.
- o FTP MGET temp file not deleted if FTP DEBUG set to OFF
- after it was ON.
- o LOCUS not switched back when FTP connection is lost.
- o Set incoming file date even if it was not completely
- received.
- o FTP MGET sent SIZE and MDTM commands even when it didn't
- have to.
- o FTP MGET sent SIZE and MDTM commands even when it knew
- they wouldn't work.
- o FTP MGET failed if no files were selected for download.
- o FTP MGET a* b* c* would fail to get any c*'s if no b*'s
- existed.
- o Big problems canceling MGET with Ctrl-C.
- o Some extraneous LOCUS dialogs squelched.
- o Some inconsistencies in SET FTP FILENAMES AUTO fixed.
- o Fixed file-descriptor pileup after multiple MGETs when
- using mkstemp().
- o Fixed "mget foo", where foo is a directory name.
-
- FTP improvements:
-
- o New [156]FTP protocol features added (FEAT, MLSD).
- o FTP MGET /RECURSIVE now works as expected if server
- supports MLSD.
- o FTP MGET /DATES-DIFFER to download if local and remote
- file dates differ.
- o FTP DATES default changed to ON.
- o FTP MPUT, MGET /EXCEPT now allows up to 64 patterns (up
- from 8).
- o Top-level SITE and PASSIVE commands added for
- convenience.
- o MGET /COLLISION:APPEND /AS-NAME:newfile *.* puts all
- remote files into one local file.
- o SET FTP SERVER-TIME-OFFSET for when server has wrong
- timezone set.
- o Allow for alternative server interpretations of [M]MPUT
- /UNIQUE.
- o SET FTP ANONOMOUS-PASSWORD lets you specify the default
- anonymous password.
- o Allow "GET /RECURSIVE path/file" to force local
- subdirectory creation.
- o SET FTP DISPLAY is like SET TRANSFER DISPLAY but applies
- only to FTP.
- o FTP { ENABLE, DISABLE } new-protocol-feature-name.
- o FTP MGET /NODOTFILES.
- o Debug log now records FTP commands and responses in
- grep-able format.
-
- [ [157]Top ] [ [158]Contents ] [ [159]C-Kermit ] [ [160]Kermit Home ]
- __________________________________________________________________________
-
-1. FIXES SINCE VERSION 7.0.196 First, the changes from 7.0.196 to 7.0.197...
-Source and makefile tweaks to get successful builds on platforms that were not
-available in time for the 7.0 release:
-
- * 4.2BSD
- * 4.3BSD
- * AIX 4.3
- * AT&T 3B2 and 3B20
- * BeOS 4.5
- * CLIX
- * Interactive UNIX System V/386 R3.2 V4.1.1
- * OS-9/68000
- * OSF/1 1.3.
- * PS/2 AIX 1.2.1
- * SCO OSR5.0.x
- * SCO Xenix 2.3.4
- * SINIX 5.41/Intel
- * Stratus FTX
- * Stratus VOS
- * SunOS 4.1 with X.25
- * Ultrix 4.2
- * Unixware 2.0
-
- There were no functional changes from 196 to 197.
-
- Fixes applied after C-Kermit 7.0.197 was released:
-
- Source code: Big flexelint and "gcc -Wall" audit and cleanup.
-
- Configuration:
- * Solaris RTS/CTS (hardware flow control) didn't work.
- * BSDI RTS/CTS worked only in one direction.
- * FreeBSD 4.0 with ncurses 5.0 broke interactive command parsing.
- * QNX-32 build lacked -DBIGBUFOK so couldn't execute big macros.
-
- Connections:
- * SET HOST /PTY didn't work on some platforms.
- * Broken SET HOST /USER:xxx /PASSWORD:yyy /ACCOUNT:zzz switches
- fixed.
- * Transparent printing was broken in Unix.
- * ANSWER 0 (wait forever) didn't work.
- * Some problems in Multitech modem command strings.
- * Spurious "?Sorry, can't condition console terminal" errors.
- * Disabling modem command strings by setting them to nothing broke
- dialing.
- * SET DIAL TIMEOUT value was usually ignored.
- * SET DIAL METHOD PULSE didn't work.
- * Certain modem commands, if changed, not refreshed if modem type
- changed.
- * SET SESSION-LOG command was missing from VMS.
- * VMS session log format fixed for scripts.
- * HANGUP by dropping DTR didn't work in NetBSD.
- * SET FLOW /AUTO versus SET FLOW confusion fixed.
- * Spurious secondary Solaris lockfile removed.
- * SCO OSR5 DTR On/Off hangup.
- * UUCP lockfile race condition.
-
- Commands and scripts:
- * Missing CAUTIOUS and FAST commands restored.
- * Broken PTY command in late-model Linuxes fixed (API changed).
- * Fixed off-by-one error in command recall when switching direction.
- * Fixed recall of commands that contain '?'.
- * COPY /SWAP-BYTES didn't work on some architectures.
- * Various combinations of COPY switches didn't work.
- * Various problems with COPY or RENAME with a directory name as
- target.
- * SHIFT didn't decrement \v(argc) if used within IF, ELSE, or SWITCH
- block.
- * SHIFT didn't affect the \%* variable.
- * Divide by zero improperly handled in some \function()s.
- * Problems with RETURN from right-recursive functions.
- * FSEEK /LINE \%c LAST didn't work if already at end.
- * Some buffer vulnerabilities and potential memory leaks were
- discovered and fixed.
- * \frdirectory() fixed not to follow symbolic links.
- * SET EXIT WARNING OFF fixed to work when EXIT given in a script.
- * Missing DELETE and MKDIR error message fixed.
- * \fday() core dump for ancient dates fixed.
-
- File transfer:
- * SEND /COMMAND was broken.
- * CRECEIVE was broken (but RECEIVE /COMMAND was OK).
- * Quoting wildcard chars in filenames didn't work.
- * Problems canceling streaming file transfers with X or Z.
- * Problems shifting between streaming and windowing file transfer.
- * Non-FULL file-transfer displays erroneously said STREAMING when
- not.
- * An active SEND-LIST prevented GET from working.
- * SET SERVER GET-PATH interpretation of relative names like "." was
- wrong.
- * The MAIL command was broken.
- * "kermit -s *" might have skipped some files.
- * Transaction log entries were not made for external protocol
- transfers.
- * File count report fixed to show number of files actually
- transferred.
- * Fixed filename conversion to convert spaces to underscores.
- * Made SET PREFIXING / SET CONTROL PREFIX also adjust CLEARCHANNEL.
- * More "Receive window full" errors fixed.
- * Broken terminal buffering after curses display in Solaris fixed.
- * SET FILE INCOMPLETE DISCARD did not work in all cases.
- * Packet log changed to reformat the start-of-packet character
- printably.
- * Dynamic timeouts could grow ridiculously large.
-
- Character sets:
- * Hebrew-7 translations missed the letter Tav.
- * C1 area of CP1252 was ignored.
- * SET TRANSFER CHARACTER-SET TRANSPARENT could give garbage
- translations.
- * TRANSLATE might not work on Little Endian architectures.
- * Insufficient range checking in certain TRANSLATE operations.
-
- The following bugs in C-Kermit 8.0.200 were fixed in 8.0.201:
-
- * An obscure path through the code could cause the Unix version of
- C-Kermit to dump core during its startup sequence. This happened
- to only one person, but now it's fixed.
- * When C-Kermit 8.0 is in Kermit server mode and the client says
- "get blah", where blah (on the server) is a symlink rather than a
- real file, the server unreasonably refused to send the linked-to
- file.
- * When C-Kermit is an FTP client and says "get foo/bar" (i.e. a
- filename that includes one or more path segments), it failed to
- accept the incoming file (this happened only with GET, not MGET).
- * Array references should be case insensitive but only lowercase
- array letters were accepted.
- * SHOW VARIABLES dumped core on \v(sexpression) and \v(svalue).
- * Spurious refusals of remote directory listings if the remote
- server's date was set in the past.
- * In AIX, and maybe elsewhere too, Kermit's COPY command always
- failed with "Source and destination are the same file" when the
- destination file didn't exist.
- * The VMS version of C-Kermit did not work in Batch or when SPAWN'd.
- To compound the problem, it also pretty much ignored the -B and -z
- command-line options, whose purpose is to work around such
- problems.
- * C-Kermit 8.0 could not be built on IRIX 5.x.
- * The C-Kermit 8.0 build for QNX6 said it was an "(unknown
- version)".
-
- Other fixes are listed in the [161]previous section.
-
- [ [162]Top ] [ [163]Contents ] [ [164]C-Kermit ] [ [165]Kermit Home ]
- __________________________________________________________________________
-
-2. SSH AND HTTP
-
- 2.1. SSH Connections
-
- This section does not apply to [166]Kermit 95 2.0, which has its
- own built-in SSH client, which is documented [167]SEPARATELY.
-
- On most UNIX platforms, C-Kermit can make SSH (Secure SHell)
- connection by running the external SSH command or program through its
- pseudoterminal interface. The command is:
-
- SSH text
- Tells Kermit to start the external SSH client, passing the
- given text to it on the command line. Normally the text is just
- the hostname, but it can be anything else that is acceptable to
- the ssh client. If the command succeeds, the connection is made
- and Kermit automatically enters CONNECT (terminal) mode. You
- can use the SSH command to make a connection to any host that
- has an SSH server.
-
- Kermit's SSH command gives you all the features of Kermit on an SSH
- connection: command language, file transfer, character-set
- translation, scripting, and all the rest. By default, C-Kermit invokes
- SSH with "-e none", which disables the ssh escape character and makes
- the connection transparent for purposes of file transfer. You can,
- however, change the SSH invocation to whatever else you might need (an
- explicit path, additional command-line arguments, etc) with:
-
- SET SSH COMMAND text
- Specifies the system command that Kermit's SSH command should
- use to invoke the external SSH client. Use this command to
- supply a specific path or alternative name, or to include
- different or more command-line options.
-
- In most cases, these connections work quite well. They can be scripted
- like any other connection, and file transfer goes as fast as, or
- faster than, on a regular Telnet connection. In some cases, however,
- the underlying pseudoterminal driver is a limiting factor, resulting
- in slow or failed file transfers. Sometimes you can work around such
- problems by reducing the Kermit packet length. Note that Kermit does
- not consider SSH connections to be reliable, so it does not offer to
- use streaming in Kermit protocol transfers (but you can force it with
- SET RELIABLE or SET STREAMING if you wish).
-
- The SSH command is like the TELNET command: it enters CONNECT mode
- automatically when the connection is made. Therefore, to script an SSH
- connection, use:
-
- set host /pty ssh -e none [ other-options ] host
- if fail ...
-
- to make the connection.
-
- Here's a sequence that can be used to make a connection to a given
- host using Telnet if the host accepts it, otherwise SSH:
-
- if not defined \%1 exit 1 Usage: \%0 host
- set quiet on
- set host \%1 23 /telnet
- if fail {
- set host /pty ssh -l \m(user) -e none \%1
- if fail exit 1 \%1: Telnet and SSH both fail
- echo SSH connection to \%1 successful
- } else {
- echo Telnet connection to \%1 successful
- }
-
- In SSH v2, it is possible to make an SSH connection direct to a Kermit
- server system if the host administrator has configured the SSH server
- to allow this; [168]CLICK HERE for details.
-
- Since Kermit uses external ssh client software, and since there are
- different ssh clients (and different releases of each one), the exact
- command to be used to make an SSH/Kermit connection can vary. Here is
- the command for the OpenSSH 3.0.2p1 client:
-
-set host /pipe ssh -e none [ -l username ] -T -s hostname kermit
-
- Example:
-
-set host /pipe ssh -e none -l olga -T -s hq.xyzcorp.com kermit
-
- The SSH client might or might not prompt you for a password or other
- information before it makes the connection; this depends on your SSH
- configuration (your public and private keys, your authorized hosts
- file, etc). Here's a brief synopsis of the OpenSSH client command
- syntax ("man ssh" for details):
-
- -e none
- This tells the SSH client to use no escape character. Since we
- will be transferring files across the connection, we don't want
- the connection to suddenly block because some character in the
- data.
-
- -l username
- This is the username on the remote host. You can omit the -l
- option and its argument if your local and remote usernames are
- the same. If they are different, you must supply the remote
- username.
-
- -T
- This tells the SSH client to tell the SSH server not to
- allocate a pseudoterminal. We are not making a terminal
- connection, we don't need a terminal, and in fact if a terminal
- were allocated on the remote end, the connection would not
- work.
-
- -s ... kermit
- This tells the SSH client to tell the SSH server to start the
- specified subsystem ("kermit") once the connection is made. The
- subsystem name comes after the hostname.
-
- hostname
- The IP host name or address of the desired host.
-
- You might want to include other or additional ssh command-line
- options; "man ssh" explains what they are. Here are some examples for
- the OpenSSH 3.0.2p1 client:
-
- -oClearAllForwardings yes
- -oForwardAgent no
- -oForwardX11 no
- -oFallbackToRsh no
- These ensure that a secure connection is used and that the
- connection used for file transfer is not also used for
- forwarding other things that might be specified in the
- ssh_config file.
-
- -oProtocol 2
- (i.e. SSH v2) Ensures that the negotiated protocol supports
- subsystems.
-
- Once you have an SSH connection to a Kermit server, it's just like any
- other connection to a Kermit server (and very similar to a connection
- to an FTP server). You give the client file transfer and management
- commands for the server, and the server executes them. Of course you
- can also give the client any other commands you wish.
-
- [ [169]SSH Kermit Server Subsystem ] [ [170]Kermit 95 Built-in SSH
- Client ]
- _________________________________________________________________
-
- 2.2. HTTP Connections
-
- Hypertext Transfer Protocol, or HTTP, is the application protocol of
- the World Wide Web (WWW), used between Web browsers (clients) and Web
- servers. It allows a client to get files from websites, upload files
- to websites, delete files from websites, get information about website
- directories and files, and interact with server-side CGI scripts.
- C-Kermit includes an HTTP client capable of both clear-text and secure
- HTTP connections, that can do all these tasks and can be automated
- through the Kermit scripting language.
-
- Although C-Kermit 7.0 could make HTTP connections to Web servers, it
- could do so only when no other connection was open, and the procedure
- was somewhat awkward. C-Kermit 8.0 improves matters by:
-
- * Allowing an HTTP connection to be open at the same time as a
- regular SET LINE or SET HOST connection, and also at the same time
- as an FTP connection ([171]Section 3);
- * Upgrading the HTTP protocol level from 1.0 to 1.1, thus allowing
- for persistent connections, in which a series of commands can be
- sent on the same connection, rather than only one as in HTTP 1.0
- (and C-Kermit 7.0);
- * Providing for "one-shot" URL-driven HTTP operations such as GET or
- PUT.
- * Providing a distinct HTTP command-line personality.
-
- Persistent HTTP connections are managed with the following commands:
-
- HTTP [ switches ] OPEN [ security-options ] host-or-url [ port ]
- Opens a persistent connection to the specified host (IP host
- name or address) on the specified port. If any switches
- (options, listed in the next section) are included, their
- values are saved and used for all subsequent HTTP action
- commands on the same connection. If no port is specified, HTTP
- (80) is used. A Uniform Resource Locator (URL, [172]RFC 1738)
- can be given instead of a hostname (or address) and port (but
- the URL can not include a directory/file path). The security
- options are explained [173]below. The HTTP OPEN command
- replaces the C-Kermit 7.0 SET HOST hostname HTTP command, which
- no longer works with HTTP GET and related commands.
-
- HTTP CLOSE
- Closes any open HTTP connection and clears any saved switch
- values.
-
- A URL starts with a protocol name, which must be http or https in this
- case; optionally includes a username and password; and must contain a
- host name or address:
-
- protocol://[user[.password]]@host[:port][URI]
-
- HTTP is Hypertext Transfer Protocol. HTTPS is the secure (SSL/TLS)
- version of HTTP. The TCP service port is derived from the protocol
- prefix (so normally the ":port" field is omitted). Thus the URL
- protocol name specifies a default TCP service port and the URL user
- and password fields can take the place of the /USER and /PASSWORD
- switches ([174]Section 2.2.1). The optional URI is a "compact string
- of characters for identifying an abstract or physical resource"
- ([175]RFC 2396), such as a file. It must begin with a slash (/); if
- the URI is omitted, "/" is supplied. Examples:
-
- http open http://www.columbia.edu/
- Equivalent to http open www.columbia.edu or http open
- www.columbia.edu http.
-
- http open https://olga.secret@www1.xyzcorp.com/
- Equivalent to http /user:olga /pass:secret open
- www1.xyzcorp.com https.
-
- Persistence is accomplished unilaterally by C-Kermit 8.0. An HTTP 1.0
- server closes the connection after each action. Although HTTP 1.1
- allows multiple actions on the same connection, an HTTP 1.1 server
- tends to close the connection if it is idle for more than a few
- seconds, to defend itself against denial-of-service attacks. But when
- you use Kermit's HTTP OPEN command to create a connection, Kermit
- reopens it automatically (if necessary) for each HTTP action until you
- close it with HTTP CLOSE, regardless of the server's HTTP protocol
- version, or how many times it closes the connection.
-
- Firewalls can be negotiated through proxies with the following
- commands:
-
- SET TCP HTTP-PROXY [ host[:port] ]
- If a host (by hostname or IP address) is specified, Kermit uses
- it as a proxy server when attempting outgoing TCP connections
- -- not only HTTP connections, but all TCP/IP connections,
- Telnet and FTP included. This allows Kermit to adapt to the
- HTTP firewall penetration method (as opposed to other methods
- such as SOCKS4). If no hostname or ip-address is specified, any
- previously specified Proxy server is removed. If no port number
- is specified, the "http" service is used. This command must be
- given before the HTTP OPEN command if a proxy is to be used or
- canceled.
-
- HTTP [ switches ] CONNECT host[:port]
- Instructs the HTTP server to act as a proxy, establishing a
- connection to the specified host (IP hostname or address) on
- the given port (80 = HTTP by default) and to redirect all data
- transmitted between Kermit and itself to the given host for the
- life of the connection. This command is to be used only for
- debugging HTTP proxy connections. If a proxy connection is
- required, instruct Kermit to use the proxy with the SET TCP
- HTTP-PROXY command.
-
- 2.2.1. HTTP Command Switches
-
- HTTP switches, like all other switches, are optional. When HTTP
- switches are included with the HTTP OPEN command, they apply
- automatically to this and all subsequent HTTP actions (GET, PUT, ...)
- on the same connection until an HTTP CLOSE command is given. So if you
- include switches (or the equivalent URL fields, such as user and
- password) in the HTTP OPEN command, you can omit them from subsequent
- commands on the same connection. If the connection has closed since
- your last command, it is automatically reopened with the same options.
-
- If you include switches with an HTTP action command (such as GET or
- PUT), they apply only to that command.
-
- /USER:name
- To be used in case a page requires a username for access. The
- username is sent with page requests. If it is given with the
- OPEN command it is saved until needed. If a username is
- included in a URL, it overrides the username given in the
- switch. CAUTION: Username and password (and all other
- information, including credit card numbers and other material
- that you might prefer to protect from public view) are sent
- across the network in clear text on regular HTTP connections,
- but authentication is performed securely on HTTPS connections.
-
- /PASSWORD:text
- To be used in case a web page requires a password for access.
- The password is sent with page requests. If it is given with
- the OPEN command it is saved until needed. If a password is
- given in a URL, it overrides the one given here. CAUTION: (same
- as for /USER:).
-
- /AGENT:user-agent
- Identifies the client to the server. Overrides the default
- agent string, which is "C-Kermit" (for C-Kermit) or "Kermit-95"
- (for Kermit 95).
-
- /ARRAY:array-designator
- Tells Kermit to store the response headers in the given array,
- one line per element. The array need not be declared in
- advance. Example: /array:&a.
-
- /TOSCREEN
- Tells Kermit to display any response text on the screen. It
- applies independently of the output file specification; thus it
- is possible to have the server response go to the screen, a
- file, both, or neither.
-
- /HEADER:header-item(s)
- Used for specifying any optional headers to be sent with HTTP
- requests.
-
- /HEADER:tag:value
-
- To send more than one header, use braces for grouping:
-
- /HEADER:{{tag:value}{tag:value}...}
-
- For a list of valid tags and value formats see [176]RFC 2616,
- "Hypertext Transfer Protocol -- HTTP/1.1". A maximum of eight
- headers may be specified.
-
- 2.2.2. HTTP Action Commands
-
- HTTP actions can occur within a persistent connection, or they can be
- self-contained ("connectionless"). A persistent HTTP connection begins
- with an HTTP OPEN command, followed by zero or more HTTP action
- commands, and is terminated with an HTTP CLOSE command:
-
- http open www.columbia.edu
- if failure stop 1 HTTP OPEN failed: \v(http_message)
- http get kermit/index.html
- if failure stop 1 HTTP GET failed: \v(http_message)
- (more actions possible here...)
- http close
-
- A self-contained HTTP action occurs when a URL is given instead of a
- remote file name to an HTTP action command. In this case, Kermit makes
- the HTTP connection, takes the action, and then closes the connection.
- If an HTTP connection was already open, it is closed silently and
- automatically.
-
- http get http://www.columbia.edu/kermit/index.html
-
- Kermit's HTTP action commands are as follows. Switches may be included
- with any of these to override switch (or default) values given in the
- HTTP OPEN command.
-
- HTTP [ switches ] GET remote-filename [ local-filename ]
- Retrieves the named file from the server specified in the most
- recent HTTP OPEN command for which a corresponding HTTP CLOSE
- command has not been given. The filename may not include
- wildcards (HTTP protocol does not support them). If no HTTP
- OPEN command is in effect, this form of the HTTP GET command
- fails. The default local filename is the same as the remote
- name, but with any pathname stripped. For example, the command
- http get kermit/index.html stores the file in the current local
- directory as index.html. If the /HEADERS: switch is included,
- information about the file is also stored in the specified
- array (explained in [177]Section 2.2.3). All files are
- transferred in binary mode. HTTP does not provide for
- record-format or character-set conversion.
-
- HTTP [ switches ] GET url [ local-filename ]
- When HTTP GET is given a URL rather than a filename, Kermit
- opens a connection to the designated server (closing any
- previously open HTTP connection), gets the file, and then
- closes the connection. If the URL does not include a filename,
- index.html is supplied. This is the self-contained one-step
- "connectionless" method for getting a file from a Web server.
- The data is not interpreted; HTTP GET is like "lynx -source"
- rather than "lynx -dump".
-
- In the remaining HTTP action commands, the distinction between a
- remote filename and a URL are the same as in the HTTP GET command.
-
- HTTP [ switches ] HEAD remote-filename-or-url [ local-filename ]
- Like GET except without actually getting the file; instead it
- retrieves only the headers. If the /ARRAY: or /TOSCREEN switch
- is included, there is no default local output filename but you
- can still specify one. If neither of these switches is
- included, the default local filename is the same as the remote
- filename, but with any path stripped and with ".head" appended.
- The HEAD command can be used in a script with the /ARRAY:
- switch to retrieve information about the requested resource to
- determine whether the resource should actually be retrieved
- with a subsequent GET request.
-
- HTTP [ switches ] INDEX remote-directory-or-url [ local-filename ]
- Asks the server to send a listing of the files in the given
- server directory. This command is not supported by most Web
- servers. Even when it is supported, there is no standard format
- for the listing.
-
- HTTP [ switches ] POST [ /MIME-TYPE:type ] source-file
- remote-path-or-url [ result-file ]
- Sends data to a process running on the remote host; the result
- is usually an HTML file but could be anything. The data to be
- posted must be read from a local file (the source-file). If a
- result file is specified, Kermit stores the server's response
- in it.
-
- HTTP [ switches ] PUT [ MIME-TYPE:type ] local-file [
- remote-file-or-url [ result-file ] ]
- Uploads a local file to the server. Only the name of a single
- file can be given; wildcards (and group transfers) are not
- supported by HTTP protocol. If no remote filename is given, the
- file is sent with the same name as the local file, but with any
- pathname stripped.
-
- HTTP [ switches ] DELETE remote-file-or-url [ local-result-file ]
- Asks the server to delete the specified single file. If a
- result file is specified, it will contain any response data
- returned by the server.
-
- Note the limitations of HTTP protocol compared to (say) FTP or Kermit.
- There is no command for changing directories, no standard way to get
- file or directory lists, no way to transfer file groups by using
- wildcard notation, etc, and therefore no good way to (say) fetch all
- pages, descend through subdirectories, perform automatic updates, etc.
- There is no assurrance a connection will stay open and, as noted,
- there is no provision for data conversion between unlike platforms.
- The data's MIME headers can be used for postprocessing.
-
- 2.2.3. HTTP Headers
-
- Each HTTP request and response contains a set of name/value pairs
- called headers. HTTP headers are specified in [178]RFC 2616. For
- example, an HTTP GET request for /index.html on www.columbia.edu
- contains the following headers:
-
- GET /index.html HTTP/1.1
- Host: www.columbia.edu:80
- User-agent: C-Kermit 8.0
- Authorization: Basic base64-encoded-username-password
-
- These might be followed by any others specified with a /HEADERS:
- switch:
-
- Accept: image/gif, image/x-xbitmap, image/jpeg, *.*
- Accept-Encoding: gzip
- Accept-Language: en
- Accept-Charset: iso-8859-1,utf-8
- Cookie: cookie-data
-
- The server sends back a short report about the file prior to sending
- the file contents. Example:
-
- HTTP/1.1 200 OK
- Date: Fri, 24 Aug 2001 21:09:39 GMT
- Server: Apache/1.3.4 (Unix)
- Last-Modified: Mon, 06 Aug 2001 21:16:13 GMT
- ETag: "1fa137-10d7-3b6f091d"
- Accept-Ranges: bytes
- Content-Length: 4311
- Content-Type: text/html
-
- If you want to have this information available to a Kermit script you
- can use the /ARRAY switch to have Kermit put it in array, one line per
- array element. Example:
-
- set exit warning off
- http open www.columbia.edu
- if fail exit 1 Can't reach server
- http /array:&a get /index.html
- if fail exit 1 Can't get file
- echo Header lines: \fdim(&a)
- for \%i 1 \fdim(&a) 1 {
- echo \%i. \&a[\%i]
- }
-
- Note that the "Date:" item is the current date and time; the
- "Last-Modifed:" item is the file's modification date and time. An
- example showing how to use this information is presented in
- [179]Section 8.13.7.
-
- 2.2.4. Secure HTTP Connections
-
- SSL/TLS (Secure Sockets Layer / Transport Layer Security) is the
- protocol used to secure HTTP, SMTP, and other Internet applications.
- See the [180]C-Kermit Reference Section 5.4 for an introduction to
- SSL/TLS. To make a secure HTTP connection, you need:
-
- 1. A secure client (a version of C-Kermit or Kermit 95 with SSL/TLS
- security built in). Type "check ssl" at the Kermit prompt to make
- sure you have it.
- 2. A secure server to connect to.
- 3. The CA Root Certificate used to authenticate the server to the
- client. (see [181]Section 15 of the security reference for an
- introduction to certificates).
-
- And you must make a connection to the secure HTTP port: service name
- HTTPS, port number 443 (as opposed to service HTTP, port 80). You can
- also make secure connections to other ports by including the /TLS or
- /SSL switch with the HTTP OPEN command, if the host supports SSL/TLS
- on the given port:
-
- The quality of the SSL/TLS connection depends on the cipher suite.
- There are several possibilities:
-
- Anonymous cipher suite:
- If an anonymous cipher suite is negotiated, the connection is
- encrypted but there is no authentication. This connection is
- subject to a Man-In-The-Middle (MITM) attack.
-
- X.509 certificate on the server:
- When you connect to certain secure servers, an X.509
- certificate is returned. This certificate is issued to a
- special hostname, something like www1.xyzcorp.com or
- wwws.xyzcorp.com (rather than the normal www.xyzcorp.com). It
- is signed by the host's Certificate Authority (CA). If the host
- certificate is configured on the client, it can be used to
- verify the certificate received from the server. If the
- certificate it verified as authentic, a check is made to ensure
- it has not expired and it was issued to the host you were
- attempting to connect to. If you had asked to connect to (say)
- www.xyzcorp.com but were given a certificate for
- www1.xyzcorp.com, you would be prompted for permission to
- continue.
-
- If the verification succeeded, the connection would be
- encrypted with one-way (server-to-client) authentication. This
- connection is not subject to a MITM attack.
-
- If a username and password are transmitted over this
- connection, they are not subject to interception. However, the
- standard risks associated with passing the password to the host
- for verification apply; for example, if the host has been
- compromised, the password will be compromised.
-
- X.509 client certificate:
- If a connection has been established with an X.509 server
- certificate, the server can ask the client to send a
- certificate of its own. This certificate must be verified
- against a CA Root certificate. The certificate itself (or
- subject info from the certificate) is used to determine the
- authorization for the client, and if successful, the username
- and password need not be sent to the server.
-
- Kerberos 5:
- Instead of using X.509 certifcates, Kerberos 5 can be used to
- perform the authentication and key exchange. In this situation,
- there is mutual authentication between the client and server.
- The Kerberos 5 principal is used by the server to look up the
- appropriate authorization data. There is no need to send
- username and password.
-
- An HTTP connection is made with the HTTP OPEN command:
-
- HTTP [ switches ] OPEN [ { /SSL, /TLS } ] host [ port ]
- If /SSL or /TLS switches are included (these are synonyms), or
- if the service is HTTPS or the port is 443, a secure connection
- is attempted using the current authentication settings; see
- HELP SET AUTHENTICATION for details ([182]Section 6.2 of the
- security reference). If the no /SSL or /TLS switch is included
- but the port is 443 or the service is HTTPS, a secure
- connection is attempted. If an /SSL or /TLS switch is included
- but a port is not specified, an SSL/TLS connection is attempted
- on the default port (80).
-
- Certificates are covered in the separate [183]Kermit Security
- Reference for C-Kermit 8.0. You should let Kermit know to verify
- certificates with the SET AUTHENTICATION TLS command. For example:
-
- SET AUTHENTICATION TLS CRL-DIR directory
- Specifies a directory that contains certificate revocation
- files where each file is named by the hash of the certificate
- that has been revoked.
-
- SET AUTHENTICATION TLS CRL-FILE filename
- Specifies a file that contains a list of certificate
- revocations.
-
- SET AUTHENTICATION TLS VERIFY-DIR directory
- Specifies a directory that contains root CA certificate files
- used to verify the certificate chains presented by the peer.
- Each file is named by a hash of the certificate.
-
- SET AUTHENTICATION TLS VERIFY-FILE filename
- Specifies a file that contains root CA certificates to be used
- for verifying certificate chains.
-
- SET AUTHENTICATION TLS VERIFY OFF
- Tells Kermit not to require a certificate and accept any
- certificate that is presented regardless of whether it is
- valid.
-
- There are many other options; see the security document for details.
-
- Now suppose you need need to fetch the file denoted by the following
- URL:
-
- https://myuserid:mypassword@wwws.xyzcorp.com/clients/info/secret.html
-
- Once you have set up the handling of certificates as desired, you can
- use the following Kermit commands:
-
- http /user:myuserid /password:mypassword open www1.xyzcorp.com https
- if success {
- http get /clients/info/secret.html
- http close
- }
-
- As another example, let's say that you have a web form you need to
- populate with three fields: red,white and blue.
-
- <FORM ACTION="http://www.xyzcorp.com/cgi-bin/form.cgi" METHOD="POST">
- <INPUT NAME="Red">
- <INPUT NAME="White">
- <INPUT NAME="Blue">
- </FORM>
-
- You can handle this with the HTTP POST command. The data to be posted
- is stored in the local file data.txt.
-
- Red=seven stripes&White=six stripes&Blue=fifty stars
-
- and the response from the server will be stored into response.txt.
-
- http open www.xyzcorp.com http
- if success {
- http /array:c post data.txt /cgi-bin/form.cgi response.txt
- http close
- }
-
- In this scenario, the Common Gateway Interface (CGI) sends a response
- whether it succeeds or fails in a script-dependent manner. The script
- can either report success and enclose the response data; or it might
- send a 302 Found error which indicates that the "Location:" header
- should be used to determine the URL at which the data can be found.
-
- 2.2.5. HTTP Variables
-
- \v(http_code)
- The HTTP protocol code number of the most recent server reply,
- e.g. 404 for "not found".
-
- \v(http_connected)
- 1 when an HTTP connection is open, 0 when there is no HTTP
- connection.
-
- \v(http_host)
- If an HTTP connection is open, the hostname:port, e.g.
- www.columbia.edu:80; otherwise, empty.
-
- \v(http_message)
- Server error message, if any, from most recent HTTP command.
-
- \v(http_security)
- A list of the security parameters and values for the current
- connection, if any. Empty if the connection is not to a secure
- server, or there is no connection.
-
- To display all the HTTP variables at once, type SHOW VAR HTTP:
-
- C-Kermit> http open www.columbia.edu
- C-Kermit> http get lkjlkjlkjlkj
- C-Kermit> sho var http
- \v(http_code) = 404
- \v(http_connected) = 1
- \v(http_host) = www.columbia.edu:80
- \v(http_message) = Not Found
- \v(http_security) = NULL
- C-Kermit>
-
- 2.2.6. The HTTP Command-Line Personality
-
- If you invoke C-Kermit with the name "http" or "https", you can use a
- special set of HTTP-specific command-line options. You can do this by
- creating a symbolic linke "http" or "https" to the C-Kermit 8.0
- executable, or by having a separate copy of it called "http" or
- "https". Here's the usage message ("http -h"):
-
- Usage: ./http host [ options... ]
- -h This message.
- -d Debug to debug.log.
- -S Stay (issue command prompt when done).
- -Y Do not execute Kermit initialization file.
- -q Quiet (suppress most messages).
- -u name Username.
- -P password Password.
- -g pathname Get remote pathname.
- -p pathname Put remote pathname.
- -H pathname Head remote pathname.
- -l pathname Local path for -g, -p, and -H.
- -z opt[=value] Security options...
- cert=file Client certificate file
- certsok Accept all certificates
- key=file Client private key file
- secure Use SSL
- verify=n 0 = none, 1 = peer , 2 = certificate required
-
- The "host" argument is the name of a Web host, e.g. www.columbia.edu.
- The action options are -p, -g, and -H. If you give an action option,
- Kermit does the action and then exits. If you give a host without an
- action option, Kermit makes an HTTP connection to the host and then
- gives you the C-Kermit prompt. Here's a simple example that fetches a
- publicly readable Web page:
-
- http www.columbia.edu -g kermit/index.html
-
- If you need to access a website for which a username and password are
- required, you can supply them on the command line with -u and -P. If
- you include a username but omit the password, Kermit prompts you for
- it:
-
- http www.columbia.edu -u olga -p kermit/index.html -l index.html
- Password:
-
- Note that when PUT'ing files to websites, you have to supply both the
- -p (remote pathname) and -l (local path) options.
-
- If your version of Kermit is built with SSL/TLS security, you can also
- use the -z option to make secure HTTP (https) connections.
-
- Finally, as noted in [184]Section 16, you can also give a URL instead
- of a host name and options.
-
- [ [185]Top ] [ [186]Contents ] [ [187]C-Kermit Home ] [ [188]Kermit
- Home ]
- __________________________________________________________________________
-
-3. THE BUILT-IN FTP CLIENT
-
- 3.1. [189]Making and Managing FTP Connections
- 3.2. [190]Making Secure FTP Connections
- 3.3. [191]Setting FTP Preferences
- 3.4. [192]Managing Directories and Files
- 3.5. [193]Uploading Files With FTP
- 3.6. [194]Downloading Files With FTP
- 3.7. [195]Translating Character Sets
- 3.8. [196]FTP Command Shortcuts
- 3.9. [197]Dual Sessions
- 3.10. [198]Automating FTP Sessions
- 3.11. [199]Advanced FTP Protocol Features
-
- Earlier versions of C-Kermit and K95 included an FTP command, but it
- simply invoked an external FTP client. Now, by popular demand, Kermit
- includes its own built-in FTP client that offers the following
- advantages over traditional FTP clients (and its previous interface to
- them):
-
- * Any of Kermit's built-in [200]security methods can be used to
- establish and conduct secure FTP sessions with [201]FTP servers
- that support these methods. (Security modules can be subject to
- export restrictions.)
- * Kermit's FTP client uses "passive mode" by default to avoid
- blockage by firewalls and network address translators. Of course
- active mode can be chosen too when needed.
- * [202]Character sets can be translated as part of the transfer
- process even when the FTP server does not support character-set
- translation, including to/from the new Internet standard
- international character set, [203]Unicode UTF-8. This includes
- both the file's name and (for text files only) its contents.
- * All of C-Kermit's [204]file-selection mechanisms are available:
- size, date, name patterns and lists, exception lists, etc.
- * [205]Atomic file movement capabilities are provided (delete, move,
- or rename files automatically after successful transfer).
- * The correct file type, "ascii" (i.e. text) or binary, is chosen
- automatically for each file (explained in [206]Section 4), and any
- mixture of text and binary files can be sent in a single
- operation, even across platforms.
- * Update mode ("don't bother transferring files that didn't change
- since last time") and recovery (resumption of an interrupted
- transfer from the point of failure) are available in both
- directions.
- * When uploading files from UNIX to UNIX, the file's permissions can
- be preserved if desired.
- * Recursive directory-tree PUTs are supported between any two
- platforms that have tree-structured file systems. Recursive GETs
- are supported between like platforms if the server cooperates and
- between like or unlike platforms if the server supports MLSD
- ([207]Section 3.11).
- * When receiving files, all of Kermit's file collision actions are
- available: backup, update, refuse, rename, etc.
- * Multi-file transfers can be interrupted on a per-file basis,
- automatically skipping to the next file.
- * FTP sessions are [208]fully scriptable.
- * An entire FTP session (connect, login, CD, upload or download,
- logout) can be specified on the command line without using a
- script.
- * All of Kermit's logging options and formats are available to keep
- an accurate and complete record of each connection and file
- transfer, and to aid in troubleshooting.
- * All of Kermit's file-transfer display options are available
- (fullscreen, brief, CRT, serial, none).
-
- And best of all:
- * Kermit doesn't give you those annoying per-file prompts every time
- you start a multi-file transfer without remembering to give a
- "prompt" command first :-).
-
- [ [209]Top ] [ [210]FTP Top ] [ [211]FTP Client Overview ] [ [212]FTP
- Script Tutorial ] [ [213]C-Kermit Home ] [ [214]Kermit Home ]
- _________________________________________________________________
-
- 3.1. Making and Managing FTP Connections
-
- Each copy of Kermit can have one FTP connection open at a time. FTP
- connections are independent of regular terminal connections; a
- terminal connection (serial or network via SET LINE, DIAL, SET HOST,
- TELNET, etc) may be, but need not be, open at the same time as an FTP
- connection, and terminal connections can also be closed, and new
- connections opened, without interfering with the FTP connection (and
- vice versa). Thus, for example, Kermit can have an FTP connection and
- a TELNET connection open to the same host simultaneously, using the
- TELNET connection (e.g.) to send mail or take other desired actions as
- various FTP actions complete. Of course, each copy of Kermit can do
- only one thing at a time, so it can't (for example) transfer a file
- with FTP and another file with Kermit protocol simultaneously.
-
- A Kermit FTP session can be established by [215]command-line options,
- by [216]URL, or by [217]interactive commands.
-
- 3.1.1. Kermit Command-Line Options for FTP
-
- The new command-line option '-9' (sorry, we're out of letters) can be
- used when starting C-Kermit, telling it to make an FTP connection:
-
- kermit -9 hostname
-
- or if a non-default FTP port is needed:
-
- kermit -9 hostname:port
-
- You can also specify the username on the command line with the -M ("My
- User ID") option that was already there for other connection types:
-
- kermit -9 hostname -M olga
-
- If you specify the username on the command line, Kermit uses it when
- making the connection and does not prompt you for it (but it does
- prompt you for the password if one is required).
-
- Once the connection is made, you get the regular Kermit prompt, and
- can give interactive commands such as the ones described below. When
- you give a BYE command, Kermit closes the session and exits, just as a
- regular FTP client would do. If you don't want Kermit to exit when you
- give a BYE command, include the -S ("Stay") option on the command
- line.
-
- Other Kermit command-line options that are not specific to non-FTP
- connections should affect the FTP session in the expected ways; for
- example, -i and -T force binary and text mode transfers, respectively.
-
- File transfers can not be initiated on the "kermit -9" command line;
- for that you need to use Kermit's FTP personality (next section) or
- you can use URLs ([218]Section 3.1.3).
- _________________________________________________________________
-
- 3.1.2. The FTP Command-Line Personality
-
- If you want to replace your regular FTP client with C-Kermit, you can
- make a link called "ftp" to the C-Kermit binary (or you can store a
- copy of the C-Kermit binary under the name "ftp"). When C-Kermit is
- invoked with a program name of "ftp" (or "FTP", case doesn't matter),
- it assumes the command-line personality of the regular FTP client:
-
- ftp [ options ] hostname [ port ]
-
- In this case the options are like those of a regular FTP client:
-
- -d Debug: enables debug messages and creates a debug.log file.
- -n No autologin: Kermit should not send your user ID automatically.
- -t Packet trace: accepted but is treated the same as -d.
- -v Verbose: accepted but ignored (operation is verbose by default).
- -i Not interactive: accepted but ignored.
-
- and the hostname can also be a URL (explained in [219]Section 3.1.3).
- To specify a non-default TCP port for the FTP server, include the port
- number or name after the hostname.
-
- There are also some bonus options that allow you to execute an entire
- FTP session from the shell command line, as long as you don't include
- the -n option. These are not available with regular FTP clients, and
- at least one of these options (-g) conflicts with UNIX ftp (where -g
- means "no globbing", which does not apply to Kermit), and some of them
- (like the options above) also conflict with regular Kermit
- command-line options:
-
- -m mode = "passive" (default) or "active"
- -Y Don't execute the Kermit initialization file [1]
- -q Quiet, suppresses all but error messages [1]
- -S Stay, don't exit automatically [1]
- -A Autologin anonymously [2]
- -u name Username for autologin [2] (synonym: -M [1])
- -P password Password for autologin (see cautions below) [2]
- -D directory cd after autologin [2]
- -b Binary mode [2]
- -a Text ("ascii") mode [2] (synonym: -T [1])
- -R Recursive (works with -p) [4]
- -p files Files to put (upload) after autologin [2] (synonym: -s [1])
- -g files Files to get (download) after autologin [3]
-
- [1] Same as Kermit, not available in regular FTP clients.
- [2] Conflicts with Kermit, not available in regular FTP clients.
- [3] Same as Kermit, conflicts with regular FTP clients.
- [4] Conflicts with Kermit, available in some FTP clients.
-
- Fancier options such as restart, character-set translation, filename
- collision selection, automatic move/rename/delete, etc, are not
- available from the command line; for these you can use the commands
- described in the following sections. The -R option might also work
- with -g (GET) but that depends on the server.
-
- The following security options are also available, explained in
- [220]Section 3.2:
-
- -k realm Kerberos 4 realm [4]
- -f Kerberos 5 credentials forwarding [4]
- -x autoencryption mode [4]
- -c cipher SRP cipher type [4]
- -H hash SRP encryption hash [4]
- -z option Security options [4]
-
- If you include -A or specify a name of "anonymous" or "ftp", you are
- logged in anonymously and, in the absence of -P, Kermit automatically
- supplies a password of "user@host", where "user" is your local user
- ID, and "host" is the hostname of the computer where Kermit is
- running. If you do not include -p or -g, Kermit enters command mode so
- you can type commands or execute them from a script.
-
- If you include -p or -g, Kermit attempts to transfer the specified
- files and then exits automatically at the end of the transfer unless
- you also included -S (Stay). It uses the "brief" file transfer display
- (one line per file) unless you include the -q option to suppress it.
-
- When uploading files with -p, Kermit switches automatically between
- text and binary mode for each file.
-
- When downloading, you can either specify a particular mode (text or
- binary) to be used for all the files, or you can let Kermit select the
- type for each file automatically, based on its name (see [221]Sections
- 3.5 and [222]3.6 for greater detail). In UNIX be sure to quote any
- wildcard characters to prevent the shell from expanding them, as shown
- in the examples just below. Filename collisions are handled according
- Kermit's FILE COLLISION setting (if specified in your Kermit
- customization file; otherwise the default, which is BACKUP).
-
- It should go without saying that the -P option should be used with
- caution. In addition to the well-known risks of transmitting plaintext
- passwords over the Internet, in this case the password also echos to
- the screen if you type it, and can be seen in ps and w listings that
- show the user's currently active command and command-line arguments.
- Thus command-line FTP sessions are most appropriate for secure or
- anonymous connections (those that do not require passwords).
-
- Here's an example in which you download the latest C-Kermit "tarball"
- from the Columbia University FTP archive:
-
- ftp -A kermit.columbia.edu -bg kermit/archives/ckermit.tar.gz
-
- This assumes that "ftp" is a symbolic link to C-Kermit. It logs you in
- anonymously and gets the ckermit.tar.gz file in binary mode from the
- kermit/archives directory.
-
- Here's a slightly more ambitious example that illustrates CD'ing to
- the desired server directory to get a group of files in text mode (in
- this case the C-Kermit source files):
-
- ftp -A kermit.columbia.edu -D kermit/f -ag "ck[cuw]*.[cwh]" makefile
-
- In this case we CD to the kermit/f directory so we don't have to
- include it in each file specification, and we quote the ck[cuw]*.[cwh]
- specification so the shell doesn't expand it, since we have to pass it
- as-is to the server. Note also that the quotes don't go around the
- entire file list; only around each file specification that needs to be
- quoted.
-
- Here's one more example, that uploads a debug log file in binary mode
- to the Kermit incoming directory (as we might ask you to do when
- following up on a problem report):
-
- ftp -A kermit.columbia.edu -D kermit/incoming -bp debug.log
-
- In this case the -D option is required to tell the server where to put
- the incoming file.
-
- Unless the -Y option is included, your Kermit initialization file
- (.mykermrc in UNIX, K95.INI in Windows) is executed before the command
- line options, so you can set any FTP-related preferences there, as
- described in the subsequent sections.
- _________________________________________________________________
-
- 3.1.3. The FTP URL Interpreter
-
- If Kermit is invoked with either its regular personality (as "kermit")
- or its FTP personality (as "ftp"), you can also give a URL
- (Universal Resource Locator) instead of a hostname and options,
- with or without a username and password:
- ftp ftp://user:password@host/path
- ftp ftp://user@host/path
- ftp ftp://@host/path (or ftp://:@host/path)
- ftp ftp://host/path
- kermit ftp://host/path
-
- If the FTP personality is used, the service must be "ftp". In all
- cases, a hostname or address must be included. If a user is included
- but no password, you are prompted for the password. If a path
- (filename) is included:
- * If "@" is included without a user, Kermit prompts for the username
- and password.
- * If no user and no "@" are included, "anonymous" is used.
- * GET is assumed.
-
- If no path (and no action options) are included, an interactive FTP
- session is started, as in this example:
- ftp ftp://kermit.columbia.edu
-
- If a path is included, but a username is not included, "anonymous" is
- used and an appropriate user@host password is supplied automatically.
- If authentication is successful, Kermit attempts to GET the file
- indicated by the path or, if the path is the name of a directory, it
- asks the server for a directory listing. In both cases, Kermit
- disconnects from the server and exits after the operation is complete
- (unless you have included the -S option on the command line).
-
- Here's an example that gets a listing of the Kermit directory at the
- Kermit ftp site:
- ftp ftp://kermit.columbia.edu/kermit/
-
- This example gets the top-level READ.ME file from the same directory:
- ftp ftp://kermit.columbia.edu/kermit/READ.ME
-
- Here's the same example, but requesting a text-mode transfer:
- ftp -T ftp://kermit.columbia.edu/kermit/READ.ME
- This illustrates that you can mix command-line options and URLs
- if you desire.
-
- Here's an example that logs in as a (fictitious) real user to get a
- file:
- ftp ftp://olga@ftp.xyzcorp.com/resume.txt
- The password is not included, so Kermit prompts for it.
-
- This scheme allows Kermit to be used as the FTP helper of other
- applications, such as Web browsers, with all its advantages over other
- FTP clients (especially the ones that are built in to most Web
- browsers), e.g. that it can be given wildcards, and it can pick text
- and binary mode automatically for each file.
-
- HINT: suppose somebody sends you an FTP URL in email, or you see it in
- some text. If your terminal screen supports copy/paste, copy the url,
- and then at the shell prompt type "kermit", a space, and then paste
- the URL, e.g.:
-
- $ kermit ftp://alpha.greenie.net/pub/mgetty/source/1.1/mgetty1.1.27-O
-
- "$ is the shell prompt; the part you type is underlined, the rest is
- pasted in. Kermit does the rest.
- _________________________________________________________________
-
- 3.1.4. Interactive FTP Session Establishment
-
- As you read this and the following sections, bear in mind that any
- command that can be given at the prompt can also be used in a script
- program. Kermit's script programming language is the same as its
- interactive command language. [223]CLICK HERE if you would like to
- learn a bit more about script writing.
-
- An FTP session is established with the FTP OPEN command:
-
- FTP [ OPEN ] [ { /SSL, /TLS } ] hostname [ switches ] [ port ]
- Opens an FTP connection to the given host on the given port
- and, if FTP AUTOLOGIN is ON, also logs you in to the server,
- prompting for username and password if necessary. If no port is
- specified, the regular FTP protocol port (21) is used. The OPEN
- keyword is optional (unless the hostname conflicts with one of
- the FTP command keywords, which you can list by typing "ftp
- ?").
-
- The hostname can be an IP host name, numeric IP address, or if you
- have a network directory active (SET NETWORK DIRECTORY; see Chapter 6
- of [224]Using C-Kermit), an entry name in the directory. In the latter
- case, if the given hostname matches exactly one entry, the associated
- name or address is used; if it matches more than one, Kermit cycles
- through them until one is found that can be opened; if it matches
- none, then the hostname is used as-is. If a directory is active but
- you want to bypass directory lookup, include an "=" sign at the
- beginning of the hostname, and/or use a numeric IP address.
-
- When an FTP connection is opened, the default file-transfer mode is
- set to binary if the client and server platforms are alike (e.g. both
- of them are some kind of UNIX), and to text ("ascii") if they are not
- alike. This has no particular effect for uploading since Kermit
- automatically switches between text and binary mode for each file, but
- might be important for downloading. The connection is also set to
- Stream mode and File structure. Record- or page-oriented file
- transfers are not supported by C-Kermit's FTP client.
-
- The optional FTP OPEN switches are:
-
- /ANONYMOUS
- Logs you in anonymously, automatically supplying username
- "anonymous" and user@host as the password, based on your local
- user and host names.
-
- /NOLOGIN
-
- Overrides SET FTP AUTOLOGIN ON for this connection only.
-
- /USER:name
- Uses the given username to log you in, thus avoiding the Name:
- prompt.
- Overrides SET FTP AUTOLOGIN OFF for this connection only.
-
- /PASSWORD:text
- Uses the given text as your password, thus avoiding the
- Password: prompt. This switch is not recommended for use in
- script files, which would be a security risk.
-
- /ACCOUNT:text
- Uses the given text as your account (or secondary password,
- depending on the requirements of the server; most servers do
- not require or accept an account name). If an account is not
- supplied, you are not prompted for one.
-
- /PASSIVE
- Opens the connection in passive mode. Passive mode is the
- default in Kermit's FTP client, unlike in most others, since it
- works better through firewalls. The /PASSIVE and /ACTIVE
- switches apply only to the connection that is being opened, and
- do not affect the global FTP PASSIVE-MODE setting.
-
- /ACTIVE
- Opens the connection in active mode. Use this switch if the
- server does not support passive mode, or use the command SET
- FTP PASSIVE-MODE OFF.
-
- /NOINIT
- Added in C-Kermit 8.0.201. Tells C-Kermit not to send REST,
- STRU, FEAT, and MODE commands to the server when the connection
- is opened, since these have been reported to cause confusion in
- certain servers.
-
- When a username or password is missing, a prompt is issued at the
- controlling terminal and you must type the response; the response can
- not be scripted. Use the switches to avoid prompts, or one of the
- secure authentication methods described in the next section, or see
- [225]SET FTP AUTOLOGIN and the [226]FTP USER and similar commands
- described later in this section.
-
- Examples:
-
- ftp open kermit.columbia.edu /anonymous ; Open and log in anonymously
- ftp kermit.columbia.edu /anonymous ; The OPEN keyword can be omitted
- ftp xyzcorp.com ; Open and maybe prompt for username
- ftp xyzcorp.com /user:olga ; Open and log in as olga
- ftp testing.abccorp.com 449 ; Specify a special TCP port number
- ftp testing.abccorp.com /user:olaf /password:secret 449
-
- The FTP OPEN command succeeds if a connection was opened to the server
- (even if the given username and password were not valid) and fails
- otherwise (see [227]Section 3.8 for details).
-
- When your FTP session is complete, you can terminate it as follows:
-
- FTP BYE
- Closes the FTP connection if one was open. The FTP prefix can
- be omitted if no other connection is open at the same time (see
- [228]Section 3.8 for details). If a connection log is active,
- an FTP record is written to it. If Kermit was started with the
- -9 command-line option or with its FTP command-line
- personality, and the -S (Stay) option was not given, AND there
- is no other active connection, the FTP BYE command also exits,
- just as it does on a regular FTP client. Synonyms: FTP CLOSE,
- FTP QUIT (but if the FTP prefix is omitted from QUIT, this
- becomes the regular Kermit QUIT command, which is equivalent to
- EXIT; i.e. it closes the connection and exits from Kermit).
-
- The following commands can be used to achieve greater control over the
- connection and login process:
-
- SET FTP ANONYMOUS-PASSWORD text
- Allows you to choose the password text to be sent automatically
- by Kermit when you open an FTP connection with the /ANONYMOUS
- switch.
-
- SET FTP AUTOLOGIN { ON, OFF }
- If you give this command prior to opening an FTP connection, it
- controls whether Kermit tries to log you in automatically as
- part of the connection process. Normally ON, which means the
- username and password are sent automatically (and prompted for
- if they are not yet known). When OFF, FTP OPEN connects to the
- server without logging in. OFF is equivalent to the -n
- command-line option when using Kermit's FTP command-line
- personality.
-
- FTP USER name [ password [ account ] ]
- Used to log in to an FTP server to which a connection has been
- made without autologin, or when autologin failed. If the
- password is furnished on the command line, it is used;
- otherwise you are prompted for a password. An account may also
- be furnished if required by the server; it is not required by
- Kermit and is not prompted for if omitted. Synonyms: USER, FTP
- LOGIN.
-
- FTP ACCOUNT text
- Sends an account name to a server that supports accounts. If
- the server does not support accounts, an error response occurs.
- If the server does support accounts, the account is accepted if
- it is valid and rejected if it is not. The account might be
- used for charging purposes or it might be a secondary password,
- or it might be used for any other purpose, such as an access
- password for a particular disk. Servers that support accounts
- might or might not allow or require the account to be sent
- prior to login; usually it is sent after login, if at all.
- Synonym: ACCOUNT.
-
- Example:
-
-set ftp autologin off ; One thing at a time please
-ftp xyzcorp.com ; Try to make the connection
-if fail exit 1 FTP connection failed ; Check that it was made
-ftp user olga secret ; Now log in to the server
-if fail exit 1 FTP login failed ; Check that it worked
-ftp account 103896854 ; Login OK - send account
-if fail echo WARNING - FTP ACCT failed ; Warn if problem
-... ; (have session here)
-bye ; Log out and disconnect
-
- The following commands are used to control or get information about
- the FTP connection. Any particular FTP server does not necessarily
- support all of them.
-
- FTP RESET
- Terminates a user session but leaves the connection open,
- allowing a new login via FTP USER.
-
- FTP IDLE [ number ]
- Most FTP servers automatically log you out and and disconnect
- your session if there has been no activity for a certain amount
- of time. Use this command to ask the server to set its idle
- limit to the given number of seconds. Omit the number to ask
- the server to inform you of its current idle limit.
-
- FTP STATUS [ filename ]
- Asks the FTP server to send information about the current
- session. The result is a free-format report that might include
- server identification, username and login time, FTP protocol
- settings, and file-transfer statistics. If a filename is given,
- the server is supposed to send detailed information about the
- file.
-
- FTP SYSTEM
- Asks the FTP server to identify its operating system (Listed in
- Internet Assigned Numbers, Operating System Names). Examples:
- UNIX, VMS, VM/CMS, WINDOWS-NT. Unfortunately many variations
- are allowed (e.g. LINUX-2.0, LINUX-2.2, FREEBSD, ULTRIX, etc,
- instead of UNIX; WINDOWS-NT-3, WINDOWS-NT-3.5, WINDOWS-NT-3.51,
- WINDOWS-NT-4, etc). The report might also include other
- information like "Type L8", "Type I", or "Type A", indicating
- the file-transfer mode.
-
- FTP HELP [ keyword [ keyword [ ... ] ]
- Asks the server to list the commands it supports. The response
- is usually cryptic, listing FTP command mnemonics, not the
- commands used by the client (since the server has no way of
- knowing anything about the client's user interface). For
- example, the PUT command is STOR in FTP protocol. If a keyword
- is given, which should be an FTP protocol command,
- slightly-more- detailed help is given about the corresponding
- command (if the FTP server supports this feature). Examples:
- "ftp help", "ftp help stor".
-
- FTP SITE text
- (Advanced) Sends an FTP SITE (site-specific) command. Usually
- this means that the FTP server is asked to run an external
- command with the given arguments. You might be able to find out
- what SITE commands are available by sending "ftp help site" to
- the server, but in general the availability of and response to
- SITE commands is (not surprisingly) site specific.
-
- FTP QUOTE text
- (Advanced) Sends an FTP command in FTP protocol format. Use
- this command to send commands to the server that the FTP client
- might not know about.
-
- SHOW FTP
- Lists client (Kermit) FTP settings and information. Also SHOW
- CONNECTION, SHOW COMMUNICATIONS.
-
- HELP FTP [ keyword ]
- Asks Kermit to list and describe its built-in FTP commands.
-
- HELP SET FTP [ keyword ]
- Asks Kermit to list and describe its built-in SET FTP commands.
-
- [ [229]Top ] [ [230]FTP Top ] [ [231]C-Kermit Home ] [ [232]Kermit
- Home ]
- _________________________________________________________________
-
- 3.2. Making Secure FTP Connections
-
- Also see: [233]Accessing IBM Information Exchange with Kermit.
-
- In the previous section, you can see several examples of traditional
- insecure authentication: username and password sent across the network
- in clear text. Of course this is bad practice on at least two counts:
- (1) storing passwords in files (such as script files) gives access to
- the target systems to anybody who can obtain read access to your
- scripts; and (2) sending this information over the network leaves it
- open to interception by network sniffers or compromised hosts.
-
- Because of the increasing need for security on the Internet, FTP
- servers are beginning to appear that offer secure forms of
- authentication, in which no information is sent over the network that
- would allow anyone who intercepts it to usurp your identity and gain
- your access rights.
-
- Kermit provides an equivalent form of FTP security for each type of
- IETF standard security implemented in Telnet. These include
- GSSAPI-KERBEROS5, KERBEROS4, Secure Remote Password (SRP), and
- Transport Layer Security (SSL and TLS). It does not presently include
- SSL tunneling nor any form of SSH v1 or v2. When Kermit is built with
- the necessary libraries, secure FTP connections are attempted by
- default, in which all connections are authenticated and the command
- and data channels are private.
-
- The use of authentication and encryption for FTP connections can be
- adjusted with the commands listed below, which are available only if
- your version of Kermit was built with the corresponding security
- options and libraries:
-
- SET FTP AUTHTYPE { AUTOMATIC, GSSAPI-KRB5, KERBEROS4, SRP, SSL, TLS }
- Specifies an ordered list of authentication methods to be
- attempted when AUTOAUTHENTICATION is ON. The default list is:
- GSSAPI-KRB5, SRP, KERBEROS_V4, TLS, SSL. If none of the
- selected methods are supported by the server, an insecure login
- is used as a fallback. Note, by the way, that SSL or TLS can be
- used to secure an anonymous connection.
-
- SET FTP AUTOAUTHENTICATION { ON, OFF }
- Tells whether authentication should be negotiated by the FTP
- OPEN command. Default is ON. Use SET FTP AUTOAUTHENTICATION OFF
- to force a clear-text, unencrypted connection to FTP servers
- (such as the one at the Kermit FTP site) that normally would
- try to negotiate secure authentication and encryption.
-
- SET FTP AUTOENCRYPTION { ON, OFF }
- Tells whether encryption (privacy) should be negotiated by the
- FTP OPEN command, which can happen only if secure
- authentication is also negotiated. Default is ON.
-
- SET FTP AUTOLOGIN { ON, OFF }
- Tells Kermit whether to try logging in automatically when you
- make an FTP connection, as opposed to letting you do it "by
- hand" with the FTP USER command.
-
- SET FTP COMMAND-PROTECTION-LEVEL { CLEAR, CONFIDENTIAL, PRIVATE, SAFE
- }
- Determines the level of protection applied to the command
- channel:
-
- CLEAR Data is sent in plaintext and not protected against tampering.
- CONFIDENTIAL Data is encrypted but not protected against tampering.
- PRIVATE Data is encrypted and is protected against tampering.
- SAFE Data is sent in plaintext but protected against tampering.
-
- The default is PRIVATE.
-
- SET FTP CREDENTIAL-FORWARDING { ON, OFF }
- Tells whether end-user credentials are to be forwarded to the
- server if supported by the authentication method (GSSAPI-KRB5
- only). This is often required to allow access to distributed
- file systems (e.g. AFS.)
-
- SET FTP DATA-PROTECTION-LEVEL { CLEAR, CONFIDENTIAL, PRIVATE, SAFE }
- Tells what level of protection is applied to subsequent data
- channels. The meanings of the protection-level keywords are the
- same as for SET FTP COMMAND-PROTECTION-LEVEL. The default is
- PRIVATE.
-
- SET FTP SRP CIPHER name
- Specifies the cipher to be used for encryption when SRP
- authentication is in use. The list of possible choices is
- computed based on the capabilities of the local SRP library and
- includes NONE plus zero or more of the following:
-
- BLOWFISH_ECB CAST5_ECB DES_ECB DES3_ECB
- BLOWFISH_CBC CAST5_CBC DES_CBC DES3_CBC
- BLOWFISH_CFB64 CAST5_CFB64 DES_CFB64 DES3_CFB64
- BLOWFISH_OFB64 CAST5_OFB64 DES_OFB64 DES3_OFB64
-
- The default is DES3_ECB.
-
- SET FTP SRP HASH name
- Specifies the hash to be used for data protection when SRP
- authentication is in use. The choices are MD5 and SHA. The
- default is SHA.
-
- Command-line options:
-
- -k name
- Specifies the realm to be used with Kerberos 4 authentication
- (= SET AUTH K4 REALM name).
-
- -f
- Enables forwarding of Kerberos 5 credentials to the host when
- using GSSAPI authentication (= SET AUTH K5 FORWARDABLE ON).
-
- -x
- Enables autoencryption (= SET FTP AUTOENCRYPTION ON).
-
- -c cipher
- Specifies the kind of cipher to be used for encryption with SRP
- authentication. Equivalent to SET FTP SRP CIPHER, with the same
- choices. If this option is not given, CAST5_CBC is used.
-
- -H hash
- Specifies the hash to be used for encryption with SRP
- authentication. Equivalent to SET FTP SRP HASH, with the same
- choices. If this option is not given, SHA is used.
-
- -z debug
- Turns on SSL/TLS debugging.
-
- -z secure
- Requires secure connection.
-
- -z certsok
- Says to accept all certificates without checking validity.
-
- -z verify=n
- Sets certificate verification mode to the given number, n:
- 0 = no verification
- 1 = verify certificate if presented
- 2 = require verification of certificate
-
- -z cert=filename
- Specifies a file containing a client certificate to be
- presented to the FTP server.
-
- -z key=filename
- Specifies a file containing a private key matching the client
- certificate.
-
- -z !krb4
- (nokrb4) Disables the use of Kerberos 4.
-
- -z !gss
- -z nogss
- Disables the use of GSSAPI - Kerberos 5.
-
- -z !srp
- -z nosrp
- Disables use of SRP.
-
- -z !ssl
- -z nossl
- Disables the use of SSL.
-
- -z !tls
- -z notls
- Disables the use of TLS.
-
- Caution: If your FTP connection is secured via AUTH TLS, it is not
- possible to interrupt a file transfer. This is a limitation of all
- known FTP servers that support AUTH TLS.
-
- Note that when using certain security methods, such as SSL or TLS, you
- may be prompted to confirm or verify certain actions or conditions,
- for example, whether to accept self-signed certificates. This can
- interfere with unattended operation of scripts; see [234]Section 3.10.
-
- [ [235]Top ] [ [236]FTP Top ] [ [237]C-Kermit Home ] [ [238]Kermit
- Home ]
- _________________________________________________________________
-
- 3.3. Setting FTP Preferences FTP preferences can be set globally and
- persistently with the commands in the following sections; many of
- these can also be overridden on a per-command basis with switches that
- have the same name.
-
- 3.3.1. Logs, Messages, and Other Feedback
-
- You can control the amount of feedback received from your FTP session
- with the commands in this section. First, you can create a log of your
- FTP transfers with the following commands:
-
- SET TRANSACTION-LOG { VERBOSE, FTP, BRIEF }
- Selects the log format. VERBOSE is the default, and is
- described in [239]the manual. FTP chooses a WU-FTPD format, the
- same as is used by the popular FTP server. BRIEF creates
- per-file records in comma-separated-list format. For greater
- detail, see [240]Section 4.17 of the [241]C-Kermit 7.0 Update
- Notes.
-
- LOG TRANSACTIONS filename
- Records FTP (or Kermit, or any other protocol) uploads and
- downloads in the given file using the format selected by the
- most recent SET TRANSACTION-LOG command, if any, or else the
- default format.
-
- FTP screen messages and displays are controlled by the following
- commands:
-
- SET TRANSFER DISPLAY { FULLSCREEN, CRT, SERIAL, BRIEF, NONE, OFF }
- FTP transfers use Kermit's normal file-transfer display styles.
- Use this command to choose the desired format; the default on
- most platforms is FULLSCREEN. The display is automatically
- disabled if Kermit is running in the background or in batch.
- BRIEF is always used for command-line initiated transfers
- (unless suppressed by -q). While a file-transfer is in
- progress, you can interrupt it in the normal Kermit way by
- typing one of the following keys or key combinations:
- X - Cancel current file but go on to the next one (if any).
- Z - Cancel the entire transfer. Ctrl-L or Ctrl-W - Refresh
- the file-transfer display (if any).
-
- SET FTP DISPLAY { FULLSCREEN, CRT, SERIAL, BRIEF, NONE, OFF }
- Like SET TRANSFER DISPLAY, but applies only to FTP connections,
- and does not affect Kermit- or other protocol file transfers.
-
- SET QUIET { ON, OFF }
- This command applies to Kermit in general, not just FTP. OFF by
- default; when ON, it surpresses most messages from most
- commands as well as the file-transfer display.
-
- SET FTP PROGRESS-MESSAGES { ON, OFF }
- Tells whether Kermit should print locally-generated feedback
- messages for each non-file-transfer command. ON by default.
-
- SET FTP VERBOSE-MODE { ON, OFF }
- Tells whether to display all responses from the FTP server. OFF
- by default. This shows all responses to all commands, except
- when the file-transfer display is active, and unless you have
- SET QUIET ON. When OFF, responses are shown only for commands
- such as FTP PWD whose purpose is to display a response.
-
- SET FTP DEBUG { ON, OFF }
- Tells whether local client debugging information should be
- displayed. OFF by default. When ON, the commands that are sent
- to the server are shown, as well as its responses (even if
- VERBOSE-MODE is OFF), plus additional informational messages
- are printed regarding the progress of secure operations. Also,
- the temporary file created by the [242]MGET command is not
- deleted so you can see what's in it.
-
- Set all of these to OFF when silent running is desired.
-
- 3.3.2. Operational Preferences
-
- FTP DISABLE new-protocol-feature-name
- FTP ENABLE new-protocol-feature-name
- Explained in [243]Section 3.11.
-
- SET FTP AUTOLOGIN { ON, OFF }
- If you give this command prior to opening an FTP connection, it
- controls whether Kermit tries to log you in automatically as
- part of the connection process. Normally ON, which means the
- username and password are sent automatically (and prompted for
- if they are not yet known). When OFF, FTP OPEN connects to the
- server without logging in. OFF is equivalent to the -n
- command-line option when using Kermit's FTP command-line
- personality. See [244]Section 3.1.4 for usage.
-
- SET FTP PASSIVE-MODE { ON, OFF }
- ON by default, to avoid random TCP port assignment for data
- connections, which can prevent FTP protocol from working
- through firewalls and network address translators (for more on
- these topics, see the [245]Kermit security reference. Set to
- OFF in case the FTP server does not support passive mode, or in
- case the client has problems with it (it has been observed, for
- example, that when using passive mode, the SCO XENIX 2.3.4
- TCP/IP stack hangs in the connect() call forever). Synonyms:
- PASSIVE [ ON ], PASSIVE OFF, PASV [ ON ], PASV OFF.
-
- SET FTP SEND-PORT-COMMANDS { ON, OFF }
- This command determines whether the FTP client sends a new PORT
- command to the server when accepting incoming data connections
- (as when not using passive mode.) When PASSIVE-MODE is OFF and
- SET SEND-PORT is OFF, the port that was originally specified is
- reused. This is the default behavior for normal FTP clients but
- it is not compatible with many firewalls.
-
- SET FTP CHARACTER-SET-TRANSLATION { ON, OFF }
- Whether to translate character sets when transferring files
- with FTP (explained in [246]Section 3.7). OFF by default.
-
- SET FTP SERVER-CHARACTER-SET name
- Tells Kermit the character set used by the FTP server, UTF-8 by
- default ([247]Section 3.7).
-
- SET FTP SERVER-TIME-OFFSET delta-time
- Tells Kermit to apply the given [248]delta time to file
- timestamps provided by the server for its files; for use when
- (for example) the server does not have its timezone set
- correctly.
-
- SET FTP ERROR-ACTION { PROCEED, QUIT }
- When transferring a group of files with FTP, and an error
- occurs with one of the files, Kermit normally goes on the next
- file. Use SET FTP ERROR-ACTION to QUIT to make Kermit stop the
- transfer immediately and fail if an error occurs with any
- single file in the group. Example: you have given Kermit a list
- of files to send, and one of the files can not be found, or
- read permission is denied. Note that cancelling a file by
- typing 'X' during transfer is not considered an error (if you
- want to cancel the entire transfer, type 'Z' or Ctrl-C).
-
- SET FTP PERMISSIONS { AUTO, ON, OFF }
- When uploading files with PUT or MPUT, this tells whether
- Kermit should send each file's permissions. The default is OFF,
- which means not to send permissions, in which case the uploaded
- file's permissions are set by the FTP server according to its
- own criteria. ON means to send them, AUTO means to send them
- only if the client (Kermit) and server are on like platforms
- (e.g. both UNIX). This command has no effect when downloading,
- since the FTP protocol does not include a way for the server to
- inform the client of a file's permissions. Also see [249]FTP
- PUT /PERMISSIONS. Note that setting permissions after uploading
- is likely to work (correctly or at all) only when the client
- and server platforms are alike (e.g. both of them are some form
- of UNIX). Also note that Windows files don't have permissions.
- Also see [250]FTP CHMOD.
-
- SET FTP DATES { ON, OFF }
- When downloading files with GET or MGET, this tells whether
- Kermit should try to set the received file's date from the
- server's date. FTP DATES is ON by default. Note, however, that
- FTP protocol does not allow date preservation when uploading.
- So at best, SET FTP DATES ON can work only when downloading,
- and then only when the server agrees to furnish file dates.
-
- SET FTP FILENAMES { AUTO, CONVERTED, LITERAL }
- When uploading (sending) files, this tells whether to convert
- outbound filenames to "common form". This means allowing only
- one period in a name, uppercasing any lowercase letters,
- replacing spaces by underscores, etc. AUTOMATIC is the default,
- meaning LITERAL when client and server are the same type of
- system (e.g. UNIX) and CONVERTED otherwise. Special case: if
- the setting is AUTOMATIC and the client is not UNIX and the
- server identifies itself as UNIX, Kermit uses a less-strict
- form of conversion, in which lowercase letters are not
- uppercased and the filename can contain any number of periods,
- but spaces are still converted to underscore. When receiving,
- conversion generally means to change all-uppercase names to
- lowercase and spaces to underscore.
-
- SET FTP UNIQUE-SERVER-NAMES { ON, OFF }
- Applies only to uploads. Tells the server to create new, unique
- names for incoming files that have the same names as existing
- files. OFF by default, in which case the server overwrites
- existing files with new files of the same name. When ON, the
- server uses its own built-in method for creating new names for
- incoming files; for example, appending a period (.) and a
- number to the name. CAUTION: Use this option only if you do not
- need to refer to the file after it is uploaded, since FTP
- protocol provides no mechanism for the client to find out what
- name was assigned by the server.
-
- SET FTP COLLISION { ... }
- When downloading, what to do if an incoming file has the same
- name as an existing file. Options are the same as for SET FILE
- COLLISION. If this command is not given, Kermit's regular FILE
- COLLISION setting is used. If this command is given, it
- overrides the FILE COLLISION setting for FTP transfers only.
- See [251]Section 3.6.2 for details.
-
- SET FTP TYPE { TEXT, BINARY, TENEX }
- Changes the default transfer mode. When sending (uploading)
- files, this command has no effect unless you disable automatic
- text/binary mode switching ([252]Section 4) with SET FILE SCAN
- OFF or SET TRANSFER MODE MANUAL. When receiving (downloading)
- files, this command establishes the transfer mode to be used
- when a filename does not match any of Kermit's text or binary
- filename patterns, unless you use SET FTP
- GET-FILETYPE-SWITCHING or SET TRANSFER MODE MANUAL to disable
- automatic switching, in which case, this command establishes
- the transfer mode for all downloaded files. In all cases,
- however, the FTP TYPE can be overridden in any GET or PUT
- command by including a /TEXT (/ASCII), /BINARY, or /TENEX
- switch. The FTP TYPE is independent of the Kermit FILE TYPE
- setting. TENEX is used for sending 8-bit binary files to 36-bit
- platforms such as TOPS-10, TOPS-20, and TENEX, and getting them
- back again. Synonym: ASCII = TEXT. Note: there is also an FTP
- TYPE command, which does what SET FTP TYPE does but also sends
- a TYPE command to the server immediately if the given type is
- different from the current one.
-
- If you want want specific FTP preference settings to be in effect for
- all your Kermit FTP sessions, put the desired SET FTP commands in your
- Kermit customization file (~/.mykermrc in UNIX, K95CUSTOM.INI in
- Windows).
-
- [ [253]Top ] [ [254]FTP Top ] [ [255]C-Kermit Home ] [ [256]Kermit
- Home ]
- _________________________________________________________________
-
- 3.4. Managing Directories and Files
-
- In Kermit, commands for directory and file management can refer to:
-
- * The local computer
- * A remote computer when you have a connection to a Kermit server or
- IKSD.
- * A remote computer when you have a connection to an FTP server.
-
- (There can also be an HTTP connection, but the commands in this
- section don't apply to HTTP connections.)
-
- Thus in general, each such command comes in three forms:
-
- 1. With no prefix in C-Kermit 8.0.200, it refers to the local
- computer (CD, DIR, etc). In C-Kermit 8.0.201 and later, however,
- the "locus" switches to automatically to the remote FTP server
- when you make an FTP connection (see the SET LOCUS description
- [257]Section 7); thus C-Kermit 8.0.201 acts almost exactly like a
- regular FTP client when it has an FTP connection, yet still acts
- like itself on other kinds of connections.
- 2. With the REMOTE prefix, it is for a Kermit server (REMOTE CD,
- REMOTE DIR).
- 3. With the FTP prefix, it's for an FTP server (FTP CD, FTP DIR).
- 4. Also see [258]Section 3.8, which explains "R-commands" and
- "L-commands".
-
- Kermit's FTP file and directory management commands are as follows.
- When an R-command is included in the Synonyms list, be sure to read
- [259]Section 3.8 about rules for use of R-commands.
-
- FTP CD [ directory ]
- Tells the FTP server to change its default (working) directory
- to the one given, which usually must be expressed in the syntax
- of the server platform (UNIX, VMS, etc). If the directory is
- not specified, the result depends on the FTP server -- it might
- complain that the command is illegal, or it might change to
- your original login directory. Synonyms: FTP CWD (Change
- Wording Directory); RCD.
-
- FTP CDUP
- Tells the FTP server to change its default (working) directory
- to the parent directory of its current one (equivalent to
- "cd .." in UNIX, or "cd [-]" in VMS). Synonyms: RCDUP, FTP UP.
-
- FTP PWD
- Asks the FTP server to report ("print") its current working
- directory. Synonym: RPWD.
-
- FTP MKDIR directory
- Asks the FTP server to create the directory whose name is
- given. In general, the name must be in the syntax of the
- server's file system, and it must be either absolute (a full
- pathname) or relative to the server's current (working)
- directory. This command fails if the directory can't be created
- for any reason, including that it exists already. Synonym:
- RMKDIR.
-
- FTP RMDIR directory
- Asks the FTP server to remove the directory whose name is
- given. The rules are the same as for MKDIR, plus in most cases,
- the server will not remove any directory unless it is empty.
- Synonym: RRMDIR.
-
- FTP DIRECTORY [ filespec ] [ redirectors ]
- Tells the FTP server to send a directory listing of the
- specified files. If no filespec is given, the server lists all
- files in its current working directory. The results are in
- whatever format the server chooses to send them. You can use
- UNIX-like redirectors to send the listing to a file or a
- pipeline, exactly as with the regular Kermit client/server
- REMOTE DIRECTORY command ([260]Using C-Kermit, Chapter 11).
- Synonym: RDIRECTORY. Examples:
-
- ftp dir ; Show listing of all files on screen
- ftp dir *.txt ; List *.txt files on screen
- ftp dir *.txt > somefile ; Put listing in somefile
- ftp dir *.txt >> somefile ; Append listing to somefile
- ftp dir *.txt | sort > somefile ; Put sorted listing in somefile
- ftp dir | more ; Runs list through "more"
- ftp dir | sort | more ; Runs list through "sort" and "more"
-
- FTP VDIRECTORY [ filespec ] [ redirectors ]
- "Verbose" directory. This is an alternative FTP DIRECTORY
- command primarily for use with DECSYSTEM-20 (TOPS-20) FTP
- servers, which send only filenames when given a DIRECTORY
- command; the VDIRECTORY command makes them also send file
- sizes, dates, and attributes.
-
- FTP CHECK filespec
- Asks the FTP server whether the given file exists or, if the
- filespec contains wildcards, if any files match, and this
- command succeeds or fails accordingly.
-
- FTP MODTIME filename
- Asks the FTP server, via the not-yet-standard FTP MDTM command,
- to send the modification date and time of the given file. The
- response should be a numeric string in the format:
- yyyymmddhhmmssxxxxx... where yyyy is the year, mm is the month,
- dd is the day, hh is the hour (0-23), mm is the minute, ss is
- the second, and xxx... is the optional fraction of the second
- (0 or more digits). The date and time is expressed in UTC (GMT,
- Zulu, Zero-Meridian). The result is available programmatically
- in the [261]\v(ftp_message) variable, and is understandable by
- Kermit's date-time switches and functions. For example, suppose
- we want to upload all local files that are newer than a
- particular file on the server:
-
- C-Kermit> ftp modtime signpost
- C-Kermit> echo \v(ftp_message)
- 20010807113542.014
- C-Kermit> ftp mput /after:\v(ftp_message)GMT *
-
- Note that we must append "GMT" to the date-time string to let
- the /AFTER switch know the time is GMT rather than local.
-
- FTP SIZE filename
- Asks the FTP server to send the size (in bytes) of the given
- file. The result might vary depending on whether the current
- FTP TYPE is binary or text ("ascii"). For a reliable byte
- count, do FTP TYPE BINARY first. The result is available
- programmatically in the [262]\v(ftp_message) variable.
-
- FTP CHMOD permissions filename
- Tells the FTP server to set the permissions (protection) of the
- given file to the ones given. The permissions and filename must
- be given in whatever syntax is required by the server. Example
- (for a UNIX-based FTP server):
-
- ftp chmod 664 oofa.txt
-
- Not all servers support this command. For non-UNIX-based
- servers, you might need to use FTP QUOTE or FTP SITE and the
- appropriate platform-specific FTP server command.
-
- FTP UMASK [ number ]
- This command is probably specific to UNIX-based servers; it
- sets the UNIX "umask", which is the default permissions mask
- for new (in this case, incoming) files. Crudely put, the UNIX
- umask is an octal representation of a binary number in in which
- a 1 bit stands for a permission bit that must be 0, and a 0 bit
- stands for a permission bit that can be 0 or 1 depending on
- other factors, such as the permissions of the parent directory.
- Example: "umask 007" requires that new files are created
- without read/write/execute world permission. If the number is
- not specified, the server's current umask is reported.
-
- FTP RENAME filename newname
- Asks the FTP server to rename the file whose name is "filename"
- to "newname". Works only for one file; can not be used with
- wildcards. The server's interpretation of "newname" can vary
- (in some cases it must be a filename, in others perhaps it can
- also be a directory name, in which case if the filename denote
- a regular file, the file might be moved to the given
- directory). Some servers might allow files to be renamed
- ("moved") between physical disks or partitions, others might
- not. Synonym: RRENAME.
-
- FTP DELETE [ switches ] filespec [ filespec [ ... ] ]
- Tells the FTP server to delete the file or files listed. Each
- file specification may, but need not, contain wildcard
- characters to match multiple files. File specifications and
- wildcard syntax must be those of the server. Any file
- specifications that contain spaces must be enclosed in braces
- or doublequotes. FTP DELETE switches are:
-
- /ERROR-ACTION: /FILENAMES: /NOBACKUPFILES /QUIET
- /EXCEPT: /LARGER-THAN: /NODOTFILES /NOPAGE
- /PAGE /RECURSIVE /SMALLER-THAN:
-
- When used with FTP DELETE, the /RECURSIVE switch deletes files
- but not directories, and furthermore depends on the server
- providing recursive file lists, which is not the normal
- behavior. For further details, see the decriptions of these
- switches in [263]Section 3.6. Synonyms: FTP MDELETE (Kermit
- makes no distinction between DELETE and MDELETE); RDELETE.
-
- FTP TYPE { TEXT, BINARY, TENEX }
- Tells the FTP server to change its file-transfer type to the
- one given, immediately. See [264]SET FTP TYPE for details.
-
- [ [265]Top ] [ [266]FTP Top ] [ [267]C-Kermit Home ] [ [268]Kermit
- Home ]
- _________________________________________________________________
-
- 3.5. Uploading Files With FTP
-
- Uploading means sending files from the client (Kermit) to the FTP
- server. The basic command for uploading files with FTP is PUT:
-
- FTP PUT [ switches ] [ filespec [ as-name ] ]
- Uploads (sends) the file or files that match the file
- specification, which may include wildcards, to the server. If
- no filespec is given, the names of files to send are taken from
- the /LISTFILE: file, if any, otherwise from the SEND-LIST, if
- any. Unless you go out of your way to prevent it, Kermit
- determines the transfer mode (text or binary) for each file
- automatically, and switches automatically on a per-file basis.
- If an as-name is given, the file is sent under that name
- instead of its own (if an as-name is given with a wildcard
- filespec, the result is a bit more complicated, and is
- explained later in this section).
-
- Unlike normal FTP clients, Kermit does not prompt you by default (or
- at all) for each file; it just sends them, just as it does with Kermit
- protocol. The filespec can be a literal filename or a Kermit pattern,
- described in:
-
- [269]http://www.columbia.edu/kermit/ckermit70.html#x4.9
-
- Kermit patterns are equivalent to C-Shell patterns and provide a fair
- amount of flexibility in selecting which files to send, which is
- augmented by the file-selection switches presented in [270]Section
- 3.5.1.
-
- FTP MPUT [ switches ] filespec [ filespec [ ... ] ]
- FTP MPUT is just like FTP PUT except it allows you to give more
- than one file specification, and it does not allow an as-name
- in the file list. However, as-names can be given to either PUT
- or MPUT with the /AS-NAME: switch.
-
- If a PUT or MPUT command results in one file being uploaded, it
- succeeds if the file is uploaded completely and fails otherwise. If
- more than one file is selected for upload, success or failure depends
- on the [271]FTP ERROR-ACTION setting; if it is PROCEED (the default
- setting), then the [M]PUT command succeeds if at least one of the
- files was completely uploaded, and fails otherwise, If FTP
- ERROR-ACTION is QUIT, the [M]PUT command succeeds if all selected
- files were uploaded successfully, and fails if any file failed.
-
- FTP uploads may be interrupted just like Kermit uploads. While the
- transfer is in progress, type:
-
- X to interrupt the current file and go on to the next file.
- Z to cancel the current file and all remaining files.
- ^C (Control-C): Like Z, but might act more quickly.
-
- MPUT may be used as in regular FTP clients, but it is not required to
- send multiple files; in Kermit it is required only if you want to give
- multiple file specifications. Examples:
-
- ftp put oofa.txt ; Send a single file oofa.txt
- ftp put oofa.txt budget.txt ; Send single file oofa.txt as budget.txt
- ftp put *.txt ; Send all *.txt files
- ftp mput *.txt ; Send all *.txt files (same as "put *.txt")
- ftp mput *.txt foo.bar ; Send all *.txt files plus foo.bar
-
- The distinction between PUT and MPUT is important only when more than
- one filespec is given, just like the distinction between Kermit SEND
- and MSEND:
-
- ftp put oofa.txt budget.txt ; Send oofa.txt AS budget.txt
- ftp mput oofa.txt budget.txt ; Send oofa.txt AND budget.txt
-
- If the source file specification includes any path segments, for
- example:
-
- put /tmp/oofa.txt
- put subdir/another/andanother/oofa.txt
-
- the path portion is stripped from the filename that is sent to the
- server. However, if an as-name contains a path, it is retained.
- Examples:
-
- ftp put /usr/doc/oofa.txt ; Send as "oofa.txt".
- ftp put oofa.txt /tmp/oofa.txt ; Send as "/tmp/oofa.txt"
-
- The latter example sends the file oofa.txt from your current local
- directory to the server's /tmp directory. This works only if the
- server uses the same directory notation that you used in the as-name
- AND the given directory already exists on the server AND if you have
- write access to it.
-
- Use caution when uploading from a case-sensitive file system, such as
- UNIX, to a file system that is not case sensitive, such as Windows or
- VMS. If you have two files in UNIX, AA and aa and upload both of them,
- the second one will overwrite the first. The only way around this
- provided by FTP protocol is its "unique server names" feature (SET FTP
- UNIQUE-SERVER-NAMES or the /UNIQUE switch described below).
- _________________________________________________________________
-
- 3.5.1. FTP PUT Switches
-
- FTP PUT and MPUT are similar in format and behavior to the regular
- Kermit SEND and MSEND commands, and they allow most of the same
- optional switches:
-
-C-Kermit>ftp put ? Filename, or switch, one of the following:
- /after: /larger-than: /rename-to:
- /array: /listfile: /server-character-set:
- /as-name: /local-character-set: /server-rename-to:
- /before: /move-to: /simulate
- /binary /nobackupfiles /smaller-than:
- /command /nodotfiles /tenex
- /delete /nofollowlinks /text
- /dotfiles /not-after: /transparent
- /error-action: /not-before: /type:
- /except: /permissions: /update
- /filenames: /quiet /unique-server-names
- /filter: /recover
- /followlinks /recursive
-
- Since most of these switches are common to Kermit's SEND and MSEND
- commands, they described only briefly here. For greater detail see:
-
- [272]http://www.columbia.edu/kermit/ckermit70.html#x1.5 (explanation
- of switches)
- [273]http://www.columbia.edu/kermit/ckermit70.html#x4.7
- (file-transfer switches)
-
- First the file-selection switches:
-
- /AFTER:date-time
- /BEFORE:date-time
- /NOT-AFTER:date-time
- /NOT-BEFORE:date-time
- Only send those files modified on or after or before the given
- date and time. These switches can be combined to select files
- modified between two date/times. Various date-time formats are
- accepted; if the date-time contains spaces, it must be enclosed
- in braces or doublequotes. See
- [274]http://www.columbia.edu/kermit/ckermit70.html#x1.6 and
- [275]Section 8.13 of this document for details about date-time
- formats. Examples:
-
- ftp put /after:{1 jan 2000 0:00:00} *
- ftp put /after:-5days *
-
- /LARGER-THAN:number
- /SMALLER-THAN:number
- Only send files larger (smaller) than the given number of bytes
- (octets). These switches can be combined to select files in a
- certain size range.
-
- /TYPE:{TEXT,BINARY}
- Only send files that are the given type, which is determined
- for each file just before sending it by file scanning. BINARY
- includes TENEX; if you have included a /TENEX switch, or
- previously given a [SET] FTP TYPE TENEX command, binary files
- are sent in TENEX, rather than BINARY mode.
-
- /[NO]DOTFILES
- [Don't] include files whose names begin with dot (.). By
- default, such files are not included unless your filespec
- explicitly mentions them.
-
- /NOBACKUPFILES
- Don't include files whose names end with .~nnn~, where nnn is a
- number, e.g. oofa.txt.~27~. These are backup files created by
- Kermit, EMACS, and other applications. By default, backup files
- are included.
-
- /NOFOLLOWLINKS
- (UNIX only) Skip over symbolic links rather than following them
- (default). This applies to wildcard and/or recursive [M]PUTs;
- if a single filename is given, and it happens to be a symbolic
- link, the file it points to is sent.
-
- /FOLLOWLINKS
- (UNIX only) Always follow (resolve) symbolic links, even in
- wildcard or recursive [M]PUTs. Use with caution. Watch out for
- circular links, endless loops, etc.
-
- /EXCEPT:pattern
- Exception list -- don't send files whose names match the given
- pattern. See [276]Section 1.5.4 of the [277]C-Kermit 7.0 Update
- Notes for details. If you want to exclude a directory from a
- recursive [M]PUT, use /EXCEPT:{dirname/*}.
-
- /RECURSIVE
- Sends the desired files from the current (or given) directory,
- plus all directories beneath it, including empty directories,
- replicating the directory structure on the server. No special
- capabilities are required in the server, but of course your
- login ID on the server must have the appropriate access and
- permission to create directories. Recursive PUTs work not only
- between like platforms (e.g. UNIX to UNIX) but also between
- unlike ones (e.g. UNIX to VMS or Windows), in which case
- text-file format differences are handled by Kermit's automatic
- text/binary mode switching ([278]Section 4) and character-set
- translation ([279]Section 3.7). Synonym: /SUBDIRECTORIES.
-
- /UPDATE
- Send only files that have changed since last time ([280]Section
- 3.5.2).
-
- /ARRAY:arrayname
- The "file" to be sent is an array, or a segment of one, rather
- than a real file. In this case the other selection switches
- don't apply. The array contents are sent in text mode, and each
- array element is treated as a line. Example:
-
- ftp put /as-name:array.txt /array:&a
-
- (or, to send a segment of the array, /array:&a[100:199]). If
- you don't include an /AS-NAME, a name of "_array_x_" is used
- (where x is the array letter). If you include this switch, most
- other switches are meaningless and ignored.
-
- /COMMAND
- The "file" to be sent is the standard output of a command,
- rather than a real file. It is sent in text or binary mode
- according to the prevailing FTP TYPE, which can be overridden
- with a /TEXT or /BINARY switch. Example: Example:
-
- ftp put /command /as-name:{userlist} {finger | sort -r}
-
- /LISTFILE:filename
- Tells Kermit to obtain the list of files to be sent from the
- file whose name is given. This file must contain one file
- specification (which may be wild) per line. If the list
- includes files from different directories, such as a recursive
- listing of a directory tree, the paths are recreated on the
- server (if possible) if you include the /RECURSIVE switch;
- otherwise all the files are sent to the current directory on
- the server.
-
- Now the other switches:
-
- /AS-NAME:text
- If a single file is being sent, send it with the given text as
- its name. If multiple files are being sent, the text must be a
- template that includes variables such as \v(filename),
- \v(filenumber), \v(ntime), to allow dynamic creation of each
- name. The same applies to the as-name field of the FTP PUT
- command. If this switch is not included (and an as-name is not
- included as the second filename to PUT), each file is sent with
- its own name.
-
- /BINARY
- /TEXT
- /TENEX
- Forces this upload to take place in the given mode, regardless
- of the current FTP TYPE setting, and without automatic
- text/binary switching. /ASCII is a synonym for /TEXT.
-
- /FILTER:command
- Specifies that the file(s) is/are to be passed through the
- given command or pipeline on their way to the server. Example:
-
- ftp put /binary /filter:{gzip -c \v(filename)} /as-name:\v(filename).gz *
-
- /TRANSPARENT
- /LOCAL-CHARACTER-SET:name
- /SERVER-CHARACTER-SET:name
- Character-set translation for text files, explained in
- [281]Section 3.7.
-
- /ERROR-ACTION:{PROCEED,QUIT}
- Overrides the prevailing [282]FTP ERROR-ACTION for the duration
- of this PUT or MPUT command only.
-
- /RECOVER
- Resume an interrupted transfer where from the point of
- interruption (explained in [283]Section 3.5.2). Synonym:
- /RESTART.
-
- /DELETE
- Tells Kermit to delete each source file immediately after, and
- only if, it has been uploaded completely and successfully.
- This, in effect, moves the file from the client to the server.
-
- /MOVE-TO:directory
- Tells Kermit to move each source file to the named local
- directory after, and only if, it has been uploaded completely
- and successfully.
-
- /RENAME-TO:template
- Tells Kermit to rename each (local) source file according to
- the given template after, and only if, it has been uploaded
- completely and successfully. The template works as in /AS-NAME.
-
- /SERVER-RENAME-TO:template
- Tells Kermit to ask the server to rename each file according to
- the given template as soon as, and only if, it has been
- received completely and successfully. The template works as in
- /AS-NAME. Requires write and rename access on the server, so
- doesn't usually work with (e.g.) anonymous uploads to public
- incoming areas where the permissions don't allow renaming.
- Examples:
-
- ftp mput /server-rename:\v(filename).ok *
- Appends ".ok" to each filename on the server when it's
- finished uploading.
-
- ftp mput /as-name:\v(filename).tmp /server-rename:\v(filename) *
- This is the reverse of the previous example; it uses a
- temporary name while uploading is in progress and reverts
- the file to its real name when uploading is complete.
-
- ftp mput /as-name:\v(filename)
- /server-rename:../final/\v(filename) *
- Moves the file from the working directory to a final
- directory when the upload is complete, but in this case
- you have to know the pathname syntax of the server. If
- the rename fails, the [M]PUT command fails according to
- the [284]FTP ERROR-ACTION selection.
-
- /FILENAMES:{AUTOMATIC,CONVERTED,LITERAL}
- Overrides the [285]FTP FILENAMES setting for this upload only.
-
- /PERMISSIONS:{ON,OFF}
- Overrides the [286]FTP PERMISSIONS setting for this upload
- only.
-
- /UNIQUE
- Tells Kermit to tell the server to give [287]unique names to
- incoming files that would otherwise overwrite existing files
- that have the same name. This switch conflicts with /UPDATE,
- /RECOVER, /PERMISSIONS, and /SERVER-RENAME since the client has
- no way of knowing the name assigned by the server.
-
- /QUIET
- Don't display file-transfer progress or statistics.
-
- /SIMULATE
- Shows which files would be sent without actually sending them.
- Useful (for example) with /UPDATE (next section). The results
- are shown in the file-transfer display (if it is not disabled)
- and in the transaction log (if one is active). Hint: use SET
- TRANSFER DISPLAY BRIEF.
- _________________________________________________________________
-
- 3.5.2. Update Mode
-
- When you include the /UPDATE switch, this means to skip sending any
- file that already exists on the server if the local file's
- modification date/time is not later than that of the corresponding
- file on the server. Here is a typical application for update mode:
- Suppose that on Computer A, you maintain a large set of files (say, a
- collection of Web pages and graphics images, or the source files for a
- software application), and you need to keep a parallel copy on another
- Computer, B. Of course you could upload the entire collection every
- day:
-
- cd source-directory
- ftp computerb.xyzcorp.com
- ( authentication details... )
- ftp cd target-directory
- ftp put [ switches ] *
-
- But if the total size is large or the network slow, this would be
- unnecessarily time-consuming. Worse, if other users or sites had to
- update whenever new files appeared in B's directory, this would cause
- them unnecessary work. By including the /UPDATE switch:
-
- ftp put /update [ other-switches ] *
-
- only those files that changed since last time are uploaded. Here's how
- it works. For each local file that is selected for uploading:
-
- * The remote filename is determined in the normal way, according to
- the [288]FTP FILENAMES setting, /FILENAMES switch, or the as-name,
- if any.
- * Kermit sends an MDTM (modification time) command for the
- corresponding remote filename to the server.
- * If the server does not understand the MDTM command, the file is
- sent.
- * If the server can't find a file with the given name, the file is
- sent.
- * If the local file's modification time is later than that of the
- remote file, the file is sent.
- * Otherwise -- the remote file exists but its modification time is
- equal to or earlier than that of the local file -- the file is
- skipped.
-
- All time comparisons take place in Coordinated Universal Time
- (UTC)([289]1), also known as GMT or Zulu time: Timezone 0; standard
- time, without daylight savings.
-
- WARNING: Some FTP servers, such as Novell NWFTPD.NLM, ignore or
- misimplement the FTP specification and send local time rather than
- UTC.
-
- Update mode is useful only when always used in the same direction.
- When you upload (PUT) a file with FTP, the destination file receives
- the current timestamp on the server's computer, not the original
- file's timestamp ([290]2). If you try to FTP PUT /UPDATE the same file
- again, it will be skipped (as expected) since the remote copy is
- newer. However, if you try to FTP GET /UPDATE the same file
- ([291]Section 3.6), it will be transferred for the same reason.
-
- To check the availability of PUT /UPDATE on a particular connection,
- issue an FTP MODTIME command for a file that is known to exist on the
- server. If it succeeds, PUT /UPDATE should work and in that case, you
- can run a procedure like the one above every day: the first time, it
- sends all the files; after that, it sends only the ones that changed.
- If a transaction log is active, a notation is included for any files
- that are skipped.
-
- Notes:
- 1. Why is Coordinated Universal Time abbreviated UTC? From the
- [292]National Institute of Standards and Technology FAQ: "In 1970
- the Coordinated Universal Time system was devised by an
- international advisory group of technical experts within the
- International Telecommunication Union (ITU). The ITU felt it was
- best to designate a single abbreviation for use in all languages
- in order to minimize confusion. Since unanimous agreement could
- not be achieved on using either the English word order, CUT, or
- the French word order, TUC, the acronym UTC was chosen as a
- compromise."
- 2. The Kermit FTP client is unusual in that, when downloading only,
- it can set the received file's date from the file's date on the
- server, but this should not affect the update feature. When
- uploading to an FTP server, however, there is no mechanism for the
- client to set the date of the uploaded file on the server.
- _________________________________________________________________
-
- 3.5.3 Recovery
-
- Suppose that while you are uploading a large file over a slow
- connection, the connection is lost before the entire file is
- transferred. With most FTP clients, you would have to start over, thus
- resending the portion of the file that was sent already, and that is
- already on the server. But Kermit's /RECOVER switch (Synonym:
- /RESTART) lets you continue an interrupted transfer from the point of
- failure, thus transferring only the part that wasn't sent already. The
- prerequisites for recovery are:
-
- * The transfer must be in BINARY mode, or else the client and server
- must reside on like systems (e.g. both on some form of UNIX).
- * The FTP server must support the SIZE command.
-
- Here's how it works. When you include the /RECOVER switch:
-
- * Kermit checks for conflicting switches, such as /UPDATE and
- /UNIQUE; if /RECOVER is given with these switches an error occurs.
- If /RECOVER is given in other circumstances where it could serve
- no useful purpose (e.g. with arrays, pipes, or filters), it is
- ignored.
-
- If the switch is accepted, then for each selected file:
-
- * If it is not binary (determined by scanning) and the client and
- server are not on like platforms, recovery is canceled (the entire
- file is sent). Otherwise:
- * A SIZE command is sent for the file (using its remote name). If
- the reply indicates the file was not found, or the SIZE command
- was not understood, or any other kind of error, recovery is
- canceled. Otherwise:
- * A MDTM (modification time) command is sent for the file. If a
- valid reply is received, and the modification time of the local
- file is later than that of the remote file, recovery is canceled.
- Otherwise:
- * If the sizes of the two files are identical, the file is not sent.
- Otherwise:
- * Kermit seeks to the recovery spot in the local file, tells the
- server to APPEND the data which is about to arrive to the remote
- file, and then sends the data starting at the recovery point.
-
- To safeguard file integrity, recovery is not attempted unless all the
- preconditions are met. For the widest possible usefulness, APPEND is
- used rather than RESTART. For stream transfers (the only kind that
- Kermit supports) the results are the same.
-
- By design, the /RECOVER switch can be included with any FTP PUT or
- MPUT command, even if it specifies a group of files. This allows you
- to resume an interrupted batch transfer from where it left off. The
- files that were already completely sent are skipped, the file that was
- interrupted is recovered, and the remaining files are uploaded.
-
- By the way, it doesn't matter how the original partial file was
- uploaded -- FTP, Kermit, Zmodem, etc: as long as the preconditions are
- met, it can be recovered with FTP PUT /RECOVER, or for that matter
- also using Kermit protocol and SEND /RECOVER.
-
- A word of caution, however, when the original upload was in text mode
- with character-set translation ([293]Section 3.7):
-
- * If the original upload involved a translation from one single-byte
- character set to another (e.g. Code Page 850 to Latin-1), recovery
- is safe if you specify the same translations for the recovery. If
- you don't, the resulting file will contain a mixture of character
- sets.
- * If the original upload involved a translation that changed the
- size of the file (e.g. from an alphabetic Code Page or Latin
- Alphabet to Unicode, or vice versa), recovery is NOT safe, even if
- you specify the same translations.
-
- Kermit has no way of knowing anything about the previous upload. As a
- safeguard, an error occurs if you include /RECOVER and also specify a
- character-set of UCS2 or UTF8, since recovery can't possibly work in
- that situation. Otherwise, it's up to you to avoid unsafe recovery
- operations.
-
- [ [294]Top ] [ [295]FTP Top ] [ [296]C-Kermit Home ] [ [297]Kermit
- Home ]
- _________________________________________________________________
-
- 3.6. Downloading Files With FTP
-
- Although uploading files with Kermit's FTP client is just as easy and
- flexible as sending files with Kermit protocol, the same is not always
- true for downloading because FTP servers lack some of the capabilities
- of a Kermit server:
-
- * If you want to get more than one file, you have to use MGET, not
- GET, since the underlying FTP protocol is different in the two
- cases. Kermit can't "autodetect" which one you mean, as it can
- with PUT and MPUT, since it can't be expected to know the wildcard
- syntax of the remote platform and/or FTP server (the same is true
- for all other FTP clients). To complicate matters, FTP protocol
- now includes two underlying mechanisms (NLST and MLSD) for
- accomplishing MGET operations and, as explained in [298]Section
- 3.11, the two behave differently.
- * Automatic text-binary mode switching is not done by the server. It
- can be done by the client (Kermit), but in this case it is not
- based on a file scan (since there is no way for Kermit prescan a
- server file), but rather on the filename, using C-Kermit 7.0
- [299]filename patterns.
- * Some options that are available with FTP PUT can not be used with
- FTP [M]GET or don't work the same way:
- /PERMISSIONS (FTP protocol has no mechanism for this).
- /[NOT-]BEFORE, /[NOT-]AFTER (because of the timezone problem).
- /RECOVER works only in binary mode. /RECURSIVE has limited
- utility.
-
- The commands for downloading are:
-
- SET FILE DOWNLOAD-DIRECTORY [ directory ]
- As with Kermit transfers, this command, if given, tells
- C-Kermit where to store incoming files in the absence of a
- specific as-name. If not given, incoming files are stored as
- indicated by the as-name, if any, otherwise in the current
- directory, just as with Kermit transfers. The more verbose
- transfer display formats give the full pathname of each
- received file, and, in case you have trouble finding a
- downloaded file afterwards, its full path is also listed in the
- transaction log (if you kept one), and you can also ask Kermit
- where it went with the [300]WHERE command.
-
- SET FTP GET-FILETYPE-SWITCHING { ON, OFF }
- ON by default, causing Kermit to switch automatically into text
- or binary mode for each file based on whether its name matches
- a text pattern or binary pattern. Set this OFF, or use a /TEXT,
- /BINARY, or /TENEX switch to defeat this feature. Use SHOW
- PATTERNS to see the current pattern list.
-
- [ FTP ] GET [ switches ] filename [ as-name ]
- Asks the server to send the given file, and if it comes, stores
- it locally under the given as-name, if any, otherwise under its
- original name (modified according to the selected filename
- conversion option), in your download directory, if you have
- specified one, otherwise in the directory indicated in the
- as-name, if any, otherwise in your current directory. If you
- accidentally use a wildcard in the filename ("get *.txt") the
- server will reply with a message like "File not found" (unless
- there is a file whose name actually is "*.txt"). If FTP
- GET-FILETYPE-SWITCHING is ON, and in the absence of any GET
- switches to override it, the file is transferred in binary mode
- if it matches any of Kermit's binary name patterns, and in text
- mode if it matches any of Kermit's text name patterns, and in
- the prevailing FTP TYPE if it matches none of these patterns.
-
- [ FTP ] MGET [ switches ] filespec [ filespec [ filespec [ ... ] ] ]
- Like GET, but for multiple files. One or more file
- specifications can be given, and any or all (or none) of them
- can contain wildcards or can be directory names. The file list
- may not include an as-name, but you can still give one with the
- /AS-NAME: switch.
-
- In both the FTP GET and MGET commands, any filenames that contain
- spaces must be enclosed in braces or doublequotes (see [301]Section 5
- for details).
-
- FTP downloads may be interrupted just like Kermit transfers. While the
- transfer is in progress, type:
-
- * X to interrupt the current file and go on to the next file.
- * Z (or Control-C) to cancel the current file and all remaining
- files.
-
- Before proceeding, a brief word about temporary files. In FTP
- protocol, the MGET command works by requesting a file list from the
- server, and then (internally) issuing a GET command (FTP RETR protocol
- directive) for each file. The file list returned by the server can be
- any size at all, so in case it is huge, we don't store it in memory;
- instead we put it in a temporary file. For troubleshooting purposes,
- you should be aware of two points:
-
- 1. The location of the temporary file is chosen according the TMP or
- TEMP environment variables. If neither of these variables is
- defined, you might need to define it. In case there is not enough
- space on the indicated disk or partition for the server's file
- list, you might need to either clean up the temporary area, or
- redefine the environment variable to indicate a different area
- that has sufficient space.
- 2. If you want to look at the list yourself, use SET FTP DEBUG ON.
- This tells Kermit to (a) give you the full pathname of the
- temporary file at the end of each MGET command, and (b) not to
- delete it, as it normally does.
- _________________________________________________________________
-
- 3.6.1. FTP GET Switches
-
- The following switches are available with FTP GET and MGET:
-
- /TEXT
- Specifies a text-mode transfer. Overrides the global FTP TYPE
- setting and filename pattern-matching for the duration of the
- current command only, All files are downloaded in text mode.
- Synonym: /ASCII.
-
- /BINARY
- Specifies a binary-mode transfer. Overrides the global FTP TYPE
- setting and filename pattern-matching for the duration of the
- current command only. All files are downloaded in binary mode.
-
- /TENEX
- Like /BINARY but specifies a special binary transfer mode to be
- used when getting 8-bit binary files from a 36-bit platform
- such as TOPS-10, TOPS-20, or TENEX. All files are downloaded in
- the special binary mode.
-
- /RECOVER
- This instructs Kermit to try to recover an incomplete download
- from the point of failure. Works only in binary mode, and only
- if the server supports the (not-yet-standard) FTP "REST"
- directive. See [302]Section 3.6.3 for details. Synonym:
- /RESTART.
-
- /FILENAMES:{CONVERTED,LITERAL}
- Overrides the [303]FTP FILENAMES (filename conversion) setting
- for this download only, forcing incoming filenames to be either
- converted or taken literally.
-
- /AS-NAME:text
- For GET, this is equivalent to giving an as-name after the
- filename. For MGET, this is the only way to specify alternative
- names for the incoming files. With MGET, the /AS-NAME text
- should (must) contain a Kermit variable, usually \v(filename)
- or \v(filenumber). Example:
-
- mget /text /as-name:\v(filename).new *.c
-
- This gets all ".c" files and stores them with "
-
- .new" appended to their names. See the [304]C-Kermit 7.0 Update
- Notes for details.
-
- /COMMAND
- This specifies that the incoming file is to be written to the
- standard input of a command, rather than to a file. The command
- name is the as-name from the GET command or the /AS-NAME
- argument. If you need to refer to the incoming file's name in
- the command, use \v(filename). See the description of the
- regular Kermit [305]GET /COMMAND command for details and
- examples.
-
- /QUIET
- Transfers the files quietly; don't put up a file-transfer
- display.
-
- /ERROR-ACTION:{QUIT,PROCEED}
- This switch affects only MGET. If an error occurs with a
- particular file, this tells whether to go on to the next file
- (PROCEED) or to stop right away and fail (QUIT). The default is
- PROCEED.
-
- The file selection switches are:
-
- /EXCEPT:{pattern} or /EXCEPT:{{pattern}{pattern}{...}}
- Exception list for MGET; skip downloading any file whose name
- matches any of the given patterns (when using the second
- format, up to 64 patterns may be specified). [306]CLICK HERE
- for syntax details.
-
- /SMALLER-THAN:number
- Download only files whose size is smaller than the given number
- of bytes (octets). Requires that the FTP server support the
- SIZE or MLSD directive.
-
- /LARGER-THAN:number
- Download only files whose size is greater than the given number
- of bytes. Requires that the FTP server support the SIZE or MLSD
- directive.
-
- /NOBACKUPFILES
- During MGET, don't download any files whose names end with
- backup suffixes (.~n~ where n is a number).
-
- /NODOTFILES
- During MGET, don't download any files whose names begin with
- period (.). Equivalent to /EXCEPT:{.*}.
-
- /LISTFILE:local-filename
- The given file contains a list of files to GET, one per line.
- Filenames in the listfile can contain wildcard characters in
- the syntax of the server. There is no limit on the number of
- lines in the listfile.
-
- /NAMELIST:local-filename
- If this switch is given, then instead of actually retrieving
- the selected files, the GET command retrieves a list of the
- names of the files that would be retrieved, and places it in
- the specifed file. The resulting file is an ordinary text file,
- with one filename per line, suitable for reading by a person,
- or processing by a computer program, including Kermit itself
- (FOPEN / FREAD / FWRITE / FCLOSE), and as /FILELIST: file. If
- the filename is omitted or given as "-" (dash, hyphen), the
- list goes to the screen. NOTE: if you want a copy of the
- complete list sent by the server, use SET FTP DEBUG ON, perform
- an MGET, and the temporary file containing the list will be
- kept rather than deleted (and Kermit tells you its name).
-
- /UPDATE, /COLLISION:keyword
- Explained in [307]Section 3.6.2.
-
- /RECURSIVE
- This means to try to download an entire directory tree, rather
- than just files from a particular directory. In fact, FTP
- protocol does not provide a method to request a recursive
- download (unless the server supports MLSD; see [308]Section
- 3.11), so this works only if the FTP server does it anyway,
- without being asked, as some do. In this case, Kermit detects
- that names in the returned file list contain directory
- separators, and therefore attempts to create the needed
- directories as the files arrive. But this can work only if the
- server is on the same kind of platform as the client, so the
- pathname syntax can be recognized, and also because the server
- does not switch between text and binary mode, which would be
- vital for cross-platform transfers. Use with caution. Synonym:
- /SUBDIRECTORIES.
-
- Even when the server does not provide recursive file lists,
- [M]GET /RECURSIVE forces Kermit to replicate any directory
- structure implied or expressed by the server's file list. For
- example:
-
- get somepath/somefile
-
- Gets the file named somefile from the server's somepath
- directory and puts it Kermit's current (or download) directory,
- whereas:
-
- get /recursive somepath/somefile
-
- creates the path locally and then puts the file in it.
- Similarly for MGET:
-
- mget */data/*
-
- downloads all the files in all the data subdirectories of all
- the subdirectories of the server's current directory and stores
- them locally in Kermit's current (or download) directory,
- whereas:
-
- mget /recursive */data/*
-
- re-creates the server's directory structure locally.
-
- The FTP protocol does not include explicit mechanisms for recursion,
- so Kermit builds upon what is available. Although an Internet draft
- describes a mechanism ("MLSD") that would allow protocol-driven
- recursion, similar to Kermit's File Attribute packets (circa 1984), it
- has not yet attained RFC or standard status, and servers are not yet
- widely available that offer this feature. In the meantime, the
- effectiveness of MGET /RECURSIVE depends on the FTP server
- implementation. If the server returns a recursive list in response to
- the standard NLST command (whose behavior is ill-defined), Kermit's
- FTP MGET /RECURSIVE command uses it to re-create the remote directory
- tree locally. If the server supports MLSD, C-Kermit 8.0.206 and Kermit
- 95 2.1 and later are able to sense it automatically and use it, as
- described below in [309]Section 3.11.
-
- The /BEFORE:, /AFTER:, /NOT-BEFORE:, and /NOT-AFTER: switches are not
- available for downloading because of the confusion with timezones.
- Would the given times be in the local timezone, the server's timezone,
- or GMT? The FTP server's directory listings show its own local times
- but since we don't know what timezone the server is in, there's no way
- to reconcile our local times with the server's. Similarly,
- /PERMISSIONS can't be preserved in downloads because FTP protocol
- provides no means of querying the server for a file's permission.
-
- Source-file disposition switches:
-
- /DELETE
- Each file that is downloaded successfully is to be deleted from
- the server. Requires the appropriate file access rights on the
- server.
-
- /SERVER-RENAME-TO:template
- Asks the server to rename each (remote) source file immediately
- after, and only if, it is sent correctly. See [310]PUT
- /SERVER-RENAME-TO: for details.
-
- Destination-file disposition switches:
-
- /TO-SCREEN
- Displays the incoming file on the screen rather than storing it
- on disk. If this switch is given, the /RENAME-TO and /MOVE-TO
- switches are ignored, the file-transfer display is suppressed,
- and the given file(s) is/are shown on the screen. Can be used
- with /FILTER, e.g.
-
- get /text /to-screen /filter:more oofa.txt
-
- In fact, you should always use /TO-SCREEN with /FILTER or
- /COMMAND when the command would result in displaying the
- incoming file on the screen; otherwise C-Kermit would have no
- way of knowing to suppress its file transfer display (since it
- can't be expected to know what the command or filter does).
-
- /RENAME-TO:template
- Each file that is downloaded is to be renamed as indicated if
- and only if it was received completely and without error. The
- template can be literal text or can contain variables that are
- evaluated for each file. For MGET, the text must contain
- variables; for GET it can be a literal string. The \v(filename)
- variable contains the name of the current file, so:
-
- ftp mget /rename-to:\v(filename).ok *
-
- causes each file that is successfully downloaded to have ".ok"
- appended to its name. For details see [311]Section 4.1 of the
- [312]C-Kermit 7.0 Update Notes.
-
- /MOVE-TO:text
- Just like /RENAME-TO:, except the text denotes the name of a
- directory to which successfully downloaded files are to be
- moved. If the directory does not exist, it is created.
-
- The file transfer display does not show the /MOVE-TO or /RENAME-TO
- value, since the incoming file has not yet been moved or renamed.
- _________________________________________________________________
-
- 3.6.2. Filename Collisions
-
- What should happen if an incoming file has the same name as an
- existing file in the same directory? By default, Kermit's FILE
- COLLISION setting applies: BACKUP, RENAME, UPDATE, DISCARD, etc, as
- described in [313]Using C-Kermit. Kermit's default FILE COLLISION
- setting is BACKUP (rename the existing file and store the incoming
- file under its own name) and therefore this is also the default FTP
- collision action.
-
- The name under which an incoming file is to be stored is determined as
- follows:
-
- * If an as-name was given, the as-name is used. Otherwise:
- * If the client and server platforms are alike or [314]FTP FILENAMES
- is set to LITERAL (or the /FILENAMES:LITERAL switch was given for
- this download), the incoming filename is used literally.
- Otherwise:
- * The incoming filename is converted to a form that is friendly to
- the local platform. For UNIX, for example, incoming filenames that
- are all uppercase (as they might be from, say, VMS or an IBM
- mainframe) are converted to lowercase.
-
- If the resulting name coincides with the name of a local file that
- already exists, we have a filename collision. Collisions are handled
- according to the currently selected collision action:
-
- SET FTP COLLISION { BACKUP, RENAME, UPDATE, DISCARD, APPEND, OVERWRITE
- }
- This establishes a filename collision for FTP, separate from
- the Kermit one. The initial FTP collision setting is inherited
- from Kermit's FILE COLLISION setting when the first FTP command
- is given, but subsequent changes to Kermit's FILE COLLISION
- setting do not affect the FTP COLLISION setting. SHOW FTP tells
- the current FTP COLLISION setting.
-
- FTP GET /COLLISION:{BACKUP,RENAME,UPDATE,DISCARD,APPEND,OVERWRITE}
- Overrides the current FTP COLLISION action for this download
- only.
-
- FTP GET /UPDATE
- This is equivalent to GET /COLLISION:UPDATE, and is included
- for symmetry with PUT /UPDATE
-
- FTP GET /UPDATE and /COLLISION:UPDATE mean to download only those
- files whose modification dates on the server are later than those on
- the client. Date-time comparisons are done in Coordinated Universal
- Time (UTC, GMT, ZULU). The command:
-
- FTP MGET /COLLISION:APPEND /AS-NAME:newfilename *.*
-
- Downloads all matching remote files into a single local file (in
- whatever order the server sends them).
- _________________________________________________________________
-
- 3.6.3. Recovery
-
- Recovery is available for downloads too, but there are some
- differences from the uploading case described in [315]Section 3.5.3:
-
- * The transfer must be in BINARY mode. It can not be in text mode,
- even if the FTP server is on the same kind of platform as Kermit,
- and even if there is no character-set translation. The original
- download must also have been in binary mode.
- * The FTP server must support the REST ("restart") directive.
- Unfortunately, this is not a standard command; at this writing, it
- is described only in an Internet Draft, not an RFC or Internet
- Standard, but nevertheless it is found in several popular FTP
- servers, such as [316]ProFTPD.
-
- Here's how download recovery works:
-
- * Kermit checks for conflicting switches, such as /UPDATE, /COMMAND,
- or /FILTER. If /RECOVER is given with these switches an error
- occurs.
- * The prevailing transfer mode (SET FTP TYPE) must be BINARY. If it
- is not, the /BINARY switch must have been included with the FTP
- [M]GET command.
-
- If the /RECOVER switch is accepted, then for each selected file:
-
- * A SIZE command is sent for the file (using its remote name). If
- the reply indicates the file was not found, or the SIZE command
- was not understood, or any other kind of error, recovery is
- canceled (i.e. the entire file is downloaded).
- * If the sizes of the two files are identical, the file is not sent.
- Otherwise:
- * Kermit sends the REST directive to the server, indicating the size
- of the local file. If the server responds affirmatively, Kermit
- opens the local file in append mode and appends the incoming data
- to it. Otherwise, recovery is canceled and the entire file is
- downloaded.
-
- The /RECOVER switch can be included with any FTP GET or MGET command,
- even if it specifies a group of files. This lets you resume an
- interrupted batch transfer from where it left off. The files that were
- already completely sent are skipped, the file that was interrupted is
- recovered, and the remaining files are uploaded. BUT... unlike with
- uploading, where this can be done with any mixture of text and binary
- files, when downloading, it can only be done if all the files are
- binary.
-
- It doesn't matter how the original partial file was downloaded -- FTP,
- Kermit, HTTP, Zmodem, etc: as long as the preconditions are met, it
- can be recovered with FTP [M]GET /RECOVER, or for that matter also
- with GET /RECOVER (using Kermit protocol).
-
- [ [317]Top ] [ [318]FTP Top ] [ [319]C-Kermit Home ] [ [320]Kermit
- Home ]
- _________________________________________________________________
-
- 3.7. Translating Character Sets
-
- A possibly unique feature of Kermit's FTP client is its ability to
- convert character sets when transferring files in text mode,
- independent of the capabilites of the FTP server, as well as to
- translate the character sets of filenames regardless of transfer mode.
- For compatibility with existing FTP clients, and because there is a
- certain performance penalty, Kermit won't do this unless you ask for
- it. If you enable this feature, you need to inform Kermit of the
- character set (to be) used on the server and in some cases (explained
- below) also the local file character set. This discussion assumes you
- know a bit about character sets (as you must if you have to use them);
- see Chapter 16 of [321]Using C-Kermit for a detailed treatment. The
- Kermit commands for FTP character-set conversion are:
-
- SET FTP CHARACTER-SET-TRANSLATION { ON, OFF }
- Whether to translate character sets when transferring text
- files with FTP. OFF by default. Set this to ON to enable
- character-set translation for subsequent FTP uploads and
- downloads.
-
- SET FTP SERVER-CHARACTER-SET [322]name
- Text character set (to be) used by the server. Most FTP servers
- are ignorant of character sets, so all translations are done
- unilaterally by Kermit's FTP client. This means that when
- downloading files, you must know in advance the character-set
- used in the files you are downloading (and in their names).
- When uploading, you must specify the character-set to which
- local filenames and text-file contents are to be translated for
- transmission to the server. If you SET FTP
- CHARACTER-SET-TRANSLATION ON but do not specify an FTP
- SERVER-CHARACTER-SET, [323]UTF8 is used, since this is the new
- Internet standard international character set; it is upwards
- compatible with ASCII and it encompasses most written languages
- and therefore does not favor any particular group of people, as
- any other default would do. If you SET FTP SERVER-CHARACTER-SET
- to something (anything) when FTP CHARACTER-SET TRANSLATION is
- OFF, this also sets the latter ON.
-
- SET FILE CHARACTER-SET [324]name
- This is the regular Kermit (non-FTP-specific) command for
- identifying the character set (to be) used in local text files
- and filenames.
-
- TO REITERATE: If you SET FTP CHARACTER-SET TRANSLATION ON but do not
- specify an FTP SERVER-CHARACTER-SET, outbound text files are converted
- to UTF-8 and inbound text files are assumed to be UTF-8. If this is
- not appropriate, be sure to also specify the desired FTP
- SERVER-CHARACTER-SET.
-
- You can use "special" (non-ASCII) characters in filenames in all the
- client / server file management commands (FTP MKDIR, RMDIR, DIRECTORY,
- VDIRECTORY, DELETE, etc), and also in file-transfer commands. When
- giving commands such as FTP DIR (RDIR) and FTP PWD (RPWD), the reply
- is translated too, so you can read it. In this example, the client and
- server use entirely different codes to represent the special
- characters of German:
-
- C-Kermit> ftp xyzcorp.de /anonymous
- C-Kermit> set ftp server-character-set latin1
- C-Kermit> set file character-set german
- C-Kermit> rcd Städte
- C-Kermit> rpwd
- "/pub/ftp/Städte is current directory"
- C-Kermit> rdir
- -rw-rw---- 1 olaf 54018 Jan 6 17:58 Adenbüttel.txt
- -rw-rw---- 1 ursula 373 Jan 5 15:19 Aßlar.txt
- -rw-rw---- 1 gisbert 482 Jan 5 15:20 Blowatz.txt
- -rw-rw---- 1 gudrun 124 Jan 5 15:19 Böblingen.txt
- -rw-rw---- 1 olga 14348 Jan 7 14:23 Köln.txt
-
- When the client and server file systems use different character sets,
- you should take care to use only those characters that the two sets
- share in common when creating filenames or text-file contents. For
- example, PC code pages contain a lot line- and box-drawing characters,
- and sometimes "smart quotes", etc, that are not found in ISO standard
- 8-bit character sets. You should be especially careful to avoid using
- such characters in filenames.
-
- [ [325]C-Kermit Character Sets ]
- _________________________________________________________________
-
- 3.7.1. Character Sets and Uploading
-
- Kermit's PUT and MPUT commands include full file-scanning
- capabilities, as described in [326]Section 4. Thus if FTP
- CHARACTER-SET-TRANSLATION is ON and your character-set associations
- are set up appropriately, Kermit automatically switches on a per-file
- basis between text and binary mode, and for each text file between
- your chosen 7-bit text character set (e.g. ASCII or ISO 646 German),
- 8-bit text (e.g. Latin-1 or Japanese EUC), UCS-2, and UTF-8, and
- converts each of these automatically to the server character-set, and
- furthermore automatically differentiates between the Little and Big
- Endian forms of UCS-2, always sending in Big Endian form.
-
- WARNING: It is not advisable to use UCS-2 (or any Unicode
- transformation other than UTF-8) "on the wire", i.e. as a server
- character set. Most FTP servers are not able to cope with it, since
- it contains lots of 0 (NUL) characters. If you do use it, Kermit
- does not translate filenames to or from UCS-2, for reasons well
- known to C programmers (for example, UNIX APIs assume filename
- strings are NUL-terminated). [327]UTF-8 is the preferred (and
- standard) Unicode format for the Internet.
-
- FTP character-set translations differ from the regular Kermit ones by
- not restricting translations to a file-character-set /
- transfer-character-set pair. You can have Kermit's FTP client
- translate between any pair of character sets it knows about. You can
- see the list of supported character sets by typing either of the
- following:
-
- set ftp server-character-set ?
- set file character-set ?
-
- A typical list looks like this ([328]CLICK HERE for an explanation of
- the names):
-
- C-Kermit>set file char ? One of the following:
- ascii cp869-greek hebrew-7 mazovia-pc
- british cyrillic-iso hebrew-iso next-multinational
- bulgaria-pc danish hp-roman8 norwegian
- canadian-french dec-kanji hungarian portuguese
- cp1250 dec-multinational iso2022jp-kanji shift-jis-kanji
- cp1251-cyrillic dg-international italian short-koi
- cp1252 dutch jis7-kanji spanish
- cp437 elot927-greek koi8 swedish
- cp850 elot928-greek koi8r swiss
- cp852 euc-jp koi8u ucs2
- cp855-cyrillic finnish latin1-iso utf8
- cp858 french latin2-iso
- cp862-hebrew german latin9-iso
- cp866-cyrillic greek-iso macintosh-latin
- C-Kermit>
-
- Thus you can translate not only between private sets (like PC code
- pages) and standard ones (like Latin-1) as in Kermit protocol, but
- also between any given pair of private sets (e.g. CP852 and Mazovia).
- All conversions go through Unicode as the intermediate character set,
- resulting in a minimum of character loss, since Unicode is a superset
- of all other character sets known to Kermit.
-
- In addition to the SET commands listed above, the FTP PUT and MPUT
- commands include switches that apply only to the current command:
-
- /LOCAL-CHARACTER-SET:name
- /SERVER-CHARACTER-SET:name
- Use these switches to force a particular translation. These
- switches override the global FTP CHARACTER-SET-TRANSLATION and
- SERVER-CHARACTER-SET settings and also character-set
- differentiation by file scanning for the duration of the PUT or
- MPUT command. The file scan is still performed, however, to
- determine whether the file is text or binary; thus these
- switches do not affect binary files unless you also include the
- /TEXT switch to force all files to be treated as text.
-
- In other words, if you include one or both of these switches with a
- PUT or MPUT command, they are used. Similarly, the /TRANSPARENT switch
- disables character-set translation for the PUT or MPUT command despite
- the prevailing FTP CHARACTER-SET-TRANSLATION and SERVER-CHARACTER-SET
- settings.
-
- When uploading, the FILE CHARACTER-SET setting is ignored unless you
- have forced Kermit not to [329]scan local files by including a /TEXT
- or /BINARY switch with your [M]PUT command, or by disabling automatic
- text/binary switching in some other way.
-
- Examples:
-
- 1. Suppose you have a CP852 (East European) text file that you want
- to upload and store in ISO Latin Alphabet 2 encoding:
- ftp put /local-char:cp852 /server-char:latin2 magyar.txt
- 2. Suppose you always want your text files converted to Latin-2 when
- uploading with FTP. Then put:
- set ftp server-character-set latin2
- in your Kermit customization file, and then you can omit the
- /SERVER-CHARACTER-SET: switch from your FTP PUT commands:
- ftp put /local-char:cp852 magyar.txt
- 3. Now suppose that all the text files on your PC are written in
- Hungarian, but they have a variety of encodings, and you don't
- want to have to include the /LOCAL-CHARACTER-SET: switch on every
- FTP PUT command, or (more to the point) you want to be able to
- send a mixture of these files all at once. Put these commands in
- your Kermit customization file:
- set ftp server-character-set latin2 ; ISO 8859-2
- set file default 7-bit-character-set hungarian ; ISO 646 Hungarian
- set file default 8-bit-character-set cp852 ; PC East European Code Page
- and now PUT and MPUT will automatically detect and switch among
- ISO 646 Hungarian, Code Page 852, UTF-8, and UCS-2 encodings,
- translating each one to Latin-2 for uploading:
- ftp put *.txt
-
- And since binary files are also detected automatically, the latter can
- be simplified to:
-
- ftp put *
-
- even when "*" matches a diverse collection of binary and text files,
- because translations are skipped automatically for binary files.
- _________________________________________________________________
-
- 3.7.2. Character Sets and Downloading
-
- The commands and switches are the same as for uploading, but automatic
- character-set switching works differently, since Kermit can't scan the
- server files in advance. Instead, the transfer mode (text or binary)
- is based on the filenames; each name is compared with Kermit's list of
- text name patterns and binary name patterns. If the name matches a
- binary pattern (for example, if the filename is oofa.tar.gz and one of
- the filename patterns is "*.gz"), the file is downloaded in binary
- mode; otherwise if it matches a text pattern (e.g. oofa.txt matches
- "*.txt"), it is transferred in text ("ascii") mode. Otherwise, it is
- transferred in the prevailing FTP TYPE.
-
- In C-Kermit 8.0, the pattern lists used with FTP GET are not the same
- lists used with Kermit transfers, and can not be viewed with SHOW
- PATTERNS, nor adjusted with ADD and REMOVE TEXT-PATTERNS and
- BINARY-PATTERNS, or SET FILE TEXT-PATTERNS and BINARY-PATTERNS.
- Configuration of the FTP patterns list will be added in a future
- release.
-
- Examples:
-
- get /server-char:latin1 /local-char:cp850 Grüße.txt
- In this command, the filename contains special characters,
- which you enter using whatever character set your local
- computer uses, in this case PC Code Page 850 (cp850). The
- command tells Kermit (in case it didn't know already from its
- FILE CHARACTER-SET setting) that the local character set is
- cp850 and the server's character-set is ISO 8859-1 Latin
- Alphabet 1 (latin1). Kermit translates the filename from cp850
- to latin1 and sends the latin1 name to the server. Since it's a
- text file (matches "*.txt"), its contents are translated to
- cp850 on arrival, and it is saved with a cp850 name.
-
- mget /text /server:latin1 /local:utf8 *.txt
- This command:
-
- + Tells C-Kermit that the server's files are encoded in ISO
- 8859-1 Latin Alphabet 1.
- + Tells C-Kermit to translate the incoming files into Unicode
- UTF-8 for storage.
- + Asks the server to send all ".txt" files in text mode.
-
- mget /server:latin1 /local:utf8 *
- Tells Kermit to get all files from the server's directory,
- switching between text and binary mode based on the filename.
- The names of all the files are translated (to UTF-8 in this
- case), but contents are translated (also to UTF-8) only for
- text files.
-
- Note that any pair of 8-bit character sets is likely to have some
- incompatibilities. Any characters in the source file that do not have
- equivalents in the destination file's character set are converted to
- question marks. This applies to both filenames and to text file
- contents.
-
- Also note that the server's ability to accept special characters in
- filenames depends on the particular server. For example:
-
- get Grüße.txt
-
- works with WU-FTPD, but:
-
- mget Grüß*.txt
-
- does not.
- _________________________________________________________________
-
- 3.7.3. RFC2640
-
- [330]RFC2640, July 1999, specifies a method by which the FTP client
- and server can negotiate the use of UTF8. However, RFC2640-capable
- servers are rare to nonexistent at this writing, and in any case you
- don't need them to be able to transfer text in UTF8. C-Kermit lets you
- upload and download text files in any character set it knows about,
- converting to or from any other character set it knows about, without
- the knowledge, permission, or cooperation of the server, and
- regardless of its capabilities.
-
- [ [331]Top ] [ [332]FTP Top ] [ [333]C-Kermit Home ] [ [334]Kermit
- Home ]
- _________________________________________________________________
-
- 3.8. FTP Command Shortcuts
-
- C-Kermit's FTP client coexists with other C-Kermit functions by
- requiring the "ftp" prefix for each FTP-related command: FTP OPEN, FTP
- GET, FTP BYE, and so on. For interactive use, however, this can be
- rather awkward and sometimes surprising, for example when a GET
- command starts a Kermit GET rather than an FTP GET. In fact, many
- Kermit commands might just as easily apply to an FTP connection: GET,
- PUT (SEND), BYE, and CLOSE. The following command lets you choose how
- these commands are interpreted:
-
- SET GET-PUT-REMOTE { AUTO, KERMIT, FTP }
- Controls the orientation of GET, PUT, REMOTE and other
- file-transfer and client/server commands that might apply to
- either Kermit or FTP. The default setting is AUTO, meaning that
- these commands apply to FTP if an FTP connection is open, and
- to Kermit otherwise. KERMIT means they always apply to Kermit,
- FTP means they always apply to FTP.
-
- Here is a complete list of affected commands:
-
- Kermit Command FTP Equivalent
- (none) FTP [ OPEN ]
- LOGIN FTP USER
- LOGOUT FTP RESET
- BYE FTP BYE
- FINISH FTP BYE
- CLOSE FTP BYE
- HANGUP FTP BYE
- BINARY FTP TYPE BINARY
- TEXT (or ASCII) FTP TYPE ASCII
- SEND (or PUT) FTP PUT
- MSEND (or MPUT) FTP MPUT
- RESEND FTP PUT /RECOVER
- CSEND FTP PUT /COMMAND
- GET FTP GET
- MGET FTP MGET
- REGET FTP GET /RECOVER
- REMOTE HELP (RHELP) FTP HELP
- REMOTE CD (RCD) FTP CD (CWD)
- REMOTE PWD (RPWD) FTP PWD
- REMOTE DIRECTORY (RDIR) FTP DIRECTORY
- REMOTE DELETE (RDEL) FTP DELETE
- REMOTE MKDIR (RMKDIR) FTP MKDIR
- REMOTE RMDIR (RRMDIR) FTP RMDIR
- REMOTE RENAME (RRENAME) FTP RENAME
- REMOTE TYPE (RTYPE) FTP TYPE
- REMOTE EXIT (REXIT) FTP BYE
-
- The commands in the right-hand column always access FTP. The commands
- in the left column can access either Kermit protocol or FTP:
-
- * When GET-PUT-REMOTE is set to KERMIT, or to AUTO when there is no
- FTP connection, the commands in the left-hand column access Kermit
- protocol, and those right-hand column are required for FTP.
- * When GET-PUT-REMOTE is set to FTP, or to AUTO when there is an
- active FTP connection, the commands in the left-hand column access
- the FTP connection and can not be used to access Kermit protocol.
- In this case, if you want to be able to use both Kermit protocol
- and the FTP connection, you must SET GET-PUT-REMOTE KERMIT, and
- then use the FTP commands in the right-hand column to access the
- FTP connection.
-
- Note that file-management commands such as DIRECTORY, DELETE, CD, PWD,
- MKDIR, RMDIR, HELP, RENAME, COPY, TYPE, and so on, always apply
- locally, no matter what kind of connection you have. This is the
- opposite of most FTP clients, where these commands are intended for
- the server, and require an "L" prefix for local execution (e.g. "dir"
- gets a directory listing from the server, "ldir" gets a local
- directory listing). To illustrate with the CD command and a typical
- UNIX FTP client:
-
- Client Server Change Local Directory Change Remote Directory
- FTP FTP lcd cd (cwd)
- Kermit Kermit cd rcd, remote cd
- Kermit FTP cd ftp cd, rcd, remote cd
-
- Also note that not all REMOTE commands are useful with FTP, since FTP
- servers do not offer the corresponding functions. These include:
-
- * REMOTE ASSIGN - FTP servers don't have variables
- * REMOTE COPY - FTP servers don't copy files
- * REMOTE HOST - FTP servers don't execute host (shell) commands
- * REMOTE KERMIT - FTP servers don't execute Kermit commands
- * REMOTE PRINT - FTP servers don't print files
- * REMOTE QUERY - FTP servers don't have variables
- * REMOTE SET - FTP servers don't have Kermit settings
- * REMOTE WHO - FTP servers don't send user lists
-
- Finally note that command shortcuts do not apply to the HELP command.
- For help about an FTP command, use (for example) "help ftp delete",
- not "help delete" or "help rdelete".
-
- [ [335]Top ] [ [336]FTP Top ] [ [337]C-Kermit Home ] [ [338]Kermit
- Home ]
- _________________________________________________________________
-
- 3.9. Dual Sessions
-
- You can have an FTP session open at the same time as a regular Kermit
- SET LINE or SET HOST (terminal) session. In this case, the default SET
- GET-PUT-REMOTE AUTO setting should ensure that all "two-faced"
- commands like GET, PUT, REMOTE, HANGUP, BYE, etc, apply to the Kermit
- session, and all commands for the FTP session must include the FTP
- prefix. To be absolutely certain, you can use SET GET-PUT-REMOTE
- KERMIT.
-
- ftp foo.bar.baz.com
- if fail ...
- (log in)
- set host foo.bar.baz.com
- if fail ...
- (log in)
-
- Now you have both an FTP and Telnet connection to the same host (of
- course they could also be to different hosts, and you could also have
- a direct or dialed serial connection instead of a Telnet connection).
- Now assuming you have a Kermit server on the far end of the Kermit
- connection:
-
- rcd incoming ; Changes Kermit server's directory (= REMOTE CD)
- ftp cd incoming ; Changes FTP server's directory
- put oofa.txt ; Sends a file on the Kermit connection
- ftp put oofa.txt ; Sends a file on the FTP connection
- bye ; Shuts down the Kermit connection
- ftp bye ; Shuts down the FTP connection
-
- Note that PUT and SEND are synonyms for both FTP and Kermit
- connections.
-
- You can also establish dual sessions on the Kermit command line:
-
- kermit -j host1 -9 host2
-
- This makes a Telnet connection to host1 and an FTP connection to
- host2.
-
- [ [339]Top ] [ [340]FTP Top ] [ [341]C-Kermit Home ] [ [342]Kermit
- Home ]
- _________________________________________________________________
-
- 3.10. Automating FTP Sessions
-
- Most of Kermit's scripting features can be used to make and control
- FTP sessions: FOR and WHILE loops, IF-ELSE and SWITCH constructions,
- variables, arrays, built-in functions, and all the rest. You can't use
- INPUT, MINPUT, OUTPUT, CLEAR, or SCRIPT on an FTP session, but these
- are not needed since the FTP protocol is well defined.
-
- [343]CLICK HERE for an FTP scripting tutorial.
-
- 3.10.1. FTP-Specific Variables and Functions
-
- The following variable tells whether an FTP connection is open:
-
- \v(ftp_connected)
- 1 if there is an active FTP connection, 0 if there isn't.
-
- The FTP OPEN command sets:
-
- \v(ftp_host)
- The host to which the most recent FTP connection was made.
-
- \v(ftp_security)
- The security method negotiated for the current FTP session. The
- value is "NULL" when no security is used. See [344]3.2. Making
- Secure FTP Connections.
-
- \v(ftp_server)
- The OS type (UNIX, VMS, etc) of the FTP server host.
-
- The FTP USER command (or FTP OPEN /USER:, or FTP with automatic login)
- sets:
-
- \v(ftp_loggedin)
- 1 if you are logged in to an FTP server, 0 if you are not.
-
- The current COMMAND-PROTECTION-LEVEL and DATA-PROTECTION-LEVEL values
- are reflected in:
-
- \v(ftp_cpl)
- \v(ftp_dpl)
- The values are "clear", "confidential", "safe" or "private".
- See [345]3.2. Making Secure FTP Connections.
-
- The FTP GET-PUT-REMOTE setting is reflected in:
-
- \v(ftp_getputremote)
- The values are "auto", "ftp", or "kermit".
-
- Every FTP command sets the \v(success) variable, as well as the
- following two FTP-specific variables:
-
- \v(ftp_code)
- The standardized numeric FTP protocol code from the server's
- response to the last client command, a 3-digit decimal number
- defined in [346]RFC959. Briefly:
-
- 1xx = Positive Preliminary Reply
- 2xx = Positive Completion Reply
- 3xx = Positive Intermediate Reply
- 4xx = Transient Negative Completion Reply
- 5xx = Permanent Negative Completion Reply
-
- \v(ftp_message)
- The text message, if any, from the server's response to the
- last client command. If the most recent response had multiple
- lines, this variable has only the final line. These messages
- are not standardized and vary in format and content from server
- to server. Synonym: \v(ftp_msg).
-
- FTP file transfers set the regular Kermit transfer status variables:
-
- \v(cps) Characters per second of most recent transfer.
- \v(filespec) File specification used in most recent transfer.
- \v(fsize) Size of file most recently transferred.
- \v(tfsize) Total size of file group most recently transferred.
- \v(xferstatus) Status of most recent transfer (0 = success, 1 = failure).
- \v(tftime) Elapsed time of most recent transfer, in seconds.
-
- During an FTP transfer, the per-file variables are:
-
- \v(filename) Name of current file.
- \v(filenumber) Ordinal file number in group (1, 2, 3, ...)
- _________________________________________________________________
-
- 3.10.2. Examples
-
- Let's begin with a simple example showing how to log in, send some
- files, and log out:
-
- define error if fail { ftp bye, stop 1 Error: \%1 }
- set transact brief
- log t
- ftp ftp.xyzcorp.com /anonymous
- if fail stop 1 Connection failed
- if not \v(ftp_loggedin) stop 1 Login failed
- ftp cd incoming
- error {ftp cd}
- cd upload
- error {local cd}
- ftp put /delete *
- error {put}
- ftp bye
-
- First we define an error handling macro to be used after the
- connection is made. Then we set up a brief-format transaction log to
- keep a record of our file transfers. Then we make a connection to the
- host and log in anonymously. The "if fail" command checks whether the
- connection was made. The "if not" command checks whether login was
- successful. Obviously the script should not continue unless both tests
- succeed.
-
- Next we change to the server's 'incoming' directory and to our own
- 'upload' directory, and send all the files that are in it (they can be
- any mixture of text and binary files), deleting each source file
- automatically after it is successfully uploaded. Each of these
- operations is checked with the ERROR macro, which prevents the script
- from continuing past a failure.
-
- Finally we close the FTP session with the "bye" command.
-
- Just like any other Kermit script, this one can be used in many ways:
-
- * It can be stored in a file, and Kermit can be told to TAKE the
- file.
- * In UNIX, it can be a "[347]kerbang" script and therefore run
- directly from the shell prompt or as a cron job.
-
- We could have used command shortcuts like "rcd", "put", and "bye", but
- since they can be ambiguous under certain circumstances, it is better
- to avoid them in scripts; they are intended mainly for convenience
- during interactive use. However, if you wish to use the shortcuts in a
- script, you can do it this way (error handling omitted for brevity):
-
- local \%t ; Declare a local temporary veriable
- assign \%t \v(ftp_getputremote) ; Save current FTP GET-PUT-REMOTE setting
- set ftp get-put-remote ftp ; Choose FTP orientation
- ftp xyzcorp.com /anonymous ; Open an FTP connection
- get oofa.txt ; GET a file
- put foo.bar ; PUT a file
- rdel yesterday.log ; Delete a file on the server
- bye ; Log out and disconnect from server.
- set ftp get-put-remote \%t ; Restore previous GET-PUT-REMOTE setting
-
- Of course, FTP scripts can also be written as macros. This lets you
- pass parameters such as hostnames, usernames, and filenames to them:
-
- define doftpget {
- if < \v(argc) 4 end 1 Usage: \%0 host user remotefile [ localfile ]
- ftp \%1 /user:\%2
- if fail end 1 FTP OPEN \%1 failed
- if not \v(ftp_loggedin) end 1 FTP LOGIN failed
- ftp get {\%3} {\%4}
- if fail end 1 FTP GET \%3 failed
- ftp bye
- }
-
- Add this definition to your Kermit customization file, and it will
- always be available when you start Kermit. This macro lets you
- download a file with FTP by giving a single command, e.g.:
-
- doftpget xyzcorp.com anonymous oofa.txt
- _________________________________________________________________
-
- 3.10.3. Automating Secure FTP Sessions
-
- Often when making secure connections, you are prompted interactively
- for certain information or permission to proceed. These prompts can
- stop an automated procedure. To avoid them, you must give the
- appropriate commands to disable them, and/or supply the prompted-for
- information beforehand. Here are a few hints:
-
- * Make sure that SET TAKE ERROR and SET MACRO ERROR are both OFF.
- This is the default, but in case you have set either one of these
- ON in your script or initialization file, this makes the script
- halt on any kind of error. Normally you would want to check each
- operation for success or failure and take appropriate action.
- * On SSL and TLS connections, you may be asked whether it is OK to
- proceed with a connection to server that presents a self-signed
- certificate. You can use the SET AUTHENTICATION SSL (or TLS)
- VERIFY or SET AUTH SSL (or TLS) CERTS-OK commands to avoid this
- prompt by not requesting a certificate from the peer.
- * (More to be added...)
-
- [ [348]Top ] [ [349]FTP Top ] [ [350]FTP Script Tutorial ] [
- [351]C-Kermit Home ] [ [352]Kermit Home ]
- _________________________________________________________________
-
- 3.11. Advanced FTP Protocol Features
-
- The remainder of the FTP documention (through the end of Section 3) is
- new to C-Kermit 8.0.206, but we leave it in black to prevent
- headaches. Except for titles.
- * [353]TERMINOLOGY
- * [354]FEATURE NEGOTIATION
- * [355]USING MGET: NLST VERSUS MLSD
- * [356]EXAMPLES
- * [357]REFERENCES
-
- The new releases of [358]C-Kermit (8.0.206) and [359]Kermit 95 (2.1)
- support new FTP protocol features from RFC 2389 as well as most of
- what's in the Elz and Hethmon Extensions to FTP Internet Draft (see
- [360]References). Some of these features, such as SIZE (request a
- file's size), MDTM (request file's modification time), and REST
- (restart interrupted transfer) have been widely implemented in FTP
- clients and servers for years (as well as in the initial release of
- the Kermit FTP clients). Others such as FEAT and MLSD are rarely seen
- and are new to the upcoming Kermit releases. TVFS (Trivial Virtual
- File Store) is supported implicitly, and the UTF-8 character-set is
- already fully supported at the protocol and data-interchange level.
-
- For Kermit users, the main benefit of the new FTP protocol extensions
- is the ability to do recursive downloads. But the extensions also
- introduce complications and tradeoffs that you should be aware of. Of
- course Kermit tries to "do the right thing" automatically in every
- case for backwards compatibility. But (as noted later) some cases are
- inherently ambiguous and/or can result in nasty surprises, and for
- those situations new commands and switches are available to give you
- precise control over Kermit's behavior, in case the defaults don't
- produce the desired results.
- _________________________________________________________________
-
- 3.11.1. Terminology Command-line FTP clients such as Kermit (as well
- as the traditional FTP programs found on Unix, VMS, ..., even Windows)
- have commands like PUT, MPUT, GET, MGET, and BYE, which they convert
- into zero or more FTP protocol commands, such as NLST, RETR, QUIT. For
- clarity, we'll use "command" to refer to commands given by the user to
- the FTP client, and "directive" for FTP protocol commands sent by the
- FTP client to the FTP server.
- _________________________________________________________________
-
- 3.11.2. Feature Negotiation New FTP protocol features are negotiated
- by the client sending a FEAT directive and the server responding with
- a list of (new) features it supports, or else with an error indication
- if it does not support the FEAT directive at all, in which case the
- client has to guess which new features it supports (Kermit guesses
- that it supports SIZE and MDTM but not MLST). Note that the MLST
- feature includes MLSD, which is not listed separately as a feature.
-
- Guessing is nice when it works, but sometimes it doesn't, and some FTP
- servers become confused when you send them a directive they don't
- understand, or they do something you didn't want, sometimes to the
- point of closing the connection. For this reason, Kermit lets you
- override default or negotiated features with the following new
- commands:
-
- FTP { ENABLE, DISABLE } FEAT
- Enables or disables the automatic sending of a FEAT directive
- upon connection to an FTP server. Note that
- FTP [ OPEN ] /NOINIT also inhibits sending the FEAT directive
- (and several others) for the connection being OPEN'd, but
- without necessarily disabling FEAT for subsequent connections
- in the same Kermit instance. FEAT is ENABLED by default, in
- which case many FTP servers are likely to reply:
-
-500 'FEAT': command not understood
-
- which is normally harmless (but you never know). (In C-Kermit
- 8.0.208, this error message is suppressed unless you SET FTP
- DEBUG ON.)
-
- FTP ENABLE { MDTM, MLST, SIZE }
- Enables the given directive for implicit use by the FTP GET and
- MGET commands in case it has been disabled or erroneously
- omitted by the server in its FEAT response. Note: MLSD can be
- used in the FTP ENABLE and DISABLE commands as a synonym for
- MLST. YOU MUST GIVE THIS COMMAND AFTER MAKING THE FTP
- CONNECTION.
-
- FTP DISABLE { MDTM, MLST, SIZE }
- Disables implicit use of the given directive by GET or MGET in
- case it causes problems; for example, because it makes
- multifile downloads take too long or the server announces it
- erroneously or misimplements it. Use DISABLE FEAT before making
- a connection to prevent Kermit from sending the FEAT directive
- as part of its initial sequence. Note that disabling FEAT,
- SIZE, or MDTM does not prevent you from executing explicit FTP
- FEATURES, FTP SIZE, or FTP MODTIME commands. Also note that
- disabling SIZE prevents PUT /RESTART (recovery of interrupted
- uploads) from working. YOU MUST GIVE THIS COMMAND AFTER MAKING
- THE FTP CONNECTION.
-
- To enable or disable more than one feature, use multiple FTP ENABLE or
- FTP DISABLE commands. The SHOW FTP command shows which features are
- currently enabled and disabled.
-
- FTP FEATURES
- This command sends a FEAT directive to the server. In case you
- have been disabling and enabling different features, this
- resynchronizes Kermit's feature list with the server's. If the
- server does not support the FEAT directive, Kermit's feature
- list is not changed.
-
- FTP OPTIONS directive
- Informational only: the server tells what options, if any, it
- supports for the given directive, e.g. MLST. Fails if the
- server does not support the OPTS directive or if the directive
- for which options are requested is not valid. The directive is
- case-insensitive.
-
- FTP SIZE filename
- Sends a SIZE directive to the server for the given file. The
- filename must not contain wildcards. The server responds with
- an error if the file can't be found, is not accessible, or the
- SIZE directive is not supported, otherwise with the length of
- the file in bytes, which Kermit displays and also makes
- available to you in its \v(ftp_message) variable. If the
- directive is successful, Kermit (re-)enables it for internal
- use by the GET and MGET directives on this connection.
-
- FTP MODTIME filename
- Works just like the SIZE directive except it sends an MDTM
- directive. Upon success, the server sends modification
- date-time string, which Kermit interprets for you and also
- makes available in its \v(ftp_message) variable.
-
- Whenever a SIZE or MDTM directive is sent implicitly and rejected by
- the server because it is unknown, Kermit automatically disables it.
- _________________________________________________________________
-
- 3.11.3. Using MGET: NLST versus MLSD When you give an MGET command to
- an FTP client, it sends a request to the FTP server for a list of
- files, and then upon successful receipt of the list, goes through it
- and issues a RETR (retrieve) directive for each file on the list (or
- possibly only for selected files).
-
- With the new FTP protocol extensions, now there are two ways to get
- the list of files: the NLST directive, which has been part of FTP
- protocol since the beginning, and the new MLSD directive, which is new
- and not yet widely implemented. When NLST is used and you give a
- command like "mget *.txt", the FTP client sends:
-
-NLST *.txt
-
- and the server sends back a list of the files whose names match, e.g.
-
-foo.txt
-bar.txt
-baz.txt
-
- Then when downloading each file, the client sends SIZE (if it wants
- have a percent-done display) and MDTM (if it wants to set the
- downloaded file's timestamp to match that of the original), as well as
- RETR (to retrieve the file).
-
- But when MLSD is used, the client is not supposed to send the filename
- or wildcard to the server; instead it sends an MLSD directive with no
- argument (or the name of a directory), and the server sends back a
- list of all the files in the current or given directory; then the
- client goes through the list and checks each file to see if it matches
- the given pattern, the rationale being that the user knows only the
- local conventions for wildcards and not necessarily the server's
- conventions. So with NLST the server interprets wildcards; with MLSD
- the client does.
-
- The interpretation of NLST wildcards by the server is not
- necessarily required or even envisioned by the FTP protocol
- definition (RFC 959), but in practice most clients and servers work
- this way.
-
- The principal advantage of MLSD is that instead of sending back a
- simple list of filenames, it sends back a kind of database in which
- each entry contains a filename together with information about the
- file: type, size, timestamp, and so on; for example:
-
-size=0;type=dir;perm=el;modify=20020409191530; bin
-size=3919312;type=file;perm=r;modify=20000310140400; bar.txt
-size=6686176;type=file;perm=r;modify=20001215181000; baz.txt
-size=3820092;type=file;perm=r;modify=20000310140300; foo.txt
-size=27439;type=file;perm=r;modify=20020923151312; foo.zip
-(etc etc...)
-
- (If the format of the file list were the only difference between NLST
- and MLSD, the discussion would be finished: it would always be better
- to use MLSD when available, and the MGET user interface would need no
- changes. But there's a lot more to MLSD than the file-list format;
- read on...)
-
- The client learns whether the server supports MLSD in FEAT exchange.
- But the fact that the server supports MLSD doesn't mean the client
- should always use it. It is better to use MLSD:
-
- * On connections where the server imposes a time penalty for every
- command, e.g. the Red Hat Rawhide server. With MLSD, the client
- needs to send only one command (RETR) per file, whereas NLST
- requires three (SIZE, RETR, and MDTM). Suppose there is a
- 30-second delay for each command and 1000 files are to be fetched;
- in that case, MLSD saves 60,000 seconds = 1000 minutes = 16 hours
- and 40 minutes.
- * For recursive downloads since there is no dependable way to
- download directory trees with NLST.
-
- But it is better to use NLST:
-
- * If you want only a couple short files out of a large directory. In
- this case, NLST is the better choice since the server sends a list
- of only the files you want, not a list of (say) a million files,
- which can make a big difference on slow connections. For example,
- suppose your wildcard matches three files of 1K each, but the
- million-file listing is 80MB long, and your connection is through
- a modem. The overhead of using MLSD is practically infinite.
- * If the server supports wildcarding features not known to the
- client, but that can be used to achieve desirable effects
- otherwise unobtainable, such as "[dir...]*.txt" in VMS or AOS/VS
- "except" clauses.
- * If you have been given a wildcard string by an FTP site
- administrator for fetching a specific group of files out of a
- larger directory, e.g. "mget ck[cuw]*.[cwh] makefile", that is
- expected to work with any client (an FTP site administrator can't
- be expected to know the wildcard syntax of every FTP client).
-
- But when using MLSD there are complications:
-
- * MLSD wants either a blank argument (meaning the current directory)
- or else the name of a specific directory. The client must not send
- it a wildcard or a filename.
- * But if the user's command is "mget xxx", how does the client know
- whether to send "xxx" in the MLSD directive? It might be the name
- of a directory on on the server, in which case it should be sent,
- or it might be the name of a file on the server (or a wildcard),
- in which case it must not be sent. Since the client knows its own
- wildcard syntax, then in most cases it would be right to send
- "MLSD" with no argument if xxx is wild, and to send "MLSD xxx" if
- it is not.
- * But suppose the server's file system allows filename characters
- that correspond with the client's wildcard syntax? For example:
- "[abc]" could be either a valid VMS directory name or a wildcard
- pattern used by the FTP client. What should the client do with
- "mget [abc]"? In this case there must be a way for the user to
- force sending the MGET argument as the MLSD argument.
- * If "xxx" is a regular file in the server's current directory,
- "mget xxx" works with NLST but not with MLSD.
-
- To further complicate matters, NLST can (in theory) work just like
- MLSD: if sent with a blank argument or a directory name, it is
- supposed to return a complete list of files in the current or given
- directory, which the client can match locally against some pattern. It
- is not known if any FTP server or client does this but nevertheless,
- it should be possible since this behavior can be inferred from RFC
- 959.
-
- In view of these considerations, and given the need to preserve the
- traditional FTP client command structure and behavior so the software
- will be usable by most people:
-
- 1. The MGET command should produce the expected result in the common
- cases, regardless of whether NLST or MLSD is used underneath.
- 2. For anomalous cases, the user needs a way to control whether the
- MGET argument is sent to the server or kept for local use.
- 3. At the same time, the user might need a way to send a directory
- name to the server, independent of any wildcard pattern.
- 4. The user needs a way to force NLST or MLSD for a given MGET
- command.
-
- By default, Kermit's MGET command uses MLSD if MLST is reported by the
- server in its FEAT list. When MLSD is used, the filespec is sent to
- the server if it is not wild (according to Kermit's own definition of
- "wild" since it can't possibly know the server's definition). If the
- filespec is wild it is held for local use to select files from the
- list returned by the server. If MLST is not reported by the server or
- is disabled, Kermit sends the MGET filespec with the NLST directive.
-
- The default behavior can be overridden globally with FTP DISABLE MLST,
- which forces Kermit to use NLST to get file lists. And then for
- situations in which MLSD is enabled, the following MGET switches can
- be used to override the defaults for a specific MGET operation:
-
- /NLST
- Forces the client to send NLST. Example:
-
-mget /nlst foo.*
-
- /MLSD
- Forces the client to send MLSD (even if MLST is disabled).
- Example:
-
-mget /mlsd foo.*
-
- /MATCH:pattern
- When this switch is given, it forces the client to hold the
- pattern for local use against the returned file list. If a
- remote filespec is also given (e.g. the "blah" in "mget
- /match:*.txt blah"), then it is sent as the NLST or MLSD
- argument, presumably to specify the directory whose files are
- to be listed. When the /MATCH switch is not given, the MGET
- filespec is sent to the server if the directive is NLST or if
- the filespec is not wild. Examples:
-
- Command: With NLST: With MLSD:
- mget NLST MLSD
- mget *.txt NLST *.txt MLSD
- mget foo NLST foo MLSD foo
- mget /match:*.txt NLST MLSD
- mget /match:*.txt foo NLST foo MLSD foo
-
- In other words, the pattern is always intepreted locally unless MGET
- uses NLST and no /MATCH switch was given.
- _________________________________________________________________
-
- 3.11.4. Examples
-
- 3.11.4.1. Downloading a Single File
-
- There are no choices here, just use the FTP GET command. Kermit always
- sends the RETR directive, and possibly SIZE and/or MDTM. The small
- advantage of using MLST in this case is outweighed by the risk and
- effort of coding a special case.
-
- 3.11.4.2. Downloading a Group of Files from a Single Directory
-
- This case presents tradeoffs, especially on slow connections:
-
- * For downloading all or most of the files in a directory, MLSD is
- better because it eliminates the need to send SIZE and MDTM for
- each file. No special actions are required in this case; Kermit
- uses MLSD automatically if the server supports it (unless you have
- disabled it).
- * For a small number of files from a large directory, NLST is better
- because it bypasses downloading of a potentially huge file list
- prior to the files themselves. If you have a connection to a
- server that supports MLSD, use the /NLST switch to force NLST:
-
-mget /nlst t[1234].h
-
- * If the server supports MLSD but does not support separate SIZE or
- MDTM directives, and you need the size and/or timestamp
- information, MLSD is better; no special actions required.
- * If the server supports MLSD but does not support the "size" and
- "modify" facts, but it does support the SIZE or MDTM directives,
- and you need the size and/or timestamp information, NLST is
- better.
-
- 3.11.4.3. Downloading a Directory Tree
-
- MLSD is the only choice for recursive downloads; they rarely, if ever,
- work with NLST (the few cases where they do work rely on
- extra-protocol "secret" notations for the NLST argument). No special
- actions are required to force MLSD when the server supports it, unless
- you have disabled it. Examples:
-
- MGET /RECURSIVE
- This tells the server to send all files and directories in the
- tree rooted at its current directory.
-
- MGET /RECURSIVE *.txt
- This tells the server to send all *.txt files in the tree
- rooted at its current directory.
-
- MGET /MLSD /RECURSIVE *.txt
- Same as the previous example but forces Kermit to send MLSD in
- case it was disabled, or in case the server is known to support
- it even though it did not announce it in its FEAT listing.
-
- MGET /RECURSIVE /MATCH:*.zip archives
- Tells the server to send all ZIP files in the tree rooted at
- its "archives" directory.
-
- MGET /RECURSIVE /MATCH:* [abc]
- The server is running on VMS and you want it to send all the
- files in the directory tree rooted at [ABC]. But since "[abc]"
- looks just like a wildcard, you have to include a /MATCH:
- switch to force Kermit to send "[abc]" as the MLSD argument.
-
- In all cases in which the /RECURSIVE switch is included, the server's
- tree is duplicated locally.
-
- Although MLSD allows recursion and NLST does not, the MLSD
- specification places a heavy burden on the client; the obvious,
- straightforward, and elegant implementation (depth-first, the one
- that Kermit currently uses) requires as many open temporary files
- as the server's directory tree is deep, and therefore client
- resource exhaustion -- e.g. exceeding the maximum number of open
- files -- is a danger. Unfortunately MLSD was not designed with
- recursion in mind. (Breadth-first traversal could be problematic
- due to lack of sufficient navigation information.)
-
- Of course all of Kermit's other MGET switches can be used too, e.g.
- for finer-grained file selection (by date, size, etc), for moving or
- renaming files as they arrive, to override Kermit's automatic per-file
- text/binary mode switching, to pass the incoming files through a
- filter, to convert text-file character sets, and so on.
-
- 3.11.4.4. NLST/MLSD Summary Table
-
- Here's a table summarizing MGET behavior when the server supports both
- NLST and MLSD. /NLST and /MLSD switches are included for clarity to
- indicate which protocol is being used, and the expected effects. In
- practice you can omit the /NLST and /MLSD switches and the Kermit
- client chooses the appropriate or desired protocol as described above.
- Sample commands presume a Unix file system on the server, but of
- course the server can have any file system or syntax at all.
-
- User's Command FTP Sends Remarks
- mget /nlst NLST Gets a list of all the files in the server's current
- and downloads each file. The list includes names only, so Kermit also
- must send SIZE and MDTM directives if size and timestamp information
- is required (this is always true of NLST). Sending NLST without an
- argument is allowed by the RFC959 NLST definition and by the Kermit
- FTP client, but might not work with other clients, and also might not
- work with every server.
- mget /nlst foo NLST foo If "foo" is a directory, this gets a list of
- all the files from the server's "foo" directory and downloads each
- file; otherwise this downloads the file named "foo" (if any) from the
- server's current directory.
- mget /nlst *.txt NLST *.txt Gets a list of the files in the server's
- current directory whose names match the pattern *.txt, and then
- downloads each file from the list. Because we are using NLST, we send
- the filespec (*.txt) to the server and the server interprets any
- wildcards.
- mget /nlst foo/*.txt NLST foo/*.txt Gets a list of the files in the
- server's "foo" directory whose names match the pattern *.txt, and then
- downloads each file from the list (server interprets wildcards).
- mget /nlst /match:*.txt NLST Gets a list of all the files in the
- server's current directory and then downloads each one whose name
- matches the pattern *.txt (client interprets wildcards).
- mget /nlst /match:*.txt foo NLST foo Gets a list of all the files in
- the server's "foo" directory and then downloads each one whose name
- matches the pattern *.txt (client interprets wildcards).
- mget /mlsd MLSD Gets a list of all the files from the server's current
- directory and then downloads each one. The list might include size and
- timestamp information, in which case Kermit does not need to send SIZE
- and MDTM directives for each file (this is always true of MLSD).
- mget /mlsd foo MLSD foo Gets a list of all the files from the server's
- "foo" directory (where the string "foo" does not contain wildcards)
- and then downloads each one. If "foo" is a regular file and not a
- directory, this command is supposed to fail, but some servers have
- been observed that send the file.
- mget /mlsd *.txt MLSD Gets a list of all the files from the server's
- current directory and then downloads only the ones whose names match
- the pattern "*.txt". Because we are using MLSD and the MGET filespec
- is wild, we do not send the filespec to the server, but treat it as
- though it had been given in a /MATCH: switch and use it locally to
- match the names in the list.
- mget /mlsd foo/*.txt MLSD This one won't work because MLSD requires
- that the notions of server directory and filename-matching pattern be
- separated. However, the client, which can't be expected to know the
- server's file-system syntax, winds up sending a request that the
- server will (or should) reject.
- mget /mlsd /match:*.txt MLSD Gets a list of all the files from the
- server's current directory and then downloads only the ones whose
- names match the pattern "*.txt" (client interprets wildcards).
- mget /mlsd /match:*.txt foo MLSD foo If "foo" is a directory on the
- server, this gets a list of all the files from the server's "foo"
- directory and then downloads only the ones whose names match the
- pattern "*.txt" (client interprets wildcards). This leaves the server
- CD'd to the "foo" directory; there's no way the client can restore the
- server's original directory because MLSD doesn't give that
- information, and since the client can not be expected to know the
- server's file-system syntax, it would not be safe to guess. If "foo"
- is a regular file, MLSD fails.
- mget /mlsd foo bar MLSD This one is problematic. You're supposed to be
- able to give MGET a list a filespecs; in this case we name two
- directories. The client must change the server's directory to "foo" to
- get the list of files, and then the files themselves. But then it has
- no way to return to the server's previous directory in order to do the
- same for "bar", as explained in the previous example.
- mget /mlsd /match:* [abc] MLSD [abc] Including a /MATCH: switch forces
- [abc] to be sent to the server even though the client would normally
- think it was a wildcard and hold it for local interpretation. In this
- example, [abc] might be a VMS directory name.
- mget /mlsd /match:* t*.h MLSD t*.h Contrary to the MLSD specification,
- some MLSD-capable FTP servers do interpret wildcards. This form of the
- MGET command can be used to force a wildcard to be sent to the server
- for interpretation.
-
- When MLSD is used implicitly (that is, without an /MLSD switch given
- to force the use of MLSD) and an MGET command such as "mget foo/*.txt"
- fails, Kermit automatically falls back to NLST and tries again.
- _________________________________________________________________
-
- 3.11.5. References
-
- 1. Postel, J., and J. Reynolds, File Transfer Protocol (FTP), RFC
- 959, October 1985: [361]ftp://ftp.isi.edu/in-notes/rfc959.txt.
- 2. Hethmon, P, and R. Elz, Feature negotiation mechanism for the File
- Transfer Protocol, RFC 2389, August 1998:
- [362]ftp://ftp.isi.edu/in-notes/rfc2389.txt.
- 3. Elz, R, and P. Hethmon, Extensions to FTP, Internet Draft
- draft-ietf-ftpext-mlst-16.txt, September 2002:
- [363]http://www.ietf.org/internet-drafts/draft-ietf-ftpext-mlst-16
- .txt.
- 4. [364]The Kermit FTP Client (overview).
-
- [ [365]Top ] [ [366]FTP Top ] [ [367]C-Kermit Home ] [ [368]Kermit
- Home ]
- __________________________________________________________________________
-
-4. FILE SCANNING
-
- A new feature called file scanning is used in various contexts to
- determine if a file is text or binary, and if it is text, what kind of
- text. The overhead of file scanning is surprisingly tolerable, usually
- about a quarter second per file. File scanning is now used instead of
- filename patterns unless you SET FILE SCAN OFF, which restores the
- previous behavior.
-
- The primary benefit of file scanning is in file transfer. For all
- practical purposes, now you can stop worrying about whether a file
- should be sent in binary or text mode, or about sending mixtures of
- text and binary files in a single operation, or configuring and
- fine-tuning your lists of binary-file and text-file name patterns: now
- it all just works.
-
- File scanning is done by the file sender, which determines the type of
- each file before it sends it and informs the receiver (Kermit or FTP
- server) of the type. File scanning is NOT done by the receiver,
- because it is the sender's responsibility to determine each file's
- type, send the file in the right mode, and inform the receiver of the
- mode. If both transfer partners are capable of this (or any other)
- form of automatic text/binary mode switching, then files can be sent
- in both directions with no worries about corruption due to
- inappropriate transfer mode. (As noted in [369]Section 3, FTP servers
- don't do this, so this discussion does not apply when using Kermit to
- download from an FTP server.)
-
- The rest of this section is mainly for the curious. If you don't read
- it and simply accept all defaults, every file you send should go in
- the appropriate mode automatically. As always, however, for
- character-set translation to work for 7- and 8-bit character-set
- files, the appropriate SET FILE CHARACTER-SET command(s) must have
- been executed to identify their encoding (Kermit's default file
- character-set is neutral ASCII except on platforms like HP-UX or
- DG/UX, where the default file character-set is known). And of course,
- receiving is another matter -- obviously the other Kermit must also
- send each file in the appropriate mode.
-
- Scanning is more reliable than filename patterns simply because
- filenames are not reliable indicators of the file's contents. Classic
- examples include ".doc" files, which are binary if Microsoft Word
- documents but text on most other platforms, and ".com" files, which
- are binary on DOS and Windows but text on VMS. Anyway, nobody knows
- the naming conventions (if any) of all the applications (and persons!)
- on your computer. Scanning, on the other hand, determines each file's
- type by inspecting its contents rather than just looking at its name.
-
- Also, file patterns -- even when they work as intended -- categorize
- each file only as text or binary, whereas file scanning can make finer
- distinctions:
-
- BINARY
- Binary data, not to be converted in any way. Examples include
- binary machine code (executable programs), graphics images
- (GIF, JPG, etc), compressed files (Z, GZ, etc), archives and
- packages (ZIP, TAR, RPM, etc), object files and libraries (OBJ,
- DLL, etc).
-
- 7-BIT TEXT
- Text encoded in a 7-bit character set such as ASCII or one of
- the ISO 646 national versions. Kermit has no way to tell which
- character is used, only that it's 7-bit text. Typical examples
- include program source code, README files, Perl or Kermit
- scripts, plain-text email, HTML, TeX, and various textual
- encodings of binary files: Hex, Base64, etc. When sending such
- files, the FILE DEFAULT 7BIT-CHARACTER-SET is used as the file
- character-set, and then the appropriate transfer character set
- is chosen from the associations list (ASSOCIATE, SHOW
- ASSOCIATIONS).
-
- 8-BIT TEXT
- Text encoded in an 8-bit character set such as Latin-1,
- Latin-2, Latin/Hebrew, Latin/Cyrillic, KOI8, HP-Roman8, JIS X
- 0208, Code Page 437, or Code Page 1252. Again, Kermit has no
- way of knowing which particular set is in use, only that it's
- 8-bit text. When sending such files, the FILE DEFAULT
- 8BIT-CHARACTER-SET is used as the file character-set, and then
- the appropriate transfer character set is chosen from the
- associations list.
-
- UCS2 TEXT
- Unicode in its basic form, 16 bits (2 octets) per character.
- When sending such files, UCS2 is the file character-set and the
- byte order is identified automatically; the appropriate
- transfer character set is chosen from the associations list.
- Normally this would be UTF8. UTF-16 is not supported yet;
- Kermit's Unicode translations are restricted to Plane 0, the
- Base Multilingual Plane (BMP).
-
- UTF8 TEXT
- Unicode in its 8-bit transformation format. When sending such
- files, UTF8 is the file character-set; the appropriate transfer
- character set is chosen from the associations list, normally
- UCS2 or UTF8.
-
- File scanning is available in UNIX C-Kermit, in K-95, and to a limited
- extent, in VMS C-Kermit (full scanning is problematic in VMS because
- even plain-text files might contain binary record-format information).
- The relevant commands are:
-
- SET TRANSFER MODE { AUTOMATIC, MANUAL }
- Tells whether the file-transfer mode (text or binary) should be
- set by automatic or "manual" means. AUTOMATIC is the default,
- which allows any of the automatic methods that are enabled to
- do their jobs: FILE SCAN, FILE PATTERNS, peer recognition, etc.
- MANUAL lets you control the transfer mode with the SET FILE
- TYPE commands. As always, /TEXT and /BINARY switches on your
- file-transfer commands override all other methods; if you give
- one of these switches, scanning is not done. SHOW TRANSFER
- displays the current TRANSFER MODE setting.
-
- SET FILE SCAN { ON [ number ], OFF }
- Turns this feature on and off. It's ON by default. When OFF,
- the previous rules apply (SET FILE PATTERNS, etc). When ON is
- given, you can also specify a number of bytes to be scanned.
- The default is 49152 (= 48K). If a negative number is given,
- the entire file is scanned, no matter how big, for maximum
- certainty (for example, a PostScript file that appears to be
- plain text might include an embedded graphic past the normal
- scanning limit). SHOW FILE displays the current FILE SCAN
- setting.
-
- SET FILE DEFAULT 7BIT-CHARACTER-SET name
- Tells the 7-bit character-set to use if scanning identifies a
- 7-bit text file, e.g. GERMAN. SHOW FILE displays the current
- SET FILE DEFAULT settings. So does SHOW CHARACTER-SETS.
-
- SET FILE DEFAULT 8BIT-CHARACTER-SET name
- Tells the 8-bit character-set to use if scanning identifies an
- 8-bit text file, e.g. LATIN1. SHOW FILE and SHOW CHARACTER-SET
- display this.
-
- ASSOCIATE FILE-CHARACTER-SET fcs tcs
- When sending files and a file character-set (fcs) is identified
- by scanning, this tells C-Kermit which transfer character-set
- (tcs) to translate it to. It also allows C-Kermit to set the
- appropriate transfer character-set automatically whenever you
- give a SET FILE CHARACTER-SET command.
-
- ASSOCIATE TRANSFER-CHARACTER-SET tcs fcs
- When receivinging files and a file arrives whose transfer
- character-set (tcs) is announced by the sender, this command
- tells C-Kermit which file character-set (fcs) to translate it
- to. It also allows C-Kermit to set the appropriate file
- character-set whenever you give a SET TRANSFER CHARACTER-SET
- command.
-
- SET FILE CHARACTER-SET name
- When given for a 7-bit set, also sets FILE DEFAULT
- 7BIT-CHARACTER-SET to the same set. When given for an 8-bit
- set, also sets FILE DEFAULT 8BIT-CHARACTER-SET to the same set.
- If an ASSOCIATE FILE-CHARACTER-SET command has been given for
- this set, also sets the corresponding transfer character-set.
-
- DIRECTORY /XFERMODE [ filespec ]
- Performs a file scan of the given files, listing the result for
- each file. If FILE SCAN is OFF but PATTERNS are ON, the result
- shown according to the current FILE TEXT-PATTERNS and
- BINARY-PATTERNS, and are restricted to (B) and (T). When FILE
- SCAN is ON, the results are:
-
- (B) Binary
- (T)(7BIT) Text: 7-bit
- (T)(8BIT) Text: 8-bit
- (T)(UTF8) Text: Unicode UTF8
- (T)(UCS2BE) Text: Unicode UCS2 Big Endian
- (T)(UCS2LE) Text: Unicode UCS2 Little Endian
-
- So you can use DIR /XFER to get a preview of how each file in a
- selected group will be transferred. Everything to the right of
- the (B) or (T) is new. If FILE SCAN is OFF, you only get the
- (B) or (T) as before.
-
- Note: Big and Little Endian refer to the ordering of bytes
- within a computer word. Big Endian architecture is standard and
- is used on most non-PC computers. Little Endian architecture is
- used on PCs.
-
- To illustrate file-transfer with scanning, suppose you have a
- directory containing a mixture of text and binary files, and each text
- file can be 7-bit German ISO 646, 8-bit Latin-1, or Unicode in any of
- the following forms: UCS2 Little Endian, UCS2 Big Endian, or UTF8
- ([370]UTF-16 is not supported yet). Assuming all the built-in defaults
- are in effect, the following three commands do the job:
-
- set file char german ; This sets the default for 7-bit text files
- set file char latin1 ; This sets the default for 8-bit text files
- send *
-
- Each file is sent in the appropriate mode (text or binary), with text
- files converted to the appropriate transfer character-set and labeled
- so the receiver can convert them according to its own local
- conventions.
-
- By the way, what if you want to inhibit character-set translation but
- still allow automatic text/binary mode switching? Previously, you
- could simply SET TRANSFER CHARACTER-SET TRANSPARENT. But now with file
- scanning, the file and transfer character-sets are set automatically
- per file. A new command was added for this purpose:
-
- SET TRANSFER TRANSLATION { ON, OFF }
- Enables and disables file-transfer character-set translation.
- It is enabled by default.
-
- When TRANSFER TRANSLATION is OFF but FILE SCAN is ON, files are still
- scanned to see if they are text or binary, but no character-set
- translation is done when they text: only the normal record-format
- conversion.
-
- Like all SET commands, SET TRANSFER TRANSLATION is global and
- persistent. You can also force a particular file-transfer command
- (SEND, MSEND, GET, RECEIVE, TRANSMIT, etc) to not translate without
- affecting the global translation settings by including the new
- /TRANSPARENT switch, e.g.
-
- send /transparent oofa.txt
-
- As of C-Kermit 8.0.206, SET TRANSFER CHARACTER-SET TRANSPARENT implies
- SET TRANSFER TRANSLATION OFF.
-
- File scanning is also used in the TYPE command. The source file type
- and character set are determined as above, and then the file is
- automatically converted to your display character-set, line by line.
- In Kermit 95, the display character-set is Unicode, perhaps converted
- to your current console code page; in other versions of C-Kermit, it
- is your current file character-set. Thus if you have the following set
- appriately:
-
- SET FILE CHARACTER-SET (necessary in Unix but not K95)
- SET FILE DEFAULT 7BIT CHARACTER-SET
- SET FILE DEFAULT 8BIT CHARACTER-SET
-
- then you should be able to TYPE any text file and see something
- reasonable. For example, in Unix, if your DEFAULT 7BIT-CHARACTER-SET
- is ITALIAN and your DEFAULT 8BIT-CHARACTER-SET is LATIN1, and your
- FILE CHARACTER-SET is LATIN1, you can TYPE an Italian ISO 646 file, a
- Latin-1 file, or any kind of Unicode file, and have it translated
- automatically to Latin-1 for your display.
-
- In the GUI version of Kermit 95, you can see mixtures of many
- different scripts if the file is UTF8 or UCS2: Roman, Cyrillic,
- Hebrew, Greek, Armenian, Georgian, etc, all on the same screen at
- once.
-
- File scanning also adds a new criterion for file selection, i.e. to
- select only text (or binary) files. Several commands now include a new
- switch, /TYPE:{BINARY,TEXT,ALL}. BINARY means select only binary
- regular files (not directories). TEXT means select only text files.
- ALL means don't scan; select all files. Examples:
-
- SEND /TYPE:BINARY *.*
- Sends only binary files, skipping over text files.
-
- NOTE: File scanning is NOT done when using external protocols (because
- the external protocol programs, such as sz, are processing each file,
- not Kermit).
-
- DIRECTORY /TYPE:TEXT
- Lists only text files but not binary files.
-
- DELETE /TYPE:BINARY foo.*
- Deletes all foo.* files that are regular binary files but does
- not delete any text files.
-
- CHMOD /TYPE:BINARY 775 *
- (UNIX) Changes the permissions of all binary files to 775.
-
- When FILE SCAN is OFF and FILE PATTERNS are ON, behavior is as before
- with PATTERNS ON, but with some improvements:
-
- * Pathnames are now stripped prior to pattern matching.
- * Backup suffixes (like .~3~) are stripped prior to pattern
- matching.
-
- [ [371]Top ] [ [372]Contents ] [ [373]C-Kermit Home ] [ [374]Kermit
- Home ]
- __________________________________________________________________________
-
-5. FILE AND DIRECTORY NAMES CONTAINING SPACES
-
- Prior to the introduction of the graphical user interface (GUI), it
- was inconceivable that file or directory names could contain spaces,
- because space is a field delimiter in all command languages. GUIs,
- however, use dialog boxes for filenames, so there is never any
- question of distinguishing a filename from adjacent fields -- because
- there are no adjacent fields -- and therefore it has become quite
- common on computers that have GUIs to have file and directory names
- composed of multiple words. Of course this poses problems for command
- shells and other text-oriented programs.
-
- Most command shells address these problems by allowing such names to
- be enclosed in doublequotes, e.g.:
-
- cd "c:\Program Files"
-
- C-Kermit previously used braces for this:
-
- cd {c:\Program Files}
-
- which was not what most people expected. And even when braces were
- used, Kermit had difficulties with completion, file menus, and so
- forth, within braced fields.
-
- C-Kermit 8.0 allows either doublequotes or braces to be used for
- grouping:
-
- send "this file"
- send {this file}
- rename "this file" "that file"
- rename {this file} "that file"
- rename "this file" {that file}
- cd {Program Files}
- cd "Program Files"
-
- Note that the doublequotes or brackets must enclose the whole file or
- directory specification:
-
- "c:\My Directory"
-
- not:
-
- c:\"My Directory"
-
- In C-Kermit 8.0, you can also use completion on these filenames, in
- which case Kermit supplies the quotes (or braces) automatically.
- Example (in which the current directory contains only one file whose
- name starts with "th" and its full name is "this file" (without the
- quotes, but with the space)):
-
- cat th<Tab>
-
- Kermit repaints the filename field like this:
-
- cat "this file"
-
- That is, it backspaces over the original "th" and then writes the
- filename in doublequotes.
-
- If completion is only partial, Kermit still supplies the quotes, but
- in this case also beeps. To continue the filename, you must first
- backspace over the closing quote. The closing quote is supplied in
- this case to make sure that you can see the spaces, especially if they
- are trailing. For example, if the current directory contains two files
- whose names start with "th", and their fill names are "this file" and
- "this other file":
-
- cat th<Tab>
-
- Kermit prints:
-
- cat "this "<Beep>
-
- If it didn't print the closing quote, you would probably wonder why it
- was beeping.
-
- Also, if you begin a filename field with a doublequote or opening
- brace, now you can use completion or get ?-help; this was never
- possible before.
-
- C-Kermit>type "thi? Input file specification, one of the following:
- this file this other file
- C-Kermit>type "thi_
-
- [ [375]Top ] [ [376]Contents ] [ [377]C-Kermit Home ] [ [378]Kermit
- Home ]
- __________________________________________________________________________
-
-6. OTHER COMMAND PARSING IMPROVEMENTS
-
- 6.1. Grouping Macro Arguments
-
- Doublequotes now can be used in macro invocations to group arguments
- containing spaces, where previously only braces could be used:
-
- define xx show args
- xx one "this is two" three
-
- Result:
-
- Macro arguments at level 0 (\v(argc) = 4):
- \%0 = xx
- \%1 = one
- \%2 = this is two
- \%3 = three
-
- Also, you can now quote braces and quotes in macro args (this didn't
- work before). Examples:
-
- xx "{" ; The argument is a single left brace
- xx {"} ; The argument is a doublequote character
-
- In case this new behavior interferes with your scripts, you can
- restore the previous behavior with:
-
- SET COMMAND DOUBLEQUOTING OFF
-
- 6.2. Directory and File Name Completion
-
- C-Kermit 8.0 also includes better completion for directory names, e.g.
- in the CD command. If the name typed so far uniquely matches a
- directory name, it is completed (as before), but now if the directory
- contains any subdirectories, completion is partial (allowing you to
- supply additional path segments without backspacing); otherwise it is
- complete.
-
- Completion has also been improved for file and directory names that
- contain not only spaces (as described above) but also "metacharacters"
- such as asterisk (*) and tilde (~): now the field is repainted if
- necessary. For example, if the current directory contains only one
- file whose name contains "blah", then in:
-
- type *blah<Tab>
-
- "*blah" is replaced by the filename. In earlier releases, the part
- typed so far was left on the command line (and in the history buffer),
- so even when the original command worked, the recalled version would
- not. Similarly for ~ (the nearly-universal Unix notation for
- username):
-
- type ~olga/x<Tab>
-
- is repainted as (e.g.):
-
- type /users/home/olga/x(Beep)
-
- Speaking of command history, the new SHOW HISTORY command shows your
- command history and recall buffer. SAVE COMMAND HISTORY saves it into
- a file of your choice.
-
- 6.3. Passing Arguments to Command Files
-
- The method for passing arguments to command files has been improved.
- Prior to C-Kermit 7.0 there was no provision for doing this. In
- C-Kermit 7.0, the TAKE command was changed to allow arguments to be
- given after the filename:
-
- take commandfile arg1 arg2 ...
-
- This was accomplished by replacing the current \%1, \%2, etc, with the
- given arguments, since a new set of macro argument variables is
- created only when a macro is executed, not a command file. It is much
- more intuitive, however, if arguments to command files worked like
- those to macros: the command file sees the arguments as its own \%1,
- \%2, etc, but the caller's variables are not disturbed. C-Kermit 8.0
- accomplishes this by automatically creating an intermediate temporary
- macro to start the command file (if any arguments were given), thus
- creating a new level of arguments as expected.
-
- 6.4. More-Prompting
-
- The familiar --more?-- prompt that appears at the end of each
- screenful of command-response output now accepts a new answer: G (Go)
- meaning "show all the rest without pausing and asking me any more
- questions". P (Proceed) is a synonym for G.
-
- 6.5. Commas in Macro Definitions
-
- As noted in the [379]C-Kermit manual, comma is used to separate
- commands in a macro definition. Even when the macro is defined on
- multiple lines using curly-brace block-structure notation without
- commas, the definition is still stored internally as a comma-separated
- list of commands. Therefore special tricks are needed to include a
- comma in a command. The classic example is:
-
- define foo {
- (some command)
- if fail echo Sorry, blah failed...
- }
-
- This would result in Kermit trying to execute a "blah" command. This
- could always be handled by enclosing the text in braces:
-
- define foo {
- (some command)
- if fail echo {Sorry, blah failed...}
- }
-
- but doublequotes (more intuitive) should have worked too. Now they do:
-
- define foo {
- (some command)
- if fail echo "Sorry, blah failed..."
- }
-
- 6.6. Arrow Keys
-
- As of version 8.0.201, C-Kermit on most platforms lets you access the
- command history buffer with arrow keys, just as you always could with
- control characters. The restrictions are:
-
- 1. Only Up and Down arrow keys are accepted.
- 2. Only 7-bit ANSI arrow-key sequences are understood (ESC followed
- by [ or uppercase letter O, followed by uppercase letter A or (up)
- B (down).
-
- This change was made to facilitate command recall in Linux-based PDAs
- that don't have a Control key, or at least not one that's easily (or
- always) accessible, such as the Sharp Zaurus SL5500.
-
- [ [380]Top ] [ [381]Contents ] [ [382]C-Kermit Home ] [ [383]Kermit
- Home ]
- __________________________________________________________________________
-
-7. NEW COMMANDS AND SWITCHES
-
- See [384]Section 4 for more about file scanning and the /TYPE: switch.
-
- ASK[Q] [ /TIMEOUT:number /QUIET /DEFAULT:text ] variable [ prompt ]
- The new optional /TIMEOUT: switch for ASK and ASKQ causes the
- command to time out and and fail if no response is given within
- the specified number of seconds, 1 or greater (0 or less means
- no timeout, wait forever). This works just like SET ASK-TIMER,
- except its effect is local to the ASK command with which it is
- given and it does not disturb the global ask timer setting. The
- new /QUIET switch tells Kermit not to print an error message if
- the ASK or ASKQ command times out waiting for a response.
-
- Version 8.0.211 adds the /DEFAULT:text switch for ASK-Class
- commands (ASK, ASKQ, and GETOK). This lets you supply a default
- answer in case the user supplies an empty answer or the
- /TIMEOUT: switch was included and the time limit expired
- without an answer. In both these cases, the command succeeds.
-
- CAT filename
- Equivalent to TYPE /NOPAGE.
-
- CDUP
- Changes Kermit's local working directory to the parent of the
- current one. Equivalent to "cd .." in UNIX or Windows, "cd [-]"
- in VMS, "cd ^" in AOS/VS, etc; in other words, it's a
- platform-independent way of moving one level up in a directory
- tree.
-
- CHMOD [ switches ] permission files
- UNIX only. Sets file permissions for one or more files or
- directories. The permission must be given as an octal number,
- e.g. 664, 755. Switches: /DIRECTORIES, /FILES, /NOLIST, /PAGE,
- /DOTFILES, /LIST, /NOPAGE, /RECURSIVE, /TYPE:{TEXT,BINARY,ALL},
- /SIMULATE. The /TYPE: switch allows selection of only text or
- binary files. For example, if you have a mixture of source
- files and executables, you can use "chmod /files /type:text
- 664" to give owner/group read/write and world read permission
- to the text files, and "chmod /files /type:binary 775" to give
- the same plus execute permission to the executables. Use
- /SIMULATE to see which files would be affected, without
- actually changing their permissions.
-
- CLEAR KEYBOARD-BUFFER
- Flushes any as-yet unread characters from the keyboard input
- buffer. Useful for flushing typeahead in scripts.
-
- CONTINUE
- When given at an interactive command prompt that was reached by
- issuing a PROMPT command (described in this section) from a
- script, this command returns to the script, continuing its
- execution at the command after the PROMPT command. In this
- context, CONTINUE is simply a more-intuitive synonym for END.
-
- COPY, RENAME, and TRANSLATE
- These commands now work on file groups if the target filename
- is a directory, e.g. "copy oofa.* ..", "rename * ~olga/tmp/"
-
- COPY /APPEND source destination
- The source file specification can now include wildcards, in
- which case all of the source files that match will go into the
- destination file in alphabetical order by name.
-
- DELETE /ASK
- Asks permission to delete each file before deleting it. In
- C-Kermit 7.0, the answers were "yes" (or "ok") and "no".
- C-Kermit 8.0 adds "go" (meaning, delete all the rest without
- asking) and "quit" (cancel the DELETE command and return to the
- prompt).
-
- DELETE /DIRECTORIES
- Deletes not only files but also directories.
-
- DELETE /RECURSIVE
- Deletes all files that match the given file specification in
- the current (or given) directory and all directories beneath
- it.
-
- DELETE /SUMMARY
- Prints only the number of files deleted and total size freed,
- without listing each file.
-
- DELETE /TREE
- Shorthand for DELETE /RECURSIVE /DIRECTORIES /DOTFILES/.
- Equivalent to Windows DELTREE or Unix "rm -Rf". If no file
- specification is given, the contents of the current directory,
- plus all of its subdirectories and their contents, are deleted.
-
- DELETE /TYPE:BINARY
- Delete only regular binary files (requires FILE SCAN ON).
-
- DELETE /TYPE:TEXT
- Delete only regular text files (requires FILE SCAN ON).
-
- DIRECTORY [ switches ] [ filespec [ filespec [ filespec ... ] ] ]
- The DIRECTORY command now accepts more than one file
- specification; e.g. "directory moon.txt sun.doc stars.*".
-
- DIRECTORY /NORECURSIVE xxx
- If xxx is a directory name, forces listing of the directory
- itself rather than its contents.
-
- DIRECTORY /FOLLOWLINKS xxx
- (UNIX only) Tells the DIRECTORY command to follow symbolic
- links. This not the default because it can cause endless loops.
-
- DIRECTORY /NOFOLLOWLINKS xxx
- (UNIX only) Tells the DIRECTORY command not to follow symbolic
- links, but rather, merely to list them. This is the default.
-
- DIRECTORY /OUTPUT:filename
- Sends the results of the DIRECTORY command to the given file.
-
- DIRECTORY /SUMMARY
- Prints only the number of directories and files and the total
- size, without listing each file.
-
- DIRECTORY /TYPE:{TEXT,BINARY}
- Shows only files of the selected type, based on file scan.
-
- DIRECTORY /XFERMODE
- Now shows results of file scan (see [385]Section 4).
-
- FOPEN [ switches ] channel filename
-
- As of version 8.0.211, FOPEN allows /dev/tty as a filename in
- Unix-based operating systems.
-
- FREAD /TRIM
- (8.0.211) Trims any trailing blanks or tabs from the item (such
- as a line of text) that it has read.
-
- FREAD /UNTABIFY
- (8.0.211) Converts Horizontal Tab characters to the appropriate
- number of spaces, based on VT100-like tab stops
- (1,9,17,25,...).
-
- GREP [ switches ] pattern files
- Similar to Unix grep command: displays file lines that match
- the given [386]pattern. Switches:
-
- /COUNT[:variable]
- Don't show the matching lines, just tell how many lines
- match. If a variable name is specified, the count is
- stored in the given variable.
-
- /DOTFILES
- Include files whose names begin with dot.
-
- /LINENUMBERS
- Show line numbers of matching lines.
-
- /NAMEONLY
- only list the names of files that contain matching lines,
- but not the lines themselves.
-
- /NOBACKUP
- Skip backup files.
-
- /NOCASE
- Ignore alphabetic case while pattern matching.
-
- /NODOTFILES
- skip files whose names start with dot (period).
-
- /NOLIST
- Suppress output but set SUCCESS or FAILURE according to
- search result.
-
- /NOMATCH
- Look for lines that do not match the pattern.
-
- /NOPAGE
- Don't pause between screens of output.
-
- /OUTPUT:filename
- Write results into the given file.
-
- /PAGE
- Pause between screens of output.
-
- /RECURSIVE
- Search files in subdirectories too.
-
- /TYPE:{TEXT,BINARY}
- Search only files of the specified type.
-
- Synonyms: FIND, SEARCH.
-
- GETOK /TIMEOUT:n /QUIET /DEFAULT:text
- The new /QUIET switch instructs GETOK, when given a timeout,
- not to print an error message if it times out. As of 8.0.211, a
- default answer can be supplied (see ASK).
-
- HEAD [ switches ] filename
- Equivalent to TYPE /HEAD [ other-switches ] filename.
-
- HELP DATE
- Explains date-time formats, including timezone notation and
- delta times.
-
- HELP FIREWALLS
- Explains the firewall negotiation capabilities of your version
- of Kermit.
-
- KCD [ symbolic-directory-name ]
- Changes Kermit's working directory to the named symbolic
- directory, such as such as exedir, inidir, startup, download,
- or and home. Type "kcd ?" for a list of symbolic directory
- names known to your copy of Kermit, or give the new ORIENTATION
- command for a more detailed explanation. If you give a KCD
- command without a directory name, Kermit returns to its "home"
- directory, which is determined in some way that depends on the
- underlying operating system, but which you can redefine with
- the (new) SET CD HOME command. Your home directory is shown by
- SHOW CD and it's also the value of the \v(home) variable.
-
- LICENSE
- Displays the C-Kermit license.
-
- L-commands
- When Kermit has a connection to a Kermit or FTP server, file
- managment commands such as CD, DIRECTORY, and DELETE might be
- intended for the local computer or the remote server. C-Kermit
- 8.0.200 and earlier always executes these commands on the local
- computer. If you want them executed by the remote server, you
- have to prefix them with REMOTE (e.g. REMOTE CD) or use special
- R-command aliases (e.g. RCD = REMOTE CD, RDIR = REMOTE DIR,
- etc). But this feels unnatural to FTP users, who expect
- unprefixed file management commands to be executed by the
- remote server, rather than locally. C-Kermit 8.0.201 adds
- automatic locus switching to present an FTP-like interface for
- FTP connections and the normal Kermit interface for Kermit
- connections, and a SET LOCUS command (described below) to
- control whether or how this is done. For when LOCUS is REMOTE,
- a new set of commands was added for local management: LCD
- (Local CD), LDIR (Local DIR), etc. These are described below
- under SET LOCUS.
-
- MORE filename
- Equivalent to TYPE /PAGE.
-
- ORIENTATION
- Displays symbolic directory names and the corresponding
- variable names and values. The symbolic names, such as exedir,
- inidir, startup, download, and home, can be used as arguments
- to the new KCD command.
-
- PROMPT [ text ]
- For use in a macro or command file: enters interactive command
- mode within the current context ([387]Section 8.1). If the
- optional text is included, the prompt is set to it. The text
- can include variables, functions, etc, as in the SET PROMPT
- command. They are evaluated each time the prompt is printed.
- Unlike the SET PROMPT command, the text argument applies only
- to the current command level. Thus you can have different
- prompts at different levels.
-
- REMOTE SET MATCH { DOTIFILE, FIFO } { ON, OFF }
- Allows the client to tell the server whether wildcards sent to
- the server should match dot files (files whose names begin with
- period) or FIFOs (named pipes). See SET MATCH.
-
- SET ATTRIBUTE RECORD-FORMAT { ON, OFF }
- Allows control of the Kermit's Record-Format attribute. Set
- this to OFF in case incoming file are refused due to unknown or
- invalid record formats if you want to accept the file anyway
- (and, perhaps, postprocess it to fix its record format).
-
- SET CD HOME [ directory ]
- Specifies the target directory for the CD and KCD commands,
- when they are given without an argument, and also sets the
- value of the \v(home) variable.
-
- SET EXIT HANGUP { OFF, ON }
- Normally ON, meaning that when Kermit exits, it also explicitly
- hangs up the current SET LINE / SET PORT serial port according
- to the current SET MODEM TYPE and SET MODEM HANGUP METHOD, and
- closes the port device if it was opened by Kermit in the first
- place (as opposed to inherited). SET EXIT HANGUP OFF tells
- Kermit not to do this. This can't prevent the operating system
- from closing the device when Kermit exits (and it's a "last
- close") but if the port or modem have been conditioned to
- somehow ignore the close and keep the connection open, at least
- Kermit itself won't do anything explicit to hang it up or close
- it.
-
- SET FILE EOF { CTRL-Z, LENGTH }
- Specifies the end-of-file detection method to be used by
- C-Kermit when sending and receiving text files, and in the TYPE
- and similar text-file oriented commands. The normal and default
- method is LENGTH. You can specify CTRL-Z when handling CP/M or
- MS-DOS format text files, in which a Ctrl-Z (ASCII 26)
- character within the file marks the end of the file.
-
- SET FILE LISTSIZE number
- Allocates space for the given number of filenames to be filled
- in by the wildcard expander. The current number is shown by
- SHOW FILE. If you give a command that includes a filename
- containing a wildcard (such as "*") that matches more files
- that Kermit's list has room for, you can adjust the list size
- with this command.
-
- SET FILE STRINGSPACE number
- Allocates space for the given amount of filename strings for
- use by the wildcard expander. The current number is shown by
- SHOW FILE. The number is the total number of bytes of all the
- file specifications that match the given wildcard.
-
- If you need to process a bigger list of files than your computer
- has memory for, you might be able use an external file list. The
- Kermit SEND and the FTP PUT and GET commands accept a /LISTFILE:
- switch, which gives the name of a file that contains the list of
- files to be transferred. Example for UNIX:
-
- !find . -print | grep / > /tmp/names
- ftp put /update /recursive /listfile:/tmp/names
-
- SET LOCUS { AUTO, LOCAL, REMOTE }
- Added in C-Kermit 8.0.201. Sets the locus for unprefixed file
- management commands such as CD, DIRECTORY, MKDIR, etc. When
- LOCUS is LOCAL these commands act locally and a REMOTE (or R)
- prefix (e.g. REMOTE CD, RCD, RDIR) is required to send file
- management commands to a remote server. When LOCUS is REMOTE,
- an L prefix is required to issue local file management commands
- (e.g. LCD, LDIR). The word LOCAL can't be used as a prefix
- since it is already used for declaring local variables. LOCUS
- applies to all types of connections, and thus is orthogonal to
- SET GET-PUT-REMOTE, which selects between Kermit and FTP for
- remote file-transfer and management commands. The default LOCUS
- is AUTO, which means we switch to REMOTE whenever an FTP
- connection is made, and to LOCAL whenever a non-FTP connection
- is made, and switch back accordingly whenever a connnection is
- closed. So by default, Kermit behaves in its traditional manner
- unless you make an FTP connection, in which case it acts like a
- regular FTP client (but better :-) LOCUS applies to the
- following commands:
-
- Unprefixed Remote Local Description
- CD (CWD) RCD LCD Change (Working) Directory
- CDUP RCDUP LCDUP CD Up
- PWD RPWD LPWD Print Working Directory
- DIRECTORY RDIR LDIR Request a directory listinga
- DELETE RDEL LDEL Delete (a) file(s)
- RENEME RREN LREN Rename a file
- MKDIR RMKDIR LMKDIR Create a directory
- RMDIR RRMDIR LRMDIR Remove a directory
-
- SET MATCH { DOTIFILE, FIFO } { ON, OFF }
- Whether C-Kermit filename patterns (wildcards) should match
- filenames that start with dot (period), or (Unix only) FIFOs
- (named pipes). The defaults are to skip dotfiles in Unix but
- match them elsewhere, and to skip FIFOs. Applies to both
- interactive use and to server mode, when the server receives
- wildcards, e.g. in a GET command. Also see REMOTE SET MATCH.
-
- SET OPTIONS DIRECTORY /DOTFILES
- Now works for server listings too (UNIX only). Give this
- command prior to having Kermit enter server mode, and then it
- will show files whose names begin with dot (period) when sent a
- REMOTE DIRECTORY command.
-
- SET QUIET ON
- (as well as the -q command-line option) Now applies also to:
-
- + SET HOST connection progress messages.
- + "Press the X or E key to cancel" file-transfer message.
- + REMOTE CD response.
- + REMOTE LOGIN response.
-
- SET RECEIVE PERMISSIONS { ON, OFF }
- Tells C-Kermit whether to set the permissions of incoming files
- (received with Kermit protocol) from the permissions supplied
- in the file's Attribute packet (if any). Normally ON. Also see
- SET SEND PERMISSIONS.
-
- SET ROOT directory
- Like UNIX chroot, without requiring privilege. Sets the root
- for file access, does not allow reference to or creation of
- files outside the root, and can't be undone.
-
- SET SEND PERMISSIONS { ON, OFF }
- Tells C-Kermit whether to include file permissions in the
- attributes it includes with each file when sending with Kermit
- protocol. Also see SET RECEIVE PERMISSIONS.
-
- SET TCP { HTTP-PROXY, SOCKS-SERVER } /USER:name /PASSWORD:text
- These commands now allow specification of username and
- password.
-
- SET TERMINAL . . .
- (See [388]Section 12.)
-
- SET TRANSFER MESSAGE [ text ]
- Sets an initial text message to be displayed in the
- file-transfer display. The transfer message is automatically
- deleted once used, so must be set each time a message a
- desired. Any variables in the message are evaluated at the time
- the SET command is given. If the optional text is omitted, any
- transfer message that is currently set is removed. Synonym: SET
- XFER MSG. SHOW TRANSFER displays it if it has been set but not
- yet used.
-
- SHOW COMMUNICATIONS
- In C-Kermit 8.0, SHOW COMMUNICATIONS, when given in remote mode
- (i.e. before any connection has been established), tells the
- typical dialout device name for the particular platform on
- which it's running (e.g. TXA0: for VMS, or /dev/cua0p0 for
- HP-UX). On Unix platforms, it also tells the name of the
- lockfile directory. This way, you have an idea of what the SET
- LINE device name should look like, and if the SET LINE command
- fails, you know the name of the directory or device that is
- protected against you.
-
- SHOW VARIABLES [ name [ name [ ... ] ] ]
- In C-Kermit 8.0.201 you can request values of a list of
- built-in (\v(xxx)) variables. Each name is a pattern, as
- before, but now it a free pattern rather than an anchored one
- (explained in [389]Section 8.12) so now "show var date time"
- shows the values of all variables whose names include the
- strings "date" or "time".
-
- TAIL [ switches ] filename
- Equivalent to TYPE /TAIL [ other-switches ] filename.
-
- TRANSMIT /NOECHO [ other switches ] filename
- The /NOECHO switch is equivalent to giving the command SET
- TRANSMIT ECHO OFF prior to the TRANSMIT command, except the
- switch affects only the command with which it was given and
- does not affect the prevailing global setting.
-
- TRANSMIT /NOWAIT [ other switches ] filename
- The /NOWAIT switch is equivalent to giving the command SET
- TRANSMIT PROMPT 0 prior to the TRANSMIT command, except the
- switch affects only the command with which it was given and
- does not affect the prevailing global setting.
-
- TRANSMIT /NOWAIT /NOECHO /BINARY [ other switches ] filename
- When the TRANSMIT command is given with the /NOWAIT, /NOECHO,
- and /BINARY switches, this activates a special "blast the whole
- file out the communications connection all at once" mode that
- Kermit didn't have prior to version 8.0. There has been
- increasing demand for this type of transmission with the advent
- of devices that expect image (e.g. .JPG) or sound (e.g. .MP3)
- files as raw input. The obvious question is: how does the
- receiving device know when it has the whole file? This depends
- on the device, of course; usually after a certain amount of
- time elapses with nothing arriving, or else when Kermit hangs
- up or closes the connection.
-
- TYPE /CHARACTER-SET:name
- Allows you to specify the character set in which the file to be
- typed is encoded.
-
- TYPE /NUMBER
- Adds line numbers.
-
- TYPE /OUTPUT:filename
- Sends the results of the TYPE command to the given file.
-
- TYPE /TRANSLATE-TO:name
- Used in conjunction with TYPE /CHARACTER-SET:xxx; allows you to
- specify the character set in which the file is to be displayed.
-
- TYPE /TRANSPARENT
- Used to disable character-set translation in the TYPE command,
- which otherwise can take place automatically based on file
- scanning, even when /CHARACTER-SET and /TRANSLATE-TO switches
- are not given.
-
- VOID text
- Parses the text, evaluating any backslash items in it (such as
- function calls) but doesn't do anything further, except
- possibly printing error messages. Useful for invoking functions
- that have side effects without using or printing their direct
- results, e.g. "void \fsplit(\%a,&a)".
-
- Symbolic Links in UNIX
-
- The UNIX versions of C-Kermit have had /FOLLOWLINKS and /NOFOLLOWLINKS
- switches added to several commands to control the treatment of
- symbolic links. Different commands deal differently with symbolic
- links:
-
- Kermit SEND, FTP MPUT
- /NOFOLLOWLINKS is the default, which means symbolic links are
- skipped entirely. The alternative, /FOLLOWLINKS, should be used
- with caution, since an innocent link might point to a whole
- file system, or it might cause a loop. There is no way in
- Kermit or FTP protocol to send the link itself. We either skip
- them or follow them; we can't duplicate them.
-
- DIRECTORY
- /NOFOLLOWLINKS is the default, which means the DIRECTORY
- command lists symbolic links in a way that shows they are
- links, but it does not follow them. The alternative,
- /FOLLOWLINKS, follows links and gives information about the
- linked-to directories and files.
-
- DELETE, RMDIR
- The DELETE command does not have link-specific switches. DELETE
- never follows links. If you tell Kermit to delete a symbolic
- link, it deletes the link itself, not the linked-to file. Ditto
- for RMDIR.
-
- COPY
- The COPY command behaves just like the UNIX cp command; it
- always follows links.
-
- RENAME
- The RENAME command behaves just like the UNIX mv command; it
- operates on links directly rather than following.
-
- [ [390]Top ] [ [391]Contents ] [ [392]C-Kermit Home ] [ [393]Kermit
- Home ]
- __________________________________________________________________________
-
-8. OTHER SCRIPTING IMPROVEMENTS
-
- 8.1. Performance and Debugging
-
- A command cache for frequently used commands plus some related
- optimizations increases the speed of compute-bound scripts by anywhere
- from 50% to 1000%.
-
- The new PROMPT command can be used to set breakpoints for debugging
- scripts. If executed in a command file or macro, it gives you an
- interactive command prompt in the current context of the script, with
- all its variables, arguments, command stack, etc, available for
- examination or change, and the ability to resume the script at any
- point (END resumes it, Ctrl-C or STOP cancels it and returns to top
- level).
-
- The new Ctrl-C trapping feature ([394]Section 8.14) lets you intercept
- interruption of scripts. This can be used in combination with the
- PROMPT command to debug scripts. Example:
-
-define ON_CTRLC {
- echo INTERRUPTED BY CTRL-C...
- echo The command stack has not yet been rolled back:
- show stack
- echo Type Ctrl-C again or use the END command to return to top level.
- prompt Debug>
-}
-
- Adding this ON_CTRL definition to your script lets you interrupt it at
- any point and get prompt that is issued at the current command level,
- so you can query local variables, etc.
-
- [ [395]Top ] [ [396]Contents ] [ [397]C-Kermit Home ] [ [398]Kermit
- Home ]
- _________________________________________________________________
-
- 8.2. Using Macros as Numeric Variables
-
- A macro is a way to assign a value to a name, and then use the name to
- refer to the value. Macros are used in two ways in Kermit: as
- "subroutines" or functions composed of Kermit commands, which are
- executed, or as variables to hold arbitrary values -- text, numbers,
- filenames, etc.
-
- When a macro is to be executed, its name is given as if it were a
- C-Kermit command, optionally preceded by the word "do". When a macro
- is used as a variable, it must be "escaped" with \m(xxx) (or
- equivalent function, e.g. \s(xxx), \:(xxx), \fdefinition(xxx)), where
- xxx is the macro name, for example:
-
- define filename /usr/olga/oofa.txt
- send \m(filename)
-
- Of course variables can also hold numbers:
-
- define size 17
- declare \&a[\m(size)]
- ...
- define index 3
- if ( == \m(index) 3 ) echo The third value is: \&a[\m(index)]
- evaluate index (\m(index) * 4)
- if ( > \m(index) \m(size) ) echo Out of range!
-
- But these are contexts in which only numbers are valid. C-Kermit 8.0
- has been changed to treat non-escaped non-numeric items in strictly
- numeric contexts as macro names. So it is now possible (but not
- required) to omit the \m(...) notation and just use the macro name in
- these contexts:
-
- define size 17
- declare \&a[size]
- ...
- define index 3
- if ( == index 3 ) echo The third value is: \&a[index]
- evaluate index (index * 4)
- if ( > index size ) echo Out of range!
-
- This is especially nice for loops that deal with arrays. Here, for
- example, is a loop that reverses the order of the elements in an
- array. Whereas formerly it was necessary to write:
-
- .\%n ::= \fdim(&a)
- for \%i 1 \%n/2 1 {
- .tmp := \&a[\%n-\%i+1]
- .\&a[\%n-\%i+1] := \&a[\%i]
- .\&a[\%i] := \m(tmp)
- }
-
- Recoding this to use macro names "i" and "n" instead of the backslash
- variables \%i and \%n, we have:
-
- .n ::= \fdim(&a)
- for i 1 n/2 1 {
- .tmp := \&a[n-i+1]
- .\&a[n-i+1] := \&a[i]
- .\&a[i] := \m(tmp)
- }
-
- which reduces the backslash count to less than half. The final
- statement in the loop could be written ".\&a[i] ::= tmp" if the array
- contained only numbers (since ::= indicates arithmetic expression
- evaluation).
-
- Also, now you can use floating-point numbers in integer contexts (such
- as array subscripts), in which case they are truncated to an integer
- value (i.e. the fractional part is discarded).
-
- Examples of numeric contexts include:
-
- * Array subscripts.
- * Any numeric function argument.
- * Right-hand side of ::= assignments.
- * EVALUATE command or \fevaluate() function expression.
- * The INCREMENT or DECREMENT by-value.
- * IF =, >, <, !=, >=, and <= comparands.
- * The IF number construct.
- * FOR-loop variables.
- * STOP, END, and EXIT status codes.
- * The INPUT timeout value.
- * PAUSE, WAIT, SLEEP, MSLEEP intervals.
- * The SHIFT argument.
- * Numeric switch arguments, e.g. TYPE /WIDTH:number, SEND
- /LARGER:number.
- * SCREEN MOVE-TO row and column number.
- * Various SET DIAL parameters (timeout, retry limit, etc).
- * Various SET SEND or RECEIVE parameters (packet length, window
- size, etc).
- * Various other SET parameters.
-
- and:
-
- * S-Expressions (explained in [399]Section 9).
-
- Macro names used in numeric contexts must not include mathematical
- operators. Although it is legal to create a macro called "foo+bar", in
- a numeric context this would be taken as the sum of the values of
- "foo" and "bar". Any such conflict can be avoided, of course, by
- enclosing the macro name in \m(...).
-
- [ [400]Top ] [ [401]Contents ] [ [402]C-Kermit Home ] [ [403]Kermit
- Home ]
- _________________________________________________________________
-
- 8.3. New IF Conditions
-
- Several new IF conditions are available:
-
- IF DECLARED arrayname
- Explained in [404]Section 8.6.
-
- IF KBHIT
- Allows a script to test whether a key was pressed without
- actually trying to read it.
-
- IF KERBANG (Unix only)
- True if Kermit was started from a Kerbang script. This is
- useful for knowing how to interpret the \&@[] and \&_[]
- argument vector arrays, and under what conditions to exit.
-
- IF INTEGER n
- This is just a synonym for IF NUMERIC, which is true if n
- contains only digits (or, if n is a variable, its value
- contains only digits).
-
- By contrast, IF FLOAT n succeeds if n is a floating-point number OR an
- integer (or a variable with floating-point or integer value).
- Therefore, IF FLOAT should be used whenever any kind of number is
- acceptable, whereas IF INTEGER (or IF NUMERIC) when only an integer
- can be used.
-
- [ [405]Top ] [ [406]Contents ] [ [407]C-Kermit Home ] [ [408]Kermit
- Home ]
- _________________________________________________________________
-
- 8.4. The ON_UNKNOWN_COMMAND Macro
-
- The new ON_UNKNOWN_COMMAND macro, if defined, is executed whenever you
- give a command that is not known to C-Kermit; any operands are passed
- as arguments. Here are some sample definitions:
-
- DEF ON_UNKNOWN_COMMAND telnet \%1 ; Treat unknown commands as hostnames
- DEF ON_UNKNOWN_COMMAND dial \%1 ; Treat unknown commands phone numbers
- DEF ON_UNKNOWN_COMMAND take \%1 ; Treat unknown commands as filenames
- DEF ON_UNKNOWN_COMMAND !\%* ; Treat unknown commands as shell commands
-
- The ON_CD macro, if defined, is executed whenever Kermit is given a CD
- (change directory) command (8.0.211). Upon entry to this macro, the
- directory has already changed and the new directory string is
- available in the \v(directory) variable, and also as the first
- argument (\%1).
-
- [ [409]Top ] [ [410]Contents ] [ [411]C-Kermit Home ] [ [412]Kermit
- Home ]
- _________________________________________________________________
-
- 8.5. The SHOW MACRO Command
-
- The SHOW MACRO command has been changed to accept more than one macro
- name:
-
- (setq a 1 b 2 c 3)
- show mac a b c
- a = 1
- b = 2
- c = 3
-
- An exact match is required for each name (except that case doesn't
- matter). If you include wildcard characters, however, a pattern match
- is performed:
-
- show mac [a-c]*x
-
- shows all macros whose names start with a, b, or c, and end with x.
-
- [ [413]Top ] [ [414]Contents ] [ [415]C-Kermit Home ] [ [416]Kermit
- Home ]
- _________________________________________________________________
-
- 8.6. Arrays
-
- A clarification regarding references to array names (as opposed to
- array elements): You can use array-name "abbreviations" like &a only
- in contexts that expect array names, like ARRAY commands or array-name
- function arguments such as the second argument of \fsplit(). In a
- LOCAL statement, however, you have to write \&a[], since "local &a"
- might refer to a macro named "&a".
-
- In function arguments, however, you MUST use the abbreviated form:
- \fsplit(\%a,&a) or \fsplit(\%a,&a[]). If you include the backslash (as
- in "\fsplit(\%a,\&a[])") a parse error occurs.
-
- Here are the new array-related commands:
-
- IF DECLARED arrayname
- Allows a script to test whether an array has been declared. The
- arrayname can be a non-array backslash variable such as \%1 or
- \m(name), in which case it is evaluated first, and the result
- is treated as the array name. Otherwise, arrayname is treated
- as in the ARRAY commands: it can be a, &a, &a[], \&a, \&a[],
- \&a[3], \&a[3:9], etc, with the appropriate results in each
- case. Synonym: IF DCL.
-
- UNDECLARE arrayname
- UNDECLARE is a new top-level command to undeclare an array.
- Previously this could only be done with "declare \&a[0]" (i.e.
- re-declare the array with a dimension of 0).
-
- ARRAY LINK linkname arrayname
- Creates a symbolic link from the array named by linkname (which
- must be the name of an array that is not yet declared in the
- current context) to the array named by arrayname (which must
- the name of a currently declared array that is not itself a
- link, or a variable containing the name of such an array). The
- two names indicate the same array: if you change an array
- element, the change is reflected in the link too, and vice
- versa. If you undeclare the link, the real array is unaffected.
- If you undeclare the real array, all links to it disappear. If
- you resize an array (directly or through a link), all links to
- it are updated automatically.
-
- Array links let you pass array names as arguments to macros. For
- example, suppose you had a program that needed to uppercase all the
- elements of different arrays at different times. You could write a
- macro to do this, with the array name as an argument. But without
- array links, there would be no way to refer to the argument array
- within the macro. Array links make it easy:
-
- define arrayupper {
- local \&e[] \%i
- array link \&e[] \%1
- for i 1 \fdim(&e) 1 { .\&e[i] := \fupper(\&e[i]) }
- }
- declare \&a[] = these are some words
- arrayupper &a
- show array &a
-
- The macro declares the array link LOCAL, which means it doesn't
- conflict with any array of the same name that might exist outside the
- macro, and that the link is destroyed automatically when the macro
- exits. This works, by the way, even if the link name and the macro
- argument name are the same, as long as the link is declared LOCAL.
-
- As noted, you can't make a link to a nonexistent array. So when
- writing a macro whose job is to create an array whose name is passed
- as an argument, you must declare the array first (the size doesn't
- matter as long as it's greater than 0). Example:
-
- define tryme { ; Demonstration macro
- local \&e[] ; We only need this inside the macro
- array link \&e[] \%1 ; Make local link
- shift ; Shift argument list
- void \fsplit(\%*,&e) ; Split remainder of arg list into array
- }
- declare \&a[1] ; Declare target array in advance
- tryme &a here are some words ; Invoke the macro with array name and words
- show array a ; See the results
-
- One final improvement allows the macro itself to declare the array
- (this was not possible in earlier Kermit releases): if the array name
- in the DECLARE command is a variable (and not an array name), or
- includes variables, the resulting value is used as the array name. So:
-
- define tryme { ; Demonstration macro
- declare \%1[1] ; Preliminary declaration for target array
- local \&e[] ; We only need this inside the macro
- array link \&e[] \%1 ; Make local link
- shift ; Shift argument list
- void \fsplit(\%*,&e) ; Split remainder of arg list into array
- }
- tryme &a here are some words ; Invoke the macro with array name and words
- show array a ; See the results
-
- The SHOW ARRAY command now indicates whether an array name is a link.
-
- Also see the descriptions of [417]\fjoin() and [418]\fsplit(), plus
- [419]Section 8.10 on the MINPUT command, which shows how an entire
- array (or segment of it) can be used as the MINPUT target list.
-
- [ [420]Top ] [ [421]Contents ] [ [422]C-Kermit Home ] [ [423]Kermit
- Home ]
- _________________________________________________________________
-
- 8.7. New or Improved Built-in Variables and Functions
-
- The following new built-in variables are available:
-
- \v(buildid) A date string like "20000808" indicating when C-Kermit was
-built.
- \v(ftime) Current time, secs since midnight, including fraction of se
-cond.
- \v(iprompt) The current SET PROMPT value
- \v(sexp) The most recent S-Expression (see [424]Section 9)
- \v(sdepth) The current S-Expression invocation depth ([425]Section 9)
- \v(svalue) The value of the most recent S-Expression ([426]Section 9)
-
- \v(ftp_code) Most recent FTP response code ([427]Section 3)
- \v(ftp_connected) FTP connection status ([428]Section 3)
- \v(ftp_cpl) FTP Command Protection Level ([429]Section 3.2)
- \v(ftp_dpl) FTP Data Protection Level ([430]Section 3.2)
- \v(ftp_getputremote) The current SET GET-PUT-REMOTE setting ([431]Section 3.8
-)
- \v(ftp_host) Name or IP address of FTP server ([432]Section 3)
- \v(ftp_loggedin) FTP login status ([433]Section 3)
- \v(ftp_message) Most recent FTP response message ([434]Section 3)
- \v(ftp_security) FTP Security method ([435]Section 3.2)
- \v(ftp_server) OS type of FTP server ([436]Section 3)
-
- \v(http_code) Most recent HTTP response code
- \v(http_connected) HTTP connection status
- \v(http_host) Name or IP address of HTTP server
- \v(http_message) Most recent HTTP response message
- \v(http_security) TLS cipher used to secure the HTTP session
-
- \v(hour) Hour of the day, 0 to 23.
- \v(timestamp) Equivalent to "\v(ndate) \v(time)".
-
- \v(log_debug) Current debug log file, if any.
- \v(log_packet) Current packet log file, if any.
- \v(log_session) Current session log file, if any.
- \v(log_transaction) Current transaction log file, if any.
- \v(log_connection) Current connection log file, if any.
-
- The following new or improved built-in functions are available:
-
- \fcmdstack() Allows programmatic access to the command stack.
- \fcvtdate() [437]Section 8.13, format options added
- \fdelta2secs() [438]Section 8.13
- \fdostounixpath(s1) Converts a DOS filename to Unix format.
- \fsplit() Now allows grouping/nesting in source string.
- \fword() Allows the same grouping and nesting.
- \fjoin(&a,s1,n1,n2) Copies an array into a single string.
- \fsubstitute(s1,s2,s3) Substitutes characters within a string.
- \freplace() Has new 4th "occurrence" argument.
- \fsexpression() Evaluates an S-Expression (explained in [439]Section
-9).
- \ftrim(), \fltrim() Now trim CR and LF by default, as well as SP and Tab.
- \funixtodospath(s1) Converts a Unix filename to DOS format.
- \fkeywordval(s1,c1) Assigns values to keywords (macros) (explained below)
-.
-
- Most functions that have "2" in their names to stand for the word "to"
- can now also be written with "to", e.g. "\fdelta2secs(),"
- \fdeltatosecs()."
-
- \funtabify(string)
- (New to 8.0.211) Replaces Horizontal Tab characters in the
- given string with spaces based on VT100-like tab stops.
-
- \fverify(s1,s2,n)
- As of version 8.0.211, returns -1 if s2 is an empty string.
- Previously it returned 0, making \fverify(abc,\%a) look as if
- \%a was a string combosed of a's, b's, and/or c's when in fact
- it contained nothing.
-
- \fcode(string)
- As of version 8.0.211, returns 0 if string is empty or missing.
- Previously it returned the empty string, which made it unsafe
- to use in arithmetic or boolean expressions.
-
- \v(inscale)
- New to version 8.0.211, its value is the INPUT SCALE-FACTOR
- ([440]Section 8.10), default 1.0.
-
- 8.7.1. The \fkeywordval() Function
-
- \fkeywordval(s1,c1) is new to C-Kermit 8.0. Given a string s1 of the
- form "name=value", it creates a macro with the given name and assigns
- it the given value. If no value appears after the equal sign, any
- existing macro of the given name is undefined. Blanks are
- automatically trimmed from around the name and value. The optional c1
- parameter is the assignment operator character, equal sign (=) by
- default. This function is handy for processing keyword parameters or
- any other form of parameter-value pair. Suppose, for example, you want
- to write a macro that accepts keyword parameters rather than
- positional ones:
-
- define MYDIAL {
- local \%i modem hangup method device speed number
- def number 5551234 ; Assign default parameter values
- def speed 57600
- def modem usrobotics
- def hangup rs232
- def method tone
- def country 1
- for \%i 1 \v(argc)-1 1 { ; Parse any keyword parameters...
- if not \fkeywordval(\&_[\%i]) end 1 Bad parameter: "\&_[\%i]"
- }
- set dial country \m(country)
- set modem type \m(modem)
- set modem hang \m(hangup)
- set dial method \m(tone)
- set line \m(device)
- if fail stop 1
- set speed \m(speed)
- if fail stop 1
- show comm
- set dial display on
- dial \m(number)
- if success connect
- }
-
- In this example, all the defaults are set up inside the macro, and
- therefore it can be invoked with no parameters at all. But if you want
- to have the macro dial a different number, you can supply it as
- follows:
-
- mydial number=7654321
-
- You can supply any number of keyword parameters, and you can give them
- in any order:
-
- mydial number=7654321 hangup=modem speed=115200
-
- 8.7.2. The \fsplit(), \fjoin(), and \fword() Functions
-
- \fjoin(&a,s1,n1,n2) is also new; it creates a string from an array (or
- a piece of one). &a is the name of the array (a range specifier can be
- included); s1 is a character or string to separate each element in the
- result string (can be omitted, in which case the elements are not
- separated at all), and n1 is a grouping mask, explained below. If s1
- is empty or not specified, the array elements are separated with
- spaces. If you want the elements concatenated with no separator,
- include a nonzero n2 argument. Given the array:
-
- declare \&a[] = 0 1 2 3 4 5 6 7 8 9
-
- you can get effects like this:
-
- \fjoin(&a) 0 1 2 3 4 5 6 7 8 9
- \fjoin(&a,:) 0:1:2:3:4:5:6:7:8:9
- \fjoin(&a,{,}) 0,1,2,3,4,5,6,7,8,9
- \fjoin(&a,...) 0...1...2...3...4...5...6...7...8...9
- \fjoin(&a,,,1) 0123456789
-
- \fsplit(), \fword(), \fstripb(), and \fjoin() accept a "grouping mask"
- argument, n1, which is a number from 0 to 63, in which:
-
- 1 = "" doublequotes
- 2 = {} braces
- 4 = '' singlequotes
- 8 = () parentheses
- 16 = [] square brackets
- 32 = <> angle brackets
-
- These can be OR'd (added) together to make any number 0-63 (-1 is
- treated the same as 63, 0 means no grouping). If a bit is on, the
- corresponding kind of grouping is selected. (If more than 1 bit is set
- for \fjoin(), only the lowest-order one is used.)
-
- If you include the same character in the grouping mask and the include
- list, the grouping mask takes precedence. Example:
-
- def \%a a "b c d" e
- \fsplit(\%a,&a[],,,-1) = 3 <-- doublequote used for grouping
- \fsplit(\%a,&a[],,",-1) = 3 <-- doublequote still used for grouping
-
- Nesting of matched left and right grouping characters (parentheses,
- braces, and brackets, but not quotes) is recognized. Example:
-
- def \%a a (b c <d e [f g {h i} j k] l m> n o) p
- \fsplit(\%a,&a,,,0) = 16 (no grouping)
- \fsplit(\%a,&a,,,2) = 15 (braces only)
- \fsplit(\%a,&a,,,16) = 11 (square brackets only)
- \fsplit(\%a,&a,,,32) = 7 (angle brackets only)
- \fsplit(\%a,&a,,,63) = 3 (all)
- \fsplit(\%a,&a,,,-1) = 3 (all)
-
- \fsplit() and \fjoin() are "reciprocal" functions. You can split a
- string up into an array and join it back into a new string that is
- equivalent, as long as \fsplit() and \fjoin() are given equivalent
- grouping masks, except that the type of braces might change. Example:
-
- def \%a a {b c [d e] f g} "h i" j <k l> m
- echo STRING=[\%a]
- echo WORDS=\fsplit(\%a,&a,,,-1)
- show array a
- asg \%b \fjoin(&a,{ },2)
- echo JOIN =[\%b]
- echo WORDS=\fsplit(\%b,&b,,,-1)
- show array b
-
- The arrays a and b are identical. The strings a and b are as follows:
-
- \%a: a {b c [d e] f g} "h i" j <k l> m
- \%b: a {b c [d e] f g} {h i} j {k l} m
-
- It is possible to quote separator grouping characters with backslash
- to override their grouping function. And of course to include
- backslash itself in the string, it must be quoted too. Furthermore,
- each backslash must be doubled, so the command parser will still pass
- one backslash to \fsplit() for each two that it sees. Here are some
- examples using \fsplit() with a grouping mask of 8 (treat parentheses
- as grouping characters).
-
- String Result
- a b c d e f 6
- a b\\ c d e f 5
- a b (c d e) f 4
- a b \\(c d e\\) f 6
- a b \\\\(c d e\\\\) f 7
-
- \fsplit() has also been changed to create its array (if one is given)
- each time it is called, so now it can be conveniently called in a loop
- without having to redeclare the array each time.
-
- Incidentally... Sometimes you might want to invoke \fsplit() in a
- situation where you don't care about its return value, e.g. when you
- just want to fill the array. Now you can "call" \fsplit() or any other
- function with the new [441]VOID command:
-
- void \fsplit(\%a,&a)
-
- \fsplit() and \fjoin() also accept a new, optional 6th argument, an
- options flag, a number that can specify a number of options. So far
- there is just one option, whose value is 1:
-
- separator-flag
- Normally separators are collapsed. So, for example,
-
- \fword(Three little words,2)
-
- returns "little" (the second word). Space is a separator, but
- there are multiple spaces between each word. If the value 1 is
- included in the option flag, however, each separator counts. If
- two separators are adjacent, an empty word is produced between
- them. This is useful for parsing (e.g.) comma-separated lists
- exported from databases or spreadsheets.
-
- 8.7.3. The \fcmdstack() Function
-
- The new \fcmdstack() function gives access to the command stack:
-
- \fcmdstack(n1,n2)
- Arguments: n1 is the command stack level. If omitted, the
- current level, \v(cmdlevel), is used. n2 is a function code
- specifying the desired type of information:
-
- 0 (default) = name of object at level n1.
- 1 (nonzero) = object type (0 = prompt; 1 = command file; 2 = macro).
-
- The default for n2 is 0.
-
- The name associated with prompt is "(prompt)". Here's a loop that can
- be included in a macro or command file to show the stack (similar to
- what the SHOW STACK command does):
-
- for \%i \v(cmdlevel) 0 -1 {
- echo \%i. [\fcmdstack(\%i,1)] \fcmdstack(\%i,0)
- }
-
- In this connection, note that \v(cmdfile) always indicates the most
- recently invoked active command file (if any), even if that file is
- executing a macro. Similarly, \v(macro) indicates the most recently
- invoked macro (if any), even if the current command source is not a
- macro. The name of the "caller" of the currently executing object
- (command file or macro) is:
-
- \fcmdstack(\v(cmdlevel)-1)
-
- and its type is:
-
- \fcmdstack(\v(cmdlevel)-1,1)
-
- To find the name of the macro that invoked the currently executing
- object, even if one or more intermediate command files (or prompting
- levels) are involved, use a loop like this:
-
- for \%i \v(cmdlevel)-1 0 -1 {
- if = \fcmdstack(\%i,1) 2 echo CALLER = \fcmdstack(\%i,0)
- }
-
- Of course if you make a macro to do this, the macro must account for
- its own additional level:
-
- define CALLER {
- for \%i \v(cmdlevel)-2 0 -1 {
- if = \fcmdstack(\%i,1) 2 return \fcmdstack(\%i,0)
- }
- return "(none)"
- }
-
- The built-in variable \v(cmdsource) gives the current command source
- as a word ("prompt", "file", or "macro").
-
- 8.7.4. The VOID Command
-
- VOID is like ECHO in that all functions and variables in its argument
- text are evaluated. but it doesn't print anything (except possibly an
- error message if a function was invocation contained or resulted in
- any errors). VOID sets FAILURE if it encounters any errors, SUCCESS
- otherwise.
-
- [ [442]Top ] [ [443]Contents ] [ [444]C-Kermit Home ] [ [445]Kermit
- Home ]
- _________________________________________________________________
-
- 8.8. The RETURN and END Commands
-
- The execution of a macro is terminated in any of the following ways:
-
- * With an END [ number [ message ] ] command. If a number is given,
- the macro succeeds if the number is 0, and fails if it is not
- zero; if a number is not given, the macro succeeds.
- * With a STOP command, which works just like END except it peels
- back the command stack all the way to top level.
- * With a RETURN [ text ] command, in which case the macro always
- succeeds.
- * By running out of commands to execute, in which case the macro
- succeeds or fails according the most recently executed command
- that sets success or failure.
-
- The same considerations apply to command files invoked by the TAKE
- command.
-
- If a macro does not execute any commands that set success or failure,
- then invoking the macro does not change the current SUCCESS/FAILURE
- status. It follows, then, that the mere invocation of a macro does not
- change the SUCCESS/FAILURE status either. This makes it possible to
- write macros to react to the status of other commands (or macros), for
- example:
-
- define CHKLINE {
- if success end 0
- stop 1 SET LINE failed - please try another device.
- }
- set modem type usrobotics
- set line /dev/cua0
- chkline
- set speed 57600
- dial 7654321
-
- By the way, none of this is news. But it was not explicitly documented
- before, and C-Kermit 7.0 and earlier did not always handle the RETURN
- statement as it should have.
-
- [ [446]Top ] [ [447]Contents ] [ [448]C-Kermit Home ] [ [449]Kermit
- Home ]
- _________________________________________________________________
-
- 8.9. UNDEFINing Groups of Variables
-
- The UNDEFINE command, which previously accepted one variable name, now
- accepts a list of them, and also accepts wildcard notation to allow
- deletion of variables that match a given pattern.
-
- UNDEFINE [ switches ] name [ name [ name [ ... ] ] ]
- Undefines the variables whose names are given. Up to 64 names
- may be given in one UNDEFINE command.
-
- If you omit the switches and include only one name, the UNDEFINE
- command works as before.
-
- Switches include:
-
- /MATCHING
- Specifies that the names given are to treated as patterns
- rather than literal variable names. Note: pattern matching
- can't be used with array references; use the ARRAY command to
- manipulate arrays and subarrays.
-
- /LIST
- List the name of each variable to be undefined, and whether it
- was undefined successfully ("ok" or "error"), plus a summary
- count at the end.
-
- /SIMULATE
- List the names of the variables that would be deleted without
- actually deleting them. Implies /LIST.
-
- The UNDEFINE command fails if there were any errors and succeeds
- otherwise.
-
- The new _UNDEFINE command is like UNDEFINE, except the names are
- assumed to be variable names themselves, which contain the names (or
- parts of them) of the variables to be undefined. For example, if you
- have the following definitions:
-
- define \%a foo
- define foo This is some text
-
- then:
-
- undef \%a
-
- undefines the variable \%a, but:
-
- _undef \%a
-
- undefines the macro foo.
-
- Normal Kermit patterns are used for matching; metacharacters include
- asterisk, question mark, braces, and square brackets. Thus, when using
- the /MATCHING switch, if the names of the macros you want to undefine
- contain any of these characters, you must quote them with backslash to
- force them to be taken literally. Also note that \%* is not the name
- of a variable; it is a special notation used within a macro for "all
- my arguments". The command "undef /match \%*" deletes all \%x
- variables, where x is 0..9 and a..z. Use "undef /match \%[0-9]" to
- delete macro argument variables or "undef /match \%[i-n]" to delete a
- range of \%x variables.
-
- [ [450]Top ] [ [451]Contents ] [ [452]C-Kermit Home ] [ [453]Kermit
- Home ]
- _________________________________________________________________
-
- 8.10. The INPUT and MINPUT Commands
-
- As of C-Kermit 8.0.211, the INPUT and MINPUT commands accept a switch:
-
- [M]INPUT /NOMATCH timeout
- The /NOMATCH switch allows INPUT or MINPUT to read incoming
- material for the specified amount of time, without attempting
- to match it with any text or patterns. When this switch is
- included, the [M]INPUT command succeeds when the timeout
- interval expires, with \v(instatus) set to 1, meaning "timed
- out", or fails upon interruption or i/o error.
-
- Also in version 8.0.211, there is a new way to apply a scale factor to
- [M]INPUT timeouts:
-
- SET INPUT SCALE-FACTOR floating-point-number
- This scales all [M]INPUT timeouts by the given factor, allowing
- time-sensitive scripts to be adjusted to changing conditions
- such as congested networks or different-speed modems without
- having to change each INPUT-class command. This affects only
- those timeouts that are given in seconds, not as wall-clock
- times. Although the scale factor can have a fractional part,
- the INPUT timeout is still an integer. The new built-in
- variable \v(inscale) tells the current INPUT SCALE-FACTOR.
-
- The MINPUT command can be used to search the incoming data stream for
- several targets simultaneously. For example:
-
- MINPUT 8 one two three
-
- waits up to 8 seconds for one of the words "one", "two", or "three" to
- arrive. Words can be grouped to indicate targets that contain spaces:
-
- MINPUT 8 nineteeen twenty "twenty one"
-
- And of course you can also use variables in place of (or as part of)
- the target names:
-
- MINPUT 8 \%a \&x[3] \m(foo)
-
- Until now you had to know the number of targets in advance when
- writing the MINPUT statement. Each of the examples above has exactly
- three targets.
-
- But suppose your script needs to look for a variable number of
- targets. For this you can use arrays and \fjoin(), described in
- [454]Section 8.7. Any number of \fjoin() invocations can be included
- in the MINPUT target list, and each one is expanded into the
- appropriate number of separate targets each time the MINPUT command is
- executed. Example:
-
- declare \&a[10] = one two three
- minput 10 foo \fjoin(&a) bar
-
- This declares an array of ten elements, and assigns values to the
- first three of them. The MINPUT command looks for these three (as well
- as the words "foo" and "bar"). Later, if you assign additional
- elements to the array, the same MINPUT command also looks for the new
- elements.
-
- If an array element contains spaces, each word becomes a separate
- target. To create one target per array element, use \fjoin()'s
- grouping feature:
-
- dcl \&a[] = {aaa bbb} {ccc ddd} {xxx yyy zzz}
-
- minput 10 \fjoin(&a) <-- 7 targets
- minput 10 \fjoin(&a,,2) <-- 3 targets
-
- [ [455]Top ] [ [456]Contents ] [ [457]C-Kermit Home ] [ [458]Kermit
- Home ]
- _________________________________________________________________
-
- 8.11. Learned Scripts
-
- C-Kermit now includes a simple script recorder that monitors your
- commands, plus your actions during CONNECT mode, and automatically
- generates a script program that mimics what it observed. You should
- think of this feature as a script-writing ASSISTANT since, as you will
- see [459]later in this section, the result generally needs some
- editing to make it both secure and flexible. The script recorder is
- controlled by the new LEARN command:
-
- LEARN [ /ON /OFF /CLOSE ] [ filename ]
- If you give a filename, the file is opened for subsequent
- recording. The /ON switch enables recording to the current file
- (if any); /OFF disables recording. /CLOSE closes the current
- script recording file (if any). If you give a filename without
- any switches, /ON is assumed.
-
- The /OFF and /ON switches let you turn recording off and on during a
- session without closing the file.
-
- When recording:
-
- * All commands that you type (or recall) at the prompt are recorded
- in the file except:
- + LEARN commands are not recorded.
- + The CONNECT command is not recorded.
- + The TELNET command is converted to SET HOST /NETWORK:TCP.
- * Commands obtained from macros or command files are not recorded.
- * During CONNECT:
- + Every line you type is converted to an OUTPUT command.
- + The last prompt before any line you type becomes an INPUT
- command.
- + Timeouts are calculated automatically for each INPUT command.
- + A PAUSE command is inserted before each OUTPUT command just
- to be safe.
-
- Thus the script recorder is inherently line-oriented. It can't be used
- to script character-oriented interactions like typing Space to a
- "More?" prompt or editing a text file with VI or EMACS.
-
- But it has advantages too; for example it takes control characters
- into account that might not be visible to you otherwise, and it
- automatically converts control characters in both the input and output
- streams to the appropriate notation. It can tell, for example that the
- "$ " prompt on the left margin in UNIX is really {\{13}\{10}$ },
- whereas in VMS it might be {\{13}\{10}\{13}$ }. These sequences are
- detected and recorded automatically.
-
- A learned script should execute correctly when you give a TAKE command
- for it. However, it is usually appropriate to edit the script a bit.
- The most important change would be to remove any passwords from it.
- For example, if the script contains:
-
- INPUT 9 {\{13}\{10}Password: }
- IF FAIL STOP 1 INPUT timeout
- PAUSE 1
- OUTPUT bigsecret\{13}
-
- you should replace this by something like:
-
- INPUT 9 {\{13}\{10}Password: }
- IF FAIL STOP 1 INPUT timeout
- ASKQ pswd Please type your password:
- PAUSE 1
- OUTPUT \m(pswd)\{13}
-
- The LEARN command can't do this for you since it knows nothing about
- "content"; it only knows about lines and can't be expected to parse or
- understand them -- after all, the Password prompt might be in some
- other language. So remember: if you use the LEARN command to record a
- login script, be sure edit the resulting file to remove any passwords.
- Also be sure to delete any backup copies your editor or OS might have
- made of the file.
-
- Other manual adjustments might also be appropriate:
-
- * If the target of an INPUT command can vary, you can replace the
- INPUT command with MINPUT and the appropriate target list, and/or
- the target with a \fpattern(). For example, suppose you are
- dialing a number that can be answered by any one of 100 terminal
- servers, whose prompts are ts-00>, ts-01>, ts-02>, ... ts-99>. The
- script records a particular one of these, but you want it to work
- for all of them, so change (e.g.):
- INPUT 10 ts-23> ; or whatever
- to:
- INPUT 10 \fpattern(ts-[0-9][0-9]>)
- * The INPUT timeout values are conservative, but they are based only
- on a single observation; you might need to tune them.
- * The PAUSE commands might not be necessary, or the PAUSE interval
- might need adjustment.
- * In case you made typographical errors during recording, they are
- incorporated in your script; you can edit them out if you want to.
-
- Here is a sample script generated by Kermit ("learn vms.ksc") in which
- a Telnet connection is made to a VMS computer, the user logs in,
- starts Kermit on VMS, sends it a file, and then logs out:
-
- ; Scriptfile: vms.ksc
- ; Directory: /usr/olga
- ; Recorded: 20001124 15:21:23
-
- SET HOST /NETWORK:TCP vms.xyzcorp.com
- IF FAIL STOP 1 Connection failed
-
- INPUT 7 {\{13}\{10}\{13}Username: }
- IF FAIL STOP 1 INPUT timeout
- PAUSE 1
- OUTPUT olga\{13}
- INPUT 3 {\{13}\{10}\{13}Password: }
- IF FAIL STOP 1 INPUT timeout
- PAUSE 1
- OUTPUT secret\{13}
- INPUT 18 {\{13}\{10}\{13}$ }
- IF FAIL STOP 1 INPUT timeout
- PAUSE 1
- OUTPUT set default [.incoming]\{13}
- INPUT 12 {\{13}\{10}\{13}$ }
- IF FAIL STOP 1 INPUT timeout
- PAUSE 1
- OUTPUT kermit\{13}
- INPUT 15 {\{13}\{10}\{13}ALTO:[OLGA.INCOMING] C-Kermit>}
- IF FAIL STOP 1 INPUT timeout
- PAUSE 1
- OUTPUT receive\{13}
- send myfile.txt
-
- INPUT 18 {\{13}\{10}\{13}ALTO:[OLGA.INCOMING] C-Kermit>}
- IF FAIL STOP 1 INPUT timeout
- PAUSE 1
- OUTPUT exit\{13}
- INPUT 6 {\{13}\{10}\{13}$ }
- IF FAIL STOP 1 INPUT timeout
- PAUSE 1
- OUTPUT logout\{13}
- close
- exit
-
- The commands generated by Kermit during CONNECT (INPUT, IF FAIL,
- PAUSE, and OUTPUT) have uppercase keywords; the commands typed by the
- user are in whatever form the user typed them (in this case,
- lowercase).
-
- [ [460]Top ] [ [461]Contents ] [ [462]C-Kermit Home ] [ [463]Kermit
- Home ]
- _________________________________________________________________
-
- 8.12. Pattern Matching
-
- A pattern is a character string that is used to match other strings.
- Patterns can contain metacharacters that represent special actions
- like "match any single character", "match zero or more characters",
- "match any single character from a list", and so on. The best known
- application of patterns is in file specifications that contain
- wildcards, as in "send *.txt", meaning "send all files whose names end
- with .txt".
-
- Patterns are also used in increasingly many other ways, to the extent
- it is useful to point out certain important distinctions in the ways
- in which they are used:
-
- Anchored Patterns
- If an anchored pattern does not begin with "*", it must match
- the beginning of the string, and if it does not end with "*",
- it must match the end of the string. For example, the anchored
- pattern "abc" matches only the string "abc", not "abcde" or
- "xyzabc" or "abcabc". The anchored pattern "abc*" matches any
- string that starts with "abc"; the anchored pattern "*abc"
- matches any string that ends with "abc"; the anchored pattern
- "*abc*" matches any string that contains "abc" (including any
- that start and/or end with it).
-
- Floating Patterns
- A floating pattern matches any string that contains a substring
- that matches the pattern. In other words, a floating pattern
- has an implied "*" at the beginning and end. You can anchor a
- floating pattern to the beginning by starting it with "^", and
- you can anchor it to the end by ending it with "$" (see
- examples below).
-
- Wildcards
- A wildcard is an anchored pattern that has the additional
- property that "*" does not match directory separators.
-
- This terminology lets us describe Kermit's commands with a bit more
- precision. When a pattern is used for matching filenames, it is a
- wildcard, except in the TEXT-PATTERNS and BINARY-PATTERNS lists and
- /EXCEPT: clauses, in which case directory separators are not
- significant (for example, a BINARY-PATTERN of "*.exe" matches any file
- whose name ends in .exe, no matter how deeply it might be buried in
- subdirectories). When Kermit parses a file specification directly,
- however, it uses the strict wildcard definition. For example, "send
- a*b" sends all files whose names start with "a" and end with "b" in
- the current directory, and not any files whose names end with "b" that
- happen to be in subdirectories whose names start with "a". And as
- noted, wildcards are anchored, so "delete foo" deletes the file named
- "foo", and not all files whose names happen to contain "foo".
-
- Most other patterns are anchored. For example:
-
- if match abc bc ...
-
- does not succeed (and you would be surprised if it did!). In fact, the
- only floating patterns are the ones used by commands or functions that
- search for patterns in files, arrays, or strings. These include:
-
- * The GREP and TYPE /MATCH commands.
- * The \fsearch(), \frsearch(), and \farraylook() functions.
-
- Thus these are the only contexts in which explicit anchors ("^" and
- "$") may be used:
-
- grep abc *.txt
- Prints all lines containing "abc" in all files whose names end
- with ".txt".
-
- grep ^abc *.txt
- Prints all lines that start with "abc" in all ".txt" files.
-
- grep abc$ *.txt
- Prints all lines that end with "abc" in all ".txt" files.
-
- grep ^a*z$ *.txt
- Prints all lines that start with "a" and end with "z" in all
- ".txt" files.
-
- Similarly for TYPE /PAGE, /fsearch(), /frsearch(), and \farraylook().
-
- Here is a brief summary of anchored and floating pattern equivalences:
-
- Anchored Floating
- abc ^abc$
- *abc abc$
- abc* ^abc
- *abc* abc
-
- [ [464]Top ] [ [465]Contents ] [ [466]C-Kermit Home ] [ [467]Kermit
- Home ]
- _________________________________________________________________
-
- 8.13. Dates and Times
-
- C-Kermit's comprehension of date-time formats is considerably expanded
- in version 8.0. Any command that reads dates, including the DATE
- command itself, or any switch, such as the /BEFORE: and /AFTER:
- switches, or any function such as \fcvtdate(), now can understand
- dates and times expressed in any ISO 8601 format, in Unix "asctime"
- format, in FTP MDTM format, and in practically any format used in RFC
- 822 or RFC 2822 electronic mail, with or without timezones, and in a
- great many other formats as well. HELP DATE briefly summarizes the
- acceptable date-time formats.
-
- Furthermore, C-Kermit 8.0 includes a new and easy-to-use form of
- date-time arithmetic, in which any date or time can be combined with a
- "delta time", to add or subtract the desired time interval (years,
- months, weeks, days, hours, minutes, seconds) to/from the given date.
- And new functions are available to compare dates and to compute their
- differences.
-
- As you can imagine, all this requires quite a bit of "syntax". The
- basic format is:
-
- [ date ] [ time ] [ delta ]
-
- Each field is optional, but in most cases (depending on the context)
- there must be at least one field. If a date is given, it must come
- first. If no date is given, the current date is assumed. If no time is
- given, an appropriate time is supplied depending on whether a date was
- supplied. If no delta is given, no arithmetic is done. If a delta is
- given without a date or time, the current date and time are used as
- the base.
-
- Date-time-delta fields are likely to contain spaces (although they
- need not; space-free forms are always available). Therefore, in most
- contexts -- and notably as switch arguments -- date-time information
- must be enclosed in braces or doublequotes, for example:
-
- send /after:"8-Aug-2001 12:00 UTC" *.txt
-
- Kermit's standard internal format for dates and times is:
-
- yyyymmdd hh:mm:ss
-
- for example:
-
- 20010208 10:28:01
-
- Date-times can always be given in this format. yyyy is the 4-digit
- year, mm is the two-digit month (1-12; supply leading zero for
- Jan-Sep), dd is the 2-digit day (leading zero for 1-9), hh is the hour
- (0-23), mm the minute (0-59), ss the second (0-59), each with leading
- zero if less than the field width. The date and time can be separated
- by a space, an underscore, a colon, or the letter T. The time is in
- 24-hour format. Thus the various quantites are at the following fixed
- positions:
-
-Position Contents
- 1-4 Year (4 digits, 0000-9999)
- 5-6 Month (2 digits, 1-12)
- 7-8 Day (2 digits, 1-31)
- 9 Date-Time Separator (space, :, _, or the letter T)
- 10-11 Hour (2 digits, 0-23)
- 12 Hour-Minute Separator (colon)
- 13-14 Minute (2 digits, 0-59)
- 15 Minute-Second Separator (colon)
- 16-17 Second (2 digits, 0-59)
-
- Example:
-
- 19800526 13:07:12 26 May 1980, 13:07:12 (1:07:12PM)
-
- This is the format produced by the DATE command and by any function
- that returns a date-time. It is suitable for lexical comparison and
- sorting, and for use as a date-time in any Kermit command. When this
- format is given as input to a command or function, various date-time
- separators (as noted) are accepted:
-
- 19800526 13:07:12 26 May 1980, 13:07:12 (1:07:12PM)
- 20010208_10:28:35 2 February 2001, 10:28:35 AM
- 18580101:12:00:00 1 January 1858, noon
- 20110208T00:00:00 2 February 2011, midnight
-
- Certain other special date-time formats that are encountered on
- computer networks are recognized:
-
- Asctime Format
- This is a fixed format used by Unix, named after Unix's
- asctime() ("ASCII time") function. It is always exactly 24
- characters long. Example: Fri Aug 10 16:38:01 2001
-
- Asctime with Timezone
- This is like Asctime format, but includes a 3-character
- timezone between the time and year. It is exactly 28 characters
- long. Example: Fri Aug 10 16:38:01 GMT 2001
-
- E-Mail Format
- E-mail date-time formats are defined in [468]RFC 2822 with a
- fair amount of flexibility and options. The following examples
- are typical of e-mails and HTTP (web-page) headers:
-
- Sat, 14 Jul 2001 11:49:29 (No timezone)
- Fri, 24 Mar 2000 14:19:59 EST (Symbolic timezone)
- Tue, 26 Jun 2001 10:19:45 -0400 (EDT) (GMT Offset + comment)
-
- FTP MDTM Format
- This is the date-time format supplied by FTP servers that
- support the (not yet standard but widely used nevertheless)
- MDTM command, by which the FTP client asks for a file's
- modification time:
-
- yyyymmddhhmmss[.ffff]
-
- where yyyy is the 4-digit year, mm is the 2-digit month, and so
- on, exactly 14 digits long. An optional fractional part
- (fraction of second) may also be included, separated by a
- decimal point (period). Kermit rounds to the nearest second.
- Example:
-
- 20020208102835.515 (8 February 2002 10:28:36 AM)
-
- 8.13.1. The Date
-
- The date, if given, must precede the time and/or delta, and can be in
- many, many formats. For starters, you can use several symbolic date
- names in place of actual dates:
-
- NOW
- This is replaced by the current date and time. The time can not
- be overriden (if you want to supply a specific time, use TODAY
- rather than NOW).
-
- TODAY
- This is replaced by the current date and a default time of
- 00:00:00 is supplied, but can be overridden by a specific time;
- for example, if today is 8 February 2002, then "TODAY" is
- "20020802 00:00:00" but "TODAY 10:28" is "20020802 10:28:00".
-
- TOMORROW
- Like TODAY, but one day later (if today is 8 February 2002,
- then "TOMORROW" is "20020803 00:00:00" but "TOMORROW 16:30" is
- "20020803 16:30:00").
-
- YESTERDAY
- Like TODAY, but one day earlier.
-
- MONDAY, TUESDAY, WEDNESDAY, ..., SUNDAY
- The date on the given day of the week, today or later. A
- default time of 00:00:00 is supplied but can be overridden.
- Example: "SATURDAY 12:00" means next Saturday (or today, if
- today is Saturday) at noon.
-
- You can give an explicit date in almost any conceivable format, but
- there are some rules:
-
- * If a date is given, it must have three fields: day, month, and
- year; the order can vary (except that the month can not be last).
- * If names are used for days, months, etc, they must be English.
- * The year must lie between 0000 and 9999, inclusive.
- * All calendar calculations use Gregorian dating, so calculated
- dates for years prior to 1582 (or later, depending on the country)
- will not agree with historical dates. Other forms of dating (e.g.
- Hebrew, Chinese) are not supported.
-
- Various date-field separators are accepted: hyphen, slash, space,
- underscore, period. The same field separator (if any) must be used in
- both places; for example 18-Sep-2001 but not 18-Sep/2001. Months can
- be numeric (1-12) or English names or abbreviations. Month name
- abbreviations are normally three letters, e.g. Apr, May, Jun, Jul.
- Capitalization doesn't matter.
-
- Here are a few examples:
-
- 18 Sep 2001 (English month, abbreviated)
- 18 September 2001 (English month, spelled out)
- 2001 Sept 18 (Year, month, day)
- 18-Sep-2001 (With hyphens)
- 18/09/2001 (All numeric with slashes)
- 18.09.2001 (Ditto, with periods)
- 18_09_2001 (Ditto, with underscores)
- 09/18/2001 (See below)
- 2001/09/18 (See below)
- September 18, 2001 (Correspondence style)
- Sep-18-2001 (Month-day-year)
- 20010918 (Numeric, no separators)
-
- You can also include the day of the week with a specific date, in
- which case it is accepted (if it is a valid day name), but not
- verified to agree with the given date:
-
- Tue, 18 Sep 2001 (Abbreviated, with comma)
- Tue,18 Sep 2001 (Comma but no space)
- Tue 18 Sep 2001 (Abbreviated, no comma)
- Tuesday 18 Sep 2001 (Spelled out)
- Tuesday, 18 Sep 2001 (etc)
- Friday, 18 Sep 2001 (Accepted even if not Friday)
-
- In all-numeric dates with the year last, such as 18/09/2001, Kermit
- identifies the year because it's 4 digits, then decides which of the
- other two numbers is the month or day based on its value. If both are
- 12 or less and are unequal, the date is ambiguous and is rejected. In
- all-numeric dates with the year first, the second field is always the
- month and the third is the day. The month never comes last. A date
- with no separators is accepted only if it is all numeric and has
- exactly eight digits, and is assumed to be in yyyymmdd format.
-
- 20010918 (18-Sep-2001 00:00:00)
-
- or 14 digits (as in FTP MDTM format):
-
- 20010918123456 (18-Sep-2001 12:34:56)
-
- You can always avoid ambiguity by putting the year first, or by using
- an English, rather than numeric, month. A date such as 09/08/2001
- would be ambiguous but 2001/09/08 is not, nor is 09-Aug-2001.
-
- Until the late 1990s, it was common to encounter 2-digit years, and
- these are found to this day in old e-mails and other documents. Kermit
- accepts these dates if they have English months, and interprets them
- according to the windowing rules of [469]RFC 2822: "If a two digit
- year is encountered whose value is between 00 and 49, the year is
- interpreted by adding 2000, ending up with a value between 2000 and
- 2049. If a two digit year is encountered with a value between 50 and
- 99, or any three digit year is encountered, the year is interpreted by
- adding 1900."
-
- If you need to specify a year prior to 1000, use leading zeros to
- ensure it is not misinterpreted as a "non-Y2K-compliant" modern year:
-
- 7-Oct-77 (19771007 00:00:00)
- 7-Oct-0077 (00771007 00:00:00)
-
- 8.13.2. The Time
-
- The basic time format is hh:mm:dd; that is hours, minutes, seconds,
- separated by colons, perhaps with an optional fractional second
- separated by a decimal point (period). The hours are in 24-hour
- format; 12 is noon, 13 is 1pm, and so on. Fields omitted from the
- right default to zero. Fields can be omitted from the left or middle
- by including the field's terminating colon. Examples:
-
- 11:59:59 (11:59:59 AM)
- 11:59 (11:59:00 AM)
- 11 (11:00:00 AM)
- 11:59:59.33 (11:59:59 AM)
- 11:59:59.66 (Noon)
- 03:21:00 (3:21:00 AM)
- 3:21:00 (3:21:00 AM)
- 15:21:00 (3:21:00 PM)
- :21:00 (00:21:00 AM)
- ::01 (00:00:01 AM)
- 11::59 (11:00:59 AM)
-
- Leading zeros can be omitted, but it is customary and more readable to
- keep them in the minute and second fields:
-
- 03:02:01 (03:02:01 AM)
- 3:02:01 (03:02:01 AM)
- 3:2:1 (03:02:01 AM)
-
- AM/PM notation is accepted if you wish to use it:
-
- 11:59:59 (11:59:59 AM)
- 11:59:59AM (11:59:59 AM)
- 11:59:59A.M. (11:59:59 AM)
- 11:59:59am (11:59:59 AM)
- 11:59:59a.m. (11:59:59 AM)
- 11:59:59PM (11:59:59 PM = 23:59:59)
- 11:59:59P.M. (11:59:59 PM = 23:59:59)
- 11:59:59pm (11:59:59 PM = 23:59:59)
- 11:59:59p.m. (11:59:59 PM = 23:59:59)
-
- You can omit the colons if you wish, in which case Kermit uses the
- following rules to interpret the time:
-
- 1. 6 digits is hh:mm:ss, e.g. 123456 is 12:34:56.
- 2. 5 digits is h:mm:ss, e.g. 12345 is 1:23:45.
- 3. 4 digits is hh:mm, e.g. 1234 is 12:34.
- 4. 3 digits is h:mm, e.g. 123 is 1:23.
- 5. 2 digits is hh, e.g. 12 is 12:00.
- 6. 1 digit is h (the hour), e.g. 1 is 1:00.
-
- Examples:
-
- 1 (01:00:00 AM)
- 10 (10:00:00 AM)
- 230 (02:30:00 AM)
- 230pm (02:30:00 PM = 14:30:00)
- 1115 (11:15:00 AM)
- 2315 (11:15:00 PM = 23:15:00 PM)
- 23150 (02:31:50 AM)
- 231500 (23:15:00 PM)
-
- 8.13.3. Time Zones
-
- If a time is given, it can (but need not) be followed by a time zone
- designator. If no time zone is included, the time is treated as local
- time and no timezone conversions are performed.
-
- The preferred time zone designator is the UTC Offset, as specified in
- [470]RFC 2822: a plus sign or minus sign immediately followed by
- exactly four decimal digits, signifying the difference in hh (hours)
- and mm (minutes) from Universal Coordinated Time (UTC, also known as
- Greenwich Mean Time, or GMT), with negative numbers to the West and
- positive numbers to the East. For example:
-
- Fri, 13 Jul 2001 12:54:29 -0700
-
- indicates a local time of 12:54:29 that is 07 hours and 00 minutes
- behind (less than, East of) Universal Time. The space is optional, so
- the example could also be written as:
-
- Fri, 13 Jul 2001 12:54:29-0700
-
- The following symbolic time zones are also accepted, as specified by
- [471]RFC 2822 and/or in ISO 8601:
-
- GMT = +0000 Greenwich Mean Time
- Z = +0000 Zulu (Zero Meridian) Time
- UTC = +0000 Universal Coordinated Time
- UT = +0000 Universal Time
- EDT = -0400 Eastern (USA) Daylight Time
- EST = -0500 Eastern (USA) Standard Time
- CDT = -0500 Central (USA) Daylight Time
- CST = -0600 Central (USA) Standard Time
- MDT = -0600 Mountain (USA) Daylight Time
- MST = -0700 Mountain (USA) Standard Time
- PDT = -0700 Pacific (USA) Daylight Time
- PST = -0800 Pacific (USA) Standard Time
-
- Note that GMT, Z, UTC, and UT all express the same concept: standard
- (not daylight) time at the Zero Meridian. UTC, by the way, is an
- international standard symbol and does not correspond to the order of
- the English words, Universal Coordinated Time, but it happens to have
- the same initial letters as these words. Of course hundreds of other
- symbolic timezones and variations exist, but they are not
- standardized, and are therefore not supported by Kermit.
-
- When a time zone is included with a time, the time is converted to
- local time. In case the conversion crosses a midnight boundary, the
- date is adjusted accordingly. Examples converting to EST (Eastern USA
- Standard Time = -0500):
-
- 11:30:00 = 11:30:00
- 11:30:00 EST = 11:30:00
- 11:30:00 GMT = 06:30:00
- 11:30:00 PST = 14:30:00
- 11:30:00Z = 06:30:00
- 11:30PM GMT = 18:30:00
- 11:30 -0500 = 11:30:00
- 11:30 -0800 = 08:30:00
- 11:30 +0200 = 04:30:00
-
- Unlike most of Kermit's other date-time conversions, timezone
- knowledge (specifically, the offset of local time from UTC) is
- embodied in the underlying operating system, not in Kermit itself, and
- any conversion errors in this department are the fault of the OS. For
- example, most UNIX platforms do not perform conversions for years
- prior to 1970.
-
- 8.13.4. Delta Time
-
- Date/time expressions can be composed of a date and/or time and a
- delta time, or a delta time by itself. When a delta time is given by
- itself, it is relative to the current local date and time. Delta times
- have the following general format:
-
- {+,-}[number units][hh[:mm[:ss]]]
-
- In other words, a delta time always starts with a plus or minus sign,
- which is followed by a "part1", a "part2", or both. The "part1", if
- given, specifies a number of days, weeks, months, or years; "part2"
- specifies a time in hh:mm:ss notation. In arithmetic terms, these
- represents some number of days or other big time units, and then a
- fraction of a day expressed as hours, minutes, and seconds; these are
- to be added to or subtracted from the given (or implied) date and
- time. The syntax is somewhat flexible, as shown by the following
- examples:
-
- +1 day (Plus one day)
- +1day (Ditto)
- +1d (Ditto)
- + 1 day (Ditto)
- + 1 day 3:00 (Plus one day and 3 hours)
- +1d3:00 (Ditto)
- +1d3 (Ditto)
- +3:00:00 (Plus 3 hours)
- +3:00 (Ditto)
- +3 (Ditto)
- +2 days (Plus 2 days)
- -12 days 7:14:22 (Minus 12 days, 7 hours, 14 minutes, and 22 seconds)
-
- The words "week", "month", and "year" can be used like "day" in the
- examples above. A week is exactly equivalent to 7 days. When months
- are specified, the numeric month number of the date is incremented or
- decremented by the given number, and the year and day adjusted
- accordingly if necessary (for example, 31-Jan-2001 +1month =
- 03-Mar-2001 because February does not have 31 days). When years are
- specified, they are added or subtracted to the base year. Examples
- (assuming the current date is 10-Aug-2001 and the current time is
- 19:21:11):
-
- 18-Sep-2001 +1day (20010918 00:00:00)
- today +1day (20010811 00:00:00)
- now+1d (20010811 19:21:11)
- + 1 day (20010811 19:21:11)
- + 1 day 3:14:42 (20010811 22:35:54)
- + 7 weeks (20010928 19:21:11)
- +1d3:14:42 (20010811 22:35:54)
- +1w3:14:42 (20010817 22:35:54)
- +1m3:14:42 (20010910 22:35:54)
- +1y3:14:42 (20020810 22:35:54)
- 2 feb 2001 + 10 years (20110208 00:00:00)
- 2001-02-08 +10y12 (20110208 12:00:00)
- 31-dec-1999 23:59:59+00:00:01 (20000101 00:00:00)
- 28-feb-1996 +1day (19960229 00:00:00) (leap year)
- 28-feb-1997 +1day (19970301 00:00:00) (nonleap year)
- 28-feb-1997 +1month (19970328 00:00:00)
- 28-feb-1997 +1month 11:59:59 (19970328 11:59:59)
- 28-feb-1997 +20years (20170228 00:00:00)
- 28-feb-1997 +8000years (99970228 00:00:00)
-
- For compatibility with VMS, the following special delta-time format is
- also accepted:
-
- +number-hh:mm:ss
- -number-hh:mm:ss
-
- (no spaces). The hyphen after the number indicates days. It
- corresponds exactly to the Kermit notation:
-
- +numberdhh:mm:ss
- -numberdhh:mm:ss
-
- The following forms all indicate exactly the same date and time:
-
- 18-Sep-2001 12:34:56 +1-3:23:01
- 18-Sep-2001 12:34:56 +1d3:23:01
- 18-Sep-2001 12:34:56 +1 day 3:23:01
-
- and mean "add a day plus 3 hours, 23 minutes, and 1 second" to the
- given date.
-
- Note that delta times are not at all the same as UTC offsets; the
- former specifies an adjustment to the given date/time and the latter
- specifies that the local time is a particular distance from Universal
- Time, for example:
-
- 11-Aug-2001 12:34:56 -0800 (20010811 16:34:56 -- UTC Offset)
- 11-Aug-2001 12:34:56 -08:00 (20010811 04:34:56 -- Delta time)
-
- If you give a time followed by a modifer that starts with a + or -
- sign, how does Kermit know whether it's a UTC offset or a delta time?
- It is treated as a UTC offset if the sign is followed by exactly four
- decimal digits; otherwise it is a delta time. Examples (for USA
- Eastern Daylight Time):
-
- 11-Aug-2001 12:34:56 -0800 (20010811 16:34:56 -- UTC Offset)
- 11-Aug-2001 12:34:56 -08:00 (20010811 04:34:56 -- Delta time)
- 11-Aug-2001 12:34:56 -800 (20010811 04:34:56 -- Delta time)
- 11-Aug-2001 12:34:56 -8 (20010811 04:34:56 -- Delta time)
-
- The first example says that at some unknown place which is 8 hours
- ahead of Universal Time, the time is 12:34:56, and this corresponds to
- 16:34:56 in Eastern Daylight time. The second example says to subtract
- 8 hours from the local time. The third and fourth are delta times
- because, even though a colon is not included, the time does not
- consist of exactly 4 digits.
-
- When a delta time is written after a timezone, however, there is no
- ambiguity and no syntax distinction is required:
-
- 11-Aug-2001 12:34:56 -0800 -0800 (20010811 08:34:56)
- 11-Aug-2001 12:34:56 -0800 -08:00 (Ditto)
- 11-Aug-2001 12:34:56 -08:00 -08:00 (Illegal)
-
- 8.13.5. The DATE Command
-
- Obviously a great many combinations of date, time, time zone, and
- delta time are possible, as well as many formatting options. The
- purpose of all this flexibility is to comply with as many standards as
- possible -- Internet RFCs, ISO standards, and proven corporate
- standards -- as well as with notations commonly used by real people,
- in order that dates and times from the widest variety of sources can
- be assigned to a variable and used in any date-time field in any
- Kermit command.
-
- You can test any date-and/or-time format with the DATE command, which
- converts it to standard yyyymmdd hh:mm:ss format if it is understood,
- or else gives an explicit error message (rather than just "BAD DATE"
- as in previous C-Kermit releases) to indicate what is wrong with it.
- Examples (on Tuesday, 31 July 2001 in New York City, Eastern Daylight
- Time, UTC -0400):
-
- DATE command argument Result
- 12:30 20010731 12:30:00
- 12:30:01 20010731 12:30:01
- 12:30:01.5 20010731 12:30:02
- 1230 20010731 12:30:00
- 230 20010731 02:30:00
- 230+1d 20010801 02:30:00
- 230+1d3:00 20010801 05:30:00
- 20010718 19:21:15 20010718 19:21:15
- 20010718_192115 20010718 19:21:15
- 20010718T192115 20010718 19:21:15
- 18 Jul 2001 +0400 20010717 23:59:59
- 18 Jul 2001 192115 20010718 19:21:15
- 18 Jul 2001 192115.8 20010718 19:21:16
- 18-Jul-2001T1921 20010718 19:21:00
- 18-Jul-2001 1921Z 20010718 15:21:00
- 18-Jul-2001 1921 GMT 20010718 15:21:00
- 18-Jul-2001 1921 UTC 20010718 15:21:00
- 18-Jul-2001 1921 Z 20010718 15:21:00
- 18-Jul-2001 1921Z 20010718 15:21:00
- 18-Jul-2001 1921 -04:00:00 20010718 19:21:00
- 21-Jul-2001_08:20:00am 20010721 08:20:00
- 21-Jul-2001_8:20:00P.M. 20010721 20:20:00
- Fri Jul 20 11:26:25 2001 20010720 11:26:25
- Fri Jul 20 11:26:25 GMT 2001 20010720 07:26:25
- Sun, 9 Apr 2000 06:46:46 +0100 20000409 01:46:46
- Sunday, 9 Apr 2000 06:46:46 +0100 20000409 01:46:46
- now 20010731 19:41:12
- today 20010731 00:00:00
- today 09:00 20010731 09:00:00
- tomorrow 20010801 00:00:00
- tomorrow 09:00 20010801 09:00:00
- tomorrow 09:00 GMT 20010801 05:00:00
- yesterday 20010730 00:00:00
- yesterday 09:00 20010730 09:00:00
- + 3 days 20010803 00:00:00
- +3 days 20010803 00:00:00
- +3days 20010803 00:00:00
- + 3days 20010803 00:00:00
- + 3 days 09:00 20010803 09:00:00
- + 2 weeks 20010814 00:00:00
- + 1 month 20010831 00:00:00
- - 7 months 20001231 00:00:00
- + 10 years 20110731 00:00:00
- friday 20010803 00:00:00
- saturday 20010804 00:00:00
- sunday 20010805 00:00:00
- monday 20010806 00:00:00
- tuesday 20010731 00:00:00
- wednesday 20010801 00:00:00
- thursday 20010802 00:00:00
- friday 07:00 20010803 07:00:00
- thursday 1:00pm 20010802 13:00:00
- thursday 1:00pm GMT 20010802 09:00:00
- Thu, 10 Nov 94 10:50:47 EST 19941110 10:50:47
- Fri, 20 Oct 1995 18:35:15 -0400 (EDT) 19951020 18:35:15
- 31/12/2001 20011231 00:00:00
- 12/31/2001 20011231 00:00:00
- 2001-July-20 20010720 00:00:00
- 2001-September-30 20010930 00:00:00
- 30-September-2001 20010930 00:00:00
- Sep 30, 2001 12:34:56 20010930 12:34:56
- September 30, 2001 20010930 00:00:00
- September 30, 2001 630 20010930 06:30:00
- September 30 2001 630 20010930 06:30:00
- Sep-30-2001 12:34:59 20010930 12:34:59
- 20010807113542.014 20010807 11:35.42
- 20010807113542.014Z 20010807 07:35:42
-
- 8.13.6. New Date-Time Functions
-
- In the following descriptions, date-time function arguments are the
- same free-format date-time strings discussed above, with the same
- defaults for missing fields. They are automatically converted to
- standard format internally prior to processing.
-
- \fcvtdate(d1)
- Converts the date-time d1 to standard format and local time.
- This function is not new, but now it accepts a wider range of
- argument formats that can include timezones and/or delta times.
- If the first argument is omitted, the current date and time are
- assumed. The optional second argument is a format code for the
- result:
-
- n1 = 1: yyyy-mmm-dd hh:mm:ss (mmm = English 3-letter month
- abbreviation)
- n1 = 2: dd-mmm-yyyy hh:mm:ss (ditto)
- n1 = 3: yyyymmddhhmmss (all numeric)
-
- \futcdate(d1)
- Converts the date-time d1 to Universal Coordinated Time (UTC),
- also known as GMT or Zulu or Zero-Meridian time. The default d1
- is NOW. If d1 is a valid date-time, the UTC result is returned
- in standard format, yyyymmdd hh:ss:mm.
-
- \fcmpdates(d1,d2)
- Compares two free-format date-times, d1 and d2, and, if both
- arguments are valid, returns a number: -1 if d1 is earlier than
- (before) d2; 0 if d1 is the same as d2; 1 if d1 is later than
- (after) d2.
-
- \fdiffdates(d1,d2)
- Computes the difference between two free-format date-times, d1
- and d2. If both arguments are valid, returns a delta time which
- is negative if d1 is earlier than (before) d2 and positive
- otherwise. If d1 and d2 are equal, the result is "+0:00".
- Otherwise, the result consists of the number of days, hours,
- minutes, and seconds that separate the two date-times. If the
- number of days is zero, it is omitted. If the number of days is
- nonzero but the hours, minutes, and seconds are all zero, the
- time is omitted. if the seconds are zero, they are omitted.
-
- \fdelta2secs(dt)
- Converts a delta time to seconds. For example, "+1d00:00:01" to
- 86401. Valid delta times must start with a + or - sign. Days
- are accepted as time units, but not years, months, or weeks. If
- the result would overflow a computer long word (as would happen
- with 32-bit long words when the number of days is greater than
- 24854), the function fails.
-
- HINT: Although Kermit has a number of built-in date and time
- variables, it doesn't have a single one suitable for writing a
- timestamp. For this you would normally use something like "\v(ndate)
- \v(time)". But \fcvtdate() (with no arguments) is equivalent: it
- returns the current date and time in yyyymmdd hh:mm:ss format,
- suitable for time stamping.
-
- 8.13.7. Date-Time Programming Examples
-
- Here's a macro that converts any date-time to UTC, which you might use
- if C-Kermit didn't already have a \futcdate() function:
-
- define utcdate {
- .local := \fcvtdate(\%*) ; 1.
- .tmp := \fcvtdate(\m(local)UTC) ; 2.
- .offset := \fdiffdate(\m(local),\m(tmp)) ; 3.
- .utc := \fcvtdate(\m(local)\m(offset)) ; 4.
- sho mac utc ; 5.
- }
-
- Brief explanation: Line 1 converts the macro argument, a free-format
- date-time, to standard-format local time. Line 2 appends the "UTC"
- timezone to the local time and converts the result to local time. In
- other words, we take the same time as the local time, but pretend it's
- UTC time, and convert it to local time. For example, if New York time
- is 4 hours ahead of UTC, then 6:00pm New York time is 2:00pm UTC. Line
- 3 gets the difference of the two results (e.g. "+04:00"). Line 4
- appends the difference (delta time) to the local time, and converts it
- again, which adds (or subtracts) the UTC offset to the given time.
- Line 5 displays the result.
-
- Here's a script that opens a web page, gets its headers into an array,
- scans the array for the "Last-Modified:" header, and inteprets it:
- http open www.columbia.edu
- if fail stop 1 HTTP OPEN failed
- http /array:a head index.html /dev/null
- if fail stop 1 HTTP GET failed
- show array a
- for \%i 1 \fdim(&a) 1 {
- .\%x := \findex(:,\&a[\%i])
- if not \%x continue
- .tag := \fleft(\&a[\%i],\%x-1)
- .val := \fltrim(\fsubstr(\&a[\%i],\%x+1))
- if ( eq "\m(tag)" "Last-Modified" ) {
- echo HTTP Date: \m(val)
- .rdate := \fcvtdate(\m(val))
- echo {Standard Date (local): \m(rdate)}
- echo {Standard Date (UTC): \futcdate(\m(rdate))}
- break
- }
- }
- http close
-
- The result:
-
- HTTP Date: Mon, 13 Aug 2001 20:05:42 GMT
- Standard Date (local): 20010813 16:05:42
- Standard Date (UTC): 20010813 20:05:42
-
- As you can see, Kermit had no trouble decoding the date-time-string
- from the website, converting to local time, and converting back to UTC
- with no conflicts or loss of information. If it had been in any other
- known format, the result would have been the same.
-
- Now suppose we want to download the web page only if it is newer than
- our local copy. The \fdate(filename) function (which returns the
- modification date-time of the given file) and the new \fcmpdates()
- function make it easy. Insert the following just before the BREAK
- statement:
-
- if ( < 0 \fcmpdates(\m(rdate),\fdate(index.html)) ) {
- echo GETTING index.html...
- http get index.html index.html
- if success echo HTTP GET OK
- } else {
- echo index.html: no update needed
- }
- http close
- exit
-
- This says, "if 0 is less than the comparison of the remote file date
- and the local file date, get the remote file, otherwise skip it." And
- it automatically reconciles the time-zone difference (if any).
-
- It would be nice to be able to extend this script into a
- general-purpose website updater, but unfortunately HTTP protocol
- doesn't provide any mechanism for the client to ask the server for a
- list of files, recursive or otherwise.
-
- [ [472]Top ] [ [473]Contents ] [ [474]C-Kermit Home ] [ [475]Kermit
- Home ]
- _________________________________________________________________
-
- 8.14. Trapping Keyboard Interruption
-
- Normally when you type Ctrl-C and Kermit is in command mode (as
- opposed to CONNECT mode) with COMMAND INTERRUPTION ON (as it is unless
- you have set it OFF), Kermit interrupts any command that is currently
- in progress, and if a command file or macro is executing, rolls the
- command stack back to top level, closing all open command files,
- deactivating all macros, deallocating all local variables and arrays,
- and leaving you at the command prompt.
-
- Suppose, however, you want certain actions to occur when a script is
- interrupted; for example, closing open files, writing log entries, or
- displaying summary results. You can do this by defining a macro named
- ON_CTRLC. When Ctrl-C is detected, and a macro with this name is
- defined, Kermit executes it from the current command level, thus
- giving it full access to the environment in which the interruption
- occurred, including local variables and open files. Only when the
- ON_CTRLC macro completes execution is the command stack rolled back to
- top level.
-
- Once the ON_CTRLC macro is defined, it can be executed only once. This
- is to prevent recursion if the user types Ctrl-C while the ON_CTRLC
- macro is executing. If you type Ctrl-C while the Ctrl-C macro is
- active, this does not start a new copy of ON_CTRLC; rather, it returns
- to the top-level command prompt. After the ON_CTRLC macro returns, it
- has been removed from the macro table so if you want to use it again
- or install a different Ctrl-C trap, you must execute a new DEFINE
- ON_CTRLC command. In any case, as always when you interrupt a script
- with Ctrl-C, its completion status is FAILURE.
-
- Normally the ON_CTRLC macro would be defined in the command file or
- macro to which it applies, and should be declared LOCAL. This way, if
- the command file or macro completes successfully without being
- interrupted, the ON_CTRLC definition disappears automatically.
- Otherwise the definition would still be valid and the macro would be
- executed, probably out of context, the next time you typed Ctrl-C.
-
- Here's a simple example of a command file that sets a Ctrl-C trap for
- itself:
-
- local on_ctrlc ; Make Ctrl-C trap local to this command file.
- define on_ctrlc { ; Define the ON_CTRLC macro.
- echo Interrupted at \v(time).
- echo Iterations: \%n
- }
- xecho Type Ctrl-C to quit
- for \%n 1 999 1 { ; Prints a dot every second until interrupted.
- sleep 1
- xecho .
- }
- echo Finished normally at \v(time) ; Get here only if not interrupted.
- decrement \%n
- echo Iterations: \%n
-
- This prints a summary no matter whether it completes normally or is
- interrupted from the keyboard. In both cases the trap is automatically
- removed afterwards.
-
- For an example of how to use ON_CTRLC to debug scripts, see
- [476]Section 8.1.
-
- [ [477]Top ] [ [478]Contents ] [ [479]C-Kermit Home ] [ [480]Kermit
- Home ]
- __________________________________________________________________________
-
-9. S-EXPRESSIONS
-
- This section is primarily for those who want to write
- calculation-intensive scripts, especially if they require
- floating-point arithmetic, and/or for those who are familiar with the
- LISP programming language.
-
- Ever since C-Kermit version 5 was released in 1988, scripting has been
- one of its major attractions, and arithmetic is a key part of it.
- Versions 5 and 6 included integer arithmetic only, using traditional
- algebraic notation, e.g.:
-
- echo \fevaluate(3*(2+7)/2)
- 13
-
- C-Kermit 7.0 added support for floating-point arithmetic, but only
- through function calls:
-
- echo \ffpdivide(\ffpmultiply(3.0,\ffpadd(2.0,7.0)),2.0)
- 13.5
-
- C-Kermit 8.0 introduces a third form of arithmetic that treats
- integers and floating-point numbers uniformly, is easier to read and
- write, and executes very quickly:
-
- (/ (* 3 (+ 2 7)) 2)
- 13.5
-
- But first some background.
-
- The Kermit command and scripting language differs from true
- programming languages (such as C or Fortran) in many ways; one of the
- most prominent differences is the way in which variables are
- distinguished from constants. In a command language, words are taken
- literally; for example, the Unix shell:
-
- cat foo.bar
-
- displays the file named foo.bar. Whereas in a programming language
- like C, words are assumed to be variables:
-
- s = foo.bar; /* Assigns the value of foo.bar to the variable s */
-
- To make a programming language take words literally, you have to quote
- or "escape" them:
-
- s = "foo.bar"; /* Assigns a pointer to the string "foo.bar" to the variable
-s */
-
- The opposite holds for command languages: to get them to treat a word
- as a variable rather than a constant, you have to escape them. For
- example, in the Unix shell:
-
- foo=123 ; Assign value 123 to variable foo.
- echo foo ; Prints "foo"
- echo $foo ; Prints "123"
-
- And in Kermit:
-
- define foo 123 ; Assign value 123 to variable foo.
- echo 123 ; This prints "123".
- echo foo ; This prints "foo".
- echo \m(foo) ; This prints "123".
-
- In other words, character strings (such as "foo" above) are
- interpreted as literal strings, rather than variable names, except in
- special commands like DEFINE that deal specifically with variable
- names (or in numeric contexts as explained in [481]Section 8.2). The
- special "escape" character (dollar sign ($) for the shell, backslash
- (\) for Kermit) indicates that a variable is to be replaced by its
- value.
-
- The requirement to escape variable names in command languages normally
- does not impose any special hardship, but can add a considerable
- notational burden to arithmetic expressions, which are typically full
- of variables. Especially in Kermit when floating point numbers are
- involved, where you must use special \ffpxxx() functions, e.g.
- "\ffpadd(\m(a),\m(b))" rather than the simple "+" operator to add two
- floating-point numbers together, because the original arithmetic
- handler doesn't support floating point (this might change in the
- future). To illustrate, the general formula for the area of a triangle
- is:
-
- sqrt(s * (s - a) * (s - b) * (s - c))
-
- where a, b, and c are the lengths of the triangle's three sides and:
-
- s = (a + b + c) / 2
-
- Except in special cases (e.g. a = 3, b = 4, c = 5), the result has a
- fractional part so the computation must be done using floating-point
- arithmetic. We can create a Kermit 7.0 function for this as follows:
-
- def area {
- local s t1 t2 t3
- assign s \ffpdiv(\ffpadd(\ffpadd(\%1,\%2),\%3),2.0)
- assign t1 \ffpsub(\m(s),\%1)
- assign t2 \ffpsub(\m(s),\%2)
- assign t3 \ffpsub(\m(s),\%3)
- return \ffpsqrt(\ffpmul(\m(s),\ffpmul(\m(t1),\ffpmul(\m(t2),\m(t3)))))
- }
-
- But as you can see, this is rather cumbersome. Note, in particular,
- that arithmetic functions like \ffpadd(), \ffpmul(), etc, take exactly
- two operands (like their symbolic counterparts + and *), so obtaining
- the product of three or more numbers (as we do in this case) is
- awkward.
-
- Using the alternative S-Expression notation, we can reduce this to a
- form that is both easier to read and executes faster (the details are
- explained later):
-
- def newarea {
- (let s (/ (+ \%1 \%2 \%3) 2.0))
- (sqrt (* s (- s \%1) (- s \%2) (- s \%3)))
- }
-
- In both examples, the \%1..3 variables are the normal Kermit macro
- arguments, referenced by the normal escaping mechanism. For increased
- readability, we can also assign the macro arguments \%1, \%2, and \%3
- to the letters a, b, and c corresponding to our formula:
-
-def newarea {
- (let a \%1 b \%2 c \%3)
- (let s (/ (+ a b c) 2.0))
- (sqrt (* s (- s a) (- s b) (- s c)))
-}
-
- And now the Kermit function reads almost like the original formula.
- Here Kermit behaves more like a regular programming language. In an
- S-Expression, macro names need not be escaped when they are used as
- the names of numeric variables.
-
- [ [482]Top ] [ [483]Contents ] [ [484]C-Kermit Home ] [ [485]Kermit
- Home ]
- _________________________________________________________________
-
- 9.1. What is an S-Expression?
-
- The S-Expression concept is borrowed from the Lisp programming
- language. "S-Expression" is short for Symbolic Expression (itself
- sometimes shortened to SEXP). S-Expressions provide a kind of
- Alternative Mini-Universe within the Kermit command language when the
- regular rules don't apply, a universe enclosed in parentheses.
-
- C-Kermit does not pretend to be a full Lisp interpreter; only the
- arithmetic parts of Lisp have been incorporated: S-Expressions that
- operate on numbers and return numeric values (plus extensibility
- features described in [486]Section 9.8, which allow some degree of
- string processing).
-
- An S-Expression is a list of zero or more items, separated by spaces,
- within parentheses. Examples:
-
- ()
- (1)
- (a)
- (+ a 1)
- (* 2 a b)
-
- If the S-Expression is empty, it has the NIL (empty) value. If it is
- not empty and the first item is an operator (such as + or *), there
- can be zero or more subsequent items, called the operands:
-
- (+ 1 2)
-
- Here the operator is "+" and the operands are "1" and "2", and the
- value of the S-Expression is the value of the operation (in this case
- 3). The operator always comes first, which is different from the
- familiar algebraic notation; this because S-Expression operators can
- have different numbers of operands:
-
- (+ 1)
- (+ 1 2)
- (+ 1 2 3 4 5 6 7 8 9)
-
- If the first item in the S-Expression is not an operator, then it must
- be a variable or a number (or a macro; see [487]Section 9.8), and the
- S-Expression can only contain one item; in this case, the
- S-Expression's value is the value of the variable or number:
-
- (a)
- (3)
-
- Operands can be numbers, variables that have numeric values, functions
- that return numbers, or other S-Expressions. To illustrate an
- S-Expression within an S-Expression, observe that:
-
- (+ 1 2)
-
- is equivalent to any of the following (plus an infinite number of
- others):
-
- (+ 1 (+ 1 1))
- (+ (- 3 2) (/ 14 (+ 3 4)))
-
- S-Expressions can be nested to any reasonable level; for example, the
- value of the following S-Expression is 64:
-
- (- (* (+ 2 (* 3 4)) (- 9 (* 2 2))) 6)
-
- Operators have no precedence, implied or otherwise, since they can't
- be mixed. The only exceptions are unary + and -, which simply indicate
- the sign of a number:
-
- (* 3 -1)
-
- Order of evaluation is specified entirely by parentheses, which are
- required around each operator and its operands: (+ a (* b c)) instead
- of (a + b * c).
-
- S-Expressions provide a simple and isolated environment in which
- Kermit's macro names can be used without the \m(...) escaping that is
- normally required. Given:
-
- define a 1
- define b 2
- define c 3
-
- Then:
-
- (+ \m(a) \m(b) \m(c))
-
- is equivalent to:
-
- (+ a b c)
-
- Within an S-Expression, as in other strictly numeric contexts
- ([488]Section 8.2), any operand that starts with a letter is treated
- as a Kermit macro name. In this context, abbreviations are not
- accepted; variable names must be spelled out in full. Alphabetic case
- is not significant; "a" and "A" are the same variable, but both are
- different from "area".
-
- Of course, regular Kermit variables and functions can be used in
- S-Expressions in the normal ways:
-
- (* \v(math_pi) (^ \%r 2)) ; Area of a circle with radius \%r
- (+ \fjoin(&a)) ; Sum of all elements of array \&a[]
-
- [ [489]Top ] [ [490]Contents ] [ [491]C-Kermit Home ] [ [492]Kermit
- Home ]
- _________________________________________________________________
-
- 9.2. Integer and Floating-Point-Arithmetic
-
- Normally, if all numbers in an S-Expression are integers, the result
- is an integer:
-
- (+ 1 1) ; Result is 2
- (/ 9 3) ; Result is 3
-
- If any of the operands is floating point, however, the result is also
- floating point:
-
- (+ 1 1.0) ; Result is 2.0
- (/ 9.0 3) ; Result is 3.0
-
- If all the operands are integers but the result has a fractional part,
- the result is floating point:
-
- (/ 10 3) ; Result is 3.333333333333333
-
- To force an integer result in such cases, use the TRUNCATE operator:
-
- (truncate (/ 10 3)) ; Result is 3
-
- Similarly, to force a computation to occur in floating point, you can
- coerce one of its operands to FLOAT:
-
- (+ 1 (float 1)) ; Result is 2.0
-
- The result is also floating point if the magnitude of any integer
- operand, intermediate result, or the result itself, is larger than the
- maximum for the underlying machine architecture:
-
- (^ 100 100)
-
- If the result is too large even for floating-point representation,
- "Infinity" is printed; if it is too small to be distinguished from 0,
- 0.0 is returned.
-
- Large numbers can be used and large results generated, but they are
- accurate only to the precision of the underlying machine. For example,
- the result of:
-
- (+ 111111111111111111111 222222222222222222222)
-
- should be 333333333333333333333, but 333333333333333300000.0 is
- produced instead if the machine is accurate to only about 16 decimal
- digits, even with coercion to floating-point. The order of magnitude
- is correct but the least significant digits are wrong. The imprecise
- nature of the result is indicated by the ".0" at the end. Contrast
- with:
-
- (+ 111111111 222222222)
-
- which produces an exact integer result.
-
- [ [493]Top ] [ [494]Contents ] [ [495]C-Kermit Home ] [ [496]Kermit
- Home ]
- _________________________________________________________________
-
- 9.3. How to Use S-Expressions
-
- S-Expressions may be given as commands to C-Kermit. Any command whose
- first character is "(" (left parenthesis) is interpreted as an
- S-Expression.
-
- If you enter an S-Expression at the C-Kermit> prompt, its result is
- printed:
-
- C-Kermit>(/ 10.0 3)
- 3.333333333333333
- C-Kermit>
-
- If an S-Expression is executed within a macro or command file, its
- value is not printed. However, you can control the printing action
- with:
-
- SET SEXPRESSION ECHO { AUTO, ON, OFF }
- AUTO is the default, meaning print the value at top level only;
- ON means always print the value; OFF means never print it.
-
- In any case, the value of the most recent S-Expression (and the
- S-Expression itself) may be accessed programmatically through the
- following variables:
-
- \v(sexpression)
- The S-Expression most recently executed.
-
- \v(svalue)
- The value of the S-Expression most recently executed.
-
- Besides issuing S-Expressions as commands in themselves, you can also
- execute them anywhere within a Kermit command, but in this case they
- must be enclosed in a function call (otherwise they are taken
- literally):
-
- \fsexpression(s)
- The argument "s" is an S-Expression; the outer parentheses may
- be omitted. The value of the S-Expression is returned. Note
- that since S-Expressions usually contain spaces, some form of
- grouping or quoting might be needed in some contexts:
-
- echo \fsexpression((+ 1 1)) ; Outer parentheses may be included
- echo \fsexpr(+ 1 1) ; Outer parentheses may be omitted
- echo Value = "\fsexp(+ 1 a)" ; Can be embedded in strings
- echo Value = \&a[\fsexp(/ b 2)] ; Can be used in array subscripts
- if = {\fsexp(+ 1 1)} 2 { ; Braces needed here for grouping
- echo One plus one still equals two
- }
-
- The IF statement illustrates how to use S-Expressions as (or in) IF or
- WHILE conditions:
-
- * Although S-Expressions and IF conditions are similar in
- appearance, they are not interchangeable. Therefore you must use
- \fsexpr() to let Kermit know it's an S-Expression rather than a
- regular IF condition, or a boolean or algebraic expression within
- an IF condition.
- * In contexts where a single "word" is expected, you must enclose
- the \fsexp() invocation in braces if the S-Expression contains
- spaces (and most of them do).
-
- If an S-Expression is the last command executed in a macro, its value
- becomes the return value of the macro; no RETURN command is needed.
- Example:
-
- def newarea {
- (let s (/ (+ \%1 \%2 \%3) 2.0))
- (sqrt (* s (- s \%1) (- s \%2) (- s \%3)))
- }
-
- This is equivalent to (but more efficient than):
-
- def newarea {
- (let s (/ (+ \%1 \%2 \%3) 2.0))
- return \fsexp(sqrt (* s (- s \%1) (- s \%2) (- s \%3)))
- }
-
- When an S-Expression is entered as a command -- that is, the first
- nonblank character of the command is a left parenthesis -- then it is
- allowed to span multiple lines, as many as you like, until the first
- left parenthesis is matched:
-
- (let s (/
- (+
- \%1
- \%2
- \%3
- )
- 2.0
- )
- )
- (sqrt (*
- s
- (- s \%1)
- (- s \%2)
- (- s \%3)
- )
- )
-
- The S-Expression concept lends itself easily to embedding and
- recursion, but the depth to which recursion can occur is limited by
- the resources of the computer (memory size, address space, swap space
- on disk) and other factors. There is no way that C-Kermit can know
- what this limit is, since it varies not only from computer to
- computer, but also from moment to moment. If resources are exhausted
- by recursion, C-Kermit simply crashes; there's no way to trap this
- error. However, you can set a depth limit on S-Expressions:
-
- SET SEXPRESSION DEPTH-LIMIT number
- Limits the number of times the S-Expression reader can invoke
- itself without returning to the given number. The default limit
- is 1000. This limit applies to S-Expressions embedded within
- other S-Expressions as well as to S-Expressions that invoke
- recursive macros. If the limit is exceeded, Kermit prints
- "?S-Expression depth limit exceeded" and returns to its prompt.
- More about recursion in [497]Section 9.8.
-
- You can also test the depth programmatically:
-
- \v(sdepth)
- The current S-Expression invocation depth. The depth includes
- both nesting level and recursion. For example, in:
- (foo (foo (foo (foo (foo))))), the innermost (foo) is at depth
- 5.
-
- Help, completion, and syntax checking are not available within an
- S-Expression. If you type ? within an S-Expression, it says:
-
- C-Kermit>(? S-Expression ("help sexp" for details)
-
- As it says, typing "help sexp" will display a brief help text.
-
- The SHOW SEXPRESSION command displays current SET SEXPRESSION settings
- and related information.
-
- [ [498]Top ] [ [499]Contents ] [ [500]C-Kermit Home ] [ [501]Kermit
- Home ]
- _________________________________________________________________
-
- 9.4. Summary of Built-in Constants and Operators
-
- Three constants are built in:
-
- * PI, whose value is the value of pi (the quotient of circumference
- of any circle and its diameter, 3.141592653...) to the underlying
- machine's precision;
- * T, which always has the value 1, which signifies truth in Kermit
- logical expressions or S-Expressions;
- * NIL, which always has the empty value, and can serve as a False
- truth value.
-
- These constants are specific to S-Expressions and are not visible
- outside them. They may not be used as the target of an assignment. So,
- for example:
-
- (setq t 0) Fails
- assign t 0 Succeeds but this is not the same T!
-
- E (the base of natural logarithms, 2.7182818184...) is not built in
- since it is not intrinsic in most Lisp dialects. If you want E to be
- the base of natural logarithms you can:
-
- (setq e (exp 1))
-
- Operators are either symbols (such as "+") or words. Words must be
- spelled out in full, not abbreviated. Differences of alphabetic case
- are ignored.
-
- The most basic operation in S-Expressions is evaluation:
-
- EVAL [ s-expression or variable or number [ another [ another ... ] ]
- ]
- Evaluates its operands and returns the value of the last one
- evaluated. Examples:
-
- (eval) 0
- (eval 1) 1
- (eval a) value of a
- (eval (+ 1 a)) value of a+1
- (eval (setq a 1) (setq b (+ a 0.5))) value of b (= a+0.5)
-
- You can use "." as a shorthand for EVAL:
-
- (.)
- (. 1)
- (. a)
- (. (+ 1 a))
- (. (setq a 1) (setq b (+ a 0.5)))
-
- Opposite of EVAL is the operator that suppresses evaluation of its
- operand:
-
- QUOTE item
- The value (quote item) is "item". If the item is itself an
- S-Expression, the result is the S-Expression with the outer
- parentheses stripped. Examples:
-
- (quote) (illegal)
- (quote a) a
- (quote hello) hello
- (quote (this is a string)) this is a string
- (quote this is a string) (illegal)
-
- A shorthand notation is also accepted for quoting:
- 'a is equivalent to (quote a). And therefore:
- '(a b c) is equivalent to (quote (a b c)).
- More about quoting in [502]Section 9.8.
-
- STRING item
- Is a combination of EVAL and QUOTE. It evaluates the item as an
- S-Expression, and then puts quotes around the result (more
- about this in [503]Section 9.8).
-
- The following operators assign values to variables:
-
- SETQ [ variable [ value [ variable [ value [ ... ] ] ] ] ]
- Applies to global variables. For each variable given: if a
- value is not given, the variable is undefined. If a value is
- given, assigns the value to the variable. The value may be a
- number, a variable, or anything that resolves to a number
- including an S-Expression. Returns the value of the last
- assignment. Examples:
-
- (setq) Does nothing, returns NIL.
- (setq a) Undefines a, returns NIL.
- (setq a 1) Assigns 1 to a, returns 1.
- (setq a 1 b 2) Assigns 1 to a, 2 to b, returns 2.
- (setq a 1 b 2 c) Assigns 1 to a, 2 to b, undefines c, returns NIL.
-
- To undefine a variable that is not the final one in the list, give it
- a value of "()" or NIL:
-
- (setq a () b 2) Undefines a, assigns 2 to b, returns 2.
- (setq a nil b 2) Ditto.
-
- Note that a variable can be used right away once it has a value:
-
- (setq a 1 b a) Assigns 1 to a, the value of a (1) to b, returns 1.
-
- The results of SETQ (when used with macro names) can be checked
- conveniently with SHOW MACRO, e.g:
-
- show mac a b c
-
- LET [ variable [ value [ variable [ value [ ... ] ] ] ] ]
- Like SETQ, but applies to local variables. Note that "local" is
- used in the Kermit sense, not the Lisp sense; it applies to the
- current Kermit command level, not to the current S-Expression.
-
- If you want to use SETQ or LET to assign a value to a backslash
- variable such as \%a or \&a[2], you must double the backslash:
-
- (setq \\%a 3)
- (setq \\%b (+ \%a 1))
- (setq \\&a[2] (setq (\\%c (+ \%a \%b))))
-
- In other words:
-
- * Double the backslash when you want to indicate the variable's
- NAME;
- * Don't double the backslash when you want its VALUE.
-
- See [504]Section 9.6 for a fuller explanation of variable syntax and
- scope.
-
- Here's a summary table of arithmetic operators; in the examples, a is
- 2 and b is -1.3:
-
- Operator Description Example Result
- + Adds all operands (0 or more) (+ a b) 0.7
- - Subtracts all operands (0 or more) (- 9 5 2 1) 1
- * Multiplies all operands (0 or more) (* a (+ b 1) 3) -1.80
- / Divides all operands (2 or more) (/ b a 2) -0.325
- ^ Raise given number to given power (^ 3 2) 9
- ++ Increments variables (++ a 1.2) 3.2
- -- Decrements variables (-- a) 1
- ABS Absolute value of 1 operand (abs (* a b 3)) 7.8
- MAX Maximum of all operands (1 or more) (max 1 2 3 4) 4
- MIN Minimum of all operands (1 or more) (min 1 2 3 4) 1
- MOD (%) Modulus of all operands (1 or more) (mod 7 4 2) 1
- FLOAT Convert an integer to floating-point (float 1) 1.0
- TRUNCATE Integer part of floating-point operand (truncate 3.333) 3
- CEILING Ceiling of floating-point operand (ceiling 1.25) 2
- FLOOR Floor of floating-point operand (floor 1.25) 1
- ROUND Operand rounded to nearest integer (round 1.75) 2
- SQRT Square root of 1 operand (sqrt 2) 1.414..
- EXP e (2.71828..) to the given power (exp -1) 0.367..
- SIN Sine of angle-in-radians (sin (/ pi 2)) 1.0
- COS Cosine of angle-in-radians (cos pi) -1.0
- TAN Tangent of angle-in-radians (tan pi) 0.0
- LOG Natural log (base e) of given number (log 2.7183) 1.000..
- LOG10 Log base 10 of given number (log10 1000) 3.0
-
- The ++ and -- operators are also assignment operators and work just
- like SETQ and LET in their interpretations of operators and operands,
- but:
-
- * Each target variable must already be defined and have a numeric
- value;
- * The assignment value is the amount by which to increment or
- decrement the variable.
- * If an assignment value is not given, 1 is used.
-
- If you include more than one variable-value pair in a ++ or --
- expression, every variable (except, optionally, the last) must be
- followed by a value. Examples:
-
- (++ a) Equivalent to (setq a (+ a 1)) and to (++ a 1)
- (++ a 2) Equivalent to (setq a (+ a 2))
- (-- a (* 2 pi)) Equivalent to (setq a (- a (* 2 pi)))
- (++ a 1 b 1 c 1 d) Equivalent to four SETQs incrementing a,b,c,d by 1.
-
- Another group of operators forms the predicates. These return a "truth
- value", in which 0 (or NIL) is false, and 1 or any other nonzero
- number is true.
-
- Operator Description Example Result
- = (or ==) Operands are equal (= 1 1.0) 1
- != Operands are not equal (!= 1 1.0) 0
- < Operands in strictly ascending order (< 1 2 3) 1
- <= Operands in ascending order (<= 1 1 2 3) 1
- > Operands in strictly descending order (> 3 2 1) 1
- >= Operands in descending order (<= 3 3 2 1) 1
- AND (&&) Operands are all true (and 1 1 1 1 0) 0
- OR (||) At least one operand is true (or 1 1 1 1 0) 1
- XOR Logical Exclusive OR (xor 3 1) 0
- NOT (!) Reverses truth value of operand (not 3) 0
-
- The Exclusive OR of two values is true if one value is true and the
- other value is false.
-
- And another group operates on bits within an integer word:
-
- Operator Description Example Result
- & Bitwise AND (& 7 2) 2
- | Bitwise OR (| 1 2 3 4) 7
- # Bitwise Exclusive OR (# 3 1) 2
- ~ Reverses all bits (~ 3) -4
-
- These operators coerce their operands to integer by truncation if
- necessary. The result of bit reversal is hardware dependent.
-
- The final category of operator works on truth values:
-
- Operator Description Example Result
- IF Conditional evaluation (if (1) 2 3) 2
-
- IF (predicate) (s1) [ (s2) ]
- The IF operator is similar to Kermit's IF command. If the
- predicate is true (i.e. evaluates to a nonzero number), the
- first S-Expression (s1) is evaluated and its value is returned.
- Otherwise, if (s2) is given, it is evaluated and its value
- returned; if (s2) is not given, nothing happens and the NIL
- (empty) value is returned.
-
- You can group multiple expressions in the s1 and s2 expressions using
- EVAL (or "."):
-
- (if (< a 0) (eval (setq x 0) (setq y 0)) (eval (setq x a) (setq y b)))
-
- or equivalently:
-
- (if (< a 0) (. (setq x 0) (setq y 0)) (. (setq x a) (setq y b)))
-
- Each operator has its own requirement as to number and type of
- operands. In the following table, "number" means any kind of number --
- integer or floating-point -- or a variable, function, macro, or
- S-Expression that returns a number; "vname" means variable name,
- "fpnumber" means a floating-point number (or anything that resolves to
- one), and "integer" means integer (or anything that resolves to one).
- "truthvalue" means anything that resolves to a value of zero or an
- empty value (which indicates false) or a nonzero value (which
- indicates true). "any" means any kind of value, including none at all.
-
- Operator Number of operands Type of operands Returns
- EVAL (.) 0 or more S-Expression Last value (default NIL)
- STRING 1 S-Expression string
- QUOTE (') 1 word string
- SETQ 0 or more vname value pairs Last value (default NIL)
- LET 0 or more vname value pairs Last value (default NIL)
- + 0 or more number number (default 0)
- - 0 or more number number (default 0)
- * 0 or more number number (see note (1))
- / 2 or more number number
- ^ 2 or more number number
- ++ 1 or more vname value pairs Result of last increment
- -- 1 or more vname value pairs Result of last decrement
- ABS 1 number number
- MAX 1 or more number number
- MIN 1 or more number number
- MOD (%) 2 number number
- FLOAT 1 number fpnumber
- TRUNCATE 1 number integer
- CEILING 1 number integer
- FLOOR 1 number integer
- ROUND 1 number integer
- SQRT 1 number fpnumber
- EXP 1 number fpnumber
- SIN 1 number fpnumber
- COS 1 number fpnumber
- TAN 1 number fpnumber
- LOG 1 number fpnumber
- LOG10 1 number fpnumber
- = (==) 1 or more number truthvalue
- != 1 or more number truthvalue
- < 1 or more number truthvalue
- <= 1 or more number truthvalue
- > 1 or more number truthvalue
- >= 1 or more number truthvalue
- AND (&&) 1 or more truthvalue truthvalue
- OR (||) 1 or more truthvalue truthvalue
- XOR 2 truthvalue truthvalue
- NOT (!) 1 truthvalue truthvalue
- & 1 or more number (see note 2) integer
- | 1 or more number (see note 2) integer
- # 2 number (see note 2) integer
- ~ 1 number (see note 2) integer
- IF 2 or 3 truthvalue,any,any any
-
- Operators that don't require any arguments return the default values
- shown.
-
- 1. The value of "*", when used as an operator, is initially "1" and
- the value of the most recent S-Expression thereafter, as in Franz
- Lisp. This is handy when doing a series of calculations by hand:
- C-Kermit>(* 13272.42 0.40)
- 5308.968
- C-Kermit>(/ * 2)
- 2654.4840
- C-Kermit>
- 2. The bitwise operators coerce their operands to integer by
- truncation.
-
- [ [505]Top ] [ [506]Contents ] [ [507]C-Kermit Home ] [ [508]Kermit
- Home ]
- _________________________________________________________________
-
- 9.5. Variables
-
- As noted elsewhere in this discussion, all backslash items (variables
- such as \%a, macro parameters such as \%1, array elements such as
- \&a[\%i], built-in variables such as \v(ndate), built-in functions
- such as \fjoin(), macro names enclosed in \m(), \s(), or \:(), etc)
- are evaluated at "top level" before the S-Expression is sent to the
- S-Expression reader. To use a backslash variable as the target of an
- assignment (e.g. by SETQ, LET, ++, or --), you must double the
- backslash, e.g. (setq \\%r 1234). This is discussed at greater length
- in the next section.
-
- Thus S-Expression reader generally deals only with macro names (not
- backslash items) as variables. It is important to understand how the
- reader handles macro names. There are fundamentally two kinds of
- S-Expressions: those that contain a single element, such as:
-
- (foo)
-
- and those that contain more than one element:
-
- (foo a b c)
-
- If an S-Expression contains only one element, and it is the name of a
- macro, the macro's definition is examined. If the definition is a
- number (integer or floating-point, positive or negative), then this
- becomes the value of the expression. If the definition starts with '
- (apostrophe), then the quoted word or string is the value of the
- expression (explained in [509]Section 9.8). Otherwise, the macro is
- assumed to be composed of Kermit commands (possibly including
- S-Expressions), which are executed. If the macro has a RETURN value,
- or it executes an S-Expression as its last command, the result becomes
- the value of the S-Expression; otherwise the result is empty.
-
- For S-Expressions that contain more than one element, and the first
- element is the name of a macro, then this macro is executed with the
- arguments that are given, after the arguments are evaluated by the
- S-Expression reader. Likewise, If the first element is a built-in
- operator, then it is applied to the operands after they are evaluated.
- In both cases, each operand is fed to the S-Expression reader
- recursively for evaluation. If an operand is a number or a quoted
- string, it is used as-is. But if it's a macro name, this degenerates
- into the first case, and the previous paragraph applies.
-
- Examples:
-
- define foo 123
- (foo) Result: 123
- define foo 'abc
- (foo) Result: abc
- define foo '(one two three)
- (foo) Result: one two three
- define foo return \frandom(1000)
- (foo) Result: 713 (or other number)
- define foo (+ a b)
- (foo) Result: The sum of a and b
-
- A more difficult example:
-
- define foo abc
- (foo) Result: ???
-
- The result in the last example depends on the definition of abc:
-
- * If it has no definition, an error occurs; otherwise:
- * If the definition is an S-Expression, the result is the
- S-Expression's value; otherwise:
- * If the definition consists of Kermit commands, they are executed.
- But in this case "(foo)" produces the empty result, because it
- doesn't RETURN anything.
-
- The use of macros as S-Expression operators is described in
- [510]Section 9.8.
-
- [ [511]Top ] [ [512]Contents ] [ [513]C-Kermit Home ] [ [514]Kermit
- Home ]
- _________________________________________________________________
-
- 9.6. Assignments and Scope
-
- The assignment operators SETQ and LET apply to global and local
- variables, respectively. SETQ and LET are standard Lisp operators
- adapted to Kermit scoping rules. When the operands are numeric or
- arithmetic, SETQ is equivalent to Kermit's EVALUATE command:
-
- (setq a (+ 1 2))
- evaluate a 1 + 2
-
- When the operand is a string, SETQ is equivalent to DEFINE:
-
- (setq a '(this is a string))
- define a this is a string
-
- In the first case, both statements create a macro named "a" with a
- value of 3. But in neither case is the macro "a" necessarily global.
- If either of these commands executes in an environment (i.e. macro
- invocation level) where a "local a" command has been given, the "a"
- macro is global to that environment, but is not visible outside it.
-
- LET is equivalent to the Kermit LOCAL command, followed by the
- corresponding EVALUATE:
-
- (let a (+ 1 2))
-
- is equivalent to:
-
- local a
- evaluate a 1 + 2
-
- Again, "local" in this context applies to the Kermit macro invocation
- stack, not to the S-Expression nesting level. To illustrate, recall
- our "newarea" macro:
-
-def newarea {
- (let a \%1 b \%2 c \%3)
- (let s (/ (+ a b c) 2.0))
- (sqrt (* s (- s a) (- s b) (- s c)))
-}
-
- Because SETQ and LET expressions return a value, they can be placed
- within a larger S-Expression. In this case we can replace the first
- reference to the "s" variable by its defining expression:
-
-def newarea {
- (let a \%1 b \%2 c \%3)
- (sqrt (* (let s (/ (+ a b c) 2.0)) (- s a) (- s b) (- s c)))
-}
-
- This would not work if LET were local to the S-Expression, but it
- works nicely in the context of Kermit macros. The previous definition
- is equivalent to:
-
-def newarea {
- local a b c s
- (setq a \%1 b \%2 c \%3)
- (sqrt (* (setq s (/ (+ a b c) 2.0)) (- s a) (- s b) (- s c)))
-}
-
- In both cases, the variables a, b, c, and s are local to the "newarea"
- macro, and global within it.
-
- Multiple assignments can be handled in several ways. Here is the
- obvious way to initialize a series of variables to the same value:
-
- (setq a 0)
- (setq b 0)
- (setq c 0)
- (setq s 0)
-
- Here is a more compact and efficient way of doing the same thing:
-
- (setq a 0 b 0 c 0 s 0)
-
- However, in case the value was more complex, it's better to put only
- one copy of it in the S-Expression; in this case we rely on the fact
- that SETQ returns the value of its last assignment:
-
- (setq a (setq b (setq c (setq s (* x (^ y 2))))))
-
- Similarly, to set a series of variables to x, x+1, x+2, ...
-
- (setq c (+ (setq b (+ (setq a (+ (setq s x) 1)) 1)) 1))
-
- In the last example, you can see why "last" does not always correspond
- to "rightmost" (the leftmost variable "c" is assigned last).
-
- If you are working with backslash variables like \%a or array elements
- like \&a[1], remember two rules:
- 1. Don't put spaces inside array brackets.
- 2. You must double the backslash when using SETQ, LET, ++, or -- to
- assign a value to a backslash variable.
-
- Examples of assigning to a backslash variable:
-
- (setq x 1)
- (setq \\%a 0)
- (setq \\&a[x+1] 1)
- (++ \\%x)
- (-- \\&a[x+2])
-
- Examples of referring to a backslash variable's value:
-
- (setq a (+ \%a 1))
- (setq b (+ \%a \&a[1]))
- (++ a \%x)
- (-- b \&a[1])
-
- The special notation is required because all backslashed items (\%x
- variables, array elements, built-in \v(xxx) variables, and \fxxx()
- function invocations) are evaluated in a single pass BEFORE the
- S-Expression is executed; any other approach would result in
- unacceptable performance. So, for example, in:
-
- declare \&a[] = 1 2 3
- define \%x 4
- define \%y 0
- (setq \\%y (+ \%x \&a[1]))
-
- the S-Expression becomes:
-
- (setq \%y (+ 4 1))
-
- before it is sent to the S-Expression evaluator. If the backslash had
- not been doubled on the assignment target, the result would have been:
-
- (setq 0 (+ 4 1))
-
- which is illegal because you can't assign a value to a number.
- Conversely, if backslashes were doubled on right-hand-side values:
-
- (setq \\%y (+ \\%x \\&a[1])
-
- this too, would give an error (not numeric - "\%x").
-
- If you omit the double backslash in the assignment target, the result
- depends on whether the variable already has a value:
-
- (setq \%a (* 3 3))
-
- If \%a has a non-numeric single-word value, then this becomes the name
- of the variable that is assigned by SETQ. To illustrate:
-
- define \%a foo
- echo \%a
- foo
- (setq \%a (* 3 3))
- echo \%a
- foo
- show macro foo
- foo = 9
-
- If \%a has no value, a numeric value, or a multiword value, an
- "invalid assignment" error occurs.
-
- [ [515]Top ] [ [516]Contents ] [ [517]C-Kermit Home ] [ [518]Kermit
- Home ]
- _________________________________________________________________
-
- 9.7. Conditional Expressions
-
- The IF operator provides a compact form of decision-making within
- S-Expressions. An IF expression can stand wherever a number might
- stand, as long is it returns a number. Here's a quick way to obtain
- the average value of all the elements in an array that contains only
- numbers:
-
- (/ (+ \fjoin(&a)) (float \fdim(&a)))
-
- This results in a "Divide by zero" error if the array is empty. If you
- want to define the average value of an empty array to be 0 instead of
- getting an error, you can use IF to check the array size:
-
- (if \fdim(&a) (/ (+ \fjoin(&a)) (float \fdim(&a))) 0)
-
- or equivalently:
-
- (if (not \fdim(&a)) 0 (/ (+ \fjoin(&a)) (float \fdim(&a))))
-
- Of course, IF can fit anywhere else into an S-Expression:
-
- (setq a (+ b (if (< c 0) 0 c)))
-
- and the IF expression can be as complex as you like:
-
- (setq a (+ b (if (and (or (> x 0) (> y 0)) (< c 0) (> d 1) (!= e 0)) 1 0)))
-
- and the "then" and "else" parts can contain multiple S-Expressions
- enclosed within (EVAL ...):
-
- (if x (eval (...) (...) (...)) (eval (...) (...) (...)))
-
- AND and OR operators are guaranteed to "short circuit". If any operand
- of AND is false, none of the subsequent operands is evaluated;
- likewise, if an OR operand is true, no further operands are evaluated.
-
- Bear in mind that the S-Expression IF is not the same as Kermit IF;
- the condition is only allowed to be an S-Expression or a variable or
- number, not the whole list of possibilities you see when you type "if
- ?" at the C-Kermit> prompt. But keep reading...
-
- [ [519]Top ] [ [520]Contents ] [ [521]C-Kermit Home ] [ [522]Kermit
- Home ]
- _________________________________________________________________
-
- 9.8. Extensibility
-
- To extend the capabilities of S-Expressions, you can use Kermit macro
- names as operators, with the following limitations:
-
- * The macro must not have the same name as a built-in operator.
- * You must use the full macro name, not an abbreviation.
-
- And with the following enhancement:
-
- * If the last statement executed by the macro is an S-Expression,
- its value is returned automatically. In other words:
-
- define bump (++ \%1)
-
- is equivalent to:
-
- define bump return \fsexpression(++ \%1)
-
- Here's an example in which we define a FIBONACCI operator that returns
- the nth element, n >= 0, of the Fibonacci series, 0 1 1 2 3 5 8 13 21
- 34 55, . . ., in which the first element is 0, the second is 1, and
- each subsequent element is the sum of the two before it. This series
- was devised by Leonardo Pisano, Filius Bonacci (Fibonacci for short)
- in 1202 to describe how fast rabbits can breed, and also forms the
- basis for the Golden Mean, the branching behavior of plants, the
- spiral of a nautilus shell, etc. (Thanks to [523]Dat Thuc Nguyen for
- December 2003 corrections to this section!)
-
- We can write a FIBONACCI function as a macro easily with
- S-Expressions:
-
- define FIBONACCI {
- (if (== \%1 0) 0
- (if (== \%1 1) 1 (+ (fibonacci (- \%1 2)) (fibonacci (- \%1 1)))))
- }
-
- You can read this as:
-
- If the argument (\%1) is 0, return a result of 0; if it is 1,
- return 1; otherwise:
- return the sum of fibonacci(argument - 2) and fibonacci(argument -
- 1)
-
- Note that a RETURN statement is not needed, since S-Expressions
- automatically set the return value of their containing macros.
-
- For comparison, here's how it would be coded without S-Expressions:
-
- define FIBONACCI {
- if == \%1 0 {
- return 0
- } else if == \%1 1 {
- return 1
- } else {
- return \feval(\fexec(fibonacci \feval(\%1-2)) -
- + \fexec(fibonacci \feval(\%1-1)))
- }
- }
-
- Now we can use the FIBONACCI function (whichever way you write it)
- just as if it were a built-in operator:
-
- (fibonacci 6)
-
- Or:
-
- (setq a 10)
- (fibonacci a)
-
- Within S-Expressions only (not outside them), S-Expressions themselves
- can be used as macro arguments:
-
- (setq a 2 b 4)
- (setq x (fibonacci (* a b )))
-
- The value of the S-Expression (in this case "8"), and not the
- S-Expression itself, is sent to the macro.
-
- Your macro is responsible for argument validation and error handling.
- A robust Fibonacci macro would be more like this:
-
- define FIBONACCI {
- if < \v(argc) 2 end 1 ?\%0: Missing argument
- if > \v(argc) 2 end 1 ?\%0: Too many arguments
- if not integer \%1 end 1 ?\%0: Integers only
- if < \%1 1 end 1 ?\%0: Argument out of range
- (if (== \%1 0) 0
- (if (== \%1 1) 1 (+ (fibonacci (- \%1 2)) (fibonacci (- \%1 1)))))
- }
-
- Recall that "END nonzero-number [ message ]" causes a macro invocation
- to fail. When the macro is the operator in an S-Expression, this makes
- the S-Expression fail too. Also note that our Fibonacci macro is just
- an illustration, not a practical example. Since it is recursive (calls
- itself), it won't work for large arguments because the call stack can
- exceed available memory. See [524]Section 9.9.2 for a practical
- alternative.
-
- Kermit macros, when used as S-Expression operators, can do anything at
- all except initiate file transfers: they can print messages on the
- screen, read and write files, interact with the user, and so on. For
- example, here's a macro ASKME that asks you to enter a number, makes
- sure that you did, and then returns its value for use in the
- S-Expression:
-
- define ASKME {
- local \%n
- while true {
- ask \%n { Number: }
- if not def \%n continue
- if not numeric \%n {
- echo Not numeric - "\%n"
- continue
- }
- break
- }
- return \%n
- }
- (setq a (* 2 (askme))) ; Get number from user, double it, assign result to a.
-
- Here's a macro you can use to validate that a number is in a given
- range:
-
- define inrange {
- if != \v(argc) 4 end 1 ?\%0: Wrong number of arguments
- if ( < \%1 \%2 || > \%1 \%3 ) return 0
- return 1
- }
-
- The first argument is the number to be checked, the second is the
- minimum acceptable value, the third is the maximum. You can use this
- (for example) in IF conditions:
-
- define yes echo \%1 IS OK
- define no echo \%1 IS NOT OK
-
- (setq a -1 b 999)
- (if (inrange a 0 100) (yes a) (no a))
- (if (inrange b -1000 +1000) (yes b) (no b))
-
- This is just an illustration, of course; there's already a built-in
- operator to let you do range checking without help from macros:
-
- (if (<= 0 a 100) (yes a) (no a))
- (if (<= -1000 b +1000) (yes b) (no b))
-
- To send string parameters to a macro, some kind of quoting is required
- to tell the S-Expression parser to take a given "word" literally
- rather than replacing it by its value. For this we use the Lisp QUOTE
- operator:
-
- define length return \flength(\%1)
- (length (quote abcdefghijklmnopqrstuvwxyz))
- 26
-
- This causes the string "abcdefghijklmnopqrstuvwxyz" to be sent
- literally to the LENGTH macro. Kermit, like Lisp, also offers a
- shortcut for QUOTE, that lets us quote a word by prefixing it with a
- single quote (') character, also called apostophe (ASCII 39):
-
- (length 'abcdefghijklmnopqrstuvwxyz)
- 26
-
- The two forms are equivalent.
-
- How the macro treats its arguments is up to the macro. In the example
- above, the argument is treated as a literal string. However, it can
- also be treated as a variable name:
-
- define string This is a string
- define length return \flength(\m(\%1))
- (length 'string)
- 16
-
- Note the construct \m(\%1). This means "the value of the macro whose
- name is the value of
- \%1". The value of \%1 in this case is the word "string", and the
- value of the macro whose name is "string" is "This is a string".
-
- What if the macro takes multiple arguments, or a variable number of
- them? Here's a simple macro that prints a phrase that includes its
- arguments:
-
- define complain echo It's too \%*!
-
- (Recall that \%* means "all arguments".)
-
- It can be called in the traditional way:
-
- complain hot Result: "It's too hot!"
- complain cold and wet Result: "It's too cold and wet!"
-
- Or from an S-Expression if you quote the arguments:
-
- (complain 'hot) Result: "It's too hot!"
- (complain 'cold 'and 'wet) Result: "It's too cold and wet!"
-
- To group multiple words into a single argument, use parentheses:
-
- (complain (quote (cold and wet))) Result: "It's too cold and wet!"
- (complain '(cold and wet)) Result: "It's too cold and wet!"
-
- Note the difference:
-
- (complain 'cold 'and 'wet) Three arguments
- (complain '(cold and wet)) One argument
-
- Since the COMPLAIN macro uses \%* to refer to all its arguments, no
- matter how many, it doesn't care which form you use. But it makes a
- difference in cases where the macro refers to its arguments
- individually.
-
- To illustrate, let's consider a macro that receives the name of a
- macro and its argument list and executes it with its arguments,
- without knowing how many arguments there are. The following LOOP macro
- is used to execute the given macro with the given argument list the
- requested number of times:
-
- def loop { local i, for i 1 \%1 1 do \%2 \%3 }
-
- Within the LOOP macro, the first argument (\%1) is the loop count, \%2
- is the macro name, and \%3 is the argument list. When the LOOP macro
- is invoked traditionally like this:
-
- loop 3 complain hot
-
- it prints "It's too hot!" three times. To invoke it from an
- S-Expression, you must quote both the macro name as well as the
- argument, since in this case the macro name itself is an argument:
-
- (loop 3 'complain 'hot)
-
- Now what if you need to send different or variable numbers of
- arguments to the LOOP macro? The LOOP macro can handle it already,
- provided you group the arguments into LOOP's third argument (\%3). In
- Kermit syntax, without grouping:
-
- loop 3 complain cold and wet
-
- prints "It's too cold!" three times ("and wet" is lost); but with
- grouping (either of the following two forms):
-
- loop 3 complain {cold and wet}
- loop 3 complain "cold and wet"
-
- the LOOP macro prints "It's too cold and wet!" three times as desired.
-
- To do the same thing in an S-Expression, just use the Lisp forms of
- quoting instead of the Kermit forms; the following two are equivalent:
-
- (loop 3 'complain (quote (cold and wet)))
- (loop 3 'complain '(cold and wet))
-
- Here's a similar example in which we write a macro that shows both the
- name and the value of one or more other macros, whose names are given
- as arguments (similar to "show macro"):
-
- define display {
- local \%i
- for \%i 1 \v(argc)-1 1 {
- echo \&_[\%i] = \m(\&_[\%i])
- }
- }
-
- (Recall that \&_[] is the macro's argument vector array, equivalent to
- \%1, \%2, ...) The DISPLAY macro can be used in S-Expressions like
- this:
-
- (setq a 1 b 2 c 3)
- (display 'a 'b 'c 'd)
-
- which prints:
-
- a = 1
- b = 2
- c = 3
- d =
-
- The names must be quoted to prevent their evaluation before they are
- sent to the macro. This ability to pass variables "by name" to macros,
- rather than by value, lets you write macros that change the values of
- argument variables. For example, here's a macro that doubles the value
- of its argument variable:
-
- define double (++ \%1 \%1)
-
- which you can call like this:
-
- (setq a 12)
- (double 'a)
-
- In the macro, \%1 is replace by the variable name "a"; "(++ a a)" adds
- "a" to itself, and sets the value of "a" to the result.
-
- There are no built-in operators other than QUOTE, ', and STRING for
- handling strings in S-Expressions, but using just these, plus macros
- that use Kermit's regular string-handling features, you can easily
- extend S-Expressions to do string manipulation:
-
- define len return \flen(\%1) Returns length of argument string
- define cap return \fupper(\%1) Uppercase argument string
- define rev return \freverse(\%1) Reverses argument string
- define sub return \fsubstr(\%1,\%2,\%3) Returns substring of arg string
-
- (len '(this is a string)) Result: 16
- (rev '(this is a string)) Result: gnirts a si siht
- (rev (cap '(this is a string))) Result: GNIRTS A SI SIHT
- (sub (rev (cap '(this is a string))) 5 9) Result: TS A SI S
-
- You can assign a string to a macro name as follows:
-
- (setq foo '(this is a string))
- (setq foo (quote (this is a string)))
-
- The two are exactly equivalent. In both cases, the macro "foo" has the
- value:
-
- '(this is a string)
-
- so when it is retrieved it can be identified as a string rather than a
- number or commands to be executed. Thus:
-
- (setq foo (quote (this is a string)))
- show macro foo
- foo = '(this is a string)
- (foo)
- this is a string
-
- Note the different results for "show macro foo" and "(foo)". The
- former shows the internal definition; the latter evaluates the
- variable, which removes the quoting. And perhaps more important, note
- that if the apostrophe and surrounding parentheses were not stored as
- part of the definition, (foo) would try to execute "this is a string"
- as a command.
-
- Given the assignment above, the following work as expected:
-
- (len foo) Result: 16
- (rev foo) Result: gnirts a si siht
- (rev (cap foo)) Result: GNIRTS A SI SIHT
- (sub (rev (cap foo)) 5 8) Result: TS A SI S
-
- Note that, unlike built-in S-Expression operators that return numbers
- or truth values, these operators return strings. If you want to assign
- their return values to other variables, you can do so:
-
- (setq bar (rev (cap foo))) Result: GNIRTS A SI SIHT
-
- But now the S-Expression processor doesn't know the value of "bar" is
- supposed to be a string, rather than a macro to execute. For this you
- need one final special operator, STRING. The STRING operator takes an
- S-Expression as an operand, evaluates it, and then returns its value
- enclosed in '(), so you can use the value as a string is subsequent
- S-Expressions. Use STRING for referencing macros that return strings:
-
- (setq bar (string (rev (cap foo)))) Result: '(GNIRTS A SI SIHT)
-
- STRING is like QUOTE, except that it evaluates its operand before
- applying the quoting, rather than taking the operand literally.
-
- To reference backslash variables or functions that return string
- values, you must use the regular quoting mechanisms:
-
- (setq time '(\v(time)))
- (setq date '(\v(date)))
- assign \%r this is a string
- (setq s1 '(\%r))
-
- That's because backslash items are evaluated BEFORE the S-Expression
- parser ever sees them, and the values of \v(time) and so on are not
- valid S-Expressions, so STRING won't like them.
-
- Finally a brief word on the touchy topic of quoting. Suppose you want
- to include (say) literal parentheses in a string that will later be
- processed by the S-Expression reader (or \fsplit() or \fword()).
- Normally, you can't do this because parentheses are meaningful in
- these contexts. To defeat the normal parsing rules, you can quote the
- parentheses with backslash. However, due to the many levels of string
- processing involved, a surprisingly large amount of backslashes might
- be required, for example:
-
- (setq s '(a b (c d) \\\\\\\\\\\\\\\\(e f (g h) x\\\\\\\\\\\\\\\\) j k))
-
- This is nearly impossible to explain(*). Instead, just remember two
- points:
-
- * In situations like this, it's better to use DEFINE to create the
- string, rather than SETQ. The example above requires only double
- backslashes when DEFINE is used:
- define s '(a b (c d) \\(e f (g h) x\\) j k)
- * The level of quoting depends on how many levels of evaluation the
- string must pass through, which is not always obvious. However,
- the number of backslashes required in any given situation is
- always a power of 2. So if 1 doesn't work, try 2; if 2 doesn't
- work, try 4; if 4 doesn't work, try 8, 16, 32, and so on.
-
- Considerations like this apply in any scripting language (shell, Tcl,
- Perl, Python, etc). The situation is known as "Quoting Hell".
-
- (*) If you really want an explanation, here it is:
-
- * Every SEXP has its backslash items evaluated in a single pass at
- top level before being passed to the SEXP reader, so \%1,
- \v(ftime), etc, can be evaluated up front, freeing the SEXP reader
- of having to know about such things, which in turn makes it much
- more efficient. Therefore one level of quoting is lost right away,
- and therefore you must double each backslash that is to be used as
- a quote.
- * When the SEXP reader sees '\', it treats it as a quote; discards
- it and keeps the next character. Thus '\\' becomes '\'. This would
- be the end of it, except that:
- * The SEXP reader must call itself recursively on its operands, so
- we must double any quotes in the operands: 2^2 = 4.
- * If the result is to be passed as an argument to a macro, the
- backslashes must again be doubled, because the macro processor
- evaluates the arguments before sending them to the macro: 2^3 = 8.
- * If the macro itself is to see the quotes, rather than just the
- result of the quoting, the quotes must be doubled again: 2^4 = 16.
-
- Moral: To create string constants in which grouping characters must be
- quoted, use DEFINE rather than SETQ.
-
- [ [525]Top ] [ [526]Contents ] [ [527]C-Kermit Home ] [ [528]Kermit
- Home ]
- _________________________________________________________________
-
- 9.9. Examples
-
- 9.9.1. Statistics
-
- The following program computes statistics -- means, maxima, mimima,
- variance, standard deviation, and correlation -- from data stored in
- parallel arrays, \&x[] and \&y[], which can contain any mixture of
- integer and floating-point numbers: positive, negative, or zero. Array
- setup and validation are not shown. Except for the traditional FOR
- loop and printing the results at the end, the entire computation is
- done with S-Expressions:
-
-; Initialize sums, maxima, minima, and number of elements
-
- (setq xsum 0 ysum 0 xsum2 0 ysum2 0 xysum 0)
- (setq xmin (setq xmax \&x[1]) ymin (setq ymax \&y[1]))
- (setq n \fdim(&x))
-
-; Loop through elements and accumulate sums, maxima, and minima
-
- for i 1 n 1 {
- (setq x \&x[i] y \&y[i]) ; Notational convenience
- (setq xmax (max xmax x) ymax (max ymax y)) ; X and Y maxima
- (setq xmin (min xmin x) ymin (min ymin y)) ; X and Y minima
- (++ xsum x ysum y) ; X and Y sums
- (++ xsum2 (^ x 2) ysum2 (^ y 2)) ; Sum of X and Y squares
- (++ xysum (* x y)) ; Sum of XY products
- }
-
-; Calculate results
-
- (setq xmean (/ xsum n) ymean (/ ysum n)) ; Mean X and Y
- (setq xss (- xsum2 (/ (^ xsum 2) n))) ; Intermediate values
- (setq yss (- ysum2 (/ (^ ysum 2) n)))
- (setq xyss (- xysum (/ (* xsum ysum) n)))
- (setq xvar (/ xss n) yvar (/ yss n)) ; X and Y variance
- (setq sdx (sqrt xvar) sdy (sqrt yvar)) ; Std deviation in X and Y
- (setq tmp (* xss yss))
- (setq cc (if tmp (/ xyss (sqrt tmp)) 1.0)) ; Correlation coefficient
- show macro xmean ymean xvar yvar sdx sdy cc ; Print the results
-
- The final "if tmp" check accounts for the possibility that both arrays
- contain all 0's. Results can also be printed with "echo CC = \m(cc)",
- or any other desired way. Interestingly, if we had not needed the sum
- of the squares and products, we could have obtained the sums, maxima,
- and minima of the X's and Y's without a loop like this:
-
- (setq xsum (+ \fjoin(&x)) ysum (+ \fjoin(&y)))
- (setq xmax (max \fjoin(&x)) ymax (max \fjoin(&y)))
- (setq xmin (min \fjoin(&x)) ymin (min \fjoin(&y)))
-
- Any Kermit function that returns numbers or lists of numbers can be
- included in an S-Expression as an operand.
- _________________________________________________________________
-
- 9.9.2. Practical Fibonacci Series
-
- The recursive Fibonacci example given previously is simple and
- elegant, but not very useful since it causes memory occupation to grow
- each time it calls itself, until eventually both physical memory and
- disk swap space are filled and the program crashes. Even for small
- arguments, like 17, execution time can be prohibitive:
-
- (setq t1 \v(ftime))
- (setq result (fibonacci 17))
- (setq t2 (- \v(ftime) t1))
- echo FIBONACCI(17) = \m(result): TIME = \ffpround(t2,3)
-
- prints (on a certain rather slow computer):
-
- FIBONACCI(17) = 1597: TIME = 5.861
-
- Any recursive function can be recoded iteratively. The result is not
- as pretty, but execution is far less expensive:
-
- define FIBITER {
- (if (== \%3 0) (\%2) (fibiter (+ \%1 \%2) \%1 (- \%3 1)))
- }
- define FIBONACCI {
- (fibiter 1 0 \%1)
- }
-
- Here's the result on the same computer for the same argument of 17:
-
- FIBONACCI(17) = 1597: TIME = 0.015
-
- (47 times faster.) Execution time increases proportionally to the size
- of the argument in the iterative case, whereas in the recursive case
- it goes up geometrically, quickly reaching infinity.
-
- [ [529]Top ] [ [530]Contents ] [ [531]C-Kermit Home ] [ [532]Kermit
- Home ]
- _________________________________________________________________
-
- 9.10. Differences from Algebraic Notation
-
- In C-Kermit:
-
- * Algebraic notation uses infix operators and normal rules of
- operator precedence, with parentheses used to force exceptions to
- the rules; many operations can be included in an expression.
- S-Expressions use prefix operators with no intrinsic precedence;
- each operation is enclosed in parentheses, and the arrangement of
- parentheses determines precedence.
- * Algebraic infix operators require two operands; S-Expression
- prefix operators can accept a variable number of operands.
- * You can use algebraic notation anywhere that C-Kermit accepts a
- number, e.g. "echo \&a[((1+1)*2-1]", but you can use S-Expressions
- only as top-level commands. You can, however, use either algebraic
- or S-Expressions anywhere at all by enclosing them in \fevaluate()
- or \fsexpression(), respectively.
- * You can use any mixture of integer and floating-point numbers in
- S-Expressions, but only integers are permitted in algebraic
- expressions. Outside of S-Expressions, floating point arithmetic
- is supported only by \ffp...() function calls.
- * Operators and operands in S-Expressions must be separated by
- spaces, e.g. "(+ a b)". Spaces are not required in algebraic
- expressions: "((a+b)*c)".
- * When assigning values to backslash variables (such as \%x or
- \&a[2]) using SETQ or LET, you must double the backslash.
-
- [ [533]Top ] [ [534]Contents ] [ [535]C-Kermit Home ] [ [536]Kermit
- Home ]
- _________________________________________________________________
-
- 9.11. Differences from Lisp
-
- * Kermit has a lot of built-in operators not found in Lisp: ++, ^,
- etc.
- * Most dialects of real Lisp do not allow S-Expressions that don't
- start with an operator, for example:
- (a)
- This expression can cause an error in Lisp (even if "a" has a
- value), but is acceptable in Kermit, where it returns the value of
- the variable "a". Similarly, (1) returns the value "1".
- * In real Lisp, EVAL requires exactly one operand. In Kermit, it can
- have 0, 1, 2, or more operands. It returns the value of the last
- operand evaluated.
- * Real Lisp SETQ and LET usually require an even number of operands.
- Kermit allows an odd number, in which case the last (or only)
- variable is undefined (i.e. deleted, destroyed).
- * Kermit does not support ratios such as "7/8". Some Lisp dialects
- accept ratios as numbers, and generate ratios when told to divide
- two integers whose quotient is not a whole number; e.g. in Common
- Lisp:
- [13] USER(37): (/ (+ 1 2 3 4) 3)
- 10/3
- [13] USER(38):
- * The result of (/ 10 3) is 3.333.... Some Lisp dialects truncate
- the result to 3 since both operands are integers, some don't; some
- give the result as a ratio. C-Kermit always gives a floating point
- result when there is a fractional part. If you want an integer
- result, you can use TRUNCATE, FLOOR, or CEILING, e.g. (truncate (/
- 10 3)).
- * There is currently no "bignum" support. Large numbers can be used
- and large results generated, but (as noted in [537]Section 9.2)
- they are accurate only to the precision of the underlying machine.
- \v(math_precision) gives the machine precision as a number of
- decimal digits, e.g. 16.
- * Scientific notation for floating-point numbers is not supported.
- If the magnitude of a number is greater than the precision of the
- underlying hardware, the less-significant digits are shown but
- their values are meaningless. If it the number is too small to be
- represented internally, it is shown as "0.0".
- * Many Lisp features are omitted: List processing (CAR, CDR, etc),
- DEFUN, Lisp-specific control structures, and so on.
-
- [ [538]Top ] [ [539]Contents ] [ [540]C-Kermit Home ] [ [541]Kermit
- Home ]
- __________________________________________________________________________
-
-10. FILE TRANSFER
-
- New commands and switches:
-
- SET TRANSFER REPORT { OFF, ON }
- Enables or disables the (new) one-line message printed by
- Kermit after a remote-mode file transfer to indicate the source
- and destination file, complete with path, to let you know where
- the file went.
-
- SEND /TYPE:{TEXT,BINARY}
- Sends only files of the given type (see [542]Section 4).
-
- SEND /NOFOLLOWLINKS:
- (UNIX only) Skip over symbolic links rather than following them
- (default). This applies to wildcard and/or recursive SENDs; if
- a single filename is given, and it happens to be a symbolic
- link, the file it points to is sent.
-
- SEND /FOLLOWLINKS:
- (UNIX only) Follow (resolve) symbolic links. Watch out for
- circular links, endless loops, etc.
-
- SET SEND I-PACKETS { OFF, ON }
- When sending commands to a Kermit server, this tells whether
- command packets should be preceded by an I (information)
- packet, which is used to synchronize parameters prior to
- executing the command. Normally ON. The only reason to set this
- OFF is for communicating with buggy Kermit servers that
- misbehave when an I packet is sent to them. There is also a SET
- RECEIVE I-PACKETS command, but presently it has no effect.
-
- SET TRANSFER MESSAGE [ text ]
- Sets an initial message to be shown in the Last Message field
- of the fullscreen file-transfer display.
-
- SET TRANSFER TRANSLATION { ON, OFF }
- Inhibits or re-enables text-file transfer character-set
- translation globally.
-
- { SEND, MSEND, GET, RECEIVE } /TRANSPARENT
- Inhibits character-set translation for this transfer only.
-
- { GET, RECEIVE } /PIPES:{ON,OFF}
- Overrides global TRANSFER PIPES setting for this transfer only;
- ON allows incoming files with names like "!tar xf -" to be
- opened as pipelines rather than regular files.
-
- The following new "hot keys" are available when Kermit's file-transfer
- display is visible:
-
- D: Turn on debugging, open "debug.log" if not already open.
- d: Turn off debugging but leave log open (if it was open).
- T: Turn on debug-log timestamps.
- t: Turn off debug-log timestamps.
-
- Other improvements:
- * SET FILE DOWNLOAD-DIRECTORY now works for external protocols (e.g.
- sz/rz) too.
- * Improved automatic per-file text/binary switching, described in
- [543]Section 4.
- * When sending a file group (e.g. "send *.*"), failure to open a
- file is no longer fatal; now C-Kermit simply goes ahead to the
- next file.
- * Transaction log entries are now made for external protocols too.
-
- [ [544]Top ] [ [545]Contents ] [ [546]C-Kermit Home ] [ [547]Kermit
- Home ]
- __________________________________________________________________________
-
-11. MODEMS AND DIALING
-
- In C-Kermit 8.0, the default modem type for dialing has changed from
- NONE (= DIRECT, meaning no modem) to GENERIC. This change should have
- no impact on direct connections. For dialing, it means that, unless
- you SET MODEM TYPE to a specific type, such as USROBOTICS or CONEXANT,
- Kermit assumes:
-
- 1. The modem uses the Hayes AT command set.
- 2. The modem supports error correction, data compression, and
- hardware flow control and is already configured to use them.
-
- In fact, Kermit assumes the modem is completely configured, and
- therefore does not send it an initialization string or any
- configuration commands. Instead, it sends only the simplest and most
- portable commands:
-
- ATQ0V1 Give dial result codes.
- ATDTnumber Dial the number.
-
- (or ATD or ATDP, as appropriate).
-
- The new defaults work for direct connections and for most modern
- modems on most platforms, and they work much faster than
- "full-treatment" dialing. If the new defaults don't work for you, or
- if you need to perform explicit modem configuations or interactions,
- then set a specific modem type and use the SET MODEM and SET DIAL
- commands as documented in Using C-Kermit.
-
- WARNING: Don't use the generic modem on hosts that do not support
- RTS/CTS flow control. If Xon/Xoff is in use on the serial port,
- you'll need to select a particular modem type so Kermit knows what
- command to give it to enable Xon/Xoff flow control between itself
- and your serial port.
-
- The following new modem types were added in C-Kermit 8.0:
-
- lucent: Lucent Venus chipset
- pctel: PCTel V.90 chipset
- conexant: Conexant (ex-Rockwell) modem family
- zoom-v32bis: New name for "Zoom"
- zoom-v34 Zoom V.34
- zoom-v90 Zoom V.90 56K
- zoom-v92: Zoom V.92 with V.44 data compression
- zoltrix-v34: New name for "zoltrix"
- zoltrix-hsp-v90: Synonym for PCTel
- zoltrix-hcf-v90: Synonym for ITU-T-V250
- smartlink-v90: Synonym for usrobotics (same chipset)
- acer-v90: Synonym for Rockwell-v90
-
- New DIAL-related variables:
-
- \v(dm_hf): Dial modifier: Wait for Hook-Flash.
- \v(dm_wb): Dial modifier: Wait for Bong.
-
- Finally, if dialing fails, Kermit now prints a context-sensitive hint
- suggesting possible reasons and remedies.
-
- Added in C-Kermit 8.0.201: Rudimentary support for Caller ID, for
- use with the ANSWER command. If the modem reports Caller ID
- information, Kermit stores it in variables that you can access after
- the call is answered:
-
- \v(callid_date) The date of the call
- \v(callid_time) The time of the call
- \v(callid_name) The name of the caller
- \v(callid_nmbr) The telephone number of the caller
- \v(callid_mesg) A message
-
- The format of these items depends on the originating and answering
- phone companies and the modems and their configuration.
-
- Not very many modems support Caller ID, and those that do (a) tend to
- have it disabled by default, and (b) use different commands to enable
- it. A quick survey shows of some current models shows:
-
- - USR V.90: No
- - ITU-T V.250: No
- - Lucent Venus: No
- - Diamond Supra: #CID=1
- - Rockwell 56K: #CID=1
- - PCTEL: #CID=1
- - Zoltrix: +VCID=1
- - Conexant: +VCID=1
-
- To use Kermit's Caller ID feature, you have to set the modem to wait
- for at least two rings before answering, and you have to give the
- command to enable Caller ID; for example (after choosing a modem with
- SET MODEM TYPE):
-
- set modem command autoanswer on ATS0=2#CID=1\{13}
- set modem command autoanswer on ATS0=2+VCID=1\{13}
-
- These commands can be undone with:
-
- set modem command autoanswer on ATS0=1#CID=0\{13}
- set modem command autoanswer on ATS0=1+VCID=0\{13}
-
- Kermit presently has no built-in knowledge of the Caller ID
- capabilities or commands of the modems in its database.
-
- Since the variables can be accessed only after the call is answered,
- the only way to refuse a call is to answer it, inspect the variables,
- and then hang it up if desired.
-
- [ [548]Top ] [ [549]Contents ] [ [550]C-Kermit Home ] [ [551]Kermit
- Home ]
- __________________________________________________________________________
-
-12. TERMINAL CONNECTION
-
- Now that 7-bit connections are no longer the norm, the default
- terminal bytesize (also called "data size" or "word size") in C-Kermit
- 8.0 is 8 bits, rather than 7 bits as it was in C-Kermit 7.0 and
- earlier:
-
- SET ESCAPE character
- This command, which specifies your CONNECT-mode escape
- character, allows you to specify any ASCII control character in
- a variety of formats. C-Kermit 8.0.201 now also lets you
- specify any 8-bit value, 128-255, as the escape character. In
- the SET ESCAPE command, you can type the 8-bit character
- literally or you can enter its numeric code. Here are examples
- that you can enter from a terminal or console that uses the ISO
- Latin-1 character set:
-
- C-Kermit> set escape Ã
- C-Kermit> set escape 195
- C-Kermit> show escape
- Escape character: Code 195 (Ã): enabled
- C-Kermit>
-
- Both of these commands set the escape character value to 195
- (decimal), which happens to be uppercase letter A with Tilde in
- Latin-1. SHOW ESCAPE and SHOW TERMINAL show the value, as does
- the CONNECT message.
-
- SET TERMINAL AUTODOWNLOAD ERROR { STOP, CONTINUE }
- When Kermit has a terminal connection to another computer, and
- a file transfer is initiated automatically because a Kermit
- packet was received in CONNECT mode (i.e. in the terminal
- screen), this command tells what Kermit should do if the
- transfer fails. The default is to STOP, which leaves Kermit in
- command mode with its file-transfer display showing, so you can
- see that the transfer failed and why. If you SET TERMINAL
- AUTODOWNLOAD ERROR CONTINUE, this causes Kermit to return
- automatically to its terminal screen (i.e. resume its CONNECT
- session) as if the transfer had succeeded; this can be
- desirable if the entire session is under control of a
- host-based script.
-
- SET TERMINAL BYTESIZE { 7, 8 }
- The byte size to use during CONNECT and INPUT command
- execution, which can be more restrictive than the bytesize
- implied by the current PARITY setting, but not less
- restrictive. In C-Kermit 7.0 and earlier, the terminal bytesize
- was 7 by default to protect against the likelihood that parity
- was in use on the connection without the user's knowledge. When
- the terminal bytesize is 8 (as it is in C-Kermit 8.0 and
- later), the user will see garbage in this (increasingly
- unlikely) situation. Note that 8 data bits are required for
- most character sets other than ASCII: Latin-1, UTF-8, and so
- on.
-
- A new command has been added to produce timestamped session logs:
-
- SET TERMINAL SESSION-LOG TIMESTAMPED-TEXT
- Records the terminal session in text mode (like SET TERMINAL
- SESSION-LOG TEXT) but adds a timestamp at the beginning of each
- line. The timestamp format is hh:mm:ss.nnn, and indicates the
- time at which the first character of the line appeared.
-
- In most UNIX versions (those built with the select()-capable CONNECT
- module -- pretty much all the ones that have or could have TELNET
- included), an idle timeout feature has been added:
-
- SET TERMINAL IDLE-TIMEOUT number
- If the number is not 0, then Kermit is to take an action when
- the given amount of time passes with no activity during CONNECT
- mode. If the number is positive it is the maximum number of
- idle seconds; if number is negative it represents milliseconds
- (thousandths of seconds). If 0 is given as the number, there
- are no idle timeouts. Synonym: SET TERMINAL IDLE-LIMIT.
-
- SET TERMINAL IDLE-ACTION { RETURN, HANGUP, EXIT, OUTPUT [ string ] }
- The action to be taken upon an idle timeout in CONNECT mode.
- RETURN to the prompt, HANGUP the connection, EXIT from Kermit,
- or OUTPUT the given string (if no string is given, a NUL (ASCII
- 0) character is sent).
-
- SET TERMINAL IDLE-ACTION { TELNET-NOP, TELNET-AYT }
- Actions that can be selected on Telnet connections only, that
- might be useful if idle limits are enforced by the Telnet
- server or in the TCP/IP protocol: TELNET-NOP sends a "NO
- Operation" (do-nothing) command, which causes no response from
- the server; TELNET-AYT sends an "Are You There" message to the
- server, which should make the server send back a message.
- Neither of these actions interferes with your remote session.
-
- SET TERMINAL IDLE-ACTION is useful for connections to hosts or
- services that automatically log you out after a certain amount of idle
- time, e.g.:
-
- set term idle-timeout 300
- set term idle-action output \32
-
- sends a space (as if you had pressed the space bar) every 300 seconds
- (five minutes) while there is no activity (32 is the ASCII code for
- space).
-
- When C-Kermit returns from CONNECT to command mode, the reason for the
- transition is given in a new variable, \v(cx_status):
-
- 0 No CONNECT command given yet.
- 1 User escaped back manually.
- 2 A trigger string was encountered.
- 3 IKSD entered server mode.
- 4 Application Program Command received from host.
- 5 Idle timeout.
- 6 Telnet protocol error.
- 7 Keystroke macro.
- 8 Time limit exceeded.
- 100 Internal error.
- 101 Carrier required by not detected.
- 102 I/O error on connection.
- 103 Disconnected by host.
- 104 Disconnected by user.
- 105 Session limit exceeded.
- 106 Rejected due to Telnet policy.
- 107 Received kill signal.
-
- Values 100 and above indicate there is no connection.
-
- [ [552]Top ] [ [553]Contents ] [ [554]C-Kermit Home ] [ [555]Kermit
- Home ]
- __________________________________________________________________________
-
-13. CHARACTER SETS
-
- See the section on [556]file scanning above, and the section on
- character-set conversion in [557]FTP. Also:
-
- * True support for CP1252 (rather than treating it as Latin-1).
- * Proper handling of C1 values when converting ISO 8-bit text to
- UTF-8.
- * TYPE /CHARACTER-SET: /TRANSLATE-TO: allows specific translations.
- * The TRANSLATE command now works on multiple files.
- * K_CHARSET environment variable to set the file character-set.
- * SET TRANSFER TRANSLATION OFF.
- * FTP client character-set translation ([558]Section 3.7).
-
- [ [559]Top ] [ [560]Contents ] [ [561]C-Kermit Home ] [ [562]Kermit
- Home ]
- __________________________________________________________________________
-
-14. DIALOUT FROM TELNET TERMINAL SERVERS
-
- For years, C-Kermit has supported dialing out from Telnet modem
- servers (also called reverse terminal servers or access servers), but
- until now there was no way for Kermit to control the communication
- parameters (speed, parity, etc) on the serial port of the terminal
- server; it had to use whatever was there.
-
- But now, if you make a connection to a server that supports the Telnet
- Com Port Control Option, [563]RFC 2217, you have the same degree of
- control as you would have over a serial port on the computer where
- Kermit is running: SET SPEED, SET FLOW, SET PARITY, SET STOP-BITS,
- SHOW COMM, WAIT, SET CARRIER-WATCH, the modem-signal variables,
- sending Break, and so on, apply to the connection between the terminal
- server and the modem.
-
- For example, using a Cisco Access Server 2509, where specifying a TCP
- port in the 6000's selects a serial port that can be used for dialing
- out:
-
- set host xxx 6001 ; xxx is the IP hostname or address of the server
- (log in if necessary) ; With a script or by hand
- set modem type usr ; Tell Kermit what kind of modem it has
- set speed 57600 ; This affects the server's port
- set flow rts/cts ; Ditto
- dial 7654321
-
- The modem server might or might not require a login sequence. It might
- also allow for automatic authentication, e.g. via Kerberos tickets.
- NOTE: If the modem server requires a login sequence, then REDIAL might
- not work as expected.
-
- When you have a Telnet Com Port connection, your SET SPEED and SET
- FLOW options change automatically to reflect the capabilities of the
- server, rather than those of your local computer.
-
- See the configuration manual for your server for additional
- information. For example, how to set up the server to drop the Telnet
- connection automatically when the telephone call is hung up (e.g.
- "autohangup" on Cisco models).
-
- For a Linux-based Telnet Com-Port server, click the Srdird link:
-
- [ [564]Top ] [ [565]Contents ] [ [566]Sredird ] [ [567]C-Kermit Home ]
- [ [568]Kermit Home ]
- __________________________________________________________________________
-
-15. COPING WITH BROKEN KERMIT PARTNERS
-
- There are lots of faulty Kermit protocol implementations out there,
- found mainly in 3rd-party products ranging from communications
- software packages to file-transfer functions imbedded within devices.
- This topic is covered [569]HERE for C-Kermit 7.0, but C-Kermit 8.0
- adds some additional tricks.
-
- SET ATTRIBUTE RECORD-FORMAT { ON, OFF }
- Allows control of the Kermit's Record-Format attribute. Set
- this to OFF in case incoming file are refused due to unknown or
- invalid record formats if you want to accept the file anyway.
-
- SET SEND I-PACKETS { ON, OFF }
- A Kermit server is supposed to accept I-packets; this is how
- the client lets the server know its capabilities and
- preferences before sending a command. Apparently there is at
- least one Kermit server implementation that does not accept
- I-packets, and does not properly respond with an Error packet
- if it gets one. To get around such situations in C-Kermit 8.0,
- you can use SET SEND I-PACKETS OFF to inhibit the sending of I
- packets. In this case, the client must be able to adjust to the
- server's configuration, rather than the other way around as we
- are used to.
-
- SET PROTOCOL KERMIT {} {} {}
- C-Kermit 6.0 and later automatically send "autoupload" and
- "autodownload" commands when in local mode and you give a file
- transfer command. For example, if you tell kermit to "send
- oofa.txt", Kermit sends "kermit -r" and a carriage return, in
- case you had forgotten to start Kermit on the far end and told
- it to receive a file. If a Kermit program had already been
- started on the far end, it should harmlessly absorb this
- string. However, some Kermit programs violate the Kermit
- protocol definition and treat such strings as Kermit packets
- even though they are not. In such cases, give this command to
- set the Kermit protocol autoupload and download strings to
- nothing, which tells Kermit not to send them. (This is not a
- new feature, but it was not previously included in the "Coping"
- section of the documentation.)
-
- [ [570]Top ] [ [571]Contents ] [ [572]C-Kermit Home ] [ [573]Kermit
- Home ]
- __________________________________________________________________________
-
-16. NEW COMMAND-LINE OPTIONS
-
- kermit -h Now prints a complete listing of its command-line options,
- rather than an abbreviated list squeezed into a 24x80 space.
-
- -dd Debug, like -d but adds timestamps
- --version Shows C-Kermit version number.
- --noperms Equivalent to SET ATTRIBUTE PROTECTION OFF.
-
- Kermit now accepts a selection of URLs (Universal Resource Locators)
- as its first command-line argument. These are:
-
- telnet:hostname
- Makes a Telnet connection to the given host (IP hostname or
- address).
-
- ftp://[user[:password]@]hostname[/path...]
- Makes an FTP connection to the given host (IP hostname or
- address). If a username is given, Kermit tries to log you in;
- if a password is given, it is used; if not, you are prompted
- for one. If no username is given, an anonymous login is
- performed. If a pathname is included, Kermit tries to GET the
- given file. See [574]Section 3.1.3 for details.
-
- ftps://[user[:password]@]hostname[/path...]
- Makes a secure FTP connection over SSL.
-
- telnets://[user[:password]@]hostname
- Makes a secure Telnet connection over SSL.
-
- kermit://[user[:password]@]hostname[/path...]
- Makes a connection to an [575]Internet Kermit Server.
-
- http://[user[:password]@]hostname[/path...]
- Makes a connection to Web server.
-
- https://[user[:password]@]hostname[/path...]
- Makes a connection to secure Web server.
-
- [ [576]Top ] [ [577]Contents ] [ [578]C-Kermit Home ] [ [579]Kermit
- Home ]
- __________________________________________________________________________
-
-17. LOGS
-
- In C-Kermit 8.0, we make an effort to keep passwords out of the debug
- log. This can never be 100% effective, but it's better than before,
- when there were no precautions at all. Whenever Kermit knows it's
- prompting for, parsing, or transmitting a password, it temporarily
- turns off logging and then turns it back on afterwards. This keeps the
- debug log password-free in most common cases, but there can be no
- guarantees.
-
- As noted elsewhere, the new "-dd" command-line option selects a
- timestamped debug log (equivalent to "set debug timestamps on", "log
- debug debug.log").
-
- C-Kermit 8.0 also supports a new timestamped session log via "set
- session-log timestamped-text", "log session".
-
- There have been requests for other kinds of logs, for example a
- command log. These might be added at some point. One person wanted to
- be able to log commands with timestamps, but only commands issued at
- the prompt, not commands from files or macros, and also wanted a
- header line at the beginning showing the date, user, and host. This
- can be done as follows:
-
- .filename := \v(home)commands.log ; (for example)
- fopen /write \%c \m(filename)
- if success {
- fwrite /line \%c \v(date): User=\v(user) Host=\v(host)
- fclose \%c
- set debug timestamps on
- log debug {| grep "CMD(P)" >> \m(filename)} append
- }
-
- [ [580]Top ] [ [581]Contents ] [ [582]C-Kermit Home ] [ [583]Kermit
- Home ]
- _________________________________________________________________
-
- C-Kermit 8.0 Update Notes / [584]The Kermit Project / Columbia
- University / 15 Dec 2003
-
-References
-
- 1. http://www.columbia.edu/kermit/ckermit80.html#contents
- 2. http://www.columbia.edu/kermit/ckermit.html
- 3. http://www.columbia.edu/kermit/index.html
- 4. http://www.columbia.edu/kermit/ckermit80.html
- 5. mailto:kermit-support@columbia.edu
- 6. http://www.columbia.edu/kermit/
- 7. http://www.kermit-project.org/
- 8. http://www.columbia.nyc.ny.us/kermit/
- 9. ftp://kermit.columbia.edu/kermit/f/COPYING.TXT
- 10. ftp://kermit.columbia.edu/kermit/f/ckcmai.c
- 11. http://www.columbia.edu/kermit/ckermit80.html#xv
- 12. http://www.columbia.edu/kermit/ck60manual.html
- 13. http://www.columbia.edu/kermit/ckermi70.html
- 14. ftp://kermit.columbia.edu/kermit/f/ckermit70.txt
- 15. http://www.columbia.edu/kermit/ckututor.html
- 16. ftp://kermit.columbia.edu/kermit/f/ckuker.nr
- 17. http://www.columbia.edu/kermit/security.htm
- 18. http://www.columbia.edu/kermit/telnet.htm
- 19. http://www.columbia.edu/kermit/ftpscripts.html
- 20. http://www.columbia.edu/kermit/ckcbwr.html
- 21. ftp://kermit.columbia.edu/kermit/f/ckcbwr.txt
- 22. http://www.columbia.edu/kermit/ckubwr.html
- 23. ftp://kermit.columbia.edu/kermit/f/ckubwr.txt
- 24. http://www.columbia.edu/kermit/ckvbwr.html
- 25. ftp://kermit.columbia.edu/kermit/f/ckvbwr.txt
- 26. http://www.columbia.edu/kermit/ckuins.html
- 27. ftp://kermit.columbia.edu/kermit/f/ckuins.txt
- 28. http://www.columbia.edu/kermit/ckvins.html
- 29. ftp://kermit.columbia.edu/kermit/f/ckvins.txt
- 30. http://www.columbia.edu/kermit/ckccfg.html
- 31. ftp://kermit.columbia.edu/kermit/f/ckccfg.txt
- 32. http://www.columbia.edu/kermit/ckcplm.html
- 33. ftp://kermit.columbia.edu/kermit/f/ckcplm.txt
- 34. http://www.columbia.edu/kermit/iksd.html
- 35. http://www.columbia.edu/kermit/skermit.html
- 36. http://www.columbia.edu/kermit/ckermit80.html#top
- 37. http://www.columbia.edu/kermit/ckermit.html
- 38. http://www.columbia.edu/kermit/index.html
- 39. http://www.columbia.edu/kermit/ckermit80.html#x0
- 40. http://www.columbia.edu/kermit/ckermit80.html#x1
- 41. http://www.columbia.edu/kermit/ckermit80.html#x2
- 42. http://www.columbia.edu/kermit/ckermit80.html#x2.1
- 43. http://www.columbia.edu/kermit/ckermit80.html#x2.2
- 44. http://www.columbia.edu/kermit/ckermit80.html#x2.2.1
- 45. http://www.columbia.edu/kermit/ckermit80.html#x2.2.2
- 46. http://www.columbia.edu/kermit/ckermit80.html#x2.2.3
- 47. http://www.columbia.edu/kermit/ckermit80.html#x2.2.4
- 48. http://www.columbia.edu/kermit/ckermit80.html#x2.2.5
- 49. http://www.columbia.edu/kermit/ckermit80.html#x2.2.6
- 50. http://www.columbia.edu/kermit/ckermit80.html#x3
- 51. http://www.columbia.edu/kermit/ckermit80.html#x3.1
- 52. http://www.columbia.edu/kermit/ckermit80.html#x3.1.1
- 53. http://www.columbia.edu/kermit/ckermit80.html#x3.1.2
- 54. http://www.columbia.edu/kermit/ckermit80.html#x3.1.3
- 55. http://www.columbia.edu/kermit/ckermit80.html#x3.1.4
- 56. http://www.columbia.edu/kermit/ckermit80.html#x3.2
- 57. http://www.columbia.edu/kermit/ckermit80.html#x3.3
- 58. http://www.columbia.edu/kermit/ckermit80.html#x3.4
- 59. http://www.columbia.edu/kermit/ckermit80.html#x3.5
- 60. http://www.columbia.edu/kermit/ckermit80.html#x3.5.1
- 61. http://www.columbia.edu/kermit/ckermit80.html#x3.5.2
- 62. http://www.columbia.edu/kermit/ckermit80.html#x3.5.3
- 63. http://www.columbia.edu/kermit/ckermit80.html#x3.6
- 64. http://www.columbia.edu/kermit/ckermit80.html#x3.6.1
- 65. http://www.columbia.edu/kermit/ckermit80.html#x3.6.2
- 66. http://www.columbia.edu/kermit/ckermit80.html#x3.6.3
- 67. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 68. http://www.columbia.edu/kermit/ckermit80.html#x3.7.1
- 69. http://www.columbia.edu/kermit/ckermit80.html#x3.7.2
- 70. http://www.columbia.edu/kermit/ckermit80.html#x3.8
- 71. http://www.columbia.edu/kermit/ckermit80.html#x3.9
- 72. http://www.columbia.edu/kermit/ckermit80.html#x3.10
- 73. http://www.columbia.edu/kermit/ckermit80.html#x3.10.1
- 74. http://www.columbia.edu/kermit/ckermit80.html#x3.10.2
- 75. http://www.columbia.edu/kermit/ckermit80.html#x3.10.3
- 76. http://www.columbia.edu/kermit/ckermit80.html#x3.11
- 77. http://www.columbia.edu/kermit/ckermit80.html#x4
- 78. http://www.columbia.edu/kermit/ckermit80.html#x5
- 79. http://www.columbia.edu/kermit/ckermit80.html#x6
- 80. http://www.columbia.edu/kermit/ckermit80.html#x6.1
- 81. http://www.columbia.edu/kermit/ckermit80.html#x6.2
- 82. http://www.columbia.edu/kermit/ckermit80.html#x6.3
- 83. http://www.columbia.edu/kermit/ckermit80.html#x6.4
- 84. http://www.columbia.edu/kermit/ckermit80.html#x6.5
- 85. http://www.columbia.edu/kermit/ckermit80.html#x6.6
- 86. http://www.columbia.edu/kermit/ckermit80.html#x7
- 87. http://www.columbia.edu/kermit/ckermit80.html#x8
- 88. http://www.columbia.edu/kermit/ckermit80.html#x8.1
- 89. http://www.columbia.edu/kermit/ckermit80.html#x8.2
- 90. http://www.columbia.edu/kermit/ckermit80.html#x8.3
- 91. http://www.columbia.edu/kermit/ckermit80.html#x8.4
- 92. http://www.columbia.edu/kermit/ckermit80.html#x8.5
- 93. http://www.columbia.edu/kermit/ckermit80.html#x8.6
- 94. http://www.columbia.edu/kermit/ckermit80.html#x8.7
- 95. http://www.columbia.edu/kermit/ckermit80.html#x8.8
- 96. http://www.columbia.edu/kermit/ckermit80.html#x8.9
- 97. http://www.columbia.edu/kermit/ckermit80.html#x8.10
- 98. http://www.columbia.edu/kermit/ckermit80.html#x8.11
- 99. http://www.columbia.edu/kermit/ckermit80.html#x8.12
- 100. http://www.columbia.edu/kermit/ckermit80.html#x8.13
- 101. http://www.columbia.edu/kermit/ckermit80.html#x8.14
- 102. http://www.columbia.edu/kermit/ckermit80.html#x9
- 103. http://www.columbia.edu/kermit/ckermit80.html#x9.1
- 104. http://www.columbia.edu/kermit/ckermit80.html#x9.2
- 105. http://www.columbia.edu/kermit/ckermit80.html#x9.3
- 106. http://www.columbia.edu/kermit/ckermit80.html#x9.4
- 107. http://www.columbia.edu/kermit/ckermit80.html#x9.5
- 108. http://www.columbia.edu/kermit/ckermit80.html#x9.6
- 109. http://www.columbia.edu/kermit/ckermit80.html#x9.7
- 110. http://www.columbia.edu/kermit/ckermit80.html#x9.8
- 111. http://www.columbia.edu/kermit/ckermit80.html#x9.9
- 112. http://www.columbia.edu/kermit/ckermit80.html#x9.10
- 113. http://www.columbia.edu/kermit/ckermit80.html#x9.11
- 114. http://www.columbia.edu/kermit/ckermit80.html#x10
- 115. http://www.columbia.edu/kermit/ckermit80.html#x11
- 116. http://www.columbia.edu/kermit/ckermit80.html#x12
- 117. http://www.columbia.edu/kermit/ckermit80.html#x13
- 118. http://www.columbia.edu/kermit/ckermit80.html#x14
- 119. http://www.columbia.edu/kermit/ckermit80.html#x15
- 120. http://www.columbia.edu/kermit/ckermit80.html#x16
- 121. http://www.columbia.edu/kermit/ckermit80.html#x17
- 122. http://www.columbia.edu/kermit/ckermit80.html#top
- 123. http://www.columbia.edu/kermit/ckermit.html
- 124. http://www.columbia.edu/kermit/index.html
- 125. http://www.columbia.edu/kermit/ckuins.html#x5
- 126. http://www.columbia.edu/kermit/ckuins.html
- 127. http://www.columbia.edu/kermit/ckermit80.html#x5
- 128. http://www.columbia.edu/kermit/ckermit80.html#x2.2
- 129. http://www.columbia.edu/kermit/ckermit80.html#contents
- 130. http://www.columbia.edu/kermit/ckermit80.html#x15
- 131. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 132. http://www.columbia.edu/kermit/ckermit80.html#ftpdates
- 133. http://www.columbia.edu/kermit/ckermit80.html#ftpcheck
- 134. http://www.columbia.edu/kermit/ckermit80.html#ftpnamelist
- 135. http://www.columbia.edu/kermit/ckermit80.html#srvrename
- 136. http://www.columbia.edu/kermit/ckermit80.html#ftpvdir
- 137. http://www.columbia.edu/kermit/ckermit80.html#setftptype
- 138. http://www.columbia.edu/kermit/ckermit80.html#x3.6
- 139. http://www.columbia.edu/kermit/ckermit80.html#x15
- 140. http://www.columbia.edu/kermit/ckermit80.html#x8.7
- 141. http://www.columbia.edu/kermit/ckermit80.html#x2.1
- 142. http://www.columbia.edu/kermit/ckermit80.html#x2.2
- 143. http://www.columbia.edu/kermit/ckermit80.html#x8.14
- 144. http://www.columbia.edu/kermit/ckermit80.html#x8.13
- 145. http://www.columbia.edu/kermit/ckermit80.html#x8.13
- 146. http://www.columbia.edu/kermit/ckututor.html
- 147. http://www.columbia.edu/kermit/ckuins.html
- 148. http://www.columbia.edu/kermit/skermit.html
- 149. http://www.columbia.edu/kermit/ckermit80.html#setlocus
- 150. http://www.columbia.edu/kermit/ckermit80.html#lcommands
- 151. http://www.columbia.edu/kermit/ckermit80.html#ftpuser
- 152. http://www.columbia.edu/kermit/ckermit80.html#showvar
- 153. http://www.columbia.edu/kermit/ckermit80.html#callerid
- 154. http://www.columbia.edu/kermit/ckermit80.html#x6.6
- 155. http://www.columbia.edu/kermit/ckermit80.html#x0
- 156. http://www.columbia.edu/kermit/ckermit80.html#x3.11
- 157. http://www.columbia.edu/kermit/ckermit80.html#top
- 158. http://www.columbia.edu/kermit/ckermit80.html#contents
- 159. http://www.columbia.edu/kermit/ckermit.html
- 160. http://www.columbia.edu/kermit/index.html
- 161. http://www.columbia.edu/kermit/ckermit80.html#x0
- 162. http://www.columbia.edu/kermit/ckermit80.html#top
- 163. http://www.columbia.edu/kermit/ckermit80.html#contents
- 164. http://www.columbia.edu/kermit/ckermit.html
- 165. http://www.columbia.edu/kermit/index.html
- 166. http://www.columbia.edu/kermit/k95.html
- 167. http://www.columbia.edu/kermit/sshclient.html
- 168. http://www.columbia.edu/kermit/skermit.html
- 169. http://www.columbia.edu/kermit/skermit.html
- 170. http://www.columbia.edu/kermit/sshclien.htm
- 171. http://www.columbia.edu/kermit/ckermit80.html#x3
- 172. ftp://ftp.isi.edu/in-notes/rfc1738.txt
- 173. http://www.columbia.edu/kermit/ckermit80.html#x2.2.2
- 174. http://www.columbia.edu/kermit/ckermit80.html#x2.2.1
- 175. ftp://ftp.isi.edu/in-notes/rfc2396.txt
- 176. ftp://ftp.isi.edu/in-notes/rfc2616.txt
- 177. http://www.columbia.edu/kermit/ckermit80.html#x2.2.3
- 178. ftp://ftp.isi.edu/in-notes/rfc2616.txt
- 179. http://www.columbia.edu/kermit/ckermit80.html#x8.13.7
- 180. http://www.columbia.edu/kermit/security.htm#x5.4
- 181. http://www.columbia.edu/kermit/security.htm#x15
- 182. http://www.columbia.edu/kermit/security.htm#x6.2
- 183. http://www.columbia.edu/kermit/security.html
- 184. http://www.columbia.edu/kermit/ckermit80.html#x16
- 185. http://www.columbia.edu/kermit/ckermit80.html#top
- 186. http://www.columbia.edu/kermit/ckermit80.html#contents
- 187. http://www.columbia.edu/kermit/ckermit.html
- 188. http://www.columbia.edu/kermit/index.html
- 189. http://www.columbia.edu/kermit/ckermit80.html#x3.1
- 190. http://www.columbia.edu/kermit/ckermit80.html#x3.2
- 191. http://www.columbia.edu/kermit/ckermit80.html#x3.3
- 192. http://www.columbia.edu/kermit/ckermit80.html#x3.4
- 193. http://www.columbia.edu/kermit/ckermit80.html#x3.5
- 194. http://www.columbia.edu/kermit/ckermit80.html#x3.6
- 195. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 196. http://www.columbia.edu/kermit/ckermit80.html#x3.8
- 197. http://www.columbia.edu/kermit/ckermit80.html#x3.9
- 198. http://www.columbia.edu/kermit/ckermit80.html#x3.10
- 199. http://www.columbia.edu/kermit/ckermit80.html#x3.11
- 200. http://www.columbia.edu/kermit/security.htm
- 201. http://www.columbia.edu/kermit/security.htm#servers
- 202. http://www.columbia.edu/kermit/ckcsets.html
- 203. http://www.columbia.edu/kermit/unicode.html
- 204. http://www.columbia.edu/kermit/ckermi70.htm#x1.5.4
- 205. http://www.columbia.edu/kermit/case10.html
- 206. http://www.columbia.edu/kermit/ckermit80.html#x4
- 207. http://www.columbia.edu/kermit/ckermit80.html#x3.11
- 208. http://www.columbia.edu/kermit/ftpscripts.html
- 209. http://www.columbia.edu/kermit/ckermit80.html#top
- 210. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 211. http://www.columbia.edu/kermit/ftpclient.html
- 212. http://www.columbia.edu/kermit/ftpscripts.html
- 213. http://www.columbia.edu/kermit/ckermit.html
- 214. http://www.columbia.edu/kermit/index.html
- 215. http://www.columbia.edu/kermit/ckermit80.html#x3.1.1
- 216. http://www.columbia.edu/kermit/ckermit80.html#x3.1.3
- 217. http://www.columbia.edu/kermit/ckermit80.html#x3.1.4
- 218. http://www.columbia.edu/kermit/ckermit80.html#x3.1.3
- 219. http://www.columbia.edu/kermit/ckermit80.html#x3.1.3
- 220. http://www.columbia.edu/kermit/ckermit80.html#x3.2
- 221. http://www.columbia.edu/kermit/ckermit80.html#x3.5
- 222. http://www.columbia.edu/kermit/ckermit80.html#x3.6
- 223. http://www.columbia.edu/kermit/ftpscripts.html
- 224. http://www.columbia.edu/kermit/ckb2.htm
- 225. http://www.columbia.edu/kermit/ckermit80.html#ftpautolog
- 226. http://www.columbia.edu/kermit/ckermit80.html#ftpuser
- 227. http://www.columbia.edu/kermit/ckermit80.html#x3.8
- 228. http://www.columbia.edu/kermit/ckermit80.html#x3.8
- 229. http://www.columbia.edu/kermit/ckermit80.html#top
- 230. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 231. http://www.columbia.edu/kermit/ckermit.html
- 232. http://www.columbia.edu/kermit/index.html
- 233. http://www.columbia.edu/kermit/ibm_ie.html
- 234. http://www.columbia.edu/kermit/ckermit80.html#x3.10
- 235. http://www.columbia.edu/kermit/ckermit80.html#top
- 236. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 237. http://www.columbia.edu/kermit/ckermit.html
- 238. http://www.columbia.edu/kermit/index.html
- 239. http://www.columbia.edu/kermit/ck60manual.html
- 240. http://www.columbia.edu/kermit/ckermit70.html#x4.17
- 241. http://www.columbia.edu/kermit/ckermit70.html
- 242. http://www.columbia.edu/kermit/ckermit80.html#x3.6
- 243. http://www.columbia.edu/kermit/ckermit80.html#x3.11
- 244. http://www.columbia.edu/kermit/ckermit80.html#x3.1.4
- 245. http://www.columbia.edu/kermit/security.html
- 246. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 247. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 248. http://www.columbia.edu/kermit/ckermit80.html#x8.13.4
- 249. http://www.columbia.edu/kermit/ckermit80.html#permswitch
- 250. http://www.columbia.edu/kermit/ckermit80.html#ftpchmod
- 251. http://www.columbia.edu/kermit/ckermit80.html#x3.6.2
- 252. http://www.columbia.edu/kermit/ckermit80.html#x4
- 253. http://www.columbia.edu/kermit/ckermit80.html#top
- 254. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 255. http://www.columbia.edu/kermit/ckermit.html
- 256. http://www.columbia.edu/kermit/index.html
- 257. http://www.columbia.edu/kermit/ckermit80.html#x7
- 258. http://www.columbia.edu/kermit/ckermit80.html#x3.8
- 259. http://www.columbia.edu/kermit/ckermit80.html#x3.8
- 260. http://www.columbia.edu/kermit/ckb2.htm
- 261. http://www.columbia.edu/kermit/ckermit80.html#x3.10
- 262. http://www.columbia.edu/kermit/ckermit80.html#x3.10
- 263. http://www.columbia.edu/kermit/ckermit80.html#x3.6
- 264. http://www.columbia.edu/kermit/ckermit80.html#setftptype
- 265. http://www.columbia.edu/kermit/ckermit80.html#top
- 266. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 267. http://www.columbia.edu/kermit/ckermit.html
- 268. http://www.columbia.edu/kermit/index.html
- 269. http://www.columbia.edu/kermit/ckermit70.html#x4.9
- 270. http://www.columbia.edu/kermit/ckermit80.html#x3.5.1
- 271. http://www.columbia.edu/kermit/ckermit80.html#erroraction
- 272. http://www.columbia.edu/kermit/ckermit70.html#x1.5
- 273. http://www.columbia.edu/kermit/ckermit70.html#x4.7
- 274. http://www.columbia.edu/kermit/ckermit70.html#x1.6
- 275. http://www.columbia.edu/kermit/ckermit80.html#x8.13
- 276. http://www.columbia.edu/kermit/ckermi70.htm#x1.5.4
- 277. http://www.columbia.edu/kermit/ckermi70.htm
- 278. http://www.columbia.edu/kermit/ckermit80.html#x4
- 279. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 280. http://www.columbia.edu/kermit/ckermit80.html#x3.5.2
- 281. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 282. http://www.columbia.edu/kermit/ckermit80.html#erroraction
- 283. http://www.columbia.edu/kermit/ckermit80.html#x3.5.2
- 284. http://www.columbia.edu/kermit/ckermit80.html#erroraction
- 285. http://www.columbia.edu/kermit/ckermit80.html#ftpfilenames
- 286. http://www.columbia.edu/kermit/ckermit80.html#ftpperms
- 287. http://www.columbia.edu/kermit/ckermit80.html#ftpunique
- 288. http://www.columbia.edu/kermit/ckermit80.html#ftpfilenames
- 289. http://www.columbia.edu/kermit/ckermit80.html#note_utc
- 290. http://www.columbia.edu/kermit/ckermit80.html#note_date
- 291. http://www.columbia.edu/kermit/ckermit80.html#x3.6
- 292. http://www.boulder.nist.gov/timefreq/faq/faq.htm#10:
- 293. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 294. http://www.columbia.edu/kermit/ckermit80.html#top
- 295. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 296. http://www.columbia.edu/kermit/ckermit.html
- 297. http://www.columbia.edu/kermit/index.html
- 298. http://www.columbia.edu/kermit/ckermit80.html#x3.11
- 299. http://www.columbia.edu/kermit/ckermi70.htm#x4.3
- 300. http://www.columbia.edu/kermit/ckermit70.html
- 301. http://www.columbia.edu/kermit/ckermit80.html#x5
- 302. http://www.columbia.edu/kermit/ckermit80.html#x3.6.3
- 303. http://www.columbia.edu/kermit/ckermit80.html#ftpfilenames
- 304. http://www.columbia.edu/kermit/ckermi70.htm#x4.1
- 305. http://www.columbia.edu/kermit/ckermi70.htm#x4.2.2
- 306. http://www.columbia.edu/kermit/ckermi70.htm#x1.5.4
- 307. http://www.columbia.edu/kermit/ckermit80.html#x3.6.2
- 308. http://www.columbia.edu/kermit/ckermit80.html#x3.11
- 309. http://www.columbia.edu/kermit/ckermit80.html#x3.11
- 310. http://www.columbia.edu/kermit/ckermit80.html#srvrename
- 311. http://www.columbia.edu/kermit/ckermi70.htm#x4.1
- 312. http://www.columbia.edu/kermit/ckermi70.htm
- 313. http://www.columbia.edu/kermit/ckb2.htm
- 314. http://www.columbia.edu/kermit/ckermit80.html#ftpfilenames
- 315. http://www.columbia.edu/kermit/ckermit80.html#x3.5.3
- 316. http://www.proftpd.net/
- 317. http://www.columbia.edu/kermit/ckermit80.html#top
- 318. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 319. http://www.columbia.edu/kermit/ckermit.html
- 320. http://www.columbia.edu/kermit/index.html
- 321. http://www.columbia.edu/kermit/ckb2.htm
- 322. http://www.columbia.edu/kermit/ckcsets.html
- 323. http://www.columbia.edu/kermit/unicode.html
- 324. http://www.columbia.edu/kermit/ckcsets.html
- 325. http://www.columbia.edu/kermit/ckcsets.html
- 326. http://www.columbia.edu/kermit/ckermit80.html#x4
- 327. http://www.columbia.edu/kermit/utf8.html
- 328. http://www.columbia.edu/kermit/ckcsets.html
- 329. http://www.columbia.edu/kermit/ckermit80.html#x4
- 330. ftp://ftp.isi.edu/in-notes/rfc2640.txt
- 331. http://www.columbia.edu/kermit/ckermit80.html#top
- 332. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 333. http://www.columbia.edu/kermit/ckermit.html
- 334. http://www.columbia.edu/kermit/index.html
- 335. http://www.columbia.edu/kermit/ckermit80.html#top
- 336. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 337. http://www.columbia.edu/kermit/ckermit.html
- 338. http://www.columbia.edu/kermit/index.html
- 339. http://www.columbia.edu/kermit/ckermit80.html#top
- 340. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 341. http://www.columbia.edu/kermit/ckermit.html
- 342. http://www.columbia.edu/kermit/index.html
- 343. http://www.columbia.edu/kermit/ftpscripts.html
- 344. http://www.columbia.edu/kermit/ckermit80.html#x3.2
- 345. http://www.columbia.edu/kermit/ckermit80.html#x3.2
- 346. ftp://ftp.isi.edu/in-notes/rfc959.txt
- 347. http://www.columbia.edu/kermit/ckscripts.html
- 348. http://www.columbia.edu/kermit/ckermit80.html#top
- 349. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 350. http://www.columbia.edu/kermit/ftpscript.html
- 351. http://www.columbia.edu/kermit/ckermit.html
- 352. http://www.columbia.edu/kermit/index.html
- 353. http://www.columbia.edu/kermit/ckermit80.html#x3.11.1
- 354. http://www.columbia.edu/kermit/ckermit80.html#x3.11.2
- 355. http://www.columbia.edu/kermit/ckermit80.html#x3.11.3
- 356. http://www.columbia.edu/kermit/ckermit80.html#x3.11.4
- 357. http://www.columbia.edu/kermit/ckermit80.html#x3.11.5
- 358. http://www.columbia.edu/kermit/ckermit.html
- 359. http://www.columbia.edu/kermit/k95.html
- 360. http://www.columbia.edu/kermit/ckermit80.html#x3.11.5
- 361. ftp://ftp.isi.edu/in-notes/rfc959.txt
- 362. ftp://ftp.isi.edu/in-notes/rfc2389.txt
- 363. http://www.ietf.org/internet-drafts/draft-ietf-ftpext-mlst-16.txt
- 364. http://www.columbia.edu/kermit/ftpclient.html
- 365. http://www.columbia.edu/kermit/ckermit80.html#top
- 366. http://www.columbia.edu/kermit/ckermit80.html#ftp
- 367. http://www.columbia.edu/kermit/ckermit.html
- 368. http://www.columbia.edu/kermit/index.html
- 369. http://www.columbia.edu/kermit/ckermit80.html#x3
- 370. http://www.columbia.edu/kermit/ckermit80.html#ucs2
- 371. http://www.columbia.edu/kermit/ckermit80.html#top
- 372. http://www.columbia.edu/kermit/ckermit80.html#contents
- 373. http://www.columbia.edu/kermit/ckermit.html
- 374. http://www.columbia.edu/kermit/index.html
- 375. http://www.columbia.edu/kermit/ckermit80.html#top
- 376. http://www.columbia.edu/kermit/ckermit80.html#contents
- 377. http://www.columbia.edu/kermit/ckermit.html
- 378. http://www.columbia.edu/kermit/index.html
- 379. http://www.columbia.edu/kermit/ckb2.htm
- 380. http://www.columbia.edu/kermit/ckermit80.html#top
- 381. http://www.columbia.edu/kermit/ckermit80.html#contents
- 382. http://www.columbia.edu/kermit/ckermit.html
- 383. http://www.columbia.edu/kermit/index.html
- 384. http://www.columbia.edu/kermit/ckermit80.html#x4
- 385. http://www.columbia.edu/kermit/ckermit80.html#x4
- 386. http://www.columbia.edu/kermit/ckermit80.html#x8.12
- 387. http://www.columbia.edu/kermit/ckermit80.html#x8.1
- 388. http://www.columbia.edu/kermit/ckermit80.html#x12
- 389. http://www.columbia.edu/kermit/ckermit80.html#x8.12
- 390. http://www.columbia.edu/kermit/ckermit80.html#top
- 391. http://www.columbia.edu/kermit/ckermit80.html#contents
- 392. http://www.columbia.edu/kermit/ckermit.html
- 393. http://www.columbia.edu/kermit/index.html
- 394. http://www.columbia.edu/kermit/ckermit80.html#x8.14
- 395. http://www.columbia.edu/kermit/ckermit80.html#top
- 396. http://www.columbia.edu/kermit/ckermit80.html#contents
- 397. http://www.columbia.edu/kermit/ckermit.html
- 398. http://www.columbia.edu/kermit/index.html
- 399. http://www.columbia.edu/kermit/ckermit80.html#x9
- 400. http://www.columbia.edu/kermit/ckermit80.html#top
- 401. http://www.columbia.edu/kermit/ckermit80.html#contents
- 402. http://www.columbia.edu/kermit/ckermit.html
- 403. http://www.columbia.edu/kermit/index.html
- 404. http://www.columbia.edu/kermit/ckermit80.html#x8.6
- 405. http://www.columbia.edu/kermit/ckermit80.html#top
- 406. http://www.columbia.edu/kermit/ckermit80.html#contents
- 407. http://www.columbia.edu/kermit/ckermit.html
- 408. http://www.columbia.edu/kermit/index.html
- 409. http://www.columbia.edu/kermit/ckermit80.html#top
- 410. http://www.columbia.edu/kermit/ckermit80.html#contents
- 411. http://www.columbia.edu/kermit/ckermit.html
- 412. http://www.columbia.edu/kermit/index.html
- 413. http://www.columbia.edu/kermit/ckermit80.html#top
- 414. http://www.columbia.edu/kermit/ckermit80.html#contents
- 415. http://www.columbia.edu/kermit/ckermit.html
- 416. http://www.columbia.edu/kermit/index.html
- 417. http://www.columbia.edu/kermit/ckermit80.html#fjoin
- 418. http://www.columbia.edu/kermit/ckermit80.html#fsplit
- 419. http://www.columbia.edu/kermit/ckermit80.html#x8.10
- 420. http://www.columbia.edu/kermit/ckermit80.html#top
- 421. http://www.columbia.edu/kermit/ckermit80.html#contents
- 422. http://www.columbia.edu/kermit/ckermit.html
- 423. http://www.columbia.edu/kermit/index.html
- 424. http://www.columbia.edu/kermit/ckermit80.html#x9
- 425. http://www.columbia.edu/kermit/ckermit80.html#x9
- 426. http://www.columbia.edu/kermit/ckermit80.html#x9
- 427. http://www.columbia.edu/kermit/ckermit80.html#x3
- 428. http://www.columbia.edu/kermit/ckermit80.html#x3
- 429. http://www.columbia.edu/kermit/ckermit80.html#x3.2
- 430. http://www.columbia.edu/kermit/ckermit80.html#x3.2
- 431. http://www.columbia.edu/kermit/ckermit80.html#x3.8
- 432. http://www.columbia.edu/kermit/ckermit80.html#x3
- 433. http://www.columbia.edu/kermit/ckermit80.html#x3
- 434. http://www.columbia.edu/kermit/ckermit80.html#x3
- 435. http://www.columbia.edu/kermit/ckermit80.html#x3.2
- 436. http://www.columbia.edu/kermit/ckermit80.html#x3
- 437. http://www.columbia.edu/kermit/ckermit80.html#x8.13
- 438. http://www.columbia.edu/kermit/ckermit80.html#x8.13
- 439. http://www.columbia.edu/kermit/ckermit80.html#x9
- 440. http://www.columbia.edu/kermit/ckermit80.html#x8.10
- 441. http://www.columbia.edu/kermit/ckermit80.html#x8.7.4
- 442. http://www.columbia.edu/kermit/ckermit80.html#top
- 443. http://www.columbia.edu/kermit/ckermit80.html#contents
- 444. http://www.columbia.edu/kermit/ckermit.html
- 445. http://www.columbia.edu/kermit/index.html
- 446. http://www.columbia.edu/kermit/ckermit80.html#top
- 447. http://www.columbia.edu/kermit/ckermit80.html#contents
- 448. http://www.columbia.edu/kermit/ckermit.html
- 449. http://www.columbia.edu/kermit/index.html
- 450. http://www.columbia.edu/kermit/ckermit80.html#top
- 451. http://www.columbia.edu/kermit/ckermit80.html#contents
- 452. http://www.columbia.edu/kermit/ckermit.html
- 453. http://www.columbia.edu/kermit/index.html
- 454. http://www.columbia.edu/kermit/ckermit80.html#x8.7
- 455. http://www.columbia.edu/kermit/ckermit80.html#top
- 456. http://www.columbia.edu/kermit/ckermit80.html#contents
- 457. http://www.columbia.edu/kermit/ckermit.html
- 458. http://www.columbia.edu/kermit/index.html
- 459. http://www.columbia.edu/kermit/ckermit80.html#scriptedit
- 460. http://www.columbia.edu/kermit/ckermit80.html#top
- 461. http://www.columbia.edu/kermit/ckermit80.html#contents
- 462. http://www.columbia.edu/kermit/ckermit.html
- 463. http://www.columbia.edu/kermit/index.html
- 464. http://www.columbia.edu/kermit/ckermit80.html#top
- 465. http://www.columbia.edu/kermit/ckermit80.html#contents
- 466. http://www.columbia.edu/kermit/ckermit.html
- 467. http://www.columbia.edu/kermit/index.html
- 468. ftp://ftp.isi.edu/in-notes/rfc2822.txt
- 469. ftp://ftp.isi.edu/in-notes/rfc2822.txt
- 470. ftp://ftp.isi.edu/in-notes/rfc2822.txt
- 471. ftp://ftp.isi.edu/in-notes/rfc2822.txt
- 472. http://www.columbia.edu/kermit/ckermit80.html#top
- 473. http://www.columbia.edu/kermit/ckermit80.html#contents
- 474. http://www.columbia.edu/kermit/ckermit.html
- 475. http://www.columbia.edu/kermit/index.html
- 476. http://www.columbia.edu/kermit/ckermit80.html#x8.1
- 477. http://www.columbia.edu/kermit/ckermit80.html#top
- 478. http://www.columbia.edu/kermit/ckermit80.html#contents
- 479. http://www.columbia.edu/kermit/ckermit.html
- 480. http://www.columbia.edu/kermit/index.html
- 481. http://www.columbia.edu/kermit/ckermit80.html#x8.2
- 482. http://www.columbia.edu/kermit/ckermit80.html#top
- 483. http://www.columbia.edu/kermit/ckermit80.html#contents
- 484. http://www.columbia.edu/kermit/ckermit.html
- 485. http://www.columbia.edu/kermit/index.html
- 486. http://www.columbia.edu/kermit/ckermit80.html#x9.8
- 487. http://www.columbia.edu/kermit/ckermit80.html#x9.8
- 488. http://www.columbia.edu/kermit/ckermit80.html#x8.2
- 489. http://www.columbia.edu/kermit/ckermit80.html#top
- 490. http://www.columbia.edu/kermit/ckermit80.html#contents
- 491. http://www.columbia.edu/kermit/ckermit.html
- 492. http://www.columbia.edu/kermit/index.html
- 493. http://www.columbia.edu/kermit/ckermit80.html#top
- 494. http://www.columbia.edu/kermit/ckermit80.html#contents
- 495. http://www.columbia.edu/kermit/ckermit.html
- 496. http://www.columbia.edu/kermit/index.html
- 497. http://www.columbia.edu/kermit/ckermit80.html#x9.8
- 498. http://www.columbia.edu/kermit/ckermit80.html#top
- 499. http://www.columbia.edu/kermit/ckermit80.html#contents
- 500. http://www.columbia.edu/kermit/ckermit.html
- 501. http://www.columbia.edu/kermit/index.html
- 502. http://www.columbia.edu/kermit/ckermit80.html#x9.8
- 503. http://www.columbia.edu/kermit/ckermit80.html#x9.8
- 504. http://www.columbia.edu/kermit/ckermit80.html#x9.6
- 505. http://www.columbia.edu/kermit/ckermit80.html#top
- 506. http://www.columbia.edu/kermit/ckermit80.html#contents
- 507. http://www.columbia.edu/kermit/ckermit.html
- 508. http://www.columbia.edu/kermit/index.html
- 509. http://www.columbia.edu/kermit/ckermit80.html#x9.8
- 510. http://www.columbia.edu/kermit/ckermit80.html#x9.8
- 511. http://www.columbia.edu/kermit/ckermit80.html#top
- 512. http://www.columbia.edu/kermit/ckermit80.html#contents
- 513. http://www.columbia.edu/kermit/ckermit.html
- 514. http://www.columbia.edu/kermit/index.html
- 515. http://www.columbia.edu/kermit/ckermit80.html#top
- 516. http://www.columbia.edu/kermit/ckermit80.html#contents
- 517. http://www.columbia.edu/kermit/ckermit.html
- 518. http://www.columbia.edu/kermit/index.html
- 519. http://www.columbia.edu/kermit/ckermit80.html#top
- 520. http://www.columbia.edu/kermit/ckermit80.html#contents
- 521. http://www.columbia.edu/kermit/ckermit.html
- 522. http://www.columbia.edu/kermit/index.html
- 523. mailto:thucdat@hotmail.com
- 524. http://www.columbia.edu/kermit/ckermit80.html#x9.9.2
- 525. http://www.columbia.edu/kermit/ckermit80.html#top
- 526. http://www.columbia.edu/kermit/ckermit80.html#contents
- 527. http://www.columbia.edu/kermit/ckermit.html
- 528. http://www.columbia.edu/kermit/index.html
- 529. http://www.columbia.edu/kermit/ckermit80.html#top
- 530. http://www.columbia.edu/kermit/ckermit80.html#contents
- 531. http://www.columbia.edu/kermit/ckermit.html
- 532. http://www.columbia.edu/kermit/index.html
- 533. http://www.columbia.edu/kermit/ckermit80.html#top
- 534. http://www.columbia.edu/kermit/ckermit80.html#contents
- 535. http://www.columbia.edu/kermit/ckermit.html
- 536. http://www.columbia.edu/kermit/index.html
- 537. http://www.columbia.edu/kermit/ckermit80.html#x9.2
- 538. http://www.columbia.edu/kermit/ckermit80.html#top
- 539. http://www.columbia.edu/kermit/ckermit80.html#contents
- 540. http://www.columbia.edu/kermit/ckermit.html
- 541. http://www.columbia.edu/kermit/index.html
- 542. http://www.columbia.edu/kermit/ckermit80.html#x4
- 543. http://www.columbia.edu/kermit/ckermit80.html#x4
- 544. http://www.columbia.edu/kermit/ckermit80.html#top
- 545. http://www.columbia.edu/kermit/ckermit80.html#contents
- 546. http://www.columbia.edu/kermit/ckermit.html
- 547. http://www.columbia.edu/kermit/index.html
- 548. http://www.columbia.edu/kermit/ckermit80.html#top
- 549. http://www.columbia.edu/kermit/ckermit80.html#contents
- 550. http://www.columbia.edu/kermit/ckermit.html
- 551. http://www.columbia.edu/kermit/index.html
- 552. http://www.columbia.edu/kermit/ckermit80.html#top
- 553. http://www.columbia.edu/kermit/ckermit80.html#contents
- 554. http://www.columbia.edu/kermit/ckermit.html
- 555. http://www.columbia.edu/kermit/index.html
- 556. http://www.columbia.edu/kermit/ckermit80.html#x4
- 557. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 558. http://www.columbia.edu/kermit/ckermit80.html#x3.7
- 559. http://www.columbia.edu/kermit/ckermit80.html#top
- 560. http://www.columbia.edu/kermit/ckermit80.html#contents
- 561. http://www.columbia.edu/kermit/ckermit.html
- 562. http://www.columbia.edu/kermit/index.html
- 563. ftp://ftp.isi.edu/in-notes/rfc2217.txt
- 564. http://www.columbia.edu/kermit/ckermit80.html#top
- 565. http://www.columbia.edu/kermit/ckermit80.html#contents
- 566. ftp://kermit.columbia.edu/kermit/sredird/
- 567. http://www.columbia.edu/kermit/ckermit.html
- 568. http://www.columbia.edu/kermit/index.html
- 569. http://www.columbia.edu/kermit/ckermi70.htm#x4.22
- 570. http://www.columbia.edu/kermit/ckermit80.html#top
- 571. http://www.columbia.edu/kermit/ckermit80.html#contents
- 572. http://www.columbia.edu/kermit/ckermit.html
- 573. http://www.columbia.edu/kermit/index.html
- 574. http://www.columbia.edu/kermit/ckermit80.html#x3.1.3
- 575. http://www.columbia.edu/kermit/cuiksd.html
- 576. http://www.columbia.edu/kermit/ckermit80.html#top
- 577. http://www.columbia.edu/kermit/ckermit80.html#contents
- 578. http://www.columbia.edu/kermit/ckermit.html
- 579. http://www.columbia.edu/kermit/index.html
- 580. http://www.columbia.edu/kermit/ckermit80.html#top
- 581. http://www.columbia.edu/kermit/ckermit80.html#contents
- 582. http://www.columbia.edu/kermit/ckermit.html
- 583. http://www.columbia.edu/kermit/index.html
- 584. http://www.columbia.edu/kermit/index.html
+++ /dev/null
-.\" @(#) kermit.1 8.0.211 2004/04/10 Columbia University
-.TH KERMIT 1 "APRIL 2004" "User Manuals"
-.na
-.SH NAME
-kermit \-
-.B C\(hyKermit 8.0:
-transport\(hy and platform\(hyindependent
-interactive and scriptable communications software.
-.IP
-
-This document is intended to give the beginner sufficient information to make
-basic (if not advanced) use of C\(hyKermit 8.0. Although it might be rather long
-for a Unix manual page, it's still far shorter than the C\(hyKermit manual, which
-should be consulted for advanced topics such as customization, character\(hysets,
-scripting, etc. We also attempt to provide a clear structural overview of
-C\(hyKermit's many capabilities, functional areas, states, and modes and their
-interrelation, that should be helpful to beginners and veterans alike, as well
-as to those upgrading to version 8.0 from earlier releases.
-.PP
-This document is also available as a Web page at:
-.IP
-http://www.columbia.edu/kermit/ckututor.html
-.SH DESCRIPTION
-C\(hyKermit is an all\(hypurpose communications software package from the Kermit
-Project at Columbia University that:
-.PP
-.nf
-\(bu Is portable to many platforms, Unix and non\(hyUnix alike.
-.br
-\(bu Can make both serial and network connections.
-.br
-\(bu Can conduct interactive terminal sessions over its connection.
-.br
-\(bu Can transfer text or binary files over the same connection.
-.br
-\(bu Can convert character sets in the terminal session.
-.br
-\(bu Can convert character sets during text\(hyfile file transfer.
-.br
-\(bu Is customizable in every aspect of its operation.
-.fi
-.PP
-C\(hyKermit is a modem program, a Telnet client, an Rlogin client, an FTP
-client, an HTTP client, and on selected platforms, also an X.25 client. It
-can make its own secure Internet connections using IETF\(hyapproved security
-methods including Kerberos IV, Kerberos V, SSL/TLS, and SRP and it can also
-make SSH connections through your external SSH client application. It can
-be the far\(hyend file\(hytransfer or client/server partner of your desktop
-Kermit client. It can also accept incoming dialed and network connections.
-It can even be installed as an Internet service on its own standard TCP
-socket, 1649 [RFC2839, RFC2840].
-.PP
-And perhaps most important, everything you can do "by hand" (interactively)
-with C\(hyKermit, can be "scripted" (automated) using its built\(hyin
-cross\(hyplatform transport\(hyindependent script programming language, which
-happens to be identical to its interactive command language.
-.PP
-This manual page offers an overview of C\(hyKermit 8.0 for Unix ("Unix" is an
-operating system family that includes AIX, DG/UX, FreeBSD, HP\(hyUX, IRIX,
-Linux, Mac OS X, NetBSD, OpenBSD, Open Server, Open Unix, QNX, Solaris,
-SunOS, System V R3, System V R4, Tru64 Unix, Unixware, Xenix, and many
-others). For thorough coverage, please consult the published C\(hyKermit
-manual and supplements (see DOCUMENTATION below). For further information
-about C\(hyKermit, Kermit software for other platforms, and Kermit manuals,
-visit the Kermit Project website:
-.PP
- http://www.columbia.edu/kermit/
-.PP
-This is a longer\(hythan\(hyaverage manual page, and yet it barely scratches the
-surface. Don't be daunted. C\(hyKermit is a large and complex package,
-evolving over decades of practice and experience, but that doesn't mean
-it's hard to learn or use. Its most commonly used functions are explained
-here with pointers to additional information elsewhere.
-.SH SYNOPSIS
-.B kermit [
-.I filename
-.B ] [
-.I options
-.B ] [ {=,\-\-,+}
-.I text
-.B ] ]
-.PP
-or:
-.PP
-.B kermit
-.I URL
-.PP
-If the first command\(hyline argument is the name of a file, interactive\(hymode
-commands are executed from the file. The '=' (or "\-\-") argument tells
-Kermit not to parse the remainder of the command line, but to make the
-words following '=' available as \e%1, \e%2, ... \e%9. The "+" argument is
-like "=" but for use in "kerbang scripts" (explained below). A second
-command\(hyline format allows the one and only argument to be a Telnet, FTP,
-HTTP, or IKSD URL.
-.PP
-Order of execution:
-.TP
- 1.
-The command file (if any).
-.TP
-.nf
- 2.
-The initialization file, if any, unless suppressed with \-Y.
-.fi
-.TP
- 3.
-The customization file (if it is executed by the initialization file).
-.TP
- 4.
-The command\(hyline URL (if any, and if so, execution stops here).
-.TP
- 5.
-Command\(hyline options (if any).
-.TP
- 6.
-Interactive commands.
-.PP
-Some command\(hyline options can cause actions (such as \-s to send a file);
-others just set parameters. If any action options are included on the
-command line, Kermit exits when finished unless also given the \-S ("stay")
-option. If no action options are given, no initialization or command files
-contained an EXIT or QUIT command, and no fatal errors occurred, Kermit
-issues its prompt and waits for you to type commands.
-.IP
-Bear in mind that C\(hyKermit can be built with selected features
-disabled, and also that certain features are not available on all
-platforms. For example, C\(hyKermit can't be built with TCP/IP
-support on a platform that does not have TCP/IP header files and
-libraries (and even if Kermit does include TCP/IP support, it
-can't be used to make TCP/IP connections on a computer that does
-not have a TCP/IP stack installed). If your version of lacks
-C\(hyKermit a feature mentioned here, use its SHOW FEATURES command to
-see what might have been excluded.
-.PP
-C\(hyKermit has three kinds of commands: regular single\(hyletter command\(hyline
-options, extended\(hyformat command\(hyline options, and interactive commands.
-.PP
-Like most Unix commands, C\(hyKermit can be be given options on the command
-line. But C\(hyKermit also can be used interactively by giving it commands
-composed of words, which are more intuitive than cryptic command\(hyline
-options, and more flexible too. In other words, you don't have to use
-C\(hyKermit's command\(hyline options, but they are available if you want to. (By
-the same token, you don't have to use its interactive commands either \(hy\(hy
-you can use either or both in any combination.)
-.PP
-C\(hyKermit is generally installed in the PATH as "kermit", and therefore is
-invoked by typing the word "kermit" (lowercase) at the shell prompt, and
-then pressing the Return or Enter key. If you wish to include command\(hyline
-options, put them after the word "kermit" but before pressing Return or
-Enter, separated by spaces, for example:
-.PP
- $ kermit \-s ckermit.tar.gz
-.PP
-('$' is the shell prompt; "kermit \-s ckermit.tar.gz" is what you type,
-followed by Return or Enter.)
-.SH OPTIONS
-Here is a list of C\(hyKermit's single\(hyletter command\(hyline options, which
-start with a single dash (\-), in ASCII ("alphabetical") order. Alphabetic
-case is significant (\-A is not the same as \-a). Action options are
-tagged "ACTION".
-.TP
-\-0
-(digit zero) 100% transparent Connect state for
-"in\(hythe\(hymiddle" operation: 8 bits, no parity, no
-escape character, everything passes through.
-.TP
-\-8
-(digit eight) Connection is 8\(hybit clean (this is the
-default in C\(hyKermit 8.0). Equivalent to the EIGHTBIT
-command, which in turn is a shortcut for SET TERMINAL
-BYTESIZE 8, SET COMMAND BYTESIZE 8, SET PARITY NONE.
-.TP
-\-9 arg
-(digit nine) Make a connection to an FTP server.
-Equivalent to the FTP OPEN command.
-Argument: IP\(hyaddress\(hyor\(hyhostname[:optional\(hyTCP\(hyport].
-NOTE: C\(hyKermit also has a separate FTP command\(hyline
-personality, with regular FTP\(hylike command\(hyline
-syntax. More about this below.
-.TP
-\-A
-Kermit is to be started as an Internet service (IKSD)
-(only from inetd.conf).
-.TP
-\-B
-Kermit is running in Batch or Background (no
-controlling terminal). To be used in case Kermit
-doesn't automatically sense its background status.
-Equivalent to the SET BACKGROUND ON command.
-.TP
-\-C arg
-Interactive\(hymode Commands to be executed.
-Argument: Commands separated by commas, list in
-doublequotes.
-.TP
-\-D arg
-Delay before starting to send in Remote mode.
-Equivalent to the SET DELAY command.
-Argument: Number of seconds.
-.TP
-\-E
-Exit automatically when connection closes. Equivalent
-to SET EXIT ON\-DISCONNECT ON.
-.TP
-\-F arg
-Use an open TCP connection.
-Argument: Numeric file descriptor of open TCP
-connection.
-Also see: \-j, \-J.
-.TP
-\-G arg
-(ACTION) Get file(s) from server, send contents to standard
-output, which normally would be piped to another
-process.
-Argument: Remote file specification, in quotes if it
-contains metacharacters.
-Also see: \-g, \-k.
-.TP
-\-H
-Suppress program startup Herald and greeting.
-.TP
-\-I
-Tell Kermit it has a reliable connection, to force streaming to be used where
-it normally would not be. Equivalent to the SET RELIABLE ON command.
-.TP
-\-J arg
-(ACTION) "Be like Telnet." Like \-j but implies \-E. Argument: IP
-hostname/address optionally followed by service. NOTE: C\(hyKermit also has a
-separate Telnet command\(hyline personality, with regular Telnet\(hylike
-command\(hyline syntax. More about this below.
-.TP
-\-L
-Recursive directory descent for files in \-s option.
-.TP
-\-M arg
-My user name (for use with Telnet, Rlogin, FTP, etc).
-Equivalent to the SET LOGIN USER command.
-Argument: Username string.
-.TP
-\-O
-(ACTION) (Uppercase letter O) Be a server for One command only.
-Also see: \-x.
-.TP
-\-P
-Don't convert file (Path) names of transferred files.
-Equivalent to SET FILE NAMES LITERAL.
-.TP
-\-Q
-Quick Kermit protocol settings. Equivalent to the FAST
-command. This is the default in C\(hyKermit 7.0 and later.
-.TP
-\-R
-Remote\(hyonly (this just makes IF REMOTE true).
-.TP
-\-S
-Stay (enter command parser after action options).
-.TP
-\-T
-Force Text mode for file transfer; implies \-V.
-Equivalent to SET TRANSFER MODE MANUAL, SET FILE TYPE TEXT.
-.TP
-\-V
-Disable automatic per\(hyfile text/binary switching.
-Equivalent to SET TRANSFER MODE MANUAL.
-.TP
-\-Y
-Skip (don't execute) the initialization file.
-.TP
-\-a arg
-As\(hyname for file(s) in \-s, \-r, or \-g.
-Argument: As\(hyname string (alternative filename). When
-receiving files, this can be a directory name.
-.TP
-\-b arg
-Speed for serial device. Equivalent to SET SPEED.
-Argument: Numeric Bits per second for serial
-connections.
-.TP
-\-c
-(ACTION) Enter Connect state before transferring files.
-.TP
-\-d
-Create a debug.log file with detailed debugging
-information (a second \-d adds timestamps). Equivalent
-to LOG DEBUG but takes effect sooner.
-.TP
-\-e arg
-Maximum length for incoming Kermit file\(hytransfer
-packets. Equivalent to SET RECEIVE PACKET\-LENGTH.
-Argument: Length in bytes.
-.TP
-\-f
-(ACTION) Send a FINISH command to a Kermit server.
-.TP
-\-g arg
-Get file(s) from a Kermit server.
-Argument: File specification on other computer, in
-quotes if it contains metacharacters. Equivalent to
-GET. Also see: \-a, \-G, \-r.
-.TP
-\-h
-(ACTION) Print Help text for single\(hyletter command\(hyline options
-(pipe thru 'more' to prevent scrolling).
-.TP
-\-i
-Force binary (Image) mode for file transfer; implies
-\-V. Equivalent to SET TRANSFER MODE MANUAL, SET FILE
-TYPE BINARY.
-.TP
-\-j arg
-Make a TCP/IP connection.
-Argument: IP host name/address and optional service
-name or number. Equivalent to the TELNET command.
-Also see: \-J, \-F.
-.TP
-\-k
-(ACTION) Receive file(s) to standard output, which normally
-would be piped to another process.
-Also see: \-r, \-G.
-.TP
-\-l arg
-(Lowercase letter L) Make a connection on the given
-serial communications device. Equivalent to the SET
-LINE (SET PORT) command.
-Argument: Serial device name, e.g. /dev/ttyS0.
-.TP
-\-m arg
-Modem type for use with the \-l device. Equivalent to
-the SET MODEM TYPE command.
-Argument: Modem name as in SET MODEM TYPE command,
-e.g. "usrobotics".
-.TP
-\-n
-(ACTION) Enter Connect state after transferring files (historical).
-.TP
-\-p arg
-Parity. Equivalent to the SET PARITY command.
-Argument: One of the following: e(ven), o(dd), m(ark),
-n(one), s(pace).
-.TP
-\-q
-Quiet (suppress most messages). Equivalent to SET QUIET ON.
-.TP
-\-r
-(ACTION) Receive file(s). Equivalent to the RECEIVE command.
-Argument: (none, but see \-a)
-.TP
-\-s arg
-Send file(s).
-Argument: One or more local file specifications.
-Equivalent to the SEND command.
-Also see: \-a.
-.TP
-\-t
-(Historical) Xon (Ctrl\-Q) Turnaround character for
-half\(hyduplex connections (used on serial linemode
-connections to old mainframes). Equivalent to SET
-DUPLEX HALF, SET HANDSHAKE XON.
-.TP
-\-v arg
-Window size for Kermit protocol (ignored when
-streaming). Equivalanet to SET WINDOW\-SIZE.
-Argument: Number, 1 to 32.
-.TP
-\-w
-Incoming files Write over existing files. Equivalent
-to SET FILE COLLISION OVERWRITE.
-.TP
-\-x
-(ACTION) Enter server mode. Equivalent to the SERVER command.
-Also see: \-O.
-.TP
-\-y arg
-Alternative initialization file.
-Argument: Filename.
-.TP
-\-z
-Force foreground behavior. To be used in case Kermit
-doesn't automatically sense its foreground status.
-Equivalent to the SET BACKGROUND OFF command.
-.PP
-Extended command\(hyline options (necessary because single\(hyletter ones are
-about used up) start with two dashes (\-\-), with words rather than single
-letters as option names. If an extended option takes an argument, it is
-separated from the option word by a colon (:). Extended options include:
-
-.TP
- \-\-bannerfile:filename
-File to display upon startup or IKSD login.
-.TP
- \-\-cdfile:filename
-File to be sent for display to the client when
-server changes directory (filename is relative to
-the changed\(hyto directory).
-.TP
- \-\-cdmessage:{on,off}
-Enable/disable the server CD message feature.
-.TP
- \-\-help
-Prints usage message for extended options.
-.TP
- \-\-helpfile:filename
-Designates a file containing custom text to
-replace the top\(hylevel HELP command.
-.TP
- \-\-nointerrupts
-Disables keyboard interrupts.
-.TP
- \-\-noperms
-Disables the Kermit protocol file Permissions
-attribute, to prevent transmission of file
-permissions (protection) from sender to receiver.
-.TP
- \-\-version
-(ACTION) C\(hyKermit prints its version number.
-.PP
-Plus several other IKSD\(hyOnly options described at:
-.PP
- http://www.columbia.edu/kermit/iksd.html
-.PP
-See the file\(hytransfer section for examples of command\(hyline invocation.
-.SH COMMAND LANGUAGE
-C\(hyKermit's interactive command language is the subject of a 622\(hypage book
-and another several hundred pages of updates, far too much for a manual
-page. But it's not hard to get started. At the shell prompt, just type
-"kermit" to get C\(hyKermit's interactive command prompt:
-.PP
-.nf
- $ kermit
- (/current/directory) C\-Kermit>
-.fi
-.PP
-Begin by typing "help" (and then press the Return or Enter key) for a
-top\(hylevel overview, read it, and go from there. Your second command should
-probably be "intro" (introduction). Note the prompt shows your current
-directory (unless you tell Kermit to prompt you with something else).
-.PP
-Interactive commands are composed mainly of regular English words, usually
-in the form of imperative sentences, such as:
-.PP
- send oofa.txt
-.PP
-which tells Kermit to send (transfer) the file whose name is oofa.txt, or:
-.PP
- set transfer mode automatic
-.PP
-which sets Kermit's "transfer mode" to "automatic" (whatever that means).
-.PP
-While typing commands, you can abbreviate, ask for help (by pressing the
-"?" key anywhere in a command), complete keywords or filenames (with the
-Tab or Esc key), and edit your typing with Backspace or Delete, Ctrl\-W,
-Ctrl\-U, etc. You can also recall previous commands, save your command
-history, and who knows what else. Give the INTRO command for details.
-.PP
-C\(hyKermit has hundreds of commands, and they can be issued in infinite
-variety and combinations, including commands for:
-.nf
-.PP
-\(bu Making connections (SET LINE, DIAL, TELNET, SSH, FTP, ...)
-.br
-\(bu Breaking connections (HANGUP, CLOSE)
-.br
-\(bu Transferring files (SEND, GET, RECEIVE, MOVE, RESEND, ...)
-.br
-\(bu Establishing preferences (SET)
-.br
-\(bu Displaying preferences (SHOW)
-.br
-\(bu Managing local files (CD, DELETE, MKDIR, DIR, RENAME, TYPE, ...)
-.br
-\(bu Managing remote files (RCD, RDEL, RMKDIR, RDIR, ...)
-.br
-\(bu Using local files (FOPEN, FCLOSE, FREAD, FWRITE)
-.br
-\(bu Programming (TAKE, DEFINE, IF, FOR, WHILE, SWITCH, DECLARE, ...)
-.br
-\(bu Interacting with the user (ECHO, ASK, ...)
-.br
-\(bu Interacting with a remote computer (INPUT, OUTPUT, ...)
-.br
-\(bu Interacting with local programs (RUN, EXEC, PTY, ...)
-.br
-\(bu Logging things (LOG SESSION, LOG PACKETS, LOG DEBUG, ...)
-.PP
-.fi
-And of course QUIT or EXIT to get out and HELP to get help, and for
-programmers: loops, decision making, variables, arrays, associative arrays,
-integer and floating point arithmetic, macros, built\(hyin and user\(hydefined
-functions, string manipulation, pattern matching, block structure, scoping,
-recursion, and all the rest. To get a list of all C\(hyKermit's commands, type
-a question mark (?) at the prompt. To get a description of any command,
-type HELP followed by the name of the command, for example:
-.PP
- help send
-.PP
-The command interruption character is Ctrl\-C (hold down the Ctrl key and
-press the C key).
-.PP
-The command language "escape character", used to introduce variable names,
-function invocations, and so on, is backslash (\). If you need to include a
-literal backslash in a command, type two of them, e.g.:
-.PP
- get c:\ek95\ek95custom.ini
-.SS Command Files, Macros, and Scripts
-A file containing Kermit commands is called a Kermit command file or Kermit
-script. It can be executed with Kermit's TAKE command:
-.PP
- (/current/dir) C\-Kermit> take commandfile
-.PP
-(where "commandfile" is the name of the command file). Please don't pipe a
-command file into Kermit's standard input (which might or might not work);
-if you have Kermit commands in a file, tell Kermit to TAKE the file.
-.PP
-In Unix only, a Kermit command file can also be executed directly by
-including a "kerbang" line as the first line of the file:
-.PP
- #!/usr/local/bin/kermit +
-.PP
-That is, a top line that starts with "#!", followed immediately by the full
-path of the Kermit executable, and then, if the Kermit script is to be
-given arguments on the command line, a space and a plus sign. The script
-file must also have execute permission:
-.PP
- chmod +x commandfile
-.PP
-Except for the " +" part, this is exactly the same as you would do for a
-shell script, a Perl script, etc. Here's a simple but useless example
-script that regurgitates its arguments (up to three of them):
-.PP
- #!/usr/local/bin/kermit +
- if defined \e%1 echo "Argument 1: \e%1"
- if defined \e%2 echo "Argument 2: \e%2"
- if defined \e%3 echo "Argument 3: \e%3"
- if defined \e%4 echo "etc..."
- exit
-.PP
-If this file is stored in your current directory as "commandfile", then:
-.PP
- ./commandfile one two three four five
-.PP
-prints:
-.PP
- Argument 1: one
- Argument 2: two
- Argument 3: three
- etc...
-.PP
-This illustrates the basic structure of a standalone Kermit script: the
-"kerbang line", then some commands. It should end with "exit" unless you
-want the Kermit prompt to appear when it is finished. \e%1 is the first
-argument, \e%2 the second, and so on.
-.PP
-You can also create your own commands by defining named macros composed of
-other Kermit commands (or macros). For example:
-.PP
-.nf
- define mydelete {
- local trash
- assign trash \ev(home)trashcan/
- if not defined \e%1 end 1 "Delete what?"
- if wild \e%1 {
- end 1 "Deleting multiple files is too scary"
- }
- if not exist \e%1 end 1 "I can't find \e%1"
- if not directory \em(trash) {
- mkdir \em(trash)
- if fail end 1 "No trash can"
- }
- rename /list \e%1 \em(trash)
- }
- define myundelete {
- local trash
- assign trash \ev(home)trashcan/
- if not defined \e%1 end 1 "Undelete what?"
- if wild \e%1 {
- end 1 "Undeleting multiple files is too hard"
- }
- if not directory \em(trash) end 1 "No trash can"
- if not exist \em(trash)\e%1 {
- end 1 "I can't find \e%1 in trash can"
- }
- rename /list \em(trash)\e%1 .
- }
-.PP
-.fi
-These sample macros are not exactly production quality (they don't handle
-filenames that include path segments, they don't handle multiple files,
-etc), but you get the idea: you can pass arguments to macros, and they can
-check them and make other kinds of decisions. If you put the above lines
-into your initialization or customization file (explained below), you'll
-have MYDELETE and MYUNDELETE commands available every time you start
-Kermit, at least as long as you don't suppress execution of the
-initialization file. (Exercise for the reader: Make these macros generally
-useful: remove limitations, add trashcan display, browsing, emptying, etc.)
-.PP
-Kerbang scripts execute without the initialization file. This to keep them
-portable and also to make them start faster. If you want to write Kerbang
-scripts that depend on the initialization file, include the command
-.PP
- take \ev(home).kermrc
-.PP
-at the desired spot in the script. By the way, \ev(xxx) is a built\(hyin
-variable (xxx is the variable name, "home" in this case). To see what
-built\(hyin variables are available, type "show variables" at the C\(hyKermit
-prompt. To see what else you can show, type "show ?". \em(xxx) is a user
-defined variable (strictly speaking, it is a macro used as a variable).
-.SS Command List
-C\(hyKermit has more than 200 top\(hylevel commands, and some of these, such as
-SET, branch off into hundreds of subcommands of their own, so it's not
-practical to describe them all here. Instead, here's a concise list of the
-most commonly used top\(hylevel commands, grouped by category. To learn about
-each command, type "help" followed by the command name, e.g. "help set".
-Terms such as Command state and Connect state are explained in subsequent
-sections.
-.PP
-Optional fields are shown in [ brackets ]. "filename" means the
-name of a single file. filespec means a file specification that is allowed
-to contain wildcard characters like '*' to match groups of files. options
-are (optional) switches like /PAGE, /NOPAGE, /QUIET, etc, listed in the
-HELP text for each command. Example:
-.PP
-.nf
- send /recursive /larger:10000 /after:\-1week /except:*.txt *
-.fi
-.PP
-which can be read as "send all the files in this directory and all the ones
-underneath it that are larger than 10000 bytes, no more than one week old,
-and whose names don't end with ".txt".
-.SS
-Basic Commands
-.RS
-.TP
-HELP
-Requests top\(hylevel help.
-.TP
-HELP command
-Requests help about the given command.
-.TP
-INTRODUCTION
-Requests a brief introduction to C\(hyKermit.
-.TP
-LICENSE
-Displays the C\(hyKermit software copyright and license.
-.TP
-VERSION
-Displays C\(hyKermit's version number.
-.TP
-EXIT [ number ]
-Exits from Kermit with the given
-status code. Synonyms: QUIT, E, Q.
-.TP
-TAKE filename [ parameters... ]
-Executes commands from the given
-.TP
-LOG item [ filename ]
-Keeps a log of the given item in the given file.
-.TP
-[ DO ] macro [ parameters... ]
-Executes commands from the given macro.
-.TP
-SET parameter value
-Sets the given parameter to the given value.
-.TP
-SHOW category
-Shows settings in a given category.
-.TP
-STATUS
-Tells whether previous command succeeded or failed.
-.TP
-DATE [ date\(hyand/or\(hytime ]
-Shows current date\(hytime or interprets given date\(hytime.
-.TP
-RUN [ extern\(hycommand [ parameters... ]
-Runs the given external command. Synonym: !.
-.TP
-EXEC [ extern\(hycommand [ params... ]
-Kermit overlays itself with the given command.
-.TP
-SUSPEND
-Stops Kermit and puts it in the background. Synonym: Z.
-.RE
-.SS
-Local File Management
-.RS
-.TP
-TYPE [ options ] filename
-Displays the contents of the given file.
-.TP
-MORE [ options ] filename
-Equivalent to TYPE /PAGE (pause after each screenful).
-.TP
-CAT [ options ] filename
-Equivalent to TYPE /NOPAGE.
-.TP
-HEAD [ options ] filename
-Displays the first few lines of a given file.
-.TP
-TAIL [ options ] filename
-Displays the last few lines of a given file.
-.TP
-GREP [ options ] pattern filespec
-Displays lines from files that match
-the pattern. Synonym: FIND.
-.TP
-DIRECTORY [ options ] [filespec ]
-Lists files (built\(hyin, many options).
-.TP
-LS [ options ] [ filespec ]
-Lists files (runs external "ls" command).
-.TP
-DELETE [ options ] [ filespec ]
-Deletes files. Synonym: RM.
-.TP
-PURGE [ options ] [ filespec ]
-Removes backup (*.~n~) files.
-.TP
-COPY [ options ] [ filespecs... ]
-Copies files. Synonym: CP.
-.TP
-RENAME [ options ] [ filespecs... ]
-Renames files. Synonym: MV.
-.TP
-CHMOD [ options ] [ filespecs... ]
-Changes permissions of files.
-.TP
-TRANSLATE filename charsets [ filename ]
-Converts file's character set. Synonym: XLATE.
-.TP
-CD
-Changes your working directory to your home directory.
-.TP
-CD directory
-Changes your working directory to the one given.
-.TP
-CDUP
-Changes your working directory one level up.
-.TP
-PWD
-Displays your working directory.
-.TP
-BACK
-Returns to your previous working directory.
-.TP
-MKDIR [ directory ]
-Creates a directory.
-.TP
-RMDIR [ directory ]
-Removes a directory.
-.RE
-.SS
-Making Connections
-.RS
-.TP
-SET LINE [ options ] devicename
-Opens the named serial port. Synonym: SET PORT.
-.TP
-OPEN LINE [ options ] devicename
-Same as SET LINE. Synonym: OPEN PORT.
-.TP
-SET MODEM TYPE [ name ]
-Tells Kermit what kind of modem is on the port.
-.TP
-DIAL [ number ]
-Tells Kermit to dial the given phone number with the modem.
-.TP
-REDIAL
-Redials the most recently dialed phone number.
-.TP
-ANSWER
-Waits for and answers an incoming call on the modem.
-.TP
-AUTHENTICATE [ parameters... ]
-Performs secure authentication on a TCP/IP connection.
-.TP
-SET NETWORK TYPE { TCP/IP, X.25, ... }
-Selects network type for subsequent SET HOST commands.
-.TP
-SET HOST [ options ] host [ port ]
-Opens a network connection to the given host and port.
-.TP
-SET HOST * port
-Waits for an incoming TCP/IP connection on the given port.
-.TP
-TELNET [ options ] host
-Opens a Telnet connection to the host and enters Connect state.
-.TP
-RLOGIN [ options ] host
-Opens an Rlogin connection to the host and enters Connect state.
-.TP
-IKSD [ options ] host
-Opens a connection to an Internet Kermit Service.
-.TP
-SSH [ options ] host
-Opens an SSH connection to the host and enters Connect state.
-.TP
-FTP OPEN host [ options ]
-Opens an FTP connection to the host.
-.TP
-HTTP [ options ] OPEN host
-Opens an HTTP connection to the host.
-.TP
-PTY external\(hycommand
-Runs the command on a pseudoterminal as if it were a connection.
-.TP
-PIPE external\(hycommand
-Runs the command through a pipe as if it were a connection.
-.RE
-.SS
-Using Connections
-.RS
-.TP
-CONNECT [ options ]
-Enters Connect (terminal) state. Synonym: C.
-.TP
-REDIRECT command
-Redirects the given external command over the connection.
-.TP
-TELOPT command
-Sends a Telnet protocol command (Telnet connections only).
-.TP
-Ctrl\-\eC
-"Escapes back" from Connect state to Command state.
-.TP
-Ctrl\-\eB
-(In Connect state) Sends a BREAK signal (serial or Telnet).
-.TP
-Ctrl\-\e!
-(In Connect state) Enters inferior shell; "exit" to return.
-.TP
-Ctrl\-\e?
-(In Connect state) Shows a menu of other escape\(hylevel options.
-.TP
-Ctrl\-\eCtrl\-\e
-(In Connect state) Type two
-Ctrl\-Backslashes to send one of them.
-.TP
-SET ESCAPE [ character ]
-Changes Kermit's Connect\(hystate escape character.
-.RE
-.SS
-Closing Connections
-.RS
-.TP
-HANGUP
-Hangs up the currently open
-serial\(hyport or network connection.
-.TP
-CLOSE
-Closes the currently open
-serial\(hyport or network connection.
-.TP
-SET LINE (with no devicename)
-Closes the currently open
-serial\(hyport or network connection.
-.TP
-SET HOST (with no hostname)
-Closes the currently open serial\(hyport or network connection.
-.TP
-FTP CLOSE
-Closes the currently open FTP connection.
-.TP
-HTTP CLOSE
-Closes the currently open HTTP connection.
-.TP
-EXIT
-Also closes all connections. Synonym: QUIT.
-.TP
-SET EXIT WARNING OFF
-Suppresses warning about open connections on exit or close.
-.RE
-.SS
-File Transfer
-.RS
-.TP
-SEND [ options ] filename [ as\(hyname ]
-Sends the given file. Synonym: S.
-.TP
-SEND [ options ] filespec
-Sends all files that match.
-.TP
-RESEND [ options ] filespec
-Resumes an interupted SEND from the point of failure.
-.TP
-RECEIVE [ options ] [ as\(hyname ]
-Waits passively for files to arrive. Synonym: R.
-.TP
-LOG TRANSACTIONS [ filename ]
-Keeps a record of file transfers.
-.TP
-FAST
-Use fast file\(hytransfer settings (default).
-.TP
-CAUTIOUS
-Use cautious and less fast file\(hytransfer settings.
-.TP
-ROBUST
-Use ultra\(hyconservative and slow file\(hytransfer settings.
-.TP
-STATISTICS [ options ]
-Gives statistics about the most recent file transfer.
-.TP
-WHERE
-After transfer: "Where did my files go?".
-.TP
-TRANSMIT [ options ] [ofilename ]
-Sends file without protocol. Synonym: XMIT.
-.TP
-LOG SESSION [ filename ]
-Captures remote text or files without protocol.
-.TP
-SET PROTOCOL [ name... ]
-Tells Kermit to use an external file\(hytransfer protocol.
-.TP
-FTP { PUT, MPUT, GET, MGET, ... }
-FTP client commands.
-.TP
-HTTP { PUT, GET, HEAD, POST, ... }
-HTTP client commands.
-.RE
-.SS
-Kermit Server
-.RS
-.TP
-ENABLE, DISABLE
-Controls which server features can be used by clients.
-.TP
-SET SERVER
-Sets parameters prior to entering Server state.
-.TP
-SERVER
-Enters Server state.
-.RE
-.SS
-Client of Kermit or FTP Server
-.RS
-.TP
-[ REMOTE ] LOGIN [ user password ]
-Logs in to a Kermit server or IKSD that requires it.
-.TP
-[ REMOTE ] LOGOUT
-Logs out from a Kermit server or IKSD.
-.TP
-SEND [ options ] filename [ as\(hyname ]
-Sends the given file to the server. Synonyms: S, PUT.
-.TP
-SEND [ options ] filespec
-Sends all files that match.
-.TP
-RESEND [ options ] filespec
-Resumes an interupted SEND from the point of failure.
-.TP
-GET [ options ] remote\(hyfilespec
-Asks the server to send the given files. Synonym: G.
-.TP
-REGET [ options ] remote\(hyfilespec
-Resumes an interrupted GET from the point of failure.
-.TP
-REMOTE CD [ directory ]
-Asks server to change its working
-directory. Synonym: RCD.
-.TP
-REMOTE PWD [ directory ]
-Asks server to display its working directory. Synonym: RPWD.
-.TP
-REMOTE DIRECTORY [ filespec... ]
-Asks server to send a directory listing. Synonym: RDIR.
-.TP
-REMOTE DELETE [ filespec... ]
-Asks server to delete files. Synonym: RDEL.
-.TP
-REMOTE [ command... ]
-(Many other commands: "remote ?" for a list).
-.TP
-MAIL [ options ] filespec
-Sends file(s) to be delivered as e\(hymail (Kermit only).
-.TP
-FINISH
-Asks the server to exit server state (Kermit only).
-.TP
-BYE
-Asks the server to log out and close the connection.
-.RE
-.SS
-Script Programming
-.PP
-.RS
-DEFINE, DECLARE, UNDEFINE, UNDECLARE, ASSIGN, EVALUATE, SEXPRESSION,
-ARRAY, SORT, INPUT, OUTPUT, IF, FOR, WHILE, SWITCH, GOTO, ECHO, ASK,
-GETC, GETOK, ASSERT, WAIT, SLEEP, FOPEN, FREAD, FWRITE, FCLOSE, STOP,
-END, RETURN, LEARN, SHIFT, TRACE, VOID, INCREMENT, DECREMENT, ... For
-these and many more you'll need to consult the manual and supplements,
-and/or visit the Kermit Script Library, which also includes a brief
-tutorial. Hint: HELP LEARN to find out how to get Kermit to write
-simple scripts for you.
-.RE
-.PP
-Many of Kermit's commands have synonyms, variants, relatives, and so on.
-For example, MSEND is a version of SEND that accepts a list of file
-specifications to be sent, rather than just one file specification, and
-MPUT is a synonym of MSEND. MOVE means to SEND and then DELETE the source
-file if successful. MMOVE is like MOVE, but accepts a list of filespecs,
-and so on. These are described in the full documentation.
-.PP
-Use question mark to feel your way through an unfamiliar command, as in
-this example:
-.PP
-.nf
- C\-Kermit> remote ? One of the following:
- assign directory kermit print rmdir
- cd exit login pwd set
- copy help logout query space
- delete host mkdir rename type
- C\-Kermit> remote set ? One of the following:
- attributes file retry transfer
- block\-check receive server window
- C\-Kermit> remote set file ? One of the following:
- character\-set incomplete record\-length
- collision names type
- C\-Kermit> remote set file names ? One of the following:
- converted literal
- C\-Kermit> remote set file names literal
- C\-Kermit>
-.PP
-.fi
-This is called menu on demand: you get a menu when you want one, but menus
-are not forced on you even when know what you're doing. Note that you can
-also abbreviate most keywords, and you can complete them with the Tab or
-Esc key. Also note that ? works for filenames too, and that you can use it
-in the middle of a keyword or filename, not just at the beginning. For
-example, "send x?" lists all the files in the current directory whose names
-start with 'x'.
-.SH INITIALIZATION FILE
-In its default configuration, C\(hyKermit executes commands from a file
-called .kermrc in your home directory when it starts, unless it is given the
-\-Y or \-y command\(hyline option. Custom configurations might substitute a shared
-system\(hywide initialization file. The SHOW FILE command tells what
-initialization file, if any, was used. The standard initialization file
-"chains" to an individual customization file, .mykermc, in the home directory,
-in which each user can establish her/his own preferences, define macros, and
-so on.
-.PP
-Since execution of the initialization file (at least the standard one)
-makes C\(hyKermit take longer to start, it might be better not to have an
-initialization file, especially now that Kermit's default startup
-configuration is well attuned to modern computing and networking \(hy\(hy in
-other words, you no longer have do anything special to make Kermit
-transfers go fast. So instead of having an initialization file that is
-executed every time Kermit starts, you might consider making one or more
-kerbang scripts (with names other that .kermrc) that do NOT include an
-"exit" command, and invoke those when you need the settings, macro
-definitions, and/or scripted actions they contain, and invoke C\(hyKermit
-directly when you don't.
-.PP
-To put it another way... We still distribute the standard initialization
-file since it's featured in the manual and backwards compatibility is
-important to us. But there's no harm in not using it if you don't need the
-stuff that's in it (services directory, dialing directory, network
-directory, and associated macro definitions). On the other hand, if there
-are settings or macros you want in effect EVERY time you use Kermit, the
-initialization file (or the customization file it chains to) is the place
-to put them, because that's the only place Kermit looks for them
-automatically each time you start it.
-.SH MODES OF OPERATION
-Kermit is said to be in Local mode if it has made a connection to another
-computer, e.g. by dialing it or establishing a Telnet connection to it. The
-other computer is remote, so if you start another copy of Kermit on the
-remote computer, it is said to be in Remote mode (as long as it has not
-made any connections of its own). The local Kermit communicates over the
-communications device or network connection, acting as a conduit between
-the the remote computer and your keyboard and screen. The remote Kermit is
-the file\(hytransfer partner to the local Kermit and communicates only through
-its standard input and output.
-.PP
-At any moment, a Kermit program can be in any of the following states. It's
-important to know what they are and how to change from one to the other.
-.TP
-Command state
-In this state, Kermit reads commands from:
-.sp
-\(bu Your keyboard; or:
-.br
-\(bu A file, or:
-.br
-\(bu A macro definition.
-.sp
-You can exit from Command state back to Unix with the EXIT or QUIT
-command (same thing). You can enter Connect state with any of various
-commands (CONNECT, DIAL, TELNET, etc). You can enter file transfer
-state with commands like SEND, RECEIVE, and GET. You can enter Server
-state with the SERVER command. The TAKE command tells Kermit to read
-and execute commands from a file. The (perhaps implied) DO command
-tells Kermit to read and execute commands from a macro definition.
-While in Command state, you can interrupt any command, macro, or
-command file by typing Ctrl\-C (hold down the Ctrl key and press the C
-key); this normally brings you back to the prompt.
-.TP
-Shell state
-You can invoke an inferior shell or external command from the Kermit
-command prompt by using the PUSH, RUN (!), EDIT, or BROWSE command.
-While the inferior shell or command is active, Kermit is suspended and
-does nothing. Return to Kermit Command state by exiting from the
-inferior shell or application.
-.TP
-Connect state
-In this state, which can be entered only when in Local mode (i.e. when
-Kermit has made a connection to another computer), Kermit is acting as
-a terminal to the remote computer. Your keystrokes are sent to the
-remote computer and characters that arrive over the communication
-connection are displayed on your screen. This state is entered when
-you give a CONNECT, DIAL, TELNET, RLOGIN, or IKSD command. You can
-return to command state by logging out of the remote computer, or by
-typing:
-.sp
- Ctrl\-\ec
-.sp
-That is: Hold down the Ctrl key and press the backslash key, then let
-go of the Ctrl key and press the C key. This is called escaping back.
-Certain other escape\(hylevel commands are also provided; type Ctrl\-\e?
-for a list. For example, you can enter Shell state with:
-.sp
- Ctrl\-\e!
-.sp
-To send a Ctrl\-\e to the host while in Connect state, type two of them
-in a row. See HELP CONNECT and HELP SET ESCAPE for more info.
-.TP
-Local file\(hytransfer state
-In this state, Kermit is sending packets back and forth with the other
-computer in order to transfer a file or accomplish some other
-file\(hyrelated task. And at the same time, it is displaying its progress
-on your screen and watching your keyboard for interruptions. In this
-state, the following single\(hykeystroke commands are accepted:
-.sp
-.RS
-.TP
-X
-Interrupt the current file and go on to the next (if any).
-.TP
-Z
-Interrupt the current file and skip all the rest.
-.TP
-E
-Like Z but uses a "stronger" protocol (use if X or Z don't work).
-.TP
-Ctrl\-C
-Interrupt file\(hytransfer mode (use if Z or E don't work).
-.sp
-.RE
-Kermit returns to its previous state (Command or Connect) when the
-transfer is complete or when interrupted successfully by X, Z, E, or
-Ctrl\-C (hold down the Ctrl key and press the C key).
-.TP
-Remote file\(hytransfer state
-In this state, Kermit is exchanging file\(hytransfer packets with its
-local partner over its standard i/o. It leaves this state
-automatically when the transfer is complete. In case you find your
-local Kermit in Connect state and the remote one in File\(hytransfer
-state (in which it seems to ignore your keystrokes), you can usually
-return it to command state by typing three Ctrl\-C's in a row. If that
-doesn't work, return your local Kermit to Command state (Ctrl\-\e C) and
-type "e\(hypacket" and then press the Return or Enter key; this forces a
-fatal Kermit protocol error.
-.TP
-Remote Server state
-This is like Remote File\(hytransfer state, except it never returns
-automatically to Command state. Rather, it awaits further instructions
-from the client program; that is, from your Local Kermit program. You
-can return the Remote Server to its previous state by issuing a
-"finish" command to the client, or if you are in Connect state, by
-typing three Ctrl\-C's in a row. You can tell the server job to log out
-and break the connection by issuing a "bye" command to the client.
-.TP
-Local Server state
-Like Remote\(hyServer state, but in local mode, and therefore with its
-file\(hytransfer display showing, and listening for single\(hykey commands,
-as in Local File\(hytransfer state. Usually this state is entered
-automatically when a remote Kermit program gives a GET command.
-.sp
-C\(hyKermit, Kermit 95, and MS\(hyDOS Kermit all can switch automatically from
-Connect state to Local File\(hytransfer state when you initiate a file
-transfer from the remote computer by starting Kermit and telling it to send
-or get a file, in which case, Connect state is automatically resumed after
-the file transfer is finished.
-.sp
-Note that C\(hyKermit is not a terminal emulator. It is a communications
-application that you run in a terminal window (e.g. console or Xterm). The
-specific emulation, such as VT100, VT220, Linux Console, or Xterm, is
-provided by the terminal window in which you are running C\(hyKermit. Kermit
-95 and MS\(hyDOS Kermit, on the other hand, are true terminal emulators. Why
-is C\(hyKermit not a terminal emulator? CLICK HERE to read about it.
-.SH MAKING CONNECTIONS
-Here is how to make different kinds of connections using interactive Kermit
-commands (as noted above, you can also make connections with command\(hyline
-options). Note that you don't have to make connections with Kermit. It can
-also be used on the far end of a connection as the remote file transfer and
-management partner of your local communications software.
-.TP
-Making a Telnet Connection
-At the C\(hyKermit command prompt, simply type:
-.sp
-.nf
- telnet foo.bar.com
-.fi
-.sp
-(substituting desired hostname or address).
-You can also include a port number:
-.sp
-.nf
- telnet xyzcorp.com 3000 ;
-.fi
-.sp
-If the connection is successful, Kermit automically enters Connect
-state. When you logout from the remote host, Kermit automatically
-returns to its prompt. More info: HELP TELNET, HELP SET TELNET, HELP
-SET TELOPT. Also see the IKSD section below.
-.TP
-Making an Rlogin connection
-This is just like Telnet, except you have to be root to do it because
-Rlogin uses a privileged TCP port:
-.sp
-.nf
- rlogin foo.bar.com
-.fi
-.sp
-More info: HELP RLOGIN.
-.TP
-Making an SSH Connection
-Unlike Telnet and Rlogin, SSH connections are not built\(hyin, but
-handled by running your external SSH client through a pseudoterminal.
-Using C\(hyKermit to control the SSH client gives you all of Kermit's
-features (file transfer, character\(hyset conversion, scripting, etc)
-over SSH.
-.sp
- ssh foo.bar.com
-.sp
-More info: HELP SSH, HELP SET SSH.
-.TP
-Dialing with a Modem
-If it's an external modem, make sure it is connected to a usable
-serial port on your computer with a regular (straight\(hythrough) modem
-cable, and to the telephone jack with a telephone cable, and that it's
-turned on. Then use these commands:
-.sp
-.nf
- set modem type usrobotics ; Or other supported type
- set line /dev/ttyS0 ; Specify device name
- set speed 57600 ; Or other desired speed
- set flow rts/cts ; Most modern modems support this
- set dial method tone ; (or pulse)
- dial 7654321 ; Dial the desired number
-.fi
-.sp
-Type "set modem type ?" for a list of supported modem types. If you
-omit the SET MODEM TYPE command, the default type is
-"generic\(hyhigh\(hyspeed", which should work for most modern AT\(hycommand\(hyset
-modems. If the line is busy, Kermit redials automatically. If the call
-does not succeed, use "set dial display on" and try it again to watch
-what happens. If the call succeeds, Kermit enters Connect state
-automatically and returns to its prompt automatically when you log out
-from the remote computer or the connection is otherwise lost.
-.sp
-You can also dial from a modem that is accessible by Telnet, e.g. to a
-reverse terminal server. In this case the command sequence is:
-.sp
-.nf
- set host ts.xxx.com 2000 ; Terminal\(hyserver and port
- set modem type usrobotics ; Or other supported type
- set dial method tone ; (or pulse)
- dial 7654321 ; Dial the desired number
-.fi
-.sp
-If the terminal server supports the Telnet Com Port Option, RFC 2217,
-you can also give serial\(hyport related commands such as SET SPEED, SET
-PARITY, and so on, and Kermit relays them to the terminal server using
-the protocol specified in the RFC.
-.sp
-More info: HELP SET MODEM, HELP SET LINE, HELP SET SPEED, HELP SET
-FLOW, HELP DIAL, HELP SET DIAL, HELP SET MODEM, HELP SET
-CARRIER\-WATCH, SHOW COMMUNICATIONS, SHOW MODEM, SHOW DIAL.
-.TP
-Direct Serial Port
-Connect the two computers, A and B, with a null modem cable (or two
-modem cables interconnected with a null\(hymodem adapter or modem
-eliminator). From Computer A:
-.sp
-.nf
- set modem type none ; There is no modem
- set line /dev/ttyS0 ; Specify device name
- set carrier\-watch off ; If DTR CD are not cross\(hyconnected
- set speed 57600 ; Or other desired speed
- set flow rts/cts ; If RTS and CTS are cross\(hyconnected
- set parity even ; (or "mark" or "space", if necessary)
- set stop\-bits 2 ; (rarely necessary)
- set flow xon/xoff ; If you can't use RTS/CTS
- connect ; Enter Connect (terminal) state
-.fi
-.sp
-This assumes Computer B is set up to let you log in. If it isn't, you
-can run a copy of Kermit on Computer B and follow approximately the
-same directions. More info: As above plus HELP CONNECT.
-.PP
-With modems or direct serial connections, you might also have to "set
-parity even" (or "mark" or "space") if it's a 7\(hybit connection.
-.PP
-Of the connection types listed above, only one can be open at a time.
-However, any one of these can be open concurrently with an FTP or HTTP
-session. Each connection type can be customized to any desired degree,
-scripted, logged, you name it. See the manual.
-.PP
-NOTE: On selected platforms, C\(hyKermit also can make X.25 connections. See
-the manual for details.
-.SH TRANSFERRING FILES WITH KERMIT
-There is a widespread and persistent belief that Kermit is a slow protocol.
-This is because, until recently, it used conservative tuning by default to
-make sure file transfers succeeded, rather than failing because they
-overloaded the connection. Some extra commands (or command\(hyline options,
-like \-Q) were needed to make it go fast, but nobody bothered to find out
-about them. Also, it takes two to tango: most non\(hyKermit\(hyProject Kermit
-protocol implementations really ARE slow. The best file\(hytransfer partners
-for C\(hyKermit are: another copy of C\(hyKermit (7.0 or later) and Kermit 95.
-These combinations work well and they work fast by default. MS\(hyDOS Kermit
-is good too, but you have to tell it to go fast (by giving it the FAST
-command).
-.PP
-Furthermore, all three of these Kermit programs support "autodownload" and
-"autoupload", meaning that when they are in Connect state and a Kermit
-packet comes in from the remote, they automatically switch into file
-transfer mode.
-.PP
-And plus, C\(hyKermit and K95 also switch automatically between text and
-binary mode for each file, so there is no need to "set file type binary" or
-"set file type text", or to worry about files being corrupted because they
-were transferred in the wrong mode.
-.PP
-What all of these words add up to is that now, when you use up\(hyto\(hydate
-Kermit software from the Kermit Project, file transfer is not only fast,
-it's ridiculously easy. You barely have to give any commands at all.
-.TP
-Downloading Files
-Let's say you have Kermit 95, C\(hyKermit, or MS\(hyDOS Kermit on your
-desktop computer, with a connection to a Unix computer that has
-C\(hyKermit installed as "kermit". To download a file (send it from Unix
-to your desktop computer), just type the following command at your
-Unix shell prompt:
-.sp
- kermit \-s oofa.txt
-.sp
-(where oofa.txt is the filename). If you want to send more than one
-file, you can put as many filenames as you want on the command line,
-and they can be any combination of text and binary:
-.sp
- kermit \-s oofa.txt oofa.zip oofa.html oofa.tar.gz
-.sp
-and/or you can use wildcards to send groups of files:
-.sp
- kermit \-s oofa.*
-.sp
-If you want to send a file under an assumed name, use:
-.sp
- kermit \-s friday.txt \-a today.txt
-.sp
-This sends the file friday.txt but tells the receiving Kermit that its
-name is today.txt. In all cases, as noted, when the file transfer is
-finished, your desktop Kermit returns automatically to Connect state.
-No worries about escaping back, re\(hyconnecting, text/binary mode
-switching. Almost too easy, right?
-.TP
-Uploading Files
-To upload files (send them from your desktop computer to the remote
-Unix computer) do the same thing, but use the \-g (GET) option instead
-of \-s:
-.sp
- kermit \-g oofa.txt
-.sp
-This causes your local Kermit to enter server mode; then the remote
-Kermit program requests the named file and the local Kermit sends it
-and returns automatically to Connect state when done.
-.sp
-If you want to upload multiple files, you have have use shell quoting
-rules, since these aren't local files:
-.sp
-.nf
- kermit \-g "oofa.txt oofa.zip oofa.html oofa.tar.gz"
- kermit \-g "oofa.*"
-.fi
-.sp
-If you want to upload a file but store it under a different name, use:
-.sp
- kermit \-g friday.txt \-a today.txt
-.TP
-Kermit Transfers the Old\(hyFashioned Way
-If your desktop communications software does not support autoupload or
-autodownload, or it does not include Kermit server mode, the procedure
-requires more steps.
-.sp
-To download a file, type:
-.sp
- kermit \-s filename
-.sp
-on the host as before, but if nothing happens automatically in
-response to this command, you have to switch your desktop
-communications software into Kermit Receive state. This might be done
-by escaping back using keyboard characters or hot keys (Alt\-x is
-typical) and/or with a command (like RECEIVE) or a menu. When the file
-transfer is complete, you have to go back to Connect state, Terminal
-emulation, or whatever terminology applies to your desktop
-communications software.
-.sp
-To upload a file, type:
-.sp
- kermit \-r
-.sp
-on the host (rather than "kermit \-g"). This tells C\(hyKermit to wait
-passively for a file to start arriving. Then regain the attention of
-your desktop software (Alt\-x or whatever) and instruct it to send the
-desired file(s) with Kermit protocol. When the transfer is finished,
-return to the Connect or Terminal screen.
-.TP
-If File Transfer Fails
-Although every aspect of Kermit's operation can be finely tuned, there
-are also three short and simple "omnibus tuning" commands you can use
-for troubleshooting:
-.RS
-.TP
-FAST
-Use fast file\(hytransfer settings. This has been the default since
-C\(hyKermit 7.0 now that most modern computers and connections
-support it. If transfers fail with fast settings, try . . .
-.TP
-CAUTIOUS
-Use cautious but not paranoid settings. File transfers, if they
-work, will go at medium speed. If not, try . . .
-.TP
-ROBUST
-Use the most robust, resilient, conservative, safe, and reliable
-settings. File transfers will almost certainly work, but they
-will be quite slow (of course this is a classic tradeoff; ROBUST
-was C\(hyKermit's default tuning in versions 6.0 and earlier, which
-made everybody think Kermit protocol was slow). If ROBUST doesn't
-do the trick, try again with SET PARITY SPACE first in case it's
-not an 8\(hybit connection.
-.RE
-.sp
-Obviously the success and performance of a file transfer also depends
-on C\(hyKermit's file transfer partner. Up\(hyto\(hydate, real Kermit Project
-partners are recommended because they contain the best Kermit protocol
-implementations and because we can support them in case of trouble.
-.sp
-If you still have trouble, consult Chapter 10 of Using C\(hyKermit, or
-send email to kermit\(hysupport@columbia.edu.
-.TP
-Advanced Kermit File\(hyTransfer Features
-Obviously there is a lot more to Kermit file transfer, including all
-sorts of interactive commands, preferences, options, logging,
-debugging, troubleshooting, and anything else you can imagine but
-that's what the manual and updates are for. Here are a few topics you
-can explore if you're interested by Typing HELP for the listed
-commands:
-.RS
-.TP
-Logging transfers:
-LOG TRANSACTIONS (HELP LOG)
-.TP
-Automatic per\(hyfile text/binary mode switching:
-SET TRANSFER MODE { AUTOMATIC, MANUAL } (HELP SET TRANSFER).
-.TP
-Cross\(hyplatform recursive directory tree transfer:
-SEND /RECURSIVE, GET /RECURSIVE (HELP SEND, HELP GET).
-.TP
-File collision options:
-SET FILE COLLISION { OVERWRITE, BACKUP, DISCARD, ... } (HELP SET FILE).
-.TP
-Update: Transfer only files that changed since last time:
-SET FILE COLLISION UPDATE (HELP SET FILE).
-.TP
-Filename selection patterns:
-(HELP WILDCARD).
-.TP
-Flexible file selection:
-SEND (or GET) /BEFORE /AFTER /LARGER /SMALLER /TYPE /EXCEPT, ...
-.TP
-Character\(hyset conversion:
-SET { FILE, TRANSFER } CHARACTER\-SET, ASSOCIATE, ...
-.TP
-File/Pathname control:
-SET { SEND, RECEIVE } PATHNAMES, SET FILE NAMES.
-.TP
-Atomic file movement:
-SEND (or GET) /DELETE /RENAME /MOVE\-TO
-.TP
-Transferring to/from standard i/o of other commands:
-SEND (or GET) /COMMAND
-.TP
-Recovery of interrupted transfer from point of failure:
-RESEND, REGET (HELP RESEND, HELP REGET).
-.RE
-.TP
-Non\(hyKermit File Transfer
-You can also use C\(hyKermit to transfer files with FTP or HTTP Internet
-protocols; see below.
-.sp
-On a regular serial or Telnet connection where the other computer
-doesn't support Kermit protocol at all, you have several options. For
-example, if your desktop communications software supports Zmodem, use
-"rz" and "sz" on the host rather than Kermit. But if Kermit is your
-desktop software, and you are using it to make calls or network
-connections to other computers that don't support Kermit protocol (or
-that don't have a good implementation of it), then if your computer
-also has external X, Y, or Zmodem programs that are redirectable,
-Kermit can use them as external protocols. HELP SET PROTOCOL for
-details.
-.sp
-You can also capture "raw" data streams from the other computer with
-LOG SESSION (HELP LOG and HELP SET SESSION\-LOG for details), and you
-can upload files without any protocol at all with TRANSMIT (HELP
-TRANSMIT, HELP SET TRANSMIT).
-.SH KERMIT'S BUILT\(hyIN FTP AND HTTP CLIENTS
-Kermit's FTP client is like the regular Unix FTP client that you're used
-to, but with some differences:
-.TP
-\(bu
-It has lots more commands and features.
-.TP
-\(bu
-Each FTP command must be prefixed with "ftp", for example "ftp open",
-"ftp get", "ftp bye", etc (this is not strictly true, but until you're
-more familiar with it, it's best to follow this rule).
-.TP
-\(bu
-Commands like "cd", "directory", etc, execute locally, not on the
-server. Use "ftp cd", "ftp dir", etc, to have them act on the server.
-.TP
-\(bu
-You can have an FTP session and a regular Kermit serial or Telnet
-session open at the same time.
-.TP
-\(bu
-FTP sessions can be fully automated.
-.PP
-Pending publication of the next edition of the manual, the Kermit FTP
-client is thoroughly documented at the Kermit Project website:
-.sp
- http://www.columbia.edu/kermit/ftpclient.html
-.sp
-You also can use HELP FTP and HELP SET FTP to get descriptions of Kermit's
-FTP\(hyrelated commands.
-.PP
-The HTTP client is similar to the FTP one, except you prefix each command
-with HTTP instead of FTP: HTTP OPEN, HTTP GET, HTTP PUT, HTTP CLOSE, etc.
-Type HELP HTTP for details, or visit the to view the manual supplements.
-HTTP connections can be open at the same time as regular serial or Telnet
-connections and FTP connections. So Kermit can manage up to three types
-connections simultaneously.
-.SH INTERNET KERMIT SERVICE
-C\(hyKermit can be configured and run as an Internet service (called IKSD),
-similar to an FTP server (FTPD) except you can (but need not) interact with
-it directly, plus it does a lot more than an FTP server can do. The TCP
-port for IKSD is 1649. It uses Telnet protocol. C\(hyKermit can be an Internet
-Kermit Server, or it can be a client of an IKSD. You can make connections
-from C\(hyKermit to an IKSD with any of the following commands:
-.sp
-.nf
- telnet foo.bar.edu 1649
- telnet foo.bar.edu kermit ; if "kermit" is listed in /etc/services
- iksd foo.bar.edu
-.fi
-.sp
-The IKSD command is equivalent to a TELNET command specifying port 1649.
-For more information about making and using connections to an IKSD, see:
-.sp
- http://www.columbia.edu/kermit/cuiksd.html
-.sp
-You can run an Internet Kermit Service on your own computer too (if you are
-the system administrator). For instructions, see:
-.sp
- http://www.columbia.edu/kermit/iksd.html
-.SH SECURITY
-All of C\(hyKermit's built\(hyin TCP/IP networking methods (Telnet, Rlogin, IKSD,
-FTP, and HTTP) can be secured by one or more of the following IETF\(hyapproved
-methods:
-.PP
-\(bu MIT Kerberos IV
-.br
-\(bu MIT Kerberos V
-.br
-\(bu SSL/TLS
-.br
-\(bu Stanford SRP
-.PP
-For complete instructions see:
-.PP
- http://www.columbia.edu/kermit/security.html
-.PP
-And as noted previously, you can also make SSH connections with C\(hyKermit if
-you already have an SSH client installed.
-.SH ALTERNATIVE COMMAND\(hyLINE PERSONALITIES
-When invoked as "kermit" or any other name besides "ftp" or "telnet",
-C\(hyKermit has the command\(hyline options described above in the OPTIONS
-section. However, if you invoke C\(hyKermit as "telnet" or "ftp", it changes
-its command\(hyline personality to match. This can be done (among other ways)
-with symbolic links (symlinks). For example, if you want C\(hyKermit to be
-your regular Telnet client, or the Telnet helper of your Web browser, you
-can create a link like the following in a directory that lies in your PATH
-ahead of the regular telnet program:
-.sp
- ln \-s /usr/local/bin/kermit telnet
-.sp
-Now when you give a "telnet" command, you are invoking Kermit instead, but
-with its Telnet command\(hyline personality so, for example:
-.sp
- telnet xyzcorp.com
-.sp
-Makes a Telnet connection to xyzcorp.com, and Kermit exits automatically
-when the connection is closed (just like the regular Telnet client). Type
-"telnet \-h" to get a list of Kermit's Telnet\(hypersonality command\(hyline
-options, which are intended to be as compatible as possible with the
-regular Telnet client.
-.PP
-Similarly for FTP:
-.sp
- ln \-s /usr/local/bin/kermit ftp
-.sp
-And now type "ftp \-h" to see its command\(hyline options, and command lines
-just like you would give your regular FTP client:
-.sp
- ftp xyzcorp.com
-.sp
-but with additional options allowing an entire session to be specified on
-the command line. Finally, if Kermit's
-first command\(hyline option is a Telnet, FTP, IKSD, or HTTP URL, Kermit
-automatically makes the appropriate kind of connection and, if indicated by
-the URL, takes the desired action:
-.TP
-kermit telnet:xyzcorp.com
-Opens a Telnet session
-.TP
-kermit telnet://olga@xyzcorp.com
-Ditto for user olga
-.TP
-kermit ftp://olga@xyzcorp.com/public/oofa.zip
-Downloads a file
-.TP
-kermit kermit://kermit.columbia.edu/kermit/f/READ.ME
-Ditto for IKSD
-.TP
-kermit iksd://kermit.columbia.edu/kermit/f/READ.ME
-(This works too)
-.TP
-kermit http://www.columbia.edu/kermit/index.html
-Grabs a web page
-.fi
-.SH LICENSE
-C\(hyKermit has an unusual license, but a fair and sensible one since the
-Kermit Project must support itself out of revenue: it's not a BSD license,
-not GPL, not Artistic, not commercial, not shareware, not freeware. It can
-be summed up like this: if you want C\(hyKermit for your own use, you can
-download and use it without cost or license (but we'd appreciate it if you
-would purchase the manual). But if you want to sell C\(hyKermit or bundle it
-with a product or otherwise distribute it in a commercial setting EXCEPT
-WITH AN OPEN\(hySOURCE OPERATING SYSTEM DISTRIBUTION such as Linux, FreeBSD,
-NetBSD, or OpenBSD, you must license it. To see the complete license, give
-the LICENSE command at the prompt, or see the COPYING.TXT file distributed
-with C\(hyKermit 7.0 or later, or download it from
-.sp
- ftp://kermit.columbia.edu/kermit/c\-kermit/COPYING.TXT
-.sp
-Send licensing inquiries to kermit@columbia.edu.
-.SH BUGS
-See the following files for listings of known bugs, limitations,
-workarounds, hints and tips:
-.TP
-ckcbwr.txt
-General C\(hyKermit bugs, hints, tips.
-.TP
-ckubwr.txt
-Unix\(hyspecific C\(hyKermit bugs, hints, tips.
-.PP
-Report bugs and problems by email to:
-.sp
- kermit\-support@columbia.edu.
-.sp
-Before requesting technical support, please read the hints here:
-.sp
- http://www.columbia.edu/kermit/support.html
-.sp
-and also read the C\(hyKermit Frequently Asked Questions:
-.sp
- http://www.columbia.edu/kermit/ckfaq.html
-.SH OTHER TOPICS
-There's way more to C\(hyKermit than we've touched on here \(hy\(hy troubleshooting,
-customization, character sets, dialing directories, sending pages, script
-writing, and on and on, all of which are covered in the manual and updates
-and supplements. For the most up\(hyto\(hydate information on documentation (or
-updated documentation itself) visit the Kermit Project website:
-.sp
- http://www.columbia.edu/kermit/
-.PP
-There you will also find Kermit software packages for other platforms:
-different Unix varieties, Windows, DOS, VMS, IBM mainframes, and many
-others: 20+ years' worth.
-.SH DOCUMENTATION AND UPDATES
-The manual for C\(hyKermit is:
-.TP
-.I
-Using C\(hyKermit
-Frank da Cruz and Christine M. Gianone,
-Second Edition, Digital Press / Butterworth\(hyHeinemann, Woburn, MA, 1997, 622
-pages, ISBN 1\-55558\-164\-1. This is a printed book. It covers C\(hyKermit 6.0.
-.TP
-The C\(hyKermit 7.0 Supplement
-http://www.columbia.edu/kermit/ckermit2.html
-.TP
-The C\(hyKermit 8.0 Supplement
-http://www.columbia.edu/kermit/ckermit3.html
-.PP
-Visit C\(hyKermit home page:
-.sp
- http://www.columbia.edu/kermit/ckermit.html
-.sp
-to learn about new versions, Beta tests, and other news; to
-read case studies and tutorials; to download source code, install packages,
-and prebuilt binaries for many platforms. Also visit:
-.TP
-http://www.columbia.edu/kermit/scriptlib.html
-The Kermit script library and tutorial
-.TP
-http://www.columbia.edu/kermit/newfaq.html
-The Kermit FAQ (Frequently Asked Questions about Kermit)
-.TP
-http://www.columbia.edu/kermit/ckfaq.html
-The C\(hyKermit FAQ (Frequently Asked Questions about C\(hyKermit)
-.TP
-http://www.columbia.edu/kermit/telnet.html
-C\(hyKermit Telnet client documentation
-.TP
-http://www.columbia.edu/kermit/security.html
-C\(hyKermit security documentation (Kerberos, SSL/TLS, etc)
-.TP
-http://www.columbia.edu/kermit/cuiksd.html
-Internet Kermit Service user documentation
-.TP
-http://www.columbia.edu/kermit/iksd.html
-Internet Kermit Service administrator documentation
-.TP
-http://www.columbia.edu/kermit/studies.html
-Case studies.
-.TP
-http://www.columbia.edu/kermit/support.html
-Technical support.
-.TP
-http://www.columbia.edu/kermit/k95tutorial.html
-Kermit 95 tutorial.
-.TP
-comp.protocols.kermit.misc
-The Kermit newsgroup (unmoderated).
-.SH FILES
-.TP
-COPYING.TXT
-C\(hyKermit license.
-.TP
-~/.kermrc
-Initialization file.
-.TP
-~/.mykermrc
-Customization file.
-.TP
-~/.kdd
-Kermit dialing directory (see manual).
-.TP
-~/.knd
-Kermit network directory (see manual).
-.TP
-~/.ksd
-Kermit services directory (see manual).
-.TP
-ca_certs.pem
-Certificate Authority certifcates used for SSL connections.
-.TP
-ckuins.txt
-Installation instructions for Unix. Also at
-http://www.columbia.edu/kermit/ckuins.html.
-.TP
-ckcbwr.txt
-General C\(hyKermit bugs, hints, tips.
-.TP
-ckubwr.txt
-Unix\(hyspecific C\(hyKermit bugs, hints, tips.
-.TP
-ckcplm.txt
-C\(hyKermit program logic manual.
-.TP
-ckccfg.txt
-C\(hyKermit compile\(hytime configuration options.
-.TP
-ssh
-(in your PATH) SSH connection helper.
-.TP
-rz, sz, etc.
-(in your PATH) external protocols for XYZmodem.
-.TP
-/var/spool/locks (or whatever)
-UUCP lockfile for dialing out (see installation instructions).
-.SH AUTHORS
-.TP
-Software
-Frank da Cruz and Jeffrey E Altman,
-.br
-1985\(hypresent, with contributions from hundreds of others all over the
-world.
-.TP
-Documentation
-Frank da Cruz and Christine M Gianone
-.TP
-Address
-.nf
-The Kermit Project \(hy Columbia Univerity
-612 West 115th Street
-New York NY 10025\-7799
-USA
-.fi
-.TP
-E\(hyMail
-kermit@columbia.edu
-.TP
-Web
-http://www.columbia.edu/kermit/
-.fi
-.br
+++ /dev/null
-
-C-KERMIT 8.0 UNIX MANUAL PAGE AND TUTORIAL
-
- Frank da Cruz, Christine M. Gianone
- [1]The Kermit Project, [2]Columbia University
-
- [ [3]PDF version ] [ [4]Nroff version ]
-
- This document is intended to give the beginner sufficient
- information to make basic (if not advanced) use of C-Kermit 8.0.
- Although it might be rather long for a Unix manual page (about 1600
- lines), it's still far shorter than the C-Kermit manual, which
- should be consulted for advanced topics such as customization,
- character-sets, scripting, etc. We also attempt to provide a clear
- structural overview of C-Kermit's many capabilities, functional
- areas, states, and modes and their interrelation, that should be
- helpful to beginners and veterans alike, as well as to those
- upgrading to the new release.
-
- Most recent update: 24 October 2002
- ________________________________________________________________________
-
- CONTENTS
- * [5]DESCRIPTION
- * [6]SYNOPSIS
- * [7]OPTIONS
- * [8]COMMAND LANGUAGE
- * [9]INITIALIZATION FILE
- * [10]MODES OF OPERATION
- * [11]MAKING CONNECTIONS
- * [12]TRANSFERRING FILES WITH KERMIT
- * [13]KERMIT CLIENT/SERVER CONNECTIONS
- * [14]KERMIT'S BUILT-IN FTP AND HTTP CLIENTS
- * [15]INTERNET KERMIT SERVICE
- * [16]SECURITY
- * [17]ALTERNATIVE COMMAND-LINE PERSONALITIES
- * [18]LICENSE
- * [19]OTHER TOPICS
- * [20]DOCUMENTATION AND UPDATES
- * [21]FILES
- * [22]AUTHORS
- _________________________________________________________________
-
- DESCRIPTION [ [23]Top ] [ [24]Contents ] [ [25]Next ]
-
- [26]C-Kermit is an all-purpose communications software package from
- the [27]Kermit Project at [28]Columbia University that:
-
- * Is portable to many platforms, Unix and non-Unix alike.
- * Can make both serial and network connections.
- * Can conduct interactive terminal sessions over its connection.
- * Can transfer text or binary files over the same connection.
- * Can convert text-file character sets in terminal mode or file
- transfer.
- * Is customizable in every aspect of its operation.
-
- C-Kermit is a modem program, a Telnet client, an Rlogin client, an FTP
- client, an HTTP client, and on selected platforms, also an X.25
- client. It can make its own secure Internet connections using
- IETF-approved security methods including Kerberos IV, Kerberos V,
- SSL/TLS, and SRP and it can also make SSH (Secure Shell) connections
- through your external SSH client application. It can be the far-end
- file-transfer or client/server partner of your desktop Kermit client.
- It can also accept incoming dialed and network connections. It can
- even be installed as an Internet service on its own standard TCP
- socket, 1649 [[29]RFC2839, [30]RFC2840].
-
- And perhaps most important, everything you can do "by hand"
- (interactively) with C-Kermit, can be "scripted" (automated) using its
- built-in cross-platform transport-independent script programming
- language, which happens to be identical to its interactive command
- language.
-
- This manual page offers an overview of C-Kermit 8.0 for Unix ("Unix"
- is an operating system family that includes AIX, DG/UX, FreeBSD,
- HP-UX, IRIX, Linux, Mac OS X, NetBSD, OpenBSD, Open Server, Open Unix,
- QNX, Solaris, SunOS, System V R3, System V R4, Tru64 Unix, Unixware,
- Xenix, and many others). For thorough coverage, please consult the
- published C-Kermit manual and supplements (see [31]DOCUMENTATION
- below). For further information about C-Kermit, Kermit software for
- other platforms, and Kermit manuals, visit the Kermit Project website:
-
- [32]http://www.columbia.edu/kermit/
-
- This is a longer-than-average manual page, and yet it barely scratches
- the surface. Don't be daunted. C-Kermit is a large and complex
- package, evolving over decades of practice and experience, but that
- doesn't mean it's hard to learn or use. Its most commonly used
- functions are explained here with pointers to additional information
- elsewhere.
-
- [ [33]Kermit Home ] [ [34]C-Kermit Home ] [ [35]C-Kermit FAQ ]
- ________________________________________________________________________
-
- SYNOPSIS [ [36]Top ] [ [37]Contents ] [ [38]Next ] [ [39]Previous ]
-
- Usage: kermit [filename] [-x arg [-x arg]...[-yyy]..] [ {=,--,+} text
- ] ]
- Or: kermit URL
-
- * -x is an option requiring an argument;
- * -y is an option with no argument.
-
- If the first command-line argument is the name of a file,
- interactive-mode commands are executed from the file. The '=' (or
- "--") argument tells Kermit not to parse the remainder of the command
- line, but to make the words following '=' available as \%1, \%2, ...
- \%9. The "+" argument is like "=" but for use in "kerbang scripts"
- (explained [40]below). A second command-line format allows the one and
- only argument to be a [41]Telnet, FTP, HTTP, or IKSD URL.
-
- Order of execution:
-
- 1. [42]The command file (if any).
- 2. [43]The initialization file, if any, unless suppressed with -Y.
- 3. [44]The customization file (if it is executed by the
- initialization file).
- 4. [45]The command-line URL (if any, and if so, execution stops
- here).
- 5. [46]Command-line options (if any).
- 6. [47]Interactive commands.
-
- Some command-line options can cause actions (such as -s to send a
- file); others just set parameters. If any action options are included
- on the command line, Kermit exits when finished unless also given the
- -S ("stay") option. If no action options are given, no initialization
- or command files contained an EXIT or QUIT command, and no fatal
- errors occurred, Kermit issues its prompt and waits for you to type
- commands.
-
- Bear in mind that C-Kermit can be built with selected features
- disabled, and also that certain features are not available on all
- platforms. For example, C-Kermit can't be built with TCP/IP support
- on a platform that does not have TCP/IP header files and libraries
- (and even if Kermit does include TCP/IP support, it can't be used
- to make TCP/IP connections on a computer that does not have a
- TCP/IP stack installed). If your version of C-Kermit lacks a
- feature mentioned here, use its SHOW FEATURES command to see what
- might have been excluded.
-
- C-Kermit has three kinds of commands: regular single-letter
- command-line options, extended-format command-line options, and
- interactive commands.
-
- [ [48]Kermit Home ] [ [49]C-Kermit Home ] [ [50]C-Kermit FAQ ]
- ________________________________________________________________________
-
- OPTIONS [ [51]Top ] [ [52]Contents ] [ [53]Next ] [ [54]Previous ]
-
- Like most Unix commands, C-Kermit can be be given options on the
- command line. But C-Kermit also can be used interactively by giving it
- [55]commands composed of words, which are more intuitive than cryptic
- command-line options, and more flexible too. In other words, you don't
- have to use C-Kermit's command-line options, but they are available if
- you want to. (By the same token, you don't have to use its interactive
- commands either -- you can use either or both in any combination.)
-
- C-Kermit is generally installed in the PATH as "kermit", and therefore
- is invoked by typing the word "kermit" (lowercase) at the shell
- prompt, and then pressing the Return or Enter key. If you wish to
- include command-line options, put them after the word "kermit" but
- before pressing Return or Enter, separated by spaces, for example:
-
- $ kermit -s ckermit.tar.gz
-
- ('$' is the shell prompt; "kermit -s ckermit.tar.gz" is what you type,
- followed by Return or Enter.)
-
- Here is a list of C-Kermit's single-letter command-line options, which
- start with a single dash (-), in ASCII ("alphabetical") order.
- Alphabetic case is significant (-A is not the same as -a). The Action?
- column contains Y for action options and N for non-action options.
- Option Action? Description
- -0 N (digit zero) 100% transparent Connect state for "in-the-middle"
- operation: 8 bits, no parity, no escape character, everything passes
- through.
- -8 N (digit eight) Connection is 8-bit clean (this is the default in
- C-Kermit 8.0). Equivalent to the EIGHTBIT command, which in turn is a
- shortcut for SET TERMINAL BYTESIZE 8, SET COMMAND BYTESIZE 8, SET
- PARITY NONE.
- -9 arg N (digit nine) Make a connection to an FTP server. Equivalent
- to the FTP OPEN command.
- Argument: IP-address-or-hostname[:optional-TCP-port].
- NOTE: C-Kermit also has a separate FTP command-line personality, with
- regular FTP-like command-line syntax. [56]More about this below.
- -A N Kermit is to be started as an Internet service (IKSD) (only from
- inetd.conf).
- -B N Kermit is running in Batch or Background (no controlling
- terminal). To be used in case Kermit doesn't automatically sense its
- background status. Equivalent to the SET BACKGROUND ON command.
- -C arg N Interactive-mode Commands to be executed.
- Argument: Commands separated by commas, list in doublequotes.
- -D arg N Delay before starting to send in Remote mode. Equivalent to
- the SET DELAY command.
- Argument: Number of seconds.
- -E N Exit automatically when connection closes. Equivalent to SET EXIT
- ON-DISCONNECT ON.
- -F arg N Use an open TCP connection.
- Argument: Numeric file descriptor of open TCP connection.
- Also see: -j, -J.
- -G arg Y Get file(s) from server, send contents to standard output,
- which normally would be piped to another process.
- Argument: Remote file specification, in quotes if it contains
- metacharacters.
- Also see: -g, -k.
- -H N Suppress program startup Herald and greeting.
- -I N Tell Kermit it has a reliable connection, to force streaming to
- be used where it normally would not be. Equivalent to the SET RELIABLE
- ON command.
- -J arg N "Be like Telnet." Like -j but implies -E.
- Argument: IP hostname/address optionally followed by service.
- NOTE: C-Kermit also has a separate Telnet command-line personality,
- with regular Telnet-like command-line syntax. [57]More about this
- below.
- -L N Recursive directory descent for files in -s option.
- -M arg N My user name (for use with Telnet, Rlogin, FTP, etc).
- Equivalent to the SET LOGIN USER command.
- Argument: Username string.
- -O Y (Uppercase letter O) Be a server for One command only. Also see:
- -x.
- -P N Don't convert file (Path) names of transferred files. Equivalent
- to SET FILE NAMES LITERAL.
- -Q N Quick Kermit protocol settings. Equivalent to the FAST command.
- This is the default in C-Kermit 7.0 and later.
- -R N Remote-only (this just makes IF REMOTE true).
- -S N Stay (enter command parser after action options).
- -T N Force Text mode for file transfer; implies -V. Equivalent to SET
- TRANSFER MODE MANUAL, SET FILE TYPE TEXT.
- -V N Disable automatic per-file text/binary switching. Equivalent to
- SET TRANSFER MODE MANUAL.
- -Y N Skip (don't execute) the initialization file.
- -a arg N As-name for file(s) in -s, -r, or -g.
- Argument: As-name string (alternative filename). When receiving files,
- this can be a directory name.
- -b arg N Speed for serial device. Equivalent to SET SPEED.
- Argument: Numeric Bits per second for serial connections.
- -c Y Enter Connect state before transferring files.
- -d N Create a debug.log file with detailed debugging information (a
- second -d adds timestamps). Equivalent to LOG DEBUG but takes effect
- sooner.
- -e arg N Maximum length for incoming Kermit file-transfer packets.
- Equivalent to SET RECEIVE PACKET-LENGTH.
- Argument: Length in bytes.
- -f Y Send a FINISH command to a Kermit server.
- -g arg N Get file(s) from a Kermit server.
- Argument: File specification on other computer, in quotes if it
- contains metacharacters. Equivalent to GET.
- Also see: -a, -G, -r.
- -h Y Print Help text for single-letter command-line options (pipe thru
- 'more' to prevent scrolling).
- -i N Force binary (Image) mode for file transfer; implies -V.
- Equivalent to SET TRANSFER MODE MANUAL, SET FILE TYPE BINARY.
- -j arg N Make a TCP/IP connection.
- Argument: IP host name/address and optional service name or number.
- Equivalent to the TELNET command.
- Also see: -J, -F.
- -k Y Receive file(s) to standard output, which normally would be piped
- to another process.
- Also see: -r, -G.
- -l arg N (Lowercase letter L) Make a connection on the given serial
- communications device. Equivalent to the SET LINE (SET PORT) command.
- Argument: Serial device name, e.g. /dev/ttyS0.
- -m arg N Modem type for use with the -l device. Equivalent to the SET
- MODEM TYPE command.
- Argument: Modem name as in SET MODEM TYPE command, e.g. "usrobotics".
- -n Y Enter Connect state after transferring files (historical).
- -p arg N Parity. Equivalent to the SET PARITY command.
- Argument: One of the following: e(ven), o(dd), m(ark), n(one),
- s(pace).
- -q N Quiet (suppress most messages). Equivalent to SET QUIET ON.
- -r Y Receive file(s). Equivalent to the RECEIVE command.
- Argument: (none, but see -a)
- -s arg N Send file(s).
- Argument: One or more local file specifications. Equivalent to the
- SEND command.
- Also see: -a.
- -t N (Historical) Xon (Ctrl-Q) Turnaround character for half-duplex
- connections (used on serial linemode connections to old mainframes).
- Equivalent to SET DUPLEX HALF, SET HANDSHAKE XON.
- -v arg N Window size for Kermit protocol (ignored when streaming).
- Equivalanet to SET WINDOW-SIZE.
- Argument: Number, 1 to 32.
- -w N Incoming files Write over existing files. Equivalent to SET FILE
- COLLISION OVERWRITE.
- -x Y Enter server mode. Equivalent to the SERVER command. Also see:
- -O.
- -y arg N Alternative initialization file.
- Argument: Filename.
- -z N Force foreground behavior. To be used in case Kermit doesn't
- automatically sense its foreground status. Equivalent to the SET
- BACKGROUND OFF command.
-
- Extended command-line options (necessary because single-letter ones
- are about used up) start with two dashes (--), with words rather than
- single letters as option names. If an extended option takes an
- argument, it is separated from the option word by a colon (:).
- Extended options include:
- Option Description
- --bannerfile:filename File to display upon startup or IKSD login.
- --cdfile:filename File to be sent for display to the client when
- server changes directory (filename is relative to the changed-to
- directory).
- --cdmessage:{on,off} Enable/disable the server CD message feature.
- --help Prints usage message for extended options.
- --helpfile:filename Designates a file containing custom text to
- replace the top-level HELP command.
- --nointerrupts Disables keyboard interrupts.
- --noperms Disables the Kermit protocol file Permissions attribute, to
- prevent transmission of file permissions (protection) from sender to
- receiver.
-
- Plus several other [58]IKSD-Only options.
-
- See the [59]file-transfer section for examples of command-line
- invocation.
- ________________________________________________________________________
-
- COMMAND LANGUAGE [ [60]Top ] [ [61]Contents ] [ [62]Next ] [ [63]Previous ]
-
- * [64]Command Files, Macros, and Scripts
- * [65]Command List
-
- C-Kermit's interactive command language is the subject of a
- [66]622-page book and another several hundred pages of updates, far
- too much for a manual page. But it's not hard to get started. At the
- shell prompt, just type "kermit" to get C-Kermit's interactive command
- prompt:
-
- $ kermit
- (/current/directory) C-Kermit>
-
- Begin by typing "help" (and then press the Return or Enter key) for a
- top-level overview, read it, and go from there. Your second command
- should probably be "intro" (introduction). Note the prompt shows your
- current directory (unless you tell Kermit to prompt you with something
- else).
-
- Interactive commands are composed mainly of regular English words,
- usually in the form of imperative sentences, such as:
-
- send oofa.txt
-
- which tells Kermit to send (transfer) the file whose name is oofa.txt,
- or:
-
- set transfer mode automatic
-
- which sets Kermit's "transfer mode" to "automatic" (whatever that
- means).
-
- While typing commands, you can abbreviate, ask for help (by pressing
- the "?" key anywhere in a command), complete keywords or filenames
- (with the Tab or Esc key), and edit your typing with Backspace or
- Delete, Ctrl-W, Ctrl-U, etc. You can also recall previous commands,
- save your command history, and who knows what else. Give the INTRO
- command for details.
-
- C-Kermit has hundreds of commands, and they can be issued in infinite
- variety and combinations, including commands for:
-
- * Making connections (SET LINE, DIAL, TELNET, SSH, FTP, CONNECT,
- ...)
- * Breaking connections (HANGUP, CLOSE)
- * Transferring files (SEND, GET, RECEIVE, MOVE, RESEND, ...)
- * Establishing preferences (SET)
- * Displaying preferences (SHOW)
- * Managing local files (CD, DELETE, MKDIR, DIRECTORY, RENAME, TYPE,
- ...)
- * Managing remote files (RCD, RDEL, RMKDIR, RDIR, ...)
- * Using local files (FOPEN, FCLOSE, FREAD, FWRITE)
- * Programming (TAKE, DEFINE, IF, FOR, WHILE, SWITCH, DECLARE, ...)
- * Interacting with the user (ECHO, ASK, ...)
- * Interacting with a remote computer (INPUT, OUTPUT, ...)
- * Interacting with local programs (RUN, EXEC, PTY, ...)
- * Logging things (LOG SESSION, LOG PACKETS, LOG DEBUG, ...)
-
- And of course QUIT or EXIT to get out and HELP to get help, and for
- programmers: loops, decision making, variables, arrays, associative
- arrays, integer and floating point arithmetic, macros, built-in and
- user-defined functions, string manipulation, pattern matching, block
- structure, scoping, recursion, and all the rest. To get a list of all
- C-Kermit's commands, type a question mark (?) at the prompt. To get a
- description of any command, type HELP followed by the name of the
- command, for example:
-
- help send
-
- The command interruption character is Ctrl-C (hold down the Ctrl key
- and press the C key).
-
- The command language "escape character", used to introduce variable
- names, function invocations, and so on, is backslash (\). If you need
- to include a literal backslash in a command, type two of them, e.g.:
-
- get c:\\k95\\k95custom.ini
-
- Command Files, Macros, and Scripts
-
- A file containing Kermit commands is called a Kermit command file or
- Kermit script. It can be executed with Kermit's TAKE command:
-
- (/current/dir) C-Kermit> take commandfile
-
- (where "commandfile" is the name of the command file). Please don't
- pipe a command file into Kermit's standard input (which might or might
- not work); if you have Kermit commands in a file, tell Kermit to TAKE
- the file.
-
- In Unix only, a Kermit command file can also be executed directly by
- including a "kerbang" line as the first line of the file:
-
- #!/usr/local/bin/kermit +
-
- That is, a top line that starts with "#!", followed immediately by the
- full path of the Kermit executable, and then, if the Kermit script is
- to be given arguments on the command line, a space and a plus sign.
- The script file must also have execute permission:
-
- chmod +x commandfile
-
- Except for the " +" part, this is exactly the same as you would do for
- a shell script, a Perl script, etc. Here's a simple but useless
- example script that regurgitates its arguments (up to three of them):
-
- #!/usr/local/bin/kermit +
- if defined \%1 echo "Argument 1: \%1"
- if defined \%2 echo "Argument 2: \%2"
- if defined \%3 echo "Argument 3: \%3"
- if defined \%4 echo "etc..."
- exit
-
- If this file is stored in your current directory as "commandfile",
- then:
-
- ./commandfile one two three four five
-
- prints:
-
- Argument 1: one
- Argument 2: two
- Argument 3: three
- etc...
-
- This illustrates the basic structure of a standalone Kermit script:
- the "kerbang line", then some commands. It should end with "exit"
- unless you want the Kermit prompt to appear when it is finished. \%1
- is the first argument, \%2 the second, and so on.
-
- You can also create your own commands by defining named macros
- composed of other Kermit commands (or macros). Here's a simple
- example:
-
- define mydial {
- set modem type usrobotics
- set port /dev/ttyS0
- if fail end 1
- set speed 57600
- dial \%1
- if success connect
- }
-
- This shows how you can combine many commands into one command,
- "mydial" in this case (you can use any name you like, provided it does
- not clash with the name of a built-in command). When this macro
- definition is in effect, you can type commands like:
-
- mydial 7654321
-
- and it executes all the commands in macro definition, substituting the
- first operand ("7654321") for the formal parameter ("\%1") in the
- definition. This saves you from having to type lots of commands every
- time you want to make a modem call.
-
- One way to have the macro definition in effect is to type the
- definition at the Kermit prompt. Another way is to store the
- definition in a file and TAKE the file. If you want the the definition
- to be in effect automatically every time you start Kermit, put the
- definition in your initialization or customization file (explained
- [67]below).
-
- Here's a somewhat more ambitious example:
-
- define mydelete {
- local trash
- assign trash \v(home)trashcan/
- if not defined \%1 end 1 "Delete what?"
- if wild \%1 end 1 "Deleting multiple files is too scary"
- if not exist \%1 end 1 "I can't find \%1"
- if not directory \m(trash) {
- mkdir \m(trash)
- if fail end 1 "No trash can"
- }
- rename /list \%1 \m(trash)
- }
- define myundelete {
- local trash
- assign trash \v(home)trashcan/
- if not defined \%1 end 1 "Undelete what?"
- if wild \%1 end 1 "Undeleting multiple files is too hard"
- if not directory \m(trash) end 1 "No trash can"
- if not exist \m(trash)\%1 end 1 "I can't find \%1 in trash can"
- rename /list \m(trash)\%1 .
- }
-
- These macros are not exactly production quality (they don't handle
- filenames that include path segments, they don't handle multiple
- files, etc), but you get the idea: you can pass arguments to macros,
- they can check them and make other kinds of decisions, and the
- commands themselves are relatively intuitive and intelligible.
-
- If you put the above lines into your initialization or customization
- file, you'll have MYDELETE and MYUNDELETE commands available every
- time you start Kermit, at least as long as you don't suppress
- execution of the initialization file. (Exercise for the reader: Make
- these macros generally useful: remove limitations, add trashcan
- display, browsing, emptying, etc.)
-
- Kerbang scripts execute without the initialization file. This to keep
- them portable and also to make them start faster. If you want to write
- Kerbang scripts that depend on the initialization file, include the
- command
-
- take \v(home).kermrc
-
- at the desired spot in the script. By the way, \v(xxx) is a built-in
- variable (xxx is the variable name, "home" in this case). To see what
- built-in variables are available, type "show variables" at the
- C-Kermit prompt. To see what else you can show, type "show ?". \m(xxx)
- is a user defined variable (strictly speaking, it is a macro used as a
- variable).
-
- Command List
-
- C-Kermit has more than 200 top-level commands, and some of these, such
- as SET, branch off into hundreds of subcommands of their own, so it's
- not practical to describe them all here. Instead, here's a concise
- list of the most commonly used top-level commands, grouped by
- category. To learn about each command, type "help" followed by the
- command name, e.g. "help set". Terms such as Command state and Connect
- state are explained in subsequent sections.
-
- Optional fields are shown in [ italicized brackets ]. filename means
- the name of a single file. filespec means a file specification that is
- allowed to contain wildcard characters like '*' to match groups of
- files. options are (optional) switches like /PAGE, /NOPAGE, /QUIET,
- etc, listed in the HELP text for each command. Example:
-
- send /recursive /larger:10000 /after:-1week /except:*.txt *
-
- which can be read as "send all the files in this directory and all the
- ones underneath it that are larger than 10000 bytes, no more than one
- week old, and whose names don't end with ".txt".
-
- Basic Commands
- HELP Requests top-level help.
- HELP command Requests help about the given command.
- INTRODUCTION Requests a brief introduction to C-Kermit.
- LICENSE Displays the C-Kermit software copyright and license.
- VERSION Displays C-Kermit's version number.
- EXIT [ number ] Exits from Kermit with the given status code.
- Synonyms: QUIT, E, Q.
- TAKE filename [ parameters... ] Executes commands from the
- given file.
- LOG item [ filename ] Keeps a log of the given item in the
- given file.
- [ DO ] macro [ parameters... ] Executes commands from the
- given macro.
- SET parameter value Sets the given parameter to the given
- value.
- SHOW category Shows settings in a given category.
- STATUS Tells whether previous command succeeded or failed.
- DATE [ date-and/or-time ] Shows current date-time or interprets
- given date-time.
- RUN [ extern-command [ parameters... ] Runs the given external
- command. Synonym: !.
- EXEC [ extern-command [ params... ] Kermit overlays itself with
- the given command.
- SUSPEND Stops Kermit and puts it in the background. Synonym: Z.
-
- Local File Management
- TYPE [ options ] filename Displays the contents of the given
- file.
- MORE [ options ] filename Equivalent to TYPE /PAGE (pause after
- each screenful).
- CAT [ options ] filename Equivalent to TYPE /NOPAGE.
- HEAD [ options ] filename Displays the first few lines of a
- given file.
- TAIL [ options ] filename Displays the last few lines of a
- given file.
- GREP [ options ] pattern filespec Displays lines from files
- that match the pattern. Synonym: FIND.
- DIRECTORY [ options ] [ filespec ] Lists files (built-in, many
- options).
- LS [ options ] [ filespec ] Lists files (runs external "ls"
- command).
- DELETE [ options ] [ filespec ] Deletes files. Synonym: RM.
- PURGE [ options ] [ filespec ] Removes backup (*.~n~) files.
- COPY [ options ] [ filespecs... ] Copies files. Synonym: CP.
- RENAME [ options ] [ filespecs... ] Renames files. Synonym: MV.
- CHMOD [ options ] [ filespecs... ] Changes permissions of
- files.
- TRANSLATE filename charsets filename ] Converts file's
- character set. Synonym: XLATE.
- CD Changes your working directory to your home directory.
- CD directory Changes your working directory to the one given.
- CDUP Changes your working directory one level up.
- PWD Displays your working directory.
- BACK Returns to your previous working directory.
- MKDIR [ directory ] Creates a directory.
- RMDIR [ directory ] Removes a directory.
-
- Making Connections
- SET LINE [ options ] devicename Opens the named serial
- port. Synonym: SET PORT.
- OPEN LINE [ options ] devicename Same as SET LINE. Synonym:
- OPEN PORT.
- SET MODEM TYPE [ name ] Tells Kermit what kind of modem is on
- the port.
- DIAL [ number ] Tells Kermit to dial the given phone number
- with the modem.
- REDIAL Redials the most recently dialed phone number.
- ANSWER Waits for and answers an incoming call on the modem.
- AUTHENTICATE [ parameters... ] Performs secure authentication
- on a TCP/IP connection.
- SET NETWORK TYPE { TCP/IP, X.25, ... } Selects network type for
- subsequent SET HOST commands.
- SET HOST [ options ] host [ port ] Opens a network connection
- to the given host and port.
- SET HOST [ options ] * port Waits for an incoming TCP/IP
- connection on the given port.
- TELNET [ options ] host Opens a Telnet connection to the host
- and enters Connect state.
- RLOGIN [ options ] host Opens an Rlogin connection to the host
- and enters Connect state.
- IKSD [ options ] host Opens a connection to an Internet Kermit
- Service.
- SSH [ options ] host Opens an SSH connection to the host and
- enters Connect state.
- FTP OPEN host [ options ] Opens an FTP connection to the host.
- HTTP [ options ] OPEN host Opens an HTTP connection to the
- host.
- PTY external-command Runs the command on a pseudoterminal as if
- it were a connection.
- PIPE external-command Runs the command through a pipe as if it
- were a connection.
-
- Using Connections
- CONNECT [ options ] Enters Connect
- (terminal) state. Synonym: C.
- REDIRECT command Redirects the given external command over the
- connection.
- TELOPT command Sends a Telnet protocol command (Telnet
- connections only).
- Ctrl-\C "Escapes back" from Connect state to Command state.
- Ctrl-\B (In Connect state) Sends a BREAK signal (serial or
- Telnet).
- Ctrl-\! (In Connect state) Enters inferior shell; "exit" to
- return.
- Ctrl-\? (In Connect state) Shows a menu of other escape-level
- options.
- Ctrl-\Ctrl-\ (In Connect state) Type two Ctrl-Backslashes to
- send one of them.
- SET ESCAPE [ character ] Changes Kermit's Connect-state escape
- character.
-
- Closing Connections
- HANGUP Hangs up the currently open serial-port or network
- connection.
- CLOSE Closes the currently open serial-port or network
- connection.
- SET LINE (with no devicename) Closes the currently
- open serial-port or network connection.
- SET HOST (with no hostname) Closes the currently open
- serial-port or network connection.
- FTP CLOSE Closes the currently open FTP connection.
- HTTP CLOSE Closes the currently open HTTP connection.
- EXIT Also closes all connections. Synonym: QUIT.
- SET EXIT WARNING OFF Suppresses warning about open connections
- on exit or close.
-
- File Transfer
- SEND [ options ] filename [ as-name ] Sends the given file.
- Synonym: S.
- SEND [ options ] filespec Sends all files that match.
- RESEND [ options ] filespec Resumes an interupted SEND from the
- point of failure.
- RECEIVE [ options ] [ as-name ] Waits passively for files to
- arrive. Synonym: R.
- LOG TRANSACTIONS [ filename ] Keeps a record of file transfers.
- FAST Use fast file-transfer settings (default).
- CAUTIOUS Use cautious and less fast file-transfer settings.
- ROBUST Use ultra-conservative and slow file-transfer settings.
- STATISTICS [ options ] Gives statistics about the most recent
- file transfer.
- WHERE After transfer: "Where did my files go?".
- TRANSMIT [ options ] [ filename ] Sends file without protocol.
- Synonym: XMIT.
- LOG SESSION [ filename ] Captures remote text or files without
- protocol.
- SET PROTOCOL [ name... ] Tells Kermit to use an external
- file-transfer protocol.
- FTP { PUT, MPUT, GET, MGET, ... } FTP client commands.
- HTTP { PUT, GET, HEAD, POST, ... } HTTP client commands.
-
- Kermit Server
- ENABLE, DISABLE Controls which features
- can be used by clients.
- SET SERVER Sets parameters prior to entering Server state.
- SERVER Enters Server state.
-
- Client of Kermit or FTP Server
- [ REMOTE ] LOGIN [ user password ] Logs in to a Kermit server
- or IKSD that requires it.
- [ REMOTE ] LOGOUT Logs out from a Kermit server or IKSD.
- SEND [ options ] filename [ as-name ] Sends the given file to
- the server. Synonyms: S, PUT.
- SEND [ options ] filespec Sends all files that match.
- RESEND [ options ] filespec Resumes an interupted SEND from the
- point of failure.
- GET [ options ] remote-filespec Asks the server to send the
- given files. Synonym: G.
- REGET [ options ] remote-filespec Resumes an interrupted GET
- from the point of failure.
- REMOTE CD [ directory ] Asks server to change its working
- directory. Synonym: RCD.
- REMOTE PWD [ directory ] Asks server to display its working
- directory. Synonym: RPWD.
- REMOTE DIRECTORY [ filespec... ] Asks server to send a
- directory listing. Synonym: RDIR.
- REMOTE DELETE [ filespec... ] Asks server to delete files.
- Synonym: RDEL.
- REMOTE [ command... ] (Many other commands: "remote ?" for a
- list).
- MAIL [ options ] filespec Sends file(s) to be delivered as
- e-mail (Kermit only).
- FINISH Asks the server to exit server state (Kermit only).
- BYE Asks the server to log out and close the connection.
-
- Script Programming
- DEFINE, DECLARE, UNDEFINE, UNDECLARE, ASSIGN, EVALUATE,
- SEXPRESSION, ARRAY, SORT, INPUT, OUTPUT, IF, FOR, WHILE,
- SWITCH, GOTO, ECHO, ASK, GETC, GETOK, ASSERT, WAIT, SLEEP,
- FOPEN, FREAD, FWRITE, FCLOSE, STOP, END, RETURN, LEARN, SHIFT,
- TRACE, VOID, INCREMENT, DECREMENT, ... For these and many more
- you'll need to consult the [68]manual and supplements, and/or
- visit the [69]Kermit Script Library, which also includes a
- brief tutorial. Hint: HELP LEARN to find out how to get Kermit
- to write simple scripts for you.
-
- Many of Kermit's commands have synonyms, variants, relatives, and so
- on. For example, MSEND is a version of SEND that accepts a list of
- file specifications to be sent, rather than just one file
- specification, and MPUT is a synonym of MSEND. MOVE means to SEND and
- then DELETE the source file if successful. MMOVE is like MOVE, but
- accepts a list of filespecs, and so on. These are described in the
- [70]full documentation.
-
- Use question mark to feel your way through an unfamiliar command, as
- in this example (the part you type is underlined):
-
- C-Kermit> remote ? One of the following:
- assign delete help login print rename space
- cd directory host logout pwd rmdir type
- copy exit kermit mkdir query set who
- C-Kermit> remote set ? One of the following:
- attributes file retry transfer
- block-check receive server window
- C-Kermit> remote set file ? One of the following:
- character-set incomplete record-length
- collision names type
- C-Kermit> remote set file names ? One of the following:
- converted literal
- C-Kermit> remote set file names literal
- C-Kermit>
-
- This is called menu on demand: you get a menu when you want one, but
- menus are not forced on you even when know what you're doing. Note
- that you can also abbreviate most keywords, and you can complete them
- with the Tab or Esc key. Also note that ? works for filenames too, and
- that you can use it in the middle of a keyword or filename, not just
- at the beginning. For example, "send x?" lists all the files in the
- current directory whose names start with 'x'.
-
- [ [71]Kermit Home ] [ [72]C-Kermit Home ] [ [73]C-Kermit FAQ ]
- ________________________________________________________________________
-
- INITIALIZATION FILE [ [74]Top ] [ [75]Contents ] [ [76]Next ] [ [77]Previous
- ]
-
- In its default configuration, C-Kermit executes commands from a file
- called .kermrc in your home directory when it starts, unless it is
- given the -Y or -y command-line option. Custom configurations might
- substitute a shared system-wide initialization file. The SHOW FILE
- command tells what initialization file, if any, was used. The standard
- initialization file "chains" to an individual customization file,
- .mykermc, in the home directory, in which each user can establish
- her/his own preferences, define macros, and so on.
-
- Since execution of the initialization file (at least the standard one)
- makes C-Kermit take longer to start, it might be better not to have an
- initialization file, especially now that Kermit's default startup
- configuration is well attuned to modern computing and networking -- in
- other words, you no longer have do anything special to make Kermit
- transfers go fast. So instead of having an initialization file that is
- executed every time Kermit starts, you might consider making one or
- more kerbang scripts (with names other that .kermrc) that do NOT
- include an "exit" command, and invoke those when you need the
- settings, macro definitions, and/or scripted actions they contain, and
- invoke C-Kermit directly when you don't.
-
- To put it another way... We still distribute the standard
- initialization file since it's featured in the manual and backwards
- compatibility is important to us. But there's no harm in not using it
- if you don't need the stuff that's in it (services directory, dialing
- directory, network directory, and associated macro definitions). On
- the other hand, if there are settings or macros you want in effect
- EVERY time you use Kermit, the initialization file (or the
- customization file it chains to) is the place to put them, because
- that's the only place Kermit looks for them automatically each time
- you start it.
-
- [ [78]Kermit Home ] [ [79]C-Kermit Home ] [ [80]C-Kermit FAQ ]
- ________________________________________________________________________
-
- MODES OF OPERATION [ [81]Top ] [ [82]Contents ] [ [83]Next ] [ [84]Previous ]
-
- Kermit is said to be in Local mode if it has made a connection to
- another computer, e.g. by dialing it or establishing a Telnet
- connection to it. The other computer is remote, so if you start
- another copy of Kermit on the remote computer, it is said to be in
- Remote mode (as long as it has not made any connections of its own).
- The local Kermit communicates over the communications device or
- network connection, acting as a conduit between the the remote
- computer and your keyboard and screen. The remote Kermit is the
- file-transfer partner to the local Kermit and communicates only
- through its standard input and output.
-
- At any moment, a Kermit program can be in any of the following states.
- It's important to know what they are and how to change from one to the
- other.
-
- Command state
-
- In this state, Kermit reads commands from:
-
- + Your keyboard; or:
- + A file, or:
- + A macro definition.
-
- You can exit from Command state back to Unix with the EXIT or
- QUIT command (same thing). You can enter Connect state with any
- of various commands (CONNECT, DIAL, TELNET, etc). You can enter
- file transfer state with commands like SEND, RECEIVE, and GET.
- You can enter Server state with the SERVER command. The TAKE
- command tells Kermit to read and execute commands from a file.
- The (perhaps implied) DO command tells Kermit to read and
- execute commands from a macro definition. While in Command
- state, you can interrupt any command, macro, or command file by
- typing Ctrl-C (hold down the Ctrl key and press the C key);
- this normally brings you back to the prompt.
-
- Shell state
-
- You can invoke an inferior shell or external command from the
- Kermit command prompt by using the PUSH, RUN (!), EDIT, or
- BROWSE command. While the inferior shell or command is active,
- Kermit is suspended and does nothing. Return to Kermit Command
- state by exiting from the inferior shell or application.
-
- Connect state
-
- In this state, which can be entered only when in Local mode
- (i.e. when Kermit has made a connection to another computer),
- Kermit is acting as a terminal to the remote computer. Your
- keystrokes are sent to the remote computer and characters that
- arrive over the communication connection are displayed on your
- screen. This state is entered when you give a CONNECT, DIAL,
- TELNET, RLOGIN, or IKSD command. You can return to command
- state by logging out of the remote computer, or by typing:
-
- Ctrl-\c
-
- That is: Hold down the Ctrl key and press the backslash key,
- then let go of the Ctrl key and press the C key. This is called
- escaping back. Certain other escape-level commands are also
- provided; type Ctrl-\? for a list. For example, you can enter
- Shell state with:
-
- Ctrl-\!
-
- To send a Ctrl-\ to the host while in Connect state, type two
- of them in a row. See HELP CONNECT and HELP SET ESCAPE for more
- info.
-
- Local file-transfer state
-
- In this state, Kermit is sending packets back and forth with
- the other computer in order to transfer a file or accomplish
- some other file-related task. And at the same time, it is
- displaying its progress on your screen and watching your
- keyboard for interruptions. In this state, the following
- single-keystroke commands are accepted:
-
- X Interrupt the current file and go on to the next (if any).
- Z Interrupt the current file and skip all the rest.
- E Like Z but uses a "stronger" protocol (use if X or Z don't
- work).
- Ctrl-C Interrupt file-transfer mode (use if Z or E don't
- work).
-
- Kermit returns to its previous state (Command or Connect) when
- the transfer is complete or when interrupted successfully by X,
- Z, E, or Ctrl-C (hold down the Ctrl key and press the C key).
-
- Remote file-transfer state
-
- In this state, Kermit is exchanging file-transfer packets with
- its local partner over its standard i/o. It leaves this state
- automatically when the transfer is complete. In case you find
- your local Kermit in Connect state and the remote one in
- File-transfer state (in which it seems to ignore your
- keystrokes), you can usually return it to command state by
- typing three Ctrl-C's in a row. If that doesn't work, return
- your local Kermit to Command state (Ctrl-\ C) and type
- "e-packet" and then press the Return or Enter key; this forces
- a fatal Kermit protocol error.
-
- Remote Server state
-
- This is like Remote File-transfer state, except it never
- returns automatically to Command state. Rather, it awaits
- further instructions from the client program; that is, from
- your Local Kermit program. You can return the Remote Server to
- its previous state by issuing a "finish" command to the client,
- or if you are in Connect state, by typing three Ctrl-C's in a
- row. You can tell the server job to log out and break the
- connection by issuing a "bye" command to the client.
-
- Local Server state
-
- Like Remote-Server state, but in local mode, and therefore with
- its file-transfer display showing, and listening for single-key
- commands, as in Local File-transfer state. Usually this state
- is entered automatically when a remote Kermit program gives a
- GET command.
-
- C-Kermit, Kermit 95, and MS-DOS Kermit all can switch automatically
- from Connect state to Local File-transfer state when you initiate a
- file transfer from the remote computer by starting Kermit and telling
- it to send or get a file, in which case, Connect state is
- automatically resumed after the file transfer is finished.
-
- Note that C-Kermit is not a terminal emulator. It is a communications
- application that you run in a terminal window (e.g. console or Xterm).
- The specific emulation, such as VT100, VT220, Linux Console, or Xterm,
- is provided by the terminal window in which you are running C-Kermit.
- Kermit 95 and MS-DOS Kermit, on the other hand, are true terminal
- emulators. Why is C-Kermit not a terminal emulator? [85]CLICK HERE to
- read about it.
-
- [ [86]Kermit Home ] [ [87]C-Kermit Home ] [ [88]C-Kermit FAQ ]
- ________________________________________________________________________
-
- MAKING CONNECTIONS [ [89]Top ] [ [90]Contents ] [ [91]Next ] [ [92]Previous ]
-
- Here is how to make different kinds of connections using interactive
- Kermit commands (as noted above, you can also make connections with
- command-line options). Note that you don't have to make connections
- with Kermit. It can also be used on the far end of a connection as the
- remote file transfer and management partner of your local
- communications software.
-
- Making a Telnet Connection
-
- At the C-Kermit command prompt, simply type:
-
- telnet foo.bar.com ; Substitute desired host name or address.
- telnet xyzcorp.com 3000 ; You can also include a port number.
-
- If the connection is successful, Kermit automically enters
- Connect state. When you logout from the remote host, Kermit
- automatically returns to its prompt. More info: HELP TELNET,
- HELP SET TELNET, HELP SET TELOPT. Also see the [93]IKSD section
- below.
-
- Making an Rlogin connection
-
- This is just like Telnet, except you have to be root to do it
- because Rlogin uses a privileged TCP port:
-
- rlogin foo.bar.com ; Substitute desired host name or address.
-
- More info: HELP RLOGIN.
-
- Making an SSH Connection
-
- Unlike Telnet and Rlogin, SSH connections are not built-in, but
- handled by running your external SSH client through a
- pseudoterminal. Using C-Kermit to control the SSH client gives
- you all of Kermit's features (file transfer, character-set
- conversion, scripting, etc) over SSH.
-
- ssh foo.bar.com ; Substitute desired host name or address.
-
- More info: HELP SSH, HELP SET SSH.
-
- Dialing with a Modem
-
- If it's an external modem, make sure it is connected to a
- usable serial port on your computer with a regular
- (straight-through) modem cable, and to the telephone jack with
- a telephone cable, and that it's turned on. Then use these
- commands:
-
- set modem type usrobotics ; Or other supported type
- set line /dev/ttyS0 ; Specify device name
- set speed 57600 ; Or other desired speed
- set flow rts/cts ; Most modern modems support this
- set dial method tone ; (or pulse)
- dial 7654321 ; Dial the desired number
-
- Type "set modem type ?" for a list of supported modem types. If
- you omit the SET MODEM TYPE command, the default type is
- "generic-high-speed", which should work for most modern
- AT-command-set modems. If the line is busy, Kermit redials
- automatically. If the call does not succeed, use "set dial
- display on" and try it again to watch what happens. If the call
- succeeds, Kermit enters Connect state automatically and returns
- to its prompt automatically when you log out from the remote
- computer or the connection is otherwise lost.
-
- You can also dial from a modem that is accessible by Telnet,
- e.g. to a reverse terminal server. In this case the command
- sequence is:
-
- set host ts.xxx.com 2000 ; Terminal-server and port
- set modem type usrobotics ; Or other supported type
- set dial method tone ; (or pulse)
- dial 7654321 ; Dial the desired number
-
- If the terminal server supports the Telnet Com Port Option,
- [94]RFC 2217, you can also give serial-port related commands
- such as SET SPEED, SET PARITY, and so on, and Kermit relays
- them to the terminal server using the protocol specified in the
- RFC.
-
- More info: HELP SET MODEM, HELP SET LINE, HELP SET SPEED, HELP
- SET FLOW, HELP DIAL, HELP SET DIAL, HELP SET MODEM, HELP SET
- CARRIER-WATCH, SHOW COMMUNICATIONS, SHOW MODEM, SHOW DIAL.
-
- Direct Serial Port
-
- Connect the two computers, A and B, with a null modem cable (or
- two modem cables interconnected with a null-modem adapter or
- modem eliminator). From Computer A:
-
- set modem type none ; There is no modem
- set line /dev/ttyS0 ; Specify device name
- set carrier-watch off ; If DTR and CD are not cross-connected
- set speed 57600 ; Or other desired speed
- set flow rts/cts ; If RTS and CTS are cross-connected
- set flow xon/xoff ; If you can't use RTS/CTS
- set parity even ; (or "mark" or "space", if necessary)
- set stop-bits 2 ; (rarely necessary)
- connect ; Enter Connect (terminal) state
-
- This assumes Computer B is set up to let you log in. If it
- isn't, you can run a copy of Kermit on Computer B and follow
- approximately the same directions. More info: As above plus
- HELP CONNECT.
-
- With modems or direct serial connections, you might also have to "set
- parity even" (or "mark" or "space") if it's a 7-bit connection.
-
- Of the connection types listed above, only one can be open at a time.
- However, any one of these can be open concurrently with an [95]FTP or
- HTTP session. Each connection type can be customized to any desired
- degree, scripted, logged, you name it. See the manual.
-
- NOTE: On selected platforms, C-Kermit also can make X.25 connections.
- See the manual for details.
-
- [ [96]Kermit Home ] [ [97]C-Kermit Home ] [ [98]C-Kermit FAQ ]
- ________________________________________________________________________
-
- TRANSFERRING FILES WITH KERMIT [ [99]Top ] [ [100]Contents ] [ [101]Next ] [
- [102]Previous ]
-
- * [103]Downloading Files
- * [104]Uploading Files
- * [105]Kermit Transfers the Old-Fashioned Way
- * [106]If File Transfer Fails
- * [107]Advanced Kermit File Transfer Features
- * [108]Non-Kermit File Transfer
-
- There is a [109]widespread and persistent belief that Kermit is a slow
- protocol. This is because, until recently, it used conservative tuning
- by default to make sure file transfers succeeded, rather than failing
- because they overloaded the connection. Some extra commands (or
- command-line options, like -Q) were needed to make it go fast, but
- nobody bothered to find out about them. Also, it takes two to tango:
- most non-Kermit-Project Kermit protocol implementations really ARE
- slow. The best file-transfer partners for C-Kermit are: another copy
- of [110]C-Kermit (7.0 or later) and [111]Kermit 95. These combinations
- work well and they work fast by default. MS-DOS Kermit is good too,
- but you have to tell it to go fast (by giving it the FAST command).
-
- Furthermore, all three of these Kermit programs support "autodownload"
- and "autoupload", meaning that when they are in Connect state and a
- Kermit packet comes in from the remote, they automatically switch into
- file transfer mode.
-
- And plus, C-Kermit and K95 also switch automatically between text and
- binary mode for each file, so there is no need to "set file type
- binary" or "set file type text", or to worry about files being
- corrupted because they were transferred in the wrong mode.
-
- What all of these words add up to is that now, when you use up-to-date
- Kermit software from the Kermit Project, file transfer is not only
- fast, it's ridiculously easy. You barely have to give any commands at
- all.
-
- Downloading Files
-
- Let's say you have [112]Kermit 95, [113]C-Kermit, or
- [114]MS-DOS Kermit on your desktop computer, with a connection
- to a Unix computer that has C-Kermit installed as "kermit". To
- download a file (send it from Unix to your desktop computer),
- just type the following command at your Unix shell prompt:
-
- kermit -s oofa.txt
-
- (where oofa.txt is the filename). If you want to send more than
- one file, you can put as many filenames as you want on the
- command line, and they can be any combination of text and
- binary:
-
- kermit -s oofa.txt oofa.zip oofa.html oofa.tar.gz
-
- and/or you can use wildcards to send groups of files:
-
- kermit -s oofa.*
-
- If you want to send a file under an assumed name, use:
-
- kermit -s friday.txt -a today.txt
-
- This sends the file friday.txt but tells the receiving Kermit
- that its name is today.txt. In all cases, as noted, when the
- file transfer is finished, your desktop Kermit returns
- automatically to Connect state. No worries about escaping back,
- re-connecting, text/binary mode switching. Almost too easy,
- right?
-
- Uploading Files
-
- To upload files (send them from your desktop computer to the
- remote Unix computer) do the same thing, but use the -g (GET)
- option instead of -s:
-
- kermit -g oofa.txt
-
- This causes your local Kermit to enter server mode; then the
- remote Kermit program requests the named file and the local
- Kermit sends it and returns automatically to Connect state when
- done.
-
- If you want to upload multiple files, you have have use shell
- quoting rules, since these aren't local files:
-
- kermit -g "oofa.txt oofa.zip oofa.html oofa.tar.gz"
- kermit -g "oofa.*"
-
- If you want to upload a file but store it under a different
- name, use:
-
- kermit -g friday.txt -a today.txt
-
- Kermit Transfers the Old-Fashioned Way
-
- If your desktop communications software does not support
- autoupload or autodownload, or it does not include Kermit
- server mode, the procedure requires more steps.
-
- To download a file, type:
-
- kermit -s filename
-
- on the host as before, but if nothing happens automatically in
- response to this command, you have to switch your desktop
- communications software into Kermit Receive state. This might
- be done by escaping back using keyboard characters or hot keys
- (Alt-x is typical) and/or with a command (like RECEIVE) or a
- menu. When the file transfer is complete, you have to go back
- to Connect state, Terminal emulation, or whatever terminology
- applies to your desktop communications software.
-
- To upload a file, type:
-
- kermit -r
-
- on the host (rather than "kermit -g"). This tells C-Kermit to
- wait passively for a file to start arriving. Then regain the
- attention of your desktop software (Alt-x or whatever) and
- instruct it to send the desired file(s) with Kermit protocol.
- When the transfer is finished, return to the Connect or
- Terminal screen.
-
- If File Transfer Fails
-
- Although every aspect of Kermit's operation can be finely
- tuned, there are also three short and simple "omnibus tuning"
- commands you can use for troubleshooting:
-
- FAST
- Use fast file-transfer settings. This has been the
- default since C-Kermit 7.0 now that most modern computers
- and connections support it. If transfers fail with fast
- settings, try . . .
-
- CAUTIOUS
- Use cautious but not paranoid settings. File transfers,
- if they work, will go at medium speed. If not, try . . .
-
- ROBUST
- Use the most robust, resilient, conservative, safe, and
- reliable settings. File transfers will almost certainly
- work, but they will be quite slow (of course this is a
- classic tradeoff; ROBUST was C-Kermit's default tuning in
- versions 6.0 and earlier, which made everybody think
- Kermit protocol was slow). If ROBUST doesn't do the
- trick, try again with SET PARITY SPACE first in case it's
- not an 8-bit connection.
-
- Obviously the success and performance of a file transfer also
- depends on C-Kermit's file transfer partner. Up-to-date, real
- [115]Kermit Project partners are recommended because they
- contain the best Kermit protocol implementations and because
- [116]we can support them in case of trouble.
-
- If you still have trouble, consult Chapter 10 of [117]Using
- C-Kermit, or send email to [118]kermit-support@columbia.edu.
-
- Advanced Kermit File-Transfer Features
-
- Obviously there is a lot more to Kermit file transfer,
- including all sorts of interactive commands, preferences,
- options, logging, debugging, troubleshooting, and anything else
- you can imagine but that's what the [119]manual and updates are
- for. Here are a few topics you can explore if you're interested
- by Typing HELP for the listed commands:
-
- Logging transfers:
- LOG TRANSACTIONS (HELP LOG)
-
- Automatic per-file text/binary mode switching:
- SET TRANSFER MODE { AUTOMATIC, MANUAL } (HELP SET
- TRANSFER).
-
- Cross-platform recursive directory tree transfer:
- SEND /RECURSIVE, GET /RECURSIVE (HELP SEND, HELP GET).
-
- File collision options:
- SET FILE COLLISION { OVERWRITE, BACKUP, DISCARD, ... }
- (HELP SET FILE).
-
- Update mode (only transfer files that changed since last time):
- SET FILE COLLISION UPDATE (HELP SET FILE).
-
- Filename selection patterns:
- (HELP WILDCARD).
-
- Flexible file selection:
- SEND (or GET) /BEFORE /AFTER /LARGER /SMALLER /TYPE
- /EXCEPT, ...
-
- Character-set conversion:
- SET { FILE, TRANSFER } CHARACTER-SET, ASSOCIATE, ...
-
- File/Pathname control:
- SET { SEND, RECEIVE } PATHNAMES, SET FILE NAMES.
-
- Atomic file movement:
- SEND (or GET) /DELETE /RENAME /MOVE-TO
-
- Transferring to/from standard i/o of other commands:
- SEND (or GET) /COMMAND
-
- Recovery of interrupted transfer from point of failure:
- RESEND, REGET (HELP RESEND, HELP REGET).
-
- Non-Kermit File Transfer
-
- You can also use C-Kermit to transfer files with FTP or HTTP
- Internet protocols; [120]see below.
-
- On a regular serial or Telnet connection where the other
- computer doesn't support Kermit protocol at all, you have
- several options. For example, if your desktop communications
- software supports Zmodem, use "rz" and "sz" on the host rather
- than Kermit. But if Kermit is your desktop software, and you
- are using it to make calls or network connections to other
- computers that don't support Kermit protocol (or that don't
- have a good implementation of it), then if your computer also
- has external X, Y, or Zmodem programs that are redirectable,
- Kermit can use them as external protocols. HELP SET PROTOCOL
- for details.
-
- You can also capture "raw" data streams from the other computer
- with LOG SESSION (HELP LOG and HELP SET SESSION-LOG for
- details), and you can upload files without any protocol at all
- with TRANSMIT (HELP TRANSMIT, HELP SET TRANSMIT).
-
- [ [121]Kermit Home ] [ [122]C-Kermit Home ] [ [123]C-Kermit FAQ ]
- ________________________________________________________________________
-
- KERMIT CLIENT/SERVER CONNECTIONS [ [124]Top ] [ [125]Contents ] [ [126]Next ]
- [ [127]Previous ]
-
- On any kind of connection you can make with Kermit -- serial, TCP/IP,
- X.25, etc -- you can set up a convenient client/server relationship
- between your Kermit client (the one that made the connection) and the
- Kermit program on the far end of the connection (the remote Kermit) by
- putting the remote Kermit in server mode. This is normally done by
- giving it a SERVER command, or by starting it with the -x command-line
- option. In some cases ([128]Internet Kermit Service, SSH connections
- to a Kermit subsystem, or specially configured hosts), there is
- already a Kermit server waiting on the far end. Here is a quick
- synopsis of the commands you can give to the client for interacting
- with the server:
-
- SEND [ switches ] filename
- Sends the named file to the server. The filename can include
- wildcards. Lots of switches are available for file selection,
- etc. Type HELP SEND at the client prompt for details.
-
- GET [ switches ] filename
- Asks the server to send the named file. The filename can
- include wildcards. Type HELP GET at the client prompt for
- details.
-
- BYE
- Terminates the server and closes your connection to it.
-
- FINISH
- Terminates the server. If you started the server yourself, this
- leaves the remote host at its shell prompt. If it was a
- dedicated server (such as IKSD or an SSH subsystem), FINISH is
- equivalent to BYE.
-
- SET LOCUS { LOCAL, REMOTE, AUTO }
- (C-Kermit 8.0.201 and later, K95 1.1.21 and later) This tells
- the client whether file-management commands like CD, PWD,
- DIRECTORY, DELETE, MKDIR, etc, should be executed locally or by
- the server. In this type of connection, the default is LOCAL.
- Use SET LOCUS REMOTE if you want Kermit to behave like an FTP
- client, in which case these commands are executed remotely, and
- their local versions must have an L prefix: LCD, LPWD,
- LDIRECTORY, etc. When LOCUS is LOCAL, then the remote versions
- must have an R prefix: RCD, RPWD, RDIRECTORY, etc. HELP SET
- LOCUS for details. SHOW COMMAND to see current locus.
-
- The following commands are affected by SET LOCUS:
-
- CD, LCD, RCD
- Change (working, current) directory. HELP CD for details.
-
- CDUP, LCDUP, RCDUP
- CD one level up.
-
- DIRECTORY, LDIRECTORY, RDIRECTORY
- Produce a directory listing. Many options are available for local
- listings. HELP DIRECTORY for details.
-
- DELETE, LDELETE, RDELETE
- Deletes files or directories. Many options available, HELP DELETE.
-
- RENAME, LRENAME, RRENAME
- Renames files or directories. Many options available, HELP RENAME.
-
- MKDIR, LMKDIR, RMKDIR
- Creates a directory. HELP MKDIR.
-
- RMDIR, LRMDIR, RRMDIR
- Removes a directory. HELP RMDIR. There are dozens -- maybe hundreds --
- of other commands, described in the built-in help, on the website,
- and/or in the published or online manuals. But even if you don't have
- access to documentation, you can "set locus remote" and then use
- pretty much the same commands you would use with any FTP client.
-
- [ [129]Kermit Home ] [ [130]C-Kermit Home ] [ [131]C-Kermit FAQ ]
- ________________________________________________________________________
-
- KERMIT'S BUILT-IN FTP AND HTTP CLIENTS [ [132]Top ] [ [133]Contents ] [
- [134]Next ] [ [135]Previous ]
-
- Kermit's FTP client is like the regular Unix FTP client that you're
- used to, but with some differences:
-
- * It has lots more commands and features.
- * You can have an FTP session and a regular Kermit serial or Telnet
- session open at the same time.
- * FTP sessions can be fully automated.
-
- By default Kermit's FTP client tries its best to present the same user
- interface as a regular FTP client: PUT, GET, DIR, CD, BYE, etc, should
- work the same, even though some of these commands have different
- meaning in Kermit-to-Kermit connections; for example, CD, DIR, RENAME,
- etc, in Kermit act locally, whereas in FTP they are commands for the
- server. This might cause some confusion, but as in all things Kermit,
- you have total control:
-
- * The [136]SET LOCUS command lets you specify where file management
- commands should be executed -- locally or remotely -- for any kind
- of connection.
- * Any FTP command can be prefixed with the word "FTP" to remove any
- ambiguity.
-
- Pending publication of the next edition of the manual, the Kermit FTP
- client is thoroughly documented at the Kermit Project website:
-
- [137]http://www.columbia.edu/kermit/ftpclient.html
-
- You also can use HELP FTP and HELP SET FTP to get descriptions of
- Kermit's FTP-related commands.
-
- The HTTP client is similar to the FTP one, except you prefix each
- command with HTTP instead of FTP: HTTP OPEN, HTTP GET, HTTP PUT, HTTP
- CLOSE, etc. Type HELP HTTP for details, or visit the to view the
- [138]manual supplements. HTTP connections can be open at the same time
- as regular serial or Telnet connections and FTP connections. So Kermit
- can manage up to three types connections simultaneously.
-
- [ [139]Kermit Home ] [ [140]C-Kermit Home ] [ [141]C-Kermit FAQ ] [
- [142]FTP Client ] [ [143]HTTP Client ]
- ________________________________________________________________________
-
- INTERNET KERMIT SERVICE [ [144]Top ] [ [145]Contents ] [ [146]Next ] [
- [147]Previous ]
-
- C-Kermit can be configured and run as an Internet service (called
- IKSD), similar to an FTP server (FTPD) except you can (but need not)
- interact with it directly, plus it does a lot more than an FTP server
- can do. The TCP port for IKSD is 1649. It uses Telnet protocol.
- C-Kermit can be an Internet Kermit Server, or it can be a client of an
- IKSD. You can make connections from C-Kermit to an IKSD with any of
- the following commands:
-
- telnet foo.bar.edu 1649
- telnet foo.bar.edu kermit ; if "kermit" is listed in /etc/services
- iksd foo.bar.edu
-
- The IKSD command is equivalent to a TELNET command specifying port
- 1649. For more information about making and using connections to an
- IKSD, see:
-
- [148]http://www.columbia.edu/kermit/cuiksd.html
-
- You can run an Internet Kermit Service on your own computer too (if
- you are the system administrator). For instructions, see:
-
- [149]http://www.columbia.edu/kermit/iksd.html
-
- [ [150]Kermit Home ] [ [151]C-Kermit Home ] [ [152]C-Kermit FAQ ]
- ________________________________________________________________________
-
- SECURITY [ [153]Top ] [ [154]Contents ] [ [155]Next ] [ [156]Previous ]
-
- All of C-Kermit's built-in TCP/IP networking methods (Telnet, Rlogin,
- IKSD, FTP, and HTTP) can be secured by one or more of the following
- IETF-approved methods:
-
- * MIT Kerberos IV
- * MIT Kerberos V
- * SSL/TLS
- * Stanford SRP
-
- For complete instructions see:
-
- [157]http://www.columbia.edu/kermit/security.html
-
- And as noted previously, you can also make SSH connections with
- C-Kermit if you already have an SSH client installed.
-
- [ [158]Kermit Home ] [ [159]C-Kermit Home ] [ [160]C-Kermit FAQ ]
- ________________________________________________________________________
-
- ALTERNATIVE COMMAND-LINE PERSONALITIES [ [161]Top ] [ [162]Contents ] [
- [163]Next ] [ [164]Previous ]
-
- When invoked as "kermit" or any other name besides any of the special
- ones, C-Kermit has the command-line options described above in the
- [165]OPTIONS section. However, if you invoke C-Kermit using any of the
- following names:
-
- telnet Telnet client
- ftp FTP client
- http HTTP client
- https Secure HTTP client
-
- Kermit's command-line personality changes to match. This can be done
- (among other ways) with symbolic links (symlinks). For example, if you
- want C-Kermit to be your regular Telnet client, or the Telnet helper
- of your Web browser, you can create a link like the following in a
- directory that lies in your PATH ahead of the regular telnet program:
-
- ln -s /usr/local/bin/kermit telnet
-
- Now when you give a "telnet" command, you are invoking Kermit instead,
- but with its Telnet command-line personality so, for example:
-
- telnet xyzcorp.com
-
- Makes a Telnet connection to xyzcorp.com, and Kermit exits
- automatically when the connection is closed (just like the regular
- Telnet client). Type "telnet -h" to get a list of Kermit's
- Telnet-personality command-line options, which are intended to be as
- compatible as possible with the regular Telnet client.
-
- Similarly for FTP:
-
- ln -s /usr/local/bin/kermit ftp
-
- And now type "ftp -h" to see its command-line options, and use command
- lines just like you would give your regular FTP client:
-
- ftp -n xyzcorp.com
-
- but with additional options allowing an entire session to be specified
- on the command line, as explained in the C-Kermit [166]FTP client
- documentation.
-
- And similarly for HTTP:
-
- ln -s /usr/local/bin/kermit http
- ./http -h
- ./http www.columbia.edu -g kermit/index.html
-
- Finally, if Kermit's first command-line option is a Telnet, FTP, IKSD,
- or HTTP URL, Kermit automatically makes the appropriate kind of
- connection and, if indicated by the URL, takes the desired action:
-
- kermit telnet:xyzcorp.com ; Opens a Telnet session
- kermit telnet://olga@xyzcorp.com ; Ditto for user olga
- kermit ftp://olga@xyzcorp.com/public/oofa.zip ; Downloads a file
- kermit kermit://kermit.columbia.edu/kermit/f/READ.ME ; Ditto for IKSD
- kermit iksd://kermit.columbia.edu/kermit/f/READ.ME ; (This works too)
- kermit http://www.columbia.edu/kermit/index.html ; Grabs a web page
- kermit https://wwws.xyzcorp.com/secret/plan.html ; Grabs a secure web pag
-e
-
- [ [167]Kermit Home ] [ [168]C-Kermit Home ] [ [169]C-Kermit FAQ ]
- ________________________________________________________________________
-
- LICENSE [ [170]Top ] [ [171]Contents ] [ [172]Next ] [ [173]Previous ]
-
- C-Kermit has an unusual license, but a fair and sensible one given
- that the Kermit Project must support itself out of revenue: it's not a
- BSD license, not GPL, not Artistic, not commercial, not shareware, not
- freeware. It can be summed up like this: if you want C-Kermit for your
- own use, you can download and use it without cost or license (but we'd
- appreciate it if you would purchase the manual). But if you want to
- sell C-Kermit or bundle it with a product or otherwise distribute it
- in a commercial setting EXCEPT WITH AN OPEN-SOURCE OPERATING SYSTEM
- DISTRIBUTION such as Linux, FreeBSD, NetBSD, or OpenBSD, you must
- license it. To see the complete license, give the LICENSE command at
- the prompt, or see the COPYING.TXT file distributed with C-Kermit 7.0
- or later, or download it from
- [174]ftp://kermit.columbia.edu/kermit/c-kermit/COPYING.TXT. Send
- licensing inquiries to [175]kermit@columbia.edu.
-
- [ [176]Kermit Home ] [ [177]C-Kermit Home ] [ [178]C-Kermit FAQ ]
- ________________________________________________________________________
-
- OTHER TOPICS [ [179]Top ] [ [180]Contents ] [ [181]Next ] [ [182]Previous ]
-
- There's way more to C-Kermit than we've touched on here --
- troubleshooting, customization, character sets, dialing directories,
- sending pages, script writing, and on and on, all of which are covered
- in the manual and updates and supplements. For the most up-to-date
- information on documentation (or updated documentation itself) visit
- the Kermit Project website:
-
- [183]http://www.columbia.edu/kermit/
-
- There you will also find [184]Kermit software packages for other
- platforms: different Unix varieties, Windows, DOS, VMS, IBM
- mainframes, and many others: 20+ years' worth.
-
- [ [185]Kermit Home ] [ [186]C-Kermit Home ] [ [187]C-Kermit FAQ ]
- ________________________________________________________________________
-
- DOCUMENTATION AND UPDATES [ [188]Top ] [ [189]Contents ] [ [190]Next ] [
- [191]Previous ]
-
- The manual for C-Kermit is:
-
- 1. Frank da Cruz and Christine M. Gianone, [192]Using C-Kermit,
- Second Edition, Digital Press / Butterworth-Heinemann, Woburn, MA,
- 1997, 622 pages, ISBN 1-55558-164-1. This is a printed book. It
- covers C-Kermit 6.0.
- 2. The C-Kermit 7.0 Supplement:
- [193]http://www.columbia.edu/kermit/ckermit70.html
- 3. The C-Kermit 8.0 Supplement:
- [194]http://www.columbia.edu/kermit/ckermit80.html
-
- The C-Kermit home page is here:
-
- [195]http://www.columbia.edu/kermit/ckermit.html
-
- Visit this page to learn about new versions, Beta tests, and other
- news; to read case studies and tutorials; to download source code,
- install packages, and [196]prebuilt binaries for many platforms. Also
- visit:
-
- [197]http://www.columbia.edu/kermit/scriptlib.html
- The Kermit script library and tutorial
-
- [198]http://www.columbia.edu/kermit/newfaq.html
- The Kermit FAQ (Frequently Asked Questions about Kermit)
-
- [199]http://www.columbia.edu/kermit/ckfaq.html
- The C-Kermit FAQ (Frequently Asked Questions about C-Kermit)
-
- [200]http://www.columbia.edu/kermit/security.html
- The Kermit security reference.
-
- [201]http://www.columbia.edu/kermit/telnet.html
- C-Kermit Telnet client documentation.
-
- [202]http://www.columbia.edu/kermit/studies.html
- Case studies.
-
- [203]http://www.columbia.edu/kermit/ckcbwr.html
- General C-Kermit Hints and Tips.
-
- [204]http://www.columbia.edu/kermit/ckubwr.html
- Unix C-Kermit Hints and Tips.
-
- [205]http://www.columbia.edu/kermit/ckvbwr.html
- VMS C-Kermit Hints and Tips.
-
- [206]http://www.columbia.edu/kermit/ckuins.html
- Unix C-Kermit Installation Instructions
-
- [207]http://www.columbia.edu/kermit/ckvins.html
- VMS C-Kermit Installation Instructions
-
- [208]http://www.columbia.edu/kermit/support.html
- Technical support.
-
- [209]http://www.columbia.edu/kermit/k95tutorial.html
- Kermit 95 tutorial (this document).
-
- [210]comp.protocols.kermit.misc
- The Kermit newsgroup (unmoderated).
-
- [ [211]Kermit Home ] [ [212]C-Kermit Home ] [ [213]C-Kermit FAQ ]
- ________________________________________________________________________
-
- FILES [ [214]Top ] [ [215]Contents ] [ [216]Next ] [ [217]Previous ]
-
- [218]COPYING.TXT
- C-Kermit license.
-
- [219]~/.kermrc
- Initialization file.
-
- [220]~/.mykermrc
- Customization file.
-
- ~/.kdd
- Kermit dialing directory (see manual).
-
- ~/.knd
- Kermit network directory (see manual).
-
- ~/.ksd
- Kermit services directory (see manual).
-
- [221]ckuins.html
- Installation instructions for Unix.
-
- [222]ckcbwr.html
- General C-Kermit bugs, hints, tips.
-
- [223]ckubwr.html
- Unix-specific C-Kermit bugs, hints, tips.
-
- [224]ckcplm.html
- C-Kermit program logic manual.
-
- [225]ckccfg.html
- C-Kermit compile-time configuration options.
-
- ssh
- (in your PATH) SSH connection helper.
-
- rz, sz, etc.
- (in your PATH) external protocols for XYZmodem.
-
- /var/spool/locks (or whatever)
- UUCP lockfile for dialing out (see [226]installation
- instructions).
-
- [ [227]Kermit Home ] [ [228]C-Kermit Home ] [ [229]C-Kermit FAQ ]
- ________________________________________________________________________
-
- AUTHORS [ [230]Top ] [ [231]Contents ] [ [232]Previous ]
-
- Frank da Cruz and Jeffrey E Altman
- The Kermit Project - Columbia Univerity
- 612 West 115th Street
- New York NY 10025-7799
- USA
-
- 1985-present, with contributions from hundreds of others all over the
- world.
- _________________________________________________________________
-
-
- C-Kermit 8.0 Unix Manual Page and Tutorial /
- [233]kermit@columbia.edu / 24 October 2002
-
-References
-
- 1. http://www.columbia.edu/kermit/
- 2. http://www.columbia.edu/
- 3. http://www.columbia.edu/kermit/ckututor.pdf
- 4. ftp://kermit.columbia.edu/kermit/test/text/ckuker.nr
- 5. http://www.columbia.edu/kermit/ckututor.html#description
- 6. http://www.columbia.edu/kermit/ckututor.html#synopsis
- 7. http://www.columbia.edu/kermit/ckututor.html#options
- 8. http://www.columbia.edu/kermit/ckututor.html#commands
- 9. http://www.columbia.edu/kermit/ckututor.html#initfile
- 10. http://www.columbia.edu/kermit/ckututor.html#modes
- 11. http://www.columbia.edu/kermit/ckututor.html#connections
- 12. http://www.columbia.edu/kermit/ckututor.html#transfer
- 13. http://www.columbia.edu/kermit/ckututor.html#server
- 14. http://www.columbia.edu/kermit/ckututor.html#ftp
- 15. http://www.columbia.edu/kermit/ckututor.html#iksd
- 16. http://www.columbia.edu/kermit/ckututor.html#security
- 17. http://www.columbia.edu/kermit/ckututor.html#personae
- 18. http://www.columbia.edu/kermit/ckututor.html#license
- 19. http://www.columbia.edu/kermit/ckututor.html#other
- 20. http://www.columbia.edu/kermit/ckututor.html#documentation
- 21. http://www.columbia.edu/kermit/ckututor.html#files
- 22. http://www.columbia.edu/kermit/ckututor.html#authors
- 23. http://www.columbia.edu/kermit/ckututor.html#top
- 24. http://www.columbia.edu/kermit/ckututor.html#contents
- 25. http://www.columbia.edu/kermit/ckututor.html#synopsis
- 26. http://www.columbia.edu/kermit/ckermit.html
- 27. http://www.columbia.edu/kermit/
- 28. http://www.columbia.edu/
- 29. ftp://ftp.isi.edu/in-notes/rfc2839.txt
- 30. ftp://ftp.isi.edu/in-notes/rfc2840.txt
- 31. http://www.columbia.edu/kermit/ckututor.html#documentation
- 32. http://www.columbia.edu/kermit/
- 33. http://www.columbia.edu/kermit/
- 34. http://www.columbia.edu/kermit/ckermit.html
- 35. http://www.columbia.edu/kermit/ckfaq.html
- 36. http://www.columbia.edu/kermit/ckututor.html#top
- 37. http://www.columbia.edu/kermit/ckututor.html#contents
- 38. http://www.columbia.edu/kermit/ckututor.html#options
- 39. http://www.columbia.edu/kermit/ckututor.html#synopsis
- 40. http://www.columbia.edu/kermit/ckututor.html#kerbang
- 41. http://www.columbia.edu/kermit/ckututor.html#personae
- 42. http://www.columbia.edu/kermit/ckututor.html#kerbang
- 43. http://www.columbia.edu/kermit/ckututor.html#initfile
- 44. http://www.columbia.edu/kermit/ckututor.html#initfile
- 45. http://www.columbia.edu/kermit/ckututor.html#personae
- 46. http://www.columbia.edu/kermit/ckututor.html#options
- 47. http://www.columbia.edu/kermit/ckututor.html#commands
- 48. http://www.columbia.edu/kermit/
- 49. http://www.columbia.edu/kermit/ckermit.html
- 50. http://www.columbia.edu/kermit/ckfaq.html
- 51. http://www.columbia.edu/kermit/ckututor.html#top
- 52. http://www.columbia.edu/kermit/ckututor.html#contents
- 53. http://www.columbia.edu/kermit/ckututor.html#commands
- 54. http://www.columbia.edu/kermit/ckututor.html#description
- 55. http://www.columbia.edu/kermit/ckututor.html#commands
- 56. http://www.columbia.edu/kermit/ckututor.html#personae
- 57. http://www.columbia.edu/kermit/ckututor.html#personae
- 58. http://www.columbia.edu/kermit/ckututor.html#iksd
- 59. http://www.columbia.edu/kermit/ckututor.html#transfer
- 60. http://www.columbia.edu/kermit/ckututor.html#top
- 61. http://www.columbia.edu/kermit/ckututor.html#contents
- 62. http://www.columbia.edu/kermit/ckututor.html#initfile
- 63. http://www.columbia.edu/kermit/ckututor.html#options
- 64. http://www.columbia.edu/kermit/ckututor.html#kerbang
- 65. http://www.columbia.edu/kermit/ckututor.html#cmdlist
- 66. http://www.columbia.edu/kermit/ckututor.html#documentation
- 67. http://www.columbia.edu/kermit/ckututor.html#initfile
- 68. http://www.columbia.edu/kermit/ckututor.html#documentation
- 69. http://www.columbia.edu/kermit/ckscripts.html
- 70. http://www.columbia.edu/kermit/ckututor.html#documentation
- 71. http://www.columbia.edu/kermit/
- 72. http://www.columbia.edu/kermit/ckermit.html
- 73. http://www.columbia.edu/kermit/ckfaq.html
- 74. http://www.columbia.edu/kermit/ckututor.html#top
- 75. http://www.columbia.edu/kermit/ckututor.html#contents
- 76. http://www.columbia.edu/kermit/ckututor.html#modes
- 77. http://www.columbia.edu/kermit/ckututor.html#commands
- 78. http://www.columbia.edu/kermit/
- 79. http://www.columbia.edu/kermit/ckermit.html
- 80. http://www.columbia.edu/kermit/ckfaq.html
- 81. http://www.columbia.edu/kermit/ckututor.html#top
- 82. http://www.columbia.edu/kermit/ckututor.html#contents
- 83. http://www.columbia.edu/kermit/ckututor.html#connections
- 84. http://www.columbia.edu/kermit/ckututor.html#initfile
- 85. http://www.columbia.edu/kermit/ckfaq.html#term
- 86. http://www.columbia.edu/kermit/
- 87. http://www.columbia.edu/kermit/ckermit.html
- 88. http://www.columbia.edu/kermit/ckfaq.html
- 89. http://www.columbia.edu/kermit/ckututor.html#top
- 90. http://www.columbia.edu/kermit/ckututor.html#contents
- 91. http://www.columbia.edu/kermit/ckututor.html#transfer
- 92. http://www.columbia.edu/kermit/ckututor.html#modes
- 93. http://www.columbia.edu/kermit/ckututor.html#iksd
- 94. ftp://ftp.isi.edu/in-notes/rfc2217.txt
- 95. http://www.columbia.edu/kermit/ckututor.html#ftp
- 96. http://www.columbia.edu/kermit/
- 97. http://www.columbia.edu/kermit/ckermit.html
- 98. http://www.columbia.edu/kermit/ckfaq.html
- 99. http://www.columbia.edu/kermit/ckututor.html#top
- 100. http://www.columbia.edu/kermit/ckututor.html#contents
- 101. http://www.columbia.edu/kermit/ckututor.html#server
- 102. http://www.columbia.edu/kermit/ckututor.html#connections
- 103. http://www.columbia.edu/kermit/ckututor.html#download
- 104. http://www.columbia.edu/kermit/ckututor.html#upload
- 105. http://www.columbia.edu/kermit/ckututor.html#oldfashioned
- 106. http://www.columbia.edu/kermit/ckututor.html#trouble
- 107. http://www.columbia.edu/kermit/ckututor.html#advanced
- 108. http://www.columbia.edu/kermit/ckututor.html#nonkermit
- 109. http://www.columbia.edu/kermit/kermit.html#notslow
- 110. http://www.columbia.edu/kermit/ckermit.html
- 111. http://www.columbia.edu/kermit/k95.html
- 112. http://www.columbia.edu/kermit/k95.html
- 113. http://www.columbia.edu/kermit/ckermit.html
- 114. http://www.columbia.edu/kermit/mskermit.html
- 115. http://www.columbia.edu/kermit/
- 116. http://www.columbia.edu/kermit/support.html
- 117. http://www.columbia.edu/kermit/ckmanual.html
- 118. mailto:kermit-support@columbia.edu
- 119. http://www.columbia.edu/kermit/ckututor.html#documentation
- 120. http://www.columbia.edu/kermit/ckututor.html#ftp
- 121. http://www.columbia.edu/kermit/
- 122. http://www.columbia.edu/kermit/ckermit.html
- 123. http://www.columbia.edu/kermit/ckfaq.html
- 124. http://www.columbia.edu/kermit/ckututor.html#top
- 125. http://www.columbia.edu/kermit/ckututor.html#contents
- 126. http://www.columbia.edu/kermit/ckututor.html#ftp
- 127. http://www.columbia.edu/kermit/ckututor.html#transfer
- 128. http://www.columbia.edu/kermit/ckututor.html#iksd
- 129. http://www.columbia.edu/kermit/
- 130. http://www.columbia.edu/kermit/ckermit.html
- 131. http://www.columbia.edu/kermit/ckfaq.html
- 132. http://www.columbia.edu/kermit/ckututor.html#top
- 133. http://www.columbia.edu/kermit/ckututor.html#contents
- 134. http://www.columbia.edu/kermit/ckututor.html#iksd
- 135. http://www.columbia.edu/kermit/ckututor.html#transfer
- 136. http://www.columbia.edu/kermit/ckututor.html#server
- 137. http://www.columbia.edu/kermit/ftpclient.html
- 138. http://www.columbia.edu/kermit/ckututor.html#documentation
- 139. http://www.columbia.edu/kermit/
- 140. http://www.columbia.edu/kermit/ckermit.html
- 141. http://www.columbia.edu/kermit/ckfaq.html
- 142. http://www.columbia.edu/kermit/ckermit3.html#x3
- 143. http://www.columbia.edu/kermit/ckermit3.html#x2.2
- 144. http://www.columbia.edu/kermit/ckututor.html#top
- 145. http://www.columbia.edu/kermit/ckututor.html#contents
- 146. http://www.columbia.edu/kermit/ckututor.html#security
- 147. http://www.columbia.edu/kermit/ckututor.html#ftp
- 148. http://www.columbia.edu/kermit/cuiksd.html
- 149. http://www.columbia.edu/kermit/iksd.html
- 150. http://www.columbia.edu/kermit/
- 151. http://www.columbia.edu/kermit/ckermit.html
- 152. http://www.columbia.edu/kermit/ckfaq.html
- 153. http://www.columbia.edu/kermit/ckututor.html#top
- 154. http://www.columbia.edu/kermit/ckututor.html#contents
- 155. http://www.columbia.edu/kermit/ckututor.html#personae
- 156. http://www.columbia.edu/kermit/ckututor.html#iksd
- 157. http://www.columbia.edu/kermit/security.html
- 158. http://www.columbia.edu/kermit/
- 159. http://www.columbia.edu/kermit/ckermit.html
- 160. http://www.columbia.edu/kermit/ckfaq.html
- 161. http://www.columbia.edu/kermit/ckututor.html#top
- 162. http://www.columbia.edu/kermit/ckututor.html#contents
- 163. http://www.columbia.edu/kermit/ckututor.html#license
- 164. http://www.columbia.edu/kermit/ckututor.html#iksd
- 165. http://www.columbia.edu/kermit/ckututor.html#options
- 166. http://www.columbia.edu/kermit/ckermit3.html#x3.1.2
- 167. http://www.columbia.edu/kermit/
- 168. http://www.columbia.edu/kermit/ckermit.html
- 169. http://www.columbia.edu/kermit/ckfaq.html
- 170. http://www.columbia.edu/kermit/ckututor.html#top
- 171. http://www.columbia.edu/kermit/ckututor.html#contents
- 172. http://www.columbia.edu/kermit/ckututor.html#other
- 173. http://www.columbia.edu/kermit/ckututor.html#personae
- 174. ftp://kermit.columbia.edu/kermit/c-kermit/COPYING.TXT
- 175. mailto:kermit@columbia.edu
- 176. http://www.columbia.edu/kermit/
- 177. http://www.columbia.edu/kermit/ckermit.html
- 178. http://www.columbia.edu/kermit/ckfaq.html
- 179. http://www.columbia.edu/kermit/ckututor.html#top
- 180. http://www.columbia.edu/kermit/ckututor.html#contents
- 181. http://www.columbia.edu/kermit/ckututor.html#documentation
- 182. http://www.columbia.edu/kermit/ckututor.html#license
- 183. http://www.columbia.edu/kermit/
- 184. http://www.columbia.edu/kermit/howtoget.html
- 185. http://www.columbia.edu/kermit/
- 186. http://www.columbia.edu/kermit/ckermit.html
- 187. http://www.columbia.edu/kermit/ckfaq.html
- 188. http://www.columbia.edu/kermit/ckututor.html#top
- 189. http://www.columbia.edu/kermit/ckututor.html#contents
- 190. http://www.columbia.edu/kermit/ckututor.html#files
- 191. http://www.columbia.edu/kermit/ckututor.html#other
- 192. http://www.columbia.edu/kermit/ckmanual.html
- 193. http://www.columbia.edu/kermit/ckermit70.html
- 194. http://www.columbia.edu/kermit/ckermit80.html
- 195. http://www.columbia.edu/kermit/ckermit.html
- 196. http://www.columbia.edu/kermit/ck80binaries.html
- 197. http://www.columbia.edu/kermit/scriptlib.html
- 198. http://www.columbia.edu/kermit/newfaq.html
- 199. http://www.columbia.edu/kermit/ckfaq.html
- 200. http://www.columbia.edu/kermit/security.html
- 201. http://www.columbia.edu/kermit/telnet.html
- 202. http://www.columbia.edu/kermit/studies.html
- 203. http://www.columbia.edu/kermit/ckcbwr.html
- 204. http://www.columbia.edu/kermit/ckubwr.html
- 205. http://www.columbia.edu/kermit/ckvbwr.html
- 206. http://www.columbia.edu/kermit/ckuins.html
- 207. http://www.columbia.edu/kermit/ckvins.html
- 208. http://www.columbia.edu/kermit/support.html
- 209. http://www.columbia.edu/kermit/k95tutorial.html
- 210. news:comp.protocols.kermit.misc
- 211. http://www.columbia.edu/kermit/
- 212. http://www.columbia.edu/kermit/ckermit.html
- 213. http://www.columbia.edu/kermit/ckfaq.html
- 214. http://www.columbia.edu/kermit/ckututor.html#top
- 215. http://www.columbia.edu/kermit/ckututor.html#contents
- 216. http://www.columbia.edu/kermit/ckututor.html#authors
- 217. http://www.columbia.edu/kermit/ckututor.html#documentation
- 218. ftp://kermit.columbia.edu/kermit/c-kermit/COPYING.TXT
- 219. ftp://kermit.columbia.edu/kermit/c-kermit/ckermit.ini
- 220. ftp://kermit.columbia.edu/kermit/c-kermit/ckermod.ini
- 221. http://www.columbia.edu/kermit/ckuins.html
- 222. http://www.columbia.edu/kermit/ckcbwr.html
- 223. http://www.columbia.edu/kermit/ckubwr.html
- 224. http://www.columbia.edu/kermit/ckcplm.html
- 225. http://www.columbia.edu/kermit/ckccfg.html
- 226. http://www.columbia.edu/kermit/ckuins.html
- 227. http://www.columbia.edu/kermit/
- 228. http://www.columbia.edu/kermit/ckermit.html
- 229. http://www.columbia.edu/kermit/ckfaq.html
- 230. http://www.columbia.edu/kermit/ckututor.html#top
- 231. http://www.columbia.edu/kermit/ckututor.html#contents
- 232. http://www.columbia.edu/kermit/ckututor.html#files
- 233. mailto:kermit@columbia.edu
+++ /dev/null
-#ifdef SSHTEST
-#define SSHBUILTIN
-#endif /* SSHTEST */
-
-/* C K U U S 2 -- User interface strings & help text module for C-Kermit */
-
-/*
- Authors:
- Frank da Cruz <fdc@columbia.edu>,
- The Kermit Project, Columbia University, New York City
- Jeffrey E Altman <jaltman@secure-endpoints.com>
- Secure Endpoints Inc., New York City
-
- Copyright (C) 1985, 2004,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-
- This module contains HELP command and other long text strings.
-
- IMPORTANT: Character string constants longer than about 250 are not portable.
- Longer strings should be broken up into arrays of strings and accessed with
- hmsga() rather than hmsg().
-*/
-#include "ckcsym.h"
-#include "ckcdeb.h"
-#include "ckcnet.h"
-#include "ckcasc.h"
-#include "ckcker.h"
-#include "ckuusr.h"
-#include "ckcxla.h"
-#ifdef OS2
-#ifdef NT
-#include <windows.h>
-#else /* not NT */
-#define INCL_KBD
-#ifdef OS2MOUSE
-#define INCL_MOU
-#endif /* OS2MOUSE */
-#define INCL_DOSMISC
-#define INCL_DOSDEVICES
-#include <os2.h> /* This pulls in a whole load of stuff */
-#undef COMMENT
-#endif /* NT */
-#include "ckocon.h"
-#include "ckokvb.h"
-#include "ckokey.h"
-#endif /* OS2 */
-
-extern xx_strp xxstring;
-extern char * ccntab[];
-/*
- hlptok contains the string for which the user requested help. This is
- useful for distinguishing synonyms, in case different help text is needed
- depending on which synonym was given.
-*/
-extern char * hlptok;
-
-#ifndef NOIKSD
- extern int inserver;
-#endif /* IKSD */
-
-#ifndef NOICP
-extern int cmflgs;
-
-#ifdef DCMDBUF
-extern char *cmdbuf, *atmbuf;
-#else
-extern char cmdbuf[], atmbuf[];
-#endif /* DCMDBUF */
-#endif /* NOICP */
-
-extern char *xarg0;
-extern int nrmt, nprm, dfloc, local, parity, escape;
-extern int turn, flow;
-extern int binary, quiet, keep;
-extern int success, xaskmore;
-#ifdef OS2
-extern int tt_rows[], tt_cols[];
-#else /* OS2 */
-extern int tt_rows, tt_cols;
-#endif /* OS2 */
-extern int cmd_rows, cmd_cols;
-
-extern long speed;
-extern char *dftty, *versio, *ckxsys;
-#ifndef NOHELP
-extern char *helpfile;
-#endif /* NOHELP */
-extern struct keytab prmtab[];
-#ifndef NOXFER
-extern struct keytab remcmd[];
-#endif /* NOXFER */
-
-#ifndef NOICP
-
-/* Interactive help strings */
-
-/* Top-level HELP text. IMPORTANT: Also see tophlpi[] for IKSD. */
-
-static char *tophlp[] = {
-"Trustees of Columbia University in the City of New York.\n",
-
-#ifndef NOHELP
-" Type EXIT to exit.",
-#ifdef OS2
-" Type INTRO for a brief introduction to the Kermit Command screen.",
-" Type LICENSE to see the Kermit 95 license.",
-#else
-" Type INTRO for a brief introduction to C-Kermit.",
-" Type LICENSE to see the C-Kermit license.",
-#endif /* OS2 */
-" Type HELP followed by a command name for help about a specific command.",
-#ifndef NOPUSH
-#ifdef UNIX
-" Type MANUAL to access the C-Kermit manual page.",
-#else
-#ifdef VMS
-" Type MANUAL to access the C-Kermit help topic.",
-#else
-#ifdef OS2
-" Type MANUAL to access the K95 manual.",
-#else
-" Type MANUAL to access the C-Kermit manual.",
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* NOPUSH */
-" Type NEWS for news about new features.",
-" Type SUPPORT to learn how to get technical support.",
-" Press ? (question mark) at the prompt, or anywhere within a command,",
-" for a menu (context-sensitive help, menu on demand).",
-#else
-"Press ? for a list of commands; see documentation for detailed descriptions.",
-#endif /* NOHELP */
-
-#ifndef NOCMDL
-#ifndef NOHELP
-" ",
-" Type HELP OPTIONS for help with command-line options.",
-#endif /* NOHELP */
-#endif /* NOCMDL */
-" ",
-#ifndef OS2
-#ifdef MAC
-"Documentation for Command Window: \"Using C-Kermit\" by Frank da Cruz and",
-"Christine M. Gianone, Digital Press, 1997, ISBN: 1-55558-164-1. To order,",
-"call +1 212 854-3703 or +1 800 366-2665.",
-#else
-"DOCUMENTATION: \"Using C-Kermit\" by Frank da Cruz and Christine M. Gianone,",
-"2nd Edition, Digital Press / Butterworth-Heinemann 1997, ISBN 1-55558-164-1,",
-"plus supplements at http://www.columbia.edu/kermit/ckermit.html.",
-#endif /* MAC */
-#endif /* OS2 */
-#ifdef MAC
-" ",
-"Also see the Mac Kermit Doc and Bwr files on the Mac Kermit diskette.\n",
-#else
-#ifdef HPUX10
-" ",
-"See the files in /usr/share/lib/kermit/ for additional information.",
-#endif /* HPUX10 */
-#endif /* MAC */
-""
-};
-
-#ifndef NOIKSD
-static char *tophlpi[] = { /* Top-level help for IKSD */
-
-"Trustees of Columbia University in the City of New York.\n",
-
-#ifndef NOHELP
-" Type INTRO for a brief introduction to Kermit commands.",
-" Type VERSION for version and copyright information.",
-" Type HELP followed by a command name for help about a specific command.",
-" Type SUPPORT to learn how to get technical support.",
-" Type LOGOUT (or EXIT) to log out.",
-" Press ? (question mark) at the prompt, or anywhere within a command,",
-" for a menu (context-sensitive help, menu on demand).",
-#else
-"Press ? for a list of commands; see documentation for detailed descriptions.",
-#endif /* NOHELP */
-" ",
-"DOCUMENTATION: \"Using C-Kermit\" by Frank da Cruz and Christine M. Gianone,",
-"2nd Edition, Digital Press / Butterworth-Heinemann 1997, ISBN 1-55558-164-1.",
-"To order: +1 212 854-3703 or +1 800 366-2665. More info at the Kermit",
-
-"Project website, http://www.columbia.edu/kermit/.",
-""
-};
-#endif /* NOIKSD */
-
-#ifndef NOHELP
-char *newstxt[] = {
-#ifdef OS2
-"Welcome to Kermit 95 2.1.3. Major new features include:",
-#else
-"Welcome to C-Kermit 8.0.206. Major new features include:",
-#endif /* OS2 */
-#ifdef NT
-#ifdef KUI
-" . Runs in GUI window",
-#else
-" . GUI version available",
-#endif /* KUI */
-#endif /* NT */
-#ifdef SSHBUILTIN
-" . New built-in SSH v1 and v2 clients",
-#endif /* SSHBUILTIN */
-#ifdef NEWFTP
-" . A new built-in FTP client",
-#endif /* NEWFTP */
-#ifndef NOHTTP
-" . A new HTTP 1.1 client",
-#endif /* NOHTTP */
-#ifdef TN_COMPORT
-" . Telnet Com Port Option for dialing from Telnet modem servers",
-#endif /* TN_COMPORT */
-" . File scanning for automatic text/binary determination",
-#ifdef CKLEARN
-#ifndef OS2
-" . Learned scripts",
-#endif /* OS2 */
-#endif /* CKLEARN */
-#ifndef NOSPL
-#ifndef NOSEXP
-" . LISP-like S-Expressions and natural floating-point arithmetic",
-#endif /* NOSEXP */
-" . Lots of script programming improvements",
-#endif /* NOSPL */
-" . Performance improvements and bug fixes",
-" ",
-"Documentation:",
-" 1. \"Using C-Kermit\", second edition (1997), current with C-Kermit 6.0.",
-" 2. http://www.columbia.edu/kermit/ckermit70.html",
-" which documents the new features of C-Kermit 7.0.",
-" 3. http://www.columbia.edu/kermit/ckermit80.html",
-" which documents the new features of C-Kermit 8.0.",
-" ",
-"If the release date shown by the VERSION command is long past, be sure to",
-"check with the Kermit Project to see if there have been updates.",
-""
-};
-#endif /* NOHELP */
-
-#ifndef NOHELP
-char *introtxt[] = {
-#ifdef OS2
-"Welcome to K-95, Kermit communications software for:",
-#else
-#ifdef UNIX
-#ifdef HPUX
-"Welcome to HP-UX C-Kermit communications software for:",
-#else
-"Welcome to UNIX C-Kermit communications software for:",
-#endif /* HPUX */
-#else
-#ifdef VMS
-"Welcome to VMS C-Kermit communications software for:",
-#else
-#ifdef VOS
-"Welcome to VOS C-Kermit communications software for:",
-#else
-#ifdef MAC
-"Welcome to Mac Kermit communications software for:",
-#else
-"Welcome to C-Kermit communications software for:",
-#endif /* MAC */
-#endif /* VOS */
-#endif /* VMS */
-#endif /* UNIX */
-#endif /* OS2 */
-#ifndef NOXFER
-" . Error-free and efficient file transfer",
-#endif /* NOXFER */
-#ifndef NOLOCAL
-#ifdef OS2
-" . VT320/220/102/100/52, ANSI, Wyse, Linux, Televideo, and other emulations",
-#else
-#ifdef MAC
-" . VT220 terminal emulation",
-#else
-" . Terminal connection",
-#endif /* MAC */
-#endif /* OS2 */
-#endif /* NOLOCAL */
-#ifndef NOSPL
-" . Script programming",
-#endif /* NOSPL */
-#ifndef NOICS
-" . International character set conversion",
-#endif /* NOICS */
-#ifndef NODIAL
-#ifndef NOSPL
-" . Numeric and alphanumeric paging",
-#endif /* NOSPL */
-#endif /* NODIAL */
-
-#ifndef NOLOCAL
-" ",
-"Supporting:",
-" . Serial connections, direct or dialed.",
-#ifndef NODIAL
-" . Automatic modem dialing",
-#endif /* NODIAL */
-#ifdef TCPSOCKET
-" . TCP/IP network connections:",
-#ifdef TNCODE
-" - Telnet sessions",
-#endif /* TNCODE */
-#ifdef SSHBUILTIN
-" - SSH v1 and v2 connections",
-#else
-#ifdef ANYSSH
-" - SSH connections via external agent",
-#endif /* ANYSSH */
-#endif /* SSHBUILTIN */
-#ifdef RLOGCODE
-" - Rlogin sessions",
-#endif /* RLOGCODE */
-#ifdef NEWFTP
-" - FTP sessions",
-#endif /* NEWFTP */
-#ifdef CKHTTP
-" - HTTP 1.1 sessions",
-#endif /* CKHTTP */
-#ifdef IKSD
-" - Internet Kermit Service",
-#endif /* IKSD */
-#endif /* TCPSOCKET */
-#ifdef ANYX25
-" . X.25 network connections",
-#endif /* ANYX25 */
-#ifdef OS2
-#ifdef DECNET
-" . DECnet/PATHWORKS LAT Ethernet connections",
-#endif /* DECNET */
-#ifdef SUPERLAT
-" . Meridian Technologies' SuperLAT connections",
-#endif /* SUPERLAT */
-#ifdef NPIPE
-" . Named-pipe connections",
-#endif /* NPIPE */
-#ifdef CK_NETBIOS
-" . NETBIOS connections",
-#endif /* CK_NETBIOS */
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
-" ",
-"While typing commands, you may use the following special characters:",
-" . DEL, RUBOUT, BACKSPACE, CTRL-H: Delete the most recent character typed.",
-" . CTRL-W: Delete the most recent word typed.",
-" . CTRL-U: Delete the current line.",
-" . CTRL-R: Redisplay the current line.",
-
-#ifdef CK_RECALL
-#ifdef OS2
-" . Uparrow: Command recall - go backwards in command recall buffer.",
-" . Downarrow: Command recall - go forward in command recall buffer.",
-#ifndef NOIKSD
-" (Note: Arrow keys can be used only on the PC's physical keyboard.)",
-#endif /* NOIKSD */
-#endif /* OS2 */
-" . CTRL-P: Command recall - go backwards in command recall buffer.",
-" . CTRL-B: Command recall - same as Ctrl-P.",
-" . CTRL-N: Command recall - go forward in command recall buffer.",
-#endif /* CK_RECALL */
-
-" . ? (question mark) Display a menu for the current command field."
-,
-" . ESC (or TAB) Attempt to complete the current field.",
-" . \\ (backslash) include the following character literally",
-#ifndef NOSPL
-" or introduce a backslash code, variable, or function.",
-#else
-" or introduce a numeric backslash code.",
-#endif /* NOSPL */
-" ",
-
-"IMPORTANT: Since backslash (\\) is Kermit's command-line escape character,",
-"you must enter DOS, Windows, or OS/2 pathnames using either forward slash (/)"
-,
-"or double backslash (\\\\) as the directory separator in most contexts.",
-"Examples: C:/TMP/README.TXT, C:\\\\TMP\\\\README.TXT.",
-" ",
-
-"Command words other than filenames can be abbreviated in most contexts.",
-" ",
-
-"Basic commands:",
-" EXIT Exit from Kermit",
-" HELP Request general help",
-" HELP command Request help about the given command",
-" TAKE Execute commands from a file",
-" TYPE Display a file on your screen",
-" ORIENTATION Explains directory structure",
-" ",
-
-#ifndef NOXFER
-"Commands for file transfer:",
-" SEND Send files",
-" RECEIVE Receive files",
-" GET Get files from a Kermit server",
-#ifdef CK_RESEND
-" RESEND Recover an interrupted send",
-" REGET Recover an interrupted get from a server",
-#endif /* CK_RESEND */
-#ifndef NOSERVER
-" SERVER Be a Kermit server",
-#endif /* NOSERVER */
-" ",
-"File-transfer speed selection:",
-" FAST Use fast settings -- THIS IS THE DEFAULT",
-" CAUTIOUS Use slower, more cautious settings",
-" ROBUST Use extremely slow and cautious settings",
-" ",
-"File-transfer performance fine tuning:",
-" SET RECEIVE PACKET-LENGTH Kermit packet size",
-" SET WINDOW Number of sliding window slots",
-" SET PREFIXING Amount of control-character prefixing",
-#endif /* NOXFER */
-
-#ifndef NOLOCAL
-" ",
-"To make a direct serial connection:",
-#ifdef OS2
-#ifdef NT
-#ifdef CK_TAPI
-" SET PORT TAPI Select TAPI communication device",
-#endif /* CK_TAPI */
-" SET PORT Select serial communication device",
-#else
-" SET PORT Select serial communication port or server",
-#endif /* NT */
-#else
-" SET LINE Select serial communication device",
-#endif /* OS2 */
-" SET SPEED Select communication speed",
-" SET PARITY Communications parity (if necessary)",
-#ifdef CK_RTSCTS
-" SET FLOW Communications flow control, such as RTS/CTS",
-#else
-" SET FLOW Communications flow control, such as XON/XOFF",
-#endif /* CK_RTSCTS */
-" CONNECT Begin terminal connection",
-
-#ifndef NODIAL
-" ",
-"To dial out with a modem:",
-" SET DIAL DIRECTORY Specify dialing directory file (optional)",
-" SET DIAL COUNTRY-CODE Country you are dialing from (*)",
-" SET DIAL AREA-CODE Area-code you are dialing from (*)",
-" LOOKUP Lookup entries in your dialing directory (*)",
-" SET MODEM TYPE Select modem type",
-#ifdef OS2
-#ifdef NT
-#ifdef CK_TAPI
-" SET PORT TAPI Select TAPI communication device",
-#endif /* CK_TAPI */
-" SET PORT Select serial communication device",
-#else
-" SET PORT Select serial communication port or server",
-#endif /* NT */
-#else
-" SET LINE Select serial communication device",
-#endif /* OS2 */
-" SET SPEED Select communication speed",
-" SET PARITY Communications parity (if necessary)",
-" DIAL Dial the phone number",
-" CONNECT Begin terminal connection",
-" ",
-#ifdef OS2
-"Further info: HELP DIAL, HELP SET MODEM, HELP SET PORT, HELP SET DIAL",
-#else
-"Further info: HELP DIAL, HELP SET MODEM, HELP SET LINE, HELP SET DIAL",
-#endif /* OS2 */
-"(*) (For use with optional dialing directory)",
-#endif /* NODIAL */
-
-#ifdef NETCONN
-" ",
-"To make a network connection:",
-#ifndef NODIAL
-" SET NETWORK DIRECTORY Specify a network services directory (optional)",
-" LOOKUP Lookup entries in your network directory",
-#endif /* NODIAL */
-" SET NETWORK TYPE Select network type (if more than one available)",
-" SET HOST Make a network connection but stay in command mode",
-" CONNECT Begin terminal connection",
-#ifdef TNCODE
-" TELNET Select a Telnet host and CONNECT to it",
-#endif /* TNCODE */
-#ifdef RLOGCODE
-" RLOGIN Select an Rlogin host and CONNECT to it",
-#endif /* RLOGCODE */
-#ifdef ANYSSH
-" SSH [ OPEN ] Select an SSH host and CONNECT to it",
-#endif /* ANYSSH */
-#ifdef NEWFTP
-" FTP [ OPEN ] Make an FTP connection",
-#endif /* NEWFTP */
-#ifdef CKHTTP
-" HTTP OPEN Make an HTTP connection",
-#endif /* CKHTTP */
-#endif /* NETCONN */
-
-#ifdef NT
-" ",
-"To return from the terminal window to the K-95> prompt:",
-#else
-#ifdef OS2
-" ",
-"To return from the terminal window to the K/2> prompt:",
-#else
-" ",
-"To return from a terminal connection to the C-Kermit prompt:",
-#endif /* OS2 */
-#endif /* NT */
-#ifdef OS2
-" \
-Press the key or key-combination shown after \"Command:\" in the status line",
-" (such as Alt-x) or type your escape character followed by the letter C.",
-#else
-" Type your escape character followed by the letter C.",
-#endif /* OS2 */
-" ",
-"To display your escape character:",
-" SHOW ESCAPE",
-" ",
-"To display other settings:",
-" SHOW COMMUNICATIONS, SHOW TERMINAL, SHOW FILE, SHOW PROTOCOL, etc.",
-#else /* !NOLOCAL */
-" ",
-"To display settings:",
-" SHOW COMMUNICATIONS, SHOW FILE, SHOW PROTOCOL, etc.",
-#endif /* NOLOCAL */
-" ",
-#ifdef OS2
-"For a Kermit 95 tutorial, visit:",
-" http://www.columbia.edu/kermit/k95tutor.html",
-" ",
-#endif /* OS2 */
-"For a C-Kermit tutorial, visit:",
-" http://www.columbia.edu/kermit/ckututor.html",
-" ",
-"To learn about script programming and automation:",
-" Read the manual, \"Using C-Kermit\". For a brief tutorial, visit:",
-" http://www.columbia.edu/kermit/ckscripts.html",
-" ",
-"For further information about a particular command, type HELP xxx,",
-"where xxx is the name of the command. For documentation, news of new",
-"releases, and information about other Kermit software, contact:",
-" ",
-" The Kermit Project E-mail: kermit@columbia.edu",
-" Columbia University Web: http://www.columbia.edu/kermit/",
-" 612 West 115th Street Voice: +1 (212) 854-3703",
-" New York NY 10025-7799 Fax: +1 (212) 662-6442",
-" USA",
-""
-};
-
-static char * hmxymatch[] = {
-"SET MATCH { DOTFILE, FIFO } { ON, OFF }",
-" Tells whether wildcards should match dotfiles (files whose names begin",
-" with period) or UNIX FIFO special files. MATCH FIFO default is OFF.",
-" MATCH DOTFILE default is OFF in UNIX, ON elsewhere.",
-""
-};
-
-#ifdef OS2
-#ifdef KUI
-static char * hmxygui[] = {
-"SET GUI DIALOGS { ON, OFF }",
-" ON means that popups, alerts, use GUI dialogs; OFF means to use",
-" text-mode popups or prompts. ON by default.",
-" ",
-"SET GUI FONT name size",
-" Chooses the font and size. Type \"set gui font ?\" to see the list of",
-" choices. The size can be a whole number or can contain a decimal point",
-" and a fraction (which is rounded to the nearest half point).",
-" ",
-"SET GUI RGBCOLOR colorname redvalue greenvalue bluevalue",
-" Specifies the red-green-blue mixture to be used to render the given",
-" color name. Type \"set gui rgbcolor\" to see a list of colornames.",
-" the RGB values are whole numbers from 0 to 255.",
-" ",
-"SET GUI WINDOW POSITION x y",
-" Moves the K95 window to the given X,Y coordinates, pixels from top left.",
-" (Not yet implemented -- use command-line options to do this.)",
-" ",
-"SET GUI WINDOW RESIZE-MODE { CHANGE-DIMENSIONS, SCALE-FONT }",
-" Default is CHANGE-DIMENSIONS.",
-"",
-"SET GUI WINDOW RUN-MODE { MAXIMIZE, MINIMIZE, RESTORE }",
-" Changes the run mode state of the GUI window.",
-""
-};
-#endif /* KUI */
-#endif /* OS2 */
-
-#ifdef ANYSSH
-static char * hmxxssh[] = {
-#ifdef SSHBUILTIN
-"Syntax: SSH { ADD, AGENT, CLEAR, KEY, [ OPEN ], V2 } operands...",
-" Performs an SSH-related action, depending on the keyword that follows:",
-" ",
-"SSH ADD LOCAL-PORT-FORWARD local-port host port",
-" Adds a port forwarding triplet to the local port forwarding list.",
-" The triplet specifies a local port to be forwarded and the hostname /",
-" ip-address and port number to which the port should be forwarded from",
-" the remote host. Port forwarding is activated at connection",
-" establishment and continues until the connection is terminated.",
-" ",
-"SSH ADD REMOTE-PORT-FORWARD remote-port host port",
-" Adds a port forwarding triplet to the remote port forwarding list.",
-" The triplet specifies a remote port to be forwarded and the",
-" hostname/ip-address and port number to which the port should be",
-" forwarded from the local machine. Port forwarding is activated at",
-" connection establishment and continues until the connection is",
-" terminated.",
-" ",
-"SSH AGENT ADD [ identity-file ]",
-" Adds the contents of the identity-file (if any) to the SSH AGENT",
-" private key cache. If no identity-file is specified, all files",
-" specified with SET SSH IDENTITY-FILE are added to the cache.",
-" ",
-"SSH AGENT DELETE [ identity-file ]",
-" Deletes the contents of the identity-file (if any) from the SSH AGENT",
-" private key cache. If no identity-file is specified, all files",
-" specified with SET SSH IDENTITY-FILE are deleted from the cache.",
-" ",
-"SSH AGENT LIST [ /FINGERPRINT ]",
-" Lists the contents of the SSH AGENT private key cache. If /FINGERPRINT",
-" is specified, the fingerprint of the private keys are displayed instead",
-" of the keys.",
-" ",
-"SSH CLEAR LOCAL-PORT-FORWARD",
-" Clears the local port forwarding list.",
-" ",
-"SSH CLEAR REMOTE-PORT-FORWARD",
-" Clears the remote port forwarding list.",
-" ",
-"SSH KEY commands:",
-" The SSH KEY commands create and manage public and private key pairs",
-" (identities). There are three forms of SSH keys. Each key pair is",
-" stored in its own set of files:",
-" ",
-" Key Type Private Key File Public Key File",
-" v1 RSA keys \\v(appdata)ssh/identity \\v(appdata)ssh/identity.pub",
-" v2 RSA keys \\v(appdata)ssh/id_rsa \\v(appdata)ssh/id_rsa.pub",
-" v2 DSA keys \\v(appdata)ssh/id_dsa \\v(appdata)ssh/id_dsa.pub",
-" ",
-" Keys are stored using the OpenSSH keyfile format. The private key",
-" files can be (optionally) protected by specifying a passphrase. A",
-" passphrase is a longer version of a password. English text provides",
-" no more than 2 bits of key data per character. 56-bit keys can be",
-" broken by a brute force attack in approximately 24 hours. When used,",
-" private key files should therefore be protected by a passphrase of at",
-" least 40 characters (about 80 bits).",
-" ",
-" To install a public key file on the host, you must transfer the file",
-" to the host and append it to your \"authorized_keys\" file. The file",
-" permissions must be 600 (or equivalent).",
-" ",
-"SSH KEY CHANGE-PASSPHRASE [ /NEW-PASSPHRASE:passphrase",
-" /OLD-PASSPHRASE:passphrase ] filename",
-" This re-encrypts the specified private key file with a new passphrase.",
-" The old passphrase is required. If the passphrases (and filename) are",
-" not provided Kermit prompts your for them.",
-" ",
-"SSH KEY CREATE [ /BITS:bits /PASSPHRASE:passphrase",
-" /TYPE:{ V1-RSA, V2-DSA, V2-RSA } /V1-RSA-COMMENT:comment ] filename",
-" This command creates a new private/public key pair. The defaults are:",
-" BITS:1024 and TYPE:V2-RSA. The filename is the name of the private",
-" key file. The public key is created with the same name with .pub",
-" appended to it. If a filename is not specified Kermit prompts you for",
-" it. V1 RSA key files may have an optional comment, which is ignored",
-" for other key types.",
-" ",
-"SSH KEY DISPLAY [ /FORMAT:{FINGERPRINT,IETF,OPENSSH,SSH.COM} ] filename",
-" This command displays the contents of a public or private key file.",
-" The default format is OPENSSH.",
-" ",
-"SSH KEY V1 SET-COMMENT filename comment",
-" This command replaces the comment associated with a V1 RSA key file.",
-" ",
-"SSH [ OPEN ] host [ port ] [ /COMMAND:command /USER:username",
-" /PASSWORD:pwd /VERSION:{ 1, 2 } /X11-FORWARDING:{ ON, OFF } ]",
-" This command establishes a new connection using SSH version 1 or",
-" version 2 protocol. The connection is made to the specified host on",
-" the SSH port (you can override the port by including a port name or",
-" number after the host name). Once the connection is established the",
-" authentication negotiations begin. If the authentication is accepted,",
-" the local and remote port forwarding lists are used to establish the",
-" desired connections. If X11 Forwarding is active, this results in a",
-" remote port forwarding between the X11 clients on the remote host and",
-" X11 Server on the local machine. If a /COMMAND is provided, the",
-" command is executed on the remote host in place of your default shell.",
-" ",
-" An example of a /COMMAND to execute C-Kermit in SERVER mode is:",
-" SSH OPEN hostname /COMMAND:{kermit -x -l 0}",
-" ",
-"SSH V2 REKEY",
-" Requests that an existing SSH V2 connection generate new session keys.",
-#else /* SSHBUILTIN */
-"Syntax: SSH [ options ] <hostname> [ command ]",
-" Makes an SSH connection using the external ssh program via the SET SSH",
-" COMMAND string, which is \"ssh -e none\" by default. Options for the",
-" external ssh program may be included. If the hostname is followed by a",
-" command, the command is executed on the host instead of an interactive",
-" shell.",
-#endif /* SSHBUILTIN */
-""
-};
-
-static char *hmxyssh[] = {
-#ifdef SSHBUILTIN
-"SET SSH AGENT-FORWARDING { ON, OFF }",
-" If an authentication agent is in use, setting this value to ON",
-" results in the connection to the agent being forwarded to the remote",
-" computer. The default is OFF.",
-" ",
-"SET SSH CHECK-HOST-IP { ON, OFF }",
-" Specifies whether the remote host's ip-address should be checked",
-" against the matching host key in the known_hosts file. This can be",
-" used to determine if the host key changed as a result of DNS spoofing.",
-" The default is ON.",
-" ",
-"SET SSH COMPRESSION { ON, OFF }",
-" Specifies whether compression will be used. The default is ON.",
-" ",
-"SET SSH DYNAMIC-FORWARDING { ON, OFF }",
-" Specifies whether Kermit is to act as a SOCKS4 service on port 1080",
-" when connected to a remote host via SSH. When Kermit acts as a SOCKS4",
-" service, it accepts connection requests and forwards the connections",
-" through the remote host. The default is OFF.",
-" ",
-"SET SSH GATEWAY-PORTS { ON, OFF }",
-" Specifies whether Kermit should act as a gateway for forwarded",
-" connections received from the remote host. The default is OFF.",
-" ",
-"SET SSH GSSAPI DELEGATE-CREDENTIALS { ON, OFF }",
-" Specifies whether Kermit should delegate GSSAPI credentials to ",
-" the remote host after authentication. Delegating credentials allows",
-" the credentials to be used from the remote host. The default is OFF.",
-" ",
-"SET SSH HEARTBEAT-INTERVAL <seconds>",
-" Specifies a number of seconds of idle time after which an IGNORE",
-" message will be sent to the server. This pulse is useful for",
-" maintaining connections through HTTP Proxy servers and Network",
-" Address Translators. The default is OFF (0 seconds).",
-" ",
-"SET SSH IDENTITY-FILE filename [ filename [ ... ] ]",
-" Specifies one or more files from which the user's authorization",
-" identities (private keys) are to be read when using public key",
-" authorization. These are files used in addition to the default files:",
-" ",
-" \\v(appdata)ssh/identity V1 RSA",
-" \\v(appdata)ssh/id_rsa V2 RSA",
-" \\v(appdata)ssh/id_dsa V2 DSA",
-" ",
-"SET SSH KERBEROS4 TGT-PASSING { ON, OFF }",
-" Specifies whether Kermit should forward Kerberos 4 TGTs to the host.",
-" The default is OFF.",
-" ",
-"SET SSH KERBEROS5 TGT-PASSING { ON, OFF }",
-" Specifies whether Kermit should forward Kerberos 5 TGTs to to the",
-" host. The default is OFF.",
-" ",
-"SET SSH PRIVILEGED-PORT { ON, OFF }",
-" Specifies whether a privileged port (less than 1024) should be used",
-" when connecting to the host. Privileged ports are not required except",
-" when using SSH V1 with Rhosts or RhostsRSA authorization. The default",
-" is OFF.",
-" ",
-"SET SSH QUIET { ON, OFF }",
-" Specifies whether all messages generated in conjunction with SSH",
-" protocols should be suppressed. The default is OFF.",
-" ",
-"SET SSH STRICT-HOST-KEY-CHECK { ASK, ON, OFF }",
-" Specifies how Kermit should behave if the the host key check fails.",
-" When strict host key checking is OFF, the new host key is added to the",
-" protocol-version-specific user-known-hosts-file. When strict host key",
-" checking is ON, the new host key is refused and the connection is",
-" dropped. When set to ASK, Kermit prompt you to say whether the new",
-" host key should be accepted. The default is ASK.",
-" ",
-" Strict host key checking protects you against Trojan horse attacks.",
-" It depends on you to maintain the contents of the known-hosts-file",
-" with current and trusted host keys.",
-" ",
-"SET SSH USE-OPENSSH-CONFIG { ON, OFF }",
-" Specifies whether Kermit should parse an OpenSSH configuration file",
-" after applying Kermit's SET SSH commands. The configuration file",
-" would be located at \\v(home)ssh/ssh_config. The default is OFF.",
-" ",
-"SET SSH V1 CIPHER { 3DES, BLOWFISH, DES }",
-" Specifies which cipher should be used to protect SSH version 1",
-" connections. The default is 3DES.",
-" ",
-"SET SSH V1 GLOBAL-KNOWN-HOSTS-FILE filename",
-" Specifies the location of the system-wide known-hosts file. The",
-" default is:",
-" ",
-" \v(common)ssh_known_hosts",
-" ",
-"SET SSH V1 USER-KNOWN-HOSTS-FILE filename",
-" Specifies the location of the user-known-hosts-file. The default",
-" location is:",
-" ",
-" \\v(appdata)ssh/known_hosts",
-" ",
-"SET SSH V2 AUTHENTICATION { EXTERNAL-KEYX, GSSAPI, HOSTBASED, ",
-" KEYBOARD-INTERACTIVE, PASSWORD, PUBKEY, SRP-GEX-SHA1 } [ ... ]",
-" Specifies an ordered list of SSH version 2 authentication methods to",
-" be used when connecting to the remote host. The default list is:",
-" ",
-" external-keyx gssapi hostbased publickey srp-gex-sha1 publickey",
-" keyboard-interactive password none",
-" ",
-"SET SSH V2 AUTO-REKEY { ON, OFF }",
-" Specifies whether Kermit automatically issues rekeying requests",
-" once an hour when SSH version 2 in in use. The default is ON.",
-" ",
-"SET SSH V2 CIPHERS { 3DES-CBC, AES128-CBC AES192-CBC AES256-CBC",
-" ARCFOUR BLOWFISH-CBC CAST128-CBC RIJNDAEL128-CBC RIJNDAEL192-CBC",
-" RIJNDAEL256-CBC }",
-" Specifies an ordered list of SSH version ciphers to be used to encrypt",
-" the established connection. The default list is:",
-" ",
-" aes128-cbc 3des-cbc blowfish-cbc cast128-cbc arcfour aes192-cbc",
-" aes256-cbc",
-" ",
-" \"rijndael\" is an alias for \"aes\".",
-" ",
-"SET SSH V2 GLOBAL-KNOWN-HOSTS-FILE filename",
-" Specifies the location of the system-wide known-hosts file. The default",
-" location is:",
-" ",
-" \\v(common)ssh/known_hosts2",
-" ",
-"SET SSH V2 HOSTKEY-ALGORITHMS { SSH-DSS, SSH-RSA }",
-" Specifies an ordered list of hostkey algorithms to be used to verify",
-" the identity of the host. The default list is",
-" ",
-" ssh-rsa ssh-dss",
-" ",
-"SET SSH V2 MACS { HMAC-MD5 HMAC-MD5-96 HMAC-RIPEMD160 HMAC-SHA1",
-" HMAC-SHA1-96 }",
-" Specifies an ordered list of Message Authentication Code algorithms to",
-" be used for integrity protection of the established connection. The",
-" default list is:",
-" ",
-" hmac-md5 hmac-sha1 hmac-ripemd160 hmac-sha1-96 hmac-md5-96",
-" ",
-"SET SSH V2 USER-KNOWN-HOSTS-FILE filename",
-" Specifies the location of the user-known-hosts file. The default",
-" location is:",
-" ",
-" \\v(appdata)ssh/known_hosts2",
-" ",
-"SET SSH VERBOSE level",
-" Specifies how many messages should be generated by the OpenSSH engine.",
-" The level can range from 0 to 7. The default value is 2.",
-" ",
-"SET SSH VERSION { 1, 2, AUTOMATIC }",
-" Specifies which SSH version should be negotiated. The default is",
-" AUTOMATIC which means use version 2 if supported; otherwise to fall",
-" back to version 1.",
-" ",
-"SET SSH X11-FORWARDING { ON, OFF }",
-" Specifies whether X Windows System Data is to be forwarded across the",
-" established SSH connection. The default is OFF. When ON, the DISPLAY",
-" value is either set using the SET TELNET ENV DISPLAY command or read",
-" from the DISPLAY environment variable.",
-" ",
-"SET SSH XAUTH-LOCATION filename",
-" Specifies the location of the xauth executable (if provided with the",
-" X11 Server software.)",
-#else /* SSHBUILTIN */
-"Syntax: SET SSH COMMAND command",
-" Specifies the external command to be used to make an SSH connection.",
-" By default it is \"ssh -e none\" (ssh with no escape character).",
-#endif /* SSHBUILTIN */
-""
-};
-#endif /* ANYSSH */
-
-#ifdef NEWFTP
-static char *hmxygpr[] = {
-"Syntax: SET GET-PUT-REMOTE { AUTO, FTP, KERMIT}",
-" Tells Kermit whether GET, PUT, and REMOTE commands should be directed",
-" at a Kermit server or an FTP server. The default is AUTO, meaning that",
-" if you have only one active connection, the appropriate action is taken",
-" when you give a GET, PUT, or REMOTE command. SET GET-PUT-REMOTE FTP forces"
-,
-" Kermit to treat GET, PUT, and REMOTE as FTP client commands; setting this",
-" to KERMIT forces these commands to be treated as Kermit client commands.",
-" NOTE: PUT includes SEND, MPUT, MSEND, and all other similar commands.",
-" Also see HELP REMOTE, HELP SET LOCUS, HELP FTP.",
-""
-};
-#endif /* NEWFTP */
-
-#ifdef LOCUS
-static char *hmxylocus[] = {
-#ifdef KUI
-"Syntax: SET LOCUS { ASK, AUTO, LOCAL, REMOTE }",
-#else
-"Syntax: SET LOCUS { AUTO, LOCAL, REMOTE }",
-#endif /* KUI */
-" Specifies whether unprefixed file management commands should operate",
-" locally or (when there is a connection to a remote FTP or Kermit",
-" server) sent to the server. The affected commands are: CD (CWD), PWD,",
-" CDUP, DIRECTORY, DELETE, RENAME, MKDIR, and RMDIR. To force any of",
-" these commands to be executed locally, give it an L-prefix: LCD, LDIR,",
-" etc. To force remote execution, use the R-prefix: RCD, RDIR, and so",
-" on. SHOW COMMAND shows the current Locus.",
-" ",
-" By default, the Locus for file management commands is switched",
-" automatically whenever you make or close a connection: if you make an",
-" FTP connection, the Locus becomes REMOTE; if you close an FTP connection",
-" or make any other kind of connection, the Locus becomes LOCAL.",
-#ifdef KUI
-" ",
-" There are two kinds of automatic switching: ASK (the default) which",
-" asks you if it's OK to switch, and AUTO, which switches without asking.",
-#endif /* KUI */
-" ",
-" If you give a SET LOCUS LOCAL or SET LOCUS REMOTE command, this sets",
-" the locus as indicated and disables automatic switching.",
-#ifdef KUI
-" SET LOCUS AUTO or SET LOCUS ASK restores automatic switching.",
-" You can also change Locus switching and behavior in the Actions menu.",
-#else
-" SET LOCUS AUTO restores automatic switching.",
-#endif /* KUI */
-"",
-};
-#endif /* LOCUS */
-
-static char *hmxxtak[] = {
-"Syntax: TAKE filename [ arguments ]",
-" Tells Kermit to execute commands from the named file. Optional argument",
-" words, are automatically assigned to the macro argument variables \\%1",
-" through \\%9. Kermit command files may themselves contain TAKE commands,",
-" up to any reasonable depth of nesting.",
-""
-};
-
-#ifdef TCPSOCKET
-static char *hmxxfirew[] = {
-#ifdef OS2
-"Firewall Traversal in Kermit 95",
-#else
-"Firewall Traversal in C-Kermit",
-#endif
-" ",
-#ifndef NEWFTP
-#ifndef CKHTTP
-#ifndef CK_SOCKS
-#define NOFIREWALL
-#endif
-#endif
-#endif
-#ifdef NOFIREWALL
-"This version of Kermit was built with no support for firewall traversal",
-"protocols. Kermit can be built with support for HTTP Proxy Servers,",
-"SOCKS authorized firewall traversal, and FTP Passive connection modes.",
-" ",
-#else /* NOFIREWALL */
-#ifdef CKHTTP
-"The simplist form of firewall traversal is the HTTP CONNECT command. The",
-"CONNECT command was implemented to allow a public web server which usually",
-"resides on the boundary between the public and private networks to forward",
-"HTTP requests from clients on the private network to public web sites. To",
-"allow secure web connections, the HTTP CONNECT command authenticates the",
-"client with a username/password and then establishes a tunnel to the",
-"desired host.",
-
-" ",
-
-"Web servers that support the CONNECT command can be configured to allow",
-"outbound connections for authenticated users to any TCP/IP hostname-port",
-"combination accessible to the Web server. HTTP CONNECT can be used only",
-"with TCP-based protocols. Protocols such as Kerberos authentication that",
-"use UDP/IP cannot be tunneled using HTTP CONNECT.",
-
-" ",
-
-"SET TCP HTTP-PROXY [switches] [<hostname or ip-address>[:<port>]]",
-" If a hostname or ip-address is specified, Kermit uses the given",
-" proxy server when attempting outgoing TCP connections. If no hostnamer",
-" or ip-address is specified, any previously specified Proxy server is",
-" removed. If no port number is specified, the \"http\" service is used.",
-" [switches] can be one or more of:",
-" /AGENT:<agent> /USER:<user> /PASSWORD:<password>",
-" Switch parameters are used when connecting to the proxy server and",
-" override any other values associated with the connection.",
-" ",
-
-#endif /* CKHTTP */
-#ifdef CK_SOCKS
-
-"In the early 1990s as firewalls were becoming prevalent, David Koblas",
-"developed the SOCKS protocol for TCP/IP firewall traversal. Two versions",
-"of SOCKS are currently in use: Version 4.2 lets TCP/IP client applications",
-"traverse firewalls, similar to HTTP CONNECT, except that the SOCKS client",
-"is aware of the public source IP address and port, which can be used within",
-"the application protocol to assist in securing the connection (e.g. FTP",
-"sessions secured with GSSAPI Kerberos 5).",
-
-" ",
-
-"In 1995 the IETF issued SOCKS Protocol Version 5 (RFC 1928), which is",
-"significantly more general than version 4. Besides supporting client-",
-"to-server TCP/IP connections, it also includes:",
-
-" ",
-" . Authenticated firewall traversal of UDP/IP packets.",
-" . Authenticated binding of incoming public ports on the firewall.",
-" ",
-
-"This lets a service on the private network offer public services. It also",
-"lets client applications like FTP establish a temporary public presence",
-"that can be used by the FTP server to create a data channel. By allowing",
-"the client to bind to a public port on the firewall and be aware of the",
-"public address, SOCKS 5 lets the application protocol communicate this",
-"information to the server.",
-
-" ",
-
-#ifdef OS2
-#ifdef NT
-"Kermit 95 supports SOCKS 4.2. The SOCKS Server is specified with:",
-" ",
-" SET TCP SOCKS-SERVER hostname/ip-address",
-" ",
-"The SOCKS.CONF file is found by examining the ETC environment variable;",
-"searching in \\WINDOWS on Windows 95/98/ME; or the",
-"\\WINDOWS\\SYSTEM\\DRIVERS\\ETC directory on NT\\2000\\XP systems.",
-
-#else /* NT */
-
-"Kermit/2 provides support for SOCKS 4.2 servers when using IBM TCP/IP 2.0,",
-"IBM OS/2 WARP, or a compatible protocol stack. SOCKS is one popular means",
-"of implementing a firewall between a private network and the Internet.",
-" ",
-"Kermit/2 shares the same SOCKS environment variables as IBM Gopher. It also",
-"supports the use of local SOCKS configuration files.",
-" ",
-"To specify the default SOCKS Server, add SET SOCKS_SERVER= to your",
-"CONFIG.SYS file.",
-" ",
-"If you must use a SOCKS Distributed Name Server, add SET SOCKS_NS= to your",
-"CONFIG.SYS file.",
-" ",
-
-"If you must use a specific with your SOCKS server, be sure to add SET USER=",
-"to your CONFIG.SYS file. Otherwise, \"os2user\" is used by default.",
-
-" ",
-
-"The SOCKS configuration file must be placed in the directory pointed to by",
-"the ETC environment variable as declared in your CONFIG.SYS file. The name",
-"should be SOCKS.CONF. On a FAT file system, use SOCKS.CNF.",
-
-" ",
-"The format of the lines in the SOCKS configuration file are as follows:",
-" ",
-" . # comments",
-" . deny [*=userlist] dst_addr dst_mask [op port]",
-" . direct [*=userlist] dst_addr dst_mask [op port]",
-" . sockd [@=serverlist] [*=userlist] dst_addr dst_mask [op port]",
-" ",
-
-"op must be one of 'eq', 'neq', 'lt', 'gt', 'le', or 'ge'. dst_addr,",
-"dst_mask, and port may be either numeric or name equivalents.",
-
-" ",
-
-"Kermit/2 ignores the [*=userlist] and [@=serverlist] fields. Matches are",
-"determined on a first match not a best match basis. Addresses for which no",
-"match is found default to \"sockd\".",
-
-" ",
-
-"For completeness: Fields in square brackets are optional. The optional",
-"@=serverlist field with a 'sockd' line specifies the list of SOCKS servers",
-"the client should try (in the given order) instead of the default SOCKS",
-"server. If the @=serverlist part is omitted, then the default SOCKS server",
-"is used. Commas are used in the userlist and serverlist as separators, no",
-"white spaces are allowed.",
-
-#endif /* NT */
-
-" ",
-
-#else /* OS2 */
-#ifdef CK_SOCKS5
-"This version of C-Kermit supports SOCKS version 5.",
-#else /* CK_SOCKS5 */
-"This version of C-Kermit supports SOCKS version 4.",
-#endif /* CK_SOCKS5 */
-
-"See the man page (or other system documentation) for information on",
-"configuring the SOCKS library via the /etc/socks.conf file.",
-
-#endif /* OS2 */
-" ",
-#endif /* CK_SOCKS */
-
-#ifdef NEWFTP
-
-"FTP is one of the few well-known Internet services that requires",
-"multiple connections. As described above, FTP originally required the",
-"server to establish the data connection to the client using a destination",
-"address and port provided by the client. This doesn't work with port",
-"filtering firewalls.",
-
-" ",
-
-"Later, FTP protocol added a \"passive\" mode, in which connections for",
-"the data channels are created in the reverse direction. Instead of the",
-"server establishing a connection to the client, the client makes a second",
-"connection with the server as the destination. This works just fine as",
-"long as the client is behind the firewall and the server is in public",
-"address space. If the server is behind a firewall then the traditional",
-"active mode must be used. If both the client and server are behind their",
-"own port filtering firewalls then data channels cannot be established.",
-
-" ",
-
-"In Kermit's FTP client, passive mode is controlled with the command:",
-
-" ",
-" SET FTP PASSIVE-MODE { ON, OFF }",
-" ",
-
-"The default is ON, meaning to use passive mode.",
-
-#endif /* NEWFTP */
-#endif /* NOFIREWALL */
-
-""
-};
-#endif /* TCPSOCKET */
-
-static char *hmxxsave[] = {
-"Syntax: SAVE item filename { NEW, APPEND }",
-" Saves the requested material in the given file. A new file is created",
-" by default; include APPEND at the end of the command to append to an",
-" existing file. Items:",
-#ifndef NOSETKEY
-" KEYMAP Saves the current key settings.",
-#endif /* NOSETKEY */
-#ifdef CK_RECALL
-" COMMAND HISTORY Saves the current command recall (history) buffer",
-#endif /* CK_RECALL */
-#ifdef OS2
-" COMMAND SCROLLBACK Saves the current command-screen scrollback buffer",
-" TERMINAL SCROLLBACK Saves the current terminal-screen scrollback buffer",
-#endif /* OS2 */
-""
-};
-
-#ifdef CKROOT
-static char *hmxxchroot[] = {
-"Syntax: SET ROOT directoryname",
-" Sets the root for file access to the given directory and disables access",
-" to system and shell commands and external programs. Once this command",
-" is given, no files or directories outside the tree rooted by the given",
-" directory can be opened, read, listed, deleted, renamed, or accessed in",
-" any other way. This command can not be undone by a subsequent SET ROOT",
-" command. Primarily for use with server mode, to restrict access of",
-" clients to a particular directory tree. Synonym: CHROOT.",
-""
-};
-#endif /* CKROOT */
-
-static char *hmxxscrn[] = {
-"Syntax: SCREEN { CLEAR, CLEOL, MOVE row column }",
-#ifdef OS2
-" Performs screen-formatting actions.",
-#else
-" Performs screen-formatting actions. Correct operation of these commands",
-" depends on proper terminal setup on both ends of the connection -- mainly",
-" that the host terminal type is set to agree with the kind of terminal or",
-" the emulation you are viewing C-Kermit through.",
-#endif /* OS2 */
-" ",
-"SCREEN CLEAR",
-" Moves the cursor to home position and clears the entire screen.",
-#ifdef OS2
-" Synonyms: CLS, CLEAR SCREEN, CLEAR COMMAND-SCREEN ALL",
-#else
-" Synonyms: CLS, CLEAR SCREEN.",
-#endif /* OS2 */
-" ",
-"SCREEN CLEOL",
-" Clears from the current cursor position to the end of the line.",
-#ifdef OS2
-" Synonym: CLEAR COMMAND-SCREEN EOL",
-#endif /* OS2 */
-" ",
-"SCREEN MOVE row column",
-" Moves the cursor to the indicated row and column. The row and column",
-" numbers are 1-based so on a 24x80 screen, the home position is 1 1 and",
-" the lower right corner is 24 80. If a row or column number is given that",
-" too large for what Kermit or the operating system thinks is your screen",
-" size, the appropriate number is substituted.",
-" ",
-"Also see:",
-#ifdef OS2
-" HELP FUNCTION SCRNCURX, HELP FUNCTION SCRNCURY, HELP FUNCTION SCRSTR,",
-#endif /* OS2 */
-" SHOW VARIABLE TERMINAL, SHOW VARIABLE COLS, SHOW VAR ROWS, SHOW COMMAND.",
-""
-};
-
-#ifndef NOSPL
-static char *hmfword[] = {
-"\\fword(s1,n1,s2,s3,n2,n3) - Extract word from string.",
-" s1 = source string",
-" n1 = word number (1-based)",
-" s2 = optional break set.",
-" s3 = optional include set.",
-" n2 = optional grouping mask.",
-" n3 = optional separator flag:",
-" 0 = collapse adjacent separators",
-" 1 = don't collapse adjacent separators.",
-" ",
-" Default break set is all characters except ASCII letters and digits.",
-" ASCII (C0) control characters are always treated as break characters.",
-" Default include set is null.",
-" ",
-" If grouping mask given and nonzero, words can be grouped by quotes or",
-" brackets selected by the sum of the following:",
-" ",
-" 1 = doublequotes: \"a b c\"",
-" 2 = braces: {a b c}",
-" 4 = apostrophes: 'a b c'",
-" 8 = parentheses: (a b c)",
-" 16 = square brackets: [a b c]",
-" 32 = angle brackets: <a b c>",
-" ",
-" Nesting is possible with {}()[]<> but not with quotes or apostrophes.",
-" ",
-"Returns string:",
-" Word number n, if there is one, otherwise an empty string.",
-""
-};
-
-static char *hmxxprompt[] = {
-"Syntax: PROMPT [ text ]",
-" Enters interactive command level from within a script in such a way that",
-" the script can be continued with an END or RETURN command. STOP, EXIT,",
-" SHOW STACK, TRACE, and Ctrl-C all have their normal effects. The PROMPT",
-" command allows variables to be examined or changed, or any other commands",
-" to be given, in any number, prior to returning to the script, allowing",
-" Kermit to serve as its own debugger; adding the PROMPT command to a script",
-" is like setting a breakpoint. If the optional text is included, it is",
-" used as the new prompt for this level, e.g. \"prompt Breakpoint_1>\".",
-""
-};
-
-static char *hxxinp[] = {
-"Syntax: INPUT [ /NOMATCH ] { number-of-seconds, time-of-day } [ text ]",
-"Example: INPUT 5 Login: or INPUT 23:59:59 RING",
-" Waits up to the given number of seconds, or until the given time of day,",
-" for the given text to arrive on the connection. If no text is given,",
-" INPUT waits for any character. If the /NOMATCH switch is included, INPUT",
-" does not attempt to match any characters, but continues reading from the",
-" communication connection until the timeout interval expires. If the",
-" timeout interval is 0, the INPUT command does not wait; i.e. the given",
-" text must already be available for reading for the INPUT command to",
-" succeed. If the interval is negative, the INPUT command waits forever.",
-" For use in script programs with IF FAILURE and IF SUCCESS. Also see",
-" MINPUT, REINPUT, SET INPUT. See HELP PAUSE for details on time-of-day",
-" format. The text, if given, can be a \\pattern() invocation, in which",
-" case it is treated as a pattern rather than a literal string (HELP",
-" PATTERNS for details).",
-""};
-
-static char *hxxout[] = {
-"Syntax: OUTPUT text",
-" Sends the text out the communications connection, as if you had typed it",
-" during CONNECT mode. The text may contain backslash codes, variables,",
-" etc, plus the following special codes:",
-" ",
-" \\N - Send a NUL (ASCII 0) character (you can't use \\0 for this).",
-" \\B - Send a BREAK signal.",
-" \\L - Send a Long BREAK signal.",
-" ",
-"Also see SET OUTPUT.",
-"" };
-#endif /* NOSPL */
-
-static char *hxypari[] = {
-"SET PARITY NONE",
-" Chooses 8 data bits and no parity.",
-" ",
-"SET PARITY { EVEN, ODD, MARK, SPACE }",
-" Chooses 7 data bits plus the indicated kind of parity.",
-" Forces 8th-bit prefixing during file transfer.",
-" ",
-#ifdef HWPARITY
-"SET PARITY HARDWARE { EVEN, ODD }",
-" Chooses 8 data bits plus the indicated kind of parity.",
-" ",
-"Also see SET TERMINAL BYTESIZE, SET SERIAL, and SET STOP-BITS.",
-#else
-"Also see SET TERMINAL BYTESIZE and SET SERIAL.",
-#endif /* HWPARITY */
-""};
-
-#ifndef NOLOCAL
-static char *hxyesc[] = {
-#ifdef OS2
-"Syntax: SET ESCAPE number",
-" Decimal ASCII value for escape character during CONNECT, normally 29",
-" (Control-]). Type the escape character followed by C to get back to the",
-" C-Kermit prompt or followed by ? to see other options, or use the \\Kexit",
-" keyboard verb, normally assigned to Alt-x.",
-#else
-#ifdef NEXT
-"Syntax: SET ESCAPE number",
-" Decimal ASCII value for escape character during CONNECT, normally 29",
-" (Control-]). Type the escape character followed by C to get back to the",
-" C-Kermit prompt or followed by ? to see other options.",
-#else
-"Syntax: SET ESCAPE number",
-" Decimal ASCII value for escape character during CONNECT, normally 28",
-" (Control-\\). Type the escape character followed by C to get back to the",
-" C-Kermit prompt or followed by ? to see other options.",
-#endif /* NEXT */
-#endif /* OS2 */
-" ",
-"You may also enter the escape character as ^X (circumflex followed by a",
-"letter or one of: @, ^, _, [, \\, or ], to indicate a control character;",
-"for example, SET ESC ^_ sets your escape character to Ctrl-Underscore.",
-" ",
-"You can also specify an 8-bit character (128-255) as your escape character,",
-"either by typing it literally or by entering its numeric code.",
-"" };
-#endif /* NOLOCAL */
-
-#ifndef NOSPL
-static char *hxyout[] = {
-"SET OUTPUT PACING <number>",
-" How many milliseconds to pause after sending each OUTPUT character,",
-" normally 0.",
-" ",
-"SET OUTPUT SPECIAL-ESCAPES { ON, OFF }",
-" Whether to process the special OUTPUT-only escapes \\B, \\L, and \\N.",
-" Normally ON (they are processed).",
-"" };
-
-static char *hxyinp[] = {
-"Syntax: SET INPUT parameter value",
-" ",
-#ifdef CK_AUTODL
-"SET INPUT AUTODOWNLOAD { ON, OFF }",
-" Controls whether autodownloads are allowed during INPUT command execution.",
-" ",
-#endif /* CK_AUTODL */
-"SET INPUT BUFFER-LENGTH number-of-bytes",
-" Removes the old INPUT buffer and creates a new one with the given length.",
-" ",
-"SET INPUT CANCELLATION { ON, OFF }",
-" Whether an INPUT in progress can be can interrupted from the keyboard.",
-" ",
-"SET INPUT CASE { IGNORE, OBSERVE }",
-" Tells whether alphabetic case is to be significant in string comparisons.",
-" This setting is local to the current macro or command file, and is",
-" inherited by subordinate macros and take files.",
-" ",
-"SET INPUT ECHO { ON, OFF }",
-" Tells whether to display arriving characters read by INPUT on the screen.",
-" ",
-#ifdef CKFLOAT
-"SET INPUT SCALE-FACTOR <number>",
-" A number to multiply all INPUT timeouts by, which may include a fractional",
-" part, e.g. 2.5. All INPUT commands that specify a timeout in seconds",
-" (as opposed to a specific time of day) have their time limit adjusted",
-" automatically by this factor, which is also available in the built-in",
-" read-only variable \\v(inscale). The default value is 1.0.",
-" ",
-
-#endif /* CKFLOAT */
-
-"SET INPUT SILENCE <number>",
-" The maximum number to seconds of silence (no input at all) before the",
-" INPUT command times out, 0 for no maximum.",
-" ",
-#ifdef OS2
-"SET INPUT TERMINAL { ON, OFF }",
-" Determines whether the data received during an INPUT command is displayed",
-" in the terminal window. Default is ON.",
-" ",
-#endif /* OS2 */
-"SET INPUT TIMEOUT-ACTION { PROCEED, QUIT }",
-" Tells whether to proceed or quit from a script program if an INPUT command",
-" fails. PROCEED (default) allows use of IF SUCCESS / IF FAILURE commands.",
-" This setting is local to the current macro or command file, and is",
-" inherited by subordinate macros and take files.",
-"" };
-
-static char *hxyfunc[] = {
-"SET FUNCTION DIAGNOSTICS { ON, OFF }",
-" Whether to issue diagnostic messages for illegal function calls and",
-" references to nonexistent built-in variables. ON by default.",
-" ",
-"SET FUNCTION ERROR { ON, OFF }",
-" Whether an illegal function call or reference to a nonexistent built-in",
-" variable should cause a command to fail. OFF by default.",
-"" };
-#endif /* NOSPL */
-
-static char *hxyxyz[] = {
-#ifdef CK_XYZ
-#ifdef XYZ_INTERNAL
-
-/* This is for built-in protocols */
-
-"Syntax: SET PROTOCOL { KERMIT, XMODEM, YMODEM, ZMODEM } [ s1 s2 [ s3 ] ]",
-" Selects protocol to use for transferring files. String s1 is a command to",
-" send to the remote host prior to SENDing files with this protocol in",
-" binary mode; string s2 is the same thing but for text mode. Use \"%\" in",
-" any of these strings to represent the filename(s). If the protocol is",
-" KERMIT, you may also specify a string s3, the command to start a Kermit",
-" server on the remote host when you give a GET, REGET, REMOTE, or other",
-" client command. Use { braces } if any command contains spaces. Examples:",
-" ",
-" set proto xmodem {rx %s} {rx -a %s}",
-" set proto kermit {kermit -YQir} {kermit -YQTr} {kermit -YQx}",
-
-#else /* This is for when non-Kermit protocols are external */
-
-"Syntax: \
-SET PROTOCOL { KERMIT, XMODEM, YMODEM, ZMODEM } [ s1 s2 s3 s4 s5 s6 ]",
-" Selects protocol to use for transferring files. s1 and s2 are commands to",
-" output prior to SENDing with this protocol, to automatically start the",
-" RECEIVE process on the other end in binary or text mode, respectively.",
-" If the protocol is KERMIT, s3 is the command to start a Kermit server on",
-" the remote computer, and there are no s4-s6 commands. Otherwise, s3 and",
-" s4 are commands used on this computer for sending files with this protocol",
-" in binary or text mode, respectively; s5 and s6 are the commands for",
-" receiving files with this protocol. Use \"%s\" in any of these strings",
-" to represent the filename(s). Use { braces } if any command contains",
-" spaces. Examples:",
-" ",
-" set proto kermit {kermit -YQir} {kermit -YQTr} {kermit -YQx}",
-" set proto ymodem rb {rb -a} {sb %s} {sb -a %s} rb rb",
-" ",
-"External protocols require REDIRECT and external file transfer programs that",
-"use redirectable standard input/output.",
-#endif /* XYZ_INTERNAL */
-#else
-"Syntax: \
-SET PROTOCOL KERMIT [ s1 [ s2 [ s3 ] ] ]",
-" Lets you specify the autoupload binary, autoupload text, and autoserver",
-" command strings to be sent to the remote system in advance of any SEND",
-" or GET commands. By default these are \"kermit -ir\", \"kermit -r\", and",
-" \"kermit -x\". Use { braces } around any command that contains spaces.",
-" Example:",
-" ",
-" set proto kermit {kermit -Yir} {kermit -YTr} {kermit -Yx}",
-#endif /* CK_XYZ */
-" ",
-" SHOW PROTOCOL displays the current settings.",
-""};
-
-static char *hmxxbye = "Syntax: BYE\n\
- Shut down and log out a remote Kermit server";
-
-#ifdef CK_PERMS
-#ifdef UNIX
-static char *hmxxchmod[] = {
-"Syntax: CHMOD [ switches ] code filespec",
-" UNIX only. Changes permissions of the given file(s) to the given code,",
-" which must be an octal number such as 664 or 775. Optional switches:",
-" ",
-" /FILES Only change permissions of regular files.",
-" /DIRECTORIES Only change permissions of directory files.",
-" /TYPE:BINARY Only change permissions of binary files.",
-" /TYPE:TEXT Only change permissions of text files.",
-" /DOTFILES Include files whose names begin with dot (.).",
-" /RECURSIVE Change permissions in subdirectories too.",
-" /LIST List each file (synonym: /VERBOSE).",
-" /NOLIST Operate silently (synonym: /QUIET).",
-" /PAGE When listing, pause at end of each screen (implies /LIST).",
-" /NOPAGE When listing, don't pause at end of each screen.",
-" /SIMULATE Show what would be done but don't actually do it.",
-""
-};
-#endif /* UNIX */
-#endif /* CK_PERMS */
-
-#ifndef NOSPL
-#ifndef NOSEXP
-static char *hmxxsexp[] = {
-"Syntax: (operation operand [ operand [ ... ] ])",
-" ",
-" C-Kermit includes a simple LISP-like S-Expression parser operating on",
-" numbers only. An S-Expression is always enclosed in parentheses. The",
-" parentheses can contain (a) a number, (b) a variable, (c) a function that",
-" returns a number, or (d) an operator followed by one or more operands.",
-" Operands can be any of (a) through (c) or an S-Expression. Numbers can be",
-" integers or floating-point. Any operand that is not a number and does not",
-" start with backslash (\\) is treated as a Kermit macro name. Operators:",
-" ",
-" Operator Action Example Value",
-" EVAL (.) Returns the contained value (6) 6",
-" QUOTE (') Inhibits evaluation of following value (quote a) a",
-" SETQ Assigns a value to a global variable (setq a 2) 2",
-" LET Assigns a value to a local variable (let b -1.3) -1.3",
-" + Adds all operands (1 or more) (+ a b) 0.7",
-" - Subtracts all operands (1 or more) (- 9 5 2 1) 1",
-" * Multiplies all operands (1 or more) (* a (+ b 1) 3) -1.8",
-" / Divides all operands (1 or more) (/ b a 2) -0.325",
-" ^ Raise given number to given power (^ 3 2) 9",
-" ++ Increments a variable (++ a 1.2) 3.2",
-" -- Decrements a variable (-- a) 1",
-" ABS Absolute value of 1 operand (abs (* a b 3)) 7.8",
-" MAX Maximum of all operands (1 or more) (max 1 2 3 4) 4",
-" MIN Minimum of all operands (1 or more) (min 1 2 3 4) 1",
-" MOD Modulus of all operands (1 or more) (mod 7 4 2) 1",
-" TRUNCATE Integer part of floating-point operand (truncate 1.333) 1",
-" CEILING Ceiling of floating-point operand (ceiling 1.25) 2",
-" FLOOR Floor of floating-point operand (floor 1.25) 1",
-" ROUND Operand rounded to nearest integer (round 1.75) 2",
-" SQRT Square root of 1 operand (sqrt 2) 1.414..",
-" EXP e (2.71828..) to the given power (exp -1) 0.367..",
-" SIN Sine of angle expressed in radians (sin (/ pi 2)) 1.0",
-" COS Cosine of given number (cos pi) -1.0",
-" TAN Tangent of given number (tan pi) 0.0",
-" LOG Natural log (base e) of given number (log 2.7183) 1.000..",
-" LOG10 Log base 10 of given number (log10 1000) 3.0",
-" ",
-"Predicate operators return 0 if false, 1 if true, and if it is the outermost",
-"operator, sets SUCCESS or FAILURE accordingly:",
-" ",
-" < Operands in strictly descending order (< 6 5 4 3 2 1) 1",
-" <= Operands in descending order (<= 6 6 5 4 3 2) 1",
-" != Operands are not equal (!= 1 1 1.0) 0",
-" = (==) All operands are equal (= 3 3 3 3) 1",
-" > Operands in strictly ascending order (> 1 2 3 4 5 6) 1",
-" >= Operands in ascending order (> 1 1 2 3 4 5) 1",
-" AND (&&) Operands are all true (and 1 1 1 1 0) 0",
-" OR (||) At least one operand is true (or 1 1 1 1 0) 1",
-" XOR Logical Exclusive OR (xor 3 1) 0",
-" NOT (!) Reverses truth value of operand (not 3) 0",
-" ",
-"Bit-oriented operators:",
-" ",
-" & Bitwise AND (& 7 2) 2",
-" | Bitwise OR (| 1 2 3 4) 7",
-" # Bitwise Exclusive OR (# 3 1) 2",
-" ~ Reverses all bits (~ 3) -4",
-" ",
-"Operators that work on truth values:",
-" ",
-" IF Conditional evaluation (if (1) 2 3) 2",
-" ",
-"Operators can also be names of Kermit macros that return either numeric",
-"values or no value at all.",
-" ",
-"Built-in constants are:",
-" ",
-" t True (1)",
-" nil False (empty)",
-" pi The value of Pi (3.1415926...)",
-" ",
-"If SET SEXPRESSION ECHO-RESULT is AUTO (the default), the value of the",
-"S-Expression is printed if the S-Expression is given at top level; if ON,",
-"it is printed at any level; if OFF it is not printed. At all levels, the",
-"variable \\v(sexpression) is set to the most recent S-Expression, and",
-"\\v(svalue) is set to its value. You can use the \\fsexpresssion() function",
-"to evaluate an S-Expression anywhere in a Kermit command.",
-""
-};
-#endif /* NOSEXP */
-#endif /* NOSPL */
-
-static char *hmxxgrep[] = {
-#ifdef UNIXOROSK
-"Syntax: GREP [ options ] pattern filespec",
-#else
-"Syntax: FIND [ options ] pattern filespec",
-#endif /* UNIXOROSK */
-" Searches through the given file or files for the given character string",
-" or pattern. In the normal case, all lines containing any text that matches"
-,
-" the pattern are printed. Pattern syntax is as described in HELP PATTERNS",
-" except that '*' is implied at the beginning unless the pattern starts with",
-" '^' and also at the end unless the pattern ends with '$'. Therefore,",
-" \"grep something *.txt\" lists all lines in all *.txt files that contain",
-" the word \"something\", but \"grep ^something *.txt\" lists only the lines",
-" that START with \"something\". The command succeeds if any of the given",
-" files contained any lines that match the pattern, otherwise it fails.",
-#ifdef UNIXOROSK
-" Synonym: FIND.",
-#else
-" Synonym: GREP.",
-#endif /* UNIXOROSK */
-" ",
-"File selection options:",
-" /NOBACKUPFILES",
-" Excludes backup files (like oofa.txt.~3~) from the search.",
-" /DOTFILES",
-" Includes files whose names start with dot (.) in the search.",
-" /NODOTFILES",
-" Excludes files whose names start with dot (.) from the search.",
-#ifdef RECURSIVE
-" /RECURSIVE",
-" Searches through files in subdirectories too.",
-#endif /* RECURSIVE */
-" /TYPE:TEXT",
-" Search only text files (requires FILE SCAN ON).",
-" /TYPE:BINARY",
-" Search only binary files (requires FILE SCAN ON).",
-" ",
-"Pattern-matching options:",
-" /NOCASE",
-" Ignores case of letters (ASCII only) when comparing.",
-" /NOMATCH",
-" Searches for lines that do NOT match the pattern.",
-" ",
-"Display options:",
-" /COUNT:variable-name",
-" For each file, prints only the filename and a count of matching lines",
-" and assigns the total match count to the variable, if one is given.",
-" /NAMEONLY",
-" Prints the name of each file that contains at least one matching line,",
-" one name per line, rather than showing each matching line.",
-" /NOLIST",
-" Doesn't print anything (but sets SUCCESS or FAILURE appropriately).",
-" /LINENUMBERS",
-" Precedes each file line by its line number within the file.",
-" /PAGE",
-" Pauses after each screenful.",
-" /NOPAGE",
-" Doesn't pause after each screenful.",
-" /OUTPUT:name",
-" Sends results to the given file. If this switch is omitted, the",
-" results appear on your screen. This switch overrides any express or",
-" implied /PAGE switch.",
-""};
-
-static char *hmxxdir[] = {
-#ifdef DOMYDIR
-"Syntax: DIRECTORY [ switches ] [ filespec [ filespec [ ... ] ] ]",
-#ifdef LOCUS
-" If LOCUS is REMOTE or LOCUS is AUTO and you have an FTP connection,",
-" this command is equivalent to REMOTE DIRECTORY (RDIR). Otherwise:",
-" ",
-#endif /* LOCUS */
-" Lists local files. The filespec may be a filename, possibly containing",
-" wildcard characters, or a directory name. If no filespec is given, all",
-" files in the current directory are listed. If a directory name is given,",
-" all the files in it are listed. Multiple filespecs can be given.",
-" Optional switches:",
-" ",
-" /BRIEF List filenames only.",
-#ifdef CK_PERMS
-" /VERBOSE + Also list permissions, size, and date.",
-#else
-" /VERBOSE + Also list date and size.",
-#endif /* CK_PERMS */
-" /FILES Show files but not directories.",
-" /DIRECTORIES Show directories but not files.",
-" /ALL + Show both files and directories.",
-" /ARRAY:&a Store file list in specified array (e.g. \\%a[]).",
-" /PAGE Pause after each screenful.",
-" /NOPAGE Don't pause after each screenful.",
-#ifdef UNIXOROSK
-" /DOTFILES Include files whose names start with dot (period).",
-" /NODOTFILES + Don't include files whose names start with dot.",
-" /FOLLOWLINKS Follow symbolic links.",
-" /NOFOLLOWLINKS + Don't follow symbolic links.",
-" /BACKUP + Include backup files (names end with .~n~).",
-" /NOBACKUPFILES Don't include backup files.",
-#endif /* UNIXOROSK */
-" /OUTPUT:file Store directory listing in the given file.",
-" /HEADING Include heading and summary.",
-" /NOHEADING + Don't include heading or summary.",
-" /SUMMARY Print only count and total size of matching files.",
-" /XFERMODE Show pattern-based transfer mode (T=Text, B=Binary).",
-" /TYPE: Show only files of the specified type (text or binary).",
-" /MESSAGE:text Add brief message to each listing line.",
-" /NOMESSAGE + Don't add message to each listing line.",
-" /NOXFERMODE + Don't show pattern-based transfer mode",
-" /ISODATE + In verbose listings, show date in ISO 8061 format.",
-" /ENGLISHDATE In verbose listings, show date in \"English\" format.",
-#ifdef RECURSIVE
-" /RECURSIVE Descend through subdirectories.",
-" /NORECURSIVE + Don't descend through subdirectories.",
-#endif /* RECURSIVE */
-" /SORT:key Sort by key, NAME, DATE, or SIZE; default key is NAME.",
-" /NOSORT + Don't sort.",
-" /ASCENDING + If sorting, sort in ascending order.",
-" /REVERSE If sorting, sort in reverse order.",
-" ",
-"Factory defaults are marked with +. Default for paging depends on SET",
-"COMMAND MORE-PROMPTING. Use SET OPTIONS DIRECTORY [ switches ] to change",
-"defaults; use SHOW OPTIONS to display customized defaults.",
-#else
-"Syntax: DIRECTORY [ filespec ]",
-" Lists the specified file or files. If no filespec is given, all files",
-" in the current directory are listed.",
-#endif /* DOMYDIR */
-""};
-
-
-#ifndef NOSPL
-static char *hmxxkcd[] = {
-"Syntax: KCD symbolic-directory-name",
-" Kermit Change Directory: Like CD (q.v.) but (a) always acts locally, and",
-" (b) takes a symbolic directory name rather than an actual directory name.",
-" The symbolic names correspond to Kermit's directory-valued built-in",
-" variables, such as \\v(download), \\v(exedir), and so on. Here's the list:"
-,
-" ",
-#ifdef NT
-" appdata Your personal Kermit 95 application data directory",
-" common Kermit 95's application data directory for all users",
-" desktop Your Windows desktop",
-#endif /* NT */
-" download Your download directory (if any)",
-#ifdef OS2ORUNIX
-" exedir The directory where the Kermit executable resides",
-#endif /* OS2ORUNIX */
-" home Your home, login, or default directory",
-" inidir The directory where Kermit's initialization was found",
-#ifdef UNIX
-" lockdir The UNIX UUCP lockfile directory on this computer",
-#endif /* UNIX */
-#ifdef NT
-" personal Your \"My Documents\" directory",
-#endif /* NT */
-" startup Your current directory at the time Kermit started",
-" textdir The directory where Kermit text files reside, if any",
-" tmpdir Your temporary directory",
-" ",
-" Also see CD, SET FILE DOWNLOAD, SET TEMP-DIRECTORY.",
-""
-};
-#endif /* NOSPL */
-
-static char *hmxxcwd[] = {
-#ifdef LOCUS
-" If LOCUS is REMOTE or LOCUS is AUTO and you have an FTP connection,",
-" this command is equivalent to REMOTE CD (RCD). Otherwise:",
-" ",
-#endif /* LOCUS */
-#ifdef vms
-"Syntax: CD [ directory or device:directory ]",
-" Change Working Directory. Equivalent to VMS SET DEFAULT command.",
-#else
-#ifdef datageneral
-"Change Working Directory, equivalent to AOS/VS 'dir' command.",
-#else
-#ifdef OS2
-"Syntax: CD [ disk or directory name ]",
-" Change Disk or Directory. If a disk or directory name is not specified,",
-" your current directory becomes the one specified by HOME environment",
-" variable, if any. A disk letter must be followed by a colon.",
-#else
-"Syntax: CD [ directory name ]",
-" Change Directory. Changes your current, working, default directory to the",
-" one given, so that future non-absolute filename references are relative to",
-" this directory. If the directory name is omitted, your home (login)",
-" directory is supplied.",
-#endif /* OS2 */
-#endif /* datageneral */
-#endif /* vms */
-" C-Kermit's default prompt shows your current directory.",
-" Synonyms: LCD, CWD.",
-#ifdef LOCUS
-" Also see: SET LOCUS, PWD, CDUP, BACK, REMOTE CD (RCD), SET CD, SET PROMPT.",
-#else
-" Also see: PWD, CDUP, BACK, REMOTE CD (RCD), SET CD, SET PROMPT.",
-#endif /* LOCUS */
-#ifndef NOSPL
-" And see: HELP KCD.",
-#endif /* NOSPL */
-" Relevant environment variables: CDPATH, HOME.",
-""};
-
-static char *hmxxdel[] = {
-"Syntax: DELETE [ switches... ] filespec",
-#ifdef LOCUS
-" If LOCUS is REMOTE or LOCUS is AUTO and you have an FTP connection,",
-" this command is equivalent to REMOTE DELETE (RDELETE). Otherwise:",
-" ",
-#endif /* LOCUS */
-" Deletes a file or files on the computer where C-Kermit is running.",
-" The filespec may denote a single file or can include wildcard characters",
-" to match multiple files. RM is a synonym for DELETE. Switches include:",
-" ",
-"/AFTER:date-time",
-#ifdef VMS
-" Specifies that only those files created after the given date-time are",
-#else
-" Specifies that only those files modified after the given date-time are",
-#endif /* VMS */
-" to be deleted. HELP DATE for info about date-time formats.",
-" ",
-"/BEFORE:date-time",
-#ifdef VMS
-" Specifies that only those files modified before the given date-time",
-#else
-" Specifies that only those files modified before the given date-time",
-#endif /* VMS */
-" are to be deleted.",
-" ",
-"/NOT-AFTER:date-time",
-#ifdef VMS
-" Specifies that only those files modified at or before the given date-time",
-#else
-" Specifies that only those files modified at or before the given date-time",
-#endif /* VMS */
-" are to be deleted.",
-" ",
-"/NOT-BEFORE:date-time",
-#ifdef VMS
-" Specifies that only those files modified at or after the given date-time",
-#else
-" Specifies that only those files modified at or after the given date-time",
-#endif /* VMS */
-" are to be deleted.",
-" ",
-"/LARGER-THAN:number",
-" Specifies that only those files longer than the given number of bytes are",
-" to be deleted.",
-" ",
-"/SMALLER-THAN:number",
-" Specifies that only those files smaller than the given number of bytes are",
-" to be sent.",
-" ",
-"/EXCEPT:pattern",
-" Specifies that any files whose names match the pattern, which can be a",
-" regular filename or may contain wildcards, are not to be deleted. To",
-" specify multiple patterns (up to 8), use outer braces around the group",
-" and inner braces around each pattern:",
-" ",
-" /EXCEPT:{{pattern1}{pattern2}...}",
-" ",
-#ifdef UNIXOROSK
-"/DOTFILES",
-" Include (delete) files whose names begin with \".\".",
-" ",
-"/NODOTFILES",
-" Skip (don't delete) files whose names begin with \".\".",
-" ",
-#endif /* UNIXOROSK */
-"/TYPE:TEXT",
-" Delete only regular text files (requires FILE SCAN ON)",
-" ",
-"/TYPE:BINARY",
-" Delete only regular binary files (requires FILE SCAN ON)",
-" ",
-"/DIRECTORIES",
-" Include directories. If this switch is not given, only regular files",
-" are deleted. If it is given, Kermit attempts to delete any directories",
-" that match the given file specification, which succeeds only if the",
-" directory is empty.",
-" ",
-#ifdef RECURSIVE
-"/RECURSIVE",
-" The DELETE command applies to the entire directory tree rooted in the",
-" current or specified directory. When the /DIRECTORIES switch is also",
-" given, Kermit deletes all the (matching) files in each directory before",
-" attempting to delete the directory itself.",
-" ",
-#endif /* RECURSIVE */
-#ifdef UNIX
-#ifdef RECURSIVE
-"/ALL",
-" This is a shortcut for /RECURSIVE /DIRECTORIES /DOTFILES.",
-#else
-"/ALL",
-" This is a shortcut for /DIRECTORIES /DOTFILES.",
-#endif /* RECURSIVE */
-#else /* !UNIX */
-#ifdef RECURSIVE
-"/ALL",
-" This is a shortcut for /RECURSIVE /DIRECTORIES.",
-#else
-"/ALL",
-" This is a synonym for /DIRECTORIES.",
-#endif /* RECURSIVE */
-#endif /* UNIX */
-" ",
-"/LIST",
-" List each file and tell whether it was deleted. Synonyms: /LOG, /VERBOSE.",
-" ",
-"/NOLIST",
-" Don't list files while deleting. Synonyms: /NOLOG, /QUIET.",
-" ",
-"/HEADING",
-" Print heading and summary information.",
-" ",
-"/NOHEADING",
-" Don't print heading and summary information.",
-" ",
-"/SUMMARY",
-" Like /HEADING /NOLIST, but only prints the summary line.",
-" ",
-"/PAGE",
-" If listing, pause after each screenful.",
-" ",
-"/NOPAGE",
-" Don't pause after each screenful.",
-" ",
-"/ASK",
-" Interactively ask permission to delete each file. Reply Yes or OK to",
-" delete it, No not to delete it, Quit to cancel the DELETE command, and",
-" Go to go ahead and delete all the rest of the files without asking.",
-" ",
-"/NOASK",
-" Delete files without asking permission.",
-" ",
-"/SIMULATE",
-" Preview files selected for deletion without actually deleting them.",
-" Implies /LIST.",
-" ",
-"Use SET OPTIONS DELETE to make selected switches effective for every DELETE",
-"command \
-unless you override them; use SHOW OPTIONS to see selections currently",
-#ifdef LOCUS
-"in effect. Also see HELP SET LOCUS, HELP PURGE, HELP WILDCARD.",
-#else
-"in effect. Also see HELP PURGE, HELP WILDCARD.",
-#endif /* LOCUS */
-""};
-
-#ifndef NOHTTP
-static char *hmxxhttp[] = {
-"Syntax:",
-#ifdef CK_SSL
-"HTTP [ <switches> ] OPEN [{ /SSL, /TLS }] <hostname> <service/port>",
-#else
-"HTTP [ <switches> ] OPEN <hostname> <service/port>",
-#endif /*CK_SSL */
-" Instructs Kermit to open a new connection for HTTP communication with",
-" the specified host on the specified port. The default port is \"http\".",
-#ifdef CK_SSL
-" If /SSL or /TLS are specified or if the service is \"https\" or port 443,",
-" a secure connection will be established using the current authentication",
-" settings. See HELP SET AUTH for details.",
-#endif /* CK_SSL */
-" If <switches> are specified, they are applied to all subsequent HTTP",
-" actions (GET, PUT, ...) until an HTTP CLOSE command is executed.",
-" A URL can be included in place of the hostname and service or port.",
-" ",
-"HTTP CLOSE",
-" Instructs Kermit to close any open HTTP connection and clear any saved",
-" switch values.",
-" ",
-"HTTP [ <switches> ] CONNECT <host>[:<port>]",
-" Instructs the server to establish a connection with the specified host",
-" and to redirect all data transmitted between Kermit and the host for the",
-" life of the connection.",
-" ",
-"HTTP [ <switches> ] GET <remote-filename> [ <local-filename> ]",
-" Retrieves the named file on the currently open HTTP connection. The",
-" default local filename is the same as the remote filename, but with any",
-" path stripped. If you want the file to be displayed on the screen instead",
-" of stored on disk, include the /TOSCREEN switch and omit the local",
-" filename. If you give a URL instead of a remote filename, this commands",
-" opens the connection, GETs the file, and closes the connection; the same",
-" is true for the remaining HTTP commands for which you can specify a",
-" remote filename, directory name, or path.",
-" ",
-"HTTP [ <switches> ] HEAD <remote-filename> [ <local-filename> ]",
-" Like GET except without actually getting the file; instead it gets only",
-" the headers, storing them into the given file (if a local filename is",
-" specified), one line per header item as shown in the /ARRAY: switch",
-" description.",
-" ",
-"HTTP [ <switches> ] INDEX <remote-directory> [ <local-filename> ]",
-" Retrieves the file listing for the given server directory.",
-" NOTE: This command is not supported by most Web servers, and even when",
-" the server understand it, there is no stardard response format.",
-" ",
-"HTTP [ <switches> ] POST [ /MIME-TYPE:<type> ] <local-file> <remote-path>",
-" [ <dest-file> ]",
-" Used to send a response as if it were sent from a form. The data to be",
-" posted must be read from a file.",
-" ",
-"HTTP [ <switches> ] PUT [ /MIME-TYPE:<type> ] <local-file> <remote-file>",
-" [ <dest-file> ]",
-" Uploads the given local file to server file. If the remote filename is",
-" omitted, the local name is used, but with any path stripped.",
-" ",
-"HTTP [ <switches> ] DELETE <remote-filename>",
-" Instructs the server to delete the specified filename.",
-" ",
-"where <switches> are:",
-"/AGENT:<user-agent>",
-" Identifies the client to the server; \"C-Kermit\" or \"Kermit-95\"",
-" by default.",
-" ",
-"/HEADER:<header-line>",
-" Used for specifying any optional headers. A list of headers is provided",
-" using braces for grouping:",
-" ",
-" /HEADER:{{<tag>:<value>}{<tag>:<value>}...}",
-" ",
-" For a listing of valid <tag> value and <value> formats see RFC 1945:",
-" \"Hypertext Transfer Protocol -- HTTP/1.0\". A maximum of eight headers",
-" may be specified.",
-" ",
-"/TOSCREEN",
-" Display server responses on the screen.",
-" ",
-"/USER:<name>",
-" In case a page requires a username for access.",
-" ",
-"/PASSWORD:<password>",
-" In case a page requires a password for access.",
-" ",
-"/ARRAY:<arrayname>",
-" Tells Kermit to store the response headers in the given array, one line",
-" per element. The array need not be declared in advance. Example:",
-" ",
-" http /array:c get kermit/index.html",
-" 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.",
-" ",
-""
-};
-#endif /* NOHTTP */
-
-#ifdef CK_KERBEROS
-static char *hmxxauth[] = {
-"Syntax:",
-"AUTHENTICATE { KERBEROS4, KERBEROS5 [ switches ] } <action> [ switches ]",
-" Obtains or destroys Kerberos tickets and lists information about them.",
-" Actions are INITIALIZE, DESTROY, and LIST-CREDENTIALS. KERBEROS4 can be",
-" abbreviated K4 or KRB4; KERBEROS5 can be abbreviated K5 or KRB5. Use ? to",
-" see which keywords, switches, or other quantities are valid at each point",
-" in the command.",
-" ",
-" The actions are INITIALIZE, DESTROY, and LIST-CREDENTIALS:",
-" ",
-" AUTH { K4, K5 } { INITIALIZE [switches], DESTROY,",
-" LIST-CREDENTIALS [switches] }",
-" ",
-" The INITIALIZE action is the most complex, and its format is different",
-" for Kerberos 4 and Kerberos 5. The format for Kerberos 4 is:",
-" ",
-" AUTH K4 INITIALIZE [ /INSTANCE:<name> /LIFETIME:<minutes> -",
-" /PASSWORD:<password> /PREAUTH /REALM:<name> <principal> ]",
-" ",
-" All switches are optional. Kerberos 4 INITIALIZE switches are:",
-" ",
-" /INSTANCE:<name>",
-" Allows an Instance (such as a hostname) to be specified.",
-" ",
-" /LIFETIME:<number>",
-" Specifies the requested lifetime in minutes for the ticket. If no",
-" lifetime is specified, 600 minutes is used. If the lifetime is greater",
-" than the maximum supported by the ticket granting service, the resulting",
-" lifetime is shortened accordingly.",
-" ",
-" /NOT-PREAUTH",
-" Instructs Kermit to send a ticket getting ticket (TGT) request to the",
-" KDC without any preauthentication data.",
-" ",
-" /PASSWORD:<string>",
-" Allows a password to be included on the command line or in a script",
-" file. If no /PASSWORD switch is included, you are prompted on a separate"
-,
-" line. The password switch is provided on a use-at-your-own-risk basis",
-" for use in automated scripts. WARNING: Passwords should not be stored in"
-,
-" files.",
-" ",
-" /PREAUTH",
-" Instructs Kermit to send a preauthenticated Ticket-Getting Ticket (TGT)",
-" request to the KDC instead of a plaintext request. The default when",
-" supported by the Kerberos libraries.",
-" ",
-" /REALM:<name>",
-" Allows a realm to be specified (overriding the default realm).",
-" ",
-" <principal>",
-" Your identity in the given or default Kerberos realm, of the form:",
-" userid[.instance[.instance]]@[realm] ",
-" Can be omitted if it is the same as your username or SET LOGIN USERID",
-" value on the client system.",
-" ",
-" The format for Kerberos 5 is as follows:",
-" ",
-" AUTH K5 [ /CACHE:<filename> ] { INITIALIZE [ switches ], DESTROY,",
-" LIST-CREDENTIALS ...}",
-" ",
-"The INITIALIZE command for Kerberos 5 can include a number of switches;",
-"all are optional:",
-" ",
-"AUTH K5 [ /CACHE:<filename> ] INITITIALIZE [ /ADDRESSES:<addr-list>",
-" /FORWARDABLE /KERBEROS4 /LIFETIME:<minutes> /PASSWORD:<password>",
-" /POSTDATE:<date-time> /PROXIABLE /REALM:<name> /RENEW /RENEWABLE:<minutes>",
-" /SERVICE:<name> /VALIDATE <principal> ]",
-" ",
-" All Kerberos 5 INITIALIZE switches are optional:",
-" ",
-" /ADDRESSES:{list of ip-addresses}",
-" Specifies a list of IP addresses that should be placed in the Ticket",
-" Getting Ticket in addition to the local machine addresses.",
-" ",
-" /FORWARDABLE",
-" Requests forwardable tickets.",
-" ",
-" /INSTANCE:<name>",
-" Allows an Instance (such as a hostname) to be specified.",
-" ",
-" /KERBEROS4",
-" Instructs Kermit to get Kerberos 4 tickets in addition to Kerberos 5",
-" tickets. If Kerberos 5 tickets are not supported by the server, a",
-" mild warning is printed and Kerberos 4 tickets are requested.",
-" ",
-" /LIFETIME:<number>",
-" Specifies the requested lifetime in minutes for the ticket. If no",
-" lifetime is specified, 600 minutes is used. If the lifetime is greater",
-" than the maximum supported by the ticket granting service, the resulting",
-" lifetime is shortened.",
-" ",
-" /NO-KERBEROS4",
-" Instructs Kermit to not attempt to retrieve Kerberos 4 credentials.",
-" ",
-" /NOT-FORWARDABLE",
-" Requests non-forwardable tickets.",
-" ",
-" /NOT-PROXIABLE",
-" Requests non-proxiable tickets.",
-" ",
-" /PASSWORD:<string>",
-" Allows a password to be included on the command line or in a script",
-" file. If no /PASSWORD switch is included, you are prompted on a separate"
-,
-" line. The password switch is provided on a use-at-your-own-risk basis",
-" for use in automated scripts. WARNING: Passwords should not be stored in"
-,
-" files.",
-" ",
-" /POSTDATE:<date-time>",
-" Requests a postdated ticket, valid starting at <date-time>. Postdated",
-" tickets are issued with the invalid flag set, and need to be fed back to",
-" the KDC before use with the /VALIDATE switch. Type HELP DATE for info",
-" on date-time formats.",
-" ",
-" /PROXIABLE",
-" Requests proxiable tickets.",
-" ",
-" /REALM:<string>",
-" Allows an alternative realm to be specified.",
-" ",
-" /RENEW",
-" Requests renewal of a renewable Ticket-Granting Ticket. Note that ",
-" an expired ticket cannot be renewed even if it is within its renewable ",
-" lifetime.",
-" ",
-" /RENEWABLE:<number>",
-" Requests renewable tickets, with a total lifetime of <number> minutes.",
-" ",
-" /SERVICE:<string>",
-" Allows a service other than the ticket granting service to be specified.",
-" ",
-" /VALIDATE",
-" Requests that the Ticket Granting Ticket in the cache (with the invalid",
-" flag set) be passed to the KDC for validation. If the ticket is within",
-" its requested time range, the cache is replaced with the validated",
-" ticket.",
-" ",
-" <principal>",
-" Your identity in the given or default Kerberos realm, of the form:",
-" userid[/instance][@realm] ",
-" Can be omitted if it is the same as your username or SET LOGIN USERID",
-" value on the client system.",
-" ",
-" Note: Kerberos 5 always attempts to retrieve a Ticket-Getting Ticket (TGT)",
-" using the preauthenticated TGT request.",
-" ",
-" AUTHORIZE K5 LIST-CREDENTIALS [ /ADDRESSES /FLAGS /ENCRYPTION ]",
-" ",
-" Shows start time, expiration time, service or principal name, plus",
-" the following additional information depending the switches:",
-" ",
-" /ADDRESSES displays the hostnames and/or IP addresses embedded within",
-" the tickets.",
-" ",
-" /FLAGS provides the following information (if applicable) for each ticket:",
-" F - Ticket is Forwardable",
-" f - Ticket was Forwarded",
-" P - Ticket is Proxiable",
-" p - Ticket is a Proxy",
-" D - Ticket may be Postdated",
-" d - Ticket has been Postdated",
-" i - Ticket is Invalid",
-" R - Ticket is Renewable",
-" I - Ticket is the Initial Ticket",
-" H - Ticket has been authenticated by Hardware",
-" A - Ticket has been Pre-authenticated",
-" ",
-" /ENCRYPTION displays the encryption used by each ticket (if applicable):",
-" DES-CBC-CRC",
-" DES-CBC-MD4",
-" DES-CBC-MD5",
-" DES3-CBC-SHA",
-""
-};
-#endif /* CK_KERBEROS */
-
-#ifndef NOCSETS
-static char *hmxxassoc[] = {
-"ASSOCIATE FILE-CHARACTER-SET <file-character-set> <transfer-character-set>",
-" Tells C-Kermit that whenever the given file-character set is selected, and",
-" SEND CHARACTER-SET (q.v.) is AUTOMATIC, the given transfer character-set",
-" is selected automatically.",
-" ",
-"ASSOCIATE XFER-CHARACTER-SET <xfer-character-set> <file-character-set>",
-" Tells C-Kermit that whenever the given transfer-character set is selected,",
-" either by command or by an announcer attached to an incoming text file,",
-" and SEND CHARACTER-SET is AUTOMATIC, the specified file character-set is",
-" to be selected automatically. Synonym: ASSOCIATE TRANSFER-CHARACTER-SET.",
-" ",
-"Use SHOW ASSOCIATIONS to list the current character-set associations, and",
-"SHOW CHARACTER-SETS to list the current settings.",
-""
-};
-#endif /* NOCSETS */
-
-static char *hmxxpat[] = {
-"A \"pattern\" is notation used in a search string when searching through",
-"text. C-Kermit uses three kinds of patterns: floating patterns, anchored",
-"patterns, and wildcards. Wildcards are anchored patterns that are used to",
-"match file names; type HELP WILDCARD to learn about them.",
-" ",
-"In a pattern, certain characters are special:",
-" ",
-"* Matches any sequence of zero or more characters. For example, \"k*t\"",
-" matches all strings that start with \"k\" and end with \"t\" including",
-" \"kt\", \"kit\", \"knight\", or \"kermit\".",
-" ",
-#ifdef VMS
-"% Matches any single character. For example, \"k%%%%t\" matches all strings",
-#else
-"? Matches any single character. For example, \"k????t\" matches all strings",
-#endif /* VMS */
-" that are exactly 6 characters long and start with \"k\" and end with",
-#ifdef VMS
-" with \"t\".",
-#else
-" with \"t\". When typing commands at the prompt, you must precede any",
-" question mark to be used for matching by a backslash (\\) to override the",
-" normal function of question mark, which is providing menus and file lists.",
-#endif /* VMS */
-" ",
-#ifdef OS2ORUNIX
-#ifdef CKREGEX
-"[abc]",
-" Square brackets enclosing a list of characters matches any character in",
-" the list. Example: h[aou]t matches hat, hot, and hut.",
-" ",
-"[a-z]",
-" Square brackets enclosing a range of characters matches any character in",
-" the range; a hyphen (-) separates the low and high elements of the range.",
-" For example, [a-z] matches any character from a to z.",
-" ",
-"[acdm-z]",
-" Lists and ranges may be combined. This example matches a, c, d, or any",
-" letter from m through z.",
-" ",
-"{string1,string2,...}",
-" Braces enclose a list of strings to be matched. For example:",
-" ker{mit,nel,beros} matches kermit, kernel, and kerberos. The strings",
-" may themselves contain *, ?, [abc], [a-z], or other lists of strings.",
-#endif /* CKREGEX */
-#endif /* OS2ORUNIX */
-#ifndef NOSPL
-" ",
-"To force a special pattern character to be taken literally, precede it with",
-"a backslash, e.g. [a\\-z] matches a, hyphen, and z rather than a through z.",
-" ",
-"A floating pattern can also include the following special characters:",
-" ",
-"^ (First character of pattern) Anchors the pattern at the beginning.",
-"$ (Last character of pattern) Anchors the pattern at the end.",
-" ",
-"If a floating pattern does not start with \"^\", the pattern can match",
-"anywhere in the string instead of only at the beginning; in other words, a",
-"leading \"*\" is assumed. Similarly, if the pattern doesn't end with \"$\",",
-"a trailing \"*\" is assumed.",
-" ",
-"The following commands and functions use floating patterns:",
-" GREP [ <switches> ] <pattern> <filespec>",
-" TYPE /MATCH:<pattern> <file>",
-" \\farraylook(<pattern>,<arrayname>)",
-" \\fsearch(<pattern>,<string>[,<offset>])",
-" \\frsearch(<pattern>,<string>[,<offset>])",
-" The /EXCEPT: clause in SEND, GET, DELETE, etc.",
-" ",
-"Example:",
-" \\fsearch(abc,xxabcxxx) succeeds because xxabcxx contains abc.",
-" \\fsearch(^abc,xxabcxx) fails because xxabcxx does not start with abc.",
-" ",
-"All other commands and functions that use patterns use anchored patterns,",
-"meaning that ^ and $ are not treated specially, and * is not assumed at the",
-"beginning or end of the pattern. This is true mainly of filename patterns",
-"(wildcards), since you would not want a command like \"delete x\" to delete",
-"all files whose names contained \"x\"!",
-" ",
-"You can use anchored patterns not only in filenames, but also in SWITCH",
-"case labels, in the INPUT and MINPUT commands, and in file binary- and",
-"text-patterns for filenames. The IF MATCH pattern is also anchored.",
-#endif /* NOSPL */
-"" };
-
-static char *hmxxwild[] = {
-
-"A \"wildcard\" is a notation used in a filename to match multiple files.",
-"For example, in \"send *.txt\" the asterisk is a wildcard. Kermit commands",
-"that accept filenames also accepts wildcards, except commands that are",
-"allowed to operate on only one file, such as TRANSMIT.",
-"This version of Kermit accepts the following wildcards:",
-" ",
-"* Matches any sequence of zero or more characters. For example, \"ck*.c\"",
-" matches all files whose names start with \"ck\" and end with \".c\"",
-" including \"ck.c\".",
-" ",
-#ifdef VMS
-"% Matches any single character. For example, \"ck%.c\" matches all files",
-#else
-"? Matches any single character. For example, \"ck?.c\" matches all files",
-#endif /* VMS */
-" whose names are exactly 5 characters long and start with \"ck\" and end",
-#ifdef VMS
-" with \".c\".",
-#else
-" with \".c\". When typing commands at the prompt, you must precede any",
-" question mark to be used for matching by a backslash (\\) to override the",
-" normal function of question mark, which is providing menus and file lists.",
-#endif /* VMS */
-" ",
-#ifdef OS2ORUNIX
-#ifdef CKREGEX
-"[abc]",
-" Square brackets enclosing a list of characters matches any character in",
-" the list. Example: ckuusr.[ch] matches ckuusr.c and ckuusr.h.",
-" ",
-"[a-z]",
-" Square brackets enclosing a range of characters matches any character in",
-" the range; a hyphen (-) separates the low and high elements of the range.",
-" For example, [a-z] matches any character from a to z.",
-" ",
-"[acdm-z]",
-" Lists and ranges may be combined. This example matches a, c, d, or any",
-" letter from m through z.",
-" ",
-"{string1,string2,...}",
-" Braces enclose a list of strings to be matched. For example:",
-" ck{ufio,vcon,cmai}.c matches ckufio.c, ckvcon.c, or ckcmai.c. The strings",
-" may themselves contain *, ?, [abc], [a-z], or other lists of strings.",
-#endif /* CKREGEX */
-#endif /* OS2ORUNIX */
-" ",
-"To force a special pattern character to be taken literally, precede it with",
-"a backslash, e.g. [a\\-z] matches a, hyphen, and z rather than a through z.",
-" ",
-#ifndef NOSPL
-"Similar notation can be used in general-purpose string matching. Type HELP",
-"PATTERNS for details. Also see HELP SET MATCH.",
-#endif /* NOSPL */
-"" };
-
-#ifndef NOXFER
-static char *hmxxfast[] = {
-"FAST, CAUTIOUS, and ROBUST are predefined macros that set several",
-"file-transfer parameters at once to achieve the desired file-transfer goal.",
-"FAST chooses a large packet size, a large window size, and a fair amount of",
-"control-character unprefixing at the risk of possible failure on some",
-"connections. FAST is the default tuning in C-Kermit 7.0 and later. In case",
-"FAST file transfers fail for you on a particular connection, try CAUTIOUS.",
-"If that fails too, try ROBUST. You can also change the definitions of each",
-"macro with the DEFINE command. To see the current definitions, type",
-"\"show macro fast\", \"show macro cautious\", or \"show macro robust\".",
-""
-};
-#endif /* NOXFER */
-
-#ifdef VMS
-static char * hmxxpurge[] = {
-"Syntax: PURGE [ switches ] [ filespec ]",
-" Runs the DCL PURGE command. Switches and filespec are not parsed or",
-" verified by Kermit, but passed directly to DCL.",
-""
-};
-#else
-#ifdef CKPURGE
-static char * hmxxpurge[] = {
-"Syntax: PURGE [ switches ] [ filespec ]",
-" Deletes backup files; that is, files whose names end in \".~n~\", where",
-" n is a number. PURGE by itself deletes all backup files in the current",
-" directory. Switches:",
-
-" ",
-"/AFTER:date-time",
-#ifdef VMS
-" Specifies that only those files created after the given date-time are",
-#else
-" Specifies that only those files modified after the given date-time are",
-#endif /* VMS */
-" to be purged. HELP DATE for info about date-time formats.",
-" ",
-"/BEFORE:date-time",
-#ifdef VMS
-" Specifies that only those files modified before the given date-time",
-#else
-" Specifies that only those files modified before the given date-time",
-#endif /* VMS */
-" are to be purged.",
-" ",
-"/NOT-AFTER:date-time",
-#ifdef VMS
-" Specifies that only those files modified at or before the given date-time",
-#else
-" Specifies that only those files modified at or before the given date-time",
-#endif /* VMS */
-" are to be purged.",
-" ",
-"/NOT-BEFORE:date-time",
-#ifdef VMS
-" Specifies that only those files modified at or after the given date-time",
-#else
-" Specifies that only those files modified at or after the given date-time",
-#endif /* VMS */
-" are to be purged.",
-" ",
-"/LARGER-THAN:number",
-" Specifies that only those files longer than the given number of bytes are",
-" to be purged.",
-" ",
-"/SMALLER-THAN:number",
-" Specifies that only those files smaller than the given number of bytes are",
-" to be purged.",
-" ",
-"/EXCEPT:pattern",
-" Specifies that any files whose names match the pattern, which can be a",
-" regular filename or may contain wildcards, are not to be purged. To",
-" specify multiple patterns (up to 8), use outer braces around the group",
-" and inner braces around each pattern:",
-" ",
-" /EXCEPT:{{pattern1}{pattern2}...}",
-" ",
-#ifdef UNIXOROSK
-"/DOTFILES",
-" Include (purge) files whose names begin with \".\".",
-" ",
-"/NODOTFILES",
-" Skip (don't purge) files whose names begin with \".\".",
-" ",
-#endif /* UNIXOROSK */
-#ifdef RECURSIVE
-"/RECURSIVE",
-" Descends through the current or specified directory tree.",
-" ",
-#endif /* RECURSIVE */
-"/KEEP:n",
-" Retain the 'n' most recent (highest-numbered) backup files for each file.",
-" By default, none are kept. If /KEEP is given without a number, 1 is used.",
-" ",
-"/LIST",
-" Display each file as it is processed and say whether it is purged or kept.",
-" Synonyms: /LOG, /VERBOSE.",
-" ",
-"/NOLIST",
-" The PURGE command should operate silently (default).",
-" Synonyms: /NOLOG, /QUIET.",
-" ",
-"/HEADING",
-" Print heading and summary information.",
-" ",
-"/NOHEADING",
-" Don't print heading and summary information.",
-" ",
-"/PAGE",
-" When /LIST is in effect, pause at the end of each screenful, even if",
-" COMMAND MORE-PROMPTING is OFF.",
-" ",
-"/NOPAGE",
-" Don't pause, even if COMMAND MORE-PROMPTING is ON.",
-" ",
-"/ASK",
-" Interactively ask permission to delete each backup file.",
-" ",
-"/NOASK",
-" Purge backup files without asking permission.",
-" ",
-"/SIMULATE",
-" Inhibits the actual deletion of files; use to preview which files would",
-" actually be deleted. Implies /LIST.",
-" ",
-"Use SET OPTIONS PURGE [ switches ] to change defaults; use SHOW OPTIONS to",
-"display customized defaults. Also see HELP DELETE, HELP WILDCARD.",
-""
-};
-#endif /* CKPURGE */
-#endif /* VMS */
-
-static char *hmxxclo[] = {
-"Syntax: CLOSE [ item ]",
-" Close the indicated item. The default item is CONNECTION, which is the",
-" current SET LINE or SET HOST connection. The other items are:",
-" ",
-#ifdef CKLOGDIAL
-" CX-LOG (connection log, opened with LOG CX)",
-#endif /* CKLOGDIAL */
-#ifndef NOLOCAL
-" SESSION-LOG (opened with LOG SESSION)",
-#endif /* NOLOCAL */
-#ifdef TLOG
-" TRANSACTION-LOG (opened with LOG TRANSACTIONS)",
-#endif /* TLOG */
-" PACKET-LOG (opened with LOG PACKETS)",
-#ifdef DEBUG
-" DEBUG-LOG (opened with LOG DEBUG)",
-#endif /* DEBUG */
-#ifndef NOSPL
-" READ-FILE (opened with OPEN READ)",
-" WRITE-FILE (opened with OPEN WRITE or OPEN APPEND)",
-#endif /* NOSPL */
-" ",
-"Type HELP LOG and HELP OPEN for further info.",
-""
-};
-
-#ifdef CKLEARN
-static char * hmxxlearn[] = {
-"Syntax: LEARN [ /ON /OFF /CLOSE ] [ filename ]",
-" Records a login script. If you give a filename, the file is opened for",
-" subsequent recording. If you don't give any switches, /ON is assumed.",
-" /ON enables recording to the current file (if any); /OFF disables",
-" recording. /CLOSE closes the current file (if any). After LEARN /CLOSE",
-" or exit from Kermit, your script is available for execution by the TAKE",
-" command.",
-""
-};
-#endif /* CKLEARN */
-
-#ifdef CK_MINPUT
-static char *hmxxminp[] = {
-"Syntax: MINPUT n [ string1 [ string2 [ ... ] ] ]",
-"Example: MINPUT 5 Login: {Username: } {NO CARRIER} BUSY RING",
-" For use in script programs. Waits up to n seconds for any one of the",
-" strings to arrive on the communication device. If no strings are given,",
-" the command waits for any character at all to arrive. Strings are",
-" separated by spaces; use { braces } for grouping. If any of the strings",
-" is encountered within the timeout interval, the command succeeds and the",
-" \\v(minput) variable is set to the number of the string that was matched:",
-" 1, 2, 3, etc. If none of the strings arrives, the command times out,",
-" fails, and \\v(minput) is set to 0. If the timeout interval is 0 the",
-" MINPUT command does not wait; i.e. the given text must already be",
-" available for reading for the MINPUT command to succeed. If the interval",
-" is negative, the MINPUT command waits forever.",
-" ",
-"Also see: INPUT, REINPUT, SET INPUT.",
-"" };
-#endif /* CK_MINPUT */
-
-#ifndef NOLOCAL
-static char *hmxxcon[] = {
-"Syntax: CONNECT (or C, or CQ) [ switches ]",
-" Connect to a remote computer via the serial communications device given in",
-#ifdef OS2
-" the most recent SET PORT command, or to the network host named in the most",
-#else
-" the most recent SET LINE command, or to the network host named in the most",
-#endif /* OS2 */
-" recent SET HOST command. Type the escape character followed by C to get",
-" back to the C-Kermit prompt, or followed by ? for a list of CONNECT-mode",
-#ifdef OS2
-" escape commands. You can also assign the \\Kexit verb to the key or",
-" key-combination of your choice; by default it is assigned to Alt-x.",
-#else
-" escape commands.",
-" ",
-"Include the /QUIETLY switch to suppress the informational message that",
-"tells you how to escape back, etc. CQ is a synonym for CONNECT /QUIETLY.",
-#endif /* OS2 */
-" ",
-"Other switches include:",
-#ifdef CK_TRIGGER
-" ",
-"/TRIGGER:string",
-" One or more strings to look for that will cause automatic return to",
-" command mode. To specify one string, just put it right after the",
-" colon, e.g. \"/TRIGGER:Goodbye\". If the string contains any spaces, you",
-" must enclose it in braces, e.g. \"/TRIGGER:{READY TO SEND...}\". To",
-" specify more than one trigger, use the following format:",
-" ",
-" /TRIGGER:{{string1}{string2}...{stringn}}",
-" ",
-" Upon return from CONNECT mode, the variable \\v(trigger) is set to the",
-" trigger string, if any, that was actually encountered. This value, like",
-" all other CONNECT switches applies only to the CONNECT command with which",
-" it is given, and overrides (temporarily) any global SET TERMINAL TRIGGER",
-" string that might be in effect.",
-#endif /* CK_TRIGGER */
-#ifdef OS2
-" ",
-"/IDLE-LIMIT:number",
-" The number of seconds of idle time, after which Kermit returns",
-" automatically to command mode; default 0 (no limit).",
-" ",
-"/IDLE-INTERVAL:number",
-" The number of seconds of idle time, after which Kermit automatically",
-" transmits the idle string.",
-" ",
-"/IDLE-STRING:string",
-" The string to transmit whenever the idle interval has passed.",
-" ",
-"/TIME-LIMIT:number",
-" The maximum number of seconds for which the CONNECT session may last.",
-" The default is 0 (no limit). If a nonzero number is given, Kermit returns",
-" automatically to command mode after this many seconds.",
-#endif /* OS2 */
-"" };
-#endif /* NOLOCAL */
-
-static char *hmxxmget[] = {
-"Syntax: MGET [ switches... ] remote-filespec [ remote-filespec ... ]",
-" ",
-"Just like GET (q.v.) except allows a list of remote file specifications,",
-"separated by spaces.",
-""
-};
-
-static char *hmxxget[] = {
-"Syntax: GET [ switches... ] remote-filespec [ as-name ]",
-" Tells the other Kermit, which must be in (or support autoswitching into)",
-" server mode, to send the named file or files. If the remote-filespec or",
-" the as-name contain spaces, they must be enclosed in braces. If as-name",
-" is the name of an existing local directory, incoming files are placed in",
-" that directory; if it is the name of directory that does not exist, Kermit",
-" tries to create it. Optional switches include:",
-" ",
-"/AS-NAME:text",
-" Specifies \"text\" as the name to store the incoming file under, or",
-" directory to store it in. You can also specify the as-name as the second",
-" filename on the GET command line.",
-" ",
-"/BINARY",
-" Performs this transfer in binary mode without affecting the global",
-" transfer mode.",
-" ",
-"/COMMAND",
-" Receives the file into the standard input of a command, rather than saving",
-" it on disk. The /AS-NAME or the second \"filename\" on the GET command",
-" line is interpreted as the name of a command.",
-" ",
-"/DELETE",
-" Asks the other Kermit to delete the file (or each file in the group)",
-" after it has been transferred successfully.",
-" ",
-"/EXCEPT:pattern",
-" Specifies that any files whose names match the pattern, which can be a",
-" regular filename, or may contain \"*\" and/or \"?\" metacharacters,",
-" are to be refused. To specify multiple patterns (up to 8), use outer",
-" braces around the group, and inner braces around each pattern:",
-" ",
-" /EXCEPT:{{pattern1}{pattern2}...}",
-" ",
-"/FILENAMES:{CONVERTED,LITERAL}",
-" Overrides the global SET FILE NAMES setting for this transfer only.",
-" ",
-"/FILTER:command",
-" Causes the incoming file to passed through the given command (standard",
-" input/output filter) before being written to disk.",
-" ",
-#ifdef VMS
-"/IMAGE",
-" Transfer in image mode.",
-" ",
-#endif /* VMS */
-#ifdef CK_LABELED
-"/LABELED",
-" VMS and OS/2 only: Specifies labeled transfer mode.",
-" ",
-#endif /* CK_LABELED */
-
-"/MOVE-TO:directory-name",
-" Specifies that each file that arrives should be moved to the specified",
-" directory after, and only if, it has been received successfully.",
-" ",
-"/PATHNAMES:{OFF,ABSOLUTE,RELATIVE,AUTO}",
-" Overrides the global SET RECEIVE PATHNAMES setting for this transfer.",
-" ",
-"/PIPES:{ON,OFF}",
-" Overrides the TRANSFER PIPES setting for this command only. ON allows",
-" reception of files with names like \"!tar xf -\" to be automatically",
-" directed to a pipeline.",
-" ",
-"/QUIET",
-" When sending in local mode, this suppresses the file-transfer display.",
-" ",
-"/RECOVER",
-" Used to recover from a previously interrupted transfer; GET /RECOVER",
-" is equivalent REGET. Works only in binary mode.",
-" ",
-"/RECURSIVE",
-" Tells the server to descend through the directory tree when locating",
-" the files to be sent.",
-" ",
-"/RENAME-TO:string",
-" Specifies that each file that arrives should be renamed as specified",
-" after, and only if, it has been received successfully. The string should",
-" normally contain variables like \\v(filename) or \\v(filenum).",
-" ",
-"/TEXT",
-" Performs this transfer in text mode without affecting the global",
-" transfer mode.",
-" ",
-"/TRANSPARENT",
-" Inhibits character-set translation of incoming text files for the duration",
-" of the GET command without affecting subsequent commands.",
-" ",
-"Also see HELP MGET, HELP SEND, HELP RECEIVE, HELP SERVER, HELP REMOTE.",
-""};
-
-static char *hmxxlg[] = {
-"Syntax: LOG (or L) log-type [ filename [ { NEW, APPEND } ] ]",
-" ",
-"Record information in a log file:",
-" ",
-#ifdef CKLOGDIAL
-"CX",
-" Connections made with SET LINE, SET PORT, SET HOST, DIAL, TELNET, etc.",
-" The default filename is CX.LOG in your home directory and APPEND is the",
-" default mode for opening.",
-" ",
-#endif /* CKLOGDIAL */
-#ifdef DEBUG
-"DEBUG",
-" Debugging information, to help track down bugs in the C-Kermit program.",
-" The default log name is debug.log in current directory.",
-" ",
-#endif /* DEBUG */
-"PACKETS",
-" Kermit packets, to help with protocol problems. The default filename is",
-" packet.log in current directory.",
-" ",
-#ifndef NOLOCAL
-"SESSION",
-" Records your CONNECT session (default: session.log in current directory).",
-" ",
-#endif /* NOLOCAL */
-#ifdef TLOG
-"TRANSACTIONS",
-" Names and statistics about files transferred (default: transact.log in",
-" current directory; see HELP SET TRANSACTION-LOG for transaction-log format",
-" options.)",
-" ",
-#endif /* TLOG */
-"If you include the APPEND keyword after the filename, the existing log file,",
-"if any, is appended to; otherwise a new file is created (except APPEND is",
-"the default for the connection log). Use CLOSE <keyword> to stop logging.",
-#ifdef OS2ORUNIX
-" ",
-"Note: The filename can also be a pipe, e.g.:",
-" ",
-" log transactions |lpr",
-" log debug {| grep \"^TELNET\" > debug.log}",
-" ",
-"Braces are required if the pipeline or filename contains spaces.",
-#endif /* OS2ORUNIX */
-"" };
-
-#ifndef NOSCRIPT
-static char *hmxxlogi[] = { "\
-Syntax: SCRIPT text",
-" A limited and cryptic \"login assistant\", carried over from old C-Kermit",
-" releases for comptability, but not recommended for use. Instead, please",
-" use the full script programming language described in chapters 17-19 of",
-" \"Using C-Kermit\".",
-" ",
-" Login to a remote system using the text provided. The login script",
-" is intended to operate similarly to UNIX uucp \"L.sys\" entries.",
-" A login script is a sequence of the form:",
-" ",
-" expect send [expect send] . . .",
-" ",
-" where 'expect' is a prompt or message to be issued by the remote site, and",
-" 'send' is the names, numbers, etc, to return. The send may also be the",
-" keyword EOT to send Control-D, or BREAK (or \\\\b) to send a break signal.",
-" Letters in send may be prefixed by ~ to send special characters:",
-" ",
-" ~b backspace, ~s space, ~q '?', ~n linefeed, ~r return, ~c don\'t",
-" append a return, and ~o[o[o]] for octal of a character. As with some",
-" UUCP systems, sent strings are followed by ~r unless they end with ~c.",
-" ",
-" Only the last 7 characters in each expect are matched. A null expect,",
-" e.g. ~0 or two adjacent dashes, causes a short delay. If you expect",
-" that a sequence might not arrive, as with uucp, conditional sequences",
-" may be expressed in the form:",
-" ",
-" -send-expect[-send-expect[...]]",
-" ",
-" where dashed sequences are followed as long as previous expects fail.",
-"" };
-#endif /* NOSCRIPT */
-
-#ifndef NOFRILLS
-static char * hmxxtyp[] = {
-"Syntax: TYPE [ switches... ] file",
-" Displays a file on the screen. Pauses automatically at end of each",
-" screenful if COMMAND MORE-PROMPTING is ON. Optional switches:",
-" ",
-" /PAGE",
-" Pause at the end of each screenful even if COMMAND MORE-PROMPTING OFF.",
-" Synonym: /MORE",
-" /NOPAGE",
-" Don't pause at the end of each screen even if COMMAND MORE-PROMPTING ON."
-,
-" /HEAD:n",
-" Only type the first 'n' lines of the file.",
-" /TAIL:n",
-" Only type the last 'n' lines of the file.",
-" /MATCH:pattern",
-" Only type lines that match the given pattern. HELP WILDCARDS for info",
-" info about patterns. /HEAD and /TAIL apply after /MATCH.",
-" /PREFIX:string",
-" Print the given string at the beginning of each line.",
-" /NUMBER",
-" Add line numbers (conflicts with /PREFIX)",
-" /WIDTH:number",
-" Truncate each line at the given column number before printing.",
-#ifdef KUI
-" Or when combined with /GUI specifies the width of the dialog box.",
-" /HEIGHT:number",
-" When combined with /GUI specifies the height of the dialog box.",
-" /GUI:string",
-" Specifies the title to use for the dialog box.",
-#endif /* KUI */
-" /COUNT",
-" Count lines (and matches) and print the count(s) but not the lines.",
-#ifdef UNICODE
-" /CHARACTER-SET:name",
-" Translates from the named character set.",
-#ifndef OS2
-" /TRANSLATE-TO:name",
-" Translates to the named character set (default = current file charset).",
-#endif /* OS2 */
-" /TRANSPARENT",
-" Inhibits character-set translation.",
-#endif /* UNICODE */
-" /OUTPUT:name",
-" Sends results to the given file. If this switch is omitted, the",
-" results appear on your screen. This switch overrides any express or",
-" implied /PAGE switch.",
-" ",
-"You can use SET OPTIONS TYPE to set the defaults for /PAGE or /NOPAGE and",
-"/WIDTH. Use SHOW OPTIONS to see current TYPE options.",
-""
-};
-
-static char * hmxxcle[] = {
-"Syntax: CLEAR [ item-name ]",
-" ",
-"Clears the named item. If no item is named, DEVICE-AND-INPUT is assumed.",
-" ",
-" ALARM Clears any pending alarm (see SET ALARM).",
-#ifdef CK_APC
-" APC-STATUS Clears Application Program Command status.",
-#endif /* CK_APC */
-#ifdef PATTERNS
-" BINARY-PATTERNS Clears the file binary-patterns list.",
-#endif /* PATTERNS */
-#ifdef OS2
-" COMMAND-SCREEN Clears the current command screen.",
-#endif /* OS2 */
-" DEVICE Clears the current port or network input buffer.",
-" DEVICE-AND-INPUT Clears both the device and the INPUT buffer.",
-" DIAL-STATUS Clears the \\v(dialstatus) variable.",
-" \
-INPUT Clears the INPUT-command buffer and the \\v(input) variable.",
-" KEYBOARD-BUFFER Clears the command terminal keyboard input buffer.",
-#ifdef OS2
-" \
-SCROLLBACK empties the scrollback buffer including the current screen.",
-#endif /* OS2 */
-" SEND-LIST Clears the current SEND list (see ADD).",
-#ifdef OS2
-" \
-TERMINAL-SCREEN Clears the current screen a places it into the scrollback.",
-" buffer.",
-#endif /* OS2 */
-#ifdef PATTERNS
-" TEXT-PATTERNS Clears the file text-patterns list.",
-#endif /* PATTERNS */
-""};
-#endif /* NOFRILLS */
-
-static char * hmxxdate[] = {
-"Syntax: DATE [ date-time [ timezone ] ] [ delta-time ]",
-" Prints a date-time in standard format: yyyymmdd_hh:mm:ss.",
-" Various date-time formats are accepted:",
-" ",
-" . The date, if given, must precede the time.",
-" . The year must be four digits or else a 2-digit format dd mmm yy,",
-" in which case if (yy < 50) yyyy = yy + 2000; else yyyy = yy + 1900.",
-" . If the year comes first, the second field is the month.",
-" . The day, month, and year may be separated by spaces, /, -, or underscore."
-," . The date and time may be separated by spaces or underscore.",
-" . The month may be numeric (1 = January) or spelled out or abbreviated in",
-" English.",
-" . The time may be in 24-hour format or 12-hour format.",
-" . If the hour is 12 or less, AM is assumed unless AM or PM is included.",
-" . If the date is omitted but a time is given, the current date is supplied."
-,
-" . If the time is given but date omitted, 00:00:00 is supplied.",
-" . If both the date and time are omitted, the current date and time are",
-" supplied.",
-" ",
-" The following shortcuts can also be used in place of dates:",
-" ",
-" TODAY",
-" Today's date, optionally followed by a time; 00:00:00 if no time given.",
-" ",
-" YESTERDAY",
-" Yesterday's date, optionally followed by a time (default 00:00:00).",
-" ",
-" TOMORROW",
-" Tomorrows's date, optionally followed by a time (default 00:00:00).",
-" ",
-" Timezone specifications are similar to those used in e-mail and HTTP",
-" headers, either a USA timezone name, e.g. EST or a signed four-digit",
-" timezone offset, {+,-}hhmm, e.g., -0500; it is used to convert date-time,"
-,
-" a local time in that timezone, to GMT which is then converted to the",
-" local time at the host. If no timezone is given, the date-time is local."
-,
-" ",
-" Delta times are given as {+,-}[number date-units][hh[:mm[:ss]]]",
-" A date in the future/past relative to the date-time; date-units may be",
-" DAYS, WEEKS, MONTHS, YEARS: +3days, -7weeks, +3:00, +1month 8:00.",
-" ",
-"All the formats shown above are acceptable as arguments to date-time switches"
-,
-"such as /AFTER: or /BEFORE:, and to functions such as \\fcvtdate(),",
-"\\fdiffdate(), and \\futcdate(), that take date-time strings as arguments.",
-""
-};
-
-
-#ifndef NOXFER
-static char * hmxxsen[] = {
-"Syntax: SEND (or S) [ switches...] [ filespec [ as-name ] ]",
-" Sends the file or files specified by filespec. If the filespec is omitted",
-" the SEND-LIST is used (HELP ADD for more info). The filespec may contain",
-" wildcard characters. An 'as-name' may be given to specify the name(s)",
-" the files(s) are sent under; if the as-name is omitted, each file is",
-" sent under its own name. Also see HELP MSEND, HELP WILDCARD.",
-" Optional switches include:",
-" ",
-#ifndef NOSPL
-"/ARRAY:<arrayname>",
-" Specifies that the data to be sent comes from the given array, such as",
-" \\&a[]. A range may be specified, e.g. SEND /ARRAY:&a[100:199]. Leave",
-" the brackets empty or omit them altogether to send the whole 1-based array."
-,
-" Include /TEXT to have Kermit supply a line terminator at the end of each",
-" array element (and translate character sets if character-set translations",
-" are set up), or /BINARY to treat the array as one long string of characters"
-,
-" to be sent as-is. If an as-name is not specified, the array is sent with",
-" the name _ARRAY_X_, where \"X\" is replaced by actual array letter.",
-" ",
-#endif /* NOSPL */
-
-"/AS-NAME:<text>",
-" Specifies <text> as the name to send the file under instead of its real",
-" name. This is equivalent to giving an as-name after the filespec.",
-" ",
-"/BINARY",
-" Performs this transfer in binary mode without affecting the global",
-" transfer mode.",
-" ",
-"/TEXT",
-" Performs this transfer in text mode without affecting the global",
-" transfer mode.",
-" ",
-"/TRANSPARENT",
-" Inhibits character-set translation for text files for the duration of",
-" the SEND command without affecting subsequent commands.",
-" ",
-"/NOBACKUPFILES",
-" Skip (don't send) Kermit or EMACS backup files (files with names that",
-" end with .~n~, where n is a number).",
-" ",
-#ifdef UNIXOROSK
-"/DOTFILES",
-" Include (send) files whose names begin with \".\".",
-" ",
-"/NODOTFILES",
-" Don't send files whose names begin with \".\".",
-" ",
-"/FOLLOWLINKS",
-" Send files that are pointed to by symbolic links.",
-" ",
-"/NOFOLLOWLINKS",
-" Skip over symbolic links (default).",
-" ",
-#endif /* UNIXOROSK */
-
-#ifdef VMS
-"/IMAGE",
-" Performs this transfer in image mode without affecting the global",
-" transfer mode.",
-" ",
-#endif /* VMS */
-#ifdef CK_LABELED
-"/LABELED",
-" Performs this transfer in labeled mode without affecting the global",
-" transfer mode.",
-" ",
-#endif /* CK_LABELED */
-"/COMMAND",
-" Sends the output from a command, rather than the contents of a file.",
-" The first \"filename\" on the SEND command line is interpreted as the name",
-" of a command; the second (if any) is the as-name.",
-" ",
-"/FILENAMES:{CONVERTED,LITERAL}",
-" Overrides the global SET FILE NAMES setting for this transfer only.",
-" ",
-"/PATHNAMES:{OFF,ABSOLUTE,RELATIVE}",
-" Overrides the global SET SEND PATHNAMES setting for this transfer.",
-" ",
-"/FILTER:command",
-" Specifies a command \
-(standard input/output filter) to pass the file through",
-" before sending it.",
-" ",
-"/DELETE",
-" Deletes the file (or each file in the group) after it has been sent",
-" successfully (applies only to real files).",
-" ",
-"/QUIET",
-" When sending in local mode, this suppresses the file-transfer display.",
-" ",
-"/RECOVER",
-" Used to recover from a previously interrupted transfer; SEND /RECOVER",
-" is equivalent RESEND (use in binary mode only).",
-" ",
-"/RECURSIVE",
-" Tells C-Kermit to look not only in the given or current directory for",
-" files that match the filespec, but also in all its subdirectories, and",
-" all their subdirectories, etc.",
-" ",
-"/RENAME-TO:name",
-" Tells C-Kermit to rename each source file that is sent successfully to",
-" the given name (usually you should include \\v(filename) in the new name,",
-" which is replaced by the original filename.",
-" ",
-"/MOVE-TO:directory",
-" Tells C-Kermit to move each source file that is sent successfully to",
-" the given directory.",
-" ",
-"/STARTING:number",
-" Starts sending the file from the given byte position.",
-" SEND /STARTING:n filename is equivalent to PSEND filename n.",
-" ",
-"/SUBJECT:text",
-" Specifies the subject of an email message, to be used with /MAIL. If the",
-" text contains spaces, it must be enclosed in braces.",
-" ",
-"/MAIL:address",
-" Sends the file as e-mail to the given address; use with /SUBJECT:.",
-" ",
-"/PRINT:options",
-" Sends the file to be printed, with optional options for the printer.",
-" ",
-#ifdef CK_XYZ
-"/PROTOCOL:name",
-" Uses the given protocol to send the file (Kermit, Zmodem, etc) for this",
-" transfer without changing global protocol.",
-" ",
-#endif /* CK_XYZ */
-"/AFTER:date-time",
-#ifdef VMS
-" Specifies that only those files created after the given date-time are",
-#else
-" Specifies that only those files modified after the given date-time are",
-#endif /* VMS */
-" to be sent. HELP DATE for info about date-time formats.",
-" ",
-"/BEFORE:date-time",
-#ifdef VMS
-" Specifies that only those files modified before the given date-time",
-#else
-" Specifies that only those files modified before the given date-time",
-#endif /* VMS */
-" are to be sent.",
-" ",
-"/NOT-AFTER:date-time",
-#ifdef VMS
-" Specifies that only those files modified at or before the given date-time",
-#else
-" Specifies that only those files modified at or before the given date-time",
-#endif /* VMS */
-" are to be sent.",
-" ",
-"/NOT-BEFORE:date-time",
-#ifdef VMS
-" Specifies that only those files modified at or after the given date-time",
-#else
-" Specifies that only those files modified at or after the given date-time",
-#endif /* VMS */
-" are to be sent.",
-" ",
-"/LARGER-THAN:number",
-" Specifies that only those files longer than the given number of bytes are",
-" to be sent.",
-" ",
-"/SMALLER-THAN:number",
-" Specifies that only those files smaller than the given number of bytes are",
-" to be sent.",
-" ",
-"/EXCEPT:pattern",
-" Specifies that any files whose names match the pattern, which can be a",
-" regular filename, or may contain \"*\" and/or \"?\" metacharacters,",
-" are not to be sent. To specify multiple patterns (up to 8), use outer",
-" braces around the group, and inner braces around each pattern:",
-" ",
-" /EXCEPT:{{pattern1}{pattern2}...}",
-" ",
-"/TYPE:{ALL,TEXT,BINARY}",
-" Send only files of the given type (see SET FILE SCAN).",
-" ",
-"/LISTFILE:filename",
-" Specifies the name of a file that contains the list of names of files",
-" that are to be sent. The filenames should be listed one name per line",
-" in this file (but a name can contain wildcards).",
-" ",
-"Also see HELP RECEIVE, HELP GET, HELP SERVER, HELP REMOTE.",
-""};
-
-static char *hmxxrc[] = {
-"Syntax: RECEIVE (or R) [ switches... ] [ as-name ]",
-" Wait for a file to arrive from the other Kermit, which must be given a",
-" SEND command. If the optional as-name is given, the incoming file or",
-" files are stored under that name, otherwise it will be stored under",
-#ifndef CK_TMPDIR
-" the name it arrives with.",
-#else
-#ifdef OS2
-" the name it arrives with. If the filespec denotes a disk and/or",
-" directory, the incoming file or files will be stored there.",
-#else
-" the name it arrives with. If the filespec denotes a directory, the",
-" incoming file or files will be placed in that directory.",
-#endif /* OS2 */
-#endif /* CK_TMPDIR */
-" ",
-"Optional switches include:",
-" ",
-"/AS-NAME:text",
-" Specifies \"text\" as the name to store the incoming file under.",
-" You can also specify the as-name as a filename on the command line.",
-" ",
-"/BINARY",
-" Skips text-mode conversions unless the incoming file arrives with binary",
-" attribute",
-" ",
-"/COMMAND",
-" Receives the file into the standard input of a command, rather than saving",
-" it on disk. The /AS-NAME or the \"filename\" on the RECEIVE command line",
-" is interpreted as the name of a command.",
-" ",
-"/EXCEPT:pattern",
-" Specifies that any files whose names match the pattern, which can be a",
-" regular filename, or may contain \"*\" and/or \"?\" metacharacters,",
-" are to be refused. To specify multiple patterns (up to 8), use outer",
-" braces around the group, and inner braces around each pattern:",
-" ",
-" /EXCEPT:{{pattern1}{pattern2}...}",
-" ",
-"/FILENAMES:{CONVERTED,LITERAL}",
-" Overrides the global SET FILE NAMES setting for this transfer only.",
-" ",
-"/FILTER:command",
-" Causes the incoming file to passed through the given command (standard",
-" input/output filter) before being written to disk.",
-" ",
-#ifdef VMS
-"/IMAGE",
-" Receives the file in image mode.",
-" ",
-#endif /* VMS */
-#ifdef CK_LABELED
-"/LABELED",
-" Specifies labeled transfer mode.",
-" ",
-#endif /* CK_LABELED */
-
-"/MOVE-TO:directory-name",
-" Specifies that each file that arrives should be moved to the specified",
-" directory after, and only if, it has been received successfully.",
-" ",
-"/PATHNAMES:{OFF,ABSOLUTE,RELATIVE,AUTO}",
-" Overrides the global SET RECEIVE PATHNAMES setting for this transfer.",
-" ",
-"/PIPES:{ON,OFF}",
-" Overrides the TRANSFER PIPES setting for this command only. ON allows",
-" reception of files with names like \"!tar xf -\" to be automatically",
-" directed to a pipeline.",
-" ",
-"/PROTOCOL:name",
-" Use the given protocol to receive the incoming file(s).",
-" ",
-"/QUIET",
-" When sending in local mode, this suppresses the file-transfer display.",
-" ",
-"/RECURSIVE",
-" Equivalent to /PATHNAMES:RELATIVE.",
-" ",
-"/RENAME-TO:string",
-" Specifies that each file that arrives should be renamed as specified",
-" after, and only if, it has been received successfully. The string should",
-" normally contain variables like \\v(filename) or \\v(filenum).",
-" ",
-"/TEXT",
-" Forces text-mode conversions unless the incoming file has the binary",
-" attribute",
-" ",
-"/TRANSPARENT",
-" Inhibits character-set translation of incoming text files for the duration",
-" of the RECEIVE command without affecting subsequent commands.",
-" ",
-"Also see HELP SEND, HELP GET, HELP SERVER, HELP REMOTE.",
-"" };
-
-#ifndef NORESEND
-static char *hmxxrsen = "\
-Syntax: RESEND filespec [name]\n\n\
- Resend the file or files, whose previous transfer was interrupted.\n\
- Picks up from where previous transfer left off, IF the receiver was told\n\
- to SET FILE INCOMPLETE KEEP. Only works for binary-mode transfers.\n\
- Requires the other Kermit to have RESEND capability.";
-
-static char *hmxxrget = "\
-Syntax: REGET filespec\n\n\
- Ask a server to RESEND a file to C-Kermit.";
-
-static char *hmxxpsen = "\
-Syntax: PSEND filespec position [name]\n\n\
- Just like SEND, except sends the file starting at the given byte position.";
-#endif /* NORESEND */
-
-#ifndef NOMSEND
-static char *hmxxmse[] = {
-"Syntax: MSEND [ switches... ] filespec [ filespec [ ... ] ]",
-" Sends the files specified by the filespecs. One or more filespecs may be",
-" listed, separated by spaces. Any or all filespecs may contain wildcards",
-" and they may be in different directories. Alternative names cannot be",
-" given. Switches include /BINARY /DELETE /MAIL /PROTOCOL /QUIET /RECOVER",
-" /TEXT /TYPE; see HELP SEND for descriptions.",
-""
-};
-#endif /* NOMSEND */
-
-static char *hmxxadd[] = {
-#ifndef NOMSEND
-"ADD SEND-LIST filespec [ <mode> [ <as-name> ] ]",
-" Adds the specified file or files to the current SEND list. Use SHOW",
-" SEND-LIST and CLEAR SEND-LIST to display and clear the list; use SEND",
-" by itself to send the files from it.",
-" ",
-#endif /* NOMSEND */
-#ifdef PATTERNS
-"ADD BINARY-PATTERNS [ <pattern> [ <pattern> ... ] ]",
-" Adds the pattern(s), if any, to the SET FILE BINARY-PATTERNS list.",
-" ",
-"ADD TEXT-PATTERNS [ <pattern> [ <pattern> ... ] ]",
-" Adds the pattern(s), if any, to the SET FILE TEXT-PATTERNS list.",
-" Use SHOW PATTERNS to see the lists. See HELP SET FILE for further info.",
-#endif /* PATTERNS */
-""};
-
-static char *hmxxremv[] = {
-#ifdef PATTERNS
-"REMOVE BINARY-PATTERNS [ <pattern> [ <pattern> ... ] ]",
-" Removes the pattern(s), if any, from the SET FILE BINARY-PATTERNS list",
-" ",
-"REMOVE TEXT-PATTERNS [ <pattern> [ <pattern> ... ] ]",
-" Removes the given patterns from the SET FILE TEXT-PATTERNS list.",
-" Use SHOW PATTERNS to see the lists. See HELP SET FILE for further info.",
-#endif /* PATTERNS */
-""};
-#endif /* NOXFER */
-
-#ifndef NOSERVER
-static char *hmxxser = "Syntax: SERVER\n\
- Enter server mode on the current connection. All further commands\n\
- are taken in packet form from the other Kermit program. Use FINISH,\n\
- BYE, or REMOTE EXIT to get C-Kermit out of server mode.";
-#endif /* NOSERVER */
-
-static char *hmhset[] = {
-" The SET command establishes communication, file, scripting, or other",
-" parameters. The SHOW command can be used to display the values of",
-" SET parameters. Help is available for each individual parameter;",
-" type HELP SET ? to see what's available.",
-"" };
-
-#ifndef NOSETKEY
-static char *hmhskey[] = {
-"Syntax: SET KEY k text",
-"Or: SET KEY CLEAR",
-" Configure the key whose \"scan code\" is k to send the given text when",
-" pressed during CONNECT mode. SET KEY CLEAR restores all the default",
-" key mappings. If there is no text, the default key binding is restored",
-#ifndef NOCSETS
-" for the key k. SET KEY mappings take place before terminal character-set",
-" translation.",
-#else
-" the key k.",
-#endif /* NOCSETS */
-#ifdef OS2
-" ",
-" The text may contain \"\\Kverbs\" to denote actions, to stand for DEC",
-" keypad, function, or editing keys, etc. For a list of available keyboard",
-" verbs, type SHOW KVERBS.",
-#endif /* OS2 */
-" ",
-" To find out the scan code and mapping for a particular key, use the",
-" SHOW KEY command.",
-""};
-#endif /* NOSETKEY */
-
-static char *hmxychkt[] = { "Syntax: SET BLOCK-CHECK type",
-" ",
-" Type of packet block check to be used for error detection, 1, 2, 3, or",
-" BLANK-FREE-2. Type 1 is standard, and catches most errors. Types 2 and 3",
-" specify more rigorous checking at the cost of higher overhead. The",
-" BLANK-FREE-2 type is the same as Type 2, but is guaranteed to contain no",
-" blanks.",
-"" };
-
-static char * hmxydeb[] = {
-"Syntax: SET DEBUG { SESSION, ON, OFF, TIMESTAMP }",
-" ",
-"SET DEBUG ON",
-#ifdef DEBUG
-" Opens a debug log file named debug.log in the current directory.",
-" Use LOG DEBUG if you want specify a different log file name or path.",
-#else
-" (Has no effect in this version of Kermit.)",
-#endif /* DEBUG */
-" ",
-"SET DEBUG OFF",
-" Stops debug logging and session debugging.",
-" ",
-"SET DEBUG SESSION",
-#ifndef NOLOCAL
-" Displays control and 8-bit characters symbolically during CONNECT mode.",
-" Equivalent to SET TERMINAL DEBUG ON.",
-#else
-" (Has no effect in this version of Kermit.)",
-#endif /* NOLOCAL */
-" ",
-"SET DEBUG TIMESTAMP { ON, OFF }",
-" Enables/Disables timestamps on debug log entries.",
-"" };
-
-#ifdef CK_SPEED
-static char *hmxyqctl[] = {
-"Syntax: SET CONTROL-CHARACTER { PREFIXED, UNPREFIXED } { <code>..., ALL }",
-" ",
-" <code> is the numeric ASCII code for a control character 1-31,127-159,255."
-,
-" The word \"ALL\" means all characters in this range.",
-" ",
-" PREFIXED <code> means the given control character must be converted to a",
-" printable character and prefixed, the default for all control characters.",
-" ",
-" UNPREFIXED <code> means you think it is safe to send the given control",
-" character as-is, without a prefix. USE THIS OPTION AT YOUR OWN RISK!",
-" ",
-" SHOW CONTROL to see current settings. SET CONTROL PREFIXED ALL is",
-" recommended for safety. You can include multiple <code> values in one",
-" command, separated by spaces.",
-"" };
-#endif /* CK_SPEED */
-
-#ifndef NODIAL
-static char *hxymodm[] = {
-"Syntax: SET MODEM <parameter> <value> ...",
-" ",
-"Note: Many of the SET MODEM parameters are configured automatically when",
-"you SET MODEM TYPE, according to the modem's capabilities. SHOW MODEM to",
-"see them. Also see HELP DIAL and HELP SET DIAL.",
-" ",
-"SET MODEM TYPE <name>",
-
-" Tells Kermit which kind of modem you have, so it can issue the",
-" appropriate modem-specific commands for configuration, dialing, and",
-" hanging up. For a list of the modem types known to Kermit, type \"set",
-" modem type ?\". The default modem type is GENERIC, which should work",
-" with any AT command-set modem that is configured for error correction,",
-" data compression, and hardware flow control. Use SET MODEM TYPE NONE",
-" for direct serial, connections. Use SET MODEM TYPE USER-DEFINED to use",
-" a type of modem that is not built in to Kermit, and then use SET MODEM",
-" CAPABILITIES, SET MODEM, DIAL-COMMAND, and SET MODEM COMMAND to tell",
-" Kermit how to configure and control it.",
-
-" ",
-
-"SET MODEM CAPABILITIES <list>",
-" Use this command for changing Kermit's idea of your modem's capabilities,",
-" for example, if your modem is supposed to have built-in error correction",
-" but in fact does not. Also use this command to define the capabilities",
-" of a USER-DEFINED modem. Capabilities are:",
-" ",
-" AT AT-commands",
-" DC data-compression",
-" EC error-correction",
-" HWFC hardware-flow",
-" ITU v25bis-commands",
-" SWFC software-flow",
-" KS kermit-spoof",
-" SB speed-buffering",
-" TB Telebit",
-" ",
-"SET MODEM CARRIER-WATCH { AUTO, ON, OFF }",
-" Synonym for SET CARRIER-WATCH (q.v.)",
-" ",
-"SET MODEM COMPRESSION { ON, OFF }",
-" Enables/disables the modem's data compression feature, if any.",
-" ",
-"SET MODEM DIAL-COMMAND <text>",
-" The text replaces Kermit's built-in modem dialing command. It must",
-" include '%s' (percent s) as a place-holder for the telephone numbers",
-" given in your DIAL commands.",
-" ",
-"SET MODEM ERROR-CORRECTION { ON, OFF }",
-" Enables/disables the modem's error-correction feature, if any.",
-" ",
-"SET MODEM ESCAPE-CHARACTER number",
-" Numeric ASCII value of modem's escape character, e.g. 43 for '+'.",
-" For Hayes-compatible modems, Kermit uses three copies, e.g. \"+++\".",
-" ",
-"SET MODEM FLOW-CONTROL {AUTO, NONE, RTS/CTS, XON/XOFF}",
-" Selects the type of local flow control to be used by the modem.",
-" ",
-"SET MODEM HANGUP-METHOD { MODEM-COMMAND, RS232-SIGNAL, DTR }",
-" How hangup operations should be done. MODEM-COMMAND means try to",
-" escape back to the modem's command processor and give a modem-specific",
-" hangup command. RS232-SIGNAL means turn off the DTR signal. DTR is a",
-" synonym for RS232-SIGNAL.",
-" ",
-"SET MODEM KERMIT-SPOOF {ON, OFF}",
-" If the selected modem type supports the Kermit protocol directly,",
-" use this command to turn its Kermit protocol function on or off.",
-" ",
-"SET MODEM MAXIMUM-SPEED <number>",
-" Specify the maximum interface speed for the modem.",
-" ",
-"SET MODEM NAME <text>",
-" Descriptive name for a USER-DEFINED modem.",
-" ",
-"SET MODEM SPEAKER {ON, OFF}",
-" Turns the modem's speaker on or off during dialing.",
-" ",
-"SET MODEM SPEED-MATCHING {ON, OFF}",
-" ON means that C-Kermit changes its serial interface speed to agree with",
-" the speed reported by the modem's CONNECT message, if any. OFF means",
-" Kermit should not change its interface speed.",
-" ",
-"SET MODEM VOLUME {LOW, MEDIUM, HIGH}",
-" Selects the desired modem speaker volume for when the speaker is ON.",
-" ",
-"SET MODEM COMMAND commands are used to override built-in modem commands for",
-"each modem type, or to fill in commands for the USER-DEFINED modem type.",
-"Omitting the optional [ text ] restores the built-in modem-specific command,",
-"if any:",
-" ",
-"SET MODEM COMMAND AUTOANSWER {ON, OFF} [ text ]",
-" Modem commands to turn autoanswer on and off.",
-" ",
-"SET MODEM COMMAND COMPRESSION {ON, OFF} [ text ]",
-" Modem commands to turn data compression on and off.",
-" ",
-"SET MODEM COMMAND ERROR-CORRECTION {ON, OFF} [ text ]",
-" Modem commands to turn error correction on and off.",
-" ",
-"SET MODEM COMMAND HANGUP [ text ]",
-" Command that tells the modem to hang up the connection.",
-" ",
-"SET MODEM COMMAND IGNORE-DIALTONE [ text ]",
-" Command that tells the modem not to wait for dialtone before dialing.",
-" ",
-"SET MODEM COMMAND INIT-STRING [ text ]",
-" The 'text' is a replacement for C-Kermit's built-in initialization command",
-" for the modem.",
-" ",
-"SET MODEM COMMAND PREDIAL-INIT [ text ]",
-" A second INIT-STRING that is to be sent to the modem just prior to \
-dialing.",
-" ",
-"SET MODEM COMMAND HARDWARE-FLOW [ text ]",
-" Modem command to enable hardware flow control (RTS/CTS) in the modem.",
-" ",
-"SET MODEM COMMAND SOFTWARE-FLOW [ text ]",
-" Modem command to enable local software flow control (Xon/Xoff) in modem.",
-" ",
-"SET MODEM COMMAND SPEAKER { ON, OFF } [ text ]",
-" Modem command to turn the modem's speaker on or off.",
-" ",
-"SET MODEM COMMAND NO-FLOW-CONTROL [ text ]",
-" Modem command to disable local flow control in the modem.",
-" ",
-"SET MODEM COMMAND PULSE [ text ]",
-" Modem command to select pulse dialing.",
-" ",
-"SET MODEM COMMAND TONE [ text ]",
-" Modem command to select tone dialing.",
-" ",
-"SET MODEM COMMAND VOLUME { LOW, MEDIUM, HIGH } [ text ]",
-" Modem command to set the modem's speaker volume.",
-""};
-
-static char *hmxydial[] = {
-"The SET DIAL command establishes or changes all parameters related to",
-"dialing the telephone. Also see HELP DIAL and HELP SET MODEM. Use SHOW",
-"DIAL to display all of the SET DIAL values.",
-" ",
-"SET DIAL COUNTRY-CODE <number>",
-" Tells Kermit the telephonic country-code of the country you are dialing",
-" from, so it can tell whether a portable-format phone number from your",
-" dialing directory will result in a national or an international call.",
-" Examples: 1 for USA, Canada, Puerto Rico, etc; 7 for Russia, 39 for Italy,",
-" 351 for Portugal, 47 for Norway, 44 for the UK, 972 for Israel, 81 for",
-" Japan, ...",
-" ",
-" If you have not already set your DIAL INTL-PREFIX and LD-PREFIX, then this",
-" command sets default values for them: 011 and 1, respectively, for country",
-" code 1; 00 and 0, respectively, for all other country codes. If these are",
-" not your true international and long-distance dialing prefixes, then you",
-" should follow this command by DIAL INTL-PREFIX and LD-PREFIX to let Kermit",
-" know what they really are.",
-" ",
-"SET DIAL AREA-CODE [ <number> ]",
-" Tells Kermit the area or city code that you are dialing from, so it can",
-" tell whether a portable-format phone number from the dialing directory is",
-" local or long distance. Be careful not to include your long-distance",
-" dialing prefix as part of your area code; for example, the area code for",
-" central London is 171, not 0171.",
-" ",
-"SET DIAL CONFIRMATION {ON, OFF}",
-" Kermit does various transformations on a telephone number retrieved from",
-" the dialing directory prior to dialing (use LOOKUP <name> to see them).",
-" In case the result might be wrong, you can use SET DIAL CONFIRM ON to have",
-" Kermit ask you if it is OK to dial the number, and if not, to let you type",
-" in a replacement.",
-" ",
-"SET DIAL CONNECT { AUTO, ON, OFF }",
-" Whether to CONNECT (enter terminal mode) automatically after successfully",
-" dialing. ON means to do this; OFF means not to. AUTO (the default) means",
-" do it if the DIAL command was given interactively, but don't do it if the",
-" DIAL command was issued from a macro or command file. If you specify ON",
-" or AUTO, you may follow this by one of the keywords VERBOSE or QUIET, to",
-" indicate whether the verbose 4-line 'Connecting...' message is to be",
-" displayed if DIAL succeeds and Kermit goes into CONNECT mode.",
-" ",
-"SET DIAL CONVERT-DIRECTORY {ASK, ON, OFF}",
-" The format of Kermit's dialing directory changed in version 5A(192). This",
-" command tells Kermit what to do when it encounters an old-style directory:",
-" ASK you whether to convert it, or convert it automatically (ON), or leave",
-" it alone (OFF). Old-style directories can still be used without",
-" conversion, but the parity and speed fields are ignored.",
-" ",
-"SET DIAL DIRECTORY [ filename [ filename [ filename [ ... ] ] ] ]",
-" The name(s) of your dialing directory file(s). If you do not supply any",
-" filenames, the dialing directory feature is disabled and all numbers are",
-" dialed literally as given in the DIAL command. If you supply more than",
-" one directory, all of them are searched.",
-" ",
-"SET DIAL SORT {ON, OFF}",
-" When multiple entries are obtained from your dialing directory, they are",
-" sorted in \"cheapest-first\" order. If this does not produce the desired",
-" effect, SET DIAL SORT OFF to disable sorting, and the numbers will be",
-" dialed in the order in which they were found.",
-" ",
-"SET DIAL DISPLAY {ON, OFF}",
-" Whether to display dialing progress on the screen; default is OFF.",
-" ",
-"SET DIAL HANGUP {ON, OFF}",
-" Whether to hang up the phone prior to dialing; default is ON.",
-" ",
-"SET DIAL IGNORE-DIALTONE {ON, OFF}",
-" Whether to ignore dialtone when dialing; default is OFF.",
-" ",
-#ifndef NOSPL
-"SET DIAL MACRO [ name ]",
-" Specify the name of a macro to execute on every phone number dialed, just",
-" prior to dialing it, in order to perform any last-minute alterations.",
-" ",
-#endif /* NOSPL */
-"SET DIAL METHOD {AUTO, DEFAULT, TONE, PULSE}",
-" Whether to use the modem's DEFAULT dialing method, or to force TONE or",
-" PULSE dialing. AUTO (the default) means to choose tone or pulse dialing",
-" based on the country code. (Also see SET DIAL TONE-COUNTRIES and SET DIAL",
-" PULSE-COUNTRIES.)",
-" ",
-"SET DIAL PACING number",
-" How many milliseconds to pause between sending each character to the modem",
-" dialer. The default is -1, meaning to use the number from the built-in",
-" modem database.",
-" ",
-"SET DIAL PULSE-COUNTRIES [ cc [ cc [ ... ] ] ]",
-" Sets the list of countries in which pulse dialing is required. Each cc",
-" is a country code.",
-" ",
-"SET DIAL TEST { ON, OFF }",
-" OFF for normal dialing. Set to ON to test dialing procedures without",
-" actually dialing.",
-" ",
-"SET DIAL TONE-COUNTRIES [ cc [ cc [ ... ] ] ]",
-" Sets the list of countries in which tone dialing is available. Each cc",
-" is a country code.",
-" ",
-"SET DIAL TIMEOUT number",
-" How many seconds to wait for a dialed call to complete. Use this command",
-" to override the DIAL command's automatic timeout calculation. A value",
-" of 0 turns off this feature and returns to Kermit's automatic dial",
-" timeout calculation.",
-" ",
-"SET DIAL RESTRICT { INTERNATIONAL, LOCAL, LONG-DISTANCE, NONE }",
-" Prevents placing calls of the type indicated, or greater. For example",
-" SET DIAL RESTRICT LONG prevents placing of long-distance and international",
-" calls. If this command is not given, there are no restrictions. Useful",
-" when dialing a list of numbers fetched from a dialing directory.",
-" ",
-"SET DIAL RETRIES <number>",
-" How many times to redial each number if the dialing result is busy or no",
-" no answer, until the call is succesfully answered. The default is 0",
-" because automatic redialing is illegal in some countries.",
-" ",
-"SET DIAL INTERVAL <number>",
-" How many seconds to pause between automatic redial attempts; default 10.",
-" ",
-"The following commands apply to all phone numbers, whether given literally",
-"or found in the dialing directory:",
-" ",
-"SET DIAL PREFIX [ text ]",
-" Establish a prefix to be applied to all phone numbers that are dialed,",
-" for example to disable call waiting.",
-" ",
-"SET DIAL SUFFIX [ text ]",
-" Establish a suffix to be added after all phone numbers that are dialed.",
-" ",
-"The following commands apply only to portable-format numbers obtained from",
-"the dialing directory; i.e. numbers that start with a \"+\" sign and",
-"country code, followed by area code in parentheses, followed by the phone",
-"number.",
-" ",
-"SET DIAL LC-AREA-CODES [ <list> ]",
-" Species a list of area codes to which dialing is local, i.e. does not",
-" require the LD-PREFIX. Up to 32 area codes may be listed, separated by",
-" spaces. Any area codes in this list will be included in the final dial",
-" string so do not include your own area code if it should not be dialed.",
-" ",
-"SET DIAL LC-PREFIX [ <text> ]",
-" Specifies a prefix to be applied to local calls made from portable dialing",
-" directory entries. Normally no prefix is used for local calls.",
-" ",
-"SET DIAL LC-SUFFIX [ <text> ]",
-" Specifies a suffix to be applied to local calls made from portable dialing",
-" directory entries. Normally no suffix is used for local calls.",
-" ",
-"SET DIAL LD-PREFIX [ <text> ]",
-" Your long-distance dialing prefix, to be used with portable dialing",
-" directory entries that result in long-distance calls.",
-" ",
-"SET DIAL LD-SUFFIX [ <text> ]",
-" Long-distance dialing suffix, if any, to be used with portable dialing",
-" directory entries that result in long-distance calls. This would normally",
-" be used for appending a calling-card number to the phone number.",
-" ",
-"SET DIAL FORCE-LONG-DISTANCE { ON, OFF }",
-" Whether to force long-distance dialing for calls that normally would be",
-" local. For use (e.g.) in France.",
-" ",
-"SET DIAL TOLL-FREE-AREA-CODE [ <number> [ <number> [ ... ] ] ]",
-" Tells Kermit the toll-free area code(s) in your country.",
-" ",
-"SET DIAL TOLL-FREE-PREFIX [ <text> ]",
-" You toll-free dialing prefix, in case it is different from your long-",
-" distance dialing prefix.",
-" ",
-"SET DIAL INTL-PREFIX <text>",
-" Your international dialing prefix, to be used with portable dialing",
-" directory entries that result in international calls.",
-" ",
-"SET DIAL INTL-SUFFIX <text>",
-" International dialing suffix, if any, to be used with portable dialing",
-" directory entries that result in international calls.",
-" ",
-"SET DIAL PBX-OUTSIDE-PREFIX <text>",
-" Use this to tell Kermit how to get an outside line when dialing from a",
-" Private Branch Exchange (PBX).",
-" ",
-"SET DIAL PBX-EXCHANGE <text> [ <text> [ ... ] ]",
-" If PBX-OUTSIDE-PREFIX is set, then you can use this command to tell Kermit",
-" the leading digits of one or more local phone numbers that identify it as",
-" being on your PBX, so it can make an internal call by deleting those digits"
-,
-" from the phone number.",
-" ",
-"SET DIAL PBX-INTERNAL-PREFIX <text>",
-" If PBX-EXCHANGE is set, and Kermit determines from it that a call is",
-" internal, then this prefix, if any, is added to the number prior to",
-" \
-dialing. Use this if internal calls from your PBX require a special prefix.",
-"" };
-#endif /* NODIAL */
-
-static char *hmxyflo[] = { "Syntax: SET FLOW [ switch ] value",
-" ",
-#ifndef NOLOCAL
-" Selects the type of flow control to use during file transfer, terminal",
-" connection, and script execution.",
-#else
-" Selects the type of flow control to use during file transfer.",
-#endif /* NOLOCAL */
-" ",
-" Switches let you associate a particular kind of flow control with each",
-" kind of connection: /REMOTE, /MODEM, /DIRECT-SERIAL, /TCPIP, etc; type",
-" \"set flow ?\" for a list of available switches. Then whenever you make",
-" a connection, the associated flow-control is chosen automatically.",
-" The flow-control values are NONE, KEEP, XON/XOFF, and possibly RTS/CTS",
-" and some others; again, type \"set flow ?\" for a list. KEEP tells Kermit",
-" not to try to change the current flow-control method for the connection.",
-" ",
-" If you omit the switch and simply supply a value, this value becomes the",
-" current flow control type, overriding any default value that might have",
-" been chosen in your most recent SET LINE, SET PORT, or SET HOST, or other",
-" connection-establishment command.",
-" ",
-" Type SHOW FLOW-CONTROL to see the current defaults for each connection type"
-,
-" as well as the current connection type and flow-control setting. SHOW",
-" COMMUNICATIONS also shows the current flow-control setting.",
-""};
-
-static char *hmxyf[] = {
-"Syntax: SET FILE parameter value",
-" ",
-"Sets file-related parameters. Use SHOW FILE to view them. Also see SET",
-"(and SHOW) TRANSFER and PROTOCOL.",
-" ",
-#ifdef VMS
-"SET FILE TYPE { TEXT, BINARY, IMAGE, LABELED }",
-#else
-#ifdef STRATUS
-"SET FILE TYPE { TEXT, BINARY, LABELED }",
-#else
-#ifdef MAC
-"SET FILE TYPE { TEXT, BINARY, MACBINARY }",
-#else
-"SET FILE TYPE { TEXT, BINARY }",
-#endif /* STRATUS */
-#endif /* MAC */
-#endif /* VMS */
-" How file contents are to be treated during file transfer in the absence",
-" of any other indication. TYPE can be TEXT for conversion of record format",
-" and character set, which is usually needed when transferring text files",
-" between unlike platforms (such as UNIX and Windows), or BINARY for no",
-" conversion if TRANSFER MODE is MANUAL, which is not the default. Use",
-" BINARY with TRANSFER MODE MANUAL for executable programs or binary data or",
-" whenever you wish to duplicate the original contents of the file, byte for"
-,
-" byte. In most modern Kermit programs, the file sender informs the receiver"
-,
-" of the file type automatically. However, when sending files from C-Kermit",
-" to an ancient or non-Columbia Kermit implementation, you might need to set",
-" the corresponding file type at the receiver as well.",
-" ",
-#ifdef VMS
-" FILE TYPE settings of TEXT and BINARY have no effect when sending files,",
-" since VMS C-Kermit determines each file's type automatically from its",
-" record format: binary for fixed, text for others. For incoming files,",
-" these settings are effective only in the absence of a file-type indication",
-" from the sender.",
-" ",
-" You may include an optional record-format after the word BINARY. This may",
-" be FIXED (the default) or UNDEFINED. UNDEFINED is used when you need to",
-" receive binary files in binary mode and have them stored with UNDEFINED",
-" record format, which is required by certain VMS applications.",
-" ",
-" Two additional VMS file types are also supported: IMAGE and LABELED.",
-" IMAGE means raw block i/o, no interference from RMS, applies to file",
-" transmission only, and overrides the normal automatica file type",
-" determination. LABELED means to send or interpret RMS attributes",
-" with the file.",
-" ",
-#else
-" When TRANSFER MODE is AUTOMATIC (as it is by default), various automatic",
-" methods (depending on the platform) are used to determine whether a file",
-" is transferred in text or binary mode; these methods (which might include",
-" content scan (see SET FILE SCAN below), filename pattern matching (SET FILE"
-,
-" PATTERNS), client/server \"kindred-spirit\" recognition, or source file",
-" record format) supersede the FILE TYPE setting but can, themselves, be",
-" superseded by including a /BINARY or /TEXT switch in the SEND, GET, or",
-" RECEIVE command.",
-" ",
-" When TRANSFER MODE is MANUAL, the automatic methods are skipped for sending"
-,
-" files; the FILE TYPE setting is used instead, which can be superseded on",
-" a per-command basis with a /TEXT or /BINARY switch.",
-#endif /* VMS */
-" ",
-
-#ifndef NOXFER
-
-"SET FILE BYTESIZE { 7, 8 }",
-" Normally 8. If 7, Kermit truncates the 8th bit of all file bytes.",
-" ",
-#ifndef NOCSETS
-"SET FILE CHARACTER-SET name",
-" Tells the encoding of the local file, ASCII by default.",
-" The names ITALIAN, PORTUGUESE, NORWEGIAN, etc, refer to 7-bit ISO-646",
-" national character sets. LATIN1 is the 8-bit ISO 8859-1 Latin Alphabet 1",
-" for Western European languages.",
-" NEXT is the 8-bit character set of the NeXT workstation.",
-" The CPnnn sets are for PCs. MACINTOSH-LATIN is for the Macintosh.",
-#ifndef NOLATIN2
-" LATIN2 is ISO 8859-2 for Eastern European languages that are written with",
-" Roman letters. Mazovia is a PC code page used in Poland.",
-#endif /* NOLATIN2 */
-#ifdef CYRILLIC
-" KOI-CYRILLIC, CYRILLIC-ISO, and CP866 are 8-bit Cyrillic character sets.",
-" SHORT-KOI is a 7-bit ASCII coding for Cyrillic. BULGARIA-PC is a PC code",
-" page used in Bulgaria",
-#endif /* CYRILLIC */
-#ifdef HEBREW
-" HEBREW-ISO is ISO 8859-8 Latin/Hebrew. CP862 is the Hebrew PC code page.",
-" HEBREW-7 is like ASCII with the lowercase letters replaced by Hebrew.",
-#endif /* HEBREW */
-#ifdef GREEK
-" GREEK-ISO is ISO 8859-7 Latin/Greek. CP869 is the Greek PC code page.",
-" ELOT-927 is like ASCII with the lowercase letters replaced by Greek.",
-#endif /* GREEK */
-#ifdef KANJI
-" JAPANESE-EUC, JIS7-KANJI, DEC-KANJI, and SHIFT-JIS-KANJI are Japanese",
-" Kanji character sets.",
-#endif /* KANJI */
-#ifdef UNICODE
-" UCS-2 is the 2-byte form of the Universal Character Set.",
-" UTF-8 is the serialized form of the Universal Character Set.",
-#endif /* UNICODE */
-" Type SET FILE CHAR ? for a complete list of file character sets.",
-" ",
-"SET FILE DEFAULT 7BIT-CHARACTER-SET",
-" When automatically switching among different kinds of files while sending",
-" this tells the character set to be used for 7-bit text files.",
-" ",
-"SET FILE DEFAULT 8BIT-CHARACTER-SET",
-" This tells the character set to be used for 8-bit text files when",
-" switching automatically among different kinds of files.",
-" ",
-#endif /* NOCSETS */
-
-"SET FILE COLLISION option",
-" Tells what to do when a file arrives that has the same name as",
-" an existing file. The options are:",
-" BACKUP (default) - Rename the old file to a new, unique name and store",
-" the incoming file under the name it was sent with.",
-" OVERWRITE - Overwrite (replace) the existing file.",
-" APPEND - Append the incoming file to the end of the existing file.",
-" DISCARD - Refuse and/or discard the incoming file.",
-" RENAME - Give the incoming file a unique name.",
-" UPDATE - Accept the incoming file only if newer than the existing file.",
-" ",
-
-"SET FILE DESTINATION { DISK, PRINTER, SCREEN, NOWHERE }",
-" DISK (default): Store incoming files on disk.",
-" PRINTER: Send incoming files to SET PRINTER device.",
-" SCREEN: Display incoming files on screen (local mode only).",
-" NOWHERE: Do not put incoming files anywhere (use for calibration).",
-" ",
-"SET FILE DISPLAY option",
-" Selects the format of the file transfer display for local-mode file",
-" transfer. The choices are:",
-" ",
-" BRIEF A line per file, showing size, mode, status, and throughput.",
-" SERIAL One dot is printed for every K bytes transferred.",
-" CRT Numbers are continuously updated on a single screen line.",
-" This format can be used on any video display terminal.",
-#ifdef CK_CURSES
-" FULLSCREEN A fully formatted 24x80 screen showing lots of information.",
-" This requires a terminal or terminal emulator.",
-#endif /* CK_CURSES */
-" NONE No file transfer display at all.",
-" ",
-
-"SET FILE DOWNLOAD-DIRECTORY [ <directory-name> ]",
-" The directory into which all received files should be placed. By default,",
-" received files go into your current directory.",
-" ",
-#endif /* NOXFER */
-
-#ifdef CK_CTRLZ
-"SET FILE EOF { CTRL-Z, LENGTH }",
-" End-Of-File detection method, normally LENGTH. Applies only to text-mode",
-" transfers. When set to CTRL-Z, this makes the file sender treat the first",
-" Ctrl-Z in the input file as the end of file (EOF), and it makes the file",
-" receiver tack a Ctrl-Z onto the end of the output file if it does not",
-" already end with Ctrl-Z.",
-" ",
-#endif /* CK_CTRLZ */
-
-"SET FILE END-OF-LINE { CR, CRLF, LF }",
-" Use this command to specify nonstandard line terminators for text files.",
-" ",
-
-#ifndef NOXFER
-"SET FILE INCOMPLETE { AUTO, KEEP, DISCARD }",
-" What to do with an incompletely received file: KEEP, DISCARD, or AUTO.",
-" AUTO (the default) means DISCARD if transfer is in text mode, KEEP if it",
-" is in binary mode.",
-" ",
-#ifdef VMS
-"SET FILE LABEL { ACL, BACKUP-DATE, NAME, OWNER, PATH } { ON, OFF }",
-" Tells which items to include (ON) or exclude (OFF) in labeled file",
-" transfers",
-" ",
-#else
-#ifdef OS2
-"SET FILE LABEL { ARCHIVE, READ-ONLY, HIDDEN, SYSTEM, EXTENDED } { ON, OFF }",
-" Tells which items to include (ON) or exclude (OFF) in labeled file",
-" transfers.",
-" ",
-#endif /* OS2 */
-#endif /* VMS */
-
-#ifdef UNIX
-#ifdef DYNAMIC
-"SET FILE LISTSIZE number",
-" Changes the size of the internal wildcard expansion list. Use SHOW FILE",
-" to see the current size. Use this command to increase the size if you get",
-" a \"?Too many files\" error. Also see SET FILE STRINGSPACE.",
-" ",
-#endif /* DYNAMIC */
-#endif /* UNIX */
-
-"SET FILE NAMES { CONVERTED, LITERAL }",
-" File names are normally CONVERTED to \"common form\" during transmission",
-" (e.g. lowercase to uppercase, extra periods changed to underscore, etc).",
-" LITERAL means use filenames literally (useful between like systems). Also",
-" see SET SEND PATHNAMES and SET RECEIVE PATHNAMES.",
-" ",
-
-#ifdef UNIX
-"SET FILE OUTPUT { { BUFFERED, UNBUFFERED } [ size ], BLOCKING, NONBLOCKING }",
-" Lets you control the disk output buffer for incoming files. Buffered",
-" blocking writes are normal. Nonblocking writes might be faster on some",
-" systems but might also be risky, depending on the underlying file service.",
-" Unbuffered writes might be useful in critical applications to ensure that",
-" cached disk writes are not lost in a crash, but will probably also be",
-" slower. The optional size parameter after BUFFERED or UNBUFFERED lets you",
-" change the disk output buffer size; this might make a difference in",
-" performance.",
-" ",
-#endif /* UNIX */
-
-#ifdef PATTERNS
-"SET FILE PATTERNS { ON, OFF, AUTO }",
-" ON means to use filename pattern lists to determine whether to send a file",
-" in text or binary mode. OFF means to send all files in the prevailing",
-" mode. AUTO (the default) is like ON if the other Kermit accepts Attribute",
-" packets and like OFF otherwise. FILE PATTERNS are used only if FILE SCAN",
-" is OFF (see SET FILE SCAN).",
-" ",
-"SET FILE BINARY-PATTERNS [ <pattern> [ <pattern> ... ] ]",
-" Zero or more filename patterns which, if matched, cause a file to be sent",
-" in binary mode when FILE PATTERNS are ON. HELP WILDCARDS for a description"
-,
-" of pattern syntax. SHOW PATTERNS to see the current file pattern lists.",
-" ",
-"SET FILE TEXT-PATTERNS [ <pattern> [ <pattern> ... ] ]",
-" Zero or more filename patterns which, if matched, cause a file to be sent",
-" in text mode when FILE PATTERNS is ON; if a file does not match a text or",
-" binary pattern, the prevailing SET FILE TYPE is used.",
-" ",
-#endif /* PATTERNS */
-
-#ifdef VMS
-"SET FILE RECORD-LENGTH number",
-" Sets the record length for received files of type BINARY. Use this to",
-" receive VMS BACKUP savesets or other fixed-format files that do not use",
-" the default record length of 512.",
-" ",
-#endif /* VMS */
-
-"SET FILE SCAN { ON [ size ], OFF }",
-" If TRANSFER MODE is AUTOMATIC and FILE SCAN is ON (as it is by default)",
-" Kermit peeks at the file's contents to see if it's text or binary. Use",
-" SET FILE SCAN OFF to disable file peeking, while still keeping TRANSFER",
-" MODE automatic to allow name patterns and other methods. The optional",
-" size is the number of file bytes to scan, 49152 by default. -1 means to",
-" scan the whole file. Also see SET FILE PATTERNS.",
-" ",
-
-#ifdef UNIX
-#ifdef DYNAMIC
-"SET FILE STRINGSPACE number",
-" Changes the size (in bytes) of the internal buffer that holds lists of",
-" filenames such as wildcard expansion lists. Use SHOW FILE to see the",
-" current size. Use this command to increase the size if you get a",
-" \"?String space exhausted\" error. Also see SET FILE LISTSIZE.",
-" ",
-#endif /* DYNAMIC */
-#endif /* UNIX */
-
-#ifdef UNICODE
-"SET FILE UCS BOM { ON, OFF }",
-" Whether to write a Byte Order Mark when creating a UCS-2 file.",
-" ",
-"SET FILE UCS BYTE-ORDER { BIG-ENDIAN, LITTLE-ENDIAN }",
-" Byte order to use when creating UCS-2 files, and to use when reading UCS-2",
-" files that do not start with a Byte Order Mark.",
-" ",
-#endif /* UNICODE */
-
-"SET FILE WARNING { ON, OFF }",
-" SET FILE WARNING is superseded by the newer command, SET FILE",
-" COLLISION. SET FILE WARNING ON is equivalent to SET FILE COLLISION RENAME",
-" and SET FILE WARNING OFF is equivalent to SET FILE COLLISION OVERWRITE.",
-#endif /* NOXFER */
-"" };
-
-static char *hmxyhsh[] = {
-"Syntax: SET HANDSHAKE { NONE, XON, LF, BELL, ESC, CODE number }",
-" Character to use for half duplex line turnaround handshake during file",
-" transfer. C-Kermit waits for this character from the other computer",
-" before sending its next packet. Default is NONE; you can give one of the",
-" other names like BELL or ESC, or use SET HANDSHAKE CODE to specify the",
-" numeric code value of the handshake character. Type SET HANDSH ? for a",
-" complete list of possibilities.",
-"" };
-
-#ifndef NOSERVER
-static char *hsetsrv[] = {
-"SET SERVER CD-MESSAGE {ON,OFF}",
-" Tells whether the server, after successfully executing a REMOTE CD",
-" command, should send the contents of the new directory's READ.ME",
-" (or similar) file to your screen.",
-" ",
-"SET SERVER CD-MESSAGE FILE name",
-" Tells the name of the file to be displayed as a CD-MESSAGE, such as",
-" READ.ME (SHOW SERVER tells the current CD-MESSAGE FILE name).",
-" To specify more than one filename to look for, use {{name1}{name2}..}.",
-" Synonym: SET CD MESSAGE FILE <list>.",
-" ",
-"SET SERVER DISPLAY {ON,OFF}",
-" Tells whether local-mode C-Kermit during server operation should put a",
-" file transfer display on the screen. Default is OFF.",
-" ",
-"SET SERVER GET-PATH [ directory [ directory [ ... ] ] ]",
-" Tells the C-Kermit server where to look for files whose names it receives",
-" from client GET commands when the names are not fully specified pathnames.",
-" Default is no GET-PATH, so C-Kermit looks only in its current directory.",
-" ",
-"SET SERVER IDLE-TIMEOUT seconds",
-" Idle time limit while in server mode, 0 for no limit.",
-#ifndef OS2
-" NOTE: SERVER IDLE-TIMEOUT and SERVER TIMEOUT are mutually exclusive.",
-#endif /* OS2 */
-" ",
-"SET SERVER KEEPALIVE {ON,OFF}",
-" Tells whether C-Kermit should send \"keepalive\" packets while executing",
-" REMOTE HOST commands, which is useful in case the command takes a long",
-" time to produce any output and therefore might cause the operation to time",
-" out. ON by default; turn it OFF if it causes trouble with the client or",
-" slows down the server too much.",
-" ",
-"SET SERVER LOGIN [ username [ password [ account ] ] ]",
-" Sets up a username and optional password which must be supplied before",
-" the server will respond to any commands other than REMOTE LOGIN. The",
-" account is ignored. If you enter SET SERVER LOGIN by itself, then login",
-" is no longer required. Only one SET SERVER LOGIN command can be in effect",
-" at a time; C-Kermit does not support multiple user/password pairs.",
-" ",
-"SET SERVER TIMEOUT n",
-" Server command wait timeout interval, how often the C-Kermit server issues",
-" a NAK while waiting for a command packet. Specify 0 for no NAKs at all.",
-" Default is 0.",
-""
-};
-#endif /* NOSERVER */
-
-static char *hmhrmt[] = {
-#ifdef NEWFTP
-"The REMOTE command sends file management instructions or other commands",
-"to a Kermit or FTP server. If you have a single connection, the command is",
-"directed to the server you are connected to; if you have multiple connections"
-,
-"the command is directed according to your GET-PUT-REMOTE setting.",
-#else
-"The REMOTE command sends file management instructions or other commands",
-"to a Kermit server. There should already be a Kermit running in server",
-"mode on the other end of the connection.",
-#endif /* NEWFTP */
-"Type REMOTE ? to see a list of available remote commands. Type HELP REMOTE",
-"xxx to get further information about a particular remote command xxx.",
-" ",
-"All REMOTE commands except LOGIN and LOGOUT have R-command shortcuts;",
-"for example, RDIR for REMOTE DIR, RCD for REMOTE CD, etc.",
-" ",
-#ifdef NEWFTP
-#ifdef LOCUS
-"Also see: HELP SET LOCUS, HELP FTP, HELP SET GET-PUT-REMOTE.",
-#else
-"Also see: HELP FTP, HELP SET GET-PUT-REMOTE.",
-#endif /* LOCUS */
-#else
-#ifdef LOCUS
-"Also see: HELP SET LOCUS.",
-#endif /* LOCUS */
-#endif /* NEWFTP */
-"" };
-
-#ifndef NOSPL
-static char *ifhlp[] = { "Syntax: IF [NOT] condition commandlist",
-" ",
-"If the condition is (is not) true, do the commandlist. The commandlist",
-"can be a single command, or a list of commands separated by commas and",
-"enclosed in braces. The condition can be a single condition or a group of",
-"conditions separated by AND (&&) or OR (||) and enclosed in parentheses.",
-"If parentheses are used they must be surrounded by spaces. Examples:",
-" ",
-" IF EXIST oofa.txt <command>",
-" IF ( EXIST oofa.txt || = \\v(nday) 3 ) <command>",
-" IF ( EXIST oofa.txt || = \\v(nday) 3 ) { <command>, <command>, ... }",
-" ",
-"The conditions are:",
-" ",
-" SUCCESS - The previous command succeeded",
-" OK - Synonym for SUCCESS",
-" FAILURE - The previous command failed",
-" ERROR - Synonym for FAILURE",
-" FLAG - Succeeds if SET FLAG ON, fails if SET FLAG OFF",
-" BACKGROUND - C-Kermit is running in the background",
-#ifdef CK_IFRO
-" FOREGROUND - C-Kermit is running in the foreground",
-" REMOTE-ONLY - C-Kermit was started with the -R command-line option",
-#else
-" FOREGROUND - C-Kermit is running in the foreground",
-#endif /* CK_IFRO */
-" KERBANG - A Kerbang script is running",
-" ALARM - SET ALARM time has passed",
-" ASKTIMEOUT - The most recent ASK, ASKQ, GETC, or GETOK timed out",
-" EMULATION - Succeeds if executed while in CONNECT mode",
-#ifdef OS2
-" TAPI - Current connection is via a Microsoft TAPI device",
-#endif /* OS2 */
-" ",
-" MS-KERMIT - Program is MS-DOS Kermit",
-" C-KERMIT - Program is C-Kermit",
-" K-95 - Program is Kermit 95",
-" GUI - Program runs in a GUI window",
-" ",
-" AVAILABLE CRYPTO - Encryption is available",
-" AVAILABLE KERBEROS4 - Kerberos 4 authentication is available",
-" AVAILABLE KERBEROS5 - Kerberos 5 authentication is available",
-" AVAILABLE NTLM - NTLM authentication is available",
-" AVAILABLE SRP - SRP authentication is available",
-" AVAILABLE SSL - SSL/TLS authentication is available",
-" MATCH string pattern - Succeeds if string matches pattern",
-#ifdef CKFLOAT
-" FLOAT number - Succeeds if floating-point number",
-#endif /* CKFLOAT */
-" COMMAND word - Succeeds if word is built-in command",
-" DEFINED variablename or macroname - The named variable or macro is defined",
-" DECLARED arrayname - The named array is declared",
-" NUMERIC variable or constant - The variable or constant is numeric",
-" EXIST filename - The named file exists",
-" ABSOLUTE filename - The filename is absolute, not relative",
-#ifdef CK_TMPDIR
-" DIRECTORY string - The string is the name of a directory",
-#endif /* CK_TMPDIR */
-" READABLE filename - Succeeds if the file is readable",
-" WRITEABLE filename - Succeeds if the file is writeable",
-#ifdef ZFCDAT
-" NEWER file1 file2 - The 1st file is newer than the 2nd one",
-#endif /* ZFCDAT */
-" OPEN { READ-FILE,SESSION-LOG,...} - The given file or log is open",
-#ifndef NOLOCAL
-" OPEN CONNECTION - A connection is open",
-#endif /* NOLOCAL */
-" KBHIT - A key has been pressed",
-" ",
-" VERSION - equivalent to \"if >= \\v(version) ...\"",
-" COUNT - subtract one from COUNT, execute the command if the result is",
-" greater than zero (see SET COUNT)",
-" ",
-" EQUAL s1 s2 - s1 and s2 (character strings or variables) are equal",
-" LLT s1 s2 - s1 is lexically (alphabetically) less than s2",
-" LGT s1 s1 - s1 is lexically (alphabetically) greater than s2",
-" ",
-" = n1 n2 - n1 and n2 (numbers or variables containing numbers) are equal",
-" < n1 n2 - n1 is arithmetically less than n2",
-" <= n1 n2 - n1 is arithmetically less than or equal to n2",
-" > n1 n2 - n1 is arithmetically greater than n2",
-" >= n1 n2 - n1 is arithmetically greater than or equal to n2",
-" ",
-" (number by itself) - fails if the number is 0, succeeds otherwise",
-" ",
-" TRUE - always succeeds",
-" FALSE - always fails",
-" ",
-"The IF command may be followed on the next line by an ELSE command. Example:",
-" ",
-" IF < \\%x 10 ECHO It's less",
-" ELSE echo It's not less",
-" ",
-"It can also include an ELSE part on the same line if braces are used:",
-" ",
-" IF < \\%x 10 { ECHO It's less } ELSE { ECHO It's not less }",
-" ",
-"Also see HELP WILDCARD (for IF MATCH pattern syntax).",
-"" };
-
-static char *hmxxeval[] = { "Syntax: EVALUATE variable expression",
-" Evaluates the expression and assigns its value to the given variable.",
-" The expression can contain numbers and/or numeric-valued variables or",
-" functions, combined with mathematical operators and parentheses in",
-" traditional notation. Operators include +-/*(), etc. Example:",
-" EVALUATE \\%n (1+1) * (\\%a / 3).",
-" ",
-" NOTE: Prior to C-Kermit 7.0, the syntax was \"EVALUATE expression\"",
-" (no variable), and the result was printed. Use SET EVAL { OLD, NEW }",
-" to choose the old or new behavior, which is NEW by default.",
-" ",
-"Alse see: HELP FUNCTION EVAL.",
-"" };
-#endif /* NOSPL */
-
-static char *hmxxexit[] = {
-"Syntax: EXIT (or QUIT) [ number [ text ] ]",
-" Exits from the Kermit program, closing all open files and devices.",
-" If a number is given it becomes Kermit's exit status code. If text is",
-" included, it is printed. Also see SET EXIT.",
-"" };
-
-#ifndef NOSPL
-static char *ifxhlp[] = { "\
-Syntax: XIF condition { commandlist } [ ELSE { commandlist } ]",
-" Obsolete. Same as IF (see HELP IF).",
-"" };
-
-static char *forhlp[] = { "\
-Syntax: FOR variablename initial-value final-value increment { commandlist }",
-" FOR loop. Execute the comma-separated commands in the commandlist the",
-" number of times given by the initial value, final value and increment.",
-" Example: FOR \\%i 10 1 -1 { pause 1, echo \\%i }", "" };
-
-static char *whihlp[] = { "\
-Syntax: WHILE condition { commandlist }",
-" WHILE loop. Execute the comma-separated commands in the bracketed",
-" commandlist while the condition is true. Conditions are the same as for",
-" IF commands.",
-"" };
-
-static char *swihlp[] = {
-"Syntax: SWITCH <variable> { case-list }",
-" Selects from a group of commands based on the value of a variable.",
-" The case-list is a series of lines like these:",
-" ",
-" :x, command, command, ..., break",
-" ",
-" where \"x\" is a possible value for the variable. At the end of the",
-" case-list, you can put a \"default\" label to catch when the variable does",
-" not match any of the labels:",
-" ",
-" :default, command, command, ...",
-" ",
-"The case label \"x\" can be a character, a string, a variable, a function",
-"invocation, a pattern, or any combination of these. See HELP WILDCARDS",
-"for information about patterns.",
-""};
-
-static char *openhlp[] = {
-"Syntax: OPEN mode filename",
-" For use with READ and WRITE commands. Open the local file in the",
-" specified mode: READ, WRITE, or APPEND. !READ and !WRITE mean to read",
-" from or write to a system command rather than a file. Examples:",
-" ",
-" OPEN READ oofa.txt",
-" OPEN !READ sort foo.bar",
-"" };
-
-static char *hxxask[] = {
-"Syntax: ASK [ switches ] variablename [ prompt ]",
-"Example: ASK \\%n { What is your name\\? }",
-" Issues the prompt and defines the variable to be whatever is typed in",
-" response, up to the terminating carriage return. Use braces to preserve",
-" leading and/or trailing spaces in the prompt.",
-" ",
-"Syntax: ASKQ [ switches ] variablename [ prompt ]",
-"Example: ASKQ \\%p { Password:}",
-" Like ASK except the response does not echo on the screen.",
-" ",
-"Switches:",
-" /DEFAULT:text",
-" Text to supply if the user enters a blank response or the /TIMEOUT",
-" limit expired with no response.",
-" ",
-#ifdef OS2
-" /POPUP",
-" The prompt and response dialog takes place in a text-mode popup.",
-" K95 only; in C-Kermit this switch is ignored.",
-" ",
-#ifdef KUI
-" /GUI",
-" The prompt and response dialog takes place in a GUI popup.",
-" K95 GUI version only; in C-Kermit and the K95 console version,",
-" this switch is ignored.",
-" ",
-#endif /* KUI */
-#endif /* OS2 */
-" /TIMEOUT:number",
-" If the response is not entered within the given number of seconds, the",
-" command fails. This is equivalent to setting ASK-TIMER to a positive",
-" number, except it applies only to this command. Also see SET ASK-TIMER.",
-" NOTE: If a /DEFAULT: value was also given, it is supplied automatically",
-" upon timeout and the command does NOT fail.",
-
-" ",
-" /QUIET",
-" Suppresses \"?Timed out\" message when /TIMEOUT is given and user doesn't",
-" respond within the time limit.",
-""};
-static char *hxxgetc[] = {
-"Syntax: GETC variablename [ prompt ]",
-"Example: GETC \\%c { Type any character to continue...}",
-" Issues the prompt and sets the variable to the first character you type.",
-" Use braces to preserve leading and/or trailing spaces in the prompt.",
-" ",
-"Also see SET ASK-TIMER.",
-""};
-
-static char *hmxytimer[] = {
-"Syntax: SET ASK-TIMER number",
-" For use with ASK, ASKQ, GETOK, and GETC. If ASK-TIMER is set to a number",
-" greater than 0, these commands will time out after the given number of",
-" seconds with no response. This command is \"sticky\", so to revert to",
-" \
-untimed ASKs after a timed one, use SET ASK-TIMER 0. Also see IF ASKTIMEOUT.",
-""};
-
-static char *hxxdot[] = {
-"Syntax: .<variable-name> <assignment-operator> <value>",
-" Assigns the value to the variable in the manner indicated by the",
-" assignment operator:",
-" = Copies without evaluation (like DEFINE).",
-" := Copies with evaluation (like ASSIGN).",
-" ::= Copies with arithmetic evaluation (like EVALUATE).",
-""};
-
-static char *hxxdef[] = {
-"Syntax: DEFINE name [ definition ]",
-" Defines a macro or variable. Its value is the definition, taken",
-" literally. No expansion or evaluation of the definition is done. Thus",
-" if the definition includes any variable or function references, their",
-" names are included, rather than their values (compare with ASSIGN). If",
-" the definition is omitted, then the named variable or macro is undefined.",
-" ",
-"A typical macro definition looks like this:",
-" ",
-" DEFINE name command, command, command, ...",
-" ",
-"for example:",
-" ",
-" DEFINE vax set parity even, set duplex full, set flow xon/xoff",
-" ",
-"which defines a Kermit command macro called 'vax'. The definition is a",
-"comma-separated list of Kermit commands. Use the DO command to execute",
-"the macro, or just type its name, followed optionally by arguments.",
-" ",
-"The definition of a variable can be anything at all, for example:",
-" ",
-" DEFINE \\%a Monday",
-" DEFINE \\%b 3",
-" ",
-"These variables can be used almost anywhere, for example:",
-" ",
-" ECHO Today is \\%a",
-" SET BLOCK-CHECK \\%b",
-"" };
-
-static char *hxxass[] = {
-"Syntax: ASSIGN variablename string.",
-"Example: ASSIGN \\%a My name is \\%b.",
-" Assigns the current value of the string to the variable (or macro).",
-" The definition string is fully evaluated before it is assigned, so that",
-" the values of any variables that are contained are used, rather than their",
-" names. Compare with DEFINE. To illustrate the difference, try this:",
-" ",
-" DEFINE \\%a hello",
-" DEFINE \\%x \\%a",
-" ASSIGN \\%y \\%a",
-" DEFINE \\%a goodbye",
-" ECHO \\%x \\%y",
-" ",
-" This prints 'goodbye hello'.", "" };
-
-static char *hxxdec[] = {
-"Syntax: DECREMENT variablename [ number ]",
-" Decrement (subtract one from) the value of a variable if the current value",
-" is numeric. If the number argument is given, subtract that number",
-" instead.",
-" ",
-"Examples: DECR \\%a, DECR \\%a 7, DECR \\%a \\%n", "" };
-
-static char *hxxinc[] = {
-"Syntax: INCREMENT variablename [ number ]",
-" Increment (add one to) the value of a variable if the current value is",
-" numeric. If the number argument is given, add that number instead.",
-" ",
-"Examples: INCR \\%a, INCR \\%a 7, INCR \\%a \\%n", "" };
-#endif /* NOSPL */
-
-#ifdef ANYX25
-#ifndef IBMX25
-static char *hxxpad[] = {
-"Syntax: PAD command",
-"X.25 PAD commands:",
-" ",
-" PAD CLEAR - Clear the virtual call",
-" PAD STATUS - Return the status of virtual call",
-" PAD RESET - Send a reset packet",
-" PAD INTERRUPT - Send an interrupt packet",
-""};
-#endif /* IBMX25 */
-
-static char *hxyx25[] = {
-"Syntax: SET X.25 option { ON [ data ], OFF }",
-" ",
-"X.25 call options:",
-" CLOSED-USER-GROUP { ON index, OFF }",
-" Enable or disable closed user group call, where index is the group",
-" index, 0 to 99.",
-" REVERSE-CHARGE { ON, OFF }",
-" Tell whether you want to reverse the charges for the call.",
-" CALL-USER-DATA { ON string, OFF }",
-" Specify call user-data for the X.25 call.",
-""};
-#endif /* ANYX25 */
-
-static char *hxyprtr[] = {
-#ifdef PRINTSWI
-"Syntax: SET PRINTER [ switches ] [ name ]",
-" ",
-" Specifies the printer to be used for transparent-print, autoprint, and",
-" screen-dump material during terminal emulation, as well as for the PRINT",
-" command, plus various options governing print behavior.",
-" ",
-"Switches for specifying the printer by type:",
-" ",
-"/NONE",
-" Include this switch to specify that all printer actions should simply be",
-" skipped. Use this, for example, if you have no printer.",
-" ",
-"/DOS-DEVICE[:name]",
-" Include this to declare a DOS printer and to specify its name, such as",
-" PRN, LPT1, etc.",
-" ",
-#ifdef NT
-"/WINDOWS-QUEUE[:[queue-name]]",
-" Include this to declare a Windows printer and specify its queue name.",
-" Type question mark (?) after the colon (:) to see a list of known queue",
-" names. If the colon is absent, the switch indicates the currently",
-" selected printer is a Windows Print Queue. If the colon is provided",
-" and the name is absent, the Windows Print Queue chosen as the Default",
-" Printer is selected.",
-" ",
-#endif /* NT */
-"/FILE[:name]",
-" Specifies that all printer material is to be appended to the named file,",
-" rather than being sent to a printer. If the file does not exist, it is",
-" created the first time any material is to be printed.",
-" ",
-"/PIPE[:name]",
-" Specifies that all printer material is to be sent as standard input to",
-" the program or command whose name is given. Example:",
-" ",
-" SET PRINTER /PIPE:{textps > lpt1}",
-" ",
-"If you give a printer name without specifying any of these switches, then it",
-"is assumed to be a DOS printer device or filename unless the name given",
-"(after removing enclosing braces, if any) starts with \"|\", \
-in which case it",
-"is a pipe. Examples:",
-" ",
-" SET PRINTER LPT1 <-- DOS device",
-" SET PRINTER {| textps > lpt1} <-- Pipe",
-" ",
-"The next group of switches tells whether the printer is one-way or",
-"bidirectional (two-way):",
-" ",
-"/OUTPUT-ONLY",
-" Include this to declare the printer capable only of receiving material to",
-" be printed, but not sending anything back. This is the normal kind of",
-" printer, Kermit's default kind, and the opposite of /BIDIRECTIONAL.",
-" ",
-"/BIDIRECTIONAL",
-" Include this to declare the printer bidirectional. This is the opposite ",
-" of /OUTPUT-ONLY. You can also use this option with serial printers, even",
-" if they aren't bidirectional, in case you need to specify speed, flow",
-" control, or parity.",
-" ",
-"The next group applies only to bidirectional and/or serial printers:",
-" ",
-"/FLOW-CONTROL:{NONE,XON/XOFF,RTS/CTS,KEEP}",
-" Flow control to use with a serial bidirectional printer, default KEEP;",
-#ifdef NT
-" i.e. use whatever the Windows driver for the port normally uses.",
-#else
-" i.e. use whatever the OS/2 driver for the port normally uses.",
-#endif /* NT */
-" ",
-"/PARITY:{NONE,EVEN,ODD,SPACE,MARK}",
-" Parity to use with a serial printer, default NONE; i.e. use 8 data bits",
-" and no parity. If you omit the colon and the keyword, NONE is selected.",
-" ",
-"/SPEED:number",
-" Interface speed, in bits per second, to use with a serial printer, such as",
-" 2400, 9600, 19200, etc. Type SET PRINTER /SPEED:? for a list of possible",
-" speeds.",
-" ",
-"The next group deals with print jobs -- how to identify them, how to start",
-"them, how to terminate them:",
-" ",
-"/TIMEOUT[:number]",
-" Used with host-directed transparent or auto printing, this is the number",
-" of seconds to wait after the host closes the printer before terminating",
-" the print job if the printer is not opened again during the specified",
-" amount of time.",
-" ",
-"/JOB-HEADER-FILE[:filename]",
-" The name of a file to be sent to the printer at the beginning of each",
-" print job, as a burst page, or to configure the printer. Normally no file",
-" is is sent.",
-" ",
-"/END-OF-JOB-STRING[:string]",
-" String of characters to be sent to the printer at the end of the print",
-" job, usually used to force the last or only page out of the printer. When",
-" such a string is needed, it usually consists of a single formfeed: \"set",
-" printer /end-of-job:{\\12}\". No end-of-job string is sent unless you",
-" specify one with this option. If the string contains any spaces or",
-" control characters (even in backslash notation, as above), enclose it in",
-" braces.",
-" ",
-"The next group is for use with printers that print only PostScript:",
-" ",
-"/POSTSCRIPT or /PS",
-" Indicates that K95 should convert all text to PostScript before sending",
-" it to the printer. The fixed-pitch Courier-11 font is used.",
-" ",
-"/WIDTH:number",
-" Specifies the width of the page in characters. If this switch is not",
-" given, 80 is used.",
-" ",
-"/HEIGHT:number",
-" Specifies the height of the page in lines. If this switch is not given",
-" 66 is used.",
-" ",
-"/NOPOSTSCRIPT or /NOPS",
-" Indicates that K95 should not convert all text to PostScript before",
-" sending it to the printer.",
-" ",
-"The final switch is for use with AutoPrint mode and Screen Dumps",
-" ",
-"/CHARACTER-SET:<character-set>",
-" Specifies the character set used by the printer which may be different",
-" from both the character set used by the host and by the local computer.",
-" The default value is CP437.",
-" ",
-"SHOW PRINTER displays your current printer settings.",
-#else
-#ifdef UNIX
-"Syntax: SET PRINTER [ { |command, filename } ]",
-" Specifies the command (such as \"|lpr\") or filename to be used by the",
-" PRINT command. If a filename is given, each PRINT command appends to the",
-" given file. If the SET PRINTER argument contains spaces, it must be",
-" enclosed in braces, e.g. \"set printer {| lpr -Plaser}\". If the argument",
-" is omitted the default value is restored. SHOW PRINTER lists the current",
-" printer. See HELP PRINT for further info.",
-#else
-"Sorry, SET PRINTER not available yet.",
-#endif /* UNIX */
-#endif /* PRINTSWI */
-""};
-
-#ifdef OS2
-#ifdef BPRINT
-static char *hxybprtr[] = {
-"Syntax: SET BPRINTER [ portname speed [ parity [ flow-control ] ] ]",
-" (Obsolete, replaced by SET PRINTER /BIDIRECTIONAL.)",
-""};
-#endif /* BPRINT */
-#endif /* OS2 */
-
-static char *hxyexit[] = {
-"Syntax: SET EXIT HANGUP { ON, OFF }",
-" When ON (which is the default), C-Kermit executes an implicit HANGUP and",
-" CLOSE command on the communications device or connection when it exits.",
-" When OFF, Kermit skips this sequence.",
-" ",
-"Syntax: SET EXIT ON-DISCONNECT { ON, OFF }",
-" When ON, C-Kermit EXITs automatically when a network connection",
-" is terminated either by the host or by issuing a HANGUP command.",
-" ",
-"Syntax: SET EXIT STATUS number",
-#ifdef NOSPL
-" Set C-Kermit's program return code to the given number.",
-#else
-" Set C-Kermit's program return code to the given number, which can be a",
-" constant, variable, function result, or arithmetic expression.",
-#endif /* NOSPL */
-" ",
-"Syntax: SET EXIT WARNING { ON, OFF, ALWAYS }",
-" When EXIT WARNING is ON, issue a warning message and ask for confirmation",
-" before EXITing if a connection to another computer might still be open.",
-" When EXIT WARNING is ALWAYS, confirmation is always requested. When OFF",
-" it is never requested. The default is ON.",
-"" };
-
-#ifndef NOSPL
-static char *hxxpau[] = {
-"Syntax: PAUSE [ { number-of-seconds, hh:mm:ss } ]",
-"Example: PAUSE 3 or PAUSE 14:52:30",
-" Do nothing for the specified number of seconds or until the given time of",
-" day in 24-hour hh:mm:ss notation. If the time of day is earlier than the",
-" current time, it is assumed to be tomorrow. If no argument given, one",
-" second is used. The pause can be interrupted by typing any character on",
-" the keyboard unless SLEEP CANCELLATION is OFF. If interrupted, PAUSE",
-" fails, otherwise it succeeds. Synonym: SLEEP.",
-"" };
-
-static char *hxxmsl[] = {
-"Syntax: MSLEEP [ number ]",
-"Example: MSLEEP 500",
-" Do nothing for the specified number of milliseconds; if no number given,",
-" 100 milliseconds.","" };
-#endif /* NOSPL */
-
-#ifndef NOPUSH
-extern int nopush;
-static char *hxxshe[] = {
-"Syntax: !, @, RUN, PUSH, or SPAWN, optionally followed by a command.",
-" Gives the command to the local operating system's command processor, and",
-" displays the results on the screen. If the command is omitted, enters the",
-" system's command line interpreter or shell; exit from it (the command for",
-" this is usually EXIT or QUIT or LOGOUT) to return to Kermit.",
-""
-};
-#endif /* NOPUSH */
-
-#ifndef NOXMIT
-static char *hxxxmit[] = {
-"Syntax: TRANSMIT [ switches ] filename",
-" Sends the contents of a file, without any error checking or correction,",
-" to the computer on the other end of your SET LINE or SET HOST connection",
-" (or if C-Kermit is in remote mode, displays it on the screen). The",
-" filename is the name of a single file (no wildcards) to be sent or, if",
-" the /PIPE switch is included, the name of a command whose output is to be",
-" sent.",
-" ",
-" The file is sent according to your current FILE TYPE setting (BINARY or",
-" TEXT), which you can override with a /BINARY or /TEXT switch without",
-" changing the global setting. In text mode, it is sent a line at a time,",
-" with carriage return at the end of each line (as if you were typing it at",
-" your keyboard), and C-Kermit waits for a linefeed to echo before sending",
-" the next line; use /NOWAIT to eliminate the feedback requirement. In",
-" binary mode, it is sent a character at a time, with no feedback required.",
-" ",
-" Normally the transmitted material is echoed to your screen. Use SET",
-" TRANSMIT ECHO OFF or the /NOECHO switch to suppress echoing. Note that",
-" TRANSMIT /NOECHO /NOWAIT /BINARY is a special case, that more or less",
-" blasts the file out at full speed.",
-" ",
-#ifndef NOCSETS
-" Character sets are translated according to your current FILE and TERMINAL",
-" CHARACTER-SET settings when TRANSMIT is in text mode. Include /TRANSPARENT"
-,
-" to disable character-set translation in text mode (/TRANSPARENT implies",
-" /TEXT).",
-" ",
-#endif /* NOCSETS */
-" There can be no guarantee that the other computer will receive the file",
-" correctly and completely. Before you start the TRANSMIT command, you",
-" must put the other computer in data collection mode, for example by",
-" starting a text editor. TRANSMIT may be interrupted by Ctrl-C. Synonym:",
-" XMIT. See HELP SET TRANSMIT for further information.",
-"" };
-#endif /* NOXMIT */
-
-#ifndef NOCSETS
-static char *hxxxla[] = {
-"Syntax: TRANSLATE file1 cs1 cs2 [ file2 ]",
-" Translates file1 from the character set cs1 into the character set cs2",
-" and stores the result in file2. The character sets can be any of",
-" C-Kermit's file character sets. If file2 is omitted, the translation",
-" is displayed on the screen. An appropriate intermediate character-set",
-" is chosen automatically, if necessary. Synonym: XLATE. Example:",
-" ",
-" TRANSLATE lasagna.lat latin1 italian lasagna.nrc",
-" ",
-" Multiple files can be translated if file2 is a directory or device name,",
-" rather than a filename, or if file2 is omitted.",
-"" };
-#endif /* NOCSETS */
-
-#ifndef NOSPL
-static char *hxxwai[] = {
-"Syntax: WAIT { number-of-seconds, hh:mm:ss } [ <what> ]",
-" ",
-"Examples:",
-" wait 5 cd cts",
-" wait 23:59:59 cd",
-" ",
-" Waits up to the given number of seconds or the given time of day for the",
-" specified item or event, which can be FILE, the name(s) of one or more",
-" modem signals, or nothing. If nothing is specified, WAIT acts like SLEEP.",
-" If one or more modem signal names are given, Kermit waits for the specified"
-,
-" modem signals to appear on the serial communication device.",
-" Sets FAILURE if the signals do not appear in the given time or interrupted",
-" from the keyboard during the waiting period.",
-" ",
-"Signals:",
-" cd = Carrier Detect;",
-" dsr = Dataset Ready;",
-" cts = Clear To Send;",
-" ri = Ring Indicate.",
-" ",
-"If you want Kermit to wait for a file event, then the syntax is:",
-" ",
-" WAIT <time> FILE { CREATION, DELETION, MODIFICATION } <filename>",
-" ",
-"where <time> is as above, and <filename> is the name of a single file.",
-"Kermit waits up to the given amount of time for the specified event to occur",
-"with the specified file, succeeds if it does, fails if it doesn't.",
-"" };
-#endif /* NOSPL */
-
-static char *hxxwri[] = {
-"Syntax: WRITE name text",
-" Writes the given text to the named log or file. The text text may include",
-" backslash codes, and is not terminated by a newline unless you include the",
-" appropriate code. The name parameter can be any of the following:",
-" ",
-" DEBUG-LOG",
-" ERROR (standard error)",
-#ifndef NOSPL
-" FILE (the OPEN WRITE, OPEN !WRITE, or OPEN APPEND file, see HELP OPEN)",
-#endif /* NOSPL */
-" PACKET-LOG",
-" SCREEN (compare with ECHO)",
-#ifndef NOLOCAL
-" SESSION-LOG",
-#endif /* NOLOCAL */
-" TRANSACTION-LOG", "" };
-
-#ifndef NODIAL
-static char *hxxlook[] = { "Syntax: LOOKUP name",
-" Looks up the given name in the dialing directory or directories, if any,",
-" specified in the most recent SET DIAL DIRECTORY command. Each matching",
-" entry is shown, along with any transformations that would be applied to",
-" portable-format entries based on your locale. HELP DIAL, HELP SET DIAL",
-" for further info.",
-""
-};
-
-static char *hxxansw[] = { "Syntax: ANSWER [ <seconds> ]",
-#ifdef OS2
-" Waits for a modem call to come in. Prior SET MODEM TYPE and SET PORT",
-#else
-" Waits for a modem call to come in. Prior SET MODEM TYPE and SET LINE",
-#endif /* OS2 */
-" required. If <seconds> is 0 or not specified, Kermit waits forever or",
-" until interrupted, otherwise Kermit waits the given number of seconds.",
-" The ANSWER command puts the modem in autoanswer mode. Subsequent DIAL",
-" commands will automatically put it (back) in originate mode. SHOW MODEM,",
-" HELP SET MODEM for more info.",
-""
-};
-
-static char *hxxdial[] = { "Syntax: DIAL phonenumber",
-"Example: DIAL 7654321",
-" \
-Dials a number using an autodial modem. First you must SET MODEM TYPE, then",
-#ifdef OS2
-" SET PORT (or in Windows only, SET PORT TAPI instead of SET MODEM TYPE and",
-" SET LINE), then SET SPEED. Then give the DIAL command, including the phone",
-#else
-" SET LINE, then SET SPEED. Then give the DIAL command, including the phone",
-#endif /* OS2 */
-" number, for example:",
-" ",
-" DIAL 7654321",
-#ifdef NETCONN
-" ",
-" If the modem is on a network modem server, SET HOST first, then SET MODEM",
-" TYPE, then DIAL.",
-#endif /* NETCONN */
-" ",
-"If you give the DIAL command interactively at the Kermit prompt, and the",
-"call is placed successfully, Kermit automatically enters CONNECT mode.",
-"If the DIAL command is given from a macro or command file, Kermit remains",
-"in command mode after the call is placed, successfully or not. You can",
-"change this behavior with the SET DIAL CONNECT command.",
-" ",
-"If the phonenumber starts with a letter, and if you have used the SET DIAL",
-"DIRECTORY command to specify one or more dialing-directory files, Kermit",
-"looks it up in the given file(s); if it is found, the name is replaced by",
-"the number or numbers associated with the name. If it is not found, the",
-"name is sent to the modem literally.",
-" ",
-"If the phonenumber starts with an equals sign (\"=\"), this forces the part",
-"after the = to be sent literally to the modem, even if it starts with a",
-"letter, without any directory lookup.",
-" ",
-"You can also give a list of phone numbers enclosed in braces, e.g:",
-" ",
-" dial {{7654321}{8765432}{+1 (212 555-1212}}",
-" ",
-"(Each number is enclosed in braces and the entire list is also enclosed in",
-"braces.) In this case, each number is tried until there is an answer. The",
-"phone numbers in this kind of list can not be names of dialing directory",
-"entries.",
-" ",
-"A dialing directory is a plain text file, one entry per line:",
-" ",
-" name phonenumber ; comments",
-" ",
-"for example:",
-" ",
-" work 9876543 ; This is a comment",
-" e-mail +1 (212) 555 4321 ; My electronic mailbox",
-" germany +49 (511) 555 1234 ; Our branch in Hanover",
-" ",
-"If a phone number starts with +, then it must include country code and",
-"area code, and C-Kermit will try to handle these appropriately based on",
-"the current locale (HELP SET DIAL for further info); these are called",
-"PORTABLE entries. If it does not start with +, it is dialed literally.",
-" ",
-"If more than one entry is found with the same name, Kermit dials all of",
-"them until the call is completed; if the entries are in portable format,",
-"Kermit dials them in cheap-to-expensive order: internal, then local, then",
-"long-distance, then international, based on its knowledge of your local",
-"country code and area code (see HELP SET DIAL).",
-" ",
-"Specify your dialing directory file(s) with the SET DIAL DIRECTORY command.",
-" ",
-#ifdef NETCONN
-"See also SET DIAL, SET MODEM, SET LINE, SET HOST, SET SPEED, REDIAL, and",
-"PDIAL.",
-#else
-"See also SET DIAL, SET MODEM, SET LINE, SET SPEED, PDIAL, and REDIAL.",
-#endif /* NETCONN */
-"" };
-
-#ifdef CK_TAPI
-static char *hxxtapi[] = {
-"TAPI CONFIGURE-LINE <tapi-line>",
-" Displays the TAPI Configure Line Dialog box and allows you to",
-" alter the default configuration for the specified <tapi-line>.",
-" ",
-"TAPI DIALING-PROPERTIES",
-" Displays the TAPI Dialing Properties (locations) Dialog box. The",
-" Dialing rules may be changed and locations created and deleted.",
-" When the dialog box is closed, K-95 imports the current Dialing",
-" Properties' Location into the Kermit DIAL command settings.",
-""};
-
-static char *hxytapi[] = {
-"SET TAPI LINE <tapi-line>",
-" Opens a TAPI device for use by Kermit.",
-" ",
-"SET TAPI MODEM-DIALING {ON, [OFF]}",
-" If TAPI MODEM-DIALING is OFF when SET TAPI LINE is issued, Kermit opens",
-" the TAPI device directly as a \"raw port\". The device is unavailable to",
-" other applications and Kermit performs dialing functions using its",
-" built-in dialing and modem databases. If TAPI MODEM-DIALING is ON, TAPI",
-" handles all dialing functions and the port may be shared with other",
-" applications when a call in not active. When TAPI MODEM-DIALING is OFF,",
-" SET MODEM TYPE TAPI Kermit uses the TAPI modem commands imported from the",
-" Windows Registry during the previous SET TAPI LINE call.",
-" ",
-"SET TAPI LOCATION <tapi-location>",
-" Specifies the TAPI location to make current for the entire system. The",
-" <tapi-location>'s dialing properties are imported into Kermit's SET DIAL",
-" command database.",
-" ",
-"SET TAPI PHONE-NUMBER-CONVERSIONS {ON, OFF, [AUTO]}",
-" Controls whether the phone number conversions are performed by TAPI (ON)",
-" or by Kermit (OFF), or according the type of port that was selected",
-" (AUTO); AUTO is the default, and is equivalent to ON if the current",
-" LINE/PORT is a TAPI device and TAPI MODEM-DIALING is ON, OFF otherwise.",
-" ",
-"SET TAPI MODEM-LIGHTS {[ON], OFF}",
-" Displays a modem lights indicator on the Windows 95 Taskbar. Does nothing",
-" in Windows NT 4.0.",
-" ",
-"SET TAPI MANUAL-DIALING {ON, [OFF]}",
-" Displays a dialog box during dialing requesting that you manually dial the",
-" phone before continuing. Applies only when TAPI MODEM-DIALING is ON.",
-" ",
-"SET TAPI WAIT-FOR-CREDIT-CARD-TONE <seconds>",
-" Some modems don't support the '$' (BONG) symbol during dialing, which",
-" means \"wait for credit card tone before continuing.\" If TAPI recognizes",
-" the modem as one that does not support BONG, it replaces the '$' with",
-" <seconds> worth of pauses. The default is 8 seconds. This command",
-" applies only when TAPI MODEM-DIALING is ON",
-" ",
-"SET TAPI PRE-DIAL-TERMINAL {ON, [OFF]}",
-"SET TAPI POST-DIAL-TERMINAL {ON, [OFF]}",
-" Displays a small terminal window that may be used to communicate with the",
-" modem or the host prior to or immediately after dialing; applies only when",
-" TAPI MODEM-DIALING is ON",
-" ",
-"SET TAPI INACTIVITY-TIMEOUT <minutes>",
-" Specifies the number of minutes of inactivity that may go by before TAPI",
-" disconnects the line. The default is 0 which means disable this function.",
-" Applies only when TAPI MODEM-DIALING is ON.",
-" ",
-"SET TAPI USE-WINDOWS-CONFIGURATION {ON, [OFF]}",
-" Specifies whether the TAPI modem values for speed, parity, stop bits, flow",
-" control, etc. are used in preference to the current values specified",
-" within Kermit-95.",
-" ",
-""};
-#endif /* CK_TAPI */
-
-#endif /* NODIAL */
-
-#ifdef TNCODE
-static char *hmxxiks[] = {
-"Syntax: IKS [ switches ] [ host [ service ] ]",
-" Establishes a new connection to an Internet Kermit Service daemon.",
-" Equivalent to SET NETWORK TYPE TCP/IP, SET HOST host KERMIT /TELNET,",
-" IF SUCCESS CONNECT. If host is omitted, the previous connection (if any)",
-" is resumed. Depending on how Kermit has been built switches may be",
-" available to require a secure authentication method and bidirectional",
-" encryption. See HELP SET TELNET for more info.",
-" ",
-#ifdef CK_AUTHENTICATION
-" /AUTH:<type> is equivalent to SET TELNET AUTH TYPE <type> and",
-" SET TELOPT AUTH REQUIRED with the following exceptions. If the type",
-" is AUTO, then SET TELOPT AUTH REQUESTED is executed and if the type",
-" is NONE, then SET TELOPT AUTH REFUSED is executed.",
-" ",
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
-" /ENCRYPT:<type> is equivalent to SET TELNET ENCRYPT TYPE <type>",
-" and SET TELOPT ENCRYPT REQUIRED REQUIRED with the following exceptions.",
-" If the type is AUTO then SET TELOPT AUTH REQUESTED REQUESTED is executed",
-" and if the type is NONE then SET TELOPT ENCRYPT REFUSED REFUSED is",
-" executed.",
-" ",
-#endif /* CK_ENCRYPTION */
-" /USERID:[<name>]",
-" This switch is equivalent to SET LOGIN USERID <name> or SET TELNET",
-" ENVIRONMENT USER <name>. If a string is given, it sent to host during",
-" Telnet negotiations; if this switch is given but the string is omitted,",
-" no user ID is sent to the host. If this switch is not given, your",
-" current USERID value, \\v(userid), is sent. When a userid is sent to the",
-" host it is a request to login as the specified user.",
-" ",
-#ifdef CK_AUTHENTICATION
-" /PASSWORD:[<string>]",
-" This switch is equivalent to SET LOGIN PASSWORD. If a string is given,",
-" it is treated as the password to be used (if required) by any Telnet",
-" Authentication protocol (Kerberos Ticket retrieval, Secure Remote",
-" Password, or X.509 certificate private key decryption.) If no password",
-" switch is specified a prompt is issued to request the password if one",
-" is required for the negotiated authentication method.",
-#endif /* CK_AUTHENTICATION */
-""};
-
-static char *hmxxtel[] = {
-"Syntax: TELNET [ switches ] [ host [ service ] ]",
-" Equivalent to SET NETWORK TYPE TCP/IP, SET HOST host [ service ] /TELNET,",
-" IF SUCCESS CONNECT. If host is omitted, the previous connection (if any)",
-" is resumed. Depending on how Kermit has been built switches may be",
-" available to require a secure authentication method and bidirectional",
-" encryption. See HELP SET TELNET for more info.",
-" ",
-#ifdef CK_AUTHENTICATION
-" /AUTH:<type> is equivalent to SET TELNET AUTH TYPE <type> and",
-" SET TELOPT AUTH REQUIRED with the following exceptions. If the type",
-" is AUTO, then SET TELOPT AUTH REQUESTED is executed and if the type",
-" is NONE, then SET TELOPT AUTH REFUSED is executed.",
-" ",
-#endif /* CK_AUTHENTICATION */
-#ifdef CK_ENCRYPTION
-" /ENCRYPT:<type> is equivalent to SET TELNET ENCRYPT TYPE <type>",
-" and SET TELOPT ENCRYPT REQUIRED REQUIRED with the following exceptions.",
-" If the type is AUTO then SET TELOPT AUTH REQUESTED REQUESTED is executed",
-" and if the type is NONE then SET TELOPT ENCRYPT REFUSED REFUSED is",
-" executed.",
-" ",
-#endif /* CK_ENCRYPTION */
-" /USERID:[<name>]",
-" This switch is equivalent to SET LOGIN USERID <name> or SET TELNET",
-" ENVIRONMENT USER <name>. If a string is given, it sent to host during",
-" Telnet negotiations; if this switch is given but the string is omitted,",
-" no user ID is sent to the host. If this switch is not given, your",
-" current USERID value, \\v(userid), is sent. When a userid is sent to the",
-" host it is a request to login as the specified user.",
-" ",
-#ifdef CK_AUTHENTICATION
-" /PASSWORD:[<string>]",
-" This switch is equivalent to SET LOGIN PASSWORD. If a string is given,",
-" it is treated as the password to be used (if required) by any Telnet",
-" Authentication protocol (Kerberos Ticket retrieval, Secure Remote",
-" Password, or X.509 certificate private key decryption.) If no password",
-" switch is specified a prompt is issued to request the password if one",
-" is required for the negotiated authentication method.",
-#endif /* CK_AUTHENTICATION */
-""};
-
-static char *hxtopt[] = {
-"TELOPT { AO, AYT, BREAK, CANCEL, EC, EL, EOF, EOR, GA, IP, DMARK, NOP, SE,",
-" SUSP, SB [ option ], DO [ option ], DONT [ option ],",
-" WILL [ option ], WONT [option] }",
-" This command lets you send all the Telnet protocol commands. Note that",
-" certain commands do not require a response, and therefore can be used as",
-" nondestructive \"probes\" to see if the Telnet session is still open;",
-" e.g.:",
-" ",
-" set host xyzcorp.com",
-" ...",
-" telopt nop",
-" telopt nop",
-" if fail stop 1 Connection lost",
-" ",
-" TELOPT NOP is sent twice because the failure of the connection will not",
-" be detected until the second send is attempted. This command is meant",
-" primarily as a debugging tool for the expert user.",
-""};
-#endif /* TNCODE */
-
-#endif /* NOHELP */
-
-/* D O H L P -- Give a help message */
-
-_PROTOTYP( int dohset, (int) );
-#ifndef NOCMDL
-_PROTOTYP( int dohopts, (void) );
-#endif /* NOCMDL */
-#ifndef NOSPL
-_PROTOTYP( int dohfunc, (int) );
-extern struct keytab fnctab[];
-extern int nfuncs;
-#endif /* NOSPL */
-#ifdef OS2
-#ifndef NOKVERBS
-_PROTOTYP( int dohkverb, (int) );
-extern struct keytab kverbs[];
-extern int nkverbs;
-#endif /* NOKVERBS */
-#endif /* OS2 */
-
-#ifndef NOSPL
-static char * hxxdcl[] = {
-"Syntax: ARRAY verb operands...",
-" ",
-"Declares arrays and performs various operations on them. Arrays have",
-"the following syntax:",
-" ",
-" \\&a[n]",
-" ",
-"where \"a\" is a letter and n is a number or a variable with a numeric value",
-"or an arithmetic expression. The value of an array element can be anything",
-"at all -- a number, a character, a string, a filename, etc.",
-" ",
-"The following ARRAY verbs are available:",
-" ",
-"[ ARRAY ] DECLARE arrayname[n] [ = initializers... ]",
-" Declares an array of the given size, n. The resulting array has n+1",
-" elements, 0 through n. Array elements can be used just like any other",
-" variables. Initial values can be given for elements 1, 2, ... by",
-" including = followed by one or more values separated by spaces. If you",
-" omit the size, the array is sized according to the number of initializers;",
-" if none are given the array is destroyed and undeclared if it already",
-" existed. The ARRAY keyword is optional. Synonym: [ ARRAY ] DCL.",
-" ",
-"[ ARRAY ] UNDECLARE arrayname",
-" Destroys and undeclares the given array. Synonym: ARRAY DESTROY.",
-" ",
-"ARRAY SHOW [ arrayname ]",
-" Displays the contents of the given array. A range specifier can be",
-" included to display a segment of the array, e.g. \"array show \\&a[1:24].\""
-,
-" If the arrayname is omitted, all declared arrays are listed, but their",
-" contents is not shown. Synonym: SHOW ARRAY.",
-" ",
-"ARRAY CLEAR arrayname",
-" Clears all elements of the array, i.e. sets them to empty values.",
-" You may include a range specifier to clear a segment of the array rather",
-" than the whole array, e.g. \"array clear \\%a[22:38]\"",
-" ",
-"ARRAY SET arrayname value",
-" Sets all elements of the array to the given value. You may specify a",
-" range to set a segment of the array, e.g. \"array set \\%a[2:9] 0\"",
-" ",
-"ARRAY RESIZE arrayname number",
-" Changes the size of the given array, which must already exist, to the",
-" number given. If the number is smaller than the current size, the extra",
-" elements are discarded; if it is larger, new empty elements are added.",
-" ",
-"ARRAY COPY array1 array2",
-" Copys array1 to array2. If array2 has not been declared, it is created",
-" automatically. Range specifiers may be given on one or both arrays.",
-" ",
-"ARRAY LINK array1 arra2",
-" Makes array1 a link to array2.",
-" ",
-"[ ARRAY ] SORT [ switches ] array-name [ array2 ]",
-" Sorts the given array lexically according to the switches. Element 0 of",
-" the array is excluded from sorting by default. The ARRAY keyword is",
-" optional. If a second array name is given, that array is sorted according",
-" to the first one. Switches:",
-" ",
-" /CASE:{ON,OFF}",
-" If ON, alphabetic case matters; if OFF it is ignored. If this switch is",
-" omitted, the current SET CASE setting applies.",
-" ",
-" /KEY:number",
-" \
-Position (1-based column number) at which comparisons begin, 1 by default.",
-" ",
-" /NUMERIC",
-" Specifies a numeric rather than lexical sort.",
-" ",
-" /RANGE:low[:high]",
-" The range of elements, low through high, to be sorted. If this switch",
-" is not given, elements 1 through the dimensioned size are sorted. If",
-" :high is omitted, the dimensioned size is used. To include element 0 in",
-" a sort, use /RANGE:0 (to sort the whole array) or /RANGE:0:n (to sort",
-" elements 0 through n). You can use a range specifier in the array name",
-" instead of the /RANGE switch.",
-" ",
-" /REVERSE",
-" Sort in reverse order. If this switch is not given, the array is sorted",
-" in ascending order.",
-" ",
-"Various functions are available for array operations; see HELP FUNCTION for",
-"details. These include \\fdimension(), \\farraylook(), \\ffiles(), \
-\\fsplit(),",
-"and many more.",
-""};
-#endif /* NOSPL */
-
-#ifdef ZCOPY
-static char * hmxxcpy[] = {
-"Syntax: COPY [ switches ] file1 file2",
-" Copies the source file (file1) to the destination file (file2). If file2",
-" is a directory, file1 can contain wildcards to denote a group of files to",
-" be copied to the given directory. Switches:",
-" ",
-" /LIST",
-" Print the filenames and status while copying. Synonyms: /LOG, /VERBOSE",
-" ",
-" /NOLIST",
-" Copy silently (default). Synonyms: /NOLOG, /QUIET",
-" ",
-" /SWAP-BYTES",
-" Swap bytes while copying.",
-#ifndef NOSPL
-" ",
-" /FROMB64",
-" Convert from Base64 encoding while copying.",
-" ",
-" /TOB64",
-" Convert to Base64 encoding while copying.",
-#endif /* NOSPL */
-""
-};
-#endif /* ZCOPY */
-
-#ifndef NOFRILLS
-static char * hmxxren[] = {
-#ifdef LOCUS
-" If LOCUS is REMOTE or LOCUS is AUTO and you have an FTP connection,",
-" this command is equivalent to REMOTE RENAME (RREN). Otherwise:",
-" ",
-#endif /* LOCUS */
-"Syntax: RENAME [ switches ] name1 name2",
-" Renames the source file (name1) to the target name2. If name2 is a",
-" directory, name1 is allowed to contain wildcards, and the file(s) matching",
-" name1 are moved to directory name2, subject to rules of the underlying",
-" operating system regarding renaming across disk boundaries, etc. If name2",
-" is not a directory, name1 may not include wildcards, and the file whose",
-" name is name1 is renamed to name2. Switches:",
-" ",
-" /LIST",
-" Print the filenames and status while renaming. Synonyms: /LOG, /VERBOSE",
-" ",
-" /NOLIST",
-" Rename silently (default). Synonyms: /NOLOG, /QUIET",
-""
-};
-#endif /* NOFRILLS */
-
-static char *
-cmdlhlp[] = {
-"Command-line options are given after the program name in the system",
-"command that you use to start Kermit. Example:",
-" ",
-" kermit -i -s oofa.exe",
-" ",
-"tells Kermit to send (-s) the file oofa.exe in binary (-i) mode.",
-" ",
-"Command-line options are case-sensitive; \"-s\" is different from \"-S\".",
-#ifdef VMS
-"In VMS, uppercase options must be enclosed in doublequotes: ",
-" ",
-" $ kermit \"-Y\" \"-S\" -s oofa.txt ",
-#endif /* VMS */
-" ",
-"If any \"action options\" are included on the command line, Kermit exits",
-"after executing its command-line options. If -S is included, or no action",
-"options were given, Kermit enters its interactive command parser and",
-"issues its prompt.",
-" ",
-"Command-line options are single characters preceded by dash (-). Some",
-"require an \"argument,\" others do not. If an argument contains spaces, it",
-"must be enclosed in doublequotes:",
-" ",
-" kermit -s \"filename with spaces\"",
-" ",
-"\
-An option that does not require an argument can be bundled with other options:"
-,
-" ",
-" kermit -Qis oofa.exe",
-" ",
-"Exceptions to the rules:",
-" ",
-" . If the first command-line option is a filename, Kermit executes commands",
-" from the file. Additional command-line options can follow the filename.",
-" ",
-" . The special option \"=\" (equal sign) or \"--\" (double hyphen) means to",
-" treat the rest of the command line as data, rather than commands; this",
-" data is placed in the argument vector array, \\&@[], along with the other",
-" items on the command line, and also in the top-level \\%1..\\%9 variables."
-,
-" ",
-#ifdef KERBANG
-" . A similar option \"+\" (plus sign) means: the name of a Kermit script",
-" file follows. This file is to be executed, and its name assigned to \\%0",
-" and \\&_[0]. All subsequent command-line arguments are to be ignored by",
-" Kermit but made available to the script as \\%1, \\%2, ..., as well as",
-" in the argument-vector arrays. The initialization file is not executed",
-" automatically in this case.",
-" ",
-#endif /* KERBANG */
-" . The -s option can accept multiple filenames, separated by spaces.",
-" ",
-" . the -j and -J options allow an optional second argument, the TCP port",
-" name or number.",
-" ",
-"Type \"help options all\" to list all the command-line options.",
-"Type \"help option x\" to see the help message for option x.",
-" ",
-"Kermit also offers a selection of \"extended command-line\" options.",
-"These begin with two dashes, followed by a keyword, and then, if the option",
-"has arguments, a colon (:) or equal sign (=) followed by the argument.",
-"Unlike single-letter options, extended option keywords aren't case sensitive",
-"and they can be abbreviated to any length that still distinguishes them from",
-"other extended-option keywords. Example:",
-" ",
-" kermit --banner:oofa.txt",
-" ",
-"which designates the file oofa.txt to be printed upon startup, rather than",
-"the built-in banner (greeting) text. To obtain a list of available",
-"extended options, type \"help extended-options ?\". To get help about all",
-"extended options, type \"help extended-options\". To get help about a",
-"particular extended option, type \"help extended-option xxx\", where \"xxx\"",
-"is the option keyword.",
-#ifdef COMMENT
-#ifndef NOIKSD
-" ",
-"At present, most of the extended options apply only to the Internet Kermit",
-"Service Daemon (IKSD). Type \"help iksd\" for details.",
-#endif /* NOIKSD */
-#endif /* COMMENT */
-""
-};
-
-#ifndef NOHELP
-#ifndef NOCMDL
-int
-doxopts() {
- extern char * xopthlp[], * xarghlp[];
- extern struct keytab xargtab[];
- extern int nxargs;
- int i, x, y, n = 0;
-#ifdef CK_TTGWSIZ
-#ifdef OS2
- ttgcwsz();
-#else /* OS2 */
- /* Check whether window size changed */
- if (ttgwsiz() > 0) {
- if (tt_rows > 0 && tt_cols > 0) {
- cmd_rows = tt_rows;
- cmd_cols = tt_cols;
- }
- }
-#endif /* OS2 */
-#endif /* CK_TTGWSIZ */
- y = cmkey(xargtab,
- nxargs,
- "Extended argument without the \"--\" prefix",
- "",
- xxstring
- );
- if (y == -3) {
- printf("\n");
- if ((x = cmcfm()) < 0)
- return(x);
- for (i = 0; i <= XA_MAX; i++) {
- if (xopthlp[i]) {
- printf("%s\n",xopthlp[i]);
- printf(" %s\n",xarghlp[i]);
- printf("\n");
- n += 3;
- if (n > (cmd_rows - 6)) {
- if (!askmore())
- return(0);
- else
- n = 0;
- }
- }
- }
- return(1);
- } else if (y < 0)
- return(y);
- if ((x = cmcfm()) < 0)
- return(x);
- printf("\n%s\n",xopthlp[y]);
- printf(" %s\n\n",xarghlp[y]);
- return(1);
-}
-
-int
-dohopts() {
- int i, n, x, y, z, all = 0, msg = 0;
- char *s;
- extern char *opthlp[], *arghlp[];
- extern char * xopthlp[], * xarghlp[];
- extern int optact[];
- if ((x = cmtxt("A command-line option character,\n\
-or the word ALL, or carriage return for an overview",
- "", &s, xxstring)) < 0)
- return(x);
- if (!*s)
- msg = 1;
- else if (!strcmp(s,"all") || (!strcmp(s,"ALL")))
- all = 1;
- else if (*s == '-') /* Be tolerant of leading hyphen */
- s++;
- if (!all && (int)strlen(s) > 1) {
- printf("?A single character, please, or carriage to list them all.\n");
- return(-9);
- }
- if (all) {
- y = 33;
- z = 127;
- } else {
- y = *s;
- z = (y == 0) ? 127 : y;
- if (y == 0) y = 33;
- }
-#ifdef CK_TTGWSIZ
-#ifdef OS2
- ttgcwsz();
-#else /* OS2 */
- /* Check whether window size changed */
- if (ttgwsiz() > 0) {
- if (tt_rows > 0 && tt_cols > 0) {
- cmd_rows = tt_rows;
- cmd_cols = tt_cols;
- }
- }
-#endif /* OS2 */
-#endif /* CK_TTGWSIZ */
- printf("\n");
- for (i = 0, n = 1; msg != 0 && *cmdlhlp[i]; i++) {
- printf("%s\n",cmdlhlp[i]);
- if (++n > (cmd_rows - 3)) {
- if (!askmore())
- return(0);
- else
- n = 0;
- }
- }
- if (all) {
- printf("The following command-line options are available:\n\n");
- n += 2;
- }
- for (i = y; msg == 0 && i <= z; i++) {
- if (!opthlp[i])
- continue;
- if (arghlp[i]) { /* Option with arg */
- printf(" -%c <arg>%s\n",(char)i,(optact[i]?" (action option)":""));
-
- printf(" %s\n",opthlp[i]);
- printf(" Argument: %s\n\n",arghlp[i]);
- x = 4;
- } else { /* Option without arg */
- printf(" -%c %s%s\n",
- (char)i, opthlp[i],
- (optact[i]?" (action option)":"")
- );
- printf(" Argument: (none)\n\n");
- x = 3;
- }
- n += x;
- if (n > (cmd_rows - x - 1)) {
- if (!askmore())
- return(0);
- else
- n = 0;
- }
- }
- if (all) { /* Jeff, Jan 2003 */
- printf("\n");
- if (++n >= cmd_rows) {
- if (!askmore())
- return(0);
- else
- n = 0;
- }
- printf("The following extended options are available:\n");
- if (++n >= cmd_rows) {
- if (!askmore())
- return(0);
- else
- n = 0;
- }
- printf("\n");
- if (++n >= cmd_rows) {
- if (!askmore())
- return(0);
- else
- n = 0;
- }
- for (i = 0; i <= XA_MAX; i++) {
- if (xopthlp[i]) {
- printf("%s\n",xopthlp[i]);
- printf(" %s\n",xarghlp[i]);
- printf("\n");
- n += 3;
- if (n > (cmd_rows - 4)) {
- if (!askmore())
- return(0);
- else
- n = 0;
- }
- }
- }
- }
- return(1);
-}
-#endif /* NOCMDL */
-#endif /* NOHELP */
-
-#ifdef CKCHANNELIO
-static char * hxxfile[] = {
-"Syntax: FILE <subcommand> [ switches ] <channel> [ <data> ]",
-" Opens, closes, reads, writes, and manages local files.",
-" ",
-"The FILE commands are:",
-" ",
-" FILE OPEN (or FOPEN) -- Open a local file.",
-" FILE CLOSE (or FCLOSE) -- Close an open file.",
-" FILE READ (or FREAD) -- Read data from an open file.",
-" FILE WRITE (or FWRITE) -- Write data to an open file.",
-" FILE LIST (or FLIST) -- List open files.",
-" FILE STATUS (or FSTATUS) -- Show status of a channel.",
-" FILE REWIND (or FREWIND) -- Rewind an open file",
-" FILE COUNT (or FCOUNT) -- Count lines or bytes in an open file",
-" FILE SEEK (or FSEEK) -- Seek to specified spot in an open file.",
-" FILE FLUSH (or FFLUSH) -- Flush output buffers for an open file.",
-" ",
-"Type HELP FILE OPEN or HELP FOPEN for details about FILE OPEN;",
-"type HELP FILE CLOSE or HELP FCLOSE for details about FILE CLOSE, and so on.",
-" ",
-"The following variables are related to the FILE command:",
-" ",
-" \\v(f_max) -- Maximum number of files that can be open at once",
-" \\v(f_error) -- Completion code of most recent FILE command or function",
-" \\v(f_count) -- Result of most recent FILE COUNT command",
-" ",
-"The following functions are related to the FILE command:",
-" ",
-" \\F_eof() -- Check if channel is at EOF",
-" \\F_pos() -- Get channel read/write position (byte number)",
-" \\F_line() -- Get channel read/write position (line number)",
-" \\F_handle() -- Get file handle",
-" \\F_status() -- Get channel status",
-" \\F_getchar() -- Read character",
-" \\F_getline() -- Read line",
-" \\F_getblock() -- Read block",
-" \\F_putchar() -- Write character",
-" \\F_putline() -- Write line",
-" \\F_putblock() -- Write block",
-" \\F_errmsg() -- Error message from most recent FILE command or function",
-" ",
-"Type HELP <function-name> for information about each one.",
-""
-};
-
-static char * hxxf_op[] = {
-"Syntax: FILE OPEN [ switches ] <variable> <filename>",
-" Opens the file indicated by <filename> in the mode indicated by the",
-" switches, if any, or if no switches are included, in read-only mode, and",
-" assigns a channel number for the file to the given variable.",
-" Synonym: FOPEN. Switches:",
-" ",
-"/READ",
-" Open the file for reading.",
-" ",
-"/WRITE",
-" Open the file for writing. If /READ was not also specified, this creates",
-" a new file. If /READ was specifed, the existing file is preserved, but",
-" writing is allowed. In both cases, the read/write pointer is initially",
-" at the beginning of the file.",
-" ",
-"/APPEND",
-" If the file does not exist, create a new file and open it for writing.",
-" If the file exists, open it for writing, but with the write pointer",
-" positioned at the end.",
-" ",
-"/BINARY",
-#ifdef VMS
-" Opens the file in binary mode to inhibit end-of-line conversions.",
-#else
-#ifdef OS2
-" Opens the file in binary mode to inhibit end-of-line conversions.",
-#else
-#ifdef UNIX
-" This option is ignored in UNIX.",
-#else
-" This option is ignored on this platform.",
-#endif /* UNIX */
-#endif /* OS2 */
-#endif /* VMS */
-" ",
-"Switches can be combined in an way that makes sense and is supported by the",
-"underlying operating system.",
-""
-};
-
-static char * hxxf_cl[] = {
-"Syntax: FILE CLOSE <channel>",
-" Closes the file on the given channel if it was open.",
-" Also see HELP FILE OPEN. Synonym: FCLOSE.",
-""
-};
-
-static char * hxxf_fl[] = {
-"Syntax: FILE FLUSH <channel>",
-" Flushes output buffers on the given channel if it was open, forcing",
-" all material previously written to be committed to disk. Synonym: FFLUSH.",
-" Also available as \\F_flush().",
-""
-};
-
-static char * hxxf_li[] = {
-"Syntax: FILE LIST",
-" Lists the channel number, name, modes, and position of each file opened",
-" with FILE OPEN. Synonym: FLIST.",
-""
-};
-
-static char * hxxf_re[] = {
-"Syntax: FILE READ [ switches ] <channel> [ <variable> ]",
-" Reads data from the file on the given channel number into the <variable>,",
-" if one was given; if no variable was given, the result is printed on",
-" the screen. The variable should be a macro name rather than a \\%x",
-" variable or array element if you want backslash characters in the file to",
-" be taken literally. Synonym: FREAD. Switches:",
-" ",
-"/LINE",
-" Specifies that a line of text is to be read. A line is defined according",
-" to the underlying operating system's text-file format. For example, in",
-" UNIX a line is a sequence of characters up to and including a linefeed.",
-" The line terminator (if any) is removed before assigning the text to the",
-" variable. If no switches are included with the FILE READ command, /LINE",
-" is assumed.",
-" ",
-"/SIZE:number",
-" Specifies that the given number of bytes (characters) is to be read.",
-" This gives a semblance of \"record i/o\" for files that do not necessarily",
-" contain lines. The resulting block of characters is assigned to the",
-" variable without any editing.",
-" ",
-"/CHARACTER",
-" Equivalent to /SIZE:1. If FILE READ /CHAR succeeds but the <variable> is",
-" empty, this indicates a NUL byte was read.",
-" ",
-"/TRIM",
-" Tells Kermit to trim trailing whitespace when used with /LINE. Ignored",
-" if used with /CHAR or /SIZE.",
-" ",
-"/UNTABIFY",
-" Tells Kermit to convert tabs to spaces (assuming tabs set every 8 spaces)",
-" when used with /LINE. Ignored if used with /CHAR or /SIZE.",
-" ",
-"Synonym: FREAD.",
-"Also available as \\F_getchar(), \\F_getline(), \\F_getblock().",
-""
-};
-
-static char * hxxf_rw[] = {
-"Syntax: FILE REWIND <channel>",
-" If the channel is open, moves the read/write pointer to the beginning of",
-" the file. Equivalent to FILE SEEK <channel> 0. Synonym: FREWIND.",
-" Also available as \\F_rewind().",
-""
-};
-
-static char * hxxf_se[] = {
-"Syntax: FILE SEEK [ switches ] <channel> { [{+,-}]<number>, EOF }",
-" Switches are /BYTE, /LINE, /RELATIVE, ABSOLUTE.",
-" Moves the file pointer for this file to the given position in the",
-" file. Subsequent FILE READs or WRITEs will take place at that position.",
-" If neither the /RELATIVE nor /ABSOLUTE switch is given, an unsigned",
-" <number> is absolute; a signed number is relative. EOF means to move to",
-" the end of the file. Synonym: FSEEK. Also available as \\F_seek().",
-""
-};
-
-static char * hxxf_st[] = {
-"Syntax: FILE STATUS <channel>",
-" If the channel is open, this command shows the name of the file, the",
-" switches it was opened with, and the current read/write position.",
-" Synonym: FSTATUS",
-""
-};
-
-static char * hxxf_co[] = {
-"Syntax: FILE COUNT [ { /BYTES, /LINES, /LIST, /NOLIST } ] <channel>",
-" If the channel is open, this command prints the nubmer of bytes (default)",
-" or lines in the file if at top level or if /LIST is included; if /NOLIST",
-" is given, the result is not printed. In all cases the result is assigned",
-" to \\v(f_count). Synonym: FCOUNT",
-""
-};
-
-static char * hxxf_wr[] = {
-"FILE WRITE [ switches ] <channel> <text>",
-" Writes the given text to the file on the given channel number. The <text>",
-" can be literal text or a variable, or any combination. If the text might",
-" contain leading or trailing spaces, it must be enclosed in braces if you",
-" want to preserve them. Synonym: FWRITE. Switches:",
-" ",
-"/LINE",
-" Specifies that an appropriate line terminator is to be added to the",
-" end of the <text>. If no switches are included, /LINE is assumed.",
-" ",
-"/SIZE:number",
-" Specifies that the given number of bytes (characters) is to be written.",
-" If the given <text> is longer than the requested size, it is truncated;",
-" if is shorter, it is padded according /LPAD and /RPAD switches. Synonym:",
-" /BLOCK.",
-" ",
-"/LPAD[:value]",
-" If /SIZE was given, but the <text> is shorter than the requested size,",
-" the text is padded on the left with sufficient copies of the character",
-" whose ASCII value is given to write the given length. If no value is",
-" specified, 32 (the code for Space) is used. The value can also be 0 to",
-" write the indicated number of NUL bytes. If /SIZE was not given, this",
-" switch is ignored.",
-" ",
-"/RPAD[:value]",
-" Like LPAD, but pads on the right.",
-" ",
-"/STRING",
-" Specifies that the <text> is to be written as-is, with no terminator added."
-,
-" ",
-"/CHARACTER",
-" Specifies that one character should be written. If the <text> is empty or",
-" not given, a NUL character is written; otherwise the first character of",
-" <text> is given.",
-" ",
-"Synonym FWRITE.",
-"Also available as \\F_putchar(), \\F_putline(), \\F_putblock().",
-""
-};
-
-static int
-dohfile(cx) int cx; {
- extern struct keytab fctab[];
- extern int nfctab;
- int x;
- if (cx == XXFILE) { /* FILE command was given */
- /* Get subcommand */
- if ((cx = cmkey(fctab,nfctab,"Operation","",xxstring)) < 0) {
- if (cx == -3) {
- if ((x = cmcfm()) < 0)
- return(x);
- cx = XXFILE;
- } else
- return(cx);
- }
- if ((x = cmcfm()) < 0)
- return(x);
- switch (cx) {
- case FIL_CLS: cx = XXF_CL; break;
- case FIL_FLU: cx = XXF_FL; break;
- case FIL_LIS: cx = XXF_LI; break;
- case FIL_OPN: cx = XXF_OP; break;
- case FIL_REA: cx = XXF_RE; break;
- case FIL_REW: cx = XXF_RW; break;
- case FIL_SEE: cx = XXF_SE; break;
- case FIL_STA: cx = XXF_ST; break;
- case FIL_WRI: cx = XXF_WR; break;
- case FIL_COU: cx = XXF_CO; break;
- }
- }
- switch (cx) {
- case XXFILE: return(hmsga(hxxfile));
- case XXF_CL: return(hmsga(hxxf_cl));
- case XXF_FL: return(hmsga(hxxf_fl));
- case XXF_LI: return(hmsga(hxxf_li));
- case XXF_OP: return(hmsga(hxxf_op));
- case XXF_RE: return(hmsga(hxxf_re));
- case XXF_RW: return(hmsga(hxxf_rw));
- case XXF_SE: return(hmsga(hxxf_se));
- case XXF_ST: return(hmsga(hxxf_st));
- case XXF_WR: return(hmsga(hxxf_wr));
- case XXF_CO: return(hmsga(hxxf_co));
- default:
- return(-2);
- }
-}
-#endif /* CKCHANNELIO */
-
-int
-dohlp(xx) int xx; {
- int x,y;
-
- debug(F101,"DOHELP xx","",xx);
- if (xx < 0) return(xx);
-
-#ifdef NOHELP
- if ((x = cmcfm()) < 0)
- return(x);
- printf("\n%s, Copyright (C) 1985, 2004,",versio);
-#ifndef NOIKSD
- if (inserver)
- return(hmsga(tophlpi));
- else
-#endif /* IKSD */
- return(hmsga(tophlp));
-
-#else /* help is available */
-
- if (helpfile)
- return(dotype(helpfile,xaskmore,0,0,NULL,0,NULL,0,0,NULL,0));
-
-#ifdef CKCHANNELIO
- if (xx == XXFILE)
- return(dohfile(xx));
- else if (xx == XXF_RE || xx == XXF_WR || xx == XXF_OP ||
- xx == XXF_CL || xx == XXF_SE || xx == XXF_RW ||
- xx == XXF_FL || xx == XXF_LI || xx == XXF_ST || xx == XXF_CO)
- return(dohfile(xx));
-#endif /* CKCHANNELIO */
-
- switch (xx) {
-
-#ifndef NOSPL
-case XXASS: /* ASSIGN */
- return(hmsga(hxxass));
-
-case XXASK: /* ASK */
-case XXASKQ: /* ASKQ */
- return(hmsga(hxxask));
-
-case XXAPC:
- return(hmsg("Syntax: APC text\n\
- Echoes the text within a VT220/320/420 Application Program Command."));
-#endif /* NOSPL */
-
-#ifndef NOFRILLS
-case XXBUG:
- return(hmsg("Describes how to get technical support."));
-#endif /* NOFRILLS */
-
-#ifndef NOSPL
-case XXBEEP:
-#ifdef OS2
- return(hmsg("Syntax: BEEP [ { ERROR, INFORMATION, WARNING } ]\n\
- Generates a bell according to the current settings. If SET BELL is set to\n\
- \"system-sounds\" then the appropriate System Sound will be generated.\n\
- Default is INFORMATION."));
-#else /* OS2 */
- return(hmsg("Syntax: BEEP\n\
-Sends a BEL character to your terminal."));
-#endif /* OS2 */
-#endif /* NOSPL */
-
-case XXBYE: /* BYE */
- return(hmsg(hmxxbye));
-
-case XXCHK: /* check */
- return(hmsg("\
-Syntax: CHECK name\n\
- Checks\
- to see if the named feature is included in this version of Kermit.\n\
- To list the features you can check, type \"check ?\"."));
-
-#ifndef NOFRILLS
-case XXCLE: /* clear */
- return(hmsga(hmxxcle));
-#endif /* NOFRILLS */
-
-case XXCLO: /* close */
- return(hmsga(hmxxclo));
-
-case XXCOM: /* comment */
-#ifndef STRATUS /* Can't use # for comments in Stratus VOS */
- return(hmsg("\
-Syntax: COMMENT text\n\
-Example: COMMENT - this is a comment.\n\
- Introduces a comment. Beginning of command line only. Commands may also\n\
- have trailing comments, introduced by ; or #."));
-#else
- return(hmsg("\
-Syntax: COMMENT text\n\
-Example: COMMENT - this is a comment.\n\
- Introduces a comment. Beginning of command line only. Commands may also\n\
- have trailing comments, introduced by ; (semicolon)."));
-#endif /* STRATUS */
-
-#ifndef NOLOCAL
-case XXCON: /* CONNECT */
-case XXCQ: /* CQ == CONNECT /QUIETLY */
- hmsga(hmxxcon);
- printf("Your escape character is Ctrl-%c (ASCII %d, %s)\r\n",
- ctl(escape), escape, (escape == 127 ? "DEL" : ccntab[escape]));
- return(0);
-#endif /* NOLOCAL */
-
-#ifdef ZCOPY
-case XXCPY:
- return(hmsga(hmxxcpy));
-#endif /* ZCOPY */
-
-#ifdef NT
-case XXLINK:
-return(hmsg(
-" LINK source destination\n\
- creates a hard link to the file specified by source to the filename\n\
- specified by destination. Hard links are only supported on NTFS.\n\
- destination can either be a filename or a directory. source may\n\
- contain wildcards if destination is a directory."));
-#endif /* NT */
-
-#ifndef NOFRILLS
-case XXLREN: /* LRENAME */
- return(hmsg(
-" LRENAME is an alias for the RENAME command forcing it to execute\n\
- on the local computer. Also see: RENAME, RRENAME, SET LOCUS."));
-
-case XXREN:
- return(hmsga(hmxxren));
-#endif /* NOFRILLS */
-
-case XXCDUP: /* CDUP */
-case XXLCDU:
- return(hmsg(
-"Change working directory to the one just above the current one."));
-
-case XXLCWD:
- return(hmsg(
-" LCD (LCWD) is an alias for the CD (CWD) command forcing it to execute\n\
- on the local computer. Also see: CD, CDUP, RCD, SET LOCUS."));
-
-case XXCWD: /* CD / CWD */
- return(hmsga(hmxxcwd));
-
-#ifndef NOSPL
-case XXKCD:
- return(hmsga(hmxxkcd));
-
-case XXARRAY:
-case XXDCL: /* DECLARE */
-case XXSORT:
- return(hmsga(hxxdcl));
-
-case XXDEF: /* DEFINE */
-#ifndef NOSPL
- if (hlptok) /* What they actually typed... */
- if (hlptok[0] == '.')
- return(hmsga(hxxdot));
-#endif /* NOSPL */
- return(hmsga(hxxdef));
-
-case XXUNDEF: /* UNDEFINE */
- return(hmsg("Syntax: UNDEFINE variable-name\n\
- Undefines a macro or variable."));
-#endif /* NOSPL */
-
-#ifndef NOFRILLS
-case XXLDEL:
- return(hmsg(
-" LDELETE is an alias for the DELETE command forcing it to execute\n\
- on the local computer. Also see: DELETE, RDELETE, SET LOCUS."));
-
-case XXDEL: /* delete */
- return(hmsga(hmxxdel));
-#endif /* NOFRILLS */
-
-#ifndef NODIAL
-case XXDIAL: /* DIAL, etc... */
- return(hmsga(hxxdial));
-
-case XXPDIA: /* PDIAL */
- return(hmsg("Syntax: PDIAL phonenumber\n\
- Partially dials a phone number. Like DIAL but does not wait for carrier\n\
- or CONNECT message."));
-
-case XXRED:
- return(hmsg("Redial the number given in the most recent DIAL commnd."));
-
-case XXANSW: /* ANSWER */
- return(hmsga(hxxansw));
-
-case XXLOOK: /* LOOKUP number in directory */
- return(hmsga(hxxlook));
-#endif /* NODIAL */
-
-case XXLDIR: /* LDIRECTORY */
- return(hmsg(
-" LDIRIRECTORY is an alias for the DIRECTORY command forcing it to execute\n\
- on the local computer. Also see: DIRECTORY, SET LOCUS, RDIRECTORY."));
-
-case XXDIR: /* DIRECTORY */
- return(hmsga(hmxxdir));
-
-case XXLMKD: /* LMKDIR */
- return(hmsg(
-" LMKDIR is an alias for the MKDIR command forcing it to execute\n\
- on the local computer. Also see: MKDIR, RMKDIR, SET LOCUS."));
-
-case XXMKDIR: /* MKDIR */
- return(hmsg("Creates a directory. Also see LRMDIR, RRMDIR, SET LOCUS."));
-
-case XXLRMD: /* LRMDIR */
- return(hmsg(
-" LRMDIR is an alias for the RMDIR command forcing it to execute\n\
- on the local computer. Also see: RMDIR, RRMDIR, SET LOCUS."));
-
-case XXRMDIR: /* RMDIR */
- return(hmsg("Removes a directory. Also see LRMDIR, RRMDIR, SET LOCUS."));
-
-case XXLS:
-#ifdef UNIXOROSK
- return(hmsg("Syntax: LS [ args ]\n\
- Runs \"ls\" with the given arguments."));
-#else
- return(hmsga(hmxxdir));
-#endif /* UNIXOROSK */
-
-#ifndef NOSERVER
-#ifndef NOFRILLS
-case XXDIS:
- return(hmsg("Syntax: DISABLE command\n\
- Security for the Kermit server. Prevents the client Kermit program from\n\
- executing the named REMOTE command, such as CD, DELETE, RECEIVE, etc."));
-#endif /* NOFRILLS */
-#endif /* NOSERVER */
-
-#ifndef NOSPL
-case XXDO: /* do */
- return(hmsg("Syntax: [ DO ] macroname [ arguments ]\n\
- Executes a macro that was defined with the DEFINE command. The word DO\n\
- can be omitted. Trailing argument words, if any, are automatically\n\
- assigned to the macro argument variables \\%1 through \\%9."));
-#endif /* NOSPL */
-
-#ifndef NOSPL
-case XXDEC:
- return(hmsga(hxxdec));
-#endif /* NOSPL */
-
-case XXECH: /* echo */
- return(hmsg("Syntax: ECHO text\n\
- Displays the text on the screen, followed by a line terminator. The ECHO\n\
- text may contain backslash codes. Example: ECHO \\7Wake up!\\7. Also see\n\
- XECHO and WRITE SCREEN."));
-
-case XXXECH: /* xecho */
- return(hmsg("Syntax: XECHO text\n\
- Just like ECHO but does not add a line terminator to the text. See ECHO."));
-
-case XXVOID:
- return(hmsg("Syntax: VOID text\n\
- Like ECHO but doesn't print anything; can be used to invoke functions\n\
- when you don't need to display or use their results."));
-
-#ifndef NOSERVER
-#ifndef NOFRILLS
-case XXENA:
- return(hmsg("Syntax: ENABLE capability\n\
- For use with server mode. Allows the client Kermit program access to the\n\
- named capability, such as CD, DELETE, RECEIVE, etc. Opposite of DISABLE."));
-#endif /* NOFRILLS */
-#endif /* NOSERVER */
-
-#ifndef NOSPL
-case XXEND: /* end */
- return(hmsg("Syntax: END [ number [ message ] ]\n\
- Exits from the current macro or TAKE file, back to wherever invoked from.\n\
- Number is return code. Message, if given, is printed."));
-
-case XXEVAL: /* evaluate */
- return(hmsga(hmxxeval));
-#endif /* NOSPL */
-
-#ifndef NOFRILLS
-case XXERR: /* e-packet */
- return(hmsg("Syntax: E-PACKET\n\
- Sends an Error packet to the other Kermit."));
-#endif /* NOFRILLS */
-
-case XXEXI: /* exit */
-case XXQUI:
- return(hmsga(hmxxexit));
-
-case XXFIN:
- return(hmsg("Syntax: FINISH\n\
- Tells the remote Kermit server to shut down without logging out."));
-
-#ifndef NOSPL
- case XXFOR:
- return(hmsga(forhlp));
-#endif /* NOSPL */
-
- case XXGET:
- return(hmsga(hmxxget));
- case XXMGET:
- return(hmsga(hmxxmget));
-
-#ifndef NOSPL
-#ifndef NOFRILLS
- case XXGOK:
- return(hmsg("Syntax: GETOK [ switches ] prompt\n\
- Prints the prompt, makes user type 'yes', 'no', or 'ok', and sets SUCCESS\n\
- or FAILURE accordingly. The optional switches are the same as for ASK."));
-#endif /* NOFRILLS */
-#endif /* NOSPL */
-
-#ifndef NOSPL
- case XXGOTO:
- return(hmsg("Syntax: GOTO label\n\
- In a TAKE file or macro, go to the given label. A label is a word on the\n\
- left margin that starts with a colon (:). Example:\n\n\
- :oofa\n\
- echo Hello!\n\
- goto oofa"));
-#endif /* NOSPL */
-
- case XXHAN:
- return(hmsg("Syntax: HANGUP\n\
-Hang up the phone or network connection."));
-
- case XXHLP:
-/*
- We get confirmation here, even though we do it again in hmsga(), to prevent
- the Copyright message from being printed prematurely. This doesn't do any
- harm, because the first call to cmcfm() sets cmflgs to 1, making the second
- call return immediately.
-*/
- if ((x = cmcfm()) < 0)
- return(x);
-
- if (helpfile) {
- printf("\n%s, Copyright (C) 1985, 2004,\n\
-Trustees of Columbia University in the City of New York.\n\n",versio);
- return(dotype(helpfile,xaskmore,3,0,NULL,0,NULL,0,0,NULL,0));
- } else {
- printf("\n%s, Copyright (C) 1985, 2004,",versio);
- return(hmsga(tophlp));
- }
-
-case XXINT:
-#ifdef OS2
- return(hmsg("Give a brief introduction to C-Kermit."));
-#else
- return(hmsg("Give a brief introduction to Kermit 95."));
-#endif /* OS2 */
-
-#ifndef NOSPL
-case XXIF:
- return(hmsga(ifhlp));
-
-case XXINC:
- return(hmsga(hxxinc));
-
-case XXINP:
- return(hmsga(hxxinp));
-#endif /* NOSPL */
-
-#ifdef CK_MINPUT
-case XXMINP:
- return(hmsga(hmxxminp));
-#endif /* CK_MINPUT */
-
-#ifndef NOSPL
-case XXREI:
- return(hmsg("Syntax: REINPUT n string\n\
- Looks for the string in the text that has recently been INPUT, set SUCCESS\n\
- or FAILURE accordingly. Timeout, n, must be specified but is ignored."));
-#endif /* NOSPL */
-
-#ifndef NOSPL
-case XXLBL:
- return(hmsg("\
- Introduces a label, like :loop, for use with GOTO in TAKE files or macros.\n\
-See GOTO."));
-#endif /* NOSPL */
-
-case XXLOG:
- return(hmsga(hmxxlg));
-
-#ifndef NOSCRIPT
-case XXLOGI:
- return(hmsga(hmxxlogi));
-#endif
-
-#ifndef NOFRILLS
-case XXMAI:
- return(hmsg("Syntax: MAIL filename address\n\
- Equivalent to SEND /MAIL:address filename."));
-#endif /* NOFRILLS */
-
-#ifndef NOMSEND
-case XXMSE:
- return(hmsga(hmxxmse));
-
-case XXADD:
- return(hmsga(hmxxadd));
-
-case XXMMOVE:
- return(hmsg("MMOVE is exactly like MSEND, except each file that is\n\
-sent successfully is deleted after it is sent."));
-#endif /* NOMSEND */
-
-#ifndef NOSPL
-case XXOPE:
- return(hmsga(openhlp));
-#endif /* NOSPL */
-
-case XXNEW:
- return(hmsg(
-" Prints news of new features since publication of \"Using C-Kermit\"."));
-
-case XXUPD:
- return(hmsg(
-" New features are described in the online Kermit 95 manual,\n\
- accessible via the MANUAL command."));
-
-#ifndef NOSPL
-case XXOUT:
- return(hmsga(hxxout));
-#endif /* NOSPL */
-
-#ifdef ANYX25
-#ifndef IBMX25
-case XXPAD:
- return(hmsga(hxxpad));
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-
-#ifndef NOSPL
-case XXPAU:
- return(hmsga(hxxpau));
-
-case XXMSL:
- return(hmsga(hxxmsl));
-#endif /* NOSPL */
-
-#ifdef TCPSOCKET
-case XXPNG:
- return(hmsg("Syntax: PING [ IP-hostname-or-number ]\n\
- Checks if the given IP network host is reachable. Default host is from\n\
- most recent SET HOST or TELNET command. Runs system PING program, if any.")
- );
-
-case XXFTP:
-#ifdef SYSFTP
- return(hmsg("Syntax: FTP [ IP-hostname-or-number ]\n\
- Makes an FTP connection to the given IP host or, if no host specified, to\n\
- the current host. Uses the system's FTP program, if any."));
-#else
-#ifndef NOFTP
- return(doftphlp());
-#endif /* NOFTP */
-#endif /* SYSFTP */
-#endif /* TCPSOCKET */
-
-#ifndef NOFRILLS
-case XXPRI:
-#ifdef UNIX
- return(hmsg("Syntax: PRINT file [ options ]\n\
- Prints the local file on a local printer with the given options. Also see\n\
- HELP SET PRINTER."));
-#else
-#ifdef VMS
- return(hmsg("Syntax: PRINT file [ options ]\n\
- Prints the local file on a local printer with the given options. Also see\n\
- HELP SET PRINTER."));
-#else
- return(hmsg("Syntax: PRINT file\n\
- Prints the local file on a local printer. Also see HELP SET PRINTER."));
-#endif /* UNIX */
-#endif /* VMS */
-#endif /* NOFRILLS */
-
-case XXPWD:
-case XXLPWD:
- return(hmsg("Syntax: PWD\n\
-Print the name of the current working directory."));
-
-#ifndef NOSPL
-case XXREA:
- return(hmsg("Syntax: READ variablename\n\
- Reads a line from the currently open READ or !READ file into the variable\n\
- (see OPEN)."));
-#endif /* NOSPL */
-
-#ifndef NOXFER
-case XXREC:
- return(hmsga(hmxxrc));
-
-case XXREM:
- y = cmkey(remcmd,nrmt,"Remote command","",xxstring);
- return(dohrmt(y));
-#endif /* NOXFER */
-
-#ifndef NOSPL
-case XXRET:
- return(hmsg("Syntax: RETURN [ value ]\n\
- Return from a macro. An optional return value can be given for use with\n\
- \\fexecute(macro), which allows macros to be used like functions."));
-#endif /* NOSPL */
-
-#ifndef NOXFER
-case XXSEN:
- return(hmsga(hmxxsen));
-case XXMOVE:
- return(hmsg("MOVE is exactly like SEND, except each file that is\n\
-sent successfully is deleted after it is sent."));
-#ifndef NORESEND
-case XXRSEN:
- return(hmsg(hmxxrsen));
-case XXREGET:
- return(hmsg(hmxxrget));
-case XXPSEN:
- return(hmsg(hmxxpsen));
-#endif /* NORESEND */
-
-#ifndef NOSERVER
-case XXSER:
- return(hmsg(hmxxser));
-#endif /* NOSERVER */
-#endif /* NOXFER */
-
-#ifndef NOJC
-case XXSUS:
- return(hmsg("Syntax: SUSPEND or Z\n\
- Suspends Kermit. Continue Kermit with the appropriate system command,\n\
- such as fg."));
-#endif /* NOJC */
-
-case XXSET:
- y = cmkey(prmtab,nprm,"Parameter","",xxstring);
- debug(F101,"HELP SET y","",y);
- return(dohset(y));
-
-#ifndef NOPUSH
-case XXSHE:
- if (nopush) {
- if ((x = cmcfm()) < 0) return(x);
- printf("Sorry, help not available for \"%s\"\n",cmdbuf);
- break;
- } else
- return(hmsga(hxxshe));
-#ifdef CK_REDIR
-case XXFUN:
- return(hmsg("Syntax: REDIRECT command\n\
- Runs the given local command with its standard input and output redirected\n\
- to the current SET LINE or SET HOST communications path.\n\
- Synonym: < (Left angle bracket)."));
-#endif /* CK_REDIR */
-
-#ifdef CK_REXX
-case XXREXX:
- return(hmsg("Syntax: REXX text\n\
- The text is a Rexx command to be executed. The \\v(rexx) variable is set\n\
- to the Rexx command's return value.\n\
- To execute a rexx program file, use: REXX call <filename>\n\
- Rexx programs may call Kermit functions by placing the Kermit command\n\
- in single quotes. For instance: 'set parity none'."));
-#endif /* CK_REXX */
-#endif /* NOPUSH */
-
-#ifndef NOSHOW
-case XXSHO:
- return(hmsg("\
- Display current values of various items (SET parameters, variables, etc).\n\
- Type SHOW ? for a list of categories."));
-#endif /* NOSHOW */
-
-case XXSPA:
-#ifdef datageneral
- return(hmsg("\
- Display disk usage in current device, directory,\n\
- or return space for a specified device, directory."));
-#else
- return(hmsg("Syntax: SPACE\n\
- Display disk usage in current device and/or directory"));
-#endif
-
-case XXSTA:
- return(hmsg("Syntax: STATISTICS [/BRIEF]\n\
- Display statistics about most recent file transfer"));
-
-#ifndef NOSPL
-case XXSTO:
- return(hmsg("Syntax: STOP [ number [ message ] ]\n\
- Stop executing the current macro or TAKE file and return immediately to\n\
- the Kermit prompt. Number is a return code. Message printed if given."));
-#endif /* NOSPL */
-
-case XXTAK:
- return(hmsga(hmxxtak));
-
-#ifdef TCPSOCKET
-#ifdef TNCODE
-case XXIKSD:
- return(hmsga(hmxxiks));
-
-case XXTEL:
- return(hmsga(hmxxtel));
-
-case XXTELOP:
- return(hmsga(hxtopt));
-#endif /* TNCODE */
-
-#ifdef RLOGCODE
-case XXRLOG:
- return(hmsg("Syntax: RLOGIN [ switches ] [ host [ username ] ]\n\
- Equivalent to SET NETWORK TYPE TCP/IP, SET HOST host [ service ] /RLOGIN,\n\
- IF SUCCESS CONNECT. If host is omitted, the previous connection (if any)\n\
- is resumed. Depending on how Kermit has been built switches may be\n\
- available to require Kerberos authentication and DES encryption."));
-#endif /* RLOGCODE */
-#endif /* TCPSOCKET */
-
-#ifndef NOXMIT
-case XXTRA:
- return(hmsga(hxxxmit));
-#endif /* NOXMIT */
-
-#ifndef NOFRILLS
-case XXTYP:
- return(hmsga(hmxxtyp));
-case XXMORE:
- return(hmsg("Syntax: MORE [ switches ] filename\n\
- Equivalent to TYPE /PAGE filename; see HELP TYPE."));
-case XXCAT:
- return(hmsg("Syntax: MORE [ switches ] filename\n\
- Equivalent to TYPE /NOPAGE filename; see HELP TYPE."));
-case XXHEAD:
- return(hmsg("Syntax: HEAD [ switches ] filename\n\
- Equivalent to TYPE /HEAD filename; see HELP TYPE."));
-case XXTAIL:
- return(hmsg("Syntax: TAIL [ switches ] filename\n\
- Equivalent to TYPE /TAIL filename; see HELP TYPE."));
-#endif /* NOFRILLS */
-
-#ifndef NOSPL
-case XXWHI:
- return(hmsga(whihlp));
-
-case XXSWIT:
- return(hmsga(swihlp));
-#endif /* NOSPL */
-
-#ifndef NOCSETS
-case XXXLA:
- return(hmsga(hxxxla));
-#endif /* NOCSETS */
-
-case XXVER:
- return(hmsg("Syntax: VERSION\nDisplays the program version number."));
-
-#ifndef NOSPL
-case XXWAI:
- return(hmsga(hxxwai));
-#endif /* NOSPL */
-
-#ifndef NOFRILLS
-case XXWHO:
- return(hmsg("Syntax: WHO [ user ]\nDisplays info about the user."));
-
-case XXWRI:
- return(hmsga(hxxwri));
-
-case XXWRL:
- return(hmsg(
-"WRITE-LINE (WRITELN) is just like WRITE, but includes a line terminator\n\
-at the end of text. See WRITE."));
-#endif /* NOFRILLS */
-
-#ifndef NOSPL
-case XXIFX:
- return(hmsga(ifxhlp));
-
-case XXGETC: /* GETC */
- return(hmsga(hxxgetc));
-
-case XXFWD: /* FORWARD */
- return(hmsg(
-"Like GOTO, but searches only forward for the label. See GOTO."));
-
-case XXLOCAL: /* LOCAL */
- return(hmsg(
-"Declares a variable to be local to the current macro or command file."));
-#endif /* NOSPL */
-
-case XXVIEW:
- return(hmsg(
-"View the terminal emulation screen even when there is no connection."));
-
-case XXASC:
- return(hmsg("Synonym for SET FILE TYPE TEXT."));
-
-case XXBIN:
- return(hmsg("Synonym for SET FILE TYPE BINARY."));
-
-case XXDATE:
- return(hmsga(hmxxdate));
-
-case XXRETR:
- return(hmsg(
-"Just like GET but asks the server to delete each file that has been\n\
-sent successfully."));
-
-case XXEIGHT:
- return(hmsg(
-"Equivalent to SET PARITY NONE, SET COMMAND BYTE 8, SET TERMINAL BYTE 8."));
-
-case XXSAVE:
- return(hmsga(hmxxsave));
-
-#ifndef NOFRILLS
-#ifndef NOPUSH
-case XXEDIT:
- return(hmsg("Syntax: EDIT [ <file> ]\n\
-Starts your preferred editor on the given file, or if none given, the most\n\
-recently edited file, if any. Also see SET EDITOR."));
-#endif /* NOPUSH */
-#endif /* NOFRILLS */
-
-#ifdef BROWSER
-case XXBROWS:
- return(hmsg("Syntax: BROWSE [ <url> ]\n\
-Starts your preferred Web browser on the given URL, or if none given, the\n\
-most recently visited URL, if any. Also see SET BROWSER."));
-#endif /* BROWSER */
-
-#ifdef CK_TAPI
-case XXTAPI:
- return(hmsga(hxxtapi));
-#endif /* CK_TAPI */
-
-#ifdef PIPESEND
-case XXCSEN:
- return(hmsg("Syntax: CSEND [ switches ] <command> [ <as-name> ]\n\
-Sends from the given <command> rather than from a file. Equivalent to\n\
-SEND /COMMAND; see HELP SEND for details."));
-
-case XXCREC:
- return(hmsg("Syntax: CRECEIVE [ switches ] <command>\n\
-Receives to the given <command> rather than to a file. Equivalent to\n\
-RECEIVE /COMMAND; see HELP RECEIVE for details."));
-
-case XXCGET:
- return(hmsg("Syntax: CGET <remote-file-or-command> <local-command>\n\
-Equivalent to GET /COMMAND; see HELP GET for details."));
-#endif /* PIPESEND */
-
-#ifndef NOSPL
-case XXFUNC:
-/*
- Tricky parsing. We want to let them type the function name in any format
- at all: \fblah(), \fblah, \\fblah(), fblah, blah, blah(), etc, but of course
- only one of these is recognized by cmkey(). So we call cmkeyx() (the "no
- complaints" version of cmkey()), and if it fails, we try the other formats
- silently, and still allow for <no-name-given>, editing and reparse, etc.
-*/
- y = cmkeyx(fnctab,nfuncs,"Name of function","",NULL);
- if (y == -1) { /* Reparse needed */
- return(y);
- } else if (y == -3) {
- if ((x = cmcfm()) < 0) /* For recall buffer... */
- return(x);
- return(dohfunc(y)); /* -3 gives general message */
- }
- if (y < 0) { /* Something given but didn't match */
- int dummy;
- char * p;
- for (p = atmbuf; *p; p++) { /* Chop off trailing parens if any */
- if (*p == '(') {
- *p = NUL;
- break;
- }
- }
- /* Chop off leading "\\f" or "\f" or "f" */
- p = atmbuf;
- if (*p == CMDQ) /* Allow for \\f... */
- p++;
- if (*p == CMDQ && (*(p+1) == 'f' || *(p+1) == 'F')) { /* or \f */
- p += 2;
- } else if (*p == 'f' || *p == 'F') { /* or just f */
- p++;
- }
- y = lookup(fnctab,p,nfuncs,&dummy); /* Look up the result */
- }
- if (y < 0) {
- printf("?No such function - \"%s\"\n",atmbuf);
- return(-9);
- }
- x = cmgbrk(); /* Find out how user terminated */
- if (x == LF || x == CR) /* if with CR or LF */
- cmflgs = 1; /* restore cmflgs to say so */
- if ((x = cmcfm()) < 0) /* And THEN confirm so command will */
- return(x); /* get into recall buffer. */
- return(dohfunc(y));
-#endif /* NOSPL */
-
-#ifndef NOCMDL
-case XXOPTS: /* Command-line options */
- return(dohopts());
-
-case XXXOPTS: /* Extended command-line options */
- return(doxopts());
-#endif /* NOCMDL */
-
-#ifdef OS2
-#ifndef NOKVERBS
-case XXKVRB: {
- y = cmkeyx(kverbs,nkverbs,"Name of keyboard verb without \\k","",NULL);
- if (y == -1) { /* Reparse needed */
- return(y);
- } else if (y == -3) {
- if ((x = cmcfm()) < 0) /* For recall buffer... */
- return(x);
- return(dohkverb(y)); /* -3 gives general message */
- }
- if (y < 0) { /* Something given but didn't match */
- int dummy;
- char * p;
- for (p = atmbuf; *p; p++) { /* Chop off trailing parens if any */
- if (*p == '(') {
- *p = NUL;
- break;
- }
- }
- /* Chop off leading "\\k" or "\k" or "k" */
- p = atmbuf;
- if (*p == CMDQ) /* Allow for \\k... */
- p++;
- if (*p == CMDQ && (*(p+1) == 'k' || *(p+1) == 'K')) { /* or \k */
- p += 2;
- } else if (*p == 'k' || *p == 'K') { /* or just k */
- p++;
- }
- y = lookup(kverbs,p,nkverbs,&dummy); /* Look up the result */
- }
- if (y < 0) {
- printf("?No such function - \"%s\"\n",atmbuf);
- return(-9);
- }
- x = cmgbrk(); /* Find out how user terminated */
- if (x == LF || x == CR) /* if with CR or LF */
- cmflgs = 1; /* restore cmflgs to say so */
- if ((x = cmcfm()) < 0) /* And THEN confirm so command will */
- return(x); /* get into recall buffer. */
- return(dohkverb(y));
-}
-#endif /* NOKVERBS */
-#endif /* OS2 */
-
-case XXKERMI:
- return(hmsg("Syntax: KERMIT [command-line-options]\n\
- Lets you give command-line options at the prompt or in a script.\n\
- HELP OPTIONS for more info."));
-
-case XXBACK:
- return(hmsg("Syntax: BACK\n Returns to your previous directory."));
-
-case XXWHERE:
- return(hmsg("Syntax: WHERE\n Tells where your transferred files went."));
-
-#ifndef NOXFER
-case XXREMV:
- return(hmsga(hmxxremv));
-#endif /* NOXFER */
-
-#ifdef CK_KERBEROS
-case XXAUTH:
- return(hmsga(hmxxauth));
-#endif /* CK_KERBEROS */
-
-#ifndef NOHTTP
-case XXHTTP:
- return(hmsga(hmxxhttp));
-#endif /* NOHTTP */
-
-#ifdef NETCMD
-case XXPIPE:
- return(hmsg("Syntax: PIPE [ command ]\n\
-Makes a connection through the program whose command line is given. Example:\n\
-\n pipe rlogin xyzcorp.com"));
-#endif /* NETCMD */
-
-case XXSTATUS:
- return(hmsg(
-"STATUS is the same as SHOW STATUS; prints SUCCESS or FAILURE for the\n\
-previous command."));
-
-#ifndef NOSPL
-case XXASSER:
- return(hmsg("Syntax: ASSERT <condition>\n\
-Succeeds or fails depending on <condition>; see HELP IF for <condition>s."));
-
-case XXFAIL:
- return(hmsg("Always fails."));
-
-case XXSUCC:
- return(hmsg("Always succeeds."));
-#endif /* NOSPL */
-
-#ifdef CK_LOGIN
-case XXLOGOUT:
- return(hmsg(
-"If you haved logged in to Kermit as an Internet Kermit server, the LOGOUT\n\
-command, given at the prompt, logs you out and closes your session."));
-#endif /* CK_LOGIN */
-
-case XXRESET:
- return(hmsg("Closes all open files and logs."));
-
-#ifndef NOCSETS
-case XXASSOC:
- return(hmsga(hmxxassoc));
-#endif /* NOCSETS */
-
-#ifndef NOSPL
-case XXSHIFT:
- return(hmsg("Syntax: SHIFT [ n ]\n\
- Shifts \\%1..9 variables n places to the left; default n = 1."));
-#endif /* NOSPL */
-
-#ifndef NOPUSH
-case XXMAN:
-#ifdef UNIX
- return(hmsg("Syntax: MANUAL [ topic ]\n\
- Runs the \"man\" command on the given topic (default \"kermit\")."));
-#else
-#ifdef OS2
- return(hmsg("Syntax: MANUAL\n\
- Accesses the Kermit 95 HTML manual using the current browser."));
-#else
- return(hmsg("Syntax: MANUAL [ topic ]\n\
- Runs the \"help\" command on the given topic (default \"kermit\")."));
-#endif /* OS2 */
-#endif /* UNIX */
-#endif /* NOPUSH */
-
-case XXWILD:
- return(hmsga(hmxxwild));
-
-case XXPAT:
- return(hmsga(hmxxpat));
-
-#ifndef NOXFER
-case XXFAST:
-case XXCAU:
-case XXROB:
- return(hmsga(hmxxfast));
-#endif /* NOXFER */
-
-#ifdef CKPURGE
-case XXPURGE:
- return(hmsga(hmxxpurge));
-#else
-#ifdef VMS
-case XXPURGE:
- return(hmsga(hmxxpurge));
-#endif /* VMS */
-#endif /* CKPURGE */
-
-#ifndef NOXFER
- case XXRASG:
- return(hmsg(" RASG and RASSIGN are short forms of REMOTE ASSIGN."));
- case XXRCWD:
- return(hmsg(" RCD and RCWD are short forms of REMOTE CD."));
- case XXRCPY:
- return(hmsg(" RCOPY is a short form of REMOTE COPY."));
- case XXRDEL:
- return(hmsg(" RDELETE is a short form of REMOTE RELETE."));
- case XXRDIR:
- return(hmsg(" RDIRECTORY is a short form of REMOTE DIRECTORY."));
- case XXRXIT:
- return(hmsg(" REXIT is a short form of REMOTE EXIT."));
- case XXRHLP:
- return(hmsg(" RHELP is a short form of REMOTE HELP."));
- case XXRHOS:
- return(hmsg(" RHOST is a short form of REMOTE HOST."));
- case XXRKER:
- return(hmsg(" RKERMIT is a short form of REMOTE KERMIT."));
- case XXRMKD:
- return(hmsg(" RMKDIR is a short form of REMOTE MKDIR."));
- case XXRPRI:
- return(hmsg(" RPRINT is a short form of REMOTE PRINT."));
- case XXRPWD:
- return(hmsg(" RPWD is a short form of REMOTE PWD."));
- case XXRQUE:
- return(hmsg(" QUERY and RQUERY are short forms of REMOTE QUERY."));
- case XXRREN:
- return(hmsg(" RRENAME is a short form of REMOTE RENAME."));
- case XXRRMD:
- return(hmsg(" RRMDIR is a short form of REMOTE RMDIR."));
- case XXRSET:
- return(hmsg(" RSET is a short form of REMOTE SET."));
- case XXRSPA:
- return(hmsg(" RSPACE is a short form of REMOTE SPACE."));
- case XXRTYP:
- return(hmsg(" RTYPE is a short form of REMOTE TYPE."));
- case XXRWHO:
- return(hmsg(" RWHO is a short form of REMOTE WHO."));
-#endif /* NOXFER */
-
- case XXSCRN:
- return(hmsga(hmxxscrn));
-
-#ifdef CKEXEC
- case XXEXEC:
- return(hmsg("Syntax: EXEC <command> [ <arg1> [ <arg2> [ ... ] ]\n\
- C-Kermit overlays itself with the given system command and starts it with\n\
- the given arguments. Upon any error, control returns to C-Kermit."));
-#endif /* CKEXEC */
-
-#ifndef NOSPL
- case XXTRACE:
- return(hmsg(
-"Syntax: TRACE { /ON, /OFF } { ASSIGNMENTS, COMMAND-LEVEL, ALL }\n\
- Turns tracing of the given object on or off."));
-#endif /* NOSPL */
-
-#ifdef CK_PERMS
-#ifdef UNIX
- case XXCHMOD:
- return(hmsga(hmxxchmod));
-#endif /* UNIX */
-#endif /* CK_PERMS */
-
-#ifdef CKROOT
- case XXCHRT:
- return(hmsga(hmxxchroot));
-#endif /* CKROOT */
-
-#ifndef NOSPL
- case XXPROMP:
- return(hmsga(hmxxprompt));
-#endif /* NOSPL */
-
- case XXGREP:
- return(hmsga(hmxxgrep));
-
-#ifndef NOSEXP
-#ifndef NOSPL
- case XXSEXP:
- return(hmsga(hmxxsexp));
-#endif /* NOSPL */
-#endif /* NOSEXP */
-
-#ifdef CKLEARN
- case XXLEARN:
- return(hmsga(hmxxlearn));
-#endif /* CKLEARN */
-
-#ifdef ANYSSH
- case XXSSH:
- return(hmsga(hmxxssh));
-#endif /* ANYSSH */
-
-#ifdef TCPSOCKET
- case XXFIREW:
- return(hmsga(hmxxfirew));
-#endif /* TCPSOCKET */
-
-#ifdef NEWFTP
- case XXUSER:
- return(hmsg(" Equivalent to FTP USER."));
- case XXACCT:
- return(hmsg(" Equivalent to FTP ACCOUNT."));
-#endif /* NEWFTP */
-
- case XXORIE:
- return(hmsg(" Shows the directories important to Kermit."));
-
- case XXCONT:
- return(hmsg(" In a FOR or WHILE loop: continue the loop.\n\
- At the prompt: continue a script that has \"shelled out\" to the prompt."));
-
- case XXNOTAV:
- return(hmsg(" This command is not configured in this version of Kermit."));
-
-default: {
- char *s;
- if ((x = cmcfm()) < 0) return(x);
- s = cmdbuf + (int)strlen(cmdbuf) -1;
- while (s >= cmdbuf && *s == SP)
- *s-- = NUL;
- while (s >= cmdbuf && *s != SP)
- s--;
- while (*s == SP) s++;
- printf("Sorry, help not available for \"%s\"\n",s);
- break;
- }
- } /* switch */
-#endif /* NOHELP */
-
- return(success = 0);
-}
-
-/* H M S G -- Get confirmation, then print the given message */
-
-int
-hmsg(s) char *s; {
- int x;
- if ((x = cmcfm()) < 0) return(x);
- printf("\n%s\n\n",s);
- return(0);
-}
-
-#ifdef NOHELP
-
-int /* Print an array of lines, */
-hmsga(s) char *s[]; { /* cheap version. */
- int i;
- if ((i = cmcfm()) < 0) return(i);
- printf("\n"); /* Start off with a blank line */
- for (i = 0; *s[i]; i++) { /* Print each line. */
- printf("%s\n",s[i]);
- }
- printf("\n");
- return(0);
-}
-
-#else /* NOHELP not defined... */
-
-int /* Print an array of lines, */
-hmsga(s) char *s[]; { /* pausing at end of each screen. */
- extern int hmtopline; /* (This should be a parameter...) */
- int x, y, i, j, k, n;
- if ((x = cmcfm()) < 0) return(x);
-
-#ifdef CK_TTGWSIZ
-#ifdef OS2
- ttgcwsz();
-#else /* OS2 */
- /* Check whether window size changed */
- if (ttgwsiz() > 0) {
- if (tt_rows > 0 && tt_cols > 0) {
- cmd_rows = tt_rows;
- cmd_cols = tt_cols;
- }
- }
-#endif /* OS2 */
-#endif /* CK_TTGWSIZ */
-
- printf("\n"); /* Start off with a blank line */
- n = (hmtopline > 0) ? hmtopline : 1; /* Line counter */
- for (i = 0; *s[i]; i++) {
- printf("%s\n",s[i]); /* Print a line. */
- y = (int)strlen(s[i]);
- k = 1;
- for (j = 0; j < y; j++) /* See how many newlines were */
- if (s[i][j] == '\n') k++; /* in the string... */
- n += k;
- if (n > (cmd_rows - 3) && *s[i+1]) /* After a screenful, give them */
- if (!askmore()) return(0); /* a "more?" prompt. */
- else n = 0;
- }
- printf("\n");
- return(0);
-}
-
-#ifndef NOXMIT
-static char *hsetxmit[] = {
-"Syntax: SET TRANSMIT parameter value",
-" ",
-"Controls the behavior of the TRANSMIT command (see HELP TRANSMIT):",
-" ",
-"SET TRANSMIT ECHO { ON, OFF }",
-" Whether to echo text to your screen as it is being transmitted.",
-" ",
-"SET TRANSMIT EOF text",
-" Text to send after end of file is reached, e.g. \\4 for Ctrl-D",
-" ",
-"SET TRANSMIT FILL number",
-" ASCII value of a character to insert into blank lines, 0 for none.",
-" Applies only to text mode. 0 by default.",
-" ",
-"SET TRANSMIT LINEFEED { ON, OFF }",
-" Transmit Linefeed as well as Carriage Return (CR) at the end of each line.",
-" Normally, only CR is sent.",
-" ",
-"SET TRANSMIT LOCKING-SHIFT { ON, OFF }",
-" Whether to use SO/SI for transmitting 8-bit data when PARITY is not NONE.",
-" ",
-"SET TRANSMIT PAUSE number",
-" How many milliseconds to pause after transmitting each line (text mode),",
-" or each character (binary mode).",
-" ",
-"SET TRANSMIT PROMPT number",
-" ASCII value of character to look for from host before sending next line",
-" when TRANSMITting in text mode; normally 10 (Linefeed). 0 means none;",
-" don't wait for a prompt.",
-" ",
-"SET TRANSMIT TIMEOUT number",
-" Number of seconds to wait for each character to echo when TRANSMIT ECHO",
-" is ON or TRANSMIT PROMPT is not 0. If 0 is specified, this means wait",
-" indefinitely for each echo.",
-" ",
-"Synonym: SET XMIT. SHOW TRANSMIT displays current settings.",
-"" };
-#endif /* NOXMIT */
-
-static char *hsetbkg[] = {
-"Syntax: SET BACKGROUND { OFF, ON }",
-" ",
-" SET BACKGROUND OFF forces prompts and messages to appear on your screen",
-" even though Kermit thinks it is running in the background.",
-"" };
-
-#ifdef DYNAMIC
-static char *hsetbuf[] = {
-"Syntax: SET BUFFERS n1 [ n2 ]",
-" ",
-" Changes the overall amount of memory allocated for SEND and RECEIVE packet",
-" buffers, respectively. Bigger numbers let you have longer packets and",
-" more window slots. If n2 is omitted, the same value as n1 is used.",
-#ifdef BIGBUFOK
-" ",
-" NOTE: This command is not needed in this version of Kermit, which is",
-" already configured for maximum-size packet buffers.",
-#endif /* BIGBUFOK */
-"" };
-#endif /* DYNAMIC */
-
-static char *hsetcmd[] = {
-"Syntax: SET COMMAND parameter value",
-" ",
-
-#ifdef CK_AUTODL
-"SET COMMAND AUTODOWNLOAD { ON, OFF }",
-" Enables/Disables automatic recognition of Kermit packets while in",
-" command mode. ON by default.",
-" ",
-#endif /* CK_AUTODL */
-
-"SET COMMAND BYTESIZE { 7, 8 }",
-" Informs Kermit of the bytesize of the communication path between itself",
-" and your keyboard and screen. 8 is assumed. SET COMMAND BYTE 7 only if",
-" 8-bit characters cannot pass.",
-" ",
-
-#ifdef OS2
-"SET COMMAND COLOR <foreground-color> <background-color>",
-" Lets you choose colors for Command screen. Use ? in the color fields to",
-" to get lists of available colors.",
-" ",
-"SET COMMAND CURSOR-POSITION <row> <column>",
-" Moves the command-screen cursor to the given position (1-based). This",
-" command should be used in scripts instead of relying on ANSI.SYS escape",
-" sequences.",
-" ",
-#endif /* OS2 */
-
-#ifdef OS2
-#ifdef NT
-"SET COMMAND HEIGHT <number>",
-" Changes the number of rows (lines) in your command screen, not",
-" counting the status line. Recommended values are 24, 42, and 49 (or 25,",
-" 43, and 50 if SET COMMAND STATUSLINE is OFF.)",
-#else
-"SET COMMAND HEIGHT <number>"
-" Changes the number of rows (lines) in your command screen, not",
-" counting the status line. Windowed sessions can use any value from 8 to",
-" 101. Fullscreen sessions are limited to 24, 42, 49, or 59. Not all"
-" heights are supported by all video adapters.",
-#endif /* NT */
-#else /* OS2 */
-"SET COMMAND HEIGHT <number>",
-" Informs Kermit of the number of rows in your command screen for the",
-" purposes of More?-prompting.",
-#endif /* OS2 */
-" ",
-"SET COMMAND WIDTH <number>",
-" Informs Kermit of the number of characters across your screen for",
-" purposes of screen formatting.",
-" ",
-"SET COMMAND MORE-PROMPTING { ON, OFF }",
-" ON (the default) enables More?-prompting when Kermit needs to display",
-" text that does not fit vertically on your screen. OFF allows the text to",
-" scroll by without intervention. If your command window has scroll bars,",
-" you might prefer OFF.",
-" ",
-
-#ifdef CK_RECALL
-"SET COMMAND RECALL-BUFFER-SIZE number",
-" How big you want Kermit's command recall buffer to be. By default, it",
-" holds 10 commands. You can make it any size you like, subject to memory",
-" constraints of the computer. A size of 0 disables command recall.",
-" Whenever you give this command, previous command history is lost.",
-" ",
-#endif /* CK_RECALL */
-
-"SET COMMAND QUOTING { ON, OFF }",
-" Whether to treat backslash and question mark as special characters (ON),",
-" or as ordinary data characters (OFF) in commands. ON by default.",
-" ",
-#ifdef DOUBLEQUOTING
-"SET COMMAND DOUBLEQUOTING { ON, OFF }",
-" Whether to allow doublequotes (\") to be used to enclose fields,",
-" filenames, directory names, and macro arguments that might contain",
-" spaces. ON by default; use OFF to force compatibility with older",
-" versions.",
-" ",
-#endif /* DOUBLEQUOTING */
-
-#ifdef CK_RECALL
-"SET COMMAND RETRY { ON, OFF }",
-" Whether to reprompt you with the correct but incomplete portion of a",
-" syntactically incorrect command. ON by default.",
-" ",
-#endif /* CK_RECALL */
-
-#ifdef OS2
-"SET COMMAND SCROLLBACK <lines>",
-" Sets size of virtual Command screen buffer to the given number of lines,",
-" which includes the active Command screen. The minimum is 256. The max",
-" is 2 million. The default is 512.",
-" ",
-"SET COMMAND STATUSLINE { ON, OFF }",
-" ON (default) enables the Kermit status line in the command screen.",
-" OFF removes it, making the line available for use by the host.",
-" ",
-#endif /* OS2 */
-
-"Use SHOW COMMAND to display these settings.",
-"" };
-
-#ifndef NOLOCAL
-static char *hsetcar[] = {
-"Syntax: SET CARRIER-WATCH { AUTO, OFF, ON }",
-" ",
-" Attempts to control treatment of carrier (the Data Carrier Detect signal)",
-" on serial communication (SET LINE or SET PORT) devices. ON means that",
-" carrier is required at all times. OFF means carrier is never required.",
-" AUTO (the default) means carrier is required at all times except during",
-" the DIAL command. Correct operation of carrier-watch depends on the",
-" capabilities of the underlying OS, drivers, devices, and cables. If you",
-" need to CONNECT to a serial device that is not asserting carrier, and",
-" Kermit won't let you, use SET CARRIER-WATCH OFF. Use SHOW COMMUNICATIONS",
-" to display the CARRIER-WATCH setting.",
-"" };
-#endif /* NOLOCAL */
-
-static char *hsetat[] = {
-"Syntax: SET ATTRIBUTES name ON or OFF",
-" ",
-" Use this command to enable (ON) or disable (OFF) the transmission of",
-" selected file attributes along with each file, and to handle or ignore",
-" selected incoming file attributes, including:",
-" ",
-#ifndef NOCSETS
-" CHARACTER-SET: The transfer character set for text files",
-#endif /* NOCSETS */
-" DATE: The file's creation date",
-" DISPOSITION: Unusual things to do with the file, like MAIL or PRINT",
-" LENGTH: The file's length",
-" PROTECTION: The file's protection (permissions)",
-" SYSTEM-ID: Machine/Operating system of origin",
-" TYPE: The file's type (text or binary)",
-" ",
-"You can also specify ALL to select all of them. Examples:",
-" ",
-" SET ATTR DATE OFF",
-" SET ATTR LENGTH ON",
-" SET ATTR ALL OFF",
-" ",
-"Also see HELP SET SEND and HELP SET RECEIVE.",
-""
-};
-
-static char *hxytak[] = {
-"Syntax: SET TAKE parameter value",
-" ",
-" Controls behavior of TAKE command:",
-" ",
-"SET TAKE ECHO { ON, OFF }",
-" Tells whether commands read from a TAKE file should be displayed on the",
-" screen (if so, each command is shown at the time it is read, and labeled",
-" with a line number).",
-" ",
-"SET TAKE ERROR { ON, OFF }",
-" Tells whether a TAKE command file should be automatically terminated when",
-" a command fails. This setting is local to the current command file, and",
-" inherited by subordinate command files.",
-"" };
-
-#ifndef NOLOCAL
-#ifdef OS2MOUSE
-static char *hxymouse[] = {
-"Syntax: SET MOUSE ACTIVATE { ON, OFF }",
-" Enables or disables the mouse in Connect mode. Default is ON",
-" ",
-"Syntax: SET MOUSE BUTTON <number> <key-modifier> <action> [ <text> ]",
-" where:",
-" <number> is the mouse button number, 1, 2, or 3;",
-" <key-modifier> denotes modifier keys held down during the mouse event:",
-" ALT, ALT-SHIFT, CTRL, CTRL-ALT CTRL-ALT-SHIFT, CTRL-SHIFT, SHIFT, NONE;",
-" <action> is the mouse action, CLICK, DRAG, or DOUBLE-CLICK.",
-" ",
-" The <text> has exactly the same properties as the <text> from the SET KEY",
-" command -- it can be a character, a string, one or more Kverbs, a macro",
-" invoked as a Kverb, or any combination of these. Thus, anything that can",
-" be assigned to a key can also be assigned to the mouse -- and vice versa.",
-" If the <text> is omitted, the action will be ignored. Examples:",
-" ",
-" SET MOUSE BUTTON 1 NONE DOUBLE \\KmouseCurPos",
-" SET MOU B 2 SHIFT CLICK help\\13",
-" ",
-" DRAG operations perform a \"mark mode\" selection of Text. You should",
-" assign only the following actions to drag operations:",
-" ",
-" \\Kdump - copy marked text to printer (or file)",
-" \\Kmarkcopyclip - copy marked text to PM Clipboard",
-" \\Kmarkcopyhost - copy marked text direct to Host",
-" \\Kmousemark - mark text, no copy operation performed",
-" ",
-" The following Kverb is only for use with the mouse:",
-" ",
-" \\KmouseCurPos",
-" ",
-" which represents the mouse-directed terminal cursor feature.",
-" ",
-"Syntax: SET MOUSE CLEAR",
-" Restores all mouse events to their default definitions",
-" Button 1 Ctrl-Click = Kverb: \\Kmouseurl",
-" Button 1 Double-Click = Kverb: \\Kmousecurpos",
-" Button 1 Drag = Kverb: \\Kmarkcopyclip",
-" Button 1 Alt-Drag = Kverb: \\Kmarkcopyclip_noeol",
-" Button 1 Ctrl-Drag = Kverb: \\Kmarkcopyhost",
-" Button 1 Ctrl-Alt-Drag = Kverb: \\Kmarkcopyhost_noeol",
-" Button 1 Ctrl-Shift-Drag = Kverb: \\Kdump",
-" Button 2 Double-Click = Kverb: \\Kpaste",
-" Button 2 Drag = Kverb: \\Kmarkcopyhost",
-" Button 2 Alt-Drag = Kverb: \\Kmarkcopyhost_noeol ",
-" Button 3 Double-Click = Kverb: \\Kpaste",
-""};
-#endif /* OS2MOUSE */
-
-static char *hxyterm[] = {
-"Syntax: SET TERMINAL parameter value",
-" ",
-#ifdef OS2
-"SET TERMINAL TYPE { ANSI, VT52, VT100, VT102, VT220, VT320, ... }",
-" Selects type type of terminal to emulate. Type SET TERMINAL TYPE ? to",
-" see a complete list.",
-" ",
-"SET TERMINAL ANSWERBACK { OFF, ON }",
-" Disables/enables the ENQ/Answerback sequence (\"K-95 version term-type\").",
-" ",
-"SET TERMINAL ANSWERBACK MESSAGE <extension>",
-" Allows you to specify an extension to the default answerback message.",
-" ",
-#else
-"SET TERMINAL TYPE ...",
-" This command is not available because this version of Kermit does not",
-" include a terminal emulator. Instead, it is a \"semitransparent pipe\"",
-" (or a totally transparent one, if you configure it that way) to the",
-" computer or service you have made a connection to. Your console,",
-" workstation window, or the terminal emulator or terminal from which you",
-" are running Kermit provides the emulation.",
-" ",
-#endif /* OS2 */
-
-#ifdef CK_APC
-"SET TERMINAL APC { ON, OFF, NO-INPUT, NO-INPUT-UNCHECKED, UNCHECKED }",
-#ifdef OS2
-" Controls execution of Application Program Commands sent by the host while",
-" K-95 is either in CONNECT mode or processing INPUT commands. ON allows",
-" execution of \"safe\" commands and disallows potentially dangerous ones",
-" such as DELETE, RENAME, OUTPUT, and RUN. OFF prevents execution of APCs.",
-" UNCHECKED allows execution of all APCs. OFF is the default.",
-#else /* OS2 */
-" Controls execution of Application Program Commands sent by the host while",
-" C-Kermit is in CONNECT mode. ON allows execution of \"safe\" commands and",
-" disallows potentially dangerous commands such as DELETE, RENAME, OUTPUT,",
-" and RUN. OFF prevents execution of APCs. UNCHECKED allows execution of",
-" all APCs. OFF is the default.",
-#endif /* OS2 */
-" ",
-#endif /* CK_APC */
-
-#ifdef OS2
-"SET TERMINAL ARROW-KEYS { APPLICATION, CURSOR }",
-" Sets the mode for the arrow keys during VT terminal emulation.",
-" ",
-"SET TERMINAL ATTRIBUTE { BLINK, DIM, PROTECTED, REVERSE, UNDERLINE }",
-" Determines how attributes are displayed by Kermit-95.",
-" ",
-"SET TERMINAL ATTRIBUTE { BLINK, DIM, REVERSE, UNDERLINE } { ON, OFF }",
-" Determines whether real Blinking, Dim, Reverse, and Underline are used in",
-" the terminal display. When BLINK is turned OFF, reverse background",
-" intensity is used. When DIM is turned OFF, dim characters appear BOLD.",
-" When REVERSE and UNDERLINE are OFF, the colors selected with SET",
-" TERMINAL COLOR { REVERSE,UNDERLINE } are used instead. This command",
-" affects the entire current screen and terminal scrollback buffer.",
-" ",
-"SET TERMINAL ATTRIBUTE PROTECTED [ -",
-" { BOLD, DIM, INVISIBLE, NORMAL, REVERSE, UNDERLINED } ]",
-" Sets the attributes used to represent Protected text in Wyse and Televideo",
-" terminal emulations. Any combination of attributes may be used. The",
-" default is DIM.)",
-" ",
-#endif /* OS2 */
-
-#ifdef OS2
-#ifdef CK_XYZ
-"SET TERMINAL AUTODOWNLOAD { ON, OFF, ERROR { STOP, CONTINUE } }",
-" enables/disables automatic switching into file-transfer mode when a Kermit",
-" or ZMODEM file transfer has been detected during CONNECT mode or while",
-" an INPUT command is active. Default is OFF.",
-#else
-"SET TERMINAL AUTODOWNLOAD { ON, OFF, ERROR { STOP, CONTINUE } }",
-" enables/disables automatic switching into file-transfer mode when a Kermit",
-" file transfer has been detected during CONNECT mode or while an INPUT",
-" command is active. Default is OFF.",
-#endif /* CK_XYZ */
-
-" ",
-" When TERMINAL AUTODOWNLOAD is ON, the TERMINAL AUTODOWNLOAD ERROR setting",
-" tells what to do if an error occurs during a file transfer or other",
-" protocol operation initiated by the terminal emulator: STOP (the default)",
-" means to remain in command mode so you can see what happened; CONTINUE",
-" means to resume the CONNECT session (e.g. so a far-end script can continue",
-" its work).",
-" ",
-
-#ifdef CK_XYZ
-"SET TERM... AUTO... { KERMIT, ZMODEM } C0-CONFLICTS { IGNORED, PROCESSED }",
-" Determines whether the active terminal emulator should process or ignore",
-" C0 control characters which are also used for the specified file transfer",
-" protocol. Kermit by default uses ^A (SOH) and Zmodem uses ^X (CAN).",
-" Default is PROCESSED.",
-" ",
-"SET TERM... AUTO... { KERMIT, ZMODEM } DETECTION-METHOD { PACKET, STRING }",
-" Determines whether the specified file transfer protocol should be detected",
-" by looking for valid packets or by identifying a specified text string.",
-" Default is PACKET.",
-" ",
-"SET TERM... AUTO... { KERMIT, ZMODEM } STRING <text>",
-" Lets you assign an autodownload detection string for use with the",
-" specified file transfer protocol.",
-" Default for Kermit is \"READY TO SEND...\", for Zmodem is \"rz\\{13}\".",
-" ",
-#else /* CK_XYZ */
-"SET TERM... AUTO... KERMIT C0-CONFLICTS { IGNORED, PROCESSED }",
-" Determines whether the active terminal emulator should process or ignore",
-" C0 control characters which are also used for the specified file transfer",
-" protocol. Kermit by default uses ^A <SOH>. Default is PROCESSED.",
-" ",
-"SET TERM... AUTO... KERMIT DETECTION-METHOD { PACKET, STRING }",
-" Determines whether the specified file transfer protocol should be detected",
-" by looking for valid packets or by identifying a specified text string.",
-" Default is PACKET.",
-" ",
-"SET TERM... AUTO... KERMIT STRING <text>",
-" Lets you assign an autodownload detection string for use with the",
-" specified file transfer protocol. Default is \"READY TO SEND...\".",
-" ",
-#endif /* CK_XYZ */
-"SET TERMINAL AUTOPAGE { ON, OFF }",
-" ",
-"SET TERMINAL AUTOSCROLL { ON, OFF }",
-" ",
-#else /* OS2 */
-"SET TERMINAL AUTODOWNLOAD { ON, OFF, ERROR { STOP, CONTINUE } }",
-" Enables/disables automatic switching into file-transfer mode when a valid",
-#ifdef CK_XYZ
-" Kermit or ZMODEM packet of the appropriate type is received during CONNECT",
-" mode. Default is OFF.",
-#else
-" Kermit packet of the appropriate type is received during CONNECT mode.",
-" Default is OFF.",
-#endif /* CK_XYZ */
-
-" ",
-" When TERMINAL AUTODOWNLOAD is ON, the TERMINAL AUTODOWNLOAD ERROR setting",
-" tells what to do if an error occurs during a file transfer or other",
-" protocol operation initiated by the terminal emulator: STOP (the default)",
-" means to remain in command mode so you can see what happened; CONTINUE",
-" means to resume the CONNECT session (e.g. so a far-end script can continue",
-" its work).",
-" ",
-
-#endif /* OS2 */
-
-#ifdef OS2
-"SET TERMINAL BELL { AUDIBLE, VISIBLE, NONE }",
-" Specifies how Control-G (bell) characters are handled. AUDIBLE means",
-" a beep is sounded; VISIBLE means the screen is flashed momentarily.",
-" ",
-" (This command has been superseded by SET BELL.)",
-" ",
-#endif /* OS2 */
-
-"SET TERMINAL BYTESIZE { 7, 8 }",
-" Use 7- or 8-bit characters between Kermit and the remote computer during",
-" terminal sessions. The default is 8.",
-" ",
-
-#ifndef NOCSETS
-#ifdef OS2
-"SET TERMINAL CHARACTER-SET <remote-cs>",
-" Specifies the character set used by the remote host, <remote-cs>.",
-" Equivalent to SET TERM REMOTE-CHARACTER-SET <remote-cs> ALL. For more",
-" control over the details, use SET TERM REMOTE-CHARACTER-SET and (in",
-" non-GUI K95 versions) SET TERM LOCAL-CHARACTER-SET; these are explained",
-" below. The default TERMINAL CHARACTER-SET is LATIN1 (ISO 8859-1).",
-#else /* not OS2 */
-"SET TERMINAL CHARACTER-SET <remote-cs> [ <local-cs> ]",
-" Specifies the character set used by the remote host, <remote-cs>, and the",
-" character set used by C-Kermit locally, <local-cs>. If you don't specify",
-" the local character set, the current FILE CHARACTER-SET is used. When",
-" you specify two different character sets, C-Kermit translates between them",
-" during CONNECT. By default, both character sets are TRANSPARENT, and",
-" no translation is done.",
-#endif /* OS2 */
-" ",
-#endif /* NOCSETS */
-
-#ifdef OS2
-
-"SET TERMINAL CODE-PAGE <number>",
-" Lets you change the PC code page. Only works for code pages that are",
-" successfully prepared in CONFIG.SYS. Use SHOW TERMINAL to list the",
-" current code page and the available code pages.",
-#ifdef OS2ONLY
-" ",
-" Also see SET TERMINAL FONT if the desired code page in not available in",
-" your version of OS/2.",
-#endif /* OS2ONLY */
-" ",
-
-#ifndef NT
-"SET TERMINAL COLOR BORDER <foreground>",
-#endif /* NT */
-"SET TERMINAL COLOR <screenpart> <foreground> <background>",
-" Sets the colors of the terminal emulation screen.",
-" <screenpart> may be any of the following:",
-" DEBUG, HELP-TEXT, REVERSE, SELECTION, STATUS-LINE, TERMINAL-SCREEN, or",
-" UNDERLINED-TEXT.",
-" <foreground> and <background> may be any of:",
-" BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LGRAY, DGRAY, LBLUE,",
-" LGREEN, LCYAN, LRED, LMAGENTA, YELLOW or WHITE.",
-" The L prefix for the color names means Light.",
-" ",
-
-"SET TERMINAL COLOR ERASE { CURRENT-COLOR, DEFAULT-COLOR }",
-" Determines whether the current color as set by the host or the default",
-" color as set by the user (SET TERMINAL COLOR TERMINAL) is used to clear",
-" the screen when erase commands are received from the host.",
-" ",
-
-"SET TERMINAL COLOR RESET-ON-ESC[0m { CURRENT-COLOR, DEFAULT-COLOR }",
-" Determines whether the current color or the default color is used after",
-" <ESC>[0m (\"reset attributes\") command sequence is received from the",
-" host.",
-" ",
-
-"SET TERMINAL CONTROLS { 7, 8 }",
-" Determines whether VT220/320 or Wyse 370 function keys, arrow keys, etc,",
-" that generate ANSI-format escape sequences should send 8-bit control",
-" characters or 7-bit escape sequences.",
-" ",
-#endif /* OS2 */
-
-"SET TERMINAL CR-DISPLAY { CRLF, NORMAL }",
-" Specifies how incoming carriage return characters are to be displayed",
-" on your screen.",
-" ",
-
-#ifdef OS2
-#ifdef KUI
-"SET TERMINAL CURSOR { FULL, HALF, UNDERLINE } {ON, OFF, NOBLINK}",
-" Selects the cursor style and visibility for the terminal screen.",
-#else
-"SET TERMINAL CURSOR { FULL, HALF, UNDERLINE } {ON, OFF}",
-" Selects the cursor style and visibility for the terminal screen.",
-#endif /* KUI */
-" ",
-"SET TERMINAL DG-UNIX-MODE { ON, OFF }",
-" Specifies whether the Data General emulations should accept control",
-" sequences in Unix compatible format or in native DG format. The",
-" default is OFF, DG format.",
-" ",
-#endif /* OS2 */
-
-"SET TERMINAL DEBUG { ON, OFF }",
-" Turns terminal session debugging on and off. When ON, incoming control",
-" characters are displayed symbolically, rather than be taken as formatting",
-" commands. SET TERMINAL DEBUG ON implies SET TELNET DEBUG ON.",
-" ",
-#ifdef OS2
-"SET TERMINAL DG-UNIX-MODE { ON, OFF }",
-" ",
-#endif /* OS2 */
-
-"SET TERMINAL ECHO { LOCAL, REMOTE }",
-" Specifies which side does the echoing during terminal connection.",
-" ",
-
-"SET TERMINAL ESCAPE-CHARACTER { ENABLED, DISABLED }",
-" Turns on/off the ability to escape back from CONNECT mode using the SET",
-#ifdef OS2
-" ESCAPE character. If you disable it you can still get back using Alt-key",
-" combinations as shown in the status line. Also see HELP SET ESCAPE.",
-#else
-" ESCAPE character. If you disable it, Kermit returns to its prompt only",
-" when the connection is closed by the other end. USE WITH EXTREME CAUTION.",
-" Also see HELP SET ESCAPE.",
-#endif /* OS2 */
-" ",
-
-#ifdef OS2
-#ifdef KUI
-"SET TERMINAL FONT <facename> <height>",
-" Specifies the font to be used in the Kermit 95 window. The font is",
-" determined by the choice of a facename and a height measured in Points.",
-" The available facenames are those installed in the Font Control Panel.",
-" ",
-#else /* KUI */
-#ifdef OS2ONLY
-"SET TERMINAL FONT { CP437, CP850, CP852, CP862, CP866, DEFAULT }",
-" CP437 - Original PC code page",
-" CP850 - \"Multilingual\" (West Europe) code page",
-" CP852 - East Europe Roman Alphabet code page (for Czech, Polish, etc)",
-" CP862 - Hebrew code page",
-" CP866 - Cyrillic (Russian, Belorussian, and Ukrainian) code page",
-" ",
-" Loads a soft into the video adapter for use during terminal emulation.",
-" Use this command when your OS/2 system does not have the desired code.",
-" page. Can be used only in full-screen sessions. Also see SET TERMINAL",
-" CODE-PAGE and SET TERMINAL REMOTE-CHARACTER-SET.",
-" ",
-#endif /* OS2ONLY */
-#endif /* KUI */
-
-#ifdef NT
-"SET TERMINAL HEIGHT <number>",
-" Changes the number of rows (lines) to use during terminal emulation, not",
-" counting the status line. Recommended values are 24, 42, and 49 (or 25,",
-" 43, and 50 if SET TERMINAL STATUSLINE is OFF.)",
-#else
-"SET TERMINAL HEIGHT <number>"
-" Changes the number of rows (lines) to use during terminal emulation, not",
-" counting the status line. Windowed sessions can use any value from 8 to",
-" 101. Fullscreen sessions are limited to 24, 42, 49, or 59. Not all"
-" heights are supported by all video adapters.",
-#endif /* NT */
-#else /* OS2 */
-"SET TERMINAL HEIGHT <number>",
-" Tells C-Kermit how many rows (lines) are on your CONNECT-mode screen.",
-#endif /* OS2 */
-" ",
-
-#ifdef CKTIDLE
-"SET TERMINAL IDLE-TIMEOUT <number>",
-" Sets the limit on idle time in CONNECT mode to the given number of",
-" seconds. 0 (the default) means no limit.",
-" ",
-"SET TERMINAL IDLE-ACTION { EXIT, HANGUP, OUTPUT [ text ], RETURN }",
-" Specifies the action to be taken when a CONNECT session is idle for the",
-" number of seconds given by SET TERMINAL IDLE-TIMEOUT. The default action",
-" is to RETURN to command mode. EXIT exits from Kermit; HANGUP hangs up the",
-" connection, and OUTPUT sends the given text to the host without leaving",
-" CONNECT mode; if no text is given a NUL (0) character is sent.",
-#ifdef TNCODE
-" ",
-"And for Telnet connections:",
-" ",
-"SET TERMINAL IDLE-ACTION { TELNET-NOP, TELNET-AYT }",
-" Sends the indicated Telnet protocol message: No Operation (NOP) or",
-" \"Are You There?\" (AYT).",
-#endif /* TNCODE */
-" ",
-#endif /* CKTIDLE */
-
-#ifdef OS2
-
-"SET TERMINAL KDB-FOLLOWS-GL/GR { ON, OFF }",
-" Specifies whether or not the keyboard character set should follow the",
-" active GL and GR character sets. This feature is OFF by default and",
-" should not be used unless it is specificly required by the host",
-" application.",
-" ",
-
-"SET TERMINAL KEY <mode> /LITERAL <keycode> <text>",
-"SET TERMINAL KEY <mode> DEFAULT",
-"SET TERMINAL KEY <mode> CLEAR",
-" Configures the key whose <keycode> is given to send the given text when",
-" pressed while <mode> is active. <mode> may be any of the valid terminal",
-" types or the special modes \"EMACS\", \"HEBREW\" or \"RUSSIAN\". DEFAULT",
-" restores all default key mappings for the specified mode. CLEAR erases",
-" all the key mappings. If there is no text, the default key binding is",
-#ifndef NOCSETS
-" restored for the key k. SET TERMINAL KEY mappings take place before",
-" terminal character-set translation. SET KEY mappings take precedence over",
-" SET TERMINAL KEY <terminal type> settings.",
-#else
-" restored for the key. SET KEY mappings take precedence over SET TERMINAL",
-" KEY <terminal type> settings.",
-#endif /* NOCSETS */
-" The /LITERAL switch may be used to instruct Kermit to ignore character-set",
-" translations when sending this definition to the host.",
-" ",
-" The text may contain \"\\Kverbs\" to denote actions, to stand for DEC",
-" keypad, function, or editing keys, etc. For a list of available keyboard",
-" verbs, type SHOW KVERBS.",
-" ",
-" To find out the keycode and mapping for a particular key, use the SHOW",
-" KEY command. Use the SAVE KEYS command to save all settings to a file.",
-" ",
-"SET TERMINAL KEYBOARD-MODE { NORMAL, EMACS, RUSSIAN, HEBREW }",
-" Select a special keyboard mode for use in the terminal screen.",
-" ",
-
-"SET TERMINAL KEYPAD-MODE { APPLICATION, NUMERIC }",
-" Specifies the \"mode\" of the numeric keypad for VT terminal emulation.",
-" Use this command in case the host or application wants the keypad to be",
-" in a different mode than it's in, but did not send the escape sequence",
-" to put it in the needed mode.",
-" ",
-#ifdef KUI
-"SET TERMINAL LINE-SPACING <float>",
-" Specifies the line spacing used when displaying text. The default is 1.0.",
-" Valid values range from 1.0 to 3.0 inclusive.",
-" ",
-#endif /* KUI */
-#endif /* OS2 */
-
-#ifndef NOCSETS
-#ifdef OS2
-"SET TERMINAL LOCAL-CHARACTER-SET <local-cs>",
-" Specifies the character set used by K-95 locally. If you don't specify",
-#ifdef OS2ONLY
-" the local character-set, the current TERMINAL FONT is used if you have",
-" given a SET TERMINAL FONT command; otherwise the current codepage is used.",
-#else
-" the local character-set, the current code page is used.",
-#endif /* OS2ONLY */
-" ",
-" When the local and remote character sets differ, Kermit translates between",
-" them during CONNECT. By default, the remote character set is Latin1 and",
-" the local one is your current code page.",
-#ifdef NT
-" ",
-" In Windows NT, Unicode is used as the local character-set regardless of",
-" this setting.",
-#endif /* NT */
-" ",
-"See also SET TERMINAL REMOTE-CHARACTER-SET",
-" ",
-#endif /* OS2 */
-#endif /* NOCSETS */
-
-#ifdef OS2
-"SET TERMINAL LOCKING-SHIFT { OFF, ON }",
-" Tells whether to send Shift-In/Shift-Out (Ctrl-O and Ctrl-N) to switch",
-" between 7-bit and 8-bit characters sent during terminal emulation over",
-" 7-bit connections. OFF by default.",
-#else
-"SET TERMINAL LOCKING-SHIFT { OFF, ON }",
-" Tells Kermit whether to use Shift-In/Shift-Out (Ctrl-O and Ctrl-N) to",
-" switch between 7-bit and 8-bit characters during CONNECT. OFF by default.",
-#endif /* OS2 */
-" ",
-
-#ifdef OS2
-"SET TERMINAL MARGIN-BELL { ON [column], OFF }",
-" Determines whether the margin-bell is activated and what column it should",
-" ring at. OFF by default.",
-" ",
-#endif /* OS2 */
-
-"SET TERMINAL NEWLINE-MODE { OFF, ON }",
-" Tells whether to send CRLF (Carriage Return and Line Feed) when you type",
-" CR (press the Return or Enter key) in CONNECT mode.",
-" ",
-
-#ifdef OS2
-"SET TERMINAL OUTPUT-PACING <milliseconds>",
-" Tells how long to pause between sending each character to the host during",
-" CONNECT mode. Normally not needed but sometimes required to work around",
-" TRANSMISSION BLOCKED conditions when pasting into the terminal window.",
-" ",
-
-#ifdef PCTERM
-"SET TERMINAL PCTERM { ON, OFF }",
-" Activates or deactivates the PCTERM terminal emulation keyboard mode.",
-" When PCTERM is ON all keystrokes in the terminal screen are sent to the",
-" host as make/break (down/up) codes instead of as characters from the",
-" REMOTE-CHARACTER-SET, and all keyboard mappings, including Kverbs and the",
-" escape character are disabled. To turn off PCTERM keyboard mode while in",
-" CONNECT mode press Control-CapsLock. PCTERM is OFF by default.",
-" ",
-#endif /* PCTERM */
-#endif /* OS2 */
-
-#ifdef OS2
-"SET TERMINAL PRINT { AUTO, COPY, OFF, USER }",
-" Allows selective control of various types of printing from the Terminal",
-" session. AUTO prints a line of text from the terminal screen whenever",
-" the cursor is moved off the line. COPY prints every byte received as",
-" it is received without interpretation. USER prints every byte after",
-" interpretation by the terminal emulator translates character-sets and",
-" construct escape sequences, ... The default is OFF.",
-" ",
-#else
-#ifdef XPRINT
-"SET TERMINAL PRINT { ON, OFF }",
-" Enables and disables host-initiated transparent printing in CONNECT mode.",
-" ",
-#endif /* XPRINT */
-#endif /* OS2 */
-
-#ifdef OS2
-#ifndef NOCSETS
-"SET TERMINAL REMOTE-CHARACTER-SET <remote-cs> [ { G0,G1,G2,G3 }... ]",
-" Specifies the character set used by the remote host, <remote-cs>.",
-" When the local and remote character sets differ, Kermit translates",
-" between them during CONNECT. By default, the remote character set is",
-" Latin1 and the local one is your current code page. Optionally, you can",
-" also designate the character set to the G0..G3 graphic tables.",
-" ",
-#endif /* NOCSETS */
-#endif /* OS2 */
-
-#ifdef OS2
-"SET TERMINAL ROLL-MODE { INSERT, OVERWRITE, KEYSTROKES [ option ] }",
-" Tells whether new data when received from the host is entered into the",
-" scrollback buffer at the current rollback position (OVERWRITE) or at the",
-" end of the buffer (INSERT). The default is INSERT. Typing is allowed",
-" during rollbacks in either mode, according to SET TERM ROLL KEYSTROKES:",
-" SEND (the default) means to process keystrokes normally; IGNORE means to",
-" ignore them when the screen is scrolled back; RESTORE-AND-SEND is like",
-" SEND but restores the screen to its active position first.",
-" ",
-
-"SET TERMINAL SCREEN-MODE { NORMAL, REVERSE }",
-" When set to REVERSE the foreground and background colors are swapped as",
-" well as the application of the foreground and background intensity bits.",
-" The default is NORMAL.",
-" ",
-
-"SET TERMINAL SCREEN-OPTIMIZE { ON, OFF }",
-" When set to ON, the default, Kermit only paints the screen with characters",
-" that have changed since the last screen paint. When OFF, the screen is",
-" completely repainted each time there is a change.",
-" ",
-
-"SET TERMINAL SCREEN-UPDATE { FAST, SMOOTH } [ <milliseconds> ]",
-" Chooses the mechanism used for screen updating and the update frequency.",
-" Defaults are FAST scrolling with updates every 100 milliseconds.",
-" ",
-
-"SET TERMINAL SCROLLBACK <lines>",
-" Sets size of CONNECT virtual screen buffer. <lines> includes the active",
-" terminal screen. The minimum is 256. The maximum is 2 million. The",
-" default is 2000.",
-" ",
-
-"SET TERMINAL SEND-DATA { ON, OFF }",
-" Determines whether ASCII emulations such as WYSE 30,50,60 or TVI 910+,925,",
-" 950 may send their screen contents to the host upon request. Allowing the",
-" screen to be read by the host is a significant security risk. The default",
-" is OFF and should only be changed after a security evaluation of host",
-" environment.",
-" ",
-
-"SET TERMINAL SEND-END-OF-BLOCK { CRLF_ETX, US_CR }",
-" Determines which set of characters should be used as end of line and end",
-" of transmission indicators when sending screen data to the host",
-" ",
-
-"SET TERMINAL SGR-COLORS { ON, OFF }",
-" ON (default) means allow host control of colors; OFF means ignore host",
-" escape sequences to set color.",
-" ",
-
-"SET TERMINAL SNI-CH.CODE { ON, OFF }",
-" This command controls the state of the CH.CODE key. It is the equivalent",
-" to the SNI_CH_CODE Keyboard verb. The SNI terminal uses CH.CODE to",
-" easily switch between the National Language character set and U.S. ASCII.",
-" The default is ON which means to display characters as U.S. ASCII. When",
-" OFF the lanuage specified by SET TERMINAL SNI-LANUAGE is used to display",
-" characters when 7-bit character sets are in use."
-" ",
-"SET TERMINAL SNI-FIRMWARE-VERSIONS <kbd-version> <terminal-version>",
-" Specifies the Firmware Version number that should be reported to the host",
-" when the terminal is queried. The default is 920031 for the keyboard",
-" and 830851 for the terminal.",
-" ",
-"SET TERMINAL SNI-LANGUAGE <national-language>",
-" An alias for SET TERMINAL VT-LANUAGE, this command specifies the national",
-" language character-set that should be used when the NRC mode is activated",
-" for VT emulations or when CH.CODE is OFF for SNI emulations. The default",
-" language for SET TERMINAL TYPE SNI-97801 is \"German\".",
-" ",
-"SET TERMINAL SNI-PAGEMODE { ON, OFF }",
-" Determines whether or not page mode is active. OFF by default.",
-" ",
-"SET TERMINAL SNI-SCROLLMODE { ON, OFF }",
-" Determines whether or not scroll mode is active. OFF by default.",
-" ",
-"SET TERMINAL STATUSLINE { ON, OFF }",
-" ON (default) enables the Kermit status line in the terminal screen.",
-" OFF removes it, making the line available for use by the host.",
-" ",
-
-"SET TERMINAL TRANSMIT-TIMEOUT <seconds>",
-" Specifies the maximum amount of time K-95 waits before returning to the",
-" prompt if your keystrokes can't be transmitted for some reason, such as a",
-" flow-control deadlock.",
-" ",
-#endif /* OS2 */
-
-#ifdef CK_TRIGGER
-"SET TERMINAL TRIGGER <string>",
-" Specifies a string that, when detected during any subsequent CONNECT",
-" session, is to cause automatic return to command mode. Give this command",
-" without a string to cancel the current trigger. See HELP CONNECT for",
-" additional information.",
-" ",
-#endif /* CK_TRIGGER */
-
-#ifdef OS2
-"SET TERMINAL URL-HIGHLIGHT { ON <attribute>, OFF }",
-" Specifies whether K-95 should highlight URLs and which screen attribute",
-" should be used. The screen attributes can be one of NORMAL, BLINK, BOLD,",
-" DIM, INVISIBLE, REVERSE, or UNDERLINE. The default is ON using the",
-" BOLD screen attribute.",
-" ",
-"SET TERMINAL VIDEO-CHANGE { DISABLED, ENABLED }",
-" Specifies whether K-95 should change video modes automatically in response",
-#ifdef NT
-" to escape sequences from the other computer. ENABLED by default (except",
-" on Windows 95).",
-#else /* NT */
-" to escape sequences from the other computer. ENABLED by default.",
-#endif /* NT */
-" ",
-
-"SET TERMINAL VT-LANGUAGE <language>",
-" Specifies the National Replacement Character Set (NRC) to be used when",
-" NRC mode is activated. The default is \"North American\".",
-" ",
-"SET TERMINAL VT-NRC-MODE { ON, OFF }",
-" OFF (default) chooses VT multinational Character Set mode. OFF chooses",
-" VT National Replacement Character-set mode. The NRC is selected with",
-" SET TERMINAL VT-LANGUAGE",
-" ",
-
-#ifdef NT
-"SET TERMINAL WIDTH <cols>",
-" Tells the number of columns in the terminal screen.",
-" ",
-" The default is 80. You can also use 132. Other widths can be chosen but",
-" are usually not supported by host software.",
-" ",
-#else
-"SET TERMINAL WIDTH <cols>",
-" Tells how many columns define the terminal size.",
-" ",
-"Default is 80. In Windowed OS/2 2.x sessions, this value may not be changed",
-"In Windowed OS/2 WARP 3.x sessions, this value may range from 20 to 255.",
-"In Full screen sessions, values of 40, 80, and 132 are valid. Not all",
-"combinations of height and width are supported on all adapters.",
-" ",
-#endif /* NT */
-"SET TERMINAL WRAP { OFF, ON }",
-" Tells whether the terminal emulator should automatically wrap long lines",
-" on your screen.",
-" ",
-#else
-
-"SET TERMINAL WIDTH <number>",
-" \
-Tells Kermit how many columns (characters) are on your CONNECT-mode screen.",
-" ",
-#endif /* OS2 */
-"Type SHOW TERMINAL to see current terminal settings.",
-"" };
-#endif /* NOLOCAL */
-
-#ifdef NETCONN
-static char *hxyhost[] = {
-"SET HOST [ switches ] hostname-or-address [ service ] [ protocol-switch ]",
-" Establishes a connection to the specified network host on the currently",
-" selected network type. For TCP/IP connections, the default service is",
-" TELNET; specify a different TCP port number or service name to choose a",
-" different service. The first set of switches can be:",
-" ",
-" /NETWORK-TYPE:name",
-" Makes the connection on the given type of network. Equivalent to SET",
-" NETWORK TYPE name prior to SET HOST, except that the selected network",
-" type is used only for this connection. Type \"set host /net:?\" to see",
-#ifdef NETCMD
-" a list. /NETWORK-TYPE:COMMAND means to make the connection through the",
-" given system command, such as \"rlogin\" or \"cu\".",
-#else
-" a list.",
-#endif /* NETCMD */
-" ",
-" /CONNECT",
-" \
-Enter CONNECT (terminal) mode automatically if the connection is successful.",
-" ",
-" /SERVER",
-" Enter server mode automatically if the connection is successful.",
-" ",
-" /USERID:[<name>]",
-" This switch is equivalent to SET LOGIN USERID <name> or SET TELNET",
-" ENVIRONMENT USER <name>. If a string is given, it sent to host during",
-" Telnet negotiations; if this switch is given but the string is omitted,",
-" no user ID is sent to the host. If this switch is not given, your",
-" current USERID value, \\v(userid), is sent. When a userid is sent to the",
-" host it is a request to login as the specified user.",
-" ",
-#ifdef CK_AUTHENTICATION
-" /PASSWORD:[<string>]",
-" This switch is equivalent to SET LOGIN PASSWORD. If a string is given,",
-" it is treated as the password to be used (if required) by any Telnet",
-" Authentication protocol (Kerberos Ticket retrieval, Secure Remote",
-" Password, or X.509 certificate private key decryption.) If no password",
-" switch is specified a prompt is issued to request the password if one",
-" is required for the negotiated authentication method.",
-" ",
-#endif /* CK_AUTHENTICATION */
-"The protocol-switches can be:",
-" ",
-" /NO-TELNET-INIT",
-" Do not send initial Telnet negotiations even if this is a Telnet port.",
-" ",
-" /RAW-SOCKET",
-" This is a connection to a raw TCP socket.",
-" ",
-#ifdef RLOGCODE
-" /RLOGIN",
-" Use Rlogin protocol even if this is not an Rlogin port.",
-" ",
-#endif /* RLOGCODE */
-" /TELNET",
-" Send initial Telnet negotiations even if this is not a Telnet port.",
-" ",
-#ifdef CK_KERBEROS
-#ifdef RLOGCODE
-#ifdef KRB4
-" /K4LOGIN",
-" Use Kerberos IV klogin protocol even if this is not a klogin port.",
-" ",
-#ifdef CK_ENCRYPTION
-" /EK4LOGIN",
-" Use Kerberos IV Encrypted login protocol even if this is not an eklogin",
-" port.",
-" ",
-#endif /* CK_ENCRYPTION */
-#endif /* KRB4 */
-#ifdef KRB5
-" /K5LOGIN",
-" Use Kerberos V klogin protocol even if this is not a klogin port.",
-" ",
-#ifdef CK_ENCRYPTION
-" /EK5LOGIN",
-" Use Kerberos V Encrypted login protocol even if this is not an eklogin",
-" port.",
-" ",
-#endif /* CK_ENCRYPTION */
-#endif /* KRB5 */
-#endif /* RLOGCODE */
-#endif /* CK_KERBEROS */
-#ifdef CK_SSL
-" /SSL",
-" Perform SSL negotiations.",
-" ",
-" /SSL-TELNET",
-" Perform SSL negotiations and if successful start Telnet negotiations.",
-" ",
-" /TLS",
-" Perform TLS negotiations.",
-" ",
-" /TLS-TELNET",
-" Perform TLS negotiations and if successful start Telnet negotiations.",
-" ",
-#endif /* CK_SSL */
-"Examples:",
-" SET HOST kermit.columbia.edu",
-" SET HOST /CONNECT kermit.columbia.edu",
-" SET HOST * 1649",
-" SET HOST /SERVER * 1649",
-" SET HOST 128.59.39.2",
-" SET HOST madlab.sprl.umich.edu 3000",
-" SET HOST xyzcorp.com 2000 /RAW-SOCKET",
-#ifdef SSHBUILTIN
-" SET HOST /NET:SSH kermit.columbia.edu /x11-forwarding:on",
-#endif /* SSHBUILTIN */
-#ifdef NETCMD
-" SET HOST /CONNECT /COMMAND rlogin xyzcorp.com",
-#endif /* NETCMD */
-" ",
-#ifdef SUPERLAT
-"Notes:",
-" ",
-" . The TELNET command is equivalent to SET NETWORK TYPE TCP/IP,",
-" SET HOST name [ port ] /TELNET, IF SUCCESS CONNECT",
-" ",
-" . For SUPERLAT connections, the hostname-or-address may be either a service",
-" name, or a node/port combination, as required by your LAT host.",
-#else
-"The TELNET command is equivalent to SET NETWORK TYPE TCP/IP,",
-"SET HOST name [ port ] /TELNET, IF SUCCESS CONNECT",
-#endif /* SUPERLAT */
-" ",
-"Also see SET NETWORK, TELNET, SET TELNET.",
-"" };
-
-static char *hmxyauth[] = {
-"Synatx: SET AUTHENTICATION <auth_type> <parameter> <value>",
-" Sets defaults for the AUTHENTICATE command:",
-" ",
-#ifdef CK_KERBEROS
-"SET AUTHENTICATION KERBEROS5 ADDRESSES {list of ip-addresses}",
-" Specifies a list of IP addresses that should be placed in the Ticket",
-" Getting Ticket in addition to the local machine addresses.",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } AUTODESTROY",
-" { ON-CLOSE, ON-EXIT, NEVER }",
-" When ON, Kermit will destroy all credentials in the default",
-" credentials cache upon Kermit termination. Default is NEVER.",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } AUTOGET { ON, OFF }",
-" When ON, if the host offers Kerberos 4 or Kerberos 5 authentication",
-" and Kermit is configured to use that authentication method and there",
-" is no TGT, Kermit will automatically attempt to retrieve one by",
-" prompting for the password (and principal if needed.) Default is ON.",
-" ",
-"SET AUTHENTICATION KERBEROS5 CREDENTIALS-CACHE <filename>",
-" Allows an alternative credentials cache to be specified. This is useful",
-" when you need to maintain two or more sets of credentials for different",
-" realms or roles. The default is specified by the environment variable",
-" KRB5CCNAME or as reported by the Kerberos 5 library.",
-" ",
-"SET AUTHENTICATION KERBEROS5 FORWARDABLE { ON, OFF }",
-" When ON, specifies that Kerberos 5 credentials should be forwardable to",
-" the host. If SET TELNET AUTHENTICATION FORWARDING is ON, forwardable",
-" credentials are sent to the host. The default is OFF.",
-" ",
-"SET AUTHENTICATION KERBEROS5 GET-K4-TGT { ON, OFF }",
-" When ON, specifies that Kerberos 4 credentials should be requested each",
-" time Kerberos 5 credentials are requested with AUTH KERBEROS5 INIT.",
-" Default is OFF.",
-" ",
-"SET AUTHENTICATION KERBEROS4 INSTANCE <instance>",
-" Allows a Kerberos 4 instance to be specified as a default (if needed).",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } KEYTAB <filename>",
-" Specifies the location of the keytab file used to authenticate incoming",
-" connections. The default is none, which means to use the default value",
-" configured in the Kerberos installation.",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } LIFETIME <minutes>",
-" Specifies the lifetime of the TGTs requested from the KDC. The default",
-" is 600 minutes (10 hours).",
-" ",
-"SET AUTHENTICATION KERBEROS5 NO-ADDRESSES { ON, OFF }",
-" Specifies whether or not IP addresses will be inserted into the TGT."
-" Default is OFF.",
-" ",
-"SET AUTHENTICATION KERBEROS4 PREAUTH { ON, OFF }",
-" Allows Kerberos 4 preauthenticated TGT requests to be turned off. The",
-" default is ON. Only use if absolutely necessary. We recommend that",
-" preauthenticated requests be required for all tickets returned by a KDC",
-" to a requestor.",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } PRINCIPAL <name>",
-" When Kermit starts, it attempts to set the principal name to that stored",
-" in the current credentials cache. If no credential cache exists, the",
-" current SET LOGIN USERID value is used. SET LOGIN USERID is set to the",
-" operating system's current username when Kermit is started. To force",
-" Kermit to prompt the user for the principal name when requesting TGTs,",
-" place:",
-" ",
-" SET AUTH K4 PRINCIPAL {}",
-" SET AUTH K5 PRINCIPAL {}",
-" ",
-" in the Kermit initialization file or connection script.",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } PROMPT PASSWORD <prompt>",
-" Specifies a custom prompt to be used when prompting for a password.",
-" The Kerberos prompt strings may contain two %s replacement fields.",
-" The first %s is replaced by the principal name; the second by the realm.",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } PROMPT PRINCIPAL <prompt>",
-" Specifies a custom prompt to be used when prompting for the Kerberos",
-" principal name. No %s replacement fields may be used. Kermit prompts",
-" for a principal name when retrieving a TGT if the command:",
-" ",
-" SET AUTHENTICATION { KERBEROS4, KERBEROS5 } PRINCIPAL {}",
-" ",
-" has been issued.",
-" ",
-"SET AUTHENTICATION KERBEROS5 PROXIABLE { ON, OFF }",
-" When ON, specifies that Kerberos 5 credentials should be proxiable.",
-" Default is OFF.",
-" ",
-"SET AUTHENTICATION KERBEROS5 RENEWABLE <minutes>",
-" When <minutes> is greater than the ticket lifetime a TGT may be renewed",
-" with AUTH K5 INIT /RENEW instead of getting a new ticket as long as the",
-" ticket is not expired and its within the renewable lifetime. Default is",
-" 0 (zero) minutes.",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } REALM <name>",
-" If no default is set, the default realm configured for the Kerberos",
-" libraries is used. Abbreviations accepted.",
-" ",
-"SET AUTHENTICATION { KERBEROS4, KERBEROS5 } SERVICE-NAME <name>",
-" This command specifies the service ticket name used to authenticate",
-" to the host when Kermit is used as a client; or the service ticket",
-" name accepted by Kermit when it is acting as the host.",
-" If no default is set, the default service name for Kerberos 4 is",
-" \"rcmd\" and for Kerberos 5 is \"host\".",
-" ",
-#endif /* CK_KERBEROS */
-#ifdef CK_SRP
-"SET AUTHENTICATION SRP PROMPT PASSWORD <prompt>",
-" Specifies a custom prompt to be used when prompting for a password.",
-" The SRP prompt string may contain one %s replacement fields which is",
-" replaced by the login userid.",
-" ",
-#endif /* CK_SRP */
-#ifdef CK_SSL
-"In all of the following commands \"SSL\" and \"TLS\" are aliases.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } CIPHER-LIST <list of ciphers>",
-"Applies to both SSL and TLS. A colon separated list of any of the following",
-"(case sensitive) options depending on the options chosen when OpenSSL was ",
-"compiled: ",
-" ",
-" Key Exchange Algorithms:",
-" \"kRSA\" RSA key exchange",
-" \"kDHr\" Diffie-Hellman key exchange (key from RSA cert)",
-" \"kDHd\" Diffie-Hellman key exchange (key from DSA cert)",
-" \"kEDH\" Ephemeral Diffie-Hellman key exchange (temporary key)",
-" \"kKRB5\" Kerberos 5",
-" ",
-" Authentication Algorithm:",
-" \"aNULL\" No authentication",
-" \"aRSA\" RSA authentication",
-" \"aDSS\" DSS authentication",
-" \"aDH\" Diffie-Hellman authentication",
-" \"aKRB5\" Kerberos 5",
-" ",
-" Cipher Encoding Algorithm:",
-" \"eNULL\" No encodiing",
-" \"DES\" DES encoding",
-" \"3DES\" Triple DES encoding",
-" \"RC4\" RC4 encoding",
-" \"RC2\" RC2 encoding",
-" \"IDEA\" IDEA encoding",
-" ",
-" MAC Digest Algorithm:",
-" \"MD5\" MD5 hash function",
-" \"SHA1\" SHA1 hash function",
-" \"SHA\" SHA hash function (should not be used)",
-" ",
-" Aliases:",
-" \"SSLv2\" all SSL version 2.0 ciphers (should not be used)",
-" \"SSLv3\" all SSL version 3.0 ciphers",
-" \"EXP\" all export ciphers (40-bit)",
-" \"EXPORT56\" all export ciphers (56-bit)",
-" \"LOW\" all low strength ciphers (no export)",
-" \"MEDIUM\" all ciphers with 128-bit encryption",
-" \"HIGH\" all ciphers using greater than 128-bit encryption",
-" \"RSA\" all ciphers using RSA key exchange",
-" \"DH\" all ciphers using Diffie-Hellman key exchange",
-" \"EDH\" all ciphers using Ephemeral Diffie-Hellman key exchange",
-" \"ADH\" all ciphers using Anonymous Diffie-Hellman key exchange",
-" \"DSS\" all ciphers using DSS authentication",
-" \"KRB5\" all ciphers using Kerberos 5 authentication",
-" \"NULL\" all ciphers using no encryption",
-" ",
-"Each item in the list may include a prefix modifier:",
-" ",
-" \"+\" move cipher(s) to the current location in the list",
-" \"-\" remove cipher(s) from the list (may be added again by",
-" a subsequent list entry)",
-" \"!\" kill cipher from the list (it may not be added again",
-" by a subsequent list entry)",
-" ",
-"If no modifier is specified the entry is added to the list at the current ",
-"position. \"+\" may also be used to combine tags to specify entries such as "
-,
-"\"RSA+RC4\" describes all ciphers that use both RSA and RC4.",
-" ",
-"For example, all available ciphers not including ADH key exchange:",
-" ",
-" ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP",
-" ",
-"All algorithms including ADH and export but excluding patented algorithms: ",
-" ",
-" HIGH:MEDIUM:LOW:EXPORT56:EXP:ADH:!kRSA:!aRSA:!RC4:!RC2:!IDEA",
-" ",
-"The OpenSSL command ",
-" ",
-" openssl.exe ciphers -v <list of ciphers> ",
-" ",
-"may be used to list all of the ciphers and the order described by a specific",
-"<list of ciphers>.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } CRL-DIR <directory>",
-"specifies a directory that contains certificate revocation files where each",
-"file is named by the hash of the certificate that has been revoked.",
-" ",
-" OpenSSL expects the hash symlinks to be made like this:",
-" ",
-" ln -s crl.pem `openssl crl -hash -noout -in crl.pem`.r0",
-" ",
-" Since not all file systems have symlinks you can use the following command",
-" in Kermit to copy the crl.pem file to the hash file name.",
-" ",
-" copy crl.pem {\\fcommand(openssl.exe crl -hash -noout -in crl.pem).r0}",
-" ",
-" This produces a hash based on the issuer field in the CRL such ",
-" that the issuer field of a Cert may be quickly mapped to the ",
-" correct CRL.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } CRL-FILE <filename>",
-"specifies a file that contains a list of certificate revocations.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } DEBUG { ON, OFF }",
-"specifies whether debug information should be displayed about the SSL/TLS",
-"connection. When DEBUG is ON, the VERIFY command does not terminate",
-"connections when set to FAIL-IF-NO-PEER-CERT when a certificate is",
-"presented that cannot be successfully verified. Instead each error",
-"is displayed but the connection automatically continues.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } DH-PARAM-FILE <filename>",
-" Specifies a file containing DH parameters which are used to generate",
-" temporary DH keys. If a DH parameter file is not provided Kermit uses a",
-" fixed set of parameters depending on the negotiated key length. Kermit",
-" provides DH parameters for key lengths of 512, 768, 1024, 1536, and 2048",
-" bits.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } DSA-CERT-CHAIN-FILE <filename>",
-" Specifies a file containing a DSA certificate chain to be sent along with",
-" the DSA-CERT to the peer. This file must only be specified if Kermit is",
-" being used as a server and the DSA certificate was signed by an",
-" intermediary certificate authority.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } DSA-CERT-FILE <filename>",
-" Specifies a file containing a DSA certificate to be sent to the peer to ",
-" authenticate the host or end user. The file may contain the matching DH ",
-" private key instead of using the DSA-KEY-FILE command.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } DSA-KEY-FILE <filename>",
-"Specifies a file containing the private DH key that matches the DSA ",
-"certificate specified with DSA-CERT-FILE. This command is only necessary if",
-"the private key is not appended to the certificate in the file specified by",
-"DSA-CERT-FILE.",
-" ",
-" Note: When executing a script in the background or when it is",
-" running as an Internet Kermit Service Daemon, Kermit cannot support ",
-" encrypted private keys. When attempting to load a private key that is",
-" encrypted, a prompt will be generated requesting the passphrase necessary",
-" to decrypt the keyfile. To automate access to the private key you must",
-" decrypt the encrypted keyfile and create an unencrypted keyfile for use",
-" by Kermit. This can be accomplished by using the following command and",
-" the passphrase:",
-" ",
-" openssl dsa -in <encrypted-key-file> -out <unencrypted-key-file>",
-" ",
-"SET AUTHENTICATION { SSL, TLS } RANDOM-FILE <filename>",
-" Specifies a file containing random data to be used as seed for the",
-" Pseudo Random Number Generator. The contents of the file are",
-" overwritten with new random data on each use.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } RSA-CERT-CHAIN-FILE <filename>",
-" Specifies a file containing a RSA certificate chain to be sent along with",
-" the RSA-CERT to the peer. This file must only be specified if Kermit is",
-" being used as a server and the RSA certificate was signed by an",
-" intermediary certificate authority.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } RSA-CERT-FILE <filename>",
-" Specifies a file containing a RSA certificate to be sent to the peer to ",
-" authenticate the host or end user. The file may contain the matching RSA ",
-" private key instead of using the RSA-KEY-FILE command.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } RSA-KEY-FILE <filename>",
-" Specifies a file containing the private RSA key that matches the RSA",
-" certificate specified with RSA-CERT-FILE. This command is only necessary",
-" if the private key is not appended to the certificate in the file specified"
-,
-" by RSA-CERT-FILE. ",
-" ",
-" Note: When executing a script in the background or when it is",
-" running as an Internet Kermit Service Daemon, Kermit cannot support ",
-" encrypted private keys. When attempting to load a private key that is",
-" encrypted, a prompt will be generated requesting the passphrase necessary",
-" to decrypt the keyfile. To automate access to the private key you must",
-" decrypt the encrypted keyfile and create an unencrypted keyfile for use",
-" by Kermit. This can be accomplished by using the following command and",
-" the passphrase:",
-" ",
-" openssl rsa -in <encrypted-key-file> -out <unencrypted-key-file>",
-" ",
-"SET AUTHENTICATION { SSL, TLS } VERBOSE { ON, OFF }",
-" Specifies whether information about the authentication (ie, the",
-" certificate chain) should be displayed upon making a connection.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } VERIFY { NO,PEER-CERT,FAIL-IF-NO-PEER-CERT }",
-" Specifies whether certificates should be requested from the peer verified;",
-" whether they should be verified when they are presented; and whether they",
-" should be required. When set to NO (the default for IKSD), Kermit does",
-" not request that the peer send a certificate; if one is presented it is",
-" ignored. When set to PEER-CERT (the default when not IKSD), Kermit",
-" requests a certificate be sent by the peer. If presented, the certificate",
-" is verified. Any errors during the verification process result in",
-" queries to the end user. When set to FAIL-IF-NO-PEER-CERT, Kermit",
-" requests a certificate be sent by the peer. If the certificate is not",
-" presented or fails to verify, the connection is terminated without",
-" querying the user.",
-" ",
-" If an anonymous cipher (i.e., ADH) is desired, the NO setting must be",
-" used. Otherwise, the receipt of the peer certificate request is",
-" interpreted as a protocol error and the negotiation fails.",
-" ",
-" If you wish to allow the peer to authenticate using either an X509",
-" certificate to userid mapping function or via use of a ~/.tlslogin file",
-" you must use either PEER-CERT or FAIL-IF-NO-PEER-CERT. Otherwise, any",
-" certificates that are presented is ignored. In other words, use NO if you",
-" want to disable the ability to use certificates to authenticate a peer.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } VERIFY-DIR <directory>",
-" Specifies a directory that contains root CA certificate files used to",
-" verify the certificate chains presented by the peer. Each file is named",
-" by a hash of the certificate.",
-" ",
-" OpenSSL expects the hash symlinks to be made like this:",
-" ",
-" ln -s cert.pem `openssl x509 -hash -noout -in cert.pem`.0",
-" ",
-" Since not all file systems have symlinks you can use the following command",
-" in Kermit to copy the cert.pem file to the hash file name.",
-" ",
-" copy cert.pem {\\fcommand(openssl.exe x509 -hash -noout -in cert.pem).0}",
-" ",
-" This produces a hash based on the subject field in the cert such that the",
-" certificate may be quickly found.",
-" ",
-"SET AUTHENTICATION { SSL, TLS } VERIFY-FILE <file>",
-" Specifies a file that contains root CA certificates to be used for",
-" verifying certificate chains.",
-" ",
-#endif /* CK_SSL */
-""
-};
-
-static char *hxynet[] = {
-"Syntax: SET NETWORK { TYPE network-type, DIRECTORY [ file(s)... ] }",
-" ",
-"Select the type of network to be used with SET HOST connections:",
-" ",
-#ifdef NETCMD
-" SET NETWORK TYPE COMMAND ; Make a connection through an external command",
-#endif /* NETCMD */
-#ifdef TCPSOCKET
-" SET NETWORK TYPE TCP/IP ; Internet: Telnet, Rlogin, etc.",
-#endif /* TCPSOCKET */
-#ifdef ANYX25
-" SET NETWORK TYPE X.25 ; X.25 peer-to-peer connections.",
-#endif /* ANYX25 */
-#ifdef DECNET
-" SET NETWORK TYPE PATHWORKS { LAT, CTERM } ; DEC LAT or CTERM connections.",
-#endif /* DECNET */
-#ifdef NPIPE
-" SET NETWORK TYPE NAMED-PIPE <pipename> ; OS/2 Named Pipe connections.",
-#endif /* NPIPE */
-#ifdef CK_NETBIOS
-" SET NETWORK TYPE NETBIOS ; NETBIOS peer-to-peer connections",
-#endif /* CK_NETBIOS */
-#ifdef SUPERLAT
-" SET NETWORK TYPE SUPERLAT ; LAT connections (Meridian Technology SuperLAT)",
-#endif /* SUPERLAT */
-" ",
-"If only one network type is listed above, that is the default network for",
-#ifdef RLOGCODE
-"SET HOST commands. Also see SET HOST, TELNET, RLOGIN.",
-#else
-#ifdef TNCODE
-"SET HOST commands. Also see SET HOST, TELNET.",
-#else
-"SET HOST commands. Also see SET HOST.",
-#endif /* TNCODE */
-#endif /* RLOGCODE */
-" ",
-"SET NETWORK DIRECTORY [ file [ file [ ... ] ] ]",
-" Specifies the name(s) of zero or more network directory files, similar to",
-" dialing directories (HELP DIAL for details). The general format of a",
-" network directory entry is:",
-" ",
-" name network-type address [ network-specific-info ] [ ; comment ]",
-" ",
-" For TCP/IP, the format is:",
-" ",
-" name tcp/ip ip-hostname-or-address [ socket ] [ ; comment ]",
-" ",
-"You can have multiple network directories and you can have multiple entries",
-"with the same name. SET HOST <name> and TELNET <name> commands look up the",
-"given <name> in the directory and, if found, fill in the additional items",
-"from the entry, and then try all matching entries until one succeeds.",
-""};
-
-#ifndef NOTCPOPTS
-static char *hxytcp[] = {
-#ifdef SOL_SOCKET
-"SET TCP ADDRESS <ip-address>",
-" This allows a specific IP Address on a multihomed host to be used",
-" instead of allowing the TCP/IP stack to choose. This may be necessary",
-" when using authentication or listening for an incoming connection.",
-" Specify no <ip-address> to remove the preference.",
-" ",
-"SET TCP KEEPALIVE { ON, OFF }",
-" Setting this ON might help to detect broken connections more quickly.",
-" (default is ON.)",
-" ",
-"SET TCP LINGER { ON [timeout], OFF }",
-" Setting this ON ensures that a connection doesn't close before all",
-" outstanding data has been transferred and acknowledged. The timeout is",
-" measured in 10ths of milliseconds. The default is ON with a timeout of 0.",
-" ",
-"SET TCP NODELAY { ON, OFF }",
-" ON means send short TCP packets immediately rather than waiting",
-" to accumulate a bunch of them before transmitting (Nagle Algorithm).",
-" (default is OFF.)",
-" ",
-"SET TCP RECVBUF <number>",
-"SET TCP SENDBUF <number>",
-" TCP receive and send buffer sizes. (default is -1, use system defaults.)",
-" ",
-"These items let you tune TCP networking performance on a per-connection",
-"basis by adjusting parameters you normally would not have access to. You",
-"should use these commands only if you feel that the TCP/IP protocol stack",
-"that Kermit is using is giving you inadequate performance, and then only if",
-"you understand the concepts (see, for example, the Comer TCP/IP books), and",
-"then at your own risk. These settings are displayed by SHOW NETWORK. Not",
-"all options are necessarily available in all Kermit versions; it depends on",
-"the underlying TCP/IP services.",
-" ",
-"The following TCP and/or IP parameter(s) may also be changed:",
-" ",
-#endif /* SOL_SOCKET */
-"SET TCP REVERSE-DNS-LOOKUP { AUTO, ON, OFF }",
-" Tells Kermit whether to perform reverse DNS lookup on TCP/IP connections",
-" so Kermit can determine the actual hostname of the host it is connected",
-" to, which is useful for connections to host pools, and is required for",
-" Kerberos connections to host pools and for incoming connections. If the",
-" other host does not have a DNS entry, the reverse lookup could take a long",
-" time (minutes) to fail, but the connection will still be made. Turn this",
-" option OFF for speedier connections if you do not need to know exactly",
-" which host you are connected to and you are not using Kerberos. AUTO, the",
-" default, means the lookup is done on hostnames, but not on numeric IP",
-" addresses unless Kerberos support is installed.",
-#ifdef CK_DNS_SRV
-" ",
-"SET TCP DNS-SERVICE-RECORDS {ON, OFF}",
-" Tells Kermit whether to try to use DNS SRV records to determine the",
-" host and port number upon which to find an advertised service. For",
-" example, if a host wants regular Telnet connections redirected to some",
-" port other than 23, this feature allows Kermit to ask the host which",
-" port it should use. Since not all domain servers are set up to answer",
-" such requests, this feature is OFF by default.",
-#endif /* CK_DNS_SRV */
-#ifdef NT
-#ifdef CK_SOCKS
-" ",
-"SET TCP SOCKS-SERVER [<hostname or ip-address>]",
-" If a hostname or ip-address is specified, Kermit will use the SOCKS",
-" server when attempting outgoing connections. If no hostname or",
-" ip-address is specified, any previously specified SOCKS server will",
-" be removed.",
-#endif /* CK_SOCKS */
-#endif /* NT */
-#ifndef NOHTTP
-" ",
-"SET TCP HTTP-PROXY [<hostname or ip-address>[:<port>]]",
-" If a hostname or ip-address is specified, Kermit will use the Proxy",
-" server when attempting outgoing connections. If no hostname or",
-" ip-address is specified, any previously specified Proxy server will",
-" be removed. If no port number is specified, the \"http\" service",
-" will be used.",
-#endif /* NOHTTP */
-""};
-#endif /* NOTCPOPTS */
-#endif /* NETCONN */
-
-#ifdef TNCODE
-static char *hxytopt[] = {
-"SET TELOPT [ { /CLIENT, /SERVER } ] <option> -",
-" { ACCEPTED, REFUSED, REQUESTED, REQUIRED } -",
-" [ { ACCEPTED, REFUSED, REQUESTED, REQUIRED } ]",
-" SET TELOPT lets you specify policy requirements for Kermit's handling of",
-" Telnet option negotiations. Setting an option REQUIRED causes Kermit",
-" to offer the option to the peer and disconnect if the option is refused.",
-" REQUESTED causes Kermit to offer an option to the peer. ACCEPTED results",
-" in no offer but Kermit will attempt to negotiate the option if it is",
-" requested. REFUSED instructs Kermit to refuse the option if it is",
-" requested by the peer.",
-" ",
-" Some options are negotiated in two directions and accept separate policies",
-" for each direction; the first keyword applies to Kermit itself, the second",
-" applies to Kermit's Telnet partner; if the second keyword is omitted, an",
-" appropriate (option-specific) default is applied. You can also include a",
-" /CLIENT or /SERVER switch to indicate whether the given policies apply",
-" when Kermit is the Telnet client or the Telnet server; if no switch is",
-" given, the command applies to the client.",
-" ",
-" Note that some of Kermit's Telnet partners fail to refuse options that",
-" they do not recognize and instead do not respond at all. In this case it",
-" is possible to use SET TELOPT to instruct Kermit to REFUSE the option",
-" before connecting to the problem host, thus skipping the problematic",
-" negotiation.",
-" ",
-" Use SHOW TELOPT to view current Telnet Option negotiation settings.",
-" SHOW TELNET displays current Telnet settings.",
-""};
-
-static char *hxytel[] = {
-"Syntax: SET TELNET parameter value",
-" ",
-"For TCP/IP TELNET connections, which are in NVT (ASCII) mode by default:",
-" ",
-#ifdef CK_AUTHENTICATION
-#ifdef COMMENT
-"SET TELNET AUTHENICATION { ACCEPTED, REFUSED, REQUESTED, REQUIRED }",
-" ACCEPT or REFUSE authentication bids, or actively REQUEST authentication.",
-" REQUIRED refuses the connection if authentication is not successfully",
-" negotiated. ACCEPTED by default.",
-" ",
-#endif /* COMMENT */
-"SET TELNET AUTHENTICATION TYPE { AUTOMATIC, KERBEROS_IV, KERBEROS_V, ...",
-#ifdef NT
-" ..., NTLM, SSL, SRP, NONE } [...]",
-#else /* NT */
-" ..., SSL, SRP, NONE } [...]",
-#endif /* NT */
-" AUTOMATIC is the default. Available options can vary depending on the",
-" features Kermit was built to support and the operating system",
-" configuration; type SET TELNET AUTHENTICATION TYPE ? for a list.",
-" ",
-" When Kermit is the Telnet client:",
-" AUTOMATIC allows the host to choose the preferred type of authentication."
-,
-" NONE instructs Kermit to refuse all authentication methods when the",
-" authentication option is negotiated. A list of one or more other values",
-" allow a specific subset of the supported authentication methods to be",
-" used.",
-" ",
-" When Kermit is the Telnet server:",
-" AUTOMATIC results in available authentication methods being offered",
-" to the telnet client in the following order:",
-" ",
-#ifdef NT
-" KERBEROS_V, KERBEROS_IV, SRP, SSL, NTLM",
-#else /* NT */
-" KERBEROS_V, KERBEROS_IV, SRP, SSL, NTLM",
-#endif /* NT */
-" ",
-" NONE results in no authentication methods being offered to the Telnet",
-" server when the authentication option is negotiated. The preferred",
-" method of disabling authentication is:",
-" ",
-" SET TELOPT /SERVER AUTHENTICATION REFUSE",
-" ",
-" A list of one or more authentication methods specifies the order those",
-" methods are to be offered to the telnet client.",
-#ifdef NT
-" ",
-" If you wish to allow NTLM authentication to be used with the Microsoft",
-" Windows 2000 or Services for Unix Telnet client you must specify a list",
-" with NTLM as the first item in the list. By default, NTLM is the last",
-" item in the list because it does not provide any form of data encryption.",
-#endif /* NT */
-" ",
-#ifdef CK_KERBEROS
-"SET TELNET AUTHENTICATION FORWARDING { ON, OFF }",
-" Set this to ON to forward Kerberos V ticket-granting-tickets to the host",
-" after authentication is complete. OFF by default.",
-" ",
-#endif /* CK_KERBEROS */
-"SET TELNET AUTHENTICATION ENCRYPT-FLAG { ANY, NONE, TELOPT }",
-" Use this command to specify which AUTH telopt encryption flags may be",
-" accepted in client mode or offered in server mode. The default is ANY.",
-" ",
-"SET TELNET AUTHENTICATION HOW-FLAG { ANY, ONE-WAY, MUTUAL }",
-" Use this command to specify which AUTH telopt how flags may be",
-" accepted in client mode or offered in server mode. The default is ANY.",
-" ",
-#endif /* CK_AUTHENTICATION */
-#ifdef COMMENT
-"SET TELNET BINARY-MODE { ACCEPTED, REFUSED, REQUESTED, REQUIRED }",
-" ACCEPT or REFUSE binary-mode bids, or actively REQUEST binary mode.",
-" REQUIRED refuses the connection if binary mode is not successfully",
-" negotiated in both directions. ACCEPTED by default.",
-" ",
-#endif /* COMMENT */
-"SET TELNET BINARY-TRANSFER-MODE { ON, OFF }",
-" When ON (OFF by default) and BINARY negotiations are not REFUSED Kermit",
-" will attempt to negotiate BINARY mode in each direction before the start",
-" of each file transfer. After the transfer is complete BINARY mode will",
-" be restored to the pre-transfer state.",
-" ",
-"SET TELNET BINARY-TRANSFER-MODE { ON, OFF }",
-" Set this command to ON if you want to force Kermit to negotiate",
-" Telnet Binary in both directions when performing file transfers.",
-" Default is OFF. Alias SET TELNET BINARY-XFER-MODE.",
-" ",
-"SET TELNET BUG AUTH-KRB5-DES { ON, OFF }",
-" Default is ON. Disable this bug to enable the use of encryption types",
-" other than DES such as 3DES or CAST-128 when the Kerberos 5 session key",
-" is longer than 8 bytes.",
-" ",
-"SET TELNET BUG BINARY-ME-MEANS-U-TOO { ON, OFF }",
-" Set this to ON to try to overcome TELNET binary-mode misnegotiations by",
-" Kermit's TELNET partner.",
-" ",
-"SET TELNET BUG BINARY-U-MEANS-ME-TOO { ON, OFF }",
-" Set this to ON to try to overcome TELNET binary-mode misnegotiations by",
-" Kermit's TELNET partner.",
-" ",
-"SET TELNET BUG INFINITE-LOOP-CHECK { ON, OFF }",
-" Set this to ON to prevent Kermit from responding to a telnet negotiation",
-" sequence that enters an infinite loop. The default is OFF because this",
-" should never occur.",
-" ",
-"SET TELNET BUG SB-IMPLIES-WILL-DO { ON, OFF }",
-" Set this to ON to allow Kermit to respond to telnet sub-negotiations if",
-" the peer forgets to respond to WILL with DO or to DO with WILL.",
-" ",
-"SET TELNET DEBUG { ON, OFF }",
-" Set this to ON to display telnet negotiations as they are sent and",
-" received.",
-" ",
-"SET TELNET DELAY-SB { ON, OFF }",
-" When ON, telnet subnegotiation responses are delayed until after all",
-" authentication and encryption options are either successfully negotiated",
-" or refused. This ensures that private data is protected. When OFF, telnet",
-" subnegotiation responses are sent immediately. The default is ON.",
-" ",
-"SET TELNET ECHO { LOCAL, REMOTE }",
-" Kermit's initial echoing state for TELNET connections, LOCAL by default.",
-" After the connection is made, TELNET negotiations determine the echoing.",
-" ",
-#ifdef CK_ENCRYPTION
-#ifdef COMMENT
-"SET TELNET ENCRYPTION { ACCEPTED, REFUSED, REQUESTED, REQUIRED }",
-" ACCEPT or REFUSE encryption bids, or actively REQUEST encryption in both.",
-" directions. REQUIRED refuses the connection if encryption is not",
-" successfully negotiated in both directions. ACCEPTED by default.",
-" ",
-#endif /* COMMENT */
-"SET TELNET ENCRYPTION TYPE { AUTOMATIC, CAST128_CFB64, CAST128_OFB64, ",
-" CAST5_40_CFB64, CAST5_40_OFB64, DES_CFB64, DES_OFB64, NONE }",
-" AUTOMATIC allows the host to choose the preferred type of encryption.",
-" Other values allow a specific encryption method to be specified.",
-" AUTOMATIC is the default. The list of options will vary depending",
-" on the encryption types selected at compilation time.",
-" ",
-#endif /* CK_ENCRYPTION */
-#ifdef CK_ENVIRONMENT
-#ifdef COMMENT
-"SET TELNET ENVIRONMENT { ON, OFF, variable-name [ value ] }",
-" This feature lets Kermit send the values of certain environment variables",
-" to the other computer if it asks for them. The variable-name can be any",
-" of the \"well-known\" variables \"USER\", \"JOB\", \"ACCT\", \"PRINTER\",",
-" \"SYSTEMTYPE\", or \"DISPLAY\". Some Telnet servers, if given a USER",
-" value in this way, will accept it and therefore not prompt you for user",
-" name when you log in. The default values are taken from your environment;",
-" use this command to change or remove them. See RFC1572 for details. You",
-" may also specify OFF to disable this feature, and ON to re-enable it.",
-" ",
-#else
-"SET TELNET ENVIRONMENT { variable-name [ value ] }",
-" This feature lets Kermit send the values of certain environment variables",
-" to the other computer if it asks for them. The variable-name can be any",
-" of the \"well-known\" variables \"USER\", \"JOB\", \"ACCT\", \"PRINTER\",",
-" \"SYSTEMTYPE\", or \"DISPLAY\". Some Telnet servers, if given a USER",
-" value in this way, will accept it and therefore not prompt you for user",
-" name when you log in. The default values are taken from your environment;",
-" use this command to change or remove them. See RFC1572 for details.",
-" ",
-#endif /* COMMENT */
-#endif /* CK_ENVIRONMENT */
-#ifdef CK_FORWARD_X
-"SET TELNET FORWARD-X XAUTHORITY-FILE <file>",
-" If your X Server requires X authentication and the location of the",
-" .Xauthority file is not defined by the XAUTHORITY environment variable,",
-" use this command to specify the location of the .Xauthority file."
-" ",
-#endif /* CK_FORWARD_X */
-#ifdef CK_SNDLOC
-"SET TELNET LOCATION [ text ]",
-" Location string to send to the Telnet server if it asks. By default this",
-" is picked up from the LOCATION environment variable. Give this command",
-" with no text to disable this feature.",
-" ",
-#endif /* CK_SNDLOC */
-"SET TELNET NEWLINE-MODE { NVT, BINARY-MODE } { OFF, ON, RAW }",
-
-" Determines how carriage returns are handled on TELNET connections. There",
-" are separate settings for NVT (ASCII) mode and binary mode. ON (default",
-" for NVT mode) means CRLF represents CR. OFF means CR followed by NUL",
-" represents CR. RAW (default for BINARY mode) means CR stands for itself.",
-" ",
-#ifdef TCPSOCKET
-"SET TELNET PROMPT-FOR-USERID <prompt>",
-" Specifies a custom prompt to be used when prompting for a userid. Kermit",
-" prompts for a userid if the command:",
-" ",
-" SET LOGIN USERID {}",
-" ",
-" has been issued prior to a Telnet authentication negotiation for an",
-" authentication type that requires the transmission of a name, such as",
-" Secure Remote Password.",
-" ",
-#endif /* TCPSOCKET */
-"SET TELNET REMOTE-ECHO { ON, OFF }",
-" Applies only to incoming connections created with:",
-" SET HOST * <port> /TELNET",
-" This command determines whether Kermit will actually echo characters",
-" received from the remote when it has negotiated to do so. The default",
-" is ON. Remote echoing may be turned off when it is necessary to read",
-" a password with the INPUT command.",
-" ",
-"SET TELNET TERMINAL-TYPE name",
-" The terminal type to send to the remote TELNET host. If none is given,",
-#ifdef OS2
-" your current SET TERMINAL TYPE value is sent, e.g. VT220.",
-" ",
-#else
-" your local terminal type is sent.",
-" ",
-#endif /* OS2 */
-"SET TELNET WAIT-FOR-NEGOTIATIONS { ON, OFF }",
-" Each Telnet option must be fully negotiated either On or Off before the",
-" session can continue. This is especially true with options that require",
-" subnegotiations such as Authentication, Encryption, and Kermit; for",
-" proper support of these options Kermit must wait for the negotiations to",
-" complete. Of course, Kermit has no way of knowing whether a reply is",
-" delayed or not coming at all, and so will wait a minute or more for",
-" required replies before continuing the session. If you know that Kermit's",
-" Telnet partner will not be sending the required replies, you can set this",
-" option of OFF to avoid the long timeouts. Or you can instruct Kermit to",
-" REFUSE specific options with the SET TELOPT command.",
-"",
-"Type SHOW TELNET to see the current values of these parameters.",
-"" };
-#endif /* TNCODE */
-
-#ifndef NOSPL
-static char *hxymacr[] = {
-"Syntax: SET MACRO parameter value",
-" Controls the behavior of macros.",
-" ",
-"SET MACRO ECHO { ON, OFF }",
-" Tells whether commands executed from a macro definition should be",
-" displayed on the screen. OFF by default; use ON for debugging.",
-" ",
-"SET MACRO ERROR { ON, OFF }",
-" Tells whether a macro should be automatically terminated upon a command",
-" error. This setting is local to the current macro, and inherited by",
-" subordinate macros.",
-"" };
-#endif /* NOSPL */
-
-static char *hmxyprm[] = {
-"Syntax: SET PROMPT [ text ]",
-" ",
-#ifdef OS2
-"Prompt text for this program, normally 'K-95>'. May contain backslash",
-#else
-#ifdef MAC
-"Prompt text for this program, normally 'Mac-Kermit>'. May contain backslash",
-#else
-"Prompt text for this program, normally 'C-Kermit>'. May contain backslash",
-#endif /* MAC */
-#endif /* OS2 */
-"codes for special effects. Surround by { } to preserve leading or trailing",
-#ifdef OS2
-"spaces. If text omitted, prompt reverts to K-95>. Prompt can include",
-#else
-#ifdef MAC
-"spaces. If text omitted, prompt reverts to Mac-Kermit>. Prompt can include",
-#else
-"spaces. If text omitted, prompt reverts to C-Kermit>. Prompt can include",
-#endif /* OS2 */
-#endif /* MAC */
-"variables like \\v(dir) or \\v(time) to show current directory or time.",
-"" };
-
-#ifdef UNIX
-static char *hxywild[] = {
-"Syntax: SET WILDCARD-EXPANSION { KERMIT [ switch ], SHELL }",
-" KERMIT (the default) means C-Kermit expands filename wildcards in SEND and",
-" similar commands itself, and in incoming GET commands. Optional switches",
-" are /NO-MATCH-DOT-FILES (\"*\" and \"?\" should not match in initial",
-" period in a filename; this is the default) and /MATCH-DOT-FILES if you",
-" want files whose names begin with \".\" included. SET WILDCARD SHELL",
-" means that Kermit asks your preferred shell to expand wildcards (this",
-" should not be necessary in C-Kermit 7.0 and later). HELP WILDCARD for",
-" further information.",
-"" };
-#endif /* UNIX */
-
-#ifndef NOXFER
-static char *hxywind[] = {
-"Syntax: SET WINDOW-SIZE number",
-" Specifies number of slots for sliding windows, i.e. the number of packets",
-" that can be transmitted before waiting for acknowledgement. The default",
-#ifdef XYZ_INTERNAL
-" for Kermit protocol is one, the maximum is 32; for ZMODEM, the default",
-" is no windowing (0). For ZMODEM, the window size is really the packet",
-" length, and is used only when non-windowed (streaming) transfers fail; the",
-" ZMODEM window size should be a largish number, like 1024, and it should be",
-" a multiple of 64.",
-#else
-" is one, the maximum is 32. Increased window size might result in reduced",
-" maximum packet length. Use sliding windows for improved efficiency on",
-" connections with long delays. A full duplex connection is required, as",
-" well as a cooperating Kermit on the other end.",
-#endif /* XYZ_INTERNAL */
-"" };
-
-static char *hxyrpt[] = {
-"Syntax: SET REPEAT { COUNTS { ON, OFF }, PREFIX <code> }",
-" SET REPEAT COUNTS turns the repeat-count compression mechanism ON and OFF.",
-" The default is ON. SET REPEAT PREFIX <code> sets the repeat-count prefix",
-" character to the given code. The default is 126 (tilde).",
-"" };
-
-static char *hxyrcv[] = {
-"Syntax: SET RECEIVE parameter value",
-" Specifies parameters for inbound packets:",
-" ",
-#ifndef NOCSETS
-"SET RECEIVE CHARACTER-SET { AUTOMATIC, MANUAL }",
-" Whether to automatically switch to an appropriate file-character set based",
-" on the transfer character-set announcer, if any, of an incoming text file.",
-" AUTOMATIC by default. Also see HELP ASSOCIATE.",
-" ",
-#endif /* NOCSETS */
-"SET RECEIVE CONTROL-PREFIX number",
-" ASCII value of prefix character used for quoting control characters in",
-" packets that Kermit receives, normally 35 (number sign). Don't change",
-" this unless something is wrong with the other Kermit program.",
-" ",
-"SET RECEIVE END-OF-PACKET number",
-" ASCII value of control character that terminates incoming packets,",
-" normally 13 (carriage return).",
-" ",
-#ifdef CKXXCHAR
-"SET RECEIVE IGNORE-CHARACTER number",
-" ASCII value of character to be discarded when receiving packets, such as",
-" line folding characters.",
-" ",
-#endif /* CKXXCHAR */
-"SET RECEIVE MOVE-TO [ directory ]",
-" If a directory name is specified, then every file that is received",
-" successfully is moved to the given directory immediately after reception",
-" is complete. Omit the directory name to remove any previously set move-to",
-" directory.",
-" ",
-"SET RECEIVE PACKET-LENGTH number",
-" Maximum length packet the other Kermit should send.",
-" ",
-"SET RECEIVE PADDING number",
-" Number of prepacket padding characters to ask for (normally 0).",
-" ",
-"SET RECEIVE PAD-CHARACTER number",
-" ASCII value of control character to use for padding (normally 0).",
-" ",
-"SET RECEIVE PATHNAMES {OFF, ABSOLUTE, RELATIVE, AUTO}",
-" If a recognizable path (directory, device) specification appears in an",
-" incoming filename, strip it OFF before trying to create the output file.",
-#ifdef CK_MKDIR
-" Otherwise, then if any of the directories in the path don't exist, Kermit",
-" tries to create them, relative to your current or download directory, or",
-" absolutely, as specified. RELATIVE means force all incoming names, even",
-" if they are absolute, to be relative to your current or download directory."
-,
-" AUTO, which is the default, means RELATIVE if the file sender indicates in",
-" advance that this is a recursive transfer, otherwise OFF.",
-#endif /* CK_MKDIR */
-" ",
-"SET RECEIVE PAUSE number",
-" Milliseconds to pause between packets, normally 0.",
-" ",
-
-#ifdef CK_PERMS
-"SET RECEIVE PERMISSIONS { ON, OFF }",
-" Whether to copy file permissions from inbound Attribute packets.",
-" ",
-#endif /* CK_PERMS */
-
-"SET RECEIVE RENAME-TO [ template ]",
-" If a template is specified, then every file that is received successfully",
-" \
-is renamed according to the given template immediately after it is received.",
-" \
-The template should include variables like \\v(filename) or \\v(filenumber).",
-" Omit the template to remove any template previously set.",
-" ",
-"SET RECEIVE START-OF-PACKET number",
-" ASCII value of character that marks start of inbound packet.",
-" ",
-"SET RECEIVE TIMEOUT number",
-" Number of seconds the other Kermit should wait for a packet before sending",
-" a NAK or retransmitting.",
-#ifdef VMS
-" ",
-"SET RECEIVE VERSION-NUMBERS { ON, OFF }",
-" If ON, and in incoming filename includes a VMS version number, use it when",
-" creating the file. If OFF (which is the default), strip any VMS version",
-" number from incoming filenames before attempting to create the file, \
-causing",
-" the new file to receive the next highest version number.",
-#endif /* VMS */
-"" };
-
-static char *hxysnd[] = {
-"Syntax: SET SEND parameter value",
-" Specifies parameters for outbound files or packets.",
-" ",
-"SET SEND BACKUP { ON, OFF }",
-" Tells whether to include backup files when sending file groups. Backup",
-" files are those created by Kermit, EMACS, etc, when creating a new file",
-" that has the same name as an existing file. A backup file has a version",
-" appended to its name, e.g. oofa.txt.~23~. ON is the default, meaning",
-" don't exclude backup files. Use OFF to exclude backup files from group",
-" transfers.",
-" ",
-#ifndef NOCSETS
-"SET SEND CHARACTER-SET { AUTOMATIC, MANUAL }",
-" Whether to automatically switch to an appropriate file-character when a",
-" SET TRANSFER CHARACTER-SET command is given, or vice versa. AUTOMATIC by",
-" default. Also see HELP ASSOCIATE.",
-" ",
-#endif /* NOCSETS */
-
-"SET SEND CONTROL-PREFIX number",
-" ASCII value of prefix character used for quoting control characters in",
-" packets that Kermit sends, normally 35 (number sign).",
-" ",
-#ifdef CKXXCHAR
-"SET SEND DOUBLE-CHARACTER number",
-" ASCII value of character to be doubled when sending packets, such as an",
-" X.25 PAD escape character.",
-" ",
-#endif /* CKXXCHAR */
-"SET SEND END-OF-PACKET number",
-" ASCII value of control character to terminate an outbound packet,",
-" normally 13 (carriage return).",
-" ",
-"SET SEND MOVE-TO [ directory ]",
-" \
-If a directory name is specified, then every file that is sent successfully",
-" is moved to the given directory immediately after it is sent.",
-" Omit the directory name to remove any previously set move-to directory.",
-" ",
-"SET SEND PACKET-LENGTH number",
-" Maximum length packet to send, even if other Kermit asks for longer ones.",
-" This command can not be used to force packets to be sent that are longer",
-" than the length requested by the receiver. Use this command only to",
-" force shorter ones.",
-" ",
-"SET SEND PADDING number",
-" Number of prepacket padding characters to send.",
-" ",
-"SET SEND PAD-CHARACTER number",
-" ASCII value of control character to use for padding.",
-" ",
-"SET SEND PATHNAMES {OFF, ABSOLUTE, RELATIVE}",
-" Include the path (device, directory) portion with the file name when",
-" sending it as specified; ABSOLUTE means to send the whole pathname,",
-" RELATIVE means to include the pathname relative to the current directory.",
-" Applies to the actual filename, not to the \"as-name\". The default is",
-" OFF.",
-" ",
-"SET SEND PAUSE number",
-" Milliseconds to pause between packets, normally 0.",
-" ",
-
-#ifdef CK_PERMS
-"SET SEND PERMISSIONS { ON, OFF }",
-" Whether to include file permissions in outbound Attribute packets.",
-" ",
-#endif /* CK_PERMS */
-
-"SET SEND RENAME-TO [ template ]",
-" If a template is specified, then every file that is sent successfully",
-" is renamed according to the given template immediately after it is sent.",
-" \
-The template should include variables like \\v(filename) or \\v(filenumber).",
-" Omit the template to remove any template previously set.",
-" ",
-"SET SEND START-OF-PACKET number",
-" ASCII value of character to mark start of outbound packet.",
-" ",
-#ifdef CK_TIMERS
-"SET SEND TIMEOUT number [ { DYNAMIC [ min max ] ], FIXED } ]",
-#else
-"SET SEND TIMEOUT number",
-#endif /* CK_TIMERS */
-
-" Number of seconds to wait for a packet before sending NAK or",
-#ifdef CK_TIMERS
-" retransmitting. Include the word DYNAMIC after the number in the",
-" SET SEND TIMEOUT command to have Kermit compute the timeouts dynamically",
-" throughout the transfer based on the packet rate. Include the word FIXED",
-" to use the \"number\" given throughout the transfer. DYNAMIC is the",
-" default. After DYNAMIC you may include minimum and maximum values.",
-#else
-" retransmitting.",
-#endif /* CK_TIMERS */
-#ifdef VMS
-" ",
-"SET SEND VERSION-NUMBERS { ON, OFF }",
-" If ON, include VMS version numbers in outbound filenames. If OFF (which",
-" is the default), strip version numbers.",
-#endif /* VMS */
-"" };
-
-static char *hxyxfer[] = {
-"Syntax: SET TRANSFER (or XFER) paramater value",
-" ",
-"Choices:",
-" ",
-"SET TRANSFER BELL { OFF, ON }",
-" Whether to ring the terminal bell at the end of a file transfer.",
-" ",
-#ifdef XFRCAN
-"SET TRANSFER CANCELLATION { OFF, ON [ <code> [ <number> ] ] }",
-" OFF disables remote-mode packet-mode cancellation from the keyboard.",
-" ON enables it. The optional <code> is the control character to use for",
-" cancellation; the optional <number> is how many consecutive occurrences",
-" of the given control character are required for cancellation.",
-" ",
-#endif /* XFRCAN */
-"SET TRANSFER INTERRUPTION { ON, OFF }",
-" TRANSFER INTERRUPTION is normally ON, allowing for interruption of a file",
-" transfer in progress by typing certain characters while the file-transfer",
-" display is active. SET TRANSFER INTERRUPTION OFF disables interruption",
-" of file transfer from the keyboard in local mode.",
-" ",
-#ifndef NOSPL
-"SET TRANSFER CRC-CALCULATION { OFF, ON }",
-" Tells whether Kermit should accumulate a Cyclic Redundancy Check for ",
-" each file transfer. Normally ON, in which case the CRC value is available",
-" in the \\v(crc16) variable after the transfer. Adds some overhead. Use",
-" SET TRANSFER CRC OFF to disable.",
-" ",
-#endif /* NOSPL */
-#ifndef NOCSETS
-"SET TRANSFER CHARACTER-SET name",
-" Selects the character set used to represent textual data in Kermit",
-" packets. Text characters are translated to/from the FILE CHARACTER-SET.",
-" Choices:",
-" ",
-" TRANSPARENT (no translation, the default)",
-" ASCII",
-" LATIN1 (ISO 8859-1 Latin Alphabet 1)",
-#ifndef NOLATIN2
-" LATIN2 (ISO 8859-2 Latin Alphabet 2)",
-#endif /* NOLATIN2 */
-" LATIN9 (ISO 8859-15 Latin Alphabet 9)",
-#ifdef CYRILLIC
-" CYRILLIC-ISO (ISO 8859-5 Latin/Cyrillic)",
-#endif /* CYRILLIC */
-#ifdef GREEK
-" GREEK-ISO (ISO 8859-7 Latin/Greek)",
-#endif /* GREEK */
-#ifdef HEBREW
-" HEBREW-ISO (ISO 8859-8 Latin/Hebrew)",
-#endif /* HEBREW */
-#ifdef KANJI
-" JAPANESE-EUC (JIS X 0208 Kanji + Roman and Katakana)",
-#endif /* KANJI */
-#ifdef UNICODE
-" UCS-2 (ISO 10646 / Unicode 2-byte form)",
-" UTF-8 (ISO 10646 / Unicode 8-bit serialized transformation format)",
-#endif /* UNICODE */
-" ",
-"SET TRANSFER TRANSLATION { ON, OFF }",
-" Enables and disables file-transfer character-set translation. It's",
-" enabled by default.",
-#endif /* NOCSETS */
-" ",
-#ifdef CK_CURSES
-"SET TRANSFER DISPLAY { BRIEF, CRT, FULLSCREEN, NONE, SERIAL }",
-#else
-"SET TRANSFER DISPLAY { BRIEF, CRT, NONE, SERIAL }",
-#endif /* CK_CURSES */
-" Choose the desired format for the progress report to be displayed on",
-" your screen during file transfers when Kermit is in local mode.",
-#ifdef CK_CURSES
-" FULLSCREEN requires your terminal type be set correctly; the others",
-" are independent of terminal type.",
-#else
-" file transfer.",
-#endif /* CK_CURSES */
-" ",
-"SET TRANSFER LOCKING-SHIFT { OFF, ON, FORCED }",
-" Tell whether locking-shift protocol should be used during file transfer",
-" to achieve 8-bit transparency on a 7-bit connection. ON means to request",
-" its use if PARITY is not NONE and to use it if the other Kermit agrees,",
-" OFF means not to use it, FORCED means to use it even if the other Kermit",
-" does not agree.",
-" ",
-"SET TRANSFER MODE { AUTOMATIC, MANUAL }",
-" Automatic (the default) means Kermit should automatically go into binary",
-" file-transfer mode and use literal filenames if the other Kermit says it",
-" has a compatible file system, e.g. UNIX-to-UNIX, but not UNIX-to-DOS.",
-#ifdef PATTERNS
-" Also, when sending files, Kermit should switch between binary and text",
-" mode automatically per file based on the SET FILE BINARY-PATTERNS and SET",
-" FILE TEXT-PATTERNS.",
-#endif /* PATTERNS */
-" ",
-#ifdef PIPESEND
-"SET TRANSFER PIPES { ON, OFF }",
-" Enables/Disables automatic sending from / reception to command pipes when",
-" the incoming filename starts with '!'. Also see CSEND, CRECEIVE.",
-" ",
-#endif /* PIPESEND */
-#ifdef CK_XYZ
-"SET TRANSFER PROTOCOL { KERMIT, XMODEM, ... }",
-" Synonym for SET PROTOCOL (q.v.).",
-" ",
-#endif /* CK_XYZ */
-"SET TRANSFER REPORT { ON, OFF }",
-" Enables/Disables the automatic post-transfer message telling what files",
-" went where from C-Kermit when it is in remote mode. ON by default.",
-" ",
-"SET TRANSFER SLOW-START { OFF, ON }",
-" ON (the default) tells Kermit, when sending files, to gradually build up",
-" the packet length to the maximum negotiated length. OFF means start",
-" sending the maximum length right away.",
-" ",
-"Synonym: SET XFER. Use SHOW TRANSFER (XFER) to see SET TRANSFER values.",
-"" };
-#endif /* NOXFER */
-
-#ifdef NT
-static char *hxywin95[] = {
-"SET WIN95 8.3-FILENAMES { ON, OFF }",
-" Instructs K-95 to report all filenames using 8.3 notation instead of the",
-" normal long filenames. Default is OFF",
-" ",
-"SET WIN95 ALT-GR { ON, OFF }",
-" Instructs K-95, when used on MS Windows 95, to interpret the Right Alt key",
-" as the Alt-Gr key. This is necessary to work around the failure of",
-" Windows 95 to properly translate non-US keyboards. Default is OFF.",
-" ",
-"SET WIN95 KEYBOARD-TRANSLATION <character-set>",
-" Specifies the character-set that Windows 95 is using to send keystrokes",
-" to Kermit-95 via the keyboard input functions. Default is Latin1-ISO.",
-" ",
-"SET WIN95 OVERLAPPED-IO { ON <requests>, OFF }",
-" Determines whether or not K-95 uses Overlapped-I/O methods for reading",
-" from and writing to serial and TAPI communication devices. <requests>",
-" specifies the maximum number of simultaneous write requests that may be",
-" overlapped, from 1 to 30. Default is ON.",
-" ",
-"SET WIN95 POPUPS { ON, OFF }",
-" Determines whether or not Kermit 95 uses Popups to query the user for",
-" necessary information such as user IDs or passwords. Default is ON.",
-" ",
-"SET WIN95 SELECT-BUG { ON, OFF }"
-" Some TCP/IP (Winsock) implementations for Windows have a defective",
-" select() function. Use this command to avoid the use of select() if",
-" K95 appears to be unable to send data over TCP/IP. Default is OFF.",
-""};
-#endif /* NT */
-
-static char *hmxybel[] = {
-#ifdef OS2
-"Syntax: SET BELL { AUDIBLE [ { BEEP, SYSTEM-SOUNDS } ], VISIBLE, NONE }",
-" Specifies how incoming Ctrl-G (bell) characters are handled in CONNECT",
-" mode and how command warnings are presented in command mode. AUDIBLE",
-" means either a beep or a system-sound is generated; VISIBLE means the",
-" screen is flashed momentarily.",
-#else
-"Syntax: SET BELL { OFF, ON }",
-" ON (the default) enables ringing of the terminal bell (beep) except where",
-" it is disabled in certain circumstances, e.g. by SET TRANSFER BELL. OFF",
-" disables ringing of the bell in all circumstances, overriding any specific",
-" SET xxx BELL selections.",
-#endif /* OS2 */
-""};
-
-static char *hmxycd[] = {
-"Syntax: SET CD { HOME <path>, PATH <path>, MESSAGE { ON, OFF, FILE <list> } }"
-,
-" ",
-"SET CD HOME <path>",
-" Specified which directory to change to if CD or KCD is given without a",
-" pathname. If this command is not given, your login or HOME directory is",
-" used.",
-" ",
-"SET CD PATH <path>",
-" Overrides normal CDPATH environment variable, which tells the CD command",
-" where to look for directories to CD to if you don't specify them fully.",
-" The format is:",
-" ",
-#ifdef UNIXOROSK
-" set cd path :directory:directory:...",
-" ",
-" in other words, a list of directories separated by colons, with a colon",
-" at the beginning, e.g.:",
-" ",
-" set cd path :/usr/olga:/usr/ivan/public:/tmp",
-#else
-#ifdef OS2
-" set cd path disk:directory;disk:directory;...",
-" ",
-" just like the DOS PATH; in other words, a list of disk:directory names",
-" separated by semicolons, e.g.:",
-" ",
-" SET CD PATH C:\\K95;C:\\HOME;C:\\LOCAL;C:\\",
-#else
-#ifdef VMS
-" set cd path directory,directory,...",
-" ",
-" in other words, a list of directory specifications or logical names that",
-" represent them, e.g.:",
-" ",
-" SET CD PATH SYS$LOGIN:,$DISK1:[OLGA],$DISK2[SCRATCH.IVAN].",
-#else
-" (unknown for this platform)",
-#endif /* VMS */
-#endif /* OS2 */
-#endif /* UNIXOROSK */
-" ",
-"SET CD MESSAGE { ON, OFF }",
-" Default is OFF. When ON, this tells Kermit to look for a file with a",
-" certain name in any directory that you CD to, and if it finds one, to",
-" display it on your screen when you give the CD command. The filename,",
-" or list of names, is given in the SET CD MESSAGE FILE command.",
-" ",
-"SET CD MESSAGE FILE name",
-" or:",
-"SET CD MESSAGE FILE {{name1}{name2}...{name8}}",
-" Specify up to 8 filenames to look for when when CDing to a new directory",
-" and CD MESSAGE is ON. The first one found, if any, in the new directory",
-#ifndef DFCDMSG
-" is displayed.",
-#else
-" is displayed. The default list is:",
-" ",
-#ifdef UNIXOROSK
-" {{./.readme}{README.TXT}{READ.ME}}",
-#else
-" {{README.TXT}{READ.ME}}",
-#endif /* UNIXOROSK */
-" ",
-#endif /* DFCDMSG */
-#ifndef NOSERVER
-"Synonym: SET SERVER CD-MESSAGE FILE.",
-#endif /* NOSERVER */
-" ",
-"Type SHOW CD to view current CD settings. Also see HELP SET SERVER.",
-""
-};
-
-#ifndef NOIKSD
-static char * hsetiks[] = {
-#ifdef OS2
-"SET IKS ANONYMOUS ACCOUNT <username>",
-" On Windows NT/2000 this is the account that will be used to allow",
-" anonymous access to the system. This account MUST have no password",
-" and its privileges should be restricted to only allow those operations",
-" which should be permitted to unknown users. In practice this means",
-" List Directories and Read-Execute privileges only. If a directory",
-" is configured for Write privileges then Read privileges should be",
-" denied for that directory. Otherwise, your system will become used",
-" by software pirates. If this command is not specified in the IKSD.KSC",
-" file the username \"GUEST\" is used by default. This command has no",
-" effect on Windows 95/98.",
-" ",
-#endif /* OS2 */
-"SET IKS ANONYMOUS INITFILE filename",
-#ifdef OS2
-" The initialization file to be executed for anonymous logins. By default",
-" it is K95.INI in the home directory associated with the ANNONYMOUS account."
-,
-" Any filename that you specify here must be readable by the ANONYMOUS",
-" account and if a SET IKS ANONYMOUS ROOT command was given, exist within",
-" the restricted directory tree. This option is independent of the SET IKS",
-" INITFILE command which applies only to real users.",
-#else
-" The initialization file to be executed for anonymous logins. By default",
-" it is .kermrc in the anonymous root directory. This option is independent",
-" of the SET IKS INITFILE command which applies only to real users.",
-#endif /* OS2 */
-" ",
-"SET IKS ANONYMOUS LOGIN { ON, OFF }",
-#ifdef OS2
-" Whether anonymous logins are allowed. By default they are NOT allowed,",
-" so this option need be included only to allow them (or for clarity, to",
-" emphasize that they are not allowed). Anonymous login occurs when the",
-" username \"anonymous\" is specified with any password (as with ftpd).",
-" In order for anonymous logins to succeed on Windows NT/2000, the",
-" ANONYMOUS account must be enabled.",
-" ",
-" On Windows NT and 2000, anonymous users have the same access rights as",
-" the ANONYMOUS account. In Windows 95/98, anonymous users, just like any",
-" other users, have full access rights to your entire PC, since Windows 95",
-" and 98 include no security features. For this reason, if you are allowing",
-" anonymous logins, be sure to also SET an IKS ANONYMOUS ROOT directory to",
-" restrict anonymous users' file access.",
-" ",
-" Anonymous user permissions may be restricted via the specification of ",
-" DISABLE commands in the ANONYMOUS initfile. Anonymous users are not ",
-" permitted to execute an ENABLE command. Anonymous users are also prevented"
-,
-" from SHOWing sensitive data about the operating system or the IKS",
-" configuration.",
-#else
-" Whether anonymous logins are allowed. By default they are allowed, so this",
-" option need be included only to disallow them (or for clarity, to emphasize"
-,
-" they are allowed). Anonymous login occurs when the username \"anonymous\"",
-" or \"ftp\" is given, with any password (as with ftpd).",
-#endif /* OS2 */
-" ",
-"SET IKS ANONYMOUS ROOT <directory>",
-" Specifies a directory tree to which anonymous users are restricted after",
-" login.",
-" ",
-"SET IKS BANNERFILE <filename>",
-" The name of a file containing a message to be printed after the user logs",
-" in, in place of the normal message (copyright notice, \"Type HELP or ? for",
-" help\", etc).",
-" ",
-"SET IKS CDFILE <filelist>",
-" When cdmessage is on, this is the name of the \"read me\" file to be shown."
-,
-" Normally you would specify a relative (not absolute) name, since the file",
-" is opened using the literal name you specified, after changing to the new",
-" directory. Example:",
-" ",
-" SET IKS CDFILE READ.ME",
-" ",
-" You can also give a list of up to 8 filenames by (a) enclosing each",
-" filename in braces, and (b) enclosing the entire list in braces. Example:",
-" ",
-" SET IKS CDFILE {{READ.ME}{aareadme.txt}{README}{read-this-first}}",
-" ",
-" When a list is given, it is searched from left to right and the first",
-" file found is displayed.",
-" ",
-"SET IKS CDMESSAGE {ON, OFF, 0, 1, 2}",
-" For use in the Server-Side Server configuration; whenever the client",
-" tells the server to change directory, the server sends the contents of a",
-" \"read me\" file to the client's screen. This feature is ON by default,",
-" and operates in client/server mode only when ON or 1. If set to 2 or",
-" higher, it also operates when the CD command is given at the IKSD> prompt.",
-" Synonym: SET IKS CDMSG.",
-" ",
-"SET IKS DATABASE { ON, OFF }",
-" This command determines whether entries are inserted into the SET IKS",
-" DBFILE (IKSD active sessions database).",
-" ",
-"SET IKS DBFILE <filename>",
-" Specifies the file which should be used for storing runtime status",
-#ifdef OS2
-" information about active connections. The default is a file called",
-" \"iksd.db\" in the WINDOWS directory.",
-#else
-#ifdef UNIX
-" information about active connections. The default is a file called",
-" \"iksd.db\" in the /var/log directory.",
-#else
-" information about active connections.",
-#endif /* UNIX */
-#endif /* OS2 */
-" ",
-#ifdef OS2
-"SET IKS DEFAULT-DOMAIN <domain-name>",
-" A userid on Windows is of the form DOMAIN\\\\userid. This command",
-" determines which domain will be searched for the userid if a domain",
-" is not specified by the user. On Windows 95/98 when User-level",
-" access is activated in the Network Control Panel, the default ",
-" domain will be automatically set. If the default domain is not",
-" specified, accounts on the local machine will take precedence over",
-" accounts in Domains to which the local machine belongs.",
-#endif /* OS2 */
-" ",
-"SET IKS HELPFILE <filename>",
-" Specifies the name of a file to be displayed if the user types HELP",
-" (not followed by a specific command or topic), in place of the built-in",
-" top-level help text. The file need not fit on one screen; more-prompting",
-" is used if the file is more than one screen long if COMMAND MORE-PROMPTING",
-" is ON, as it is by default.",
-" ",
-"SET IKS INITFILE <filename>",
-" Execute <filename> rather than the normal initialization file for real",
-" users; this option does not apply to anonymous users.",
-" ",
-"SET IKS NO-INITFILE { ON, OFF }",
-" Do not execute an initialization file, even if a real user is logging in.",
-" ",
-"SET IKS SERVER-ONLY { ON, OFF }",
-" If this option is included on the IKSD command line, the Client Side Server"
-,
-" configuration is disabled, and the user will not get a Username: or",
-" Password: prompt, and will not be able to access the IKSD command prompt.",
-" A FINISH command sent to the IKSD will log it out and close the",
-" connection, rather than returning it to its prompt.",
-" ",
-"SET IKS TIMEOUT <number>",
-" This sets a limit (in seconds) on the amount of time the client has to log",
-" in once the connection is made. If successful login does not occur within",
-" the given number of seconds, the connection is closed. The default timeout"
-,
-" is 300 seconds (5 minutes). A value of 0 or less indicates there is to be",
-" no limit.",
-" ",
-"SET IKS USERFILE <filename>",
-#ifdef UNIX
-" This file contains a list of local usernames that are to be denied access",
-" to Internet Kermit Service. The default is /etc/ftpusers. This can be the"
-,
-" same file that is used by wuftpd, and the syntax is the same: one username",
-" per line; lines starting with \"#\" are ignored. Use this option to",
-" specify the name of a different forbidden-user file, or use",
-" \"set iks userfile /dev/null\" to disable this feature in case there is a",
-" /etc/ftpusers file but you don't want to use it.",
-#else
-" This file contains a list of local usernames that are to be denied access",
-" to Internet Kermit Service. The syntax is: one username per line; lines",
-" starting with \"#\" are ignored.",
-#endif /* UNIX */
-" ",
-"SET IKS XFERLOG { ON, OFF }",
-#ifdef UNIX
-" Whether a file-transfer log should be kept. Off by default. If \"on\",",
-" but no SET IKSD XFERFILE command is given, /var/log/iksd.log is used.",
-#else
-" Whether a file-transfer log should be kept. Off by default.",
-#endif /* UNIX */
-" ",
-"SET IKS XFERFILE <filename>",
-" Use this option to specify an iksd log file name. If you include this",
-" option, it implies SET IKS XFERFILE ON.",
-""
-};
-#endif /* NOIKSD */
-
-/* D O H S E T -- Give help for SET command */
-
-int
-dohset(xx) int xx; {
- int x;
-
- if (xx == -3) return(hmsga(hmhset));
- if (xx < 0) return(xx);
-
-#ifdef NEWFTP
- if (xx == XYFTPX)
- return(dosetftphlp());
- if (xx == XYGPR)
- return(hmsga(hmxygpr));
-#endif /* NEWFTP */
-
- if ((x = cmcfm()) < 0) return(x);
- switch (xx) {
-#ifndef NOIKSD
- case XYIKS:
- return(hmsga(hsetiks));
-#endif /* NOIKSD */
-
-case XYATTR:
- return(hmsga(hsetat));
-
-case XYBACK:
- return(hmsga(hsetbkg));
-
-case XYBELL:
- return(hmsga(hmxybel));
-
-#ifdef OS2
-case XYPRTY:
- return(hmsg("SET PRIORITY { REGULAR, FOREGROUND-SERVER, TIME-CRITICAL }\n\
- Specifies at which priority level the communication and screen update\n\
- threads should operate. The default value is FOREGROUND-SERVER."));
-#endif /* OS2 */
-
-#ifdef DYNAMIC
-case XYBUF:
- return(hmsga(hsetbuf));
-#endif /* DYNAMIC */
-
-#ifndef NOLOCAL
-case XYCARR:
- return(hmsga(hsetcar));
-#endif /* NOLOCAL */
-
-#ifndef NOSPL
-case XYCASE:
- return(hmsg("Syntax: SET CASE { ON, OFF }\n\
- Tells whether alphabetic case is significant in string comparisons\n\
- done by INPUT, IF, and other commands. This setting is local to the\n\
- current macro or command file, and inherited by subordinates."));
-
-#endif /* NOSPL */
-
-case XYCMD:
- return(hmsga(hsetcmd));
-
-case XYIFD:
- return(hmsg("Syntax: SET INCOMPLETE { DISCARD, KEEP }\n\
- Whether to discard or keep incompletely received files, default is KEEP."));
-
-#ifndef NOSPL
-case XYINPU:
- return(hmsga(hxyinp));
-#endif /* NOSPL */
-
-case XYCHKT:
- return(hmsga(hmxychkt));
-
-#ifndef NOSPL
-case XYCOUN:
- return(hmsg("Syntax: SET COUNT number\n\
- Example: SET COUNT 5\n\
- Set up a loop counter, for use with IF COUNT. Local to current macro\n\
- or command file, inherited by subordinate macros and command files."));
-#endif /* NOSPL */
-
-case XYDEBU:
- return(hmsga(hmxydeb));
-
-case XYDFLT:
- return(hmsg("Syntax: SET DEFAULT directory\n\
- Change directory. Equivalent to CD command."));
-
-case XYDELA:
- return(hmsg("Syntax: SET DELAY number\n\
- Number of seconds to wait before sending first packet after SEND command."));
-
-#ifndef NODIAL
-case XYDIAL:
- return(hmsga(hmxydial));
-#endif /* NODIAL */
-
-#ifdef UNIX
-case XYSUSP:
- return(hmsg("Syntax: SET SUSPEND { OFF, ON }\n\
- Disables SUSPEND command, suspend signals, and <esc-char>Z during CONNECT.")
- );
-#endif
-
-#ifndef NOSCRIPT
-case XYSCRI:
- return(hmsg("Syntax: SET SCRIPT ECHO { OFF, ON }\n\
- Disables/Enables echoing of SCRIPT command operation."));
-#endif /* NOSCRIPT */
-
-case XYTAKE:
- return(hmsga(hxytak));
-
-#ifndef NOLOCAL
-case XYTERM:
- return(hmsga(hxyterm));
-
-case XYDUPL:
- return(hmsg("Syntax: SET DUPLEX { FULL, HALF }\n\
- During CONNECT: FULL means remote host echoes, HALF means Kermit\n\
- does its own echoing."));
-
-case XYLCLE:
- return(hmsg("Syntax: SET LOCAL-ECHO { OFF, ON }\n\
- During CONNECT: OFF means remote host echoes, ON means Kermit\n\
- does its own echoing. Synonym for SET DUPLEX { FULL, HALF }."));
-
-case XYESC:
- return(hmsga(hxyesc)); /* SET ESCAPE */
-#endif /* NOLOCAL */
-
-case XYPRTR: /* SET PRINTER */
- return(hmsga(hxyprtr));
-
-#ifdef OS2
-#ifdef BPRINT
-case XYBDCP: /* SET BPRINTER */
- return(hmsga(hxybprtr));
-#endif /* BPRINT */
-#endif /* OS2 */
-
-case XYEXIT:
- return(hmsga(hxyexit));
-
-case XYFILE:
- return(hmsga(hmxyf));
-
-case XYFLOW:
- return(hmsga(hmxyflo));
-
-case XYHAND:
- return(hmsga(hmxyhsh));
-
-#ifdef NETCONN
-
-case XYHOST:
- return(hmsga(hxyhost));
-
-case XYNET:
- return(hmsga(hxynet));
-
-#ifndef NOTCPOPTS
-#ifdef SOL_SOCKET
-case XYTCP:
- return(hmsga(hxytcp));
-#endif /* SOL_SOCKET */
-#endif /* NOTCPOPTS */
-
-#ifdef ANYX25
-case XYX25:
- return(hmsga(hxyx25));
-
-#ifndef IBMX25
-case XYPAD:
- return(hmsg("Syntax: SET PAD name value\n\
-Set a PAD X.3 parameter with a desired value."));
-#endif /* IBMX25 */
-#endif /* ANYX25 */
-#endif /* NETCONN */
-
-#ifndef NOSPL
-case XYOUTP:
- return(hmsga(hxyout));
-#endif /* NOSPL */
-
-#ifndef NOSETKEY
-case XYKEY: /* SET KEY */
- return(hmsga(hmhskey));
-#endif /* NOSETKEY */
-
-#ifndef NOCSETS
-case XYLANG:
- return(hmsg("Syntax: SET LANGUAGE name\n\
- Selects language-specific translation rules for text-mode file transfers.\n\
- Used with SET FILE CHARACTER-SET and SET TRANSFER CHARACTER-SET when one\n\
- of these is ASCII."));
-#endif /* NOCSETS */
-
-case XYLINE:
- printf("\nSyntax: SET LINE (or SET PORT) [ switches ] [ devicename ]\n\
- Selects a serial-port device to use for making connections.\n");
-#ifdef OS2
-#ifdef NT
- printf("\n");
- printf(
-" You may access communication ports by the traditional \"DOS\" port name\n");
- printf(
-" (e.g. SET PORT COM1) or by the Microsoft Telephony modem name from the\n");
- printf(
-" Modems folder of the Control Panel (e.g. SET PORT TAPI). If one method\n");
- printf(" doesn't work, try the other.\n\n");
-#endif /* NT */
-#else /* OS2 */
- printf(" Typical device name for this platform: %s.\n",ttgtpn());
- printf(" The default device name is %s (i.e. none).\n",dftty);
- if (!dfloc) {
- printf(
-" If you do not give a SET LINE command or if you give a SET LINE command\n");
- printf(
-" with no device name, or if you specify %s as the device name,\n",dftty);
- printf(
-" Kermit will be in \"remote mode\", suitable for use on the far end of a\n");
- printf(
-" connection, e.g. as the file-transfer partner of your desktop communication\
-\n");
- printf(
-" software. If you SET LINE to a specific device other than %s,\n", dftty);
- printf(
-" Kermit is in \"local mode\", suitable for making a connection to another\n"
- );
- printf(
-" computer. SET LINE alone resets Kermit to remote mode.\n");
- }
-#endif /* OS2 */
- printf(
-" To use a modem to dial out, first SET MODEM TYPE (e.g., to USR), then\n");
- printf(
-#ifdef OS2
-" SET PORT COMx (or SET PORT TAPI), SET SPEED, then give a DIAL command.\n");
-#else
-" SET LINE xxx, then SET SPEED, then give a DIAL command.\n");
-#endif /* OS2 */
- printf(
-#ifdef OS2
-" For direct null-modem connections use SET MODEM TYPE NONE, SET PORT COMx,\n"
-#else
-" For direct null-modem connections, use SET MODEM TYPE NONE, SET LINE xxx,\n"
-#endif /* OS2 */
- );
- printf(
-" then SET FLOW, SET SPEED, and CONNECT.\n");
- printf(
-"\nOptional switches:\n\
- /CONNECT - Enter CONNECT mode automatically if SET LINE succeeds.\n");
- printf(
-" /SERVER - Enter server mode automatically if SET LINE succeeds.\n");
-#ifdef VMS
- printf(
-" /SHARE - Open the device in shared mode.\n");
- printf(
-" /NOSHARE - Open the device in exclusive mode.\n");
-#endif /* VMS */
- printf("\n");
- printf(
-"Also see HELP SET MODEM, HELP SET DIAL, HELP SET SPEED, HELP SET FLOW.\n");
- return(0);
-
-#ifndef NOSPL
-case XYMACR:
- return(hmsga(hxymacr));
-#endif /* NOSPL */
-
-#ifndef NODIAL
-case XYMODM:
- return(hmsga(hxymodm));
-#endif /* NODIAL */
-
-case XYPARI:
- return(hmsga(hxypari));
-
-case XYPROM:
- return(hmsga(hmxyprm));
-
-case XYQUIE:
- return(hmsg("Syntax: SET QUIET {ON, OFF}\n\
- Normally OFF. ON disables most information messages during interactive\n\
- operation."));
-
-#ifdef CK_SPEED
-case XYQCTL:
- return(hmsga(hmxyqctl));
-#endif /* CK_SPEED */
-
-case XYRETR:
- return(hmsg("Syntax: SET RETRY number\n\
- In Kermit protocol file transfers: How many times to retransmit a\n\
- particular packet before giving up; 0 = no limit."));
-
-#ifndef NOLOCAL
-case XYSESS:
-#ifdef UNIX
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out CR, NUL, and XON/XOFF characters. DEBUG is the same as BINARY but\n\
- also includes Telnet negotiations on TCP/IP connections."));
-#else
-#ifdef datageneral
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out CR, NUL, and XON/XOFF characters. DEBUG is the same as BINARY but\n\
- also includes Telnet negotiations on TCP/IP connections."));
-#else
-#ifdef STRATUS
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out CR, NUL, and XON/XOFF characters. DEBUG is the same as BINARY but\n\
- also includes Telnet negotiations on TCP/IP connections."));
-#else
-#ifdef AMIGA
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out CR, NUL, and XON/XOFF characters. DEBUG is the same as BINARY but\n\
- also includes Telnet negotiations on TCP/IP connections."));
-#else
-#ifdef GEMDOS
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out CR, NUL, and XON/XOFF characters. DEBUG is the same as BINARY but\n\
- also includes Telnet negotiations on TCP/IP connections."));
-#else
-#ifdef OS2
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out NUL and XON/XOFF characters. DEBUG is the same as BINARY but\n\
- also includes Telnet negotiations on TCP/IP connections."));
-#else
-#ifdef VMS
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out CR, NUL, and XON/XOFF characters. DEBUG is the same as BINARY but\n\
- also includes Telnet negotiations on TCP/IP connections."));
-#else
-#ifdef OSK
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out LF, NUL and XON/XOFF characters."));
-#else
-#ifdef MAC
- return(hmsg(
-"Syntax: SET SESSION-LOG { BINARY, DEBUG, TEXT, TIMESTAMPED-TEXT }\n\
- If BINARY, record all CONNECT characters in session log. If TEXT, strip\n\
- out LF, NUL and XON/XOFF characters."));
-#endif /* MAC */
-#endif /* OSK */
-#endif /* OS2 */
-#endif /* VMS */
-#endif /* GEMDOS */
-#endif /* AMIGA */
-#endif /* STRATUS */
-#endif /* datageneral */
-#endif /* OS2ORUNIX */
-
-case XYSPEE:
-#ifdef OS2
-
- return(hmsg("Syntax: SET SPEED number\n\
- Speed for serial-port communication device specified in most recent\n\
- SET PORT command, in bits per second. Type SET SPEED ? for a list of\n\
- possible speeds."));
-#else
- return(hmsg("Syntax: SET SPEED number\n\
- Speed for serial-port communication device specified in most recent\n\
- SET LINE command, in bits per second. Type SET SPEED ? for a list of\n\
- possible speeds. Has no effect on job's controlling terminal."));
-#endif /* OS2 */
-#endif /* NOLOCAL */
-
-#ifndef NOXFER
-case XYRECV:
- return(hmsga(hxyrcv));
-case XYSEND:
- return(hmsga(hxysnd));
-case XYREPT:
- return(hmsga(hxyrpt));
-#endif /* NOXFER */
-
-#ifndef NOSERVER
-case XYSERV:
- return(hmsga(hsetsrv));
-#endif /* NOSERVER */
-
-#ifdef TNCODE
-case XYTEL:
- return(hmsga(hxytel));
-
-case XYTELOP:
- return(hmsga(hxytopt));
-#endif /* TNCODE */
-
-#ifndef NOXMIT
-case XYXMIT:
- return(hmsga(hsetxmit));
-#endif /* NOXMIT */
-
-#ifndef NOCSETS
-case XYUNCS:
- return(hmsg("Syntax: SET UNKNOWN-CHAR-SET action\n\
- DISCARD (default) means reject any arriving files encoded in unknown\n\
- character sets. KEEP means to accept them anyway."));
-#endif /* NOCSETS */
-
-#ifdef UNIX
-case XYWILD:
- return(hmsga(hxywild));
-#endif /* UNIX */
-
-#ifndef NOXFER
-case XYWIND:
- return(hmsga(hxywind));
-case XYXFER:
- return(hmsga(hxyxfer));
-#endif /* NOXFER */
-
-#ifndef NOLOCAL
-#ifdef OS2MOUSE
-case XYMOUSE:
- return(hmsga(hxymouse));
-#endif /* OS2MOUSE */
-#endif /* NOLOCAL */
-
-case XYALRM:
- return(hmsg("Syntax: SET ALARM [ { seconds, hh:mm:ss } ]\n\
- Number of seconds from now, or time of day, after which IF ALARM\n\
- will succeed. 0, or no time at all, means no alarm."));
-
-case XYPROTO:
- return(hmsga(hxyxyz));
-
-#ifdef CK_SPEED
-case XYPREFIX:
- return(hmsg("Syntax: SET PREFIXING { ALL, CAUTIOUS, MINIMAL }\n\
- \
-Selects the degree of control-character prefixing. Also see HELP SET CONTROL."
-));
-#endif /* CK_SPEED */
-
-#ifdef OS2
-case XYLOGIN:
- return(hmsg("Syntax: SET LOGIN { USERID, PASSWORD, PROMPT } <text>\n\
- Provides access information for use by login scripts."));
-#endif /* OS2 */
-
-#ifndef NOSPL
-case XYTMPDIR:
- return(hmsg("Syntax: SET TEMP-DIRECTORY [ <directory-name> ]\n\
- Overrides automatic assignment of \\v(tmpdir) variable."));
-#endif /* NOSPL */
-
-#ifdef OS2
-case XYTITLE:
- return(hmsg("Syntax: SET TITLE <text>\n\
- Sets window title to text instead of using current host/port name."));
-#endif /* OS2 */
-
-#ifndef NOPUSH
-#ifndef NOFRILLS
-case XYEDIT:
- return(hmsg("Syntax: SET EDITOR pathname [ options ]\n\
- Specifies the name of your preferred editor, plus any command-line\n\
- options. SHOW EDITOR displays it."));
-#endif /* NOFRILLS */
-#endif /* NOPUSH */
-
-#ifdef BROWSER
-case XYBROWSE:
-#ifdef NT
- return(hmsg("Syntax: SET BROWSER [ pathname [ options ] ]\n\
- Specifies the name of your preferred browser plus any command-line\n\
- options. SHOW BROWSER displays it. Omit pathname and options to use\n\
- ShellExecute."));
-#else
- return(hmsg("Syntax: SET BROWSER [ pathname [ options ] ]\n\
- Specifies the name of your preferred browser plus any command-line\n\
- options. SHOW BROWSER displays it."));
-#endif /* NT */
-#endif /* BROWSER */
-
-#ifdef CK_TAPI
-case XYTAPI:
- return(hmsga(hxytapi));
-#endif /* CK_TAPI */
-
-#ifdef NT
-case XYWIN95:
- return(hmsga(hxywin95));
-#endif /* NT */
-
-#ifndef NOSPL
-case XYFUNC:
- return(hmsga(hxyfunc));
-#endif /* NOSPL */
-
-#ifdef CK_AUTHENTICATION
-case XYAUTH:
- return(hmsga(hmxyauth));
-#else /* CK_AUTHENTICATION */
-#ifdef CK_SSL
-case XYAUTH:
- return(hmsga(hmxyauth));
-#endif /* CK_SSL */
-#endif /* CK_AUTHENTICATION */
-
-#ifdef BROWSER
-case XYFTP:
- return(hmsg("Syntax: SET FTP [ pathname [ options ] ]\n\
- Specifies the name of your ftp client, plus any command-line options.\n\
- SHOW FTP displays it."));
-#endif /* BROWSER */
-
-case XYSLEEP:
- return(hmsg("Syntax: SET SLEEP CANCELLATION { ON, OFF }\n\
- Tells whether SLEEP (PAUSE) or WAIT commands can be interrupted from the\n\
- keyboard; ON by default."));
-
-case XYCD:
- return(hmsga(hmxycd));
-
-case XYSERIAL:
- return(hmsg("Syntax: SET SERIAL dps\n\
- d is data length in bits, 7 or 8; p is first letter of parity; s is stop\n\
- bits, 1 or 2. Examples: \"set serial 7e1\", \"set serial 8n1\"."));
-
-#ifdef HWPARITY
-case XYSTOP:
- return(hmsg("Syntax: SET STOP-BITS { 1, 2 }\n\
- Number of stop bits to use on SET LINE connections, normally 1."));
-#endif /* HWPARITY */
-
-#ifndef NOLOCAL
-case XYDISC:
- return(hmsg("Syntax: SET DISCONNECT { ON, OFF }\n\
- Whether to close and release a SET LINE device automatically upon\n\
- disconnection; OFF = keep device open (default); ON = close and release."));
-#endif /* NOLOCAL */
-
-#ifdef STREAMING
-case XYSTREAM:
- return(hmsg("Syntax: SET STREAMING { ON, OFF, AUTO }\n\
- Tells Kermit whether streaming protocol can be used during Kermit file\n\
- transfers. Default is AUTO, meaning use it if connection is reliable."));
-#endif /* STREAMING */
-
-case XYRELY:
- return(hmsg("Syntax: SET RELIABLE { ON, OFF, AUTO }\n\
- Tells Kermit whether its connection is reliable. Default is AUTO,\n\
- meaning Kermit should figure it out for itself."));
-
-case XYCLEAR:
- return(hmsg("Syntax: SET CLEAR-CHANNEL { ON, OFF, AUTO }\n\
- Tells Kermit whether its connection is transparent to all 8-bit bytes.\n\
- Default is AUTO, meaning Kermit figures it out from the connection type.\n\
- When both sender and receiver agree channel is clear, SET PREFIXING NONE\n\
- is used automatically."));
-
-#ifdef TLOG
-case XYTLOG:
- return(hmsg("Syntax: SET TRANSACTION-LOG { BRIEF, FTP, VERBOSE }\n\
- Selects the transaction-log format; BRIEF and FTP have one line per file;\n\
- FTP is compatible with FTP log. VERBOSE (the default) has more info."));
-#endif /* TLOG */
-
-case XYOPTS:
- return(hmsg("Syntax: SET OPTIONS command [ switches... ]\n\
- For use with commands that have switches; sets the default switches for\n\
- the given command. Type SET OPTIONS ? for a list of amenable commands."));
-
-#ifndef NOSPL
-case XYTIMER:
- return(hmsga(hmxytimer));
-#endif /* NOSPL */
-
-#ifdef CKROOT
- case XYROOT:
- return(hmsga(hmxxchroot));
-#endif /* XYROOT */
-
-#ifdef ANYSSH
- case XYSSH:
- return(hmsga(hmxyssh));
-#endif /* ANYCMD */
-
-#ifdef LOCUS
- case XYLOCUS:
- return(hmsga(hmxylocus));
-#endif /* LOCUS */
-
-#ifdef OS2
-#ifdef KUI
- case XYGUI:
- return(hmsga(hmxygui));
-#endif /* KUI */
-#endif /* OS2 */
-
- case XYMATCH:
- return(hmsga(hmxymatch));
-
-default:
- printf("Not available - \"%s\"\n",cmdbuf);
- return(0);
- }
-}
-
-#ifndef NOSPL
-/* D O H F U N C -- Give help for a function */
-
-int
-dohfunc(xx) int xx; {
- /* int x; */
- if (xx == -3) {
- printf("\n Type SHOW FUNCTIONS to see a list of available functions.\n"
- );
- printf(
- " Type HELP FUNCTION <name> for help on a particular function.\n");
- printf(
- " For function settings use HELP SET FUNCTION and SHOW SCRIPTS.\n\n");
- return(0);
- }
- if (xx == FN_WORD) /* Long help message */
- return(hmsga(hmfword));
-
- printf("\n");
- switch (xx) {
- case FN_IND: /* Index (of string 1 in string 2) */
- case FN_RIX: /* Rindex (index from right) */
- printf("\\f%sindex(s1,s2,n1)\n\
- s1 = string to look for.\n\
- s2 = string to look in.\n\
- n1 = optional 1-based starting position, default = 1.\n",
- xx == FN_RIX ? "r" : ""
- );
- printf("Returns integer:\n\
- 1-based position of %smost occurrence of s1 in s2, ignoring the %smost\n\
- (n1-1) characters in s2; returns 0 if s1 not found in s2.\n",
- xx == FN_IND ? "left" : "right",
- xx == FN_IND ? "left" : "right"
- );
- break;
- case FN_SEARCH: /* Search for pattern */
- case FN_RSEARCH: /* Search for pattern from right */
- printf("\\f%ssearch(s1,s2,n1)\n\
- s1 = pattern to look for.\n\
- s2 = string to look in.\n\
- n1 = optional 1-based offset, default = 1.\n",
- xx == FN_RSEARCH ? "r" : ""
- );
- printf("Returns integer:\n\
- 1-based position of %smost match for s1 in s2, ignoring the %smost\n\
- (n1-1) characters in s2; returns 0 if no match.\n",
- xx == FN_SEARCH ? "left" : "right",
- xx == FN_SEARCH ? "left" : "right"
- );
- printf(" See HELP WILDCARDS for info about patterns.\n");
- break;
- case FN_LEN: /* Length (of string) */
- printf("\\flength(s1)\n\
- s1 = string.\n");
- printf("Returns integer:\n\
- Length of string s1.\n");
- break;
- case FN_LIT: /* Literal (don't expand the string) */
- printf("\\fliteral(s1)\n\
- s1 = string.\n");
- printf("Returns string:\n\
- s1 literally without evaluation.\n");
- break;
- case FN_LOW: /* Lower (convert to lowercase) */
- printf("\\flower(s1)\n\
- s1 = string.\n");
- printf("Returns string:\n\
- s1 with uppercase letters converted to lowercase.\n");
- break;
- case FN_MAX: /* Max (maximum) */
- printf("\\fmaximum(n1,n2)\n\
- n1 = integer.\n\
- n2 = integer.\n");
- printf("Returns integer:\n\
- The greater of n1 and n2.\n");
- break;
- case FN_MIN: /* Min (minimum) */
- printf("\\fminimum(n1,n2)\n\
- n1 = integer.\n\
- n2 = integer.\n");
- printf("Returns integer:\n\
- The lesser of n1 and n2.\n");
- break;
- case FN_MOD: /* Mod (modulus) */
- printf("\\fmodulus(n1,n2)\n\
- n1 = integer.\n\
- n2 = integer.\n");
- printf("Returns integer:\n\
- The remainder after dividing n1 by n2.\n");
- break;
- case FN_EVA: /* Eval (evaluate arith expression) */
- printf("\\fevaluate(e)\n\
- e = arithmetic expression.\n");
- printf("Returns integer:\n\
- The result of evaluating the expression.\n");
- break;
- case FN_SUB: /* Substr (substring) */
- printf("\\fsubstring(s1,n1,n2)\n\
- s1 = string.\n\
- n1 = integer, 1-based starting position, default = 1.\n\
- n2 = integer, length, default = length(s1) - n1 + 1.\n");
- printf("Returns string:\n\
- Substring of s1 starting at n1, length n2.\n");
- break;
- case FN_UPP: /* Upper (convert to uppercase) */
- printf("\\fupper(s1)\n\
- s1 = string.\n");
- printf("Returns string:\n\
- s1 with lowercase letters converted to uppercase.\n");
- break;
- case FN_REV: /* Reverse (a string) */
- printf("\\freverse(s1)\n\
- s1 = string.\n");
- printf("Returns string:\n\
- s1 with its characters in reverse order.\n");
- break;
- case FN_REP: /* Repeat (a string) */
- printf("\\frepeat(s1,n1)\n\
- s1 = string.\n\
- n1 = integer.\n");
- printf("Returns string:\n\
- s1 repeated n1 times.\n");
- break;
- case FN_EXE: /* Execute (a macro) */
- printf("\\fexecute(m1,a1,a2,a3,...)\n\
- m1 = macro name.\n\
- a1 = argument 1.\n\
- a2 = argument 2, etc\n");
- printf("Returns string:\n\
- The return value of the macro (HELP RETURN for further info).\n");
- break;
- case FN_LPA: /* LPAD (left pad) */
- case FN_RPA: /* RPAD (right pad) */
- printf("\\f%cpad(s1,n1,c1)\n\
- s1 = string.\n\
- n1 = integer.\n\
- c1 = character, default = space.\n",
- xx == FN_LPA ? 'l' : 'r');
- printf("Returns string:\n\
- s1 %s-padded with character c1 to length n1.\n",
- xx == FN_LPA ? "left" : "right");
- break;
- case FN_DEF: /* Definition of a macro, unexpanded */
- printf("\\fdefinition(m1)\n\
- m1 = macro name.\n");
- printf("Returns string:\n\
- Literal definition of macro m1.\n");
- break;
- case FN_CON: /* Contents of a variable, ditto */
- printf("\\fcontents(v1)\n\
- v1 = variable name such as \\%%a.\n");
- printf("Returns string:\n\
- Literal definition of variable v1, evaluated one level only.\n");
- break;
- case FN_FIL: /* Next file */
- printf("\\fnextfile()\n");
- printf("Returns string:\n\
- Name of next file from list created by most recent \\f[r]files() or\n\
- \\f[r]dir()invocation, or an empty string if there are no more files in\n\
- the list.\n");
- break;
- case FN_FC: /* File count */
- printf("\\ffiles(f1[,&a]) - File list.\n\
- f1 = file specification, possibly containing wildcards.\n\
- &a = optional name of array to assign file list to.\n");
- printf("Returns integer:\n\
- The number of regular files that match f1. Use with \\fnextfile().\n");
- break;
- case FN_CHR: /* Character (like BASIC CHR$()) */
- printf("\\fcharacter(n1)\n\
- n1 = integer.\n");
- printf("Returns character:\n\
- The character whose numeric code is n1.\n");
- break;
- case FN_RIG: /* Right (like BASIC RIGHT$()) */
- printf("\\fright(s1,n1)\n\
- s1 = string.\n\
- n1 = integer, default = length(s1).\n");
- printf("Returns string:\n\
- The rightmost n1 characters of string s1.\n");
- break;
- case FN_LEF: /* Left (like BASIC LEFT$()) */
- printf("\\fleft(s1,n1)\n\
- s1 = string.\n\
- n1 = integer, default = length(s1).\n");
- printf("Returns string:\n\
- The leftmost n1 characters of string s1.\n");
- break;
- case FN_COD: /* Code value of character */
- printf("\\fcode(s1)\n\
- c1 = character.\n");
- printf("Returns integer:\n\
- The numeric code of the first character in string s1, or 0 if s1 empty.\n");
- break;
- case FN_RPL: /* Replace */
- printf("\\freplace(s1,s2,s3[,n1])\n\
- s1 = original string.\n\
- s2 = match string.\n\
- s3 = replacement string.\n\
- n1 = occurrence.\n");
- printf("Returns string:\n\
- s1 with occurrence number n1 of s2 replaced by s3.\n\
- If n1 = 0 or omitted, all occurrences are replaced.\n\
- If n1 < 0, occurrences are counted from the right.\n");
- break;
-
- case FN_FD: /* File date */
- printf("\\fdate(f1)\n\
- f1 = filename.\n");
-#ifdef VMS
- printf("Returns string:\n\
- Creation date of file f1, format: yyyymmdd hh:mm:ss.\n");
-#else
- printf("Returns string:\n\
- Modification date of file f1, format: yyyymmdd hh:mm:ss.\n");
-#endif /* VMS */
- break;
- case FN_FS: /* File size */
- printf("\\fsize(f1)\n\
- f1 = filename.\n");
- printf("Returns integer:\n\
- Size of file f1.\n");
- break;
- case FN_VER: /* Verify */
- printf("\\fverify(s1,s2,n1)\n\
- s1 = string of characters to look for.\n\
- s2 = string to look in.\n\
- n1 = starting position in s2.\n");
- printf("Returns integer:\n\
- 1-based position of first character in s2 that is not also in s1,\n\
- or -1 if s1 is empty, or 0 if all characters in s2 are also in s1.\n");
- break;
- case FN_IPA: /* Find and return IP address */
- printf("\\fipaddress(s1,n1)\n\
- s1 = string.\n\
- n1 = 1-based integer starting position, default = 1.\n");
- printf("Returns string:\n\
- First IP address in s1, scanning from left starting at position n1.\n");
- break;
- case FN_HEX: /* Hexify */
- printf("\\fhexify(s1)\n\
- s1 = string.\n");
- printf("Returns string:\n\
- The hexadecimal representation of s1. Also see \\fn2hex().\n");
- break;
- case FN_UNH: /* Unhexify */
- printf("\\funhexify(h1)\n\
- h1 = Hexadecimal string.\n");
- printf("Returns string:\n\
- The result of unhexifying s1, or nothing if s1 is not a hex string.\n");
- break;
- case FN_UNTAB: /* Untabify */
- printf("\\funtabify(s1)\n\
- s1 = string.\n");
- printf("Returns string:\n\
- The result of converting tabs in s1 to spaces assuming tab stops every\n\
- 8 spaces.\n");
- break;
- case FN_BRK: /* Break */
- case FN_SPN: /* Span */
- printf("\\f%s(s1,s2,n1)\n\
- s1 = string to look in.\n\
- s2 = string of characters to look for.\n\
- n1 = 1-based integer starting position, default = 1.\n",
- xx == FN_BRK ? "break" : "span"
- );
- printf("Returns string:\n\
- s1 up to the first occurrence of any character%salso in s2,\n\
- scanning from the left starting at position n1.\n",
- xx == FN_SPN ? " not " : " ");
- break;
- case FN_TRM: /* Trim */
- case FN_LTR: /* Left-Trim */
- printf("\\f%s(s1,s2)\n\
- s1 = string to look in.\n\
- s2 = string of characters to look for, default = blanks and tabs.\n",
- xx == FN_TRM ? "trim" : "ltrim");
- printf("Returns string:\n\
- s1 with all characters that are also in s2 trimmed from the %s.\n.",
- xx == FN_TRM ? "right" : "left");
- break;
- case FN_CAP: /* Capitalize */
- printf("\\fcapitalize(s1)\n\
- s1 = string.\n");
- printf("Returns string:\n\
- s1 with its first letter converted to uppercase and the remaining\n\
- letters to lowercase.\n");
- printf("Synonym: \\fcaps(s1)\n");
- break;
- case FN_TOD: /* Time-of-day-to-secs-since-midnite */
- printf("\\ftod2secs(s1)\n\
- s1 = time-of-day string, hh:mm:ss, 24-hour format.\n");
- printf("Returns number:\n\
- Seconds since midnight.\n");
- break;
- case FN_FFN: /* Full file name */
- printf("\\fpathname(f1)\n\
- f1 = filename, possibly wild.\n");
- printf("Returns string:\n\
- Full pathname of f1.\n");
- break;
- case FN_CHK: /* Checksum of text */
- printf("\\fchecksum(s1)\n\
- s1 = string.\n");
- printf("Returns integer:\n\
- 16-bit checksum of string s1.\n");
- break;
- case FN_CRC: /* CRC-16 of text */
- printf("\\fcrc16(s1)\n\
- s1 = string.\n");
- printf("Returns integer:\n\
- 16-bit cyclic redundancy check of string s1.\n");
- break;
- case FN_BSN: /* Basename of file */
- printf("\\fbasename(f1)\n\
- f1 = filename, possibly wild.\n");
- printf("Returns string:\n\
- Filename f1 stripped of all device and directory information.\n");
- break;
- case FN_CMD: /* Output of a command (cooked) */
- printf("\\fcommand(s1)\n\
- s1 = string\n");
- printf("Returns string:\n\
- Output of system command s1, if any, with final line terminator stripped.\n"
- );
- break;
- case FN_RAW: /* Output of a command (raw) */
- printf("\\frawcommand(s1)\n\
- s1 = string\n");
- printf("Returns string:\n\
- Output of system command s1, if any.\n");
- break;
- case FN_STX: /* Strip from right */
- printf("\\fstripx(s1,c1)\n\
- s1 = string to look in.\n\
- c1 = character to look for, default = \".\".\n");
- printf("Returns string:\n\
- s1 up to the rightmost occurrence of character c1.\n"
- );
- break;
-
- case FN_STL: /* Strip from left */
- printf("\\flop(s1,c1)\n\
- s1 = string to look in.\n\
- c1 = character to look for, default = \".\".\n");
- printf("Returns string:\n\
- The part of s1 after the leftmost occurrence of character c1.\n"
- );
- break;
-
- case FN_STN: /* Strip n chars */
- printf("\\fstripn(s1,n1)\n\
- s1 = string to look in.\n\
- n1 = integer, default = 0.\n");
- printf("Returns string:\n\
- s1 with n1 characters removed from the right.\n"
- );
- break;
-
- case FN_STB: /* Strip enclosing brackets */
- printf("\\fstripb(s1[,c1[,c2]])\n\
- s1 = original string.\n\
- c1 = optional first character\n");
- printf("\
- c2 = optional final character.\n");
- printf("Returns string:\n\
- s1 with the indicated enclosing characters removed. If c1 and c2 not\n\
- specified, any matching brackets, braces, parentheses, or quotes are\n");
- printf("\
- assumed. If c1 is given but not c2, the appropriate c2 is assumed.\n\
- if both c1 and c2 are given, they are used as-is.\n"
- );
- printf(
-"Alternative format:\n\
- Include a grouping mask number in place of c1 and omit c2 to specify more\n\
- than one possibility at once; see \\fword() for details.\n"
- );
- break;
-
-#ifdef OS2
- case FN_SCRN_CX: /* Screen Cursor X Pos */
- printf("\\fscrncurx()\n");
- printf("Returns integer:\n\
- The 0-based X coordinate (column) of the Terminal screen cursor.\n");
- break;
- case FN_SCRN_CY: /* Screen Cursor Y Pos */
- printf("\\fscrncury()\n");
- printf("Returns integer:\n\
- The 0-based Y coordinate (row) of the Terminal screen cursor.\n");
- break;
- case FN_SCRN_STR: /* Screen String */
- printf("\\fscrnstr(ny,nx,n1)\n\
- ny = integer.\n\
- nx = integer.\n\
- n1 = integer.\n");
- printf("Returns string:\n\
- The string at Terminal-screen coordinates (nx,ny), length n1,\n\
- blanks included. Coordinates start at 0. Default values are\n\
- 0 for ny and nx, and line width for n1.\n");
- break;
-#endif /* OS2 */
-
- case FN_2HEX: /* Num to hex */
- printf("\\fn2hex(n1) - Number to hex\n n1 = integer.\n");
- printf("Returns string:\n The hexadecimal representation of n1.\n");
- break;
-
- case FN_2OCT: /* Num to hex */
- printf("\\fn2octal(n1) - Number to octal\n n1 = integer.\n");
- printf("Returns string:\n The octal representation of n1.\n");
- break;
-
-#ifdef RECURSIVE
- case FN_DIR: /* Recursive directory count */
- printf("\\fdirectories(f1) - Directory list.\n\
- f1 = directory specification, possibly containing wildcards.\n\
- &a = optional name of array to assign directory list to.\n");
- printf("Returns integer:\n\
- The number of directories that match f1; use with \\fnextfile().\n");
- break;
-
- case FN_RFIL: /* Recursive file count */
- printf("\\frfiles(f1[,&a]) - Recursive file list.\n\
- f1 = file specification, possibly containing wildcards.\n\
- &a = optional name of array to assign file list to.\n");
- printf("Returns integer:\n\
- The number of files whose names match f1 in the current or given\n\
- directory tree; use with \\fnextfile().\n");
- break;
-
- case FN_RDIR: /* Recursive directory count */
- printf("\\frdirectories(f1) - Recursive directory list.\n\
- f1 = directory specification, possibly containing wildcards.\n\
- &a = optional name of array to assign directory list to.\n");
- printf("Returns integer:\n\
- The number of directories that match f1 in the current or given directory\n\
- tree. Use with \\fnextfile().\n");
- break;
-#endif /* RECURSIVE */
-
- case FN_DNAM: /* Directory part of a filename */
- printf("\\fdirname(f) - Directory part of a filename.\n\
- f = a file specification.\n");
- printf("Returns directory name:\n\
- The full name of the directory that the file is in, or if the file is a\n\
- directory, its full name.\n");
- break;
-
-#ifndef NORANDOM
- case FN_RAND: /* Random number */
- printf("\\frandom(n) - Random number.\n\
- n = a positive integer.\n");
- printf("Returns integer:\n\
- A random number between 0 and n-1.\n");
- break;
-#endif /* NORANDOM */
-
- case FN_SPLIT: /* Split */
- printf("\\fsplit(s1,&a,s2,s3,n2,n3) - \
-Assign string words to an array.\n\
- s1 = source string\n &a = array designator\n s2 = optional break set.\n");
- printf(" s3 = optional include set.\n");
- printf(" n2 = optional grouping mask.\n");
- printf(" n3 = optional separator flag.\n");
- printf(" s2, s3, n2, n3 are as in \\fword().\n");
- printf(
-" All arguments are optional; if \\&a[] already exists, it is recycled;\n\
- if array not specified, the count is returned but no array is created.\n");
- printf("Returns integer:\n\
- Number of words in source string.\n");
- break;
-
- case FN_DTIM: /* CVTDATE */
- printf("\\fcvtdate([date-time][,n1]) - Date/time conversion.\n");
- printf(" Converts date and/or time to standard format.\n");
- printf(" If no date/time given, returns current date/time.\n");
- printf(" [date-time], if given, is free-format date and/or time.\n");
- printf(" HELP DATE for info about date-time formats.\n");
- printf("Returns string:\n\
- Standard-format date and time: yyyymmdd hh:mm:ss (numeric)\n");
- printf(" If n1 is given:\n\
- n1 = 1: yyyy-mmm-dd hh:mm:ss (mmm = English 3-letter month abbreviation)\n\
- n1 = 2: dd-mmm-yyyy hh:mm:ss (ditto)\n\
- n1 = 3: yyyymmddhhmmss (all numeric)\n");
- break;
-
- case FN_JDATE: /* DOY */
- printf("\\fdoy([date-time]) - Day of Year.\n");
- printf(" Converts date and/or time to day-of-year (DOY) format.\n");
- printf(" If no date/time given, returns current date.\n");
- printf(" [date-time], if given, is free-format date and/or time.\n");
- printf(" HELP DATE for info about date-time formats.\n");
- printf("Returns numeric string:\n\
- DOY: yyyyddd, where ddd is 1-based day number in year.\n");
- break;
-
- case FN_PNCVT:
- printf("\\fdialconvert(phone-number) - Convert phone number.\n");
- printf(" Converts the given phone number for dialing according\n");
- printf(
-" to the prevailing dialing rules -- country code, area code, etc.\n");
- printf("Returns string:\n\
- The dial string that would be used if the same phone number had been\n\
- given to the DIAL command.\n"
- );
- break;
-
- case FN_DATEJ: /* DOY2DATE */
- printf("\\fdoy2date([doy[ time]]) - Day of Year to Date.\n");
- printf(" Converts yyyymmm to yyyymmdd\n");
- printf(" If time included, it is converted to 24-hour format.");
- printf(
- "Returns standard date or date-time string yyyymmdd hh:mm:ss\n");
- break;
-
- case FN_MJD:
- printf("\\fmjd([[date][ time]]) - Modified Julian Date (MJD).\n");
- printf(
-" Converts date and/or time to MJD, the number of days since 17 Nov 1858.\n");
- printf(" HELP DATE for info about date-time formats.\n");
- printf("Returns: integer.\n");
- break;
-
- case FN_MJD2:
- printf("\\fmjd2date(mjd) - Modified Julian Date (MJD) to Date.\n");
- printf(" Converts MJD to standard-format date.\n");
- printf("Returns: yyyymmdd.\n");
- break;
-
- case FN_DAY:
- printf("\\fday([[date][ time]]) - Day of Week.\n");
- printf("Returns day of week of given date as Mon, Tue, etc.\n");
- printf("HELP DATE for info about date-time formats.\n");
- break;
-
- case FN_NDAY:
- printf("\\fnday([[date][ time]]) - Numeric Day of Week.\n");
- printf(
- "Returns numeric day of week of given date, 0=Sun, 1=Mon, ..., 6=Sat.\n");
- printf("HELP DATE for info about date-time formats.\n");
- break;
-
- case FN_TIME:
- printf("\\ftime([[date][ time]]) - Time.\n");
- printf(
-"Returns time portion of given date and/or time in hh:mm:ss format.\n");
- printf("If no argument given, returns current time.\n");
- printf("HELP DATE for info about date-time formats.\n");
- break;
-
- case FN_NTIM:
- printf("\\fntime([[date][ time]]) - Numeric Time.\n");
- printf(
-"Returns time portion of given date and/or time as seconds since midnight.\n");
- printf("If no argument given, returns current time.\n");
- printf("HELP DATE for info about date-time formats.\n");
- break;
-
- case FN_N2TIM:
- printf("\\fn2time(seconds) - Numeric Time to Time.\n");
- printf(
-"Returns the given number of seconds in hh:mm:ss format.\n");
- break;
-
- case FN_PERM:
- printf("\\fpermissions(file) - Permissions of File.\n");
- printf(
-#ifdef UNIX
-"Returns permissions of given file as they would be shown by \"ls -l\".\n"
-#else
-#ifdef VMS
-"Returns permissions of given file as they would be shown by \"dir /prot\".\n"
-#else
-"Returns the permissions of the given file.\n"
-#endif /* VMS */
-#endif /* UNIX */
- );
- break;
-
- case FN_ALOOK:
- printf("\\farraylook(pattern,&a) - Lookup pattern in array.\n\
- pattern = String or pattern\n");
- printf(" &a = array designator, can include range specifier.\n");
- printf(
-"Returns number:\n\
- The index of the first matching array element or -1 if none.\n");
- printf("More info:\n\
- HELP PATTERN for pattern syntax.\n HELP ARRAY for arrays.\n");
- break;
-
- case FN_TLOOK:
- printf(
-"\\ftablelook(keyword,&a,[c]) - Lookup keyword in keyword table.\n\
- pattern = String\n");
- printf(" keyword = keyword to look up (can be abbreviated).\n");
- printf(" &a = array designator, can include range specifier.\n");
- printf(" This array must be in alphabetical order.\n");
- printf(" c = Optional field delimiter, colon(:) by default.\n");
- printf(
-"Returns number:\n\
- 1 or greater, index of array element that uniquely matches given keyword;\n"
- );
- printf(
-"or -2 if keyword was ambiguous, or -1 if keyword empty or not found.\n"
- );
- printf("Also see:\n\
- HELP FUNC ARRAYLOOK for a similar function.\n HELP ARRAY for arrays.\n");
- break;
-
- case FN_ABS: /* Absolute */
- printf("\\fabsolute(n1)\n\
- n1 = integer.\n");
- printf("Returns integer:\n\
- The absolute (unsigned) value of n1.\n");
- break;
-
-#ifdef FNFLOAT
- case FN_FPABS:
- printf("\\ffpabsolute(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The absolute (unsigned) value of f1 to d decimal places.\n");
- break;
-
- case FN_FPADD:
- printf("\\ffpadd(f1,f2,d)\n\
- f1,f2 = floating-point numbers or integers.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The sum of f1 and f2 to d decimal places.\n");
- break;
-
- case FN_FPSUB:
- printf("\\ffpsubtract(f1,f2,d)\n\
- f1,f2 = floating-point numbers or integers.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- f1 minus f2 to d decimal places.\n");
- break;
-
- case FN_FPMUL:
- printf("\\ffpmultiply(f1,f2,d)\n\
- f1,f2 = floating-point numbers or integers.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The product of f1 and f2 to d decimal places.\n");
- break;
-
- case FN_FPDIV:
- printf("\\ffpdivide(f1,f2,d)\n\
- f1,f2 = floating-point numbers or integers.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- f1 divided by f2 to d decimal places.\n");
- break;
-
- case FN_FPMAX:
- printf("\\ffpmaximum(f1,f2,d)\n\
- f1,f2 = floating-point numbers or integers.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The maximum of f1 and f2 to d decimal places.\n");
- break;
-
- case FN_FPMIN:
- printf("\\ffpminimum(f1,f2,d)\n\
- f1,f2 = floating-point numbers or integers.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The minimum of f1 and f2 to d decimal places.\n");
- break;
-
- case FN_FPMOD:
- printf("\\ffpmodulus(f1,f2,d)\n\
- f1,f2 = floating-point numbers or integers.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The modulus of f1 and f2 to d decimal places.\n");
- break;
-
- case FN_FPPOW:
- printf("\\ffpraise(f1,f2,d)\n\
- f1,f2 = floating-point numbers or integers.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- f1 raised to the power f2, to d decimal places.\n");
- break;
-
- case FN_FPCOS:
- printf("\\ffpcosine(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The cosine of angle f1 (in radians) to d decimal places.\n");
- break;
-
- case FN_FPSIN:
- printf("\\ffpsine(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The sine of angle f1 (in radians) to d decimal places.\n");
- break;
-
- case FN_FPTAN:
- printf("\\ffptangent(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The tangent of angle f1 (in radians) to d decimal places.\n");
- break;
-
- case FN_FPEXP:
- printf("\\ffpexp(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- e (the base of natural logarithms) raised to the f1 power,\n\
- to d decimal places.\n");
- break;
-
- case FN_FPINT:
- printf("\\ffpint(f1)\n\
- f1 = floating-point number or integer.\n");
- printf("Returns integer:\n\
- The integer part of f1.\n");
- break;
-
- case FN_FPLOG:
- printf("\\ffplog10(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The logarithm, base 10, of f1 to d decimal places.\n");
- break;
-
- case FN_FPLN:
- printf("\\ffplogn(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The natural logarithm of f1 to d decimal places.\n");
- break;
-
- case FN_FPROU:
- printf("\\ffpround(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- f1 rounded to d decimal places.\n");
- break;
-
- case FN_FPSQR:
- printf("\\ffpsqrt(f1,d)\n\
- f1 = floating-point number or integer.\n\
- d = integer.\n");
- printf("Returns floating-point number:\n\
- The square root of f1 to d decimal places.\n");
- break;
-#endif /* FNFLOAT */
-
-#ifdef CKCHANNELIO
- case FN_FEOF:
- printf("\\f_eof(n1)\n\
- n1 = channel number.\n");
- printf("Returns number:\n\
- 1 if channel n1 at end of file, 0 otherwise.\n");
- break;
- case FN_FPOS:
- printf("\\f_pos(n1)\n\
- n1 = channel number.\n");
- printf("Returns number:\n\
- Read/write pointer of channel n1 as byte number.\n");
- break;
- case FN_NLINE:
- printf("\\f_line(n1)\n\
- n1 = channel number.\n");
- printf("Returns number:\n\
- Read/write pointer of channel n1 as line number.\n");
- break;
- case FN_FILNO:
- printf("\\f_handle(n1)\n\
- n1 = channel number.\n");
- printf("Returns number:\n\
- File %s of open file on channel n1.\n",
-#ifdef OS2
- "handle"
-#else
- "descriptor"
-#endif /* OS2 */
- );
- break;
- case FN_FSTAT:
- printf("\\f_status(n1)\n\
- n1 = channel number.\n");
- printf("Returns number:\n\
- Sum of open modes of channel n1: 1 = read; 2 = write; 4 = append, or:\n\
- 0 if not open.\n");
- break;
- case FN_FGCHAR:
- printf("\\f_getchar(n1)\n\
- n1 = channel number.\n");
- printf(" Reads a character from channel n1 and returns it.\n");
- break;
- case FN_FGLINE:
- printf("\\f_getline(n1)\n\
- n1 = channel number.\n");
- printf(" Reads a line from channel n1 and returns it.\n");
- break;
- case FN_FGBLK:
- printf("\\f_getblock(n1,n2)\n\
- n1 = channel number, n2 = size\n");
- printf(
-" Reads a block of n2 characters from channel n1 and returns it.\n");
- break;
- case FN_FPCHAR:
- printf("\\f_putchar(n1,c)\n\
- n1 = channel number, c = character\n");
- printf(" Writes a character to channel n1.\n\
-Returns number:\n\
- 1 if successful, otherwise a negative error code.\n");
- break;
- case FN_FPLINE:
- printf("\\f_putline(n1,s1)\n\
- n1 = channel number, s1 = string\n");
- printf(
-" Writes the string s1 to channel n1 and adds a line terminator.\n\
-Returns number:\n");
- printf(" How many characters written if successful;\n\
- Otherwise a negative error code.\n"
- );
- break;
- case FN_FPBLK:
- printf("\\f_putblock(n1,s1)\n\
- n1 = channel number, s1 = string\n");
- printf(
-" Writes the string s1 to channel n1.\n\
- Returns number:\n");
- printf(" How many characters written if successful;\n\
- Otherwise a negative error code.\n"
- );
- break;
- case FN_FERMSG:
- printf("\\f_errmsg([n1])\n\
- n1 = numeric error code, \\v(f_error) by default.\n");
- printf(" Returns the associated error message string.\n");
- break;
-#endif /* CKCHANNELIO */
-
- case FN_AADUMP:
- printf("\\faaconvert(name,&a[,&b])\n\
- name = name of associative array, &a and &b = names of regular arrays.\n");
- printf(
-" Converts the given associative array into two regular arrays, &a and &b,\n\
- containing the indices and values, respectively:\n");
- printf("Returns number:\n\
- How many elements were converted.\n");
- break;
-
-#ifdef CK_KERBEROS
- case FN_KRB_TK:
- printf("\\fkrbtickets(n)\n\
- n = Kerberos version number (4 or 5).\n\
- Returns string:\n\
- The number of active Kerberos 4 or 5 tickets.\n\
- Resets the ticket list used by \\fkrbnextticket(n).\n");
- break;
-
- case FN_KRB_NX:
- printf("\\fkrbnextticket(n)\n\
- n = Kerberos version number (4 or 5).\n\
- Returns string:\n\
- The next ticket in the Kerberos 4 or 5 ticket list that was set up by\n\
- the most recent invocation of \\fkrbtickets(n).\n");
- break;
-
- case FN_KRB_IV:
- printf("\\fkrbisvalid(n,name)\n\
- n = Kerberos version number (4 or 5).\n\
- name = a ticket name as returned by \\fkrbnextticket(n).\n\
- Returns number:\n\
- 1 if the ticket is valid, 0 if not valid.\n\
- A ticket is valid if all the following conditions are true:\n\n");
- printf("\n\
- (i) it exists in the current cache file;\n\
- (ii) it is not expired;\n\
- (iii) it is not marked invalid (K5 only);\n\
- (iv) it was issued from the current IP address\n");
- printf("\n This value can be used in an IF statement, e.g.:\n\n");
- printf(" if \\fkrbisvalid(4,krbtgt.FOO.BAR.EDU@FOO.BAR.EDU) ...\n");
- break;
-
- case FN_KRB_TT:
- printf("\\fkrbtimeleft(n,name)\n\
- n = Kerberos version number (4 or 5).\n\
- name = a ticket name as returned by \\fkrbnextticket(n).\n\
- Returns string:\n\
- The number of seconds remaining in the ticket's lifetime.\n");
- break;
-
- case FN_KRB_FG:
- printf("\\fkrbflags(n,name)\n\
- n = Kerberos version number (4 or 5).\n\
- name = a ticket name as returned by \\fkrbnextticket(n).\n\
- Returns string:\n");
- printf(
-" The flags string as reported with AUTH K5 LIST /FLAGS. This string can\n\
- be searched for a particular flag using the \\findex() function when\n\
- SET CASE is ON (for case sensitive searches). Flag strings are only\n\
- available for K5 tickets.\n");
- break;
-#endif /* CK_KERBEROS */
-
- case FN_PATTERN:
- printf("\\fpattern(s)\n\
- s = string\n\
- Returns string: s with any variables, etc, evaluated in the normal manner.\n"
- );
- printf("\
- For use with INPUT, MINPUT, and REINPUT to declare that a search target is\n\
- a pattern rather than a literal string.\n");
- break;
-
- case FN_HEX2N:
- printf("\\fhex2n(s)\n\
- s = hexadecimal number\n\
- Returns decimal equivalent.\n");
- break;
-
- case FN_HEX2IP:
- printf("\\fhex2ip(s)\n\
- s = 8-digit hexadecimal number\n\
- Returns the equivalent decimal dotted IP address.\n");
- break;
-
- case FN_IP2HEX:
- printf("\\fip2hex(s)\n\
- s = decimal dotted IP address\n\
- Returns the equivalent 8-digit hexadecimal number.\n");
- break;
-
- case FN_OCT2N:
- printf("\\foct2n(s)\n\
- s = octal number\n\
- Returns decimal equivalent.\n");
- break;
-
- case FN_RADIX:
- printf("\\fradix(s,n1,n2)\n\
- s = number in radix n1\n\
- Returns the number's representation in radix n2.\n");
- break;
-
- case FN_JOIN:
- printf("\\fjoin(&a[,s[,n1[,n2]]])\n\
- &a = array designator, can include range specifier.\n\
- s = optional separator.\n");
- printf("\
- n1 = nonzero to put grouping around elements that contain spaces;\n\
- see \\fword() grouping mask for values of n.\n");
- printf("\
- n2 = 0 or omitted to put spaces between elements; nonzero to omit them.\n");
- printf("\
- Returns the (selected) elements of the array joined to together,\n\
- separated by the separator.\n");
- break;
-
- case FN_SUBST:
- printf("\\fsubstitute(s1,s2,s3)\n\
- s1 = Source string.\n\
- s2 = List of characters to be translated.\n\
- s3 = List of characters to translate them to.\n");
- printf(
-" Returns: s1, with each character that is in s2 translated to the\n\
- corresponding character in s3. s2 and s3 can contain ASCII ranges,\n\
- like [a-z]. Any characters in s2 that don't have corresponding\n\
- characters in s3 (after range expansion) are removed from the result.\n");
- break;
-
-#ifndef NOSEXP
- case FN_SEXP:
- printf("\\fsexpression(s1)\n\
- s1 = S-Expression.\n");
- printf(" Returns: The result of evaluating s1.\n");
- break;
-
-#endif /* NOSEXP */
-
- case FN_CMDSTK:
- printf("\\fcmdstack(n1,n2)\n\
- n1 = Command-stack level, 0 to \\v(cmdlevel), default \\v(cmdlevel).\n\
- n2 = Function code, 0 or 1.\n");
- printf("Returns:\n");
- printf(" n2 = 0: name of object at stack level n1\n\
- n2 = 1: type of object at stack level n1:\n\
- 0 = interactive prompt\n\
- 1 = command file\n\
- 2 = macro\n"
- );
- break;
-
-#ifdef CKFLOAT
- case FN_DIFDATE:
- printf("\\fdiffdates(d1,d2)\n\
- d1 = free-format date and/or time (default = NOW).\n\
- d2 = ditto.\n");
- printf("Returns:\n");
- printf(" Difference expressed as delta time:\n");
- printf(" Negative if d2 is later than d1, otherwise positive.\n");
- break;
-#endif /* CKFLOAT */
-
- case FN_CMPDATE:
- printf("\\fcmpdates(d1,d2)\n\
- d1 = free-format date and/or time (default = NOW).\n\
- d2 = ditto.\n");
- printf("Returns:\n");
- printf(" 0 if d1 is equal to d2;\n\
- 1 if d1 is later than d2;\n\
- -1 if d1 is earlier than d2.\n");
- break;
-
- case FN_TOGMT:
- printf("\\futcdate(d1)\n\
- d1 = free-format date and/or time (default = NOW).\n");
- printf("Returns:\n");
- printf(" Date-time converted to UTC (GMT) yyyymmdd hh:mm:ss.\n");
- break;
-
-#ifdef TCPSOCKET
- case FN_HSTADD:
- printf("\\faddr2name(s)\n\
- s = numeric IP address.\n");
- printf("Returns:\n");
- printf(" Corresponding IP hostname if found, otherwise null.\n");
- break;
- case FN_HSTNAM:
- printf("\\fname2addr(s)\n\
- s = IP host name.\n");
- printf("Returns:\n");
- printf(" Corresponding numeric IP address if found, else null.\n");
- break;
-#endif /* TCPSOCKET */
-
- case FN_DELSEC:
- printf("\\fdelta2secs(dt)\n\
- dt = Delta time, e.g. +3d14:27:52.\n");
- printf("Returns:\n");
- printf(" The corresponding number of seconds.\n");
- break;
-
- case FN_PC_DU:
- printf("\\fdos2unixpath(p)\n\
- p = string, DOS pathname.\n");
- printf("Returns:\n");
- printf(" The argument converted to a Unix pathname.\n");
- break;
-
- case FN_PC_UD:
- printf("\\funix2dospath(p)\n\
- p = string, Unix pathname.\n");
- printf("Returns:\n");
- printf(" The argument converted to a DOS pathname.\n");
- break;
-
-#ifdef FN_ERRMSG
- case FN_ERRMSG:
- printf("\\ferrstring(n)\n\
- n = platform-dependent numeric error code.\n");
- printf("Returns:\n");
- printf(" The corresponding error string.\n");
- break;
-#endif /* FN_ERRMSG */
-
- case FN_KWVAL:
- printf("\\fkeywordvalue(s1,c1)\n\
- s1 = string of the form \"name=value\"\n\
- c1 = separator character (default separator is \"=\")\n");
- printf(" Assigns the value, if any, to the named macro.\n");
- printf(" If s1 contains no separator, nothing happens.\n");
- printf(
-" If s1 contains a separator but no value, the macro is undefined.\n");
- printf("Returns:\n");
- printf(" 0 on failure\n");
- printf(" 1 on success\n");
- break;
-
-#ifdef COMMENT
- case FN_SLEEP:
- printf("\\fsleep(n)\n\
- n = number of seconds\n");
- printf(" Pauses for the given number of seconds.\n");
- printf("Returns: the empty string.\n");
- break;
-
- case FN_MSLEEP:
- printf("\\fmsleep(n)\n\
- n = number of milliseconds\n");
- printf(" Pauses for the given number of milliseconds.\n");
- printf("Returns: the empty string.\n");
- break;
-#endif /* COMMENT */
-
-#ifdef NT
- case FN_SNAME:
- printf("\\fshortpathname(s)\n\
- s = file or directory name string\n");
- printf(" Returns the short path form of the given input.\n");
- break;
-
- case FN_LNAME:
- printf("\\flongpathname(s)\n\
- s = file or directory name string\n");
- printf(" Returns the long path form of the given input.\n");
- break;
-#else
- case FN_SNAME:
- printf("\\fshortpathname(s)\n\
- Synonym for \fpathname()\n");
- break;
-
- case FN_LNAME:
- printf("\\flongpathname(s)\n\
- Synonym for \fpathname()\n");
- break;
-#endif /* NT */
-
- default:
- printf("Sorry, help not available for \"%s\"\n",cmdbuf);
- }
- printf("\n");
- return(0);
-}
-#endif /* NOSPL */
-
-#ifdef OS2
-#ifndef NOKVERBS
-
-/* D O H K V E R B -- Give help for a Kverb */
-
-int
-dohkverb(xx) int xx; {
- int x,i,found,button,event;
-
- if (xx == -3) {
- printf("\n Type SHOW KVERBS to see a list of available Kverbs.\n"
- );
- printf(
-" Type HELP KVERB <name> to see the current definition of a given Kverb.\n\n"
- );
- return(-9);
- }
- if (xx < 0) return(xx);
- if ((x = cmcfm()) < 0) return(x);
- switch ( xx ) {
- /* DEC VT keyboard key definitions */
-
- case K_COMPOSE : /* Compose key */
- printf("\\Kcompose Compose an accented character\n");
- break;
- case K_C_UNI16 : /* UCS2 key */
- printf("\\Kucs2 Enter a Unicode character\n");
- break;
-
-/* DEC arrow keys */
-
- case K_UPARR : /* DEC Up Arrow key */
- printf("\\Kuparr Transmit Terminal Up Arrow sequence\n");
- break;
- case K_DNARR : /* DEC Down Arrow key */
- printf("\\Kdnarr Transmit Terminal Down Arrow sequence\n");
- break;
- case K_RTARR : /* DEC Right Arrow key */
- printf("\\Krtarr Transmit Terminal Right Arrow sequence\n");
- break;
- case K_LFARR : /* DEC Left Arrow key */
- printf("\\Klfarr Transmit Terminal Left Arrow sequence\n");
- break;
-
- case K_PF1 : /* DEC PF1 key */
- printf("\\Kpf1,\\Kgold Transmit DEC PF1 sequence\n");
- break;
- case K_PF2 : /* DEC PF2 key */
- printf("\\Kpf2 Transmit DEC PF2 sequence\n");
- break;
- case K_PF3 : /* DEC PF3 key */
- printf("\\Kpf3 Transmit DEC PF3 sequence\n");
- break;
- case K_PF4 : /* DEC PF4 key */
- printf("\\Kpf4 Transmit DEC PF4 sequence\n");
- break;
-
- case K_KP0 : /* DEC Keypad 0 */
- printf("\\Kkp0 Transmit DEC Keypad-0 sequence\n");
- break;
- case K_KP1 : /* DEC Keypad 1 */
- printf("\\Kkp1 Transmit DEC Keypad-1 sequence\n");
- break;
- case K_KP2 : /* etc ... through 9 */
- printf("\\Kkp2 Transmit DEC Keypad-2 sequence\n");
- break;
- case K_KP3 :
- printf("\\Kkp3 Transmit DEC Keypad-3 sequence\n");
- break;
- case K_KP4 :
- printf("\\Kkp4 Transmit DEC Keypad-4 sequence\n");
- break;
- case K_KP5 :
- printf("\\Kkp5 Transmit DEC Keypad-5 sequence\n");
- break;
- case K_KP6 :
- printf("\\Kkp6 Transmit DEC Keypad-6 sequence\n");
- break;
- case K_KP7 :
- printf("\\Kkp7 Transmit DEC Keypad-7 sequence\n");
- break;
- case K_KP8 :
- printf("\\Kkp8 Transmit DEC Keypad-8 sequence\n");
- break;
- case K_KP9 :
- printf("\\Kkp9 Transmit DEC Keypad-9 sequence\n");
- break;
- case K_KPCOMA : /* DEC keypad comma */
- printf("\\Kkpcoma Transmit DEC Keypad-Comma sequence\n");
- break;
- case K_KPMINUS : /* DEC keypad minus */
- printf("\\Kkpminus Transmit DEC Keypad-Minus sequence\n");
- break;
- case K_KPDOT : /* DEC keypad period */
- printf("\\Kkpdot Transmit DEC Keypad-Period sequence\n");
- break;
- case K_KPENTER : /* DEC keypad enter */
- printf("\\Kkpenter Transmit DEC Keypad-Enter sequence\n");
- break;
-
-/* DEC Top-Rank F keys */
-
- case K_DECF1 : /* DEC F1 key */
- printf("\\Kdecf1 Transmit DEC F1 sequence for PC keyboard\n");
- break;
- case K_DECF2 : /* DEC F2 key */
- printf("\\Kdecf2 Transmit DEC F2 sequence for PC keyboard\n");
- break;
- case K_DECF3 : /* DEC F3 key */
- printf("\\Kdecf3 Transmit DEC F3 sequence for PC keyboard\n");
- break;
- case K_DECF4 : /* DEC F4 key */
- printf("\\Kdecf4 Transmit DEC F4 sequence for PC keyboard\n");
- break;
- case K_DECF5 : /* DEC F5 key */
- printf("\\Kdecf5 Transmit DEC F5 sequence for PC keyboard\n");
- break;
- case K_DECHOME: /* DEC HOME key */
- printf("\\Kdechome Transmit DEC HOME sequence for PC keyboard\n");
- break;
-
- case K_DECF6 : /* DEC F6 key */
- printf("\\Kdecf6 Transmit DEC F6 sequence\n");
- break;
- case K_DECF7 : /* etc, through F20 */
- printf("\\Kdecf7 Transmit DEC F7 sequence\n");
- break;
- case K_DECF8 :
- printf("\\Kdecf8 Transmit DEC F8 sequence\n");
- break;
- case K_DECF9 :
- printf("\\Kdecf9 Transmit DEC F9 sequence\n");
- break;
- case K_DECF10 :
- printf("\\Kdecf10 Transmit DEC F10 sequence\n");
- break;
- case K_DECF11 :
- printf("\\Kdecf11 Transmit DEC F11 sequence\n");
- break;
- case K_DECF12 :
- printf("\\Kdecf12 Transmit DEC F12 sequence\n");
- break;
- case K_DECF13 :
- printf("\\Kdecf13 Transmit DEC F13 sequence\n");
- break;
- case K_DECF14 :
- printf("\\Kdecf14 Transmit DEC F14 sequence\n");
- break;
- case K_DECHELP : /* DEC Help key */
- printf("\\Kdecf15,\\Kdechelp Transmit DEC HELP sequence\n");
- break;
- case K_DECDO : /* DEC Do key */
- printf("\\Kdecf16,\\Kdecdo Transmit DEC DO sequence\n");
- break;
- case K_DECF17 :
- printf("\\Kdecf17 Transmit DEC F17 sequence\n");
- break;
- case K_DECF18 :
- printf("\\Kdecf18 Transmit DEC F18 sequence\n");
- break;
- case K_DECF19 :
- printf("\\Kdecf19 Transmit DEC F19 sequence\n");
- break;
- case K_DECF20 :
- printf("\\Kdecf20 Transmit DEC F20 sequence\n");
- break;
-
-/* DEC editing keys */
-
- case K_DECFIND : /* DEC Find key */
- printf("\\Kdecfind Transmit DEC FIND sequence\n");
- break;
- case K_DECINSERT : /* DEC Insert key */
- printf("\\Kdecinsert Transmit DEC INSERT HERE sequence\n");
- break;
- case K_DECREMOVE : /* DEC Remove key */
- printf("\\Kdecremove Transmit DEC REMOVE sequence\n");
- break;
- case K_DECSELECT : /* DEC Select key */
- printf("\\Kdecfselect Transmit DEC SELECT sequence\n");
- break;
- case K_DECPREV : /* DEC Previous Screen key */
- printf("\\Kdecprev Transmit DEC PREV SCREEN sequence\n");
- break;
- case K_DECNEXT : /* DEC Next Screen key */
- printf("\\Kdecnext Transmit DEC NEXT SCREEN sequence\n");
- break;
-
-/* DEC User-Defined Keys */
-
- case K_UDKF1 : /* F1 - F5 are XTERM extensions */
- printf("\\Kudkf1 Transmit XTERM F1 User Defined Key sequence\n");
- break;
- case K_UDKF2 :
- printf("\\Kudkf2 Transmit XTERM F2 User Defined Key sequence\n");
- break;
- case K_UDKF3 :
- printf("\\Kudkf3 Transmit XTERM F3 User Defined Key sequence\n");
- break;
- case K_UDKF4 :
- printf("\\Kudkf4 Transmit XTERM F4 User Defined Key sequence\n");
- break;
- case K_UDKF5 :
- printf("\\Kudkf5 Transmit XTERM F5 User Defined Key sequence\n");
- break;
- case K_UDKF6 : /* DEC User Defined Key F6 */
- printf("\\Kudkf6 Transmit DEC F6 User Defined Key sequence\n");
- break;
- case K_UDKF7 : /* DEC User Defined Key F7 */
- printf("\\Kudkf7 Transmit DEC F7 User Defined Key sequence\n");
- break;
- case K_UDKF8 : /* etc ... through F20 */
- printf("\\Kudkf8 Transmit DEC F8 User Defined Key sequence\n");
- break;
- case K_UDKF9 :
- printf("\\Kudkf9 Transmit DEC F9 User Defined Key sequence\n");
- break;
- case K_UDKF10 :
- printf("\\Kudkf10 Transmit DEC F10 User Defined Key sequence\n");
- break;
- case K_UDKF11 :
- printf("\\Kudkf11 Transmit DEC F11 User Defined Key sequence\n");
- break;
- case K_UDKF12 :
- printf("\\Kudkf12 Transmit DEC F12 User Defined Key sequence\n");
- break;
- case K_UDKF13 :
- printf("\\Kudkf13 Transmit DEC F13 User Defined Key sequence\n");
- break;
- case K_UDKF14 :
- printf("\\Kudkf14 Transmit DEC F14 User Defined Key sequence\n");
- break;
- case K_UDKHELP :
- printf(
- "\\Kudkhelp,\\Kudkf15 Transmit DEC HELP User Defined Key sequence\n");
- break;
- case K_UDKDO :
- printf(
- "\\Kudkdo,\\Kudkf16 Transmit DEC DO User Defined Key sequence\n");
- break;
- case K_UDKF17 :
- printf("\\Kudkf17 Transmit DEC F17 User Defined Key sequence\n");
- break;
- case K_UDKF18 :
- printf("\\Kudkf18 Transmit DEC F18 User Defined Key sequence\n");
- break;
- case K_UDKF19 :
- printf("\\Kudkf19 Transmit DEC F19 User Defined Key sequence\n");
- break;
- case K_UDKF20 :
- printf("\\Kudkf20 Transmit DEC F20 User Defined Key sequence\n");
- break;
-
-/* Emacs Keys */
- case K_EMACS_OVER:
- printf(
- "\\Kemacs_overwrite Transmit EMACS Overwrite toggle command sequence\n");
- break;
-
-/* Kermit screen-scrolling keys */
-
- case K_DNONE : /* Screen rollback: down one line */
- printf("\\Kdnone Screen rollback: down one line\n");
- break;
- case K_DNSCN : /* Screen rollback: down one screen */
- printf("\\Kdnscn Screen rollback: down one screen\n");
- break;
- case K_UPONE : /* Screen rollback: Up one line */
- printf("\\Kupone Screen rollback: up one line\n");
- break;
- case K_UPSCN : /* Screen rollback: Up one screen */
- printf("\\Kupscn Screen rollback: up one screen\n");
- break;
- case K_ENDSCN : /* Screen rollback: latest screen */
- printf("\\Kendscn Screen rollback: latest screen\n");
- break;
- case K_HOMSCN : /* Screen rollback: oldest screen */
- printf("\\Khomscn Screen rollback: oldest screen\n");
- break;
- case K_GO_BOOK : /* Scroll to bookmark */
- printf("\\Kgobook Screen rollback: go to bookmark\n");
- break;
- case K_GOTO : /* Scroll to line number */
- printf("\\Kgoto Screen rollback: go to line number\n");
- break;
-
- case K_LFONE : /* Horizontal Scroll: Left one cell */
- printf("\\Klfone Horizontal Scroll: Left one column\n");
- break;
- case K_LFPAGE : /* Horizontal Scroll: Left one page */
- printf("\\Klfpage Horizontal Scroll: Left eight columns\n");
- break;
- case K_LFALL :
- printf("\\Klfall Horizontal Scroll: Left to margin\n");
- break;
- case K_RTONE : /* Horizontal Scroll: Right one cell */
- printf("\\Krtone Horizontal Scroll: Right one column\n");
- break;
- case K_RTPAGE : /* Horizontal Scroll: Right one page */
- printf("\\Krtpage Horizontal Scroll: Right eight columns\n");
- break;
- case K_RTALL :
- printf("\\Krtall Horizontal Scroll: Right to margin\n");
- break;
-
-/* Keyboard language switching verbs */
-
- case K_KB_ENG : /* English keyboard mode */
- printf("\\Kkbenglish Switch to Normal (English) keyboard mode\n");
- break;
- case K_KB_HEB : /* Hebrew keyboard mode */
- printf("\\Kkbhebrew Switch to Hebrew keyboard mode\n");
- break;
- case K_KB_RUS : /* Russian keyboard mode */
- printf("\\Kkbrussian Switch to Russian keyboard mode\n");
- break;
- case K_KB_EMA : /* Emacs keyboard mode */
- printf("\\Kkbemacs Switch to EMACS keyboard mode\n");
- break;
- case K_KB_WP : /* Word Perfect 5.1 mode */
- printf("\\Kkbwp Switch to Word Perfect 5.1 keyboard mode\n");
- break;
-
-/* Mark Mode actions */
-
- case K_MARK_START : /* Enter Mark Mode/Start marking */
- printf("\\Kmarkstart Mark Mode: Enter mode or Start marking\n");
- break;
- case K_MARK_CANCEL : /* Exit Mark Mode - Do Nothing */
- printf("\\Kmarkcancel Mark Mode: Cancel mode\n");
- break;
- case K_MARK_COPYCLIP: /* Exit Mark Mode - Copy data to clipboard */
- printf("\\Kmarkcopyclip Mark Mode: Copy marked text to clipboard\n");
- break;
- case K_MARK_COPYHOST: /* Exit Mark Mode - Copy data to host */
- printf("\\Kmarkcopyhost Mark Mode: Copy marked text to host\n");
- break;
- case K_MARK_SELECT : /* Exit Mark Mode - Select */
- printf(
- "\\Kmarkselect Mark Mode: Place marked text into \\v(select)\n");
- break;
- case K_BACKSRCH : /* Search Backwards for text */
- printf("\\Kbacksearch Search: Begin backward search for text\n");
- break;
- case K_FWDSRCH : /* Search Forwards for text */
- printf("\\Kfwdsearch Search: Begin forward search for text\n");
- break;
- case K_BACKNEXT : /* Search Backwards for next instance of text */
- printf(
- "\\Kbacknext Search: Find next instance of text backwards\n");
- break;
- case K_FWDNEXT : /* Search Forwards for next instance of text */
- printf("\\Kfwdnext Search: Find next instance of text forwards\n");
- break;
-
-/* Miscellaneous Kermit actions */
-
- case K_EXIT : /* Return to command parser */
- printf("\\Kexit Toggle between COMMAND and CONNECT modes\n");
- break;
- case K_BREAK : /* Send a BREAK */
- printf("\\Kbreak Transmit BREAK signal to host\n");
- break;
- case K_RESET : /* Reset emulator */
- printf("\\Kreset Reset Terminal Emulator to user defaults\n");
- break;
- case K_DOS : /* Push to DOS (i.e. OS/2) */
- printf("\\Kdos,\\Kos2 Push to Command Shell\n");
- break;
- case K_HANGUP : /* Hang up the connection */
- printf("\\Khangup Hangup the active connection\n");
- break;
- case K_DUMP : /* Dump/Print current screen */
- printf(
- "\\Kdump Dump/copy current screen to SET PRINTER device/file\n");
- break;
- case K_LBREAK : /* Send a Long BREAK */
- printf("\\Klbreak Transmit LONG BREAK signal to host\n");
- break;
- case K_NULL : /* Send a NUL */
- printf("\\Knull Transmit NULL ('\0') character to host\n");
- break;
- case K_HELP : /* Pop-up help */
- printf("\\Khelp Raise Pop-Up help display\n");
- break;
- case K_HOLDSCRN : /* Hold screen */
- printf("\\Kholdscrn Pause data input during CONNECT mode\n");
- break;
- case K_IGNORE : /* Ignore this key, don't even beep */
- printf("\\Kignore Ignore key\n");
- break;
-
- case K_LOGOFF : /* Turn off session logging */
- printf("\\Klogoff Turn off session logging (see \\Ksession)\n");
- break;
- case K_LOGON : /* Turn on session logging */
- printf("\\Klogon Turn on session logging (see \\Ksession)\n");
- break;
- case K_SESSION:
- printf(
- "\\Ksession Toggle on/off session logging to 'session.log'\n");
- break;
- case K_AUTODOWN:
- printf("\\Kautodown Toggle on/off terminal autodownload.\n");
- break;
- case K_BYTESIZE:
- printf(
- "\\Kbytesize Toggle terminal bytesize between 7 and 8 bits.\n");
- break;
-
-#ifdef COMMENT
- case MODELINE:
- case K_NETHOLD : /* Put network connection on hold */
- case K_NEXTSESS : /* Toggle to next network session */
-#endif /* COMMENT */
-
- case K_CURSOR_URL:
- printf(
- "\\Kurl Treat text under cursor position as a URL\n");
- break;
- case K_STATUS : /* Show status */
- printf(
- "\\Kstatus Toggle statusline (None, Indicator, Host Writeable)\n");
- break;
- case K_TERMTYPE : /* Toggle term type: text/graphics */
- printf("\\Ktermtype Toggle Terminal Type\n");
- break;
- case K_PRTCTRL : /* Print Controller mode */
- printf("\\Kprtctrl Toggle Ctrl-Print (transparent) mode\n");
- break;
- case K_PRINTFF : /* Print formfeed */
- printf("\\Kprintff Output Form Feed to SET PRINTER device\n");
- break;
- case K_FLIPSCN : /* Flip screen */
- printf("\\Kflipscn Reverse foreground and background colors\n");
- break;
- case K_DEBUG : /* Toggle debugging */
- printf("\\Kdebug Toggle Terminal Debug mode\n");
- break;
- case K_TN_SAK : /* TELNET Secure Access Key */
- printf("\\Ktn_sak TELNET: IBM Secure Access Key\n");
- printf(" Used to request a Trusted Shell with AIX\n");
- break;
- case K_TN_AO : /* TELNET Cancel Output */
- printf("\\Ktn_ao TELNET: Transmit Cancel-Output request\n");
- break;
- case K_TN_AYT : /* TELNET Are You There */
- printf("\\Ktnayt TELNET: Transmit Are You There? request\n");
- break;
- case K_TN_EC : /* TELNET Erase Character */
- printf("\\Ktn_ec TELNET: Transmit Erase Character request\n");
- break;
- case K_TN_EL : /* TELNET Erase Line */
- printf("\\Ktn_el TELNET: Transmit Erase Line request\n");
- break;
- case K_TN_GA : /* TELNET Go Ahead */
- printf("\\Ktn_ga TELNET: Transmit Go Ahead request\n");
- break;
- case K_TN_IP : /* TELNET Interrupt Process */
- printf("\\Ktn_ip TELNET: Transmit Interrupt Process request\n");
- break;
- case K_TN_LOGOUT : /* TELNET Logout */
- printf("\\Ktn_logout TELNET: Transmit Do Logout Option\n");
- break;
- case K_TN_NAWS : /* TELNET NAWS */
- printf(
- "\\Ktn_naws TELNET: Transmit Window Size if NAWS is active\n");
- break;
- case K_PASTE : /* Paste data from clipboard */
- printf("\\Kpaste Paste data from clipboard to host\n");
- break;
- case K_CLRSCRN : /* Clear Terminal Screen */
- printf("\\Kclearscreen Clear the Terminal screen\n");
- break;
- case K_PRTAUTO : /* Print Auto mode */
- printf("\\Kprtauto Toggle Auto-Print mode\n");
- break;
- case K_PRTCOPY : /* Print Copy mode */
- printf("\\Kprtcopy Toggle Copy-Print mode\n");
- break;
- case K_ANSWERBACK : /* Transmit Answerback String */
- printf("\\Kanswerback Transmit answerback string to host\n");
- break;
- case K_SET_BOOK : /* Set Bookmark */
- printf("\\Ksetbook Set bookmark\n");
- break;
- case K_QUIT : /* Quit Kermit */
- printf("\\Kquit Hangup connection and quit kermit\n");
- break;
- case K_KEYCLICK : /* Toggle Keyclick */
- printf("\\Kkeyclick Toggle Keyclick mode\n");
- break;
- case K_LOGDEBUG : /* Toggle Debug Log File */
- printf("\\Klogdebug Toggle Debug Logging to File\n");
- break;
- case K_FNKEYS : /* Show Function Key Labels */
- printf("\\Kfnkeys Display Function Key Labels\n");
- break;
-
-#ifdef OS2MOUSE
-/* Mouse only Kverbs */
-
- case K_MOUSE_CURPOS :
- printf("\\Kmousecurpos Mouse: Move host cursor to position\n");
- break;
- case K_MOUSE_MARK :
- printf(
- "\\Kmousemark Mouse: Mark text for selection (drag event only)\n");
- break;
- case K_MOUSE_URL :
- printf("\\Kmouseurl Mouse: Start browser with selected URL\n");
- break;
-#endif /* OS2MOUSE */
-
-/* ANSI Function Key definitions */
- case K_ANSIF01 :
- printf("\\Kansif01 Transmit SCOANSI/AT386: F1 \n");
- break;
- case K_ANSIF02 :
- printf("\\Kansif02 Transmit SCOANSI/AT386: F2 \n");
- break;
- case K_ANSIF03 :
- printf("\\Kansif03 Transmit SCOANSI/AT386: F3 \n");
- break;
- case K_ANSIF04 :
- printf("\\Kansif04 Transmit SCOANSI/AT386: F4 \n");
- break;
- case K_ANSIF05 :
- printf("\\Kansif05 Transmit SCOANSI/AT386: F5 \n");
- break;
- case K_ANSIF06 :
- printf("\\Kansif06 Transmit SCOANSI/AT386: F6 \n");
- break;
- case K_ANSIF07 :
- printf("\\Kansif07 Transmit SCOANSI/AT386: F7 \n");
- break;
- case K_ANSIF08 :
- printf("\\Kansif08 Transmit SCOANSI/AT386: F8 \n");
- break;
- case K_ANSIF09 :
- printf("\\Kansif09 Transmit SCOANSI/AT386: F9 \n");
- break;
- case K_ANSIF10 :
- printf("\\Kansif10 Transmit SCOANSI/AT386: F10\n");
- break;
- case K_ANSIF11 :
- printf("\\Kansif11 Transmit SCOANSI/AT386: F11\n");
- break;
- case K_ANSIF12 :
- printf("\\Kansif12 Transmit SCOANSI/AT386: F12\n");
- break;
- case K_ANSIF13 :
- printf("\\Kansif13 Transmit SCOANSI/AT386: Shift-F1 \n");
- break;
- case K_ANSIF14 :
- printf("\\Kansif14 Transmit SCOANSI/AT386: Shift-F2 \n");
- break;
- case K_ANSIF15 :
- printf("\\Kansif15 Transmit SCOANSI/AT386: Shift-F3 \n");
- break;
- case K_ANSIF16 :
- printf("\\Kansif16 Transmit SCOANSI/AT386: Shift-F4 \n");
- break;
- case K_ANSIF17 :
- printf("\\Kansif17 Transmit SCOANSI/AT386: Shift-F5 \n");
- break;
- case K_ANSIF18 :
- printf("\\Kansif18 Transmit SCOANSI/AT386: Shift-F6 \n");
- break;
- case K_ANSIF19 :
- printf("\\Kansif19 Transmit SCOANSI/AT386: Shift-F7 \n");
- break;
- case K_ANSIF20 :
- printf("\\Kansif20 Transmit SCOANSI/AT386: Shift-F8 \n");
- break;
- case K_ANSIF21 :
- printf("\\Kansif21 Transmit SCOANSI/AT386: Shift-F9 \n");
- break;
- case K_ANSIF22 :
- printf("\\Kansif22 Transmit SCOANSI/AT386: Shift-F10\n");
- break;
- case K_ANSIF23 :
- printf("\\Kansif23 Transmit SCOANSI/AT386: Shift-F11\n");
- break;
- case K_ANSIF24 :
- printf("\\Kansif24 Transmit SCOANSI/AT386: Shift-F12\n");
- break;
- case K_ANSIF25 :
- printf("\\Kansif25 Transmit SCOANSI/AT386: Ctrl-F1 \n");
- break;
- case K_ANSIF26 :
- printf("\\Kansif26 Transmit SCOANSI/AT386: Ctrl-F2 \n");
- break;
- case K_ANSIF27 :
- printf("\\Kansif27 Transmit SCOANSI/AT386: Ctrl-F3 \n");
- break;
- case K_ANSIF28 :
- printf("\\Kansif28 Transmit SCOANSI/AT386: Ctrl-F4 \n");
- break;
- case K_ANSIF29 :
- printf("\\Kansif29 Transmit SCOANSI/AT386: Ctrl-F5 \n");
- break;
- case K_ANSIF30 :
- printf("\\Kansif30 Transmit SCOANSI/AT386: Ctrl-F6 \n");
- break;
- case K_ANSIF31 :
- printf("\\Kansif31 Transmit SCOANSI/AT386: Ctrl-F7 \n");
- break;
- case K_ANSIF32 :
- printf("\\Kansif32 Transmit SCOANSI/AT386: Ctrl-F8 \n");
- break;
- case K_ANSIF33 :
- printf("\\Kansif33 Transmit SCOANSI/AT386: Ctrl-F9 \n");
- break;
- case K_ANSIF34 :
- printf("\\Kansif34 Transmit SCOANSI/AT386: Ctrl-F10\n");
- break;
- case K_ANSIF35 :
- printf("\\Kansif35 Transmit SCOANSI/AT386: Ctrl-F11\n");
- break;
- case K_ANSIF36 :
- printf("\\Kansif36 Transmit SCOANSI/AT386: Ctrl-F12\n");
- break;
- case K_ANSIF37 :
- printf("\\Kansif37 Transmit SCOANSI/AT386: Ctrl-Shift-F1 \n");
- break;
- case K_ANSIF38 :
- printf("\\Kansif38 Transmit SCOANSI/AT386: Ctrl-Shift-F2 \n");
- break;
- case K_ANSIF39 :
- printf("\\Kansif39 Transmit SCOANSI/AT386: Ctrl-Shift-F3 \n");
- break;
- case K_ANSIF40 :
- printf("\\Kansif40 Transmit SCOANSI/AT386: Ctrl-Shift-F4 \n");
- break;
- case K_ANSIF41 :
- printf("\\Kansif41 Transmit SCOANSI/AT386: Ctrl-Shift-F5 \n");
- break;
- case K_ANSIF42 :
- printf("\\Kansif42 Transmit SCOANSI/AT386: Ctrl-Shift-F6 \n");
- break;
- case K_ANSIF43 :
- printf("\\Kansif43 Transmit SCOANSI/AT386: Ctrl-Shift-F7 \n");
- break;
- case K_ANSIF44 :
- printf("\\Kansif44 Transmit SCOANSI/AT386: Ctrl-Shift-F8 \n");
- break;
- case K_ANSIF45 :
- printf("\\Kansif45 Transmit SCOANSI/AT386: Ctrl-Shift-F9 \n");
- break;
- case K_ANSIF46 :
- printf("\\Kansif46 Transmit SCOANSI/AT386: Ctrl-Shift-F10\n");
- break;
- case K_ANSIF47 :
- printf("\\Kansif47 Transmit SCOANSI/AT386: Ctrl-Shift-F11\n");
- break;
- case K_ANSIF48 :
- printf("\\Kansif48 Transmit SCOANSI/AT386: Ctrl-Shift-F12\n");
- break;
- case K_ANSIF49 :
- printf("\\Kansif49 Transmit SCOANSI/AT386: Home\n");
- break;
- case K_ANSIF50 :
- printf("\\Kansif50 Transmit SCOANSI/AT386: Up Arrow\n");
- break;
- case K_ANSIF51 :
- printf("\\Kansif51 Transmit SCOANSI/AT386: PgUp\n");
- break;
- case K_ANSIF52 :
- printf("\\Kansif52 Transmit SCOANSI/AT386: Ctrl-Shift-Subtract\n");
- break;
- case K_ANSIF53 :
- printf("\\Kansif53 Transmit SCOANSI/AT386: Left Arrow\n");
- break;
- case K_ANSIF54 :
- printf("\\Kansif54 Transmit SCOANSI/AT386: Clear\n");
- break;
- case K_ANSIF55 :
- printf("\\Kansif55 Transmit SCOANSI/AT386: Right Arrow\n");
- break;
- case K_ANSIF56 :
- printf("\\Kansif56 Transmit SCOANSI/AT386: Shift-Add\n");
- break;
- case K_ANSIF57 :
- printf("\\Kansif57 Transmit SCOANSI/AT386: End\n");
- break;
- case K_ANSIF58 :
- printf("\\Kansif58 Transmit SCOANSI/AT386: Down Arrow\n");
- break;
- case K_ANSIF59 :
- printf("\\Kansif59 Transmit SCOANSI/AT386: PgDn\n");
- break;
- case K_ANSIF60 :
- printf("\\Kansif60 Transmit SCOANSI/AT386: Insert\n");
- break;
- case K_ANSIF61 :
- printf("\\Kansif61 Transmit SCOANSI/AT386: (not named)\n");
- break;
-
-/* WYSE Function Keys (unshifted) */
- case K_WYF01 :
- printf("\\Kwyf01 Transmit WYSE 30/50/60/160: F1\n");
- break;
- case K_WYF02 :
- printf("\\Kwyf02 Transmit WYSE 30/50/60/160: F2\n");
- break;
- case K_WYF03 :
- printf("\\Kwyf03 Transmit WYSE 30/50/60/160: F3\n");
- break;
- case K_WYF04 :
- printf("\\Kwyf04 Transmit WYSE 30/50/60/160: F4\n");
- break;
- case K_WYF05 :
- printf("\\Kwyf05 Transmit WYSE 30/50/60/160: F5\n");
- break;
- case K_WYF06 :
- printf("\\Kwyf06 Transmit WYSE 30/50/60/160: F6\n");
- break;
- case K_WYF07 :
- printf("\\Kwyf07 Transmit WYSE 30/50/60/160: F7\n");
- break;
- case K_WYF08 :
- printf("\\Kwyf08 Transmit WYSE 30/50/60/160: F8\n");
- break;
- case K_WYF09 :
- printf("\\Kwyf09 Transmit WYSE 30/50/60/160: F9\n");
- break;
- case K_WYF10 :
- printf("\\Kwyf10 Transmit WYSE 30/50/60/160: F10\n");
- break;
- case K_WYF11 :
- printf("\\Kwyf11 Transmit WYSE 30/50/60/160: F11\n");
- break;
- case K_WYF12 :
- printf("\\Kwyf12 Transmit WYSE 30/50/60/160: F12\n");
- break;
- case K_WYF13 :
- printf("\\Kwyf13 Transmit WYSE 30/50/60/160: F13\n");
- break;
- case K_WYF14 :
- printf("\\Kwyf14 Transmit WYSE 30/50/60/160: F14\n");
- break;
- case K_WYF15 :
- printf("\\Kwyf15 Transmit WYSE 30/50/60/160: F15\n");
- break;
- case K_WYF16 :
- printf("\\Kwyf16 Transmit WYSE 30/50/60/160: F16\n");
- break;
- case K_WYF17 :
- printf("\\Kwyf17 Transmit WYSE 30/50/60/160: F17\n");
- break;
- case K_WYF18 :
- printf("\\Kwyf18 Transmit WYSE 30/50/60/160: F18\n");
- break;
- case K_WYF19 :
- printf("\\Kwyf19 Transmit WYSE 30/50/60/160: F19\n");
- break;
- case K_WYF20 :
- printf("\\Kwyf20 Transmit WYSE 30/50/60/160: F20\n");
- break;
-
-/* WYSE Function Keys (shifted) */
- case K_WYSF01 :
- printf("\\Kwysf01 Transmit WYSE 30/50/60/160: Shift-F1\n");
- break;
- case K_WYSF02 :
- printf("\\Kwysf02 Transmit WYSE 30/50/60/160: Shift-F2\n");
- break;
- case K_WYSF03 :
- printf("\\Kwysf03 Transmit WYSE 30/50/60/160: Shift-F3\n");
- break;
- case K_WYSF04 :
- printf("\\Kwysf04 Transmit WYSE 30/50/60/160: Shift-F4\n");
- break;
- case K_WYSF05 :
- printf("\\Kwysf05 Transmit WYSE 30/50/60/160: Shift-F5\n");
- break;
- case K_WYSF06 :
- printf("\\Kwysf06 Transmit WYSE 30/50/60/160: Shift-F6\n");
- break;
- case K_WYSF07 :
- printf("\\Kwysf07 Transmit WYSE 30/50/60/160: Shift-F7\n");
- break;
- case K_WYSF08 :
- printf("\\Kwysf08 Transmit WYSE 30/50/60/160: Shift-F8\n");
- break;
- case K_WYSF09 :
- printf("\\Kwysf09 Transmit WYSE 30/50/60/160: Shift-F9\n");
- break;
- case K_WYSF10 :
- printf("\\Kwysf10 Transmit WYSE 30/50/60/160: Shift-F10\n");
- break;
- case K_WYSF11 :
- printf("\\Kwysf11 Transmit WYSE 30/50/60/160: Shift-F11\n");
- break;
- case K_WYSF12 :
- printf("\\Kwysf12 Transmit WYSE 30/50/60/160: Shift-F12\n");
- break;
- case K_WYSF13 :
- printf("\\Kwysf13 Transmit WYSE 30/50/60/160: Shift-F13\n");
- break;
- case K_WYSF14 :
- printf("\\Kwysf14 Transmit WYSE 30/50/60/160: Shift-F14\n");
- break;
- case K_WYSF15 :
- printf("\\Kwysf15 Transmit WYSE 30/50/60/160: Shift-F15\n");
- break;
- case K_WYSF16 :
- printf("\\Kwysf16 Transmit WYSE 30/50/60/160: Shift-F16\n");
- break;
- case K_WYSF17 :
- printf("\\Kwysf17 Transmit WYSE 30/50/60/160: Shift-F17\n");
- break;
- case K_WYSF18 :
- printf("\\Kwysf18 Transmit WYSE 30/50/60/160: Shift-F18\n");
- break;
- case K_WYSF19 :
- printf("\\Kwysf19 Transmit WYSE 30/50/60/160: Shift-F19\n");
- break;
- case K_WYSF20 :
- printf("\\Kwysf20 Transmit WYSE 30/50/60/160: Shift-F20\n");
- break;
-
-/* WYSE Edit and Special Keys */
- case K_WYBS :
- printf("\\Kwybs Transmit WYSE 30/50/60/160: Backspace\n");
- break;
- case K_WYCLRLN :
- printf("\\Kwyclrln Transmit WYSE 30/50/60/160: Clear Line\n");
- break;
- case K_WYSCLRLN :
- printf("\\Kwysclrln Transmit WYSE 30/50/60/160: Shift-Clear Line\n");
- break;
- case K_WYCLRPG :
- printf("\\Kwyclrpg Transmit WYSE 30/50/60/160: Clear Page\n");
- break;
- case K_WYSCLRPG :
- printf("\\Kwysclrpg Transmit WYSE 30/50/60/160: Shift-Clear Page\n");
- break;
- case K_WYDELCHAR :
- printf("\\Kwydelchar Transmit WYSE 30/50/60/160: Delete Char\n");
- break;
- case K_WYDELLN :
- printf("\\Kwydelln Transmit WYSE 30/50/60/160: Delete Line\n");
- break;
- case K_WYENTER :
- printf("\\Kwyenter Transmit WYSE 30/50/60/160: Enter\n");
- break;
- case K_WYESC :
- printf("\\Kwyesc Transmit WYSE 30/50/60/160: Esc\n");
- break;
- case K_WYHOME :
- printf("\\Kwyhome Transmit WYSE 30/50/60/160: Home\n");
- break;
- case K_WYSHOME :
- printf("\\Kwyshome Transmit WYSE 30/50/60/160: Shift-Home\n");
- break;
- case K_WYINSERT :
- printf("\\Kwyinsert Transmit WYSE 30/50/60/160: Insert\n");
- break;
- case K_WYINSCHAR :
- printf("\\Kwyinschar Transmit WYSE 30/50/60/160: Insert Char\n");
- break;
- case K_WYINSLN :
- printf("\\Kwyinsln Transmit WYSE 30/50/60/160: Insert Line\n");
- break;
- case K_WYPGNEXT :
- printf("\\Kwypgnext Transmit WYSE 30/50/60/160: Page Next\n");
- break;
- case K_WYPGPREV :
- printf("\\Kwypgprev Transmit WYSE 30/50/60/160: Page Previous\n");
- break;
- case K_WYREPLACE :
- printf("\\Kwyreplace Transmit WYSE 30/50/60/160: Replace \n");
- break;
- case K_WYRETURN :
- printf("\\Kwyreturn Transmit WYSE 30/50/60/160: Return \n");
- break;
- case K_WYTAB :
- printf("\\Kwytab Transmit WYSE 30/50/60/160: Tab \n");
- break;
- case K_WYSTAB :
- printf("\\Kwystab Transmit WYSE 30/50/60/160: Shift-Tab \n");
- break;
- case K_WYPRTSCN :
- printf("\\Kwyprtscn Transmit WYSE 30/50/60/160: Print Screen \n");
- break;
- case K_WYSESC :
- printf("\\Kwysesc Transmit WYSE 30/50/60/160: Shift-Esc \n");
- break;
- case K_WYSBS :
- printf("\\Kwysbs Transmit WYSE 30/50/60/160: Shift-Backspace\n");
- break;
- case K_WYSENTER :
- printf("\\Kwysenter Transmit WYSE 30/50/60/160: Shift-Enter\n");
- break;
- case K_WYSRETURN :
- printf("\\Kwysreturn Transmit WYSE 30/50/60/160: Shift-Return\n");
- break;
- case K_WYUPARR :
- printf("\\Kwyuparr Transmit WYSE 30/50/60/160: Up Arrow\n");
- break;
- case K_WYDNARR :
- printf("\\Kwydnarr Transmit WYSE 30/50/60/160: Down Arrow\n");
- break;
- case K_WYLFARR :
- printf("\\Kwylfarr Transmit WYSE 30/50/60/160: Left Arrow\n");
- break;
- case K_WYRTARR :
- printf("\\Kwyrtarr Transmit WYSE 30/50/60/160: Right Arrow\n");
- break;
- case K_WYSUPARR :
- printf("\\Kwysuparr Transmit WYSE 30/50/60/160: Shift-Up Arrow\n");
- break;
- case K_WYSDNARR :
- printf("\\Kwysdnarr Transmit WYSE 30/50/60/160: Shift-Down Arrow\n");
- break;
- case K_WYSLFARR :
- printf("\\Kwyslfarr Transmit WYSE 30/50/60/160: Shift-Left Arrow\n");
- break;
- case K_WYSRTARR :
- printf("\\Kwysrtarr Transmit WYSE 30/50/60/160: Shift-Right Arrow\n");
- break;
- case K_WYSEND:
- printf("\\Kwysend Transmit WYSE 30/50/60/160: Send\n");
- break;
- case K_WYSSEND:
- printf("\\Kwyssend Transmit WYSE 30/50/60/160: Shift-Send\n");
- break;
-
-/* Data General Function Keys (unshifted) */
- case K_DGF01 :
- printf("\\Kdgf01 Transmit Data General: F1 \n");
- break;
- case K_DGF02 :
- printf("\\Kdgf01 Transmit Data General: F2 \n");
- break;
- case K_DGF03 :
- printf("\\Kdgf01 Transmit Data General: F3 \n");
- break;
- case K_DGF04 :
- printf("\\Kdgf01 Transmit Data General: F4 \n");
- break;
- case K_DGF05 :
- printf("\\Kdgf01 Transmit Data General: F5 \n");
- break;
- case K_DGF06 :
- printf("\\Kdgf01 Transmit Data General: F6 \n");
- break;
- case K_DGF07 :
- printf("\\Kdgf01 Transmit Data General: F7 \n");
- break;
- case K_DGF08 :
- printf("\\Kdgf01 Transmit Data General: F8 \n");
- break;
- case K_DGF09 :
- printf("\\Kdgf01 Transmit Data General: F9 \n");
- break;
- case K_DGF10 :
- printf("\\Kdgf01 Transmit Data General: F10 \n");
- break;
- case K_DGF11 :
- printf("\\Kdgf01 Transmit Data General: F11 \n");
- break;
- case K_DGF12 :
- printf("\\Kdgf01 Transmit Data General: F12 \n");
- break;
- case K_DGF13 :
- printf("\\Kdgf01 Transmit Data General: F13 \n");
- break;
- case K_DGF14 :
- printf("\\Kdgf01 Transmit Data General: F14 \n");
- break;
- case K_DGF15 :
- printf("\\Kdgf01 Transmit Data General: F15 \n");
- break;
-
-/* Data General Function Keys (shifted) */
- case K_DGSF01 :
- printf(
- "\\Kdgsf01 Transmit Data General: Shift-F1 \n");
- break;
- case K_DGSF02 :
- printf(
- "\\Kdgsf02 Transmit Data General: Shift-F2 \n");
- break;
- case K_DGSF03 :
- printf(
- "\\Kdgsf03 Transmit Data General: Shift-F3 \n");
- break;
- case K_DGSF04 :
- printf(
- "\\Kdgsf04 Transmit Data General: Shift-F4 \n");
- break;
- case K_DGSF05 :
- printf(
- "\\Kdgsf05 Transmit Data General: Shift-F5 \n");
- break;
- case K_DGSF06 :
- printf(
- "\\Kdgsf06 Transmit Data General: Shift-F6 \n");
- break;
- case K_DGSF07 :
- printf(
- "\\Kdgsf07 Transmit Data General: Shift-F7 \n");
- break;
- case K_DGSF08 :
- printf(
- "\\Kdgsf08 Transmit Data General: Shift-F8 \n");
- break;
- case K_DGSF09 :
- printf(
- "\\Kdgsf09 Transmit Data General: Shift-F9 \n");
- break;
- case K_DGSF10 :
- printf(
- "\\Kdgsf10 Transmit Data General: Shift-F10 \n");
- break;
- case K_DGSF11 :
- printf(
- "\\Kdgsf11 Transmit Data General: Shift-F11 \n");
- break;
- case K_DGSF12 :
- printf(
- "\\Kdgsf12 Transmit Data General: Shift-F12 \n");
- break;
- case K_DGSF13 :
- printf(
- "\\Kdgsf13 Transmit Data General: Shift-F13 \n");
- break;
- case K_DGSF14 :
- printf(
- "\\Kdgsf14 Transmit Data General: Shift-F14 \n");
- break;
- case K_DGSF15 :
- printf(
- "\\Kdgsf15 Transmit Data General: Shift-F15 \n");
- break;
-
-/* Data General Function Keys (control) */
- case K_DGCF01 :
- printf(
- "\\Kdgcf01 Transmit Data General: Ctrl-F1 \n");
- break;
- case K_DGCF02 :
- printf(
- "\\Kdgcf02 Transmit Data General: Ctrl-F2 \n");
- break;
- case K_DGCF03 :
- printf(
- "\\Kdgcf03 Transmit Data General: Ctrl-F3 \n");
- break;
- case K_DGCF04 :
- printf(
- "\\Kdgcf04 Transmit Data General: Ctrl-F4 \n");
- break;
- case K_DGCF05 :
- printf(
- "\\Kdgcf05 Transmit Data General: Ctrl-F5 \n");
- break;
- case K_DGCF06 :
- printf(
- "\\Kdgcf06 Transmit Data General: Ctrl-F6 \n");
- break;
- case K_DGCF07 :
- printf(
- "\\Kdgcf07 Transmit Data General: Ctrl-F7 \n");
- break;
- case K_DGCF08 :
- printf(
- "\\Kdgcf08 Transmit Data General: Ctrl-F8 \n");
- break;
- case K_DGCF09 :
- printf(
- "\\Kdgcf09 Transmit Data General: Ctrl-F9 \n");
- break;
- case K_DGCF10 :
- printf(
- "\\Kdgcf10 Transmit Data General: Ctrl-F10 \n");
- break;
- case K_DGCF11 :
- printf(
- "\\Kdgcf11 Transmit Data General: Ctrl-F11 \n");
- break;
- case K_DGCF12 :
- printf(
- "\\Kdgcf12 Transmit Data General: Ctrl-F12 \n");
- break;
- case K_DGCF13 :
- printf(
- "\\Kdgcf13 Transmit Data General: Ctrl-F13 \n");
- break;
- case K_DGCF14 :
- printf(
- "\\Kdgcf14 Transmit Data General: Ctrl-F14 \n");
- break;
- case K_DGCF15 :
- printf(
- "\\Kdgcf15 Transmit Data General: Ctrl-F15 \n");
- break;
-
-/* Data General Function Keys (control shifted) */
- case K_DGCSF01 :
- printf(
- "\\Kdgcsf01 Transmit Data General: Ctrl-Shift-F1 \n");
- break;
- case K_DGCSF02 :
- printf(
- "\\Kdgcsf02 Transmit Data General: Ctrl-Shift-F2 \n");
- break;
- case K_DGCSF03 :
- printf(
- "\\Kdgcsf03 Transmit Data General: Ctrl-Shift-F3 \n");
- break;
- case K_DGCSF04 :
- printf(
- "\\Kdgcsf04 Transmit Data General: Ctrl-Shift-F4 \n");
- break;
- case K_DGCSF05 :
- printf(
- "\\Kdgcsf05 Transmit Data General: Ctrl-Shift-F5 \n");
- break;
- case K_DGCSF06 :
- printf(
- "\\Kdgcsf06 Transmit Data General: Ctrl-Shift-F6 \n");
- break;
- case K_DGCSF07 :
- printf(
- "\\Kdgcsf07 Transmit Data General: Ctrl-Shift-F7 \n");
- break;
- case K_DGCSF08 :
- printf(
- "\\Kdgcsf08 Transmit Data General: Ctrl-Shift-F8 \n");
- break;
- case K_DGCSF09 :
- printf(
- "\\Kdgcsf09 Transmit Data General: Ctrl-Shift-F9 \n");
- break;
- case K_DGCSF10 :
- printf(
- "\\Kdgcsf10 Transmit Data General: Ctrl-Shift-F10 \n");
- break;
- case K_DGCSF11 :
- printf(
- "\\Kdgcsf11 Transmit Data General: Ctrl-Shift-F11 \n");
- break;
- case K_DGCSF12 :
- printf(
- "\\Kdgcsf12 Transmit Data General: Ctrl-Shift-F12 \n");
- break;
- case K_DGCSF13 :
- printf(
- "\\Kdgcsf13 Transmit Data General: Ctrl-Shift-F13 \n");
- break;
- case K_DGCSF14 :
- printf(
- "\\Kdgcsf14 Transmit Data General: Ctrl-Shift-F14 \n");
- break;
- case K_DGCSF15 :
- printf(
- "\\Kdgcsf15 Transmit Data General: Ctrl-Shift-F15 \n");
- break;
-
- case K_DGUPARR :
- printf("\\Kdguparr Transmit Data General: Up Arrow \n");
- break;
- case K_DGDNARR :
- printf("\\Kdgdnarr Transmit Data General: Down Arrow \n");
- break;
- case K_DGLFARR :
- printf("\\Kdglfarr Transmit Data General: Left Arrow \n");
- break;
- case K_DGRTARR :
- printf("\\Kdgrtarr Transmit Data General: Right Arrow \n");
- break;
- case K_DGSUPARR :
- printf("\\Kdgsuparr Transmit Data General: Shift-Up Arrow \n");
- break;
- case K_DGSDNARR :
- printf("\\Kdgsdnarr Transmit Data General: Shift-Down Arrow \n");
- break;
- case K_DGSLFARR :
- printf("\\Kdgslfarr Transmit Data General: Shift-Left Arrow \n");
- break;
- case K_DGSRTARR :
- printf("\\Kdgsrtarr Transmit Data General: Shift-Right Arrow \n");
- break;
-
- case K_DGERASEPAGE :
- printf("\\Kdgerasepage Transmit Data General: Erase Page \n");
- break;
- case K_DGC1 :
- printf("\\Kdgc1 Transmit Data General: C1 \n");
- break;
- case K_DGC2 :
- printf("\\Kdgc2 Transmit Data General: C2 \n");
- break;
- case K_DGERASEEOL :
- printf("\\Kdgeraseeol Transmit Data General: Erase EOL \n");
- break;
- case K_DGC3 :
- printf("\\Kdgc3 Transmit Data General: C3 \n");
- break;
- case K_DGC4 :
- printf("\\Kdgc4 Transmit Data General: C4 \n");
- break;
- case K_DGCMDPRINT :
- printf("\\Kdgcmdprint Transmit Data General: Command Print \n");
- break;
- case K_DGHOME :
- printf("\\Kdghome Transmit Data General: Home \n");
- break;
- case K_DGSERASEPAGE :
- printf("\\Kdgserasepage Transmit Data General: Erase Page \n");
- break;
- case K_DGSC1 :
- printf("\\Kdgsc1 Transmit Data General: Shift-C1 \n");
- break;
- case K_DGSC2 :
- printf("\\Kdgsc2 Transmit Data General: Shift-C2 \n");
- break;
- case K_DGSERASEEOL :
- printf("\\Kdgseraseeol Transmit Data General: Shift-Erase EOL \n");
- break;
- case K_DGSC3 :
- printf("\\Kdgsc3 Transmit Data General: Shift-C3 \n");
- break;
- case K_DGSC4 :
- printf("\\Kdgsc4 Transmit Data General: Shift-C4 \n");
- break;
- case K_DGSCMDPRINT :
- printf("\\Kdgscmdprint Transmit Data General: Shift-Command Print\n");
- break;
- case K_DGBS :
- printf("\\Kdgbs Transmit Data General: Backspace \n");
- break;
- case K_DGSHOME :
- printf("\\Kdshome Transmit Data General: Shift-Home \n");
- break;
-
-
-/* Televideo Function Keys (unshifted) */
- case K_TVIF01 :
- printf("\\Ktvif01 Transmit Televideo: F1 \n");
- break;
- case K_TVIF02 :
- printf("\\Ktvif02 Transmit Televideo: F2 \n");
- break;
- case K_TVIF03 :
- printf("\\Ktvif03 Transmit Televideo: F3 \n");
- break;
- case K_TVIF04 :
- printf("\\Ktvif04 Transmit Televideo: F4 \n");
- break;
- case K_TVIF05 :
- printf("\\Ktvif05 Transmit Televideo: F5 \n");
- break;
- case K_TVIF06 :
- printf("\\Ktvif06 Transmit Televideo: F6 \n");
- break;
- case K_TVIF07 :
- printf("\\Ktvif07 Transmit Televideo: F7 \n");
- break;
- case K_TVIF08 :
- printf("\\Ktvif08 Transmit Televideo: F8 \n");
- break;
- case K_TVIF09 :
- printf("\\Ktvif09 Transmit Televideo: F9 \n");
- break;
- case K_TVIF10 :
- printf("\\Ktvif10 Transmit Televideo: F10 \n");
- break;
- case K_TVIF11 :
- printf("\\Ktvif11 Transmit Televideo: F11 \n");
- break;
- case K_TVIF12 :
- printf("\\Ktvif12 Transmit Televideo: F12 \n");
- break;
- case K_TVIF13 :
- printf("\\Ktvif13 Transmit Televideo: F13 \n");
- break;
- case K_TVIF14 :
- printf("\\Ktvif14 Transmit Televideo: F14 \n");
- break;
- case K_TVIF15 :
- printf("\\Ktvif15 Transmit Televideo: F15 \n");
- break;
- case K_TVIF16 :
- printf("\\Ktvif16 Transmit Televideo: F16 \n");
- break;
-
-/* Televideo Function Keys (shifted) */
- case K_TVISF01 :
- printf("\\Ktvisf01 Transmit Televideo: Shift-F1 \n");
- break;
- case K_TVISF02 :
- printf("\\Ktvisf02 Transmit Televideo: Shift-F2 \n");
- break;
- case K_TVISF03 :
- printf("\\Ktvisf03 Transmit Televideo: Shift-F3 \n");
- break;
- case K_TVISF04 :
- printf("\\Ktvisf04 Transmit Televideo: Shift-F4 \n");
- break;
- case K_TVISF05 :
- printf("\\Ktvisf05 Transmit Televideo: Shift-F5 \n");
- break;
- case K_TVISF06 :
- printf("\\Ktvisf06 Transmit Televideo: Shift-F6 \n");
- break;
- case K_TVISF07 :
- printf("\\Ktvisf07 Transmit Televideo: Shift-F7 \n");
- break;
- case K_TVISF08 :
- printf("\\Ktvisf08 Transmit Televideo: Shift-F8 \n");
- break;
- case K_TVISF09 :
- printf("\\Ktvisf09 Transmit Televideo: Shift-F9 \n");
- break;
- case K_TVISF10 :
- printf("\\Ktvisf10 Transmit Televideo: Shift-F10\n");
- break;
- case K_TVISF11 :
- printf("\\Ktvisf11 Transmit Televideo: Shift-F11\n");
- break;
- case K_TVISF12 :
- printf("\\Ktvisf12 Transmit Televideo: Shift-F12\n");
- break;
- case K_TVISF13 :
- printf("\\Ktvisf13 Transmit Televideo: Shift-F13\n");
- break;
- case K_TVISF14 :
- printf("\\Ktvisf14 Transmit Televideo: Shift-F14\n");
- break;
- case K_TVISF15 :
- printf("\\Ktvisf15 Transmit Televideo: Shift-F15\n");
- break;
- case K_TVISF16 :
- printf("\\Ktvisf16 Transmit Televideo: Shift-F16\n");
- break;
-
-/* Televideo Edit and Special Keys */
- case K_TVIBS :
- printf("\\Ktvibs Transmit Televideo: Backspace \n");
- break;
- case K_TVICLRLN :
- printf("\\Ktviclrln Transmit Televideo: Clear Line \n");
- break;
- case K_TVISCLRLN :
- printf("\\Ktvisclrln Transmit Televideo: Shift-Clear Line\n");
- break;
- case K_TVICLRPG :
- printf("\\Ktviclrpg Transmit Televideo: Clear Page \n");
- break;
- case K_TVISCLRPG :
- printf("\\Ktvisclrpg Transmit Televideo: Shift-Clear Page\n");
- break;
- case K_TVIDELCHAR :
- printf("\\Ktvidelchar Transmit Televideo: Delete Char \n");
- break;
- case K_TVIDELLN :
- printf("\\Ktvidelln Transmit Televideo: Delete Line \n");
- break;
- case K_TVIENTER :
- printf("\\Ktvienter Transmit Televideo: Enter \n");
- break;
- case K_TVIESC :
- printf("\\Ktviesc Transmit Televideo: Esc \n");
- break;
- case K_TVIHOME :
- printf("\\Ktvihome Transmit Televideo: Home \n");
- break;
- case K_TVISHOME :
- printf("\\Ktvishome Transmit Televideo: Shift-Home \n");
- break;
- case K_TVIINSERT :
- printf("\\Ktviinsert Transmit Televideo: Insert \n");
- break;
- case K_TVIINSCHAR :
- printf("\\Ktviinschar Transmit Televideo: Insert Char \n");
- break;
- case K_TVIINSLN :
- printf("\\Ktviinsln Transmit Televideo: Insert Line \n");
- break;
- case K_TVIPGNEXT :
- printf("\\Ktvipgnext Transmit Televideo: Page Next \n");
- break;
- case K_TVIPGPREV :
- printf("\\Ktvipgprev Transmit Televideo: Page Previous \n");
- break;
- case K_TVIREPLACE :
- printf("\\Ktvireplace Transmit Televideo: Replace \n");
- break;
- case K_TVIRETURN :
- printf("\\Ktvireturn Transmit Televideo: Return \n");
- break;
- case K_TVITAB :
- printf("\\Ktvitab Transmit Televideo: Tab \n");
- break;
- case K_TVISTAB :
- printf("\\Ktvistab Transmit Televideo: Shift-Tab \n");
- break;
- case K_TVIPRTSCN :
- printf("\\Ktviprtscn Transmit Televideo: Print Screen \n");
- break;
- case K_TVISESC :
- printf("\\Ktvisesc Transmit Televideo: Shift-Esc \n");
- break;
- case K_TVISBS :
- printf("\\Ktvisbs Transmit Televideo: Shift-Backspace \n");
- break;
- case K_TVISENTER :
- printf("\\Ktvisenter Transmit Televideo: Shift-Enter \n");
- break;
- case K_TVISRETURN :
- printf("\\Ktvisreturn Transmit Televideo: Shift-Return \n");
- break;
- case K_TVIUPARR :
- printf("\\Ktviuparr Transmit Televideo: Up Arrow \n");
- break;
- case K_TVIDNARR :
- printf("\\Ktvidnarr Transmit Televideo: Down Arrow \n");
- break;
- case K_TVILFARR :
- printf("\\Ktvilfarr Transmit Televideo: Left Arrow \n");
- break;
- case K_TVIRTARR :
- printf("\\Ktvirtarr Transmit Televideo: Right Arrow \n");
- break;
- case K_TVISUPARR :
- printf("\\Ktvisuparr Transmit Televideo: Shift-Up Arrow \n");
- break;
- case K_TVISDNARR :
- printf("\\Ktvisdnarr Transmit Televideo: Shift-Down Arrow\n");
- break;
- case K_TVISLFARR :
- printf("\\Ktvislfarr Transmit Televideo: Shift-Left Arrow\n");
- break;
- case K_TVISRTARR :
- printf("\\Ktvisrtarr Transmit Televideo: Shift-Right Arrow\n");
- break;
- case K_TVISEND:
- printf("\\Ktvisend Transmit Televideo: Send\n");
- break;
- case K_TVISSEND:
- printf("\\Ktvissend Transmit Televideo: Shift-Send\n");
- break;
-
-/* HP Function and Edit keys */
- case K_HPF01 :
- printf("\\Khpf01 Transmit Hewlett-Packard: F1 \n");
- break;
- case K_HPF02 :
- printf("\\Khpf02 Transmit Hewlett-Packard: F2 \n");
- break;
- case K_HPF03 :
- printf("\\Khpf03 Transmit Hewlett-Packard: F3 \n");
- break;
- case K_HPF04 :
- printf("\\Khpf04 Transmit Hewlett-Packard: F4 \n");
- break;
- case K_HPF05 :
- printf("\\Khpf05 Transmit Hewlett-Packard: F5 \n");
- break;
- case K_HPF06 :
- printf("\\Khpf06 Transmit Hewlett-Packard: F6 \n");
- break;
- case K_HPF07 :
- printf("\\Khpf07 Transmit Hewlett-Packard: F7 \n");
- break;
- case K_HPF08 :
- printf("\\Khpf08 Transmit Hewlett-Packard: F8 \n");
- break;
- case K_HPF09 :
- printf("\\Khpf09 Transmit Hewlett-Packard: F9 \n");
- break;
- case K_HPF10 :
- printf("\\Khpf10 Transmit Hewlett-Packard: F10 \n");
- break;
- case K_HPF11 :
- printf("\\Khpf11 Transmit Hewlett-Packard: F11 \n");
- break;
- case K_HPF12 :
- printf("\\Khpf12 Transmit Hewlett-Packard: F12 \n");
- break;
- case K_HPF13 :
- printf("\\Khpf13 Transmit Hewlett-Packard: F13 \n");
- break;
- case K_HPF14 :
- printf("\\Khpf14 Transmit Hewlett-Packard: F14 \n");
- break;
- case K_HPF15 :
- printf("\\Khpf15 Transmit Hewlett-Packard: F15 \n");
- break;
- case K_HPF16 :
- printf("\\Khpf16 Transmit Hewlett-Packard: F16 \n");
- break;
- case K_HPRETURN :
- printf("\\Khpreturn Transmit Hewlett-Packard: Return\n");
- break;
- case K_HPENTER :
- printf("\\Khpenter Transmit Hewlett-Packard: Enter (keypad)\n");
- break;
- case K_HPBACKTAB :
- printf("\\Khpbacktab Transmit Hewlett-Packard: Back Tab\n");
- break;
- /* Siemens Nixdorf International 97801-5xx kverbs */
- case K_SNI_DOUBLE_0 :
- printf("\\Ksni_00 Transmit SNI-97801-5xx: Double-Zero\n");
- break;
- case K_SNI_C_DOUBLE_0 :
- printf(
-"\\Ksni_c_00 Transmit SNI-97801-5xx: Ctrl-Double-Zero\n");
- break;
- case K_SNI_C_CE :
- printf("\\Ksni_c_ce Transmit SNI-97801-5xx: Ctrl-CE\n");
- break;
- case K_SNI_C_COMPOSE :
- printf("\\Ksni_c_compose Transmit SNI-97801-5xx: Ctrl-Compose\n");
- break;
- case K_SNI_C_DELETE_CHAR :
- printf(
-"\\Ksni_c_del_char Transmit SNI-97801-5xx: Ctrl-Delete Char\n");
- break;
- case K_SNI_C_DELETE_LINE :
- printf(
-"\\Ksni_c_del_line Transmit SNI-97801-5xx: Ctrl-Delete Line\n");
- break;
- case K_SNI_C_DELETE_WORD :
- printf(
-"\\Ksni_c_del_word Transmit SNI-97801-5xx: Ctrl-Delete Word\n");
- break;
- case K_SNI_C_CURSOR_DOWN :
- printf(
-"\\Ksni_c_dnarr Transmit SNI-97801-5xx: Ctrl-Cursor Down\n");
- break;
- case K_SNI_C_ENDMARKE :
- printf("\\Ksni_c_endmarke Transmit SNI-97801-5xx: Ctrl-End Marke\n");
- break;
- case K_SNI_C_F01 :
- printf("\\Ksni_c_f01 Transmit SNI-97801-5xx: Ctrl-F1\n");
- break;
- case K_SNI_C_F02 :
- printf("\\Ksni_c_f02 Transmit SNI-97801-5xx: Ctrl-F2\n");
- break;
- case K_SNI_C_F03 :
- printf("\\Ksni_c_f03 Transmit SNI-97801-5xx: Ctrl-F3\n");
- break;
- case K_SNI_C_F04 :
- printf("\\Ksni_c_f04 Transmit SNI-97801-5xx: Ctrl-F4\n");
- break;
- case K_SNI_C_F05 :
- printf("\\Ksni_c_f05 Transmit SNI-97801-5xx: Ctrl-F5\n");
- break;
- case K_SNI_C_F06 :
- printf("\\Ksni_c_f06 Transmit SNI-97801-5xx: Ctrl-F6\n");
- break;
- case K_SNI_C_F07 :
- printf("\\Ksni_c_f07 Transmit SNI-97801-5xx: Ctrl-F7\n");
- break;
- case K_SNI_C_F08 :
- printf("\\Ksni_c_f08 Transmit SNI-97801-5xx: Ctrl-F8\n");
- break;
- case K_SNI_C_F09 :
- printf("\\Ksni_c_f09 Transmit SNI-97801-5xx: Ctrl-F9\n");
- break;
- case K_SNI_C_F10 :
- printf("\\Ksni_c_f10 Transmit SNI-97801-5xx: Ctrl-F10\n");
- break;
- case K_SNI_C_F11 :
- printf("\\Ksni_c_f11 Transmit SNI-97801-5xx: Ctrl-F11\n");
- break;
- case K_SNI_C_F12 :
- printf("\\Ksni_c_f12 Transmit SNI-97801-5xx: Ctrl-F12\n");
- break;
- case K_SNI_C_F13 :
- printf("\\Ksni_c_f13 Transmit SNI-97801-5xx: Ctrl-F13\n");
- break;
- case K_SNI_C_F14 :
- printf("\\Ksni_c_f14 Transmit SNI-97801-5xx: Ctrl-F14\n");
- break;
- case K_SNI_C_F15 :
- printf("\\Ksni_c_f15 Transmit SNI-97801-5xx: Ctrl-F15\n");
- break;
- case K_SNI_C_F16 :
- printf("\\Ksni_c_f16 Transmit SNI-97801-5xx: Ctrl-F16\n");
- break;
- case K_SNI_C_F17 :
- printf("\\Ksni_c_f17 Transmit SNI-97801-5xx: Ctrl-F17\n");
- break;
- case K_SNI_C_F18 :
- printf("\\Ksni_c_f18 Transmit SNI-97801-5xx: Ctrl-F18\n");
- break;
- case K_SNI_C_USER1 :
- printf(
-"\\Ksni_c_user1 Transmit SNI-97801-5xx: Ctrl-Key below F18\n");
- break;
- case K_SNI_C_F19 :
- printf("\\Ksni_c_f19 Transmit SNI-97801-5xx: Ctrl-F19\n");
- break;
- case K_SNI_C_USER2 :
- printf(
-"\\Ksni_c_user2 Transmit SNI-97801-5xx: Ctrl-Key below F19\n");
- break;
- case K_SNI_C_F20 :
- printf("\\Ksni_c_f20 Transmit SNI-97801-5xx: Ctrl-F20\n");
- break;
- case K_SNI_C_USER3 :
- printf(
-"\\Ksni_c_user3 Transmit SNI-97801-5xx: Ctrl-Key below F20\n");
- break;
- case K_SNI_C_F21 :
- printf("\\Ksni_c_f21 Transmit SNI-97801-5xx: Ctrl-F21\n");
- break;
- case K_SNI_C_USER4 :
- printf(
-"\\Ksni_c_user4 Transmit SNI-97801-5xx: Ctrl-Key below F21\n");
- break;
- case K_SNI_C_F22 :
- printf("\\Ksni_c_f22 Transmit SNI-97801-5xx: Ctrl-F22\n");
- break;
- case K_SNI_C_USER5 :
- printf(
-"\\Ksni_c_user5 Transmit SNI-97801-5xx: Ctrl-Key below F22\n");
- break;
- case K_SNI_C_HELP :
- printf("\\Ksni_c_help Transmit SNI-97801-5xx: Ctrl-Help\n");
- break;
- case K_SNI_C_HOME :
- printf("\\Ksni_c_home Transmit SNI-97801-5xx: Ctrl-Home\n");
- break;
- case K_SNI_C_INSERT_CHAR :
- printf(
-"\\Ksni_c_ins_char Transmit SNI-97801-5xx: Ctrl-Insert Char\n");
- break;
- case K_SNI_C_INSERT_LINE :
- printf(
-"\\Ksni_c_ins_line Transmit SNI-97801-5xx: Ctrl-Insert Line\n");
- break;
- case K_SNI_C_INSERT_WORD :
- printf(
-"\\Ksni_c_ins_word Transmit SNI-97801-5xx: Ctrl-Insert Word\n");
- break;
- case K_SNI_C_LEFT_TAB :
- printf("\\Ksni_c_left_tab Transmit SNI-97801-5xx: Ctrl-Left Tab\n");
- break;
- case K_SNI_C_CURSOR_LEFT :
- printf(
-"\\Ksni_c_lfarr Transmit SNI-97801-5xx: Ctrl-Cursor Left\n");
- break;
- case K_SNI_C_MODE :
- printf("\\Ksni_c_mode Transmit SNI-97801-5xx: Ctrl-Mode\n");
- break;
- case K_SNI_C_PAGE :
- printf("\\Ksni_c_page Transmit SNI-97801-5xx: Ctrl-Page\n");
- break;
- case K_SNI_C_PRINT :
- printf("\\Ksni_c_print Transmit SNI-97801-5xx: Ctrl-Print\n");
- break;
- case K_SNI_C_CURSOR_RIGHT:
- printf(
-"\\Ksni_c_rtarr Transmit SNI-97801-5xx: Ctrl-Cursor Right\n");
- break;
- case K_SNI_C_SCROLL_DOWN :
- printf(
-"\\Ksni_c_scroll_dn Transmit SNI-97801-5xx: Ctrl-Scroll Down\n");
- break;
- case K_SNI_C_SCROLL_UP :
- printf("\\Ksni_c_scroll_up Transmit SNI-97801-5xx: Ctrl-Scroll Up\n");
- break;
- case K_SNI_C_START :
- printf("\\Ksni_c_start Transmit SNI-97801-5xx: Ctrl-Start\n");
- break;
- case K_SNI_C_CURSOR_UP :
- printf("\\Ksni_c_uparr Transmit SNI-97801-5xx: Ctrl-Cursor Up\n");
- break;
- case K_SNI_C_TAB :
- printf("\\Ksni_c_tab Transmit SNI-97801-5xx: Ctrl-Tab\n");
- break;
- case K_SNI_CE :
- printf("\\Ksni_ce Transmit SNI-97801-5xx: CE\n");
- break;
- case K_SNI_CH_CODE:
- printf("\\Ksni_ch_code Toggle SNI-97801-5xx: CH.CODE function.\n");
- break;
- case K_SNI_COMPOSE :
- printf("\\Ksni_compose Transmit SNI-97801-5xx: Compose\n");
- break;
- case K_SNI_DELETE_CHAR :
- printf("\\Ksni_del_char Transmit SNI-97801-5xx: Delete Char\n");
- break;
- case K_SNI_DELETE_LINE :
- printf("\\Ksni_del_line Transmit SNI-97801-5xx: Delete Line\n");
- break;
- case K_SNI_DELETE_WORD :
- printf("\\Ksni_del_word Transmit SNI-97801-5xx: Delete Word\n");
- break;
- case K_SNI_CURSOR_DOWN :
- printf("\\Ksni_dnarr Transmit SNI-97801-5xx: Cursor Down\n");
- break;
- case K_SNI_ENDMARKE :
- printf("\\Ksni_endmarke Transmit SNI-97801-5xx: End Marke\n");
- break;
- case K_SNI_F01 :
- printf("\\Ksni_f01 Transmit SNI-97801-5xx: F1\n");
- break;
- case K_SNI_F02 :
- printf("\\Ksni_f02 Transmit SNI-97801-5xx: F2\n");
- break;
- case K_SNI_F03 :
- printf("\\Ksni_f03 Transmit SNI-97801-5xx: F3\n");
- break;
- case K_SNI_F04 :
- printf("\\Ksni_f04 Transmit SNI-97801-5xx: F4\n");
- break;
- case K_SNI_F05 :
- printf("\\Ksni_f05 Transmit SNI-97801-5xx: F5\n");
- break;
- case K_SNI_F06 :
- printf("\\Ksni_f06 Transmit SNI-97801-5xx: F6\n");
- break;
- case K_SNI_F07 :
- printf("\\Ksni_f07 Transmit SNI-97801-5xx: F7\n");
- break;
- case K_SNI_F08 :
- printf("\\Ksni_f08 Transmit SNI-97801-5xx: F8\n");
- break;
- case K_SNI_F09 :
- printf("\\Ksni_f09 Transmit SNI-97801-5xx: F9\n");
- break;
- case K_SNI_F10 :
- printf("\\Ksni_f10 Transmit SNI-97801-5xx: F10\n");
- break;
- case K_SNI_F11 :
- printf("\\Ksni_f11 Transmit SNI-97801-5xx: F11\n");
- break;
- case K_SNI_F12 :
- printf("\\Ksni_f12 Transmit SNI-97801-5xx: F12\n");
- break;
- case K_SNI_F13 :
- printf("\\Ksni_f13 Transmit SNI-97801-5xx: F13\n");
- break;
- case K_SNI_F14 :
- printf("\\Ksni_f14 Transmit SNI-97801-5xx: F14\n");
- break;
- case K_SNI_F15 :
- printf("\\Ksni_f15 Transmit SNI-97801-5xx: F15\n");
- break;
- case K_SNI_F16 :
- printf("\\Ksni_f16 Transmit SNI-97801-5xx: F16\n");
- break;
- case K_SNI_F17 :
- printf("\\Ksni_f17 Transmit SNI-97801-5xx: F17\n");
- break;
- case K_SNI_F18 :
- printf("\\Ksni_f18 Transmit SNI-97801-5xx: F18\n");
- break;
- case K_SNI_USER1 :
- printf("\\Ksni_user1 Transmit SNI-97801-5xx: Key below F18\n");
- break;
- case K_SNI_F19 :
- printf("\\Ksni_f19 Transmit SNI-97801-5xx: F19\n");
- break;
- case K_SNI_USER2 :
- printf("\\Ksni_user2 Transmit SNI-97801-5xx: Key below F19\n");
- break;
- case K_SNI_F20 :
- printf("\\Ksni_f20 Transmit SNI-97801-5xx: F20\n");
- break;
- case K_SNI_USER3 :
- printf("\\Ksni_user3 Transmit SNI-97801-5xx: Key below F20\n");
- break;
- case K_SNI_F21 :
- printf("\\Ksni_f21 Transmit SNI-97801-5xx: F21\n");
- break;
- case K_SNI_USER4 :
- printf("\\Ksni_user4 Transmit SNI-97801-5xx: Key below F21\n");
- break;
- case K_SNI_F22 :
- printf("\\Ksni_f22 Transmit SNI-97801-5xx: F22\n");
- break;
- case K_SNI_USER5 :
- printf("\\Ksni_user5 Transmit SNI-97801-5xx: Key below F22\n");
- break;
- case K_SNI_HELP :
- printf("\\Ksni_help Transmit SNI-97801-5xx: Help\n");
- break;
- case K_SNI_HOME :
- printf("\\Ksni_home Transmit SNI-97801-5xx: Home\n");
- break;
- case K_SNI_INSERT_CHAR :
- printf("\\Ksni_ins_char Transmit SNI-97801-5xx: Insert Char\n");
- break;
- case K_SNI_INSERT_LINE :
- printf("\\Ksni_ins_line Transmit SNI-97801-5xx: Insert Line\n");
- break;
- case K_SNI_INSERT_WORD :
- printf("\\Ksni_ins_word Transmit SNI-97801-5xx: Insert Word\n");
- break;
- case K_SNI_LEFT_TAB :
- printf("\\Ksni_left_tab Transmit SNI-97801-5xx: Left Tab\n");
- break;
- case K_SNI_CURSOR_LEFT :
- printf("\\Ksni_lfarr Transmit SNI-97801-5xx: Cursor Left\n");
- break;
- case K_SNI_MODE :
- printf("\\Ksni_mode Transmit SNI-97801-5xx: Mode\n");
- break;
- case K_SNI_PAGE :
- printf("\\Ksni_page Transmit SNI-97801-5xx: Page\n");
- break;
- case K_SNI_PRINT :
- printf("\\Ksni_print Transmit SNI-97801-5xx: Print\n");
- break;
- case K_SNI_CURSOR_RIGHT :
- printf("\\Ksni_rtarr Transmit SNI-97801-5xx: Cursor Right\n");
- break;
- case K_SNI_S_DOUBLE_0 :
- printf(
-"\\Ksni_s_00 Transmit SNI-97801-5xx: Shift-Double-Zero\n");
- break;
- case K_SNI_S_CE :
- printf("\\Ksni_s_ce Transmit SNI-97801-5xx: Shift-CE\n");
- break;
- case K_SNI_S_COMPOSE :
- printf("\\Ksni_s_compose Transmit SNI-97801-5xx: Shift-Compose\n");
- break;
- case K_SNI_S_DELETE_CHAR :
- printf(
-"\\Ksni_s_del_char Transmit SNI-97801-5xx: Shift-Delete Char\n");
- break;
- case K_SNI_S_DELETE_LINE :
- printf(
-"\\Ksni_s_del_line Transmit SNI-97801-5xx: Shift-Delete Line\n");
- break;
- case K_SNI_S_DELETE_WORD :
- printf(
-"\\Ksni_s_del_word Transmit SNI-97801-5xx: Shift-Delete Word\n");
- break;
- case K_SNI_S_CURSOR_DOWN :
- printf(
-"\\Ksni_s_dnarr Transmit SNI-97801-5xx: Shift-Cursor Down\n");
- break;
- case K_SNI_S_ENDMARKE :
- printf("\\Ksni_s_endmarke Transmit SNI-97801-5xx: Shift-End Marke\n");
- break;
- case K_SNI_S_F01 :
- printf("\\Ksni_s_f01 Transmit SNI-97801-5xx: Shift-F1\n");
- break;
- case K_SNI_S_F02 :
- printf("\\Ksni_s_f02 Transmit SNI-97801-5xx: Shift-F2\n");
- break;
- case K_SNI_S_F03 :
- printf("\\Ksni_s_f03 Transmit SNI-97801-5xx: Shift-F3\n");
- break;
- case K_SNI_S_F04 :
- printf("\\Ksni_s_f04 Transmit SNI-97801-5xx: Shift-F4\n");
- break;
- case K_SNI_S_F05 :
- printf("\\Ksni_s_f05 Transmit SNI-97801-5xx: Shift-F5\n");
- break;
- case K_SNI_S_F06 :
- printf("\\Ksni_s_f06 Transmit SNI-97801-5xx: Shift-F6\n");
- break;
- case K_SNI_S_F07 :
- printf("\\Ksni_s_f07 Transmit SNI-97801-5xx: Shift-F7\n");
- break;
- case K_SNI_S_F08 :
- printf("\\Ksni_s_f08 Transmit SNI-97801-5xx: Shift-F8\n");
- break;
- case K_SNI_S_F09 :
- printf("\\Ksni_s_f09 Transmit SNI-97801-5xx: Shift-F9\n");
- break;
- case K_SNI_S_F10 :
- printf("\\Ksni_s_f10 Transmit SNI-97801-5xx: Shift-F10\n");
- break;
- case K_SNI_S_F11 :
- printf("\\Ksni_s_f11 Transmit SNI-97801-5xx: Shift-F11\n");
- break;
- case K_SNI_S_F12 :
- printf("\\Ksni_s_f12 Transmit SNI-97801-5xx: Shift-F12\n");
- break;
- case K_SNI_S_F13 :
- printf("\\Ksni_s_f13 Transmit SNI-97801-5xx: Shift-F13\n");
- break;
- case K_SNI_S_F14 :
- printf("\\Ksni_s_f14 Transmit SNI-97801-5xx: Shift-F14\n");
- break;
- case K_SNI_S_F15 :
- printf("\\Ksni_s_f15 Transmit SNI-97801-5xx: Shift-F15\n");
- break;
- case K_SNI_S_F16 :
- printf("\\Ksni_s_f16 Transmit SNI-97801-5xx: Shift-F16\n");
- break;
- case K_SNI_S_F17 :
- printf("\\Ksni_s_f17 Transmit SNI-97801-5xx: Shift-F17\n");
- break;
- case K_SNI_S_F18 :
- printf("\\Ksni_s_f18 Transmit SNI-97801-5xx: Shift-F18\n");
- break;
- case K_SNI_S_USER1 :
- printf(
-"\\Ksni_s_user1 Transmit SNI-97801-5xx: Shift-Key below F18\n");
- break;
- case K_SNI_S_F19 :
- printf("\\Ksni_s_f19 Transmit SNI-97801-5xx: Shift-F19\n");
- break;
- case K_SNI_S_USER2 :
- printf(
-"\\Ksni_s_user2 Transmit SNI-97801-5xx: Shift-Key below F19\n");
- break;
- case K_SNI_S_F20 :
- printf("\\Ksni_s_f20 Transmit SNI-97801-5xx: Shift-F20\n");
- break;
- case K_SNI_S_USER3 :
- printf(
-"\\Ksni_s_user3 Transmit SNI-97801-5xx: Shift-Key below F20\n");
- break;
- case K_SNI_S_F21 :
- printf("\\Ksni_s_f21 Transmit SNI-97801-5xx: Shift-F21\n");
- break;
- case K_SNI_S_USER4 :
- printf(
-"\\Ksni_s_user4 Transmit SNI-97801-5xx: Shift-Key below F21\n");
- break;
- case K_SNI_S_F22 :
- printf("\\Ksni_s_f22 Transmit SNI-97801-5xx: Shift-F22\n");
- break;
- case K_SNI_S_USER5 :
- printf(
-"\\Ksni_s_user5 Transmit SNI-97801-5xx: Shift-Key below F22\n");
- break;
- case K_SNI_S_HELP :
- printf("\\Ksni_s_help Transmit SNI-97801-5xx: Shift-Help\n");
- break;
- case K_SNI_S_HOME :
- printf("\\Ksni_s_home Transmit SNI-97801-5xx: Shift-Home\n");
- break;
- case K_SNI_S_INSERT_CHAR :
- printf(
-"\\Ksni_s_ins_char Transmit SNI-97801-5xx: Shift-Insert Char\n");
- break;
- case K_SNI_S_INSERT_LINE :
- printf(
-"\\Ksni_s_ins_line Transmit SNI-97801-5xx: Shift-Insert Line\n");
- break;
- case K_SNI_S_INSERT_WORD :
- printf(
-"\\Ksni_s_ins_word Transmit SNI-97801-5xx: Shift-Insert Word\n");
- break;
- case K_SNI_S_LEFT_TAB :
- printf("\\Ksni_s_left_tab Transmit SNI-97801-5xx: Shift-Left Tab\n");
- break;
- case K_SNI_S_CURSOR_LEFT :
- printf(
-"\\Ksni_s_lfarr Transmit SNI-97801-5xx: Shift-Cursor Left\n");
- break;
- case K_SNI_S_MODE :
- printf("\\Ksni_s_mode Transmit SNI-97801-5xx: Shift-Mode\n");
- break;
- case K_SNI_S_PAGE :
- printf("\\Ksni_s_page Transmit SNI-97801-5xx: Shift-Page\n");
- break;
- case K_SNI_S_PRINT :
- printf("\\Ksni_s_print Transmit SNI-97801-5xx: Shift-Print\n");
- break;
- case K_SNI_S_CURSOR_RIGHT:
- printf(
-"\\Ksni_s_rtarr Transmit SNI-97801-5xx: Shift-Cursor Right\n");
- break;
- case K_SNI_S_SCROLL_DOWN :
- printf(
-"\\Ksni_s_scroll_dn Transmit SNI-97801-5xx: Shift-Scroll Down\n");
- break;
- case K_SNI_S_SCROLL_UP :
- printf("\\Ksni_s_scroll_up Transmit SNI-97801-5xx: Shift-Scroll Up\n");
- break;
- case K_SNI_S_START :
- printf("\\Ksni_s_start Transmit SNI-97801-5xx: Shift-Start\n");
- break;
- case K_SNI_S_CURSOR_UP :
- printf("\\Ksni_s_uparr Transmit SNI-97801-5xx: Shift-Cursor Up\n");
- break;
- case K_SNI_S_TAB :
- printf("\\Ksni_s_tab Transmit SNI-97801-5xx: Shift-Tab\n");
- break;
- case K_SNI_SCROLL_DOWN :
- printf("\\Ksni_scroll_dn Transmit SNI-97801-5xx: Scroll Down\n");
- break;
- case K_SNI_SCROLL_UP :
- printf("\\Ksni_scroll_up Transmit SNI-97801-5xx: Scroll Up\n");
- break;
- case K_SNI_START :
- printf("\\Ksni_start Transmit SNI-97801-5xx: Start\n");
- break;
- case K_SNI_TAB :
- printf("\\Ksni_tab Transmit SNI-97801-5xx: Tab\n");
- break;
- case K_SNI_CURSOR_UP :
- printf("\\Ksni_uparr Transmit SNI-97801-5xx: Cursor Up\n");
- break;
-
- case K_BA80_ATTR:
- printf("\\Kba80_attr Transmit BA80: Attr\n");
- break;
- case K_BA80_C_KEY:
- printf("\\Kba80_c_key Transmit BA80: C\n");
- break;
- case K_BA80_CLEAR:
- printf("\\Kba80_clear Transmit BA80: Clear\n");
- break;
- case K_BA80_CMD:
- printf("\\Kba80_cmd Transmit BA80: Cmd\n");
- break;
- case K_BA80_COPY:
- printf("\\Kba80_copy Transmit BA80: Copy\n");
- break;
- case K_BA80_DEL:
- printf("\\Kba80_del Transmit BA80: Delete\n");
- break;
- case K_BA80_DEL_B:
- printf("\\Kba80_del_b Transmit BA80: Delete B\n");
- break;
- case K_BA80_DO:
- printf("\\Kba80_do Transmit BA80: Do\n");
- break;
- case K_BA80_END:
- printf("\\Kba80_end Transmit BA80: End\n");
- break;
- case K_BA80_ENV:
- printf("\\Kba80_env Transmit BA80: Env\n");
- break;
- case K_BA80_EOP:
- printf("\\Kba80_eop Transmit BA80: EOP\n");
- break;
- case K_BA80_ERASE:
- printf("\\Kba80_erase Transmit BA80: Erase\n");
- break;
- case K_BA80_FMT:
- printf("\\Kba80_fmt Transmit BA80: Format\n");
- break;
- case K_BA80_HELP:
- printf("\\Kba80_help Transmit BA80: Help\n");
- break;
- case K_BA80_HOME:
- printf("\\Kba80_home Transmit BA80: Home\n");
- break;
- case K_BA80_INS:
- printf("\\Kba80_ins Transmit BA80: Insert\n");
- break;
- case K_BA80_INS_B:
- printf("\\Kba80_ins_b Transmit BA80: Insert B\n");
- break;
- case K_BA80_MARK:
- printf("\\Kba80_mark Transmit BA80: Mark\n");
- break;
- case K_BA80_MOVE:
- printf("\\Kba80_move Transmit BA80: Move\n");
- break;
- case K_BA80_PA01:
- printf("\\Kba80_pa01 Transmit BA80: PA1\n");
- break;
- case K_BA80_PA02:
- printf("\\Kba80_pa02 Transmit BA80: PA2\n");
- break;
- case K_BA80_PA03:
- printf("\\Kba80_pa03 Transmit BA80: PA3\n");
- break;
- case K_BA80_PA04:
- printf("\\Kba80_pa04 Transmit BA80: PA4\n");
- break;
- case K_BA80_PA05:
- printf("\\Kba80_pa05 Transmit BA80: PA5\n");
- break;
- case K_BA80_PA06:
- printf("\\Kba80_pa06 Transmit BA80: PA6\n");
- break;
- case K_BA80_PA07:
- printf("\\Kba80_pa07 Transmit BA80: PA7\n");
- break;
- case K_BA80_PA08:
- printf("\\Kba80_pa08 Transmit BA80: PA8\n");
- break;
- case K_BA80_PA09:
- printf("\\Kba80_pa09 Transmit BA80: PA9\n");
- break;
- case K_BA80_PA10:
- printf("\\Kba80_pa10 Transmit BA80: PA10\n");
- break;
- case K_BA80_PA11:
- printf("\\Kba80_pa11 Transmit BA80: PA11\n");
- break;
- case K_BA80_PA12:
- printf("\\Kba80_pa12 Transmit BA80: PA12\n");
- break;
- case K_BA80_PA13:
- printf("\\Kba80_pa13 Transmit BA80: PA13\n");
- break;
- case K_BA80_PA14:
- printf("\\Kba80_pa14 Transmit BA80: PA14\n");
- break;
- case K_BA80_PA15:
- printf("\\Kba80_pa15 Transmit BA80: PA15\n");
- break;
- case K_BA80_PA16:
- printf("\\Kba80_pa16 Transmit BA80: PA16\n");
- break;
- case K_BA80_PA17:
- printf("\\Kba80_pa17 Transmit BA80: PA17\n");
- break;
- case K_BA80_PA18:
- printf("\\Kba80_pa18 Transmit BA80: PA18\n");
- break;
- case K_BA80_PA19:
- printf("\\Kba80_pa19 Transmit BA80: PA19\n");
- break;
- case K_BA80_PA20:
- printf("\\Kba80_pa20 Transmit BA80: PA20\n");
- break;
- case K_BA80_PA21:
- printf("\\Kba80_pa21 Transmit BA80: PA21\n");
- break;
- case K_BA80_PA22:
- printf("\\Kba80_pa22 Transmit BA80: PA22\n");
- break;
- case K_BA80_PA23:
- printf("\\Kba80_pa23 Transmit BA80: PA23\n");
- break;
- case K_BA80_PA24:
- printf("\\Kba80_pa24 Transmit BA80: PA24\n");
- break;
- case K_BA80_PGDN:
- printf("\\Kba80_pgdn Transmit BA80: Page Down\n");
- break;
- case K_BA80_PGUP:
- printf("\\Kba80_pgup Transmit BA80: Page Up\n");
- break;
- case K_BA80_PICK:
- printf("\\Kba80_pick Transmit BA80: Pick\n");
- break;
- case K_BA80_PRINT:
- printf("\\Kba80_print Transmit BA80: Print\n");
- break;
- case K_BA80_PUT:
- printf("\\Kba80_put Transmit BA80: Put\n");
- break;
- case K_BA80_REFRESH:
- printf("\\Kba80_refresh Transmit BA80: Refresh \n");
- break;
- case K_BA80_RESET:
- printf("\\Kba80_reset Transmit BA80: Reset\n");
- break;
- case K_BA80_RUBOUT:
- printf("\\Kba80_rubout Transmit BA80: Rubout\n");
- break;
- case K_BA80_SAVE:
- printf("\\Kba80_save Transmit BA80: Save\n");
- break;
- case K_BA80_SOFTKEY1:
- printf("\\Kba80_softkey1 Transmit BA80: Softkey 1\n");
- break;
- case K_BA80_SOFTKEY2:
- printf("\\Kba80_softkey2 Transmit BA80: Softkey 2\n");
- break;
- case K_BA80_SOFTKEY3:
- printf("\\Kba80_softkey3 Transmit BA80: Softkey 3\n");
- break;
- case K_BA80_SOFTKEY4:
- printf("\\Kba80_softkey4 Transmit BA80: Softkey 4\n");
- break;
- case K_BA80_SOFTKEY5:
- printf("\\Kba80_softkey5 Transmit BA80: Softkey 5\n");
- break;
- case K_BA80_SOFTKEY6:
- printf("\\Kba80_softkey6 Transmit BA80: Softkey 6\n");
- break;
- case K_BA80_SOFTKEY7:
- printf("\\Kba80_softkey7 Transmit BA80: Softkey 7\n");
- break;
- case K_BA80_SOFTKEY8:
- printf("\\Kba80_softkey8 Transmit BA80: Softkey 8\n");
- break;
- case K_BA80_SOFTKEY9:
- printf("\\Kba80_softkey9 Transmit BA80: Softkey 9\n");
- break;
- case K_BA80_UNDO:
- printf("\\Kba80_undo Transmit BA80: Undo\n");
- break;
-
- case K_I31_F01:
- printf("\\Ki31_f01 Transmit IBM 31xx: F1\n");
- break;
- case K_I31_F02:
- printf("\\Ki31_f02 Transmit IBM 31xx: F2\n");
- break;
- case K_I31_F03:
- printf("\\Ki31_f03 Transmit IBM 31xx: F3\n");
- break;
- case K_I31_F04:
- printf("\\Ki31_f04 Transmit IBM 31xx: F4\n");
- break;
- case K_I31_F05:
- printf("\\Ki31_f05 Transmit IBM 31xx: F5\n");
- break;
- case K_I31_F06:
- printf("\\Ki31_f06 Transmit IBM 31xx: F6\n");
- break;
- case K_I31_F07:
- printf("\\Ki31_f07 Transmit IBM 31xx: F7\n");
- break;
- case K_I31_F08:
- printf("\\Ki31_f08 Transmit IBM 31xx: F8\n");
- break;
- case K_I31_F09:
- printf("\\Ki31_f09 Transmit IBM 31xx: F9\n");
- break;
- case K_I31_F10:
- printf("\\Ki31_f10 Transmit IBM 31xx: F10\n");
- break;
- case K_I31_F11:
- printf("\\Ki31_f11 Transmit IBM 31xx: F11\n");
- break;
- case K_I31_F12:
- printf("\\Ki31_f12 Transmit IBM 31xx: F12\n");
- break;
- case K_I31_F13:
- printf("\\Ki31_f13 Transmit IBM 31xx: F13\n");
- break;
- case K_I31_F14:
- printf("\\Ki31_f14 Transmit IBM 31xx: F14\n");
- break;
- case K_I31_F15:
- printf("\\Ki31_f15 Transmit IBM 31xx: F15\n");
- break;
- case K_I31_F16:
- printf("\\Ki31_f16 Transmit IBM 31xx: F16\n");
- break;
- case K_I31_F17:
- printf("\\Ki31_f17 Transmit IBM 31xx: F17\n");
- break;
- case K_I31_F18:
- printf("\\Ki31_f18 Transmit IBM 31xx: F18\n");
- break;
- case K_I31_F19:
- printf("\\Ki31_f19 Transmit IBM 31xx: F19\n");
- break;
- case K_I31_F20:
- printf("\\Ki31_f20 Transmit IBM 31xx: F20\n");
- break;
- case K_I31_F21:
- printf("\\Ki31_f21 Transmit IBM 31xx: F21\n");
- break;
- case K_I31_F22:
- printf("\\Ki31_f22 Transmit IBM 31xx: F22\n");
- break;
- case K_I31_F23:
- printf("\\Ki31_f23 Transmit IBM 31xx: F23\n");
- break;
- case K_I31_F24:
- printf("\\Ki31_f24 Transmit IBM 31xx: F24\n");
- break;
- case K_I31_F25:
- printf("\\Ki31_f25 Transmit IBM 31xx: F25\n");
- break;
- case K_I31_F26:
- printf("\\Ki31_f26 Transmit IBM 31xx: F26\n");
- break;
- case K_I31_F27:
- printf("\\Ki31_f27 Transmit IBM 31xx: F27\n");
- break;
- case K_I31_F28:
- printf("\\Ki31_f28 Transmit IBM 31xx: F28\n");
- break;
- case K_I31_F29:
- printf("\\Ki31_f29 Transmit IBM 31xx: F29\n");
- break;
- case K_I31_F30:
- printf("\\Ki31_f30 Transmit IBM 31xx: F30\n");
- break;
- case K_I31_F31:
- printf("\\Ki31_f31 Transmit IBM 31xx: F31\n");
- break;
- case K_I31_F32:
- printf("\\Ki31_f32 Transmit IBM 31xx: F32\n");
- break;
- case K_I31_F33:
- printf("\\Ki31_f33 Transmit IBM 31xx: F33\n");
- break;
- case K_I31_F34:
- printf("\\Ki31_f34 Transmit IBM 31xx: F34\n");
- break;
- case K_I31_F35:
- printf("\\Ki31_f35 Transmit IBM 31xx: F35\n");
- break;
- case K_I31_F36:
- printf("\\Ki31_f36 Transmit IBM 31xx: F36\n");
- break;
- case K_I31_PA1:
- printf("\\Ki31_pa1 Transmit IBM 31xx: PA1\n");
- break;
- case K_I31_PA2:
- printf("\\Ki31_pa2 Transmit IBM 31xx: PA2\n");
- break;
- case K_I31_PA3:
- printf("\\Ki31_pa3 Transmit IBM 31xx: PA3\n");
- break;
- case K_I31_RESET:
- printf("\\Ki31_reset Transmit IBM 31xx: Reset\n");
- break;
- case K_I31_JUMP:
- printf("\\Ki31_jump Transmit IBM 31xx: Jump\n");
- break;
- case K_I31_CLEAR:
- printf("\\Ki31_clear Transmit IBM 31xx: Clear\n");
- break;
- case K_I31_ERASE_EOF:
- printf("\\Ki31_erase_eof Transmit IBM 31xx: Erase to End of Field\n");
- break;
- case K_I31_ERASE_EOP:
- printf("\\Ki31_eop Transmit IBM 31xx: Erase to End of Page\n");
- break;
- case K_I31_ERASE_INP:
- printf("\\Ki31_inp Transmit IBM 31xx: Erase Input Operation\n");
- break;
- case K_I31_INSERT_CHAR:
- printf("\\Ki31_ins_char Transmit IBM 31xx: Insert Character\n");
- break;
- case K_I31_INSERT_SPACE:
- printf("\\Ki31_ins_space Transmit IBM 31xx: Insert Space\n");
- break;
- case K_I31_DELETE:
- printf("\\Ki31_delete Transmit IBM 31xx: Delete Character\n");
- break;
- case K_I31_INS_LN:
- printf("\\Ki31_ins_line Transmit IBM 31xx: Insert Line\n");
- break;
- case K_I31_DEL_LN:
- printf("\\Ki31_del_ln Transmit IBM 31xx: Delete Line\n");
- break;
- case K_I31_PRINT_LINE:
- printf("\\Ki31_prt_line Transmit IBM 31xx: Print Line\n");
- break;
- case K_I31_PRINT_MSG:
- printf("\\Ki31_prt_msg Transmit IBM 31xx: Print Message\n");
- break;
- case K_I31_PRINT_SHIFT:
- printf("\\Ki31_prt_shift Transmit IBM 31xx: Print Shift\n");
- break;
- case K_I31_CANCEL:
- printf("\\Ki31_cancel Transmit IBM 31xx: Cancel\n");
- break;
- case K_I31_SEND_LINE:
- printf("\\Ki31_send_line Transmit IBM 31xx: Send Line\n");
- break;
- case K_I31_SEND_MSG:
- printf("\\Ki31_send_msg Transmit IBM 31xx: Send Message\n");
- break;
- case K_I31_SEND_PAGE:
- printf("\\Ki31_send_page Transmit IBM 31xx: Send Page\n");
- break;
- case K_I31_HOME:
- printf("\\Ki31_home Transmit IBM 31xx: Home\n");
- break;
- case K_I31_BACK_TAB:
- printf("\\Ki31_back_tab Transmit IBM 31xx: Back Tab\n");
- break;
- case K_SUN_STOP:
- printf("\\Ksunstop Transmit SUN Console: Stop\n");
- break;
- case K_SUN_AGAIN:
- printf("\\Ksunagain Transmit SUN Console: Again\n");
- break;
- case K_SUN_PROPS:
- printf("\\Ksunprops Transmit SUN Console: Props\n");
- break;
- case K_SUN_UNDO:
- printf("\\Ksunundo Transmit SUN Console: Undo\n");
- break;
- case K_SUN_FRONT:
- printf("\\Ksunfront Transmit SUN Console: Front\n");
- break;
- case K_SUN_COPY:
- printf("\\Ksuncopy Transmit SUN Console: Copy\n");
- break;
- case K_SUN_OPEN:
- printf("\\Ksunopen Transmit SUN Console: Open\n");
- break;
- case K_SUN_PASTE:
- printf("\\Ksunpaste Transmit SUN Console: Paste\n");
- break;
- case K_SUN_FIND:
- printf("\\Ksunfind Transmit SUN Console: Find\n");
- break;
- case K_SUN_CUT:
- printf("\\Ksuncut Transmit SUN Console: Cut\n");
- break;
- case K_SUN_HELP:
- printf("\\Ksunhelp Transmit SUN Console: Help\n");
- break;
-
- default:
- printf("No additional help available for this kverb\n");
- }
- printf("\n");
-
- /* This is not the proper way to do it since it doesn't show */
- /* all emulations, nor does it show the special modes, but it */
- /* is better than nothing. */
-
- printf("Current bindings:\n");
- found = 0;
- for (i = 256; i < KMSIZE ; i++) {
- con_event evt = mapkey(i);
- if (evt.type != kverb)
- continue;
- if ((evt.kverb.id & ~F_KVERB) == xx) {
- found = 1;
- printf(" \\%-4d - %s\n",i,keyname(i));
- }
- }
-#ifdef OS2MOUSE
- for ( button = 0 ; button < MMBUTTONMAX ; button++ )
- for ( event = 0 ; event < MMEVENTSIZE ; event++ )
- if ( mousemap[button][event].type == kverb ) {
- if ( (mousemap[button][event].kverb.id & ~F_KVERB) == xx ) {
- found = 1;
- printf(" Mouse - %s\n",mousename(button,event));
- }
- }
-#endif /* OS2MOUSE */
-
- if ( !found ) {
- printf(" (none)\n");
- }
- return(0);
-}
-#endif /* NOKVERBS */
-#endif /* OS2 */
-
-#ifndef NOXFER
-/* D O H R M T -- Give help about REMOTE command */
-
-static char *hrset[] = {
-"Syntax: REMOTE SET parameter value",
-"Example: REMOTE SET FILE TYPE BINARY",
-" Asks the Kermit server to set the named parameter to the given value.",
-" Equivalent to typing the corresponding SET command directly to the other",
-" Kermit if it were in interactive mode.", "" };
-
-int
-dohrmt(xx) int xx; {
- int x;
- if (xx == -3) return(hmsga(hmhrmt));
- if (xx < 0) return(xx);
- if ((x = cmcfm()) < 0) return(x);
- switch (xx) {
-
-case XZCPY:
- return(hmsg("Syntax: REMOTE COPY source destination\n\
- Asks the Kermit server to copy the source file to destination.\n\
- Synonym: RCOPY."));
-
-case XZCWD:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE CD [ name ]\n\
- Asks the Kermit or FTP server to change its working directory or device.\n\
- If the device or directory name is omitted, restore the default.\n\
- Synonym: RCD."));
-#else
- return(hmsg("Syntax: REMOTE CD [ name ]\n\
- Asks the Kermit server to change its working directory or device.\n\
- If the device or directory name is omitted, restore the default.\n\
- Synonym: RCD."));
-#endif /* NEWFTP */
-
-case XZDEL:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE DELETE filespec\n\
- Asks the Kermit or FTP server to delete the named file(s).\n\
- Synonym: RDEL."));
-#else
- return(hmsg("Syntax: REMOTE DELETE filespec\n\
- Asks the Kermit server to delete the named file(s).\n\
- Synonym: RDEL."));
-#endif /* NEWFTP */
-
-case XZMKD:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE MKDIR directory-name\n\
- Asks the Kermit or FTP server to create the named directory.\n\
- Synonym: RMKDIR."));
-#else
- return(hmsg("Syntax: REMOTE MKDIR directory-name\n\
- Asks the Kermit server to create the named directory.\n\
- Synonym: RMKDIR."));
-#endif /* NEWFTP */
-
-case XZRMD:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE RMDIR directory-name\n\
- Asks the Kermit or FTP server to remove the named directory.\n\
- Synonym: RRMDIR."));
-#else
- return(hmsg("Syntax: REMOTE RMDIR directory-name\n\
- Asks the Kermit server to remove the named directory.\n\
- Synonym: RRMDIR."));
-#endif /* NEWFTP */
-
-case XZDIR:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE DIRECTORY [ filespec ]\n\
- Asks the Kermit or FTP server to provide a directory listing of the named\n\
- file(s) or if no file specification is given, of all files in its current\n\
- directory. Synonym: RDIR."));
-#else
- return(hmsg("Syntax: REMOTE DIRECTORY [ filespec ]\n\
- Asks the Kermit server to provide a directory listing of the named\n\
- file(s) or if no file specification is given, of all files in its current\n\
- directory. Synonym: RDIR."));
-#endif /* NEWFTP */
-
-case XZHLP:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE HELP\n\
- Asks the Kermit or FTP server to list the services it provides.\n\
- Synonym: RHELP."));
-#else
- return(hmsg("Syntax: REMOTE HELP\n\
- Asks the Kermit server to list the services it provides.\n\
- Synonym: RHELP."));
-#endif /* NEWFTP */
-
-case XZHOS:
- return(hmsg("Syntax: REMOTE HOST command\n\
- Sends a command to the other computer in its own command language\n\
- through the Kermit server that is running on that host. Synonym: RHOST."));
-
-#ifndef NOFRILLS
-case XZKER:
- return(hmsg("Syntax: REMOTE KERMIT command\n\
- Sends a command to the remote Kermit server in its own command language.\n\
- Synonym: RKERMIT."));
-
-case XZLGI:
- return(hmsg("Syntax: REMOTE LOGIN user password [ account ]\n\
- Logs in to a remote Kermit server that requires you login. Note: RLOGIN\n\
- is NOT a synonym for REMOTE LOGIN."));
-
-case XZLGO:
- return(hmsg("Syntax: REMOTE LOGOUT\n\
- Logs out from a remote Kermit server to which you have previously logged in."
-));
-
-case XZPRI:
- return(hmsg("Syntax: REMOTE PRINT filespec [ options ]\n\
- Sends the specified file(s) to the remote Kermit and ask it to have the\n\
- file printed on the remote system's printer, using any specified options.\n\
- Synonym: RPRINT."));
-#endif /* NOFRILLS */
-
-case XZREN:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE RENAME filespec newname\n\
- Asks the Kermit or FTP server to rename the file. Synonym: RRENAME."));
-#else
- return(hmsg("Syntax: REMOTE RENAME filespec newname\n\
- Asks the Kermit server to rename the file. Synonym: RRENAME."));
-#endif /* NEWFTP */
-
-case XZSET:
- return(hmsga(hrset));
-
-case XZSPA:
- return(hmsg("Syntax: REMOTE SPACE [ name ]\n\
- Asks the Kermit server to tell you about its disk space on the current\n\
- disk or directory, or in the one that you name. Synonym: RSPACE."));
-
-#ifndef NOFRILLS
-case XZTYP:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE TYPE file\n\
- Asks the Kermit or FTP server to send the named file to your screen.\n\
- Synonym: RTYPE."));
-#else
- return(hmsg("Syntax: REMOTE TYPE file\n\
- Asks the Kermit server to send the named file(s) to your screen.\n\
- Synonym: RTYPE."));
-#endif /* NEWFTP */
-
-
-case XZWHO:
- return(hmsg("Syntax: REMOTE WHO [ name ]\n\
- Asks the Kermit server to list who's logged in, or to give information\n\
- about the named user. Synonym: RWHO."));
-#endif /* NOFRILLS */
-
-#ifndef NOSPL
-case XZQUE:
- return(hmsg(
-"Syntax: [ REMOTE ] QUERY { KERMIT, SYSTEM, USER } variable-name\n\
- Asks the Kermit server to send the value of the named variable of the\n\
- given type, and make it available in the \\v(query) variable. When the\n\
- type is KERMIT functions may also be specified as if they were variables."));
-
-case XZASG:
- return(hmsg(
-"Syntax: REMOTE ASSIGN variable-name [ value ]\n\
- Assigns the given value to the named global variable on the server.\n\
- Synonyms: RASG, RASSIGN."));
-#endif /* NOSPL */
-
-case XZPWD:
- return(hmsg(
-#ifdef NEWFTP
-"Syntax: REMOTE PWD\n\
- Asks the Kermit server to display its current working directory.\n\
- Synonym: RPWD."));
-#else
-"Syntax: REMOTE PWD\n\
- Asks the Kermit or FTP server to display its current working directory.\n\
- Synonym: RPWD."));
-#endif /* NEWFTP */
-
-case XZXIT:
-#ifdef NEWFTP
- return(hmsg("Syntax: REMOTE EXIT\n\
- Asks the Kermit server to exit (without disconnecting), or closes an FTP\n\
- connection. Synonym: REXIT, and (for FTP only) BYE, FTP BYE."));
-#else
- return(hmsg("Syntax: REMOTE EXIT\n\
- Asks the Kermit server to exit. Synonym: REXIT."));
-#endif /* NEWFTP */
-
-default:
- if ((x = cmcfm()) < 0) return(x);
- printf("?Sorry, no help available - \"%s\"\n",cmdbuf);
- return(-9);
- }
-}
-#endif /* NOXFER */
-#endif /* NOHELP */
-#endif /* NOICP */
+++ /dev/null
-/* C K U U S R . H -- Symbol definitions for C-Kermit ckuus*.c modules */
-
-/*
- Author: Frank da Cruz <fdc@columbia.edu>,
- Columbia University Academic Information Systems, New York City.
-
- Copyright (C) 1985, 2004,
- Trustees of Columbia University in the City of New York.
- All rights reserved. See the C-Kermit COPYING.TXT file or the
- copyright text in the ckcmai.c module for disclaimer and permissions.
-*/
-#ifndef CKUUSR_H
-#define CKUUSR_H
-
-#include "ckucmd.h" /* Get symbols from command package */
-
-#ifndef NOLUCACHE /* Use lookup() cache */
-#ifndef NOSPL /* To speed up script programs */
-#ifndef USE_LUCACHE
-#define USE_LUCACHE
-#endif /* USE_LUCACHE */
-#endif /* NOSPL */
-#endif /* NOLUCACHE */
-
-#ifndef NODOUBLEQUOTING /* New to 8.0 */
-#define DOUBLEQUOTING /* Allow fields to be enclosed in */
-#endif /* NODOUBLEQUOTING */ /* doublequotes. */
-
-#ifndef NOLOCUS /* SET LOCUS */
-#define LOCUS
-#endif /* NOLOCUS */
-
-/* Sizes of things */
-
-#ifdef BIGBUFOK
-#define FNVALL 10238 /* Function return value length */
-#define MAXARGLEN 8191 /* Max func arg length after eval */
-#define MAXARGLIST 1024 /* Max number of args for a macro */
-#define FSPECL CMDBL /* Max length for MSEND/GET string */
-#define MSENDMAX 1024 /* Number of filespecs for MSEND */
-#define MAC_MAX 16384 /* Maximum number of macros */
-
-#else /* Same as above but for smaller builds... */
-
-#define FNVALL 1022
-#define MAXARGLEN 1023
-#define MAXARGLIST 64
-#define FSPECL 300
-#define MSENDMAX 128
-#define MAC_MAX 1024
-#endif /* BIGBUFOK */
-
-#define GVARS 127 /* Highest global var allowed */
-#ifdef BIGBUFOK
-#define VNAML 4096 /* Max length for variable name */
-#define ARRAYREFLEN 1024 /* Max length for array reference */
-#define FORDEPTH 32 /* Maximum depth of nested FOR loops */
-#define MAXTAKE 54 /* Maximum nesting of TAKE files */
-#define MACLEVEL 128 /* Maximum nesting for macros */
-#define INPBUFSIZ 4096 /* Size of INPUT buffer */
-#define PROMPTL 1024 /* Max length for prompt */
-#else
-#define VNAML 256 /* Max length for variable name */
-#define ARRAYREFLEN 128 /* Max length for array reference */
-#define FORDEPTH 10 /* Maximum depth of nested FOR loops */
-#define MAXTAKE 32 /* Maximum nesting of TAKE files */
-#define MACLEVEL 64 /* Maximum nesting for macros */
-#define INPBUFSIZ 256
-#define PROMPTL 256 /* Max length for prompt */
-#endif /* BIGBUFOK */
-#define NARGS 10 /* Max number of macro arguments */
-#define LINBUFSIZ (CMDBL + 10) /* Size of line[] buffer */
-#define TMPBUFSIZ (CMDBL + 10) /* Size of temporary buffer */
-#define LBLSIZ 50 /* Maximum length for a GOTO label */
-#define CMDSTKL ( MACLEVEL + MAXTAKE + 2) /* Command stack depth */
-
-#ifndef NOPURGE /* PURGE command */
-#ifdef UNIX
-#define CKPURGE
-#endif /* UNIX */
-#endif /* NOPURGE */
-
-#ifndef NOMINPUT /* MINPUT command */
-#ifndef NOSPL
-#define CK_MINPUT
-#ifndef MINPMAX
-#ifdef BIGBUFOK
-#define MINPMAX 96 /* Max number of MINPUT strings */
-#else
-#define MINPMAX 16
-#endif /* BIGBUFOK */
-#endif /* MINPMAX */
-#define MINPBUFL 256 /* Size of MINPUT temp buffer */
-#endif /* NOSPL */
-#endif /* NOMINPUT */
-
-#define ARRAYBASE 95 /* Lowest array-name character */
-
-#ifndef NOKERBANG
-#ifndef KERBANG
-#define KERBANG
-#endif /* KERBANG */
-#endif /* NOKERBANG */
-
-/* Bit values (1, 2, 4, 8, ...) for the ccflgs field */
-
-#define CF_APC 1 /* Executing an APC command */
-#define CF_KMAC 2 /* Executing a \Kmacro */
-#define CF_CMDL 4 /* Macro from -C "blah" command line */
-#define CF_REXX 8 /* Macro from REXX interpreter */
-#define CF_IMAC 16 /* Internal macro like FOR, WHILE... */
-
-struct cmdptr { /* Command stack structure */
- int src; /* Command Source */
- int lvl; /* Current TAKE or DO level */
- int ccflgs; /* Flags */
-};
-
-struct mtab { /* Macro table, like keyword table */
- char *kwd; /* But with pointers for vals */
- char *mval; /* instead of ints. */
- short flgs;
-};
-
-struct localvar { /* Local variable structure. */
- char * lv_name;
- char * lv_value;
- struct localvar * lv_next;
-};
-
-struct stringlist { /* General purpose string list */
- char * sl_name;
- struct stringlist * sl_next;
-};
-
-#ifndef NOICP
-/*
- C-Kermit Initialization file...
-
- System-dependent defaults are built into the program, see below.
- These can be overridden in either of two ways:
- 1. CK_DSYSINI is defined at compile time, in which case a default
- system-wide initialization file name is chosen from below, or:
- 2: CK_SYSINI is defined to be a string, which lets the program
- builder choose the initialization filespec at compile time.
- These can be given on the CC command line, so the source code need not be
- changed.
-*/
-
-#ifndef CK_SYSINI /* If no initialization file given, */
-#ifdef CK_DSYSINI /* but CK_DSYSINI is defined... */
-
-/* Supply system-dependent "default default" initialization file */
-
-#ifdef UNIX /* For UNIX, system-wide */
-/* This allows one copy of the standard init file on the whole system, */
-/* rather than a separate copy in each user's home directory. */
-#ifdef HPUX10
-#define CK_SYSINI "/usr/share/lib/kermit/ckermit.ini"
-#else
-#ifdef CU_ACIS
-#define CK_SYSINI "/usr/share/lib/kermit/ckermit.ini"
-#else
-#ifdef __linux__
-#define CK_SYSINI "/usr/share/kermit/ckermit.ini"
-#else
-#define CK_SYSINI "/usr/local/bin/ckermit.ini"
-#endif /* linux */
-#endif /* CU_ACIS */
-#endif /* HPUX10 */
-/* Fill in #else..#ifdef's here for VMS, OS/2, etc. */
-/* Fill in matching #endif's here. */
-#endif /* UNIX */
-
-#endif /* CK_DSYSINI */
-#endif /* CK_SYSINI */
-
-#ifdef CK_SYSINI /* Init-file precedence */
-#ifndef CK_INI_A /* A means system-wide file first */
-#ifndef CK_INI_B /* B means user's first */
-#define CK_INI_A /* A is default */
-#endif /* CK_INI_B */
-#endif /* CK_INI_A */
-#else
-#ifdef CK_INI_A /* Otherwise */
-#undef CK_INI_A /* make sure these aren't defined */
-#endif /* CK_INI_A */
-#ifdef CK_INI_B
-#undef CK_INI_B
-#endif /* CK_INI_B */
-#endif /* CK_SYSINI */
-
-#ifdef CK_SYSINI /* One more check... */
-#ifdef CK_INI_A /* Make sure they're not both */
-#ifdef CK_INI_B /* defined. */
-#undef CK_INI_B
-#endif /* CK_INI_B */
-#endif /* CK_INI_A */
-#endif /* CK_SYSINI */
-/*
- If neither CK_DSYSINI nor CK_SYSINI are defined, these are the
- built-in defaults for each platform. USE_CUSTOM means to execute the
- customization file automatically if the initialization file is not found.
-*/
-#ifndef NOCUSTOM
-#ifndef USE_CUSTOM
-#define USE_CUSTOM
-#endif /* USE_CUSTOM */
-#endif /* NOCUSTOM */
-
-#ifndef KERMRCL /* Path length for init file */
-#define KERMRCL CKMAXPATH
-#endif /* KERMRCL */
-
-#ifdef vms
-#define KERMRC "CKERMIT.INI" /* Init file name */
-#define MYCUSTOM "CKERMOD.INI" /* Customization file name */
-#else
-#ifdef OS2
-#ifdef NT
-#define KERMRC "k95.ini"
-#define MYCUSTOM "k95custom.ini"
-#else
-#define KERMRC "k2.ini"
-#define MYCUSTOM "k2custom.ini"
-#endif /* NT */
-#else
-#ifdef UNIXOROSK
-#define KERMRC ".kermrc"
-#define MYCUSTOM ".mykermrc"
-#else
-#ifdef STRATUS
-#define KERMRC "ckermit.ini"
-#define MYCUSTOM "ckermod.ini"
-#else
-#define KERMRC "CKERMIT.INI"
-#define MYCUSTOM "ckermod.ini"
-#endif /* STRATUS */
-#endif /* UNIXOROSK */
-#endif /* OS2 */
-#endif /* vms */
-
-#ifndef KERMRCL
-#define KERMRCL 256
-#endif /* KERMRCL */
-#endif /* NOICP */
-
-/* User interface features */
-
-#ifdef CK_CURSES /* Thermometer */
-#ifndef NO_PCT_BAR
-#ifndef CK_PCT_BAR
-#define CK_PCT_BAR
-#endif /* NO_PCT_BAR */
-#endif /* CK_PCT_BAR */
-#endif /* CK_CURSES */
-
-#ifdef KUI /* KUI requires the Thermometer code */
-#ifndef NO_PCT_BAR
-#ifndef CK_PCT_BAR
-#define CK_PCT_BAR
-#endif /* NO_PCT_BAR */
-#endif /* CK_PCT_BAR */
-#endif /* KUI */
-
-/* Includes */
-
-#ifdef MINIX
-/* why? */
-#include <sys/types.h>
-#endif /* MINIX */
-
-/* Symbols for command source */
-
-#define CMD_KB 0 /* KeyBoard or standard input */
-#define CMD_TF 1 /* TAKE command File */
-#define CMD_MD 2 /* Macro Definition */
-
-/*
- SET TRANSFER CANCELLATION command should be available in all versions.
- But for now...
-*/
-#ifdef UNIX /* UNIX has it */
-#ifndef XFRCAN
-#define XFRCAN
-#endif /* XFRCAN */
-#endif /* UNIX */
-#ifdef VMS /* VMS has it */
-#ifndef XFRCAN
-#define XFRCAN
-#endif /* XFRCAN */
-#endif /* VMS */
-#ifdef datageneral /* DG AOS/VS has it */
-#ifndef XFRCAN
-#define XFRCAN
-#endif /* XFRCAN */
-#endif /* datageneral */
-#ifdef STRATUS /* Stratus VOS has it */
-#ifndef XFRCAN
-#define XFRCAN
-#endif /* XFRCAN */
-#endif /* STRATUS */
-#ifdef OSK /* OS-9 */
-#ifndef XFRCAN
-#define XFRCAN
-#endif /* XFRCAN */
-#endif /* OSK */
-
-#ifndef NOCMDL
-/* Extended Command-Line Option Codes (keep alphabetical by keyword) */
-
-#define XA_ANON 0 /* --anonymous */
-#define XA_BAFI 1 /* --bannerfile */
-#define XA_CDFI 2 /* --cdfile */
-#define XA_CDMS 3 /* --cdmessage */
-#define XA_HELP 4 /* --help */
-#define XA_HEFI 5 /* --helpfile */
-#define XA_IKFI 6 /* --xferfile */
-#define XA_IKLG 7 /* --xferlog */
-#define XA_ANFI 8 /* --initfile */
-#define XA_PERM 9 /* --permissions */
-#define XA_ROOT 10 /* --root */
-#define XA_SYSL 11 /* --syslog */
-#define XA_USFI 12 /* --userfile */
-#define XA_WTFI 13 /* --wtmpfile */
-#define XA_WTMP 14 /* --wtmplog */
-#define XA_TIMO 15 /* --timeout */
-#define XA_NOIN 16 /* --nointerrupts */
-#define XA_DBAS 17 /* --database */
-#define XA_DBFI 18 /* --dbfile */
-#define XA_PRIV 19 /* --privid */
-#define XA_VERS 20 /* --version */
-#define XA_NPRM 21 /* --noperms */
-#define XA_XPOS 22 /* Window position X coordinate */
-#define XA_YPOS 23 /* Window position Y coordinate */
-#define XA_FNAM 24 /* Font Facename */
-#define XA_FSIZ 25 /* Font Size */
-#define XA_TERM 26 /* Terminal type */
-#define XA_CSET 27 /* Remote Character Set */
-#define XA_ROWS 28 /* Screen rows (height) */
-#define XA_COLS 29 /* Screen columns (width) */
-#define XA_TEL 30 /* Make a Telnet connection */
-#define XA_FTP 31 /* Make an FTP connection */
-#define XA_SSH 32 /* Make an SSH connection */
-#define XA_USER 33 /* Username for login */
-#define XA_PASS 34 /* Password for login */
-#define XA_TITL 35 /* Window Title */
-#define XA_NOMN 36 /* No GUI Menu Bar */
-#define XA_NOTB 37 /* No GUI Tool Bar */
-#define XA_NOSB 38 /* No GUI Status Bar */
-#define XA_NOPUSH 39 /* Disable external commands */
-#define XA_NOSCROLL 40 /* Disable scrollback operations */
-#define XA_NOESCAPE 41 /* Disable escape from connect mode */
-#define XA_LOCK 42 /* All lockdown options */
-#define XA_NOBAR 43 /* No GUI Bars */
-#define XA_WMAX 44
-#define XA_WMIN 45
-#define XA_SCALE 46 /* GUI Scale Font */
-#define XA_CHGD 47 /* GUI Change Dimensions */
-#define XA_MAX 47 /* Highest extended option number */
-#endif /* NOCMDL */
-
-#ifndef NOICP
-/* Top Level Commands */
-/* Values associated with top-level commands must be 0 or greater. */
-
-#define XXBYE 0 /* BYE */
-#define XXCLE 1 /* CLEAR */
-#define XXCLO 2 /* CLOSE */
-#define XXCON 3 /* CONNECT */
-#define XXCPY 4 /* COPY */
-#define XXCWD 5 /* CWD (Change Working Directory) */
-#define XXDEF 6 /* DEFINE (a macro or variable) */
-#define XXDEL 7 /* (Local) DELETE */
-#define XXDIR 8 /* (Local) DIRECTORY */
-
-/* DIRECTORY Command options... */
-#define DIR_BRF 1 /* BRIEF */
-#define DIR_VRB 2 /* VERBOSE */
-#define DIR_PAG 3 /* PAGE */
-#define DIR_NOP 4 /* NOPAGE */
-#define DIR_ISO 5 /* ISODATE */
-#define DIR_DAT 6 /* ENGLISHDATE */
-#define DIR_HDG 7 /* HEADINGS */
-#define DIR_NOH 8 /* NOHEADINGS */
-#define DIR_SRT 9 /* SORT */
-#define DIR_NOS 10 /* NOSORT */
-#define DIR_ASC 11 /* ASCENDING */
-#define DIR_DSC 12 /* DESCENDING */
-#define DIR_REC 13 /* RECURSIVE */
-#define DIR_NOR 14 /* NORECURIVE */
-#define DIR_DOT 15 /* DOTFILES */
-#define DIR_NOD 16 /* NODOTFILES */
-#define DIR_DIR 17 /* DIRECTORIES */
-#define DIR_FIL 18 /* FILES */
-#define DIR_ALL 19 /* ALL */
-#define DIR_NAM 20 /* NAMES: */
-#define DIR_TYP 21 /* FILETYPES */
-#define DIR_NOT 22 /* NOFILETYPES */
-#define DIR_BUP 23 /* BACKUP */
-#define DIR_NOB 24 /* NOBACKUP */
-#define DIR_MSG 25 /* MESSAGE */
-#define DIR_NOM 26 /* NOMESSAGE */
-#define DIR_ARR 27 /* ARRAY: */
-#define DIR_NAR 28 /* NOARRAY */
-#define DIR_EXC 29 /* EXCEPT: */
-#define DIR_LAR 30 /* LARGER-THAN: */
-#define DIR_SMA 31 /* SMALLER-THAN: */
-#define DIR_AFT 32 /* AFTER: */
-#define DIR_NAF 33 /* NOT-AFTER: */
-#define DIR_BEF 34 /* BEFORE: */
-#define DIR_NBF 35 /* NOT-BEFORE: */
-#define DIR_SUM 36 /* SUMMARY */
-#define DIR_BIN 37 /* TYPE (only show binary or text) */
-#define DIR_LNK 38 /* follow symlinks */
-#define DIR_NLK 39 /* don't follow symlinks */
-#define DIR_OUT 40 /* Output file for listing */
-
-#define DIRS_NM 0 /* Sort directory by NAME */
-#define DIRS_DT 1 /* Sort directory by DATE */
-#define DIRS_SZ 2 /* Sort directory by SIZE */
-
-#define XXDIS 9 /* DISABLE */
-#define XXECH 10 /* ECHO */
-#define XXEXI 11 /* EXIT */
-#define XXFIN 12 /* FINISH */
-#define XXGET 13 /* GET */
-#define XXHLP 14 /* HELP */
-#define XXINP 15 /* INPUT */
-#define XXLOC 16 /* LOCAL */
-#define XXLOG 17 /* LOG */
-#define XXMAI 18 /* MAIL */
-#define XXMOU 19 /* (Local) MOUNT */
-#define XXMSG 20 /* (Local) MESSAGE */
-#define XXOUT 21 /* OUTPUT */
-#define XXPAU 22 /* PAUSE */
-#define XXPRI 23 /* (Local) PRINT */
-#define XXQUI 24 /* QUIT */
-#define XXREC 25 /* RECEIVE */
-#define XXREM 26 /* REMOTE */
-#define XXREN 27 /* (Local) RENAME */
-#define XXSEN 28 /* SEND */
-
-/* SEND switches */
-
-#define SND_BIN 0 /* Binary mode */
-#define SND_DEL 1 /* Delete after */
-#define SND_EXC 2 /* Except */
-#define SND_LAR 3 /* Larger than */
-#define SND_MAI 4 /* Mail */
-#define SND_BEF 5 /* Before */
-#define SND_AFT 6 /* After */
-#define SND_PRI 7 /* Print */
-#define SND_SHH 8 /* Quiet */
-#define SND_REC 9 /* Recursive */
-#define SND_SMA 10 /* Smaller than */
-#define SND_STA 11 /* Starting-from */
-#define SND_TXT 12 /* Text mode */
-#define SND_CMD 13 /* From command (pipe) */
-#define SND_RES 14 /* Resend/Recover */
-#define SND_PRO 15 /* Protocol */
-#define SND_ASN 16 /* As-name */
-#define SND_IMG 17 /* Image */
-#define SND_LBL 18 /* Labeled */
-#define SND_NAF 19 /* Not-After */
-#define SND_NBE 20 /* Not-Before */
-#define SND_FLT 21 /* Filter */
-#define SND_PTH 22 /* Pathnames */
-#define SND_NAM 23 /* Filenames */
-#define SND_MOV 24 /* MOVE to another directory */
-#define SND_REN 25 /* RENAME after sending */
-#define SND_CAL 26 /* Calibrate */
-#define SND_FIL 27 /* File containing list of files to send */
-#define SND_NOB 28 /* Skip backup files */
-#define SND_DOT 29 /* Include dot-files */
-#define SND_NOD 30 /* Exclude dot-files */
-#define SND_ARR 31 /* Send from array */
-#define SND_TYP 32 /* TYPE (only send text (or binary)) */
-#define SND_XPA 33 /* TRANSPARENT */
-#define SND_PIP 34 /* PIPES */
-#define SND_ERR 35 /* ERROR */
-#define SND_CSL 36 /* Local character set */
-#define SND_CSR 37 /* Remote character set */
-#define SND_UPD 38 /* Update */
-#define SND_COL 39 /* Collision */
-#define SND_NML 40 /* Namelist */
-#define SND_SRN 41 /* Server-Rename */
-#define SND_LNK 42 /* Follow links */
-#define SND_NLK 43 /* Don't follow links */
-#define SND_SIM 44 /* Simulate */
-#define SND_DIF 45 /* If dates Differ */
-#define SND_PAT 46 /* Pattern to use locally when GET'ing */
-#define SND_NLS 47 /* (FTP only) MGET forces NLST */
-#define SND_MLS 48 /* (FTP only) MGET forces MLSD */
-
-#define SND_MAX 48 /* Highest SEND switch */
-
-#define XXSER 29 /* SERVER */
-#define XXSET 30 /* SET */
-#define XXSHE 31 /* Command for SHELL */
-#define XXSHO 32 /* SHOW */
-#define XXSPA 33 /* (Local) SPACE */
-#define XXSTA 34 /* STATISTICS */
-#define XXSUB 35 /* (Local) SUBMIT */
-#define XXTAK 36 /* TAKE */
-#define XXTRA 37 /* TRANSMIT */
-#define XXTYP 38 /* (Local) TYPE */
-#define XXWHO 39 /* (Local) WHO */
-#define XXDIAL 40 /* (Local) DIAL */
-#define XXLOGI 41 /* (Local) SCRIPT */
-#define XXCOM 42 /* Comment */
-#define XXHAN 43 /* HANGUP */
-#define XXXLA 44 /* TRANSLATE */
-#define XXIF 45 /* IF */
-#define XXLBL 46 /* label */
-#define XXGOTO 47 /* GOTO */
-#define XXEND 48 /* END */
-#define XXSTO 49 /* STOP */
-#define XXDO 50 /* DO */
-#define XXPWD 51 /* PWD */
-#define XXTES 52 /* TEST */
-#define XXASK 53 /* ASK */
-#define XXASKQ 54 /* ASKQ */
-#define XXASS 55 /* ASSIGN */
-#define XXREI 56 /* REINPUT */
-#define XXINC 57 /* INCREMENT */
-#define XXDEC 59 /* DECREMENT */
-#define XXELS 60 /* ELSE */
-#define XXEXE 61 /* EXECUTE */
-#define XXWAI 62 /* WAIT */
-#define XXVER 63 /* VERSION */
-#define XXENA 64 /* ENABLE */
-#define XXWRI 65 /* WRITE */
-#define XXCLS 66 /* CLS (clear screen) */
-#define XXRET 67 /* RETURN */
-#define XXOPE 68 /* OPEN */
-#define XXREA 69 /* READ */
-#define XXON 70 /* ON */
-#define XXDCL 71 /* DECLARE */
-#define XXBEG 72 /* BEGIN (not used) */
-#define XXFOR 72 /* FOR */
-#define XXWHI 73 /* WHILE */
-#define XXIFX 74 /* Extended IF */
-#define XXCMS 75 /* SEND from command output (not yet) */
-#define XXCMR 76 /* RECEIVE to a command's input (not yet) */
-#define XXCMG 77 /* GET to a command's input (not yet) */
-#define XXSUS 78 /* SUSPEND */
-#define XXERR 79 /* ERROR */
-#define XXMSE 80 /* MSEND */
-#define XXBUG 81 /* BUG */
-#define XXPAD 82 /* PAD (as in X.25 PAD) ANYX25 */
-#define XXRED 83 /* REDIAL */
-#define XXGTA 84 /* _getargs (invisible internal) */
-#define XXPTA 85 /* _putargs (invisible internal) */
-#define XXGOK 86 /* GETOK - Ask for YES/NO */
-#define XXTEL 87 /* TELNET */
-#define XXASX 88 /* _ASSIGN (evaluates var name) */
-#define XXDFX 89 /* _DEFINE (evaluates var name) */
-#define XXPNG 90 /* PING (for TCP/IP) */
-#define XXINT 91 /* INTRODUCTION */
-#define XXCHK 92 /* CHECK (a feature) */
-#define XXMSL 93 /* MSLEEP, MPAUSE (millisecond sleep) */
-#define XXNEW 94 /* NEWS */
-#define XXAPC 95 /* APC */
-#define XXFUN 96 /* REDIRECT */
-#define XXWRL 97 /* WRITE-LINE */
-#define XXREXX 98 /* Rexx */
-#define XXMINP 100 /* MINPUT */
-#define XXRSEN 101 /* RESEND */
-#define XXPSEN 102 /* PSEND */
-#define XXGETC 103 /* GETC */
-#define XXEVAL 104 /* EVALUATE */
-#define XXFWD 105 /* FORWARD */
-#define XXUPD 106 /* UPDATES */
-#define XXBEEP 107 /* BEEP */
-#define XXMOVE 108 /* MOVE */
-#define XXMMOVE 109 /* MMOVE */
-#define XXREGET 110 /* REGET */
-#define XXLOOK 111 /* LOOKUP */
-#define XXVIEW 112 /* VIEW (terminal buffer) */
-#define XXANSW 113 /* ANSWER (the phone) */
-#define XXPDIA 114 /* PDIAL (partial dial) */
-#define XXASC 115 /* ASCII / TEXT */
-#define XXBIN 116 /* BINARY */
-#define XXFTP 117 /* FTP */
-#define XXMKDIR 118 /* MKDIR */
-#define XXRMDIR 119 /* RMDIR */
-#define XXTELOP 120 /* TELOPT */
-#define XXRLOG 121 /* RLOGIN */
-#define XXUNDEF 122 /* UNDEFINE */
-#define XXNPSH 123 /* NOPUSH */
-#define XXADD 124 /* ADD */
-#define ADD_SND 0 /* ADD SEND-LIST */
-#define ADD_BIN 1 /* ADD BINARY-PATTERNS */
-#define ADD_TXT 2 /* ADD TEXT-PATTERNS */
-#define XXLOCAL 125 /* LOCAL */
-#define XXKERMI 126 /* KERMIT */
-#define XXDATE 127 /* DATE */
-#define XXSWIT 128 /* SWITCH */
-#define XXXFWD 129 /* _FORWARD */
-#define XXSAVE 130 /* SAVE */
-#define XXXECH 131 /* XECHO */
-#define XXRDBL 132 /* READBLOCK */
-#define XXWRBL 133 /* WRITEBLOCK */
-#define XXRETR 134 /* RETRIEVE */
-#define XXEIGHT 135 /* EIGHTBIT */
-#define XXEDIT 136 /* EDIT */
-#define XXCSEN 137 /* CSEND */
-#define XXCREC 138 /* CRECEIVE */
-#define XXCQ 139 /* CQ */
-#define XXTAPI 140 /* TAPI actions such as dialogs */
-#define XXRES 141 /* RESET */
-#define XXCGET 142 /* CGET */
-#define XXFUNC 143 /* Function (help-only) */
-#define XXKVRB 144 /* Kverb (help-only) */
-#define XXBROWS 145 /* BROWSE */
-#define XXMGET 146 /* MGET */
-#define XXBACK 147 /* BACK */
-#define XXWHERE 148 /* WHERE */
-#define XXREDO 149 /* REDO */
-#define XXEXCH 150 /* EXCHANGE */
-#define XXREMV 151 /* REMOVE */
-#define XXCHRT 152 /* CHROOT */
-#define XXOPTS 153 /* Options (help-only) */
-#define XXAUTH 154 /* AUTHORIZE */
-#define XXPIPE 155 /* PIPE */
-#define XXSSH 156 /* SSH */
-#define XXTERM 157 /* TERMINAL */
-#define XXSTATUS 158 /* STATUS */
-#define XXCPR 159 /* COPYRIGHT */
-#define XXASSER 160 /* ASSERT */
-#define XXSUCC 161 /* SUCCEED */
-#define XXFAIL 162 /* FAIL */
-#define XXLOGIN 163 /* LOGIN */
-#define XXLOGOUT 164 /* LOGOUT */
-#define XXNLCL 165 /* NOLOCAL */
-#define XXWILD 166 /* WILDCARDS (help-only) */
-
-/* One-word synonyms for REMOTE commands */
-
-#define XXRCPY 167 /* REMOTE COPY */
-#define XXRCWD 168 /* Change Working Directory */
-#define XXRDEL 169 /* Delete */
-#define XXRDIR 170 /* Directory */
-#define XXRHLP 171 /* Help */
-#define XXRHOS 172 /* Host */
-#define XXRKER 173 /* Kermit */
-#define XXRMSG 174 /* Message */
-#define XXRPRI 175 /* Print */
-#define XXRREN 176 /* Rename */
-#define XXRSET 177 /* Set */
-#define XXRSPA 178 /* Space */
-#define XXRSUB 179 /* Submit */
-#define XXRTYP 180 /* Type */
-#define XXRWHO 181 /* Who */
-#define XXRPWD 182 /* Print Working Directory */
-#define XXRQUE 183 /* Query */
-#define XXRASG 184 /* Assign */
-#define XXRMKD 185 /* mkdir */
-#define XXRRMD 186 /* rmdir */
-#define XXRXIT 187 /* Exit */
-
-/* Top-Level commands, cont'd... */
-
-#define XXGETK 188 /* GETKEYCODE */
-#define XXMORE 189 /* MORE */
-#define XXXOPTS 190 /* Extended-Options (help-only) */
-#define XXIKSD 191 /* IKSD */
-#define XXRESET 192 /* RESET */
-#define XXASSOC 193 /* ASSOCIATE */
-
-#define ASSOC_FC 0 /* ASSOCIATE FILE-CHARACTER-SET */
-#define ASSOC_TC 1 /* ASSOCIATE TRANSFER-CHARACTER-SET */
-
-#define XXSHIFT 194 /* SHIFT */
-#define XXMAN 195 /* MANUAL */
-#define XXLS 196 /* LS */
-#define XXSORT 197 /* SORT */
-#define XXPURGE 198 /* PURGE */
-#define XXFAST 199 /* FAST */
-#define XXCAU 200 /* CAUTIOUS */
-#define XXROB 201 /* ROBUST */
-#define XXMACRO 202 /* Immediate macro */
-#define XXSCRN 203 /* SCREEN */
-#define XXLNOUT 204 /* LINEOUT */
-#define XX_INCR 205 /* _INCREMENT */
-#define XX_DECR 206 /* _DECREMENT */
-#define XX_EVAL 207 /* _EVALUATE */
-#define XXARRAY 208 /* ARRAY */
-#define XXPARSE 209 /* PARSE */
-#define XXHTTP 210 /* HTTP */
-
-#ifdef CKCHANNELIO
-#define XXFILE 211 /* FILE */
-#define XXF_CL 212 /* FCLOSE */
-#define XXF_FL 213 /* FFLUSH */
-#define XXF_LI 214 /* FLIST */
-#define XXF_OP 215 /* FOPEN */
-#define XXF_RE 216 /* FREAD */
-#define XXF_SE 217 /* FSEEK */
-#define XXF_ST 218 /* FSTATUS */
-#define XXF_WR 219 /* FWRITE */
-#define XXF_RW 220 /* FREWIND */
-#define XXF_CO 221 /* FCOUNT */
-#endif /* CKCHANNELIO */
-
-#define XXEXEC 222 /* exec() */
-#define XXTRACE 223 /* TRACE */
-#define XXNOTAV 224 /* The "not available" command */
-#define XXPTY 225 /* PTY (like PIPE) */
-#define XXCHMOD 226 /* CHMOD */
-#define XXPROMP 227 /* PROMPT */
-#define XXFEACH 228 /* FOREACH */
-#define XXGREP 229 /* GREP */
-#define XXSEXP 230 /* S-Expression */
-#define XXUNDCL 231 /* UNDECLARE */
-#define XXVOID 232 /* VOID */
-#define XXPUT 233 /* PUT */
-#define XXUNDFX 234 /* _UNDEFINE */
-#define XXHEAD 235 /* HEAD */
-#define XXTAIL 236 /* TAIL */
-#define XXDEBUG 237 /* DEBUG */
-#define XXLEARN 238 /* LEARN */
-#define XXPAT 239 /* PATTERNS (help only) */
-
-#define XXCDUP 240 /* CDUP (Change working directory upwards) */
-#define XXRCDUP 241 /* REMOTE CDUP */
-#define XXCAT 242 /* CAT (= TYPE /NOPAGE) */
-#define XXFIREW 243 /* FIREWALL (help only) */
-
-#define XXLCWD 244 /* Local C(W)D */
-#define XXLCDU 245 /* Local CDUP */
-#define XXLPWD 246 /* Local PWD */
-#define XXLDEL 247 /* Local DELETE */
-#define XXLDIR 248 /* Local DIRECTORY */
-#define XXLREN 249 /* Local RENAME */
-#define XXLMKD 250 /* Local MKDIR */
-#define XXLRMD 251 /* Local RMDIR */
-#define XXUSER 252 /* (FTP) USER */
-#define XXACCT 253 /* (FTP) ACCOUNT */
-#define XXLINK 254 /* LINK source destination */
-#define XXORIE 255 /* ORIENT(ATION) */
-#define XXDIALER 256 /* DIALER */
-#define XXKCD 257 /* KCD */
-#define XXSITE 258 /* (FTP) SITE */
-#define XXPASV 259 /* (FTP) PASSIVE */
-#define XXCONT 260 /* CONTINUE */
-#define XXNSCR 261 /* NOSCROLL */
-#define XXSFTP 262 /* SFTP */
-#define XXSKRM 263 /* SKERMIT */
-
-/* End of Top-Level Commands */
-
-#define SCN_CLR 0 /* SCREEN CLEAR */
-#define SCN_CLE 1 /* SCREEN CLEOL */
-#define SCN_MOV 2 /* SCREEN MOVE */
-
-/* ARRAY operations */
-
-#define ARR_DCL 0 /* Declare */
-#define ARR_CPY 1 /* Copy */
-#define ARR_RSZ 2 /* Resize */
-#define ARR_SRT 3 /* Sort */
-#define ARR_CLR 4 /* Clear */
-#define ARR_SEA 5 /* Search */
-#define ARR_DST 6 /* Destroy */
-#define ARR_SHO 7 /* Show */
-#define ARR_SET 8 /* Set */
-#define ARR_EQU 9 /* Equate */
-
-/* SORT options */
-
-#define SRT_CAS 0 /* /CASE */
-#define SRT_KEY 1 /* /KEY:n */
-#define SRT_REV 2 /* /REVERSE */
-#define SRT_RNG 3 /* /RANGE:n:m */
-#define SRT_NUM 4 /* /NUMERIC */
-
-/* PURGE command options */
-
-#define PU_KEEP 0 /* /KEEP: */
-#define PU_LIST 1 /* /LIST */
-#define PU_PAGE 2 /* /PAGE */
-#define PU_NOPA 3 /* /NOPAGE */
-#define PU_NODE 4 /* /SIMULATE */
-#define PU_DELE 5 /* /DELETE */
-#define PU_NOLI 6 /* /NOLIST */
-#define PU_QUIE 7 /* /QUIET (= NOLIST) */
-#define PU_VERB 8 /* /VERBOSE (= LIST) */
-#define PU_ASK 9 /* /ASK */
-#define PU_NASK 10 /* /NOASK */
-#define PU_LAR 11 /* /LARGER-THAN: */
-#define PU_SMA 12 /* /SMALLER-THAN: */
-#define PU_AFT 13 /* /AFTER: */
-#define PU_NAF 14 /* /NOT-AFTER: */
-#define PU_BEF 15 /* /BEFORE: */
-#define PU_NBF 16 /* /NOT-BEFORE: */
-#define PU_EXC 17 /* /EXCEPT: */
-#define PU_RECU 18 /* /RECURSIVE */
-#define PU_DOT 19 /* /DOTFILES */
-#define PU_NODOT 20 /* /NODOTFILES */
-#define PU_HDG 21 /* /HEADING */
-#define PU_NOH 22 /* /NOHEADING */
-
-/* DELETE command options */
-
-#define DEL_NOL 0 /* /NOLIST */
-#define DEL_LIS 1 /* /LIST */
-#define DEL_HDG 2 /* /HEADINGS */
-#define DEL_NOH 2 /* /NOHEADINGS */
-#define DEL_BEF 3 /* /BEFORE: */
-#define DEL_NBF 4 /* /NOT-BEFORE: */
-#define DEL_AFT 5 /* /AFTER: */
-#define DEL_NAF 6 /* /NOT-AFTER: */
-#define DEL_DOT 7 /* /DOTFILES */
-#define DEL_NOD 8 /* /NODOTFILES */
-#define DEL_EXC 9 /* /EXCEPT:*/
-#define DEL_PAG 10 /* /PAGE */
-#define DEL_NOP 11 /* /NOPAGE */
-#define DEL_REC 12 /* /RECURSIVE */
-#define DEL_NOR 13 /* /NORECURSIVE */
-#define DEL_VRB 14 /* /VERBOSE */
-#define DEL_QUI 15 /* /QUIET */
-#define DEL_SMA 16 /* /SMALLER-THAN: */
-#define DEL_LAR 17 /* /LARGER-THAN: */
-#define DEL_SIM 18 /* /SIMULATE */
-#define DEL_ASK 19 /* /ASK */
-#define DEL_NAS 20 /* /NOASK */
-#define DEL_SUM 21 /* /SUMMARY */
-#define DEL_DIR 22 /* /DIRECTORY */
-#define DEL_ALL 23 /* /ALL */
-#define DEL_TYP 24 /* /TYPE: */
-#define DEL_LNK 25 /* /FOLLOWLINKS */
-#define DEL_NLK 26 /* /NOFOLLOWLINKS */
-
-/* FILE operations */
-
-#define FIL_OPN 0 /* OPEN */
-#define FIL_CLS 1 /* CLOSE */
-#define FIL_REA 2 /* READ */
-#define FIL_GET 3 /* GET */
-#define FIL_WRI 4 /* WRITE */
-#define FIL_REW 5 /* REWIND */
-#define FIL_LIS 6 /* LIST */
-#define FIL_FLU 7 /* FLUSH */
-#define FIL_SEE 8 /* SEEK */
-#define FIL_STA 9 /* STATUS */
-#define FIL_COU 10 /* COUNT */
-
-/* OPEN / CLOSE items */
-
-#define OPN_FI_R 1 /* FILE READ */
-#define OPN_FI_W 2 /* FILE WRITE */
-#define OPN_FI_A 3 /* FILE APPEND */
-#define OPN_PI_R 4 /* PIPE READ */
-#define OPN_PI_W 5 /* PIPE WRITE */
-#define OPN_PT_R 6 /* PTY READ */
-#define OPN_PT_W 7 /* PTY WRITE */
-#define OPN_SER 8 /* PORT or LINE */
-#define OPN_NET 9 /* HOST */
-
-/* KERBEROS command switches */
-
-#define KRB_S_VE 0 /* /VERSION */
-#define KRB_S_CA 1 /* /CACHE: */
-#define KRB_S_MAX 1 /* Highest KERBEROS switch number */
-
-#ifdef CK_KERBEROS
-
-/* KERBEROS actions */
-
-#define KRB_A_IN 0 /* INITIALIZE */
-#define KRB_A_DE 1 /* DESTROY */
-#define KRB_A_LC 2 /* LIST-CREDENTIALS */
-
-/* KERBEROS INIT switches */
-
-#define KRB_I_FW 0 /* /FORWARDABLE */
-#define KRB_I_LF 1 /* /LIFETIME: */
-#define KRB_I_PD 2 /* /POSTDATE: */
-#define KRB_I_PR 3 /* /PROXIABLE */
-#define KRB_I_RB 4 /* /RENEWABLE: */
-#define KRB_I_RN 5 /* /RENEW */
-#define KRB_I_SR 6 /* /SERVICE: */
-#define KRB_I_VA 7 /* /VALIDATE */
-#define KRB_I_RL 8 /* /REALM: */
-#define KRB_I_IN 9 /* /INSTANCE: */
-#define KRB_I_PW 10 /* /PASSWORD: */
-#define KRB_I_PA 11 /* /PREAUTH */
-#define KRB_I_VB 12 /* /VERBOSE */
-#define KRB_I_BR 13 /* /BRIEF */
-#define KRB_I_NFW 14 /* /NOT-FORWARDABLE */
-#define KRB_I_NPR 15 /* /NOT-PROXIABLE */
-#define KRB_I_NPA 16 /* /NOT-PREAUTH */
-#define KRB_I_K4 17 /* /KERBEROS4 (should k5 get k4 as well) */
-#define KRB_I_NK4 18 /* /NO-KERBEROS4 */
-#define KRB_I_POP 19 /* /POPUP */
-#define KRB_I_ADR 20 /* /ADDRESSES: */
-#define KRB_I_NAD 21 /* /NO-ADDRESSES */
-#define KRB_I_MAX 21 /* Highest KERBEROS INIT switch number */
-
-#endif /* CK_KERBEROS */
-
-/* SET parameters */
-
-#define XYBREA 0 /* BREAK simulation */
-#define XYCHKT 1 /* Block check type */
-#define XYDEBU 2 /* Debugging */
-#define XYDELA 3 /* Delay */
-#define XYDUPL 4 /* Duplex */
-#define XYEOL 5 /* End-Of-Line (packet terminator) */
-#define XYESC 6 /* Escape character */
-#define XYFILE 7 /* File Parameters (see ckcker.h for values) */
- /* (this space available) */
-#define XYFLOW 9 /* Flow Control */
-#define XYHAND 10 /* Handshake */
-#define XYIFD 11 /* Incomplete File Disposition */
-#define XYIMAG 12 /* "Image Mode" */
-#define XYINPU 13 /* INPUT command parameters */
-#define XYLEN 14 /* Maximum packet length to send */
-#define XYLINE 15 /* Communication line to use */
-
-/* SET LINE / SET HOST command switches */
-
-#define SL_CNX 0 /* /CONNECT */
-#define SL_SRV 1 /* /SERVER */
-#define SL_SHR 2 /* /SHARE */
-#define SL_NSH 3 /* /NOSHARE */
-#define SL_BEE 4 /* /BEEP */
-#define SL_ANS 5 /* /ANSWER */
-#define SL_DIA 6 /* /DIAL:xxx */
-#define SL_SPD 7 /* /SPEED:xxx */
-#define SL_FLO 8 /* /FLOW:xxx */
-#define SL_TMO 9 /* /TIMEOUT:xxx */
-#define SL_CMD 10 /* /COMMAND */
-#define SL_PSW 11 /* /PASSWORD:xxx */
-#define SL_IKS 12 /* /KERMIT-SERVICE */
-#define SL_NET 13 /* /NETWORK-TYPE:xxx */
-#define SL_ENC 14 /* /ENCRYPT:type (telnet) /ENCRYPT (rlogin) */
-#define SL_KRB4 15 /* /KERBEROS 4 (rlogin/telnet) */
-#define SL_KRB5 16 /* /KERBEROS 5 (rlogin/telnet) */
-#define SL_SRP 17 /* /SRP (telnet) */
-#define SL_NTLM 18 /* /NTLM (telnet) */
-#define SL_SSL 19 /* /SSL (telnet) */
-#define SL_UID 20 /* /USERID:xxxx */
-#define SL_AUTH 21 /* /AUTH:type */
-#define SL_WAIT 22 /* /WAIT */
-#define SL_NOWAIT 23 /* /NOWAIT */
-#define SL_PTY 24 /* /PTY */
-
-#define XYLOG 16 /* Log file */
-#define XYMARK 17 /* Start of Packet mark */
-#define XYNPAD 18 /* Amount of padding */
-#define XYPADC 19 /* Pad character */
-#define XYPARI 20 /* Parity */
-#define XYPAUS 21 /* Interpacket pause */
-#define XYPROM 22 /* Program prompt string */
-#define XYQBIN 23 /* 8th-bit prefix */
-#define XYQCTL 24 /* Control character prefix */
-#define XYREPT 25 /* Repeat count prefix */
-#define XYRETR 26 /* Retry limit */
-#define XYSPEE 27 /* Line speed (baud rate) */
-#define XYTACH 28 /* Character to be doubled */
-#define XYTIMO 29 /* Timeout interval */
-#define XYMODM 30 /* Modem - also see XYDIAL */
-
-#define XYSEND 31 /* SET SEND parameters */
-#define XYRECV 32 /* SET RECEIVE parameters */
-#define XYTERM 33 /* SET TERMINAL parameters */
-#define XYTBYT 0 /* Terminal Bytesize (7 or 8) */
-#define XYTTYP 1 /* Terminal emulation Type */
-#define TT_NONE 0 /* NONE, no emulation */
-#ifdef OS2
-/*
- Note, the symbols for VT and VT-like terminals should be in ascending
- numerical order, so that higher ones can be treated as supersets of
- lower ones with respect to capabilities.
-
- This is no longer the case with the influx of new terminal types.
- Just make sure that the ISXXXXX() macros include the proper family
- groups.
-*/
-#define TT_DG200 1 /* Data General 200 */
-#define TT_DG210 2 /* Data General 210 */
-#define TT_DG217 3 /* Data General 217 */
-#define TT_HP2621 4 /* Hewlett-Packard 2621A */
-#define TT_HPTERM 5 /* Hewlett-Packard Console */
-#define TT_HZL1500 6 /* Hazeltine 1500 */
-#define TT_VC4404 7 /* Volker Craig VC4404/404 */
-#define TT_WY30 8 /* WYSE-30/30+ */
-#define TT_WY50 9 /* WYSE-50/50+ */
-#define TT_WY60 10 /* WYSE-60 */
-#define TT_WY160 11 /* WYSE-160 */
-#define TT_QNX 12 /* QNX */
-#define TT_QANSI 13 /* QNX Ansi emulation */
-#define TT_VT52 14 /* DEC VT-52 */
-#define TT_H19 15 /* Heath-19 */
-#define TT_IBM31 16 /* IBM 31xx */
-#define TT_SCOANSI 17 /* SCOANSI (Unix mode) */
-#define TT_AT386 18 /* Unixware AT386 (Unix mode) */
-#define TT_ANSI 19 /* IBM ANSI.SYS (BBS) */
-#define TT_VIP7809 20 /* Honeywell VIP7809 */
-#define TT_LINUX 21 /* Linux Console */
-#define TT_HFT 22 /* IBM High Function Terminal */
-#define TT_AIXTERM 23 /* IBM AIXterm */
-#define TT_SUN 24 /* SUN Console */
-#define TT_BA80 25 /* Nixdorf BA80 */
-#define TT_BEOS 26 /* BeOS Ansi */
-#define TT_VT100 27 /* DEC VT-100 */
-#define TT_VT102 28 /* DEC VT-102 */
-#define TT_VT220 29 /* DEC VT-220 */
-#define TT_VT220PC 30 /* DEC VT-220 with PC keyboard */
-#define TT_VT320 31 /* DEC VT-320 */
-#define TT_VT320PC 32 /* DEC VT-320 with PC keyboard */
-#define TT_WY370 33 /* WYSE 370 ANSI Terminal */
-#define TT_97801 34 /* Sinix 97801-5xx terminal */
-#define TT_AAA 35 /* Ann Arbor Ambassador */
-#define TT_TVI910 36 /* TVI 910+ */
-#define TT_TVI925 37 /* TVI 925 */
-#define TT_TVI950 38 /* TVI950 */
-#define TT_ADM3A 39 /* LSI ADM 3A */
-#define TT_ADM5 40 /* LSI ADM 5 */
-#define TT_VTNT 41 /* Microsoft NT Virtual Terminal */
-#define TT_MAX TT_VTNT
-#define TT_VT420 96 /* DEC VT-420 */
-#define TT_VT520 97 /* DEC VT-520/525 */
-#define TT_TEK40 99 /* Tektronix 401x */
-#define TT_KBM_EMACS TT_MAX+1
-#define TT_KBM_HEBREW TT_MAX+2
-#define TT_KBM_RUSSIAN TT_MAX+3
-#define TT_KBM_WP TT_MAX+4
-
-#define ISAAA(x) (x == TT_AAA)
-#define ISANSI(x) (x >= TT_SCOANSI && x <= TT_ANSI)
-#define ISBA80(x) (x == TT_BA80)
-#define ISBEOS(x) (x == TT_BEOS)
-#define ISQNX(x) (x == TT_QNX)
-#define ISQANSI(x) (x == TT_QANSI)
-#define ISLINUX(x) (x == TT_LINUX)
-#define ISSCO(x) (x == TT_SCOANSI)
-#define ISAT386(x) (x == TT_AT386)
-#define ISAVATAR(x) (x == TT_ANSI)
-#define ISSUN(x) (x == TT_SUN)
-#define ISUNIXCON(x) (x == TT_SCOANSI || x == TT_AT386 || \
- x == TT_LINUX || x == TT_SUN)
-#define ISDG200(x) (x >= TT_DG200 && x <= TT_DG217)
-#define ISHZL(x) (x == TT_HZL1500)
-#define ISH19(x) (x == TT_H19)
-#define ISIBM31(x) (x == TT_IBM31)
-#define ISTVI(x) (x >= TT_TVI910 && x <= TT_TVI950)
-#define ISTVI910(x) (x == TT_TVI910)
-#define ISTVI925(x) (x == TT_TVI925)
-#define ISTVI950(x) (x == TT_TVI950)
-#define ISVT52(x) (x == TT_VT52 || x == TT_H19)
-#ifdef COMMENT
-#define ISVT520(x) (x == TT_VT520)
-#define ISVT420(x) (x >= TT_VT420 && x <= TT_VT520)
-#else /* COMMENT */
-/* Since we do not yet support 420/520 extend 320 */
-#define ISVT520(x) (ISVT320(x))
-#define ISVT420(x) (ISVT320(x))
-#endif /* COMMENT */
-#define ISVT320(x) (x >= TT_VT320 && x <= TT_AAA)
-#define ISVT220(x) (x >= TT_VT220 && x <= TT_AAA || \
- ISBEOS(x) || ISQANSI(x) || \
- ISLINUX(x) || ISSUN(x))
-#define ISVT102(x) (x >= TT_VIP7809 && x <= TT_BA80 || \
- x == TT_VT102 || ISVT220(x))
-#define ISVT100(x) (x == TT_VT100 || ISVT102(x))
-#define ISWY30(x) (x == TT_WY30)
-#define ISWYSE(x) (x >= TT_WY30 && x <= TT_WY160)
-#define ISWY50(x) (x == TT_WY50)
-#define ISWY60(x) (x == TT_WY60 || x == TT_WY160)
-#define ISWY160(x) (x == TT_WY160)
-#define ISWY370(x) (x == TT_WY370)
-#define ISVC(x) (x == TT_VC4404)
-#define ISHP(x) (x == TT_HPTERM || x == TT_HP2621)
-#define ISHPTERM(x) (x == TT_HPTERM)
-#define ISVIP(x) (x == TT_VIP7809)
-#define IS97801(x) (x == TT_97801)
-#define ISHFT(x) (x == TT_HFT || x == TT_AIXTERM)
-#define ISAIXTERM(x) (x == TT_AIXTERM)
-#define ISTEK(x) (x == TT_TEK40)
-#define ISVTNT(x) (x == TT_VTNT)
-#define ISADM3A(x) (x == TT_ADM3A)
-#define ISADM5(x) (x == TT_ADM5)
-#endif /* OS2 */
-
-#define XYTCS 2 /* Terminal Character Set */
-#define XYTSO 3 /* Terminal Shift-In/Shift-Out */
-#define XYTNL 4 /* Terminal newline mode */
-#ifdef OS2
-#define XYTCOL 5 /* Terminal colors */
-#endif /* OS2 */
-#define XYTEC 6 /* Terminal echo = duplex = local-echo */
-#ifdef OS2
-#define XYTCUR 7 /* Terminal cursor */
-#define TTC_ULINE 0
-#define TTC_HALF 1
-#define TTC_BLOCK 2
-#define XYTARR 8 /* Terminal arrow-key mode */
-#define XYTKPD 9 /* Terminal keypad mode */
-#define TTK_NORM 0 /* Normal mode for arrow / keyad keys */
-#define TTK_APPL 1 /* Application mode for arrow / keyad keys */
-#define XYTWRP 10 /* Terminal wrap */
-#endif /* OS2 */
-#define XYTCRD 11 /* Terminal CR-display */
-#define XYTANS 12 /* Terminal answerback */
-#ifdef OS2
-#define XYSCRS 13 /* Terminal scrollback buffer size */
-#endif /* OS2 */
-#define XYTAPC 14 /* Terminal APC */
-#ifdef OS2
-#define XYTBEL 15 /* Terminal Bell */
-#endif /* OS2 */
-#define XYTDEB 16 /* Terminal Debug */
-#ifdef OS2
-#define XYTROL 17 /* Terminal Rollback */
-#define TTR_OVER 0 /* Rollback Overwrite */
-#define TTR_INSERT 1 /* Rollback Insert */
-#define TTR_KEYS 2 /* Keystrokes */
-#define TTRK_IGN 0 /* Ignore */
-#define TTRK_RST 2 /* Restore and Send */
-#define TTRK_SND 1 /* Send */
-#define XYTCTS 18 /* Terminal Transmit-Timeout */
-#define XYTCPG 19 /* Terminal Code Page */
-#ifdef COMMENT
-#define XYTHCU 20 /* Terminal Hide-Cursor */
-#endif /* COMMENT */
-#define XYTPAC 21 /* Terminal Output-Pacing */
-#define XYTMOU 22 /* Terminal Mouse */
-#endif /* OS2 */
-#define XYTHIG 23 /* Terminal Width */
-#define XYTWID 24 /* Terminal Height */
-#ifdef OS2
-#define XYTUPD 25 /* Terminal Screen-update */
-#define TTU_FAST 0 /* FAST but jerky */
-#define TTU_SMOOTH 1 /* SMOOTH but slow */
-#define XYTFON 26 /* Terminal Full screen Font */
-#define TTF_ROM 0 /* ROM font */
-#define TTF_CY1 1 /* CYRILL1 font */
-#define TTF_CY2 2 /* CYRILL2 font */
-#define TTF_CY3 3 /* CYRILL3 font */
-#define TTF_111 111 /* CP111 font */
-#define TTF_112 112 /* CP112 font */
-#define TTF_113 113 /* CP113 font */
-#define TTF_437 437 /* CP437 font */
-#define TTF_850 850 /* CP850 font */
-#define TTF_851 851 /* CP851 font */
-#define TTF_852 852 /* CP852 font */
-#define TTF_853 853 /* CP853 font */
-#define TTF_860 860 /* CP860 font */
-#define TTF_861 861 /* CP861 font */
-#define TTF_862 862 /* CP862 font */
-#define TTF_863 863 /* CP863 font */
-#define TTF_864 864 /* CP864 font */
-#define TTF_865 865 /* CP865 font */
-#define TTF_866 866 /* CP866 font */
-#define TTF_880 880 /* CP880 font */
-#define TTF_881 881 /* CP881 font */
-#define TTF_882 882 /* CP882 font */
-#define TTF_883 883 /* CP883 font */
-#define TTF_884 884 /* CP884 font */
-#define TTF_885 885 /* CP885 font */
-#define XYTVCH 27 /* SET TERMINAL VIDEO-CHANGE */
-#define TVC_DIS 0 /* DISABLED */
-#define TVC_ENA 1 /* ENABLED */
-#define TVC_W95 2 /* WIN95-SAFE */
-#endif /* OS2 */
-#define XYTAUTODL 28 /* SET TERMINAL AUTODOWNLOAD */
-#define TAD_OFF 0 /* OFF */
-#define TAD_ON 1 /* ON */
-#define TAD_K 2 /* KERMIT */
-#define TAD_Z 3 /* ZMODEM */
-#define TAD_X_STR 0 /* STRING */
-#define TAD_X_DETECT 1 /* DETECTION ( PACKET, STRING ) */
-#define TAD_X_C0 2 /* C0 CONFLICTS */
-#define TAD_ERR 4 /* ERROR { STOP, CONTINUE } */
-#define TAD_ASK 5 /* ASK (dialog) */
-#define XYTAUTOUL 29 /* SET TERMINAL AUTOUPLOAD */
-#ifdef OS2
-#define XYTATTBUG 30 /* SET TERM ATTR-BUG */
-#define XYTSTAT 31 /* SET TERM STATUSLINE */
-#endif /* OS2 */
-#define XYTESC 32 /* SET TERM ESCAPE-CHARACTER */
-#define XYTCTRL 33 /* SET TERM CONTROLS */
-#ifdef OS2
-#define XYTATTR 34 /* SET TERM ATTRIBUTE representation */
-#define XYTSGRC 35 /* SET TERM SGRCOLORS */
-#endif /* OS2 */
-#define XYTLCS 36 /* SET TERM LOCAL-CHARACTER-SET */
-#define XYTRCS 37 /* SET TERM REMOTE-CHARACTER-SET */
-#define XYTUNI 38 /* SET TERM UNICODE */
-#define XYTKEY 39 /* SET TERM KEY */
-#ifdef OS2
-#define XYTSEND 40 /* SET TERM SEND-DATA */
-#define XYTSEOB 41 /* SET TERM SEND-END-OF-BLOCK */
-#define XYTMBEL 42 /* SET TERM MARGIN-BELL */
-#endif /* OS2 */
-#define XYTIDLE 43 /* SET TERM IDLE-SEND */
-#ifdef OS2
-#define XYTKBMOD 44 /* SET TERM KEYBOARD-MODE */
-#define XYTUNX 45 /* SET TERM UNIX-MODE (DG) */
-#define XYTASCRL 46 /* SET TERM AUTOSCROLL */
-#define XYTAPAGE 47 /* SET TERM AUTOPAGE */
-#endif /* OS2 */
-#define XYTRIGGER 48 /* SET TERM TRIGGER */
-#ifdef OS2
-#define XYTPCTERM 49 /* SET TERM PCTERM */
-#define XYTOPTI 50 /* SET TERM SCREEN-OPTIMIZE */
-#define XYTSCNM 51 /* SET TERM SCREEN-MODE (DECSCNM) */
-#endif /* OS2 */
-#define XYTPRN 52 /* SET TERM PRINT {AUTO, COPY, OFF} */
-#ifdef OS2
-#define XYTSAC 53 /* SET TERM SPACING-ATTRIBUTE-CHARACTER (inv) */
-#define XYTSNIPM 54 /* SET TERM SNI-AUTOROLL */
-#define XYTSNISM 55 /* SET TERM SNI-SCROLLMODE */
-#define XYTKBDGL 56 /* SET TERM KBD-FOLLOWS-GL/GR */
-#define XYTVTLNG 57 /* SET TERM VT-LANGUAGE */
-#define VTL_NORTH_AM 1
-#define VTL_BRITISH 2
-#define VTL_BELGIAN 3
-#define VTL_FR_CAN 4
-#define VTL_DANISH 5
-#define VTL_FINNISH 6
-#define VTL_GERMAN 7
-#define VTL_DUTCH 8
-#define VTL_ITALIAN 9
-#define VTL_SW_FR 10
-#define VTL_SW_GR 11
-#define VTL_SWEDISH 12
-#define VTL_NORWEGIA 13
-#define VTL_FRENCH 14
-#define VTL_SPANISH 15
-#define VTL_PORTUGES 16
-#define VTL_HEBREW 19
-#define VTL_GREEK 22
-#define VTL_CANADIAN 28
-#define VTL_TURK_Q 29
-#define VTL_TURK_F 30
-#define VTL_HUNGARIA 31
-#define VTL_SLOVAK 33
-#define VTL_CZECH 34
-#define VTL_POLISH 35
-#define VTL_ROMANIAN 36
-#define VTL_SCS 38
-#define VTL_RUSSIAN 39
-#define VTL_LATIN_AM 40
-#define XYTVTNRC 58 /* SET TERM VT-NRC-MODE */
-#define XYTSNICC 59 /* SET TERM SNI-CH.CODE */
-#define XYTSNIFV 60 /* SET TERM SNI-FIRMWARE-VERSIONS */
-#define XYTURLHI 61 /* SET TERM URL-HIGHLIGHT */
-#endif /* OS2 */
-#define XYTITMO 62 /* SET TERM IDLE-TIMEOUT */
-#define XYTIACT 63 /* SET TERM IDLE-ACTION */
-#define XYTLSP 64 /* SET TERM LINE-SPACING */
-
-#define XYATTR 34 /* Attribute packets */
-#define XYSERV 35 /* Server parameters */
-#define XYSERT 0 /* Server timeout */
-#define XYSERD 1 /* Server display */
-#define XYSERI 2 /* Server idle */
-#define XYSERP 3 /* Server get-path */
-#define XYSERL 4 /* Server login */
-#define XYSERC 5 /* Server CD-Message */
-#define XYSERK 6 /* Server keepalive */
-#define XYWIND 36 /* Window size */
-#define XYXFER 37 /* Transfer */
-#define XYX_CAN 0 /* Cancellation */
-#define XYX_CSE 1 /* Character-Set */
-#define XYX_LSH 2 /* Locking-Shift */
-#define XYX_PRO 3 /* Protocol */
-#define XYX_MOD 4 /* Mode */
-#define XYX_DIS 5 /* Display */
-#define XYX_SLO 6 /* Slow-start */
-#define XYX_CRC 7 /* CRC calculation */
-#define XYX_BEL 8 /* Bell */
-#define XYX_PIP 9 /* Pipes */
-#define XYX_INT 10 /* Interruption */
-#define XYX_XLA 11 /* (character-set) Translation On/Off */
-#define XYX_MSG 12 /* Message */
-#define XYX_RPT 13 /* Report */
-#define XYLANG 38 /* Language */
-#define XYCOUN 39 /* Count */
-#define XYTAKE 40 /* Take */
-#define XYUNCS 41 /* Unknown-character-set */
-#define XYKEY 42 /* Key */
-#define XYMACR 43 /* Macro */
-#define XYHOST 44 /* Hostname on network */
-#define XYNET 45 /* SET NETWORK things */
-
-#define XYNET_D 99 /* NETWORK DIRECTORY */
-#define XYNET_T 100 /* NETWORK TYPE */
-
-#define XYCARR 46 /* Carrier */
-#define XYXMIT 47 /* Transmit */
-
-#define XYDIAL 48 /* Dial options */
-
-/* And now we interrupt the flow to bring you lots of stuff about dialing */
-
-#ifndef MAXTOLLFREE /* Maximum number of toll-free area codes */
-#define MAXTOLLFREE 8
-#endif /* MAXTOLLFREE */
-
-#ifndef MAXTPCC /* Maximum Tone or Pulse dialing countries */
-#define MAXTPCC 160
-#endif /* MAXTPCC */
-
-#ifndef MAXPBXEXCH /* Maximum number of PBX exchanges */
-#define MAXPBXEXCH 8
-#endif /* MAXPBXEXCH */
-
-#ifndef MAXLOCALAC
-#define MAXLOCALAC 32
-#endif /* MAXLOCALAC */
-
-#ifndef MAXDNUMS
-#ifdef BIGBUFOK
-#define MAXDDIR 32 /* Maximum number of dialing directories */
-#define MAXDNUMS 4095 /* Max numbers to fetch from dialing directories */
-#else
-#define MAXDDIR 12
-#define MAXDNUMS 1024
-#endif /* BIGBUFOK */
-#endif /* MAXDNUMS */
-/*
- IMPORTANT: In 5A(192), the old SET DIAL command was split into two commands:
- SET MODEM (for modem-related parameters) and SET DIAL (for dialing items).
- To preserve the old formats, etc, invisibly we keep one symbol space for
- both commands.
-*/
-#define XYDHUP 0 /* Dial Hangup */
-#define XYDINI 1 /* MODEM (dial) Initialization string */
-#define XYDKSP 2 /* MODEM (dial) Kermit-Spoof */
-#define XYDTMO 3 /* Dial Timeout */
-#define XYDDPY 4 /* Dial Display */
-#define XYDSPD 5 /* Dial Speed matching */
-#define XYDMNP 6 /* MODEM (dial) MNP negotiation enabled (obsolete) */
-#define XYDEC 7 /* MODEM (dial) error correction enabled */
-#define XYDDC 8 /* MODEM (dial) compression enabled */
-#define XYDHCM 9 /* MODEM (dial) hangup-string (moved elsewhere) */
-#define XYDDIR 10 /* Dial directory */
-#define XYDDIA 11 /* MODEM (dial) dial-command */
-#define XYDMHU 12 /* MODEM HANGUP (dial modem-hangup) */
-
-#ifndef DEFMDHUP /* Default MODEM HANGUP-METHOD */
-#define DEFMDMHUP 1 /* 0 = RS232, 1 = modem command */
-#endif /* DEFMDMHUP */
-
-#define XYDNPR 13 /* Dial PREFIX */
-#define XYDSTR 14 /* MODEM COMMAND (dial string) ... */
-
-#define XYDS_DC 0 /* Data compression */
-#define XYDS_EC 1 /* Error correction */
-#define XYDS_HU 2 /* Hangup command */
-#define XYDS_HW 3 /* Hardware flow control */
-#define XYDS_IN 4 /* Init-string */
-#define XYDS_NF 5 /* No flow control */
-#define XYDS_PX 6 /* Prefix (no, this goes in SET DIAL) */
-#define XYDS_SW 7 /* Software flow control */
-#define XYDS_DT 8 /* Tone dialing command */
-#define XYDS_DP 9 /* Pulse dialing command */
-#define XYDS_AN 10 /* Autoanswer */
-#define XYDS_RS 11 /* Reset */
-#define XYDS_MS 12 /* Dial mode string */
-#define XYDS_MP 13 /* Dial mode prompt */
-#define XYDS_SP 14 /* Modem speaker */
-#define XYDS_VO 15 /* Modem speaker volume */
-#define XYDS_ID 16 /* Ignore dialtone */
-#define XYDS_I2 17 /* Init string #2 */
-
-#define XYDM_A 9 /* Method: Auto */
-#define XYDM_D 0 /* Default */
-#define XYDM_T 2 /* Tone */
-#define XYDM_P 3 /* Pulse */
-
-#define XYDFC 15 /* MODEM (dial) flow-control */
-#define XYDMTH 16 /* Dial method */
-#define XYDESC 17 /* MODEM (dial) escape-character */
-#define XYDMAX 18 /* MODEM (dial) maximum interface speed */
-#define XYDCAP 19 /* MODEM (dial) capabilities */
-#define XYDTYP 20 /* MODEM TYPE */
-#define XYDINT 21 /* DIAL retries */
-#define XYDRTM 22 /* DIAL time between retries */
-#define XYDNAM 23 /* MODEM NAME */
-#define XYDLAC 24 /* DIAL (LOCAL-)AREA-CODE */
-#define XYDMCD 25 /* MODEM CARRIER */
-
-#define XYDCNF 26 /* DIAL CONFIRMATION */
-#define XYDCVT 27 /* DIAL CONVERT-DIRECTORY */
-#define XYDIXP 28 /* DIAL INTERNATIONAL-PREFIX */
-#define XYDIXS 29 /* DIAL INTERNATIONAL-SUFFIX */
-#define XYDLCC 30 /* DIAL LOCAL-COUNTRY-CODE */
-#define XYDLDP 31 /* DIAL LONG-DISTANCE-PREFIX */
-#define XYDLDS 32 /* DIAL LONG-DISTANCE-SUFFIX */
-#define XYDPXX 33 /* DIAL PBX-EXCHANGE */
-#define XYDPXI 34 /* DIAL PBX-INTERNAL-PREFIX */
-#define XYDPXO 35 /* DIAL PBX-OUTSIDE-PREFIX */
-#define XYDSFX 36 /* DIAL SUFFIX */
-#define XYDSRT 37 /* DIAL SORT */
-#define XYDTFC 38 /* DIAL TOLL-FREE-AREA-CODE */
-#define XYDTFP 39 /* DIAL TOLL-FREE-PREFIX */
-#define XYDTFS 40 /* DIAL TOLL-FREE-SUFFIX */
-#define XYDCON 41 /* DIAL CONNECT */
-#define XYDRSTR 42 /* DIAL RESTRICT */
-#define XYDRSET 43 /* MODEM RESET */
-#define XYDLCP 44 /* DIAL LOCAL-PREFIX */
-#define XYDLCS 45 /* DIAL LOCAL-SUFFIX */
-#define XYDLLAC 46 /* DIAL LC-AREA-CODES */
-#define XYDFLD 47 /* DIAL FORCE LONG-DISTANCE */
-#define XYDSPK 48 /* MODEM SPEAKER */
-#define XYDVOL 49 /* MODEM VOLUME */
-#define XYDIDT 50 /* IGNORE DIALTONE */
-#define XYDPAC 51 /* PACING */
-#define XYDMAC 52 /* MACRO */
-#define XYDPUCC 53 /* PULSE-COUNTRIES */
-#define XYDTOCC 54 /* TONE-COUNTRIES */
-#define XYDTEST 55 /* TEST */
-
-#define XYA_CID 1 /* SET ANSWER CALLER-ID */
-#define XYA_RNG 2 /* SET ANSWER RINGS */
-
-#define XYSESS 49 /* SET SESSION options */
-#define XYBUF 50 /* Buffer length */
-#define XYBACK 51 /* Background */
-#define XYDFLT 52 /* Default */
-#define XYDBL 53 /* Double */
-#define XYCMD 54 /* COMMAND */
-#define XYCASE 55 /* Case */
-#define XYCOMP 56 /* Compression */
-#define XYX25 57 /* X.25 parameter (ANYX25) */
-#define XYPAD 58 /* X.3 PAD parameter (ANYX25) */
-#define XYWILD 59 /* Wildcard expansion method */
-#define XYSUSP 60 /* Suspend */
-#define XYMAIL 61 /* Mail-Command */
-#define XYPRIN 62 /* Print-Command */
-#define XYQUIE 63 /* Quiet */
-#define XYLCLE 64 /* Local-echo */
-#define XYSCRI 65 /* SCRIPT command paramaters */
-#define XYMSGS 66 /* MESSAGEs ON/OFF */
-#ifdef TNCODE
-#define XYTEL 67 /* SET TELNET parameters */
-#define CK_TN_EC 0 /* TELNET ECHO */
-#define CK_TN_TT 1 /* TELNET TERMINAL-TYPE */
-#define CK_TN_NL 2 /* TELNET NEWLINE-MODE */
-#define CK_TN_BM 3 /* TELNET BINARY-MODE */
-#define CK_TN_BUG 4 /* TELNET BUG */
-#define CK_TN_ENV 5 /* TELNET ENVIRONMENT */
-#define TN_ENV_USR 0 /* VAR USER */
-#define TN_ENV_JOB 1 /* VAR JOB */
-#define TN_ENV_ACCT 2 /* VAR ACCT */
-#define TN_ENV_PRNT 3 /* VAR PRINTER */
-#define TN_ENV_SYS 4 /* VAR SYSTEMTYPE */
-#define TN_ENV_DISP 5 /* VAR DISPLAY */
-#define TN_ENV_UVAR 6 /* USERVAR */
-#define TN_ENV_LOC 7 /* USERVAR LOCATION */
-#define TN_ENV_ON 98 /* ON (enabled) */
-#define TN_ENV_OFF 99 /* OFF (disabled) */
-#define CK_TN_LOC 6 /* TELNET LOCATION */
-#define CK_TN_AU 7 /* TELNET AUTHENTICATION */
-#define TN_AU_FWD 4 /* AUTH FORWARD */
-#define TN_AU_TYP 5 /* AUTH TYPE */
-#define AUTH_NONE 0 /* AUTH NONE */
-#define AUTH_KRB4 1 /* AUTH Kerberos IV */
-#define AUTH_KRB5 2 /* AUTH Kerberos V */
-#define AUTH_SSL 7 /* AUTH Secure Sockets Layer */
-#define AUTH_TLS 98 /* AUTH Transport Layer Security */
-#define AUTH_SRP 5 /* AUTH Secure Remote Password */
-#define AUTH_NTLM 15 /* AUTH NT Lan Manager */
-#define AUTH_AUTO 99 /* AUTH AUTOMATIC */
-#define TN_AU_HOW 8 /* AUTH HOW FLAG */
-#define TN_AU_ENC 9 /* AUTH ENCRYPT FLAG */
-#define CK_TN_ENC 8 /* TELNET ENCRYPTION */
-#define TN_EN_TYP 4 /* ENCRYPT TYPE */
-#define TN_EN_START 5 /* ENCRYPT START */
-#define TN_EN_STOP 6 /* ENCRYPT STOP */
-#define CK_TN_IKS 9 /* TELNET KERMIT-SERVER */
-#define CK_TN_RE 10 /* TELNET REMOTE-ECHO */
-#define CK_TN_TLS 11 /* TELNET START_TLS */
-#define CK_TN_XD 12 /* TELNET XDISPLOC */
-#define CK_TN_NAWS 13 /* TELNET NAWS */
-#define CK_TN_WAIT 14 /* TELNET WAIT-FOR-NEGOTIATIONS */
-#define CK_TN_SGA 15 /* TELNET SGA */
-#define CK_TN_CLIENT 16 /* TELNET CLIENT */
-#define CK_TN_SERVER 17 /* TELNET SERVER */
-#define CK_TN_PHR 18 /* TELNET PRAGMA-HEARTBEAT */
-#define CK_TN_PLG 19 /* TELNET PRAGMA-LOGON */
-#define CK_TN_PSP 20 /* TELNET PRAGMA-SSPI */
-#define CK_TN_SAK 21 /* TELNET IBM SAK */
-#define CK_TN_FLW 22 /* TELNET LFLOW */
-#define CK_TN_XF 23 /* TELNET TRANSFER-MODE */
-#define CK_TN_PUID 24 /* TELNET PROMPT-FOR-USERID */
-#define CK_TN_NE 25 /* TELNET NO-ENCRYPT-DURING-XFER */
-#define CK_TN_CPC 26 /* TELNET COM-PORT-CONTROL */
-#define CK_TN_DB 27 /* TELNET DEBUG */
-#define CK_TN_FX 28 /* TELNET FORWARD_X */
-#define CK_TN_DL 29 /* TELNET DELAY-SB */
-#define CK_TN_SFU 30 /* TELNET SFU-COMPATIBILITY */
-#define CK_TN_LOG 31 /* TELNET LOGOUT */
-#endif /* TNCODE */
-#define XYOUTP 68 /* OUTPUT command parameters */
-#define OUT_PAC 0 /* OUTPUT PACING */
-#define OUT_ESC 1 /* OUTPUT SPECIAL-ESCAPES */
-#define XYEXIT 69 /* SET EXIT */
-#define XYPRTR 70 /* SET PRINTER */
-#define XYFPATH 71 /* PATHNAME */
-
-#ifdef OS2
-#define XYMOUSE 72 /* MOUSE SUPPORT */
-#define XYM_ON 0 /* Mouse ON/OFF */
-#define XYM_BUTTON 1 /* Define Mouse Events */
-#define XYM_CLEAR 2 /* Clear Mouse Events */
-#define XYM_DEBUG 3 /* Debug Mode ON/OFF */
-/* These must match similar definitions in ckokey.h */
-#define XYM_B1 0 /* Mouse Button One */
-#define XYM_B2 1 /* Mouse Button Two */
-#define XYM_B3 2 /* Mouse Button Three */
-#define XYM_ALT 1 /* Alt */
-#define XYM_CTRL 2 /* Ctrl */
-#define XYM_SHIFT 4 /* Shift */
-#define XYM_C1 0 /* Single Click */
-#define XYM_C2 8 /* Double Click */
-#define XYM_DRAG 16 /* Drag Event */
-#endif /* OS2 */
-
-#define XYBELL 73 /* BELL */
-
-#ifdef OS2
-#define XYPRTY 74 /* Thread Priority Level */
-#define XYP_IDLE 1
-#define XYP_REG 2
-#define XYP_SRV 4
-#define XYP_RTP 3
-#endif /* OS2 */
-
-#define XYALRM 75 /* SET ALARM */
-#define XYPROTO 76 /* SET PROTOCOL */
-#define XYPREFIX 77 /* SET PREFIXING */
-#define XYLOGIN 78 /* Login info for script programs... */
-
-#define LOGI_UID 0 /* User ID */
-#define LOGI_PSW 1 /* Password */
-#define LOGI_PRM 2 /* Prompt */
-
-#define XYSTARTUP 79 /* Startup file */
-#define XYTMPDIR 80 /* Temporary directory */
-
-#ifdef OS2
-#define XYTAPI 81 /* Microsoft Telephone API options */
-#define XYTAPI_CFG 1 /* TAPI Configure-Line Dialog */
-#define XYTAPI_DIAL 2 /* TAPI Dialing-Properties Dialog */
-#define XYTAPI_LIN 3 /* TAPI Line */
-#define XYTAPI_LOC 4 /* TAPI Location */
-#define XYTAPI_PASS 5 /* TAPI Passthrough */
-#define XYTAPI_CON 6 /* TAPI Conversions */
-#define XYTAPI_LGHT 7 /* TAPI Modem Lights */
-#define XYTAPI_PRE 8 /* TAPI Pre-dialing Terminal */
-#define XYTAPI_PST 9 /* TAPI Post-dialing Terminal */
-#define XYTAPI_INA 10 /* TAPI Inactivity Timeout */
-#define XYTAPI_BNG 11 /* TAPI Wait for Credit Card Tone */
-#define XYTAPI_MAN 12 /* TAPI Manual Dialing */
-#define XYTAPI_USE 13 /* TAPI Use Line Config settings */
-#endif /* OS2 */
-
-#ifdef TCPSOCKET
-#define XYTCP 82 /* TCP options */
-#define XYTCP_NODELAY 1 /* No Delay */
-#define XYTCP_SENDBUF 2 /* Send Buffer Size */
-#define XYTCP_LINGER 3 /* Linger */
-#define XYTCP_RECVBUF 4 /* Receive Buffer Size */
-#define XYTCP_KEEPALIVE 5 /* Keep Alive packets */
-#define XYTCP_UCX 6 /* UCX 2.0 port swabbing bug */
-#define XYTCP_NAGLE 7 /* Delay - inverse of 1 */
-#define XYTCP_RDNS 8 /* Reverse DNS lookup */
-#define XYTCP_ADDRESS 9 /* Set preferred IP Address */
-#define XYTCP_DNS_SRV 10 /* Use DNS Service Records */
-#define XYTCP_DONTROUTE 11 /* Dont Route */
-#define XYTCP_SOCKS_SVR 12 /* Name of Socks Server */
-#define XYTCP_HTTP_PROXY 13 /* Name/Port of HTTP Proxy Server */
-#define XYTCP_SOCKS_NS 14 /* Name of Socks Name Server */
-#endif /* TCPSOCKET */
-
-#ifdef OS2
-#define XYMSK 83 /* MS-DOS Kermit compatibility options */
-#define MSK_COLOR 0 /* Terminal color handling */
-#define MSK_KEYS 1 /* SET KEY uses MSK keycodes */
-#endif /* OS2 */
-
-#define XYDEST 84 /* SET DESTINATION as in MS-DOS Kermit */
-
-#ifdef OS2
-#define XYWIN95 85 /* SET WIN95 work arounds */
-#define XYWKEY 0 /* Keyboard translation */
-#define XYWAGR 1 /* Alt-Gr */
-#define XYWOIO 2 /* Overlapped I/O */
-#define XYWLUC 3 /* Lucida Console substitutions */
-#define XYWSELECT 4 /* Select on Write Bug */
-#define XYW8_3 5 /* Use 8.3 filenames? */
-#define XYWPOPUP 6 /* Use Popups? */
-#define XYWHSL 7 /* Horz Scan Line substitutions */
-#define XYDLR 86 /* SET K95 DIALER work arounds */
-#define XYTITLE 87 /* SET TITLE of window */
-#endif /* OS2 */
-
-#define XYIGN 88 /* SET IGNORE-CHARACTER */
-#define XYEDIT 89 /* SET EDITOR */
-#define XYFLTR 90 /* SET { SEND, RECEIVE } FILTER */
-#define XYBROWSE 91 /* SET BROWSER */
-#define XYEOF 92 /* EOF (= FILE EOF) */
-#ifdef OS2
-#define XYBDCP 93 /* BPRINTER */
-#endif /* OS2 */
-#define XYFLAG 94 /* FLAG */
-#define XYLIMIT 95 /* SESSION-LIMIT */
-#define XYINIL 96 /* Protocol negotiation string max length */
-#define XYRELY 97 /* RELIABLE */
-#define XYSTREAM 98 /* STREAMING */
-#define XYTLOG 99 /* TRANSACTION-LOG */
-#define XYCLEAR 100 /* CLEARCHANNEL */
-#define XYAUTH 101 /* AUTHENTICATION */
-
-#ifdef TNCODE
-#define XYKRBPR 0 /* Kerberos Principal */
-#define XYKRBRL 1 /* Kerberos Realm */
-#define XYKRBCC 2 /* Kerberos 5 Credentials-Cache */
-#define XYKRBSRV 3 /* Kerberos Service Name */
-#define XYKRBDBG 4 /* Kerberos Debugging */
-#define XYKRBLIF 5 /* Kerberos Lifetime */
-#define XYKRBPRE 6 /* Kerberos 4 Preauth */
-#define XYKRBINS 7 /* Kerberos 4 Instance */
-#define XYKRBFWD 8 /* Kerberos 5 Forwardable */
-#define XYKRBPRX 9 /* Kerberos 5 Proxiable */
-#define XYKRBRNW 10 /* Kerberos 5 Renewable lifetime */
-#define XYKRBGET 11 /* Kerberos Auto-Get-TGTs */
-#define XYKRBDEL 12 /* Kerberos Auto-Destroy-TGTs */
-#define KRB_DEL_NO 0 /* Kerberos No Auto Destroy */
-#define KRB_DEL_CL 1 /* Kerberos Auto Destory on Close */
-#define KRB_DEL_EX 2 /* Kerberos Auto Destroy on Exit */
-#define XYKRBK5K4 13 /* Kerberos 5 Get K4 Tickets */
-#define XYKRBPRM 14 /* Kerberos 4/5 Prompt */
-#define XYKRBADR 15 /* Kerberos 4/5 CheckAddrs */
-#define XYKRBNAD 16 /* Kerberos 5 No Addresses */
-#define XYKRBADD 17 /* Kerberos 5 Address List */
-#define XYKRBKTB 18 /* Kerberos 4/5 Key Table */
-#define XYSRPPRM 0 /* SRP Prompt */
-#define XYSSLRCFL 0 /* SSL/TLS RSA Certs file */
-#define XYSSLCOK 1 /* SSL/TLS Certs-Ok flag */
-#define XYSSLCRQ 2 /* SSL/TLS Certs-Required flag */
-#define XYSSLCL 3 /* SSL/TLS Cipher List */
-#define XYSSLDBG 4 /* SSL/TLS Debug flag */
-#define XYSSLRKFL 5 /* SSL/TLS RSA Key File */
-#define XYSSLLFL 6 /* SSL/TLS Log File */
-#define XYSSLON 7 /* SSL/TLS Only flag */
-#define XYSSLSEC 8 /* SSL/TLS Secure flag */
-#define XYSSLVRB 9 /* SSL/TLS Verbose flag */
-#define XYSSLVRF 10 /* SSL/TLS Verify flag */
-#define XYSSLDUM 11 /* SSL/TLS Dummy flag */
-#define XYSSLDCFL 12 /* SSL/TLS DSA Certs file */
-#define XYSSLDKFL 13 /* SSL/TLS DH Certs file */
-#define XYSSLDPFL 14 /* SSL/TLS DH Param file */
-#define XYSSLCRL 15 /* SSL/TLS CRL file */
-#define XYSSLCRLD 16 /* SSL/TLS CRL dir */
-#define XYSSLVRFF 17 /* SSL/TLS Verify file */
-#define XYSSLVRFD 18 /* SSL/TLS Verify dir */
-#define XYSSLRND 19 /* SSL/TLS Random file */
-#define XYSSLDCCF 20 /* SSL/TLS DSA Certs Chain File */
-#define XYSSLRCCF 21 /* SSL/TLS RSA Certs Chain File */
-
-/* The following must be powers of 2 for a bit mask */
-
-#define XYKLCEN 1 /* Kerberos List Credentials: Encryption */
-#define XYKLCFL 2 /* Kerberos List Credentials: Flags */
-#define XYKLCAD 4 /* Kerberos List Credentials: Addresses */
-#endif /* TNCODE */
-
-#define XYFUNC 102 /* SET FUNCTION */
-
-#define FUNC_DI 0 /* FUNCTION DIAGNOSTICS */
-#define FUNC_ER 1 /* FUNCTION ERROR */
-
-#define XYFTP 103 /* FTP application */
-#define XYSLEEP 104 /* SLEEP / PAUSE options */
-#define XYSSH 105 /* SSH options */
-#define XYTELOP 106 /* TELNET OPTIONS (TELOPT) */
-#define XYCD 107 /* SET CD */
-#define XYCSET 108 /* CHARACTER-SET */
-#define XYSTOP 109 /* STOP-BITS */
-#define XYSERIAL 110 /* SERIAL */
-#define XYDISC 111 /* CLOSE-ON-DISCONNECT */
-#define XYOPTS 112 /* OPTIONS */
-#define XYQ8FLG 113 /* Q8FLAG (invisible) */
-#define XYTIMER 114 /* TIMER */
-#define XYFACKB 115 /* F-ACK-BUG */
-#define XYBUP 116 /* SET SEND/RECEIVE BACKUP */
-#define XYMOVE 117 /* SET SEND/RECEIVE MOVE-TO */
-#define XYRENAME 118 /* SET SEND/RECEIVE RENAME-TO */
-#define XYHINTS 119 /* SET HINTS */
-#define XYEVAL 120 /* SET EVALUATE */
-#define XYFACKP 121 /* F-ACK-PATH */
-#define XYSYSL 122 /* SysLog */
-#define XYQNXPL 123 /* QNX Port Lock */
-#define XYIKS 124 /* SET IKS ... */
-#define XYROOT 125 /* SET ROOT */
-#define XYFTPX 126 /* SET FTP */
-#define XYSEXP 127 /* SET SEXP */
-#define XYGPR 128 /* SET GET-PUT-REMOTE */
-#define XYLOCUS 129 /* SET LOCUS */
-#define XYGUI 130 /* SET GUI */
-#define XYANSWER 131 /* SET ANSWER */
-#define XYMATCH 132 /* SET MATCHDOT */
-#define XYSFTP 133 /* SET SFTP */
-
-/* End of SET commands */
-
-/* S-Expressions -- floating-point support required */
-
-#ifndef CKFLOAT
-#ifndef NOSEXP
-#define NOSEXP
-#endif /* NOSEXP */
-#endif /* CKFLOAT */
-
-/* Maximum number of elements in an S-Expression */
-
-#ifndef NOSEXP
-#ifndef SEXPMAX
-#ifdef BIGBUFOK
-#define SEXPMAX 1024
-#else
-#define SEXPMAX 32
-#endif /* BIGBUFOK */
-#endif /* SEXPMAX */
-#endif /* NOSEXP */
-
-#ifdef ANYX25
-/* PAD command parameters */
-
-#define XYPADL 0 /* clear virtual call */
-#define XYPADS 1 /* status of virtual call */
-#define XYPADR 2 /* reset of virtual call */
-#define XYPADI 3 /* send an interrupt packet */
-
-/* Used with XYX25... */
-#define XYUDAT 0 /* X.25 call user data */
-#define XYCLOS 1 /* X.25 closed user group call */
-#define XYREVC 2 /* X.25 reverse charge call */
-#endif /* ANYX25 */
-
-#ifdef OS2
-/* SET PRINTER switches */
-
-#define PRN_OUT 0 /* Output only */
-#define PRN_BID 1 /* Bidirectional */
-#define PRN_DOS 2 /* DOS device */
-#define PRN_WIN 3 /* Windows queue */
-#define PRN_TMO 4 /* Timeout */
-#define PRN_TRM 5 /* Terminator */
-#define PRN_SEP 6 /* Separator */
-#define PRN_SPD 7 /* COM-port speed */
-#define PRN_FLO 8 /* COM-port flow control */
-#define PRN_PAR 9 /* COM-port parity */
-#define PRN_NON 10 /* No printer */
-#define PRN_FIL 11 /* Filename */
-#define PRN_PIP 12 /* Pipename */
-#define PRN_PS 13 /* Text to PS */
-#define PRN_WID 14 /* PS Width */
-#define PRN_LEN 15 /* PS Length */
-#define PRN_RAW 16 /* Non-PS */
-#define PRN_CS 17 /* Character Set */
-#define PRN_MAX 17 /* Number of switches defined */
-
-/* Printer types */
-
-#define PRT_DOS 0 /* DOS */
-#define PRT_WIN 1 /* Windows Queue */
-#define PRT_FIL 2 /* File */
-#define PRT_PIP 3 /* Pipe */
-#define PRT_NON 4 /* None */
-
-#define PRINTSWI
-#endif /* OS2 */
-#endif /* NOICP */
-
-#ifndef NODIAL
-/*
- Symbols for modem types, moved here from ckudia.c, May 1997, because now
- they are also used in some other modules. The numbers MUST correspond to
- the ordering of entries within the modemp[] array.
-*/
-#ifdef MINIDIAL /* Minimum dialer support */
-
-#define n_DIRECT 0 /* Direct connection -- no modem */
-#define n_CCITT 1 /* CCITT/ITU-T V.25bis */
-#define n_HAYES 2 /* Hayes 2400 */
-#define n_UNKNOWN 3 /* Unknown */
-#define n_UDEF 4 /* User-Defined */
-#define n_GENERIC 5 /* Generic High Speed */
-#define n_ITUTV250 6 /* ITU-T V.250 */
-#define MAX_MDM 6 /* Number of modem types */
-
-#else /* Full-blown dialer support */
-
-#define n_DIRECT 0 /* Direct connection -- no modem */
-#define n_ATTDTDM 1
-#define n_ATTISN 2
-#define n_ATTMODEM 3
-#define n_CCITT 4
-#define n_CERMETEK 5
-#define n_DF03 6
-#define n_DF100 7
-#define n_DF200 8
-#define n_GDC 9
-#define n_HAYES 10
-#define n_PENRIL 11
-#define n_RACAL 12
-#define n_UNKNOWN 13
-#define n_VENTEL 14
-#define n_CONCORD 15
-#define n_ATTUPC 16 /* aka UNIX PC and ATT7300 */
-#define n_ROLM 17 /* Rolm CBX DCM */
-#define n_MICROCOM 18 /* Microcoms in SX command mode */
-#define n_USR 19 /* Modern USRs */
-#define n_TELEBIT 20 /* Telebits of all kinds */
-#define n_DIGITEL 21 /* Digitel DT-22 (CCITT variant) */
-#define n_H_1200 22 /* Hayes 1200 */
-#define n_H_ULTRA 23 /* Hayes Ultra and maybe Optima */
-#define n_H_ACCURA 24 /* Hayes Accura and maybe Optima */
-#define n_PPI 25 /* Practical Peripherals */
-#define n_DATAPORT 26 /* AT&T Dataport */
-#define n_BOCA 27 /* Boca */
-#define n_MOTOROLA 28 /* Motorola Fastalk or Lifestyle */
-#define n_DIGICOMM 29 /* Digicomm Connection */
-#define n_DYNALINK 30 /* Dynalink 1414VE */
-#define n_INTEL 31 /* Intel 14400 Faxmodem */
-#define n_UCOM_AT 32 /* Microcoms in AT mode */
-#define n_MULTI 33 /* Multitech MT1432 */
-#define n_SUPRA 34 /* SupraFAXmodem */
-#define n_ZOLTRIX 35 /* Zoltrix */
-#define n_ZOOM 36 /* Zoom */
-#define n_ZYXEL 37 /* ZyXEL */
-#define n_TAPI 38 /* TAPI Line modem - whatever it is */
-#define n_TBNEW 39 /* Newer Telebit models */
-#define n_MAXTECH 40 /* MaxTech XM288EA */
-#define n_UDEF 41 /* User-Defined */
-#define n_RWV32 42 /* Generic Rockwell V.32 */
-#define n_RWV32B 43 /* Generic Rockwell V.32bis */
-#define n_RWV34 44 /* Generic Rockwell V.34 */
-#define n_MWAVE 45 /* IBM Mwave Adapter */
-#define n_TELEPATH 46 /* Gateway Telepath */
-#define n_MICROLINK 47 /* MicroLink modems */
-#define n_CARDINAL 48 /* Cardinal modems */
-#define n_GENERIC 49 /* Generic high-speed */
-#define n_XJACK 50 /* Megahertz X-Jack */
-#define n_SPIRITII 51 /* Quickcomm Spirit II */
-#define n_MONTANA 52 /* Motorola Montana */
-#define n_COMPAQ 53 /* Compaq Data+Fax Modem */
-#define n_FUJITSU 54 /* Fujitsu Fax/Modem Adpater */
-#define n_MHZATT 55 /* Megahertz AT&T V.34 */
-#define n_SUPRASON 56 /* SupraSonic */
-#define n_BESTDATA 57 /* Best Data */
-#define n_ATT1900 58 /* AT&T STU III Model 1900 */
-#define n_ATT1910 59 /* AT&T STU III Model 1910 */
-#define n_KEEPINTOUCH 60 /* AT&T KeepinTouch */
-#define n_USRX2 61 /* USR XJ-1560 X2 56K */
-#define n_ROLMAT 62 /* Rolm with AT command set */
-#define n_ATLAS 63 /* Atlas / Newcom ixfC 33.6 */
-#define n_CODEX 64 /* Motorola Codex 326X Series */
-#define n_MT5634ZPX 65 /* Multitech MT5634ZPX */
-#define n_ULINKV250 66 /* Microlink ITU-T V.250 56K */
-#define n_ITUTV250 67 /* Generic ITU-T V.250 */
-#define n_RWV90 68 /* Generic Rockwell V.90 */
-#define n_SUPRAX 69 /* Diamond Supra Express V.90 */
-#define n_LUCENT 70 /* Lucent Venus chipset */
-#define n_PCTEL 71 /* PCTel chipset */
-#define n_CONEXANT 72 /* Conexant modem family */
-#define n_ZOOMV34 73 /* Zoom */
-#define n_ZOOMV90 74 /* Zoom */
-#define n_ZOOMV92 75 /* ZOOM V.92 */
-#define n_MOTSM56 76 /* Motorola SM56 chipset */
-#define MAX_MDM 76 /* Number of modem types */
-
-#endif /* MINIDIAL */
-#endif /* NODIAL */
-
-#ifndef NOICP
-/* SHOW command symbols */
-
-#define SHPAR 0 /* Parameters */
-#define SHVER 1 /* Versions */
-#define SHCOM 2 /* Communications */
-#define SHPRO 3 /* Protocol */
-#define SHFIL 4 /* File */
-#define SHLNG 5 /* Language */
-#define SHCOU 6 /* Count */
-#define SHMAC 7 /* Macros */
-#define SHKEY 8 /* Key */
-#define SHSCR 9 /* Scripts */
-#define SHSPD 10 /* Speed */
-#define SHSTA 11 /* Status */
-#define SHSER 12 /* Server */
-#define SHXMI 13 /* Transmit */
-#define SHATT 14 /* Attributes */
-#define SHMOD 15 /* Modem */
-#define SHDFLT 16 /* Default (as in VMS) */
-#define SHVAR 17 /* Show global variables */
-#define SHARG 18 /* Show macro arguments */
-#define SHARR 19 /* Show arrays */
-#define SHBUI 20 /* Show builtin variables */
-#define SHFUN 21 /* Show functions */
-#define SHPAD 22 /* Show (X.25) PAD */
-#define SHTER 23 /* Show terminal settings */
-#define SHESC 24 /* Show escape character */
-#define SHDIA 25 /* Show DIAL parameters */
-#define SHNET 26 /* Show network parameters */
-#define SHLBL 27 /* Show VMS labeled file parameters */
-#define SHSTK 28 /* Show stack, MAC debugging */
-#define SHCSE 29 /* Show character sets */
-#define SHFEA 30 /* Show features */
-#define SHCTL 31 /* Show control-prefix table */
-#define SHEXI 32 /* Show EXIT items */
-#define SHPRT 33 /* Show printer */
-#define SHCMD 34 /* Show command parameters */
-#define SHKVB 35 /* Show \Kverbs */
-#define SHMOU 36 /* Show Mouse (like Show Key) */
-#define SHTAB 37 /* Show Tabs (OS/2) */
-#define SHVSCRN 38 /* Show Virtual Screen (OS/2) */
-#define SHALRM 39 /* ALARM */
-#define SHSFL 40 /* SEND-LIST */
-#define SHUDK 41 /* DEC VT UDKs (OS/2) */
-#define SHDBL 42 /* DOUBLE/IGNORE characters */
-#define SHEDIT 43 /* EDITOR */
-#define SHBROWSE 44 /* BROWSER */
-#define SHTAPI 45 /* TAPI */
-#define SHTAPI_L 46 /* TAPI Location */
-#define SHTAPI_M 47 /* TAPI Modem Properties */
-#define SHTAPI_C 48 /* TAPI Comm Properties */
-#define SHTEL 49 /* SHOW TELNET */
-#define SHINP 50 /* SHOW INPUT */
-#define SHTRIG 51 /* SHOW TRIGGER */
-#define SHLOG 52 /* SHOW LOGS */
-#define SHOUTP 53 /* SHOW OUTPUT */
-#define SHOPAT 54 /* SHOW PATTERNS */
-#define SHOSTR 55 /* SHOW STREAMING */
-#define SHOAUTH 56 /* SHOW AUTHENTICATION */
-#define SHOFTP 57 /* SHOW FTP */
-#define SHTOPT 58 /* SHOW TELOPT */
-#define SHXOPT 59 /* SHOW EXTENDED-OPTIONS */
-#define SHCD 60 /* SHOW CD */
-#define SHASSOC 61 /* SHOW ASSOCIATIONS */
-#define SHCONNX 62 /* SHOW CONNECTION */
-#define SHOPTS 63 /* SHOW OPTIONS */
-#define SHOFLO 64 /* SHOW FLOW-CONTROL */
-#define SHOXFER 65 /* SHOW TRANSFER */
-#define SHTCP 66 /* SHOW TCP */
-#define SHHISTORY 67 /* SHOW (command) HISTORY */
-#define SHSEXP 68 /* SHOW SEXPRESSIONS */
-#define SHOSSH 69 /* SHOW SSH */
-#define SHOIKS 70 /* SHOW IKS */
-#define SHOGUI 71 /* SHOW RGB */
-
-/* REMOTE command symbols */
-
-#define XZCPY 0 /* Copy */
-#define XZCWD 1 /* Change Working Directory */
-#define XZDEL 2 /* Delete */
-#define XZDIR 3 /* Directory */
-#define XZHLP 4 /* Help */
-#define XZHOS 5 /* Host */
-#define XZKER 6 /* Kermit */
-#define XZLGI 7 /* Login */
-#define XZLGO 8 /* Logout */
-#define XZMAI 9 /* Mail <-- wrong, this should be top-level */
-#define XZMOU 10 /* Mount */
-#define XZMSG 11 /* Message */
-#define XZPRI 12 /* Print */
-#define XZREN 13 /* Rename */
-#define XZSET 14 /* Set */
-#define XZSPA 15 /* Space */
-#define XZSUB 16 /* Submit */
-#define XZTYP 17 /* Type */
-#define XZWHO 18 /* Who */
-#define XZPWD 19 /* Print Working Directory */
-#define XZQUE 20 /* Query */
-#define XZASG 21 /* Assign */
-#define XZMKD 22 /* mkdir */
-#define XZRMD 23 /* rmdir */
-#define XZXIT 24 /* Exit */
-#define XZCDU 25 /* CDUP */
-
-/* SET INPUT command parameters */
-
-#define IN_DEF 0 /* Default timeout */
-#define IN_TIM 1 /* Timeout action */
-#define IN_CAS 2 /* Case (matching) */
-#define IN_ECH 3 /* Echo */
-#define IN_SIL 4 /* Silence */
-#define IN_BUF 5 /* Buffer size */
-#define IN_PAC 6 /* Input Pacing (debug) */
-#define IN_TRM 7 /* Input Terminal Display */
-#define IN_ADL 8 /* Input autodownload */
-#define IN_PAT 9 /* Pattern to match */
-#define IN_ASG 10 /* Assign matching text to variable */
-#define IN_CAN 11 /* Keyboard cancellation of INPUT */
-#define IN_SCA 12 /* Timeout scaling */
-
-/* ENABLE/DISABLE command parameters */
-
-#define EN_ALL 0 /* ALL */
-#define EN_CWD 1 /* CD/CWD */
-#define EN_DIR 2 /* DIRECTORY */
-#define EN_FIN 3 /* FINISH */
-#define EN_GET 4 /* GET */
-#define EN_HOS 5 /* HOST command */
-#define EN_KER 6 /* KERMIT command */
-#define EN_LOG 7 /* LOGIN */
-#define EN_SEN 8 /* SEND */
-#define EN_SET 9 /* SET */
-#define EN_SPA 10 /* SPACE */
-#define EN_TYP 11 /* TYPE */
-#define EN_WHO 12 /* WHO, finger */
-#define EN_DEL 13 /* Delete */
-#define EN_BYE 14 /* BYE (as opposed to FINISH) */
-#define EN_QUE 15 /* QUERY */
-#define EN_ASG 16 /* ASSIGN */
-#define EN_CPY 17 /* COPY */
-#define EN_REN 18 /* RENAME */
-#define EN_RET 19 /* RETRIEVE */
-#define EN_MAI 20 /* MAIL */
-#define EN_PRI 21 /* PRINT */
-#define EN_MKD 22 /* MKDIR */
-#define EN_RMD 23 /* RMDIR */
-#define EN_XIT 24 /* EXIT */
-#define EN_ENA 25 /* ENABLE */
-#endif /* NOICP */
-
-#ifndef NOICP
-/* CLEAR command symbols */
-#define CLR_DEV 1 /* Clear Device Buffers */
-#define CLR_INP 2 /* Clear Input Buffers */
-#define CLR_BTH CLR_DEV|CLR_INP /* Clear Device and Input */
-#define CLR_SCL 4 /* Clear Scrollback buffer */
-#define CLR_CMD 8 /* Clear Command Screen */
-#define CLR_TRM 16 /* Clear Terminal Screen */
-#define CLR_DIA 32 /* Clear Dial Status */
-#define CLR_SFL 64 /* Clear Send-File-List */
-#define CLR_APC 128 /* Clear APC */
-#define CLR_ALR 256 /* Clear Alarm */
-#define CLR_TXT 512 /* Clear text-patterns */
-#define CLR_BIN 1024 /* Clear binary-patterns */
-#define CLR_SCR 2048 /* Clear screen */
-#define CLR_KBD 4096 /* Clear keyboard buffer */
-#endif /* NOICP */
-
-/* Symbols for logs */
-
-#define LOGD 0 /* Debugging */
-#define LOGP 1 /* Packets */
-#define LOGS 2 /* Session */
-#define LOGT 3 /* Transaction */
-#define LOGX 4 /* Screen */
-#define LOGR 5 /* The "open read" file */
-#define LOGW 6 /* The "open write/append" file */
-#define LOGE 7 /* Error (e.g. stderr) */
-#define LOGM 8 /* The dialing log */
-
-#ifndef NOSPL
-/* Symbols for builtin variables */
-
-#define VN_ARGC 0 /* ARGC */
-#define VN_COUN 1 /* COUNT */
-#define VN_DATE 2 /* DATE */
-#define VN_DIRE 3 /* DIRECTORY */
-#define VN_ERRO 4 /* ERRORLEVEL */
-#define VN_TIME 5 /* TIME */
-#define VN_VERS 6 /* VERSION */
-#define VN_IBUF 7 /* INPUT buffer */
-#define VN_SUCC 8 /* SUCCESS flag */
-#define VN_LINE 9 /* LINE */
-#define VN_ARGS 10 /* Program command-line arg count */
-#define VN_SYST 11 /* System type */
-#define VN_SYSV 12 /* System version */
-#define VN_RET 13 /* RETURN value */
-#define VN_FILE 14 /* Most recent filespec */
-#define VN_NDAT 15 /* Numeric date yyyy/mm/dd */
-#define VN_HOME 16 /* Home directory */
-#define VN_SPEE 17 /* Transmission speed */
-#define VN_HOST 18 /* Host name */
-#define VN_TTYF 19 /* TTY file descriptor (UNIX only) */
-#define VN_PROG 20 /* Program name */
-#define VN_NTIM 21 /* NTIME */
-#define VN_FFC 22 /* Characters in last file xferred */
-#define VN_TFC 23 /* Chars in last file group xferred */
-#define VN_CPU 24 /* CPU type */
-#define VN_CMDL 25 /* Command level */
-#define VN_DAY 26 /* Day of week, string */
-#define VN_NDAY 27 /* Day of week, numeric */
-#define VN_LCL 28 /* Local (vs) remote mode */
-#define VN_CMDS 29 /* Command source */
-#define VN_CMDF 30 /* Command file name */
-#define VN_MAC 31 /* Macro name */
-#define VN_EXIT 32 /* Exit status */
-#define VN_ICHR 33 /* INPUT character */
-#define VN_ICNT 34 /* INPUT count */
-#define VN_PRTY 35 /* Current parity */
-#define VN_DIAL 36 /* DIAL status */
-#define VN_KEYB 37 /* Keyboard type */
-#define VN_CPS 38 /* Chars per second, last transfer */
-#define VN_RPL 39 /* Receive packet length */
-#define VN_SPL 40 /* Send packet length */
-#define VN_MODE 41 /* Transfer mode (text, binary) */
-#define VN_REXX 42 /* Rexx return value */
-#define VN_NEWL 43 /* Newline character or sequence */
-#define VN_COLS 44 /* Columns on console screen */
-#define VN_ROWS 45 /* Rows on console screen */
-#define VN_TTYP 46 /* Terminal type */
-#define VN_MINP 47 /* MINPUT result */
-#define VN_CONN 48 /* Connection type */
-#define VN_SYSI 49 /* System ID */
-#define VN_TZ 50 /* Timezone */
-#define VN_SPA 51 /* Space */
-#define VN_QUE 52 /* Query */
-#define VN_STAR 53 /* Startup directory */
-#define VN_CSET 54 /* Local character set */
-#define VN_MDM 55 /* Modem type */
-#define VN_EVAL 56 /* Most recent EVALUATE result */
-
-#define VN_D_CC 57 /* DIAL COUNTRY-CODE */
-#define VN_D_AC 58 /* DIAL AREA-CODE */
-#define VN_D_IP 59 /* DIAL INTERNATIONAL-PREFIX */
-#define VN_D_LP 60 /* DIAL LD-PREFIX */
-
-#define VN_UID 61
-#define VN_PWD 62
-#define VN_PRM 63
-
-#define VN_PROTO 64 /* Protocol */
-#define VN_DLDIR 65 /* Download directory */
-
-#define VN_M_AAA 66 /* First MODEM one */
-#define VN_M_INI 66 /* Modem init string */
-#define VN_M_DCM 67 /* Modem dial command */
-#define VN_M_DCO 68 /* Modem data compression on */
-#define VN_M_DCX 69 /* Modem data compression off */
-#define VN_M_ECO 70 /* Modem error correction on */
-#define VN_M_ECX 71 /* Modem error correction off */
-#define VN_M_AAO 72 /* Modem autoanswer on */
-#define VN_M_AAX 73 /* Modem autoanswer off */
-#define VN_M_HUP 74 /* Modem hangup command */
-#define VN_M_HWF 75 /* Modem hardware flow command */
-#define VN_M_SWF 76 /* Modem software flow command */
-#define VN_M_NFC 77 /* Modem no flow-control command */
-#define VN_M_PDM 78 /* Modem pulse dialing mode */
-#define VN_M_TDM 79 /* Modem tone dialing mode */
-#define VN_M_ZZZ 79 /* Last MODEM one */
-
-#define VN_SELCT 80 /* Selected Text from Mark Mode */
-#define VN_TEMP 81 /* Temporary directory */
-#define VN_ISTAT 82 /* INPUT command status */
-#define VN_INI 83 /* INI (kermrc) directory */
-#define VN_EXEDIR 84 /* EXE directory */
-#define VN_ERRNO 85 /* Value of errno */
-#define VN_ERSTR 86 /* Corresponding error message */
-#define VN_TFLN 87 /* TAKE file line number */
-#define VN_XVNUM 88 /* Product-specific version number */
-#define VN_RPSIZ 89 /* Receive packet length */
-#define VN_WINDO 90 /* Window size */
-#define VN_MDMSG 91 /* Modem message */
-#define VN_DNUM 92 /* Dial number */
-#define VN_APC 93 /* APC active */
-#define VN_IPADDR 94 /* My IP address */
-#define VN_CRC16 95 /* CRC-16 of most recent file group */
-#define VN_TRMK 96 /* Macro executed from Terminal Mode */
-#define VN_PID 97 /* Process ID */
-#define VN_FNAM 98 /* Name of file being transferred */
-#define VN_FNUM 99 /* Number of file being transferred */
-#define VN_PEXIT 100 /* Process exit status */
-#define VN_P_CTL 101 /* Control Prefix */
-#define VN_P_8BIT 102 /* 8-bit prefix */
-#define VN_P_RPT 103 /* Repeat count prefix */
-#define VN_D_LCP 104 /* DIAL LOCAL-PREFIX */
-#define VN_URL 105 /* Last URL selected */
-#define VN_REGN 106 /* Registration Name */
-#define VN_REGO 107 /* Registration Organization */
-#define VN_REGS 108 /* Registration Serial number */
-#define VN_XPROG 109 /* xprogram (like xversion) */
-#define VN_EDITOR 110 /* Editor */
-#define VN_EDOPT 111 /* Editor options */
-#define VN_EDFILE 112 /* Editor file */
-#define VN_BROWSR 113 /* Browser */
-#define VN_BROPT 114 /* Browser options */
-#define VN_HERALD 115 /* Program herald */
-#define VN_TEST 116 /* Program test level or "0" */
-#define VN_XFSTAT 117 /* File-Transfer status */
-#define VN_XFMSG 119 /* File-Transfer message */
-#define VN_SNDL 120 /* Send-list status */
-#define VN_TRIG 121 /* Trigger value */
-#define VN_MOU_X 122 /* OS/2 Mouse Cursor X */
-#define VN_MOU_Y 123 /* OS/2 Mouse Cursor Y */
-#define VN_PRINT 124 /* Printer */
-#define VN_ESC 125 /* Escape character */
-#define VN_INTIME 126 /* INPUT elapsed time */
-#define VN_K4RLM 127 /* Kerberos 4 Realm */
-#define VN_K5RLM 128 /* Kerberos 5 Realm */
-#define VN_K4PRN 129 /* Kerberos 4 Principal */
-#define VN_K5PRN 130 /* Kerberos 5 Principal */
-#define VN_K4CC 131 /* Kerberos 4 Credentials Cache */
-#define VN_K5CC 132 /* Kerberos 5 Credentials Cache */
-#define VN_OSNAM 133 /* OS name */
-#define VN_OSVER 134 /* OS version */
-#define VN_OSREL 135 /* OS release */
-#define VN_NAME 136 /* Name I was called by */
-#define VN_MODL 137 /* CPU model */
-#define VN_X25LA 138 /* X.25 local address */
-#define VN_X25RA 139 /* X.25 remote address */
-#define VN_K4SRV 140 /* Kerberos 4 Service Name */
-#define VN_K5SRV 141 /* Kerberos 5 Service Name */
-#define VN_PDSFX 142 /* PDIAL suffix */
-#define VN_DTYPE 143 /* DIAL type */
-#define VN_LCKPID 144 /* Lockfile PID (UNIX) */
-#define VN_BLK 145 /* Block check */
-#define VN_TFTIM 146 /* File transfer elapsed time */
-#define VN_D_PXX 147 /* DIAL PBX-EXCHANGE */
-#define VN_HWPAR 148 /* Hardware Parity */
-#define VN_SERIAL 149 /* SET SERIAL value */
-#define VN_LCKDIR 150 /* Lockfile directory (UNIX) */
-
-#define VN_K4ENO 151 /* Kerberos 4 Last Errno */
-#define VN_K4EMSG 152 /* Kerberos 4 Last Err Msg */
-#define VN_K5ENO 153 /* Kerberos 5 Last Errno */
-#define VN_K5EMSG 154 /* Kerberos 5 Last Err Msg */
-
-#define VN_INTMO 155 /* Input timeout */
-#define VN_AUTHS 156 /* Authentication State */
-
-#define VN_DM_LP 157 /* Dial Modifier: Long Pause */
-#define VN_DM_SP 158 /* Dial Modifier: Short Pause */
-#define VN_DM_PD 159 /* Dial Modifier: Pulse Dial */
-#define VN_DM_TD 160 /* Dial Modifier: Tone Dial */
-#define VN_DM_WA 161 /* Dial Modifier: Wait for Answer */
-#define VN_DM_WD 162 /* Dial Modifier: Wait for Dialtone */
-#define VN_DM_RC 163 /* Dial Modifier: Return to Command */
-
-/* (more below...) */
-
-#define VN_TY_LN 164 /* TYPE command line number */
-#define VN_TY_LC 165 /* TYPE command line count */
-#define VN_TY_LM 166 /* TYPE command match count */
-
-#define VN_MACLVL 167 /* \v(maclevel) */
-
-#define VN_XF_BC 168 /* Transfer blockcheck errors */
-#define VN_XF_TM 169 /* Transfer timeouts */
-#define VN_XF_RX 170 /* Transfer retransmissions */
-
-#define VN_M_NAM 171 /* Modem full name */
-#define VN_MS_CD 172 /* Modem signal CD */
-#define VN_MS_CTS 173 /* Modem signal CTS */
-#define VN_MS_DSR 174 /* Modem signal DSR */
-#define VN_MS_DTR 175 /* Modem signal DTR */
-#define VN_MS_RI 176 /* Modem signal RI */
-#define VN_MS_RTS 177 /* Modem signal RTS */
-
-#define VN_MATCH 178 /* Most recent pattern match */
-#define VN_SLMSG 179 /* SET LINE (error) message */
-#define VN_TXTDIR 180 /* Kermit text-file directory */
-#define VN_MA_PI 181 /* Math constant Pi */
-#define VN_MA_E 182 /* Math constant e */
-#define VN_MA_PR 183 /* Math precision (digits) */
-#define VN_CMDBL 184 /* Command buffer length */
-
-#define VN_AUTHT 185 /* Authentication Type */
-
-#ifdef CKCHANNELIO
-#define VN_FERR 186 /* FILE error */
-#define VN_FMAX 187 /* FILE max */
-#define VN_FCOU 188 /* Result of last FILE COUNT */
-#endif /* CKCHANNELIO */
-
-#define VN_DRTR 189 /* DIAL retry counter */
-#define VN_CXTIME 190 /* Elapsed time in session */
-#define VN_BYTE 191 /* Byte order */
-#define VN_AUTHN 192 /* Authentication Name */
-#define VN_KBCHAR 193 /* kbchar */
-#define VN_TTYNAM 194 /* Name of controlling terminal */
-
-#define VN_X509_S 195 /* X.509 Certificate Subject */
-#define VN_X509_I 196 /* X.509 Certificate Issuer */
-
-#define VN_PROMPT 197 /* C-Kermit's prompt */
-#define VN_BUILD 198 /* Build ID string */
-
-#define VN_SEXP 199 /* Last S-Expression */
-#define VN_VSEXP 200 /* Value of last S-Expression */
-#define VN_LSEXP 201 /* SEXP depth */
-
-#define VN_FTIME 202 /* Time as floating-poing number */
-
-#define VN_FTP_C 203 /* FTP Reply Code */
-#define VN_FTP_M 204 /* FTP Reply Message */
-#define VN_FTP_S 205 /* FTP Server type */
-#define VN_FTP_H 206 /* FTP Host */
-#define VN_FTP_X 207 /* FTP Connected */
-#define VN_FTP_L 208 /* FTP Logged in */
-#define VN_FTP_G 209 /* FTP GET-PUT-REMOTE setting */
-
-#define VN_SECURE 210 /* Encrypted connection 0 or 1 */
-
-#define VN_DM_HF 211 /* Dial Modifier: Hook Flash */
-#define VN_DM_WB 212 /* Dial Modifier: Wait for Bong */
-#define VN_CX_STA 213 /* CX_STATUS */
-
-#define VN_FTP_B 214 /* FTP CPL */
-#define VN_FTP_D 215 /* FTP DPL */
-#define VN_FTP_Z 216 /* FTP SECURITY */
-#define VN_HTTP_C 217 /* HTTP Code */
-#define VN_HTTP_N 218 /* HTTP Connected */
-#define VN_HTTP_H 219 /* HTTP Host */
-#define VN_HTTP_M 220 /* HTTP Message */
-#define VN_HTTP_S 221 /* HTTP Security */
-
-#define VN_NOW 222 /* Timestamp yyyymmdd hh:mm:ss */
-#define VN_HOUR 223 /* Current hour of the day 0-23 */
-
-#define VN_CI_DA 224 /* Caller ID date */
-#define VN_CI_TI 225 /* Caller ID time */
-#define VN_CI_NA 226 /* Caller ID name */
-#define VN_CI_NU 227 /* Caller ID number */
-#define VN_CI_ME 228 /* Caller ID message */
-#define VN_PERSONAL 229 /* Personal Directory on Windows */
-#define VN_APPDATA 230 /* User AppData directory */
-#define VN_COMMON 231 /* Common AppData directory */
-#define VN_DESKTOP 232 /* User Desktop directory */
-#define VN_TNC_SIG 233 /* RFC 2717 Signature */
-
-#ifdef KUI
-#define VN_GUI_XP 234 /* GUI Window X position */
-#define VN_GUI_YP 235 /* GUI Window Y position */
-#define VN_GUI_XR 236 /* GUI Window X resolution */
-#define VN_GUI_YR 237 /* GUI Window Y resolution */
-#define VN_GUI_RUN 238 /* GUI Window Run mode */
-#define VN_GUI_FNM 239 /* GUI Window Font Name */
-#define VN_GUI_FSZ 240 /* GUI Window Font Size */
-#endif /* KUI */
-
-#define VN_LOG_PKT 241 /* Packet Log Filename */
-#define VN_LOG_TRA 242 /* Transaction Log Filename */
-#define VN_LOG_SES 243 /* Session Log Filename */
-#define VN_LOG_DEB 244 /* Debug Log Filename */
-#define VN_LOG_CON 245 /* Connection Log Filename */
-
-#define VN_ISCALE 246 /* INPUT scale factor */
-#endif /* NOSPL */
-
-/* INPUT status values */
-
-#define INP_OK 0 /* Succeeded */
-#define INP_TO 1 /* Timed out */
-#define INP_UI 2 /* User interrupted */
-#define INP_IE 3 /* Internal error */
-#define INP_IO 4 /* I/O error or connection lost */
-#define INP_IKS 5 /* Kermit Server Active */
-
-#ifndef NOSPL
-/* Symbols for builtin functions */
-
-#define FNARGS 6 /* Maximum number of function args */
-
-#define FN_IND 0 /* Index (of string 1 in string 2) */
-#define FN_LEN 1 /* Length (of string) */
-#define FN_LIT 2 /* Literal (don't expand the string) */
-#define FN_LOW 3 /* Lower (convert to lowercase) */
-#define FN_MAX 4 /* Max (maximum) */
-#define FN_MIN 5 /* Min (minimum) */
-#define FN_MOD 6 /* Mod (modulus) */
-#define FN_EVA 7 /* Eval (evaluate arith expression) */
-#define FN_SUB 8 /* Substr (substring) */
-#define FN_UPP 9 /* Upper (convert to uppercase) */
-#define FN_REV 10 /* Reverse (a string) */
-#define FN_REP 11 /* Repeat (a string) */
-#define FN_EXE 12 /* Execute (a macro) */
-#define FN_VAL 13 /* Return value (of a macro) */
-#define FN_LPA 14 /* LPAD (left pad) */
-#define FN_RPA 15 /* RPAD (right pad) */
-#define FN_DEF 16 /* Definition of a macro, unexpanded */
-#define FN_CON 17 /* Contents of a variable, ditto */
-#define FN_FIL 18 /* File list */
-#define FN_FC 19 /* File count */
-#define FN_CHR 20 /* Character (like BASIC CHR$()) */
-#define FN_RIG 21 /* Right (like BASIC RIGHT$()) */
-#define FN_COD 22 /* Code value of character */
-#define FN_RPL 23 /* Replace */
-#define FN_FD 24 /* File date */
-#define FN_FS 25 /* File size */
-#define FN_RIX 26 /* Rindex (index from right) */
-#define FN_VER 27 /* Verify */
-#define FN_IPA 28 /* Find and return IP address */
-#define FN_CRY 39 /* ... */
-#define FN_OOX 40 /* ... */
-#define FN_HEX 41 /* Hexify */
-#define FN_UNH 42 /* Unhexify */
-#define FN_BRK 43 /* Break */
-#define FN_SPN 44 /* Span */
-#define FN_TRM 45 /* Trim */
-#define FN_LTR 46 /* Left-Trim */
-#define FN_CAP 47 /* Capitalize */
-#define FN_TOD 48 /* Time-of-day-to-secs-since-midnite */
-#define FN_SEC 49 /* Secs-since-midnite-to-time-of-day */
-#define FN_FFN 50 /* Full file name */
-#define FN_CHK 51 /* Checksum of text */
-#define FN_CRC 52 /* CRC-16 of text */
-#define FN_BSN 53 /* Basename of file */
-#define FN_CMD 54 /* Output of a command (cooked) */
-#define FN_RAW 55 /* Output of a command (raw) */
-#define FN_STX 56 /* Strip from right */
-#define FN_STL 57 /* Strip from left */
-#define FN_STN 58 /* Strip n chars */
-#define FN_SCRN_CX 59 /* Screen Cursor X Pos */
-#define FN_SCRN_CY 60 /* Screen Cursor Y Pos */
-#define FN_SCRN_STR 61 /* Screen String */
-#define FN_2HEX 62 /* Number (not string) to hex */
-#define FN_2OCT 63 /* Number (not string) to octal */
-#define FN_RFIL 64 /* Recursive file list */
-#define FN_DIR 65 /* Directory list */
-#define FN_RDIR 66 /* Recursive directory list */
-#define FN_DNAM 67 /* Directory part of filename */
-#define FN_RAND 68 /* Random number */
-#define FN_WORD 69 /* Word extraction */
-#define FN_SPLIT 70 /* Split string into words */
-#define FN_KRB_TK 71 /* Kerberos tickets */
-#define FN_KRB_NX 72 /* Kerberos next ticket */
-#define FN_KRB_IV 73 /* Kerberos ticket is valid */
-#define FN_KRB_TT 74 /* Kerberos ticket time */
-#define FN_ERRMSG 75 /* Error code to message */
-
-#ifndef UNIX
-#ifndef VMS
-#undef FN_ERRMSG
-#endif /* VMS */
-#endif /* UNIX */
-
-#define FN_DIM 76 /* Dimension of array */
-#define FN_DTIM 77 /* Convert to standard date/time */
-#define FN_JDATE 78 /* Regular date to day of year */
-#define FN_PNCVT 79 /* Convert phone number for dialing */
-#define FN_DATEJ 80 /* Day of year to date */
-#define FN_MJD 81 /* Date to modified Julian date */
-#define FN_MJD2 82 /* Modified Julian date to date */
-#define FN_DAY 83 /* Day of week of given date */
-#define FN_NDAY 84 /* Numeric day of week of given date */
-#define FN_TIME 85 /* Convert to hh:mm:ss */
-#define FN_NTIM 86 /* Convert to seconds since midnite */
-#define FN_N2TIM 87 /* Sec since midnite to hh:mm:ss */
-#define FN_PERM 88 /* Permissions of file */
-#define FN_KRB_FG 89 /* Kerberos Ticket Flags */
-#define FN_SEARCH 90 /* Search for pattern in string */
-#define FN_RSEARCH 91 /* Ditto, but right to left */
-#define FN_XLATE 92 /* Translate string charset */
-#define FN_ALOOK 93 /* Array lookup */
-#define FN_TLOOK 94 /* Table lookup */
-#define FN_TOB64 95 /* Encode into Base64 */
-#define FN_FMB64 96 /* Decode from Base64 */
-
-#define FN_ABS 97 /* Absolute value */
-
-#ifdef CKFLOAT
-#define FN_FPADD 98 /* Floating-point add */
-#define FN_FPSUB 99 /* Floating-point substract */
-#define FN_FPMUL 100 /* Floating-point multiply */
-#define FN_FPDIV 101 /* Floating-point divide */
-#define FN_FPEXP 102 /* Floating-point e to the x */
-#define FN_FPLN 103 /* Floating-point natural log */
-#define FN_FPLOG 104 /* Floating-point base-10 log */
-#define FN_FPPOW 105 /* Floating-point raise to power */
-#define FN_FPSQR 106 /* Floating-point square root */
-#define FN_FPABS 107 /* Floating-point absolute value */
-#define FN_FPMOD 108 /* Floating-point modulus */
-#define FN_FPMAX 109 /* Floating-point maximum */
-#define FN_FPMIN 110 /* Floating-point minimum*/
-#define FN_FPINT 111 /* Floating-point to integer */
-#define FN_FPROU 112 /* Floating-point round */
-#define FN_FPSIN 113 /* FP sine */
-#define FN_FPCOS 114 /* FP cosine */
-#define FN_FPTAN 115 /* FP tangent */
-#endif /* CKFLOAT */
-
-#ifdef CKCHANNELIO
-#define FN_FSTAT 116 /* File status */
-#define FN_FPOS 117 /* File position */
-#define FN_FEOF 118 /* File eof */
-#define FN_FILNO 119 /* File number / handle */
-#define FN_FGCHAR 120 /* File getchar */
-#define FN_FGLINE 121 /* File getline */
-#define FN_FGBLK 122 /* File getblock */
-#define FN_FPCHAR 123 /* File putchar */
-#define FN_FPLINE 124 /* File putline */
-#define FN_FPBLK 125 /* File putblock */
-#define FN_NLINE 126 /* File get current line number */
-#define FN_FERMSG 127 /* File error message */
-#endif /* CKCHANNELIO */
-
-#define FN_LEF 128 /* Left (= substr starting on left) */
-#define FN_AADUMP 129 /* Associative Array Dump */
-#define FN_STB 130 /* \fstripb() */
-#define FN_PATTERN 131 /* \fpattern() */
-#define FN_HEX2N 132 /* \fhexton() */
-#define FN_OCT2N 133 /* \foctton() */
-#define FN_HEX2IP 134 /* \fhextoip() */
-#define FN_IP2HEX 135 /* \fiptohex() */
-#define FN_RADIX 136 /* \fradix() */
-#define FN_JOIN 137 /* \fjoin() */
-#define FN_SUBST 138 /* \fsubstitute() */
-#define FN_SEXP 139 /* \fsexpression() */
-#define FN_CMDSTK 140 /* \fcmdstack() */
-#define FN_TOGMT 141 /* \ftogmt() */
-#define FN_CMPDATE 142 /* \fcmpdates() */
-#define FN_DIFDATE 143 /* \fdiffdates() */
-#ifdef TCPSOCKET
-#define FN_HSTADD 144 /* \faddr2name() */
-#define FN_HSTNAM 145 /* \fname2addr() */
-#endif /* TCPSOCKET */
-#define FN_DELSEC 146 /* \fdelta2sec() */
-#define FN_PC_DU 147 /* Path conversion DOS to Unix */
-#define FN_PC_VU 148 /* Path conversion VMS to Unix */
-#define FN_PC_UD 149 /* Path conversion Unix to DOS */
-#define FN_PC_UV 150 /* Path conversion Unix to VMS */
-#define FN_KWVAL 151 /* \fkeywordvalue() */
-#define FN_SLEEP 152 /* \fsleep() */
-#define FN_MSLEEP 153 /* \fmsleep() */
-#define FN_LNAME 154 /* \fLongPathName() (Windows) */
-#define FN_SNAME 155 /* \fShortPathName() (Windows) */
-#define FN_UNTAB 156 /* \funtabify() */
-
-#endif /* NOSPL */
-
-/* Time Units */
-
-#define TU_DAYS 0
-#define TU_WEEKS 1
-#define TU_MONTHS 2
-#define TU_YEARS 3
-
-#ifdef CK_CURSES
-/* Screen line numbers for fullscreen file-transfer display */
-
-#define CW_BAN 0 /* Curses Window Banner */
-#define CW_DIR 2 /* Current directory */
-#define CW_LIN 3 /* Communication device */
-#define CW_SPD 4 /* Communication speed */
-#define CW_PAR 5 /* Parity */
-#define CW_TMO 6
-#define CW_NAM 7 /* Filename */
-#define CW_TYP 8 /* File type */
-#define CW_SIZ 9 /* File size */
-#define CW_PCD 10 /* Percent done */
-
-#ifndef CK_PCT_BAR
-#define CW_TR 11 /* Time remaining */
-#define CW_CP 12 /* Characters per second */
-#define CW_WS 13 /* Window slots */
-#define CW_PT 14 /* Packet type */
-#define CW_PC 15 /* Packet count */
-#define CW_PL 16 /* Packet length */
-#define CW_PR 17 /* Packet retry */
-#ifdef COMMENT
-#define CW_PB 17 /* Packet block check */
-#endif /* COMMENT */
-#else /* CK_PCT_BAR */
-#define CW_BAR 11 /* Percent Bar Scale */
-#define CW_TR 12 /* Time remaining */
-#define CW_CP 13 /* Chars per sec */
-#define CW_WS 14 /* Window slots */
-#define CW_PT 15 /* Packet type */
-#define CW_PC 16 /* Packet count */
-#define CW_PL 17 /* Packet length */
-#define CW_PR 18 /* Packet retry */
-#ifdef COMMENT
-#define CW_PB 18 /* Packet block check */
-#endif /* COMMENT */
-#endif /* CK_PCT_BAR */
-
-#define CW_ERR 19 /* Error message */
-#define CW_MSG 20 /* Info message */
-#define CW_INT 22 /* Instructions */
-#define CW_FFC 99 /* File Characters Sent/Received */
-#endif /* CK_CURSES */
-
-#ifndef NOICP
-/* Save Commands */
-#define XSKEY 0 /* Key map file */
-#define XSCMD 1 /* Command mode */
-#define XSTERM 2 /* Terminal mode */
-#endif /* NOICP */
-
-#ifndef NODIAL
-/* Dial routine sort priorities */
-#define DN_INTERN 0
-#define DN_FREE 1
-#define DN_LOCAL 2
-#define DN_UNK 3
-#define DN_LONG 4
-#define DN_INTL 5
-#endif /* NODIAL */
-
-#ifdef SSHBUILTIN
-#define XSSH_OPN 1
-#define XSSH_V2 2
-#define XSSH_FLP 3
-#define XSSH_FRP 4
-#define XSSH_ADD 5
-#define XSSH_KEY 6
-#define XSSH_CLR 7
-#define XSSH_AGT 8
-
-#define SSHKT_1R 0 /* SSH KEY TYPE symbols */
-#define SSHKT_2R 1 /* must match ssh/key.h values */
-#define SSHKT_2D 2
-#define SSHKT_SRP 3
-
-#define SSHKD_IN 1 /* SSH KEY DISPLAY /IN-FORMAT */
-#define SSHKD_OUT 2 /* SSH KEY DISPLAY /OUT-FORMAT */
-
-#define SKDF_OSSH 1 /* Key display format OpenSSH */
-#define SKDF_SSHC 2 /* Key display format SSH.COM */
-#define SKDF_IETF 3 /* Key display format IETF */
-#define SKDF_FING 4 /* Key display format FINGERPRINT */
-
-#define SSHSW_USR 1
-#define SSHSW_VER 2
-#define SSHSW_CMD 3
-#define SSHSW_X11 4
-#define SSHSW_PWD 5
-#define SSHSW_SUB 6
-
-#define SSHC_LPF 1
-#define SSHC_RPF 2
-
-#define XSSH2_RKE 1
-
-#define SSHF_LCL 1
-#define SSHF_RMT 2
-
-#define SSHA_ADD 1
-#define SSHA_DEL 2
-#define SSHA_LST 3
-
-#define SSHASW_FP 1
-
-#define SSHK_PASS 1
-#define SSHK_CREA 2
-#define SSHK_DISP 3
-#define SSHK_V1 4
-
-#define SSHKC_BI 1
-#define SSHKC_PP 2
-#define SSHKC_TY 3
-#define SSHKC_1R 4
-
-#define SKRM_OPN 1
-#endif /* SSHBUILTIN */
-
-#ifdef SFTP_BUILTIN
-#define SFTP_OPN 1
-#define SFTP_CD 2
-#define SFTP_CHGRP 3
-#define SFTP_CHMOD 4
-#define SFTP_CHOWN 5
-#define SFTP_DIR 6
-#define SFTP_GET 7
-#define SFTP_MKDIR 8
-#define SFTP_PWD 9
-#define SFTP_PUT 10
-#define SFTP_REN 11
-#define SFTP_RM 12
-#define SFTP_RMDIR 13
-#define SFTP_LINK 14
-#define SFTP_VER 15
-
-#define XY_SFTP_RCS 1
-#define XY_SFTP_EOL 2
-#endif /* SFTP_BUILTIN */
-
-/* ANSI-C prototypes for user interface functions */
-
-#ifndef NOICP
-_PROTOTYP( int matchname, ( char *, int, int ) );
-_PROTOTYP( int ck_cls, ( void ) );
-_PROTOTYP( int ck_cleol, ( void ) );
-_PROTOTYP( int ck_curpos, ( int, int ) );
-_PROTOTYP( int cmdsrc, ( void ) );
-_PROTOTYP( int parser, ( int ) );
-_PROTOTYP( int chkvar, (char *) );
-_PROTOTYP( int zzstring, (char *, char **, int *) );
-#ifndef NOFRILLS
-_PROTOTYP( int yystring, (char *, char **) );
-#endif /* NOFRILLS */
-_PROTOTYP( int getncm, (char *, int) );
-_PROTOTYP( int getnct, (char *, int, FILE *, int) );
-#endif /* NOICP */
-_PROTOTYP( VOID bgchk, (void) );
-_PROTOTYP( char * nvlook, (char *) );
-_PROTOTYP( int xarray, (char *) );
-_PROTOTYP( int arraynam, (char *, int *, int *) );
-_PROTOTYP( int arraybounds, (char *, int *, int *) );
-_PROTOTYP( int arrayitoa, (int) );
-_PROTOTYP( int arrayatoi, (int) );
-_PROTOTYP( char * bldlen, (char *, char *) );
-_PROTOTYP( int chkarray, (int, int) );
-_PROTOTYP( int dclarray, (char, int) );
-_PROTOTYP( int pusharray, (int, int) );
-_PROTOTYP( int parsevar, (char *, int *, int *) );
-_PROTOTYP( int macini, (void) );
-_PROTOTYP( VOID initmac, (void) );
-_PROTOTYP( int delmac, (char *, int) );
-_PROTOTYP( int addmac, (char *, char *) );
-_PROTOTYP( int domac, (char *, char *, int) );
-_PROTOTYP( int addmmac, (char *, char *[]) );
-_PROTOTYP( int dobug, (void) );
-_PROTOTYP( int docd, (int) );
-_PROTOTYP( int doclslog, (int) );
-_PROTOTYP( int docmd, (int) );
-_PROTOTYP( int dodir, (int) );
-_PROTOTYP( int dodo, (int, char *, int) );
-_PROTOTYP( int doenable, (int, int) );
-_PROTOTYP( int dogoto, (char *, int) );
-_PROTOTYP( int dogta, (int) );
-_PROTOTYP( int dohlp, (int) );
-_PROTOTYP( int dohrmt, (int) );
-_PROTOTYP( int doif, (int) );
-_PROTOTYP( int doinput, (int, char *[], int[], int) );
-_PROTOTYP( int doreinp, (int, char *, int) );
-_PROTOTYP( int dolog, (int) );
-_PROTOTYP( int dologin, (char *) );
-_PROTOTYP( int doopen, (void) );
-_PROTOTYP( int doprm, (int, int) );
-_PROTOTYP( int doreturn, (char *) );
-_PROTOTYP( int dormt, (int) );
-_PROTOTYP( int dosort, (void) );
-_PROTOTYP( int dostat, (int) );
-_PROTOTYP( int dostop, (void) );
-_PROTOTYP( int dotype, (char *, int, int, int, char *, int, char *, int, int,
- char *, int));
-_PROTOTYP( int transmit, (char *, char, int, int, int) );
-_PROTOTYP( int xlate, (char *, char *, int, int) );
-_PROTOTYP( int litcmd, (char **, char **, int) );
-_PROTOTYP( int incvar, (char *, int, int) );
-_PROTOTYP( int ckdial, (char *, int, int, int, int) );
-_PROTOTYP( int hmsg, (char *) );
-_PROTOTYP( int hmsga, (char * []) );
-_PROTOTYP( int mlook, (struct mtab [], char *, int) );
-_PROTOTYP( int mxlook, (struct mtab [], char *, int) );
-_PROTOTYP( int mxxlook, (struct mtab [], char *, int) );
-_PROTOTYP( int prtopt, (int *, char *) );
-_PROTOTYP( CHAR rfilop, (char *, char) );
-_PROTOTYP( int setcc, (char *, int *) );
-_PROTOTYP( int setnum, (int *, int, int, int) );
-_PROTOTYP( int seton, (int *) );
-_PROTOTYP( int setonaut, (int *) );
-_PROTOTYP( VOID shmdmlin, (void) );
-_PROTOTYP( VOID initmdm, (int) );
-_PROTOTYP( char * showoff, (int) );
-_PROTOTYP( char * showooa, (int) );
-_PROTOTYP( char * showstring, (char *) );
-_PROTOTYP( int pktopn, (char *,int) );
-_PROTOTYP( int traopn, (char *,int) );
-_PROTOTYP( int sesopn, (char *,int) );
-_PROTOTYP( int debopn, (char *,int) );
-_PROTOTYP( int diaopn, (char *,int,int) );
-_PROTOTYP( int prepop, (void) );
-_PROTOTYP( int popclvl, (void) );
-_PROTOTYP( int varval, (char *, int *) );
-_PROTOTYP( char * evala, (char *) );
-_PROTOTYP( char * evalx, (char *) );
-_PROTOTYP( int setalarm, (long) );
-_PROTOTYP( int setat, (int) );
-_PROTOTYP( int setinp, (void) );
-_PROTOTYP( VOID dolognet, (void) );
-_PROTOTYP( VOID dologline, (void) );
-_PROTOTYP( int setlin, (int, int, int) );
-_PROTOTYP( int setmodem, (void) );
-_PROTOTYP( int setfil, (int) );
-_PROTOTYP( char * homepath, (void) );
-#ifdef OS2
-_PROTOTYP( int settapi, (void) ) ;
-#ifdef OS2MOUSE
-_PROTOTYP( int setmou, (void) );
-#endif /* OS2MOUSE */
-#endif /* OS2 */
-#ifdef LOCUS
-_PROTOTYP( VOID setlocus, (int,int) );
-_PROTOTYP( VOID setautolocus, (int) );
-#endif /* LOCUS */
-_PROTOTYP( int setbell, (void) );
-_PROTOTYP( VOID setcmask, (int));
-_PROTOTYP( VOID setautodl, (int,int));
-_PROTOTYP( VOID setdebses, (int));
-_PROTOTYP( VOID setseslog, (int));
-_PROTOTYP( VOID setaprint, (int));
-_PROTOTYP( int settrm, (void) );
-_PROTOTYP( int settrmtyp, (void) );
-_PROTOTYP( int setsr, (int, int) );
-_PROTOTYP( int setxmit, (void) );
-_PROTOTYP( int dosetkey, (void) );
-_PROTOTYP( int dochk, (void) );
-_PROTOTYP( int ludial, (char *, int) );
-_PROTOTYP( char * getdnum, (int) );
-_PROTOTYP( VOID getnetenv, (void) );
-_PROTOTYP( int getyesno, (char *, int) );
-_PROTOTYP( VOID xwords, (char *, int, char *[], int) );
-#ifdef OS2
-_PROTOTYP( VOID keynaminit, (void) );
-#endif /* OS2 */
-_PROTOTYP( int xlookup, (struct keytab[], char *, int, int *) );
-_PROTOTYP( char * rlookup, (struct keytab[], int, int) );
-_PROTOTYP( int hupok, (int) );
-_PROTOTYP( char * zzndate, (void) );
-_PROTOTYP( char * zjdate, (char *) );
-_PROTOTYP( char * jzdate, (char *) );
-_PROTOTYP( char * ckdate, (void) );
-_PROTOTYP( char * chk_ac, (int, char[]) );
-_PROTOTYP( char * gmdmtyp, (void) );
-_PROTOTYP( char * gfmode, (int, int) );
-_PROTOTYP( int setdest, (void) );
-_PROTOTYP( VOID ndinit, (void) );
-_PROTOTYP( int doswitch, (void) );
-_PROTOTYP( int dolocal, (void) );
-_PROTOTYP( long tod2sec, (char *) );
-_PROTOTYP( int lunet, (char *) );
-_PROTOTYP( int doxdis, (int) );
-_PROTOTYP( int dosave, (int) );
-_PROTOTYP( int doxsend, (int) );
-_PROTOTYP( int doxget, (int) );
-_PROTOTYP( int doxconn, (int) );
-_PROTOTYP( int clsconnx, (int) );
-_PROTOTYP( VOID ftreset, (void) );
-#ifdef CK_KERBEROS
-_PROTOTYP (int cp_auth, ( void ) );
-#endif /* CK_KERBEROS */
-_PROTOTYP( long mjd, (char *) );
-_PROTOTYP( char * mjd2date, (long) );
-_PROTOTYP( char * ckgetpid, (void) );
-
-_PROTOTYP( int dogrep, (void) );
-
-#ifndef NOFTP
-#ifndef SYSFTP
-_PROTOTYP( int doxftp, (void) );
-_PROTOTYP( int doftphlp, (void) );
-_PROTOTYP( int dosetftp, (void) );
-_PROTOTYP( int dosetftphlp, (void) );
-_PROTOTYP( int shoftp, (int) );
-#endif /* SYSFTP */
-#endif /* NOFTP */
-
-_PROTOTYP( VOID cmhistory, (void) );
-_PROTOTYP( char * getdcset, (void) );
-_PROTOTYP( char * ttgtpn, (void) );
-
-#ifndef NOSHOW
-_PROTOTYP( int doshow, (int) );
-_PROTOTYP( int shotcp, (int) );
-_PROTOTYP( VOID shopar, (void) );
-_PROTOTYP( VOID shofil, (void) );
-_PROTOTYP( VOID shoparp, (void) );
-_PROTOTYP( int shoatt, (void) );
-_PROTOTYP( VOID shover, (void) );
-_PROTOTYP( VOID shoctl, (void) );
-_PROTOTYP( VOID shodbl, (void) );
-#ifndef NOSPL
-_PROTOTYP( int shomac, (char *, char *) );
-_PROTOTYP( int doshift, (int) );
-#endif /* NOSPL */
-#ifndef NOCSETS
-_PROTOTYP( VOID shocharset, (void) );
-_PROTOTYP( VOID shoparl, (void) );
-_PROTOTYP( VOID shotcs, (int, int) );
-#endif /* NOCSETS */
-#ifndef NOLOCAL
-_PROTOTYP( VOID shoparc, (void) );
-_PROTOTYP( int shomodem, (void) );
-#ifndef NODIAL
-_PROTOTYP( VOID shods, (char *) );
-_PROTOTYP( VOID shodial, (void) );
-_PROTOTYP( int doshodial, (void) );
-#endif /* NODIAL */
-#ifndef NONET
-_PROTOTYP( int shonet, (void) );
-_PROTOTYP( int shotopt, (int) );
-_PROTOTYP( int shotel, (int) );
-#ifdef CK_AUTHENTICATION
-_PROTOTYP (int sho_auth,( int ) );
-#endif /* CK_AUTHENTICATION */
-#endif /* NONET */
-_PROTOTYP( VOID shomdm, (void) );
-#endif /* NOLOCAL */
-#ifdef OS2
-_PROTOTYP( VOID shokeycode, (int,int) );
-#else
-_PROTOTYP( VOID shokeycode, (int) );
-#endif /* OS2 */
-_PROTOTYP( VOID showassoc, (void) );
-_PROTOTYP( VOID showdiropts, (void) );
-_PROTOTYP( VOID showdelopts, (void) );
-_PROTOTYP( VOID showtypopts, (void) );
-_PROTOTYP( VOID showpurgopts, (void) );
-_PROTOTYP( VOID shoflow, (void) );
-_PROTOTYP( VOID shoxfer, (void) );
-#ifdef ANYSSH
-_PROTOTYP( VOID shossh, (void) );
-#endif /* ANYSSH */
-#endif /* NOSHOW */
-
-_PROTOTYP( VOID shostrdef, (CHAR *) );
-
-#ifndef NOSPL
-_PROTOTYP( int addlocal, (char *) );
-#endif /* NOSPL */
-
-_PROTOTYP( int setdelopts, (void) );
-
-#ifdef VMS
-_PROTOTYP( int cvtdir, (char *, char *, int) );
-#endif /* VMS */
-
-#ifdef FNFLOAT
-_PROTOTYP( VOID initfloat, (void) );
-#endif /* FNFLOAT */
-
-#ifdef CKCHANNELIO
-_PROTOTYP( int dofile, (int) );
-#endif /* CKCHANNELIO */
-
-#ifdef CKROOT
-_PROTOTYP( int dochroot, (void) );
-#endif /* CKROOT */
-
-#ifdef NEWFTP
-_PROTOTYP( int doftpusr, (void) );
-_PROTOTYP( int doftpput, (int,int) );
-_PROTOTYP( int doftpget, (int,int) );
-_PROTOTYP( int doftprmt, (int,int) );
-_PROTOTYP( int ftpopen, (char *, char *, int) );
-_PROTOTYP( int cmdlinget, (int) );
-_PROTOTYP( int cmdlinput, (int) );
-_PROTOTYP( int doftparg, (char) );
-_PROTOTYP( int doftpacct, (void) );
-_PROTOTYP( int doftpsite, (void) );
-_PROTOTYP( int dosetftppsv, (void) );
-_PROTOTYP( int ftpbye, (void) );
-#endif /* NEWFTP */
-
-#ifdef COMMENT
-/* These prototypes are no longer used */
-_PROTOTYP( char * getdws, (int) );
-_PROTOTYP( char * getdcs, (int) );
-_PROTOTYP( int doget, (int) );
-_PROTOTYP( char * arrayval, (int, int) );
-#endif /* COMMENT */
-
-#ifdef KUI
-_PROTOTYP(int BuildFontTable,
- (struct keytab ** pTable, struct keytab ** pTable2, int * pN));
-#endif /* KUI */
-
-_PROTOTYP(int cx_net, (int net, int protocol, char * xhost, char * svc,
- char * username, char * password, char * command,
- int param1, int param2, int param3,
- int cx, int sx, int flag, int gui));
-_PROTOTYP(int cx_serial, (char *device,
- int cx, int sx, int shr, int flag, int gui, int special));
-
-#endif /* CKUUSR_H */
-
-/* End of ckuusr.h */
030_fix-if-else.patch
040_pam-password-prompting.patch
050_ck_patch.patch
-060_speeling.patch
#endif /* NOCSETS */
" /SERVER-RENAME:text",
" Each server source file is to be renamed on the server as indicated",
- " immediately after, but only if, it has arrived successfully.",
+ " immediately after, but only if, it has arrived succesfully.",
" /SMALLER-THAN:number",
" Download only those files smaller than the given number of bytes.",
" /TEXT", /* /ASCII */
xxscreen(SCR_TC,0,0L,""); /* Display */
doclean(1); /* Clean up files, etc */
#ifdef DEBUG
- debug(F100,"C-Kermit BYE - Logging out...","",0);
+ debug(F100,"C-Kermit BYE - Loggin out...","",0);
zclose(ZDFILE);
#endif /* DEBUG */
#ifdef IKSD
If this switch is given, then instead of actually retrieving
the selected files, the GET command retrieves a list of the
names of the files that would be retrieved, and places it in
- the specified file. The resulting file is an ordinary text file,
+ the specifed file. The resulting file is an ordinary text file,
with one filename per line, suitable for reading by a person,
or processing by a computer program, including Kermit itself
(FOPEN / FREAD / FWRITE / FCLOSE), and as /FILELIST: file. If
Sends all files that match.
.TP
RESEND [ options ] filespec
-Resumes an interrupted SEND from the point of failure.
+Resumes an interupted SEND from the point of failure.
.TP
RECEIVE [ options ] [ as\(hyname ]
Waits passively for files to arrive. Synonym: R.
Sends all files that match.
.TP
RESEND [ options ] filespec
-Resumes an interrupted SEND from the point of failure.
+Resumes an interupted SEND from the point of failure.
.TP
GET [ options ] remote\(hyfilespec
Asks the server to send the given files. Synonym: G.
SEND [ options ] filename [ as-name ] Sends the given file.
Synonym: S.
SEND [ options ] filespec Sends all files that match.
- RESEND [ options ] filespec Resumes an interrupted SEND from the
+ RESEND [ options ] filespec Resumes an interupted SEND from the
point of failure.
RECEIVE [ options ] [ as-name ] Waits passively for files to
arrive. Synonym: R.
SEND [ options ] filename [ as-name ] Sends the given file to
the server. Synonyms: S, PUT.
SEND [ options ] filespec Sends all files that match.
- RESEND [ options ] filespec Resumes an interrupted SEND from the
+ RESEND [ options ] filespec Resumes an interupted SEND from the
point of failure.
GET [ options ] remote-filespec Asks the server to send the
given files. Synonym: G.
" ",
"SET DIAL RETRIES <number>",
" How many times to redial each number if the dialing result is busy or no",
-" no answer, until the call is successfully answered. The default is 0",
+" no answer, until the call is succesfully answered. The default is 0",
" because automatic redialing is illegal in some countries.",
" ",
"SET DIAL INTERVAL <number>",
" ",
"/WRITE",
" Open the file for writing. If /READ was not also specified, this creates",
-" a new file. If /READ was specified, the existing file is preserved, but",
+" a new file. If /READ was specifed, the existing file is preserved, but",
" writing is allowed. In both cases, the read/write pointer is initially",
" at the beginning of the file.",
" ",
"" };
static char *hxyxfer[] = {
-"Syntax: SET TRANSFER (or XFER) parameter value",
+"Syntax: SET TRANSFER (or XFER) paramater value",
" ",
"Choices:",
" ",
#define XYPRIN 62 /* Print-Command */
#define XYQUIE 63 /* Quiet */
#define XYLCLE 64 /* Local-echo */
-#define XYSCRI 65 /* SCRIPT command parameters */
+#define XYSCRI 65 /* SCRIPT command paramaters */
#define XYMSGS 66 /* MESSAGEs ON/OFF */
#ifdef TNCODE
#define XYTEL 67 /* SET TELNET parameters */