blob: a47de15673a7a3e7b60098ae9df64b73770c25e3 [file] [log] [blame]
#include "ckcsym.h"
/* C K U U S 4 -- "User Interface" for C-Kermit, part 4 */
/*
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.
*/
/*
File ckuus4.c -- Functions moved from other ckuus*.c modules to even
out their sizes.
*/
#include "ckcdeb.h"
#include "ckcasc.h"
#include "ckcker.h"
#include "ckcnet.h" /* Network symbols */
#include "ckuusr.h"
#include "ckuver.h"
#include "ckcxla.h" /* Character sets */
#ifdef CK_AUTHENTICATION
#include "ckuath.h"
#endif /* CK_AUTHENTICATION */
#ifdef CK_SSL
#include "ck_ssl.h"
#endif /* CK_SSL */
#ifdef VMS
#include <errno.h> /* For \v(errno) */
extern char * ckvmserrstr(unsigned long);
#ifndef OLD_VMS
#include <lib$routines.h> /* Not for VAX C 2.4 */
#else
#include <libdef.h>
#endif /* OLD_VMS */
_PROTOTYP(int vmsttyfd, (void) );
#endif /* VMS */
#ifdef OS2
#ifndef NT
#define INCL_NOPM
#define INCL_VIO /* Needed for ckocon.h */
#include <os2.h>
#undef COMMENT
#else
#include <windows.h>
#include <tapi.h>
#include "ckntap.h"
#define APIRET ULONG
#endif /* NT */
#include "ckocon.h"
#include "ckoetc.h"
int StartedFromDialer = 0;
HWND hwndDialer = 0;
LONG KermitDialerID = 0;
#ifdef putchar
#undef putchar
#endif /* putchar */
#define putchar(x) conoc(x)
#ifdef CK_PID
#include <process.h>
#endif /* CK_PID */
#endif /* OS2 */
#ifdef KUI
extern struct keytab * term_font;
extern int ntermfont, tt_font, tt_font_size;
#endif /* KUI */
extern xx_strp xxstring;
#ifdef DEC_TCPIP
#include <descrip>
#include <dvidef>
#include <dcdef>
#endif /* DEC_TCPIP */
#ifdef FNFLOAT
#include <math.h> /* Floating-point functions */
#endif /* FNFLOAT */
extern int quiet, network, xitsta, escape, nopush, xferstat,
exitonclose, tn_exit, ttnproto, autodl, flow, byteorder, what, lastxfer;
extern int filepeek, nscanfile, makestrlen;
extern char * k_info_dir;
#ifndef MAC
#ifndef AMIGA
extern int ttyfd;
#endif /* MAC */
#endif /* AMIGA */
#ifdef TNCODE
extern int tn_nlm, tn_b_nlm, tn_b_xfer, tn_sb_bug;
extern int tn_rem_echo;
extern int tn_b_meu, tn_b_ume, tn_auth_krb5_des_bug;
#endif /* TNCODE */
char * xferfile = NULL;
int xferlog = 0;
extern int local, xargc, stayflg, rcflag, bgset, backgrd, cfilef,
inserver, srvcdmsg, success;
#ifdef VMS
extern int batch;
#endif /* VMS */
extern char cmdfil[], *versio, *ckxsys, **xargv;
#ifdef DEBUG
extern char debfil[]; /* Debug log file name */
extern int debtim;
#endif /* DEBUG */
extern int noinit;
static char ndatbuf[10];
char *months[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
char *
zzndate() { /* Returns today's date as yyyymmdd */
char * p = NULL;
int x;
/* WARNING - This will fail if asctime() returns non-English month names */
ztime(&p); /* Get "asctime" string */
if (p == NULL || *p == NUL) return("");
for (x = 20; x < 24; x++) /* yyyy */
ndatbuf[x - 20] = p[x];
ndatbuf[6] = (char) ((p[8] == ' ') ? '0' : p[8]);
ndatbuf[7] = p[9]; /* dd */
for (x = 0; x < 12; x++) /* mm */
if (!strncmp(p+4,months[x],3)) break;
if (x == 12) {
ndatbuf[4] = ndatbuf[5] = '?';
} else {
x++;
ndatbuf[4] = (char) ((x < 10) ? '0' : '1');
ndatbuf[5] = (char) ((x % 10) + 48);
}
ndatbuf[8] = NUL;
debug(F110,"zzndate return",ndatbuf,0);
return((char *)ndatbuf);
}
#ifdef DCMDBUF
extern struct cmdptr *cmdstk;
extern char *line, *tmpbuf;
#else
extern struct cmdptr cmdstk[];
extern char line[], tmpbuf[];
#endif /* DCMDBUF */
#ifdef OS2
extern char exedir[];
#else
extern char * exedir;
#endif /* OS2 */
extern int nettype;
#ifndef NOICP /* Most of this file... */
#ifdef CKLOGDIAL
extern char diafil[];
#endif /* CKLOGDIAL */
#ifndef AMIGA
#ifndef MAC
#include <signal.h>
#endif /* MAC */
#endif /* AMIGA */
#ifdef STRATUS /* Stratus Computer, Inc. VOS */
#ifdef putchar
#undef putchar
#endif /* putchar */
#define putchar(x) conoc(x)
#ifdef getchar
#undef getchar
#endif /* getchar */
#define getchar(x) coninc(0)
#endif /* STRATUS */
#ifdef ANYX25
extern int revcall, closgr, cudata;
int x25ver;
extern char udata[];
#ifndef IBMX25
extern int npadx3;
extern CHAR padparms[];
extern struct keytab padx3tab[];
#endif /* !IBMX25 */
#ifdef IBMX25
/* global variables only available for IBM X.25 - possibly interesting for
* other implementations
*/
extern x25addr_t local_nua;
extern x25addr_t remote_nua;
#endif /* IBMX25 */
#endif /* ANYX25 */
#ifdef NETCONN
#ifndef NODIAL
extern int nnetdir;
extern char *netdir[];
#endif /* NODIAL */
extern char ipaddr[];
#ifdef CK_NETBIOS
extern unsigned short netbiosAvail;
extern unsigned long NetbeuiAPI;
extern unsigned char NetBiosName[];
extern unsigned char NetBiosAdapter;
extern unsigned char NetBiosLSN;
#endif /* CK_NETBIOS */
#ifdef TCPSOCKET
extern char myipaddr[];
extern int tcp_rdns;
#ifdef CK_DNS_SRV
extern int tcp_dns_srv;
#endif /* CK_DNS_SRV */
extern char * tcp_address;
#ifndef NOHTTP
extern char * tcp_http_proxy;
#endif /* NOHTTP */
#ifdef NT
#ifdef CK_SOCKS
extern char * tcp_socks_svr;
#ifdef CK_SOCKS_NS
extern char * tcp_socks_ns;
#endif /* CK_SOCKS_NS */
#endif /* CK_SOCKS */
#endif /* NT */
#ifndef NOTCPOPTS
#ifdef SOL_SOCKET
#ifdef SO_LINGER
extern int tcp_linger;
extern int tcp_linger_tmo;
#endif /* SO_LINGER */
#ifdef SO_DONTROUTE
extern int tcp_dontroute;
#endif /* SO_DONTROUTE */
#ifdef TCP_NODELAY
extern int tcp_nodelay;
#endif /* TCP_NODELAY */
#ifdef SO_SNDBUF
extern int tcp_sendbuf;
#endif /* SO_SNDBUF */
#ifdef SO_RCVBUF
extern int tcp_recvbuf;
#endif /* SO_RCVBUF */
#ifdef SO_KEEPALIVE
extern int tcp_keepalive;
#endif /* SO_KEEPALIVE */
#endif /* SOL_SOCKET */
#endif /* NOTCPOPTS */
#endif /* TCPSOCKET */
#endif /* NETCONN */
extern char * floname[];
#ifndef NOSPL
extern int fndiags; /* Function diagnostics on/off */
extern int divbyzero;
int ispattern = 0;
int isjoin = 0;
#ifdef CK_APC
extern int apcactive; /* Nonzero = APC command was rec'd */
extern int apcstatus; /* Are APC commands being processed? */
#ifdef DCMDBUF
extern char *apcbuf; /* APC command buffer */
#else
extern char apcbuf[];
#endif /* DCMDBUF */
#endif /* CK_APC */
extern char evalbuf[]; /* EVALUATE result */
extern char uidbuf[], pwbuf[], prmbuf[];
_PROTOTYP( static char * fneval, (char *, char * [], int, char * ) );
_PROTOTYP( static VOID myflsh, (void) );
_PROTOTYP( static char * getip, (char *) );
_PROTOTYP( int delta2sec, (char *, long *) );
#ifdef NEWFTP
_PROTOTYP( char * ftp_cpl_mode, (void) );
_PROTOTYP( char * ftp_dpl_mode, (void) );
_PROTOTYP( char * ftp_authtype, (void) );
#endif /* NEWFTP */
#ifndef NOHTTP
_PROTOTYP( char * http_host, (void) );
_PROTOTYP( int http_isconnected, (void) );
_PROTOTYP( char * http_security, (void) );
#endif /* NOHTTP */
#ifndef NOSEXP
_PROTOTYP( char * dosexp, (char *) );
int fsexpflag = 0;
#endif /* NOSEXP */
static char hexdigits[16] = {
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
};
extern char * tempdir;
#ifdef CK_REXX
extern char rexxbuf[];
#endif /* CK_REXX */
extern int tfline[];
/* These need to be internationalized... */
static
char *wkdays[] = {
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
};
#endif /* NOSPL */
#ifdef OS2
extern char startupdir[], inidir[];
#else
#ifdef VMSORUNIX
extern char startupdir[];
#endif /* VMSORUNIX */
#endif /* OS2 */
#ifdef OS2
_PROTOTYP (int os2getcp, (void) );
#ifdef TCPSOCKET
extern char tcpname[];
#endif /* TCPSOCKET */
extern int tcp_avail;
#ifdef DECNET
extern int dnet_avail;
#endif /* DECNET */
#ifdef SUPERLAT
extern int slat_avail;
#endif /* SUPERLAT */
#ifndef NOTERM
extern int tt_type, max_tt;
extern struct tt_info_rec tt_info[];
#endif /* NOTERM */
extern int tt_rows[], tt_cols[];
#else /* OS2 */
extern int tt_rows, tt_cols;
#endif /* OS2 */
#ifdef CK_TAPI
extern int tttapi;
extern int tapipass;
extern struct keytab * tapilinetab;
extern struct keytab * _tapilinetab;
extern int ntapiline;
#endif /* CK_TAPI */
extern struct keytab colxtab[];
extern int ncolx;
extern char ttname[], *zinptr, *kermrc;
extern char inidir[];
extern int activecmd, remonly, cmd_rows, cmd_cols, parity, seslog,
sessft, sosi, hwparity, tsecs, xargs, zincnt, tlevel, insilence, cmdmsk,
timint, timef, inbufsize, dialog, binary, carrier, cdtimo, cmask, duplex,
fmask, inecho, nmac, turnch, turn, kbchar;
#ifndef NOXFER
extern CHAR eol, mypadc, mystch, padch, seol, stchr, * epktmsg, feol;
extern char *cksysid;
extern struct ck_p ptab[];
extern int
protocol, prefixing, xfrbel, xfrcan, xfrint, xfrchr, xfrnum, pktpaus,
lscapr, lscapu, xfermode, dest, slostart, maxrps, maxsps, maxtry, mypadn,
npad, pkttim, bigrbsiz, bigsbsiz, keep, atcapr, autopar, bctr, bctu,
crunched, ckdelay, ebq, ebqflg, pktlog, retrans, rpackets, rptflg, rptq,
rtimo, spackets, spsiz, spsizf, spsizr, timeouts, fncact, fncnv, urpsiz,
wmax, wslotn, wslotr, fdispla, spmax, fnrpath, fnspath, crc16;
#endif /* NOXFER */
#ifdef OS2
extern int zxpn;
extern int viewonly;
#endif /* OS2 */
#ifndef NOXFER
#ifdef GFTIMER
extern CKFLOAT fptsecs, fpxfsecs;
#endif /* GFTIMER */
extern long xfsecs, tfcps;
#ifdef CK_TMPDIR
extern char *dldir;
#endif /* CK_TMPDIR */
#endif /* NOXFER */
#ifdef RECURSIVE
extern int recursive;
#endif /* RECURSIVE */
#ifdef VMS
extern int frecl;
#endif /* VMS */
extern long
ffc, filcnt, rptn, speed, tfc, tlci, tlco, ccu, ccp, vernum, xvernum;
#ifndef NOSPL
extern char fspec[], myhost[];
#endif /* NOSPL */
extern char *tfnam[]; /* Command file names */
extern char pktfil[], /* Packet log file name */
#ifdef TLOG
trafil[], /* Transaction log file name */
#endif /* TLOG */
sesfil[]; /* Session log file name */
#ifndef NOXMIT /* TRANSMIT command variables */
extern char xmitbuf[];
extern int xmitf, xmitl, xmitx, xmits, xmitw, xmitt;
#endif /* NOXMIT */
extern int cmdlvl;
#ifndef NOSPL
/* Script programming language items */
extern char **a_ptr[]; /* Arrays */
extern int a_dim[];
static char * inpmatch = NULL;
#ifdef CKFLOAT
char * inpscale = NULL;
#endif /* CKFLOAT */
extern char * inpbuf, inchar[]; /* Buffers for INPUT and REINPUT */
extern char *inpbp; /* And pointer to same */
static char *r3 = (char *)0;
extern int incount; /* INPUT character count */
extern int m_found; /* MINPUT result */
extern int maclvl; /* Macro invocation level */
extern struct mtab *mactab; /* Macro table */
extern char *mrval[];
extern int macargc[], topargc;
#ifdef COMMENT
extern char *m_line[];
extern char *topline;
#endif /* COMMENT */
extern char *m_arg[MACLEVEL][10]; /* You have to put in the dimensions */
extern char *g_var[GVARS]; /* for external 2-dimensional arrays. */
#ifdef DCMDBUF
extern int *count, *inpcas;
#else
extern int count[], inpcas[];
#endif /* DCMDBUF */
#endif /* NOSPL */
#ifdef UNIX
extern int haslock; /* For UUCP locks */
extern char flfnam[];
#ifndef USETTYLOCK
extern char lock2[];
#endif /* USETTYLOCK */
#endif /* UNIX */
#ifdef OS2ORUNIX
extern int maxnam, maxpath; /* Longest name, path length */
#endif /* OS2ORUNIX */
extern int mdmtyp, mdmsav;
#ifndef NODIAL
/* DIAL-related variables */
extern char modemmsg[];
extern MDMINF *modemp[]; /* Pointers to modem info structs */
extern int nmdm, dialhng, dialtmo, dialksp, dialdpy, dialsrt, dialsta;
extern int dialrtr, dialint, dialrstr, dialcon, dialcq, dialfld;
extern int mdmspd, dialec, dialdc, dialmth, dialmauto, dialesc;
extern char *dialnum, *dialini, *dialdir[], *dialcmd, *dialnpr,
*dialdcon, *dialdcoff, *dialecon, *dialecoff, *dialhcmd, *diallac,
*dialhwfc, *dialswfc, *dialnofc, *dialpulse, *dialtone, *dialname,
*dialaaon, *dialaaoff, *dialmac;
extern char *diallcc, *dialixp, *dialixs, *dialldp, *diallds,
*dialpxi, *dialpxo, *dialsfx, *dialtfp;
extern char *diallcp, *diallcs;
extern int ntollfree, ndialpxx, nlocalac;
extern char *dialtfc[], *diallcac[], *dialpxx[], *matchpxx;
extern int ndialpucc, ndialtocc;
extern char *dialtocc[], *dialpucc[];
extern int ndialdir, dialcnf, dialcvt, dialidt, dialpace;
extern long dialmax, dialcapas;
extern struct keytab mdmtab[];
#ifdef BIGBUFOK
#define ARGBUFSIZ 8191
#else
#define ARGBUFSIZ 1023
#endif /* BIGBUFOK */
#ifdef BIGBUFOK
extern char * dialmsg[];
#endif /* BIGBUFOK */
#endif /* NODIAL */
#ifndef NOCSETS
/* Translation stuff */
extern int fcharset, tcharset, tslevel, language, nlng, tcsr, tcsl;
extern int dcset7, dcset8;
extern struct keytab lngtab[];
extern struct csinfo fcsinfo[], tcsinfo[];
extern struct langinfo langs[];
#ifdef CK_ANSIC
extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(CHAR); /* Character set */
extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(CHAR); /* translation functions */
#else
extern CHAR (*xls[MAXTCSETS+1][MAXFCSETS+1])(); /* Character set */
extern CHAR (*xlr[MAXTCSETS+1][MAXFCSETS+1])(); /* translation functions. */
#endif /* CK_ANSIC */
#ifdef UNICODE
extern int ucsbom, ucsorder;
#endif /* UNICODE */
#endif /* NOCSETS */
#ifndef NOSPL
/* Built-in variable names, maximum length VNAML (20 characters) */
struct keytab vartab[] = {
{ "_line", VN_TFLN, CM_INV}, /* 192 */
#ifdef OS2
{ "_regname", VN_REGN, CM_INV}, /* 1.1.12 */
{ "_regorg", VN_REGO, CM_INV}, /* 1.1.12 */
{ "_regnum", VN_REGS, CM_INV}, /* 1.1.12 */
#endif /* OS2 */
{ "apcactive", VN_APC, CM_INV}, /* 192 */
#ifdef NT
{ "appdata", VN_APPDATA, 0}, /* 201 */
#endif /* NT */
{ "argc", VN_ARGC, 0},
{ "args", VN_ARGS, 0},
{ "authname", VN_AUTHN, 0}, /* 196 */
{ "authstate", VN_AUTHS, 0}, /* 195 */
{ "authtype", VN_AUTHT, 0}, /* 195 */
{ "blockcheck",VN_BLK, 0}, /* 195 */
#ifdef BROWSER
{ "browser", VN_BROWSR,0}, /* 193 */
{ "browsopts", VN_BROPT, 0}, /* 193 */
{ "browsurl", VN_URL, 0}, /* 193 */
{ "buildid", VN_BUILD, 0}, /* 199 */
#endif /* BROWSER */
{ "byteorder", VN_BYTE, 0}, /* 195 */
#ifndef NOCSETS
{ "charset", VN_CSET, 0}, /* 192 */
#endif /* NOCSETS */
{ "cmdbufsize",VN_CMDBL, 0}, /* 195 */
{ "cmdfile", VN_CMDF, 0},
{ "cmdlevel", VN_CMDL, 0},
{ "cmdsource", VN_CMDS, 0},
{ "cols", VN_COLS, 0}, /* 190 */
#ifdef NT
{ "common", VN_COMMON, 0}, /* 201 */
#endif /* NT */
{ "connection",VN_CONN, 0}, /* 190 */
{ "count", VN_COUN, 0},
#ifndef NOXFER
{ "cps", VN_CPS, 0}, /* 190 */
#endif /* NOXFER */
{ "cpu", VN_CPU, 0},
#ifndef NOXFER
{ "crc16", VN_CRC16, 0}, /* 192 */
{ "ctty", VN_TTYNAM,0}, /* 196 */
#endif /* NOXFER */
#ifndef NOLOGDIAL
#ifndef NOLOCAL
{ "cx_time", VN_CXTIME,0}, /* 195 */
{ "cx_status", VN_CX_STA,0}, /* 199 */
#endif /* NOLOCAL */
#endif /* NOLOGDIAL */
#ifndef NODIAL
{ "d$ac", VN_D_AC, 0}, /* 192 */
{ "d$cc", VN_D_CC, 0}, /* 192 */
{ "d$ip", VN_D_IP, 0}, /* 192 */
{ "d$lc", VN_D_LCP, 0}, /* 193 */
{ "d$lcp", VN_D_LCP, CM_INV}, /* 193 */
{ "d$lp", VN_D_LP, 0}, /* 192 */
{ "d$px", VN_D_PXX, 0}, /* 195 */
{ "d$pxx", VN_D_PXX, CM_INV}, /* 195 */
#endif /* NODIAL */
{ "date", VN_DATE, 0},
{ "day", VN_DAY, 0},
#ifdef NT
{ "desktop", VN_DESKTOP, 0}, /* 201 */
#endif /* NT */
#ifndef NODIAL
{ "dialcount", VN_DRTR, 0}, /* 195 */
{ "dialnumber",VN_DNUM, 0}, /* 192 */
{ "dialresult",VN_MDMSG, 0}, /* 192 */
{ "dialstatus",VN_DIAL, 0}, /* 190 */
{ "dialsuffix",VN_PDSFX, 0}, /* 193 */
{ "dialtype", VN_DTYPE, 0}, /* 193 */
#endif /* NODIAL */
{ "directory", VN_DIRE, 0},
#ifndef NODIAL
{ "dm_hf", VN_DM_HF, 0}, /* 199 */
{ "dm_lp", VN_DM_LP, 0}, /* 195 */
{ "dm_sp", VN_DM_SP, 0}, /* 195 */
{ "dm_pd", VN_DM_PD, 0}, /* 195 */
{ "dm_td", VN_DM_TD, 0}, /* 195 */
{ "dm_wa", VN_DM_WA, 0}, /* 195 */
{ "dm_wb", VN_DM_WB, 0}, /* 199 */
{ "dm_wd", VN_DM_WD, 0}, /* 195 */
{ "dm_rc", VN_DM_RC, 0}, /* 195 */
#endif /* NODIAL */
#ifndef NOXFER
{ "download", VN_DLDIR, 0}, /* 192 */
#endif /* NOXFER */
{ "editor", VN_EDITOR,0},
{ "editfile", VN_EDFILE,0},
{ "editopts", VN_EDOPT, 0},
{ "errno", VN_ERRNO, 0}, /* 192 */
{ "errstring", VN_ERSTR, 0}, /* 192 */
{ "escape", VN_ESC, 0}, /* 193 */
{ "evaluate", VN_EVAL, 0}, /* 190 */
#ifdef OS2ORUNIX
{ "exedir", VN_EXEDIR,0}, /* 192 */
#endif /* OS2ORUNIX */
{ "exitstatus",VN_EXIT, 0},
#ifdef CKCHANNELIO
{ "f_count", VN_FCOU, 0}, /* 195 */
{ "f_error", VN_FERR, 0}, /* 195 */
{ "f_max", VN_FMAX, 0}, /* 195 */
{ "fileerror", VN_FERR, CM_INV}, /* 195 */
{ "filemax", VN_FERR, CM_INV}, /* 195 */
#endif /* CKCHANNELIO */
{ "filename", VN_FNAM, 0}, /* 193 */
{ "filenumber",VN_FNUM, 0}, /* 193 */
{ "filespec", VN_FILE, 0},
{ "fsize", VN_FFC, 0}, /* 190 */
#ifdef GFTIMER
{ "ftime", VN_FTIME, 0}, /* 199 */
#else
{ "ftime", VN_NTIM, CM_INV},
#endif /* GFTIMER */
#ifndef NOFTP
#ifndef SYSFTP
{ "ftp_code", VN_FTP_C, 0}, /* 199 */
{ "ftp_cpl", VN_FTP_B, 0}, /* 199 */
{ "ftp_connected", VN_FTP_X, 0}, /* 199 */
{ "ftp_dpl", VN_FTP_D, 0}, /* 199 */
{ "ftp_getputremote", VN_FTP_G, 0}, /* 199 */
{ "ftp_host", VN_FTP_H, 0}, /* 199 */
{ "ftp_loggedin", VN_FTP_L, 0}, /* 199 */
{ "ftp_message", VN_FTP_M, 0}, /* 199 */
{ "ftp_msg", VN_FTP_M, CM_INV}, /* 199 */
{ "ftp_security", VN_FTP_Z, 0}, /* 199 */
{ "ftp_server", VN_FTP_S, 0}, /* 199 */
#endif /* SYSFTP */
#endif /* NOFTP */
{ "ftype", VN_MODE, 0}, /* 190 */
#ifdef KUI
{ "gui_fontname", VN_GUI_FNM, 0}, /* 205 */
{ "gui_fontsize", VN_GUI_FSZ, 0}, /* 205 */
{ "gui_runmode", VN_GUI_RUN, 0}, /* 205 */
{ "gui_xpos", VN_GUI_XP, 0}, /* 205 */
{ "gui_xres", VN_GUI_XR, 0}, /* 205 */
{ "gui_ypos", VN_GUI_YP, 0}, /* 205 */
{ "gui_yres", VN_GUI_YR, 0}, /* 205 */
#endif /* KUI */
{ "herald", VN_HERALD, 0},
{ "home", VN_HOME, 0},
{ "host", VN_HOST, 0},
{ "hour", VN_HOUR, 0}, /* 200 */
#ifndef NOHTTP
{ "http_code", VN_HTTP_C, 0}, /* 199 */
{ "http_connected", VN_HTTP_N, 0}, /* 199 */
{ "http_host", VN_HTTP_H, 0}, /* 199 */
{ "http_message", VN_HTTP_M, 0}, /* 199 */
{ "http_security", VN_HTTP_S, 0}, /* 199 */
#endif /* NOHTTP */
{ "hwparity", VN_HWPAR, 0}, /* 195 */
{ "input", VN_IBUF, 0},
{ "inchar", VN_ICHR, 0},
{ "incount", VN_ICNT, 0},
{ "inidir", VN_INI, 0}, /* 192 */
{ "inmatch", VN_MATCH, 0}, /* 196 */
{ "inscale", VN_ISCALE,0}, /* 210 */
{ "instatus", VN_ISTAT, 0}, /* 192 */
{ "intime", VN_INTIME,0}, /* 193 */
{ "inwait", VN_INTMO, 0}, /* 195 */
{ "ip", VN_IPADDR, CM_ABR|CM_INV},
{ "ipaddress", VN_IPADDR,0}, /* 192 */
{ "iprompt", VN_PROMPT,0}, /* 199 */
{ "kbchar", VN_KBCHAR,0}, /* 196 */
#ifndef NOLOCAL
#ifdef OS2
{ "keyboard", VN_KEYB, 0},
#endif /* OS2 */
#endif /* NOLOCAL */
#ifdef CK_KERBEROS
{ "krb4errmsg", VN_K4EMSG,0},
{ "krb4errno", VN_K4ENO, 0},
{ "krb4principal", VN_K4PRN, 0},
{ "krb4realm", VN_K4RLM, 0},
{ "krb4service", VN_K4SRV, 0},
{ "krb5cc", VN_K5CC, 0},
{ "krb5errmsg", VN_K5EMSG,0},
{ "krb5errno", VN_K5ENO, 0},
{ "krb5principal", VN_K5PRN, 0},
{ "krb5realm", VN_K5RLM, 0},
{ "krb5service", VN_K5SRV, 0},
#endif /* CK_KERBEROS */
{ "line", VN_LINE, 0},
{ "local", VN_LCL, 0},
#ifdef UNIX
{ "lockdir", VN_LCKDIR,0}, /* 195 */
{ "lockpid", VN_LCKPID,0}, /* 195 */
#endif /* UNIX */
{ "log_connection", VN_LOG_CON, 0}, /* 206 */
{ "log_debug", VN_LOG_DEB, 0}, /* 206 */
{ "log_packet", VN_LOG_PKT, 0}, /* 206 */
{ "log_session", VN_LOG_SES, 0}, /* 206 */
{ "log_transaction", VN_LOG_TRA, 0},/* 206 */
{ "maclevel", VN_MACLVL,0}, /* 195 */
{ "macro", VN_MAC, 0},
#ifdef FNFLOAT
{ "math_e", VN_MA_E, 0}, /* 195 */
{ "math_pi", VN_MA_PI, 0}, /* 195 */
{ "math_precision", VN_MA_PR, 0}, /* 195 */
#endif /* FNFLOAT */
{ "minput", VN_MINP, 0}, /* 192 */
{ "model", VN_MODL, 0}, /* 193 */
{ "modem", VN_MDM, 0},
#ifndef NOLOCAL
#ifdef OS2
{ "mousecurx", VN_MOU_X, 0}, /* K95 1.1.14 */
{ "mousecury", VN_MOU_Y, 0}, /* K95 1.1.14 */
#endif /* OS2 */
#endif /* NOLOCAL */
#ifndef NODIAL
{ "m_aa_off", VN_M_AAX, 0}, /* all 192... */
{ "m_aa_on", VN_M_AAO, 0},
{ "m_dc_off", VN_M_DCX, 0},
{ "m_dc_on", VN_M_DCO, 0},
{ "m_dial", VN_M_DCM, 0},
{ "m_ec_off", VN_M_ECX, 0},
{ "m_ec_on", VN_M_ECO, 0},
{ "m_fc_hw", VN_M_HWF, 0},
{ "m_fc_no", VN_M_NFC, 0},
{ "m_fc_sw", VN_M_SWF, 0},
{ "m_hup", VN_M_HUP, 0},
{ "m_init", VN_M_INI, 0},
{ "m_name", VN_M_NAM, 0}, /* 195 */
{ "m_pulse", VN_M_PDM, 0},
{ "m_sig_cd", VN_MS_CD, 0}, /* 195 */
{ "m_sig_cts", VN_MS_CTS,0}, /* 195 */
{ "m_sig_dsr", VN_MS_DSR,0}, /* 195 */
{ "m_sig_dtr", VN_MS_DTR,0}, /* 195 */
{ "m_sig_ri", VN_MS_RI, 0}, /* 195 */
{ "m_sig_rts", VN_MS_RTS,0}, /* 195 */
{ "m_tone", VN_M_TDM, 0},
#endif /* NODIAL */
{ "name", VN_NAME, 0},
{ "ndate", VN_NDAT, 0},
{ "nday", VN_NDAY, 0},
{ "newline", VN_NEWL, 0},
{ "ntime", VN_NTIM, 0},
{ "osname", VN_OSNAM, 0}, /* 193 */
{ "osrelease", VN_OSREL, 0}, /* 193 */
{ "osversion", VN_OSVER, 0}, /* 193 */
#ifndef NOXFER
{ "packetlen", VN_RPSIZ, 0}, /* 192 */
#endif /* NOXFER */
{ "parity", VN_PRTY, 0}, /* 190 */
{ "password", VN_PWD, CM_INV}, /* 192 */
#ifdef NT
{ "personal", VN_PERSONAL, 0}, /* 201 */
#endif /* NT */
#ifdef PEXITSTAT
{ "pexitstat", VN_PEXIT, 0}, /* 193 */
#endif /* PEXITSTAT */
#ifdef CK_PID
{ "pid", VN_PID, 0}, /* 193 */
#endif /* CK_PID */
{ "platform", VN_SYSV, 0},
{ "printer", VN_PRINT, 0}, /* 193 */
{ "program", VN_PROG, 0},
{ "prompt", VN_PRM, CM_INV}, /* 192 */
#ifndef NOXFER
{ "protocol", VN_PROTO, 0}, /* 192 */
{ "p_8bit", VN_P_8BIT,0}, /* 193 */
{ "p_ctl", VN_P_CTL, 0}, /* 193 */
{ "p_rpt", VN_P_RPT, 0}, /* 193 */
{ "query", VN_QUE, 0}, /* 190 */
#endif /* NOXFER */
{ "return", VN_RET, 0},
#ifdef CK_REXX
{ "rexx", VN_REXX, 0}, /* 190 */
#endif /* CK_REXX */
#ifdef TN_COMPORT
{ "rfc2217_signature", VN_TNC_SIG, 0}, /* 201 */
{ "rfc2717_signature", VN_TNC_SIG, CM_INV}, /* 202 */
#endif /* TN_COMPORT */
{ "rows", VN_ROWS, 0}, /* 190 */
#ifndef NOSEXP
{ "sdepth", VN_LSEXP,0}, /* 199 */
#endif /* NOSEXP */
{ "secure", VN_SECURE, 0}, /* 199 */
#ifndef NOLOCAL
#ifdef OS2
{ "select", VN_SELCT, 0}, /* 192 */
#endif /* OS2 */
#endif /* NOLOCAL */
{ "sendlist", VN_SNDL, 0},
{ "serial", VN_SERIAL,0}, /* 195 */
{ "setlinemsg",VN_SLMSG, 0}, /* 195 */
#ifndef NOSEXP
{ "sexpression",VN_SEXP, 0}, /* 199 */
#endif /* NOSEXP */
{ "speed", VN_SPEE, 0},
#ifdef OS2
{ "space", VN_SPA, 0},
{ "startup", VN_STAR, 0}, /* 190 */
#else
#ifdef UNIX
{ "startup", VN_STAR, 0}, /* 193 */
#else
#ifdef VMS
{ "startup", VN_STAR, 0}, /* 193 */
#endif /* VMS */
#endif /* UNIX */
#endif /* OS2 */
{ "status", VN_SUCC, 0},
#ifndef NOSEXP
{ "svalue", VN_VSEXP, 0}, /* 199 */
#endif /* NOSEXP */
#ifndef NOXFER
{ "sysid", VN_SYSI, 0},
#endif /* NOXFER */
{ "system", VN_SYST, 0},
{ "terminal", VN_TTYP, 0},
#ifdef OS2
#ifndef NOKVERBS
{ "termkey", VN_TRMK, CM_INV}, /* 192 */
#endif /* NOKVERBS */
#endif /* OS2 */
{ "test", VN_TEST, 0}, /* 193 */
{ "textdir", VN_TXTDIR,0}, /* 195 */
#ifndef NOXFER
{ "tfsize", VN_TFC, 0},
{ "tftime", VN_TFTIM, 0}, /* 195 */
#endif /* NOXFER */
{ "time", VN_TIME, 0},
{ "timestamp", VN_NOW, 0}, /* 200 */
{ "tmpdir", VN_TEMP, 0}, /* 192 */
#ifdef CK_TRIGGER
{ "trigger", VN_TRIG, 0}, /* 193 */
#endif /* CK_TRIGGER */
#ifdef CK_TTYFD
{ "ttyfd", VN_TTYF, 0},
#endif /* CK_TTYFD */
{ "ty_ln", VN_TY_LN, 0}, /* 195 */
{ "ty_lc", VN_TY_LC, 0}, /* 195 */
{ "ty_lm", VN_TY_LM, 0}, /* 195 */
#ifdef BROWSER
{ "url", VN_URL, CM_INV}, /* 193 */
#endif /* BROWSER */
{ "userid", VN_UID, 0}, /* 192 */
{ "version", VN_VERS, 0},
#ifndef NOXFER
{ "window", VN_WINDO, 0}, /* 192 */
#endif /* NOXFER */
#ifdef IBMX25
{ "x25local_nua", VN_X25LA, 0}, /* 193 */
{ "x25remote_nua", VN_X25RA, 0}, /* 193 */
#endif /* IBMX25 */
#ifdef CK_SSL
{ "x509_issuer", VN_X509_I, 0},
{ "x509_subject", VN_X509_S, 0},
#endif /* CK_SSL */
#ifndef NOXFER
{ "xferstatus",VN_XFSTAT,0}, /* 193 */
{ "xfermsg", VN_XFMSG, 0}, /* 193 */
{ "xfer_badpackets", VN_XF_BC, 0}, /* 195 */
{ "xfer_timeouts", VN_XF_TM, 0}, /* 195 */
{ "xfer_retransmits",VN_XF_RX, 0}, /* 195 */
#endif /* NOXFER */
{ "xprogram", VN_XPROG, 0}, /* 193 */
{ "xversion", VN_XVNUM, 0} /* 192 */
};
int nvars = (sizeof(vartab) / sizeof(struct keytab));
#endif /* NOSPL */
#ifndef NOSPL
struct keytab fnctab[] = { /* Function names */
#ifdef OS2
{ ".oox", FN_OOX, CM_INV}, /* ... */
#endif /* OS2 */
#ifdef CKCHANNELIO
{ "_eof", FN_FEOF, 0},
{ "_errmsg", FN_FERMSG, 0},
{ "_getblock", FN_FGBLK, 0},
{ "_getchar", FN_FGCHAR, 0},
{ "_getline", FN_FGLINE, 0},
{ "_handle", FN_FILNO, 0},
{ "_line", FN_NLINE, 0},
{ "_pos", FN_FPOS, 0},
{ "_putblock", FN_FPBLK, 0},
{ "_putchar", FN_FPCHAR, 0},
{ "_putline", FN_FPLINE, 0},
{ "_status", FN_FSTAT, 0},
#endif /* CKCHANNELIO */
{ "aaconvert", FN_AADUMP, 0}, /* Associative Array conversion */
{ "absolute", FN_ABS, 0}, /* Absolute value */
#ifdef TCPSOCKET
{ "addr2name", FN_HSTADD,CM_INV}, /* IP Address to Hostname */
{ "addrtoname", FN_HSTADD,CM_INV}, /* IP Address to Hostname */
#endif /* TCPSOCKET */
{ "arraylook", FN_ALOOK,0}, /* Array lookup */
{ "b64decode", FN_FMB64,0}, /* Base-64 conversion */
{ "b64encode", FN_TOB64,0}, /* ... */
{ "basename", FN_BSN, 0}, /* Basename */
{ "break", FN_BRK, 0}, /* Break (as in Snobol) */
{ "ca", FN_CAP, CM_INV|CM_ABR}, /* Abbreviation for capitablize */
{ "cap", FN_CAP, CM_INV|CM_ABR}, /* Abbreviation for capitablize */
{ "capitalize", FN_CAP, 0}, /* First Letter -> uppercase */
{ "caps", FN_CAP, CM_INV}, /* ditto */
{ "character", FN_CHR, 0}, /* Character from code */
{ "checksum", FN_CHK, 0}, /* Checksum */
{ "cmdstack", FN_CMDSTK,0}, /* Command stack */
{ "cmpdates", FN_CMPDATE,0}, /* Compare dates */
{ "code", FN_COD, 0}, /* Code from character */
#ifndef NOPUSH
{ "command", FN_CMD, 0}, /* Output from a command */
#endif /* NOPUSH */
{ "contents", FN_CON, 0}, /* Definition (contents) of variable */
{ "crc16", FN_CRC, 0}, /* CRC-16 */
#ifdef OS2
{ "crypt", FN_CRY, CM_INV},
#endif /* OS2 */
{ "cvtdate", FN_DTIM, 0}, /* Convert free date/time to std */
#ifdef ZFCDAT
{ "date", FN_FD, 0}, /* File modification/creation date */
#endif /* ZFCDAT */
{ "day", FN_DAY, 0}, /* Day of week */
{ "dayofyear", FN_JDATE,0}, /* Date to Day of Year */
{ "definition", FN_DEF, 0}, /* Return definition of given macro */
{ "delta2secs", FN_DELSEC, 0}, /* Delta time to seconds */
{ "deltatosecs", FN_DELSEC, CM_INV}, /* Delta time to seconds */
#ifndef NODIAL
{ "dialconvert",FN_PNCVT,0}, /* Convert portable phone number */
#endif /* NODIAL */
{ "diffdates", FN_DIFDATE,0}, /* Difference of two date-times */
{ "dimension", FN_DIM, 0}, /* Dimension of array */
{ "directories",FN_DIR, 0}, /* List of directories */
{ "dirname", FN_DNAM, 0}, /* Directory part of filename */
{ "dos2unixpath",FN_PC_DU, }, /* DOS to UNIX path */
{ "dostounixpath",FN_PC_DU, CM_INV}, /* DOS to UNIX path */
{ "doy", FN_JDATE,CM_INV}, /* Date to Day of Year */
{ "doy2date", FN_DATEJ,0}, /* Day of Year to date */
{ "doytodate", FN_DATEJ,CM_INV}, /* Day of Year to date */
#ifdef FN_ERRMSG
{ "errstring", FN_ERRMSG,0}, /* Error code to message */
#endif /* FN_ERRMSG */
{ "evaluate", FN_EVA, 0}, /* Evaluate given arith expression */
{ "execute", FN_EXE, 0}, /* Execute given macro */
{ "files", FN_FC, 0}, /* File count */
#ifdef FNFLOAT
{ "fpabsolute", FN_FPABS, 0}, /* Floating-point absolute value */
{ "fpadd", FN_FPADD, 0}, /* FP add */
{ "fpcosine", FN_FPCOS, 0}, /* FP cosine */
{ "fpdivide", FN_FPDIV, 0}, /* FP divide */
{ "fpexp", FN_FPEXP, 0}, /* FP e to the x */
{ "fpint", FN_FPINT, 0}, /* FP to integer */
{ "fplog10", FN_FPLOG, 0}, /* FP base-10 logarithm */
{ "fplogn", FN_FPLN, 0}, /* FP natural logarithm */
{ "fpmaximum", FN_FPMAX, 0}, /* FP maxinum */
{ "fpminimum", FN_FPMIN, 0}, /* FP mininum */
{ "fpmodulus", FN_FPMOD, 0}, /* FP modulus */
{ "fpmultiply", FN_FPMUL, 0}, /* FP multiply */
{ "fpraise", FN_FPPOW, 0}, /* FP raise to a power */
{ "fpround", FN_FPROU, 0}, /* FP round */
{ "fpsine", FN_FPSIN, 0}, /* FP sine */
{ "fpsqrt", FN_FPSQR, 0}, /* FP square root */
{ "fpsubtract", FN_FPSUB, 0}, /* FP subtract */
{ "fptangent", FN_FPTAN, 0}, /* FP tangent */
#endif /* FNFLOAT */
{ "hex2ip", FN_HEX2IP,0}, /* Hex to IP address */
{ "hextoip", FN_HEX2IP,CM_INV}, /* Hex to IP address */
{ "hex2n", FN_HEX2N, CM_INV}, /* Hex to decimal number */
{ "hexify", FN_HEX, 0}, /* Hexify (string) */
{ "index", FN_IND, 0}, /* Index (string search) */
{ "ip2hex", FN_IP2HEX,0}, /* IP address to hex */
{ "iptohex", FN_IP2HEX,CM_INV}, /* IP address to hex */
{ "ipaddress", FN_IPA, 0}, /* Find and return IP address */
{ "jdate", FN_JDATE, CM_INV}, /* Date to Day of Year */
{ "join", FN_JOIN, 0}, /* Join array elements */
{ "keywordvalue", FN_KWVAL, 0}, /* Keyword=Value */
#ifdef CK_KERBEROS
{ "krbflags", FN_KRB_FG, 0}, /* Kerberos functions */
{ "krbisvalid", FN_KRB_IV, 0},
{ "krbnextticket", FN_KRB_NX, 0},
{ "krbtickets", FN_KRB_TK, 0},
{ "krbtimeleft", FN_KRB_TT, 0},
#endif /* CK_KERBEROS */
{ "left", FN_LEF, 0}, /* Leftmost n characters of string */
{ "length", FN_LEN, 0}, /* Return length of argument */
{ "literal", FN_LIT, 0}, /* Return argument literally */
#ifdef NT
{ "longpathname",FN_LNAME,0}, /* GetLongPathName() */
#else
{ "longpathname",FN_FFN,CM_INV},
#endif /* NT */
{ "lop", FN_STL, 0}, /* Lop */
{ "lower", FN_LOW, 0}, /* Return lowercased argument */
{ "lpad", FN_LPA, 0}, /* Return left-padded argument */
{ "ltrim", FN_LTR, 0}, /* Left-Trim */
{ "maximum", FN_MAX, 0}, /* Return maximum of two arguments */
{ "minimum", FN_MIN, 0}, /* Return minimum of two arguments */
{ "mjd", FN_MJD, 0}, /* Date to Modified Julian Date */
{ "mjd2date", FN_MJD2, 0}, /* MJD to Date */
{ "mjdtodate", FN_MJD2, CM_INV}, /* MJD to Date */
{ "modulus", FN_MOD, 0}, /* Return modulus of two arguments */
#ifdef COMMENT
{ "msleep", FN_MSLEEP,0}, /* Sleep for n milliseconds */
#endif /* COMMENT */
{ "n2hex", FN_2HEX, CM_INV}, /* Number to hex */
{ "n2octal", FN_2OCT, CM_INV}, /* Number to octal */
{ "n2time", FN_N2TIM,0}, /* Number to hh:mm:ss */
#ifdef TCPSOCKET
{ "name2addr", FN_HSTNAM,CM_INV}, /* Hostname to IP Address */
#endif /* TCPSOCKET */
{ "nday", FN_NDAY, 0}, /* Numeric day of week */
{ "nextfile", FN_FIL, 0}, /* Next file in list */
{ "ntime", FN_NTIM, 0}, /* Time to seconds since midnight */
{ "ntohex", FN_2HEX, CM_INV}, /* Number to hex */
{ "ntooctal", FN_2OCT, CM_INV}, /* Number to octal */
{ "ntotime", FN_N2TIM,CM_INV}, /* Number to hh:mm:ss */
{ "oct2n", FN_OCT2N,CM_INV}, /* Octal to decimal number */
{ "octton", FN_OCT2N,CM_INV}, /* Octal to decimal number */
{ "pathname", FN_FFN, 0}, /* Full file name */
{ "pattern", FN_PATTERN, 0}, /* Pattern (for INPUT) */
#ifdef CK_PERMS
{ "permissions",FN_PERM, 0}, /* Permissions of file */
#else
{ "permissions",FN_PERM, CM_INV}, /* Permissions of file */
#endif /* CK_PERMS */
{ "radix", FN_RADIX,0}, /* Radix conversion */
#ifndef NORANDOM
{ "random", FN_RAND, 0}, /* Random number */
#endif /* NORANDOM */
#ifndef NOPUSH
{ "rawcommand", FN_RAW, 0}, /* Output from a command (raw) */
#endif /* NOPUSH */
#ifdef RECURSIVE
{ "rdirectories", FN_RDIR, 0}, /* Recursive directory list */
{ "rfiles", FN_RFIL, 0}, /* Recursive file list */
#endif /* RECURSIVE */
{ "rep", FN_REP, CM_INV|CM_ABR},
{ "repeat", FN_REP, 0}, /* Repeat argument given # of times */
{ "replace", FN_RPL, 0}, /* Replace characters in string */
{ "reverse", FN_REV, 0}, /* Reverse the argument string */
{ "right", FN_RIG, 0}, /* Rightmost n characters of string */
{ "rindex", FN_RIX, 0}, /* Right index */
{ "rpad", FN_RPA, 0}, /* Right-pad the argument */
{ "rsearch", FN_RSEARCH, 0}, /* R-L Search for pattern in string */
#ifdef OS2
{ "scrncurx", FN_SCRN_CX, 0}, /* Screen Cursor X Pos */
{ "scrncury", FN_SCRN_CY, 0}, /* Screen Cursor Y Pos */
{ "scrnstr", FN_SCRN_STR, 0}, /* Screen String */
#endif /* OS2 */
{ "search", FN_SEARCH, 0}, /* L-R Search for pattern in string */
#ifndef NOSEXP
{ "sexpression",FN_SEXP, 0}, /* S-Expression */
#endif /* NOSEXP */
#ifdef NT
{ "shortpathname",FN_SNAME,0}, /* GetShortPathName() */
#else
{ "shortpathname",FN_FFN,CM_INV},
#endif /* NT */
{ "size", FN_FS, 0}, /* File size */
#ifdef COMMENT
{ "sleep", FN_SLEEP,0}, /* Sleep for n seconds */
#endif /* COMMENT */
{ "span", FN_SPN, 0}, /* Span - like Snobol */
{ "split", FN_SPLIT,0}, /* Split string into words */
{ "stripb", FN_STB, 0}, /* Strip enclosing braces/brackets */
{ "stripn", FN_STN, 0}, /* Strip n chars */
{ "stripx", FN_STX, 0}, /* Strip suffix */
{ "su", FN_SUB, CM_INV|CM_ABR},
{ "sub", FN_SUB, CM_INV|CM_ABR},
{ "subs", FN_SUB, CM_INV|CM_ABR},
{ "subst", FN_SUB, CM_INV|CM_ABR},
{ "substitute", FN_SUBST,0}, /* Substitute chars */
{ "substring", FN_SUB, 0}, /* Extract substring from argument */
{ "tablelook", FN_TLOOK,0}, /* Table lookup */
{ "time", FN_TIME, 0}, /* Free-format time to hh:mm:ss */
{ "tod2secs", FN_NTIM, CM_INV}, /* Time-of-day-to-secs-since-midnite */
{ "todtosecs", FN_NTIM, CM_INV}, /* Time-of-day-to-secs-since-midnite */
{ "trim", FN_TRM, 0}, /* Trim */
{ "unhexify", FN_UNH, 0}, /* Unhexify */
{ "unix2dospath",FN_PC_UD, 0}, /* UNIX to DOS path */
{ "unixtodospath",FN_PC_UD, CM_INV}, /* UNIX to DOS path */
{ "untabify", FN_UNTAB,0}, /* Untabify */
{ "upper", FN_UPP, 0}, /* Return uppercased argument */
{ "utcdate", FN_TOGMT,0}, /* Date-time to UTC (GMT) */
{ "verify", FN_VER, 0}, /* Verify */
{ "word", FN_WORD, 0}, /* Extract a word */
{ "", 0, 0}
};
int nfuncs = (sizeof(fnctab) / sizeof(struct keytab)) - 1;
#endif /* NOSPL */
#ifndef NOSPL /* Buffer for expansion of */
#ifdef BIGBUFOK /* built-in variables. */
#define VVBUFL 1024
#else
#define VVBUFL 256
#endif /* BIGBUFOK */
char vvbuf[VVBUFL+1];
#endif /* NOSPL */
struct keytab disptb[] = { /* Log file disposition */
{ "append", 1, 0},
{ "new", 0, 0}
};
#ifdef CKFLOAT
/* I N I T F L O A T -- Deduce floating-point precision by inspection */
int fp_rounding = 0; /* Nonzero if printf("%f") rounds */
int fp_digits = 0; /* Digits of floating point precision */
#ifdef COMMENT
/* For looking at internal floating-point representations */
static char fp_xbuf[128];
static char *
tohex(s, n) CHAR * s; int n; {
int x;
char * p = fp_xbuf;
while (n-- > 0) {
x = (*s >> 4) & 0x0f;
*p++ = hexdigits[x];
x = *s++ & 0x0f;
*p++ = hexdigits[x];
}
*p = NUL;
return((char *)fp_xbuf);
}
#endif /* COMMENT */
char math_pi[] = "3.1415926535897932384626433832795";
char math_e[] = "2.7182818284590452353602874713527";
VOID
initfloat() {
char * buf = NULL;
int i, x, y;
/*
We malloc a big temporary buffer for sprintf() to minimize likelihood of
(and damage from) sprintf buffer overflows. In any case, the only way this
could happen would be if sprintf() itself had bugs, since the format
descriptor says to cut it off at 250 decimal places.
*/
if ((buf = (char *)malloc(4096))) {
sprintf(buf,"%0.250f",(10.0 / 3.0));
for (i = 2; i < 250 && buf[i] == '3'; i++) ;
x = i - 1;
debug(F111,"initfloat 10.0/3.0",buf,x);
sprintf(buf,"%0.250f",(4.0 / 9.0));
for (i = 2; i < 250 && buf[i] == '4'; i++) ;
y = i - 1;
debug(F111,"initfloat 4.0/9.0",buf,y);
fp_digits = (x < y) ? x : y;
if (fp_digits < sizeof(math_pi) - 1) {
math_pi[fp_digits+1] = NUL;
math_e[fp_digits+1] = NUL;
}
sprintf(buf,"%0.6f",(7.0 / 9.0));
if (buf[7] == '8') fp_rounding = 1;
debug(F111,"initfloat 7.0/9.0",buf,fp_rounding);
debug(F101,"initfloat precision","",fp_digits);
free(buf);
}
}
#endif /* CKFLOAT */
/*
P R E S C A N -- A quick look through the command-line options for
items that must be handled before the initialization file is executed.
*/
#ifdef NT
extern int StartedFromDialer;
#endif /* NT */
#ifdef OS2
extern int k95stdio;
unsigned long startflags = 0L;
#endif /* OS2 */
static char *
findinpath(arg) char * arg; {
#ifdef OS2
char * scriptenv, * keymapenv;
int len;
#endif /* OS2 */
#ifdef DCMDBUF
extern char * cmdbuf;
#else
extern char cmdbuf[];
#endif /* DCMDBUF */
char takepath[4096];
char * s;
int x, z;
/* Set up search path... */
#ifdef OS2
char * appdata0 = NULL, *appdata1 = NULL;
#ifdef NT
scriptenv = getenv("K95SCRIPTS");
keymapenv = getenv("K95KEYMAPS");
makestr(&appdata0,(char *)GetAppData(0));
makestr(&appdata1,(char *)GetAppData(1));
#else /* NT */
scriptenv = getenv("K2SCRIPTS");
keymapenv = getenv("K2KEYMAPS");
#endif /* NT */
if (!scriptenv)
scriptenv = getenv("CK_SCRIPTS");
if (!scriptenv)
scriptenv = "";
if (!keymapenv)
keymapenv = getenv("CK_KEYMAPS");
if (!keymapenv)
keymapenv = "";
debug(F110,"startupdir",startupdir,0);
debug(F110,"common appdata directory",appdata1,0);
debug(F110,"appdata directory",appdata0,0);
debug(F110,"inidir",inidir,0);
debug(F110,"home",zhome(),0);
debug(F110,"exedir",exedir,0);
len = strlen(scriptenv) + strlen(keymapenv) + 3*strlen(startupdir)
+ 3*strlen(inidir) + 3*strlen(zhome()) + 3*strlen(exedir)
+ (appdata0 ? 3*strlen(appdata0) : 0)
+ (appdata1 ? 3*strlen(appdata1) : 0)
+ 6*strlen("SCRIPTS/") + 6*strlen("KEYMAPS/") + 16;
if (len >= 4096) { /* SAFE (length is checked) */
takepath[0] = '\0';
debug(F111,"findinpath error - path length too long","len",len);
} else
sprintf(takepath,
/* semicolon-separated path list */
"%s%s%s%s%s;%s%s;%s%s;%s%s%s%s%s%s%s%s%s%s%s%s%s;%s%s;%s%s;%s;%s%s;%s%s",
scriptenv,
(scriptenv[0] && scriptenv[strlen(scriptenv)-1]==';')?"":";",
keymapenv,
(keymapenv[0] && keymapenv[strlen(keymapenv)-1]==';')?"":";",
startupdir,
startupdir, "SCRIPTS/",
startupdir, "KEYMAPS/",
appdata1 ? appdata1 : "",
appdata1 ? "Kermit 95;" : "",
appdata1 ? appdata1 : "",
appdata1 ? "Kermit 95/SCRIPTS/;" : "",
appdata1 ? appdata1 : "",
appdata1 ? "Kermit 95/KEYMAPS/;" : "",
appdata0 ? appdata0 : "",
appdata0 ? "Kermit 95;" : "",
appdata0 ? appdata0 : "",
appdata0 ? "Kermit 95/SCRIPTS/;" : "",
appdata0 ? appdata0 : "",
appdata0 ? "Kermit 95/KEYMAPS/;" : "",
inidir,
inidir, "SCRIPTS/",
inidir, "KEYMAPS/",
zhome(),
zhome(), "SCRIPTS/",
zhome(), "KEYMAPS/",
exedir,
exedir, "SCRIPTS/",
exedir, "KEYMAPS/"
);
debug(F110,"findinpath takepath",takepath,0);
#ifdef NT
makestr(&appdata0,NULL);
makestr(&appdata1,NULL);
#endif /* NT */
#else /* not OS2 */
#ifndef NOSPL
z = 1024; /* Look in home directory */
s = takepath;
zzstring("\\v(home)",&s,&z);
#else
takepath[0] = '\0';
#endif /* NOSPL */
#endif /* OS2 */
/*
All the logic for searching the take path is in the command parser.
So even though we aren't parsing commands, we initialize and call the
parser from here, with the purported filename stuffed into the command
buffer, followed by some carriage returns to make the parser return.
If the file is not found, or otherwise not accessible, the parser prints
an appropriate message, and then we just exit.
*/
cmdini(); /* Allocate command buffers etc */
cmini(0); /* Initialize them */
/* Stuff filename into command buf with braces in case of spaces */
ckmakmsg(cmdbuf,CMDBL,"{",arg,"}",NULL);
debug(F110,"findinpath cmdbuf",cmdbuf,0);
ckstrncat(cmdbuf,"\r\r",CMDBL); /* And some carriage returns */
if (cmifip("","",&s,&x,0,takepath,xxstring) < 0)
return(NULL);
cmres();
return(s);
}
static int tr_int; /* Flag if TRANSMIT interrupted */
#ifndef MAC
SIGTYP
#ifdef CK_ANSIC
trtrap(int foo) /* TRANSMIT interrupt trap */
#else
trtrap(foo) int foo; /* TRANSMIT interrupt trap */
#endif /* CK_ANSIC */
/* trtrap */ {
#ifdef __EMX__
signal(SIGINT, SIG_ACK);
#endif
tr_int = 1; /* (Need arg for ANSI C) */
SIGRETURN;
}
#endif /* MAC */
#endif /* NOICP */
#ifdef UNIX
VOID
getexedir() {
extern char * xarg0;
long xx;
/*
Unix provides no standard service for this. We look in argv[0], and if
we're lucky there's a full pathname. If not we do a PATH search.
*/
if (ckstrchr(xarg0,'/')) { /* Global copy of argv[0] */
int i, k;
char * p = NULL;
if ((k = ckstrncpy(tmpbuf,xarg0,TMPBUFSIZ-2)) > 0) {
p = tmpbuf;
/* Convert to fully qualified pathname */
if (tmpbuf[0]) if (tmpbuf[0] != '/') {
line[0] = NUL;
zfnqfp(tmpbuf,LINBUFSIZ-2,(char *)line);
if (line[0])
p = line;
}
xx = zchki(p);
if (xx > -1) { /* Is the result an existing file? */
k = strlen(p);
for (i = k-1; i > 0; i--) { /* Yes, strip name part */
if (p[i] == '/') {
if (i < k-1)
p[i+1] = NUL;
break;
}
}
}
makestr(&exedir,p); /* Save the result */
}
}
if (!exedir && xarg0) { /* Not found? */
char * p;
p = getenv("PATH"); /* Search the PATH */
if (p) { /* If there is one... */
char * q, * PATH = NULL;
int k;
makestr(&PATH,p); /* Pokeable copy of PATH string */
if (PATH) { /* If malloc succeeded... */
p = PATH;
while (p && *p) { /* Loop through segments */
q = ckstrchr(p,':'); /* End of this segment */
if (q == p) { /* Null PATH segment */
p++; /* Skip over colon */
continue;
}
if (q) /* If not at end of PATH string */
*q++ = NUL; /* zero out the colon */
if ((k = ckstrncpy(tmpbuf,p,TMPBUFSIZ)) > 0) {
if (tmpbuf[k-1] != '/') { /* Copy this PATH segment */
tmpbuf[k++] = '/'; /* Append '/' if needed */
tmpbuf[k] = NUL;
}
/* Append the argv[0] value */
if (ckstrncpy(&tmpbuf[k],xarg0,TMPBUFSIZ) > 0) {
if (zchki(tmpbuf) > -1) { /* File exists? */
tmpbuf[k] = NUL; /* Yes, we're done */
zfnqfp(tmpbuf,LINBUFSIZ,(char *)line);
makestr(&exedir,line);
break;
}
} else break;
} else break;
p = q; /* Not found, go to next segment */
} /* while */
free(PATH); /* Free PATH copy */
}
}
if (!exedir) { /* Still nothing? */
if (zchki(xarg0) > -1) { /* Maybe it's in the current dir */
zfnqfp(zgtdir(),LINBUFSIZ,(char *)line);
makestr(&exedir,line);
}
}
}
if (!exedir) { /* Still nothing? */
makestr(&exedir,"/"); /* Fake it with with root. */
}
}
#endif /* UNIX */
int arg_x = 0;
static int x_prescan = 0;
/*
The argument y once meant something but I can't imagine what so now
it's ignored. (Prior to 22 Aug 98, prescan() was called twice by main(),
and the arg differentiated the two calls. But this caused all sorts of
problems & confusion, so I commented out the second call. This issue might
need to be revisited.)
*/
VOID
prescan(dummy) int dummy; { /* Arg is ignored. */
extern int howcalled;
int yargc; char **yargv;
char x;
char *yp, *yy;
#ifdef DEBUG
int debcount = 0;
#endif /* DEBUG */
int z;
if (x_prescan) /* Only run once */
return;
x_prescan = 1;
yargc = xargc; /* Make copy of arg vector */
yargv = xargv;
#ifndef NOICP
#ifdef DCMDBUF
if (!kermrc)
if (!(kermrc = (char *) malloc(KERMRCL+1)))
fatal("prescan: no memory for kermrc");
#endif /* DCMDBUF */
ckstrncpy(kermrc,KERMRC,KERMRCL); /* Default init file name */
#endif /* NOICP */
#ifdef IKSD
if (howcalled == I_AM_IKSD) /* Internet Kermit Service daemon */
inserver = 1; /* (See inserver section of ckcmai) */
#endif /* IKSD */
/* Command line options for Kermit */
#ifndef NOCMDL
if (yargc > 1
&& *yargv[1] != '-'
&& (yargv[1][0] != '=')
#ifdef KERBANG
&& (yargv[1][0] != '+')
#endif /* KERBANG */
#ifdef IKSD
&& (howcalled != I_AM_IKSD)
#endif /* IKSD */
) { /* Filename as 1st argument */
#ifndef NOICP
char *s;
#endif /* NOICP */
#ifndef NOURL
extern int haveurl;
extern struct urldata g_url;
if (urlparse(yargv[1],&g_url)) {
if (!ckstrcmp(g_url.svc,"ftp",-1,0) ||
!ckstrcmp(g_url.svc,"ftps",-1,0)) {
haveurl = 1;
howcalled = I_AM_FTP;
} else if (!ckstrcmp(g_url.svc,"telnet",-1,0) ||
!ckstrcmp(g_url.svc,"telnets",-1,0)) {
haveurl = 1;
howcalled = I_AM_TELNET;
} else if (!ckstrcmp(g_url.svc,"ssh",-1,0)) {
haveurl = 1;
howcalled = I_AM_SSH;
} else if (!ckstrcmp(g_url.svc,"iksd",-1,0) ||
!ckstrcmp(g_url.svc,"kermit",-1,0)) {
haveurl = 1;
howcalled = I_AM_KERMIT;
} else if (!ckstrcmp(g_url.svc,"http",-1,0) ||
!ckstrcmp(g_url.svc,"https",-1,0)) {
haveurl = 1;
howcalled = I_AM_HTTP;
}
if (haveurl) {
while (--yargc > 0) { /* Go through command-line args */
yargv++; /* looking for -Y and -d */
yp = *yargv+1;
if (**yargv == '-') {
x = *(*yargv+1);
while (x) {
switch (x) {
#ifndef NOICP
case '+':
case '-':
if (doxarg(yargv,1) < 0) {
fatal("Extended argument error");
}
yp = "";
break;
#endif /* NOICP */
case 'Y':
noinit++;
break;
case 'h':
noinit = 1;
#ifdef OS2
startflags |= 2; /* No network DLLs */
startflags |= 4; /* No TAPI DLLs */
startflags |= 8; /* No Security DLLs */
startflags |= 16; /* No Zmodem DLLs */
startflags |= 32; /* Stdin */
startflags |= 64; /* Stdout */
#endif /* OS2 */
break;
case 'd': /* = SET DEBUG ON */
#ifdef DEBUG
if (debcount++ > 0)
debtim = 1;
if (!deblog)
deblog = debopn("debug.log",0);
#endif /* DEBUG */
break;
#ifdef OS2
case 'W':
if (*(yp+1))
fatal("invalid argument bundling after -W");
yargv++, yargc--;
if (yargc < 1)
fatal("Window handle missing");
hwndDialer = (HWND) atol(*yargv);
StartedFromDialer = 1;
yargv++, yargc--;
KermitDialerID = atol(*yargv) ;
break;
case '#': /* K95 initialization options */
if (*(yp+1)) {
fatal("invalid argument bundling");
}
yargv++, yargc--;
if (yargc < 1)
fatal("-# argument missing");
startflags |= atol(*yargv);
break;
#endif /* OS2 */
}
if (!yp)
break;
x = *++yp;
}
}
}
return;
}
}
/* after this point non-Kermit personalities must return */
switch (howcalled) {
case I_AM_KERMIT:
case I_AM_IKSD:
case I_AM_SSHSUB:
break;
default:
return;
}
#endif /* NOURL */
#ifndef NOICP
/* If it is not a URL that we recognize, try to treat it as a file */
if (!isabsolute(yargv[1])) /* If not absolute */
s = findinpath(yargv[1]); /* Look in PATH */
else
s = yargv[1];
if (!s)
doexit(BAD_EXIT,xitsta);
zfnqfp(s,CKMAXPATH,cmdfil); /* In case of CD in file */
yargc -= 1; /* Skip past the filename */
yargv += 1; /* Otherwise we'll get an error */
#endif /* NOICP */
}
#ifndef NOCMDL
#ifdef NEWFTP
if (howcalled == I_AM_FTP) { /* Kermit's FTP client personality */
while (--yargc > 0) { /* Go through command-line args */
yargv++; /* looking for -Y and -d */
yp = *yargv+1;
if (**yargv == '-') {
x = *(*yargv+1);
while (x) {
switch (x) {
#ifndef NOICP
case '+':
case '-':
if (doxarg(yargv,1) < 0) {
fatal("Extended argument error");
}
yp = "";
break;
#endif /* NOICP */
case 'Y':
noinit++;
break;
case 'h':
noinit = 1;
#ifdef OS2
startflags |= 2; /* No network DLLs */
startflags |= 4; /* No TAPI DLLs */
startflags |= 8; /* No Security DLLs */
startflags |= 16; /* No Zmodem DLLs */
startflags |= 32; /* Stdin */
startflags |= 64; /* Stdout */
#endif /* OS2 */
break;
case 'd': /* = SET DEBUG ON */
#ifdef DEBUG
if (debcount++ > 0)
debtim = 1;
if (!deblog)
deblog = debopn("debug.log",0);
#endif /* DEBUG */
break;
#ifdef OS2
case 'W':
if (*(yp+1))
fatal("invalid argument bundling after -W");
yargv++, yargc--;
if (yargc < 1)
fatal("Window handle missing");
hwndDialer = (HWND) atol(*yargv);
StartedFromDialer = 1;
yargv++, yargc--;
KermitDialerID = atol(*yargv) ;
break;
case '#': /* K95 initialization options */
if (*(yp+1)) {
fatal("invalid argument bundling");
}
yargv++, yargc--;
if (yargc < 1)
fatal("-# argument missing");
startflags |= atol(*yargv);
break;
#endif /* OS2 */
}
if (!yp)
break;
x = *++yp;
}
}
}
return;
}
#endif /* NEWFTP */
#endif /* NOCMDL */
while (--yargc > 0) { /* Go through command-line args */
yargv++;
yp = *yargv+1; /* Pointer for bundled args */
if (**yargv == '=') /* Same rules as cmdlin()... */
return;
debug(F110,"prescan *yargv",*yargv,0);
#ifndef NOICP
#ifdef KERBANG
yy = *yargv;
if (!strcmp(yy,"+") || (*yy == '+' && *(yy+1) < (char)33)) {
char * s;
yargv++;
noinit = 1;
if (!*yargv)
return;
cfilef = 1;
s = findinpath(*yargv);
if (s) {
zfnqfp(s,CKMAXPATH,cmdfil);
return;
} else
doexit(BAD_EXIT,xitsta);
}
#endif /* KERBANG */
#endif /* NOICP */
if (!strcmp(*yargv,"--")) /* getopt() conformance */
return;
#ifdef VMS
else if (**yargv == '/')
continue;
#endif /* VMS */
else if (**yargv == '-') { /* Got an option (begins with dash) */
x = *(*yargv+1); /* Get option letter */
while (x) { /* Allow for bundled options */
debug(F000,"prescan arg","",x);
switch (x) {
#ifndef NOICP
case '+':
case '-':
if (doxarg(yargv,1) < 0) {
fatal("Extended argument error");
}
#ifndef COMMENT /* Jeff 28 Apr 2003 */
yp = NULL; /* (not "") */
#else
yargv++, yargc--;
yp = *yargv;
#endif /* COMMENT */
break;
#endif /* NOICP */
case '7': /* Undocumented... */
sstelnet = 1; /* (because it doesn't work) */
break;
#ifdef IKSD
case 'A': {
char * p;
inserver = 1; /* Flag that we are doing this */
srvcdmsg = 2; /* Preset this */
/* See inserver section of ckcmai.c for more settings */
#ifdef OS2
if (*(yp+1)) {
fatal("invalid argument bundling after -A");
}
#ifdef NT
/* Support for Pragma Systems Telnet/Terminal Servers */
p = getenv("PRAGMASYS_INETD_SOCK");
if (p && atoi(p) != 0) {
ttname[0] = '$';
ckstrncpy(&ttname[1],p,TTNAMLEN-1);
break;
}
#endif /* NT */
yargv++, yargc--;
if (yargc < 1 || **yargv == '-') {
fatal("-A argument missing");
} else {
ttname[0] = '$';
ckstrncpy(&ttname[1],*yargv,TTNAMLEN-1);
}
#endif /* OS2 */
break;
}
#endif /* IKSD */
#ifdef OS2
case 'W':
if (*(yp+1))
fatal("invalid argument bundling after -W");
yargv++, yargc--;
if (yargc < 1)
fatal("Window handle missing");
#ifdef COMMENT
if (dummy) {
yargv++, yargc--;
break;
} else {
#endif /* COMMENT */
hwndDialer = (HWND) atol(*yargv);
StartedFromDialer = 1;
yargv++, yargc--;
KermitDialerID = atol(*yargv) ;
#ifdef COMMENT
}
#endif /* COMMENT */
break;
case '#': /* K95 initialization options */
if (*(yp+1)) {
fatal("invalid argument bundling");
}
yargv++, yargc--;
if (yargc < 1)
fatal("-# argument missing");
startflags |= atol(*yargv);
break;
#endif /* OS2 */
#ifndef NOSPL
case 'M': /* My User Name */
if (*(yp+1)) {
fatal("invalid argument bundling");
}
yargv++, yargc--;
if ((yargc < 1) || (**yargv == '-')) {
fatal("missing username");
}
if ((int)strlen(*yargv) > UIDBUFLEN) {
fatal("username too long");
}
#ifdef COMMENT
/*
This can't work. uidbuf is overwritten in sysinit() which has yet to be
called. This cannot be set in prescan().
*/
#ifdef IKSD
if (!inserver)
#endif /* IKSD */
ckstrncpy(uidbuf,*yargv,UIDBUFLEN);
#endif /* COMMENT */
break;
#endif /* NOSPL */
case 'R': /* Remote-only advisory */
#ifdef CK_IFRO
remonly = 1;
#endif /* CK_IFRO */
break;
case 'S': /* STAY */
stayflg = 1;
break;
case 'h':
noinit = 1;
#ifdef OS2
startflags |= 2; /* No network DLLs */
startflags |= 4; /* No TAPI DLLs */
startflags |= 8; /* No Security DLLs */
startflags |= 16; /* No Zmodem DLLs */
startflags |= 32; /* Stdin */
startflags |= 64; /* Stdout */
#endif /* OS2 */
break;
#ifndef NOICP
case 'Y': /* No init file */
noinit = 1;
break;
#endif /* NOICP */
case 'd': /* = SET DEBUG ON */
#ifdef DEBUG
if (debcount++ > 0)
debtim = 1;
if (!deblog)
deblog = debopn("debug.log",0);
#endif /* DEBUG */
break;
case 'x': /* Server */
arg_x = 1; /* Note in advance */
break;
#ifndef NOICP
case 'y': /* Alternative init file */
noinit = 0;
yargv++, yargc--;
if (yargc < 1) fatal("missing name in -y");
/* Replace init file name */
ckstrncpy(kermrc,*yargv,KERMRCL);
rcflag = 1; /* Flag that this has been done */
debug(F111,"prescan kermrc",kermrc,rcflag);
break;
#endif /* NOICP */
case 'z': /* = SET BACKGROUND OFF */
bgset = 0;
backgrd = 0;
#ifdef VMS
batch = 0;
#endif /* VMS */
break;
case 'B': /* Force background (batch) */
bgset = 1;
backgrd = 1;
#ifdef VMS
batch = 1;
#endif /* VMS */
break;
#ifdef CK_NETBIOS
case 'N':
{
int n ;
yargv++, yargc--;
#ifdef COMMENT
if (y)
break;
#endif /* COMMENT */
if (strlen(*yargv) != 1 || (*yargv)[0] == 'X') {
NetBiosAdapter = -1;
} else {
n = atoi(*yargv);
if (n >= 0 && n <= 9)
NetBiosAdapter = n;
else
NetBiosAdapter = -1;
}
}
break;
#endif /* CK_NETBIOS */
default:
break;
}
if (!yp)
break;
x = *++yp; /* See if options are bundled */
}
}
}
#endif /* NOCMDL */
}
/* G E T T C S -- Get Transfer (Intermediate) Character Set */
/*
Given two file character sets, this routine picks out the appropriate
"transfer" character set to use for translating between them.
The transfer character set number is returned.
Translation between two file character sets is done, for example,
by the CONNECT, TRANSMIT, and TRANSLATE commands.
Translation between Kanji character sets is not yet supported.
*/
int
gettcs(cs1,cs2) int cs1, cs2; {
#ifdef NOCSETS /* No character-set support */
return(0); /* so no translation */
#else
int tcs = TC_TRANSP;
#ifdef KANJI
/* Kanji not supported yet */
if (fcsinfo[cs1].alphabet == AL_JAPAN ||
fcsinfo[cs2].alphabet == AL_JAPAN )
tcs = TC_TRANSP;
else
#endif /* KANJI */
#ifdef CYRILLIC
/*
I can't remember why we don't test both sets here, but I think there
must have been a reason...
*/
if (fcsinfo[cs2].alphabet == AL_CYRIL)
tcs = TC_CYRILL;
else
#endif /* CYRILLIC */
#ifdef HEBREW
if (fcsinfo[cs1].alphabet == AL_HEBREW ||
fcsinfo[cs2].alphabet == AL_HEBREW )
tcs = TC_HEBREW;
else
#endif /* HEBREW */
#ifdef GREEK
if (fcsinfo[cs1].alphabet == AL_GREEK ||
fcsinfo[cs2].alphabet == AL_GREEK )
tcs = TC_GREEK;
else
#endif /* GREEK */
/* Roman sets ... */
#ifdef LATIN2 /* East European */
if (cs1 == FC_2LATIN || cs2 == FC_2LATIN || /* Latin-2 */
cs1 == FC_CP852 || cs2 == FC_CP852 || /* CP852 */
cs1 == FC_CP1250 || cs2 == FC_CP1250 || /* Windows Latin-2 */
cs1 == FC_MAZOVIA || cs2 == FC_MAZOVIA) /* Polish Mazovia */
tcs = TC_2LATIN;
else
#endif /* LATIN2 */
/* West European Euro-aware */
if (cs1 == FC_CP858 || cs1 == FC_9LATIN ||
cs2 == FC_CP858 || cs2 == FC_9LATIN)
tcs = TC_9LATIN;
else /* Traditional West European */
tcs = TC_1LATIN;
return(tcs);
#endif /* NOCSETS */
}
#ifndef NOLOCAL
/* D O C O N E C T -- Do the connect command */
/*
q = 0 means issue normal informational message about how to get back, etc.
q != 0 means to skip the message.
*/
int
doconect(q,async) int q, async; {
int x; /* Return code */
#ifdef CK_AUTODL
extern CHAR ksbuf[];
#endif /* CK_AUTODL */
#ifndef NOKVERBS /* Keyboard macro material */
extern int keymac, keymacx;
#endif /* NOKVERBS */
extern int justone, adl_err;
int qsave; /* For remembering "quiet" value */
#ifdef OS2
extern int term_io;
extern int display_demo;
int term_io_save;
#ifdef KUI
extern int kui_async;
#endif /* KUI */
#endif /* OS2 */
int is_tn = 0;
#ifdef IKSD
if (inserver) {
if (!quiet)
printf("?Sorry, IKSD cannot CONNECT.\r\n");
return(success = 0);
}
#endif /* IKSD */
is_tn =
#ifdef TNCODE
(local && network && IS_TELNET()) || (!local && sstelnet)
#else
0
#endif /* TNCODE */
;
/*
Saving, changing, and restoring the global "quiet" variable around calls
to conect() to control whether the verbose CONNECT message is printed is
obviously less elegant than passing a parameter to conect(), but we do it
this way to avoid the need to change all of the ck?con.c modules. NOTE:
it is important to restore the value immediately upon return in case there
is an autodownload or APC.
*/
qsave = quiet; /* Save it */
if (!quiet && q > -1)
quiet = q; /* Use argument temporarily */
conres(); /* Put console back to normal */
debug(F101,"doconect justone 1","",justone);
#ifdef CK_AUTODL
ksbuf[0] = NUL; /* Autodownload packet buffer */
#endif /* CK_AUTODL */
#ifdef OS2
display_demo = 1; /* Remember to display demo */
#endif /* OS2 */
#ifdef IKS_OPTION
if (is_tn && TELOPT_U(TELOPT_KERMIT) && ttchk() >= 0
#ifdef OS2
&& !viewonly
#endif /* OS2 */
) {
/* If the remote side is in a state of IKS START-SERVER */
/* we request that the state be changed. We will detect */
/* a failure to adhere to the request when we call ttinc() */
if (!iks_wait(KERMIT_REQ_STOP,0) && !tcp_incoming) {
if (!quiet) {
printf("\r\nEnter Client/Server Mode... Use:\r\n\r\n");
printf(
" REMOTE LOGIN <user> <password> to log in to the server if necessary.\r\n");
printf(" SEND and GET for file transfer.\r\n");
printf(" REMOTE commands for file management.\r\n");
printf(" FINISH to terminate Client/Server mode.\r\n");
printf(" BYE to terminate and close connection.\r\n");
printf(" REMOTE HELP for additional information.\r\n\r\n");
}
quiet = qsave;
return(0); /* Failure */
}
}
/* Let our peer know our state. */
#ifdef CK_AUTODL
if (is_tn && TELOPT_ME(TELOPT_KERMIT)
#ifdef OS2
&& !viewonly
#endif /* OS2 */
) {
if (autodl && !TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
tn_siks(KERMIT_START); /* Send Kermit-Server Start */
} else if (!autodl && TELOPT_SB(TELOPT_KERMIT).kermit.me_start) {
tn_siks(KERMIT_STOP);
}
}
#else /* CK_AUTODL */
if (is_tn && TELOPT_ME(TELOPT_KERMIT) &&
TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
tn_siks(KERMIT_STOP);
#endif /* CK_AUTODL */
#endif /* IKS_OPTION */
debug(F101,"doconect flow","",flow);
#ifdef OS2
debug(F101,"doconect async","",async);
#ifdef KUI
if (kui_async)
async = 1;;
#endif /* KUI */
x = conect(async); /* Connect the first time */
#else /* OS2 */
x = conect();
#endif /* OS2 */
debok = 1;
#ifdef IKS_OPTION
if (TELOPT_U(TELOPT_KERMIT) &&
TELOPT_SB(TELOPT_KERMIT).kermit.u_start &&
!tcp_incoming && !quiet && ttchk() >= 0
) {
printf("\r\nEnter Client/Server Mode... Use:\r\n\r\n");
printf(
" REMOTE LOGIN <user> <password> to log in to the server if necessary.\r\n");
printf(" SEND and GET for file transfer.\r\n");
printf(" REMOTE commands for file management.\r\n");
printf(" FINISH to terminate Client/Server mode.\r\n");
printf(" BYE to terminate and close connection.\r\n");
printf(" REMOTE HELP for additional information.\r\n\r\n");
}
#endif /* IKS_OPTION */
quiet = qsave; /* Restore "quiet" value */
debug(F101,"doconect justone 2","",justone);
#ifdef NETCONN
if (network && tn_exit && ttchk() < 0)
doexit(GOOD_EXIT,xitsta); /* Exit with good status */
#endif /* NETCONN */
#ifdef OS2ORUNIX
/* Exit on disconnect if the port is not open or carrier detect */
if (exitonclose && (ttchk() < 0))
doexit(GOOD_EXIT,xitsta);
#endif /* OS2ORUNIX */
#ifdef CKCONINTB4CB
/* The order makes a difference in HP-UX 8.00. */
/* The other order makes it think it's in the background when it */
/* returns from CONNECT (Apr 1999). */
setint();
concb((char)escape); /* Restore console for commands */
#else
/* This is how it has always been so better leave it */
/* this way for all non-HP-UX-8.00 builds. */
concb((char)escape); /* Restore console for commands */
setint();
#endif /* CKCONINTB4CB */
#ifdef OS2
if (!async) {
term_io_save = term_io; /* Disable I/O by emulator */
term_io = 0;
#endif /* OS2 */
#ifdef CK_APC
/*
If an APC command was received during CONNECT mode, we define it now
as a macro, execute the macro, and then return to CONNECT mode.
We do this in a WHILE loop in case additional APCs come during subsequent
CONNECT sessions.
*/
debug(F101,"doconect apcactive","",apcactive);
debug(F101,"doconect success","",success);
while (x > 0 && (apcactive == APC_LOCAL ||
(apcactive == APC_REMOTE && apcstatus != APC_OFF))) {
debug(F101,"doconect justone 3","",justone);
if (mlook(mactab,"_apc_commands",nmac) == -1) {
debug(F110,"doconect about to execute APC",apcbuf,0);
domac("_apc_commands",apcbuf,cmdstk[cmdlvl].ccflgs|CF_APC);
delmac("_apc_commands",1);
#ifdef DEBUG
} else {
debug(F100,"doconect APC in progress","",0);
#endif /* DEBUG */
}
debug(F101,"doconect apcactive after domac","",apcactive);
if (!apcactive) { /* In case CLEAR APC was in APC */
debug(F101,"doconect quit APC loop: apcactive","",apcactive);
break;
}
/* Also don't reconnect if autodownload failed - very confusing! */
/* Let them view the local screen to see what happened. - fdc */
/* This should be conditional. If someone is relying on the */
/* connect mode autodownload for the kermit server to use with */
/* a remotely executed script we should be able to return to */
/* connect mode on the failure. What we really need to do is */
/* report the status of the transfer and then return to CONNECT. */
/* In unix this would simply be a printf(), but in K95 it could */
/* use a popup dialog to report the status. - Jeff */
#ifndef NOXFER
debug(F101,"doconect xferstat","",xferstat);
if (apcactive == APC_LOCAL && !xferstat && adl_err != 0) {
debug(F101,"doconect quit APC loop: xferstat","",xferstat);
apcactive = APC_INACTIVE;
break;
}
#endif /* NOXFER */
#ifdef OS2
msleep(250);
#endif /* OS2 */
debug(F101,"doconect justone 4","",justone);
qsave = quiet; /* Do this again... */
if (!quiet && q > -1)
quiet = q;
#ifdef CK_AUTODL
ksbuf[0] = NUL;
#endif /* CK_AUTODL */
#ifdef IKS_OPTION
#ifdef CK_AUTODL
if (is_tn &&
TELOPT_ME(TELOPT_KERMIT) &&
!TELOPT_SB(TELOPT_KERMIT).kermit.me_start &&
autodl
#ifdef CK_APC
&& !apcactive
#endif /* CK_APC */
#ifdef OS2
&& !viewonly
#endif /* OS2 */
) {
tn_siks(KERMIT_START); /* Send Kermit-Server Start */
}
#endif /* CK_AUTODL */
#endif /* IKS_OPTION */
#ifndef OS2
x = conect(); /* Re-CONNECT. */
#else /* OS2 */
x = conect(0);
term_io = term_io_save;
#endif /* OS2 */
debok = 1;
quiet = qsave;
debug(F101,"doconect justone 5","",justone);
#ifdef NETCONN
if (network && ttchk() < 0) {
if (tn_exit || exitonclose)
doexit(GOOD_EXIT,xitsta);
else
break;
}
#endif /* NETCONN */
#ifdef OS2ORUNIX
/* If connection dropped */
if (ttchk() < 0) {
concb((char)escape); /* Restore console. */
if (exitonclose)
doexit(GOOD_EXIT,xitsta);
else
break;
}
#endif /* OS2ORUNIX */
} /* Loop back for more. */
#endif /* CK_APC */
#ifndef NOKVERBS
if ((keymac > 0) && (keymacx > -1)) { /* Executing a keyboard macro? */
/* Set up the macro and return */
/* Do not clear the keymac flag */
#ifdef OS2
term_io = term_io_save;
#endif /* OS2 */
return(dodo(keymacx,NULL,CF_KMAC|cmdstk[cmdlvl].ccflgs));
}
#endif /* NOKVERBS */
#ifdef OS2
term_io = term_io_save;
} /* if (!async) */
#endif /* OS2 */
#ifdef CKCONINTB4CB
/* The order makes a difference in HP-UX 8.00. */
/* The other order makes it think it's in the background when it */
/* returns from CONNECT (Apr 1999). */
setint();
concb((char)escape); /* Restore console for commands */
#else
/* This is how it has always been so better leave it */
/* this way for all non-HP-UX-8.00 builds. */
concb((char)escape); /* Restore console for commands */
setint();
#endif /* CKCONINTB4CB */
#ifdef OS2
if (!async)
#endif /* OS2 */
what = W_COMMAND; /* Back in command mode. */
return(x); /* Done. */
}
#endif /* NOLOCAL */
#ifndef NOICP
#ifdef COMMENT
/*
It seemed that this was needed for OS/2, in which \v(cmdfile) and other
file-oriented variables or functions can return filenames containing
backslashes, which are subsequently interpreted as quotes rather than
directory separators (e.g. see commented section for VN_CMDF below).
But the problem can't be cured at this level. Example:
type \v(cmdfile)
Without doubling, the filename is parsed correctly, but then when passed
to UNIX 'cat' through the shell, the backslash is removed, and then cat
can't open the file. With doubling, the filename is not parsed correctly
and the TYPE command fails immediately with a "file not found" error.
*/
/*
Utility routine to double all backslashes in a string.
s1 is pointer to source string, s2 is pointer to destination string,
n is length of destination string, both NUL-terminated.
Returns 0 if OK, -1 if not OK (destination string too short).
*/
int
dblbs(s1,s2,n) char *s1, *s2; int n; {
int i = 0;
while (*s1) {
if (*s1 == '\\') {
if (++i > n) return(-1);
*s2++ = '\\';
}
if (++i > n) return(-1);
*s2++ = *s1++;
}
*s2 = NUL;
return(0);
}
#endif /* COMMENT */
char *
gmdmtyp() { /* Get modem type */
#ifndef NODIAL
int i, x;
debug(F111,"gmdmtyp","mdmtyp",mdmtyp);
debug(F111,"gmdmtyp","mdmsav",mdmsav);
x = mdmtyp;
if (x < 0) /* In case of network dialing */
x = mdmsav;
if (x < 1)
return("none");
else
for (i = 0; i < nmdm; i++)
if ((mdmtab[i].kwval == x) && (mdmtab[i].flgs == 0))
return(mdmtab[i].kwd);
#endif /* NODIAL */
return("none");
}
#ifndef NOXMIT
#ifndef NOLOCAL
/* T R A N S M I T -- Raw upload */
/* Obey current line, duplex, parity, flow, text/binary settings. */
/* Returns 0 upon apparent success, 1 on obvious failure. */
/***
Things to add:
. Make both text and binary mode obey set file bytesize.
. Maybe allow user to specify terminators other than CR?
. Maybe allow user to specify prompts other than single characters?
. Make STATISTICS also work for TRANSMIT.
. If TRANSMIT is done without echo, make some kind of (optional) display.
. Make the same optimization for binary-mode transmit that was done for
text-mode (in the no-echo / no-prompt / no-pause case).
***/
/* T R A N S M I T -- Raw upload */
/* s is the filename, t is the turnaround (prompt) character */
/*
Maximum number of characters to buffer.
Must be less than LINBUFSIZ
*/
#ifdef OS2
#define XMBUFS 4096 /* For compatibility with XYZmodem */
#else /* OS2 */
#define XMBUFS 1024
#endif /* OS2 */
#ifdef TNCODE
#ifndef IAC
#define IAC 255
#endif /* IAC */
#endif /* TNCODE */
#define OUTXBUFSIZ 15
static CHAR inxbuf[OUTXBUFSIZ+1]; /* Host-to-screen expansion buffer */
static int inxcount = 0; /* and count */
static CHAR outxbuf[OUTXBUFSIZ+1]; /* Keyboard-to-host expansion buf */
static int outxcount = 0; /* and count */
/* T R A N S M I T -- Unguarded non-protocol file transmission */
/*
Call with:
char * s: Name of file to transmit.
char t: Turnaround char for text-mode transmission (normally LF).
int xlate: nonzero = charset translation for text-mode xfer, 0 = skip.
int binary: nonzero = transmit in binary mode, 0 = in text mode.
*/
#define XBBUFSIZ 252 /* For binary blasting */
static CHAR xbbuf[XBBUFSIZ+4];
int
#ifdef CK_ANSIC
transmit(char * s, char t, int xlate, int binary, int xxecho)
#else
transmit(s,t,xlate,binary,xxecho) char *s; char t; int xlate, binary, xxecho;
#endif /* CK_ANSIC */
/* transmit */ {
#ifdef MAC
extern char sstate;
int count = 100;
#else
int count = 0;
#ifdef OS2
#ifdef NT
SIGTYP (* oldsig)(int); /* For saving old interrupt trap. */
#else /* NT */
SIGTYP (* volatile oldsig)(int);
#endif /* NT */
#else /* OS2 */
SIGTYP (* oldsig)();
#endif /* OS2 */
#endif /* MAC */
int eof = 0; /* End of File flag */
int eol = 0; /* End of Line flag */
int rc = 1; /* Return code. 0=fail, 1=succeed. */
int myflow; /* Local copy of global flow... */
int is_tn = 0; /* Do Telnet negotiations */
int xbufsiz = XMBUFS; /* Size of TRANSMIT buffer */
int x, y, c, i; /* Int workers... */
int control = 0; /* Echo loop control */
long nbytes = 0; /* File byte count */
long zz; /* Long worker */
char *p; /* Char * worker */
#ifdef PIPESEND
extern int pipesend;
#endif /* PIPESEND */
#ifndef NOCSETS
int tcs = TC_TRANSP; /* Intermediate (xfer) char set */
int langsv = L_USASCII; /* Save current language */
int unicode = 0;
int tcssize = 0;
#ifdef CK_ANSIC /* ANSI C prototypes... */
CHAR (*sxo)(CHAR);
CHAR (*rxo)(CHAR);
CHAR (*sxi)(CHAR);
CHAR (*rxi)(CHAR);
#else /* Not ANSI C... */
CHAR (*sxo)();
CHAR (*rxo)();
CHAR (*sxi)();
CHAR (*rxi)();
#endif /* CK_ANSIC */
#ifdef UNICODE
union ck_short uc;
int bomorder = 0;
#ifdef CK_ANSIC
extern int (*xl_ufc[MAXFCSETS+1])(USHORT); /* Unicode to FCS */
extern USHORT (*xl_fcu[MAXFCSETS+1])(CHAR); /* FCS to Unicode */
extern int (*xuf)(USHORT);
extern USHORT (*xfu)(CHAR);
#else
extern int (*xl_ufc[MAXFCSETS+1])();
extern USHORT (*xl_fcu[MAXFCSETS+1])();
extern int (*xuf)();
extern USHORT (*xfu)();
#endif /* CK_ANSIC */
#endif /* UNICODE */
#endif /* NOCSETS */
debug(F101,"xmit t","",t);
debug(F101,"xmit xlate","",xlate);
debug(F101,"xmit binary","",binary);
#ifdef PIPESEND
if (pipesend) {
if (nopush) return(-2);
if (zxcmd(ZIFILE,s) < 1) {
printf("?Can't start command: %s\n",s);
return(0);
}
} else
#endif /* PIPESEND */
if (zopeni(ZIFILE,s) == 0) { /* Open the file to be transmitted */
printf("?Can't open file %s\n",s);
return(0);
}
x = -1; /* Open the communication channel */
if (ttopen(ttname,&x,mdmtyp,cdtimo) < 0) { /* (no harm if already open) */
printf("Can't open device %s\n",ttname);
return(0);
}
zz = x ? speed : -1L;
if (binary) { /* Binary file transmission */
myflow = (flow == FLO_XONX) ? FLO_NONE : flow;
if (ttvt(zz,myflow) < 0) { /* So no Xon/Xoff! */
printf("Can't condition line\n");
return(0);
}
} else {
if (ttpkt(zz,flow,parity) < 0) { /* Put the line in "packet mode" */
printf("Can't condition line\n"); /* so Xon/Xoff will work, etc. */
return(0);
}
}
is_tn =
#ifdef TNCODE
(local && network && IS_TELNET()) || (!local && sstelnet)
#else
0
#endif /* TNCODE */
;
#ifndef NOCSETS
/* Set up character set translations */
tcs = 0; /* "Transfer" or "Other" charset */
sxo = rxo = NULL; /* Initialize byte-to-byte functions */
sxi = rxi = NULL;
unicode = 0; /* Assume Unicode won't be involved */
if (!binary && xlate) { /* Set up charset translations */
/*
In the SENDING direction, we are converting from the local file's
character-set (fcharset) to the remote terminal charset (tcsr). In the
RECEIVING direction (echoing) we are converting from the remote end of the
terminal charset (tcsr) to its local end (tcsl), which is not necessarily
the same as the file character-set. Especially when the file character
set is UCS-2, which is not a valid terminal character set. The various
combinations are represented in this table:
FCS = File Character Set
RCS = Remote Terminal Character Set
CCS = Console (Local Terminal) Character Set
8 4 2 1
FCS FCS RCS CCS
UCS UTF UTF UTF
0 0 0 0 = 0 = No translation
0 0 0 1 = 1 = FCS -> RCS, Echo RCS -> UTF
0 0 1 0 = 2 = FCS -> UTF, Echo UTF -> CCS
0 0 1 1 = 3 = FCS -> UTF, Echo no translation
0 1 0 0 = 4 = UTF -> RCS, Echo RCS -> CCS
0 1 0 1 = 5 = UTF -> RCS, Echo RCS -> UTF
0 1 1 0 = 6 = UTF -> UTF, Echo UTF -> CCS
0 1 1 1 = 7 = No translation
1 0 0 0 = 8 = UCS -> RCS, Echo RCS -> CCS
1 0 0 1 = 9 = UCS -> RCS, Echo RCS -> UTF
1 0 1 0 = 10 = UCS -> UTF, Echo UTF -> CCS
1 0 1 1 = 11 = UCS -> UTF, Echo no translation
*/
#ifdef UNICODE
xfu = NULL; /* Unicode translation functions */
xuf = NULL;
bomorder = ucsorder; /* UCS-2 byte order */
if (fcharset == FC_UCS2) /* File charset is UCS-2 */
unicode |= 8;
else if (fcharset == FC_UTF8) /* File charset is UTF-8 */
unicode |= 4;
if (tcsr == FC_UTF8) /* Remote term charset is UTF-8 */
unicode |= 2;
if (tcsl == FC_UTF8) /* Local term charset is UTF-8 */
unicode |= 1;
#endif /* UNICODE */
/*
When Unicode not involved -- TCS is the intermediate (xfer) set, and:
sxo = File-to-Intermediate charset function
rxo = Intermediate-to-Remote-Terminal charset function
sxi = Remote-Terminal-to-Intermediate
rxi = Intermediate-to-Local-Terminal
*/
tcs = gettcs(tcsr,fcharset); /* Get intermediate set. */
sxo = xls[tcs][fcharset]; /* translation function */
rxo = xlr[tcs][tcsr]; /* pointers for output functions */
sxi = xls[tcs][tcsr]; /* and for input functions. */
rxi = xlr[tcs][tcsl];
/*
At this point we have unicode nonzero if Unicode is involved in the
conversion, and to 0 if it is not.
The following is to prevent use of zmstuff() and zdstuff() by translation
functions (stuffing works with file i/o, not with communication i/o).
*/
langsv = language; /* Save current SET LANGUAGE */
language = L_USASCII; /* No language-specific translations */
}
#endif /* NOCSETS */
i = 0; /* Beginning of buffer. */
#ifndef MAC
#ifndef AMIGA
oldsig = signal(SIGINT, trtrap); /* Save current interrupt trap. */
#endif /* AMIGA */
#endif /* MAC */
tr_int = 0; /* Have not been interrupted (yet). */
rc = 1; /* Return code presumed good. */
#ifdef VMS
conres();
#endif /* VMS */
#ifndef NOCSETS
debug(F101,"XMIT unicode","",unicode);
#ifdef UNICODE
debug(F101,"XMIT bomorder","",bomorder);
#endif /* UNICODE */
#endif /* NOCSETS */
c = 0; /* Initial condition */
while (c > -1 && !eof) { /* Loop for all characters in file */
eol = 0;
#ifdef MAC
/*
* It is expensive to run the miniparser so don't do it for
* every character.
*/
if (--count < 0) {
count = 100;
miniparser(1);
if (sstate == 'a') {
sstate = '\0';
goto xmitfail;
}
}
#else /* Not MAC */
if (tr_int) { /* Interrupted? */
printf("^C...\n"); /* Print message */
goto xmitfail;
}
#endif /* MAC */
c = zminchar(); /* Get a file character */
#ifdef COMMENT
/* too much */
#ifdef DEBUG
if (deblog) {
if (c < 0)
debug(F101,"XMIT zminchar","",c);
else
debug(F000,"XMIT zminchar","",c);
}
#endif /* DEBUG */
#endif /* COMMENT */
if (c < -1) { /* Other error */
printf("?TRANSMIT file read error: %s\n",ck_errstr());
goto xmitfail;
} else if (c > -1) {
nbytes++;
c &= fmask; /* Apply SET FILE BYTESIZE mask */
} else if (c == -1) {
eof = 1;
debug(F101,"XMIT eof","",eof);
}
if (binary) { /* Binary... */
if (c == -1) { /* If EOF */
rc = 1; /* Success */
eof = 1;
goto xmitexit; /* Done */
}
if (!xmitw && !xxecho) { /* Special "blast" mode */
if (count == XBBUFSIZ) { /* File input buffer full... */
while (count > 0) {
errno = 0;
y = ttol(xbbuf,count);
if (y < 0) { /* try to send it. */
printf("?TRANSMIT output error: %s\n",
ck_errstr());
debug(F111,"XMIT binary ttol error",
ck_errstr(),errno);
rc = 0;
break;
}
if (y < 0) break;
count -= y;
}
count = 0;
}
xbbuf[count++] = c;
#ifdef TNCODE
if (c == IAC && is_tn) /* Telnet IAC */
xbbuf[count++] = IAC; /* must be doubled */
#endif /* TNCODE */
continue;
}
if (ttoc(dopar((char) c)) < 0) { /* else just send the char */
printf("?Can't transmit character\n");
goto xmitfail;
}
#ifdef TNCODE
if (c == IAC && is_tn) /* Quote Telnet IAC */
ttoc((char)IAC);
#endif /* TNCODE */
if (xmitw) /* Pause if requested */
msleep(xmitw);
if (xxecho) { /* SET TRANSMIT ECHO ON? */
if (duplex) { /* Yes, for half duplex */
#ifndef NOLOCAL
#ifdef OS2
/* Echo to emulator */
scriptwrtbuf((USHORT)(c & cmdmsk));
#endif /* OS2 */
#endif /* NOLOCAL */
if (conoc((char)(c & cmdmsk)) < 0) /* echo locally. */
goto xmitfail;
} else { /* For full duplex, */
int i, n; /* display whatever is there. */
n = ttchk(); /* See how many chars are waiting */
if (n < 0) { /* Connection dropped? */
printf("?Connection lost\n");
goto xmitfail;
}
for (i = 0; i < n; i++) { /* Read and echo that many. */
x = ttinc(xmitt); /* Timed read just in case. */
if (x > -1) { /* If no timeout */
if (parity) x &= 0x7f; /* display the char, */
#ifndef NOLOCAL
#ifdef OS2
/* Echo to emulator */
scriptwrtbuf((USHORT)x);
#endif /* OS2 */
#endif /* NOLOCAL */
if (conoc((char)(x & cmdmsk)) < 0) {
printf("?Output error\n");
goto xmitfail;
}
} else if (x == -2) {
printf("Connection closed.\n");
ttclos(1);
goto xmitfail;
} else if (x == -3) {
printf(
"Session Limit exceeded - closing connection.\n"
);
ttclos(1);
goto xmitfail;
} else {
printf("?Communications error\n");
goto xmitfail;
}
}
}
} else ttflui(); /* Not echoing, just flush input. */
} else { /* Text mode, line at a time. */
#ifdef UNICODE
if (fcharset == FC_UCS2 && xlate) { /* Special for UCS-2 */
char xbuf[8];
x = 1 - (nbytes & 1); /* Odd or even byte */
if (x == 0) /* Note: 1 = the 1st, 0 = 2nd, etc */
uc.x_short = 0;
if (bomorder) /* Little Endian */
x = 1 - x; /* Save byte in appropriate half */
debug(F101,"XMIT UCS2 x","",x);
uc.x_char[x] = (CHAR) (c & 0xff);
if (nbytes & 1) /* First byte, go back for next */
continue;
if (nbytes == 2) { /* UCS-2 Byte Order Mark */
if (uc.x_short == (USHORT) 0xfeff) {
debug(F100,"XMIT UCS2 BOM FEFF","",bomorder);
continue;
} else if (uc.x_short == (USHORT) 0xfffe) {
bomorder = 1 - bomorder;
debug(F100,"XMIT UCS2 BOM FFFE (swap)","",bomorder);
continue;
}
}
sprintf(xbuf,"%04X",uc.x_short); /* SAFE */
debug(F111,"XMIT UCS2",xbuf,uc.x_short);
if (nbytes & 1) /* Special eol test for UCS-2 */
if (uc.x_short == '\n')
eol = 1;
#ifdef COMMENT
if (uc.x_short == 0x2028 || uc.x_short == 0x2029)