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

  1. #ifdef SSHTEST
  2. #define SSHBUILTIN
  3. #endif /* SSHTEST */
  4.  
  5. #include "ckcsym.h"
  6. char *userv = "User Interface 8.0.268, 17 Mar 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;            /* RCD active */
  99. int keepallchars = 0;            /* See cmfld() */
  100.  
  101. int locus = 1;                /* Current LOCUS is LOCAL */
  102. #ifdef OS2
  103. int autolocus = 2;            /* Automatic LOCUS switching: ASK */
  104. #else /* OS2 */
  105. int autolocus = 1;            /* Automatic LOCUS switching enabled */
  106. #endif /* OS2 */
  107.  
  108. #ifndef NOICP
  109. #ifdef CKLEARN
  110. #ifdef VMS
  111. #include <time.h>            /* For CKLEARN */
  112. #endif /* VMS */
  113. #endif /* CKLEARN */
  114. #ifdef OS2
  115. #ifndef NT
  116. #define INCL_NOPM
  117. #define INCL_VIO            /* Needed for ckocon.h */
  118. #include <os2.h>
  119. #undef COMMENT
  120. #else
  121. #define APIRET ULONG
  122. #include <windows.h>
  123. #include <tapi.h>
  124. #include "cknwin.h"
  125. #include "ckntap.h"            /* CK_TAPI definition */
  126. #endif /* NT */
  127. #include "ckowin.h"
  128. #include "ckocon.h"
  129. extern int tcp_avail;
  130. extern bool viewonly;
  131. extern int k95stdout;
  132. extern int tt_scroll;
  133. #ifndef NOTERM
  134. extern tt_status[VNUM];
  135. #endif /* NOTERM */
  136. int display_demo = 1;
  137. #include "ckossh.h"
  138. #ifdef KUI
  139. #include "ikui.h"
  140. #endif /* KUI */
  141. #endif /* OS2 */
  142.  
  143. int optlines = 0;
  144. int didsetlin = 0;
  145.  
  146. #ifdef NEWFTP
  147. extern int ftpget, ftpisopen(), ftpbye(), doftpres();
  148. _PROTOTYP(int doftptyp,(int));
  149. #endif /* NEWFTP */
  150.  
  151. #ifdef VMS
  152. extern int batch;
  153. #endif /* VMS */
  154.  
  155. #ifdef datageneral
  156. #include <packets:common.h>
  157. #define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd)
  158. #endif /* datageneral */
  159.  
  160. extern int xcmdsrc, hints, cmflgs, whyclosed;
  161.  
  162. char * hlptok = NULL;
  163.  
  164. #ifdef CK_TTGWSIZ            /* Whether to use more-prompting */
  165. int xaskmore = 1;            /* Momentary setting */
  166. int saveask  = 1;            /* Permanent setting */
  167. #else
  168. int xaskmore = 0;
  169. int saveask  = 0;
  170. #endif /* CK_TTGWSIZ */
  171.  
  172. #ifndef NOCSETS
  173. extern int nfilc;
  174. extern struct keytab fcstab[];
  175. extern int fcharset;
  176. #endif /* NOCSETS */
  177.  
  178. char * g_pswd = NULL;
  179. int g_pcpt = -1;
  180. int g_pflg = -1;
  181.  
  182. extern int cmd_rows, cmd_cols;
  183.  
  184. #ifdef CKROOT
  185. extern int ckrooterr;
  186. #endif /* CKROOT */
  187.  
  188. extern int inserver, filepeek;
  189.  
  190. #ifdef CKLEARN
  191. FILE * learnfp = NULL;
  192. char * learnfile = NULL;
  193. int learning = 0;
  194. #endif /* CKLEARN */
  195.  
  196. #ifndef NOXFER
  197. extern int atcapr, atdiso, nfils, moving, protocol, sendmode, epktflg, size,
  198.   sndsrc, server, displa, fncnv, fnspath, fnrpath, xfermode, urpsiz,
  199.   spsizf, spsiz, spsizr, spmax, wslotr, prefixing, fncact, reliable,
  200.   setreliable;
  201.  
  202. #ifdef IKSDCONF
  203. extern int iksdcf;
  204. #endif /* IKSDCONF */
  205.  
  206. #ifdef CK_LOGIN
  207. extern int isguest;
  208. #endif /* CK_LOGIN */
  209.  
  210. extern long sendstart;
  211.  
  212. extern char *cmarg, *cmarg2, **cmlist, *dftty;
  213.  
  214. extern struct keytab fntab[]; extern int nfntab;
  215. extern struct ck_p ptab[NPROTOS];
  216.  
  217. int sndcmd = 0;        /* Last command was a SEND-class command. */
  218.  
  219. int g_xfermode = -1;
  220. int g_proto  = -1;
  221. int g_urpsiz = -1;
  222. int g_spsizf = -1;
  223. int g_spsiz  = -1;
  224. int g_spsizr = -1;
  225. int g_spmax  = -1;
  226. int g_wslotr = -1;
  227. int g_prefixing = -1;
  228. int g_fncnv  = -1;
  229. int g_fnspath = -1;
  230. int g_fnrpath = -1;
  231. int g_fnact  = -1;
  232. int g_displa = -1;
  233. int g_spath  = -1;
  234. int g_rpath  = -1;
  235. char * g_sfilter = NULL;
  236. char * g_rfilter = NULL;
  237.  
  238. extern int patterns;
  239. #ifdef PATTERNS
  240. extern char *txtpatterns[], *binpatterns[];
  241. int g_patterns = -1;
  242. #endif /* PATTERNS */
  243. int g_skipbup = -1;
  244.  
  245. #ifdef PIPESEND
  246. extern int usepipes, pipesend;
  247. extern char * sndfilter;
  248. #endif /* PIPESEND */
  249.  
  250. #ifndef NOSPL
  251. extern int sndxlo, sndxhi, sndxin;
  252. #endif /* NOSPL */
  253.  
  254. extern char fspec[];            /* Most recent filespec */
  255. extern int fspeclen;            /* Length of fspec[] buffer */
  256.  
  257. #ifndef NOFRILLS
  258. extern int rmailf;            /* MAIL command items */
  259. extern char optbuf[];
  260. #endif /* NOFRILLS */
  261.  
  262. extern int
  263.   en_cpy, en_cwd, en_del, en_dir, en_fin, en_get, en_bye, en_mai, en_pri,
  264.   en_hos, en_ren, en_sen, en_spa, en_set, en_typ, en_who, en_ret, en_xit,
  265.   en_mkd, en_rmd, en_asg;
  266.  
  267. #ifndef NOMSEND                /* Multiple SEND */
  268. extern char *msfiles[];
  269. int filesinlist = 0;            /* And ADD ... */
  270. extern struct filelist * filehead;
  271. extern struct filelist * filetail;
  272. extern struct filelist * filenext;
  273. extern int addlist;
  274. #endif /* NOMSEND */
  275.  
  276. static struct keytab addtab[] = {
  277. #ifdef PATTERNS
  278.     { "binary-patterns", ADD_BIN, 0 },
  279. #endif /* PATTERNS */
  280. #ifndef NOMSEND
  281.     { "send-list", ADD_SND, 0 },
  282. #endif /* NOMSEND */
  283. #ifdef PATTERNS
  284.     { "text-patterns", ADD_TXT, 0 },
  285. #endif /* PATTERNS */
  286.     { "", 0, 0 }
  287. };
  288. static int naddtab = sizeof(addtab)/sizeof(struct keytab) - 1;
  289.  
  290. #ifndef NOCSETS
  291. struct keytab assoctab[] = {
  292.     { "file-character-set",     ASSOC_FC, 0 },
  293.     { "transfer-character-set", ASSOC_TC, 0 },
  294.     { "xfer-character-set",     ASSOC_TC, CM_INV }
  295. };
  296. static int nassoc = sizeof(assoctab)/sizeof(struct keytab);
  297. extern int afcset[MAXFCSETS+1];        /* Character-set associations */
  298. extern int axcset[MAXTCSETS+1];
  299. #endif /* NOCSETS */
  300.  
  301. #ifndef ADDCMD
  302. #ifndef NOMSEND
  303. #define ADDCMD
  304. #endif /* NOMSEND */
  305. #ifndef ADDCMD
  306. #ifdef PATTERNS
  307. #define ADDCMD
  308. #endif /* PATTERNS */
  309. #endif /* ADDCMD */
  310. #endif /* ADDCMD */
  311. #endif /* NOXFER */
  312.  
  313. /* External Kermit Variables, see ckmain.c for description. */
  314.  
  315. extern xx_strp xxstring;
  316. extern long xvernum;
  317.  
  318. extern int local, xitsta, binary, msgflg, escape, duplex, quiet, tlevel,
  319.   pflag, zincnt, ckxech, carrier, what, nopush, haveline, bye_active;
  320. #ifdef TNCODE
  321. extern int debses;
  322. extern char tn_msg[];
  323. #endif /* TNCODE */
  324.  
  325. int sleepcan = 1;
  326. int g_binary = -1;
  327. int g_recursive = -1;
  328. int g_matchdot = -1;
  329. extern int nolinks;
  330.  
  331. extern long vernum;
  332. extern char *versio, *copyright[];
  333. extern char *ckxsys;
  334. #ifndef NOHELP
  335. extern char *introtxt[];
  336. extern char *newstxt[];
  337. #endif /* NOHELP */
  338.  
  339. #ifndef OS2
  340. #ifndef UNIX
  341. extern char *PWDCMD;
  342. #endif /* UNIX */
  343. extern char *WHOCMD;
  344. #endif /* OS2 */
  345.  
  346. extern char ttname[];
  347.  
  348. extern CHAR sstate;
  349.  
  350. extern int network;            /* Have active network connection */
  351. extern int nettype;            /* Type of network */
  352. extern int ttnproto;                    /* NET_TCPB protocol */
  353.  
  354. #ifndef NODIAL
  355. extern int dialsta, dialatmo, dialcon, dialcq; /* DIAL status, etc. */
  356. #endif /* NODIAL */
  357.  
  358. #ifdef CK_APC
  359. extern int apcactive, apcstatus;
  360. #endif /* CK_APC */
  361.  
  362. #ifndef NOPUSH
  363. #ifndef NOFRILLS
  364. extern char editor[];
  365. extern char editopts[];
  366. extern char editfile[];
  367. #endif /* NOFRILLS */
  368. #endif /* NOPUSH */
  369.  
  370. #ifdef BROWSER
  371. extern char browser[];            /* Web browser application */
  372. extern char browsopts[];        /* Web browser options */
  373. extern char browsurl[];            /* Most recent URL */
  374. #endif /* BROWSER */
  375. #ifndef NOFTP
  376. char ftpapp[CKMAXPATH+1] = { NUL, NUL }; /* ftp executable */
  377. char ftpopts[128] = { NUL, NUL };    /* ftp command-line options */
  378. #endif /* NOFTP */
  379. extern struct keytab onoff[];        /* On/Off keyword table */
  380.  
  381. #ifdef CK_TMPDIR
  382. int f_tmpdir = 0;            /* Directory changed temporarily */
  383. char savdir[TMPDIRLEN];            /* For saving current directory */
  384. #endif /* CK_TMPDIR */
  385.  
  386. int activecmd = -1;            /* Keyword index of active command */
  387. int doconx = -1;            /* CONNECT-class command active */
  388. int ooflag = 0;                /* User-settable on/off flag */
  389.  
  390. int rcflag = 0;                /* Pointer to home directory string */
  391. int repars,                /* Reparse needed */
  392.     techo = 0;                /* Take echo */
  393. int secho = 1;                /* SCRIPT echo */
  394.  
  395. int xitwarn =            /* Warn about open connection on exit */
  396. #ifdef NOWARN
  397. 0
  398. #else
  399. 1
  400. #endif /* NOWARN */
  401. ;
  402.  
  403. struct keytab onoffsw[] = {
  404.     { "/off", 0, 0 },
  405.     { "/on",  1, 0 }
  406. };
  407.  
  408. #ifdef CKEXEC
  409. struct keytab redirsw[] = {
  410.     { "/redirect", 1, 0 }
  411. };
  412. #endif /* CKEXEC */
  413.  
  414. #ifndef NOXMIT
  415. /* Variables for TRANSMIT command */
  416.  
  417. int xmitx = 1;            /* Whether to echo during TRANSMIT */
  418. int xmitf = 0;            /* Character to fill empty lines */
  419. int xmitl = 0;            /* 0 = Don't send linefeed too */
  420. int xmitp = LF;            /* Host line prompt */
  421. int xmits = 0;            /* Use shift-in/shift-out, 0 = no */
  422. int xmitw = 0;            /* Milliseconds to pause during TRANSMIT */
  423. int xmitt = 1;            /* Seconds to wait for each char to echo */
  424. int xmita = 1;            /* Action upon timeout */
  425.  
  426. #define XMI_BIN 1
  427. #define XMI_TXT 2
  428. #define XMI_CMD 3
  429. #define XMI_TRA 4
  430. #define XMI_VRB 5
  431. #define XMI_QUI 6
  432. #define XMI_NOW 7
  433. #define XMI_NOE 8
  434.  
  435. static struct keytab xmitsw[] = {    /* TRANSMIT command options */
  436.     { "/binary",          XMI_BIN, 0 },
  437. #ifdef PIPESEND
  438.     { "/command",         XMI_CMD, CM_INV|CM_PSH },
  439. #endif /* PIPESEND */
  440.     { "/noecho",          XMI_NOE, 0 },
  441.     { "/nowait",          XMI_NOW, 0 },
  442. #ifdef PIPESEND
  443.     { "/pipe",            XMI_CMD, 0 },
  444. #endif /* PIPESEND */
  445. #ifdef COMMENT
  446.     { "/quiet",           XMI_QUI, 0 },
  447. #endif /* COMMENT */
  448.     { "/text",            XMI_TXT, 0 },
  449.     { "/transparent",     XMI_TRA, 0 },
  450. #ifdef COMMENT
  451.     { "/verbose",         XMI_VRB, 0 },
  452. #endif /* COMMENT */
  453.     { "", 0, 0 }
  454. };
  455. #define NXMITSW sizeof(xmitsw)/sizeof(struct keytab) - 1
  456. static int nxmitsw = NXMITSW;
  457.  
  458. #endif /* NOXMIT */
  459.  
  460. /* Declarations from ck?fio.c module */
  461.  
  462. extern char *SPACMD, *SPACM2;        /* SPACE commands */
  463.  
  464. /* Command-oriented items */
  465.  
  466. #ifdef DCMDBUF
  467. extern char *cmdbuf;            /* Command buffers */
  468. extern char *atmbuf;
  469. extern char *line;            /* Character buffer for anything */
  470. extern char *tmpbuf;            /* Short temporary string buffer */
  471. extern int *ifcmd;
  472. extern int *intime;
  473. extern int *inpcas;
  474. #else
  475. extern char cmdbuf[];            /* Command buffers */
  476. extern char atmbuf[];
  477. extern char line[];            /* Character buffer for anything */
  478. extern char tmpbuf[];            /* Temporary buffer */
  479. extern int ifcmd[];
  480. extern int intime[];
  481. extern int inpcas[];
  482. #endif /* DCMDBUF */
  483.  
  484. #ifndef NOSPL
  485. extern char * prstring[];
  486. #endif /* NOSPL */
  487.  
  488. char *lp;                /* Pointer to line buffer */
  489.  
  490. #ifndef NOSPL
  491. int unkmacro = 0;            /* Flag for in ON_UNKNOWN_COMMAND */
  492. int oldeval = 0;
  493. char evalbuf[33];            /* EVALUATE result */
  494. extern char * inpbuf;            /* Buffer for INPUT and REINPUT */
  495. char *inpbp;                /* And pointer to same */
  496. extern char lblbuf[];            /* Buffer for labels */
  497. int m_found;                /* MINPUT result */
  498. int i_active = 0;            /* INPUT command is active */
  499. char *ms[MINPMAX];            /* Pointers to MINPUT strings */
  500. static int mp[MINPMAX];            /* and flags */
  501. extern int fndiags, fnerror, fnsuccess;    /* Function diagnostics */
  502. #ifndef NOSEXP
  503. char * lastsexp = NULL;            /* S-Expressions */
  504. char * sexpval = NULL;
  505. int sexpecho = SET_AUTO;
  506. #endif /* NOSEXP */
  507. #endif /* NOSPL */
  508.  
  509. char psave[PROMPTL] = { NUL };        /* For saving & restoring prompt */
  510.  
  511. extern int success;            /* Command success/failure flag */
  512. extern int cmdlvl;            /* Current position in command stack */
  513.  
  514. #ifndef NOSPL
  515. int                    /* SET INPUT parameters. */
  516. /* Note, INPUT TIMEOUT, intime[], is on the command-level stack. */
  517.   inbufsize = 0,            /* INPUT buffer size */
  518.   indef = 1,                /* default timeout, seconds */
  519.   inecho = 1,                /* 1 = echo on */
  520.   inautodl = 0,                /* INPUT autodownload */
  521.   inintr = 1,                /* INPUT interrupion allowed */
  522.   insilence = 0;            /* 0 = no silence constraint */
  523. #ifdef OS2
  524. int interm = 1;                /* Terminal emulator displays input */
  525. #endif /* OS2 */
  526. int maclvl = -1;            /* Macro nesting level */
  527. int mecho = 0;                /* Macro echo, 0 = don't */
  528. char varnam[6];                /* For variable names */
  529. extern int macargc[];            /* ARGC from macro invocation */
  530.  
  531. extern char *m_arg[MACLEVEL][NARGS];    /* Stack of macro arguments */
  532. extern char *mrval[];
  533.  
  534. extern char **a_ptr[];            /* Array pointers */
  535. extern int a_dim[];            /* Array dimensions */
  536. extern int a_link[];
  537.  
  538. #ifdef DCMDBUF
  539. extern struct cmdptr *cmdstk;        /* The command stack itself */
  540. #else
  541. extern struct cmdptr cmdstk[];        /* The command stack itself */
  542. #endif /* DCMDBUF */
  543.  
  544. long ck_alarm = 0;            /* SET ALARM value */
  545. char alrm_date[24] = { ' ',' ',' ',' ',' ',' ',' ',' ',' ' };
  546. char alrm_time[24] = { ' ',' ',' ',' ',' ',' ',' ' };
  547.  
  548. #endif /* NOSPL */
  549.  
  550. static int x, y, z = 0;            /* Local workers */
  551. static char *s;
  552.  
  553. #ifdef CK_MINPUT
  554. static char c1chars[] = {        /* C1 control chars escept NUL */
  555.     001,002,003,004,005,006,007,010,011,012,013,014,015,016,017,020,
  556.     021,022,023,024,025,026,027,030,031,032,033,034,035,036,037
  557. };
  558. #endif /* CK_MINPUT */
  559.  
  560. #define xsystem(s) zsyscmd(s)
  561.  
  562. /* Top-Level Interactive Command Keyword Table */
  563. /* Keywords must be in lowercase and in alphabetical order. */
  564.  
  565. struct keytab cmdtab[] = {
  566. #ifndef NOPUSH
  567.     { "!",       XXSHE, CM_INV|CM_PSH }, /* Shell escape */
  568. #else
  569.     { "!",       XXNOTAV, CM_INV|CM_PSH },
  570. #endif /* NOPUSH */
  571.     { "#",           XXCOM, CM_INV },    /* Comment */
  572. #ifndef NOSPL
  573.     { "(",           XXSEXP,CM_INV },    /* S-Expression */
  574.     { ".",           XXDEF, CM_INV },    /* Assignment */
  575.     { ":",           XXLBL, CM_INV },    /* Label */
  576. #endif /* NOSPL */
  577. #ifdef CK_REDIR
  578. #ifndef NOPUSH
  579.     { "<",           XXFUN, CM_INV|CM_PSH }, /* REDIRECT */
  580. #else
  581.     { "<",           XXNOTAV, CM_INV|CM_PSH }, /* REDIRECT */
  582. #endif /* NOPUSH */
  583. #endif /* CK_REDIR */
  584. #ifndef NOPUSH
  585.     { "@",           XXSHE, CM_INV|CM_PSH }, /* DCL escape */
  586. #else
  587.     { "@",           XXNOTAV, CM_INV|CM_PSH }, /* DCL escape */
  588. #endif /* NOPUSH */
  589.  
  590. #ifdef CK_RECALL
  591.     { "^",           XXREDO,CM_INV|CM_NOR }, /* Synonym for REDO */
  592. #endif /* CK_RECALL */
  593. #ifndef NOSPL
  594.     { "_asg",        XXASX,   CM_INV },    /* Used internally by FOR, etc */
  595.     { "_assign",     XXASX,   CM_INV },    /* Used internally by FOR, etc */
  596.     { "_decrement",  XX_DECR, CM_INV },
  597.     { "_define",     XXDFX,   CM_INV },    /* Used internally by FOR, etc */
  598.     { "_evaluate",   XX_EVAL, CM_INV },
  599.     { "_forward",    XXXFWD,  CM_INV },    /* Used internally by SWITCH   */
  600.     { "_getargs",    XXGTA,   CM_INV },    /* Used internally by FOR, etc */
  601.     { "_increment",  XX_INCR, CM_INV },
  602.     { "_putargs",    XXPTA,   CM_INV },    /* Used internally by FOR, etc */
  603.     { "_undefine",   XXUNDFX, CM_INV },
  604. #endif /* NOSPL */
  605.  
  606.     { "about",       XXVER,   CM_INV },    /* Synonym for VERSION */
  607. #ifndef NOSPL
  608. #ifdef NEWFTP
  609.     { "account",     XXACCT,  CM_INV }, /* (FTP) Account */
  610. #endif /* NEWFTP */
  611. #ifdef ADDCMD
  612.     { "add",         XXADD, 0 },    /* ADD */
  613. #endif /* ADDCMD */
  614. #ifndef NODIAL
  615.     { "answer",      XXANSW, CM_LOC },    /* ANSWER the phone */
  616. #else
  617.     { "answer",      XXNOTAV, CM_INV|CM_LOC }, /* ANSWER the phone */
  618. #endif /* NODIAL */
  619.     { "apc",         XXAPC, 0 },    /* Application Program Command */
  620. #ifndef NOSPL
  621.     { "array",       XXARRAY, 0 },    /* Array operations */
  622. #endif /* NOSPL */
  623.     { "ascii",       XXASC, CM_INV },    /* == SET FILE TYPE TEXT */
  624.     { "asg",         XXASS, CM_INV },    /* Invisible synonym for ASSIGN */
  625.     { "ask",         XXASK, 0 },    /* ASK for text, assign to variable */
  626.     { "askq",        XXASKQ,0 },    /* ASK quietly (no echo) */
  627. #ifndef NOSPL
  628.     { "ass",         XXASS, CM_INV|CM_ABR }, /* ASSIGN */
  629.     { "assert",      XXASSER, CM_INV },    /* ASSERT */
  630.     { "assign",      XXASS, 0 },    /* ASSIGN */
  631. #endif /* NOSPL */
  632. #ifndef NOXFER
  633. #ifndef NOCSETS
  634.     { "associate",   XXASSOC, 0 },    /* ASSOCIATE */
  635. #else
  636.     { "associate",   XXNOTAV, CM_INV },    /* ASSOCIATE */
  637. #endif /* NOCSETS */
  638. #endif /* NOXFER */
  639. #ifdef CK_KERBEROS
  640. #ifdef CK_AUTHENTICATION
  641.     { "authenticate",XXAUTH, 0 },    /* Authentication */
  642. #else
  643.     { "authenticate",XXAUTH, CM_INV },
  644. #endif /* CK_AUTHENTICATION */
  645. #endif /* CK_KERBEROS */
  646. #endif /* NOSPL */
  647. #ifndef NOFRILLS
  648.     { "back",        XXBACK, 0 },    /* BACK to previous directory */
  649. #else
  650.     { "back",        XXNOTAV,CM_INV },
  651. #endif /* NOFRILLS */
  652.     { "beep",        XXBEEP,CM_INV },    /* BEEP */
  653. #ifndef NOXFER
  654.     { "binary",      XXBIN, CM_INV },    /* == SET FILE TYPE BINARY */
  655. #endif /* NOXFER */
  656. #ifndef NOFRILLS
  657.     { "bug",         XXBUG, CM_INV },    /* BUG report instructions */
  658. #else
  659.     { "bug",         XXNOTAV, CM_INV },
  660. #endif /* NOFRILLS */
  661. #ifdef BROWSER
  662.     { "browse",      XXBROWS, CM_PSH|CM_LOC }, /* BROWSE (start browser) */
  663. #else
  664.     { "browse",      XXNOTAV, CM_INV|CM_PSH|CM_LOC },
  665. #endif /* BROWSER */
  666. #ifndef NOXFER
  667.     { "bye",         XXBYE, 0 },    /* BYE to remote server */
  668. #endif /* NOXFER */
  669. #ifndef NOLOCAL
  670.     { "c",           XXCON, CM_INV|CM_ABR|CM_LOC }, /* (CONNECT) */
  671. #endif /* NOLOCAL */
  672. #ifndef NOFRILLS
  673.     { "cat",         XXCAT, CM_INV },    /* Invisible synonym for TYPE */
  674. #endif /* NOFRILLS */
  675. #ifndef NOSPL
  676.  
  677. #ifndef NOXFER
  678.     { "cautious",    XXCAU, CM_INV },
  679. #endif /* NOXFER */
  680.  
  681. #endif /* NOSPL */
  682.  
  683.     { "cd",          XXCWD, 0 },    /* Change Directory */
  684.     { "cdup",        XXCDUP, CM_INV },    /* Change Directory Up */
  685.  
  686. #ifndef NOXFER
  687. #ifdef PIPESEND
  688.     { "cget",        XXCGET, CM_INV|CM_PSH }, /* CGET */
  689. #else
  690.     { "cget",        XXNOTAV, CM_INV|CM_PSH }, /* CGET */
  691. #endif /* PIPESEND */
  692. #endif /* NOXFER */
  693.     { "ch",          XXCHK,   CM_INV|CM_ABR },
  694.     { "check",       XXCHK,   0 },    /* CHECK for a feature */
  695. #ifdef CK_PERMS
  696. #ifdef UNIX
  697.     { "chmod",       XXCHMOD, 0 },    /* CHMOD */
  698. #else
  699.     { "chmod",       XXNOTAV, CM_INV },
  700. #endif /* UNIX */
  701. #else
  702.     { "chmod",       XXNOTAV, CM_INV },
  703. #endif /* CK_PERMS */
  704. #ifdef CKROOT
  705.     { "chroot",      XXCHRT,  CM_INV },    /* CHROOT */
  706. #endif /* CKROOT */
  707.     { "ckermit",     XXKERMI, CM_INV },    /* CKERMIT (like KERMIT) */
  708.     { "cl",          XXCLO,   CM_ABR|CM_INV },
  709. #ifndef NOFRILLS
  710.     { "clear",       XXCLE, 0 },    /* CLEAR input and/or device buffer */
  711. #else
  712.     { "clear",       XXNOTAV, CM_INV },
  713. #endif /* NOFRILLS */
  714.     { "close",         XXCLO, 0 },    /* CLOSE a log or other file */
  715.     { "cls",         XXCLS, CM_INV },    /* Clear Screen (CLS) */
  716.     { "comment",     XXCOM, CM_INV },    /* Introduce a comment */
  717. #ifndef NOLOCAL
  718.     { "connect",     XXCON, CM_LOC },    /* Begin terminal connection */
  719. #else
  720.     { "connect",     XXNOTAV, CM_LOC },
  721. #endif /* NOLOCAL */
  722.     { "continue",    XXCONT,  CM_INV },    /* CONTINUE */
  723. #ifndef NOFRILLS
  724. #ifdef ZCOPY
  725.     { "co",          XXCPY, CM_INV|CM_ABR },
  726.     { "cop",         XXCPY, CM_INV|CM_ABR },
  727.     { "copy",        XXCPY, 0 },    /* COPY a file */
  728. #else
  729.     { "copy",        XXNOTAV, CM_INV },
  730. #endif /* ZCOPY */
  731.     { "copyright",   XXCPR, CM_INV },    /* COPYRIGHT */
  732. #ifdef ZCOPY
  733.     { "cp",          XXCPY, CM_INV },    /* COPY a file */
  734. #endif /* ZCOPY */
  735. #ifndef NOLOCAL
  736. #ifndef OS2
  737.     { "cq",          XXCQ, CM_INV|CM_LOC }, /* CQ (connect quietly) */
  738. #endif /* OS2 */
  739. #endif /* NOLOCAL */
  740. #ifndef NOXFER
  741. #ifdef PIPESEND
  742.     { "creceive",    XXCREC,CM_INV|CM_PSH }, /* RECEIVE to a command */
  743.     { "csend",       XXCSEN,CM_INV|CM_PSH }, /* SEND from command */
  744. #else
  745.     { "creceive",    XXNOTAV,CM_INV|CM_PSH },
  746.     { "csend",       XXNOTAV,CM_INV|CM_PSH },
  747. #endif /* PIPESEND */
  748. #endif /* NOXFER */
  749. #endif /* NOFRILLS */
  750.  
  751.     { "cwd",         XXCWD,   CM_INV },    /* Traditional synonym for cd */
  752.  
  753. #ifndef NOSPL
  754.     { "date",        XXDATE,  0 },    /* DATE */
  755.     { "dcl",         XXDCL,   CM_INV },    /* DECLARE an array (see ARRAY) */
  756.     { "debug",       XXDEBUG, CM_INV },
  757.     { "declare",     XXDCL,   CM_INV },    /* DECLARE an array (see ARRAY) */
  758.     { "decrement",   XXDEC,   0 },    /* DECREMENT a numeric variable */
  759.     { "define",      XXDEF,   0 },    /* DEFINE a macro or variable */
  760. #else
  761.     { "date",        XXNOTAV, CM_INV },
  762.     { "dcl",         XXNOTAV, CM_INV },
  763.     { "declare",     XXNOTAV, CM_INV },
  764.     { "decrement",   XXNOTAV, CM_INV },
  765.     { "define",      XXNOTAV, CM_INV },
  766. #endif /* NOSPL */
  767.  
  768. #ifndef NOFRILLS
  769.     { "delete",      XXDEL, 0 },    /* DELETE a file */
  770. #else
  771.     { "delete",      XXNOTAV, CM_INV },
  772. #endif /* NOFRILLS */
  773.  
  774. #ifndef NODIAL
  775.     { "dial",        XXDIAL,  CM_LOC },    /* DIAL a phone number */
  776. #else
  777.     { "dial",        XXNOTAV, CM_INV|CM_LOC },
  778. #endif /* NODIAL */
  779.  
  780. #ifdef NT
  781.     { "dialer",      XXDIALER, CM_INV }, /* K95 Dialer */
  782. #endif /* NT */
  783.  
  784.     { "directory",   XXDIR, 0 },    /* DIRECTORY of files */
  785.  
  786. #ifndef NOFRILLS
  787. #ifndef NOSERVER
  788.     { "disable",     XXDIS, 0 },    /* DISABLE a server function */
  789. #else
  790.     { "disable",     XXNOTAV, CM_INV },
  791. #endif /* NOSERVER */
  792. #endif /* NOFRILLS */
  793.  
  794. #ifndef NOSPL
  795.     { "do",          XXDO,  0 },    /* DO (execute) a macro */
  796. #else
  797.     { "do",          XXNOTAV, CM_INV },
  798. #endif /* NOSPL */
  799.  
  800.     { "e",           XXEXI, CM_INV|CM_ABR },
  801.  
  802. #ifndef NOFRILLS
  803. #ifndef NOXFER
  804.     { "e-packet",    XXERR, CM_INV },    /* Send an Error-Packet */
  805. #endif /* NOXFER */
  806. #endif /* NOFRILLS */
  807.  
  808.     { "echo",        XXECH, 0 },    /* ECHO text */
  809.  
  810. #ifndef NOFRILLS
  811. #ifndef NOPUSH
  812.     { "edit",        XXEDIT, CM_PSH },    /* EDIT */
  813. #else
  814.     { "edit",        XXNOTAV, CM_INV|CM_PSH }, /* EDIT */
  815. #endif /* NOPUSH */
  816. #endif /* NOFRILLS */
  817.  
  818.     { "eightbit",    XXEIGHT, CM_INV },    /* EIGHTBIT */
  819.  
  820. #ifndef NOSPL
  821.     { "else",        XXELS, CM_INV },    /* ELSE part of IF statement */
  822. #else
  823.     { "else",        XXNOTAV, CM_INV },    /* ELSE part of IF statement */
  824. #endif /* NOSPL */
  825.  
  826. #ifndef NOSERVER
  827. #ifndef NOFRILLS
  828.     { "enable",      XXENA,  0 },    /* ENABLE a server function */
  829. #else
  830.     { "enable",      XXNOTAV, CM_INV },
  831. #endif /* NOFRILLS */
  832. #endif /* NOSERVER */
  833.  
  834. #ifndef NOSPL
  835.     { "end",         XXEND,  0 },    /* END command file or macro */
  836. #else
  837.     { "end",         XXNOTAV, CM_INV },
  838. #endif /* NOSPL */
  839.  
  840.     { "erase",       XXDEL, CM_INV },    /* Synonym for DELETE */
  841.  
  842. #ifndef NOSPL
  843.     { "evaluate",    XXEVAL, 0 },    /* EVALUATE */
  844. #else
  845.     { "evaluate",    XXNOTAV, CM_INV },
  846. #endif /* NOSPL */
  847.  
  848.     { "ex",          XXEXI, CM_INV|CM_ABR }, /* Let "ex" still be EXIT */
  849.  
  850. #ifdef CKEXEC
  851.     { "exec",        XXEXEC, CM_INV|CM_LOC }, /* exec() */
  852. #else
  853.     { "exec",        XXNOTAV, CM_INV|CM_LOC },
  854. #endif /* CKEXEC */
  855.  
  856.     { "exit",       XXEXI, 0 },        /* EXIT from C-Kermit */
  857.     { "extended-options", XXXOPTS,CM_INV|CM_HLP }, /* Extended-Options */
  858.  
  859. #ifdef OS2
  860.     { "extproc",     XXCOM, CM_INV },    /* Dummy command for OS/2 */
  861. #endif /* OS2 */
  862.  
  863. #ifndef NOXFER
  864.     { "f",           XXFIN, CM_INV|CM_ABR }, /* Invisible abbrev for FIN */
  865. #endif /* NOXFER */
  866.  
  867. #ifndef NOSPL
  868.     { "fail",        XXFAIL, CM_INV },    /* FAIL */
  869.  
  870. #ifndef NOXFER
  871.     { "fast",        XXFAST, CM_INV },
  872. #endif /* NOXFER */
  873.  
  874. #ifdef CKCHANNELIO
  875.     { "fclose",      XXF_CL, CM_INV },    /* FCLOSE */
  876.     { "fcount",      XXF_CO, CM_INV },    /* FCOUNT */
  877.     { "fflush",      XXF_FL, CM_INV },    /* FFLUSH */
  878. #endif /* CKCHANNELIO */
  879.  
  880. #ifndef NOXFER
  881.     { "fi",          XXFIN, CM_INV|CM_ABR }, /* FINISH */
  882. #endif /* NOXFER */
  883.  
  884. #ifdef CKCHANNELIO
  885.     { "file",        XXFILE, 0 },    /* FILE */
  886. #endif /* CKCHANNELIO */
  887. #endif /* NOSPL */
  888.  
  889. #ifndef NOXFER
  890.     { "fin",         XXFIN, CM_INV|CM_ABR }, /* FINISH */
  891. #endif /* NOXFER */
  892.  
  893. #ifndef UNIXOROSK
  894.     { "find",        XXGREP, 0 },    /* FIND (grep) */
  895. #else
  896.     { "find",        XXGREP,CM_INV },
  897. #endif /* UNIXOROSK */
  898.  
  899. #ifndef NOXFER
  900.     { "finish",      XXFIN, 0 },    /* FINISH */
  901. #endif /* NOXFER */
  902.  
  903. #ifdef TCPSOCKET
  904.     { "firewall",    XXFIREW, CM_INV|CM_HLP },
  905. #endif /* TCPSOCKET */
  906.  
  907. #ifdef CKCHANNELIO
  908.     { "flist",       XXF_LI, CM_INV },    /* FLIST */
  909.     { "fopen",       XXF_OP, CM_INV },    /* FOPEN */
  910. #endif /* CKCHANNELIO */
  911.  
  912. #ifndef NOSPL
  913.     { "fo",          XXFOR, CM_INV|CM_ABR }, /* Invisible abbrev for... */
  914.     { "for",         XXFOR, 0 },    /* FOR loop */
  915.     { "forward",     XXFWD, CM_INV },    /* FORWARD */
  916. #endif /* NOSPL */
  917. #ifndef NOFRILLS
  918.     { "fot",       XXDIR, CM_INV },    /* "fot" = "dir" (for Chris) */
  919. #endif /* NOFRILLS */
  920.  
  921. #ifdef CKCHANNELIO
  922.     { "fread",      XXF_RE, CM_INV },    /* FREAD */
  923.     { "frewind",    XXF_RW, CM_INV },    /* FREWIND */
  924.     { "fseek",      XXF_SE, CM_INV },    /* FSEEK */
  925.     { "fstatus",    XXF_ST, CM_INV },    /* FSTATUS */
  926. #endif /* CKCHANNELIO */
  927.  
  928. #ifdef TCPSOCKET
  929. #ifndef NOFTP
  930. #ifdef SYSFTP
  931. #ifndef NOPUSH
  932.     { "ftp",       XXFTP,   CM_INV|CM_PSH|CM_LOC }, /* System FTP */
  933. #else
  934.     { "ftp",       XXNOTAV, CM_INV|CM_PSH|CM_LOC },
  935. #endif /* NOPUSH */
  936. #else  /* SYSFTP */
  937.     { "ftp",       XXFTP,   0 },    /* Built-in FTP */
  938. #endif /* SYSFTP */
  939. #else  /* NOFTP */
  940.     { "ftp",       XXNOTAV, CM_INV },    /* No FTP */
  941. #endif /* NOFTP */
  942. #endif /* TCPSOCKET */
  943.  
  944. #ifndef NOSPL
  945.     { "function",    XXFUNC, CM_INV|CM_HLP }, /* (for HELP FUNCTION) */
  946. #endif /* NOSPL */
  947.  
  948. #ifdef CKCHANNELIO
  949.     { "fwrite",      XXF_WR, CM_INV },    /* FWRITE */
  950. #endif /* CKCHANNELIO */
  951.  
  952. #ifndef NOXFER
  953.     { "g",           XXGET, CM_INV|CM_ABR }, /* Invisible abbrev for GET */
  954. #ifndef NOSPL
  955.     { "ge",          XXGET, CM_INV|CM_ABR }, /* Ditto */
  956. #endif /* NOSPL */
  957.     { "get",         XXGET, 0 },    /* GET */
  958. #endif /* NOXFER */
  959. #ifndef NOSPL
  960.     { "getc",        XXGETC, 0 },    /* GETC */
  961. #ifdef OS2
  962.     { "getkeycode",  XXGETK, 0 },    /* GETKEYCODE */
  963. #endif /* OS2 */
  964. #ifndef NOFRILLS
  965.     { "getok",       XXGOK, 0 },    /* GETOK (ask for Yes/No/OK) */
  966. #endif /* NOFRILLS */
  967. #endif /* NOSPL */
  968. #ifndef NOSPL
  969.     { "goto",        XXGOTO,0 },    /* GOTO label in take file or macro */
  970. #endif /* NOSPL */
  971. #ifdef UNIXOROSK
  972.     { "grep",        XXGREP,0 },    /* GREP (find) */
  973. #else
  974.     { "grep",        XXGREP,CM_INV },    /* GREP (find) */
  975. #endif /* UNIXOROSK */
  976.     { "h",           XXHLP, CM_INV|CM_ABR }, /* Invisible synonym for HELP */
  977.     { "he",          XXHLP, CM_INV|CM_ABR }, /* Invisible synonym for HELP */
  978. #ifndef NOFRILLS
  979.     { "head",        XXHEAD, 0 },
  980. #endif /* NOFRILLS */
  981. #ifndef NOLOCAL
  982.     { "hangup",      XXHAN, CM_LOC },    /* HANGUP the connection */
  983. #endif /* NOLOCAL */
  984.     { "HELP",        XXHLP, 0 },    /* Display HELP text */
  985. #ifndef NOHTTP
  986. #ifdef TCPSOCKET
  987.     { "http",        XXHTTP, 0 },    /* HTTP operations */
  988. #endif /* TCPSOCKET */
  989. #endif /* NOHTTP */
  990. #ifndef NOSPL
  991.     { "i",           XXINP, CM_INV|CM_ABR }, /* Invisible synonym for INPUT */
  992.     { "if",          XXIF,  0 },         /* IF ( condition ) command */
  993. #ifdef TCPSOCKET
  994.     { "iksd",        XXIKSD, CM_INV },         /* Make connection to IKSD */
  995. #else
  996.     { "iksd",        XXNOTAV, CM_INV },
  997. #endif /* TCPSOCKET */
  998.     { "in",          XXINP, CM_INV|CM_ABR }, /* Invisible synonym for INPUT */
  999.     { "increment",   XXINC, 0 },    /* Increment a numeric variable */
  1000.     { "input",       XXINP, 0 },    /* INPUT text from comm device */
  1001. #endif /* NOSPL */
  1002.  
  1003. #ifndef NOHELP
  1004.     { "int",         XXINT, CM_INV|CM_ABR },
  1005.     { "intr",        XXINT, CM_INV|CM_ABR },
  1006.     { "INTRO",       XXINT, 0 },
  1007.     { "introduction",XXINT, CM_INV },    /* Print introductory text */
  1008. #else
  1009.     { "intro",       XXNOTAV, CM_INV },
  1010.     { "introduction",XXNOTAV, CM_INV },
  1011. #endif /* NOHELP */
  1012.  
  1013. #ifdef OS2
  1014.     { "k95",         XXKERMI, CM_INV },    /* Hmmm what's this... */
  1015. #endif /* OS2 */
  1016.  
  1017. #ifndef NOSPL
  1018.     { "kcd",         XXKCD,   0      },
  1019. #endif /* NOSPL */
  1020.  
  1021.     { "kermit",      XXKERMI, CM_INV },
  1022.  
  1023. #ifdef OS2
  1024. #ifndef NOKVERBS
  1025.     { "kverb",       XXKVRB, CM_INV|CM_HLP }, /* Keyboard verb */
  1026. #endif /* NOKVERBS */
  1027. #endif /* OS2 */
  1028.  
  1029. #ifndef NOFRILLS
  1030.     { "l",           XXLOG, CM_INV|CM_ABR }, /* Invisible synonym for log */
  1031. #endif /* NOFRILLS */
  1032.  
  1033.     { "lcd",         XXLCWD, CM_INV },
  1034.     { "lcdup",       XXLCDU, CM_INV },
  1035.     { "lcwd",        XXLCWD, CM_INV },
  1036.     { "ldelete",     XXLDEL, CM_INV },
  1037.     { "ldirectory",  XXLDIR, CM_INV },
  1038.  
  1039. #ifdef CKLEARN
  1040.     { "learn",       XXLEARN, 0 },    /* LEARN - automatic script writing */
  1041. #else
  1042.     { "learn",       XXNOTAV, CM_INV },
  1043. #endif /* CKLEARN */
  1044.  
  1045.     { "li",          XXLNOUT, CM_INV|CM_ABR },
  1046.     { "LICENSE",     XXCPR, 0 },    /* LICENSE */
  1047.  
  1048. #ifndef NOSPL
  1049.     { "lineout",     XXLNOUT, 0 },    /* LINEOUT = OUTPUT + eol */
  1050. #endif /* NOSPL */
  1051.  
  1052. #ifdef NT
  1053.     { "link",        XXLINK, 0 },       /* LINK source destination */
  1054. #endif /* NT */
  1055.  
  1056.     { "lmkdir",      XXLMKD, CM_INV },
  1057.  
  1058. #ifndef NOFRILLS
  1059.     { "lo",          XXLOG,  CM_INV|CM_ABR }, /* Invisible synonym for log */
  1060. #endif /* NOFRILLS */
  1061.  
  1062. #ifndef NOSPL
  1063.     { "local",       XXLOCAL, CM_INV },    /* LOCAL variable declaration */
  1064. #else
  1065.     { "local",       XXNOTAV, CM_INV },
  1066. #endif /* NOSPL */
  1067.  
  1068.     { "log",           XXLOG, 0 },    /* Open a log file */
  1069.  
  1070.     { "login",       XXLOGIN,  0 },    /* (REMOTE) LOGIN to server or IKSD */
  1071.     { "logout",      XXLOGOUT, 0 },    /* LOGOUT from server or IKSD */
  1072.  
  1073. #ifndef NOFRILLS
  1074. #ifndef NODIAL
  1075.     { "lookup",      XXLOOK,  0 },    /* LOOKUP */
  1076. #else
  1077.     { "lookup",      XXNOTAV, CM_INV },
  1078. #endif /* NODIAL */
  1079.  
  1080.     { "lpwd",        XXLPWD, CM_INV },
  1081.     { "lrename",     XXLREN, CM_INV },
  1082.     { "lrmdir",      XXLRMD, CM_INV },
  1083.  
  1084. #ifdef UNIXOROSK
  1085.     { "ls",          XXLS,  CM_INV|CM_PSH }, /* UNIX ls command */
  1086. #else
  1087.     { "ls",          XXDIR, CM_INV },    /* Invisible synonym for DIR */
  1088. #endif /* UNIXOROSK */
  1089. #ifndef NOXFER
  1090.     { "mail",        XXMAI, 0 },    /* Send a file as e-mail */
  1091. #endif /* NOXFER */
  1092. #ifndef NOHELP
  1093.     { "manual",      XXMAN, CM_PSH },    /* MAN(UAL) */
  1094. #else
  1095.     { "manual",      XXNOTAV, CM_INV|CM_PSH },
  1096. #endif /* NOHELP */
  1097. #endif /* NOFRILLS */
  1098. #ifdef CK_MKDIR
  1099.     { "md",          XXMKDIR, CM_INV },    /* Synonym for MKDIR */
  1100. #endif /* CK_MKDIR */
  1101. #ifdef CK_MINPUT
  1102.     { "minput",      XXMINP, 0 },    /* MINPUT */
  1103. #else
  1104.     { "minput",      XXNOTAV, CM_INV },
  1105. #endif /* CK_MINPUT */
  1106. #ifndef NOMSEND
  1107.     { "mget",        XXMGET, 0 },    /* MGET */
  1108. #else
  1109.     { "mget",        XXNOTAV, CM_INV },
  1110. #endif /* NOMSEND */
  1111. #ifdef CK_MKDIR
  1112.     { "mkdir",       XXMKDIR, 0 },    /* MKDIR */
  1113. #else
  1114.     { "mkdir",       XXNOTAV, CM_INV },
  1115. #endif /* CK_MKDIR */
  1116.  
  1117. #ifndef NOXFER
  1118. #ifndef NOMSEND
  1119.     { "mmove",       XXMMOVE, 0 },    /* MMOVE */
  1120. #else
  1121.     { "mmove",       XXNOTAV, CM_INV },
  1122. #endif /* NOMSEND */
  1123. #endif /* NOXFER */
  1124.  
  1125. #ifndef NOFRILLS
  1126.     { "more",        XXMORE, CM_INV },    /* MORE */
  1127. #endif /* NOFRILLS */
  1128.  
  1129. #ifndef NOXFER
  1130.     { "move",        XXMOVE, 0 },    /* MOVE  */
  1131. #endif /* NOXFER */
  1132.  
  1133. #ifndef NOSPL
  1134.     { "mpause",      XXMSL, CM_INV },    /* Millisecond sleep */
  1135. #else
  1136.     { "mpause",      XXNOTAV, CM_INV },
  1137. #endif /* NOSPL */
  1138.  
  1139. #ifndef NOXFER
  1140. #ifndef NOMSEND
  1141.     { "mput",        XXMSE, CM_INV },    /* MPUT = MSEND */
  1142.     { "ms",          XXMSE, CM_INV|CM_ABR },
  1143.     { "msend",       XXMSE, 0 },    /* Multiple SEND */
  1144. #else
  1145.     { "mput",        XXNOTAV, CM_INV },
  1146.     { "msend",       XXNOTAV, CM_INV },
  1147. #endif /* NOMSEND */
  1148. #endif /* NOXFER */
  1149. #ifndef NOSPL
  1150.     { "msleep",      XXMSL, 0 },    /* Millisecond sleep */
  1151. #else
  1152.     { "msleep",      XXNOTAV, CM_INV },
  1153. #endif /* NOSPL */
  1154. #ifndef NOFRILLS
  1155.     { "mv",          XXREN, CM_INV },    /* Synonym for rename */
  1156. #endif /* NOFRILLS */
  1157. #ifndef NOHELP
  1158.     { "news",        XXNEW, CM_INV },    /* Display NEWS of new features */
  1159. #else
  1160.     { "news",        XXNOTAV, CM_INV },
  1161. #endif /* NOHELP */
  1162.     { "nolocal",     XXNLCL, CM_INV },    /* Disable SET LINE / SET HOST */
  1163.     { "nopush",      XXNPSH, CM_INV },    /* Disable PUSH command/features */
  1164. #ifdef OS2
  1165.     { "noscroll",    XXNSCR, CM_INV },  /* Disable scroll operations */
  1166. #endif /* OS2 */
  1167. #ifndef NOSPL
  1168.     { "o",           XXOUT, CM_INV|CM_ABR }, /* Invisible synonym for OUTPUT */
  1169.     { "open",        XXOPE, 0 },    /* OPEN file for reading or writing */
  1170. #else
  1171.     { "open",        XXOPE, CM_INV },    /* OPEN */
  1172. #endif /* NOSPL */
  1173. #ifndef NOHELP
  1174.     { "options",     XXOPTS,CM_INV|CM_HLP }, /* Options */
  1175. #endif /* NOHELP */
  1176.     { "orientation", XXORIE, 0 },
  1177. #ifndef NOSPL
  1178.     { "output",      XXOUT, 0 },    /* OUTPUT text to comm device */
  1179. #else
  1180.     { "output",      XXNOTAV, CM_INV },
  1181. #endif /* NOSPL */
  1182. #ifdef ANYX25
  1183. #ifndef IBMX25
  1184.     { "pad",         XXPAD, CM_LOC },    /* X.3 PAD commands */
  1185. #endif /* IBMX25 */
  1186. #endif /* ANYX25 */
  1187.  
  1188. #ifdef NEWFTP
  1189.     { "passive",     XXPASV, CM_INV },    /* (FTP) PASSIVE */
  1190. #endif /* NEWFTP */
  1191.  
  1192. #ifndef NOHELP
  1193.     { "patterns",    XXPAT,CM_INV|CM_HLP }, /* Pattern syntax */
  1194. #endif /* NOHELP */
  1195.  
  1196. #ifndef NOSPL
  1197.     { "pause",       XXPAU, 0 },    /* Sleep for specified interval */
  1198. #else
  1199.     { "pause",       XXNOTAV, CM_INV },
  1200. #endif /* NOSPL */
  1201. #ifndef NODIAL
  1202.     { "pdial",       XXPDIA,  CM_LOC },    /* PDIAL (partial dial) */
  1203. #else
  1204.     { "pdial",       XXNOTAV, CM_INV|CM_LOC },
  1205. #endif /* NODIAL */
  1206. #ifdef TCPSOCKET
  1207. #ifndef NOPUSH
  1208.     { "ping",        XXPNG, CM_INV|CM_PSH|CM_LOC }, /* PING */
  1209. #else
  1210.     { "ping",        XXNOTAV, CM_INV|CM_PSH|CM_LOC },
  1211. #endif /* NOPUSH */
  1212. #endif /* TCPSOCKET */
  1213. #ifdef NETCMD
  1214. #ifndef NOPUSH
  1215.     { "pipe",        XXPIPE, CM_PSH },    /* PIPE */
  1216. #else
  1217.     { "pipe",        XXNOTAV, CM_INV|CM_PSH }, /* PIPE */
  1218. #endif /* NOPUSH */
  1219. #endif /* NETCMD */
  1220.  
  1221. #ifndef NOSPL
  1222.     { "pop",         XXEND, CM_INV },    /* Invisible synonym for END */
  1223. #endif /* NOSPL */
  1224. #ifndef NOFRILLS
  1225.     { "print",       XXPRI, 0 },    /* PRINT a file locally */
  1226. #endif /* NOFRILLS */
  1227.  
  1228.     { "prompt",      XXPROMP, CM_INV },    /* Go interactive (from script) */
  1229.  
  1230. #ifndef NOXFER
  1231. #ifdef CK_RESEND
  1232.     { "psend",       XXPSEN, CM_INV },    /* PSEND */
  1233. #else
  1234.     { "psend",       XXNOTAV, CM_INV },
  1235. #endif /* CK_RESEND */
  1236. #endif /* NOXFER */
  1237.  
  1238. #ifdef NETPTY
  1239.     { "pty",         XXPTY, CM_PSH },    /* PTY */
  1240. #else
  1241.     { "pty",         XXNOTAV, CM_INV|CM_PSH },
  1242. #endif /* NETPTY */
  1243.  
  1244. #ifndef NOPUSH
  1245.     { "pu",          XXSHE, CM_INV|CM_ABR|CM_PSH }, /* PU = PUSH */
  1246. #endif /* NOPUSH */
  1247.  
  1248. #ifdef CKPURGE
  1249.     { "purge",       XXPURGE, 0 },    /* PURGE (real) */
  1250. #else
  1251. #ifdef VMS
  1252.     { "purge",       XXPURGE, 0 },    /* PURGE (fake) */
  1253. #else
  1254.     { "purge",       XXNOTAV, CM_INV },
  1255. #endif /* VMS */
  1256. #endif /* CKPURGE */
  1257.  
  1258. #ifndef NOPUSH
  1259.     { "push",        XXSHE, CM_PSH },    /* PUSH command (like RUN, !) */
  1260. #else
  1261.     { "push",        XXNOTAV, CM_INV|CM_PSH },
  1262. #endif /* NOPUSH */
  1263.  
  1264. #ifndef NOXFER
  1265.     { "put",         XXSEN, CM_INV },    /* PUT = SEND */
  1266. #endif /* NOXFER */
  1267.  
  1268.     { "pwd",         XXPWD, 0 },    /* Print Working Directory */
  1269.     { "q",           XXQUI, CM_INV|CM_ABR }, /* Invisible synonym for QUIT */
  1270.  
  1271. #ifndef NOXFER
  1272.     { "query",       XXRQUE,CM_INV },    /* (= REMOTE QUERY) */
  1273. #endif /* NOXFER */
  1274.  
  1275.     { "quit",        XXQUI, 0 },    /* QUIT from program = EXIT */
  1276.  
  1277. #ifndef NOXFER
  1278.     { "r",           XXREC, CM_INV|CM_ABR }, /* Inv synonym for RECEIVE */
  1279. #endif /* NOXFER */
  1280.  
  1281. #ifndef NOXFER
  1282.     { "rasg",        XXRASG, CM_INV },    /* REMOTE ASSIGN */
  1283.     { "rassign",     XXRASG, CM_INV },    /* ditto */
  1284.     { "rcd",         XXRCWD, CM_INV },    /* REMOTE CD */
  1285.     { "rcdup",       XXRCDUP,CM_INV },    /* REMOTE CD */
  1286.     { "rcopy",       XXRCPY, CM_INV },    /* REMOTE COPY */
  1287.     { "rcwd",        XXRCWD, CM_INV },    /* REMOTE CWD */
  1288.     { "rdelete",     XXRDEL, CM_INV },    /* REMOTE DELETE */
  1289.     { "rdirectory",  XXRDIR, CM_INV },    /* REMODE DIRECTORY */
  1290. #endif /* NOXFER */
  1291.  
  1292. #ifndef NOSPL
  1293.     { "read",        XXREA, 0 },    /* READ a line from a file */
  1294. #else
  1295.     { "read",        XXNOTAV, CM_INV },
  1296. #endif /* NOSPL */
  1297.  
  1298. #ifndef NOXFER
  1299.     { "receive",     XXREC, 0 },    /* RECEIVE files */
  1300. #endif /* NOXFER */
  1301.  
  1302. #ifndef NODIAL
  1303.     { "red",         XXRED, CM_INV|CM_ABR|CM_LOC }, /* Inv syn for REDIAL */
  1304.     { "redi",        XXRED, CM_INV|CM_ABR|CM_LOC }, /* ditto */
  1305.     { "redial",      XXRED, CM_LOC },    /* REDIAL last DIAL number */
  1306. #else
  1307.     { "red",         XXNOTAV, CM_INV|CM_LOC },
  1308.     { "redi",        XXNOTAV, CM_INV|CM_LOC },
  1309.     { "redial",      XXNOTAV, CM_INV|CM_LOC },
  1310. #endif /* NODIAL */
  1311.  
  1312. #ifdef CK_REDIR
  1313. #ifdef OS2
  1314. #ifndef NOPUSH
  1315.     { "redirect",    XXFUN, CM_INV|CM_PSH }, /* REDIRECT */
  1316. #else
  1317.     { "redirect",    XXNOTAV, CM_INV|CM_PSH },
  1318. #endif /* NOPUSH */
  1319. #else /* OS2 */
  1320. #ifndef NOPUSH
  1321.     { "redirect",    XXFUN, CM_PSH },    /* REDIRECT */
  1322. #else
  1323.     { "redirect",    XXNOTAV, CM_INV|CM_PSH },
  1324. #endif /* NOPUSH */
  1325. #endif /* OS2 */
  1326. #endif /* CK_REDIR */
  1327.  
  1328. #ifdef CK_RECALL
  1329.     { "redo",        XXREDO,  CM_NOR },    /* REDO */
  1330. #else
  1331.     { "redo",        XXNOTAV, CM_INV },
  1332. #endif /* CK_RECALL */
  1333.  
  1334. #ifndef NOXFER
  1335. #ifdef CK_RESEND
  1336.     { "reget",       XXREGET, 0 },    /* REGET */
  1337. #else
  1338.     { "reget",       XXNOTAV, CM_INV },
  1339. #endif /* CK_RESEND */
  1340. #endif /* NOXFER */
  1341.  
  1342. #ifndef NOSPL
  1343.     { "reinput",     XXREI, CM_INV },    /* REINPUT (from INPUT buffer) */
  1344. #else
  1345.     { "reinput",     XXNOTAV, CM_INV },
  1346. #endif /* NOSPL */
  1347.  
  1348. #ifndef NOXFER
  1349. #ifdef ADDCMD
  1350.     { "rem",         XXREM, CM_INV|CM_ABR },
  1351.     { "remo",        XXREM, CM_INV|CM_ABR },
  1352. #endif /* ADDCMD */
  1353.     { "remote",         XXREM, 0 },    /* Send REMOTE command to server */
  1354. #endif /* NOXFER */
  1355.  
  1356. #ifdef ADDCMD
  1357.     { "remove",      XXREMV,0 },    /* REMOVE (something from a list) */
  1358. #else
  1359.     { "remove",      XXNOTAV, CM_INV },
  1360. #endif /* ADDCMD */
  1361.  
  1362. #ifndef NOFRILLS
  1363. #ifndef NORENAME
  1364.     { "rename",      XXREN, 0 },    /* RENAME a local file */
  1365. #else
  1366.     { "rename",      XXNOTAV, CM_INV },
  1367. #endif /* NORENAME */
  1368.     { "replay",      XXTYP, CM_INV },    /* REPLAY (for now, just type) */
  1369. #endif /* NOFRILLS */
  1370.  
  1371. #ifndef NOXFER
  1372. #ifdef CK_RESEND
  1373.     { "res",         XXRSEN, CM_INV|CM_ABR }, /* RESEND */
  1374.     { "rese",        XXRSEN, CM_INV|CM_ABR }, /* RESEND */
  1375.     { "resend",      XXRSEN, 0 },    /* RESEND */
  1376. #else
  1377.     { "res",         XXNOTAV, CM_INV },
  1378.     { "rese",        XXNOTAV, CM_INV },
  1379.     { "resend",      XXNOTAV, CM_INV },
  1380. #endif /* CK_RESEND */
  1381. #endif /* NOXFER */
  1382.  
  1383.     { "reset",       XXRESET, CM_INV },    /* RESET */
  1384.  
  1385. #ifdef CK_RESEND
  1386. #ifndef NOSPL
  1387.     { "ret",         XXRET, CM_INV|CM_ABR },
  1388. #endif /* NOSPL */
  1389. #endif /* CK_RESEND */
  1390.  
  1391. #ifndef NOXFER
  1392.     { "retrieve",    XXRETR, CM_INV },    /* RETRIEVE */
  1393. #endif /* NOXFER */
  1394.  
  1395. #ifndef NOSPL
  1396.     { "return",      XXRET, 0 },    /* RETURN from a function */
  1397. #else
  1398.     { "return",      XXNOTAV, CM_INV },
  1399. #endif /* NOSPL */
  1400.  
  1401. #ifndef NOXFER
  1402.     { "rexit",       XXRXIT, CM_INV },    /* REMOTE EXIT */
  1403. #endif /* NOXFER */
  1404.  
  1405. #ifdef CK_REXX
  1406. #ifndef NOPUSH
  1407.     { "rexx",        XXREXX, CM_PSH },    /* Execute a Rexx command */
  1408. #else
  1409.     { "rexx",        XXNOTAV, CM_INV|CM_PSH },
  1410. #endif /* NOPUSH */
  1411. #endif /* CK_REXX */
  1412.  
  1413. #ifndef NOXFER
  1414.     { "rhelp",       XXRHLP, CM_INV },    /* REMOTE HELP */
  1415.     { "rhost",       XXRHOS, CM_INV },    /* REMOTE HOST */
  1416.     { "rkermit",     XXRKER, CM_INV },    /* REMOTE KERMIT */
  1417. #endif /* NOXFER */
  1418.  
  1419. #ifdef TCPSOCKET
  1420.     { "rlogin",      XXRLOG, CM_LOC },    /* Make an Rlogin connection */
  1421. #else
  1422.     { "rlogin",      XXNOTAV, CM_INV|CM_LOC },
  1423. #endif /* TCPSOCKET */
  1424.  
  1425. #ifndef NOFRILLS
  1426.     { "rm",          XXDEL, CM_INV },    /* Invisible synonym for delete */
  1427. #endif /* NOFRILLS */
  1428.  
  1429. #ifdef CK_MKDIR
  1430.     { "rmdir",       XXRMDIR, 0 },    /* RMDIR */
  1431. #else
  1432.     { "rmdir",       XXNOTAV, CM_INV },
  1433. #endif /* CK_MKDIR */
  1434.  
  1435. #ifndef NOXFER
  1436.     { "rmkdir",      XXRMKD, CM_INV },    /* REMOTE MKDIR */
  1437. #ifndef NOSPL
  1438.     { "robust",      XXROB,  CM_INV },
  1439. #else
  1440.     { "robust",      XXNOTAV, CM_INV },
  1441. #endif /* NOSPL */
  1442.     { "rprint",      XXRPRI, CM_INV },  /* REMOTE PRINT */
  1443.     { "rpwd",        XXRPWD, CM_INV },    /* REMOTE PWD */
  1444.     { "rquery",      XXRQUE, CM_INV },    /* REMOTE QUERY */
  1445. #endif /* NOXFER */
  1446.  
  1447. #ifdef CK_RECALL
  1448.     { "rr",          XXREDO, CM_INV|CM_NOR },
  1449. #endif /* CK_RECALL */
  1450.  
  1451. #ifndef NOXFER
  1452.     { "rrename",    XXRREN, CM_INV },    /* REMOTE RENAME */
  1453.     { "rrmdir",     XXRRMD, CM_INV },    /* REMOTE REMDIR */
  1454.     { "rset",       XXRSET, CM_INV },    /* REMOTE SET */
  1455.     { "rspace",     XXRSPA, CM_INV },    /* REMOTE SPACE */
  1456.     { "rtype",      XXRTYP, CM_INV },    /* REMOTE TYPE */
  1457. #endif /* NOXFER */
  1458.  
  1459. #ifndef NOPUSH
  1460.     { "run",         XXSHE, CM_PSH },    /* RUN a program or command */
  1461. #else
  1462.     { "run",         XXNOTAV, CM_INV|CM_PSH },
  1463. #endif /* NOPUSH */
  1464.  
  1465. #ifndef NOXFER
  1466.     { "rwho",        XXRWHO, CM_INV },    /* REMOTE WHO */
  1467.     { "s",           XXSEN, CM_INV|CM_ABR }, /* Invisible synonym for send */
  1468. #endif /* NOXFER */
  1469.  
  1470. #ifndef NOSETKEY
  1471. #ifdef OS2
  1472.     { "save",       XXSAVE, 0 },        /* SAVE something */
  1473. #else
  1474.     { "save",       XXSAVE, CM_INV },
  1475. #endif /* OS2 */
  1476. #else
  1477.     { "save",       XXNOTAV, CM_INV },
  1478. #endif /* NOSETKEY */
  1479.  
  1480. #ifndef NOSCRIPT
  1481.     { "sc",        XXLOGI, CM_INV|CM_ABR|CM_LOC },
  1482.     { "scr",       XXLOGI, CM_INV|CM_ABR|CM_LOC },
  1483. #endif /* NOSCRIPT */
  1484.     { "screen",      XXSCRN, 0 },    /* SCREEN actions */
  1485. #ifndef NOSCRIPT
  1486.     { "script",       XXLOGI, CM_LOC },    /* Expect-Send-style script line */
  1487. #else
  1488.     { "script",       XXNOTAV, CM_INV|CM_LOC },
  1489. #endif /* NOSCRIPT */
  1490.  
  1491.     { "search",    XXGREP,CM_INV },    /* Synonym for GREP and FIND */
  1492.  
  1493. #ifndef NOXFER
  1494.     { "send",       XXSEN, 0 },        /* Send (a) file(s) */
  1495. #ifndef NOSERVER
  1496.     { "server",       XXSER, 0 },        /* Be a SERVER */
  1497. #else
  1498.     { "server",       XXNOTAV, CM_INV },
  1499. #endif /* NOSERVER */
  1500. #endif /* NOXFER */
  1501.  
  1502.     { "set",       XXSET, 0 },        /* SET parameters */
  1503.  
  1504. #ifndef NOSPL
  1505. #ifndef NOSEXP
  1506.     { "sexpression", XXSEXP, CM_INV|CM_HLP }, /* SEXPR */
  1507. #endif /* NOSEXP */
  1508. #ifndef NOSHOW
  1509.     { "sh",          XXSHO, CM_INV|CM_ABR }, /* SHOW parameters */
  1510. #endif /* NOSHOW */
  1511.     { "shift",       XXSHIFT, 0 },    /* SHIFT args */
  1512. #else
  1513.     { "shift",       XXNOTAV, CM_INV },
  1514. #endif /* NOSPL */
  1515.  
  1516. #ifndef NOSHOW
  1517.     { "show",        XXSHO, 0 },        /* SHOW parameters */
  1518. #else
  1519.     { "show",        XXNOTAV, CM_INV },
  1520. #endif /* NOSHOW */
  1521.  
  1522. #ifndef NOSPL
  1523. #ifndef NOFRILLS
  1524.     { "sleep",       XXPAU, CM_INV },    /* SLEEP for specified interval */
  1525. #endif /* NOFRILLS */
  1526. #endif /* NOSPL */
  1527.  
  1528. #ifdef NEWFTP
  1529.     { "site",        XXSITE, CM_INV },    /* (FTP) SITE */
  1530. #endif /* NEWFTP */
  1531.  
  1532. #ifndef NOSPL
  1533.     { "sort",        XXSORT, CM_INV },    /* (see ARRAY) */
  1534. #else
  1535.     { "sort",        XXNOTAV, CM_INV },
  1536. #endif /* NOSPL */
  1537.  
  1538. #ifndef MAC
  1539. #ifndef NOFRILLS
  1540.     { "sp",          XXSPA, CM_INV|CM_ABR },
  1541.     { "spa",         XXSPA, CM_INV|CM_ABR },
  1542. #endif /* NOFRILLS */
  1543.     { "space",       XXSPA, 0 },    /* Show available disk SPACE */
  1544. #endif /* MAC */
  1545.  
  1546. #ifndef NOFRILLS
  1547. #ifndef NOPUSH
  1548.     { "spawn",       XXSHE, CM_INV|CM_PSH }, /* Synonym for PUSH, RUN */
  1549. #else
  1550.     { "spawn",       XXNOTAV, CM_INV|CM_PSH }, /* Synonym for PUSH, RUN */
  1551. #endif /* NOPUSH */
  1552. #endif /* NOFRILLS */
  1553.  
  1554. #ifdef ANYSSH
  1555.     { "ssh",         XXSSH, 0 },
  1556. #endif /* ANYSSH */
  1557.  
  1558. #ifndef NOXFER
  1559.     { "sta",         XXSTA, CM_INV|CM_ABR },
  1560.     { "stat",        XXSTA, CM_INV|CM_ABR },
  1561.     { "statistics",  XXSTA, 0 },    /* Display file transfer stats */
  1562. #endif /* NOXFER */
  1563.  
  1564.     { "status",      XXSTATUS,0 },    /* Show status of previous command */
  1565.  
  1566. #ifndef NOSPL
  1567.     { "stop",        XXSTO,   0 },    /* STOP all take files and macros */
  1568.     { "succeed",     XXSUCC,  CM_INV },    /* SUCCEED */
  1569. #else
  1570.     { "stop",        XXNOTAV, CM_INV },
  1571.     { "succeed",     XXNOTAV, CM_INV },
  1572. #endif /* NOSPL */
  1573.  
  1574. #ifndef NOFRILLS
  1575.     { "SUPPORT",     XXBUG, 0 },    /* Tech support instructions */
  1576. #else
  1577.     { "support",     XXNOTAV, CM_INV },
  1578. #endif /* NOFRILLS */
  1579.  
  1580. #ifndef NOJC
  1581.     { "suspend",     XXSUS, CM_PSH },    /* SUSPEND C-Kermit (UNIX only) */
  1582. #else
  1583.     { "suspend",     XXNOTAV, CM_INV|CM_PSH },
  1584. #endif /* NOJC */
  1585.  
  1586. #ifndef NOSPL
  1587.     { "switch",      XXSWIT, 0 },    /* SWITCH */
  1588. #else
  1589.     { "switch",      XXNOTAV, CM_INV },
  1590. #endif /* NOSPL */
  1591.  
  1592. #ifdef CK_TAPI
  1593.     { "ta",       XXTAK, CM_INV|CM_ABR }, /* (because of TAPI) */
  1594. #endif /* CK_TAPI */
  1595.  
  1596. #ifndef NOFRILLS
  1597.     { "tail",        XXTAIL, 0 },    /* Display end of a local file */
  1598. #endif /* NOFRILLS */
  1599.  
  1600.     { "take",       XXTAK, 0 },        /* TAKE commands from a file */
  1601.  
  1602. #ifdef CK_TAPI
  1603.     { "tapi",       XXTAPI, CM_LOC },    /* Microsoft TAPI commands */
  1604. #else
  1605.     { "tapi",       XXNOTAV, CM_INV|CM_LOC },
  1606. #endif /* CK_TAPI */
  1607.  
  1608. #ifndef NOFRILLS
  1609. #ifdef TCPSOCKET
  1610.     { "tel",         XXTEL, CM_INV|CM_ABR|CM_LOC },
  1611.     { "telnet",      XXTEL, CM_LOC },    /* TELNET (TCP/IP only) */
  1612.     { "telopt",      XXTELOP, CM_INV },    /* TELOPT (ditto) */
  1613. #else
  1614.     { "tel",         XXNOTAV, CM_INV|CM_LOC },
  1615.     { "telnet",      XXNOTAV, CM_INV|CM_LOC },
  1616.     { "telopt",      XXNOTAV, CM_INV },
  1617. #endif /* TCPSOCKET */
  1618. #ifdef OS2
  1619.     { "terminal",    XXTERM, CM_INV|CM_LOC }, /* == SET TERMINAL TYPE */
  1620. #else
  1621.     { "terminal",    XXTERM, CM_INV },
  1622. #endif /* OS2 */
  1623. #endif /* NOFRILLS */
  1624. #ifndef NOXFER
  1625.     { "text",        XXASC, CM_INV },    /* == SET FILE TYPE TEXT */
  1626. #endif /* NOXFER */
  1627.  
  1628. #ifndef NOSPL
  1629.     { "trace",       XXTRACE, 0 },    /* TRACE */
  1630. #else
  1631.     { "trace",       XXNOTAV, CM_INV },
  1632. #endif /* NOSPL */
  1633.  
  1634. #ifndef NOCSETS
  1635.     { "translate",   XXXLA, 0 },    /* TRANSLATE local file char sets */
  1636. #else
  1637.     { "translate",   XXNOTAV, CM_INV },
  1638. #endif /* NOCSETS */
  1639.  
  1640. #ifndef NOXMIT
  1641.     { "transmit",    XXTRA, 0 },    /* Send (upload) a file, no protocol */
  1642. #else
  1643.     { "transmit",    XXNOTAV, CM_INV },
  1644. #endif /* NOXMIT */
  1645.  
  1646. #ifndef NOFRILLS
  1647.     { "type",        XXTYP, 0 },    /* Display a local file */
  1648. #endif /* NOFRILLS */
  1649.  
  1650. #ifndef NOSPL
  1651.     { "undcl",       XXUNDCL, CM_INV },
  1652.     { "undeclare",   XXUNDCL, 0 },    /* UNDECLARE an array */
  1653.     { "undefine",    XXUNDEF, 0 },    /* UNDEFINE a variable or macro */
  1654. #else
  1655.     { "undcl",       XXNOTAV, CM_INV },
  1656.     { "undeclare",   XXNOTAV, CM_INV },
  1657.     { "undefine",    XXNOTAV, CM_INV },
  1658. #endif /* NOSPL */
  1659.  
  1660. #ifdef NEWFTP
  1661.     { "user",        XXUSER,  CM_INV }, /* (FTP) USER */
  1662. #endif /* NEWFTP */
  1663.  
  1664.     { "version",     XXVER, 0 },    /* VERSION-number display */
  1665.  
  1666. #ifdef OS2
  1667.     { "viewonly",    XXVIEW, CM_LOC },    /* VIEWONLY Terminal Mode */
  1668. #endif /* OS2 */
  1669.  
  1670.     { "void",        XXVOID, 0 },    /* VOID */
  1671.  
  1672. #ifndef NOSPL
  1673.     { "wait",        XXWAI, 0 },    /* WAIT */
  1674. #else
  1675.     { "wait",        XXNOTAV, CM_INV },
  1676. #endif /* NOSPL */
  1677.  
  1678.     { "wermit",      XXKERMI, CM_INV },
  1679.  
  1680. #ifndef NOXFER
  1681.     { "where",       XXWHERE, 0 },    /* WHERE (did my file go?) */
  1682. #endif /* NOXFER */
  1683.  
  1684. #ifndef NOSPL
  1685.     { "while",       XXWHI, 0 },    /* WHILE loop */
  1686. #else
  1687.     { "while",       XXNOTAV, CM_INV },
  1688. #endif /* NOSPL */
  1689.  
  1690. #ifndef OS2
  1691. #ifndef MAC
  1692. #ifndef NOFRILLS
  1693.     { "who",         XXWHO, CM_PSH },    /* WHO's logged in? */
  1694. #endif /* NOFRILLS */
  1695. #endif /* MAC */
  1696. #endif /* OS2 */
  1697.  
  1698. #ifndef NOHELP
  1699.     { "wildcards",   XXWILD,CM_INV|CM_HLP }, /* Wildcard syntax */
  1700. #endif /* NOHELP */
  1701.  
  1702. #ifndef NOSPL
  1703.     { "wr",          XXWRI, CM_INV|CM_ABR },
  1704.     { "wri",         XXWRI, CM_INV|CM_ABR },
  1705.     { "writ",        XXWRI, CM_INV|CM_ABR },
  1706.     { "write",       XXWRI, 0 },    /* WRITE characters to a file */
  1707.     { "write-line",  XXWRL, CM_INV },    /* WRITE a line to a file */
  1708.     { "writeln",     XXWRL, CM_INV },    /* Pascalisch synonym for write-line */
  1709. #else
  1710.     { "wr",          XXNOTAV, CM_INV },
  1711.     { "wri",         XXNOTAV, CM_INV },
  1712.     { "writ",        XXNOTAV, CM_INV },
  1713.     { "write",       XXNOTAV, CM_INV },
  1714.     { "write-line",  XXNOTAV, CM_INV },
  1715.     { "writeln",     XXNOTAV, CM_INV },
  1716. #endif /* NOSPL */
  1717.  
  1718. #ifndef NOFRILLS
  1719.     { "xecho",       XXXECH,0 },    /* XECHO */
  1720. #endif /* NOFRILLS */
  1721.  
  1722. #ifndef NOSPL
  1723.     { "xif",         XXIFX, CM_INV },    /* Extended IF command (obsolete) */
  1724. #else
  1725.     { "xif",         XXNOTAV, CM_INV },
  1726. #endif /* NOSPL */
  1727.  
  1728. #ifndef NOCSETS
  1729.     { "xlate",       XXXLA, CM_INV },    /* Synonym for TRANSLATE */
  1730. #else
  1731.     { "xlate",       XXNOTAV, CM_INV },
  1732. #endif /* NOCSETS */
  1733.  
  1734. #ifndef NOXMIT
  1735.     { "xmit",        XXTRA, CM_INV },    /* Synonym for TRANSMIT */
  1736. #else
  1737.     { "xmit",        XXNOTAV, CM_INV },
  1738. #endif /* NOXMIT */
  1739.  
  1740. #ifndef OS2
  1741. #ifndef NOJC
  1742.     { "z",           XXSUS, CM_INV|CM_PSH }, /* Synonym for SUSPEND */
  1743. #else
  1744.     { "z",           XXNOTAV, CM_INV|CM_PSH },
  1745. #endif /* NOJC */
  1746. #endif /* OS2 */
  1747.  
  1748. #ifndef NOSPL
  1749.     { "{",           XXMACRO, CM_INV },    /* Immediate macro */
  1750. #endif /* NOSPL */
  1751.     { "", 0, 0 }
  1752. };
  1753. int ncmd = (sizeof(cmdtab) / sizeof(struct keytab)) - 1;
  1754.  
  1755. /* NOTE: Tokens must also be entered above into cmdtab[]. */
  1756.  
  1757. char toktab[] = {
  1758. #ifndef NOPUSH
  1759.     '!',                /* Shell escape */
  1760. #endif /* NOPUSH */
  1761.     '#',                /* Comment */
  1762. #ifndef NOSPL
  1763.     '(',                /* S-Expression */
  1764.     '.',                /* Assignment */
  1765. #endif /* NOSPL */
  1766.     ';',                /* Comment */
  1767. #ifndef NOSPL
  1768.     ':',                /* Label */
  1769. #endif /* NOSPL */
  1770. #ifndef NOPUSH
  1771. #ifdef CK_REDIR
  1772.     '<',                /* REDIRECT */
  1773. #endif /* CK_REDIR */
  1774.     '@',                /* DCL escape */
  1775. #endif /* NOPUSH */
  1776. #ifdef CK_RECALL
  1777.     '^',                /* Command recall */
  1778. #endif /* CK_RECALL */
  1779. #ifndef NOSPL
  1780.     '{',                /* Immediate macro */
  1781. #endif /* NOSPL */
  1782.     '\0'                /* End of this string */
  1783. };
  1784. int xxdot = 0;                /* Used with "." token */
  1785.  
  1786. struct keytab yesno[] = {        /* Yes/No keyword table */
  1787.     { "no",    0, 0 },
  1788.     { "ok",    1, 0 },
  1789.     { "yes",   1, 0 }
  1790. };
  1791. int nyesno = (sizeof(yesno) / sizeof(struct keytab));
  1792.  
  1793. /* Save keyword table */
  1794.  
  1795. struct keytab savtab[] = {
  1796. #ifdef OS2
  1797.     { "command",  XSCMD, 0 },
  1798. #else
  1799. #ifdef CK_RECALL
  1800.     { "command",  XSCMD, 0 },
  1801. #endif /* CK_RECALL */
  1802. #endif /* OS2 */
  1803. #ifndef NOSETKEY
  1804.     { "keymap",   XSKEY, 0 },
  1805. #endif /* NOSETKEY */
  1806. #ifdef OS2
  1807.     { "terminal", XSTERM, 0 },
  1808. #endif /* OS2 */
  1809.     { "", 0, 0 }
  1810. };
  1811. int nsav = (sizeof(savtab) / sizeof(struct keytab)) - 1;
  1812.  
  1813. /* Parameter keyword table */
  1814.  
  1815. struct keytab prmtab[] = {
  1816.     { "alarm",            XYALRM,  0 },
  1817. #ifdef COMMENT                /* SET ANSWER not implemented yet */
  1818. #ifndef NODIAL
  1819.     { "answer",           XYANSWER,0 },
  1820. #endif /* NODIAL */
  1821. #endif /* COMMENT */
  1822.     { "ask-timer",        XYTIMER, 0 },
  1823. #ifndef NOXFER
  1824.     { "attributes",       XYATTR,  0 },
  1825. #endif /* NOXFER */
  1826. #ifdef CK_AUTHENTICATION
  1827.     { "authentication",   XYAUTH,  0 },
  1828. #else  /* CK_AUTHENTICATION */
  1829. #ifdef CK_SSL
  1830.     { "authentication",   XYAUTH,  0 },
  1831. #endif /* CK_SSL */
  1832. #endif /* CK_AUTHENTICATION */
  1833.     { "b",          XYBACK,  CM_INV|CM_ABR|CM_PSH },
  1834.     { "ba",          XYBACK,  CM_INV|CM_ABR|CM_PSH },
  1835. #ifdef VMS
  1836.     { "background",       XYBACK,  CM_INV|CM_PSH },
  1837.     { "batch",            XYBACK,  CM_PSH },
  1838. #else
  1839.     { "background",       XYBACK,  CM_PSH },
  1840.     { "batch",            XYBACK,  CM_INV|CM_PSH },
  1841. #endif /* VMS */
  1842. #ifndef NOLOCAL
  1843.     { "baud",              XYSPEE,  CM_INV|CM_LOC },
  1844. #endif /* NOLOCAL */
  1845.     { "bell",             XYBELL,  0 },
  1846. #ifndef NOXFER
  1847.     { "block-check",        XYCHKT,  0 },
  1848. #endif /* NOXFER */
  1849. #ifdef OS2
  1850. #ifdef BPRINT
  1851.     { "bprinter",         XYBDCP,  CM_INV },
  1852. #endif /* BPRINT */
  1853. #endif /*  OS2 */
  1854. #ifdef BROWSER
  1855.     { "browser",          XYBROWSE,CM_PSH|CM_LOC },
  1856. #endif /* BROWSER */
  1857. #ifndef NOXFER
  1858. #ifdef DYNAMIC
  1859.     { "buffers",          XYBUF,   0 },
  1860. #endif /* DYNAMIC */
  1861. #endif /* NOXFER */
  1862. #ifndef NOLOCAL
  1863. #ifndef MAC
  1864.     { "carrier-watch",    XYCARR,  CM_LOC },
  1865. #endif /* MAC */
  1866. #endif /* NOLOCAL */
  1867. #ifndef NOSPL
  1868.     { "case",             XYCASE,  0 },
  1869. #endif /* NOSPL */
  1870.     { "cd",               XYCD,    0 },
  1871. #ifndef NOXFER
  1872.     { "cl",               XYCLEAR, CM_INV|CM_ABR },
  1873.     { "cle",              XYCLEAR, CM_INV|CM_ABR },
  1874.     { "clea",             XYCLEAR, CM_INV|CM_ABR },
  1875.     { "clear",            XYCLEAR, CM_INV|CM_ABR },
  1876.     { "clear-channel",    XYCLEAR, 0 },
  1877.     { "clearchannel",     XYCLEAR, CM_INV },
  1878. #endif /* NOXFER */
  1879. #ifndef NOLOCAL
  1880.     { "close-on-disconnect", XYDISC, CM_INV|CM_LOC },
  1881. #endif /* NOLOCAL */
  1882.     { "cmd",              XYCMD,   CM_INV },
  1883.     { "command",          XYCMD,   0 },
  1884. #ifdef CK_SPEED
  1885.     { "con",              XYQCTL,  CM_INV|CM_ABR },
  1886. #endif /* CK_SPEED */
  1887.     { "console",          XYCMD,   CM_INV },
  1888. #ifdef CK_SPEED
  1889.     { "control-character",XYQCTL,  0 },
  1890. #endif /* CK_SPEED */
  1891. #ifndef NOSPL
  1892.     { "count",            XYCOUN,  0 },
  1893. #endif /* NOSPL */
  1894. #ifndef NOXFER
  1895.     { "d",          XYDELA,  CM_INV|CM_ABR },
  1896.     { "de",          XYDELA,  CM_INV|CM_ABR },
  1897. #endif /* NOXFER */
  1898.     { "debug",            XYDEBU,  0 },
  1899. #ifdef VMS
  1900.     { "default",          XYDFLT,  0 },
  1901. #else
  1902. #ifndef MAC
  1903.     { "default",          XYDFLT,  CM_INV },
  1904. #endif /* MAC */
  1905. #endif /* VMS */
  1906. #ifndef NOXFER
  1907.     { "delay",              XYDELA,  0 },
  1908.     { "destination",      XYDEST,  0 },
  1909. #endif /* NOXFER */
  1910. #ifndef NODIAL
  1911.     { "di",          XYDIAL,  CM_INV|CM_ABR|CM_LOC },
  1912.     { "dia",          XYDIAL,  CM_INV|CM_ABR|CM_LOC },
  1913.     { "dial",             XYDIAL,  CM_LOC },
  1914. #endif /* NODIAL */
  1915. #ifdef OS2
  1916.     { "dialer",          XYDLR,   CM_INV },
  1917. #endif /* OS2 */
  1918. #ifndef NOLOCAL
  1919.     { "disconnect",       XYDISC,  CM_LOC },
  1920.     { "duplex",              XYDUPL,  CM_LOC },
  1921. #endif /* NOLOCAL */
  1922. #ifndef NOPUSH
  1923. #ifndef NOFRILLS
  1924.     { "editor",           XYEDIT,  CM_PSH },
  1925. #endif /*  NOFRILLS */
  1926. #endif /* NOPUSH */
  1927. #ifdef CK_CTRLZ
  1928.     { "eof",              XYEOF,   CM_INV },
  1929. #endif /* CK_CTRLZ */
  1930. #ifndef NOLOCAL
  1931.     { "escape-character", XYESC,   CM_LOC },
  1932. #endif /* NOLOCAL */
  1933. #ifndef NOSPL
  1934.     { "evaluate",         XYEVAL,  CM_INV },
  1935. #endif /* NOSPL */
  1936.     { "exit",          XYEXIT,  0 },
  1937. #ifndef NOXFER
  1938.     { "f-ack-bug",        XYFACKB, CM_INV },
  1939.     { "f-ack-path",       XYFACKP, CM_INV },
  1940. #endif /* NOXFER */
  1941.     { "file",             XYFILE,  0 },
  1942.     { "fl",                 XYFLOW,  CM_INV|CM_ABR },
  1943. #ifndef NOSPL
  1944.     { "flag",             XYFLAG,  0 },
  1945. #endif /* NOSPL */
  1946. #ifdef TCPSOCKET
  1947. #ifndef SYSFTP
  1948. #ifndef NOFTP
  1949.     { "ft",                 XYFTPX,  CM_INV|CM_ABR },
  1950.     { "ftp",                XYFTPX,  0 },
  1951. #endif /* NOFTP */
  1952. #endif /* SYSFTP */
  1953. #endif /* TCPSOCKET */
  1954. #ifdef BROWSER
  1955.     { "ftp-client",       XYFTP,   CM_PSH },
  1956. #endif /* BROWSER */
  1957.     { "flow-control",       XYFLOW,  0 },
  1958. #ifndef NOSPL
  1959.     { "function",         XYFUNC,  0 },
  1960. #endif /* NOSPL */
  1961. #ifdef NEWFTP
  1962.     { "get-put-remote",   XYGPR,   0 },
  1963. #endif /* NEWFTP */
  1964. #ifdef KUI
  1965.     { "gui",              XYGUI,   0 },
  1966. #endif /* KUI */
  1967.     { "handshake",          XYHAND,  0 },
  1968.     { "hints",            XYHINTS, 0 },
  1969. #ifdef NETCONN
  1970.     { "host",             XYHOST,  CM_LOC },
  1971. #endif /* NETCONN */
  1972. #ifndef NOSPL
  1973.     { "i",          XYINPU,  CM_INV|CM_ABR },
  1974. #endif /* NOSPL */
  1975. #ifdef IKSD
  1976.     { "iks",              XYIKS,   0 },
  1977. #else
  1978.     { "iks",              XYIKS,   CM_INV },
  1979. #endif /* IKSD */
  1980. #ifndef NOSPL
  1981.     { "in",          XYINPU,  CM_INV|CM_ABR },
  1982. #endif /* NOSPL */
  1983. #ifndef NOXFER
  1984.     { "incomplete",         XYIFD,   CM_INV },
  1985. #endif /* NOXFER */
  1986. #ifndef NOSPL
  1987.     { "input",            XYINPU,  0 },
  1988. #endif /* NOSPL */
  1989. #ifndef NOSETKEY
  1990.     { "key",          XYKEY,   0 },
  1991. #endif /* NOSETKEY */
  1992.     { "l",                XYLINE,  CM_INV|CM_ABR },
  1993. #ifndef NOCSETS
  1994.     { "language",         XYLANG,  0 },
  1995. #endif /* NOCSETS */
  1996. #ifndef NOLOCAL
  1997.     { "line",             XYLINE,  CM_LOC },
  1998.     { "local-echo",      XYLCLE,  CM_INV|CM_LOC },
  1999. #endif /* NOLOCAL */
  2000. #ifdef LOCUS
  2001.     { "locus",            XYLOCUS, 0 },
  2002. #endif /* LOCUS */
  2003. #ifndef NOSPL
  2004.     { "login",          XYLOGIN, CM_LOC },
  2005. #endif /* NOSPL */
  2006. #ifndef NOSPL
  2007.     { "macro",            XYMACR,  0 },
  2008. #endif /* NOSPL */
  2009.     { "match",            XYMATCH, 0 },
  2010. #ifdef COMMENT
  2011. #ifdef VMS
  2012.     { "messages",         XYMSGS,  0 },
  2013. #endif /* VMS */
  2014. #endif /* COMMENT */
  2015. #ifndef NODIAL
  2016.     { "modem",          XYMODM,  CM_LOC },
  2017. #endif /* NODIAL */
  2018. #ifndef NOLOCAL
  2019. #ifdef OS2MOUSE
  2020.     { "mouse",          XYMOUSE, 0 },
  2021. #endif /* OS2MOUSE */
  2022. #endif /* NOLOCAL */
  2023. #ifdef OS2
  2024.     { "mskermit",         XYMSK,   0 },
  2025. #endif /* OS2 */
  2026. #ifdef NETCONN
  2027.     { "network",          XYNET,   CM_LOC },
  2028. #endif /* NETCONN */
  2029. #ifndef NOSPL
  2030.     { "output",           XYOUTP,  0 },
  2031. #endif /* NOSPL */
  2032.     { "options",          XYOPTS,  0 },
  2033.     { "pause",            XYSLEEP, CM_INV },
  2034. #ifdef ANYX25
  2035. #ifndef IBMX25
  2036.     { "pad",              XYPAD,   CM_LOC },
  2037. #endif /* IBMX25 */
  2038. #endif /* ANYX25 */
  2039.     { "parity",              XYPARI,  0 },
  2040. #ifndef NOLOCAL
  2041. #ifdef OS2
  2042.     { "port",             XYLINE,  CM_LOC },
  2043. #else
  2044.     { "port",             XYLINE,  CM_INV|CM_LOC },
  2045. #endif /* OS2 */
  2046. #endif /* NOLOCAL */
  2047. #ifndef NOFRILLS
  2048.     { "pr",                 XYPROM,  CM_INV|CM_ABR },
  2049.     { "printer",          XYPRTR,  0 },
  2050. #endif /* NOFRILLS */
  2051. #ifdef OS2
  2052.     { "priority",         XYPRTY,  0 },
  2053. #endif /* OS2 */
  2054. #ifdef CK_SPEED
  2055.     { "prefixing",        XYPREFIX, 0 },
  2056. #endif /* CK_SPEED */
  2057. #ifndef NOFRILLS
  2058.     { "prompt",              XYPROM,  0 },
  2059. #endif /* NOFRILLS */
  2060. #ifndef NOXFER
  2061.     { "protocol",      XYPROTO, 0 },
  2062. #endif /* NOXFER */
  2063.     { "q",          XYQUIE,  CM_INV|CM_ABR },
  2064. #ifndef NOXFER
  2065.     { "q8flag",           XYQ8FLG, CM_INV },
  2066. #endif /* NOXFER */
  2067. #ifdef QNX
  2068.     { "qnx-port-lock",    XYQNXPL, 0 },
  2069. #else
  2070.     { "qnx-port-lock",    XYQNXPL, CM_INV },
  2071. #endif /* QNX */
  2072.     { "quiet",          XYQUIE,  0 },
  2073. #ifndef NOXFER
  2074.     { "rec",              XYRECV,  CM_INV|CM_ABR },
  2075.     { "receive",          XYRECV,  0 },
  2076.     { "recv",             XYRECV,  CM_INV },
  2077. #endif /* NOXFER */
  2078.     { "reliable",         XYRELY,  0 },
  2079. #ifndef NOXFER
  2080.     { "repeat",           XYREPT,  0 },
  2081.     { "retry-limit",      XYRETR,  0 },
  2082. #endif /* NOXFER */
  2083. #ifdef CKROOT
  2084.     { "root",             XYROOT,  0 },
  2085. #endif /* CKROOT */
  2086. #ifndef NOSCRIPT
  2087.     { "script",          XYSCRI,  CM_LOC },
  2088. #endif /* NOSCRIPT */
  2089. #ifndef NOXFER
  2090.     { "send",             XYSEND,  0 },
  2091. #ifndef NOLOCAL
  2092. #ifndef NOSERVER
  2093.     { "ser",              XYSERV,  CM_INV|CM_ABR },
  2094. #endif /* NOSERVER */
  2095. #endif /* NOXFER */
  2096.     { "serial",           XYSERIAL,CM_LOC },
  2097. #endif /* NOLOCAL */
  2098. #ifndef NOSERVER
  2099.     { "server",           XYSERV,  0 },
  2100. #endif /* NOSERVER */
  2101. #ifdef SESLIMIT
  2102. #ifndef NOLOCAL
  2103.     { "session-l",        XYSESS,  CM_INV|CM_ABR },
  2104. #endif /* NOLOCAL */
  2105.     { "session-limit",    XYLIMIT, CM_INV|CM_LOC }, /* Session Limit */
  2106. #endif /* SESLIMIT */
  2107.  
  2108. #ifndef NOLOCAL
  2109.     { "session-log",      XYSESS,  CM_LOC },
  2110. #endif /* NOLOCAL */
  2111.  
  2112. #ifndef NOSPL
  2113. #ifndef NOSEXP
  2114.     { "sexpression",      XYSEXP,  CM_INV },
  2115. #endif /* NOSEXP */
  2116. #endif /* NOSPL */
  2117.  
  2118.     { "sleep",            XYSLEEP, 0 },
  2119.  
  2120. #ifndef NOLOCAL
  2121.     { "speed",              XYSPEE,  CM_LOC },
  2122. #endif /* NOLOCAL */
  2123.  
  2124. #ifdef ANYSSH
  2125.     { "ssh",              XYSSH,   0 },
  2126. #endif /* ANYSSH */
  2127.  
  2128. #ifndef NOSPL
  2129.     { "startup-file",     XYSTARTUP, CM_INV },
  2130. #endif /* NOSPL */
  2131.  
  2132. #ifndef NOLOCAL
  2133. #ifdef HWPARITY
  2134.     { "stop-bits",        XYSTOP, CM_LOC },
  2135. #else
  2136. #ifdef TN_COMPORT
  2137.     { "stop-bits",        XYSTOP, CM_LOC },
  2138. #endif /* TN_COMPORT */
  2139. #endif /* HWPARITY */
  2140. #endif /* NOLOCAL */
  2141.  
  2142. #ifndef NOXFER
  2143. #ifdef STREAMING
  2144.     { "streaming",        XYSTREAM, 0 },
  2145. #endif /* STREAMING */
  2146. #endif /* NOXFER */
  2147.  
  2148. #ifndef NOJC
  2149.     { "suspend",          XYSUSP,  CM_PSH },
  2150. #endif /* NOJC */
  2151. #ifdef CKSYSLOG
  2152.     { "syslog",           XYSYSL,  CM_INV },
  2153. #endif /* CKSYSLOG */
  2154.     { "take",             XYTAKE,  0 },
  2155.  
  2156. #ifdef CK_TAPI
  2157.     { "tapi",             XYTAPI,  CM_LOC },
  2158. #endif /* CK_TAPI */
  2159.  
  2160. #ifndef NOTCPOPTS
  2161. #ifdef TCPSOCKET
  2162.     { "tcp",              XYTCP,   CM_LOC },
  2163. #endif /* TCPSOCKET */
  2164. #endif /* NOTCPOPTS */
  2165.  
  2166. #ifdef TNCODE
  2167.     { "tel",              XYTEL,   CM_INV|CM_ABR },
  2168.     { "telnet",           XYTEL,   0 },
  2169.     { "telopt",           XYTELOP, 0 },
  2170. #endif /* TNCODE */
  2171.  
  2172. #ifndef NOSPL
  2173.     { "temp-directory",   XYTMPDIR,0 },
  2174. #endif /* NOSPL */
  2175.  
  2176. #ifndef NOLOCAL
  2177.     { "terminal",         XYTERM,  CM_LOC },
  2178. #endif /* NOLOCAL */
  2179.  
  2180. #ifdef OS2
  2181.     { "title",          XYTITLE, CM_LOC },
  2182. #endif /* OS2 */
  2183. #ifdef TLOG
  2184.     { "transaction-log",  XYTLOG,  0 },
  2185. #endif /* TLOG */
  2186. #ifndef NOXFER
  2187.     { "transfer",         XYXFER,  0 },
  2188. #endif /* NOXFER */
  2189. #ifndef NOXMIT
  2190.     { "transmit",         XYXMIT,  0 },
  2191. #endif /* NOXMIT */
  2192. #ifndef NOXFER
  2193. #ifndef NOCSETS
  2194.     { "unknown-char-set", XYUNCS,  0 },
  2195. #endif /* NOCSETS */
  2196. #endif /* NOXFER */
  2197.     { "wait",             XYSLEEP, CM_INV },
  2198. #ifndef NOPUSH
  2199. #ifdef UNIX
  2200.     { "wildcard-expansion", XYWILD, 0 },
  2201. #endif /* UNIX */
  2202. #endif /* NOPUSH */
  2203. #ifdef NT
  2204.     { "w",                XYWIND,  CM_INV|CM_ABR },
  2205.     { "wi",               XYWIND,  CM_INV|CM_ABR },
  2206.     { "win",              XYWIND,  CM_INV|CM_ABR },
  2207. #endif /* NT */
  2208.     { "window-size",      XYWIND,  0 },
  2209. #ifdef NT
  2210.     { "win95",            XYWIN95, 0 },
  2211. #endif /* NT */
  2212. #ifdef ANYX25
  2213.     { "x.25",             XYX25,   CM_LOC },
  2214.     { "x25",              XYX25,   CM_INV|CM_LOC },
  2215. #endif /* ANYX25 */
  2216.     { "xfer",             XYXFER,  CM_INV },
  2217. #ifndef NOXMIT
  2218.     { "xmit",             XYXMIT,  CM_INV },
  2219. #endif /* NOXMIT */
  2220.     { "", 0, 0 }
  2221. };
  2222. int nprm = (sizeof(prmtab) / sizeof(struct keytab)) - 1; /* How many */
  2223.  
  2224. struct keytab scntab[] = {        /* Screen commands */
  2225.     { "clear",   SCN_CLR, 0 },
  2226.     { "cleol",   SCN_CLE, 0 },
  2227.     { "move-to", SCN_MOV, 0 }
  2228. };
  2229. int nscntab = (sizeof(scntab) / sizeof(struct keytab)); /* How many */
  2230.  
  2231. #ifdef ANYSSH                /* SSH command table */
  2232. #ifdef SSHBUILTIN
  2233. int    ssh_pf_lcl_n = 0,
  2234.        ssh_pf_rmt_n = 0;
  2235. struct ssh_pf ssh_pf_lcl[32] = { 0, NULL, 0 }; /* SSH Port Forwarding */
  2236. struct ssh_pf ssh_pf_rmt[32] = { 0, NULL, 0 }; /* structs... */
  2237. extern char * ssh_hst, * ssh_cmd, * ssh_prt;
  2238. extern int    ssh_ver,   ssh_xfw;
  2239. char * ssh_tmpuid = NULL, *ssh_tmpcmd = NULL, *ssh_tmpport = NULL,
  2240.      * ssh_tmpstr = NULL;
  2241.  
  2242. int
  2243.  sshk_type = SSHKT_2D,            /* SSH KEY CREATE /TYPE:x */
  2244.  sshk_bits = 1024,            /* SSH KEY CREATE /BITS:n */
  2245.  sshk_din  = SKDF_OSSH,            /* SSH KEY DISPLAY /IN-FORMAT: */
  2246.  sshk_dout = SKDF_OSSH;            /* SSH KEY DISPLAY /OUT-FORMAT: */
  2247.  
  2248. char
  2249.  * sshk1_comment = NULL,        /* SSH V1 COMMENT */
  2250.  * sshkp_old = NULL,            /* Old key passphrase */
  2251.  * sshkp_new = NULL,            /* New key passphrase */
  2252.  * sshkc_pass = NULL,            /* KEY CREATE /PASS:xxx */
  2253.  * sshkc_comm = NULL,            /* KEY CREATE /V1-RSA-COMMENT:xxx */
  2254.  * sshd_file = NULL,            /* DISPLAY file */
  2255.  * sshk_file = NULL;            /* SSH CREATE KEY file */
  2256.  
  2257. static struct keytab sshclr[] = {
  2258.     { "local-port-forward",  SSHC_LPF, 0 },
  2259.     { "remote-port-forward", SSHC_RPF, 0 },
  2260.     { "", 0, 0 }
  2261. };
  2262. static int nsshclr = (sizeof(sshclr) / sizeof(struct keytab)) - 1;
  2263.  
  2264. struct keytab sshopnsw[] = {
  2265.     { "/command",        SSHSW_CMD, CM_ARG },
  2266.     { "/password",       SSHSW_PWD, CM_ARG },
  2267.     { "/subsystem",      SSHSW_SUB, CM_ARG },
  2268.     { "/user",           SSHSW_USR, CM_ARG },
  2269.     { "/version",        SSHSW_VER, CM_ARG },
  2270.     { "/x11-forwarding", SSHSW_X11, CM_ARG },
  2271.     { "", 0, 0 }
  2272. };
  2273. int nsshopnsw = (sizeof(sshopnsw) / sizeof(struct keytab)) - 1;
  2274.  
  2275. static struct keytab sshkwtab[] = {
  2276.     { "add",                 XSSH_ADD, 0 },
  2277.     { "agent",               XSSH_AGT, 0 },
  2278.     { "clear",               XSSH_CLR, 0 },
  2279.     { "forward-local-port",  XSSH_FLP, CM_INV },
  2280.     { "forward-remote-port", XSSH_FRP, CM_INV },
  2281.     { "key",                 XSSH_KEY, 0 },
  2282.     { "open",                XSSH_OPN, 0 },
  2283.     { "v2",                  XSSH_V2,  0 },
  2284.     { "", 0, 0 }
  2285. };
  2286. static int nsshcmd = (sizeof(sshkwtab) / sizeof(struct keytab)) - 1;
  2287.  
  2288. static struct keytab ssh2tab[] = {
  2289.     { "rekey", XSSH2_RKE, 0 },
  2290.     { "", 0, 0 }
  2291. };
  2292. static int nssh2tab = (sizeof(ssh2tab) / sizeof(struct keytab));
  2293.  
  2294. static struct keytab addfwd[] = {    /* SET SSH ADD command table */
  2295.     { "local-port-forward",  SSHF_LCL, 0 },
  2296.     { "remote-port-forward", SSHF_RMT, 0 },
  2297.     { "", 0, 0 }
  2298. };
  2299. static int naddfwd = (sizeof(addfwd) / sizeof(struct keytab)) - 1;
  2300.  
  2301. static struct keytab sshagent[] = {    /* SET SSH AGENT command table */
  2302.     { "add",    SSHA_ADD, 0 },
  2303.     { "delete", SSHA_DEL, 0 },
  2304.     { "list",   SSHA_LST, 0 },
  2305.     { "", 0, 0 }
  2306. };
  2307. static int nsshagent = (sizeof(sshagent) / sizeof(struct keytab)) - 1;
  2308.  
  2309. static struct keytab sshagtsw[] = {    /* SET SSH AGENT LIST switch table */
  2310.     { "/fingerprint", SSHASW_FP, 0 },
  2311.     { "", 0, 0 }
  2312. };
  2313. static int nsshagtsw = (sizeof(sshagtsw) / sizeof(struct keytab)) - 1;
  2314.  
  2315. static struct keytab sshkey[] = {    /* SET SSH KEY command table */
  2316.     { "change-passphrase",  SSHK_PASS, 0 },
  2317.     { "create",             SSHK_CREA, 0 },
  2318.     { "display",            SSHK_DISP, 0 },
  2319.     { "v1",                 SSHK_V1,   0 },
  2320.     { "", 0, 0 }
  2321. };
  2322. static int nsshkey = (sizeof(sshkey) / sizeof(struct keytab)) - 1;
  2323.  
  2324. static struct keytab sshkv1[] = {    /* SET SSH KEY V1 command table */
  2325.     { "set-comment",  1, 0 }
  2326. };
  2327.  
  2328. static struct keytab sshkpsw[] = {    /* SET SSH KEY PASSPHRASE table */
  2329.     { "/new-passphrase",  2, CM_ARG },
  2330.     { "/old-passphrase",  1, CM_ARG }
  2331. };
  2332.  
  2333. static struct keytab sshkcrea[] = {    /* SSH KEY CREATE table */
  2334.     { "/bits",           SSHKC_BI, CM_ARG },
  2335.     { "/passphrase",     SSHKC_PP, CM_ARG },
  2336.     { "/type",           SSHKC_TY, CM_ARG },
  2337.     { "/v1-rsa-comment", SSHKC_1R, CM_ARG }
  2338. };
  2339. static int nsshkcrea = (sizeof(sshkcrea) / sizeof(struct keytab));
  2340.  
  2341. static struct keytab sshkcty[] = {    /* SSH KEY CREATE /TYPE:xxx */
  2342.     { "srp",    SSHKT_SRP, 0 },
  2343.     { "v1-rsa", SSHKT_1R, 0 },
  2344.     { "v2-dsa", SSHKT_2D, 0 },
  2345.     { "v2-rsa", SSHKT_2R, 0 }
  2346. };
  2347. static int nsshkcty = (sizeof(sshkcty) / sizeof(struct keytab));
  2348.  
  2349. static struct keytab sshdswi[] = {    /* SET SSH KEY DISPLAY /switches */
  2350.     { "/format", SSHKD_OUT, CM_ARG }
  2351. };
  2352. static int nsshdswi = (sizeof(sshdswi) / sizeof(struct keytab));
  2353.  
  2354. #ifdef COMMENT
  2355. static struct keytab sshdifmt[] = {    /* SSH KEY DISPLAY /IN-FORMAT: */
  2356.     { "openssh", SKDF_OSSH, 0 },
  2357.     { "ssh.com", SKDF_SSHC, 0 }
  2358. };
  2359. static int nsshdifmt = (sizeof(sshdifmt) / sizeof(struct keytab));
  2360. #endif /* COMMENT */
  2361.  
  2362. static struct keytab sshdofmt[] = {    /* SSH KEY DISPLAY /IN-FORMAT: */
  2363.     { "fingerprint", SKDF_FING, 0 },
  2364.     { "ietf",        SKDF_IETF, 0 },
  2365.     { "openssh",     SKDF_OSSH, 0 },
  2366.     { "ssh.com",     SKDF_SSHC, 0 }
  2367. };
  2368. static int nsshdofmt = (sizeof(sshdofmt) / sizeof(struct keytab));
  2369. #endif /* SSHBUILTIN */
  2370. #endif /* ANYSSH */
  2371.  
  2372. #ifdef NETCONN
  2373. struct keytab netkey[] = {        /* SET NETWORK table */
  2374.     { "directory", XYNET_D,  0 },
  2375.     { "type",      XYNET_T,  0 }
  2376. };
  2377. int nnetkey = (sizeof(netkey) / sizeof(struct keytab));
  2378.  
  2379. struct keytab netcmd[] = {
  2380. /*
  2381.   These are the network types.
  2382. */
  2383. #ifdef NETCMD
  2384.     { "command",       NET_CMD,  CM_INV }, /* Command */
  2385. #endif /* NETCMD */
  2386.  
  2387. #ifdef DECNET                /* DECnet / PATHWORKS */
  2388.     { "decnet",        NET_DEC,  0 },
  2389. #endif /* DECNET */
  2390.  
  2391. #ifdef NETDLL
  2392.     { "dll",           NET_DLL,  CM_INV }, /* DLL to be loaded */
  2393. #endif /* NETDLL */
  2394.  
  2395. #ifdef NETFILE
  2396.     { "file",           NET_FILE, CM_INV }, /* FILE (real crude) */
  2397. #endif /* NETFILE */
  2398.  
  2399. #ifdef NPIPE                /* Named Pipes */
  2400.     { "named-pipe",     NET_PIPE,  0 },
  2401. #endif /* NPIPE */
  2402.  
  2403. #ifdef CK_NETBIOS
  2404.     { "netbios",        NET_BIOS,  0 },    /* NETBIOS */
  2405. #endif /* CK_NETBIOS */
  2406.  
  2407. #ifdef DECNET                /* DECnet / PATHWORKS (alias) */
  2408.     { "pathworks",     NET_DEC,  CM_INV },
  2409. #endif /* DECNET */
  2410.  
  2411. #ifdef NETCMD
  2412.     { "pipe",          NET_CMD,  0 },    /* Pipe */
  2413. #endif /* NETCMD */
  2414.  
  2415. #ifdef NETPTY
  2416.     { "pseudoterminal",NET_PTY, 0 },    /* Pseudoterminal */
  2417. #endif /* NETPTY */
  2418.  
  2419. #ifdef NETPTY
  2420.     { "pty",          NET_PTY,  CM_INV }, /* Inv syn for pseudoterm */
  2421. #endif /* NETPTY */
  2422.  
  2423. #ifdef SSHBUILTIN
  2424.     { "ssh",          NET_SSH,  0 },
  2425. #endif /* SSHBUILTIN */
  2426.  
  2427. #ifdef SUPERLAT
  2428.     { "superlat",     NET_SLAT, 0 },    /* Meridian Technologies' SuperLAT */
  2429. #endif /* SUPERLAT */
  2430.  
  2431. #ifdef TCPSOCKET            /* TCP/IP sockets library */
  2432.     { "tcp/ip",       NET_TCPB, 0 },
  2433. #endif /* TCPSOCKET */
  2434. #ifdef SUPERLAT
  2435.     { "tes32",        NET_SLAT, 0 },    /* Emulux TES32 */
  2436. #endif /* SUPERLAT */
  2437. #ifdef ANYX25                /* X.25 */
  2438. #ifdef SUNX25
  2439.     { "x",            NET_SX25, CM_INV|CM_ABR },
  2440.     { "x.25",         NET_SX25, 0 },
  2441.     { "x25",          NET_SX25, CM_INV },
  2442. #else
  2443. #ifdef STRATUSX25
  2444.     { "x",            NET_VX25, CM_INV|CM_ABR },
  2445.     { "x.25",         NET_VX25, 0 },
  2446.     { "x25",          NET_VX25, CM_INV },
  2447. #endif /* STRATUSX25 */
  2448. #endif /* SUNX25 */
  2449. #ifdef IBMX25
  2450.     { "x",            NET_IX25, CM_INV|CM_ABR },
  2451.     { "x.25",         NET_IX25, CM_INV },
  2452.     { "x25",          NET_IX25, CM_INV },
  2453. #endif /* IBMX25 */
  2454. #ifdef HPX25
  2455.     { "x",            NET_IX25, CM_INV|CM_ABR },
  2456.     { "x.25",         NET_IX25, 0 },
  2457.     { "x25",          NET_IX25, CM_INV },
  2458. #endif /* HPX25 */
  2459. #endif /* ANYX25 */
  2460.     { "", 0, 0 }
  2461. };
  2462. int nnets = (sizeof(netcmd) / sizeof(struct keytab));
  2463.  
  2464. #ifndef NOTCPOPTS
  2465. #ifdef TCPSOCKET
  2466.  
  2467. /* TCP options */
  2468.  
  2469. struct keytab tcpopt[] = {
  2470.     { "address",   XYTCP_ADDRESS, 0 },
  2471. #ifdef CK_DNS_SRV
  2472.     { "dns-service-records", XYTCP_DNS_SRV, 0 },
  2473. #endif /* CK_DNS_SRV */
  2474. #ifdef SO_DONTROUTE
  2475.     { "dontroute",   XYTCP_DONTROUTE, 0 },
  2476. #endif /* SO_DONTROUTE */
  2477. #ifndef NOHTTP
  2478.     { "http-proxy", XYTCP_HTTP_PROXY, 0 },
  2479. #endif /* NOHTTP */
  2480. #ifdef SO_KEEPALIVE
  2481.     { "keepalive", XYTCP_KEEPALIVE, 0 },
  2482. #endif /* SO_KEEPALIVE */
  2483. #ifdef SO_LINGER
  2484.     { "linger", XYTCP_LINGER, 0 },
  2485. #endif /* SO_LINGER */
  2486. #ifdef TCP_NODELAY
  2487.     { "nagle",  XYTCP_NAGLE,    CM_INV },
  2488.     { "nodelay", XYTCP_NODELAY, 0 },
  2489. #endif /* TCP_NODELAY */
  2490.     { "reverse-dns-lookup", XYTCP_RDNS, 0 },
  2491. #ifdef SO_RCVBUF
  2492.     { "recvbuf", XYTCP_RECVBUF, 0 },
  2493. #endif /* SO_RCVBUF */
  2494. #ifdef SO_SNDBUF
  2495.     { "sendbuf", XYTCP_SENDBUF, 0 },
  2496. #endif /* SO_SNDBUF */
  2497. #ifdef NT
  2498. #ifdef CK_SOCKS
  2499.     { "socks-server", XYTCP_SOCKS_SVR, 0 },
  2500. #endif /* CK_SOCKS */
  2501. #endif /* NT */
  2502. #ifdef VMS
  2503. #ifdef DEC_TCPIP
  2504.     { "ucx-port-bug", XYTCP_UCX, 0 },
  2505. #endif /* DEC_TCPIP */
  2506. #endif /* VMS */
  2507.     { "",0,0 }
  2508. };
  2509. int ntcpopt = (sizeof(tcpopt) / sizeof(struct keytab));
  2510. #endif /* TCPSOCKET */
  2511. #endif /* NOTCPOPTS */
  2512. #endif /* NETCONN */
  2513.  
  2514. #ifdef OS2
  2515. /* K95 Manual Chapter Table -- Keep these two tables in sync! */
  2516.  
  2517. static char * linktbl[] = {        /* Internal links in k95.htm */
  2518.     "#top",                /* 00 */
  2519.     "#what",                /* 01 */
  2520.     "#install",                /* 02 */
  2521.     "#start",                /* 03 */
  2522.     "#dialer",                /* 04 */
  2523.     "#entries",                /* 05 */
  2524.     "#command",                /* 06 */
  2525.     "#terminal",            /* 07 */
  2526.     "#transfer",            /* 08 */
  2527.     "#hostmode"                /* 09 */
  2528. };
  2529.  
  2530. static struct keytab chaptbl[] = {
  2531.     { "Command-Screen",     6, 0 },
  2532.     { "Contents",           0, 0 },
  2533.     { "Dialer-Entries",     5, 0 },
  2534.     { "File-Transfer",      8, 0 },
  2535.     { "Getting-Started",    3, 0 },
  2536.     { "Host-Mode",          9, 0 },
  2537.     { "Installation",       2, 0 },
  2538.     { "Terminal-Emulation", 7, 0 },
  2539.     { "Using-The-Dialer",   4, 0 },
  2540.     { "What-Is-K95",        1, 0 },
  2541.     { "",                   0, 0 }
  2542. };
  2543. static int nchaptbl = (sizeof(chaptbl) / sizeof(struct keytab) - 1);
  2544. #endif /* OS2 */
  2545.  
  2546. #ifndef NOXFER
  2547. /* Remote Command Table */
  2548.  
  2549. struct keytab remcmd[] = {
  2550. #ifndef NOSPL
  2551.     { "as",        XZASG, CM_INV|CM_ABR },
  2552.     { "asg",       XZASG, CM_INV },
  2553.     { "assign",    XZASG, 0 },
  2554. #endif /* NOSPL */
  2555.     { "cd",        XZCWD, 0 },
  2556.     { "cdup",      XZCDU, CM_INV },
  2557.     { "copy",      XZCPY, 0 },
  2558.     { "cwd",       XZCWD, CM_INV },
  2559.     { "delete",    XZDEL, 0 },
  2560.     { "directory", XZDIR, 0 },
  2561.     { "e",         XZXIT, CM_ABR|CM_INV },
  2562.     { "erase",     XZDEL, CM_INV },
  2563.     { "exit",      XZXIT, 0 },
  2564.     { "help",      XZHLP, 0 },
  2565. #ifndef NOPUSH
  2566.     { "host",      XZHOS, 0 },
  2567. #endif /* NOPUSH */
  2568. #ifndef NOFRILLS
  2569.     { "kermit",    XZKER, 0 },
  2570.     { "l",         XZLGI, CM_ABR|CM_INV },
  2571.     { "lo",        XZLGI, CM_ABR|CM_INV },
  2572.     { "log",       XZLGI, CM_ABR|CM_INV },
  2573.     { "login",     XZLGI, 0 },
  2574.     { "logout",    XZLGO, 0 },
  2575.     { "mkdir",     XZMKD, 0 },
  2576.     { "print",     XZPRI, 0 },
  2577. #endif /* NOFRILLS */
  2578.     { "pwd",       XZPWD, 0 },
  2579. #ifndef NOSPL
  2580.     { "query",       XZQUE, 0 },
  2581. #endif /* NOSPL */
  2582.     { "rename",    XZREN, 0 },
  2583.     { "rmdir",     XZRMD, 0 },
  2584.     { "set",       XZSET, 0 },
  2585.     { "space",       XZSPA, 0 },
  2586. #ifndef NOFRILLS
  2587.     { "type",      XZTYP, 0 },
  2588.     { "who",       XZWHO, 0 },
  2589. #endif /* NOFRILLS */
  2590.     { "", 0, 0}
  2591. };
  2592. int nrmt = (sizeof(remcmd) / sizeof(struct keytab)) - 1;
  2593. #endif /* NOXFER */
  2594.  
  2595. struct keytab logtab[] = {
  2596. #ifdef CKLOGDIAL
  2597.     { "connections",  LOGM, CM_INV },
  2598.     { "cx",           LOGM, 0 },
  2599. #endif /* CKLOGDIAL */
  2600. #ifdef DEBUG
  2601.     { "debugging",    LOGD, 0 },
  2602. #endif /* DEBUG */
  2603.     { "packets",      LOGP, 0 },
  2604. #ifndef NOLOCAL
  2605.     { "session",      LOGS, 0 },
  2606. #endif /* NOLOCAL */
  2607. #ifdef TLOG
  2608.     { "transactions", LOGT, 0 },
  2609. #endif /* TLOG */
  2610.     { "", 0, 0 }
  2611. };
  2612. int nlog = (sizeof(logtab) / sizeof(struct keytab)) - 1;
  2613.  
  2614. struct keytab writab[] = {
  2615. #ifndef NOSPL
  2616.     { "append-file",     LOGW, CM_INV },
  2617. #endif /* NOSPL */
  2618.     { "debug-log",       LOGD, 0 },
  2619.     { "error",           LOGE, 0 },
  2620. #ifndef NOSPL
  2621.     { "file",            LOGW, 0 },
  2622. #endif /* NOSPL */
  2623.     { "packet-log",      LOGP, 0 },
  2624.     { "screen",          LOGX, 0 },
  2625. #ifndef NOLOCAL
  2626.     { "session-log",     LOGS, 0 },
  2627. #endif /* NOLOCAL */
  2628.     { "sys$output",      LOGX, CM_INV },
  2629.     { "t",               LOGT, CM_ABR|CM_INV }, /* Because of a typo in */
  2630.     { "tr",              LOGT, CM_ABR|CM_INV }, /* the book... */
  2631.     { "tra",             LOGT, CM_ABR|CM_INV },
  2632.     { "tran",            LOGT, CM_ABR|CM_INV },
  2633.     { "trans",           LOGT, CM_ABR|CM_INV },
  2634.     { "transa",          LOGT, CM_ABR|CM_INV },
  2635.     { "transac",         LOGT, CM_ABR|CM_INV },
  2636.     { "transact",        LOGT, CM_ABR|CM_INV },
  2637.     { "transacti",       LOGT, CM_ABR|CM_INV },
  2638.     { "transactio",      LOGT, CM_ABR|CM_INV },
  2639.     { "transaction",     LOGT, CM_ABR|CM_INV },
  2640.     { "transaction-log", LOGT, 0 },
  2641.     { "transactions",    LOGT, CM_INV }
  2642. };
  2643. int nwri = (sizeof(writab) / sizeof(struct keytab));
  2644.  
  2645. #ifdef COMMENT                /* INPUT switches not used yet... */
  2646. static struct keytab inswtab[] = {
  2647. #ifdef COMMENT
  2648.     { "/assign",       IN_ASG, CM_ARG },
  2649. #endif /* COMMENT */
  2650.     { "/autodownload", IN_ADL, CM_ARG },
  2651.     { "/case",         IN_CAS, CM_ARG },
  2652.     { "/echo",         IN_ECH, CM_ARG },
  2653.     { "/interrupts",   IN_NOI, CM_ARG },
  2654.     { "/silence",      IN_SIL, CM_ARG },
  2655. #ifdef COMMENT
  2656.     { "/pattern",      IN_PAT, CM_ARG },
  2657. #endif /* COMMENT */
  2658.     { "", 0, 0 }
  2659. };
  2660. static int ninswtab = (sizeof(inswtab) / sizeof(struct keytab)) - 1;
  2661. #endif /* COMMENT */
  2662.  
  2663. static struct keytab clrtab[] = {    /* Keywords for CLEAR command */
  2664. #ifndef NOSPL
  2665.     { "alarm",            CLR_ALR,         0 },
  2666. #ifdef CK_APC
  2667.     { "apc",              CLR_APC,         0 },
  2668. #endif /* CK_APC */
  2669. #ifdef PATTERNS
  2670.     { "binary-patterns",  CLR_BIN,         0 },
  2671. #endif /* PATTERNS */
  2672.     { "both",             CLR_DEV|CLR_INP, CM_INV },
  2673. #endif /* NOSPL */
  2674. #ifdef OS2
  2675.     { "command-screen",   CLR_CMD,         0 },
  2676. #endif /* OS2 */
  2677. #ifndef NOSPL
  2678.     { "device",           CLR_DEV,         CM_INV|CM_ABR },
  2679.     { "device-and-input", CLR_DEV|CLR_INP, 0 },
  2680. #endif /* NOSPL */
  2681.     { "device-buffer",    CLR_DEV,         0 },
  2682. #ifndef NODIAL
  2683.     { "dial-status",      CLR_DIA,     0 },
  2684. #endif /* NODIAL */
  2685. #ifndef NOSPL
  2686.     { "input-buffer",     CLR_INP,         0 },
  2687. #endif /* NOSPL */
  2688.     { "keyboard-buffer",  CLR_KBD,         0 },
  2689.     { "send-list",        CLR_SFL,         0 },
  2690. #ifdef OS2
  2691.     { "scr",              CLR_SCL,         CM_INV|CM_ABR },
  2692. #endif /* OS2 */
  2693.     { "screen",           CLR_SCR,         0 },
  2694. #ifdef OS2
  2695.     { "scrollback",       CLR_SCL,         CM_INV },
  2696.     { "terminal-screen",  CLR_TRM,         0 },
  2697. #endif /* OS2 */
  2698. #ifdef PATTERNS
  2699.     { "text-patterns",    CLR_TXT,         0 },
  2700. #endif /* PATTERNS */
  2701.     { "", 0, 0 }
  2702. };
  2703. int nclear = (sizeof(clrtab) / sizeof(struct keytab)) - 1;
  2704.  
  2705. struct keytab clstab[] = {        /* Keywords for CLOSE command */
  2706. #ifndef NOSPL
  2707.     { "!read",           LOGR, CM_INV },
  2708.     { "!write",          LOGW, CM_INV },
  2709. #ifndef NOPUSH
  2710. #endif /* NOPUSH */
  2711. #endif /* NOSPL */
  2712. #ifndef NOSPL
  2713.     { "append-file",     LOGW, CM_INV },
  2714. #endif /* NOSPL */
  2715. #ifndef NOLOCAL
  2716.     { "connection",      9999, 0 },
  2717. #endif /* NOLOCAL */
  2718. #ifdef CKLOGDIAL
  2719.     { "cx-log",          LOGM, 0 },
  2720. #endif /* CKLOGDIAL */
  2721. #ifdef DEBUG
  2722.     { "debug-log",       LOGD, 0 },
  2723. #endif /* DEBUG */
  2724.     { "host",            9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
  2725.     { "line",            9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
  2726.     { "p",               LOGP, CM_INV|CM_ABR },
  2727.     { "packet-log",      LOGP, 0 },
  2728.     { "port",            9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
  2729. #ifndef NOSPL
  2730.     { "read-file",       LOGR, 0 },
  2731. #endif /* NOSPL */
  2732. #ifndef NOLOCAL
  2733.     { "session-log",     LOGS, 0 },
  2734. #endif /* NOLOCAL */
  2735. #ifdef TLOG
  2736.     { "t",               LOGT, CM_ABR|CM_INV }, /* Because of a typo in */
  2737.     { "tr",              LOGT, CM_ABR|CM_INV }, /* the book... */
  2738.     { "tra",             LOGT, CM_ABR|CM_INV },
  2739.     { "tran",            LOGT, CM_ABR|CM_INV },
  2740.     { "trans",           LOGT, CM_ABR|CM_INV },
  2741.     { "transa",          LOGT, CM_ABR|CM_INV },
  2742.     { "transac",         LOGT, CM_ABR|CM_INV },
  2743.     { "transact",        LOGT, CM_ABR|CM_INV },
  2744.     { "transacti",       LOGT, CM_ABR|CM_INV },
  2745.     { "transactio",      LOGT, CM_ABR|CM_INV },
  2746.     { "transaction",     LOGT, CM_ABR|CM_INV },
  2747.     { "transaction-log", LOGT, 0 },
  2748.     { "transactions",    LOGT, CM_INV },
  2749. #endif /* TLOG */
  2750. #ifndef NOSPL
  2751.     { "write-file",      LOGW, 0 },
  2752. #endif /* NOSPL */
  2753.     { "", 0, 0 }
  2754. };
  2755. int ncls = (sizeof(clstab) / sizeof(struct keytab)) - 1;
  2756.  
  2757. /* SHOW command arguments */
  2758.  
  2759. #ifndef NOSHOW
  2760. struct keytab shotab[] = {
  2761. #ifndef NOSPL
  2762.     { "alarm",        SHALRM, 0 },
  2763.     { "arg",          SHARG, CM_INV|CM_ABR },
  2764.     { "arguments",    SHARG, 0 },
  2765.     { "args",         SHARG, CM_INV },
  2766.     { "arrays",       SHARR, 0 },
  2767. #endif /* NOSPL */
  2768.  
  2769. #ifndef NOCSETS
  2770.     { "associations", SHASSOC, 0 },
  2771. #endif /* NOCSETS */
  2772.  
  2773. #ifndef NOXFER
  2774.     { "attributes",   SHATT, 0 },
  2775. #endif /* NOXFER */
  2776.  
  2777. #ifdef CK_AUTHENTICATION
  2778.     { "authentication", SHOAUTH, CM_INV },
  2779. #endif /* CK_AUTHENTICATION */
  2780.  
  2781. #ifndef NOPUSH
  2782. #ifdef BROWSER
  2783.     { "browser",      SHBROWSE, CM_PSH|CM_LOC },
  2784. #endif /*  BROWSER */
  2785. #endif /* NOPUSH */
  2786.     { "cd",           SHCD, 0 },
  2787.     { "character-sets", SHCSE, 0 },
  2788.     { "cmd",          SHCMD, CM_INV },
  2789. #ifndef NOLOCAL
  2790.     { "com",          SHCOM, CM_INV|CM_ABR },
  2791.     { "comm",         SHCOM, CM_INV|CM_ABR },
  2792.     { "communications", SHCOM, 0 },
  2793. #endif /* NOLOCAL */
  2794.     { "command",      SHCMD, 0 },
  2795.     { "connection",   SHCONNX, 0 },
  2796. #ifdef CK_SPEED
  2797.     { "control-prefixing", SHCTL, 0 },
  2798. #endif /* CK_SPEED */
  2799. #ifdef CKLOGDIAL
  2800.     { "cx",           SHCONNX, CM_INV },
  2801. #endif /* CKLOGDIAL */
  2802. #ifndef NOSPL
  2803.     { "count",        SHCOU, 0 },
  2804. #endif /* NOSPL */
  2805.     { "d",            SHDIA, CM_INV|CM_ABR },
  2806. #ifdef VMS
  2807.     { "default",      SHDFLT, 0 },
  2808. #else
  2809.     { "default",      SHDFLT, CM_INV },
  2810. #endif /* VMS */
  2811. #ifndef NODIAL
  2812.     { "dial",         SHDIA, CM_LOC },
  2813. #endif /* NODIAL */
  2814.     { "double/ignore",SHDBL, 0 },
  2815. #ifndef NOPUSH
  2816. #ifndef NOFRILLS
  2817.     { "editor",       SHEDIT, CM_PSH },
  2818. #endif /*  NOFRILLS */
  2819. #endif /* NOPUSH */
  2820. #ifndef NOLOCAL
  2821.     { "escape",       SHESC, CM_LOC },
  2822. #endif /* NOLOCAL */
  2823.     { "exit",         SHEXI, 0 },
  2824.     { "extended-options", SHXOPT, CM_INV },
  2825.     { "features",     SHFEA, 0 },
  2826.     { "file",         SHFIL, 0 },
  2827. #ifndef NOLOCAL
  2828.     { "flow-control", SHOFLO, 0 },
  2829. #endif /* NOLOCAL */
  2830. #ifdef BROWSER
  2831.     { "ftp",          SHOFTP, CM_PSH|CM_LOC },
  2832. #else
  2833. #ifndef NOFTP
  2834. #ifndef SYSFTP
  2835. #ifdef TCPSOCKET
  2836.     { "ftp",          SHOFTP, 0 },    /* (built-in ftp) */
  2837. #endif /* TCPSOCKET */
  2838. #endif /* SYSFTP */
  2839. #endif /* NOFTP */
  2840. #endif /* BROWSER */
  2841. #ifndef NOSPL
  2842.     { "functions",    SHFUN, 0 },
  2843.     { "globals",      SHVAR, 0 },
  2844. #endif /* NOSPL */
  2845. #ifdef KUI
  2846.     { "gui",          SHOGUI, 0 },
  2847. #endif /* KUI */
  2848. #ifdef CK_RECALL
  2849.     { "history",      SHHISTORY, 0 },
  2850. #endif /* CK_RECALL */
  2851.     { "ignore/double",SHDBL, CM_INV },
  2852.     { "iksd",         SHOIKS, CM_INV },
  2853. #ifndef NOSPL
  2854.     { "input",        SHINP, 0 },
  2855. #endif /* NOSPL */
  2856. #ifndef NOSETKEY
  2857.     { "k",            SHKEY, CM_INV|CM_ABR },
  2858.     { "key",          SHKEY, 0 },
  2859. #ifndef NOKVERBS
  2860.     { "kverbs",       SHKVB, 0 },
  2861. #endif /* NOKVERBS */
  2862. #endif /* NOSETKEY */
  2863. #ifdef CK_LABELED
  2864.     { "labeled-file-info", SHLBL, 0 },
  2865. #endif /* CK_LABELED */
  2866. #ifndef NOCSETS
  2867.     { "languages",    SHLNG, 0 },
  2868. #endif /* NOCSETS */
  2869.     { "logs",         SHLOG, 0 },
  2870. #ifndef NOSPL
  2871.     { "macros",       SHMAC, 0 },
  2872. #endif /* NOSPL */
  2873. #ifndef NODIAL
  2874.     { "modem",        SHMOD, CM_LOC },
  2875. #else
  2876.     { "modem-signals",SHCOM, CM_INV|CM_LOC },
  2877. #endif /* NODIAL */
  2878. #ifndef NOLOCAL
  2879. #ifdef OS2MOUSE
  2880.     { "mouse",        SHMOU, CM_LOC },
  2881. #endif /* OS2MOUSE */
  2882. #endif /* NOLOCAL */
  2883. #ifdef NETCONN
  2884.     { "network",      SHNET, CM_LOC },
  2885. #else
  2886.     { "network",      SHNET, CM_INV|CM_LOC },
  2887. #endif /* NETCONN */
  2888.     { "options",      SHOPTS, 0 },
  2889. #ifndef NOSPL
  2890.     { "output",       SHOUTP, CM_INV },
  2891. #endif /* NOSPL */
  2892. #ifdef ANYX25
  2893. #ifndef IBMX25
  2894.     { "pad",          SHPAD,  CM_LOC },
  2895. #endif /* IBMX25 */
  2896. #endif /* ANYX25 */
  2897.     { "parameters",   SHPAR,  CM_INV },
  2898. #ifdef PATTERNS
  2899.     { "patterns",     SHOPAT, 0 },
  2900. #endif /* PATTERNS */
  2901.     { "printer",      SHPRT,  0 },
  2902. #ifdef CK_SPEED
  2903.     { "prefixing",    SHCTL,  CM_INV },
  2904. #endif /* CK_SPEED */
  2905. #ifndef NOXFER
  2906.     { "protocol",     SHPRO,  0 },
  2907. #endif /* NOXFER */
  2908. #ifndef NOSPL
  2909.     { "scripts",      SHSCR,  CM_LOC },
  2910. #endif /* NOSPL */
  2911.     { "send-list",    SHSFL,  0 },
  2912. #ifndef NOSERVER
  2913.     { "server",       SHSER,  0 },
  2914. #endif /* NOSERVER */
  2915. #ifndef NOSEXP
  2916.     { "sexpression",  SHSEXP, 0 },
  2917. #endif /* NOSEXP */
  2918. #ifdef ANYSSH
  2919.     { "ssh",          SHOSSH, 0 },
  2920. #endif /* ANYSSH */
  2921.     { "stack",        SHSTK,  0 },
  2922.     { "status",       SHSTA,  0 },
  2923. #ifdef STREAMING
  2924.     { "streaming",    SHOSTR, 0 },
  2925. #endif /* STREAMING */
  2926. #ifndef NOLOCAL
  2927. #ifdef OS2
  2928.     { "tabs",          SHTAB, CM_INV|CM_LOC },
  2929. #endif /* OS2 */
  2930. #ifdef CK_TAPI
  2931.     { "tapi",          SHTAPI, CM_LOC },
  2932.     { "tapi-comm",     SHTAPI_C, CM_INV|CM_LOC },
  2933.     { "tapi-location", SHTAPI_L, CM_INV|CM_LOC },
  2934.     { "tapi-modem",    SHTAPI_M, CM_INV|CM_LOC },
  2935. #endif /* CK_TAPI */
  2936.     { "tcp",           SHTCP,  CM_LOC },
  2937. #ifdef TNCODE
  2938.     { "tel",           SHTEL,  CM_INV|CM_ABR },
  2939.     { "telnet",        SHTEL,  0 },
  2940.     { "telopt",        SHTOPT, 0 },
  2941. #endif /* TNCODE */
  2942.     { "terminal",      SHTER,  CM_LOC },
  2943. #endif /* NOLOCAL */
  2944. #ifndef NOXMIT
  2945.     { "tr",            SHXMI, CM_INV|CM_ABR },
  2946.     { "tra",           SHXMI, CM_INV|CM_ABR },
  2947.     { "tran",          SHXMI, CM_INV|CM_ABR },
  2948.     { "trans",         SHXMI, CM_INV|CM_ABR },
  2949. #endif /* NOXMIT */
  2950. #ifndef NOXFER
  2951.     { "transfer",      SHOXFER, 0 },
  2952. #endif /* NOXFER */
  2953. #ifndef NOXMIT
  2954.     { "transmit",      SHXMI, 0 },
  2955. #endif /* NOXMIT */
  2956. #ifdef CK_TRIGGER
  2957.     { "trigger",       SHTRIG, CM_LOC },
  2958. #endif /* CK_TRIGGER */
  2959. #ifndef NOSETKEY
  2960. #ifndef NOKVERBS
  2961. #ifdef OS2
  2962.     { "udk",           SHUDK, CM_LOC },
  2963. #endif /* OS2 */
  2964. #endif /* NOKVERBS */
  2965. #endif /* NOSETKEY */
  2966. #ifndef NOSPL
  2967.     { "variables",     SHBUI, 0 },
  2968. #endif /* NOSPL */
  2969. #ifndef NOFRILLS
  2970.     { "versions",      SHVER, 0 },
  2971. #endif /* NOFRILLS */
  2972. #ifdef OS2
  2973.     { "vscrn",         SHVSCRN, CM_INV|CM_LOC },
  2974. #endif /* OS2 */
  2975.     { "xfer",          SHOXFER,  CM_INV },
  2976. #ifndef NOXMIT
  2977.     { "xmit",          SHXMI,    CM_INV },
  2978. #endif /* NOXMIT */
  2979.     { "", 0, 0 }
  2980. };
  2981. int nsho = (sizeof(shotab) / sizeof(struct keytab)) - 1;
  2982. #endif /* NOSHOW */
  2983.  
  2984. #ifdef ANYX25
  2985. #ifndef IBMX25
  2986. struct keytab padtab[] = {              /* PAD commands */
  2987.     { "clear",      XYPADL, 0 },
  2988.     { "interrupt",  XYPADI, 0 },
  2989.     { "reset",      XYPADR, 0 },
  2990.     { "status",     XYPADS, 0 }
  2991. };
  2992. int npadc = (sizeof(padtab) / sizeof(struct keytab));
  2993. #endif /* IBMX25 */
  2994. #endif /* ANYX25 */
  2995.  
  2996. #ifndef NOSERVER
  2997. static struct keytab kmstab[] = {
  2998.     { "both",    3, 0 },
  2999.     { "local",   1, 0 },
  3000.     { "remote",  2, 0 }
  3001. };
  3002.  
  3003. static struct keytab enatab[] = {    /* ENABLE commands */
  3004.     { "all",        EN_ALL,  0 },
  3005. #ifndef NOSPL
  3006.     { "as",         EN_ASG,  CM_INV|CM_ABR },
  3007.     { "asg",        EN_ASG,  CM_INV },
  3008.     { "assign",     EN_ASG,  0 },
  3009. #endif /* NOSPL */
  3010. #ifndef datageneral
  3011.     { "bye",        EN_BYE,  0 },
  3012. #endif /* datageneral */
  3013.     { "cd",         EN_CWD,  0 },
  3014. #ifdef ZCOPY
  3015.     { "copy",       EN_CPY,  0 },
  3016. #endif /* ZCOPY */
  3017.     { "cwd",        EN_CWD,  CM_INV },
  3018.     { "delete",     EN_DEL,  0 },
  3019.     { "directory",  EN_DIR,  0 },
  3020.     { "enable",     EN_ENA,  CM_INV },
  3021.     { "exit",       EN_XIT,  0 },
  3022.     { "finish",     EN_FIN,  0 },
  3023.     { "get",        EN_GET,  0 },
  3024.     { "host",       EN_HOS,  0 },
  3025.     { "mail",       EN_MAI,  0 },
  3026.     { "mkdir",      EN_MKD,  0 },
  3027.     { "print",      EN_PRI,  0 },
  3028. #ifndef NOSPL
  3029.     { "query",      EN_QUE,  0 },
  3030. #endif /* NOSPL */
  3031.     { "rename",     EN_REN,  0 },
  3032.     { "retrieve",   EN_RET,  CM_INV },
  3033.     { "rmdir",      EN_RMD,  0 },
  3034.     { "send",       EN_SEN,  0 },
  3035.     { "set",        EN_SET,  0 },
  3036.     { "space",      EN_SPA,  0 },
  3037.     { "type",       EN_TYP,  0 },
  3038.     { "who",        EN_WHO,  0 }
  3039. };
  3040. static int nena = (sizeof(enatab) / sizeof(struct keytab));
  3041. #endif /* NOSERVER */
  3042.  
  3043. struct keytab txtbin[] = {
  3044.     { "all",        2, 0 },
  3045.     { "binary",     1, 0 },
  3046.     { "text",       0, 0 }
  3047. };
  3048.  
  3049. #ifndef NOXFER
  3050. static struct keytab sndtab[] = {    /* SEND command options */
  3051.     { "/after",           SND_AFT, CM_ARG },
  3052. #ifndef NOSPL
  3053.     { "/array",           SND_ARR, CM_ARG },
  3054. #endif /* NOSPL */
  3055.     { "/as-name",         SND_ASN, CM_ARG },
  3056.     { "/b",               SND_BIN, CM_INV|CM_ABR },
  3057.     { "/before",          SND_BEF, CM_ARG },
  3058.     { "/binary",          SND_BIN, 0 },
  3059. #ifdef CALIBRATE
  3060.     { "/c",               SND_CMD, CM_INV|CM_ABR },
  3061.     { "/calibrate",       SND_CAL, CM_INV|CM_ARG },
  3062. #endif /* CALIBRATE */
  3063.     { "/command",         SND_CMD, CM_PSH },
  3064.     { "/delete",          SND_DEL, 0 },
  3065. #ifdef UNIXOROSK
  3066.     { "/dotfiles",        SND_DOT, 0 },
  3067. #endif /* UNIXOROSK */
  3068.     { "/except",          SND_EXC, CM_ARG },
  3069. #ifdef PIPESEND
  3070.     { "/filter",          SND_FLT, CM_ARG|CM_PSH },
  3071. #endif /* PIPESEND */
  3072.     { "/filenames",       SND_NAM, CM_ARG },
  3073. #ifdef CKSYMLINK
  3074.     { "/followlinks",      SND_LNK, 0 },
  3075. #endif /* CKSYMLINK */
  3076. #ifdef VMS
  3077.     { "/image",           SND_IMG, 0 },
  3078. #else
  3079.     { "/image",           SND_BIN, CM_INV },
  3080. #endif /* VMS */
  3081. #ifdef CK_LABELED
  3082.     { "/labeled",         SND_LBL, 0 },
  3083. #endif /* CK_LABELED */
  3084.     { "/larger-than",     SND_LAR, CM_ARG },
  3085.     { "/listfile",        SND_FIL, CM_ARG },
  3086. #ifndef NOFRILLS
  3087.     { "/mail",            SND_MAI, CM_ARG },
  3088. #endif /* NOFRILLS */
  3089. #ifdef CK_TMPDIR
  3090.     { "/move-to",         SND_MOV, CM_ARG },
  3091. #endif /* CK_TMPDIR */
  3092.     { "/nobackupfiles",   SND_NOB, 0 },
  3093. #ifdef UNIXOROSK
  3094.     { "/nodotfiles",      SND_NOD, 0 },
  3095. #endif /* UNIXOROSK */
  3096. #ifdef CKSYMLINK
  3097.     { "/nofollowlinks",      SND_NLK, 0 },
  3098. #endif /* CKSYMLINK */
  3099.     { "/not-after",       SND_NAF, CM_ARG },
  3100.     { "/not-before",      SND_NBE, CM_ARG },
  3101.     { "/pathnames",       SND_PTH, CM_ARG },
  3102.     { "/print",           SND_PRI, CM_ARG },
  3103. #ifdef CK_XYZ
  3104.     { "/protocol",        SND_PRO, CM_ARG },
  3105. #else
  3106.     { "/protocol",        SND_PRO, CM_ARG|CM_INV },
  3107. #endif /* CK_XYZ */
  3108.     { "/quiet",           SND_SHH, 0 },
  3109.     { "/recover",         SND_RES, 0 },
  3110. #ifdef RECURSIVE
  3111. /* Systems where we do recursion */
  3112.     { "/recursive",       SND_REC, 0 },
  3113. #else
  3114. #ifdef VMS
  3115. /* Systems that do recursion themselves without our assistance */
  3116. /* if we give them the right kind of wildcard */
  3117.     { "/recursive",       SND_REC, 0 },
  3118. #else
  3119. #ifdef datageneral
  3120.     { "/recursive",       SND_REC, 0 },
  3121. #else
  3122.     { "/recursive",       SND_REC, CM_INV },
  3123. #endif /* datageneral */
  3124. #endif /* VMS */
  3125. #endif /* RECURSIVE */
  3126.     { "/rename-to",       SND_REN, CM_ARG },
  3127.     { "/since",           SND_AFT, CM_INV|CM_ARG },
  3128.     { "/smaller-than",    SND_SMA, CM_ARG },
  3129.     { "/starting-at",     SND_STA, CM_ARG },
  3130. #ifndef NOFRILLS
  3131.     { "/su",              SND_ASN, CM_ARG|CM_INV|CM_ABR },
  3132.     { "/sub",             SND_ASN, CM_ARG|CM_INV|CM_ABR },
  3133.     { "/subject",         SND_ASN, CM_ARG },
  3134. #endif /* NOFRILLS */
  3135. #ifdef RECURSIVE
  3136.     { "/subdirectories",  SND_REC, CM_INV },
  3137. #endif /* RECURSIVE */
  3138.     { "/text",            SND_TXT, 0 },
  3139.     { "/transparent",     SND_XPA, 0 },
  3140.     { "/type",            SND_TYP, CM_ARG }
  3141. };
  3142. #define NSNDTAB sizeof(sndtab)/sizeof(struct keytab)
  3143. static int nsndtab = NSNDTAB;
  3144.  
  3145. #ifndef NOMSEND
  3146. static struct keytab msndtab[] = {    /* MSEND options */
  3147.     { "/after",           SND_AFT, CM_ARG },
  3148.     { "/before",          SND_BEF, CM_ARG },
  3149.     { "/binary",          SND_BIN, 0 },
  3150.     { "/delete",          SND_DEL, 0 },
  3151.     { "/except",          SND_EXC, CM_ARG },
  3152.     { "/filenames",       SND_NAM, CM_ARG },
  3153. #ifdef CKSYMLINK
  3154.     { "/followlinks",      SND_LNK, 0 },
  3155. #endif /* CKSYMLINK */
  3156. #ifdef VMS
  3157.     { "/image",           SND_IMG, 0 },
  3158. #else
  3159.     { "/image",           SND_BIN, CM_INV },
  3160. #endif /* VMS */
  3161. #ifdef CK_LABELED
  3162.     { "/labeled",         SND_LBL, 0 },
  3163. #endif /* CK_LABELED */
  3164.     { "/larger-than",     SND_LAR, CM_ARG },
  3165.     { "/list",            SND_FIL, CM_ARG },
  3166. #ifndef NOFRILLS
  3167.     { "/mail",            SND_MAI, CM_ARG },
  3168. #endif /* NOFRILLS */
  3169. #ifdef CK_TMPDIR
  3170.     { "/move-to",         SND_MOV, CM_ARG },
  3171. #endif /* CK_TMPDIR */
  3172. #ifdef CKSYMLINK
  3173.     { "/nofollowlinks",    SND_NLK, 0 },
  3174. #endif /* CKSYMLINK */
  3175.     { "/not-after",       SND_NAF, CM_ARG },
  3176.     { "/not-before",      SND_NBE, CM_ARG },
  3177.     { "/pathnames",       SND_PTH, CM_ARG },
  3178.     { "/print",           SND_PRI, CM_ARG },
  3179. #ifdef CK_XYZ
  3180.     { "/protocol",        SND_PRO, CM_ARG },
  3181. #endif /* CK_XYZ */
  3182.     { "/quiet",           SND_SHH, 0 },
  3183.     { "/recover",         SND_RES, 0 },
  3184.     { "/rename-to",       SND_REN, CM_ARG },
  3185.     { "/since",           SND_AFT, CM_INV|CM_ARG },
  3186.     { "/smaller-than",    SND_SMA, CM_ARG },
  3187.     { "/starting-at",     SND_STA, CM_ARG },
  3188. #ifndef NOFRILLS
  3189.     { "/subject",         SND_ASN, CM_ARG },
  3190. #endif /* NOFRILLS */
  3191.     { "/text",            SND_TXT, 0 },
  3192.     { "/transparent",     SND_XPA, 0 },
  3193.     { "/type",            SND_TYP, CM_ARG }
  3194. };
  3195. #define NMSNDTAB sizeof(msndtab)/sizeof(struct keytab)
  3196. static int nmsndtab = NMSNDTAB;
  3197. #endif /* NOMSEND */
  3198. #endif /* NOXFER */
  3199.  
  3200. /* CONNECT command switches */
  3201.  
  3202. #define CONN_II  0    /* Idle interval */
  3203. #define CONN_IS  1    /* Idle string */
  3204. #define CONN_IL  2    /* Idle limit */
  3205. #define CONN_NV  3    /* Non-Verbose */
  3206. #define CONN_TL  4    /* Time limit */
  3207. #define CONN_TS  5    /* Trigger string */
  3208. #define CONN_AS  6    /* Asynchronous */
  3209. #define CONN_SY  7    /* Synchronous */
  3210. #define CONN_MAX 7    /* Number of CONNECT switches */
  3211.  
  3212. #ifndef NOLOCAL
  3213. static struct keytab conntab[] = {
  3214. #ifdef OS2
  3215.     { "/asynchronous",    CONN_AS, CM_INV },
  3216. #endif /* OS2 */
  3217. #ifdef XLIMITS
  3218.     { "/idle-interval",   CONN_II, CM_ARG },
  3219.     { "/idle-limit",      CONN_IL, CM_ARG },
  3220.     { "/idle-string",     CONN_IS, CM_ARG },
  3221.     { "/quietly",         CONN_NV, CM_INV },
  3222. #else
  3223.     { "/quietly",         CONN_NV, 0 },
  3224. #endif /* XLIMITS */
  3225. #ifdef OS2
  3226.     { "/synchronous",     CONN_SY, CM_INV },
  3227. #endif /* OS2 */
  3228. #ifdef XLIMITS
  3229.     { "/time-limit",      CONN_TL, CM_ARG },
  3230. #endif /* XLIMITS */
  3231. #ifdef CK_TRIGGER
  3232.     { "/trigger",         CONN_TS, CM_ARG },
  3233. #endif /* CK_TRIGGER */
  3234.     { "",0,0 }
  3235. };
  3236. #define NCONNTAB sizeof(conntab)/sizeof(struct keytab)
  3237. static int nconntab = NCONNTAB;
  3238. #endif /* NOLOCAL */
  3239.  
  3240. #ifndef NOXFER
  3241. static struct keytab stattab[] = {    /* STATISTICS command switches */
  3242.     { "/brief",   1, 0 },
  3243.     { "/verbose", 0, 0 }
  3244. };
  3245. #endif /* NOXFER */
  3246.  
  3247. #ifndef NOSPL
  3248. #ifdef COMMENT
  3249. struct mtab mactab[MAC_MAX] = {        /* Preinitialized macro table */
  3250.     { NULL, NULL, 0 }
  3251. };
  3252. #else
  3253. struct mtab *mactab;            /* Dynamically allocated macro table */
  3254. #endif /* COMMENT */
  3255. int nmac = 0;
  3256.  
  3257. struct keytab mackey[MAC_MAX];        /* Macro names as command keywords */
  3258. #endif /* NOSPL */
  3259.  
  3260. #ifndef NOSPL
  3261. #ifdef  OS2
  3262. struct keytab beeptab[] = {        /* Beep options */
  3263.     { "error", BP_FAIL, 0 },
  3264.     { "information", BP_NOTE, 0 },
  3265.     { "warning", BP_WARN, 0 }
  3266. };
  3267. int nbeeptab = sizeof(beeptab)/sizeof(struct keytab);
  3268.  
  3269. /* CLEAR COMMMAND-SCREEN options */
  3270.  
  3271. #define CLR_C_ALL 0
  3272. #define CLR_C_BOL 1
  3273. #define CLR_C_BOS 2
  3274. #define CLR_C_EOL 3
  3275. #define CLR_C_EOS 4
  3276. #define CLR_C_LIN 5
  3277. #define CLR_C_SCR 6
  3278.  
  3279. struct keytab clrcmdtab[] = {
  3280.     { "all",        CLR_C_ALL, 0 },
  3281.     { "bol",        CLR_C_BOL, 0 },
  3282.     { "bos",        CLR_C_BOS, 0 },
  3283.     { "eol",        CLR_C_EOL, 0 },
  3284.     { "eos",        CLR_C_EOS, 0 },
  3285.     { "line",       CLR_C_LIN, 0 },
  3286.     { "scrollback", CLR_C_SCR, 0 }
  3287. };
  3288. int nclrcmd = sizeof(clrcmdtab)/sizeof(struct keytab);
  3289. #endif /* OS2 */
  3290. #endif /* NOSPL */
  3291.  
  3292. #ifdef COMMENT
  3293. /* Not used at present */
  3294. static struct keytab pagetab[] = {
  3295.     { "/more",   1, CM_INV },
  3296.     { "/nopage", 0, 0 },
  3297.     { "/page",   1, 0 }
  3298. };
  3299. int npagetab = sizeof(pagetab)/sizeof(struct keytab);
  3300. #endif /* COMMENT */
  3301.  
  3302. #define TYP_NOP  0            /* /NOPAGE */
  3303. #define TYP_PAG  1            /* /PAGE */
  3304. #define TYP_HEA  2            /* /HEAD:n */
  3305. #define TYP_TAI  3            /* /TAIL:n */
  3306. #define TYP_PAT  4            /* /MATCH:pattern */
  3307. #define TYP_WID  5            /* /WIDTH:cols */
  3308. #define TYP_COU  6            /* /COUNT */
  3309. #define TYP_OUT  7            /* /OUTPUT:file */
  3310. #define TYP_PFX  8            /* /PREFIX:string */
  3311. #ifdef UNICODE
  3312. #define TYP_XIN  9            /* /TRANSLATE-FROM:charset */
  3313. #define TYP_XUT 10            /* /TRANSLATE-TO:charset */
  3314. #define TYP_XPA 11            /* /TRANSPARENT */
  3315. #endif /* UNICODE */
  3316. #define TYP_NUM 12            /* /NUMBER */
  3317.  
  3318. static struct keytab typetab[] = {    /* TYPE command switches */
  3319.     { "/count",          TYP_COU, 0 },
  3320. #ifdef UNICODE
  3321.     { "/character-set",  TYP_XIN, CM_ARG },
  3322. #endif /* UNICODE */
  3323.     { "/head",           TYP_HEA, CM_ARG },
  3324.     { "/match",          TYP_PAT, CM_ARG },
  3325. #ifdef CK_TTGWSIZ
  3326.     { "/more",           TYP_PAG, CM_INV },
  3327.     { "/nopage",         TYP_NOP, 0 },
  3328.     { "/number",         TYP_NUM, 0 },
  3329.     { "/output",         TYP_OUT, CM_ARG },
  3330.     { "/page",           TYP_PAG, 0 },
  3331. #endif /* CK_TTGWSIZ */
  3332.     { "/prefix",         TYP_PFX, CM_ARG },
  3333.     { "/tail",           TYP_TAI, CM_ARG },
  3334. #ifdef UNICODE
  3335.     { "/translate-to",   TYP_XUT, CM_ARG },
  3336.     { "/transparent",    TYP_XPA, 0 },
  3337. #endif /* UNICODE */
  3338.     { "/width",          TYP_WID, CM_ARG },
  3339. #ifdef UNICODE
  3340.     { "/xlate-to",       TYP_XUT, CM_INV|CM_ARG },
  3341. #endif /* UNICODE */
  3342.     { "", 0, 0 }
  3343. };
  3344. int ntypetab = sizeof(typetab)/sizeof(struct keytab) - 1;
  3345.  
  3346. int typ_page = -1;            /* TYPE /[NO]PAGE default */
  3347. int typ_wid  = -1;
  3348.  
  3349. #ifndef NOSPL
  3350. #define TRA_ALL 999            /* TRACE command */
  3351. #define TRA_ASG 0
  3352. #define TRA_CMD 1
  3353.  
  3354. int tra_asg = 0;
  3355. int tra_cmd = 0;
  3356.  
  3357. static struct keytab tracetab[] = {    /* TRACE options */
  3358.     { "all",            TRA_ALL, 0 },
  3359.     { "assignments",    TRA_ASG, 0 },
  3360.     { "command-level",  TRA_CMD, 0 }
  3361. };
  3362. static int ntracetab = sizeof(tracetab)/sizeof(struct keytab);
  3363. #endif /* NOSPL */
  3364.  
  3365. #ifndef NOSHOW
  3366. VOID
  3367. showtypopts() {
  3368.     printf(" TYPE ");
  3369.     if (typ_page > -1) {
  3370.     prtopt(&optlines,typ_page ? "/PAGE" : "/NOPAGE");
  3371.     } else
  3372.       prtopt(&optlines,"(no options set)");
  3373.     if (typ_wid > -1) {
  3374.     ckmakmsg(tmpbuf,TMPBUFSIZ,"/WIDTH:",ckitoa(typ_wid),NULL,NULL);
  3375.     prtopt(&optlines,tmpbuf);
  3376.     }
  3377.     prtopt(&optlines,"");
  3378. }
  3379. #endif /* NOSHOW */
  3380.  
  3381. #ifdef LOCUS
  3382. /* isauto == 1 if locus is being switched automatically */
  3383.  
  3384. VOID
  3385. setlocus(x, isauto) int x, isauto; {
  3386.     extern int quitting;
  3387.     if (x) x = 1;
  3388.     if (x && locus) return;
  3389.     if (!x && !locus) return;
  3390.     /* Get here if it actually needs to be changed */
  3391. #ifdef OS2
  3392.     if (isauto &&            /* Automatically switching */
  3393.     !quitting &&            /* not exiting */
  3394.     autolocus == 2) {        /* and AUTOLOCUS is set to ASK */
  3395.     char locmsg[300];
  3396.     ckmakmsg(locmsg,300,
  3397.          "Switching Locus to ",
  3398.          x ? "LOCAL" : "REMOTE",
  3399.          " for file management commands\n"
  3400.                  "such as CD, DIRECTORY, DELETE, RENAME.  Type HELP SET\n"
  3401.                  "LOCUS at the K-95> prompt for further info.  Use the\n"
  3402. #ifdef KUI
  3403.                   "Actions menu or SET LOCUS command to disable automatic\n"
  3404.                   "Locus switching or to disable these queries.",
  3405. #else /* KUI */
  3406.                   "SET LOCUS command to disable automatic locus switching\n"
  3407.                   "or to disable these queries.",
  3408. #endif /* KUI */
  3409.                   NULL);
  3410.     if (uq_ok(locmsg,"OK to switch Locus?",3,NULL,1)) {
  3411.         locus = x;
  3412. #ifdef KUI
  3413.         KuiSetProperty(KUI_LOCUS,x,0);
  3414. #endif /* KUI */
  3415.         return;
  3416.     }
  3417.     } else {
  3418. #endif /* OS2 */
  3419.         if (isauto && msgflg && !quitting)
  3420.           printf("Switching LOCUS for file-management commands to %s.\n",
  3421.          x ? "LOCAL" : "REMOTE"
  3422.          );
  3423.     locus = x;
  3424. #ifdef OS2
  3425. #ifdef KUI
  3426.     KuiSetProperty(KUI_LOCUS,x,0);
  3427. #endif /* KUI */
  3428.     }
  3429. #endif /* OS2 */
  3430. }
  3431.  
  3432. VOID
  3433. setautolocus(x) int x; {
  3434.     autolocus = x;
  3435. #ifdef KUI
  3436.     KuiSetProperty(KUI_AUTO_LOCUS,x,0);
  3437. #endif /* KUI */
  3438. }
  3439. #endif /* LOCUS */
  3440.  
  3441. int
  3442. settypopts() {                /* Set TYPE option defaults */
  3443.     int xp = -1;
  3444.     int c, getval;
  3445.     while (1) {
  3446.     if ((y = cmswi(typetab,ntypetab,"Switch","",xxstring)) < 0) {
  3447.         if (y == -3)
  3448.           break;
  3449.         else
  3450.           return(y);
  3451.     }
  3452.     c = cmgbrk();
  3453.     if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  3454.         printf("?This switch does not take an argument\n");
  3455.         return(-9);
  3456.     }
  3457.     switch (y) {
  3458.       case TYP_NOP: xp = 0; break;
  3459.       case TYP_PAG: xp = 1; break;
  3460.       case TYP_WID:
  3461.         if (getval)
  3462.           if ((x = cmnum("Column at which to truncate",
  3463.                  ckitoa(cmd_cols),10,&y,xxstring)) < 0)
  3464.         return(x);
  3465.         typ_wid = y;
  3466.         break;
  3467.  
  3468.           default:
  3469.         printf("?Sorry, this option can not be set\n");
  3470.         return(-9);
  3471.     }
  3472.     }
  3473.     if ((x = cmcfm()) < 0)        /* Get confirmation */
  3474.       return(x);
  3475.     if (xp > -1) typ_page = xp;        /* Confirmed, save defaults */
  3476.     return(success = 1);
  3477. }
  3478.  
  3479. /* Forward declarations of functions local to this module */
  3480.  
  3481. #ifdef UNIX
  3482. _PROTOTYP (int douchmod, ( void ) );
  3483. #endif /* UNIX */
  3484. #ifdef CKPURGE
  3485. _PROTOTYP (int dopurge,  ( void ) );
  3486. #endif /* CKPURGE */
  3487. #ifndef NOSPL
  3488. _PROTOTYP (int doundef,  ( int  ) );
  3489. _PROTOTYP (int doask,    ( int  ) );
  3490. _PROTOTYP (int dodef,    ( int  ) );
  3491. _PROTOTYP (int doelse,   ( void ) );
  3492. _PROTOTYP (int dofor,    ( void ) );
  3493. _PROTOTYP (int doincr,   ( int  ) );
  3494. #endif /* NOSPL  */
  3495. #ifndef NODIAL
  3496. _PROTOTYP (int dodial,   ( int  ) );
  3497. #endif /* NODIAL */
  3498. _PROTOTYP (int dodel,    ( void ) );
  3499. _PROTOTYP (int dopaus,   ( int  ) );
  3500. #ifndef NOPUSH
  3501. #ifdef TCPSOCKET
  3502. _PROTOTYP (int doping,   ( void ) );
  3503. _PROTOTYP (int doftp,    ( void ) );
  3504. #endif /* TCPSOCKET */
  3505. #endif /* NOPUSH */
  3506. #ifndef NORENAME
  3507. #ifndef NOFRILLS
  3508. _PROTOTYP (int dorenam,  ( void ) );
  3509. #endif /* NOFRILLS */
  3510. #endif /* NORENAME */
  3511. #ifdef ZCOPY
  3512. _PROTOTYP (int docopy,   ( void ) );
  3513. #endif /* ZCOPY */
  3514. #ifdef NT
  3515. _PROTOTYP (int dolink,   ( void ));
  3516. #endif /* NT */
  3517. #ifdef CK_REXX
  3518. _PROTOTYP (int dorexx,   ( void ) );
  3519. #endif /* CK_REXX */
  3520.  
  3521. #ifdef TNCODE
  3522. static struct keytab telcmd[] = {
  3523.     { "abort", TN_ABORT, CM_INV },    /* Emotionally toned - don't show */
  3524.     { "ao",    TN_AO,    0 },
  3525.     { "ayt",   TN_AYT,   0 },
  3526.     { "break", BREAK,    0 },
  3527.     { "cancel",TN_ABORT, 0 },
  3528.     { "dmark", TN_DM,    0 },
  3529.     { "do",    DO,       0 },
  3530.     { "dont",  DONT,     0 },
  3531.     { "ec",    TN_EC,    0 },
  3532.     { "el",    TN_EL,    0 },
  3533.     { "eof",   TN_EOF,   0 },
  3534.     { "eor",   TN_EOR,   0 },
  3535. #ifdef CK_KERBEROS
  3536. #ifdef KRB5
  3537. #define TN_FWD 1
  3538.     { "forward", TN_FWD, CM_INV },
  3539. #endif /* KRB5 */
  3540. #endif /* CK_KERBEROS */
  3541.     { "ga",    TN_GA,    0 },
  3542.     { "ip",    TN_IP,    0 },
  3543.     { "nop",   TN_NOP,   0 },
  3544.     { "sak",   TN_SAK,   CM_INV },
  3545.     { "sb",    SB,       0 },
  3546.     { "se",    SE,       0 },
  3547.     { "susp",  TN_SUSP,  0 },
  3548.     { "will",  WILL,     0 },
  3549.     { "wont",  WONT,     0 }
  3550. };
  3551. static int ntelcmd = (sizeof(telcmd) / sizeof(struct keytab));
  3552.  
  3553. static struct keytab tnopts[] = {
  3554. #ifdef CK_AUTHENTICATION
  3555.     { "auth",   TELOPT_AUTHENTICATION,   0 },
  3556. #else
  3557.     { "auth",   TELOPT_AUTHENTICATION,   CM_INV },
  3558. #endif /* CK_AUTHENTICATION */
  3559.     { "binary", TELOPT_BINARY, 0 },
  3560. #ifdef TN_COMPORT
  3561.     { "c",      TELOPT_COMPORT, CM_INV|CM_ABR},
  3562.     { "co",     TELOPT_COMPORT, CM_INV|CM_ABR},
  3563.     { "com",    TELOPT_COMPORT, CM_INV|CM_ABR},
  3564.     { "com-port-control", TELOPT_COMPORT, 0 },
  3565.     { "comport-control", TELOPT_COMPORT, CM_INV},
  3566. #else  /* TN_COMPORT */
  3567.     { "com-port-control", TELOPT_COMPORT, CM_INV },
  3568.     { "comport-control", TELOPT_COMPORT, CM_INV},
  3569. #endif /* TN_COMPORT */
  3570.     { "echo", TELOPT_ECHO, 0 },
  3571. #ifdef CK_ENCRYPTION
  3572.     { "encrypt", TELOPT_ENCRYPTION, 0 },
  3573. #else
  3574.     { "encrypt", TELOPT_ENCRYPTION, CM_INV },
  3575. #endif /* CK_ENCRYPTION */
  3576. #ifdef CK_FORWARD_X
  3577.     { "forward-x", TELOPT_FORWARD_X, 0 },
  3578. #else
  3579.     { "forward-x", TELOPT_FORWARD_X, CM_INV },
  3580. #endif /* CK_FORWARD_X */
  3581. #ifdef IKS_OPTION
  3582.     { "kermit", TELOPT_KERMIT, 0 },
  3583. #else
  3584.     { "kermit", TELOPT_KERMIT, CM_INV },
  3585. #endif /* IKS_OPTION */
  3586.     { "lflow",  TELOPT_LFLOW, CM_INV },
  3587.     { "logout", TELOPT_LOGOUT, CM_INV },
  3588. #ifdef CK_NAWS
  3589.     { "naws", TELOPT_NAWS, 0 },
  3590. #else
  3591.     { "naws", TELOPT_NAWS, CM_INV },
  3592. #endif /* CK_NAWS */
  3593. #ifdef CK_ENVIRONMENT
  3594.     { "new-environment", TELOPT_NEWENVIRON,  0 },
  3595. #else
  3596.     { "new-environment", TELOPT_NEWENVIRON,  CM_INV },
  3597. #endif /* CK_ENVIRONMENT */
  3598.     { "pragma-heartbeat",TELOPT_PRAGMA_HEARTBEAT,  CM_INV },
  3599.     { "pragma-logon",    TELOPT_PRAGMA_LOGON,  CM_INV },
  3600.     { "pragma-sspi",     TELOPT_SSPI_LOGON,  CM_INV },
  3601.     { "sak",   TELOPT_IBM_SAK, CM_INV },
  3602. #ifdef CK_SNDLOC
  3603.     { "send-location",   TELOPT_SNDLOC,  0 },
  3604. #else
  3605.     { "send-location",   TELOPT_SNDLOC,  CM_INV },
  3606. #endif /* CK_SNDLOC */
  3607.     { "sga", TELOPT_SGA, 0 },
  3608. #ifdef CK_SSL
  3609.     { "start-tls",       TELOPT_START_TLS,  0 },
  3610. #else
  3611.     { "start-tls",       TELOPT_START_TLS,  CM_INV },
  3612. #endif /* CK_SSL */
  3613.     { "ttype", TELOPT_TTYPE, 0 },
  3614. #ifdef CK_ENVIRONMENT
  3615.     { "xdisplay-location", TELOPT_XDISPLOC, 0 },
  3616. #else
  3617.     { "xdisplay-location", TELOPT_XDISPLOC, CM_INV },
  3618. #endif /* CK_ENVIRONMENT */
  3619.     { "", 0, 0 }
  3620. };
  3621. static int ntnopts = (sizeof(tnopts) / sizeof(struct keytab)) - 1;
  3622.  
  3623. static struct keytab tnsbopts[] = {
  3624. #ifdef CK_NAWS
  3625.     { "naws", TELOPT_NAWS, 0 },
  3626. #endif /* CK_NAWS */
  3627.     { "", 0, 0 }
  3628. };
  3629. static int ntnsbopts = (sizeof(tnsbopts) / sizeof(struct keytab)) - 1;
  3630. #endif /* TNCODE */
  3631.  
  3632. #ifdef TCPSOCKET
  3633. #ifndef NOPUSH
  3634. #ifdef SYSFTP
  3635. int
  3636. doftp() {                /* (External) FTP command */
  3637.     char *p, *f;            /* (See doxftp() for internal one) */
  3638.     int x;
  3639.  
  3640.     if (network)            /* If we have a current connection */
  3641.       ckstrncpy(line,ttname,LINBUFSIZ);    /* get the host name */
  3642.     else *line = '\0';            /* as default host */
  3643.     for (p = line; *p; p++)        /* Remove ":service" from end. */
  3644.       if (*p == ':') { *p = '\0'; break; }
  3645.     if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
  3646.       return(x);
  3647.     if (nopush) {
  3648.         printf("?Sorry, FTP command disabled\n");
  3649.         return(success = 0);
  3650.     }
  3651. /* Construct FTP command */
  3652. #ifdef VMS
  3653. #ifdef MULTINET                /* TGV MultiNet */
  3654.     ckmakmsg(line,LINBUFSIZ,"multinet ftp ",s,NULL,NULL);
  3655. #else
  3656.     ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
  3657. #endif /* MULTINET */
  3658. #else                    /* Not VMS */
  3659. #ifdef OS2ORUNIX
  3660. #ifndef NOFTP
  3661.     f = ftpapp;
  3662.     if (!f) f = "";
  3663.     if (!f[0]) f = "ftp";
  3664.     ckmakmsg(line,LINBUFSIZ,f," ",s,NULL);
  3665. #ifdef OS2
  3666.     p = line + strlen(ftpapp);
  3667.     while (p != line) {
  3668.         if (*p == '/') *p = '\\';
  3669.         p--;
  3670.     }
  3671. #endif /* OS2 */
  3672. #else /* NOFTP */
  3673.     ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
  3674. #endif /* NOFTP */
  3675. #else /* OS2ORUNIX */
  3676.     ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
  3677. #endif /* OS2ORUNIX */
  3678. #endif /* VMS */
  3679.     conres();                /* Make console normal  */
  3680. #ifdef DEC_TCPIP
  3681.     printf("\n");            /* Prevent prompt-stomping */
  3682. #endif /* DEC_TCPIP */
  3683.     x = zshcmd(line);
  3684.     concb((char)escape);
  3685.     return(success = x);
  3686. }
  3687. #endif /* SYSFTP */
  3688.  
  3689. int
  3690. doping() {                /* PING command */
  3691.     char *p;                /* just runs ping program */
  3692.     int x;
  3693.  
  3694.     if (network)            /* If we have a current connection */
  3695.       ckstrncpy(line,ttname,LINBUFSIZ);    /* get the host name */
  3696.     else *line = '\0';            /* as default host to be pinged. */
  3697.     for (p = line; *p; p++)        /* Remove ":service" from end. */
  3698.       if (*p == ':') { *p = '\0'; break; }
  3699.     if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
  3700.       return(x);
  3701.     if (nopush) {
  3702.         printf("?Sorry, PING command disabled\n");
  3703.         return(success = 0);
  3704.     }
  3705.  
  3706.     /* Construct PING command */
  3707. #ifdef VMS
  3708. #ifdef MULTINET                /* TGV MultiNet */
  3709.     ckmakmsg(line,LINBUFSIZ,"multinet ping ",s," /num=1",NULL);
  3710. #else
  3711.     ckmakmsg(line,LINBUFSIZ,"ping ",s," 56 1",NULL); /* Other VMS TCP/IP's */
  3712. #endif /* MULTINET */
  3713. #else                    /* Not VMS */
  3714.     ckmakmsg(line,LINBUFSIZ,"ping ",s,NULL,NULL);
  3715. #endif /* VMS */
  3716.     conres();                /* Make console normal  */
  3717. #ifdef DEC_TCPIP
  3718.     printf("\n");            /* Prevent prompt-stomping */
  3719. #endif /* DEC_TCPIP */
  3720.     x = zshcmd(line);
  3721.     concb((char)escape);
  3722.     return(success = x);
  3723. }
  3724. #endif /* NOPUSH */
  3725. #endif /* TCPSOCKET */
  3726.  
  3727. static VOID
  3728. doend(x) int x; {
  3729. #ifndef NOSPL
  3730.     /* Pop from all FOR/WHILE/XIF/SWITCH's */
  3731.     debug(F101,"doend maclvl 1","",maclvl);
  3732.     while ((maclvl > 0) &&
  3733.        (m_arg[maclvl-1][0]) &&
  3734.        (cmdstk[cmdlvl].src == CMD_MD) &&
  3735.        (!strncmp(m_arg[maclvl-1][0],"_xif",4) ||
  3736.         !strncmp(m_arg[maclvl-1][0],"_for",4) ||
  3737.         !strncmp(m_arg[maclvl-1][0],"_whi",4) ||
  3738.         !strncmp(m_arg[maclvl-1][0],"_swi",4))) {
  3739.     debug(F110,"END popping",m_arg[maclvl-1][0],0);
  3740.     dogta(XXPTA);            /* Put args back */
  3741.     popclvl();            /* Pop up two levels */
  3742.     popclvl();
  3743.     debug(F101,"doend maclvl 2","",maclvl);
  3744.     }
  3745.     if (maclvl > -1) {
  3746.     if (mrval[maclvl])        /* Free previous retval if any */
  3747.       free(mrval[maclvl]);
  3748.     mrval[maclvl] = malloc(16);    /* Room for up to 15 digits */
  3749.     if (mrval[maclvl])        /* Record current retval */
  3750.       ckmakmsg(mrval[maclvl],16,ckitoa(x),NULL,NULL,NULL);
  3751.     }
  3752. #endif /* NOSPL */
  3753.     popclvl();                /* Now pop out of macro or TAKE file */
  3754. #ifndef NOSPL
  3755. #ifdef DEBUG
  3756.     if (deblog) {
  3757.     debug(F101,"END maclvl 3","",maclvl);
  3758.     debug(F111,"END mrval[maclvl]",mrval[maclvl],maclvl);
  3759.     debug(F111,"END mrval[maclvl+1]",mrval[maclvl+1],maclvl+1);
  3760.     }
  3761. #endif /* DEBUG */
  3762. #endif /* NOSPL */
  3763. }
  3764.  
  3765. #ifdef CKROOT
  3766. int
  3767. dochroot() {
  3768.     if ((x = cmdir("Name of new root directory","",&s,xxstring)) < 0) {
  3769.     if (x == -3) {
  3770.         printf("?Directory name required\n");
  3771.         return(-9);
  3772.     }
  3773.     return(x);
  3774.     }
  3775.     ckstrncpy(line,s,LINBUFSIZ);
  3776.     s = line;
  3777.     if ((x = cmcfm()) < 0) return(x);
  3778.     s = brstrip(s);
  3779.     x = zsetroot(s);
  3780.     if (x < 0) {
  3781.     char * m = NULL;
  3782.     switch (x) {
  3783.       case -1:
  3784.       case -2: m = "Not a directory"; break;
  3785.       case -3: m = "Internal error"; break;
  3786.       case -4: m = "Access denied"; break;
  3787.       case -5: m = "Off limits"; break;
  3788.     }
  3789.     if (m) printf("%s: \"%s\"\n", m, s);
  3790.     return(m ? -9 : -2);
  3791.     } else {
  3792.     nopush = 1;
  3793.     return(success = 1);
  3794.     }
  3795. }
  3796. #endif /* CKROOT */
  3797.  
  3798. #ifndef NOXFER
  3799. static char * asnbuf = NULL;        /* As-name buffer pointer */
  3800.  
  3801. char sndxnam[] = { "_array_x_" };    /* (with replaceable x!) */
  3802.  
  3803. /*
  3804.   The new SEND command, replacing BSEND, CSEND, PSEND, etc etc.
  3805.   Call with cx = top-level keyword value.  Returns:
  3806.     < 0  On parse error.
  3807.     0    On other type of failure (e.g. requested operation not allowed).
  3808.     1    On success with sstate set to 's' so protocol will begin.
  3809. */
  3810.  
  3811. /*  D O X S E N D  --  Parse SEND and related commands with switches  */
  3812.  
  3813. int
  3814. doxsend(cx) int cx; {
  3815.     int c, i, n, wild, confirmed = 0;    /* Workers */
  3816.     int x, y;                /* of the world... */
  3817.     int getval = 0;            /* Whether to get switch value */
  3818.     extern char * snd_move;        /* Directory to move sent files to */
  3819.     extern char * snd_rename;        /* What to rename sent files to */
  3820.     extern char * filefile;        /* File containing filenames to send */
  3821.     extern int xfiletype;        /* Send only text (or binary) files */
  3822.     extern struct keytab pathtab[];    /* PATHNAMES option keywords */
  3823.     extern int npathtab;        /* How many of them */
  3824.     extern int recursive;        /* Recursive directory traversal */
  3825.     extern int rprintf;            /* REMOTE PRINT flag */
  3826.     extern int fdispla;            /* TRANSFER DISPLAY setting */
  3827.     extern int skipbup;            /* Skip backup files when sending */
  3828.     struct stringint {            /* Temporary array for switch values */
  3829.     char * sval;
  3830.     int ival;
  3831.     } pv[SND_MAX+1];
  3832.     struct FDB sf, sw, fl, cm;        /* FDBs for each parse function */
  3833.     int mlist = 0;            /* Flag for MSEND or MMOVE */
  3834.     char * m;                /* For making help messages */
  3835.     extern struct keytab protos[];    /* File transfer protocols */
  3836.     extern int xfrxla, g_xfrxla, nprotos;
  3837.     extern char sndbefore[], sndafter[], *sndexcept[]; /* Selection criteria */
  3838.     extern char sndnbefore[], sndnafter[];
  3839.     extern long sndsmaller, sndlarger, calibrate;
  3840. #ifndef NOSPL
  3841.     int range[2];            /* Array range */
  3842.     char ** ap = NULL;            /* Array pointer */
  3843.     int arrayx = -1;            /* Array index */
  3844. #endif /* NOSPL */
  3845.  
  3846. #ifdef NEWFTP
  3847.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) {
  3848.     if (cx == XXMAI) {
  3849.         printf("?Sorry, No MAIL with FTP\n");
  3850.         return(-9);
  3851.     }
  3852.     return(doftpput(cx,0));
  3853.     }
  3854. #endif /* NEWFTP */
  3855.  
  3856.     for (i = 0; i <= SND_MAX; i++) {    /* Initialize switch values */
  3857.     pv[i].sval = NULL;        /* to null pointers */
  3858.     pv[i].ival = -1;        /* and -1 int values */
  3859.     }
  3860. #ifndef NOSPL
  3861.     range[0] = -1;
  3862.     range[1] = -1;
  3863.     sndxin = -1;            /* Array index */
  3864. #endif /* NOSPL */
  3865.     sndarray = NULL;            /* Array pointer */
  3866.  
  3867. #ifdef UNIXOROSK
  3868.     g_matchdot = matchdot;        /* Match dot files */
  3869. #endif /* UNIXOROSK */
  3870.     g_recursive = recursive;        /* Recursive sending */
  3871.     recursive = 0;            /* Save global value, set local */
  3872.     debug(F101,"xsend entry fncnv","",fncnv);
  3873.  
  3874.     /* Preset switch values based on top-level command that called us */
  3875.  
  3876.     switch (cx) {
  3877.       case XXMSE:            /* MSEND */
  3878.     mlist = 1; break;
  3879.       case XXCSEN:            /* CSEND */
  3880.     pv[SND_CMD].ival = 1; break;
  3881.       case XXMMOVE:            /* MMOVE */
  3882.     mlist = 1;
  3883.       case XXMOVE:            /* MOVE */
  3884.     pv[SND_DEL].ival = 1; break;
  3885.       case XXRSEN:            /* RESEND */
  3886.     pv[SND_BIN].ival = 1;        /* Implies /BINARY */
  3887.     pv[SND_RES].ival = 1; break;
  3888.       case XXMAI:            /* MAIL */
  3889.     pv[SND_MAI].ival = 1; break;
  3890.     }
  3891.  
  3892.     /* Set up chained parse functions... */
  3893.  
  3894.     cmfdbi(&sw,                /* First FDB - command switches */
  3895.        _CMKEY,            /* fcode */
  3896.        "Filename, or switch",    /* hlpmsg */
  3897.        "",                /* default */
  3898.        "",                /* addtl string data */
  3899. #ifdef NOMSEND
  3900.        nsndtab,            /* addtl numeric data 1: tbl size */
  3901. #else
  3902.        mlist ? nmsndtab : nsndtab,    /* addtl numeric data 1: tbl size */
  3903. #endif /* NOMSEND */
  3904.        4,                /* addtl numeric data 2: 4 = cmswi */
  3905.        xxstring,            /* Processing function */
  3906. #ifdef NOMSEND
  3907.        sndtab,            /* Keyword table */
  3908. #else
  3909.        mlist ? msndtab : sndtab,
  3910. #endif /* NOMSEND */
  3911.        &sf                /* Pointer to next FDB */
  3912.        );
  3913.     cmfdbi(&sf,                /* 2nd FDB - file to send */
  3914.        _CMIFI,            /* fcode */
  3915.        "File(s) to send",        /* hlpmsg */
  3916.        "",                /* default */
  3917.        "",                /* addtl string data */
  3918.        nolinks,            /* addtl numeric data 1 */
  3919.        0,                /* addtl numeric data 2 */
  3920.        xxstring,
  3921.        NULL,
  3922.        mlist ? &cm : &fl
  3923.        );
  3924.     cmfdbi(&fl,                /* 3rd FDB - command to send from */
  3925.        _CMFLD,            /* fcode */
  3926.        "Command",            /* hlpmsg */
  3927.        "",                /* default */
  3928.        "",                /* addtl string data */
  3929.        0,                /* addtl numeric data 1 */
  3930.        0,                /* addtl numeric data 2 */
  3931.        xxstring,
  3932.        NULL,
  3933.        &cm
  3934.        );
  3935.     cmfdbi(&cm,                /* 4th FDB - Confirmation */
  3936.        _CMCFM,            /* fcode */
  3937.        "",                /* hlpmsg */
  3938.        "",                /* default */
  3939.        "",                /* addtl string data */
  3940.        0,                /* addtl numeric data 1 */
  3941.        0,                /* addtl numeric data 2 */
  3942.        NULL,
  3943.        NULL,
  3944.        NULL
  3945.        );
  3946.  
  3947.     while (1) {                /* Parse 0 or more switches */
  3948.     x = cmfdb(&sw);            /* Parse something */
  3949.     debug(F101,"xsend cmfdb","",x);
  3950.     if (x < 0)            /* Error */
  3951.       goto xsendx;            /* or reparse needed */
  3952.     if (cmresult.fcode != _CMKEY)    /* Break out if not a switch */
  3953.       break;
  3954. /*
  3955.   They gave a switch, but let's see how they terminated it.
  3956.   If they ended it with : or =, then we must parse a value.
  3957.   If they ended it with anything else, then we must NOT parse a value.
  3958. */
  3959.     c = cmgbrk();            /* Get break character */
  3960.     getval = (c == ':' || c == '='); /* to see how they ended the switch */
  3961.     if (getval && !(cmresult.kflags & CM_ARG)) {
  3962.         printf("?This switch does not take arguments\n");
  3963.         x = -9;
  3964.         goto xsendx;
  3965.     }
  3966.     if (!getval && (cmgkwflgs() & CM_ARG)) {
  3967.         printf("?This switch requires an argument\n");
  3968.         x = -9;
  3969.         goto xsendx;
  3970.     }
  3971.     n = cmresult.nresult;        /* Numeric result = switch value */
  3972.     debug(F101,"xsend switch","",n);
  3973.  
  3974.     switch (n) {            /* Process the switch */
  3975.       case SND_CMD:            /* These take no args */
  3976.         if (nopush) {
  3977.         printf("?Sorry, system command access is disabled\n");
  3978.         x = -9;
  3979.         goto xsendx;
  3980.         }
  3981. #ifdef PIPESEND
  3982.         else if (sndfilter) {
  3983.         printf(
  3984. "?Sorry, no SEND /COMMAND or CSEND when SEND FILTER selected\n");
  3985.         x = -9;
  3986.         goto xsendx;
  3987.         }
  3988. #endif /* PIPESEND */
  3989.         sw.hlpmsg = "Command, or switch"; /* Change help message */
  3990.         pv[n].ival = 1;        /* Just set the flag */
  3991.         pv[SND_ARR].ival = 0;
  3992.         break;
  3993.  
  3994.       case SND_REC:            /* /RECURSIVE */
  3995.         recursive = 2;        /* Set the real variable */
  3996.         pv[SND_PTH].ival = PATH_REL; /* Give them relative pathnames */
  3997.         pv[n].ival = 1;        /* Just set the flag */
  3998.         break;
  3999.  
  4000.       case SND_RES:            /* /RECOVER (resend) */
  4001.         pv[SND_ARR].ival = 0;
  4002.         pv[SND_BIN].ival = 1;    /* Implies /BINARY */
  4003.       case SND_NOB:            /* /NOBACKUP */
  4004.       case SND_DEL:            /* /DELETE */
  4005.       case SND_SHH:            /* /QUIET */
  4006.         pv[n].ival = 1;        /* Just set the flag */
  4007.         break;
  4008.  
  4009. #ifdef UNIXOROSK
  4010. /* Like recursive, these are set immediately because they affect cmifi() */
  4011.       case SND_DOT:            /* /DOTFILES */
  4012.         matchdot = 1;
  4013.         break;
  4014.       case SND_NOD:            /* /NODOTFILES */
  4015.         matchdot = 0;
  4016.         break;
  4017. #endif /* UNIXOROSK */
  4018.  
  4019.       /* File transfer modes - each undoes the others */
  4020.  
  4021.       case SND_BIN:            /* Binary */
  4022.       case SND_TXT:            /* Text */
  4023.       case SND_IMG:            /* Image */
  4024.       case SND_LBL:            /* Labeled */
  4025.         pv[SND_BIN].ival = 0;
  4026.         pv[SND_TXT].ival = 0;
  4027.         pv[SND_IMG].ival = 0;
  4028.         pv[SND_LBL].ival = 0;
  4029.         pv[n].ival = 1;
  4030.         break;
  4031.  
  4032. #ifdef CKSYMLINK
  4033.       case SND_LNK:
  4034.       case SND_NLK:
  4035.         nolinks = (n == SND_NLK) ? 2 : 0;
  4036.         cmfdbi(&sf,            /* Redo cmifi() */
  4037.            _CMIFI,        /* fcode */
  4038.            "File(s) to send",    /* hlpmsg */
  4039.            "",            /* default */
  4040.            "",            /* addtl string data */
  4041.            nolinks,        /* addtl numeric data 1 */
  4042.            0,            /* addtl numeric data 2 */
  4043.            xxstring,
  4044.            NULL,
  4045.            mlist ? &cm : &fl
  4046.            );
  4047.         break;
  4048. #endif /* CKSYMLINK */
  4049.  
  4050.       case SND_EXC:            /* Excludes */
  4051.         if (!getval) break;
  4052.         if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
  4053.         if (x == -3) {
  4054.             printf("?Pattern required\n");
  4055.             x = -9;
  4056.         }
  4057.         goto xsendx;
  4058.         }
  4059.         if (pv[n].sval) free(pv[n].sval);
  4060.         y = strlen(s);
  4061.         if (y > 256) {
  4062.         printf("?Pattern too long - 256 max\n");
  4063.         x = -9;
  4064.         goto xsendx;
  4065.         }
  4066.         pv[n].sval = malloc(y+1);
  4067.         if (pv[n].sval) {
  4068.         strcpy(pv[n].sval,s);    /* safe */
  4069.         pv[n].ival = 1;
  4070.         }
  4071.         break;
  4072.  
  4073.       case SND_MOV:            /* MOVE after */
  4074.       case SND_REN:            /* RENAME after */
  4075.         if (!getval) break;
  4076.         if ((x = cmfld(n == SND_MOV ?
  4077.        "device and/or directory for source file after sending" :
  4078.        "new name for source file after sending",
  4079.                "",
  4080.                &s,
  4081.                n == SND_MOV ? xxstring : NULL
  4082.                )) < 0) {
  4083.         if (x == -3) {
  4084.             printf("%s\n", n == SND_MOV ?
  4085.                "?Destination required" :
  4086.                "?New name required"
  4087.                );
  4088.             x = -9;
  4089.         }
  4090.         goto xsendx;
  4091.         }
  4092.         if (pv[n].sval) free(pv[n].sval);
  4093.         s = brstrip(s);
  4094.         y = strlen(s);
  4095.         if (y > 0) {
  4096.         pv[n].sval = malloc(y+1);
  4097.         if (pv[n].sval) {
  4098.             strcpy(pv[n].sval,s); /* safe */
  4099.             pv[n].ival = 1;
  4100.         }
  4101.         }
  4102.         break;
  4103.  
  4104.       case SND_SMA:            /* Smaller / larger than */
  4105.       case SND_LAR:
  4106.         if (!getval) break;
  4107.         if ((x = cmnum("Size in bytes","0",10,&y,xxstring)) < 0)
  4108.           goto xsendx;
  4109.         pv[n].ival = y;
  4110.         break;
  4111.  
  4112.       case SND_AFT:            /* Send /AFTER:date-time */
  4113.       case SND_BEF:            /* Send /BEFORE:date-time */
  4114.       case SND_NAF:            /* Send /NOT-AFTER:date-time */
  4115.       case SND_NBE:            /* Send /NOT-BEFORE:date-time */
  4116.         if (!getval) break;
  4117.         if ((x = cmdate("File date-time","",&s,0,xxstring)) < 0) {
  4118.         if (x == -3) {
  4119.             printf("?Date-time required\n");
  4120.             x = -9;
  4121.         }
  4122.         goto xsendx;
  4123.         }
  4124.         if (pv[n].sval) free(pv[n].sval);
  4125.         pv[n].sval = malloc((int)strlen(s)+1);
  4126.         if (pv[n].sval) {
  4127.         strcpy(pv[n].sval,s);    /* safe */
  4128.         pv[n].ival = 1;
  4129.         }
  4130.         break;
  4131.  
  4132.       case SND_MAI:            /* Send as mail (= MAIL) */
  4133. #ifdef IKSD
  4134.         if (inserver && !ENABLED(en_mai)) {
  4135.         printf("?Sorry, sending files as mail is disabled\n");
  4136.         return(-9);
  4137.         }
  4138. #endif /* IKSD */
  4139.         pv[n].ival = 1;
  4140.         if (!getval) break;
  4141.         if ((x = cmfld("e-mail address","",&s,xxstring)) < 0) {
  4142.         if (x == -3) {
  4143.             printf("?address required\n");
  4144.             x = -9;
  4145.         }
  4146.         goto xsendx;
  4147.         }
  4148.         s = brstrip(s);
  4149.         if (pv[n].sval) free(pv[n].sval);
  4150.         pv[n].sval = malloc((int)strlen(s)+1);
  4151.         if (pv[n].sval)
  4152.           strcpy(pv[n].sval,s);    /* safe */
  4153.         break;
  4154.  
  4155.       case SND_PRI:            /* Send to be printed (REMOTE PRINT) */
  4156. #ifdef IKSD
  4157.         if (inserver && !ENABLED(en_mai)) {
  4158.         printf("?Sorry, sending files for printing is disabled\n");
  4159.         return(-9);
  4160.         }
  4161. #endif /* IKSD */
  4162.         pv[n].ival = 1;
  4163.         if (!getval) break;
  4164.         if ((x = cmfld("Print options","",&s,xxstring)) < 0)
  4165.           if (x != -3) goto xsendx;
  4166.         s = brstrip(s);
  4167.         if (pv[n].sval) free(pv[n].sval);
  4168.         pv[n].sval = malloc((int)strlen(s)+1);
  4169.         if (pv[n].sval)
  4170.           strcpy(pv[n].sval,s);    /* safe */
  4171.         break;
  4172.  
  4173.       case SND_ASN:            /* As-name */
  4174.         debug(F101,"xsend /as-name getval","",getval);
  4175.         if (!getval) break;
  4176.         if ((x = cmfld("Name to send under","",&s,NULL)) < 0) {
  4177.         if (x == -3) {
  4178.             printf("?name required\n");
  4179.             x = -9;
  4180.         }
  4181.         goto xsendx;
  4182.         }
  4183.         s = brstrip(s);
  4184.         if ((y = strlen(s)) > 0) {
  4185.         if (pv[n].sval) free(pv[n].sval);
  4186.         pv[n].sval = malloc(y+1);
  4187.         if (pv[n].sval) {
  4188.             strcpy(pv[n].sval,s); /* safe */
  4189.             pv[n].ival = 1;
  4190.         }
  4191.         }
  4192.         break;
  4193.  
  4194.       case SND_STA:            /* Starting position (= PSEND) */
  4195.         if (!getval) break;
  4196.         if ((x = cmnum("0-based position","0",10,&y,xxstring)) < 0)
  4197.           goto xsendx;
  4198.         pv[n].ival = y;
  4199.         break;
  4200.  
  4201.       case SND_PRO:            /* Protocol to use */
  4202.         if (!getval) break;
  4203.         if ((x = cmkey(protos,nprotos,"File-transfer protocol","",
  4204.                xxstring)) < 0) {
  4205.         if (x == -3) {
  4206.             printf("?name of protocol required\n");
  4207.             x = -9;
  4208.         }
  4209.         goto xsendx;
  4210.         }
  4211.         pv[n].ival = x;
  4212.         break;
  4213.  
  4214. #ifdef PIPESEND
  4215.       case SND_FLT:            /* Filter */
  4216.         debug(F101,"xsend /filter getval","",getval);
  4217.         if (!getval) break;
  4218.         if ((x = cmfld("Filter program to send through","",&s,NULL)) < 0) {
  4219.         if (x == -3)
  4220.           s = "";
  4221.         else
  4222.           goto xsendx;
  4223.         }
  4224.         if (*s) s = brstrip(s);
  4225.         y = strlen(s);
  4226.         for (x = 0; x < y; x++) {    /* Make sure they included "\v(...)" */
  4227.         if (s[x] != '\\') continue;
  4228.         if (s[x+1] == 'v') break;
  4229.         }
  4230.         if (x == y) {
  4231.         printf(
  4232.         "?Filter must contain a replacement variable for filename.\n"
  4233.                );
  4234.         x = -9;
  4235.         goto xsendx;
  4236.         }
  4237.         pv[n].ival = 1;
  4238.         if (pv[n].sval) {
  4239.         free(pv[n].sval);
  4240.         pv[n].sval = NULL;
  4241.         }
  4242.         if ((y = strlen(s)) > 0) {
  4243.         if ((pv[n].sval = malloc(y+1)))
  4244.           strcpy(pv[n].sval,s);    /* safe */
  4245.         }
  4246.         break;
  4247. #endif /* PIPESEND */
  4248.  
  4249.       case SND_PTH:            /* Pathnames */
  4250.         if (!getval) {
  4251.         pv[n].ival = PATH_REL;
  4252.         break;
  4253.         }
  4254.         if ((x = cmkey(pathtab,npathtab,"","absolute",xxstring)) < 0)
  4255.           goto xsendx;
  4256.         pv[n].ival = x;
  4257.         break;
  4258.  
  4259.       case SND_NAM:            /* Filenames */
  4260.         if (!getval) break;
  4261.         if ((x = cmkey(fntab,nfntab,"","converted",xxstring)) < 0)
  4262.           goto xsendx;
  4263.         debug(F101,"xsend /filenames","",x);
  4264.         pv[n].ival = x;
  4265.         break;
  4266.  
  4267. #ifdef CALIBRATE
  4268.           case SND_CAL:            /* /CALIBRATE */
  4269.         if (getval) {
  4270.         if ((x = cmnum("number of Kbytes to send",
  4271.                "1024",10,&y,xxstring)) < 0)
  4272.           goto xsendx;
  4273.         } else
  4274.           y = 1024;
  4275.         pv[n].ival = y;
  4276.         pv[SND_ARR].ival = 0;
  4277.         break;
  4278. #endif /* CALIBRATE */
  4279.  
  4280.       case SND_FIL:            /* Name of file containing filnames */
  4281.         if (!getval) break;
  4282.         if ((x = cmifi("Name of file containing list of filenames",
  4283.                    "",&s,&y,xxstring)) < 0) {
  4284.         if (x == -3) {
  4285.             printf("?Filename required\n");
  4286.             x = -9;
  4287.         }
  4288.         goto xsendx;
  4289.         } else if (y) {
  4290.         printf("?Wildcards not allowed\n");
  4291.         x = -9;
  4292.         goto xsendx;
  4293.         }
  4294.         if (pv[n].sval)
  4295.           free(pv[n].sval);
  4296.         if (s) if (*s) {
  4297.         if ((pv[n].sval = malloc((int)strlen(s)+1))) {
  4298.             strcpy(pv[n].sval,s);
  4299.             pv[n].ival = 1;
  4300.             pv[SND_ARR].ival = 0;
  4301.         }
  4302.         }
  4303.         break;
  4304.  
  4305. #ifndef NOSPL
  4306.       case SND_ARR:            /* SEND /ARRAY: */
  4307.         if (!getval) break;
  4308.         ap = NULL;
  4309.         if ((x = cmfld("Array name (a single letter will do)",
  4310.                "",
  4311.                &s,
  4312.                NULL
  4313.                )) < 0) {
  4314.         if (x == -3)
  4315.           break;
  4316.         else
  4317.           return(x);
  4318.         }
  4319.         if ((x = arraybounds(s,&(range[0]),&(range[1]))) < 0) {
  4320.         printf("?Bad array: %s\n",s);
  4321.         return(-9);
  4322.         }
  4323.         if (!(ap = a_ptr[x])) {
  4324.         printf("?No such array: %s\n",s);
  4325.         return(-9);
  4326.         }
  4327.         pv[n].ival = 1;
  4328.         pv[SND_CMD].ival = 0;    /* Undo any conflicting ones... */
  4329.         pv[SND_RES].ival = 0;
  4330.         pv[SND_CAL].ival = 0;
  4331.         pv[SND_FIL].ival = 0;
  4332.         arrayx = x;
  4333.         break;
  4334. #endif /* NOSPL */
  4335.  
  4336.       case SND_XPA:            /* /TRANSPARENT */
  4337.         pv[n].ival = 1;
  4338.         break;
  4339.  
  4340.       case SND_TYP:            /* Only files of given type */
  4341.         if (!getval) break;
  4342.         if ((x = cmkey(txtbin,3,"","all",xxstring)) < 0)
  4343.           goto xsendx;
  4344.         pv[n].ival = (x == 2) ? -1 : x;
  4345.         break;
  4346.  
  4347.       default:
  4348.         printf("?Unexpected switch value - %d\n",cmresult.nresult);
  4349.         x = -9;
  4350.         goto xsendx;
  4351.     }
  4352.     }
  4353.     debug(F101,"xsend cmresult fcode","",cmresult.fcode);
  4354.  
  4355. #ifdef COMMENT
  4356.     /* List switch parsing results in debug log */
  4357.     for (i = 0; i <= SND_MAX; i++) {
  4358.     ckmakmsg(line,LINBUFSIZ,"xsend switch ",ckitoa(i),NULL,NULL);
  4359.     debug(F111,line, pv[i].sval, pv[i].ival);
  4360.     }
  4361. #endif /* COMMENT */
  4362.  
  4363. /* Now we have all switches, plus maybe a filename or command, or nothing */
  4364.  
  4365. #ifdef PIPESEND
  4366.     if (protocol != PROTO_K && pv[SND_CMD].ival > 0) {
  4367.     printf("?Sorry, %s works only with Kermit protocol\n",
  4368.            (cx == XXCSEN) ? "CSEND" : "SEND /COMMAND");
  4369.     x = -9;
  4370.     goto xsendx;
  4371.     }
  4372.     if (pv[SND_RES].ival > 0 ||    /* /RECOVER */
  4373.     pv[SND_STA].ival > 0) {    /* or /STARTING */
  4374.     if (sndfilter || pv[SND_FLT].ival > 0) {
  4375.         printf("?Sorry, no /RECOVER or /START if SEND FILTER selected\n");
  4376.         x = -9;
  4377.         goto xsendx;
  4378.     }
  4379.     }
  4380. #endif /* PIPESEND */
  4381.  
  4382.     cmarg = "";
  4383.     cmarg2 = "";
  4384.     line[0] = NUL;
  4385.     s = line;
  4386.     wild = 0;
  4387.  
  4388.     switch (cmresult.fcode) {        /* How did we get out of switch loop */
  4389.       case _CMIFI:            /* Input filename */
  4390.     ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Name */
  4391.     if (pv[SND_ARR].ival > 0)
  4392.       cmarg2 = line;
  4393.     else
  4394.       wild = cmresult.nresult;    /* Wild flag */
  4395.     if (!recursive && !wild)
  4396.       nolinks = 0;
  4397.     break;
  4398.       case _CMFLD:            /* Field */
  4399.     /* Only allowed with /COMMAND and /ARRAY */
  4400.     if (pv[SND_CMD].ival < 1 && pv[SND_ARR].ival < 1) {
  4401. #ifdef CKROOT
  4402.         if (ckrooterr)
  4403.           printf("?Off limits: %s\n",cmresult.sresult);
  4404.         else
  4405. #endif /* CKROOT */
  4406.           printf("?%s - \"%s\"\n",
  4407.            iswild(cmresult.sresult) ?
  4408.            "No files match" : "File not found",
  4409.            cmresult.sresult
  4410.            );
  4411.         x = -9;
  4412.         goto xsendx;
  4413.     }
  4414.     ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  4415.     if (pv[SND_ARR].ival > 0)
  4416.       cmarg2 = line;
  4417.     break;
  4418.       case _CMCFM:            /* Confirmation */
  4419.     /* s = ""; */
  4420.     confirmed = 1;
  4421.     break;
  4422.       default:
  4423.     printf("?Unexpected function code: %d\n",cmresult.fcode);
  4424.     x = -9;
  4425.     goto xsendx;
  4426.     }
  4427.     debug(F110,"xsend string",s,0);
  4428.     debug(F101,"xsend confirmed","",confirmed);
  4429.  
  4430.     /* Save and change protocol and transfer mode */
  4431.     /* Global values are restored in main parse loop */
  4432.  
  4433.     g_proto = protocol;            /* Save current global protocol */
  4434.     g_urpsiz = urpsiz;
  4435.     g_spsizf = spsizf;
  4436.     g_spsiz = spsiz;
  4437.     g_spsizr = spsizr;
  4438.     g_spmax = spmax;
  4439.     g_wslotr = wslotr;
  4440.     g_prefixing = prefixing;
  4441.     g_fncact = fncact;
  4442.     g_fncnv = fncnv;
  4443.     g_fnspath = fnspath;
  4444.     g_fnrpath = fnrpath;
  4445.     g_xfrxla = xfrxla;
  4446.  
  4447.     if (pv[SND_PRO].ival > -1) {    /* Change according to switch */
  4448.     protocol = pv[SND_PRO].ival;
  4449.         if (ptab[protocol].rpktlen > -1) /* copied from initproto() */
  4450.             urpsiz = ptab[protocol].rpktlen;
  4451.         if (ptab[protocol].spktflg > -1)
  4452.             spsizf = ptab[protocol].spktflg;
  4453.         if (ptab[protocol].spktlen > -1) {
  4454.             spsiz = ptab[protocol].spktlen;
  4455.             if (spsizf)
  4456.           spsizr = spmax = spsiz;
  4457.         }
  4458.         if (ptab[protocol].winsize > -1)
  4459.             wslotr = ptab[protocol].winsize;
  4460.         if (ptab[protocol].prefix > -1)
  4461.             prefixing = ptab[protocol].prefix;
  4462.         if (ptab[protocol].fnca > -1)
  4463.             fncact  = ptab[protocol].fnca;
  4464.         if (ptab[protocol].fncn > -1)
  4465.             fncnv   = ptab[protocol].fncn;
  4466.         if (ptab[protocol].fnsp > -1)
  4467.             fnspath = ptab[protocol].fnsp;
  4468.         if (ptab[protocol].fnrp > -1)
  4469.             fnrpath = ptab[protocol].fnrp;
  4470.     }
  4471.     debug(F101,"xsend protocol","",protocol);
  4472.  
  4473.     if (pv[SND_NOB].ival > -1) {    /* /NOBACKUP (skip backup file) */
  4474.     g_skipbup = skipbup;
  4475.     skipbup = 1;
  4476.     }
  4477.     if (pv[SND_REC].ival > 0)        /* /RECURSIVE */
  4478.       recursive = 2;
  4479.  
  4480.     if (pv[SND_TYP].ival > -1) {    /* /TYPE */
  4481.     xfiletype = pv[SND_TYP].ival;
  4482.     if (xfiletype == 2)
  4483.       xfiletype = -1;
  4484.     }
  4485.     g_binary = binary;            /* Save global transfer mode */
  4486. #ifdef PATTERNS
  4487.     g_patterns = patterns;        /* Save FILE PATTERNS setting */
  4488. #endif /* PATTERNS */
  4489.     if (pv[SND_BIN].ival > 0) {        /* Change according to switch */
  4490.     /* If they said /BINARY they mean /BINARY */
  4491.     patterns = 0;            /* So no pattern-based switching */
  4492.     g_xfermode = xfermode;        /* or automatic transfer mode */
  4493.     xfermode = XMODE_M;
  4494.     binary = XYFT_B;
  4495.     debug(F101,"doxsend /BINARY xfermode","",xfermode);
  4496.     } else if (pv[SND_TXT].ival > 0) {    /* Ditto for /TEXT */
  4497.     patterns = 0;
  4498.     g_xfermode = xfermode;
  4499.     xfermode = XMODE_M;
  4500.     binary = XYFT_T;
  4501.     debug(F101,"doxsend /TEXT xfermode","",xfermode);
  4502.     } else if (pv[SND_IMG].ival > 0) {
  4503. #ifdef VMS
  4504.     binary = XYFT_I;
  4505. #else
  4506.     binary = XYFT_B;
  4507. #endif /* VMS */
  4508.     }
  4509. #ifdef CK_LABELED
  4510.     else if (pv[SND_LBL].ival > 0) {
  4511.     binary = XYFT_L;
  4512.     }
  4513. #endif /* CK_LABELED */
  4514.     debug(F101,"xsend binary","",binary);
  4515.  
  4516.     if (pv[SND_XPA].ival > 0)        /* /TRANSPARENT */
  4517.       xfrxla = 0;            /* Don't translate character sets */
  4518.  
  4519.     /* Check for legal combinations of switches, filenames, etc */
  4520.  
  4521. #ifdef PIPESEND
  4522.     if (pv[SND_CMD].ival > 0) {    /* COMMAND - strip any braces */
  4523.     debug(F110,"SEND /COMMAND before stripping",s,0);
  4524.     s = brstrip(s);
  4525.     debug(F110,"SEND /COMMAND after stripping",s,0);
  4526.     if (!*s) {
  4527.         printf("?Sorry, a command to send from is required\n");
  4528.         x = -9;
  4529.         goto xsendx;
  4530.     }
  4531.     cmarg = s;
  4532.     }
  4533. #endif /* PIPESEND */
  4534.  
  4535. /* Set up /MOVE and /RENAME */
  4536.  
  4537.     if (pv[SND_DEL].ival > 0 &&
  4538.     (pv[SND_MOV].ival > 0 || pv[SND_REN].ival > 0)) {
  4539.     printf("?Sorry, /DELETE conflicts with /MOVE or /RENAME\n");
  4540.     x = -9;
  4541.     goto xsendx;
  4542.     }
  4543. #ifdef CK_TMPDIR
  4544.     if (pv[SND_MOV].ival > 0) {
  4545.     int len;
  4546.     char * p = pv[SND_MOV].sval;
  4547. #ifdef CK_LOGIN
  4548.     if (isguest) {
  4549.         printf("?Sorry, /MOVE-TO not available to guests\n");
  4550.         x = -9;
  4551.         goto xsendx;
  4552.     }
  4553. #endif /* CK_LOGIN */
  4554.     len = strlen(p);
  4555.     if (!isdir(p)) {        /* Check directory */
  4556. #ifdef CK_MKDIR
  4557.         char * s = NULL;
  4558.         s = (char *)malloc(len + 4);
  4559.         if (s) {
  4560.         strcpy(s,p);        /* safe */
  4561. #ifdef datageneral
  4562.         if (s[len-1] != ':') { s[len++] = ':'; s[len] = NUL; }
  4563. #else
  4564.         if (s[len-1] != '/') { s[len++] = '/'; s[len] = NUL; }
  4565. #endif /* datageneral */
  4566.         s[len++] = 'X';
  4567.         s[len] = NUL;
  4568.         x = zmkdir(s);
  4569.         free(s);
  4570.         if (x < 0) {
  4571.             printf("?Can't create \"%s\"\n",p);
  4572.             x = -9;
  4573.             goto xsendx;
  4574.         }
  4575.         }
  4576. #else
  4577.         printf("?Directory \"%s\" not found\n",p);
  4578.         x = -9;
  4579.         goto xsendx;
  4580. #endif /* CK_MKDIR */
  4581.     }
  4582.         zfnqfp(p,LINBUFSIZ,line);
  4583.     makestr(&snd_move,line);
  4584.     }
  4585. #endif /* CK_TMPDIR */
  4586.  
  4587.     if (pv[SND_REN].ival > 0) {        /* /RENAME */
  4588.     char * p = pv[SND_REN].sval;
  4589. #ifdef CK_LOGIN
  4590.     if (isguest) {
  4591.         printf("?Sorry, /RENAME-TO not available to guests\n");
  4592.         x = -9;
  4593.         goto xsendx;
  4594.     }
  4595. #endif /* CK_LOGIN */
  4596.     if (!p) p = "";
  4597.     if (!*p) {
  4598.         printf("?New name required for /RENAME\n");
  4599.         x = -9;
  4600.         goto xsendx;
  4601.     }
  4602.     p = brstrip(p);
  4603. #ifndef NOSPL
  4604.     /* If name given is wild, rename string must contain variables */
  4605.     if (wild) {
  4606.         char * s = tmpbuf;
  4607.         x = TMPBUFSIZ;
  4608.         zzstring(p,&s,&x);
  4609.         if (!strcmp(tmpbuf,p)) {
  4610.         printf(
  4611.     "?/RENAME for file group must contain variables such as \\v(filename)\n"
  4612.                );
  4613.         x = -9;
  4614.         goto xsendx;
  4615.         }
  4616.     }
  4617. #endif /* NOSPL */
  4618.     makestr(&snd_rename,p);
  4619.     }
  4620.  
  4621. /* Handle /RECOVER and /START */
  4622.  
  4623. #ifdef CK_RESEND
  4624.     if (pv[SND_RES].ival > 0 && binary != XYFT_B && !filepeek
  4625. #ifdef PATTERNS
  4626.     && !patterns
  4627. #else
  4628. #ifdef VMS
  4629. /* VMS sets text/binary automatically later when it opens the file */
  4630.     && 0
  4631. #endif /* VMS */
  4632. #endif /* PATTERNS */
  4633.     ) {
  4634.     printf("?Sorry, /BINARY required\n");
  4635.     x = -9;
  4636.     goto xsendx;
  4637.     }
  4638.     if (pv[SND_STA].ival > 0) {        /* /START */
  4639.     if (wild) {
  4640.         printf("?Sorry, wildcards not permitted with /START\n");
  4641.         x = -9;
  4642.         goto xsendx;
  4643.     }
  4644.     if (sizeof(int) < 4) {
  4645.         printf("?Sorry, this command needs 32-bit integers\n");
  4646.         x = -9;
  4647.         goto xsendx;
  4648.     }
  4649. #ifdef CK_XYZ
  4650.     if (protocol != PROTO_K) {
  4651.         printf("?Sorry, SEND /START works only with Kermit protocol\n");
  4652.         x = -9;
  4653.         goto xsendx;
  4654.     }
  4655. #endif /* CK_XYZ */
  4656.     }
  4657. #ifdef CK_XYZ
  4658.     if (pv[SND_RES].ival > 0) {
  4659.     if (protocol != PROTO_K && protocol != PROTO_Z) {
  4660.         printf(
  4661.     "Sorry, /RECOVER is possible only with Kermit or ZMODEM protocol\n"
  4662.            );
  4663.         x = -9;
  4664.         goto xsendx;
  4665.     }
  4666.     }
  4667. #endif /* CK_XYZ */
  4668. #endif /* CK_RESEND */
  4669.  
  4670.     if (protocol == PROTO_K) {
  4671.     if ((pv[SND_MAI].ival > 0 ||    /* MAIL */
  4672.          pv[SND_PRI].ival > 0 ||    /* PRINT */
  4673.          pv[SND_RES].ival > 0    /* RESEND */
  4674.          ) &&
  4675.         (!atdiso || !atcapr)) {    /* Disposition attribute off? */
  4676.         printf("?Sorry, ATTRIBUTE DISPOSITION must be ON\n");
  4677.         x = -9;
  4678.         goto xsendx;
  4679.     }
  4680.     }
  4681.  
  4682. #ifdef CK_XYZ
  4683.     if (wild && (protocol == PROTO_X || protocol == PROTO_XC)) {
  4684.     printf(
  4685. "Sorry, you can only send one file at a time with XMODEM protocol\n"
  4686.            );
  4687.     x = -9;
  4688.     goto xsendx;
  4689.     }
  4690. #endif /* CK_XYZ */
  4691.  
  4692.     if (!confirmed) {            /* CR not typed yet, get more fields */
  4693.     char *m;
  4694.     if (mlist) {            /* MSEND or MMOVE */
  4695.         nfils = 0;            /* We already have the first one */
  4696. #ifndef NOMSEND
  4697.         msfiles[nfils++] = line;    /* Store pointer */
  4698.         lp = line + (int)strlen(line) + 1; /* Point past it */
  4699.         debug(F111,"xsend msend",msfiles[nfils-1],nfils-1);
  4700.         while (1) {            /* Get more filenames */
  4701.         char *p;
  4702.         if ((x = cmifi("Names of files to send, separated by spaces",
  4703.                    "", &s,&y,xxstring)) < 0) {
  4704.             if (x != -3)
  4705.               goto xsendx;
  4706.             if ((x = cmcfm()) < 0)
  4707.               goto xsendx;
  4708.             break;
  4709.         }
  4710.         msfiles[nfils++] = lp;    /* Got one, count it, point to it, */
  4711.         p = lp;            /* remember pointer, */
  4712.         while ((*lp++ = *s++))    /* and copy it into buffer */
  4713.           if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
  4714.               printf("?MSEND list too long\n");
  4715.               line[0] = NUL;
  4716.               x = -9;
  4717.               goto xsendx;
  4718.           }
  4719.         debug(F111,"xsend msend",msfiles[nfils-1],nfils-1);
  4720.         if (nfils == 1) fspec[0] = NUL; /* Take care of \v(filespec) */
  4721. #ifdef ZFNQFP
  4722.         zfnqfp(p,TMPBUFSIZ,tmpbuf);
  4723.         p = tmpbuf;
  4724. #endif /* ZFNQFP */
  4725.         if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) {
  4726.             strcat(fspec,p);    /* safe */
  4727.             strcat(fspec," ");    /* safe */
  4728.         } else
  4729. #ifdef COMMENT
  4730.           printf("WARNING - \\v(filespec) buffer overflow\n");
  4731. #else
  4732.           debug(F101,"doxsend filespec buffer overflow","",0);
  4733. #endif /* COMMENT */
  4734.         }
  4735. #endif /* NOMSEND */
  4736.     } else {            /* Regular SEND */
  4737.         char *p; int y;
  4738.         nfils = -1;
  4739.         if (pv[SND_MAI].ival > 0)
  4740.           m = (pv[SND_MAI].sval) ?
  4741.         "e-mail address (optional)" :
  4742.           "e-mail address (required)";
  4743.         else if (pv[SND_PRI].ival > 0)
  4744.           m = "printer options (optional)";
  4745.         else if (wild)
  4746.           m =
  4747. "\nOptional as-name template containing replacement variables \
  4748. like \\v(filename)";
  4749.         else
  4750.           m = "Optional name to send it with";
  4751.         if ((x = cmtxt(m,"",&p,NULL)) < 0)
  4752.           goto xsendx;
  4753.         if (!p) p = "";
  4754.         if (*p) {            /* If some text was given... */
  4755.         p = brstrip(p);        /* Replace /AS-NAME: value if any */
  4756.         if ((y = strlen(p)) > 0) {
  4757.                     if (pv[SND_MAI].ival > 0) {
  4758.                         makestr(&pv[SND_MAI].sval, p);
  4759.                     } else {
  4760.             if (pv[SND_ASN].sval) free(pv[SND_ASN].sval);
  4761.             pv[SND_ASN].sval = malloc(y+1);
  4762.             if (pv[SND_ASN].sval) {
  4763.                 strcpy(pv[SND_ASN].sval,p);    /* safe */
  4764.                 pv[SND_ASN].ival = 1;
  4765.             }
  4766.             }
  4767.         }
  4768.         }
  4769.     }
  4770.     }
  4771.     /* Set cmarg2 from as-name, however we got it. */
  4772.  
  4773.     if (pv[SND_ASN].ival > 0 && pv[SND_ASN].sval && !*cmarg2) {
  4774.     int x;
  4775.     x = strlen(line);
  4776.     ckstrncpy(line+x+2,pv[SND_ASN].sval,LINBUFSIZ-x-1);
  4777.     cmarg2 = line+x+2;
  4778.     debug(F110,"doxsend cmarg2",cmarg2,0);
  4779.     }
  4780.  
  4781. #ifndef NOFRILLS
  4782.     if ((pv[SND_MAI].ival > 0) && (pv[SND_PRI].ival > 0)) {
  4783.     printf("Sorry, /MAIL and /PRINT are conflicting options\n");
  4784.     x = -9;
  4785.     goto xsendx;
  4786.     }
  4787.     n = 0;                /* /MAIL or /PRINT? */
  4788.     if (pv[SND_MAI].ival > 0)
  4789.       n = SND_MAI;
  4790.     else if (pv[SND_PRI].ival > 0)
  4791.       n = SND_PRI;
  4792.     if (n) {                /* Yes... */
  4793. #ifdef DEBUG
  4794.     char * p;
  4795.     if (n == SND_MAI)
  4796.       p = "/MAIL";
  4797.     else
  4798.       p = "/PRINT";
  4799.     debug(F111,"xsend",p,n);
  4800. #endif /* DEBUG */
  4801. #ifdef CK_XYZ
  4802.     if (protocol != PROTO_K) {
  4803.         printf("Sorry, %s available only with Kermit protocol\n",
  4804.            (n == SND_MAI) ? "/MAIL" : "/PRINT"
  4805.            );
  4806.         x = -9;
  4807.         goto xsendx;
  4808.     }
  4809. #endif /* CK_XYZ */
  4810.     debug(F101,"xsend print/mail wild","",wild);
  4811.     *optbuf = NUL;            /* Wipe out any old options */
  4812.     s = pv[n].sval;            /* mail address or print switch val */
  4813.     if (!s) s = "";
  4814.     debug(F110,"doxsend mail address or printer options",s,0);
  4815.     if (n == SND_MAI && !*s) {
  4816.         printf("?E-mail address required\n");
  4817.         x = -9;
  4818.         goto xsendx;
  4819.     } else if ((int)strlen(s) > 94) { /* Ensure legal size */
  4820.         printf("?%s too long\n",
  4821.            (n == SND_MAI) ?
  4822.            "E-mail address" :
  4823.            "Print option string"
  4824.            );
  4825.         x = -9;
  4826.         goto xsendx;
  4827.     }
  4828.     ckstrncpy(optbuf,s,OPTBUFLEN);    /* OK, copy to option buffer */
  4829.     cmarg = line;            /* File to send */
  4830.     if (n == SND_MAI) {
  4831.         debug(F110,"xsend mailing",cmarg,0);
  4832.         debug(F110,"xsend address:",optbuf,0);
  4833.         rmailf = 1;
  4834.     } else {
  4835.         debug(F110,"xsend printing",cmarg,0);
  4836.         debug(F110,"xsend options",optbuf,0);
  4837.         rprintf = 1;
  4838.     }
  4839.     }
  4840. #endif /* NOFRILLS */
  4841.  
  4842. #ifdef CALIBRATE
  4843.     if (pv[SND_CAL].ival > 0) {        /* Handle /CALIBRATE */
  4844.     if (confirmed) {
  4845.         calibrate = pv[SND_CAL].ival * 1024L;
  4846.         sndsrc = -9;
  4847.         nfils = 1;
  4848.         wild = 0;
  4849. #ifndef NOMSEND
  4850.         addlist = 0;
  4851. #endif /* NOMSEND */
  4852.         ckstrncpy(line,"CALIBRATION",LINBUFSIZ);
  4853.         s = cmarg = line;
  4854.         if (!cmarg2) cmarg2 = "";
  4855.         debug(F110,"doxsend cmarg2 calibrate",cmarg2,0);
  4856.     } else if (line[0]) {
  4857.         calibrate = 0L;
  4858.         pv[SND_CAL].ival = 0L;
  4859.     }
  4860.     }
  4861. #endif /* CALIBRATE */
  4862.  
  4863.     if (pv[SND_FIL].ival > 0) {
  4864.     if (confirmed && !calibrate) {
  4865.         if (zopeni(ZMFILE,pv[SND_FIL].sval) < 1) {
  4866.         debug(F110,"xsend can't open",pv[SND_FIL].sval,0);
  4867.         printf("?Failure to open %s\n",filefile);
  4868.         x = -9;
  4869.         goto xsendx;
  4870.         }
  4871.         makestr(&filefile,pv[SND_FIL].sval); /* Open, remember name */
  4872.         debug(F110,"xsend opened",filefile,0);
  4873.         wild = 1;
  4874.     }
  4875.     }
  4876.  
  4877.     /* SEND alone... */
  4878.  
  4879. #ifndef NOSPL
  4880.     if (confirmed && pv[SND_ARR].ival > 0) {
  4881.     if (!*cmarg2) {
  4882.         sndxnam[7] = (char)((arrayx == 1) ? 64 : arrayx + ARRAYBASE);
  4883.         cmarg2 = sndxnam;
  4884.     }
  4885.     cmarg = "";
  4886.     goto sendend;
  4887.     }
  4888. #endif /* NOSPL */
  4889.  
  4890.     if (confirmed && !line[0] && !filefile && !calibrate) {
  4891. #ifndef NOMSEND
  4892.     if (filehead) {            /* OK if we have a SEND-LIST */
  4893.         nfils = filesinlist;
  4894.         sndsrc = nfils;        /* Like MSEND */
  4895.         addlist = 1;        /* But using a different list... */
  4896.         filenext = filehead;
  4897.         goto sendend;
  4898.     }
  4899. #endif /* NOMSEND */
  4900.     printf("?Filename required but not given\n");
  4901.     x = -9;
  4902.     goto xsendx;
  4903.     }
  4904.  
  4905.     /* Not send-list or array */
  4906.  
  4907. #ifndef NOMSEND
  4908.     addlist = 0;            /* Don't use SEND-LIST. */
  4909.     filenext = NULL;
  4910. #endif /* NOMSEND */
  4911.  
  4912.     if (mlist) {            /* MSEND or MMOVE */
  4913. #ifndef NOMSEND
  4914.     cmlist = msfiles;        /* List of files to send */
  4915.     sndsrc = nfils;
  4916.     cmarg2 = "";
  4917.     sendstart = 0L;
  4918. #endif /* NOMSEND */
  4919. #ifdef PIPESEND
  4920.     pipesend = 0;
  4921. #endif /* PIPESEND */
  4922.     } else if (filefile) {        /* File contains list of filenames */
  4923.     s = "";
  4924.     cmarg = "";
  4925.     cmarg2 = "";
  4926.     line[0] = NUL;
  4927.     nfils = 1;
  4928.     sndsrc = 1;
  4929.  
  4930.     } else if (!calibrate && pv[SND_ARR].ival < 1 && pv[SND_CMD].ival < 1) {
  4931.  
  4932.     nfils = sndsrc = -1;    /* Not MSEND, MMOVE, /LIST, or /ARRAY */
  4933.     if (                /* or /COMMAND */
  4934.  
  4935. #ifndef NOFRILLS
  4936.         !rmailf && !rprintf        /* Not MAIL or PRINT */
  4937. #else
  4938.         1
  4939. #endif /* NOFRILLS */
  4940.         ) {
  4941.         int y = 1;
  4942.         if (!wild)
  4943.           y = zchki(s);
  4944.         if (y < 0) {
  4945.         printf("?Read access denied - \"%s\"\n", s);
  4946.         x = -9;
  4947.         goto xsendx;
  4948.         }
  4949.         if (s != line)        /* We might already have done this. */
  4950.           ckstrncpy(line,s,LINBUFSIZ); /* Copy of string just parsed. */
  4951.         else
  4952.           debug(F110,"doxsend line=s",line,0);
  4953.         cmarg = line;        /* File to send */
  4954.     }
  4955.     zfnqfp(cmarg,fspeclen,fspec);
  4956.     }
  4957.     if (!mlist) {            /* For all but MSEND... */
  4958. #ifdef PIPESEND
  4959.     if (pv[SND_CMD].ival > 0)    /* /COMMAND sets pipesend flag */
  4960.       pipesend = 1;
  4961.     debug(F101,"xsend /COMMAND pipesend","",pipesend);
  4962.     if (pipesend && filefile) {
  4963.         printf("?Invalid switch combination\n");
  4964.         x = -9;
  4965.         goto xsendx;
  4966.     }
  4967. #endif /* PIPESEND */
  4968.  
  4969. #ifndef NOSPL
  4970.     /* If as-name given and filespec is wild, as-name must contain variables */
  4971.     debug(F111,"doxsend cmarg2 wild",cmarg2,wild);
  4972.     if (wild && *cmarg2) {
  4973.         char * s = tmpbuf;
  4974.         x = TMPBUFSIZ;
  4975.         zzstring(cmarg2,&s,&x);
  4976.         if (!strcmp(tmpbuf,cmarg2)) {
  4977.         printf(
  4978.     "?As-name for file group must contain variables such as \\v(filename)\n"
  4979.                );
  4980.         x = -9;
  4981.         goto xsendx;
  4982.         }
  4983.     }
  4984. #endif /* NOSPL */
  4985.  
  4986.     /* Strip braces from as-name */
  4987.     debug(F110,"xsend cmarg2 before stripping",cmarg2,0);
  4988.     cmarg2 = brstrip(cmarg2);
  4989.     debug(F110,"xsend filename",cmarg,0);
  4990.     debug(F110,"xsend as-name",cmarg2,0);
  4991.  
  4992.     /* Copy as-name to a safe place */
  4993.  
  4994.     if (asnbuf) {
  4995.         free(asnbuf);
  4996.         asnbuf = NULL;
  4997.     }
  4998.     if ((y = strlen(cmarg2)) > 0) {
  4999.         asnbuf = (char *) malloc(y + 1);
  5000.         if (asnbuf) {
  5001.         strcpy(asnbuf,cmarg2);    /* safe */
  5002.         cmarg2 = asnbuf;
  5003.         } else cmarg2 = "";
  5004.     }
  5005.  
  5006. #ifdef CK_RESEND
  5007.     debug(F111,"xsend pv[SND_STA].ival","",pv[SND_STA].ival);
  5008.     if (pv[SND_STA].ival > -1) {    /* /START position */
  5009.         if (wild) {
  5010.         printf("?/STARTING-AT may not be used with multiple files.\n");
  5011.         x = -9;
  5012.         goto xsendx;
  5013.         } else
  5014.           sendstart = pv[SND_STA].ival;
  5015.     } else
  5016.       sendstart = 0L;
  5017.     debug(F101,"xsend /STARTING","",sendstart);
  5018. #endif /* CK_RESEND */
  5019.     }
  5020.  
  5021. sendend:                /* Common successful exit */
  5022.     moving = 0;
  5023.     if (pv[SND_SHH].ival > 0) {        /* SEND /QUIET... */
  5024.     g_displa = fdispla;
  5025.     fdispla = 0;
  5026.     debug(F101,"xsend display","",fdispla);
  5027.     }
  5028.  
  5029. #ifndef NOSPL                /* SEND /ARRAY... */
  5030.     if (pv[SND_ARR].ival > 0) {
  5031.     if (!ap) { x = -2; goto xsendx; } /* (shouldn't happen) */
  5032.     if (range[0] == -1)        /* If low end of range not specified */
  5033.       range[0] = 1;            /* default to 1 */
  5034.     if (range[1] == -1)        /* If high not specified */
  5035.       range[1] = a_dim[arrayx];    /* default to size of array */
  5036.     if ((range[0] < 0) ||        /* Check range */
  5037.         (range[0] > a_dim[arrayx]) ||
  5038.         (range[1] < range[0]) ||
  5039.         (range[1] > a_dim[arrayx])) {
  5040.         printf("?Bad array range - [%d:%d]\n",range[0],range[1]);
  5041.         x = -9;
  5042.         goto xsendx;
  5043.     }
  5044.     sndarray = ap;            /* Array pointer */
  5045.     sndxin = arrayx;        /* Array index */
  5046.     sndxlo = range[0];        /* Array range */
  5047.     sndxhi = range[1];
  5048.     sndxnam[7] = (char)((sndxin == 1) ? 64 : sndxin + ARRAYBASE);
  5049.  
  5050. #ifdef COMMENT
  5051.     printf("SENDING FROM ARRAY: &%c[]...\n", /* debugging */
  5052.            (sndxin == 1) ? 64 : sndxin + ARRAYBASE);
  5053.     printf("Lo=%d\nHi=%d\n", sndxlo, sndxhi);
  5054.     printf("cmarg=[%s]\ncmarg2=[%s]\n", cmarg, cmarg2);
  5055.     while ((x = agnbyte()) > -1) {
  5056.         putchar((char)x);
  5057.     }
  5058.     return(1);
  5059. #endif /* COMMENT */
  5060.     }
  5061. #endif /* NOSPL */
  5062.  
  5063.     if (pv[SND_ARR].ival < 1) {        /* File selection & disposition... */
  5064.  
  5065.     if (pv[SND_DEL].ival > 0)    /* /DELETE was specified */
  5066.       moving = 1;
  5067.     debug(F101,"xsend /DELETE","",moving);
  5068.     if (pv[SND_AFT].ival > 0)    /* Copy SEND criteria */
  5069.       ckstrncpy(sndafter,pv[SND_AFT].sval,19);
  5070.     if (pv[SND_BEF].ival > 0)
  5071.       ckstrncpy(sndbefore,pv[SND_BEF].sval,19);
  5072.     if (pv[SND_NAF].ival > 0)
  5073.       ckstrncpy(sndnafter,pv[SND_NAF].sval,19);
  5074.     if (pv[SND_NBE].ival > 0)
  5075.       ckstrncpy(sndnbefore,pv[SND_NBE].sval,19);
  5076.     if (pv[SND_EXC].ival > 0)
  5077.       makelist(pv[SND_EXC].sval,sndexcept,NSNDEXCEPT);
  5078.     if (pv[SND_SMA].ival > -1)
  5079.       sndsmaller = pv[SND_SMA].ival;
  5080.     if (pv[SND_LAR].ival > -1)
  5081.       sndlarger = pv[SND_LAR].ival;
  5082.     if (pv[SND_NAM].ival > -1) {
  5083.         g_fncnv = fncnv;        /* Save global value */
  5084.         fncnv = pv[SND_NAM].ival;
  5085.         debug(F101,"xsend fncnv","",fncnv);
  5086.     }
  5087.     if (pv[SND_PTH].ival > -1) {
  5088.         g_spath = fnspath;        /* Save global values */
  5089.         fnspath = pv[SND_PTH].ival;
  5090. #ifndef NZLTOR
  5091.         if (fnspath != PATH_OFF) {
  5092.         g_fncnv = fncnv;    /* Bad bad... */
  5093.         fncnv = XYFN_C;
  5094.         }
  5095. #endif /* NZLTOR */
  5096.         debug(F101,"xsend fnspath","",fnspath);
  5097.         debug(F101,"xsend fncnv","",fncnv);
  5098.     }
  5099.     }
  5100.  
  5101. #ifdef PIPESEND
  5102.     if (pv[SND_FLT].ival > 0) {
  5103.     makestr(&sndfilter,pv[SND_FLT].sval);
  5104.     debug(F110,"xsend /FILTER", sndfilter, 0);
  5105.     }
  5106. #endif /* PIPESEND */
  5107.  
  5108. #ifdef CK_APC
  5109. /* MOVE not allowed in APCs */
  5110.     if (moving &&
  5111.     (apcactive == APC_LOCAL || apcactive == APC_REMOTE)
  5112.     && !(apcstatus & APC_UNCH))
  5113.       return(success = 0);
  5114. #endif /* CK_APC */
  5115. #ifdef IKS_OPTION
  5116.     if (
  5117. #ifdef CK_XYZ
  5118.         protocol == PROTO_K &&
  5119. #endif /* CK_XYZ */
  5120.         !iks_wait(KERMIT_REQ_START,1)) {
  5121.         printf("?A Kermit Server is not available to process this command.\n");
  5122.         printf("?Start a RECEIVE command to complement this command.\n");
  5123.     }
  5124. #endif /* IKS_OPTION */
  5125.  
  5126. #ifdef IKSD
  5127. #ifdef CK_LOGIN
  5128.     if (moving && inserver && isguest) {
  5129.         printf("?File deletion not allowed for guests.\n");
  5130.     return(-9);
  5131.     }
  5132. #endif /* CK_LOGIN */
  5133. #endif /* IKSD */
  5134.  
  5135.     sstate = 's';            /* Set start state to SEND */
  5136.     sndcmd = 1;
  5137. #ifdef CK_RESEND
  5138.     if (pv[SND_RES].ival > 0)        /* Send sendmode appropriately */
  5139.       sendmode = SM_RESEND;
  5140.     else if (pv[SND_STA].ival > 0)
  5141.       sendmode = SM_PSEND;
  5142.     else
  5143. #endif /* CK_RESEND */
  5144.     if (mlist)
  5145.       sendmode = SM_MSEND;
  5146.     else
  5147.       sendmode = SM_SEND;
  5148. #ifdef MAC
  5149.     what = W_SEND;
  5150.     scrcreate();
  5151. #endif /* MAC */
  5152.     if (local && pv[SND_SHH].ival != 0) { /* If in local mode, */
  5153.     displa = 1;            /* turn on file transfer display */
  5154.     }
  5155.     x = 0;
  5156.  
  5157.   xsendx:                /* Common exit, including failure */
  5158.     debug(F101,"doxsend sndsrc","",sndsrc);
  5159.     for (i = 0; i <= SND_MAX; i++) {    /* Free malloc'd memory */
  5160.     if (pv[i].sval)
  5161.       free(pv[i].sval);
  5162.     }
  5163.     return(x);
  5164. }
  5165. #endif /* NOXFER */
  5166.  
  5167. #ifndef NOLOCAL
  5168. /*  D O X C O N N  --  CONNECT command parsing with switches */
  5169.  
  5170. #ifdef XLIMITS
  5171. #define XLIMORTRIGGER
  5172. #else
  5173. #ifdef CK_TRIGGER
  5174. #define XLIMORTRIGGER
  5175. #endif /* CK_TRIGGER */
  5176. #endif /*  XLIMITS */
  5177.  
  5178. #ifdef CKTIDLE
  5179. int tt_idlelimit = 0;            /* Terminal idle limit */
  5180. int tt_idleact = IDLE_RET;        /* Terminal idle action */
  5181. #endif /* CKTIDLE */
  5182.  
  5183. #ifdef OS2                /* K95 only: */
  5184. extern int
  5185.   tt_idlesnd_tmo;            /*   Idle interval */
  5186. int tt_timelimit = 0;            /*   Time limit, 0 = none */
  5187. extern char *                /* Parse results - strings: */
  5188.   tt_idlesnd_str;            /*   Idle string */
  5189. #endif /* OS2 */
  5190.  
  5191. #ifdef CK_TRIGGER
  5192. extern char *tt_trigger[];
  5193. extern CHAR *tt_trmatch[];
  5194. extern char *triggerval;
  5195. static char *g_tt_trigger[TRIGGERS];
  5196. #endif /* CK_TRIGGER */
  5197.  
  5198. #ifdef OS2
  5199. static int g_tt_idlesnd_tmo, g_tt_timelimit; /* For saving and restoring */
  5200. static int g_tt_idlelimit, g_tt_saved = 0;
  5201. static char * g_tt_idlesnd_str;        /* global settings */
  5202. #endif /* OS2 */
  5203.  
  5204. static struct stringint {        /* Temporary array for switch values */
  5205.     char * sval;
  5206.     int ival;
  5207. } pv[CONN_MAX+1];
  5208.  
  5209. VOID
  5210. resconn() {
  5211.     int i;
  5212.  
  5213. #ifdef OS2
  5214.     if ( g_tt_saved ) {
  5215.         tt_idlelimit   = g_tt_idlelimit;
  5216.         tt_idlesnd_tmo = g_tt_idlesnd_tmo;
  5217.         tt_timelimit   = g_tt_timelimit;
  5218.         tt_idlesnd_str = g_tt_idlesnd_str;
  5219.         g_tt_saved = 0;
  5220.     }
  5221. #endif /* OS2 */
  5222.  
  5223. #ifdef CK_TRIGGER
  5224.     for (i = 0; i < TRIGGERS; i++)
  5225.       tt_trigger[i] = g_tt_trigger[i];
  5226. #endif /* CK_TRIGGER */
  5227.  
  5228.     for (i = 0; i <= CONN_MAX; i++) {    /* Free malloc'd memory */
  5229.     if (pv[i].sval)
  5230.       free(pv[i].sval);
  5231.         pv[i].sval = NULL;
  5232.     }
  5233. }
  5234.  
  5235. int
  5236. doxconn(cx) int cx; {
  5237.     int c, i, n;            /* Workers */
  5238.     int x, y;
  5239.     int getval = 0;            /* Whether to get switch value */
  5240.     int async = 0;                      /* Make an async connect */
  5241.     struct FDB sw, cm;            /* FDBs for each parse function */
  5242.     extern FILE * tfile[];
  5243.     extern char * macp[];
  5244.  
  5245. #ifdef OS2
  5246.     g_tt_idlesnd_tmo = tt_idlesnd_tmo;    /* Save global settings */
  5247.     g_tt_timelimit   = tt_timelimit;
  5248.     g_tt_idlelimit   = tt_idlelimit;
  5249.     g_tt_idlesnd_str = tt_idlesnd_str;
  5250.     g_tt_saved = 1;
  5251. #endif /* OS2 */
  5252.  
  5253. #ifdef CK_TRIGGER
  5254.     if (!tt_trigger[0]) {        /* First initialization */
  5255.     for (i = 1; i < TRIGGERS; i++)
  5256.       tt_trigger[i] = NULL;
  5257.     }
  5258.     for (i = 0; i < TRIGGERS; i++)
  5259.       g_tt_trigger[i] = tt_trigger[i];
  5260.     if (triggerval) {
  5261.     free(triggerval);
  5262.     triggerval = NULL;
  5263.     }
  5264. #endif /* CK_TRIGGER */
  5265.  
  5266.     for (i = 0; i <= CONN_MAX; i++) {    /* Initialize switch values */
  5267.     pv[i].sval = NULL;        /* to null pointers */
  5268.     pv[i].ival = -1;        /* and -1 int values */
  5269.     }
  5270.     if (cx == XXCQ)            /* CQ == CONNECT /QUIETLY */
  5271.       pv[CONN_NV].ival = 1;
  5272.  
  5273.     /* Set up chained parse functions... */
  5274.  
  5275.     cmfdbi(&sw,                /* First FDB - command switches */
  5276.        _CMKEY,            /* fcode */
  5277.        "Switch",            /* hlpmsg */
  5278.        "",                /* default */
  5279.        "",                /* addtl string data */
  5280.        nconntab,            /* addtl numeric data 1: tbl size */
  5281.        4,                /* addtl numeric data 2: 4 = cmswi */
  5282.        xxstring,            /* Processing function */
  5283.        conntab,            /* Keyword table */
  5284.        &cm                /* Pointer to next FDB */
  5285.        );
  5286.     cmfdbi(&cm,                /* 2nd FDB - Confirmation */
  5287.        _CMCFM,            /* fcode */
  5288.        "",                /* hlpmsg */
  5289.        "",                /* default */
  5290.        "",                /* addtl string data */
  5291.        0,                /* addtl numeric data 1 */
  5292.        0,                /* addtl numeric data 2 */
  5293.        NULL,
  5294.        NULL,
  5295.        NULL
  5296.        );
  5297.  
  5298.     while (1) {                /* Parse 0 or more switches */
  5299.     x = cmfdb(&sw);            /* Parse switch or confirmation */
  5300.     debug(F101,"doxconn cmfdb","",x);
  5301.     if (x < 0) {            /* Error */
  5302.         if (x == -9 || x == -2)
  5303.           printf("?No switches match - \"%s\"\n",atmbuf);
  5304.         goto xconnx;        /* or reparse needed */
  5305.     }
  5306.     if (cmresult.fcode != _CMKEY)    /* Break out if not a switch */
  5307.       break;
  5308.     c = cmgbrk();            /* Get break character */
  5309.     getval = (c == ':' || c == '='); /* to see how they ended the switch */
  5310.     if (getval && !(cmresult.kflags & CM_ARG)) {
  5311.         printf("?This switch does not take arguments\n");
  5312.         x = -9;
  5313.         goto xconnx;
  5314.     }
  5315.     if (!getval && (cmgkwflgs() & CM_ARG)) {
  5316.         printf("?This switch requires an argument\n");
  5317.         return(-9);
  5318.     }
  5319.     n = cmresult.nresult;        /* Numeric result = switch value */
  5320.     debug(F101,"doxconn switch","",n);
  5321.  
  5322.     switch (n) {            /* Process the switch */
  5323. #ifdef OS2
  5324.       case CONN_AS:            /* Asynchronous */
  5325.             pv[CONN_AS].ival = 1;
  5326.             pv[CONN_SY].ival = 0;
  5327.             break;
  5328.           case CONN_SY:                 /* Synchronous */
  5329.             pv[CONN_SY].ival = 1;
  5330.             pv[CONN_AS].ival = 0;
  5331.             break;
  5332. #endif /* OS2 */
  5333.       case CONN_NV:            /* Non-verbal */
  5334.         pv[n].ival = 1;
  5335.         break;
  5336. #ifdef XLIMITS
  5337.       case CONN_II:            /* Idle-interval */
  5338.       case CONN_IL:            /* Idle-limit */
  5339.       case CONN_TL:            /* Time-limit */
  5340.         if (!getval) break;
  5341.         if ((x = cmnum("Seconds","0",10,&y,xxstring)) < 0)
  5342.           goto xconnx;
  5343.         pv[n].ival = y;
  5344.         break;
  5345.       case CONN_IS:            /* Idle-string */
  5346. #endif /* XLIMITS */
  5347. #ifdef CK_TRIGGER
  5348.       case CONN_TS:            /* Trigger-string */
  5349. #endif /* CK_TRIGGER */
  5350. #ifdef XLIMORTRIGGER
  5351.         if (!getval) break;
  5352.         if ((x = cmfld("String (enclose in braces if it contains spaces)",
  5353.                "",&s,xxstring)) < 0) {
  5354.         if (x == -3) {
  5355.             printf("?String required\n");
  5356.             x = -9;
  5357.         }
  5358.         goto xconnx;
  5359.         }
  5360.         if (n != CONN_TS)
  5361.           s = brstrip(s);
  5362.         if ((y = strlen(s)) > 0) {
  5363.         if (pv[n].sval) free(pv[n].sval);
  5364.         pv[n].sval = malloc(y+1);
  5365.         if (pv[n].sval) {
  5366.             strcpy(pv[n].sval,s); /* safe */
  5367.             pv[n].ival = 1;
  5368.         }
  5369.         }
  5370.         break;
  5371. #endif /* XLIMORTRIGGER */
  5372.       default:
  5373.         printf("?Unexpected switch value - %d\n",cmresult.nresult);
  5374.         x = -9;
  5375.         goto xconnx;
  5376.     }
  5377.     }
  5378.     debug(F101,"doxconn cmresult.fcode","",cmresult.fcode);
  5379.     if (cmresult.fcode != _CMCFM) {
  5380.     printf("?Unexpected function code: %d\n",cmresult.fcode);
  5381.     x = -9;
  5382.     goto xconnx;
  5383.     }
  5384.  
  5385.     /* Command was confirmed so we can pre-pop command level. */
  5386.     /* This is so CONNECT module won't think we're executing a script */
  5387.     /* if CONNECT was the final command in the script. */
  5388.  
  5389.     if (cmdlvl > 0)
  5390.       prepop();
  5391.  
  5392. #ifdef OS2                /* Make results available globally */
  5393.     if (pv[CONN_IL].ival > -1)        /* Idle limit */
  5394.       tt_idlelimit = pv[CONN_IL].ival;
  5395.     if (pv[CONN_II].ival > -1)        /* Idle limit */
  5396.       tt_idlesnd_tmo = pv[CONN_II].ival;
  5397.     if (pv[CONN_IS].sval)        /* Idle string */
  5398.       if (tt_idlesnd_str = (char *)malloc((int)strlen(pv[CONN_IS].sval)+1))
  5399.     strcpy(tt_idlesnd_str,pv[CONN_IS].sval); /* safe */
  5400.     if (pv[CONN_TL].ival > -1)        /* Session limit */
  5401.       tt_timelimit = pv[CONN_TL].ival;
  5402.     async = (pv[CONN_AS].ival > 0 ||
  5403.              pv[CONN_SY].ival <= 0 && cmdlvl == 0) ? 1 : 0;
  5404. #endif /* OS2 */
  5405.  
  5406. #ifdef CK_TRIGGER
  5407.     if (pv[CONN_TS].sval)        /* Trigger strings */
  5408.       makelist(pv[CONN_TS].sval,tt_trigger,TRIGGERS);
  5409.     for (i = 0; i < TRIGGERS; i++)    /* Trigger match pointers */
  5410.       tt_trmatch[i] = NULL;
  5411.     if (triggerval) {            /* Reset trigger value */
  5412.     free(triggerval);
  5413.     triggerval = NULL;
  5414.     }
  5415. #endif /* CK_TRIGGER */
  5416.  
  5417.     x = doconect((pv[CONN_NV].ival > 0) ? 1 : 0, async);
  5418.     {
  5419.     int xx;
  5420.     debug(F101,"doxconn doconect returns","",x);
  5421.     if ((xx = ttchk()) < 0) dologend();
  5422.     debug(F101,"doxconn ttchk returns","",xx);
  5423.     }
  5424.  
  5425. #ifdef CK_TRIGGER
  5426.     debug(F111,"doxconn doconect triggerval",triggerval,x);
  5427. #endif /* CK_TRIGGER */
  5428.  
  5429.   xconnx:
  5430.     /* Back from CONNECT -- Restore global settings */
  5431.  
  5432.     if (!async)
  5433.       resconn();
  5434.  
  5435.     success = (x > 0) ? 1 : 0;
  5436.     return(x);
  5437. }
  5438. #endif /* NOLOCAL */
  5439.  
  5440. #ifdef ADDCMD
  5441. /* cx == XXADD or XXREMV */
  5442. /* fc == ADD_BIN or ADD_TXT */
  5443. static int
  5444. doadd(cx,fc) int cx, fc; {
  5445. #ifdef PATTERNS
  5446.     char * tmp[FTPATTERNS];
  5447.     char **p = NULL;
  5448.     int i, j, k, n = 0, x = 0, last;
  5449.  
  5450. #endif /* PATTERNS */
  5451.     if (cx != XXADD && cx != XXREMV) {
  5452.     printf("?Unexpected function code: %d\n",cx);
  5453.     return(-9);
  5454.     }
  5455. #ifdef PATTERNS
  5456.     while (n < FTPATTERNS) {        /* Collect new patterns */
  5457.     tmp[n] = NULL;
  5458.     if ((x = cmfld("Pattern","",&s,xxstring)) < 0)
  5459.       break;
  5460.     ckstrncpy(line,s,LINBUFSIZ);
  5461.     s = brstrip(line);
  5462.     makestr(&(tmp[n++]),s);
  5463.     }
  5464.     if (x == -3)
  5465.       x = cmcfm();
  5466.     if (x < 0)
  5467.       goto xdoadd;
  5468.     p = (fc == ADD_BIN) ? binpatterns : txtpatterns; /* Which list */
  5469.     last = 0;
  5470.     for (i = 0; i < FTPATTERNS; i++) { /* Find last one in list */
  5471.     if (!p[i]) {
  5472.         last = i;
  5473.         break;
  5474.     }
  5475.     }
  5476.     if (cx == XXADD) {            /* Adding */
  5477.     if (last + n > FTPATTERNS) {    /* Check if too many */
  5478.         printf("?Too many patterns - %d is the maximum\n", FTPATTERNS);
  5479.         goto xdoadd;
  5480.     }
  5481.         for (i = 0; i < n; i++) {        /* Copy in the new ones. */
  5482.           for (j = 0, x = 0; x == 0 && j < last ; j++ )
  5483.             x = !ckstrcmp(tmp[i],p[j],-1,filecase); /* match */
  5484.           if (x == 0)
  5485.             makestr(&(p[last++]),tmp[i]);
  5486.         }
  5487.         makestr(&(p[last]),NULL);    /* Null-terminate the list */
  5488.         x = 1;
  5489.         goto xdoadd;                    /* Done */
  5490.     } else if (cx == XXREMV) {        /* Remove something(s) */
  5491.     int j, k;
  5492.     if (last == 0)                    /* List is empty */
  5493.       goto xdoadd;                    /* Nothing to remove */
  5494.     for (i = 0; i < n; i++) {            /* i = Patterns they typed */
  5495.         for (j = 0; j < last; j++) {        /* j = Patterns in list */
  5496.         /* Change this to ckstrcmp()... */
  5497.         if (filecase)
  5498.                   x = !ckstrcmp(tmp[i],p[j],-1,filecase); /* match */
  5499.         else
  5500.           x = ckstrcmp(tmp[i],p[j],-1,0); /* Case-independent match */
  5501.         if (x) {                    /* This one matches */
  5502.             makestr(&(p[j]),NULL);      /* Free it */
  5503.             for (k = j; k < last; k++)  /* Move the rest up */
  5504.               p[k] = p[k+1];
  5505.             p[k] = NULL;            /* Erase last one */
  5506.             if (!p[k])
  5507.               break;
  5508.         }
  5509.         }
  5510.     }
  5511.     }
  5512.   xdoadd:                /* Common exit */
  5513.     for (i = 0; i < n; i++)
  5514.       if (tmp[i])
  5515.     free(tmp[i]);
  5516.     return(x);
  5517. #endif /* PATTERNS */
  5518. }
  5519.  
  5520. /* ADD SEND-LIST */
  5521.  
  5522. static int
  5523. addsend(cx) int cx; {
  5524. #ifndef NOMSEND
  5525.     extern struct keytab fttab[];
  5526.     extern int nfttyp;
  5527.     struct filelist * flp;
  5528.     char * fmode = "";
  5529.     int xmode = 0;
  5530.     int xbinary = 0;
  5531. #endif /* NOMSEND */
  5532.  
  5533. #ifdef NOMSEND
  5534.     printf("?Sorry, ADD/REMOVE SEND-LIST not available.\n");
  5535.     return(-9);
  5536. #endif /* NOMSEND */
  5537.     if (cx == XXREMV) {
  5538.     printf("?Sorry, REMOVE SEND-LIST not implemented yet.\n");
  5539.     return(-9);
  5540.     }
  5541. #ifndef NOMSEND
  5542. #ifndef XYZ_INTERNAL
  5543.     if (protocol != PROTO_K) {
  5544.        printf("?Sorry, ADD SEND-LIST does not work with external protocols\n");
  5545.        return(-9);
  5546.     }
  5547. #endif /* XYZ_INTERNAL */
  5548.  
  5549.     x = cmifi("File specification to add","", &s,&y,xxstring);
  5550.     if (x < 0) {
  5551.     if (x == -3) {
  5552.         printf("?A file specification is required\n");
  5553.         return(-9);
  5554.     } else
  5555.       return(x);
  5556.     }
  5557.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  5558.     s = tmpbuf;
  5559.     if (filesinlist == 0)        /* Take care of \v(filespec) */
  5560.       fspec[0] = NUL;
  5561.     zfnqfp(s,LINBUFSIZ,line);
  5562.     s = line;
  5563.     if (((int)strlen(fspec) + (int)strlen(s) + 1) < fspeclen) {
  5564.     strcat(fspec,s);        /* safe */
  5565.     strcat(fspec," ");        /* safe */
  5566.     } else
  5567.       printf("WARNING - \\v(filespec) buffer overflow\n");
  5568.  
  5569.  
  5570.     xbinary = binary;
  5571.     if ((patterns || filepeek)        /* FILE PATTERNS or SCAN is ON */
  5572. #ifdef CK_LABELED
  5573.     && binary != XYFT_L        /* And not if FILE TYPE LABELED */
  5574. #endif /* CK_LABELED */
  5575. #ifdef VMS
  5576.     && binary != XYFT_I        /* or FILE TYPE IMAGE */
  5577. #endif /* VMS */
  5578.     ) {
  5579.     int k, x;
  5580.     x = -1;
  5581.     k = scanfile(line,&x,nscanfile);
  5582.     if (k > 0) xbinary = (k == FT_BIN) ? XYFT_B : XYFT_T;
  5583.     }
  5584.     fmode = gfmode(xbinary,0);
  5585.     if ((x = cmkey(fttab,nfttyp,
  5586.            "type of file transfer", fmode, xxstring)) < 0)
  5587.       return(x);
  5588.     xmode = x;
  5589.  
  5590.     cmarg2 = "";
  5591.     if ((x = cmfld(y ?
  5592.   "\nAs-name template containing replacement variables such as \\v(filename)" :
  5593.   "Name to send it with", "",&s,NULL)) < 0)
  5594.       if (x != -3)
  5595.     return(x);
  5596. #ifndef NOSPL
  5597.     if (y && *s) {
  5598.     char * p = tmpbuf;
  5599.     x = TMPBUFSIZ;
  5600.     zzstring(s,&p,&x);
  5601.     if (!strcmp(tmpbuf,s)) {
  5602.         printf(
  5603.   "?As-name for file group must contain variables such as \\v(filename)\n"
  5604.            );
  5605.         return(-9);
  5606.     }
  5607.     }
  5608. #endif /* NOSPL */
  5609.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  5610.     cmarg2 = tmpbuf;
  5611.  
  5612.     if ((x = cmcfm()) < 0)
  5613.       return(x);
  5614.     flp = (struct filelist *) malloc(sizeof(struct filelist));
  5615.     if (flp) {
  5616.     if (filetail)
  5617.       filetail->fl_next = flp;
  5618.     filetail = flp;
  5619.     if (!filehead)
  5620.       filehead = flp;
  5621.     x = (int) strlen(line);    /* Length of filename */
  5622.     s = (char *) malloc(x + 1);
  5623.     if (s) {
  5624.         strcpy(s,line);        /* safe */
  5625.         flp->fl_name = s;
  5626.         flp->fl_mode = xmode;
  5627.         x = (int) strlen(cmarg2);    /* Length of as-name */
  5628.         if (x < 1) {
  5629.         flp->fl_alias = NULL;
  5630.         } else {
  5631.         s = (char *) malloc(x + 1);
  5632.         if (s) {
  5633.             strcpy(s,cmarg2);    /* safe */
  5634.             flp->fl_alias = s;
  5635.         } else {
  5636.             printf("Sorry, can't allocate space for as-name");
  5637.             return(-9);
  5638.         }
  5639.         }
  5640.         flp->fl_next = NULL;
  5641.         filesinlist++;        /* Count this node */
  5642.         return(success = 1);    /* Finished adding this node */
  5643.     } else {
  5644.         printf("Sorry, can't allocate space for name");
  5645.         return(-9);
  5646.     }
  5647.     } else {
  5648.     printf("Sorry, can't allocate file list node");
  5649.     return(-9);
  5650.     }
  5651. #endif /* NOMSEND */
  5652. }
  5653. #endif /* ADDCMD */
  5654.  
  5655. #ifndef NOHTTP                /* HTTP ops... */
  5656. #ifdef TCPSOCKET
  5657. #define HTTP_GET 0            /* GET */
  5658. #define HTTP_PUT 1            /* PUT */
  5659. #define HTTP_POS 2            /* POST */
  5660. #define HTTP_IDX 3            /* INDEX */
  5661. #define HTTP_HED 4                      /* HEAD */
  5662. #define HTTP_DEL 5                      /* DELETE */
  5663. #define HTTP_CON 6                      /* CONNECT */
  5664. #define HTTP_OPN 7                      /* OPEN */
  5665. #define HTTP_CLS 8                      /* CLOSE */
  5666.  
  5667. static struct keytab httptab[] = {
  5668.     { "close",   HTTP_CLS, 0 },
  5669.     { "connect", HTTP_CON, 0 },
  5670.     { "delete",  HTTP_DEL, 0 },
  5671.     { "get",     HTTP_GET, 0 },
  5672.     { "head",    HTTP_HED, 0 },
  5673.     { "index",   HTTP_IDX, 0 },
  5674.     { "open",    HTTP_OPN, 0 },
  5675.     { "put",     HTTP_PUT, 0 },
  5676.     { "post",    HTTP_POS, 0 }
  5677. };
  5678. static int nhttptab = sizeof(httptab)/sizeof(struct keytab);
  5679.  
  5680. /* HTTP switches */
  5681. #define HT_SW_AG 0            /* /AGENT */
  5682. #define HT_SW_HD 1            /* /HEADER */
  5683. #define HT_SW_US 2            /* /USER */
  5684. #define HT_SW_PW 3            /* /PASSWORD */
  5685. #define HT_SW_AR 4                      /* /ARRAY */
  5686. #define HT_SW_TP 5                      /* /TOSCREEN */
  5687.  
  5688. static struct keytab httpswtab[] = {
  5689.     { "/agent",    HT_SW_AG, CM_ARG },
  5690. #ifndef NOSPL
  5691.     { "/array",    HT_SW_AR, CM_ARG },
  5692. #endif /* NOSPL */
  5693.     { "/header",   HT_SW_HD, CM_ARG },
  5694.     { "/password", HT_SW_PW, CM_ARG },
  5695.     { "/toscreen", HT_SW_TP, 0 },
  5696.     { "/user",     HT_SW_US, CM_ARG },
  5697.     { "", 0, 0 }
  5698. };
  5699. static int nhttpswtab = sizeof(httpswtab)/sizeof(struct keytab) - 1;
  5700.  
  5701. /* HTTP PUT/POST switches */
  5702. #define HT_PP_MT 0            /* /MIME-TYPE */
  5703.  
  5704. static struct keytab httpptab[] = {
  5705.     { "/mime-type", HT_PP_MT, CM_ARG },
  5706.     { "", 0, 0 }
  5707. };
  5708. static int nhttpptab = sizeof(httpptab)/sizeof(struct keytab) - 1;
  5709.  
  5710. #define HTTP_MAXHDR 8
  5711.  
  5712. static int
  5713. xdohttp(action, lfile, rf, dfile, agent, hdr, user, pass, mime, array, type)
  5714.     int action;
  5715.     char *lfile, *rf, *dfile, *agent, *hdr, *user, *pass, *mime, array;
  5716.     int type;
  5717. /* xdohttp */ {
  5718.     int i, rc = 0;
  5719.     char * hdrlist[HTTP_MAXHDR];
  5720.     char rfile[CKMAXPATH+1];
  5721.     extern int httpfd;
  5722.  
  5723.     /* Check for a valid state to execute the command */
  5724.     if (inserver) {
  5725.         printf("?The HTTP command may not be used from the IKS\r\n");
  5726.     } else if (httpfd == -1) {
  5727.         if (http_reopen() < 0)
  5728.       printf("?No connection\n");
  5729.         else
  5730.       rc = 1;
  5731.     } else {
  5732.     rc = 1;
  5733.     }
  5734.  
  5735.     /* If the command is not valid, exit with failure */
  5736.     if (rc == 0)
  5737.         return(success = 0);
  5738.  
  5739.     if (action != HTTP_CON && rf[0] != '/') {
  5740.         rfile[0] = '/';
  5741.         ckstrncpy(&rfile[1],rf,CKMAXPATH);
  5742.     } else {
  5743.         ckstrncpy(rfile,rf,CKMAXPATH);
  5744.     }
  5745.     for (i = 0; i < HTTP_MAXHDR; i++)    /* Initialize header list */
  5746.       hdrlist[i] = NULL;
  5747.     makelist(hdr,hdrlist,HTTP_MAXHDR);    /* Make header list */
  5748.  
  5749. #ifdef BETADEBUG
  5750.     for (i = 0; i < nhttptab; i++)    /* Find action keyword */
  5751.       if (httptab[i].kwval == action)
  5752.     break;
  5753.     if (i == nhttptab) {        /* Shouldn't happen... */
  5754.     printf("?Invalid action - %d\n",action);
  5755.     return(0);            /* Failure */
  5756.     }
  5757.  
  5758.     printf("HTTP action:  %s\n",httptab[i].kwd);
  5759.     printf(" Agent:       %s\n",agent ? agent : "(null)");
  5760.  
  5761.     if (hdrlist[1]) {
  5762.     printf(" Header list: 1. %s\n",hdrlist[0]);
  5763.     for (i = 1; i < HTTP_MAXHDR && hdrlist[i]; i++)
  5764.       printf("%15d. %s\n",i+1,hdrlist[i]);
  5765.     } else
  5766.       printf(" Header:      %s\n",hdrlist[0] ? hdrlist[0] : "(null)");
  5767.  
  5768.     printf(" User:        %s\n",user ? user : "(null)");
  5769. #ifdef COMMENT
  5770.     printf(" Password:    %s\n",pass ? pass : "(null)");
  5771. #endif /* COMMENT */
  5772.  
  5773. #ifndef NOSPL
  5774.     if (array)
  5775.       printf(" Array:       \\%%%c[]\n", array);
  5776.     else
  5777.       printf(" Array:       (none)\n");
  5778. #endif /* NOSPL */
  5779.  
  5780.     if (action == HTTP_PUT || action == HTTP_POS)
  5781.       printf(" Mime-type:   %s\n",mime ? mime : "(null)");
  5782.  
  5783.     printf(" Local file:  %s\n",lfile ? lfile : "(null)");
  5784.     printf(" Remote file: %s\n",rfile ? rfile : "(null)");
  5785.     printf(" Destination file: %s\n",dfile ? dfile : "(null)");
  5786. #endif /* BETADEBUG */
  5787.  
  5788.     /* The http_xxxx() functions return 0 on success, -1 on failure */
  5789.     switch (action) {
  5790.       case HTTP_CON: {
  5791.       extern int ttyfd;
  5792.       rc = http_connect(httpfd,agent,hdrlist,user,pass,array,rfile);
  5793.       break;
  5794.       }
  5795.       case HTTP_DEL:
  5796.         rc = http_delete(agent,hdrlist,user,pass,array,rfile);
  5797.         break;
  5798.       case HTTP_GET:
  5799.         rc = http_get(agent,hdrlist,user,pass,array,lfile,rfile,type);
  5800.         break;
  5801.       case HTTP_HED:
  5802.         rc = http_head(agent,hdrlist,user,pass,array,lfile,rfile,type);
  5803.         break;
  5804.       case HTTP_PUT:
  5805.         rc = http_put(agent,hdrlist,mime,user,pass,array,lfile,rfile,dfile,
  5806.               type);
  5807.         break;
  5808.       case HTTP_POS:
  5809.         rc = http_post(agent,hdrlist,mime,user,pass,array,lfile,rfile,dfile,
  5810.                type);
  5811.         break;
  5812.       case HTTP_IDX:
  5813.         rc = http_index(agent,hdrlist,user,pass,array,lfile,rfile,type);
  5814.         break;
  5815.       default:
  5816.         rc = -1;
  5817.     }
  5818.     return(rc == 0 ? 1 : 0);            /* Success is set by caller */
  5819. }
  5820. #endif /* TCPSOCKET */
  5821. #endif /* NOHTTP */
  5822.  
  5823. #ifndef NOSPL                /* ARRAY ops... */
  5824. static struct keytab arraytab[] = {
  5825.     { "clear",     ARR_CLR, 0 },
  5826.     { "copy",      ARR_CPY, 0 },
  5827.     { "dcl",       ARR_DCL, CM_INV },
  5828.     { "declare",   ARR_DCL, 0 },
  5829.     { "destroy",   ARR_DST, CM_INV },
  5830.     { "equate",    ARR_EQU, CM_INV },
  5831.     { "link",      ARR_EQU, 0 },
  5832.     { "resize",    ARR_RSZ, 0 },
  5833.     { "set",       ARR_SET, 0 },
  5834. #ifndef NOSHOW
  5835.     { "show",      ARR_SHO, 0 },
  5836. #endif /* NOSHOW */
  5837.     { "sort",      ARR_SRT, 0 },
  5838.     { "undeclare", ARR_DST, 0 },
  5839.     { "", 0, 0 }
  5840. };
  5841. static int narraytab = sizeof(arraytab)/sizeof(struct keytab) - 1;
  5842.  
  5843. #ifdef CKLEARN
  5844. static struct keytab learnswi[] = {
  5845.     { "/close",    2, 0 },
  5846.     { "/off",      0, 0 },
  5847.     { "/on",       1, 0 }
  5848. };
  5849. #endif /* CKLEARN */
  5850.  
  5851. int
  5852. arrayitoa(x) int x; {            /* Array index to array letter */
  5853.     if (x == 1)
  5854.       return(64);
  5855.     else if (x < 0 || x > (122 - ARRAYBASE))
  5856.       return(-1);
  5857.     else
  5858.       return(x + ARRAYBASE);
  5859. }
  5860.  
  5861. int
  5862. arrayatoi(c) int c; {            /* Array letter to array index */
  5863.     if (c == 64)
  5864.       c = 96;
  5865.     if (c > 63 && c < 91)
  5866.       c += 32;
  5867.     if (c < ARRAYBASE || c > 122)
  5868.       return(-1);
  5869.     return(c - ARRAYBASE);
  5870. }
  5871.  
  5872. static int                /* Declare an array */
  5873. dodcl(cx) int cx; {
  5874.     int i, n, v, lo, hi, rc = 0;
  5875.     int isdynamic = 0;
  5876.     char tmpbuf[64];
  5877.     char ** p = NULL;
  5878.     char tmp[64];            /* Local temporary string buffer */
  5879.     if ((y = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
  5880.     if (y == -3) {
  5881.         printf("?Array name required\n");
  5882.         return(-9);
  5883.     } else return(y);
  5884.     }
  5885.     ckstrncpy(line,s,LINBUFSIZ);
  5886.     s = line;
  5887.     x = arraybounds(s,&lo,&hi);        /* Check syntax and get bounds */
  5888.     debug(F111,"XXX dodcl arraybounds",s,x);
  5889.     if (x < 0) {            /* Error - Maybe it's a variable */
  5890.     char * p;            /* whose value is an array name */
  5891.     int n;
  5892.     p = tmpbuf;
  5893.     n = 63;
  5894.     p[0] = NUL;
  5895.     if (s[0] == CMDQ && s[1] == '&')
  5896.       s++;
  5897.     if (zzstring(s,&p,&n) > -1) {
  5898.         s = tmpbuf;
  5899.         x = arraybounds(s,&lo,&hi);
  5900.         debug(F111,"XXX dodcl arraybounds 2",s,x);
  5901.     }
  5902.     if (x < 0) {
  5903.         printf("?Bad array name - \"%s\"\n",s);
  5904.         return(-9);
  5905.     }
  5906.     }
  5907.     debug(F101,"XXX dodcl lo","",lo);
  5908.     debug(F101,"XXX dodcl hi","",hi);
  5909.  
  5910.     if (lo < 0 && hi < 0) {        /* Have good array name and bounds */
  5911.     isdynamic = 1;
  5912.     n = CMDBL / 5;
  5913.     } else if (hi > -1) {
  5914.     printf("?Segment notation not allowed in array declarations\n");
  5915.     return(-9);
  5916.     } else
  5917.       n = lo;
  5918.     x = arrayitoa(x);
  5919.     if (cx == XXUNDCL) {
  5920.     n = 0;
  5921.     v = 0;
  5922.     if ((y = cmcfm()) < 0)
  5923.       return(y);
  5924.     } else {
  5925.     p = (char **)malloc(sizeof(char **)*(n+1));
  5926.     if (!p) {
  5927.         printf("?Memory allocation error\n");
  5928.         return(-9);
  5929.     }
  5930.     v = 0;                /* Highest initialized member */
  5931.     p[0] = NULL;            /* Element 0 */
  5932.     keepallchars = 1;
  5933.     while (n > 0 && v < n) {    /* Parse initializers */
  5934.         p[v+1] = NULL;
  5935.         ckmakxmsg(tmp,
  5936.               64,
  5937.               "Initial value for \\&",
  5938.               ckctoa((char)x),
  5939.               "[",
  5940.               ckitoa(v+1),
  5941.               "]",
  5942.               NULL,NULL,NULL,NULL,NULL,NULL,NULL
  5943.               );
  5944.         if ((rc = cmfld((char *)tmp,"",&s,xxstring)) < 0) { /* Get field */
  5945.         if (rc == -3)        /* If answer is empty, we're done */
  5946.           break;
  5947.         else            /* Parse error, free temp pointers */
  5948.           goto dclx;
  5949.         }
  5950.         rc = 1;
  5951.         if (v == 0 && !strcmp(s,"=")) /* Skip the = sign. */
  5952.           continue;
  5953.         s = brstrip(s);        /* Strip any braces */
  5954.         makestr(&(p[++v]),s);
  5955.     }
  5956.     keepallchars = 0;
  5957.     if ((y = cmtxt("Carriage return to confirm","",&s,NULL)) < 0)
  5958.       return(y);
  5959.     if (isdynamic)
  5960.       n = v;
  5961.     }
  5962.     if (dclarray((char)x,n) < 0) {    /* Declare the array */
  5963.     printf("?Declare failed\n");
  5964.     goto dclx;
  5965.     }
  5966.     for (i = 1; i <= v; i++) {        /* Add any initial values */
  5967.     tmp[0] = '&';
  5968.     ckmakmsg(&tmp[1],63,ckctoa((char)x),"[",ckitoa(i),"]");
  5969.     if (addmac(tmp,p[i]) < 0) {
  5970.         printf("Array initialization error: %s %s\n",tmp,p[i]);
  5971.         rc = -9;
  5972.         goto dclx;
  5973.     }
  5974.     }
  5975.   dclx:
  5976.     if (p) {
  5977.     for (i = 1; i <= v; i++)
  5978.       if (p[i]) free(p[i]);
  5979.     free((char *)p);
  5980.     }
  5981.     debug(F101,"DCL rc","",rc);
  5982.     return(success = rc);
  5983. }
  5984.  
  5985. static int
  5986. rszarray() {
  5987.     int i, x, y, n, lo, hi, islink = -1;
  5988.     char c, * s, ** ap = NULL;
  5989.     if ((x = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
  5990.     if (x == -3) {
  5991.         printf("?Array name required\n");
  5992.         return(-9);
  5993.     } else return(x);
  5994.     }
  5995.     ckstrncpy(line,s,LINBUFSIZ);    /* Make safe copy of name */
  5996.     s = line;
  5997.     x = arraybounds(s,&lo,&hi);
  5998.     if (x < 0) {            /* Parse the name, get index */
  5999.     printf("?Bad array reference - \"%s\"\n", s);
  6000.     return(-9);
  6001.     }
  6002.     if (lo < 0 && hi < 0) {
  6003.     y = cmnum("New size","",10,&lo,xxstring);
  6004.     if (y < 0) {
  6005.         if (y == -3)
  6006.           printf("?New size required\n");
  6007.         return(y);
  6008.     }
  6009.     }
  6010.     if ((y = cmcfm()) < 0)
  6011.       return(y);
  6012.     if (a_link[x] > -1) {        /* Link? */
  6013.     islink = x;            /* Yes follow it */
  6014.     x = a_link[x];            /* and remember */
  6015.     }
  6016.     if (!a_ptr[x]) {
  6017.     printf("?Array not declared - \"%s\"\n", s);
  6018.     return(-9);
  6019.     }
  6020.     if (lo < 0) {
  6021.     printf("?New size required\n");
  6022.     return(-9);
  6023.     }
  6024.     if (hi > -1) {
  6025.     printf("?Array segments not allowed for this operation\n");
  6026.     return(-9);
  6027.     }
  6028.     c = arrayitoa(x);            /* Get array letter */
  6029.     if (c == '@') {            /* Argument vector array off limits */
  6030.     printf("?Sorry, \\&@[] is read-only\n");
  6031.     return(-9);
  6032.     }
  6033.     if (lo == 0) {            /* If new size is 0... */
  6034.     dclarray(c,0);            /* Undeclare the array */
  6035.     return(success = 1);
  6036.     }
  6037.     n = a_dim[x];            /* Current size */
  6038.     ap = (char **) malloc((lo+1) * sizeof(char *)); /* New array */
  6039.     y = (n < lo) ? n : lo;
  6040.     for (i = 0; i <= y; i++)        /* Copy the part that fits */
  6041.       ap[i] = a_ptr[x][i];
  6042.     if (n < lo) {            /* If original array smaller */
  6043.     for (; i <= lo; i++)        /* initialize extra elements in */
  6044.       ap[i] = NULL;            /* new array to NULL. */
  6045.     } else if (n > lo) {        /* If new array smaller */
  6046.     for (; i <= lo; i++)        /* deallocate leftover elements */
  6047.       makestr(&(a_ptr[x][i]),NULL);    /* from original array. */
  6048.     }
  6049.     free((char *)a_ptr[x]);        /* Free original array list */
  6050.     a_ptr[x] = ap;            /* Replace with new one */
  6051.     a_dim[x] = lo;            /* Record the new dimension */
  6052.     if (islink > -1) {            /* Was this a link? */
  6053.     a_ptr[islink] = ap;        /* If so point to the resized array */
  6054.     a_dim[islink] = lo;
  6055.     } else {                /* If not are there links to here? */
  6056.     for (i = 0; i < (int) 'z' - ARRAYBASE; i++) { /* Any linked arrays? */
  6057.         if (i != x && a_link[i] == x) {     /* Find and update them */
  6058.         a_ptr[i] = ap;
  6059.         a_dim[i] = lo;
  6060.         }
  6061.     }
  6062.     }
  6063.     return(success = 1);
  6064. }
  6065.  
  6066. static int
  6067. copyarray() {
  6068.     int i, j, x1, lo1, hi1, x2, lo2, hi2, whole = 0;
  6069.     char c1, c2, * a1, * a2;
  6070.     if ((y = cmfld("Name of source array","",&s,NULL)) < 0)
  6071.       return(y);
  6072.     ckstrncpy(line,s,LINBUFSIZ);
  6073.     a1 = line;
  6074.     if ((x1 = arraybounds(a1,&lo1,&hi1)) < 0) {
  6075.     printf("?Bad array reference - \"%s\"\n", a1);
  6076.     return(-9);
  6077.     } else if (!a_ptr[x1]) {
  6078.     printf("?Array not declared - \"%s\"\n", a1);
  6079.     return(-9);
  6080.     }
  6081.     c1 = arrayitoa(x1);
  6082.  
  6083.     if ((y = cmfld("Name of destination array","",&s,NULL)) < 0)
  6084.       return(y);
  6085.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  6086.     a2 = tmpbuf;
  6087.     if ((x2 = arraybounds(a2,&lo2,&hi2)) < 0) {
  6088.     printf("?Bad array reference - \"%s\"\n", a2);
  6089.     return(-9);
  6090.     }
  6091.     c2 = arrayitoa(x2);
  6092.  
  6093.     if ((x = cmcfm()) < 0)
  6094.       return(x);
  6095.  
  6096.     if (c2 == '@') {            /* Argument vector array off limits */
  6097.     printf("?Sorry, \\&@[] is read-only\n");
  6098.     return(-9);
  6099.     }
  6100.     if (lo1 < 0 && lo2 < 0 && hi1 < 0 && hi2 < 0) /* Special case for */
  6101.       whole = 1;                      /* whole array... */
  6102.  
  6103.     if (lo1 < 0) lo1 = whole ? 0 : 1;    /* Supply lower bound of source */
  6104.     if (hi1 < 0) hi1 = a_dim[x1];    /* Supply upper bound of source */
  6105.     if (lo2 < 0) lo2 = whole ? 0 : 1;    /* Lower bound of target */
  6106.     if (hi2 < 0) hi2 = lo2 + hi1 - lo1;    /* Upper bound of target */
  6107.     if (a_ptr[x2]) {            /* Target array is already declared? */
  6108.     if (hi2 > a_dim[x2])        /* If upper bound out of range */
  6109.       hi2 = a_dim[x2];        /* shrink to fit */
  6110.     } else {                /* Otherwise... */
  6111.     x2 = dclarray(c2, hi2);        /* declare the target array */
  6112.     }
  6113.     for (i = lo1, j = lo2; i <= hi1 && j <= hi2; i++,j++) { /* Copy */
  6114.     makestr(&(a_ptr[x2][j]),a_ptr[x1][i]);
  6115.     }
  6116.     return(success = 1);
  6117. }
  6118.  
  6119. static int                /* Undeclare an array */
  6120. unarray() {
  6121.     int x, y, n, rc = 0;
  6122.     char c, * s;
  6123.  
  6124.     if ((y = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
  6125.     if (y == -3) {
  6126.         printf("?Array name required\n");
  6127.         return(-9);
  6128.     } else return(y);
  6129.     }
  6130.     ckstrncpy(line,s,LINBUFSIZ);    /* Make safe copy of name */
  6131.     s = line;
  6132.     if ((y = cmcfm()) < 0)
  6133.       return(y);
  6134.     if ((x = arraybounds(s,&y,&n)) < 0) { /* Parse the name, get index */
  6135.     printf("?Bad array reference - \"%s\"\n", s);
  6136.     return(-9);
  6137.     }
  6138.     if (y > 0 || n > 0) {
  6139.     printf("?Partial arrays can not be destroyed\n");
  6140.     return(-9);
  6141.     }
  6142.     c = arrayitoa(x);            /* Get array letter */
  6143.     if (a_ptr[x]) {            /* If array is declared */
  6144.     if (c == '@') {            /* Argument vector array off limits */
  6145.         printf("?Sorry, \\&@[] is read-only\n");
  6146.         return(-9);
  6147.     }
  6148.     rc = dclarray(c,0);        /* Undeclare the array */
  6149.     } else                /* It wasn't declared */
  6150.       rc = 1;
  6151.     if (rc > -1) {            /* Set return code and success */
  6152.     success = 1;
  6153.     rc = 1;
  6154.     } else {
  6155.     success = 0;
  6156.     printf("?Failed - destroy \"\\&%c[]\"\n", c);
  6157.     rc = -9;
  6158.     }
  6159.     return(rc);
  6160. }
  6161.  
  6162. static int
  6163. clrarray(cx) int cx; {
  6164.     int i, x, lo, hi;
  6165.     char c, * s, * val = NULL;
  6166.  
  6167.     if ((x = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
  6168.     if (x == -3) {
  6169.         printf("?Array name required\n");
  6170.         return(-9);
  6171.     } else return(x);
  6172.     }
  6173.     ckstrncpy(line,s,LINBUFSIZ);    /* Make safe copy of name */
  6174.     s = line;
  6175.     if (cx == ARR_SET) {        /* SET */
  6176.     if ((x = cmtxt("Value","",&val,xxstring)) < 0)
  6177.       return(x);
  6178.     ckstrncpy(tmpbuf,val,TMPBUFSIZ); /* Value to set */
  6179.     val = tmpbuf;
  6180.     if (!*val) val = NULL;
  6181.     } else if ((x = cmcfm()) < 0)    /* CLEAR */
  6182.       return(x);
  6183.  
  6184.     if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Parse the name */
  6185.     printf("?Bad array reference - \"%s\"\n", s);
  6186.     return(-9);
  6187.     }
  6188.     c = arrayitoa(x);            /* Get array letter */
  6189.     if (!a_ptr[x]) {            /* If array is declared */
  6190.     printf("?Array %s is not declared\n", s);
  6191.     return(-9);
  6192.     } else if (c == '@') {        /* Argument vector array off limits */
  6193.     printf("?Sorry, \\&@[] is read-only\n");
  6194.     return(-9);
  6195.     }
  6196.     if (lo < 0) lo = 0;
  6197.     if (hi < 0) hi = a_dim[x];
  6198.     for (i = lo; i <= hi; i++)        /* Clear/Set selected range */
  6199.       makestr(&(a_ptr[x][i]),val);
  6200.  
  6201.     return(success = 1);
  6202. }
  6203.  
  6204. extern char **aa_ptr[CMDSTKL][28];
  6205. extern int aa_dim[CMDSTKL][28];
  6206.  
  6207. static int                /* Create symbolic link to an array */
  6208. linkarray() {
  6209.     int i = 0, x, y, lo, hi, flag = 0;
  6210.     char c, * s, * p;
  6211.  
  6212.     if ((x = cmfld("Array name not currently in use","",&s,NULL)) < 0) {
  6213.     if (x == -3) {
  6214.         printf("?Array name required\n");
  6215.         return(-9);
  6216.     } else return(x);
  6217.     }
  6218.     ckstrncpy(line,s,LINBUFSIZ);    /* Make safe copy of link name */
  6219.     s = line;
  6220.     if ((x = cmfld("Name of existing array","",&p,xxstring)) < 0) {
  6221.     if (x == -3) {
  6222.         printf("?Array name required\n");
  6223.         return(-9);
  6224.     } else return(x);
  6225.     }
  6226.     ckstrncpy(tmpbuf,p,TMPBUFSIZ);    /* Make safe copy of array name */
  6227.     p = tmpbuf;
  6228.     if ((x = cmcfm()) < 0)
  6229.       return(x);
  6230.  
  6231.     if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Parse the link name */
  6232.     printf("?Bad array reference - \"%s\"\n", s);
  6233.     return(-9);
  6234.     }
  6235.     if (a_ptr[x]) {            /* Must not already exist */
  6236.     c = arrayitoa(x);
  6237.     printf("?Array already exists: \\&%c[]\n", c);
  6238.     return(-9);
  6239.     }
  6240.     if (lo > -1 || hi > -1) {
  6241.     printf("?Sorry, whole arrays only: %s\n",s);
  6242.     return(-9);
  6243.     }
  6244.     if ((y = arraybounds(p,&lo,&hi)) < 0) { /* Parse the array name */
  6245.     printf("?Bad array reference - \"%s\"\n", s);
  6246.     return(-9);
  6247.     }
  6248.     if (lo > -1 || hi > -1) {
  6249.     printf("?Sorry, whole arrays only: %s\n",p);
  6250.     return(-9);
  6251.     }
  6252.     if (x == y) {
  6253.     for (i = cmdlvl; i >= 0; i--)
  6254.       if (aa_ptr[i][x]) {
  6255.           flag++;
  6256.           break;
  6257.       }
  6258.     }
  6259.     if (flag) {
  6260.     a_ptr[x] = aa_ptr[i][y];    /* Link to saved copy */
  6261.     a_dim[x] = aa_dim[i][y];
  6262.     } else {                /* Otherwise... */
  6263.     c = arrayitoa(y);        /* Check if it's declared */
  6264.     if (!a_ptr[y]) {
  6265.         printf("?Array is not declared: \\&%c[]\n", c);
  6266.         return(-9);
  6267.     }
  6268.     if (a_link[y] > -1) {        /* And if it's a link itself */
  6269.         printf("?Links to links not allowed: \\&%c[]\n", c);
  6270.         return(-9);
  6271.     }
  6272.     a_ptr[x] = a_ptr[y];        /* All OK, make the link */
  6273.     a_dim[x] = a_dim[y];
  6274.     }
  6275.     a_link[x] = y;
  6276.     return(success = 1);
  6277. }
  6278. #endif /* NOSPL */
  6279.  
  6280. #ifndef NOCSETS
  6281. static char * dcsetname = NULL;
  6282.  
  6283. /* Get Display Character-Set Name */
  6284.  
  6285. char *
  6286. getdcset() {
  6287.     char * s;
  6288.     int y;
  6289. #ifdef PCFONTS
  6290.     extern int tt_font, ntermfont;
  6291.     extern struct keytab term_font[];
  6292. #endif /* PCFONTS */
  6293.  
  6294.     s = "";
  6295. #ifdef OS2
  6296.     y = os2getcp();            /* Default is current code page */
  6297.     switch (y) {
  6298.       case 437: s = "cp437"; break;
  6299.       case 850: s = "cp850"; break;
  6300.       case 852: s = "cp852"; break;
  6301.       case 857: s = "cp857"; break;
  6302.       case 858: s = "cp858"; break;
  6303.       case 862: s = "cp862"; break;
  6304.       case 866: s = "cp866"; break;
  6305.       case 869: s = "cp869"; break;
  6306.       case 1250: s = "cp1250"; break;
  6307.       case 1251: s = "cp1251"; break;
  6308.       case 1252: s = "cp1252"; break;
  6309.       case 1253: s = "cp1253"; break;
  6310.       case 1254: s = "cp1254"; break;
  6311.       case 1255: s = "cp1255"; break;
  6312.       case 1256: s = "cp1256"; break;
  6313.       case 1257: s = "cp1257"; break;
  6314.       case 1258: s = "cp1258"; break;
  6315.     }
  6316. #ifdef PCFONTS
  6317. /*
  6318.    If the user has loaded a font with SET TERMINAL FONT then we want
  6319.    to change the default code page to the font that was loaded.
  6320. */
  6321.     if (tt_font != TTF_ROM) {
  6322.     for (y = 0; y < ntermfont; y++ ) {
  6323.         if (term_font[y].kwval == tt_font) {
  6324.         s = term_font[y].kwd;
  6325.         break;
  6326.         }
  6327.     }
  6328.     }
  6329. #endif /* PCFONTS */
  6330. #else /* OS2 */
  6331. #ifdef COMMENT
  6332.     /* Hack not needed as of C-Kermit 7.1 */
  6333.     if (fcharset == FC_1LATIN) {
  6334.     s = "latin1-iso";        /* Hack to avoid reporting "cp1252" */
  6335.     } else {                /* Report current file character set */
  6336. #endif /* COMMENT */
  6337.     for (y = 0; y <= nfilc; y++)
  6338.       if (fcstab[y].kwval == fcharset) {
  6339.           s = fcstab[y].kwd;
  6340.           break;
  6341.       }
  6342. #ifdef COMMENT
  6343.     }
  6344. #endif /* COMMENT */
  6345. #endif /* OS2 */
  6346.     makestr(&dcsetname,s);        /* Return stable pointer */
  6347.     return((char *)dcsetname);
  6348. }
  6349. #endif /* NOCSETS */
  6350.  
  6351. #ifndef NOFRILLS
  6352. static int
  6353. doclear() {
  6354.     if ((x = cmkey(clrtab,nclear,"item to clear",
  6355. #ifdef NOSPL
  6356.            "device-buffer"
  6357. #else
  6358.            "device-and-input"
  6359. #endif /* NOSPL */
  6360.            ,xxstring)) < 0) return(x);
  6361. #ifndef NOSPL
  6362. #ifdef OS2
  6363.     if (x == CLR_CMD || x == CLR_TRM) {
  6364.     if ((z = cmkey(clrcmdtab,nclrcmd,"how much screen to clear\n",
  6365.                "all",xxstring)) < 0)
  6366.       return(z);
  6367.     }
  6368. #endif /* OS2 */
  6369. #endif /* NOSPL */
  6370.     if ((y = cmcfm()) < 0)
  6371.       return(y);
  6372.  
  6373.     /* Clear device input buffer if requested */
  6374.     y = (x & CLR_DEV) ? ttflui() : 0;
  6375.  
  6376.     if (x & CLR_SCR)            /* CLEAR SCREEN */
  6377.       y = ck_cls();            /* (= SCREEN CLEAR = CLS) */
  6378.  
  6379.     if (x & CLR_KBD) {            /* CLEAR KEYBOARD */
  6380.     int n;
  6381.     n = conchk();
  6382.     y = 0;
  6383.     while (n-- > 0 && (y = coninc(0) > -1))
  6384.       ;
  6385.     y = (y > -1) ? 0 : -1;
  6386.     }
  6387.  
  6388. #ifndef NOSPL
  6389.     /* Clear INPUT command buffer if requested */
  6390.     if (x & CLR_INP) {
  6391.     for (z = 0; z < inbufsize; z++)
  6392.       inpbuf[z] = NUL;
  6393.     inpbp = inpbuf;
  6394.     y = 0;
  6395.     }
  6396. #ifdef CK_APC
  6397.     if (x & CLR_APC) {
  6398.     debug(F101,"Executing CLEAR APC","",apcactive);
  6399.     apcactive = 0;
  6400.     y = 0;
  6401.     }
  6402. #endif /* CK_APC */
  6403.     if (x & CLR_ALR) {
  6404.     setalarm(0L);
  6405.     y = 0;
  6406.     }
  6407. #endif /* NOSPL */
  6408.  
  6409. #ifdef PATTERNS
  6410.     if (x & (CLR_TXT|CLR_BIN)) {
  6411.     int i;
  6412.     for (i = 0; i < FTPATTERNS; i++) {
  6413.         if (x & CLR_TXT)
  6414.           makestr(&txtpatterns[i],NULL);
  6415.         if (x & CLR_BIN)
  6416.           makestr(&binpatterns[i],NULL);
  6417.     }
  6418.     y = 0;
  6419.     }
  6420. #endif /* PATTERNS */
  6421.  
  6422. #ifndef NODIAL
  6423.     if (x & CLR_DIA) {
  6424.     dialsta = DIA_UNK;
  6425.     y = 0;
  6426.     }
  6427. #endif /* NODIAL */
  6428.  
  6429. #ifndef NOMSEND
  6430.     if (x & CLR_SFL) {            /* CLEAR SEND-LIST */
  6431.     if (filehead) {
  6432.         struct filelist * flp, * next;
  6433.         flp = filehead;
  6434.         while (flp) {
  6435.         if (flp->fl_name)
  6436.           free(flp->fl_name);
  6437.         if (flp->fl_alias)
  6438.           free(flp->fl_alias);
  6439.         next = flp->fl_next;
  6440.         free((char *)flp);
  6441.         flp = next;
  6442.         }
  6443.     }
  6444.     filesinlist = 0;
  6445.     filehead = NULL;
  6446.     filetail = NULL;
  6447.     addlist = 0;
  6448.     y = 0;
  6449.     }
  6450. #endif /* NOMSEND */
  6451.  
  6452. #ifdef OS2
  6453. #ifndef NOLOCAL
  6454.     switch (x) {
  6455.       case CLR_SCL:
  6456.     clearscrollback(VTERM);
  6457.     break;
  6458.       case CLR_CMD:
  6459.     switch ( z ) {
  6460.       case CLR_C_ALL:
  6461.         clear();
  6462.         break;
  6463.       case CLR_C_BOS:
  6464.         clrboscr_escape(VCMD,SP);
  6465.         break;
  6466.       case CLR_C_BOL:
  6467.         clrbol_escape(VCMD,SP);
  6468.         break;
  6469.       case CLR_C_EOL:
  6470.         clrtoeoln(VCMD,SP);
  6471.         break;
  6472.       case CLR_C_EOS:
  6473.         clreoscr_escape(VCMD,SP);
  6474.         break;
  6475.       case CLR_C_LIN:
  6476.         clrline_escape(VCMD,SP);
  6477.         break;
  6478.       case CLR_C_SCR:
  6479.         clearscrollback(VCMD);
  6480.         break;
  6481.     default:
  6482.         printf("Not implemented yet, sorry.\n");
  6483.         break;
  6484.     }
  6485.     break;
  6486.  
  6487. #ifndef NOTERM
  6488.       case CLR_TRM:
  6489.      switch ( z ) {
  6490.       case CLR_C_ALL:
  6491.          if (VscrnGetBufferSize(VTERM) > 0 ) {
  6492.          VscrnScroll(VTERM, UPWARD, 0,
  6493.                  VscrnGetHeight(VTERM)-(tt_status[VTERM]?2:1),
  6494.                  VscrnGetHeight(VTERM) -
  6495.                  (tt_status[VTERM]?1:0), TRUE, SP
  6496.                  );
  6497.          cleartermscreen(VTERM);
  6498.          }
  6499.          break;
  6500.       case CLR_C_BOS:
  6501.         clrboscr_escape(VTERM,SP);
  6502.         break;
  6503.       case CLR_C_BOL:
  6504.         clrbol_escape(VTERM,SP);
  6505.         break;
  6506.       case CLR_C_EOL:
  6507.         clrtoeoln(VTERM,SP);
  6508.         break;
  6509.       case CLR_C_EOS:
  6510.         clreoscr_escape(VTERM,SP);
  6511.         break;
  6512.       case CLR_C_LIN:
  6513.         clrline_escape(VTERM,SP);
  6514.         break;
  6515.      case CLR_C_SCR:
  6516.          clearscrollback(VTERM);
  6517.          break;
  6518.      default:
  6519.          printf("Not implemented yet, sorry.\n");
  6520.          break;
  6521.     }
  6522.     break;
  6523. #endif /* NOTERM */
  6524.     }
  6525.     y = 0;
  6526. #endif /* NOLOCAL */
  6527. #endif /* OS2 */
  6528.     return(success = (y == 0));
  6529. }
  6530. #endif /* NOFRILLS */
  6531.  
  6532. #ifndef NOSPL
  6533. static int
  6534. doeval(cx) int cx; {
  6535.     char *p;
  6536.     char vnambuf[VNAML], * vnp = NULL;    /* These must be on the stack */
  6537.     if (!oldeval) {
  6538.     if ((y = cmfld("Variable name","",&s,
  6539.                ((cx == XX_EVAL) ? xxstring : NULL))) < 0) {
  6540.         if (y == -3) {
  6541.         printf("?Variable name required\n");
  6542.         return(-9);
  6543.         } else return(y);
  6544.     }
  6545.     ckstrncpy(vnambuf,s,VNAML);    /* Make a copy. */
  6546.     vnp = vnambuf;
  6547.     if (vnambuf[0] == CMDQ &&
  6548.         (vnambuf[1] == '%' || vnambuf[1] == '&'))
  6549.       vnp++;
  6550.     y = 0;
  6551.     if (*vnp == '%' || *vnp == '&') {
  6552.         if ((y = parsevar(vnp,&x,&z)) < 0)
  6553.           return(y);
  6554.     }
  6555.     }
  6556.     if ((x = cmtxt("Integer arithmetic expression","",&s,xxstring)) < 0)
  6557.       return(x);
  6558.     p = evala(s);
  6559.     if (!p) p = "";
  6560.     if (oldeval && *p)
  6561.       printf("%s\n", p);
  6562.     ckstrncpy(evalbuf,p,32);
  6563.     if (!oldeval)
  6564.       return(success = addmac(vnambuf,p));
  6565.     else
  6566.       return(success = *p ? 1 : 0);
  6567. }
  6568. #endif /* NOSPL */
  6569.  
  6570. #ifdef TNCODE
  6571. static int
  6572. dotelopt() {
  6573.     if ((x = cmkey(telcmd, ntelcmd, "TELNET command", "", xxstring)) < 0 )
  6574.       return(x);
  6575.     switch (x) {
  6576.       case WILL:
  6577.       case WONT:
  6578.       case DO:
  6579.       case DONT:
  6580.     if ((y = cmkey(tnopts,ntnopts,"TELNET option","",xxstring)) < 0)
  6581.       return(y);
  6582.     if ((z = cmcfm()) < 0) return(z);
  6583.  
  6584.     switch (x) {
  6585.       case WILL:
  6586.         if (TELOPT_UNANSWERED_WILL(y))
  6587.           return(success = 0);
  6588.         break;
  6589.       case WONT:
  6590.         if (TELOPT_UNANSWERED_WONT(y))
  6591.           return(success = 0);
  6592.         break;
  6593.       case DO:
  6594.         if (TELOPT_UNANSWERED_DO(y))
  6595.           return(success = 0);
  6596.         break;
  6597.       case DONT:
  6598.         if (TELOPT_UNANSWERED_DONT(y))
  6599.           return(success = 0);
  6600.         break;
  6601.     }
  6602.     if (local) {
  6603.         success = ((tn_sopt(x,y) > -1) ? 1 : 0);
  6604.     } else {
  6605.         printf("ff%02x%02x\n",x,y);
  6606.         success = 1;
  6607.     }
  6608.     if (success) {
  6609.         switch (x) {
  6610.           case WILL:
  6611.         TELOPT_UNANSWERED_WILL(y) = 1;
  6612.         break;
  6613.           case WONT:
  6614.         if ( TELOPT_ME(y) )
  6615.           TELOPT_UNANSWERED_WONT(y) = 1;
  6616.         break;
  6617.           case DO:
  6618.         TELOPT_UNANSWERED_DO(y) = 1;
  6619.         break;
  6620.           case DONT:
  6621.         if ( TELOPT_ME(y) )
  6622.           TELOPT_UNANSWERED_DONT(y) = 1;
  6623.         break;
  6624.         }
  6625.         if (tn_wait("XXTELOP") < 0) {
  6626.         tn_push();
  6627.         success = 0;
  6628.         }
  6629.     }
  6630.     return(success);
  6631.       case SB:
  6632.     if ((y=cmkey(tnsbopts,ntnsbopts,"TELNET option","",xxstring)) < 0)
  6633.       return(y);
  6634.     switch (y) {
  6635.       case TELOPT_NAWS:
  6636.         /* Some compilers require switch() to have at least 1 case */
  6637. #ifdef CK_NAWS
  6638.         TELOPT_SB(TELOPT_NAWS).naws.x = 0;
  6639.         TELOPT_SB(TELOPT_NAWS).naws.y = 0;
  6640.         if (local)
  6641.           return(success = ((tn_snaws() > -1) ? 1 : 0));
  6642.         else
  6643.           return(success = 0);
  6644. #else
  6645.         return(success = 0);
  6646. #endif /* CK_NAWS */
  6647.     }
  6648.         return(success = 0);
  6649.  
  6650. #ifdef CK_KERBEROS
  6651. #ifdef KRB5
  6652.       case TN_FWD:
  6653.         success = (kerberos5_forward() == AUTH_SUCCESS);
  6654.         return(success);
  6655. #endif /* KRB5 */
  6656. #endif /* CK_KERBEROS */
  6657.  
  6658.       default:
  6659.     if ((z = cmcfm()) < 0) return(z);
  6660. #ifndef NOLOCAL
  6661.     if (local) {
  6662.         CHAR temp[3];
  6663.         if (network && IS_TELNET()) { /* TELNET */
  6664.         temp[0] = (CHAR) IAC;
  6665.         temp[1] = x;
  6666.         temp[2] = NUL;
  6667.         success = (ttol((CHAR *)temp,2) > -1 ? 1 : 0);
  6668.         if (tn_deb || debses || deblog) {
  6669.             /* TN_MSG_LEN is in ckctel.h */
  6670.             ckmakmsg(tn_msg,256,"TELNET SENT ",TELCMD(x),NULL,NULL);
  6671.             debug(F101,tn_msg,"",x);
  6672.             if (debses || tn_deb) tn_debug(tn_msg);
  6673.         }
  6674.         return(success);
  6675.         }
  6676.             return(success = 0);
  6677.     } else {
  6678. #endif /* NOLOCAL */
  6679.         printf("ff%02x\n",x);
  6680.         return(success = 1);
  6681. #ifndef NOLOCAL
  6682.     }
  6683. #endif /* NOLOCAL */
  6684.     }
  6685. }
  6686. #endif /* TNCODE */
  6687.  
  6688.  
  6689. #ifndef NOPUSH
  6690. #ifndef NOFRILLS
  6691. static int
  6692. doedit() {
  6693. #ifdef OS2
  6694.     char * p = NULL;
  6695. #endif /* OS2 */
  6696.     if (!editor[0]) {
  6697.     s = getenv("EDITOR");
  6698.     if (s) ckstrncpy(editor,s,CKMAXPATH);
  6699.     editor[CKMAXPATH] = NUL;
  6700.     if (!editor[0]) {
  6701.         printf("?Editor not defined - use SET EDITOR to define\n");
  6702.         return(-9);
  6703.     }
  6704.     }
  6705.     ckstrncpy(tmpbuf,editfile,TMPBUFSIZ);
  6706. /*
  6707.   cmiofi() lets us parse the name of an existing file, or the name of
  6708.   a nonexistent file to be created.
  6709. */
  6710.     x = cmiofi("File to edit", (char *)tmpbuf, &s, &y, xxstring);
  6711.     if (x < 0) {
  6712.     if (x == -9) {
  6713.         if (zchko(s) < 0) {
  6714.         printf("Can't create \"%s\"\n",s);
  6715.         return(x);
  6716.         }
  6717.     } else if (x != -3)
  6718.       return(x);
  6719.     }
  6720.     if (x == -3)
  6721.       tmpbuf[0] = NUL;
  6722.     else {
  6723.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  6724.     if (iswild((char *)tmpbuf)) {
  6725.         printf("?A single file please\n");
  6726.         return(-9);
  6727.     }
  6728.     }
  6729.     if ((z = cmcfm()) < 0) return(z);
  6730.     if (nopush) {
  6731.     printf("?Sorry, editing not allowed\n");
  6732.     return(success = 0);
  6733.     }
  6734.     if (tmpbuf[0]) {
  6735.     /* Get full path in case we change directories between EDIT commands */
  6736.     zfnqfp(tmpbuf, CKMAXPATH, editfile);
  6737.     editfile[CKMAXPATH] = NUL;
  6738. #ifdef OS2
  6739.     p = editfile;            /* Flip the stupid slashes */
  6740.     while (*p) {
  6741.         if (*p == '/') *p = '\\';
  6742.         p++;
  6743.     }
  6744. #endif /* OS2 */
  6745.     } else
  6746.       editfile[0] = NUL;
  6747.     x = 0;
  6748.     if (editopts[0]) {
  6749. #ifdef OS2
  6750.     x = ckindex("%1",(char *)editopts,0,0,1);
  6751.     if (x > 0)
  6752.       editopts[x] = 's';
  6753.     else
  6754. #endif /* OS2 */
  6755.       x = ckindex("%s",(char *)editopts,0,0,1);
  6756.     }
  6757.     if (((int)strlen(editopts) + (int)strlen(editfile) + 1) < TMPBUFSIZ) {
  6758.     if (x)
  6759.       sprintf(tmpbuf,editopts,editfile);
  6760.     else
  6761.       sprintf(tmpbuf,"%s %s",editopts,editfile);
  6762.     }
  6763.     s = line;
  6764.     ckmakmsg(s,LINBUFSIZ,editor," ",tmpbuf,NULL);
  6765. #ifdef OS2
  6766.     p = s + strlen(editor);        /* And again with the slashes */
  6767.     while (p != s) {
  6768.     if (*p == '/') *p = '\\';
  6769.     p--;
  6770.     }
  6771. #endif /* OS2 */
  6772.     conres();
  6773.     x = zshcmd(s);
  6774.     concb((char)escape);
  6775.     return(x);
  6776. }
  6777. #endif /* NOFRILLS */
  6778. #endif /* NOPUSH */
  6779.  
  6780. #ifdef BROWSER
  6781. static int
  6782. dobrowse() {
  6783. #ifdef OS2
  6784.     char * p = NULL;
  6785. #endif /* OS2 */
  6786.     if (nopush) {
  6787.     printf("?Sorry, browsing not allowed\n");
  6788.     return(success = 0);
  6789.     }
  6790. #ifndef NT
  6791.     /* Windows lets the Shell Execute the URL if no Browser is defined */
  6792.     if (!browser[0]) {
  6793.     s = getenv("BROWSER");
  6794.     if (s) ckstrncpy(browser,s,CKMAXPATH);
  6795.     browser[CKMAXPATH] = NUL;
  6796.     if (!browser[0]) {
  6797.         printf("?Browser not defined - use SET BROWSER to define\n");
  6798.         return(-9);
  6799.     }
  6800.     }
  6801. #endif /* NT */
  6802.     ckstrncpy(tmpbuf,browsurl,TMPBUFSIZ);
  6803.     if ((x = cmtxt("URL",(char *)browsurl,&s,xxstring)) < 0)
  6804.       return(x);
  6805.     ckstrncpy(browsurl,s,4096);
  6806.     x = 0;
  6807.     if (browsopts[0]) {
  6808. #ifdef OS2
  6809.     x = ckindex("%1",(char *)browsopts,0,0,1);
  6810.     if (x > 0)
  6811.       browsopts[x] = 's';
  6812.     else
  6813. #endif /* OS2 */
  6814.       x = ckindex("%s",(char *)browsopts,0,0,1);
  6815.     }
  6816.     if (((int)strlen(browsopts) + (int)strlen(browsurl) + 1) < TMPBUFSIZ) {
  6817.     if (x)
  6818.       sprintf(tmpbuf,browsopts,browsurl);
  6819.     else
  6820.       sprintf(tmpbuf,"%s %s",browsopts,browsurl);
  6821.     }
  6822. #ifdef NT
  6823.     if (!browser[0])
  6824.       return(success = Win32ShellExecute(browsurl));
  6825. #endif /* NT */
  6826.     s = line;
  6827.     ckmakmsg(s,LINBUFSIZ,browser," ",tmpbuf,NULL);
  6828. #ifdef OS2
  6829.     p = line + strlen(browser);        /* Flip slashes */
  6830.     while (p != line) {
  6831.     if (*p == '/') *p = '\\';
  6832.     p--;
  6833.     }
  6834. #endif /* OS2 */
  6835.     conres();
  6836.     x = zshcmd(s);
  6837.     concb((char)escape);
  6838.     return(x);
  6839. }
  6840. #endif /* BROWSER */
  6841.  
  6842. #ifdef CK_RECALL
  6843. static int
  6844. doredo() {            /* Find a previous cmd and redo it */
  6845.     extern int on_recall, in_recall;
  6846.     int x;
  6847.     char * p;
  6848.  
  6849.     if ((x = cmtxt(
  6850. "pattern, or first few characters of a previous command",
  6851.            "*",&s,xxstring)) < 0)
  6852.       return(x);
  6853.     ckstrncpy(line,s,LINBUFSIZ);
  6854.     x = strlen(s);
  6855.     s = line;
  6856.     if (*s == '{') {            /* Braces disable adding * to end */
  6857.     if (s[x-1] == '}') {
  6858.         s[x-1] = NUL;
  6859.         s++;
  6860.         x--;
  6861.     }
  6862.     } else {                /* No braces, add * to end. */
  6863.     s[x] = '*';
  6864.     s[x+1] = NUL;
  6865.     }
  6866.  
  6867.     while (x > 0 && s[x] == '*' && s[x-1] == '*') s[x--] = NUL;
  6868.  
  6869.     if (!on_recall || !in_recall) {
  6870.     printf("?Sorry, command recall can't be used now.\n");
  6871.     return(-9);
  6872.     }
  6873.     if ((p = cmgetcmd(s))) {        /* Look for it history buffer */
  6874.     ckmakmsg(cmdbuf,CMDBL,p,"\r",NULL,NULL); /* Copy to command buffer */
  6875.     if (!quiet)            /* Echo it */
  6876.       printf("%s\n",cmdbuf);
  6877.     cmaddnext();            /* Force re-add to history buffer */
  6878.     return(cmflgs = -1);        /* Force reparse */
  6879.     } else {
  6880.     printf("?Sorry - \"%s\" not found\n", s);
  6881.     return(-9);
  6882.     }
  6883. }
  6884. #endif /* CK_RECALL */
  6885.  
  6886. #ifndef NOXFER
  6887. #ifndef NOCSETS
  6888. static int
  6889. doassoc()  {                /* ASSOCIATE */
  6890.     extern struct keytab tcstab[];
  6891.     extern int ntcs;
  6892.     if ((x = cmkey(assoctab, nassoc, "", "", xxstring)) < 0 )
  6893.       return(x);
  6894.  
  6895.     switch (x) {            /* Associate what? */
  6896.  
  6897.       case ASSOC_TC:            /* Transfer character-set... */
  6898.     if ((x = cmkey(tcstab, ntcs,
  6899.                "transfer character-set name","",xxstring)) < 0)
  6900.       return(x);
  6901.     if ((y = cmkey(fcstab, nfilc,
  6902.                "with file character-set","", xxstring)) < 0)
  6903.       if (y != -3)
  6904.         return(y);
  6905.     if ((z = cmcfm()) < 0)
  6906.       return(z);
  6907.     axcset[x] = y;
  6908.     return(success = 1);
  6909.  
  6910.       case ASSOC_FC:            /* File character-set... */
  6911.     if ((x = cmkey(fcstab, nfilc,
  6912.                "file character-set name","",xxstring)) < 0)
  6913.       return(x);
  6914.     if ((y = cmkey(tcstab, ntcs,
  6915.                "with transfer character-set","", xxstring)) < 0)
  6916.       if (y != -3)
  6917.         return(y);
  6918.     if ((z = cmcfm()) < 0)
  6919.       return(z);
  6920.     afcset[x] = y;
  6921.     return(success = 1);
  6922.  
  6923.       default:
  6924.     return(-2);
  6925.     }
  6926. }
  6927. #endif /* NOCSETS */
  6928. #endif /* NOXFER */
  6929.  
  6930. #ifndef NOHELP
  6931. static int
  6932. domanual() {
  6933. #ifdef OS2
  6934.     if ((x = cmcfm()) < 0)
  6935.       return(x);
  6936.     if (nopush) {
  6937.     printf("?Sorry, access to system commands is disabled.\n");
  6938.     return(-9);
  6939.     }
  6940.     y = mxlook(mactab,"manual",nmac);
  6941.     if (y > -1) {
  6942.     z = maclvl;            /* Save the current maclvl */
  6943.     dodo(y,NULL,cmdstk[cmdlvl].ccflgs); /* Run the macro */
  6944.     while (maclvl > z) {
  6945.         debug(F101,"XXMAN loop maclvl 1","",maclvl);
  6946.         sstate = (CHAR) parser(1);
  6947.         debug(F101,"XXMAN loop maclvl 2","",maclvl);
  6948.         if (sstate) proto();
  6949.     }
  6950.     debug(F101,"XXMAN loop exit maclvl","",maclvl);
  6951.     return(success);
  6952.     }
  6953.     return(success = 0);
  6954. #else
  6955.     if ((x = cmtxt(
  6956. #ifdef UNIX
  6957.            "Carriage return to confirm the command, or manual topic",
  6958. #else
  6959.            "Carriage return to confirm the command, or help topic",
  6960. #endif /* UNIX */
  6961.            "kermit",
  6962.            &s,
  6963.            xxstring
  6964.            )
  6965.      ) < 0)
  6966.       return(x);
  6967. #endif /* OS2 */
  6968.  
  6969. #ifdef UNIX
  6970.     ckmakmsg(tmpbuf,TMPBUFSIZ,"man ",s,NULL,NULL);
  6971. #else
  6972.     ckmakmsg(tmpbuf,TMPBUFSIZ,"help ",s,NULL,NULL);
  6973. #endif /* UNIX */
  6974.     debug(F110,"MANUAL",tmpbuf,0);
  6975.     if (nopush) {
  6976.     printf("?Sorry, access to system commands is disabled.\n");
  6977.     return(-9);
  6978.     } else {
  6979.     conres();            /* Restore the console */
  6980.     success = zshcmd(tmpbuf);
  6981.     concb((char)escape);        /* Restore CBREAK mode */
  6982.     return(success);
  6983.     }
  6984. }
  6985. #endif /* NOHELP */
  6986.  
  6987. #ifndef NOHTTP
  6988. #ifdef TCPSOCKET
  6989. static struct keytab sslswtab[] = {
  6990.     { "/ssl", 1, 0 },
  6991.     { "/tls", 1, 0 }
  6992. };
  6993.  
  6994. #ifndef NOURL
  6995. struct urldata http_url = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};
  6996. #endif /* NOURL */
  6997.  
  6998. static int
  6999. dohttp() {                /* HTTP */
  7000.     struct FDB sw, kw, fi;
  7001.     int n, getval, allinone = 0;
  7002.     char c, * p;
  7003.     char rdns[128];
  7004.  
  7005.     char * http_agent = NULL;        /* Parse results */
  7006.     char * http_hdr   = NULL;
  7007.     char * http_user  = NULL;
  7008.     char * http_pass  = NULL;
  7009.     char * http_mime  = NULL;
  7010.     char * http_lfile = NULL;
  7011.     char * http_rfile = NULL;
  7012.     char * http_dfile = NULL;
  7013.     char   http_array = NUL;
  7014.     int    http_action = -1;
  7015.  
  7016.     char * http_host = NULL;
  7017.     char * http_srv  = NULL;
  7018.     int    http_ssl  = 0;
  7019.  
  7020.     static char * http_d_agent = NULL;
  7021.     static char * http_d_user = NULL;
  7022.     static char * http_d_pass = NULL;
  7023.  
  7024.     static int    http_d_type = 0;
  7025.     int           http_type = http_d_type;
  7026.  
  7027. #ifdef OS2
  7028.     p = "Kermit 95";            /* Default user agent */
  7029. #else
  7030.     p = "C-Kermit";
  7031. #endif /* OS2 */
  7032.     makestr(&http_agent,p);
  7033.     makestr(&http_mime,"text/HTML");    /* MIME type default */
  7034.     rdns[0] = '\0';
  7035.  
  7036.     cmfdbi(&sw,                /* 1st FDB - general switches */
  7037.        _CMKEY,                /* fcode */
  7038.        "OPEN, CLOSE, GET, HEAD, PUT, INDEX, or POST,\n or switch", /* hlpmsg */
  7039.        "",                /* default */
  7040.        "",                /* addtl string data */
  7041.        nhttpswtab,            /* addtl numeric data 1: tbl size */
  7042.        4,                /* addtl numeric data 2: 4 = cmswi */
  7043.        xxstring,            /* Processing function */
  7044.        httpswtab,            /* Keyword table */
  7045.        &kw                /* Pointer to next FDB */
  7046.        );
  7047.     cmfdbi(&kw,                /* 2nd FDB - commands */
  7048.        _CMKEY,                /* fcode */
  7049.        "Command",            /* hlpmsg */
  7050.        "",                /* default */
  7051.        "",                /* addtl string data */
  7052.        nhttptab,            /* addtl numeric data 1: tbl size */
  7053.        0,                /* addtl numeric data 2: 0 = keyword */
  7054.        xxstring,            /* Processing function */
  7055.        httptab,                /* Keyword table */
  7056.        NULL                /* Pointer to next FDB */
  7057.        );
  7058.  
  7059.     while (1) {
  7060.     x = cmfdb(&sw);            /* Parse something */
  7061.     if (x < 0)            /* Error */
  7062.       goto xhttp;
  7063.     n = cmresult.nresult;
  7064.     if (cmresult.fdbaddr == &kw)    /* Command - exit this loop */
  7065.       break;
  7066.     c = cmgbrk();            /* Switch... */
  7067.     getval = (c == ':' || c == '=');
  7068.     x = -9;
  7069.     if (getval && !(cmgkwflgs() & CM_ARG)) {
  7070.         printf("?This switch does not take an argument\n");
  7071.         goto xhttp;
  7072.     }
  7073.     switch (cmresult.nresult) {    /* Handle each switch */
  7074.           case HT_SW_TP:                /* /TOSCREEN */
  7075.             http_type = 1;
  7076.             break;
  7077.       case HT_SW_AG:        /* /AGENT */
  7078.         if (getval) {
  7079.         if ((x = cmfld("User agent",p,&s,xxstring)) < 0)
  7080.           goto xhttp;
  7081.         } else {
  7082.         s = p;
  7083.         }
  7084.         makestr(&http_agent,s);
  7085.         break;
  7086.       case HT_SW_HD:        /* /HEADER */
  7087.         s = NULL;
  7088.         if (getval) {
  7089.         if ((x = cmfld("Header line","",&s,xxstring)) < 0) {
  7090.             if (x == -3)
  7091.               s = NULL;
  7092.             else
  7093.               goto xhttp;
  7094.         }
  7095.         }
  7096.         makestr(&http_hdr,s);
  7097.         break;
  7098.       case HT_SW_US:        /* /USER */
  7099.         s = NULL;
  7100.         if (getval) {
  7101.         if ((x = cmfld("User ID","",&s,xxstring)) < 0) {
  7102.                   if (x == -3)
  7103.                     s = "";
  7104.                   else
  7105.             goto xhttp;
  7106.                 }
  7107.         }
  7108.         makestr(&http_user,s);
  7109.         break;
  7110.       case HT_SW_PW:        /* /PASSWORD */
  7111.         debok = 0;
  7112.         s = NULL;
  7113.         if (getval) {
  7114.         if ((x = cmfld("Password","",&s,xxstring)) < 0)
  7115.           goto xhttp;
  7116.         }
  7117.         makestr(&http_pass,s);
  7118.         break;
  7119. #ifndef NOSPL
  7120.       case HT_SW_AR: {        /* /ARRAY: */
  7121.           char * s2, array = NUL;
  7122.           if (!getval) {
  7123.           printf("?This switch requires an argument\n");
  7124.           x = -9;
  7125.           goto xhttp;
  7126.           }
  7127.           if ((x = cmfld("Array name (a single letter will do)",
  7128.                  "",
  7129.                  &s,
  7130.                  NULL
  7131.                  )) < 0) {
  7132.           if (x == -3) {
  7133.               printf("?Array name required\n");
  7134.               x = -9;
  7135.               goto xhttp;
  7136.           } else
  7137.             goto xhttp;
  7138.           }
  7139.           if (!*s) {
  7140.           printf("?Array name required\n");
  7141.           x = -9;
  7142.           goto xhttp;
  7143.           }
  7144.           s2 = s;
  7145.           if (*s == CMDQ) s++;
  7146.           if (*s == '&') s++;
  7147.           if (!isalpha(*s)) {
  7148.           printf("?Bad array name - \"%s\"\n",s2);
  7149.           x = -9;
  7150.           goto xhttp;
  7151.           }
  7152.           array = *s++;
  7153.           if (isupper(array))
  7154.         array = tolower(array);
  7155.           if (*s && (*s != '[' || *(s+1) != ']')) {
  7156.           printf("?Bad array name - \"%s\"\n",s2);
  7157.           http_array = NUL;
  7158.           x = -9;
  7159.           goto xhttp;
  7160.           }
  7161.           http_array = array;
  7162.           break;
  7163.       }
  7164. #endif /* NOSPL */
  7165.       default:
  7166.         x = -2;
  7167.         goto xhttp;
  7168.     }
  7169.     }
  7170.     http_action = n;            /* Save the action */
  7171.     if (http_action == HTTP_PUT || http_action == HTTP_POS) {
  7172.     cmfdbi(&sw,            /* 1st FDB - switch */
  7173.            _CMKEY,            /* fcode */
  7174.            "Local filename\n Or switch", /* help */
  7175.            "",            /* default */
  7176.            "",            /* addtl string data */
  7177.            nhttpptab,        /* keyword table size */
  7178.            4,            /* addtl numeric data 2: 4 = cmswi */
  7179.            xxstring,        /* Processing function */
  7180.            httpptab,        /* Keyword table */
  7181.            &fi            /* Pointer to next FDB */
  7182.            );
  7183.     cmfdbi(&fi,            /* 2nd FDB - filename */
  7184.            _CMIFI,            /* fcode */
  7185.            "Local filename",    /* hlpmsg */
  7186.            "",            /* default */
  7187.            "",            /* addtl string data */
  7188.            0,            /* addtl numeric data 1 */
  7189.            0,            /* addtl numeric data 2 */
  7190.            xxstring,
  7191.            NULL,
  7192.            NULL
  7193.            );
  7194.     while (1) {
  7195.         x = cmfdb(&sw);
  7196.         if (x < 0)
  7197.           goto xhttp;        /* Free any malloc'd temp strings */
  7198.         n = cmresult.nresult;
  7199.         if (cmresult.fcode != _CMKEY)
  7200.           break;
  7201.         c = cmgbrk();        /* Switch... */
  7202.         getval = (c == ':' || c == '=');
  7203.         if (getval && !(cmgkwflgs() & CM_ARG)) {
  7204.         printf("?This switch does not take an argument\n");
  7205.         x = -9;
  7206.         goto xhttp;
  7207.         }
  7208.         switch (n) {
  7209.           case HT_PP_MT:
  7210.         s = "text/HTML";
  7211.         if (getval) {
  7212.             if ((x = cmfld("MIME type",
  7213.                    "text/HTML",&s,xxstring)) < 0)
  7214.               goto xhttp;
  7215.         }
  7216.         makestr(&http_mime,s);
  7217.         break;
  7218.           default:
  7219.         x = -2;
  7220.         goto xhttp;
  7221.         }
  7222.     }
  7223.     makestr(&http_lfile,cmresult.sresult);
  7224.     n = ckindex("/",http_lfile,-1,1,0);
  7225.     if (n)
  7226.       p = &http_lfile[n];
  7227.     else
  7228.       p = http_lfile;
  7229.     if ((x = cmfld("URL or remote filename",p,&s,xxstring)) < 0) {
  7230.           if (x == -3) {
  7231.             printf("?%s what?\n",(http_action == HTTP_PUT) ? "Put" : "Post");
  7232.             x = -9;
  7233.           }
  7234.           goto xhttp;
  7235.         }
  7236.     if (!*s) s = NULL;
  7237.     makestr(&http_rfile,s);
  7238.  
  7239.     if ((x = cmtxt("Response filename","",&s,xxstring)) < 0) {
  7240.           if (x != -3)
  7241.             goto xhttp;
  7242.         }
  7243.         if (*s)
  7244.           makestr(&http_dfile,s);
  7245.     }
  7246.     switch (http_action) {
  7247.       case HTTP_DEL:            /* DELETE */
  7248.     if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
  7249.           if (x == -3) {
  7250.             printf("?Delete what?\n");
  7251.             x = -9;
  7252.           }
  7253.           goto xhttp;
  7254.         }
  7255.     makestr(&http_rfile,s);
  7256.     break;
  7257.       case HTTP_CON:            /* CONNECT */
  7258.         if ((x = cmfld("Remote host[:port]","",&s,xxstring)) < 0) {
  7259.           if (x == -3) {
  7260.             printf("?Remote host[:port] is required\n");
  7261.             x = -9;
  7262.           }
  7263.           goto xhttp;
  7264.         }
  7265.     makestr(&http_rfile,s);
  7266.     break;
  7267.       case HTTP_HED: {            /* HEAD */
  7268.       char buf[CKMAXPATH+1];
  7269.       if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
  7270.           if (x == -3) {
  7271.           printf("?Head of what?\n");
  7272.           x = -9;
  7273.           }
  7274.           goto xhttp;
  7275.       }
  7276.       makestr(&http_rfile,s);
  7277.  
  7278.       if (http_array || http_type) { /* Default result filename */
  7279.           p = "";             /* None if /ARRAY or /TOSCREEN */
  7280.       } else {
  7281.           n = ckindex("/",http_rfile,-1,1,0); /* Otherwise strip path */
  7282.           if (n)                          /* and add ".head" */
  7283.         p = &http_rfile[n];
  7284.           else
  7285.         p = http_rfile;
  7286.           ckmakmsg(buf,CKMAXPATH,p,".head",NULL,NULL);
  7287.           p = buf;
  7288.       }
  7289.       if ((x = cmofi("Local filename",p,&s,xxstring)) < 0) {
  7290.           if (x != -3)
  7291.         goto xhttp;
  7292.       }
  7293.       makestr(&http_lfile,s);
  7294.       break;
  7295.       }
  7296.       case HTTP_GET:            /* GET */
  7297.       case HTTP_IDX: {            /* INDEX */
  7298.       char * lfile = "";
  7299.       if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
  7300.           if (x == -3) {
  7301.           printf("?Get what?\n");
  7302.           x = -9;
  7303.           }
  7304.           goto xhttp;
  7305.       }
  7306.       makestr(&http_rfile,s);
  7307.       if (http_action == HTTP_GET && !http_type)
  7308.         zstrip(http_rfile,&lfile);
  7309.       if ((x = cmofi("Local filename",lfile,&s,xxstring)) < 0)
  7310.         if (x != -3)
  7311.           goto xhttp;
  7312.       makestr(&http_lfile,s);
  7313.       break;
  7314.       }
  7315.       case HTTP_OPN: {
  7316.       int sslswitch = 0;
  7317. #ifdef CK_SSL
  7318.       struct FDB sw, fl;
  7319.       cmfdbi(&sw,
  7320.          _CMKEY,        /* fcode */
  7321.          "IP host name or address, or switch", /* hlpmsg */
  7322.          "",            /* default */
  7323.          "",            /* addtl string data */
  7324.          2,            /* addtl numeric data 1: tbl size */
  7325.          4,            /* addtl numeric data 2: 4 = cmswi */
  7326.          xxstring,        /* Processing function */
  7327.          sslswtab,        /* Keyword table */
  7328.          &fl            /* Pointer to next FDB */
  7329.          );
  7330.       cmfdbi(&fl,            /* 2nd FDB - host */
  7331.          _CMFLD,        /* fcode */
  7332.          "",            /* hlpmsg */
  7333.          "",            /* default */
  7334.          "",            /* addtl string data */
  7335.          0,            /* addtl numeric data 1 */
  7336.          0,            /* addtl numeric data 2 */
  7337.          xxstring,
  7338.          NULL,
  7339.          NULL
  7340.          );
  7341.       x = cmfdb(&sw);        /* Parse switch or host */
  7342.       if (x < 0)            /* Error */
  7343.         goto xhttp;
  7344.       if (cmresult.fcode == _CMFLD) { /* Host */
  7345.           s = cmresult.sresult;      /* Set up expected pointer */
  7346.           goto havehost;              /* Go parse rest of command */
  7347.       }
  7348.       sslswitch = 1;        /* /SSL or /TLS switch - set flag */
  7349. #endif /* CK_SSL */
  7350.  
  7351.       /* Parse host */
  7352.  
  7353.       if ((x = cmfld("URL, hostname, or ip-address","",&s,xxstring)) < 0) {
  7354.           if (x == -3) {
  7355.           printf("?Open what?\n");
  7356.           x = -9;
  7357.           }
  7358.           goto xhttp;
  7359.       }
  7360.  
  7361.     havehost:            /* Come here with s -> host */
  7362. #ifdef CK_URL
  7363.       x = urlparse(s,&http_url);    /* Was a URL given? */
  7364.       if (x < 1) {            /* Not a URL */
  7365. #endif /* CK_URL */
  7366.           makestr(&http_host,s);
  7367.           if ((x =
  7368.            cmfld("Service name or port number",
  7369.              "http",&s,xxstring)) < 0)
  7370.         goto xhttp;
  7371.           else
  7372.         makestr(&http_srv,s);
  7373. #ifdef CK_URL
  7374.       } else if (ckstrcmp(http_url.svc,"http",-1,0) && /* Non-HTTP URL */
  7375.              ckstrcmp(http_url.svc,"https",-1,0)) {
  7376.           printf("?Non-HTTP URL\n");
  7377.           x = -9;
  7378.           goto xhttp;
  7379.       } else {            /* Have HTTP URL */
  7380.           makestr(&http_srv, http_url.svc);
  7381.           makestr(&http_user,http_url.usr);
  7382.           makestr(&http_pass,http_url.psw);
  7383.           makestr(&http_host,http_url.hos);
  7384.           if (http_url.por)
  7385.         makestr(&http_srv,http_url.por);
  7386.           makestr(&http_rfile,http_url.pth);
  7387.       }
  7388.       if (http_rfile) {        /* Open, GET, and Close */
  7389.           printf("?Directory/file path not allowed in HTTP OPEN URL\n");
  7390.           x = -9;
  7391.           goto xhttp;
  7392.       }
  7393.       if (!ckstrcmp("https",http_srv,-1,0) || sslswitch ||
  7394.           !ckstrcmp("443",http_srv,-1,0))
  7395.         http_ssl = 1;
  7396. #endif /* CK_URL */
  7397.       break;
  7398.       }
  7399.       case HTTP_CLS:
  7400.         break;
  7401.     }
  7402.     if ((x = cmcfm()) < 0)
  7403.       goto xhttp;
  7404.  
  7405.     if (http_action == HTTP_OPN) {
  7406.         x = (http_open(http_host,http_srv,http_ssl,rdns,128) == 0);
  7407.         if (x) {
  7408.             if (!quiet) {
  7409.               if (rdns[0])
  7410.                 printf("Connected to %s [%s]\r\n",http_host,rdns);
  7411.               else
  7412.                 printf("Connected to %s\r\n",http_host);
  7413.             }
  7414.             if (http_agent) {
  7415.                 if (http_d_agent)
  7416.           free(http_d_agent);
  7417.                 http_d_agent = http_agent;
  7418.                 http_agent = NULL;
  7419.             }
  7420.             if (http_user) {
  7421.                 if (http_d_user)
  7422.           free(http_d_user);
  7423.                 http_d_user = http_user;
  7424.                 http_user = NULL;
  7425.             }
  7426.             if (http_pass) {
  7427.                 if (http_d_pass) {
  7428.                     memset(http_d_pass,0,strlen(http_d_pass));
  7429.                     free(http_d_pass);
  7430.                 }
  7431.                 http_d_pass = http_pass;
  7432.                 http_pass = NULL;
  7433.             }
  7434.             http_d_type = http_type;
  7435.         } else {
  7436.             if (!quiet)
  7437.           printf("?HTTP Connection failed.\r\n");
  7438.         }
  7439.     } else if (http_action == HTTP_CLS) {
  7440.         if (http_d_agent) {
  7441.             free(http_d_agent);
  7442.             http_d_agent = NULL;
  7443.         }
  7444.         if (http_d_user) {
  7445.             free(http_d_user);
  7446.             http_d_user = NULL;
  7447.         }
  7448.         if (http_d_pass) {
  7449.             memset(http_d_pass,0,strlen(http_d_pass));
  7450.             free(http_d_pass);
  7451.             http_d_pass = NULL;
  7452.         }
  7453.         http_d_type = 0;
  7454.         x = (http_close() == 0);
  7455.     }
  7456.     if ((http_action != HTTP_CLS) &&
  7457.     (http_action != HTTP_CON) && http_rfile) { /* Remote file is URL? */
  7458.  
  7459.     /* All-in-one actions when a URL is given... */
  7460.  
  7461. #ifdef CK_URL
  7462.     if (urlparse(http_rfile,&http_url) > 0) { /* Have URL? */
  7463.         if (ckstrcmp(http_url.svc,"http",-1,0) && /* It's an HTTP URL? */
  7464.         ckstrcmp(http_url.svc,"https",-1,0)) {
  7465.         printf("?Non-HTTP URL\n");
  7466.         x = -9;
  7467.         goto xhttp;
  7468.         } else {            /* Yes, collect the pieces */
  7469.         makestr(&http_srv, http_url.svc);
  7470.         makestr(&http_user,http_url.usr);
  7471.         makestr(&http_pass,http_url.psw);
  7472.         makestr(&http_host,http_url.hos);
  7473.         if (http_url.por)
  7474.           makestr(&http_srv,http_url.por);
  7475.         makestr(&http_rfile,http_url.pth);
  7476.         }
  7477.         if (!http_rfile) {        /* Still have a path? */
  7478.                 makestr(&http_rfile,"/");
  7479.         }
  7480.         if (!ckstrcmp("https",http_srv,-1,0) || /* Check for SSL/TLS */
  7481.         !ckstrcmp("443",http_srv,-1,0))
  7482.           http_ssl = 1;
  7483.         if (http_isconnected())    /* Close any open HTTP connection */
  7484.           http_close();
  7485.         if (http_pass == NULL && http_d_pass != NULL)
  7486.           makestr(&http_pass,http_d_pass);
  7487.         x = (http_open(http_host,http_srv,http_ssl,rdns,128) == 0);
  7488.         if (x < 0) {
  7489.         x = 0;
  7490.         goto xhttp;
  7491.         }
  7492.         allinone = 1;
  7493.     }
  7494. #endif /* CK_URL */
  7495.         if (http_pass == NULL && http_d_pass != NULL)
  7496.       makestr(&http_pass,http_d_pass);
  7497.  
  7498.     if (http_action == HTTP_OPN && allinone) {
  7499.         http_action = HTTP_GET;
  7500.     }
  7501.         x = xdohttp(http_action,
  7502.                     http_lfile,
  7503.             http_rfile,
  7504.                     http_dfile,
  7505.             http_agent ? http_agent : http_d_agent,
  7506.             http_hdr,
  7507.             http_user  ? http_user  : http_d_user,
  7508.             http_pass  ? http_pass  : http_d_pass,
  7509.             http_mime,
  7510.             http_array,
  7511.             http_type
  7512.             );
  7513.     if (allinone)
  7514.       x = (http_close() == 0);
  7515.     }
  7516.  
  7517.   xhttp:
  7518.     if (http_agent) free(http_agent);
  7519.     if (http_hdr)   free(http_hdr);
  7520.     if (http_user)  free(http_user);
  7521.     if (http_pass) {
  7522.         memset(http_pass,0,strlen(http_pass));
  7523.         free(http_pass);
  7524.     }
  7525.     if (http_mime)  free(http_mime);
  7526.     if (http_lfile) free(http_lfile);
  7527.     if (http_rfile) free(http_rfile);
  7528.     if (http_dfile) free(http_dfile);
  7529.     if (http_host)  free(http_host);
  7530.     if (http_srv)   free(http_srv);
  7531.  
  7532.     if (x > -1)
  7533.       success = x;
  7534.     return(x);
  7535. }
  7536. #endif /* TCPSOCKET */
  7537. #endif /* NOHTTP */
  7538.  
  7539.  
  7540. #ifndef NOSPL
  7541. static int
  7542. dotrace() {
  7543.     int on = 1;
  7544.     struct FDB sw, kw;
  7545.     cmfdbi(&sw,                /* 1st FDB - switch */
  7546.        _CMKEY,            /* fcode */
  7547.        "Trace object;\n Or switch", /* help */
  7548.        "",                /* default */
  7549.        "",                /* addtl string data */
  7550.        2,                /* keyword table size */
  7551.        4,                /* addtl numeric data 2: 4 = cmswi */
  7552.        xxstring,            /* Processing function */
  7553.        onoffsw,            /* Keyword table */
  7554.        &kw                /* Pointer to next FDB */
  7555.        );
  7556.     cmfdbi(&kw,                /* 2nd FDB - Trace object */
  7557.        _CMKEY,            /* fcode */
  7558.        "Trace object",        /* help */
  7559.        "all",            /* default */
  7560.        "",                /* addtl string data */
  7561.        ntracetab,            /* keyword table size */
  7562.        0,                /* addtl numeric data 2: 0 = keyword */
  7563.        xxstring,            /* Processing function */
  7564.        tracetab,            /* Keyword table */
  7565.        NULL                /* Pointer to next FDB */
  7566.        );
  7567.     if ((x = cmfdb(&sw)) < 0)
  7568.       return(x);
  7569.     if (cmresult.fdbaddr == &sw) {
  7570.     on = cmresult.nresult;
  7571.     if ((x = cmkey(tracetab, ntracetab,"","all",xxstring)) < 0)
  7572.       return(x);
  7573.     } else {
  7574.     x = cmresult.nresult;
  7575.     }
  7576.     if ((y = cmcfm()) < 0)
  7577.       return(y);
  7578.  
  7579.     switch (x) {
  7580.       case TRA_ASG:
  7581.     tra_asg = on;
  7582.     break;
  7583.       case TRA_CMD:
  7584.     tra_cmd = on;
  7585.     break;
  7586.       case TRA_ALL:
  7587.     tra_asg = on;
  7588.     tra_cmd = on;
  7589.     break;
  7590.       default:
  7591.     return(-2);
  7592.     }
  7593.     printf("TRACE %s\n", on ? "ON" : "OFF");
  7594.     return(success = 1);
  7595. }
  7596. #endif /* NOSPL */
  7597.  
  7598.  
  7599. static int
  7600. doprompt() {
  7601.     extern int xcmdsrc;
  7602.     if ((x = cmtxt("Optional message","",&s,xxstring)) < 0)
  7603.       return(x);
  7604. #ifdef NOSPL
  7605.     printf("?Sorry, PROMPT requires script programming language\n");
  7606.     return(-9);
  7607. #else
  7608.     debug(F101,"Prompt cmdlvl","",cmdlvl);
  7609.     cmdlvl++;
  7610.     if (cmdlvl > CMDSTKL) {
  7611.     printf("?Command stack overflow: %d\n",cmdlvl);
  7612.     cmdlvl--;
  7613.     return(-9);
  7614.     }
  7615.     xcmdsrc = CMD_KB;
  7616.     cmdstk[cmdlvl].src = CMD_KB;    /* Say we're at the prompt */
  7617.     cmdstk[cmdlvl].lvl = 0;
  7618.     cmdstk[cmdlvl].ccflgs = cmdstk[cmdlvl-1].ccflgs;
  7619.     if (tra_cmd)
  7620.       printf("[%d] +P: \"(prompt)\"\n",cmdlvl);
  7621.     concb((char)escape);
  7622.     if (!quiet)
  7623.       printf(
  7624. "(Recursive command prompt: Resume script with CONTINUE, STOP to stop...)\n"
  7625.             );
  7626.     if (*s) {                /* If prompt given */
  7627.     makestr(&(prstring[cmdlvl-1]),cmgetp()); /* Save current prompt */
  7628.     cmsetp(s);            /* Set new one */
  7629.     }
  7630.     return(success = 1);
  7631. #endif /* NOSPL */
  7632. }
  7633.  
  7634. #ifdef CKLEARN
  7635. VOID
  7636. learncmd(s) char *s; {            /* Record commands in learned script */
  7637.     char buf[64];
  7638.     int i, k;
  7639.     if (learnfp && learning) {        /* Only if open and on */
  7640.     k = ckstrncpy(buf,s,64);
  7641.     for (i = 0; i < k; i++) {    /* Get top-level command keyword */
  7642.         if (buf[i] <= SP) {
  7643.         buf[i] = NUL;
  7644.         break;
  7645.         }
  7646.     }
  7647.     k = lookup(cmdtab,buf,ncmd,NULL); /* Look it up */
  7648.     if (k == XXCON || k == XXLEARN)      /* Don't record CONNECT or LEARN */
  7649.       return;
  7650.     if (k == XXTEL) {
  7651.         fputs("SET HOST /NETWORK:TCP",learnfp);
  7652.         fputs(&s[i],learnfp);
  7653.         fputs(" TELNET /TELNET",learnfp);
  7654.         fputs("\nIF FAIL STOP 1 Connection failed\n",learnfp);
  7655.     } else {
  7656.         fputs(s,learnfp);
  7657.         fputs("\n",learnfp);
  7658.     }
  7659.     }
  7660. }
  7661. #endif /* CKLEARN */
  7662.  
  7663.  
  7664. /*  D O C M D  --  Do a command  */
  7665.  
  7666. /*
  7667.  Returns:
  7668.    -2: user typed an illegal command
  7669.    -1: reparse needed
  7670.     0: parse was successful (even tho command may have failed).
  7671. */
  7672. #ifdef DEBUG
  7673. int cmdstats[256] = { -1, -1 };
  7674. #endif /* DEBUG */
  7675.  
  7676. int
  7677. docmd(cx) int cx; {
  7678.     extern int nolocal, cmkwflgs;
  7679.  
  7680.     debug(F101,"docmd entry, cx","",cx);
  7681.     activecmd = cx;
  7682.     doconx = ((activecmd == XXCON)  || (activecmd == XXTEL) ||
  7683.           (activecmd == XXRLOG) || (activecmd == XXPIPE) ||
  7684.               (activecmd == XXIKSD) || (activecmd == XXPTY));
  7685. /*
  7686.   Originally all commands were handled with a big switch() statement,
  7687.   but eventually this started blowing up compilers.  Now we have a series
  7688.   of separate if statements and small switches, with the commands that are
  7689.   most commonly executed in scipts and loops coming first, to speed up
  7690.   compute-bound scripts.
  7691.   */
  7692.  
  7693. #ifdef DEBUG
  7694.     if (cmdstats[0] == -1) {        /* Count commands */
  7695.     int i;                /* for tuning... */
  7696.     for (i = 0; i < 256; i++)
  7697.       cmdstats[i] = 0;
  7698.     }
  7699. #endif /* DEBUG */
  7700.  
  7701.     switch (cx) {
  7702.       case -4:                /* EOF */
  7703. #ifdef OSK
  7704.     if (msgflg)  printf("\n");
  7705. #else
  7706.     if (msgflg)  printf("\r\n");
  7707. #endif /* OSK */
  7708.       doexit(GOOD_EXIT,xitsta);
  7709.       case -3:                /* Null command */
  7710.     return(0);
  7711.       case -9:                /* Like -2, but errmsg already done */
  7712.       case -1:                /* Reparse needed */
  7713.     return(cx);
  7714.       case -6:                /* Special */
  7715.       case -2:                /* Error, maybe */
  7716.  
  7717. #ifndef NOSPL
  7718. /*
  7719.   Maybe they typed a macro name.  Let's look it up and see.
  7720. */
  7721.     if (cx == -6)            /* If they typed CR */
  7722.       ckstrncat(cmdbuf,"\015",CMDBL); /*  add it back to command buffer. */
  7723.     if (ifcmd[cmdlvl] == 2)        /* Watch out for IF commands. */
  7724.       ifcmd[cmdlvl]--;
  7725.     repars = 1;            /* Force reparse */
  7726.     cmres();
  7727.     cx = XXDO;            /* Try DO command */
  7728. #else
  7729.     return(cx);
  7730. #endif /* NOSPL */
  7731.       default:
  7732.     if (cx < 0)
  7733.       return(cx);
  7734.     break;
  7735.     }
  7736. #ifdef DEBUG
  7737.     if (cx < 256)
  7738.       cmdstats[cx]++;
  7739. #endif /* DEBUG */
  7740.  
  7741.     if ((cmkwflgs & CM_PSH)
  7742. #ifndef NOPUSH
  7743.     && nopush
  7744. #endif /* NOPUSH */
  7745.     ) {
  7746.     printf("?Access to system disabled\n");
  7747.     return(-9);
  7748.     }
  7749.     if ((cmkwflgs & CM_LOC)
  7750. #ifndef NOLOCAL
  7751.     && nolocal
  7752. #endif /* NOLOCAL */
  7753.     ) {
  7754.     printf("?Connections disabled\n");
  7755.     return(-9);
  7756.     }
  7757.  
  7758. #ifndef NOSPL
  7759.     /* Used in FOR loops */
  7760.  
  7761.     if (cx == XX_INCR || cx == XXINC  || /* _INCREMENT, INCREMENT */
  7762.     cx == XX_DECR || cx == XXDEC)     /* _DECREMENT, DECREMENT */
  7763.       return(doincr(cx));
  7764.  
  7765.     /* Define (or change the definition of) a macro or variable */
  7766.  
  7767.     if (cx == XXUNDEF || cx == XXUNDFX) {
  7768. #ifdef IKSD
  7769.     if (inserver && !ENABLED(en_asg)) {
  7770.         printf("?Sorry, DEFINE/ASSIGN disabled\n");
  7771.         return(-9);
  7772.     }
  7773. #endif /* IKSD */
  7774.     return(doundef(cx));        /* [_]UNDEFINE */
  7775.     }
  7776.     if (cx == XXDEF || cx == XXASS ||
  7777.     cx == XXDFX || cx == XXASX) {
  7778. #ifdef IKSD
  7779.     if (inserver && !ENABLED(en_asg)) {
  7780.         printf("?Sorry, DEFINE/ASSIGN disabled\n");
  7781.         return(-9);
  7782.     }
  7783. #endif /* IKSD */
  7784.     if (atmbuf[0] == '.' && !atmbuf[1]) /* "." entered as keyword */
  7785.       xxdot = 1;            /* i.e. with space after it... */
  7786.     return(dodef(cx));        /* DEFINE, ASSIGN, etc... */
  7787.     }
  7788.  
  7789.     /* IF, WHILE, and friends  */
  7790.  
  7791.     if (cx == XXIF || cx == XXIFX || cx == XXWHI || cx == XXASSER) {
  7792.     return(doif(cx));
  7793.     }
  7794.     if (cx == XXSWIT) {            /* SWITCH */
  7795.     return(doswitch());
  7796.     }
  7797.  
  7798.     /* GOTO, FORWARD, and _FORWARD (used internally by FOR, WHILE, etc) */
  7799.  
  7800.     if (cx == XXGOTO || cx == XXFWD || cx == XXXFWD) { /* GOTO or FORWARD */
  7801.     /* Note, here we don't set SUCCESS/FAILURE flag */
  7802. #ifdef COMMENT
  7803.     if ((y = cmfld("label","",&s,xxstring)) < 0) {
  7804.         if (y == -3) {
  7805.         if (cx != XXXFWD) {
  7806.             printf("?Label name required\n");
  7807.             return(-9);
  7808.         }
  7809.         } else
  7810.           return(y);
  7811.     }
  7812.     ckstrncpy(lblbuf,s,LBLSIZ);
  7813.     if ((x = cmcfm()) < 0) return(x);
  7814. #else
  7815.     if ((y = cmtxt("label","",&s,xxstring)) < 0) {
  7816.         if (y == -3) {
  7817.         if (cx != XXXFWD) {
  7818.             printf("?GOTO: Label name required: \"%s\" \"%s\"\n",
  7819.                atmbuf,
  7820.                cmdbuf);
  7821.             return(-9);
  7822.         }
  7823.         } else
  7824.           return(y);
  7825.     }
  7826.     ckstrncpy(lblbuf,brstrip(s),LBLSIZ);
  7827. #endif /* COMMENT */
  7828.     s = lblbuf;
  7829.     return(dogoto(s,cx));
  7830.     }
  7831.     if (cx == XXDO || cx == XXMACRO) {    /* DO (a macro) */
  7832.     char mnamebuf[16];        /* (buffer for controlled temp name) */
  7833.     struct FDB kw, fl;
  7834.     int mx;                /* Macro index (on stack!) */
  7835.  
  7836.     debug(F101,"XXMACRO 0",line,cx);
  7837.     if (cx == XXDO) {
  7838.         if (nmac == 0) {
  7839.         printf("\n?No macros defined\n");
  7840.         return(-9);
  7841.         }
  7842.         for (y = 0; y < nmac; y++) { /* copy the macro table into a */
  7843.         mackey[y].kwd = mactab[y].kwd; /* regular keyword table */
  7844.         mackey[y].kwval = y;    /* with value = pointer to macro tbl */
  7845.         mackey[y].flgs = mactab[y].flgs;
  7846.         }
  7847.         cmfdbi(&kw,            /* First FDB - macro name */
  7848.            _CMKEY,        /* fcode */
  7849.            "Macro",        /* hlpmsg */
  7850.            "",            /* default */
  7851.            "",            /* addtl string data */
  7852.            nmac,        /* addtl numeric data 1: tbl size */
  7853.            0,            /* addtl numeric data 2: 0 = cmkey */
  7854.            xxstring,        /* Processing function */
  7855.            mackey,        /* Keyword table */
  7856.            &fl            /* Pointer to next FDB */
  7857.            );
  7858.         cmfdbi(&fl,            /* 2nd FDB - for "{" */
  7859.            _CMFLD,        /* fcode */
  7860.            "",            /* hlpmsg */
  7861.            "",
  7862.            "",            /* addtl string data */
  7863.            0,            /* addtl numeric data 1 */
  7864.            0,            /* addtl numeric data 2 */
  7865.            xxstring,
  7866.            NULL,
  7867.            NULL
  7868.            );
  7869.         x = cmfdb(&kw);        /* Parse something */
  7870.         if (x < 0) {        /* Error */
  7871.         if (x == -3) {
  7872.             printf("?Macro name required\n");
  7873.             return(-9);
  7874.         } else
  7875.           return(x);
  7876.         }
  7877.         if (cmresult.fcode == _CMKEY) {
  7878.         extern int mtchanged;
  7879.         char * macroname = NULL;
  7880.  
  7881.         /* In case args include an \fexec() that changes the macro table */
  7882.  
  7883.         mx = x;            /* Save macro index on stack */
  7884.         mtchanged = 0;        /* Mark state of macro table */
  7885.         makestr(¯oname,mactab[mx].kwd); /* Save name */
  7886.  
  7887.         if ((y = cmtxt("optional arguments","",&s,xxstring)) < 0)
  7888.           return(y);        /* Get macro args */
  7889.  
  7890.         if (mtchanged) {    /* Macro table changed? */
  7891.             mx = mlook(mactab,macroname,nmac); /* Look up name again */
  7892.         }
  7893.         if (macroname)
  7894.           free(macroname);
  7895.  
  7896.         return(dodo(mx,s,cmdstk[cmdlvl].ccflgs) < 1 ?
  7897.                (success = 0) : 1);
  7898.         }
  7899.         ckstrncpy(line,cmresult.sresult,LINBUFSIZ);    /* _CMFLD */
  7900.         if (atmbuf[0] == '{') {
  7901.         if ((y = cmcfm()) < 0)
  7902.           return(y);
  7903.         }
  7904.     } else {            /* XXMACRO ("immediate macro") */
  7905.         int k = 0;
  7906.         line[k++] = '{';
  7907.         line[k++] = SP;
  7908.         line[k] = NUL;
  7909.         debug(F111,"XXMACRO A",line,k);
  7910.         /* Defer evaluation of variables until the commands are exec'd */
  7911.         if ((y = cmtxt("Braced list of commands","",&s,NULL)) < 0)
  7912.           return(y);
  7913.         k = ckstrncpy(line+k,s,LINBUFSIZ-k);
  7914.         debug(F111,"XXMACRO B",line,k);
  7915.     }
  7916.     x = strlen(line);
  7917.     if ((line[0] == '{' && line[x-1] != '}') || line[0] == '}')
  7918.       return(-2);
  7919.     if (line[0] != '{' && line[x-1] != '}') {
  7920.         /* Unknown command.  If ON_UNKNOWN_COMMAND macro is defined, */
  7921.         /* parse args and then execute it, but only if it is not */
  7922.         /* already active. */
  7923.         int k = -1;
  7924.         if (!unkmacro) {
  7925.         k = mxlook(mactab,"on_unknown_command",nmac);
  7926.         }
  7927.         if (k > -1) {
  7928.         ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ);
  7929.         z = maclvl;        /* Save the current maclvl */
  7930.         if ((y = cmtxt("text","",&s,xxstring)) < 0)
  7931.           return(y);
  7932.         ckstrncat(tmpbuf," ",TMPBUFSIZ);
  7933.         ckstrncat(tmpbuf,s,TMPBUFSIZ);
  7934.         unkmacro = 1;
  7935.         debug(F110,"ON_UNKNOWN_COMMAND",s,0);
  7936.         dodo(k,tmpbuf,cmdstk[cmdlvl].ccflgs); /* Run the macro */
  7937.         while (maclvl > z) {
  7938.             sstate = (CHAR) parser(1);
  7939.             if (sstate) proto();
  7940.         }
  7941.         debug(F101,"UNKMAC loop exit maclvl","",maclvl);
  7942.         unkmacro = 0;
  7943.         return(success);
  7944.         }
  7945.             if (x > 0)
  7946.           printf("?Not a command or macro name: \"%s\"\n",line);
  7947.             else
  7948.           printf("?Not a command or macro name.\n");
  7949.         return(-9);
  7950.     }
  7951.     s = brstrip(line);
  7952.     sprintf(mnamebuf," ..tmp:%03d",cmdlvl);    /* safe (16) */
  7953.     x = addmac(mnamebuf,s);
  7954.     return(dodo(x,NULL,cmdstk[cmdlvl].ccflgs) < 1 ? (success = 0) : 1);
  7955.     }
  7956.  
  7957.     if (cx == XXLBL) {            /* LABEL */
  7958.     if ((x = cmfld("label","",&s,xxstring)) < 0) {
  7959.         if (x == -3) {
  7960. #ifdef COMMENT
  7961.         printf("?LABEL: Label name required: \"%s\"\n", cmdbuf);
  7962.         return(-9);
  7963. #else
  7964.         s = "";
  7965. #endif /* COMMENT */
  7966.         } else return(x);
  7967.  
  7968.     }
  7969.     debug(F111,"LABEL",s,x);
  7970.     if ((x = cmcfm()) < 0) return(x);
  7971.     return(0);
  7972.     }
  7973.  
  7974.     if (cx == XXEVAL || cx == XX_EVAL) /* _EVALUATE,  EVALUATE  */
  7975.       return(doeval(cx));
  7976.  
  7977. #ifndef NOSEXP
  7978.     if (cx == XXSEXP) {            /* Lisp-like S-Expression */
  7979.     struct stringarray * q;
  7980.     char /* *p, *r, */ *tmp, *m;
  7981.     int i, k, n, quote = 0, contd = 0, size = 0, len = 0;
  7982.     extern int sexprc, sexppv;
  7983.  
  7984.     tmp = tmpbuf;            /* Buffer to collect SEXP */
  7985.     tmpbuf[0] = NUL;        /* Clear it */
  7986.     size = TMPBUFSIZ;        /* Capacity of buffer */
  7987.     sexprc = -1;            /* Assume bad input */
  7988.     n = 0;                /* Paren balance counter */
  7989.  
  7990.     while (1) {            /* Allow SEXP on multiple lines */
  7991.         m = contd ?
  7992.           "Continuation of S-Expression" :
  7993.         "S-Expression (\"help sexp\" for details)";
  7994.         x = cmtxt(m,"",&s,xxstring);
  7995.         if (x < 0)
  7996.           return(x);
  7997.         if (!*s)            /* Needed for (=) and (:) */
  7998.           s = atmbuf;
  7999.         k = ckmakmsg(tmp, size, contd ? " " : "(", s, NULL, NULL);
  8000.         if (k < 1) {
  8001.         printf("?SEXP too long - %d max\n",TMPBUFSIZ);
  8002.         return(-9);
  8003.         }
  8004.         debug(F111,contd ? "sexp contd" : "sexp",s,k);
  8005.  
  8006.         for (i = len; i < len+k; i++) { /* Check balance  */
  8007.         if (!quote && tmpbuf[i] == CMDQ) {
  8008.             quote = 1;
  8009.             continue;
  8010.         }
  8011.         if (quote) {
  8012.             quote = 0;
  8013.             continue;
  8014.         }
  8015.         if (tmpbuf[i] == '(')
  8016.           n++;
  8017.         else if (tmpbuf[i] == ')')
  8018.           n--;
  8019.         }
  8020.         if (n == 0) {        /* Break when balanced */
  8021.         break;
  8022.         }
  8023.         if (n < 0) {        /* Too many right parens */
  8024.         printf("?Unbalanced S-Expression: \"%s\"\n",tmpbuf);
  8025.         return(-9);
  8026.         }
  8027.         contd++;            /* Need more right parens */
  8028.         cmini(ckxech);        /* so keep parsing */
  8029.         tmp += k;            /* adjust buffer pointer */
  8030.         size -= k;            /* and capacity */
  8031.         len += k;            /* and length so far */
  8032.     }
  8033.     s = tmpbuf;
  8034.     makestr(&lastsexp,s);
  8035.     q = cksplit(1,SEXPMAX,s,NULL,NULL,8,0,0); /* Precheck for > 1 SEXP */
  8036.     debug(F101,"sexp split","",q->a_size);
  8037.  
  8038.     if (q->a_size == 1) {        /* We should get exactly one back */
  8039.         char * result, * dosexp();
  8040.         sexprc = 0;            /* Reset out-of-band return code */
  8041.         result = dosexp(s);        /* Get result */
  8042.         debug(F111,"sexp result",result,sexprc);
  8043.         if (sexprc == 0) {        /* Success */
  8044.         /* Echo the result if desired */
  8045.         if ((!xcmdsrc && sexpecho != SET_OFF) || sexpecho == SET_ON)
  8046.           printf(" %s\n",result ? result : "");
  8047.         makestr(&sexpval,result);
  8048.         success = sexppv > -1 ? sexppv : 1;
  8049.         return(success);
  8050.         }
  8051.     }
  8052.     if (sexprc < 0)
  8053.       printf("?Invalid S-Expression: \"%s\"\n",lastsexp);
  8054.     return(-9);
  8055.     }
  8056. #endif /* NOSEXP */
  8057.  
  8058. #endif /* NOSPL */
  8059.  
  8060.     if (cx == XXECH || cx == XXXECH || cx == XXVOID
  8061. #ifndef NOSPL
  8062.     || cx == XXAPC
  8063. #endif /* NOSPL */
  8064.     ) {                /* ECHO or APC */
  8065.     if ((x = cmtxt((cx == XXECH || cx == XXXECH) ?
  8066.                "Text to be echoed" :
  8067.                ((cx == XXVOID) ? "Text" :
  8068.             "Application Program Command text"),
  8069.                "",
  8070.                &s,
  8071.                xxstring
  8072.                )
  8073.          ) < 0)
  8074.       return(x);
  8075.     if (!s) s = "";
  8076. #ifdef COMMENT
  8077. /* This is to preserver the pre-8.0 behavior but it's too confusing */
  8078.     x = strlen(s);
  8079.     x = (x > 1) ? ((s[0] == '"' && s[x-1] == '"') ? 1 : 0) : 0;
  8080. #endif /* COMMENT */
  8081.     s = brstrip(s);            /* Strip braces and doublequotes */
  8082.     if (cx == XXECH) {        /* ECHO */
  8083. #ifndef NOSPL
  8084.         if (!fndiags || fnsuccess) {
  8085. #endif /* NOSPL */
  8086. #ifdef COMMENT
  8087.         /* The "if (x)" business preserves previous behavior */
  8088.         /* by putting back the doublequotes if they were included. */
  8089.         if (x)
  8090.           printf("\"%s\"\n",s);
  8091.         else
  8092. #endif /* COMMENT */
  8093.           printf("%s\n",s);
  8094. #ifndef NOSPL
  8095.         }
  8096. #endif /* NOSPL */
  8097.     } else if (cx == XXXECH) {    /* XECHO */
  8098.         if (x)
  8099.           printf("\"%s\"",s);
  8100.         else
  8101.           printf("%s",s);
  8102. #ifdef UNIX
  8103.         fflush(stdout);
  8104. #endif /* UNIX */
  8105.     } else if (cx == XXAPC) {    /* APC */
  8106. #ifdef CK_APC
  8107.         if (apcactive == APC_LOCAL ||
  8108.         (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
  8109.           return(success = 0);
  8110. #endif /* CK_APC */
  8111.         if (!local) {
  8112.         printf("%c_%s%c\\",ESC,s,ESC);
  8113. #ifdef UNIX
  8114.         fflush(stdout);
  8115. #endif /* UNIX */
  8116.  
  8117.         } else {            /* Local mode - have connection */
  8118. #ifndef NOSPL
  8119.         if (ckmakxmsg(tmpbuf,    /* Form APC string in buffer */
  8120.                   TMPBUFSIZ,
  8121.                   ckctoa((char)ESC),
  8122.                   ckctoa('_'),
  8123.                   s,
  8124.                   ckctoa((char)ESC),
  8125.                   ckctoa('\\'),
  8126.                   NULL,NULL,NULL,NULL,NULL,NULL,NULL
  8127.                   ) > 0)
  8128.           return(success = dooutput(tmpbuf, XXOUT));
  8129.         printf("?Too long\n");
  8130.         return(-9);
  8131. #else
  8132.         printf("%c_%s%c\\",ESC,s,ESC);
  8133. #endif /* NOSPL */
  8134.         }
  8135.     }
  8136.     return(success = 1);
  8137.     }
  8138.  
  8139. #ifndef NOSPL
  8140. /* Copy macro args from/to two levels up, used internally by _floop et al. */
  8141.     if (cx == XXGTA || cx == XXPTA) {    /* _GETARGS, _PUTARGS */
  8142.     int x;
  8143.     debug(F101,"docmd XXGTA","",XXGTA);
  8144.     debug(F101,"docmd cx","",cx);
  8145.     debug(F101,"docmd XXGTA maclvl","",maclvl);
  8146.     x = dogta(cx);
  8147.     debug(F101,"docmd dogta returns","",x);
  8148.     debug(F101,"docmd dogta maclvl","",maclvl);
  8149.     return(x);
  8150.     }
  8151. #endif /* NOSPL */
  8152.  
  8153. #ifndef NOSPL
  8154. #ifdef CKCHANNELIO
  8155.     if (cx == XXFILE)
  8156.       return(dofile(cx));
  8157.     else if (cx == XXF_RE || cx == XXF_WR || cx == XXF_OP ||
  8158.          cx == XXF_CL || cx == XXF_SE || cx == XXF_RW ||
  8159.          cx == XXF_FL || cx == XXF_LI || cx == XXF_ST || cx == XXF_CO)
  8160.       return(dofile(cx));
  8161. #endif /* CKCHANNELIO */
  8162.  
  8163. /* ASK, ASKQ, READ */
  8164.     if (cx == XXASK  || cx == XXASKQ || cx == XXREA ||
  8165.     cx == XXRDBL || cx == XXGETC || cx == XXGETK) {
  8166.     return(doask(cx));
  8167.     }
  8168. #endif /* NOSPL */
  8169.  
  8170. #ifndef NOFRILLS
  8171.     if (cx == XXBUG) {            /* BUG */
  8172.     if ((x = cmcfm()) < 0) return(x);
  8173.     return(dobug());
  8174.     }
  8175. #endif /* NOFRILLS */
  8176.  
  8177. #ifndef NOXFER
  8178.     if (cx == XXBYE) {            /* BYE */
  8179.     extern int ftp_cmdlin;
  8180.     if ((x = cmcfm()) < 0) return(x);
  8181.  
  8182. #ifdef NEWFTP
  8183.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) {
  8184.         extern int stayflg, ftp_fai;
  8185.         success = ftpbye();
  8186.         if (ftp_cmdlin && !stayflg && !local)
  8187.           doexit(ftp_fai ? BAD_EXIT : GOOD_EXIT,-1);
  8188.         else
  8189.           return(success);
  8190.     }
  8191. #endif /* NEWFTP */
  8192.  
  8193.     if (!local) {
  8194.         printf("?No connection - use EXIT to quit.\n");
  8195.         return(-9);
  8196.     }
  8197.  
  8198. #ifdef CK_XYZ
  8199.     if (protocol != PROTO_K) {
  8200.         printf("?Sorry, BYE only works with Kermit protocol\n");
  8201.         return(-9);
  8202.     }
  8203. #endif /* CK_XYZ */
  8204.  
  8205. #ifdef IKS_OPTION
  8206.         if (
  8207. #ifdef CK_XYZ
  8208.             protocol == PROTO_K &&
  8209. #endif /* CK_XYZ */
  8210.             !iks_wait(KERMIT_REQ_START,1)) {
  8211.         printf(
  8212.          "?A Kermit Server is not available to process this command\n");
  8213.         return(-9);            /* Correct the return code */
  8214.         }
  8215. #endif /* IKS_OPTION */
  8216.  
  8217.     bye_active = 1;
  8218.     sstate = setgen('L',"","","");
  8219.     if (local) ttflui();        /* If local, flush tty input buffer */
  8220.     return(0);
  8221.     }
  8222. #endif /* NOXFER */
  8223.  
  8224.     if (cx == XXBEEP) {            /* BEEP */
  8225.         int x;
  8226. #ifdef OS2
  8227.     int y;
  8228.         if ((y = cmkey(beeptab, nbeeptab, "which kind of beep", "information",
  8229.                xxstring)) < 0 )
  8230.       return (y);
  8231.         if ((x = cmcfm()) < 0) return(x);
  8232.         bleep((short)y);        /* y is one of the BP_ values */
  8233. #else  /* OS2 */
  8234.         if ((x = cmcfm()) < 0) return(x);
  8235. #ifndef NOSPL
  8236.         bleep(BP_NOTE);
  8237. #else
  8238.     putchar('\07');
  8239. #endif /* NOSPL */
  8240. #endif /* OS2 */
  8241.         return(0);
  8242.     }
  8243.  
  8244. #ifndef NOFRILLS
  8245.     if (cx == XXCLE)            /* CLEAR */
  8246.       return(success = doclear());
  8247. #endif /* NOFRILLS */
  8248.  
  8249.     if (cx == XXCOM) {            /* COMMENT */
  8250.     if ((x = cmtxt("Text of comment line","",&s,NULL)) < 0)
  8251.       return(x);
  8252.     /* Don't change SUCCESS flag for this one */
  8253.     return(0);
  8254.     }
  8255.  
  8256. #ifndef NOLOCAL
  8257.     if (cx == XXCON || cx == XXCQ)    /* CONNECT or CONNECT /QUIETLY */
  8258.       return(doxconn(cx));
  8259. #endif /* NOLOCAL */
  8260.  
  8261. #ifndef NOFRILLS
  8262. #ifdef ZCOPY
  8263.     if (cx == XXCPY) {            /* COPY a file */
  8264. #ifdef IKSD
  8265.     if (inserver && !ENABLED(en_cpy)) {
  8266.         printf("?Sorry, COPY is disabled\n");
  8267.         return(-9);
  8268.     }
  8269. #endif /* IKSD */
  8270. #ifdef CK_APC
  8271.     if (apcactive == APC_LOCAL ||
  8272.         (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
  8273.         )
  8274.       return(success = 0);
  8275. #endif /* CK_APC */
  8276.     return(docopy());
  8277.     }
  8278. #endif /* ZCOPY */
  8279. #ifdef NT
  8280.     if ( cx == XXLINK ) {
  8281. #ifdef IKSD
  8282.         if (inserver && !ENABLED(en_cpy)) {
  8283.             printf("?Sorry, LINK (COPY) is disabled\n");
  8284.             return(-9);
  8285.         }
  8286. #endif /* IKSD */
  8287. #ifdef CK_APC
  8288.         if (apcactive == APC_LOCAL ||
  8289.             (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
  8290.             )
  8291.           return(success = 0);
  8292. #endif /* CK_APC */
  8293.         return(dolink());
  8294.     }
  8295. #endif /* NT */
  8296. #endif /* NOFRILLS */
  8297.  
  8298.     /* CD and friends */
  8299.     if (cx == XXCWD  || cx == XXCDUP || cx == XXBACK ||
  8300.     cx == XXLCWD || cx == XXLCDU || cx == XXKCD) {
  8301. #ifdef LOCUS
  8302.     if (!locus) {
  8303.         if (cx == XXCWD) {
  8304. #ifdef NOXFER
  8305.                 return(-2);
  8306. #else
  8307.                 return(dormt(XZCWD));
  8308. #endif /* NOXFER */
  8309.         } else if (cx == XXCDUP) {
  8310. #ifdef NOXFER
  8311.                 return(-2);
  8312. #else
  8313.                 return(dormt(XZCDU));
  8314. #endif /* NOXFER */
  8315.             }
  8316.     }
  8317. #endif /* LOCUS */
  8318. #ifdef IKSD
  8319.     if (inserver && !ENABLED(en_cwd)) {
  8320.         printf("?Sorry, changing directories is disabled\n");
  8321.         return(-9);
  8322.     }
  8323. #endif /* IKSD */
  8324.     return(success = docd(cx));
  8325.     }
  8326.  
  8327.     if (cx == XXCHK)            /* CHECK */
  8328.       return(success = dochk());
  8329.  
  8330.     if (cx == XXCLO) {            /* CLOSE */
  8331.     x = cmkey(clstab,ncls,"\"CONNECTION\", or log or file to close",
  8332.           "connection",xxstring);
  8333.     if (x == -3) {
  8334.         printf("?You must say which file or log\n");
  8335.         return(-9);
  8336.     }
  8337.     if (x < 0) return(x);
  8338.     if ((y = cmcfm()) < 0) return(y);
  8339. #ifndef NOLOCAL
  8340.     if (x == 9999) {        /* CLOSE CONNECTION */
  8341.         x = clsconnx(0);
  8342.         switch (x) {
  8343.           case 0:
  8344.         if (msgflg) printf("?Connection was not open\n");
  8345.           case -1:
  8346.         return(0);
  8347.           case 1:
  8348.         whyclosed = WC_CLOS;
  8349.         return(1);
  8350.         }
  8351.         return(0);
  8352.     }
  8353. #endif /* NOLOCAL */
  8354.     y = doclslog(x);
  8355.     success = (y == 1);
  8356.     return(success);
  8357.     }
  8358.  
  8359. #ifndef NOSPL
  8360.     if (cx == XXDCL || cx == XXUNDCL) {    /* DECLARE an array */
  8361.     return(dodcl(cx));
  8362.     }
  8363. #endif /* NOSPL */
  8364.  
  8365. #ifndef NODIAL
  8366.     if (cx == XXRED  || cx == XXDIAL || cx == XXPDIA ||
  8367.     cx == XXANSW || cx == XXLOOK) { /* DIAL, REDIAL etc */
  8368. #ifdef VMS
  8369.     extern int batch;
  8370. #else
  8371. #ifdef UNIXOROSK
  8372.     extern int backgrd;
  8373. #endif /* UNIXOROSK */
  8374. #endif /* VMS */
  8375.     x = dodial(cx);
  8376.     debug(F101,"dodial returns","",x);
  8377.     if ((cx == XXDIAL || cx == XXRED || cx == XXANSW) &&
  8378.         (x > 0) &&            /* If DIAL or REDIAL succeeded */
  8379.         (dialsta != DIA_PART) &&    /* and it wasn't partial */
  8380.         (dialcon > 0)) {
  8381.         if ((dialcon == 1 ||    /* And DIAL CONNECT is ON, */
  8382.         ((dialcon == 2) &&    /* or DIAL CONNECT is AUTO */
  8383.          !xcmdsrc        /* and we're at top level... */
  8384. #ifdef VMS
  8385.          && !batch        /* Not if running from batch */
  8386. #else
  8387. #ifdef UNIXOROSK
  8388.          && !backgrd        /* Not if running in background */
  8389. #endif /* UNIXOROSK */
  8390. #endif /* VMS */
  8391.          ))) /* Or AUTO */
  8392.           x = doconect(dialcq,    /* Then also CONNECT */
  8393.                            cmdlvl == 0 ? 1 : 0
  8394.                );
  8395.         if (ttchk() < 0)
  8396.           dologend();
  8397.     }
  8398.     return(success = x);
  8399.     }
  8400. #endif /* NODIAL */
  8401.  
  8402. #ifndef NOPUSH
  8403. #ifdef CK_REXX
  8404.     if (cx == XXREXX) {            /* REXX */
  8405.         extern int nopush;
  8406.         if ( nopush )
  8407.           return(success=0);
  8408.         return(dorexx());
  8409.     }
  8410. #endif /* CK_REXX */
  8411. #endif /* NOPUSH */
  8412.  
  8413. #ifndef NOFRILLS
  8414.     if (cx == XXDEL || cx == XXLDEL) {    /* DELETE */
  8415. #ifdef LOCUS
  8416.     if (!locus && cx != XXLDEL) {
  8417. #ifdef NOXFER
  8418.         return(-2);
  8419. #else
  8420.         return(dormt(XZDEL));
  8421. #endif /* NOXFER */
  8422.         }
  8423. #endif /* LOCUS */
  8424. #ifdef IKSD
  8425.     if (inserver && (!ENABLED(en_del)
  8426. #ifdef CK_LOGIN
  8427.              || isguest
  8428. #endif /* CK_LOGIN */
  8429.              )) {
  8430.         printf("?Sorry, DELETE is disabled\n");
  8431.         return(-9);
  8432.     }
  8433. #endif /* IKSD */
  8434. #ifdef CK_APC
  8435.     if ((apcactive == APC_LOCAL) ||
  8436.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  8437.       return(success = 0);
  8438. #endif /* CK_APC */
  8439.     return(dodel());
  8440.     }
  8441. #endif /* NOFRILLS */
  8442.  
  8443.     if (cx == XXDIR || cx == XXLS || cx == XXLDIR) { /* DIRECTORY or LS */
  8444. #ifdef LOCUS
  8445.     if (!locus && cx != XXLDIR) {
  8446. #ifdef NOXFER
  8447.         return(-2);
  8448. #else
  8449.         return(dormt(XZDIR));
  8450. #endif /* NOXFER */
  8451.         }
  8452. #endif /* LOCUS */
  8453. #ifdef IKSD
  8454.     if (inserver && !ENABLED(en_dir)) {
  8455.         printf("?Sorry, DIRECTORY is disabled\n");
  8456.         return(-9);
  8457.     }
  8458. #endif /* IKSD */
  8459.     return(dodir(cx));
  8460.     }
  8461.  
  8462. #ifndef NOSPL
  8463.     if (cx == XXELS)            /* ELSE */
  8464.       return(doelse());
  8465. #endif /* NOSPL */
  8466.  
  8467. #ifndef NOSERVER
  8468. #ifndef NOFRILLS
  8469.     if (cx == XXENA || cx == XXDIS) {    /* ENABLE, DISABLE */
  8470.     s = (cx == XXENA) ?
  8471.       "Server function to enable" :
  8472.         "Server function to disable";
  8473.  
  8474.     if ((x = cmkey(enatab,nena,s,"",xxstring)) < 0) {
  8475.         if (x == -3) {
  8476.         printf("?Name of server function required\n");
  8477.         return(-9);
  8478.         } else return(x);
  8479.     }
  8480.     if ((y = cmkey(kmstab,3,"mode","both",xxstring)) < 0) {
  8481.         if (y == -3) {
  8482.         printf("?Please specify remote, local, or both\n");
  8483.         return(-9);
  8484.         } else return(y);
  8485.     }
  8486.     if (cx == XXDIS)        /* Disabling, not enabling */
  8487.       y = 3 - y;
  8488.     if ((z = cmcfm()) < 0) return(z);
  8489. #ifdef CK_APC
  8490.     if ((apcactive == APC_LOCAL) ||
  8491.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  8492.       return(success = 0);
  8493. #endif /* CK_APC */
  8494. #ifdef IKSD
  8495.         /* This may seem like it duplicates the work in doenable()  */
  8496.         /* but this code returns failure whereas doenable() returns */
  8497.         /* success.                                                 */
  8498.         if (inserver &&
  8499. #ifdef IKSDCONF
  8500.             iksdcf &&
  8501. #endif /* IKSDCONF */
  8502.             (x == EN_HOS || x == EN_PRI || x == EN_MAI || x == EN_WHO ||
  8503.               isguest))
  8504.             return(success = 0);
  8505. #endif /* IKSD */
  8506.     return(doenable(y,x));
  8507.     }
  8508. #endif /* NOFRILLS */
  8509. #endif /* NOSERVER */
  8510.  
  8511. #ifndef NOSPL
  8512.     if (cx == XXRET) {            /* RETURN */
  8513.     if ((x = cmtxt("Optional return value","",&s,NULL)) < 0)
  8514.       return(x);
  8515.     s = brstrip(s);            /* Strip braces */
  8516.     if (cmdlvl == 0)        /* At top level, nothing happens... */
  8517.       return(success = 1);
  8518.     switch (cmdstk[cmdlvl].src) {    /* Action depends on command source */
  8519.       case CMD_TF:            /* Command file */
  8520.         popclvl();            /* Pop command level */
  8521.         return(success = 1);    /* always succeeds */
  8522.       case CMD_MD:            /* Macro */
  8523.       case CMD_KB:            /* Prompt */
  8524.         return(doreturn(s));    /* Trailing text is return value. */
  8525.       default:            /* Shouldn't happen */
  8526.         return(-2);
  8527.     }
  8528.     }
  8529. #endif /* NOSPL */
  8530.  
  8531. #ifndef NOSPL
  8532.     if (cx == XXOPE)            /* OPEN */
  8533.       return(doopen());
  8534. #endif /* NOSPL */
  8535.  
  8536. #ifndef NOSPL
  8537.     if (cx == XXOUT || cx == XXLNOUT) {    /* OUTPUT or LINEOUT */
  8538.     if ((x = cmtxt("Text to be output","",&s,NULL)) < 0)
  8539.       return(x);
  8540. #ifdef CK_APC
  8541.     if ((apcactive == APC_LOCAL) ||
  8542.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  8543.       return(success = 0);
  8544. #endif /* CK_APC */
  8545.     debug(F110,"OUTPUT 1",s,0);
  8546.     s = brstrip(s);            /* Strip enclosing braces, */
  8547.     debug(F110,"OUTPUT 2",s,0);
  8548. /*
  8549.   I don't think I could ever fully explain this in a million years...
  8550.   We have read the user's string without calling the variable-expander
  8551.   function.  Now, before we call it, we have to double backslashes that
  8552.   appear before \N, \B, \L, and \ itself, so the expander function will
  8553.   reduce them back to single backslashes, so when we call dooutput()...
  8554.   But it's more complicated than that.
  8555. */
  8556.     if (cmdgquo()) {        /* Only if COMMAND QUOTING ON ... */
  8557.         for (x = 0, y = 0; s[x]; x++, y++) {
  8558.         if (s[x] == CMDQ) {
  8559.             char c = s[x+1];
  8560.             if (c == 'n' || c == 'N' ||
  8561.             c == 'b' || c == 'B' ||
  8562.             c == 'l' || c == 'L' ||
  8563.             c == CMDQ)
  8564.               line[y++] = CMDQ;
  8565.         }
  8566.         line[y] = s[x];
  8567.         }
  8568.         line[y++] = '\0';        /* Now expand variables, etc. */
  8569.         debug(F110,"OUTPUT 3",line,0);
  8570.         s = line+y+1;
  8571.         x = LINBUFSIZ - (int) strlen(line) - 1;
  8572.         debug(F101,"OUTPUT size","",x);
  8573.         if (zzstring(line,&s,&x) < 0)
  8574.           return(success = 0);
  8575.         s = line+y+1;
  8576.         debug(F110,"OUTPUT 4",s,0);
  8577.     }
  8578.     success = dooutput(s,cx);
  8579.     return(success);
  8580.     }
  8581. #endif /* NOSPL */
  8582.  
  8583. #ifdef ANYX25
  8584. #ifndef IBMX25
  8585.     if (cx == XXPAD) {            /* PAD commands */
  8586.     x = cmkey(padtab,npadc,"PAD command","",xxstring);
  8587.     if (x == -3) {
  8588.         printf("?You must specify a PAD command to execute\n");
  8589.         return(-9);
  8590.     }
  8591.     if (x < 0) return(x);
  8592.  
  8593.     switch (x) {
  8594.       case XYPADL:
  8595.         if (x25stat() < 0)
  8596.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  8597.         else {
  8598.         x25clear();
  8599.         initpad();
  8600.         }
  8601.         break;
  8602.       case XYPADS:
  8603.         if (x25stat() < 0)
  8604.           printf("Not connected\r\n");
  8605.         else {
  8606.         extern int linkid, lcn;
  8607.         conol("Connected thru ");
  8608.         conol(ttname);
  8609.         printf(", Link id %d, Logical channel number %d\r\n",
  8610.                linkid,lcn);
  8611.         }
  8612.         break;
  8613.       case XYPADR:
  8614.         if (x25stat() < 0)
  8615.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  8616.         else
  8617.           x25reset(0,0);
  8618.         break;
  8619.       case XYPADI:
  8620.         if (x25stat() < 0)
  8621.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  8622.         else
  8623.           x25intr(0);
  8624.     }
  8625.     return(0);
  8626.     }
  8627. #endif /* IBMX25 */
  8628. #endif /* ANYX25 */
  8629.  
  8630. #ifndef NOSPL
  8631.     if (cx == XXPAU || cx == XXWAI || cx == XXMSL) /* PAUSE, WAIT, etc */
  8632.       return(dopaus(cx));
  8633. #endif /* NOSPL */
  8634.  
  8635. #ifndef NOFRILLS
  8636.     if (cx == XXPRI) {
  8637. #ifdef IKSD
  8638. #ifdef CK_LOGIN
  8639.     if (inserver && (isguest || !ENABLED(en_pri))) {
  8640.         printf("?Sorry, printing is disabled\n");
  8641.         return(-9);
  8642.     }
  8643. #endif /* CK_LOGIN */
  8644. #endif /* IKSD */
  8645.     if ((x = cmifi("File to print","",&s,&y,xxstring)) < 0) {
  8646.         if (x == -3) {
  8647.         printf("?A file specification is required\n");
  8648.         return(-9);
  8649.         } else return(x);
  8650.     }
  8651.     if (y != 0) {
  8652.         printf("?Wildcards not allowed\n");
  8653.         return(-9);
  8654.     }
  8655.     ckstrncpy(line,s,LINBUFSIZ);
  8656.     s = "";
  8657. #ifndef NT
  8658.     if ((x = cmtxt("Local print command options, or carriage return","",&s,
  8659.                xxstring)) < 0)
  8660.       return(x);
  8661. #endif /* NT */
  8662.     if ((x = cmcfm()) < 0)
  8663.       return(x);
  8664.     return(success = (zprint(s,line) == 0) ? 1 : 0);
  8665.     }
  8666. #endif /* NOFRILLS */
  8667.  
  8668. #ifdef TCPSOCKET
  8669. #ifndef NOPUSH
  8670.     if (cx == XXPNG)             /* PING an IP host */
  8671.       return(doping());
  8672. #endif /* NOPUSH */
  8673.  
  8674. #ifndef NOFTP
  8675.     if (cx == XXFTP)            /* FTP */
  8676. #ifdef SYSFTP
  8677. #ifndef NOPUSH
  8678.       return(doftp());            /* Just runs system's ftp program */
  8679. #else
  8680.       return(-2);
  8681. #endif /* NOPUSH */
  8682. #else
  8683.     return(doxftp());
  8684. #endif /* SYSFTP */
  8685. #endif /* NOFTP */
  8686. #endif /* TCPSOCKET */
  8687.  
  8688.     if (cx == XXPWD || cx == XXLPWD) {    /* PWD */
  8689. #ifdef OS2
  8690.     char *pwp;
  8691. #endif /* OS2 */
  8692.     if ((x = cmcfm()) < 0)
  8693.       return(x);
  8694. #ifdef LOCUS
  8695.     if (!locus && cx != XXLPWD) {
  8696. #ifdef NOXFER
  8697.         return(-2);
  8698. #else
  8699.         return(dormt(XZPWD));
  8700. #endif /* NOXFER */
  8701.         }
  8702. #endif /* LOCUS */
  8703.  
  8704. #ifndef MAC
  8705. #ifndef OS2
  8706. #ifdef UNIX
  8707.     printf("%s\n",zgtdir());
  8708. #else
  8709.     xsystem(PWDCMD);
  8710. #endif /* UNIX */
  8711.     return(success = 1);        /* Blind faith */
  8712. #else  /* OS2 */
  8713.     if (pwp = zgtdir()) {
  8714.         if (*pwp) {
  8715. #ifdef NT
  8716.         line[0] = NUL;
  8717.         ckGetLongPathName(pwp,line,LINBUFSIZ);
  8718.         line[LINBUFSIZ-1] = NUL;
  8719.         tmpbuf[0] = NUL;
  8720.         GetShortPathName(pwp,tmpbuf,TMPBUFSIZ);
  8721.         tmpbuf[TMPBUFSIZ-1] = NUL;
  8722.         pwp = line;
  8723.         if (!strcmp(line,tmpbuf)) {
  8724. #endif /* NT */
  8725.             printf("%s\n",pwp);
  8726. #ifdef NT
  8727.         } else {
  8728.             printf("  Long name:  %s\n",line);
  8729.             printf("  Short name: %s\n",tmpbuf);
  8730.         }            
  8731. #endif /* NT */
  8732.         }
  8733.         return(success = ((int)strlen(pwp) > 0));
  8734.     } else return(success = 0);
  8735. #endif /* OS2 */
  8736. #else  /* MAC */
  8737.     if (pwp = zgtdir()) {
  8738.         printf("%s\n",pwp);
  8739.         return(success = ((int)strlen(pwp) > 0));
  8740.     } else return(success = 0);
  8741. #endif /* MAC */
  8742.     }
  8743.  
  8744.     if (cx == XXQUI || cx == XXEXI) {    /* EXIT, QUIT */
  8745.     extern int quitting;
  8746.  
  8747.     if ((y = cmnum("exit status code",ckitoa(xitsta),10,&x,xxstring)) < 0)
  8748.       return(y);
  8749.     if ((y = cmtxt("Optional EXIT message","",&s,xxstring)) < 0)
  8750.       return(y);
  8751.     s = brstrip(s);
  8752.     ckstrncpy(line,s,LINBUFSIZ);
  8753.  
  8754.     if (!hupok(0))            /* Check if connection still open */
  8755.       return(success = 0);
  8756.  
  8757.     if (line[0])            /* Print EXIT message if given */
  8758.       printf("%s\n",(char *)line);
  8759.  
  8760.     quitting = 1;            /* Flag that we are quitting. */
  8761.  
  8762. #ifdef VMS
  8763.     doexit(GOOD_EXIT,x);
  8764. #else
  8765. #ifdef OSK
  8766. /* Returning any codes here makes the OS-9 shell print an error message. */
  8767.     doexit(GOOD_EXIT,-1);
  8768. #else
  8769. #ifdef datageneral
  8770.         doexit(GOOD_EXIT,x);
  8771. #else
  8772.     doexit(x,-1);
  8773. #endif /* datageneral */
  8774. #endif /* OSK */
  8775. #endif /* VMS */
  8776.     }
  8777.  
  8778. #ifndef NOXFER
  8779. #ifndef NOFRILLS
  8780.     if (cx == XXERR) {            /* ERROR */
  8781. #ifdef CK_XYZ
  8782.     if (protocol != PROTO_K) {
  8783.         printf("Sorry, E-PACKET only works with Kermit protocol\n");
  8784.         return(-9);
  8785.     }
  8786. #endif /* CK_XYZ */
  8787.     if ((x = cmcfm()) < 0) return(x);
  8788.     ttflui();
  8789.     epktflg = 1;
  8790.     sstate = 'a';
  8791.     return(0);
  8792.     }
  8793. #endif /* NOFRILLS */
  8794.  
  8795.     if (cx == XXFIN) {            /* FINISH */
  8796. #ifdef NEWFTP
  8797.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  8798.       return(ftpbye());
  8799. #endif /* NEWFTP */
  8800. #ifdef CK_XYZ
  8801.     if (protocol != PROTO_K) {
  8802.         printf("Sorry, FINISH only works with Kermit protocol\n");
  8803.         return(-9);
  8804.     }
  8805. #endif /* CK_XYZ */
  8806.     if ((x = cmcfm()) < 0) return(x);
  8807.  
  8808. #ifdef IKS_OPTION
  8809.         if (
  8810. #ifdef CK_XYZ
  8811.             protocol == PROTO_K &&
  8812. #endif /* CK_XYZ */
  8813.             !iks_wait(KERMIT_REQ_START,1)) {
  8814.         printf(
  8815.               "?A Kermit Server is not available to process this command\n");
  8816.         return(-9);            /* Correct the return code */
  8817.         }
  8818. #endif /* IKS_OPTION */
  8819.  
  8820.     sstate = setgen('F',"","","");
  8821.     if (local) ttflui();        /* If local, flush tty input buffer */
  8822.     return(0);
  8823.     }
  8824. #endif /* NOXFER */
  8825.  
  8826. #ifndef NOSPL
  8827.     if (cx == XXFOR)            /* FOR loop */
  8828.       return(dofor());
  8829. #endif /* NOSPL */
  8830.  
  8831. #ifndef NOXFER
  8832.     /* GET MGET REGET RETRIEVE etc */
  8833.     if (cx == XXGET || cx == XXMGET || cx == XXREGET || cx == XXRETR) {
  8834. #ifdef IKSD
  8835.     if (inserver && !ENABLED(en_sen)) {
  8836.         printf("?Sorry, reception of files is disabled\n");
  8837.         return(-9);
  8838.     }
  8839. #endif /* IKSD */
  8840.     return(doxget(cx));
  8841.     }
  8842. #endif /* NOXFER */
  8843.  
  8844. #ifndef NOSPL
  8845. #ifndef NOFRILLS
  8846.     if (cx == XXGOK) {            /* GETOK */
  8847.     return(success = doask(cx));
  8848.     }
  8849. #endif /* NOFRILLS */
  8850. #endif /* NOSPL */
  8851.  
  8852.     if (cx == XXHLP) {            /* HELP */
  8853. #ifdef NOHELP
  8854.     return(dohlp(XXHLP));
  8855. #else
  8856.     x = cmkey2(cmdtab,ncmd,"\nCommand or topic","help",toktab,xxstring,3);
  8857.     debug(F101,"HELP command x","",x);
  8858.     if (x == -5) {
  8859.         y = chktok(toktab);
  8860.         debug(F101,"HELP cmkey token","",y);
  8861.         /* ungword(); */
  8862.         switch (y) {
  8863. #ifndef NOPUSH
  8864.           case '!': x = XXSHE; break;
  8865. #endif /* NOPUSH */
  8866.           case '#': x = XXCOM; break;
  8867.           case ';': x = XXCOM; break;
  8868. #ifndef NOSPL
  8869.               case '.': x = XXDEF; break;
  8870.           case ':': x = XXLBL; break;
  8871. #ifndef NOSEXP
  8872.           case '(': x = XXSEXP; break;
  8873. #endif /* NOSEXP */
  8874. #endif /* NOSPL */
  8875.           case '&': x = XXECH; break;
  8876.           default:
  8877.         printf("\n?Invalid - %s\n",cmdbuf);
  8878.         x = -2;
  8879.         }
  8880.     }
  8881.     makestr(&hlptok,atmbuf);
  8882.     debug(F111,"HELP token",hlptok,x);
  8883.     return(dohlp(x));
  8884. #endif /* NOHELP */
  8885.     }
  8886.  
  8887. #ifndef NOHELP
  8888.     if (cx == XXINT)            /* INTRO */
  8889.       return(hmsga(introtxt));
  8890.     if (cx == XXNEW) {            /* NEWS */
  8891.     int x;
  8892.     extern char * k_info_dir;
  8893.     x = hmsga(newstxt);
  8894.     return(x);
  8895.     }
  8896.  
  8897. #ifdef OS2ONLY
  8898.     if (cx == XXUPD) {            /* View UPDATE file */
  8899.         extern char exedir[];
  8900.         char * pTopic;
  8901.         char updstr[2048];
  8902.         if ((x = cmtxt("topic name","",&pTopic,xxstring)) < 0)
  8903.             return x;
  8904. #ifdef COMMENT
  8905.     sprintf(updstr,
  8906.         "start view %s\\docs\\k2.inf+%s\\docs\\using_ck.inf+\
  8907. %s\\docs\\dialing.inf+%s\\docs\\modems.inf %s",
  8908.         exedir,exedir,exedir,exedir,pTopic
  8909.         );
  8910. #else
  8911.     if (ckmakxmsg(updstr,
  8912.              2048,
  8913.              "start view ",
  8914.              exedir,
  8915.              "\\docs\\k2.inf+",
  8916.              exedir,
  8917.              "\\docs\\using_ck.inf+",
  8918.              exedir,
  8919.              "\\docs\\dialing.inf+",
  8920.              exedir,
  8921.              "\\docs\\modems.inf ",
  8922.              pTopic,
  8923.              NULL,
  8924.              NULL
  8925.              ) > 0)
  8926. #endif /* COMMENT */
  8927.       system(updstr);
  8928.         return(success = 1);
  8929.     }
  8930. #endif /* OS2ONLY */
  8931. #endif /* NOHELP */
  8932.  
  8933. #ifndef NOLOCAL
  8934.     if (cx == XXHAN) {            /* HANGUP */
  8935.     if ((x = cmcfm()) < 0) return(x);
  8936. #ifdef NEWFTP
  8937.     if ((ftpget == 1) || ((ftpget == 2) && !local && ftpisopen()))
  8938.       return(success = ftpbye());
  8939. #endif /* NEWFTP */
  8940. #ifndef NODIAL
  8941.     if ((x = mdmhup()) < 1) {
  8942.         debug(F101,"HANGUP mdmup","",x);
  8943. #endif /* NODIAL */
  8944.         x = tthang();
  8945.         debug(F101,"HANGUP tthang","",x);
  8946.         x = (x > -1);
  8947. #ifndef NODIAL
  8948.     }
  8949.     dialsta = DIA_UNK;
  8950. #endif /* NODIAL */
  8951.     whyclosed = WC_CLOS;
  8952.     ttchk();            /* In case of CLOSE-ON-DISCONNECT */
  8953.     dologend();
  8954. #ifdef OS2
  8955.     if (x)
  8956.       DialerSend(OPT_KERMIT_HANGUP, 0);
  8957. #endif /* OS2 */
  8958.     if (x) haveline = 0;
  8959.     return(success = x);
  8960.     }
  8961. #endif /* NOLOCAL */
  8962.  
  8963. #ifndef NOSPL
  8964.     /* INPUT, REINPUT, and MINPUT */
  8965.  
  8966.     if (cx == XXINP || cx == XXREI || cx == XXMINP) {
  8967.     long zz;
  8968.     extern int x_ifnum, ispattern, isjoin;
  8969.     zz = -1L;
  8970.     x_ifnum = 1;            /* Turn off internal complaints */
  8971.     y = cmnum("Seconds to wait for input,\n or time of day hh:mm:ss",
  8972.           ckitoa(indef), 10, &x, xxstring
  8973.           );
  8974.     x_ifnum = 0;
  8975.     if (y < 0) {
  8976.         if (y == -2) {        /* Invalid number or expression */
  8977.         zz = tod2sec(atmbuf);    /* Convert to secs since midnight */
  8978.         if (zz < 0L) {
  8979.             printf("?Number, expression, or time of day required\n");
  8980.             return(-9);
  8981.         } else {
  8982.             char now[32];    /* Current time */
  8983.             char *p;
  8984.             long tnow;
  8985.             p = now;
  8986.             ztime(&p);
  8987.             tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
  8988.             if (zz < tnow)    /* User's time before now */
  8989.               zz += 86400L;    /* So make it tomorrow */
  8990.             zz -= tnow;        /* Seconds from now. */
  8991.         }
  8992.         } else
  8993.           return(y);
  8994.     }
  8995.     if (zz > -1L) {
  8996.         x = zz;
  8997.         if (zz != (long) x) {
  8998.         printf(
  8999. "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
  9000.                );
  9001.         return(-9);
  9002.         }
  9003.     }
  9004.  
  9005. #ifdef CK_MINPUT
  9006.     for (y = 0; y < MINPMAX; y++) {    /* Initialize strings */
  9007.         mp[y] = 0;            /* Assume it's not a pattern */
  9008.         if (ms[y]) {
  9009.         free(ms[y]);        /* Free old strings, if any */
  9010.         ms[y] = NULL;
  9011.         }
  9012.     }
  9013.     if (cx == XXMINP) {        /* MINPUT */
  9014.         int i, k = 0, n = 0;
  9015.         struct stringarray * q;
  9016.         keepallchars = 1;
  9017.         while (k < MINPMAX) {
  9018.         if ((y = cmfld("String or pattern","",&s,xxstring)) < 0) {
  9019.             if (y == -3) {
  9020.             if ((y = cmcfm()) < 0)
  9021.               return(y);
  9022.             break;
  9023.             } else {
  9024.             return(y);
  9025.             }
  9026.         }
  9027.         debug(F111,"MINPUT field",s,k);
  9028.         if (isjoin) {
  9029.             if ((q = cksplit(1,0,s," ",(char *)c1chars,3,0,0))) {
  9030.             char ** ap = q->a_head;
  9031.             n = q->a_size;
  9032.             debug(F101,"minput cksplit size","",n);
  9033.             for (i = 1; i <= n && k < MINPMAX; i++) {
  9034.                 if (!ap[i]) /* Add non-empty elements */
  9035.                   continue;
  9036.                 if (!*(ap[i]))
  9037.                   continue;
  9038.                 makestr(&(ms[k]),ap[i]);
  9039.                 debug(F111,"MINPUT JOIN",ms[k],k);
  9040.                 k++;
  9041.             }
  9042.             }
  9043.         } else {
  9044.             if (s) if (*s) {
  9045.             makestr(&(ms[k]),brstrip(s));
  9046.             if (ispattern) mp[k] = 1;
  9047.             debug(F111,"MINPUT",ms[k],ispattern);
  9048.             k++;
  9049.             }
  9050.         }
  9051.         }
  9052.         keepallchars = 0;
  9053.     } else {
  9054. #endif /* CK_MINPUT */
  9055.  
  9056.         /* INPUT or REINPUT */
  9057.  
  9058.         if ((y = cmtxt("Material to be input","",&s,xxstring)) < 0)
  9059.           return(y);
  9060.         mp[0] = ispattern ? 1 : 0;
  9061.         makestr(&(ms[0]),brstrip(s));
  9062.         ms[1] = NULL;
  9063.  
  9064. #ifdef CK_MINPUT
  9065.     }
  9066. #endif /* CK_MINPUT */
  9067.  
  9068.     if (cx == XXINP || cx == XXMINP) { /* Not REINPUT... */
  9069.         i_active = 1;
  9070.         success = doinput(x,ms,mp);    /* Go try to input the search string */
  9071.         i_active = 0;
  9072.     } else {            /* REINPUT */
  9073.         success = doreinp(x,ms[0],ispattern);
  9074.     }
  9075.     if (intime[cmdlvl] && !success) { /* TIMEOUT-ACTION = QUIT? */
  9076.         popclvl();            /* If so, pop command level. */
  9077.         if (pflag && cmdlvl == 0) {
  9078.         if (cx == XXINP)  printf("?INPUT timed out\n");
  9079.         if (cx == XXMINP) printf("?MINPUT timed out\n");
  9080.         if (cx == XXREI)  printf("?REINPUT failed\n");
  9081.         }
  9082.     }
  9083.     return(success);        /* Return do(re)input's return code */
  9084.     }
  9085.  
  9086. #endif /* NOSPL */
  9087.  
  9088.     if (cx == XXLOG) {            /* LOG */
  9089.     x = cmkey(logtab,nlog,"What to log","",xxstring);
  9090.     if (x == -3) {
  9091.         printf("?Type of log required\n");
  9092.         return(-9);
  9093.     }
  9094.     if (x < 0) return(x);
  9095.     x = dolog(x);
  9096.     if (x < 0)
  9097.       return(x);
  9098.     else
  9099.       return(success = x);
  9100.     }
  9101.  
  9102.     if (cx == XXLOGIN) {        /* (REMOTE) LOGIN */
  9103. #ifdef NEWFTP
  9104.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  9105.       return(success = doftpusr());
  9106. #endif /* NEWFTP */
  9107. #ifdef IKSD
  9108.     if (inserver) {
  9109.         printf("?Already logged in\n");
  9110.         return(-9);
  9111.     } else
  9112. #endif /* IKSD */
  9113.     {
  9114. #ifdef NOXFER
  9115.         return(-2);
  9116. #else
  9117.         return(dormt(XZLGI));
  9118. #endif /* NOXFER */
  9119.     }
  9120.     }
  9121.     if (cx == XXLOGOUT) {        /* (REMOTE) LOGOUT */
  9122. #ifdef NEWFTP
  9123.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  9124.       return(success = doftpres());
  9125. #endif /* NEWFTP */
  9126.  
  9127. #ifdef IKSD
  9128.         if (inserver) {
  9129.         if ((x = cmcfm()) < 0)
  9130.           return(x);
  9131.         doexit(GOOD_EXIT,xitsta);
  9132.     } else
  9133. #endif /* IKSD */
  9134.     if (!local || (network && ttchk() < 0)) {
  9135.         printf("?No connection.\n");
  9136.         return(-9);
  9137.     } else {
  9138. #ifdef NOXFER
  9139.         return(-2);
  9140. #else
  9141.         return(dormt(XZLGO));
  9142. #endif /* NOXFER */
  9143.     }
  9144.     }
  9145.  
  9146. #ifndef NOSCRIPT
  9147.     if (cx == XXLOGI) {            /* UUCP-style script */
  9148.     if ((x = cmtxt("expect-send expect-send ...","",&s,xxstring)) < 0)
  9149.       return(x);
  9150. #ifdef CK_APC
  9151.     if ((apcactive == APC_LOCAL) ||
  9152.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  9153.       return(success = 0);
  9154. #endif /* CK_APC */
  9155. #ifdef VMS
  9156.     conres();            /* For Ctrl-C to work... */
  9157. #endif /* VMS */
  9158.     return(success = dologin(s));    /* Return 1=completed, 0=failed */
  9159.     }
  9160. #endif /* NOSCRIPT */
  9161.  
  9162. #ifndef NOXFER
  9163. #ifdef PIPESEND
  9164.     if (cx == XXCREC) {            /* CRECEIVE */
  9165.     if (protocol != PROTO_K) {
  9166.         printf("?Sorry, CRECEIVE works only with Kermit protocol\n");
  9167.         return(-9);
  9168.     } else
  9169.       return(doxget(cx));
  9170.     }
  9171.     if (cx == XXCGET) {            /* CGET */
  9172.     return(doxget(cx));
  9173.     }
  9174. #endif /* PIPESEND */
  9175.  
  9176.     if (cx == XXREC)            /* RECEIVE */
  9177.       return(doxget(cx));
  9178. #endif /* NOXFER */
  9179.  
  9180. #ifndef NOXFER
  9181.     if (cx == XXREM) {            /* REMOTE */
  9182. #ifdef NEWFTP
  9183.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  9184.       return(doftprmt(0,0));
  9185. #endif /* NEWFTP */
  9186. #ifdef CK_XYZ
  9187.     if (protocol != PROTO_K) {
  9188.         printf("Sorry, REMOTE commands only work with Kermit protocol\n");
  9189.         return(-9);
  9190.     }
  9191. #endif /* CK_XYZ */
  9192.     x = cmkey(remcmd,nrmt,"Remote Kermit server command","",xxstring);
  9193.     if (x == -3) {
  9194.         printf("?You must specify a command for the remote server\n");
  9195.         return(-9);
  9196.     }
  9197.     return(dormt(x));
  9198.     }
  9199. #endif /* NOXFER */
  9200.  
  9201. #ifndef NORENAME
  9202. #ifndef NOFRILLS
  9203.     if (cx == XXREN || cx == XXLREN) {    /* RENAME */
  9204. #ifdef LOCUS
  9205.     if (!locus && cx != XXLREN) {
  9206. #ifdef NOXFER
  9207.         return(-2);
  9208. #else
  9209.         return(dormt(XZREN));
  9210. #endif /* NOXFER */
  9211.         }
  9212. #endif /* LOCUS */
  9213. #ifdef IKSD
  9214.     if (inserver && (!ENABLED(en_ren)
  9215. #ifdef CK_LOGIN
  9216.              || isguest
  9217. #endif /* CK_LOGIN */
  9218.              )) {
  9219.         printf("?Sorry, renaming of files is disabled\n");
  9220.         return(-9);
  9221.     }
  9222. #endif /* IKSD */
  9223. #ifdef CK_APC
  9224.     if ((apcactive == APC_LOCAL) ||
  9225.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  9226.       return(success = 0);
  9227. #endif /* CK_APC */
  9228.     return(dorenam());
  9229.     }
  9230. #endif /* NOFRILLS */
  9231. #endif /* NORENAME */
  9232.  
  9233.     if (cx == XXEIGHT) {        /* EIGHTBIT */
  9234.     extern int parity, cmask, cmdmsk;
  9235.     if ((x = cmcfm()) < 0)
  9236.       return(x);
  9237.     parity = 0;
  9238.     cmask = 0xff;
  9239.     cmdmsk = 0xff;
  9240.     return(success = 1);
  9241.     }
  9242.  
  9243. #ifndef NOXFER
  9244. /* SEND, CSEND, MOVE, MAIL, and RESEND use the new common code */
  9245.  
  9246.     if (cx == XXSEN            /* SEND */
  9247. #ifdef PIPESEND
  9248.     || cx == XXCSEN            /* CSEND */
  9249. #endif /* PIPESEND */
  9250.     || cx == XXMOVE            /* MOVE */
  9251.     || cx == XXMAI            /* MAIL */
  9252. #ifdef CK_RESEND
  9253.     || cx == XXRSEN            /* RESEND */
  9254. #endif /* CK_RESEND */
  9255.     ) {
  9256. #ifdef IKSD
  9257.     if (inserver && !ENABLED(en_get)) {
  9258.         printf("?Sorry, sending files is disabled\n");
  9259.         return(-9);
  9260.     }
  9261. #endif /* IKSD */
  9262.     return(doxsend(cx));
  9263.     }
  9264.  
  9265. /* PSEND, ADD, and REMOVE use special parsing */
  9266.  
  9267. #ifdef ADDCMD
  9268.     /* ADD and REMOVE */
  9269.     if (cx == XXADD || cx == XXREMV) {
  9270.     char * m;
  9271.     m = (cx == XXADD) ? "Add to which list?" : "Remove from which list?";
  9272.     x = cmkey(addtab,naddtab,m,"",xxstring);
  9273.     if (x < 0)
  9274.       return(x);
  9275. #ifndef NOMSEND
  9276.     if (x == ADD_SND)
  9277.       return(addsend(cx));
  9278.     else
  9279. #endif /* NOMSEND */
  9280.       return(doadd(cx,x));
  9281.     }
  9282. #endif /* ADDCMD */
  9283.  
  9284. #ifdef CK_RESEND
  9285.     if (cx == XXPSEN) {            /* PSEND */
  9286.     int seekto = 0;
  9287.  
  9288.     cmarg = cmarg2 = "";
  9289.     x = cmifi("File to partially send", "", &s, &y, xxstring);
  9290.     if (x < 0) {
  9291.         if (x == -3) {
  9292.         printf("?A file specification is required\n");
  9293.         return(-9);
  9294.         } else return(x);
  9295.     }
  9296.     nfils = -1;            /* Files come from internal list. */
  9297. #ifndef NOMSEND
  9298.         addlist = 0;            /* Don't use SEND-LIST. */
  9299.         filenext = NULL;
  9300. #endif /* NOMSEND */
  9301.     ckstrncpy(line,s,LINBUFSIZ);    /* Save copy of string just parsed. */
  9302.     debug(F110,"PSEND line",line,0);
  9303.     if (y != 0) {
  9304.         printf("?Sorry, wildcards not permitted in this command\n");
  9305.         return(-9);
  9306.     }
  9307.     if (sizeof(int) < 4) {
  9308.         printf("?Sorry, this command needs 32-bit integers\n");
  9309.         return(-9);
  9310.     }
  9311.     x = cmnum("starting position (byte number)",
  9312.           "",10,&seekto,xxstring);
  9313.     if (x < 0)
  9314.       return(x);
  9315.     zfnqfp(s,fspeclen,fspec);    /* Get full path */
  9316.     if ((x = cmtxt("Name to send it with","",&s,NULL)) < 0)
  9317.       return(x);
  9318.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  9319.  
  9320. #ifdef IKSD
  9321.     if (inserver && !ENABLED(en_get)) {
  9322.         printf("?Sorry, sending files is disabled\n");
  9323.         return(-9);
  9324.     }
  9325. #endif /* IKSD */
  9326. #ifdef PIPESEND
  9327.     if (sndfilter) {
  9328.         printf("?Sorry, no PSEND while SEND FILTER selected\n");
  9329.         return(-9);
  9330.     }
  9331. #endif /* PIPESEND */
  9332. #ifdef CK_XYZ
  9333.     if ((protocol == PROTO_X || protocol == PROTO_XC)) {
  9334.         printf("Sorry, PSEND works only with Kermit protocol\n");
  9335.         return(-9);
  9336.     }
  9337. #endif /* CK_XYZ */
  9338.  
  9339.     cmarg2 = brstrip(tmpbuf);    /* Strip braces */
  9340.     cmarg = line;            /* File to send */
  9341.     debug(F110,"PSEND filename",cmarg,0);
  9342.     debug(F110,"PSEND as-name",cmarg2,0);
  9343.     sendstart = seekto;
  9344.     sstate = 's';            /* Set start state to SEND */
  9345. #ifndef NOMSEND
  9346.     addlist = 0;
  9347.     filenext = NULL;
  9348. #endif /* NOMSEND */
  9349.     sendmode = SM_PSEND;
  9350. #ifdef MAC
  9351.     what = W_SEND;
  9352.     scrcreate();
  9353. #endif /* MAC */
  9354.     if (local) {            /* If in local mode, */
  9355.         displa = 1;            /* enable file transfer display */
  9356.     }
  9357.     return(0);
  9358.     }
  9359. #endif /* CK_RESEND */
  9360. #endif /* NOXFER */
  9361.  
  9362. #ifndef NOXFER
  9363. #ifndef NOMSEND
  9364.     if (cx == XXMSE || cx == XXMMOVE) {
  9365. #ifdef NEWFTP
  9366.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  9367.       return(doftpput(cx,0));
  9368. #endif /* NEWFTP */
  9369. #ifdef CK_XYZ
  9370.     if (protocol == PROTO_X || protocol == PROTO_XC) {
  9371.         printf(
  9372. "Sorry, you can only send one file at a time with XMODEM protocol\n"
  9373.            );
  9374.         return(-9);
  9375.     }
  9376. #endif /* CK_XYZ */
  9377.         return(doxsend(cx));
  9378.     }
  9379.  
  9380. #ifdef COMMENT                /* (moved to doxsend) */
  9381.     if (cx == XXMSE || cx == XXMMOVE) {    /* MSEND and MMOVE commands */
  9382.     nfils = 0;            /* Like getting a list of */
  9383.     lp = line;            /* files on the command line */
  9384.     addlist = 0;            /* Do not use SEND-LIST */
  9385.     filenext = NULL;        /* Ditto ! */
  9386.  
  9387.     while (1) {
  9388.         char *p;
  9389.         if ((x = cmifi("Names of files to send, separated by spaces","",
  9390.                &s,&y,xxstring)) < 0) {
  9391.         if (x == -3) {
  9392.             if (nfils <= 0) {
  9393.             printf("?A file specification is required\n");
  9394.             return(-9);
  9395.             } else break;
  9396.         }
  9397.         return(x);
  9398.         }
  9399.         msfiles[nfils++] = lp;    /* Got one, count it, point to it, */
  9400.         p = lp;            /* remember pointer, */
  9401.         while (*lp++ = *s++)    /* and copy it into buffer */
  9402.           if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
  9403.           printf("?MSEND list too long\n");
  9404.           line[0] = NUL;
  9405.           return(-9);
  9406.           }
  9407.         debug(F111,"msfiles",msfiles[nfils-1],nfils-1);
  9408.         if (nfils == 1) *fspec = NUL; /* Take care of \v(filespec) */
  9409. #ifdef ZFNQFP
  9410.         zfnqfp(p,TMPBUFSIZ,tmpbuf);
  9411.         p = tmpbuf;
  9412. #endif /* ZFNQFP */
  9413.         if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) {
  9414.         strcat(fspec,p);    /* safe */
  9415.         strcat(fspec," ");    /* safe */
  9416.         } else printf("WARNING - \\v(filespec) buffer overflow\n");
  9417.     }
  9418.     cmlist = msfiles;        /* Point cmlist to pointer array */
  9419.     cmarg2 = "";            /* No internal expansion list (yet) */
  9420.     sndsrc = nfils;            /* Filenames come from cmlist */
  9421.     sendmode = SM_MSEND;        /* Remember this kind of SENDing */
  9422.     sstate = 's';            /* Set start state for SEND */
  9423.     if (cx == XXMMOVE)        /* If MMOVE'ing, */
  9424.       moving = 1;            /*  set this flag. */
  9425. #ifdef MAC
  9426.     what = W_SEND;
  9427.     scrcreate();
  9428. #endif /* MAC */
  9429.     if (local) {            /* If in local mode, */
  9430.         displa = 1;            /* turn on file transfer display */
  9431.         ttflui();            /* and flush tty input buffer. */
  9432.     }
  9433.     return(0);
  9434.     }
  9435. #endif /* COMMENT */
  9436. #endif /* NOMSEND */
  9437. #endif /* NOXFER */
  9438.  
  9439. #ifndef NOSERVER
  9440.     if (cx == XXSER) {            /* SERVER */
  9441. #ifdef CK_XYZ
  9442.     if (protocol != PROTO_K) {
  9443.         printf("Sorry, SERVER only works with Kermit protocol\n");
  9444.         return(-9);
  9445.     }
  9446. #endif /* CK_XYZ */
  9447. #ifdef COMMENT
  9448. /*
  9449.   Parse for time limit, but since we don't use it yet,
  9450.   the parsing is commented out.
  9451. */
  9452.     x_ifnum = 1;            /* Turn off internal complaints */
  9453.     y = cmnum("optional time limit, seconds, or time of day as hh:mm:ss",
  9454.           "0", 10, &x, xxstring
  9455.           );
  9456.     x_ifnum = 0;
  9457.     if (y < 0) {
  9458.         if (y == -2) {        /* Invalid number or expression */
  9459.         zz = tod2sec(atmbuf);    /* Convert to secs since midnight */
  9460.         if (zz < 0L) {
  9461.             printf("?Number, expression, or time of day required\n");
  9462.             return(-9);
  9463.         } else {
  9464.             char now[32];    /* Current time */
  9465.             char *p;
  9466.             long tnow;
  9467.             p = now;
  9468.             ztime(&p);
  9469.             tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
  9470.             if (zz < tnow)    /* User's time before now */
  9471.               zz += 86400L;    /* So make it tomorrow */
  9472.             zz -= tnow;        /* Seconds from now. */
  9473.         }
  9474.         } else
  9475.           return(y);
  9476.     }
  9477.     if (zz > -1L) {
  9478.         x = zz;
  9479.         if (zz != (long) x) {
  9480.         printf(
  9481. "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
  9482.                );
  9483.         return(-9);
  9484.         }
  9485.     }
  9486.     if (x < 0)
  9487.       x = 0;
  9488. #endif /* COMMENT */
  9489.  
  9490.     if ((x = cmcfm()) < 0) return(x);
  9491.     sstate = 'x';
  9492. #ifdef MAC
  9493.     what = W_RECV;
  9494.     scrcreate();
  9495. #endif /* MAC */
  9496.     if (local) displa = 1;
  9497. #ifdef AMIGA
  9498.     reqoff();            /* No DOS requestors while server */
  9499. #endif /* AMIGA */
  9500.     return(0);
  9501.     }
  9502. #endif /* NOSERVER */
  9503.  
  9504.     if (cx == XXSAVE) {            /* SAVE command */
  9505.     x = cmkey(savtab,nsav,"option","keymap",xxstring);
  9506.     if (x == -3) {
  9507.         printf("?You must specify an option to save\n");
  9508.         return(-9);
  9509.     }
  9510.     if (x < 0) return(x);
  9511.     /* have to set success separately for each item in doprm()... */
  9512.     /* actually not really, could have just had doprm return 0 or 1 */
  9513.     /* and set success here... */
  9514.     y = dosave(x);
  9515.     if (y == -3) {
  9516.         printf("?More fields required\n");
  9517.         return(-9);
  9518.     } else return(y);
  9519.     }
  9520.  
  9521.     if (cx == XXSET) {            /* SET command */
  9522.     x = cmkey(prmtab,nprm,"Parameter","",xxstring);
  9523.     if (x == -3) {
  9524.         printf("?You must specify a parameter to set\n");
  9525.         return(-9);
  9526.     }
  9527.     if (x < 0) return(x);
  9528.     /* have to set success separately for each item in doprm()... */
  9529.     /* actually not really, could have just had doprm return 0 or 1 */
  9530.     /* and set success here... */
  9531.     y = doprm(x,0);
  9532.     if (y == -3) {
  9533.         printf("?More fields required\n");
  9534.         return(-9);
  9535.     } else return(y);
  9536.     }
  9537.  
  9538. #ifndef NOPUSH
  9539.     if (cx == XXSHE            /* SHELL (system) command */
  9540.     || cx == XXEXEC            /* exec() */
  9541.     ) {
  9542.     int rx = 0;
  9543.     char * p = NULL;
  9544.     int i /* ,n */ ;
  9545. #ifdef UNIXOROSK
  9546.     char * args[256];
  9547. #endif /* UNIXOROSK */
  9548.  
  9549. #ifdef IKSD
  9550.     if (inserver && (nopush || !ENABLED(en_hos))) {
  9551.         printf("?Sorry, host command access is disabled\n");
  9552.         return(-9);
  9553.     }
  9554. #endif /* IKSD */
  9555.  
  9556. #ifdef CKEXEC
  9557.     if (cx == XXEXEC) {        /* EXEC (overlay ourselves) */
  9558.         struct FDB sw, fl;
  9559.         cmfdbi(&sw,            /* First FDB - command switches */
  9560.            _CMKEY,        /* fcode */
  9561.            "Command to overlay C-Kermit\n or switch", /* hlpmsg */
  9562.            "",            /* default */
  9563.            "",            /* addtl string data */
  9564.            1,            /* addtl numeric data 1: tbl size */
  9565.            4,            /* addtl numeric data 2: 4 = cmswi */
  9566.            xxstring,        /* Processing function */
  9567.            redirsw,        /* Keyword table */
  9568.            &fl            /* Pointer to next FDB */
  9569.            );
  9570.         cmfdbi(&fl,            /* 2nd FDB - command to exec */
  9571.            _CMFLD,        /* fcode */
  9572.            "Command to overlay C-Kermit", /* hlpmsg */
  9573.            "",            /* default */
  9574.            "",            /* addtl string data */
  9575.            0,            /* addtl numeric data 1 */
  9576.            0,            /* addtl numeric data 2 */
  9577.            xxstring,
  9578.            NULL,
  9579.            NULL            /* No more after this */
  9580.            );
  9581.         while (1) {
  9582.         x = cmfdb(&sw);        /* Parse something */
  9583.         debug(F101,"exec cmfdb","",x);
  9584.         if (x < 0)
  9585.           return(x);
  9586.         /* Generalize this if we add more switches */
  9587.         if (cmresult.fcode == _CMKEY) {
  9588.             rx = 1;
  9589.             continue;
  9590.         }
  9591.         if (cmresult.fcode == _CMFLD)
  9592.           break;
  9593.         return(-2);
  9594.         }
  9595.         ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ);
  9596.         if (!tmpbuf[0]) {
  9597.         printf("?Command required\n");
  9598.         return(-9);
  9599.         }
  9600.         p = brstrip(tmpbuf);
  9601.         args[0] = NULL;        /* Set argv[0] to it */
  9602.         makestr(&args[0],p);
  9603.         for (i = 1; i < 255; i++) {    /* Get arguments for command */
  9604.         if ((x = cmfld("Argument","",&s,xxstring)) < 0) {
  9605.             if (x == -3) {
  9606.             if ((x = cmcfm()) < 0)
  9607.               return(x);
  9608.             break;
  9609.             } else
  9610.               return(x);
  9611.         }
  9612.         args[i] = NULL;
  9613.         s = brstrip(s);
  9614.         makestr(&args[i],s);
  9615.         }
  9616.         args[i] = NULL;
  9617.     } else {
  9618. #endif /* CKEXEC */
  9619.         if ((x = cmtxt("System command to execute","",&s,xxstring)) < 0)
  9620.           return(x);
  9621. #ifdef CKEXEC
  9622.     }
  9623. #endif /* CKEXEC */
  9624.         if (nopush)
  9625.           return(success = 0);
  9626. #ifdef CK_APC
  9627.     if (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
  9628.       return(success = 0);
  9629. #endif /* CK_APC */
  9630.     conres();            /* Make console normal  */
  9631. #ifdef OS2
  9632.     if (!(s && *s)) {
  9633.         os2push();
  9634.             return(success = 1);
  9635.     } else
  9636. #endif /* OS2 */
  9637.       if (cx == XXSHE) {
  9638.           x = zshcmd(s);
  9639.           debug(F101,"RUN zshcmd code","",x);
  9640.           concb((char)escape);
  9641.           return(success = x);
  9642. #ifdef CKEXEC
  9643.       } else {
  9644. #ifdef DEBUG
  9645.           if (deblog) {
  9646.           debug(F111,"EXEC cmd",p,0);
  9647.           for (i = 0; i < 256 && args[i]; i++)
  9648.             debug(F111,"EXEC arg",args[i],i);
  9649.           }
  9650. #endif /* DEBUG */
  9651.           if (p) {
  9652.           z_exec(p,args,rx);    /* Overlay ourself */
  9653.           debug(F100,"EXEC fails","",0);
  9654.           concb((char)escape);    /* In case it returns */
  9655.           }
  9656.           return(success = 0);
  9657. #endif /* CKEXEC */
  9658.       }
  9659.     }
  9660.  
  9661. #ifdef CK_REDIR
  9662.     if (cx == XXFUN) {            /* REDIRECT */
  9663. #ifdef CK_APC
  9664.     if ((apcactive == APC_LOCAL) ||
  9665.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  9666.       return(success = 0);
  9667. #endif /* CK_APC */
  9668.     ckmakmsg(tmpbuf,
  9669.          TMPBUFSIZ,
  9670.          "Local command to run,\n",
  9671.          "with its standard input/output redirected to ",
  9672.          local ? ttname : "the communications connection",
  9673.          "\n"
  9674.          );
  9675.     if ((x = cmtxt(tmpbuf,"",&s,xxstring)) < 0)
  9676.       return(x);
  9677.         if (nopush) {
  9678.             printf("?REDIRECT disabled\n");
  9679.             return(success=0);
  9680.         }
  9681.     if (!local) {
  9682.         printf("?SET LINE or SET HOST required first\n");
  9683.         return(-9);
  9684.     }
  9685.     if (!*s) {
  9686.         printf("?REDIRECT requires a command to redirect\n");
  9687.         return(-9);
  9688.     }
  9689.     return(success = ttruncmd(s));
  9690.     }
  9691. #endif /* CK_REDIR */
  9692. #endif /* NOPUSH */
  9693.  
  9694. #ifndef NOSHOW
  9695.     if (cx == XXSHO) {            /* SHOW */
  9696.     x = cmkey(shotab,nsho,"","parameters",xxstring);
  9697.     if (x < 0) return(x);
  9698.     return(doshow(x));
  9699.     }
  9700. #endif /* NOSHOW */
  9701.  
  9702. #ifndef MAC
  9703.     if (cx == XXSPA) {            /* SPACE */
  9704. #ifdef IKSD
  9705.     if (inserver && !ENABLED(en_spa)) {
  9706.         printf("?Sorry, SPACE command disabled\n");
  9707.         return(-9);
  9708.     }
  9709. #endif /* IKSD */
  9710. #ifdef datageneral
  9711.     /* AOS/VS can take an argument after its "space" command. */
  9712.     if ((x = cmtxt("Confirm, or local directory name","",&s,xxstring)) < 0)
  9713.       return(x);
  9714.     if (nopush) {
  9715.         printf("?Sorry, SPACE command disabled\n");
  9716.         return(-9);
  9717.     } else if (*s == NUL) {
  9718.         xsystem(SPACMD);
  9719.     } else {
  9720.         ckmakmsg(line,LINBUFSIZ,"space ",s,NULL,NULL);
  9721.         xsystem(line);
  9722.     }
  9723. #else
  9724. #ifdef OS2
  9725.     if ((x = cmtxt("Press Enter for current disk,\n\
  9726.  or specify a disk letter like A:","",&s,xxstring)) < 0)
  9727.       return(x);
  9728.     if (*s == NUL) {        /* Current disk */
  9729.             unsigned long space = zdskspace(0);
  9730.             if (space > 0 && space < 1024)
  9731.               printf(" Free space: unknown\n");
  9732.             else
  9733.           printf(" Free space: %ldK\n", space/1024L);
  9734.     } else {
  9735.         int drive = toupper(*s);
  9736.             unsigned long space = zdskspace(drive - 'A' + 1);
  9737.             if (space > 0 && space < 1024)
  9738.               printf(" Drive %c: unknown free\n");
  9739.             else
  9740.               printf(" Drive %c: %ldK free\n", drive,space / 1024L);
  9741.     }
  9742. #else
  9743. #ifdef UNIXOROSK
  9744.     x = cmdir("Confirm for current disk,\n\
  9745.  or specify a disk device or directory","",&s,xxstring);
  9746.     if (x == -3)
  9747.       s = "";
  9748.     else if (x < 0)
  9749.       return(x);
  9750.         ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  9751.         s = tmpbuf;
  9752.     if ((x = cmcfm()) < 0) return(x);
  9753.     if (nopush) {
  9754.         printf("?Sorry, SPACE command disabled\n");
  9755.         return(-9);
  9756.     }
  9757.     if (!*s) {            /* Current disk */
  9758.         xsystem(SPACMD);
  9759.     } else {            /* Specified disk */
  9760.         ckmakmsg(line,LINBUFSIZ,SPACM2," ",s,NULL);
  9761.         xsystem(line);
  9762.     }
  9763. #else
  9764.     if ((x = cmcfm()) < 0) return(x);
  9765.     if (nopush) {
  9766.         printf("?Sorry, SPACE command disabled\n");
  9767.         return(-9);
  9768.     }
  9769.     xsystem(SPACMD);
  9770. #endif /* UNIXOROSK */
  9771. #endif /* OS2 */
  9772. #endif /* datageneral */
  9773.     return(success = 1);        /* Pretend it worked */
  9774.     }
  9775. #endif /* MAC */
  9776.  
  9777. #ifndef NOXFER
  9778.     if (cx == XXSTA) {            /* STATISTICS */
  9779.     if ((x = cmkey(stattab,2,"Carriage return, or option",
  9780.                "/brief",xxstring)) < 0)
  9781.       return(x);
  9782.     if ((y = cmcfm()) < 0) return(y);
  9783.     return(success = dostat(x));
  9784.     }
  9785. #endif /* NOXFER */
  9786.  
  9787.     if (cx == XXSTO || cx == XXEND) {    /* STOP, END, or POP */
  9788.     if ((y = cmnum("exit status code","0",10,&x,xxstring)) < 0)
  9789.       return(y);
  9790.     if ((y = cmtxt("Message to print","",&s,xxstring)) < 0)
  9791.       return(y);
  9792.     s = brstrip(s);
  9793.     if (*s) printf("%s\n",s);
  9794.     if (cx == XXSTO) {
  9795.         dostop();
  9796.     } else {
  9797.         doend(x);
  9798.     }
  9799.     return(success = (x == 0));
  9800.     }
  9801.     if (cx == XXSUS) {            /* SUSPEND */
  9802.     if ((y = cmcfm()) < 0) return(y);
  9803. #ifdef NOJC
  9804.     printf("Sorry, this version of Kermit cannot be suspended\n");
  9805. #else
  9806. #ifdef IKSD
  9807.     if (inserver) {
  9808.         printf("?Sorry, IKSD can not be suspended\n");
  9809.         return(-9);
  9810.     } else
  9811. #endif /* IKSD */
  9812.       if (nopush) {
  9813.         printf("?Sorry, access to system is disabled\n");
  9814.         return(-9);
  9815.     }
  9816.     stptrap(0);
  9817. #endif /* NOJC */
  9818.     return(0);
  9819.     }
  9820.  
  9821.     if (cx == XXTAK) {            /* TAKE */
  9822.     char * scriptenv = NULL;    
  9823. #ifdef OS2
  9824.         char * GetAppData(int);
  9825.     extern char startupdir[],exedir[],inidir[];
  9826.     char * keymapenv = NULL;
  9827.         char * appdata0 = NULL, *appdata1 = NULL;
  9828.     int xx;
  9829. #define TAKEPATHLEN 4096
  9830. #else /* OS2 */
  9831. #define TAKEPATHLEN 1024
  9832. #endif /* OS2 */
  9833.     char takepath[TAKEPATHLEN];
  9834.  
  9835.     if (tlevel >= MAXTAKE-1) {
  9836.         printf("?Take files nested too deeply\n");
  9837.         return(-9);
  9838.     }
  9839. #ifdef OS2
  9840. #ifdef NT
  9841.     scriptenv = getenv("K95SCRIPTS");
  9842.     keymapenv = getenv("K95KEYMAPS");
  9843.         makestr(&appdata0,(char *)GetAppData(0));
  9844.         makestr(&appdata1,(char *)GetAppData(1));
  9845. #else /* NT */
  9846.     scriptenv = getenv("K2SCRIPTS");
  9847.     keymapenv = getenv("K2KEYMAPS");
  9848. #endif /* NT */
  9849. #endif /* OS2 */
  9850.  
  9851.     if (!scriptenv)            /* Let this work for Unix etc too */
  9852.       scriptenv = getenv("CK_SCRIPTS"); /* Use this if defined */
  9853. #ifndef OS2
  9854.     if (!scriptenv)            /* Otherwise use home directory */
  9855.       scriptenv = homepath();
  9856. #endif /* OS2 */
  9857.     if (!scriptenv)
  9858.       scriptenv = "";
  9859.     ckstrncpy(takepath,scriptenv,TAKEPATHLEN);
  9860.     debug(F110,"TAKE initial takepath",takepath,0);
  9861.  
  9862. #ifdef OS2
  9863.     if (!keymapenv)
  9864.       keymapenv = getenv("CK_KEYMAPS");
  9865.     if (!keymapenv)
  9866.       keymapenv = "";
  9867.  
  9868.     ckstrncat(takepath,
  9869.           (scriptenv && scriptenv[strlen(scriptenv)-1]==';')?"":";",
  9870.           TAKEPATHLEN
  9871.           );
  9872.     ckstrncat(takepath,keymapenv?keymapenv:"",TAKEPATHLEN);
  9873.     ckstrncat(takepath,
  9874.           (keymapenv && keymapenv[strlen(keymapenv)-1]==';')?"":";",
  9875.           TAKEPATHLEN
  9876.           );
  9877.     ckstrncat(takepath,startupdir,TAKEPATHLEN);
  9878.     ckstrncat(takepath,";",TAKEPATHLEN);
  9879.     ckstrncat(takepath,startupdir,TAKEPATHLEN);
  9880.     ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
  9881.     ckstrncat(takepath,startupdir,TAKEPATHLEN);
  9882.     ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
  9883.  
  9884.     ckstrncat(takepath,appdata1,TAKEPATHLEN);
  9885.     ckstrncat(takepath,"Kermit 95/;",TAKEPATHLEN);
  9886.     ckstrncat(takepath,appdata1,TAKEPATHLEN);
  9887.     ckstrncat(takepath,"Kermit 95/SCRIPTS/;",TAKEPATHLEN);
  9888.     ckstrncat(takepath,appdata1,TAKEPATHLEN);
  9889.     ckstrncat(takepath,"Kermit 95/KEYMAPS/;",TAKEPATHLEN);
  9890.  
  9891.     ckstrncat(takepath,appdata0,TAKEPATHLEN);
  9892.     ckstrncat(takepath,"Kermit 95/;",TAKEPATHLEN);
  9893.     ckstrncat(takepath,appdata0,TAKEPATHLEN);
  9894.     ckstrncat(takepath,"Kermit 95/SCRIPTS/;",TAKEPATHLEN);
  9895.     ckstrncat(takepath,appdata0,TAKEPATHLEN);
  9896.     ckstrncat(takepath,"Kermit 95/KEYMAPS/;",TAKEPATHLEN);
  9897.  
  9898.     ckstrncat(takepath,inidir,TAKEPATHLEN);
  9899.     ckstrncat(takepath,";",TAKEPATHLEN);
  9900.     ckstrncat(takepath,inidir,TAKEPATHLEN);
  9901.     ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
  9902.     ckstrncat(takepath,inidir,TAKEPATHLEN);
  9903.     ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
  9904.  
  9905.     ckstrncat(takepath,zhome(),TAKEPATHLEN);
  9906.     ckstrncat(takepath,";",TAKEPATHLEN);
  9907.     ckstrncat(takepath,zhome(),TAKEPATHLEN);
  9908.     ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
  9909.     ckstrncat(takepath,zhome(),TAKEPATHLEN);
  9910.     ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
  9911.  
  9912.     ckstrncat(takepath,exedir,TAKEPATHLEN);
  9913.     ckstrncat(takepath,";",TAKEPATHLEN);
  9914.     ckstrncat(takepath,exedir,TAKEPATHLEN);
  9915.     ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
  9916.     ckstrncat(takepath,exedir,TAKEPATHLEN);
  9917.     ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
  9918. #endif /* OS2 */
  9919.     debug(F110,"TAKE final takepath",takepath,0);
  9920.  
  9921.     if ((y = cmifip("Commands from file",
  9922.             "",&s,&x,0,takepath,xxstring)) < 0) {
  9923.         if (y == -3) {
  9924.         printf("?A file name is required\n");
  9925.         return(-9);
  9926.         } else
  9927.           return(y);
  9928.     }
  9929.     if (x != 0) {
  9930.         printf("?Wildcards not allowed in command file name\n");
  9931.         return(-9);
  9932.     }
  9933.     ckstrncpy(line,s,LINBUFSIZ);
  9934.     debug(F110,"TAKE file",s,0);
  9935.     if (isdir(s)) {
  9936.         printf("?Can't execute a directory - \"%s\"\n", s);
  9937.         return(-9);
  9938.     }
  9939. #ifndef NOTAKEARGS
  9940.     {
  9941.         char * p;
  9942.         x = strlen(line);
  9943.         debug(F111,"TAKE args",line,x);
  9944.         p = line + x + 1;
  9945.         if ((y = cmtxt("Optional arguments","",&s,xxstring)) < 0)
  9946.           return(y);
  9947.         if (*s) {            /* Args given? */
  9948.         ckstrncpy(p,s,LINBUFSIZ-x-1);
  9949. #ifdef ZFNQFP
  9950.         zfnqfp(line,TMPBUFSIZ,tmpbuf);
  9951.         s = tmpbuf;
  9952. #else
  9953.         s = line;
  9954. #endif /* ZFNQFP */
  9955.         debug(F110,"TAKE filename",s,0);
  9956.         x = strlen(s);
  9957.         debug(F101,"TAKE new len",s,x);
  9958.  
  9959. #ifdef COMMENT
  9960. /*
  9961.   This was added in C-Kermit 7.0 to allow args to be passed from the TAKE
  9962.   command to the command file.  But it overwrites the current argument vector,
  9963.   which is at best surprising, and at worst unsafe.
  9964. */
  9965.         addmac("%0",s);        /* Define %0 = name of file */
  9966.         varnam[0] = '%';
  9967.         varnam[2] = '\0';
  9968.         debug(F110,"take arg 0",s,0);
  9969.         debug(F110,"take args",p,0);
  9970.         for (y = 1; y < 10; y++) { /* Clear current args %1..%9 */
  9971.             varnam[1] = (char) (y + '0');
  9972.             delmac(varnam,0);
  9973.         }
  9974.         xwords(p,MAXARGLIST,NULL,0); /* Assign new args */
  9975.         debug(F110,"take args",p,0);
  9976. #else
  9977. /*
  9978.   This method is used in 8.0.  If the TAKE command includes arguments, we
  9979.   insert an intermediate temporary macro between the current level; we pass
  9980.   the arguments to the macro and then the macro TAKEs the command file.
  9981.   If the user Ctrl-C's out of the TAKE file, some temporary macro definitions
  9982.   and other small malloc'd bits might be left behind.
  9983. */
  9984.         {
  9985.             char * q = NULL;
  9986.             char * r = NULL;
  9987.             int k, m;
  9988.             m = maclvl;
  9989.             q = (char *)malloc(x+24);
  9990.             if (q) {
  9991.             r = (char *)malloc(x+24);
  9992.             if (r) {
  9993.                 sprintf(q,"_file[%s](%d)",s,cmdlvl); /* safe */
  9994.                 sprintf(r,"take %s",s); /* safe */
  9995.                 k = addmac(q,r);
  9996.                 if (k > -1) {
  9997.                 dodo(k,p,0);
  9998.                 while (maclvl > m) {
  9999.                     sstate = (CHAR) parser(1);
  10000.                     if (sstate) proto();
  10001.                 }
  10002.                 }
  10003.                 k = delmac(q,0);
  10004.                 free(q);
  10005.                 free(r);
  10006.                 return(success);
  10007.             }
  10008.             }
  10009.         }
  10010.         return(success = 0);
  10011. #endif /* COMMENT */
  10012.         }
  10013.     }
  10014. #else
  10015.     if ((y = cmcfm()) < 0) return(y);
  10016. #endif /* NOTAKEARGS */
  10017.     return(success = dotake(line));
  10018.     }
  10019.  
  10020. #ifndef NOLOCAL
  10021. #ifdef OS2
  10022.     if (cx == XXVIEW) {            /* VIEW Only Terminal mode */
  10023.     viewonly = TRUE;
  10024.     success = doconect(0, 0);
  10025.     viewonly = FALSE;
  10026.     return success;
  10027.     }
  10028. #endif /* OS2 */
  10029.  
  10030. #ifdef NETCONN
  10031.     if (cx == XXTEL || cx == XXIKSD) {    /* TELNET */
  10032.     int x,z;
  10033. #ifdef OS2
  10034.     if (!tcp_avail) {
  10035.         printf("?Sorry, either TCP/IP is not available on this system or\n\
  10036. necessary DLLs did not load.  Use SHOW NETWORK to check network status.\n");
  10037.         success = 0;
  10038.         return(-9);
  10039.     } else
  10040. #endif /* OS2 */
  10041.       {
  10042.       x = nettype;            /* Save net type in case of failure */
  10043.       z = ttnproto;            /* Save protocol in case of failure */
  10044.       nettype = NET_TCPB;
  10045.       ttnproto = (cx == XXTEL) ? NP_TELNET : NP_KERMIT;
  10046.       if ((y = setlin(XYHOST,0,1)) <= 0) {
  10047.               nettype = x;        /* Failed, restore net type. */
  10048.               ttnproto = z;        /* and protocol */
  10049.               success = 0;
  10050.       }
  10051.       didsetlin++;
  10052.         }
  10053.     return(y);
  10054.     }
  10055.  
  10056. #ifndef PTYORPIPE
  10057. #ifdef NETCMD
  10058. #define PTYORPIPE
  10059. #else
  10060. #ifdef NETPTY
  10061. #define PTYORPIPE
  10062. #endif /* NETPTY */
  10063. #endif /* NETCMD */
  10064. #endif /* PTYORPIPE */
  10065.  
  10066. #ifdef PTYORPIPE
  10067.     if (cx == XXPIPE || cx == XXPTY) {    /* PIPE or PTY */
  10068.     int x;
  10069.     extern int netsave;
  10070.     x = nettype;            /* Save net type in case of failure */
  10071.     nettype = (cx == XXPIPE) ? NET_CMD : NET_PTY;
  10072.     if ((y = setlin(XYHOST,0,1)) < 0) {
  10073.         nettype = x;        /* Failed, restore net type. */
  10074.         ttnproto = z;        /* and protocol */
  10075.         success = 0;
  10076.     }
  10077.     didsetlin++;
  10078.     netsave = x;
  10079.     return(y);
  10080.     }
  10081. #endif /* PTYORPIPE */
  10082.  
  10083. #ifdef ANYSSH
  10084.     if (cx == XXSSH) {            /* SSH (Secure Shell) */
  10085.     extern int netsave;
  10086. #ifdef SSHBUILTIN
  10087.     int k, x, havehost = 0, trips = 0;
  10088.         int    tmpver = -1, tmpxfw = -1;
  10089. #ifndef SSHTEST
  10090.         extern int sl_ssh_xfw, sl_ssh_xfw_saved;
  10091.         extern int sl_ssh_ver, sl_ssh_ver_saved;
  10092. #endif /* SSHTEST */
  10093.         extern int mdmtyp, mdmsav, cxtype, sl_uid_saved;
  10094.         extern char * slmsg;
  10095.     extern char uidbuf[], sl_uidbuf[];
  10096.         extern char pwbuf[], * g_pswd;
  10097.         extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
  10098.     struct FDB sw, kw, fl;
  10099.  
  10100.         if (ssh_tmpstr)
  10101.             memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
  10102.         makestr(&ssh_tmpstr,NULL);
  10103.         makestr(&ssh_tmpuid,NULL);
  10104.         makestr(&ssh_tmpcmd,NULL);
  10105.         makestr(&ssh_tmpport,NULL);
  10106.  
  10107.     cmfdbi(&kw,            /* 1st FDB - commands */
  10108.            _CMKEY,            /* fcode */
  10109.            "host [ port ],\n or action",    /* hlpmsg */
  10110.            "",            /* default */
  10111.            "",            /* addtl string data */
  10112.            nsshcmd,            /* addtl numeric data 1: tbl size */
  10113.            0,            /* addtl numeric data 2: 0 = keyword */
  10114.            xxstring,        /* Processing function */
  10115.            sshkwtab,        /* Keyword table */
  10116.            &fl            /* Pointer to next FDB */
  10117.            );
  10118.     cmfdbi(&fl,            /* Host */
  10119.            _CMFLD,            /* fcode */
  10120.            "",            /* hlpmsg */
  10121.            "",            /* default */
  10122.            "",            /* addtl string data */
  10123.            0,            /* addtl numeric data 1 */
  10124.            0,            /* addtl numeric data 2 */
  10125.            xxstring,
  10126.            NULL,
  10127.            NULL
  10128.            );
  10129.  
  10130.     x = cmfdb(&kw);
  10131.     if (x == -3) {
  10132.         printf("?ssh what?\n");
  10133.         return(-9);
  10134.     }
  10135.     if (x < 0)
  10136.       return(x);
  10137.     havehost = 0;
  10138.     if (cmresult.fcode == _CMFLD) {
  10139.         havehost = 1;
  10140.         ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Hostname */
  10141.         cmresult.nresult = XSSH_OPN;
  10142.     }
  10143.     switch (cmresult.nresult) {    /* SSH keyword */
  10144.       case XSSH_OPN:        /* SSH OPEN */
  10145.         if (!havehost) {
  10146.         if ((x = cmfld("Host","",&s,xxstring)) < 0)
  10147.           return(x);
  10148.         ckstrncpy(line,s,LINBUFSIZ);
  10149.         }
  10150.         /* Parse [ port ] [ switches ] */
  10151.         cmfdbi(&kw,            /* Switches */
  10152.            _CMKEY,
  10153.            "Port number or service name,\nor switch",
  10154.            "",
  10155.            "",
  10156.            nsshopnsw,
  10157.            4,
  10158.            xxstring,
  10159.            sshopnsw,
  10160.            &fl
  10161.            );
  10162.         cmfdbi(&fl,            /* Port number or service name */
  10163.            _CMFLD,
  10164.            "",
  10165.            "",
  10166.            "",
  10167.            0,
  10168.            0,
  10169.            xxstring,
  10170.            NULL,
  10171.            NULL
  10172.            );
  10173.         trips = 0;            /* Explained below */
  10174.         while (1) {            /* Parse port and switches */
  10175.         x = cmfdb(&kw);        /* Get a field */
  10176.         if (x == -3)        /* User typed CR so quit from loop */
  10177.           break;
  10178.         if (x < 0)        /* Other parse error, pass it back */
  10179.           return(x);
  10180.         switch (cmresult.fcode) { /* Field or Keyword? */
  10181.                   case _CMFLD:          /* Field */
  10182.                     makestr(&ssh_tmpport,cmresult.sresult);
  10183.             break;
  10184.           case _CMKEY:        /* Keyword */
  10185.             switch (cmresult.nresult) {    /* Which one? */
  10186.               case SSHSW_USR:            /* /USER: */
  10187.             if (!cmgbrk()) {
  10188.                 printf("?This switch requires an argument\n");
  10189.                 return(-9);
  10190.             }
  10191.             if ((y = cmfld("Username","",&s,xxstring)) < 0)
  10192.               return(y);
  10193.             s = brstrip(s);
  10194.             makestr(&ssh_tmpuid,s);
  10195.             break;
  10196.                       case SSHSW_PWD:
  10197.             if (!cmgbrk()) {
  10198.                 printf("?This switch requires an argument\n");
  10199.                 return(-9);
  10200.             }
  10201.             debok = 0;
  10202.             if ((x = cmfld("Password","",&s,xxstring)) < 0) {
  10203.                 if (x == -3) {
  10204.                 makestr(&ssh_tmpstr,"");
  10205.                 } else {
  10206.                 return(x);
  10207.                 }
  10208.             } else {
  10209.                 s = brstrip(s);
  10210.                 if ((x = (int)strlen(s)) > PWBUFL) {
  10211.                 makestr(&slmsg,"Internal error");
  10212.                 printf("?Sorry, too long - max = %d\n",PWBUFL);
  10213.                 return(-9);
  10214.                 }
  10215.                 makestr(&ssh_tmpstr,s);
  10216.             }
  10217.             break;
  10218.  
  10219.               case SSHSW_VER:
  10220.             if ((x = cmnum("Number","",10,&z,xxstring)) < 0)
  10221.               return(x);
  10222.             if (z < 1 || z > 2) {
  10223.                 printf("?Out of range: %d\n",z);
  10224.                 return(-9);
  10225.             }
  10226.                         tmpver = z;
  10227.             break;
  10228.               case SSHSW_CMD:
  10229.               case SSHSW_SUB:
  10230.             if ((x = cmfld("Text","",&s,xxstring)) < 0)
  10231.               return(x);
  10232.                         makestr(&ssh_tmpcmd,s);
  10233.             ssh_cas = (cmresult.nresult == SSHSW_SUB);
  10234.             break;
  10235.               case SSHSW_X11:
  10236.             if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
  10237.               return(x);
  10238.                         tmpxfw = x;
  10239.             break;
  10240.               default:
  10241.                 return(-2);
  10242.             }
  10243.         }
  10244.         if (trips++ == 0) {    /* After first time through */
  10245.             cmfdbi(&kw,        /* only parse switches, not port. */
  10246.                _CMKEY,
  10247.                "Switch",
  10248.                "",
  10249.                "",
  10250.                nsshopnsw,
  10251.                4,
  10252.                xxstring,
  10253.                sshopnsw,
  10254.                NULL
  10255.                );
  10256.         }
  10257.         }
  10258.         if ((x = cmcfm()) < 0)    /* Get confirmation */
  10259.           return(x);
  10260.             if (clskconnx(1) < 0) {    /* Close current Kermit connection */
  10261.               if ( ssh_tmpstr ) {
  10262.                   memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
  10263.                   makestr(&ssh_tmpstr,NULL);
  10264.               }
  10265.               return(success = 0);
  10266.             }
  10267.         makestr(&ssh_hst,line);    /* Stash everything */
  10268.         if (ssh_tmpuid) {
  10269.                 if (!sl_uid_saved) {
  10270.                     ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
  10271.                     sl_uid_saved = 1;
  10272.                 }
  10273.         ckstrncpy(uidbuf,ssh_tmpuid,UIDBUFLEN);
  10274.         makestr(&ssh_tmpuid,NULL);
  10275.         }
  10276.             if (ssh_tmpport) {
  10277.                 makestr(&ssh_prt,ssh_tmpport);
  10278.                 makestr(&ssh_tmpport,NULL);
  10279.             } else
  10280.                 makestr(&ssh_prt,NULL);
  10281.  
  10282.             if (ssh_tmpcmd) {
  10283.                 makestr(&ssh_cmd,brstrip(ssh_tmpcmd));
  10284.                 makestr(&ssh_tmpcmd,NULL);
  10285.             } else
  10286.                 makestr(&ssh_cmd,NULL);
  10287.  
  10288.             if (tmpver > -1) {
  10289. #ifndef SSHTEST
  10290.                 if (!sl_ssh_ver_saved) {
  10291.                     sl_ssh_ver = ssh_ver;
  10292.                     sl_ssh_ver_saved = 1;
  10293.                 }
  10294. #endif /* SSHTEST */
  10295.                 ssh_ver = tmpver;
  10296.             }
  10297.             if (tmpxfw > -1) {
  10298. #ifndef SSHTEST
  10299.                 if (!sl_ssh_xfw_saved) {
  10300.                     sl_ssh_xfw = ssh_xfw;
  10301.                     sl_ssh_xfw_saved = 1;
  10302.                 }
  10303. #endif /* SSHTEST */
  10304.                 ssh_xfw = tmpxfw;
  10305.             }
  10306.         if (ssh_tmpstr) {
  10307.         if (ssh_tmpstr[0]) {
  10308.             ckstrncpy(pwbuf,ssh_tmpstr,PWBUFL+1);
  10309.             pwflg = 1;
  10310.             pwcrypt = 0;
  10311.         } else
  10312.           pwflg = 0;
  10313.         makestr(&ssh_tmpstr,NULL);
  10314.         }
  10315.         nettype = NET_SSH;
  10316.         if (mdmsav < 0)
  10317.           mdmsav = mdmtyp;
  10318.         mdmtyp = -nettype;
  10319.         x = 1;
  10320.  
  10321. #ifndef NOSPL
  10322.             makestr(&g_pswd,pwbuf);             /* Save global pwbuf */
  10323.             g_pflg = pwflg;                     /* and flag */
  10324.             g_pcpt = pwcrypt;
  10325. #endif /* NOSPL */
  10326.  
  10327.         /* Line parameter to ttopen() is ignored */
  10328.         k = ttopen(line,&x,mdmtyp, 0);
  10329.         if (k < 0) {
  10330.         printf("?Unable to connect to %s\n",ssh_hst);
  10331.         mdmtyp = mdmsav;
  10332.                 slrestor();
  10333.         return(success = 0);
  10334.         }
  10335.         duplex = 0;             /* Remote echo */
  10336.         ckstrncpy(ttname,line,TTNAMLEN); /* Record the command */
  10337.         debug(F110,"ssh ttname",ttname,0);
  10338.         makestr(&slmsg,NULL);    /* No SET LINE error message */
  10339.         cxtype = CXT_SSH;
  10340. #ifndef NODIAL
  10341.         dialsta = DIA_UNK;
  10342. #endif /* NODIAL */
  10343.         success = 1;        /* SET LINE succeeded */
  10344.         network = 1;        /* Network connection (not serial) */
  10345.         local = 1;            /* Local mode (not remote) */
  10346.         if ((reliable != SET_OFF || !setreliable))
  10347.           reliable = SET_ON;    /* Transport is reliable end to end */
  10348. #ifdef OS2
  10349.             DialerSend(OPT_KERMIT_CONNECT, 0);
  10350. #endif /* OS2 */
  10351.         setflow();            /* Set appropriate flow control */
  10352.  
  10353.         haveline = 1;
  10354. #ifdef CKLOGDIAL
  10355. #ifdef NETCONN
  10356.         dolognet();
  10357. #endif /* NETCONN */
  10358. #endif /* CKLOGDIAL */
  10359.  
  10360. #ifndef NOSPL
  10361.         if (local) {
  10362.         if (nmac) {        /* Any macros defined? */
  10363.             int k;        /* Yes */
  10364.             k = mlook(mactab,"on_open",nmac); /* Look this up */
  10365.             if (k >= 0) {                  /* If found, */
  10366.             if (dodo(k,ssh_hst,0) > -1)   /* set it up, */
  10367.               parser(1);              /* and execute it */
  10368.             }
  10369.         }
  10370.         }
  10371. #endif /* NOSPL */
  10372. #ifdef LOCUS        
  10373.         if (autolocus)
  10374.         setlocus(1,1);
  10375. #endif /* LOCUS */
  10376.  
  10377.     /* Command was confirmed so we can pre-pop command level. */
  10378.     /* This is so CONNECT module won't think we're executing a */
  10379.     /* script if CONNECT was the final command in the script. */
  10380.         if (cmdlvl > 0)
  10381.           prepop();
  10382.         success = doconect(0,cmdlvl == 0 ? 1 : 0);
  10383.         if (ttchk() < 0)
  10384.           dologend();
  10385.         return(success);
  10386.  
  10387.       case XSSH_CLR:
  10388.         if ((y = cmkey(sshclr,nsshclr,"","", xxstring)) < 0) {
  10389.             if (y == -3) {
  10390.             printf("?clear what?\n");
  10391.             return(-9);
  10392.         }
  10393.             return(y);
  10394.         }
  10395.         if ((x = cmcfm()) < 0)
  10396.           return(x);
  10397.         switch (y) {
  10398.           case SSHC_LPF:
  10399.                 ssh_pf_lcl_n = 0;
  10400.         break;
  10401.           case SSHC_RPF:
  10402.         ssh_pf_rmt_n = 0;
  10403.         break;
  10404.           default:
  10405.         return(-2);
  10406.         }
  10407.             return(success = 1);    /* or whatever */
  10408.  
  10409.       case XSSH_AGT: {        /* SSH AGENT */
  10410.           int doeach = 0;
  10411.           if ((y = cmkey(sshagent,nsshagent,"","",xxstring)) < 0)
  10412.         return(y);
  10413.           switch (y) {
  10414.         case SSHA_ADD:        /* SSH AGENT ADD ... */
  10415.           if ((x = cmifi("Identity file","",&s,&y,xxstring)) < 0) {
  10416. #ifndef SSHTEST
  10417.               if (x == -3)    /* No name given */
  10418.             doeach = 1;    /* so do them all */
  10419.               else
  10420. #endif /* SSHTEST */
  10421.             return(x);
  10422.           }
  10423.           ckstrncpy(line,s,LINBUFSIZ);
  10424.           if ((x = cmcfm()) < 0)
  10425.             return(x);
  10426. #ifdef SSHTEST
  10427.           x = 0;
  10428. #else
  10429.           if (doeach) {
  10430.                       int i;
  10431.                       x = 0;
  10432.                       for (i = 0; i < ssh_idf_n; i++)
  10433.             x += ssh_agent_add_file(ssh_idf[i]);
  10434.           } else
  10435.             x = ssh_agent_add_file(line);
  10436. #endif /* SSHTEST */
  10437.           return(success = (x == 0));
  10438.  
  10439.         case SSHA_DEL: {    /* SSH AGENT DELETE ... */
  10440.             int doall = 0;
  10441.             if ((x = cmifi("Identity file","",&s,&y,xxstring)) < 0) {
  10442. #ifndef SSHTEST
  10443.             if (x == -3)    /* No name given */
  10444.               doall = 1;    /* so do them all */
  10445.             else
  10446. #endif /* SSHTEST */
  10447.               return(x);
  10448.             }
  10449.             ckstrncpy(line,s,LINBUFSIZ);
  10450.             if ((x = cmcfm()) < 0)
  10451.               return(x);
  10452. #ifdef SSHTEST
  10453.             x = 0;
  10454. #else
  10455.             if (doall)
  10456.               x = ssh_agent_delete_all();
  10457.             else
  10458.               x = ssh_agent_delete_file(line);
  10459. #endif /* SSHTEST */
  10460.             return(success = (x == 0));
  10461.         }
  10462.         case SSHA_LST: {
  10463.             int fingerprint = 0;
  10464.             if ((y = cmswi(sshagtsw,nsshagtsw,"","",xxstring)) < 0) {
  10465.             if (y != -3)
  10466.               return(y);
  10467.             } else if (cmgbrk() > SP) {
  10468.             printf("?This switch does not take an argument\n");
  10469.             return(-9);
  10470.             } else if (y == SSHASW_FP) {
  10471.             fingerprint = 1;
  10472.             }
  10473.             if ((x = cmcfm()) < 0)
  10474.               return(x);
  10475. #ifdef SSHTEST
  10476.             return(success = 1);
  10477. #else
  10478.             return(success =
  10479.                (ssh_agent_list_identities(fingerprint) == 0));
  10480. #endif /* SSHTEST */
  10481.         }
  10482.         default:
  10483.           return(-2);
  10484.           }
  10485.       }
  10486.       case XSSH_ADD: {        /* SSH ADD */
  10487.           /* ssh add { local, remote } port host port */
  10488.           int cx, i, j, k;
  10489.           char * h;
  10490.           if ((cx = cmkey(addfwd,naddfwd,"","", xxstring)) < 0)
  10491.         return(cx);
  10492.           if ((x = cmnum((cx == SSHF_LCL) ?
  10493.                  "Local port number" : "Remote port number",
  10494.                  "",10,&j,xxstring)) < 0)
  10495.         return(x);
  10496.           if ((x = cmfld("Host","",&s,xxstring)) < 0)
  10497.         return(x);
  10498.           makestr(&h,s);
  10499.           if ((x = cmnum("Port","",10,&k,xxstring)) < 0)
  10500.         return(x);
  10501.           if ((x = cmcfm()) < 0)
  10502.         return(x);
  10503.  
  10504.           switch(cx) {
  10505.         case SSHF_LCL:
  10506.            if (ssh_pf_lcl_n == 32) {
  10507.                printf(
  10508. "?Maximum number of local port forwardings already specified\n"
  10509.                  );
  10510.                free(h);
  10511.                return(success = 0);
  10512.           }
  10513.           ssh_pf_lcl[ssh_pf_lcl_n].p1 = j;
  10514.           makestr(&(ssh_pf_lcl[ssh_pf_lcl_n].host),h);
  10515.           makestr(&h,NULL);
  10516.           ssh_pf_lcl[ssh_pf_lcl_n].p2 = k;
  10517.           ssh_pf_lcl_n++;
  10518.           break;
  10519.         case SSHF_RMT:
  10520.           if (ssh_pf_rmt_n == 32) {
  10521.               printf(
  10522. "?Maximum number of remote port forwardings already specified\n"
  10523.                 );
  10524.               free(h);
  10525.               return(success = 0);
  10526.           }
  10527.           ssh_pf_rmt[ssh_pf_rmt_n].p1 = j;
  10528.           makestr(&(ssh_pf_rmt[ssh_pf_rmt_n].host),h);
  10529.           makestr(&h,NULL);
  10530.           ssh_pf_rmt[ssh_pf_rmt_n].p2 = k;
  10531.           ssh_pf_rmt_n++;
  10532.           }
  10533.           return(success = 1);
  10534.       }
  10535.       /* Not supporting arbitrary forwarding yet */
  10536.       case XSSH_FLP:        /* SSH FORWARD-LOCAL-PORT */
  10537.       case XSSH_FRP: {        /* SSH FORWARD-REMOTE-PORT */
  10538.           int li_port = 0;
  10539.           int to_port = 0;
  10540.           char * fw_host = NULL;
  10541.           int n;
  10542.               if ((x = cmnum(cmresult.nresult == XSSH_FLP ?
  10543.                               "local-port":"remote-port",
  10544.                               "",10,&li_port,xxstring)) < 0)
  10545.                   return(x);
  10546.               if (li_port < 1 || li_port > 65535) {
  10547.                   printf("?Out range - min: 1, max: 65535\n");
  10548.                   return(-9);
  10549.               }
  10550.           if ((x = cmfld("host",ssh_hst?ssh_hst:"",&s,xxstring)) < 0)
  10551.         return(x);
  10552.               n = ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  10553.               fw_host = tmpbuf;
  10554.               if ((x = cmnum("host-port",ckuitoa(li_port),10,
  10555.                               &to_port,xxstring)) < 0)
  10556.                   return(x);
  10557.               if (to_port < 1 || to_port > 65535) {
  10558.                   printf("?Out range - min: 1, max: 65535\n");
  10559.                   return(-9);
  10560.               }
  10561.           if ((x = cmcfm()) < 0)
  10562.         return(x);
  10563.           switch (cmresult.nresult) {
  10564.                 case XSSH_FLP:    /* SSH FORWARD-LOCAL-PORT */
  10565. #ifndef SSHTEST
  10566.                   ssh_fwd_local_port(li_port,fw_host,to_port);
  10567. #endif /* SSHTEST */
  10568.           return(success = 1);
  10569.         case XSSH_FRP:    /* SSH FORWARD-REMOTE-PORT */
  10570. #ifndef SSHTEST
  10571.                   ssh_fwd_remote_port(li_port,fw_host,to_port);
  10572. #endif /* SSHTEST */
  10573.           return(success = 1);
  10574.           }
  10575.           return(success = 1);
  10576.       }
  10577.     case XSSH_V2:        /* SSH V2 */
  10578.       if ((cx = cmkey(ssh2tab,nssh2tab,"","", xxstring)) < 0)
  10579.         return(cx);
  10580.       switch (cx) {
  10581.         case XSSH2_RKE:
  10582.           if ((x = cmcfm()) < 0)
  10583.         return(x);
  10584. #ifndef SSHTEST
  10585.           ssh_v2_rekey();
  10586. #endif /* SSHTEST */
  10587.           return(success = 1);
  10588.         default:
  10589.           return(-2);
  10590.       }
  10591.     case XSSH_KEY:
  10592.       if ((cx = cmkey(sshkey,nsshkey,"","", xxstring)) < 0)
  10593.         return(cx);
  10594.       switch (cx) {
  10595.         case SSHK_PASS: {    /* Change passphrase */
  10596.           char * oldp = NULL, * newp = NULL;
  10597.           struct FDB df, sw;
  10598.           cmfdbi(&sw,
  10599.              _CMKEY,        /* fcode */
  10600.              "Filename, or switch", /* hlpmsg */
  10601.              "",        /* default */
  10602.              "",        /* addtl string data */
  10603.              2,            /* addtl numeric data 1: tbl size */
  10604.              4,            /* addtl numeric data 2: 4 = cmswi */
  10605.              xxstring,        /* Processing function */
  10606.              sshkpsw,        /* Keyword table */
  10607.              &df        /* Pointer to next FDB */
  10608.              );
  10609.           cmfdbi(&df,        /* 2nd FDB - file for display */
  10610.              _CMIFI,        /* output file */
  10611.              "",        /* hlpmsg */
  10612.              "",        /* default */
  10613.              "",        /* addtl string data */
  10614.              0,            /* addtl numeric data 1 */
  10615.              0,            /* addtl numeric data 2 */
  10616.              xxstring,
  10617.              NULL,
  10618.              NULL
  10619.              );
  10620.           line[0] = NUL;
  10621.  
  10622.           while (1) {
  10623.           x = cmfdb(&sw);
  10624.           if (x == -3) break;
  10625.           if (x < 0)
  10626.             return(x);
  10627.           if (cmresult.fcode != _CMKEY)
  10628.             break;
  10629.           if (!cmgbrk()) {
  10630.               printf("?This switch requires an argument\n");
  10631.               return(-9);
  10632.           }
  10633.           if ((y = cmfld("Passphrase","",&s,xxstring)) < 0)
  10634.             return(y);
  10635.           switch (cmresult.nresult) {
  10636.             case 1:        /* Old */
  10637.               makestr(&oldp,s);
  10638.               break;
  10639.             case 2:        /* New */
  10640.               makestr(&newp,s);
  10641.           }
  10642.           }
  10643.           if (cmresult.fcode == _CMIFI) { /* Filename */
  10644.           ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  10645.           if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
  10646.             ckstrncpy(line,tmpbuf,LINBUFSIZ);
  10647.           }
  10648.           if ((x = cmcfm()) < 0) return(x);
  10649.  
  10650. #ifndef SSHTEST
  10651.           x = sshkey_change_passphrase(line[0] ? line : NULL,
  10652.                          oldp, newp);
  10653. #endif /* SSHTEST */
  10654.           makestr(&oldp,NULL);
  10655.           makestr(&newp,NULL);
  10656.           success = (x == 0);
  10657.           return(success);
  10658.         }
  10659.         case SSHK_CREA: {    /* SSH KEY CREATE /switches... */
  10660.           int bits = 1024, keytype = SSHKT_2R;
  10661.           char * pass = NULL, * comment = NULL;
  10662.           struct FDB df, sw;
  10663.  
  10664.               /*
  10665.                * char * sshkey_default_file(int keytype) 
  10666.                * will provide the default filename for a given keytype
  10667.                * is it possible to have the default value for the 2nd
  10668.                * FDB set and changed when a /TYPE switch is provided?
  10669.                * Would this allow for tab completion of the filename?
  10670.                */
  10671.           cmfdbi(&sw,
  10672.              _CMKEY,        /* fcode */
  10673.              "Filename, or switch", /* hlpmsg */
  10674.              "",        /* default */
  10675.              "",        /* addtl string data */
  10676.              nsshkcrea,        /* addtl numeric data 1: tbl size */
  10677.              4,            /* addtl numeric data 2: 4 = cmswi */
  10678.              xxstring,        /* Processing function */
  10679.              sshkcrea,        /* Keyword table */
  10680.              &df        /* Pointer to next FDB */
  10681.              );
  10682.           cmfdbi(&df,        /* 2nd FDB - file for display */
  10683.              _CMOFI,        /* output file */
  10684.              "",        /* hlpmsg */
  10685.              "",        /* default */
  10686.              "",        /* addtl string data */
  10687.              0,            /* addtl numeric data 1 */
  10688.              0,            /* addtl numeric data 2 */
  10689.              xxstring,
  10690.              NULL,
  10691.              NULL
  10692.              );
  10693.           line[0] = NUL;
  10694.  
  10695.           while (1) {
  10696.           x = cmfdb(&sw);
  10697.           if (x == -3) break;
  10698.           if (x < 0)
  10699.             return(x);
  10700.           if (cmresult.fcode != _CMKEY)
  10701.             break;
  10702.           if (!cmgbrk()) {
  10703.               printf("?This switch requires an argument\n");
  10704.               return(-9);
  10705.           }
  10706.           switch (cmresult.nresult) {
  10707.             case SSHKC_BI:    /* /BITS:n */
  10708.               if ((y = cmnum("","1024",10,&z,xxstring)) < 0)
  10709.             return(y);
  10710.               if (z < 512 || z > 4096) {
  10711.               printf("?Out range - min: 512, max: 4096\n");
  10712.               return(-9);
  10713.               }
  10714.               bits = z;
  10715.               break;
  10716.             case SSHKC_PP:    /* /PASSPHRASE:blah */
  10717.               if ((y = cmfld("Passphrase","",&s,xxstring)) < 0)
  10718.             return(y);
  10719.               makestr(&pass,s);
  10720.               break;
  10721.             case SSHKC_TY:    /* /TYPE:keyword */
  10722.               if ((y = cmkey(sshkcty,nsshkcty,"",
  10723.                      "v2-rsa",xxstring)) < 0)
  10724.             return(y);
  10725.               keytype = y;
  10726.               break;
  10727.             case SSHKC_1R:    /* /COMMENT */
  10728.               if ((y = cmfld("Text","",&s,xxstring)) < 0)
  10729.             return(y);
  10730.               makestr(&comment,s);
  10731.               break;
  10732.           }
  10733.           }
  10734.           if (cmresult.fcode == _CMOFI) { /* Filename */
  10735.                   if (cmresult.sresult) {
  10736.                       ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  10737.                       if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
  10738.                           ckstrncpy(line,tmpbuf,LINBUFSIZ);
  10739.           }
  10740.           }
  10741.           if ((y = cmcfm()) < 0) /* Confirm */
  10742.         return(y);
  10743. #ifndef SSHTEST
  10744.           x = sshkey_create(line[0] ? line : NULL,
  10745.                 bits, pass, keytype, comment);
  10746.           if (pass)
  10747.         memset(pass,0,strlen(pass));
  10748. #endif /* SSHTEST */
  10749.           makestr(&pass,NULL);
  10750.           makestr(&comment,NULL);
  10751.           return(success = (x == 0));
  10752.         }
  10753.         case SSHK_DISP: {    /* SSH KEY DISPLAY /switches... */
  10754.           char c;
  10755.           int infmt = 0, outfmt = 0;
  10756.           struct FDB df, sw;
  10757.           cmfdbi(&sw,
  10758.              _CMKEY,        /* fcode */
  10759.              "Filename, or switch", /* hlpmsg */
  10760.              "",        /* default */
  10761.              "",        /* addtl string data */
  10762.              nsshdswi,        /* addtl numeric data 1: tbl size */
  10763.              4,            /* addtl numeric data 2: 4 = cmswi */
  10764.              xxstring,        /* Processing function */
  10765.              sshdswi,        /* Keyword table */
  10766.              &df        /* Pointer to next FDB */
  10767.              );
  10768.           cmfdbi(&df,        /* 2nd FDB - file for display */
  10769.              _CMIFI,        /* fcode */
  10770.              "",        /* hlpmsg */
  10771.              "",        /* default */
  10772.              "",        /* addtl string data */
  10773.              0,            /* addtl numeric data 1 */
  10774.              0,            /* addtl numeric data 2 */
  10775.              xxstring,
  10776.              NULL,
  10777.              NULL
  10778.              );
  10779.           line[0] = NUL;
  10780.  
  10781.           while (1) {
  10782.           x = cmfdb(&sw);
  10783.           if (x == -3) break;
  10784.           if (x < 0)
  10785.             return(x);
  10786.           if (cmresult.fcode != _CMKEY)
  10787.             break;
  10788.           if (!cmgbrk()) {
  10789.               printf("?This switch requires an argument\n");
  10790.               return(-9);
  10791.           }
  10792.           switch (cmresult.nresult) {
  10793. #ifdef COMMENT
  10794.             case SSHKD_IN:    /* /IN-FORMAT: */
  10795.               if ((y = cmkey(sshdifmt,nsshdifmt,
  10796.                      "","",xxstring)) < 0)
  10797.             return(y);
  10798.               infmt = y;
  10799.               break;
  10800. #endif /* COMMENT */
  10801.             case SSHKD_OUT:    /* /FORMAT: */
  10802.               if ((y = cmkey(sshdofmt,nsshdofmt,
  10803.                      "","",xxstring)) < 0)
  10804.             return(y);
  10805.               outfmt = y;
  10806.               break;
  10807.           }
  10808.           }
  10809.           if (cmresult.fcode == _CMIFI) { /* Filename */
  10810.           ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  10811.           if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
  10812.             ckstrncpy(line,tmpbuf,LINBUFSIZ);
  10813.           }
  10814. #ifdef COMMENT
  10815.           if (!line[0]) {
  10816.           printf("?Key filename required\n");
  10817.           return(-9);
  10818.           }
  10819. #endif /* COMMENT */
  10820.           if ((y = cmcfm()) < 0) /* Confirm */
  10821.         return(y);
  10822. #ifndef SSHTEST
  10823.           switch (outfmt) {
  10824.         case SKDF_OSSH:
  10825.                   /* 2nd param is optional passphrase */
  10826.           x = sshkey_display_public(line[0] ? line : NULL, NULL);
  10827.           break;
  10828.         case SKDF_SSHC:
  10829.                   /* 2nd param is optional passphrase */
  10830.           x = sshkey_display_public_as_ssh2(line[0] ? line : NULL,
  10831.                             NULL);
  10832.           break;
  10833.         case SKDF_IETF:
  10834.           x = sshkey_display_fingerprint(line[0] ? line : NULL, 1);
  10835.           break;
  10836.         case SKDF_FING:
  10837.           x = sshkey_display_fingerprint(line[0] ? line : NULL, 0);
  10838.           break;
  10839.           }
  10840. #endif /* SSHTEST */
  10841.           return(success = (x == 0));
  10842.         }
  10843.         case SSHK_V1:        /* SSH KEY V1 SET-COMMENT */
  10844.           if ((x = cmkey(sshkv1,1,"","set-comment", xxstring)) < 0)
  10845.         return(x);
  10846.           if (x != 1) return(-2);
  10847.           if ((x = cmifi("Key file name","",&s,&y,xxstring)) < 0) {
  10848.           if (x == -3) {
  10849.               printf("?Name of key file required\n");
  10850.               return(-9);
  10851.           }
  10852.           }
  10853.           ckstrncpy(line,s,LINBUFSIZ);
  10854.           if ((x = cmtxt("Comment text","",&s,xxstring)) < 0)
  10855.         return(x);
  10856. #ifndef SSHTEST
  10857.           x = sshkey_v1_change_comment(line,  /* filename */
  10858.                        s,     /* new comment */
  10859.                        NULL   /* passphrase */
  10860.                        );
  10861. #endif /* SSHTEST */
  10862.           success = (x == 0);
  10863.           return(success);
  10864.       }
  10865.       default:
  10866.         return(-2);
  10867.     }
  10868. #else  /* SSHBUILTIN */
  10869. #ifdef SSHCMD
  10870.     x = nettype;
  10871.     if ((y = setlin(XXSSH,0,1)) < 0) {
  10872.         if (errno)
  10873.           printf("?%s\n",ck_errstr());
  10874.             else
  10875. #ifdef COMMENT
  10876.         /* This isn't right either because it catches command editing */
  10877.           printf("?Sorry, pseudoterminal open failed\n");
  10878.             if (hints)
  10879.           printf("Hint: Try \"ssh -t %s\"\n",line);
  10880. #else
  10881.           return(y);
  10882. #endif /* COMMENT */
  10883.         nettype = x;        /* Failed, restore net type. */
  10884.         ttnproto = z;        /* and protocol */
  10885.         success = 0;
  10886.     }
  10887.     didsetlin++;
  10888.     netsave = x;
  10889.     return(y);
  10890. #endif /* SSHCMD */
  10891. #endif /* SSHBUILTIN */
  10892.     }
  10893. #endif /* ANYSSH */
  10894.  
  10895.     if (cx == XXRLOG) {            /* RLOGIN */
  10896. #ifdef RLOGCODE
  10897.     int x,z;
  10898. #ifdef OS2
  10899.     if (!tcp_avail) {
  10900.         printf("?Sorry, either TCP/IP is not available on this system or\n\
  10901. necessary DLLs did not load.  Use SHOW NETWORK to check network status.\n"
  10902.            );
  10903.         success = 0;
  10904.         return(-9);
  10905.     } else {
  10906. #endif /* OS2 */
  10907.         x = nettype;        /* Save net type in case of failure */
  10908.         z = ttnproto;        /* Save protocol in case of failure */
  10909.         nettype = NET_TCPB;
  10910.         ttnproto = NP_RLOGIN;
  10911.         if ((y = setlin(XYHOST,0,1)) <= 0) {
  10912.         nettype = x;        /* Failed, restore net type. */
  10913.         ttnproto = z;        /* and protocol */
  10914.         success = 0;
  10915.         }
  10916.         didsetlin++;
  10917. #ifdef OS2
  10918.     }
  10919. #endif /* OS2 */
  10920.     return(y);
  10921. #else
  10922.     printf("?Sorry, RLOGIN is not configured in this copy of C-Kermit.\n");
  10923.     return(-9);
  10924. #endif /* RLOGCODE */
  10925.     }
  10926. #endif /* NETCONN */
  10927. #endif /* NOLOCAL */
  10928.  
  10929. #ifndef NOXMIT
  10930.     if (cx == XXTRA) {            /* TRANSMIT */
  10931.     extern int xfrxla;
  10932.     int i, n, xpipe = 0, xbinary = 0, xxlate = 1, xxnowait = 0, getval;
  10933.     int xxecho = 0;
  10934.     int scan = 1;
  10935.     char c;
  10936.     struct FDB sf, sw, tx;        /* FDBs for parse functions */
  10937. #ifndef NOCSETS
  10938.     extern int tcs_transp;        /* Term charset is transparent */
  10939. #else
  10940.     int tcs_transp = 1;
  10941. #endif /* NOCSETS */
  10942.  
  10943. #ifdef COMMENT
  10944.     xbinary = binary;        /* Default text/binary mode */
  10945. #else
  10946.     xbinary = 0;            /* Default is text */
  10947. #endif /* COMMENT */
  10948.     xxecho = xmitx;
  10949.  
  10950.     cmfdbi(&sw,            /* First FDB - command switches */
  10951.            _CMKEY,            /* fcode */
  10952.            "Filename, or switch",    /* hlpmsg */
  10953.            "",            /* default */
  10954.            "",            /* addtl string data */
  10955.            nxmitsw,            /* addtl numeric data 1: tbl size */
  10956.            4,            /* addtl numeric data 2: 4 = cmswi */
  10957.            xxstring,        /* Processing function */
  10958.            xmitsw,            /* Keyword table */
  10959.            &sf            /* Pointer to next FDB */
  10960.            );
  10961.     cmfdbi(&sf,            /* 2nd FDB - file to send */
  10962.            _CMIFI,            /* fcode */
  10963.            "File to transmit",    /* hlpmsg */
  10964.            "",            /* default */
  10965.            "",            /* addtl string data */
  10966.            0,            /* addtl numeric data 1 */
  10967.            0,            /* addtl numeric data 2 */
  10968.            xxstring,
  10969.            NULL,
  10970. #ifdef PIPESEND
  10971.            &tx
  10972. #else
  10973.            NULL
  10974. #endif /* PIPESEND */
  10975.            );
  10976. #ifdef PIPESEND
  10977.         cmfdbi(&tx,
  10978.            _CMTXT,            /* fcode */
  10979.            "Command",        /* hlpmsg */
  10980.            "",            /* default */
  10981.            "",            /* addtl string data */
  10982.            0,            /* addtl numeric data 1 */
  10983.            0,            /* addtl numeric data 2 */
  10984.            xxstring,
  10985.            NULL,
  10986.            NULL
  10987.            );
  10988. #endif /* PIPESEND */
  10989.  
  10990.     while (1) {
  10991.         x = cmfdb(&sw);
  10992.         if (x < 0)
  10993.           return(x);
  10994.         if (cmresult.fcode != _CMKEY)
  10995.           break;
  10996.         c = cmgbrk();        /* Have switch, get break character */
  10997.         if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  10998.         printf("?This switch does not take an argument\n");
  10999.         return(-9);
  11000.         }
  11001.         if (!getval && (cmgkwflgs() & CM_ARG)) {
  11002.         printf("?This switch requires an argument\n");
  11003.         return(-9);
  11004.         }
  11005.         n = cmresult.nresult;    /* Numeric result = switch ID */
  11006.         switch (n) {        /* Process the switch */
  11007. #ifdef PIPESEND
  11008.           case XMI_CMD:        /* Transmit from a command */
  11009.         if (nopush) {
  11010.             printf("?Sorry, system command access is disabled\n");
  11011.             return(-9);
  11012.         }
  11013.         sw.hlpmsg = "Command, or switch"; /* Change help message */
  11014.         xpipe = 1;        /* (No way to undo this one) */
  11015.         break;
  11016. #endif /* PIPESEND */
  11017.  
  11018.           case XMI_BIN:        /* Binary */
  11019.         xbinary = 1;
  11020.         xxlate = 0;        /* Don't translate charsets */
  11021.         scan = 0;
  11022.         break;
  11023.  
  11024.           case XMI_TXT:        /* Text */
  11025.         xbinary = 0;
  11026.         xxlate = !tcs_transp;    /* Translate if TERM CHAR not TRANSP */
  11027.         scan = 0;
  11028.         break;
  11029.  
  11030.           case XMI_TRA:        /* Transparent text */
  11031.         xbinary = 0;
  11032.         xxlate = 0;        /* But don't translate charsets */
  11033.         scan = 0;
  11034.         break;
  11035.  
  11036. #ifdef COMMENT
  11037.           case XMI_VRB:        /* /VERBOSE */
  11038.           case XMI_QUI:        /* /QUIET */
  11039.         break;            /* (not implemented yet) */
  11040. #endif /* COMMENT */
  11041.  
  11042.           case XMI_NOW:        /* /NOWAIT */
  11043.         xxnowait = 1;
  11044.         break;
  11045.  
  11046.           case XMI_NOE:        /* /NOWAIT */
  11047.         xxecho = 0;
  11048.         break;
  11049.  
  11050.           default:
  11051.         return(-2);
  11052.         }
  11053.  
  11054.     }
  11055.     if (cmresult.fcode != _CMIFI && cmresult.fcode != _CMTXT)
  11056.       return(-2);
  11057.     ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Filename */
  11058.     if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
  11059.       ckstrncpy(line,tmpbuf,LINBUFSIZ);
  11060.     s = line;
  11061.     if ((y = cmcfm()) < 0)        /* Confirm */
  11062.       return(y);
  11063. #ifdef CK_APC
  11064.     if ((apcactive == APC_LOCAL) ||
  11065.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  11066.       return(success = 0);
  11067. #endif /* CK_APC */
  11068.     if (cmresult.nresult != 0) {
  11069.         printf("?Only a single file may be transmitted\n");
  11070.         return(-9);
  11071.     }
  11072. #ifdef PIPESEND
  11073.     if (xpipe) {
  11074.         s = brstrip(s);
  11075.         if (!*s) {
  11076.         printf("?Sorry, a command to send from is required\n");
  11077.         return(-9);
  11078.         }
  11079.         pipesend = 1;
  11080.     }
  11081. #endif /* PIPESEND */
  11082.  
  11083.     if (scan && (filepeek
  11084. #ifndef NOXFER
  11085.              || patterns
  11086. #endif /* NOXFER */
  11087.              )) {        /* If user didn't specify type */
  11088.         int k, x;                  /* scan the file to see */
  11089.         x = -1;
  11090.         k = scanfile(s,&x,nscanfile);
  11091.         if (k > 0) xbinary = (k == FT_BIN) ? XYFT_B : XYFT_T;
  11092.     }
  11093.     if (!xfrxla) xxlate = 0;
  11094.     success = transmit(s,
  11095.                (char) (xxnowait ? '\0' : (char)xmitp),
  11096.                xxlate,
  11097.                xbinary,
  11098.                xxecho
  11099.                );
  11100.     return(success);
  11101.     }
  11102. #endif /* NOXMIT */
  11103.  
  11104. #ifndef NOFRILLS
  11105.     if (cx == XXTYP  || cx == XXCAT || cx == XXMORE ||
  11106.     cx == XXHEAD || cx == XXTAIL) {
  11107.     int paging = 0, havename = 0, head = 0, width = 0, count = 0;
  11108.     char pfxbuf[64], * prefix = NULL;
  11109.     char outfile[CKMAXPATH+1];
  11110.     struct FDB sf, sw;
  11111.     char * pat = NULL;
  11112.     int incs = 0, outcs = 0, cset = -1, number = 0;
  11113. #ifdef UNICODE
  11114.         char * tocs = "";
  11115.     extern int fileorder;
  11116. #ifdef OS2
  11117. #ifndef NOCSETS
  11118.     extern int tcsr, tcsl;
  11119. #endif /* NOCSETS */
  11120. #endif /* OS2 */
  11121. #endif /* UNICODE */
  11122.  
  11123.     outfile[0] = NUL;
  11124.  
  11125.     if (cx == XXMORE)
  11126.       paging = 1;
  11127.     else if (cx == XXCAT)
  11128.       paging = 0;
  11129.     else
  11130.       paging = (typ_page < 0) ? xaskmore : typ_page;
  11131.     if (paging < 0)
  11132.       paging = saveask;
  11133.  
  11134.     if (cx == XXHEAD) {
  11135.         head = 10;
  11136.         cx = XXTYP;
  11137.     } else if (cx == XXTAIL) {
  11138.         head = -10;
  11139.         cx = XXTYP;
  11140.     }
  11141.  
  11142. #ifdef IKSD
  11143.     if (inserver && !ENABLED(en_typ)) {
  11144.         printf("?Sorry, TYPE command disabled\n");
  11145.         return(-9);
  11146.     }
  11147. #endif /* IKSD */
  11148.  
  11149.     cmfdbi(&sw,            /* 2nd FDB - optional /PAGE switch */
  11150.            _CMKEY,            /* fcode */
  11151.            "Filename or switch",    /* hlpmsg */
  11152.            "",            /* default */
  11153.            "",            /* addtl string data */
  11154.            ntypetab,        /* addtl numeric data 1: tbl size */
  11155.            4,            /* addtl numeric data 2: 4 = cmswi */
  11156.            xxstring,        /* Processing function */
  11157.            typetab,            /* Keyword table */
  11158.            &sf            /* Pointer to next FDB */
  11159.            );
  11160.     cmfdbi(&sf,            /* 1st FDB - file to type */
  11161.            _CMIFI,            /* fcode */
  11162.            "",            /* hlpmsg */
  11163.            "",            /* default */
  11164.            "",            /* addtl string data */
  11165.            0,            /* addtl numeric data 1 */
  11166.            0,            /* addtl numeric data 2 */
  11167.            xxstring,
  11168.            NULL,
  11169.            NULL
  11170.            );
  11171.  
  11172.     while (!havename) {
  11173.         x = cmfdb(&sw);        /* Parse something */
  11174.         debug(F101,"type cmfdb","",x);
  11175.         debug(F101,"type cmresult.fcode","",cmresult.fcode);
  11176.         debug(F101,"type cmresult.nresult","",cmresult.nresult);
  11177.         if (x < 0) {            /* Error */
  11178.         if (x == -3) {
  11179.             x = -9;
  11180.             printf("?Filename required\n");
  11181.         }
  11182.         return(x);
  11183.         } else if (cmresult.fcode == _CMKEY) {
  11184.         char c; int getval;
  11185.         c = cmgbrk();
  11186.         getval = (c == ':' || c == '=');
  11187.         if (getval && !(cmgkwflgs() & CM_ARG)) {
  11188.             printf("?This switch does not take an argument\n");
  11189.             return(-9);
  11190.         }
  11191. #ifdef COMMENT
  11192.         if (!getval && (cmgkwflgs() & CM_ARG)) {
  11193.             printf("?This switch requires an argument\n");
  11194.             /* Not if it has a default! */
  11195.             return(-9);
  11196.         }
  11197. #endif /* COMMENT */
  11198.         switch (cmresult.nresult) {
  11199. #ifdef CK_TTGWSIZ
  11200.           case TYP_PAG:
  11201.             paging = 1;
  11202.             break;
  11203.  
  11204.           case TYP_NOP:
  11205.             paging = 0;
  11206.             break;
  11207. #endif /* CK_TTGWSIZ */
  11208.  
  11209.           case TYP_COU:
  11210.             paging = 0;
  11211.             count = 1;
  11212.             break;
  11213.  
  11214.           case TYP_HEA:
  11215.           case TYP_TAI:
  11216.             y = 10;
  11217.             if (getval)
  11218.               if ((x = cmnum("Number of lines",
  11219.                      "10",10,&y,xxstring)) < 0)
  11220.             return(x);
  11221.             head = (cmresult.nresult == TYP_TAI) ? -y : y;
  11222.             break;
  11223.  
  11224.           case TYP_WID:
  11225.             y = typ_wid > -1 ? typ_wid : cmd_cols;
  11226.             if (getval)
  11227.               if ((x = cmnum("Column at which to truncate",
  11228.                      ckitoa(y),10,&y,xxstring)) < 0)
  11229.             return(x);
  11230.             width = y;
  11231.             break;
  11232.  
  11233.           case TYP_PAT:
  11234.             if (!getval && (cmgkwflgs() & CM_ARG)) {
  11235.             printf("?This switch requires an argument\n");
  11236.             return(-9);
  11237.             }
  11238.             if ((x = cmfld("pattern","",&s,xxstring)) < 0)
  11239.               return(x);
  11240.             ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  11241.             pat = tmpbuf;
  11242.             break;
  11243.  
  11244.           case TYP_PFX:
  11245.             if (!getval && (cmgkwflgs() & CM_ARG)) {
  11246.             printf("?This switch requires an argument\n");
  11247.             return(-9);
  11248.             }
  11249.             if ((x = cmfld("prefix for each line","",&s,xxstring)) < 0)
  11250.               return(x);
  11251.             if ((int)strlen(s) > 63) {
  11252.             printf("?Too long - 63 max\n");
  11253.             return(-9);
  11254.             }
  11255.             ckstrncpy(pfxbuf,s,64);
  11256.             prefix = brstrip(pfxbuf);
  11257.             number = 0;
  11258.             break;
  11259.  
  11260.           case TYP_NUM:        /* /NUMBER */
  11261.             number = 1;
  11262.             prefix = NULL;
  11263.             break;
  11264.  
  11265. #ifdef UNICODE
  11266.           case TYP_XPA:        /* /TRANSPARENT */
  11267.             incs = 0;
  11268.             cset = 0;
  11269.             outcs = -1;
  11270.             break;
  11271.  
  11272.           case TYP_XIN:        /* /CHARACTER-SET: */
  11273.             if (!getval && (cmgkwflgs() & CM_ARG)) {
  11274.             printf("?This switch requires an argument\n");
  11275.             return(-9);
  11276.             }
  11277.             if ((incs = cmkey(fcstab,nfilc,
  11278.                       "character-set name","",xxstring)) < 0) {
  11279.             if (incs == -3)    /* Note: No default */
  11280.               incs = -2;
  11281.             return(incs);
  11282.             }
  11283.             cset = incs;
  11284.             break;
  11285.  
  11286.           case TYP_XUT:        /* /TRANSLATE-TO: */
  11287.             if (!getval && (cmgkwflgs() & CM_ARG)) {
  11288.             printf("?This switch requires an argument\n");
  11289.             return(-9);
  11290.             }
  11291. #ifdef OS2
  11292.             if (!inserver && !k95stdout) {
  11293.             tocs = "ucs2";
  11294.             } else {
  11295. #ifdef CKOUNI
  11296.             tocs = rlookup(txrtab,ntxrtab,tcsl);
  11297. #else /* CKOUNI */
  11298.             extern struct keytab ttcstab[];
  11299.             extern int ntxrtab;
  11300.             tocs = rlookup(ttcstab,ntermc,tocs);
  11301.             if (!tocs)
  11302.               tocs = getdcset();
  11303. #endif /* CKOUNI */
  11304.                     }
  11305. #else /* OS2 */
  11306.             tocs = getdcset();
  11307. #endif /* OS2 */
  11308.             if ((outcs = cmkey(fcstab,nfilc,
  11309.                        "character-set",tocs,xxstring)) < 0)
  11310.               return(outcs);
  11311.             break;
  11312. #endif /* UNICODE */
  11313.           case TYP_OUT:
  11314.             if ((x = cmofi("File for result lines","",
  11315.                    &s,xxstring)) < 0)
  11316.               return(x);
  11317.             ckstrncpy(outfile,s,CKMAXPATH);
  11318.             break;
  11319.         }
  11320.         } else if (cmresult.fcode == _CMIFI)
  11321.           havename = 1;
  11322.         else
  11323.           return(-2);
  11324.     }
  11325.     if (havename) {
  11326.         ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  11327.         y = cmresult.nresult;
  11328.     } else {
  11329.         if ((x = cmifi("Filename","",&s,&y,xxstring)) < 0) {
  11330.         if (x == -3) {
  11331.             printf("?Name of an existing file required\n");
  11332.             return(-9);
  11333.         } else return(x);
  11334.         }
  11335.         ckstrncpy(line,s,LINBUFSIZ);
  11336.     }
  11337.     if (y != 0) {
  11338.         printf("?A single file please\n");
  11339.         return(-9);
  11340.     }
  11341.     if ((y = cmcfm()) < 0)        /* Confirm the command */
  11342.       return(y);
  11343.  
  11344. #ifdef UNICODE
  11345.     fileorder = -1;
  11346.     if (cset < 0 && filepeek) {    /* If no charset switches given */
  11347.         int k, x = -1;
  11348.         k = scanfile(line,&x,nscanfile); /* Call file analyzer */
  11349.         debug(F111,"type scanfile",line,k);
  11350.         debug(F101,"type scanfile flag","",x);
  11351.         switch(k) {
  11352.           case FT_UTF8:        /* which can detect UTF-8... */
  11353.         cset = 0;
  11354.         incs = FC_UTF8;
  11355.         break;
  11356.           case FT_UCS2:        /* and UCS-2... */
  11357.         cset = 0;
  11358.         incs = FC_UCS2;
  11359.         fileorder = x;        /* even if there is no BOM. */
  11360.         debug(F101,"type fileorder","",fileorder);
  11361.         break;
  11362.         }
  11363.     }
  11364. #ifdef OS2
  11365.         if (cset < 0) {            /* If input charset still not known */
  11366. #ifdef CKOUNI
  11367.             tocs = rlookup(txrtab,ntxrtab,tcsl);
  11368. #else /* CKOUNI */
  11369.             extern struct keytab ttcstab[];
  11370.             extern int ntxrtab;
  11371.             tocs = rlookup(ttcstab,ntermc,incs);
  11372.             if (!tocs)
  11373.           tocs = getdcset();
  11374. #endif /* CKOUNI */
  11375.             incs = lookup(fcstab,tocs,nfilc,&x);
  11376.         }
  11377. #endif /* OS2 */
  11378.  
  11379.         if (outcs == 0 && incs != 0) {    /* Supply default target charset */
  11380.         int x = 0;            /* if switch not given. */
  11381.         tocs = getdcset();
  11382.         outcs = lookup(fcstab,tocs,nfilc,&x);
  11383.     }
  11384. #else  /* !UNICODE */
  11385.     if (cset < 0) incs = outcs = 0;
  11386. #endif /* UNICODE */
  11387.  
  11388.     if (outfile[0] && paging)    /* This combination makes no sense */
  11389.       paging = 0;            /* so turn off paging */
  11390.  
  11391.     if (count) paging = -1;
  11392.     debug(F111,"type",line,paging);
  11393.     s = outfile;
  11394.     success =
  11395.       dotype(line,paging,0,head,pat,width,prefix,incs,outcs,s,number);
  11396.     return(success);
  11397.     }
  11398. #endif /* NOFRILLS */
  11399.  
  11400. #ifndef NOCSETS
  11401.     if (cx == XXXLA) {            /* TRANSLATE file's charset */
  11402.     _PROTOTYP (int doxlate, ( void ) );
  11403.     return(doxlate());
  11404.     }
  11405. #endif /* NOCSETS */
  11406.  
  11407.     if (cx == XXVER) {            /* VERSION */
  11408.     int n = 0;
  11409.     extern char * ck_patch, * ck_s_test;
  11410. #ifdef COMMENT
  11411.     extern int hmtopline;
  11412. #endif /* COMMENT */
  11413.     if ((y = cmcfm()) < 0)
  11414.           return(y);
  11415.  
  11416.     printf("\n%s, for%s\n Numeric: %ld",versio,ckxsys,vernum);
  11417.     printf("\n");
  11418.     n = 3;
  11419.     if (*ck_s_test) {
  11420.         printf("\n THIS IS A TEST VERSION, NOT FOR PRODUCTION USE.\n");
  11421.         n += 2;
  11422.     }
  11423.     if (*ck_patch) {
  11424.         printf(" Patches: %s\n", ck_patch);
  11425.         n++;
  11426.     }
  11427.     printf(" Type COPYRIGHT for copyright information.\n\n");
  11428. #ifdef OS2
  11429.     shoreg();
  11430. #else
  11431. #ifdef COMMENT
  11432.     hmtopline = n+1;
  11433.     hmsga(copyright);
  11434.     hmtopline = 0;
  11435. #endif /* COMMENT */
  11436. #endif /* OS2 */
  11437.     return(success = 1);
  11438.     }
  11439.  
  11440.     if (cx == XXCPR) {            /* COPYRIGHT or LICENSE */
  11441.     if ((y = cmcfm()) < 0)
  11442.           return(y);
  11443. #ifdef OS2
  11444.     if (inserver) {            /* Free WIKSD */
  11445.         extern char * wiksdcpr[];
  11446.         hmsga(wiksdcpr);
  11447.     } else
  11448. #endif /* OS2 */
  11449.       hmsga(copyright);
  11450.     return(success = 1);
  11451.     }
  11452.  
  11453. #ifndef MAC                /* Only for multiuser systems */
  11454. #ifndef OS2
  11455. #ifndef NOFRILLS
  11456.     if (cx == XXWHO) {            /* WHO */
  11457.     char *wc;
  11458. #ifdef IKSD
  11459.     if (inserver && !ENABLED(en_who)) {
  11460.         printf("?Sorry, WHO command disabled\n");
  11461.         return(-9);
  11462.     }
  11463. #endif /* IKSD */
  11464. #ifdef datageneral
  11465.     if ((z = cmcfm()) < 0) return(z);
  11466.     if (nopush) {
  11467.         printf("?Sorry, who not allowed\n");
  11468.         return(success = 0);
  11469.     }
  11470.         xsystem(WHOCMD);
  11471. #else
  11472.     if ((y = cmtxt("user name","",&s,xxstring)) < 0) return(y);
  11473.         if (nopush) {
  11474.         printf("?Sorry, WHO command disabled\n");
  11475.         return(success = 0);
  11476.     }
  11477.     if (!(wc = getenv("CK_WHO"))) wc = WHOCMD;
  11478.     if (wc)
  11479.       if ((int) strlen(wc) > 0) {
  11480.           ckmakmsg(line,LINBUFSIZ,wc," ",s,NULL);
  11481.           xsystem(line);
  11482.       }
  11483. #endif /* datageneral */
  11484.     return(success = 1);
  11485.     }
  11486. #endif /* NOFRILLS */
  11487. #endif /* OS2 */
  11488. #endif /* MAC */
  11489.  
  11490. #ifndef NOFRILLS
  11491.     if (cx == XXWRI || cx == XXWRL || cx == XXWRBL) { /* WRITE */
  11492.     int x,y;            /* On stack in case of \fexec() */
  11493.     if ((x = cmkey(writab,nwri,"to file or log","",xxstring)) < 0) {
  11494.         if (x == -3) printf("?Write to what?\n");
  11495.         return(x);
  11496.     }
  11497.     if ((y = cmtxt("text","",&s,xxstring)) < 0) return(y);
  11498.     s = brstrip(s);
  11499.     switch (x) {
  11500.       case LOGD: y = ZDFILE; break;
  11501.       case LOGP: y = ZPFILE; break;
  11502. #ifndef NOLOCAL
  11503.       case LOGS: y = ZSFILE; break;
  11504. #endif /* NOLOCAL */
  11505.       case LOGT: y = ZTFILE; break;
  11506. #ifndef NOSPL
  11507.       case LOGW: y = ZWFILE; break;
  11508. #endif /* NOSPL */
  11509.       case LOGX:            /* SCREEN (stdout) */
  11510.       case LOGE:            /* ERROR  (stderr) */
  11511.         if (x == LOGE) {
  11512.         debug(F110,
  11513.               (cx == XXWRL) ? "WRITELN ERROR" : "WRITE ERROR", s,0);
  11514.         fprintf(stderr,"%s%s",s,(cx == XXWRL) ? "\n" : "");
  11515.         } else {
  11516.         debug(F110,
  11517.               (cx == XXWRL) ? "WRITELN SCREEN" : "WRITE SCREEN", s,0);
  11518.         printf("%s%s",s,(cx == XXWRL) ? "\n" : "");
  11519.         }
  11520.         return(success = 1);
  11521.       default: return(-2);
  11522.     }
  11523.     if (chkfn(y) > 0) {
  11524.         x = (cx == XXWRI) ? zsout(y,s) : zsoutl(y,s);
  11525.         if (x < 0) printf("?Write error\n");
  11526.     } else {
  11527.         x = -1;
  11528.         printf("?File or log not open\n");
  11529.     }
  11530.     return(success = (x == 0) ? 1 : 0);
  11531.     }
  11532. #endif /* NOFRILLS */
  11533.  
  11534. #ifndef NOXFER
  11535.     if (cx == XXASC || cx == XXBIN) {
  11536.     if ((x = cmcfm()) < 0) return(x);
  11537. #ifdef NEWFTP
  11538.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  11539.       return(success = doftptyp((cx == XXASC) ? 0 : 1));
  11540. #endif /* NEWFTP */
  11541.     binary = (cx == XXASC) ? XYFT_T : XYFT_B;
  11542.     return(success = 1);
  11543.     }
  11544. #endif /* NOXFER */
  11545.  
  11546.     if (cx == XXCLS) {
  11547.     if ((x = cmcfm()) < 0) return(x);
  11548.     y = ck_cls();
  11549.     return(success = (y > -1) ? 1 : 0);
  11550.     }
  11551.  
  11552. #ifdef CK_MKDIR
  11553.     if (cx == XXMKDIR || cx == XXLMKD) {
  11554.     char *p;
  11555. #ifdef LOCUS
  11556.     if (!locus && cx != XXLMKD) {
  11557. #ifdef NOXFER
  11558.         return(-2);
  11559. #else
  11560.         return(dormt(XZMKD));
  11561. #endif /* NOXFER */
  11562.         }
  11563. #endif /* LOCUS */
  11564. #ifdef IKSD
  11565.     if (inserver && !ENABLED(en_mkd)) {
  11566.         printf("?Sorry, directory creation is disabled\n");
  11567.         return(-9);
  11568.     }
  11569. #endif /* IKSD */
  11570.     if ((x = cmfld("Name for new directory","",&s,xxstring)) < 0) {
  11571.         if (x != -3) {
  11572.         return(x);
  11573.         } else {
  11574.         printf("?Directory name required\n");
  11575.         return(-9);
  11576.         }
  11577.     }
  11578.     ckstrncpy(line,s,LINBUFSIZ);
  11579.     s = line;
  11580.     if ((x = cmcfm()) < 0) return(x);
  11581.     s = brstrip(s);
  11582.     bgchk();            /* Set msgflg */
  11583.     x = ckmkdir(0,s,&p,msgflg,0);
  11584. #ifdef COMMENT
  11585.     if (msgflg && x == 0)
  11586.       printf("?Directory already exists\n");
  11587. #endif /* COMMENT */
  11588.     return(success = (x < 0) ? 0 : 1);
  11589.     }
  11590.     if (cx == XXRMDIR || cx == XXLRMD) { /* RMDIR */
  11591.     char *p;
  11592. #ifdef LOCUS
  11593.     if (!locus && cx != XXLRMD) {
  11594. #ifdef NOXFER
  11595.         return(-2);
  11596. #else
  11597.         return(dormt(XZRMD));
  11598. #endif /* NOXFER */
  11599.         }
  11600. #endif /* LOCUS */
  11601. #ifdef IKSD
  11602.     if (inserver && !ENABLED(en_rmd)) {
  11603.         printf("?Sorry, directory removal is disabled\n");
  11604.         return(-9);
  11605.     }
  11606. #endif /* IKSD */
  11607.     if ((x = cmdir("Name of directory to be removed","",&s,xxstring)) < 0)
  11608.       return(x);
  11609.     ckstrncpy(line,s,LINBUFSIZ);
  11610.     s = line;
  11611.     if ((x = cmcfm()) < 0) return(x);
  11612.     s = brstrip(s);
  11613.     x = ckmkdir(1,s,&p,msgflg,0);
  11614.     return(success = (x < 0) ? 0 : 1);
  11615.     }
  11616. #endif /* CK_MKDIR */
  11617.  
  11618. #ifdef TNCODE
  11619.     if (cx == XXTELOP)
  11620.       return(dotelopt());
  11621. #endif /* TNCODE */
  11622.  
  11623. #ifndef NOPUSH
  11624.     if (cx == XXNPSH) {
  11625.     if ((z = cmcfm()) < 0) return(z);
  11626.         nopush = 1;
  11627. #ifndef NOSERVER
  11628.         en_hos = 0;
  11629. #endif /* NOSERVER */
  11630. #ifdef PIPESEND
  11631.     usepipes = 0;
  11632. #endif /* PIPESEND */
  11633.         return(success = 1);
  11634.     }
  11635. #endif /* NOPUSH */
  11636.  
  11637. #ifdef OS2
  11638.     if (cx == XXNSCR) {
  11639.     if ((z = cmcfm()) < 0) return(z);
  11640.         tt_scroll = 0;
  11641.         return(success = 1);
  11642.     }
  11643. #endif /* OS2 */
  11644.  
  11645. #ifndef NOSPL
  11646.     if (cx == XXLOCAL)            /* LOCAL variable declarations */
  11647.       return(success = dolocal());
  11648. #endif /* NOSPL */
  11649.  
  11650.     if (cx == XXKERMI) {        /* The KERMIT command */
  11651.     char * list[65];
  11652.     extern char **xargv;
  11653.     extern int xargc;
  11654.     int i;
  11655.     if ((y = cmtxt("kermit command-line arguments, -h for help",
  11656.                "",&s,xxstring)) < 0)
  11657.       return(y);
  11658.     ckstrncpy(line,"kermit ",LINBUFSIZ);
  11659.     ckstrncat(line,s,LINBUFSIZ-8);
  11660.     xwords(line,64,list,0);
  11661.     for (i = 1; i < 64; i++) {
  11662.         if (!list[i])
  11663.           break;
  11664.     }
  11665.     i--;
  11666.     xargc = i;
  11667.     xargv = list;
  11668.     xargv++;
  11669.     sstate = cmdlin();
  11670.     if (sstate) {
  11671.         extern int justone;
  11672.         debug(F000,"KERMIT sstate","",sstate);
  11673.         justone = 1;        /* Force return to command mode */
  11674.         proto();            /* after protocol */
  11675.         return(success);
  11676.     } else {
  11677.         debug(F101,"KERMIT sstate","",sstate);
  11678.         return(success = 1);    /* Not exactly right, but... */
  11679.     }
  11680.     }
  11681.     if (cx == XXDATE) {            /* DATE command */
  11682.     extern char cmdatebuf[], * cmdatemsg;
  11683.  
  11684. #ifndef COMMENT
  11685.     char * dp;
  11686.     if ((y = cmtxt("date and/or time, or carriage return for current",
  11687.                "",&s,xxstring)) < 0)
  11688.       return(y);
  11689.     s = brstrip(s);
  11690.     dp = cmcvtdate(s,1);
  11691.     if (!dp) {
  11692.         printf("?%s\n",cmdatemsg ? cmdatemsg : "Date conversion error");
  11693.         success = 0;
  11694.     } else {
  11695.         printf("%s\n",dp);
  11696.         success = 1;
  11697.     }
  11698. #else
  11699.     /* This works fine but messes up my "dates" torture-test script */
  11700.  
  11701.     if ((x = cmdate("Date and/or time, or carriage return for current",
  11702.             "",&s,0,xxstring)) < 0) {
  11703.         return(x);
  11704.     } else {
  11705.         printf("%s\n",cmdatebuf);
  11706.         success = 1;
  11707.     }
  11708. #endif /* COMMENT */
  11709.     return(success);
  11710.     }
  11711. #ifndef NOPUSH
  11712. #ifndef NOFRILLS
  11713.     if (cx == XXEDIT)
  11714.       return(doedit());
  11715. #endif /* NOFRILLS */
  11716. #endif /* NOPUSH */
  11717.  
  11718. #ifdef BROWSER                /* Defined only ifndef NOPUSH */
  11719.     if (cx == XXBROWS)
  11720.       return(dobrowse());
  11721. #endif /* BROWSER */
  11722.  
  11723. #ifdef CK_TAPI
  11724.     if (cx == XXTAPI) {            /* Microsoft TAPI */
  11725.     return (success = dotapi());
  11726.     }
  11727. #endif /* CK_TAPI */
  11728.  
  11729. #ifndef NOXFER
  11730.     if (cx == XXWHERE) {
  11731.     extern char * rfspec, * sfspec, * srfspec, * rrfspec;
  11732.     if ((x = cmcfm()) < 0) return(x);
  11733.     printf("\nFile most recently...\n\n");
  11734.     printf("  Sent:       %s\n",   sfspec ? sfspec : "(none)");
  11735.     if (sfspec && srfspec) {
  11736.         printf("  Stored as:  %s\n",   srfspec);
  11737.         printf("\n");
  11738.     }
  11739.     printf("  Received:   %s\n",   rrfspec ? rrfspec : "(none)");
  11740.     if (rfspec && rrfspec)
  11741.     printf("  Stored as:  %s\n",   rfspec);
  11742.     printf(
  11743. "\nIf the full path is not shown, then the file is probably in your current\n"
  11744.            );
  11745.     printf(
  11746. "directory or your download directory (if any - SHOW FILE to find out).\n\n"
  11747.            );
  11748.     return(success = 1);
  11749.     }
  11750. #endif /* NOXFER */
  11751.  
  11752. #ifdef CK_RECALL
  11753.     if (cx == XXREDO)
  11754.       return(doredo());
  11755. #endif /* CK_RECALL */
  11756.  
  11757. #ifdef CKROOT
  11758.     if (cx == XXCHRT)            /* Change Kermit's root directory */
  11759.       return(dochroot());
  11760. #endif /* CKROOT */
  11761.  
  11762. #ifdef CK_KERBEROS
  11763.     if (cx == XXAUTH) {            /* KERBEROS */
  11764.     x = cp_auth();            /* Parse it */
  11765. #ifdef IKSD
  11766.         if (inserver) {
  11767.             printf("?Command disabled in IKSD.\r\n");
  11768.             return(success = 0);
  11769.         }
  11770. #endif /* IKSD */
  11771.     if (x < 0)            /* Pass parse errors back */
  11772.       return(x);
  11773.     return(success = doauth(cx));
  11774.     }
  11775. #endif /* CK_KERBEROS */
  11776.  
  11777. #ifndef NOLOCAL
  11778.     if (cx == XXTERM) {
  11779.     return(settrmtyp());
  11780.     }
  11781. #endif /* NOLOCAL */
  11782.  
  11783.     if (cx == XXSTATUS) {
  11784.     if ((x = cmcfm()) < 0) return(x);
  11785.     printf( " %s\n", success ? "SUCCESS" : "FAILURE" );
  11786.     return(0);            /* Don't change it */
  11787.     }
  11788.  
  11789.     if (cx == XXFAIL) {
  11790.     if ((x = cmcfm()) < 0) return(x);
  11791.     return(success = 0);
  11792.     }
  11793.  
  11794.     if (cx == XXSUCC) {
  11795.     if ((x = cmcfm()) < 0) return(x);
  11796.     return(success = 1);
  11797.     }
  11798.  
  11799.     if (cx == XXNLCL) {
  11800.     extern int nolocal;
  11801.     if ((x = cmcfm()) < 0) return(x);
  11802.     nolocal = 1;
  11803.     return(success = 1);
  11804.     }
  11805.  
  11806. #ifndef NOXFER
  11807.     if (cx == XXRASG)            /* Shortcuts for REMOTE commands */
  11808.       return(dormt(XZASG));
  11809.     if (cx == XXRCWD)
  11810.       return(dormt(XZCWD));
  11811.     if (cx == XXRCPY)
  11812.       return(dormt(XZCPY));
  11813.     if (cx == XXRDEL)
  11814.       return(dormt(XZDEL));
  11815.     if (cx == XXRDIR)
  11816.       return(dormt(XZDIR));
  11817.     if (cx == XXRXIT)
  11818.       return(dormt(XZXIT));
  11819.     if (cx == XXRHLP)
  11820.       return(dormt(XZHLP));
  11821.     if (cx == XXRHOS)
  11822.       return(dormt(XZHOS));
  11823.     if (cx == XXRKER)
  11824.       return(dormt(XZKER));
  11825.     if (cx == XXRPWD)
  11826.       return(dormt(XZPWD));
  11827.     if (cx == XXRQUE)
  11828.       return(dormt(XZQUE));
  11829.     if (cx == XXRREN)
  11830.       return(dormt(XZREN));
  11831.     if (cx == XXRMKD)
  11832.       return(dormt(XZMKD));
  11833.     if (cx == XXRRMD)
  11834.       return(dormt(XZRMD));
  11835.     if (cx == XXRSET)
  11836.       return(dormt(XZSET));
  11837.     if (cx == XXRSPA)
  11838.       return(dormt(XZSPA));
  11839.     if (cx == XXRTYP)
  11840.       return(dormt(XZTYP));
  11841.     if (cx == XXRWHO)
  11842.       return(dormt(XZWHO));
  11843.     if (cx == XXRCDUP)
  11844.       return(dormt(XZCDU));
  11845.     if (cx == XXRPRI)
  11846.       return(dormt(XZPRI));
  11847. #endif /* NOXFER */
  11848.  
  11849.     if (cx == XXRESET) {        /* RESET */
  11850.     if ((x = cmcfm()) < 0)
  11851.       return(x);
  11852.     doclean(0);            /* Close all files */
  11853.     return(success = 1);
  11854.     }
  11855.  
  11856. #ifndef NOXFER
  11857. #ifndef NOCSETS
  11858.     if (cx == XXASSOC)            /* ASSOCIATE */
  11859.       return(doassoc());
  11860. #endif /* NOCSETS */
  11861. #endif /* NOXFER */
  11862.  
  11863. #ifndef NOSPL
  11864.     if (cx == XXSHIFT) {        /* SHIFT */
  11865.     if ((y = cmnum("Number of arguments to shift","1",10,&x,xxstring)) < 0)
  11866.       return(y);
  11867.     if ((z = cmcfm()) < 0)
  11868.       return(z);
  11869.     return(success = doshift(x));
  11870.     }
  11871. #endif /* NOSPL */
  11872.  
  11873. #ifndef NOHELP
  11874.     if (cx == XXMAN)
  11875.       return(domanual());
  11876. #endif /* NOHELP */
  11877.  
  11878. #ifndef NOSPL
  11879.     if (cx == XXSORT)            /* SORT an array */
  11880.       return(dosort());
  11881. #endif /* NOSPL */
  11882.  
  11883.     if (cx == XXPURGE) {
  11884. #ifdef IKSD
  11885.     if (inserver && (!ENABLED(en_del)
  11886. #ifdef CK_LOGIN
  11887.                           || isguest
  11888. #endif /* CK_LOGIN */
  11889.              )) {
  11890.         printf("?Sorry, DELETE is disabled\n");
  11891.         return(-9);
  11892.     }
  11893. #endif /* IKSD */
  11894. #ifdef CK_APC
  11895.     if ((apcactive == APC_LOCAL) ||
  11896.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  11897.       return(success = 0);
  11898. #endif /* CK_APC */
  11899. #ifdef CKPURGE
  11900.         return(dopurge());
  11901. #else
  11902. #ifdef VMS
  11903.     if ((x = cmtxt("optional switches followed by filespec",
  11904.                "",&s,xxstring)) < 0)
  11905.       return(x);
  11906.     if (nopush) {
  11907.         printf("?Sorry, DCL access is disabled\n");
  11908.         return(-9);
  11909.     }
  11910.     ckstrncpy(line,s,LINBUFSIZ);
  11911.     s = line;
  11912.     x = mlook(mactab,"purge",nmac);
  11913.     return(success = dodo(x,s,cmdstk[cmdlvl].ccflgs));
  11914. #else
  11915.     return(-2);
  11916. #endif /* VMS */
  11917. #endif /* CKPURGE */
  11918.     }
  11919.  
  11920. #ifndef NOSPL
  11921.     if (cx == XXFAST) {
  11922.     if ((x = cmcfm()) < 0) return(x);
  11923.     x = mlook(mactab,"fast",nmac);
  11924.     return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
  11925.     }
  11926.     if (cx == XXCAU) {
  11927.     if ((x = cmcfm()) < 0) return(x);
  11928.     x = mlook(mactab,"cautious",nmac);
  11929.     return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
  11930.     }
  11931.     if (cx == XXROB) {
  11932.     if ((x = cmcfm()) < 0) return(x);
  11933.     x = mlook(mactab,"robust",nmac);
  11934.     return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
  11935.     }
  11936. #endif /* NOSPL */
  11937.  
  11938.     if (cx == XXSCRN) {            /* SCREEN */
  11939.     int row, col;
  11940.     if ((x = cmkey(scntab, nscntab,"screen action","", xxstring)) < 0)
  11941.       return(x);
  11942.     switch (x) {            /* MOVE-TO (cursor position) */
  11943.       case SCN_MOV:
  11944.         if ((y = cmnum("Row (1-based)","",10,&z,xxstring)) < 0)
  11945.           return(y);
  11946.         row = z;
  11947.         y = cmnum("Column (1-based)","1",10,&z,xxstring);
  11948.         if (y < 0)
  11949.           return(y);
  11950.         col = z;
  11951.         if ((y = cmcfm()) < 0)
  11952.           return(y);
  11953.         if (row < 0 || col < 0) {
  11954.         printf("?Row and Column must be 1 or greater\n");
  11955.         return(-9);
  11956.         }
  11957.         if (cmd_rows > 0 && row > cmd_rows)
  11958.           row = cmd_rows;
  11959.         if (cmd_cols > 0 && col > cmd_cols)
  11960.           col = cmd_cols;
  11961.         y = ck_curpos(row,col);
  11962.         return(success = (y > -1) ? 1 : 0);
  11963.  
  11964.       case SCN_CLR:            /* CLEAR */
  11965.         if ((y = cmcfm()) < 0)
  11966.           return(y);
  11967.         debug(F100,"screen calling ck_cls()","",0);
  11968.         y = ck_cls();
  11969.         return(success = (y > -1) ? 1 : 0);
  11970.  
  11971.       case SCN_CLE:            /* CLEOL */
  11972.         if ((y = cmcfm()) < 0)
  11973.           return(y);
  11974.         y = ck_cleol();
  11975.         return(success = (y > -1) ? 1 : 0);
  11976.     }
  11977.     }
  11978.  
  11979. #ifndef NOHTTP
  11980. #ifdef TCPSOCKET
  11981.     if (cx == XXHTTP)
  11982.       return(dohttp());
  11983. #endif /* TCPSOCKET */
  11984. #endif /* NOHTTP */
  11985.  
  11986. #ifndef NOSPL
  11987.     if (cx == XXARRAY) {        /* ARRAY */
  11988. #ifndef NOSHOW
  11989.     extern int showarray();
  11990. #endif /* NOSHOW */
  11991.     if ((x = cmkey(arraytab, narraytab,"Array operation","",xxstring)) < 0)
  11992.       return(x);
  11993.     switch (x) {
  11994.       case ARR_DCL:
  11995.         return(dodcl(XXDCL));
  11996.       case ARR_SRT:
  11997.         return(dosort());
  11998. #ifndef NOSHOW
  11999.       case ARR_SHO:
  12000.         return(showarray());
  12001. #endif /* NOSHOW */
  12002.       case ARR_CPY:
  12003.         return(copyarray());
  12004.       case ARR_SET:
  12005.       case ARR_CLR:
  12006.         return(clrarray(x));
  12007.       case ARR_DST:
  12008.         return(unarray());
  12009.       case ARR_RSZ:
  12010.         return(rszarray());
  12011.       case ARR_EQU:
  12012.         return(linkarray());
  12013.  
  12014.       default:
  12015.         printf("?Sorry, not implemented yet - \"%s\"\n",cmdbuf);
  12016.         return(-9);
  12017.     }
  12018.     }
  12019.     if (cx == XXTRACE)
  12020.       return(dotrace());
  12021. #endif /* NOSPL */
  12022.  
  12023. #ifdef CK_PERMS
  12024. #ifdef UNIX
  12025.     if (cx == XXCHMOD)
  12026.       return(douchmod());        /* Do Unix chmod */
  12027. #endif /* UNIX */
  12028. #endif /* CK_PERMS */
  12029.  
  12030.     if (cx == XXPROMP)
  12031.       return(doprompt());
  12032.  
  12033.     if (cx == XXGREP)
  12034.       return(dogrep());
  12035.  
  12036.     if (cx == XXDEBUG) {        /* DEBUG */
  12037. #ifndef DEBUG
  12038.     int dummy = 0;
  12039.     return(seton(&dummy));
  12040. #else
  12041.     return(seton(&deblog));
  12042. #endif /* DEBUG */
  12043.     }
  12044.  
  12045. #ifdef CKLEARN
  12046.     if (cx == XXLEARN) {        /* LEARN */
  12047.     struct FDB of, sw, cm;
  12048.     int closing = 0, off = 0, on = 0, confirmed = 0;
  12049.     char c;
  12050.  
  12051.     cmfdbi(&sw,            /* 2nd FDB - optional /PAGE switch */
  12052.            _CMKEY,            /* fcode */
  12053.            "Script file name, or switch", /* hlpmsg */
  12054.            "",            /* default */
  12055.            "",            /* addtl string data */
  12056.            3,            /* addtl numeric data 1: tbl size */
  12057.            4,            /* addtl numeric data 2: 4 = cmswi */
  12058.            xxstring,        /* Processing function */
  12059.            learnswi,        /* Keyword table */
  12060.            &of            /* Pointer to next FDB */
  12061.            );
  12062.     cmfdbi(&of,_CMOFI,"","","",0,0,xxstring,NULL,&cm);
  12063.     cmfdbi(&cm,_CMCFM,"","","",0,0,NULL,NULL,NULL);
  12064.     line[0] = NUL;
  12065.  
  12066.     while (!confirmed) {
  12067.         x = cmfdb(&sw);        /* Parse something */
  12068.         if (x < 0)
  12069.           return(x);
  12070.         switch (cmresult.fcode) {    /* What was it? */
  12071.           case _CMOFI:        /* Output file name */
  12072.         ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  12073.         break;
  12074.           case _CMKEY:        /* Switch */
  12075.         c = cmgbrk();
  12076.         if ((c == ':' || c == '=') && !(cmgkwflgs() & CM_ARG)) {
  12077.             printf("?This switch does not take an argument\n");
  12078.             return(-9);
  12079.         }
  12080.         switch (cmresult.nresult) {
  12081.           case 2:        /* /CLOSE */
  12082.             closing = 1;    /* Fall thru on purpose */
  12083.           case 0:        /* /OFF */
  12084.             off = 1;
  12085.             on = 0;
  12086.             break;
  12087.           case 1:        /* /ON */
  12088.             on = 1;
  12089.             off = 0;
  12090.             break;
  12091.         }
  12092.         break;
  12093.           case _CMCFM:        /* Confirmation */
  12094.         confirmed++;
  12095.         break;
  12096.         }
  12097.     }
  12098.     if (closing) {
  12099.         if (learnfp) {
  12100.         fclose(learnfp);
  12101.         learnfp = NULL;
  12102.         }
  12103.         makestr(&learnfile,NULL);
  12104.     }
  12105.     if (line[0]) {
  12106.         if (!on && !off)
  12107.           on = 1;
  12108.         if (learnfp) {
  12109.         fclose(learnfp);
  12110.         learnfp = NULL;
  12111.         }
  12112.         makestr(&learnfile,line);
  12113.         if (learnfile) {
  12114.         char * modes = "w";
  12115.         learnfp = fopen(learnfile,modes);
  12116.         if (!learnfp) {
  12117.             debug(F110,"LEARN file open error",learnfile,0);
  12118.             perror(learnfile);
  12119.             return(-9);
  12120.         } else {
  12121. #ifdef ZFNQFP
  12122.             if (zfnqfp(learnfile,TMPBUFSIZ,tmpbuf))
  12123.               makestr(&learnfile,tmpbuf);
  12124. #endif /* ZFNQFP */
  12125.             debug(F110,"LEARN file open ok",learnfile,0);
  12126.             if (!quiet) {
  12127.             printf("Recording to %s...\n\n",learnfile);
  12128.             printf(
  12129. " WARNING: If you type your password during script recording, it will appear\n\
  12130.  in the file.  Be sure to edit it or take other appropriate precautions.\n\n"
  12131.                    );
  12132.             }
  12133.             fputs(  "; Scriptfile: ",learnfp);
  12134.             fputs(learnfile,learnfp);
  12135.             fputs("\n; Directory:  ",learnfp);
  12136.             fputs(zgtdir(),learnfp);
  12137.             fputs("\n; Recorded:   ",learnfp);
  12138.             fputs(ckdate(),learnfp);
  12139.             fputs("\n",learnfp);
  12140.         }
  12141.         }
  12142.     }
  12143.     if (on) {
  12144.         learning = 1;
  12145.     } else if (off) {
  12146.         learning = 0;
  12147.     }
  12148.     debug(F101,"LEARN learning","",learning);
  12149.     return(success = 1);
  12150.     }
  12151. #endif /* CKLEARN */
  12152.  
  12153. #ifdef NEWFTP
  12154.     if (cx == XXUSER || cx == XXACCT) {
  12155.     if (!ftpisopen()) {
  12156.         printf("?FTP connection is not open\n");
  12157.         return(-9);
  12158.     }
  12159.     return(success = (cx == XXUSER) ? doftpusr() : doftpacct());
  12160.     }
  12161.     if (cx == XXSITE || cx == XXPASV) {
  12162.     if (!ftpisopen()) {
  12163.         printf("?FTP connection is not open\n");
  12164.         return(-9);
  12165.     }
  12166.     return(success = (cx == XXSITE) ? doftpsite() : dosetftppsv());
  12167.     }
  12168. #endif /* NEWFTP */
  12169.  
  12170.     if (cx == XXORIE) {            /* ORIENTATION */
  12171.     extern char * myname;
  12172.     int i, y, n = 0;
  12173.         char * s, *p, vbuf[32];
  12174.     char * vars[16];       char * legend[16];
  12175.  
  12176.     if ((y = cmcfm()) < 0)
  12177.       return(y);
  12178.  
  12179.     printf("\nProgram name:\n  %s\n\n",myname);
  12180.     n += 4;
  12181.  
  12182. #ifdef NT
  12183.     vars[0] = "home";      legend[0] = "Your home directory";
  12184.     vars[1] = "directory"; legend[1] = "K95's current directory";
  12185.     vars[2] = "exedir";    legend[2] = "K95 Program directory";
  12186.     vars[3] = "inidir";    legend[3] = "K95 Initialization file directory";
  12187.     vars[4] = "startup";   legend[4] = "Current directory when started";
  12188.     
  12189.         vars[5] = "common";
  12190.         legend[5] = "K95 data for all users and K95SITE.INI file";
  12191.     
  12192.         vars[6] = "personal";  legend[6] = "Your personal data directory tree";
  12193.         vars[7] = "desktop";   legend[7] = "Your deskop directory tree";
  12194.     
  12195.         vars[8] = "appdata";
  12196.         legend[8] = "Your personal K95 data tree and K95CUSTOM.INI file";
  12197.     
  12198.         vars[9] = "download";  legend[9] = "Your K95 download directory";
  12199.         vars[10] = "tmpdir";   legend[10] = "Your TEMP directory";
  12200.     vars[11] = NULL;       legend[11] = NULL;
  12201.  
  12202.     for (i = 0; i < 16 && vars[i]; i++) {
  12203.         printf("%s:\n",legend[i]);
  12204.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12205.         ckmakmsg(vbuf,32,"\\v(",vars[i],")",NULL);
  12206.         printf("  Variable:   %s\n",vbuf);
  12207.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12208.         y = TMPBUFSIZ;
  12209.         s = tmpbuf;
  12210.         zzstring(vbuf,&s,&y);
  12211.         line[0] = NUL;
  12212.         ckGetLongPathName(tmpbuf,line,LINBUFSIZ);
  12213.         printf("  Long name:  %s\n",line);
  12214.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12215.         line[0] = NUL;
  12216.         GetShortPathName(tmpbuf,line,LINBUFSIZ);
  12217.         printf("  Short name: %s\n",line);
  12218.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12219.             printf("\n");
  12220.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12221.     }
  12222. #else  /* NT */
  12223.  
  12224.     vars[0] = "home";      legend[0] = "Your home directory";
  12225.     vars[1] = "directory"; legend[1] = "Kermit's current directory";
  12226.     vars[2] = "exedir";    legend[2] = "Kermit's program directory";
  12227.     vars[3] = "inidir";    legend[3] = "Initialization file directory";
  12228.     vars[4] = "startup";   legend[4] = "Current directory when started";
  12229.     vars[5] = "download";  legend[5] = "Kermit download directory";
  12230.     vars[6] = NULL;           legend[6] = NULL;
  12231.  
  12232.     for (i = 0; i < 16 && vars[i]; i++) {
  12233.         printf("%s:\n",legend[i]);
  12234.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12235.         ckmakmsg(vbuf,32,"\\v(",vars[i],")",NULL);
  12236.         printf("  Variable: %s\n",vbuf);
  12237.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12238.         y = TMPBUFSIZ;
  12239.         s = tmpbuf;
  12240.         zzstring(vbuf,&s,&y);
  12241.             printf("  Value:    %s\n",tmpbuf);
  12242.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12243.             printf("\n");
  12244.         if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
  12245.     }
  12246. #endif /* NT */
  12247.     return(success = 1);
  12248.     }
  12249.  
  12250. #ifdef NT
  12251.     if (cx == XXDIALER) {
  12252.         StartDialer();
  12253.         return(success = 1);
  12254.     }
  12255. #endif /* NT */
  12256.  
  12257.     if (cx == XXCONT) {            /* CONTINUE */
  12258.     if ((x = cmcfm()) < 0)
  12259.       return(x);
  12260.     if (!xcmdsrc) {            /* At prompt: continue script */
  12261.         if (cmdlvl > 0)
  12262.           popclvl();        /* Pop command level */
  12263.         return(success = 1);    /* always succeeds */
  12264. #ifndef NOSPL
  12265.     } else {            /* In script: whatever... */
  12266.         x = mlook(mactab,"continue",nmac);
  12267.         return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
  12268. #endif /* NOSPL */
  12269.     }
  12270.     }
  12271.  
  12272.     if (cx == XXNOTAV) {        /* Command in table not available */
  12273.     ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ);
  12274.     if ((x = cmtxt("Rest of command","",&s,NULL)) < 0)
  12275.       return(x);
  12276.     printf("Sorry, \"%s\" not configured in this version of Kermit.\n",
  12277.            tmpbuf
  12278.            );
  12279.     return(success = 0);
  12280.     }
  12281.     return(-2);                /* None of the above */
  12282.  
  12283. } /* end of docmd() */
  12284.  
  12285. #endif /* NOICP */
  12286.