home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / ckv200.zip / ckuusr.c < prev    next >
C/C++ Source or Header  |  2001-12-07  |  305KB  |  11,094 lines

  1. #include "ckcsym.h"
  2. char *userv = "User Interface 8.0.247, 10 Nov 2001";
  3.  
  4. /*  C K U U S R --  "User Interface" for C-Kermit (Part 1)  */
  5.  
  6. /*
  7.   Author: Frank da Cruz <fdc@columbia.edu>
  8.   Columbia University Academic Information Systems, New York City.
  9.  
  10.   Copyright (C) 1985, 2001,
  11.     Trustees of Columbia University in the City of New York.
  12.     All rights reserved.  See the C-Kermit COPYING.TXT file or the
  13.     copyright text in the ckcmai.c module for disclaimer and permissions.
  14. */
  15.  
  16. /*
  17.   Originally the entire user interface was in one module, ckuusr.c.  Over
  18.   the years it has been split into many modules: ckuus2.c, ckuus3.c, ...,
  19.   ckuus7.c.  ckuus2.c contains the HELP command parser and help-text strings;
  20.   ckuusy.c contains the UNIX-style command-line interface; ckuusx.c contains
  21.   routines needed by both the command-line interface and the interactive
  22.   command parser.
  23. */
  24.  
  25. /*
  26.   The ckuus*.c modules depend on the existence of C library features like
  27.   fopen, fgets, feof, (f)printf, argv/argc, etc.  Other functions that are
  28.   likely to vary among different platforms -- like setting terminal modes or
  29.   interrupts -- are invoked via calls to functions that are defined in the
  30.   system- dependent modules, ck?[ft]io.c.  The command line parser processes
  31.   any arguments found on the command line, as passed to main() via argv/argc.
  32.   The interactive parser uses the facilities of the cmd package (developed for
  33.   this program, but usable by any program).  Any command parser may be
  34.   substituted for this one.  The only requirements for the Kermit command
  35.   parser are these:
  36.  
  37.   . Set parameters via global variables like duplex, speed, ttname, etc.  See
  38.     ckmain.c for the declarations and descriptions of these variables.
  39.  
  40.   . If a command can be executed without the use of Kermit protocol, then
  41.     execute the command directly and set the variable sstate to 0. Examples
  42.     include 'set' commands, local directory listings, the 'connect' command.
  43.  
  44.   . If a command requires the Kermit protocol, set the following variables:
  45.  
  46.      sstate                             string data
  47.        'x' (enter server mode)            (none)
  48.        'r' (send a 'get' command)         cmarg, cmarg2
  49.        'v' (enter receive mode)           cmarg2
  50.        'g' (send a generic command)       cmarg
  51.        's' (send files)                   nfils, cmarg & cmarg2 OR cmlist
  52.        'c' (send a remote host command)   cmarg
  53.  
  54.      cmlist is an array of pointers to strings.
  55.      cmarg, cmarg2 are pointers to strings.
  56.      nfils is an integer.
  57.  
  58.      cmarg can be a filename string (possibly wild), or
  59.     a pointer to a prefabricated generic command string, or
  60.     a pointer to a host command string.
  61.      cmarg2 is an "as-name" - the name to send file(s) under, or
  62.     the name under which to store incoming file(s); must not be wild.
  63.     A null or empty value means to use the file's own name.
  64.      cmlist is a list of filenames, such as passed via argv.
  65.      nfils is an integer, interpreted as follows:
  66.        -1: filespec (possibly wild) in cmarg, must be expanded internally.
  67.     0: send from stdin (standard input).
  68.        >0: number of files to send, from cmlist.
  69.  
  70.   The screen() function is used to update the screen during file transfer.
  71.   The tlog() function writes to a transaction log.
  72.   The debug() function writes to a debugging log.
  73.   The intmsg() and chkint() functions provide the user i/o for interrupting
  74.     file transfers.
  75. */
  76.  
  77. /* Includes */
  78.  
  79. #ifdef MULTINET
  80. #define MULTINET_OLD_STYLE        /* Leave select prototype undefined */
  81. #endif /* MULTINET */
  82.  
  83. #include "ckcdeb.h"
  84. #include "ckcasc.h"
  85. #include "ckcker.h"
  86. #include "ckcnet.h"            /* Network symbols */
  87. #include "ckuusr.h"
  88. #include "ckcxla.h"
  89.  
  90. int g_fncact = -1;            /* Needed for NOICP builds */
  91. int noinit = 0;                /* Flag for skipping init file */
  92. int nscanfile = SCANFILEBUF;
  93.  
  94. #ifndef NOICP
  95. #ifdef CKLEARN
  96. #ifdef VMS
  97. #include <time.h>            /* For CKLEARN */
  98. #endif /* VMS */
  99. #endif /* CKLEARN */
  100. #ifdef OS2
  101. #ifndef NT
  102. #define INCL_NOPM
  103. #define INCL_VIO            /* Needed for ckocon.h */
  104. #include <os2.h>
  105. #undef COMMENT
  106. #else
  107. #define APIRET ULONG
  108. #include <windows.h>
  109. #include <tapi.h>
  110. #include "cknwin.h"
  111. #include "ckntap.h"            /* CK_TAPI definition */
  112. #endif /* NT */
  113. #include "ckowin.h"
  114. #include "ckocon.h"
  115. extern int tcp_avail;
  116. extern bool viewonly;
  117. extern int k95stdout;
  118. #ifndef NOTERM
  119. extern tt_status[VNUM];
  120. #endif /* NOTERM */
  121. int display_demo = 1;
  122. #include "ckossh.h"
  123. #endif /* OS2 */
  124.  
  125. int optlines = 0;
  126. int didsetlin = 0;
  127.  
  128. #ifdef NEWFTP
  129. extern int ftpget, ftpisopen(), ftpbye(), doftpres();
  130. _PROTOTYP(int doftptyp,(int));
  131. #endif /* NEWFTP */
  132.  
  133. #ifdef VMS
  134. extern int batch;
  135. #endif /* VMS */
  136.  
  137. #ifdef datageneral
  138. #include <packets:common.h>
  139. #define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd)
  140. #endif /* datageneral */
  141.  
  142. extern int xcmdsrc, hints, cmflgs, whyclosed;
  143.  
  144. char * hlptok = NULL;
  145.  
  146. #ifdef CK_TTGWSIZ            /* Whether to use more-prompting */
  147. int xaskmore = 1;            /* Momentary setting */
  148. int saveask  = 1;            /* Permanent setting */
  149. #else
  150. int xaskmore = 0;
  151. int saveask  = 0;
  152. #endif /* CK_TTGWSIZ */
  153.  
  154. #ifndef NOCSETS
  155. extern int nfilc;
  156. extern struct keytab fcstab[];
  157. extern int fcharset;
  158. #endif /* NOCSETS */
  159.  
  160. char * g_pswd = NULL;
  161. int g_pcpt = -1;
  162. int g_pflg = -1;
  163.  
  164. extern int cmd_rows, cmd_cols;
  165.  
  166. #ifdef CKROOT
  167. extern int ckrooterr;
  168. #endif /* CKROOT */
  169.  
  170. extern int inserver, filepeek;
  171.  
  172. #ifdef CKLEARN
  173. FILE * learnfp = NULL;
  174. char * learnfile = NULL;
  175. int learning = 0;
  176. #endif /* CKLEARN */
  177.  
  178. #ifndef NOXFER
  179. extern int atcapr, atdiso, nfils, moving, protocol, sendmode, epktflg, size,
  180.   sndsrc, server, displa, fncnv, fnspath, fnrpath, xfermode, urpsiz,
  181.   spsizf, spsiz, spsizr, spmax, wslotr, prefixing, fncact;
  182.  
  183. #ifdef IKSDCONF
  184. extern int iksdcf;
  185. #endif /* IKSDCONF */
  186.  
  187. #ifdef CK_LOGIN
  188. extern int isguest;
  189. #endif /* CK_LOGIN */
  190.  
  191. extern long sendstart;
  192.  
  193. extern char *cmarg, *cmarg2, **cmlist, *dftty;
  194.  
  195. extern struct keytab fntab[]; extern int nfntab;
  196. extern struct ck_p ptab[NPROTOS];
  197.  
  198. int sndcmd = 0;        /* Last command was a SEND-class command. */
  199.  
  200. int g_xfermode = -1;
  201. int g_proto  = -1;
  202. int g_urpsiz = -1;
  203. int g_spsizf = -1;
  204. int g_spsiz  = -1;
  205. int g_spsizr = -1;
  206. int g_spmax  = -1;
  207. int g_wslotr = -1;
  208. int g_prefixing = -1;
  209. int g_fncnv  = -1;
  210. int g_fnspath = -1;
  211. int g_fnrpath = -1;
  212. int g_fnact  = -1;
  213. int g_displa = -1;
  214. int g_spath  = -1;
  215. int g_rpath  = -1;
  216. char * g_sfilter = NULL;
  217. char * g_rfilter = NULL;
  218.  
  219. extern int patterns;
  220. #ifdef PATTERNS
  221. extern char *txtpatterns[], *binpatterns[];
  222. int g_patterns = -1;
  223. #endif /* PATTERNS */
  224. int g_skipbup = -1;
  225.  
  226. #ifdef PIPESEND
  227. extern int usepipes, pipesend;
  228. extern char * sndfilter;
  229. #endif /* PIPESEND */
  230.  
  231. #ifndef NOSPL
  232. extern int sndxlo, sndxhi, sndxin;
  233. #endif /* NOSPL */
  234.  
  235. extern char fspec[];            /* Most recent filespec */
  236. extern int fspeclen;            /* Length of fspec[] buffer */
  237.  
  238. #ifndef NOFRILLS
  239. extern int rmailf;            /* MAIL command items */
  240. extern char optbuf[];
  241. #endif /* NOFRILLS */
  242.  
  243. extern int
  244.   en_cpy, en_cwd, en_del, en_dir, en_fin, en_get, en_bye, en_mai, en_pri,
  245.   en_hos, en_ren, en_sen, en_spa, en_set, en_typ, en_who, en_ret, en_xit,
  246.   en_mkd, en_rmd, en_asg;
  247.  
  248. #ifndef NOMSEND                /* Multiple SEND */
  249. extern char *msfiles[];
  250. int filesinlist = 0;            /* And ADD ... */
  251. extern struct filelist * filehead;
  252. extern struct filelist * filetail;
  253. extern struct filelist * filenext;
  254. extern int addlist;
  255. #endif /* NOMSEND */
  256.  
  257. static struct keytab addtab[] = {
  258. #ifdef PATTERNS
  259.     { "binary-patterns", ADD_BIN, 0 },
  260. #endif /* PATTERNS */
  261. #ifndef NOMSEND
  262.     { "send-list", ADD_SND, 0 },
  263. #endif /* NOMSEND */
  264. #ifdef PATTERNS
  265.     { "text-patterns", ADD_TXT, 0 },
  266. #endif /* PATTERNS */
  267.     { "", 0, 0 }
  268. };
  269. static int naddtab = sizeof(addtab)/sizeof(struct keytab) - 1;
  270.  
  271. #ifndef NOCSETS
  272. struct keytab assoctab[] = {
  273.     { "file-character-set",     ASSOC_FC, 0 },
  274.     { "transfer-character-set", ASSOC_TC, 0 },
  275.     { "xfer-character-set",     ASSOC_TC, CM_INV }
  276. };
  277. static int nassoc = sizeof(assoctab)/sizeof(struct keytab);
  278. extern int afcset[MAXFCSETS+1];        /* Character-set associations */
  279. extern int axcset[MAXTCSETS+1];
  280. #endif /* NOCSETS */
  281.  
  282. #ifndef ADDCMD
  283. #ifndef NOMSEND
  284. #define ADDCMD
  285. #endif /* NOMSEND */
  286. #ifndef ADDCMD
  287. #ifdef PATTERNS
  288. #define ADDCMD
  289. #endif /* PATTERNS */
  290. #endif /* ADDCMD */
  291. #endif /* ADDCMD */
  292. #endif /* NOXFER */
  293.  
  294. /* External Kermit Variables, see ckmain.c for description. */
  295.  
  296. extern xx_strp xxstring;
  297. extern long xvernum;
  298.  
  299. extern int local, xitsta, binary, msgflg, escape, duplex, quiet, tlevel,
  300.   pflag, zincnt, ckxech, carrier, what, nopush, haveline, bye_active;
  301. #ifdef TNCODE
  302. extern int debses;
  303. extern char tn_msg[];
  304. #endif /* TNCODE */
  305.  
  306. int sleepcan = 1;
  307. int g_binary = -1;
  308. int g_recursive = -1;
  309. int g_matchdot = -1;
  310. extern int nolinks;
  311.  
  312. extern long vernum;
  313. extern char *versio, *copyright[];
  314. extern char *ckxsys;
  315. #ifndef NOHELP
  316. extern char *introtxt[];
  317. extern char *newstxt[];
  318. #endif /* NOHELP */
  319.  
  320. #ifndef OS2
  321. #ifndef UNIX
  322. extern char *PWDCMD;
  323. #endif /* UNIX */
  324. extern char *WHOCMD;
  325. #endif /* OS2 */
  326.  
  327. extern char ttname[];
  328.  
  329. extern CHAR sstate;
  330.  
  331. extern int network;            /* Have active network connection */
  332. #ifdef NETCONN
  333. extern int nettype;            /* Type of network */
  334. #endif /* NETCONN */
  335. extern int ttnproto;
  336.  
  337. #ifndef NODIAL
  338. extern int dialsta, dialatmo, dialcon, dialcq; /* DIAL status, etc. */
  339. #endif /* NODIAL */
  340.  
  341. #ifdef CK_APC
  342. extern int apcactive, apcstatus;
  343. #endif /* CK_APC */
  344.  
  345. #ifndef NOPUSH
  346. #ifndef NOFRILLS
  347. extern char editor[];
  348. extern char editopts[];
  349. extern char editfile[];
  350. #endif /* NOFRILLS */
  351. #endif /* NOPUSH */
  352.  
  353. #ifdef BROWSER
  354. extern char browser[];            /* Web browser application */
  355. extern char browsopts[];        /* Web browser options */
  356. extern char browsurl[];            /* Most recent URL */
  357. #endif /* BROWSER */
  358. #ifndef NOFTP
  359. char ftpapp[CKMAXPATH+1] = { NUL, NUL }; /* ftp executable */
  360. char ftpopts[128] = { NUL, NUL };    /* ftp command-line options */
  361. #endif /* NOFTP */
  362. extern struct keytab onoff[];        /* On/Off keyword table */
  363.  
  364. #ifdef CK_TMPDIR
  365. int f_tmpdir = 0;            /* Directory changed temporarily */
  366. char savdir[TMPDIRLEN];            /* For saving current directory */
  367. #endif /* CK_TMPDIR */
  368.  
  369. int activecmd = -1;            /* Keyword index of active command */
  370. int doconx = -1;            /* CONNECT-class command active */
  371. int ooflag = 0;                /* User-settable on/off flag */
  372.  
  373. int rcflag = 0;                /* Pointer to home directory string */
  374. int repars,                /* Reparse needed */
  375.     techo = 0;                /* Take echo */
  376. int secho = 1;                /* SCRIPT echo */
  377.  
  378. int xitwarn =            /* Warn about open connection on exit */
  379. #ifdef NOWARN
  380. 0
  381. #else
  382. 1
  383. #endif /* NOWARN */
  384. ;
  385.  
  386. struct keytab onoffsw[] = {
  387.     { "/off", 0, 0 },
  388.     { "/on",  1, 0 }
  389. };
  390.  
  391. #ifdef CKEXEC
  392. struct keytab redirsw[] = {
  393.     { "/redirect", 1, 0 }
  394. };
  395. #endif /* CKEXEC */
  396.  
  397. #ifndef NOXMIT
  398. /* Variables for TRANSMIT command */
  399.  
  400. int xmitx = 1;            /* Whether to echo during TRANSMIT */
  401. int xmitf = 0;            /* Character to fill empty lines */
  402. int xmitl = 0;            /* 0 = Don't send linefeed too */
  403. int xmitp = LF;            /* Host line prompt */
  404. int xmits = 0;            /* Use shift-in/shift-out, 0 = no */
  405. int xmitw = 0;            /* Milliseconds to pause during TRANSMIT */
  406. int xmitt = 1;            /* Seconds to wait for each char to echo */
  407. int xmita = 1;            /* Action upon timeout */
  408.  
  409. #define XMI_BIN 1
  410. #define XMI_TXT 2
  411. #define XMI_CMD 3
  412. #define XMI_TRA 4
  413. #define XMI_VRB 5
  414. #define XMI_QUI 6
  415. #define XMI_NOW 7
  416. #define XMI_NOE 8
  417.  
  418. static struct keytab xmitsw[] = {    /* TRANSMIT command options */
  419.     { "/binary",          XMI_BIN, 0 },
  420. #ifdef PIPESEND
  421.     { "/command",         XMI_CMD, CM_INV|CM_PSH },
  422. #endif /* PIPESEND */
  423.     { "/noecho",          XMI_NOE, 0 },
  424.     { "/nowait",          XMI_NOW, 0 },
  425. #ifdef PIPESEND
  426.     { "/pipe",            XMI_CMD, 0 },
  427. #endif /* PIPESEND */
  428. #ifdef COMMENT
  429.     { "/quiet",           XMI_QUI, 0 },
  430. #endif /* COMMENT */
  431.     { "/text",            XMI_TXT, 0 },
  432.     { "/transparent",     XMI_TRA, 0 },
  433. #ifdef COMMENT
  434.     { "/verbose",         XMI_VRB, 0 },
  435. #endif /* COMMENT */
  436.     { "", 0, 0 }
  437. };
  438. #define NXMITSW sizeof(xmitsw)/sizeof(struct keytab) - 1
  439. static int nxmitsw = NXMITSW;
  440.  
  441. #endif /* NOXMIT */
  442.  
  443. /* Declarations from ck?fio.c module */
  444.  
  445. extern char *SPACMD, *SPACM2;        /* SPACE commands */
  446.  
  447. /* Command-oriented items */
  448.  
  449. #ifdef DCMDBUF
  450. extern char *cmdbuf;            /* Command buffers */
  451. extern char *atmbuf;
  452. extern char *line;            /* Character buffer for anything */
  453. extern char *tmpbuf;            /* Short temporary string buffer */
  454. extern int *ifcmd;
  455. extern int *intime;
  456. extern int *inpcas;
  457. #else
  458. extern char cmdbuf[];            /* Command buffers */
  459. extern char atmbuf[];
  460. extern char line[];            /* Character buffer for anything */
  461. extern char tmpbuf[];            /* Temporary buffer */
  462. extern int ifcmd[];
  463. extern int intime[];
  464. extern int inpcas[];
  465. #endif /* DCMDBUF */
  466.  
  467. #ifndef NOSPL
  468. extern char * prstring[];
  469. #endif /* NOSPL */
  470.  
  471. char *lp;                /* Pointer to line buffer */
  472.  
  473. #ifndef NOSPL
  474. int unkmacro = 0;            /* Flag for in ON_UNKNOWN_COMMAND */
  475. int oldeval = 0;
  476. char evalbuf[33];            /* EVALUATE result */
  477. extern char * inpbuf;            /* Buffer for INPUT and REINPUT */
  478. char *inpbp;                /* And pointer to same */
  479. extern char lblbuf[];            /* Buffer for labels */
  480. int m_found;                /* MINPUT result */
  481. int i_active = 0;            /* INPUT command is active */
  482. char *ms[MINPMAX];            /* Pointers to MINPUT strings */
  483. static int mp[MINPMAX];            /* and flags */
  484. extern int fndiags, fnerror, fnsuccess;    /* Function diagnostics */
  485. #ifndef NOSEXP
  486. char * lastsexp = NULL;            /* S-Expressions */
  487. char * sexpval = NULL;
  488. int sexpecho = SET_AUTO;
  489. #endif /* NOSEXP */
  490. #endif /* NOSPL */
  491.  
  492. char psave[PROMPTL] = { NUL };        /* For saving & restoring prompt */
  493.  
  494. extern int success;            /* Command success/failure flag */
  495. extern int cmdlvl;            /* Current position in command stack */
  496.  
  497. #ifndef NOSPL
  498. int                    /* SET INPUT parameters. */
  499. /* Note, INPUT TIMEOUT, intime[], is on the command-level stack. */
  500.   inbufsize = 0,            /* INPUT buffer size */
  501.   indef = 1,                /* default timeout, seconds */
  502.   inecho = 1,                /* 1 = echo on */
  503.   inautodl = 0,                /* INPUT autodownload */
  504.   inintr = 1,                /* INPUT interrupion allowed */
  505.   insilence = 0;            /* 0 = no silence constraint */
  506. #ifdef OS2
  507. int interm = 1;                /* Terminal emulator displays input */
  508. #endif /* OS2 */
  509. int maclvl = -1;            /* Macro nesting level */
  510. int mecho = 0;                /* Macro echo, 0 = don't */
  511. char varnam[6];                /* For variable names */
  512. extern int macargc[];            /* ARGC from macro invocation */
  513.  
  514. extern char *m_arg[MACLEVEL][NARGS];    /* Stack of macro arguments */
  515. extern char *mrval[];
  516.  
  517. extern char **a_ptr[];            /* Array pointers */
  518. extern int a_dim[];            /* Array dimensions */
  519. extern int a_link[];
  520.  
  521. #ifdef DCMDBUF
  522. extern struct cmdptr *cmdstk;        /* The command stack itself */
  523. #else
  524. extern struct cmdptr cmdstk[];        /* The command stack itself */
  525. #endif /* DCMDBUF */
  526.  
  527. long ck_alarm = 0;            /* SET ALARM value */
  528. char alrm_date[24] = { ' ',' ',' ',' ',' ',' ',' ',' ',' ' };
  529. char alrm_time[24] = { ' ',' ',' ',' ',' ',' ',' ' };
  530.  
  531. #endif /* NOSPL */
  532.  
  533. static int x, y, z = 0;            /* Local workers */
  534. static char *s;
  535.  
  536. #define xsystem(s) zsyscmd(s)
  537.  
  538. /* Top-Level Interactive Command Keyword Table */
  539. /* Keywords must be in lowercase and in alphabetical order. */
  540.  
  541. struct keytab cmdtab[] = {
  542. #ifndef NOPUSH
  543.     { "!",       XXSHE, CM_INV|CM_PSH }, /* Shell escape */
  544. #else
  545.     { "!",       XXNOTAV, CM_INV|CM_PSH },
  546. #endif /* NOPUSH */
  547.     { "#",           XXCOM, CM_INV },    /* Comment */
  548. #ifndef NOSPL
  549.     { "(",           XXSEXP,CM_INV },    /* S-Expression */
  550.     { ".",           XXDEF, CM_INV },    /* Assignment */
  551.     { ":",           XXLBL, CM_INV },    /* Label */
  552. #endif /* NOSPL */
  553. #ifdef CK_REDIR
  554. #ifndef NOPUSH
  555.     { "<",           XXFUN, CM_INV|CM_PSH }, /* REDIRECT */
  556. #else
  557.     { "<",           XXNOTAV, CM_INV|CM_PSH }, /* REDIRECT */
  558. #endif /* NOPUSH */
  559. #endif /* CK_REDIR */
  560. #ifndef NOPUSH
  561.     { "@",           XXSHE, CM_INV|CM_PSH }, /* DCL escape */
  562. #else
  563.     { "@",           XXNOTAV, CM_INV|CM_PSH }, /* DCL escape */
  564. #endif /* NOPUSH */
  565.  
  566. #ifdef CK_RECALL
  567.     { "^",           XXREDO,CM_INV|CM_NOR }, /* Synonym for REDO */
  568. #endif /* CK_RECALL */
  569. #ifndef NOSPL
  570.     { "_asg",        XXASX,   CM_INV },    /* Used internally by FOR, etc */
  571.     { "_assign",     XXASX,   CM_INV },    /* Used internally by FOR, etc */
  572.     { "_decrement",  XX_DECR, CM_INV },
  573.     { "_define",     XXDFX,   CM_INV },    /* Used internally by FOR, etc */
  574.     { "_evaluate",   XX_EVAL, CM_INV },
  575.     { "_forward",    XXXFWD,  CM_INV },    /* Used internally by SWITCH   */
  576.     { "_getargs",    XXGTA,   CM_INV },    /* Used internally by FOR, etc */
  577.     { "_increment",  XX_INCR, CM_INV },
  578.     { "_putargs",    XXPTA,   CM_INV },    /* Used internally by FOR, etc */
  579.     { "_undefine",   XXUNDFX, CM_INV },
  580. #endif /* NOSPL */
  581.  
  582.     { "about",       XXVER, CM_INV },    /* Synonym for VERSION */
  583. #ifndef NOSPL
  584. #ifdef ADDCMD
  585.     { "add",         XXADD, 0 },    /* ADD */
  586. #endif /* ADDCMD */
  587. #ifndef NODIAL
  588.     { "answer",      XXANSW, CM_LOC },    /* ANSWER the phone */
  589. #else
  590.     { "answer",      XXNOTAV, CM_INV|CM_LOC }, /* ANSWER the phone */
  591. #endif /* NODIAL */
  592.     { "apc",         XXAPC, 0 },    /* Application Program Command */
  593. #ifndef NOSPL
  594.     { "array",       XXARRAY, 0 },    /* Array operations */
  595. #endif /* NOSPL */
  596.     { "ascii",       XXASC, CM_INV },    /* == SET FILE TYPE TEXT */
  597.     { "asg",         XXASS, CM_INV },    /* Invisible synonym for ASSIGN */
  598.     { "ask",         XXASK, 0 },    /* ASK for text, assign to variable */
  599.     { "askq",        XXASKQ,0 },    /* ASK quietly (no echo) */
  600. #ifndef NOSPL
  601.     { "ass",         XXASS, CM_INV|CM_ABR }, /* ASSIGN */
  602.     { "assert",      XXASSER, CM_INV },    /* ASSERT */
  603.     { "assign",      XXASS, 0 },    /* ASSIGN */
  604. #endif /* NOSPL */
  605. #ifndef NOXFER
  606. #ifndef NOCSETS
  607.     { "associate",   XXASSOC, 0 },    /* ASSOCIATE */
  608. #else
  609.     { "associate",   XXNOTAV, CM_INV },    /* ASSOCIATE */
  610. #endif /* NOCSETS */
  611. #endif /* NOXFER */
  612. #ifdef CK_KERBEROS
  613. #ifdef CK_AUTHENTICATION
  614.     { "authenticate",XXAUTH, 0 },    /* Authentication */
  615. #else
  616.     { "authenticate",XXAUTH, CM_INV },
  617. #endif /* CK_AUTHENTICATION */
  618. #endif /* CK_KERBEROS */
  619. #endif /* NOSPL */
  620. #ifndef NOFRILLS
  621.     { "back",        XXBACK, 0 },    /* BACK to previous directory */
  622. #else
  623.     { "back",        XXNOTAV,CM_INV },
  624. #endif /* NOFRILLS */
  625.     { "beep",        XXBEEP,CM_INV },    /* BEEP */
  626. #ifndef NOXFER
  627.     { "binary",      XXBIN, CM_INV },    /* == SET FILE TYPE BINARY */
  628. #endif /* NOXFER */
  629. #ifndef NOFRILLS
  630.     { "bug",         XXBUG, CM_INV },    /* BUG report instructions */
  631. #else
  632.     { "bug",         XXNOTAV, CM_INV },
  633. #endif /* NOFRILLS */
  634. #ifdef BROWSER
  635.     { "browse",      XXBROWS, CM_PSH|CM_LOC }, /* BROWSE (start browser) */
  636. #else
  637.     { "browse",      XXNOTAV, CM_INV|CM_PSH|CM_LOC },
  638. #endif /* BROWSER */
  639. #ifndef NOXFER
  640.     { "bye",         XXBYE, 0 },    /* BYE to remote server */
  641. #endif /* NOXFER */
  642. #ifndef NOLOCAL
  643.     { "c",           XXCON, CM_INV|CM_ABR|CM_LOC }, /* (CONNECT) */
  644. #endif /* NOLOCAL */
  645. #ifndef NOFRILLS
  646.     { "cat",         XXCAT, CM_INV },    /* Invisible synonym for TYPE */
  647. #endif /* NOFRILLS */
  648. #ifndef NOSPL
  649.  
  650. #ifndef NOXFER
  651.     { "cautious",    XXCAU, CM_INV },
  652. #endif /* NOXFER */
  653.  
  654. #endif /* NOSPL */
  655.  
  656.     { "cd",          XXCWD, 0 },    /* Change Directory */
  657.     { "cdup",        XXCDUP, CM_INV },    /* Change Directory Up */
  658.  
  659. #ifndef NOXFER
  660. #ifdef PIPESEND
  661.     { "cget",        XXCGET, CM_INV|CM_PSH }, /* CGET */
  662. #else
  663.     { "cget",        XXNOTAV, CM_INV|CM_PSH }, /* CGET */
  664. #endif /* PIPESEND */
  665. #endif /* NOXFER */
  666.     { "ch",          XXCHK,   CM_INV|CM_ABR },
  667.     { "check",       XXCHK,   0 },    /* CHECK for a feature */
  668. #ifdef CK_PERMS
  669. #ifdef UNIX
  670.     { "chmod",       XXCHMOD, 0 },    /* CHMOD */
  671. #else
  672.     { "chmod",       XXNOTAV, CM_INV },
  673. #endif /* UNIX */
  674. #else
  675.     { "chmod",       XXNOTAV, CM_INV },
  676. #endif /* CK_PERMS */
  677. #ifdef CKROOT
  678.     { "chroot",      XXCHRT,  CM_INV },    /* CHROOT */
  679. #endif /* CKROOT */
  680.     { "ckermit",     XXKERMI, CM_INV },    /* CKERMIT (like KERMIT) */
  681.     { "cl",          XXCLO,   CM_ABR|CM_INV },
  682. #ifndef NOFRILLS
  683.     { "clear",       XXCLE, 0 },    /* CLEAR input and/or device buffer */
  684. #else
  685.     { "clear",       XXNOTAV, CM_INV },
  686. #endif /* NOFRILLS */
  687.     { "close",         XXCLO, 0 },    /* CLOSE a log or other file */
  688.     { "cls",         XXCLS, CM_INV },    /* Clear Screen (CLS) */
  689.     { "comment",     XXCOM, CM_INV },    /* Introduce a comment */
  690. #ifndef NOLOCAL
  691.     { "connect",     XXCON, CM_LOC },    /* Begin terminal connection */
  692. #else
  693.     { "connect",     XXNOTAV, CM_LOC },
  694. #endif /* NOLOCAL */
  695. #ifndef NOFRILLS
  696. #ifdef ZCOPY
  697.     { "co",          XXCPY, CM_INV|CM_ABR },
  698.     { "cop",         XXCPY, CM_INV|CM_ABR },
  699.     { "copy",        XXCPY, 0 },    /* COPY a file */
  700. #else
  701.     { "copy",        XXNOTAV, CM_INV },
  702. #endif /* ZCOPY */
  703.     { "copyright",   XXCPR, CM_INV },    /* COPYRIGHT */
  704. #ifdef ZCOPY
  705.     { "cp",          XXCPY, CM_INV },    /* COPY a file */
  706. #endif /* ZCOPY */
  707. #ifndef NOLOCAL
  708. #ifndef OS2
  709.     { "cq",          XXCQ, CM_INV|CM_LOC }, /* CQ (connect quietly) */
  710. #endif /* OS2 */
  711. #endif /* NOLOCAL */
  712. #ifndef NOXFER
  713. #ifdef PIPESEND
  714.     { "creceive",    XXCREC,CM_INV|CM_PSH }, /* RECEIVE to a command */
  715.     { "csend",       XXCSEN,CM_INV|CM_PSH }, /* SEND from command */
  716. #else
  717.     { "creceive",    XXNOTAV,CM_INV|CM_PSH },
  718.     { "csend",       XXNOTAV,CM_INV|CM_PSH },
  719. #endif /* PIPESEND */
  720. #endif /* NOXFER */
  721. #endif /* NOFRILLS */
  722.  
  723.     { "cwd",         XXCWD,   CM_INV },    /* Traditional synonym for cd */
  724.  
  725. #ifndef NOSPL
  726.     { "date",        XXDATE,  0 },    /* DATE */
  727.     { "dcl",         XXDCL,   CM_INV },    /* DECLARE an array (see ARRAY) */
  728.     { "debug",       XXDEBUG, CM_INV },
  729.     { "declare",     XXDCL,   CM_INV },    /* DECLARE an array (see ARRAY) */
  730.     { "decrement",   XXDEC,   0 },    /* DECREMENT a numeric variable */
  731.     { "define",      XXDEF,   0 },    /* DEFINE a macro or variable */
  732. #else
  733.     { "date",        XXNOTAV, CM_INV },
  734.     { "dcl",         XXNOTAV, CM_INV },
  735.     { "declare",     XXNOTAV, CM_INV },
  736.     { "decrement",   XXNOTAV, CM_INV },
  737.     { "define",      XXNOTAV, CM_INV },
  738. #endif /* NOSPL */
  739.  
  740. #ifndef NOFRILLS
  741.     { "delete",      XXDEL, 0 },    /* DELETE a file */
  742. #else
  743.     { "delete",      XXNOTAV, CM_INV },
  744. #endif /* NOFRILLS */
  745.  
  746. #ifndef NODIAL
  747.     { "dial",        XXDIAL,  CM_LOC },    /* DIAL a phone number */
  748. #else
  749.     { "dial",        XXNOTAV, CM_INV|CM_LOC },
  750. #endif /* NODIAL */
  751.  
  752.     { "directory",   XXDIR, 0 },    /* DIRECTORY of files */
  753.     
  754. #ifndef NOFRILLS
  755. #ifndef NOSERVER
  756.     { "disable",     XXDIS, 0 },    /* DISABLE a server function */
  757. #else
  758.     { "disable",     XXNOTAV, CM_INV },
  759. #endif /* NOSERVER */
  760. #endif /* NOFRILLS */
  761.  
  762. #ifndef NOSPL
  763.     { "do",          XXDO,  0 },    /* DO (execute) a macro */
  764. #else
  765.     { "do",          XXNOTAV, CM_INV },
  766. #endif /* NOSPL */
  767.  
  768.     { "e",           XXEXI, CM_INV|CM_ABR },
  769.     
  770. #ifndef NOFRILLS
  771. #ifndef NOXFER
  772.     { "e-packet",    XXERR, CM_INV },    /* Send an Error-Packet */
  773. #endif /* NOXFER */
  774. #endif /* NOFRILLS */
  775.  
  776.     { "echo",        XXECH, 0 },    /* ECHO text */
  777.     
  778. #ifndef NOFRILLS
  779. #ifndef NOPUSH
  780.     { "edit",        XXEDIT, CM_PSH },    /* EDIT */
  781. #else
  782.     { "edit",        XXNOTAV, CM_INV|CM_PSH }, /* EDIT */
  783. #endif /* NOPUSH */
  784. #endif /* NOFRILLS */
  785.  
  786.     { "eightbit",    XXEIGHT, CM_INV },    /* EIGHTBIT */
  787.     
  788. #ifndef NOSPL
  789.     { "else",        XXELS, CM_INV },    /* ELSE part of IF statement */
  790. #else
  791.     { "else",        XXNOTAV, CM_INV },    /* ELSE part of IF statement */
  792. #endif /* NOSPL */
  793.  
  794. #ifndef NOSERVER
  795. #ifndef NOFRILLS
  796.     { "enable",      XXENA,  0 },    /* ENABLE a server function */
  797. #else
  798.     { "enable",      XXNOTAV, CM_INV },
  799. #endif /* NOFRILLS */
  800. #endif /* NOSERVER */
  801.  
  802. #ifndef NOSPL
  803.     { "end",         XXEND,  0 },    /* END command file or macro */
  804. #else
  805.     { "end",         XXNOTAV, CM_INV },
  806. #endif /* NOSPL */
  807.  
  808.     { "erase",       XXDEL, CM_INV },    /* Synonym for DELETE */
  809.  
  810. #ifndef NOSPL
  811.     { "evaluate",    XXEVAL, 0 },    /* EVALUATE */
  812. #else
  813.     { "evaluate",    XXNOTAV, CM_INV },
  814. #endif /* NOSPL */
  815.  
  816.     { "ex",          XXEXI, CM_INV|CM_ABR }, /* Let "ex" still be EXIT */
  817.  
  818. #ifdef CKEXEC
  819.     { "exec",        XXEXEC, CM_INV|CM_LOC }, /* exec() */
  820. #else
  821.     { "exec",        XXNOTAV, CM_INV|CM_LOC },
  822. #endif /* CKEXEC */
  823.  
  824.     { "exit",       XXEXI, 0 },        /* EXIT from C-Kermit */
  825.     { "extended-options", XXXOPTS,CM_INV|CM_HLP }, /* Extended-Options */
  826.  
  827. #ifdef OS2
  828.     { "extproc",     XXCOM, CM_INV },    /* Dummy command for OS/2 */
  829. #endif /* OS2 */
  830.  
  831. #ifndef NOXFER
  832.     { "f",           XXFIN, CM_INV|CM_ABR }, /* Invisible abbrev for FIN */
  833. #endif /* NOXFER */
  834.  
  835. #ifndef NOSPL
  836.     { "fail",        XXFAIL, CM_INV },    /* FAIL */
  837.     
  838. #ifndef NOXFER
  839.     { "fast",        XXFAST, CM_INV },
  840. #endif /* NOXFER */
  841.  
  842. #ifdef CKCHANNELIO
  843.     { "fclose",      XXF_CL, CM_INV },    /* FCLOSE */
  844.     { "fcount",      XXF_CO, CM_INV },    /* FCOUNT */
  845.     { "fflush",      XXF_FL, CM_INV },    /* FFLUSH */
  846. #endif /* CKCHANNELIO */
  847.  
  848. #ifndef NOXFER
  849.     { "fi",          XXFIN, CM_INV|CM_ABR }, /* FINISH */
  850. #endif /* NOXFER */
  851.  
  852. #ifdef CKCHANNELIO
  853.     { "file",        XXFILE, 0 },    /* FILE */
  854. #endif /* CKCHANNELIO */
  855. #endif /* NOSPL */
  856.  
  857. #ifndef NOXFER
  858.     { "fin",         XXFIN, CM_INV|CM_ABR }, /* FINISH */
  859. #endif /* NOXFER */
  860.  
  861. #ifndef UNIXOROSK
  862.     { "find",        XXGREP, 0 },    /* FIND (grep) */
  863. #else
  864.     { "find",        XXGREP,CM_INV },
  865. #endif /* UNIXOROSK */
  866.  
  867. #ifndef NOXFER
  868.     { "finish",      XXFIN, 0 },    /* FINISH */
  869. #endif /* NOXFER */
  870.  
  871. #ifdef TCPSOCKET
  872.     { "firewall",    XXFIREW, CM_INV|CM_HLP },
  873. #endif /* TCPSOCKET */
  874.  
  875. #ifdef CKCHANNELIO
  876.     { "flist",       XXF_LI, CM_INV },    /* FLIST */
  877.     { "fopen",       XXF_OP, CM_INV },    /* FOPEN */
  878. #endif /* CKCHANNELIO */
  879.  
  880. #ifndef NOSPL
  881.     { "fo",          XXFOR, CM_INV|CM_ABR }, /* Invisible abbrev for... */
  882.     { "for",         XXFOR, 0 },    /* FOR loop */
  883.     { "forward",     XXFWD, CM_INV },    /* FORWARD */
  884. #endif /* NOSPL */
  885. #ifndef NOFRILLS
  886.     { "fot",       XXDIR, CM_INV },    /* "fot" = "dir" (for Chris) */
  887. #endif /* NOFRILLS */
  888.  
  889. #ifdef CKCHANNELIO
  890.     { "fread",      XXF_RE, CM_INV },    /* FREAD */
  891.     { "frewind",    XXF_RW, CM_INV },    /* FREWIND */
  892.     { "fseek",      XXF_SE, CM_INV },    /* FSEEK */
  893.     { "fstatus",    XXF_ST, CM_INV },    /* FSTATUS */
  894. #endif /* CKCHANNELIO */
  895.  
  896. #ifdef TCPSOCKET
  897. #ifndef NOFTP
  898. #ifdef SYSFTP
  899. #ifndef NOPUSH
  900.     { "ftp",       XXFTP,   CM_INV|CM_PSH|CM_LOC }, /* System FTP */
  901. #else
  902.     { "ftp",       XXNOTAV, CM_INV|CM_PSH|CM_LOC },
  903. #endif /* NOPUSH */
  904. #else  /* SYSFTP */
  905.     { "ftp",       XXFTP,   0 },    /* Built-in FTP */
  906. #endif /* SYSFTP */
  907. #endif /* NOFTP */
  908. #endif /* TCPSOCKET */
  909.  
  910. #ifndef NOSPL
  911.     { "function",    XXFUNC, CM_INV|CM_HLP }, /* (for HELP FUNCTION) */
  912. #endif /* NOSPL */
  913.  
  914. #ifdef CKCHANNELIO
  915.     { "fwrite",      XXF_WR, CM_INV },    /* FWRITE */
  916. #endif /* CKCHANNELIO */
  917.  
  918. #ifndef NOXFER
  919.     { "g",           XXGET, CM_INV|CM_ABR }, /* Invisible abbrev for GET */
  920. #ifndef NOSPL
  921.     { "ge",          XXGET, CM_INV|CM_ABR }, /* Ditto */
  922. #endif /* NOSPL */
  923.     { "get",         XXGET, 0 },    /* GET */
  924. #endif /* NOXFER */
  925. #ifndef NOSPL
  926.     { "getc",        XXGETC, 0 },    /* GETC */
  927. #ifdef OS2
  928.     { "getkeycode",  XXGETK, 0 },    /* GETKEYCODE */
  929. #endif /* OS2 */
  930. #ifndef NOFRILLS
  931.     { "getok",       XXGOK, 0 },    /* GETOK (ask for Yes/No/OK) */
  932. #endif /* NOFRILLS */
  933. #endif /* NOSPL */
  934. #ifndef NOSPL
  935.     { "goto",        XXGOTO,0 },    /* GOTO label in take file or macro */
  936. #endif /* NOSPL */
  937. #ifdef UNIXOROSK
  938.     { "grep",        XXGREP,0 },    /* GREP (find) */
  939. #else
  940.     { "grep",        XXGREP,CM_INV },    /* GREP (find) */
  941. #endif /* UNIXOROSK */
  942.     { "h",           XXHLP, CM_INV|CM_ABR }, /* Invisible synonym for HELP */
  943.     { "he",          XXHLP, CM_INV|CM_ABR }, /* Invisible synonym for HELP */
  944. #ifndef NOFRILLS
  945.     { "head",        XXHEAD, 0 },
  946. #endif /* NOFRILLS */
  947. #ifndef NOLOCAL
  948.     { "hangup",      XXHAN, CM_LOC },    /* HANGUP the connection */
  949. #endif /* NOLOCAL */
  950.     { "HELP",        XXHLP, 0 },    /* Display HELP text */
  951. #ifndef NOHTTP
  952. #ifdef TCPSOCKET
  953.     { "http",        XXHTTP, 0 },    /* HTTP operations */
  954. #endif /* TCPSOCKET */
  955. #endif /* NOHTTP */
  956. #ifndef NOSPL
  957.     { "i",           XXINP, CM_INV|CM_ABR }, /* Invisible synonym for INPUT */
  958.     { "if",          XXIF,  0 },         /* IF ( condition ) command */
  959. #ifdef TCPSOCKET
  960.     { "iksd",        XXIKSD, CM_INV },         /* Make connection to IKSD */
  961. #else
  962.     { "iksd",        XXNOTAV, CM_INV },
  963. #endif /* TCPSOCKET */
  964.     { "in",          XXINP, CM_INV|CM_ABR }, /* Invisible synonym for INPUT */
  965.     { "increment",   XXINC, 0 },    /* Increment a numeric variable */
  966.     { "input",       XXINP, 0 },    /* INPUT text from comm device */
  967. #endif /* NOSPL */
  968.  
  969. #ifndef NOHELP
  970.     { "int",         XXINT, CM_INV|CM_ABR },
  971.     { "intr",        XXINT, CM_INV|CM_ABR },
  972.     { "INTRO",       XXINT, 0 },
  973.     { "introduction",XXINT, CM_INV },    /* Print introductory text */
  974. #else
  975.     { "intro",       XXNOTAV, CM_INV },
  976.     { "introduction",XXNOTAV, CM_INV },
  977. #endif /* NOHELP */
  978.  
  979. #ifdef OS2
  980.     { "k95",         XXKERMI, CM_INV },    /* Hmmm what's this... */
  981.     { "kermit",      XXKERMI, CM_INV },
  982. #else
  983.     { "kermit",      XXKERMI, CM_INV },
  984. #endif /* OS2 */
  985.  
  986. #ifdef OS2
  987. #ifndef NOKVERBS
  988.     { "kverb",       XXKVRB, CM_INV|CM_HLP }, /* Keyboard verb */
  989. #endif /* NOKVERBS */
  990. #endif /* OS2 */
  991.  
  992. #ifndef NOFRILLS
  993.     { "l",           XXLOG, CM_INV|CM_ABR }, /* Invisible synonym for log */
  994. #endif /* NOFRILLS */
  995.  
  996. #ifdef CKLEARN
  997.     { "learn",       XXLEARN, 0 },    /* LEARN - automatic script writing */
  998. #else
  999.     { "learn",       XXNOTAV, CM_INV },
  1000. #endif /* CKLEARN */
  1001.  
  1002.     { "li",          XXLNOUT, CM_INV|CM_ABR },
  1003.     { "LICENSE",     XXCPR, 0 },    /* LICENSE */
  1004.     
  1005. #ifndef NOSPL
  1006.     { "lineout",     XXLNOUT, 0 },    /* LINEOUT = OUTPUT + eol */
  1007. #endif /* NOSPL */
  1008.  
  1009. #ifndef NOFRILLS
  1010.     { "lo",          XXLOG, CM_INV|CM_ABR }, /* Invisible synonym for log */
  1011. #endif /* NOFRILLS */
  1012.  
  1013. #ifndef NOSPL
  1014.     { "local",       XXLOCAL, CM_INV },    /* LOCAL variable declaration */
  1015. #else
  1016.     { "local",       XXNOTAV, CM_INV },
  1017. #endif /* NOSPL */
  1018.  
  1019.     { "log",           XXLOG, 0 },    /* Open a log file */
  1020.     
  1021.     { "login",       XXLOGIN,  0 },    /* (REMOTE) LOGIN to server or IKSD */
  1022.     { "logout",      XXLOGOUT, 0 },    /* LOGOUT from server or IKSD */
  1023.     
  1024. #ifndef NOFRILLS
  1025. #ifndef NODIAL
  1026.     { "lookup",      XXLOOK,  0 },    /* LOOKUP */
  1027. #else
  1028.     { "lookup",      XXNOTAV, CM_INV },
  1029. #endif /* NODIAL */
  1030. #ifdef UNIXOROSK
  1031.     { "ls",          XXLS,  CM_INV|CM_PSH }, /* UNIX ls command */
  1032. #else
  1033.     { "ls",          XXDIR, CM_INV },    /* Invisible synonym for DIR */
  1034. #endif /* UNIXOROSK */
  1035. #ifndef NOXFER
  1036.     { "mail",        XXMAI, 0 },    /* Send a file as e-mail */
  1037. #endif /* NOXFER */
  1038. #ifndef NOHELP
  1039.     { "manual",      XXMAN, CM_PSH },    /* MAN(UAL) */
  1040. #else
  1041.     { "manual",      XXNOTAV, CM_INV|CM_PSH },
  1042. #endif /* NOHELP */
  1043. #endif /* NOFRILLS */
  1044. #ifdef CK_MKDIR
  1045.     { "md",          XXMKDIR, CM_INV },    /* Synonym for MKDIR */
  1046. #endif /* CK_MKDIR */
  1047. #ifdef CK_MINPUT
  1048.     { "minput",      XXMINP, 0 },    /* MINPUT */
  1049. #else
  1050.     { "minput",      XXNOTAV, CM_INV },
  1051. #endif /* CK_MINPUT */
  1052. #ifndef NOMSEND
  1053.     { "mget",        XXMGET, 0 },    /* MGET */
  1054. #else
  1055.     { "mget",        XXNOTAV, CM_INV },
  1056. #endif /* NOMSEND */
  1057. #ifdef CK_MKDIR
  1058.     { "mkdir",       XXMKDIR, 0 },    /* MKDIR */
  1059. #else
  1060.     { "mkdir",       XXNOTAV, CM_INV },
  1061. #endif /* CK_MKDIR */
  1062.  
  1063. #ifndef NOXFER
  1064. #ifndef NOMSEND
  1065.     { "mmove",       XXMMOVE, 0 },    /* MMOVE */
  1066. #else
  1067.     { "mmove",       XXNOTAV, CM_INV },
  1068. #endif /* NOMSEND */
  1069. #endif /* NOXFER */
  1070.  
  1071. #ifndef NOFRILLS
  1072.     { "more",        XXMORE, CM_INV },    /* MORE */
  1073. #endif /* NOFRILLS */
  1074.  
  1075. #ifndef NOXFER
  1076.     { "move",        XXMOVE, 0 },    /* MOVE  */
  1077. #endif /* NOXFER */
  1078.  
  1079. #ifndef NOSPL
  1080.     { "mpause",      XXMSL, CM_INV },    /* Millisecond sleep */
  1081. #else
  1082.     { "mpause",      XXNOTAV, CM_INV },
  1083. #endif /* NOSPL */
  1084.  
  1085. #ifndef NOXFER
  1086. #ifndef NOMSEND
  1087.     { "mput",        XXMSE, CM_INV },    /* MPUT = MSEND */
  1088.     { "ms",          XXMSE, CM_INV|CM_ABR },
  1089.     { "msend",       XXMSE, 0 },    /* Multiple SEND */
  1090. #else
  1091.     { "mput",        XXNOTAV, CM_INV },
  1092.     { "msend",       XXNOTAV, CM_INV },
  1093. #endif /* NOMSEND */
  1094. #endif /* NOXFER */
  1095. #ifndef NOSPL
  1096.     { "msleep",      XXMSL, 0 },    /* Millisecond sleep */
  1097. #else
  1098.     { "msleep",      XXNOTAV, CM_INV },
  1099. #endif /* NOSPL */
  1100. #ifndef NOFRILLS
  1101.     { "mv",          XXREN, CM_INV },    /* Synonym for rename */
  1102. #endif /* NOFRILLS */
  1103. #ifndef NOHELP
  1104.     { "news",        XXNEW, CM_INV },    /* Display NEWS of new features */
  1105. #else
  1106.     { "news",        XXNOTAV, CM_INV },
  1107. #endif /* NOHELP */
  1108.     { "nolocal",     XXNLCL, CM_INV },    /* Disable SET LINE / SET HOST */
  1109.     { "nopush",      XXNPSH, CM_INV },    /* Disable PUSH command/features */
  1110. #ifndef NOSPL
  1111.     { "o",           XXOUT, CM_INV|CM_ABR }, /* Invisible synonym for OUTPUT */
  1112.     { "open",        XXOPE, 0 },    /* OPEN file for reading or writing */
  1113. #else
  1114.     { "open",        XXNPSH, CM_INV },    /* Disable PUSH command/features */
  1115. #endif /* NOSPL */
  1116. #ifndef NOHELP
  1117.     { "options",     XXOPTS,CM_INV|CM_HLP }, /* Options */
  1118. #endif /* NOHELP */
  1119. #ifndef NOSPL
  1120.     { "output",      XXOUT, 0 },    /* OUTPUT text to comm device */
  1121. #else
  1122.     { "output",      XXNOTAV, CM_INV },
  1123. #endif /* NOSPL */
  1124. #ifdef ANYX25
  1125. #ifndef IBMX25
  1126.     { "pad",         XXPAD, CM_LOC },    /* X.3 PAD commands */
  1127. #endif /* IBMX25 */
  1128. #endif /* ANYX25 */
  1129.  
  1130. #ifndef NOHELP
  1131.     { "patterns",    XXPAT,CM_INV|CM_HLP }, /* Pattern syntax */
  1132. #endif /* NOHELP */
  1133.  
  1134. #ifndef NOSPL
  1135.     { "pause",       XXPAU, 0 },    /* Sleep for specified interval */
  1136. #else
  1137.     { "pause",       XXNOTAV, CM_INV },
  1138. #endif /* NOSPL */
  1139. #ifndef NODIAL
  1140.     { "pdial",       XXPDIA,  CM_LOC },    /* PDIAL (partial dial) */
  1141. #else
  1142.     { "pdial",       XXNOTAV, CM_INV|CM_LOC },
  1143. #endif /* NODIAL */
  1144. #ifdef TCPSOCKET
  1145. #ifndef NOPUSH
  1146.     { "ping",        XXPNG, CM_INV|CM_PSH|CM_LOC }, /* PING */
  1147. #else
  1148.     { "ping",        XXNOTAV, CM_INV|CM_PSH|CM_LOC },
  1149. #endif /* NOPUSH */
  1150. #endif /* TCPSOCKET */
  1151. #ifdef NETCMD
  1152. #ifndef NOPUSH
  1153.     { "pipe",        XXPIPE, CM_PSH },    /* PIPE */
  1154. #else
  1155.     { "pipe",        XXNOTAV, CM_INV|CM_PSH }, /* PIPE */
  1156. #endif /* NOPUSH */
  1157. #endif /* NETCMD */
  1158.  
  1159. #ifndef NOSPL
  1160.     { "pop",         XXEND, CM_INV },    /* Invisible synonym for END */
  1161. #endif /* NOSPL */
  1162. #ifndef NOFRILLS
  1163.     { "print",       XXPRI, 0 },    /* PRINT a file locally */
  1164. #endif /* NOFRILLS */
  1165.  
  1166.     { "prompt",      XXPROMP, CM_INV },    /* Go interactive (from script) */
  1167.     
  1168. #ifndef NOXFER
  1169. #ifdef CK_RESEND
  1170.     { "psend",       XXPSEN, CM_INV },    /* PSEND */
  1171. #else
  1172.     { "psend",       XXNOTAV, CM_INV },
  1173. #endif /* CK_RESEND */
  1174. #endif /* NOXFER */
  1175.  
  1176. #ifdef NETPTY
  1177.     { "pty",         XXPTY, CM_PSH },    /* PTY */
  1178. #else
  1179.     { "pty",         XXNOTAV, CM_INV|CM_PSH },
  1180. #endif /* NETPTY */
  1181.  
  1182. #ifndef NOPUSH
  1183.     { "pu",          XXSHE, CM_INV|CM_ABR|CM_PSH }, /* PU = PUSH */
  1184. #endif /* NOPUSH */
  1185.  
  1186. #ifdef CKPURGE
  1187.     { "purge",       XXPURGE, 0 },    /* PURGE (real) */
  1188. #else
  1189. #ifdef VMS
  1190.     { "purge",       XXPURGE, 0 },    /* PURGE (fake) */
  1191. #else
  1192.     { "purge",       XXNOTAV, CM_INV },
  1193. #endif /* VMS */
  1194. #endif /* CKPURGE */
  1195.  
  1196. #ifndef NOPUSH
  1197.     { "push",        XXSHE, CM_PSH },    /* PUSH command (like RUN, !) */
  1198. #else
  1199.     { "push",        XXNOTAV, CM_INV|CM_PSH },
  1200. #endif /* NOPUSH */
  1201.  
  1202. #ifndef NOXFER
  1203.     { "put",         XXSEN, CM_INV },    /* PUT = SEND */
  1204. #endif /* NOXFER */
  1205.  
  1206.     { "pwd",         XXPWD, 0 },    /* Print Working Directory */
  1207.     { "q",           XXQUI, CM_INV|CM_ABR }, /* Invisible synonym for QUIT */
  1208.     
  1209. #ifndef NOXFER
  1210.     { "query",       XXRQUE,CM_INV },    /* (= REMOTE QUERY) */
  1211. #endif /* NOXFER */
  1212.  
  1213.     { "quit",        XXQUI, 0 },    /* QUIT from program = EXIT */
  1214.     
  1215. #ifndef NOXFER
  1216.     { "r",           XXREC, CM_INV|CM_ABR }, /* Inv synonym for RECEIVE */
  1217. #endif /* NOXFER */
  1218.  
  1219. #ifndef NOXFER
  1220.     { "rasg",        XXRASG, CM_INV },    /* REMOTE ASSIGN */
  1221.     { "rassign",     XXRASG, CM_INV },    /* ditto */
  1222.     { "rcd",         XXRCWD, CM_INV },    /* REMOTE CD */
  1223.     { "rcdup",       XXRCDUP,CM_INV },    /* REMOTE CD */
  1224.     { "rcopy",       XXRCPY, CM_INV },    /* REMOTE COPY */
  1225.     { "rcwd",        XXRCWD, CM_INV },    /* REMOTE CWD */
  1226.     { "rdelete",     XXRDEL, CM_INV },    /* REMOTE DELETE */
  1227.     { "rdirectory",  XXRDIR, CM_INV },    /* REMODE DIRECTORY */
  1228. #endif /* NOXFER */
  1229.  
  1230. #ifndef NOSPL
  1231.     { "read",        XXREA, 0 },    /* READ a line from a file */
  1232. #else
  1233.     { "read",        XXNOTAV, CM_INV },
  1234. #endif /* NOSPL */
  1235.  
  1236. #ifndef NOXFER
  1237.     { "receive",     XXREC, 0 },    /* RECEIVE files */
  1238. #endif /* NOXFER */
  1239.  
  1240. #ifndef NODIAL
  1241.     { "red",         XXRED, CM_INV|CM_ABR|CM_LOC }, /* Inv syn for REDIAL */
  1242.     { "redi",        XXRED, CM_INV|CM_ABR|CM_LOC }, /* ditto */
  1243.     { "redial",      XXRED, CM_LOC },    /* REDIAL last DIAL number */
  1244. #else
  1245.     { "red",         XXNOTAV, CM_INV|CM_LOC },
  1246.     { "redi",        XXNOTAV, CM_INV|CM_LOC },
  1247.     { "redial",      XXNOTAV, CM_INV|CM_LOC },
  1248. #endif /* NODIAL */
  1249.  
  1250. #ifdef CK_REDIR
  1251. #ifdef OS2
  1252. #ifndef NOPUSH
  1253.     { "redirect",    XXFUN, CM_INV|CM_PSH }, /* REDIRECT */
  1254. #else
  1255.     { "redirect",    XXNOTAV, CM_INV|CM_PSH },
  1256. #endif /* NOPUSH */
  1257. #else /* OS2 */
  1258. #ifndef NOPUSH
  1259.     { "redirect",    XXFUN, CM_PSH },    /* REDIRECT */
  1260. #else
  1261.     { "redirect",    XXNOTAV, CM_INV|CM_PSH },
  1262. #endif /* NOPUSH */
  1263. #endif /* OS2 */
  1264. #endif /* CK_REDIR */
  1265.  
  1266. #ifdef CK_RECALL
  1267.     { "redo",        XXREDO,  CM_NOR },    /* REDO */
  1268. #else
  1269.     { "redo",        XXNOTAV, CM_INV },
  1270. #endif /* CK_RECALL */
  1271.  
  1272. #ifndef NOXFER
  1273. #ifdef CK_RESEND
  1274.     { "reget",       XXREGET, 0 },    /* REGET */
  1275. #else
  1276.     { "reget",       XXNOTAV, CM_INV },
  1277. #endif /* CK_RESEND */
  1278. #endif /* NOXFER */
  1279.  
  1280. #ifndef NOSPL
  1281.     { "reinput",     XXREI, CM_INV },    /* REINPUT (from INPUT buffer) */
  1282. #else
  1283.     { "reinput",     XXNOTAV, CM_INV },
  1284. #endif /* NOSPL */
  1285.  
  1286. #ifndef NOXFER
  1287. #ifdef ADDCMD
  1288.     { "rem",         XXREM, CM_INV|CM_ABR },
  1289.     { "remo",        XXREM, CM_INV|CM_ABR },
  1290. #endif /* ADDCMD */
  1291.     { "remote",         XXREM, 0 },    /* Send REMOTE command to server */
  1292. #endif /* NOXFER */
  1293.  
  1294. #ifdef ADDCMD
  1295.     { "remove",      XXREMV,0 },    /* REMOVE (something from a list) */
  1296. #else
  1297.     { "remove",      XXNOTAV, CM_INV },
  1298. #endif /* ADDCMD */
  1299.  
  1300. #ifndef NOFRILLS
  1301. #ifndef NORENAME
  1302.     { "rename",      XXREN, 0 },    /* RENAME a local file */
  1303. #else
  1304.     { "rename",      XXNOTAV, CM_INV },
  1305. #endif /* NORENAME */
  1306.     { "replay",      XXTYP, CM_INV },    /* REPLAY (for now, just type) */
  1307. #endif /* NOFRILLS */
  1308.  
  1309. #ifndef NOXFER
  1310. #ifdef CK_RESEND
  1311.     { "res",         XXRSEN, CM_INV|CM_ABR }, /* RESEND */
  1312.     { "rese",        XXRSEN, CM_INV|CM_ABR }, /* RESEND */
  1313.     { "resend",      XXRSEN, 0 },    /* RESEND */
  1314. #else
  1315.     { "res",         XXNOTAV, CM_INV },
  1316.     { "rese",        XXNOTAV, CM_INV },
  1317.     { "resend",      XXNOTAV, CM_INV },
  1318. #endif /* CK_RESEND */
  1319. #endif /* NOXFER */
  1320.  
  1321.     { "reset",       XXRESET, CM_INV },    /* RESET */
  1322.     
  1323. #ifdef CK_RESEND
  1324. #ifndef NOSPL
  1325.     { "ret",         XXRET, CM_INV|CM_ABR },
  1326. #endif /* NOSPL */
  1327. #endif /* CK_RESEND */
  1328.  
  1329. #ifndef NOXFER
  1330.     { "retrieve",    XXRETR, CM_INV },    /* RETRIEVE */
  1331. #endif /* NOXFER */
  1332.  
  1333. #ifndef NOSPL
  1334.     { "return",      XXRET, 0 },    /* RETURN from a function */
  1335. #else
  1336.     { "return",      XXNOTAV, CM_INV },
  1337. #endif /* NOSPL */
  1338.  
  1339. #ifndef NOXFER
  1340.     { "rexit",       XXRXIT, CM_INV },    /* REMOTE EXIT */
  1341. #endif /* NOXFER */
  1342.  
  1343. #ifdef CK_REXX
  1344. #ifndef NOPUSH
  1345.     { "rexx",        XXREXX, CM_PSH },    /* Execute a Rexx command */
  1346. #else
  1347.     { "rexx",        XXNOTAV, CM_INV|CM_PSH },
  1348. #endif /* NOPUSH */
  1349. #endif /* CK_REXX */
  1350.  
  1351. #ifndef NOXFER
  1352.     { "rhelp",       XXRHLP, CM_INV },    /* REMOTE HELP */
  1353.     { "rhost",       XXRHOS, CM_INV },    /* REMOTE HOST */
  1354.     { "rkermit",     XXRKER, CM_INV },    /* REMOTE KERMIT */
  1355. #endif /* NOXFER */
  1356.  
  1357. #ifdef TCPSOCKET
  1358.     { "rlogin",      XXRLOG, CM_LOC },    /* Make an Rlogin connection */
  1359. #else
  1360.     { "rlogin",      XXNOTAV, CM_INV|CM_LOC },
  1361. #endif /* TCPSOCKET */
  1362.  
  1363. #ifndef NOFRILLS
  1364.     { "rm",          XXDEL, CM_INV },    /* Invisible synonym for delete */
  1365. #endif /* NOFRILLS */
  1366.  
  1367. #ifdef CK_MKDIR
  1368.     { "rmdir",       XXRMDIR, 0 },    /* RMDIR */
  1369. #else
  1370.     { "rmdir",       XXNOTAV, CM_INV },
  1371. #endif /* CK_MKDIR */
  1372.  
  1373. #ifndef NOXFER
  1374.     { "rmkdir",      XXRMKD, CM_INV },    /* REMOTE MKDIR */
  1375. #ifndef NOSPL
  1376.     { "robust",      XXROB,  CM_INV },
  1377. #else
  1378.     { "robust",      XXNOTAV, CM_INV },
  1379. #endif /* NOSPL */
  1380.     { "rpwd",        XXRPWD, CM_INV },    /* REMOTE PWD */
  1381.     { "rquery",      XXRQUE, CM_INV },    /* REMOTE QUERY */
  1382. #endif /* NOXFER */
  1383.  
  1384. #ifdef CK_RECALL
  1385.     { "rr",          XXREDO, CM_INV|CM_NOR },
  1386. #endif /* CK_RECALL */
  1387.  
  1388. #ifndef NOXFER
  1389.     { "rrename",    XXRREN, CM_INV },    /* REMOTE RENAME */
  1390.     { "rrmdir",     XXRRMD, CM_INV },    /* REMOTE REMDIR */
  1391.     { "rset",       XXRSET, CM_INV },    /* REMOTE SET */
  1392.     { "rspace",     XXRSPA, CM_INV },    /* REMOTE SPACE */
  1393.     { "rtype",      XXRTYP, CM_INV },    /* REMOTE TYPE */
  1394. #endif /* NOXFER */
  1395.  
  1396. #ifndef NOPUSH
  1397.     { "run",         XXSHE, CM_PSH },    /* RUN a program or command */
  1398. #else
  1399.     { "run",         XXNOTAV, CM_INV|CM_PSH },
  1400. #endif /* NOPUSH */
  1401.  
  1402. #ifndef NOXFER
  1403.     { "rwho",        XXRWHO, CM_INV },    /* REMOTE WHO */
  1404.     { "s",           XXSEN, CM_INV|CM_ABR }, /* Invisible synonym for send */
  1405. #endif /* NOXFER */
  1406.  
  1407. #ifndef NOSETKEY
  1408. #ifdef OS2
  1409.     { "save",       XXSAVE, 0 },        /* SAVE something */
  1410. #else
  1411.     { "save",       XXSAVE, CM_INV },
  1412. #endif /* OS2 */
  1413. #else
  1414.     { "save",       XXNOTAV, CM_INV },
  1415. #endif /* NOSETKEY */
  1416.  
  1417. #ifndef NOSCRIPT
  1418.     { "sc",        XXLOGI, CM_INV|CM_ABR|CM_LOC },
  1419.     { "scr",       XXLOGI, CM_INV|CM_ABR|CM_LOC },
  1420. #endif /* NOSCRIPT */
  1421.     { "screen",      XXSCRN, 0 },    /* SCREEN actions */
  1422. #ifndef NOSCRIPT
  1423.     { "script",       XXLOGI, CM_LOC },    /* Expect-Send-style script line */
  1424. #else
  1425.     { "script",       XXNOTAV, CM_INV|CM_LOC },
  1426. #endif /* NOSCRIPT */
  1427.  
  1428.     { "search",    XXGREP,CM_INV },    /* Synonym for GREP and FIND */
  1429.     
  1430. #ifndef NOXFER
  1431.     { "send",       XXSEN, 0 },        /* Send (a) file(s) */
  1432. #ifndef NOSERVER
  1433.     { "server",       XXSER, 0 },        /* Be a SERVER */
  1434. #else
  1435.     { "server",       XXNOTAV, CM_INV },
  1436. #endif /* NOSERVER */
  1437. #endif /* NOXFER */
  1438.  
  1439.     { "set",       XXSET, 0 },        /* SET parameters */
  1440.     
  1441. #ifndef NOSPL
  1442. #ifndef NOSEXP
  1443.     { "sexpression", XXSEXP, CM_INV|CM_HLP }, /* SEXPR */
  1444. #endif /* NOSEXP */
  1445. #ifndef NOSHOW
  1446.     { "sh",          XXSHO, CM_INV|CM_ABR }, /* SHOW parameters */
  1447. #endif /* NOSHOW */
  1448.     { "shift",       XXSHIFT, 0 },    /* SHIFT args */
  1449. #else
  1450.     { "shift",       XXNOTAV, CM_INV },
  1451. #endif /* NOSPL */
  1452.  
  1453. #ifndef NOSHOW
  1454.     { "show",        XXSHO, 0 },        /* SHOW parameters */
  1455. #else
  1456.     { "show",        XXNOTAV, CM_INV },
  1457. #endif /* NOSHOW */
  1458.  
  1459. #ifndef NOSPL
  1460. #ifndef NOFRILLS
  1461.     { "sleep",       XXPAU, CM_INV },    /* SLEEP for specified interval */
  1462. #endif /* NOFRILLS */
  1463.     { "sort",        XXSORT, CM_INV },    /* (see ARRAY) */
  1464. #else
  1465.     { "sort",        XXNOTAV, CM_INV },
  1466. #endif /* NOSPL */
  1467.  
  1468. #ifndef MAC
  1469. #ifndef NOFRILLS
  1470.     { "sp",          XXSPA, CM_INV|CM_ABR },
  1471.     { "spa",         XXSPA, CM_INV|CM_ABR },
  1472. #endif /* NOFRILLS */
  1473.     { "space",       XXSPA, 0 },    /* Show available disk SPACE */
  1474. #endif /* MAC */
  1475.  
  1476. #ifndef NOFRILLS
  1477. #ifndef NOPUSH
  1478.     { "spawn",       XXSHE, CM_INV|CM_PSH }, /* Synonym for PUSH, RUN */
  1479. #else
  1480.     { "spawn",       XXNOTAV, CM_INV|CM_PSH }, /* Synonym for PUSH, RUN */
  1481. #endif /* NOPUSH */
  1482. #endif /* NOFRILLS */
  1483.  
  1484. #ifdef ANYSSH
  1485.     { "ssh",         XXSSH, 0 },
  1486. #endif /* ANYSSH */
  1487.  
  1488. #ifndef NOXFER
  1489.     { "sta",         XXSTA, CM_INV|CM_ABR },
  1490.     { "stat",        XXSTA, CM_INV|CM_ABR },
  1491.     { "statistics",  XXSTA, 0 },    /* Display file transfer stats */
  1492. #endif /* NOXFER */
  1493.  
  1494.     { "status",      XXSTATUS,0 },    /* Show status of previous command */
  1495.     
  1496. #ifndef NOSPL
  1497.     { "stop",        XXSTO,   0 },    /* STOP all take files and macros */
  1498.     { "succeed",     XXSUCC,  CM_INV },    /* SUCCEED */
  1499. #else
  1500.     { "stop",        XXNOTAV, CM_INV },
  1501.     { "succeed",     XXNOTAV, CM_INV },
  1502. #endif /* NOSPL */
  1503.  
  1504. #ifndef NOFRILLS
  1505.     { "SUPPORT",     XXBUG, 0 },    /* Tech support instructions */
  1506. #else
  1507.     { "support",     XXNOTAV, CM_INV },
  1508. #endif /* NOFRILLS */
  1509.  
  1510. #ifndef NOJC
  1511.     { "suspend",     XXSUS, CM_PSH },    /* SUSPEND C-Kermit (UNIX only) */
  1512. #else
  1513.     { "suspend",     XXNOTAV, CM_INV|CM_PSH },
  1514. #endif /* NOJC */
  1515.  
  1516. #ifndef NOSPL
  1517.     { "switch",      XXSWIT, 0 },    /* SWITCH */
  1518. #else
  1519.     { "switch",      XXNOTAV, CM_INV },
  1520. #endif /* NOSPL */
  1521.  
  1522. #ifdef CK_TAPI
  1523.     { "ta",       XXTAK, CM_INV|CM_ABR }, /* (because of TAPI) */
  1524. #endif /* CK_TAPI */
  1525.  
  1526. #ifndef NOFRILLS
  1527.     { "tail",        XXTAIL, 0 },    /* Display end of a local file */
  1528. #endif /* NOFRILLS */
  1529.  
  1530.     { "take",       XXTAK, 0 },        /* TAKE commands from a file */
  1531.     
  1532. #ifdef CK_TAPI
  1533.     { "tapi",       XXTAPI, CM_LOC },    /* Microsoft TAPI commands */
  1534. #else
  1535.     { "tapi",       XXNOTAV, CM_INV|CM_LOC },
  1536. #endif /* CK_TAPI */
  1537.  
  1538. #ifndef NOFRILLS
  1539. #ifdef TCPSOCKET
  1540.     { "tel",         XXTEL, CM_INV|CM_ABR|CM_LOC },
  1541.     { "telnet",      XXTEL, CM_LOC },    /* TELNET (TCP/IP only) */
  1542.     { "telopt",      XXTELOP, CM_INV },    /* TELOPT (ditto) */
  1543. #else
  1544.     { "tel",         XXNOTAV, CM_INV|CM_LOC },
  1545.     { "telnet",      XXNOTAV, CM_INV|CM_LOC },
  1546.     { "telopt",      XXNOTAV, CM_INV },
  1547. #endif /* TCPSOCKET */
  1548. #ifdef OS2
  1549.     { "terminal",    XXTERM, CM_INV|CM_LOC }, /* == SET TERMINAL TYPE */
  1550. #else
  1551.     { "terminal",    XXTERM, CM_INV },
  1552. #endif /* OS2 */
  1553. #endif /* NOFRILLS */
  1554. #ifndef NOXFER
  1555.     { "text",        XXASC, CM_INV },    /* == SET FILE TYPE TEXT */
  1556. #endif /* NOXFER */
  1557.  
  1558. #ifndef NOSPL
  1559.     { "trace",       XXTRACE, 0 },    /* TRACE */
  1560. #else
  1561.     { "trace",       XXNOTAV, CM_INV },
  1562. #endif /* NOSPL */
  1563.  
  1564. #ifndef NOCSETS
  1565.     { "translate",   XXXLA, 0 },    /* TRANSLATE local file char sets */
  1566. #else
  1567.     { "translate",   XXNOTAV, CM_INV },
  1568. #endif /* NOCSETS */
  1569.  
  1570. #ifndef NOXMIT
  1571.     { "transmit",    XXTRA, 0 },    /* Send (upload) a file, no protocol */
  1572. #else
  1573.     { "transmit",    XXNOTAV, CM_INV },
  1574. #endif /* NOXMIT */
  1575.  
  1576. #ifndef NOFRILLS
  1577.     { "type",        XXTYP, 0 },    /* Display a local file */
  1578. #endif /* NOFRILLS */
  1579.  
  1580. #ifndef NOSPL
  1581.     { "undcl",       XXUNDCL, CM_INV },
  1582.     { "undeclare",   XXUNDCL, 0 },    /* UNDECLARE an array */
  1583.     { "undefine",    XXUNDEF, 0 },    /* UNDEFINE a variable or macro */
  1584. #else
  1585.     { "undcl",       XXNOTAV, CM_INV },
  1586.     { "undeclare",   XXNOTAV, CM_INV },
  1587.     { "undefine",    XXNOTAV, CM_INV },
  1588. #endif /* NOSPL */
  1589.  
  1590.     { "version",     XXVER, 0 },    /* VERSION-number display */
  1591.     
  1592. #ifdef OS2
  1593.     { "viewonly",    XXVIEW, CM_LOC },    /* VIEWONLY Terminal Mode */
  1594. #endif /* OS2 */
  1595.  
  1596.     { "void",        XXVOID, 0 },    /* VOID */
  1597.     
  1598. #ifndef NOSPL
  1599.     { "wait",        XXWAI, 0 },    /* WAIT */
  1600. #else
  1601.     { "wait",        XXNOTAV, CM_INV },
  1602. #endif /* NOSPL */
  1603.  
  1604.     { "wermit",      XXKERMI, CM_INV },
  1605.     
  1606. #ifndef NOXFER
  1607.     { "where",       XXWHERE, 0 },    /* WHERE (did my file go?) */
  1608. #endif /* NOXFER */
  1609.  
  1610. #ifndef NOSPL
  1611.     { "while",       XXWHI, 0 },    /* WHILE loop */
  1612. #else
  1613.     { "while",       XXNOTAV, CM_INV },
  1614. #endif /* NOSPL */
  1615.  
  1616. #ifndef OS2
  1617. #ifndef MAC
  1618. #ifndef NOFRILLS
  1619.     { "who",         XXWHO, CM_PSH },    /* WHO's logged in? */
  1620. #endif /* NOFRILLS */
  1621. #endif /* MAC */
  1622. #endif /* OS2 */
  1623.  
  1624. #ifndef NOHELP
  1625.     { "wildcards",   XXWILD,CM_INV|CM_HLP }, /* Wildcard syntax */
  1626. #endif /* NOHELP */
  1627.  
  1628. #ifndef NOSPL
  1629.     { "wr",          XXWRI, CM_INV|CM_ABR },
  1630.     { "wri",         XXWRI, CM_INV|CM_ABR },
  1631.     { "writ",        XXWRI, CM_INV|CM_ABR },
  1632.     { "write",       XXWRI, 0 },    /* WRITE characters to a file */
  1633.     { "write-line",  XXWRL, CM_INV },    /* WRITE a line to a file */
  1634.     { "writeln",     XXWRL, CM_INV },    /* Pascalisch synonym for write-line */
  1635. #else
  1636.     { "wr",          XXNOTAV, CM_INV },
  1637.     { "wri",         XXNOTAV, CM_INV },
  1638.     { "writ",        XXNOTAV, CM_INV },
  1639.     { "write",       XXNOTAV, CM_INV },
  1640.     { "write-line",  XXNOTAV, CM_INV },
  1641.     { "writeln",     XXNOTAV, CM_INV },
  1642. #endif /* NOSPL */
  1643.  
  1644. #ifndef NOFRILLS
  1645.     { "xecho",       XXXECH,0 },    /* XECHO */
  1646. #endif /* NOFRILLS */
  1647.  
  1648. #ifndef NOSPL
  1649.     { "xif",         XXIFX, CM_INV },    /* Extended IF command (obsolete) */
  1650. #else
  1651.     { "xif",         XXNOTAV, CM_INV },
  1652. #endif /* NOSPL */
  1653.  
  1654. #ifndef NOCSETS
  1655.     { "xlate",       XXXLA, CM_INV },    /* Synonym for TRANSLATE */
  1656. #else
  1657.     { "xlate",       XXNOTAV, CM_INV },
  1658. #endif /* NOCSETS */
  1659.  
  1660. #ifndef NOXMIT
  1661.     { "xmit",        XXTRA, CM_INV },    /* Synonym for TRANSMIT */
  1662. #else
  1663.     { "xmit",        XXNOTAV, CM_INV },
  1664. #endif /* NOXMIT */
  1665.  
  1666. #ifndef OS2
  1667. #ifndef NOJC
  1668.     { "z",           XXSUS, CM_INV|CM_PSH }, /* Synonym for SUSPEND */
  1669. #else
  1670.     { "z",           XXNOTAV, CM_INV|CM_PSH },
  1671. #endif /* NOJC */
  1672. #endif /* OS2 */
  1673.  
  1674.     { "", 0, 0 }
  1675. };
  1676. int ncmd = (sizeof(cmdtab) / sizeof(struct keytab)) - 1;
  1677.  
  1678. /* NOTE: Tokens must also be entered above into cmdtab[]. */
  1679.  
  1680. char toktab[] = {
  1681. #ifndef NOPUSH
  1682.     '!',                /* Shell escape */
  1683. #endif /* NOPUSH */
  1684.     '#',                /* Comment */
  1685. #ifndef NOSPL
  1686.     '(',                /* S-Expression */
  1687.     '.',                /* Assignment */
  1688. #endif /* NOSPL */
  1689.     ';',                /* Comment */
  1690. #ifndef NOSPL
  1691.     ':',                /* Label */
  1692. #endif /* NOSPL */
  1693. #ifndef NOPUSH
  1694. #ifdef CK_REDIR
  1695.     '<',                /* REDIRECT */
  1696. #endif /* CK_REDIR */
  1697.     '@',                /* DCL escape */
  1698. #endif /* NOPUSH */
  1699. #ifdef CK_RECALL
  1700.     '^',                /* Command recall */
  1701. #endif /* CK_RECALL */
  1702. #ifndef NOSPL
  1703.     '{',                /* Immediate macro */
  1704. #endif /* NOSPL */
  1705.     '\0'                /* End of this string */
  1706. };
  1707. int xxdot = 0;                /* Used with "." token */
  1708.  
  1709. struct keytab yesno[] = {        /* Yes/No keyword table */
  1710.     { "no",    0, 0 },
  1711.     { "ok",    1, 0 },
  1712.     { "yes",   1, 0 }
  1713. };
  1714. int nyesno = (sizeof(yesno) / sizeof(struct keytab));
  1715.  
  1716. /* Save keyword table */
  1717.  
  1718. struct keytab savtab[] = {
  1719. #ifdef OS2
  1720.     { "command",  XSCMD, 0 },
  1721. #else
  1722. #ifdef CK_RECALL
  1723.     { "command",  XSCMD, 0 },
  1724. #endif /* CK_RECALL */
  1725. #endif /* OS2 */
  1726. #ifndef NOSETKEY
  1727.     { "keymap",   XSKEY, 0 },
  1728. #endif /* NOSETKEY */
  1729. #ifdef OS2
  1730.     { "terminal", XSTERM, 0 },
  1731. #endif /* OS2 */
  1732.     { "", 0, 0 }
  1733. };
  1734. int nsav = (sizeof(savtab) / sizeof(struct keytab)) - 1;
  1735.  
  1736. /* Parameter keyword table */
  1737.  
  1738. struct keytab prmtab[] = {
  1739.     { "alarm",            XYALRM,  0 },
  1740.     { "ask-timer",        XYTIMER, 0 },
  1741. #ifndef NOXFER
  1742.     { "attributes",       XYATTR,  0 },
  1743. #endif /* NOXFER */
  1744. #ifdef CK_AUTHENTICATION
  1745.     { "authentication",   XYAUTH,  0 },
  1746. #else  /* CK_AUTHENTICATION */
  1747. #ifdef CK_SSL
  1748.     { "authentication",   XYAUTH,  0 },
  1749. #endif /* CK_SSL */
  1750. #endif /* CK_AUTHENTICATION */
  1751.     { "b",          XYBACK,  CM_INV|CM_ABR|CM_PSH },
  1752.     { "ba",          XYBACK,  CM_INV|CM_ABR|CM_PSH },
  1753. #ifdef VMS
  1754.     { "background",       XYBACK,  CM_INV|CM_PSH },
  1755.     { "batch",            XYBACK,  CM_PSH },
  1756. #else
  1757.     { "background",       XYBACK,  CM_PSH },
  1758.     { "batch",            XYBACK,  CM_INV|CM_PSH },
  1759. #endif /* VMS */
  1760. #ifndef NOLOCAL
  1761.     { "baud",              XYSPEE,  CM_INV|CM_LOC },
  1762. #endif /* NOLOCAL */
  1763.     { "bell",             XYBELL,  0 },
  1764. #ifndef NOXFER
  1765.     { "block-check",        XYCHKT,  0 },
  1766. #endif /* NOXFER */
  1767. #ifdef OS2
  1768. #ifdef BPRINT
  1769.     { "bprinter",         XYBDCP,  CM_INV },
  1770. #endif /* BPRINT */
  1771. #endif /*  OS2 */
  1772. #ifdef BROWSER
  1773.     { "browser",          XYBROWSE,CM_PSH|CM_LOC },
  1774. #endif /* BROWSER */
  1775. #ifndef NOXFER
  1776. #ifdef DYNAMIC
  1777.     { "buffers",          XYBUF,   0 },
  1778. #endif /* DYNAMIC */
  1779. #endif /* NOXFER */
  1780. #ifndef NOLOCAL
  1781. #ifndef MAC
  1782.     { "carrier-watch",    XYCARR,  CM_LOC },
  1783. #endif /* MAC */
  1784. #endif /* NOLOCAL */
  1785. #ifndef NOSPL
  1786.     { "case",             XYCASE,  0 },
  1787. #endif /* NOSPL */
  1788.     { "cd",               XYCD,    0 },
  1789. #ifndef NOXFER
  1790.     { "cl",               XYCLEAR, CM_INV|CM_ABR },
  1791.     { "cle",              XYCLEAR, CM_INV|CM_ABR },
  1792.     { "clea",             XYCLEAR, CM_INV|CM_ABR },
  1793.     { "clear",            XYCLEAR, CM_INV|CM_ABR },
  1794.     { "clear-channel",    XYCLEAR, 0 },
  1795.     { "clearchannel",     XYCLEAR, CM_INV },
  1796. #endif /* NOXFER */
  1797. #ifndef NOLOCAL
  1798.     { "close-on-disconnect", XYDISC, CM_INV|CM_LOC },
  1799. #endif /* NOLOCAL */
  1800.     { "cmd",              XYCMD,   CM_INV },
  1801.     { "command",          XYCMD,   0 },
  1802. #ifdef CK_SPEED
  1803.     { "con",              XYQCTL,  CM_INV|CM_ABR },
  1804. #endif /* CK_SPEED */
  1805.     { "console",          XYCMD,   CM_INV },
  1806. #ifdef CK_SPEED
  1807.     { "control-character",XYQCTL,  0 },
  1808. #endif /* CK_SPEED */
  1809. #ifndef NOSPL
  1810.     { "count",            XYCOUN,  0 },
  1811. #endif /* NOSPL */
  1812. #ifndef NOXFER
  1813.     { "d",          XYDELA,  CM_INV|CM_ABR },
  1814.     { "de",          XYDELA,  CM_INV|CM_ABR },
  1815. #endif /* NOXFER */
  1816.     { "debug",            XYDEBU,  0 },
  1817. #ifdef VMS
  1818.     { "default",          XYDFLT,  0 },
  1819. #else
  1820. #ifndef MAC
  1821.     { "default",          XYDFLT,  CM_INV },
  1822. #endif /* MAC */
  1823. #endif /* VMS */
  1824. #ifndef NOXFER
  1825.     { "delay",              XYDELA,  0 },
  1826.     { "destination",      XYDEST,  0 },
  1827. #endif /* NOXFER */
  1828. #ifndef NODIAL
  1829.     { "di",          XYDIAL,  CM_INV|CM_ABR|CM_LOC },
  1830.     { "dia",          XYDIAL,  CM_INV|CM_ABR|CM_LOC },
  1831.     { "dial",             XYDIAL,  CM_LOC },
  1832. #endif /* NODIAL */
  1833. #ifdef OS2
  1834.     { "dialer",          XYDLR,   CM_INV },
  1835. #endif /* OS2 */
  1836. #ifndef NOLOCAL
  1837.     { "disconnect",       XYDISC,  CM_LOC },
  1838.     { "duplex",              XYDUPL,  CM_LOC },
  1839. #endif /* NOLOCAL */
  1840. #ifndef NOPUSH
  1841. #ifndef NOFRILLS
  1842.     { "editor",           XYEDIT,  CM_PSH },
  1843. #endif /*  NOFRILLS */
  1844. #endif /* NOPUSH */
  1845. #ifdef CK_CTRLZ
  1846.     { "eof",              XYEOF,   CM_INV },
  1847. #endif /* CK_CTRLZ */
  1848. #ifndef NOLOCAL
  1849.     { "escape-character", XYESC,   CM_LOC },
  1850. #endif /* NOLOCAL */
  1851. #ifndef NOSPL
  1852.     { "evaluate",         XYEVAL,  CM_INV },
  1853. #endif /* NOSPL */
  1854.     { "exit",          XYEXIT,  0 },
  1855. #ifndef NOXFER
  1856.     { "f-ack-bug",        XYFACKB, CM_INV },
  1857.     { "f-ack-path",       XYFACKP, CM_INV },
  1858. #endif /* NOXFER */
  1859.     { "file",             XYFILE,  0 },
  1860.     { "fl",                 XYFLOW,  CM_INV|CM_ABR },
  1861. #ifndef NOSPL
  1862.     { "flag",             XYFLAG,  0 },
  1863. #endif /* NOSPL */
  1864. #ifdef TCPSOCKET
  1865. #ifndef SYSFTP
  1866. #ifndef NOFTP
  1867.     { "ft",                 XYFTPX,  CM_INV|CM_ABR },
  1868.     { "ftp",                XYFTPX,  0 },
  1869. #endif /* NOFTP */
  1870. #endif /* SYSFTP */
  1871. #endif /* TCPSOCKET */
  1872. #ifdef BROWSER
  1873.     { "ftp-client",       XYFTP,   CM_PSH },
  1874. #endif /* BROWSER */
  1875.     { "flow-control",       XYFLOW,  0 },
  1876. #ifndef NOSPL
  1877.     { "function",         XYFUNC,  0 },
  1878. #endif /* NOSPL */
  1879. #ifdef NEWFTP
  1880.     { "get-put-remote",   XYGPR,   0 },
  1881. #endif /* NEWFTP */
  1882.     { "handshake",          XYHAND,  0 },
  1883.     { "hints",            XYHINTS, 0 },
  1884. #ifdef NETCONN
  1885.     { "host",             XYHOST,  CM_LOC },
  1886. #endif /* NETCONN */
  1887. #ifndef NOSPL
  1888.     { "i",          XYINPU,  CM_INV|CM_ABR },
  1889. #endif /* NOSPL */
  1890. #ifdef IKSD
  1891.     { "iks",              XYIKS,   0 },
  1892. #else
  1893.     { "iks",              XYIKS,   CM_INV },
  1894. #endif /* IKSD */
  1895. #ifndef NOSPL
  1896.     { "in",          XYINPU,  CM_INV|CM_ABR },
  1897. #endif /* NOSPL */
  1898. #ifndef NOXFER
  1899.     { "incomplete",         XYIFD,   CM_INV },
  1900. #endif /* NOXFER */
  1901. #ifndef NOSPL
  1902.     { "input",            XYINPU,  0 },
  1903. #endif /* NOSPL */
  1904. #ifndef NOSETKEY
  1905.     { "key",          XYKEY,   0 },
  1906. #endif /* NOSETKEY */
  1907.     { "l",                XYLINE,  CM_INV|CM_ABR },
  1908. #ifndef NOCSETS
  1909.     { "language",         XYLANG,  0 },
  1910. #endif /* NOCSETS */
  1911. #ifndef NOLOCAL
  1912.     { "line",             XYLINE,  CM_LOC },
  1913.     { "local-echo",      XYLCLE,  CM_INV|CM_LOC },
  1914. #endif /* NOLOCAL */
  1915. #ifndef NOSPL
  1916.     { "login",          XYLOGIN, CM_LOC },
  1917. #endif /* NOSPL */
  1918. #ifndef NOSPL
  1919.     { "macro",            XYMACR,  0 },
  1920. #endif /* NOSPL */
  1921. #ifdef COMMENT
  1922. #ifdef VMS
  1923.     { "messages",         XYMSGS,  0 },
  1924. #endif /* VMS */
  1925. #endif /* COMMENT */
  1926. #ifndef NODIAL
  1927.     { "modem",          XYMODM,  CM_LOC },
  1928. #endif /* NODIAL */
  1929. #ifndef NOLOCAL
  1930. #ifdef OS2MOUSE
  1931.     { "mouse",          XYMOUSE, 0 },
  1932. #endif /* OS2MOUSE */
  1933. #endif /* NOLOCAL */
  1934. #ifdef OS2
  1935.     { "mskermit",         XYMSK,   0 },
  1936. #endif /* OS2 */
  1937. #ifdef NETCONN
  1938.     { "network",          XYNET,   CM_LOC },
  1939. #endif /* NETCONN */
  1940. #ifndef NOSPL
  1941.     { "output",           XYOUTP,  0 },
  1942. #endif /* NOSPL */
  1943.     { "options",          XYOPTS,  0 },
  1944.     { "pause",            XYSLEEP, CM_INV },
  1945. #ifdef ANYX25
  1946. #ifndef IBMX25
  1947.     { "pad",              XYPAD,   CM_LOC },
  1948. #endif /* IBMX25 */
  1949. #endif /* ANYX25 */
  1950.     { "parity",              XYPARI,  0 },
  1951. #ifndef NOLOCAL
  1952. #ifdef OS2
  1953.     { "port",             XYLINE,  CM_LOC },
  1954. #else
  1955.     { "port",             XYLINE,  CM_INV|CM_LOC },
  1956. #endif /* OS2 */
  1957. #endif /* NOLOCAL */
  1958. #ifndef NOFRILLS
  1959.     { "pr",                 XYPROM,  CM_INV|CM_ABR },
  1960.     { "printer",          XYPRTR,  0 },
  1961. #endif /* NOFRILLS */
  1962. #ifdef OS2
  1963.     { "priority",         XYPRTY,  0 },
  1964. #endif /* OS2 */
  1965. #ifdef CK_SPEED
  1966.     { "prefixing",        XYPREFIX, 0 },
  1967. #endif /* CK_SPEED */
  1968. #ifndef NOFRILLS
  1969.     { "prompt",              XYPROM,  0 },
  1970. #endif /* NOFRILLS */
  1971. #ifndef NOXFER
  1972.     { "protocol",      XYPROTO, 0 },
  1973. #endif /* NOXFER */
  1974.     { "q",          XYQUIE,  CM_INV|CM_ABR },
  1975. #ifndef NOXFER
  1976.     { "q8flag",           XYQ8FLG, CM_INV },
  1977. #endif /* NOXFER */
  1978. #ifdef QNX
  1979.     { "qnx-port-lock",    XYQNXPL, 0 },
  1980. #else
  1981.     { "qnx-port-lock",    XYQNXPL, CM_INV },
  1982. #endif /* QNX */
  1983.     { "quiet",          XYQUIE,  0 },
  1984. #ifndef NOXFER
  1985.     { "rec",              XYRECV,  CM_INV|CM_ABR },
  1986.     { "receive",          XYRECV,  0 },
  1987.     { "recv",             XYRECV,  CM_INV },
  1988. #endif /* NOXFER */
  1989.     { "reliable",         XYRELY,  0 },
  1990. #ifndef NOXFER
  1991.     { "repeat",           XYREPT,  0 },
  1992.     { "retry-limit",      XYRETR,  0 },
  1993. #endif /* NOXFER */
  1994. #ifdef CKROOT
  1995.     { "root",             XYROOT,  0 },
  1996. #endif /* CKROOT */
  1997. #ifndef NOSCRIPT
  1998.     { "script",          XYSCRI,  CM_LOC },
  1999. #endif /* NOSCRIPT */
  2000. #ifndef NOXFER
  2001.     { "send",             XYSEND,  0 },
  2002. #ifndef NOLOCAL
  2003. #ifndef NOSERVER
  2004.     { "ser",              XYSERV,  CM_INV|CM_ABR },
  2005. #endif /* NOSERVER */
  2006. #endif /* NOXFER */
  2007.     { "serial",           XYSERIAL,CM_LOC },
  2008. #endif /* NOLOCAL */
  2009. #ifndef NOSERVER
  2010.     { "server",           XYSERV,  0 },
  2011. #endif /* NOSERVER */
  2012. #ifdef SESLIMIT
  2013. #ifndef NOLOCAL
  2014.     { "session-l",        XYSESS,  CM_INV|CM_ABR },
  2015. #endif /* NOLOCAL */
  2016.     { "session-limit",    XYLIMIT, CM_INV|CM_LOC }, /* Session Limit */
  2017. #endif /* SESLIMIT */
  2018.  
  2019. #ifndef NOLOCAL
  2020.     { "session-log",      XYSESS,  CM_LOC },
  2021. #endif /* NOLOCAL */
  2022.  
  2023. #ifndef NOSPL
  2024. #ifndef NOSEXP
  2025.     { "sexpression",      XYSEXP,  CM_INV },
  2026. #endif /* NOSEXP */
  2027. #endif /* NOSPL */
  2028.  
  2029.     { "sleep",            XYSLEEP, 0 },
  2030.     
  2031. #ifndef NOLOCAL
  2032.     { "speed",              XYSPEE,  CM_LOC },
  2033. #endif /* NOLOCAL */
  2034.  
  2035. #ifdef ANYSSH
  2036.     { "ssh",              XYSSH,   0 },
  2037. #endif /* ANYSSH */
  2038.  
  2039. #ifndef NOSPL
  2040.     { "startup-file",     XYSTARTUP, CM_INV },
  2041. #endif /* NOSPL */
  2042.  
  2043. #ifndef NOLOCAL
  2044. #ifdef HWPARITY
  2045.     { "stop-bits",        XYSTOP, CM_LOC },
  2046. #else
  2047. #ifdef TN_COMPORT
  2048.     { "stop-bits",        XYSTOP, CM_LOC },
  2049. #endif /* TN_COMPORT */
  2050. #endif /* HWPARITY */
  2051. #endif /* NOLOCAL */
  2052.  
  2053. #ifndef NOXFER
  2054. #ifdef STREAMING
  2055.     { "streaming",        XYSTREAM, 0 },
  2056. #endif /* STREAMING */
  2057. #endif /* NOXFER */
  2058.  
  2059. #ifndef NOJC
  2060.     { "suspend",          XYSUSP,  CM_PSH },
  2061. #endif /* NOJC */
  2062. #ifdef CKSYSLOG
  2063.     { "syslog",           XYSYSL,  CM_INV },
  2064. #endif /* CKSYSLOG */
  2065.     { "take",             XYTAKE,  0 },
  2066.     
  2067. #ifdef CK_TAPI
  2068.     { "tapi",             XYTAPI,  CM_LOC },
  2069. #endif /* CK_TAPI */
  2070.  
  2071. #ifndef NOTCPOPTS
  2072. #ifdef TCPSOCKET
  2073.     { "tcp",              XYTCP,   CM_LOC },
  2074. #endif /* TCPSOCKET */
  2075. #endif /* NOTCPOPTS */
  2076.  
  2077. #ifdef TNCODE
  2078.     { "tel",              XYTEL,   CM_INV|CM_ABR },
  2079.     { "telnet",           XYTEL,   0 },
  2080.     { "telopt",           XYTELOP, 0 },
  2081. #endif /* TNCODE */
  2082.  
  2083. #ifndef NOSPL
  2084.     { "temp-directory",   XYTMPDIR,0 },
  2085. #endif /* NOSPL */
  2086.  
  2087. #ifndef NOLOCAL
  2088.     { "terminal",         XYTERM,  CM_LOC },
  2089. #endif /* NOLOCAL */
  2090.  
  2091. #ifdef OS2
  2092.     { "title",          XYTITLE, CM_LOC },
  2093. #endif /* OS2 */
  2094. #ifdef TLOG
  2095.     { "transaction-log",  XYTLOG,  0 },
  2096. #endif /* TLOG */
  2097. #ifndef NOXFER
  2098.     { "transfer",         XYXFER,  0 },
  2099. #endif /* NOXFER */
  2100. #ifndef NOXMIT
  2101.     { "transmit",         XYXMIT,  0 },
  2102. #endif /* NOXMIT */
  2103. #ifndef NOXFER
  2104. #ifndef NOCSETS
  2105.     { "unknown-char-set", XYUNCS,  0 },
  2106. #endif /* NOCSETS */
  2107. #endif /* NOXFER */
  2108.     { "wait",             XYSLEEP, CM_INV },
  2109. #ifndef NOPUSH
  2110. #ifdef UNIX
  2111.     { "wildcard-expansion", XYWILD, 0 },
  2112. #endif /* UNIX */
  2113. #endif /* NOPUSH */
  2114. #ifdef NT
  2115.     { "w",                XYWIND,  CM_INV|CM_ABR },
  2116.     { "wi",               XYWIND,  CM_INV|CM_ABR },
  2117.     { "win",              XYWIND,  CM_INV|CM_ABR },
  2118. #endif /* NT */
  2119.     { "window-size",      XYWIND,  0 },
  2120. #ifdef NT
  2121.     { "win95",            XYWIN95, 0 },
  2122. #endif /* NT */
  2123. #ifdef ANYX25
  2124.     { "x.25",             XYX25,   CM_LOC },
  2125.     { "x25",              XYX25,   CM_INV|CM_LOC },
  2126. #endif /* ANYX25 */
  2127.     { "xfer",             XYXFER,  CM_INV },
  2128. #ifndef NOXMIT
  2129.     { "xmit",             XYXMIT,  CM_INV },
  2130. #endif /* NOXMIT */
  2131.     { "", 0, 0 }
  2132. };
  2133. int nprm = (sizeof(prmtab) / sizeof(struct keytab)) - 1; /* How many */
  2134.  
  2135. struct keytab scntab[] = {        /* Screen commands */
  2136.     { "clear",   SCN_CLR, 0 },
  2137.     { "cleol",   SCN_CLE, 0 },
  2138.     { "move-to", SCN_MOV, 0 }
  2139. };
  2140. int nscntab = (sizeof(scntab) / sizeof(struct keytab)); /* How many */
  2141.  
  2142. #ifdef ANYSSH                /* SSH command table */
  2143. #ifdef SSHBUILTIN
  2144. #define XSSH_OPN 1
  2145. #define XSSH_V2R 2
  2146. #define XSSH_FLP 3
  2147. #define XSSH_FRP 4
  2148.  
  2149. static struct keytab sshkwtab[] = {
  2150.     { "forward-local-port",  XSSH_FLP, 0 },
  2151.     { "forward-remote-port", XSSH_FRP, 0 },
  2152.     { "open",                XSSH_OPN, 0 },
  2153.     { "v2-rekey",            XSSH_V2R, 0 }
  2154. };
  2155. static int nsshcmd = (sizeof(sshkwtab) / sizeof(struct keytab));
  2156. #endif /* SSHBUILTIN */
  2157. #endif /* ANYSSH */
  2158.  
  2159. #ifdef NETCONN
  2160. struct keytab netkey[] = {        /* SET NETWORK table */
  2161.     { "directory", XYNET_D,  0 },
  2162.     { "type",      XYNET_T,  0 }
  2163. };
  2164. int nnetkey = (sizeof(netkey) / sizeof(struct keytab));
  2165.  
  2166. struct keytab netcmd[] = {
  2167. /*
  2168.   These are the network types.
  2169. */
  2170. #ifdef NETCMD
  2171.     { "command",       NET_CMD,  CM_INV }, /* Command */
  2172. #endif /* NETCMD */
  2173.  
  2174. #ifdef DECNET                /* DECnet / PATHWORKS */
  2175.     { "decnet",        NET_DEC,  0 },
  2176. #endif /* DECNET */
  2177.  
  2178. #ifdef NETDLL
  2179.     { "dll",           NET_DLL,  CM_INV }, /* DLL to be loaded */
  2180. #endif /* NETDLL */
  2181.  
  2182. #ifdef NETFILE
  2183.     { "file",           NET_FILE, CM_INV }, /* FILE (real crude) */
  2184. #endif /* NETFILE */
  2185.  
  2186. #ifdef NPIPE                /* Named Pipes */
  2187.     { "named-pipe",     NET_PIPE,  0 },
  2188. #endif /* NPIPE */
  2189.  
  2190. #ifdef CK_NETBIOS
  2191.     { "netbios",        NET_BIOS,  0 },    /* NETBIOS */
  2192. #endif /* CK_NETBIOS */
  2193.  
  2194. #ifdef DECNET                /* DECnet / PATHWORKS (alias) */
  2195.     { "pathworks",     NET_DEC,  CM_INV },
  2196. #endif /* DECNET */
  2197.  
  2198. #ifdef NETCMD
  2199.     { "pipe",          NET_CMD,  0 },    /* Pipe */
  2200. #endif /* NETCMD */
  2201.  
  2202. #ifdef NETPTY
  2203.     { "pseudoterminal",NET_PTY, 0 },    /* Pseudoterminal */
  2204. #endif /* NETPTY */
  2205.  
  2206. #ifdef NETPTY
  2207.     { "pty",          NET_PTY,  CM_INV }, /* Inv syn for pseudoterm */
  2208. #endif /* NETPTY */
  2209.  
  2210. #ifdef SUPERLAT
  2211.     { "superlat",     NET_SLAT, 0 },    /* Meridian Technologies' SuperLAT */
  2212. #endif /* SUPERLAT */
  2213.  
  2214. #ifdef TCPSOCKET            /* TCP/IP sockets library */
  2215.     { "tcp/ip",       NET_TCPB, 0 },
  2216. #endif /* TCPSOCKET */
  2217. #ifdef SUPERLAT
  2218.     { "tes32",        NET_SLAT, 0 },    /* Emulux TES32 */
  2219. #endif /* SUPERLAT */
  2220. #ifdef ANYX25                /* X.25 */
  2221. #ifdef SUNX25
  2222.     { "x",            NET_SX25, CM_INV|CM_ABR },
  2223.     { "x.25",         NET_SX25, 0 },
  2224.     { "x25",          NET_SX25, CM_INV },
  2225. #else
  2226. #ifdef STRATUSX25
  2227.     { "x",            NET_VX25, CM_INV|CM_ABR },
  2228.     { "x.25",         NET_VX25, 0 },
  2229.     { "x25",          NET_VX25, CM_INV },
  2230. #endif /* STRATUSX25 */
  2231. #endif /* SUNX25 */
  2232. #ifdef IBMX25
  2233.     { "x",            NET_IX25, CM_INV|CM_ABR },
  2234.     { "x.25",         NET_IX25, CM_INV },
  2235.     { "x25",          NET_IX25, CM_INV },
  2236. #endif /* IBMX25 */
  2237. #ifdef HPX25
  2238.     { "x",            NET_IX25, CM_INV|CM_ABR },
  2239.     { "x.25",         NET_IX25, 0 },
  2240.     { "x25",          NET_IX25, CM_INV },
  2241. #endif /* HPX25 */
  2242. #endif /* ANYX25 */
  2243.     { "", 0, 0 }
  2244. };
  2245. int nnets = (sizeof(netcmd) / sizeof(struct keytab));
  2246.  
  2247. #ifndef NOTCPOPTS
  2248. #ifdef TCPSOCKET
  2249.  
  2250. /* TCP options */
  2251.  
  2252. struct keytab tcpopt[] = {
  2253.     { "address",   XYTCP_ADDRESS, 0 },
  2254. #ifdef CK_DNS_SRV
  2255.     { "dns-service-records", XYTCP_DNS_SRV, 0 },
  2256. #endif /* CK_DNS_SRV */
  2257. #ifdef SO_DONTROUTE
  2258.     { "dontroute",   XYTCP_DONTROUTE, 0 },
  2259. #endif /* SO_DONTROUTE */
  2260. #ifndef NOHTTP
  2261.     { "http-proxy", XYTCP_HTTP_PROXY, 0 },
  2262. #endif /* NOHTTP */
  2263. #ifdef SO_KEEPALIVE
  2264.     { "keepalive", XYTCP_KEEPALIVE, 0 },
  2265. #endif /* SO_KEEPALIVE */
  2266. #ifdef SO_LINGER
  2267.     { "linger", XYTCP_LINGER, 0 },
  2268. #endif /* SO_LINGER */
  2269. #ifdef TCP_NODELAY
  2270.     { "nagle",  XYTCP_NAGLE,    CM_INV },
  2271.     { "nodelay", XYTCP_NODELAY, 0 },
  2272. #endif /* TCP_NODELAY */
  2273.     { "reverse-dns-lookup", XYTCP_RDNS, 0 },
  2274. #ifdef SO_RCVBUF
  2275.     { "recvbuf", XYTCP_RECVBUF, 0 },
  2276. #endif /* SO_RCVBUF */
  2277. #ifdef SO_SNDBUF
  2278.     { "sendbuf", XYTCP_SENDBUF, 0 },
  2279. #endif /* SO_SNDBUF */
  2280. #ifdef NT
  2281. #ifdef CK_SOCKS
  2282.     { "socks-server", XYTCP_SOCKS_SVR, 0 },
  2283. #endif /* CK_SOCKS */
  2284. #endif /* NT */
  2285. #ifdef VMS
  2286. #ifdef DEC_TCPIP
  2287.     { "ucx-port-bug", XYTCP_UCX, 0 },
  2288. #endif /* DEC_TCPIP */
  2289. #endif /* VMS */
  2290.     { "",0,0 }
  2291. };
  2292. int ntcpopt = (sizeof(tcpopt) / sizeof(struct keytab));
  2293.  
  2294. #endif /* TCPSOCKET */
  2295. #endif /* NOTCPOPTS */
  2296.  
  2297. #endif /* NETCONN */
  2298.  
  2299. #ifdef OS2
  2300. /* K95 Manual Chapter Table -- Keep these two tables in sync! */
  2301.  
  2302. static char * linktbl[] = {        /* Internal links in k95.htm */
  2303.     "#top",                /* 00 */
  2304.     "#what",                /* 01 */
  2305.     "#install",                /* 02 */
  2306.     "#start",                /* 03 */
  2307.     "#dialer",                /* 04 */
  2308.     "#entries",                /* 05 */
  2309.     "#command",                /* 06 */
  2310.     "#terminal",            /* 07 */
  2311.     "#transfer",            /* 08 */
  2312.     "#hostmode"                /* 09 */
  2313. };
  2314.  
  2315. static struct keytab chaptbl[] = {
  2316.     { "Command-Screen",     6, 0 },
  2317.     { "Contents",           0, 0 },
  2318.     { "Dialer-Entries",     5, 0 },
  2319.     { "File-Transfer",      8, 0 },
  2320.     { "Getting-Started",    3, 0 },
  2321.     { "Host-Mode",          9, 0 },
  2322.     { "Installation",       2, 0 },
  2323.     { "Terminal-Emulation", 7, 0 },
  2324.     { "Using-The-Dialer",   4, 0 },
  2325.     { "What-Is-K95",        1, 0 },
  2326.     { "",                   0, 0 }
  2327. };
  2328. static int nchaptbl = (sizeof(chaptbl) / sizeof(struct keytab));
  2329. #endif /* OS2 */
  2330.  
  2331. #ifndef NOXFER
  2332. /* Remote Command Table */
  2333.  
  2334. struct keytab remcmd[] = {
  2335. #ifndef NOSPL
  2336.     { "as",        XZASG, CM_INV|CM_ABR },
  2337.     { "asg",       XZASG, CM_INV },
  2338.     { "assign",    XZASG, 0 },
  2339. #endif /* NOSPL */
  2340.     { "cd",        XZCWD, 0 },
  2341.     { "cdup",      XZCDU, CM_INV },
  2342.     { "copy",      XZCPY, 0 },
  2343.     { "cwd",       XZCWD, CM_INV },
  2344.     { "delete",    XZDEL, 0 },
  2345.     { "directory", XZDIR, 0 },
  2346.     { "e",         XZXIT, CM_ABR|CM_INV },
  2347.     { "erase",     XZDEL, CM_INV },
  2348.     { "exit",      XZXIT, 0 },
  2349.     { "help",      XZHLP, 0 },
  2350. #ifndef NOPUSH
  2351.     { "host",      XZHOS, 0 },
  2352. #endif /* NOPUSH */
  2353. #ifndef NOFRILLS
  2354.     { "kermit",    XZKER, 0 },
  2355.     { "l",         XZLGI, CM_ABR|CM_INV },
  2356.     { "lo",        XZLGI, CM_ABR|CM_INV },
  2357.     { "log",       XZLGI, CM_ABR|CM_INV },
  2358.     { "login",     XZLGI, 0 },
  2359.     { "logout",    XZLGO, 0 },
  2360.     { "mkdir",     XZMKD, 0 },
  2361.     { "print",     XZPRI, 0 },
  2362. #endif /* NOFRILLS */
  2363.     { "pwd",       XZPWD, 0 },
  2364. #ifndef NOSPL
  2365.     { "query",       XZQUE, 0 },
  2366. #endif /* NOSPL */
  2367.     { "rename",    XZREN, 0 },
  2368.     { "rmdir",     XZRMD, 0 },
  2369.     { "set",       XZSET, 0 },
  2370.     { "space",       XZSPA, 0 },
  2371. #ifndef NOFRILLS
  2372.     { "type",      XZTYP, 0 },
  2373.     { "who",       XZWHO, 0 },
  2374. #endif /* NOFRILLS */
  2375.     { "", 0, 0}
  2376. };
  2377. int nrmt = (sizeof(remcmd) / sizeof(struct keytab)) - 1;
  2378. #endif /* NOXFER */
  2379.  
  2380. struct keytab logtab[] = {
  2381. #ifdef CKLOGDIAL
  2382.     { "connections",  LOGM, CM_INV },
  2383.     { "cx",           LOGM, 0 },
  2384. #endif /* CKLOGDIAL */
  2385. #ifdef DEBUG
  2386.     { "debugging",    LOGD, 0 },
  2387. #endif /* DEBUG */
  2388.     { "packets",      LOGP, 0 },
  2389. #ifndef NOLOCAL
  2390.     { "session",      LOGS, 0 },
  2391. #endif /* NOLOCAL */
  2392. #ifdef TLOG
  2393.     { "transactions", LOGT, 0 },
  2394. #endif /* TLOG */
  2395.     { "", 0, 0 }
  2396. };
  2397. int nlog = (sizeof(logtab) / sizeof(struct keytab)) - 1;
  2398.  
  2399. struct keytab writab[] = {
  2400. #ifndef NOSPL
  2401.     { "append-file",     LOGW, CM_INV },
  2402. #endif /* NOSPL */
  2403.     { "debug-log",       LOGD, 0 },
  2404.     { "error",           LOGE, 0 },
  2405. #ifndef NOSPL
  2406.     { "file",            LOGW, 0 },
  2407. #endif /* NOSPL */
  2408.     { "packet-log",      LOGP, 0 },
  2409.     { "screen",          LOGX, 0 },
  2410. #ifndef NOLOCAL
  2411.     { "session-log",     LOGS, 0 },
  2412. #endif /* NOLOCAL */
  2413.     { "sys$output",      LOGX, CM_INV },
  2414.     { "t",               LOGT, CM_ABR|CM_INV }, /* Because of a typo in */
  2415.     { "tr",              LOGT, CM_ABR|CM_INV }, /* the book... */
  2416.     { "tra",             LOGT, CM_ABR|CM_INV },
  2417.     { "tran",            LOGT, CM_ABR|CM_INV },
  2418.     { "trans",           LOGT, CM_ABR|CM_INV },
  2419.     { "transa",          LOGT, CM_ABR|CM_INV },
  2420.     { "transac",         LOGT, CM_ABR|CM_INV },
  2421.     { "transact",        LOGT, CM_ABR|CM_INV },
  2422.     { "transacti",       LOGT, CM_ABR|CM_INV },
  2423.     { "transactio",      LOGT, CM_ABR|CM_INV },
  2424.     { "transaction",     LOGT, CM_ABR|CM_INV },
  2425.     { "transaction-log", LOGT, 0 },
  2426.     { "transactions",    LOGT, CM_INV }
  2427. };
  2428. int nwri = (sizeof(writab) / sizeof(struct keytab));
  2429.  
  2430. #ifdef COMMENT                /* INPUT switches not used yet... */
  2431. static struct keytab inswtab[] = {
  2432. #ifdef COMMENT
  2433.     { "/assign",       IN_ASG, CM_ARG },
  2434. #endif /* COMMENT */
  2435.     { "/autodownload", IN_ADL, CM_ARG },
  2436.     { "/case",         IN_CAS, CM_ARG },
  2437.     { "/echo",         IN_ECH, CM_ARG },
  2438.     { "/interrupts",   IN_NOI, CM_ARG },
  2439.     { "/silence",      IN_SIL, CM_ARG },
  2440. #ifdef COMMENT
  2441.     { "/pattern",      IN_PAT, CM_ARG },
  2442. #endif /* COMMENT */
  2443.     { "", 0, 0 }
  2444. };
  2445. static int ninswtab = (sizeof(inswtab) / sizeof(struct keytab)) - 1;
  2446. #endif /* COMMENT */
  2447.  
  2448. static struct keytab clrtab[] = {    /* Keywords for CLEAR command */
  2449. #ifndef NOSPL
  2450.     { "alarm",            CLR_ALR,         0 },
  2451. #ifdef CK_APC
  2452.     { "apc",              CLR_APC,         0 },
  2453. #endif /* CK_APC */
  2454. #ifdef PATTERNS
  2455.     { "binary-patterns",  CLR_BIN,         0 },
  2456. #endif /* PATTERNS */
  2457.     { "both",             CLR_DEV|CLR_INP, CM_INV },
  2458. #endif /* NOSPL */
  2459. #ifdef OS2
  2460.     { "command-screen",   CLR_CMD,         0 },
  2461. #endif /* OS2 */
  2462. #ifndef NOSPL
  2463.     { "device",           CLR_DEV,         CM_INV|CM_ABR },
  2464.     { "device-and-input", CLR_DEV|CLR_INP, 0 },
  2465. #endif /* NOSPL */
  2466.     { "device-buffer",    CLR_DEV,         0 },
  2467. #ifndef NODIAL
  2468.     { "dial-status",      CLR_DIA,     0 },
  2469. #endif /* NODIAL */
  2470. #ifndef NOSPL
  2471.     { "input-buffer",     CLR_INP,         0 },
  2472. #endif /* NOSPL */
  2473.     { "keyboard-buffer",  CLR_KBD,         0 },
  2474.     { "send-list",        CLR_SFL,         0 },
  2475. #ifdef OS2
  2476.     { "scr",              CLR_SCL,         CM_INV|CM_ABR },
  2477. #endif /* OS2 */
  2478.     { "screen",           CLR_SCR,         0 },
  2479. #ifdef OS2
  2480.     { "scrollback",       CLR_SCL,         CM_INV },
  2481.     { "terminal-screen",  CLR_TRM,         0 },
  2482. #endif /* OS2 */
  2483. #ifdef PATTERNS
  2484.     { "text-patterns",    CLR_TXT,         0 },
  2485. #endif /* PATTERNS */
  2486.     { "", 0, 0 }
  2487. };
  2488. int nclear = (sizeof(clrtab) / sizeof(struct keytab)) - 1;
  2489.  
  2490. struct keytab clstab[] = {        /* Keywords for CLOSE command */
  2491. #ifndef NOSPL
  2492.     { "!read",           LOGR, CM_INV },
  2493.     { "!write",          LOGW, CM_INV },
  2494. #ifndef NOPUSH
  2495. #endif /* NOPUSH */
  2496. #endif /* NOSPL */
  2497. #ifndef NOSPL
  2498.     { "append-file",     LOGW, CM_INV },
  2499. #endif /* NOSPL */
  2500. #ifndef NOLOCAL
  2501.     { "connection",      9999, 0 },
  2502. #endif /* NOLOCAL */
  2503. #ifdef CKLOGDIAL
  2504.     { "cx-log",          LOGM, 0 },
  2505. #endif /* CKLOGDIAL */
  2506. #ifdef DEBUG
  2507.     { "debug-log",       LOGD, 0 },
  2508. #endif /* DEBUG */
  2509.     { "host",            9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
  2510.     { "line",            9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
  2511.     { "p",               LOGP, CM_INV|CM_ABR },
  2512.     { "packet-log",      LOGP, 0 },
  2513.     { "port",            9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
  2514. #ifndef NOSPL
  2515.     { "read-file",       LOGR, 0 },
  2516. #endif /* NOSPL */
  2517. #ifndef NOLOCAL
  2518.     { "session-log",     LOGS, 0 },
  2519. #endif /* NOLOCAL */
  2520. #ifdef TLOG
  2521.     { "t",               LOGT, CM_ABR|CM_INV }, /* Because of a typo in */
  2522.     { "tr",              LOGT, CM_ABR|CM_INV }, /* the book... */
  2523.     { "tra",             LOGT, CM_ABR|CM_INV },
  2524.     { "tran",            LOGT, CM_ABR|CM_INV },
  2525.     { "trans",           LOGT, CM_ABR|CM_INV },
  2526.     { "transa",          LOGT, CM_ABR|CM_INV },
  2527.     { "transac",         LOGT, CM_ABR|CM_INV },
  2528.     { "transact",        LOGT, CM_ABR|CM_INV },
  2529.     { "transacti",       LOGT, CM_ABR|CM_INV },
  2530.     { "transactio",      LOGT, CM_ABR|CM_INV },
  2531.     { "transaction",     LOGT, CM_ABR|CM_INV },
  2532.     { "transaction-log", LOGT, 0 },
  2533.     { "transactions",    LOGT, CM_INV },
  2534. #endif /* TLOG */
  2535. #ifndef NOSPL
  2536.     { "write-file",      LOGW, 0 },
  2537. #endif /* NOSPL */
  2538.     { "", 0, 0 }
  2539. };
  2540. int ncls = (sizeof(clstab) / sizeof(struct keytab)) - 1;
  2541.  
  2542. /* SHOW command arguments */
  2543.  
  2544. #ifndef NOSHOW
  2545. struct keytab shotab[] = {
  2546. #ifndef NOSPL
  2547.     { "alarm",        SHALRM, 0 },
  2548.     { "arg",          SHARG, CM_INV|CM_ABR },
  2549.     { "arguments",    SHARG, 0 },
  2550.     { "args",         SHARG, CM_INV },
  2551.     { "arrays",       SHARR, 0 },
  2552. #endif /* NOSPL */
  2553.  
  2554. #ifndef NOCSETS
  2555.     { "associations", SHASSOC, 0 },
  2556. #endif /* NOCSETS */
  2557.  
  2558. #ifndef NOXFER
  2559.     { "attributes",   SHATT, 0 },
  2560. #endif /* NOXFER */
  2561.  
  2562. #ifdef CK_AUTHENTICATION
  2563.     { "authentication", SHOAUTH, CM_INV },
  2564. #endif /* CK_AUTHENTICATION */
  2565.  
  2566. #ifndef NOPUSH
  2567. #ifdef BROWSER
  2568.     { "browser",      SHBROWSE, CM_PSH|CM_LOC },
  2569. #endif /*  BROWSER */
  2570. #endif /* NOPUSH */
  2571.     { "cd",           SHCD, 0 },
  2572.     { "character-sets", SHCSE, 0 },
  2573.     { "cmd",          SHCMD, CM_INV },
  2574. #ifndef NOLOCAL
  2575.     { "com",          SHCOM, CM_INV|CM_ABR },
  2576.     { "comm",         SHCOM, CM_INV|CM_ABR },
  2577.     { "communications", SHCOM, 0 },
  2578. #endif /* NOLOCAL */
  2579.     { "command",      SHCMD, 0 },
  2580.     { "connection",   SHCONNX, 0 },
  2581. #ifdef CK_SPEED
  2582.     { "control-prefixing", SHCTL, 0 },
  2583. #endif /* CK_SPEED */
  2584. #ifdef CKLOGDIAL
  2585.     { "cx",           SHCONNX, CM_INV },
  2586. #endif /* CKLOGDIAL */
  2587. #ifndef NOSPL
  2588.     { "count",        SHCOU, 0 },
  2589. #endif /* NOSPL */
  2590.     { "d",            SHDIA, CM_INV|CM_ABR },
  2591. #ifdef VMS
  2592.     { "default",      SHDFLT, 0 },
  2593. #else
  2594.     { "default",      SHDFLT, CM_INV },
  2595. #endif /* VMS */
  2596. #ifndef NODIAL
  2597.     { "dial",         SHDIA, CM_LOC },
  2598. #endif /* NODIAL */
  2599.     { "double/ignore",SHDBL, 0 },
  2600. #ifndef NOPUSH
  2601. #ifndef NOFRILLS
  2602.     { "editor",       SHEDIT, CM_PSH },
  2603. #endif /*  NOFRILLS */
  2604. #endif /* NOPUSH */
  2605. #ifndef NOLOCAL
  2606.     { "escape",       SHESC, CM_LOC },
  2607. #endif /* NOLOCAL */
  2608.     { "exit",         SHEXI, 0 },
  2609.     { "extended-options", SHXOPT, CM_INV },
  2610.     { "features",     SHFEA, 0 },
  2611.     { "file",         SHFIL, 0 },
  2612. #ifndef NOLOCAL
  2613.     { "flow-control", SHOFLO, 0 },
  2614. #endif /* NOLOCAL */
  2615. #ifdef BROWSER
  2616.     { "ftp",          SHOFTP, CM_PSH|CM_LOC },
  2617. #else
  2618. #ifndef NOFTP
  2619. #ifndef SYSFTP
  2620. #ifdef TCPSOCKET
  2621.     { "ftp",          SHOFTP, 0 },    /* (built-in ftp) */
  2622. #endif /* TCPSOCKET */
  2623. #endif /* SYSFTP */
  2624. #endif /* NOFTP */
  2625. #endif /* BROWSER */
  2626. #ifndef NOSPL
  2627.     { "functions",    SHFUN, 0 },
  2628.     { "globals",      SHVAR, 0 },
  2629. #endif /* NOSPL */
  2630. #ifdef CK_RECALL
  2631.     { "history",      SHHISTORY, 0 },
  2632. #endif /* CK_RECALL */
  2633.     { "ignore/double",SHDBL, CM_INV },
  2634.     { "iksd",         SHOIKS, CM_INV },
  2635. #ifndef NOSPL
  2636.     { "input",        SHINP, 0 },
  2637. #endif /* NOSPL */
  2638. #ifndef NOSETKEY
  2639.     { "k",            SHKEY, CM_INV|CM_ABR },
  2640.     { "key",          SHKEY, 0 },
  2641. #ifndef NOKVERBS
  2642.     { "kverbs",       SHKVB, 0 },
  2643. #endif /* NOKVERBS */
  2644. #endif /* NOSETKEY */
  2645. #ifdef CK_LABELED
  2646.     { "labeled-file-info", SHLBL, 0 },
  2647. #endif /* CK_LABELED */
  2648. #ifndef NOCSETS
  2649.     { "languages",    SHLNG, 0 },
  2650. #endif /* NOCSETS */
  2651.     { "logs",         SHLOG, 0 },
  2652. #ifndef NOSPL
  2653.     { "macros",       SHMAC, 0 },
  2654. #endif /* NOSPL */
  2655. #ifndef NODIAL
  2656.     { "modem",        SHMOD, CM_LOC },
  2657. #else
  2658.     { "modem-signals",SHCOM, CM_INV|CM_LOC },
  2659. #endif /* NODIAL */
  2660. #ifndef NOLOCAL
  2661. #ifdef OS2MOUSE
  2662.     { "mouse",        SHMOU, CM_LOC },
  2663. #endif /* OS2MOUSE */
  2664. #endif /* NOLOCAL */
  2665. #ifdef NETCONN
  2666.     { "network",      SHNET, CM_LOC },
  2667. #else
  2668.     { "network",      SHNET, CM_INV|CM_LOC },
  2669. #endif /* NETCONN */
  2670.     { "options",      SHOPTS, 0 },
  2671. #ifndef NOSPL
  2672.     { "output",       SHOUTP, CM_INV },
  2673. #endif /* NOSPL */
  2674. #ifdef ANYX25
  2675. #ifndef IBMX25
  2676.     { "pad",          SHPAD,  CM_LOC },
  2677. #endif /* IBMX25 */
  2678. #endif /* ANYX25 */
  2679.     { "parameters",   SHPAR,  CM_INV },
  2680. #ifdef PATTERNS
  2681.     { "patterns",     SHOPAT, 0 },
  2682. #endif /* PATTERNS */
  2683.     { "printer",      SHPRT,  0 },
  2684. #ifdef CK_SPEED
  2685.     { "prefixing",    SHCTL,  CM_INV },
  2686. #endif /* CK_SPEED */
  2687. #ifndef NOXFER
  2688.     { "protocol",     SHPRO,  0 },
  2689. #endif /* NOXFER */
  2690. #ifndef NOSPL
  2691.     { "scripts",      SHSCR,  CM_LOC },
  2692. #endif /* NOSPL */
  2693.     { "send-list",    SHSFL,  0 },
  2694. #ifndef NOSERVER
  2695.     { "server",       SHSER,  0 },
  2696. #endif /* NOSERVER */
  2697. #ifndef NOSEXP
  2698.     { "sexpression",  SHSEXP, 0 },
  2699. #endif /* NOSEXP */
  2700. #ifdef ANYSSH
  2701.     { "ssh",          SHOSSH, 0 },
  2702. #endif /* ANYSSH */
  2703.     { "stack",        SHSTK,  0 },
  2704.     { "status",       SHSTA,  0 },
  2705. #ifdef STREAMING
  2706.     { "streaming",    SHOSTR, 0 },
  2707. #endif /* STREAMING */
  2708. #ifndef NOLOCAL
  2709. #ifdef OS2
  2710.     { "tabs",          SHTAB, CM_INV|CM_LOC },
  2711. #endif /* OS2 */
  2712. #ifdef CK_TAPI
  2713.     { "tapi",          SHTAPI, CM_LOC },
  2714.     { "tapi-comm",     SHTAPI_C, CM_INV|CM_LOC },
  2715.     { "tapi-location", SHTAPI_L, CM_INV|CM_LOC },
  2716.     { "tapi-modem",    SHTAPI_M, CM_INV|CM_LOC },
  2717. #endif /* CK_TAPI */
  2718.     { "tcp",           SHTCP,  CM_LOC },
  2719. #ifdef TNCODE
  2720.     { "tel",           SHTEL,  CM_INV|CM_ABR },
  2721.     { "telnet",        SHTEL,  0 },
  2722.     { "telopt",        SHTOPT, 0 },
  2723. #endif /* TNCODE */
  2724.     { "terminal",      SHTER,  CM_LOC },
  2725. #endif /* NOLOCAL */
  2726. #ifndef NOXMIT
  2727.     { "tr",            SHXMI, CM_INV|CM_ABR },
  2728.     { "tra",           SHXMI, CM_INV|CM_ABR },
  2729.     { "tran",          SHXMI, CM_INV|CM_ABR },
  2730.     { "trans",         SHXMI, CM_INV|CM_ABR },
  2731. #endif /* NOXMIT */
  2732. #ifndef NOXFER
  2733.     { "transfer",      SHOXFER, 0 },
  2734. #endif /* NOXFER */
  2735. #ifndef NOXMIT
  2736.     { "transmit",      SHXMI, 0 },
  2737. #endif /* NOXMIT */
  2738. #ifdef CK_TRIGGER
  2739.     { "trigger",       SHTRIG, CM_LOC },
  2740. #endif /* CK_TRIGGER */
  2741. #ifndef NOSETKEY
  2742. #ifndef NOKVERBS
  2743. #ifdef OS2
  2744.     { "udk",           SHUDK, CM_LOC },
  2745. #endif /* OS2 */
  2746. #endif /* NOKVERBS */
  2747. #endif /* NOSETKEY */
  2748. #ifndef NOSPL
  2749.     { "variables",     SHBUI, 0 },
  2750. #endif /* NOSPL */
  2751. #ifndef NOFRILLS
  2752.     { "versions",      SHVER, 0 },
  2753. #endif /* NOFRILLS */
  2754. #ifdef OS2
  2755.     { "vscrn",         SHVSCRN, CM_INV|CM_LOC },
  2756. #endif /* OS2 */
  2757.     { "xfer",          SHOXFER,  CM_INV },
  2758. #ifndef NOXMIT
  2759.     { "xmit",          SHXMI,    CM_INV },
  2760. #endif /* NOXMIT */
  2761.     { "", 0, 0 }
  2762. };
  2763. int nsho = (sizeof(shotab) / sizeof(struct keytab)) - 1;
  2764. #endif /* NOSHOW */
  2765.  
  2766. #ifdef ANYX25
  2767. #ifndef IBMX25
  2768. struct keytab padtab[] = {              /* PAD commands */
  2769.     { "clear",      XYPADL, 0 },
  2770.     { "interrupt",  XYPADI, 0 },
  2771.     { "reset",      XYPADR, 0 },
  2772.     { "status",     XYPADS, 0 }
  2773. };
  2774. int npadc = (sizeof(padtab) / sizeof(struct keytab));
  2775. #endif /* IBMX25 */
  2776. #endif /* ANYX25 */
  2777.  
  2778. #ifndef NOSERVER
  2779. static struct keytab kmstab[] = {
  2780.     { "both",    3, 0 },
  2781.     { "local",   1, 0 },
  2782.     { "remote",  2, 0 }
  2783. };
  2784.  
  2785. static struct keytab enatab[] = {    /* ENABLE commands */
  2786.     { "all",        EN_ALL,  0 },
  2787. #ifndef NOSPL
  2788.     { "as",         EN_ASG,  CM_INV|CM_ABR },
  2789.     { "asg",        EN_ASG,  CM_INV },
  2790.     { "assign",     EN_ASG,  0 },
  2791. #endif /* NOSPL */
  2792. #ifndef datageneral
  2793.     { "bye",        EN_BYE,  0 },
  2794. #endif /* datageneral */
  2795.     { "cd",         EN_CWD,  0 },
  2796. #ifdef ZCOPY
  2797.     { "copy",       EN_CPY,  0 },
  2798. #endif /* ZCOPY */
  2799.     { "cwd",        EN_CWD,  CM_INV },
  2800.     { "delete",     EN_DEL,  0 },
  2801.     { "directory",  EN_DIR,  0 },
  2802.     { "enable",     EN_ENA,  CM_INV },
  2803.     { "exit",       EN_XIT,  0 },
  2804.     { "finish",     EN_FIN,  0 },
  2805.     { "get",        EN_GET,  0 },
  2806.     { "host",       EN_HOS,  0 },
  2807.     { "mail",       EN_MAI,  0 },
  2808.     { "mkdir",      EN_MKD,  0 },
  2809. #ifndef NOSPL
  2810.     { "query",      EN_QUE,  0 },
  2811. #endif /* NOSPL */
  2812.     { "print",      EN_PRI,  0 },
  2813.     { "rename",     EN_REN,  0 },
  2814.     { "retrieve",   EN_RET,  CM_INV },
  2815.     { "rmdir",      EN_RMD,  0 },
  2816.     { "send",       EN_SEN,  0 },
  2817.     { "set",        EN_SET,  0 },
  2818.     { "space",      EN_SPA,  0 },
  2819.     { "type",       EN_TYP,  0 },
  2820.     { "who",        EN_WHO,  0 }
  2821. };
  2822. static int nena = (sizeof(enatab) / sizeof(struct keytab));
  2823. #endif /* NOSERVER */
  2824.  
  2825. struct keytab txtbin[] = {
  2826.     { "all",        2, 0 },
  2827.     { "binary",     1, 0 },
  2828.     { "text",       0, 0 }
  2829. };
  2830.  
  2831. #ifndef NOXFER
  2832. static struct keytab sndtab[] = {    /* SEND command options */
  2833.     { "/after",           SND_AFT, CM_ARG },
  2834. #ifndef NOSPL
  2835.     { "/array",           SND_ARR, CM_ARG },
  2836. #endif /* NOSPL */
  2837.     { "/as-name",         SND_ASN, CM_ARG },
  2838.     { "/b",               SND_BIN, CM_INV|CM_ABR },
  2839.     { "/before",          SND_BEF, CM_ARG },
  2840.     { "/binary",          SND_BIN, 0 },
  2841. #ifdef CALIBRATE
  2842.     { "/c",               SND_CMD, CM_INV|CM_ABR },
  2843.     { "/calibrate",       SND_CAL, CM_INV|CM_ARG },
  2844. #endif /* CALIBRATE */
  2845.     { "/command",         SND_CMD, CM_PSH },
  2846.     { "/delete",          SND_DEL, 0 },
  2847. #ifdef UNIXOROSK
  2848.     { "/dotfiles",        SND_DOT, 0 },
  2849. #endif /* UNIXOROSK */
  2850.     { "/except",          SND_EXC, CM_ARG },
  2851. #ifdef PIPESEND
  2852.     { "/filter",          SND_FLT, CM_ARG|CM_PSH },
  2853. #endif /* PIPESEND */
  2854.     { "/filenames",       SND_NAM, CM_ARG },
  2855. #ifdef CKSYMLINK
  2856.     { "/followlinks",      SND_LNK, 0 },
  2857. #endif /* CKSYMLINK */
  2858. #ifdef VMS
  2859.     { "/image",           SND_IMG, 0 },
  2860. #else
  2861.     { "/image",           SND_BIN, CM_INV },
  2862. #endif /* VMS */
  2863. #ifdef CK_LABELED
  2864.     { "/labeled",         SND_LBL, 0 },
  2865. #endif /* CK_LABELED */
  2866.     { "/larger-than",     SND_LAR, CM_ARG },
  2867.     { "/listfile",        SND_FIL, CM_ARG },
  2868. #ifndef NOFRILLS
  2869.     { "/mail",            SND_MAI, CM_ARG },
  2870. #endif /* NOFRILLS */
  2871. #ifdef CK_TMPDIR
  2872.     { "/move-to",         SND_MOV, CM_ARG },
  2873. #endif /* CK_TMPDIR */
  2874.     { "/nobackupfiles",   SND_NOB, 0 },
  2875. #ifdef UNIXOROSK
  2876.     { "/nodotfiles",      SND_NOD, 0 },
  2877. #endif /* UNIXOROSK */
  2878. #ifdef CKSYMLINK
  2879.     { "/nofollowlinks",      SND_NLK, 0 },
  2880. #endif /* CKSYMLINK */
  2881.     { "/not-after",       SND_NAF, CM_ARG },
  2882.     { "/not-before",      SND_NBE, CM_ARG },
  2883.     { "/pathnames",       SND_PTH, CM_ARG },
  2884.     { "/print",           SND_PRI, CM_ARG },
  2885. #ifdef CK_XYZ
  2886.     { "/protocol",        SND_PRO, CM_ARG },
  2887. #else
  2888.     { "/protocol",        SND_PRO, CM_ARG|CM_INV },
  2889. #endif /* CK_XYZ */
  2890.     { "/quiet",           SND_SHH, 0 },
  2891.     { "/recover",         SND_RES, 0 },
  2892. #ifdef RECURSIVE
  2893. /* Systems where we do recursion */
  2894.     { "/recursive",       SND_REC, 0 },
  2895. #else
  2896. #ifdef VMS
  2897. /* Systems that do recursion themselves without our assistance */
  2898. /* if we give them the right kind of wildcard */
  2899.     { "/recursive",       SND_REC, 0 },
  2900. #else
  2901. #ifdef datageneral
  2902.     { "/recursive",       SND_REC, 0 },
  2903. #else
  2904.     { "/recursive",       SND_REC, CM_INV },
  2905. #endif /* datageneral */
  2906. #endif /* VMS */
  2907. #endif /* RECURSIVE */
  2908.     { "/rename-to",       SND_REN, CM_ARG },
  2909.     { "/since",           SND_AFT, CM_INV|CM_ARG },
  2910.     { "/smaller-than",    SND_SMA, CM_ARG },
  2911.     { "/starting-at",     SND_STA, CM_ARG },
  2912. #ifndef NOFRILLS
  2913.     { "/su",              SND_ASN, CM_ARG|CM_INV|CM_ABR },
  2914.     { "/sub",             SND_ASN, CM_ARG|CM_INV|CM_ABR },
  2915.     { "/subject",         SND_ASN, CM_ARG },
  2916. #endif /* NOFRILLS */
  2917. #ifdef RECURSIVE
  2918.     { "/subdirectories",  SND_REC, CM_INV },
  2919. #endif /* RECURSIVE */
  2920.     { "/text",            SND_TXT, 0 },
  2921.     { "/transparent",     SND_XPA, 0 },
  2922.     { "/type",            SND_TYP, CM_ARG }
  2923. };
  2924. #define NSNDTAB sizeof(sndtab)/sizeof(struct keytab)
  2925. static int nsndtab = NSNDTAB;
  2926.  
  2927. #ifndef NOMSEND
  2928. static struct keytab msndtab[] = {    /* MSEND options */
  2929.     { "/after",           SND_AFT, CM_ARG },
  2930.     { "/before",          SND_BEF, CM_ARG },
  2931.     { "/binary",          SND_BIN, 0 },
  2932.     { "/delete",          SND_DEL, 0 },
  2933.     { "/except",          SND_EXC, CM_ARG },
  2934.     { "/filenames",       SND_NAM, CM_ARG },
  2935. #ifdef CKSYMLINK
  2936.     { "/followlinks",      SND_LNK, 0 },
  2937. #endif /* CKSYMLINK */
  2938. #ifdef VMS
  2939.     { "/image",           SND_IMG, 0 },
  2940. #else
  2941.     { "/image",           SND_BIN, CM_INV },
  2942. #endif /* VMS */
  2943. #ifdef CK_LABELED
  2944.     { "/labeled",         SND_LBL, 0 },
  2945. #endif /* CK_LABELED */
  2946.     { "/larger-than",     SND_LAR, CM_ARG },
  2947.     { "/list",            SND_FIL, CM_ARG },
  2948. #ifndef NOFRILLS
  2949.     { "/mail",            SND_MAI, CM_ARG },
  2950. #endif /* NOFRILLS */
  2951. #ifdef CK_TMPDIR
  2952.     { "/move-to",         SND_MOV, CM_ARG },
  2953. #endif /* CK_TMPDIR */
  2954. #ifdef CKSYMLINK
  2955.     { "/nofollowlinks",    SND_NLK, 0 },
  2956. #endif /* CKSYMLINK */
  2957.     { "/not-after",       SND_NAF, CM_ARG },
  2958.     { "/not-before",      SND_NBE, CM_ARG },
  2959.     { "/pathnames",       SND_PTH, CM_ARG },
  2960.     { "/print",           SND_PRI, CM_ARG },
  2961. #ifdef CK_XYZ
  2962.     { "/protocol",        SND_PRO, CM_ARG },
  2963. #endif /* CK_XYZ */
  2964.     { "/quiet",           SND_SHH, 0 },
  2965.     { "/recover",         SND_RES, 0 },
  2966.     { "/rename-to",       SND_REN, CM_ARG },
  2967.     { "/since",           SND_AFT, CM_INV|CM_ARG },
  2968.     { "/smaller-than",    SND_SMA, CM_ARG },
  2969.     { "/starting-at",     SND_STA, CM_ARG },
  2970. #ifndef NOFRILLS
  2971.     { "/subject",         SND_ASN, CM_ARG },
  2972. #endif /* NOFRILLS */
  2973.     { "/text",            SND_TXT, 0 },
  2974.     { "/transparent",     SND_XPA, 0 },
  2975.     { "/type",            SND_TYP, CM_ARG }
  2976. };
  2977. #define NMSNDTAB sizeof(msndtab)/sizeof(struct keytab)
  2978. static int nmsndtab = NMSNDTAB;
  2979. #endif /* NOMSEND */
  2980. #endif /* NOXFER */
  2981.  
  2982. /* CONNECT command switches */
  2983.  
  2984. #define CONN_II  0    /* Idle interval */
  2985. #define CONN_IS  1    /* Idle string */
  2986. #define CONN_IL  2    /* Idle limit */
  2987. #define CONN_NV  3    /* Non-Verbose */
  2988. #define CONN_TL  4    /* Time limit */
  2989. #define CONN_TS  5    /* Trigger string */
  2990. #define CONN_AS  6    /* Asynchronous */
  2991. #define CONN_SY  7    /* Synchronous */
  2992. #define CONN_MAX 7    /* Number of CONNECT switches */
  2993.  
  2994. #ifndef NOLOCAL
  2995. static struct keytab conntab[] = {
  2996. #ifdef OS2
  2997.     { "/asynchronous",    CONN_AS, CM_INV },
  2998. #endif /* OS2 */
  2999. #ifdef XLIMITS
  3000.     { "/idle-interval",   CONN_II, CM_ARG },
  3001.     { "/idle-limit",      CONN_IL, CM_ARG },
  3002.     { "/idle-string",     CONN_IS, CM_ARG },
  3003.     { "/quietly",         CONN_NV, CM_INV }, 
  3004. #else
  3005.     { "/quietly",         CONN_NV, 0 },
  3006. #endif /* XLIMITS */
  3007. #ifdef OS2
  3008.     { "/synchronous",     CONN_SY, CM_INV },
  3009. #endif /* OS2 */
  3010. #ifdef XLIMITS
  3011.     { "/time-limit",      CONN_TL, CM_ARG },
  3012. #endif /* XLIMITS */
  3013. #ifdef CK_TRIGGER
  3014.     { "/trigger",         CONN_TS, CM_ARG },
  3015. #endif /* CK_TRIGGER */
  3016.     { "",0,0 }
  3017. };
  3018. #define NCONNTAB sizeof(conntab)/sizeof(struct keytab)
  3019. static int nconntab = NCONNTAB;
  3020. #endif /* NOLOCAL */
  3021.  
  3022. #ifndef NOXFER
  3023. static struct keytab stattab[] = {    /* STATISTICS command switches */
  3024.     { "/brief",   1, 0 },
  3025.     { "/verbose", 0, 0 }
  3026. };
  3027. #endif /* NOXFER */
  3028.  
  3029. #ifndef NOSPL
  3030. #ifdef COMMENT
  3031. struct mtab mactab[MAC_MAX] = {        /* Preinitialized macro table */
  3032.     { NULL, NULL, 0 }
  3033. };
  3034. #else
  3035. struct mtab *mactab;            /* Dynamically allocated macro table */
  3036. #endif /* COMMENT */
  3037. int nmac = 0;
  3038.  
  3039. struct keytab mackey[MAC_MAX];        /* Macro names as command keywords */
  3040. #endif /* NOSPL */
  3041.  
  3042. #ifndef NOSPL
  3043. #ifdef  OS2
  3044. struct keytab beeptab[] = {        /* Beep options */
  3045.     { "error", BP_FAIL, 0 },
  3046.     { "information", BP_NOTE, 0 },
  3047.     { "warning", BP_WARN, 0 }
  3048. };
  3049. int nbeeptab = sizeof(beeptab)/sizeof(struct keytab);
  3050.  
  3051. /* CLEAR COMMMAND-SCREEN options */
  3052.  
  3053. #define CLR_C_ALL 0
  3054. #define CLR_C_BOL 1
  3055. #define CLR_C_BOS 2
  3056. #define CLR_C_EOL 3
  3057. #define CLR_C_EOS 4
  3058. #define CLR_C_LIN 5
  3059. #define CLR_C_SCR 6
  3060.  
  3061. struct keytab clrcmdtab[] = {
  3062.     { "all",        CLR_C_ALL, 0 },
  3063.     { "bol",        CLR_C_BOL, 0 },
  3064.     { "bos",        CLR_C_BOS, 0 },
  3065.     { "eol",        CLR_C_EOL, 0 },
  3066.     { "eos",        CLR_C_EOS, 0 },
  3067.     { "line",       CLR_C_LIN, 0 },
  3068.     { "scrollback", CLR_C_SCR, 0 }
  3069. };
  3070. int nclrcmd = sizeof(clrcmdtab)/sizeof(struct keytab);
  3071. #endif /* OS2 */
  3072. #endif /* NOSPL */
  3073.  
  3074. #ifdef COMMENT
  3075. /* Not used at present */
  3076. static struct keytab pagetab[] = {
  3077.     { "/more",   1, CM_INV },
  3078.     { "/nopage", 0, 0 },
  3079.     { "/page",   1, 0 }
  3080. };
  3081. int npagetab = sizeof(pagetab)/sizeof(struct keytab);
  3082. #endif /* COMMENT */
  3083.  
  3084. #define TYP_NOP  0            /* /NOPAGE */
  3085. #define TYP_PAG  1            /* /PAGE */
  3086. #define TYP_HEA  2            /* /HEAD:n */
  3087. #define TYP_TAI  3            /* /TAIL:n */
  3088. #define TYP_PAT  4            /* /MATCH:pattern */
  3089. #define TYP_WID  5            /* /WIDTH:cols */
  3090. #define TYP_COU  6            /* /COUNT */
  3091. #define TYP_OUT  7            /* /OUTPUT:file */
  3092. #define TYP_PFX  8            /* /PREFIX:string */
  3093. #ifdef UNICODE
  3094. #define TYP_XIN  9            /* /TRANSLATE-FROM:charset */
  3095. #define TYP_XUT 10            /* /TRANSLATE-TO:charset */
  3096. #define TYP_XPA 11            /* /TRANSPARENT */
  3097. #endif /* UNICODE */
  3098. #define TYP_NUM 12            /* /NUMBER */
  3099.  
  3100. static struct keytab typetab[] = {    /* TYPE command switches */
  3101.     { "/count",          TYP_COU, 0 },
  3102. #ifdef UNICODE
  3103.     { "/character-set",  TYP_XIN, CM_ARG },
  3104. #endif /* UNICODE */
  3105.     { "/head",           TYP_HEA, CM_ARG },
  3106.     { "/match",          TYP_PAT, CM_ARG },
  3107. #ifdef CK_TTGWSIZ
  3108.     { "/more",           TYP_PAG, CM_INV },
  3109.     { "/nopage",         TYP_NOP, 0 },
  3110.     { "/number",         TYP_NUM, 0 },
  3111.     { "/output",         TYP_OUT, CM_ARG },
  3112.     { "/page",           TYP_PAG, 0 },
  3113. #endif /* CK_TTGWSIZ */
  3114.     { "/prefix",         TYP_PFX, CM_ARG },
  3115.     { "/tail",           TYP_TAI, CM_ARG },
  3116. #ifdef UNICODE
  3117.     { "/translate-to",   TYP_XUT, CM_ARG },
  3118.     { "/transparent",    TYP_XPA, 0 },
  3119. #endif /* UNICODE */
  3120.     { "/width",          TYP_WID, CM_ARG },
  3121. #ifdef UNICODE
  3122.     { "/xlate-to",       TYP_XUT, CM_INV|CM_ARG },
  3123. #endif /* UNICODE */
  3124.     { "", 0, 0 }
  3125. };
  3126. int ntypetab = sizeof(typetab)/sizeof(struct keytab) - 1;
  3127.  
  3128. int typ_page = -1;            /* TYPE /[NO]PAGE default */
  3129. int typ_wid  = -1;
  3130.  
  3131. #ifndef NOSPL
  3132. #define TRA_ALL 999            /* TRACE command */
  3133. #define TRA_ASG 0
  3134. #define TRA_CMD 1
  3135.  
  3136. int tra_asg = 0;
  3137. int tra_cmd = 0;
  3138.  
  3139. static struct keytab tracetab[] = {    /* TRACE options */
  3140.     { "all",            TRA_ALL, 0 },
  3141.     { "assignments",    TRA_ASG, 0 },
  3142.     { "command-level",  TRA_CMD, 0 }
  3143. };
  3144. static int ntracetab = sizeof(tracetab)/sizeof(struct keytab);
  3145. #endif /* NOSPL */
  3146.  
  3147. #ifndef NOSHOW
  3148. VOID
  3149. showtypopts() {
  3150.     printf(" TYPE ");
  3151.     if (typ_page > -1) {
  3152.     prtopt(&optlines,typ_page ? "/PAGE" : "/NOPAGE");
  3153.     } else
  3154.       prtopt(&optlines,"(no options set)");
  3155.     if (typ_wid > -1) {
  3156.     ckmakmsg(tmpbuf,TMPBUFSIZ,"/WIDTH:",ckitoa(typ_wid),NULL,NULL);
  3157.     prtopt(&optlines,tmpbuf);
  3158.     }
  3159.     prtopt(&optlines,"");
  3160. }
  3161. #endif /* NOSHOW */
  3162.  
  3163. int
  3164. settypopts() {                /* Set TYPE option defaults */
  3165.     int xp = -1;
  3166.     int c, getval;
  3167.     while (1) {
  3168.     if ((y = cmswi(typetab,ntypetab,"Switch","",xxstring)) < 0) {
  3169.         if (y == -3)
  3170.           break;
  3171.         else
  3172.           return(y);
  3173.     }
  3174.     c = cmgbrk();
  3175.     if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  3176.         printf("?This switch does not take an argument\n");
  3177.         return(-9);
  3178.     }
  3179.     switch (y) {
  3180.       case TYP_NOP: xp = 0; break;
  3181.       case TYP_PAG: xp = 1; break;
  3182.       case TYP_WID:
  3183.         if (getval)
  3184.           if ((x = cmnum("Column at which to truncate",
  3185.                  ckitoa(cmd_cols),10,&y,xxstring)) < 0)
  3186.         return(x);
  3187.         typ_wid = y;
  3188.         break;
  3189.  
  3190.           default:
  3191.         printf("?Sorry, this option can not be set\n");
  3192.         return(-9);
  3193.     }
  3194.     }
  3195.     if ((x = cmcfm()) < 0)        /* Get confirmation */
  3196.       return(x);
  3197.     if (xp > -1) typ_page = xp;        /* Confirmed, save defaults */
  3198.     return(success = 1);
  3199. }
  3200.  
  3201. /* Forward declarations of functions local to this module */
  3202.  
  3203. #ifdef UNIX
  3204. _PROTOTYP (int douchmod, ( void ) );
  3205. #endif /* UNIX */
  3206. #ifdef CKPURGE
  3207. _PROTOTYP (int dopurge,  ( void ) );
  3208. #endif /* CKPURGE */
  3209. #ifndef NOSPL
  3210. _PROTOTYP (int doundef,  ( int  ) );
  3211. _PROTOTYP (int doask,    ( int  ) );
  3212. _PROTOTYP (int dodef,    ( int  ) );
  3213. _PROTOTYP (int doelse,   ( void ) );
  3214. _PROTOTYP (int dofor,    ( void ) );
  3215. _PROTOTYP (int doincr,   ( int  ) );
  3216. #endif /* NOSPL  */
  3217. #ifndef NODIAL
  3218. _PROTOTYP (int dodial,   ( int  ) );
  3219. #endif /* NODIAL */
  3220. _PROTOTYP (int dodel,    ( void ) );
  3221. _PROTOTYP (int dopaus,   ( int  ) );
  3222. #ifndef NOPUSH
  3223. #ifdef TCPSOCKET
  3224. _PROTOTYP (int doping,   ( void ) );
  3225. _PROTOTYP (int doftp,    ( void ) );
  3226. #endif /* TCPSOCKET */
  3227. #endif /* NOPUSH */
  3228. #ifndef NORENAME
  3229. #ifndef NOFRILLS
  3230. _PROTOTYP (int dorenam,  ( void ) );
  3231. #endif /* NOFRILLS */
  3232. #endif /* NORENAME */
  3233. #ifdef ZCOPY
  3234. _PROTOTYP (int docopy,   ( void ) );
  3235. #endif /* ZCOPY */
  3236. #ifdef CK_REXX
  3237. _PROTOTYP (int dorexx,   ( void ) );
  3238. #endif /* CK_REXX */
  3239.  
  3240. #ifdef TNCODE
  3241. static struct keytab telcmd[] = {
  3242.     { "abort", TN_ABORT, CM_INV },    /* Emotionally toned - don't show */
  3243.     { "ao",    TN_AO,    0 },
  3244.     { "ayt",   TN_AYT,   0 },
  3245.     { "break", BREAK,    0 },
  3246.     { "cancel",TN_ABORT, 0 },
  3247.     { "dmark", TN_DM,    0 },
  3248.     { "do",    DO,       0 },
  3249.     { "dont",  DONT,     0 },
  3250.     { "ec",    TN_EC,    0 },
  3251.     { "el",    TN_EL,    0 },
  3252.     { "eof",   TN_EOF,   0 },
  3253.     { "eor",   TN_EOR,   0 },
  3254. #ifdef CK_KERBEROS
  3255. #ifdef KRB5
  3256. #define TN_FWD 1
  3257.     { "forward", TN_FWD, CM_INV },
  3258. #endif /* KRB5 */
  3259. #endif /* CK_KERBEROS */
  3260.     { "ga",    TN_GA,    0 },
  3261.     { "ip",    TN_IP,    0 },
  3262.     { "nop",   TN_NOP,   0 },
  3263.     { "sak",   TN_SAK,   CM_INV },
  3264.     { "sb",    SB,       0 },
  3265.     { "se",    SE,       0 },
  3266.     { "susp",  TN_SUSP,  0 },
  3267.     { "will",  WILL,     0 },
  3268.     { "wont",  WONT,     0 }
  3269. };
  3270. static int ntelcmd = (sizeof(telcmd) / sizeof(struct keytab));
  3271.  
  3272. static struct keytab tnopts[] = {
  3273. #ifdef CK_AUTHENTICATION
  3274.     { "auth",   TELOPT_AUTHENTICATION,   0 },
  3275. #else
  3276.     { "auth",   TELOPT_AUTHENTICATION,   CM_INV },
  3277. #endif /* CK_AUTHENTICATION */
  3278.     { "binary", TELOPT_BINARY, 0 },
  3279. #ifdef TN_COMPORT
  3280.     { "c",      TELOPT_COMPORT, CM_INV|CM_ABR},
  3281.     { "co",     TELOPT_COMPORT, CM_INV|CM_ABR},
  3282.     { "com",    TELOPT_COMPORT, CM_INV|CM_ABR},
  3283.     { "com-port-control", TELOPT_COMPORT, 0 },
  3284.     { "comport-control", TELOPT_COMPORT, CM_INV},
  3285. #else  /* TN_COMPORT */
  3286.     { "com-port-control", TELOPT_COMPORT, CM_INV },
  3287.     { "comport-control", TELOPT_COMPORT, CM_INV},
  3288. #endif /* TN_COMPORT */
  3289.     { "echo", TELOPT_ECHO, 0 },
  3290. #ifdef CK_ENCRYPTION
  3291.     { "encrypt", TELOPT_ENCRYPTION, 0 },
  3292. #else
  3293.     { "encrypt", TELOPT_ENCRYPTION, CM_INV },
  3294. #endif /* CK_ENCRYPTION */
  3295. #ifdef CK_FORWARD_X
  3296.     { "forward-x", TELOPT_FORWARD_X, 0 },
  3297. #else
  3298.     { "forward-x", TELOPT_FORWARD_X, CM_INV },
  3299. #endif /* CK_FORWARD_X */
  3300. #ifdef IKS_OPTION
  3301.     { "kermit", TELOPT_KERMIT, 0 },
  3302. #else
  3303.     { "kermit", TELOPT_KERMIT, CM_INV },
  3304. #endif /* IKS_OPTION */
  3305.     { "lflow",  TELOPT_LFLOW, CM_INV },
  3306.     { "logout", TELOPT_LOGOUT, CM_INV },
  3307. #ifdef CK_NAWS
  3308.     { "naws", TELOPT_NAWS, 0 },
  3309. #else
  3310.     { "naws", TELOPT_NAWS, CM_INV },
  3311. #endif /* CK_NAWS */
  3312. #ifdef CK_ENVIRONMENT
  3313.     { "new-environment", TELOPT_NEWENVIRON,  0 },
  3314. #else
  3315.     { "new-environment", TELOPT_NEWENVIRON,  CM_INV },
  3316. #endif /* CK_ENVIRONMENT */
  3317.     { "pragma-heartbeat",TELOPT_PRAGMA_HEARTBEAT,  CM_INV },
  3318.     { "pragma-logon",    TELOPT_PRAGMA_LOGON,  CM_INV },
  3319.     { "pragma-sspi",     TELOPT_SSPI_LOGON,  CM_INV },
  3320.     { "sak",   TELOPT_IBM_SAK, CM_INV },
  3321. #ifdef CK_SNDLOC
  3322.     { "send-location",   TELOPT_SNDLOC,  0 },
  3323. #else
  3324.     { "send-location",   TELOPT_SNDLOC,  CM_INV },
  3325. #endif /* CK_SNDLOC */
  3326.     { "sga", TELOPT_SGA, 0 },
  3327. #ifdef CK_SSL
  3328.     { "start-tls",       TELOPT_START_TLS,  0 },
  3329. #else
  3330.     { "start-tls",       TELOPT_START_TLS,  CM_INV },
  3331. #endif /* CK_SSL */
  3332.     { "ttype", TELOPT_TTYPE, 0 },
  3333. #ifdef CK_ENVIRONMENT
  3334.     { "xdisplay-location", TELOPT_XDISPLOC, 0 },
  3335. #else
  3336.     { "xdisplay-location", TELOPT_XDISPLOC, CM_INV },
  3337. #endif /* CK_ENVIRONMENT */
  3338.     { "", 0, 0 }
  3339. };
  3340. static int ntnopts = (sizeof(tnopts) / sizeof(struct keytab)) - 1;
  3341.  
  3342. static struct keytab tnsbopts[] = {
  3343. #ifdef CK_NAWS
  3344.     { "naws", TELOPT_NAWS, 0 },
  3345. #endif /* CK_NAWS */
  3346.     { "", 0, 0 }
  3347. };
  3348. static int ntnsbopts = (sizeof(tnsbopts) / sizeof(struct keytab)) - 1;
  3349. #endif /* TNCODE */
  3350.  
  3351. #ifdef TCPSOCKET
  3352. #ifndef NOPUSH
  3353. #ifdef SYSFTP
  3354. int
  3355. doftp() {                /* (External) FTP command */
  3356.     char *p, *f;            /* (See doxftp() for internal one) */
  3357.     int x;
  3358.  
  3359.     if (network)            /* If we have a current connection */
  3360.       ckstrncpy(line,ttname,LINBUFSIZ);    /* get the host name */
  3361.     else *line = '\0';            /* as default host */
  3362.     for (p = line; *p; p++)        /* Remove ":service" from end. */
  3363.       if (*p == ':') { *p = '\0'; break; }
  3364.     if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
  3365.       return(x);
  3366.     if (nopush) {
  3367.         printf("?Sorry, FTP command disabled\n");
  3368.         return(success = 0);
  3369.     }
  3370. /* Construct FTP command */
  3371. #ifdef VMS
  3372. #ifdef MULTINET                /* TGV MultiNet */
  3373.     ckmakmsg(line,LINBUFSIZ,"multinet ftp ",s,NULL,NULL);
  3374. #else
  3375.     ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
  3376. #endif /* MULTINET */
  3377. #else                    /* Not VMS */
  3378. #ifdef OS2ORUNIX
  3379. #ifndef NOFTP
  3380.     f = ftpapp;
  3381.     if (!f) f = "";
  3382.     if (!f[0]) f = "ftp";
  3383.     ckmakmsg(line,LINBUFSIZ,f," ",s,NULL);
  3384. #ifdef OS2
  3385.     p = line + strlen(ftpapp);
  3386.     while (p != line) {
  3387.         if (*p == '/') *p = '\\';
  3388.         p--;
  3389.     }
  3390. #endif /* OS2 */
  3391. #else /* NOFTP */
  3392.     ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
  3393. #endif /* NOFTP */
  3394. #else /* OS2ORUNIX */
  3395.     ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
  3396. #endif /* OS2ORUNIX */
  3397. #endif /* VMS */
  3398.     conres();                /* Make console normal  */
  3399. #ifdef DEC_TCPIP
  3400.     printf("\n");            /* Prevent prompt-stomping */
  3401. #endif /* DEC_TCPIP */
  3402.     x = zshcmd(line);
  3403.     concb((char)escape);
  3404.     return(success = x);
  3405. }
  3406. #endif /* SYSFTP */
  3407.  
  3408. int
  3409. doping() {                /* PING command */
  3410.     char *p;                /* just runs ping program */
  3411.     int x;
  3412.  
  3413.     if (network)            /* If we have a current connection */
  3414.       ckstrncpy(line,ttname,LINBUFSIZ);    /* get the host name */
  3415.     else *line = '\0';            /* as default host to be pinged. */
  3416.     for (p = line; *p; p++)        /* Remove ":service" from end. */
  3417.       if (*p == ':') { *p = '\0'; break; }
  3418.     if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
  3419.       return(x);
  3420.     if (nopush) {
  3421.         printf("?Sorry, PING command disabled\n");
  3422.         return(success = 0);
  3423.     }
  3424.  
  3425.     /* Construct PING command */
  3426. #ifdef VMS
  3427. #ifdef MULTINET                /* TGV MultiNet */
  3428.     ckmakmsg(line,LINBUFSIZ,"multinet ping ",s," /num=1",NULL);
  3429. #else
  3430.     ckmakmsg(line,LINBUFSIZ,"ping ",s," 56 1",NULL); /* Other VMS TCP/IP's */
  3431. #endif /* MULTINET */
  3432. #else                    /* Not VMS */
  3433.     ckmakmsg(line,LINBUFSIZ,"ping ",s,NULL,NULL);
  3434. #endif /* VMS */
  3435.     conres();                /* Make console normal  */
  3436. #ifdef DEC_TCPIP
  3437.     printf("\n");            /* Prevent prompt-stomping */
  3438. #endif /* DEC_TCPIP */
  3439.     x = zshcmd(line);
  3440.     concb((char)escape);
  3441.     return(success = x);
  3442. }
  3443. #endif /* NOPUSH */
  3444. #endif /* TCPSOCKET */
  3445.  
  3446. static VOID
  3447. doend(x) int x; {
  3448. #ifndef NOSPL
  3449.     /* Pop from all FOR/WHILE/XIF/SWITCH's */
  3450.     debug(F101,"doend maclvl 1","",maclvl);
  3451.     while ((maclvl > 0) &&
  3452.        (m_arg[maclvl-1][0]) &&
  3453.        (cmdstk[cmdlvl].src == CMD_MD) &&
  3454.        (!strncmp(m_arg[maclvl-1][0],"_xif",4) ||
  3455.         !strncmp(m_arg[maclvl-1][0],"_for",4) ||
  3456.         !strncmp(m_arg[maclvl-1][0],"_whi",4) ||
  3457.         !strncmp(m_arg[maclvl-1][0],"_swi",4))) {
  3458.     debug(F110,"END popping",m_arg[maclvl-1][0],0);
  3459.     dogta(XXPTA);            /* Put args back */
  3460.     popclvl();            /* Pop up two levels */
  3461.     popclvl();
  3462.     debug(F101,"doend maclvl 2","",maclvl);
  3463.     }
  3464.     if (maclvl > -1) {
  3465.     if (mrval[maclvl])        /* Free previous retval if any */
  3466.       free(mrval[maclvl]);
  3467.     mrval[maclvl] = malloc(16);    /* Room for up to 15 digits */
  3468.     if (mrval[maclvl])        /* Record current retval */
  3469.       ckmakmsg(mrval[maclvl],16,ckitoa(x),NULL,NULL,NULL);
  3470.     }
  3471. #endif /* NOSPL */
  3472.     popclvl();                /* Now pop out of macro or TAKE file */
  3473. #ifndef NOSPL
  3474. #ifdef DEBUG
  3475.     if (deblog) {
  3476.     debug(F101,"END maclvl 3","",maclvl);
  3477.     debug(F111,"END mrval[maclvl]",mrval[maclvl],maclvl);
  3478.     debug(F111,"END mrval[maclvl+1]",mrval[maclvl+1],maclvl+1);
  3479.     }
  3480. #endif /* DEBUG */
  3481. #endif /* NOSPL */
  3482. }
  3483.  
  3484. #ifdef CKROOT
  3485. int
  3486. dochroot() {
  3487.     if ((x = cmdir("Name of new root directory","",&s,xxstring)) < 0) {
  3488.     if (x == -3) {
  3489.         printf("?Directory name required\n");
  3490.         return(-9);
  3491.     }
  3492.     return(x);
  3493.     }
  3494.     ckstrncpy(line,s,LINBUFSIZ);
  3495.     s = line;
  3496.     if ((x = cmcfm()) < 0) return(x);
  3497.     s = brstrip(s);
  3498.     x = zsetroot(s);
  3499.     if (x < 0) {
  3500.     char * m = NULL;
  3501.     switch (x) {
  3502.       case -1:
  3503.       case -2: m = "Not a directory"; break;
  3504.       case -3: m = "Internal error"; break;
  3505.       case -4: m = "Access denied"; break;
  3506.       case -5: m = "Off limits"; break;
  3507.     }
  3508.     if (m) printf("%s: \"%s\"\n", m, s);
  3509.     return(m ? -9 : -2);
  3510.     } else {
  3511.     nopush = 1;
  3512.     return(success = 1);
  3513.     }
  3514. }
  3515. #endif /* CKROOT */
  3516.  
  3517. #ifndef NOXFER
  3518. static char * asnbuf = NULL;        /* As-name buffer pointer */
  3519.  
  3520. char sndxnam[] = { "_array_x_" };    /* (with replaceable x!) */
  3521.  
  3522. /*
  3523.   The new SEND command, replacing BSEND, CSEND, PSEND, etc etc.
  3524.   Call with cx = top-level keyword value.  Returns:
  3525.     < 0  On parse error.
  3526.     0    On other type of failure (e.g. requested operation not allowed).
  3527.     1    On success with sstate set to 's' so protocol will begin.
  3528. */
  3529.  
  3530. /*  D O X S E N D  --  Parse SEND and related commands with switches  */
  3531.  
  3532. int
  3533. doxsend(cx) int cx; {
  3534.     int c, i, n, wild, confirmed = 0;    /* Workers */
  3535.     int x, y;                /* of the world... */
  3536.     int getval = 0;            /* Whether to get switch value */
  3537.     extern char * snd_move;        /* Directory to move sent files to */
  3538.     extern char * snd_rename;        /* What to rename sent files to */
  3539.     extern char * filefile;        /* File containing filenames to send */
  3540.     extern int xfiletype;        /* Send only text (or binary) files */
  3541.     extern struct keytab pathtab[];    /* PATHNAMES option keywords */
  3542.     extern int npathtab;        /* How many of them */
  3543.     extern int recursive;        /* Recursive directory traversal */
  3544.     extern int rprintf;            /* REMOTE PRINT flag */
  3545.     extern int fdispla;            /* TRANSFER DISPLAY setting */
  3546.     extern int skipbup;            /* Skip backup files when sending */
  3547.     struct stringint {            /* Temporary array for switch values */
  3548.     char * sval;
  3549.     int ival;
  3550.     } pv[SND_MAX+1];
  3551.     struct FDB sf, sw, fl, cm;        /* FDBs for each parse function */
  3552.     int mlist = 0;            /* Flag for MSEND or MMOVE */
  3553.     char * m;                /* For making help messages */
  3554.     extern struct keytab protos[];    /* File transfer protocols */
  3555.     extern int xfrxla, g_xfrxla, nprotos;
  3556.     extern char sndbefore[], sndafter[], *sndexcept[]; /* Selection criteria */
  3557.     extern char sndnbefore[], sndnafter[];
  3558.     extern long sndsmaller, sndlarger, calibrate;
  3559. #ifndef NOSPL
  3560.     int range[2];            /* Array range */
  3561.     char ** ap = NULL;            /* Array pointer */
  3562.     int arrayx = -1;            /* Array index */
  3563. #endif /* NOSPL */
  3564.  
  3565. #ifdef NEWFTP
  3566.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) {
  3567.     if (cx == XXMAI) {
  3568.         printf("?Sorry, No MAIL with FTP\n");
  3569.         return(-9);
  3570.     }
  3571.     return(doftpput(cx,0));
  3572.     }
  3573. #endif /* NEWFTP */
  3574.  
  3575.     for (i = 0; i <= SND_MAX; i++) {    /* Initialize switch values */
  3576.     pv[i].sval = NULL;        /* to null pointers */
  3577.     pv[i].ival = -1;        /* and -1 int values */
  3578.     }
  3579. #ifndef NOSPL
  3580.     range[0] = -1;
  3581.     range[1] = -1;
  3582.     sndxin = -1;            /* Array index */
  3583. #endif /* NOSPL */
  3584.     sndarray = NULL;            /* Array pointer */
  3585.  
  3586. #ifdef UNIXOROSK
  3587.     g_matchdot = matchdot;        /* Match dot files */
  3588. #endif /* UNIXOROSK */
  3589.     g_recursive = recursive;        /* Recursive sending */
  3590.     recursive = 0;            /* Save global value, set local */
  3591.     debug(F101,"xsend entry fncnv","",fncnv);
  3592.  
  3593.     /* Preset switch values based on top-level command that called us */
  3594.  
  3595.     switch (cx) {
  3596.       case XXMSE:            /* MSEND */
  3597.     mlist = 1; break;
  3598.       case XXCSEN:            /* CSEND */
  3599.     pv[SND_CMD].ival = 1; break;
  3600.       case XXMMOVE:            /* MMOVE */
  3601.     mlist = 1;
  3602.       case XXMOVE:            /* MOVE */
  3603.     pv[SND_DEL].ival = 1; break;
  3604.       case XXRSEN:            /* RESEND */
  3605.     pv[SND_BIN].ival = 1;        /* Implies /BINARY */
  3606.     pv[SND_RES].ival = 1; break;
  3607.       case XXMAI:            /* MAIL */
  3608.     pv[SND_MAI].ival = 1; break;
  3609.     }
  3610.  
  3611.     /* Set up chained parse functions... */
  3612.  
  3613.     cmfdbi(&sw,                /* First FDB - command switches */
  3614.        _CMKEY,            /* fcode */
  3615.        "Filename, or switch",    /* hlpmsg */
  3616.        "",                /* default */
  3617.        "",                /* addtl string data */
  3618. #ifdef NOMSEND
  3619.        nsndtab,            /* addtl numeric data 1: tbl size */
  3620. #else
  3621.        mlist ? nmsndtab : nsndtab,    /* addtl numeric data 1: tbl size */
  3622. #endif /* NOMSEND */
  3623.        4,                /* addtl numeric data 2: 4 = cmswi */
  3624.        xxstring,            /* Processing function */
  3625. #ifdef NOMSEND
  3626.        sndtab,            /* Keyword table */
  3627. #else
  3628.        mlist ? msndtab : sndtab,
  3629. #endif /* NOMSEND */
  3630.        &sf                /* Pointer to next FDB */
  3631.        );
  3632.     cmfdbi(&sf,                /* 2nd FDB - file to send */
  3633.        _CMIFI,            /* fcode */
  3634.        "File(s) to send",        /* hlpmsg */
  3635.        "",                /* default */
  3636.        "",                /* addtl string data */
  3637.        nolinks,            /* addtl numeric data 1 */
  3638.        0,                /* addtl numeric data 2 */
  3639.        xxstring,
  3640.        NULL,
  3641.        mlist ? &cm : &fl
  3642.        );
  3643.     cmfdbi(&fl,                /* 3rd FDB - command to send from */
  3644.        _CMFLD,            /* fcode */
  3645.        "Command",            /* hlpmsg */
  3646.        "",                /* default */
  3647.        "",                /* addtl string data */
  3648.        0,                /* addtl numeric data 1 */
  3649.        0,                /* addtl numeric data 2 */
  3650.        xxstring,
  3651.        NULL,
  3652.        &cm
  3653.        );
  3654.     cmfdbi(&cm,                /* 4th FDB - Confirmation */
  3655.        _CMCFM,            /* fcode */
  3656.        "",                /* hlpmsg */
  3657.        "",                /* default */
  3658.        "",                /* addtl string data */
  3659.        0,                /* addtl numeric data 1 */
  3660.        0,                /* addtl numeric data 2 */
  3661.        NULL,
  3662.        NULL,
  3663.        NULL
  3664.        );
  3665.  
  3666.     while (1) {                /* Parse 0 or more switches */
  3667.     x = cmfdb(&sw);            /* Parse something */
  3668.     debug(F101,"xsend cmfdb","",x);
  3669.     if (x < 0)            /* Error */
  3670.       goto xsendx;            /* or reparse needed */
  3671.     if (cmresult.fcode != _CMKEY)    /* Break out if not a switch */
  3672.       break;
  3673. /*
  3674.   They gave a switch, but let's see how they terminated it.
  3675.   If they ended it with : or =, then we must parse a value.
  3676.   If they ended it with anything else, then we must NOT parse a value.
  3677. */
  3678.     c = cmgbrk();            /* Get break character */
  3679.     getval = (c == ':' || c == '='); /* to see how they ended the switch */
  3680.     if (getval && !(cmresult.kflags & CM_ARG)) {
  3681.         printf("?This switch does not take arguments\n");
  3682.         x = -9;
  3683.         goto xsendx;
  3684.     }
  3685.     if (!getval && (cmgkwflgs() & CM_ARG)) {
  3686.         printf("?This switch requires an argument\n");
  3687.         x = -9;
  3688.         goto xsendx;
  3689.     }
  3690.     n = cmresult.nresult;        /* Numeric result = switch value */
  3691.     debug(F101,"xsend switch","",n);
  3692.  
  3693.     switch (n) {            /* Process the switch */
  3694.       case SND_CMD:            /* These take no args */
  3695.         if (nopush) {
  3696.         printf("?Sorry, system command access is disabled\n");
  3697.         x = -9;
  3698.         goto xsendx;
  3699.         }
  3700. #ifdef PIPESEND
  3701.         else if (sndfilter) {
  3702.         printf(
  3703. "?Sorry, no SEND /COMMAND or CSEND when SEND FILTER selected\n");
  3704.         x = -9;
  3705.         goto xsendx;
  3706.         }
  3707. #endif /* PIPESEND */
  3708.         sw.hlpmsg = "Command, or switch"; /* Change help message */
  3709.         pv[n].ival = 1;        /* Just set the flag */
  3710.         pv[SND_ARR].ival = 0;
  3711.         break;
  3712.  
  3713.       case SND_REC:            /* /RECURSIVE */
  3714.         recursive = 2;        /* Set the real variable */
  3715.         pv[SND_PTH].ival = PATH_REL; /* Give them relative pathnames */
  3716.         pv[n].ival = 1;        /* Just set the flag */
  3717.         break;
  3718.  
  3719.       case SND_RES:            /* /RECOVER (resend) */
  3720.         pv[SND_ARR].ival = 0;
  3721.         pv[SND_BIN].ival = 1;    /* Implies /BINARY */
  3722.       case SND_NOB:            /* /NOBACKUP */
  3723.       case SND_DEL:            /* /DELETE */
  3724.       case SND_SHH:            /* /QUIET */
  3725.         pv[n].ival = 1;        /* Just set the flag */
  3726.         break;
  3727.  
  3728. #ifdef UNIXOROSK
  3729. /* Like recursive, these are set immediately because they affect cmifi() */
  3730.       case SND_DOT:            /* /DOTFILES */
  3731.         matchdot = 1;
  3732.         break;
  3733.       case SND_NOD:            /* /NODOTFILES */
  3734.         matchdot = 0;
  3735.         break;
  3736. #endif /* UNIXOROSK */
  3737.  
  3738.       /* File transfer modes - each undoes the others */
  3739.  
  3740.       case SND_BIN:            /* Binary */
  3741.       case SND_TXT:            /* Text */
  3742.       case SND_IMG:            /* Image */
  3743.       case SND_LBL:            /* Labeled */
  3744.         pv[SND_BIN].ival = 0;
  3745.         pv[SND_TXT].ival = 0;
  3746.         pv[SND_IMG].ival = 0;
  3747.         pv[SND_LBL].ival = 0;
  3748.         pv[n].ival = 1;
  3749.         break;
  3750.  
  3751. #ifdef CKSYMLINK
  3752.       case SND_LNK:
  3753.       case SND_NLK:
  3754.         nolinks = (n == SND_NLK) ? 2 : 0;
  3755.         cmfdbi(&sf,            /* Redo cmifi() */
  3756.            _CMIFI,        /* fcode */
  3757.            "File(s) to send",    /* hlpmsg */
  3758.            "",            /* default */
  3759.            "",            /* addtl string data */
  3760.            nolinks,        /* addtl numeric data 1 */
  3761.            0,            /* addtl numeric data 2 */
  3762.            xxstring,
  3763.            NULL,
  3764.            mlist ? &cm : &fl
  3765.            );
  3766.         break;
  3767. #endif /* CKSYMLINK */
  3768.  
  3769.       case SND_EXC:            /* Excludes */
  3770.         if (!getval) break;
  3771.         if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
  3772.         if (x == -3) {
  3773.             printf("?Pattern required\n");
  3774.             x = -9;
  3775.         }
  3776.         goto xsendx;
  3777.         }
  3778.         if (pv[n].sval) free(pv[n].sval);
  3779.         y = strlen(s);
  3780.         if (y > 256) {
  3781.         printf("?Pattern too long - 256 max\n");
  3782.         x = -9;
  3783.         goto xsendx;
  3784.         }
  3785.         pv[n].sval = malloc(y+1);
  3786.         if (pv[n].sval) {
  3787.         strcpy(pv[n].sval,s);    /* safe */
  3788.         pv[n].ival = 1;
  3789.         }
  3790.         break;
  3791.  
  3792.       case SND_MOV:            /* MOVE after */
  3793.       case SND_REN:            /* RENAME after */
  3794.         if (!getval) break;
  3795.         if ((x = cmfld(n == SND_MOV ?
  3796.        "device and/or directory for source file after sending" :
  3797.        "new name for source file after sending",
  3798.                "",
  3799.                &s,
  3800.                n == SND_MOV ? xxstring : NULL
  3801.                )) < 0) {
  3802.         if (x == -3) {
  3803.             printf("%s\n", n == SND_MOV ?
  3804.                "?Destination required" :
  3805.                "?New name required"
  3806.                );
  3807.             x = -9;
  3808.         }
  3809.         goto xsendx;
  3810.         }
  3811.         if (pv[n].sval) free(pv[n].sval);
  3812.         s = brstrip(s);
  3813.         y = strlen(s);
  3814.         if (y > 0) {
  3815.         pv[n].sval = malloc(y+1);
  3816.         if (pv[n].sval) {
  3817.             strcpy(pv[n].sval,s); /* safe */
  3818.             pv[n].ival = 1;
  3819.         }
  3820.         }
  3821.         break;
  3822.  
  3823.       case SND_SMA:            /* Smaller / larger than */
  3824.       case SND_LAR:
  3825.         if (!getval) break;
  3826.         if ((x = cmnum("Size in bytes","0",10,&y,xxstring)) < 0)
  3827.           goto xsendx;
  3828.         pv[n].ival = y;
  3829.         break;
  3830.  
  3831.       case SND_AFT:            /* Send /AFTER:date-time */
  3832.       case SND_BEF:            /* Send /BEFORE:date-time */
  3833.       case SND_NAF:            /* Send /NOT-AFTER:date-time */
  3834.       case SND_NBE:            /* Send /NOT-BEFORE:date-time */
  3835.         if (!getval) break;
  3836.         if ((x = cmdate("File date-time","",&s,0,xxstring)) < 0) {
  3837.         if (x == -3) {
  3838.             printf("?Date-time required\n");
  3839.             x = -9;
  3840.         }
  3841.         goto xsendx;
  3842.         }
  3843.         if (pv[n].sval) free(pv[n].sval);
  3844.         pv[n].sval = malloc((int)strlen(s)+1);
  3845.         if (pv[n].sval) {
  3846.         strcpy(pv[n].sval,s);    /* safe */
  3847.         pv[n].ival = 1;
  3848.         }
  3849.         break;
  3850.  
  3851.       case SND_MAI:            /* Send as mail (= MAIL) */
  3852. #ifdef IKSD
  3853.         if (inserver && !ENABLED(en_mai)) {
  3854.         printf("?Sorry, sending files as mail is disabled\n");
  3855.         return(-9);
  3856.         }
  3857. #endif /* IKSD */
  3858.         pv[n].ival = 1;
  3859.         if (!getval) break;
  3860.         if ((x = cmfld("e-mail address","",&s,xxstring)) < 0) {
  3861.         if (x == -3) {
  3862.             printf("?address required\n");
  3863.             x = -9;
  3864.         }
  3865.         goto xsendx;
  3866.         }
  3867.         s = brstrip(s);
  3868.         if (pv[n].sval) free(pv[n].sval);
  3869.         pv[n].sval = malloc((int)strlen(s)+1);
  3870.         if (pv[n].sval)
  3871.           strcpy(pv[n].sval,s);    /* safe */
  3872.         break;
  3873.  
  3874.       case SND_PRI:            /* Send to be printed (REMOTE PRINT) */
  3875. #ifdef IKSD
  3876.         if (inserver && !ENABLED(en_mai)) {
  3877.         printf("?Sorry, sending files for printing is disabled\n");
  3878.         return(-9);
  3879.         }
  3880. #endif /* IKSD */
  3881.         pv[n].ival = 1;
  3882.         if (!getval) break;
  3883.         if ((x = cmfld("Print options","",&s,xxstring)) < 0)
  3884.           if (x != -3) goto xsendx;
  3885.         s = brstrip(s);
  3886.         if (pv[n].sval) free(pv[n].sval);
  3887.         pv[n].sval = malloc((int)strlen(s)+1);
  3888.         if (pv[n].sval)
  3889.           strcpy(pv[n].sval,s);    /* safe */
  3890.         break;
  3891.  
  3892.       case SND_ASN:            /* As-name */
  3893.         debug(F101,"xsend /as-name getval","",getval);
  3894.         if (!getval) break;
  3895.         if ((x = cmfld("Name to send under","",&s,NULL)) < 0) {
  3896.         if (x == -3) {
  3897.             printf("?name required\n");
  3898.             x = -9;
  3899.         }
  3900.         goto xsendx;
  3901.         }
  3902.         s = brstrip(s);
  3903.         if ((y = strlen(s)) > 0) {
  3904.         if (pv[n].sval) free(pv[n].sval);
  3905.         pv[n].sval = malloc(y+1);
  3906.         if (pv[n].sval) {
  3907.             strcpy(pv[n].sval,s); /* safe */
  3908.             pv[n].ival = 1;
  3909.         }
  3910.         }
  3911.         break;
  3912.  
  3913.       case SND_STA:            /* Starting position (= PSEND) */
  3914.         if (!getval) break;
  3915.         if ((x = cmnum("0-based position","0",10,&y,xxstring)) < 0)
  3916.           goto xsendx;
  3917.         pv[n].ival = y;
  3918.         break;
  3919.  
  3920.       case SND_PRO:            /* Protocol to use */
  3921.         if (!getval) break;
  3922.         if ((x = cmkey(protos,nprotos,"File-transfer protocol","",
  3923.                xxstring)) < 0) {
  3924.         if (x == -3) {
  3925.             printf("?name of protocol required\n");
  3926.             x = -9;
  3927.         }
  3928.         goto xsendx;
  3929.         }
  3930.         pv[n].ival = x;
  3931.         break;
  3932.  
  3933. #ifdef PIPESEND
  3934.       case SND_FLT:            /* Filter */
  3935.         debug(F101,"xsend /filter getval","",getval);
  3936.         if (!getval) break;
  3937.         if ((x = cmfld("Filter program to send through","",&s,NULL)) < 0) {
  3938.         if (x == -3)
  3939.           s = "";
  3940.         else
  3941.           goto xsendx;
  3942.         }
  3943.         s = brstrip(s);
  3944.         y = strlen(s);
  3945.         for (x = 0; x < y; x++) {    /* Make sure they included "\v(...)" */
  3946.         if (s[x] != '\\') continue;
  3947.         if (s[x+1] == 'v') break;
  3948.         }
  3949.         if (x == y) {
  3950.         printf(
  3951.         "?Filter must contain a replacement variable for filename.\n"
  3952.                );
  3953.         x = -9;
  3954.         goto xsendx;
  3955.         }
  3956.         pv[n].ival = 1;
  3957.         if (pv[n].sval) {
  3958.         free(pv[n].sval);
  3959.         pv[n].sval = NULL;
  3960.         }
  3961.         if ((y = strlen(s)) > 0) {
  3962.         if ((pv[n].sval = malloc(y+1)))
  3963.           strcpy(pv[n].sval,s);    /* safe */
  3964.         }
  3965.         break;
  3966. #endif /* PIPESEND */
  3967.  
  3968.       case SND_PTH:            /* Pathnames */
  3969.         if (!getval) {
  3970.         pv[n].ival = PATH_REL;
  3971.         break;
  3972.         }
  3973.         if ((x = cmkey(pathtab,npathtab,"","absolute",xxstring)) < 0)
  3974.           goto xsendx;
  3975.         pv[n].ival = x;
  3976.         break;
  3977.  
  3978.       case SND_NAM:            /* Filenames */
  3979.         if (!getval) break;
  3980.         if ((x = cmkey(fntab,nfntab,"","converted",xxstring)) < 0)
  3981.           goto xsendx;
  3982.         debug(F101,"xsend /filenames","",x);
  3983.         pv[n].ival = x;
  3984.         break;
  3985.  
  3986. #ifdef CALIBRATE
  3987.           case SND_CAL:            /* /CALIBRATE */
  3988.         if (getval) {
  3989.         if ((x = cmnum("number of Kbytes to send",
  3990.                "1024",10,&y,xxstring)) < 0)
  3991.           goto xsendx;
  3992.         } else
  3993.           y = 1024;
  3994.         pv[n].ival = y;
  3995.         pv[SND_ARR].ival = 0;
  3996.         break;
  3997. #endif /* CALIBRATE */
  3998.  
  3999.       case SND_FIL:            /* Name of file containing filnames */
  4000.         if (!getval) break;
  4001.         if ((x = cmifi("Name of file containing list of filenames",
  4002.                    "",&s,&y,xxstring)) < 0) {
  4003.         if (x == -3) {
  4004.             printf("?Filename required\n");
  4005.             x = -9;
  4006.         }
  4007.         goto xsendx;
  4008.         } else if (y) {
  4009.         printf("?Wildcards not allowed\n");
  4010.         x = -9;
  4011.         goto xsendx;
  4012.         }
  4013.         if (pv[n].sval)
  4014.           free(pv[n].sval);
  4015.         if (s) if (*s) {
  4016.         if ((pv[n].sval = malloc((int)strlen(s)+1))) {
  4017.             strcpy(pv[n].sval,s);
  4018.             pv[n].ival = 1;
  4019.             pv[SND_ARR].ival = 0;
  4020.         }
  4021.         }
  4022.         break;
  4023.  
  4024. #ifndef NOSPL
  4025.       case SND_ARR:            /* SEND /ARRAY: */
  4026.         if (!getval) break;
  4027.         ap = NULL;
  4028.         if ((x = cmfld("Array name (a single letter will do)",
  4029.                "",
  4030.                &s,
  4031.                NULL
  4032.                )) < 0) {
  4033.         if (x == -3)
  4034.           break;
  4035.         else
  4036.           return(x);
  4037.         }
  4038.         if ((x = arraybounds(s,&(range[0]),&(range[1]))) < 0) {
  4039.         printf("?Bad array: %s\n",s);
  4040.         return(-9);
  4041.         }
  4042.         if (!(ap = a_ptr[x])) {
  4043.         printf("?No such array: %s\n",s);
  4044.         return(-9);
  4045.         }
  4046.         pv[n].ival = 1;
  4047.         pv[SND_CMD].ival = 0;    /* Undo any conflicting ones... */
  4048.         pv[SND_RES].ival = 0;
  4049.         pv[SND_CAL].ival = 0;
  4050.         pv[SND_FIL].ival = 0;
  4051.         arrayx = x;
  4052.         break;
  4053. #endif /* NOSPL */
  4054.  
  4055.       case SND_XPA:            /* /TRANSPARENT */
  4056.         pv[n].ival = 1;
  4057.         break;
  4058.  
  4059.       case SND_TYP:            /* Only files of given type */
  4060.         if (!getval) break;
  4061.         if ((x = cmkey(txtbin,3,"","all",xxstring)) < 0)
  4062.           goto xsendx;
  4063.         pv[n].ival = (x == 2) ? -1 : x;
  4064.         break;
  4065.  
  4066.       default:
  4067.         printf("?Unexpected switch value - %d\n",cmresult.nresult);
  4068.         x = -9;
  4069.         goto xsendx;
  4070.     }
  4071.     }
  4072.     debug(F101,"xsend cmresult fcode","",cmresult.fcode);
  4073.  
  4074. #ifdef COMMENT
  4075.     /* List switch parsing results in debug log */
  4076.     for (i = 0; i <= SND_MAX; i++) {
  4077.     ckmakmsg(line,LINBUFSIZ,"xsend switch ",ckitoa(i),NULL,NULL);
  4078.     debug(F111,line, pv[i].sval, pv[i].ival);
  4079.     }
  4080. #endif /* COMMENT */
  4081.  
  4082. /* Now we have all switches, plus maybe a filename or command, or nothing */
  4083.  
  4084. #ifdef PIPESEND
  4085.     if (protocol != PROTO_K && pv[SND_CMD].ival > 0) {
  4086.     printf("?Sorry, %s works only with Kermit protocol\n",
  4087.            (cx == XXCSEN) ? "CSEND" : "SEND /COMMAND");
  4088.     x = -9;
  4089.     goto xsendx;
  4090.     }
  4091.     if (pv[SND_RES].ival > 0 ||    /* /RECOVER */
  4092.     pv[SND_STA].ival > 0) {    /* or /STARTING */
  4093.     if (sndfilter || pv[SND_FLT].ival > 0) {
  4094.         printf("?Sorry, no /RECOVER or /START if SEND FILTER selected\n");
  4095.         x = -9;
  4096.         goto xsendx;
  4097.     }
  4098.     }
  4099. #endif /* PIPESEND */
  4100.  
  4101.     cmarg = "";
  4102.     cmarg2 = "";
  4103.     line[0] = NUL;
  4104.     s = line;
  4105.     wild = 0;
  4106.  
  4107.     switch (cmresult.fcode) {        /* How did we get out of switch loop */
  4108.       case _CMIFI:            /* Input filename */
  4109.     ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Name */
  4110.     if (pv[SND_ARR].ival > 0)
  4111.       cmarg2 = line;
  4112.     else
  4113.       wild = cmresult.nresult;    /* Wild flag */
  4114.     if (!recursive && !wild)
  4115.       nolinks = 0;
  4116.     break;
  4117.       case _CMFLD:            /* Field */
  4118.     /* Only allowed with /COMMAND and /ARRAY */
  4119.     if (pv[SND_CMD].ival < 1 && pv[SND_ARR].ival < 1) {
  4120. #ifdef CKROOT
  4121.         if (ckrooterr)
  4122.           printf("?Off limits: %s\n",cmresult.sresult);
  4123.         else
  4124. #endif /* CKROOT */
  4125.           printf("?%s - \"%s\"\n",
  4126.            iswild(cmresult.sresult) ?
  4127.            "No files match" : "File not found",
  4128.            cmresult.sresult
  4129.            );
  4130.         x = -9;
  4131.         goto xsendx;
  4132.     }
  4133.     ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  4134.     if (pv[SND_ARR].ival > 0)
  4135.       cmarg2 = line;
  4136.     break;
  4137.       case _CMCFM:            /* Confirmation */
  4138.     /* s = ""; */
  4139.     confirmed = 1;
  4140.     break;
  4141.       default:
  4142.     printf("?Unexpected function code: %d\n",cmresult.fcode);
  4143.     x = -9;
  4144.     goto xsendx;
  4145.     }
  4146.     debug(F110,"xsend string",s,0);
  4147.     debug(F101,"xsend confirmed","",confirmed);
  4148.  
  4149.     /* Save and change protocol and transfer mode */
  4150.     /* Global values are restored in main parse loop */
  4151.  
  4152.     g_proto = protocol;            /* Save current global protocol */
  4153.     g_urpsiz = urpsiz;
  4154.     g_spsizf = spsizf;
  4155.     g_spsiz = spsiz;
  4156.     g_spsizr = spsizr;
  4157.     g_spmax = spmax;
  4158.     g_wslotr = wslotr;
  4159.     g_prefixing = prefixing;
  4160.     g_fncact = fncact;
  4161.     g_fncnv = fncnv;
  4162.     g_fnspath = fnspath;
  4163.     g_fnrpath = fnrpath;
  4164.     g_xfrxla = xfrxla;
  4165.  
  4166.     if (pv[SND_PRO].ival > -1) {    /* Change according to switch */
  4167.     protocol = pv[SND_PRO].ival;
  4168.         if (ptab[protocol].rpktlen > -1) /* copied from initproto() */
  4169.             urpsiz = ptab[protocol].rpktlen;
  4170.         if (ptab[protocol].spktflg > -1)
  4171.             spsizf = ptab[protocol].spktflg;
  4172.         if (ptab[protocol].spktlen > -1) {
  4173.             spsiz = ptab[protocol].spktlen;
  4174.             if (spsizf)
  4175.           spsizr = spmax = spsiz;
  4176.         }
  4177.         if (ptab[protocol].winsize > -1)
  4178.             wslotr = ptab[protocol].winsize;
  4179.         if (ptab[protocol].prefix > -1)
  4180.             prefixing = ptab[protocol].prefix;
  4181.         if (ptab[protocol].fnca > -1)
  4182.             fncact  = ptab[protocol].fnca;
  4183.         if (ptab[protocol].fncn > -1)
  4184.             fncnv   = ptab[protocol].fncn;
  4185.         if (ptab[protocol].fnsp > -1)
  4186.             fnspath = ptab[protocol].fnsp;
  4187.         if (ptab[protocol].fnrp > -1)
  4188.             fnrpath = ptab[protocol].fnrp;
  4189.     }
  4190.     debug(F101,"xsend protocol","",protocol);
  4191.  
  4192.     if (pv[SND_NOB].ival > -1) {    /* /NOBACKUP (skip backup file) */
  4193.     g_skipbup = skipbup;
  4194.     skipbup = 1;
  4195.     }
  4196.     if (pv[SND_REC].ival > 0)        /* /RECURSIVE */
  4197.       recursive = 2;
  4198.  
  4199.     if (pv[SND_TYP].ival > -1) {    /* /TYPE */
  4200.     xfiletype = pv[SND_TYP].ival;
  4201.     if (xfiletype == 2)
  4202.       xfiletype = -1;
  4203.     }
  4204.     g_binary = binary;            /* Save global transfer mode */
  4205. #ifdef PATTERNS
  4206.     g_patterns = patterns;        /* Save FILE PATTERNS setting */
  4207. #endif /* PATTERNS */
  4208.     if (pv[SND_BIN].ival > 0) {        /* Change according to switch */
  4209.     /* If they said /BINARY they mean /BINARY */
  4210.     patterns = 0;            /* So no pattern-based switching */
  4211.     g_xfermode = xfermode;        /* or automatic transfer mode */
  4212.     xfermode = XMODE_M;
  4213.     binary = XYFT_B;
  4214.     debug(F101,"doxsend /BINARY xfermode","",xfermode);
  4215.     } else if (pv[SND_TXT].ival > 0) {    /* Ditto for /TEXT */
  4216.     patterns = 0;
  4217.     g_xfermode = xfermode;
  4218.     xfermode = XMODE_M;
  4219.     binary = XYFT_T;
  4220.     debug(F101,"doxsend /TEXT xfermode","",xfermode);
  4221.     } else if (pv[SND_IMG].ival > 0) {
  4222. #ifdef VMS
  4223.     binary = XYFT_I;
  4224. #else
  4225.     binary = XYFT_B;
  4226. #endif /* VMS */
  4227.     }
  4228. #ifdef CK_LABELED
  4229.     else if (pv[SND_LBL].ival > 0) {
  4230.     binary = XYFT_L;
  4231.     }
  4232. #endif /* CK_LABELED */
  4233.     debug(F101,"xsend binary","",binary);
  4234.  
  4235.     if (pv[SND_XPA].ival > 0)        /* /TRANSPARENT */
  4236.       xfrxla = 0;            /* Don't translate character sets */
  4237.  
  4238.     /* Check for legal combinations of switches, filenames, etc */
  4239.  
  4240. #ifdef PIPESEND
  4241.     if (pv[SND_CMD].ival > 0) {    /* COMMAND - strip any braces */
  4242.     debug(F110,"SEND /COMMAND before stripping",s,0);
  4243.     s = brstrip(s);
  4244.     debug(F110,"SEND /COMMAND after stripping",s,0);
  4245.     if (!*s) {
  4246.         printf("?Sorry, a command to send from is required\n");
  4247.         x = -9;
  4248.         goto xsendx;
  4249.     }
  4250.     cmarg = s;
  4251.     }
  4252. #endif /* PIPESEND */
  4253.  
  4254. /* Set up /MOVE and /RENAME */
  4255.  
  4256.     if (pv[SND_DEL].ival > 0 &&
  4257.     (pv[SND_MOV].ival > 0 || pv[SND_REN].ival > 0)) {
  4258.     printf("?Sorry, /DELETE conflicts with /MOVE or /RENAME\n");
  4259.     x = -9;
  4260.     goto xsendx;
  4261.     }
  4262. #ifdef CK_TMPDIR
  4263.     if (pv[SND_MOV].ival > 0) {
  4264.     int len;
  4265.     char * p = pv[SND_MOV].sval;
  4266. #ifdef CK_LOGIN
  4267.     if (isguest) {
  4268.         printf("?Sorry, /MOVE-TO not available to guests\n");
  4269.         x = -9;
  4270.         goto xsendx;
  4271.     }
  4272. #endif /* CK_LOGIN */
  4273.     len = strlen(p);
  4274.     if (!isdir(p)) {        /* Check directory */
  4275. #ifdef CK_MKDIR
  4276.         char * s = NULL;
  4277.         s = (char *)malloc(len + 4);
  4278.         if (s) {
  4279.         strcpy(s,p);        /* safe */
  4280. #ifdef datageneral
  4281.         if (s[len-1] != ':') { s[len++] = ':'; s[len] = NUL; }
  4282. #else
  4283.         if (s[len-1] != '/') { s[len++] = '/'; s[len] = NUL; }
  4284. #endif /* datageneral */
  4285.         s[len++] = 'X';
  4286.         s[len] = NUL;
  4287.         x = zmkdir(s);
  4288.         free(s);
  4289.         if (x < 0) {
  4290.             printf("?Can't create \"%s\"\n",p);
  4291.             x = -9;
  4292.             goto xsendx;
  4293.         }
  4294.         }
  4295. #else
  4296.         printf("?Directory \"%s\" not found\n",p);
  4297.         x = -9;
  4298.         goto xsendx;
  4299. #endif /* CK_MKDIR */
  4300.     }
  4301.     makestr(&snd_move,p);
  4302.     }
  4303. #endif /* CK_TMPDIR */
  4304.  
  4305.     if (pv[SND_REN].ival > 0) {        /* /RENAME */
  4306.     char * p = pv[SND_REN].sval;
  4307. #ifdef CK_LOGIN
  4308.     if (isguest) {
  4309.         printf("?Sorry, /RENAME-TO not available to guests\n");
  4310.         x = -9;
  4311.         goto xsendx;
  4312.     }
  4313. #endif /* CK_LOGIN */
  4314.     if (!p) p = "";
  4315.     if (!*p) {
  4316.         printf("?New name required for /RENAME\n");
  4317.         x = -9;
  4318.         goto xsendx;
  4319.     }
  4320.     p = brstrip(p);
  4321. #ifndef NOSPL
  4322.     /* If name given is wild, rename string must contain variables */
  4323.     if (wild) {
  4324.         char * s = tmpbuf;
  4325.         x = TMPBUFSIZ;
  4326.         zzstring(p,&s,&x);
  4327.         if (!strcmp(tmpbuf,p)) {
  4328.         printf(
  4329.     "?/RENAME for file group must contain variables such as \\v(filename)\n"
  4330.                );
  4331.         x = -9;
  4332.         goto xsendx;
  4333.         }
  4334.     }
  4335. #endif /* NOSPL */
  4336.     makestr(&snd_rename,p);
  4337.     }
  4338.  
  4339. /* Handle /RECOVER and /START */
  4340.  
  4341. #ifdef CK_RESEND
  4342.     if (pv[SND_RES].ival > 0 && binary != XYFT_B && !filepeek
  4343. #ifdef PATTERNS
  4344.     && !patterns
  4345. #else
  4346. #ifdef VMS
  4347. /* VMS sets text/binary automatically later when it opens the file */
  4348.     && 0
  4349. #endif /* VMS */
  4350. #endif /* PATTERNS */
  4351.     ) {
  4352.     printf("?Sorry, /BINARY required\n");
  4353.     x = -9;
  4354.     goto xsendx;
  4355.     }
  4356.     if (pv[SND_STA].ival > 0) {        /* /START */
  4357.     if (wild) {
  4358.         printf("?Sorry, wildcards not permitted with /START\n");
  4359.         x = -9;
  4360.         goto xsendx;
  4361.     }
  4362.     if (sizeof(int) < 4) {
  4363.         printf("?Sorry, this command needs 32-bit integers\n");
  4364.         x = -9;
  4365.         goto xsendx;
  4366.     }
  4367. #ifdef CK_XYZ
  4368.     if (protocol != PROTO_K) {
  4369.         printf("?Sorry, SEND /START works only with Kermit protocol\n");
  4370.         x = -9;
  4371.         goto xsendx;
  4372.     }
  4373. #endif /* CK_XYZ */
  4374.     }
  4375. #ifdef CK_XYZ
  4376.     if (pv[SND_RES].ival > 0) {
  4377.     if (protocol != PROTO_K && protocol != PROTO_Z) {
  4378.         printf(
  4379.     "Sorry, /RECOVER is possible only with Kermit or ZMODEM protocol\n"
  4380.            );
  4381.         x = -9;
  4382.         goto xsendx;
  4383.     }
  4384.     }
  4385. #endif /* CK_XYZ */
  4386. #endif /* CK_RESEND */
  4387.  
  4388.     if (protocol == PROTO_K) {
  4389.     if ((pv[SND_MAI].ival > 0 ||    /* MAIL */
  4390.          pv[SND_PRI].ival > 0 ||    /* PRINT */
  4391.          pv[SND_RES].ival > 0    /* RESEND */
  4392.          ) &&
  4393.         (!atdiso || !atcapr)) {    /* Disposition attribute off? */
  4394.         printf("?Sorry, ATTRIBUTE DISPOSITION must be ON\n");
  4395.         x = -9;
  4396.         goto xsendx;
  4397.     }
  4398.     }
  4399.  
  4400. #ifdef CK_XYZ
  4401.     if (wild && (protocol == PROTO_X || protocol == PROTO_XC)) {
  4402.     printf(
  4403. "Sorry, you can only send one file at a time with XMODEM protocol\n"
  4404.            );
  4405.     x = -9;
  4406.     goto xsendx;
  4407.     }
  4408. #endif /* CK_XYZ */
  4409.  
  4410.     if (!confirmed) {            /* CR not typed yet, get more fields */
  4411.     char *m;
  4412.     if (mlist) {            /* MSEND or MMOVE */
  4413.         nfils = 0;            /* We already have the first one */
  4414. #ifndef NOMSEND
  4415.         msfiles[nfils++] = line;    /* Store pointer */
  4416.         lp = line + (int)strlen(line) + 1; /* Point past it */
  4417.         debug(F111,"xsend msend",msfiles[nfils-1],nfils-1);
  4418.         while (1) {            /* Get more filenames */
  4419.         char *p;
  4420.         if ((x = cmifi("Names of files to send, separated by spaces",
  4421.                    "", &s,&y,xxstring)) < 0) {
  4422.             if (x != -3)
  4423.               goto xsendx;
  4424.             if ((x = cmcfm()) < 0)
  4425.               goto xsendx;
  4426.             break;
  4427.         }
  4428.         msfiles[nfils++] = lp;    /* Got one, count it, point to it, */
  4429.         p = lp;            /* remember pointer, */
  4430.         while ((*lp++ = *s++))    /* and copy it into buffer */
  4431.           if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
  4432.               printf("?MSEND list too long\n");
  4433.               line[0] = NUL;
  4434.               x = -9;
  4435.               goto xsendx;
  4436.           }
  4437.         debug(F111,"xsend msend",msfiles[nfils-1],nfils-1);
  4438.         if (nfils == 1) fspec[0] = NUL; /* Take care of \v(filespec) */
  4439. #ifdef ZFNQFP
  4440.         zfnqfp(p,TMPBUFSIZ,tmpbuf);
  4441.         p = tmpbuf;
  4442. #endif /* ZFNQFP */
  4443.         if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) {
  4444.             strcat(fspec,p);    /* safe */
  4445.             strcat(fspec," ");    /* safe */
  4446.         } else
  4447. #ifdef COMMENT
  4448.           printf("WARNING - \\v(filespec) buffer overflow\n");
  4449. #else
  4450.           debug(F101,"doxsend filespec buffer overflow","",0);
  4451. #endif /* COMMENT */
  4452.         }
  4453. #endif /* NOMSEND */
  4454.     } else {            /* Regular SEND */
  4455.         char *p; int y;
  4456.         nfils = -1;
  4457.         if (pv[SND_MAI].ival > 0)
  4458.           m = (pv[SND_MAI].sval) ?
  4459.         "e-mail address (optional)" :
  4460.           "e-mail address (required)";
  4461.         else if (pv[SND_PRI].ival > 0)
  4462.           m = "printer options (optional)";
  4463.         else if (wild)
  4464.           m =
  4465. "\nOptional as-name template containing replacement variables \
  4466. like \\v(filename)";
  4467.         else
  4468.           m = "Optional name to send it with";
  4469.         if ((x = cmtxt(m,"",&p,NULL)) < 0)
  4470.           goto xsendx;
  4471.         if (!p) p = "";
  4472.         if (*p) {            /* If some text was given... */
  4473.         p = brstrip(p);        /* Replace /AS-NAME: value if any */
  4474.         if ((y = strlen(p)) > 0) {
  4475.                     if (pv[SND_MAI].ival > 0) {
  4476.                         makestr(&pv[SND_MAI].sval, p);
  4477.                     } else {
  4478.             if (pv[SND_ASN].sval) free(pv[SND_ASN].sval);
  4479.             pv[SND_ASN].sval = malloc(y+1);
  4480.             if (pv[SND_ASN].sval) {
  4481.                 strcpy(pv[SND_ASN].sval,p);    /* safe */
  4482.                 pv[SND_ASN].ival = 1;
  4483.             }
  4484.             }
  4485.         }
  4486.         }
  4487.     }
  4488.     }
  4489.     /* Set cmarg2 from as-name, however we got it. */
  4490.  
  4491.     if (pv[SND_ASN].ival > 0 && pv[SND_ASN].sval && !*cmarg2) {
  4492.     int x;
  4493.     x = strlen(line);
  4494.     ckstrncpy(line+x+2,pv[SND_ASN].sval,LINBUFSIZ-x-1);
  4495.     cmarg2 = line+x+2;
  4496.     debug(F110,"doxsend cmarg2",cmarg2,0);
  4497.     }
  4498.  
  4499. #ifndef NOFRILLS
  4500.     if ((pv[SND_MAI].ival > 0) && (pv[SND_PRI].ival > 0)) {
  4501.     printf("Sorry, /MAIL and /PRINT are conflicting options\n");
  4502.     x = -9;
  4503.     goto xsendx;
  4504.     }
  4505.     n = 0;                /* /MAIL or /PRINT? */
  4506.     if (pv[SND_MAI].ival > 0)
  4507.       n = SND_MAI;
  4508.     else if (pv[SND_PRI].ival > 0)
  4509.       n = SND_PRI;
  4510.     if (n) {                /* Yes... */
  4511. #ifdef DEBUG
  4512.     char * p;
  4513.     if (n == SND_MAI)
  4514.       p = "/MAIL";
  4515.     else
  4516.       p = "/PRINT";
  4517.     debug(F111,"xsend",p,n);
  4518. #endif /* DEBUG */
  4519. #ifdef CK_XYZ
  4520.     if (protocol != PROTO_K) {
  4521.         printf("Sorry, %s available only with Kermit protocol\n",
  4522.            (n == SND_MAI) ? "/MAIL" : "/PRINT"
  4523.            );
  4524.         x = -9;
  4525.         goto xsendx;
  4526.     }
  4527. #endif /* CK_XYZ */
  4528.     debug(F101,"xsend print/mail wild","",wild);
  4529.     *optbuf = NUL;            /* Wipe out any old options */
  4530.     s = pv[n].sval;            /* mail address or print switch val */
  4531.     if (!s) s = "";
  4532.     debug(F110,"doxsend mail address or printer options",s,0);
  4533.     if (n == SND_MAI && !*s) {
  4534.         printf("?E-mail address required\n");
  4535.         x = -9;
  4536.         goto xsendx;
  4537.     } else if ((int)strlen(s) > 94) { /* Ensure legal size */
  4538.         printf("?%s too long\n",
  4539.            (n == SND_MAI) ?
  4540.            "E-mail address" :
  4541.            "Print option string"
  4542.            );
  4543.         x = -9;
  4544.         goto xsendx;
  4545.     }
  4546.     ckstrncpy(optbuf,s,OPTBUFLEN);    /* OK, copy to option buffer */
  4547.     cmarg = line;            /* File to send */
  4548.     if (n == SND_MAI) {
  4549.         debug(F110,"xsend mailing",cmarg,0);
  4550.         debug(F110,"xsend address:",optbuf,0);
  4551.         rmailf = 1;
  4552.     } else {
  4553.         debug(F110,"xsend printing",cmarg,0);
  4554.         debug(F110,"xsend options",optbuf,0);
  4555.         rprintf = 1;
  4556.     }
  4557.     }
  4558. #endif /* NOFRILLS */
  4559.  
  4560. #ifdef CALIBRATE
  4561.     if (pv[SND_CAL].ival > 0) {        /* Handle /CALIBRATE */
  4562.     if (confirmed) {
  4563.         calibrate = pv[SND_CAL].ival * 1024L;
  4564.         sndsrc = -9;
  4565.         nfils = 1;
  4566.         wild = 0;
  4567. #ifndef NOMSEND
  4568.         addlist = 0;
  4569. #endif /* NOMSEND */
  4570.         ckstrncpy(line,"CALIBRATION",LINBUFSIZ);
  4571.         s = cmarg = line;
  4572.         if (!cmarg2) cmarg2 = "";
  4573.         debug(F110,"doxsend cmarg2 calibrate",cmarg2,0);
  4574.     } else if (line[0]) {
  4575.         calibrate = 0L;
  4576.         pv[SND_CAL].ival = 0L;
  4577.     }
  4578.     }
  4579. #endif /* CALIBRATE */
  4580.  
  4581.     if (pv[SND_FIL].ival > 0) {
  4582.     if (confirmed && !calibrate) {
  4583.         if (zopeni(ZMFILE,pv[SND_FIL].sval) < 1) {
  4584.         debug(F110,"xsend can't open",pv[SND_FIL].sval,0);
  4585.         printf("?Failure to open %s\n",filefile);
  4586.         x = -9;
  4587.         goto xsendx;
  4588.         }
  4589.         makestr(&filefile,pv[SND_FIL].sval); /* Open, remember name */
  4590.         debug(F110,"xsend opened",filefile,0);
  4591.         wild = 1;
  4592.     }
  4593.     }
  4594.  
  4595.     /* SEND alone... */
  4596.  
  4597. #ifndef NOSPL
  4598.     if (confirmed && pv[SND_ARR].ival > 0) {
  4599.     if (!*cmarg2) {
  4600.         sndxnam[7] = (char)((arrayx == 1) ? 64 : arrayx + ARRAYBASE);
  4601.         cmarg2 = sndxnam;
  4602.     }
  4603.     cmarg = "";
  4604.     goto sendend;
  4605.     }
  4606. #endif /* NOSPL */
  4607.  
  4608.     if (confirmed && !line[0] && !filefile && !calibrate) {
  4609. #ifndef NOMSEND
  4610.     if (filehead) {            /* OK if we have a SEND-LIST */
  4611.         nfils = filesinlist;
  4612.         sndsrc = nfils;        /* Like MSEND */
  4613.         addlist = 1;        /* But using a different list... */
  4614.         filenext = filehead;
  4615.         goto sendend;
  4616.     }
  4617. #endif /* NOMSEND */
  4618.     printf("?Filename required but not given\n");
  4619.     x = -9;
  4620.     goto xsendx;
  4621.     }
  4622.  
  4623.     /* Not send-list or array */
  4624.  
  4625. #ifndef NOMSEND
  4626.     addlist = 0;            /* Don't use SEND-LIST. */
  4627.     filenext = NULL;
  4628. #endif /* NOMSEND */
  4629.  
  4630.     if (mlist) {            /* MSEND or MMOVE */
  4631. #ifndef NOMSEND
  4632.     cmlist = msfiles;        /* List of files to send */
  4633.     sndsrc = nfils;
  4634.     cmarg2 = "";
  4635.     sendstart = 0L;
  4636. #endif /* NOMSEND */
  4637. #ifdef PIPESEND
  4638.     pipesend = 0;
  4639. #endif /* PIPESEND */
  4640.     } else if (filefile) {        /* File contains list of filenames */
  4641.     s = "";
  4642.     cmarg = "";
  4643.     cmarg2 = "";
  4644.     line[0] = NUL;
  4645.     nfils = 1;
  4646.     sndsrc = 1;
  4647.  
  4648.     } else if (!calibrate && pv[SND_ARR].ival < 1 && pv[SND_CMD].ival < 1) {
  4649.  
  4650.     nfils = sndsrc = -1;    /* Not MSEND, MMOVE, /LIST, or /ARRAY */
  4651.     if (                /* or /COMMAND */
  4652.  
  4653. #ifndef NOFRILLS
  4654.         !rmailf && !rprintf        /* Not MAIL or PRINT */
  4655. #else
  4656.         1
  4657. #endif /* NOFRILLS */
  4658.         ) {
  4659.         int y = 1;
  4660.         if (!wild)
  4661.           y = zchki(s);
  4662.         if (y < 0) {
  4663.         printf("?Read access denied - \"%s\"\n", s);
  4664.         x = -9;
  4665.         goto xsendx;
  4666.         }
  4667.         if (s != line)        /* We might already have done this. */
  4668.           ckstrncpy(line,s,LINBUFSIZ); /* Copy of string just parsed. */
  4669.         else
  4670.           debug(F110,"doxsend line=s",line,0);
  4671.         cmarg = line;        /* File to send */
  4672.     }
  4673.     zfnqfp(cmarg,fspeclen,fspec);
  4674.     }
  4675.     if (!mlist) {            /* For all but MSEND... */
  4676. #ifdef PIPESEND
  4677.     if (pv[SND_CMD].ival > 0)    /* /COMMAND sets pipesend flag */
  4678.       pipesend = 1;
  4679.     debug(F101,"xsend /COMMAND pipesend","",pipesend);
  4680.     if (pipesend && filefile) {
  4681.         printf("?Invalid switch combination\n");
  4682.         x = -9;
  4683.         goto xsendx;
  4684.     }
  4685. #endif /* PIPESEND */
  4686.  
  4687. #ifndef NOSPL
  4688.     /* If as-name given and filespec is wild, as-name must contain variables */
  4689.     debug(F111,"doxsend cmarg2 wild",cmarg2,wild);
  4690.     if (wild && *cmarg2) {
  4691.         char * s = tmpbuf;
  4692.         x = TMPBUFSIZ;
  4693.         zzstring(cmarg2,&s,&x);
  4694.         if (!strcmp(tmpbuf,cmarg2)) {
  4695.         printf(
  4696.     "?As-name for file group must contain variables such as \\v(filename)\n"
  4697.                );
  4698.         x = -9;
  4699.         goto xsendx;
  4700.         }
  4701.     }
  4702. #endif /* NOSPL */
  4703.  
  4704.     /* Strip braces from as-name */
  4705.     debug(F110,"xsend cmarg2 before stripping",cmarg2,0);
  4706.     cmarg2 = brstrip(cmarg2);
  4707.     debug(F110,"xsend filename",cmarg,0);
  4708.     debug(F110,"xsend as-name",cmarg2,0);
  4709.  
  4710.     /* Copy as-name to a safe place */
  4711.  
  4712.     if (asnbuf) {
  4713.         free(asnbuf);
  4714.         asnbuf = NULL;
  4715.     }
  4716.     if ((y = strlen(cmarg2)) > 0) {
  4717.         asnbuf = (char *) malloc(y + 1);
  4718.         if (asnbuf) {
  4719.         strcpy(asnbuf,cmarg2);    /* safe */
  4720.         cmarg2 = asnbuf;
  4721.         } else cmarg2 = "";
  4722.     }
  4723.  
  4724. #ifdef CK_RESEND
  4725.     debug(F111,"xsend pv[SND_STA].ival","",pv[SND_STA].ival);
  4726.     if (pv[SND_STA].ival > -1) {    /* /START position */
  4727.         if (wild) {
  4728.         printf("?/STARTING-AT may not be used with multiple files.\n");
  4729.         x = -9;
  4730.         goto xsendx;
  4731.         } else
  4732.           sendstart = pv[SND_STA].ival;
  4733.     } else
  4734.       sendstart = 0L;
  4735.     debug(F101,"xsend /STARTING","",sendstart);
  4736. #endif /* CK_RESEND */
  4737.     }
  4738.  
  4739. sendend:                /* Common successful exit */
  4740.     moving = 0;
  4741.     if (pv[SND_SHH].ival > 0) {        /* SEND /QUIET... */
  4742.     g_displa = fdispla;
  4743.     fdispla = 0;
  4744.     debug(F101,"xsend display","",fdispla);
  4745.     }
  4746.  
  4747. #ifndef NOSPL                /* SEND /ARRAY... */
  4748.     if (pv[SND_ARR].ival > 0) {
  4749.     if (!ap) { x = -2; goto xsendx; } /* (shouldn't happen) */
  4750.     if (range[0] == -1)        /* If low end of range not specified */
  4751.       range[0] = 1;            /* default to 1 */
  4752.     if (range[1] == -1)        /* If high not specified */
  4753.       range[1] = a_dim[arrayx];    /* default to size of array */
  4754.     if ((range[0] < 0) ||        /* Check range */
  4755.         (range[0] > a_dim[arrayx]) ||
  4756.         (range[1] < range[0]) ||
  4757.         (range[1] > a_dim[arrayx])) {
  4758.         printf("?Bad array range - [%d:%d]\n",range[0],range[1]);
  4759.         x = -9;
  4760.         goto xsendx;
  4761.     }
  4762.     sndarray = ap;            /* Array pointer */
  4763.     sndxin = arrayx;        /* Array index */
  4764.     sndxlo = range[0];        /* Array range */
  4765.     sndxhi = range[1];
  4766.     sndxnam[7] = (char)((sndxin == 1) ? 64 : sndxin + ARRAYBASE);
  4767.  
  4768. #ifdef COMMENT
  4769.     printf("SENDING FROM ARRAY: &%c[]...\n", /* debugging */
  4770.            (sndxin == 1) ? 64 : sndxin + ARRAYBASE);
  4771.     printf("Lo=%d\nHi=%d\n", sndxlo, sndxhi);
  4772.     printf("cmarg=[%s]\ncmarg2=[%s]\n", cmarg, cmarg2);
  4773.     while ((x = agnbyte()) > -1) {
  4774.         putchar((char)x);
  4775.     }
  4776.     return(1);
  4777. #endif /* COMMENT */
  4778.     }
  4779. #endif /* NOSPL */
  4780.  
  4781.     if (pv[SND_ARR].ival < 1) {        /* File selection & disposition... */
  4782.  
  4783.     if (pv[SND_DEL].ival > 0)    /* /DELETE was specified */
  4784.       moving = 1;
  4785.     debug(F101,"xsend /DELETE","",moving);
  4786.     if (pv[SND_AFT].ival > 0)    /* Copy SEND criteria */
  4787.       ckstrncpy(sndafter,pv[SND_AFT].sval,19);
  4788.     if (pv[SND_BEF].ival > 0)
  4789.       ckstrncpy(sndbefore,pv[SND_BEF].sval,19);
  4790.     if (pv[SND_NAF].ival > 0)
  4791.       ckstrncpy(sndnafter,pv[SND_NAF].sval,19);
  4792.     if (pv[SND_NBE].ival > 0)
  4793.       ckstrncpy(sndnbefore,pv[SND_NBE].sval,19);
  4794.     if (pv[SND_EXC].ival > 0)
  4795.       makelist(pv[SND_EXC].sval,sndexcept,8);
  4796.     if (pv[SND_SMA].ival > -1)
  4797.       sndsmaller = pv[SND_SMA].ival;
  4798.     if (pv[SND_LAR].ival > -1)
  4799.       sndlarger = pv[SND_LAR].ival;
  4800.     if (pv[SND_NAM].ival > -1) {
  4801.         g_fncnv = fncnv;        /* Save global value */
  4802.         fncnv = pv[SND_NAM].ival;
  4803.         debug(F101,"xsend fncnv","",fncnv);
  4804.     }
  4805.     if (pv[SND_PTH].ival > -1) {
  4806.         g_spath = fnspath;        /* Save global values */
  4807.         fnspath = pv[SND_PTH].ival;
  4808. #ifndef NZLTOR
  4809.         if (fnspath != PATH_OFF) {
  4810.         g_fncnv = fncnv;    /* Bad bad... */
  4811.         fncnv = XYFN_C;
  4812.         }
  4813. #endif /* NZLTOR */
  4814.         debug(F101,"xsend fnspath","",fnspath);
  4815.         debug(F101,"xsend fncnv","",fncnv);
  4816.     }
  4817.     }
  4818.  
  4819. #ifdef PIPESEND
  4820.     if (pv[SND_FLT].ival > 0) {
  4821.     makestr(&sndfilter,pv[SND_FLT].sval);
  4822.     debug(F110,"xsend /FILTER", sndfilter, 0);
  4823.     }
  4824. #endif /* PIPESEND */
  4825.  
  4826. #ifdef CK_APC
  4827. /* MOVE not allowed in APCs */
  4828.     if (moving &&
  4829.     (apcactive == APC_LOCAL || apcactive == APC_REMOTE)
  4830.     && !(apcstatus & APC_UNCH))
  4831.       return(success = 0);
  4832. #endif /* CK_APC */
  4833. #ifdef IKS_OPTION
  4834.     if (
  4835. #ifdef CK_XYZ
  4836.         protocol == PROTO_K &&
  4837. #endif /* CK_XYZ */
  4838.         !iks_wait(KERMIT_REQ_START,1)) {
  4839.         printf("?A Kermit Server is not available to process this command.\n");
  4840.         printf("?Start a RECEIVE command to complement this command.\n");
  4841.     }
  4842. #endif /* IKS_OPTION */
  4843.  
  4844. #ifdef IKSD
  4845. #ifdef CK_LOGIN
  4846.     if (moving && inserver && isguest) {
  4847.         printf("?File deletion not allowed for guests.\n");
  4848.     return(-9);
  4849.     }
  4850. #endif /* CK_LOGIN */
  4851. #endif /* IKSD */
  4852.  
  4853.     sstate = 's';            /* Set start state to SEND */
  4854.     sndcmd = 1;
  4855. #ifdef CK_RESEND
  4856.     if (pv[SND_RES].ival > 0)        /* Send sendmode appropriately */
  4857.       sendmode = SM_RESEND;
  4858.     else if (pv[SND_STA].ival > 0)
  4859.       sendmode = SM_PSEND;
  4860.     else
  4861. #endif /* CK_RESEND */
  4862.     if (mlist)
  4863.       sendmode = SM_MSEND;
  4864.     else
  4865.       sendmode = SM_SEND;
  4866. #ifdef MAC
  4867.     what = W_SEND;
  4868.     scrcreate();
  4869. #endif /* MAC */
  4870.     if (local && pv[SND_SHH].ival != 0) { /* If in local mode, */
  4871.     displa = 1;            /* turn on file transfer display */
  4872.     }
  4873.     x = 0;
  4874.  
  4875.   xsendx:                /* Common exit, including failure */
  4876.     debug(F101,"doxsend sndsrc","",sndsrc);
  4877.     for (i = 0; i <= SND_MAX; i++) {    /* Free malloc'd memory */
  4878.     if (pv[i].sval)
  4879.       free(pv[i].sval);
  4880.     }
  4881.     return(x);
  4882. }
  4883. #endif /* NOXFER */
  4884.  
  4885. #ifndef NOLOCAL
  4886. /*  D O X C O N N  --  CONNECT command parsing with switches */
  4887.  
  4888. #ifdef XLIMITS
  4889. #define XLIMORTRIGGER
  4890. #else
  4891. #ifdef CK_TRIGGER
  4892. #define XLIMORTRIGGER
  4893. #endif /* CK_TRIGGER */
  4894. #endif /*  XLIMITS */
  4895.  
  4896. #ifdef CKTIDLE
  4897. int tt_idlelimit = 0;            /* Terminal idle limit */
  4898. int tt_idleact = IDLE_RET;        /* Terminal idle action */
  4899. #endif /* CKTIDLE */
  4900.  
  4901. #ifdef OS2                /* K95 only: */
  4902. extern int
  4903.   tt_idlesnd_tmo;            /*   Idle interval */
  4904. int tt_timelimit = 0;            /*   Time limit, 0 = none */
  4905. extern char *                /* Parse results - strings: */
  4906.   tt_idlesnd_str;            /*   Idle string */
  4907. #endif /* OS2 */
  4908.  
  4909. #ifdef CK_TRIGGER
  4910. extern char *tt_trigger[];
  4911. extern CHAR *tt_trmatch[];
  4912. extern char *triggerval;
  4913. static char *g_tt_trigger[TRIGGERS];
  4914. #endif /* CK_TRIGGER */
  4915.  
  4916. #ifdef OS2
  4917. static int g_tt_idlesnd_tmo, g_tt_timelimit; /* For saving and restoring */
  4918. static int g_tt_idlelimit;
  4919. static char * g_tt_idlesnd_str;        /* global settings */
  4920. #endif /* OS2 */
  4921.  
  4922. static struct stringint {        /* Temporary array for switch values */
  4923.     char * sval;
  4924.     int ival;
  4925. } pv[CONN_MAX+1];
  4926.  
  4927. VOID
  4928. resconn() {
  4929.     int i;
  4930.  
  4931. #ifdef OS2
  4932.     tt_idlelimit   = g_tt_idlelimit;
  4933.     tt_idlesnd_tmo = g_tt_idlesnd_tmo;
  4934.     tt_timelimit   = g_tt_timelimit;
  4935.     tt_idlesnd_str = g_tt_idlesnd_str;
  4936. #endif /* OS2 */
  4937.  
  4938. #ifdef CK_TRIGGER
  4939.     for (i = 0; i < TRIGGERS; i++)
  4940.       tt_trigger[i] = g_tt_trigger[i];
  4941. #endif /* CK_TRIGGER */
  4942.  
  4943.     for (i = 0; i <= CONN_MAX; i++) {    /* Free malloc'd memory */
  4944.     if (pv[i].sval)
  4945.       free(pv[i].sval);
  4946.         pv[i].sval = NULL;
  4947.     }
  4948. }
  4949.  
  4950. int
  4951. doxconn(cx) int cx; {
  4952.     int c, i, n;            /* Workers */
  4953.     int x, y;
  4954.     int getval = 0;            /* Whether to get switch value */
  4955.     int async = 0;                      /* Make an async connect */
  4956.     struct FDB sw, cm;            /* FDBs for each parse function */
  4957.     extern FILE * tfile[];
  4958.     extern char * macp[];
  4959.  
  4960. #ifdef OS2
  4961.     g_tt_idlesnd_tmo = tt_idlesnd_tmo;    /* Save global settings */
  4962.     g_tt_timelimit   = tt_timelimit;
  4963.     g_tt_idlelimit   = tt_idlelimit;
  4964.     g_tt_idlesnd_str = tt_idlesnd_str;
  4965. #endif /* OS2 */
  4966.  
  4967. #ifdef CK_TRIGGER
  4968.     if (!tt_trigger[0]) {        /* First initialization */
  4969.     for (i = 1; i < TRIGGERS; i++)
  4970.       tt_trigger[i] = NULL;
  4971.     }
  4972.     for (i = 0; i < TRIGGERS; i++)
  4973.       g_tt_trigger[i] = tt_trigger[i];
  4974.     if (triggerval) {
  4975.     free(triggerval);
  4976.     triggerval = NULL;
  4977.     }
  4978. #endif /* CK_TRIGGER */
  4979.  
  4980.     for (i = 0; i <= CONN_MAX; i++) {    /* Initialize switch values */
  4981.     pv[i].sval = NULL;        /* to null pointers */
  4982.     pv[i].ival = -1;        /* and -1 int values */
  4983.     }
  4984.     if (cx == XXCQ)            /* CQ == CONNECT /QUIETLY */
  4985.       pv[CONN_NV].ival = 1;
  4986.  
  4987.     /* Set up chained parse functions... */
  4988.  
  4989.     cmfdbi(&sw,                /* First FDB - command switches */
  4990.        _CMKEY,            /* fcode */
  4991.        "Switch",            /* hlpmsg */
  4992.        "",                /* default */
  4993.        "",                /* addtl string data */
  4994.        nconntab,            /* addtl numeric data 1: tbl size */
  4995.        4,                /* addtl numeric data 2: 4 = cmswi */
  4996.        xxstring,            /* Processing function */
  4997.        conntab,            /* Keyword table */
  4998.        &cm                /* Pointer to next FDB */
  4999.        );
  5000.     cmfdbi(&cm,                /* 2nd FDB - Confirmation */
  5001.        _CMCFM,            /* fcode */
  5002.        "",                /* hlpmsg */
  5003.        "",                /* default */
  5004.        "",                /* addtl string data */
  5005.        0,                /* addtl numeric data 1 */
  5006.        0,                /* addtl numeric data 2 */
  5007.        NULL,
  5008.        NULL,
  5009.        NULL
  5010.        );
  5011.  
  5012.     while (1) {                /* Parse 0 or more switches */
  5013.     x = cmfdb(&sw);            /* Parse switch or confirmation */
  5014.     debug(F101,"doxconn cmfdb","",x);
  5015.     if (x < 0) {            /* Error */
  5016.         if (x == -9 || x == -2)
  5017.           printf("?No switches match - \"%s\"\n",atmbuf);
  5018.         goto xconnx;        /* or reparse needed */
  5019.     }
  5020.     if (cmresult.fcode != _CMKEY)    /* Break out if not a switch */
  5021.       break;
  5022.     c = cmgbrk();            /* Get break character */
  5023.     getval = (c == ':' || c == '='); /* to see how they ended the switch */
  5024.     if (getval && !(cmresult.kflags & CM_ARG)) {
  5025.         printf("?This switch does not take arguments\n");
  5026.         x = -9;
  5027.         goto xconnx;
  5028.     }
  5029.     if (!getval && (cmgkwflgs() & CM_ARG)) {
  5030.         printf("?This switch requires an argument\n");
  5031.         return(-9);
  5032.     }
  5033.     n = cmresult.nresult;        /* Numeric result = switch value */
  5034.     debug(F101,"doxconn switch","",n);
  5035.  
  5036.     switch (n) {            /* Process the switch */
  5037. #ifdef OS2
  5038.       case CONN_AS:            /* Asynchronous */
  5039.             pv[CONN_AS].ival = 1;
  5040.             pv[CONN_SY].ival = 0;
  5041.             break;
  5042.           case CONN_SY:                 /* Synchronous */
  5043.             pv[CONN_SY].ival = 1;
  5044.             pv[CONN_AS].ival = 0;
  5045.             break;
  5046. #endif /* OS2 */
  5047.       case CONN_NV:            /* Non-verbal */
  5048.         pv[n].ival = 1;
  5049.         break;
  5050. #ifdef XLIMITS
  5051.       case CONN_II:            /* Idle-interval */
  5052.       case CONN_IL:            /* Idle-limit */
  5053.       case CONN_TL:            /* Time-limit */
  5054.         if (!getval) break;
  5055.         if ((x = cmnum("Seconds","0",10,&y,xxstring)) < 0)
  5056.           goto xconnx;
  5057.         pv[n].ival = y;
  5058.         break;
  5059.       case CONN_IS:            /* Idle-string */
  5060. #endif /* XLIMITS */
  5061. #ifdef CK_TRIGGER
  5062.       case CONN_TS:            /* Trigger-string */
  5063. #endif /* CK_TRIGGER */
  5064. #ifdef XLIMORTRIGGER
  5065.         if (!getval) break;
  5066.         if ((x = cmfld("String (enclose in braces if it contains spaces)",
  5067.                "",&s,xxstring)) < 0) {
  5068.         if (x == -3) {
  5069.             printf("?String required\n");
  5070.             x = -9;
  5071.         }
  5072.         goto xconnx;
  5073.         }
  5074.         if (n != CONN_TS)
  5075.           s = brstrip(s);
  5076.         if ((y = strlen(s)) > 0) {
  5077.         if (pv[n].sval) free(pv[n].sval);
  5078.         pv[n].sval = malloc(y+1);
  5079.         if (pv[n].sval) {
  5080.             strcpy(pv[n].sval,s); /* safe */
  5081.             pv[n].ival = 1;
  5082.         }
  5083.         }
  5084.         break;
  5085. #endif /* XLIMORTRIGGER */
  5086.       default:
  5087.         printf("?Unexpected switch value - %d\n",cmresult.nresult);
  5088.         x = -9;
  5089.         goto xconnx;
  5090.     }
  5091.     }
  5092.     debug(F101,"doxconn cmresult.fcode","",cmresult.fcode);
  5093.     if (cmresult.fcode != _CMCFM) {
  5094.     printf("?Unexpected function code: %d\n",cmresult.fcode);
  5095.     x = -9;
  5096.     goto xconnx;
  5097.     }
  5098.  
  5099.     /* Command was confirmed so we can pre-pop command level. */
  5100.     /* This is so CONNECT module won't think we're executing a script */
  5101.     /* if CONNECT was the final command in the script. */
  5102.  
  5103.     if (cmdlvl > 0)
  5104.       prepop();
  5105.  
  5106. #ifdef OS2                /* Make results available globally */
  5107.     if (pv[CONN_IL].ival > -1)        /* Idle limit */
  5108.       tt_idlelimit = pv[CONN_IL].ival;
  5109.     if (pv[CONN_II].ival > -1)        /* Idle limit */
  5110.       tt_idlesnd_tmo = pv[CONN_II].ival;
  5111.     if (pv[CONN_IS].sval)        /* Idle string */
  5112.       if (tt_idlesnd_str = (char *)malloc((int)strlen(pv[CONN_IS].sval)+1))
  5113.     strcpy(tt_idlesnd_str,pv[CONN_IS].sval); /* safe */
  5114.     if (pv[CONN_TL].ival > -1)        /* Session limit */
  5115.       tt_timelimit = pv[CONN_TL].ival;
  5116.     async = (pv[CONN_AS].ival > 0 ||
  5117.              pv[CONN_SY].ival <= 0 && cmdlvl == 0) ? 1 : 0;
  5118. #endif /* OS2 */
  5119.  
  5120. #ifdef CK_TRIGGER
  5121.     if (pv[CONN_TS].sval)        /* Trigger strings */
  5122.       makelist(pv[CONN_TS].sval,tt_trigger,TRIGGERS);
  5123.     for (i = 0; i < TRIGGERS; i++)    /* Trigger match pointers */
  5124.       tt_trmatch[i] = NULL;
  5125.     if (triggerval) {            /* Reset trigger value */
  5126.     free(triggerval);
  5127.     triggerval = NULL;
  5128.     }
  5129. #endif /* CK_TRIGGER */
  5130.  
  5131.     x = doconect((pv[CONN_NV].ival > 0) ? 1 : 0, async);
  5132.  
  5133. #ifdef CKLOGDIAL
  5134.     {
  5135.     int xx;
  5136.     debug(F101,"doxconn doconect returns","",x);
  5137.     if ((xx = ttchk()) < 0) dologend();
  5138.     debug(F101,"doxconn ttchk returns","",xx);
  5139.     }
  5140. #endif /* CKLOGDIAL */
  5141.  
  5142. #ifdef CK_TRIGGER
  5143.     debug(F111,"doxconn doconect triggerval",triggerval,x);
  5144. #endif /* CK_TRIGGER */
  5145.  
  5146.   xconnx:
  5147.     /* Back from CONNECT -- Restore global settings */
  5148.  
  5149.     if (!async)
  5150.       resconn();
  5151.  
  5152.     success = (x > 0) ? 1 : 0;
  5153.     return(x);
  5154. }
  5155. #endif /* NOLOCAL */
  5156.  
  5157. #ifdef ADDCMD
  5158. /* cx == XXADD or XXREMV */
  5159. /* fc == ADD_BIN or ADD_TXT */
  5160. static int
  5161. doadd(cx,fc) int cx, fc; {
  5162. #ifdef PATTERNS
  5163.     char * tmp[FTPATTERNS];
  5164.     char **p = NULL;
  5165.     int i, n = 0, x = 0, last;
  5166. #endif /* PATTERNS */
  5167.     if (cx != XXADD && cx != XXREMV) {
  5168.     printf("?Unexpected function code: %d\n",cx);
  5169.     return(-9);
  5170.     }
  5171. #ifdef PATTERNS
  5172.     while (n < FTPATTERNS) {        /* Collect new patterns */
  5173.     tmp[n] = NULL;
  5174.     if ((x = cmfld("Pattern","",&s,xxstring)) < 0)
  5175.       break;
  5176.     ckstrncpy(line,s,LINBUFSIZ);
  5177.     s = brstrip(line);
  5178.     makestr(&(tmp[n++]),s);
  5179.     }
  5180.     if (x == -3)
  5181.       x = cmcfm();
  5182.     if (x < 0)
  5183.       goto xdoadd;
  5184.     p = (fc == ADD_BIN) ? binpatterns : txtpatterns; /* Which list */
  5185.     last = 0;
  5186.     for (i = 0; i < FTPATTERNS; i++) { /* Find last one in list */
  5187.     if (!p[i]) {
  5188.         last = i;
  5189.         break;
  5190.     }
  5191.     }
  5192.     if (cx == XXADD) {            /* Adding */
  5193.     if (last + n > FTPATTERNS) {    /* Check if too many */
  5194.         printf("?Too many patterns - %d is the maximum\n", FTPATTERNS);
  5195.         goto xdoadd;
  5196.     }
  5197.     for (i = 0; i < n; i++)        /* Copy in the new ones. */
  5198.       makestr(&(p[i+last]),tmp[i]);
  5199.     makestr(&(p[i+last]),NULL);    /* Null-terminate the list */
  5200.     x = 1;
  5201.     goto xdoadd;            /* Done */
  5202.     } else if (cx == XXREMV) {        /* Remove something(s) */
  5203.     int j, k;
  5204.     if (last == 0)                    /* List is empty */
  5205.       goto xdoadd;                    /* Nothing to remove */
  5206.     for (i = 0; i < n; i++) {            /* i = Patterns they typed */
  5207.         for (j = 0; j < last; j++) {        /* j = Patterns in list */
  5208.         /* Change this to ckstrcmp()... */
  5209.         if (filecase)
  5210.           x = !strcmp(tmp[i],p[j]);     /* Case-sensitive match */
  5211.         else
  5212.           x = ckstrcmp(tmp[i],p[j],-1,0); /* Case-independent match */
  5213.         if (x) {                    /* This one matches */
  5214.             makestr(&(p[j]),NULL);      /* Free it */
  5215.             for (k = j; k < last; k++)  /* Move the rest up */
  5216.               p[k] = p[k+1];
  5217.             p[k] = NULL;            /* Erase last one */
  5218.             if (!p[k])
  5219.               break;
  5220.         }
  5221.         }
  5222.     }
  5223.     }
  5224.   xdoadd:                /* Common exit */
  5225.     for (i = 0; i < n; i++)
  5226.       if (tmp[i])
  5227.     free(tmp[i]);
  5228.     return(x);
  5229. #endif /* PATTERNS */
  5230. }
  5231.  
  5232. /* ADD SEND-LIST */
  5233.  
  5234. static int
  5235. addsend(cx) int cx; {
  5236. #ifndef NOMSEND
  5237.     extern struct keytab fttab[];
  5238.     extern int nfttyp;
  5239.     struct filelist * flp;
  5240.     char * fmode = "";
  5241.     int xmode = 0;
  5242.     int xbinary = 0;
  5243. #endif /* NOMSEND */
  5244.  
  5245. #ifdef NOMSEND
  5246.     printf("?Sorry, ADD/REMOVE SEND-LIST not available.\n");
  5247.     return(-9);
  5248. #endif /* NOMSEND */
  5249.     if (cx == XXREMV) {
  5250.     printf("?Sorry, REMOVE SEND-LIST not implemented yet.\n");
  5251.     return(-9);
  5252.     }
  5253. #ifndef NOMSEND
  5254. #ifndef XYZ_INTERNAL
  5255.     if (protocol != PROTO_K) {
  5256.        printf("?Sorry, ADD SEND-LIST does not work with external protocols\n");
  5257.        return(-9);
  5258.     }
  5259. #endif /* XYZ_INTERNAL */
  5260.  
  5261.     x = cmifi("File specification to add","", &s,&y,xxstring);
  5262.     if (x < 0) {
  5263.     if (x == -3) {
  5264.         printf("?A file specification is required\n");
  5265.         return(-9);
  5266.     } else
  5267.       return(x);
  5268.     }
  5269.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  5270.     s = tmpbuf;
  5271.     if (filesinlist == 0)        /* Take care of \v(filespec) */
  5272.       fspec[0] = NUL;
  5273.     zfnqfp(s,LINBUFSIZ,line);
  5274.     s = line;
  5275.     if (((int)strlen(fspec) + (int)strlen(s) + 1) < fspeclen) {
  5276.     strcat(fspec,s);        /* safe */
  5277.     strcat(fspec," ");        /* safe */
  5278.     } else
  5279.       printf("WARNING - \\v(filespec) buffer overflow\n");
  5280.  
  5281.  
  5282.     xbinary = binary;
  5283.     if ((patterns || filepeek)        /* FILE PATTERNS or SCAN is ON */
  5284. #ifdef CK_LABELED
  5285.     && binary != XYFT_L        /* And not if FILE TYPE LABELED */
  5286. #endif /* CK_LABELED */
  5287. #ifdef VMS
  5288.     && binary != XYFT_I        /* or FILE TYPE IMAGE */
  5289. #endif /* VMS */
  5290.     ) {
  5291.     int k, x;
  5292.     x = -1;
  5293.     k = scanfile(line,&x,nscanfile);
  5294.     if (k > 0) xbinary = (k == FT_BIN) ? XYFT_B : XYFT_T;
  5295.     }
  5296.     fmode = gfmode(xbinary,0);
  5297.     if ((x = cmkey(fttab,nfttyp,
  5298.            "type of file transfer", fmode, xxstring)) < 0)
  5299.       return(x);
  5300.     xmode = x;
  5301.  
  5302.     cmarg2 = "";
  5303.     if ((x = cmfld(y ?
  5304.   "\nAs-name template containing replacement variables such as \\v(filename)" :
  5305.   "Name to send it with", "",&s,NULL)) < 0)
  5306.       if (x != -3)
  5307.     return(x);
  5308. #ifndef NOSPL
  5309.     if (y && *s) {
  5310.     char * p = tmpbuf;
  5311.     x = TMPBUFSIZ;
  5312.     zzstring(s,&p,&x);
  5313.     if (!strcmp(tmpbuf,s)) {
  5314.         printf(
  5315.   "?As-name for file group must contain variables such as \\v(filename)\n"
  5316.            );
  5317.         return(-9);
  5318.     }
  5319.     }
  5320. #endif /* NOSPL */
  5321.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  5322.     cmarg2 = tmpbuf;
  5323.  
  5324.     if ((x = cmcfm()) < 0)
  5325.       return(x);
  5326.     flp = (struct filelist *) malloc(sizeof(struct filelist));
  5327.     if (flp) {
  5328.     if (filetail)
  5329.       filetail->fl_next = flp;
  5330.     filetail = flp;
  5331.     if (!filehead)
  5332.       filehead = flp;
  5333.     x = (int) strlen(line);    /* Length of filename */
  5334.     s = (char *) malloc(x + 1);
  5335.     if (s) {
  5336.         strcpy(s,line);        /* safe */
  5337.         flp->fl_name = s;
  5338.         flp->fl_mode = xmode;
  5339.         x = (int) strlen(cmarg2);    /* Length of as-name */
  5340.         if (x < 1) {
  5341.         flp->fl_alias = NULL;
  5342.         } else {
  5343.         s = (char *) malloc(x + 1);
  5344.         if (s) {
  5345.             strcpy(s,cmarg2);    /* safe */
  5346.             flp->fl_alias = s;
  5347.         } else {
  5348.             printf("Sorry, can't allocate space for as-name");
  5349.             return(-9);
  5350.         }
  5351.         }
  5352.         flp->fl_next = NULL;
  5353.         filesinlist++;        /* Count this node */
  5354.         return(success = 1);    /* Finished adding this node */
  5355.     } else {
  5356.         printf("Sorry, can't allocate space for name");
  5357.         return(-9);
  5358.     }
  5359.     } else {
  5360.     printf("Sorry, can't allocate file list node");
  5361.     return(-9);
  5362.     }
  5363. #endif /* NOMSEND */
  5364. }
  5365. #endif /* ADDCMD */
  5366.  
  5367. #ifndef NOHTTP                /* HTTP ops... */
  5368. #ifdef TCPSOCKET
  5369. #define HTTP_GET 0            /* GET */
  5370. #define HTTP_PUT 1            /* PUT */
  5371. #define HTTP_POS 2            /* POST */
  5372. #define HTTP_IDX 3            /* INDEX */
  5373. #define HTTP_HED 4                      /* HEAD */
  5374. #define HTTP_DEL 5                      /* DELETE */
  5375. #define HTTP_CON 6                      /* CONNECT */
  5376. #define HTTP_OPN 7                      /* OPEN */
  5377. #define HTTP_CLS 8                      /* CLOSE */
  5378.  
  5379. static struct keytab httptab[] = {
  5380.     { "close",   HTTP_CLS, 0 },
  5381.     { "connect", HTTP_CON, 0 },
  5382.     { "delete",  HTTP_DEL, 0 },
  5383.     { "get",     HTTP_GET, 0 },
  5384.     { "head",    HTTP_HED, 0 },
  5385.     { "index",   HTTP_IDX, 0 },
  5386.     { "open",    HTTP_OPN, 0 },
  5387.     { "put",     HTTP_PUT, 0 },
  5388.     { "post",    HTTP_POS, 0 }
  5389. };
  5390. static int nhttptab = sizeof(httptab)/sizeof(struct keytab);
  5391.  
  5392. /* HTTP switches */
  5393. #define HT_SW_AG 0            /* /AGENT */
  5394. #define HT_SW_HD 1            /* /HEADER */
  5395. #define HT_SW_US 2            /* /USER */
  5396. #define HT_SW_PW 3            /* /PASSWORD */
  5397. #define HT_SW_AR 4                      /* /ARRAY */
  5398. #define HT_SW_TP 5                      /* /TOSCREEN */
  5399.  
  5400. static struct keytab httpswtab[] = {
  5401.     { "/agent",    HT_SW_AG, CM_ARG },
  5402. #ifndef NOSPL
  5403.     { "/array",    HT_SW_AR, CM_ARG },
  5404. #endif /* NOSPL */
  5405.     { "/header",   HT_SW_HD, CM_ARG },
  5406.     { "/password", HT_SW_PW, CM_ARG },
  5407.     { "/toscreen", HT_SW_TP, 0 },
  5408.     { "/user",     HT_SW_US, CM_ARG },
  5409.     { "", 0, 0 }
  5410. };
  5411. static int nhttpswtab = sizeof(httpswtab)/sizeof(struct keytab) - 1;
  5412.  
  5413. /* HTTP PUT/POST switches */
  5414. #define HT_PP_MT 0            /* /MIME-TYPE */
  5415.  
  5416. static struct keytab httpptab[] = {
  5417.     { "/mime-type", HT_PP_MT, CM_ARG },
  5418.     { "", 0, 0 }
  5419. };
  5420. static int nhttpptab = sizeof(httpptab)/sizeof(struct keytab) - 1;
  5421.  
  5422. #define HTTP_MAXHDR 8
  5423.  
  5424. static int
  5425. xdohttp(action, lfile, rf, dfile, agent, hdr, user, pass, mime, array, type)
  5426.     int action;
  5427.     char *lfile, *rf, *dfile, *agent, *hdr, *user, *pass, *mime, array;
  5428.     int type;
  5429. /* xdohttp */ {
  5430.     int i, rc = 0;
  5431.     char * hdrlist[HTTP_MAXHDR];
  5432.     char rfile[CKMAXPATH+1];
  5433.     extern int httpfd;
  5434.  
  5435.     /* Check for a valid state to execute the command */
  5436.     if (inserver) {
  5437.         printf("?The HTTP command may not be used from the IKS\r\n");
  5438.     } else if (httpfd == -1) {
  5439.         if (http_reopen() < 0)
  5440.       printf("?No connection\n");
  5441.         else 
  5442.       rc = 1;
  5443.     } else {
  5444.     rc = 1;
  5445.     }
  5446.  
  5447.     /* If the command is not valid, exit with failure */
  5448.     if (rc == 0)
  5449.         return(success = 0);
  5450.  
  5451.     if (action != HTTP_CON && rf[0] != '/') {
  5452.         rfile[0] = '/';
  5453.         ckstrncpy(&rfile[1],rf,CKMAXPATH);
  5454.     } else {
  5455.         ckstrncpy(rfile,rf,CKMAXPATH);
  5456.     }
  5457.     for (i = 0; i < HTTP_MAXHDR; i++)    /* Initialize header list */
  5458.       hdrlist[i] = NULL;
  5459.     makelist(hdr,hdrlist,HTTP_MAXHDR);    /* Make header list */
  5460.  
  5461. #ifdef BETADEBUG
  5462.     for (i = 0; i < nhttptab; i++)    /* Find action keyword */
  5463.       if (httptab[i].kwval == action)
  5464.     break;
  5465.     if (i == nhttptab) {        /* Shouldn't happen... */
  5466.     printf("?Invalid action - %d\n",action);
  5467.     return(0);            /* Failure */
  5468.     }
  5469.  
  5470.     printf("HTTP action:  %s\n",httptab[i].kwd);
  5471.     printf(" Agent:       %s\n",agent ? agent : "(null)");
  5472.  
  5473.     if (hdrlist[1]) {
  5474.     printf(" Header list: 1. %s\n",hdrlist[0]);
  5475.     for (i = 1; i < HTTP_MAXHDR && hdrlist[i]; i++)
  5476.       printf("%15d. %s\n",i+1,hdrlist[i]);
  5477.     } else
  5478.       printf(" Header:      %s\n",hdrlist[0] ? hdrlist[0] : "(null)");
  5479.  
  5480.     printf(" User:        %s\n",user ? user : "(null)");
  5481. #ifdef COMMENT
  5482.     printf(" Password:    %s\n",pass ? pass : "(null)");
  5483. #endif /* COMMENT */
  5484.  
  5485. #ifndef NOSPL
  5486.     if (array)
  5487.       printf(" Array:       \\%%%c[]\n", array);
  5488.     else
  5489.       printf(" Array:       (none)\n");
  5490. #endif /* NOSPL */
  5491.  
  5492.     if (action == HTTP_PUT || action == HTTP_POS)
  5493.       printf(" Mime-type:   %s\n",mime ? mime : "(null)");
  5494.  
  5495.     printf(" Local file:  %s\n",lfile ? lfile : "(null)");
  5496.     printf(" Remote file: %s\n",rfile ? rfile : "(null)");
  5497.     printf(" Destination file: %s\n",dfile ? dfile : "(null)");
  5498. #endif /* BETADEBUG */
  5499.  
  5500.     /* The http_xxxx() functions return 0 on success, -1 on failure */
  5501.     switch (action) {
  5502.       case HTTP_CON: {
  5503.       extern int ttyfd;
  5504.       rc = http_connect(httpfd,agent,hdrlist,user,pass,array,rfile);
  5505.       break;
  5506.       }
  5507.       case HTTP_DEL:
  5508.         rc = http_delete(agent,hdrlist,user,pass,array,rfile);
  5509.         break;
  5510.       case HTTP_GET:
  5511.         rc = http_get(agent,hdrlist,user,pass,array,lfile,rfile,type);
  5512.         break;
  5513.       case HTTP_HED:
  5514.         rc = http_head(agent,hdrlist,user,pass,array,lfile,rfile,type);
  5515.         break;
  5516.       case HTTP_PUT:
  5517.         rc = http_put(agent,hdrlist,mime,user,pass,array,lfile,rfile,dfile,
  5518.               type);
  5519.         break;
  5520.       case HTTP_POS:
  5521.         rc = http_post(agent,hdrlist,mime,user,pass,array,lfile,rfile,dfile,
  5522.                type);
  5523.         break;
  5524.       case HTTP_IDX:
  5525.         rc = http_index(agent,hdrlist,user,pass,array,lfile,rfile,type);
  5526.         break;
  5527.       default:
  5528.         rc = -1;
  5529.     }
  5530.     return(rc == 0 ? 1 : 0);            /* Success is set by caller */
  5531. }
  5532. #endif /* TCPSOCKET */
  5533. #endif /* NOHTTP */
  5534.  
  5535. #ifndef NOSPL                /* ARRAY ops... */
  5536. static struct keytab arraytab[] = {
  5537.     { "clear",     ARR_CLR, 0 },
  5538.     { "copy",      ARR_CPY, 0 },
  5539.     { "dcl",       ARR_DCL, CM_INV },
  5540.     { "declare",   ARR_DCL, 0 },
  5541.     { "destroy",   ARR_DST, CM_INV },
  5542.     { "equate",    ARR_EQU, CM_INV },
  5543.     { "link",      ARR_EQU, 0 },
  5544.     { "resize",    ARR_RSZ, 0 },
  5545.     { "set",       ARR_SET, 0 },
  5546. #ifndef NOSHOW
  5547.     { "show",      ARR_SHO, 0 },
  5548. #endif /* NOSHOW */
  5549.     { "sort",      ARR_SRT, 0 },
  5550.     { "undeclare", ARR_DST, 0 },
  5551.     { "", 0, 0 }
  5552. };
  5553. static int narraytab = sizeof(arraytab)/sizeof(struct keytab) - 1;
  5554.  
  5555. #ifdef CKLEARN
  5556. static struct keytab learnswi[] = {
  5557.     { "/close",    2, 0 },
  5558.     { "/off",      0, 0 },
  5559.     { "/on",       1, 0 }
  5560. };
  5561. #endif /* CKLEARN */
  5562.  
  5563. int
  5564. arrayitoa(x) int x; {            /* Array index to array letter */
  5565.     if (x == 1)
  5566.       return(64);
  5567.     else if (x < 0 || x > (122 - ARRAYBASE))
  5568.       return(-1);
  5569.     else
  5570.       return(x + ARRAYBASE);
  5571. }
  5572.  
  5573. int
  5574. arrayatoi(c) int c; {            /* Array letter to array index */
  5575.     if (c == 64)
  5576.       c = 96;
  5577.     if (c > 63 && c < 91)
  5578.       c += 32;
  5579.     if (c < ARRAYBASE || c > 122)
  5580.       return(-1);
  5581.     return(c - ARRAYBASE);
  5582. }
  5583.  
  5584. static int                /* Declare an array */
  5585. dodcl(cx) int cx; {
  5586.     int i, n, v, lo, hi, rc = 0;
  5587.     int isdynamic = 0;
  5588.     char tmpbuf[64];
  5589.     char ** p = NULL;
  5590.     char tmp[64];            /* Local temporary string buffer */
  5591.     if ((y = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
  5592.     if (y == -3) {
  5593.         printf("?Array name required\n");
  5594.         return(-9);
  5595.     } else return(y);
  5596.     }
  5597.     ckstrncpy(line,s,LINBUFSIZ);
  5598.     s = line;
  5599.     x = arraybounds(s,&lo,&hi);        /* Check syntax and get bounds */
  5600.     if (x < 0) {            /* Error - Maybe it's a variable */
  5601.     char * p;            /* whose value is an array name */
  5602.     int n;
  5603.     p = tmpbuf;
  5604.     n = 63;
  5605.     p[0] = NUL;
  5606.     if (s[0] == CMDQ && s[1] == '&')
  5607.       s++;
  5608.     if (zzstring(s,&p,&n) > -1) {
  5609.         s = tmpbuf;
  5610.         x = arraybounds(s,&lo,&hi);
  5611.     }
  5612.     if (x < 0) {
  5613.         printf("?Bad array name - \"%s\"\n",s);
  5614.         return(-9);
  5615.     }
  5616.     }
  5617.     if (lo < 0 && hi < 0) {        /* Have good array name and bounds */
  5618.     isdynamic = 1;
  5619.     n = CMDBL / 5;
  5620.     } else if (hi > -1) {
  5621.     printf("?Segment notation not allowed in array declarations\n");
  5622.     return(-9);
  5623.     } else
  5624.       n = lo;
  5625.     x = arrayitoa(x);
  5626.     if (cx == XXUNDCL) {
  5627.     n = 0;
  5628.     v = 0;
  5629.     if ((y = cmcfm()) < 0)
  5630.       return(y);
  5631.     } else {
  5632.     p = (char **)malloc(sizeof(char **)*(n+1));
  5633.     if (!p) {
  5634.         printf("?Memory allocation error\n");
  5635.         return(-9);
  5636.     }
  5637.     v = 0;                /* Highest initialized member */
  5638.     p[0] = NULL;            /* Element 0 */
  5639.     while (n > 0 && v < n) {    /* Parse initializers */
  5640.         p[v+1] = NULL;
  5641.         ckmakxmsg(tmp,
  5642.               64,
  5643.               "Initial value for \\&",
  5644.               ckctoa((char)x),
  5645.               "[",
  5646.               ckitoa(v+1),
  5647.               "]",
  5648.               NULL,NULL,NULL,NULL,NULL,NULL,NULL
  5649.               );
  5650.         if ((rc = cmfld((char *)tmp,"",&s,xxstring)) < 0) { /* Get field */
  5651.         if (rc == -3)        /* If answer is empty, we're done */
  5652.           break;
  5653.         else            /* Parse error, free temp pointers */
  5654.           goto dclx;
  5655.         }
  5656.         rc = 1;
  5657.         if (v == 0 && !strcmp(s,"=")) /* Skip the = sign. */
  5658.           continue;
  5659.         s = brstrip(s);        /* Strip any braces */
  5660.         makestr(&(p[++v]),s);
  5661.     }
  5662.     if ((y = cmtxt("Carriage return to confirm","",&s,NULL)) < 0)
  5663.       return(y);
  5664.     if (isdynamic)
  5665.       n = v;
  5666.     }
  5667.     if (dclarray((char)x,n) < 0) {    /* Declare the array */
  5668.     printf("?Declare failed\n");
  5669.     goto dclx;
  5670.     }
  5671.     for (i = 1; i <= v; i++) {        /* Add any initial values */
  5672.     tmp[0] = '&';
  5673.     ckmakmsg(&tmp[1],63,ckctoa((char)x),"[",ckitoa(i),"]");
  5674.     if (addmac(tmp,p[i]) < 0) {
  5675.         printf("Array initialization error: %s %s\n",tmp,p[i]);
  5676.         rc = -9;
  5677.         goto dclx;
  5678.     }
  5679.     }
  5680.   dclx:
  5681.     if (p) {
  5682.     for (i = 1; i <= v; i++)
  5683.       if (p[i]) free(p[i]);
  5684.     free((char *)p);
  5685.     }
  5686.     debug(F101,"DCL rc","",rc);
  5687.     return(success = rc);
  5688. }
  5689.  
  5690. static int
  5691. rszarray() {
  5692.     int i, x, y, n, lo, hi, islink = -1;
  5693.     char c, * s, ** ap = NULL;
  5694.     if ((x = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
  5695.     if (x == -3) {
  5696.         printf("?Array name required\n");
  5697.         return(-9);
  5698.     } else return(x);
  5699.     }
  5700.     ckstrncpy(line,s,LINBUFSIZ);    /* Make safe copy of name */
  5701.     s = line;
  5702.     x = arraybounds(s,&lo,&hi);
  5703.     if (x < 0) {            /* Parse the name, get index */
  5704.     printf("?Bad array reference - \"%s\"\n", s);
  5705.     return(-9);
  5706.     }
  5707.     if (lo < 0 && hi < 0) {
  5708.     y = cmnum("New size","",10,&lo,xxstring);
  5709.     if (y < 0) {
  5710.         if (y == -3)
  5711.           printf("?New size required\n");
  5712.         return(y);
  5713.     }
  5714.     }
  5715.     if ((y = cmcfm()) < 0)
  5716.       return(y);
  5717.     if (a_link[x] > -1) {        /* Link? */
  5718.     islink = x;            /* Yes follow it */
  5719.     x = a_link[x];            /* and remember */
  5720.     }
  5721.     if (!a_ptr[x]) {
  5722.     printf("?Array not declared - \"%s\"\n", s);
  5723.     return(-9);
  5724.     }
  5725.     if (lo < 0) {
  5726.     printf("?New size required\n");
  5727.     return(-9);
  5728.     }
  5729.     if (hi > -1) {
  5730.     printf("?Array segments not allowed for this operation\n");
  5731.     return(-9);
  5732.     }
  5733.     c = arrayitoa(x);            /* Get array letter */
  5734.     if (c == '@') {            /* Argument vector array off limits */
  5735.     printf("?Sorry, \\&@[] is read-only\n");
  5736.     return(-9);
  5737.     }
  5738.     if (lo == 0) {            /* If new size is 0... */
  5739.     dclarray(c,0);            /* Undeclare the array */
  5740.     return(success = 1);
  5741.     }
  5742.     n = a_dim[x];            /* Current size */
  5743.     ap = (char **) malloc((lo+1) * sizeof(char *)); /* New array */
  5744.     y = (n < lo) ? n : lo;
  5745.     for (i = 0; i <= y; i++)        /* Copy the part that fits */
  5746.       ap[i] = a_ptr[x][i];
  5747.     if (n < lo) {            /* If original array smaller */
  5748.     for (; i <= lo; i++)        /* initialize extra elements in */
  5749.       ap[i] = NULL;            /* new array to NULL. */
  5750.     } else if (n > lo) {        /* If new array smaller */
  5751.     for (; i <= lo; i++)        /* deallocate leftover elements */
  5752.       makestr(&(a_ptr[x][i]),NULL);    /* from original array. */
  5753.     }
  5754.     free((char *)a_ptr[x]);        /* Free original array list */
  5755.     a_ptr[x] = ap;            /* Replace with new one */
  5756.     a_dim[x] = lo;            /* Record the new dimension */
  5757.     if (islink > -1) {            /* Was this a link? */
  5758.     a_ptr[islink] = ap;        /* If so point to the resized array */
  5759.     a_dim[islink] = lo;
  5760.     } else {                /* If not are there links to here? */
  5761.     for (i = 0; i < (int) 'z' - ARRAYBASE; i++) { /* Any linked arrays? */
  5762.         if (i != x && a_link[i] == x) {     /* Find and update them */
  5763.         a_ptr[i] = ap;
  5764.         a_dim[i] = lo;
  5765.         }
  5766.     }
  5767.     }
  5768.     return(success = 1);
  5769. }
  5770.  
  5771. static int
  5772. copyarray() {
  5773.     int i, j, x1, lo1, hi1, x2, lo2, hi2, whole = 0;
  5774.     char c1, c2, * a1, * a2;
  5775.     if ((y = cmfld("Name of source array","",&s,NULL)) < 0)
  5776.       return(y);
  5777.     ckstrncpy(line,s,LINBUFSIZ);
  5778.     a1 = line;
  5779.     if ((x1 = arraybounds(a1,&lo1,&hi1)) < 0) {
  5780.     printf("?Bad array reference - \"%s\"\n", a1);
  5781.     return(-9);
  5782.     } else if (!a_ptr[x1]) {
  5783.     printf("?Array not declared - \"%s\"\n", a1);
  5784.     return(-9);
  5785.     }
  5786.     c1 = arrayitoa(x1);
  5787.  
  5788.     if ((y = cmfld("Name of destination array","",&s,NULL)) < 0)
  5789.       return(y);
  5790.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  5791.     a2 = tmpbuf;
  5792.     if ((x2 = arraybounds(a2,&lo2,&hi2)) < 0) {
  5793.     printf("?Bad array reference - \"%s\"\n", a2);
  5794.     return(-9);
  5795.     }
  5796.     c2 = arrayitoa(x2);
  5797.  
  5798.     if ((x = cmcfm()) < 0)
  5799.       return(x);
  5800.  
  5801.     if (c2 == '@') {            /* Argument vector array off limits */
  5802.     printf("?Sorry, \\&@[] is read-only\n");
  5803.     return(-9);
  5804.     }
  5805.     if (lo1 < 0 && lo2 < 0 && hi1 < 0 && hi2 < 0) /* Special case for */
  5806.       whole = 1;                      /* whole array... */
  5807.  
  5808.     if (lo1 < 0) lo1 = whole ? 0 : 1;    /* Supply lower bound of source */
  5809.     if (hi1 < 0) hi1 = a_dim[x1];    /* Supply upper bound of source */
  5810.     if (lo2 < 0) lo2 = whole ? 0 : 1;    /* Lower bound of target */
  5811.     if (hi2 < 0) hi2 = lo2 + hi1 - lo1;    /* Upper bound of target */
  5812.     if (a_ptr[x2]) {            /* Target array is already declared? */
  5813.     if (hi2 > a_dim[x2])        /* If upper bound out of range */
  5814.       hi2 = a_dim[x2];        /* shrink to fit */
  5815.     } else {                /* Otherwise... */
  5816.     x2 = dclarray(c2, hi2);        /* declare the target array */
  5817.     }
  5818.     for (i = lo1, j = lo2; i <= hi1 && j <= hi2; i++,j++) { /* Copy */
  5819.     makestr(&(a_ptr[x2][j]),a_ptr[x1][i]);
  5820.     }
  5821.     return(success = 1);
  5822. }
  5823.  
  5824. static int                /* Undeclare an array */
  5825. unarray() {
  5826.     int x, y, n, rc = 0;
  5827.     char c, * s;
  5828.  
  5829.     if ((y = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
  5830.     if (y == -3) {
  5831.         printf("?Array name required\n");
  5832.         return(-9);
  5833.     } else return(y);
  5834.     }
  5835.     ckstrncpy(line,s,LINBUFSIZ);    /* Make safe copy of name */
  5836.     s = line;
  5837.     if ((y = cmcfm()) < 0)
  5838.       return(y);
  5839.     if ((x = arraybounds(s,&y,&n)) < 0) { /* Parse the name, get index */
  5840.     printf("?Bad array reference - \"%s\"\n", s);
  5841.     return(-9);
  5842.     }
  5843.     if (y > 0 || n > 0) {
  5844.     printf("?Partial arrays can not be destroyed\n");
  5845.     return(-9);
  5846.     }
  5847.     c = arrayitoa(x);            /* Get array letter */
  5848.     if (a_ptr[x]) {            /* If array is declared */
  5849.     if (c == '@') {            /* Argument vector array off limits */
  5850.         printf("?Sorry, \\&@[] is read-only\n");
  5851.         return(-9);
  5852.     }
  5853.     rc = dclarray(c,0);        /* Undeclare the array */
  5854.     } else                /* It wasn't declared */
  5855.       rc = 1;
  5856.     if (rc > -1) {            /* Set return code and success */
  5857.     success = 1;
  5858.     rc = 1;
  5859.     } else {
  5860.     success = 0;
  5861.     printf("?Failed - destroy \"\\&%c[]\"\n", c);
  5862.     rc = -9;
  5863.     }
  5864.     return(rc);
  5865. }
  5866.  
  5867. static int
  5868. clrarray(cx) int cx; {
  5869.     int i, x, lo, hi;
  5870.     char c, * s, * val = NULL;
  5871.  
  5872.     if ((x = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
  5873.     if (x == -3) {
  5874.         printf("?Array name required\n");
  5875.         return(-9);
  5876.     } else return(x);
  5877.     }
  5878.     ckstrncpy(line,s,LINBUFSIZ);    /* Make safe copy of name */
  5879.     s = line;
  5880.     if (cx == ARR_SET) {        /* SET */
  5881.     if ((x = cmtxt("Value","",&val,xxstring)) < 0)
  5882.       return(x);
  5883.     ckstrncpy(tmpbuf,val,TMPBUFSIZ); /* Value to set */
  5884.     val = tmpbuf;
  5885.     if (!*val) val = NULL;
  5886.     } else if ((x = cmcfm()) < 0)    /* CLEAR */
  5887.       return(x);
  5888.  
  5889.     if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Parse the name */
  5890.     printf("?Bad array reference - \"%s\"\n", s);
  5891.     return(-9);
  5892.     }
  5893.     c = arrayitoa(x);            /* Get array letter */
  5894.     if (!a_ptr[x]) {            /* If array is declared */
  5895.     printf("?Array %s is not declared\n", s);
  5896.     return(-9);
  5897.     } else if (c == '@') {        /* Argument vector array off limits */
  5898.     printf("?Sorry, \\&@[] is read-only\n");
  5899.     return(-9);
  5900.     }
  5901.     if (lo < 0) lo = 0;
  5902.     if (hi < 0) hi = a_dim[x];
  5903.     for (i = lo; i <= hi; i++)        /* Clear/Set selected range */
  5904.       makestr(&(a_ptr[x][i]),val);
  5905.  
  5906.     return(success = 1);
  5907. }
  5908.  
  5909. extern char **aa_ptr[CMDSTKL][28];
  5910. extern int aa_dim[CMDSTKL][28];
  5911.  
  5912. static int                /* Create symbolic link to an array */
  5913. linkarray() {
  5914.     int i = 0, x, y, lo, hi, flag = 0;
  5915.     char c, * s, * p;
  5916.  
  5917.     if ((x = cmfld("Array name not currently in use","",&s,NULL)) < 0) {
  5918.     if (x == -3) {
  5919.         printf("?Array name required\n");
  5920.         return(-9);
  5921.     } else return(x);
  5922.     }
  5923.     ckstrncpy(line,s,LINBUFSIZ);    /* Make safe copy of link name */
  5924.     s = line;
  5925.     if ((x = cmfld("Name of existing array","",&p,xxstring)) < 0) {
  5926.     if (x == -3) {
  5927.         printf("?Array name required\n");
  5928.         return(-9);
  5929.     } else return(x);
  5930.     }
  5931.     ckstrncpy(tmpbuf,p,TMPBUFSIZ);    /* Make safe copy of array name */
  5932.     p = tmpbuf;
  5933.     if ((x = cmcfm()) < 0)
  5934.       return(x);
  5935.  
  5936.     if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Parse the link name */
  5937.     printf("?Bad array reference - \"%s\"\n", s);
  5938.     return(-9);
  5939.     }
  5940.     if (a_ptr[x]) {            /* Must not already exist */
  5941.     c = arrayitoa(x);
  5942.     printf("?Array already exists: \\&%c[]\n", c);
  5943.     return(-9);
  5944.     }
  5945.     if (lo > -1 || hi > -1) {
  5946.     printf("?Sorry, whole arrays only: %s\n",s);
  5947.     return(-9);
  5948.     }
  5949.     if ((y = arraybounds(p,&lo,&hi)) < 0) { /* Parse the array name */
  5950.     printf("?Bad array reference - \"%s\"\n", s);
  5951.     return(-9);
  5952.     }
  5953.     if (lo > -1 || hi > -1) {
  5954.     printf("?Sorry, whole arrays only: %s\n",p);
  5955.     return(-9);
  5956.     }
  5957.     if (x == y) {
  5958.     for (i = cmdlvl; i >= 0; i--)
  5959.       if (aa_ptr[i][x]) {
  5960.           flag++;
  5961.           break;
  5962.       }
  5963.     }
  5964.     if (flag) {
  5965.     a_ptr[x] = aa_ptr[i][y];    /* Link to saved copy */
  5966.     a_dim[x] = aa_dim[i][y];
  5967.     } else {                /* Otherwise... */
  5968.     c = arrayitoa(y);        /* Check if it's declared */
  5969.     if (!a_ptr[y]) {
  5970.         printf("?Array is not declared: \\&%c[]\n", c);
  5971.         return(-9);
  5972.     }
  5973.     if (a_link[y] > -1) {        /* And if it's a link itself */
  5974.         printf("?Links to links not allowed: \\&%c[]\n", c);
  5975.         return(-9);
  5976.     }
  5977.     a_ptr[x] = a_ptr[y];        /* All OK, make the link */
  5978.     a_dim[x] = a_dim[y];
  5979.     }
  5980.     a_link[x] = y;
  5981.     return(success = 1);
  5982. }
  5983. #endif /* NOSPL */
  5984.  
  5985. #ifndef NOCSETS
  5986. static char * dcsetname = NULL;
  5987.  
  5988. /* Get Display Character-Set Name */
  5989.  
  5990. char *
  5991. getdcset() {
  5992.     char * s;
  5993.     int y;
  5994. #ifdef PCFONTS
  5995.     extern int tt_font, ntermfont;
  5996.     extern struct keytab term_font[];
  5997. #endif /* PCFONTS */
  5998.  
  5999.     s = "";
  6000. #ifdef OS2
  6001.     y = os2getcp();            /* Default is current code page */
  6002.     switch (y) {
  6003.       case 437: s = "cp437"; break;
  6004.       case 850: s = "cp850"; break;
  6005.       case 852: s = "cp852"; break;
  6006.       case 857: s = "cp857"; break;
  6007.       case 858: s = "cp858"; break;
  6008.       case 862: s = "cp862"; break;
  6009.       case 866: s = "cp866"; break;
  6010.       case 869: s = "cp869"; break;
  6011.       case 1250: s = "cp1250"; break;
  6012.       case 1251: s = "cp1251"; break;
  6013.       case 1252: s = "cp1252"; break;
  6014.       case 1253: s = "cp1253"; break;
  6015.       case 1254: s = "cp1254"; break;
  6016.       case 1255: s = "cp1255"; break;
  6017.       case 1256: s = "cp1256"; break;
  6018.       case 1257: s = "cp1257"; break;
  6019.       case 1258: s = "cp1258"; break;
  6020.     }
  6021. #ifdef PCFONTS
  6022. /*
  6023.    If the user has loaded a font with SET TERMINAL FONT then we want
  6024.    to change the default code page to the font that was loaded.
  6025. */
  6026.     if (tt_font != TTF_ROM) {
  6027.     for (y = 0; y < ntermfont; y++ ) {
  6028.         if (term_font[y].kwval == tt_font) {
  6029.         s = term_font[y].kwd;
  6030.         break;
  6031.         }
  6032.     }
  6033.     }
  6034. #endif /* PCFONTS */
  6035. #else /* OS2 */
  6036. #ifdef COMMENT
  6037.     /* Hack not needed as of C-Kermit 7.1 */
  6038.     if (fcharset == FC_1LATIN) {
  6039.     s = "latin1-iso";        /* Hack to avoid reporting "cp1252" */
  6040.     } else {                /* Report current file character set */
  6041. #endif /* COMMENT */
  6042.     for (y = 0; y <= nfilc; y++)
  6043.       if (fcstab[y].kwval == fcharset) {
  6044.           s = fcstab[y].kwd;
  6045.           break;
  6046.       }
  6047. #ifdef COMMENT
  6048.     }
  6049. #endif /* COMMENT */
  6050. #endif /* OS2 */
  6051.     makestr(&dcsetname,s);        /* Return stable pointer */
  6052.     return((char *)dcsetname);
  6053. }
  6054. #endif /* NOCSETS */
  6055.  
  6056. #ifndef NOFRILLS
  6057. static int
  6058. doclear() {
  6059.     if ((x = cmkey(clrtab,nclear,"item to clear",
  6060. #ifdef NOSPL
  6061.            "device-buffer"
  6062. #else
  6063.            "device-and-input"
  6064. #endif /* NOSPL */
  6065.            ,xxstring)) < 0) return(x);
  6066. #ifndef NOSPL
  6067. #ifdef OS2
  6068.     if (x == CLR_CMD || x == CLR_TRM) {
  6069.     if ((z = cmkey(clrcmdtab,nclrcmd,"how much screen to clear\n",
  6070.                "all",xxstring)) < 0)
  6071.       return(z);
  6072.     }
  6073. #endif /* OS2 */
  6074. #endif /* NOSPL */
  6075.     if ((y = cmcfm()) < 0)
  6076.       return(y);
  6077.  
  6078.     /* Clear device input buffer if requested */
  6079.     y = (x & CLR_DEV) ? ttflui() : 0;
  6080.  
  6081.     if (x & CLR_SCR)            /* CLEAR SCREEN */
  6082.       y = ck_cls();            /* (= SCREEN CLEAR = CLS) */
  6083.  
  6084.     if (x & CLR_KBD) {            /* CLEAR KEYBOARD */
  6085.     int n;
  6086.     n = conchk();
  6087.     y = 0;
  6088.     while (n-- > 0 && (y = coninc(0) > -1))
  6089.       ;
  6090.     y = (y > -1) ? 0 : -1;
  6091.     }
  6092.  
  6093. #ifndef NOSPL
  6094.     /* Clear INPUT command buffer if requested */
  6095.     if (x & CLR_INP) {
  6096.     for (z = 0; z < inbufsize; z++)
  6097.       inpbuf[z] = NUL;
  6098.     inpbp = inpbuf;
  6099.     y = 0;
  6100.     }
  6101. #ifdef CK_APC
  6102.     if (x & CLR_APC) {
  6103.     debug(F101,"Executing CLEAR APC","",apcactive);
  6104.     apcactive = 0;
  6105.     y = 0;
  6106.     }
  6107. #endif /* CK_APC */
  6108.     if (x & CLR_ALR) {
  6109.     setalarm(0L);
  6110.     y = 0;
  6111.     }
  6112. #endif /* NOSPL */
  6113.  
  6114. #ifdef PATTERNS
  6115.     if (x & (CLR_TXT|CLR_BIN)) {
  6116.     int i;
  6117.     for (i = 0; i < FTPATTERNS; i++) {
  6118.         if (x & CLR_TXT)
  6119.           makestr(&txtpatterns[i],NULL);
  6120.         if (x & CLR_BIN)
  6121.           makestr(&binpatterns[i],NULL);
  6122.     }
  6123.     y = 0;
  6124.     }
  6125. #endif /* PATTERNS */
  6126.  
  6127. #ifndef NODIAL
  6128.     if (x & CLR_DIA) {
  6129.     dialsta = DIA_UNK;
  6130.     y = 0;
  6131.     }
  6132. #endif /* NODIAL */
  6133.  
  6134. #ifndef NOMSEND
  6135.     if (x & CLR_SFL) {            /* CLEAR SEND-LIST */
  6136.     if (filehead) {
  6137.         struct filelist * flp, * next;
  6138.         flp = filehead;
  6139.         while (flp) {
  6140.         if (flp->fl_name)
  6141.           free(flp->fl_name);
  6142.         if (flp->fl_alias)
  6143.           free(flp->fl_alias);
  6144.         next = flp->fl_next;
  6145.         free((char *)flp);
  6146.         flp = next;
  6147.         }
  6148.     }
  6149.     filesinlist = 0;
  6150.     filehead = NULL;
  6151.     filetail = NULL;
  6152.     addlist = 0;
  6153.     y = 0;
  6154.     }
  6155. #endif /* NOMSEND */
  6156.  
  6157. #ifdef OS2
  6158. #ifndef NOLOCAL
  6159.     switch (x) {
  6160.       case CLR_SCL:
  6161.     clearscrollback(VTERM);
  6162.     break;
  6163.       case CLR_CMD:
  6164.     switch ( z ) {
  6165.       case CLR_C_ALL:
  6166.         clear();
  6167.         break;
  6168.       case CLR_C_BOS:
  6169.         clrboscr_escape(VCMD,SP);
  6170.         break;
  6171.       case CLR_C_BOL:
  6172.         clrbol_escape(VCMD,SP);
  6173.         break;
  6174.       case CLR_C_EOL:
  6175.         clrtoeoln(VCMD,SP);
  6176.         break;
  6177.       case CLR_C_EOS:
  6178.         clreoscr_escape(VCMD,SP);
  6179.         break;
  6180.       case CLR_C_LIN:
  6181.         clrline_escape(VCMD,SP);
  6182.         break;
  6183.       case CLR_C_SCR:
  6184.         clearscrollback(VCMD);
  6185.         break;
  6186.     default:
  6187.         printf("Not implemented yet, sorry.\n");
  6188.         break;
  6189.     }
  6190.     break;
  6191.  
  6192. #ifndef NOTERM
  6193.       case CLR_TRM:
  6194.      switch ( z ) {
  6195.       case CLR_C_ALL:
  6196.          if (VscrnGetBufferSize(VTERM) > 0 ) {
  6197.          VscrnScroll(VTERM, UPWARD, 0,
  6198.                  VscrnGetHeight(VTERM)-(tt_status[VTERM]?2:1),
  6199.                  VscrnGetHeight(VTERM) -
  6200.                  (tt_status[VTERM]?1:0), TRUE, SP
  6201.                  );
  6202.          cleartermscreen(VTERM);
  6203.          }
  6204.          break;
  6205.       case CLR_C_BOS:
  6206.         clrboscr_escape(VTERM,SP);
  6207.         break;
  6208.       case CLR_C_BOL:
  6209.         clrbol_escape(VTERM,SP);
  6210.         break;
  6211.       case CLR_C_EOL:
  6212.         clrtoeoln(VTERM,SP);
  6213.         break;
  6214.       case CLR_C_EOS:
  6215.         clreoscr_escape(VTERM,SP);
  6216.         break;
  6217.       case CLR_C_LIN:
  6218.         clrline_escape(VTERM,SP);
  6219.         break;
  6220.      case CLR_C_SCR:
  6221.          clearscrollback(VTERM);
  6222.          break;
  6223.      default:
  6224.          printf("Not implemented yet, sorry.\n");
  6225.          break;
  6226.     }
  6227.     break;
  6228. #endif /* NOTERM */
  6229.     }
  6230.     y = 0;
  6231. #endif /* NOLOCAL */
  6232. #endif /* OS2 */
  6233.     return(success = (y == 0));
  6234. }
  6235. #endif /* NOFRILLS */
  6236.  
  6237. #ifndef NOSPL
  6238. static int
  6239. doeval(cx) int cx; {
  6240.     char *p;
  6241.     char vnambuf[VNAML], * vnp = NULL;    /* These must be on the stack */
  6242.     if (!oldeval) {
  6243.     if ((y = cmfld("Variable name","",&s,
  6244.                ((cx == XX_EVAL) ? xxstring : NULL))) < 0) {
  6245.         if (y == -3) {
  6246.         printf("?Variable name required\n");
  6247.         return(-9);
  6248.         } else return(y);
  6249.     }
  6250.     ckstrncpy(vnambuf,s,VNAML);    /* Make a copy. */
  6251.     vnp = vnambuf;
  6252.     if (vnambuf[0] == CMDQ &&
  6253.         (vnambuf[1] == '%' || vnambuf[1] == '&'))
  6254.       vnp++;
  6255.     y = 0;
  6256.     if (*vnp == '%' || *vnp == '&') {
  6257.         if ((y = parsevar(vnp,&x,&z)) < 0)
  6258.           return(y);
  6259.     }
  6260.     }
  6261.     if ((x = cmtxt("Integer arithmetic expression","",&s,xxstring)) < 0)
  6262.       return(x);
  6263.     p = evala(s);
  6264.     if (!p) p = "";
  6265.     if (oldeval && *p)
  6266.       printf("%s\n", p);
  6267.     ckstrncpy(evalbuf,p,32);
  6268.     if (!oldeval)
  6269.       return(success = addmac(vnambuf,p));
  6270.     else
  6271.       return(success = *p ? 1 : 0);
  6272. }
  6273. #endif /* NOSPL */
  6274.  
  6275. #ifdef TNCODE
  6276. static int
  6277. dotelopt() {
  6278.     if ((x = cmkey(telcmd, ntelcmd, "TELNET command", "", xxstring)) < 0 )
  6279.       return(x);
  6280.     switch (x) {
  6281.       case WILL:
  6282.       case WONT:
  6283.       case DO:
  6284.       case DONT:
  6285.     if ((y = cmkey(tnopts,ntnopts,"TELNET option","",xxstring)) < 0)
  6286.       return(y);
  6287.     if ((z = cmcfm()) < 0) return(z);
  6288.  
  6289.     switch (x) {
  6290.       case WILL:
  6291.         if (TELOPT_UNANSWERED_WILL(y))
  6292.           return(success = 0);
  6293.         break;
  6294.       case WONT:
  6295.         if (TELOPT_UNANSWERED_WONT(y))
  6296.           return(success = 0);
  6297.         break;
  6298.       case DO:
  6299.         if (TELOPT_UNANSWERED_DO(y))
  6300.           return(success = 0);
  6301.         break;
  6302.       case DONT:
  6303.         if (TELOPT_UNANSWERED_DONT(y))
  6304.           return(success = 0);
  6305.         break;
  6306.     }
  6307.     if (local) {
  6308.         success = ((tn_sopt(x,y) > -1) ? 1 : 0);
  6309.     } else {
  6310.         printf("ff%02x%02x\n",x,y);
  6311.         success = 1;
  6312.     }
  6313.     if (success) {
  6314.         switch (x) {
  6315.           case WILL:
  6316.         TELOPT_UNANSWERED_WILL(y) = 1;
  6317.         break;
  6318.           case WONT:
  6319.         if ( TELOPT_ME(y) )
  6320.           TELOPT_UNANSWERED_WONT(y) = 1;
  6321.         break;
  6322.           case DO:
  6323.         TELOPT_UNANSWERED_DO(y) = 1;
  6324.         break;
  6325.           case DONT:
  6326.         if ( TELOPT_ME(y) )
  6327.           TELOPT_UNANSWERED_DONT(y) = 1;
  6328.         break;
  6329.         }
  6330.         if (tn_wait("XXTELOP") < 0) {
  6331.         tn_push();
  6332.         success = 0;
  6333.         }
  6334.     }
  6335.     return(success);
  6336.       case SB:
  6337.     if ((y=cmkey(tnsbopts,ntnsbopts,"TELNET option","",xxstring)) < 0)
  6338.       return(y);
  6339.     switch (y) {
  6340.       case TELOPT_NAWS:
  6341.         /* Some compilers require switch() to have at least 1 case */
  6342. #ifdef CK_NAWS
  6343.         TELOPT_SB(TELOPT_NAWS).naws.x = 0;
  6344.         TELOPT_SB(TELOPT_NAWS).naws.y = 0;
  6345.         if (local)
  6346.           return(success = ((tn_snaws() > -1) ? 1 : 0));
  6347.         else
  6348.           return(success = 0);
  6349. #else
  6350.         return(success = 0);
  6351. #endif /* CK_NAWS */
  6352.     }
  6353.         return(success = 0);
  6354.  
  6355. #ifdef CK_KERBEROS
  6356. #ifdef KRB5
  6357.       case TN_FWD:
  6358.         success = (kerberos5_forward() == AUTH_SUCCESS);
  6359.         return(success);
  6360. #endif /* KRB5 */
  6361. #endif /* CK_KERBEROS */
  6362.  
  6363.       default:
  6364.     if ((z = cmcfm()) < 0) return(z);
  6365.     if (local) {
  6366.         CHAR temp[3];
  6367.         if (network && (ttnproto == NP_TELNET)) { /* TELNET */
  6368.         temp[0] = (CHAR) IAC;
  6369.         temp[1] = x;
  6370.         temp[2] = NUL;
  6371.         success = (ttol((CHAR *)temp,2) > -1 ? 1 : 0);
  6372.         if (tn_deb || debses || deblog) {
  6373.             /* TN_MSG_LEN is in ckctel.h */
  6374.             ckmakmsg(tn_msg,256,"TELNET SENT ",TELCMD(x),NULL,NULL);
  6375.             debug(F101,tn_msg,"",x);
  6376.             if (debses || tn_deb) tn_debug(tn_msg);
  6377.         }
  6378.         return(success);
  6379.         }
  6380.             return(success = 0);
  6381.     } else {
  6382.         printf("ff%02x\n",x);
  6383.         return(success = 1);
  6384.     }
  6385.     }
  6386. }
  6387. #endif /* TNCODE */
  6388.  
  6389.  
  6390. #ifndef NOPUSH
  6391. #ifndef NOFRILLS
  6392. static int
  6393. doedit() {
  6394. #ifdef OS2
  6395.     char * p = NULL;
  6396. #endif /* OS2 */
  6397.     if (!editor[0]) {
  6398.     s = getenv("EDITOR");
  6399.     if (s) ckstrncpy(editor,s,CKMAXPATH);
  6400.     editor[CKMAXPATH] = NUL;
  6401.     if (!editor[0]) {
  6402.         printf("?Editor not defined - use SET EDITOR to define\n");
  6403.         return(-9);
  6404.     }
  6405.     }
  6406.     ckstrncpy(tmpbuf,editfile,TMPBUFSIZ);
  6407. /*
  6408.   cmiofi() lets us parse the name of an existing file, or the name of
  6409.   a nonexistent file to be created.
  6410. */
  6411.     x = cmiofi("File to edit", (char *)tmpbuf, &s, &y, xxstring);
  6412.     if (x < 0) {
  6413.     if (x == -9) {
  6414.         if (zchko(s) < 0) {
  6415.         printf("Can't create \"%s\"\n",s);
  6416.         return(x);
  6417.         }
  6418.     } else if (x != -3)
  6419.       return(x);
  6420.     }
  6421.     if (x == -3)
  6422.       tmpbuf[0] = NUL;
  6423.     else {
  6424.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  6425.     if (iswild((char *)tmpbuf)) {
  6426.         printf("?A single file please\n");
  6427.         return(-9);
  6428.     }
  6429.     }
  6430.     if ((z = cmcfm()) < 0) return(z);
  6431.     if (nopush) {
  6432.     printf("?Sorry, editing not allowed\n");
  6433.     return(success = 0);
  6434.     }
  6435.     if (tmpbuf[0]) {
  6436.     /* Get full path in case we change directories between EDIT commands */
  6437.     zfnqfp(tmpbuf, CKMAXPATH, editfile);
  6438.     editfile[CKMAXPATH] = NUL;
  6439. #ifdef OS2
  6440.     p = editfile;            /* Flip the stupid slashes */
  6441.     while (*p) {
  6442.         if (*p == '/') *p = '\\';
  6443.         p++;
  6444.     }
  6445. #endif /* OS2 */
  6446.     } else
  6447.       editfile[0] = NUL;
  6448.     x = 0;
  6449.     if (editopts[0]) {
  6450. #ifdef OS2
  6451.     x = ckindex("%1",(char *)editopts,0,0,1);
  6452.     if (x > 0)
  6453.       editopts[x] = 's';
  6454.     else
  6455. #endif /* OS2 */
  6456.       x = ckindex("%s",(char *)editopts,0,0,1);
  6457.     }
  6458.     if (((int)strlen(editopts) + (int)strlen(editfile) + 1) < TMPBUFSIZ) {
  6459.     if (x)
  6460.       sprintf(tmpbuf,editopts,editfile);
  6461.     else
  6462.       sprintf(tmpbuf,"%s %s",editopts,editfile);
  6463.     }
  6464.     s = line;
  6465.     ckmakmsg(s,LINBUFSIZ,editor," ",tmpbuf,NULL);
  6466. #ifdef OS2
  6467.     p = s + strlen(editor);        /* And again with the slashes */
  6468.     while (p != s) {
  6469.     if (*p == '/') *p = '\\';
  6470.     p--;
  6471.     }
  6472. #endif /* OS2 */
  6473.     conres();
  6474.     x = zshcmd(s);
  6475.     concb((char)escape);
  6476.     return(x);
  6477. }
  6478. #endif /* NOFRILLS */
  6479. #endif /* NOPUSH */
  6480.  
  6481. #ifdef BROWSER
  6482. static int
  6483. dobrowse() {
  6484. #ifdef OS2
  6485.     char * p = NULL;
  6486. #endif /* OS2 */
  6487.     if (nopush) {
  6488.     printf("?Sorry, browsing not allowed\n");
  6489.     return(success = 0);
  6490.     }
  6491. #ifndef NT
  6492.     /* Windows lets the Shell Execute the URL if no Browser is defined */
  6493.     if (!browser[0]) {
  6494.     s = getenv("BROWSER");
  6495.     if (s) ckstrncpy(browser,s,CKMAXPATH);
  6496.     browser[CKMAXPATH] = NUL;
  6497.     if (!browser[0]) {
  6498.         printf("?Browser not defined - use SET BROWSER to define\n");
  6499.         return(-9);
  6500.     }
  6501.     }
  6502. #endif /* NT */
  6503.     ckstrncpy(tmpbuf,browsurl,TMPBUFSIZ);
  6504.     if ((x = cmtxt("URL",(char *)browsurl,&s,xxstring)) < 0)
  6505.       return(x);
  6506.     ckstrncpy(browsurl,s,4096);
  6507.     x = 0;
  6508.     if (browsopts[0]) {
  6509. #ifdef OS2
  6510.     x = ckindex("%1",(char *)browsopts,0,0,1);
  6511.     if (x > 0)
  6512.       browsopts[x] = 's';
  6513.     else
  6514. #endif /* OS2 */
  6515.       x = ckindex("%s",(char *)browsopts,0,0,1);
  6516.     }
  6517.     if (((int)strlen(browsopts) + (int)strlen(browsurl) + 1) < TMPBUFSIZ) {
  6518.     if (x)
  6519.       sprintf(tmpbuf,browsopts,browsurl);
  6520.     else
  6521.       sprintf(tmpbuf,"%s %s",browsopts,browsurl);
  6522.     }
  6523. #ifdef NT
  6524.     if (!browser[0])
  6525.       return(success = Win32ShellExecute(browsurl));
  6526. #endif /* NT */
  6527.     s = line;
  6528.     ckmakmsg(s,LINBUFSIZ,browser," ",tmpbuf,NULL);
  6529. #ifdef OS2
  6530.     p = line + strlen(browser);        /* Flip slashes */
  6531.     while (p != line) {
  6532.     if (*p == '/') *p = '\\';
  6533.     p--;
  6534.     }
  6535. #endif /* OS2 */
  6536.     conres();
  6537.     x = zshcmd(s);
  6538.     concb((char)escape);
  6539.     return(x);
  6540. }
  6541. #endif /* BROWSER */
  6542.  
  6543. #ifdef CK_RECALL
  6544. static int
  6545. doredo() {            /* Find a previous cmd and redo it */
  6546.     extern int on_recall, in_recall;
  6547.     int x;
  6548.     char * p;
  6549.  
  6550.     if ((x = cmtxt(
  6551. "pattern, or first few characters of a previous command",
  6552.            "*",&s,xxstring)) < 0)
  6553.       return(x);
  6554.     ckstrncpy(line,s,LINBUFSIZ);
  6555.     x = strlen(s);
  6556.     s = line;
  6557.     if (*s == '{') {            /* Braces disable adding * to end */
  6558.     if (s[x-1] == '}') {
  6559.         s[x-1] = NUL;
  6560.         s++;
  6561.         x--;
  6562.     }
  6563.     } else {                /* No braces, add * to end. */
  6564.     s[x] = '*';
  6565.     s[x+1] = NUL;
  6566.     }
  6567.  
  6568.     while (x > 0 && s[x] == '*' && s[x-1] == '*') s[x--] = NUL;
  6569.  
  6570.     if (!on_recall || !in_recall) {
  6571.     printf("?Sorry, command recall can't be used now.\n");
  6572.     return(-9);
  6573.     }
  6574.     if ((p = cmgetcmd(s))) {        /* Look for it history buffer */
  6575.     ckmakmsg(cmdbuf,CMDBL,p,"\r",NULL,NULL); /* Copy to command buffer */
  6576.     cmaddnext();            /* Force re-add to history buffer */
  6577.     return(cmflgs = -1);        /* Force reparse */
  6578.     } else {
  6579.     printf("?Sorry - \"%s\" not found\n", s);
  6580.     return(-9);
  6581.     }
  6582. }
  6583. #endif /* CK_RECALL */
  6584.  
  6585. #ifndef NOXFER
  6586. #ifndef NOCSETS
  6587. static int
  6588. doassoc()  {                /* ASSOCIATE */
  6589.     extern struct keytab tcstab[];
  6590.     extern int ntcs;
  6591.     if ((x = cmkey(assoctab, nassoc, "", "", xxstring)) < 0 )
  6592.       return(x);
  6593.  
  6594.     switch (x) {            /* Associate what? */
  6595.  
  6596.       case ASSOC_TC:            /* Transfer character-set... */
  6597.     if ((x = cmkey(tcstab, ntcs,
  6598.                "transfer character-set name","",xxstring)) < 0)
  6599.       return(x);
  6600.     if ((y = cmkey(fcstab, nfilc,
  6601.                "with file character-set","", xxstring)) < 0)
  6602.       if (y != -3)
  6603.         return(y);
  6604.     if ((z = cmcfm()) < 0)
  6605.       return(z);
  6606.     axcset[x] = y;
  6607.     return(success = 1);
  6608.  
  6609.       case ASSOC_FC:            /* File character-set... */
  6610.     if ((x = cmkey(fcstab, nfilc,
  6611.                "file character-set name","",xxstring)) < 0)
  6612.       return(x);
  6613.     if ((y = cmkey(tcstab, ntcs,
  6614.                "with transfer character-set","", xxstring)) < 0)
  6615.       if (y != -3)
  6616.         return(y);
  6617.     if ((z = cmcfm()) < 0)
  6618.       return(z);
  6619.     afcset[x] = y;
  6620.     return(success = 1);
  6621.  
  6622.       default:
  6623.     return(-2);
  6624.     }
  6625. }
  6626. #endif /* NOCSETS */
  6627. #endif /* NOXFER */
  6628.  
  6629. #ifndef NOHELP
  6630. static int
  6631. domanual() {
  6632. #ifdef OS2
  6633.     if ((x = cmcfm()) < 0)
  6634.       return(x);
  6635.     if (nopush) {
  6636.     printf("?Sorry, access to system commands is disabled.\n");
  6637.     return(-9);
  6638.     }
  6639.     y = mxlook(mactab,"manual",nmac);
  6640.     if (y > -1) {
  6641.     z = maclvl;            /* Save the current maclvl */
  6642.     dodo(y,NULL,cmdstk[cmdlvl].ccflgs); /* Run the macro */
  6643.     while (maclvl > z) {
  6644.         debug(F101,"XXMAN loop maclvl 1","",maclvl);
  6645.         sstate = (CHAR) parser(1);
  6646.         debug(F101,"XXMAN loop maclvl 2","",maclvl);
  6647.         if (sstate) proto();
  6648.     }
  6649.     debug(F101,"XXMAN loop exit maclvl","",maclvl);
  6650.     return(success);
  6651.     }
  6652.     return(success = 0);
  6653. #else
  6654.     if ((x = cmtxt(
  6655. #ifdef UNIX
  6656.            "Carriage return to confirm the command, or manual topic",
  6657. #else
  6658.            "Carriage return to confirm the command, or help topic",
  6659. #endif /* UNIX */
  6660.            "kermit",
  6661.            &s,
  6662.            xxstring
  6663.            )
  6664.      ) < 0)
  6665.       return(x);
  6666. #endif /* OS2 */
  6667.  
  6668. #ifdef UNIX
  6669.     ckmakmsg(tmpbuf,TMPBUFSIZ,"man ",s,NULL,NULL);
  6670. #else
  6671.     ckmakmsg(tmpbuf,TMPBUFSIZ,"help ",s,NULL,NULL);
  6672. #endif /* UNIX */
  6673.     debug(F110,"MANUAL",tmpbuf,0);
  6674.     if (nopush) {
  6675.     printf("?Sorry, access to system commands is disabled.\n");
  6676.     return(-9);
  6677.     } else {
  6678.     conres();            /* Restore the console */
  6679.     success = zshcmd(tmpbuf);
  6680.     concb((char)escape);        /* Restore CBREAK mode */
  6681.     return(success);
  6682.     }
  6683. }
  6684. #endif /* NOHELP */
  6685.  
  6686. #ifndef NOHTTP
  6687. #ifdef TCPSOCKET
  6688. static struct keytab sslswtab[] = {
  6689.     { "/ssl", 1, 0 },
  6690.     { "/tls", 1, 0 }
  6691. };
  6692.  
  6693. #ifndef NOURL
  6694. struct urldata http_url = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};
  6695. #endif /* NOURL */
  6696.  
  6697. static int
  6698. dohttp() {                /* HTTP */
  6699.     struct FDB sw, kw, fi;
  6700.     int n, getval, allinone = 0;
  6701.     char c, * p;
  6702.     char rdns[128];
  6703.  
  6704.     char * http_agent = NULL;        /* Parse results */
  6705.     char * http_hdr   = NULL;
  6706.     char * http_user  = NULL;
  6707.     char * http_pass  = NULL;
  6708.     char * http_mime  = NULL;
  6709.     char * http_lfile = NULL;
  6710.     char * http_rfile = NULL;
  6711.     char * http_dfile = NULL;
  6712.     char   http_array = NUL;
  6713.     int    http_action = -1;
  6714.  
  6715.     char * http_host = NULL;
  6716.     char * http_srv  = NULL;
  6717.     int    http_ssl  = 0;
  6718.  
  6719.     static char * http_d_agent = NULL;
  6720.     static char * http_d_user = NULL;
  6721.     static char * http_d_pass = NULL;
  6722.  
  6723.     static int    http_d_type = 0;
  6724.     int           http_type = http_d_type;
  6725.  
  6726. #ifdef OS2
  6727.     p = "Kermit 95";            /* Default user agent */
  6728. #else
  6729.     p = "C-Kermit";
  6730. #endif /* OS2 */
  6731.     makestr(&http_agent,p);
  6732.     makestr(&http_mime,"text/HTML");    /* MIME type default */
  6733.     rdns[0] = '\0';
  6734.  
  6735.     cmfdbi(&sw,                /* 1st FDB - general switches */
  6736.        _CMKEY,                /* fcode */
  6737.        "OPEN, CLOSE, GET, HEAD, PUT, INDEX, or POST,\n or switch", /* hlpmsg */
  6738.        "",                /* default */
  6739.        "",                /* addtl string data */
  6740.        nhttpswtab,            /* addtl numeric data 1: tbl size */
  6741.        4,                /* addtl numeric data 2: 4 = cmswi */
  6742.        xxstring,            /* Processing function */
  6743.        httpswtab,            /* Keyword table */
  6744.        &kw                /* Pointer to next FDB */
  6745.        );
  6746.     cmfdbi(&kw,                /* 2nd FDB - commands */
  6747.        _CMKEY,                /* fcode */
  6748.        "Command",            /* hlpmsg */
  6749.        "",                /* default */
  6750.        "",                /* addtl string data */
  6751.        nhttptab,            /* addtl numeric data 1: tbl size */
  6752.        0,                /* addtl numeric data 2: 0 = keyword */
  6753.        xxstring,            /* Processing function */
  6754.        httptab,                /* Keyword table */
  6755.        NULL                /* Pointer to next FDB */
  6756.        );
  6757.  
  6758.     while (1) {
  6759.     x = cmfdb(&sw);            /* Parse something */
  6760.     if (x < 0)            /* Error */
  6761.       goto xhttp;
  6762.     n = cmresult.nresult;
  6763.     if (cmresult.fdbaddr == &kw)    /* Command - exit this loop */
  6764.       break;
  6765.     c = cmgbrk();            /* Switch... */
  6766.     getval = (c == ':' || c == '=');
  6767.     x = -9;
  6768.     if (getval && !(cmgkwflgs() & CM_ARG)) {
  6769.         printf("?This switch does not take an argument\n");
  6770.         goto xhttp;
  6771.     }
  6772.     switch (cmresult.nresult) {    /* Handle each switch */
  6773.           case HT_SW_TP:                /* /TOSCREEN */
  6774.             http_type = 1;
  6775.             break;
  6776.       case HT_SW_AG:        /* /AGENT */
  6777.         if (getval) {
  6778.         if ((x = cmfld("User agent",p,&s,xxstring)) < 0)
  6779.           goto xhttp;
  6780.         } else {
  6781.         s = p;
  6782.         }
  6783.         makestr(&http_agent,s);
  6784.         break;
  6785.       case HT_SW_HD:        /* /HEADER */
  6786.         s = NULL;
  6787.         if (getval) {
  6788.         if ((x = cmfld("Header line","",&s,xxstring)) < 0) {
  6789.             if (x == -3)
  6790.               s = NULL;
  6791.             else
  6792.               goto xhttp;
  6793.         }
  6794.         }
  6795.         makestr(&http_hdr,s);
  6796.         break;
  6797.       case HT_SW_US:        /* /USER */
  6798.         s = NULL;
  6799.         if (getval) {
  6800.         if ((x = cmfld("User ID","",&s,xxstring)) < 0) {
  6801.                   if (x == -3)
  6802.                     s = "";
  6803.                   else
  6804.             goto xhttp;
  6805.                 }
  6806.         }
  6807.         makestr(&http_user,s);
  6808.         break;
  6809.       case HT_SW_PW:        /* /PASSWORD */
  6810.         debok = 0;
  6811.         s = NULL;
  6812.         if (getval) {
  6813.         if ((x = cmfld("Password","",&s,xxstring)) < 0)
  6814.           goto xhttp;
  6815.         }
  6816.         makestr(&http_pass,s);
  6817.         break;
  6818. #ifndef NOSPL
  6819.       case HT_SW_AR: {        /* /ARRAY: */
  6820.           char * s2, array = NUL;
  6821.           if (!getval) {
  6822.           printf("?This switch requires an argument\n");
  6823.           x = -9;
  6824.           goto xhttp;
  6825.           }
  6826.           if ((x = cmfld("Array name (a single letter will do)",
  6827.                  "",
  6828.                  &s,
  6829.                  NULL
  6830.                  )) < 0) {
  6831.           if (x == -3) {
  6832.               printf("?Array name required\n");
  6833.               x = -9;
  6834.               goto xhttp;
  6835.           } else
  6836.             goto xhttp;
  6837.           }
  6838.           if (!*s) {
  6839.           printf("?Array name required\n");
  6840.           x = -9;
  6841.           goto xhttp;
  6842.           }
  6843.           s2 = s;
  6844.           if (*s == CMDQ) s++;
  6845.           if (*s == '&') s++;
  6846.           if (!isalpha(*s)) {
  6847.           printf("?Bad array name - \"%s\"\n",s2);
  6848.           x = -9;
  6849.           goto xhttp;
  6850.           }
  6851.           array = *s++;
  6852.           if (isupper(array))
  6853.         array = tolower(array);
  6854.           if (*s && (*s != '[' || *(s+1) != ']')) {
  6855.           printf("?Bad array name - \"%s\"\n",s2);
  6856.           http_array = NUL;
  6857.           x = -9;
  6858.           goto xhttp;
  6859.           }
  6860.           http_array = array;
  6861.           break;
  6862.       }
  6863. #endif /* NOSPL */
  6864.       default:
  6865.         x = -2;
  6866.         goto xhttp;
  6867.     }
  6868.     }
  6869.     http_action = n;            /* Save the action */
  6870.     if (http_action == HTTP_PUT || http_action == HTTP_POS) {
  6871.     cmfdbi(&sw,            /* 1st FDB - switch */
  6872.            _CMKEY,            /* fcode */
  6873.            "Local filename\n Or switch", /* help */
  6874.            "",            /* default */
  6875.            "",            /* addtl string data */
  6876.            nhttpptab,        /* keyword table size */
  6877.            4,            /* addtl numeric data 2: 4 = cmswi */
  6878.            xxstring,        /* Processing function */
  6879.            httpptab,        /* Keyword table */
  6880.            &fi            /* Pointer to next FDB */
  6881.            );
  6882.     cmfdbi(&fi,            /* 2nd FDB - filename */
  6883.            _CMIFI,            /* fcode */
  6884.            "Local filename",    /* hlpmsg */
  6885.            "",            /* default */
  6886.            "",            /* addtl string data */
  6887.            0,            /* addtl numeric data 1 */
  6888.            0,            /* addtl numeric data 2 */
  6889.            xxstring,
  6890.            NULL,
  6891.            NULL
  6892.            );
  6893.     while (1) {
  6894.         x = cmfdb(&sw);
  6895.         if (x < 0)
  6896.           goto xhttp;        /* Free any malloc'd temp strings */
  6897.         n = cmresult.nresult;
  6898.         if (cmresult.fcode != _CMKEY)
  6899.           break;
  6900.         c = cmgbrk();        /* Switch... */
  6901.         getval = (c == ':' || c == '=');
  6902.         if (getval && !(cmgkwflgs() & CM_ARG)) {
  6903.         printf("?This switch does not take an argument\n");
  6904.         x = -9;
  6905.         goto xhttp;
  6906.         }
  6907.         switch (n) {
  6908.           case HT_PP_MT:
  6909.         s = "text/HTML";
  6910.         if (getval) {
  6911.             if ((x = cmfld("MIME type",
  6912.                    "text/HTML",&s,xxstring)) < 0)
  6913.               goto xhttp;
  6914.         }
  6915.         makestr(&http_mime,s);
  6916.         break;
  6917.           default:
  6918.         x = -2;
  6919.         goto xhttp;
  6920.         }
  6921.     }
  6922.     makestr(&http_lfile,cmresult.sresult);
  6923.     n = ckindex("/",http_lfile,-1,1,0);
  6924.     if (n)
  6925.       p = &http_lfile[n];
  6926.     else
  6927.       p = http_lfile;
  6928.     if ((x = cmfld("URL or remote filename",p,&s,xxstring)) < 0) {
  6929.           if (x == -3) {
  6930.             printf("?%s what?\n",(http_action == HTTP_PUT) ? "Put" : "Post");
  6931.             x = -9;
  6932.           }
  6933.           goto xhttp;
  6934.         }
  6935.     if (!*s) s = NULL;
  6936.     makestr(&http_rfile,s);
  6937.  
  6938.     if ((x = cmtxt("Response filename","",&s,xxstring)) < 0) {
  6939.           if (x != -3)
  6940.             goto xhttp;
  6941.         }
  6942.         if (*s)
  6943.           makestr(&http_dfile,s);
  6944.     }
  6945.     switch (http_action) {
  6946.       case HTTP_DEL:            /* DELETE */
  6947.     if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
  6948.           if (x == -3) {
  6949.             printf("?Delete what?\n");
  6950.             x = -9;
  6951.           }
  6952.           goto xhttp;
  6953.         }
  6954.     makestr(&http_rfile,s);
  6955.     break;
  6956.       case HTTP_CON:            /* CONNECT */
  6957.         if ((x = cmfld("Remote host[:port]","",&s,xxstring)) < 0) {
  6958.           if (x == -3) {
  6959.             printf("?Remote host[:port] is required\n");
  6960.             x = -9;
  6961.           }
  6962.           goto xhttp;
  6963.         }
  6964.     makestr(&http_rfile,s);
  6965.     break;
  6966.       case HTTP_HED: {            /* HEAD */
  6967.       char buf[CKMAXPATH+1];
  6968.       if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
  6969.           if (x == -3) {
  6970.           printf("?Head of what?\n");
  6971.           x = -9;
  6972.           }
  6973.           goto xhttp;
  6974.       }
  6975.       makestr(&http_rfile,s);
  6976.  
  6977.       if (http_array || http_type) { /* Default result filename */
  6978.           p = "";             /* None if /ARRAY or /TOSCREEN */
  6979.       } else {
  6980.           n = ckindex("/",http_rfile,-1,1,0); /* Otherwise strip path */
  6981.           if (n)                          /* and add ".head" */
  6982.         p = &http_rfile[n];
  6983.           else
  6984.         p = http_rfile;
  6985.           ckmakmsg(buf,CKMAXPATH,p,".head",NULL,NULL);
  6986.           p = buf;
  6987.       }
  6988.       if ((x = cmofi("Local filename",p,&s,xxstring)) < 0) {
  6989.           if (x != -3)
  6990.         goto xhttp;
  6991.       }
  6992.       makestr(&http_lfile,s);
  6993.       break;
  6994.       }
  6995.       case HTTP_GET:            /* GET */
  6996.       case HTTP_IDX: {            /* INDEX */
  6997.       char * lfile = "";
  6998.       if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
  6999.           if (x == -3) {
  7000.           printf("?Get what?\n");
  7001.           x = -9;
  7002.           }
  7003.           goto xhttp;
  7004.       }
  7005.       makestr(&http_rfile,s);
  7006.       if (http_action == HTTP_GET && !http_type)
  7007.         zstrip(http_rfile,&lfile);
  7008.       if ((x = cmofi("Local filename",lfile,&s,xxstring)) < 0)
  7009.         if (x != -3)
  7010.           goto xhttp;
  7011.       makestr(&http_lfile,s);
  7012.       break;
  7013.       }
  7014.       case HTTP_OPN: {
  7015.       int sslswitch = 0;
  7016. #ifdef CK_SSL
  7017.       struct FDB sw, fl;
  7018.       cmfdbi(&sw,
  7019.          _CMKEY,        /* fcode */
  7020.          "IP host name or address, or switch", /* hlpmsg */
  7021.          "",            /* default */
  7022.          "",            /* addtl string data */
  7023.          2,            /* addtl numeric data 1: tbl size */
  7024.          4,            /* addtl numeric data 2: 4 = cmswi */
  7025.          xxstring,        /* Processing function */
  7026.          sslswtab,        /* Keyword table */
  7027.          &fl            /* Pointer to next FDB */
  7028.          );
  7029.       cmfdbi(&fl,            /* 2nd FDB - host */
  7030.          _CMFLD,        /* fcode */
  7031.          "",            /* hlpmsg */
  7032.          "",            /* default */
  7033.          "",            /* addtl string data */
  7034.          0,            /* addtl numeric data 1 */
  7035.          0,            /* addtl numeric data 2 */
  7036.          xxstring,
  7037.          NULL,
  7038.          NULL
  7039.          );
  7040.       x = cmfdb(&sw);        /* Parse switch or host */
  7041.       if (x < 0)            /* Error */
  7042.         goto xhttp;
  7043.       if (cmresult.fcode == _CMFLD) { /* Host */
  7044.           s = cmresult.sresult;      /* Set up expected pointer */
  7045.           goto havehost;              /* Go parse rest of command */
  7046.       }
  7047.       sslswitch = 1;        /* /SSL or /TLS switch - set flag */
  7048. #endif /* CK_SSL */
  7049.  
  7050.       /* Parse host */
  7051.  
  7052.       if ((x = cmfld("URL, hostname, or ip-address","",&s,xxstring)) < 0) {
  7053.           if (x == -3) {
  7054.           printf("?Open what?\n");
  7055.           x = -9;
  7056.           }
  7057.           goto xhttp;
  7058.       }
  7059.  
  7060.     havehost:            /* Come here with s -> host */
  7061. #ifdef CK_URL
  7062.       x = urlparse(s,&http_url);    /* Was a URL given? */
  7063.       if (x < 1) {            /* Not a URL */
  7064. #endif /* CK_URL */
  7065.           makestr(&http_host,s);
  7066.           if ((x =
  7067.            cmfld("Service name or port number",
  7068.              "http",&s,xxstring)) < 0)
  7069.         goto xhttp;
  7070.           else
  7071.         makestr(&http_srv,s);
  7072. #ifdef CK_URL
  7073.       } else if (ckstrcmp(http_url.svc,"http",-1,0) && /* Non-HTTP URL */
  7074.              ckstrcmp(http_url.svc,"https",-1,0)) {
  7075.           printf("?Non-HTTP URL\n");
  7076.           x = -9;
  7077.           goto xhttp;
  7078.       } else {            /* Have HTTP URL */
  7079.           makestr(&http_srv, http_url.svc);
  7080.           makestr(&http_user,http_url.usr);
  7081.           makestr(&http_pass,http_url.psw);
  7082.           makestr(&http_host,http_url.hos);
  7083.           if (http_url.por)
  7084.         makestr(&http_srv,http_url.por);
  7085.           makestr(&http_rfile,http_url.pth);
  7086.       }          
  7087.       if (http_rfile) {        /* Open, GET, and Close */
  7088.           printf("?Directory/file path not allowed in HTTP OPEN URL\n");
  7089.           x = -9;
  7090.           goto xhttp;
  7091.       }
  7092.       if (!ckstrcmp("https",http_srv,-1,0) || sslswitch ||
  7093.           !ckstrcmp("443",http_srv,-1,0))
  7094.         http_ssl = 1;
  7095. #endif /* CK_URL */
  7096.       break;
  7097.       }
  7098.       case HTTP_CLS:
  7099.         break;
  7100.     }
  7101.     if ((x = cmcfm()) < 0)
  7102.       goto xhttp;
  7103.  
  7104.     if (http_action == HTTP_OPN) {
  7105.         x = (http_open(http_host,http_srv,http_ssl,rdns,128) == 0);
  7106.         if (x) {
  7107.             if (!quiet) {
  7108.               if (rdns[0])
  7109.                 printf("Connected to %s [%s]\r\n",http_host,rdns);
  7110.               else
  7111.                 printf("Connected to %s\r\n",http_host);
  7112.             }
  7113.             if (http_agent) {
  7114.                 if (http_d_agent)
  7115.           free(http_d_agent);
  7116.                 http_d_agent = http_agent;
  7117.                 http_agent = NULL;
  7118.             }
  7119.             if (http_user) {
  7120.                 if (http_d_user)
  7121.           free(http_d_user);
  7122.                 http_d_user = http_user;
  7123.                 http_user = NULL;
  7124.             }
  7125.             if (http_pass) {
  7126.                 if (http_d_pass) {
  7127.                     memset(http_d_pass,0,strlen(http_d_pass));
  7128.                     free(http_d_pass);
  7129.                 }
  7130.                 http_d_pass = http_pass;
  7131.                 http_pass = NULL;
  7132.             }
  7133.             http_d_type = http_type;
  7134.         } else {
  7135.             if (!quiet)
  7136.           printf("?HTTP Connection failed.\r\n");
  7137.         }
  7138.     } else if (http_action == HTTP_CLS) {
  7139.         if (http_d_agent) {
  7140.             free(http_d_agent);
  7141.             http_d_agent = NULL;
  7142.         }
  7143.         if (http_d_user) {
  7144.             free(http_d_user);
  7145.             http_d_user = NULL;
  7146.         }
  7147.         if (http_d_pass) {
  7148.             memset(http_d_pass,0,strlen(http_d_pass));
  7149.             free(http_d_pass);
  7150.             http_d_pass = NULL;
  7151.         }
  7152.         http_d_type = 0;
  7153.         x = (http_close() == 0);
  7154.     }
  7155.     if ((http_action != HTTP_CLS) &&
  7156.     (http_action != HTTP_CON) && http_rfile) { /* Remote file is URL? */
  7157.  
  7158.     /* All-in-one actions when a URL is given... */
  7159.  
  7160. #ifdef CK_URL
  7161.     if (urlparse(http_rfile,&http_url) > 0) { /* Have URL? */
  7162.         if (ckstrcmp(http_url.svc,"http",-1,0) && /* It's an HTTP URL? */
  7163.         ckstrcmp(http_url.svc,"https",-1,0)) {
  7164.         printf("?Non-HTTP URL\n");
  7165.         x = -9;
  7166.         goto xhttp;
  7167.         } else {            /* Yes, collect the pieces */
  7168.         makestr(&http_srv, http_url.svc);
  7169.         makestr(&http_user,http_url.usr);
  7170.         makestr(&http_pass,http_url.psw);
  7171.         makestr(&http_host,http_url.hos);
  7172.         if (http_url.por)
  7173.           makestr(&http_srv,http_url.por);
  7174.         makestr(&http_rfile,http_url.pth);
  7175.         }          
  7176.         if (!http_rfile) {        /* Still have a path? */
  7177.                 makestr(&http_rfile,"/");
  7178.         }
  7179.         if (!ckstrcmp("https",http_srv,-1,0) || /* Check for SSL/TLS */
  7180.         !ckstrcmp("443",http_srv,-1,0))
  7181.           http_ssl = 1;
  7182.         if (http_isconnected())    /* Close any open HTTP connection */
  7183.           http_close();
  7184.         if (http_pass == NULL && http_d_pass != NULL)
  7185.           makestr(&http_pass,http_d_pass);
  7186.         x = (http_open(http_host,http_srv,http_ssl,rdns,128) == 0);
  7187.         if (x < 0) {
  7188.         x = 0;
  7189.         goto xhttp;
  7190.         }
  7191.         allinone = 1;
  7192.     }
  7193. #endif /* CK_URL */
  7194.         if (http_pass == NULL && http_d_pass != NULL)
  7195.       makestr(&http_pass,http_d_pass);
  7196.  
  7197.     if (http_action == HTTP_OPN && allinone) {
  7198.         http_action = HTTP_GET;
  7199.     }
  7200.         x = xdohttp(http_action,
  7201.                     http_lfile,
  7202.             http_rfile,
  7203.                     http_dfile,
  7204.             http_agent ? http_agent : http_d_agent,
  7205.             http_hdr,
  7206.             http_user  ? http_user  : http_d_user,
  7207.             http_pass  ? http_pass  : http_d_pass,
  7208.             http_mime,
  7209.             http_array,
  7210.             http_type
  7211.             );
  7212.     if (allinone)
  7213.       x = (http_close() == 0);
  7214.     }
  7215.  
  7216.   xhttp:
  7217.     if (http_agent) free(http_agent);
  7218.     if (http_hdr)   free(http_hdr);
  7219.     if (http_user)  free(http_user);
  7220.     if (http_pass) {
  7221.         memset(http_pass,0,strlen(http_pass));
  7222.         free(http_pass);
  7223.     }
  7224.     if (http_mime)  free(http_mime);
  7225.     if (http_lfile) free(http_lfile);
  7226.     if (http_rfile) free(http_rfile);
  7227.     if (http_dfile) free(http_dfile);
  7228.     if (http_host)  free(http_host);
  7229.     if (http_srv)   free(http_srv);
  7230.  
  7231.     if (x > -1)
  7232.       success = x;
  7233.     return(x);
  7234. }
  7235. #endif /* TCPSOCKET */
  7236. #endif /* NOHTTP */
  7237.  
  7238.  
  7239. #ifndef NOSPL
  7240. static int
  7241. dotrace() {
  7242.     int on = 1;
  7243.     struct FDB sw, kw;
  7244.     cmfdbi(&sw,                /* 1st FDB - switch */
  7245.        _CMKEY,            /* fcode */
  7246.        "Trace object;\n Or switch", /* help */
  7247.        "",                /* default */
  7248.        "",                /* addtl string data */
  7249.        2,                /* keyword table size */
  7250.        4,                /* addtl numeric data 2: 4 = cmswi */
  7251.        xxstring,            /* Processing function */
  7252.        onoffsw,            /* Keyword table */
  7253.        &kw                /* Pointer to next FDB */
  7254.        );
  7255.     cmfdbi(&kw,                /* 2nd FDB - Trace object */
  7256.        _CMKEY,            /* fcode */
  7257.        "Trace object",        /* help */
  7258.        "all",            /* default */
  7259.        "",                /* addtl string data */
  7260.        ntracetab,            /* keyword table size */
  7261.        0,                /* addtl numeric data 2: 0 = keyword */
  7262.        xxstring,            /* Processing function */
  7263.        tracetab,            /* Keyword table */
  7264.        NULL                /* Pointer to next FDB */
  7265.        );
  7266.     if ((x = cmfdb(&sw)) < 0)
  7267.       return(x);
  7268.     if (cmresult.fdbaddr == &sw) {
  7269.     on = cmresult.nresult;
  7270.     if ((x = cmkey(tracetab, ntracetab,"","all",xxstring)) < 0)
  7271.       return(x);
  7272.     } else {
  7273.     x = cmresult.nresult;
  7274.     }
  7275.     if ((y = cmcfm()) < 0)
  7276.       return(y);
  7277.  
  7278.     switch (x) {
  7279.       case TRA_ASG:
  7280.     tra_asg = on;
  7281.     break;
  7282.       case TRA_CMD:
  7283.     tra_cmd = on;
  7284.     break;
  7285.       case TRA_ALL:
  7286.     tra_asg = on;
  7287.     tra_cmd = on;
  7288.     break;
  7289.       default:
  7290.     return(-2);
  7291.     }
  7292.     printf("TRACE %s\n", on ? "ON" : "OFF");
  7293.     return(success = 1);
  7294. }
  7295. #endif /* NOSPL */
  7296.  
  7297.  
  7298. static int
  7299. doprompt() {
  7300.     extern int xcmdsrc;
  7301.     if ((x = cmtxt("Optional message","",&s,xxstring)) < 0)
  7302.       return(x);
  7303. #ifdef NOSPL
  7304.     printf("?Sorry, PROMPT requires script programming language\n");
  7305.     return(-9);
  7306. #else
  7307.     debug(F101,"Prompt cmdlvl","",cmdlvl);
  7308.     cmdlvl++;
  7309.     if (cmdlvl > CMDSTKL) {
  7310.     printf("?Command stack overflow: %d\n",cmdlvl);
  7311.     cmdlvl--;
  7312.     return(-9);
  7313.     }
  7314.     xcmdsrc = CMD_KB;
  7315.     cmdstk[cmdlvl].src = CMD_KB;    /* Say we're at the prompt */
  7316.     cmdstk[cmdlvl].lvl = 0;
  7317.     cmdstk[cmdlvl].ccflgs = cmdstk[cmdlvl-1].ccflgs;
  7318.     if (tra_cmd)
  7319.       printf("[%d] +P: \"(prompt)\"\n",cmdlvl);
  7320.     concb((char)escape);
  7321.     if (!quiet)
  7322.       printf("(Recursive command prompt; use END or RETURN to return...)\n");
  7323.  
  7324.     if (*s) {                /* If prompt given */
  7325.     makestr(&(prstring[cmdlvl-1]),cmgetp()); /* Save current prompt */
  7326.     cmsetp(s);            /* Set new one */
  7327.     }
  7328.     return(success = 1);
  7329. #endif /* NOSPL */
  7330. }
  7331.  
  7332. #ifdef CKLEARN
  7333. VOID
  7334. learncmd(s) char *s; {            /* Record commands in learned script */
  7335.     char buf[64];
  7336.     int i, k;
  7337.     if (learnfp && learning) {        /* Only if open and on */
  7338.     k = ckstrncpy(buf,s,64);
  7339.     for (i = 0; i < k; i++) {    /* Get top-level command keyword */
  7340.         if (buf[i] <= SP) {
  7341.         buf[i] = NUL;
  7342.         break;
  7343.         }
  7344.     }
  7345.     k = lookup(cmdtab,buf,ncmd,NULL); /* Look it up */
  7346.     if (k == XXCON || k == XXLEARN)      /* Don't record CONNECT or LEARN */
  7347.       return;
  7348.     if (k == XXTEL) {
  7349.         fputs("SET HOST /NETWORK:TCP",learnfp);
  7350.         fputs(&s[i],learnfp);
  7351.         fputs(" TELNET /TELNET",learnfp);
  7352.         fputs("\nIF FAIL STOP 1 Connection failed\n",learnfp);
  7353.     } else {
  7354.         fputs(s,learnfp);
  7355.         fputs("\n",learnfp);
  7356.     }
  7357.     }
  7358. }
  7359. #endif /* CKLEARN */
  7360.  
  7361.  
  7362. /*  D O C M D  --  Do a command  */
  7363.  
  7364. /*
  7365.  Returns:
  7366.    -2: user typed an illegal command
  7367.    -1: reparse needed
  7368.     0: parse was successful (even tho command may have failed).
  7369. */
  7370. #ifdef DEBUG
  7371. int cmdstats[256] = { -1, -1 };
  7372. #endif /* DEBUG */
  7373.  
  7374. int
  7375. docmd(cx) int cx; {
  7376.     extern int nolocal, cmkwflgs;
  7377.  
  7378.     debug(F101,"docmd entry, cx","",cx);
  7379.     activecmd = cx;
  7380.     doconx = ((activecmd == XXCON)  || (activecmd == XXTEL) ||
  7381.           (activecmd == XXRLOG) || (activecmd == XXPIPE) ||
  7382.               (activecmd == XXIKSD) || (activecmd == XXPTY));
  7383. /*
  7384.   Originally all commands were handled with a big switch() statement,
  7385.   but eventually this started blowing up compilers.  Now we have a series
  7386.   of separate if statements and small switches, with the commands that are
  7387.   most commonly executed in scipts and loops coming first, to speed up
  7388.   compute-bound scripts.
  7389. */
  7390.  
  7391. #ifdef DEBUG
  7392.     if (cmdstats[0] == -1) {        /* Count commands */
  7393.     int i;                /* for tuning... */
  7394.     for (i = 0; i < 256; i++)
  7395.       cmdstats[i] = 0;
  7396.     }
  7397. #endif /* DEBUG */
  7398.  
  7399.     switch (cx) {
  7400.       case -4:                /* EOF */
  7401. #ifdef OSK
  7402.     if (msgflg)  printf("\n");
  7403. #else
  7404.     if (msgflg)  printf("\r\n");
  7405. #endif /* OSK */
  7406.       doexit(GOOD_EXIT,xitsta);
  7407.       case -3:                /* Null command */
  7408.     return(0);
  7409.       case -9:                /* Like -2, but errmsg already done */
  7410.       case -1:                /* Reparse needed */
  7411.     return(cx);
  7412.       case -6:                /* Special */
  7413.       case -2:                /* Error, maybe */
  7414.  
  7415. #ifndef NOSPL
  7416. /*
  7417.   Maybe they typed a macro name.  Let's look it up and see.
  7418. */
  7419.     if (cx == -6)            /* If they typed CR */
  7420.       ckstrncat(cmdbuf,"\015",CMDBL); /*  add it back to command buffer. */
  7421.     if (ifcmd[cmdlvl] == 2)        /* Watch out for IF commands. */
  7422.       ifcmd[cmdlvl]--;
  7423.     repars = 1;            /* Force reparse */
  7424.     cmres();
  7425.     cx = XXDO;            /* Try DO command */
  7426. #else
  7427.     return(cx);
  7428. #endif /* NOSPL */
  7429.       default:
  7430.     if (cx < 0)
  7431.       return(cx);
  7432.     break;
  7433.     }
  7434. #ifdef DEBUG
  7435.     if (cx < 256)
  7436.       cmdstats[cx]++;
  7437. #endif /* DEBUG */
  7438.  
  7439.     if ((cmkwflgs & CM_PSH)
  7440. #ifndef NOPUSH
  7441.     && nopush
  7442. #endif /* NOPUSH */
  7443.     ) {
  7444.     printf("?Access to system disabled\n");
  7445.     return(-9);
  7446.     }
  7447.     if ((cmkwflgs & CM_LOC)
  7448. #ifndef NOLOCAL
  7449.     && nolocal
  7450. #endif /* NOLOCAL */
  7451.     ) {
  7452.     printf("?Connections disabled\n");
  7453.     return(-9);
  7454.     }
  7455.  
  7456. #ifndef NOSPL
  7457.     /* Used in FOR loops */
  7458.  
  7459.     if (cx == XX_INCR || cx == XXINC  || /* _INCREMENT, INCREMENT */
  7460.     cx == XX_DECR || cx == XXDEC)     /* _DECREMENT, DECREMENT */
  7461.       return(doincr(cx));
  7462.  
  7463.     /* Define (or change the definition of) a macro or variable */
  7464.  
  7465.     if (cx == XXUNDEF || cx == XXUNDFX) {
  7466. #ifdef IKSD
  7467.     if (inserver && !ENABLED(en_asg)) {
  7468.         printf("?Sorry, DEFINE/ASSIGN disabled\n");
  7469.         return(-9);
  7470.     }
  7471. #endif /* IKSD */
  7472.     return(doundef(cx));        /* [_]UNDEFINE */
  7473.     }
  7474.     if (cx == XXDEF || cx == XXASS ||
  7475.     cx == XXDFX || cx == XXASX) {
  7476. #ifdef IKSD
  7477.     if (inserver && !ENABLED(en_asg)) {
  7478.         printf("?Sorry, DEFINE/ASSIGN disabled\n");
  7479.         return(-9);
  7480.     }
  7481. #endif /* IKSD */
  7482.     if (atmbuf[0] == '.' && !atmbuf[1]) /* "." entered as keyword */
  7483.       xxdot = 1;            /* i.e. with space after it... */
  7484.     return(dodef(cx));        /* DEFINE, ASSIGN, etc... */
  7485.     }
  7486.  
  7487.     /* IF, WHILE, and friends  */
  7488.  
  7489.     if (cx == XXIF || cx == XXIFX || cx == XXWHI || cx == XXASSER) {
  7490.     return(doif(cx));
  7491.     }
  7492.     if (cx == XXSWIT) {            /* SWITCH */
  7493.     return(doswitch());
  7494.     }
  7495.  
  7496.     /* GOTO, FORWARD, and _FORWARD (used internally by FOR, WHILE, etc) */
  7497.  
  7498.     if (cx == XXGOTO || cx == XXFWD || cx == XXXFWD) { /* GOTO or FORWARD */
  7499.     /* Note, here we don't set SUCCESS/FAILURE flag */
  7500. #ifdef COMMENT
  7501.     if ((y = cmfld("label","",&s,xxstring)) < 0) {
  7502.         if (y == -3) {
  7503.         if (cx != XXXFWD) {
  7504.             printf("?Label name required\n");
  7505.             return(-9);
  7506.         }
  7507.         } else
  7508.           return(y);
  7509.     }
  7510.     ckstrncpy(lblbuf,s,LBLSIZ);
  7511.     if ((x = cmcfm()) < 0) return(x);
  7512. #else
  7513.     if ((y = cmtxt("label","",&s,xxstring)) < 0) {
  7514.         if (y == -3) {
  7515.         if (cx != XXXFWD) {
  7516.             printf("?GOTO: Label name required: \"%s\" \"%s\"\n",
  7517.                atmbuf,
  7518.                cmdbuf);
  7519.             return(-9);
  7520.         }
  7521.         } else
  7522.           return(y);
  7523.     }
  7524.     ckstrncpy(lblbuf,s,LBLSIZ);
  7525. #endif /* COMMENT */
  7526.     s = lblbuf;
  7527.     return(dogoto(s,cx));
  7528.     }
  7529.     if (cx == XXDO || cx == XXMACRO) {    /* DO (a macro) */
  7530.     char mnamebuf[16];        /* (buffer for controlled temp name) */
  7531.     struct FDB kw, fl;
  7532.     int mx;                /* Macro index (on stack!) */
  7533.  
  7534.     if (cx == XXDO) {
  7535.         if (nmac == 0) {
  7536.         printf("\n?No macros defined\n");
  7537.         return(-9);
  7538.         }
  7539.         for (y = 0; y < nmac; y++) { /* copy the macro table into a */
  7540.         mackey[y].kwd = mactab[y].kwd; /* regular keyword table */
  7541.         mackey[y].kwval = y;    /* with value = pointer to macro tbl */
  7542.         mackey[y].flgs = mactab[y].flgs;
  7543.         }
  7544.         cmfdbi(&kw,            /* First FDB - macro name */
  7545.            _CMKEY,        /* fcode */
  7546.            "Macro",        /* hlpmsg */
  7547.            "",            /* default */
  7548.            "",            /* addtl string data */
  7549.            nmac,        /* addtl numeric data 1: tbl size */
  7550.            0,            /* addtl numeric data 2: 0 = cmkey */
  7551.            xxstring,        /* Processing function */
  7552.            mackey,        /* Keyword table */
  7553.            &fl            /* Pointer to next FDB */
  7554.            );
  7555.         cmfdbi(&fl,            /* 2nd FDB - for "{" */
  7556.            _CMFLD,        /* fcode */
  7557.            "",            /* hlpmsg */
  7558.            "",
  7559.            "",            /* addtl string data */
  7560.            0,            /* addtl numeric data 1 */
  7561.            0,            /* addtl numeric data 2 */
  7562.            xxstring,
  7563.            NULL,
  7564.            NULL
  7565.            );
  7566.         x = cmfdb(&kw);        /* Parse something */
  7567.         if (x < 0) {        /* Error */
  7568.         if (x == -3) {
  7569.             printf("?Macro name required\n");
  7570.             return(-9);
  7571.         } else
  7572.           return(x);
  7573.         }
  7574.         if (cmresult.fcode == _CMKEY) {
  7575.         extern int mtchanged;
  7576.         char * macroname = NULL;
  7577.  
  7578.         /* In case args include an \fexec() that changes the macro table */
  7579.  
  7580.         mx = x;            /* Save macro index on stack */
  7581.         mtchanged = 0;        /* Mark state of macro table */
  7582.         makestr(¯oname,mactab[mx].kwd); /* Save name */
  7583.  
  7584.         if ((y = cmtxt("optional arguments","",&s,xxstring)) < 0)
  7585.           return(y);        /* Get macro args */
  7586.  
  7587.         if (mtchanged) {    /* Macro table changed? */
  7588.             mx = mlook(mactab,macroname,nmac); /* Look up name again */
  7589.         }
  7590.         if (macroname)
  7591.           free(macroname);
  7592.  
  7593.         return(dodo(mx,s,cmdstk[cmdlvl].ccflgs) < 1 ?
  7594.                (success = 0) : 1);
  7595.         }
  7596.         ckstrncpy(line,cmresult.sresult,LINBUFSIZ);    /* _CMFLD */
  7597.         if (atmbuf[0] == '{') {
  7598.         if ((y = cmcfm()) < 0)
  7599.           return(y);
  7600.         }
  7601.     } else {            /* XXMACRO */
  7602.         int k = 0;
  7603.         line[k++] = '{';
  7604.         line[k++] = SP;
  7605.         if ((y = cmtxt("braced list of commands","",&s,xxstring)) < 0)
  7606.           return(y);
  7607.         ckstrncpy(line+k,s,LINBUFSIZ-k);
  7608.     }
  7609.     x = strlen(line);
  7610.     if ((line[0] == '{' && line[x-1] != '}') || line[0] == '}')
  7611.       return(-2);
  7612.     if (line[0] != '{' && line[x-1] != '}') {
  7613.         /* Unknown command.  If ON_UNKNOWN_COMMAND macro is defined, */
  7614.         /* parse args and then execute it, but only if it is not */
  7615.         /* already active. */
  7616.         int k = -1;
  7617.         if (!unkmacro) {
  7618.         k = mxlook(mactab,"on_unknown_command",nmac);
  7619.         }
  7620.         if (k > -1) {
  7621.         ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ);
  7622.         z = maclvl;        /* Save the current maclvl */
  7623.         if ((y = cmtxt("text","",&s,xxstring)) < 0)
  7624.           return(y);
  7625.         ckstrncat(tmpbuf," ",TMPBUFSIZ);
  7626.         ckstrncat(tmpbuf,s,TMPBUFSIZ);
  7627.         unkmacro = 1;
  7628.         debug(F110,"ON_UNKNOWN_COMMAND",s,0);
  7629.         dodo(k,tmpbuf,cmdstk[cmdlvl].ccflgs); /* Run the macro */
  7630.         while (maclvl > z) {
  7631.             sstate = (CHAR) parser(1);
  7632.             if (sstate) proto();
  7633.         }
  7634.         debug(F101,"UNKMAC loop exit maclvl","",maclvl);
  7635.         unkmacro = 0;
  7636.         return(success);
  7637.         }
  7638.             if (x > 0)
  7639.           printf("?Not a command or macro name: \"%s\"\n",line);
  7640.             else
  7641.           printf("?Not a command or macro name.\n");
  7642.         return(-9);
  7643.     }
  7644.     s = brstrip(line);
  7645.     sprintf(mnamebuf," ..tmp:%03d",cmdlvl);    /* safe (16) */
  7646.     x = addmac(mnamebuf,s);
  7647.     return(dodo(x,NULL,cmdstk[cmdlvl].ccflgs) < 1 ? (success = 0) : 1);
  7648.     }
  7649.  
  7650.     if (cx == XXLBL) {            /* LABEL */
  7651.     if ((x = cmfld("label","",&s,xxstring)) < 0) {
  7652.         if (x == -3) {
  7653.         printf("?LABEL: Label name required: \"%s\"\n", cmdbuf);
  7654.         return(-9);
  7655.         } else return(x);
  7656.     }
  7657.     debug(F111,"LABEL",s,x);
  7658.     if ((x = cmcfm()) < 0) return(x);
  7659.     return(0);
  7660.     }
  7661.  
  7662.     if (cx == XXEVAL || cx == XX_EVAL) /* _EVALUATE,  EVALUATE  */
  7663.       return(doeval(cx));
  7664.  
  7665. #ifndef NOSEXP
  7666.     if (cx == XXSEXP) {            /* Lisp-like S-Expression */
  7667.     struct stringarray * q;
  7668.     char /* *p, *r, */ *tmp, *m;
  7669.     int i, k, n, quote = 0, contd = 0, size = 0, len = 0;
  7670.     extern int sexprc, sexppv;
  7671.  
  7672.     tmp = tmpbuf;            /* Buffer to collect SEXP */
  7673.     tmpbuf[0] = NUL;        /* Clear it */
  7674.     size = TMPBUFSIZ;        /* Capacity of buffer */
  7675.     sexprc = -1;            /* Assume bad input */
  7676.     n = 0;                /* Paren balance counter */
  7677.  
  7678.     while (1) {            /* Allow SEXP on multiple lines */
  7679.         m = contd ?
  7680.           "Continuation of S-Expression" :
  7681.         "S-Expression (\"help sexp\" for details)";
  7682.         x = cmtxt(m,"",&s,xxstring);
  7683.         if (x < 0)
  7684.           return(x);
  7685.         if (!*s)            /* Needed for (=) and (:) */
  7686.           s = atmbuf;
  7687.         k = ckmakmsg(tmp, size, contd ? " " : "(", s, NULL, NULL);
  7688.         if (k < 1) {
  7689.         printf("?SEXP too long - %d max\n",TMPBUFSIZ);
  7690.         return(-9);
  7691.         }
  7692.         debug(F111,contd ? "sexp contd" : "sexp",s,k);
  7693.  
  7694.         for (i = len; i < len+k; i++) { /* Check balance  */
  7695.         if (!quote && tmpbuf[i] == CMDQ) {
  7696.             quote = 1;
  7697.             continue;
  7698.         }
  7699.         if (quote) {
  7700.             quote = 0;
  7701.             continue;
  7702.         }
  7703.         if (tmpbuf[i] == '(')
  7704.           n++;
  7705.         else if (tmpbuf[i] == ')')
  7706.           n--;
  7707.         }
  7708.         if (n == 0) {        /* Break when balanced */
  7709.         break;
  7710.         }
  7711.         if (n < 0) {        /* Too many right parens */
  7712.         printf("?Unbalanced S-Expression: \"%s\"\n",tmpbuf);
  7713.         return(-9);
  7714.         }
  7715.         contd++;            /* Need more right parens */
  7716.         cmini(ckxech);        /* so keep parsing */
  7717.         tmp += k;            /* adjust buffer pointer */
  7718.         size -= k;            /* and capacity */
  7719.         len += k;            /* and length so far */
  7720.     }
  7721.     s = tmpbuf;
  7722.     makestr(&lastsexp,s);
  7723.     q = cksplit(1,SEXPMAX,s,NULL,NULL,8,0,0); /* Precheck for > 1 SEXP */
  7724.     debug(F101,"sexp split","",q->a_size);
  7725.  
  7726.     if (q->a_size == 1) {        /* We should get exactly one back */
  7727.         char * result, * dosexp();
  7728.         sexprc = 0;            /* Reset out-of-band return code */
  7729.         result = dosexp(s);        /* Get result */
  7730.         debug(F111,"sexp result",result,sexprc);
  7731.         if (sexprc == 0) {        /* Success */
  7732.         /* Echo the result if desired */
  7733.         if ((!xcmdsrc && sexpecho != SET_OFF) || sexpecho == SET_ON)
  7734.           printf(" %s\n",result ? result : "");
  7735.         makestr(&sexpval,result);
  7736.         success = sexppv > -1 ? sexppv : 1;
  7737.         return(success);
  7738.         }
  7739.     }
  7740.     if (sexprc < 0)
  7741.       printf("?Invalid S-Expression: \"%s\"\n",lastsexp);
  7742.     return(-9);
  7743.     }
  7744. #endif /* NOSEXP */
  7745.  
  7746. #endif /* NOSPL */
  7747.  
  7748.     if (cx == XXECH || cx == XXXECH || cx == XXVOID
  7749. #ifndef NOSPL
  7750.     || cx == XXAPC
  7751. #endif /* NOSPL */
  7752.     ) {                /* ECHO or APC */
  7753.     if ((x = cmtxt((cx == XXECH || cx == XXXECH) ?
  7754.                "Text to be echoed" :
  7755.                ((cx == XXVOID) ? "Text" :
  7756.             "Application Program Command text"),
  7757.                "",
  7758.                &s,
  7759.                xxstring
  7760.                )
  7761.          ) < 0)
  7762.       return(x);
  7763.     if (!s) s = "";
  7764. #ifdef COMMENT
  7765. /* This is to preserver the pre-8.0 behavior but it's too confusing */
  7766.     x = strlen(s);
  7767.     x = (x > 1) ? ((s[0] == '"' && s[x-1] == '"') ? 1 : 0) : 0;
  7768. #endif /* COMMENT */
  7769.     s = brstrip(s);            /* Strip braces and doublequotes */
  7770.     if (cx == XXECH) {        /* ECHO */
  7771. #ifndef NOSPL
  7772.         if (!fndiags || fnsuccess) {
  7773. #endif /* NOSPL */
  7774. #ifdef COMMENT
  7775.         /* The "if (x)" business preserves previous behavior */
  7776.         /* by putting back the doublequotes if they were included. */
  7777.         if (x)
  7778.           printf("\"%s\"\n",s);
  7779.         else
  7780. #endif /* COMMENT */
  7781.           printf("%s\n",s);
  7782. #ifndef NOSPL
  7783.         }
  7784. #endif /* NOSPL */
  7785.     } else if (cx == XXXECH) {    /* XECHO */
  7786.         if (x)
  7787.           printf("\"%s\"",s);
  7788.         else
  7789.           printf("%s",s);
  7790. #ifdef UNIX
  7791.         fflush(stdout);
  7792. #endif /* UNIX */
  7793.     } else if (cx == XXAPC) {    /* APC */
  7794. #ifdef CK_APC
  7795.         if (apcactive == APC_LOCAL ||
  7796.         (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
  7797.           return(success = 0);
  7798. #endif /* CK_APC */
  7799.         if (!local) {
  7800.         printf("%c_%s%c\\",ESC,s,ESC);
  7801. #ifdef UNIX
  7802.         fflush(stdout);
  7803. #endif /* UNIX */
  7804.  
  7805.         } else {            /* Local mode - have connection */
  7806. #ifndef NOSPL
  7807.         if (ckmakxmsg(tmpbuf,    /* Form APC string in buffer */
  7808.                   TMPBUFSIZ,
  7809.                   ckctoa((char)ESC),
  7810.                   ckctoa('_'),
  7811.                   s,
  7812.                   ckctoa((char)ESC),
  7813.                   ckctoa('\\'),
  7814.                   NULL,NULL,NULL,NULL,NULL,NULL,NULL
  7815.                   ) > 0)
  7816.           return(success = dooutput(tmpbuf, XXOUT));
  7817.         printf("?Too long\n");
  7818.         return(-9);
  7819. #else
  7820.         printf("%c_%s%c\\",ESC,s,ESC);
  7821. #endif /* NOSPL */
  7822.         }
  7823.     }
  7824.     return(success = 1);
  7825.     }
  7826.  
  7827. #ifndef NOSPL
  7828. /* Copy macro args from/to two levels up, used internally by _floop et al. */
  7829.     if (cx == XXGTA || cx == XXPTA) {    /* _GETARGS, _PUTARGS */
  7830.     int x;
  7831.     debug(F101,"docmd XXGTA","",XXGTA);
  7832.     debug(F101,"docmd cx","",cx);
  7833.     debug(F101,"docmd XXGTA maclvl","",maclvl);
  7834.     x = dogta(cx);
  7835.     debug(F101,"docmd dogta returns","",x);
  7836.     debug(F101,"docmd dogta maclvl","",maclvl);
  7837.     return(x);
  7838.     }
  7839. #endif /* NOSPL */
  7840.  
  7841. #ifndef NOSPL
  7842. #ifdef CKCHANNELIO
  7843.     if (cx == XXFILE)
  7844.       return(dofile(cx));
  7845.     else if (cx == XXF_RE || cx == XXF_WR || cx == XXF_OP ||
  7846.          cx == XXF_CL || cx == XXF_SE || cx == XXF_RW ||
  7847.          cx == XXF_FL || cx == XXF_LI || cx == XXF_ST || cx == XXF_CO)
  7848.       return(dofile(cx));
  7849. #endif /* CKCHANNELIO */
  7850.  
  7851. /* ASK, ASKQ, READ */
  7852.     if (cx == XXASK  || cx == XXASKQ || cx == XXREA ||
  7853.     cx == XXRDBL || cx == XXGETC || cx == XXGETK) {
  7854.     return(doask(cx));
  7855.     }
  7856. #endif /* NOSPL */
  7857.  
  7858. #ifndef NOFRILLS
  7859.     if (cx == XXBUG) {            /* BUG */
  7860.     if ((x = cmcfm()) < 0) return(x);
  7861.     return(dobug());
  7862.     }
  7863. #endif /* NOFRILLS */
  7864.  
  7865. #ifndef NOXFER
  7866.     if (cx == XXBYE) {            /* BYE */
  7867.     extern int ftp_cmdlin;
  7868.     if ((x = cmcfm()) < 0) return(x);
  7869.  
  7870. #ifdef NEWFTP
  7871.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) {
  7872.         extern int stayflg, ftp_fai;
  7873.         success = ftpbye();
  7874.         if (ftp_cmdlin && !stayflg && !local)
  7875.           doexit(ftp_fai ? BAD_EXIT : GOOD_EXIT,-1);
  7876.         else
  7877.           return(success);
  7878.     }
  7879. #endif /* NEWFTP */
  7880.  
  7881.     if (!local) {
  7882.         printf("?No connection - use EXIT to quit.\n");
  7883.         return(-9);
  7884.     }
  7885.  
  7886. #ifdef CK_XYZ
  7887.     if (protocol != PROTO_K) {
  7888.         printf("?Sorry, BYE only works with Kermit protocol\n");
  7889.         return(-9);
  7890.     }
  7891. #endif /* CK_XYZ */
  7892.  
  7893. #ifdef IKS_OPTION
  7894.         if (
  7895. #ifdef CK_XYZ
  7896.             protocol == PROTO_K &&
  7897. #endif /* CK_XYZ */
  7898.             !iks_wait(KERMIT_REQ_START,1)) {
  7899.         printf(
  7900.          "?A Kermit Server is not available to process this command\n");
  7901.         return(-9);            /* Correct the return code */
  7902.         }
  7903. #endif /* IKS_OPTION */
  7904.  
  7905.     bye_active = 1;
  7906.     sstate = setgen('L',"","","");
  7907.     if (local) ttflui();        /* If local, flush tty input buffer */
  7908.     return(0);
  7909.     }
  7910. #endif /* NOXFER */
  7911.  
  7912.     if (cx == XXBEEP) {            /* BEEP */
  7913.         int x;
  7914. #ifdef OS2
  7915.     int y;
  7916.         if ((y = cmkey(beeptab, nbeeptab, "which kind of beep", "information",
  7917.                xxstring)) < 0 )
  7918.       return (y);
  7919.         if ((x = cmcfm()) < 0) return(x);
  7920.         bleep((short)y);        /* y is one of the BP_ values */
  7921. #else  /* OS2 */
  7922.         if ((x = cmcfm()) < 0) return(x);
  7923. #ifndef NOSPL
  7924.         bleep(BP_NOTE);
  7925. #else
  7926.     putchar('\07');
  7927. #endif /* NOSPL */
  7928. #endif /* OS2 */
  7929.         return(0);
  7930.     }
  7931.  
  7932. #ifndef NOFRILLS
  7933.     if (cx == XXCLE)            /* CLEAR */
  7934.       return(success = doclear());
  7935. #endif /* NOFRILLS */
  7936.  
  7937.     if (cx == XXCOM) {            /* COMMENT */
  7938.     if ((x = cmtxt("Text of comment line","",&s,NULL)) < 0)
  7939.       return(x);
  7940.     /* Don't change SUCCESS flag for this one */
  7941.     return(0);
  7942.     }
  7943.  
  7944. #ifndef NOLOCAL
  7945.     if (cx == XXCON || cx == XXCQ)    /* CONNECT or CONNECT /QUIETLY */
  7946.       return(doxconn(cx));
  7947. #endif /* NOLOCAL */
  7948.  
  7949. #ifndef NOFRILLS
  7950. #ifdef ZCOPY
  7951.     if (cx == XXCPY) {            /* COPY a file */
  7952. #ifdef IKSD
  7953.     if (inserver && !ENABLED(en_cpy)) {
  7954.         printf("?Sorry, COPY is disabled\n");
  7955.         return(-9);
  7956.     }
  7957. #endif /* IKSD */
  7958. #ifdef CK_APC
  7959.     if (apcactive == APC_LOCAL ||
  7960.         (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
  7961.         )
  7962.       return(success = 0);
  7963. #endif /* CK_APC */
  7964.     return(docopy());
  7965.     }
  7966. #endif /* ZCOPY */
  7967. #endif /* NOFRILLS */
  7968.  
  7969.     if (cx == XXCWD || cx == XXBACK || cx == XXCDUP) { /* CD[UP] or BACK */
  7970. #ifdef IKSD
  7971.     if (inserver && !ENABLED(en_cwd)) {
  7972.         printf("?Sorry, changing directories is disabled\n");
  7973.         return(-9);
  7974.     }
  7975. #endif /* IKSD */
  7976.     return(success = docd(cx));
  7977.     }
  7978.  
  7979.     if (cx == XXCHK)            /* CHECK */
  7980.       return(success = dochk());
  7981.  
  7982.     if (cx == XXCLO) {            /* CLOSE */
  7983.     x = cmkey(clstab,ncls,"\"CONNECTION\", or log or file to close",
  7984.           "connection",xxstring);
  7985.     if (x == -3) {
  7986.         printf("?You must say which file or log\n");
  7987.         return(-9);
  7988.     }
  7989.     if (x < 0) return(x);
  7990.     if ((y = cmcfm()) < 0) return(y);
  7991. #ifndef NOLOCAL
  7992.     if (x == 9999) {        /* CLOSE CONNECTION */
  7993.         x = clsconnx(0);
  7994.         switch (x) {
  7995.           case 0:
  7996.         if (msgflg) printf("?Connection was not open\n");
  7997.           case -1:
  7998.         return(0);
  7999.           case 1:
  8000.         whyclosed = WC_CLOS;
  8001.         return(1);
  8002.         }
  8003.         return(0);
  8004.     }
  8005. #endif /* NOLOCAL */
  8006.     y = doclslog(x);
  8007.     success = (y == 1);
  8008.     return(success);
  8009.     }
  8010.  
  8011. #ifndef NOSPL
  8012.     if (cx == XXDCL || cx == XXUNDCL) {    /* DECLARE an array */
  8013.     return(dodcl(cx));
  8014.     }
  8015. #endif /* NOSPL */
  8016.  
  8017. #ifndef NODIAL
  8018.     if (cx == XXRED  || cx == XXDIAL || cx == XXPDIA ||
  8019.     cx == XXANSW || cx == XXLOOK) { /* DIAL, REDIAL etc */
  8020. #ifdef VMS
  8021.     extern int batch;
  8022. #else
  8023. #ifdef UNIXOROSK
  8024.     extern int backgrd;
  8025. #endif /* UNIXOROSK */
  8026. #endif /* VMS */
  8027.     x = dodial(cx);
  8028.     debug(F101,"dodial returns","",x);
  8029.     if ((cx == XXDIAL || cx == XXRED || cx == XXANSW) &&
  8030.         (x > 0) &&            /* If DIAL or REDIAL succeeded */
  8031.         (dialsta != DIA_PART) &&    /* and it wasn't partial */
  8032.         (dialcon > 0)) {
  8033.         if ((dialcon == 1 ||    /* And DIAL CONNECT is ON, */
  8034.         ((dialcon == 2) &&    /* or DIAL CONNECT is AUTO */
  8035.          !xcmdsrc        /* and we're at top level... */
  8036. #ifdef VMS
  8037.          && !batch        /* Not if running from batch */
  8038. #else
  8039. #ifdef UNIXOROSK
  8040.          && !backgrd        /* Not if running in background */
  8041. #endif /* UNIXOROSK */
  8042. #endif /* VMS */
  8043.          ))) /* Or AUTO */
  8044.           x = doconect(dialcq,    /* Then also CONNECT */
  8045.                            cmdlvl == 0 ? 1 : 0
  8046.                );
  8047. #ifdef CKLOGDIAL
  8048.         if (ttchk() < 0)
  8049.           dologend();
  8050. #endif /* CKLOGDIAL */
  8051.     }
  8052.     return(success = x);
  8053.     }
  8054. #endif /* NODIAL */
  8055.  
  8056. #ifndef NOPUSH
  8057. #ifdef CK_REXX
  8058.     if (cx == XXREXX) {            /* REXX */
  8059.         extern int nopush;
  8060.         if ( nopush )
  8061.           return(success=0);
  8062.         return(dorexx());
  8063.     }
  8064. #endif /* CK_REXX */
  8065. #endif /* NOPUSH */
  8066.  
  8067. #ifndef NOFRILLS
  8068.     if (cx == XXDEL) {            /* DELETE */
  8069. #ifdef IKSD
  8070.     if (inserver && (!ENABLED(en_del)
  8071. #ifdef CK_LOGIN
  8072.              || isguest
  8073. #endif /* CK_LOGIN */
  8074.              )) {
  8075.         printf("?Sorry, DELETE is disabled\n");
  8076.         return(-9);
  8077.     }
  8078. #endif /* IKSD */
  8079. #ifdef CK_APC
  8080.     if ((apcactive == APC_LOCAL) ||
  8081.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  8082.       return(success = 0);
  8083. #endif /* CK_APC */
  8084.     return(dodel());
  8085.     }
  8086. #endif /* NOFRILLS */
  8087.  
  8088.     if (cx == XXDIR || cx == XXLS) {    /* DIRECTORY or LS */
  8089. #ifdef IKSD
  8090.     if (inserver && !ENABLED(en_dir)) {
  8091.         printf("?Sorry, DIRECTORY is disabled\n");
  8092.         return(-9);
  8093.     }
  8094. #endif /* IKSD */
  8095.     return(dodir(cx));
  8096.     }
  8097.  
  8098. #ifndef NOSPL
  8099.     if (cx == XXELS)            /* ELSE */
  8100.       return(doelse());
  8101. #endif /* NOSPL */
  8102.  
  8103. #ifndef NOSERVER
  8104. #ifndef NOFRILLS
  8105.     if (cx == XXENA || cx == XXDIS) {    /* ENABLE, DISABLE */
  8106.     s = (cx == XXENA) ?
  8107.       "Server function to enable" :
  8108.         "Server function to disable";
  8109.  
  8110.     if ((x = cmkey(enatab,nena,s,"",xxstring)) < 0) {
  8111.         if (x == -3) {
  8112.         printf("?Name of server function required\n");
  8113.         return(-9);
  8114.         } else return(x);
  8115.     }
  8116.     if ((y = cmkey(kmstab,3,"mode","both",xxstring)) < 0) {
  8117.         if (y == -3) {
  8118.         printf("?Please specify remote, local, or both\n");
  8119.         return(-9);
  8120.         } else return(y);
  8121.     }
  8122.     if (cx == XXDIS)        /* Disabling, not enabling */
  8123.       y = 3 - y;
  8124.     if ((z = cmcfm()) < 0) return(z);
  8125. #ifdef CK_APC
  8126.     if ((apcactive == APC_LOCAL) ||
  8127.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  8128.       return(success = 0);
  8129. #endif /* CK_APC */
  8130. #ifdef IKSD
  8131.         /* This may seem like it duplicates the work in doenable()  */
  8132.         /* but this code returns failure whereas doenable() returns */
  8133.         /* success.                                                 */
  8134.         if (inserver &&
  8135. #ifdef IKSDCONF
  8136.             iksdcf &&
  8137. #endif /* IKSDCONF */
  8138.             (x == EN_HOS || x == EN_PRI || x == EN_MAI || x == EN_WHO ||
  8139.               isguest))
  8140.             return(success = 0);
  8141. #endif /* IKSD */
  8142.     return(doenable(y,x));
  8143.     }
  8144. #endif /* NOFRILLS */
  8145. #endif /* NOSERVER */
  8146.  
  8147. #ifndef NOSPL
  8148.     if (cx == XXRET) {            /* RETURN */
  8149.     if ((x = cmtxt("Optional return value","",&s,NULL)) < 0)
  8150.       return(x);
  8151.     s = brstrip(s);            /* Strip braces */
  8152.     if (cmdlvl == 0)        /* At top level, nothing happens... */
  8153.       return(success = 1);
  8154.     switch (cmdstk[cmdlvl].src) {    /* Action depends on command source */
  8155.       case CMD_TF:            /* Command file */
  8156.         popclvl();            /* Pop command level */
  8157.         return(success = 1);    /* always succeeds */
  8158.       case CMD_MD:            /* Macro */
  8159.       case CMD_KB:            /* Prompt */
  8160.         return(doreturn(s));    /* Trailing text is return value. */
  8161.       default:            /* Shouldn't happen */
  8162.         return(-2);
  8163.     }
  8164.     }
  8165. #endif /* NOSPL */
  8166.  
  8167. #ifndef NOSPL
  8168.     if (cx == XXOPE)            /* OPEN */
  8169.       return(doopen());
  8170. #endif /* NOSPL */
  8171.  
  8172. #ifndef NOSPL
  8173.     if (cx == XXOUT || cx == XXLNOUT) {    /* OUTPUT or LINEOUT */
  8174.     if ((x = cmtxt("Text to be output","",&s,NULL)) < 0)
  8175.       return(x);
  8176. #ifdef CK_APC
  8177.     if ((apcactive == APC_LOCAL) ||
  8178.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  8179.       return(success = 0);
  8180. #endif /* CK_APC */
  8181.     debug(F110,"OUTPUT 1",s,0);
  8182.     s = brstrip(s);            /* Strip enclosing braces, */
  8183.     debug(F110,"OUTPUT 2",s,0);
  8184. /*
  8185.   I don't think I could ever fully explain this in a million years...
  8186.   We have read the user's string without calling the variable-expander
  8187.   function.  Now, before we call it, we have to double backslashes that
  8188.   appear before \N, \B, \L, and \ itself, so the expander function will
  8189.   reduce them back to single backslashes, so when we call dooutput()...
  8190.   But it's more complicated than that.
  8191. */
  8192.     if (cmdgquo()) {        /* Only if COMMAND QUOTING ON ... */
  8193.         for (x = 0, y = 0; s[x]; x++, y++) {
  8194.         if (s[x] == CMDQ) {
  8195.             char c = s[x+1];
  8196.             if (c == 'n' || c == 'N' ||
  8197.             c == 'b' || c == 'B' ||
  8198.             c == 'l' || c == 'L' ||
  8199.             c == CMDQ)
  8200.               line[y++] = CMDQ;
  8201.         }
  8202.         line[y] = s[x];
  8203.         }
  8204.         line[y++] = '\0';        /* Now expand variables, etc. */
  8205.         debug(F110,"OUTPUT 3",line,0);
  8206.         s = line+y+1;
  8207.         x = LINBUFSIZ - (int) strlen(line) - 1;
  8208.         debug(F101,"OUTPUT size","",x);
  8209.         if (zzstring(line,&s,&x) < 0)
  8210.           return(success = 0);
  8211.         s = line+y+1;
  8212.         debug(F110,"OUTPUT 4",s,0);
  8213.     }
  8214.     success = dooutput(s,cx);
  8215.     return(success);
  8216.     }
  8217. #endif /* NOSPL */
  8218.  
  8219. #ifdef ANYX25
  8220. #ifndef IBMX25
  8221.     if (cx == XXPAD) {            /* PAD commands */
  8222.     x = cmkey(padtab,npadc,"PAD command","",xxstring);
  8223.     if (x == -3) {
  8224.         printf("?You must specify a PAD command to execute\n");
  8225.         return(-9);
  8226.     }
  8227.     if (x < 0) return(x);
  8228.  
  8229.     switch (x) {
  8230.       case XYPADL:
  8231.         if (x25stat() < 0)
  8232.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  8233.         else {
  8234.         x25clear();
  8235.         initpad();
  8236.         }
  8237.         break;
  8238.       case XYPADS:
  8239.         if (x25stat() < 0)
  8240.           printf("Not connected\r\n");
  8241.         else {
  8242.         extern int linkid, lcn;
  8243.         conol("Connected thru ");
  8244.         conol(ttname);
  8245.         printf(", Link id %d, Logical channel number %d\r\n",
  8246.                linkid,lcn);
  8247.         }
  8248.         break;
  8249.       case XYPADR:
  8250.         if (x25stat() < 0)
  8251.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  8252.         else
  8253.           x25reset(0,0);
  8254.         break;
  8255.       case XYPADI:
  8256.         if (x25stat() < 0)
  8257.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  8258.         else
  8259.           x25intr(0);
  8260.     }
  8261.     return(0);
  8262.     }
  8263. #endif /* IBMX25 */
  8264. #endif /* ANYX25 */
  8265.  
  8266. #ifndef NOSPL
  8267.     if (cx == XXPAU || cx == XXWAI || cx == XXMSL) /* PAUSE, WAIT, etc */
  8268.       return(dopaus(cx));
  8269. #endif /* NOSPL */
  8270.  
  8271. #ifndef NOFRILLS
  8272.     if (cx == XXPRI) {
  8273. #ifdef IKSD
  8274. #ifdef CK_LOGIN
  8275.     if (inserver && (isguest || !ENABLED(en_pri))) {
  8276.         printf("?Sorry, printing is disabled\n");
  8277.         return(-9);
  8278.     }
  8279. #endif /* CK_LOGIN */
  8280. #endif /* IKSD */
  8281.     if ((x = cmifi("File to print","",&s,&y,xxstring)) < 0) {
  8282.         if (x == -3) {
  8283.         printf("?A file specification is required\n");
  8284.         return(-9);
  8285.         } else return(x);
  8286.     }
  8287.     if (y != 0) {
  8288.         printf("?Wildcards not allowed\n");
  8289.         return(-9);
  8290.     }
  8291.     ckstrncpy(line,s,LINBUFSIZ);
  8292.     s = "";
  8293. #ifndef NT
  8294.     if ((x = cmtxt("Local print command options, or carriage return","",&s,
  8295.                xxstring)) < 0)
  8296.       return(x);
  8297. #endif /* NT */
  8298.     if ((x = cmcfm()) < 0)
  8299.       return(x);
  8300.     return(success = (zprint(s,line) == 0) ? 1 : 0);
  8301.     }
  8302. #endif /* NOFRILLS */
  8303.  
  8304. #ifdef TCPSOCKET
  8305. #ifndef NOPUSH
  8306.     if (cx == XXPNG)             /* PING an IP host */
  8307.       return(doping());
  8308. #endif /* NOPUSH */
  8309.  
  8310. #ifndef NOFTP
  8311.     if (cx == XXFTP)            /* FTP */
  8312. #ifdef SYSFTP
  8313. #ifndef NOPUSH
  8314.       return(doftp());            /* Just runs system's ftp program */
  8315. #else
  8316.       return(-2);
  8317. #endif /* NOPUSH */
  8318. #else
  8319.     return(doxftp());
  8320. #endif /* SYSFTP */
  8321. #endif /* NOFTP */
  8322. #endif /* TCPSOCKET */
  8323.  
  8324.     if (cx == XXPWD) {            /* PWD */
  8325. #ifdef OS2
  8326.     char *pwp;
  8327. #endif /* OS2 */
  8328.     if ((x = cmcfm()) < 0)
  8329.       return(x);
  8330. #ifndef MAC
  8331. #ifndef OS2
  8332. #ifdef UNIX
  8333.     printf("%s\n",zgtdir());
  8334. #else
  8335.     xsystem(PWDCMD);
  8336. #endif /* UNIX */
  8337.     return(success = 1);        /* Blind faith */
  8338. #else  /* OS2 */
  8339.     if (pwp = zgtdir()) {
  8340.         printf("%s\n",pwp);
  8341.         return(success = ((int)strlen(pwp) > 0));
  8342.     } else return(success = 0);
  8343. #endif /* OS2 */
  8344. #else  /* MAC */
  8345.     if (pwp = zgtdir()) {
  8346.         printf("%s\n",pwp);
  8347.         return(success = ((int)strlen(pwp) > 0));
  8348.     } else return(success = 0);
  8349. #endif /* MAC */
  8350.     }
  8351.  
  8352.     if (cx == XXQUI || cx == XXEXI) {    /* EXIT, QUIT */
  8353.     if ((y = cmnum("exit status code",ckitoa(xitsta),10,&x,xxstring)) < 0)
  8354.       return(y);
  8355.     if ((y = cmtxt("Optional EXIT message","",&s,xxstring)) < 0)
  8356.       return(y);
  8357.     s = brstrip(s);
  8358.     ckstrncpy(line,s,LINBUFSIZ);
  8359.  
  8360.     if (!hupok(0))            /* Check if connection still open */
  8361.       return(success = 0);
  8362.  
  8363.     if (line[0])            /* Print EXIT message if given */
  8364.       printf("%s\n",(char *)line);
  8365.  
  8366. #ifdef VMS
  8367.     doexit(GOOD_EXIT,x);
  8368. #else
  8369. #ifdef OSK
  8370. /* Returning any codes here makes the OS-9 shell print an error message. */
  8371.     doexit(GOOD_EXIT,-1);
  8372. #else
  8373. #ifdef datageneral
  8374.         doexit(GOOD_EXIT,x);
  8375. #else
  8376.     doexit(x,-1);
  8377. #endif /* datageneral */
  8378. #endif /* OSK */
  8379. #endif /* VMS */
  8380.     }
  8381.  
  8382. #ifndef NOXFER
  8383. #ifndef NOFRILLS
  8384.     if (cx == XXERR) {            /* ERROR */
  8385. #ifdef CK_XYZ
  8386.     if (protocol != PROTO_K) {
  8387.         printf("Sorry, E-PACKET only works with Kermit protocol\n");
  8388.         return(-9);
  8389.     }
  8390. #endif /* CK_XYZ */
  8391.     if ((x = cmcfm()) < 0) return(x);
  8392.     ttflui();
  8393.     epktflg = 1;
  8394.     sstate = 'a';
  8395.     return(0);
  8396.     }
  8397. #endif /* NOFRILLS */
  8398.  
  8399.     if (cx == XXFIN) {            /* FINISH */
  8400. #ifdef NEWFTP
  8401.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  8402.       return(ftpbye());
  8403. #endif /* NEWFTP */
  8404. #ifdef CK_XYZ
  8405.     if (protocol != PROTO_K) {
  8406.         printf("Sorry, FINISH only works with Kermit protocol\n");
  8407.         return(-9);
  8408.     }
  8409. #endif /* CK_XYZ */
  8410.     if ((x = cmcfm()) < 0) return(x);
  8411.  
  8412. #ifdef IKS_OPTION
  8413.         if (
  8414. #ifdef CK_XYZ
  8415.             protocol == PROTO_K &&
  8416. #endif /* CK_XYZ */
  8417.             !iks_wait(KERMIT_REQ_START,1)) {
  8418.         printf(
  8419.               "?A Kermit Server is not available to process this command\n");
  8420.         return(-9);            /* Correct the return code */
  8421.         }
  8422. #endif /* IKS_OPTION */
  8423.  
  8424.     sstate = setgen('F',"","","");
  8425.     if (local) ttflui();        /* If local, flush tty input buffer */
  8426.     return(0);
  8427.     }
  8428. #endif /* NOXFER */
  8429.  
  8430. #ifndef NOSPL
  8431.     if (cx == XXFOR)            /* FOR loop */
  8432.       return(dofor());
  8433. #endif /* NOSPL */
  8434.  
  8435. #ifndef NOXFER
  8436.     /* GET MGET REGET RETRIEVE etc */
  8437.     if (cx == XXGET || cx == XXMGET || cx == XXREGET || cx == XXRETR) {
  8438. #ifdef IKSD
  8439.     if (inserver && !ENABLED(en_sen)) {
  8440.         printf("?Sorry, reception of files is disabled\n");
  8441.         return(-9);
  8442.     }
  8443. #endif /* IKSD */
  8444.     return(doxget(cx));
  8445.     }
  8446. #endif /* NOXFER */
  8447.  
  8448. #ifndef NOSPL
  8449. #ifndef NOFRILLS
  8450.     if (cx == XXGOK) {            /* GETOK */
  8451.     return(success = doask(cx));
  8452.     }
  8453. #endif /* NOFRILLS */
  8454. #endif /* NOSPL */
  8455.  
  8456.     if (cx == XXHLP) {            /* HELP */
  8457. #ifdef NOHELP
  8458.     return(dohlp(XXHLP));
  8459. #else
  8460.     x = cmkey2(cmdtab,ncmd,"\nCommand or topic","help",toktab,xxstring,3);
  8461.     debug(F101,"HELP command x","",x);
  8462.     if (x == -5) {
  8463.         y = chktok(toktab);
  8464.         debug(F101,"HELP cmkey token","",y);
  8465.         /* ungword(); */
  8466.         switch (y) {
  8467. #ifndef NOPUSH
  8468.           case '!': x = XXSHE; break;
  8469. #endif /* NOPUSH */
  8470.           case '#': x = XXCOM; break;
  8471.           case ';': x = XXCOM; break;
  8472. #ifndef NOSPL
  8473.               case '.': x = XXDEF; break;
  8474.           case ':': x = XXLBL; break;
  8475. #ifndef NOSEXP
  8476.           case '(': x = XXSEXP; break;
  8477. #endif /* NOSEXP */
  8478. #endif /* NOSPL */
  8479.           case '&': x = XXECH; break;
  8480.           default:
  8481.         printf("\n?Invalid - %s\n",cmdbuf);
  8482.         x = -2;
  8483.         }
  8484.     }
  8485.     makestr(&hlptok,atmbuf);
  8486.     debug(F111,"HELP token",hlptok,x);
  8487.     return(dohlp(x));
  8488. #endif /* NOHELP */
  8489.     }
  8490.  
  8491. #ifndef NOHELP
  8492.     if (cx == XXINT)            /* INTRO */
  8493.       return(hmsga(introtxt));
  8494.     if (cx == XXNEW) {            /* NEWS */
  8495.     int x;
  8496.     extern char * k_info_dir;
  8497.     x = hmsga(newstxt);
  8498.     return(x);
  8499.     }
  8500.  
  8501. #ifdef OS2ONLY
  8502.     if (cx == XXUPD) {            /* View UPDATE file */
  8503.         extern char exedir[];
  8504.         char * pTopic;
  8505.         char updstr[2048];
  8506.         if ((x = cmtxt("topic name","",&pTopic,xxstring)) < 0)
  8507.             return x;
  8508. #ifdef COMMENT
  8509.     sprintf(updstr,
  8510.         "start view %s\\docs\\k2.inf+%s\\docs\\using_ck.inf+\
  8511. %s\\docs\\dialing.inf+%s\\docs\\modems.inf %s",
  8512.         exedir,exedir,exedir,exedir,pTopic
  8513.         );
  8514. #else
  8515.     if (ckmakxmsg(updstr,
  8516.              2048,
  8517.              "start view ",
  8518.              exedir,
  8519.              "\\docs\\k2.inf+",
  8520.              exedir,
  8521.              "\\docs\\using_ck.inf+",
  8522.              exedir,
  8523.              "\\docs\\dialing.inf+",
  8524.              exedir,
  8525.              "\\docs\\modems.inf ",
  8526.              pTopic,
  8527.              NULL,
  8528.              NULL
  8529.              ) > 0)
  8530. #endif /* COMMENT */
  8531.       system(updstr);
  8532.         return(success = 1);
  8533.     }
  8534. #endif /* OS2ONLY */
  8535. #endif /* NOHELP */
  8536.  
  8537. #ifndef NOLOCAL
  8538.     if (cx == XXHAN) {            /* HANGUP */
  8539.     if ((x = cmcfm()) < 0) return(x);
  8540. #ifdef NEWFTP
  8541.     if ((ftpget == 1) || ((ftpget == 2) && !local && ftpisopen()))
  8542.       return(success = ftpbye());
  8543. #endif /* NEWFTP */
  8544. #ifndef NODIAL
  8545.     if ((x = mdmhup()) < 1) {
  8546.         debug(F101,"HANGUP mdmup","",x);
  8547. #endif /* NODIAL */
  8548.         x = tthang();
  8549.         debug(F101,"HANGUP tthang","",x);
  8550.         x = (x > -1);
  8551. #ifndef NODIAL
  8552.     }
  8553.     dialsta = DIA_UNK;
  8554. #endif /* NODIAL */
  8555.     whyclosed = WC_CLOS;
  8556.     ttchk();            /* In case of CLOSE-ON-DISCONNECT */
  8557. #ifdef CKLOGDIAL
  8558.     dologend();
  8559. #endif /* CKLOGDIAL */
  8560. #ifdef OS2
  8561.     if (x)
  8562.       DialerSend(OPT_KERMIT_HANGUP, 0);
  8563. #endif /* OS2 */
  8564.     if (x) haveline = 0;
  8565.     return(success = x);
  8566.     }
  8567. #endif /* NOLOCAL */
  8568.  
  8569. #ifndef NOSPL
  8570.     /* INPUT, REINPUT, and MINPUT */
  8571.  
  8572.     if (cx == XXINP || cx == XXREI || cx == XXMINP) {
  8573.     long zz;
  8574.     extern int x_ifnum, ispattern;
  8575.     zz = -1L;
  8576.     x_ifnum = 1;            /* Turn off internal complaints */
  8577.     y = cmnum("Seconds to wait for input,\n or time of day hh:mm:ss",
  8578.           ckitoa(indef), 10, &x, xxstring
  8579.           );
  8580.     x_ifnum = 0;
  8581.     if (y < 0) {
  8582.         if (y == -2) {        /* Invalid number or expression */
  8583.         zz = tod2sec(atmbuf);    /* Convert to secs since midnight */
  8584.         if (zz < 0L) {
  8585.             printf("?Number, expression, or time of day required\n");
  8586.             return(-9);
  8587.         } else {
  8588.             char now[32];    /* Current time */
  8589.             char *p;
  8590.             long tnow;
  8591.             p = now;
  8592.             ztime(&p);
  8593.             tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
  8594.             if (zz < tnow)    /* User's time before now */
  8595.               zz += 86400L;    /* So make it tomorrow */
  8596.             zz -= tnow;        /* Seconds from now. */
  8597.         }
  8598.         } else
  8599.           return(y);
  8600.     }
  8601.     if (zz > -1L) {
  8602.         x = zz;
  8603.         if (zz != (long) x) {
  8604.         printf(
  8605. "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
  8606.                );
  8607.         return(-9);
  8608.         }
  8609.     }
  8610.  
  8611. #ifdef CK_MINPUT
  8612.     for (y = 0; y < MINPMAX; y++) {    /* Initialize strings */
  8613.         mp[y] = 0;            /* Assume it's not a pattern */
  8614.         if (ms[y]) {
  8615.         free(ms[y]);        /* Free old strings, if any */
  8616.         ms[y] = NULL;
  8617.         }
  8618.     }
  8619.     if (cx == XXMINP) {        /* MINPUT */
  8620.         int i, k, n = 0, rc = 0;
  8621.         struct stringarray * q;
  8622.         if ((y = cmtxt("List of targets","",&s,xxstring)) < 0)
  8623.           return(y);
  8624.         if ((q = cksplit(1,0,s," ",NULL,3,0,0))) {
  8625.         char ** ap = q->a_head;
  8626.  
  8627.         n = q->a_size;
  8628.         debug(F101,"minput cksplit size","",n);
  8629.  
  8630.         for (i = 1, k = 0; i <= n; i++) { /* Array is 1-based */
  8631.             if (!ap[i])                  /* Add non-empty elements */
  8632.               continue;
  8633.             if (!*(ap[i]))
  8634.               continue;
  8635.             makestr(&(ms[k++]),ap[i]);    /* Not empty - add it */
  8636.             debug(F111,"MINPUT",ms[k-1],k-1);
  8637.             if (k > MINPMAX)              /* Check for too many */
  8638.               break;
  8639.         }
  8640.         rc = (k > 0) ? 1 : 0;
  8641.         }
  8642.     } else {
  8643. #endif /* CK_MINPUT */
  8644.  
  8645.         /* INPUT or REINPUT */
  8646.  
  8647.         if ((y = cmtxt("Material to be input","",&s,xxstring)) < 0)
  8648.           return(y);
  8649.         mp[0] = ispattern ? 1 : 0;
  8650.         makestr(&(ms[0]),brstrip(s));
  8651.         ms[1] = NULL;
  8652.  
  8653. #ifdef CK_MINPUT
  8654.     }
  8655. #endif /* CK_MINPUT */
  8656.  
  8657.     if (cx == XXINP || cx == XXMINP) { /* Not REINPUT... */
  8658.         i_active = 1;
  8659.         success = doinput(x,ms,mp);    /* Go try to input the search string */
  8660.         i_active = 0;
  8661.     } else {            /* REINPUT */
  8662.         success = doreinp(x,s,ispattern);
  8663.     }
  8664.     if (intime[cmdlvl] && !success) { /* TIMEOUT-ACTION = QUIT? */
  8665.         popclvl();            /* If so, pop command level. */
  8666.         if (pflag && cmdlvl == 0) {
  8667.         if (cx == XXINP)  printf("?INPUT timed out\n");
  8668.         if (cx == XXMINP) printf("?MINPUT timed out\n");
  8669.         if (cx == XXREI)  printf("?REINPUT failed\n");
  8670.         }
  8671.     }
  8672.     return(success);        /* Return do(re)input's return code */
  8673.     }
  8674.  
  8675. #endif /* NOSPL */
  8676.  
  8677.     if (cx == XXLOG) {            /* LOG */
  8678.     x = cmkey(logtab,nlog,"What to log","",xxstring);
  8679.     if (x == -3) {
  8680.         printf("?Type of log required\n");
  8681.         return(-9);
  8682.     }
  8683.     if (x < 0) return(x);
  8684.     x = dolog(x);
  8685.     if (x < 0)
  8686.       return(x);
  8687.     else
  8688.       return(success = x);
  8689.     }
  8690.  
  8691.     if (cx == XXLOGIN) {        /* (REMOTE) LOGIN */
  8692. #ifdef NEWFTP
  8693.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  8694.       return(success = doftpusr());
  8695. #endif /* NEWFTP */
  8696. #ifdef IKSD
  8697.     if (inserver) {
  8698.         printf("?Already logged in\n");
  8699.         return(-9);
  8700.     } else
  8701. #endif /* IKSD */
  8702.     {
  8703. #ifdef NOXFER
  8704.         return(-2);
  8705. #else
  8706.         return(dormt(XZLGI));
  8707. #endif /* NOXFER */
  8708.     }
  8709.     }
  8710.     if (cx == XXLOGOUT) {        /* (REMOTE) LOGOUT */
  8711. #ifdef NEWFTP
  8712.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  8713.       return(success = doftpres());
  8714. #endif /* NEWFTP */
  8715.  
  8716. #ifdef IKSD
  8717.         if (inserver) {
  8718.         if ((x = cmcfm()) < 0)
  8719.           return(x);
  8720.         doexit(GOOD_EXIT,xitsta);
  8721.     } else
  8722. #endif /* IKSD */
  8723.     if (!local || (network && ttchk() < 0)) {
  8724.         printf("?No connection.\n");
  8725.         return(-9);
  8726.     } else {
  8727. #ifdef NOXFER
  8728.         return(-2);
  8729. #else
  8730.         return(dormt(XZLGO));
  8731. #endif /* NOXFER */
  8732.     }
  8733.     }
  8734.  
  8735. #ifndef NOSCRIPT
  8736.     if (cx == XXLOGI) {            /* UUCP-style script */
  8737.     if ((x = cmtxt("expect-send expect-send ...","",&s,xxstring)) < 0)
  8738.       return(x);
  8739. #ifdef CK_APC
  8740.     if ((apcactive == APC_LOCAL) ||
  8741.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  8742.       return(success = 0);
  8743. #endif /* CK_APC */
  8744. #ifdef VMS
  8745.     conres();            /* For Ctrl-C to work... */
  8746. #endif /* VMS */
  8747.     return(success = dologin(s));    /* Return 1=completed, 0=failed */
  8748.     }
  8749. #endif /* NOSCRIPT */
  8750.  
  8751. #ifndef NOXFER
  8752. #ifdef PIPESEND
  8753.     if (cx == XXCREC) {            /* CRECEIVE */
  8754.     if (protocol != PROTO_K) {
  8755.         printf("?Sorry, CRECEIVE works only with Kermit protocol\n");
  8756.         return(-9);
  8757.     } else
  8758.       return(doxget(cx));
  8759.     }
  8760.     if (cx == XXCGET) {            /* CGET */
  8761.     return(doxget(cx));
  8762.     }
  8763. #endif /* PIPESEND */
  8764.  
  8765.     if (cx == XXREC)            /* RECEIVE */
  8766.       return(doxget(cx));
  8767. #endif /* NOXFER */
  8768.  
  8769. #ifndef NOXFER
  8770.     if (cx == XXREM) {            /* REMOTE */
  8771. #ifdef NEWFTP
  8772.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  8773.       return(doftprmt(0,0));
  8774. #endif /* NEWFTP */
  8775. #ifdef CK_XYZ
  8776.     if (protocol != PROTO_K) {
  8777.         printf("Sorry, REMOTE commands only work with Kermit protocol\n");
  8778.         return(-9);
  8779.     }
  8780. #endif /* CK_XYZ */
  8781.     x = cmkey(remcmd,nrmt,"Remote Kermit server command","",xxstring);
  8782.     if (x == -3) {
  8783.         printf("?You must specify a command for the remote server\n");
  8784.         return(-9);
  8785.     }
  8786.     return(dormt(x));
  8787.     }
  8788. #endif /* NOXFER */
  8789.  
  8790. #ifndef NORENAME
  8791. #ifndef NOFRILLS
  8792.     if (cx == XXREN) {            /* RENAME */
  8793. #ifdef IKSD
  8794.     if (inserver && (!ENABLED(en_ren)
  8795. #ifdef CK_LOGIN
  8796.              || isguest
  8797. #endif /* CK_LOGIN */
  8798.              )) {
  8799.         printf("?Sorry, renaming of files is disabled\n");
  8800.         return(-9);
  8801.     }
  8802. #endif /* IKSD */
  8803. #ifdef CK_APC
  8804.     if ((apcactive == APC_LOCAL) ||
  8805.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  8806.       return(success = 0);
  8807. #endif /* CK_APC */
  8808.     return(dorenam());
  8809.     }
  8810. #endif /* NOFRILLS */
  8811. #endif /* NORENAME */
  8812.  
  8813.     if (cx == XXEIGHT) {        /* EIGHTBIT */
  8814.     extern int parity, cmask, cmdmsk;
  8815.     if ((x = cmcfm()) < 0)
  8816.       return(x);
  8817.     parity = 0;
  8818.     cmask = 0xff;
  8819.     cmdmsk = 0xff;
  8820.     return(success = 1);
  8821.     }
  8822.  
  8823. #ifndef NOXFER
  8824. /* SEND, CSEND, MOVE, MAIL, and RESEND use the new common code */
  8825.  
  8826.     if (cx == XXSEN            /* SEND */
  8827. #ifdef PIPESEND
  8828.     || cx == XXCSEN            /* CSEND */
  8829. #endif /* PIPESEND */
  8830.     || cx == XXMOVE            /* MOVE */
  8831.     || cx == XXMAI            /* MAIL */
  8832. #ifdef CK_RESEND
  8833.     || cx == XXRSEN            /* RESEND */
  8834. #endif /* CK_RESEND */
  8835.     ) {
  8836. #ifdef IKSD
  8837.     if (inserver && !ENABLED(en_get)) {
  8838.         printf("?Sorry, sending files is disabled\n");
  8839.         return(-9);
  8840.     }
  8841. #endif /* IKSD */
  8842.     return(doxsend(cx));
  8843.     }
  8844.  
  8845. /* PSEND, ADD, and REMOVE use special parsing */
  8846.  
  8847. #ifdef ADDCMD
  8848.     /* ADD and REMOVE */
  8849.     if (cx == XXADD || cx == XXREMV) {
  8850.     char * m;
  8851.     m = (cx == XXADD) ? "Add to which list?" : "Remove from which list?";
  8852.     x = cmkey(addtab,naddtab,m,"",xxstring);
  8853.     if (x < 0)
  8854.       return(x);
  8855. #ifndef NOMSEND
  8856.     if (x == ADD_SND)
  8857.       return(addsend(cx));
  8858.     else
  8859. #endif /* NOMSEND */
  8860.       return(doadd(cx,x));
  8861.     }
  8862. #endif /* ADDCMD */
  8863.  
  8864. #ifdef CK_RESEND
  8865.     if (cx == XXPSEN) {            /* PSEND */
  8866.     int seekto = 0;
  8867.  
  8868.     cmarg = cmarg2 = "";
  8869.     x = cmifi("File to partially send", "", &s, &y, xxstring);
  8870.     if (x < 0) {
  8871.         if (x == -3) {
  8872.         printf("?A file specification is required\n");
  8873.         return(-9);
  8874.         } else return(x);
  8875.     }
  8876.     nfils = -1;            /* Files come from internal list. */
  8877. #ifndef NOMSEND
  8878.         addlist = 0;            /* Don't use SEND-LIST. */
  8879.         filenext = NULL;
  8880. #endif /* NOMSEND */
  8881.     ckstrncpy(line,s,LINBUFSIZ);    /* Save copy of string just parsed. */
  8882.     debug(F110,"PSEND line",line,0);
  8883.     if (y != 0) {
  8884.         printf("?Sorry, wildcards not permitted in this command\n");
  8885.         return(-9);
  8886.     }
  8887.     if (sizeof(int) < 4) {
  8888.         printf("?Sorry, this command needs 32-bit integers\n");
  8889.         return(-9);
  8890.     }
  8891.     x = cmnum("starting position (byte number)",
  8892.           "",10,&seekto,xxstring);
  8893.     if (x < 0)
  8894.       return(x);
  8895.     zfnqfp(s,fspeclen,fspec);    /* Get full path */
  8896.     if ((x = cmtxt("Name to send it with","",&s,NULL)) < 0)
  8897.       return(x);
  8898.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  8899.  
  8900. #ifdef IKSD
  8901.     if (inserver && !ENABLED(en_get)) {
  8902.         printf("?Sorry, sending files is disabled\n");
  8903.         return(-9);
  8904.     }
  8905. #endif /* IKSD */
  8906. #ifdef PIPESEND
  8907.     if (sndfilter) {
  8908.         printf("?Sorry, no PSEND while SEND FILTER selected\n");
  8909.         return(-9);
  8910.     }
  8911. #endif /* PIPESEND */
  8912. #ifdef CK_XYZ
  8913.     if ((protocol == PROTO_X || protocol == PROTO_XC)) {
  8914.         printf("Sorry, PSEND works only with Kermit protocol\n");
  8915.         return(-9);
  8916.     }
  8917. #endif /* CK_XYZ */
  8918.  
  8919.     cmarg2 = brstrip(tmpbuf);    /* Strip braces */
  8920.     cmarg = line;            /* File to send */
  8921.     debug(F110,"PSEND filename",cmarg,0);
  8922.     debug(F110,"PSEND as-name",cmarg2,0);
  8923.     sendstart = seekto;
  8924.     sstate = 's';            /* Set start state to SEND */
  8925. #ifndef NOMSEND
  8926.     addlist = 0;
  8927.     filenext = NULL;
  8928. #endif /* NOMSEND */
  8929.     sendmode = SM_PSEND;
  8930. #ifdef MAC
  8931.     what = W_SEND;
  8932.     scrcreate();
  8933. #endif /* MAC */
  8934.     if (local) {            /* If in local mode, */
  8935.         displa = 1;            /* enable file transfer display */
  8936.     }
  8937.     return(0);
  8938.     }
  8939. #endif /* CK_RESEND */
  8940. #endif /* NOXFER */
  8941.  
  8942. #ifndef NOXFER
  8943. #ifndef NOMSEND
  8944.     if (cx == XXMSE || cx == XXMMOVE) {
  8945. #ifdef NEWFTP
  8946.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  8947.       return(doftpput(cx,0));
  8948. #endif /* NEWFTP */
  8949. #ifdef CK_XYZ
  8950.     if (protocol == PROTO_X || protocol == PROTO_XC) {
  8951.         printf(
  8952. "Sorry, you can only send one file at a time with XMODEM protocol\n"
  8953.            );
  8954.         return(-9);
  8955.     }
  8956. #endif /* CK_XYZ */
  8957.         return(doxsend(cx));
  8958.     }
  8959.  
  8960. #ifdef COMMENT                /* (moved to doxsend) */
  8961.     if (cx == XXMSE || cx == XXMMOVE) {    /* MSEND and MMOVE commands */
  8962.     nfils = 0;            /* Like getting a list of */
  8963.     lp = line;            /* files on the command line */
  8964.     addlist = 0;            /* Do not use SEND-LIST */
  8965.     filenext = NULL;        /* Ditto ! */
  8966.  
  8967.     while (1) {
  8968.         char *p;
  8969.         if ((x = cmifi("Names of files to send, separated by spaces","",
  8970.                &s,&y,xxstring)) < 0) {
  8971.         if (x == -3) {
  8972.             if (nfils <= 0) {
  8973.             printf("?A file specification is required\n");
  8974.             return(-9);
  8975.             } else break;
  8976.         }
  8977.         return(x);
  8978.         }
  8979.         msfiles[nfils++] = lp;    /* Got one, count it, point to it, */
  8980.         p = lp;            /* remember pointer, */
  8981.         while (*lp++ = *s++)    /* and copy it into buffer */
  8982.           if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
  8983.           printf("?MSEND list too long\n");
  8984.           line[0] = NUL;
  8985.           return(-9);
  8986.           }
  8987.         debug(F111,"msfiles",msfiles[nfils-1],nfils-1);
  8988.         if (nfils == 1) *fspec = NUL; /* Take care of \v(filespec) */
  8989. #ifdef ZFNQFP
  8990.         zfnqfp(p,TMPBUFSIZ,tmpbuf);
  8991.         p = tmpbuf;
  8992. #endif /* ZFNQFP */
  8993.         if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) {
  8994.         strcat(fspec,p);    /* safe */
  8995.         strcat(fspec," ");    /* safe */
  8996.         } else printf("WARNING - \\v(filespec) buffer overflow\n");
  8997.     }
  8998.     cmlist = msfiles;        /* Point cmlist to pointer array */
  8999.     cmarg2 = "";            /* No internal expansion list (yet) */
  9000.     sndsrc = nfils;            /* Filenames come from cmlist */
  9001.     sendmode = SM_MSEND;        /* Remember this kind of SENDing */
  9002.     sstate = 's';            /* Set start state for SEND */
  9003.     if (cx == XXMMOVE)        /* If MMOVE'ing, */
  9004.       moving = 1;            /*  set this flag. */
  9005. #ifdef MAC
  9006.     what = W_SEND;
  9007.     scrcreate();
  9008. #endif /* MAC */
  9009.     if (local) {            /* If in local mode, */
  9010.         displa = 1;            /* turn on file transfer display */
  9011.         ttflui();            /* and flush tty input buffer. */
  9012.     }
  9013.     return(0);
  9014.     }
  9015. #endif /* COMMENT */
  9016. #endif /* NOMSEND */
  9017. #endif /* NOXFER */
  9018.  
  9019. #ifndef NOSERVER
  9020.     if (cx == XXSER) {            /* SERVER */
  9021. #ifdef CK_XYZ
  9022.     if (protocol != PROTO_K) {
  9023.         printf("Sorry, SERVER only works with Kermit protocol\n");
  9024.         return(-9);
  9025.     }
  9026. #endif /* CK_XYZ */
  9027. #ifdef COMMENT
  9028. /*
  9029.   Parse for time limit, but since we don't use it yet,
  9030.   the parsing is commented out.
  9031. */
  9032.     x_ifnum = 1;            /* Turn off internal complaints */
  9033.     y = cmnum("optional time limit, seconds, or time of day as hh:mm:ss",
  9034.           "0", 10, &x, xxstring
  9035.           );
  9036.     x_ifnum = 0;
  9037.     if (y < 0) {
  9038.         if (y == -2) {        /* Invalid number or expression */
  9039.         zz = tod2sec(atmbuf);    /* Convert to secs since midnight */
  9040.         if (zz < 0L) {
  9041.             printf("?Number, expression, or time of day required\n");
  9042.             return(-9);
  9043.         } else {
  9044.             char now[32];    /* Current time */
  9045.             char *p;
  9046.             long tnow;
  9047.             p = now;
  9048.             ztime(&p);
  9049.             tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
  9050.             if (zz < tnow)    /* User's time before now */
  9051.               zz += 86400L;    /* So make it tomorrow */
  9052.             zz -= tnow;        /* Seconds from now. */
  9053.         }
  9054.         } else
  9055.           return(y);
  9056.     }
  9057.     if (zz > -1L) {
  9058.         x = zz;
  9059.         if (zz != (long) x) {
  9060.         printf(
  9061. "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
  9062.                );
  9063.         return(-9);
  9064.         }
  9065.     }
  9066.     if (x < 0)
  9067.       x = 0;
  9068. #endif /* COMMENT */
  9069.  
  9070.     if ((x = cmcfm()) < 0) return(x);
  9071.     sstate = 'x';
  9072. #ifdef MAC
  9073.     what = W_RECV;
  9074.     scrcreate();
  9075. #endif /* MAC */
  9076.     if (local) displa = 1;
  9077. #ifdef AMIGA
  9078.     reqoff();            /* No DOS requestors while server */
  9079. #endif /* AMIGA */
  9080.     return(0);
  9081.     }
  9082. #endif /* NOSERVER */
  9083.  
  9084.     if (cx == XXSAVE) {            /* SAVE command */
  9085.     x = cmkey(savtab,nsav,"option","keymap",xxstring);
  9086.     if (x == -3) {
  9087.         printf("?You must specify an option to save\n");
  9088.         return(-9);
  9089.     }
  9090.     if (x < 0) return(x);
  9091.     /* have to set success separately for each item in doprm()... */
  9092.     /* actually not really, could have just had doprm return 0 or 1 */
  9093.     /* and set success here... */
  9094.     y = dosave(x);
  9095.     if (y == -3) {
  9096.         printf("?More fields required\n");
  9097.         return(-9);
  9098.     } else return(y);
  9099.     }
  9100.  
  9101.     if (cx == XXSET) {            /* SET command */
  9102.     x = cmkey(prmtab,nprm,"Parameter","",xxstring);
  9103.     if (x == -3) {
  9104.         printf("?You must specify a parameter to set\n");
  9105.         return(-9);
  9106.     }
  9107.     if (x < 0) return(x);
  9108.     /* have to set success separately for each item in doprm()... */
  9109.     /* actually not really, could have just had doprm return 0 or 1 */
  9110.     /* and set success here... */
  9111.     y = doprm(x,0);
  9112.     if (y == -3) {
  9113.         printf("?More fields required\n");
  9114.         return(-9);
  9115.     } else return(y);
  9116.     }
  9117.  
  9118. #ifndef NOPUSH
  9119.     if (cx == XXSHE            /* SHELL (system) command */
  9120.     || cx == XXEXEC            /* exec() */
  9121.     ) {
  9122.     int rx = 0;
  9123.     char * p = NULL;
  9124.     int i /* ,n */ ;
  9125. #ifdef UNIXOROSK
  9126.     char * args[256];
  9127. #endif /* UNIXOROSK */
  9128.  
  9129. #ifdef IKSD
  9130.     if (inserver && (nopush || !ENABLED(en_hos))) {
  9131.         printf("?Sorry, host command access is disabled\n");
  9132.         return(-9);
  9133.     }
  9134. #endif /* IKSD */
  9135.  
  9136. #ifdef CKEXEC
  9137.     if (cx == XXEXEC) {        /* EXEC (overlay ourselves) */
  9138.         struct FDB sw, fl;
  9139.         cmfdbi(&sw,            /* First FDB - command switches */
  9140.            _CMKEY,        /* fcode */
  9141.            "Command to overlay C-Kermit\n or switch", /* hlpmsg */
  9142.            "",            /* default */
  9143.            "",            /* addtl string data */
  9144.            1,            /* addtl numeric data 1: tbl size */
  9145.            4,            /* addtl numeric data 2: 4 = cmswi */
  9146.            xxstring,        /* Processing function */
  9147.            redirsw,        /* Keyword table */
  9148.            &fl            /* Pointer to next FDB */
  9149.            );
  9150.         cmfdbi(&fl,            /* 2nd FDB - command to exec */
  9151.            _CMFLD,        /* fcode */
  9152.            "Command to overlay C-Kermit", /* hlpmsg */
  9153.            "",            /* default */
  9154.            "",            /* addtl string data */
  9155.            0,            /* addtl numeric data 1 */
  9156.            0,            /* addtl numeric data 2 */
  9157.            xxstring,
  9158.            NULL,
  9159.            NULL            /* No more after this */
  9160.            );
  9161.         while (1) {
  9162.         x = cmfdb(&sw);        /* Parse something */
  9163.         debug(F101,"exec cmfdb","",x);
  9164.         if (x < 0)
  9165.           return(x);
  9166.         /* Generalize this if we add more switches */
  9167.         if (cmresult.fcode == _CMKEY) {
  9168.             rx = 1;
  9169.             continue;
  9170.         }
  9171.         if (cmresult.fcode == _CMFLD)
  9172.           break;
  9173.         return(-2);
  9174.         }
  9175.         ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ);
  9176.         if (!tmpbuf[0]) {
  9177.         printf("?Command required\n");
  9178.         return(-9);
  9179.         }
  9180.         p = brstrip(tmpbuf);
  9181.         args[0] = NULL;        /* Set argv[0] to it */
  9182.         makestr(&args[0],p);
  9183.         for (i = 1; i < 255; i++) {    /* Get arguments for command */
  9184.         if ((x = cmfld("Argument","",&s,xxstring)) < 0) {
  9185.             if (x == -3) {
  9186.             if ((x = cmcfm()) < 0)
  9187.               return(x);
  9188.             break;
  9189.             } else
  9190.               return(x);
  9191.         }
  9192.         args[i] = NULL;
  9193.         s = brstrip(s);
  9194.         makestr(&args[i],s);
  9195.         }
  9196.         args[i] = NULL;
  9197.     } else {
  9198. #endif /* CKEXEC */
  9199.         if ((x = cmtxt("System command to execute","",&s,xxstring)) < 0)
  9200.           return(x);
  9201. #ifdef CKEXEC
  9202.     }
  9203. #endif /* CKEXEC */
  9204.         if (nopush)
  9205.           return(success = 0);
  9206. #ifdef CK_APC
  9207.     if (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
  9208.       return(success = 0);
  9209. #endif /* CK_APC */
  9210.     conres();            /* Make console normal  */
  9211. #ifdef OS2
  9212.     if (!(s && *s)) {
  9213.         os2push();
  9214.             return(success = 1);
  9215.     } else
  9216. #endif /* OS2 */
  9217.       if (cx == XXSHE) {
  9218.           x = zshcmd(s);
  9219.           debug(F101,"RUN zshcmd code","",x);
  9220.           concb((char)escape);
  9221.           return(success = x);
  9222. #ifdef CKEXEC
  9223.       } else {
  9224. #ifdef DEBUG
  9225.           if (deblog) {
  9226.           debug(F111,"EXEC cmd",p,0);
  9227.           for (i = 0; i < 256 && args[i]; i++)
  9228.             debug(F111,"EXEC arg",args[i],i);
  9229.           }
  9230. #endif /* DEBUG */
  9231.           if (p) {
  9232.           z_exec(p,args,rx);    /* Overlay ourself */
  9233.           debug(F100,"EXEC fails","",0);
  9234.           concb((char)escape);    /* In case it returns */
  9235.           }
  9236.           return(success = 0);
  9237. #endif /* CKEXEC */
  9238.       }
  9239.     }
  9240.  
  9241. #ifdef CK_REDIR
  9242.     if (cx == XXFUN) {            /* REDIRECT */
  9243. #ifdef CK_APC
  9244.     if ((apcactive == APC_LOCAL) ||
  9245.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  9246.       return(success = 0);
  9247. #endif /* CK_APC */
  9248.     ckmakmsg(tmpbuf,
  9249.          TMPBUFSIZ,
  9250.          "Local command to run,\n",
  9251.          "with its standard input/output redirected to ",
  9252.          local ? ttname : "the communications connection",
  9253.          "\n"
  9254.          );
  9255.     if ((x = cmtxt(tmpbuf,"",&s,xxstring)) < 0)
  9256.       return(x);
  9257.         if (nopush) {
  9258.             printf("?REDIRECT disabled\n");
  9259.             return(success=0);
  9260.         }
  9261.     if (!local) {
  9262.         printf("?SET LINE or SET HOST required first\n");
  9263.         return(-9);
  9264.     }
  9265.     if (!*s) {
  9266.         printf("?REDIRECT requires a command to redirect\n");
  9267.         return(-9);
  9268.     }
  9269.     return(success = ttruncmd(s));
  9270.     }
  9271. #endif /* CK_REDIR */
  9272. #endif /* NOPUSH */
  9273.  
  9274. #ifndef NOSHOW
  9275.     if (cx == XXSHO) {            /* SHOW */
  9276.     x = cmkey(shotab,nsho,"","parameters",xxstring);
  9277.     if (x < 0) return(x);
  9278.     return(doshow(x));
  9279.     }
  9280. #endif /* NOSHOW */
  9281.  
  9282. #ifndef MAC
  9283.     if (cx == XXSPA) {            /* SPACE */
  9284. #ifdef IKSD
  9285.     if (inserver && !ENABLED(en_spa)) {
  9286.         printf("?Sorry, SPACE command disabled\n");
  9287.         return(-9);
  9288.     }
  9289. #endif /* IKSD */
  9290. #ifdef datageneral
  9291.     /* AOS/VS can take an argument after its "space" command. */
  9292.     if ((x = cmtxt("Confirm, or local directory name","",&s,xxstring)) < 0)
  9293.       return(x);
  9294.     if (nopush) {
  9295.         printf("?Sorry, SPACE command disabled\n");
  9296.         return(-9);
  9297.     } else if (*s == NUL) {
  9298.         xsystem(SPACMD);
  9299.     } else {
  9300.         ckmakmsg(line,LINBUFSIZ,"space ",s,NULL,NULL);
  9301.         xsystem(line);
  9302.     }
  9303. #else
  9304. #ifdef OS2
  9305.     if ((x = cmtxt("Press Enter for current disk,\n\
  9306.  or specify a disk letter like A:","",&s,xxstring)) < 0)
  9307.       return(x);
  9308.     if (*s == NUL) {        /* Current disk */
  9309.             unsigned long space = zdskspace(0);
  9310.             if (space > 0 && space < 1024)
  9311.               printf(" Free space: unknown\n");
  9312.             else
  9313.           printf(" Free space: %ldK\n", space/1024L);
  9314.     } else {
  9315.         int drive = toupper(*s);
  9316.             unsigned long space = zdskspace(drive - 'A' + 1);
  9317.             if (space > 0 && space < 1024)
  9318.               printf(" Drive %c: unknown free\n");
  9319.             else
  9320.               printf(" Drive %c: %ldK free\n", drive,space / 1024L);
  9321.     }
  9322. #else
  9323. #ifdef UNIXOROSK
  9324.     x = cmdir("Confirm for current disk,\n\
  9325.  or specify a disk device or directory","",&s,xxstring);
  9326.     if (x == -3)
  9327.       s = "";
  9328.     else if (x < 0)
  9329.       return(x);
  9330.         ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  9331.         s = tmpbuf;
  9332.     if ((x = cmcfm()) < 0) return(x);
  9333.     if (nopush) {
  9334.         printf("?Sorry, SPACE command disabled\n");
  9335.         return(-9);
  9336.     }
  9337.     if (!*s) {            /* Current disk */
  9338.         xsystem(SPACMD);
  9339.     } else {            /* Specified disk */
  9340.         ckmakmsg(line,LINBUFSIZ,SPACM2," ",s,NULL);
  9341.         xsystem(line);
  9342.     }
  9343. #else
  9344.     if ((x = cmcfm()) < 0) return(x);
  9345.     if (nopush) {
  9346.         printf("?Sorry, SPACE command disabled\n");
  9347.         return(-9);
  9348.     }
  9349.     xsystem(SPACMD);
  9350. #endif /* UNIXOROSK */
  9351. #endif /* OS2 */
  9352. #endif /* datageneral */
  9353.     return(success = 1);        /* Pretend it worked */
  9354.     }
  9355. #endif /* MAC */
  9356.  
  9357. #ifndef NOXFER
  9358.     if (cx == XXSTA) {            /* STATISTICS */
  9359.     if ((x = cmkey(stattab,2,"Carriage return, or option",
  9360.                "/brief",xxstring)) < 0)
  9361.       return(x);
  9362.     if ((y = cmcfm()) < 0) return(y);
  9363.     return(success = dostat(x));
  9364.     }
  9365. #endif /* NOXFER */
  9366.  
  9367.     if (cx == XXSTO || cx == XXEND) {    /* STOP, END, or POP */
  9368.     if ((y = cmnum("exit status code","0",10,&x,xxstring)) < 0)
  9369.       return(y);
  9370.     if ((y = cmtxt("Message to print","",&s,xxstring)) < 0)
  9371.       return(y);
  9372.     s = brstrip(s);
  9373.     if (*s) printf("%s\n",s);
  9374.     if (cx == XXSTO) {
  9375.         dostop();
  9376.     } else {
  9377.         doend(x);
  9378.     }
  9379.     return(success = (x == 0));
  9380.     }
  9381.     if (cx == XXSUS) {            /* SUSPEND */
  9382.     if ((y = cmcfm()) < 0) return(y);
  9383. #ifdef NOJC
  9384.     printf("Sorry, this version of Kermit cannot be suspended\n");
  9385. #else
  9386. #ifdef IKSD
  9387.     if (inserver) {
  9388.         printf("?Sorry, IKSD can not be suspended\n");
  9389.         return(-9);
  9390.     } else
  9391. #endif /* IKSD */
  9392.       if (nopush) {
  9393.         printf("?Sorry, access to system is disabled\n");
  9394.         return(-9);
  9395.     }
  9396.     stptrap(0);
  9397. #endif /* NOJC */
  9398.     return(0);
  9399.     }
  9400.  
  9401.     if (cx == XXTAK) {            /* TAKE */
  9402. #ifdef OS2
  9403.     extern char startupdir[],exedir[],inidir[];
  9404.     char * scriptenv, * keymapenv;
  9405.     int xx;
  9406. #define TAKEPATHLEN 4096
  9407. #else /* OS2 */
  9408. #define TAKEPATHLEN 1024
  9409. #endif /* OS2 */
  9410.     char takepath[TAKEPATHLEN];
  9411.  
  9412.     if (tlevel >= MAXTAKE-1) {
  9413.         printf("?Take files nested too deeply\n");
  9414.         return(-9);
  9415.     }
  9416. #ifdef OS2
  9417. #ifdef NT
  9418.     scriptenv = getenv("K95SCRIPTS");
  9419.     keymapenv = getenv("K95KEYMAPS");
  9420. #else /* NT */
  9421.     scriptenv = getenv("K2SCRIPTS");
  9422.     keymapenv = getenv("K2KEYMAPS");
  9423. #endif /* NT */
  9424.     if (!scriptenv)
  9425.       scriptenv = getenv("CK_SCRIPTS");
  9426.     if (!keymapenv)
  9427.       keymapenv = getenv("CK_KEYMAPS");
  9428. #ifdef COMMENT
  9429.     /* This is not only unsafe but it's wrong */
  9430.     /* There are 19 %s's but 24 strings to print */
  9431.     sprintf(takepath,        /* UNSAFE */
  9432.                 /* semicolon-separated path list */
  9433.                 "%s%s%s%s%s;%s%s;%s%s;%s;%s%s;%s%s;%s;%s%s;%s%s",
  9434.                 scriptenv?scriptenv:"",
  9435.                 (scriptenv && scriptenv[strlen(scriptenv)-1]==';')?"":";",
  9436.                 keymapenv?keymapenv:"",
  9437.                 (keymapenv && keymapenv[strlen(keymapenv)-1]==';')?"":";",
  9438.                 startupdir,
  9439.                 startupdir, "SCRIPTS/",
  9440.                 startupdir, "KEYMAPS/",
  9441.                 inidir,
  9442.                 inidir, "SCRIPTS/",
  9443.                 inidir, "KEYMAPS/",
  9444.                 zhome(),
  9445.                 zhome(), "SCRIPTS/",
  9446.                 zhome(), "KEYMAPS/",
  9447.                 exedir,
  9448.                 exedir, "SCRIPTS/",
  9449.                 exedir, "KEYMAPS/"
  9450.                 );
  9451. #else
  9452.     ckstrncpy(takepath,scriptenv?scriptenv:"",TAKEPATHLEN); /* SAFE */
  9453.     ckstrncat(takepath,
  9454.           (scriptenv && scriptenv[strlen(scriptenv)-1]==';')?"":";",
  9455.           TAKEPATHLEN
  9456.           );
  9457.     ckstrncat(takepath,keymapenv?keymapenv:"",TAKEPATHLEN);
  9458.     ckstrncat(takepath,
  9459.           (keymapenv && keymapenv[strlen(keymapenv)-1]==';')?"":";",
  9460.           TAKEPATHLEN
  9461.           );
  9462.     ckstrncat(takepath,startupdir,TAKEPATHLEN);
  9463.     ckstrncat(takepath,";",TAKEPATHLEN);
  9464.     ckstrncat(takepath,startupdir,TAKEPATHLEN);
  9465.     ckstrncat(takepath,"SCRIPTS/",TAKEPATHLEN);
  9466.     ckstrncat(takepath,";",TAKEPATHLEN);
  9467.     ckstrncat(takepath,startupdir,TAKEPATHLEN);
  9468.     ckstrncat(takepath,"KEYMAPS/",TAKEPATHLEN);
  9469.     ckstrncat(takepath,";",TAKEPATHLEN);
  9470.  
  9471.     ckstrncat(takepath,inidir,TAKEPATHLEN);
  9472.     ckstrncat(takepath,";",TAKEPATHLEN);
  9473.     ckstrncat(takepath,inidir,TAKEPATHLEN);
  9474.     ckstrncat(takepath,"SCRIPTS/",TAKEPATHLEN);
  9475.     ckstrncat(takepath,";",TAKEPATHLEN);
  9476.     ckstrncat(takepath,inidir,TAKEPATHLEN);
  9477.     ckstrncat(takepath,"KEYMAPS/",TAKEPATHLEN);
  9478.     ckstrncat(takepath,";",TAKEPATHLEN);
  9479.  
  9480.     ckstrncat(takepath,zhome(),TAKEPATHLEN);
  9481.     ckstrncat(takepath,";",TAKEPATHLEN);
  9482.     ckstrncat(takepath,zhome(),TAKEPATHLEN);
  9483.     ckstrncat(takepath,"SCRIPTS/",TAKEPATHLEN);
  9484.     ckstrncat(takepath,";",TAKEPATHLEN);
  9485.     ckstrncat(takepath,zhome(),TAKEPATHLEN);
  9486.     ckstrncat(takepath,"KEYMAPS/",TAKEPATHLEN);
  9487.     ckstrncat(takepath,";",TAKEPATHLEN);
  9488.  
  9489.     ckstrncat(takepath,exedir,TAKEPATHLEN);
  9490.     ckstrncat(takepath,";",TAKEPATHLEN);
  9491.     ckstrncat(takepath,exedir,TAKEPATHLEN);
  9492.     ckstrncat(takepath,"SCRIPTS/",TAKEPATHLEN);
  9493.     ckstrncat(takepath,";",TAKEPATHLEN);
  9494.     ckstrncat(takepath,exedir,TAKEPATHLEN);
  9495.     ckstrncat(takepath,"KEYMAPS/",TAKEPATHLEN);
  9496.     ckstrncat(takepath,";",TAKEPATHLEN);
  9497. #endif /* COMMENT */
  9498.  
  9499. #else /* not OS2 */
  9500.     y = TAKEPATHLEN;
  9501.     s = takepath;
  9502.     zzstring("\\v(home)",&s,&y);
  9503. #endif /* OS2 */
  9504.  
  9505.     if ((y = cmifip("Commands from file",
  9506.             "",&s,&x,0,takepath,xxstring)) < 0) {
  9507.         if (y == -3) {
  9508.         printf("?A file name is required\n");
  9509.         return(-9);
  9510.         } else
  9511.           return(y);
  9512.     }
  9513.     if (x != 0) {
  9514.         printf("?Wildcards not allowed in command file name\n");
  9515.         return(-9);
  9516.     }
  9517.     ckstrncpy(line,s,LINBUFSIZ);
  9518.     debug(F110,"TAKE file",s,0);
  9519.     if (isdir(s)) {
  9520.         printf("?Can't execute a directory - \"%s\"\n", s);
  9521.         return(-9);
  9522.     }
  9523. #ifndef NOTAKEARGS
  9524.     {
  9525.         char * p;
  9526.         x = strlen(line);
  9527.         debug(F111,"TAKE args",line,x);
  9528.         p = line + x + 1;
  9529.         if ((y = cmtxt("Optional arguments","",&s,xxstring)) < 0)
  9530.           return(y);
  9531.         if (*s) {            /* Args given? */
  9532.         ckstrncpy(p,s,LINBUFSIZ-x-1);
  9533. #ifdef ZFNQFP
  9534.         zfnqfp(line,TMPBUFSIZ,tmpbuf);
  9535.         s = tmpbuf;
  9536. #else
  9537.         s = line;
  9538. #endif /* ZFNQFP */
  9539.         debug(F110,"TAKE filename",s,0);
  9540.         x = strlen(s);
  9541.         debug(F101,"TAKE new len",s,x);
  9542.  
  9543. #ifdef COMMENT
  9544. /*
  9545.   This was added in C-Kermit 7.0 to allow args to be passed from the TAKE
  9546.   command to the command file.  But it overwrites the current argument vector,
  9547.   which is at best surprising, and at worst unsafe.
  9548. */
  9549.         addmac("%0",s);        /* Define %0 = name of file */
  9550.         varnam[0] = '%';
  9551.         varnam[2] = '\0';
  9552.         debug(F110,"take arg 0",s,0);
  9553.         debug(F110,"take args",p,0);
  9554.         for (y = 1; y < 10; y++) { /* Clear current args %1..%9 */
  9555.             varnam[1] = (char) (y + '0');
  9556.             delmac(varnam,0);
  9557.         }
  9558.         xwords(p,MAXARGLIST,NULL,0); /* Assign new args */
  9559.         debug(F110,"take args",p,0);
  9560. #else
  9561. /*
  9562.   This method is used in 8.0.  If the TAKE command includes arguments, we
  9563.   insert an intermediate temporary macro between the current level; we pass
  9564.   the arguments to the macro and then the macro TAKEs the command file.
  9565.   If the user Ctrl-C's out of the TAKE file, some temporary macro definitions
  9566.   and other small malloc'd bits might be left behind.
  9567. */
  9568.         {
  9569.             char * q = NULL;
  9570.             char * r = NULL;
  9571.             int k, m;
  9572.             m = maclvl;
  9573.             q = (char *)malloc(x+24);
  9574.             if (q) {
  9575.             r = (char *)malloc(x+24);
  9576.             if (r) {
  9577.                 sprintf(q,"_file[%s](%d)",s,cmdlvl); /* safe */
  9578.                 sprintf(r,"take %s",s); /* safe */
  9579.                 k = addmac(q,r);
  9580.                 if (k > -1) {
  9581.                 dodo(k,p,0);
  9582.                 while (maclvl > m) {
  9583.                     sstate = (CHAR) parser(1);
  9584.                     if (sstate) proto();
  9585.                 }
  9586.                 }
  9587.                 k = delmac(q,0);
  9588.                 free(q);
  9589.                 free(r);
  9590.                 return(success);
  9591.             }
  9592.             }
  9593.         }
  9594.         return(success = 0);
  9595. #endif /* COMMENT */
  9596.         }
  9597.     }
  9598. #else
  9599.     if ((y = cmcfm()) < 0) return(y);
  9600. #endif /* NOTAKEARGS */
  9601.     return(success = dotake(line));
  9602.     }
  9603.  
  9604. #ifndef NOLOCAL
  9605. #ifdef OS2
  9606.     if (cx == XXVIEW) {            /* VIEW Only Terminal mode */
  9607.     viewonly = TRUE;
  9608.     success = doconect(0, 0);
  9609.     viewonly = FALSE;
  9610.     return success;
  9611.     }
  9612. #endif /* OS2 */
  9613.  
  9614. #ifdef NETCONN
  9615.     if (cx == XXTEL || cx == XXIKSD) {    /* TELNET */
  9616.     int x,z;
  9617. #ifdef OS2
  9618.     if (!tcp_avail) {
  9619.         printf("?Sorry, either TCP/IP is not available on this system or\n\
  9620. necessary DLLs did not load.  Use SHOW NETWORK to check network status.\n");
  9621.         success = 0;
  9622.         return(-9);
  9623.     } else
  9624. #endif /* OS2 */
  9625.       {
  9626.       x = nettype;            /* Save net type in case of failure */
  9627.       z = ttnproto;            /* Save protocol in case of failure */
  9628.       nettype = NET_TCPB;
  9629.       ttnproto = (cx == XXTEL) ? NP_TELNET : NP_KERMIT;
  9630.       if ((y = setlin(XYHOST,0,1)) <= 0) {
  9631.               nettype = x;        /* Failed, restore net type. */
  9632.               ttnproto = z;        /* and protocol */
  9633.               success = 0;
  9634.       }
  9635.       didsetlin++;
  9636.         }
  9637.     return(y);
  9638.     }
  9639.  
  9640. #ifndef PTYORPIPE
  9641. #ifdef NETCMD
  9642. #define PTYORPIPE
  9643. #else
  9644. #ifdef NETPTY
  9645. #define PTYORPIPE
  9646. #endif /* NETPTY */
  9647. #endif /* NETCMD */
  9648. #endif /* PTYORPIPE */
  9649.  
  9650. #ifdef PTYORPIPE
  9651.     if (cx == XXPIPE || cx == XXPTY) {    /* PIPE or PTY */
  9652.     int x;
  9653.     extern int netsave;
  9654.     x = nettype;            /* Save net type in case of failure */
  9655.     nettype = (cx == XXPIPE) ? NET_CMD : NET_PTY;
  9656.     if ((y = setlin(XYHOST,0,1)) < 0) {
  9657.         nettype = x;        /* Failed, restore net type. */
  9658.         ttnproto = z;        /* and protocol */
  9659.         success = 0;
  9660.     }
  9661.     didsetlin++;
  9662.     netsave = x;
  9663.     return(y);
  9664.     }
  9665. #endif /* PTYORPIPE */
  9666.  
  9667. #ifdef ANYSSH
  9668.     if (cx == XXSSH) {            /* SSH (Secure Shell) */
  9669.     int x,k;
  9670.         extern int mdmtyp, cxtype;
  9671.         extern char * slmsg;
  9672. #ifdef SSHBUILTIN
  9673.     struct FDB kw, fl;
  9674. #endif /* SSHBUILTIN */
  9675.  
  9676.     extern int netsave;
  9677.     x = nettype;            /* Save net type in case of failure */
  9678.     nettype = NET_PTY;        /* THIS IS VULNERABLE TO SIGINT */
  9679.  
  9680. #ifdef SSHBUILTIN
  9681.     cmfdbi(&kw,            /* 1st FDB - commands */
  9682.            _CMKEY,            /* fcode */
  9683.            "host [ command ], or action", /* hlpmsg */
  9684.            "",            /* default */
  9685.            "",            /* addtl string data */
  9686.            nsshcmd,            /* addtl numeric data 1: tbl size */
  9687.            0,            /* addtl numeric data 2: 0 = keyword */
  9688.            xxstring,        /* Processing function */
  9689.            sshkwtab,        /* Keyword table */
  9690.            &fl            /* Pointer to next FDB */
  9691.            );
  9692.     cmfdbi(&fl,            /* 2nd FDB - command to send from */
  9693.            _CMFLD,            /* fcode */
  9694.            "Command",        /* hlpmsg */
  9695.            "",            /* default */
  9696.            "",            /* addtl string data */
  9697.            0,            /* addtl numeric data 1 */
  9698.            0,            /* addtl numeric data 2 */
  9699.            xxstring,
  9700.            NULL,
  9701.            NULL
  9702.            );
  9703.     x = cmfdb(&kw);
  9704.     if (x < 0)
  9705.       return(x);
  9706.     switch (cmresult.fcode) {
  9707.       case _CMFLD:
  9708.         ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Hostname */
  9709.         if ((y = cmtxt("Optional command","",&s,xxstring)) < 0)
  9710.           return(y);
  9711.         ckstrncpy(tmpbuf,s,TMPBUFSIZ); /* Command */
  9712.             makestr(&ssh_hst,line);
  9713.             makestr(&ssh_cmd,tmpbuf);
  9714.             nettype = NET_SSH;
  9715.             x = 1;
  9716.         errno = 0;
  9717.         /* Line parameter to ttopen() is ignored */
  9718.         k = ttopen(line,&x,-mdmtyp, 0);
  9719.             if (k < 0) {
  9720.         if (errno)
  9721.           printf("?%s\n",ck_errstr());
  9722.         else
  9723.           printf("?Sorry, pseudoterminal open failed\n");
  9724.         if (hints)
  9725.           printf("Hint: Try \"ssh -t %s\"\n",ssh_hst);
  9726.         return(success = 0);
  9727.         }
  9728.             ckstrncpy(ttname,line,TTNAMLEN); /* Record the command */
  9729.             debug(F110,"ssh ttname",ttname,0);
  9730.             makestr(&slmsg,NULL);    /* No SET LINE error message */
  9731.             cxtype = CXT_TCPIP;
  9732. #ifndef NODIAL
  9733.             dialsta = DIA_UNK;
  9734. #endif /* NODIAL */
  9735.         success = 1;        /* SET LINE succeeded */
  9736.         network = 1;        /* Network connection (not serial) */
  9737.         local = 1;            /* Local mode (not remote) */
  9738.             /* Command was confirmed so we can pre-pop command level. */
  9739.             /* This is so CONNECT module won't think we're executing a */
  9740.             /* script if CONNECT was the final command in the script. */
  9741.  
  9742.             if (cmdlvl > 0)
  9743.                 prepop();
  9744. #ifndef NODIAL
  9745.             dialsta = DIA_UNK;
  9746. #endif /* NODIAL */
  9747.             success = doconect(0,cmdlvl == 0 ? 1 : 0);
  9748. #ifdef CKLOGDIAL
  9749.             if (ttchk() < 0)
  9750.               dologend();
  9751. #endif /* CKLOGDIAL */
  9752.             return(success);
  9753.  
  9754.       case _CMKEY:
  9755.         switch (cmresult.nresult) {    /* SSH keyword */
  9756.           case XSSH_OPN:        /* SSH OPEN */
  9757.         if ((x = cmfld("Host","",&s,xxstring)) < 0)
  9758.           return(x);
  9759.         ckstrncpy(line,s,LINBUFSIZ);
  9760.         if ((x = cmtxt("Optional command","",&s,xxstring)) < 0)
  9761.           return(x);
  9762.         ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  9763.                 makestr(&ssh_hst,line);
  9764.                 makestr(&ssh_cmd,tmpbuf);
  9765.                 nettype = NET_SSH;
  9766.                 x = 1;
  9767.                 /* Line parameter to ttopen() is ignored */
  9768.                 k = ttopen(line,&x,-mdmtyp, 0);
  9769.                 if (k < 0)
  9770.           return(success = 0);
  9771.                 ckstrncpy(ttname,line,TTNAMLEN); /* Record the command */
  9772.                 debug(F110,"ssh ttname",ttname,0);
  9773.                 makestr(&slmsg,NULL);    /* No SET LINE error message */
  9774.                 cxtype = CXT_TCPIP;
  9775. #ifndef NODIAL
  9776.                 dialsta = DIA_UNK;
  9777. #endif /* NODIAL */
  9778.                 success = 1;        /* SET LINE succeeded */
  9779.                 network = 1;        /* Network connection (not serial) */
  9780.                 local = 1;            /* Local mode (not remote) */
  9781.             /* Command was confirmed so we can pre-pop command level. */
  9782.             /* This is so CONNECT module won't think we're executing a */
  9783.             /* script if CONNECT was the final command in the script. */
  9784.                 if (cmdlvl > 0)
  9785.                   prepop();
  9786. #ifndef NODIAL
  9787.                 dialsta = DIA_UNK;
  9788. #endif /* NODIAL */
  9789.                 success = doconect(0,cmdlvl == 0 ? 1 : 0);
  9790. #ifdef CKLOGDIAL
  9791.                 if (ttchk() < 0)
  9792.                   dologend();
  9793. #endif /* CKLOGDIAL */
  9794.                 return(success);
  9795.  
  9796.           case XSSH_V2R:        /* SSH V2-REKEY */
  9797.         if ((x = cmcfm()) < 0)
  9798.           return(x);
  9799.         printf("Put SSH V2-REKEY action code here\n");
  9800.         return(success = 1);
  9801.  
  9802.           case XSSH_FLP:        /* SSH FORWARD-LOCAL-PORT */
  9803.           case XSSH_FRP: {        /* SSH FORWARD-REMOTE-PORT */
  9804.           char * li_port = NULL;
  9805.           char * to_port = NULL;
  9806.           char * fw_host = NULL;
  9807.           int n;
  9808.           if ((x = cmfld("listen-port","",&s,xxstring)) < 0)
  9809.             return(x);
  9810.           n = ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  9811.           li_port = tmpbuf;
  9812.           if ((x = cmfld((cmresult.nresult == XSSH_FLP) ?
  9813.                  "to-host" : "from-host",
  9814.                  "",&s,xxstring)) < 0)
  9815.             return(x);
  9816.           ckstrncpy(line,s,LINBUFSIZ);
  9817.           fw_host = tmpbuf;
  9818.           if ((x = cmfld("to-port","",&s,xxstring)) < 0)
  9819.             return(x);
  9820.           to_port = &tmpbuf[n+1];
  9821.           ckstrncpy(to_port,s,TMPBUFSIZ - n - 1);
  9822.           if ((x = cmcfm()) < 0)
  9823.             return(x);
  9824.           switch (cmresult.nresult) {
  9825.             case XSSH_FLP:    /* SSH FORWARD-LOCAL-PORT */
  9826.               printf("Put SSH FORWARD-LOCAL-PORT action code here\n");
  9827.               printf(" listen-port: %s\n",showstring(li_port));
  9828.               printf(" to-host:     %s\n",showstring(fw_host));
  9829.               printf(" to-port:     %s\n",showstring(to_port));
  9830.               break;
  9831.             case XSSH_FRP:    /* SSH FORWARD-REMOTE-PORT */
  9832.               printf("Put SSH FORWARD-REMOTE-PORT action code here\n");
  9833.               printf(" listen-port: %s\n",showstring(li_port));
  9834.               printf(" from-host:   %s\n",showstring(fw_host));
  9835.               printf(" to-port:     %s\n",showstring(to_port));
  9836.               break;
  9837.           }
  9838.           return(success = 1);
  9839.           }
  9840.       }
  9841.       default:
  9842.         return(-2);
  9843.     }
  9844. #else
  9845. #ifdef SSHCMD
  9846.     if ((y = setlin(XXSSH,0,1)) < 0) {
  9847.         nettype = x;        /* Failed, restore net type. */
  9848.         ttnproto = z;        /* and protocol */
  9849.         success = 0;
  9850.     }
  9851.     didsetlin++;
  9852.     netsave = x;
  9853.     return(y);
  9854. #endif /* SSHCMD */
  9855. #endif /* SSHBUILTIN */
  9856.     }
  9857. #endif /* ANYSSH */
  9858.  
  9859.     if (cx == XXRLOG) {            /* RLOGIN */
  9860. #ifdef RLOGCODE
  9861.     int x,z;
  9862. #ifdef OS2
  9863.     if (!tcp_avail) {
  9864.         printf("?Sorry, either TCP/IP is not available on this system or\n\
  9865. necessary DLLs did not load.  Use SHOW NETWORK to check network status.\n"
  9866.            );
  9867.         success = 0;
  9868.         return(-9);
  9869.     } else {
  9870. #endif /* OS2 */
  9871.         x = nettype;        /* Save net type in case of failure */
  9872.         z = ttnproto;        /* Save protocol in case of failure */
  9873.         nettype = NET_TCPB;
  9874.         ttnproto = NP_RLOGIN;
  9875.         if ((y = setlin(XYHOST,0,1)) <= 0) {
  9876.         nettype = x;        /* Failed, restore net type. */
  9877.         ttnproto = z;        /* and protocol */
  9878.         success = 0;
  9879.         }
  9880.         didsetlin++;
  9881. #ifdef OS2
  9882.     }
  9883. #endif /* OS2 */
  9884.     return(y);
  9885. #else
  9886.     printf("?Sorry, RLOGIN is not configured in this copy of C-Kermit.\n");
  9887.     return(-9);
  9888. #endif /* RLOGCODE */
  9889.     }
  9890. #endif /* NETCONN */
  9891. #endif /* NOLOCAL */
  9892.  
  9893. #ifndef NOXMIT
  9894.     if (cx == XXTRA) {            /* TRANSMIT */
  9895.     extern int xfrxla;
  9896.     int i, n, xpipe = 0, xbinary = 0, xxlate = 1, xxnowait = 0, getval;
  9897.     int xxecho = 0;
  9898.     int scan = 1;
  9899.     char c;
  9900.     struct FDB sf, sw, tx;        /* FDBs for parse functions */
  9901. #ifndef NOCSETS
  9902.     extern int tcs_transp;        /* Term charset is transparent */
  9903. #else
  9904.     int tcs_transp = 1;
  9905. #endif /* NOCSETS */
  9906.  
  9907. #ifdef COMMENT
  9908.     xbinary = binary;        /* Default text/binary mode */
  9909. #else
  9910.     xbinary = 0;            /* Default is text */
  9911. #endif /* COMMENT */
  9912.     xxecho = xmitx;
  9913.  
  9914.     cmfdbi(&sw,            /* First FDB - command switches */
  9915.            _CMKEY,            /* fcode */
  9916.            "Filename, or switch",    /* hlpmsg */
  9917.            "",            /* default */
  9918.            "",            /* addtl string data */
  9919.            nxmitsw,            /* addtl numeric data 1: tbl size */
  9920.            4,            /* addtl numeric data 2: 4 = cmswi */
  9921.            xxstring,        /* Processing function */
  9922.            xmitsw,            /* Keyword table */
  9923.            &sf            /* Pointer to next FDB */
  9924.            );
  9925.     cmfdbi(&sf,            /* 2nd FDB - file to send */
  9926.            _CMIFI,            /* fcode */
  9927.            "File to transmit",    /* hlpmsg */
  9928.            "",            /* default */
  9929.            "",            /* addtl string data */
  9930.            0,            /* addtl numeric data 1 */
  9931.            0,            /* addtl numeric data 2 */
  9932.            xxstring,
  9933.            NULL,
  9934. #ifdef PIPESEND
  9935.            &tx
  9936. #else
  9937.            NULL
  9938. #endif /* PIPESEND */
  9939.            );
  9940. #ifdef PIPESEND
  9941.     cmfdbi(&tx,
  9942.          _CMTXT,            /* fcode */
  9943.          "Command",            /* hlpmsg */
  9944.            "",            /* default */
  9945.            "",            /* addtl string data */
  9946.            0,            /* addtl numeric data 1 */
  9947.            0,            /* addtl numeric data 2 */
  9948.            xxstring,
  9949.            NULL,
  9950.            NULL
  9951.            );
  9952. #endif /* PIPESEND */
  9953.  
  9954.     while (1) {
  9955.         x = cmfdb(&sw);
  9956.         if (x < 0)
  9957.           return(x);
  9958.         if (cmresult.fcode != _CMKEY)
  9959.           break;
  9960.         c = cmgbrk();        /* Have switch, get break character */
  9961.         if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  9962.         printf("?This switch does not take an argument\n");
  9963.         return(-9);
  9964.         }
  9965.         if (!getval && (cmgkwflgs() & CM_ARG)) {
  9966.         printf("?This switch requires an argument\n");
  9967.         return(-9);
  9968.         }
  9969.         n = cmresult.nresult;    /* Numeric result = switch ID */
  9970.         switch (n) {        /* Process the switch */
  9971. #ifdef PIPESEND
  9972.           case XMI_CMD:        /* Transmit from a command */
  9973.         if (nopush) {
  9974.             printf("?Sorry, system command access is disabled\n");
  9975.             return(-9);
  9976.         }
  9977.         sw.hlpmsg = "Command, or switch"; /* Change help message */
  9978.         xpipe = 1;        /* (No way to undo this one) */
  9979.         break;
  9980. #endif /* PIPESEND */
  9981.  
  9982.           case XMI_BIN:        /* Binary */
  9983.         xbinary = 1;
  9984.         xxlate = 0;        /* Don't translate charsets */
  9985.         scan = 0;
  9986.         break;
  9987.  
  9988.           case XMI_TXT:        /* Text */
  9989.         xbinary = 0;
  9990.         xxlate = !tcs_transp;    /* Translate if TERM CHAR not TRANSP */
  9991.         scan = 0;
  9992.         break;
  9993.  
  9994.           case XMI_TRA:        /* Transparent text */
  9995.         xbinary = 0;
  9996.         xxlate = 0;        /* But don't translate charsets */
  9997.         scan = 0;
  9998.         break;
  9999.  
  10000. #ifdef COMMENT
  10001.           case XMI_VRB:        /* /VERBOSE */
  10002.           case XMI_QUI:        /* /QUIET */
  10003.         break;            /* (not implemented yet) */
  10004. #endif /* COMMENT */
  10005.  
  10006.           case XMI_NOW:        /* /NOWAIT */
  10007.         xxnowait = 1;
  10008.         break;
  10009.  
  10010.           case XMI_NOE:        /* /NOWAIT */
  10011.         xxecho = 0;
  10012.         break;
  10013.  
  10014.           default:
  10015.         return(-2);
  10016.         }
  10017.  
  10018.     }
  10019.     if (cmresult.fcode != _CMIFI && cmresult.fcode != _CMTXT)
  10020.       return(-2);
  10021.     ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Filename */
  10022.     s = line;
  10023.     if ((y = cmcfm()) < 0)        /* Confirm */
  10024.       return(y);
  10025. #ifdef CK_APC
  10026.     if ((apcactive == APC_LOCAL) ||
  10027.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  10028.       return(success = 0);
  10029. #endif /* CK_APC */
  10030.     if (cmresult.nresult != 0) {
  10031.         printf("?Only a single file may be transmitted\n");
  10032.         return(-9);
  10033.     }
  10034. #ifdef PIPESEND
  10035.     if (xpipe) {
  10036.         s = brstrip(s);
  10037.         if (!*s) {
  10038.         printf("?Sorry, a command to send from is required\n");
  10039.         return(-9);
  10040.         }
  10041.         pipesend = 1;
  10042.     }
  10043. #endif /* PIPESEND */
  10044.  
  10045.     if (scan && (filepeek
  10046. #ifndef NOXFER
  10047.              || patterns
  10048. #endif /* NOXFER */
  10049.              )) {        /* If user didn't specify type */
  10050.         int k, x;                  /* scan the file to see */
  10051.         x = -1;
  10052.         k = scanfile(s,&x,nscanfile);
  10053.         if (k > 0) xbinary = (k == FT_BIN) ? XYFT_B : XYFT_T;
  10054.     }
  10055.     if (!xfrxla) xxlate = 0;
  10056.     success = transmit(s,
  10057.                (char) (xxnowait ? '\0' : (char)xmitp),
  10058.                xxlate,
  10059.                xbinary,
  10060.                xxecho
  10061.                );
  10062.     return(success);
  10063.     }
  10064. #endif /* NOXMIT */
  10065.  
  10066. #ifndef NOFRILLS
  10067.     if (cx == XXTYP  || cx == XXCAT || cx == XXMORE ||
  10068.     cx == XXHEAD || cx == XXTAIL) {
  10069.     int paging = 0, havename = 0, head = 0, width = 0, count = 0;
  10070.     char pfxbuf[64], * prefix = NULL;
  10071.     char outfile[CKMAXPATH+1];
  10072.     struct FDB sf, sw;
  10073.     char * pat = NULL;
  10074.     int incs = 0, outcs = 0, cset = -1, number = 0;
  10075. #ifdef UNICODE
  10076.         char * tocs = "";
  10077.     extern int fileorder;
  10078. #ifdef OS2
  10079. #ifndef NOCSETS
  10080.     extern int tcsr, tcsl;
  10081. #endif /* NOCSETS */
  10082. #endif /* OS2 */
  10083. #endif /* UNICODE */
  10084.  
  10085.     outfile[0] = NUL;
  10086.  
  10087.     if (cx == XXMORE)
  10088.       paging = 1;
  10089.     else if (cx == XXCAT)
  10090.       paging = 0;
  10091.     else
  10092.       paging = (typ_page < 0) ? xaskmore : typ_page;
  10093.     if (paging < 0)
  10094.       paging = saveask;
  10095.  
  10096.     if (cx == XXHEAD) {
  10097.         head = 10;
  10098.         cx = XXTYP;
  10099.     } else if (cx == XXTAIL) {
  10100.         head = -10;
  10101.         cx = XXTYP;
  10102.     }
  10103.  
  10104. #ifdef IKSD
  10105.     if (inserver && !ENABLED(en_typ)) {
  10106.         printf("?Sorry, TYPE command disabled\n");
  10107.         return(-9);
  10108.     }
  10109. #endif /* IKSD */
  10110.  
  10111.     cmfdbi(&sw,            /* 2nd FDB - optional /PAGE switch */
  10112.            _CMKEY,            /* fcode */
  10113.            "Filename or switch",    /* hlpmsg */
  10114.            "",            /* default */
  10115.            "",            /* addtl string data */
  10116.            ntypetab,        /* addtl numeric data 1: tbl size */
  10117.            4,            /* addtl numeric data 2: 4 = cmswi */
  10118.            xxstring,        /* Processing function */
  10119.            typetab,            /* Keyword table */
  10120.            &sf            /* Pointer to next FDB */
  10121.            );
  10122.     cmfdbi(&sf,            /* 1st FDB - file to type */
  10123.            _CMIFI,            /* fcode */
  10124.            "",            /* hlpmsg */
  10125.            "",            /* default */
  10126.            "",            /* addtl string data */
  10127.            0,            /* addtl numeric data 1 */
  10128.            0,            /* addtl numeric data 2 */
  10129.            xxstring,
  10130.            NULL,
  10131.            NULL
  10132.            );
  10133.  
  10134.     while (!havename) {
  10135.         x = cmfdb(&sw);        /* Parse something */
  10136.         debug(F101,"type cmfdb","",x);
  10137.         debug(F101,"type cmresult.fcode","",cmresult.fcode);
  10138.         debug(F101,"type cmresult.nresult","",cmresult.nresult);
  10139.         if (x < 0) {            /* Error */
  10140.         if (x == -3) {
  10141.             x = -9;
  10142.             printf("?Filename required\n");
  10143.         }
  10144.         return(x);
  10145.         } else if (cmresult.fcode == _CMKEY) {
  10146.         char c; int getval;
  10147.         c = cmgbrk();
  10148.         getval = (c == ':' || c == '=');
  10149.         if (getval && !(cmgkwflgs() & CM_ARG)) {
  10150.             printf("?This switch does not take an argument\n");
  10151.             return(-9);
  10152.         }
  10153. #ifdef COMMENT
  10154.         if (!getval && (cmgkwflgs() & CM_ARG)) {
  10155.             printf("?This switch requires an argument\n");
  10156.             /* Not if it has a default! */
  10157.             return(-9);
  10158.         }
  10159. #endif /* COMMENT */
  10160.         switch (cmresult.nresult) {
  10161. #ifdef CK_TTGWSIZ
  10162.           case TYP_PAG:
  10163.             paging = 1;
  10164.             break;
  10165.  
  10166.           case TYP_NOP:
  10167.             paging = 0;
  10168.             break;
  10169. #endif /* CK_TTGWSIZ */
  10170.  
  10171.           case TYP_COU:
  10172.             paging = 0;
  10173.             count = 1;
  10174.             break;
  10175.  
  10176.           case TYP_HEA:
  10177.           case TYP_TAI:
  10178.             y = 10;
  10179.             if (getval)
  10180.               if ((x = cmnum("Number of lines",
  10181.                      "10",10,&y,xxstring)) < 0)
  10182.             return(x);
  10183.             head = (cmresult.nresult == TYP_TAI) ? -y : y;
  10184.             break;
  10185.  
  10186.           case TYP_WID:
  10187.             y = typ_wid > -1 ? typ_wid : cmd_cols;
  10188.             if (getval)
  10189.               if ((x = cmnum("Column at which to truncate",
  10190.                      ckitoa(y),10,&y,xxstring)) < 0)
  10191.             return(x);
  10192.             width = y;
  10193.             break;
  10194.  
  10195.           case TYP_PAT:
  10196.             if (!getval && (cmgkwflgs() & CM_ARG)) {
  10197.             printf("?This switch requires an argument\n");
  10198.             return(-9);
  10199.             }
  10200.             if ((x = cmfld("pattern","",&s,xxstring)) < 0)
  10201.               return(x);
  10202.             ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  10203.             pat = tmpbuf;
  10204.             break;
  10205.  
  10206.           case TYP_PFX:
  10207.             if (!getval && (cmgkwflgs() & CM_ARG)) {
  10208.             printf("?This switch requires an argument\n");
  10209.             return(-9);
  10210.             }
  10211.             if ((x = cmfld("prefix for each line","",&s,xxstring)) < 0)
  10212.               return(x);
  10213.             if ((int)strlen(s) > 63) {
  10214.             printf("?Too long - 63 max\n");
  10215.             return(-9);
  10216.             }
  10217.             ckstrncpy(pfxbuf,s,64);
  10218.             prefix = brstrip(pfxbuf);
  10219.             number = 0;
  10220.             break;
  10221.  
  10222.           case TYP_NUM:        /* /NUMBER */
  10223.             number = 1;
  10224.             prefix = NULL;
  10225.             break;
  10226.  
  10227. #ifdef UNICODE
  10228.           case TYP_XPA:        /* /TRANSPARENT */
  10229.             incs = 0;
  10230.             cset = 0;
  10231.             outcs = -1;
  10232.             break;
  10233.  
  10234.           case TYP_XIN:        /* /CHARACTER-SET: */
  10235.             if (!getval && (cmgkwflgs() & CM_ARG)) {
  10236.             printf("?This switch requires an argument\n");
  10237.             return(-9);
  10238.             }
  10239.             if ((incs = cmkey(fcstab,nfilc,
  10240.                       "character-set name","",xxstring)) < 0) {
  10241.             if (incs == -3)    /* Note: No default */
  10242.               incs = -2;
  10243.             return(incs);
  10244.             }
  10245.             cset = incs;
  10246.             break;
  10247.  
  10248.           case TYP_XUT:        /* /TRANSLATE-TO: */
  10249.             if (!getval && (cmgkwflgs() & CM_ARG)) {
  10250.             printf("?This switch requires an argument\n");
  10251.             return(-9);
  10252.             }
  10253. #ifdef OS2
  10254.             if (!inserver && !k95stdout) {
  10255.             tocs = "ucs2";
  10256.             } else {
  10257. #ifdef CKOUNI
  10258.             tocs = rlookup(txrtab,ntxrtab,tcsl);
  10259. #else /* CKOUNI */
  10260.             extern struct keytab ttcstab[];
  10261.             extern int ntxrtab;
  10262.             tocs = rlookup(ttcstab,ntermc,tocs);
  10263.             if (!tocs)
  10264.               tocs = getdcset();
  10265. #endif /* CKOUNI */
  10266.                     }
  10267. #else /* OS2 */
  10268.             tocs = getdcset();
  10269. #endif /* OS2 */
  10270.             if ((outcs = cmkey(fcstab,nfilc,
  10271.                        "character-set",tocs,xxstring)) < 0)
  10272.               return(outcs);
  10273.             break;
  10274. #endif /* UNICODE */
  10275.           case TYP_OUT:
  10276.             if ((x = cmofi("File for result lines","",
  10277.                    &s,xxstring)) < 0)
  10278.               return(x);
  10279.             ckstrncpy(outfile,s,CKMAXPATH);
  10280.             break;
  10281.         }
  10282.         } else if (cmresult.fcode == _CMIFI)
  10283.           havename = 1;
  10284.         else
  10285.           return(-2);
  10286.     }
  10287.     if (havename) {
  10288.         ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  10289.         y = cmresult.nresult;
  10290.     } else {
  10291.         if ((x = cmifi("Filename","",&s,&y,xxstring)) < 0) {
  10292.         if (x == -3) {
  10293.             printf("?Name of an existing file required\n");
  10294.             return(-9);
  10295.         } else return(x);
  10296.         }
  10297.         ckstrncpy(line,s,LINBUFSIZ);
  10298.     }
  10299.     if (y != 0) {
  10300.         printf("?A single file please\n");
  10301.         return(-9);
  10302.     }
  10303.     if ((y = cmcfm()) < 0)        /* Confirm the command */
  10304.       return(y);
  10305.  
  10306. #ifdef UNICODE
  10307.     fileorder = -1;
  10308.     if (cset < 0 && filepeek) {    /* If no charset switches given */
  10309.         int k, x = -1;
  10310.         k = scanfile(line,&x,nscanfile); /* Call file analyzer */
  10311.         debug(F111,"type scanfile",line,k);
  10312.         debug(F101,"type scanfile flag","",x);
  10313.         switch(k) {
  10314.           case FT_UTF8:        /* which can detect UTF-8... */
  10315.         cset = 0;
  10316.         incs = FC_UTF8;
  10317.         break;
  10318.           case FT_UCS2:        /* and UCS-2... */
  10319.         cset = 0;
  10320.         incs = FC_UCS2;
  10321.         fileorder = x;        /* even if there is no BOM. */
  10322.         debug(F101,"type fileorder","",fileorder);
  10323.         break;
  10324.         }
  10325.     }
  10326. #ifdef OS2
  10327.         if (cset < 0) {            /* If input charset still not known */
  10328. #ifdef CKOUNI
  10329.             tocs = rlookup(txrtab,ntxrtab,tcsl);
  10330. #else /* CKOUNI */
  10331.             extern struct keytab ttcstab[];
  10332.             extern int ntxrtab;
  10333.             tocs = rlookup(ttcstab,ntermc,incs);
  10334.             if (!tocs)
  10335.           tocs = getdcset();
  10336. #endif /* CKOUNI */
  10337.             incs = lookup(fcstab,tocs,nfilc,&x);
  10338.         }
  10339. #endif /* OS2 */
  10340.  
  10341.         if (outcs == 0 && incs != 0) {    /* Supply default target charset */
  10342.         int x = 0;            /* if switch not given. */
  10343.         tocs = getdcset();
  10344.         outcs = lookup(fcstab,tocs,nfilc,&x);
  10345.     }
  10346. #else  /* !UNICODE */
  10347.     if (cset < 0) incs = outcs = 0;
  10348. #endif /* UNICODE */
  10349.  
  10350.     if (outfile[0] && paging)    /* This combination makes no sense */
  10351.       paging = 0;            /* so turn off paging */
  10352.  
  10353.     if (count) paging = -1;
  10354.     debug(F111,"type",line,paging);
  10355.     s = outfile;
  10356.     success =
  10357.       dotype(line,paging,0,head,pat,width,prefix,incs,outcs,s,number);
  10358.     return(success);
  10359.     }
  10360. #endif /* NOFRILLS */
  10361.  
  10362. #ifndef NOCSETS
  10363.     if (cx == XXXLA) {            /* TRANSLATE file's charset */
  10364.     _PROTOTYP (int doxlate, ( void ) );
  10365.     return(doxlate());
  10366.     }
  10367. #endif /* NOCSETS */
  10368.  
  10369.     if (cx == XXVER) {            /* VERSION */
  10370.     int n = 0;
  10371.     extern char * ck_patch, * ck_s_test;
  10372. #ifdef COMMENT
  10373.     extern int hmtopline;
  10374. #endif /* COMMENT */
  10375.     if ((y = cmcfm()) < 0)
  10376.           return(y);
  10377.  
  10378.     printf("\n%s, for%s\n Numeric: %ld",versio,ckxsys,vernum);
  10379.     printf("\n");
  10380.     n = 3;
  10381.     if (*ck_s_test) {
  10382.         printf("\n THIS IS A TEST VERSION, NOT FOR PRODUCTION USE.\n");
  10383.         n += 2;
  10384.     }
  10385.     if (*ck_patch) {
  10386.         printf(" Patches: %s\n", ck_patch);
  10387.         n++;
  10388.     }
  10389. #ifdef OS2
  10390.     printf(" Type COPYRIGHT for copyright information.\n\n");
  10391.     shoreg();
  10392. #else
  10393. #ifdef COMMENT
  10394.     hmtopline = n+1;
  10395.     hmsga(copyright);
  10396.     hmtopline = 0;
  10397. #endif /* COMMENT */
  10398. #endif /* OS2 */
  10399.     return(success = 1);
  10400.     }
  10401.  
  10402.     if (cx == XXCPR) {            /* COPYRIGHT or LICENSE */
  10403.     if ((y = cmcfm()) < 0)
  10404.           return(y);
  10405.     hmsga(copyright);
  10406.     return(success = 1);
  10407.     }
  10408.  
  10409. #ifndef MAC                /* Only for multiuser systems */
  10410. #ifndef OS2
  10411. #ifndef NOFRILLS
  10412.     if (cx == XXWHO) {            /* WHO */
  10413.     char *wc;
  10414. #ifdef IKSD
  10415.     if (inserver && !ENABLED(en_who)) {
  10416.         printf("?Sorry, WHO command disabled\n");
  10417.         return(-9);
  10418.     }
  10419. #endif /* IKSD */
  10420. #ifdef datageneral
  10421.     if ((z = cmcfm()) < 0) return(z);
  10422.     if (nopush) {
  10423.         printf("?Sorry, who not allowed\n");
  10424.         return(success = 0);
  10425.     }
  10426.         xsystem(WHOCMD);
  10427. #else
  10428.     if ((y = cmtxt("user name","",&s,xxstring)) < 0) return(y);
  10429.         if (nopush) {
  10430.         printf("?Sorry, WHO command disabled\n");
  10431.         return(success = 0);
  10432.     }
  10433.     if (!(wc = getenv("CK_WHO"))) wc = WHOCMD;
  10434.     if (wc)
  10435.       if ((int) strlen(wc) > 0) {
  10436.           ckmakmsg(line,LINBUFSIZ,wc," ",s,NULL);
  10437.           xsystem(line);
  10438.       }
  10439. #endif /* datageneral */
  10440.     return(success = 1);
  10441.     }
  10442. #endif /* NOFRILLS */
  10443. #endif /* OS2 */
  10444. #endif /* MAC */
  10445.  
  10446. #ifndef NOFRILLS
  10447.     if (cx == XXWRI || cx == XXWRL || cx == XXWRBL) { /* WRITE */
  10448.     if ((x = cmkey(writab,nwri,"to file or log","",xxstring)) < 0) {
  10449.         if (x == -3) printf("?Write to what?\n");
  10450.         return(x);
  10451.     }
  10452.     if ((y = cmtxt("text","",&s,xxstring)) < 0) return(y);
  10453.     s = brstrip(s);
  10454.     switch (x) {
  10455.       case LOGD: y = ZDFILE; break;
  10456.       case LOGP: y = ZPFILE; break;
  10457. #ifndef NOLOCAL
  10458.       case LOGS: y = ZSFILE; break;
  10459. #endif /* NOLOCAL */
  10460.       case LOGT: y = ZTFILE; break;
  10461. #ifndef NOSPL
  10462.       case LOGW: y = ZWFILE; break;
  10463. #endif /* NOSPL */
  10464.       case LOGX:            /* SCREEN (stdout) */
  10465.       case LOGE:            /* ERROR  (stderr) */
  10466.         if (x == LOGE) {
  10467.         debug(F110,
  10468.               (cx == XXWRL) ? "WRITELN ERROR" : "WRITE ERROR", s,0);
  10469.         fprintf(stderr,"%s%s",s,(cx == XXWRL) ? "\n" : "");
  10470.         } else {
  10471.         debug(F110,
  10472.               (cx == XXWRL) ? "WRITELN SCREEN" : "WRITE SCREEN", s,0);
  10473.         printf("%s%s",s,(cx == XXWRL) ? "\n" : "");
  10474.         }
  10475.         return(success = 1);
  10476.       default: return(-2);
  10477.     }
  10478.     if (chkfn(y) > 0) {
  10479.         x = (cx == XXWRI) ? zsout(y,s) : zsoutl(y,s);
  10480.         if (x < 0) printf("?Write error\n");
  10481.     } else {
  10482.         x = -1;
  10483.         printf("?File or log not open\n");
  10484.     }
  10485.     return(success = (x == 0) ? 1 : 0);
  10486.     }
  10487. #endif /* NOFRILLS */
  10488.  
  10489. #ifndef NOXFER
  10490.     if (cx == XXASC || cx == XXBIN) {
  10491.     if ((x = cmcfm()) < 0) return(x);
  10492. #ifdef NEWFTP
  10493.     if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
  10494.       return(success = doftptyp((cx == XXASC) ? 0 : 1));
  10495. #endif /* NEWFTP */
  10496.     binary = (cx == XXASC) ? XYFT_T : XYFT_B;
  10497.     return(success = 1);
  10498.     }
  10499. #endif /* NOXFER */
  10500.  
  10501.     if (cx == XXCLS) {
  10502.     if ((x = cmcfm()) < 0) return(x);
  10503.     y = ck_cls();
  10504.     return(success = (y > -1) ? 1 : 0);
  10505.     }
  10506.  
  10507. #ifdef CK_MKDIR
  10508.     if (cx == XXMKDIR) {
  10509.     char *p;
  10510. #ifdef IKSD
  10511.     if (inserver && !ENABLED(en_mkd)) {
  10512.         printf("?Sorry, directory creation is disabled\n");
  10513.         return(-9);
  10514.     }
  10515. #endif /* IKSD */
  10516.     if ((x = cmfld("Name for new directory","",&s,xxstring)) < 0) {
  10517.         if (x != -3) {
  10518.         return(x);
  10519.         } else {
  10520.         printf("?Directory name required\n");
  10521.         return(-9);
  10522.         }
  10523.     }
  10524.     ckstrncpy(line,s,LINBUFSIZ);
  10525.     s = line;
  10526.     if ((x = cmcfm()) < 0) return(x);
  10527.     s = brstrip(s);
  10528.     bgchk();            /* Set msgflg */
  10529.     x = ckmkdir(0,s,&p,msgflg,0);
  10530. #ifdef COMMENT
  10531.     if (msgflg && x == 0)
  10532.       printf("?Directory already exists\n");
  10533. #endif /* COMMENT */
  10534.     return(success = (x < 0) ? 0 : 1);
  10535.     }
  10536.     if (cx == XXRMDIR) {        /* RMDIR */
  10537.     char *p;
  10538. #ifdef IKSD
  10539.     if (inserver && !ENABLED(en_rmd)) {
  10540.         printf("?Sorry, directory removal is disabled\n");
  10541.         return(-9);
  10542.     }
  10543. #endif /* IKSD */
  10544.     if ((x = cmdir("Name of directory to be removed","",&s,xxstring)) < 0)
  10545.       return(x);
  10546.     ckstrncpy(line,s,LINBUFSIZ);
  10547.     s = line;
  10548.     if ((x = cmcfm()) < 0) return(x);
  10549.     s = brstrip(s);
  10550.     x = ckmkdir(1,s,&p,msgflg,0);
  10551.     return(success = (x < 0) ? 0 : 1);
  10552.     }
  10553. #endif /* CK_MKDIR */
  10554.  
  10555. #ifdef TNCODE
  10556.     if (cx == XXTELOP)
  10557.       return(dotelopt());
  10558. #endif /* TNCODE */
  10559.  
  10560. #ifndef NOPUSH
  10561.     if (cx == XXNPSH) {
  10562.     if ((z = cmcfm()) < 0) return(z);
  10563.         nopush = 1;
  10564. #ifndef NOSERVER
  10565.         en_hos = 0;
  10566. #endif /* NOSERVER */
  10567. #ifdef PIPESEND
  10568.     usepipes = 0;
  10569. #endif /* PIPESEND */
  10570.         return(success = 1);
  10571.     }
  10572. #endif /* NOPUSH */
  10573.  
  10574. #ifndef NOSPL
  10575.     if (cx == XXLOCAL)            /* LOCAL variable declarations */
  10576.       return(success = dolocal());
  10577. #endif /* NOSPL */
  10578.  
  10579.     if (cx == XXKERMI) {        /* The KERMIT command */
  10580.     char * list[65];
  10581.     extern char **xargv;
  10582.     extern int xargc;
  10583.     int i;
  10584.     if ((y = cmtxt("kermit command-line arguments, -h for help",
  10585.                "",&s,xxstring)) < 0)
  10586.       return(y);
  10587.     ckstrncpy(line,"kermit ",LINBUFSIZ);
  10588.     ckstrncat(line,s,LINBUFSIZ-8);
  10589.     xwords(line,64,list,0);
  10590.     for (i = 1; i < 64; i++) {
  10591.         if (!list[i])
  10592.           break;
  10593.     }
  10594.     i--;
  10595.     xargc = i;
  10596.     xargv = list;
  10597.     xargv++;
  10598.     sstate = cmdlin();
  10599.     if (sstate) {
  10600.         extern int justone;
  10601.         debug(F000,"KERMIT sstate","",sstate);
  10602.         justone = 1;        /* Force return to command mode */
  10603.         proto();            /* after protocol */
  10604.         return(success);
  10605.     } else {
  10606.         debug(F101,"KERMIT sstate","",sstate);
  10607.         return(success = 1);    /* Not exactly right, but... */
  10608.     }
  10609.     }
  10610.     if (cx == XXDATE) {            /* DATE command */
  10611.     extern char cmdatebuf[], * cmdatemsg;
  10612.  
  10613. #ifndef COMMENT
  10614.     char * dp;
  10615.     if ((y = cmtxt("date and/or time, or carriage return for current",
  10616.                "",&s,xxstring)) < 0)
  10617.       return(y);
  10618.     s = brstrip(s);
  10619.     dp = cmcvtdate(s,1);
  10620.     if (!dp) {
  10621.         printf("?%s\n",cmdatemsg);
  10622.         success = 0;
  10623.     } else {
  10624.         printf("%s\n",dp);
  10625.         success = 1;
  10626.     }    
  10627. #else
  10628.     /* This works fine but messes up my "dates" torture-test script */
  10629.  
  10630.     if ((x = cmdate("Date and/or time, or carriage return for current",
  10631.             "",&s,0,xxstring)) < 0) {
  10632.         return(x);
  10633.     } else {
  10634.         printf("%s\n",cmdatebuf);
  10635.         success = 1;
  10636.     }
  10637. #endif /* COMMENT */
  10638.     return(success);
  10639.     }
  10640. #ifndef NOPUSH
  10641. #ifndef NOFRILLS
  10642.     if (cx == XXEDIT)
  10643.       return(doedit());
  10644. #endif /* NOFRILLS */
  10645. #endif /* NOPUSH */
  10646.  
  10647. #ifdef BROWSER                /* Defined only ifndef NOPUSH */
  10648.     if (cx == XXBROWS)
  10649.       return(dobrowse());
  10650. #endif /* BROWSER */
  10651.  
  10652. #ifdef CK_TAPI
  10653.     if (cx == XXTAPI) {            /* Microsoft TAPI */
  10654.     return (success = dotapi());
  10655.     }
  10656. #endif /* CK_TAPI */
  10657.  
  10658. #ifndef NOXFER
  10659.     if (cx == XXWHERE) {
  10660.     extern char * rfspec, * sfspec, * srfspec, * rrfspec;
  10661.     if ((x = cmcfm()) < 0) return(x);
  10662.     printf("\nFile most recently...\n\n");
  10663.     printf("  Sent:       %s\n",   sfspec ? sfspec : "(none)");
  10664.     if (sfspec && srfspec) {
  10665.         printf("  Stored as:  %s\n",   srfspec);
  10666.         printf("\n");
  10667.     }
  10668.     printf("  Received:   %s\n",   rrfspec ? rrfspec : "(none)");
  10669.     if (rfspec && rrfspec)
  10670.     printf("  Stored as:  %s\n",   rfspec);
  10671.     printf(
  10672. "\nIf the full path is not shown, then the file is probably in your current\n"
  10673.            );
  10674.     printf(
  10675. "directory or your download directory (if any - SHOW FILE to find out).\n\n"
  10676.            );
  10677.     return(success = 1);
  10678.     }
  10679. #endif /* NOXFER */
  10680.  
  10681. #ifdef CK_RECALL
  10682.     if (cx == XXREDO)
  10683.       return(doredo());
  10684. #endif /* CK_RECALL */
  10685.  
  10686. #ifdef CKROOT
  10687.     if (cx == XXCHRT)            /* Change Kermit's root directory */
  10688.       return(dochroot());
  10689. #endif /* CKROOT */
  10690.  
  10691. #ifdef CK_KERBEROS
  10692.     if (cx == XXAUTH) {            /* KERBEROS */
  10693.     x = cp_auth();            /* Parse it */
  10694. #ifdef IKSD
  10695.         if (inserver) {
  10696.             printf("?Command disabled in IKSD.\r\n");
  10697.             return(success = 0);
  10698.         }
  10699. #endif /* IKSD */
  10700.     if (x < 0)            /* Pass parse errors back */
  10701.       return(x);
  10702.     return(success = doauth(cx));
  10703.     }
  10704. #endif /* CK_KERBEROS */
  10705.  
  10706. #ifndef NOLOCAL
  10707.     if (cx == XXTERM) {
  10708.     return(settrmtyp());
  10709.     }
  10710. #endif /* NOLOCAL */
  10711.  
  10712.     if (cx == XXSTATUS) {
  10713.     if ((x = cmcfm()) < 0) return(x);
  10714.     printf( " %s\n", success ? "SUCCESS" : "FAILURE" );
  10715.     return(0);            /* Don't change it */
  10716.     }
  10717.  
  10718.     if (cx == XXFAIL) {
  10719.     if ((x = cmcfm()) < 0) return(x);
  10720.     return(success = 0);
  10721.     }
  10722.  
  10723.     if (cx == XXSUCC) {
  10724.     if ((x = cmcfm()) < 0) return(x);
  10725.     return(success = 1);
  10726.     }
  10727.  
  10728.     if (cx == XXNLCL) {
  10729.     extern int nolocal;
  10730.     if ((x = cmcfm()) < 0) return(x);
  10731.     nolocal = 1;
  10732.     return(success = 1);
  10733.     }
  10734.  
  10735. #ifndef NOXFER
  10736.     if (cx == XXRASG)            /* Shortcuts for REMOTE commands */
  10737.       return(dormt(XZASG));
  10738.     if (cx == XXRCWD)
  10739.       return(dormt(XZCWD));
  10740.     if (cx == XXRCPY)
  10741.       return(dormt(XZCPY));
  10742.     if (cx == XXRDEL)
  10743.       return(dormt(XZDEL));
  10744.     if (cx == XXRDIR)
  10745.       return(dormt(XZDIR));
  10746.     if (cx == XXRXIT)
  10747.       return(dormt(XZXIT));
  10748.     if (cx == XXRHLP)
  10749.       return(dormt(XZHLP));
  10750.     if (cx == XXRHOS)
  10751.       return(dormt(XZHOS));
  10752.     if (cx == XXRKER)
  10753.       return(dormt(XZKER));
  10754.     if (cx == XXRPWD)
  10755.       return(dormt(XZPWD));
  10756.     if (cx == XXRQUE)
  10757.       return(dormt(XZQUE));
  10758.     if (cx == XXRREN)
  10759.       return(dormt(XZREN));
  10760.     if (cx == XXRMKD)
  10761.       return(dormt(XZMKD));
  10762.     if (cx == XXRRMD)
  10763.       return(dormt(XZRMD));
  10764.     if (cx == XXRSET)
  10765.       return(dormt(XZSET));
  10766.     if (cx == XXRSPA)
  10767.       return(dormt(XZSPA));
  10768.     if (cx == XXRTYP)
  10769.       return(dormt(XZTYP));
  10770.     if (cx == XXRWHO)
  10771.       return(dormt(XZWHO));
  10772.     if (cx == XXRCDUP)
  10773.       return(dormt(XZCDU));
  10774. #endif /* NOXFER */
  10775.  
  10776.     if (cx == XXRESET) {        /* RESET */
  10777.     if ((x = cmcfm()) < 0)
  10778.       return(x);
  10779.     doclean(0);            /* Close all files */
  10780.     return(success = 1);
  10781.     }
  10782.  
  10783. #ifndef NOXFER
  10784. #ifndef NOCSETS
  10785.     if (cx == XXASSOC)            /* ASSOCIATE */
  10786.       return(doassoc());
  10787. #endif /* NOCSETS */
  10788. #endif /* NOXFER */
  10789.  
  10790. #ifndef NOSPL
  10791.     if (cx == XXSHIFT) {        /* SHIFT */
  10792.     if ((y = cmnum("Number of arguments to shift","1",10,&x,xxstring)) < 0)
  10793.       return(y);
  10794.     if ((z = cmcfm()) < 0)
  10795.       return(z);
  10796.     return(success = doshift(x));
  10797.     }
  10798. #endif /* NOSPL */
  10799.  
  10800. #ifndef NOHELP
  10801.     if (cx == XXMAN)
  10802.       return(domanual());
  10803. #endif /* NOHELP */
  10804.  
  10805. #ifndef NOSPL
  10806.     if (cx == XXSORT)            /* SORT an array */
  10807.       return(dosort());
  10808. #endif /* NOSPL */
  10809.  
  10810.     if (cx == XXPURGE) {
  10811. #ifdef IKSD
  10812.     if (inserver && (!ENABLED(en_del)
  10813. #ifdef CK_LOGIN
  10814.                           || isguest
  10815. #endif /* CK_LOGIN */
  10816.              )) {
  10817.         printf("?Sorry, DELETE is disabled\n");
  10818.         return(-9);
  10819.     }
  10820. #endif /* IKSD */
  10821. #ifdef CK_APC
  10822.     if ((apcactive == APC_LOCAL) ||
  10823.         ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
  10824.       return(success = 0);
  10825. #endif /* CK_APC */
  10826. #ifdef CKPURGE
  10827.         return(dopurge());
  10828. #else
  10829. #ifdef VMS
  10830.     if ((x = cmtxt("optional switches followed by filespec",
  10831.                "",&s,xxstring)) < 0)
  10832.       return(x);
  10833.     if (nopush) {
  10834.         printf("?Sorry, DCL access is disabled\n");
  10835.         return(-9);
  10836.     }
  10837.     ckstrncpy(line,s,LINBUFSIZ);
  10838.     s = line;
  10839.     x = mlook(mactab,"purge",nmac);
  10840.     return(success = dodo(x,s,cmdstk[cmdlvl].ccflgs));
  10841. #else
  10842.     return(-2);
  10843. #endif /* VMS */
  10844. #endif /* CKPURGE */
  10845.     }
  10846.  
  10847. #ifndef NOSPL
  10848.     if (cx == XXFAST) {
  10849.     if ((x = cmcfm()) < 0) return(x);
  10850.     x = mlook(mactab,"fast",nmac);
  10851.     return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
  10852.     }
  10853.     if (cx == XXCAU) {
  10854.     if ((x = cmcfm()) < 0) return(x);
  10855.     x = mlook(mactab,"cautious",nmac);
  10856.     return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
  10857.     }
  10858.     if (cx == XXROB) {
  10859.     if ((x = cmcfm()) < 0) return(x);
  10860.     x = mlook(mactab,"robust",nmac);
  10861.     return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
  10862.     }
  10863. #endif /* NOSPL */
  10864.  
  10865.     if (cx == XXSCRN) {            /* SCREEN */
  10866.     int row, col;
  10867.     if ((x = cmkey(scntab, nscntab,"screen action","", xxstring)) < 0)
  10868.       return(x);
  10869.     switch (x) {            /* MOVE-TO (cursor position) */
  10870.       case SCN_MOV:
  10871.         if ((y = cmnum("Row (1-based)","",10,&z,xxstring)) < 0)
  10872.           return(y);
  10873.         row = z;
  10874.         y = cmnum("Column (1-based)","1",10,&z,xxstring);
  10875.         if (y < 0)
  10876.           return(y);
  10877.         col = z;
  10878.         if ((y = cmcfm()) < 0)
  10879.           return(y);
  10880.         if (row < 0 || col < 0) {
  10881.         printf("?Row and Column must be 1 or greater\n");
  10882.         return(-9);
  10883.         }
  10884.         if (cmd_rows > 0 && row > cmd_rows)
  10885.           row = cmd_rows;
  10886.         if (cmd_cols > 0 && col > cmd_cols)
  10887.           col = cmd_cols;
  10888.         y = ck_curpos(row,col);
  10889.         return(success = (y > -1) ? 1 : 0);
  10890.  
  10891.       case SCN_CLR:            /* CLEAR */
  10892.         if ((y = cmcfm()) < 0)
  10893.           return(y);
  10894.         debug(F100,"screen calling ck_cls()","",0);
  10895.         y = ck_cls();
  10896.         return(success = (y > -1) ? 1 : 0);
  10897.  
  10898.       case SCN_CLE:            /* CLEOL */
  10899.         if ((y = cmcfm()) < 0)
  10900.           return(y);
  10901.         y = ck_cleol();
  10902.         return(success = (y > -1) ? 1 : 0);
  10903.     }
  10904.     }
  10905.  
  10906. #ifndef NOHTTP
  10907. #ifdef TCPSOCKET
  10908.     if (cx == XXHTTP)
  10909.       return(dohttp());
  10910. #endif /* TCPSOCKET */
  10911. #endif /* NOHTTP */
  10912.  
  10913. #ifndef NOSPL
  10914.     if (cx == XXARRAY) {        /* ARRAY */
  10915. #ifndef NOSHOW
  10916.     extern int showarray();
  10917. #endif /* NOSHOW */
  10918.     if ((x = cmkey(arraytab, narraytab,"Array operation","",xxstring)) < 0)
  10919.       return(x);
  10920.     switch (x) {
  10921.       case ARR_DCL:
  10922.         return(dodcl(XXDCL));
  10923.       case ARR_SRT:
  10924.         return(dosort());
  10925. #ifndef NOSHOW
  10926.       case ARR_SHO:
  10927.         return(showarray());
  10928. #endif /* NOSHOW */
  10929.       case ARR_CPY:
  10930.         return(copyarray());
  10931.       case ARR_SET:
  10932.       case ARR_CLR:
  10933.         return(clrarray(x));
  10934.       case ARR_DST:
  10935.         return(unarray());
  10936.       case ARR_RSZ:
  10937.         return(rszarray());
  10938.       case ARR_EQU:
  10939.         return(linkarray());
  10940.  
  10941.       default:
  10942.         printf("?Sorry, not implemented yet - \"%s\"\n",cmdbuf);
  10943.         return(-9);
  10944.     }
  10945.     }
  10946.     if (cx == XXTRACE)
  10947.       return(dotrace());
  10948. #endif /* NOSPL */
  10949.  
  10950. #ifdef CK_PERMS
  10951. #ifdef UNIX
  10952.     if (cx == XXCHMOD)
  10953.       return(douchmod());        /* Do Unix chmod */
  10954. #endif /* UNIX */
  10955. #endif /* CK_PERMS */
  10956.  
  10957.     if (cx == XXPROMP)
  10958.       return(doprompt());
  10959.  
  10960.     if (cx == XXGREP)
  10961.       return(dogrep());
  10962.  
  10963.     if (cx == XXDEBUG) {        /* DEBUG */
  10964. #ifndef DEBUG
  10965.     int dummy = 0;
  10966.     return(seton(&dummy));
  10967. #else
  10968.     return(seton(&deblog));
  10969. #endif /* DEBUG */
  10970.     }
  10971.  
  10972. #ifdef CKLEARN
  10973.     if (cx == XXLEARN) {        /* LEARN */
  10974.     struct FDB of, sw, cm;
  10975.     int closing = 0, off = 0, on = 0, confirmed = 0;
  10976.     char c;
  10977.  
  10978.     cmfdbi(&sw,            /* 2nd FDB - optional /PAGE switch */
  10979.            _CMKEY,            /* fcode */
  10980.            "Script file name, or switch", /* hlpmsg */
  10981.            "",            /* default */
  10982.            "",            /* addtl string data */
  10983.            3,            /* addtl numeric data 1: tbl size */
  10984.            4,            /* addtl numeric data 2: 4 = cmswi */
  10985.            xxstring,        /* Processing function */
  10986.            learnswi,        /* Keyword table */
  10987.            &of            /* Pointer to next FDB */
  10988.            );
  10989.     cmfdbi(&of,_CMOFI,"","","",0,0,xxstring,NULL,&cm);
  10990.     cmfdbi(&cm,_CMCFM,"","","",0,0,NULL,NULL,NULL);
  10991.     line[0] = NUL;
  10992.  
  10993.     while (!confirmed) {
  10994.         x = cmfdb(&sw);        /* Parse something */
  10995.         if (x < 0)
  10996.           return(x);
  10997.         switch (cmresult.fcode) {    /* What was it? */
  10998.           case _CMOFI:        /* Output file name */
  10999.         ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  11000.         break;
  11001.           case _CMKEY:        /* Switch */
  11002.         c = cmgbrk();
  11003.         if ((c == ':' || c == '=') && !(cmgkwflgs() & CM_ARG)) {
  11004.             printf("?This switch does not take an argument\n");
  11005.             return(-9);
  11006.         }
  11007.         switch (cmresult.nresult) {
  11008.           case 2:        /* /CLOSE */
  11009.             closing = 1;    /* Fall thru on purpose */
  11010.           case 0:        /* /OFF */
  11011.             off = 1;
  11012.             on = 0;
  11013.             break;
  11014.           case 1:        /* /ON */
  11015.             on = 1;
  11016.             off = 0;
  11017.             break;
  11018.         }
  11019.         break;
  11020.           case _CMCFM:        /* Confirmation */
  11021.         confirmed++;
  11022.         break;
  11023.         }
  11024.     }
  11025.     if (closing) {
  11026.         if (learnfp) {
  11027.         fclose(learnfp);
  11028.         learnfp = NULL;
  11029.         }
  11030.         makestr(&learnfile,NULL);
  11031.     }
  11032.     if (line[0]) {
  11033.         if (!on && !off)
  11034.           on = 1;
  11035.         if (learnfp) {
  11036.         fclose(learnfp);
  11037.         learnfp = NULL;
  11038.         }
  11039.         makestr(&learnfile,line);
  11040.         if (learnfile) {
  11041.         char * modes = "w";
  11042.         learnfp = fopen(learnfile,modes);
  11043.         if (!learnfp) {
  11044.             debug(F110,"LEARN file open error",learnfile,0);
  11045.             perror(learnfile);
  11046.             return(-9);
  11047.         } else {
  11048. #ifdef ZFNQFP
  11049.             if (zfnqfp(learnfile,TMPBUFSIZ,tmpbuf))
  11050.               makestr(&learnfile,tmpbuf);
  11051. #endif /* ZFNQFP */
  11052.             debug(F110,"LEARN file open ok",learnfile,0);
  11053.             if (!quiet) {
  11054.             printf("Recording to %s...\n\n",learnfile);
  11055.             printf(
  11056. " WARNING: If you type your password during script recording, it will appear\n\
  11057.  in the file.  Be sure to edit it or take other appropriate precautions.\n\n"
  11058.                    );
  11059.             }
  11060.             fputs(  "; Scriptfile: ",learnfp);
  11061.             fputs(learnfile,learnfp);
  11062.             fputs("\n; Directory:  ",learnfp);
  11063.             fputs(zgtdir(),learnfp);
  11064.             fputs("\n; Recorded:   ",learnfp);
  11065.             fputs(ckdate(),learnfp);
  11066.             fputs("\n",learnfp);
  11067.         }
  11068.         }
  11069.     }
  11070.     if (on) {
  11071.         learning = 1;
  11072.     } else if (off) {
  11073.         learning = 0;
  11074.     }
  11075.     debug(F101,"LEARN learning","",learning);
  11076.     return(success = 1);
  11077.     }
  11078. #endif /* CKLEARN */
  11079.  
  11080.     if (cx == XXNOTAV) {        /* Command in table not available */
  11081.     ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ);
  11082.     if ((x = cmtxt("Rest of command","",&s,NULL)) < 0)
  11083.       return(x);
  11084.     printf("Sorry, \"%s\" not configured in this version of Kermit.\n",
  11085.            tmpbuf
  11086.            );
  11087.     return(success = 0);
  11088.     }
  11089.     return(-2);                /* None of the above */
  11090.  
  11091. } /* end of docmd() */
  11092.  
  11093. #endif /* NOICP */
  11094.