home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / ck208 / cku208.tar.gz / cku208.tar / ckuusr.c < prev    next >
C/C++ Source or Header  |  2003-02-21  |  326KB  |  12,274 lines

  1. #ifdef SSHTEST
  2. #define SSHBUILTIN
  3. #endif /* SSHTEST */
  4.  
  5. #include "ckcsym.h"
  6. char *userv = "User Interface 8.0.265, 21 Feb 2003";
  7.  
  8. /*  C K U U S R --  "User Interface" for C-Kermit (Part 1)  */
  9.  
  10. /*
  11.   Author: Frank da Cruz <fdc@columbia.edu>
  12.   Columbia University Academic Information Systems, New York City.
  13.  
  14.   Copyright (C) 1985, 2003,
  15.     Trustees of Columbia University in the City of New York.
  16.     All rights reserved.  See the C-Kermit COPYING.TXT file or the
  17.     copyright text in the ckcmai.c module for disclaimer and permissions.
  18. */
  19.  
  20. /*
  21.   Originally the entire user interface was in one module, ckuusr.c.  Over
  22.   the years it has been split into many modules: ckuus2.c, ckuus3.c, ...,
  23.   ckuus7.c.  ckuus2.c contains the HELP command parser and help-text strings;
  24.   ckuusy.c contains the UNIX-style command-line interface; ckuusx.c contains
  25.   routines needed by both the command-line interface and the interactive
  26.   command parser.
  27. */
  28.  
  29. /*
  30.   The ckuus*.c modules depend on the existence of C library features like
  31.   fopen, fgets, feof, (f)printf, argv/argc, etc.  Other functions that are
  32.   likely to vary among different platforms -- like setting terminal modes or
  33.   interrupts -- are invoked via calls to functions that are defined in the
  34.   system- dependent modules, ck?[ft]io.c.  The command line parser processes
  35.   any arguments found on the command line, as passed to main() via argv/argc.
  36.   The interactive parser uses the facilities of the cmd package (developed for
  37.   this program, but usable by any program).  Any command parser may be
  38.   substituted for this one.  The only requirements for the Kermit command
  39.   parser are these:
  40.  
  41.   . Set parameters via global variables like duplex, speed, ttname, etc.  See
  42.     ckmain.c for the declarations and descriptions of these variables.
  43.  
  44.   . If a command can be executed without the use of Kermit protocol, then
  45.     execute the command directly and set the variable sstate to 0. Examples
  46.     include 'set' commands, local directory listings, the 'connect' command.
  47.  
  48.   . If a command requires the Kermit protocol, set the following variables:
  49.  
  50.      sstate                             string data
  51.        'x' (enter server mode)            (none)
  52.        'r' (send a 'get' command)         cmarg, cmarg2
  53.        'v' (enter receive mode)           cmarg2
  54.        'g' (send a generic command)       cmarg
  55.        's' (send files)                   nfils, cmarg & cmarg2 OR cmlist
  56.        'c' (send a remote host command)   cmarg
  57.  
  58.      cmlist is an array of pointers to strings.
  59.      cmarg, cmarg2 are pointers to strings.
  60.      nfils is an integer.
  61.  
  62.      cmarg can be a filename string (possibly wild), or
  63.     a pointer to a prefabricated generic command string, or
  64.     a pointer to a host command string.
  65.      cmarg2 is an "as-name" - the name to send file(s) under, or
  66.     the name under which to store incoming file(s); must not be wild.
  67.     A null or empty value means to use the file's own name.
  68.      cmlist is a list of filenames, such as passed via argv.
  69.      nfils is an integer, interpreted as follows:
  70.        -1: filespec (possibly wild) in cmarg, must be expanded internally.
  71.     0: send from stdin (standard input).
  72.        >0: number of files to send, from cmlist.
  73.  
  74.   The screen() function is used to update the screen during file transfer.
  75.   The tlog() function writes to a transaction log.
  76.   The debug() function writes to a debugging log.
  77.   The intmsg() and chkint() functions provide the user i/o for interrupting
  78.     file transfers.
  79. */
  80.  
  81. /* Includes */
  82.  
  83. #ifdef MULTINET
  84. #define MULTINET_OLD_STYLE        /* Leave select prototype undefined */
  85. #endif /* MULTINET */
  86.  
  87. #include "ckcdeb.h"
  88. #include "ckcasc.h"
  89. #include "ckcker.h"
  90. #include "ckcnet.h"            /* Network symbols */
  91. #include "ckuusr.h"
  92. #include "ckcxla.h"
  93.  
  94. int g_fncact = -1;            /* Needed for NOICP builds */
  95. int noinit = 0;                /* Flag for skipping init file */
  96. int nscanfile = SCANFILEBUF;
  97.  
  98. int rcdactive = 0;
  99.  
  100. int locus = 1;                /* Current LOCUS is LOCAL */
  101. #ifdef OS2
  102. int autolocus = 2;            /* Automatic LOCUS switching: ASK */
  103. #else /* OS2 */
  104. int autolocus = 1;            /* Automatic LOCUS switching enabled */
  105. #endif /* OS2 */
  106.  
  107. #ifndef NOICP
  108. #ifdef CKLEARN
  109. #ifdef VMS
  110. #include <time.h>            /* For CKLEARN */
  111. #endif /* VMS */
  112. #endif /* CKLEARN */
  113. #ifdef OS2
  114. #ifndef NT
  115. #define INCL_NOPM
  116. #define INCL_VIO            /* Needed for ckocon.h */
  117. #include <os2.h>
  118. #undef COMMENT
  119. #else
  120. #define APIRET ULONG
  121. #include <windows.h>
  122. #include <tapi.h>
  123. #include "cknwin.h"
  124. #include "ckntap.h"            /* CK_TAPI definition */
  125. #endif /* NT */
  126. #include "ckowin.h"
  127. #include "ckocon.h"
  128. extern int tcp_avail;
  129. extern bool viewonly;
  130. extern int k95stdout;
  131. extern int tt_scroll;
  132. #ifndef NOTERM
  133. extern tt_status[VNUM];
  134. #endif /* NOTERM */
  135. int display_demo = 1;
  136. #include "ckossh.h"
  137. #ifdef KUI
  138. #include "ikui.h"
  139. #endif /* KUI */
  140. #endif /* OS2 */
  141.  
  142. int optlines = 0;
  143. int didsetlin = 0;
  144.  
  145. #ifdef NEWFTP
  146. extern int ftpget, ftpisopen(), ftpbye(), doftpres();
  147. _PROTOTYP(int doftptyp,(int));
  148. #endif /* NEWFTP */
  149.  
  150. #ifdef VMS
  151. extern int batch;
  152. #endif /* VMS */
  153.  
  154. #ifdef datageneral
  155. #include <packets:common.h>
  156. #define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd)
  157. #endif /* datageneral */
  158.  
  159. extern int xcmdsrc, hints, cmflgs, whyclosed;
  160.  
  161. char * hlptok = NULL;
  162.  
  163. #ifdef CK_TTGWSIZ            /* Whether to use more-prompting */
  164. int xaskmore = 1;            /* Momentary setting */
  165. int saveask  = 1;            /* Permanent setting */
  166. #else
  167. int xaskmore = 0;
  168. int saveask  = 0;
  169. #endif /* CK_TTGWSIZ */
  170.  
  171. #ifndef NOCSETS
  172. extern int nfilc;
  173. extern struct keytab fcstab[];
  174. extern int fcharset;
  175. #endif /* NOCSETS */
  176.  
  177. char * g_pswd = NULL;
  178. int g_pcpt = -1;
  179. int g_pflg = -1;
  180.  
  181. extern int cmd_rows, cmd_cols;
  182.  
  183. #ifdef CKROOT
  184. extern int ckrooterr;
  185. #endif /* CKROOT */
  186.  
  187. extern int inserver, filepeek;
  188.  
  189. #ifdef CKLEARN
  190. FILE * learnfp = NULL;
  191. char * learnfile = NULL;
  192. int learning = 0;
  193. #endif /* CKLEARN */
  194.  
  195. #ifndef NOXFER
  196. extern int atcapr, atdiso, nfils, moving, protocol, sendmode, epktflg, size,
  197.   sndsrc, server, displa, fncnv, fnspath, fnrpath, xfermode, urpsiz,
  198.   spsizf, spsiz, spsizr, spmax, wslotr, prefixing, fncact, reliable,
  199.   setreliable;
  200.  
  201. #ifdef IKSDCONF
  202. extern int iksdcf;
  203. #endif /* IKSDCONF */
  204.  
  205. #ifdef CK_LOGIN
  206. extern int isguest;
  207. #endif /* CK_LOGIN */
  208.  
  209. extern long sendstart;
  210.  
  211. extern char *cmarg, *cmarg2, **cmlist, *dftty;
  212.  
  213. extern struct keytab fntab[]; extern int nfntab;
  214. extern struct ck_p ptab[NPROTOS];
  215.  
  216. int sndcmd = 0;        /* Last command was a SEND-class command. */
  217.  
  218. int g_xfermode = -1;
  219. int g_proto  = -1;
  220. int g_urpsiz = -1;
  221. int g_spsizf = -1;
  222. int g_spsiz  = -1;
  223. int g_spsizr = -1;
  224. int g_spmax  = -1;
  225. int g_wslotr = -1;
  226. int g_prefixing = -1;
  227. int g_fncnv  = -1;
  228. int g_fnspath = -1;
  229. int g_fnrpath = -1;
  230. int g_fnact  = -1;
  231. int g_displa = -1;
  232. int g_spath  = -1;
  233. int g_rpath  = -1;
  234. char * g_sfilter = NULL;
  235. char * g_rfilter = NULL;
  236.  
  237. extern int patterns;
  238. #ifdef PATTERNS
  239. extern char *txtpatterns[], *binpatterns[];
  240. int g_patterns = -1;
  241. #endif /* PATTERNS */
  242. int g_skipbup = -1;
  243.  
  244. #ifdef PIPESEND
  245. extern int usepipes, pipesend;
  246. extern char * sndfilter;
  247. #endif /* PIPESEND */
  248.  
  249. #ifndef NOSPL
  250. extern int sndxlo, sndxhi, sndxin;
  251. #endif /* NOSPL */
  252.  
  253. extern char fspec[];            /* Most recent filespec */
  254. extern int fspeclen;            /* Length of fspec[] buffer */
  255.  
  256. #ifndef NOFRILLS
  257. extern int rmailf;            /* MAIL command items */
  258. extern char optbuf[];
  259. #endif /* NOFRILLS */
  260.  
  261. extern int
  262.   en_cpy, en_cwd, en_del, en_dir, en_fin, en_get, en_bye, en_mai, en_pri,
  263.   en_hos, en_ren, en_sen, en_spa, en_set, en_typ, en_who, en_ret, en_xit,
  264.   en_mkd, en_rmd, en_asg;
  265.  
  266. #ifndef NOMSEND                /* Multiple SEND */
  267. extern char *msfiles[];
  268. int filesinlist = 0;            /* And ADD ... */
  269. extern struct filelist * filehead;
  270. extern struct filelist * filetail;
  271. extern struct filelist * filenext;
  272. extern int addlist;
  273. #endif /* NOMSEND */
  274.  
  275. static struct keytab addtab[] = {
  276. #ifdef PATTERNS
  277.     { "binary-patterns", ADD_BIN, 0 },
  278. #endif /* PATTERNS */
  279. #ifndef NOMSEND
  280.     { "send-list", ADD_SND, 0 },
  281. #endif /* NOMSEND */
  282. #ifdef PATTERNS
  283.     { "text-patterns", ADD_TXT, 0 },
  284. #endif /* PATTERNS */
  285.     { "", 0, 0 }
  286. };
  287. static int naddtab = sizeof(addtab)/sizeof(struct keytab) - 1;
  288.  
  289. #ifndef NOCSETS
  290. struct keytab assoctab[] = {
  291.     { "file-character-set",     ASSOC_FC, 0 },
  292.     { "transfer-character-set", ASSOC_TC, 0 },
  293.     { "xfer-character-set",     ASSOC_TC, CM_INV }
  294. };
  295. static int nassoc = sizeof(assoctab)/sizeof(struct keytab);
  296. extern int afcset[MAXFCSETS+1];        /* Character-set associations */
  297. extern int axcset[MAXTCSETS+1];
  298. #endif /* NOCSETS */
  299.  
  300. #ifndef ADDCMD
  301. #ifndef NOMSEND
  302. #define ADDCMD
  303. #endif /* NOMSEND */
  304. #ifndef ADDCMD
  305. #ifdef PATTERNS
  306. #define ADDCMD
  307. #endif /* PATTERNS */
  308. #endif /* ADDCMD */
  309. #endif /* ADDCMD */
  310. #endif /* NOXFER */
  311.  
  312. /* External Kermit Variables, see ckmain.c for description. */
  313.  
  314. extern xx_strp xxstring;
  315. extern long xvernum;
  316.  
  317. extern int local, xitsta, binary, msgflg, escape, duplex, quiet, tlevel,
  318.   pflag, zincnt, ckxech, carrier, what, nopush, haveline, bye_active;
  319. #ifdef TNCODE
  320. extern int debses;
  321. extern char tn_msg[];
  322. #endif /* TNCODE */
  323.  
  324. int sleepcan = 1;
  325. int g_binary = -1;
  326. int g_recursive = -1;
  327. int g_matchdot = -1;
  328. extern int nolinks;
  329.  
  330. extern long vernum;
  331. extern char *versio, *copyright[];
  332. extern char *ckxsys;
  333. #ifndef NOHELP
  334. extern char *introtxt[];
  335. extern char *newstxt[];
  336. #endif /* NOHELP */
  337.  
  338. #ifndef OS2
  339. #ifndef UNIX
  340. extern char *PWDCMD;
  341. #endif /* UNIX */
  342. extern char *WHOCMD;
  343. #endif /* OS2 */
  344.  
  345. extern char ttname[];
  346.  
  347. extern CHAR sstate;
  348.  
  349. extern int network;            /* Have active network connection */
  350. extern int nettype;            /* Type of network */
  351. extern int ttnproto;                    /* NET_TCPB protocol */
  352.  
  353. #ifndef NODIAL
  354. extern int dialsta, dialatmo, dialcon, dialcq; /* DIAL status, etc. */
  355. #endif /* NODIAL */
  356.  
  357. #ifdef CK_APC
  358. extern int apcactive, apcstatus;
  359. #endif /* CK_APC */
  360.  
  361. #ifndef NOPUSH
  362. #ifndef NOFRILLS
  363. extern char editor[];
  364. extern char editopts[];
  365. extern char editfile[];
  366. #endif /* NOFRILLS */
  367. #endif /* NOPUSH */
  368.  
  369. #ifdef BROWSER
  370. extern char browser[];            /* Web browser application */
  371. extern char browsopts[];        /* Web browser options */
  372. extern char browsurl[];            /* Most recent URL */
  373. #endif /* BROWSER */
  374. #ifndef NOFTP
  375. char ftpapp[CKMAXPATH+1] = { NUL, NUL }; /* ftp executable */
  376. char ftpopts[128] = { NUL, NUL };    /* ftp command-line options */
  377. #endif /* NOFTP */
  378. extern struct keytab onoff[];        /* On/Off keyword table */
  379.  
  380. #ifdef CK_TMPDIR
  381. int f_tmpdir = 0;            /* Directory changed temporarily */
  382. char savdir[TMPDIRLEN];            /* For saving current directory */
  383. #endif /* CK_TMPDIR */
  384.  
  385. int activecmd = -1;            /* Keyword index of active command */
  386. int doconx = -1;            /* CONNECT-class command active */
  387. int ooflag = 0;                /* User-settable on/off flag */
  388.  
  389. int rcflag = 0;                /* Pointer to home directory string */
  390. int repars,                /* Reparse needed */
  391.     techo = 0;                /* Take echo */
  392. int secho = 1;                /* SCRIPT echo */
  393.  
  394. int xitwarn =            /* Warn about open connection on exit */
  395. #ifdef NOWARN
  396. 0
  397. #else
  398. 1
  399. #endif /* NOWARN */
  400. ;
  401.  
  402. struct keytab onoffsw[] = {
  403.     { "/off", 0, 0 },
  404.     { "/on",  1, 0 }
  405. };
  406.  
  407. #ifdef CKEXEC
  408. struct keytab redirsw[] = {
  409.     { "/redirect", 1, 0 }
  410. };
  411. #endif /* CKEXEC */
  412.  
  413. #ifndef NOXMIT
  414. /* Variables for TRANSMIT command */
  415.  
  416. int xmitx = 1;            /* Whether to echo during TRANSMIT */
  417. int xmitf = 0;            /* Character to fill empty lines */
  418. int xmitl = 0;            /* 0 = Don't send linefeed too */
  419. int xmitp = LF;            /* Host line prompt */
  420. int xmits = 0;            /* Use shift-in/shift-out, 0 = no */
  421. int xmitw = 0;            /* Milliseconds to pause during TRANSMIT */
  422. int xmitt = 1;            /* Seconds to wait for each char to echo */
  423. int xmita = 1;            /* Action upon timeout */
  424.  
  425. #define XMI_BIN 1
  426. #define XMI_TXT 2
  427. #define XMI_CMD 3
  428. #define XMI_TRA 4
  429. #define XMI_VRB 5
  430. #define XMI_QUI 6
  431. #define XMI_NOW 7
  432. #define XMI_NOE 8
  433.  
  434. static struct keytab xmitsw[] = {    /* TRANSMIT command options */
  435.     { "/binary",          XMI_BIN, 0 },
  436. #ifdef PIPESEND
  437.     { "/command",         XMI_CMD, CM_INV|CM_PSH },
  438. #endif /* PIPESEND */
  439.     { "/noecho",          XMI_NOE, 0 },
  440.     { "/nowait",          XMI_NOW, 0 },
  441. #ifdef PIPESEND
  442.     { "/pipe",            XMI_CMD, 0 },
  443. #endif /* PIPESEND */
  444. #ifdef COMMENT
  445.     { "/quiet",           XMI_QUI, 0 },
  446. #endif /* COMMENT */
  447.     { "/text",            XMI_TXT, 0 },
  448.     { "/transparent",     XMI_TRA, 0 },
  449. #ifdef COMMENT
  450.     { "/verbose",         XMI_VRB, 0 },
  451. #endif /* COMMENT */
  452.     { "", 0, 0 }
  453. };
  454. #define NXMITSW sizeof(xmitsw)/sizeof(struct keytab) - 1
  455. static int nxmitsw = NXMITSW;
  456.  
  457. #endif /* NOXMIT */
  458.  
  459. /* Declarations from ck?fio.c module */
  460.  
  461. extern char *SPACMD, *SPACM2;        /* SPACE commands */
  462.  
  463. /* Command-oriented items */
  464.  
  465. #ifdef DCMDBUF
  466. extern char *cmdbuf;            /* Command buffers */
  467. extern char *atmbuf;
  468. extern char *line;            /* Character buffer for anything */
  469. extern char *tmpbuf;            /* Short temporary string buffer */
  470. extern int *ifcmd;
  471. extern int *intime;
  472. extern int *inpcas;
  473. #else
  474. extern char cmdbuf[];            /* Command buffers */
  475. extern char atmbuf[];
  476. extern char line[];            /* Character buffer for anything */
  477. extern char tmpbuf[];            /* Temporary buffer */
  478. extern int ifcmd[];
  479. extern int intime[];
  480. extern int inpcas[];
  481. #endif /* DCMDBUF */
  482.  
  483. #ifndef NOSPL
  484. extern char * prstring[];
  485. #endif /* NOSPL */
  486.  
  487. char *lp;                /* Pointer to line buffer */
  488.  
  489. #ifndef NOSPL
  490. int unkmacro = 0;            /* Flag for in ON_UNKNOWN_COMMAND */
  491. int oldeval = 0;
  492. char evalbuf[33];            /* EVALUATE result */
  493. extern char * inpbuf;            /* Buffer for INPUT and REINPUT */
  494. char *inpbp;                /* And pointer to same */
  495. extern char lblbuf[];            /* Buffer for labels */
  496. int m_found;                /* MINPUT result */
  497. int i_active = 0;            /* INPUT command is active */
  498. char *ms[MINPMAX];            /* Pointers to MINPUT strings */
  499. static int mp[MINPMAX];            /* and flags */
  500. extern int fndiags, fnerror, fnsuccess;    /* Function diagnostics */
  501. #ifndef NOSEXP
  502. char * lastsexp = NULL;            /* S-Expressions */
  503. char * sexpval = NULL;
  504. int sexpecho = SET_AUTO;
  505. #endif /* NOSEXP */
  506. #endif /* NOSPL */
  507.  
  508. char psave[PROMPTL] = { NUL };        /* For saving & restoring prompt */
  509.  
  510. extern int success;            /* Command success/failure flag */
  511. extern int cmdlvl;            /* Current position in command stack */
  512.  
  513. #ifndef NOSPL
  514. int                    /* SET INPUT parameters. */
  515. /* Note, INPUT TIMEOUT, intime[], is on the command-level stack. */
  516.   inbufsize = 0,            /* INPUT buffer size */
  517.   indef = 1,                /* default timeout, seconds */
  518.   inecho = 1,                /* 1 = echo on */
  519.   inautodl = 0,                /* INPUT autodownload */
  520.   inintr = 1,                /* INPUT interrupion allowed */
  521.   insilence = 0;            /* 0 = no silence constraint */
  522. #ifdef OS2
  523. int interm = 1;                /* Terminal emulator displays input */
  524. #endif /* OS2 */
  525. int maclvl = -1;            /* Macro nesting level */
  526. int mecho = 0;                /* Macro echo, 0 = don't */
  527. char varnam[6];                /* For variable names */
  528. extern int macargc[];            /* ARGC from macro invocation */
  529.  
  530. extern char *m_arg[MACLEVEL][NARGS];    /* Stack of macro arguments */
  531. extern char *mrval[];
  532.  
  533. extern char **a_ptr[];            /* Array pointers */
  534. extern int a_dim[];            /* Array dimensions */
  535. extern int a_link[];
  536.  
  537. #ifdef DCMDBUF
  538. extern struct cmdptr *cmdstk;        /* The command stack itself */
  539. #else
  540. extern struct cmdptr cmdstk[];        /* The command stack itself */
  541. #endif /* DCMDBUF */
  542.  
  543. long ck_alarm = 0;            /* SET ALARM value */
  544. char alrm_date[24] = { ' ',' ',' ',' ',' ',' ',' ',' ',' ' };
  545. char alrm_time[24] = { ' ',' ',' ',' ',' ',' ',' ' };
  546.  
  547. #endif /* NOSPL */
  548.  
  549. static int x, y, z = 0;            /* Local workers */
  550. static char *s;
  551.  
  552. #define xsystem(s) zsyscmd(s)
  553.  
  554. /* Top-Level Interactive Command Keyword Table */
  555. /* Keywords must be in lowercase and in alphabetical order. */
  556.  
  557. struct keytab cmdtab[] = {
  558. #ifndef NOPUSH
  559.     { "!",       XXSHE, CM_INV|CM_PSH }, /* Shell escape */
  560. #else
  561.     { "!",       XXNOTAV, CM_INV|CM_PSH },
  562. #endif /* NOPUSH */
  563.     { "#",           XXCOM, CM_INV },    /* Comment */
  564. #ifndef NOSPL
  565.     { "(",           XXSEXP,CM_INV },    /* S-Expression */
  566.     { ".",           XXDEF, CM_INV },    /* Assignment */
  567.     { ":",           XXLBL, CM_INV },    /* Label */
  568. #endif /* NOSPL */
  569. #ifdef CK_REDIR
  570. #ifndef NOPUSH
  571.     { "<",           XXFUN, CM_INV|CM_PSH }, /* REDIRECT */
  572. #else
  573.     { "<",           XXNOTAV, CM_INV|CM_PSH }, /* REDIRECT */
  574. #endif /* NOPUSH */
  575. #endif /* CK_REDIR */
  576. #ifndef NOPUSH
  577.     { "@",           XXSHE, CM_INV|CM_PSH }, /* DCL escape */
  578. #else
  579.     { "@",           XXNOTAV, CM_INV|CM_PSH }, /* DCL escape */
  580. #endif /* NOPUSH */
  581.  
  582. #ifdef CK_RECALL
  583.     { "^",           XXREDO,CM_INV|CM_NOR }, /* Synonym for REDO */
  584. #endif /* CK_RECALL */
  585. #ifndef NOSPL
  586.     { "_asg",        XXASX,   CM_INV },    /* Used internally by FOR, etc */
  587.     { "_assign",     XXASX,   CM_INV },    /* Used internally by FOR, etc */
  588.     { "_decrement",  XX_DECR, CM_INV },
  589.     { "_define",     XXDFX,   CM_INV },    /* Used internally by FOR, etc */
  590.     { "_evaluate",   XX_EVAL, CM_INV },
  591.     { "_forward",    XXXFWD,  CM_INV },    /* Used internally by SWITCH   */
  592.     { "_getargs",    XXGTA,   CM_INV },    /* Used internally by FOR, etc */
  593.     { "_increment",  XX_INCR, CM_INV },
  594.     { "_putargs",    XXPTA,   CM_INV },    /* Used internally by FOR, etc */
  595.     { "_undefine",   XXUNDFX, CM_INV },
  596. #endif /* NOSPL */
  597.  
  598.     { "about",       XXVER,   CM_INV },    /* Synonym for VERSION */
  599. #ifndef NOSPL
  600. #ifdef NEWFTP
  601.     { "account",     XXACCT,  CM_INV }, /* (FTP) Account */
  602. #endif /* NEWFTP */
  603. #ifdef ADDCMD
  604.     { "add",         XXADD, 0 },    /* ADD */
  605. #endif /* ADDCMD */
  606. #ifndef NODIAL
  607.     { "answer",      XXANSW, CM_LOC },    /* ANSWER the phone */
  608. #else
  609.     { "answer",      XXNOTAV, CM_INV|CM_LOC }, /* ANSWER the phone */
  610. #endif /* NODIAL */
  611.     { "apc",         XXAPC, 0 },    /* Application Program Command */
  612. #ifndef NOSPL
  613.     { "array",       XXARRAY, 0 },    /* Array operations */
  614. #endif /* NOSPL */
  615.     { "ascii",       XXASC, CM_INV },    /* == SET FILE TYPE TEXT */
  616.     { "asg",         XXASS, CM_INV },    /* Invisible synonym for ASSIGN */
  617.     { "ask",         XXASK, 0 },    /* ASK for text, assign to variable */
  618.     { "askq",        XXASKQ,0 },    /* ASK quietly (no echo) */
  619. #ifndef NOSPL
  620.     { "ass",         XXASS, CM_INV|CM_ABR }, /* ASSIGN */
  621.     { "assert",      XXASSER, CM_INV },    /* ASSERT */
  622.     { "assign",      XXASS, 0 },    /* ASSIGN */
  623. #endif /* NOSPL */
  624. #ifndef NOXFER
  625. #ifndef NOCSETS
  626.     { "associate",   XXASSOC, 0 },    /* ASSOCIATE */
  627. #else
  628.     { "associate",   XXNOTAV, CM_INV },    /* ASSOCIATE */
  629. #endif /* NOCSETS */
  630. #endif /* NOXFER */
  631. #ifdef CK_KERBEROS
  632. #ifdef CK_AUTHENTICATION
  633.     { "authenticate",XXAUTH, 0 },    /* Authentication */
  634. #else
  635.     { "authenticate",XXAUTH, CM_INV },
  636. #endif /* CK_AUTHENTICATION */
  637. #endif /* CK_KERBEROS */
  638. #endif /* NOSPL */
  639. #ifndef NOFRILLS
  640.     { "back",        XXBACK, 0 },    /* BACK to previous directory */
  641. #else
  642.     { "back",        XXNOTAV,CM_INV },
  643. #endif /* NOFRILLS */
  644.     { "beep",        XXBEEP,CM_INV },    /* BEEP */
  645. #ifndef NOXFER
  646.     { "binary",      XXBIN, CM_INV },    /* == SET FILE TYPE BINARY */
  647. #endif /* NOXFER */
  648. #ifndef NOFRILLS
  649.     { "bug",         XXBUG, CM_INV },    /* BUG report instructions */
  650. #else
  651.     { "bug",         XXNOTAV, CM_INV },
  652. #endif /* NOFRILLS */
  653. #ifdef BROWSER
  654.     { "browse",      XXBROWS, CM_PSH|CM_LOC }, /* BROWSE (start browser) */
  655. #else
  656.     { "browse",      XXNOTAV, CM_INV|CM_PSH|CM_LOC },
  657. #endif /* BROWSER */
  658. #ifndef NOXFER
  659.     { "bye",         XXBYE, 0 },    /* BYE to remote server */
  660. #endif /* NOXFER */
  661. #ifndef NOLOCAL
  662.     { "c",           XXCON, CM_INV|CM_ABR|CM_LOC }, /* (CONNECT) */
  663. #endif /* NOLOCAL */
  664. #ifndef NOFRILLS
  665.     { "cat",         XXCAT, CM_INV },    /* Invisible synonym for TYPE */
  666. #endif /* NOFRILLS */
  667. #ifndef NOSPL
  668.  
  669. #ifndef NOXFER
  670.     { "cautious",    XXCAU, CM_INV },
  671. #endif /* NOXFER */
  672.  
  673. #endif /* NOSPL */
  674.  
  675.     { "cd",          XXCWD, 0 },    /* Change Directory */
  676.     { "cdup",        XXCDUP, CM_INV },    /* Change Directory Up */
  677.  
  678. #ifndef NOXFER
  679. #ifdef PIPESEND
  680.     { "cget",        XXCGET, CM_INV|CM_PSH }, /* CGET */
  681. #else
  682.     { "cget",        XXNOTAV, CM_INV|CM_PSH }, /* CGET */
  683. #endif /* PIPESEND */
  684. #endif /* NOXFER */
  685.     { "ch",          XXCHK,   CM_INV|CM_ABR },
  686.     { "check",       XXCHK,   0 },    /* CHECK for a feature */
  687. #ifdef CK_PERMS
  688. #ifdef UNIX
  689.     { "chmod",       XXCHMOD, 0 },    /* CHMOD */
  690. #else
  691.     { "chmod",       XXNOTAV, CM_INV },
  692. #endif /* UNIX */
  693. #else
  694.     { "chmod",       XXNOTAV, CM_INV },
  695. #endif /* CK_PERMS */
  696. #ifdef CKROOT
  697.     { "chroot",      XXCHRT,  CM_INV },    /* CHROOT */
  698. #endif /* CKROOT */
  699.     { "ckermit",     XXKERMI, CM_INV },    /* CKERMIT (like KERMIT) */
  700.     { "cl",          XXCLO,   CM_ABR|CM_INV },
  701. #ifndef NOFRILLS
  702.     { "clear",       XXCLE, 0 },    /* CLEAR input and/or device buffer */
  703. #else
  704.     { "clear",       XXNOTAV, CM_INV },
  705. #endif /* NOFRILLS */
  706.     { "close",         XXCLO, 0 },    /* CLOSE a log or other file */
  707.     { "cls",         XXCLS, CM_INV },    /* Clear Screen (CLS) */
  708.     { "comment",     XXCOM, CM_INV },    /* Introduce a comment */
  709. #ifndef NOLOCAL
  710.     { "connect",     XXCON, CM_LOC },    /* Begin terminal connection */
  711. #else
  712.     { "connect",     XXNOTAV, CM_LOC },
  713. #endif /* NOLOCAL */
  714.     { "continue",    XXCONT,  CM_INV },    /* CONTINUE */
  715. #ifndef NOFRILLS
  716. #ifdef ZCOPY
  717.     { "co",          XXCPY, CM_INV|CM_ABR },
  718.     { "cop",         XXCPY, CM_INV|CM_ABR },
  719.     { "copy",        XXCPY, 0 },    /* COPY a file */
  720. #else
  721.     { "copy",        XXNOTAV, CM_INV },
  722. #endif /* ZCOPY */
  723.     { "copyright",   XXCPR, CM_INV },    /* COPYRIGHT */
  724. #ifdef ZCOPY
  725.     { "cp",          XXCPY, CM_INV },    /* COPY a file */
  726. #endif /* ZCOPY */
  727. #ifndef NOLOCAL
  728. #ifndef OS2
  729.     { "cq",          XXCQ, CM_INV|CM_LOC }, /* CQ (connect quietly) */
  730. #endif /* OS2 */
  731. #endif /* NOLOCAL */
  732. #ifndef NOXFER
  733. #ifdef PIPESEND
  734.     { "creceive",    XXCREC,CM_INV|CM_PSH }, /* RECEIVE to a command */
  735.     { "csend",       XXCSEN,CM_INV|CM_PSH }, /* SEND from command */
  736. #else
  737.     { "creceive",    XXNOTAV,CM_INV|CM_PSH },
  738.     { "csend",       XXNOTAV,CM_INV|CM_PSH },
  739. #endif /* PIPESEND */
  740. #endif /* NOXFER */
  741. #endif /* NOFRILLS */
  742.  
  743.     { "cwd",         XXCWD,   CM_INV },    /* Traditional synonym for cd */
  744.  
  745. #ifndef NOSPL
  746.     { "date",        XXDATE,  0 },    /* DATE */
  747.     { "dcl",         XXDCL,   CM_INV },    /* DECLARE an array (see ARRAY) */
  748.     { "debug",       XXDEBUG, CM_INV },
  749.     { "declare",     XXDCL,   CM_INV },    /* DECLARE an array (see ARRAY) */
  750.     { "decrement",   XXDEC,   0 },    /* DECREMENT a numeric variable */
  751.     { "define",      XXDEF,   0 },    /* DEFINE a macro or variable */
  752. #else
  753.     { "date",        XXNOTAV, CM_INV },
  754.     { "dcl",         XXNOTAV, CM_INV },
  755.     { "declare",     XXNOTAV, CM_INV },
  756.     { "decrement",   XXNOTAV, CM_INV },
  757.     { "define",      XXNOTAV, CM_INV },
  758. #endif /* NOSPL */
  759.  
  760. #ifndef NOFRILLS
  761.     { "delete",      XXDEL, 0 },    /* DELETE a file */
  762. #else
  763.     { "delete",      XXNOTAV, CM_INV },
  764. #endif /* NOFRILLS */
  765.  
  766. #ifndef NODIAL
  767.     { "dial",        XXDIAL,  CM_LOC },    /* DIAL a phone number */
  768. #else
  769.     { "dial",        XXNOTAV, CM_INV|CM_LOC },
  770. #endif /* NODIAL */
  771.  
  772. #ifdef NT
  773.     { "dialer",      XXDIALER, CM_INV }, /* K95 Dialer */
  774. #endif /* NT */
  775.  
  776.     { "directory",   XXDIR, 0 },    /* DIRECTORY of files */
  777.  
  778. #ifndef NOFRILLS
  779. #ifndef NOSERVER
  780.     { "disable",     XXDIS, 0 },    /* DISABLE a server function */
  781. #else
  782.     { "disable",     XXNOTAV, CM_INV },
  783. #endif /* NOSERVER */
  784. #endif /* NOFRILLS */
  785.  
  786. #ifndef NOSPL
  787.     { "do",          XXDO,  0 },    /* DO (execute) a macro */
  788. #else
  789.     { "do",          XXNOTAV, CM_INV },
  790. #endif /* NOSPL */
  791.  
  792.     { "e",           XXEXI, CM_INV|CM_ABR },
  793.  
  794. #ifndef NOFRILLS
  795. #ifndef NOXFER
  796.     { "e-packet",    XXERR, CM_INV },    /* Send an Error-Packet */
  797. #endif /* NOXFER */
  798. #endif /* NOFRILLS */
  799.  
  800.     { "echo",        XXECH, 0 },    /* ECHO text */
  801.  
  802. #ifndef NOFRILLS
  803. #ifndef NOPUSH
  804.     { "edit",        XXEDIT, CM_PSH },    /* EDIT */
  805. #else
  806.     { "edit",        XXNOTAV, CM_INV|CM_PSH }, /* EDIT */
  807. #endif /* NOPUSH */
  808. #endif /* NOFRILLS */
  809.  
  810.     { "eightbit",    XXEIGHT, CM_INV },    /* EIGHTBIT */
  811.  
  812. #ifndef NOSPL
  813.     { "else",        XXELS, CM_INV },    /* ELSE part of IF statement */
  814. #else
  815.     { "else",        XXNOTAV, CM_INV },    /* ELSE part of IF statement */
  816. #endif /* NOSPL */
  817.  
  818. #ifndef NOSERVER
  819. #ifndef NOFRILLS
  820.     { "enable",      XXENA,  0 },    /* ENABLE a server function */
  821. #else
  822.     { "enable",      XXNOTAV, CM_INV },
  823. #endif /* NOFRILLS */
  824. #endif /* NOSERVER */
  825.  
  826. #ifndef NOSPL
  827.     { "end",         XXEND,  0 },    /* END command file or macro */
  828. #else
  829.     { "end",         XXNOTAV, CM_INV },
  830. #endif /* NOSPL */
  831.  
  832.     { "erase",       XXDEL, CM_INV },    /* Synonym for DELETE */
  833.  
  834. #ifndef NOSPL
  835.     { "evaluate",    XXEVAL, 0 },    /* EVALUATE */
  836. #else
  837.     { "evaluate",    XXNOTAV, CM_INV },
  838. #endif /* NOSPL */
  839.  
  840.     { "ex",          XXEXI, CM_INV|CM_ABR }, /* Let "ex" still be EXIT */
  841.  
  842. #ifdef CKEXEC
  843.     { "exec",        XXEXEC, CM_INV|CM_LOC }, /* exec() */
  844. #else
  845.     { "exec",        XXNOTAV, CM_INV|CM_LOC },
  846. #endif /* CKEXEC */
  847.  
  848.     { "exit",       XXEXI, 0 },        /* EXIT from C-Kermit */
  849.     { "extended-options", XXXOPTS,CM_INV|CM_HLP }, /* Extended-Options */
  850.  
  851. #ifdef OS2
  852.     { "extproc",     XXCOM, CM_INV },    /* Dummy command for OS/2 */
  853. #endif /* OS2 */
  854.  
  855. #ifndef NOXFER
  856.     { "f",           XXFIN, CM_INV|CM_ABR }, /* Invisible abbrev for FIN */
  857. #endif /* NOXFER */
  858.  
  859. #ifndef NOSPL
  860.     { "fail",        XXFAIL, CM_INV },    /* FAIL */
  861.  
  862. #ifndef NOXFER
  863.     { "fast",        XXFAST, CM_INV },
  864. #endif /* NOXFER */
  865.  
  866. #ifdef CKCHANNELIO
  867.     { "fclose",      XXF_CL, CM_INV },    /* FCLOSE */
  868.     { "fcount",      XXF_CO, CM_INV },    /* FCOUNT */
  869.     { "fflush",      XXF_FL, CM_INV },    /* FFLUSH */
  870. #endif /* CKCHANNELIO */
  871.  
  872. #ifndef NOXFER
  873.     { "fi",          XXFIN, CM_INV|CM_ABR }, /* FINISH */
  874. #endif /* NOXFER */
  875.  
  876. #ifdef CKCHANNELIO
  877.     { "file",        XXFILE, 0 },    /* FILE */
  878. #endif /* CKCHANNELIO */
  879. #endif /* NOSPL */
  880.  
  881. #ifndef NOXFER
  882.     { "fin",         XXFIN, CM_INV|CM_ABR }, /* FINISH */
  883. #endif /* NOXFER */
  884.  
  885. #ifndef UNIXOROSK
  886.     { "find",        XXGREP, 0 },    /* FIND (grep) */
  887. #else
  888.     { "find",        XXGREP,CM_INV },
  889. #endif /* UNIXOROSK */
  890.  
  891. #ifndef NOXFER
  892.     { "finish",      XXFIN, 0 },    /* FINISH */
  893. #endif /* NOXFER */
  894.  
  895. #ifdef TCPSOCKET
  896.     { "firewall",    XXFIREW, CM_INV|CM_HLP },
  897. #endif /* TCPSOCKET */
  898.  
  899. #ifdef CKCHANNELIO
  900.     { "flist",       XXF_LI, CM_INV },    /* FLIST */
  901.     { "fopen",       XXF_OP, CM_INV },    /* FOPEN */
  902. #endif /* CKCHANNELIO */
  903.  
  904. #ifndef NOSPL
  905.     { "fo",          XXFOR, CM_INV|CM_ABR }, /* Invisible abbrev for... */
  906.     { "for",         XXFOR, 0 },    /* FOR loop */
  907.     { "forward",     XXFWD, CM_INV },    /* FORWARD */
  908. #endif /* NOSPL */
  909. #ifndef NOFRILLS
  910.     { "fot",       XXDIR, CM_INV },    /* "fot" = "dir" (for Chris) */
  911. #endif /* NOFRILLS */
  912.  
  913. #ifdef CKCHANNELIO
  914.     { "fread",      XXF_RE, CM_INV },    /* FREAD */
  915.     { "frewind",    XXF_RW, CM_INV },    /* FREWIND */
  916.     { "fseek",      XXF_SE, CM_INV },    /* FSEEK */
  917.     { "fstatus",    XXF_ST, CM_INV },    /* FSTATUS */
  918. #endif /* CKCHANNELIO */
  919.  
  920. #ifdef TCPSOCKET
  921. #ifndef NOFTP
  922. #ifdef SYSFTP
  923. #ifndef NOPUSH
  924.     { "ftp",       XXFTP,   CM_INV|CM_PSH|CM_LOC }, /* System FTP */
  925. #else
  926.     { "ftp",       XXNOTAV, CM_INV|CM_PSH|CM_LOC },
  927. #endif /* NOPUSH */
  928. #else  /* SYSFTP */
  929.     { "ftp",       XXFTP,   0 },    /* Built-in FTP */
  930. #endif /* SYSFTP */
  931. #else  /* NOFTP */
  932.     { "ftp",       XXNOTAV, CM_INV },    /* No FTP */
  933. #endif /* NOFTP */
  934. #endif /* TCPSOCKET */
  935.  
  936. #ifndef NOSPL
  937.     { "function",    XXFUNC, CM_INV|CM_HLP }, /* (for HELP FUNCTION) */
  938. #endif /* NOSPL */
  939.  
  940. #ifdef CKCHANNELIO
  941.     { "fwrite",      XXF_WR, CM_INV },    /* FWRITE */
  942. #endif /* CKCHANNELIO */
  943.  
  944. #ifndef NOXFER
  945.     { "g",           XXGET, CM_INV|CM_ABR }, /* Invisible abbrev for GET */
  946. #ifndef NOSPL
  947.     { "ge",          XXGET, CM_INV|CM_ABR }, /* Ditto */
  948. #endif /* NOSPL */
  949.     { "get",         XXGET, 0 },    /* GET */
  950. #endif /* NOXFER */
  951. #ifndef NOSPL
  952.     { "getc",        XXGETC, 0 },    /* GETC */
  953. #ifdef OS2
  954.     { "getkeycode",  XXGETK, 0 },    /* GETKEYCODE */
  955. #endif /* OS2 */
  956. #ifndef NOFRILLS
  957.     { "getok",       XXGOK, 0 },    /* GETOK (ask for Yes/No/OK) */
  958. #endif /* NOFRILLS */
  959. #endif /* NOSPL */
  960. #ifndef NOSPL
  961.     { "goto",        XXGOTO,0 },    /* GOTO label in take file or macro */
  962. #endif /* NOSPL */
  963. #ifdef UNIXOROSK
  964.     { "grep",        XXGREP,0 },    /* GREP (find) */
  965. #else
  966.     { "grep",        XXGREP,CM_INV },    /* GREP (find) */
  967. #endif /* UNIXOROSK */
  968.     { "h",           XXHLP, CM_INV|CM_ABR }, /* Invisible synonym for HELP */
  969.     { "he",          XXHLP, CM_INV|CM_ABR }, /* Invisible synonym for HELP */
  970. #ifndef NOFRILLS
  971.     { "head",        XXHEAD, 0 },
  972. #endif /* NOFRILLS */
  973. #ifndef NOLOCAL
  974.     { "hangup",      XXHAN, CM_LOC },    /* HANGUP the connection */
  975. #endif /* NOLOCAL */
  976.     { "HELP",        XXHLP, 0 },    /* Display HELP text */
  977. #ifndef NOHTTP
  978. #ifdef TCPSOCKET
  979.     { "http",        XXHTTP, 0 },    /* HTTP operations */
  980. #endif /* TCPSOCKET */
  981. #endif /* NOHTTP */
  982. #ifndef NOSPL
  983.     { "i",           XXINP, CM_INV|CM_ABR }, /* Invisible synonym for INPUT */
  984.     { "if",          XXIF,  0 },         /* IF ( condition ) command */
  985. #ifdef TCPSOCKET
  986.     { "iksd",        XXIKSD, CM_INV },         /* Make connection to IKSD */
  987. #else
  988.     { "iksd",        XXNOTAV, CM_INV },
  989. #endif /* TCPSOCKET */
  990.     { "in",          XXINP, CM_INV|CM_ABR }, /* Invisible synonym for INPUT */
  991.     { "increment",   XXINC, 0 },    /* Increment a numeric variable */
  992.     { "input",       XXINP, 0 },    /* INPUT text from comm device */
  993. #endif /* NOSPL */
  994.  
  995. #ifndef NOHELP
  996.     { "int",         XXINT, CM_INV|CM_ABR },
  997.     { "intr",        XXINT, CM_INV|CM_ABR },
  998.     { "INTRO",       XXINT, 0 },
  999.     { "introduction",XXINT, CM_INV },    /* Print introductory text */
  1000. #else
  1001.     { "intro",       XXNOTAV, CM_INV },
  1002.     { "introduction",XXNOTAV, CM_INV },
  1003. #endif /* NOHELP */
  1004.  
  1005. #ifdef OS2
  1006.     { "k95",         XXKERMI, CM_INV },    /* Hmmm what's this... */
  1007. #endif /* OS2 */
  1008.  
  1009. #ifndef NOSPL
  1010.     { "kcd",         XXKCD,   0      },
  1011. #endif /* NOSPL */
  1012.  
  1013.     { "kermit",      XXKERMI, CM_INV },
  1014.  
  1015. #ifdef OS2
  1016. #ifndef NOKVERBS
  1017.     { "kverb",       XXKVRB, CM_INV|CM_HLP }, /* Keyboard verb */
  1018. #endif /* NOKVERBS */
  1019. #endif /* OS2 */
  1020.  
  1021. #ifndef NOFRILLS
  1022.     { "l",           XXLOG, CM_INV|CM_ABR }, /* Invisible synonym for log */
  1023. #endif /* NOFRILLS */
  1024.  
  1025.     { "lcd",         XXLCWD, CM_INV },
  1026.     { "lcdup",       XXLCDU, CM_INV },
  1027.     { "lcwd",        XXLCWD, CM_INV },
  1028.     { "ldelete",     XXLDEL, CM_INV },
  1029.     { "ldirectory",  XXLDIR, CM_INV },
  1030.  
  1031. #ifdef CKLEARN
  1032.     { "learn",       XXLEARN, 0 },    /* LEARN - automatic script writing */
  1033. #else
  1034.     { "learn",       XXNOTAV, CM_INV },
  1035. #endif /* CKLEARN */
  1036.  
  1037.     { "li",          XXLNOUT, CM_INV|CM_ABR },
  1038.     { "LICENSE",     XXCPR, 0 },    /* LICENSE */
  1039.  
  1040. #ifndef NOSPL
  1041.     { "lineout",     XXLNOUT, 0 },    /* LINEOUT = OUTPUT + eol */
  1042. #endif /* NOSPL */
  1043.  
  1044. #ifdef NT
  1045.     { "link",        XXLINK, 0 },       /* LINK source destination */
  1046. #endif /* NT */
  1047.  
  1048.     { "lmkdir",      XXLMKD, CM_INV },
  1049.  
  1050. #ifndef NOFRILLS
  1051.     { "lo",          XXLOG,  CM_INV|CM_ABR }, /* Invisible synonym for log */
  1052. #endif /* NOFRILLS */
  1053.  
  1054. #ifndef NOSPL
  1055.     { "local",       XXLOCAL, CM_INV },    /* LOCAL variable declaration */
  1056. #else
  1057.     { "local",       XXNOTAV, CM_INV },
  1058. #endif /* NOSPL */
  1059.  
  1060.     { "log",           XXLOG, 0 },    /* Open a log file */
  1061.  
  1062.     { "login",       XXLOGIN,  0 },    /* (REMOTE) LOGIN to server or IKSD */
  1063.     { "logout",      XXLOGOUT, 0 },    /* LOGOUT from server or IKSD */
  1064.  
  1065. #ifndef NOFRILLS
  1066. #ifndef NODIAL
  1067.     { "lookup",      XXLOOK,  0 },    /* LOOKUP */
  1068. #else
  1069.     { "lookup",      XXNOTAV, CM_INV },
  1070. #endif /* NODIAL */
  1071.  
  1072.     { "lpwd",        XXLPWD, CM_INV },
  1073.     { "lrename",     XXLREN, CM_INV },
  1074.     { "lrmdir",      XXLRMD, CM_INV },
  1075.  
  1076. #ifdef UNIXOROSK
  1077.     { "ls",          XXLS,  CM_INV|CM_PSH }, /* UNIX ls command */
  1078. #else
  1079.     { "ls",          XXDIR, CM_INV },    /* Invisible synonym for DIR */
  1080. #endif /* UNIXOROSK */
  1081. #ifndef NOXFER
  1082.     { "mail",        XXMAI, 0 },    /* Send a file as e-mail */
  1083. #endif /* NOXFER */
  1084. #ifndef NOHELP
  1085.     { "manual",      XXMAN, CM_PSH },    /* MAN(UAL) */
  1086. #else
  1087.     { "manual",      XXNOTAV, CM_INV|CM_PSH },
  1088. #endif /* NOHELP */
  1089. #endif /* NOFRILLS */
  1090. #ifdef CK_MKDIR
  1091.     { "md",          XXMKDIR, CM_INV },    /* Synonym for MKDIR */
  1092. #endif /* CK_MKDIR */
  1093. #ifdef CK_MINPUT
  1094.     { "minput",      XXMINP, 0 },    /* MINPUT */
  1095. #else
  1096.     { "minput",      XXNOTAV, CM_INV },
  1097. #endif /* CK_MINPUT */
  1098. #ifndef NOMSEND
  1099.     { "mget",        XXMGET, 0 },    /* MGET */
  1100. #else
  1101.     { "mget",        XXNOTAV, CM_INV },
  1102. #endif /* NOMSEND */
  1103. #ifdef CK_MKDIR
  1104.     { "mkdir",       XXMKDIR, 0 },    /* MKDIR */
  1105. #else
  1106.     { "mkdir",       XXNOTAV, CM_INV },
  1107. #endif /* CK_MKDIR */
  1108.  
  1109. #ifndef NOXFER
  1110. #ifndef NOMSEND
  1111.     { "mmove",       XXMMOVE, 0 },    /* MMOVE */
  1112. #else
  1113.     { "mmove",       XXNOTAV, CM_INV },
  1114. #endif /* NOMSEND */
  1115. #endif /* NOXFER */
  1116.  
  1117. #ifndef NOFRILLS
  1118.     { "more",        XXMORE, CM_INV },    /* MORE */
  1119. #endif /* NOFRILLS */
  1120.  
  1121. #ifndef NOXFER
  1122.     { "move",        XXMOVE, 0 },    /* MOVE  */
  1123. #endif /* NOXFER */
  1124.  
  1125. #ifndef NOSPL
  1126.     { "mpause",      XXMSL, CM_INV },    /* Millisecond sleep */
  1127. #else
  1128.     { "mpause",      XXNOTAV, CM_INV },
  1129. #endif /* NOSPL */
  1130.  
  1131. #ifndef NOXFER
  1132. #ifndef NOMSEND
  1133.     { "mput",        XXMSE, CM_INV },    /* MPUT = MSEND */
  1134.     { "ms",          XXMSE, CM_INV|CM_ABR },
  1135.     { "msend",       XXMSE, 0 },    /* Multiple SEND */
  1136. #else
  1137.     { "mput",        XXNOTAV, CM_INV },
  1138.     { "msend",       XXNOTAV, CM_INV },
  1139. #endif /* NOMSEND */
  1140. #endif /* NOXFER */
  1141. #ifndef NOSPL
  1142.     { "msleep",      XXMSL, 0 },    /* Millisecond sleep */
  1143. #else
  1144.     { "msleep",      XXNOTAV, CM_INV },
  1145. #endif /* NOSPL */
  1146. #ifndef NOFRILLS
  1147.     { "mv",          XXREN, CM_INV },    /* Synonym for rename */
  1148. #endif /* NOFRILLS */
  1149. #ifndef NOHELP
  1150.     { "news",        XXNEW, CM_INV },    /* Display NEWS of new features */
  1151. #else
  1152.     { "news",        XXNOTAV, CM_INV },
  1153. #endif /* NOHELP */
  1154.     { "nolocal",     XXNLCL, CM_INV },    /* Disable SET LINE / SET HOST */
  1155.     { "nopush",      XXNPSH, CM_INV },    /* Disable PUSH command/features */
  1156. #ifdef OS2
  1157.     { "noscroll",    XXNSCR, CM_INV },  /* Disable scroll operations */
  1158. #endif /* OS2 */
  1159. #ifndef NOSPL
  1160.     { "o",           XXOUT, CM_INV|CM_ABR }, /* Invisible synonym for OUTPUT */
  1161.     { "open",        XXOPE, 0 },    /* OPEN file for reading or writing */
  1162. #else
  1163.     { "open",        XXOPE, CM_INV },    /* OPEN */
  1164. #endif /* NOSPL */
  1165. #ifndef NOHELP
  1166.     { "options",     XXOPTS,CM_INV|CM_HLP }, /* Options */
  1167. #endif /* NOHELP */
  1168.     { "orientation", XXORIE, 0 },
  1169. #ifndef NOSPL
  1170.     { "output",      XXOUT, 0 },    /* OUTPUT text to comm device */
  1171. #else
  1172.     { "output",      XXNOTAV, CM_INV },
  1173. #endif /* NOSPL */
  1174. #ifdef ANYX25
  1175. #ifndef IBMX25
  1176.     { "pad",         XXPAD, CM_LOC },    /* X.3 PAD commands */
  1177. #endif /* IBMX25 */
  1178. #endif /* ANYX25 */
  1179.  
  1180. #ifdef NEWFTP
  1181.     { "passive",     XXPASV, CM_INV },    /* (FTP) PASSIVE */
  1182. #endif /* NEWFTP */
  1183.  
  1184. #ifndef NOHELP
  1185.     { "patterns",    XXPAT,CM_INV|CM_HLP }, /* Pattern syntax */
  1186. #endif /* NOHELP */
  1187.  
  1188. #ifndef NOSPL
  1189.     { "pause",       XXPAU, 0 },    /* Sleep for specified interval */
  1190. #else
  1191.     { "pause",       XXNOTAV, CM_INV },
  1192. #endif /* NOSPL */
  1193. #ifndef NODIAL
  1194.     { "pdial",       XXPDIA,  CM_LOC },    /* PDIAL (partial dial) */
  1195. #else
  1196.     { "pdial",       XXNOTAV, CM_INV|CM_LOC },
  1197. #endif /* NODIAL */
  1198. #ifdef TCPSOCKET
  1199. #ifndef NOPUSH
  1200.     { "ping",        XXPNG, CM_INV|CM_PSH|CM_LOC }, /* PING */
  1201. #else
  1202.     { "ping",        XXNOTAV, CM_INV|CM_PSH|CM_LOC },
  1203. #endif /* NOPUSH */
  1204. #endif /* TCPSOCKET */
  1205. #ifdef NETCMD
  1206. #ifndef NOPUSH
  1207.     { "pipe",        XXPIPE, CM_PSH },    /* PIPE */
  1208. #else
  1209.     { "pipe",        XXNOTAV, CM_INV|CM_PSH }, /* PIPE */
  1210. #endif /* NOPUSH */
  1211. #endif /* NETCMD */
  1212.  
  1213. #ifndef NOSPL
  1214.     { "pop",         XXEND, CM_INV },    /* Invisible synonym for END */
  1215. #endif /* NOSPL */
  1216. #ifndef NOFRILLS
  1217.     { "print",       XXPRI, 0 },    /* PRINT a file locally */
  1218. #endif /* NOFRILLS */
  1219.  
  1220.     { "prompt",      XXPROMP, CM_INV },    /* Go interactive (from script) */
  1221.  
  1222. #ifndef NOXFER
  1223. #ifdef CK_RESEND
  1224.     { "psend",       XXPSEN, CM_INV },    /* PSEND */
  1225. #else
  1226.     { "psend",       XXNOTAV, CM_INV },
  1227. #endif /* CK_RESEND */
  1228. #endif /* NOXFER */
  1229.  
  1230. #ifdef NETPTY
  1231.     { "pty",         XXPTY, CM_PSH },    /* PTY */
  1232. #else
  1233.     { "pty",         XXNOTAV, CM_INV|CM_PSH },
  1234. #endif /* NETPTY */
  1235.  
  1236. #ifndef NOPUSH
  1237.     { "pu",          XXSHE, CM_INV|CM_ABR|CM_PSH }, /* PU = PUSH */
  1238. #endif /* NOPUSH */
  1239.  
  1240. #ifdef CKPURGE
  1241.     { "purge",       XXPURGE, 0 },    /* PURGE (real) */
  1242. #else
  1243. #ifdef VMS
  1244.     { "purge",       XXPURGE, 0 },    /* PURGE (fake) */
  1245. #else
  1246.     { "purge",       XXNOTAV, CM_INV },
  1247. #endif /* VMS */
  1248. #endif /* CKPURGE */
  1249.  
  1250. #ifndef NOPUSH
  1251.     { "push",        XXSHE, CM_PSH },    /* PUSH command (like RUN, !) */
  1252. #else
  1253.     { "push",        XXNOTAV, CM_INV|CM_PSH },
  1254. #endif /* NOPUSH */
  1255.  
  1256. #ifndef NOXFER
  1257.     { "put",         XXSEN, CM_INV },    /* PUT = SEND */
  1258. #endif /* NOXFER */
  1259.  
  1260.     { "pwd",         XXPWD, 0 },    /* Print Working Directory */
  1261.     { "q",           XXQUI, CM_INV|CM_ABR }, /* Invisible synonym for QUIT */
  1262.  
  1263. #ifndef NOXFER
  1264.     { "query",       XXRQUE,CM_INV },    /* (= REMOTE QUERY) */
  1265. #endif /* NOXFER */
  1266.  
  1267.     { "quit",        XXQUI, 0 },    /* QUIT from program = EXIT */
  1268.  
  1269. #ifndef NOXFER
  1270.     { "r",           XXREC, CM_INV|CM_ABR }, /* Inv synonym for RECEIVE */
  1271. #endif /* NOXFER */
  1272.  
  1273. #ifndef NOXFER
  1274.     { "rasg",        XXRASG, CM_INV },    /* REMOTE ASSIGN */
  1275.     { "rassign",     XXRASG, CM_INV },    /* ditto */
  1276.     { "rcd",         XXRCWD, CM_INV },    /* REMOTE CD */
  1277.     { "rcdup",       XXRCDUP,CM_INV },    /* REMOTE CD */
  1278.     { "rcopy",       XXRCPY, CM_INV },    /* REMOTE COPY */
  1279.     { "rcwd",        XXRCWD, CM_INV },    /* REMOTE CWD */
  1280.     { "rdelete",     XXRDEL, CM_INV },    /* REMOTE DELETE */
  1281.     { "rdirectory",  XXRDIR, CM_INV },    /* REMODE DIRECTORY */
  1282. #endif /* NOXFER */
  1283.  
  1284. #ifndef NOSPL
  1285.     { "read",        XXREA, 0 },    /* READ a line from a file */
  1286. #else
  1287.     { "read",        XXNOTAV, CM_INV },
  1288. #endif /* NOSPL */
  1289.  
  1290. #ifndef NOXFER
  1291.     { "receive",     XXREC, 0 },    /* RECEIVE files */
  1292. #endif /* NOXFER */
  1293.  
  1294. #ifndef NODIAL
  1295.     { "red",         XXRED, CM_INV|CM_ABR|CM_LOC }, /* Inv syn for REDIAL */
  1296.     { "redi",        XXRED, CM_INV|CM_ABR|CM_LOC }, /* ditto */
  1297.     { "redial",      XXRED, CM_LOC },    /* REDIAL last DIAL number */
  1298. #else
  1299.     { "red",         XXNOTAV, CM_INV|CM_LOC },
  1300.     { "redi",        XXNOTAV, CM_INV|CM_LOC },
  1301.     { "redial",      XXNOTAV, CM_INV|CM_LOC },
  1302. #endif /* NODIAL */
  1303.  
  1304. #ifdef CK_REDIR
  1305. #ifdef OS2
  1306. #ifndef NOPUSH
  1307.     { "redirect",    XXFUN, CM_INV|CM_PSH }, /* REDIRECT */
  1308. #else
  1309.     { "redirect",    XXNOTAV, CM_INV|CM_PSH },
  1310. #endif /* NOPUSH */
  1311. #else /* OS2 */
  1312. #ifndef NOPUSH
  1313.     { "redirect",    XXFUN, CM_PSH },    /* REDIRECT */
  1314. #else
  1315.     { "redirect",    XXNOTAV, CM_INV|CM_PSH },
  1316. #endif /* NOPUSH */
  1317. #endif /* OS2 */
  1318. #endif /* CK_REDIR */
  1319.  
  1320. #ifdef CK_RECALL
  1321.     { "redo",        XXREDO,  CM_NOR },    /* REDO */
  1322. #else
  1323.     { "redo",        XXNOTAV, CM_INV },
  1324. #endif /* CK_RECALL */
  1325.  
  1326. #ifndef NOXFER
  1327. #ifdef CK_RESEND
  1328.     { "reget",       XXREGET, 0 },    /* REGET */
  1329. #else
  1330.     { "reget",       XXNOTAV, CM_INV },
  1331. #endif /* CK_RESEND */
  1332. #endif /* NOXFER */
  1333.  
  1334. #ifndef NOSPL
  1335.     { "reinput",     XXREI, CM_INV },    /* REINPUT (from INPUT buffer) */
  1336. #else
  1337.     { "reinput",     XXNOTAV, CM_INV },
  1338. #endif /* NOSPL */
  1339.  
  1340. #ifndef NOXFER
  1341. #ifdef ADDCMD
  1342.     { "rem",         XXREM, CM_INV|CM_ABR },
  1343.     { "remo",        XXREM, CM_INV|CM_ABR },
  1344. #endif /* ADDCMD */
  1345.     { "remote",         XXREM, 0 },    /* Send REMOTE command to server */
  1346. #endif /* NOXFER */
  1347.  
  1348. #ifdef ADDCMD
  1349.     { "remove",      XXREMV,0 },    /* REMOVE (something from a list) */
  1350. #else
  1351.     { "remove",      XXNOTAV, CM_INV },
  1352. #endif /* ADDCMD */
  1353.  
  1354. #ifndef NOFRILLS
  1355. #ifndef NORENAME
  1356.     { "rename",      XXREN, 0 },    /* RENAME a local file */
  1357. #else
  1358.     { "rename",      XXNOTAV, CM_INV },
  1359. #endif /* NORENAME */
  1360.     { "replay",      XXTYP, CM_INV },    /* REPLAY (for now, just type) */
  1361. #endif /* NOFRILLS */
  1362.  
  1363. #ifndef NOXFER
  1364. #ifdef CK_RESEND
  1365.     { "res",         XXRSEN, CM_INV|CM_ABR }, /* RESEND */
  1366.     { "rese",        XXRSEN, CM_INV|CM_ABR }, /* RESEND */
  1367.     { "resend",      XXRSEN, 0 },    /* RESEND */
  1368. #else
  1369.     { "res",         XXNOTAV, CM_INV },
  1370.     { "rese",        XXNOTAV, CM_INV },
  1371.     { "resend",      XXNOTAV, CM_INV },
  1372. #endif /* CK_RESEND */
  1373. #endif /* NOXFER */
  1374.  
  1375.     { "reset",       XXRESET, CM_INV },    /* RESET */
  1376.  
  1377. #ifdef CK_RESEND
  1378. #ifndef NOSPL
  1379.     { "ret",         XXRET, CM_INV|CM_ABR },
  1380. #endif /* NOSPL */
  1381. #endif /* CK_RESEND */
  1382.  
  1383. #ifndef NOXFER
  1384.     { "retrieve",    XXRETR, CM_INV },    /* RETRIEVE */
  1385. #endif /* NOXFER */
  1386.  
  1387. #ifndef NOSPL
  1388.     { "return",      XXRET, 0 },    /* RETURN from a function */
  1389. #else
  1390.     { "return",      XXNOTAV, CM_INV },
  1391. #endif /* NOSPL */
  1392.  
  1393. #ifndef NOXFER
  1394.     { "rexit",       XXRXIT, CM_INV },    /* REMOTE EXIT */
  1395. #endif /* NOXFER */
  1396.  
  1397. #ifdef CK_REXX
  1398. #ifndef NOPUSH
  1399.     { "rexx",        XXREXX, CM_PSH },    /* Execute a Rexx command */
  1400. #else
  1401.     { "rexx",        XXNOTAV, CM_INV|CM_PSH },
  1402. #endif /* NOPUSH */
  1403. #endif /* CK_REXX */
  1404.  
  1405. #ifndef NOXFER
  1406.     { "rhelp",       XXRHLP, CM_INV },    /* REMOTE HELP */
  1407.     { "rhost",       XXRHOS, CM_INV },    /* REMOTE HOST */
  1408.     { "rkermit",     XXRKER, CM_INV },    /* REMOTE KERMIT */
  1409. #endif /* NOXFER */
  1410.  
  1411. #ifdef TCPSOCKET
  1412.     { "rlogin",      XXRLOG, CM_LOC },    /* Make an Rlogin connection */
  1413. #else
  1414.     { "rlogin",      XXNOTAV, CM_INV|CM_LOC },
  1415. #endif /* TCPSOCKET */
  1416.  
  1417. #ifndef NOFRILLS
  1418.     { "rm",          XXDEL, CM_INV },    /* Invisible synonym for delete */
  1419. #endif /* NOFRILLS */
  1420.  
  1421. #ifdef CK_MKDIR
  1422.     { "rmdir",       XXRMDIR, 0 },    /* RMDIR */
  1423. #else
  1424.     { "rmdir",       XXNOTAV, CM_INV },
  1425. #endif /* CK_MKDIR */
  1426.  
  1427. #ifndef NOXFER
  1428.     { "rmkdir",      XXRMKD, CM_INV },    /* REMOTE MKDIR */
  1429. #ifndef NOSPL
  1430.     { "robust",      XXROB,  CM_INV },
  1431. #else
  1432.     { "robust",      XXNOTAV, CM_INV },
  1433. #endif /* NOSPL */
  1434.     { "rprint",      XXRPRI, CM_INV },  /* REMOTE PRINT */
  1435.     { "rpwd",        XXRPWD, CM_INV },    /* REMOTE PWD */
  1436.     { "rquery",      XXRQUE, CM_INV },    /* REMOTE QUERY */
  1437. #endif /* NOXFER */
  1438.  
  1439. #ifdef CK_RECALL
  1440.     { "rr",          XXREDO, CM_INV|CM_NOR },
  1441. #endif /* CK_RECALL */
  1442.  
  1443. #ifndef NOXFER
  1444.     { "rrename",    XXRREN, CM_INV },    /* REMOTE RENAME */
  1445.     { "rrmdir",     XXRRMD, CM_INV },    /* REMOTE REMDIR */
  1446.     { "rset",       XXRSET, CM_INV },    /* REMOTE SET */
  1447.     { "rspace",     XXRSPA, CM_INV },    /* REMOTE SPACE */
  1448.     { "rtype",      XXRTYP, CM_INV },    /* REMOTE TYPE */
  1449. #endif /* NOXFER */
  1450.  
  1451. #ifndef NOPUSH
  1452.     { "run",         XXSHE, CM_PSH },    /* RUN a program or command */
  1453. #else
  1454.     { "run",         XXNOTAV, CM_INV|CM_PSH },
  1455. #endif /* NOPUSH */
  1456.  
  1457. #ifndef NOXFER
  1458.     { "rwho",        XXRWHO, CM_INV },    /* REMOTE WHO */
  1459.     { "s",           XXSEN, CM_INV|CM_ABR }, /* Invisible synonym for send */
  1460. #endif /* NOXFER */
  1461.  
  1462. #ifndef NOSETKEY
  1463. #ifdef OS2
  1464.     { "save",       XXSAVE, 0 },        /* SAVE something */
  1465. #else
  1466.     { "save",       XXSAVE, CM_INV },
  1467. #endif /* OS2 */
  1468. #else
  1469.     { "save",       XXNOTAV, CM_INV },
  1470. #endif /* NOSETKEY */
  1471.  
  1472. #ifndef NOSCRIPT
  1473.     { "sc",        XXLOGI, CM_INV|CM_ABR|CM_LOC },
  1474.     { "scr",       XXLOGI, CM_INV|CM_ABR|CM_LOC },
  1475. #endif /* NOSCRIPT */
  1476.     { "screen",      XXSCRN, 0 },    /* SCREEN actions */
  1477. #ifndef NOSCRIPT
  1478.     { "script",       XXLOGI, CM_LOC },    /* Expect-Send-style script line */
  1479. #else
  1480.     { "script",       XXNOTAV, CM_INV|CM_LOC },
  1481. #endif /* NOSCRIPT */
  1482.  
  1483.     { "search",    XXGREP,CM_INV },    /* Synonym for GREP and FIND */
  1484.  
  1485. #ifndef NOXFER
  1486.     { "send",       XXSEN, 0 },        /* Send (a) file(s) */
  1487. #ifndef NOSERVER
  1488.     { "server",       XXSER, 0 },        /* Be a SERVER */
  1489. #else
  1490.     { "server",       XXNOTAV, CM_INV },
  1491. #endif /* NOSERVER */
  1492. #endif /* NOXFER */
  1493.  
  1494.     { "set",       XXSET, 0 },        /* SET parameters */
  1495.  
  1496. #ifndef NOSPL
  1497. #ifndef NOSEXP
  1498.     { "sexpression", XXSEXP, CM_INV|CM_HLP }, /* SEXPR */
  1499. #endif /* NOSEXP */
  1500. #ifndef NOSHOW
  1501.     { "sh",          XXSHO, CM_INV|CM_ABR }, /* SHOW parameters */
  1502. #endif /* NOSHOW */
  1503.     { "shift",       XXSHIFT, 0 },    /* SHIFT args */
  1504. #else
  1505.     { "shift",       XXNOTAV, CM_INV },
  1506. #endif /* NOSPL */
  1507.  
  1508. #ifndef NOSHOW
  1509.     { "show",        XXSHO, 0 },        /* SHOW parameters */
  1510. #else
  1511.     { "show",        XXNOTAV, CM_INV },
  1512. #endif /* NOSHOW */
  1513.  
  1514. #ifndef NOSPL
  1515. #ifndef NOFRILLS
  1516.     { "sleep",       XXPAU, CM_INV },    /* SLEEP for specified interval */
  1517. #endif /* NOFRILLS */
  1518. #endif /* NOSPL */
  1519.  
  1520. #ifdef NEWFTP
  1521.     { "site",        XXSITE, CM_INV },    /* (FTP) SITE */
  1522. #endif /* NEWFTP */
  1523.  
  1524. #ifndef NOSPL
  1525.     { "sort",        XXSORT, CM_INV },    /* (see ARRAY) */
  1526. #else
  1527.     { "sort",        XXNOTAV, CM_INV },
  1528. #endif /* NOSPL */
  1529.  
  1530. #ifndef MAC
  1531. #ifndef NOFRILLS
  1532.     { "sp",          XXSPA, CM_INV|CM_ABR },
  1533.     { "spa",         XXSPA, CM_INV|CM_ABR },
  1534. #endif /* NOFRILLS */
  1535.     { "space",       XXSPA, 0 },    /* Show available disk SPACE */
  1536. #endif /* MAC */
  1537.  
  1538. #ifndef NOFRILLS
  1539. #ifndef NOPUSH
  1540.     { "spawn",       XXSHE, CM_INV|CM_PSH }, /* Synonym for PUSH, RUN */
  1541. #else
  1542.     { "spawn",       XXNOTAV, CM_INV|CM_PSH }, /* Synonym for PUSH, RUN */
  1543. #endif /* NOPUSH */
  1544. #endif /* NOFRILLS */
  1545.  
  1546. #ifdef ANYSSH
  1547.     { "ssh",         XXSSH, 0 },
  1548. #endif /* ANYSSH */
  1549.  
  1550. #ifndef NOXFER
  1551.     { "sta",         XXSTA, CM_INV|CM_ABR },
  1552.     { "stat",        XXSTA, CM_INV|CM_ABR },
  1553.     { "statistics",  XXSTA, 0 },    /* Display file transfer stats */
  1554. #endif /* NOXFER */
  1555.  
  1556.     { "status",      XXSTATUS,0 },    /* Show status of previous command */
  1557.  
  1558. #ifndef NOSPL
  1559.     { "stop",        XXSTO,   0 },    /* STOP all take files and macros */
  1560.     { "succeed",     XXSUCC,  CM_INV },    /* SUCCEED */
  1561. #else
  1562.     { "stop",        XXNOTAV, CM_INV },
  1563.     { "succeed",     XXNOTAV, CM_INV },
  1564. #endif /* NOSPL */
  1565.  
  1566. #ifndef NOFRILLS
  1567.     { "SUPPORT",     XXBUG, 0 },    /* Tech support instructions */
  1568. #else
  1569.     { "support",     XXNOTAV, CM_INV },
  1570. #endif /* NOFRILLS */
  1571.  
  1572. #ifndef NOJC
  1573.     { "suspend",     XXSUS, CM_PSH },    /* SUSPEND C-Kermit (UNIX only) */
  1574. #else
  1575.     { "suspend",     XXNOTAV, CM_INV|CM_PSH },
  1576. #endif /* NOJC */
  1577.  
  1578. #ifndef NOSPL
  1579.     { "switch",      XXSWIT, 0 },    /* SWITCH */
  1580. #else
  1581.     { "switch",      XXNOTAV, CM_INV },
  1582. #endif /* NOSPL */
  1583.  
  1584. #ifdef CK_TAPI
  1585.     { "ta",       XXTAK, CM_INV|CM_ABR }, /* (because of TAPI) */
  1586. #endif /* CK_TAPI */
  1587.  
  1588. #ifndef NOFRILLS
  1589.     { "tail",        XXTAIL, 0 },    /* Display end of a local file */
  1590. #endif /* NOFRILLS */
  1591.  
  1592.     { "take",       XXTAK, 0 },        /* TAKE commands from a file */
  1593.  
  1594. #ifdef CK_TAPI
  1595.     { "tapi",       XXTAPI, CM_LOC },    /* Microsoft TAPI commands */
  1596. #else
  1597.     { "tapi",       XXNOTAV, CM_INV|CM_LOC },
  1598. #endif /* CK_TAPI */
  1599.  
  1600. #ifndef NOFRILLS
  1601. #ifdef TCPSOCKET
  1602.     { "tel",         XXTEL, CM_INV|CM_ABR|CM_LOC },
  1603.     { "telnet",      XXTEL, CM_LOC },    /* TELNET (TCP/IP only) */
  1604.     { "telopt",      XXTELOP, CM_INV },    /* TELOPT (ditto) */
  1605. #else
  1606.     { "tel",         XXNOTAV, CM_INV|CM_LOC },
  1607.     { "telnet",      XXNOTAV, CM_INV|CM_LOC },
  1608.     { "telopt",      XXNOTAV, CM_INV },
  1609. #endif /* TCPSOCKET */
  1610. #ifdef OS2
  1611.     { "terminal",    XXTERM, CM_INV|CM_LOC }, /* == SET TERMINAL TYPE */
  1612. #else
  1613.     { "terminal",    XXTERM, CM_INV },
  1614. #endif /* OS2 */
  1615. #endif /* NOFRILLS */
  1616. #ifndef NOXFER
  1617.     { "text",        XXASC, CM_INV },    /* == SET FILE TYPE TEXT */
  1618. #endif /* NOXFER */
  1619.  
  1620. #ifndef NOSPL
  1621.     { "trace",       XXTRACE, 0 },    /* TRACE */
  1622. #else
  1623.     { "trace",       XXNOTAV, CM_INV },
  1624. #endif /* NOSPL */
  1625.  
  1626. #ifndef NOCSETS
  1627.     { "translate",   XXXLA, 0 },    /* TRANSLATE local file char sets */
  1628. #else
  1629.     { "translate",   XXNOTAV, CM_INV },
  1630. #endif /* NOCSETS */
  1631.  
  1632. #ifndef NOXMIT
  1633.     { "transmit",    XXTRA, 0 },    /* Send (upload) a file, no protocol */
  1634. #else
  1635.     { "transmit",    XXNOTAV, CM_INV },
  1636. #endif /* NOXMIT */
  1637.  
  1638. #ifndef NOFRILLS
  1639.     { "type",        XXTYP, 0 },    /* Display a local file */
  1640. #endif /* NOFRILLS */
  1641.  
  1642. #ifndef NOSPL
  1643.     { "undcl",       XXUNDCL, CM_INV },
  1644.     { "undeclare",   XXUNDCL, 0 },    /* UNDECLARE an array */
  1645.     { "undefine",    XXUNDEF, 0 },    /* UNDEFINE a variable or macro */
  1646. #else
  1647.     { "undcl",       XXNOTAV, CM_INV },
  1648.     { "undeclare",   XXNOTAV, CM_INV },
  1649.     { "undefine",    XXNOTAV, CM_INV },
  1650. #endif /* NOSPL */
  1651.  
  1652. #ifdef NEWFTP
  1653.     { "user",        XXUSER,  CM_INV }, /* (FTP) USER */
  1654. #endif /* NEWFTP */
  1655.  
  1656.     { "version",     XXVER, 0 },    /* VERSION-number display */
  1657.  
  1658. #ifdef OS2
  1659.     { "viewonly",    XXVIEW, CM_LOC },    /* VIEWONLY Terminal Mode */
  1660. #endif /* OS2 */
  1661.  
  1662.     { "void",        XXVOID, 0 },    /* VOID */
  1663.  
  1664. #ifndef NOSPL
  1665.     { "wait",        XXWAI, 0 },    /* WAIT */
  1666. #else
  1667.     { "wait",        XXNOTAV, CM_INV },
  1668. #endif /* NOSPL */
  1669.  
  1670.     { "wermit",      XXKERMI, CM_INV },
  1671.  
  1672. #ifndef NOXFER
  1673.     { "where",       XXWHERE, 0 },    /* WHERE (did my file go?) */
  1674. #endif /* NOXFER */
  1675.  
  1676. #ifndef NOSPL
  1677.     { "while",       XXWHI, 0 },    /* WHILE loop */
  1678. #else
  1679.     { "while",       XXNOTAV, CM_INV },
  1680. #endif /* NOSPL */
  1681.  
  1682. #ifndef OS2
  1683. #ifndef MAC
  1684. #ifndef NOFRILLS
  1685.     { "who",         XXWHO, CM_PSH },    /* WHO's logged in? */
  1686. #endif /* NOFRILLS */
  1687. #endif /* MAC */
  1688. #endif /* OS2 */
  1689.  
  1690. #ifndef NOHELP
  1691.     { "wildcards",   XXWILD,CM_INV|CM_HLP }, /* Wildcard syntax */
  1692. #endif /* NOHELP */
  1693.  
  1694. #ifndef NOSPL
  1695.     { "wr",          XXWRI, CM_INV|CM_ABR },
  1696.     { "wri",         XXWRI, CM_INV|CM_ABR },
  1697.     { "writ",        XXWRI, CM_INV|CM_ABR },
  1698.     { "write",       XXWRI, 0 },    /* WRITE characters to a file */
  1699.     { "write-line",  XXWRL, CM_INV },    /* WRITE a line to a file */
  1700.     { "writeln",     XXWRL, CM_INV },    /* Pascalisch synonym for write-line */
  1701. #else
  1702.     { "wr",          XXNOTAV, CM_INV },
  1703.     { "wri",         XXNOTAV, CM_INV },
  1704.     { "writ",        XXNOTAV, CM_INV },
  1705.     { "write",       XXNOTAV, CM_INV },
  1706.     { "write-line",  XXNOTAV, CM_INV },
  1707.     { "writeln",     XXNOTAV, CM_INV },
  1708. #endif /* NOSPL */
  1709.  
  1710. #ifndef NOFRILLS
  1711.     { "xecho",       XXXECH,0 },    /* XECHO */
  1712. #endif /* NOFRILLS */
  1713.  
  1714. #ifndef NOSPL
  1715.     { "xif",         XXIFX, CM_INV },    /* Extended IF command (obsolete) */
  1716. #else
  1717.     { "xif",         XXNOTAV, CM_INV },
  1718. #endif /* NOSPL */
  1719.  
  1720. #ifndef NOCSETS
  1721.     { "xlate",       XXXLA, CM_INV },    /* Synonym for TRANSLATE */
  1722. #else
  1723.     { "xlate",       XXNOTAV, CM_INV },
  1724. #endif /* NOCSETS */
  1725.  
  1726. #ifndef NOXMIT
  1727.     { "xmit",        XXTRA, CM_INV },    /* Synonym for TRANSMIT */
  1728. #else
  1729.     { "xmit",        XXNOTAV, CM_INV },
  1730. #endif /* NOXMIT */
  1731.  
  1732. #ifndef OS2
  1733. #ifndef NOJC
  1734.     { "z",           XXSUS, CM_INV|CM_PSH }, /* Synonym for SUSPEND */
  1735. #else
  1736.     { "z",           XXNOTAV, CM_INV|CM_PSH },
  1737. #endif /* NOJC */
  1738. #endif /* OS2 */
  1739.  
  1740. #ifndef NOSPL
  1741.     { "{",           XXMACRO, CM_INV },    /* Immediate macro */
  1742. #endif /* NOSPL */
  1743.     { "", 0, 0 }
  1744. };
  1745. int ncmd = (sizeof(cmdtab) / sizeof(struct keytab)) - 1;
  1746.  
  1747. /* NOTE: Tokens must also be entered above into cmdtab[]. */
  1748.  
  1749. char toktab[] = {
  1750. #ifndef NOPUSH
  1751.     '!',                /* Shell escape */
  1752. #endif /* NOPUSH */
  1753.     '#',                /* Comment */
  1754. #ifndef NOSPL
  1755.     '(',                /* S-Expression */
  1756.     '.',                /* Assignment */
  1757. #endif /* NOSPL */
  1758.     ';',                /* Comment */
  1759. #ifndef NOSPL
  1760.     ':',                /* Label */
  1761. #endif /* NOSPL */
  1762. #ifndef NOPUSH
  1763. #ifdef CK_REDIR
  1764.     '<',                /* REDIRECT */
  1765. #endif /* CK_REDIR */
  1766.     '@',                /* DCL escape */
  1767. #endif /* NOPUSH */
  1768. #ifdef CK_RECALL
  1769.     '^',                /* Command recall */
  1770. #endif /* CK_RECALL */
  1771. #ifndef NOSPL
  1772.     '{',                /* Immediate macro */
  1773. #endif /* NOSPL */
  1774.     '\0'                /* End of this string */
  1775. };
  1776. int xxdot = 0;                /* Used with "." token */
  1777.  
  1778. struct keytab yesno[] = {        /* Yes/No keyword table */
  1779.     { "no",    0, 0 },
  1780.     { "ok",    1, 0 },
  1781.     { "yes",   1, 0 }
  1782. };
  1783. int nyesno = (sizeof(yesno) / sizeof(struct keytab));
  1784.  
  1785. /* Save keyword table */
  1786.  
  1787. struct keytab savtab[] = {
  1788. #ifdef OS2
  1789.     { "command",  XSCMD, 0 },
  1790. #else
  1791. #ifdef CK_RECALL
  1792.     { "command",  XSCMD, 0 },
  1793. #endif /* CK_RECALL */
  1794. #endif /* OS2 */
  1795. #ifndef NOSETKEY
  1796.     { "keymap",   XSKEY, 0 },
  1797. #endif /* NOSETKEY */
  1798. #ifdef OS2
  1799.     { "terminal", XSTERM, 0 },
  1800. #endif /* OS2 */
  1801.     { "", 0, 0 }
  1802. };
  1803. int nsav = (sizeof(savtab) / sizeof(struct keytab)) - 1;
  1804.  
  1805. /* Parameter keyword table */
  1806.  
  1807. struct keytab prmtab[] = {
  1808.     { "alarm",            XYALRM,  0 },
  1809. #ifdef COMMENT                /* SET ANSWER not implemented yet */
  1810. #ifndef NODIAL
  1811.     { "answer",           XYANSWER,0 },
  1812. #endif /* NODIAL */
  1813. #endif /* COMMENT */
  1814.     { "ask-timer",        XYTIMER, 0 },
  1815. #ifndef NOXFER
  1816.     { "attributes",       XYATTR,  0 },
  1817. #endif /* NOXFER */
  1818. #ifdef CK_AUTHENTICATION
  1819.     { "authentication",   XYAUTH,  0 },
  1820. #else  /* CK_AUTHENTICATION */
  1821. #ifdef CK_SSL
  1822.     { "authentication",   XYAUTH,  0 },
  1823. #endif /* CK_SSL */
  1824. #endif /* CK_AUTHENTICATION */
  1825.     { "b",          XYBACK,  CM_INV|CM_ABR|CM_PSH },
  1826.     { "ba",          XYBACK,  CM_INV|CM_ABR|CM_PSH },
  1827. #ifdef VMS
  1828.     { "background",       XYBACK,  CM_INV|CM_PSH },
  1829.     { "batch",            XYBACK,  CM_PSH },
  1830. #else
  1831.     { "background",       XYBACK,  CM_PSH },
  1832.     { "batch",            XYBACK,  CM_INV|CM_PSH },
  1833. #endif /* VMS */
  1834. #ifndef NOLOCAL
  1835.     { "baud",              XYSPEE,  CM_INV|CM_LOC },
  1836. #endif /* NOLOCAL */
  1837.     { "bell",             XYBELL,  0 },
  1838. #ifndef NOXFER
  1839.     { "block-check",        XYCHKT,  0 },
  1840. #endif /* NOXFER */
  1841. #ifdef OS2
  1842. #ifdef BPRINT
  1843.     { "bprinter",         XYBDCP,  CM_INV },
  1844. #endif /* BPRINT */
  1845. #endif /*  OS2 */
  1846. #ifdef BROWSER
  1847.     { "browser",          XYBROWSE,CM_PSH|CM_LOC },
  1848. #endif /* BROWSER */
  1849. #ifndef NOXFER
  1850. #ifdef DYNAMIC
  1851.     { "buffers",          XYBUF,   0 },
  1852. #endif /* DYNAMIC */
  1853. #endif /* NOXFER */
  1854. #ifndef NOLOCAL
  1855. #ifndef MAC
  1856.     { "carrier-watch",    XYCARR,  CM_LOC },
  1857. #endif /* MAC */
  1858. #endif /* NOLOCAL */
  1859. #ifndef NOSPL
  1860.     { "case",             XYCASE,  0 },
  1861. #endif /* NOSPL */
  1862.     { "cd",               XYCD,    0 },
  1863. #ifndef NOXFER
  1864.     { "cl",               XYCLEAR, CM_INV|CM_ABR },
  1865.     { "cle",              XYCLEAR, CM_INV|CM_ABR },
  1866.     { "clea",             XYCLEAR, CM_INV|CM_ABR },
  1867.     { "clear",            XYCLEAR, CM_INV|CM_ABR },
  1868.     { "clear-channel",    XYCLEAR, 0 },
  1869.     { "clearchannel",     XYCLEAR, CM_INV },
  1870. #endif /* NOXFER */
  1871. #ifndef NOLOCAL
  1872.     { "close-on-disconnect", XYDISC, CM_INV|CM_LOC },
  1873. #endif /* NOLOCAL */
  1874.     { "cmd",              XYCMD,   CM_INV },
  1875.     { "command",          XYCMD,   0 },
  1876. #ifdef CK_SPEED
  1877.     { "con",              XYQCTL,  CM_INV|CM_ABR },
  1878. #endif /* CK_SPEED */
  1879.     { "console",          XYCMD,   CM_INV },
  1880. #ifdef CK_SPEED
  1881.     { "control-character",XYQCTL,  0 },
  1882. #endif /* CK_SPEED */
  1883. #ifndef NOSPL
  1884.     { "count",            XYCOUN,  0 },
  1885. #endif /* NOSPL */
  1886. #ifndef NOXFER
  1887.     { "d",          XYDELA,  CM_INV|CM_ABR },
  1888.     { "de",          XYDELA,  CM_INV|CM_ABR },
  1889. #endif /* NOXFER */
  1890.     { "debug",            XYDEBU,  0 },
  1891. #ifdef VMS
  1892.     { "default",          XYDFLT,  0 },
  1893. #else
  1894. #ifndef MAC
  1895.     { "default",          XYDFLT,  CM_INV },
  1896. #endif /* MAC */
  1897. #endif /* VMS */
  1898. #ifndef NOXFER
  1899.     { "delay",              XYDELA,  0 },
  1900.     { "destination",      XYDEST,  0 },
  1901. #endif /* NOXFER */
  1902. #ifndef NODIAL
  1903.     { "di",          XYDIAL,  CM_INV|CM_ABR|CM_LOC },
  1904.     { "dia",          XYDIAL,  CM_INV|CM_ABR|CM_LOC },
  1905.     { "dial",             XYDIAL,  CM_LOC },
  1906. #endif /* NODIAL */
  1907. #ifdef OS2
  1908.     { "dialer",          XYDLR,   CM_INV },
  1909. #endif /* OS2 */
  1910. #ifndef NOLOCAL
  1911.     { "disconnect",       XYDISC,  CM_LOC },
  1912.     { "duplex",              XYDUPL,  CM_LOC },
  1913. #endif /* NOLOCAL */
  1914. #ifndef NOPUSH
  1915. #ifndef NOFRILLS
  1916.     { "editor",           XYEDIT,  CM_PSH },
  1917. #endif /*  NOFRILLS */
  1918. #endif /* NOPUSH */
  1919. #ifdef CK_CTRLZ
  1920.     { "eof",              XYEOF,   CM_INV },
  1921. #endif /* CK_CTRLZ */
  1922. #ifndef NOLOCAL
  1923.     { "escape-character", XYESC,   CM_LOC },
  1924. #endif /* NOLOCAL */
  1925. #ifndef NOSPL
  1926.     { "evaluate",         XYEVAL,  CM_INV },
  1927. #endif /* NOSPL */
  1928.     { "exit",          XYEXIT,  0 },
  1929. #ifndef NOXFER
  1930.     { "f-ack-bug",        XYFACKB, CM_INV },
  1931.     { "f-ack-path",       XYFACKP, CM_INV },
  1932. #endif /* NOXFER */
  1933.     { "file",             XYFILE,  0 },
  1934.     { "fl",                 XYFLOW,  CM_INV|CM_ABR },
  1935. #ifndef NOSPL
  1936.     { "flag",             XYFLAG,  0 },
  1937. #endif /* NOSPL */
  1938. #ifdef TCPSOCKET
  1939. #ifndef SYSFTP
  1940. #ifndef NOFTP
  1941.     { "ft",                 XYFTPX,  CM_INV|CM_ABR },
  1942.     { "ftp",                XYFTPX,  0 },
  1943. #endif /* NOFTP */
  1944. #endif /* SYSFTP */
  1945. #endif /* TCPSOCKET */
  1946. #ifdef BROWSER
  1947.     { "ftp-client",       XYFTP,   CM_PSH },
  1948. #endif /* BROWSER */
  1949.     { "flow-control",       XYFLOW,  0 },
  1950. #ifndef NOSPL
  1951.     { "function",         XYFUNC,  0 },
  1952. #endif /* NOSPL */
  1953. #ifdef NEWFTP
  1954.     { "get-put-remote",   XYGPR,   0 },
  1955. #endif /* NEWFTP */
  1956. #ifdef KUI
  1957.     { "gui",              XYGUI,   0 },
  1958. #endif /* KUI */
  1959.     { "handshake",          XYHAND,  0 },
  1960.     { "hints",            XYHINTS, 0 },
  1961. #ifdef NETCONN
  1962.     { "host",             XYHOST,  CM_LOC },
  1963. #endif /* NETCONN */
  1964. #ifndef NOSPL
  1965.     { "i",          XYINPU,  CM_INV|CM_ABR },
  1966. #endif /* NOSPL */
  1967. #ifdef IKSD
  1968.     { "iks",              XYIKS,   0 },
  1969. #else
  1970.     { "iks",              XYIKS,   CM_INV },
  1971. #endif /* IKSD */
  1972. #ifndef NOSPL
  1973.     { "in",          XYINPU,  CM_INV|CM_ABR },
  1974. #endif /* NOSPL */
  1975. #ifndef NOXFER
  1976.     { "incomplete",         XYIFD,   CM_INV },
  1977. #endif /* NOXFER */
  1978. #ifndef NOSPL
  1979.     { "input",            XYINPU,  0 },
  1980. #endif /* NOSPL */
  1981. #ifndef NOSETKEY
  1982.     { "key",          XYKEY,   0 },
  1983. #endif /* NOSETKEY */
  1984.     { "l",                XYLINE,  CM_INV|CM_ABR },
  1985. #ifndef NOCSETS
  1986.     { "language",         XYLANG,  0 },
  1987. #endif /* NOCSETS */
  1988. #ifndef NOLOCAL
  1989.     { "line",             XYLINE,  CM_LOC },
  1990.     { "local-echo",      XYLCLE,  CM_INV|CM_LOC },
  1991. #endif /* NOLOCAL */
  1992. #ifdef LOCUS
  1993.     { "locus",            XYLOCUS, 0 },
  1994. #endif /* LOCUS */
  1995. #ifndef NOSPL
  1996.     { "login",          XYLOGIN, CM_LOC },
  1997. #endif /* NOSPL */
  1998. #ifndef NOSPL
  1999.     { "macro",            XYMACR,  0 },
  2000. #endif /* NOSPL */
  2001.     { "match",            XYMATCH, 0 },
  2002. #ifdef COMMENT
  2003. #ifdef VMS
  2004.     { "messages",         XYMSGS,  0 },
  2005. #endif /* VMS */
  2006. #endif /* COMMENT */
  2007. #ifndef NODIAL
  2008.     { "modem",          XYMODM,  CM_LOC },
  2009. #endif /* NODIAL */
  2010. #ifndef NOLOCAL
  2011. #ifdef OS2MOUSE
  2012.     { "mouse",          XYMOUSE, 0 },
  2013. #endif /* OS2MOUSE */
  2014. #endif /* NOLOCAL */
  2015. #ifdef OS2
  2016.     { "mskermit",         XYMSK,   0 },
  2017. #endif /* OS2 */
  2018. #ifdef NETCONN
  2019.     { "network",          XYNET,   CM_LOC },
  2020. #endif /* NETCONN */
  2021. #ifndef NOSPL
  2022.     { "output",           XYOUTP,  0 },
  2023. #endif /* NOSPL */
  2024.     { "options",          XYOPTS,  0 },
  2025.     { "pause",            XYSLEEP, CM_INV },
  2026. #ifdef ANYX25
  2027. #ifndef IBMX25
  2028.     { "pad",              XYPAD,   CM_LOC },
  2029. #endif /* IBMX25 */
  2030. #endif /* ANYX25 */
  2031.     { "parity",              XYPARI,  0 },
  2032. #ifndef NOLOCAL
  2033. #ifdef OS2
  2034.     { "port",             XYLINE,  CM_LOC },
  2035. #else
  2036.     { "port",             XYLINE,  CM_INV|CM_LOC },
  2037. #endif /* OS2 */
  2038. #endif /* NOLOCAL */
  2039. #ifndef NOFRILLS
  2040.     { "pr",                 XYPROM,  CM_INV|CM_ABR },
  2041.     { "printer",          XYPRTR,  0 },
  2042. #endif /* NOFRILLS */
  2043. #ifdef OS2
  2044.     { "priority",         XYPRTY,  0 },
  2045. #endif /* OS2 */
  2046. #ifdef CK_SPEED
  2047.     { "prefixing",        XYPREFIX, 0 },
  2048. #endif /* CK_SPEED */
  2049. #ifndef NOFRILLS
  2050.     { "prompt",              XYPROM,  0 },
  2051. #endif /* NOFRILLS */
  2052. #ifndef NOXFER
  2053.     { "protocol",      XYPROTO, 0 },
  2054. #endif /* NOXFER */
  2055.     { "q",          XYQUIE,  CM_INV|CM_ABR },
  2056. #ifndef NOXFER
  2057.     { "q8flag",           XYQ8FLG, CM_INV },
  2058. #endif /* NOXFER */
  2059. #ifdef QNX
  2060.     { "qnx-port-lock",    XYQNXPL, 0 },
  2061. #else
  2062.     { "qnx-port-lock",    XYQNXPL, CM_INV },
  2063. #endif /* QNX */
  2064.     { "quiet",          XYQUIE,  0 },
  2065. #ifndef NOXFER
  2066.     { "rec",              XYRECV,  CM_INV|CM_ABR },
  2067.     { "receive",          XYRECV,  0 },
  2068.     { "recv",             XYRECV,  CM_INV },
  2069. #endif /* NOXFER */
  2070.     { "reliable",         XYRELY,  0 },
  2071. #ifndef NOXFER
  2072.     { "repeat",           XYREPT,  0 },
  2073.     { "retry-limit",      XYRETR,  0 },
  2074. #endif /* NOXFER */
  2075. #ifdef CKROOT
  2076.     { "root",             XYROOT,  0 },
  2077. #endif /* CKROOT */
  2078. #ifndef NOSCRIPT
  2079.     { "script",          XYSCRI,  CM_LOC },
  2080. #endif /* NOSCRIPT */
  2081. #ifndef NOXFER
  2082.     { "send",             XYSEND,  0 },
  2083. #ifndef NOLOCAL
  2084. #ifndef NOSERVER
  2085.     { "ser",              XYSERV,  CM_INV|CM_ABR },
  2086. #endif /* NOSERVER */
  2087. #endif /* NOXFER */
  2088.     { "serial",           XYSERIAL,CM_LOC },
  2089. #endif /* NOLOCAL */
  2090. #ifndef NOSERVER
  2091.     { "server",           XYSERV,  0 },
  2092. #endif /* NOSERVER */
  2093. #ifdef SESLIMIT
  2094. #ifndef NOLOCAL
  2095.     { "session-l",        XYSESS,  CM_INV|CM_ABR },
  2096. #endif /* NOLOCAL */
  2097.     { "session-limit",    XYLIMIT, CM_INV|CM_LOC }, /* Session Limit */
  2098. #endif /* SESLIMIT */
  2099.  
  2100. #ifndef NOLOCAL
  2101.     { "session-log",      XYSESS,  CM_LOC },
  2102. #endif /* NOLOCAL */
  2103.  
  2104. #ifndef NOSPL
  2105. #ifndef NOSEXP
  2106.     { "sexpression",      XYSEXP,  CM_INV },
  2107. #endif /* NOSEXP */
  2108. #endif /* NOSPL */
  2109.  
  2110.     { "sleep",            XYSLEEP, 0 },
  2111.  
  2112. #ifndef NOLOCAL
  2113.     { "speed",              XYSPEE,  CM_LOC },
  2114. #endif /* NOLOCAL */
  2115.  
  2116. #ifdef ANYSSH
  2117.     { "ssh",              XYSSH,   0 },
  2118. #endif /* ANYSSH */
  2119.  
  2120. #ifndef NOSPL
  2121.     { "startup-file",     XYSTARTUP, CM_INV },
  2122. #endif /* NOSPL */
  2123.  
  2124. #ifndef NOLOCAL
  2125. #ifdef HWPARITY
  2126.     { "stop-bits",        XYSTOP, CM_LOC },
  2127. #else
  2128. #ifdef TN_COMPORT
  2129.     { "stop-bits",        XYSTOP, CM_LOC },
  2130. #endif /* TN_COMPORT */
  2131. #endif /* HWPARITY */
  2132. #endif /* NOLOCAL */
  2133.  
  2134. #ifndef NOXFER
  2135. #ifdef STREAMING
  2136.     { "streaming",        XYSTREAM, 0 },
  2137. #endif /* STREAMING */
  2138. #endif /* NOXFER */
  2139.  
  2140. #ifndef NOJC
  2141.     { "suspend",          XYSUSP,  CM_PSH },
  2142. #endif /* NOJC */
  2143. #ifdef CKSYSLOG
  2144.     { "syslog",           XYSYSL,  CM_INV },
  2145. #endif /* CKSYSLOG */
  2146.     { "take",             XYTAKE,  0 },
  2147.  
  2148. #ifdef CK_TAPI
  2149.     { "tapi",             XYTAPI,  CM_LOC },
  2150. #endif /* CK_TAPI */
  2151.  
  2152. #ifndef NOTCPOPTS
  2153. #ifdef TCPSOCKET
  2154.     { "tcp",              XYTCP,   CM_LOC },
  2155. #endif /* TCPSOCKET */
  2156. #endif /* NOTCPOPTS */
  2157.  
  2158. #ifdef TNCODE
  2159.     { "tel",              XYTEL,   CM_INV|CM_ABR },
  2160.     { "telnet",           XYTEL,   0 },
  2161.     { "telopt",           XYTELOP, 0 },
  2162. #endif /* TNCODE */
  2163.  
  2164. #ifndef NOSPL
  2165.     { "temp-directory",   XYTMPDIR,0 },
  2166. #endif /* NOSPL */
  2167.  
  2168. #ifndef NOLOCAL
  2169.     { "terminal",         XYTERM,  CM_LOC },
  2170. #endif /* NOLOCAL */
  2171.  
  2172. #ifdef OS2
  2173.     { "title",          XYTITLE, CM_LOC },
  2174. #endif /* OS2 */
  2175. #ifdef TLOG
  2176.     { "transaction-log",  XYTLOG,  0 },
  2177. #endif /* TLOG */
  2178. #ifndef NOXFER
  2179.     { "transfer",         XYXFER,  0 },
  2180. #endif /* NOXFER */
  2181. #ifndef NOXMIT
  2182.     { "transmit",         XYXMIT,  0 },
  2183. #endif /* NOXMIT */
  2184. #ifndef NOXFER
  2185. #ifndef NOCSETS
  2186.     { "unknown-char-set", XYUNCS,  0 },
  2187. #endif /* NOCSETS */
  2188. #endif /* NOXFER */
  2189.     { "wait",             XYSLEEP, CM_INV },
  2190. #ifndef NOPUSH
  2191. #ifdef UNIX
  2192.     { "wildcard-expansion", XYWILD, 0 },
  2193. #endif /* UNIX */
  2194. #endif /* NOPUSH */
  2195. #ifdef NT
  2196.     { "w",                XYWIND,  CM_INV|CM_ABR },
  2197.     { "wi",               XYWIND,  CM_INV|CM_ABR },
  2198.     { "win",              XYWIND,  CM_INV|CM_ABR },
  2199. #endif /* NT */
  2200.     { "window-size",      XYWIND,  0 },
  2201. #ifdef NT
  2202.     { "win95",            XYWIN95, 0 },
  2203. #endif /* NT */
  2204. #ifdef ANYX25
  2205.     { "x.25",             XYX25,   CM_LOC },
  2206.     { "x25",              XYX25,   CM_INV|CM_LOC },
  2207. #endif /* ANYX25 */
  2208.     { "xfer",             XYXFER,  CM_INV },
  2209. #ifndef NOXMIT
  2210.     { "xmit",             XYXMIT,  CM_INV },
  2211. #endif /* NOXMIT */
  2212.     { "", 0, 0 }
  2213. };
  2214. int nprm = (sizeof(prmtab) / sizeof(struct keytab)) - 1; /* How many */
  2215.  
  2216. struct keytab scntab[] = {        /* Screen commands */
  2217.     { "clear",   SCN_CLR, 0 },
  2218.     { "cleol",   SCN_CLE, 0 },
  2219.     { "move-to", SCN_MOV, 0 }
  2220. };
  2221. int nscntab = (sizeof(scntab) / sizeof(struct keytab)); /* How many */
  2222.  
  2223. #ifdef ANYSSH                /* SSH command table */
  2224. #ifdef SSHBUILTIN
  2225. int    ssh_pf_lcl_n = 0,
  2226.        ssh_pf_rmt_n = 0;
  2227. struct ssh_pf ssh_pf_lcl[32] = { 0, NULL, 0 }; /* SSH Port Forwarding */
  2228. struct ssh_pf ssh_pf_rmt[32] = { 0, NULL, 0 }; /* structs... */
  2229. extern char * ssh_hst, * ssh_cmd, * ssh_prt;
  2230. extern int    ssh_ver,   ssh_xfw;
  2231. char * ssh_tmpuid = NULL, *ssh_tmpcmd = NULL, *ssh_tmpport = NULL,
  2232.      * ssh_tmpstr = NULL;
  2233.  
  2234. int
  2235.  sshk_type = SSHKT_2D,            /* SSH KEY CREATE /TYPE:x */
  2236.  sshk_bits = 1024,            /* SSH KEY CREATE /BITS:n */
  2237.  sshk_din  = SKDF_OSSH,            /* SSH KEY DISPLAY /IN-FORMAT: */
  2238.  sshk_dout = SKDF_OSSH;            /* SSH KEY DISPLAY /OUT-FORMAT: */
  2239.  
  2240. char
  2241.  * sshk1_comment = NULL,        /* SSH V1 COMMENT */
  2242.  * sshkp_old = NULL,            /* Old key passphrase */
  2243.  * sshkp_new = NULL,            /* New key passphrase */
  2244.  * sshkc_pass = NULL,            /* KEY CREATE /PASS:xxx */
  2245.  * sshkc_comm = NULL,            /* KEY CREATE /V1-RSA-COMMENT:xxx */
  2246.  * sshd_file = NULL,            /* DISPLAY file */
  2247.  * sshk_file = NULL;            /* SSH CREATE KEY file */
  2248.  
  2249. static struct keytab sshclr[] = {
  2250.     { "local-port-forward",  SSHC_LPF, 0 },
  2251.     { "remote-port-forward", SSHC_RPF, 0 },
  2252.     { "", 0, 0 }
  2253. };
  2254. static int nsshclr = (sizeof(sshclr) / sizeof(struct keytab)) - 1;
  2255.  
  2256. struct keytab sshopnsw[] = {
  2257.     { "/command",        SSHSW_CMD, CM_ARG },
  2258.     { "/password",       SSHSW_PWD, CM_ARG },
  2259.     { "/subsystem",      SSHSW_SUB, CM_ARG },
  2260.     { "/user",           SSHSW_USR, CM_ARG },
  2261.     { "/version",        SSHSW_VER, CM_ARG },
  2262.     { "/x11-forwarding", SSHSW_X11, CM_ARG },
  2263.     { "", 0, 0 }
  2264. };
  2265. int nsshopnsw = (sizeof(sshopnsw) / sizeof(struct keytab)) - 1;
  2266.  
  2267. static struct keytab sshkwtab[] = {
  2268.     { "add",                 XSSH_ADD, 0 },
  2269.     { "agent",               XSSH_AGT, 0 },
  2270.     { "clear",               XSSH_CLR, 0 },
  2271.     { "forward-local-port",  XSSH_FLP, CM_INV },
  2272.     { "forward-remote-port", XSSH_FRP, CM_INV },
  2273.     { "key",                 XSSH_KEY, 0 },
  2274.     { "open",                XSSH_OPN, 0 },
  2275.     { "v2",                  XSSH_V2,  0 },
  2276.     { "", 0, 0 }
  2277. };
  2278. static int nsshcmd = (sizeof(sshkwtab) / sizeof(struct keytab)) - 1;
  2279.  
  2280. static struct keytab ssh2tab[] = {
  2281.     { "rekey", XSSH2_RKE, 0 },
  2282.     { "", 0, 0 }
  2283. };
  2284. static int nssh2tab = (sizeof(ssh2tab) / sizeof(struct keytab));
  2285.  
  2286. static struct keytab addfwd[] = {    /* SET SSH ADD command table */
  2287.     { "local-port-forward",  SSHF_LCL, 0 },
  2288.     { "remote-port-forward", SSHF_RMT, 0 },
  2289.     { "", 0, 0 }
  2290. };
  2291. static int naddfwd = (sizeof(addfwd) / sizeof(struct keytab)) - 1;
  2292.  
  2293. static struct keytab sshagent[] = {    /* SET SSH AGENT command table */
  2294.     { "add",    SSHA_ADD, 0 },
  2295.     { "delete", SSHA_DEL, 0 },
  2296.     { "list",   SSHA_LST, 0 },
  2297.     { "", 0, 0 }
  2298. };
  2299. static int nsshagent = (sizeof(sshagent) / sizeof(struct keytab)) - 1;
  2300.  
  2301. static struct keytab sshagtsw[] = {    /* SET SSH AGENT LIST switch table */
  2302.     { "/fingerprint", SSHASW_FP, 0 },
  2303.     { "", 0, 0 }
  2304. };
  2305. static int nsshagtsw = (sizeof(sshagtsw) / sizeof(struct keytab)) - 1;
  2306.  
  2307. static struct keytab sshkey[] = {    /* SET SSH KEY command table */
  2308.     { "change-passphrase",  SSHK_PASS, 0 },
  2309.     { "create",             SSHK_CREA, 0 },
  2310.     { "display",            SSHK_DISP, 0 },
  2311.     { "v1",                 SSHK_V1,   0 },
  2312.     { "", 0, 0 }
  2313. };
  2314. static int nsshkey = (sizeof(sshkey) / sizeof(struct keytab)) - 1;
  2315.  
  2316. static struct keytab sshkv1[] = {    /* SET SSH KEY V1 command table */
  2317.     { "set-comment",  1, 0 }
  2318. };
  2319.  
  2320. static struct keytab sshkpsw[] = {    /* SET SSH KEY PASSPHRASE table */
  2321.     { "/new-passphrase",  2, CM_ARG },
  2322.     { "/old-passphrase",  1, CM_ARG }
  2323. };
  2324.  
  2325. static struct keytab sshkcrea[] = {    /* SSH KEY CREATE table */
  2326.     { "/bits",           SSHKC_BI, CM_ARG },
  2327.     { "/passphrase",     SSHKC_PP, CM_ARG },
  2328.     { "/type",           SSHKC_TY, CM_ARG },
  2329.     { "/v1-rsa-comment", SSHKC_1R, CM_ARG }
  2330. };
  2331. static int nsshkcrea = (sizeof(sshkcrea) / sizeof(struct keytab));
  2332.  
  2333. static struct keytab sshkcty[] = {    /* SSH KEY CREATE /TYPE:xxx */
  2334.     { "srp",    SSHKT_SRP, 0 },
  2335.     { "v1-rsa", SSHKT_1R, 0 },
  2336.     { "v2-dsa", SSHKT_2D, 0 },
  2337.     { "v2-rsa", SSHKT_2R, 0 }
  2338. };
  2339. static int nsshkcty = (sizeof(sshkcty) / sizeof(struct keytab));
  2340.  
  2341. static struct keytab sshdswi[] = {    /* SET SSH KEY DISPLAY /switches */
  2342.     { "/format", SSHKD_OUT, CM_ARG }
  2343. };
  2344. static int nsshdswi = (sizeof(sshdswi) / sizeof(struct keytab));
  2345.  
  2346. #ifdef COMMENT
  2347. static struct keytab sshdifmt[] = {    /* SSH KEY DISPLAY /IN-FORMAT: */
  2348.     { "openssh", SKDF_OSSH, 0 },
  2349.     { "ssh.com", SKDF_SSHC, 0 }
  2350. };
  2351. static int nsshdifmt = (sizeof(sshdifmt) / sizeof(struct keytab));
  2352. #endif /* COMMENT */
  2353.  
  2354. static struct keytab sshdofmt[] = {    /* SSH KEY DISPLAY /IN-FORMAT: */
  2355.     { "fingerprint", SKDF_FING, 0 },
  2356.     { "ietf",        SKDF_IETF, 0 },
  2357.     { "openssh",     SKDF_OSSH, 0 },
  2358.     { "ssh.com",     SKDF_SSHC, 0 }
  2359. };
  2360. static int nsshdofmt = (sizeof(sshdofmt) / sizeof(struct keytab));
  2361. #endif /* SSHBUILTIN */
  2362. #endif /* ANYSSH */
  2363.  
  2364. #ifdef NETCONN
  2365. struct keytab netkey[] = {        /* SET NETWORK table */
  2366.     { "directory", XYNET_D,  0 },
  2367.     { "type",      XYNET_T,  0 }
  2368. };
  2369. int nnetkey = (sizeof(netkey) / sizeof(struct keytab));
  2370.  
  2371. struct keytab netcmd[] = {
  2372. /*
  2373.   These are the network types.
  2374. */
  2375. #ifdef NETCMD
  2376.     { "command",       NET_CMD,  CM_INV }, /* Command */
  2377. #endif /* NETCMD */
  2378.  
  2379. #ifdef DECNET                /* DECnet / PATHWORKS */
  2380.     { "decnet",        NET_DEC,  0 },
  2381. #endif /* DECNET */
  2382.  
  2383. #ifdef NETDLL
  2384.     { "dll",           NET_DLL,  CM_INV }, /* DLL to be loaded */
  2385. #endif /* NETDLL */
  2386.  
  2387. #ifdef NETFILE
  2388.     { "file",           NET_FILE, CM_INV }, /* FILE (real crude) */
  2389. #endif /* NETFILE */
  2390.  
  2391. #ifdef NPIPE                /* Named Pipes */
  2392.     { "named-pipe",     NET_PIPE,  0 },
  2393. #endif /* NPIPE */
  2394.  
  2395. #ifdef CK_NETBIOS
  2396.     { "netbios",        NET_BIOS,  0 },    /* NETBIOS */
  2397. #endif /* CK_NETBIOS */
  2398.  
  2399. #ifdef DECNET                /* DECnet / PATHWORKS (alias) */
  2400.     { "pathworks",     NET_DEC,  CM_INV },
  2401. #endif /* DECNET */
  2402.  
  2403. #ifdef NETCMD
  2404.     { "pipe",          NET_CMD,  0 },    /* Pipe */
  2405. #endif /* NETCMD */
  2406.  
  2407. #ifdef NETPTY
  2408.     { "pseudoterminal",NET_PTY, 0 },    /* Pseudoterminal */
  2409. #endif /* NETPTY */
  2410.  
  2411. #ifdef NETPTY
  2412.     { "pty",          NET_PTY,  CM_INV }, /* Inv syn for pseudoterm */
  2413. #endif /* NETPTY */
  2414.  
  2415. #ifdef SSHBUILTIN
  2416.     { "ssh",          NET_SSH,  0 },
  2417. #endif /* SSHBUILTIN */
  2418.  
  2419. #ifdef SUPERLAT
  2420.     { "superlat",     NET_SLAT, 0 },    /* Meridian Technologies' SuperLAT */
  2421. #endif /* SUPERLAT */
  2422.  
  2423. #ifdef TCPSOCKET            /* TCP/IP sockets library */
  2424.     { "tcp/ip",       NET_TCPB, 0 },
  2425. #endif /* TCPSOCKET */
  2426. #ifdef SUPERLAT
  2427.     { "tes32",        NET_SLAT, 0 },    /* Emulux TES32 */
  2428. #endif /* SUPERLAT */
  2429. #ifdef ANYX25                /* X.25 */
  2430. #ifdef SUNX25
  2431.     { "x",            NET_SX25, CM_INV|CM_ABR },
  2432.     { "x.25",         NET_SX25, 0 },
  2433.     { "x25",          NET_SX25, CM_INV },
  2434. #else
  2435. #ifdef STRATUSX25
  2436.     { "x",            NET_VX25, CM_INV|CM_ABR },
  2437.     { "x.25",         NET_VX25, 0 },
  2438.     { "x25",          NET_VX25, CM_INV },
  2439. #endif /* STRATUSX25 */
  2440. #endif /* SUNX25 */
  2441. #ifdef IBMX25
  2442.     { "x",            NET_IX25, CM_INV|CM_ABR },
  2443.     { "x.25",         NET_IX25, CM_INV },
  2444.     { "x25",          NET_IX25, CM_INV },
  2445. #endif /* IBMX25 */
  2446. #ifdef HPX25
  2447.     { "x",            NET_IX25, CM_INV|CM_ABR },
  2448.     { "x.25",         NET_IX25, 0 },
  2449.     { "x25",          NET_IX25, CM_INV },
  2450. #endif /* HPX25 */
  2451. #endif /* ANYX25 */
  2452.     { "", 0, 0 }
  2453. };
  2454. int nnets = (sizeof(netcmd) / sizeof(struct keytab));
  2455.  
  2456. #ifndef NOTCPOPTS
  2457. #ifdef TCPSOCKET
  2458.  
  2459. /* TCP options */
  2460.  
  2461. struct keytab tcpopt[] = {
  2462.     { "address",   XYTCP_ADDRESS, 0 },
  2463. #ifdef CK_DNS_SRV
  2464.     { "dns-service-records", XYTCP_DNS_SRV, 0 },
  2465. #endif /* CK_DNS_SRV */
  2466. #ifdef SO_DONTROUTE
  2467.     { "dontroute",   XYTCP_DONTROUTE, 0 },
  2468. #endif /* SO_DONTROUTE */
  2469. #ifndef NOHTTP
  2470.     { "http-proxy", XYTCP_HTTP_PROXY, 0 },
  2471. #endif /* NOHTTP */
  2472. #ifdef SO_KEEPALIVE
  2473.     { "keepalive", XYTCP_KEEPALIVE, 0 },
  2474. #endif /* SO_KEEPALIVE */
  2475. #ifdef SO_LINGER
  2476.     { "linger", XYTCP_LINGER, 0 },
  2477. #endif /* SO_LINGER */
  2478. #ifdef TCP_NODELAY
  2479.     { "nagle",  XYTCP_NAGLE,    CM_INV },
  2480.     { "nodelay", XYTCP_NODELAY, 0 },
  2481. #endif /* TCP_NODELAY */
  2482.     { "reverse-dns-lookup", XYTCP_RDNS, 0 },
  2483. #ifdef SO_RCVBUF
  2484.     { "recvbuf", XYTCP_RECVBUF, 0 },
  2485. #endif /* SO_RCVBUF */
  2486. #ifdef SO_SNDBUF
  2487.     { "sendbuf", XYTCP_SENDBUF, 0 },
  2488. #endif /* SO_SNDBUF */
  2489. #ifdef NT
  2490. #ifdef CK_SOCKS
  2491.     { "socks-server", XYTCP_SOCKS_SVR, 0 },
  2492. #endif /* CK_SOCKS */
  2493. #endif /* NT */
  2494. #ifdef VMS
  2495. #ifdef DEC_TCPIP
  2496.     { "ucx-port-bug", XYTCP_UCX, 0 },
  2497. #endif /* DEC_TCPIP */
  2498. #endif /* VMS */
  2499.     { "",0,0 }
  2500. };
  2501. int ntcpopt = (sizeof(tcpopt) / sizeof(struct keytab));
  2502. #endif /* TCPSOCKET */
  2503. #endif /* NOTCPOPTS */
  2504. #endif /* NETCONN */
  2505.  
  2506. #ifdef OS2
  2507. /* K95 Manual Chapter Table -- Keep these two tables in sync! */
  2508.  
  2509. static char * linktbl[] = {        /* Internal links in k95.htm */
  2510.     "#top",                /* 00 */
  2511.     "#what",                /* 01 */
  2512.     "#install",                /* 02 */
  2513.     "#start",                /* 03 */
  2514.     "#dialer",                /* 04 */
  2515.     "#entries",                /* 05 */
  2516.     "#command",                /* 06 */
  2517.     "#terminal",            /* 07 */
  2518.     "#transfer",            /* 08 */
  2519.     "#hostmode"                /* 09 */
  2520. };
  2521.  
  2522. static struct keytab chaptbl[] = {
  2523.     { "Command-Screen",     6, 0 },
  2524.     { "Contents",           0, 0 },
  2525.     { "Dialer-Entries",     5, 0 },
  2526.     { "File-Transfer",      8, 0 },
  2527.     { "Getting-Started",    3, 0 },
  2528.     { "Host-Mode",          9, 0 },
  2529.     { "Installation",       2, 0 },
  2530.     { "Terminal-Emulation", 7, 0 },
  2531.     { "Using-The-Dialer",   4, 0 },
  2532.     { "What-Is-K95",        1, 0 },
  2533.     { "",                   0, 0 }
  2534. };
  2535. static int nchaptbl = (sizeof(chaptbl) / sizeof(struct keytab) - 1);
  2536. #endif /* OS2 */
  2537.  
  2538. #ifndef NOXFER
  2539. /* Remote Command Table */
  2540.  
  2541. struct keytab remcmd[] = {
  2542. #ifndef NOSPL
  2543.     { "as",        XZASG, CM_INV|CM_ABR },
  2544.     { "asg",       XZASG, CM_INV },
  2545.     { "assign",    XZASG, 0 },
  2546. #endif /* NOSPL */
  2547.     { "cd",        XZCWD, 0 },
  2548.     { "cdup",      XZCDU, CM_INV },
  2549.     { "copy",      XZCPY, 0 },
  2550.     { "cwd",       XZCWD, CM_INV },
  2551.     { "delete",    XZDEL, 0 },
  2552.     { "directory", XZDIR, 0 },
  2553.     { "e",         XZXIT, CM_ABR|CM_INV },
  2554.     { "erase",     XZDEL, CM_INV },
  2555.     { "exit",      XZXIT, 0 },
  2556.     { "help",      XZHLP, 0 },
  2557. #ifndef NOPUSH
  2558.     { "host",      XZHOS, 0 },
  2559. #endif /* NOPUSH */
  2560. #ifndef NOFRILLS
  2561.     { "kermit",    XZKER, 0 },
  2562.     { "l",         XZLGI, CM_ABR|CM_INV },
  2563.     { "lo",        XZLGI, CM_ABR|CM_INV },
  2564.     { "log",       XZLGI, CM_ABR|CM_INV },
  2565.     { "login",     XZLGI, 0 },
  2566.     { "logout",    XZLGO, 0 },
  2567.     { "mkdir",     XZMKD, 0 },
  2568.     { "print",     XZPRI, 0 },
  2569. #endif /* NOFRILLS */
  2570.     { "pwd",       XZPWD, 0 },
  2571. #ifndef NOSPL
  2572.     { "query",       XZQUE, 0 },
  2573. #endif /* NOSPL */
  2574.     { "rename",    XZREN, 0 },
  2575.     { "rmdir",     XZRMD, 0 },
  2576.     { "set",       XZSET, 0 },
  2577.     { "space",       XZSPA, 0 },
  2578. #ifndef NOFRILLS
  2579.     { "type",      XZTYP, 0 },
  2580.     { "who",       XZWHO, 0 },
  2581. #endif /* NOFRILLS */
  2582.     { "", 0, 0}
  2583. };
  2584. int nrmt = (sizeof(remcmd) / sizeof(struct keytab)) - 1;
  2585. #endif /* NOXFER */
  2586.  
  2587. struct keytab logtab[] = {
  2588. #ifdef CKLOGDIAL
  2589.     { "connections",  LOGM, CM_INV },
  2590.     { "cx",           LOGM, 0 },
  2591. #endif /* CKLOGDIAL */
  2592. #ifdef DEBUG
  2593.     { "debugging",    LOGD, 0 },
  2594. #endif /* DEBUG */
  2595.     { "packets",      LOGP, 0 },
  2596. #ifndef NOLOCAL
  2597.     { "session",      LOGS, 0 },
  2598. #endif /* NOLOCAL */
  2599. #ifdef TLOG
  2600.     { "transactions", LOGT, 0 },
  2601. #endif /* TLOG */
  2602.     { "", 0, 0 }
  2603. };
  2604. int nlog = (sizeof(logtab) / sizeof(struct keytab)) - 1;
  2605.  
  2606. struct keytab writab[] = {
  2607. #ifndef NOSPL
  2608.     { "append-file",     LOGW, CM_INV },
  2609. #endif /* NOSPL */
  2610.     { "debug-log",       LOGD, 0 },
  2611.     { "error",           LOGE, 0 },
  2612. #ifndef NOSPL
  2613.     { "file",            LOGW, 0 },
  2614. #endif /* NOSPL */
  2615.     { "packet-log",      LOGP, 0 },
  2616.     { "screen",          LOGX, 0 },
  2617. #ifndef NOLOCAL
  2618.     { "session-log",     LOGS, 0 },
  2619. #endif /* NOLOCAL */
  2620.     { "sys$output",      LOGX, CM_INV },
  2621.     { "t",               LOGT, CM_ABR|CM_INV }, /* Because of a typo in */
  2622.     { "tr",              LOGT, CM_ABR|CM_INV }, /* the book... */
  2623.     { "tra",             LOGT, CM_ABR|CM_INV },
  2624.     { "tran",            LOGT, CM_ABR|CM_INV },
  2625.     { "trans",           LOGT, CM_ABR|CM_INV },
  2626.     { "transa",          LOGT, CM_ABR|CM_INV },
  2627.     { "transac",         LOGT, CM_ABR|CM_INV },
  2628.     { "transact",        LOGT, CM_ABR|CM_INV },
  2629.     { "transacti",       LOGT, CM_ABR|CM_INV },
  2630.     { "transactio",      LOGT, CM_ABR|CM_INV },
  2631.     { "transaction",     LOGT, CM_ABR|CM_INV },
  2632.     { "transaction-log", LOGT, 0 },
  2633.     { "transactions",    LOGT, CM_INV }
  2634. };
  2635. int nwri = (sizeof(writab) / sizeof(struct keytab));
  2636.  
  2637. #ifdef COMMENT                /* INPUT switches not used yet... */
  2638. static struct keytab inswtab[] = {
  2639. #ifdef COMMENT
  2640.     { "/assign",       IN_ASG, CM_ARG },
  2641. #endif /* COMMENT */
  2642.     { "/autodownload", IN_ADL, CM_ARG },
  2643.     { "/case",         IN_CAS, CM_ARG },
  2644.     { "/echo",         IN_ECH, CM_ARG },
  2645.     { "/interrupts",   IN_NOI, CM_ARG },
  2646.     { "/silence",      IN_SIL, CM_ARG },
  2647. #ifdef COMMENT
  2648.     { "/pattern",      IN_PAT, CM_ARG },
  2649. #endif /* COMMENT */
  2650.     { "", 0, 0 }
  2651. };
  2652. static int ninswtab = (sizeof(inswtab) / sizeof(struct keytab)) - 1;
  2653. #endif /* COMMENT */
  2654.  
  2655. static struct keytab clrtab[] = {    /* Keywords for CLEAR command */
  2656. #ifndef NOSPL
  2657.     { "alarm",            CLR_ALR,         0 },
  2658. #ifdef CK_APC
  2659.     { "apc",              CLR_APC,         0 },
  2660. #endif /* CK_APC */
  2661. #ifdef PATTERNS
  2662.     { "binary-patterns",  CLR_BIN,         0 },
  2663. #endif /* PATTERNS */
  2664.     { "both",             CLR_DEV|CLR_INP, CM_INV },
  2665. #endif /* NOSPL */
  2666. #ifdef OS2
  2667.     { "command-screen",   CLR_CMD,         0 },
  2668. #endif /* OS2 */
  2669. #ifndef NOSPL
  2670.     { "device",           CLR_DEV,         CM_INV|CM_ABR },
  2671.     { "device-and-input", CLR_DEV|CLR_INP, 0 },
  2672. #endif /* NOSPL */
  2673.     { "device-buffer",    CLR_DEV,         0 },
  2674. #ifndef NODIAL
  2675.     { "dial-status",      CLR_DIA,     0 },
  2676. #endif /* NODIAL */
  2677. #ifndef NOSPL
  2678.     { "input-buffer",     CLR_INP,         0 },
  2679. #endif /* NOSPL */
  2680.     { "keyboard-buffer",  CLR_KBD,         0 },
  2681.     { "send-list",        CLR_SFL,         0 },
  2682. #ifdef OS2
  2683.     { "scr",              CLR_SCL,         CM_INV|CM_ABR },
  2684. #endif /* OS2 */
  2685.     { "screen",           CLR_SCR,         0 },
  2686. #ifdef OS2
  2687.     { "scrollback",       CLR_SCL,         CM_INV },
  2688.     { "terminal-screen",  CLR_TRM,         0 },
  2689. #endif /* OS2 */
  2690. #ifdef PATTERNS
  2691.     { "text-patterns",    CLR_TXT,         0 },
  2692. #endif /* PATTERNS */
  2693.     { "", 0, 0 }
  2694. };
  2695. int nclear = (sizeof(clrtab) / sizeof(struct keytab)) - 1;
  2696.  
  2697. struct keytab clstab[] = {        /* Keywords for CLOSE command */
  2698. #ifndef NOSPL
  2699.     { "!read",           LOGR, CM_INV },
  2700.     { "!write",          LOGW, CM_INV },
  2701. #ifndef NOPUSH
  2702. #endif /* NOPUSH */
  2703. #endif /* NOSPL */
  2704. #ifndef NOSPL
  2705.     { "append-file",     LOGW, CM_INV },
  2706. #endif /* NOSPL */
  2707. #ifndef NOLOCAL
  2708.     { "connection",      9999, 0 },
  2709. #endif /* NOLOCAL */
  2710. #ifdef CKLOGDIAL
  2711.     { "cx-log",          LOGM, 0 },
  2712. #endif /* CKLOGDIAL */
  2713. #ifdef DEBUG
  2714.     { "debug-log",       LOGD, 0 },
  2715. #endif /* DEBUG */
  2716.     { "host",            9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
  2717.     { "line",            9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
  2718.     { "p",               LOGP, CM_INV|CM_ABR },
  2719.     { "packet-log",      LOGP, 0 },
  2720.     { "port",            9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
  2721. #ifndef NOSPL
  2722.     { "read-file",       LOGR, 0 },
  2723. #endif /* NOSPL */
  2724. #ifndef NOLOCAL
  2725.     { "session-log",     LOGS, 0 },
  2726. #endif /* NOLOCAL */
  2727. #ifdef TLOG
  2728.     { "t",               LOGT, CM_ABR|CM_INV }, /* Because of a typo in */
  2729.     { "tr",              LOGT, CM_ABR|CM_INV }, /* the book... */
  2730.     { "tra",             LOGT, CM_ABR|CM_INV },
  2731.     { "tran",            LOGT, CM_ABR|CM_INV },
  2732.     { "trans",           LOGT, CM_ABR|CM_INV },
  2733.     { "transa",          LOGT, CM_ABR|CM_INV },
  2734.     { "transac",         LOGT, CM_ABR|CM_INV },
  2735.     { "transact",        LOGT, CM_ABR|CM_INV },
  2736.     { "transacti",       LOGT, CM_ABR|CM_INV },
  2737.     { "transactio",      LOGT, CM_ABR|CM_INV },
  2738.     { "transaction",     LOGT, CM_ABR|CM_INV },
  2739.     { "transaction-log", LOGT, 0 },
  2740.     { "transactions",    LOGT, CM_INV },
  2741. #endif /* TLOG */
  2742. #ifndef NOSPL
  2743.     { "write-file",      LOGW, 0 },
  2744. #endif /* NOSPL */
  2745.     { "", 0, 0 }
  2746. };
  2747. int ncls = (sizeof(clstab) / sizeof(struct keytab)) - 1;
  2748.  
  2749. /* SHOW command arguments */
  2750.  
  2751. #ifndef NOSHOW
  2752. struct keytab shotab[] = {
  2753. #ifndef NOSPL
  2754.     { "alarm",        SHALRM, 0 },
  2755.     { "arg",          SHARG, CM_INV|CM_ABR },
  2756.     { "arguments",    SHARG, 0 },
  2757.     { "args",         SHARG, CM_INV },
  2758.     { "arrays",       SHARR, 0 },
  2759. #endif /* NOSPL */
  2760.  
  2761. #ifndef NOCSETS
  2762.     { "associations", SHASSOC, 0 },
  2763. #endif /* NOCSETS */
  2764.  
  2765. #ifndef NOXFER
  2766.     { "attributes",   SHATT, 0 },
  2767. #endif /* NOXFER */
  2768.  
  2769. #ifdef CK_AUTHENTICATION
  2770.     { "authentication", SHOAUTH, CM_INV },
  2771. #endif /* CK_AUTHENTICATION */
  2772.  
  2773. #ifndef NOPUSH
  2774. #ifdef BROWSER
  2775.     { "browser",      SHBROWSE, CM_PSH|CM_LOC },
  2776. #endif /*  BROWSER */
  2777. #endif /* NOPUSH */
  2778.     { "cd",           SHCD, 0 },
  2779.     { "character-sets", SHCSE, 0 },
  2780.     { "cmd",          SHCMD, CM_INV },
  2781. #ifndef NOLOCAL
  2782.     { "com",          SHCOM, CM_INV|CM_ABR },
  2783.     { "comm",         SHCOM, CM_INV|CM_ABR },
  2784.     { "communications", SHCOM, 0 },
  2785. #endif /* NOLOCAL */
  2786.     { "command",      SHCMD, 0 },
  2787.     { "connection",   SHCONNX, 0 },
  2788. #ifdef CK_SPEED
  2789.     { "control-prefixing", SHCTL, 0 },
  2790. #endif /* CK_SPEED */
  2791. #ifdef CKLOGDIAL
  2792.     { "cx",           SHCONNX, CM_INV },
  2793. #endif /* CKLOGDIAL */
  2794. #ifndef NOSPL
  2795.     { "count",        SHCOU, 0 },
  2796. #endif /* NOSPL */
  2797.     { "d",            SHDIA, CM_INV|CM_ABR },
  2798. #ifdef VMS
  2799.     { "default",      SHDFLT, 0 },
  2800. #else
  2801.     { "default",      SHDFLT, CM_INV },
  2802. #endif /* VMS */
  2803. #ifndef NODIAL
  2804.     { "dial",         SHDIA, CM_LOC },
  2805. #endif /* NODIAL */
  2806.     { "double/ignore",SHDBL, 0 },
  2807. #ifndef NOPUSH
  2808. #ifndef NOFRILLS
  2809.     { "editor",       SHEDIT, CM_PSH },
  2810. #endif /*  NOFRILLS */
  2811. #endif /* NOPUSH */
  2812. #ifndef NOLOCAL
  2813.     { "escape",       SHESC, CM_LOC },
  2814. #endif /* NOLOCAL */
  2815.     { "exit",         SHEXI, 0 },
  2816.     { "extended-options", SHXOPT, CM_INV },
  2817.     { "features",     SHFEA, 0 },
  2818.     { "file",         SHFIL, 0 },
  2819. #ifndef NOLOCAL
  2820.     { "flow-control", SHOFLO, 0 },
  2821. #endif /* NOLOCAL */
  2822. #ifdef BROWSER
  2823.     { "ftp",          SHOFTP, CM_PSH|CM_LOC },
  2824. #else
  2825. #ifndef NOFTP
  2826. #ifndef SYSFTP
  2827. #ifdef TCPSOCKET
  2828.     { "ftp",          SHOFTP, 0 },    /* (built-in ftp) */
  2829. #endif /* TCPSOCKET */
  2830. #endif /* SYSFTP */
  2831. #endif /* NOFTP */
  2832. #endif /* BROWSER */
  2833. #ifndef NOSPL
  2834.     { "functions",    SHFUN, 0 },
  2835.     { "globals",      SHVAR, 0 },
  2836. #endif /* NOSPL */
  2837. #ifdef KUI
  2838.     { "gui",          SHOGUI, 0 },
  2839. #endif /* KUI */
  2840. #ifdef CK_RECALL
  2841.     { "history",      SHHISTORY, 0 },
  2842. #endif /* CK_RECALL */
  2843.     { "ignore/double",SHDBL, CM_INV },
  2844.     { "iksd",         SHOIKS, CM_INV },
  2845. #ifndef NOSPL
  2846.     { "input",        SHINP, 0 },
  2847. #endif /* NOSPL */
  2848. #ifndef NOSETKEY
  2849.     { "k",            SHKEY, CM_INV|CM_ABR },
  2850.     { "key",          SHKEY, 0 },
  2851. #ifndef NOKVERBS
  2852.     { "kverbs",       SHKVB, 0 },
  2853. #endif /* NOKVERBS */
  2854. #endif /* NOSETKEY */
  2855. #ifdef CK_LABELED
  2856.     { "labeled-file-info", SHLBL, 0 },
  2857. #endif /* CK_LABELED */
  2858. #ifndef NOCSETS
  2859.     { "languages",    SHLNG, 0 },
  2860. #endif /* NOCSETS */
  2861.     { "logs",         SHLOG, 0 },
  2862. #ifndef NOSPL
  2863.     { "macros",       SHMAC, 0 },
  2864. #endif /* NOSPL */
  2865. #ifndef NODIAL
  2866.     { "modem",        SHMOD, CM_LOC },
  2867. #else
  2868.     { "modem-signals",SHCOM, CM_INV|CM_LOC },
  2869. #endif /* NODIAL */
  2870. #ifndef NOLOCAL
  2871. #ifdef OS2MOUSE
  2872.     { "mouse",        SHMOU, CM_LOC },
  2873. #endif /* OS2MOUSE */
  2874. #endif /* NOLOCAL */
  2875. #ifdef NETCONN
  2876.     { "network",      SHNET, CM_LOC },
  2877. #else
  2878.     { "network",      SHNET, CM_INV|CM_LOC },
  2879. #endif /* NETCONN */
  2880.     { "options",      SHOPTS, 0 },
  2881. #ifndef NOSPL
  2882.     { "output",       SHOUTP, CM_INV },
  2883. #endif /* NOSPL */
  2884. #ifdef ANYX25
  2885. #ifndef IBMX25
  2886.     { "pad",          SHPAD,  CM_LOC },
  2887. #endif /* IBMX25 */
  2888. #endif /* ANYX25 */
  2889.     { "parameters",   SHPAR,  CM_INV },
  2890. #ifdef PATTERNS
  2891.     { "patterns",     SHOPAT, 0 },
  2892. #endif /* PATTERNS */
  2893.     { "printer",      SHPRT,  0 },
  2894. #ifdef CK_SPEED
  2895.     { "prefixing",    SHCTL,  CM_INV },
  2896. #endif /* CK_SPEED */
  2897. #ifndef NOXFER
  2898.     { "protocol",     SHPRO,  0 },
  2899. #endif /* NOXFER */
  2900. #ifndef NOSPL
  2901.     { "scripts",      SHSCR,  CM_LOC },
  2902. #endif /* NOSPL */
  2903.     { "send-list",    SHSFL,  0 },
  2904. #ifndef NOSERVER
  2905.     { "server",       SHSER,  0 },
  2906. #endif /* NOSERVER */
  2907. #ifndef NOSEXP
  2908.     { "sexpression",  SHSEXP, 0 },
  2909. #endif /* NOSEXP */
  2910. #ifdef ANYSSH
  2911.     { "ssh",          SHOSSH, 0 },
  2912. #endif /* ANYSSH */
  2913.     { "stack",        SHSTK,  0 },
  2914.     { "status",       SHSTA,  0 },
  2915. #ifdef STREAMING
  2916.     { "streaming",    SHOSTR, 0 },
  2917. #endif /* STREAMING */
  2918. #ifndef NOLOCAL
  2919. #ifdef OS2
  2920.     { "tabs",          SHTAB, CM_INV|CM_LOC },
  2921. #endif /* OS2 */
  2922. #ifdef CK_TAPI
  2923.     { "tapi",          SHTAPI, CM_LOC },
  2924.     { "tapi-comm",     SHTAPI_C, CM_INV|CM_LOC },
  2925.     { "tapi-location", SHTAPI_L, CM_INV|CM_LOC },
  2926.     { "tapi-modem",    SHTAPI_M, CM_INV|CM_LOC },
  2927. #endif /* CK_TAPI */
  2928.     { "tcp",           SHTCP,  CM_LOC },
  2929. #ifdef TNCODE
  2930.     { "tel",           SHTEL,  CM_INV|CM_ABR },
  2931.     { "telnet",        SHTEL,  0 },
  2932.     { "telopt",        SHTOPT, 0 },
  2933. #endif /* TNCODE */
  2934.     { "terminal",      SHTER,  CM_LOC },
  2935. #endif /* NOLOCAL */
  2936. #ifndef NOXMIT
  2937.     { "tr",            SHXMI, CM_INV|CM_ABR },
  2938.     { "tra",           SHXMI, CM_INV|CM_ABR },
  2939.     { "tran",          SHXMI, CM_INV|CM_ABR },
  2940.     { "trans",         SHXMI, CM_INV|CM_ABR },
  2941. #endif /* NOXMIT */
  2942. #ifndef NOXFER
  2943.     { "transfer",      SHOXFER, 0 },
  2944. #endif /* NOXFER */
  2945. #ifndef NOXMIT
  2946.     { "transmit",      SHXMI, 0 },
  2947. #endif /* NOXMIT */
  2948. #ifdef CK_TRIGGER
  2949.     { "trigger",       SHTRIG, CM_LOC },
  2950. #endif /* CK_TRIGGER */
  2951. #ifndef NOSETKEY
  2952. #ifndef NOKVERBS
  2953. #ifdef OS2
  2954.     { "udk",           SHUDK, CM_LOC },
  2955. #endif /* OS2 */
  2956. #endif /* NOKVERBS */
  2957. #endif /* NOSETKEY */
  2958. #ifndef NOSPL
  2959.     { "variables",     SHBUI, 0 },
  2960. #endif /* NOSPL */
  2961. #ifndef NOFRILLS
  2962.     { "versions",      SHVER, 0 },
  2963. #endif /* NOFRILLS */
  2964. #ifdef OS2
  2965.     { "vscrn",         SHVSCRN, CM_INV|CM_LOC },
  2966. #endif /* OS2 */
  2967.     { "xfer",          SHOXFER,  CM_INV },
  2968. #ifndef NOXMIT
  2969.     { "xmit",          SHXMI,    CM_INV },
  2970. #endif /* NOXMIT */
  2971.     { "", 0, 0 }
  2972. };
  2973. int nsho = (sizeof(shotab) / sizeof(struct keytab)) - 1;
  2974. #endif /* NOSHOW */
  2975.  
  2976. #ifdef ANYX25
  2977. #ifndef IBMX25
  2978. struct keytab padtab[] = {              /* PAD commands */
  2979.     { "clear",      XYPADL, 0 },
  2980.     { "interrupt",  XYPADI, 0 },
  2981.     { "reset",      XYPADR, 0 },
  2982.     { "status",     XYPADS, 0 }
  2983. };
  2984. int npadc = (sizeof(padtab) / sizeof(struct keytab));
  2985. #endif /* IBMX25 */
  2986. #endif /* ANYX25 */
  2987.  
  2988. #ifndef NOSERVER
  2989. static struct keytab kmstab[] = {
  2990.     { "both",    3, 0 },
  2991.     { "local",   1, 0 },
  2992.     { "remote",  2, 0 }
  2993. };
  2994.  
  2995. static struct keytab enatab[] = {    /* ENABLE commands */
  2996.     { "all",        EN_ALL,  0 },
  2997. #ifndef NOSPL
  2998.     { "as",         EN_ASG,  CM_INV|CM_ABR },
  2999.     { "asg",        EN_ASG,  CM_INV },
  3000.     { "assign",     EN_ASG,  0 },
  3001. #endif /* NOSPL */
  3002. #ifndef datageneral
  3003.     { "bye",        EN_BYE,  0 },
  3004. #endif /* datageneral */
  3005.     { "cd",         EN_CWD,  0 },
  3006. #ifdef ZCOPY
  3007.     { "copy",       EN_CPY,  0 },
  3008. #endif /* ZCOPY */
  3009.     { "cwd",        EN_CWD,  CM_INV },
  3010.     { "delete",     EN_DEL,  0 },
  3011.     { "directory",  EN_DIR,  0 },
  3012.     { "enable",     EN_ENA,  CM_INV },
  3013.     { "exit",       EN_XIT,  0 },
  3014.     { "finish",     EN_FIN,  0 },
  3015.     { "get",        EN_GET,  0 },
  3016.     { "host",       EN_HOS,  0 },
  3017.     { "mail",       EN_MAI,  0 },
  3018.     { "mkdir",      EN_MKD,  0 },
  3019.     { "print",      EN_PRI,  0 },
  3020. #ifndef NOSPL
  3021.     { "query",      EN_QUE,  0 },
  3022. #endif /* NOSPL */
  3023.     { "rename",     EN_REN,  0 },
  3024.     { "retrieve",   EN_RET,  CM_INV },
  3025.     { "rmdir",      EN_RMD,  0 },
  3026.     { "send",       EN_SEN,  0 },
  3027.     { "set",        EN_SET,  0 },
  3028.     { "space",      EN_SPA,  0 },
  3029.     { "type",       EN_TYP,  0 },
  3030.     { "who",        EN_WHO,  0 }
  3031. };
  3032. static int nena = (sizeof(enatab) / sizeof(struct keytab));
  3033. #endif /* NOSERVER */
  3034.  
  3035. struct keytab txtbin[] = {
  3036.     { "all",        2, 0 },
  3037.     { "binary",     1, 0 },
  3038.     { "text",       0, 0 }
  3039. };
  3040.  
  3041. #ifndef NOXFER
  3042. static struct keytab sndtab[] = {    /* SEND command options */
  3043.     { "/after",           SND_AFT, CM_ARG },
  3044. #ifndef NOSPL
  3045.     { "/array",           SND_ARR, CM_ARG },
  3046. #endif /* NOSPL */
  3047.     { "/as-name",         SND_ASN, CM_ARG },
  3048.     { "/b",               SND_BIN, CM_INV|CM_ABR },
  3049.     { "/before",          SND_BEF, CM_ARG },
  3050.     { "/binary",          SND_BIN, 0 },
  3051. #ifdef CALIBRATE
  3052.     { "/c",               SND_CMD, CM_INV|CM_ABR },
  3053.     { "/calibrate",       SND_CAL, CM_INV|CM_ARG },
  3054. #endif /* CALIBRATE */
  3055.     { "/command",         SND_CMD, CM_PSH },
  3056.     { "/delete",          SND_DEL, 0 },
  3057. #ifdef UNIXOROSK
  3058.     { "/dotfiles",        SND_DOT, 0 },
  3059. #endif /* UNIXOROSK */
  3060.     { "/except",          SND_EXC, CM_ARG },
  3061. #ifdef PIPESEND
  3062.     { "/filter",          SND_FLT, CM_ARG|CM_PSH },
  3063. #endif /* PIPESEND */
  3064.     { "/filenames",       SND_NAM, CM_ARG },
  3065. #ifdef CKSYMLINK
  3066.     { "/followlinks",      SND_LNK, 0 },
  3067. #endif /* CKSYMLINK */
  3068. #ifdef VMS
  3069.     { "/image",           SND_IMG, 0 },
  3070. #else
  3071.     { "/image",           SND_BIN, CM_INV },
  3072. #endif /* VMS */
  3073. #ifdef CK_LABELED
  3074.     { "/labeled",         SND_LBL, 0 },
  3075. #endif /* CK_LABELED */
  3076.     { "/larger-than",     SND_LAR, CM_ARG },
  3077.     { "/listfile",        SND_FIL, CM_ARG },
  3078. #ifndef NOFRILLS
  3079.     { "/mail",            SND_MAI, CM_ARG },
  3080. #endif /* NOFRILLS */
  3081. #ifdef CK_TMPDIR
  3082.     { "/move-to",         SND_MOV, CM_ARG },
  3083. #endif /* CK_TMPDIR */
  3084.     { "/nobackupfiles",   SND_NOB, 0 },
  3085. #ifdef UNIXOROSK
  3086.     { "/nodotfiles",      SND_NOD, 0 },
  3087. #endif /* UNIXOROSK */
  3088. #ifdef CKSYMLINK
  3089.     { "/nofollowlinks",      SND_NLK, 0 },
  3090. #endif /* CKSYMLINK */
  3091.     { "/not-after",       SND_NAF, CM_ARG },
  3092.     { "/not-before",      SND_NBE, CM_ARG },
  3093.     { "/pathnames",       SND_PTH, CM_ARG },
  3094.     { "/print",           SND_PRI, CM_ARG },
  3095. #ifdef CK_XYZ
  3096.     { "/protocol",        SND_PRO, CM_ARG },
  3097. #else
  3098.     { "/protocol",        SND_PRO, CM_ARG|CM_INV },
  3099. #endif /* CK_XYZ */
  3100.     { "/quiet",           SND_SHH, 0 },
  3101.     { "/recover",         SND_RES, 0 },
  3102. #ifdef RECURSIVE
  3103. /* Systems where we do recursion */
  3104.     { "/recursive",       SND_REC, 0 },
  3105. #else
  3106. #ifdef VMS
  3107. /* Systems that do recursion themselves without our assistance */
  3108. /* if we give them the right kind of wildcard */
  3109.     { "/recursive",       SND_REC, 0 },
  3110. #else
  3111. #ifdef datageneral
  3112.     { "/recursive",       SND_REC, 0 },
  3113. #else
  3114.     { "/recursive",       SND_REC, CM_INV },
  3115. #endif /* datageneral */
  3116. #endif /* VMS */
  3117. #endif /* RECURSIVE */
  3118.     { "/rename-to",       SND_REN, CM_ARG },
  3119.     { "/since",           SND_AFT, CM_INV|CM_ARG },
  3120.     { "/smaller-than",    SND_SMA, CM_ARG },
  3121.     { "/starting-at",     SND_STA, CM_ARG },
  3122. #ifndef NOFRILLS
  3123.     { "/su",              SND_ASN, CM_ARG|CM_INV|CM_ABR },
  3124.     { "/sub",             SND_ASN, CM_ARG|CM_INV|CM_ABR },
  3125.     { "/subject",         SND_ASN, CM_ARG },
  3126. #endif /* NOFRILLS */
  3127. #ifdef RECURSIVE
  3128.     { "/subdirectories",  SND_REC, CM_INV },
  3129. #endif /* RECURSIVE */
  3130.     { "/text",            SND_TXT, 0 },
  3131.     { "/transparent",     SND_XPA, 0 },
  3132.     { "/type",            SND_TYP, CM_ARG }
  3133. };
  3134. #define NSNDTAB sizeof(sndtab)/sizeof(struct keytab)
  3135. static int nsndtab = NSNDTAB;
  3136.  
  3137. #ifndef NOMSEND
  3138. static struct keytab msndtab[] = {    /* MSEND options */
  3139.     { "/after",           SND_AFT, CM_ARG },
  3140.     { "/before",          SND_BEF, CM_ARG },
  3141.     { "/binary",          SND_BIN, 0 },
  3142.     { "/delete",          SND_DEL, 0 },
  3143.     { "/except",          SND_EXC, CM_ARG },
  3144.     { "/filenames",       SND_NAM, CM_ARG },
  3145. #ifdef CKSYMLINK
  3146.     { "/followlinks",      SND_LNK, 0 },
  3147. #endif /* CKSYMLINK */
  3148. #ifdef VMS
  3149.     { "/image",           SND_IMG, 0 },
  3150. #else
  3151.     { "/image",           SND_BIN, CM_INV },
  3152. #endif /* VMS */
  3153. #ifdef CK_LABELED
  3154.     { "/labeled",         SND_LBL, 0 },
  3155. #endif /* CK_LABELED */
  3156.     { "/larger-than",     SND_LAR, CM_ARG },
  3157.     { "/list",            SND_FIL, CM_ARG },
  3158. #ifndef NOFRILLS
  3159.     { "/mail",            SND_MAI, CM_ARG },
  3160. #endif /* NOFRILLS */
  3161. #ifdef CK_TMPDIR
  3162.     { "/move-to",         SND_MOV, CM_ARG },
  3163. #endif /* CK_TMPDIR */
  3164. #ifdef CKSYMLINK
  3165.     { "/nofollowlinks",    SND_NLK, 0 },
  3166. #endif /* CKSYMLINK */
  3167.     { "/not-after",       SND_NAF, CM_ARG },
  3168.     { "/not-before",      SND_NBE, CM_ARG },
  3169.     { "/pathnames",       SND_PTH, CM_ARG },
  3170.     { "/print",           SND_PRI, CM_ARG },
  3171. #ifdef CK_XYZ
  3172.     { "/protocol",        SND_PRO, CM_ARG },
  3173. #endif /* CK_XYZ */
  3174.     { "/quiet",           SND_SHH, 0 },
  3175.     { "/recover",         SND_RES, 0 },
  3176.     { "/rename-to",       SND_REN, CM_ARG },
  3177.     { "/since",           SND_AFT, CM_INV|CM_ARG },
  3178.     { "/smaller-than",    SND_SMA, CM_ARG },
  3179.     { "/starting-at",     SND_STA, CM_ARG },
  3180. #ifndef NOFRILLS
  3181.     { "/subject",         SND_ASN, CM_ARG },
  3182. #endif /* NOFRILLS */
  3183.     { "/text",            SND_TXT, 0 },
  3184.     { "/transparent",     SND_XPA, 0 },
  3185.     { "/type",            SND_TYP, CM_ARG }
  3186. };
  3187. #define NMSNDTAB sizeof(msndtab)/sizeof(struct keytab)
  3188. static int nmsndtab = NMSNDTAB;
  3189. #endif /* NOMSEND */
  3190. #endif /* NOXFER */
  3191.  
  3192. /* CONNECT command switches */
  3193.  
  3194. #define CONN_II  0    /* Idle interval */
  3195. #define CONN_IS  1    /* Idle string */
  3196. #define CONN_IL  2    /* Idle limit */
  3197. #define CONN_NV  3    /* Non-Verbose */
  3198. #define CONN_TL  4    /* Time limit */
  3199. #define CONN_TS  5    /* Trigger string */
  3200. #define CONN_AS  6    /* Asynchronous */
  3201. #define CONN_SY  7    /* Synchronous */
  3202. #define CONN_MAX 7    /* Number of CONNECT switches */
  3203.  
  3204. #ifndef NOLOCAL
  3205. static struct keytab conntab[] = {
  3206. #ifdef OS2
  3207.     { "/asynchronous",    CONN_AS, CM_INV },
  3208. #endif /* OS2 */
  3209. #ifdef XLIMITS
  3210.     { "/idle-interval",   CONN_II, CM_ARG },
  3211.     { "/idle-limit",      CONN_IL, CM_ARG },
  3212.     { "/idle-string",     CONN_IS, CM_ARG },
  3213.     { "/quietly",         CONN_NV, CM_INV },
  3214. #else
  3215.     { "/quietly",         CONN_NV, 0 },
  3216. #endif /* XLIMITS */
  3217. #ifdef OS2
  3218.     { "/synchronous",     CONN_SY, CM_INV },
  3219. #endif /* OS2 */
  3220. #ifdef XLIMITS
  3221.     { "/time-limit",      CONN_TL, CM_ARG },
  3222. #endif /* XLIMITS */
  3223. #ifdef CK_TRIGGER
  3224.     { "/trigger",         CONN_TS, CM_ARG },
  3225. #endif /* CK_TRIGGER */
  3226.     { "",0,0 }
  3227. };
  3228. #define NCONNTAB sizeof(conntab)/sizeof(struct keytab)
  3229. static int nconntab = NCONNTAB;
  3230. #endif /* NOLOCAL */
  3231.  
  3232. #ifndef NOXFER
  3233. static struct keytab stattab[] = {    /* STATISTICS command switches */
  3234.     { "/brief",   1, 0 },
  3235.     { "/verbose", 0, 0 }
  3236. };
  3237. #endif /* NOXFER */
  3238.  
  3239. #ifndef NOSPL
  3240. #ifdef COMMENT
  3241. struct mtab mactab[MAC_MAX] = {        /* Preinitialized macro table */
  3242.     { NULL, NULL, 0 }
  3243. };
  3244. #else
  3245. struct mtab *mactab;            /* Dynamically allocated macro table */
  3246. #endif /* COMMENT */
  3247. int nmac = 0;
  3248.  
  3249. struct keytab mackey[MAC_MAX];        /* Macro names as command keywords */
  3250. #endif /* NOSPL */
  3251.  
  3252. #ifndef NOSPL
  3253. #ifdef  OS2
  3254. struct keytab beeptab[] = {        /* Beep options */
  3255.     { "error", BP_FAIL, 0 },
  3256.     { "information", BP_NOTE, 0 },
  3257.     { "warning", BP_WARN, 0 }
  3258. };
  3259. int nbeeptab = sizeof(beeptab)/sizeof(struct keytab);
  3260.  
  3261. /* CLEAR COMMMAND-SCREEN options */
  3262.  
  3263. #define CLR_C_ALL 0
  3264. #define CLR_C_BOL 1
  3265. #define CLR_C_BOS 2
  3266. #define CLR_C_EOL 3
  3267. #define CLR_C_EOS 4
  3268. #define CLR_C_LIN 5
  3269. #define CLR_C_SCR 6
  3270.  
  3271. struct keytab clrcmdtab[] = {
  3272.     { "all",        CLR_C_ALL, 0 },
  3273.     { "bol",        CLR_C_BOL, 0 },
  3274.     { "bos",        CLR_C_BOS, 0 },
  3275.     { "eol",        CLR_C_EOL, 0 },
  3276.     { "eos",        CLR_C_EOS, 0 },
  3277.     { "line",       CLR_C_LIN, 0 },
  3278.     { "scrollback", CLR_C_SCR, 0 }
  3279. };
  3280. int nclrcmd = sizeof(clrcmdtab)/sizeof(struct keytab);
  3281. #endif /* OS2 */
  3282. #endif /* NOSPL */
  3283.  
  3284. #ifdef COMMENT
  3285. /* Not used at present */
  3286. static struct keytab pagetab[] = {
  3287.     { "/more",   1, CM_INV },
  3288.     { "/nopage", 0, 0 },
  3289.     { "/page",   1, 0 }
  3290. };
  3291. int npagetab = sizeof(pagetab)/sizeof(struct keytab);
  3292. #endif /* COMMENT */
  3293.  
  3294. #define TYP_NOP  0            /* /NOPAGE */
  3295. #define TYP_PAG  1            /* /PAGE */
  3296. #define TYP_HEA  2            /* /HEAD:n */
  3297. #define TYP_TAI  3            /* /TAIL:n */
  3298. #define TYP_PAT  4            /* /MATCH:pattern */
  3299. #define TYP_WID  5            /* /WIDTH:cols */
  3300. #define TYP_COU  6            /* /COUNT */
  3301. #define TYP_OUT  7            /* /OUTPUT:file */
  3302. #define TYP_PFX  8            /* /PREFIX:string */
  3303. #ifdef UNICODE
  3304. #define TYP_XIN  9            /* /TRANSLATE-FROM:charset */
  3305. #define TYP_XUT 10            /* /TRANSLATE-TO:charset */
  3306. #define TYP_XPA 11            /* /TRANSPARENT */
  3307. #endif /* UNICODE */
  3308. #define TYP_NUM 12            /* /NUMBER */
  3309.  
  3310. static struct keytab typetab[] = {    /* TYPE command switches */
  3311.     { "/count",          TYP_COU, 0 },
  3312. #ifdef UNICODE
  3313.     { "/character-set",  TYP_XIN, CM_ARG },
  3314. #endif /* UNICODE */
  3315.     { "/head",           TYP_HEA, CM_ARG },
  3316.     { "/match",          TYP_PAT, CM_ARG },
  3317. #ifdef CK_TTGWSIZ
  3318.     { "/more",           TYP_PAG, CM_INV },
  3319.     { "/nopage",         TYP_NOP, 0 },
  3320.     { "/number",         TYP_NUM, 0 },
  3321.     { "/output",         TYP_OUT, CM_ARG },
  3322.     { "/page",           TYP_PAG, 0 },
  3323. #endif /* CK_TTGWSIZ */
  3324.     { "/prefix",         TYP_PFX, CM_ARG },
  3325.     { "/tail",           TYP_TAI, CM_ARG },
  3326. #ifdef UNICODE
  3327.     { "/translate-to",   TYP_XUT, CM_ARG },
  3328.     { "/transparent",    TYP_XPA, 0 },
  3329. #endif /* UNICODE */
  3330.     { "/width",          TYP_WID, CM_ARG },
  3331. #ifdef UNICODE
  3332.     { "/xlate-to",       TYP_XUT, CM_INV|CM_ARG },
  3333. #endif /* UNICODE */
  3334.     { "", 0, 0 }
  3335. };
  3336. int ntypetab = sizeof(typetab)/sizeof(struct keytab) - 1;
  3337.  
  3338. int typ_page = -1;            /* TYPE /[NO]PAGE default */
  3339. int typ_wid  = -1;
  3340.  
  3341. #ifndef NOSPL
  3342. #define TRA_ALL 999            /* TRACE command */
  3343. #define TRA_ASG 0
  3344. #define TRA_CMD 1
  3345.  
  3346. int tra_asg = 0;
  3347. int tra_cmd = 0;
  3348.  
  3349. static struct keytab tracetab[] = {    /* TRACE options */
  3350.     { "all",            TRA_ALL, 0 },
  3351.     { "assignments",    TRA_ASG, 0 },
  3352.     { "command-level",  TRA_CMD, 0 }
  3353. };
  3354. static int ntracetab = sizeof(tracetab)/sizeof(struct keytab);
  3355. #endif /* NOSPL */
  3356.  
  3357. #ifndef NOSHOW
  3358. VOID
  3359. showtypopts() {
  3360.     printf(" TYPE ");
  3361.     if (typ_page > -1) {
  3362.     prtopt(&optlines,typ_page ? "/PAGE" : "/NOPAGE");
  3363.     } else
  3364.       prtopt(&optlines,"(no options set)");
  3365.     if (typ_wid > -1) {
  3366.     ckmakmsg(tmpbuf,TMPBUFSIZ,"/WIDTH:",ckitoa(typ_wid),NULL,NULL);
  3367.     prtopt(&optlines,tmpbuf);
  3368.     }
  3369.     prtopt(&optlines,"");
  3370. }
  3371. #endif /* NOSHOW */
  3372.  
  3373. #ifdef LOCUS
  3374. /* isauto == 1 if locus is being switched automatically */
  3375.  
  3376. VOID
  3377. setlocus(x, isauto) int x, isauto; {
  3378.     extern int quitting;
  3379.     if (x) x = 1;
  3380.     if (x && locus) return;
  3381.     if (!x && !locus) return;
  3382.     /* Get here if it actually needs to be changed */
  3383. #ifdef OS2
  3384.     if (isauto &&            /* Automatically switching */
  3385.     !quitting &&            /* not exiting */
  3386.     autolocus == 2) {        /* and AUTOLOCUS is set to ASK */
  3387.     char locmsg[300];
  3388.     ckmakmsg(locmsg,300,
  3389.          "Switching Locus to ",
  3390.          x ? "LOCAL" : "REMOTE",
  3391.          " for file management commands\n"
  3392.                  "such as CD, DIRECTORY, DELETE, RENAME.  Type HELP SET\n"
  3393.                  "LOCUS at the K-95> prompt for further info.  Use the\n"
  3394. #ifdef KUI
  3395.                   "Actions menu or SET LOCUS command to disable automatic\n"
  3396.                   "Locus switching or to disable these queries.",
  3397. #else /* KUI */
  3398.                   "SET LOCUS command to disable automatic locus switching\n"
  3399.                   "or to disable these queries.",
  3400. #endif /* KUI */
  3401.                   NULL);
  3402.     if (uq_ok(locmsg,"OK to switch Locus?",3,NULL,1)) {
  3403.         locus = x;
  3404. #ifdef KUI
  3405.         KuiSetProperty(KUI_LOCUS,x,0);
  3406. #endif /* KUI */
  3407.         return;
  3408.     }
  3409.     } else {
  3410. #endif /* OS2 */
  3411.         if (isauto && msgflg && !quitting)
  3412.           printf("Switching LOCUS for file-management commands to %s.\n",
  3413.          x ? "LOCAL" : "REMOTE"
  3414.          );
  3415.     locus = x;
  3416. #ifdef OS2
  3417. #ifdef KUI
  3418.     KuiSetProperty(KUI_LOCUS,x,0);
  3419. #endif /* KUI */
  3420.     }
  3421. #endif /* OS2 */
  3422. }
  3423.  
  3424. VOID
  3425. setautolocus(x) int x; {
  3426.     autolocus = x;
  3427. #ifdef KUI
  3428.     KuiSetProperty(KUI_AUTO_LOCUS,x,0);
  3429. #endif /* KUI */
  3430. }
  3431. #endif /* LOCUS */
  3432.  
  3433. int
  3434. settypopts() {                /* Set TYPE option defaults */
  3435.     int xp = -1;
  3436.     int c, getval;
  3437.     while (1) {
  3438.     if ((y = cmswi(typetab,ntypetab,"Switch","",xxstring)) < 0) {
  3439.         if (y == -3)
  3440.           break;
  3441.         else
  3442.           return(y);
  3443.     }
  3444.     c = cmgbrk();
  3445.     if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  3446.         printf("?This switch does not take an argument\n");
  3447.         return(-9);
  3448.     }
  3449.     switch (y) {
  3450.       case TYP_NOP: xp = 0; break;
  3451.       case TYP_PAG: xp = 1; break;
  3452.       case TYP_WID:
  3453.         if (getval)
  3454.           if ((x = cmnum("Column at which to truncate",
  3455.                  ckitoa(cmd_cols),10,&y,xxstring)) < 0)
  3456.         return(x);
  3457.         typ_wid = y;
  3458.         break;
  3459.  
  3460.           default:
  3461.         printf("?Sorry, this option can not be set\n");
  3462.         return(-9);
  3463.     }
  3464.     }
  3465.     if ((x = cmcfm()) < 0)        /* Get confirmation */
  3466.       return(x);
  3467.     if (xp > -1) typ_page = xp;        /* Confirmed, save defaults */
  3468.     return(success = 1);
  3469. }
  3470.  
  3471. /* Forward declarations of functions local to this module */
  3472.  
  3473. #ifdef UNIX
  3474. _PROTOTYP (int douchmod, ( void ) );
  3475. #endif /* UNIX */
  3476. #ifdef CKPURGE
  3477. _PROTOTYP (int dopurge,  ( void ) );
  3478. #endif /* CKPURGE */
  3479. #ifndef NOSPL
  3480. _PROTOTYP (int doundef,  ( int  ) );
  3481. _PROTOTYP (int doask,    ( int  ) );
  3482. _PROTOTYP (int dodef,    ( int  ) );
  3483. _PROTOTYP (int doelse,   ( void ) );
  3484. _PROTOTYP (int dofor,    ( void ) );
  3485. _PROTOTYP (int doincr,   ( int  ) );
  3486. #endif /* NOSPL  */
  3487. #ifndef NODIAL
  3488. _PROTOTYP (int dodial,   ( int  ) );
  3489. #endif /* NODIAL */
  3490. _PROTOTYP (int dodel,    ( void ) );
  3491. _PROTOTYP (int dopaus,   ( int  ) );
  3492. #ifndef NOPUSH
  3493. #ifdef TCPSOCKET
  3494. _PROTOTYP (int doping,   ( void ) );
  3495. _PROTOTYP (int doftp,    ( void ) );
  3496. #endif /* TCPSOCKET */
  3497. #endif /* NOPUSH */
  3498. #ifndef NORENAME
  3499. #ifndef NOFRILLS
  3500. _PROTOTYP (int dorenam,  ( void ) );
  3501. #endif /* NOFRILLS */
  3502. #endif /* NORENAME */
  3503. #ifdef ZCOPY
  3504. _PROTOTYP (int docopy,   ( void ) );
  3505. #endif /* ZCOPY */
  3506. #ifdef NT
  3507. _PROTOTYP (int dolink,   ( void ));
  3508. #endif /* NT */
  3509. #ifdef CK_REXX
  3510. _PROTOTYP (int dorexx,   ( void ) );
  3511. #endif /* CK_REXX */
  3512.  
  3513. #ifdef TNCODE
  3514. static struct keytab telcmd[] = {
  3515.     { "abort", TN_ABORT, CM_INV },    /* Emotionally toned - don't show */
  3516.     { "ao",    TN_AO,    0 },
  3517.     { "ayt",   TN_AYT,   0 },
  3518.     { "break", BREAK,    0 },
  3519.     { "cancel",TN_ABORT, 0 },
  3520.     { "dmark", TN_DM,    0 },
  3521.     { "do",    DO,       0 },
  3522.     { "dont",  DONT,     0 },
  3523.     { "ec",    TN_EC,    0 },
  3524.     { "el",    TN_EL,    0 },
  3525.     { "eof",   TN_EOF,   0 },
  3526.     { "eor",   TN_EOR,   0 },
  3527. #ifdef CK_KERBEROS
  3528. #ifdef KRB5
  3529. #define TN_FWD 1
  3530.     { "forward", TN_FWD, CM_INV },
  3531. #endif /* KRB5 */
  3532. #endif /* CK_KERBEROS */
  3533.     { "ga",    TN_GA,    0 },
  3534.     { "ip",    TN_IP,    0 },
  3535.     { "nop",   TN_NOP,   0 },
  3536.     { "sak",   TN_SAK,   CM_INV },
  3537.     { "sb",    SB,       0 },
  3538.     { "se",    SE,       0 },
  3539.     { "susp",  TN_SUSP,  0 },
  3540.     { "will",  WILL,     0 },
  3541.     { "wont",  WONT,     0 }
  3542. };
  3543. static int ntelcmd = (sizeof(telcmd) / sizeof(struct keytab));
  3544.  
  3545. static struct keytab tnopts[] = {
  3546. #ifdef CK_AUTHENTICATION
  3547.     { "auth",   TELOPT_AUTHENTICATION,   0 },
  3548. #else
  3549.     { "auth",   TELOPT_AUTHENTICATION,   CM_INV },
  3550. #endif /* CK_AUTHENTICATION */
  3551.     { "binary", TELOPT_BINARY, 0 },
  3552. #ifdef TN_COMPORT
  3553.     { "c",      TELOPT_COMPORT, CM_INV|CM_ABR},
  3554.     { "co",     TELOPT_COMPORT, CM_INV|CM_ABR},
  3555.     { "com",    TELOPT_COMPORT, CM_INV|CM_ABR},
  3556.     { "com-port-control", TELOPT_COMPORT, 0 },
  3557.     { "comport-control", TELOPT_COMPORT, CM_INV},
  3558. #else  /* TN_COMPORT */
  3559.     { "com-port-control", TELOPT_COMPORT, CM_INV },
  3560.     { "comport-control", TELOPT_COMPORT, CM_INV},
  3561. #endif /* TN_COMPORT */
  3562.     { "echo", TELOPT_ECHO, 0 },
  3563. #ifdef CK_ENCRYPTION
  3564.     { "encrypt", TELOPT_ENCRYPTION, 0 },
  3565. #else
  3566.     { "encrypt", TELOPT_ENCRYPTION, CM_INV },
  3567. #endif /* CK_ENCRYPTION */
  3568. #ifdef CK_FORWARD_X
  3569.     { "forward-x", TELOPT_FORWARD_X, 0 },
  3570. #else
  3571.     { "forward-x", TELOPT_FORWARD_X, CM_INV },
  3572. #endif /* CK_FORWARD_X */
  3573. #ifdef IKS_OPTION
  3574.     { "kermit", TELOPT_KERMIT, 0 },
  3575. #else
  3576.     { "kermit", TELOPT_KERMIT, CM_INV },
  3577. #endif /* IKS_OPTION */
  3578.     { "lflow",  TELOPT_LFLOW, CM_INV },
  3579.     { "logout", TELOPT_LOGOUT, CM_INV },
  3580. #ifdef CK_NAWS
  3581.     { "naws", TELOPT_NAWS, 0 },
  3582. #else
  3583.     { "naws", TELOPT_NAWS, CM_INV },
  3584. #endif /* CK_NAWS */
  3585. #ifdef CK_ENVIRONMENT
  3586.     { "new-environment", TELOPT_NEWENVIRON,  0 },
  3587. #else
  3588.     { "new-environment", TELOPT_NEWENVIRON,  CM_INV },
  3589. #endif /* CK_ENVIRONMENT */
  3590.     { "pragma-heartbeat",TELOPT_PRAGMA_HEARTBEAT,  CM_INV },
  3591.     { "pragma-logon",    TELOPT_PRAGMA_LOGON,  CM_INV },
  3592.     { "pragma-sspi",     TELOPT_SSPI_LOGON,  CM_INV },
  3593.     { "sak",   TELOPT_IBM_SAK, CM_INV },
  3594. #ifdef CK_SNDLOC
  3595.     { "send-location",   TELOPT_SNDLOC,  0 },
  3596. #else
  3597.     { "send-location",   TELOPT_SNDLOC,  CM_INV },
  3598. #endif /* CK_SNDLOC */
  3599.     { "sga", TELOPT_SGA, 0 },
  3600. #ifdef CK_SSL
  3601.     { "start-tls",       TELOPT_START_TLS,  0 },
  3602. #else
  3603.     { "start-tls",       TELOPT_START_TLS,  CM_INV },
  3604. #endif /* CK_SSL */
  3605.     { "ttype", TELOPT_TTYPE, 0 },
  3606. #ifdef CK_ENVIRONMENT
  3607.     { "xdisplay-location", TELOPT_XDISPLOC, 0 },
  3608. #else
  3609.     { "xdisplay-location", TELOPT_XDISPLOC, CM_INV },
  3610. #endif /* CK_ENVIRONMENT */
  3611.     { "", 0, 0 }
  3612. };
  3613. static int ntnopts = (sizeof(tnopts) / sizeof(struct keytab)) - 1;
  3614.  
  3615. static struct keytab tnsbopts[] = {
  3616. #ifdef CK_NAWS
  3617.     { "naws", TELOPT_NAWS, 0 },
  3618. #endif /* CK_NAWS */
  3619.     { "", 0, 0 }
  3620. };
  3621. static int ntnsbopts = (sizeof(tnsbopts) / sizeof(struct keytab)) - 1;
  3622. #endif /* TNCODE */
  3623.  
  3624. #ifdef TCPSOCKET
  3625. #ifndef NOPUSH
  3626. #ifdef SYSFTP
  3627. int
  3628. doftp() {                /* (External) FTP command */
  3629.     char *p, *f;            /* (See doxftp() for internal one) */
  3630.     int x;
  3631.  
  3632.     if (network)            /* If we have a current connection */
  3633.       ckstrncpy(line,ttname,LINBUFSIZ);    /* get the host name */
  3634.     else *line = '\0';            /* as default host */
  3635.     for (p = line; *p; p++)        /* Remove ":service" from end. */
  3636.       if (*p == ':') { *p = '\0'; break; }
  3637.     if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
  3638.       return(x);
  3639.     if (nopush) {
  3640.         printf("?Sorry, FTP command disabled\n");
  3641.         return(success = 0);
  3642.     }
  3643. /* Construct FTP command */
  3644. #ifdef VMS
  3645. #ifdef MULTINET                /* TGV MultiNet */
  3646.     ckmakmsg(line,LINBUFSIZ,"multinet ftp ",s,NULL,NULL);
  3647. #else
  3648.     ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
  3649. #endif /* MULTINET */
  3650. #else                    /* Not VMS */
  3651. #ifdef OS2ORUNIX
  3652. #ifndef NOFTP
  3653.     f = ftpapp;
  3654.     if (!f) f = "";
  3655.     if (!f[0]) f = "ftp";
  3656.     ckmakmsg(line,LINBUFSIZ,f," ",s,NULL);
  3657. #ifdef OS2
  3658.     p = line + strlen(ftpapp);
  3659.     while (p != line) {
  3660.         if (*p == '/') *p = '\\';
  3661.         p--;
  3662.     }
  3663. #endif /* OS2 */
  3664. #else /* NOFTP */
  3665.     ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
  3666. #endif /* NOFTP */
  3667. #else /* OS2ORUNIX */
  3668.     ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
  3669. #endif /* OS2ORUNIX */
  3670. #endif /* VMS */
  3671.     conres();                /* Make console normal  */
  3672. #ifdef DEC_TCPIP
  3673.     printf("\n");            /* Prevent prompt-stomping */
  3674. #endif /* DEC_TCPIP */
  3675.     x = zshcmd(line);
  3676.     concb((char)escape);
  3677.     return(success = x);
  3678. }
  3679. #endif /* SYSFTP */
  3680.  
  3681. int
  3682. doping() {                /* PING command */
  3683.     char *p;                /* just runs ping program */
  3684.     int x;
  3685.  
  3686.     if (network)            /* If we have a current connection */
  3687.       ckstrncpy(line,ttname,LINBUFSIZ);    /* get the host name */
  3688.     else *line = '\0';            /* as default host to be pinged. */
  3689.     for (p = line; *p; p++)        /* Remove ":service" from end. */
  3690.       if (*p == ':') { *p = '\0'; break; }
  3691.     if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
  3692.       return(x);
  3693.     if (nopush) {
  3694.         printf("?Sorry, PING command disabled\n");
  3695.         return(success = 0);
  3696.     }
  3697.  
  3698.     /* Construct PING command */
  3699. #ifdef VMS
  3700. #ifdef MULTINET                /* TGV MultiNet */
  3701.     ckmakmsg(line,LINBUFSIZ,"multinet ping ",s," /num=1",NULL);
  3702. #else
  3703.     ckmakmsg(line,LINBUFSIZ,"ping ",s," 56 1",NULL); /* Other VMS TCP/IP's */
  3704. #endif /* MULTINET */
  3705. #else                    /* Not VMS */
  3706.     ckmakmsg(line,LINBUFSIZ,"ping ",s,NULL,NULL);
  3707. #endif /* VMS */
  3708.     conres();                /* Make console normal  */
  3709. #ifdef DEC_TCPIP
  3710.     printf("\n");            /* Prevent prompt-stomping */
  3711. #endif /* DEC_TCPIP */
  3712.     x = zshcmd(line);
  3713.     concb((char)escape);
  3714.     return(success = x);
  3715. }
  3716. #endif /* NOPUSH */
  3717. #endif /* TCPSOCKET */
  3718.  
  3719. static VOID
  3720. doend(x) int x; {
  3721. #ifndef NOSPL
  3722.     /* Pop from all FOR/WHILE/XIF/SWITCH's */
  3723.     debug(F101,"doend maclvl 1","",maclvl);
  3724.     while ((maclvl > 0) &&
  3725.        (m_arg[maclvl-1][0]) &&
  3726.        (cmdstk[cmdlvl].src == CMD_MD) &&
  3727.        (!strncmp(m_arg[maclvl-1][0],"_xif",4) ||
  3728.         !strncmp(m_arg[maclvl-1][0],"_for",4) ||
  3729.         !strncmp(m_arg[maclvl-1][0],"_whi",4) ||
  3730.         !strncmp(m_arg[maclvl-1][0],"_swi",4))) {
  3731.     debug(F110,"END popping",m_arg[maclvl-1][0],0);
  3732.     dogta(XXPTA);            /* Put args back */
  3733.     popclvl();            /* Pop up two levels */
  3734.     popclvl();
  3735.     debug(F101,"doend maclvl 2","",maclvl);
  3736.     }
  3737.     if (maclvl > -1) {
  3738.     if (mrval[maclvl])        /* Free previous retval if any */
  3739.       free(mrval[maclvl]);
  3740.     mrval[maclvl] = malloc(16);    /* Room for up to 15 digits */
  3741.     if (mrval[maclvl])        /* Record current retval */
  3742.       ckmakmsg(mrval[maclvl],16,ckitoa(x),NULL,NULL,NULL);
  3743.     }
  3744. #endif /* NOSPL */
  3745.     popclvl();                /* Now pop out of macro or TAKE file */
  3746. #ifndef NOSPL
  3747. #ifdef DEBUG
  3748.     if (deblog) {
  3749.     debug(F101,"END maclvl 3","",maclvl);
  3750.     debug(F111,"END mrval[maclvl]",mrval[maclvl],maclvl);
  3751.     debug(F111,"END mrval[maclvl+1]",mrval[maclvl+1],maclvl+1);
  3752.     }
  3753. #endif /* DEBUG */
  3754. #endif /* NOSPL */
  3755. }
  3756.  
  3757. #ifdef CKROOT
  3758. int
  3759. dochroot() {
  3760.     if ((x = cmdir("Name of new root directory","",&s,xxstring)) < 0) {
  3761.     if (x == -3) {
  3762.         printf("?Directory name required\n");
  3763.         return(-9);
  3764.     }
  3765.     return(x);
  3766.     }
  3767.     ckstrncpy(line,s,LINBUFSIZ);
  3768.     s = line;
  3769.     if ((x = cmcfm()) < 0) return(x);
  3770.     s = brstrip(s);
  3771.     x = zsetroot(s);
  3772.     if (x < 0) {
  3773.     char * m = NULL;
  3774.     switch (x) {
  3775.       case -1:
  3776.       case -2: m = "Not a directory"; break;
  3777.       case -3: m = "Internal error"; break;
  3778.       case -4: m = "Access denied"; break;
  3779.       case -5: m = "Off limits"; break;
  3780.     }
  3781.     if (m) printf("%s: \"%s\"\n", m, s);
  3782.     return(m ? -9 : -2);
  3783.     } else {
  3784.     nopush = 1;
  3785.     return(success = 1);
  3786.     }
  3787. }
  3788. #endif /* CKROOT */
  3789.  
  3790. #ifndef NOXFER
  3791. static char * asnbuf = NULL;        /* As-name buffer pointer */
  3792.  
  3793. char sndxnam[] = { "_array_x_" };    /* (with replaceable x!) */
  3794.  
  3795. /*
  3796.   The new SEND command, replacing BSEND, CSEND, PSEND, etc etc.
  3797.   Call with cx = top-level keyword value.  Returns:
  3798.     < 0  On parse error.
  3799.     0    On other type of failure (e.g. requested operation not allowed).
  3800.     1    On success with sstate set to 's' so protocol will begin.
  3801. */
  3802.  
  3803. /*  D O X S E N D  --  Parse SEND and related commands with switches  */
  3804.  
  3805. int
  3806. doxsend(cx) int cx; {
  3807.     int c, i, n, wild, confirmed = 0;    /* Workers */
  3808.     int x, y;                /* of the world... */
  3809.     int getval = 0;            /* Whether to get switch value */
  3810.     extern char * snd_move;        /* Directory to move sent files to */
  3811.     extern char * snd_rename;        /* What to rename sent files to */
  3812.     extern char * filefile;        /* File containing filenames to send */
  3813.     extern int xfiletype;        /* Send only text (or binary) files */
  3814.     extern struct keytab pathtab[];    /* PATHNAMES option keywords */
  3815.     extern int npathtab;        /* How many of them */
  3816.     extern int recursive;        /* Recursive directory traversal */
  3817.     extern int rprintf;            /* REMOTE PRINT flag */
  3818.     extern int fdispla;            /* TRANSFER DISPLAY setting */
  3819.     extern int skipbup;            /* Skip backup files when sending */
  3820.     struct stringint {            /* Temporary array for switch values */
  3821.     char * sval;
  3822.     int ival;
  3823.     } pv[SND_MAX+1];
  3824.     struct FDB sf, sw, fl, cm;        /* FDBs for each parse function */
  3825.     int mlist = 0;            /* Flag for MSEND or MMOVE */
  3826.     char * m;                /* For making help messages */
  3827.     extern struct keytab protos[];    /* File transfer protocols */
  3828.     extern int xfrxla, g_xfrxla, nprotos;
  3829.     extern char sndbefore[], sndafter[], *sndexcept[]; /* Selection criteria */
  3830.     extern char sndnbefore[], sndnafter[];
  3831.     extern long sndsmaller, sndlarger, calibrate;
  3832. #ifndef NOSPL
  3833.     int range[2];            /* Array range */
  3834.     char ** ap = NULL;            /* Array pointer */
  3835.     int arrayx = -1;            /* Array index */
  3836. #endif /* NOSPL */
  3837.  
  3838. #ifdef NEWFTP
  3839.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) {
  3840.     if (cx == XXMAI) {
  3841.         printf("?Sorry, No MAIL with FTP\n");
  3842.         return(-9);
  3843.     }
  3844.     return(doftpput(cx,0));
  3845.     }
  3846. #endif /* NEWFTP */
  3847.  
  3848.     for (i = 0; i <= SND_MAX; i++) {    /* Initialize switch values */
  3849.     pv[i].sval = NULL;        /* to null pointers */
  3850.     pv[i].ival = -1;        /* and -1 int values */
  3851.     }
  3852. #ifndef NOSPL
  3853.     range[0] = -1;
  3854.     range[1] = -1;
  3855.     sndxin = -1;            /* Array index */
  3856. #endif /* NOSPL */
  3857.     sndarray = NULL;            /* Array pointer */
  3858.  
  3859. #ifdef UNIXOROSK
  3860.     g_matchdot = matchdot;        /* Match dot files */
  3861. #endif /* UNIXOROSK */
  3862.     g_recursive = recursive;        /* Recursive sending */
  3863.     recursive = 0;            /* Save global value, set local */
  3864.     debug(F101,"xsend entry fncnv","",fncnv);
  3865.  
  3866.     /* Preset switch values based on top-level command that called us */
  3867.  
  3868.     switch (cx) {
  3869.       case XXMSE:            /* MSEND */
  3870.     mlist = 1; break;
  3871.       case XXCSEN:            /* CSEND */
  3872.     pv[SND_CMD].ival = 1; break;
  3873.       case XXMMOVE:            /* MMOVE */
  3874.     mlist = 1;
  3875.       case XXMOVE:            /* MOVE */
  3876.     pv[SND_DEL].ival = 1; break;
  3877.       case XXRSEN:            /* RESEND */
  3878.     pv[SND_BIN].ival = 1;        /* Implies /BINARY */
  3879.     pv[SND_RES].ival = 1; break;
  3880.       case XXMAI:            /* MAIL */
  3881.     pv[SND_MAI].ival = 1; break;
  3882.     }
  3883.  
  3884.     /* Set up chained parse functions... */
  3885.  
  3886.     cmfdbi(&sw,                /* First FDB - command switches */
  3887.        _CMKEY,            /* fcode */
  3888.        "Filename, or switch",    /* hlpmsg */
  3889.        "",                /* default */
  3890.        "",                /* addtl string data */
  3891. #ifdef NOMSEND
  3892.        nsndtab,            /* addtl numeric data 1: tbl size */
  3893. #else
  3894.        mlist ? nmsndtab : nsndtab,    /* addtl numeric data 1: tbl size */
  3895. #endif /* NOMSEND */
  3896.        4,                /* addtl numeric data 2: 4 = cmswi */
  3897.        xxstring,            /* Processing function */
  3898. #ifdef NOMSEND
  3899.        sndtab,            /* Keyword table */
  3900. #else
  3901.        mlist ? msndtab : sndtab,
  3902. #endif /* NOMSEND */
  3903.        &sf                /* Pointer to next FDB */
  3904.        );
  3905.     cmfdbi(&sf,                /* 2nd FDB - file to send */
  3906.        _CMIFI,            /* fcode */
  3907.        "File(s) to send",        /* hlpmsg */
  3908.        "",                /* default */
  3909.        "",                /* addtl string data */
  3910.        nolinks,            /* addtl numeric data 1 */
  3911.        0,                /* addtl numeric data 2 */
  3912.        xxstring,
  3913.        NULL,
  3914.        mlist ? &cm : &fl
  3915.        );
  3916.     cmfdbi(&fl,                /* 3rd FDB - command to send from */
  3917.        _CMFLD,            /* fcode */
  3918.        "Command",            /* hlpmsg */
  3919.        "",                /* default */
  3920.        "",                /* addtl string data */
  3921.        0,                /* addtl numeric data 1 */
  3922.        0,                /* addtl numeric data 2 */
  3923.        xxstring,
  3924.        NULL,
  3925.        &cm
  3926.        );
  3927.     cmfdbi(&cm,                /* 4th FDB - Confirmation */
  3928.        _CMCFM,            /* fcode */
  3929.        "",                /* hlpmsg */
  3930.        "",                /* default */
  3931.        "",                /* addtl string data */
  3932.        0,                /* addtl numeric data 1 */
  3933.        0,                /* addtl numeric data 2 */
  3934.        NULL,
  3935.        NULL,
  3936.        NULL
  3937.        );
  3938.  
  3939.     while (1) {                /* Parse 0 or more switches */
  3940.     x = cmfdb(&sw);            /* Parse something */
  3941.     debug(F101,"xsend cmfdb","",x);
  3942.     if (x < 0)            /* Error */
  3943.       goto xsendx;            /* or reparse needed */
  3944.     if (cmresult.fcode != _CMKEY)    /* Break out if not a switch */
  3945.       break;
  3946. /*
  3947.   They gave a switch, but let's see how they terminated it.
  3948.   If they ended it with : or =, then we must parse a value.
  3949.   If they ended it with anything else, then we must NOT parse a value.
  3950. */
  3951.     c = cmgbrk();            /* Get break character */
  3952.     getval = (c == ':' || c == '='); /* to see how they ended the switch */
  3953.     if (getval && !(cmresult.kflags & CM_ARG)) {
  3954.         printf("?This switch does not take arguments\n");
  3955.         x = -9;
  3956.         goto xsendx;
  3957.     }
  3958.     if (!getval && (cmgkwflgs() & CM_ARG)) {
  3959.         printf("?This switch requires an argument\n");
  3960.         x = -9;
  3961.         goto xsendx;
  3962.     }
  3963.     n = cmresult.nresult;        /* Numeric result = switch value */
  3964.     debug(F101,"xsend switch","",n);
  3965.  
  3966.     switch (n) {            /* Process the switch */
  3967.       case SND_CMD:            /* These take no args */
  3968.         if (nopush) {
  3969.         printf("?Sorry, system command access is disabled\n");
  3970.         x = -9;
  3971.         goto xsendx;
  3972.         }
  3973. #ifdef PIPESEND
  3974.         else if (sndfilter) {
  3975.         printf(
  3976. "?Sorry, no SEND /COMMAND or CSEND when SEND FILTER selected\n");
  3977.         x = -9;
  3978.         goto xsendx;
  3979.         }
  3980. #endif /* PIPESEND */
  3981.         sw.hlpmsg = "Command, or switch"; /* Change help message */
  3982.         pv[n].ival = 1;        /* Just set the flag */
  3983.         pv[SND_ARR].ival = 0;
  3984.         break;
  3985.  
  3986.       case SND_REC:            /* /RECURSIVE */
  3987.         recursive = 2;        /* Set the real variable */
  3988.         pv[SND_PTH].ival = PATH_REL; /* Give them relative pathnames */
  3989.         pv[n].ival = 1;        /* Just set the flag */
  3990.         break;
  3991.  
  3992.       case SND_RES:            /* /RECOVER (resend) */
  3993.         pv[SND_ARR].ival = 0;
  3994.         pv[SND_BIN].ival = 1;    /* Implies /BINARY */
  3995.       case SND_NOB:            /* /NOBACKUP */
  3996.       case SND_DEL:            /* /DELETE */
  3997.       case SND_SHH:            /* /QUIET */
  3998.         pv[n].ival = 1;        /* Just set the flag */
  3999.         break;
  4000.  
  4001. #ifdef UNIXOROSK
  4002. /* Like recursive, these are set immediately because they affect cmifi() */
  4003.       case SND_DOT:            /* /DOTFILES */
  4004.         matchdot = 1;
  4005.         break;
  4006.       case SND_NOD:            /* /NODOTFILES */
  4007.         matchdot = 0;
  4008.         break;
  4009. #endif /* UNIXOROSK */
  4010.  
  4011.       /* File transfer modes - each undoes the others */
  4012.  
  4013.       case SND_BIN:            /* Binary */
  4014.       case SND_TXT:            /* Text */
  4015.       case SND_IMG:            /* Image */
  4016.       case SND_LBL:            /* Labeled */
  4017.         pv[SND_BIN].ival = 0;
  4018.         pv[SND_TXT].ival = 0;
  4019.         pv[SND_IMG].ival = 0;
  4020.         pv[SND_LBL].ival = 0;
  4021.         pv[n].ival = 1;
  4022.         break;
  4023.  
  4024. #ifdef CKSYMLINK
  4025.       case SND_LNK:
  4026.       case SND_NLK:
  4027.         nolinks = (n == SND_NLK) ? 2 : 0;
  4028.         cmfdbi(&sf,            /* Redo cmifi() */
  4029.            _CMIFI,        /* fcode */
  4030.            "File(s) to send",    /* hlpmsg */
  4031.            "",            /* default */
  4032.            "",            /* addtl string data */
  4033.            nolinks,        /* addtl numeric data 1 */
  4034.            0,            /* addtl numeric data 2 */
  4035.            xxstring,
  4036.            NULL,
  4037.            mlist ? &cm : &fl
  4038.            );
  4039.         break;
  4040. #endif /* CKSYMLINK */
  4041.  
  4042.       case SND_EXC:            /* Excludes */
  4043.         if (!getval) break;
  4044.         if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
  4045.         if (x == -3) {
  4046.             printf("?Pattern required\n");
  4047.             x = -9;
  4048.         }
  4049.         goto xsendx;
  4050.         }
  4051.         if (pv[n].sval) free(pv[n].sval);
  4052.         y = strlen(s);
  4053.         if (y > 256) {
  4054.         printf("?Pattern too long - 256 max\n");
  4055.         x = -9;
  4056.         goto xsendx;
  4057.         }
  4058.         pv[n].sval = malloc(y+1);
  4059.         if (pv[n].sval) {
  4060.         strcpy(pv[n].sval,s);    /* safe */
  4061.         pv[n].ival = 1;
  4062.         }
  4063.         break;
  4064.  
  4065.       case SND_MOV:            /* MOVE after */
  4066.       case SND_REN:            /* RENAME after */
  4067.         if (!getval) break;
  4068.         if ((x = cmfld(n == SND_MOV ?
  4069.        "device and/or directory for source file after sending" :
  4070.        "new name for source file after sending",
  4071.                "",
  4072.                &s,
  4073.                n == SND_MOV ? xxstring : NULL
  4074.                )) < 0) {
  4075.         if (x == -3) {
  4076.             printf("%s\n", n == SND_MOV ?
  4077.                "?Destination required" :
  4078.                "?New name required"
  4079.                );
  4080.             x = -9;
  4081.         }
  4082.         goto xsendx;
  4083.         }
  4084.         if (pv[n].sval) free(pv[n].sval);
  4085.         s = brstrip(s);
  4086.         y = strlen(s);
  4087.         if (y > 0) {
  4088.         pv[n].sval = malloc(y+1);
  4089.         if (pv[n].sval) {
  4090.             strcpy(pv[n].sval,s); /* safe */
  4091.             pv[n].ival = 1;
  4092.         }
  4093.         }
  4094.         break;
  4095.  
  4096.       case SND_SMA:            /* Smaller / larger than */
  4097.       case SND_LAR:
  4098.         if (!getval) break;
  4099.         if ((x = cmnum("Size in bytes","0",10,&y,xxstring)) < 0)
  4100.           goto xsendx;
  4101.         pv[n].ival = y;
  4102.         break;
  4103.  
  4104.       case SND_AFT:            /* Send /AFTER:date-time */
  4105.       case SND_BEF:            /* Send /BEFORE:date-time */
  4106.       case SND_NAF:            /* Send /NOT-AFTER:date-time */
  4107.       case SND_NBE:            /* Send /NOT-BEFORE:date-time */
  4108.         if (!getval) break;
  4109.         if ((x = cmdate("File date-time","",&s,0,xxstring)) < 0) {
  4110.         if (x == -3) {
  4111.             printf("?Date-time required\n");
  4112.             x = -9;
  4113.         }
  4114.         goto xsendx;
  4115.         }
  4116.         if (pv[n].sval) free(pv[n].sval);
  4117.         pv[n].sval = malloc((int)strlen(s)+1);
  4118.         if (pv[n].sval) {
  4119.         strcpy(pv[n].sval,s);    /* safe */
  4120.         pv[n].ival = 1;
  4121.         }
  4122.         break;
  4123.  
  4124.       case SND_MAI:            /* Send as mail (= MAIL) */
  4125. #ifdef IKSD
  4126.         if (inserver && !ENABLED(en_mai)) {
  4127.         printf("?Sorry, sending files as mail is disabled\n");
  4128.         return(-9);
  4129.         }
  4130. #endif /* IKSD */
  4131.         pv[n].ival = 1;
  4132.         if (!getval) break;
  4133.         if ((x = cmfld("e-mail address","",&s,xxstring)) < 0) {
  4134.         if (x == -3) {
  4135.             printf("?address required\n");
  4136.             x = -9;
  4137.         }
  4138.         goto xsendx;
  4139.         }
  4140.         s = brstrip(s);
  4141.         if (pv[n].sval) free(pv[n].sval);
  4142.         pv[n].sval = malloc((int)strlen(s)+1);
  4143.         if (pv[n].sval)
  4144.           strcpy(pv[n].sval,s);    /* safe */
  4145.         break;
  4146.  
  4147.       case SND_PRI:            /* Send to be printed (REMOTE PRINT) */
  4148. #ifdef IKSD
  4149.         if (inserver && !ENABLED(en_mai)) {
  4150.         printf("?Sorry, sending files for printing is disabled\n");
  4151.         return(-9);
  4152.         }
  4153. #endif /* IKSD */
  4154.         pv[n].ival = 1;
  4155.         if (!getval) break;
  4156.         if ((x = cmfld("Print options","",&s,xxstring)) < 0)
  4157.           if (x != -3) goto xsendx;
  4158.         s = brstrip(s);
  4159.         if (pv[n].sval) free(pv[n].sval);
  4160.         pv[n].sval = malloc((int)strlen(s)+1);
  4161.         if (pv[n].sval)
  4162.           strcpy(pv[n].sval,s);    /* safe */
  4163.         break;
  4164.  
  4165.       case SND_ASN:            /* As-name */
  4166.         debug(F101,"xsend /as-name getval","",getval);
  4167.         if (!getval) break;
  4168.         if ((x = cmfld("Name to send under","",&s,NULL)) < 0) {
  4169.         if (x == -3) {
  4170.             printf("?name required\n");
  4171.             x = -9;
  4172.         }
  4173.         goto xsendx;
  4174.         }
  4175.         s = brstrip(s);
  4176.         if ((y = strlen(s)) > 0) {
  4177.         if (pv[n].sval) free(pv[n].sval);
  4178.         pv[n].sval = malloc(y+1);
  4179.         if (pv[n].sval) {
  4180.             strcpy(pv[n].sval,s); /* safe */
  4181.             pv[n].ival = 1;
  4182.         }
  4183.         }
  4184.         break;
  4185.  
  4186.       case SND_STA:            /* Starting position (= PSEND) */
  4187.         if (!getval) break;
  4188.         if ((x = cmnum("0-based position","0",10,&y,xxstring)) < 0)
  4189.           goto xsendx;
  4190.         pv[n].ival = y;
  4191.         break;
  4192.  
  4193.       case SND_PRO:            /* Protocol to use */
  4194.         if (!getval) break;
  4195.         if ((x = cmkey(protos,nprotos,"File-transfer protocol","",
  4196.                xxstring)) < 0) {
  4197.         if (x == -3) {
  4198.             printf("?name of protocol required\n");
  4199.             x = -9;
  4200.         }
  4201.         goto xsendx;
  4202.         }
  4203.         pv[n].ival = x;
  4204.         break;
  4205.  
  4206. #ifdef PIPESEND
  4207.       case SND_FLT:            /* Filter */
  4208.         debug(F101,"xsend /filter getval","",getval);
  4209.         if (!getval) break;
  4210.         if ((x = cmfld("Filter program to send through","",&s,NULL)) < 0) {
  4211.         if (x == -3)
  4212.           s = "";
  4213.         else
  4214.           goto xsendx;
  4215.         }
  4216.         if (*s) s = brstrip(s);
  4217.         y = strlen(s);
  4218.         for (x = 0; x < y; x++) {    /* Make sure they included "\v(...)" */
  4219.         if (s[x] != '\\') continue;
  4220.         if (s[x+1] == 'v') break;
  4221.         }
  4222.         if (x == y) {
  4223.         printf(
  4224.         "?Filter must contain a replacement variable for filename.\n"
  4225.                );
  4226.         x = -9;
  4227.         goto xsendx;
  4228.         }
  4229.         pv[n].ival = 1;
  4230.         if (pv[n].sval) {
  4231.         free(pv[n].sval);
  4232.         pv[n].sval = NULL;
  4233.         }
  4234.         if ((y = strlen(s)) > 0) {
  4235.         if ((pv[n].sval = malloc(y+1)))
  4236.           strcpy(pv[n].sval,s);    /* safe */
  4237.         }
  4238.         break;
  4239. #endif /* PIPESEND */
  4240.  
  4241.       case SND_PTH:            /* Pathnames */
  4242.         if (!getval) {
  4243.         pv[n].ival = PATH_REL;
  4244.         break;
  4245.         }
  4246.         if ((x = cmkey(pathtab,npathtab,"","absolute",xxstring)) < 0)
  4247.           goto xsendx;
  4248.         pv[n].ival = x;
  4249.         break;
  4250.  
  4251.       case SND_NAM:            /* Filenames */
  4252.         if (!getval) break;
  4253.         if ((x = cmkey(fntab,nfntab,"","converted",xxstring)) < 0)
  4254.           goto xsendx;
  4255.         debug(F101,"xsend /filenames","",x);
  4256.         pv[n].ival = x;
  4257.         break;
  4258.  
  4259. #ifdef CALIBRATE
  4260.           case SND_CAL:            /* /CALIBRATE */
  4261.         if (getval) {
  4262.         if ((x = cmnum("number of Kbytes to send",
  4263.                "1024",10,&y,xxstring)) < 0)
  4264.           goto xsendx;
  4265.         } else
  4266.           y = 1024;
  4267.         pv[n].ival = y;
  4268.         pv[SND_ARR].ival = 0;
  4269.         break;
  4270. #endif /* CALIBRATE */
  4271.  
  4272.       case SND_FIL:            /* Name of file containing filnames */
  4273.         if (!getval) break;
  4274.         if ((x = cmifi("Name of file containing list of filenames",
  4275.                    "",&s,&y,xxstring)) < 0) {
  4276.         if (x == -3) {
  4277.             printf("?Filename required\n");
  4278.             x = -9;
  4279.         }
  4280.         goto xsendx;
  4281.         } else if (y) {
  4282.         printf("?Wildcards not allowed\n");
  4283.         x = -9;
  4284.         goto xsendx;
  4285.         }
  4286.         if (pv[n].sval)
  4287.           free(pv[n].sval);
  4288.         if (s) if (*s) {
  4289.         if ((pv[n].sval = malloc((int)strlen(s)+1))) {
  4290.             strcpy(pv[n].sval,s);
  4291.             pv[n].ival = 1;
  4292.             pv[SND_ARR].ival = 0;
  4293.         }
  4294.         }
  4295.         break;
  4296.  
  4297. #ifndef NOSPL
  4298.       case SND_ARR:            /* SEND /ARRAY: */
  4299.         if (!getval) break;
  4300.         ap = NULL;
  4301.         if ((x = cmfld("Array name (a single letter will do)",
  4302.                "",
  4303.                &s,
  4304.                NULL
  4305.                )) < 0) {
  4306.         if (x == -3)
  4307.           break;
  4308.         else
  4309.           return(x);
  4310.         }
  4311.         if ((x = arraybounds(s,&(range[0]),&(range[1]))) < 0) {
  4312.         printf("?Bad array: %s\n",s);
  4313.         return(-9);
  4314.         }
  4315.         if (!(ap = a_ptr[x])) {
  4316.         printf("?No such array: %s\n",s);
  4317.         return(-9);
  4318.         }
  4319.         pv[n].ival = 1;
  4320.         pv[SND_CMD].ival = 0;    /* Undo any conflicting ones... */
  4321.         pv[SND_RES].ival = 0;
  4322.         pv[SND_CAL].ival = 0;
  4323.         pv[SND_FIL].ival = 0;
  4324.         arrayx = x;
  4325.         break;
  4326. #endif /* NOSPL */
  4327.  
  4328.       case SND_XPA:            /* /TRANSPARENT */
  4329.         pv[n].ival = 1;
  4330.         break;
  4331.  
  4332.       case SND_TYP:            /* Only files of given type */
  4333.         if (!getval) break;
  4334.         if ((x = cmkey(txtbin,3,"","all",xxstring)) < 0)
  4335.           goto xsendx;
  4336.         pv[n].ival = (x == 2) ? -1 : x;
  4337.         break;
  4338.  
  4339.       default:
  4340.         printf("?Unexpected switch value - %d\n",cmresult.nresult);
  4341.         x = -9;
  4342.         goto xsendx;
  4343.     }
  4344.     }
  4345.     debug(F101,"xsend cmresult fcode","",cmresult.fcode);
  4346.  
  4347. #ifdef COMMENT
  4348.     /* List switch parsing results in debug log */
  4349.     for (i = 0; i <= SND_MAX; i++) {
  4350.     ckmakmsg(line,LINBUFSIZ,"xsend switch ",ckitoa(i),NULL,NULL);
  4351.     debug(F111,line, pv[i].sval, pv[i].ival);
  4352.     }
  4353. #endif /* COMMENT */
  4354.  
  4355. /* Now we have all switches, plus maybe a filename or command, or nothing */
  4356.  
  4357. #ifdef PIPESEND
  4358.     if (protocol != PROTO_K && pv[SND_CMD].ival > 0) {
  4359.     printf("?Sorry, %s works only with Kermit protocol\n",
  4360.            (cx == XXCSEN) ? "CSEND" : "SEND /COMMAND");
  4361.     x = -9;
  4362.     goto xsendx;
  4363.     }
  4364.     if (pv[SND_RES].ival > 0 ||    /* /RECOVER */
  4365.     pv[SND_STA].ival > 0) {    /* or /STARTING */
  4366.     if (sndfilter || pv[SND_FLT].ival > 0) {
  4367.         printf("?Sorry, no /RECOVER or /START if SEND FILTER selected\n");
  4368.         x = -9;
  4369.         goto xsendx;
  4370.     }
  4371.     }
  4372. #endif /* PIPESEND */
  4373.  
  4374.     cmarg = "";
  4375.     cmarg2 = "";
  4376.     line[0] = NUL;
  4377.     s = line;
  4378.     wild = 0;
  4379.  
  4380.     switch (cmresult.fcode) {        /* How did we get out of switch loop */
  4381.       case _CMIFI:            /* Input filename */
  4382.     ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Name */
  4383.     if (pv[SND_ARR].ival > 0)
  4384.       cmarg2 = line;
  4385.     else
  4386.       wild = cmresult.nresult;    /* Wild flag */
  4387.     if (!recursive && !wild)
  4388.       nolinks = 0;
  4389.     break;
  4390.       case _CMFLD:            /* Field */
  4391.     /* Only allowed with /COMMAND and /ARRAY */
  4392.     if (pv[SND_CMD].ival < 1 && pv[SND_ARR].ival < 1) {
  4393. #ifdef CKROOT
  4394.         if (ckrooterr)
  4395.           printf("?Off limits: %s\n",cmresult.sresult);
  4396.         else
  4397. #endif /* CKROOT */
  4398.           printf("?%s - \"%s\"\n",
  4399.            iswild(cmresult.sresult) ?
  4400.            "No files match" : "File not found",
  4401.            cmresult.sresult
  4402.            );
  4403.         x = -9;
  4404.         goto xsendx;
  4405.     }
  4406.     ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  4407.     if (pv[SND_ARR].ival > 0)
  4408.       cmarg2 = line;
  4409.     break;
  4410.       case _CMCFM:            /* Confirmation */
  4411.     /* s = ""; */
  4412.     confirmed = 1;
  4413.     break;
  4414.       default:
  4415.     printf("?Unexpected function code: %d\n",cmresult.fcode);
  4416.     x = -9;
  4417.     goto xsendx;
  4418.     }
  4419.     debug(F110,"xsend string",s,0);
  4420.     debug(F101,"xsend confirmed","",confirmed);
  4421.  
  4422.     /* Save and change protocol and transfer mode */
  4423.     /* Global values are restored in main parse loop */
  4424.  
  4425.     g_proto = protocol;            /* Save current global protocol */
  4426.     g_urpsiz = urpsiz;
  4427.     g_spsizf = spsizf;
  4428.     g_spsiz = spsiz;
  4429.     g_spsizr = spsizr;
  4430.     g_spmax = spmax;
  4431.     g_wslotr = wslotr;
  4432.     g_prefixing = prefixing;
  4433.     g_fncact = fncact;
  4434.     g_fncnv = fncnv;
  4435.     g_fnspath = fnspath;
  4436.     g_fnrpath = fnrpath;
  4437.     g_xfrxla = xfrxla;
  4438.  
  4439.     if (pv[SND_PRO].ival > -1) {    /* Change according to switch */
  4440.     protocol = pv[SND_PRO].ival;
  4441.         if (ptab[protocol].rpktlen > -1) /* copied from initproto() */
  4442.             urpsiz = ptab[protocol].rpktlen;
  4443.         if (ptab[protocol].spktflg > -1)
  4444.             spsizf = ptab[protocol].spktflg;
  4445.         if (ptab[protocol].spktlen > -1) {
  4446.             spsiz = ptab[protocol].spktlen;
  4447.             if (spsizf)
  4448.           spsizr = spmax = spsiz;
  4449.         }
  4450.         if (ptab[protocol].winsize > -1)
  4451.             wslotr = ptab[protocol].winsize;
  4452.         if (ptab[protocol].prefix > -1)
  4453.             prefixing = ptab[protocol].prefix;
  4454.         if (ptab[protocol].fnca > -1)
  4455.             fncact  = ptab[protocol].fnca;
  4456.         if (ptab[protocol].fncn > -1)
  4457.             fncnv   = ptab[protocol].fncn;
  4458.         if (ptab[protocol].fnsp > -1)
  4459.             fnspath = ptab[protocol].fnsp;
  4460.         if (ptab[protocol].fnrp > -1)
  4461.             fnrpath = ptab[protocol].fnrp;
  4462.     }
  4463.     debug(F101,"xsend protocol","",protocol);
  4464.  
  4465.     if (pv[SND_NOB].ival > -1) {    /* /NOBACKUP (skip backup file) */
  4466.     g_skipbup = skipbup;
  4467.     skipbup = 1;
  4468.     }
  4469.     if (pv[SND_REC].ival > 0)        /* /RECURSIVE */
  4470.       recursive = 2;
  4471.  
  4472.     if (pv[SND_TYP].ival > -1) {    /* /TYPE */
  4473.     xfiletype = pv[SND_TYP].ival;
  4474.     if (xfiletype == 2)
  4475.       xfiletype = -1;
  4476.     }
  4477.     g_binary = binary;            /* Save global transfer mode */
  4478. #ifdef PATTERNS
  4479.     g_patterns = patterns;        /* Save FILE PATTERNS setting */
  4480. #endif /* PATTERNS */
  4481.     if (pv[SND_BIN].ival > 0) {        /* Change according to switch */
  4482.     /* If they said /BINARY they mean /BINARY */
  4483.     patterns = 0;            /* So no pattern-based switching */
  4484.     g_xfermode = xfermode;        /* or automatic transfer mode */
  4485.     xfermode = XMODE_M;
  4486.     binary = XYFT_B;
  4487.     debug(F101,"doxsend /BINARY xfermode","",xfermode);
  4488.     } else if (pv[SND_TXT].ival > 0) {    /* Ditto for /TEXT */
  4489.     patterns = 0;
  4490.     g_xfermode = xfermode;
  4491.     xfermode = XMODE_M;
  4492.     binary = XYFT_T;
  4493.     debug(F101,"doxsend /TEXT xfermode","",xfermode);
  4494.     } else if (pv[SND_IMG].ival > 0) {
  4495. #ifdef VMS
  4496.     binary = XYFT_I;
  4497. #else
  4498.     binary = XYFT_B;
  4499. #endif /* VMS */
  4500.     }
  4501. #ifdef CK_LABELED
  4502.     else if (pv[SND_LBL].ival > 0) {
  4503.     binary = XYFT_L;
  4504.     }
  4505. #endif /* CK_LABELED */
  4506.     debug(F101,"xsend binary","",binary);
  4507.  
  4508.     if (pv[SND_XPA].ival > 0)        /* /TRANSPARENT */
  4509.       xfrxla = 0;            /* Don't translate character sets */
  4510.  
  4511.     /* Check for legal combinations of switches, filenames, etc */
  4512.  
  4513. #ifdef PIPESEND
  4514.     if (pv[SND_CMD].ival > 0) {    /* COMMAND - strip any braces */
  4515.     debug(F110,"SEND /COMMAND before stripping",s,0);
  4516.     s = brstrip(s);
  4517.     debug(F110,"SEND /COMMAND after stripping",s,0);
  4518.     if (!*s) {
  4519.         printf("?Sorry, a command to send from is required\n");
  4520.         x = -9;
  4521.         goto xsendx;
  4522.     }
  4523.     cmarg = s;
  4524.     }
  4525. #endif /* PIPESEND */
  4526.  
  4527. /* Set up /MOVE and /RENAME */
  4528.  
  4529.     if (pv[SND_DEL].ival > 0 &&
  4530.     (pv[SND_MOV].ival > 0 || pv[SND_REN].ival > 0)) {
  4531.     printf("?Sorry, /DELETE conflicts with /MOVE or /RENAME\n");
  4532.     x = -9;
  4533.     goto xsendx;
  4534.     }
  4535. #ifdef CK_TMPDIR
  4536.     if (pv[SND_MOV].ival > 0) {
  4537.     int len;
  4538.     char * p = pv[SND_MOV].sval;
  4539. #ifdef CK_LOGIN
  4540.     if (isguest) {
  4541.         printf("?Sorry, /MOVE-TO not available to guests\n");
  4542.         x = -9;
  4543.         goto xsendx;
  4544.     }
  4545. #endif /* CK_LOGIN */
  4546.     len = strlen(p);
  4547.     if (!isdir(p)) {        /* Check directory */
  4548. #ifdef CK_MKDIR
  4549.         char * s = NULL;
  4550.         s = (char *)malloc(len + 4);
  4551.         if (s) {
  4552.         strcpy(s,p);        /* safe */
  4553. #ifdef datageneral
  4554.         if (s[len-1] != ':') { s[len++] = ':'; s[len] = NUL; }
  4555. #else
  4556.         if (s[len-1] != '/') { s[len++] = '/'; s[len] = NUL; }
  4557. #endif /* datageneral */
  4558.         s[len++] = 'X';
  4559.         s[len] = NUL;
  4560.         x = zmkdir(s);
  4561.         free(s);
  4562.         if (x < 0) {
  4563.             printf("?Can't create \"%s\"\n",p);
  4564.             x = -9;
  4565.             goto xsendx;
  4566.         }
  4567.         }
  4568. #else
  4569.         printf("?Directory \"%s\" not found\n",p);
  4570.         x = -9;
  4571.         goto xsendx;
  4572. #endif /* CK_MKDIR */
  4573.     }
  4574.         zfnqfp(p,LINBUFSIZ,line);
  4575.     makestr(&snd_move,line);
  4576.     }
  4577. #endif /* CK_TMPDIR */
  4578.  
  4579.     if (pv[SND_REN].ival > 0) {        /* /RENAME */
  4580.     char * p = pv[SND_REN].sval;
  4581. #ifdef CK_LOGIN
  4582.     if (isguest) {
  4583.         printf("?Sorry, /RENAME-TO not available to guests\n");
  4584.         x = -9;
  4585.         goto xsendx;
  4586.     }
  4587. #endif /* CK_LOGIN */
  4588.     if (!p) p = "";
  4589.     if (!*p) {
  4590.         printf("?New name required for /RENAME\n");
  4591.         x = -9;
  4592.         goto xsendx;
  4593.     }
  4594.     p = brstrip(p);
  4595. #ifndef NOSPL
  4596.     /* If name given is wild, rename string must contain variables */
  4597.     if (wild) {
  4598.         char * s = tmpbuf;
  4599.         x = TMPBUFSIZ;
  4600.         zzstring(p,&s,&x);
  4601.         if (!strcmp(tmpbuf,p)) {
  4602.         printf(
  4603.     "?/RENAME for file group must contain variables such as \\v(filename)\n"
  4604.                );
  4605.         x = -9;
  4606.         goto xsendx;
  4607.         }
  4608.     }
  4609. #endif /* NOSPL */
  4610.     makestr(&snd_rename,p);
  4611.     }
  4612.  
  4613. /* Handle /RECOVER and /START */
  4614.  
  4615. #ifdef CK_RESEND
  4616.     if (pv[SND_RES].ival > 0 && binary != XYFT_B && !filepeek
  4617. #ifdef PATTERNS
  4618.     && !patterns
  4619. #else
  4620. #ifdef VMS
  4621. /* VMS sets text/binary automatically later when it opens the file */
  4622.     && 0
  4623. #endif /* VMS */
  4624. #endif /* PATTERNS */
  4625.     ) {
  4626.     printf("?Sorry, /BINARY required\n");
  4627.     x = -9;
  4628.     goto xsendx;
  4629.     }
  4630.     if (pv[SND_STA].ival > 0) {        /* /START */
  4631.     if (wild) {
  4632.         printf("?Sorry, wildcards not permitted with /START\n");
  4633.         x = -9;
  4634.         goto xsendx;
  4635.     }
  4636.     if (sizeof(int) < 4) {
  4637.         printf("?Sorry, this command needs 32-bit integers\n");
  4638.         x = -9;
  4639.         goto xsendx;
  4640.     }
  4641. #ifdef CK_XYZ
  4642.     if (protocol != PROTO_K) {
  4643.         printf("?Sorry, SEND /START works only with Kermit protocol\n");
  4644.         x = -9;
  4645.         goto xsendx;
  4646.     }
  4647. #endif /* CK_XYZ */
  4648.     }
  4649. #ifdef CK_XYZ
  4650.     if (pv[SND_RES].ival > 0) {
  4651.     if (protocol != PROTO_K && protocol != PROTO_Z) {
  4652.         printf(
  4653.     "Sorry, /RECOVER is possible only with Kermit or ZMODEM protocol\n"
  4654.            );
  4655.         x = -9;
  4656.         goto xsendx;
  4657.     }
  4658.     }
  4659. #endif /* CK_XYZ */
  4660. #endif /* CK_RESEND */
  4661.  
  4662.     if (protocol == PROTO_K) {
  4663.     if ((pv[SND_MAI].ival > 0 ||    /* MAIL */
  4664.          pv[SND_PRI].ival > 0 ||    /* PRINT */
  4665.          pv[SND_RES].ival > 0    /* RESEND */
  4666.          ) &&
  4667.         (!atdiso || !atcapr)) {    /* Disposition attribute off? */
  4668.         printf("?Sorry, ATTRIBUTE DISPOSITION must be ON\n");
  4669.         x = -9;
  4670.         goto xsendx;
  4671.     }
  4672.     }
  4673.  
  4674. #ifdef CK_XYZ
  4675.     if (wild && (protocol == PROTO_X || protocol == PROTO_XC)) {
  4676.     printf(
  4677. "Sorry, you can only send one file at a time with XMODEM protocol\n"
  4678.            );
  4679.     x = -9;
  4680.     goto xsendx;
  4681.     }
  4682. #endif /* CK_XYZ */
  4683.  
  4684.     if (!confirmed) {            /* CR not typed yet, get more fields */
  4685.     char *m;
  4686.     if (mlist) {            /* MSEND or MMOVE */
  4687.         nfils = 0;            /* We already have the first one */
  4688. #ifndef NOMSEND
  4689.         msfiles[nfils++] = line;    /* Store pointer */
  4690.         lp = line + (int)strlen(line) + 1; /* Point past it */
  4691.         debug(F111,"xsend msend",msfiles[nfils-1],nfils-1);
  4692.         while (1) {            /* Get more filenames */
  4693.         char *p;
  4694.         if ((x = cmifi("Names of files to send, separated by spaces",
  4695.                    "", &s,&y,xxstring)) < 0) {
  4696.             if (x != -3)
  4697.               goto xsendx;
  4698.             if ((x = cmcfm()) < 0)
  4699.               goto xsendx;
  4700.             break;
  4701.         }
  4702.         msfiles[nfils++] = lp;    /* Got one, count it, point to it, */
  4703.         p = lp;            /* remember pointer, */
  4704.         while ((*lp++ = *s++))    /* and copy it into buffer */
  4705.           if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
  4706.               printf("?MSEND list too long\n");
  4707.               line[0] = NUL;
  4708.               x = -9;
  4709.               goto xsendx;
  4710.           }
  4711.         debug(F111,"xsend msend",msfiles[nfils-1],nfils-1);
  4712.         if (nfils == 1) fspec[0] = NUL; /* Take care of \v(filespec) */
  4713. #ifdef ZFNQFP
  4714.         zfnqfp(p,TMPBUFSIZ,tmpbuf);
  4715.         p = tmpbuf;
  4716. #endif /* ZFNQFP */
  4717.         if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) {
  4718.             strcat(fspec,p);    /* safe */
  4719.             strcat(fspec," ");    /* safe */
  4720.         } else
  4721. #ifdef COMMENT
  4722.           printf("WARNING - \\v(filespec) buffer overflow\n");
  4723. #else
  4724.           debug(F101,"doxsend filespec buffer overflow","",0);
  4725. #endif /* COMMENT */
  4726.         }
  4727. #endif /* NOMSEND */
  4728.     } else {            /* Regular SEND */
  4729.         char *p; int y;
  4730.         nfils = -1;
  4731.         if (pv[SND_MAI].ival > 0)
  4732.           m = (pv[SND_MAI].sval) ?
  4733.         "e-mail address (optional)" :
  4734.           "e-mail address (required)";
  4735.         else if (pv[SND_PRI].ival > 0)
  4736.           m = "printer options (optional)";
  4737.         else if (wild)
  4738.           m =
  4739. "\nOptional as-name template containing replacement variables \
  4740. like \\v(filename)";
  4741.         else
  4742.           m = "Optional name to send it with";
  4743.         if ((x = cmtxt(m,"",&p,NULL)) < 0)
  4744.           goto xsendx;
  4745.         if (!p) p = "";
  4746.         if (*p) {            /* If some text was given... */
  4747.         p = brstrip(p);        /* Replace /AS-NAME: value if any */
  4748.         if ((y = strlen(p)) > 0) {
  4749.                     if (pv[SND_MAI].ival > 0) {
  4750.                         makestr(&pv[SND_MAI].sval, p);
  4751.                     } else {
  4752.             if (pv[SND_ASN].sval) free(pv[SND_ASN].sval);
  4753.             pv[SND_ASN].sval = malloc(y+1);
  4754.             if (pv[SND_ASN].sval) {
  4755.                 strcpy(pv[SND_ASN].sval,p);    /* safe */
  4756.                 pv[SND_ASN].ival = 1;
  4757.             }
  4758.             }
  4759.         }
  4760.         }
  4761.     }
  4762.     }
  4763.     /* Set cmarg2 from as-name, however we got it. */
  4764.  
  4765.     if (pv[SND_ASN].ival > 0 && pv[SND_ASN].sval && !*cmarg2) {
  4766.     int x;
  4767.     x = strlen(line);
  4768.     ckstrncpy(line+x+2,pv[SND_ASN].sval,LINBUFSIZ-x-1);
  4769.     cmarg2 = line+x+2;
  4770.     debug(F110,"doxsend cmarg2",cmarg2,0);
  4771.     }
  4772.  
  4773. #ifndef NOFRILLS
  4774.     if ((pv[SND_MAI].ival > 0) && (pv[SND_PRI].ival > 0)) {
  4775.     printf("Sorry, /MAIL and /PRINT are conflicting options\n");
  4776.     x = -9;
  4777.     goto xsendx;
  4778.     }
  4779.     n = 0;                /* /MAIL or /PRINT? */
  4780.     if (pv[SND_MAI].ival > 0)
  4781.       n = SND_MAI;
  4782.     else if (pv[SND_PRI].ival > 0)
  4783.       n = SND_PRI;
  4784.     if (n) {                /* Yes... */
  4785. #ifdef DEBUG
  4786.     char * p;
  4787.     if (n == SND_MAI)
  4788.       p = "/MAIL";
  4789.     else
  4790.       p = "/PRINT";
  4791.     debug(F111,"xsend",p,n);
  4792. #endif /* DEBUG */
  4793. #ifdef CK_XYZ
  4794.     if (protocol != PROTO_K) {
  4795.         printf("Sorry, %s available only with Kermit protocol\n",
  4796.            (n == SND_MAI) ? "/MAIL" : "/PRINT"
  4797.            );
  4798.         x = -9;
  4799.         goto xsendx;
  4800.     }
  4801. #endif /* CK_XYZ */
  4802.     debug(F101,"xsend print/mail wild","",wild);
  4803.     *optbuf = NUL;            /* Wipe out any old options */
  4804.     s = pv[n].sval;            /* mail address or print switch val */
  4805.     if (!s) s = "";
  4806.     debug(F110,"doxsend mail address or printer options",s,0);
  4807.     if (n == SND_MAI && !*s) {
  4808.         printf("?E-mail address required\n");
  4809.         x = -9;
  4810.         goto xsendx;
  4811.     } else if ((int)strlen(s) > 94) { /* Ensure legal size */
  4812.         printf("?%s too long\n",
  4813.            (n == SND_MAI) ?
  4814.            "E-mail address" :
  4815.            "Print option string"
  4816.            );
  4817.         x = -9;
  4818.         goto xsendx;
  4819.     }
  4820.     ckstrncpy(optbuf,s,OPTBUFLEN);    /* OK, copy to option buffer */
  4821.     cmarg = line;            /* File to send */
  4822.     if (n == SND_MAI) {
  4823.         debug(F110,"xsend mailing",cmarg,0);
  4824.         debug(F110,"xsend address:",optbuf,0);
  4825.         rmailf = 1;
  4826.     } else {
  4827.         debug(F110,"xsend printing",cmarg,0);
  4828.         debug(F110,"xsend options",optbuf,0);
  4829.         rprintf = 1;
  4830.     }
  4831.     }
  4832. #endif /* NOFRILLS */
  4833.  
  4834. #ifdef CALIBRATE
  4835.     if (pv[SND_CAL].ival > 0) {        /* Handle /CALIBRATE */
  4836.     if (confirmed) {
  4837.         calibrate = pv[SND_CAL].ival * 1024L;
  4838.         sndsrc = -9;
  4839.         nfils = 1;
  4840.         wild = 0;
  4841. #ifndef NOMSEND
  4842.         addlist = 0;
  4843. #endif /* NOMSEND */
  4844.         ckstrncpy(line,"CALIBRATION",LINBUFSIZ);
  4845.         s = cmarg = line;
  4846.         if (!cmarg2) cmarg2 = "";
  4847.         debug(F110,"doxsend cmarg2 calibrate",cmarg2,0);
  4848.     } else if (line[0]) {
  4849.         calibrate = 0L;
  4850.         pv[SND_CAL].ival = 0L;
  4851.     }
  4852.     }
  4853. #endif /* CALIBRATE */
  4854.  
  4855.     if (pv[SND_FIL].ival > 0) {
  4856.     if (confirmed && !calibrate) {
  4857.         if (zopeni(ZMFILE,pv[SND_FIL].sval) < 1) {
  4858.         debug(F110,"xsend can't open",pv[SND_FIL].sval,0);
  4859.         printf("?Failure to open %s\n",filefile);
  4860.         x = -9;
  4861.         goto xsendx;
  4862.         }
  4863.         makestr(&filefile,pv[SND_FIL].sval); /* Open, remember name */
  4864.         debug(F110,"xsend opened",filefile,0);
  4865.         wild = 1;
  4866.     }
  4867.     }
  4868.  
  4869.     /* SEND alone... */
  4870.  
  4871. #ifndef NOSPL
  4872.     if (confirmed && pv[SND_ARR].ival > 0) {
  4873.     if (!*cmarg2) {
  4874.         sndxnam[7] = (char)((arrayx == 1) ? 64 : arrayx + ARRAYBASE);
  4875.         cmarg2 = sndxnam;
  4876.     }
  4877.     cmarg = "";
  4878.     goto sendend;
  4879.     }
  4880. #endif /* NOSPL */
  4881.  
  4882.     if (confirmed && !line[0] && !filefile && !calibrate) {
  4883. #ifndef NOMSEND
  4884.     if (filehead) {            /* OK if we have a SEND-LIST */
  4885.         nfils = filesinlist;
  4886.         sndsrc = nfils;        /* Like MSEND */
  4887.         addlist = 1;        /* But using a different list... */
  4888.         filenext = filehead;
  4889.         goto sendend;
  4890.     }
  4891. #endif /* NOMSEND */
  4892.     printf("?Filename required but not given\n");
  4893.     x = -9;
  4894.     goto xsendx;
  4895.     }
  4896.  
  4897.     /* Not send-list or array */
  4898.  
  4899. #ifndef NOMSEND
  4900.     addlist = 0;            /* Don't use SEND-LIST. */
  4901.     filenext = NULL;
  4902. #endif /* NOMSEND */
  4903.  
  4904.     if (mlist) {            /* MSEND or MMOVE */
  4905. #ifndef NOMSEND
  4906.     cmlist = msfiles;        /* List of files to send */
  4907.     sndsrc = nfils;
  4908.     cmarg2 = "";
  4909.     sendstart = 0L;
  4910. #endif /* NOMSEND */
  4911. #ifdef PIPESEND
  4912.     pipesend = 0;
  4913. #endif /* PIPESEND */
  4914.     } else if (filefile) {        /* File contains list of filenames */
  4915.     s = "";
  4916.     cmarg = "";
  4917.     cmarg2 = "";
  4918.     line[0] = NUL;
  4919.     nfils = 1;
  4920.     sndsrc = 1;
  4921.  
  4922.     } else if (!calibrate && pv[SND_ARR].ival < 1 && pv[SND_CMD].ival < 1) {
  4923.  
  4924.     nfils = sndsrc = -1;    /* Not MSEND, MMOVE, /LIST, or /ARRAY */
  4925.     if (                /* or /COMMAND */
  4926.  
  4927. #ifndef NOFRILLS
  4928.         !rmailf && !rprintf        /* Not MAIL or PRINT */
  4929. #else
  4930.         1
  4931. #endif /* NOFRILLS */
  4932.         ) {
  4933.         int y = 1;
  4934.         if (!wild)
  4935.           y = zchki(s);
  4936.         if (y < 0) {
  4937.         printf("?Read access denied - \"%s\"\n", s);
  4938.         x = -9;
  4939.         goto xsendx;
  4940.         }
  4941.         if (s != line)        /* We might already have done this. */
  4942.           ckstrncpy(line,s,LINBUFSIZ); /* Copy of string just parsed. */
  4943.         else
  4944.           debug(F110,"doxsend line=s",line,0);
  4945.         cmarg = line;        /* File to send */
  4946.     }
  4947.     zfnqfp(cmarg,fspeclen,fspec);
  4948.     }
  4949.     if (!mlist) {            /* For all but MSEND... */
  4950. #ifdef PIPESEND
  4951.     if (pv[SND_CMD].ival > 0)    /* /COMMAND sets pipesend flag */
  4952.       pipesend = 1;
  4953.     debug(F101,"xsend /COMMAND pipesend","",pipesend);
  4954.     if (pipesend && filefile) {
  4955.         printf("?Invalid switch combination\n");
  4956.         x = -9;
  4957.         goto xsendx;
  4958.     }
  4959. #endif /* PIPESEND */
  4960.  
  4961. #ifndef NOSPL
  4962.     /* If as-name given and filespec is wild, as-name must contain variables */
  4963.     debug(F111,"doxsend cmarg2 wild",cmarg2,wild);
  4964.     if (wild && *cmarg2) {
  4965.         char * s = tmpbuf;
  4966.         x = TMPBUFSIZ;
  4967.         zzstring(cmarg2,&s,&x);
  4968.         if (!strcmp(tmpbuf,cmarg2)) {
  4969.         printf(
  4970.     "?As-name for file group must contain variables such as \\v(filename)\n"
  4971.                );
  4972.         x = -9;
  4973.         goto xsendx;
  4974.         }
  4975.     }
  4976. #endif /* NOSPL */
  4977.  
  4978.     /* Strip braces from as-name */
  4979.     debug(F110,"xsend cmarg2 before stripping",cmarg2,0);
  4980.     cmarg2 = brstrip(cmarg2);
  4981.     debug(F110,"xsend filename",cmarg,0);
  4982.     debug(F110,"xsend as-name",cmarg2,0);
  4983.  
  4984.     /* Copy as-name to a safe place */
  4985.  
  4986.     if (asnbuf) {
  4987.         free(asnbuf);
  4988.         asnbuf = NULL;
  4989.     }
  4990.     if ((y = strlen(cmarg2)) > 0) {
  4991.         asnbuf = (char *) malloc(y + 1);
  4992.         if (asnbuf) {
  4993.         strcpy(asnbuf,cmarg2);    /* safe */
  4994.         cmarg2 = asnbuf;
  4995.         } else cmarg2 = "";
  4996.     }
  4997.  
  4998. #ifdef CK_RESEND
  4999.     debug(F111,"xsend pv[SND_STA].ival","",pv[SND_STA].ival);
  5000.     if (pv[SND_STA].ival > -1) {    /* /START position */
  5001.         if (wild) {
  5002.         printf("?/STARTING-AT may not be used with multiple files.\n");
  5003.         x = -9;
  5004.         goto xsendx;
  5005.         } else
  5006.           sendstart = pv[SND_STA].ival;
  5007.     } else
  5008.       sendstart = 0L;
  5009.     debug(F101,"xsend /STARTING","",sendstart);
  5010. #endif /* CK_RESEND */
  5011.     }
  5012.  
  5013. sendend:                /* Common successful exit */
  5014.     moving = 0;
  5015.     if (pv[SND_SHH].ival > 0) {        /* SEND /QUIET... */
  5016.     g_displa = fdispla;
  5017.     fdispla = 0;
  5018.     debug(F101,"xsend display","",fdispla);
  5019.     }
  5020.  
  5021. #ifndef NOSPL                /* SEND /ARRAY... */
  5022.     if (pv[SND_ARR].ival > 0) {
  5023.     if (!ap) { x = -2; goto xsendx; } /* (shouldn't happen) */
  5024.     if (range[0] == -1)        /* If low end of range not specified */
  5025.       range[0] = 1;            /* default to 1 */
  5026.     if (range[1] == -1)        /* If high not specified */
  5027.       range[1] = a_dim[arrayx];    /* default to size of array */
  5028.     if ((range[0] < 0) ||        /* Check range */
  5029.         (range[0] > a_dim[arrayx]) ||
  5030.         (range[1] < range[0]) ||
  5031.         (range[1] > a_dim[arrayx])) {
  5032.         printf("?Bad array range - [%d:%d]\n",range[0],range[1]);
  5033.         x = -9;
  5034.         goto xsendx;
  5035.     }
  5036.     sndarray = ap;            /* Array pointer */
  5037.     sndxin = arrayx;        /* Array index */
  5038.     sndxlo = range[0];        /* Array range */
  5039.     sndxhi = range[1];
  5040.     sndxnam[7] = (char)((sndxin == 1) ? 64 : sndxin + ARRAYBASE);
  5041.  
  5042. #ifdef COMMENT
  5043.     printf("SENDING FROM ARRAY: &%c[]...\n", /* debugging */
  5044.            (sndxin == 1) ? 64 : sndxin + ARRAYBASE);
  5045.     printf("Lo=%d\nHi=%d\n", sndxlo, sndxhi);
  5046.     printf("cmarg=[%s]\ncmarg2=[%s]\n", cmarg, cmarg2);
  5047.     while ((x = agnbyte()) > -1) {
  5048.         putchar((char)x);
  5049.     }
  5050.     return(1);
  5051. #endif /* COMMENT */
  5052.     }
  5053. #endif /* NOSPL */
  5054.  
  5055.     if (pv[SND_ARR].ival < 1) {        /* File selection & disposition... */
  5056.  
  5057.     if (pv[SND_DEL].ival > 0)    /* /DELETE was specified */
  5058.       moving = 1;
  5059.     debug(F101,"xsend /DELETE","",moving);
  5060.     if (pv[SND_AFT].ival > 0)    /* Copy SEND criteria */
  5061.       ckstrncpy(sndafter,pv[SND_AFT].sval,19);
  5062.     if (pv[SND_BEF].ival > 0)
  5063.       ckstrncpy(sndbefore,pv[SND_BEF].sval,19);
  5064.     if (pv[SND_NAF].ival > 0)
  5065.       ckstrncpy(sndnafter,pv[SND_NAF].sval,19);
  5066.     if (pv[SND_NBE].ival > 0)
  5067.       ckstrncpy(sndnbefore,pv[SND_NBE].sval,19);
  5068.     if (pv[SND_EXC].ival > 0)
  5069.       makelist(pv[SND_EXC].sval,sndexcept,NSNDEXCEPT);
  5070.     if (pv[SND_SMA].ival > -1)
  5071.       sndsmaller = pv[SND_SMA].ival;
  5072.     if (pv[SND_LAR].ival > -1)
  5073.       sndlarger = pv[SND_LAR].ival;
  5074.     if (pv[SND_NAM].ival > -1) {
  5075.         g_fncnv = fncnv;        /* Save global value */
  5076.         fncnv = pv[SND_NAM].ival;
  5077.         debug(F101,"xsend fncnv","",fncnv);
  5078.     }
  5079.     if (pv[SND_PTH].ival > -1) {
  5080.         g_spath = fnspath;        /* Save global values */
  5081.         fnspath = pv[SND_PTH].ival;
  5082. #ifndef NZLTOR
  5083.         if (fnspath != PATH_OFF) {
  5084.         g_fncnv = fncnv;    /* Bad bad... */
  5085.         fncnv = XYFN_C;
  5086.         }
  5087. #endif /* NZLTOR */
  5088.         debug(F101,"xsend fnspath","",fnspath);
  5089.         debug(F101,"xsend fncnv","",fncnv);
  5090.     }
  5091.     }
  5092.  
  5093. #ifdef PIPESEND
  5094.     if (pv[SND_FLT].ival > 0) {
  5095.     makestr(&sndfilter,pv[SND_FLT].sval);
  5096.     debug(F110,"xsend /FILTER", sndfilter, 0);
  5097.     }
  5098. #endif /* PIPESEND */
  5099.  
  5100. #ifdef CK_APC
  5101. /* MOVE not allowed in APCs */
  5102.     if (moving &&
  5103.     (apcactive == APC_LOCAL || apcactive == APC_REMOTE)
  5104.     && !(apcstatus & APC_UNCH))
  5105.       return(success = 0);
  5106. #endif /* CK_APC */
  5107. #ifdef IKS_OPTION
  5108.     if (
  5109. #ifdef CK_XYZ
  5110.         protocol == PROTO_K &&
  5111. #endif /* CK_XYZ */
  5112.         !iks_wait(KERMIT_REQ_START,1)) {
  5113.         printf("?A Kermit Server is not available to process this command.\n");
  5114.         printf("?Start a RECEIVE command to complement this command.\n");
  5115.     }
  5116. #endif /* IKS_OPTION */
  5117.  
  5118. #ifdef IKSD
  5119. #ifdef CK_LOGIN
  5120.     if (moving && inserver && isguest) {
  5121.         printf("?File deletion not allowed for guests.\n");
  5122.     return(-9);
  5123.     }
  5124. #endif /* CK_LOGIN */
  5125. #endif /* IKSD */
  5126.  
  5127.     sstate = 's';            /* Set start state to SEND */
  5128.     sndcmd = 1;
  5129. #ifdef CK_RESEND
  5130.     if (pv[SND_RES].ival > 0)        /* Send sendmode appropriately */
  5131.       sendmode = SM_RESEND;
  5132.     else if (pv[SND_STA].ival > 0)
  5133.       sendmode = SM_PSEND;
  5134.     else
  5135. #endif /* CK_RESEND */
  5136.     if (mlist)
  5137.       sendmode = SM_MSEND;
  5138.     else
  5139.       sendmode = SM_SEND;
  5140. #ifdef MAC
  5141.     what = W_SEND;
  5142.     scrcreate();
  5143. #endif /* MAC */
  5144.     if (local && pv[SND_SHH].ival != 0) { /* If in local mode, */
  5145.     displa = 1;            /* turn on file transfer display */
  5146.     }
  5147.     x = 0;
  5148.  
  5149.   xsendx:                /* Common exit, including failure */
  5150.     debug(F101,"doxsend sndsrc","",sndsrc);
  5151.     for (i = 0; i <= SND_MAX; i++) {    /* Free malloc'd memory */
  5152.     if (pv[i].sval)
  5153.       free(pv[i].sval);
  5154.     }
  5155.     return(x);
  5156. }
  5157. #endif /* NOXFER */
  5158.  
  5159. #ifndef NOLOCAL
  5160. /*  D O X C O N N  --  CONNECT command parsing with switches */
  5161.  
  5162. #ifdef XLIMITS
  5163. #define XLIMORTRIGGER
  5164. #else
  5165. #ifdef CK_TRIGGER
  5166. #define XLIMORTRIGGER
  5167. #endif /* CK_TRIGGER */
  5168. #endif /*  XLIMITS */
  5169.  
  5170. #ifdef CKTIDLE
  5171. int tt_idlelimit = 0;            /* Terminal idle limit */
  5172. int tt_idleact = IDLE_RET;        /* Terminal idle action */
  5173. #endif /* CKTIDLE */
  5174.  
  5175. #ifdef OS2                /* K95 only: */
  5176. extern int
  5177.   tt_idlesnd_tmo;            /*   Idle interval */
  5178. int tt_timelimit = 0;            /*   Time limit, 0 = none */
  5179. extern char *                /* Parse results - strings: */
  5180.   tt_idlesnd_str;            /*   Idle string */
  5181. #endif /* OS2 */
  5182.  
  5183. #ifdef CK_TRIGGER
  5184. extern char *tt_trigger[];
  5185. extern CHAR *tt_trmatch[];
  5186. extern char *triggerval;
  5187. static char *g_tt_trigger[TRIGGERS];
  5188. #endif /* CK_TRIGGER */
  5189.  
  5190. #ifdef OS2
  5191. static int g_tt_idlesnd_tmo, g_tt_timelimit; /* For saving and restoring */
  5192. static int g_tt_idlelimit, g_tt_saved = 0;
  5193. static char * g_tt_idlesnd_str;        /* global settings */
  5194. #endif /* OS2 */
  5195.  
  5196. static struct stringint {        /* Temporary array for switch values */
  5197.     char * sval;
  5198.     int ival;
  5199. } pv[CONN_MAX+1];
  5200.  
  5201. VOID
  5202. resconn() {
  5203.     int i;
  5204.  
  5205. #ifdef OS2
  5206.     if ( g_tt_saved ) {
  5207.         tt_idlelimit   = g_tt_idlelimit;
  5208.         tt_idlesnd_tmo = g_tt_idlesnd_tmo;
  5209.         tt_timelimit   = g_tt_timelimit;
  5210.         tt_idlesnd_str = g_tt_idlesnd_str;
  5211.         g_tt_saved = 0;
  5212.     }
  5213. #endif /* OS2 */
  5214.  
  5215. #ifdef CK_TRIGGER
  5216.     for (i = 0; i < TRIGGERS; i++)
  5217.       tt_trigger[i] = g_tt_trigger[i];
  5218. #endif /* CK_TRIGGER */
  5219.  
  5220.     for (i = 0; i <= CONN_MAX; i++) {    /* Free malloc'd memory */
  5221.     if (pv[i].sval)
  5222.       free(pv[i].sval);
  5223.         pv[i].sval = NULL;
  5224.     }
  5225. }
  5226.  
  5227. int
  5228. doxconn(cx) int cx; {
  5229.     int c, i, n;            /* Workers */
  5230.     int x, y;
  5231.     int getval = 0;            /* Whether to get switch value */
  5232.     int async = 0;                      /* Make an async connect */
  5233.     struct FDB sw, cm;            /* FDBs for each parse function */
  5234.     extern FILE * tfile[];
  5235.     extern char * macp[];
  5236.  
  5237. #ifdef OS2
  5238.     g_tt_idlesnd_tmo = tt_idlesnd_tmo;    /* Save global settings */
  5239.     g_tt_timelimit   = tt_timelimit;
  5240.     g_tt_idlelimit   = tt_idlelimit;
  5241.     g_tt_idlesnd_str = tt_idlesnd_str;
  5242.     g_tt_saved = 1;
  5243. #endif /* OS2 */
  5244.  
  5245. #ifdef CK_TRIGGER
  5246.     if (!tt_trigger[0]) {        /* First initialization */
  5247.     for (i = 1; i < TRIGGERS; i++)
  5248.       tt_trigger[i] = NULL;
  5249.     }
  5250.     for (i = 0; i < TRIGGERS; i++)
  5251.       g_tt_trigger[i] = tt_trigger[i];
  5252.     if (triggerval) {
  5253.     free(triggerval);
  5254.     triggerval = NULL;
  5255.     }
  5256. #endif /* CK_TRIGGER */
  5257.  
  5258.     for (i = 0; i <= CONN_MAX; i++) {    /* Initialize switch values */
  5259.     pv[i].sval = NULL;        /* to null pointers */
  5260.     pv[i].ival = -1;        /* and -1 int values */
  5261.     }
  5262.     if (cx == XXCQ)            /* CQ == CONNECT /QUIETLY */
  5263.       pv[CONN_NV].ival = 1;
  5264.  
  5265.     /* Set up chained parse functions... */
  5266.  
  5267.     cmfdbi(&sw,                /* First FDB - command switches */
  5268.        _CMKEY,            /* fcode */
  5269.        "Switch",            /* hlpmsg */
  5270.        "",                /* default */
  5271.        "",                /* addtl string data */
  5272.        nconntab,            /* addtl numeric data 1: tbl size */
  5273.        4,                /* addtl numeric data 2: 4 = cmswi */
  5274.        xxstring,            /* Processing function */
  5275.        conntab,            /* Keyword table */
  5276.        &cm                /* Pointer to next FDB */
  5277.        );
  5278.     cmfdbi(&cm,                /* 2nd FDB - Confirmation */
  5279.        _CMCFM,            /* fcode */
  5280.        "",                /* hlpmsg */
  5281.        "",                /* default */
  5282.        "",                /* addtl string data */
  5283.        0,                /* addtl numeric data 1 */
  5284.        0,                /* addtl numeric data 2 */
  5285.        NULL,
  5286.        NULL,
  5287.        NULL
  5288.        );
  5289.  
  5290.     while (1) {                /* Parse 0 or more switches */
  5291.     x = cmfdb(&sw);            /* Parse switch or confirmation */
  5292.     debug(F101,"doxconn cmfdb","",x);
  5293.     if (x < 0) {            /* Error */
  5294.         if (x == -9 || x == -2)
  5295.           printf("?No switches match - \"%s\"\n",atmbuf);
  5296.         goto xconnx;        /* or reparse needed */
  5297.     }
  5298.     if (cmresult.fcode != _CMKEY)    /* Break out if not a switch */
  5299.       break;
  5300.     c = cmgbrk();            /* Get break character */
  5301.     getval = (c == ':' || c == '='); /* to see how they ended the switch */
  5302.     if (getval && !(cmresult.kflags & CM_ARG)) {
  5303.         printf("?This switch does not take arguments\n");
  5304.         x = -9;
  5305.         goto xconnx;
  5306.     }
  5307.     if (!getval && (cmgkwflgs() & CM_ARG)) {
  5308.         printf("?This switch requires an argument\n");
  5309.         return(-9);
  5310.     }
  5311.     n = cmresult.nresult;        /* Numeric result = switch value */
  5312.     debug(F101,"doxconn switch","",n);
  5313.  
  5314.     switch (n) {            /* Process the switch */
  5315. #ifdef OS2
  5316.       case CONN_AS:            /* Asynchronous */
  5317.             pv[CONN_AS].ival = 1;
  5318.             pv[CONN_SY].ival = 0;
  5319.             break;
  5320.           case CONN_SY:                 /* Synchronous */
  5321.             pv[CONN_SY].ival = 1;
  5322.             pv[CONN_AS].ival = 0;
  5323.             break;
  5324. #endif /* OS2 */
  5325.       case CONN_NV:            /* Non-verbal */
  5326.         pv[n].ival = 1;
  5327.         break;
  5328. #ifdef XLIMITS
  5329.       case CONN_II:            /* Idle-interval */
  5330.       case CONN_IL:            /* Idle-limit */
  5331.       case CONN_TL:            /* Time-limit */
  5332.         if (!getval) break;
  5333.         if ((x = cmnum("Seconds","0",10,&y,xxstring)) < 0)
  5334.           goto xconnx;
  5335.         pv[n].ival = y;
  5336.         break;
  5337.       case CONN_IS:            /* Idle-string */
  5338. #endif /* XLIMITS */
  5339. #ifdef CK_TRIGGER
  5340.       case CONN_TS:            /* Trigger-string */
  5341. #endif /* CK_TRIGGER */
  5342. #ifdef XLIMORTRIGGER
  5343.         if (!getval) break;
  5344.         if ((x = cmfld("String (enclose in braces if it contains spaces)",
  5345.                "",&s,xxstring)) < 0) {
  5346.         if (x == -3) {
  5347.             printf("?String required\n");
  5348.             x = -9;
  5349.         }
  5350.         goto xconnx;
  5351.         }
  5352.         if (n != CONN_TS)
  5353.           s = brstrip(s);
  5354.         if ((y = strlen(s)) > 0) {
  5355.         if (pv[n].sval) free(pv[n].sval);
  5356.         pv[n].sval = malloc(y+1);
  5357.         if (pv[n].sval) {
  5358.             strcpy(pv[n].sval,s); /* safe */
  5359.             pv[n].ival = 1;
  5360.         }
  5361.         }
  5362.         break;
  5363. #endif /* XLIMORTRIGGER */
  5364.       default:
  5365.         printf("?Unexpected switch value - %d\n",cmresult.nresult);
  5366.         x = -9;
  5367.         goto xconnx;
  5368.     }
  5369.     }
  5370.     debug(F101,"doxconn cmresult.fcode","",cmresult.fcode);
  5371.     if (cmresult.fcode != _CMCFM) {
  5372.     printf("?Unexpected function code: %d\n",cmresult.fcode);
  5373.     x = -9;
  5374.     goto xconnx;
  5375.     }
  5376.  
  5377.     /* Command was confirmed so we can pre-pop command level. */
  5378.     /* This is so CONNECT module won't think we're executing a script */
  5379.     /* if CONNECT was the final command in the script. */
  5380.  
  5381.     if (cmdlvl > 0)
  5382.       prepop();
  5383.  
  5384. #ifdef OS2                /* Make results available globally */
  5385.     if (pv[CONN_IL].ival > -1)        /* Idle limit */
  5386.       tt_idlelimit = pv[CONN_IL].ival;
  5387.     if (pv[CONN_II].ival > -1)        /* Idle limit */
  5388.       tt_idlesnd_tmo = pv[CONN_II].ival;
  5389.     if (pv[CONN_IS].sval)        /* Idle string */
  5390.       if (tt_idlesnd_str = (char *)malloc((int)strlen(pv[CONN_IS].sval)+1))
  5391.     strcpy(tt_idlesnd_str,pv[CONN_IS].sval); /* safe */
  5392.     if (pv[CONN_TL].ival > -1)        /* Session limit */
  5393.       tt_timelimit = pv[CONN_TL].ival;
  5394.     async = (pv[CONN_AS].ival > 0 ||
  5395.              pv[CONN_SY].ival <= 0 && cmdlvl == 0) ? 1 : 0;
  5396. #endif /* OS2 */
  5397.  
  5398. #ifdef CK_TRIGGER
  5399.     if (pv[CONN_TS].sval)        /* Trigger strings */
  5400.       makelist(pv[CONN_TS].sval,tt_trigger,TRIGGERS);
  5401.     for (i = 0; i < TRIGGERS; i++)    /* Trigger match pointers */
  5402.       tt_trmatch[i] = NULL;
  5403.     if (triggerval) {            /* Reset trigger value */
  5404.     free(triggerval);
  5405.     triggerval = NULL;
  5406.     }
  5407. #endif /* CK_TRIGGER */
  5408.  
  5409.     x = doconect((pv[CONN_NV].ival > 0) ? 1 : 0, async);
  5410.     {
  5411.     int xx;
  5412.     debug(F101,"doxconn doconect returns","",x);
  5413.     if ((xx = ttchk()) < 0) dologend();
  5414.     debug(F101,"doxconn ttchk returns","",xx);
  5415.     }
  5416.  
  5417. #ifdef CK_TRIGGER
  5418.     debug(F111,"doxconn doconect triggerval",triggerval,x);
  5419. #endif /* CK_TRIGGER */
  5420.  
  5421.   xconnx:
  5422.     /* Back from CONNECT -- Restore global settings */
  5423.  
  5424.     if (!async)
  5425.       resconn();
  5426.  
  5427.     success = (x > 0) ? 1 : 0;
  5428.     return(x);
  5429. }
  5430. #endif /* NOLOCAL */
  5431.  
  5432. #ifdef ADDCMD
  5433. /* cx == XXADD or XXREMV */
  5434. /* fc == ADD_BIN or ADD_TXT */
  5435. static int
  5436. doadd(cx,fc) int cx, fc; {
  5437. #ifdef PATTERNS
  5438.     char * tmp[FTPATTERNS];
  5439.     char **p = NULL;
  5440.     int i, j, k, n = 0, x = 0, last;
  5441.  
  5442. #endif /* PATTERNS */
  5443.     if (cx != XXADD && cx != XXREMV) {
  5444.     printf("?Unexpected function code: %d\n",cx);
  5445.     return(-9);
  5446.     }
  5447. #ifdef PATTERNS
  5448.     while (n < FTPATTERNS) {        /* Collect new patterns */
  5449.     tmp[n] = NULL;
  5450.     if ((x = cmfld("Pattern","",&s,xxstring)) < 0)
  5451.       break;
  5452.     ckstrncpy(line,s,LINBUFSIZ);
  5453.     s = brstrip(line);
  5454.     makestr(&(tmp[n++]),s);
  5455.     }
  5456.     if (x == -3)
  5457.       x = cmcfm();
  5458.     if (x < 0)
  5459.       goto xdoadd;
  5460.     p = (fc == ADD_BIN) ? binpatterns : txtpatterns; /* Which list */
  5461.     last = 0;
  5462.     for (i = 0; i < FTPATTERNS; i++) { /* Find last one in list */
  5463.     if (!p[i]) {
  5464.         last = i;
  5465.         break;
  5466.     }
  5467.     }
  5468.     if (cx == XXADD) {            /* Adding */
  5469.     if (last + n > FTPATTERNS) {    /* Check if too many */
  5470.         printf("?Too many patterns - %d is the maximum\n", FTPATTERNS);
  5471.         goto xdoadd;
  5472.     }
  5473.         for (i = 0; i < n; i++) {        /* Copy in the new ones. */
  5474.           for (j = 0, x = 0; x == 0 && j < last ; j++ )
  5475.             x = !ckstrcmp(tmp[i],p[j],-1,filecase); /* match */
  5476.           if (x == 0)
  5477.             makestr(&(p[last++]),tmp[i]);
  5478.         }
  5479.         makestr(&(p[last]),NULL);    /* Null-terminate the list */
  5480.         x = 1;
  5481.         goto xdoadd;                    /* Done */
  5482.     } else if (cx == XXREMV) {        /* Remove something(s) */
  5483.     int j, k;
  5484.     if (last == 0)                    /* List is empty */
  5485.       goto xdoadd;                    /* Nothing to remove */
  5486.     for (i = 0; i < n; i++) {            /* i = Patterns they typed */
  5487.         for (j = 0; j < last; j++) {        /* j = Patterns in list */
  5488.         /* Change this to ckstrcmp()... */
  5489.         if (filecase)
  5490.                   x = !ckstrcmp(tmp[i],p[j],-1,filecase); /* match */
  5491.         else
  5492.           x = ckstrcmp(tmp[i],p[j],-1,0); /* Case-independent match */
  5493.         if (x) {                    /* This one matches */
  5494.             makestr(&(p[j]),NULL);      /* Free it */
  5495.             for (k = j; k < last; k++)  /* Move the rest up */
  5496.               p[k] = p[k+1];
  5497.             p[k] = NULL;            /* Erase last one */
  5498.             if (!p[k])
  5499.               break;
  5500.         }
  5501.         }
  5502.     }
  5503.     }
  5504.   xdoadd:                /* Common exit */
  5505.     for (i = 0; i < n; i++)
  5506.       if (tmp[i])
  5507.     free(tmp[i]);
  5508.     return(x);
  5509. #endif /* PATTERNS */
  5510. }
  5511.  
  5512. /* ADD SEND-LIST */
  5513.  
  5514. static int
  5515. addsend(cx) int cx; {
  5516. #ifndef NOMSEND
  5517.     extern struct keytab fttab[];
  5518.     extern int nfttyp;
  5519.     struct filelist * flp;
  5520.     char * fmode = "";
  5521.     int xmode = 0;
  5522.     int xbinary = 0;
  5523. #endif /* NOMSEND */
  5524.  
  5525. #ifdef NOMSEND
  5526.     printf("?Sorry, ADD/REMOVE SEND-LIST not available.\n");
  5527.     return(-9);
  5528. #endif /* NOMSEND */
  5529.     if (cx == XXREMV) {
  5530.     printf("?Sorry, REMOVE SEND-LIST not implemented yet.\n");
  5531.     return(-9);
  5532.     }
  5533. #ifndef NOMSEND
  5534. #ifndef XYZ_INTERNAL
  5535.     if (protocol != PROTO_K) {
  5536.        printf("?Sorry, ADD SEND-LIST does not work with external protocols\n");
  5537.        return(-9);
  5538.     }
  5539. #endif /* XYZ_INTERNAL */
  5540.  
  5541.     x = cmifi("File specification to add","", &s,&y,xxstring);
  5542.     if (x < 0) {
  5543.     if (x == -3) {
  5544.         printf("?A file specification is required\n");
  5545.         return(-9);
  5546.     } else
  5547.       return(x);
  5548.     }
  5549.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  5550.     s = tmpbuf;
  5551.     if (filesinlist == 0)        /* Take care of \v(filespec) */
  5552.       fspec[0] = NUL;
  5553.     zfnqfp(s,LINBUFSIZ,line);
  5554.     s = line;
  5555.     if (((int)strlen(fspec) + (int)strlen(s) + 1) < fspeclen) {
  5556.     strcat(fspec,s);        /* safe */
  5557.     strcat(fspec," ");        /* safe */
  5558.     } else
  5559.       printf("WARNING - \\v(filespec) buffer overflow\n");
  5560.  
  5561.  
  5562.     xbinary = binary;
  5563.     if ((patterns || filepeek)        /* FILE PATTERNS or SCAN is ON */
  5564. #ifdef CK_LABELED
  5565.     && binary != XYFT_L        /* And not if FILE TYPE LABELED */
  5566. #endif /* CK_LABELED */
  5567. #ifdef VMS
  5568.     && binary != XYFT_I        /* or FILE TYPE IMAGE */
  5569. #endif /* VMS */
  5570.     ) {
  5571.     int k, x;
  5572.     x = -1;
  5573.     k = scanfile(line,&x,nscanfile);
  5574.     if (k > 0) xbinary = (k == FT_BIN) ? XYFT_B : XYFT_T;
  5575.     }
  5576.     fmode = gfmode(xbinary,0);
  5577.     if ((x = cmkey(fttab,nfttyp,
  5578.            "type of file transfer", fmode, xxstring)) < 0)
  5579.       return(x);
  5580.     xmode = x;
  5581.  
  5582.     cmarg2 = "";
  5583.     if ((x = cmfld(y ?
  5584.   "\nAs-name template containing replacement variables such as \\v(filename)" :
  5585.   "Name to send it with", "",&s,NULL)) < 0)
  5586.       if (x != -3)
  5587.     return(x);
  5588. #ifndef NOSPL
  5589.     if (y && *s) {
  5590.     char * p = tmpbuf;
  5591.     x = TMPBUFSIZ;
  5592.     zzstring(s,&p,&x);
  5593.     if (!strcmp(tmpbuf,s)) {
  5594.         printf(
  5595.   "?As-name for file group must contain variables such as \\v(filename)\n"
  5596.            );
  5597.         return(-9);
  5598.     }
  5599.     }
  5600. #endif /* NOSPL */
  5601.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  5602.     cmarg2 = tmpbuf;
  5603.  
  5604.     if ((x = cmcfm()) < 0)
  5605.       return(x);
  5606.     flp = (struct filelist *) malloc(sizeof(struct filelist));
  5607.     if (flp) {
  5608.     if (filetail)
  5609.       filetail->fl_next = flp;
  5610.     filetail = flp;
  5611.     if (!filehead)
  5612.       filehead = flp;
  5613.     x = (int) strlen(line);    /* Length of filename */
  5614.     s = (char *) malloc(x + 1);
  5615.     if (s) {
  5616.         strcpy(s,line);        /* safe */
  5617.         flp->fl_name = s;
  5618.         flp->fl_mode = xmode;
  5619.         x = (int) strlen(cmarg2);    /* Length of as-name */
  5620.         if (x < 1) {
  5621.         flp->fl_alias = NULL;
  5622.         } else {
  5623.         s = (char *) malloc(x + 1);
  5624.         if (s) {
  5625.             strcpy(s,cmarg2);    /* safe */
  5626.             flp->fl_alias = s;
  5627.         } else {
  5628.             printf("Sorry, can't allocate space for as-name");
  5629.             return(-9);
  5630.         }
  5631.         }
  5632.         flp->fl_next = NULL;
  5633.         filesinlist++;        /* Count this node */
  5634.         return(success = 1);    /* Finished adding this node */
  5635.     } else {
  5636.         printf("Sorry, can't allocate space for name");
  5637.         return(-9);
  5638.     }
  5639.     } else {
  5640.     printf("Sorry, can't allocate file list node");
  5641.     return(-9);
  5642.     }
  5643. #endif /* NOMSEND */
  5644. }
  5645. #endif /* ADDCMD */
  5646.  
  5647. #ifndef NOHTTP                /* HTTP ops... */
  5648. #ifdef TCPSOCKET
  5649. #define HTTP_GET 0            /* GET */
  5650. #define HTTP_PUT 1            /* PUT */
  5651. #define HTTP_POS 2            /* POST */
  5652. #define HTTP_IDX 3            /* INDEX */
  5653. #define HTTP_HED 4                      /* HEAD */
  5654. #define HTTP_DEL 5                      /* DELETE */
  5655. #define HTTP_CON 6                      /* CONNECT */
  5656. #define HTTP_OPN 7                      /* OPEN */
  5657. #define HTTP_CLS 8                      /* CLOSE */
  5658.  
  5659. static struct keytab httptab[] = {
  5660.     { "close",   HTTP_CLS, 0 },
  5661.     { "connect", HTTP_CON, 0 },
  5662.     { "delete",  HTTP_DEL, 0 },
  5663.     { "get",     HTTP_GET, 0 },
  5664.     { "head",    HTTP_HED, 0 },
  5665.     { "index",   HTTP_IDX, 0 },
  5666.     { "open",    HTTP_OPN, 0 },
  5667.     { "put",     HTTP_PUT, 0 },
  5668.     { "post",    HTTP_POS, 0 }
  5669. };
  5670. static int nhttptab = sizeof(httptab)/sizeof(struct keytab);
  5671.  
  5672. /* HTTP switches */
  5673. #define HT_SW_AG 0            /* /AGENT */
  5674. #define HT_SW_HD 1            /* /HEADER */
  5675. #define HT_SW_US 2            /* /USER */
  5676. #define HT_SW_PW 3            /* /PASSWORD */
  5677. #define HT_SW_AR 4                      /* /ARRAY */
  5678. #define HT_SW_TP 5                      /* /TOSCREEN */
  5679.  
  5680. static struct keytab httpswtab[] = {
  5681.     { "/agent",    HT_SW_AG, CM_ARG },
  5682. #ifndef NOSPL
  5683.     { "/array",    HT_SW_AR, CM_ARG },
  5684. #endif /* NOSPL */
  5685.     { "/header",   HT_SW_HD, CM_ARG },
  5686.     { "/password", HT_SW_PW, CM_ARG },
  5687.     { "/toscreen", HT_SW_TP, 0 },
  5688.     { "/user",     HT_SW_US, CM_ARG },
  5689.     { "", 0, 0 }
  5690. };
  5691. static int nhttpswtab = sizeof(httpswtab)/sizeof(struct keytab) - 1;
  5692.  
  5693. /* HTTP PUT/POST switches */
  5694. #define HT_PP_MT 0            /* /MIME-TYPE */
  5695.  
  5696. static struct keytab httpptab[] = {
  5697.     { "/mime-type", HT_PP_MT, CM_ARG },
  5698.     { "", 0, 0 }
  5699. };
  5700. static int nhttpptab = sizeof(httpptab)/sizeof(struct keytab) - 1;
  5701.  
  5702. #define HTTP_MAXHDR 8
  5703.  
  5704. static int
  5705. xdohttp(action, lfile, rf, dfile, agent, hdr, user, pass, mime, array, type)
  5706.     int action;
  5707.     char *lfile, *rf, *dfile, *agent, *hdr, *user, *pass, *mime, array;
  5708.     int type;
  5709. /* xdohttp */ {
  5710.     int i, rc = 0;
  5711.     char * hdrlist[HTTP_MAXHDR];
  5712.     char rfile[CKMAXPATH+1];
  5713.     extern int httpfd;
  5714.  
  5715.     /* Check for a valid state to execute the command */
  5716.     if (inserver) {
  5717.         printf("?The HTTP command may not be used from the IKS\r\n");
  5718.     } else if (httpfd == -1) {
  5719.         if (http_reopen() < 0)
  5720.       printf("?No connection\n");
  5721.         else
  5722.       rc = 1;
  5723.     } else {
  5724.     rc = 1;
  5725.     }
  5726.  
  5727.     /* If the command is not valid, exit with failure */
  5728.     if (rc == 0)
  5729.         return(success = 0);
  5730.  
  5731.     if (action != HTTP_CON && rf[0] != '/') {
  5732.         rfile[0] = '/';
  5733.         ckstrncpy(&rfile[1],rf,CKMAXPATH);
  5734.     } else {
  5735.         ckstrncpy(rfile,rf,CKMAXPATH);
  5736.     }
  5737.     for (i = 0; i < HTTP_MAXHDR; i++)    /* Initialize header list */
  5738.       hdrlist[i] = NULL;
  5739.     makelist(hdr,hdrlist,HTTP_MAXHDR);    /* Make header list */
  5740.  
  5741. #ifdef BETADEBUG
  5742.     for (i = 0; i < nhttptab; i++)    /* Find action keyword */
  5743.       if (httptab[i].kwval == action)
  5744.     break;
  5745.     if (i == nhttptab) {        /* Shouldn't happen... */
  5746.     printf("?Invalid action - %d\n",action);
  5747.     return(0);            /* Failure */
  5748.     }
  5749.  
  5750.     printf("HTTP action:  %s\n",httptab[i].kwd);
  5751.     printf(" Agent:       %s\n",agent ? agent : "(null)");
  5752.  
  5753.     if (hdrlist[1]) {
  5754.     printf(" Header list: 1. %s\n",hdrlist[0]);
  5755.     for (i = 1; i < HTTP_MAXHDR && hdrlist[i]; i++)
  5756.       printf("%15d. %s\n",i+1,hdrlist[i]);
  5757.     } else
  5758.       printf(" Header:      %s\n",hdrlist[0] ? hdrlist[0] : "(null)");
  5759.  
  5760.     printf(" User:        %s\n",user ? user : "(null)");
  5761. #ifdef COMMENT
  5762.     printf(" Password:    %s\n",pass ? pass : "(null)");
  5763. #endif /* COMMENT */
  5764.  
  5765. #ifndef NOSPL
  5766.     if (array)
  5767.       printf(" Array:       \\%%%c[]\n", array);
  5768.     else
  5769.       printf(" Array:       (none)\n");
  5770. #endif /* NOSPL */
  5771.  
  5772.     if (action == HTTP_PUT || action == HTTP_POS)
  5773.       printf(" Mime-type:   %s\n",mime ? mime : "(null)");
  5774.  
  5775.     printf(" Local file:  %s\n",lfile ? lfile : "(null)");
  5776.     printf(" Remote file: %s\n",rfile ? rfile : "(null)");
  5777.     printf(" Destination file: %s\n",dfile ? dfile : "(null)");
  5778. #endif /* BETADEBUG */
  5779.  
  5780.     /* The http_xxxx() functions return 0 on success, -1 on failure */
  5781.     switch (action) {
  5782.       case HTTP_CON: {
  5783.       extern int ttyfd;
  5784.       rc = http_connect(httpfd,agent,hdrlist,user,pass,array,rfile);
  5785.       break;
  5786.       }
  5787.       case HTTP_DEL:
  5788.         rc = http_delete(agent,hdrlist,user,pass,array,rfile);
  5789.         break;
  5790.       case HTTP_GET:
  5791.         rc = http_get(agent,hdrlist,user,pass,array,lfile,rfile,type);
  5792.         break;
  5793.       case HTTP_HED:
  5794.         rc = http_head(agent,hdrlist,user,pass,array,lfile,rfile,type);
  5795.         break;
  5796.       case HTTP_PUT:
  5797.         rc = http_put(agent,hdrlist,mime,user,pass,array,lfile,rfile,dfile,
  5798.               type);
  5799.         break;
  5800.       case HTTP_POS:
  5801.         rc = http_post(agent,hdrlist,mime,user,pass,array,lfile,rfile,dfile,
  5802.                type);
  5803.         break;
  5804.       case HTTP_IDX:
  5805.         rc = http_index(agent,hdrlist,user,pass,array,lfile,rfile,type);
  5806.         break;
  5807.       default:
  5808.         rc = -1;
  5809.     }
  5810.     return(rc == 0 ? 1 : 0);            /* Success is set by caller */
  5811. }
  5812. #endif /* TCPSOCKET */
  5813. #endif /* NOHTTP */
  5814.  
  5815. #ifndef NOSPL                /* ARRAY ops... */
  5816. static struct keytab arraytab[] = {
  5817.     { "clear",     ARR_CLR, 0 },
  5818.     { "copy",      ARR_CPY, 0 },
  5819.     { "dcl",       ARR_DCL, CM_INV },
  5820.     { "declare",   ARR_DCL, 0 },
  5821.     { "destroy",   ARR_DST, CM_INV },
  5822.     { "equate",    ARR_EQU, CM_INV },
  5823.     { "link",      ARR_EQU, 0 },
  5824.     { "resize",    ARR_RSZ, 0 },
  5825.     { "set",       ARR_SET, 0 },
  5826. #ifndef NOSHOW
  5827.     { "show",      ARR_SHO, 0 },
  5828. #endif /* NOSHOW */
  5829.     { "sort",      ARR_SRT, 0 },
  5830.     { "undeclare", ARR_DST, 0 },
  5831.     { "", 0, 0 }
  5832. };
  5833. static int narraytab = sizeof(arraytab)/sizeof(struct keytab) - 1;
  5834.  
  5835. #ifdef CKLEARN
  5836. static struct keytab learnswi[] = {
  5837.     { "/close",    2, 0 },
  5838.     { "/off",      0, 0 },
  5839.     { "/on",       1, 0 }
  5840. };
  5841. #endif /* CKLEARN */
  5842.  
  5843. int
  5844. arrayitoa(x) int x; {            /* Array index to array letter */
  5845.     if (x == 1)
  5846.       return(64);
  5847.     else if (x < 0 || x > (122 - ARRAYBASE))
  5848.       return(-1);
  5849.     else
  5850.       return(x + ARRAYBASE);
  5851. }
  5852.  
  5853. int
  5854. arrayatoi(c) int c; {            /* Array letter to array index */
  5855.     if (c == 64)
  5856.       c = 96;
  5857.     if (c > 63 && c < 91)
  5858.       c += 32;
  5859.     if (c < ARRAYBASE || c > 122)
  5860.       return(-1);
  5861.     return(c - ARRAYBASE);
  5862. }
  5863.  
  5864. static int                /* Declare an array */
  5865. dodcl(cx) int cx; {
  5866.     int i, n, v, lo, hi, rc = 0;
  5867.     int isdynamic = 0;
  5868.     char tmpbuf[64];
  5869.     char ** p = NULL;
  5870.     char tmp[64];            /* Local temporary string buffer */
  5871.     if ((y = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
  5872.     if (y == -3) {
  5873.         printf("?Array name required\n");
  5874.         return(-9);
  5875.     } else return(y);
  5876.     }
  5877.     ckstrncpy(line,s,LINBUFSIZ);
  5878.     s = line;
  5879.     x = arraybounds(s,&lo,&hi);        /* Check syntax and get bounds */
  5880.     debug(F111,"XXX dodcl arraybounds",s,x);
  5881.     if (x < 0) {            /* Error - Maybe it's a variable */
  5882.     char * p;            /* whose value is an array name */
  5883.     int n;
  5884.     p = tmpbuf;
  5885.     n = 63;
  5886.     p[0] = NUL;
  5887.     if (s[0] == CMDQ && s[1] == '&')
  5888.       s++;
  5889.     if (zzstring(s,&p,&n) > -1) {
  5890.         s = tmpbuf;
  5891.         x = arraybounds(s,&lo,&hi);
  5892.         debug(F111,"XXX dodcl arraybounds 2",s,x);
  5893.     }
  5894.     if (x < 0) {
  5895.         printf("?Bad array name - \"%s\"\n",s);
  5896.         return(-9);
  5897.     }
  5898.     }
  5899.     debug(F101,"XXX dodcl lo","",lo);
  5900.     debug(F101,"XXX dodcl hi","",hi);
  5901.  
  5902.     if (lo < 0 && hi < 0) {        /* Have good array name and bounds */
  5903.     isdynamic = 1;
  5904.     n = CMDBL / 5;
  5905.     } else if (hi > -1) {
  5906.     printf("?Segment notation not allowed in array declarations\n");
  5907.     return(-9);
  5908.     } else
  5909.       n = lo;
  5910.     x = arrayitoa(x);
  5911.     if (cx == XXUNDCL) {
  5912.     n = 0;
  5913.     v = 0;
  5914.     if ((y = cmcfm()) < 0)
  5915.       return(y);
  5916.     } else {
  5917.     p = (char **)malloc(sizeof(char **)*(n+1));
  5918.     if (!p) {
  5919.         printf("?Memory allocation error\n");
  5920.         return(-9);
  5921.     }
  5922.     v = 0;                /* Highest initialized member */
  5923.     p[0] = NULL;            /* Element 0 */
  5924.     while (n > 0 && v < n) {    /* Parse initializers */
  5925.         p[v+1] = NULL;
  5926.         ckmakxmsg(tmp,
  5927.               64,
  5928.               "Initial value for \\&",
  5929.               ckctoa((char)x),
  5930.               "[",
  5931.               ckitoa(v+1),
  5932.               "]",
  5933.               NULL,NULL,NULL,NULL,NULL,NULL,NULL
  5934.               );
  5935.         if ((rc = cmfld((char *)tmp,"",&s,xxstring)) < 0) { /* Get field */
  5936.         if (rc == -3)        /* If answer is empty, we're done */
  5937.           break;
  5938.         else            /* Parse error, free temp pointers */
  5939.           goto dclx;
  5940.         }
  5941.         rc = 1;
  5942.         if (v == 0 && !strcmp(s,"=")) /* Skip the = sign. */
  5943.           continue;
  5944.         s = brstrip(s);        /* Strip any braces */
  5945.         makestr(&(p[++v]),s);
  5946.     }
  5947.     if ((y = cmtxt("Carriage return to confirm","",&s,NULL)) < 0)
  5948.       return(y);
  5949.     if (isdynamic)
  5950.       n = v;
  5951.     }
  5952.     if (dclarray((char)x,n) < 0) {    /* Declare the array */
  5953.     printf("?Declare failed\n");
  5954.     goto dclx;
  5955.     }
  5956.     for (i = 1; i <= v; i++) {        /* Add any initial values */
  5957.     tmp[0] = '&';
  5958.     ckmakmsg(&tmp[1],63,ckctoa((char)x),"[",ckitoa(i),"]");
  5959.     if (addmac(tmp,p[i]) < 0) {
  5960.         printf("Array initialization error: %s %s\n",tmp,p[i]);
  5961.         rc = -9;
  5962.         goto dclx;
  5963.     }
  5964.     }
  5965.   dclx:
  5966.     if (p) {
  5967.     for (i = 1; i <= v; i++)
  5968.       if (p[i]) free(p[i]);
  5969.     free((char *)p);
  5970.     }
  5971.     debug(F101,"DCL rc","",rc);
  5972.     return(success = rc);
  5973. }
  5974.  
  5975. static int
  5976. rszarray() {
  5977.     int i, x, y, n, lo, hi, islink = -1;
  5978.     char c, * s, ** ap = NULL;
  5979.     if ((x = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
  5980.     if (x == -3) {
  5981.         printf("?Array name required\n");
  5982.         return(-9);
  5983.     } else return(x);
  5984.     }
  5985.     ckstrncpy(line,s,LINBUFSIZ);    /* Make safe copy of name */
  5986.     s = line;
  5987.     x = arraybounds(s,&lo,&hi);
  5988.     if (x < 0) {            /* Parse the name, get index */
  5989.     printf("?Bad array reference - \"%s\"\n", s);
  5990.     return(-9);
  5991.     }
  5992.     if (lo < 0 && hi < 0) {
  5993.     y = cmnum("New size","",10,&lo,xxstring);
  5994.     if (y < 0) {
  5995.         if (y == -3)
  5996.           printf("?New size required\n");
  5997.         return(y);
  5998.     }
  5999.     }
  6000.     if ((y = cmcfm()) < 0)
  6001.       return(y);
  6002.     if (a_link[x] > -1) {        /* Link? */
  6003.     islink = x;            /* Yes follow it */
  6004.     x = a_link[x];            /* and remember */
  6005.     }
  6006.     if (!a_ptr[x]) {
  6007.     printf("?Array not declared - \"%s\"\n", s);
  6008.     return(-9);
  6009.     }
  6010.     if (lo < 0) {
  6011.     printf("?New size required\n");
  6012.     return(-9);
  6013.     }
  6014.     if (hi > -1) {
  6015.     printf("?Array segments not allowed for this operation\n");
  6016.     return(-9);
  6017.     }
  6018.     c = arrayitoa(x);            /* Get array letter */
  6019.     if (c == '@') {            /* Argument vector array off limits */
  6020.     printf("?Sorry, \\&@[] is read-only\n");
  6021.     return(-9);
  6022.     }
  6023.     if (lo == 0) {            /* If new size is 0... */
  6024.     dclarray(c,0);            /* Undeclare the array */
  6025.     return(success = 1);
  6026.     }
  6027.     n = a_dim[x];            /* Current size */
  6028.     ap = (char **) malloc((lo+1) * sizeof(char *)); /* New array */
  6029.     y = (n < lo) ? n : lo;
  6030.     for (i = 0; i <= y; i++)        /* Copy the part that fits */
  6031.       ap[i] = a_ptr[x][i];
  6032.     if (n < lo) {            /* If original array smaller */
  6033.     for (; i <= lo; i++)        /* initialize extra elements in */
  6034.       ap[i] = NULL;            /* new array to NULL. */
  6035.     } else if (n > lo) {        /* If new array smaller */
  6036.     for (; i <= lo; i++)        /* deallocate leftover elements */
  6037.       makestr(&(a_ptr[x][i]),NULL);    /* from original array. */
  6038.     }
  6039.     free((char *)a_ptr[x]);        /* Free original array list */
  6040.     a_ptr[x] = ap;            /* Replace with new one */
  6041.     a_dim[x] = lo;            /* Record the new dimension */
  6042.     if (islink > -1) {            /* Was this a link? */
  6043.     a_ptr[islink] = ap;        /* If so point to the resized array */
  6044.     a_dim[islink] = lo;
  6045.     } else {                /* If not are there links to here? */
  6046.     for (i = 0; i < (int) 'z' - ARRAYBASE; i++) { /* Any linked arrays? */
  6047.         if (i != x && a_link[i] == x) {     /* Find and update them */
  6048.         a_ptr[i] = ap;
  6049.         a_dim[i] = lo;
  6050.         }
  6051.     }
  6052.     }
  6053.     return(success = 1);
  6054. }
  6055.  
  6056. static int
  6057. copyarray() {
  6058.     int i, j, x1, lo1, hi1, x2, lo2, hi2, whole = 0;
  6059.     char c1, c2, * a1, * a2;
  6060.     if ((y = cmfld("Name of source array","",&s,NULL)) < 0)
  6061.       return(y);
  6062.     ckstrncpy(line,s,LINBUFSIZ);
  6063.     a1 = line;
  6064.     if ((x1 = arraybounds(a1,&lo1,&hi1)) < 0) {
  6065.     printf("?Bad array reference - \"%s\"\n", a1);
  6066.     return(-9);
  6067.     } else if (!a_ptr[x1]) {
  6068.     printf("?Array not declared - \"%s\"\n", a1);
  6069.     return(-9);
  6070.     }
  6071.     c1 = arrayitoa(x1);
  6072.  
  6073.     if ((y = cmfld("Name of destination array","",&s,NULL)) < 0)
  6074.       return(y);
  6075.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  6076.     a2 = tmpbuf;
  6077.     if ((x2 = arraybounds(a2,&lo2,&hi2)) < 0) {
  6078.     printf("?Bad array reference - \"%s\"\n", a2);
  6079.     return(-9);
  6080.     }
  6081.     c2 = arrayitoa(x2);
  6082.  
  6083.     if ((x = cmcfm()) < 0)
  6084.       return(x);
  6085.  
  6086.     if (c2 == '@') {            /* Argument vector array off limits */
  6087.     printf("?Sorry, \\&@[] is read-only\n");
  6088.     return(-9);
  6089.     }
  6090.     if (lo1 < 0 && lo2 < 0 && hi1 < 0 && hi2 < 0) /* Special case for */
  6091.       whole = 1;                      /* whole array... */
  6092.  
  6093.     if (lo1 < 0) lo1 = whole ? 0 : 1;    /* Supply lower bound of source */
  6094.     if (hi1 < 0) hi1 = a_dim[x1];    /* Supply upper bound of source */
  6095.     if (lo2 < 0) lo2 = whole ? 0 : 1;    /* Lower bound of target */
  6096.     if (hi2 < 0) hi2 = lo2 + hi1 - lo1;    /* Upper bound of target */
  6097.     if (a_ptr[x2]) {            /* Target array is already declared? */
  6098.     if (hi2 > a_dim[x2])        /* If upper bound out of range */
  6099.       hi2 = a_dim[x2];        /* shrink to fit */
  6100.     } else {                /* Otherwise... */
  6101.     x2 = dclarray(c2, hi2);        /* declare the target array */
  6102.     }
  6103.     for (i = lo1, j = lo2; i <= hi1 && j <= hi2; i++,j++) { /* Copy */
  6104.     makestr(&(a_ptr[x2][j]),a_ptr[x1][i]);
  6105.     }
  6106.     return(success = 1);
  6107. }
  6108.  
  6109. static int                /* Undeclare an array */
  6110. unarray() {
  6111.     int x, y, n, rc = 0;
  6112.     char c, * s;
  6113.  
  6114.     if ((y = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
  6115.     if (y == -3) {
  6116.         printf("?Array name required\n");
  6117.         return(-9);
  6118.     } else return(y);
  6119.     }
  6120.     ckstrncpy(line,s,LINBUFSIZ);    /* Make safe copy of name */
  6121.     s = line;
  6122.     if ((y = cmcfm()) < 0)
  6123.       return(y);
  6124.     if ((x = arraybounds(s,&y,&n)) < 0) { /* Parse the name, get index */
  6125.     printf("?Bad array reference - \"%s\"\n", s);
  6126.     return(-9);
  6127.     }
  6128.     if (y > 0 || n > 0) {
  6129.     printf("?Partial arrays can not be destroyed\n");
  6130.     return(-9);
  6131.     }
  6132.     c = arrayitoa(x);            /* Get array letter */
  6133.     if (a_ptr[x]) {            /* If array is declared */
  6134.     if (c == '@') {            /* Argument vector array off limits */
  6135.         printf("?Sorry, \\&@[] is read-only\n");
  6136.         return(-9);
  6137.     }
  6138.     rc = dclarray(c,0);        /* Undeclare the array */
  6139.     } else                /* It wasn't declared */
  6140.       rc = 1;
  6141.     if (rc > -1) {            /* Set return code and success */
  6142.     success = 1;
  6143.     rc = 1;
  6144.     } else {
  6145.     success = 0;
  6146.     printf("?Failed - destroy \"\\&%c[]\"\n", c);
  6147.     rc = -9;
  6148.     }
  6149.     return(rc);
  6150. }
  6151.  
  6152. static int
  6153. clrarray(cx) int cx; {
  6154.     int i, x, lo, hi;
  6155.     char c, * s, * val = NULL;
  6156.  
  6157.     if ((x = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
  6158.     if (x == -3) {
  6159.         printf("?Array name required\n");
  6160.         return(-9);
  6161.     } else return(x);
  6162.     }
  6163.     ckstrncpy(line,s,LINBUFSIZ);    /* Make safe copy of name */
  6164.     s = line;
  6165.     if (cx == ARR_SET) {        /* SET */
  6166.     if ((x = cmtxt("Value","",&val,xxstring)) < 0)
  6167.       return(x);
  6168.     ckstrncpy(tmpbuf,val,TMPBUFSIZ); /* Value to set */
  6169.     val = tmpbuf;
  6170.     if (!*val) val = NULL;
  6171.     } else if ((x = cmcfm()) < 0)    /* CLEAR */
  6172.       return(x);
  6173.  
  6174.     if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Parse the name */
  6175.     printf("?Bad array reference - \"%s\"\n", s);
  6176.     return(-9);
  6177.     }
  6178.     c = arrayitoa(x);            /* Get array letter */
  6179.     if (!a_ptr[x]) {            /* If array is declared */
  6180.     printf("?Array %s is not declared\n", s);
  6181.     return(-9);
  6182.     } else if (c == '@') {        /* Argument vector array off limits */
  6183.     printf("?Sorry, \\&@[] is read-only\n");
  6184.     return(-9);
  6185.     }
  6186.     if (lo < 0) lo = 0;
  6187.     if (hi < 0) hi = a_dim[x];
  6188.     for (i = lo; i <= hi; i++)        /* Clear/Set selected range */
  6189.       makestr(&(a_ptr[x][i]),val);
  6190.  
  6191.     return(success = 1);
  6192. }
  6193.  
  6194. extern char **aa_ptr[CMDSTKL][28];
  6195. extern int aa_dim[CMDSTKL][28];
  6196.  
  6197. static int                /* Create symbolic link to an array */
  6198. linkarray() {
  6199.     int i = 0, x, y, lo, hi, flag = 0;
  6200.     char c, * s, * p;
  6201.  
  6202.     if ((x = cmfld("Array name not currently in use","",&s,NULL)) < 0) {
  6203.     if (x == -3) {
  6204.         printf("?Array name required\n");
  6205.         return(-9);
  6206.     } else return(x);
  6207.     }
  6208.     ckstrncpy(line,s,LINBUFSIZ);    /* Make safe copy of link name */
  6209.     s = line;
  6210.     if ((x = cmfld("Name of existing array","",&p,xxstring)) < 0) {
  6211.     if (x == -3) {
  6212.         printf("?Array name required\n");
  6213.         return(-9);
  6214.     } else return(x);
  6215.     }
  6216.     ckstrncpy(tmpbuf,p,TMPBUFSIZ);    /* Make safe copy of array name */
  6217.     p = tmpbuf;
  6218.     if ((x = cmcfm()) < 0)
  6219.       return(x);
  6220.  
  6221.     if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Parse the link name */
  6222.     printf("?Bad array reference - \"%s\"\n", s);
  6223.     return(-9);
  6224.     }
  6225.     if (a_ptr[x]) {            /* Must not already exist */
  6226.     c = arrayitoa(x);
  6227.     printf("?Array already exists: \\&%c[]\n", c);
  6228.     return(-9);
  6229.     }
  6230.     if (lo > -1 || hi > -1) {
  6231.     printf("?Sorry, whole arrays only: %s\n",s);
  6232.     return(-9);
  6233.     }
  6234.     if ((y = arraybounds(p,&lo,&hi)) < 0) { /* Parse the array name */
  6235.     printf("?Bad array reference - \"%s\"\n", s);
  6236.     return(-9);
  6237.     }
  6238.     if (lo > -1 || hi > -1) {
  6239.     printf("?Sorry, whole arrays only: %s\n",p);
  6240.     return(-9);
  6241.     }
  6242.     if (x == y) {
  6243.     for (i = cmdlvl; i >= 0; i--)
  6244.       if (aa_ptr[i][x]) {
  6245.           flag++;
  6246.           break;
  6247.       }
  6248.     }
  6249.     if (flag) {
  6250.     a_ptr[x] = aa_ptr[i][y];    /* Link to saved copy */
  6251.     a_dim[x] = aa_dim[i][y];
  6252.     } else {                /* Otherwise... */
  6253.     c = arrayitoa(y);        /* Check if it's declared */
  6254.     if (!a_ptr[y]) {
  6255.         printf("?Array is not declared: \\&%c[]\n", c);
  6256.         return(-9);
  6257.     }
  6258.     if (a_link[y] > -1) {        /* And if it's a link itself */
  6259.         printf("?Links to links not allowed: \\&%c[]\n", c);
  6260.         return(-9);
  6261.     }
  6262.     a_ptr[x] = a_ptr[y];        /* All OK, make the link */
  6263.     a_dim[x] = a_dim[y];
  6264.     }
  6265.     a_link[x] = y;
  6266.     return(success = 1);
  6267. }
  6268. #endif /* NOSPL */
  6269.  
  6270. #ifndef NOCSETS
  6271. static char * dcsetname = NULL;
  6272.  
  6273. /* Get Display Character-Set Name */
  6274.  
  6275. char *
  6276. getdcset() {
  6277.     char * s;
  6278.     int y;
  6279. #ifdef PCFONTS
  6280.     extern int tt_font, ntermfont;
  6281.     extern struct keytab term_font[];
  6282. #endif /* PCFONTS */
  6283.  
  6284.     s = "";
  6285. #ifdef OS2
  6286.     y = os2getcp();            /* Default is current code page */
  6287.     switch (y) {
  6288.       case 437: s = "cp437"; break;
  6289.       case 850: s = "cp850"; break;
  6290.       case 852: s = "cp852"; break;
  6291.       case 857: s = "cp857"; break;
  6292.       case 858: s = "cp858"; break;
  6293.       case 862: s = "cp862"; break;
  6294.       case 866: s = "cp866"; break;
  6295.       case 869: s = "cp869"; break;
  6296.       case 1250: s = "cp1250"; break;
  6297.       case 1251: s = "cp1251"; break;
  6298.       case 1252: s = "cp1252"; break;
  6299.       case 1253: s = "cp1253"; break;
  6300.       case 1254: s = "cp1254"; break;
  6301.       case 1255: s = "cp1255"; break;
  6302.       case 1256: s = "cp1256"; break;
  6303.       case 1257: s = "cp1257"; break;
  6304.       case 1258: s = "cp1258"; break;
  6305.     }
  6306. #ifdef PCFONTS
  6307. /*
  6308.    If the user has loaded a font with SET TERMINAL FONT then we want
  6309.    to change the default code page to the font that was loaded.
  6310. */
  6311.     if (tt_font != TTF_ROM) {
  6312.     for (y = 0; y < ntermfont; y++ ) {
  6313.         if (term_font[y].kwval == tt_font) {
  6314.         s = term_font[y].kwd;
  6315.         break;
  6316.         }
  6317.     }
  6318.     }
  6319. #endif /* PCFONTS */
  6320. #else /* OS2 */
  6321. #ifdef COMMENT
  6322.     /* Hack not needed as of C-Kermit 7.1 */
  6323.     if (fcharset == FC_1LATIN) {
  6324.     s = "latin1-iso";        /* Hack to avoid reporting "cp1252" */
  6325.     } else {                /* Report current file character set */
  6326. #endif /* COMMENT */
  6327.     for (y = 0; y <= nfilc; y++)
  6328.       if (fcstab[y].kwval == fcharset) {
  6329.           s = fcstab[y].kwd;
  6330.           break;
  6331.       }
  6332. #ifdef COMMENT
  6333.     }
  6334. #endif /* COMMENT */
  6335. #endif /* OS2 */
  6336.     makestr(&dcsetname,s);        /* Return stable pointer */
  6337.     return((char *)dcsetname);
  6338. }
  6339. #endif /* NOCSETS */
  6340.  
  6341. #ifndef NOFRILLS
  6342. static int
  6343. doclear() {
  6344.     if ((x = cmkey(clrtab,nclear,"item to clear",
  6345. #ifdef NOSPL
  6346.            "device-buffer"
  6347. #else
  6348.            "device-and-input"
  6349. #endif /* NOSPL */
  6350.            ,xxstring)) < 0) return(x);
  6351. #ifndef NOSPL
  6352. #ifdef OS2
  6353.     if (x == CLR_CMD || x == CLR_TRM) {
  6354.     if ((z = cmkey(clrcmdtab,nclrcmd,"how much screen to clear\n",
  6355.                "all",xxstring)) < 0)
  6356.       return(z);
  6357.     }
  6358. #endif /* OS2 */
  6359. #endif /* NOSPL */
  6360.     if ((y = cmcfm()) < 0)
  6361.       return(y);
  6362.  
  6363.     /* Clear device input buffer if requested */
  6364.     y = (x & CLR_DEV) ? ttflui() : 0;
  6365.  
  6366.     if (x & CLR_SCR)            /* CLEAR SCREEN */
  6367.       y = ck_cls();            /* (= SCREEN CLEAR = CLS) */
  6368.  
  6369.     if (x & CLR_KBD) {            /* CLEAR KEYBOARD */
  6370.     int n;
  6371.     n = conchk();
  6372.     y = 0;
  6373.     while (n-- > 0 && (y = coninc(0) > -1))
  6374.       ;
  6375.     y = (y > -1) ? 0 : -1;
  6376.     }
  6377.  
  6378. #ifndef NOSPL
  6379.     /* Clear INPUT command buffer if requested */
  6380.     if (x & CLR_INP) {
  6381.     for (z = 0; z < inbufsize; z++)
  6382.       inpbuf[z] = NUL;
  6383.     inpbp = inpbuf;
  6384.     y = 0;
  6385.     }
  6386. #ifdef CK_APC
  6387.     if (x & CLR_APC) {
  6388.     debug(F101,"Executing CLEAR APC","",apcactive);
  6389.     apcactive = 0;
  6390.     y = 0;
  6391.     }
  6392. #endif /* CK_APC */
  6393.     if (x & CLR_ALR) {
  6394.     setalarm(0L);
  6395.     y = 0;
  6396.     }
  6397. #endif /* NOSPL */
  6398.  
  6399. #ifdef PATTERNS
  6400.     if (x & (CLR_TXT|CLR_BIN)) {
  6401.     int i;
  6402.     for (i = 0; i < FTPATTERNS; i++) {
  6403.         if (x & CLR_TXT)
  6404.           makestr(&txtpatterns[i],NULL);
  6405.         if (x & CLR_BIN)
  6406.           makestr(&binpatterns[i],NULL);
  6407.     }
  6408.     y = 0;
  6409.     }
  6410. #endif /* PATTERNS */
  6411.  
  6412. #ifndef NODIAL
  6413.     if (x & CLR_DIA) {
  6414.     dialsta = DIA_UNK;
  6415.     y = 0;
  6416.     }
  6417. #endif /* NODIAL */
  6418.  
  6419. #ifndef NOMSEND
  6420.     if (x & CLR_SFL) {            /* CLEAR SEND-LIST */
  6421.     if (filehead) {
  6422.         struct filelist * flp, * next;
  6423.         flp = filehead;
  6424.         while (flp) {
  6425.         if (flp->fl_name)
  6426.           free(flp->fl_name);
  6427.         if (flp->fl_alias)
  6428.           free(flp->fl_alias);
  6429.         next = flp->fl_next;
  6430.         free((char *)flp);
  6431.         flp = next;
  6432.         }
  6433.     }
  6434.     filesinlist = 0;
  6435.     filehead = NULL;
  6436.     filetail = NULL;
  6437.     addlist = 0;
  6438.     y = 0;
  6439.     }
  6440. #endif /* NOMSEND */
  6441.  
  6442. #ifdef OS2
  6443. #ifndef NOLOCAL
  6444.     switch (x) {
  6445.       case CLR_SCL:
  6446.     clearscrollback(VTERM);
  6447.     break;
  6448.       case CLR_CMD:
  6449.     switch ( z ) {
  6450.       case CLR_C_ALL:
  6451.         clear();
  6452.         break;
  6453.       case CLR_C_BOS:
  6454.         clrboscr_escape(VCMD,SP);
  6455.         break;
  6456.       case CLR_C_BOL:
  6457.         clrbol_escape(VCMD,SP);
  6458.         break;
  6459.       case CLR_C_EOL:
  6460.         clrtoeoln(VCMD,SP);
  6461.         break;
  6462.       case CLR_C_EOS:
  6463.         clreoscr_escape(VCMD,SP);
  6464.         break;
  6465.       case CLR_C_LIN:
  6466.         clrline_escape(VCMD,SP);
  6467.         break;
  6468.       case CLR_C_SCR:
  6469.         clearscrollback(VCMD);
  6470.         break;
  6471.     default:
  6472.         printf("Not implemented yet, sorry.\n");
  6473.         break;
  6474.     }
  6475.     break;
  6476.  
  6477. #ifndef NOTERM
  6478.       case CLR_TRM:
  6479.      switch ( z ) {
  6480.       case CLR_C_ALL:
  6481.          if (VscrnGetBufferSize(VTERM) > 0 ) {
  6482.          VscrnScroll(VTERM, UPWARD, 0,
  6483.                  VscrnGetHeight(VTERM)-(tt_status[VTERM]?2:1),
  6484.                  VscrnGetHeight(VTERM) -
  6485.                  (tt_status[VTERM]?1:0), TRUE, SP
  6486.                  );
  6487.          cleartermscreen(VTERM);
  6488.          }
  6489.          break;
  6490.       case CLR_C_BOS:
  6491.         clrboscr_escape(VTERM,SP);
  6492.         break;
  6493.       case CLR_C_BOL:
  6494.         clrbol_escape(VTERM,SP);
  6495.         break;
  6496.       case CLR_C_EOL:
  6497.         clrtoeoln(VTERM,SP);
  6498.         break;
  6499.       case CLR_C_EOS:
  6500.         clreoscr_escape(VTERM,SP);
  6501.         break;
  6502.       case CLR_C_LIN:
  6503.         clrline_escape(VTERM,SP);
  6504.         break;
  6505.      case CLR_C_SCR:
  6506.          clearscrollback(VTERM);
  6507.          break;
  6508.      default:
  6509.          printf("Not implemented yet, sorry.\n");
  6510.          break;
  6511.     }
  6512.     break;
  6513. #endif /* NOTERM */
  6514.     }
  6515.     y = 0;
  6516. #endif /* NOLOCAL */
  6517. #endif /* OS2 */
  6518.     return(success = (y == 0));
  6519. }
  6520. #endif /* NOFRILLS */
  6521.  
  6522. #ifndef NOSPL
  6523. static int
  6524. doeval(cx) int cx; {
  6525.     char *p;
  6526.     char vnambuf[VNAML], * vnp = NULL;    /* These must be on the stack */
  6527.     if (!oldeval) {
  6528.     if ((y = cmfld("Variable name","",&s,
  6529.                ((cx == XX_EVAL) ? xxstring : NULL))) < 0) {
  6530.         if (y == -3) {
  6531.         printf("?Variable name required\n");
  6532.         return(-9);
  6533.         } else return(y);
  6534.     }
  6535.     ckstrncpy(vnambuf,s,VNAML);    /* Make a copy. */
  6536.     vnp = vnambuf;
  6537.     if (vnambuf[0] == CMDQ &&
  6538.         (vnambuf[1] == '%' || vnambuf[1] == '&'))
  6539.       vnp++;
  6540.     y = 0;
  6541.     if (*vnp == '%' || *vnp == '&') {
  6542.         if ((y = parsevar(vnp,&x,&z)) < 0)
  6543.           return(y);
  6544.     }
  6545.     }
  6546.     if ((x = cmtxt("Integer arithmetic expression","",&s,xxstring)) < 0)
  6547.       return(x);
  6548.     p = evala(s);
  6549.     if (!p) p = "";
  6550.     if (oldeval && *p)
  6551.       printf("%s\n", p);
  6552.     ckstrncpy(evalbuf,p,32);
  6553.     if (!oldeval)
  6554.       return(success = addmac(vnambuf,p));
  6555.     else
  6556.       return(success = *p ? 1 : 0);
  6557. }
  6558. #endif /* NOSPL */
  6559.  
  6560. #ifdef TNCODE
  6561. static int
  6562. dotelopt() {
  6563.     if ((x = cmkey(telcmd, ntelcmd, "TELNET command", "", xxstring)) < 0 )
  6564.       return(x);
  6565.     switch (x) {
  6566.       case WILL:
  6567.       case WONT:
  6568.       case DO:
  6569.       case DONT:
  6570.     if ((y = cmkey(tnopts,ntnopts,"TELNET option","",xxstring)) < 0)
  6571.       return(y);
  6572.     if ((z = cmcfm()) < 0) return(z);
  6573.  
  6574.     switch (x) {
  6575.       case WILL:
  6576.         if (TELOPT_UNANSWERED_WILL(y))
  6577.           return(success = 0);
  6578.         break;
  6579.       case WONT:
  6580.         if (TELOPT_UNANSWERED_WONT(y))
  6581.           return(success = 0);
  6582.         break;
  6583.       case DO:
  6584.         if (TELOPT_UNANSWERED_DO(y))
  6585.           return(success = 0);
  6586.         break;
  6587.       case DONT:
  6588.         if (TELOPT_UNANSWERED_DONT(y))
  6589.           return(success = 0);
  6590.         break;
  6591.     }
  6592.     if (local) {
  6593.         success = ((tn_sopt(x,y) > -1) ? 1 : 0);
  6594.     } else {
  6595.         printf("ff%02x%02x\n",x,y);
  6596.         success = 1;
  6597.     }
  6598.     if (success) {
  6599.         switch (x) {
  6600.           case WILL:
  6601.         TELOPT_UNANSWERED_WILL(y) = 1;
  6602.         break;
  6603.           case WONT:
  6604.         if ( TELOPT_ME(y) )
  6605.           TELOPT_UNANSWERED_WONT(y) = 1;
  6606.         break;
  6607.           case DO:
  6608.         TELOPT_UNANSWERED_DO(y) = 1;
  6609.         break;
  6610.           case DONT:
  6611.         if ( TELOPT_ME(y) )
  6612.           TELOPT_UNANSWERED_DONT(y) = 1;
  6613.         break;
  6614.         }
  6615.         if (tn_wait("XXTELOP") < 0) {
  6616.         tn_push();
  6617.         success = 0;
  6618.         }
  6619.     }
  6620.     return(success);
  6621.       case SB:
  6622.     if ((y=cmkey(tnsbopts,ntnsbopts,"TELNET option","",xxstring)) < 0)
  6623.       return(y);
  6624.     switch (y) {
  6625.       case TELOPT_NAWS:
  6626.         /* Some compilers require switch() to have at least 1 case */
  6627. #ifdef CK_NAWS
  6628.         TELOPT_SB(TELOPT_NAWS).naws.x = 0;
  6629.         TELOPT_SB(TELOPT_NAWS).naws.y = 0;
  6630.         if (local)
  6631.           return(success = ((tn_snaws() > -1) ? 1 : 0));
  6632.         else
  6633.           return(success = 0);
  6634. #else
  6635.         return(success = 0);
  6636. #endif /* CK_NAWS */
  6637.     }
  6638.         return(success = 0);
  6639.  
  6640. #ifdef CK_KERBEROS
  6641. #ifdef KRB5
  6642.       case TN_FWD:
  6643.         success = (kerberos5_forward() == AUTH_SUCCESS);
  6644.         return(success);
  6645. #endif /* KRB5 */
  6646. #endif /* CK_KERBEROS */
  6647.  
  6648.       default:
  6649.     if ((z = cmcfm()) < 0) return(z);
  6650. #ifndef NOLOCAL
  6651.     if (local) {
  6652.         CHAR temp[3];
  6653.         if (network && IS_TELNET()) { /* TELNET */
  6654.         temp[0] = (CHAR) IAC;
  6655.         temp[1] = x;
  6656.         temp[2] = NUL;
  6657.         success = (ttol((CHAR *)temp,2) > -1 ? 1 : 0);
  6658.         if (tn_deb || debses || deblog) {
  6659.             /* TN_MSG_LEN is in ckctel.h */
  6660.             ckmakmsg(tn_msg,256,"TELNET SENT ",TELCMD(x),NULL,NULL);
  6661.             debug(F101,tn_msg,"",x);
  6662.             if (debses || tn_deb) tn_debug(tn_msg);
  6663.         }
  6664.         return(success);
  6665.         }
  6666.             return(success = 0);
  6667.     } else {
  6668. #endif /* NOLOCAL */
  6669.         printf("ff%02x\n",x);
  6670.         return(success = 1);
  6671. #ifndef NOLOCAL
  6672.     }
  6673. #endif /* NOLOCAL */
  6674.     }
  6675. }
  6676. #endif /* TNCODE */
  6677.  
  6678.  
  6679. #ifndef NOPUSH
  6680. #ifndef NOFRILLS
  6681. static int
  6682. doedit() {
  6683. #ifdef OS2
  6684.     char * p = NULL;
  6685. #endif /* OS2 */
  6686.     if (!editor[0]) {
  6687.     s = getenv("EDITOR");
  6688.     if (s) ckstrncpy(editor,s,CKMAXPATH);
  6689.     editor[CKMAXPATH] = NUL;
  6690.     if (!editor[0]) {
  6691.         printf("?Editor not defined - use SET EDITOR to define\n");
  6692.         return(-9);
  6693.     }
  6694.     }
  6695.     ckstrncpy(tmpbuf,editfile,TMPBUFSIZ);
  6696. /*
  6697.   cmiofi() lets us parse the name of an existing file, or the name of
  6698.   a nonexistent file to be created.
  6699. */
  6700.     x = cmiofi("File to edit", (char *)tmpbuf, &s, &y, xxstring);
  6701.     if (x < 0) {
  6702.     if (x == -9) {
  6703.         if (zchko(s) < 0) {
  6704.         printf("Can't create \"%s\"\n",s);
  6705.         return(x);
  6706.         }
  6707.     } else if (x != -3)
  6708.       return(x);
  6709.     }
  6710.     if (x == -3)
  6711.       tmpbuf[0] = NUL;
  6712.     else {
  6713.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  6714.     if (iswild((char *)tmpbuf)) {
  6715.         printf("?A single file please\n");
  6716.         return(-9);
  6717.     }
  6718.     }
  6719.     if ((z = cmcfm()) < 0) return(z);
  6720.     if (nopush) {
  6721.     printf("?Sorry, editing not allowed\n");
  6722.     return(success = 0);
  6723.     }
  6724.     if (tmpbuf[0]) {
  6725.     /* Get full path in case we change directories between EDIT commands */
  6726.     zfnqfp(tmpbuf, CKMAXPATH, editfile);
  6727.     editfile[CKMAXPATH] = NUL;
  6728. #ifdef OS2
  6729.     p = editfile;            /* Flip the stupid slashes */
  6730.     while (*p) {
  6731.         if (*p == '/') *p = '\\';
  6732.         p++;
  6733.     }
  6734. #endif /* OS2 */
  6735.     } else
  6736.       editfile[0] = NUL;
  6737.     x = 0;
  6738.     if (editopts[0]) {
  6739. #ifdef OS2
  6740.     x = ckindex("%1",(char *)editopts,0,0,1);
  6741.     if (x > 0)
  6742.       editopts[x] = 's';
  6743.     else
  6744. #endif /* OS2 */
  6745.       x = ckindex("%s",(char *)editopts,0,0,1);
  6746.     }
  6747.     if (((int)strlen(editopts) + (int)strlen(editfile) + 1) < TMPBUFSIZ) {
  6748.     if (x)
  6749.       sprintf(tmpbuf,editopts,editfile);
  6750.     else
  6751.       sprintf(tmpbuf,"%s %s",editopts,editfile);
  6752.     }
  6753.     s = line;
  6754.     ckmakmsg(s,LINBUFSIZ,editor," ",tmpbuf,NULL);
  6755. #ifdef OS2
  6756.     p = s + strlen(editor);        /* And again with the slashes */
  6757.     while (p != s) {
  6758.     if (*p == '/') *p = '\\';
  6759.     p--;
  6760.     }
  6761. #endif /* OS2 */
  6762.     conres();
  6763.     x = zshcmd(s);
  6764.     concb((char)escape);
  6765.     return(x);
  6766. }
  6767. #endif /* NOFRILLS */
  6768. #endif /* NOPUSH */
  6769.  
  6770. #ifdef BROWSER
  6771. static int
  6772. dobrowse() {
  6773. #ifdef OS2
  6774.     char * p = NULL;
  6775. #endif /* OS2 */
  6776.     if (nopush) {
  6777.     printf("?Sorry, browsing not allowed\n");
  6778.     return(success = 0);
  6779.     }
  6780. #ifndef NT
  6781.     /* Windows lets the Shell Execute the URL if no Browser is defined */
  6782.     if (!browser[0]) {
  6783.     s = getenv("BROWSER");
  6784.     if (s) ckstrncpy(browser,s,CKMAXPATH);
  6785.     browser[CKMAXPATH] = NUL;
  6786.     if (!browser[0]) {
  6787.         printf("?Browser not defined - use SET BROWSER to define\n");
  6788.         return(-9);
  6789.     }
  6790.     }
  6791. #endif /* NT */
  6792.     ckstrncpy(tmpbuf,browsurl,TMPBUFSIZ);
  6793.     if ((x = cmtxt("URL",(char *)browsurl,&s,xxstring)) < 0)
  6794.       return(x);
  6795.     ckstrncpy(browsurl,s,4096);
  6796.     x = 0;
  6797.     if (browsopts[0]) {
  6798. #ifdef OS2
  6799.     x = ckindex("%1",(char *)browsopts,0,0,1);
  6800.     if (x > 0)
  6801.       browsopts[x] = 's';
  6802.     else
  6803. #endif /* OS2 */
  6804.       x = ckindex("%s",(char *)browsopts,0,0,1);
  6805.     }
  6806.     if (((int)strlen(browsopts) + (int)strlen(browsurl) + 1) < TMPBUFSIZ) {
  6807.     if (x)
  6808.       sprintf(tmpbuf,browsopts,browsurl);
  6809.     else
  6810.       sprintf(tmpbuf,"%s %s",browsopts,browsurl);
  6811.     }
  6812. #ifdef NT
  6813.     if (!browser[0])
  6814.       return(success = Win32ShellExecute(browsurl));
  6815. #endif /* NT */
  6816.     s = line;
  6817.     ckmakmsg(s,LINBUFSIZ,browser," ",tmpbuf,NULL);
  6818. #ifdef OS2
  6819.     p = line + strlen(browser);        /* Flip slashes */
  6820.     while (p != line) {
  6821.     if (*p == '/') *p = '\\';
  6822.     p--;
  6823.     }
  6824. #endif /* OS2 */
  6825.     conres();
  6826.     x = zshcmd(s);
  6827.     concb((char)escape);
  6828.     return(x);
  6829. }
  6830. #endif /* BROWSER */
  6831.  
  6832. #ifdef CK_RECALL
  6833. static int
  6834. doredo() {            /* Find a previous cmd and redo it */
  6835.     extern int on_recall, in_recall;
  6836.     int x;
  6837.     char * p;
  6838.  
  6839.     if ((x = cmtxt(
  6840. "pattern, or first few characters of a previous command",
  6841.            "*",&s,xxstring)) < 0)
  6842.       return(x);
  6843.     ckstrncpy(line,s,LINBUFSIZ);
  6844.     x = strlen(s);
  6845.     s = line;
  6846.     if (*s == '{') {            /* Braces disable adding * to end */
  6847.     if (s[x-1] == '}') {
  6848.         s[x-1] = NUL;
  6849.         s++;
  6850.         x--;
  6851.     }
  6852.     } else {                /* No braces, add * to end. */
  6853.     s[x] = '*';
  6854.     s[x+1] = NUL;
  6855.     }
  6856.  
  6857.     while (x > 0 && s[x] == '*' && s[x-1] == '*') s[x--] = NUL;
  6858.  
  6859.     if (!on_recall || !in_recall) {
  6860.     printf("?Sorry, command recall can't be used now.\n");
  6861.     return(-9);
  6862.     }
  6863.     if ((p = cmgetcmd(s))) {        /* Look for it history buffer */
  6864.     ckmakmsg(cmdbuf,CMDBL,p,"\r",NULL,NULL); /* Copy to command buffer */
  6865.     if (!quiet)            /* Echo it */
  6866.       printf("%s\n",cmdbuf);
  6867.     cmaddnext();            /* Force re-add to history buffer */
  6868.     return(cmflgs = -1);        /* Force reparse */
  6869.     } else {
  6870.     printf("?Sorry - \"%s\" not found\n", s);
  6871.     return(-9);
  6872.     }
  6873. }
  6874. #endif /* CK_RECALL */
  6875.  
  6876. #ifndef NOXFER
  6877. #ifndef NOCSETS
  6878. static int
  6879. doassoc()  {                /* ASSOCIATE */
  6880.     extern struct keytab tcstab[];
  6881.     extern int ntcs;
  6882.     if ((x = cmkey(assoctab, nassoc, "", "", xxstring)) < 0 )
  6883.       return(x);
  6884.  
  6885.     switch (x) {            /* Associate what? */
  6886.  
  6887.       case ASSOC_TC:            /* Transfer character-set... */
  6888.     if ((x = cmkey(tcstab, ntcs,
  6889.                "transfer character-set name","",xxstring)) < 0)
  6890.       return(x);
  6891.     if ((y = cmkey(fcstab, nfilc,
  6892.                "with file character-set","", xxstring)) < 0)
  6893.       if (y != -3)
  6894.         return(y);
  6895.     if ((z = cmcfm()) < 0)
  6896.       return(z);
  6897.     axcset[x] = y;
  6898.     return(success = 1);
  6899.  
  6900.       case ASSOC_FC:            /* File character-set... */
  6901.     if ((x = cmkey(fcstab, nfilc,
  6902.                "file character-set name","",xxstring)) < 0)
  6903.       return(x);
  6904.     if ((y = cmkey(tcstab, ntcs,
  6905.                "with transfer character-set","", xxstring)) < 0)
  6906.       if (y != -3)
  6907.         return(y);
  6908.     if ((z = cmcfm()) < 0)
  6909.       return(z);
  6910.     afcset[x] = y;
  6911.     return(success = 1);
  6912.  
  6913.       default:
  6914.     return(-2);
  6915.     }
  6916. }
  6917. #endif /* NOCSETS */
  6918. #endif /* NOXFER */
  6919.  
  6920. #ifndef NOHELP
  6921. static int
  6922. domanual() {
  6923. #ifdef OS2
  6924.     if ((x = cmcfm()) < 0)
  6925.       return(x);
  6926.     if (nopush) {
  6927.     printf("?Sorry, access to system commands is disabled.\n");
  6928.     return(-9);
  6929.     }
  6930.     y = mxlook(mactab,"manual",nmac);
  6931.     if (y > -1) {
  6932.     z = maclvl;            /* Save the current maclvl */
  6933.     dodo(y,NULL,cmdstk[cmdlvl].ccflgs); /* Run the macro */
  6934.     while (maclvl > z) {
  6935.         debug(F101,"XXMAN loop maclvl 1","",maclvl);
  6936.         sstate = (CHAR) parser(1);
  6937.         debug(F101,"XXMAN loop maclvl 2","",maclvl);
  6938.         if (sstate) proto();
  6939.     }
  6940.     debug(F101,"XXMAN loop exit maclvl","",maclvl);
  6941.     return(success);
  6942.     }
  6943.     return(success = 0);
  6944. #else
  6945.     if ((x = cmtxt(
  6946. #ifdef UNIX
  6947.            "Carriage return to confirm the command, or manual topic",
  6948. #else
  6949.            "Carriage return to confirm the command, or help topic",
  6950. #endif /* UNIX */
  6951.            "kermit",
  6952.            &s,
  6953.            xxstring
  6954.            )
  6955.      ) < 0)
  6956.       return(x);
  6957. #endif /* OS2 */
  6958.  
  6959. #ifdef UNIX
  6960.     ckmakmsg(tmpbuf,TMPBUFSIZ,"man ",s,NULL,NULL);
  6961. #else
  6962.     ckmakmsg(tmpbuf,TMPBUFSIZ,"help ",s,NULL,NULL);
  6963. #endif /* UNIX */
  6964.     debug(F110,"MANUAL",tmpbuf,0);
  6965.     if (nopush) {
  6966.     printf("?Sorry, access to system commands is disabled.\n");
  6967.     return(-9);
  6968.     } else {
  6969.     conres();            /* Restore the console */
  6970.     success = zshcmd(tmpbuf);
  6971.     concb((char)escape);        /* Restore CBREAK mode */
  6972.     return(success);
  6973.     }
  6974. }
  6975. #endif /* NOHELP */
  6976.  
  6977. #ifndef NOHTTP
  6978. #ifdef TCPSOCKET
  6979. static struct keytab sslswtab[] = {
  6980.     { "/ssl", 1, 0 },
  6981.     { "/tls", 1, 0 }
  6982. };
  6983.  
  6984. #ifndef NOURL
  6985. struct urldata http_url = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};
  6986. #endif /* NOURL */
  6987.  
  6988. static int
  6989. dohttp() {                /* HTTP */
  6990.     struct FDB sw, kw, fi;
  6991.     int n, getval, allinone = 0;
  6992.     char c, * p;
  6993.     char rdns[128];
  6994.  
  6995.     char * http_agent = NULL;        /* Parse results */
  6996.     char * http_hdr   = NULL;
  6997.     char * http_user  = NULL;
  6998.     char * http_pass  = NULL;
  6999.     char * http_mime  = NULL;
  7000.     char * http_lfile = NULL;
  7001.     char * http_rfile = NULL;
  7002.     char * http_dfile = NULL;
  7003.     char   http_array = NUL;
  7004.     int    http_action = -1;
  7005.  
  7006.     char * http_host = NULL;
  7007.     char * http_srv  = NULL;
  7008.     int    http_ssl  = 0;
  7009.  
  7010.     static char * http_d_agent = NULL;
  7011.     static char * http_d_user = NULL;
  7012.     static char * http_d_pass = NULL;
  7013.  
  7014.     static int    http_d_type = 0;
  7015.     int           http_type = http_d_type;
  7016.  
  7017. #ifdef OS2
  7018.     p = "Kermit 95";            /* Default user agent */
  7019. #else
  7020.     p = "C-Kermit";
  7021. #endif /* OS2 */
  7022.     makestr(&http_agent,p);
  7023.     makestr(&http_mime,"text/HTML");    /* MIME type default */
  7024.     rdns[0] = '\0';
  7025.  
  7026.     cmfdbi(&sw,                /* 1st FDB - general switches */
  7027.        _CMKEY,                /* fcode */
  7028.        "OPEN, CLOSE, GET, HEAD, PUT, INDEX, or POST,\n or switch", /* hlpmsg */
  7029.        "",                /* default */
  7030.        "",                /* addtl string data */
  7031.        nhttpswtab,            /* addtl numeric data 1: tbl size */
  7032.        4,                /* addtl numeric data 2: 4 = cmswi */
  7033.        xxstring,            /* Processing function */
  7034.        httpswtab,            /* Keyword table */
  7035.        &kw                /* Pointer to next FDB */
  7036.        );
  7037.     cmfdbi(&kw,                /* 2nd FDB - commands */
  7038.        _CMKEY,                /* fcode */
  7039.        "Command",            /* hlpmsg */
  7040.        "",                /* default */
  7041.        "",                /* addtl string data */
  7042.        nhttptab,            /* addtl numeric data 1: tbl size */
  7043.        0,                /* addtl numeric data 2: 0 = keyword */
  7044.        xxstring,            /* Processing function */
  7045.        httptab,                /* Keyword table */
  7046.        NULL                /* Pointer to next FDB */
  7047.        );
  7048.  
  7049.     while (1) {
  7050.     x = cmfdb(&sw);            /* Parse something */
  7051.     if (x < 0)            /* Error */
  7052.       goto xhttp;
  7053.     n = cmresult.nresult;
  7054.     if (cmresult.fdbaddr == &kw)    /* Command - exit this loop */
  7055.       break;
  7056.     c = cmgbrk();            /* Switch... */
  7057.     getval = (c == ':' || c == '=');
  7058.     x = -9;
  7059.     if (getval && !(cmgkwflgs() & CM_ARG)) {
  7060.         printf("?This switch does not take an argument\n");
  7061.         goto xhttp;
  7062.     }
  7063.     switch (cmresult.nresult) {    /* Handle each switch */
  7064.           case HT_SW_TP:                /* /TOSCREEN */
  7065.             http_type = 1;
  7066.             break;
  7067.       case HT_SW_AG:        /* /AGENT */
  7068.         if (getval) {
  7069.         if ((x = cmfld("User agent",p,&s,xxstring)) < 0)
  7070.           goto xhttp;
  7071.         } else {
  7072.         s = p;
  7073.         }
  7074.         makestr(&http_agent,s);
  7075.         break;
  7076.       case HT_SW_HD:        /* /HEADER */
  7077.         s = NULL;
  7078.         if (getval) {
  7079.         if ((x = cmfld("Header line","",&s,xxstring)) < 0) {
  7080.             if (x == -3)
  7081.               s = NULL;
  7082.             else
  7083.               goto xhttp;
  7084.         }
  7085.         }
  7086.         makestr(&http_hdr,s);
  7087.         break;
  7088.       case HT_SW_US:        /* /USER */
  7089.         s = NULL;
  7090.         if (getval) {
  7091.         if ((x = cmfld("User ID","",&s,xxstring)) < 0) {
  7092.                   if (x == -3)
  7093.                     s = "";
  7094.                   else
  7095.             goto xhttp;
  7096.                 }
  7097.         }
  7098.         makestr(&http_user,s);
  7099.         break;
  7100.       case HT_SW_PW:        /* /PASSWORD */
  7101.         debok = 0;
  7102.         s = NULL;
  7103.         if (getval) {
  7104.         if ((x = cmfld("Password","",&s,xxstring)) < 0)
  7105.           goto xhttp;
  7106.         }
  7107.         makestr(&http_pass,s);
  7108.         break;
  7109. #ifndef NOSPL
  7110.       case HT_SW_AR: {        /* /ARRAY: */
  7111.           char * s2, array = NUL;
  7112.           if (!getval) {
  7113.           printf("?This switch requires an argument\n");
  7114.           x = -9;
  7115.           goto xhttp;
  7116.           }
  7117.           if ((x = cmfld("Array name (a single letter will do)",
  7118.                  "",
  7119.                  &s,
  7120.                  NULL
  7121.                  )) < 0) {
  7122.           if (x == -3) {
  7123.               printf("?Array name required\n");
  7124.               x = -9;
  7125.               goto xhttp;
  7126.           } else
  7127.             goto xhttp;
  7128.           }
  7129.           if (!*s) {
  7130.           printf("?Array name required\n");
  7131.           x = -9;
  7132.           goto xhttp;
  7133.           }
  7134.           s2 = s;
  7135.           if (*s == CMDQ) s++;
  7136.           if (*s == '&') s++;
  7137.           if (!isalpha(*s)) {
  7138.           printf("?Bad array name - \"%s\"\n",s2);
  7139.           x = -9;
  7140.           goto xhttp;
  7141.           }
  7142.           array = *s++;
  7143.           if (isupper(array))
  7144.         array = tolower(array);
  7145.           if (*s && (*s != '[' || *(s+1) != ']')) {
  7146.           printf("?Bad array name - \"%s\"\n",s2);
  7147.           http_array = NUL;
  7148.           x = -9;
  7149.           goto xhttp;
  7150.           }
  7151.           http_array = array;
  7152.           break;
  7153.       }
  7154. #endif /* NOSPL */
  7155.       default:
  7156.         x = -2;
  7157.         goto xhttp;
  7158.     }
  7159.     }
  7160.     http_action = n;            /* Save the action */
  7161.     if (http_action == HTTP_PUT || http_action == HTTP_POS) {
  7162.     cmfdbi(&sw,            /* 1st FDB - switch */
  7163.            _CMKEY,            /* fcode */
  7164.            "Local filename\n Or switch", /* help */
  7165.            "",            /* default */
  7166.            "",            /* addtl string data */
  7167.            nhttpptab,        /* keyword table size */
  7168.            4,            /* addtl numeric data 2: 4 = cmswi */
  7169.            xxstring,        /* Processing function */
  7170.            httpptab,        /* Keyword table */
  7171.            &fi            /* Pointer to next FDB */
  7172.            );
  7173.     cmfdbi(&fi,            /* 2nd FDB - filename */
  7174.            _CMIFI,            /* fcode */
  7175.            "Local filename",    /* hlpmsg */
  7176.            "",            /* default */
  7177.            "",            /* addtl string data */
  7178.            0,            /* addtl numeric data 1 */
  7179.            0,            /* addtl numeric data 2 */
  7180.            xxstring,
  7181.            NULL,
  7182.            NULL
  7183.            );
  7184.     while (1) {
  7185.         x = cmfdb(&sw);
  7186.         if (x < 0)
  7187.           goto xhttp;        /* Free any malloc'd temp strings */
  7188.         n = cmresult.nresult;
  7189.         if (cmresult.fcode != _CMKEY)
  7190.           break;
  7191.         c = cmgbrk();        /* Switch... */
  7192.         getval = (c == ':' || c == '=');
  7193.         if (getval && !(cmgkwflgs() & CM_ARG)) {
  7194.         printf("?This switch does not take an argument\n");
  7195.         x = -9;
  7196.         goto xhttp;
  7197.         }
  7198.         switch (n) {
  7199.           case HT_PP_MT:
  7200.         s = "text/HTML";
  7201.         if (getval) {
  7202.             if ((x = cmfld("MIME type",
  7203.                    "text/HTML",&s,xxstring)) < 0)
  7204.               goto xhttp;
  7205.         }
  7206.         makestr(&http_mime,s);
  7207.         break;
  7208.           default:
  7209.         x = -2;
  7210.         goto xhttp;
  7211.         }
  7212.     }
  7213.     makestr(&http_lfile,cmresult.sresult);
  7214.     n = ckindex("/",http_lfile,-1,1,0);
  7215.     if (n)
  7216.       p = &http_lfile[n];
  7217.     else
  7218.       p = http_lfile;
  7219.     if ((x = cmfld("URL or remote filename",p,&s,xxstring)) < 0) {
  7220.           if (x == -3) {
  7221.             printf("?%s what?\n",(http_action == HTTP_PUT) ? "Put" : "Post");
  7222.             x = -9;
  7223.           }
  7224.           goto xhttp;
  7225.         }
  7226.     if (!*s) s = NULL;
  7227.     makestr(&http_rfile,s);
  7228.  
  7229.     if ((x = cmtxt("Response filename","",&s,xxstring)) < 0) {
  7230.           if (x != -3)
  7231.             goto xhttp;
  7232.         }
  7233.         if (*s)
  7234.           makestr(&http_dfile,s);
  7235.     }
  7236.     switch (http_action) {
  7237.       case HTTP_DEL:            /* DELETE */
  7238.     if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
  7239.           if (x == -3) {
  7240.             printf("?Delete what?\n");
  7241.             x = -9;
  7242.           }
  7243.           goto xhttp;
  7244.         }
  7245.     makestr(&http_rfile,s);
  7246.     break;
  7247.       case HTTP_CON:            /* CONNECT */
  7248.         if ((x = cmfld("Remote host[:port]","",&s,xxstring)) < 0) {
  7249.           if (x == -3) {
  7250.             printf("?Remote host[:port] is required\n");
  7251.             x = -9;
  7252.           }
  7253.           goto xhttp;
  7254.         }
  7255.     makestr(&http_rfile,s);
  7256.     break;
  7257.       case HTTP_HED: {            /* HEAD */
  7258.       char buf[CKMAXPATH+1];
  7259.       if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
  7260.           if (x == -3) {
  7261.           printf("?Head of what?\n");
  7262.           x = -9;
  7263.           }
  7264.           goto xhttp;
  7265.       }
  7266.       makestr(&http_rfile,s);
  7267.  
  7268.       if (http_array || http_type) { /* Default result filename */
  7269.           p = "";             /* None if /ARRAY or /TOSCREEN */
  7270.       } else {
  7271.           n = ckindex("/",http_rfile,-1,1,0); /* Otherwise strip path */
  7272.           if (n)                          /* and add ".head" */
  7273.         p = &http_rfile[n];
  7274.           else
  7275.         p = http_rfile;
  7276.           ckmakmsg(buf,CKMAXPATH,p,".head",NULL,NULL);
  7277.           p = buf;
  7278.       }
  7279.       if ((x = cmofi("Local filename",p,&s,xxstring)) < 0) {
  7280.           if (x != -3)
  7281.         goto xhttp;
  7282.       }
  7283.       makestr(&http_lfile,s);
  7284.       break;
  7285.       }
  7286.       case HTTP_GET:            /* GET */
  7287.       case HTTP_IDX: {            /* INDEX */
  7288.       char * lfile = "";
  7289.       if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
  7290.           if (x == -3) {
  7291.           printf("?Get what?\n");
  7292.           x = -9;
  7293.           }
  7294.           goto xhttp;
  7295.       }
  7296.       makestr(&http_rfile,s);
  7297.       if (http_action == HTTP_GET && !http_type)
  7298.         zstrip(http_rfile,&lfile);
  7299.       if ((x = cmofi("Local filename",lfile,&s,xxstring)) < 0)
  7300.         if (x != -3)
  7301.           goto xhttp;
  7302.       makestr(&http_lfile,s);
  7303.       break;
  7304.       }
  7305.       case HTTP_OPN: {
  7306.       int sslswitch = 0;
  7307. #ifdef CK_SSL
  7308.       struct FDB sw, fl;
  7309.       cmfdbi(&sw,
  7310.          _CMKEY,        /* fcode */
  7311.          "IP host name or address, or switch", /* hlpmsg */
  7312.          "",            /* default */
  7313.          "",            /* addtl string data */
  7314.          2,            /* addtl numeric data 1: tbl size */
  7315.          4,            /* addtl numeric data 2: 4 = cmswi */
  7316.          xxstring,        /* Processing function */
  7317.          sslswtab,        /* Keyword table */
  7318.          &fl            /* Pointer to next FDB */
  7319.          );
  7320.       cmfdbi(&fl,            /* 2nd FDB - host */
  7321.          _CMFLD,        /* fcode */
  7322.          "",            /* hlpmsg */
  7323.          "",            /* default */
  7324.          "",            /* addtl string data */
  7325.          0,            /* addtl numeric data 1 */
  7326.          0,            /* addtl numeric data 2 */
  7327.          xxstring,
  7328.          NULL,
  7329.          NULL
  7330.          );
  7331.       x = cmfdb(&sw);        /* Parse switch or host */
  7332.       if (x < 0)            /* Error */
  7333.         goto xhttp;
  7334.       if (cmresult.fcode == _CMFLD) { /* Host */
  7335.           s = cmresult.sresult;      /* Set up expected pointer */
  7336.           goto havehost;              /* Go parse rest of command */
  7337.       }
  7338.       sslswitch = 1;        /* /SSL or /TLS switch - set flag */
  7339. #endif /* CK_SSL */
  7340.  
  7341.       /* Parse host */
  7342.  
  7343.       if ((x = cmfld("URL, hostname, or ip-address","",&s,xxstring)) < 0) {
  7344.           if (x == -3) {
  7345.           printf("?Open what?\n");
  7346.           x = -9;
  7347.           }
  7348.           goto xhttp;
  7349.       }
  7350.  
  7351.     havehost:            /* Come here with s -> host */
  7352. #ifdef CK_URL
  7353.       x = urlparse(s,&http_url);    /* Was a URL given? */
  7354.       if (x < 1) {            /* Not a URL */
  7355. #endif /* CK_URL */
  7356.           makestr(&http_host,s);
  7357.           if ((x =
  7358.            cmfld("Service name or port number",
  7359.              "http",&s,xxstring)) < 0)
  7360.         goto xhttp;
  7361.           else
  7362.         makestr(&http_srv,s);
  7363. #ifdef CK_URL
  7364.       } else if (ckstrcmp(http_url.svc,"http",-1,0) && /* Non-HTTP URL */
  7365.              ckstrcmp(http_url.svc,"https",-1,0)) {
  7366.           printf("?Non-HTTP URL\n");
  7367.           x = -9;
  7368.           goto xhttp;
  7369.       } else {            /* Have HTTP URL */
  7370.           makestr(&http_srv, http_url.svc);
  7371.           makestr(&http_user,http_url.usr);
  7372.           makestr(&http_pass,http_url.psw);
  7373.           makestr(&http_host,http_url.hos);
  7374.           if (http_url.por)
  7375.         makestr(&http_srv,http_url.por);
  7376.           makestr(&http_rfile,http_url.pth);
  7377.       }
  7378.       if (http_rfile) {        /* Open, GET, and Close */
  7379.           printf("?Directory/file path not allowed in HTTP OPEN URL\n");
  7380.           x = -9;
  7381.           goto xhttp;
  7382.       }
  7383.       if (!ckstrcmp("https",http_srv,-1,0) || sslswitch ||
  7384.           !ckstrcmp("443",http_srv,-1,0))
  7385.         http_ssl = 1;
  7386. #endif /* CK_URL */
  7387.       break;
  7388.       }
  7389.       case HTTP_CLS:
  7390.         break;
  7391.     }
  7392.     if ((x = cmcfm()) < 0)
  7393.       goto xhttp;
  7394.  
  7395.     if (http_action == HTTP_OPN) {
  7396.         x = (http_open(http_host,http_srv,http_ssl,rdns,128) == 0);
  7397.         if (x) {
  7398.             if (!quiet) {
  7399.               if (rdns[0])
  7400.                 printf("Connected to %s [%s]\r\n",http_host,rdns);
  7401.               else
  7402.                 printf("Connected to %s\r\n",http_host);
  7403.             }
  7404.             if (http_agent) {
  7405.                 if (http_d_agent)
  7406.           free(http_d_agent);
  7407.                 http_d_agent = http_agent;
  7408.                 http_agent = NULL;
  7409.             }
  7410.             if (http_user) {
  7411.                 if (http_d_user)
  7412.           free(http_d_user);
  7413.                 http_d_user = http_user;
  7414.                 http_user = NULL;
  7415.             }
  7416.             if (http_pass) {
  7417.                 if (http_d_pass) {
  7418.                     memset(http_d_pass,0,strlen(http_d_pass));
  7419.                     free(http_d_pass);
  7420.                 }
  7421.                 http_d_pass = http_pass;
  7422.                 http_pass = NULL;
  7423.             }
  7424.             http_d_type = http_type;
  7425.         } else {
  7426.             if (!quiet)
  7427.           printf("?HTTP Connection failed.\r\n");
  7428.         }
  7429.     } else if (http_action == HTTP_CLS) {
  7430.         if (http_d_agent) {
  7431.             free(http_d_agent);
  7432.             http_d_agent = NULL;
  7433.         }
  7434.         if (http_d_user) {
  7435.             free(http_d_user);
  7436.             http_d_user = NULL;
  7437.         }
  7438.         if (http_d_pass) {
  7439.             memset(http_d_pass,0,strlen(http_d_pass));
  7440.             free(http_d_pass);
  7441.             http_d_pass = NULL;
  7442.         }
  7443.         http_d_type = 0;
  7444.         x = (http_close() == 0);
  7445.     }
  7446.     if ((http_action != HTTP_CLS) &&
  7447.     (http_action != HTTP_CON) && http_rfile) { /* Remote file is URL? */
  7448.  
  7449.     /* All-in-one actions when a URL is given... */
  7450.  
  7451. #ifdef CK_URL
  7452.     if (urlparse(http_rfile,&http_url) > 0) { /* Have URL? */
  7453.         if (ckstrcmp(http_url.svc,"http",-1,0) && /* It's an HTTP URL? */
  7454.         ckstrcmp(http_url.svc,"https",-1,0)) {
  7455.         printf("?Non-HTTP URL\n");
  7456.         x = -9;
  7457.         goto xhttp;
  7458.         } else {            /* Yes, collect the pieces */
  7459.         makestr(&http_srv, http_url.svc);
  7460.         makestr(&http_user,http_url.usr);
  7461.         makestr(&http_pass,http_url.psw);
  7462.         makestr(&http_host,http_url.hos);
  7463.         if (http_url.por)
  7464.           makestr(&http_srv,http_url.por);
  7465.         makestr(&http_rfile,http_url.pth);
  7466.         }
  7467.         if (!http_rfile) {        /* Still have a path? */
  7468.                 makestr(&http_rfile,"/");
  7469.         }
  7470.         if (!ckstrcmp("https",http_srv,-1,0) || /* Check for SSL/TLS */
  7471.         !ckstrcmp("443",http_srv,-1,0))
  7472.           http_ssl = 1;
  7473.         if (http_isconnected())    /* Close any open HTTP connection */
  7474.           http_close();
  7475.         if (http_pass == NULL && http_d_pass != NULL)
  7476.           makestr(&http_pass,http_d_pass);
  7477.         x = (http_open(http_host,http_srv,http_ssl,rdns,128) == 0);
  7478.         if (x < 0) {
  7479.         x = 0;
  7480.         goto xhttp;
  7481.         }
  7482.         allinone = 1;
  7483.     }
  7484. #endif /* CK_URL */
  7485.         if (http_pass == NULL && http_d_pass != NULL)
  7486.       makestr(&http_pass,http_d_pass);
  7487.  
  7488.     if (http_action == HTTP_OPN && allinone) {
  7489.         http_action = HTTP_GET;
  7490.     }
  7491.         x = xdohttp(http_action,
  7492.                     http_lfile,
  7493.             http_rfile,
  7494.                     http_dfile,
  7495.             http_agent ? http_agent : http_d_agent,
  7496.             http_hdr,
  7497.             http_user  ? http_user  : http_d_user,
  7498.             http_pass  ? http_pass  : http_d_pass,
  7499.             http_mime,
  7500.             http_array,
  7501.             http_type
  7502.             );
  7503.     if (allinone)
  7504.       x = (http_close() == 0);
  7505.     }
  7506.  
  7507.   xhttp:
  7508.     if (http_agent) free(http_agent);
  7509.     if (http_hdr)   free(http_hdr);
  7510.     if (http_user)  free(http_user);
  7511.     if (http_pass) {
  7512.         memset(http_pass,0,strlen(http_pass));
  7513.         free(http_pass);
  7514.     }
  7515.     if (http_mime)  free(http_mime);
  7516.     if (http_lfile) free(http_lfile);
  7517.     if (http_rfile) free(http_rfile);
  7518.     if (http_dfile) free(http_dfile);
  7519.     if (http_host)  free(http_host);
  7520.     if (http_srv)   free(http_srv);
  7521.  
  7522.     if (x > -1)
  7523.       success = x;
  7524.     return(x);
  7525. }
  7526. #endif /* TCPSOCKET */
  7527. #endif /* NOHTTP */
  7528.  
  7529.  
  7530. #ifndef NOSPL
  7531. static int
  7532. dotrace() {
  7533.     int on = 1;
  7534.     struct FDB sw, kw;
  7535.     cmfdbi(&sw,                /* 1st FDB - switch */
  7536.        _CMKEY,            /* fcode */
  7537.        "Trace object;\n Or switch", /* help */
  7538.        "",                /* default */
  7539.        "",                /* addtl string data */
  7540.        2,                /* keyword table size */
  7541.        4,                /* addtl numeric data 2: 4 = cmswi */
  7542.        xxstring,            /* Processing function */
  7543.        onoffsw,            /* Keyword table */
  7544.        &kw                /* Pointer to next FDB */
  7545.        );
  7546.     cmfdbi(&kw,                /* 2nd FDB - Trace object */
  7547.        _CMKEY,            /* fcode */
  7548.        "Trace object",        /* help */
  7549.        "all",            /* default */
  7550.        "",                /* addtl string data */
  7551.        ntracetab,            /* keyword table size */
  7552.        0,                /* addtl numeric data 2: 0 = keyword */
  7553.        xxstring,            /* Processing function */
  7554.        tracetab,            /* Keyword table */
  7555.        NULL                /* Pointer to next FDB */
  7556.        );
  7557.     if ((x = cmfdb(&sw)) < 0)
  7558.       return(x);
  7559.     if (cmresult.fdbaddr == &sw) {
  7560.     on = cmresult.nresult;
  7561.     if ((x = cmkey(tracetab, ntracetab,"","all",xxstring)) < 0)
  7562.       return(x);
  7563.     } else {
  7564.     x = cmresult.nresult;
  7565.     }
  7566.     if ((y = cmcfm()) < 0)
  7567.       return(y);
  7568.  
  7569.     switch (x) {
  7570.       case TRA_ASG:
  7571.     tra_asg = on;
  7572.     break;
  7573.       case TRA_CMD:
  7574.     tra_cmd = on;
  7575.     break;
  7576.       case TRA_ALL:
  7577.     tra_asg = on;
  7578.     tra_cmd = on;
  7579.     break;
  7580.       default:
  7581.     return(-2);
  7582.     }
  7583.     printf("TRACE %s\n", on ? "ON" : "OFF");
  7584.     return(success = 1);
  7585. }
  7586. #endif /* NOSPL */
  7587.  
  7588.  
  7589. static int
  7590. doprompt() {
  7591.     extern int xcmdsrc;
  7592.     if ((x = cmtxt("Optional message","",&s,xxstring)) < 0)
  7593.       return(x);
  7594. #ifdef NOSPL
  7595.     printf("?Sorry, PROMPT requires script programming language\n");
  7596.     return(-9);
  7597. #else
  7598.     debug(F101,"Prompt cmdlvl","",cmdlvl);
  7599.     cmdlvl++;
  7600.     if (cmdlvl > CMDSTKL) {
  7601.     printf("?Command stack overflow: %d\n",cmdlvl);
  7602.     cmdlvl--;
  7603.     return(-9);
  7604.     }
  7605.     xcmdsrc = CMD_KB;
  7606.     cmdstk[cmdlvl].src = CMD_KB;    /* Say we're at the prompt */
  7607.     cmdstk[cmdlvl].lvl = 0;
  7608.     cmdstk[cmdlvl].ccflgs = cmdstk[cmdlvl-1].ccflgs;
  7609.     if (tra_cmd)
  7610.       printf("[%d] +P: \"(prompt)\"\n",cmdlvl);
  7611.     concb((char)escape);
  7612.     if (!quiet)
  7613.       printf(
  7614. "(Recursive command prompt: Resume script with CONTINUE, STOP to stop...)\n"
  7615.             );
  7616.     if (*s) {                /* If prompt given */
  7617.     makestr(&(prstring[cmdlvl-1]),cmgetp()); /* Save current prompt */
  7618.     cmsetp(s);            /* Set new one */
  7619.     }
  7620.     return(success = 1);
  7621. #endif /* NOSPL */
  7622. }
  7623.  
  7624. #ifdef CKLEARN
  7625. VOID
  7626. learncmd(s) char *s; {            /* Record commands in learned script */
  7627.     char buf[64];
  7628.     int i, k;
  7629.     if (learnfp && learning) {        /* Only if open and on */
  7630.     k = ckstrncpy(buf,s,64);
  7631.     for (i = 0; i < k; i++) {    /* Get top-level command keyword */
  7632.         if (buf[i] <= SP) {
  7633.         buf[i] = NUL;
  7634.         break;
  7635.         }
  7636.     }
  7637.     k = lookup(cmdtab,buf,ncmd,NULL); /* Look it up */
  7638.     if (k == XXCON || k == XXLEARN)      /* Don't record CONNECT or LEARN */
  7639.       return;
  7640.     if (k == XXTEL) {
  7641.         fputs("SET HOST /NETWORK:TCP",learnfp);
  7642.         fputs(&s[i],learnfp);
  7643.         fputs(" TELNET /TELNET",learnfp);
  7644.         fputs("\nIF FAIL STOP 1 Connection failed\n",learnfp);
  7645.     } else {
  7646.         fputs(s,learnfp);
  7647.         fputs("\n",learnfp);
  7648.     }
  7649.     }
  7650. }
  7651. #endif /* CKLEARN */
  7652.  
  7653.  
  7654. /*  D O C M D  --  Do a command  */
  7655.  
  7656. /*
  7657.  Returns:
  7658.    -2: user typed an illegal command
  7659.    -1: reparse needed
  7660.     0: parse was successful (even tho command may have failed).
  7661. */
  7662. #ifdef DEBUG
  7663. int cmdstats[256] = { -1, -1 };
  7664. #endif /* DEBUG */
  7665.  
  7666. int
  7667. docmd(cx) int cx; {
  7668.     extern int nolocal, cmkwflgs;
  7669.  
  7670.     debug(F101,"docmd entry, cx","",cx);
  7671.     activecmd = cx;
  7672.     doconx = ((activecmd == XXCON)  || (activecmd == XXTEL) ||
  7673.           (activecmd == XXRLOG) || (activecmd == XXPIPE) ||
  7674.               (activecmd == XXIKSD) || (activecmd == XXPTY));
  7675. /*
  7676.   Originally all commands were handled with a big switch() statement,
  7677.   but eventually this started blowing up compilers.  Now we have a series
  7678.   of separate if statements and small switches, with the commands that are
  7679.   most commonly executed in scipts and loops coming first, to speed up
  7680.   compute-bound scripts.
  7681.   */
  7682.  
  7683. #ifdef DEBUG
  7684.     if (cmdstats[0] == -1) {        /* Count commands */
  7685.     int i;                /* for tuning... */
  7686.     for (i = 0; i < 256; i++)
  7687.       cmdstats[i] = 0;
  7688.     }
  7689. #endif /* DEBUG */
  7690.  
  7691.     switch (cx) {
  7692.       case -4:                /* EOF */
  7693. #ifdef OSK
  7694.     if (msgflg)  printf("\n");
  7695. #else
  7696.     if (msgflg)  printf("\r\n");
  7697. #endif /* OSK */
  7698.       doexit(GOOD_EXIT,xitsta);
  7699.       case -3:                /* Null command */
  7700.     return(0);
  7701.       case -9:                /* Like -2, but errmsg already done */
  7702.       case -1:                /* Reparse needed */
  7703.     return(cx);
  7704.       case -6:                /* Special */
  7705.       case -2:                /* Error, maybe */
  7706.  
  7707. #ifndef NOSPL
  7708. /*
  7709.   Maybe they typed a macro name.  Let's look it up and see.
  7710. */
  7711.     if (cx == -6)            /* If they typed CR */
  7712.       ckstrncat(cmdbuf,"\015",CMDBL); /*  add it back to command buffer. */
  7713.     if (ifcmd[cmdlvl] == 2)        /* Watch out for IF commands. */
  7714.       ifcmd[cmdlvl]--;
  7715.     repars = 1;            /* Force reparse */
  7716.     cmres();
  7717.     cx = XXDO;            /* Try DO command */
  7718. #else
  7719.     return(cx);
  7720. #endif /* NOSPL */
  7721.       default:
  7722.     if (cx < 0)
  7723.       return(cx);
  7724.     break;
  7725.     }
  7726. #ifdef DEBUG
  7727.     if (cx < 256)
  7728.       cmdstats[cx]++;
  7729. #endif /* DEBUG */
  7730.  
  7731.     if ((cmkwflgs & CM_PSH)
  7732. #ifndef NOPUSH
  7733.     && nopush
  7734. #endif /* NOPUSH */
  7735.     ) {
  7736.     printf("?Access to system disabled\n");
  7737.     return(-9);
  7738.     }
  7739.     if ((cmkwflgs & CM_LOC)
  7740. #ifndef NOLOCAL
  7741.     && nolocal
  7742. #endif /* NOLOCAL */
  7743.     ) {
  7744.     printf("?Connections disabled\n");
  7745.     return(-9);
  7746.     }
  7747.  
  7748. #ifndef NOSPL
  7749.     /* Used in FOR loops */
  7750.  
  7751.     if (cx == XX_INCR || cx == XXINC  || /* _INCREMENT, INCREMENT */
  7752.     cx == XX_DECR || cx == XXDEC)     /* _DECREMENT, DECREMENT */
  7753.       return(doincr(cx));
  7754.  
  7755.     /* Define (or change the definition of) a macro or variable */
  7756.  
  7757.     if (cx == XXUNDEF || cx == XXUNDFX) {
  7758. #ifdef IKSD
  7759.     if (inserver && !ENABLED(en_asg)) {
  7760.         printf("?Sorry, DEFINE/ASSIGN disabled\n");
  7761.         return(-9);
  7762.     }
  7763. #endif /* IKSD */
  7764.     return(doundef(cx));        /* [_]UNDEFINE */
  7765.     }
  7766.     if (cx == XXDEF || cx == XXASS ||
  7767.     cx == XXDFX || cx == XXASX) {
  7768. #ifdef IKSD
  7769.     if (inserver && !ENABLED(en_asg)) {
  7770.         printf("?Sorry, DEFINE/ASSIGN disabled\n");
  7771.         return(-9);
  7772.     }
  7773. #endif /* IKSD */
  7774.     if (atmbuf[0] == '.' && !atmbuf[1]) /* "." entered as keyword */
  7775.       xxdot = 1;            /* i.e. with space after it... */
  7776.     return(dodef(cx));        /* DEFINE, ASSIGN, etc... */
  7777.     }
  7778.  
  7779.     /* IF, WHILE, and friends  */
  7780.  
  7781.     if (cx == XXIF || cx == XXIFX || cx == XXWHI || cx == XXASSER) {
  7782.     return(doif(cx));
  7783.     }
  7784.     if (cx == XXSWIT) {            /* SWITCH */
  7785.     return(doswitch());
  7786.     }
  7787.  
  7788.     /* GOTO, FORWARD, and _FORWARD (used internally by FOR, WHILE, etc) */
  7789.  
  7790.     if (cx == XXGOTO || cx == XXFWD || cx == XXXFWD) { /* GOTO or FORWARD */
  7791.     /* Note, here we don't set SUCCESS/FAILURE flag */
  7792. #ifdef COMMENT
  7793.     if ((y = cmfld("label","",&s,xxstring)) < 0) {
  7794.         if (y == -3) {
  7795.         if (cx != XXXFWD) {
  7796.             printf("?Label name required\n");
  7797.             return(-9);
  7798.         }
  7799.         } else
  7800.           return(y);
  7801.     }
  7802.     ckstrncpy(lblbuf,s,LBLSIZ);
  7803.     if ((x = cmcfm()) < 0) return(x);
  7804. #else
  7805.     if ((y = cmtxt("label","",&s,xxstring)) < 0) {
  7806.         if (y == -3) {
  7807.         if (cx != XXXFWD) {
  7808.             printf("?GOTO: Label name required: \"%s\" \"%s\"\n",
  7809.                atmbuf,
  7810.                cmdbuf);
  7811.             return(-9);
  7812.         }
  7813.         } else
  7814.           return(y);
  7815.     }
  7816.     ckstrncpy(lblbuf,brstrip(s),LBLSIZ);
  7817. #endif /* COMMENT */
  7818.     s = lblbuf;
  7819.     return(dogoto(s,cx));
  7820.     }
  7821.     if (cx == XXDO || cx == XXMACRO) {    /* DO (a macro) */
  7822.     char mnamebuf[16];        /* (buffer for controlled temp name) */
  7823.     struct FDB kw, fl;
  7824.     int mx;                /* Macro index (on stack!) */
  7825.  
  7826.     debug(F101,"XXMACRO 0",line,cx);
  7827.     if (cx == XXDO) {
  7828.         if (nmac == 0) {
  7829.         printf("\n?No macros defined\n");
  7830.         return(-9);
  7831.         }
  7832.         for (y = 0; y < nmac; y++) { /* copy the macro table into a */
  7833.         mackey[y].kwd = mactab[y].kwd; /* regular keyword table */
  7834.         mackey[y].kwval = y;    /* with value = pointer to macro tbl */
  7835.         mackey[y].flgs = mactab[y].flgs;
  7836.         }
  7837.         cmfdbi(&kw,            /* First FDB - macro name */
  7838.            _CMKEY,        /* fcode */
  7839.            "Macro",        /* hlpmsg */
  7840.            "",            /* default */
  7841.            "",            /* addtl string data */
  7842.            nmac,        /* addtl numeric data 1: tbl size */
  7843.            0,            /* addtl numeric data 2: 0 = cmkey */
  7844.            xxstring,        /* Processing function */
  7845.            mackey,        /* Keyword table */
  7846.            &fl            /* Pointer to next FDB */
  7847.            );
  7848.         cmfdbi(&fl,            /* 2nd FDB - for "{" */
  7849.            _CMFLD,        /* fcode */
  7850.            "",            /* hlpmsg */
  7851.            "",
  7852.            "",            /* addtl string data */
  7853.            0,            /* addtl numeric data 1 */
  7854.            0,            /* addtl numeric data 2 */
  7855.            xxstring,
  7856.            NULL,
  7857.            NULL
  7858.            );
  7859.         x = cmfdb(&kw);        /* Parse something */
  7860.         if (x < 0) {        /* Error */
  7861.         if (x == -3) {
  7862.             printf("?Macro name required\n");
  7863.             return(-9);
  7864.         } else
  7865.           return(x);
  7866.         }
  7867.         if (cmresult.fcode == _CMKEY) {
  7868.         extern int mtchanged;
  7869.         char * macroname = NULL;
  7870.  
  7871.         /* In case args include an \fexec() that changes the macro table */
  7872.  
  7873.         mx = x;            /* Save macro index on stack */
  7874.         mtchanged = 0;        /* Mark state of macro table */
  7875.         makestr(¯oname,mactab[mx].kwd); /* Save name */
  7876.  
  7877.         if ((y = cmtxt("optional arguments","",&s,xxstring)) < 0)
  7878.           return(y);        /* Get macro args */
  7879.  
  7880.         if (mtchanged) {    /* Macro table changed? */
  7881.             mx = mlook(mactab,macroname,nmac); /* Look up name again */
  7882.         }
  7883.         if (macroname)
  7884.           free(macroname);
  7885.  
  7886.         return(dodo(mx,s,cmdstk[cmdlvl].ccflgs) < 1 ?
  7887.                (success = 0) : 1);
  7888.         }
  7889.         ckstrncpy(line,cmresult.sresult,LINBUFSIZ);    /* _CMFLD */
  7890.         if (atmbuf[0] == '{') {
  7891.         if ((y = cmcfm()) < 0)
  7892.           return(y);
  7893.         }
  7894.     } else {            /* XXMACRO ("immediate macro") */
  7895.         int k = 0;
  7896.         line[k++] = '{';
  7897.         line[k++] = SP;
  7898.         line[k] = NUL;
  7899.         debug(F111,"XXMACRO A",line,k);
  7900.         /* Defer evaluation of variables until the commands are exec'd */
  7901.         if ((y = cmtxt("Braced list of commands","",&s,NULL)) < 0)
  7902.           return(y);
  7903.         k = ckstrncpy(line+k,s,LINBUFSIZ-k);
  7904.         debug(F111,"XXMACRO B",line,k);
  7905.     }
  7906.     x = strlen(line);
  7907.     if ((line[0] == '{' && line[x-1] != '}') || line[0] == '}')
  7908.       return(-2);
  7909.     if (line[0] != '{' && line[x-1] != '}') {
  7910.         /* Unknown command.  If ON_UNKNOWN_COMMAND macro is defined, */
  7911.         /* parse args and then execute it, but only if it is not */
  7912.         /* already active. */
  7913.         int k = -1;
  7914.         if (!unkmacro) {
  7915.         k = mxlook(mactab,"on_unknown_command",nmac);
  7916.         }
  7917.         if (k > -1) {
  7918.         ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ);
  7919.         z = maclvl;        /* Save the current maclvl */
  7920.         if ((y = cmtxt("text","",&s,xxstring)) < 0)
  7921.           return(y);
  7922.         ckstrncat(tmpbuf," ",TMPBUFSIZ);
  7923.         ckstrncat(tmpbuf,s,TMPBUFSIZ);
  7924.         unkmacro = 1;
  7925.         debug(F110,"ON_UNKNOWN_COMMAND",s,0);
  7926.         dodo(k,tmpbuf,cmdstk[cmdlvl].ccflgs); /* Run the macro */
  7927.         while (maclvl > z) {
  7928.             sstate = (CHAR) parser(1);
  7929.             if (sstate) proto();
  7930.         }
  7931.         debug(F101,"UNKMAC loop exit maclvl","",maclvl);
  7932.         unkmacro = 0;
  7933.         return(success);
  7934.         }
  7935.             if (x > 0)
  7936.           printf("?Not a command or macro name: \"%s\"\n",line);
  7937.             else
  7938.           printf("?Not a command or macro name.\n");
  7939.         return(-9);
  7940.     }
  7941.     s = brstrip(line);
  7942.     sprintf(mnamebuf," ..tmp:%03d",cmdlvl);    /* safe (16) */
  7943.     x = addmac(mnamebuf,s);
  7944.     return(dodo(x,NULL,cmdstk[cmdlvl].ccflgs) < 1 ? (success = 0) : 1);
  7945.     }
  7946.  
  7947.     if (cx == XXLBL) {            /* LABEL */
  7948.     if ((x = cmfld("label","",&s,xxstring)) < 0) {
  7949.         if (x == -3) {
  7950. #ifdef COMMENT
  7951.         printf("?LABEL: Label name required: \"%s\"\n", cmdbuf);
  7952.         return(-9);
  7953. #else
  7954.         s = "";
  7955. #endif /* COMMENT */
  7956.         } else return(x);
  7957.  
  7958.     }
  7959.     debug(F111,"LABEL",s,x);
  7960.     if ((x = cmcfm()) < 0) return(x);
  7961.     return(0);
  7962.     }
  7963.  
  7964.     if (cx == XXEVAL || cx == XX_EVAL) /* _EVALUATE,  EVALUATE  */
  7965.       return(doeval(cx));
  7966.  
  7967. #ifndef NOSEXP
  7968.     if (cx == XXSEXP) {            /* Lisp-like S-Expression */
  7969.     struct stringarray * q;
  7970.     char /* *p, *r, */ *tmp, *m;
  7971.     int i, k, n, quote = 0, contd = 0, size = 0, len = 0;
  7972.     extern int sexprc, sexppv;
  7973.  
  7974.     tmp = tmpbuf;            /* Buffer to collect SEXP */
  7975.     tmpbuf[0] = NUL;        /* Clear it */
  7976.     size = TMPBUFSIZ;        /* Capacity of buffer */
  7977.     sexprc = -1;            /* Assume bad input */
  7978.     n = 0;                /* Paren balance counter */
  7979.  
  7980.     while (1) {            /* Allow SEXP on multiple lines */
  7981.         m = contd ?
  7982.           "Continuation of S-Expression" :
  7983.         "S-Expression (\"help sexp\" for details)";
  7984.         x = cmtxt(m,"",&s,xxstring);
  7985.         if (x < 0)
  7986.           return(x);
  7987.         if (!*s)            /* Needed for (=) and (:) */
  7988.           s = atmbuf;
  7989.         k = ckmakmsg(tmp, size, contd ? " " : "(", s, NULL, NULL);
  7990.         if (k < 1) {
  7991.         printf("?SEXP too long - %d max\n",TMPBUFSIZ);
  7992.         return(-9);
  7993.         }
  7994.         debug(F111,contd ? "sexp contd" : "sexp",s,k);
  7995.  
  7996.         for (i = len; i < len+k; i++) { /* Check balance  */
  7997.         if (!quote && tmpbuf[i] == CMDQ) {
  7998.             quote = 1;
  7999.             continue;
  8000.         }
  8001.         if (quote) {
  8002.             quote = 0;
  8003.             continue;
  8004.         }
  8005.         if (tmpbuf[i] == '(')
  8006.           n++;
  8007.         else if (tmpbuf[i] == ')')
  8008.           n--;
  8009.         }
  8010.         if (n == 0) {        /* Break when balanced */
  8011.         break;
  8012.         }
  8013.         if (n < 0) {        /* Too many right parens */
  8014.         printf("?Unbalanced S-Expression: \"%s\"\n",tmpbuf);
  8015.         return(-9);
  8016.         }
  8017.         contd++;            /* Need more right parens */
  8018.         cmini(ckxech);        /* so keep parsing */
  8019.         tmp += k;            /* adjust buffer pointer */
  8020.         size -= k;            /* and capacity */
  8021.         len += k;            /* and length so far */
  8022.     }
  8023.     s = tmpbuf;
  8024.     makestr(&lastsexp,s);
  8025.     q = cksplit(1,SEXPMAX,s,NULL,NULL,8,0,0); /* Precheck for > 1 SEXP */
  8026.     debug(F101,"sexp split","",q->a_size);
  8027.  
  8028.     if (q->a_size == 1) {        /* We should get exactly one back */
  8029.         char * result, * dosexp();
  8030.         sexprc = 0;            /* Reset out-of-band return code */
  8031.         result = dosexp(s);        /* Get result */
  8032.         debug(F111,"sexp result",result,sexprc);
  8033.         if (sexprc == 0) {        /* Success */
  8034.         /* Echo the result if desired */
  8035.         if ((!xcmdsrc && sexpecho != SET_OFF) || sexpecho == SET_ON)
  8036.           printf(" %s\n",result ? result : "");
  8037.         makestr(&sexpval,result);
  8038.         success = sexppv > -1 ? sexppv : 1;
  8039.         return(success);
  8040.         }
  8041.     }
  8042.     if (sexprc < 0)
  8043.       printf("?Invalid S-Expression: \"%s\"\n",lastsexp);
  8044.     return(-9);
  8045.     }
  8046. #endif /* NOSEXP */
  8047.  
  8048. #endif /* NOSPL */
  8049.  
  8050.     if (cx == XXECH || cx == XXXECH || cx == XXVOID
  8051. #ifndef NOSPL
  8052.     || cx == XXAPC
  8053. #endif /* NOSPL */
  8054.     ) {                /* ECHO or APC */
  8055.     if ((x = cmtxt((cx == XXECH || cx == XXXECH) ?
  8056.                "Text to be echoed" :
  8057.                ((cx == XXVOID) ? "Text" :
  8058.             "Application Program Command text"),
  8059.                "",
  8060.                &s,
  8061.                xxstring
  8062.                )
  8063.          ) < 0)
  8064.       return(x);
  8065.     if (!s) s = "";
  8066. #ifdef COMMENT
  8067. /* This is to preserver the pre-8.0 behavior but it's too confusing */
  8068.     x = strlen(s);
  8069.     x = (x > 1) ? ((s[0] == '"' && s[x-1] == '"') ? 1 : 0) : 0;
  8070. #endif /* COMMENT */
  8071.     s = brstrip(s);            /* Strip braces and doublequotes */
  8072.     if (cx == XXECH) {        /* ECHO */
  8073. #ifndef NOSPL
  8074.         if (!fndiags || fnsuccess) {
  8075. #endif /* NOSPL */
  8076. #ifdef COMMENT
  8077.         /* The "if (x)" business preserves previous behavior */
  8078.         /* by putting back the doublequotes if they were included. */
  8079.         if (x)
  8080.           printf("\"%s\"\n",s);
  8081.         else
  8082. #endif /* COMMENT */
  8083.           printf("%s\n",s);
  8084. #ifndef NOSPL
  8085.         }
  8086. #endif /* NOSPL */
  8087.     } else if (cx == XXXECH) {    /* XECHO */
  8088.         if (x)
  8089.           printf("\"%s\"",s);
  8090.         else
  8091.           printf("%s",s);
  8092. #ifdef UNIX
  8093.         fflush(stdout);
  8094. #endif /* UNIX */
  8095.     } else if (cx == XXAPC) {    /* APC */
  8096. #ifdef CK_APC
  8097.         if (apcactive == APC_LOCAL ||
  8098.         (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
  8099.           return(success = 0);
  8100. #endif /* CK_APC */
  8101.         if (!local) {
  8102.         printf("%c_%s%c\\",ESC,s,ESC);
  8103. #ifdef UNIX
  8104.         fflush(stdout);
  8105. #endif /* UNIX */
  8106.  
  8107.         } else {            /* Local mode - have connection */
  8108. #ifndef NOSPL
  8109.         if (ckmakxmsg(tmpbuf,    /* Form APC string in buffer */
  8110.                   TMPBUFSIZ,
  8111.                   ckctoa((char)ESC),
  8112.                   ckctoa('_'),
  8113.                   s,
  8114.                   ckctoa((char)ESC),
  8115.                   ckctoa('\\'),
  8116.                   NULL,NULL,NULL,NULL,NULL,NULL,NULL
  8117.                   ) > 0)
  8118.           return(success = dooutput(tmpbuf, XXOUT));
  8119.         printf("?Too long\n");
  8120.         return(-9);
  8121. #else
  8122.         printf("%c_%s%c\\",ESC,s,ESC);
  8123. #endif /* NOSPL */
  8124.         }
  8125.     }
  8126.     return(success = 1);
  8127.     }
  8128.  
  8129. #ifndef NOSPL
  8130. /* Copy macro args from/to two levels up, used internally by _floop et al. */
  8131.     if (cx == XXGTA || cx == XXPTA) {    /* _GETARGS, _PUTARGS */
  8132.     int x;
  8133.     debug(F101,"docmd XXGTA","",XXGTA);
  8134.     debug(F101,"docmd cx","",cx);
  8135.     debug(F101,"docmd XXGTA maclvl","",maclvl);
  8136.     x = dogta(cx);
  8137.     debug(F101,"docmd dogta returns","",x);
  8138.     debug(F101,"docmd dogta maclvl","",maclvl);
  8139.     return(x);
  8140.     }
  8141. #endif /* NOSPL */
  8142.  
  8143. #ifndef NOSPL
  8144. #ifdef CKCHANNELIO
  8145.     if (cx == XXFILE)
  8146.       return(dofile(cx));
  8147.     else if (cx == XXF_RE || cx == XXF_WR || cx == XXF_OP ||
  8148.          cx == XXF_CL || cx == XXF_SE || cx == XXF_RW ||
  8149.          cx == XXF_FL || cx == XXF_LI || cx == XXF_ST || cx == XXF_CO)
  8150.       return(dofile(cx));
  8151. #endif /* CKCHANNELIO */
  8152.  
  8153. /* ASK, ASKQ, READ */
  8154.     if (cx == XXASK  || cx == XXASKQ || cx == XXREA ||
  8155.     cx == XXRDBL || cx == XXGETC || cx == XXGETK) {
  8156.     return(doask(cx));
  8157.     }
  8158. #endif /* NOSPL */
  8159.  
  8160. #ifndef NOFRILLS
  8161.     if (cx == XXBUG) {            /* BUG */
  8162.     if ((x = cmcfm()) < 0) return(x);
  8163.     return(dobug());
  8164.     }
  8165. #endif /* NOFRILLS */
  8166.  
  8167. #ifndef NOXFER
  8168.     if (cx == XXBYE) {            /* BYE */
  8169.     extern int ftp_cmdlin;
  8170.     if ((x = cmcfm()) < 0) return(x);
  8171.  
  8172. #ifdef NEWFTP
  8173.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) {
  8174.         extern int stayflg, ftp_fai;
  8175.         success = ftpbye();
  8176.         if (ftp_cmdlin && !stayflg && !local)
  8177.           doexit(ftp_fai ? BAD_EXIT : GOOD_EXIT,-1);
  8178.         else
  8179.           return(success);
  8180.     }
  8181. #endif /* NEWFTP */
  8182.  
  8183.     if (!local) {
  8184.         printf("?No connection - use EXIT to quit.\n");
  8185.         return(-9);
  8186.     }
  8187.  
  8188. #ifdef CK_XYZ
  8189.     if (protocol != PROTO_K) {
  8190.         printf("?Sorry, BYE only works with Kermit protocol\n");
  8191.         return(-9);
  8192.     }
  8193. #endif /* CK_XYZ */
  8194.  
  8195. #ifdef IKS_OPTION
  8196.         if (
  8197. #ifdef CK_XYZ
  8198.             protocol == PROTO_K &&
  8199. #endif /* CK_XYZ */
  8200.             !iks_wait(KERMIT_REQ_START,1)) {
  8201.         printf(
  8202.          "?A Kermit Server is not available to process this command\n");
  8203.         return(-9);            /* Correct the return code */
  8204.         }
  8205. #endif /* IKS_OPTION */
  8206.  
  8207.     bye_active = 1;
  8208.     sstate = setgen('L',"","","");
  8209.     if (local) ttflui();        /* If local, flush tty input buffer */
  8210.     return(0);
  8211.     }
  8212. #endif /* NOXFER */
  8213.  
  8214.     if (cx == XXBEEP) {            /* BEEP */
  8215.         int x;
  8216. #ifdef OS2
  8217.     int y;
  8218.         if ((y = cmkey(beeptab, nbeeptab, "which kind of beep", "information",
  8219.                xxstring)) < 0 )
  8220.       return (y);
  8221.         if ((x = cmcfm()) < 0) return(x);
  8222.         bleep((short)y);        /* y is one of the BP_ values */
  8223. #else  /* OS2 */
  8224.         if ((x = cmcfm()) < 0) return(x);
  8225. #ifndef NOSPL
  8226.         bleep(BP_NOTE);
  8227. #else
  8228.     putchar('\07');
  8229. #endif /* NOSPL */
  8230. #endif /* OS2 */
  8231.         return(0);
  8232.     }
  8233.  
  8234. #ifndef NOFRILLS
  8235.     if (cx == XXCLE)            /* CLEAR */
  8236.       return(success = doclear());
  8237. #endif /* NOFRILLS */
  8238.  
  8239.     if (cx == XXCOM) {            /* COMMENT */
  8240.     if ((x = cmtxt("Text of comment line","",&s,NULL)) < 0)
  8241.       return(x);
  8242.     /* Don't change SUCCESS flag for this one */
  8243.     return(0);
  8244.     }
  8245.  
  8246. #ifndef NOLOCAL
  8247.     if (cx == XXCON || cx == XXCQ)    /* CONNECT or CONNECT /QUIETLY */
  8248.       return(doxconn(cx));
  8249. #endif /* NOLOCAL */
  8250.  
  8251. #ifndef NOFRILLS
  8252. #ifdef ZCOPY
  8253.     if (cx == XXCPY) {            /* COPY a file */
  8254. #ifdef IKSD
  8255.     if (inserver && !ENABLED(en_cpy)) {
  8256.         printf("?Sorry, COPY is disabled\n");
  8257.         return(-9);
  8258.     }
  8259. #endif /* IKSD */
  8260. #ifdef CK_APC
  8261.     if (apcactive == APC_LOCAL ||
  8262.         (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
  8263.         )
  8264.       return(success = 0);
  8265. #endif /* CK_APC */
  8266.     return(docopy());
  8267.     }
  8268. #endif /* ZCOPY */
  8269. #ifdef NT
  8270.     if ( cx == XXLINK ) {
  8271. #ifdef IKSD
  8272.         if (inserver && !ENABLED(en_cpy)) {
  8273.             printf("?Sorry, LINK (COPY) is disabled\n");
  8274.             return(-9);
  8275.         }
  8276. #endif /* IKSD */
  8277. #ifdef CK_APC
  8278.         if (apcactive == APC_LOCAL ||
  8279.             (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
  8280.             )
  8281.           return(success = 0);
  8282. #endif /* CK_APC */
  8283.         return(dolink());
  8284.     }
  8285. #endif /* NT */
  8286. #endif /* NOFRILLS */
  8287.  
  8288.     /* CD and friends */
  8289.     if (cx == XXCWD  || cx == XXCDUP || cx == XXBACK ||
  8290.     cx == XXLCWD || cx == XXLCDU || cx == XXKCD) {
  8291. #ifdef LOCUS
  8292.     if (!locus) {
  8293.         if (cx == XXCWD) {
  8294. #ifdef NOXFER
  8295.                 return(-2);
  8296. #else
  8297.                 return(dormt(XZCWD));
  8298. #endif /* NOXFER */
  8299.         } else if (cx == XXCDUP) {
  8300. #ifdef NOXFER
  8301.                 return(-2);
  8302. #else
  8303.                 return(dormt(XZCDU));
  8304. #endif /* NOXFER */
  8305.             }
  8306.     }
  8307. #endif /* LOCUS */
  8308. #ifdef IKSD
  8309.     if (inserver && !ENABLED(en_cwd)) {
  8310.         printf("?Sorry, changing directories is disabled\n");
  8311.         return(-9);
  8312.     }
  8313. #endif /* IKSD */
  8314.     return(success = docd(cx));
  8315.     }
  8316.  
  8317.     if (cx == XXCHK)            /* CHECK */
  8318.       return(success = dochk());
  8319.  
  8320.     if (cx == XXCLO) {            /* CLOSE */
  8321.     x = cmkey(clstab,ncls,"\"CONNECTION\", or log or file to close",
  8322.           "connection",xxstring);
  8323.     if (x == -3) {
  8324.         printf("?You must say which file or log\n");
  8325.         return(-9);
  8326.     }
  8327.     if (x < 0) return(x);
  8328.     if ((y = cmcfm()) < 0) return(y);
  8329. #ifndef NOLOCAL
  8330.     if (x == 9999) {        /* CLOSE CONNECTION */
  8331.         x = clsconnx(0);
  8332.         switch (x) {
  8333.           case 0:
  8334.         if (msgflg) printf("?Connection was not open\n");
  8335.           case -1:
  8336.         return(0);
  8337.           case 1:
  8338.         whyclosed = WC_CLOS;
  8339.         return(1);
  8340.         }
  8341.         return(0);
  8342.     }
  8343. #endif /* NOLOCAL */
  8344.     y = doclslog(x);
  8345.     success = (y == 1);
  8346.     return(success);
  8347.     }
  8348.  
  8349. #ifndef NOSPL
  8350.     if (cx == XXDCL || cx == XXUNDCL) {    /* DECLARE an array */
  8351.     return(dodcl(cx));
  8352.     }
  8353. #endif /* NOSPL */
  8354.  
  8355. #ifndef NODIAL
  8356.     if (cx == XXRED  || cx == XXDIAL || cx == XXPDIA ||
  8357.     cx == XXANSW || cx == XXLOOK) { /* DIAL, REDIAL etc */
  8358. #ifdef VMS
  8359.     extern int batch;
  8360. #else
  8361. #ifdef UNIXOROSK
  8362.     extern int backgrd;
  8363. #endif /* UNIXOROSK */
  8364. #endif /* VMS */
  8365.     x = dodial(cx);
  8366.     debug(F101,"dodial returns","",x);
  8367.     if ((cx == XXDIAL || cx == XXRED || cx == XXANSW) &&
  8368.         (x > 0) &&            /* If DIAL or REDIAL succeeded */
  8369.         (dialsta != DIA_PART) &&    /* and it wasn't partial */
  8370.         (dialcon > 0)) {
  8371.         if ((dialcon == 1 ||    /* And DIAL CONNECT is ON, */
  8372.         ((dialcon == 2) &&    /* or DIAL CONNECT is AUTO */
  8373.          !xcmdsrc        /* and we're at top level... */
  8374. #ifdef VMS
  8375.          && !batch        /* Not if running from batch */
  8376. #else
  8377. #ifdef UNIXOROSK
  8378.          && !backgrd        /* Not if running in background */
  8379. #endif /* UNIXOROSK */
  8380. #endif /* VMS */
  8381.          ))) /* Or AUTO */
  8382.           x = doconect(dialcq,    /* Then also CONNECT */
  8383.                            cmdlvl == 0 ? 1 : 0
  8384.                );
  8385.         if (ttchk() < 0)
  8386.           dologend();
  8387.     }
  8388.     return(success = x);
  8389.     }
  8390. #endif /* NODIAL */
  8391.  
  8392. #ifndef NOPUSH
  8393. #ifdef CK_REXX
  8394.     if (cx == XXREXX) {            /* REXX */
  8395.         extern int nopush;
  8396.         if ( nopush )
  8397.           return(success=0);
  8398.         return(dorexx());
  8399.     }
  8400. #endif /* CK_REXX */
  8401. #endif /* NOPUSH */
  8402.  
  8403. #ifndef NOFRILLS
  8404.     if (cx == XXDEL || cx == XXLDEL) {    /* DELETE */
  8405. #ifdef LOCUS
  8406.     if (!locus && cx != XXLDEL) {
  8407. #ifdef NOXFER
  8408.         return(-2);
  8409. #else
  8410.         return(dormt(XZDEL));
  8411. #endif /* NOXFER */
  8412.         }
  8413. #endif /* LOCUS */
  8414. #ifdef IKSD
  8415.     if (inserver && (!ENABLED(en_del)
  8416. #ifdef CK_LOGIN
  8417.              || isguest
  8418. #endif /* CK_LOGIN */
  8419.              )) {
  8420.         printf("?Sorry, DELETE is disabled\n");
  8421.         return(-9);
  8422.     }
  8423. #endif /* IKSD */
  8424. #ifdef CK_APC
  8425.     if ((apcactive == APC_LOCAL) ||
  8426.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  8427.       return(success = 0);
  8428. #endif /* CK_APC */
  8429.     return(dodel());
  8430.     }
  8431. #endif /* NOFRILLS */
  8432.  
  8433.     if (cx == XXDIR || cx == XXLS || cx == XXLDIR) { /* DIRECTORY or LS */
  8434. #ifdef LOCUS
  8435.     if (!locus && cx != XXLDIR) {
  8436. #ifdef NOXFER
  8437.         return(-2);
  8438. #else
  8439.         return(dormt(XZDIR));
  8440. #endif /* NOXFER */
  8441.         }
  8442. #endif /* LOCUS */
  8443. #ifdef IKSD
  8444.     if (inserver && !ENABLED(en_dir)) {
  8445.         printf("?Sorry, DIRECTORY is disabled\n");
  8446.         return(-9);
  8447.     }
  8448. #endif /* IKSD */
  8449.     return(dodir(cx));
  8450.     }
  8451.  
  8452. #ifndef NOSPL
  8453.     if (cx == XXELS)            /* ELSE */
  8454.       return(doelse());
  8455. #endif /* NOSPL */
  8456.  
  8457. #ifndef NOSERVER
  8458. #ifndef NOFRILLS
  8459.     if (cx == XXENA || cx == XXDIS) {    /* ENABLE, DISABLE */
  8460.     s = (cx == XXENA) ?
  8461.       "Server function to enable" :
  8462.         "Server function to disable";
  8463.  
  8464.     if ((x = cmkey(enatab,nena,s,"",xxstring)) < 0) {
  8465.         if (x == -3) {
  8466.         printf("?Name of server function required\n");
  8467.         return(-9);
  8468.         } else return(x);
  8469.     }
  8470.     if ((y = cmkey(kmstab,3,"mode","both",xxstring)) < 0) {
  8471.         if (y == -3) {
  8472.         printf("?Please specify remote, local, or both\n");
  8473.         return(-9);
  8474.         } else return(y);
  8475.     }
  8476.     if (cx == XXDIS)        /* Disabling, not enabling */
  8477.       y = 3 - y;
  8478.     if ((z = cmcfm()) < 0) return(z);
  8479. #ifdef CK_APC
  8480.     if ((apcactive == APC_LOCAL) ||
  8481.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  8482.       return(success = 0);
  8483. #endif /* CK_APC */
  8484. #ifdef IKSD
  8485.         /* This may seem like it duplicates the work in doenable()  */
  8486.         /* but this code returns failure whereas doenable() returns */
  8487.         /* success.                                                 */
  8488.         if (inserver &&
  8489. #ifdef IKSDCONF
  8490.             iksdcf &&
  8491. #endif /* IKSDCONF */
  8492.             (x == EN_HOS || x == EN_PRI || x == EN_MAI || x == EN_WHO ||
  8493.               isguest))
  8494.             return(success = 0);
  8495. #endif /* IKSD */
  8496.     return(doenable(y,x));
  8497.     }
  8498. #endif /* NOFRILLS */
  8499. #endif /* NOSERVER */
  8500.  
  8501. #ifndef NOSPL
  8502.     if (cx == XXRET) {            /* RETURN */
  8503.     if ((x = cmtxt("Optional return value","",&s,NULL)) < 0)
  8504.       return(x);
  8505.     s = brstrip(s);            /* Strip braces */
  8506.     if (cmdlvl == 0)        /* At top level, nothing happens... */
  8507.       return(success = 1);
  8508.     switch (cmdstk[cmdlvl].src) {    /* Action depends on command source */
  8509.       case CMD_TF:            /* Command file */
  8510.         popclvl();            /* Pop command level */
  8511.         return(success = 1);    /* always succeeds */
  8512.       case CMD_MD:            /* Macro */
  8513.       case CMD_KB:            /* Prompt */
  8514.         return(doreturn(s));    /* Trailing text is return value. */
  8515.       default:            /* Shouldn't happen */
  8516.         return(-2);
  8517.     }
  8518.     }
  8519. #endif /* NOSPL */
  8520.  
  8521. #ifndef NOSPL
  8522.     if (cx == XXOPE)            /* OPEN */
  8523.       return(doopen());
  8524. #endif /* NOSPL */
  8525.  
  8526. #ifndef NOSPL
  8527.     if (cx == XXOUT || cx == XXLNOUT) {    /* OUTPUT or LINEOUT */
  8528.     if ((x = cmtxt("Text to be output","",&s,NULL)) < 0)
  8529.       return(x);
  8530. #ifdef CK_APC
  8531.     if ((apcactive == APC_LOCAL) ||
  8532.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  8533.       return(success = 0);
  8534. #endif /* CK_APC */
  8535.     debug(F110,"OUTPUT 1",s,0);
  8536.     s = brstrip(s);            /* Strip enclosing braces, */
  8537.     debug(F110,"OUTPUT 2",s,0);
  8538. /*
  8539.   I don't think I could ever fully explain this in a million years...
  8540.   We have read the user's string without calling the variable-expander
  8541.   function.  Now, before we call it, we have to double backslashes that
  8542.   appear before \N, \B, \L, and \ itself, so the expander function will
  8543.   reduce them back to single backslashes, so when we call dooutput()...
  8544.   But it's more complicated than that.
  8545. */
  8546.     if (cmdgquo()) {        /* Only if COMMAND QUOTING ON ... */
  8547.         for (x = 0, y = 0; s[x]; x++, y++) {
  8548.         if (s[x] == CMDQ) {
  8549.             char c = s[x+1];
  8550.             if (c == 'n' || c == 'N' ||
  8551.             c == 'b' || c == 'B' ||
  8552.             c == 'l' || c == 'L' ||
  8553.             c == CMDQ)
  8554.               line[y++] = CMDQ;
  8555.         }
  8556.         line[y] = s[x];
  8557.         }
  8558.         line[y++] = '\0';        /* Now expand variables, etc. */
  8559.         debug(F110,"OUTPUT 3",line,0);
  8560.         s = line+y+1;
  8561.         x = LINBUFSIZ - (int) strlen(line) - 1;
  8562.         debug(F101,"OUTPUT size","",x);
  8563.         if (zzstring(line,&s,&x) < 0)
  8564.           return(success = 0);
  8565.         s = line+y+1;
  8566.         debug(F110,"OUTPUT 4",s,0);
  8567.     }
  8568.     success = dooutput(s,cx);
  8569.     return(success);
  8570.     }
  8571. #endif /* NOSPL */
  8572.  
  8573. #ifdef ANYX25
  8574. #ifndef IBMX25
  8575.     if (cx == XXPAD) {            /* PAD commands */
  8576.     x = cmkey(padtab,npadc,"PAD command","",xxstring);
  8577.     if (x == -3) {
  8578.         printf("?You must specify a PAD command to execute\n");
  8579.         return(-9);
  8580.     }
  8581.     if (x < 0) return(x);
  8582.  
  8583.     switch (x) {
  8584.       case XYPADL:
  8585.         if (x25stat() < 0)
  8586.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  8587.         else {
  8588.         x25clear();
  8589.         initpad();
  8590.         }
  8591.         break;
  8592.       case XYPADS:
  8593.         if (x25stat() < 0)
  8594.           printf("Not connected\r\n");
  8595.         else {
  8596.         extern int linkid, lcn;
  8597.         conol("Connected thru ");
  8598.         conol(ttname);
  8599.         printf(", Link id %d, Logical channel number %d\r\n",
  8600.                linkid,lcn);
  8601.         }
  8602.         break;
  8603.       case XYPADR:
  8604.         if (x25stat() < 0)
  8605.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  8606.         else
  8607.           x25reset(0,0);
  8608.         break;
  8609.       case XYPADI:
  8610.         if (x25stat() < 0)
  8611.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  8612.         else
  8613.           x25intr(0);
  8614.     }
  8615.     return(0);
  8616.     }
  8617. #endif /* IBMX25 */
  8618. #endif /* ANYX25 */
  8619.  
  8620. #ifndef NOSPL
  8621.     if (cx == XXPAU || cx == XXWAI || cx == XXMSL) /* PAUSE, WAIT, etc */
  8622.       return(dopaus(cx));
  8623. #endif /* NOSPL */
  8624.  
  8625. #ifndef NOFRILLS
  8626.     if (cx == XXPRI) {
  8627. #ifdef IKSD
  8628. #ifdef CK_LOGIN
  8629.     if (inserver && (isguest || !ENABLED(en_pri))) {
  8630.         printf("?Sorry, printing is disabled\n");
  8631.         return(-9);
  8632.     }
  8633. #endif /* CK_LOGIN */
  8634. #endif /* IKSD */
  8635.     if ((x = cmifi("File to print","",&s,&y,xxstring)) < 0) {
  8636.         if (x == -3) {
  8637.         printf("?A file specification is required\n");
  8638.         return(-9);
  8639.         } else return(x);
  8640.     }
  8641.     if (y != 0) {
  8642.         printf("?Wildcards not allowed\n");
  8643.         return(-9);
  8644.     }
  8645.     ckstrncpy(line,s,LINBUFSIZ);
  8646.     s = "";
  8647. #ifndef NT
  8648.     if ((x = cmtxt("Local print command options, or carriage return","",&s,
  8649.                xxstring)) < 0)
  8650.       return(x);
  8651. #endif /* NT */
  8652.     if ((x = cmcfm()) < 0)
  8653.       return(x);
  8654.     return(success = (zprint(s,line) == 0) ? 1 : 0);
  8655.     }
  8656. #endif /* NOFRILLS */
  8657.  
  8658. #ifdef TCPSOCKET
  8659. #ifndef NOPUSH
  8660.     if (cx == XXPNG)             /* PING an IP host */
  8661.       return(doping());
  8662. #endif /* NOPUSH */
  8663.  
  8664. #ifndef NOFTP
  8665.     if (cx == XXFTP)            /* FTP */
  8666. #ifdef SYSFTP
  8667. #ifndef NOPUSH
  8668.       return(doftp());            /* Just runs system's ftp program */
  8669. #else
  8670.       return(-2);
  8671. #endif /* NOPUSH */
  8672. #else
  8673.     return(doxftp());
  8674. #endif /* SYSFTP */
  8675. #endif /* NOFTP */
  8676. #endif /* TCPSOCKET */
  8677.  
  8678.     if (cx == XXPWD || cx == XXLPWD) {    /* PWD */
  8679. #ifdef OS2
  8680.     char *pwp;
  8681. #endif /* OS2 */
  8682.     if ((x = cmcfm()) < 0)
  8683.       return(x);
  8684. #ifdef LOCUS
  8685.     if (!locus && cx != XXLPWD) {
  8686. #ifdef NOXFER
  8687.         return(-2);
  8688. #else
  8689.         return(dormt(XZPWD));
  8690. #endif /* NOXFER */
  8691.         }
  8692. #endif /* LOCUS */
  8693.  
  8694. #ifndef MAC
  8695. #ifndef OS2
  8696. #ifdef UNIX
  8697.     printf("%s\n",zgtdir());
  8698. #else
  8699.     xsystem(PWDCMD);
  8700. #endif /* UNIX */
  8701.     return(success = 1);        /* Blind faith */
  8702. #else  /* OS2 */
  8703.     if (pwp = zgtdir()) {
  8704.         if (*pwp) {
  8705. #ifdef NT
  8706.         line[0] = NUL;
  8707.         ckGetLongPathName(pwp,line,LINBUFSIZ);
  8708.         line[LINBUFSIZ-1] = NUL;
  8709.         tmpbuf[0] = NUL;
  8710.         GetShortPathName(pwp,tmpbuf,TMPBUFSIZ);
  8711.         tmpbuf[TMPBUFSIZ-1] = NUL;
  8712.         pwp = line;
  8713.         if (!strcmp(line,tmpbuf)) {
  8714. #endif /* NT */
  8715.             printf("%s\n",pwp);
  8716. #ifdef NT
  8717.         } else {
  8718.             printf("  Long name:  %s\n",line);
  8719.             printf("  Short name: %s\n",tmpbuf);
  8720.         }            
  8721. #endif /* NT */
  8722.         }
  8723.         return(success = ((int)strlen(pwp) > 0));
  8724.     } else return(success = 0);
  8725. #endif /* OS2 */
  8726. #else  /* MAC */
  8727.     if (pwp = zgtdir()) {
  8728.         printf("%s\n",pwp);
  8729.         return(success = ((int)strlen(pwp) > 0));
  8730.     } else return(success = 0);
  8731. #endif /* MAC */
  8732.     }
  8733.  
  8734.     if (cx == XXQUI || cx == XXEXI) {    /* EXIT, QUIT */
  8735.     extern int quitting;
  8736.  
  8737.     if ((y = cmnum("exit status code",ckitoa(xitsta),10,&x,xxstring)) < 0)
  8738.       return(y);
  8739.     if ((y = cmtxt("Optional EXIT message","",&s,xxstring)) < 0)
  8740.       return(y);
  8741.     s = brstrip(s);
  8742.     ckstrncpy(line,s,LINBUFSIZ);
  8743.  
  8744.     if (!hupok(0))            /* Check if connection still open */
  8745.       return(success = 0);
  8746.  
  8747.     if (line[0])            /* Print EXIT message if given */
  8748.       printf("%s\n",(char *)line);
  8749.  
  8750.     quitting = 1;            /* Flag that we are quitting. */
  8751.  
  8752. #ifdef VMS
  8753.     doexit(GOOD_EXIT,x);
  8754. #else
  8755. #ifdef OSK
  8756. /* Returning any codes here makes the OS-9 shell print an error message. */
  8757.     doexit(GOOD_EXIT,-1);
  8758. #else
  8759. #ifdef datageneral
  8760.         doexit(GOOD_EXIT,x);
  8761. #else
  8762.     doexit(x,-1);
  8763. #endif /* datageneral */
  8764. #endif /* OSK */
  8765. #endif /* VMS */
  8766.     }
  8767.  
  8768. #ifndef NOXFER
  8769. #ifndef NOFRILLS
  8770.     if (cx == XXERR) {            /* ERROR */
  8771. #ifdef CK_XYZ
  8772.     if (protocol != PROTO_K) {
  8773.         printf("Sorry, E-PACKET only works with Kermit protocol\n");
  8774.         return(-9);
  8775.     }
  8776. #endif /* CK_XYZ */
  8777.     if ((x = cmcfm()) < 0) return(x);
  8778.     ttflui();
  8779.     epktflg = 1;
  8780.     sstate = 'a';
  8781.     return(0);
  8782.     }
  8783. #endif /* NOFRILLS */
  8784.  
  8785.     if (cx == XXFIN) {            /* FINISH */
  8786. #ifdef NEWFTP
  8787.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  8788.       return(ftpbye());
  8789. #endif /* NEWFTP */
  8790. #ifdef CK_XYZ
  8791.     if (protocol != PROTO_K) {
  8792.         printf("Sorry, FINISH only works with Kermit protocol\n");
  8793.         return(-9);
  8794.     }
  8795. #endif /* CK_XYZ */
  8796.     if ((x = cmcfm()) < 0) return(x);
  8797.  
  8798. #ifdef IKS_OPTION
  8799.         if (
  8800. #ifdef CK_XYZ
  8801.             protocol == PROTO_K &&
  8802. #endif /* CK_XYZ */
  8803.             !iks_wait(KERMIT_REQ_START,1)) {
  8804.         printf(
  8805.               "?A Kermit Server is not available to process this command\n");
  8806.         return(-9);            /* Correct the return code */
  8807.         }
  8808. #endif /* IKS_OPTION */
  8809.  
  8810.     sstate = setgen('F',"","","");
  8811.     if (local) ttflui();        /* If local, flush tty input buffer */
  8812.     return(0);
  8813.     }
  8814. #endif /* NOXFER */
  8815.  
  8816. #ifndef NOSPL
  8817.     if (cx == XXFOR)            /* FOR loop */
  8818.       return(dofor());
  8819. #endif /* NOSPL */
  8820.  
  8821. #ifndef NOXFER
  8822.     /* GET MGET REGET RETRIEVE etc */
  8823.     if (cx == XXGET || cx == XXMGET || cx == XXREGET || cx == XXRETR) {
  8824. #ifdef IKSD
  8825.     if (inserver && !ENABLED(en_sen)) {
  8826.         printf("?Sorry, reception of files is disabled\n");
  8827.         return(-9);
  8828.     }
  8829. #endif /* IKSD */
  8830.     return(doxget(cx));
  8831.     }
  8832. #endif /* NOXFER */
  8833.  
  8834. #ifndef NOSPL
  8835. #ifndef NOFRILLS
  8836.     if (cx == XXGOK) {            /* GETOK */
  8837.     return(success = doask(cx));
  8838.     }
  8839. #endif /* NOFRILLS */
  8840. #endif /* NOSPL */
  8841.  
  8842.     if (cx == XXHLP) {            /* HELP */
  8843. #ifdef NOHELP
  8844.     return(dohlp(XXHLP));
  8845. #else
  8846.     x = cmkey2(cmdtab,ncmd,"\nCommand or topic","help",toktab,xxstring,3);
  8847.     debug(F101,"HELP command x","",x);
  8848.     if (x == -5) {
  8849.         y = chktok(toktab);
  8850.         debug(F101,"HELP cmkey token","",y);
  8851.         /* ungword(); */
  8852.         switch (y) {
  8853. #ifndef NOPUSH
  8854.           case '!': x = XXSHE; break;
  8855. #endif /* NOPUSH */
  8856.           case '#': x = XXCOM; break;
  8857.           case ';': x = XXCOM; break;
  8858. #ifndef NOSPL
  8859.               case '.': x = XXDEF; break;
  8860.           case ':': x = XXLBL; break;
  8861. #ifndef NOSEXP
  8862.           case '(': x = XXSEXP; break;
  8863. #endif /* NOSEXP */
  8864. #endif /* NOSPL */
  8865.           case '&': x = XXECH; break;
  8866.           default:
  8867.         printf("\n?Invalid - %s\n",cmdbuf);
  8868.         x = -2;
  8869.         }
  8870.     }
  8871.     makestr(&hlptok,atmbuf);
  8872.     debug(F111,"HELP token",hlptok,x);
  8873.     return(dohlp(x));
  8874. #endif /* NOHELP */
  8875.     }
  8876.  
  8877. #ifndef NOHELP
  8878.     if (cx == XXINT)            /* INTRO */
  8879.       return(hmsga(introtxt));
  8880.     if (cx == XXNEW) {            /* NEWS */
  8881.     int x;
  8882.     extern char * k_info_dir;
  8883.     x = hmsga(newstxt);
  8884.     return(x);
  8885.     }
  8886.  
  8887. #ifdef OS2ONLY
  8888.     if (cx == XXUPD) {            /* View UPDATE file */
  8889.         extern char exedir[];
  8890.         char * pTopic;
  8891.         char updstr[2048];
  8892.         if ((x = cmtxt("topic name","",&pTopic,xxstring)) < 0)
  8893.             return x;
  8894. #ifdef COMMENT
  8895.     sprintf(updstr,
  8896.         "start view %s\\docs\\k2.inf+%s\\docs\\using_ck.inf+\
  8897. %s\\docs\\dialing.inf+%s\\docs\\modems.inf %s",
  8898.         exedir,exedir,exedir,exedir,pTopic
  8899.         );
  8900. #else
  8901.     if (ckmakxmsg(updstr,
  8902.              2048,
  8903.              "start view ",
  8904.              exedir,
  8905.              "\\docs\\k2.inf+",
  8906.              exedir,
  8907.              "\\docs\\using_ck.inf+",
  8908.              exedir,
  8909.              "\\docs\\dialing.inf+",
  8910.              exedir,
  8911.              "\\docs\\modems.inf ",
  8912.              pTopic,
  8913.              NULL,
  8914.              NULL
  8915.              ) > 0)
  8916. #endif /* COMMENT */
  8917.       system(updstr);
  8918.         return(success = 1);
  8919.     }
  8920. #endif /* OS2ONLY */
  8921. #endif /* NOHELP */
  8922.  
  8923. #ifndef NOLOCAL
  8924.     if (cx == XXHAN) {            /* HANGUP */
  8925.     if ((x = cmcfm()) < 0) return(x);
  8926. #ifdef NEWFTP
  8927.     if ((ftpget == 1) || ((ftpget == 2) && !local && ftpisopen()))
  8928.       return(success = ftpbye());
  8929. #endif /* NEWFTP */
  8930. #ifndef NODIAL
  8931.     if ((x = mdmhup()) < 1) {
  8932.         debug(F101,"HANGUP mdmup","",x);
  8933. #endif /* NODIAL */
  8934.         x = tthang();
  8935.         debug(F101,"HANGUP tthang","",x);
  8936.         x = (x > -1);
  8937. #ifndef NODIAL
  8938.     }
  8939.     dialsta = DIA_UNK;
  8940. #endif /* NODIAL */
  8941.     whyclosed = WC_CLOS;
  8942.     ttchk();            /* In case of CLOSE-ON-DISCONNECT */
  8943.     dologend();
  8944. #ifdef OS2
  8945.     if (x)
  8946.       DialerSend(OPT_KERMIT_HANGUP, 0);
  8947. #endif /* OS2 */
  8948.     if (x) haveline = 0;
  8949.     return(success = x);
  8950.     }
  8951. #endif /* NOLOCAL */
  8952.  
  8953. #ifndef NOSPL
  8954.     /* INPUT, REINPUT, and MINPUT */
  8955.  
  8956.     if (cx == XXINP || cx == XXREI || cx == XXMINP) {
  8957.     long zz;
  8958.     extern int x_ifnum, ispattern, isjoin;
  8959.     zz = -1L;
  8960.     x_ifnum = 1;            /* Turn off internal complaints */
  8961.     y = cmnum("Seconds to wait for input,\n or time of day hh:mm:ss",
  8962.           ckitoa(indef), 10, &x, xxstring
  8963.           );
  8964.     x_ifnum = 0;
  8965.     if (y < 0) {
  8966.         if (y == -2) {        /* Invalid number or expression */
  8967.         zz = tod2sec(atmbuf);    /* Convert to secs since midnight */
  8968.         if (zz < 0L) {
  8969.             printf("?Number, expression, or time of day required\n");
  8970.             return(-9);
  8971.         } else {
  8972.             char now[32];    /* Current time */
  8973.             char *p;
  8974.             long tnow;
  8975.             p = now;
  8976.             ztime(&p);
  8977.             tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
  8978.             if (zz < tnow)    /* User's time before now */
  8979.               zz += 86400L;    /* So make it tomorrow */
  8980.             zz -= tnow;        /* Seconds from now. */
  8981.         }
  8982.         } else
  8983.           return(y);
  8984.     }
  8985.     if (zz > -1L) {
  8986.         x = zz;
  8987.         if (zz != (long) x) {
  8988.         printf(
  8989. "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
  8990.                );
  8991.         return(-9);
  8992.         }
  8993.     }
  8994.  
  8995. #ifdef CK_MINPUT
  8996.     for (y = 0; y < MINPMAX; y++) {    /* Initialize strings */
  8997.         mp[y] = 0;            /* Assume it's not a pattern */
  8998.         if (ms[y]) {
  8999.         free(ms[y]);        /* Free old strings, if any */
  9000.         ms[y] = NULL;
  9001.         }
  9002.     }
  9003.     if (cx == XXMINP) {        /* MINPUT */
  9004.         int i, k = 0, n = 0;
  9005.         struct stringarray * q;
  9006.         while (k < MINPMAX) {
  9007.         if ((y = cmfld("String or pattern","",&s,xxstring)) < 0) {
  9008.             if (y == -3) {
  9009.             if ((y = cmcfm()) < 0)
  9010.               return(y);
  9011.             break;
  9012.             } else {
  9013.             return(y);
  9014.             }
  9015.         }
  9016.         debug(F111,"MINPUT field",s,k);
  9017.         if (isjoin) {
  9018.             if ((q = cksplit(1,0,s," ",NULL,3,0,0))) {
  9019.             char ** ap = q->a_head;
  9020.             n = q->a_size;
  9021.             debug(F101,"minput cksplit size","",n);
  9022.             for (i = 1; i <= n && k < MINPMAX; i++) {
  9023.                 if (!ap[i]) /* Add non-empty elements */
  9024.                   continue;
  9025.                 if (!*(ap[i]))
  9026.                   continue;
  9027.                 makestr(&(ms[k]),ap[i]);
  9028.                 debug(F111,"MINPUT JOIN",ms[k],k);
  9029.                 k++;
  9030.             }
  9031.             }
  9032.         } else {
  9033.             if (s) if (*s) {
  9034.             makestr(&(ms[k]),s);
  9035.             if (ispattern) mp[k] = 1;
  9036.             debug(F111,"MINPUT",ms[k],ispattern);
  9037.             k++;
  9038.             }
  9039.         }
  9040.         }
  9041.     } else {
  9042. #endif /* CK_MINPUT */
  9043.  
  9044.         /* INPUT or REINPUT */
  9045.  
  9046.         if ((y = cmtxt("Material to be input","",&s,xxstring)) < 0)
  9047.           return(y);
  9048.         mp[0] = ispattern ? 1 : 0;
  9049.         makestr(&(ms[0]),brstrip(s));
  9050.         ms[1] = NULL;
  9051.  
  9052. #ifdef CK_MINPUT
  9053.     }
  9054. #endif /* CK_MINPUT */
  9055.  
  9056.     if (cx == XXINP || cx == XXMINP) { /* Not REINPUT... */
  9057.         i_active = 1;
  9058.         success = doinput(x,ms,mp);    /* Go try to input the search string */
  9059.         i_active = 0;
  9060.     } else {            /* REINPUT */
  9061.         success = doreinp(x,ms[0],ispattern);
  9062.     }
  9063.     if (intime[cmdlvl] && !success) { /* TIMEOUT-ACTION = QUIT? */
  9064.         popclvl();            /* If so, pop command level. */
  9065.         if (pflag && cmdlvl == 0) {
  9066.         if (cx == XXINP)  printf("?INPUT timed out\n");
  9067.         if (cx == XXMINP) printf("?MINPUT timed out\n");
  9068.         if (cx == XXREI)  printf("?REINPUT failed\n");
  9069.         }
  9070.     }
  9071.     return(success);        /* Return do(re)input's return code */
  9072.     }
  9073.  
  9074. #endif /* NOSPL */
  9075.  
  9076.     if (cx == XXLOG) {            /* LOG */
  9077.     x = cmkey(logtab,nlog,"What to log","",xxstring);
  9078.     if (x == -3) {
  9079.         printf("?Type of log required\n");
  9080.         return(-9);
  9081.     }
  9082.     if (x < 0) return(x);
  9083.     x = dolog(x);
  9084.     if (x < 0)
  9085.       return(x);
  9086.     else
  9087.       return(success = x);
  9088.     }
  9089.  
  9090.     if (cx == XXLOGIN) {        /* (REMOTE) LOGIN */
  9091. #ifdef NEWFTP
  9092.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  9093.       return(success = doftpusr());
  9094. #endif /* NEWFTP */
  9095. #ifdef IKSD
  9096.     if (inserver) {
  9097.         printf("?Already logged in\n");
  9098.         return(-9);
  9099.     } else
  9100. #endif /* IKSD */
  9101.     {
  9102. #ifdef NOXFER
  9103.         return(-2);
  9104. #else
  9105.         return(dormt(XZLGI));
  9106. #endif /* NOXFER */
  9107.     }
  9108.     }
  9109.     if (cx == XXLOGOUT) {        /* (REMOTE) LOGOUT */
  9110. #ifdef NEWFTP
  9111.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  9112.       return(success = doftpres());
  9113. #endif /* NEWFTP */
  9114.  
  9115. #ifdef IKSD
  9116.         if (inserver) {
  9117.         if ((x = cmcfm()) < 0)
  9118.           return(x);
  9119.         doexit(GOOD_EXIT,xitsta);
  9120.     } else
  9121. #endif /* IKSD */
  9122.     if (!local || (network && ttchk() < 0)) {
  9123.         printf("?No connection.\n");
  9124.         return(-9);
  9125.     } else {
  9126. #ifdef NOXFER
  9127.         return(-2);
  9128. #else
  9129.         return(dormt(XZLGO));
  9130. #endif /* NOXFER */
  9131.     }
  9132.     }
  9133.  
  9134. #ifndef NOSCRIPT
  9135.     if (cx == XXLOGI) {            /* UUCP-style script */
  9136.     if ((x = cmtxt("expect-send expect-send ...","",&s,xxstring)) < 0)
  9137.       return(x);
  9138. #ifdef CK_APC
  9139.     if ((apcactive == APC_LOCAL) ||
  9140.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  9141.       return(success = 0);
  9142. #endif /* CK_APC */
  9143. #ifdef VMS
  9144.     conres();            /* For Ctrl-C to work... */
  9145. #endif /* VMS */
  9146.     return(success = dologin(s));    /* Return 1=completed, 0=failed */
  9147.     }
  9148. #endif /* NOSCRIPT */
  9149.  
  9150. #ifndef NOXFER
  9151. #ifdef PIPESEND
  9152.     if (cx == XXCREC) {            /* CRECEIVE */
  9153.     if (protocol != PROTO_K) {
  9154.         printf("?Sorry, CRECEIVE works only with Kermit protocol\n");
  9155.         return(-9);
  9156.     } else
  9157.       return(doxget(cx));
  9158.     }
  9159.     if (cx == XXCGET) {            /* CGET */
  9160.     return(doxget(cx));
  9161.     }
  9162. #endif /* PIPESEND */
  9163.  
  9164.     if (cx == XXREC)            /* RECEIVE */
  9165.       return(doxget(cx));
  9166. #endif /* NOXFER */
  9167.  
  9168. #ifndef NOXFER
  9169.     if (cx == XXREM) {            /* REMOTE */
  9170. #ifdef NEWFTP
  9171.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  9172.       return(doftprmt(0,0));
  9173. #endif /* NEWFTP */
  9174. #ifdef CK_XYZ
  9175.     if (protocol != PROTO_K) {
  9176.         printf("Sorry, REMOTE commands only work with Kermit protocol\n");
  9177.         return(-9);
  9178.     }
  9179. #endif /* CK_XYZ */
  9180.     x = cmkey(remcmd,nrmt,"Remote Kermit server command","",xxstring);
  9181.     if (x == -3) {
  9182.         printf("?You must specify a command for the remote server\n");
  9183.         return(-9);
  9184.     }
  9185.     return(dormt(x));
  9186.     }
  9187. #endif /* NOXFER */
  9188.  
  9189. #ifndef NORENAME
  9190. #ifndef NOFRILLS
  9191.     if (cx == XXREN || cx == XXLREN) {    /* RENAME */
  9192. #ifdef LOCUS
  9193.     if (!locus && cx != XXLREN) {
  9194. #ifdef NOXFER
  9195.         return(-2);
  9196. #else
  9197.         return(dormt(XZREN));
  9198. #endif /* NOXFER */
  9199.         }
  9200. #endif /* LOCUS */
  9201. #ifdef IKSD
  9202.     if (inserver && (!ENABLED(en_ren)
  9203. #ifdef CK_LOGIN
  9204.              || isguest
  9205. #endif /* CK_LOGIN */
  9206.              )) {
  9207.         printf("?Sorry, renaming of files is disabled\n");
  9208.         return(-9);
  9209.     }
  9210. #endif /* IKSD */
  9211. #ifdef CK_APC
  9212.     if ((apcactive == APC_LOCAL) ||
  9213.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  9214.       return(success = 0);
  9215. #endif /* CK_APC */
  9216.     return(dorenam());
  9217.     }
  9218. #endif /* NOFRILLS */
  9219. #endif /* NORENAME */
  9220.  
  9221.     if (cx == XXEIGHT) {        /* EIGHTBIT */
  9222.     extern int parity, cmask, cmdmsk;
  9223.     if ((x = cmcfm()) < 0)
  9224.       return(x);
  9225.     parity = 0;
  9226.     cmask = 0xff;
  9227.     cmdmsk = 0xff;
  9228.     return(success = 1);
  9229.     }
  9230.  
  9231. #ifndef NOXFER
  9232. /* SEND, CSEND, MOVE, MAIL, and RESEND use the new common code */
  9233.  
  9234.     if (cx == XXSEN            /* SEND */
  9235. #ifdef PIPESEND
  9236.     || cx == XXCSEN            /* CSEND */
  9237. #endif /* PIPESEND */
  9238.     || cx == XXMOVE            /* MOVE */
  9239.     || cx == XXMAI            /* MAIL */
  9240. #ifdef CK_RESEND
  9241.     || cx == XXRSEN            /* RESEND */
  9242. #endif /* CK_RESEND */
  9243.     ) {
  9244. #ifdef IKSD
  9245.     if (inserver && !ENABLED(en_get)) {
  9246.         printf("?Sorry, sending files is disabled\n");
  9247.         return(-9);
  9248.     }
  9249. #endif /* IKSD */
  9250.     return(doxsend(cx));
  9251.     }
  9252.  
  9253. /* PSEND, ADD, and REMOVE use special parsing */
  9254.  
  9255. #ifdef ADDCMD
  9256.     /* ADD and REMOVE */
  9257.     if (cx == XXADD || cx == XXREMV) {
  9258.     char * m;
  9259.     m = (cx == XXADD) ? "Add to which list?" : "Remove from which list?";
  9260.     x = cmkey(addtab,naddtab,m,"",xxstring);
  9261.     if (x < 0)
  9262.       return(x);
  9263. #ifndef NOMSEND
  9264.     if (x == ADD_SND)
  9265.       return(addsend(cx));
  9266.     else
  9267. #endif /* NOMSEND */
  9268.       return(doadd(cx,x));
  9269.     }
  9270. #endif /* ADDCMD */
  9271.  
  9272. #ifdef CK_RESEND
  9273.     if (cx == XXPSEN) {            /* PSEND */
  9274.     int seekto = 0;
  9275.  
  9276.     cmarg = cmarg2 = "";
  9277.     x = cmifi("File to partially send", "", &s, &y, xxstring);
  9278.     if (x < 0) {
  9279.         if (x == -3) {
  9280.         printf("?A file specification is required\n");
  9281.         return(-9);
  9282.         } else return(x);
  9283.     }
  9284.     nfils = -1;            /* Files come from internal list. */
  9285. #ifndef NOMSEND
  9286.         addlist = 0;            /* Don't use SEND-LIST. */
  9287.         filenext = NULL;
  9288. #endif /* NOMSEND */
  9289.     ckstrncpy(line,s,LINBUFSIZ);    /* Save copy of string just parsed. */
  9290.     debug(F110,"PSEND line",line,0);
  9291.     if (y != 0) {
  9292.         printf("?Sorry, wildcards not permitted in this command\n");
  9293.         return(-9);
  9294.     }
  9295.     if (sizeof(int) < 4) {
  9296.         printf("?Sorry, this command needs 32-bit integers\n");
  9297.         return(-9);
  9298.     }
  9299.     x = cmnum("starting position (byte number)",
  9300.           "",10,&seekto,xxstring);
  9301.     if (x < 0)
  9302.       return(x);
  9303.     zfnqfp(s,fspeclen,fspec);    /* Get full path */
  9304.     if ((x = cmtxt("Name to send it with","",&s,NULL)) < 0)
  9305.       return(x);
  9306.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  9307.  
  9308. #ifdef IKSD
  9309.     if (inserver && !ENABLED(en_get)) {
  9310.         printf("?Sorry, sending files is disabled\n");
  9311.         return(-9);
  9312.     }
  9313. #endif /* IKSD */
  9314. #ifdef PIPESEND
  9315.     if (sndfilter) {
  9316.         printf("?Sorry, no PSEND while SEND FILTER selected\n");
  9317.         return(-9);
  9318.     }
  9319. #endif /* PIPESEND */
  9320. #ifdef CK_XYZ
  9321.     if ((protocol == PROTO_X || protocol == PROTO_XC)) {
  9322.         printf("Sorry, PSEND works only with Kermit protocol\n");
  9323.         return(-9);
  9324.     }
  9325. #endif /* CK_XYZ */
  9326.  
  9327.     cmarg2 = brstrip(tmpbuf);    /* Strip braces */
  9328.     cmarg = line;            /* File to send */
  9329.     debug(F110,"PSEND filename",cmarg,0);
  9330.     debug(F110,"PSEND as-name",cmarg2,0);
  9331.     sendstart = seekto;
  9332.     sstate = 's';            /* Set start state to SEND */
  9333. #ifndef NOMSEND
  9334.     addlist = 0;
  9335.     filenext = NULL;
  9336. #endif /* NOMSEND */
  9337.     sendmode = SM_PSEND;
  9338. #ifdef MAC
  9339.     what = W_SEND;
  9340.     scrcreate();
  9341. #endif /* MAC */
  9342.     if (local) {            /* If in local mode, */
  9343.         displa = 1;            /* enable file transfer display */
  9344.     }
  9345.     return(0);
  9346.     }
  9347. #endif /* CK_RESEND */
  9348. #endif /* NOXFER */
  9349.  
  9350. #ifndef NOXFER
  9351. #ifndef NOMSEND
  9352.     if (cx == XXMSE || cx == XXMMOVE) {
  9353. #ifdef NEWFTP
  9354.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  9355.       return(doftpput(cx,0));
  9356. #endif /* NEWFTP */
  9357. #ifdef CK_XYZ
  9358.     if (protocol == PROTO_X || protocol == PROTO_XC) {
  9359.         printf(
  9360. "Sorry, you can only send one file at a time with XMODEM protocol\n"
  9361.            );
  9362.         return(-9);
  9363.     }
  9364. #endif /* CK_XYZ */
  9365.         return(doxsend(cx));
  9366.     }
  9367.  
  9368. #ifdef COMMENT                /* (moved to doxsend) */
  9369.     if (cx == XXMSE || cx == XXMMOVE) {    /* MSEND and MMOVE commands */
  9370.     nfils = 0;            /* Like getting a list of */
  9371.     lp = line;            /* files on the command line */
  9372.     addlist = 0;            /* Do not use SEND-LIST */
  9373.     filenext = NULL;        /* Ditto ! */
  9374.  
  9375.     while (1) {
  9376.         char *p;
  9377.         if ((x = cmifi("Names of files to send, separated by spaces","",
  9378.                &s,&y,xxstring)) < 0) {
  9379.         if (x == -3) {
  9380.             if (nfils <= 0) {
  9381.             printf("?A file specification is required\n");
  9382.             return(-9);
  9383.             } else break;
  9384.         }
  9385.         return(x);
  9386.         }
  9387.         msfiles[nfils++] = lp;    /* Got one, count it, point to it, */
  9388.         p = lp;            /* remember pointer, */
  9389.         while (*lp++ = *s++)    /* and copy it into buffer */
  9390.           if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
  9391.           printf("?MSEND list too long\n");
  9392.           line[0] = NUL;
  9393.           return(-9);
  9394.           }
  9395.         debug(F111,"msfiles",msfiles[nfils-1],nfils-1);
  9396.         if (nfils == 1) *fspec = NUL; /* Take care of \v(filespec) */
  9397. #ifdef ZFNQFP
  9398.         zfnqfp(p,TMPBUFSIZ,tmpbuf);
  9399.         p = tmpbuf;
  9400. #endif /* ZFNQFP */
  9401.         if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) {
  9402.         strcat(fspec,p);    /* safe */
  9403.         strcat(fspec," ");    /* safe */
  9404.         } else printf("WARNING - \\v(filespec) buffer overflow\n");
  9405.     }
  9406.     cmlist = msfiles;        /* Point cmlist to pointer array */
  9407.     cmarg2 = "";            /* No internal expansion list (yet) */
  9408.     sndsrc = nfils;            /* Filenames come from cmlist */
  9409.     sendmode = SM_MSEND;        /* Remember this kind of SENDing */
  9410.     sstate = 's';            /* Set start state for SEND */
  9411.     if (cx == XXMMOVE)        /* If MMOVE'ing, */
  9412.       moving = 1;            /*  set this flag. */
  9413. #ifdef MAC
  9414.     what = W_SEND;
  9415.     scrcreate();
  9416. #endif /* MAC */
  9417.     if (local) {            /* If in local mode, */
  9418.         displa = 1;            /* turn on file transfer display */
  9419.         ttflui();            /* and flush tty input buffer. */
  9420.     }
  9421.     return(0);
  9422.     }
  9423. #endif /* COMMENT */
  9424. #endif /* NOMSEND */
  9425. #endif /* NOXFER */
  9426.  
  9427. #ifndef NOSERVER
  9428.     if (cx == XXSER) {            /* SERVER */
  9429. #ifdef CK_XYZ
  9430.     if (protocol != PROTO_K) {
  9431.         printf("Sorry, SERVER only works with Kermit protocol\n");
  9432.         return(-9);
  9433.     }
  9434. #endif /* CK_XYZ */
  9435. #ifdef COMMENT
  9436. /*
  9437.   Parse for time limit, but since we don't use it yet,
  9438.   the parsing is commented out.
  9439. */
  9440.     x_ifnum = 1;            /* Turn off internal complaints */
  9441.     y = cmnum("optional time limit, seconds, or time of day as hh:mm:ss",
  9442.           "0", 10, &x, xxstring
  9443.           );
  9444.     x_ifnum = 0;
  9445.     if (y < 0) {
  9446.         if (y == -2) {        /* Invalid number or expression */
  9447.         zz = tod2sec(atmbuf);    /* Convert to secs since midnight */
  9448.         if (zz < 0L) {
  9449.             printf("?Number, expression, or time of day required\n");
  9450.             return(-9);
  9451.         } else {
  9452.             char now[32];    /* Current time */
  9453.             char *p;
  9454.             long tnow;
  9455.             p = now;
  9456.             ztime(&p);
  9457.             tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
  9458.             if (zz < tnow)    /* User's time before now */
  9459.               zz += 86400L;    /* So make it tomorrow */
  9460.             zz -= tnow;        /* Seconds from now. */
  9461.         }
  9462.         } else
  9463.           return(y);
  9464.     }
  9465.     if (zz > -1L) {
  9466.         x = zz;
  9467.         if (zz != (long) x) {
  9468.         printf(
  9469. "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
  9470.                );
  9471.         return(-9);
  9472.         }
  9473.     }
  9474.     if (x < 0)
  9475.       x = 0;
  9476. #endif /* COMMENT */
  9477.  
  9478.     if ((x = cmcfm()) < 0) return(x);
  9479.     sstate = 'x';
  9480. #ifdef MAC
  9481.     what = W_RECV;
  9482.     scrcreate();
  9483. #endif /* MAC */
  9484.     if (local) displa = 1;
  9485. #ifdef AMIGA
  9486.     reqoff();            /* No DOS requestors while server */
  9487. #endif /* AMIGA */
  9488.     return(0);
  9489.     }
  9490. #endif /* NOSERVER */
  9491.  
  9492.     if (cx == XXSAVE) {            /* SAVE command */
  9493.     x = cmkey(savtab,nsav,"option","keymap",xxstring);
  9494.     if (x == -3) {
  9495.         printf("?You must specify an option to save\n");
  9496.         return(-9);
  9497.     }
  9498.     if (x < 0) return(x);
  9499.     /* have to set success separately for each item in doprm()... */
  9500.     /* actually not really, could have just had doprm return 0 or 1 */
  9501.     /* and set success here... */
  9502.     y = dosave(x);
  9503.     if (y == -3) {
  9504.         printf("?More fields required\n");
  9505.         return(-9);
  9506.     } else return(y);
  9507.     }
  9508.  
  9509.     if (cx == XXSET) {            /* SET command */
  9510.     x = cmkey(prmtab,nprm,"Parameter","",xxstring);
  9511.     if (x == -3) {
  9512.         printf("?You must specify a parameter to set\n");
  9513.         return(-9);
  9514.     }
  9515.     if (x < 0) return(x);
  9516.     /* have to set success separately for each item in doprm()... */
  9517.     /* actually not really, could have just had doprm return 0 or 1 */
  9518.     /* and set success here... */
  9519.     y = doprm(x,0);
  9520.     if (y == -3) {
  9521.         printf("?More fields required\n");
  9522.         return(-9);
  9523.     } else return(y);
  9524.     }
  9525.  
  9526. #ifndef NOPUSH
  9527.     if (cx == XXSHE            /* SHELL (system) command */
  9528.     || cx == XXEXEC            /* exec() */
  9529.     ) {
  9530.     int rx = 0;
  9531.     char * p = NULL;
  9532.     int i /* ,n */ ;
  9533. #ifdef UNIXOROSK
  9534.     char * args[256];
  9535. #endif /* UNIXOROSK */
  9536.  
  9537. #ifdef IKSD
  9538.     if (inserver && (nopush || !ENABLED(en_hos))) {
  9539.         printf("?Sorry, host command access is disabled\n");
  9540.         return(-9);
  9541.     }
  9542. #endif /* IKSD */
  9543.  
  9544. #ifdef CKEXEC
  9545.     if (cx == XXEXEC) {        /* EXEC (overlay ourselves) */
  9546.         struct FDB sw, fl;
  9547.         cmfdbi(&sw,            /* First FDB - command switches */
  9548.            _CMKEY,        /* fcode */
  9549.            "Command to overlay C-Kermit\n or switch", /* hlpmsg */
  9550.            "",            /* default */
  9551.            "",            /* addtl string data */
  9552.            1,            /* addtl numeric data 1: tbl size */
  9553.            4,            /* addtl numeric data 2: 4 = cmswi */
  9554.            xxstring,        /* Processing function */
  9555.            redirsw,        /* Keyword table */
  9556.            &fl            /* Pointer to next FDB */
  9557.            );
  9558.         cmfdbi(&fl,            /* 2nd FDB - command to exec */
  9559.            _CMFLD,        /* fcode */
  9560.            "Command to overlay C-Kermit", /* hlpmsg */
  9561.            "",            /* default */
  9562.            "",            /* addtl string data */
  9563.            0,            /* addtl numeric data 1 */
  9564.            0,            /* addtl numeric data 2 */
  9565.            xxstring,
  9566.            NULL,
  9567.            NULL            /* No more after this */
  9568.            );
  9569.         while (1) {
  9570.         x = cmfdb(&sw);        /* Parse something */
  9571.         debug(F101,"exec cmfdb","",x);
  9572.         if (x < 0)
  9573.           return(x);
  9574.         /* Generalize this if we add more switches */
  9575.         if (cmresult.fcode == _CMKEY) {
  9576.             rx = 1;
  9577.             continue;
  9578.         }
  9579.         if (cmresult.fcode == _CMFLD)
  9580.           break;
  9581.         return(-2);
  9582.         }
  9583.         ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ);
  9584.         if (!tmpbuf[0]) {
  9585.         printf("?Command required\n");
  9586.         return(-9);
  9587.         }
  9588.         p = brstrip(tmpbuf);
  9589.         args[0] = NULL;        /* Set argv[0] to it */
  9590.         makestr(&args[0],p);
  9591.         for (i = 1; i < 255; i++) {    /* Get arguments for command */
  9592.         if ((x = cmfld("Argument","",&s,xxstring)) < 0) {
  9593.             if (x == -3) {
  9594.             if ((x = cmcfm()) < 0)
  9595.               return(x);
  9596.             break;
  9597.             } else
  9598.               return(x);
  9599.         }
  9600.         args[i] = NULL;
  9601.         s = brstrip(s);
  9602.         makestr(&args[i],s);
  9603.         }
  9604.         args[i] = NULL;
  9605.     } else {
  9606. #endif /* CKEXEC */
  9607.         if ((x = cmtxt("System command to execute","",&s,xxstring)) < 0)
  9608.           return(x);
  9609. #ifdef CKEXEC
  9610.     }
  9611. #endif /* CKEXEC */
  9612.         if (nopush)
  9613.           return(success = 0);
  9614. #ifdef CK_APC
  9615.     if (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
  9616.       return(success = 0);
  9617. #endif /* CK_APC */
  9618.     conres();            /* Make console normal  */
  9619. #ifdef OS2
  9620.     if (!(s && *s)) {
  9621.         os2push();
  9622.             return(success = 1);
  9623.     } else
  9624. #endif /* OS2 */
  9625.       if (cx == XXSHE) {
  9626.           x = zshcmd(s);
  9627.           debug(F101,"RUN zshcmd code","",x);
  9628.           concb((char)escape);
  9629.           return(success = x);
  9630. #ifdef CKEXEC
  9631.       } else {
  9632. #ifdef DEBUG
  9633.           if (deblog) {
  9634.           debug(F111,"EXEC cmd",p,0);
  9635.           for (i = 0; i < 256 && args[i]; i++)
  9636.             debug(F111,"EXEC arg",args[i],i);
  9637.           }
  9638. #endif /* DEBUG */
  9639.           if (p) {
  9640.           z_exec(p,args,rx);    /* Overlay ourself */
  9641.           debug(F100,"EXEC fails","",0);
  9642.           concb((char)escape);    /* In case it returns */
  9643.           }
  9644.           return(success = 0);
  9645. #endif /* CKEXEC */
  9646.       }
  9647.     }
  9648.  
  9649. #ifdef CK_REDIR
  9650.     if (cx == XXFUN) {            /* REDIRECT */
  9651. #ifdef CK_APC
  9652.     if ((apcactive == APC_LOCAL) ||
  9653.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  9654.       return(success = 0);
  9655. #endif /* CK_APC */
  9656.     ckmakmsg(tmpbuf,
  9657.          TMPBUFSIZ,
  9658.          "Local command to run,\n",
  9659.          "with its standard input/output redirected to ",
  9660.          local ? ttname : "the communications connection",
  9661.          "\n"
  9662.          );
  9663.     if ((x = cmtxt(tmpbuf,"",&s,xxstring)) < 0)
  9664.       return(x);
  9665.         if (nopush) {
  9666.             printf("?REDIRECT disabled\n");
  9667.             return(success=0);
  9668.         }
  9669.     if (!local) {
  9670.         printf("?SET LINE or SET HOST required first\n");
  9671.         return(-9);
  9672.     }
  9673.     if (!*s) {
  9674.         printf("?REDIRECT requires a command to redirect\n");
  9675.         return(-9);
  9676.     }
  9677.     return(success = ttruncmd(s));
  9678.     }
  9679. #endif /* CK_REDIR */
  9680. #endif /* NOPUSH */
  9681.  
  9682. #ifndef NOSHOW
  9683.     if (cx == XXSHO) {            /* SHOW */
  9684.     x = cmkey(shotab,nsho,"","parameters",xxstring);
  9685.     if (x < 0) return(x);
  9686.     return(doshow(x));
  9687.     }
  9688. #endif /* NOSHOW */
  9689.  
  9690. #ifndef MAC
  9691.     if (cx == XXSPA) {            /* SPACE */
  9692. #ifdef IKSD
  9693.     if (inserver && !ENABLED(en_spa)) {
  9694.         printf("?Sorry, SPACE command disabled\n");
  9695.         return(-9);
  9696.     }
  9697. #endif /* IKSD */
  9698. #ifdef datageneral
  9699.     /* AOS/VS can take an argument after its "space" command. */
  9700.     if ((x = cmtxt("Confirm, or local directory name","",&s,xxstring)) < 0)
  9701.       return(x);
  9702.     if (nopush) {
  9703.         printf("?Sorry, SPACE command disabled\n");
  9704.         return(-9);
  9705.     } else if (*s == NUL) {
  9706.         xsystem(SPACMD);
  9707.     } else {
  9708.         ckmakmsg(line,LINBUFSIZ,"space ",s,NULL,NULL);
  9709.         xsystem(line);
  9710.     }
  9711. #else
  9712. #ifdef OS2
  9713.     if ((x = cmtxt("Press Enter for current disk,\n\
  9714.  or specify a disk letter like A:","",&s,xxstring)) < 0)
  9715.       return(x);
  9716.     if (*s == NUL) {        /* Current disk */
  9717.             unsigned long space = zdskspace(0);
  9718.             if (space > 0 && space < 1024)
  9719.               printf(" Free space: unknown\n");
  9720.             else
  9721.           printf(" Free space: %ldK\n", space/1024L);
  9722.     } else {
  9723.         int drive = toupper(*s);
  9724.             unsigned long space = zdskspace(drive - 'A' + 1);
  9725.             if (space > 0 && space < 1024)
  9726.               printf(" Drive %c: unknown free\n");
  9727.             else
  9728.               printf(" Drive %c: %ldK free\n", drive,space / 1024L);
  9729.     }
  9730. #else
  9731. #ifdef UNIXOROSK
  9732.     x = cmdir("Confirm for current disk,\n\
  9733.  or specify a disk device or directory","",&s,xxstring);
  9734.     if (x == -3)
  9735.       s = "";
  9736.     else if (x < 0)
  9737.       return(x);
  9738.         ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  9739.         s = tmpbuf;
  9740.     if ((x = cmcfm()) < 0) return(x);
  9741.     if (nopush) {
  9742.         printf("?Sorry, SPACE command disabled\n");
  9743.         return(-9);
  9744.     }
  9745.     if (!*s) {            /* Current disk */
  9746.         xsystem(SPACMD);
  9747.     } else {            /* Specified disk */
  9748.         ckmakmsg(line,LINBUFSIZ,SPACM2," ",s,NULL);
  9749.         xsystem(line);
  9750.     }
  9751. #else
  9752.     if ((x = cmcfm()) < 0) return(x);
  9753.     if (nopush) {
  9754.         printf("?Sorry, SPACE command disabled\n");
  9755.         return(-9);
  9756.     }
  9757.     xsystem(SPACMD);
  9758. #endif /* UNIXOROSK */
  9759. #endif /* OS2 */
  9760. #endif /* datageneral */
  9761.     return(success = 1);        /* Pretend it worked */
  9762.     }
  9763. #endif /* MAC */
  9764.  
  9765. #ifndef NOXFER
  9766.     if (cx == XXSTA) {            /* STATISTICS */
  9767.     if ((x = cmkey(stattab,2,"Carriage return, or option",
  9768.                "/brief",xxstring)) < 0)
  9769.       return(x);
  9770.     if ((y = cmcfm()) < 0) return(y);
  9771.     return(success = dostat(x));
  9772.     }
  9773. #endif /* NOXFER */
  9774.  
  9775.     if (cx == XXSTO || cx == XXEND) {    /* STOP, END, or POP */
  9776.     if ((y = cmnum("exit status code","0",10,&x,xxstring)) < 0)
  9777.       return(y);
  9778.     if ((y = cmtxt("Message to print","",&s,xxstring)) < 0)
  9779.       return(y);
  9780.     s = brstrip(s);
  9781.     if (*s) printf("%s\n",s);
  9782.     if (cx == XXSTO) {
  9783.         dostop();
  9784.     } else {
  9785.         doend(x);
  9786.     }
  9787.     return(success = (x == 0));
  9788.     }
  9789.     if (cx == XXSUS) {            /* SUSPEND */
  9790.     if ((y = cmcfm()) < 0) return(y);
  9791. #ifdef NOJC
  9792.     printf("Sorry, this version of Kermit cannot be suspended\n");
  9793. #else
  9794. #ifdef IKSD
  9795.     if (inserver) {
  9796.         printf("?Sorry, IKSD can not be suspended\n");
  9797.         return(-9);
  9798.     } else
  9799. #endif /* IKSD */
  9800.       if (nopush) {
  9801.         printf("?Sorry, access to system is disabled\n");
  9802.         return(-9);
  9803.     }
  9804.     stptrap(0);
  9805. #endif /* NOJC */
  9806.     return(0);
  9807.     }
  9808.  
  9809.     if (cx == XXTAK) {            /* TAKE */
  9810.     char * scriptenv = NULL;    
  9811. #ifdef OS2
  9812.         char * GetAppData(int);
  9813.     extern char startupdir[],exedir[],inidir[];
  9814.     char * keymapenv = NULL;
  9815.         char * appdata0 = NULL, *appdata1 = NULL;
  9816.     int xx;
  9817. #define TAKEPATHLEN 4096
  9818. #else /* OS2 */
  9819. #define TAKEPATHLEN 1024
  9820. #endif /* OS2 */
  9821.     char takepath[TAKEPATHLEN];
  9822.  
  9823.     if (tlevel >= MAXTAKE-1) {
  9824.         printf("?Take files nested too deeply\n");
  9825.         return(-9);
  9826.     }
  9827. #ifdef OS2
  9828. #ifdef NT
  9829.     scriptenv = getenv("K95SCRIPTS");
  9830.     keymapenv = getenv("K95KEYMAPS");
  9831.         makestr(&appdata0,(char *)GetAppData(0));
  9832.         makestr(&appdata1,(char *)GetAppData(1));
  9833. #else /* NT */
  9834.     scriptenv = getenv("K2SCRIPTS");
  9835.     keymapenv = getenv("K2KEYMAPS");
  9836. #endif /* NT */
  9837. #endif /* OS2 */
  9838.  
  9839.     if (!scriptenv)            /* Let this work for Unix etc too */
  9840.       scriptenv = getenv("CK_SCRIPTS"); /* Use this if defined */
  9841. #ifndef OS2
  9842.     if (!scriptenv)            /* Otherwise use home directory */
  9843.       scriptenv = homepath();
  9844. #endif /* OS2 */
  9845.     if (!scriptenv)
  9846.       scriptenv = "";
  9847.     ckstrncpy(takepath,scriptenv,TAKEPATHLEN);
  9848.     debug(F110,"TAKE initial takepath",takepath,0);
  9849.  
  9850. #ifdef OS2
  9851.     if (!keymapenv)
  9852.       keymapenv = getenv("CK_KEYMAPS");
  9853.     if (!keymapenv)
  9854.       keymapenv = "";
  9855.  
  9856.     ckstrncat(takepath,
  9857.           (scriptenv && scriptenv[strlen(scriptenv)-1]==';')?"":";",
  9858.           TAKEPATHLEN
  9859.           );
  9860.     ckstrncat(takepath,keymapenv?keymapenv:"",TAKEPATHLEN);
  9861.     ckstrncat(takepath,
  9862.           (keymapenv && keymapenv[strlen(keymapenv)-1]==';')?"":";",
  9863.           TAKEPATHLEN
  9864.           );
  9865.     ckstrncat(takepath,startupdir,TAKEPATHLEN);
  9866.     ckstrncat(takepath,";",TAKEPATHLEN);
  9867.     ckstrncat(takepath,startupdir,TAKEPATHLEN);
  9868.     ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
  9869.     ckstrncat(takepath,startupdir,TAKEPATHLEN);
  9870.     ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
  9871.  
  9872.     ckstrncat(takepath,appdata1,TAKEPATHLEN);
  9873.     ckstrncat(takepath,"Kermit 95/;",TAKEPATHLEN);
  9874.     ckstrncat(takepath,appdata1,TAKEPATHLEN);
  9875.     ckstrncat(takepath,"Kermit 95/SCRIPTS/;",TAKEPATHLEN);
  9876.     ckstrncat(takepath,appdata1,TAKEPATHLEN);
  9877.     ckstrncat(takepath,"Kermit 95/KEYMAPS/;",TAKEPATHLEN);
  9878.  
  9879.     ckstrncat(takepath,appdata0,TAKEPATHLEN);
  9880.     ckstrncat(takepath,"Kermit 95/;",TAKEPATHLEN);
  9881.     ckstrncat(takepath,appdata0,TAKEPATHLEN);
  9882.     ckstrncat(takepath,"Kermit 95/SCRIPTS/;",TAKEPATHLEN);
  9883.     ckstrncat(takepath,appdata0,TAKEPATHLEN);
  9884.     ckstrncat(takepath,"Kermit 95/KEYMAPS/;",TAKEPATHLEN);
  9885.  
  9886.     ckstrncat(takepath,inidir,TAKEPATHLEN);
  9887.     ckstrncat(takepath,";",TAKEPATHLEN);
  9888.     ckstrncat(takepath,inidir,TAKEPATHLEN);
  9889.     ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
  9890.     ckstrncat(takepath,inidir,TAKEPATHLEN);
  9891.     ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
  9892.  
  9893.     ckstrncat(takepath,zhome(),TAKEPATHLEN);
  9894.     ckstrncat(takepath,";",TAKEPATHLEN);
  9895.     ckstrncat(takepath,zhome(),TAKEPATHLEN);
  9896.     ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
  9897.     ckstrncat(takepath,zhome(),TAKEPATHLEN);
  9898.     ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
  9899.  
  9900.     ckstrncat(takepath,exedir,TAKEPATHLEN);
  9901.     ckstrncat(takepath,";",TAKEPATHLEN);
  9902.     ckstrncat(takepath,exedir,TAKEPATHLEN);
  9903.     ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
  9904.     ckstrncat(takepath,exedir,TAKEPATHLEN);
  9905.     ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
  9906. #endif /* OS2 */
  9907.     debug(F110,"TAKE final takepath",takepath,0);
  9908.  
  9909.     if ((y = cmifip("Commands from file",
  9910.             "",&s,&x,0,takepath,xxstring)) < 0) {
  9911.         if (y == -3) {
  9912.         printf("?A file name is required\n");
  9913.         return(-9);
  9914.         } else
  9915.           return(y);
  9916.     }
  9917.     if (x != 0) {
  9918.         printf("?Wildcards not allowed in command file name\n");
  9919.         return(-9);
  9920.     }
  9921.     ckstrncpy(line,s,LINBUFSIZ);
  9922.     debug(F110,"TAKE file",s,0);
  9923.     if (isdir(s)) {
  9924.         printf("?Can't execute a directory - \"%s\"\n", s);
  9925.         return(-9);
  9926.     }
  9927. #ifndef NOTAKEARGS
  9928.     {
  9929.         char * p;
  9930.         x = strlen(line);
  9931.         debug(F111,"TAKE args",line,x);
  9932.         p = line + x + 1;
  9933.         if ((y = cmtxt("Optional arguments","",&s,xxstring)) < 0)
  9934.           return(y);
  9935.         if (*s) {            /* Args given? */
  9936.         ckstrncpy(p,s,LINBUFSIZ-x-1);
  9937. #ifdef ZFNQFP
  9938.         zfnqfp(line,TMPBUFSIZ,tmpbuf);
  9939.         s = tmpbuf;
  9940. #else
  9941.         s = line;
  9942. #endif /* ZFNQFP */
  9943.         debug(F110,"TAKE filename",s,0);
  9944.         x = strlen(s);
  9945.         debug(F101,"TAKE new len",s,x);
  9946.  
  9947. #ifdef COMMENT
  9948. /*
  9949.   This was added in C-Kermit 7.0 to allow args to be passed from the TAKE
  9950.   command to the command file.  But it overwrites the current argument vector,
  9951.   which is at best surprising, and at worst unsafe.
  9952. */
  9953.         addmac("%0",s);        /* Define %0 = name of file */
  9954.         varnam[0] = '%';
  9955.         varnam[2] = '\0';
  9956.         debug(F110,"take arg 0",s,0);
  9957.         debug(F110,"take args",p,0);
  9958.         for (y = 1; y < 10; y++) { /* Clear current args %1..%9 */
  9959.             varnam[1] = (char) (y + '0');
  9960.             delmac(varnam,0);
  9961.         }
  9962.         xwords(p,MAXARGLIST,NULL,0); /* Assign new args */
  9963.         debug(F110,"take args",p,0);
  9964. #else
  9965. /*
  9966.   This method is used in 8.0.  If the TAKE command includes arguments, we
  9967.   insert an intermediate temporary macro between the current level; we pass
  9968.   the arguments to the macro and then the macro TAKEs the command file.
  9969.   If the user Ctrl-C's out of the TAKE file, some temporary macro definitions
  9970.   and other small malloc'd bits might be left behind.
  9971. */
  9972.         {
  9973.             char * q = NULL;
  9974.             char * r = NULL;
  9975.             int k, m;
  9976.             m = maclvl;
  9977.             q = (char *)malloc(x+24);
  9978.             if (q) {
  9979.             r = (char *)malloc(x+24);
  9980.             if (r) {
  9981.                 sprintf(q,"_file[%s](%d)",s,cmdlvl); /* safe */
  9982.                 sprintf(r,"take %s",s); /* safe */
  9983.                 k = addmac(q,r);
  9984.                 if (k > -1) {
  9985.                 dodo(k,p,0);
  9986.                 while (maclvl > m) {
  9987.                     sstate = (CHAR) parser(1);
  9988.                     if (sstate) proto();
  9989.                 }
  9990.                 }
  9991.                 k = delmac(q,0);
  9992.                 free(q);
  9993.                 free(r);
  9994.                 return(success);
  9995.             }
  9996.             }
  9997.         }
  9998.         return(success = 0);
  9999. #endif /* COMMENT */
  10000.         }
  10001.     }
  10002. #else
  10003.     if ((y = cmcfm()) < 0) return(y);
  10004. #endif /* NOTAKEARGS */
  10005.     return(success = dotake(line));
  10006.     }
  10007.  
  10008. #ifndef NOLOCAL
  10009. #ifdef OS2
  10010.     if (cx == XXVIEW) {            /* VIEW Only Terminal mode */
  10011.     viewonly = TRUE;
  10012.     success = doconect(0, 0);
  10013.     viewonly = FALSE;
  10014.     return success;
  10015.     }
  10016. #endif /* OS2 */
  10017.  
  10018. #ifdef NETCONN
  10019.     if (cx == XXTEL || cx == XXIKSD) {    /* TELNET */
  10020.     int x,z;
  10021. #ifdef OS2
  10022.     if (!tcp_avail) {
  10023.         printf("?Sorry, either TCP/IP is not available on this system or\n\
  10024. necessary DLLs did not load.  Use SHOW NETWORK to check network status.\n");
  10025.         success = 0;
  10026.         return(-9);
  10027.     } else
  10028. #endif /* OS2 */
  10029.       {
  10030.       x = nettype;            /* Save net type in case of failure */
  10031.       z = ttnproto;            /* Save protocol in case of failure */
  10032.       nettype = NET_TCPB;
  10033.       ttnproto = (cx == XXTEL) ? NP_TELNET : NP_KERMIT;
  10034.       if ((y = setlin(XYHOST,0,1)) <= 0) {
  10035.               nettype = x;        /* Failed, restore net type. */
  10036.               ttnproto = z;        /* and protocol */
  10037.               success = 0;
  10038.       }
  10039.       didsetlin++;
  10040.         }
  10041.     return(y);
  10042.     }
  10043.  
  10044. #ifndef PTYORPIPE
  10045. #ifdef NETCMD
  10046. #define PTYORPIPE
  10047. #else
  10048. #ifdef NETPTY
  10049. #define PTYORPIPE
  10050. #endif /* NETPTY */
  10051. #endif /* NETCMD */
  10052. #endif /* PTYORPIPE */
  10053.  
  10054. #ifdef PTYORPIPE
  10055.     if (cx == XXPIPE || cx == XXPTY) {    /* PIPE or PTY */
  10056.     int x;
  10057.     extern int netsave;
  10058.     x = nettype;            /* Save net type in case of failure */
  10059.     nettype = (cx == XXPIPE) ? NET_CMD : NET_PTY;
  10060.     if ((y = setlin(XYHOST,0,1)) < 0) {
  10061.         nettype = x;        /* Failed, restore net type. */
  10062.         ttnproto = z;        /* and protocol */
  10063.         success = 0;
  10064.     }
  10065.     didsetlin++;
  10066.     netsave = x;
  10067.     return(y);
  10068.     }
  10069. #endif /* PTYORPIPE */
  10070.  
  10071. #ifdef ANYSSH
  10072.     if (cx == XXSSH) {            /* SSH (Secure Shell) */
  10073.     extern int netsave;
  10074. #ifdef SSHBUILTIN
  10075.     int k, x, havehost = 0, trips = 0;
  10076.         int    tmpver = -1, tmpxfw = -1;
  10077. #ifndef SSHTEST
  10078.         extern int sl_ssh_xfw, sl_ssh_xfw_saved;
  10079.         extern int sl_ssh_ver, sl_ssh_ver_saved;
  10080. #endif /* SSHTEST */
  10081.         extern int mdmtyp, mdmsav, cxtype, sl_uid_saved;
  10082.         extern char * slmsg;
  10083.     extern char uidbuf[], sl_uidbuf[];
  10084.         extern char pwbuf[], * g_pswd;
  10085.         extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
  10086.     struct FDB sw, kw, fl;
  10087.  
  10088.         if (ssh_tmpstr)
  10089.             memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
  10090.         makestr(&ssh_tmpstr,NULL);
  10091.         makestr(&ssh_tmpuid,NULL);
  10092.         makestr(&ssh_tmpcmd,NULL);
  10093.         makestr(&ssh_tmpport,NULL);
  10094.  
  10095.     cmfdbi(&kw,            /* 1st FDB - commands */
  10096.            _CMKEY,            /* fcode */
  10097.            "host [ port ],\n or action",    /* hlpmsg */
  10098.            "",            /* default */
  10099.            "",            /* addtl string data */
  10100.            nsshcmd,            /* addtl numeric data 1: tbl size */
  10101.            0,            /* addtl numeric data 2: 0 = keyword */
  10102.            xxstring,        /* Processing function */
  10103.            sshkwtab,        /* Keyword table */
  10104.            &fl            /* Pointer to next FDB */
  10105.            );
  10106.     cmfdbi(&fl,            /* Host */
  10107.            _CMFLD,            /* fcode */
  10108.            "",            /* hlpmsg */
  10109.            "",            /* default */
  10110.            "",            /* addtl string data */
  10111.            0,            /* addtl numeric data 1 */
  10112.            0,            /* addtl numeric data 2 */
  10113.            xxstring,
  10114.            NULL,
  10115.            NULL
  10116.            );
  10117.  
  10118.     x = cmfdb(&kw);
  10119.     if (x == -3) {
  10120.         printf("?ssh what?\n");
  10121.         return(-9);
  10122.     }
  10123.     if (x < 0)
  10124.       return(x);
  10125.     havehost = 0;
  10126.     if (cmresult.fcode == _CMFLD) {
  10127.         havehost = 1;
  10128.         ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Hostname */
  10129.         cmresult.nresult = XSSH_OPN;
  10130.     }
  10131.     switch (cmresult.nresult) {    /* SSH keyword */
  10132.       case XSSH_OPN:        /* SSH OPEN */
  10133.         if (!havehost) {
  10134.         if ((x = cmfld("Host","",&s,xxstring)) < 0)
  10135.           return(x);
  10136.         ckstrncpy(line,s,LINBUFSIZ);
  10137.         }
  10138.         /* Parse [ port ] [ switches ] */
  10139.         cmfdbi(&kw,            /* Switches */
  10140.            _CMKEY,
  10141.            "Port number or service name,\nor switch",
  10142.            "",
  10143.            "",
  10144.            nsshopnsw,
  10145.            4,
  10146.            xxstring,
  10147.            sshopnsw,
  10148.            &fl
  10149.            );
  10150.         cmfdbi(&fl,            /* Port number or service name */
  10151.            _CMFLD,
  10152.            "",
  10153.            "",
  10154.            "",
  10155.            0,
  10156.            0,
  10157.            xxstring,
  10158.            NULL,
  10159.            NULL
  10160.            );
  10161.         trips = 0;            /* Explained below */
  10162.         while (1) {            /* Parse port and switches */
  10163.         x = cmfdb(&kw);        /* Get a field */
  10164.         if (x == -3)        /* User typed CR so quit from loop */
  10165.           break;
  10166.         if (x < 0)        /* Other parse error, pass it back */
  10167.           return(x);
  10168.         switch (cmresult.fcode) { /* Field or Keyword? */
  10169.                   case _CMFLD:          /* Field */
  10170.                     makestr(&ssh_tmpport,cmresult.sresult);
  10171.             break;
  10172.           case _CMKEY:        /* Keyword */
  10173.             switch (cmresult.nresult) {    /* Which one? */
  10174.               case SSHSW_USR:            /* /USER: */
  10175.             if (!cmgbrk()) {
  10176.                 printf("?This switch requires an argument\n");
  10177.                 return(-9);
  10178.             }
  10179.             if ((y = cmfld("Username","",&s,xxstring)) < 0)
  10180.               return(y);
  10181.             s = brstrip(s);
  10182.             makestr(&ssh_tmpuid,s);
  10183.             break;
  10184.                       case SSHSW_PWD:
  10185.             if (!cmgbrk()) {
  10186.                 printf("?This switch requires an argument\n");
  10187.                 return(-9);
  10188.             }
  10189.             debok = 0;
  10190.             if ((x = cmfld("Password","",&s,xxstring)) < 0) {
  10191.                 if (x == -3) {
  10192.                 makestr(&ssh_tmpstr,"");
  10193.                 } else {
  10194.                 return(x);
  10195.                 }
  10196.             } else {
  10197.                 s = brstrip(s);
  10198.                 if ((x = (int)strlen(s)) > PWBUFL) {
  10199.                 makestr(&slmsg,"Internal error");
  10200.                 printf("?Sorry, too long - max = %d\n",PWBUFL);
  10201.                 return(-9);
  10202.                 }
  10203.                 makestr(&ssh_tmpstr,s);
  10204.             }
  10205.             break;
  10206.  
  10207.               case SSHSW_VER:
  10208.             if ((x = cmnum("Number","",10,&z,xxstring)) < 0)
  10209.               return(x);
  10210.             if (z < 1 || z > 2) {
  10211.                 printf("?Out of range: %d\n",z);
  10212.                 return(-9);
  10213.             }
  10214.                         tmpver = z;
  10215.             break;
  10216.               case SSHSW_CMD:
  10217.               case SSHSW_SUB:
  10218.             if ((x = cmfld("Text","",&s,xxstring)) < 0)
  10219.               return(x);
  10220.                         makestr(&ssh_tmpcmd,s);
  10221.             ssh_cas = (cmresult.nresult == SSHSW_SUB);
  10222.             break;
  10223.               case SSHSW_X11:
  10224.             if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
  10225.               return(x);
  10226.                         tmpxfw = x;
  10227.             break;
  10228.               default:
  10229.                 return(-2);
  10230.             }
  10231.         }
  10232.         if (trips++ == 0) {    /* After first time through */
  10233.             cmfdbi(&kw,        /* only parse switches, not port. */
  10234.                _CMKEY,
  10235.                "Switch",
  10236.                "",
  10237.                "",
  10238.                nsshopnsw,
  10239.                4,
  10240.                xxstring,
  10241.                sshopnsw,
  10242.                NULL
  10243.                );
  10244.         }
  10245.         }
  10246.         if ((x = cmcfm()) < 0)    /* Get confirmation */
  10247.           return(x);
  10248.             if (clskconnx(1) < 0) {    /* Close current Kermit connection */
  10249.               if ( ssh_tmpstr ) {
  10250.                   memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
  10251.                   makestr(&ssh_tmpstr,NULL);
  10252.               }
  10253.               return(success = 0);
  10254.             }
  10255.         makestr(&ssh_hst,line);    /* Stash everything */
  10256.         if (ssh_tmpuid) {
  10257.                 if (!sl_uid_saved) {
  10258.                     ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
  10259.                     sl_uid_saved = 1;
  10260.                 }
  10261.         ckstrncpy(uidbuf,ssh_tmpuid,UIDBUFLEN);
  10262.         makestr(&ssh_tmpuid,NULL);
  10263.         }
  10264.             if (ssh_tmpport) {
  10265.                 makestr(&ssh_prt,ssh_tmpport);
  10266.                 makestr(&ssh_tmpport,NULL);
  10267.             } else
  10268.                 makestr(&ssh_prt,NULL);
  10269.  
  10270.             if (ssh_tmpcmd) {
  10271.                 makestr(&ssh_cmd,brstrip(ssh_tmpcmd));
  10272.                 makestr(&ssh_tmpcmd,NULL);
  10273.             } else
  10274.                 makestr(&ssh_cmd,NULL);
  10275.  
  10276.             if (tmpver > -1) {
  10277. #ifndef SSHTEST
  10278.                 if (!sl_ssh_ver_saved) {
  10279.                     sl_ssh_ver = ssh_ver;
  10280.                     sl_ssh_ver_saved = 1;
  10281.                 }
  10282. #endif /* SSHTEST */
  10283.                 ssh_ver = tmpver;
  10284.             }
  10285.             if (tmpxfw > -1) {
  10286. #ifndef SSHTEST
  10287.                 if (!sl_ssh_xfw_saved) {
  10288.                     sl_ssh_xfw = ssh_xfw;
  10289.                     sl_ssh_xfw_saved = 1;
  10290.                 }
  10291. #endif /* SSHTEST */
  10292.                 ssh_xfw = tmpxfw;
  10293.             }
  10294.         if (ssh_tmpstr) {
  10295.         if (ssh_tmpstr[0]) {
  10296.             ckstrncpy(pwbuf,ssh_tmpstr,PWBUFL+1);
  10297.             pwflg = 1;
  10298.             pwcrypt = 0;
  10299.         } else
  10300.           pwflg = 0;
  10301.         makestr(&ssh_tmpstr,NULL);
  10302.         }
  10303.         nettype = NET_SSH;
  10304.         if (mdmsav < 0)
  10305.           mdmsav = mdmtyp;
  10306.         mdmtyp = -nettype;
  10307.         x = 1;
  10308.  
  10309. #ifndef NOSPL
  10310.             makestr(&g_pswd,pwbuf);             /* Save global pwbuf */
  10311.             g_pflg = pwflg;                     /* and flag */
  10312.             g_pcpt = pwcrypt;
  10313. #endif /* NOSPL */
  10314.  
  10315.         /* Line parameter to ttopen() is ignored */
  10316.         k = ttopen(line,&x,mdmtyp, 0);
  10317.         if (k < 0) {
  10318.         printf("?Unable to connect to %s\n",ssh_hst);
  10319.         mdmtyp = mdmsav;
  10320.                 slrestor();
  10321.         return(success = 0);
  10322.         }
  10323.         duplex = 0;             /* Remote echo */
  10324.         ckstrncpy(ttname,line,TTNAMLEN); /* Record the command */
  10325.         debug(F110,"ssh ttname",ttname,0);
  10326.         makestr(&slmsg,NULL);    /* No SET LINE error message */
  10327.         cxtype = CXT_SSH;
  10328. #ifndef NODIAL
  10329.         dialsta = DIA_UNK;
  10330. #endif /* NODIAL */
  10331.         success = 1;        /* SET LINE succeeded */
  10332.         network = 1;        /* Network connection (not serial) */
  10333.         local = 1;            /* Local mode (not remote) */
  10334.         if ((reliable != SET_OFF || !setreliable))
  10335.           reliable = SET_ON;    /* Transport is reliable end to end */
  10336. #ifdef OS2
  10337.             DialerSend(OPT_KERMIT_CONNECT, 0);
  10338. #endif /* OS2 */
  10339.         setflow();            /* Set appropriate flow control */
  10340.  
  10341.         haveline = 1;
  10342. #ifdef CKLOGDIAL
  10343. #ifdef NETCONN
  10344.         dolognet();
  10345. #endif /* NETCONN */
  10346. #endif /* CKLOGDIAL */
  10347.  
  10348. #ifndef NOSPL
  10349.         if (local) {
  10350.         if (nmac) {        /* Any macros defined? */
  10351.             int k;        /* Yes */
  10352.             k = mlook(mactab,"on_open",nmac); /* Look this up */
  10353.             if (k >= 0) {                  /* If found, */
  10354.             if (dodo(k,ssh_hst,0) > -1)   /* set it up, */
  10355.               parser(1);              /* and execute it */
  10356.             }
  10357.         }
  10358.         }
  10359. #endif /* NOSPL */
  10360. #ifdef LOCUS        
  10361.         if (autolocus)
  10362.         setlocus(1,1);
  10363. #endif /* LOCUS */
  10364.  
  10365.     /* Command was confirmed so we can pre-pop command level. */
  10366.     /* This is so CONNECT module won't think we're executing a */
  10367.     /* script if CONNECT was the final command in the script. */
  10368.         if (cmdlvl > 0)
  10369.           prepop();
  10370.         success = doconect(0,cmdlvl == 0 ? 1 : 0);
  10371.         if (ttchk() < 0)
  10372.           dologend();
  10373.         return(success);
  10374.  
  10375.       case XSSH_CLR:
  10376.         if ((y = cmkey(sshclr,nsshclr,"","", xxstring)) < 0) {
  10377.             if (y == -3) {
  10378.             printf("?clear what?\n");
  10379.             return(-9);
  10380.         }
  10381.             return(y);
  10382.         }
  10383.         if ((x = cmcfm()) < 0)
  10384.           return(x);
  10385.         switch (y) {
  10386.           case SSHC_LPF:
  10387.                 ssh_pf_lcl_n = 0;
  10388.         break;
  10389.           case SSHC_RPF:
  10390.         ssh_pf_rmt_n = 0;
  10391.         break;
  10392.           default:
  10393.         return(-2);
  10394.         }
  10395.             return(success = 1);    /* or whatever */
  10396.  
  10397.       case XSSH_AGT: {        /* SSH AGENT */
  10398.           int doeach = 0;
  10399.           if ((y = cmkey(sshagent,nsshagent,"","",xxstring)) < 0)
  10400.         return(y);
  10401.           switch (y) {
  10402.         case SSHA_ADD:        /* SSH AGENT ADD ... */
  10403.           if ((x = cmifi("Identity file","",&s,&y,xxstring)) < 0) {
  10404. #ifndef SSHTEST
  10405.               if (x == -3)    /* No name given */
  10406.             doeach = 1;    /* so do them all */
  10407.               else
  10408. #endif /* SSHTEST */
  10409.             return(x);
  10410.           }
  10411.           ckstrncpy(line,s,LINBUFSIZ);
  10412.           if ((x = cmcfm()) < 0)
  10413.             return(x);
  10414. #ifdef SSHTEST
  10415.           x = 0;
  10416. #else
  10417.           if (doeach) {
  10418.                       int i;
  10419.                       x = 0;
  10420.                       for (i = 0; i < ssh_idf_n; i++)
  10421.             x += ssh_agent_add_file(ssh_idf[i]);
  10422.           } else
  10423.             x = ssh_agent_add_file(line);
  10424. #endif /* SSHTEST */
  10425.           return(success = (x == 0));
  10426.  
  10427.         case SSHA_DEL: {    /* SSH AGENT DELETE ... */
  10428.             int doall = 0;
  10429.             if ((x = cmifi("Identity file","",&s,&y,xxstring)) < 0) {
  10430. #ifndef SSHTEST
  10431.             if (x == -3)    /* No name given */
  10432.               doall = 1;    /* so do them all */
  10433.             else
  10434. #endif /* SSHTEST */
  10435.               return(x);
  10436.             }
  10437.             ckstrncpy(line,s,LINBUFSIZ);
  10438.             if ((x = cmcfm()) < 0)
  10439.               return(x);
  10440. #ifdef SSHTEST
  10441.             x = 0;
  10442. #else
  10443.             if (doall)
  10444.               x = ssh_agent_delete_all();
  10445.             else
  10446.               x = ssh_agent_delete_file(line);
  10447. #endif /* SSHTEST */
  10448.             return(success = (x == 0));
  10449.         }
  10450.         case SSHA_LST: {
  10451.             int fingerprint = 0;
  10452.             if ((y = cmswi(sshagtsw,nsshagtsw,"","",xxstring)) < 0) {
  10453.             if (y != -3)
  10454.               return(y);
  10455.             } else if (cmgbrk() > SP) {
  10456.             printf("?This switch does not take an argument\n");
  10457.             return(-9);
  10458.             } else if (y == SSHASW_FP) {
  10459.             fingerprint = 1;
  10460.             }
  10461.             if ((x = cmcfm()) < 0)
  10462.               return(x);
  10463. #ifdef SSHTEST
  10464.             return(success = 1);
  10465. #else
  10466.             return(success =
  10467.                (ssh_agent_list_identities(fingerprint) == 0));
  10468. #endif /* SSHTEST */
  10469.         }
  10470.         default:
  10471.           return(-2);
  10472.           }
  10473.       }
  10474.       case XSSH_ADD: {        /* SSH ADD */
  10475.           /* ssh add { local, remote } port host port */
  10476.           int cx, i, j, k;
  10477.           char * h;
  10478.           if ((cx = cmkey(addfwd,naddfwd,"","", xxstring)) < 0)
  10479.         return(cx);
  10480.           if ((x = cmnum((cx == SSHF_LCL) ?
  10481.                  "Local port number" : "Remote port number",
  10482.                  "",10,&j,xxstring)) < 0)
  10483.         return(x);
  10484.           if ((x = cmfld("Host","",&s,xxstring)) < 0)
  10485.         return(x);
  10486.           makestr(&h,s);
  10487.           if ((x = cmnum("Port","",10,&k,xxstring)) < 0)
  10488.         return(x);
  10489.           if ((x = cmcfm()) < 0)
  10490.         return(x);
  10491.  
  10492.           switch(cx) {
  10493.         case SSHF_LCL:
  10494.            if (ssh_pf_lcl_n == 32) {
  10495.                printf(
  10496. "?Maximum number of local port forwardings already specified\n"
  10497.                  );
  10498.                free(h);
  10499.                return(success = 0);
  10500.           }
  10501.           ssh_pf_lcl[ssh_pf_lcl_n].p1 = j;
  10502.           makestr(&(ssh_pf_lcl[ssh_pf_lcl_n].host),h);
  10503.           makestr(&h,NULL);
  10504.           ssh_pf_lcl[ssh_pf_lcl_n].p2 = k;
  10505.           ssh_pf_lcl_n++;
  10506.           break;
  10507.         case SSHF_RMT:
  10508.           if (ssh_pf_rmt_n == 32) {
  10509.               printf(
  10510. "?Maximum number of remote port forwardings already specified\n"
  10511.                 );
  10512.               free(h);
  10513.               return(success = 0);
  10514.           }
  10515.           ssh_pf_rmt[ssh_pf_rmt_n].p1 = j;
  10516.           makestr(&(ssh_pf_rmt[ssh_pf_rmt_n].host),h);
  10517.           makestr(&h,NULL);
  10518.           ssh_pf_rmt[ssh_pf_rmt_n].p2 = k;
  10519.           ssh_pf_rmt_n++;
  10520.           }
  10521.           return(success = 1);
  10522.       }
  10523.       /* Not supporting arbitrary forwarding yet */
  10524.       case XSSH_FLP:        /* SSH FORWARD-LOCAL-PORT */
  10525.       case XSSH_FRP: {        /* SSH FORWARD-REMOTE-PORT */
  10526.           int li_port = 0;
  10527.           int to_port = 0;
  10528.           char * fw_host = NULL;
  10529.           int n;
  10530.               if ((x = cmnum(cmresult.nresult == XSSH_FLP ?
  10531.                               "local-port":"remote-port",
  10532.                               "",10,&li_port,xxstring)) < 0)
  10533.                   return(x);
  10534.               if (li_port < 1 || li_port > 65535) {
  10535.                   printf("?Out range - min: 1, max: 65535\n");
  10536.                   return(-9);
  10537.               }
  10538.           if ((x = cmfld("host",ssh_hst?ssh_hst:"",&s,xxstring)) < 0)
  10539.         return(x);
  10540.               n = ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  10541.               fw_host = tmpbuf;
  10542.               if ((x = cmnum("host-port",ckuitoa(li_port),10,
  10543.                               &to_port,xxstring)) < 0)
  10544.                   return(x);
  10545.               if (to_port < 1 || to_port > 65535) {
  10546.                   printf("?Out range - min: 1, max: 65535\n");
  10547.                   return(-9);
  10548.               }
  10549.           if ((x = cmcfm()) < 0)
  10550.         return(x);
  10551.           switch (cmresult.nresult) {
  10552.                 case XSSH_FLP:    /* SSH FORWARD-LOCAL-PORT */
  10553. #ifndef SSHTEST
  10554.                   ssh_fwd_local_port(li_port,fw_host,to_port);
  10555. #endif /* SSHTEST */
  10556.           return(success = 1);
  10557.         case XSSH_FRP:    /* SSH FORWARD-REMOTE-PORT */
  10558. #ifndef SSHTEST
  10559.                   ssh_fwd_remote_port(li_port,fw_host,to_port);
  10560. #endif /* SSHTEST */
  10561.           return(success = 1);
  10562.           }
  10563.           return(success = 1);
  10564.       }
  10565.     case XSSH_V2:        /* SSH V2 */
  10566.       if ((cx = cmkey(ssh2tab,nssh2tab,"","", xxstring)) < 0)
  10567.         return(cx);
  10568.       switch (cx) {
  10569.         case XSSH2_RKE:
  10570.           if ((x = cmcfm()) < 0)
  10571.         return(x);
  10572. #ifndef SSHTEST
  10573.           ssh_v2_rekey();
  10574. #endif /* SSHTEST */
  10575.           return(success = 1);
  10576.         default:
  10577.           return(-2);
  10578.       }
  10579.     case XSSH_KEY:
  10580.       if ((cx = cmkey(sshkey,nsshkey,"","", xxstring)) < 0)
  10581.         return(cx);
  10582.       switch (cx) {
  10583.         case SSHK_PASS: {    /* Change passphrase */
  10584.           char * oldp = NULL, * newp = NULL;
  10585.           struct FDB df, sw;
  10586.           cmfdbi(&sw,
  10587.              _CMKEY,        /* fcode */
  10588.              "Filename, or switch", /* hlpmsg */
  10589.              "",        /* default */
  10590.              "",        /* addtl string data */
  10591.              2,            /* addtl numeric data 1: tbl size */
  10592.              4,            /* addtl numeric data 2: 4 = cmswi */
  10593.              xxstring,        /* Processing function */
  10594.              sshkpsw,        /* Keyword table */
  10595.              &df        /* Pointer to next FDB */
  10596.              );
  10597.           cmfdbi(&df,        /* 2nd FDB - file for display */
  10598.              _CMIFI,        /* output file */
  10599.              "",        /* hlpmsg */
  10600.              "",        /* default */
  10601.              "",        /* addtl string data */
  10602.              0,            /* addtl numeric data 1 */
  10603.              0,            /* addtl numeric data 2 */
  10604.              xxstring,
  10605.              NULL,
  10606.              NULL
  10607.              );
  10608.           line[0] = NUL;
  10609.  
  10610.           while (1) {
  10611.           x = cmfdb(&sw);
  10612.           if (x == -3) break;
  10613.           if (x < 0)
  10614.             return(x);
  10615.           if (cmresult.fcode != _CMKEY)
  10616.             break;
  10617.           if (!cmgbrk()) {
  10618.               printf("?This switch requires an argument\n");
  10619.               return(-9);
  10620.           }
  10621.           if ((y = cmfld("Passphrase","",&s,xxstring)) < 0)
  10622.             return(y);
  10623.           switch (cmresult.nresult) {
  10624.             case 1:        /* Old */
  10625.               makestr(&oldp,s);
  10626.               break;
  10627.             case 2:        /* New */
  10628.               makestr(&newp,s);
  10629.           }
  10630.           }
  10631.           if (cmresult.fcode == _CMIFI) { /* Filename */
  10632.           ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  10633.           if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
  10634.             ckstrncpy(line,tmpbuf,LINBUFSIZ);
  10635.           }
  10636.           if ((x = cmcfm()) < 0) return(x);
  10637.  
  10638. #ifndef SSHTEST
  10639.           x = sshkey_change_passphrase(line[0] ? line : NULL,
  10640.                          oldp, newp);
  10641. #endif /* SSHTEST */
  10642.           makestr(&oldp,NULL);
  10643.           makestr(&newp,NULL);
  10644.           success = (x == 0);
  10645.           return(success);
  10646.         }
  10647.         case SSHK_CREA: {    /* SSH KEY CREATE /switches... */
  10648.           int bits = 1024, keytype = SSHKT_2R;
  10649.           char * pass = NULL, * comment = NULL;
  10650.           struct FDB df, sw;
  10651.  
  10652.               /*
  10653.                * char * sshkey_default_file(int keytype) 
  10654.                * will provide the default filename for a given keytype
  10655.                * is it possible to have the default value for the 2nd
  10656.                * FDB set and changed when a /TYPE switch is provided?
  10657.                * Would this allow for tab completion of the filename?
  10658.                */
  10659.           cmfdbi(&sw,
  10660.              _CMKEY,        /* fcode */
  10661.              "Filename, or switch", /* hlpmsg */
  10662.              "",        /* default */
  10663.              "",        /* addtl string data */
  10664.              nsshkcrea,        /* addtl numeric data 1: tbl size */
  10665.              4,            /* addtl numeric data 2: 4 = cmswi */
  10666.              xxstring,        /* Processing function */
  10667.              sshkcrea,        /* Keyword table */
  10668.              &df        /* Pointer to next FDB */
  10669.              );
  10670.           cmfdbi(&df,        /* 2nd FDB - file for display */
  10671.              _CMOFI,        /* output file */
  10672.              "",        /* hlpmsg */
  10673.              "",        /* default */
  10674.              "",        /* addtl string data */
  10675.              0,            /* addtl numeric data 1 */
  10676.              0,            /* addtl numeric data 2 */
  10677.              xxstring,
  10678.              NULL,
  10679.              NULL
  10680.              );
  10681.           line[0] = NUL;
  10682.  
  10683.           while (1) {
  10684.           x = cmfdb(&sw);
  10685.           if (x == -3) break;
  10686.           if (x < 0)
  10687.             return(x);
  10688.           if (cmresult.fcode != _CMKEY)
  10689.             break;
  10690.           if (!cmgbrk()) {
  10691.               printf("?This switch requires an argument\n");
  10692.               return(-9);
  10693.           }
  10694.           switch (cmresult.nresult) {
  10695.             case SSHKC_BI:    /* /BITS:n */
  10696.               if ((y = cmnum("","1024",10,&z,xxstring)) < 0)
  10697.             return(y);
  10698.               if (z < 512 || z > 4096) {
  10699.               printf("?Out range - min: 512, max: 4096\n");
  10700.               return(-9);
  10701.               }
  10702.               bits = z;
  10703.               break;
  10704.             case SSHKC_PP:    /* /PASSPHRASE:blah */
  10705.               if ((y = cmfld("Passphrase","",&s,xxstring)) < 0)
  10706.             return(y);
  10707.               makestr(&pass,s);
  10708.               break;
  10709.             case SSHKC_TY:    /* /TYPE:keyword */
  10710.               if ((y = cmkey(sshkcty,nsshkcty,"",
  10711.                      "v2-rsa",xxstring)) < 0)
  10712.             return(y);
  10713.               keytype = y;
  10714.               break;
  10715.             case SSHKC_1R:    /* /COMMENT */
  10716.               if ((y = cmfld("Text","",&s,xxstring)) < 0)
  10717.             return(y);
  10718.               makestr(&comment,s);
  10719.               break;
  10720.           }
  10721.           }
  10722.           if (cmresult.fcode == _CMOFI) { /* Filename */
  10723.                   if (cmresult.sresult) {
  10724.                       ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  10725.                       if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
  10726.                           ckstrncpy(line,tmpbuf,LINBUFSIZ);
  10727.           }
  10728.           }
  10729.           if ((y = cmcfm()) < 0) /* Confirm */
  10730.         return(y);
  10731. #ifndef SSHTEST
  10732.           x = sshkey_create(line[0] ? line : NULL,
  10733.                 bits, pass, keytype, comment);
  10734.           if (pass)
  10735.         memset(pass,0,strlen(pass));
  10736. #endif /* SSHTEST */
  10737.           makestr(&pass,NULL);
  10738.           makestr(&comment,NULL);
  10739.           return(success = (x == 0));
  10740.         }
  10741.         case SSHK_DISP: {    /* SSH KEY DISPLAY /switches... */
  10742.           char c;
  10743.           int infmt = 0, outfmt = 0;
  10744.           struct FDB df, sw;
  10745.           cmfdbi(&sw,
  10746.              _CMKEY,        /* fcode */
  10747.              "Filename, or switch", /* hlpmsg */
  10748.              "",        /* default */
  10749.              "",        /* addtl string data */
  10750.              nsshdswi,        /* addtl numeric data 1: tbl size */
  10751.              4,            /* addtl numeric data 2: 4 = cmswi */
  10752.              xxstring,        /* Processing function */
  10753.              sshdswi,        /* Keyword table */
  10754.              &df        /* Pointer to next FDB */
  10755.              );
  10756.           cmfdbi(&df,        /* 2nd FDB - file for display */
  10757.              _CMIFI,        /* fcode */
  10758.              "",        /* hlpmsg */
  10759.              "",        /* default */
  10760.              "",        /* addtl string data */
  10761.              0,            /* addtl numeric data 1 */
  10762.              0,            /* addtl numeric data 2 */
  10763.              xxstring,
  10764.              NULL,
  10765.              NULL
  10766.              );
  10767.           line[0] = NUL;
  10768.  
  10769.           while (1) {
  10770.           x = cmfdb(&sw);
  10771.           if (x == -3) break;
  10772.           if (x < 0)
  10773.             return(x);
  10774.           if (cmresult.fcode != _CMKEY)
  10775.             break;
  10776.           if (!cmgbrk()) {
  10777.               printf("?This switch requires an argument\n");
  10778.               return(-9);
  10779.           }
  10780.           switch (cmresult.nresult) {
  10781. #ifdef COMMENT
  10782.             case SSHKD_IN:    /* /IN-FORMAT: */
  10783.               if ((y = cmkey(sshdifmt,nsshdifmt,
  10784.                      "","",xxstring)) < 0)
  10785.             return(y);
  10786.               infmt = y;
  10787.               break;
  10788. #endif /* COMMENT */
  10789.             case SSHKD_OUT:    /* /FORMAT: */
  10790.               if ((y = cmkey(sshdofmt,nsshdofmt,
  10791.                      "","",xxstring)) < 0)
  10792.             return(y);
  10793.               outfmt = y;
  10794.               break;
  10795.           }
  10796.           }
  10797.           if (cmresult.fcode == _CMIFI) { /* Filename */
  10798.           ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  10799.           if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
  10800.             ckstrncpy(line,tmpbuf,LINBUFSIZ);
  10801.           }
  10802. #ifdef COMMENT
  10803.           if (!line[0]) {
  10804.           printf("?Key filename required\n");
  10805.           return(-9);
  10806.           }
  10807. #endif /* COMMENT */
  10808.           if ((y = cmcfm()) < 0) /* Confirm */
  10809.         return(y);
  10810. #ifndef SSHTEST
  10811.           switch (outfmt) {
  10812.         case SKDF_OSSH:
  10813.                   /* 2nd param is optional passphrase */
  10814.           x = sshkey_display_public(line[0] ? line : NULL, NULL);
  10815.           break;
  10816.         case SKDF_SSHC:
  10817.                   /* 2nd param is optional passphrase */
  10818.           x = sshkey_display_public_as_ssh2(line[0] ? line : NULL,
  10819.                             NULL);
  10820.           break;
  10821.         case SKDF_IETF:
  10822.           x = sshkey_display_fingerprint(line[0] ? line : NULL, 1);
  10823.           break;
  10824.         case SKDF_FING:
  10825.           x = sshkey_display_fingerprint(line[0] ? line : NULL, 0);
  10826.           break;
  10827.           }
  10828. #endif /* SSHTEST */
  10829.           return(success = (x == 0));
  10830.         }
  10831.         case SSHK_V1:        /* SSH KEY V1 SET-COMMENT */
  10832.           if ((x = cmkey(sshkv1,1,"","set-comment", xxstring)) < 0)
  10833.         return(x);
  10834.           if (x != 1) return(-2);
  10835.           if ((x = cmifi("Key file name","",&s,&y,xxstring)) < 0) {
  10836.           if (x == -3) {
  10837.               printf("?Name of key file required\n");
  10838.               return(-9);
  10839.           }
  10840.           }
  10841.           ckstrncpy(line,s,LINBUFSIZ);
  10842.           if ((x = cmtxt("Comment text","",&s,xxstring)) < 0)
  10843.         return(x);
  10844. #ifndef SSHTEST
  10845.           x = sshkey_v1_change_comment(line,  /* filename */
  10846.                        s,     /* new comment */
  10847.                        NULL   /* passphrase */
  10848.                        );
  10849. #endif /* SSHTEST */
  10850.           success = (x == 0);
  10851.           return(success);
  10852.       }
  10853.       default:
  10854.         return(-2);
  10855.     }
  10856. #else  /* SSHBUILTIN */
  10857. #ifdef SSHCMD
  10858.     x = nettype;
  10859.     if ((y = setlin(XXSSH,0,1)) < 0) {
  10860.         if (errno)
  10861.           printf("?%s\n",ck_errstr());
  10862.             else
  10863. #ifdef COMMENT
  10864.         /* This isn't right either because it catches command editing */
  10865.           printf("?Sorry, pseudoterminal open failed\n");
  10866.             if (hints)
  10867.           printf("Hint: Try \"ssh -t %s\"\n",line);
  10868. #else
  10869.           return(y);
  10870. #endif /* COMMENT */
  10871.         nettype = x;        /* Failed, restore net type. */
  10872.         ttnproto = z;        /* and protocol */
  10873.         success = 0;
  10874.     }
  10875.     didsetlin++;
  10876.     netsave = x;
  10877.     return(y);
  10878. #endif /* SSHCMD */
  10879. #endif /* SSHBUILTIN */
  10880.     }
  10881. #endif /* ANYSSH */
  10882.  
  10883.     if (cx == XXRLOG) {            /* RLOGIN */
  10884. #ifdef RLOGCODE
  10885.     int x,z;
  10886. #ifdef OS2
  10887.     if (!tcp_avail) {
  10888.         printf("?Sorry, either TCP/IP is not available on this system or\n\
  10889. necessary DLLs did not load.  Use SHOW NETWORK to check network status.\n"
  10890.            );
  10891.         success = 0;
  10892.         return(-9);
  10893.     } else {
  10894. #endif /* OS2 */
  10895.         x = nettype;        /* Save net type in case of failure */
  10896.         z = ttnproto;        /* Save protocol in case of failure */
  10897.         nettype = NET_TCPB;
  10898.         ttnproto = NP_RLOGIN;
  10899.         if ((y = setlin(XYHOST,0,1)) <= 0) {
  10900.         nettype = x;        /* Failed, restore net type. */
  10901.         ttnproto = z;        /* and protocol */
  10902.         success = 0;
  10903.         }
  10904.         didsetlin++;
  10905. #ifdef OS2
  10906.     }
  10907. #endif /* OS2 */
  10908.     return(y);
  10909. #else
  10910.     printf("?Sorry, RLOGIN is not configured in this copy of C-Kermit.\n");
  10911.     return(-9);
  10912. #endif /* RLOGCODE */
  10913.     }
  10914. #endif /* NETCONN */
  10915. #endif /* NOLOCAL */
  10916.  
  10917. #ifndef NOXMIT
  10918.     if (cx == XXTRA) {            /* TRANSMIT */
  10919.     extern int xfrxla;
  10920.     int i, n, xpipe = 0, xbinary = 0, xxlate = 1, xxnowait = 0, getval;
  10921.     int xxecho = 0;
  10922.     int scan = 1;
  10923.     char c;
  10924.     struct FDB sf, sw, tx;        /* FDBs for parse functions */
  10925. #ifndef NOCSETS
  10926.     extern int tcs_transp;        /* Term charset is transparent */
  10927. #else
  10928.     int tcs_transp = 1;
  10929. #endif /* NOCSETS */
  10930.  
  10931. #ifdef COMMENT
  10932.     xbinary = binary;        /* Default text/binary mode */
  10933. #else
  10934.     xbinary = 0;            /* Default is text */
  10935. #endif /* COMMENT */
  10936.     xxecho = xmitx;
  10937.  
  10938.     cmfdbi(&sw,            /* First FDB - command switches */
  10939.            _CMKEY,            /* fcode */
  10940.            "Filename, or switch",    /* hlpmsg */
  10941.            "",            /* default */
  10942.            "",            /* addtl string data */
  10943.            nxmitsw,            /* addtl numeric data 1: tbl size */
  10944.            4,            /* addtl numeric data 2: 4 = cmswi */
  10945.            xxstring,        /* Processing function */
  10946.            xmitsw,            /* Keyword table */
  10947.            &sf            /* Pointer to next FDB */
  10948.            );
  10949.     cmfdbi(&sf,            /* 2nd FDB - file to send */
  10950.            _CMIFI,            /* fcode */
  10951.            "File to transmit",    /* hlpmsg */
  10952.            "",            /* default */
  10953.            "",            /* addtl string data */
  10954.            0,            /* addtl numeric data 1 */
  10955.            0,            /* addtl numeric data 2 */
  10956.            xxstring,
  10957.            NULL,
  10958. #ifdef PIPESEND
  10959.            &tx
  10960. #else
  10961.            NULL
  10962. #endif /* PIPESEND */
  10963.            );
  10964. #ifdef PIPESEND
  10965.         cmfdbi(&tx,
  10966.            _CMTXT,            /* fcode */
  10967.            "Command",        /* hlpmsg */
  10968.            "",            /* default */
  10969.            "",            /* addtl string data */
  10970.            0,            /* addtl numeric data 1 */
  10971.            0,            /* addtl numeric data 2 */
  10972.            xxstring,
  10973.            NULL,
  10974.            NULL
  10975.            );
  10976. #endif /* PIPESEND */
  10977.  
  10978.     while (1) {
  10979.         x = cmfdb(&sw);
  10980.         if (x < 0)
  10981.           return(x);
  10982.         if (cmresult.fcode != _CMKEY)
  10983.           break;
  10984.         c = cmgbrk();        /* Have switch, get break character */
  10985.         if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  10986.         printf("?This switch does not take an argument\n");
  10987.         return(-9);
  10988.         }
  10989.         if (!getval && (cmgkwflgs() & CM_ARG)) {
  10990.         printf("?This switch requires an argument\n");
  10991.         return(-9);
  10992.         }
  10993.         n = cmresult.nresult;    /* Numeric result = switch ID */
  10994.         switch (n) {        /* Process the switch */
  10995. #ifdef PIPESEND
  10996.           case XMI_CMD:        /* Transmit from a command */
  10997.         if (nopush) {
  10998.             printf("?Sorry, system command access is disabled\n");
  10999.             return(-9);
  11000.         }
  11001.         sw.hlpmsg = "Command, or switch"; /* Change help message */
  11002.         xpipe = 1;        /* (No way to undo this one) */
  11003.         break;
  11004. #endif /* PIPESEND */
  11005.  
  11006.           case XMI_BIN:        /* Binary */
  11007.         xbinary = 1;
  11008.         xxlate = 0;        /* Don't translate charsets */
  11009.         scan = 0;
  11010.         break;
  11011.  
  11012.           case XMI_TXT:        /* Text */
  11013.         xbinary = 0;
  11014.         xxlate = !tcs_transp;    /* Translate if TERM CHAR not TRANSP */
  11015.         scan = 0;
  11016.         break;
  11017.  
  11018.           case XMI_TRA:        /* Transparent text */
  11019.         xbinary = 0;
  11020.         xxlate = 0;        /* But don't translate charsets */
  11021.         scan = 0;
  11022.         break;
  11023.  
  11024. #ifdef COMMENT
  11025.           case XMI_VRB:        /* /VERBOSE */
  11026.           case XMI_QUI:        /* /QUIET */
  11027.         break;            /* (not implemented yet) */
  11028. #endif /* COMMENT */
  11029.  
  11030.           case XMI_NOW:        /* /NOWAIT */
  11031.         xxnowait = 1;
  11032.         break;
  11033.  
  11034.           case XMI_NOE:        /* /NOWAIT */
  11035.         xxecho = 0;
  11036.         break;
  11037.  
  11038.           default:
  11039.         return(-2);
  11040.         }
  11041.  
  11042.     }
  11043.     if (cmresult.fcode != _CMIFI && cmresult.fcode != _CMTXT)
  11044.       return(-2);
  11045.     ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Filename */
  11046.     if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
  11047.       ckstrncpy(line,tmpbuf,LINBUFSIZ);
  11048.     s = line;
  11049.     if ((y = cmcfm()) < 0)        /* Confirm */
  11050.       return(y);
  11051. #ifdef CK_APC
  11052.     if ((apcactive == APC_LOCAL) ||
  11053.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  11054.       return(success = 0);
  11055. #endif /* CK_APC */
  11056.     if (cmresult.nresult != 0) {
  11057.         printf("?Only a single file may be transmitted\n");
  11058.         return(-9);
  11059.     }
  11060. #ifdef PIPESEND
  11061.     if (xpipe) {
  11062.         s = brstrip(s);
  11063.         if (!*s) {
  11064.         printf("?Sorry, a command to send from is required\n");
  11065.         return(-9);
  11066.         }
  11067.         pipesend = 1;
  11068.     }
  11069. #endif /* PIPESEND */
  11070.  
  11071.     if (scan && (filepeek
  11072. #ifndef NOXFER
  11073.              || patterns
  11074. #endif /* NOXFER */
  11075.              )) {        /* If user didn't specify type */
  11076.         int k, x;                  /* scan the file to see */
  11077.         x = -1;
  11078.         k = scanfile(s,&x,nscanfile);
  11079.         if (k > 0) xbinary = (k == FT_BIN) ? XYFT_B : XYFT_T;
  11080.     }
  11081.     if (!xfrxla) xxlate = 0;
  11082.     success = transmit(s,
  11083.                (char) (xxnowait ? '\0' : (char)xmitp),
  11084.                xxlate,
  11085.                xbinary,
  11086.                xxecho
  11087.                );
  11088.     return(success);
  11089.     }
  11090. #endif /* NOXMIT */
  11091.  
  11092. #ifndef NOFRILLS
  11093.     if (cx == XXTYP  || cx == XXCAT || cx == XXMORE ||
  11094.     cx == XXHEAD || cx == XXTAIL) {
  11095.     int paging = 0, havename = 0, head = 0, width = 0, count = 0;
  11096.     char pfxbuf[64], * prefix = NULL;
  11097.     char outfile[CKMAXPATH+1];
  11098.     struct FDB sf, sw;
  11099.     char * pat = NULL;
  11100.     int incs = 0, outcs = 0, cset = -1, number = 0;
  11101. #ifdef UNICODE
  11102.         char * tocs = "";
  11103.     extern int fileorder;
  11104. #ifdef OS2
  11105. #ifndef NOCSETS
  11106.     extern int tcsr, tcsl;
  11107. #endif /* NOCSETS */
  11108. #endif /* OS2 */
  11109. #endif /* UNICODE */
  11110.  
  11111.     outfile[0] = NUL;
  11112.  
  11113.     if (cx == XXMORE)
  11114.       paging = 1;
  11115.     else if (cx == XXCAT)
  11116.       paging = 0;
  11117.     else
  11118.       paging = (typ_page < 0) ? xaskmore : typ_page;
  11119.     if (paging < 0)
  11120.       paging = saveask;
  11121.  
  11122.     if (cx == XXHEAD) {
  11123.         head = 10;
  11124.         cx = XXTYP;
  11125.     } else if (cx == XXTAIL) {
  11126.         head = -10;
  11127.         cx = XXTYP;
  11128.     }
  11129.  
  11130. #ifdef IKSD
  11131.     if (inserver && !ENABLED(en_typ)) {
  11132.         printf("?Sorry, TYPE command disabled\n");
  11133.         return(-9);
  11134.     }
  11135. #endif /* IKSD */
  11136.  
  11137.     cmfdbi(&sw,            /* 2nd FDB - optional /PAGE switch */
  11138.            _CMKEY,            /* fcode */
  11139.            "Filename or switch",    /* hlpmsg */
  11140.            "",            /* default */
  11141.            "",            /* addtl string data */
  11142.            ntypetab,        /* addtl numeric data 1: tbl size */
  11143.            4,            /* addtl numeric data 2: 4 = cmswi */
  11144.            xxstring,        /* Processing function */
  11145.            typetab,            /* Keyword table */
  11146.            &sf            /* Pointer to next FDB */
  11147.            );
  11148.     cmfdbi(&sf,            /* 1st FDB - file to type */
  11149.            _CMIFI,            /* fcode */
  11150.            "",            /* hlpmsg */
  11151.            "",            /* default */
  11152.            "",            /* addtl string data */
  11153.            0,            /* addtl numeric data 1 */
  11154.            0,            /* addtl numeric data 2 */
  11155.            xxstring,
  11156.            NULL,
  11157.            NULL
  11158.            );
  11159.  
  11160.     while (!havename) {
  11161.         x = cmfdb(&sw);        /* Parse something */
  11162.         debug(F101,"type cmfdb","",x);
  11163.         debug(F101,"type cmresult.fcode","",cmresult.fcode);
  11164.         debug(F101,"type cmresult.nresult","",cmresult.nresult);
  11165.         if (x < 0) {            /* Error */
  11166.         if (x == -3) {
  11167.             x = -9;
  11168.             printf("?Filename required\n");
  11169.         }
  11170.         return(x);
  11171.         } else if (cmresult.fcode == _CMKEY) {
  11172.         char c; int getval;
  11173.         c = cmgbrk();
  11174.         getval = (c == ':' || c == '=');
  11175.         if (getval && !(cmgkwflgs() & CM_ARG)) {
  11176.             printf("?This switch does not take an argument\n");
  11177.             return(-9);
  11178.         }
  11179. #ifdef COMMENT
  11180.         if (!getval && (cmgkwflgs() & CM_ARG)) {
  11181.             printf("?This switch requires an argument\n");
  11182.             /* Not if it has a default! */
  11183.             return(-9);
  11184.         }
  11185. #endif /* COMMENT */
  11186.         switch (cmresult.nresult) {
  11187. #ifdef CK_TTGWSIZ
  11188.           case TYP_PAG:
  11189.             paging = 1;
  11190.             break;
  11191.  
  11192.           case TYP_NOP:
  11193.             paging = 0;
  11194.             break;
  11195. #endif /* CK_TTGWSIZ */
  11196.  
  11197.           case TYP_COU:
  11198.             paging = 0;
  11199.             count = 1;
  11200.             break;
  11201.  
  11202.           case TYP_HEA:
  11203.           case TYP_TAI:
  11204.             y = 10;
  11205.             if (getval)
  11206.               if ((x = cmnum("Number of lines",
  11207.                      "10",10,&y,xxstring)) < 0)
  11208.             return(x);
  11209.             head = (cmresult.nresult == TYP_TAI) ? -y : y;
  11210.             break;
  11211.  
  11212.           case TYP_WID:
  11213.             y = typ_wid > -1 ? typ_wid : cmd_cols;
  11214.             if (getval)
  11215.               if ((x = cmnum("Column at which to truncate",
  11216.                      ckitoa(y),10,&y,xxstring)) < 0)
  11217.             return(x);
  11218.             width = y;
  11219.             break;
  11220.  
  11221.           case TYP_PAT:
  11222.             if (!getval && (cmgkwflgs() & CM_ARG)) {
  11223.             printf("?This switch requires an argument\n");
  11224.             return(-9);
  11225.             }
  11226.             if ((x = cmfld("pattern","",&s,xxstring)) < 0)
  11227.               return(x);
  11228.             ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  11229.             pat = tmpbuf;
  11230.             break;
  11231.  
  11232.           case TYP_PFX:
  11233.             if (!getval && (cmgkwflgs() & CM_ARG)) {
  11234.             printf("?This switch requires an argument\n");
  11235.             return(-9);
  11236.             }
  11237.             if ((x = cmfld("prefix for each line","",&s,xxstring)) < 0)
  11238.               return(x);
  11239.             if ((int)strlen(s) > 63) {
  11240.             printf("?Too long - 63 max\n");
  11241.             return(-9);
  11242.             }
  11243.             ckstrncpy(pfxbuf,s,64);
  11244.             prefix = brstrip(pfxbuf);
  11245.             number = 0;
  11246.             break;
  11247.  
  11248.           case TYP_NUM:        /* /NUMBER */
  11249.             number = 1;
  11250.             prefix = NULL;
  11251.             break;
  11252.  
  11253. #ifdef UNICODE
  11254.           case TYP_XPA:        /* /TRANSPARENT */
  11255.             incs = 0;
  11256.             cset = 0;
  11257.             outcs = -1;
  11258.             break;
  11259.  
  11260.           case TYP_XIN:        /* /CHARACTER-SET: */
  11261.             if (!getval && (cmgkwflgs() & CM_ARG)) {
  11262.             printf("?This switch requires an argument\n");
  11263.             return(-9);
  11264.             }
  11265.             if ((incs = cmkey(fcstab,nfilc,
  11266.                       "character-set name","",xxstring)) < 0) {
  11267.             if (incs == -3)    /* Note: No default */
  11268.               incs = -2;
  11269.             return(incs);
  11270.             }
  11271.             cset = incs;
  11272.             break;
  11273.  
  11274.           case TYP_XUT:        /* /TRANSLATE-TO: */
  11275.             if (!getval && (cmgkwflgs() & CM_ARG)) {
  11276.             printf("?This switch requires an argument\n");
  11277.             return(-9);
  11278.             }
  11279. #ifdef OS2
  11280.             if (!inserver && !k95stdout) {
  11281.             tocs = "ucs2";
  11282.             } else {
  11283. #ifdef CKOUNI
  11284.             tocs = rlookup(txrtab,ntxrtab,tcsl);
  11285. #else /* CKOUNI */
  11286.             extern struct keytab ttcstab[];
  11287.             extern int ntxrtab;
  11288.             tocs = rlookup(ttcstab,ntermc,tocs);
  11289.             if (!tocs)
  11290.               tocs = getdcset();
  11291. #endif /* CKOUNI */
  11292.                     }
  11293. #else /* OS2 */
  11294.             tocs = getdcset();
  11295. #endif /* OS2 */
  11296.             if ((outcs = cmkey(fcstab,nfilc,
  11297.                        "character-set",tocs,xxstring)) < 0)
  11298.               return(outcs);
  11299.             break;
  11300. #endif /* UNICODE */
  11301.           case TYP_OUT:
  11302.             if ((x = cmofi("File for result lines","",
  11303.                    &s,xxstring)) < 0)
  11304.               return(x);
  11305.             ckstrncpy(outfile,s,CKMAXPATH);
  11306.             break;
  11307.         }
  11308.         } else if (cmresult.fcode == _CMIFI)
  11309.           havename = 1;
  11310.         else
  11311.           return(-2);
  11312.     }
  11313.     if (havename) {
  11314.         ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  11315.         y = cmresult.nresult;
  11316.     } else {
  11317.         if ((x = cmifi("Filename","",&s,&y,xxstring)) < 0) {
  11318.         if (x == -3) {
  11319.             printf("?Name of an existing file required\n");
  11320.             return(-9);
  11321.         } else return(x);
  11322.         }
  11323.         ckstrncpy(line,s,LINBUFSIZ);
  11324.     }
  11325.     if (y != 0) {
  11326.         printf("?A single file please\n");
  11327.         return(-9);
  11328.     }
  11329.     if ((y = cmcfm()) < 0)        /* Confirm the command */
  11330.       return(y);
  11331.  
  11332. #ifdef UNICODE
  11333.     fileorder = -1;
  11334.     if (cset < 0 && filepeek) {    /* If no charset switches given */
  11335.         int k, x = -1;
  11336.         k = scanfile(line,&x,nscanfile); /* Call file analyzer */
  11337.         debug(F111,"type scanfile",line,k);
  11338.         debug(F101,"type scanfile flag","",x);
  11339.         switch(k) {
  11340.           case FT_UTF8:        /* which can detect UTF-8... */
  11341.         cset = 0;
  11342.         incs = FC_UTF8;
  11343.         break;
  11344.           case FT_UCS2:        /* and UCS-2... */
  11345.         cset = 0;
  11346.         incs = FC_UCS2;
  11347.         fileorder = x;        /* even if there is no BOM. */
  11348.         debug(F101,"type fileorder","",fileorder);
  11349.         break;
  11350.         }
  11351.     }
  11352. #ifdef OS2
  11353.         if (cset < 0) {            /* If input charset still not known */
  11354. #ifdef CKOUNI
  11355.             tocs = rlookup(txrtab,ntxrtab,tcsl);
  11356. #else /* CKOUNI */
  11357.             extern struct keytab ttcstab[];
  11358.             extern int ntxrtab;
  11359.             tocs = rlookup(ttcstab,ntermc,incs);
  11360.             if (!tocs)
  11361.           tocs = getdcset();
  11362. #endif /* CKOUNI */
  11363.             incs = lookup(fcstab,tocs,nfilc,&x);
  11364.         }
  11365. #endif /* OS2 */
  11366.  
  11367.         if (outcs == 0 && incs != 0) {    /* Supply default target charset */
  11368.         int x = 0;            /* if switch not given. */
  11369.         tocs = getdcset();
  11370.         outcs = lookup(fcstab,tocs,nfilc,&x);
  11371.     }
  11372. #else  /* !UNICODE */
  11373.     if (cset < 0) incs = outcs = 0;
  11374. #endif /* UNICODE */
  11375.  
  11376.     if (outfile[0] && paging)    /* This combination makes no sense */
  11377.       paging = 0;            /* so turn off paging */
  11378.  
  11379.     if (count) paging = -1;
  11380.     debug(F111,"type",line,paging);
  11381.     s = outfile;
  11382.     success =
  11383.       dotype(line,paging,0,head,pat,width,prefix,incs,outcs,s,number);
  11384.     return(success);
  11385.     }
  11386. #endif /* NOFRILLS */
  11387.  
  11388. #ifndef NOCSETS
  11389.     if (cx == XXXLA) {            /* TRANSLATE file's charset */
  11390.     _PROTOTYP (int doxlate, ( void ) );
  11391.     return(doxlate());
  11392.     }
  11393. #endif /* NOCSETS */
  11394.  
  11395.     if (cx == XXVER) {            /* VERSION */
  11396.     int n = 0;
  11397.     extern char * ck_patch, * ck_s_test;
  11398. #ifdef COMMENT
  11399.     extern int hmtopline;
  11400. #endif /* COMMENT */
  11401.     if ((y = cmcfm()) < 0)
  11402.           return(y);
  11403.  
  11404.     printf("\n%s, for%s\n Numeric: %ld",versio,ckxsys,vernum);
  11405.     printf("\n");
  11406.     n = 3;
  11407.     if (*ck_s_test) {
  11408.         printf("\n THIS IS A TEST VERSION, NOT FOR PRODUCTION USE.\n");
  11409.         n += 2;
  11410.     }
  11411.     if (*ck_patch) {
  11412.         printf(" Patches: %s\n", ck_patch);
  11413.         n++;
  11414.     }
  11415.     printf(" Type COPYRIGHT for copyright information.\n\n");
  11416. #ifdef OS2
  11417.     shoreg();
  11418. #else
  11419. #ifdef COMMENT
  11420.     hmtopline = n+1;
  11421.     hmsga(copyright);
  11422.     hmtopline = 0;
  11423. #endif /* COMMENT */
  11424. #endif /* OS2 */
  11425.     return(success = 1);
  11426.     }
  11427.  
  11428.     if (cx == XXCPR) {            /* COPYRIGHT or LICENSE */
  11429.     if ((y = cmcfm()) < 0)
  11430.           return(y);
  11431. #ifdef OS2
  11432.     if (inserver) {            /* Free WIKSD */
  11433.         extern char * wiksdcpr[];
  11434.         hmsga(wiksdcpr);
  11435.     } else
  11436. #endif /* OS2 */
  11437.       hmsga(copyright);
  11438.     return(success = 1);
  11439.     }
  11440.  
  11441. #ifndef MAC                /* Only for multiuser systems */
  11442. #ifndef OS2
  11443. #ifndef NOFRILLS
  11444.     if (cx == XXWHO) {            /* WHO */
  11445.     char *wc;
  11446. #ifdef IKSD
  11447.     if (inserver && !ENABLED(en_who)) {
  11448.         printf("?Sorry, WHO command disabled\n");
  11449.         return(-9);
  11450.     }
  11451. #endif /* IKSD */
  11452. #ifdef datageneral
  11453.     if ((z = cmcfm()) < 0) return(z);
  11454.     if (nopush) {
  11455.         printf("?Sorry, who not allowed\n");
  11456.         return(success = 0);
  11457.     }
  11458.         xsystem(WHOCMD);
  11459. #else
  11460.     if ((y = cmtxt("user name","",&s,xxstring)) < 0) return(y);
  11461.         if (nopush) {
  11462.         printf("?Sorry, WHO command disabled\n");
  11463.         return(success = 0);
  11464.     }
  11465.     if (!(wc = getenv("CK_WHO"))) wc = WHOCMD;
  11466.     if (wc)
  11467.       if ((int) strlen(wc) > 0) {
  11468.           ckmakmsg(line,LINBUFSIZ,wc," ",s,NULL);
  11469.           xsystem(line);
  11470.       }
  11471. #endif /* datageneral */
  11472.     return(success = 1);
  11473.     }
  11474. #endif /* NOFRILLS */
  11475. #endif /* OS2 */
  11476. #endif /* MAC */
  11477.  
  11478. #ifndef NOFRILLS
  11479.     if (cx == XXWRI || cx == XXWRL || cx == XXWRBL) { /* WRITE */
  11480.     int x,y;            /* On stack in case of \fexec() */
  11481.     if ((x = cmkey(writab,nwri,"to file or log","",xxstring)) < 0) {
  11482.         if (x == -3) printf("?Write to what?\n");
  11483.         return(x);
  11484.     }
  11485.     if ((y = cmtxt("text","",&s,xxstring)) < 0) return(y);
  11486.     s = brstrip(s);
  11487.     switch (x) {
  11488.       case LOGD: y = ZDFILE; break;
  11489.       case LOGP: y = ZPFILE; break;
  11490. #ifndef NOLOCAL
  11491.       case LOGS: y = ZSFILE; break;
  11492. #endif /* NOLOCAL */
  11493.       case LOGT: y = ZTFILE; break;
  11494. #ifndef NOSPL
  11495.       case LOGW: y = ZWFILE; break;
  11496. #endif /* NOSPL */
  11497.       case LOGX:            /* SCREEN (stdout) */
  11498.       case LOGE:            /* ERROR  (stderr) */
  11499.         if (x == LOGE) {
  11500.         debug(F110,
  11501.               (cx == XXWRL) ? "WRITELN ERROR" : "WRITE ERROR", s,0);
  11502.         fprintf(stderr,"%s%s",s,(cx == XXWRL) ? "\n" : "");
  11503.         } else {
  11504.         debug(F110,
  11505.               (cx == XXWRL) ? "WRITELN SCREEN" : "WRITE SCREEN", s,0);
  11506.         printf("%s%s",s,(cx == XXWRL) ? "\n" : "");
  11507.         }
  11508.         return(success = 1);
  11509.       default: return(-2);
  11510.     }
  11511.     if (chkfn(y) > 0) {
  11512.         x = (cx == XXWRI) ? zsout(y,s) : zsoutl(y,s);
  11513.         if (x < 0) printf("?Write error\n");
  11514.     } else {
  11515.         x = -1;
  11516.         printf("?File or log not open\n");
  11517.     }
  11518.     return(success = (x == 0) ? 1 : 0);
  11519.     }
  11520. #endif /* NOFRILLS */
  11521.  
  11522. #ifndef NOXFER
  11523.     if (cx == XXASC || cx == XXBIN) {
  11524.     if ((x = cmcfm()) < 0) return(x);
  11525. #ifdef NEWFTP
  11526.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  11527.       return(success = doftptyp((cx == XXASC) ? 0 : 1));
  11528. #endif /* NEWFTP */
  11529.     binary = (cx == XXASC) ? XYFT_T : XYFT_B;
  11530.     return(success = 1);
  11531.     }
  11532. #endif /* NOXFER */
  11533.  
  11534.     if (cx == XXCLS) {
  11535.     if ((x = cmcfm()) < 0) return(x);
  11536.     y = ck_cls();
  11537.     return(success = (y > -1) ? 1 : 0);
  11538.     }
  11539.  
  11540. #ifdef CK_MKDIR
  11541.     if (cx == XXMKDIR || cx == XXLMKD) {
  11542.     char *p;
  11543. #ifdef LOCUS
  11544.     if (!locus && cx != XXLMKD) {
  11545. #ifdef NOXFER
  11546.         return(-2);
  11547. #else
  11548.         return(dormt(XZMKD));
  11549. #endif /* NOXFER */
  11550.         }
  11551. #endif /* LOCUS */
  11552. #ifdef IKSD
  11553.     if (inserver && !ENABLED(en_mkd)) {
  11554.         printf("?Sorry, directory creation is disabled\n");
  11555.         return(-9);
  11556.     }
  11557. #endif /* IKSD */
  11558.     if ((x = cmfld("Name for new directory","",&s,xxstring)) < 0) {
  11559.         if (x != -3) {
  11560.         return(x);
  11561.         } else {
  11562.         printf("?Directory name required\n");
  11563.         return(-9);
  11564.         }
  11565.     }
  11566.     ckstrncpy(line,s,LINBUFSIZ);
  11567.     s = line;
  11568.     if ((x = cmcfm()) < 0) return(x);
  11569.     s = brstrip(s);
  11570.     bgchk();            /* Set msgflg */
  11571.     x = ckmkdir(0,s,&p,msgflg,0);
  11572. #ifdef COMMENT
  11573.     if (msgflg && x == 0)
  11574.       printf("?Directory already exists\n");
  11575. #endif /* COMMENT */
  11576.     return(success = (x < 0) ? 0 : 1);
  11577.     }
  11578.     if (cx == XXRMDIR || cx == XXLRMD) { /* RMDIR */
  11579.     char *p;
  11580. #ifdef LOCUS
  11581.     if (!locus && cx != XXLRMD) {
  11582. #ifdef NOXFER
  11583.         return(-2);
  11584. #else
  11585.         return(dormt(XZRMD));
  11586. #endif /* NOXFER */
  11587.         }
  11588. #endif /* LOCUS */
  11589. #ifdef IKSD
  11590.     if (inserver && !ENABLED(en_rmd)) {
  11591.         printf("?Sorry, directory removal is disabled\n");
  11592.         return(-9);
  11593.     }
  11594. #endif /* IKSD */
  11595.     if ((x = cmdir("Name of directory to be removed","",&s,xxstring)) < 0)
  11596.       return(x);
  11597.     ckstrncpy(line,s,LINBUFSIZ);
  11598.     s = line;
  11599.     if ((x = cmcfm()) < 0) return(x);
  11600.     s = brstrip(s);
  11601.     x = ckmkdir(1,s,&p,msgflg,0);
  11602.     return(success = (x < 0) ? 0 : 1);
  11603.     }
  11604. #endif /* CK_MKDIR */
  11605.  
  11606. #ifdef TNCODE
  11607.     if (cx == XXTELOP)
  11608.       return(dotelopt());
  11609. #endif /* TNCODE */
  11610.  
  11611. #ifndef NOPUSH
  11612.     if (cx == XXNPSH) {
  11613.     if ((z = cmcfm()) < 0) return(z);
  11614.         nopush = 1;
  11615. #ifndef NOSERVER
  11616.         en_hos = 0;
  11617. #endif /* NOSERVER */
  11618. #ifdef PIPESEND
  11619.     usepipes = 0;
  11620. #endif /* PIPESEND */
  11621.         return(success = 1);
  11622.     }
  11623. #endif /* NOPUSH */
  11624.  
  11625. #ifdef OS2
  11626.     if (cx == XXNSCR) {
  11627.     if ((z = cmcfm()) < 0) return(z);
  11628.         tt_scroll = 0;
  11629.         return(success = 1);
  11630.     }
  11631. #endif /* OS2 */
  11632.  
  11633. #ifndef NOSPL
  11634.     if (cx == XXLOCAL)            /* LOCAL variable declarations */
  11635.       return(success = dolocal());
  11636. #endif /* NOSPL */
  11637.  
  11638.     if (cx == XXKERMI) {        /* The KERMIT command */
  11639.     char * list[65];
  11640.     extern char **xargv;
  11641.     extern int xargc;
  11642.     int i;
  11643.     if ((y = cmtxt("kermit command-line arguments, -h for help",
  11644.                "",&s,xxstring)) < 0)
  11645.       return(y);
  11646.     ckstrncpy(line,"kermit ",LINBUFSIZ);
  11647.     ckstrncat(line,s,LINBUFSIZ-8);
  11648.     xwords(line,64,list,0);
  11649.     for (i = 1; i < 64; i++) {
  11650.         if (!list[i])
  11651.           break;
  11652.     }
  11653.     i--;
  11654.     xargc = i;
  11655.     xargv = list;
  11656.     xargv++;
  11657.     sstate = cmdlin();
  11658.     if (sstate) {
  11659.         extern int justone;
  11660.         debug(F000,"KERMIT sstate","",sstate);
  11661.         justone = 1;        /* Force return to command mode */
  11662.         proto();            /* after protocol */
  11663.         return(success);
  11664.     } else {
  11665.         debug(F101,"KERMIT sstate","",sstate);
  11666.         return(success = 1);    /* Not exactly right, but... */
  11667.     }
  11668.     }
  11669.     if (cx == XXDATE) {            /* DATE command */
  11670.     extern char cmdatebuf[], * cmdatemsg;
  11671.  
  11672. #ifndef COMMENT
  11673.     char * dp;
  11674.     if ((y = cmtxt("date and/or time, or carriage return for current",
  11675.                "",&s,xxstring)) < 0)
  11676.       return(y);
  11677.     s = brstrip(s);
  11678.     dp = cmcvtdate(s,1);
  11679.     if (!dp) {
  11680.         printf("?%s\n",cmdatemsg ? cmdatemsg : "Date conversion error");
  11681.         success = 0;
  11682.     } else {
  11683.         printf("%s\n",dp);
  11684.         success = 1;
  11685.     }
  11686. #else
  11687.     /* This works fine but messes up my "dates" torture-test script */
  11688.  
  11689.     if ((x = cmdate("Date and/or time, or carriage return for current",
  11690.             "",&s,0,xxstring)) < 0) {
  11691.         return(x);
  11692.     } else {
  11693.         printf("%s\n",cmdatebuf);
  11694.         success = 1;
  11695.     }
  11696. #endif /* COMMENT */
  11697.     return(success);
  11698.     }
  11699. #ifndef NOPUSH
  11700. #ifndef NOFRILLS
  11701.     if (cx == XXEDIT)
  11702.       return(doedit());
  11703. #endif /* NOFRILLS */
  11704. #endif /* NOPUSH */
  11705.  
  11706. #ifdef BROWSER                /* Defined only ifndef NOPUSH */
  11707.     if (cx == XXBROWS)
  11708.       return(dobrowse());
  11709. #endif /* BROWSER */
  11710.  
  11711. #ifdef CK_TAPI
  11712.     if (cx == XXTAPI) {            /* Microsoft TAPI */
  11713.     return (success = dotapi());
  11714.     }
  11715. #endif /* CK_TAPI */
  11716.  
  11717. #ifndef NOXFER
  11718.     if (cx == XXWHERE) {
  11719.     extern char * rfspec, * sfspec, * srfspec, * rrfspec;
  11720.     if ((x = cmcfm()) < 0) return(x);
  11721.     printf("\nFile most recently...\n\n");
  11722.     printf("  Sent:       %s\n",   sfspec ? sfspec : "(none)");
  11723.     if (sfspec && srfspec) {
  11724.         printf("  Stored as:  %s\n",   srfspec);
  11725.         printf("\n");
  11726.     }
  11727.     printf("  Received:   %s\n",   rrfspec ? rrfspec : "(none)");
  11728.     if (rfspec && rrfspec)
  11729.     printf("  Stored as:  %s\n",   rfspec);
  11730.     printf(
  11731. "\nIf the full path is not shown, then the file is probably in your current\n"
  11732.            );
  11733.     printf(
  11734. "directory or your download directory (if any - SHOW FILE to find out).\n\n"
  11735.            );
  11736.     return(success = 1);
  11737.     }
  11738. #endif /* NOXFER */
  11739.  
  11740. #ifdef CK_RECALL
  11741.     if (cx == XXREDO)
  11742.       return(doredo());
  11743. #endif /* CK_RECALL */
  11744.  
  11745. #ifdef CKROOT
  11746.     if (cx == XXCHRT)            /* Change Kermit's root directory */
  11747.       return(dochroot());
  11748. #endif /* CKROOT */
  11749.  
  11750. #ifdef CK_KERBEROS
  11751.     if (cx == XXAUTH) {            /* KERBEROS */
  11752.     x = cp_auth();            /* Parse it */
  11753. #ifdef IKSD
  11754.         if (inserver) {
  11755.             printf("?Command disabled in IKSD.\r\n");
  11756.             return(success = 0);
  11757.         }
  11758. #endif /* IKSD */
  11759.     if (x < 0)            /* Pass parse errors back */
  11760.       return(x);
  11761.     return(success = doauth(cx));
  11762.     }
  11763. #endif /* CK_KERBEROS */
  11764.  
  11765. #ifndef NOLOCAL
  11766.     if (cx == XXTERM) {
  11767.     return(settrmtyp());
  11768.     }
  11769. #endif /* NOLOCAL */
  11770.  
  11771.     if (cx == XXSTATUS) {
  11772.     if ((x = cmcfm()) < 0) return(x);
  11773.     printf( " %s\n", success ? "SUCCESS" : "FAILURE" );
  11774.     return(0);            /* Don't change it */
  11775.     }
  11776.  
  11777.     if (cx == XXFAIL) {
  11778.     if ((x = cmcfm()) < 0) return(x);
  11779.     return(success = 0);
  11780.     }
  11781.  
  11782.     if (cx == XXSUCC) {
  11783.     if ((x = cmcfm()) < 0) return(x);
  11784.     return(success = 1);
  11785.     }
  11786.  
  11787.     if (cx == XXNLCL) {
  11788.     extern int nolocal;
  11789.     if ((x = cmcfm()) < 0) return(x);
  11790.     nolocal = 1;
  11791.     return(success = 1);
  11792.     }
  11793.  
  11794. #ifndef NOXFER
  11795.     if (cx == XXRASG)            /* Shortcuts for REMOTE commands */
  11796.       return(dormt(XZASG));
  11797.     if (cx == XXRCWD)
  11798.       return(dormt(XZCWD));
  11799.     if (cx == XXRCPY)
  11800.       return(dormt(XZCPY));
  11801.     if (cx == XXRDEL)
  11802.       return(dormt(XZDEL));
  11803.     if (cx == XXRDIR)
  11804.       return(dormt(XZDIR));
  11805.     if (cx == XXRXIT)
  11806.       return(dormt(XZXIT));
  11807.     if (cx == XXRHLP)
  11808.       return(dormt(XZHLP));
  11809.     if (cx == XXRHOS)
  11810.       return(dormt(XZHOS));
  11811.     if (cx == XXRKER)
  11812.       return(dormt(XZKER));
  11813.     if (cx == XXRPWD)
  11814.       return(dormt(XZPWD));
  11815.     if (cx == XXRQUE)
  11816.       return(dormt(XZQUE));
  11817.     if (cx == XXRREN)
  11818.       return(dormt(XZREN));
  11819.     if (cx == XXRMKD)
  11820.       return(dormt(XZMKD));
  11821.     if (cx == XXRRMD)
  11822.       return(dormt(XZRMD));
  11823.     if (cx == XXRSET)
  11824.       return(dormt(XZSET));
  11825.     if (cx == XXRSPA)
  11826.       return(dormt(XZSPA));
  11827.     if (cx == XXRTYP)
  11828.       return(dormt(XZTYP));
  11829.     if (cx == XXRWHO)
  11830.       return(dormt(XZWHO));
  11831.     if (cx == XXRCDUP)
  11832.       return(dormt(XZCDU));
  11833.     if (cx == XXRPRI)
  11834.       return(dormt(XZPRI));
  11835. #endif /* NOXFER */
  11836.  
  11837.     if (cx == XXRESET) {        /* RESET */
  11838.     if ((x = cmcfm()) < 0)
  11839.       return(x);
  11840.     doclean(0);            /* Close all files */
  11841.     return(success = 1);
  11842.     }
  11843.  
  11844. #ifndef NOXFER
  11845. #ifndef NOCSETS
  11846.     if (cx == XXASSOC)            /* ASSOCIATE */
  11847.       return(doassoc());
  11848. #endif /* NOCSETS */
  11849. #endif /* NOXFER */
  11850.  
  11851. #ifndef NOSPL
  11852.     if (cx == XXSHIFT) {        /* SHIFT */
  11853.     if ((y = cmnum("Number of arguments to shift","1",10,&x,xxstring)) < 0)
  11854.       return(y);
  11855.     if ((z = cmcfm()) < 0)
  11856.       return(z);
  11857.     return(success = doshift(x));
  11858.     }
  11859. #endif /* NOSPL */
  11860.  
  11861. #ifndef NOHELP
  11862.     if (cx == XXMAN)
  11863.       return(domanual());
  11864. #endif /* NOHELP */
  11865.  
  11866. #ifndef NOSPL
  11867.     if (cx == XXSORT)            /* SORT an array */
  11868.       return(dosort());
  11869. #endif /* NOSPL */
  11870.  
  11871.     if (cx == XXPURGE) {
  11872. #ifdef IKSD
  11873.     if (inserver && (!ENABLED(en_del)
  11874. #ifdef CK_LOGIN
  11875.                           || isguest
  11876. #endif /* CK_LOGIN */
  11877.              )) {
  11878.         printf("?Sorry, DELETE is disabled\n");
  11879.         return(-9);
  11880.     }
  11881. #endif /* IKSD */
  11882. #ifdef CK_APC
  11883.     if ((apcactive == APC_LOCAL) ||
  11884.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  11885.       return(success = 0);
  11886. #endif /* CK_APC */
  11887. #ifdef CKPURGE
  11888.         return(dopurge());
  11889. #else
  11890. #ifdef VMS
  11891.     if ((x = cmtxt("optional switches followed by filespec",
  11892.                "",&s,xxstring)) < 0)
  11893.       return(x);
  11894.     if (nopush) {
  11895.         printf("?Sorry, DCL access is disabled\n");
  11896.         return(-9);
  11897.     }
  11898.     ckstrncpy(line,s,LINBUFSIZ);
  11899.     s = line;
  11900.     x = mlook(mactab,"purge",nmac);
  11901.     return(success = dodo(x,s,cmdstk[cmdlvl].ccflgs));
  11902. #else
  11903.     return(-2);
  11904. #endif /* VMS */
  11905. #endif /* CKPURGE */
  11906.     }
  11907.  
  11908. #ifndef NOSPL
  11909.     if (cx == XXFAST) {
  11910.     if ((x = cmcfm()) < 0) return(x);
  11911.     x = mlook(mactab,"fast",nmac);
  11912.     return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
  11913.     }
  11914.     if (cx == XXCAU) {
  11915.     if ((x = cmcfm()) < 0) return(x);
  11916.     x = mlook(mactab,"cautious",nmac);
  11917.     return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
  11918.     }
  11919.     if (cx == XXROB) {
  11920.     if ((x = cmcfm()) < 0) return(x);
  11921.     x = mlook(mactab,"robust",nmac);
  11922.     return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
  11923.     }
  11924. #endif /* NOSPL */
  11925.  
  11926.     if (cx == XXSCRN) {            /* SCREEN */
  11927.     int row, col;
  11928.     if ((x = cmkey(scntab, nscntab,"screen action","", xxstring)) < 0)
  11929.       return(x);
  11930.     switch (x) {            /* MOVE-TO (cursor position) */
  11931.       case SCN_MOV:
  11932.         if ((y = cmnum("Row (1-based)","",10,&z,xxstring)) < 0)
  11933.           return(y);
  11934.         row = z;
  11935.         y = cmnum("Column (1-based)","1",10,&z,xxstring);
  11936.         if (y < 0)
  11937.           return(y);
  11938.         col = z;
  11939.         if ((y = cmcfm()) < 0)
  11940.           return(y);
  11941.         if (row < 0 || col < 0) {
  11942.         printf("?Row and Column must be 1 or greater\n");
  11943.         return(-9);
  11944.         }
  11945.         if (cmd_rows > 0 && row > cmd_rows)
  11946.           row = cmd_rows;
  11947.         if (cmd_cols > 0 && col > cmd_cols)
  11948.           col = cmd_cols;
  11949.         y = ck_curpos(row,col);
  11950.         return(success = (y > -1) ? 1 : 0);
  11951.  
  11952.       case SCN_CLR:            /* CLEAR */
  11953.         if ((y = cmcfm()) < 0)
  11954.           return(y);
  11955.         debug(F100,"screen calling ck_cls()","",0);
  11956.         y = ck_cls();
  11957.         return(success = (y > -1) ? 1 : 0);
  11958.  
  11959.       case SCN_CLE:            /* CLEOL */
  11960.         if ((y = cmcfm()) < 0)
  11961.           return(y);
  11962.         y = ck_cleol();
  11963.         return(success = (y > -1) ? 1 : 0);
  11964.     }
  11965.     }
  11966.  
  11967. #ifndef NOHTTP
  11968. #ifdef TCPSOCKET
  11969.     if (cx == XXHTTP)
  11970.       return(dohttp());
  11971. #endif /* TCPSOCKET */
  11972. #endif /* NOHTTP */
  11973.  
  11974. #ifndef NOSPL
  11975.     if (cx == XXARRAY) {        /* ARRAY */
  11976. #ifndef NOSHOW
  11977.     extern int showarray();
  11978. #endif /* NOSHOW */
  11979.     if ((x = cmkey(arraytab, narraytab,"Array operation","",xxstring)) < 0)
  11980.       return(x);
  11981.     switch (x) {
  11982.       case ARR_DCL:
  11983.         return(dodcl(XXDCL));
  11984.       case ARR_SRT:
  11985.         return(dosort());
  11986. #ifndef NOSHOW
  11987.       case ARR_SHO:
  11988.         return(showarray());
  11989. #endif /* NOSHOW */
  11990.       case ARR_CPY:
  11991.         return(copyarray());
  11992.       case ARR_SET:
  11993.       case ARR_CLR:
  11994.         return(clrarray(x));
  11995.       case ARR_DST:
  11996.         return(unarray());
  11997.       case ARR_RSZ:
  11998.         return(rszarray());
  11999.       case ARR_EQU:
  12000.         return(linkarray());
  12001.  
  12002.       default:
  12003.         printf("?Sorry, not implemented yet - \"%s\"\n",cmdbuf);
  12004.         return(-9);
  12005.     }
  12006.     }
  12007.     if (cx == XXTRACE)
  12008.       return(dotrace());
  12009. #endif /* NOSPL */
  12010.  
  12011. #ifdef CK_PERMS
  12012. #ifdef UNIX
  12013.     if (cx == XXCHMOD)
  12014.       return(douchmod());        /* Do Unix chmod */
  12015. #endif /* UNIX */
  12016. #endif /* CK_PERMS */
  12017.  
  12018.     if (cx == XXPROMP)
  12019.       return(doprompt());
  12020.  
  12021.     if (cx == XXGREP)
  12022.       return(dogrep());
  12023.  
  12024.     if (cx == XXDEBUG) {        /* DEBUG */
  12025. #ifndef DEBUG
  12026.     int dummy = 0;
  12027.     return(seton(&dummy));
  12028. #else
  12029.     return(seton(&deblog));
  12030. #endif /* DEBUG */
  12031.     }
  12032.  
  12033. #ifdef CKLEARN
  12034.     if (cx == XXLEARN) {        /* LEARN */
  12035.     struct FDB of, sw, cm;
  12036.     int closing = 0, off = 0, on = 0, confirmed = 0;
  12037.     char c;
  12038.  
  12039.     cmfdbi(&sw,            /* 2nd FDB - optional /PAGE switch */
  12040.            _CMKEY,            /* fcode */
  12041.            "Script file name, or switch", /* hlpmsg */
  12042.            "",            /* default */
  12043.            "",            /* addtl string data */
  12044.            3,            /* addtl numeric data 1: tbl size */
  12045.            4,            /* addtl numeric data 2: 4 = cmswi */
  12046.            xxstring,        /* Processing function */
  12047.            learnswi,        /* Keyword table */
  12048.            &of            /* Pointer to next FDB */
  12049.            );
  12050.     cmfdbi(&of,_CMOFI,"","","",0,0,xxstring,NULL,&cm);
  12051.     cmfdbi(&cm,_CMCFM,"","","",0,0,NULL,NULL,NULL);
  12052.     line[0] = NUL;
  12053.  
  12054.     while (!confirmed) {
  12055.         x = cmfdb(&sw);        /* Parse something */
  12056.         if (x < 0)
  12057.           return(x);
  12058.         switch (cmresult.fcode) {    /* What was it? */
  12059.           case _CMOFI:        /* Output file name */
  12060.         ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  12061.         break;
  12062.           case _CMKEY:        /* Switch */
  12063.         c = cmgbrk();
  12064.         if ((c == ':' || c == '=') && !(cmgkwflgs() & CM_ARG)) {
  12065.             printf("?This switch does not take an argument\n");
  12066.             return(-9);
  12067.         }
  12068.         switch (cmresult.nresult) {
  12069.           case 2:        /* /CLOSE */
  12070.             closing = 1;    /* Fall thru on purpose */
  12071.           case 0:        /* /OFF */
  12072.             off = 1;
  12073.             on = 0;
  12074.             break;
  12075.           case 1:        /* /ON */
  12076.             on = 1;
  12077.             off = 0;
  12078.             break;
  12079.         }
  12080.         break;
  12081.           case _CMCFM:        /* Confirmation */
  12082.         confirmed++;
  12083.         break;
  12084.         }
  12085.     }
  12086.     if (closing) {
  12087.         if (learnfp) {
  12088.         fclose(learnfp);
  12089.         learnfp = NULL;
  12090.         }
  12091.         makestr(&learnfile,NULL);
  12092.     }
  12093.     if (line[0]) {
  12094.         if (!on && !off)
  12095.           on = 1;
  12096.         if (learnfp) {
  12097.         fclose(learnfp);
  12098.         learnfp = NULL;
  12099.         }
  12100.         makestr(&learnfile,line);
  12101.         if (learnfile) {
  12102.         char * modes = "w";
  12103.         learnfp = fopen(learnfile,modes);
  12104.         if (!learnfp) {
  12105.             debug(F110,"LEARN file open error",learnfile,0);
  12106.             perror(learnfile);
  12107.             return(-9);
  12108.         } else {
  12109. #ifdef ZFNQFP
  12110.             if (zfnqfp(learnfile,TMPBUFSIZ,tmpbuf))
  12111.               makestr(&learnfile,tmpbuf);
  12112. #endif /* ZFNQFP */
  12113.             debug(F110,"LEARN file open ok",learnfile,0);
  12114.             if (!quiet) {
  12115.             printf("Recording to %s...\n\n",learnfile);
  12116.             printf(
  12117. " WARNING: If you type your password during script recording, it will appear\n\
  12118.  in the file.  Be sure to edit it or take other appropriate precautions.\n\n"
  12119.                    );
  12120.             }
  12121.             fputs(  "; Scriptfile: ",learnfp);
  12122.             fputs(learnfile,learnfp);
  12123.             fputs("\n; Directory:  ",learnfp);
  12124.             fputs(zgtdir(),learnfp);
  12125.             fputs("\n; Recorded:   ",learnfp);
  12126.             fputs(ckdate(),learnfp);
  12127.             fputs("\n",learnfp);
  12128.         }
  12129.         }
  12130.     }
  12131.     if (on) {
  12132.         learning = 1;
  12133.     } else if (off) {
  12134.         learning = 0;
  12135.     }
  12136.     debug(F101,"LEARN learning","",learning);
  12137.     return(success = 1);
  12138.     }
  12139. #endif /* CKLEARN */
  12140.  
  12141. #ifdef NEWFTP
  12142.     if (cx == XXUSER || cx == XXACCT) {
  12143.     if (!ftpisopen()) {
  12144.         printf("?FTP connection is not open\n");
  12145.         return(-9);
  12146.     }
  12147.     return(success = (cx == XXUSER) ? doftpusr() : doftpacct());
  12148.     }
  12149.     if (cx == XXSITE || cx == XXPASV) {
  12150.     if (!ftpisopen()) {
  12151.         printf("?FTP connection is not open\n");
  12152.         return(-9);
  12153.     }
  12154.     return(success = (cx == XXSITE) ? doftpsite() : dosetftppsv());
  12155.     }
  12156. #endif /* NEWFTP */
  12157.  
  12158.     if (cx == XXORIE) {            /* ORIENTATION */
  12159.     extern char * myname;
  12160.     int i, y, n = 0;
  12161.         char * s, *p, vbuf[32];
  12162.     char * vars[16];       char * legend[16];
  12163.  
  12164.     if ((y = cmcfm()) < 0)
  12165.       return(y);
  12166.  
  12167.     printf("\nProgram name:\n  %s\n\n",myname);
  12168.     n += 4;
  12169.  
  12170. #ifdef NT
  12171.     vars[0] = "home";      legend[0] = "Your home directory";
  12172.     vars[1] = "directory"; legend[1] = "K95's current directory";
  12173.     vars[2] = "exedir";    legend[2] = "K95 Program directory";
  12174.     vars[3] = "inidir";    legend[3] = "K95 Initialization file directory";
  12175.     vars[4] = "startup";   legend[4] = "Current directory when started";
  12176.     
  12177.         vars[5] = "common";
  12178.         legend[5] = "K95 data for all users and K95SITE.INI file";
  12179.     
  12180.         vars[6] = "personal";  legend[6] = "Your personal data directory tree";
  12181.         vars[7] = "desktop";   legend[7] = "Your deskop directory tree";
  12182.     
  12183.         vars[8] = "appdata";
  12184.         legend[8] = "Your personal K95 data tree and K95CUSTOM.INI file";
  12185.     
  12186.         vars[9] = "download";  legend[9] = "Your K95 download directory";
  12187.         vars[10] = "tmpdir";   legend[10] = "Your TEMP directory";
  12188.     vars[11] = NULL;       legend[11] = NULL;
  12189.  
  12190.     for (i = 0; i < 16 && vars[i]; i++) {
  12191.         printf("%s:\n",legend[i]);
  12192.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12193.         ckmakmsg(vbuf,32,"\\v(",vars[i],")",NULL);
  12194.         printf("  Variable:   %s\n",vbuf);
  12195.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12196.         y = TMPBUFSIZ;
  12197.         s = tmpbuf;
  12198.         zzstring(vbuf,&s,&y);
  12199.         line[0] = NUL;
  12200.         ckGetLongPathName(tmpbuf,line,LINBUFSIZ);
  12201.         printf("  Long name:  %s\n",line);
  12202.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12203.         line[0] = NUL;
  12204.         GetShortPathName(tmpbuf,line,LINBUFSIZ);
  12205.         printf("  Short name: %s\n",line);
  12206.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12207.             printf("\n");
  12208.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12209.     }
  12210. #else  /* NT */
  12211.  
  12212.     vars[0] = "home";      legend[0] = "Your home directory";
  12213.     vars[1] = "directory"; legend[1] = "Kermit's current directory";
  12214.     vars[2] = "exedir";    legend[2] = "Kermit's program directory";
  12215.     vars[3] = "inidir";    legend[3] = "Initialization file directory";
  12216.     vars[4] = "startup";   legend[4] = "Current directory when started";
  12217.     vars[5] = "download";  legend[5] = "Kermit download directory";
  12218.     vars[6] = NULL;           legend[6] = NULL;
  12219.  
  12220.     for (i = 0; i < 16 && vars[i]; i++) {
  12221.         printf("%s:\n",legend[i]);
  12222.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12223.         ckmakmsg(vbuf,32,"\\v(",vars[i],")",NULL);
  12224.         printf("  Variable: %s\n",vbuf);
  12225.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12226.         y = TMPBUFSIZ;
  12227.         s = tmpbuf;
  12228.         zzstring(vbuf,&s,&y);
  12229.             printf("  Value:    %s\n",tmpbuf);
  12230.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12231.             printf("\n");
  12232.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12233.     }
  12234. #endif /* NT */
  12235.     return(success = 1);
  12236.     }
  12237.  
  12238. #ifdef NT
  12239.     if (cx == XXDIALER) {
  12240.         StartDialer();
  12241.         return(success = 1);
  12242.     }
  12243. #endif /* NT */
  12244.  
  12245.     if (cx == XXCONT) {            /* CONTINUE */
  12246.     if ((x = cmcfm()) < 0)
  12247.       return(x);
  12248.     if (!xcmdsrc) {            /* At prompt: continue script */
  12249.         if (cmdlvl > 0)
  12250.           popclvl();        /* Pop command level */
  12251.         return(success = 1);    /* always succeeds */
  12252. #ifndef NOSPL
  12253.     } else {            /* In script: whatever... */
  12254.         x = mlook(mactab,"continue",nmac);
  12255.         return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
  12256. #endif /* NOSPL */
  12257.     }
  12258.     }
  12259.  
  12260.     if (cx == XXNOTAV) {        /* Command in table not available */
  12261.     ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ);
  12262.     if ((x = cmtxt("Rest of command","",&s,NULL)) < 0)
  12263.       return(x);
  12264.     printf("Sorry, \"%s\" not configured in this version of Kermit.\n",
  12265.            tmpbuf
  12266.            );
  12267.     return(success = 0);
  12268.     }
  12269.     return(-2);                /* None of the above */
  12270.  
  12271. } /* end of docmd() */
  12272.  
  12273. #endif /* NOICP */
  12274.