home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / old / ckermit70 / ckuusr.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  238KB  |  9,171 lines

  1. #include "ckcsym.h"
  2. char *userv = "User Interface 7.0.222, 1 Jan 2000";
  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, 2000,
  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. int g_fncact = -1;            /* Needed for NOICP builds */
  77. int noinit = 0;                /* Flag for skipping init file */
  78.  
  79. #ifndef NOICP
  80. /* Includes */
  81.  
  82. #include "ckcdeb.h"
  83. #include "ckcasc.h"
  84. #include "ckcker.h"
  85. #include "ckcnet.h"            /* Network symbols */
  86. #include "ckuusr.h"
  87. #include "ckcxla.h"
  88.  
  89. #ifdef OS2
  90. #ifndef NT
  91. #define INCL_NOPM
  92. #define INCL_VIO            /* Needed for ckocon.h */
  93. #include <os2.h>
  94. #undef COMMENT
  95. #else
  96. #define APIRET ULONG
  97. #include <windows.h>
  98. #include <tapi.h>
  99. #include "cknwin.h"
  100. #include "ckntap.h"            /* CK_TAPI definition */
  101. #endif /* NT */
  102. #include "ckowin.h"
  103. #include "ckocon.h"
  104. extern int tcp_avail;
  105. extern bool viewonly;
  106. extern tt_status;
  107. int display_demo = 1;
  108. #endif /* OS2 */
  109.  
  110. int optlines = 0;
  111. int didsetlin = 0;
  112.  
  113. #ifdef VMS
  114. extern int batch;
  115. #endif /* VMS */
  116.  
  117. #ifdef datageneral
  118. #include <packets:common.h>
  119. #define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd)
  120. #endif /* datageneral */
  121.  
  122. extern int hints, cmflgs, whyclosed;
  123.  
  124. #ifndef NOCSETS
  125. extern int nfilc;
  126. extern struct keytab fcstab[];
  127. extern int fcharset;
  128. #endif /* NOCSETS */
  129.  
  130. char * g_pswd = NULL;
  131. int g_pcpt = -1;
  132. int g_pflg = -1;
  133.  
  134. extern int cmd_rows, cmd_cols;
  135.  
  136. #ifndef NOXFER
  137. extern int atcapr, atdiso, nfils, moving, protocol, sendmode, epktflg, size,
  138.   sndsrc, server, displa, inserver, fncnv, fnspath, fnrpath, xfermode, urpsiz,
  139.   spsizf, spsiz, spsizr, spmax, wslotr, prefixing, fncact;
  140.  
  141. #ifdef CK_LOGIN
  142. extern int isguest;
  143. #endif /* CK_LOGIN */
  144.  
  145. extern long sendstart;
  146.  
  147. extern char *cmarg, *cmarg2, **cmlist, * dftty;
  148.  
  149. extern struct keytab fntab[]; extern int nfntab;
  150. extern struct ck_p ptab[NPROTOS];
  151.  
  152. int sndcmd = 0;        /* Last command was a SEND-class command. */
  153.  
  154. int g_xfermode = -1;
  155. int g_proto  = -1;
  156. int g_urpsiz = -1;
  157. int g_spsizf = -1;
  158. int g_spsiz  = -1;
  159. int g_spsizr = -1;
  160. int g_spmax  = -1;
  161. int g_wslotr = -1;
  162. int g_prefixing = -1;
  163. int g_fncnv  = -1;
  164. int g_fnspath = -1;
  165. int g_fnrpath = -1;
  166. int g_fnact  = -1;
  167. int g_displa = -1;
  168. int g_spath  = -1;
  169. int g_rpath  = -1;
  170. char * g_sfilter = NULL;
  171. char * g_rfilter = NULL;
  172.  
  173. #ifdef PATTERNS
  174. extern int patterns;
  175. int g_patterns = -1;
  176. #endif /* PATTERNS */
  177. int g_skipbup = -1;
  178.  
  179. #ifdef PIPESEND
  180. extern int usepipes, pipesend;
  181. extern char * sndfilter, * rcvfilter;
  182. #endif /* PIPESEND */
  183.  
  184. #ifdef PATTERNS
  185. extern char *txtpatterns[], *binpatterns[];
  186. #endif /* PATTERNS */
  187.  
  188. #ifndef NOSPL
  189. extern int sndxlo, sndxhi, sndxin;
  190. #endif /* NOSPL */
  191.  
  192. extern char fspec[];            /* Most recent filespec */
  193. extern int fspeclen;            /* Length of fspec[] buffer */
  194.  
  195. #ifndef NOFRILLS
  196. extern int rmailf;            /* MAIL command items */
  197. extern char optbuf[];
  198. #endif /* NOFRILLS */
  199.  
  200. extern int
  201.   en_cpy, en_cwd, en_del, en_dir, en_fin, en_get, en_bye, en_mai, en_pri,
  202.   en_hos, en_ren, en_sen, en_spa, en_set, en_typ, en_who, en_ret, en_xit,
  203.   en_mkd, en_rmd, en_asg;
  204.  
  205. #ifndef NOMSEND                /* Multiple SEND */
  206. extern char *msfiles[];
  207. int filesinlist = 0;            /* And ADD ... */
  208. extern struct filelist * filehead;
  209. extern struct filelist * filetail;
  210. extern struct filelist * filenext;
  211. extern int addlist;
  212. #endif /* NOMSEND */
  213.  
  214. static struct keytab addtab[] = {
  215. #ifdef PATTERNS
  216.     "binary-patterns", ADD_BIN, 0,
  217. #endif /* PATTERNS */
  218. #ifndef NOMSEND
  219.     "send-list", ADD_SND, 0,
  220. #endif /* NOMSEND */
  221. #ifdef PATTERNS
  222.     "text-patterns", ADD_TXT, 0,
  223. #endif /* PATTERNS */
  224.     "", 0, 0
  225. };
  226. static int naddtab = sizeof(addtab)/sizeof(struct keytab) - 1;
  227.  
  228. #ifndef NOCSETS
  229. struct keytab assoctab[] = {
  230.     "file-character-set",     ASSOC_FC, 0,
  231.     "transfer-character-set", ASSOC_TC, 0,
  232.     "xfer-character-set",     ASSOC_TC, CM_INV
  233. };
  234. static int nassoc = sizeof(assoctab)/sizeof(struct keytab);
  235. extern int afcset[MAXFCSETS+1];        /* Character-set associations */
  236. extern int axcset[MAXTCSETS+1];
  237. #endif /* NOCSETS */
  238.  
  239. #ifndef ADDCMD
  240. #ifndef NOMSEND
  241. #define ADDCMD
  242. #endif /* NOMSEND */
  243. #ifndef ADDCMD
  244. #ifdef PATTERNS
  245. #define ADDCMD
  246. #endif /* PATTERNS */
  247. #endif /* ADDCMD */
  248. #endif /* ADDCMD */
  249. #endif /* NOXFER */
  250.  
  251. /* External Kermit Variables, see ckmain.c for description. */
  252.  
  253. extern xx_strp xxstring;
  254. extern long xvernum;
  255.  
  256. extern int local, xitsta, binary, msgflg, escape, duplex, quiet, tlevel,
  257.   pflag, zincnt, ckxech, carrier, what, nopush, haveline, bye_active;
  258. #ifdef TNCODE
  259. extern int debses;
  260. extern char tn_msg[];
  261. #endif /* TNCODE */
  262.  
  263. int sleepcan = 1;
  264. int g_binary = -1;
  265. int g_recursive = -1;
  266. int g_matchdot = -1;
  267.  
  268. extern long vernum;
  269. extern char *versio, *copyright[];
  270. extern char *ckxsys;
  271. #ifndef NOHELP
  272. extern char *introtxt[];
  273. extern char *newstxt[];
  274. #endif /* NOHELP */
  275.  
  276. #ifndef OS2
  277. #ifndef UNIX
  278. extern char *PWDCMD;
  279. #endif /* UNIX */
  280. extern char *WHOCMD;
  281. #endif /* OS2 */
  282.  
  283. extern char ttname[];
  284.  
  285. extern CHAR sstate;
  286.  
  287. extern int network;            /* Have active network connection */
  288. #ifdef NETCONN
  289. extern int nettype,            /* Type of network */
  290.   ttnproto;                /* Network Protocol */
  291. #endif /* NETCONN */
  292.  
  293. #ifndef NODIAL
  294. extern int dialsta, dialatmo, dialcon, dialcq; /* DIAL status, etc. */
  295. #endif /* NODIAL */
  296.  
  297. #ifdef CK_APC
  298. extern int apcactive, apcstatus;
  299. #endif /* CK_APC */
  300.  
  301. #ifndef NOPUSH
  302. #ifndef NOFRILLS
  303. extern char editor[];
  304. extern char editopts[];
  305. extern char editfile[];
  306. #endif /* NOFRILLS */
  307. #endif /* NOPUSH */
  308.  
  309. #ifdef BROWSER
  310. extern char browser[];            /* Web browser application */
  311. extern char browsopts[];        /* Web browser options */
  312. extern char browsurl[];            /* Most recent URL */
  313. char ftpapp[CKMAXPATH+1] = { NUL, NUL }; /* ftp executable */
  314. char ftpopts[128] = { NUL, NUL };    /* ftp command-line options */
  315. #endif /* BROWSER */
  316.  
  317. extern struct keytab onoff[];        /* On/Off keyword table */
  318.  
  319. #ifdef CK_TMPDIR
  320. int f_tmpdir = 0;            /* Directory changed temporarily */
  321. char savdir[TMPDIRLEN];            /* For saving current directory */
  322. extern char * dldir;
  323. #endif /* CK_TMPDIR */
  324.  
  325. int activecmd = -1;            /* Keyword index of active command */
  326. int doconx = -1;            /* CONNECT-class command active */
  327. int ooflag = 0;                /* User-settable on/off flag */
  328.  
  329. int rcflag = 0;                /* Pointer to home directory string */
  330. int repars,                /* Reparse needed */
  331.     techo = 0;                /* Take echo */
  332. int secho = 1;                /* SCRIPT echo */
  333.  
  334. int xitwarn =            /* Warn about open connection on exit */
  335. #ifdef NOWARN
  336. 0
  337. #else
  338. 1
  339. #endif /* NOWARN */
  340. ;
  341.  
  342. struct keytab onoffsw[] = {
  343.     "/off", 0, 0,
  344.     "/on",  1, 0
  345. };
  346.  
  347. #ifdef CKEXEC
  348. struct keytab redirsw[] = {
  349.     "/redirect", 1, 0
  350. };
  351. #endif /* CKEXEC */
  352.  
  353. #ifndef NOXMIT
  354. /* Variables for TRANSMIT command */
  355.  
  356. int xmitx = 1;            /* Whether to echo during TRANSMIT */
  357. int xmitf = 0;            /* Character to fill empty lines */
  358. int xmitl = 0;            /* 0 = Don't send linefeed too */
  359. int xmitp = LF;            /* Host line prompt */
  360. int xmits = 0;            /* Use shift-in/shift-out, 0 = no */
  361. int xmitw = 0;            /* Milliseconds to pause during TRANSMIT */
  362. int xmitt = 1;            /* Seconds to wait for each char to echo */
  363. int xmita = 1;            /* Action upon timeout */
  364.  
  365. #define XMI_BIN 1
  366. #define XMI_TXT 2
  367. #define XMI_CMD 3
  368. #define XMI_TRA 4
  369. #define XMI_VRB 5
  370. #define XMI_QUI 6
  371. #define XMI_NOW 7
  372.  
  373. static struct keytab xmitsw[] = {    /* TRANSMIT command options */
  374.     "/binary",          XMI_BIN, 0,
  375. #ifdef PIPESEND
  376.     "/command",         XMI_CMD, CM_INV,
  377. #endif /* PIPESEND */
  378.     "/nowait",          XMI_NOW, 0,
  379. #ifdef PIPESEND
  380.     "/pipe",            XMI_CMD, 0,
  381. #endif /* PIPESEND */
  382. #ifdef COMMENT
  383.     "/quiet",           XMI_QUI, 0,
  384. #endif /* COMMENT */
  385.     "/text",            XMI_TXT, 0,
  386.     "/transparent",     XMI_TRA, 0,
  387. #ifdef COMMENT
  388.     "/verbose",         XMI_VRB, 0,
  389. #endif /* COMMENT */
  390.     "", 0, 0
  391. };
  392. #define NXMITSW sizeof(xmitsw)/sizeof(struct keytab) - 1
  393. static int nxmitsw = NXMITSW;
  394.  
  395. #endif /* NOXMIT */
  396.  
  397. /* Declarations from ck?fio.c module */
  398.  
  399. extern char *SPACMD, *SPACM2;        /* SPACE commands */
  400.  
  401. /* Command-oriented items */
  402.  
  403. #ifdef DCMDBUF
  404. extern char *cmdbuf;            /* Command buffers */
  405. extern char *atmbuf;
  406. extern char *line;            /* Character buffer for anything */
  407. extern char *tmpbuf;            /* Short temporary string buffer */
  408. extern int *ifcmd;
  409. extern int *intime;
  410. extern char *inpcas;
  411. #else
  412. extern char cmdbuf[];            /* Command buffers */
  413. extern char atmbuf[];
  414. extern char line[];            /* Character buffer for anything */
  415. extern char tmpbuf[];            /* Temporary buffer */
  416. extern int ifcmd[];
  417. extern int intime[];
  418. extern char inpcas[];
  419. #endif /* DCMDBUF */
  420.  
  421. char *lp;                /* Pointer to line buffer */
  422.  
  423. #ifndef NOSPL
  424. int oldeval = 0;
  425. char evalbuf[33];            /* EVALUATE result */
  426. extern char * inpbuf;            /* Buffer for INPUT and REINPUT */
  427. char *inpbp;                /* And pointer to same */
  428. extern char lblbuf[];            /* Buffer for labels */
  429. int m_found;                /* MINPUT result */
  430. int i_active = 0;            /* INPUT command is active */
  431. char *ms[MINPMAX];            /* Pointers to MINPUT strings */
  432. static int mp[MINPMAX];            /* and flags */
  433. extern int fndiags, fnerror, fnsuccess;    /* Function diagnostics */
  434. #endif /* NOSPL */
  435.  
  436. char psave[PROMPTL] = { NUL };        /* For saving & restoring prompt */
  437.  
  438. extern int success;            /* Command success/failure flag */
  439. extern int cmdlvl;            /* Current position in command stack */
  440.  
  441. #ifndef NOSPL
  442. int                    /* SET INPUT parameters. */
  443. /* Note, INPUT TIMEOUT, intime[], is on the command-level stack. */
  444.   inbufsize = 0,            /* INPUT buffer size */
  445.   indef = 1,                /* default timeout, seconds */
  446.   inecho = 1,                /* 1 = echo on */
  447.   inautodl = 0,                /* INPUT autodownload */
  448.   inintr = 1,                /* INPUT interrupion allowed */
  449.   insilence = 0;            /* 0 = no silence constraint */
  450. #ifdef OS2
  451. int interm = 1;                /* Terminal emulator displays input */
  452. #endif /* OS2 */
  453. int maclvl = -1;            /* Macro nesting level */
  454. int mecho = 0;                /* Macro echo, 0 = don't */
  455. char varnam[6];                /* For variable names */
  456. extern int macargc[];            /* ARGC from macro invocation */
  457.  
  458. extern char *m_arg[MACLEVEL][NARGS];    /* Stack of macro arguments */
  459. extern char *mrval[];
  460.  
  461. extern char **a_ptr[];            /* Array pointers */
  462. extern int a_dim[];            /* Array dimensions */
  463.  
  464. #ifdef DCMDBUF
  465. extern struct cmdptr *cmdstk;        /* The command stack itself */
  466. #else
  467. extern struct cmdptr cmdstk[];        /* The command stack itself */
  468. #endif /* DCMDBUF */
  469.  
  470. long ck_alarm = 0;            /* SET ALARM value */
  471. char alrm_date[10] = { ' ',' ',' ',' ',' ',' ',' ',' ',' ' };
  472. char alrm_time[ 8] = { ' ',' ',' ',' ',' ',' ',' ' };
  473.  
  474. #endif /* NOSPL */
  475.  
  476. static int x, y, z = 0;            /* Local workers */
  477. static char *s;
  478.  
  479. #define xsystem(s) zsyscmd(s)
  480.  
  481. /* Top-Level Interactive Command Keyword Table */
  482. /* Keywords must be in lowercase and in alphabetical order. */
  483.  
  484. struct keytab cmdtab[] = {
  485. #ifndef NOPUSH
  486.     "!",       XXSHE, CM_INV,    /* Shell escape */
  487. #else
  488.     "!",       XXNOTAV, CM_INV,
  489. #endif /* NOPUSH */
  490.     "#",           XXCOM, CM_INV,    /* Comment */
  491. #ifndef NOSPL
  492.     ".",           XXDEF, CM_INV,    /* Assignment */
  493.     ":",           XXLBL, CM_INV,    /* Label */
  494. #endif /* NOSPL */
  495. #ifdef CK_REDIR
  496. #ifndef NOPUSH
  497.     "<",           XXFUN, CM_INV,    /* REDIRECT */
  498. #else
  499.     "<",           XXNOTAV, CM_INV,    /* REDIRECT */
  500. #endif /* NOPUSH */
  501. #endif /* CK_REDIR */
  502. #ifndef NOPUSH
  503.     "@",           XXSHE, CM_INV,    /* DCL escape */
  504. #else
  505.     "@",           XXNOTAV, CM_INV,    /* DCL escape */
  506. #endif /* NOPUSH */
  507.     "about",       XXVER, CM_INV,    /* Synonym for VERSION */
  508. #ifndef NOSPL
  509. #ifdef ADDCMD
  510.     "add",         XXADD, 0,        /* ADD */
  511. #endif /* ADDCMD */
  512. #ifndef NODIAL
  513.     "answer",      XXANSW, 0,        /* ANSWER the phone */
  514. #else
  515.     "answer",      XXNOTAV, CM_INV,    /* ANSWER the phone */
  516. #endif /* NODIAL */
  517.     "apc",         XXAPC, 0,        /* Application Program Command */
  518. #ifndef NOSPL
  519.     "array",       XXARRAY, 0,          /* Array operations */
  520. #endif /* NOSPL */
  521.     "ascii",       XXASC, CM_INV,
  522.     "asg",         XXASS, CM_INV,       /* Invisible synonym for ASSIGN */
  523.     "ask",         XXASK, 0,        /* ASK for text, assign to variable */
  524.     "askq",        XXASKQ,0,            /* ASK quietly (no echo) */
  525. #ifndef NOSPL
  526.     "ass",         XXASS, CM_INV|CM_ABR,
  527.     "assert",      XXASSER, 0,        /* ASSERT */
  528.     "assign",      XXASS, 0,        /* ASSIGN */
  529. #endif /* NOSPL */
  530. #ifndef NOXFER
  531. #ifndef NOCSETS
  532.     "associate",   XXASSOC, 0,        /* ASSOCIATE */
  533. #else
  534.     "associate",   XXNOTAV, CM_INV,    /* ASSOCIATE */
  535. #endif /* NOCSETS */
  536. #endif /* NOXFER */
  537. #ifdef CK_KERBEROS
  538.     "authenticate",XXAUTH,        /* Authentication */
  539. #ifdef CK_AUTHENTICATION
  540.                           0,
  541. #else
  542.                           CM_INV,
  543. #endif /* CK_AUTHENTICATION */
  544. #endif /* CK_KERBEROS */
  545. #endif /* NOSPL */
  546. #ifndef NOFRILLS
  547.     "back",        XXBACK,0,        /* BACK to previous directory */
  548. #else
  549.     "back",        XXNOTAV,CM_INV,
  550. #endif /* NOFRILLS */
  551.     "beep",        XXBEEP,CM_INV,    /* BEEP */
  552. #ifndef NOXFER
  553.     "binary",      XXBIN, CM_INV,    /* == SET FILE TYPE BINARY */
  554. #endif /* NOXFER */
  555. #ifndef NOFRILLS
  556.     "bug",         XXBUG, CM_INV,    /* BUG report instructions */
  557. #else
  558.     "bug",         XXNOTAV, CM_INV,
  559. #endif /* NOFRILLS */
  560. #ifdef BROWSER
  561.     "browse",      XXBROWS, 0,        /* BROWSE (start browser) */
  562. #else
  563.     "browse",      XXNOTAV, CM_INV,    /* BROWSE (start browser) */
  564. #endif /* BROWSER */
  565. #ifndef NOXFER
  566.     "bye",         XXBYE, 0,        /* BYE to remote server */
  567. #endif /* NOXFER */
  568. #ifndef NOLOCAL
  569.     "c",           XXCON, CM_INV|CM_ABR, /* invisible synonym for CONNECT */
  570. #endif /* NOLOCAL */
  571. #ifndef NOFRILLS
  572.     "cat",         XXTYP, CM_INV,    /* Invisible synonym for TYPE */
  573. #endif /* NOFRILLS */
  574. #ifndef NOSPL
  575. #ifdef COMMENT
  576. #ifndef NOXFER
  577.     "cautious",    XXCAU, CM_INV,
  578. #endif /* NOXFER */
  579. #endif /* COMMENT */
  580. #endif /* NOSPL */
  581.     "cd",          XXCWD, 0,        /* Change Directory */
  582. #ifndef NOXFER
  583. #ifdef PIPESEND
  584.     "cget",        XXCGET, CM_INV,    /* CGET */
  585. #else
  586.     "cget",        XXNOTAV, CM_INV,    /* CGET */
  587. #endif /* PIPESEND */
  588. #endif /* NOXFER */
  589.     "check",       XXCHK, 0,        /* CHECK for a feature */
  590.     "ckermit",     XXKERMI, CM_INV,
  591. #ifndef NOFRILLS
  592.     "clear",       XXCLE, 0,        /* CLEAR input and/or device buffer */
  593. #else
  594.     "clear",       XXNOTAV, CM_INV,
  595. #endif /* NOFRILLS */
  596.     "close",       XXCLO, 0,        /* CLOSE a log or other file */
  597.     "cls",         XXCLS, CM_INV,    /* Clear Screen (CLS) */
  598.     "comment",     XXCOM, CM_INV,    /* Introduce a comment */
  599. #ifndef NOLOCAL
  600.     "connect",     XXCON, 0,        /* Begin terminal connection */
  601. #else
  602.     "connect",     XXNOTAV, 0,
  603. #endif /* NOLOCAL */
  604. #ifndef NOFRILLS
  605. #ifdef ZCOPY
  606.     "co",          XXCPY, CM_INV|CM_ABR,
  607.     "cop",         XXCPY, CM_INV|CM_ABR,
  608.     "copy",        XXCPY, 0,        /* COPY a file */
  609. #else
  610.     "copy",        XXNOTAV, CM_INV,
  611. #endif /* ZCOPY */
  612.     "copyright",   XXCPR, CM_INV,    /* COPYRIGHT */
  613. #ifdef ZCOPY
  614.     "cp",          XXCPY, CM_INV,    /* COPY a file */
  615. #endif /* ZCOPY */
  616. #ifndef NOLOCAL
  617. #ifndef OS2
  618.     "cq",          XXCQ, CM_INV,    /* CQ (connect quietly) */
  619. #endif /* OS2 */
  620. #endif /* NOLOCAL */
  621. #ifndef NOXFER
  622. #ifdef PIPESEND
  623.     "creceive",    XXCREC,CM_INV,    /* CRECEIVE (receive to command) */
  624.     "csend",       XXCSEN,CM_INV,    /* CSEND (send from command) */
  625. #else
  626.     "creceive",    XXNOTAV,CM_INV,    /* CRECEIVE (receive to command) */
  627.     "csend",       XXNOTAV,CM_INV,    /* CSEND (send from command) */
  628. #endif /* PIPESEND */
  629. #endif /* NOXFER */
  630. #endif /* NOFRILLS */
  631.  
  632.     "cwd",       XXCWD, CM_INV,    /* Invisible synonym for cd */
  633.  
  634. #ifndef NOSPL
  635.     "date",        XXDATE,0,        /* DATE */
  636.     "dcl",         XXDCL, CM_INV,    /* DECLARE an array (see ARRAY) */
  637.     "declare",     XXDCL, CM_INV,    /* DECLARE an array (see ARRAY) */
  638.     "decrement",   XXDEC, 0,        /* DECREMENT a numeric variable */
  639.     "define",      XXDEF, 0,        /* DEFINE a macro or variable */
  640. #else
  641.     "date",        XXNOTAV, CM_INV,
  642.     "dcl",         XXNOTAV, CM_INV,
  643.     "declare",     XXNOTAV, CM_INV,
  644.     "decrement",   XXNOTAV, CM_INV,
  645.     "define",      XXNOTAV, CM_INV,
  646. #endif /* NOSPL */
  647.  
  648. #ifndef NOFRILLS
  649.     "delete",      XXDEL, 0,        /* DELETE a file */
  650. #else
  651.     "delete",      XXNOTAV, CM_INV,
  652. #endif /* NOFRILLS */
  653.  
  654. #ifndef NODIAL
  655.     "dial",       XXDIAL,0,        /* DIAL a phone number */
  656. #else
  657.     "dial",       XXNOTAV, CM_INV,
  658. #endif /* NODIAL */
  659.  
  660.     "directory",   XXDIR, 0,        /* DIRECTORY of files */
  661.  
  662. #ifndef NOFRILLS
  663. #ifndef NOSERVER
  664.     "disable",     XXDIS, 0,        /* DISABLE a server function */
  665. #else
  666.     "disable",     XXNOTAV, CM_INV,
  667. #endif /* NOSERVER */
  668. #endif /* NOFRILLS */
  669.  
  670. #ifndef NOSPL
  671.     "do",          XXDO,  0,        /* DO (execute) a macro */
  672. #else
  673.     "do",          XXNOTAV, CM_INV,
  674. #endif /* NOSPL */
  675.  
  676.     "e",           XXEXI, CM_INV|CM_ABR,
  677.  
  678. #ifndef NOFRILLS
  679. #ifndef NOXFER
  680.     "e-packet",    XXERR, CM_INV,    /* Send an Error-Packet */
  681. #endif /* NOXFER */
  682. #endif /* NOFRILLS */
  683.  
  684.     "echo",        XXECH, 0,        /* ECHO text */
  685.  
  686. #ifndef NOFRILLS
  687. #ifndef NOPUSH
  688.     "edit",        XXEDIT, 0,        /* EDIT */
  689. #else
  690.     "edit",        XXNOTAV, CM_INV,    /* EDIT */
  691. #endif /* NOPUSH */
  692. #endif /* NOFRILLS */
  693.  
  694.     "eightbit",    XXEIGHT, 0,        /* EIGHTBIT */
  695.  
  696. #ifndef NOSPL
  697.     "else",        XXELS, CM_INV,    /* ELSE part of IF statement */
  698. #else
  699.     "else",        XXNOTAV, CM_INV,    /* ELSE part of IF statement */
  700. #endif /* NOSPL */
  701.  
  702. #ifndef NOSERVER
  703. #ifndef NOFRILLS
  704.     "enable",      XXENA,  0,        /* ENABLE a server function */
  705. #else
  706.     "enable",      XXNOTAV, CM_INV,
  707. #endif /* NOFRILLS */
  708. #endif /* NOSERVER */
  709.  
  710. #ifndef NOSPL
  711.     "end",         XXEND,  0,        /* END command file or macro */
  712.     "evaluate",    XXEVAL, 0,        /* EVALUATE */
  713. #else
  714.     "end",         XXNOTAV, CM_INV,
  715.     "evaluate",    XXNOTAV, CM_INV,
  716. #endif /* NOSPL */
  717.  
  718.     "ex",          XXEXI, CM_INV|CM_ABR, /* Let "ex" still be EXIT */
  719.  
  720. #ifdef CKEXEC
  721.     "exec",        XXEXEC, CM_INV,    /* exec() */
  722. #else
  723.     "exec",        XXNOTAV, CM_INV,
  724. #endif /* CKEXEC */
  725.  
  726.     "exit",       XXEXI, 0,        /* EXIT from C-Kermit */
  727.     "extended-options", XXXOPTS,CM_INV|CM_HLP, /* Extended-Options */
  728.  
  729. #ifdef OS2
  730.     "extproc",     XXCOM, CM_INV,    /* Dummy command for OS/2 */
  731. #endif /* OS2 */
  732.  
  733. #ifndef NOXFER
  734.     "f",           XXFIN, CM_INV|CM_ABR, /* Invisible abbreviation for FIN */
  735. #endif /* NOXFER */
  736.  
  737. #ifndef NOSPL
  738.     "fail",        XXFAIL,0,        /* FAIL */
  739.  
  740. #ifdef COMMENT
  741. #ifndef NOXFER
  742.     "fast",        XXFAST, CM_INV,
  743. #endif /* NOXFER */
  744. #endif /* COMMENT */
  745.  
  746. #ifdef CKCHANNELIO
  747.     "fclose",      XXF_CL, CM_INV,    /* FCLOSE */
  748.     "fcount",      XXF_CO, CM_INV,    /* FCOUNT */
  749.     "fflush",      XXF_FL, CM_INV,    /* FFLUSH */
  750. #endif /* CKCHANNELIO */
  751.  
  752. #ifndef NOXFER
  753.     "fi",          XXFIN, CM_INV|CM_ABR, /* FINISH */
  754. #endif /* NOXFER */
  755.  
  756. #ifdef CKCHANNELIO
  757.     "file",        XXFILE, 0,        /* FILE */
  758. #endif /* CKCHANNELIO */
  759. #endif /* NOSPL */
  760.  
  761. #ifndef NOXFER
  762.     "finish",      XXFIN, 0,        /* FINISH */
  763. #endif /* NOXFER */
  764.  
  765. #ifdef CKCHANNELIO
  766.     "flist",      XXF_LI, CM_INV,    /* FLIST */
  767.     "fopen",      XXF_OP, CM_INV,    /* FOPEN */
  768. #endif /* CKCHANNELIO */
  769.  
  770. #ifndef NOSPL
  771.     "fo",          XXFOR, CM_INV|CM_ABR, /* Invisible abbreviation for... */
  772.     "for",         XXFOR, 0,        /* FOR loop */
  773.     "forward",     XXFWD, CM_INV,    /* FORWARD */
  774. #endif /* NOSPL */
  775. #ifndef NOFRILLS
  776.     "fot",       XXDIR, CM_INV,    /* "fot" = "dir" (for Chris) */
  777. #endif /* NOFRILLS */
  778.  
  779. #ifdef CKCHANNELIO
  780.     "fread",      XXF_RE, CM_INV,    /* FREAD */
  781.     "frewind",    XXF_RW, CM_INV,    /* FREWIND */
  782.     "fseek",      XXF_SE, CM_INV,    /* FSEEK */
  783.     "fstatus",    XXF_ST, CM_INV,    /* FSTATUS */
  784. #endif /* CKCHANNELIO */
  785.  
  786. #ifdef TCPSOCKET
  787. #ifndef NOPUSH
  788.     "ftp",       XXFTP,   CM_INV,    /* FTP */
  789. #else
  790.     "ftp",       XXNOTAV, CM_INV,
  791. #endif /* NOPUSH */
  792. #else
  793.     "ftp",       XXNOTAV, CM_INV,
  794. #endif /* TCPSOCKET */
  795.  
  796. #ifndef NOSPL
  797.     "function",    XXFUNC, CM_INV|CM_HLP, /* Function (for HELP FUNCTION) */
  798. #endif /* NOSPL */
  799.  
  800. #ifdef CKCHANNELIO
  801.     "fwrite",      XXF_WR, CM_INV,    /* FWRITE */
  802. #endif /* CKCHANNELIO */
  803.  
  804. #ifndef NOXFER
  805.     "g",           XXGET, CM_INV|CM_ABR, /* Invisible abbreviation for GET */
  806. #ifndef NOSPL
  807.     "ge",          XXGET, CM_INV|CM_ABR, /* Ditto */
  808. #endif /* NOSPL */
  809.     "get",         XXGET, 0,        /* GET */
  810. #endif /* NOXFER */
  811. #ifndef NOSPL
  812.     "getc",        XXGETC, 0,        /* GETC */
  813. #ifdef OS2
  814.     "getkeycode",  XXGETK, 0,        /* GETKEYCODE */
  815. #endif /* OS2 */
  816. #ifndef NOFRILLS
  817.     "getok",       XXGOK, 0,        /* GETOK (ask for Yes/No/OK) */
  818. #endif /* NOFRILLS */
  819. #endif /* NOSPL */
  820. #ifndef NOSPL
  821.     "goto",        XXGOTO,0,         /* GOTO label in take file or macro */
  822. #endif /* NOSPL */
  823.     "h",           XXHLP, CM_INV|CM_ABR, /* Invisible synonym for HELP */
  824. #ifndef NOLOCAL
  825.     "hangup",      XXHAN, 0,         /* HANGUP the connection */
  826. #endif /* NOLOCAL */
  827.     "help",       XXHLP, 0,         /* Display HELP text */
  828. #ifndef NOHTTP
  829. #ifdef TCPSOCKET
  830.     "http",        XXHTTP,CM_INV,     /* HTTP operations (not yet) */
  831. #endif /* TCPSOCKET */
  832. #endif /* NOHTTP */
  833. #ifndef NOSPL
  834.     "i",           XXINP, CM_INV|CM_ABR, /* Invisible synonym for INPUT */
  835.     "if",          XXIF,  0,         /* IF ( condition ) command */
  836. #ifdef TCPSOCKET
  837.     "iksd",        XXIKSD,0,            /* IKSD (TCP/IP only) */
  838. #else
  839.     "iksd",        XXNOTAV, CM_INV,
  840. #endif /* TCPSOCKET */
  841.     "in",          XXINP, CM_INV|CM_ABR, /* Invisible synonym for INPUT */
  842.     "increment",   XXINC, 0,         /* Increment a numeric variable */
  843.     "input",       XXINP, 0,         /* INPUT text from comm device */
  844. #endif /* NOSPL */
  845.  
  846. #ifndef NOHELP
  847.     "int",         XXINT, CM_INV|CM_ABR,
  848.     "intr",        XXINT, CM_INV|CM_ABR,
  849.     "intro",       XXINT, 0,
  850.     "introduction",XXINT, CM_INV,    /* Print introductory text */
  851. #else
  852.     "intro",       XXNOTAV, CM_INV,
  853.     "introduction",XXNOTAV, CM_INV,
  854. #endif /* NOHELP */
  855.  
  856. #ifdef OS2
  857.     "k95",         XXKERMI, CM_INV,    /* Hmmm what's this... */
  858.     "kermit",      XXKERMI, CM_INV,
  859. #else
  860.     "kermit",      XXKERMI, CM_INV,
  861. #endif /* OS2 */
  862.  
  863. #ifdef OS2
  864. #ifndef NOKVERBS
  865.     "kverb",       XXKVRB, CM_INV|CM_HLP, /* Keyboard verb */
  866. #endif /* NOKVERBS */
  867. #endif /* OS2 */
  868.  
  869. #ifndef NOFRILLS
  870.     "l",           XXLOG, CM_INV|CM_ABR, /* Invisible synonym for log */
  871. #endif /* NOFRILLS */
  872.  
  873. #ifndef NOSPL
  874.     "lineout",     XXLNOUT, 0,        /* LINEOUT = OUTPUT + eol */
  875. #endif /* NOSPL */
  876.  
  877. #ifndef NOFRILLS
  878.     "lo",           XXLOG, CM_INV|CM_ABR, /* Invisible synonym for log */
  879. #endif /* NOFRILLS */
  880.  
  881. #ifndef NOSPL
  882.     "local",       XXLOCAL, 0,        /* LOCAL variable declaration */
  883. #else
  884.     "local",       XXNOTAV, CM_INV,
  885. #endif /* NOSPL */
  886.  
  887.     "log",         XXLOG, 0,        /* Open a log file */
  888.  
  889.     "login",       XXLOGIN,  0,        /* LOGIN to server or IKSD */
  890.     "logout",      XXLOGOUT, 0,         /* LOGOUT from server or IKSD */
  891.  
  892. #ifndef NOFRILLS
  893. #ifndef NODIAL
  894.     "lookup",      XXLOOK,0,        /* LOOKUP */
  895. #else
  896.     "lookup",      XXNOTAV, CM_INV,
  897. #endif /* NODIAL */
  898. #ifdef UNIXOROSK
  899.     "ls",          XXLS,  0,        /* UNIX ls command */
  900. #else
  901.     "ls",          XXDIR, CM_INV,    /* Invisible synonym for DIR */
  902. #endif /* UNIXOROSK */
  903. #ifndef NOXFER
  904.     "mail",        XXMAI, 0,        /* Send a file as e-mail */
  905. #endif /* NOXFER */
  906. #ifndef NOHELP
  907.     "manual",      XXMAN, 0,        /* MAN(UAL) */
  908. #else
  909.     "manual",      XXNOTAV, CM_INV,
  910. #endif /* NOHELP */
  911. #endif /* NOFRILLS */
  912. #ifdef CK_MKDIR
  913.     "md",          XXMKDIR, CM_INV,    /* Synonym for MKDIR */
  914. #endif /* CK_MKDIR */
  915. #ifdef CK_MINPUT
  916.     "minput",      XXMINP, 0,        /* MINPUT */
  917. #else
  918.     "minput",      XXNOTAV, CM_INV,
  919. #endif /* CK_MINPUT */
  920. #ifndef NOMSEND
  921.     "mget",        XXMGET, 0,        /* MGET */
  922. #else
  923.     "mget",        XXNOTAV, CM_INV,
  924. #endif /* NOMSEND */
  925. #ifdef CK_MKDIR
  926.     "mkdir",       XXMKDIR, 0,        /* MKDIR */
  927. #else
  928.     "mkdir",       XXNOTAV, CM_INV,
  929. #endif /* CK_MKDIR */
  930.  
  931. #ifndef NOXFER
  932. #ifndef NOMSEND
  933.     "mmove",       XXMMOVE, 0,        /* MMOVE */
  934. #else
  935.     "mmove",       XXNOTAV, CM_INV,
  936. #endif /* NOMSEND */
  937. #endif /* NOXFER */
  938.  
  939. #ifndef NOFRILLS
  940.     "more",        XXMORE, CM_INV,    /* MORE */
  941. #endif /* NOFRILLS */
  942.  
  943. #ifndef NOXFER
  944.     "move",        XXMOVE, 0,        /* MOVE  */
  945. #endif /* NOXFER */
  946.  
  947. #ifndef NOSPL
  948.     "mpause",      XXMSL, CM_INV,    /* Millisecond sleep */
  949. #else
  950.     "mpause",      XXNOTAV, CM_INV,
  951. #endif /* NOSPL */
  952.  
  953. #ifndef NOXFER
  954. #ifndef NOMSEND
  955.     "mput",        XXMSE, CM_INV,    /* MPUT = MSEND */
  956.     "ms",          XXMSE, CM_INV|CM_ABR,
  957.     "msend",       XXMSE, 0,        /* Multiple SEND */
  958. #else
  959.     "mput",        XXNOTAV, CM_INV,
  960.     "msend",       XXNOTAV, CM_INV,
  961. #endif /* NOMSEND */
  962. #endif /* NOXFER */
  963. #ifndef NOSPL
  964.     "msleep",      XXMSL, 0,        /* Millisecond sleep */
  965. #else
  966.     "msleep",      XXNOTAV, CM_INV,
  967. #endif /* NOSPL */
  968. #ifndef NOFRILLS
  969.     "mv",          XXREN, CM_INV,    /* Synonym for rename */
  970. #endif /* NOFRILLS */
  971. #ifndef NOHELP
  972.     "news",        XXNEW, CM_INV,    /* Display NEWS of new features */
  973. #else
  974.     "news",        XXNOTAV, CM_INV,
  975. #endif /* NOHELP */
  976.     "nolocal",     XXNLCL, CM_INV,    /* Disable SET LINE / SET HOST */
  977.     "nopush",      XXNPSH, CM_INV,    /* Disable PUSH command/features */
  978. #ifndef NOSPL
  979.     "o",           XXOUT, CM_INV|CM_ABR, /* Invisible synonym for OUTPUT */
  980.     "open",        XXOPE, 0,        /* OPEN file for reading or writing */
  981. #else
  982.     "open",        XXNPSH, CM_INV,    /* Disable PUSH command/features */
  983. #endif /* NOSPL */
  984. #ifndef NOHELP
  985.     "options",     XXOPTS,CM_INV|CM_HLP, /* Options */
  986. #endif /* NOHELP */
  987. #ifndef NOSPL
  988.     "output",      XXOUT, 0,        /* OUTPUT text to comm device */
  989. #else
  990.     "output",      XXNOTAV, CM_INV,
  991. #endif /* NOSPL */
  992. #ifdef ANYX25
  993. #ifndef IBMX25
  994.     "pad",         XXPAD, 0,            /* X.3 PAD commands */
  995. #endif /* IBMX25 */
  996. #endif /* ANYX25 */
  997. #ifndef NOSPL
  998.     "pause",       XXPAU, 0,        /* Sleep for specified interval */
  999. #else
  1000.     "pause",       XXNOTAV, CM_INV,
  1001. #endif /* NOSPL */
  1002. #ifndef NODIAL
  1003.     "pdial",       XXPDIA,0,        /* PDIAL (partial dial) */
  1004. #else
  1005.     "pdial",       XXNOTAV, CM_INV,
  1006. #endif /* NODIAL */
  1007. #ifdef TCPSOCKET
  1008. #ifndef NOPUSH
  1009.     "ping",        XXPNG, CM_INV,    /* PING */
  1010. #else
  1011.     "ping",        XXNOTAV, CM_INV,
  1012. #endif /* NOPUSH */
  1013. #endif /* TCPSOCKET */
  1014. #ifdef NETCMD
  1015. #ifndef NOPUSH
  1016.     "pipe",        XXPIPE, 0,        /* PIPE */
  1017. #else
  1018.     "pipe",        XXNOTAV, CM_INV,    /* PIPE */
  1019. #endif /* NOPUSH */
  1020. #endif /* NETCMD */
  1021.  
  1022. #ifndef NOSPL
  1023.     "pop",         XXEND, CM_INV,    /* Invisible synonym for END */
  1024. #endif /* NOSPL */
  1025. #ifndef NOFRILLS
  1026.     "print",       XXPRI, 0,        /* PRINT a file locally */
  1027. #endif /* NOFRILLS */
  1028. #ifndef NOXFER
  1029. #ifdef CK_RESEND
  1030.     "psend",       XXPSEN, CM_INV,    /* PSEND */
  1031. #else
  1032.     "psend",       XXNOTAV, CM_INV,
  1033. #endif /* CK_RESEND */
  1034. #endif /* NOXFER */
  1035.  
  1036. #ifdef NETPTY
  1037.     "pty",         XXPTY, 0,        /* PTY */
  1038. #else
  1039.     "pty",         XXNOTAV, CM_INV,
  1040. #endif /* NETPTY */
  1041.  
  1042. #ifndef NOPUSH
  1043.     "pu",          XXSHE, CM_INV|CM_ABR, /* PU = PUSH */
  1044. #endif /* NOPUSH */
  1045.  
  1046. #ifdef CKPURGE
  1047.     "purge",       XXPURGE, 0,        /* PURGE (real) */
  1048. #else
  1049. #ifdef VMS
  1050.     "purge",       XXPURGE, 0,        /* PURGE (fake) */
  1051. #else
  1052.     "purge",       XXNOTAV, CM_INV,
  1053. #endif /* VMS */
  1054. #endif /* CKPURGE */
  1055.  
  1056. #ifndef NOPUSH
  1057.     "push",        XXSHE, 0,        /* PUSH command (like RUN, !) */
  1058. #else
  1059.     "push",        XXNOTAV, CM_INV,
  1060. #endif /* NOPUSH */
  1061.  
  1062. #ifndef NOXFER
  1063.     "put",       XXSEN, CM_INV,    /* PUT = SEND */
  1064. #endif /* NOXFER */
  1065.  
  1066.     "pwd",         XXPWD, 0,            /* Print Working Directory */
  1067.     "q",              XXQUI, CM_INV|CM_ABR, /* Invisible synonym for QUIT */
  1068.  
  1069. #ifndef NOXFER
  1070.     "query",       XXRQUE,0,
  1071. #endif /* NOXFER */
  1072.  
  1073.     "quit",       XXQUI, 0,        /* QUIT from program = EXIT */
  1074.  
  1075. #ifndef NOXFER
  1076.     "r",           XXREC, CM_INV|CM_ABR, /* Invisible synonym for RECEIVE */
  1077. #endif /* NOXFER */
  1078.  
  1079. #ifndef NOXFER
  1080.     "rasg",        XXRASG, CM_INV,    /* REMOTE ASSIGN */
  1081.     "rassign",     XXRASG, CM_INV,    /* ditto */
  1082.     "rcd",         XXRCWD, CM_INV,    /* REMOTE CD */
  1083.     "rcopy",       XXRCPY, CM_INV,    /* REMOTE COPY */
  1084.     "rcwd",        XXRCWD, CM_INV,    /* REMOTE CWD */
  1085.     "rdelete",     XXRDEL, CM_INV,    /* REMOTE DELETE */
  1086.     "rdirectory",  XXRDIR, CM_INV,    /* REMODE DIRECTORY */
  1087. #endif /* NOXFER */
  1088.  
  1089. #ifndef NOSPL
  1090.     "read",        XXREA, 0,            /* READ a line from a file */
  1091. #else
  1092.     "read",        XXNOTAV, CM_INV,
  1093. #endif /* NOSPL */
  1094.  
  1095. #ifndef NOXFER
  1096.     "receive",       XXREC, 0,        /* RECEIVE files */
  1097. #endif /* NOXFER */
  1098.  
  1099. #ifndef NODIAL
  1100.     "red",         XXRED, CM_INV|CM_ABR, /* Invisible synonym for REDIAL */
  1101.     "redi",        XXRED, CM_INV|CM_ABR, /* Invisible synonym for REDIAL */
  1102.     "redial",      XXRED, 0,        /* REDIAL last DIAL number */
  1103. #else
  1104.     "red",         XXNOTAV, CM_INV,
  1105.     "redi",        XXNOTAV, CM_INV,
  1106.     "redial",      XXNOTAV, CM_INV,
  1107. #endif /* NODIAL */
  1108.  
  1109. #ifdef CK_REDIR
  1110. #ifdef OS2
  1111. #ifndef NOPUSH
  1112.     "redirect",    XXFUN, CM_INV,    /* REDIRECT local command to ttyfd */
  1113. #else
  1114.     "redirect",    XXNOTAV, CM_INV,
  1115. #endif /* NOPUSH */
  1116. #else /* OS2 */
  1117. #ifndef NOPUSH
  1118.     "redirect",    XXFUN, 0,        /* REDIRECT local command to ttyfd */
  1119. #else
  1120.     "redirect",    XXNOTAV, CM_INV,
  1121. #endif /* NOPUSH */
  1122. #endif /* OS2 */
  1123. #endif /* CK_REDIR */
  1124.  
  1125. #ifdef CK_RECALL
  1126.     "redo",        XXREDO,  CM_NOR,    /* REDO */
  1127. #else
  1128.     "redo",        XXNOTAV, CM_INV,
  1129. #endif /* CK_RECALL */
  1130.  
  1131. #ifndef NOXFER
  1132. #ifdef CK_RESEND
  1133.     "reget",       XXREGET, 0,        /* REGET */
  1134. #else
  1135.     "reget",       XXNOTAV, CM_INV,
  1136. #endif /* CK_RESEND */
  1137. #endif /* NOXFER */
  1138.  
  1139. #ifndef NOHELP
  1140.     "regular-expressions", XXWILD,CM_INV|CM_HLP,
  1141. #endif /* NOHELP */
  1142.  
  1143. #ifndef NOSPL
  1144.     "reinput",     XXREI, 0,            /* REINPUT (from INPUT buffer) */
  1145. #else
  1146.     "reinput",     XXNOTAV, CM_INV,
  1147. #endif /* NOSPL */
  1148.  
  1149. #ifndef NOXFER
  1150. #ifdef ADDCMD
  1151.     "rem",         XXREM, CM_INV|CM_ABR,
  1152.     "remo",        XXREM, CM_INV|CM_ABR,
  1153. #endif /* ADDCMD */
  1154.     "remote",       XXREM, 0,        /* Send REMOTE command to server */
  1155. #endif /* NOXFER */
  1156.  
  1157. #ifdef ADDCMD
  1158.     "remove",      XXREMV,0,        /* REMOVE (something from a list) */
  1159. #else
  1160.     "remove",      XXNOTAV, CM_INV,
  1161. #endif /* ADDCMD */
  1162.  
  1163. #ifndef NOFRILLS
  1164. #ifndef NORENAME
  1165.     "rename",      XXREN, 0,        /* RENAME a local file */
  1166. #else
  1167.     "rename",      XXNOTAV, CM_INV,
  1168. #endif /* NORENAME */
  1169.     "replay",      XXTYP, CM_INV,    /* REPLAY (for now, just type) */
  1170. #endif /* NOFRILLS */
  1171.  
  1172. #ifndef NOXFER
  1173. #ifdef CK_RESEND
  1174.     "res",         XXRSEN, CM_INV|CM_ABR, /* RESEND */
  1175.     "rese",        XXRSEN, CM_INV|CM_ABR, /* RESEND */
  1176.     "resend",      XXRSEN, 0,          /* RESEND */
  1177. #else
  1178.     "res",         XXNOTAV, CM_INV,
  1179.     "rese",        XXNOTAV, CM_INV,
  1180.     "resend",      XXNOTAV, CM_INV,
  1181. #endif /* CK_RESEND */
  1182. #endif /* NOXFER */
  1183.  
  1184.     "reset",       XXRESET, CM_INV,    /* RESET */
  1185.  
  1186. #ifdef CK_RESEND
  1187. #ifndef NOSPL
  1188.     "ret",         XXRET, CM_INV|CM_ABR,
  1189. #endif /* NOSPL */
  1190. #endif /* CK_RESEND */
  1191.  
  1192. #ifndef NOXFER
  1193.     "retrieve",    XXRETR, CM_INV,    /* RETRIEVE */
  1194. #endif /* NOXFER */
  1195.  
  1196. #ifndef NOSPL
  1197.     "return",      XXRET, 0,        /* RETURN from a function */
  1198. #else
  1199.     "return",      XXNOTAV, CM_INV,
  1200. #endif /* NOSPL */
  1201.  
  1202. #ifndef NOXFER
  1203.     "rexit",      XXRXIT, CM_INV,    /* REMOTE EXIT */
  1204. #endif /* NOXFER */
  1205.  
  1206. #ifdef CK_REXX
  1207. #ifndef NOPUSH
  1208.     "rexx",       XXREXX, 0,        /* Execute a Rexx command */
  1209. #else
  1210.     "rexx",       XXNOTAV, CM_INV,
  1211. #endif /* NOPUSH */
  1212. #endif /* CK_REXX */
  1213.  
  1214. #ifndef NOXFER
  1215.     "rhelp",      XXRHLP, CM_INV,    /* REMOTE HELP */
  1216.     "rhost",      XXRHOS, CM_INV,    /* REMOTE HOST */
  1217.     "rkermit",    XXRKER, CM_INV,    /* REMOTE KERMIT */
  1218. #endif /* NOXFER */
  1219.  
  1220. #ifdef TCPSOCKET
  1221.     "rlogin",    XXRLOG, 0,        /* Make an Rlogin connection */
  1222. #else
  1223.     "rlogin",    XXNOTAV, CM_INV,
  1224. #endif /* TCPSOCKET */
  1225.  
  1226. #ifndef NOFRILLS
  1227.     "rm",          XXDEL, CM_INV,    /* Invisible synonym for delete */
  1228. #endif /* NOFRILLS */
  1229.  
  1230. #ifdef CK_MKDIR
  1231.     "rmdir",       XXRMDIR, 0,          /* RMDIR */
  1232. #else
  1233.     "rmdir",       XXNOTAV, CM_INV,
  1234. #endif /* CK_MKDIR */
  1235.  
  1236. #ifndef NOXFER
  1237.     "rmkdir",      XXRMKD, CM_INV,    /* REMOTE MKDIR */
  1238. #ifndef NOSPL
  1239.     "robust",      XXROB,  CM_INV,
  1240. #else
  1241.     "robust",      XXNOTAV, CM_INV,
  1242. #endif /* NOSPL */
  1243.     "rpwd",        XXRPWD, CM_INV,    /* REMOTE PWD */
  1244.     "rquery",      XXRQUE, CM_INV,    /* REMOTE QUERY */
  1245. #endif /* NOXFER */
  1246.  
  1247. #ifdef CK_RECALL
  1248.     "rr",          XXREDO, CM_INV|CM_NOR,
  1249. #endif /* CK_RECALL */
  1250.  
  1251. #ifndef NOXFER
  1252.     "rrename",    XXRREN, CM_INV,    /* REMOTE RENAME */
  1253.     "rrmdir",     XXRRMD, CM_INV,    /* REMOTE REMDIR */
  1254.     "rset",       XXRSET, CM_INV,    /* REMOTE SET */
  1255.     "rspace",     XXRSPA, CM_INV,    /* REMOTE SPACE */
  1256.     "rtype",      XXRTYP, CM_INV,    /* REMOTE TYPE */
  1257. #endif /* NOXFER */
  1258.  
  1259. #ifndef NOPUSH
  1260.     "run",         XXSHE, 0,        /* RUN a program or command */
  1261. #else
  1262.     "run",         XXNOTAV, CM_INV,
  1263. #endif /* NOPUSH */
  1264.  
  1265. #ifndef NOXFER
  1266.     "rwho",        XXRWHO, CM_INV,    /* REMOTE WHO */
  1267.     "s",           XXSEN, CM_INV|CM_ABR, /* Invisible synonym for send */
  1268. #endif /* NOXFER */
  1269.  
  1270. #ifndef NOSETKEY
  1271. #ifdef OS2
  1272.     "save",       XXSAVE, 0,        /* SAVE something */
  1273. #else
  1274.     "save",       XXSAVE, CM_INV,
  1275. #endif /* OS2 */
  1276. #else
  1277.     "save",       XXNOTAV, CM_INV,
  1278. #endif /* NOSETKEY */
  1279.  
  1280. #ifndef NOSCRIPT
  1281.     "sc",        XXLOGI, CM_INV|CM_ABR,
  1282.     "scr",       XXLOGI, CM_INV|CM_ABR,
  1283. #endif /* NOSCRIPT */
  1284.     "screen",      XXSCRN, 0,        /* SCREEN actions */
  1285. #ifndef NOSCRIPT
  1286.     "script",       XXLOGI,0,        /* Expect-Send-style script line */
  1287. #else
  1288.     "script",       XXNOTAV, CM_INV,
  1289. #endif /* NOSCRIPT */
  1290.  
  1291. #ifndef NOXFER
  1292.     "send",       XXSEN, 0,        /* Send (a) file(s) */
  1293. #ifndef NOSERVER
  1294.     "server",       XXSER, 0,        /* Be a SERVER */
  1295. #else
  1296.     "server",       XXNOTAV, CM_INV,
  1297. #endif /* NOSERVER */
  1298. #endif /* NOXFER */
  1299.  
  1300.     "set",       XXSET, 0,        /* SET parameters */
  1301.  
  1302. #ifndef NOSPL
  1303. #ifndef NOSHOW
  1304.     "sh",          XXSHO, CM_INV|CM_ABR,/* SHOW parameters */
  1305. #endif /* NOSHOW */
  1306.     "shift",       XXSHIFT, 0,        /* SHIFT args */
  1307. #else
  1308.     "shift",       XXNOTAV, CM_INV,
  1309. #endif /* NOSPL */
  1310.  
  1311. #ifndef NOSHOW
  1312.     "show",        XXSHO, 0,        /* SHOW parameters */
  1313. #else
  1314.     "show",        XXNOTAV, CM_INV,
  1315. #endif /* NOSHOW */
  1316.  
  1317. #ifndef NOSPL
  1318. #ifndef NOFRILLS
  1319.     "sleep",       XXPAU, CM_INV,    /* SLEEP for specified interval */
  1320. #endif /* NOFRILLS */
  1321.     "sort",        XXSORT, CM_INV,    /* (see ARRAY) */
  1322. #else
  1323.     "sort",        XXNOTAV, CM_INV,
  1324. #endif /* NOSPL */
  1325.  
  1326. #ifndef MAC
  1327. #ifndef NOFRILLS
  1328.     "sp",          XXSPA, CM_INV|CM_ABR,
  1329.     "spa",         XXSPA, CM_INV|CM_ABR,
  1330. #endif /* NOFRILLS */
  1331.     "space",       XXSPA, 0,        /* Show available disk SPACE */
  1332. #endif /* MAC */
  1333.  
  1334. #ifndef NOFRILLS
  1335. #ifndef NOPUSH
  1336.     "spawn",       XXSHE, CM_INV,    /* Synonym for PUSH, RUN */
  1337. #else
  1338.     "spawn",       XXNOTAV, CM_INV,    /* Synonym for PUSH, RUN */
  1339. #endif /* NOPUSH */
  1340. #endif /* NOFRILLS */
  1341.  
  1342. #ifndef NOXFER
  1343.     "sta",         XXSTA, CM_INV|CM_ABR,
  1344.     "stat",        XXSTA, CM_INV|CM_ABR,
  1345.     "statistics",  XXSTA, 0,        /* Display file transfer stats */
  1346. #endif /* NOXFER */
  1347.  
  1348.     "status",      XXSTATUS, 0,        /* Show status of previous command */
  1349.  
  1350. #ifndef NOSPL
  1351.     "stop",        XXSTO, 0,        /* STOP all take files and macros */
  1352.     "succeed",     XXSUCC, 0,        /* SUCCEED */
  1353. #else
  1354.     "stop",        XXNOTAV, CM_INV,
  1355.     "succeed",     XXNOTAV, CM_INV,
  1356. #endif /* NOSPL */
  1357.  
  1358. #ifndef NOFRILLS
  1359.     "support",     XXBUG, 0,        /* BUG report instructions */
  1360. #else
  1361.     "support",     XXNOTAV, CM_INV,
  1362. #endif /* NOFRILLS */
  1363.  
  1364. #ifndef NOJC
  1365.     "suspend",     XXSUS, 0,        /* SUSPEND C-Kermit (UNIX only) */
  1366. #else
  1367.     "suspend",     XXNOTAV, CM_INV,
  1368. #endif /* NOJC */
  1369.  
  1370. #ifndef NOSPL
  1371.     "switch",      XXSWIT, 0,        /* SWITCH */
  1372. #else
  1373.     "switch",      XXNOTAV, CM_INV,
  1374. #endif /* NOSPL */
  1375.  
  1376. #ifdef CK_TAPI
  1377.     "ta",       XXTAK, CM_INV|CM_ABR, /* (because of TAPI) */
  1378. #endif /* CK_TAPI */
  1379.  
  1380.     "take",       XXTAK, 0,        /* TAKE commands from a file */
  1381.  
  1382. #ifdef CK_TAPI
  1383.     "tapi",       XXTAPI, 0,        /* Microsoft TAPI commands */
  1384. #else
  1385.     "tapi",       XXNOTAV, CM_INV,
  1386. #endif /* CK_TAPI */
  1387.  
  1388. #ifndef NOFRILLS
  1389. #ifdef TCPSOCKET
  1390.     "tel",         XXTEL, CM_INV|CM_ABR,
  1391.     "telnet",      XXTEL, 0,        /* TELNET (TCP/IP only) */
  1392.     "telopt",      XXTELOP, CM_INV,     /* TELOPT (ditto) */
  1393. #else
  1394.     "tel",         XXNOTAV, CM_INV,
  1395.     "telnet",      XXNOTAV, CM_INV,
  1396.     "telopt",      XXNOTAV, CM_INV,
  1397. #endif /* TCPSOCKET */
  1398. #ifdef OS2
  1399.     "terminal",    XXTERM, 0,        /* == SET TERMINAL TYPE */
  1400. #else
  1401.     "terminal",    XXTERM, CM_INV,
  1402. #endif /* OS2 */
  1403. #endif /* NOFRILLS */
  1404. #ifndef NOXFER
  1405.     "text",        XXASC, CM_INV,    /* == SET FILE TYPE TEXT */
  1406. #endif /* NOXFER */
  1407.  
  1408. #ifndef NOSPL
  1409.     "trace",       XXTRACE, 0,        /* TRACE */
  1410. #else
  1411.     "trace",       XXNOTAV, CM_INV,
  1412. #endif /* NOSPL */
  1413.  
  1414. #ifndef NOCSETS
  1415.     "translate",   XXXLA, 0,        /* TRANSLATE local file char sets */
  1416. #else
  1417.     "translate",   XXNOTAV, CM_INV,
  1418. #endif /* NOCSETS */
  1419.  
  1420. #ifndef NOXMIT
  1421.     "transmit",    XXTRA, 0,        /* Send (upload) a file, no protocol */
  1422. #else
  1423.     "transmit",    XXNOTAV, CM_INV,
  1424. #endif /* NOXMIT */
  1425.  
  1426. #ifndef NOFRILLS
  1427.     "type",        XXTYP, 0,        /* Display a local file */
  1428. #endif /* NOFRILLS */
  1429.  
  1430. #ifndef NOSPL
  1431.     "undefine",    XXUNDEF, 0,        /* UNDEFINE a variable or macro */
  1432. #else
  1433.     "undefine",    XXNOTAV, CM_INV,
  1434. #endif /* NOSPL */
  1435.  
  1436. #ifdef COMMENT
  1437.     "updates",     XXUPD, 0,        /* View UPDATES file */
  1438. #endif /* COMMENT */
  1439.  
  1440.     "version",     XXVER, 0,        /* VERSION-number display */
  1441.  
  1442. #ifdef OS2
  1443.     "viewonly",    XXVIEW, 0,        /* VIEWONLY Terminal Mode */
  1444. #endif /* OS2 */
  1445.  
  1446. #ifndef NOSPL
  1447.     "wait",        XXWAI, 0,        /* WAIT (like pause) */
  1448. #else
  1449.     "wait",        XXNOTAV, CM_INV,
  1450. #endif /* NOSPL */
  1451.  
  1452.     "wermit",      XXKERMI, CM_INV,
  1453.  
  1454. #ifndef NOXFER
  1455.     "where",       XXWHERE, 0,        /* WHERE (did my file go?) */
  1456. #endif /* NOXFER */
  1457.  
  1458. #ifndef NOSPL
  1459.     "while",       XXWHI, 0,        /* WHILE loop */
  1460. #else
  1461.     "while",       XXNOTAV, CM_INV,
  1462. #endif /* NOSPL */
  1463.  
  1464. #ifndef OS2
  1465. #ifndef MAC
  1466. #ifndef NOFRILLS
  1467.     "who",         XXWHO, 0,        /* WHO's logged in? */
  1468. #endif /* NOFRILLS */
  1469. #endif /* MAC */
  1470. #endif /* OS2 */
  1471.  
  1472. #ifndef NOHELP
  1473.     "wildcards",   XXWILD,CM_INV|CM_HLP, /* Wildcard syntax */
  1474. #endif /* NOHELP */
  1475.  
  1476. #ifndef NOSPL
  1477.     "wr",          XXWRI, CM_INV|CM_ABR,
  1478.     "wri",         XXWRI, CM_INV|CM_ABR,
  1479.     "writ",        XXWRI, CM_INV|CM_ABR,
  1480.     "write",       XXWRI, 0,        /* WRITE characters to a file */
  1481.     "write-line",  XXWRL, CM_INV,    /* WRITE a line to a file */
  1482.     "writeln",     XXWRL, CM_INV,    /* Pascalisch synonym for write-line */
  1483. #else
  1484.     "wr",          XXNOTAV, CM_INV,
  1485.     "wri",         XXNOTAV, CM_INV,
  1486.     "writ",        XXNOTAV, CM_INV,
  1487.     "write",       XXNOTAV, CM_INV,
  1488.     "write-line",  XXNOTAV, CM_INV,
  1489.     "writeln",     XXNOTAV, CM_INV,
  1490. #endif /* NOSPL */
  1491.  
  1492. #ifndef NOFRILLS
  1493.     "xecho",       XXXECH,0,        /* XECHO */
  1494. #endif /* NOFRILLS */
  1495.  
  1496. #ifndef NOSPL
  1497.     "xif",         XXIFX, CM_INV,    /* Extended IF command (obsolete) */
  1498. #else
  1499.     "xif",         XXNOTAV, CM_INV,
  1500. #endif /* NOSPL */
  1501.  
  1502. #ifndef NOCSETS
  1503.     "xlate",       XXXLA, CM_INV,    /* Synonym for TRANSLATE */
  1504. #else
  1505.     "xlate",       XXNOTAV, CM_INV,
  1506. #endif /* NOCSETS */
  1507.  
  1508. #ifndef NOXMIT
  1509.     "xmit",        XXTRA, CM_INV,    /* Synonym for TRANSMIT */
  1510. #else
  1511.     "xmit",        XXNOTAV, CM_INV,
  1512. #endif /* NOXMIT */
  1513.  
  1514. #ifndef OS2
  1515. #ifndef NOJC
  1516.     "z",           XXSUS, CM_INV,    /* Synonym for SUSPEND */
  1517. #else
  1518.     "z",           XXNOTAV, CM_INV,
  1519. #endif /* NOJC */
  1520. #endif /* OS2 */
  1521.  
  1522. #ifdef CK_RECALL
  1523.     "^",           XXREDO,CM_INV|CM_NOR, /* Synonym for REDO */
  1524. #endif /* CK_RECALL */
  1525. #ifndef NOSPL
  1526.     "_asg",        XXASX,   CM_INV,    /* Used internally by FOR, etc */
  1527.     "_assign",     XXASX,   CM_INV,    /* Used internally by FOR, etc */
  1528.     "_decrement",  XX_DECR, CM_INV,
  1529.     "_define",     XXDFX,   CM_INV,    /* Used internally by FOR, etc */
  1530.     "_evaluate",   XX_EVAL, CM_INV,
  1531.     "_forward",    XXXFWD,  CM_INV,    /* Used internally by SWITCH   */
  1532.     "_getargs",    XXGTA,   CM_INV,    /* Used internally by FOR, etc */
  1533.     "_increment",  XX_INCR, CM_INV,
  1534.     "_putargs",    XXPTA,   CM_INV,    /* Used internally by FOR, etc */
  1535. #endif /* NOSPL */
  1536.       "", 0, 0
  1537. };
  1538. int ncmd = (sizeof(cmdtab) / sizeof(struct keytab)) - 1;
  1539.  
  1540. char toktab[] = {
  1541. #ifndef NOPUSH
  1542.     '!',                /* Shell escape */
  1543. #endif /* NOPUSH */
  1544.     '#',                /* Comment */
  1545. #ifndef NOSPL
  1546.     '.',                /* Assignment */
  1547. #endif /* NOSPL */
  1548.     ';',                /* Comment */
  1549. #ifndef NOSPL
  1550.     ':',                /* Label */
  1551. #endif /* NOSPL */
  1552. #ifndef NOPUSH
  1553. #ifdef CK_REDIR
  1554.     '<',                /* REDIRECT */
  1555. #endif /* CK_REDIR */
  1556.     '@',                /* DCL escape */
  1557. #endif /* NOPUSH */
  1558. #ifdef CK_RECALL
  1559.     '^',                /* Command recall */
  1560. #endif /* CK_RECALL */
  1561. #ifndef NOSPL
  1562.     '{',                /* Immediate macro */
  1563. #endif /* NOSPL */
  1564.     '\0'                /* End of this string */
  1565. };
  1566. int xxdot = 0;                /* Used with "." token */
  1567.  
  1568. struct keytab yesno[] = {        /* Yes/No keyword table */
  1569.     "no",    0, 0,
  1570.     "ok",    1, 0,
  1571.     "yes",   1, 0
  1572. };
  1573. int nyesno = (sizeof(yesno) / sizeof(struct keytab));
  1574.  
  1575. /* Save keyword table */
  1576.  
  1577. struct keytab savtab[] = {
  1578. #ifdef OS2
  1579.     "command",  XSCMD, 0,
  1580. #endif /* OS2 */
  1581. #ifndef NOSETKEY
  1582.     "keymap",   XSKEY, 0,
  1583. #endif    /* NOSETKEY */
  1584. #ifdef OS2
  1585.     "terminal", XSTERM, 0,
  1586. #endif /* OS2 */
  1587.     "",     0,     0
  1588. };
  1589. int nsav = (sizeof(savtab) / sizeof(struct keytab)) - 1;
  1590.  
  1591. /* Parameter keyword table */
  1592.  
  1593. struct keytab prmtab[] = {
  1594.     "alarm",            XYALRM,  0,
  1595.     "ask-timer",        XYTIMER, 0,
  1596. #ifndef NOXFER
  1597.     "attributes",       XYATTR,  0,
  1598. #endif /* NOXFER */
  1599. #ifdef CK_AUTHENTICATION
  1600.     "authentication",   XYAUTH,  0,
  1601. #else /* CK_AUTHENTICATION */
  1602. #ifdef CK_SSL
  1603.     "authentication",   XYAUTH,  0,
  1604. #endif /* CK_SSL */
  1605. #endif /* CK_AUTHENTICATION */
  1606.     "b",        XYBACK,  CM_INV|CM_ABR,
  1607.     "ba",        XYBACK,  CM_INV|CM_ABR,
  1608. #ifdef VMS
  1609.     "background",       XYBACK,  CM_INV,
  1610.     "batch",            XYBACK,  0,
  1611. #else
  1612.     "background",       XYBACK,  0,
  1613.     "batch",            XYBACK,  CM_INV,
  1614. #endif /* VMS */
  1615. #ifndef NOLOCAL
  1616.     "baud",            XYSPEE,  CM_INV,
  1617. #endif /* NOLOCAL */
  1618.     "bell",             XYBELL,  0,
  1619. #ifndef NOXFER
  1620.     "block-check",      XYCHKT,  0,
  1621. #endif /* NOXFER */
  1622. #ifdef OS2
  1623. #ifdef BPRINT
  1624.     "bprinter",         XYBDCP,  CM_INV,
  1625. #endif /* BPRINT */
  1626. #endif /*  OS2 */
  1627. #ifdef BROWSER
  1628.     "browser",          XYBROWSE,0,
  1629. #endif /* BROWSER */
  1630. #ifndef NOXFER
  1631. #ifdef DYNAMIC
  1632.     "buffers",          XYBUF,   0,
  1633. #endif /* DYNAMIC */
  1634. #endif /* NOXFER */
  1635. #ifndef NOLOCAL
  1636. #ifndef MAC
  1637.     "carrier-watch",    XYCARR,  0,
  1638. #endif /* MAC */
  1639. #endif /* NOLOCAL */
  1640. #ifndef NOSPL
  1641.     "case",             XYCASE,  0,
  1642. #endif /* NOSPL */
  1643.     "cd",               XYCD,    0,
  1644. #ifndef NOXFER
  1645.     "cl",               XYCLEAR, CM_INV|CM_ABR,
  1646.     "cle",              XYCLEAR, CM_INV|CM_ABR,
  1647.     "clea",             XYCLEAR, CM_INV|CM_ABR,
  1648.     "clear",            XYCLEAR, CM_INV|CM_ABR,
  1649.     "clear-channel",    XYCLEAR, 0,
  1650.     "clearchannel",     XYCLEAR, CM_INV,
  1651. #endif /* NOXFER */
  1652. #ifndef NOLOCAL
  1653.     "close-on-disconnect", XYDISC, CM_INV,
  1654. #endif /* NOLOCAL */
  1655.     "cmd",              XYCMD,   CM_INV,
  1656.     "command",          XYCMD,   0,
  1657. #ifdef CK_SPEED
  1658.     "con",              XYQCTL,  CM_INV|CM_ABR,
  1659. #endif /* CK_SPEED */
  1660.     "console",          XYCMD,   CM_INV,
  1661. #ifdef CK_SPEED
  1662.     "control-character",XYQCTL,  0,
  1663. #endif /* CK_SPEED */
  1664. #ifndef NOSPL
  1665.     "count",            XYCOUN,  0,
  1666. #endif /* NOSPL */
  1667. #ifndef NOXFER
  1668.     "d",        XYDELA,  CM_INV|CM_ABR,
  1669.     "de",        XYDELA,  CM_INV|CM_ABR,
  1670. #endif /* NOXFER */
  1671.     "debug",            XYDEBU,  CM_INV,
  1672. #ifdef VMS
  1673.     "default",          XYDFLT,  0,
  1674. #else
  1675. #ifndef MAC
  1676.     "default",          XYDFLT,  CM_INV,
  1677. #endif /* MAC */
  1678. #endif /* VMS */
  1679. #ifndef NOXFER
  1680.     "delay",            XYDELA,  0,
  1681.     "destination",    XYDEST,  0,
  1682. #endif /* NOXFER */
  1683. #ifndef NODIAL
  1684.     "di",        XYDIAL,  CM_INV|CM_ABR,
  1685.     "dia",        XYDIAL,  CM_INV|CM_ABR,
  1686.     "dial",             XYDIAL,  0,
  1687. #endif /* NODIAL */
  1688. #ifdef OS2
  1689.     "dialer",        XYDLR,   CM_INV,
  1690. #endif /* OS2 */
  1691. #ifndef NOLOCAL
  1692.     "disconnect",       XYDISC,  0,
  1693.     "duplex",            XYDUPL,  0,
  1694. #endif /* NOLOCAL */
  1695. #ifndef NOPUSH
  1696. #ifndef NOFRILLS
  1697.     "editor",           XYEDIT,  0,
  1698. #endif /*  NOFRILLS */
  1699. #endif /* NOPUSH */
  1700. #ifdef CK_CTRLZ
  1701.     "eof",              XYEOF,   CM_INV,
  1702. #endif /* CK_CTRLZ */
  1703. #ifndef NOLOCAL
  1704.     "escape-character", XYESC,   0,
  1705. #endif /* NOLOCAL */
  1706. #ifndef NOSPL
  1707.     "evaluate",         XYEVAL,  CM_INV,
  1708. #endif /* NOSPL */
  1709.     "exit",        XYEXIT,  0,
  1710. #ifndef NOXFER
  1711.     "f-ack-bug",        XYFACKB, CM_INV,
  1712.     "f-ack-path",       XYFACKP, CM_INV,
  1713. #endif /* NOXFER */
  1714.     "file",           XYFILE,  0,
  1715.     "fl",               XYFLOW,  CM_INV|CM_ABR,
  1716. #ifndef NOSPL
  1717.     "flag",             XYFLAG,  0,
  1718. #endif /* NOSPL */
  1719. #ifdef BROWSER
  1720.     "ftp-client",       XYFTP,   0,
  1721. #endif /* BROWSER */
  1722.     "flow-control",     XYFLOW,  0,
  1723. #ifndef NOSPL
  1724.     "function",         XYFUNC,  0,
  1725. #endif /* NOSPL */
  1726.     "handshake",        XYHAND,  0,
  1727.     "hints",            XYHINTS, 0,
  1728. #ifdef NETCONN
  1729.     "host",             XYHOST,  0,
  1730. #endif /* NETCONN */
  1731. #ifndef NOSPL
  1732.     "i",        XYINPU,  CM_INV|CM_ABR,
  1733.     "in",        XYINPU,  CM_INV|CM_ABR,
  1734. #endif /* NOSPL */
  1735. #ifndef NOXFER
  1736.     "incomplete",       XYIFD,   CM_INV,
  1737. #endif /* NOXFER */
  1738. #ifndef NOSPL
  1739.     "input",            XYINPU,  0,
  1740. #endif /* NOSPL */
  1741. #ifndef NOSETKEY
  1742.     "key",        XYKEY,   0,
  1743. #endif /* NOSETKEY */
  1744.     "l",                XYLINE,  CM_INV|CM_ABR,
  1745. #ifndef NOCSETS
  1746.     "language",         XYLANG,  0,
  1747. #endif /* NOCSETS */
  1748. #ifndef NOLOCAL
  1749.     "line",             XYLINE,  0,
  1750.     "local-echo",    XYLCLE,  CM_INV,
  1751. #endif /* NOLOCAL */
  1752. #ifndef NOSPL
  1753.     "login",        XYLOGIN, 0,
  1754. #endif /* NOSPL */
  1755. #ifndef NOSPL
  1756.     "macro",            XYMACR,  0,
  1757. #endif /* NOSPL */
  1758. #ifdef COMMENT
  1759. #ifdef VMS
  1760.     "messages",         XYMSGS,  0,
  1761. #endif /* VMS */
  1762. #endif /* COMMENT */
  1763. #ifndef NODIAL
  1764.     "modem",        XYMODM,     0,
  1765. #endif /* NODIAL */
  1766. #ifndef NOLOCAL
  1767. #ifdef OS2MOUSE
  1768.     "mouse",        XYMOUSE, 0,
  1769. #endif /* OS2MOUSE */
  1770. #endif /* NOLOCAL */
  1771. #ifdef OS2
  1772.     "mskermit",         XYMSK,   0,
  1773. #endif /* OS2 */
  1774. #ifdef NETCONN
  1775.     "network",          XYNET,   0,
  1776. #endif /* NETCONN */
  1777. #ifndef NOSPL
  1778.     "output",           XYOUTP,  0,
  1779. #endif /* NOSPL */
  1780.     "options",          XYOPTS,  0,
  1781.     "pause",            XYSLEEP, CM_INV,
  1782. #ifdef ANYX25
  1783. #ifndef IBMX25
  1784.     "pad",              XYPAD,   0,
  1785. #endif /* IBMX25 */
  1786. #endif /* ANYX25 */
  1787.     "parity",            XYPARI,   0,
  1788. #ifndef NOLOCAL
  1789. #ifdef OS2
  1790.     "port",             XYLINE,   0,
  1791. #else
  1792.     "port",             XYLINE,   CM_INV,
  1793. #endif /* OS2 */
  1794. #endif /* NOLOCAL */
  1795. #ifndef NOFRILLS
  1796.     "pr",               XYPROM,  CM_INV|CM_ABR,
  1797.     "printer",          XYPRTR,  0,
  1798. #endif /* NOFRILLS */
  1799. #ifdef OS2
  1800.     "priority",         XYPRTY,  0,
  1801. #endif /* OS2 */
  1802. #ifdef CK_SPEED
  1803.     "prefixing",        XYPREFIX, 0,
  1804. #endif /* CK_SPEED */
  1805. #ifndef NOFRILLS
  1806.     "prompt",            XYPROM,  0,
  1807. #endif /* NOFRILLS */
  1808. #ifndef NOXFER
  1809.     "protocol",        XYPROTO, 0,
  1810. #endif /* NOXFER */
  1811.     "q",        XYQUIE,  CM_INV|CM_ABR,
  1812. #ifndef NOXFER
  1813.     "q8flag",           XYQ8FLG, CM_INV,
  1814. #endif /* NOXFER */
  1815. #ifdef QNX
  1816.     "qnx-port-lock",    XYQNXPL, 0,
  1817. #else
  1818.     "qnx-port-lock",    XYQNXPL, CM_INV,
  1819. #endif /* QNX */
  1820.     "quiet",        XYQUIE,  0,
  1821. #ifndef NOXFER
  1822.     "rec",              XYRECV,  CM_INV|CM_ABR,
  1823.     "receive",          XYRECV,  0,
  1824.     "recv",             XYRECV,  CM_INV,
  1825. #endif /* NOXFER */
  1826.     "reliable",         XYRELY,  0,
  1827. #ifndef NOXFER
  1828.     "repeat",           XYREPT,  0,
  1829.     "retry-limit",      XYRETR,  0,
  1830. #endif /* NOXFER */
  1831. #ifndef NOSCRIPT
  1832.     "script",        XYSCRI,  0,
  1833. #endif /* NOSCRIPT */
  1834. #ifndef NOXFER
  1835.     "send",             XYSEND,  0,
  1836. #ifndef NOLOCAL
  1837. #ifndef NOSERVER
  1838.     "ser",              XYSERV,  CM_INV|CM_ABR,
  1839. #endif /* NOSERVER */
  1840. #endif /* NOXFER */
  1841.     "serial",           XYSERIAL,0,
  1842. #endif /* NOLOCAL */
  1843. #ifndef NOSERVER
  1844.     "server",           XYSERV,  0,
  1845. #endif /* NOSERVER */
  1846. #ifdef SESLIMIT
  1847. #ifndef NOLOCAL
  1848.     "session-l",        XYSESS,  CM_INV|CM_ABR,
  1849. #endif /* NOLOCAL */
  1850.     "session-limit",    XYLIMIT, CM_INV,        /* Session Limit */
  1851. #endif /* SESLIMIT */
  1852.  
  1853. #ifndef NOLOCAL
  1854. #ifdef OS2ORUNIX
  1855.     "session-log",      XYSESS,  0,
  1856. #else
  1857. #ifdef OSK
  1858.     "session-log",      XYSESS,  0,
  1859. #endif /* OSK */
  1860. #endif /* OS2ORUNIX */
  1861. #endif /* NOLOCAL */
  1862.  
  1863.     "sleep",            XYSLEEP, 0,
  1864.  
  1865. #ifndef NOLOCAL
  1866.     "speed",            XYSPEE,  0,
  1867. #endif /* NOLOCAL */
  1868.  
  1869. #ifndef NOSPL
  1870.     "startup-file",     XYSTARTUP, CM_INV,
  1871. #endif /* NOSPL */
  1872.  
  1873. #ifndef NOLOCAL
  1874. #ifdef HWPARITY
  1875.     "stop-bits",        XYSTOP, 0,
  1876. #endif /* HWPARITY */
  1877. #endif /* NOLOCAL */
  1878.  
  1879. #ifndef NOXFER
  1880. #ifdef STREAMING
  1881.     "streaming",        XYSTREAM, 0,
  1882. #endif /* STREAMING */
  1883. #endif /* NOXFER */
  1884.  
  1885. #ifndef NOJC
  1886.     "suspend",          XYSUSP,  0,
  1887. #endif /* NOJC */
  1888. #ifdef CKSYSLOG
  1889.     "syslog",           XYSYSL,  CM_INV,
  1890. #endif /* CKSYSLOG */
  1891.     "take",             XYTAKE,  0,
  1892.  
  1893. #ifdef CK_TAPI
  1894.     "tapi",             XYTAPI,  0,
  1895. #endif /* CK_TAPI */
  1896.  
  1897. #ifndef NOTCPOPTS
  1898. #ifdef TCPSOCKET
  1899.     "tcp",              XYTCP, 0,
  1900. #endif /* TCPSOCKET */
  1901. #endif /* NOTCPOPTS */
  1902.  
  1903. #ifdef TNCODE
  1904.     "tel",              XYTEL,   CM_INV|CM_ABR,
  1905.     "telnet",           XYTEL,   0,
  1906.     "telopt",           XYTELOP, 0,
  1907. #endif /* TNCODE */
  1908.  
  1909. #ifndef NOSPL
  1910.     "temp-directory",   XYTMPDIR,0,
  1911. #endif /* NOSPL */
  1912.  
  1913. #ifndef NOLOCAL
  1914.     "terminal",         XYTERM,  0,
  1915. #endif /* NOLOCAL */
  1916.  
  1917. #ifdef OS2
  1918.     "title",        XYTITLE, 0,
  1919. #endif /* OS2 */
  1920. #ifdef TLOG
  1921.     "transaction-log",  XYTLOG,  0,
  1922. #endif /* TLOG */
  1923. #ifndef NOXFER
  1924.     "transfer",         XYXFER,  0,
  1925. #endif /* NOXFER */
  1926. #ifndef NOXMIT
  1927.     "transmit",         XYXMIT,  0,
  1928. #endif /* NOXMIT */
  1929. #ifndef NOXFER
  1930. #ifndef NOCSETS
  1931.     "unknown-char-set", XYUNCS,  0,
  1932. #endif /* NOCSETS */
  1933. #endif /* NOXFER */
  1934.     "wait",             XYSLEEP, CM_INV,
  1935. #ifndef NOPUSH
  1936. #ifdef UNIX
  1937.     "wildcard-expansion", XYWILD, 0,
  1938. #endif /* UNIX */
  1939. #endif /* NOPUSH */
  1940. #ifdef NT
  1941.     "w",                XYWIND,  CM_INV|CM_ABR,
  1942.     "wi",               XYWIND,  CM_INV|CM_ABR,
  1943.     "win",              XYWIND,  CM_INV|CM_ABR,
  1944. #endif /* NT */
  1945.     "window-size",      XYWIND,  0,
  1946. #ifdef NT
  1947.     "win95",            XYWIN95, 0,
  1948. #endif /* NT */
  1949. #ifdef ANYX25
  1950.     "x.25",             XYX25,   0,
  1951.     "x25",              XYX25,   CM_INV,
  1952. #endif /* ANYX25 */
  1953.     "xfer",             XYXFER,  CM_INV,
  1954. #ifndef NOXMIT
  1955.     "xmit",             XYXMIT,  CM_INV,
  1956. #endif /* NOXMIT */
  1957.     "", 0, 0
  1958. };
  1959. int nprm = (sizeof(prmtab) / sizeof(struct keytab)) - 1; /* How many */
  1960.  
  1961. struct keytab scntab[] = {
  1962.     "clear",   SCN_CLR, 0,
  1963.     "cleol",   SCN_CLE, 0,
  1964.     "move-to", SCN_MOV, 0
  1965. };
  1966. int nscntab = (sizeof(scntab) / sizeof(struct keytab)); /* How many */
  1967.  
  1968. /* Table of networks */
  1969. #ifdef NETCONN
  1970. struct keytab netkey[] = {
  1971.     "directory",     XYNET_D,  0,
  1972.     "type",          XYNET_T,  0
  1973. };
  1974. int nnetkey = (sizeof(netkey) / sizeof(struct keytab));
  1975.  
  1976. struct keytab netcmd[] = {
  1977. /*
  1978.   These are the network types.
  1979. */
  1980. #ifdef NETCMD
  1981.     "command",       NET_CMD,  CM_INV,    /* Command */
  1982. #endif /* NETCMD */
  1983.  
  1984. #ifdef DECNET                /* DECnet / PATHWORKS */
  1985.     "decnet",        NET_DEC,  0,
  1986. #endif /* DECNET */
  1987.  
  1988. #ifdef NETDLL
  1989.     "dll",           NET_DLL,  CM_INV,  /* DLL to be loaded */
  1990. #endif /* NETDLL */
  1991.  
  1992. #ifdef NETFILE
  1993.     "file",           NET_FILE, CM_INV,  /* FILE (real crude) */
  1994. #endif /* NETFILE */
  1995.  
  1996. #ifdef NPIPE                /* Named Pipes */
  1997.     "named-pipe",     NET_PIPE,  0,
  1998. #endif /* NPIPE */
  1999.  
  2000. #ifdef CK_NETBIOS
  2001.     "netbios",        NET_BIOS,  0,    /* NETBIOS */
  2002. #endif /* CK_NETBIOS */
  2003.  
  2004. #ifdef DECNET                /* DECnet / PATHWORKS (alias) */
  2005.     "pathworks",     NET_DEC,  CM_INV,
  2006. #endif /* DECNET */
  2007.  
  2008. #ifdef NETCMD
  2009.     "pipe",          NET_CMD,  0,    /* Pipe */
  2010. #endif /* NETCMD */
  2011.  
  2012. #ifdef NETPTY
  2013.     "pseudoterminal", NET_PTY, 0,    /* Pseudoterminal */
  2014. #endif /* NETPTY */
  2015.  
  2016. #ifdef NETPTY
  2017.     "pty",           NET_PTY,  CM_INV,    /* Invisible synonym for pseudoterm */
  2018. #endif /* NETPTY */
  2019.  
  2020. #ifdef SSH
  2021.     "ssh",           NET_SSH,  CM_INV,  /* SSH */
  2022. #endif /* SSH */
  2023.  
  2024. #ifdef SUPERLAT
  2025.    "superlat",        NET_SLAT,  0,    /* Meridian Technologies' SuperLAT */
  2026. #endif /* SUPERLAT */
  2027.  
  2028. #ifdef TCPSOCKET            /* TCP/IP sockets library */
  2029.     "tcp/ip",       NET_TCPB,    0,
  2030. #endif /* TCPSOCKET */
  2031. #ifdef SUPERLAT
  2032.     "tes32",        NET_SLAT,   0,    /* Emulux TES32 */
  2033. #endif /* SUPERLAT */
  2034. #ifdef ANYX25                /* X.25 */
  2035. #ifdef SUNX25
  2036.     "x",            NET_SX25, CM_INV|CM_ABR,
  2037.     "x.25",         NET_SX25, 0,
  2038.     "x25",          NET_SX25, CM_INV,
  2039. #else
  2040. #ifdef STRATUSX25
  2041.     "x",            NET_VX25, CM_INV|CM_ABR,
  2042.     "x.25",         NET_VX25, 0,
  2043.     "x25",          NET_VX25, CM_INV,
  2044. #endif /* STRATUSX25 */
  2045. #endif /* SUNX25 */
  2046. #ifdef IBMX25
  2047.     "x",            NET_IX25, CM_INV|CM_ABR,
  2048.     "x.25",         NET_IX25, CM_INV,
  2049.     "x25",          NET_IX25, CM_INV,
  2050. #endif /* IBMX25 */
  2051. #ifdef HPX25
  2052.     "x",            NET_IX25, CM_INV|CM_ABR,
  2053.     "x.25",         NET_IX25, 0,
  2054.     "x25",          NET_IX25, CM_INV,
  2055. #endif /* HPX25 */
  2056. #endif /* ANYX25 */
  2057.     "", 0, 0
  2058. };
  2059. int nnets = (sizeof(netcmd) / sizeof(struct keytab));
  2060.  
  2061. #ifndef NOTCPOPTS
  2062. #ifdef TCPSOCKET
  2063.  
  2064. /* TCP options */
  2065.  
  2066. struct keytab tcpopt[] = {
  2067.    "address",   XYTCP_ADDRESS, 0,
  2068. #ifdef CK_DNS_SRV
  2069.    "dns-service-records", XYTCP_DNS_SRV, 0,
  2070. #endif /* CK_DNS_SRV */
  2071. #ifdef SO_DONTROUTE
  2072.     "dontroute",   XYTCP_DONTROUTE, 0,
  2073. #endif /* SO_DONTROUTE */
  2074. #ifdef SO_KEEPALIVE
  2075.    "keepalive", XYTCP_KEEPALIVE, 0,
  2076. #endif /* SO_KEEPALIVE */
  2077. #ifdef SO_LINGER
  2078.    "linger", XYTCP_LINGER, 0,
  2079. #endif  /* SO_LINGER */
  2080. #ifdef TCP_NODELAY
  2081.    "nagle",  XYTCP_NAGLE,    CM_INV,
  2082.    "nodelay", XYTCP_NODELAY, 0,
  2083. #endif /* TCP_NODELAY */
  2084.    "reverse-dns-lookup", XYTCP_RDNS, 0,
  2085. #ifdef SO_RCVBUF
  2086.    "recvbuf", XYTCP_RECVBUF, 0,
  2087. #endif /* SO_RCVBUF */
  2088. #ifdef SO_SNDBUF
  2089.    "sendbuf", XYTCP_SENDBUF, 0,
  2090. #endif /* SO_SNDBUF */
  2091. #ifdef VMS
  2092. #ifdef DEC_TCPIP
  2093.    "ucx-port-bug", XYTCP_UCX, 0,
  2094. #endif /* DEC_TCPIP */
  2095. #endif /* VMS */
  2096.    "",0,0
  2097. };
  2098. int ntcpopt = (sizeof(tcpopt) / sizeof(struct keytab));
  2099.  
  2100. #endif /* TCPSOCKET */
  2101. #endif /* NOTCPOPTS */
  2102.  
  2103. #endif /* NETCONN */
  2104.  
  2105. #ifdef OS2
  2106. /* K95 Manual Chapter Table -- Keep these two tables in sync! */
  2107.  
  2108. static char * linktbl[] = {        /* Internal links in k95.htm */
  2109.     "#top",                /* 00 */
  2110.     "#what",                /* 01 */
  2111.     "#install",                /* 02 */
  2112.     "#start",                /* 03 */
  2113.     "#dialer",                /* 04 */
  2114.     "#entries",                /* 05 */
  2115.     "#command",                /* 06 */
  2116.     "#terminal",            /* 07 */
  2117.     "#transfer",            /* 08 */
  2118.     "#hostmode"                /* 09 */
  2119. };
  2120.  
  2121. static struct keytab chaptbl[] = {
  2122.     "Command-Screen",     6, 0,
  2123.     "Contents",           0, 0,
  2124.     "Dialer-Entries",     5, 0,
  2125.     "File-Transfer",      8, 0,
  2126.     "Getting-Started",    3, 0,
  2127.     "Host-Mode",          9, 0,
  2128.     "Installation",       2, 0,
  2129.     "Terminal-Emulation", 7, 0,
  2130.     "Using-The-Dialer",   4, 0,
  2131.     "What-Is-K95",        1, 0,
  2132.     "",                   0, 0,
  2133. };
  2134. static int nchaptbl = (sizeof(chaptbl) / sizeof(struct keytab));
  2135. #endif /* OS2 */
  2136.  
  2137. #ifndef NOXFER
  2138. /* Remote Command Table */
  2139.  
  2140. struct keytab remcmd[] = {
  2141. #ifndef NOSPL
  2142.     "as",     XZASG, CM_INV|CM_ABR,    /*  */
  2143.     "asg",     XZASG, CM_INV,
  2144.     "assign",     XZASG, 0,
  2145. #endif /* NOSPL */
  2146.     "cd",        XZCWD, 0,
  2147.     "copy",      XZCPY, 0,
  2148.     "cwd",       XZCWD, CM_INV,
  2149.     "delete",    XZDEL, 0,
  2150.     "directory", XZDIR, 0,
  2151.     "exit",      XZXIT, 0,
  2152.     "help",      XZHLP, 0,
  2153. #ifndef NOPUSH
  2154.     "host",      XZHOS, 0,
  2155. #endif /* NOPUSH */
  2156. #ifndef NOFRILLS
  2157.     "kermit",    XZKER, 0,
  2158.     "l",         XZLGI, CM_ABR|CM_INV,
  2159.     "lo",        XZLGI, CM_ABR|CM_INV,
  2160.     "log",       XZLGI, CM_ABR|CM_INV,
  2161.     "login",     XZLGI, 0,
  2162.     "logout",    XZLGO, 0,
  2163.     "mkdir",     XZMKD, 0,
  2164.     "print",     XZPRI, 0,
  2165. #endif /* NOFRILLS */
  2166.     "pwd",       XZPWD, 0,
  2167. #ifndef NOSPL
  2168.     "query",     XZQUE, 0,
  2169. #endif /* NOSPL */
  2170.     "rename",    XZREN, 0,
  2171.     "rmdir",     XZRMD, 0,
  2172.     "set",       XZSET, 0,
  2173.     "space",     XZSPA, 0
  2174. #ifndef NOFRILLS
  2175. ,   "type",      XZTYP, 0,
  2176.     "who",       XZWHO, 0
  2177. #endif /* NOFRILLS */
  2178. };
  2179. int nrmt = (sizeof(remcmd) / sizeof(struct keytab));
  2180. #endif /* NOXFER */
  2181.  
  2182. struct keytab logtab[] = {
  2183. #ifdef CKLOGDIAL
  2184.     "connections",  LOGM, CM_INV,
  2185.     "cx",           LOGM, 0,
  2186. #endif /* CKLOGDIAL */
  2187. #ifdef DEBUG
  2188.     "debugging",    LOGD, 0,
  2189. #endif /* DEBUG */
  2190.     "packets",        LOGP, 0,
  2191. #ifndef NOLOCAL
  2192.     "session",      LOGS, 0,
  2193. #endif /* NOLOCAL */
  2194. #ifdef TLOG
  2195.     "transactions", LOGT, 0,
  2196. #endif /* TLOG */
  2197.     "", 0, 0
  2198. };
  2199. int nlog = (sizeof(logtab) / sizeof(struct keytab)) - 1;
  2200.  
  2201. struct keytab writab[] = {
  2202. #ifndef NOSPL
  2203.     "append-file",     LOGW, CM_INV,
  2204. #endif /* NOSPL */
  2205.     "debug-log",       LOGD, 0,
  2206.     "error",           LOGE, 0,
  2207. #ifndef NOSPL
  2208.     "file",            LOGW, 0,
  2209. #endif /* NOSPL */
  2210.     "packet-log",      LOGP, 0,
  2211.     "screen",          LOGX, 0,
  2212. #ifndef NOLOCAL
  2213.     "session-log",     LOGS, 0,
  2214. #endif /* NOLOCAL */
  2215.     "sys$output",      LOGX, CM_INV,
  2216.     "t",               LOGT, CM_ABR|CM_INV, /* Because of a typo in */
  2217.     "tr",              LOGT, CM_ABR|CM_INV, /* the book... */
  2218.     "tra",             LOGT, CM_ABR|CM_INV,
  2219.     "tran",            LOGT, CM_ABR|CM_INV,
  2220.     "trans",           LOGT, CM_ABR|CM_INV,
  2221.     "transa",          LOGT, CM_ABR|CM_INV,
  2222.     "transac",         LOGT, CM_ABR|CM_INV,
  2223.     "transact",        LOGT, CM_ABR|CM_INV,
  2224.     "transacti",       LOGT, CM_ABR|CM_INV,
  2225.     "transactio",      LOGT, CM_ABR|CM_INV,
  2226.     "transaction",     LOGT, CM_ABR|CM_INV,
  2227.     "transaction-log", LOGT, 0,
  2228.     "transactions",    LOGT, CM_INV
  2229. };
  2230. int nwri = (sizeof(writab) / sizeof(struct keytab));
  2231.  
  2232. #ifdef COMMENT                /* INPUT switches not used yet... */
  2233. static struct keytab inswtab[] = {
  2234. #ifdef COMMENT
  2235.     "/assign",       IN_ASG, CM_ARG,
  2236. #endif /* COMMENT */
  2237.     "/autodownload", IN_ADL, CM_ARG,
  2238.     "/case",         IN_CAS, CM_ARG,
  2239.     "/echo",         IN_ECH, CM_ARG,
  2240.     "/interrupts",   IN_NOI, CM_ARG,
  2241.     "/silence",      IN_SIL, CM_ARG,
  2242. #ifdef COMMENT
  2243.     "/pattern",      IN_PAT, CM_ARG,
  2244. #endif /* COMMENT */
  2245.     "", 0, 0
  2246. };
  2247. static int ninswtab = (sizeof(inswtab) / sizeof(struct keytab)) - 1;
  2248. #endif /* COMMENT */
  2249.  
  2250. static struct keytab clrtab[] = {    /* Keywords for CLEAR command */
  2251. #ifndef NOSPL
  2252.     "alarm",            CLR_ALR,         0,
  2253. #ifdef CK_APC
  2254.     "apc",              CLR_APC,         0,
  2255. #endif /* CK_APC */
  2256. #ifdef PATTERNS
  2257.     "binary-patterns",  CLR_BIN,         0,
  2258. #endif /* PATTERNS */
  2259.     "both",             CLR_DEV|CLR_INP, CM_INV,
  2260. #endif /* NOSPL */
  2261. #ifdef OS2
  2262.     "command-screen",   CLR_CMD,         0,
  2263. #endif /* OS2 */
  2264. #ifndef NOSPL
  2265.     "device",           CLR_DEV,         CM_INV|CM_ABR,
  2266.     "device-and-input", CLR_DEV|CLR_INP, 0,
  2267. #endif /* NOSPL */
  2268.     "device-buffer",    CLR_DEV,         0,
  2269. #ifndef NODIAL
  2270.     "dial-status",      CLR_DIA,     0,
  2271. #endif /* NODIAL */
  2272. #ifndef NOSPL
  2273.     "input-buffer",     CLR_INP,         0,
  2274. #endif /* NOSPL */
  2275.     "send-list",        CLR_SFL,         0,
  2276. #ifdef OS2
  2277.     "scr",              CLR_SCL,         CM_INV|CM_ABR,
  2278. #endif /* OS2 */
  2279.     "screen",           CLR_SCR,         0,
  2280. #ifdef OS2
  2281.     "scrollback",       CLR_SCL,         CM_INV,
  2282.     "terminal-screen",  CLR_TRM,         0,
  2283. #endif /* OS2 */
  2284. #ifdef PATTERNS
  2285.     "text-patterns",    CLR_TXT,         0,
  2286. #endif /* PATTERNS */
  2287.     "", 0, 0
  2288. };
  2289. int nclear = (sizeof(clrtab) / sizeof(struct keytab)) - 1;
  2290.  
  2291. struct keytab clstab[] = {        /* Keywords for CLOSE command */
  2292. #ifndef NOSPL
  2293.     "!read",           LOGR, CM_INV,
  2294.     "!write",          LOGW, CM_INV,
  2295. #ifndef NOPUSH
  2296. #endif /* NOPUSH */
  2297. #endif /* NOSPL */
  2298. #ifndef NOSPL
  2299.     "append-file",     LOGW, CM_INV,
  2300. #endif /* NOSPL */
  2301. #ifndef NOLOCAL
  2302.     "connection",      9999, 0,
  2303. #endif /* NOLOCAL */
  2304. #ifdef CKLOGDIAL
  2305.     "cx-log",          LOGM, 0,
  2306. #endif /* CKLOGDIAL */
  2307. #ifdef DEBUG
  2308.     "debug-log",       LOGD, 0,
  2309. #endif /* DEBUG */
  2310.     "host",            9999, CM_INV,    /* Synonym for CLOSE CONNECTION */
  2311.     "line",            9999, CM_INV,    /* Synonym for CLOSE CONNECTION */
  2312.     "packet-log",      LOGP, 0,
  2313.     "port",            9999, CM_INV,    /* Synonym for CLOSE CONNECTION */
  2314. #ifndef NOSPL
  2315.     "read-file",       LOGR, 0,
  2316. #endif /* NOSPL */
  2317. #ifndef NOLOCAL
  2318.     "session-log",     LOGS, 0,
  2319. #endif /* NOLOCAL */
  2320. #ifdef TLOG
  2321.     "t",               LOGT, CM_ABR|CM_INV, /* Because of a typo in */
  2322.     "tr",              LOGT, CM_ABR|CM_INV, /* the book... */
  2323.     "tra",             LOGT, CM_ABR|CM_INV,
  2324.     "tran",            LOGT, CM_ABR|CM_INV,
  2325.     "trans",           LOGT, CM_ABR|CM_INV,
  2326.     "transa",          LOGT, CM_ABR|CM_INV,
  2327.     "transac",         LOGT, CM_ABR|CM_INV,
  2328.     "transact",        LOGT, CM_ABR|CM_INV,
  2329.     "transacti",       LOGT, CM_ABR|CM_INV,
  2330.     "transactio",      LOGT, CM_ABR|CM_INV,
  2331.     "transaction",     LOGT, CM_ABR|CM_INV,
  2332.     "transaction-log", LOGT, 0,
  2333.     "transactions",    LOGT, CM_INV,
  2334. #endif /* TLOG */
  2335. #ifndef NOSPL
  2336.     "write-file",      LOGW, 0,
  2337. #endif /* NOSPL */
  2338.     "", 0, 0
  2339. };
  2340. int ncls = (sizeof(clstab) / sizeof(struct keytab)) - 1;
  2341.  
  2342. /* SHOW command arguments */
  2343.  
  2344. #ifndef NOSHOW
  2345. struct keytab shotab[] = {
  2346. #ifndef NOSPL
  2347.     "alarm", SHALRM, 0,
  2348.     "arg",  SHARG, CM_INV|CM_ABR,
  2349.     "arguments", SHARG, 0,
  2350.     "args", SHARG, CM_INV,
  2351.     "arrays", SHARR, 0,
  2352. #endif /* NOSPL */
  2353.  
  2354. #ifndef NOCSETS
  2355.     "associations", SHASSOC, 0,
  2356. #endif /* NOCSETS */
  2357.  
  2358. #ifndef NOXFER
  2359.     "attributes", SHATT, 0,
  2360. #endif /* NOXFER */
  2361.  
  2362. #ifdef CK_AUTHENTICATION
  2363.     "authentication", SHOAUTH, CM_INV,
  2364. #endif /* CK_AUTHENTICATION */
  2365.  
  2366. #ifndef NOPUSH
  2367. #ifdef BROWSER
  2368.     "browser", SHBROWSE, 0,
  2369. #endif /*  BROWSER */
  2370. #endif /* NOPUSH */
  2371.     "cd", SHCD, 0,
  2372.     "character-sets", SHCSE, 0,
  2373.     "cmd",  SHCMD, CM_INV,
  2374. #ifndef NOLOCAL
  2375.     "com",  SHCOM, CM_INV|CM_ABR,
  2376.     "comm", SHCOM, CM_INV|CM_ABR,
  2377.     "communications", SHCOM, 0,
  2378. #endif /* NOLOCAL */
  2379.     "command", SHCMD, 0,
  2380. #ifdef CK_SPEED
  2381.     "control-prefixing", SHCTL, 0,
  2382. #endif /* CK_SPEED */
  2383. #ifdef CKLOGDIAL
  2384.     "connection", SHCONNX, 0,
  2385.     "cx", SHCONNX, CM_INV,
  2386. #endif /* CKLOGDIAL */
  2387. #ifndef NOSPL
  2388.     "count", SHCOU, 0,
  2389. #endif /* NOSPL */
  2390.     "d",       SHDIA, CM_INV|CM_ABR,
  2391. #ifdef VMS
  2392.     "default", SHDFLT, 0,
  2393. #else
  2394.     "default", SHDFLT, CM_INV,
  2395. #endif /* VMS */
  2396. #ifndef NODIAL
  2397.     "dial", SHDIA, 0,
  2398. #endif /* NODIAL */
  2399.     "double/ignore", SHDBL, 0,
  2400. #ifndef NOPUSH
  2401. #ifndef NOFRILLS
  2402.     "editor",        SHEDIT, 0,
  2403. #endif /*  NOFRILLS */
  2404. #endif /* NOPUSH */
  2405. #ifndef NOLOCAL
  2406.     "escape", SHESC, 0,
  2407. #endif /* NOLOCAL */
  2408.     "exit", SHEXI, 0,
  2409.     "extended-options", SHXOPT, CM_INV,
  2410.     "features", SHFEA, 0,
  2411.     "file", SHFIL, 0,
  2412. #ifndef NOLOCAL
  2413.     "flow-control", SHOFLO, 0,
  2414. #endif /* NOLOCAL */
  2415. #ifdef BROWSER
  2416.     "ftp", SHOFTP, 0,
  2417. #endif /* BROWSER */
  2418. #ifndef NOSPL
  2419.     "functions", SHFUN, 0,
  2420.     "globals", SHVAR, 0,
  2421. #endif /* NOSPL */
  2422.     "ignore/double", SHDBL, CM_INV,
  2423. #ifndef NOSPL
  2424.     "input", SHINP, 0,
  2425. #endif /* NOSPL */
  2426. #ifndef NOSETKEY
  2427.     "k",   SHKEY, CM_INV|CM_ABR,
  2428.     "key", SHKEY, 0,
  2429. #ifndef NOKVERBS
  2430.     "kverbs", SHKVB, 0,
  2431. #endif /* NOKVERBS */
  2432. #endif /* NOSETKEY */
  2433. #ifdef CK_LABELED
  2434.     "labeled-file-info", SHLBL, 0,
  2435. #endif /* CK_LABELED */
  2436. #ifndef NOCSETS
  2437.     "languages", SHLNG, 0,
  2438. #endif /* NOCSETS */
  2439.     "logs", SHLOG, 0,
  2440. #ifndef NOSPL
  2441.     "macros", SHMAC, 0,
  2442. #endif /* NOSPL */
  2443. #ifndef NODIAL
  2444.     "modem", SHMOD, 0,
  2445. #else
  2446.     "modem-signals", SHCOM, CM_INV,
  2447. #endif /* NODIAL */
  2448. #ifndef NOLOCAL
  2449. #ifdef OS2MOUSE
  2450.     "mouse", SHMOU, 0,
  2451. #endif /* OS2MOUSE */
  2452. #endif /* NOLOCAL */
  2453. #ifdef NETCONN
  2454.     "network", SHNET, 0,
  2455. #else
  2456.     "network", SHNET, CM_INV,
  2457. #endif /* NETCONN */
  2458.     "options", SHOPTS, 0,
  2459. #ifndef NOSPL
  2460.     "output", SHOUTP, CM_INV,
  2461. #endif /* NOSPL */
  2462. #ifdef ANYX25
  2463. #ifndef IBMX25
  2464.     "pad", SHPAD, 0,
  2465. #endif /* IBMX25 */
  2466. #endif /* ANYX25 */
  2467.     "parameters", SHPAR, CM_INV,
  2468. #ifdef PATTERNS
  2469.     "patterns", SHOPAT, 0,
  2470. #endif /* PATTERNS */
  2471.     "printer",  SHPRT, 0,
  2472. #ifdef CK_SPEED
  2473.     "prefixing", SHCTL, CM_INV,
  2474. #endif /* CK_SPEED */
  2475. #ifndef NOXFER
  2476.     "protocol", SHPRO, 0,
  2477. #endif /* NOXFER */
  2478. #ifndef NOSPL
  2479.     "scripts", SHSCR, 0,
  2480. #endif /* NOSPL */
  2481.     "send-list", SHSFL, 0,
  2482. #ifndef NOSERVER
  2483.     "server", SHSER, 0,
  2484. #endif /* NOSERVER */
  2485.     "stack", SHSTK, 0,
  2486.     "status", SHSTA, 0,
  2487. #ifdef STREAMING
  2488.     "streaming", SHOSTR, 0,
  2489. #endif /* STREAMING */
  2490. #ifndef NOLOCAL
  2491. #ifdef OS2
  2492.     "tabs",SHTAB, CM_INV,
  2493. #endif /* OS2 */
  2494. #ifdef CK_TAPI
  2495.     "tapi",          SHTAPI, 0,
  2496.     "tapi-comm",     SHTAPI_C, CM_INV,
  2497.     "tapi-location", SHTAPI_L, CM_INV,
  2498.     "tapi-modem",    SHTAPI_M, CM_INV,
  2499. #endif /* CK_TAPI */
  2500. #ifdef TNCODE
  2501.     "tel",      SHTEL,  CM_INV|CM_ABR,
  2502.     "telnet",   SHTEL,  0,
  2503.     "telopt",   SHTOPT, 0,
  2504. #endif /* TNCODE */
  2505.     "terminal", SHTER, 0,
  2506. #endif /* NOLOCAL */
  2507. #ifndef NOXMIT
  2508.     "tr",    SHXMI, CM_INV|CM_ABR,
  2509.     "tra",   SHXMI, CM_INV|CM_ABR,
  2510.     "tran",  SHXMI, CM_INV|CM_ABR,
  2511.     "trans", SHXMI, CM_INV|CM_ABR,
  2512. #endif /* NOXMIT */
  2513. #ifndef NOXFER
  2514.     "transfer", SHOXFER, 0,
  2515. #endif /* NOXFER */
  2516. #ifndef NOXMIT
  2517.     "transmit", SHXMI, 0,
  2518. #endif /* NOXMIT */
  2519. #ifdef CK_TRIGGER
  2520.     "trigger", SHTRIG, 0,
  2521. #endif /* CK_TRIGGER */
  2522. #ifndef NOSETKEY
  2523. #ifndef NOKVERBS
  2524. #ifdef OS2
  2525.      "udk", SHUDK, 0,
  2526. #endif /* OS2 */
  2527. #endif /* NOKVERBS */
  2528. #endif /* NOSETKEY */
  2529. #ifndef NOSPL
  2530.     "variables", SHBUI, 0,
  2531. #endif /* NOSPL */
  2532. #ifndef NOFRILLS
  2533.     "versions", SHVER, 0,
  2534. #endif /* NOFRILLS */
  2535. #ifdef OS2
  2536.     "vscrn",    SHVSCRN, CM_INV,
  2537. #endif /* OS2 */
  2538.     "xfer", SHOXFER, CM_INV,
  2539. #ifndef NOXMIT
  2540.     "xmit", SHXMI, CM_INV,
  2541. #endif /* NOXMIT */
  2542.     "", 0, 0
  2543. };
  2544. int nsho = (sizeof(shotab) / sizeof(struct keytab)) - 1;
  2545. #endif /* NOSHOW */
  2546.  
  2547. #ifdef ANYX25
  2548. #ifndef IBMX25
  2549. struct keytab padtab[] = {              /* PAD commands */
  2550.     "clear",      XYPADL, 0,
  2551.     "interrupt",  XYPADI, 0,
  2552.     "reset",      XYPADR, 0,
  2553.     "status",     XYPADS, 0
  2554. };
  2555. int npadc = (sizeof(padtab) / sizeof(struct keytab));
  2556. #endif /* IBMX25 */
  2557. #endif /* ANYX25 */
  2558.  
  2559. #ifndef NOSERVER
  2560. static struct keytab kmstab[] = {
  2561.     "both",    3, 0,
  2562.     "remote",  2, 0,
  2563.     "local",   1, 0
  2564. };
  2565.  
  2566. static struct keytab enatab[] = {    /* ENABLE commands */
  2567.     "all",        EN_ALL,  0,
  2568. #ifndef NOSPL
  2569.     "as",         EN_ASG,  CM_INV|CM_ABR,
  2570.     "asg",        EN_ASG,  CM_INV,
  2571.     "assign",     EN_ASG,  0,
  2572. #endif /* NOSPL */
  2573. #ifndef datageneral
  2574.     "bye",        EN_BYE,  0,
  2575. #endif /* datageneral */
  2576.     "cd",         EN_CWD,  0,
  2577. #ifdef ZCOPY
  2578.     "copy",       EN_CPY,  0,
  2579. #endif /* ZCOPY */
  2580.     "cwd",        EN_CWD,  CM_INV,
  2581.     "delete",     EN_DEL,  0,
  2582.     "directory",  EN_DIR,  0,
  2583.     "enable",     EN_ENA,  CM_INV,
  2584.     "exit",       EN_XIT,  0,
  2585.     "finish",     EN_FIN,  0,
  2586.     "get",        EN_GET,  0,
  2587.     "host",       EN_HOS,  0,
  2588.     "mail",       EN_MAI,  0,
  2589.     "mkdir",      EN_MKD,  0,
  2590. #ifndef NOSPL
  2591.     "query",      EN_QUE,  0,
  2592. #endif /* NOSPL */
  2593.     "print",      EN_PRI,  0,
  2594.     "rename",     EN_REN,  0,
  2595.     "retrieve",   EN_RET,  CM_INV,
  2596.     "rmdir",      EN_RMD,  0,
  2597.     "send",       EN_SEN,  0,
  2598.     "set",        EN_SET,  0,
  2599.     "space",      EN_SPA,  0,
  2600.     "type",       EN_TYP,  0,
  2601.     "who",        EN_WHO,  0
  2602. };
  2603. static int nena = (sizeof(enatab) / sizeof(struct keytab));
  2604. #endif /* NOSERVER */
  2605.  
  2606. #ifndef NOXFER
  2607. static struct keytab sndtab[] = {    /* SEND command options */
  2608.     "/after",           SND_AFT, CM_ARG,
  2609. #ifndef NOSPL
  2610.     "/array",           SND_ARR, CM_ARG,
  2611. #endif /* NOSPL */
  2612.     "/as-name",         SND_ASN, CM_ARG,
  2613.     "/b",               SND_BIN, CM_INV|CM_ABR,
  2614.     "/before",          SND_BEF, CM_ARG,
  2615.     "/binary",          SND_BIN, 0,
  2616. #ifdef CALIBRATE
  2617.     "/c",               SND_CMD, CM_INV|CM_ABR,
  2618.     "/calibrate",       SND_CAL, CM_INV|CM_ARG,
  2619. #endif /* CALIBRATE */
  2620.     "/command",         SND_CMD, 0,
  2621.     "/delete",          SND_DEL, 0,
  2622. #ifdef UNIXOROSK
  2623.     "/dotfiles",        SND_DOT, 0,
  2624. #endif /* UNIXOROSK */
  2625.     "/except",          SND_EXC, CM_ARG,
  2626. #ifdef PIPESEND
  2627.     "/filter",          SND_FLT, CM_ARG,
  2628. #endif /* PIPESEND */
  2629.     "/filenames",       SND_NAM, CM_ARG,
  2630. #ifdef VMS
  2631.     "/image",           SND_IMG, 0,
  2632. #else
  2633.     "/image",           SND_BIN, CM_INV,
  2634. #endif /* VMS */
  2635. #ifdef CK_LABELED
  2636.     "/labeled",         SND_LBL, 0,
  2637. #endif /* CK_LABELED */
  2638.     "/larger-than",     SND_LAR, CM_ARG,
  2639.     "/listfile",        SND_FIL, CM_ARG,
  2640. #ifndef NOFRILLS
  2641.     "/mail",            SND_MAI, CM_ARG,
  2642. #endif /* NOFRILLS */
  2643. #ifdef CK_TMPDIR
  2644.     "/move-to",         SND_MOV, CM_ARG,
  2645. #endif /* CK_TMPDIR */
  2646.     "/nobackup",        SND_NOB, 0,
  2647. #ifdef UNIXOROSK
  2648.     "/nodotfiles",      SND_NOD, 0,
  2649. #endif /* UNIXOROSK */
  2650.     "/not-after",       SND_NAF, CM_ARG,
  2651.     "/not-before",      SND_NBE, CM_ARG,
  2652.     "/pathnames",       SND_PTH, CM_ARG,
  2653.     "/print",           SND_PRI, CM_ARG,
  2654. #ifdef CK_XYZ
  2655.     "/protocol",        SND_PRO, CM_ARG,
  2656. #else
  2657.     "/protocol",        SND_PRO, CM_ARG|CM_INV,
  2658. #endif /* CK_XYZ */
  2659.     "/quiet",           SND_SHH, 0,
  2660.     "/recover",         SND_RES, 0,
  2661. #ifdef RECURSIVE
  2662. /* Systems where we do recursion */
  2663.     "/recursive",       SND_REC, 0,
  2664. #else
  2665. #ifdef VMS
  2666. /* Systems that do recursion themselves without our assistance */
  2667. /* if we give them the right kind of wildcard */
  2668.     "/recursive",       SND_REC, 0,
  2669. #else
  2670. #ifdef datageneral
  2671.     "/recursive",       SND_REC, 0,
  2672. #else
  2673.     "/recursive",       SND_REC, CM_INV,
  2674. #endif /* datageneral */
  2675. #endif /* VMS */
  2676. #endif /* RECURSIVE */
  2677.     "/rename-to",       SND_REN, CM_ARG,
  2678.     "/since",           SND_AFT, CM_INV|CM_ARG,
  2679.     "/smaller-than",    SND_SMA, CM_ARG,
  2680.     "/starting-at",     SND_STA, CM_ARG,
  2681. #ifndef NOFRILLS
  2682.     "/su",              SND_ASN, CM_ARG|CM_INV|CM_ABR,
  2683.     "/sub",             SND_ASN, CM_ARG|CM_INV|CM_ABR,
  2684.     "/subject",         SND_ASN, CM_ARG,
  2685. #endif /* NOFRILLS */
  2686. #ifdef RECURSIVE
  2687.     "/subdirectories",  SND_REC, CM_INV,
  2688. #endif /* RECURSIVE */
  2689.     "/text",            SND_TXT, 0
  2690. };
  2691. #define NSNDTAB sizeof(sndtab)/sizeof(struct keytab)
  2692. static int nsndtab = NSNDTAB;
  2693.  
  2694. #ifndef NOMSEND
  2695. static struct keytab msndtab[] = {    /* MSEND options */
  2696.     "/after",           SND_AFT, CM_ARG,
  2697.     "/before",          SND_BEF, CM_ARG,
  2698.     "/binary",          SND_BIN, 0,
  2699.     "/delete",          SND_DEL, 0,
  2700.     "/except",          SND_EXC, CM_ARG,
  2701.     "/filenames",       SND_NAM, CM_ARG,
  2702. #ifdef VMS
  2703.     "/image",           SND_IMG, 0,
  2704. #else
  2705.     "/image",           SND_BIN, CM_INV,
  2706. #endif /* VMS */
  2707. #ifdef CK_LABELED
  2708.     "/labeled",         SND_LBL, 0,
  2709. #endif /* CK_LABELED */
  2710.     "/larger-than",     SND_LAR, CM_ARG,
  2711.     "/list",            SND_FIL, CM_ARG,
  2712. #ifndef NOFRILLS
  2713.     "/mail",            SND_MAI, CM_ARG,
  2714. #endif /* NOFRILLS */
  2715. #ifdef CK_TMPDIR
  2716.     "/move-to",         SND_MOV, CM_ARG,
  2717. #endif /* CK_TMPDIR */
  2718.     "/not-after",       SND_NAF, CM_ARG,
  2719.     "/not-before",      SND_NBE, CM_ARG,
  2720.     "/pathnames",       SND_PTH, CM_ARG,
  2721.     "/print",           SND_PRI, CM_ARG,
  2722. #ifdef CK_XYZ
  2723.     "/protocol",        SND_PRO, CM_ARG,
  2724. #endif /* CK_XYZ */
  2725.     "/quiet",           SND_SHH, 0,
  2726.     "/recover",         SND_RES, 0,
  2727.     "/rename-to",       SND_REN, CM_ARG,
  2728.     "/since",           SND_AFT, CM_INV|CM_ARG,
  2729.     "/smaller-than",    SND_SMA, CM_ARG,
  2730.     "/starting-at",     SND_STA, CM_ARG,
  2731. #ifndef NOFRILLS
  2732.     "/subject",         SND_ASN, CM_ARG,
  2733. #endif /* NOFRILLS */
  2734.     "/text",            SND_TXT, 0
  2735. };
  2736. #define NMSNDTAB sizeof(msndtab)/sizeof(struct keytab)
  2737. static int nmsndtab = NMSNDTAB;
  2738. #endif /* NOMSEND */
  2739. #endif /* NOXFER */
  2740.  
  2741. /* CONNECT command switches */
  2742.  
  2743. #ifndef NOLOCAL
  2744. static struct keytab conntab[] = {
  2745. #ifdef XLIMITS
  2746.     "/idle-interval",   CONN_II, CM_ARG,
  2747.     "/idle-limit",      CONN_IL, CM_ARG,
  2748.     "/idle-string",     CONN_IS, CM_ARG,
  2749.     "/quietly",         CONN_NV, CM_INV
  2750. #else
  2751.     "/quietly",         CONN_NV, 0
  2752. #endif /* XLIMITS */
  2753. #ifdef XLIMITS
  2754. ,   "/time-limit",      CONN_TL, CM_ARG
  2755. #endif /* XLIMITS */
  2756. #ifdef CK_TRIGGER
  2757. ,   "/trigger",         CONN_TS, CM_ARG
  2758. #endif /* CK_TRIGGER */
  2759. };
  2760. #define NCONNTAB sizeof(conntab)/sizeof(struct keytab)
  2761. static int nconntab = NCONNTAB;
  2762. #endif /* NOLOCAL */
  2763.  
  2764. #ifndef NOXFER
  2765. static struct keytab stattab[] = {    /* STATISTICS command switches */
  2766.     "/brief", 1, 0,
  2767.     "/verbose", 0, 0
  2768. };
  2769. #endif /* NOXFER */
  2770.  
  2771. #ifndef NOSPL
  2772. #ifdef COMMENT
  2773. struct mtab mactab[MAC_MAX] = {        /* Preinitialized macro table */
  2774.     NULL, NULL, 0
  2775. };
  2776. #else
  2777. struct mtab *mactab;            /* Dynamically allocated macro table */
  2778. #endif /* COMMENT */
  2779. int nmac = 0;
  2780.  
  2781. struct keytab mackey[MAC_MAX];        /* Macro names as command keywords */
  2782. #endif /* NOSPL */
  2783.  
  2784. #ifndef NOSPL
  2785. #ifdef  OS2
  2786. struct keytab beeptab[] = {        /* Beep options */
  2787.     "error", BP_FAIL, 0,
  2788.     "information", BP_NOTE, 0,
  2789.     "warning", BP_WARN, 0
  2790. };
  2791. int nbeeptab = sizeof(beeptab)/sizeof(struct keytab);
  2792.  
  2793. /* CLEAR COMMMAND-SCREEN options */
  2794.  
  2795. #define CLR_C_ALL 0
  2796. #define CLR_C_BOL 1
  2797. #define CLR_C_BOS 2
  2798. #define CLR_C_EOL 3
  2799. #define CLR_C_EOS 4
  2800. #define CLR_C_LIN 5
  2801. #define CLR_C_SCR 6
  2802.  
  2803. struct keytab clrcmdtab[] = {
  2804.     "all",     CLR_C_ALL, 0,
  2805.     "bol",     CLR_C_BOL, 0,
  2806.     "bos",     CLR_C_BOS, 0,
  2807.     "eol",     CLR_C_EOL, 0,
  2808.     "eos",     CLR_C_EOS, 0,
  2809.     "line",    CLR_C_LIN, 0,
  2810.     "scrollback", CLR_C_SCR, 0
  2811. };
  2812. int nclrcmd = sizeof(clrcmdtab)/sizeof(struct keytab);
  2813. #endif /* OS2 */
  2814. #endif /* NOSPL */
  2815.  
  2816. #ifdef COMMENT
  2817. /* Not used at present */
  2818. static struct keytab pagetab[] = {
  2819.     "/more",   1, CM_INV,
  2820.     "/nopage", 0, 0,
  2821.     "/page",   1, 0
  2822. };
  2823. int npagetab = sizeof(pagetab)/sizeof(struct keytab);
  2824. #endif /* COMMENT */
  2825.  
  2826. #define TYP_NOP 0            /* /NOPAGE */
  2827. #define TYP_PAG 1            /* /PAGE */
  2828. #define TYP_HEA 2            /* /HEAD:n */
  2829. #define TYP_TAI 3            /* /TAIL:n */
  2830. #define TYP_PAT 4            /* /MATCH:pattern */
  2831. #define TYP_WID 5            /* /WIDTH:cols */
  2832. #define TYP_COU 6            /* /COUNT */
  2833. #define TYP_OUT 7            /* /OUTPUT:file */
  2834. #define TYP_PFX 8            /* /PREFIX:string */
  2835.  
  2836. static struct keytab typetab[] = {
  2837.     "/count",  TYP_COU, 0,
  2838.     "/head",   TYP_HEA, CM_ARG,
  2839.     "/match",  TYP_PAT, CM_ARG,
  2840. #ifdef CK_TTGWSIZ
  2841.     "/more",   TYP_PAG, CM_INV,
  2842.     "/nopage", TYP_NOP, 0,
  2843.     "/page",   TYP_PAG, 0,
  2844. #endif /* CK_TTGWSIZ */
  2845.     "/prefix", TYP_PFX, CM_ARG,
  2846.     "/tail",   TYP_TAI, CM_ARG,
  2847.     "/width",  TYP_WID, CM_ARG,
  2848.     "", 0, 0
  2849. };
  2850. int ntypetab = sizeof(typetab)/sizeof(struct keytab) - 1;
  2851.  
  2852. int typ_page = -1;            /* TYPE /[NO]PAGE default */
  2853. int typ_wid  = -1;
  2854.  
  2855. #ifndef NOSPL
  2856. #define TRA_ALL 999            /* TRACE command */
  2857. #define TRA_ASG 0
  2858. #define TRA_CMD 1
  2859.  
  2860. int tra_asg = 0;
  2861. int tra_cmd = 0;
  2862.  
  2863. static struct keytab tracetab[] = {    /* TRACE options */
  2864.     "all",            TRA_ALL, 0,
  2865.     "assignments",    TRA_ASG, 0,
  2866.     "command-level",  TRA_CMD, 0
  2867. };
  2868. static int ntracetab = sizeof(tracetab)/sizeof(struct keytab);
  2869. #endif /* NOSPL */
  2870.  
  2871. #ifndef NOSHOW
  2872. VOID
  2873. showtypopts() {
  2874.     printf(" TYPE ");
  2875.     if (typ_page > -1) {
  2876.     prtopt(&optlines,typ_page ? "/PAGE" : "/NOPAGE");
  2877.     } else
  2878.       prtopt(&optlines,"(no options set)");
  2879.     if (typ_wid > -1) {
  2880.     sprintf(tmpbuf,"/WIDTH:%d",typ_wid);
  2881.     prtopt(&optlines,tmpbuf);
  2882.     }
  2883.     prtopt(&optlines,"");
  2884. }
  2885. #endif /* NOSHOW */
  2886.  
  2887. int
  2888. settypopts() {                /* Set TYPE option defaults */
  2889.     int xp = -1;
  2890.     int c, getval;
  2891.     while (1) {
  2892.     if ((y = cmswi(typetab,ntypetab,"Switch","",xxstring)) < 0) {
  2893.         if (y == -3)
  2894.           break;
  2895.         else
  2896.           return(y);
  2897.     }
  2898.     c = cmgbrk();
  2899.     if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  2900.         printf("?This switch does not take an argument\n");
  2901.         return(-9);
  2902.     }
  2903.     switch (y) {
  2904.       case TYP_NOP: xp = 0; break;
  2905.       case TYP_PAG: xp = 1; break;
  2906.       case TYP_WID:
  2907.         if (getval)
  2908.           if ((x = cmnum("Column at which to truncate",
  2909.                  ckitoa(cmd_cols),10,&y,xxstring)) < 0)
  2910.         return(x);
  2911.         typ_wid = y;
  2912.         break;
  2913.           default:
  2914.         printf("?Sorry, this option can not be set\n");
  2915.         return(-9);
  2916.     }
  2917.     }
  2918.     if ((x = cmcfm()) < 0)        /* Get confirmation */
  2919.       return(x);
  2920.     if (xp > -1) typ_page = xp;        /* Confirmed, save defaults */
  2921.     return(success = 1);
  2922. }
  2923.  
  2924. /* Forward declarations of functions local to this module */
  2925.  
  2926. _PROTOTYP (int doask,   ( int  ) );
  2927. _PROTOTYP (int dodef,   ( int  ) );
  2928. _PROTOTYP (int dodel,   ( void ) );
  2929. _PROTOTYP (int dodial,  ( int  ) );
  2930. _PROTOTYP (int doelse,  ( void ) );
  2931. _PROTOTYP (int dofor,   ( void ) );
  2932. _PROTOTYP (int doincr,  ( int  ) );
  2933. _PROTOTYP (int dopaus,  ( int  ) );
  2934. #ifndef NOPUSH
  2935. _PROTOTYP (int doping,  ( void ) );
  2936. _PROTOTYP (int doftp,   ( void ) );
  2937. #endif /* NOPUSH */
  2938. #ifndef NORENAME
  2939. #ifndef NOFRILLS
  2940. _PROTOTYP (int dorenam, ( void ) );
  2941. #endif /* NOFRILLS */
  2942. #endif /* NORENAME */
  2943. #ifdef ZCOPY
  2944. _PROTOTYP (int docopy, ( void ) );
  2945. #endif /* ZCOPY */
  2946. #ifdef CK_REXX
  2947. _PROTOTYP (int dorexx,  ( void ) );
  2948. #endif /* CK_REXX */
  2949.  
  2950. #ifdef TCPSOCKET
  2951. static struct keytab telcmd[] = {
  2952.     "abort", TN_ABORT, CM_INV, /* Emotionally toned word - don't show */
  2953.     "ao",    TN_AO,    0,
  2954.     "ayt",   TN_AYT,   0,
  2955.     "break", BREAK,    0,
  2956.     "cancel",TN_ABORT, 0,
  2957.     "ec",    TN_EC,    0,
  2958.     "el",    TN_EL,    0,
  2959.     "eof",   TN_EOF,   0,
  2960.     "eor",   TN_EOR,   0,
  2961.     "ga",    TN_GA,    0,
  2962.     "ip",    TN_IP,    0,
  2963.     "dmark", TN_DM,    0,
  2964.     "do",    DO,       0,
  2965.     "dont",  DONT,     0,
  2966.     "nop",   TN_NOP,   0,
  2967.     "sak",   TN_SAK,   CM_INV,
  2968.     "sb",    SB,       0,
  2969.     "se",    SE,       0,
  2970.     "susp",  TN_SUSP,  0,
  2971.     "will",  WILL,     0,
  2972.     "wont",  WONT,     0
  2973. };
  2974. static int ntelcmd = (sizeof(telcmd) / sizeof(struct keytab));
  2975.  
  2976. static struct keytab tnopts[] = {
  2977. #ifdef CK_AUTHENTICATION
  2978.     "auth",   TELOPT_AUTHENTICATION,   CM_INV,
  2979. #endif /* CK_AUTHENTICATION */
  2980.     "binary", TELOPT_BINARY, 0,
  2981.     "com-port-control", TELOPT_COM_PORT, CM_INV,
  2982.     "echo", TELOPT_ECHO, 0,
  2983. #ifdef CK_ENCRYPTION
  2984.     "encrypt", TELOPT_ENCRYPTION, CM_INV,
  2985. #endif /* CK_ENCRYPTION */
  2986. #ifdef IKS_OPTION
  2987.     "kermit", TELOPT_KERMIT, 0,
  2988. #endif /* IKS_OPTION */
  2989.     "lflow",  TELOPT_LFLOW, CM_INV,
  2990. #ifdef CK_NAWS
  2991.     "naws", TELOPT_NAWS, 0,
  2992. #endif /* CK_NAWS */
  2993. #ifdef CK_ENVIRONMENT
  2994.     "new-environment", TELOPT_NEWENVIRON,  CM_INV,
  2995. #endif /* CK_ENVIRONMENT */
  2996.     "pragma-heartbeat",TELOPT_PRAGMA_HEARTBEAT,  CM_INV,
  2997.     "pragma-logon",    TELOPT_PRAGMA_LOGON,  CM_INV,
  2998.     "pragma-sspi",     TELOPT_SSPI_LOGON,  CM_INV,
  2999.     "sak",   TELOPT_IBM_SAK, CM_INV,
  3000. #ifdef CK_SNDLOC
  3001.     "send-location",   TELOPT_SNDLOC,  CM_INV,
  3002. #endif /* CK_SNDLOC */
  3003.     "sga", TELOPT_SGA, 0,
  3004. #ifdef CK_SSL
  3005.     "start-tls",       TELOPT_START_TLS,  CM_INV,
  3006. #endif /* CK_SSL */
  3007.     "ttype", TELOPT_TTYPE, 0,
  3008. #ifdef CK_ENVIRONMENT
  3009.     "xdisplay-location", TELOPT_XDISPLOC, CM_INV,
  3010. #endif /* CK_ENVIRONMENT */
  3011.     "", 0, 0
  3012. };
  3013. static int ntnopts = (sizeof(tnopts) / sizeof(struct keytab)) - 1;
  3014.  
  3015. static struct keytab tnsbopts[] = {
  3016. #ifdef CK_NAWS
  3017.     "naws", TELOPT_NAWS, 0,
  3018. #endif /* CK_NAWS */
  3019.     "", 0, 0
  3020. };
  3021. static int ntnsbopts = (sizeof(tnsbopts) / sizeof(struct keytab)) - 1;
  3022.  
  3023. #ifndef NOPUSH
  3024. int
  3025. doftp() {                /* FTP command */
  3026.     char *p;                /* for now just runs the ftp program */
  3027.     int x;
  3028.  
  3029.     if (network)            /* If we have a current connection */
  3030.       ckstrncpy(line,ttname,LINBUFSIZ);    /* get the host name */
  3031.     else *line = '\0';            /* as default host */
  3032.     for (p = line; *p; p++)        /* Remove ":service" from end. */
  3033.       if (*p == ':') { *p = '\0'; break; }
  3034.     if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
  3035.       return(x);
  3036.     if (nopush) {
  3037.         printf("?Sorry, FTP command disabled\n");
  3038.         return(success = 0);
  3039.     }
  3040. /* Construct FTP command */
  3041. #ifdef VMS
  3042. #ifdef MULTINET                /* TGV MultiNet */
  3043.     sprintf(line,"multinet ftp %s",s);
  3044. #else
  3045.     sprintf(line,"ftp %s",s);        /* Other VMS TCP/IP's */
  3046. #endif /* MULTINET */
  3047. #else                    /* Not VMS */
  3048. #ifdef OS2ORUNIX
  3049.     sprintf(line,"%s %s",ftpapp,s);
  3050. #ifdef OS2
  3051.     p = line + strlen(ftpapp);
  3052.     while (p != line) {
  3053.         if (*p == '/') *p = '\\';
  3054.         p--;
  3055.     }
  3056. #endif /* OS2 */
  3057. #else /* OS2ORUNIX */
  3058.     sprintf(line,"ftp %s",s);
  3059. #endif /* OS2ORUNIX */
  3060. #endif /* VMS */
  3061.     conres();                /* Make console normal  */
  3062. #ifdef DEC_TCPIP
  3063.     printf("\n");            /* Prevent prompt-stomping */
  3064. #endif /* DEC_TCPIP */
  3065.     x = zshcmd(line);
  3066.     concb((char)escape);
  3067.     return(success = x);
  3068. }
  3069.  
  3070. int
  3071. doping() {                /* PING command */
  3072.     char *p;                /* just runs ping program */
  3073.     int x;
  3074.  
  3075.     if (network)            /* If we have a current connection */
  3076.       ckstrncpy(line,ttname,LINBUFSIZ);    /* get the host name */
  3077.     else *line = '\0';            /* as default host to be pinged. */
  3078.     for (p = line; *p; p++)        /* Remove ":service" from end. */
  3079.       if (*p == ':') { *p = '\0'; break; }
  3080.     if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
  3081.       return(x);
  3082.     if (nopush) {
  3083.         printf("?Sorry, PING command disabled\n");
  3084.         return(success = 0);
  3085.     }
  3086.  
  3087.     /* Construct PING command */
  3088. #ifdef VMS
  3089. #ifdef MULTINET                /* TGV MultiNet */
  3090.     sprintf(line,"multinet ping %s /num=1",s);
  3091. #else
  3092.     sprintf(line,"ping %s 56 1",s);    /* Other VMS TCP/IP's */
  3093. #endif /* MULTINET */
  3094. #else                    /* Not VMS */
  3095.     sprintf(line,"ping %s",s);
  3096. #endif /* VMS */
  3097.     conres();                /* Make console normal  */
  3098. #ifdef DEC_TCPIP
  3099.     printf("\n");            /* Prevent prompt-stomping */
  3100. #endif /* DEC_TCPIP */
  3101.     x = zshcmd(line);
  3102.     concb((char)escape);
  3103.     return(success = x);
  3104. }
  3105. #endif /* NOPUSH */
  3106. #endif /* TCPSOCKET */
  3107.  
  3108.  
  3109. #ifndef NOXFER
  3110. static char * asnbuf = NULL;        /* As-name buffer pointer */
  3111.  
  3112. char sndxnam[] = { "_array_x_" };    /* (with replaceable x!) */
  3113.  
  3114. /*
  3115.   The new SEND command, replacing BSEND, CSEND, PSEND, etc etc.
  3116.   Call with cx = top-level keyword value.  Returns:
  3117.     < 0  On parse error.
  3118.     0    On other type of failure (e.g. requested operation not allowed).
  3119.     1    On success with sstate set to 's' so protocol will begin.
  3120. */
  3121.  
  3122. /*  D O X S E N D  --  Parse SEND and related commands with switches  */
  3123.  
  3124. int
  3125. doxsend(cx) int cx; {
  3126.     int c, i, n, wild, confirmed = 0;    /* Workers */
  3127.     int x, y;                /* of the world... */
  3128.     int getval = 0;            /* Whether to get switch value */
  3129.     extern char * snd_move;        /* Directory to move sent files to */
  3130.     extern char * snd_rename;        /* What to rename sent files to */
  3131.     extern char * g_snd_move;
  3132.     extern char * g_snd_rename;
  3133.     extern char * filefile;        /* File containing filenames to send */
  3134.     extern struct keytab pathtab[];    /* PATHNAMES option keywords */
  3135.     extern int npathtab;        /* How many of them */
  3136.     extern int recursive;        /* Recursive directory traversal */
  3137.     extern int rprintf;            /* REMOTE PRINT flag */
  3138.     extern int fdispla;            /* TRANSFER DISPLAY setting */
  3139.     extern int skipbup;            /* Skip backup files when sending */
  3140.     struct stringint {            /* Temporary array for switch values */
  3141.     char * sval;
  3142.     int ival;
  3143.     } pv[SND_MAX+1];
  3144.     struct FDB sf, sw, fl, cm;        /* FDBs for each parse function */
  3145.     int mlist = 0;            /* Flag for MSEND or MMOVE */
  3146.     char * m;                /* For making help messages */
  3147.     extern struct keytab protos[];    /* File transfer protocols */
  3148.     extern int nprotos;
  3149.     extern char sndbefore[], sndafter[], *sndexcept[]; /* Selection criteria */
  3150.     extern char sndnbefore[], sndnafter[];
  3151.     extern long sndsmaller, sndlarger, calibrate;
  3152. #ifndef NOSPL
  3153.     int range[2];            /* Array range */
  3154.     char ** ap = NULL;            /* Array pointer */
  3155.     int arrayx = -1;            /* Array index */
  3156. #endif /* NOSPL */
  3157.  
  3158.     for (i = 0; i <= SND_MAX; i++) {    /* Initialize switch values */
  3159.     pv[i].sval = NULL;        /* to null pointers */
  3160.     pv[i].ival = -1;        /* and -1 int values */
  3161.     }
  3162. #ifndef NOSPL
  3163.     range[0] = -1;
  3164.     range[1] = -1;
  3165.     sndxin = -1;            /* Array index */
  3166. #endif /* NOSPL */
  3167.     sndarray = NULL;            /* Array pointer */
  3168.  
  3169. #ifdef UNIXOROSK
  3170.     g_matchdot = matchdot;        /* Match dot files */
  3171. #endif /* UNIXOROSK */
  3172.     g_recursive = recursive;        /* Recursive sending */
  3173.     recursive = 0;            /* Save global value, set local */
  3174.     debug(F101,"xsend entry fncnv","",fncnv);
  3175.  
  3176.     /* Preset switch values based on top-level command that called us */
  3177.  
  3178.     switch (cx) {
  3179.       case XXMSE:            /* MSEND */
  3180.     mlist = 1; break;
  3181.       case XXCSEN:            /* CSEND */
  3182.     pv[SND_CMD].ival = 1; break;
  3183.       case XXMMOVE:            /* MMOVE */
  3184.     mlist = 1;
  3185.       case XXMOVE:            /* MOVE */
  3186.     pv[SND_DEL].ival = 1; break;
  3187.       case XXRSEN:            /* RESEND */
  3188.     pv[SND_BIN].ival = 1;        /* Implies /BINARY */
  3189.     pv[SND_RES].ival = 1; break;
  3190.       case XXMAI:            /* MAIL */
  3191.     pv[SND_MAI].ival = 1; break;
  3192.     }
  3193.  
  3194.     /* Set up chained parse functions... */
  3195.  
  3196.     cmfdbi(&sw,                /* First FDB - command switches */
  3197.        _CMKEY,            /* fcode */
  3198.        "Filename, or switch",    /* hlpmsg */
  3199.        "",                /* default */
  3200.        "",                /* addtl string data */
  3201. #ifdef NOMSEND
  3202.        nsndtab,            /* addtl numeric data 1: tbl size */
  3203. #else
  3204.        mlist ? nmsndtab : nsndtab,    /* addtl numeric data 1: tbl size */
  3205. #endif /* NOMSEND */
  3206.        4,                /* addtl numeric data 2: 4 = cmswi */
  3207.        xxstring,            /* Processing function */
  3208. #ifdef NOMSEND
  3209.        sndtab,            /* Keyword table */
  3210. #else
  3211.        mlist ? msndtab : sndtab,
  3212. #endif /* NOMSEND */
  3213.        &sf                /* Pointer to next FDB */
  3214.        );
  3215.     cmfdbi(&sf,                /* 2nd FDB - file to send */
  3216.        _CMIFI,            /* fcode */
  3217.        "File(s) to send",        /* hlpmsg */
  3218.        "",                /* default */
  3219.        "",                /* addtl string data */
  3220.        0,                /* addtl numeric data 1 */
  3221.        0,                /* addtl numeric data 2 */
  3222.        xxstring,
  3223.        NULL,
  3224.        mlist ? &cm : &fl
  3225.        );
  3226.     cmfdbi(&fl,                /* 3rd FDB - command to send from */
  3227.        _CMFLD,            /* fcode */
  3228.        "Command",            /* hlpmsg */
  3229.        "",                /* default */
  3230.        "",                /* addtl string data */
  3231.        0,                /* addtl numeric data 1 */
  3232.        0,                /* addtl numeric data 2 */
  3233.        xxstring,
  3234.        NULL,
  3235.        &cm
  3236.        );
  3237.     cmfdbi(&cm,                /* 4th FDB - Confirmation */
  3238.        _CMCFM,            /* fcode */
  3239.        "",                /* hlpmsg */
  3240.        "",                /* default */
  3241.        "",                /* addtl string data */
  3242.        0,                /* addtl numeric data 1 */
  3243.        0,                /* addtl numeric data 2 */
  3244.        NULL,
  3245.        NULL,
  3246.        NULL
  3247.        );
  3248.  
  3249.     while (1) {                /* Parse 0 or more switches */
  3250.     x = cmfdb(&sw);            /* Parse something */
  3251.     debug(F101,"xsend cmfdb","",x);
  3252.     if (x < 0)            /* Error */
  3253.       goto xsendx;            /* or reparse needed */
  3254.     if (cmresult.fcode != _CMKEY)    /* Break out if not a switch */
  3255.       break;
  3256. /*
  3257.   They gave a switch, but let's see how they terminated it.
  3258.   If they ended it with : or =, then we must parse a value.
  3259.   If they ended it with anything else, then we must NOT parse a value.
  3260. */
  3261.     c = cmgbrk();            /* Get break character */
  3262.     getval = (c == ':' || c == '='); /* to see how they ended the switch */
  3263.     if (getval && !(cmresult.kflags & CM_ARG)) {
  3264.         printf("?This switch does not take arguments\n");
  3265.         x = -9;
  3266.         goto xsendx;
  3267.     }
  3268.     if (!getval && (cmgkwflgs() & CM_ARG)) {
  3269.         printf("?This switch requires an argument\n");
  3270.         x = -9;
  3271.         goto xsendx;
  3272.     }
  3273.     n = cmresult.nresult;        /* Numeric result = switch value */
  3274.     debug(F101,"xsend switch","",n);
  3275.  
  3276.     switch (n) {            /* Process the switch */
  3277.       case SND_CMD:            /* These take no args */
  3278.         if (nopush) {
  3279.         printf("?Sorry, system command access is disabled\n");
  3280.         x = -9;
  3281.         goto xsendx;
  3282.         }
  3283. #ifdef PIPESEND
  3284.         else if (sndfilter) {
  3285.         printf(
  3286. "?Sorry, no SEND /COMMAND or CSEND when SEND FILTER selected\n");
  3287.         x = -9;
  3288.         goto xsendx;
  3289.         }
  3290. #endif /* PIPESEND */
  3291.         sw.hlpmsg = "Command, or switch"; /* Change help message */
  3292.         pv[n].ival = 1;        /* Just set the flag */
  3293.         pv[SND_ARR].ival = 0;
  3294.         break;
  3295.  
  3296.       case SND_REC:            /* /RECURSIVE */
  3297.         recursive = 2;        /* Set the real variable */
  3298.         pv[SND_PTH].ival = PATH_REL; /* Give them relative pathnames */
  3299.         pv[n].ival = 1;        /* Just set the flag */
  3300.         break;
  3301.  
  3302.       case SND_RES:            /* /RECOVER (resend) */
  3303.         pv[SND_ARR].ival = 0;
  3304.         pv[SND_BIN].ival = 1;    /* Implies /BINARY */
  3305.       case SND_NOB:            /* /NOBACKUP */
  3306.       case SND_DEL:            /* /DELETE */
  3307.       case SND_SHH:            /* /QUIET */
  3308.         pv[n].ival = 1;        /* Just set the flag */
  3309.         break;
  3310.  
  3311. #ifdef UNIXOROSK
  3312. /* Like recursive, these are set immediately because they affect cmifi() */
  3313.       case SND_DOT:            /* /DOTFILES */
  3314.         matchdot = 1;
  3315.         break;
  3316.       case SND_NOD:            /* /NODOTFILES */
  3317.         matchdot = 0;
  3318.         break;
  3319. #endif /* UNIXOROSK */
  3320.  
  3321.       /* File transfer modes - each undoes the others */
  3322.  
  3323.       case SND_BIN:            /* Binary */
  3324.       case SND_TXT:            /* Text */
  3325.       case SND_IMG:            /* Image */
  3326.       case SND_LBL:            /* Labeled */
  3327.         pv[SND_BIN].ival = 0;
  3328.         pv[SND_TXT].ival = 0;
  3329.         pv[SND_IMG].ival = 0;
  3330.         pv[SND_LBL].ival = 0;
  3331.         pv[n].ival = 1;
  3332.         break;
  3333.  
  3334.       case SND_EXC:            /* Excludes */
  3335.         if (!getval) break;
  3336.         if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
  3337.         if (x == -3) {
  3338.             printf("?Pattern required\n");
  3339.             x = -9;
  3340.         }
  3341.         goto xsendx;
  3342.         }
  3343.         if (pv[n].sval) free(pv[n].sval);
  3344.         y = strlen(s);
  3345.         if (y > 256) {
  3346.         printf("?Pattern too long - 256 max\n");
  3347.         x = -9;
  3348.         goto xsendx;
  3349.         }
  3350.         pv[n].sval = malloc(y+1);
  3351.         if (pv[n].sval) {
  3352.         strcpy(pv[n].sval,s);
  3353.         pv[n].ival = 1;
  3354.         }
  3355.         break;
  3356.  
  3357.       case SND_MOV:            /* MOVE after */
  3358.       case SND_REN:            /* RENAME after */
  3359.         if (!getval) break;
  3360.         if ((x = cmfld(n == SND_MOV ?
  3361.        "device and/or directory for source file after sending" :
  3362.        "new name for source file after sending",
  3363.                "",
  3364.                &s,
  3365.                n == SND_MOV ? xxstring : NULL
  3366.                )) < 0) {
  3367.         if (x == -3) {
  3368.             printf("%s\n", n == SND_MOV ?
  3369.                "?Destination required" :
  3370.                "?New name required"
  3371.                );
  3372.             x = -9;
  3373.         }
  3374.         goto xsendx;
  3375.         }
  3376.         if (pv[n].sval) free(pv[n].sval);
  3377.         s = brstrip(s);
  3378.         y = strlen(s);
  3379.         if (y > 0) {
  3380.         pv[n].sval = malloc(y+1);
  3381.         if (pv[n].sval) {
  3382.             strcpy(pv[n].sval,s);
  3383.             pv[n].ival = 1;
  3384.         }
  3385.         }
  3386.         break;
  3387.  
  3388.       case SND_SMA:            /* Smaller / larger than */
  3389.       case SND_LAR:
  3390.         if (!getval) break;
  3391.         if ((x = cmnum("Size in bytes","0",10,&y,xxstring)) < 0)
  3392.           goto xsendx;
  3393.         pv[n].ival = y;
  3394.         break;
  3395.  
  3396.       case SND_AFT:            /* Send /AFTER:date-time */
  3397.       case SND_BEF:            /* Send /BEFORE:date-time */
  3398.       case SND_NAF:            /* Send /NOT-AFTER:date-time */
  3399.       case SND_NBE:            /* Send /NOT-BEFORE:date-time */
  3400.         if (!getval) break;
  3401.         if ((x = cmdate("File date-time","",&s,0,xxstring)) < 0) {
  3402.         if (x == -3) {
  3403.             printf("?Date-time required\n");
  3404.             x = -9;
  3405.         }
  3406.         goto xsendx;
  3407.         }
  3408.         if (pv[n].sval) free(pv[n].sval);
  3409.         pv[n].sval = malloc((int)strlen(s)+1);
  3410.         if (pv[n].sval) {
  3411.         strcpy(pv[n].sval,s);
  3412.         pv[n].ival = 1;
  3413.         }
  3414.         break;
  3415.  
  3416.       case SND_MAI:            /* Send as mail (= MAIL) */
  3417. #ifdef IKSD
  3418.         if (inserver && !ENABLED(en_mai)) {
  3419.         printf("?Sorry, sending files as mail is disabled\n");
  3420.         return(-9);
  3421.         }
  3422. #endif /* IKSD */
  3423.         pv[n].ival = 1;
  3424.         if (!getval) break;
  3425.         if ((x = cmfld("e-mail address","",&s,xxstring)) < 0) {
  3426.         if (x == -3) {
  3427.             printf("?address required\n");
  3428.             x = -9;
  3429.         }
  3430.         goto xsendx;
  3431.         }
  3432.         s = brstrip(s);
  3433.         if (pv[n].sval) free(pv[n].sval);
  3434.         pv[n].sval = malloc((int)strlen(s)+1);
  3435.         if (pv[n].sval)
  3436.           strcpy(pv[n].sval,s);
  3437.         break;
  3438.  
  3439.       case SND_PRI:            /* Send to be printed (REMOTE PRINT) */
  3440. #ifdef IKSD
  3441.         if (inserver && !ENABLED(en_mai)) {
  3442.         printf("?Sorry, sending files for printing is disabled\n");
  3443.         return(-9);
  3444.         }
  3445. #endif /* IKSD */
  3446.         pv[n].ival = 1;
  3447.         if (!getval) break;
  3448.         if ((x = cmfld("Print options","",&s,xxstring)) < 0)
  3449.           if (x != -3) goto xsendx;
  3450.         s = brstrip(s);
  3451.         if (pv[n].sval) free(pv[n].sval);
  3452.         pv[n].sval = malloc((int)strlen(s)+1);
  3453.         if (pv[n].sval)
  3454.           strcpy(pv[n].sval,s);
  3455.         break;
  3456.  
  3457.       case SND_ASN:            /* As-name */
  3458.         debug(F101,"xsend /as-name getval","",getval);
  3459.         if (!getval) break;
  3460.         if ((x = cmfld("Name to send under","",&s,NULL)) < 0) {
  3461.         if (x == -3) {
  3462.             printf("?name required\n");
  3463.             x = -9;
  3464.         }
  3465.         goto xsendx;
  3466.         }
  3467.         s = brstrip(s);
  3468.         if ((y = strlen(s)) > 0) {
  3469.         if (pv[n].sval) free(pv[n].sval);
  3470.         pv[n].sval = malloc(y+1);
  3471.         if (pv[n].sval) {
  3472.             strcpy(pv[n].sval,s);
  3473.             pv[n].ival = 1;
  3474.         }
  3475.         }
  3476.         break;
  3477.  
  3478.       case SND_STA:            /* Starting position (= PSEND) */
  3479.         if (!getval) break;
  3480.         if ((x = cmnum("0-based position","0",10,&y,xxstring)) < 0)
  3481.           goto xsendx;
  3482.         pv[n].ival = y;
  3483.         break;
  3484.  
  3485.       case SND_PRO:            /* Protocol to use */
  3486.         if (!getval) break;
  3487.         if ((x = cmkey(protos,nprotos,"File-transfer protocol","",
  3488.                xxstring)) < 0) {
  3489.         if (x == -3) {
  3490.             printf("?name of protocol required\n");
  3491.             x = -9;
  3492.         }
  3493.         goto xsendx;
  3494.         }
  3495.         pv[n].ival = x;
  3496.         break;
  3497.  
  3498. #ifdef PIPESEND
  3499.       case SND_FLT:            /* Filter */
  3500.         debug(F101,"xsend /filter getval","",getval);
  3501.         if (!getval) break;
  3502.         if ((x = cmfld("Filter program to send through","",&s,NULL)) < 0) {
  3503.         if (x == -3)
  3504.           s = "";
  3505.         else
  3506.           goto xsendx;
  3507.         }
  3508.         s = brstrip(s);
  3509.         y = strlen(s);
  3510.         for (x = 0; x < y; x++) {    /* Make sure they included "\v(...)" */
  3511.         if (s[x] != '\\') continue;
  3512.         if (s[x+1] == 'v') break;
  3513.         }
  3514.         if (x == y) {
  3515.         printf(
  3516.         "?Filter must contain a replacement variable for filename.\n"
  3517.                );
  3518.         x = -9;
  3519.         goto xsendx;
  3520.         }
  3521.         pv[n].ival = 1;
  3522.         if (pv[n].sval) {
  3523.         free(pv[n].sval);
  3524.         pv[n].sval = NULL;
  3525.         }
  3526.         if ((y = strlen(s)) > 0) {
  3527.         if (pv[n].sval = malloc(y+1))
  3528.           strcpy(pv[n].sval,s);
  3529.         }
  3530.         break;
  3531. #endif /* PIPESEND */
  3532.  
  3533.       case SND_PTH:            /* Pathnames */
  3534.         if (!getval) {
  3535.         pv[n].ival = PATH_REL;
  3536.         break;
  3537.         }
  3538.         if ((x = cmkey(pathtab,npathtab,"","absolute",xxstring)) < 0)
  3539.           goto xsendx;
  3540.         pv[n].ival = x;
  3541.         break;
  3542.  
  3543.       case SND_NAM:            /* Filenames */
  3544.         if (!getval) break;
  3545.         if ((x = cmkey(fntab,nfntab,"","converted",xxstring)) < 0)
  3546.           goto xsendx;
  3547.         debug(F101,"xsend /filenames","",x);
  3548.         pv[n].ival = x;
  3549.         break;
  3550.  
  3551. #ifdef CALIBRATE
  3552.           case SND_CAL:            /* /CALIBRATE */
  3553.         if (getval) {
  3554.         if ((x = cmnum("number of Kbytes to send",
  3555.                "1024",10,&y,xxstring)) < 0)
  3556.           goto xsendx;
  3557.         } else
  3558.           y = 1024;
  3559.         pv[n].ival = y;
  3560.         pv[SND_ARR].ival = 0;
  3561.         break;
  3562. #endif /* CALIBRATE */
  3563.  
  3564.       case SND_FIL:            /* Name of file containing filnames */
  3565.         if (!getval) break;
  3566.         if ((x = cmifi("Name of file containing list of filenames",
  3567.                    "",&s,&y,xxstring)) < 0) {
  3568.         if (x == -3) {
  3569.             printf("?Filename required\n");
  3570.             x = -9;
  3571.         }
  3572.         goto xsendx;
  3573.         } else if (y) {
  3574.         printf("?Wildcards not allowed\n");
  3575.         x = -9;
  3576.         goto xsendx;
  3577.         }
  3578.         if (pv[n].sval)
  3579.           free(pv[n].sval);
  3580.         if (s) if (*s) {
  3581.         if (pv[n].sval = malloc((int)strlen(s)+1)) {
  3582.             strcpy(pv[n].sval,s);
  3583.             pv[n].ival = 1;
  3584.             pv[SND_ARR].ival = 0;
  3585.         }
  3586.         }
  3587.         break;
  3588.  
  3589. #ifndef NOSPL
  3590.       case SND_ARR:            /* SEND /ARRAY: */
  3591.         if (!getval) break;
  3592.         ap = NULL;
  3593.         if ((x = cmfld("Array name (a single letter will do)",
  3594.                "",
  3595.                &s,
  3596.                NULL
  3597.                )) < 0) {
  3598.         if (x == -3)
  3599.           break;
  3600.         else
  3601.           return(x);
  3602.         }
  3603.         if ((x = arraybounds(s,&(range[0]),&(range[1]))) < 0) {
  3604.         printf("?Bad array: %s\n",s);
  3605.         return(-9);
  3606.         }
  3607.         if (!(ap = a_ptr[x])) {
  3608.         printf("?No such array: %s\n",s);
  3609.         return(-9);
  3610.         }
  3611.         pv[n].ival = 1;
  3612.         pv[SND_CMD].ival = 0;    /* Undo any conflicting ones... */
  3613.         pv[SND_RES].ival = 0;
  3614.         pv[SND_CAL].ival = 0;
  3615.         pv[SND_FIL].ival = 0;
  3616.         arrayx = x;
  3617.         break;
  3618. #endif /* NOSPL */
  3619.  
  3620.       default:
  3621.         printf("?Unexpected switch value - %d\n",cmresult.nresult);
  3622.         x = -9;
  3623.         goto xsendx;
  3624.     }
  3625.     }
  3626.     debug(F101,"xsend cmresult fcode","",cmresult.fcode);
  3627.  
  3628. #ifdef COMMENT
  3629.     /* List switch parsing results in debug log */
  3630.     for (i = 0; i <= SND_MAX; i++) {
  3631.     sprintf(line,"xsend switch %02d",i);
  3632.     debug(F111,line, pv[i].sval, pv[i].ival);
  3633.     }
  3634. #endif /* COMMENT */
  3635.  
  3636. /* Now we have all switches, plus maybe a filename or command, or nothing */
  3637.  
  3638. #ifdef PIPESEND
  3639.     if (protocol != PROTO_K && pv[SND_CMD].ival > 0) {
  3640.     printf("?Sorry, %s works only with Kermit protocol\n",
  3641.            (cx == XXCSEN) ? "CSEND" : "SEND /COMMAND");
  3642.     x = -9;
  3643.     goto xsendx;
  3644.     }
  3645.     if (pv[SND_RES].ival > 0 ||    /* /RECOVER */
  3646.     pv[SND_STA].ival > 0) {    /* or /STARTING */
  3647.     if (sndfilter || pv[SND_FLT].ival > 0) {
  3648.         printf("?Sorry, no /RECOVER or /START if SEND FILTER selected\n");
  3649.         x = -9;
  3650.         goto xsendx;
  3651.     }
  3652.     }
  3653. #endif /* PIPESEND */
  3654.  
  3655.     cmarg = "";
  3656.     cmarg2 = "";
  3657.     line[0] = NUL;
  3658.     s = line;
  3659.     wild = 0;
  3660.  
  3661.     switch (cmresult.fcode) {        /* How did we get out of switch loop */
  3662.       case _CMIFI:            /* Input filename */
  3663.     ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Name */
  3664.     if (pv[SND_ARR].ival > 0)
  3665.       cmarg2 = line;
  3666.     else
  3667.       wild = cmresult.nresult;    /* Wild flag */
  3668.     break;
  3669.       case _CMFLD:            /* Field */
  3670.     /* Only allowed with /COMMAND and /ARRAY */
  3671.     if (pv[SND_CMD].ival < 1 && pv[SND_ARR].ival < 1) {
  3672.         printf("?%s - \"%s\"\n",
  3673.            iswild(cmresult.sresult) ?
  3674.            "No files match" : "File not found",
  3675.            cmresult.sresult
  3676.            );
  3677.         x = -9;
  3678.         goto xsendx;
  3679.     }
  3680.     ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  3681.     if (pv[SND_ARR].ival > 0)
  3682.       cmarg2 = line;
  3683.     break;
  3684.       case _CMCFM:            /* Confirmation */
  3685.     /* s = ""; */
  3686.     confirmed = 1;
  3687.     break;
  3688.       default:
  3689.     printf("?Unexpected function code: %d\n",cmresult.fcode);
  3690.     x = -9;
  3691.     goto xsendx;
  3692.     }
  3693.     debug(F110,"xsend string",s,0);
  3694.     debug(F101,"xsend confirmed","",confirmed);
  3695.  
  3696.     /* Save and change protocol and transfer mode */
  3697.     /* Global values are restored in main parse loop */
  3698.  
  3699.     g_proto = protocol;            /* Save current global protocol */
  3700.     g_urpsiz = urpsiz;
  3701.     g_spsizf = spsizf;
  3702.     g_spsiz = spsiz;
  3703.     g_spsizr = spsizr;
  3704.     g_spmax = spmax;
  3705.     g_wslotr = wslotr;
  3706.     g_prefixing = prefixing;
  3707.     g_fncact = fncact;
  3708.     g_fncnv = fncnv;
  3709.     g_fnspath = fnspath;
  3710.     g_fnrpath = fnrpath;
  3711.  
  3712.     if (pv[SND_PRO].ival > -1) {    /* Change according to switch */
  3713.     protocol = pv[SND_PRO].ival;
  3714.         if (ptab[protocol].rpktlen > -1) /* copied from initproto() */
  3715.             urpsiz = ptab[protocol].rpktlen;
  3716.         if (ptab[protocol].spktflg > -1)
  3717.             spsizf = ptab[protocol].spktflg;
  3718.         if (ptab[protocol].spktlen > -1) {
  3719.             spsiz = ptab[protocol].spktlen;
  3720.             if (spsizf)
  3721.           spsizr = spmax = spsiz;
  3722.         }
  3723.         if (ptab[protocol].winsize > -1)
  3724.             wslotr = ptab[protocol].winsize;
  3725.         if (ptab[protocol].prefix > -1)
  3726.             prefixing = ptab[protocol].prefix;
  3727.         if (ptab[protocol].fnca > -1)
  3728.             fncact  = ptab[protocol].fnca;
  3729.         if (ptab[protocol].fncn > -1)
  3730.             fncnv   = ptab[protocol].fncn;
  3731.         if (ptab[protocol].fnsp > -1)
  3732.             fnspath = ptab[protocol].fnsp;
  3733.         if (ptab[protocol].fnrp > -1)
  3734.             fnrpath = ptab[protocol].fnrp;
  3735.     }
  3736.     debug(F101,"xsend protocol","",protocol);
  3737.  
  3738.     if (pv[SND_NOB].ival > -1) {    /* /NOBACKUP (skip backup file) */
  3739.     g_skipbup = skipbup;
  3740.     skipbup = 1;
  3741.     }
  3742.     if (pv[SND_REC].ival > 0)        /* Recursive */
  3743.       recursive = 2;
  3744.  
  3745.     g_binary = binary;            /* Save global transfer mode */
  3746. #ifdef PATTERNS
  3747.     g_patterns = patterns;        /* Save FILE PATTERNS setting */
  3748. #endif /* PATTERNS */
  3749.     if (pv[SND_BIN].ival > 0) {        /* Change according to switch */
  3750.     /* If they said /BINARY they mean /BINARY */
  3751. #ifdef PATTERNS
  3752.     patterns = 0;            /* So no pattern-based switching */
  3753. #endif /* PATTERNS */
  3754.     g_xfermode = xfermode;        /* or automatic transfer mode */
  3755.     xfermode = XMODE_M;
  3756.     binary = XYFT_B;
  3757.     debug(F101,"doxsend /BINARY xfermode","",xfermode);
  3758.     } else if (pv[SND_TXT].ival > 0) {    /* Ditto for /TEXT */
  3759. #ifdef PATTERNS
  3760.     patterns = 0;
  3761. #endif /* PATTERNS */
  3762.     g_xfermode = xfermode;
  3763.     xfermode = XMODE_M;
  3764.     binary = XYFT_T;
  3765.     debug(F101,"doxsend /TEXT xfermode","",xfermode);
  3766.     } else if (pv[SND_IMG].ival > 0) {
  3767. #ifdef VMS
  3768.     binary = XYFT_I;
  3769. #else
  3770.     binary = XYFT_B;
  3771. #endif /* VMS */
  3772.     }
  3773. #ifdef CK_LABELED
  3774.     else if (pv[SND_LBL].ival > 0) {
  3775.     binary = XYFT_L;
  3776.     }
  3777. #endif /* CK_LABELED */
  3778.     debug(F101,"xsend binary","",binary);
  3779.  
  3780.     /* Check for legal combinations of switches, filenames, etc */
  3781.  
  3782. #ifdef PIPESEND
  3783.     if (pv[SND_CMD].ival > 0) {    /* COMMAND - strip any braces */
  3784.     debug(F110,"SEND /COMMAND before stripping",s,0);
  3785.     s = brstrip(s);
  3786.     debug(F110,"SEND /COMMAND after stripping",s,0);
  3787.     if (!*s) {
  3788.         printf("?Sorry, a command to send from is required\n");
  3789.         x = -9;
  3790.         goto xsendx;
  3791.     }
  3792.     }
  3793. #endif /* PIPESEND */
  3794.  
  3795. /* Set up /MOVE and /RENAME */
  3796.  
  3797.     if (pv[SND_DEL].ival > 0 &&
  3798.     (pv[SND_MOV].ival > 0 || pv[SND_REN].ival > 0)) {
  3799.     printf("?Sorry, /DELETE conflicts with /MOVE or /RENAME\n");
  3800.     x = -9;
  3801.     goto xsendx;
  3802.     }
  3803. #ifdef CK_TMPDIR
  3804.     if (pv[SND_MOV].ival > 0) {
  3805.     int len;
  3806.     char * p = pv[SND_MOV].sval;
  3807. #ifdef CK_LOGIN
  3808.     if (isguest) {
  3809.         printf("?Sorry, /MOVE-TO not available to guests\n");
  3810.         x = -9;
  3811.         goto xsendx;
  3812.     }
  3813. #endif /* CK_LOGIN */
  3814.     len = strlen(p);
  3815.     if (!isdir(p)) {        /* Check directory */
  3816. #ifdef CK_MKDIR
  3817.         char * s = NULL;
  3818.         s = (char *)malloc(len + 4);
  3819.         if (s) {
  3820.         strcpy(s,p);
  3821. #ifdef datageneral
  3822.         if (s[len-1] != ':') { s[len++] = ':'; s[len] = NUL; }
  3823. #else
  3824.         if (s[len-1] != '/') { s[len++] = '/'; s[len] = NUL; }
  3825. #endif /* datageneral */
  3826.         s[len++] = 'X';
  3827.         s[len] = NUL;
  3828.         x = zmkdir(s);
  3829.         free(s);
  3830.         if (x < 0) {
  3831.             printf("?Can't create \"%s\"\n",p);
  3832.             x = -9;
  3833.             goto xsendx;
  3834.         }
  3835.         }
  3836. #else
  3837.         printf("?Directory \"%s\" not found\n",p);
  3838.         x = -9;
  3839.         goto xsendx;
  3840. #endif /* CK_MKDIR */
  3841.     }
  3842.     makestr(&snd_move,p);
  3843.     }
  3844. #endif /* CK_TMPDIR */
  3845.  
  3846.     if (pv[SND_REN].ival > 0) {        /* /RENAME */
  3847.     char * p = pv[SND_REN].sval;
  3848. #ifdef CK_LOGIN
  3849.     if (isguest) {
  3850.         printf("?Sorry, /RENAME-TO not available to guests\n");
  3851.         x = -9;
  3852.         goto xsendx;
  3853.     }
  3854. #endif /* CK_LOGIN */
  3855.     if (!p) p = "";
  3856.     if (!*p) {
  3857.         printf("?New name required for /RENAME\n");
  3858.         x = -9;
  3859.         goto xsendx;
  3860.     }
  3861.     p = brstrip(p);
  3862. #ifndef NOSPL
  3863.     /* If name given is wild, rename string must contain variables */
  3864.     if (wild) {
  3865.         char * s = tmpbuf;
  3866.         x = TMPBUFSIZ;
  3867.         zzstring(p,&s,&x);
  3868.         if (!strcmp(tmpbuf,p)) {
  3869.         printf(
  3870.     "?/RENAME for file group must contain variables such as \\v(filename)\n"
  3871.                );
  3872.         x = -9;
  3873.         goto xsendx;
  3874.         }
  3875.     }
  3876. #endif /* NOSPL */
  3877.     makestr(&snd_rename,p);
  3878.     }
  3879.  
  3880. /* Handle /RECOVER and /START */
  3881.  
  3882. #ifdef CK_RESEND
  3883.     if (pv[SND_RES].ival > 0 && binary != XYFT_B
  3884. #ifdef PATTERNS
  3885.     && !patterns
  3886. #else
  3887. #ifdef VMS
  3888. /* VMS sets text/binary automatically later when it opens the file */
  3889.     && 0
  3890. #endif /* VMS */
  3891. #endif /* PATTERNS */
  3892.     ) {
  3893.     printf("?Sorry, /BINARY required\n");
  3894.     x = -9;
  3895.     goto xsendx;
  3896.     }
  3897.  
  3898.     if (pv[SND_STA].ival > 0) {        /* /START */
  3899.     if (wild) {
  3900.         printf("?Sorry, wildcards not permitted with /START\n");
  3901.         x = -9;
  3902.         goto xsendx;
  3903.     }
  3904.     if (sizeof(int) < 4) {
  3905.         printf("?Sorry, this command needs 32-bit integers\n");
  3906.         x = -9;
  3907.         goto xsendx;
  3908.     }
  3909. #ifdef CK_XYZ
  3910.     if (protocol != PROTO_K) {
  3911.         printf("?Sorry, SEND /START works only with Kermit protocol\n");
  3912.         x = -9;
  3913.         goto xsendx;
  3914.     }
  3915. #endif /* CK_XYZ */
  3916.     }
  3917. #ifdef CK_XYZ
  3918.     if (pv[SND_RES].ival > 0) {
  3919.     if (protocol != PROTO_K && protocol != PROTO_Z) {
  3920.         printf(
  3921.     "Sorry, /RECOVER is possible only with Kermit or ZMODEM protocol\n"
  3922.            );
  3923.         x = -9;
  3924.         goto xsendx;
  3925.     }
  3926.     }
  3927. #endif /* CK_XYZ */
  3928. #endif /* CK_RESEND */
  3929.  
  3930.     if (protocol == PROTO_K) {
  3931.     if ((pv[SND_MAI].ival > 0 ||    /* MAIL */
  3932.          pv[SND_PRI].ival > 0 ||    /* PRINT */
  3933.          pv[SND_RES].ival > 0    /* RESEND */
  3934.          ) &&
  3935.         (!atdiso || !atcapr)) {    /* Disposition attribute off? */
  3936.         printf("?Sorry, ATTRIBUTE DISPOSITION must be ON\n");
  3937.         x = -9;
  3938.         goto xsendx;
  3939.     }
  3940.     }
  3941.  
  3942. #ifdef CK_XYZ
  3943.     if (wild && (protocol == PROTO_X || protocol == PROTO_XC)) {
  3944.     printf(
  3945. "Sorry, you can only send one file at a time with XMODEM protocol\n"
  3946.            );
  3947.     x = -9;
  3948.     goto xsendx;
  3949.     }
  3950. #endif /* CK_XYZ */
  3951.  
  3952.     if (!confirmed) {            /* CR not typed yet, get more fields */
  3953.     char *m;
  3954.     if (mlist) {            /* MSEND or MMOVE */
  3955.         nfils = 0;            /* We already have the first one */
  3956. #ifndef NOMSEND
  3957.         msfiles[nfils++] = line;    /* Store pointer */
  3958.         lp = line + (int)strlen(line) + 1; /* Point past it */
  3959.         debug(F111,"xsend msend",msfiles[nfils-1],nfils-1);
  3960.         while (1) {            /* Get more filenames */
  3961.         char *p;
  3962.         if ((x = cmifi("Names of files to send, separated by spaces",
  3963.                    "", &s,&y,xxstring)) < 0) {
  3964.             if (x != -3)
  3965.               goto xsendx;
  3966.             if ((x = cmcfm()) < 0)
  3967.               goto xsendx;
  3968.             break;
  3969.         }
  3970.         msfiles[nfils++] = lp;    /* Got one, count it, point to it, */
  3971.         p = lp;            /* remember pointer, */
  3972.         while (*lp++ = *s++)    /* and copy it into buffer */
  3973.           if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
  3974.               printf("?MSEND list too long\n");
  3975.               line[0] = NUL;
  3976.               x = -9;
  3977.               goto xsendx;
  3978.           }
  3979.         debug(F111,"xsend msend",msfiles[nfils-1],nfils-1);
  3980.         if (nfils == 1) fspec[0] = NUL; /* Take care of \v(filespec) */
  3981. #ifdef ZFNQFP
  3982.         zfnqfp(p,TMPBUFSIZ,tmpbuf);
  3983.         p = tmpbuf;
  3984. #endif /* ZFNQFP */
  3985.         if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) {
  3986.             strcat(fspec,p);
  3987.             strcat(fspec," ");
  3988.         } else
  3989. #ifdef COMMENT
  3990.           printf("WARNING - \\v(filespec) buffer overflow\n");
  3991. #else
  3992.           debug(F101,"doxsend filespec buffer overflow","",0);
  3993. #endif /* COMMENT */
  3994.         }
  3995. #endif /* NOMSEND */
  3996.     } else {            /* Regular SEND */
  3997.         char *p; int y;
  3998.         nfils = -1;
  3999.         if (pv[SND_MAI].ival > 0)
  4000.           m = (pv[SND_MAI].sval) ?
  4001.         "e-mail address (optional)" :
  4002.           "e-mail address (required)";
  4003.         else if (pv[SND_PRI].ival > 0)
  4004.           m = "printer options (optional)";
  4005.         else if (wild)
  4006.           m =
  4007. "\nOptional as-name template containing replacement variables \
  4008. like \\v(filename)";
  4009.         else
  4010.           m = "Optional name to send it with";
  4011.         if ((x = cmtxt(m,"",&p,NULL)) < 0)
  4012.           goto xsendx;
  4013.         if (!p) p = "";
  4014.         if (*p) {            /* If some text was given... */
  4015.         p = brstrip(p);        /* Replace /AS-NAME: value if any */
  4016.         if ((y = strlen(p)) > 0) {
  4017.             if (pv[SND_ASN].sval) free(pv[SND_ASN].sval);
  4018.             pv[SND_ASN].sval = malloc(y+1);
  4019.             if (pv[SND_ASN].sval) {
  4020.             strcpy(pv[SND_ASN].sval,p);
  4021.             pv[SND_ASN].ival = 1;
  4022.             }
  4023.         }
  4024.         }
  4025.     }
  4026.     }
  4027.     /* Set cmarg2 from as-name, however we got it. */
  4028.  
  4029.     if (pv[SND_ASN].ival > 0 && pv[SND_ASN].sval && !*cmarg2) {
  4030.     int x;
  4031.     x = strlen(line);
  4032.     ckstrncpy(line+x+2,pv[SND_ASN].sval,LINBUFSIZ-x-1);
  4033.     cmarg2 = line+x+2;
  4034.     debug(F110,"doxsend cmarg2",cmarg2,0);
  4035.     }
  4036.  
  4037. #ifndef NOFRILLS
  4038.     if ((pv[SND_MAI].ival > 0) && (pv[SND_PRI].ival > 0)) {
  4039.     printf("Sorry, /MAIL and /PRINT are conflicting options\n");
  4040.     x = -9;
  4041.     goto xsendx;
  4042.     }
  4043.     n = 0;                /* /MAIL or /PRINT? */
  4044.     if (pv[SND_MAI].ival > 0)
  4045.       n = SND_MAI;
  4046.     else if (pv[SND_PRI].ival > 0)
  4047.       n = SND_PRI;
  4048.     if (n) {                /* Yes... */
  4049. #ifdef DEBUG
  4050.     char * p;
  4051.     if (n == SND_MAI)
  4052.       p = "/MAIL";
  4053.     else
  4054.       p = "/PRINT";
  4055.     debug(F111,"xsend",p,n);
  4056. #endif /* DEBUG */
  4057. #ifdef CK_XYZ
  4058.     if (protocol != PROTO_K) {
  4059.         printf("Sorry, %s available only with Kermit protocol\n",
  4060.            (n == SND_MAI) ? "/MAIL" : "/PRINT"
  4061.            );
  4062.         x = -9;
  4063.         goto xsendx;
  4064.     }
  4065. #endif /* CK_XYZ */
  4066.     debug(F101,"xsend print/mail wild","",wild);
  4067.     *optbuf = NUL;            /* Wipe out any old options */
  4068.     s = pv[n].sval;            /* mail address or print switch val */
  4069.     if (!s) s = "";
  4070.     debug(F110,"doxsend mail address or printer options",s,0);
  4071.     if (n == SND_MAI && !*s) {
  4072.         printf("?E-mail address required\n");
  4073.         x = -9;
  4074.         goto xsendx;
  4075.     } else if ((int)strlen(s) > 94) { /* Ensure legal size */
  4076.         printf("?%s too long\n",
  4077.            (n == SND_MAI) ?
  4078.            "E-mail address" :
  4079.            "Print option string"
  4080.            );
  4081.         x = -9;
  4082.         goto xsendx;
  4083.     }
  4084.     strcpy(optbuf,s);        /* OK, copy to option buffer */
  4085.     cmarg = line;            /* File to send */
  4086.     if (n == SND_MAI) {
  4087.         debug(F110,"xsend mailing",cmarg,0);
  4088.         debug(F110,"xsend address:",optbuf,0);
  4089.         rmailf = 1;
  4090.     } else {
  4091.         debug(F110,"xsend printing",cmarg,0);
  4092.         debug(F110,"xsend options",optbuf,0);
  4093.         rprintf = 1;
  4094.     }
  4095.     }
  4096. #endif /* NOFRILLS */
  4097.  
  4098. #ifdef CALIBRATE
  4099.     if (pv[SND_CAL].ival > 0) {        /* Handle /CALIBRATE */
  4100.     if (confirmed) {
  4101.         calibrate = pv[SND_CAL].ival * 1024L;
  4102.         sndsrc = -9;
  4103.         nfils = 1;
  4104.         wild = 0;
  4105. #ifndef NOMSEND
  4106.         addlist = 0;
  4107. #endif /* NOMSEND */
  4108.         strcpy(line,"CALIBRATION");
  4109.         s = cmarg = line;
  4110.         if (!cmarg2) cmarg2 = "";
  4111.         debug(F110,"doxsend cmarg2 calibrate",cmarg2,0);
  4112.     } else if (line[0]) {
  4113.         calibrate = 0L;
  4114.         pv[SND_CAL].ival = 0L;
  4115.     }
  4116.     }
  4117. #endif /* CALIBRATE */
  4118.  
  4119.     if (pv[SND_FIL].ival > 0) {
  4120.     if (confirmed && !calibrate) {
  4121.         if (zopeni(ZMFILE,pv[SND_FIL].sval) < 1) {
  4122.         debug(F110,"xsend can't open",pv[SND_FIL].sval,0);
  4123.         printf("?Failure to open %s\n",filefile);
  4124.         x = -9;
  4125.         goto xsendx;
  4126.         }
  4127.         makestr(&filefile,pv[SND_FIL].sval); /* Open, remember name */
  4128.         debug(F110,"xsend opened",filefile,0);
  4129.         wild = 1;
  4130.     }
  4131.     }
  4132.  
  4133.     /* SEND alone... */
  4134.  
  4135. #ifndef NOSPL
  4136.     if (confirmed && pv[SND_ARR].ival > 0) {
  4137.     if (!*cmarg2) {
  4138.         sndxnam[7] = (char)((arrayx == 1) ? 64 : arrayx + ARRAYBASE);
  4139.         cmarg2 = sndxnam;
  4140.     }
  4141.     cmarg = "";
  4142.     goto sendend;
  4143.     }
  4144. #endif /* NOSPL */
  4145.  
  4146.     if (confirmed && !line[0] && !filefile && !calibrate) {
  4147. #ifndef NOMSEND
  4148.     if (filehead) {            /* OK if we have a SEND-LIST */
  4149.         nfils = filesinlist;
  4150.         sndsrc = nfils;        /* Like MSEND */
  4151.         addlist = 1;        /* But using a different list... */
  4152.         filenext = filehead;
  4153.         if (pv[SND_DEL].ival > 0)    /* /DELETE given? */
  4154.           moving = 1;
  4155.         goto sendend;
  4156.     }
  4157. #endif /* NOMSEND */
  4158.     printf("?Filename required but not given\n");
  4159.     x = -9;
  4160.     goto xsendx;
  4161.     }
  4162.  
  4163.     /* Not send-list or array */
  4164.  
  4165. #ifndef NOMSEND
  4166.     addlist = 0;            /* Don't use SEND-LIST. */
  4167.     filenext = NULL;
  4168. #endif /* NOMSEND */
  4169.  
  4170.     if (mlist) {            /* MSEND or MMOVE */
  4171. #ifndef NOMSEND
  4172.     cmlist = msfiles;        /* List of files to send */
  4173.     sndsrc = nfils;
  4174.     cmarg2 = "";
  4175.     sendstart = 0L;
  4176. #endif /* NOMSEND */
  4177. #ifdef PIPESEND
  4178.     pipesend = 0;
  4179. #endif /* PIPESEND */
  4180.     } else if (filefile) {        /* File contains list of filenames */
  4181.     s = "";
  4182.     cmarg = "";
  4183.     cmarg2 = "";
  4184.     line[0] = NUL;
  4185.     nfils = 1;
  4186.     sndsrc = 1;
  4187.  
  4188.     } else if (!calibrate &&  pv[SND_ARR].ival < 1) {
  4189.  
  4190.     nfils = sndsrc = -1;    /* Not MSEND, MMOVE, /LIST, or /ARRAY */
  4191.     if (
  4192. #ifndef NOFRILLS
  4193.         !rmailf && !rprintf        /* Not MAIL or PRINT */
  4194. #else
  4195.         1
  4196. #endif /* NOFRILLS */
  4197.         ) {
  4198.         int y = 1;
  4199.         if (!iswild(s))
  4200.           y = zchki(s);
  4201.         if (y < 0) {
  4202.         printf("?Read access denied - \"%s\"\n", s);
  4203.         x = -9;
  4204.         goto xsendx;
  4205.         }
  4206.         if (s != line)        /* We might already have done this. */
  4207.           ckstrncpy(line,s,LINBUFSIZ); /* Copy of string just parsed. */
  4208.         else
  4209.           debug(F110,"doxsend line=s",line,0);
  4210.         cmarg = line;        /* File to send */
  4211.     }
  4212.     zfnqfp(cmarg,fspeclen,fspec);
  4213.     }
  4214.     if (!mlist) {            /* For all but MSEND... */
  4215. #ifdef PIPESEND
  4216.     if (pv[SND_CMD].ival > 0)    /* /COMMAND sets pipesend flag */
  4217.       pipesend = 1;
  4218.     debug(F101,"xsend /COMMAND pipesend","",pipesend);
  4219.     if (pipesend && filefile) {
  4220.         printf("?Invalid switch combination\n");
  4221.         x = -9;
  4222.         goto xsendx;
  4223.     }
  4224. #endif /* PIPESEND */
  4225.  
  4226. #ifndef NOSPL
  4227.     /* If as-name given and filespec is wild, as-name must contain variables */
  4228.     debug(F111,"doxsend cmarg2 wild",cmarg2,wild);
  4229.     if (wild && *cmarg2) {
  4230.         char * s = tmpbuf;
  4231.         x = TMPBUFSIZ;
  4232.         zzstring(cmarg2,&s,&x);
  4233.         if (!strcmp(tmpbuf,cmarg2)) {
  4234.         printf(
  4235.     "?As-name for file group must contain variables such as \\v(filename)\n"
  4236.                );
  4237.         x = -9;
  4238.         goto xsendx;
  4239.         }
  4240.     }
  4241. #endif /* NOSPL */
  4242.  
  4243.     /* Strip braces from as-name */
  4244.     debug(F110,"xsend cmarg2 before stripping",cmarg2,0);
  4245.     cmarg2 = brstrip(cmarg2);
  4246.     debug(F110,"xsend filename",cmarg,0);
  4247.     debug(F110,"xsend as-name",cmarg2,0);
  4248.  
  4249.     /* Copy as-name to a safe place */
  4250.  
  4251.     if (asnbuf) {
  4252.         free(asnbuf);
  4253.         asnbuf = NULL;
  4254.     }
  4255.     if ((y = strlen(cmarg2)) > 0) {
  4256.         asnbuf = (char *) malloc(y + 1);
  4257.         if (asnbuf) {
  4258.         strcpy(asnbuf,cmarg2);
  4259.         cmarg2 = asnbuf;
  4260.         } else cmarg2 = "";
  4261.     }
  4262.  
  4263. #ifdef CK_RESEND
  4264.     debug(F111,"xsend pv[SND_STA].ival","",pv[SND_STA].ival);
  4265.     if (pv[SND_STA].ival > -1) {    /* /START position */
  4266.         if (wild) {
  4267.         printf("?/STARTING-AT may not be used with multiple files.\n");
  4268.         x = -9;
  4269.         goto xsendx;
  4270.         } else
  4271.           sendstart = pv[SND_STA].ival;
  4272.     } else
  4273.       sendstart = 0L;
  4274.     debug(F110,"xsend /STARTING","",sendstart);
  4275. #endif /* CK_RESEND */
  4276.     }
  4277.  
  4278. sendend:                /* Common successful exit */
  4279.     moving = 0;
  4280.     if (pv[SND_SHH].ival > 0) {        /* SEND /QUIET... */
  4281.     g_displa = fdispla;
  4282.     fdispla = 0;
  4283.     debug(F101,"xsend display","",fdispla);
  4284.     }
  4285.  
  4286. #ifndef NOSPL                /* SEND /ARRAY... */
  4287.     if (pv[SND_ARR].ival > 0) {
  4288.     if (!ap) { x = -2; goto xsendx; } /* (shouldn't happen) */
  4289.     if (range[0] == -1)        /* If low end of range not specified */
  4290.       range[0] = 1;            /* default to 1 */
  4291.     if (range[1] == -1)        /* If high not specified */
  4292.       range[1] = a_dim[arrayx];    /* default to size of array */
  4293.     if ((range[0] < 0) ||        /* Check range */
  4294.         (range[0] > a_dim[arrayx]) ||
  4295.         (range[1] < range[0]) ||
  4296.         (range[1] > a_dim[arrayx])) {
  4297.         printf("?Bad array range - [%d:%d]\n",range[0],range[1]);
  4298.         x = -9;
  4299.         goto xsendx;
  4300.     }
  4301.     sndarray = ap;            /* Array pointer */
  4302.     sndxin = arrayx;        /* Array index */
  4303.     sndxlo = range[0];        /* Array range */
  4304.     sndxhi = range[1];
  4305.     sndxnam[7] = (char)((sndxin == 1) ? 64 : sndxin + ARRAYBASE);
  4306.  
  4307. #ifdef COMMENT
  4308.     printf("SENDING FROM ARRAY: &%c[]...\n", /* debugging */
  4309.            (sndxin == 1) ? 64 : sndxin + ARRAYBASE);
  4310.     printf("Lo=%d\nHi=%d\n", sndxlo, sndxhi);
  4311.     printf("cmarg=[%s]\ncmarg2=[%s]\n", cmarg, cmarg2);
  4312.     while ((x = agnbyte()) > -1) {
  4313.         putchar((char)x);
  4314.     }
  4315.     return(1);
  4316. #endif /* COMMENT */
  4317.     }
  4318. #endif /* NOSPL */
  4319.  
  4320.     if (pv[SND_ARR].ival < 1) {        /* File selection & disposition... */
  4321.  
  4322.     if (pv[SND_DEL].ival > 0)    /* /DELETE was specified */
  4323.       moving = 1;
  4324.     debug(F110,"xsend /DELETE","",moving);
  4325.     if (pv[SND_AFT].ival > 0)    /* Copy SEND criteria */
  4326.       ckstrncpy(sndafter,pv[SND_AFT].sval,19);
  4327.     if (pv[SND_BEF].ival > 0)
  4328.       ckstrncpy(sndbefore,pv[SND_BEF].sval,19);
  4329.     if (pv[SND_NAF].ival > 0)
  4330.       ckstrncpy(sndnafter,pv[SND_NAF].sval,19);
  4331.     if (pv[SND_NBE].ival > 0)
  4332.       ckstrncpy(sndnbefore,pv[SND_NBE].sval,19);
  4333.     if (pv[SND_EXC].ival > 0)
  4334.       makelist(pv[SND_EXC].sval,sndexcept,8);
  4335.     if (pv[SND_SMA].ival > -1)
  4336.       sndsmaller = pv[SND_SMA].ival;
  4337.     if (pv[SND_LAR].ival > -1)
  4338.       sndlarger = pv[SND_LAR].ival;
  4339.     if (pv[SND_NAM].ival > -1) {
  4340.         g_fncnv = fncnv;        /* Save global value */
  4341.         fncnv = pv[SND_NAM].ival;
  4342.         debug(F101,"xsend fncnv","",fncnv);
  4343.     }
  4344.     if (pv[SND_PTH].ival > -1) {
  4345.         g_spath = fnspath;        /* Save global values */
  4346.         fnspath = pv[SND_PTH].ival;
  4347. #ifndef NZLTOR
  4348.         if (fnspath != PATH_OFF) {
  4349.         g_fncnv = fncnv;    /* Bad bad... */
  4350.         fncnv = XYFN_C;
  4351.         }
  4352. #endif /* NZLTOR */
  4353.         debug(F101,"xsend fnspath","",fnspath);
  4354.         debug(F101,"xsend fncnv","",fncnv);
  4355.     }
  4356.     }
  4357.  
  4358. #ifdef PIPESEND
  4359.     if (pv[SND_FLT].ival > 0) {
  4360.     g_sfilter = sndfilter;
  4361.     if (!pv[SND_FLT].sval) {
  4362.         sndfilter = NULL;
  4363.     } else {
  4364.         sndfilter = (char *) malloc((int) strlen(pv[SND_FLT].sval) + 1);
  4365.         if (sndfilter) strcpy(sndfilter,pv[SND_FLT].sval);
  4366.     }
  4367.     }
  4368. #endif /* PIPESEND */
  4369.  
  4370. #ifdef CK_APC
  4371. /* MOVE not allowed in APCs */
  4372.     if (moving &&
  4373.     (apcactive == APC_LOCAL || apcactive == APC_REMOTE)
  4374.     && apcstatus != APC_UNCH)
  4375.       return(success = 0);
  4376. #endif /* CK_APC */
  4377. #ifdef IKS_OPTION
  4378.     if (!iks_wait(KERMIT_REQ_START,1)) {
  4379.         printf("?A Kermit Server is unavailable to process this command.\n");
  4380.         printf("?Start a RECEIVE command to complement this command.\n");
  4381.     }
  4382. #endif /* IKS_OPTION */
  4383.  
  4384. #ifdef IKSD
  4385. #ifdef CK_LOGIN
  4386.     if (moving && inserver && isguest) {
  4387.         printf("?File deletion not allowed for guests.\n");
  4388.     return(-9);
  4389.     }
  4390. #endif /* CK_LOGIN */
  4391. #endif /* IKSD */
  4392.  
  4393.     sstate = 's';            /* Set start state to SEND */
  4394.     sndcmd = 1;
  4395. #ifdef CK_RESEND
  4396.     if (pv[SND_RES].ival > 0)        /* Send sendmode appropriately */
  4397.       sendmode = SM_RESEND;
  4398.     else if (pv[SND_STA].ival > 0)
  4399.       sendmode = SM_PSEND;
  4400.     else
  4401. #endif /* CK_RESEND */
  4402.     if (mlist)
  4403.       sendmode = SM_MSEND;
  4404.     else
  4405.       sendmode = SM_SEND;
  4406. #ifdef MAC
  4407.     what = W_SEND;
  4408.     scrcreate();
  4409. #endif /* MAC */
  4410.     if (local && pv[SND_SHH].ival != 0) { /* If in local mode, */
  4411.     displa = 1;            /* turn on file transfer display */
  4412.     }
  4413.     x = 0;
  4414.  
  4415.   xsendx:                /* Common exit, including failure */
  4416.     debug(F101,"doxsend sndsrc","",sndsrc);
  4417.     for (i = 0; i <= SND_MAX; i++) {    /* Free malloc'd memory */
  4418.     if (pv[i].sval)
  4419.       free(pv[i].sval);
  4420.     }
  4421.     return(x);
  4422. }
  4423. #endif /* NOXFER */
  4424.  
  4425. #ifndef NOLOCAL
  4426. /*  D O X C O N N  --  CONNECT command parsing with switches */
  4427.  
  4428. #ifdef XLIMITS
  4429. #define XLIMORTRIGGER
  4430. #else
  4431. #ifdef CK_TRIGGER
  4432. #define XLIMORTRIGGER
  4433. #endif /* CK_TRIGGER */
  4434. #endif /*  XLIMITS */
  4435.  
  4436. #ifdef OS2                /* K95 only: */
  4437. extern int
  4438.   tt_idlesnd_tmo;            /*   Idle interval */
  4439. int tt_idlelimit = 0;            /*   Idle limit */
  4440. int tt_timelimit = 0;            /*   Time limit, 0 = none */
  4441. extern char *                /* Parse results - strings: */
  4442.   tt_idlesnd_str;            /*   Idle string */
  4443. #endif /* OS2 */
  4444.  
  4445. #ifdef CK_TRIGGER
  4446. extern char *tt_trigger[];
  4447. extern CHAR *tt_trmatch[];
  4448. extern char *triggerval;
  4449. #endif /* CK_TRIGGER */
  4450.  
  4451. int
  4452. doxconn(cx) int cx; {
  4453.     int c, i, n;            /* Workers */
  4454.     int x, y;
  4455.     int getval = 0;            /* Whether to get switch value */
  4456.     struct stringint {            /* Temporary array for switch values */
  4457.     char * sval;
  4458.     int ival;
  4459.     } pv[CONN_MAX+1];
  4460.     struct FDB sw, cm;            /* FDBs for each parse function */
  4461.  
  4462. #ifdef CK_TRIGGER
  4463.     char *g_tt_trigger[TRIGGERS];
  4464. #endif /* CK_TRIGGER */
  4465.  
  4466. #ifdef OS2
  4467.     int g_tt_idlesnd_tmo, g_tt_timelimit; /* For saving and restoring */
  4468.     int g_tt_idlelimit;
  4469.     char * g_tt_idlesnd_str;        /* global settings */
  4470.  
  4471.     g_tt_idlesnd_tmo = tt_idlesnd_tmo;    /* Save global settings */
  4472.     g_tt_timelimit   = tt_timelimit;
  4473.     g_tt_idlelimit   = tt_idlelimit;
  4474.     g_tt_idlesnd_str = tt_idlesnd_str;
  4475. #endif /* OS2 */
  4476.  
  4477. #ifdef CK_TRIGGER
  4478.     if (!tt_trigger[0]) {        /* First initialization */
  4479.     for (i = 1; i < TRIGGERS; i++)
  4480.       tt_trigger[i] = NULL;
  4481.     }
  4482.     for (i = 0; i < TRIGGERS; i++)
  4483.       g_tt_trigger[i] = tt_trigger[i];
  4484.     if (triggerval) {
  4485.     free(triggerval);
  4486.     triggerval = NULL;
  4487.     }
  4488. #endif /* CK_TRIGGER */
  4489.  
  4490.     for (i = 0; i <= CONN_MAX; i++) {    /* Initialize switch values */
  4491.     pv[i].sval = NULL;        /* to null pointers */
  4492.     pv[i].ival = -1;        /* and -1 int values */
  4493.     }
  4494.     if (cx == XXCQ)            /* CQ == CONNECT /QUIETLY */
  4495.       pv[CONN_NV].ival = 1;
  4496.  
  4497.     /* Set up chained parse functions... */
  4498.  
  4499.     cmfdbi(&sw,                /* First FDB - command switches */
  4500.        _CMKEY,            /* fcode */
  4501.        "Switch",            /* hlpmsg */
  4502.        "",                /* default */
  4503.        "",                /* addtl string data */
  4504.        nconntab,            /* addtl numeric data 1: tbl size */
  4505.        4,                /* addtl numeric data 2: 4 = cmswi */
  4506.        xxstring,            /* Processing function */
  4507.        conntab,            /* Keyword table */
  4508.        &cm                /* Pointer to next FDB */
  4509.        );
  4510.     cmfdbi(&cm,                /* 2nd FDB - Confirmation */
  4511.        _CMCFM,            /* fcode */
  4512.        "",                /* hlpmsg */
  4513.        "",                /* default */
  4514.        "",                /* addtl string data */
  4515.        0,                /* addtl numeric data 1 */
  4516.        0,                /* addtl numeric data 2 */
  4517.        NULL,
  4518.        NULL,
  4519.        NULL
  4520.        );
  4521.  
  4522.     while (1) {                /* Parse 0 or more switches */
  4523.     x = cmfdb(&sw);            /* Parse switch or confirmation */
  4524.     debug(F101,"doxconn cmfdb","",x);
  4525.     if (x < 0) {            /* Error */
  4526.         if (x == -9 || x == -2)
  4527.           printf("?No switches match - \"%s\"\n",atmbuf);
  4528.         goto xconnx;        /* or reparse needed */
  4529.     }
  4530.     if (cmresult.fcode != _CMKEY)    /* Break out if not a switch */
  4531.       break;
  4532.     c = cmgbrk();            /* Get break character */
  4533.     getval = (c == ':' || c == '='); /* to see how they ended the switch */
  4534.     if (getval && !(cmresult.kflags & CM_ARG)) {
  4535.         printf("?This switch does not take arguments\n");
  4536.         x = -9;
  4537.         goto xconnx;
  4538.     }
  4539.     if (!getval && (cmgkwflgs() & CM_ARG)) {
  4540.         printf("?This switch requires an argument\n");
  4541.         return(-9);
  4542.     }
  4543.     n = cmresult.nresult;        /* Numeric result = switch value */
  4544.     debug(F101,"doxconn switch","",n);
  4545.  
  4546.     switch (n) {            /* Process the switch */
  4547.       case CONN_NV:            /* Non-verbal */
  4548.         pv[n].ival = 1;
  4549.         break;
  4550. #ifdef XLIMITS
  4551.       case CONN_II:            /* Idle-interval */
  4552.       case CONN_IL:            /* Idle-limit */
  4553.       case CONN_TL:            /* Time-limit */
  4554.         if (!getval) break;
  4555.         if ((x = cmnum("Seconds","0",10,&y,xxstring)) < 0)
  4556.           goto xconnx;
  4557.         pv[n].ival = y;
  4558.         break;
  4559.       case CONN_IS:            /* Idle-string */
  4560. #endif /* XLIMITS */
  4561. #ifdef CK_TRIGGER
  4562.       case CONN_TS:            /* Trigger-string */
  4563. #endif /* CK_TRIGGER */
  4564. #ifdef XLIMORTRIGGER
  4565.         if (!getval) break;
  4566.         if ((x = cmfld("String (enclose in braces if it contains spaces)",
  4567.                "",&s,xxstring)) < 0) {
  4568.         if (x == -3) {
  4569.             printf("?String required\n");
  4570.             x = -9;
  4571.         }
  4572.         goto xconnx;
  4573.         }
  4574.         if (n != CONN_TS)
  4575.           s = brstrip(s);
  4576.         if ((y = strlen(s)) > 0) {
  4577.         if (pv[n].sval) free(pv[n].sval);
  4578.         pv[n].sval = malloc(y+1);
  4579.         if (pv[n].sval) {
  4580.             strcpy(pv[n].sval,s);
  4581.             pv[n].ival = 1;
  4582.         }
  4583.         }
  4584.         break;
  4585. #endif /* XLIMORTRIGGER */
  4586.       default:
  4587.         printf("?Unexpected switch value - %d\n",cmresult.nresult);
  4588.         x = -9;
  4589.         goto xconnx;
  4590.     }
  4591.     }
  4592.     debug(F101,"doxconn cmresult.fcode","",cmresult.fcode);
  4593.     if (cmresult.fcode != _CMCFM) {
  4594.     printf("?Unexpected function code: %d\n",cmresult.fcode);
  4595.     x = -9;
  4596.     goto xconnx;
  4597.     }
  4598.  
  4599. #ifdef OS2                /* Make results available globally */
  4600.     if (pv[CONN_IL].ival > -1)        /* Idle limit */
  4601.       tt_idlelimit = pv[CONN_IL].ival;
  4602.     if (pv[CONN_II].ival > -1)        /* Idle limit */
  4603.       tt_idlesnd_tmo = pv[CONN_II].ival;
  4604.     if (pv[CONN_IS].sval)        /* Idle string */
  4605.       if (tt_idlesnd_str = (char *)malloc((int)strlen(pv[CONN_IS].sval)+1))
  4606.     strcpy(tt_idlesnd_str,pv[CONN_IS].sval);
  4607.     if (pv[CONN_TL].ival > -1)        /* Session limit */
  4608.       tt_timelimit = pv[CONN_TL].ival;
  4609. #endif /* OS2 */
  4610.  
  4611. #ifdef CK_TRIGGER
  4612.     if (pv[CONN_TS].sval)        /* Trigger strings */
  4613.       makelist(pv[CONN_TS].sval,tt_trigger,TRIGGERS);
  4614.     for (i = 0; i < TRIGGERS; i++)    /* Trigger match pointers */
  4615.       tt_trmatch[i] = NULL;
  4616.     if (triggerval) {            /* Reset trigger value */
  4617.     free(triggerval);
  4618.     triggerval = NULL;
  4619.     }
  4620. #endif /* CK_TRIGGER */
  4621.  
  4622.     x = doconect((pv[CONN_NV].ival > 0) ? 1 : 0);
  4623. #ifdef CKLOGDIAL
  4624.     {
  4625.     int xx;
  4626.     debug(F101,"doxconn doconect returns","",x);
  4627.     if ((xx = ttchk()) < 0) dologend();
  4628.     debug(F101,"doxconn ttchk returns","",xx);
  4629.     }
  4630. #endif /* CKLOGDIAL */
  4631.  
  4632. #ifdef CK_TRIGGER
  4633.     debug(F111,"doxconn doconect triggerval",triggerval,x);
  4634. #endif /* CK_TRIGGER */
  4635.  
  4636.     /* Back from CONNECT -- Restore global settings */
  4637.  
  4638. #ifdef OS2
  4639.     tt_idlelimit   = g_tt_idlelimit;
  4640.     tt_idlesnd_tmo = g_tt_idlesnd_tmo;
  4641.     tt_timelimit   = g_tt_timelimit;
  4642.     tt_idlesnd_str = g_tt_idlesnd_str;
  4643. #endif /* OS2 */
  4644.  
  4645. #ifdef CK_TRIGGER
  4646.     for (i = 0; i < TRIGGERS; i++)
  4647.       tt_trigger[i] = g_tt_trigger[i];
  4648. #endif /* CK_TRIGGER */
  4649.  
  4650.   xconnx:
  4651.     for (i = 0; i <= CONN_MAX; i++) {    /* Free malloc'd memory */
  4652.     if (pv[i].sval)
  4653.       free(pv[i].sval);
  4654.     }
  4655.     success = (x > 0) ? 1 : 0;
  4656.     return(x);
  4657. }
  4658. #endif /* NOLOCAL */
  4659.  
  4660. #ifdef ADDCMD
  4661. /* cx == XXADD or XXREMV */
  4662. /* fc == ADD_BIN or ADD_TXT */
  4663. static int
  4664. doadd(cx,fc) int cx, fc; {
  4665. #ifdef PATTERNS
  4666.     char * tmp[FTPATTERNS];
  4667.     char **p = NULL;
  4668.     int i, n = 0, x = 0, last;
  4669. #endif /* PATTERNS */
  4670.     if (cx != XXADD && cx != XXREMV) {
  4671.     printf("?Unexpected function code: %d\n",cx);
  4672.     return(-9);
  4673.     }
  4674. #ifdef PATTERNS
  4675.     while (n < FTPATTERNS) {        /* Collect new patterns */
  4676.     tmp[n] = NULL;
  4677.     if ((x = cmfld("Pattern","",&s,xxstring)) < 0)
  4678.       break;
  4679.     strcpy(line,s);
  4680.     s = brstrip(line);
  4681.     makestr(&(tmp[n++]),s);
  4682.     }
  4683.     if (x == -3)
  4684.       x = cmcfm();
  4685.     if (x < 0)
  4686.       goto xdoadd;
  4687.     p = (fc == ADD_BIN) ? binpatterns : txtpatterns; /* Which list */
  4688.     last = 0;
  4689.     for (i = 0; i < FTPATTERNS; i++) { /* Find last one in list */
  4690.     if (!p[i]) {
  4691.         last = i;
  4692.         break;
  4693.     }
  4694.     }
  4695.     if (cx == XXADD) {            /* Adding */
  4696.     if (last + n > FTPATTERNS) {    /* Check if too many */
  4697.         printf("?Too many patterns - %d is the maximum\n", FTPATTERNS);
  4698.         goto xdoadd;
  4699.     }
  4700.     for (i = 0; i < n; i++)        /* Copy in the new ones. */
  4701.       makestr(&(p[i+last]),tmp[i]);
  4702.     makestr(&(p[i+last]),NULL);    /* Null-terminate the list */
  4703.     x = 1;
  4704.     goto xdoadd;            /* Done */
  4705.     } else if (cx == XXREMV) {        /* Remove something(s) */
  4706.     int j, k;
  4707.     if (last == 0)                    /* List is empty */
  4708.       goto xdoadd;                    /* Nothing to remove */
  4709.     for (i = 0; i < n; i++) {            /* i = Patterns they typed */
  4710.         for (j = 0; j < last; j++) {        /* j = Patterns in list */
  4711.         /* Change this to ckstrcmp()... */
  4712.         if (filecase)
  4713.           x = !strcmp(tmp[i],p[j]);     /* Case-sensitive match */
  4714.         else
  4715.           x = ckstrcmp(tmp[i],p[j],-1,0); /* Case-independent match */
  4716.         if (x) {                    /* This one matches */
  4717.             makestr(&(p[j]),NULL);      /* Free it */
  4718.             for (k = j; k < last; k++)  /* Move the rest up */
  4719.               p[k] = p[k+1];
  4720.             p[k] = NULL;            /* Erase last one */
  4721.             if (!p[k])
  4722.               break;
  4723.         }
  4724.         }
  4725.     }
  4726.     }
  4727.   xdoadd:                /* Common exit */
  4728.     for (i = 0; i < n; i++)
  4729.       if (tmp[i])
  4730.     free(tmp[i]);
  4731.     return(x);
  4732. #endif /* PATTERNS */
  4733. }
  4734.  
  4735. /* ADD SEND-LIST */
  4736.  
  4737. static int
  4738. addsend(cx) int cx; {
  4739. #ifndef NOMSEND
  4740.     extern struct keytab fttab[];
  4741.     extern int nfttyp;
  4742.     struct filelist * flp;
  4743.     char * fmode = "";
  4744.     int xmode = 0;
  4745.     int xbinary = 0;
  4746. #endif /* NOMSEND */
  4747.  
  4748. #ifdef NOMSEND
  4749.     printf("?Sorry, ADD/REMOVE SEND-LIST not available.\n");
  4750.     return(-9);
  4751. #endif /* NOMSEND */
  4752.     if (cx == XXREMV) {
  4753.     printf("?Sorry, REMOVE SEND-LIST not implemented yet.\n");
  4754.     return(-9);
  4755.     }
  4756. #ifndef NOMSEND
  4757. #ifndef XYZ_INTERNAL
  4758.     if (protocol != PROTO_K) {
  4759.        printf("?Sorry, ADD SEND-LIST does not work with external protocols\n");
  4760.        return(-9);
  4761.     }
  4762. #endif /* XYZ_INTERNAL */
  4763.  
  4764.     x = cmifi("File specification to add","", &s,&y,xxstring);
  4765.     if (x < 0) {
  4766.     if (x == -3) {
  4767.         printf("?A file specification is required\n");
  4768.         return(-9);
  4769.     } else
  4770.       return(x);
  4771.     }
  4772.     strcpy(tmpbuf,s);
  4773.     s = tmpbuf;
  4774.     if (filesinlist == 0)        /* Take care of \v(filespec) */
  4775.       fspec[0] = NUL;
  4776.     zfnqfp(s,LINBUFSIZ,line);
  4777.     s = line;
  4778.     if (((int)strlen(fspec) + (int)strlen(s) + 1) < fspeclen) {
  4779.     strcat(fspec,s);
  4780.     strcat(fspec," ");
  4781.     } else
  4782.       printf("WARNING - \\v(filespec) buffer overflow\n");
  4783.  
  4784.  
  4785.     xbinary = binary;
  4786. #ifdef PATTERNS
  4787.     if (patterns            /* PATTERNS are ON */
  4788. #ifdef CK_LABELED
  4789.     && binary != XYFT_L        /* And not if FILE TYPE LABELED */
  4790. #endif /* CK_LABELED */
  4791. #ifdef VMS
  4792.     && binary != XYFT_I        /* or FILE TYPE IMAGE */
  4793. #endif /* VMS */
  4794.     ) {
  4795.     if (binary != XYFT_T && txtpatterns[0]) {
  4796.         int i;
  4797.         for (i = 0; i < FTPATTERNS && txtpatterns[i]; i++) {
  4798.         if (ckmatch(txtpatterns[i],line,filecase,1)) {
  4799.             xbinary = XYFT_T;
  4800.             break;
  4801.         }
  4802.         }
  4803.     }
  4804.     if (binary != XYFT_B && binpatterns[0]) {
  4805.         int i;
  4806.         for (i = 0; i < FTPATTERNS && binpatterns[i]; i++) {
  4807.         if (ckmatch(binpatterns[i],line,filecase,1)) {
  4808.             xbinary = XYFT_B;
  4809.             break;
  4810.         }
  4811.         }
  4812.     }
  4813.     }
  4814. #endif /* PATTERNS */
  4815.  
  4816.     fmode = gfmode(xbinary,0);
  4817.     if ((x = cmkey(fttab,nfttyp,
  4818.            "type of file transfer", fmode, xxstring)) < 0)
  4819.       return(x);
  4820.     xmode = x;
  4821.  
  4822.     cmarg2 = "";
  4823.     if ((x = cmfld(y ?
  4824.   "\nAs-name template containing replacement variables such as \\v(filename)" :
  4825.   "Name to send it with", "",&s,NULL)) < 0)
  4826.       if (x != -3)
  4827.     return(x);
  4828. #ifndef NOSPL
  4829.     if (y && *s) {
  4830.     char * p = tmpbuf;
  4831.     x = TMPBUFSIZ;
  4832.     zzstring(s,&p,&x);
  4833.     if (!strcmp(tmpbuf,s)) {
  4834.         printf(
  4835.   "?As-name for file group must contain variables such as \\v(filename)\n"
  4836.            );
  4837.         return(-9);
  4838.     }
  4839.     }
  4840. #endif /* NOSPL */
  4841.     strcpy(tmpbuf,s);
  4842.     cmarg2 = tmpbuf;
  4843.  
  4844.     if ((x = cmcfm()) < 0)
  4845.       return(x);
  4846.     flp = (struct filelist *) malloc(sizeof(struct filelist));
  4847.     if (flp) {
  4848.     if (filetail)
  4849.       filetail->fl_next = flp;
  4850.     filetail = flp;
  4851.     if (!filehead)
  4852.       filehead = flp;
  4853.     x = (int) strlen(line);    /* Length of filename */
  4854.     s = (char *) malloc(x + 1);
  4855.     if (s) {
  4856.         strcpy(s,line);
  4857.         flp->fl_name = s;
  4858.         flp->fl_mode = xmode;
  4859.         x = (int) strlen(cmarg2);    /* Length of as-name */
  4860.         if (x < 1) {
  4861.         flp->fl_alias = NULL;
  4862.         } else {
  4863.         s = (char *) malloc(x + 1);
  4864.         if (s) {
  4865.             strcpy(s,cmarg2);
  4866.             flp->fl_alias = s;
  4867.         } else {
  4868.             printf("Sorry, can't allocate space for as-name");
  4869.             return(-9);
  4870.         }
  4871.         }
  4872.         flp->fl_next = NULL;
  4873.         filesinlist++;        /* Count this node */
  4874.         return(success = 1);    /* Finished adding this node */
  4875.     } else {
  4876.         printf("Sorry, can't allocate space for name");
  4877.         return(-9);
  4878.     }
  4879.     } else {
  4880.     printf("Sorry, can't allocate file list node");
  4881.     return(-9);
  4882.     }
  4883. #endif /* NOMSEND */
  4884. }
  4885. #endif /* ADDCMD */
  4886.  
  4887. #ifndef NOHTTP                /* HTTP ops... */
  4888. #ifdef TCPSOCKET
  4889. #define HTTP_GET 0            /* GET */
  4890. #define HTTP_PUT 1            /* PUT */
  4891. #define HTTP_POS 2            /* POST */
  4892. #define HTTP_IDX 3            /* INDEX */
  4893. #define HTTP_HED 4                      /* HEAD */
  4894. #define HTTP_DEL 5                      /* DELETE */
  4895.  
  4896. static struct keytab httptab[] = {
  4897.     "delete", HTTP_DEL, 0,
  4898.     "get",    HTTP_GET, 0,
  4899.     "head",   HTTP_HED, 0,
  4900.     "index",  HTTP_IDX, 0,
  4901.     "put",    HTTP_PUT, 0,
  4902.     "post",   HTTP_POS, 0
  4903. };
  4904. static int nhttptab = sizeof(httptab)/sizeof(struct keytab);
  4905.  
  4906. /* HTTP switches */
  4907. #define HT_SW_AG 0            /* /AGENT */
  4908. #define HT_SW_HD 1            /* /HEADER */
  4909. #define HT_SW_US 2            /* /USER */
  4910. #define HT_SW_PW 3            /* /PASSWORD */
  4911. #define HT_SW_AR 4
  4912.  
  4913. static struct keytab httpswtab[] = {
  4914.     "/agent",    HT_SW_AG, CM_ARG,
  4915. #ifndef NOSPL
  4916.     "/array",    HT_SW_AR, CM_ARG,
  4917. #endif /* NOSPL */
  4918.     "/header",   HT_SW_HD, CM_ARG,
  4919.     "/password", HT_SW_PW, CM_ARG,
  4920.     "/user",     HT_SW_US, CM_ARG,
  4921.     "", 0, 0
  4922. };
  4923. static int nhttpswtab = sizeof(httpswtab)/sizeof(struct keytab) - 1;
  4924.  
  4925. /* HTTP PUT/POST switches */
  4926. #define HT_PP_MT 0            /* /MIME-TYPE */
  4927.  
  4928. static struct keytab httpptab[] = {
  4929.     "/mime-type", HT_PP_MT, CM_ARG,
  4930.     "", 0, 0
  4931. };
  4932. static int nhttpptab = sizeof(httpptab)/sizeof(struct keytab) - 1;
  4933.  
  4934. #define HTTP_MAXHDR 8
  4935.  
  4936. static int
  4937. dohttp(action, lfile, rf, agent, hdr, user, pass, mime, array)
  4938.     int action; char *lfile, *rf, *agent, *hdr, *user, *pass, *mime, array;
  4939. /* dohttp */ {
  4940.     int i, rc = 0;
  4941.     char * hdrlist[HTTP_MAXHDR];
  4942.     char rfile[CKMAXPATH+1];
  4943.  
  4944.     /* Check for a valid state to execute the command */
  4945.     if (inserver) {
  4946.         printf("?The HTTP command may not be used from the IKS\r\n");
  4947.     } else if (!local || ttchk() < 0) {
  4948.     printf("?No connection\n");
  4949.     } else if (!network) {
  4950.     printf("?The HTTP command is not for serial connections\n");
  4951.     } else if (nettype != NET_TCPB && nettype != NET_TCPA) {
  4952.     printf("?The HTTP command only for TCP/IP connections\n");
  4953.     } else {
  4954.     rc = 1;
  4955.     }
  4956.  
  4957.     /* If the command is not valid, exit with failure */
  4958.     if (rc == 0)
  4959.         return(success = 0);
  4960.  
  4961.     if (rf[0] != '/') {
  4962.         rfile[0] = '/';
  4963.         ckstrncpy(&rfile[1],rf,CKMAXPATH);
  4964.     } else {
  4965.         ckstrncpy(rfile,rf,CKMAXPATH);
  4966.     }
  4967.     for (i = 0; i < HTTP_MAXHDR; i++)    /* Initialize header list */
  4968.       hdrlist[i] = NULL;
  4969.     makelist(hdr,hdrlist,HTTP_MAXHDR);    /* Make header list */
  4970.  
  4971. #ifdef BETATEST
  4972.     for (i = 0; i < nhttptab; i++)    /* Find action keyword */
  4973.       if (httptab[i].kwval == action)
  4974.     break;
  4975.     if (i == nhttptab) {        /* Shouldn't happen... */
  4976.     printf("?Invalid action - %d\n",action);
  4977.     return(success = 0);
  4978.     }
  4979.  
  4980.     printf("HTTP action:  %s\n",httptab[i].kwd);
  4981.     printf(" Agent:       %s\n",agent ? agent : "(null)");
  4982.  
  4983.     if (hdrlist[1]) {
  4984.     printf(" Header list: 1. %s\n",hdrlist[0]);
  4985.     for (i = 1; i < HTTP_MAXHDR && hdrlist[i]; i++)
  4986.       printf("%15d. %s\n",i+1,hdrlist[i]);
  4987.     } else
  4988.       printf(" Header:      %s\n",hdrlist[0] ? hdrlist[0] : "(null)");
  4989.  
  4990.     printf(" User:        %s\n",user ? user : "(null)");
  4991.     printf(" Password:    %s\n",pass ? pass : "(null)");
  4992.  
  4993. #ifndef NOSPL
  4994.     if (array)
  4995.       printf(" Array:       \\%%%c[]\n", array);
  4996.     else
  4997.       printf(" Array:       (none)\n");
  4998. #endif /* NOSPL */
  4999.  
  5000.     if (action == HTTP_PUT || action == HTTP_POS)
  5001.       printf(" Mime-type:   %s\n",mime ? mime : "(null)");
  5002.  
  5003.     printf(" Local file:  %s\n",lfile ? lfile : "(null)");
  5004.     printf(" Remote file: %s\n",rfile ? rfile : "(null)");
  5005. #endif /* BETATEST */
  5006.     switch (action) {
  5007.       case HTTP_DEL:
  5008.         rc = http_delete(agent,hdrlist,user,pass,array,rfile);
  5009.         break;
  5010.       case HTTP_GET:
  5011.         rc = http_get(agent,hdrlist,user,pass,array,lfile,rfile);
  5012.         break;
  5013.       case HTTP_HED:
  5014.         rc = http_head(agent,hdrlist,user,pass,array,lfile,rfile);
  5015.         break;
  5016.       case HTTP_PUT:
  5017.         rc = http_put(agent,hdrlist,mime,user,pass,array,lfile,rfile);
  5018.         break;
  5019.       case HTTP_POS:
  5020.         rc = http_post(agent,hdrlist,mime,user,pass,array,lfile,rfile);
  5021.         break;
  5022.       case HTTP_IDX:
  5023.         rc = http_index(agent,hdrlist,user,pass,array,lfile,rfile);
  5024.         break;
  5025.     }
  5026.     return(success = ((rc < 0) ? 0 : 1));
  5027. }
  5028. #endif /* TCPSOCKET */
  5029. #endif /* NOHTTP */
  5030.  
  5031. #ifndef NOSPL                /* ARRAY ops... */
  5032. static struct keytab arraytab[] = {
  5033.     "clear",    ARR_CLR, 0,
  5034.     "copy",     ARR_CPY, 0,
  5035.     "dcl",      ARR_DCL, CM_INV,
  5036.     "declare",  ARR_DCL, 0,
  5037.     "destroy",  ARR_DST, 0,
  5038.     "resize",   ARR_RSZ, 0,
  5039.     "set",      ARR_SET, 0,
  5040. #ifndef NOSHOW
  5041.     "show",     ARR_SHO, 0,
  5042. #endif /* NOSHOW */
  5043.     "sort",     ARR_SRT, 0,
  5044.     "", 0, 0
  5045. };
  5046. static int narraytab = sizeof(arraytab)/sizeof(struct keytab) - 1;
  5047.  
  5048. int
  5049. arrayitoa(x) int x; {            /* Array index to array letter */
  5050.     if (x == 1)
  5051.       return(64);
  5052.     else if (x < 0 || x > (122 - ARRAYBASE))
  5053.       return(-1);
  5054.     else
  5055.       return(x + ARRAYBASE);
  5056. }
  5057.  
  5058. int
  5059. arrayatoi(c) int c; {            /* Array letter to array index */
  5060.     if (c == 64)
  5061.       c = 96;
  5062.     if (c > 63 && c < 91)
  5063.       c += 32;
  5064.     if (c < ARRAYBASE || c > 122)
  5065.       return(-1);
  5066.     return(c - ARRAYBASE);
  5067. }
  5068.  
  5069. static int
  5070. dodcl() {
  5071.     int i, n, v, lo, hi, rc = 0;
  5072.     int isdynamic = 0;
  5073.     char ** p = NULL;
  5074.     char tmp[64];            /* Local temporary string buffer */
  5075.     if ((y = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
  5076.     if (y == -3) {
  5077.         printf("?Array name required\n");
  5078.         return(-9);
  5079.     } else return(y);
  5080.     }
  5081. #ifdef COMMENT
  5082.     if ((y = arraynam(s,&x,&n)) < 0) {    /* Check it */
  5083.     if (y == -2 && n == -17) {    /* Secret code for emtpy brackets */
  5084.         isdynamic = 1;
  5085.         n = CMDBL / 5;
  5086.     } else {
  5087.         return(y);
  5088.     }
  5089.     }
  5090.     debug(F111,"DCL",s,n);
  5091. #else
  5092.     ckstrncpy(line,s,LINBUFSIZ);
  5093.     s = line;
  5094.     x = arraybounds(s,&lo,&hi);
  5095.     if (lo < 0 && hi < 0) {
  5096.     isdynamic = 1;
  5097.     n = CMDBL / 5;
  5098.     } else if (hi > -1) {
  5099.     printf("?Segment notation not allowed in array declarations\n");
  5100.     return(-9);
  5101.     } else
  5102.       n = lo;
  5103.     x = arrayitoa(x);
  5104. #endif /* COMMENT */
  5105.     p = (char **)malloc(sizeof(char **)*(n+1));
  5106.     if (!p) {
  5107.     printf("?Memory allocation error\n");
  5108.     return(-9);
  5109.     }
  5110.     v = 0;                /* Highest initialized member */
  5111.     p[0] = NULL;            /* Element 0 */
  5112.     while (n > 0 && v < n) {        /* Parse initializers */
  5113.     p[v+1] = NULL;
  5114.     sprintf(tmp,"Initial value for \\&%c[%d]",x,v+1); /* Help string */
  5115.     if ((rc = cmfld((char *)tmp,"",&s,xxstring)) < 0) { /* Get field */
  5116.         if (rc == -3)        /* If answer is empty, we're done */
  5117.           break;
  5118.         else            /* Parse error, free temp pointers */
  5119.           goto dclx;
  5120.     }
  5121.     rc = 1;
  5122.     if (v == 0 && !strcmp(s,"="))    /* Skip the = sign. */
  5123.       continue;
  5124.     s = brstrip(s);            /* Strip any braces */
  5125.     makestr(&(p[++v]),s);
  5126.     }
  5127.     if ((y = cmtxt("Carriage return to confirm","",&s,NULL)) < 0)
  5128.       return(y);
  5129.     if (isdynamic)
  5130.       n = v;
  5131.     if (dclarray((char)x,n) < 0) {    /* Declare the array */
  5132.     printf("?Declare failed\n");
  5133.     goto dclx;
  5134.     }
  5135.     for (i = 1; i <= v; i++) {        /* Add any initial values */
  5136.     sprintf(tmp,"&%c[%d]",(char)x,i);
  5137.     if (addmac(tmp,p[i]) < 0) {
  5138.         printf("Array initialization error: %s %s\n",tmp,p[i]);
  5139.         rc = -9;
  5140.         goto dclx;
  5141.     }
  5142.     }
  5143.   dclx:
  5144.     if (p) {
  5145.     for (i = 1; i <= v; i++)
  5146.       if (p[i]) free(p[i]);
  5147.     free(p);
  5148.     }
  5149.     debug(F101,"DCL rc","",rc);
  5150.     return(success = rc);
  5151. }
  5152.  
  5153. static int
  5154. rszarray() {
  5155.     int i, x, y, n, lo, hi;
  5156.     char c, * s, ** ap = NULL;
  5157.     if ((x = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
  5158.     if (x == -3) {
  5159.         printf("?Array name required\n");
  5160.         return(-9);
  5161.     } else return(x);
  5162.     }
  5163.     ckstrncpy(line,s,LINBUFSIZ);    /* Make safe copy of name */
  5164.     s = line;
  5165.     x = arraybounds(s,&lo,&hi);
  5166.     if (lo < 0 && hi < 0) {
  5167.     y = cmnum("New size","",10,&lo,xxstring);
  5168.     if (y < 0) {
  5169.         if (y == -3)
  5170.           printf("?New size required\n");
  5171.         return(y);
  5172.     }
  5173.     }
  5174.     if ((y = cmcfm()) < 0)
  5175.       return(y);
  5176.     if (x < 0) {            /* Parse the name, get index */
  5177.     printf("?Bad array reference - \"%s\"\n", s);
  5178.     return(-9);
  5179.     }
  5180.     if (!a_ptr[x]) {
  5181.     printf("?Array not declared - \"%s\"\n", s);
  5182.     return(-9);
  5183.     }
  5184.     if (lo < 0) {
  5185.     printf("?New size required\n");
  5186.     return(-9);
  5187.     }
  5188.     if (hi > -1) {
  5189.     printf("?Array segments not allowed for this operation\n");
  5190.     return(-9);
  5191.     }
  5192.     c = arrayitoa(x);            /* Get array letter */
  5193.     if (c == '@') {            /* Argument vector array off limits */
  5194.     printf("?Sorry, \\&@[] is read-only\n");
  5195.     return(-9);
  5196.     }
  5197.     if (lo == 0) {            /* If new size is 0... */
  5198.     dclarray(c,0);            /* Undeclare the array */
  5199.     return(success = 1);
  5200.     }
  5201.     n = a_dim[x];            /* Current size */
  5202.     ap = (char **) malloc((lo+1) * sizeof(char *)); /* New array */
  5203.     y = (n < lo) ? n : lo;
  5204.     for (i = 0; i <= y; i++)        /* Copy the part that fits */
  5205.       ap[i] = a_ptr[x][i];
  5206.     if (n < lo) {            /* If original array smaller */
  5207.     for (; i <= lo; i++)        /* initialize extra elements in */
  5208.       ap[i] = NULL;            /* new array to NULL. */
  5209.     } else if (n > lo) {        /* If new array smaller */
  5210.     for (; i <= lo; i++)        /* deallocate leftover elements */
  5211.       makestr(&(a_ptr[x][i]),NULL);    /* from original array. */
  5212.     }
  5213.     free(a_ptr[x]);            /* Free original array list */
  5214.     a_ptr[x] = ap;            /* Replace with new one */
  5215.     a_dim[x] = lo;            /* Record the new dimension */
  5216.     return(success = 1);
  5217. }
  5218.  
  5219. static int
  5220. copyarray() {
  5221.     int i, j, x1, lo1, hi1, x2, lo2, hi2, whole = 0;
  5222.     char c1, c2, * a1, * a2;
  5223.     if ((y = cmfld("Name of source array","",&s,NULL)) < 0)
  5224.       return(y);
  5225.     ckstrncpy(line,s,LINBUFSIZ);
  5226.     a1 = line;
  5227.     if ((x1 = arraybounds(a1,&lo1,&hi1)) < 0) {
  5228.     printf("?Bad array reference - \"%s\"\n", a1);
  5229.     return(-9);
  5230.     } else if (!a_ptr[x1]) {
  5231.     printf("?Array not declared - \"%s\"\n", a1);
  5232.     return(-9);
  5233.     }
  5234.     c1 = arrayitoa(x1);
  5235.  
  5236.     if ((y = cmfld("Name of destination array","",&s,NULL)) < 0)
  5237.       return(y);
  5238.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  5239.     a2 = tmpbuf;
  5240.     if ((x2 = arraybounds(a2,&lo2,&hi2)) < 0) {
  5241.     printf("?Bad array reference - \"%s\"\n", a2);
  5242.     return(-9);
  5243.     }
  5244.     c2 = arrayitoa(x2);
  5245.  
  5246.     if ((x = cmcfm()) < 0)
  5247.       return(x);
  5248.  
  5249.     if (c2 == '@') {            /* Argument vector array off limits */
  5250.     printf("?Sorry, \\&@[] is read-only\n");
  5251.     return(-9);
  5252.     }
  5253.     if (lo1 < 0 && lo2 < 0 && hi1 < 0 && hi2 < 0) /* Special case for */
  5254.       whole = 1;                      /* whole array... */
  5255.  
  5256.     if (lo1 < 0) lo1 = whole ? 0 : 1;    /* Supply lower bound of source */
  5257.     if (hi1 < 0) hi1 = a_dim[x1];    /* Supply upper bound of source */
  5258.     if (lo2 < 0) lo2 = whole ? 0 : 1;    /* Lower bound of target */
  5259.     if (hi2 < 0) hi2 = lo2 + hi1 - lo1;    /* Upper bound of target */
  5260.     if (a_ptr[x2]) {            /* Target array is already declared? */
  5261.     if (hi2 > a_dim[x2])        /* If upper bound out of range */
  5262.       hi2 = a_dim[x2];        /* shrink to fit */
  5263.     } else {                /* Otherwise... */
  5264.     x2 = dclarray(c2, hi2);        /* declare the target array */
  5265.     }
  5266.     for (i = lo1, j = lo2; i <= hi1 && j <= hi2; i++,j++) { /* Copy */
  5267.     makestr(&(a_ptr[x2][j]),a_ptr[x1][i]);
  5268.     }
  5269.     return(success = 1);
  5270. }
  5271.  
  5272. static int                /* Undeclare an array */
  5273. unarray() {
  5274.     int x, y, n, rc = 0;
  5275.     char c, * s;
  5276.  
  5277.     if ((y = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
  5278.     if (y == -3) {
  5279.         printf("?Array name required\n");
  5280.         return(-9);
  5281.     } else return(y);
  5282.     }
  5283.     ckstrncpy(line,s,LINBUFSIZ);    /* Make safe copy of name */
  5284.     s = line;
  5285.     if ((y = cmcfm()) < 0)
  5286.       return(y);
  5287.     if ((x = arraybounds(s,&y,&n)) < 0) { /* Parse the name, get index */
  5288.     printf("?Bad array reference - \"%s\"\n", s);
  5289.     return(-9);
  5290.     }
  5291.     if (y > 0 || n > 0) {
  5292.     printf("?Partial arrays can not be destroyed\n");
  5293.     return(-9);
  5294.     }
  5295.     c = arrayitoa(x);            /* Get array letter */
  5296.     if (a_ptr[x]) {            /* If array is declared */
  5297.     if (c == '@') {            /* Argument vector array off limits */
  5298.         printf("?Sorry, \\&@[] is read-only\n");
  5299.         return(-9);
  5300.     }
  5301.     rc = dclarray(c,0);        /* Undeclare the array */
  5302.     } else                /* It wasn't declared */
  5303.       rc = 1;
  5304.     if (rc > -1) {            /* Set return code and success */
  5305.     success = 1;
  5306.     rc = 1;
  5307.     } else {
  5308.     success = 0;
  5309.     printf("?Failed - destroy \"\\&%c[]\"\n", c);
  5310.     rc = -9;
  5311.     }
  5312.     return(rc);
  5313. }
  5314.  
  5315. static int
  5316. clrarray(cx) int cx; {
  5317.     int i, x, lo, hi;
  5318.     char c, * s, * val = NULL;
  5319.  
  5320.     if ((x = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
  5321.     if (x == -3) {
  5322.         printf("?Array name required\n");
  5323.         return(-9);
  5324.     } else return(x);
  5325.     }
  5326.     ckstrncpy(line,s,LINBUFSIZ);    /* Make safe copy of name */
  5327.     s = line;
  5328.     if (cx == ARR_SET) {        /* SET */
  5329.     if ((x = cmtxt("Value","",&val,xxstring)) < 0)
  5330.       return(x);
  5331.     ckstrncpy(tmpbuf,val,TMPBUFSIZ); /* Value to set */
  5332.     val = tmpbuf;
  5333.     if (!*val) val = NULL;
  5334.     } else if ((x = cmcfm()) < 0)    /* CLEAR */
  5335.       return(x);
  5336.  
  5337.     if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Parse the name */
  5338.     printf("?Bad array reference - \"%s\"\n", s);
  5339.     return(-9);
  5340.     }
  5341.     c = arrayitoa(x);            /* Get array letter */
  5342.     if (!a_ptr[x]) {            /* If array is declared */
  5343.     printf("?Array %s is not declared\n", s);
  5344.     return(-9);
  5345.     } else if (c == '@') {        /* Argument vector array off limits */
  5346.     printf("?Sorry, \\&@[] is read-only\n");
  5347.     return(-9);
  5348.     }
  5349.     if (lo < 0) lo = 0;
  5350.     if (hi < 0) hi = a_dim[x];
  5351.     for (i = lo; i <= hi; i++)        /* Clear/Set selected range */
  5352.       makestr(&(a_ptr[x][i]),val);
  5353.  
  5354.     return(success = 1);
  5355. }
  5356. #endif /* NOSPL */
  5357.  
  5358. /*  D O C M D  --  Do a command  */
  5359.  
  5360. /*
  5361.  Returns:
  5362.    -2: user typed an illegal command
  5363.    -1: reparse needed
  5364.     0: parse was successful (even tho command may have failed).
  5365. */
  5366. int
  5367. docmd(cx) int cx; {
  5368.  
  5369.     debug(F101,"docmd entry, cx","",cx);
  5370.     activecmd = cx;
  5371.     doconx = ((activecmd == XXCON)  || (activecmd == XXTEL) ||
  5372.           (activecmd == XXRLOG) || (activecmd == XXPIPE) ||
  5373.               (activecmd == XXIKSD) || (activecmd == XXPTY));
  5374. /*
  5375.   Massive switch() broken up into many smaller ones, for the benefit of
  5376.   compilers that run out of space when trying to handle large switch
  5377.   statements.
  5378. */
  5379.     switch (cx) {
  5380.       case -4:            /* EOF */
  5381. #ifdef OSK
  5382.     if (msgflg)  printf("\n");
  5383. #else
  5384.     if (msgflg)  printf("\r\n");
  5385. #endif /* OSK */
  5386.       doexit(GOOD_EXIT,xitsta);
  5387.       case -3:                /* Null command */
  5388.     return(0);
  5389.       case -9:                /* Like -2, but errmsg already done */
  5390.       case -1:                /* Reparse needed */
  5391.     return(cx);
  5392.       case -6:                /* Special */
  5393.       case -2:                /* Error, maybe */
  5394. #ifndef NOSPL
  5395. /*
  5396.   Maybe they typed a macro name.  Let's look it up and see.
  5397. */
  5398.     if (cx == -6)            /* If they typed CR */
  5399.       strcat(cmdbuf,"\015");    /*  add it back to command buffer. */
  5400.     if (ifcmd[cmdlvl] == 2)        /* Watch out for IF commands. */
  5401.       ifcmd[cmdlvl]--;
  5402.     repars = 1;            /* Force reparse */
  5403.     cmres();
  5404.     cx = XXDO;            /* Try DO command */
  5405. #else
  5406.     return(cx);
  5407. #endif /* NOSPL */
  5408.       default:
  5409.     break;
  5410.     }
  5411.  
  5412. #ifndef NOSPL
  5413. /* Copy macro args from/to two levels up, used internally by _floop et al. */
  5414.     if (cx == XXGTA || cx == XXPTA) {    /* _GETARGS, _PUTARGS */
  5415.     int x;
  5416.     debug(F101,"docmd XXGTA","",XXGTA);
  5417.     debug(F101,"docmd cx","",cx);
  5418.     debug(F101,"docmd XXGTA maclvl","",maclvl);
  5419.     x = dogta(cx);
  5420.     debug(F101,"docmd dogta returns","",x);
  5421.     debug(F101,"docmd dogta maclvl","",maclvl);
  5422.     return(x);
  5423.     }
  5424. #endif /* NOSPL */
  5425.  
  5426. #ifndef NOSPL
  5427. #ifdef CKCHANNELIO
  5428.     if (cx == XXFILE)
  5429.       return(dofile(cx));
  5430.     else if (cx == XXF_RE || cx == XXF_WR || cx == XXF_OP ||
  5431.          cx == XXF_CL || cx == XXF_SE || cx == XXF_RW ||
  5432.          cx == XXF_FL || cx == XXF_LI || cx == XXF_ST || cx == XXF_CO)
  5433.       return(dofile(cx));
  5434. #endif /* CKCHANNELIO */
  5435.  
  5436. /* ASK, ASKQ, READ */
  5437.     if (cx == XXASK  || cx == XXASKQ || cx == XXREA ||
  5438.     cx == XXRDBL || cx == XXGETC || cx == XXGETK) {
  5439.     return(doask(cx));
  5440.     }
  5441. #endif /* NOSPL */
  5442.  
  5443. #ifndef NOFRILLS
  5444.     if (cx == XXBUG) {            /* BUG */
  5445.     if ((x = cmcfm()) < 0) return(x);
  5446.     return(dobug());
  5447.     }
  5448. #endif /* NOFRILLS */
  5449.  
  5450. #ifndef NOXFER
  5451.     if (cx == XXBYE) {            /* BYE */
  5452.     bye_active = 1;
  5453. #ifdef CK_XYZ
  5454.     if (protocol != PROTO_K) {
  5455.         printf("Sorry, BYE only works with Kermit protocol\n");
  5456.         return(-9);
  5457.     }
  5458. #endif /* CK_XYZ */
  5459.     if ((x = cmcfm()) < 0) return(x);
  5460.  
  5461. #ifdef IKS_OPTION
  5462.         if (!iks_wait(KERMIT_REQ_START,1)) {
  5463.         printf(
  5464.          "?A Kermit Server is unavailable to process this command\n");
  5465.         return(-9);            /* Correct the return code */
  5466.         }
  5467. #endif /* IKS_OPTION */
  5468.  
  5469.     sstate = setgen('L',"","","");
  5470.     if (local) ttflui();        /* If local, flush tty input buffer */
  5471.     return(0);
  5472.     }
  5473. #endif /* NOXFER */
  5474.  
  5475.     if (cx == XXBEEP) {            /* BEEP */
  5476.         int x;
  5477. #ifdef OS2
  5478.     int y;
  5479.         if ((y = cmkey(beeptab, nbeeptab, "which kind of beep", "information",
  5480.                xxstring)) < 0 )
  5481.       return (y);
  5482.         if ((x = cmcfm()) < 0) return(x);
  5483.         bleep((short)y);        /* y is one of the BP_ values */
  5484. #else  /* OS2 */
  5485.         if ((x = cmcfm()) < 0) return(x);
  5486. #ifndef NOSPL
  5487.         bleep(BP_NOTE);
  5488. #else
  5489.     putchar('\07');
  5490. #endif /* NOSPL */
  5491. #endif /* OS2 */
  5492.         return(0);
  5493.     }
  5494.  
  5495. #ifndef NOFRILLS
  5496.     if (cx == XXCLE) {            /* CLEAR */
  5497.     if ((x = cmkey(clrtab,nclear,"item to clear",
  5498. #ifdef NOSPL
  5499.           "device-buffer"
  5500. #else
  5501.           "device-and-input"
  5502. #endif /* NOSPL */
  5503.           ,xxstring)) < 0) return(x);
  5504. #ifndef NOSPL
  5505. #ifdef OS2
  5506.         if (x == CLR_CMD || x == CLR_TRM) {
  5507.             if ((z = cmkey(clrcmdtab,nclrcmd,"how much screen to clear\n",
  5508.                "all",xxstring)) < 0)
  5509.           return(z);
  5510.         }
  5511. #endif /* OS2 */
  5512. #endif /* NOSPL */
  5513.     if ((y = cmcfm()) < 0) return(y);
  5514.  
  5515.     /* Clear device input buffer if requested */
  5516.     y = (x & CLR_DEV) ? ttflui() : 0;
  5517.  
  5518.     if (x & CLR_SCR)        /* CLEAR SCREEN */
  5519.       y = ck_cls();            /* (= SCREEN CLEAR = CLS) */
  5520.  
  5521. #ifndef NOSPL
  5522.     /* Clear INPUT command buffer if requested */
  5523.     if (x & CLR_INP) {
  5524.         for (z = 0; z < inbufsize; z++)
  5525.           inpbuf[z] = NUL;
  5526.         inpbp = inpbuf;
  5527.         y = 0;
  5528.     }
  5529. #ifdef CK_APC
  5530.     if (x & CLR_APC) {
  5531.         debug(F101,"Executing CLEAR APC","",apcactive);
  5532.         apcactive = 0;
  5533.         y = 0;
  5534.     }
  5535. #endif /* CK_APC */
  5536.     if (x & CLR_ALR) {
  5537.         setalarm(0L);
  5538.         y = 0;
  5539.     }
  5540. #endif /* NOSPL */
  5541.  
  5542. #ifdef PATTERNS
  5543.     if (x & CLR_TXT|CLR_BIN) {
  5544.         int i;
  5545.         for (i = 0; i < FTPATTERNS; i++) {
  5546.         if (x & CLR_TXT)
  5547.           makestr(&txtpatterns[i],NULL);
  5548.         if (x & CLR_BIN)
  5549.           makestr(&binpatterns[i],NULL);
  5550.         }
  5551.         y = 0;
  5552.     }
  5553. #endif /* PATTERNS */
  5554.  
  5555. #ifndef NODIAL
  5556.     if (x & CLR_DIA) {
  5557.         dialsta = DIA_UNK;
  5558.         y = 0;
  5559.     }
  5560. #endif /* NODIAL */
  5561.  
  5562. #ifndef NOMSEND
  5563.     if (x & CLR_SFL) {        /* CLEAR SEND-LIST */
  5564.         if (filehead) {
  5565.         struct filelist * flp, * next;
  5566.         flp = filehead;
  5567.         while (flp) {
  5568.             if (flp->fl_name)
  5569.               free(flp->fl_name);
  5570.             if (flp->fl_alias)
  5571.               free(flp->fl_alias);
  5572.             next = flp->fl_next;
  5573.             free(flp);
  5574.             flp = next;
  5575.         }
  5576.         }
  5577.         filesinlist = 0;
  5578.         filehead = NULL;
  5579.         filetail = NULL;
  5580.         y = 0;
  5581.     }
  5582. #endif /* NOMSEND */
  5583.  
  5584. #ifdef OS2
  5585.     switch (x) {
  5586.       case CLR_SCL:
  5587.         clearscrollback(VTERM);
  5588.         break;
  5589.       case CLR_CMD:
  5590.         switch ( z ) {
  5591.           case CLR_C_ALL:
  5592.         clear();
  5593.         break;
  5594.           case CLR_C_BOS:
  5595.         clrboscr_escape(VCMD,SP);
  5596.         break;
  5597.           case CLR_C_BOL:
  5598.         clrbol_escape(VCMD,SP);
  5599.         break;
  5600.           case CLR_C_EOL:
  5601.         clrtoeoln(VCMD,SP);
  5602.         break;
  5603.           case CLR_C_EOS:
  5604.         clreoscr_escape(VCMD,SP);
  5605.         break;
  5606.           case CLR_C_LIN:
  5607.         clrline_escape(VCMD,SP);
  5608.         break;
  5609.           case CLR_C_SCR:
  5610.         clearscrollback(VCMD);
  5611.         break;
  5612.             default:
  5613.         printf("Not implemented yet, sorry.\n");
  5614.         break;
  5615.         }
  5616.         break;
  5617.  
  5618.       case CLR_TRM:
  5619.              switch ( z ) {
  5620.           case CLR_C_ALL:
  5621.                  if (VscrnGetBufferSize(VTERM) > 0 ) {
  5622.                      VscrnScroll(VTERM, UPWARD, 0,
  5623.                  VscrnGetHeight(VTERM)-(tt_status?2:1),
  5624.                  VscrnGetHeight(VTERM) -
  5625.                  (tt_status?1:0), TRUE, SP
  5626.                  );
  5627.                      cleartermscreen(VTERM);
  5628.                  }
  5629.                  break;
  5630.           case CLR_C_BOS:
  5631.         clrboscr_escape(VTERM,SP);
  5632.         break;
  5633.           case CLR_C_BOL:
  5634.         clrbol_escape(VTERM,SP);
  5635.         break;
  5636.           case CLR_C_EOL:
  5637.         clrtoeoln(VTERM,SP);
  5638.         break;
  5639.           case CLR_C_EOS:
  5640.         clreoscr_escape(VTERM,SP);
  5641.         break;
  5642.           case CLR_C_LIN:
  5643.         clrline_escape(VTERM,SP);
  5644.         break;
  5645.              case CLR_C_SCR:
  5646.                  clearscrollback(VTERM);
  5647.                  break;
  5648.              default:
  5649.                  printf("Not implemented yet, sorry.\n");
  5650.                  break;
  5651.         }
  5652.         break;
  5653.     }
  5654.     y = 0;
  5655. #endif /* OS2 */
  5656.     return(success = (y == 0));
  5657.     }
  5658. #endif /* NOFRILLS */
  5659.  
  5660.     if (cx == XXCOM) {            /* COMMENT */
  5661.     if ((x = cmtxt("Text of comment line","",&s,NULL)) < 0)
  5662.       return(x);
  5663.     /* Don't change SUCCESS flag for this one */
  5664.     return(0);
  5665.     }
  5666.  
  5667. #ifndef NOLOCAL
  5668.     if (cx == XXCON || cx == XXCQ)    /* CONNECT or CONNECT /QUIETLY */
  5669.       return(doxconn(cx));
  5670. #endif /* NOLOCAL */
  5671.  
  5672. #ifndef NOFRILLS
  5673. #ifdef ZCOPY
  5674.     if (cx == XXCPY) {            /* COPY a file */
  5675. #ifdef IKSD
  5676.     if (inserver && !ENABLED(en_cpy)) {
  5677.         printf("?Sorry, COPY is disabled\n");
  5678.         return(-9);
  5679.     }
  5680. #endif /* IKSD */
  5681. #ifdef CK_APC
  5682.     if (apcactive == APC_LOCAL ||
  5683.         (apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  5684.         )
  5685.       return(success = 0);
  5686. #endif /* CK_APC */
  5687.     return(docopy());
  5688.     }
  5689. #endif /* ZCOPY */
  5690. #endif /* NOFRILLS */
  5691.  
  5692.     if (cx == XXCWD || cx == XXBACK) {    /* CD or BACK */
  5693. #ifdef IKSD
  5694.     if (inserver && !ENABLED(en_cwd)) {
  5695.         printf("?Sorry, changing directories is disabled\n");
  5696.         return(-9);
  5697.     }
  5698. #endif /* IKSD */
  5699.     return(success = docd(cx));
  5700.     }
  5701.  
  5702.     if (cx == XXCHK)            /* CHECK */
  5703.       return(success = dochk());
  5704.  
  5705.     if (cx == XXCLO) {            /* CLOSE */
  5706.     x = cmkey(clstab,ncls,"\"CONNECTION\", or log or file to close",
  5707.           "connection",xxstring);
  5708.     if (x == -3) {
  5709.         printf("?You must say which file or log\n");
  5710.         return(-9);
  5711.     }
  5712.     if (x < 0) return(x);
  5713.     if ((y = cmcfm()) < 0) return(y);
  5714. #ifndef NOLOCAL
  5715.     if (x == 9999) {        /* CLOSE CONNECTION */
  5716.         x = clsconnx(0);
  5717.         switch (x) {
  5718.           case 0:
  5719.         if (msgflg) printf("?Connection was not open\n");
  5720.           case -1:
  5721.         return(0);
  5722.           case 1:
  5723.         whyclosed = WC_CLOS;
  5724.         return(1);
  5725.         }
  5726.         return(0);
  5727.     }
  5728. #endif /* NOLOCAL */
  5729.     y = doclslog(x);
  5730.     success = (y == 1);
  5731.     return(success);
  5732.     }
  5733.  
  5734. #ifndef NOSPL
  5735.     if (cx == XX_INCR || cx == XXINC  || /* _INCREMENT, INCREMENT */
  5736.     cx == XX_DECR || cx == XXDEC)     /* _DECREMENT, DECREMENT */
  5737.       return(doincr(cx));
  5738.  
  5739.     if (cx == XXEVAL || cx == XX_EVAL) { /* _EVALUATE,  EVALUATE  */
  5740.     char *p;
  5741.     char vnambuf[VNAML], * vnp = NULL; /* These must be on the stack */
  5742.     if (!oldeval) {
  5743.         if ((y = cmfld("Variable name","",&s,
  5744.                ((cx == XX_EVAL) ? xxstring : NULL))) < 0) {
  5745.         if (y == -3) {
  5746.             printf("?Variable name required\n");
  5747.             return(-9);
  5748.         } else return(y);
  5749.         }
  5750.         ckstrncpy(vnambuf,s,VNAML);    /* Make a copy. */
  5751.         vnp = vnambuf;
  5752.         if (vnambuf[0] == CMDQ &&
  5753.         (vnambuf[1] == '%' || vnambuf[1] == '&'))
  5754.           vnp++;
  5755.         y = 0;
  5756.         if (*vnp == '%' || *vnp == '&') {
  5757.         if ((y = parsevar(vnp,&x,&z)) < 0)
  5758.           return(y);
  5759.         }
  5760.     }
  5761.     if ((x = cmtxt("Integer arithmetic expression","",&s,xxstring)) < 0)
  5762.       return(x);
  5763.     p = evala(s);
  5764.     if (!p) p = "";
  5765.     if (oldeval && *p)
  5766.       printf("%s\n", p);
  5767.     ckstrncpy(evalbuf,p,32);
  5768.     if (!oldeval)
  5769.       return(success = addmac(vnambuf,p));
  5770.     else
  5771.       return(success = *p ? 1 : 0);
  5772.     }
  5773. #endif /* NOSPL */
  5774.  
  5775. #ifndef NOSPL
  5776.     if (cx == XXDEF || cx == XXASS ||
  5777.     cx == XXDFX || cx == XXASX || cx == XXUNDEF) {
  5778. #ifdef IKSD
  5779.  
  5780.     if (inserver && !ENABLED(en_asg)) {
  5781.         printf("?Sorry, DEFINE/ASSIGN disabled\n");
  5782.         return(-9);
  5783.     }
  5784. #endif /* IKSD */
  5785.     if (atmbuf[0] == '.' && !atmbuf[1]) /* "." entered as keyword */
  5786.       xxdot = 1;            /* i.e. with space after it... */
  5787.     return(dodef(cx));        /* DEFINE, ASSIGN, etc... */
  5788.     }
  5789. #endif /* NOSPL */
  5790.  
  5791. #ifndef NOSPL
  5792.     if (cx == XXDCL) {            /* DECLARE an array */
  5793.     return(dodcl());
  5794.     }
  5795. #endif /* NOSPL */
  5796.  
  5797. #ifndef NODIAL
  5798.     if (cx == XXRED  || cx == XXDIAL || cx == XXPDIA ||
  5799.     cx == XXANSW || cx == XXLOOK) { /* DIAL, REDIAL etc */
  5800. #ifdef VMS
  5801.     extern int batch;
  5802. #else
  5803. #ifdef UNIXOROSK
  5804.     extern int backgrd;
  5805. #endif /* UNIXOROSK */
  5806. #endif /* VMS */
  5807.     x = dodial(cx);
  5808.     debug(F101,"dodial returns","",x);
  5809.     if ((cx == XXDIAL || cx == XXRED || cx == XXANSW) &&
  5810.         (x > 0) &&            /* If DIAL or REDIAL succeeded */
  5811.         (dialsta != DIA_PART) &&    /* and it wasn't partial */
  5812.         (dialcon > 0)) {
  5813.         if ((dialcon == 1 ||    /* And DIAL CONNECT is ON, */
  5814.         (dialcon == 2) &&    /* or DIAL CONNECT is AUTO */
  5815.          !cmdsrc()        /* and we're at top level... */
  5816. #ifdef VMS
  5817.          && !batch        /* Not if running from batch */
  5818. #else
  5819. #ifdef UNIXOROSK
  5820.          && !backgrd        /* Not if running in background */
  5821. #endif /* UNIXOROSK */
  5822. #endif /* VMS */
  5823.          )) /* Or AUTO */
  5824.           x = doconect(dialcq);    /* Then also CONNECT */
  5825. #ifdef CKLOGDIAL
  5826.         if (ttchk() < 0)
  5827.           dologend();
  5828. #endif /* CKLOGDIAL */
  5829.     }
  5830.     return(success = x);
  5831.     }
  5832. #endif /* NODIAL */
  5833.  
  5834. #ifndef NOPUSH
  5835. #ifdef CK_REXX
  5836.     if (cx == XXREXX) {            /* REXX */
  5837.         extern int nopush;
  5838.         if ( nopush )
  5839.           return(success=0);
  5840.         return(dorexx());
  5841.     }
  5842. #endif /* CK_REXX */
  5843. #endif /* NOPUSH */
  5844.  
  5845. #ifndef NOFRILLS
  5846.     if (cx == XXDEL) {            /* DELETE */
  5847. #ifdef IKSD
  5848.     if (inserver && (!ENABLED(en_del)
  5849. #ifdef CK_LOGIN
  5850.              || isguest
  5851. #endif /* CK_LOGIN */
  5852.              )) {
  5853.         printf("?Sorry, DELETE is disabled\n");
  5854.         return(-9);
  5855.     }
  5856. #endif /* IKSD */
  5857. #ifdef CK_APC
  5858.     if (apcactive == APC_LOCAL ||
  5859.         apcactive == APC_REMOTE && apcstatus != APC_UNCH) return(success = 0);
  5860. #endif /* CK_APC */
  5861.     return(dodel());
  5862.     }
  5863. #endif /* NOFRILLS */
  5864.  
  5865.     if (cx == XXDIR || cx == XXLS) {    /* DIRECTORY or LS */
  5866. #ifdef IKSD
  5867.     if (inserver && !ENABLED(en_dir)) {
  5868.         printf("?Sorry, DIRECTORY is disabled\n");
  5869.         return(-9);
  5870.     }
  5871. #endif /* IKSD */
  5872.     return(dodir(cx));
  5873.     }
  5874.  
  5875. #ifndef NOSPL
  5876.     if (cx == XXELS)            /* ELSE */
  5877.       return(doelse());
  5878. #endif /* NOSPL */
  5879.  
  5880. #ifndef NOSERVER
  5881. #ifndef NOFRILLS
  5882.     if (cx == XXENA || cx == XXDIS) {    /* ENABLE, DISABLE */
  5883.     s = (cx == XXENA) ?
  5884.       "Server function to enable" :
  5885.         "Server function to disable";
  5886.  
  5887.     if ((x = cmkey(enatab,nena,s,"",xxstring)) < 0) {
  5888.         if (x == -3) {
  5889.         printf("?Name of server function required\n");
  5890.         return(-9);
  5891.         } else return(x);
  5892.     }
  5893.     if ((y = cmkey(kmstab,3,"mode","both",xxstring)) < 0) {
  5894.         if (y == -3) {
  5895.         printf("?Please specify remote, local, or both\n");
  5896.         return(-9);
  5897.         } else return(y);
  5898.     }
  5899.     if (cx == XXDIS)        /* Disabling, not enabling */
  5900.       y = 3 - y;
  5901.     if ((z = cmcfm()) < 0) return(z);
  5902. #ifdef CK_APC
  5903.     if (apcactive == APC_LOCAL ||
  5904.         apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  5905.       return(success = 0);
  5906. #endif /* CK_APC */
  5907. #ifdef IKSD
  5908.         /* This may seem like it duplicates the work in doenable()  */
  5909.         /* but this code returns failure whereas doenable() returns */
  5910.         /* success.                                                 */
  5911.         if (inserver &&
  5912.             (x == EN_HOS || x == EN_PRI || x == EN_MAI || x == EN_WHO))
  5913.             return(success = 0);
  5914. #endif /* IKSD */
  5915.     return(doenable(y,x));
  5916.     }
  5917. #endif /* NOFRILLS */
  5918. #endif /* NOSERVER */
  5919.  
  5920. #ifndef NOSPL
  5921.     if (cx == XXRET) {            /* RETURN */
  5922.     if ((x = cmtxt("optional return value","",&s,NULL)) < 0)
  5923.       return(x);
  5924.     s = brstrip(s);            /* Strip braces */
  5925.     if (cmdlvl == 0) {        /* At top level, nothing happens... */
  5926.         return(success = 1);
  5927.     } else if (cmdstk[cmdlvl].src == CMD_TF) { /* In TAKE file, like POP */
  5928.         popclvl();            /* pop command level */
  5929.         return(success = 1);    /* always succeeds */
  5930.     } else if (cmdstk[cmdlvl].src == CMD_MD) { /* Within macro */
  5931.         return(doreturn(s));    /* Trailing text is return value. */
  5932.     } else return(-2);
  5933.     }
  5934. #endif /* NOSPL */
  5935.  
  5936. #ifndef NOSPL
  5937.     if (cx == XXDO || cx == XXMACRO) {    /* DO (a macro) */
  5938.     char mnamebuf[16];
  5939.     struct FDB kw, fl;
  5940.  
  5941.     if (cx == XXDO) {
  5942.         if (nmac == 0) {
  5943.         printf("\n?No macros defined\n");
  5944.         return(-9);
  5945.         }
  5946.         for (y = 0; y < nmac; y++) { /* copy the macro table into a */
  5947.         mackey[y].kwd = mactab[y].kwd; /* regular keyword table */
  5948.         mackey[y].kwval = y;    /* with value = pointer to macro tbl */
  5949.         mackey[y].flgs = mactab[y].flgs;
  5950.         }
  5951.         cmfdbi(&kw,            /* First FDB - command switches */
  5952.            _CMKEY,        /* fcode */
  5953.            "Macro",        /* hlpmsg */
  5954.            "",            /* default */
  5955.            "",            /* addtl string data */
  5956.            nmac,        /* addtl numeric data 1: tbl size */
  5957.            0,            /* addtl numeric data 2: 0 = cmkey */
  5958.            xxstring,        /* Processing function */
  5959.            mackey,        /* Keyword table */
  5960.            &fl            /* Pointer to next FDB */
  5961.            );
  5962.         cmfdbi(&fl,            /* 2nd FDB - for "{" */
  5963.            _CMFLD,        /* fcode */
  5964.            "",            /* hlpmsg */
  5965.            "",
  5966.            "",            /* addtl string data */
  5967.            0,            /* addtl numeric data 1 */
  5968.            0,            /* addtl numeric data 2 */
  5969.            xxstring,
  5970.            NULL,
  5971.            NULL
  5972.            );
  5973.         x = cmfdb(&kw);        /* Parse something */
  5974.         if (x < 0) {        /* Error */
  5975.         if (x == -3) {
  5976.             printf("?Macro name required\n");
  5977.             return(-9);
  5978.         } else
  5979.           return(x);
  5980.         }
  5981.         if (cmresult.fcode == _CMKEY) {
  5982.         if ((y = cmtxt("optional arguments","",&s,xxstring)) < 0)
  5983.           return(y);        /* get args */
  5984.         return(dodo(x,s,cmdstk[cmdlvl].ccflgs) < 1 ?
  5985.                (success = 0) : 1);
  5986.         }
  5987.         ckstrncpy(line,cmresult.sresult,LINBUFSIZ);    /* _CMFLD */
  5988.         if (atmbuf[0] == '{') {
  5989.         if ((y = cmcfm()) < 0)
  5990.           return(y);
  5991.         }
  5992.     } else {            /* XXMACRO */
  5993.         int k = 0;
  5994.         line[k++] = '{';
  5995.         line[k++] = SP;
  5996.         if ((y = cmtxt("braced list of commands","",&s,xxstring)) < 0)
  5997.           return(y);
  5998.         ckstrncpy(line+k,s,LINBUFSIZ);
  5999.     }
  6000.     x = strlen(line);
  6001.     if (line[0] != '{' && line[x-1] != '}') {
  6002.             if (x > 0)
  6003.           printf("?Not a command or macro name: \"%s\"\n",line);
  6004.             else
  6005.           printf("?Not a command or macro name.\n");
  6006.         return(-9);
  6007.     }
  6008.     s = brstrip(line);
  6009.     sprintf(mnamebuf," ..tmp:%03d",cmdlvl);
  6010.     x = addmac(mnamebuf,s);
  6011.     return(dodo(x,NULL,cmdstk[cmdlvl].ccflgs) < 1 ?
  6012.            (success = 0) : 1);
  6013.     }
  6014. #endif /* NOSPL */
  6015.  
  6016.     if (cx == XXECH || cx == XXXECH
  6017. #ifndef NOSPL
  6018.     || cx == XXAPC
  6019. #endif /* NOSPL */
  6020.     ) {                /* ECHO or APC */
  6021.     if ((x = cmtxt((cx == XXECH || cx == XXXECH) ?
  6022.                "Text to be echoed" :
  6023.                "Application Program Command text",
  6024.                "",&s,xxstring)) < 0)
  6025.       return(x);
  6026.     s = brstrip(s);            /* Strip braces */
  6027.     if (cx == XXECH) {        /* ECHO */
  6028. #ifndef NOSPL
  6029.         if (!fndiags || fnsuccess)
  6030. #endif /* NOSPL */
  6031.           printf("%s\n",s);
  6032.  
  6033.     } else if (cx == XXXECH) {    /* XECHO */
  6034.         printf("%s",s);
  6035. #ifdef UNIX
  6036.         fflush(stdout);
  6037. #endif /* UNIX */
  6038.     } else {            /* APC */
  6039. #ifdef CK_APC
  6040.         if (apcactive == APC_LOCAL ||
  6041.             apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  6042.           return(success = 0);
  6043. #endif /* CK_APC */
  6044.         if (!local) {
  6045.         printf("%c_%s%c\\",ESC,s,ESC);
  6046. #ifdef UNIX
  6047.         fflush(stdout);
  6048. #endif /* UNIX */
  6049.  
  6050.         } else {
  6051. #ifndef NOSPL
  6052.         sprintf(tmpbuf,"%c_%s%c\\",ESC,s,ESC);
  6053.         return(success = dooutput(tmpbuf, XXOUT));
  6054. #else
  6055.         printf("%c_%s%c\\",ESC,s,ESC);
  6056. #endif /* NOSPL */
  6057.         }
  6058.     }
  6059.     return(success = 1);        /* Always succeeds */
  6060.     }
  6061.  
  6062. #ifndef NOSPL
  6063.     if (cx == XXOPE)            /* OPEN */
  6064.       return(doopen());
  6065. #endif /* NOSPL */
  6066.  
  6067. #ifndef NOSPL
  6068.     if (cx == XXOUT || cx == XXLNOUT) {    /* OUTPUT or LINEOUT */
  6069.     if ((x = cmtxt("Text to be output","",&s,NULL)) < 0)
  6070.       return(x);
  6071. #ifdef CK_APC
  6072.     if (apcactive == APC_LOCAL ||
  6073.         apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  6074.       return(success = 0);
  6075. #endif /* CK_APC */
  6076.     debug(F110,"OUTPUT 1",s,0);
  6077.     s = brstrip(s);            /* Strip enclosing braces, */
  6078.     debug(F110,"OUTPUT 2",s,0);
  6079. /*
  6080.   I don't think I could ever fully explain this in a million years...
  6081.   We have read the user's string without calling the variable-expander
  6082.   function.  Now, before we call it, we have to double backslashes that
  6083.   appear before \N, \B, \L, and \ itself, so the expander function will
  6084.   reduce them back to single backslashes, so when we call dooutput()...
  6085.   But it's more complicated than that.
  6086. */
  6087.     if (cmdgquo()) {        /* Only if COMMAND QUOTING ON ... */
  6088.         for (x = 0, y = 0; s[x]; x++, y++) {
  6089.         if (s[x] == CMDQ) {
  6090.             char c = s[x+1];
  6091.             if (c == 'n' || c == 'N' ||
  6092.             c == 'b' || c == 'B' ||
  6093.             c == 'l' || c == 'L' ||
  6094.             c == CMDQ)
  6095.               line[y++] = CMDQ;
  6096.         }
  6097.         line[y] = s[x];
  6098.         }
  6099.         line[y++] = '\0';        /* Now expand variables, etc. */
  6100.         debug(F110,"OUTPUT 3",line,0);
  6101.         s = line+y+1;
  6102.         x = LINBUFSIZ - (int) strlen(line) - 1;
  6103.         debug(F101,"OUTPUT size","",x);
  6104.         if (zzstring(line,&s,&x) < 0)
  6105.           return(success = 0);
  6106.         s = line+y+1;
  6107.         debug(F110,"OUTPUT 4",s,0);
  6108.     }
  6109.     success = dooutput(s,cx);
  6110.     return(success);
  6111.     }
  6112. #endif /* NOSPL */
  6113.  
  6114. #ifdef ANYX25
  6115. #ifndef IBMX25
  6116.     if (cx == XXPAD) {            /* PAD commands */
  6117.     x = cmkey(padtab,npadc,"PAD command","",xxstring);
  6118.     if (x == -3) {
  6119.         printf("?You must specify a PAD command to execute\n");
  6120.         return(-9);
  6121.     }
  6122.     if (x < 0) return(x);
  6123.  
  6124.     switch (x) {
  6125.       case XYPADL:
  6126.         if (x25stat() < 0)
  6127.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  6128.         else {
  6129.         x25clear();
  6130.         initpad();
  6131.         }
  6132.         break;
  6133.       case XYPADS:
  6134.         if (x25stat() < 0)
  6135.           printf("Not connected\r\n");
  6136.         else {
  6137.         extern int linkid, lcn;
  6138.         conol("Connected thru ");
  6139.         conol(ttname);
  6140.         printf(", Link id %d, Logical channel number %d\r\n",
  6141.                linkid,lcn);
  6142.         }
  6143.         break;
  6144.       case XYPADR:
  6145.         if (x25stat() < 0)
  6146.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  6147.         else
  6148.           x25reset(0,0);
  6149.         break;
  6150.       case XYPADI:
  6151.         if (x25stat() < 0)
  6152.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  6153.         else
  6154.           x25intr(0);
  6155.     }
  6156.     return(0);
  6157.     }
  6158. #endif /* IBMX25 */
  6159. #endif /* ANYX25 */
  6160.  
  6161. #ifndef NOSPL
  6162.     if (cx == XXPAU || cx == XXWAI || cx == XXMSL) /* PAUSE, WAIT, etc */
  6163.       return(dopaus(cx));
  6164. #endif /* NOSPL */
  6165.  
  6166. #ifndef NOFRILLS
  6167.     if (cx == XXPRI) {
  6168. #ifdef IKSD
  6169. #ifdef CK_LOGIN
  6170.     if (inserver && (isguest || !ENABLED(en_pri))) {
  6171.         printf("?Sorry, printing is disabled\n");
  6172.         return(-9);
  6173.     }
  6174. #endif /* CK_LOGIN */
  6175. #endif /* IKSD */
  6176.     if ((x = cmifi("File to print","",&s,&y,xxstring)) < 0) {
  6177.         if (x == -3) {
  6178.         printf("?A file specification is required\n");
  6179.         return(-9);
  6180.         } else return(x);
  6181.     }
  6182.     if (y != 0) {
  6183.         printf("?Wildcards not allowed\n");
  6184.         return(-9);
  6185.     }
  6186.     ckstrncpy(line,s,LINBUFSIZ);
  6187.     s = "";
  6188. #ifndef NT
  6189.     if ((x = cmtxt("Local print command options, or carriage return","",&s,
  6190.                xxstring)) < 0)
  6191.       return(x);
  6192. #endif /* NT */
  6193.     if ((x = cmcfm()) < 0)
  6194.       return(x);
  6195.     return(success = (zprint(s,line) == 0) ? 1 : 0);
  6196.     }
  6197. #endif /* NOFRILLS */
  6198.  
  6199. #ifndef NOPUSH
  6200. #ifdef TCPSOCKET
  6201.     if (cx == XXPNG)             /* PING an IP host */
  6202.       return(doping());
  6203.  
  6204.     if (cx == XXFTP)            /* FTP an IP host */
  6205.       return(doftp());
  6206. #endif /* TCPSOCKET */
  6207. #endif /* NOPUSH */
  6208.  
  6209.     if (cx == XXPWD) {            /* PWD */
  6210.     char *pwp;
  6211.     if ((x = cmcfm()) < 0)
  6212.       return(x);
  6213. #ifndef MAC
  6214. #ifndef OS2
  6215. #ifdef UNIX
  6216.     printf("%s\n",zgtdir());
  6217. #else
  6218.     xsystem(PWDCMD);
  6219. #endif /* UNIX */
  6220.     return(success = 1);        /* Blind faith */
  6221. #else  /* OS2 */
  6222.     if (pwp = zgtdir()) {
  6223.         printf("%s\n",pwp);
  6224.         return(success = ((int)strlen(pwp) > 0));
  6225.     } else return(success = 0);
  6226. #endif /* OS2 */
  6227. #else  /* MAC */
  6228.     if (pwp = zgtdir()) {
  6229.         printf("%s\n",pwp);
  6230.         return(success = ((int)strlen(pwp) > 0));
  6231.     } else return(success = 0);
  6232. #endif /* MAC */
  6233.     }
  6234.  
  6235.     if (cx == XXQUI || cx == XXEXI) {    /* EXIT, QUIT */
  6236.     if ((y = cmnum("exit status code","",10,&x,xxstring)) < 0) {
  6237.         if (y == -3)
  6238.           x = xitsta;
  6239.         else return(y);
  6240.     }
  6241.     if ((y = cmtxt("Optional EXIT message","",&s,xxstring)) < 0)
  6242.       return(y);
  6243.     s = brstrip(s);
  6244.     ckstrncpy(line,s,LINBUFSIZ);
  6245.     if ((y = cmcfm()) < 0) return(y);
  6246.  
  6247.     if (!hupok(0))            /* Check if connection still open */
  6248.       return(success = 0);
  6249.  
  6250.     if (line[0])            /* Print EXIT message if given */
  6251.       printf("%s\n",(char *)line);
  6252.  
  6253. #ifdef VMS
  6254.     doexit(GOOD_EXIT,x);
  6255. #else
  6256. #ifdef OSK
  6257. /* Returning any codes here makes the OS-9 shell print an error message. */
  6258.     doexit(GOOD_EXIT,-1);
  6259. #else
  6260. #ifdef datageneral
  6261.         doexit(GOOD_EXIT,x);
  6262. #else
  6263.     doexit(x,-1);
  6264. #endif /* datageneral */
  6265. #endif /* OSK */
  6266. #endif /* VMS */
  6267.     }
  6268.  
  6269. #ifndef NOXFER
  6270. #ifndef NOFRILLS
  6271.     if (cx == XXERR) {            /* ERROR */
  6272. #ifdef CK_XYZ
  6273.     if (protocol != PROTO_K) {
  6274.         printf("Sorry, E-PACKET only works with Kermit protocol\n");
  6275.         return(-9);
  6276.     }
  6277. #endif /* CK_XYZ */
  6278.     if ((x = cmcfm()) < 0) return(x);
  6279.     ttflui();
  6280.     epktflg = 1;
  6281.     sstate = 'a';
  6282.     return(0);
  6283.     }
  6284. #endif /* NOFRILLS */
  6285.  
  6286.     if (cx == XXFIN) {            /* FINISH */
  6287. #ifdef CK_XYZ
  6288.     if (protocol != PROTO_K) {
  6289.         printf("Sorry, FINISH only works with Kermit protocol\n");
  6290.         return(-9);
  6291.     }
  6292. #endif /* CK_XYZ */
  6293.     if ((x = cmcfm()) < 0) return(x);
  6294.  
  6295. #ifdef IKS_OPTION
  6296.         if (!iks_wait(KERMIT_REQ_START,1)) {
  6297.         printf(
  6298.               "?A Kermit Server is unavailable to process this command\n");
  6299.         return(-9);            /* Correct the return code */
  6300.         }
  6301. #endif /* IKS_OPTION */
  6302.  
  6303.     sstate = setgen('F',"","","");
  6304.     if (local) ttflui();        /* If local, flush tty input buffer */
  6305.     return(0);
  6306.     }
  6307. #endif /* NOXFER */
  6308.  
  6309. #ifndef NOSPL
  6310.     if (cx == XXFOR)            /* FOR loop */
  6311.       return(dofor());
  6312. #endif /* NOSPL */
  6313.  
  6314. #ifndef NOXFER
  6315.     /* GET MGET REGET RETRIEVE etc */
  6316.     if (cx == XXGET || cx == XXMGET || cx == XXREGET || cx == XXRETR) {
  6317. #ifdef IKSD
  6318.     if (inserver && !ENABLED(en_sen)) {
  6319.         printf("?Sorry, reception of files is disabled\n");
  6320.         return(-9);
  6321.     }
  6322. #endif /* IKSD */
  6323.     return(doxget(cx));
  6324.     }
  6325. #endif /* NOXFER */
  6326.  
  6327. #ifndef NOSPL
  6328. #ifndef NOFRILLS
  6329.     if (cx == XXGOK) {            /* GETOK */
  6330.     return(success = doask(cx));
  6331.     }
  6332. #endif /* NOFRILLS */
  6333. #endif /* NOSPL */
  6334.  
  6335.     if (cx == XXHLP) {            /* HELP */
  6336. #ifdef NOHELP
  6337.     return(dohlp(XXHLP));
  6338. #else
  6339.     x = cmkey2(cmdtab,ncmd,"C-Kermit command","help",toktab,xxstring,3);
  6340.     debug(F101,"HELP command x","",x);
  6341.     if (x == -5) {
  6342.         y = chktok(toktab);
  6343.         debug(F101,"top-level cmkey token","",y);
  6344.         ungword();
  6345.         switch (y) {
  6346. #ifndef NOPUSH
  6347.           case '!': x = XXSHE; break;
  6348. #endif /* NOPUSH */
  6349.           case '#': x = XXCOM; break;
  6350.           case ';': x = XXCOM; break;
  6351. #ifndef NOSPL
  6352.               case '.': x = XXDEF; break;
  6353.           case ':': x = XXLBL; break;
  6354. #endif /* NOSPL */
  6355.           case '&': x = XXECH; break;
  6356.           default:
  6357.         printf("\n?Invalid - %s\n",cmdbuf);
  6358.         x = -2;
  6359.         }
  6360.     }
  6361.     return(dohlp(x));
  6362. #endif /* NOHELP */
  6363.     }
  6364.  
  6365. #ifndef NOHELP
  6366.     if (cx == XXINT)            /* INTRO */
  6367.       return(hmsga(introtxt));
  6368.     if (cx == XXNEW) {            /* NEWS */
  6369.     int x;
  6370.     extern char * k_info_dir;
  6371.     x = hmsga(newstxt);
  6372.     if (k_info_dir) {
  6373.         printf("The ckermit2.txt file can be found in %s.\n",
  6374.            k_info_dir
  6375.            );
  6376.     }
  6377. #ifdef UNIX
  6378.     printf(
  6379. "Type \"man kermit\" at the shell prompt to view the Kermit man page.\n\n"
  6380.            );
  6381. #else
  6382. #ifdef VMS
  6383.     printf(
  6384. "Type \"help kermit\" at the DCL prompt to view the Kermit help topic.\n\n"
  6385.            );
  6386. #endif /* VMS */
  6387. #endif /* UNIX */
  6388.     return(x);
  6389.     }
  6390.  
  6391. #ifdef OS2ONLY
  6392.     if (cx == XXUPD) {            /* View UPDATE file */
  6393.         extern char exedir[];
  6394.         char * pTopic;
  6395.         char updstr[2048];
  6396.         if ((x = cmtxt("topic name","",&pTopic,xxstring)) < 0)
  6397.             return x;
  6398.     sprintf(updstr,
  6399.         "start view %s\\docs\\k2.inf+%s\\docs\\using_ck.inf+\
  6400. %s\\docs\\dialing.inf+%s\\docs\\modems.inf %s",
  6401.         exedir,exedir,exedir,exedir,pTopic
  6402.         );
  6403.         system(updstr);
  6404.         return(success = 1);
  6405.     }
  6406. #endif /* OS2ONLY */
  6407. #endif /* NOHELP */
  6408.  
  6409. #ifndef NOLOCAL
  6410.     if (cx == XXHAN) {            /* HANGUP */
  6411.     if ((x = cmcfm()) < 0) return(x);
  6412. #ifndef NODIAL
  6413.     if ((x = mdmhup()) < 1)
  6414. #endif /* NODIAL */
  6415.       x = (tthang() > -1);
  6416. #ifndef NODIAL
  6417.     dialsta = DIA_UNK;
  6418. #endif /* NODIAL */
  6419.     whyclosed = WC_CLOS;
  6420.     ttchk();            /* In case of CLOSE-ON-DISCONNECT */
  6421. #ifdef CKLOGDIAL
  6422.     dologend();
  6423. #endif /* CKLOGDIAL */
  6424. #ifdef OS2
  6425.     if (x)
  6426.       DialerSend(OPT_KERMIT_HANGUP, 0);
  6427. #endif /* OS2 */
  6428.     if (x) haveline = 0;
  6429.     return(success = x);
  6430.     }
  6431. #endif /* NOLOCAL */
  6432.  
  6433. #ifndef NOSPL
  6434.     if (cx == XXGOTO || cx == XXFWD || cx == XXXFWD) { /* GOTO or FORWARD */
  6435. /* Note, here we don't set SUCCESS/FAILURE flag */
  6436.     if ((y = cmfld("label","",&s,xxstring)) < 0) {
  6437.         if (y == -3) {
  6438.         printf("?Label name required\n");
  6439.         return(-9);
  6440.         } else return(y);
  6441.     }
  6442.     ckstrncpy(lblbuf,s,LBLSIZ);
  6443.     if ((x = cmcfm()) < 0) return(x);
  6444.     s = lblbuf;
  6445.     return(dogoto(s,cx));
  6446.     }
  6447. #endif /* NOSPL */
  6448.  
  6449. #ifndef NOSPL
  6450. /* IF, Extended IF, WHILE */
  6451.     if (cx == XXIF || cx == XXIFX || cx == XXWHI || cx == XXASSER) {
  6452.     return(doif(cx));
  6453.     }
  6454.     if (cx == XXSWIT) {
  6455.     return(doswitch());
  6456.     }
  6457. #endif /* NOSPL */
  6458.  
  6459. #ifndef NOSPL
  6460.     /* INPUT, REINPUT, and MINPUT */
  6461.  
  6462.     if (cx == XXINP || cx == XXREI
  6463. #ifdef CK_MINPUT
  6464.     || cx == XXMINP
  6465. #endif /* CK_MINPUT */
  6466.     ) {
  6467.     long zz;
  6468.     extern int x_ifnum, ispattern;
  6469.     zz = -1L;
  6470.     x_ifnum = 1;            /* Turn off internal complaints */
  6471.     y = cmnum("Seconds to wait for input,\n or time of day hh:mm:ss",
  6472.           ckitoa(indef), 10, &x, xxstring
  6473.           );
  6474.     x_ifnum = 0;
  6475.     if (y < 0) {
  6476.         if (y == -2) {        /* Invalid number or expression */
  6477.         zz = tod2sec(atmbuf);    /* Convert to secs since midnight */
  6478.         if (zz < 0L) {
  6479.             printf("?Number, expression, or time of day required\n");
  6480.             return(-9);
  6481.         } else {
  6482.             char now[32];    /* Current time */
  6483.             char *p;
  6484.             long tnow;
  6485.             p = now;
  6486.             ztime(&p);
  6487.             tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
  6488.             if (zz < tnow)    /* User's time before now */
  6489.               zz += 86400L;    /* So make it tomorrow */
  6490.             zz -= tnow;        /* Seconds from now. */
  6491.         }
  6492.         } else
  6493.           return(y);
  6494.     }
  6495.     if (zz > -1L) {
  6496.         x = zz;
  6497.         if (zz != (long) x) {
  6498.         printf(
  6499. "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
  6500.                );
  6501.         return(-9);
  6502.         }
  6503.     }
  6504. #ifdef CK_MINPUT
  6505.     for (y = 0; y < MINPMAX; y++) {    /* Initialize strings */
  6506.         mp[y] = 0;            /* Assume it's not a pattern */
  6507.         if (ms[y]) {
  6508.         free(ms[y]);        /* Free old strings, if any */
  6509.         ms[y] = NULL;
  6510.         }
  6511.     }
  6512.     if (cx == XXMINP) {        /* MINPUT */
  6513.         int rc = 0, cfm = 1;
  6514.         for (y = 0; y < MINPMAX; y++) { /* Parse up to MINPMAX strings */
  6515.                 rc = cmfld("List of input strings","",&s,xxstring);
  6516.         debug(F111,"MINPUT cmfld returns",s,rc);
  6517.                 if (rc < 0) return(rc);
  6518.                 if (*s == '{') {
  6519.             char *ss;
  6520.             int n;
  6521.             ss = s; n = 0;
  6522.             while (*ss) {*ss = *(ss+1); ss++; n++; }
  6523.             while (--n > 0) if (s[n] == '}') break;
  6524.             if (n > 0) {
  6525.             ss = s + n;
  6526.             while (*ss) {*ss = *(ss+1); ss++; n++; }
  6527.             }
  6528.                 }
  6529.         if (!(ms[y] = malloc((int)strlen(s) + 1))) { /* Get memory */
  6530.             printf("?Memory allocation failure\n");
  6531.             return(-9);
  6532.         }
  6533.         strcpy(ms[y],s);    /* Got memory, copy. */
  6534.         mp[y] = ispattern ? 1 : 0; /* Mark whether it's a pattern */
  6535.                 if (rc == 1) {        /* List terminated by CR */
  6536.             cfm = cmcfm();    /* Always call cmcfm() */
  6537.             debug(F101,"MINPUT cmcfm","",cfm);
  6538.             break;
  6539.         }
  6540.             }
  6541.         for (y++; y < MINPMAX; y++) { /* Clean up old strings */
  6542.         if (ms[y]) {
  6543.             free(ms[y]);    /* Free old strings, if any */
  6544.             ms[y] = NULL;
  6545.         }
  6546.             }
  6547.         debug(F101,"MINPUT end parse x","",x);
  6548.         if (cfm < 0)
  6549.           return(cfm);
  6550. #ifdef DEBUG
  6551.         if (deblog) {        /* Check the parsing */
  6552.         for (y = 0; y < MINPMAX; y++)
  6553.           if (ms[y]) debug(F111,"MINPUT",ms[y],mp[y]);
  6554.         }
  6555. #endif /* DEBUG */
  6556.  
  6557.     } else
  6558. #endif /* CK_MINPUT */
  6559.     {
  6560.         if ((y = cmtxt("Material to be input","",&s,xxstring)) < 0)
  6561.           return(y);
  6562.         mp[0] = ispattern ? 1 : 0;
  6563.         s = brstrip(s);
  6564.         if (!(ms[0] = malloc((int)strlen(s) + 1))) { /* Get memory */
  6565.         printf("?Memory allocation failure\n");
  6566.         return(-9);
  6567.         }
  6568.         strcpy(ms[0],s);        /* Got memory, copy. */
  6569.         ms[1] = NULL;
  6570.     }
  6571.     if (cx == XXINP            /* INPUT */
  6572. #ifdef CK_MINPUT
  6573.         || cx == XXMINP        /* or MINPUT */
  6574. #endif /* CK_MINPUT */
  6575.         ) {
  6576.         i_active = 1;
  6577.         success = doinput(x,ms,mp);    /* Go try to input the search string */
  6578.         i_active = 0;
  6579.     } else {            /* REINPUT */
  6580.         debug(F110,"xxrei line",s,0);
  6581.         success = doreinp(x,s,ispattern);
  6582.     }
  6583.     if (intime[cmdlvl] && !success) { /* TIMEOUT-ACTION = QUIT? */
  6584.         popclvl();            /* If so, pop command level. */
  6585.         if (pflag && cmdlvl == 0) {
  6586.         if (cx == XXINP)  printf("?INPUT timed out\n");
  6587.         if (cx == XXMINP) printf("?MINPUT timed out\n");
  6588.         if (cx == XXREI)  printf("?REINPUT failed\n");
  6589.         }
  6590.     }
  6591.     return(success);        /* Return do(re)input's return code */
  6592.     }
  6593.  
  6594. #endif /* NOSPL */
  6595.  
  6596. #ifndef NOSPL
  6597.     if (cx == XXLBL) {            /* LABEL */
  6598.     if ((x = cmfld("label","",&s,xxstring)) < 0) {
  6599.         if (x == -3) {
  6600.         printf("?Label name required\n");
  6601.         return(-9);
  6602.         } else return(x);
  6603.     }
  6604.     if ((x = cmcfm()) < 0) return(x);
  6605.     return(0);
  6606.     }
  6607. #endif /* NOSPL */
  6608.  
  6609.     if (cx == XXLOG) {            /* LOG */
  6610.     x = cmkey(logtab,nlog,"What to log","",xxstring);
  6611.     if (x == -3) {
  6612.         printf("?Type of log required\n");
  6613.         return(-9);
  6614.     }
  6615.     if (x < 0) return(x);
  6616.     x = dolog(x);
  6617.     if (x < 0)
  6618.       return(x);
  6619.     else
  6620.       return(success = x);
  6621.     }
  6622.  
  6623.     if (cx == XXLOGIN) {        /* (REMOTE) LOGIN */
  6624. #ifdef IKSD
  6625.     if (inserver) {
  6626.         printf("?Already logged in\n");
  6627.         return(-9);
  6628.     } else
  6629. #endif /* IKSD */
  6630.     {
  6631. #ifdef NOXFER
  6632.         return(-2);
  6633. #else
  6634.         return(dormt(XZLGI));
  6635. #endif /* NOXFER */
  6636.     }
  6637.     }
  6638.     if (cx == XXLOGOUT) {        /* (REMOTE) LOGOUT */
  6639. #ifdef IKSD
  6640.         if (inserver) {
  6641.         if ((x = cmcfm()) < 0)
  6642.           return(x);
  6643.         doexit(GOOD_EXIT,xitsta);
  6644.     } else
  6645. #endif /* IKSD */
  6646.     if (!local || (network && ttchk() < 0)) {
  6647.         printf("?No connection.\n");
  6648.         return(-9);
  6649.     } else {
  6650. #ifdef NOXFER
  6651.         return(-2);
  6652. #else
  6653.         return(dormt(XZLGO));
  6654. #endif /* NOXFER */
  6655.     }
  6656.     }
  6657.  
  6658. #ifndef NOSCRIPT
  6659.     if (cx == XXLOGI) {            /* UUCP-style script */
  6660.     if ((x = cmtxt("expect-send expect-send ...","",&s,xxstring)) < 0)
  6661.       return(x);
  6662. #ifdef CK_APC
  6663.     if (apcactive == APC_LOCAL ||
  6664.         apcactive == APC_REMOTE && apcstatus != APC_UNCH) return(success = 0);
  6665. #endif /* CK_APC */
  6666. #ifdef VMS
  6667.     conres();            /* For Ctrl-C to work... */
  6668. #endif /* VMS */
  6669.     return(success = dologin(s));    /* Return 1=completed, 0=failed */
  6670.     }
  6671. #endif /* NOSCRIPT */
  6672.  
  6673. #ifndef NOXFER
  6674. #ifdef PIPESEND
  6675.     if (cx == XXCREC) {            /* CRECEIVE */
  6676.     if (protocol != PROTO_K) {
  6677.         printf("?Sorry, CRECEIVE works only with Kermit protocol\n");
  6678.         return(-9);
  6679.     }
  6680.     }
  6681.     if (cx == XXCGET) {            /* CGET */
  6682.     return(doxget(cx));
  6683.     }
  6684. #endif /* PIPESEND */
  6685.  
  6686.     if (cx == XXREC)            /* RECEIVE */
  6687.       return(doxget(cx));
  6688. #endif /* NOXFER */
  6689.  
  6690. #ifndef NOXFER
  6691.     if (cx == XXREM) {            /* REMOTE */
  6692. #ifdef CK_XYZ
  6693.     if (protocol != PROTO_K) {
  6694.         printf("Sorry, REMOTE commands only work with Kermit protocol\n");
  6695.         return(-9);
  6696.     }
  6697. #endif /* CK_XYZ */
  6698.     x = cmkey(remcmd,nrmt,"Remote Kermit server command","",xxstring);
  6699.     if (x == -3) {
  6700.         printf("?You must specify a command for the remote server\n");
  6701.         return(-9);
  6702.     }
  6703.     return(dormt(x));
  6704.     }
  6705. #endif /* NOXFER */
  6706.  
  6707. #ifndef NORENAME
  6708. #ifndef NOFRILLS
  6709.     if (cx == XXREN) {            /* RENAME */
  6710. #ifdef IKSD
  6711.     if (inserver && (!ENABLED(en_ren)
  6712. #ifdef CK_LOGIN
  6713.              || isguest
  6714. #endif /* CK_LOGIN */
  6715.              )) {
  6716.         printf("?Sorry, renaming of files is disabled\n");
  6717.         return(-9);
  6718.     }
  6719. #endif /* IKSD */
  6720. #ifdef CK_APC
  6721.     if (apcactive == APC_LOCAL ||
  6722.         apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  6723.       return(success = 0);
  6724. #endif /* CK_APC */
  6725.     return(dorenam());
  6726.     }
  6727. #endif /* NOFRILLS */
  6728. #endif /* NORENAME */
  6729.  
  6730.     if (cx == XXEIGHT) {        /* EIGHTBIT */
  6731.     extern int parity, cmask, cmdmsk;
  6732.     if ((x = cmcfm()) < 0)
  6733.       return(x);
  6734.     parity = 0;
  6735.     cmask = 0xff;
  6736.     cmdmsk = 0xff;
  6737.     return(success = 1);
  6738.     }
  6739.  
  6740. #ifndef NOXFER
  6741. /* SEND, CSEND, MOVE, MAIL, and RESEND use the new common code */
  6742.  
  6743.     if (cx == XXSEN            /* SEND */
  6744. #ifdef PIPESEND
  6745.     || cx == XXCSEN            /* CSEND */
  6746. #endif /* PIPESEND */
  6747.     || cx == XXMOVE            /* MOVE */
  6748.     || cx == XXMAI            /* MAIL */
  6749. #ifdef CK_RESEND
  6750.     || cx == XXRSEN            /* RESEND */
  6751. #endif /* CK_RESEND */
  6752.     ) {
  6753. #ifdef IKSD
  6754.     if (inserver && !ENABLED(en_get)) {
  6755.         printf("?Sorry, sending files is disabled\n");
  6756.         return(-9);
  6757.     }
  6758. #endif /* IKSD */
  6759.     return(doxsend(cx));
  6760.     }
  6761.  
  6762. /* PSEND, ADD, and REMOVE use special parsing */
  6763.  
  6764. #ifdef ADDCMD
  6765.     /* ADD and REMOVE */
  6766.     if (cx == XXADD || cx == XXREMV) {
  6767.     char * m;
  6768.     m = (cx == XXADD) ? "Add to which list?" : "Remove from which list?";
  6769.     x = cmkey(addtab,naddtab,m,"",xxstring);
  6770.     if (x < 0)
  6771.       return(x);
  6772. #ifndef NOMSEND
  6773.     if (x == ADD_SND)
  6774.       return(addsend(cx));
  6775.     else
  6776. #endif /* NOMSEND */
  6777.       return(doadd(cx,x));
  6778.     }
  6779. #endif /* ADDCMD */
  6780.  
  6781. #ifdef CK_RESEND
  6782.     if (cx == XXPSEN) {            /* PSEND */
  6783.     int seekto = 0;
  6784.  
  6785.     cmarg = cmarg2 = "";
  6786.     x = cmifi("File to partially send", "", &s, &y, xxstring);
  6787.     if (x < 0) {
  6788.         if (x == -3) {
  6789.         printf("?A file specification is required\n");
  6790.         return(-9);
  6791.         } else return(x);
  6792.     }
  6793.     nfils = -1;            /* Files come from internal list. */
  6794. #ifndef NOMSEND
  6795.         addlist = 0;            /* Don't use SEND-LIST. */
  6796.         filenext = NULL;
  6797. #endif /* NOMSEND */
  6798.     ckstrncpy(line,s,LINBUFSIZ);    /* Save copy of string just parsed. */
  6799.     debug(F110,"PSEND line",line,0);
  6800.     if (y != 0) {
  6801.         printf("?Sorry, wildcards not permitted in this command\n");
  6802.         return(-9);
  6803.     }
  6804.     if (sizeof(int) < 4) {
  6805.         printf("?Sorry, this command needs 32-bit integers\n");
  6806.         return(-9);
  6807.     }
  6808.     x = cmnum("starting position (byte number)",
  6809.           "",10,&seekto,xxstring);
  6810.     if (x < 0)
  6811.       return(x);
  6812.     zfnqfp(s,fspeclen,fspec);    /* Get full path */
  6813.     if ((x = cmtxt("Name to send it with","",&s,NULL)) < 0)
  6814.       return(x);
  6815.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  6816.  
  6817. #ifdef IKSD
  6818.     if (inserver && !ENABLED(en_get)) {
  6819.         printf("?Sorry, sending files is disabled\n");
  6820.         return(-9);
  6821.     }
  6822. #endif /* IKSD */
  6823. #ifdef PIPESEND
  6824.     if (sndfilter) {
  6825.         printf("?Sorry, no PSEND while SEND FILTER selected\n");
  6826.         return(-9);
  6827.     }
  6828. #endif /* PIPESEND */
  6829. #ifdef CK_XYZ
  6830.     if ((protocol == PROTO_X || protocol == PROTO_XC)) {
  6831.         printf("Sorry, PSEND works only with Kermit protocol\n");
  6832.         return(-9);
  6833.     }
  6834. #endif /* CK_XYZ */
  6835.  
  6836.     cmarg2 = brstrip(tmpbuf);    /* Strip braces */
  6837.     cmarg = line;            /* File to send */
  6838.     debug(F110,"PSEND filename",cmarg,0);
  6839.     debug(F110,"PSEND as-name",cmarg2,0);
  6840.     sendstart = seekto;
  6841.     sstate = 's';            /* Set start state to SEND */
  6842. #ifndef NOMSEND
  6843.     addlist = 0;
  6844.     filenext = NULL;
  6845. #endif /* NOMSEND */
  6846.     sendmode = SM_PSEND;
  6847. #ifdef MAC
  6848.     what = W_SEND;
  6849.     scrcreate();
  6850. #endif /* MAC */
  6851.     if (local) {            /* If in local mode, */
  6852.         displa = 1;            /* enable file transfer display */
  6853.     }
  6854.     return(0);
  6855.     }
  6856. #endif /* CK_RESEND */
  6857. #endif /* NOXFER */
  6858.  
  6859. #ifndef NOXFER
  6860. #ifndef NOMSEND
  6861.     if (cx == XXMSE || cx == XXMMOVE) {
  6862. #ifdef CK_XYZ
  6863.     if (protocol == PROTO_X || protocol == PROTO_XC) {
  6864.         printf(
  6865. "Sorry, you can only send one file at a time with XMODEM protocol\n"
  6866.            );
  6867.         return(-9);
  6868.     }
  6869. #endif /* CK_XYZ */
  6870.         return(doxsend(cx));
  6871.     }
  6872.  
  6873. #ifdef COMMENT                /* (moved to doxsend) */
  6874.     if (cx == XXMSE || cx == XXMMOVE) {    /* MSEND and MMOVE commands */
  6875.     nfils = 0;            /* Like getting a list of */
  6876.     lp = line;            /* files on the command line */
  6877.     addlist = 0;            /* Do not use SEND-LIST */
  6878.     filenext = NULL;        /* Ditto ! */
  6879.  
  6880.     while (1) {
  6881.         char *p;
  6882.         if ((x = cmifi("Names of files to send, separated by spaces","",
  6883.                &s,&y,xxstring)) < 0) {
  6884.         if (x == -3) {
  6885.             if (nfils <= 0) {
  6886.             printf("?A file specification is required\n");
  6887.             return(-9);
  6888.             } else break;
  6889.         }
  6890.         return(x);
  6891.         }
  6892.         msfiles[nfils++] = lp;    /* Got one, count it, point to it, */
  6893.         p = lp;            /* remember pointer, */
  6894.         while (*lp++ = *s++)    /* and copy it into buffer */
  6895.           if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
  6896.           printf("?MSEND list too long\n");
  6897.           line[0] = NUL;
  6898.           return(-9);
  6899.           }
  6900.         debug(F111,"msfiles",msfiles[nfils-1],nfils-1);
  6901.         if (nfils == 1) *fspec = NUL; /* Take care of \v(filespec) */
  6902. #ifdef ZFNQFP
  6903.         zfnqfp(p,TMPBUFSIZ,tmpbuf);
  6904.         p = tmpbuf;
  6905. #endif /* ZFNQFP */
  6906.         if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) {
  6907.         strcat(fspec,p);
  6908.         strcat(fspec," ");
  6909.         } else printf("WARNING - \\v(filespec) buffer overflow\n");
  6910.     }
  6911.     cmlist = msfiles;        /* Point cmlist to pointer array */
  6912.     cmarg2 = "";            /* No internal expansion list (yet) */
  6913.     sndsrc = nfils;            /* Filenames come from cmlist */
  6914.     sendmode = SM_MSEND;        /* Remember this kind of SENDing */
  6915.     sstate = 's';            /* Set start state for SEND */
  6916.     if (cx == XXMMOVE)        /* If MMOVE'ing, */
  6917.       moving = 1;            /*  set this flag. */
  6918. #ifdef MAC
  6919.     what = W_SEND;
  6920.     scrcreate();
  6921. #endif /* MAC */
  6922.     if (local) {            /* If in local mode, */
  6923.         displa = 1;            /* turn on file transfer display */
  6924.         ttflui();            /* and flush tty input buffer. */
  6925.     }
  6926.     return(0);
  6927.     }
  6928. #endif /* COMMENT */
  6929. #endif /* NOMSEND */
  6930. #endif /* NOXFER */
  6931.  
  6932. #ifndef NOSERVER
  6933.     if (cx == XXSER) {            /* SERVER */
  6934. #ifdef CK_XYZ
  6935.     if (protocol != PROTO_K) {
  6936.         printf("Sorry, SERVER only works with Kermit protocol\n");
  6937.         return(-9);
  6938.     }
  6939. #endif /* CK_XYZ */
  6940. #ifdef COMMENT
  6941. /*
  6942.   Parse for time limit, but since we don't use it yet,
  6943.   the parsing is commented out.
  6944. */
  6945.     x_ifnum = 1;            /* Turn off internal complaints */
  6946.     y = cmnum("optional time limit, seconds, or time of day as hh:mm:ss",
  6947.           "0", 10, &x, xxstring
  6948.           );
  6949.     x_ifnum = 0;
  6950.     if (y < 0) {
  6951.         if (y == -2) {        /* Invalid number or expression */
  6952.         zz = tod2sec(atmbuf);    /* Convert to secs since midnight */
  6953.         if (zz < 0L) {
  6954.             printf("?Number, expression, or time of day required\n");
  6955.             return(-9);
  6956.         } else {
  6957.             char now[32];    /* Current time */
  6958.             char *p;
  6959.             long tnow;
  6960.             p = now;
  6961.             ztime(&p);
  6962.             tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
  6963.             if (zz < tnow)    /* User's time before now */
  6964.               zz += 86400L;    /* So make it tomorrow */
  6965.             zz -= tnow;        /* Seconds from now. */
  6966.         }
  6967.         } else
  6968.           return(y);
  6969.     }
  6970.     if (zz > -1L) {
  6971.         x = zz;
  6972.         if (zz != (long) x) {
  6973.         printf(
  6974. "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
  6975.                );
  6976.         return(-9);
  6977.         }
  6978.     }
  6979.     if (x < 0)
  6980.       x = 0;
  6981. #endif /* COMMENT */
  6982.  
  6983.     if ((x = cmcfm()) < 0) return(x);
  6984.     sstate = 'x';
  6985. #ifdef MAC
  6986.     what = W_RECV;
  6987.     scrcreate();
  6988. #endif /* MAC */
  6989.     if (local) displa = 1;
  6990. #ifdef AMIGA
  6991.     reqoff();            /* No DOS requestors while server */
  6992. #endif /* AMIGA */
  6993.     return(0);
  6994.     }
  6995. #endif /* NOSERVER */
  6996.  
  6997.     if (cx == XXSAVE) {            /* SAVE command */
  6998.     x = cmkey(savtab,nsav,"option","keymap",xxstring);
  6999.     if (x == -3) {
  7000.         printf("?You must specify an option to save\n");
  7001.         return(-9);
  7002.     }
  7003.     if (x < 0) return(x);
  7004.     /* have to set success separately for each item in doprm()... */
  7005.     /* actually not really, could have just had doprm return 0 or 1 */
  7006.     /* and set success here... */
  7007.     y = dosave(x);
  7008.     if (y == -3) {
  7009.         printf("?More fields required\n");
  7010.         return(-9);
  7011.     } else return(y);
  7012.     }
  7013.  
  7014.     if (cx == XXSET) {            /* SET command */
  7015.     x = cmkey(prmtab,nprm,"Parameter","",xxstring);
  7016.     if (x == -3) {
  7017.         printf("?You must specify a parameter to set\n");
  7018.         return(-9);
  7019.     }
  7020.     if (x < 0) return(x);
  7021.     /* have to set success separately for each item in doprm()... */
  7022.     /* actually not really, could have just had doprm return 0 or 1 */
  7023.     /* and set success here... */
  7024.     y = doprm(x,0);
  7025.     if (y == -3) {
  7026.         printf("?More fields required\n");
  7027.         return(-9);
  7028.     } else return(y);
  7029.     }
  7030.  
  7031. #ifndef NOPUSH
  7032.     if (cx == XXSHE            /* SHELL (system) command */
  7033.     || cx == XXEXEC            /* exec() */
  7034.     ) {
  7035.     int rx = 0;
  7036.     char * p = NULL;
  7037.     int i,n;
  7038. #ifdef UNIXOROSK
  7039.     char * args[256];
  7040. #endif /* UNIXOROSK */
  7041.  
  7042. #ifdef IKSD
  7043.     if (inserver && (nopush || !ENABLED(en_hos))) {
  7044.         printf("?Sorry, host command access is disabled\n");
  7045.         return(-9);
  7046.     }
  7047. #endif /* IKSD */
  7048.  
  7049. #ifdef CKEXEC
  7050.     if (cx == XXEXEC) {        /* EXEC (overlay ourselves) */
  7051.         struct FDB sw, fl;
  7052.         cmfdbi(&sw,            /* First FDB - command switches */
  7053.            _CMKEY,        /* fcode */
  7054.            "Command to overlay C-Kermit\n or switch", /* hlpmsg */
  7055.            "",            /* default */
  7056.            "",            /* addtl string data */
  7057.            1,            /* addtl numeric data 1: tbl size */
  7058.            4,            /* addtl numeric data 2: 4 = cmswi */
  7059.            xxstring,        /* Processing function */
  7060.            redirsw,        /* Keyword table */
  7061.            &fl            /* Pointer to next FDB */
  7062.            );
  7063.         cmfdbi(&fl,            /* 2nd FDB - command to exec */
  7064.            _CMFLD,        /* fcode */
  7065.            "Command to overlay C-Kermit", /* hlpmsg */
  7066.            "",            /* default */
  7067.            "",            /* addtl string data */
  7068.            0,            /* addtl numeric data 1 */
  7069.            0,            /* addtl numeric data 2 */
  7070.            xxstring,
  7071.            NULL,
  7072.            NULL            /* No more after this */
  7073.            );
  7074.         while (1) {
  7075.         x = cmfdb(&sw);        /* Parse something */
  7076.         debug(F101,"exec cmfdb","",x);
  7077.         if (x < 0)
  7078.           return(x);
  7079.         /* Generalize this if we add more switches */
  7080.         if (cmresult.fcode == _CMKEY) {
  7081.             rx = 1;
  7082.             continue;
  7083.         }
  7084.         if (cmresult.fcode == _CMFLD)
  7085.           break;
  7086.         return(-2);
  7087.         }
  7088.         ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ);
  7089.         if (!tmpbuf[0]) {
  7090.         printf("?Command required\n");
  7091.         return(-9);
  7092.         }
  7093.         p = brstrip(tmpbuf);
  7094.         args[0] = NULL;        /* Set argv[0] to it */
  7095.         makestr(&args[0],p);
  7096.         for (i = 1; i < 255; i++) {    /* Get arguments for command */
  7097.         if ((x = cmfld("Argument","",&s,xxstring)) < 0) {
  7098.             if (x == -3) {
  7099.             if ((x = cmcfm()) < 0)
  7100.               return(x);
  7101.             break;
  7102.             } else
  7103.               return(x);
  7104.         }
  7105.         args[i] = NULL;
  7106.         s = brstrip(s);
  7107.         makestr(&args[i],s);
  7108.         }
  7109.         args[i] = NULL;
  7110.     } else {
  7111. #endif /* CKEXEC */
  7112.         if ((x = cmtxt("System command to execute","",&s,xxstring)) < 0)
  7113.           return(x);
  7114. #ifdef CKEXEC
  7115.     }
  7116. #endif /* CKEXEC */
  7117.         if (nopush)
  7118.           return(success = 0);
  7119. #ifdef CK_APC
  7120.     if (apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  7121.       return(success = 0);
  7122. #endif /* CK_APC */
  7123.     conres();            /* Make console normal  */
  7124. #ifdef OS2
  7125.     if (!(s && *s)) {
  7126.         os2push();
  7127.         x = 1;
  7128.     } else
  7129. #endif /* OS2 */
  7130.       if (cx == XXSHE) {
  7131.           x = zshcmd(s);
  7132.           debug(F101,"RUN zshcmd code","",x);
  7133.           concb((char)escape);
  7134.           return(success = x);
  7135. #ifdef CKEXEC
  7136.       } else {
  7137. #ifdef DEBUG
  7138.           if (deblog) {
  7139.           debug(F111,"EXEC cmd",p,0);
  7140.           for (i = 0; i < 256 && args[i]; i++)
  7141.             debug(F111,"EXEC arg",args[i],i);
  7142.           }
  7143. #endif /* DEBUG */
  7144.           if (p) {
  7145.           z_exec(p,args,rx);    /* Overlay ourself */
  7146.           debug(F100,"EXEC fails","",0);
  7147.           concb((char)escape);    /* In case it returns */
  7148.           }
  7149.           return(success = 0);
  7150. #endif /* CKEXEC */
  7151.       }
  7152.     }
  7153.  
  7154. #ifdef CK_REDIR
  7155.     if (cx == XXFUN) {            /* REDIRECT */
  7156. #ifdef CK_APC
  7157.     if (apcactive == APC_LOCAL ||
  7158.         apcactive == APC_REMOTE && apcstatus != APC_UNCH) return(success = 0);
  7159. #endif /* CK_APC */
  7160.     sprintf(tmpbuf,
  7161.         "Local command to run,\n\
  7162. with its standard input/output redirected to %s\n",
  7163.         ttname);
  7164.     if ((x = cmtxt(tmpbuf,"",&s,xxstring)) < 0)
  7165.       return(x);
  7166.         if (nopush) {
  7167.             printf("?REDIRECT disabled\n");
  7168.             return(success=0);
  7169.         }
  7170.     if (!local) {
  7171.         printf("?SET LINE or SET HOST required first\n");
  7172.         return(-9);
  7173.     }
  7174.     return(success = ttruncmd(s));
  7175.     }
  7176. #endif /* CK_REDIR */
  7177. #endif /* NOPUSH */
  7178.  
  7179. #ifndef NOSHOW
  7180.     if (cx == XXSHO) {            /* SHOW */
  7181.     x = cmkey(shotab,nsho,"","parameters",xxstring);
  7182.     if (x < 0) return(x);
  7183.     return(doshow(x));
  7184.     }
  7185. #endif /* NOSHOW */
  7186.  
  7187. #ifndef MAC
  7188.     if (cx == XXSPA) {            /* SPACE */
  7189. #ifdef IKSD
  7190.     if (inserver && !ENABLED(en_spa)) {
  7191.         printf("?Sorry, SPACE command disabled\n");
  7192.         return(-9);
  7193.     }
  7194. #endif /* IKSD */
  7195. #ifdef datageneral
  7196.     /* AOS/VS can take an argument after its "space" command. */
  7197.     if ((x = cmtxt("Confirm, or local directory name","",&s,xxstring)) < 0)
  7198.       return(x);
  7199.     if (nopush) {
  7200.         printf("?Sorry, SPACE command disabled\n");
  7201.         return(-9);
  7202.     } else if (*s == NUL) {
  7203.         xsystem(SPACMD);
  7204.     } else {
  7205.         sprintf(line,"space %s",s);
  7206.         xsystem(line);
  7207.     }
  7208. #else
  7209. #ifdef OS2
  7210.     if ((x = cmtxt("Press Enter for current disk,\n\
  7211.  or specify a disk letter like A:","",&s,xxstring)) < 0)
  7212.       return(x);
  7213.     if (*s == NUL) {        /* Current disk */
  7214.         printf(" Free space: %ldK\n", zdskspace(0)/1024L);
  7215.     } else {
  7216.         int drive = toupper(*s);
  7217.         printf(" Drive %c: %ldK free\n", drive,
  7218.            zdskspace(drive - 'A' + 1) / 1024L);
  7219.     }
  7220. #else
  7221. #ifdef UNIXOROSK
  7222.     x = cmdir("Confirm for current disk,\n\
  7223.  or specify a disk device or directory","",&s,xxstring);
  7224.     if (x == -3)
  7225.       s = "";
  7226.     else if (x < 0)
  7227.       return(x);
  7228.         ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  7229.         s = tmpbuf;
  7230.     if ((x = cmcfm()) < 0) return(x);
  7231.     if (nopush) {
  7232.         printf("?Sorry, SPACE command disabled\n");
  7233.         return(-9);
  7234.     }
  7235.     if (!*s) {            /* Current disk */
  7236.         xsystem(SPACMD);
  7237.     } else {            /* Specified disk */
  7238.         sprintf(line,"%s %s",SPACM2,s);
  7239.         xsystem(line);
  7240.     }
  7241. #else
  7242.     if ((x = cmcfm()) < 0) return(x);
  7243.     if (nopush) {
  7244.         printf("?Sorry, SPACE command disabled\n");
  7245.         return(-9);
  7246.     }
  7247.     xsystem(SPACMD);
  7248. #endif /* UNIXOROSK */
  7249. #endif /* OS2 */
  7250. #endif /* datageneral */
  7251.     return(success = 1);        /* Pretend it worked */
  7252.     }
  7253. #endif /* MAC */
  7254.  
  7255. #ifndef NOXFER
  7256.     if (cx == XXSTA) {            /* STATISTICS */
  7257.     if ((x = cmkey(stattab,2,"Carriage return, or option",
  7258.                "/brief",xxstring)) < 0)
  7259.       return(x);
  7260.     if ((y = cmcfm()) < 0) return(y);
  7261.     return(success = dostat(x));
  7262.     }
  7263. #endif /* NOXFER */
  7264.  
  7265.     if (cx == XXSTO || cx == XXEND) {    /* STOP, END, or POP */
  7266.     if ((y = cmnum("exit status code","0",10,&x,xxstring)) < 0)
  7267.       return(y);
  7268.     if ((y = cmtxt("Message to print","",&s,xxstring)) < 0)
  7269.       return(y);
  7270.     s = brstrip(s);
  7271.     if (*s) printf("%s\n",s);
  7272.     if (cx == XXSTO) {
  7273.         dostop();
  7274.     } else {
  7275. #ifndef NOSPL
  7276.         /* Pop from all FOR/WHILE/XIF/SWITCH's */
  7277.         debug(F101,"END maclvl 1","",maclvl);
  7278.         while ((maclvl > 0) &&
  7279.            (m_arg[maclvl-1][0]) &&
  7280.            (cmdstk[cmdlvl].src == CMD_MD) &&
  7281.              (!strncmp(m_arg[maclvl-1][0],"_xif",4) ||
  7282.               !strncmp(m_arg[maclvl-1][0],"_for",4) ||
  7283.               !strncmp(m_arg[maclvl-1][0],"_whi",4) ||
  7284.               !strncmp(m_arg[maclvl-1][0],"_swi",4))) {
  7285.         debug(F110,"END popping",m_arg[maclvl-1][0],0);
  7286.         dogta(XXPTA);        /* Put args back */
  7287.         popclvl();        /* Pop up two levels */
  7288.         popclvl();
  7289.         debug(F101,"END maclvl 2","",maclvl);
  7290.         }
  7291.             if (maclvl > -1) {
  7292.         if (mrval[maclvl])    /* Free previous retval if any */
  7293.           free(mrval[maclvl]);
  7294.         mrval[maclvl] = malloc(16); /* Room for up to 15 digits */
  7295.         if (mrval[maclvl])
  7296.           sprintf(mrval[maclvl],"%d",x); /* Record current retval */
  7297.         }
  7298. #endif /* NOSPL */
  7299.         popclvl();            /* Now pop out of macro or TAKE file */
  7300. #ifndef NOSPL
  7301. #ifdef DEBUG
  7302.         if (deblog) {
  7303.         debug(F101,"END maclvl 3","",maclvl);
  7304.         debug(F111,"END mrval[maclvl]",mrval[maclvl],maclvl);
  7305.         debug(F111,"END mrval[maclvl+1]",mrval[maclvl+1],maclvl+1);
  7306.         }
  7307. #endif /* DEBUG */
  7308. #endif /* NOSPL */
  7309.     }
  7310.     return(success = (x == 0));
  7311.     }
  7312.     if (cx == XXSUS) {            /* SUSPEND */
  7313.     if ((y = cmcfm()) < 0) return(y);
  7314. #ifdef NOJC
  7315.     printf("Sorry, this version of Kermit cannot be suspended\n");
  7316. #else
  7317. #ifdef IKSD
  7318.     if (inserver) {
  7319.         printf("?Sorry, IKSD can not be suspended\n");
  7320.         return(-9);
  7321.     } else
  7322. #endif /* IKSD */
  7323.       if (nopush) {
  7324.         printf("?Sorry, access to system is disabled\n");
  7325.         return(-9);
  7326.     }
  7327.     stptrap(0);
  7328. #endif /* NOJC */
  7329.     return(0);
  7330.     }
  7331.  
  7332.     if (cx == XXTAK) {            /* TAKE */
  7333. #ifdef OS2
  7334.     extern char startupdir[],exedir[],inidir[];
  7335.     char * scriptenv, * keymapenv;
  7336. #endif /* OS2 */
  7337.     char takepath[1024];
  7338.  
  7339.     if (tlevel >= MAXTAKE-1) {
  7340.         printf("?Take files nested too deeply\n");
  7341.         return(-9);
  7342.     }
  7343. #ifdef OS2
  7344. #ifdef NT
  7345.     scriptenv = getenv("K95SCRIPTS");
  7346.     keymapenv = getenv("K95KEYMAPS");
  7347. #else /* NT */
  7348.     scriptenv = getenv("K2SCRIPTS");
  7349.     keymapenv = getenv("K2KEYMAPS");
  7350. #endif /* NT */
  7351.     if (!scriptenv)
  7352.       scriptenv = getenv("CK_SCRIPTS");
  7353.     if (!keymapenv)
  7354.       keymapenv = getenv("CK_KEYMAPS");
  7355.  
  7356.     sprintf(takepath,
  7357.                 /* semicolon-separated path list */
  7358.                 "%s%s%s%s%s;%s%s;%s%s;%s;%s%s;%s%s;%s;%s%s;%s%s",
  7359.                 scriptenv?scriptenv:"",
  7360.                 (scriptenv && scriptenv[strlen(scriptenv)-1]==';')?"":";",
  7361.                 keymapenv?keymapenv:"",
  7362.                 (keymapenv && keymapenv[strlen(keymapenv)-1]==';')?"":";",
  7363.                 startupdir,
  7364.                 startupdir, "SCRIPTS/",
  7365.                 startupdir, "KEYMAPS/",
  7366.                 inidir,
  7367.                 inidir, "SCRIPTS/",
  7368.                 inidir, "KEYMAPS/",
  7369.                 zhome(),
  7370.                 zhome(), "SCRIPTS/",
  7371.                 zhome(), "KEYMAPS/",
  7372.                 exedir,
  7373.                 exedir, "SCRIPTS/",
  7374.                 exedir, "KEYMAPS/"
  7375.                 );
  7376. #else /* not OS2 */
  7377.     y = 1024;
  7378.     s = takepath;
  7379.     zzstring("\\v(home)",&s,&y);
  7380. #endif /* OS2 */
  7381.  
  7382.     if ((y = cmifip("C-Kermit command file",
  7383.             "",&s,&x,0,takepath,xxstring)) < 0) {
  7384.         if (y == -3) {
  7385.         printf("?A file name is required\n");
  7386.         return(-9);
  7387.         } else
  7388.           return(y);
  7389.     }
  7390.     if (x != 0) {
  7391.         printf("?Wildcards not allowed in command file name\n");
  7392.         return(-9);
  7393.     }
  7394.     ckstrncpy(line,s,LINBUFSIZ);
  7395.     debug(F110,"take file",s,0);
  7396.     if (isdir(s)) {
  7397.         printf("?Can't execute a directory - \"%s\"\n", s);
  7398.         return(-9);
  7399.     }
  7400. #ifndef NOTAKEARGS
  7401.     {
  7402.         char * p;
  7403.         /* extern char **m_xarg[]; */
  7404.         x = strlen(line);
  7405.         p = line + x + 1;
  7406.         if ((y = cmtxt("Optional arguments","",&s,xxstring)) < 0)
  7407.           return(y);
  7408.         if (*s) {            /* Args given? */
  7409.         ckstrncpy(p,s,LINBUFSIZ-x-1);
  7410. #ifdef ZFNQFP
  7411.         zfnqfp(line,TMPBUFSIZ,tmpbuf);
  7412.         s = tmpbuf;
  7413. #else
  7414.         s = line;
  7415. #endif /* ZFNQFP */
  7416.         addmac("%0",s);        /* Define %0 = name of file */
  7417.         varnam[0] = '%';
  7418.         varnam[2] = '\0';
  7419.         debug(F110,"take arg 0",s,0);
  7420.         debug(F110,"take args",p,0);
  7421.         for (y = 1; y < 10; y++) { /* Clear current args %1..%9 */
  7422.             varnam[1] = (char) (y + '0');
  7423.             delmac(varnam);
  7424.         }
  7425.         xwords(p,MAXARGLIST,NULL,0); /* Assign new args */
  7426.         debug(F110,"take args",p,0);
  7427.         }
  7428.     }
  7429. #else
  7430.     if ((y = cmcfm()) < 0) return(y);
  7431. #endif /* NOTAKEARGS */
  7432.     return(success = dotake(line));
  7433.     }
  7434.  
  7435. #ifndef NOLOCAL
  7436. #ifdef OS2
  7437.     if (cx == XXVIEW) {            /* VIEW Only Terminal mode */
  7438.     viewonly = TRUE;
  7439.     success = doconect(0);
  7440.     viewonly = FALSE;
  7441.     return success;
  7442.     }
  7443. #endif /* OS2 */
  7444.  
  7445. #ifdef NETCONN
  7446.     if (cx == XXTEL || cx == XXIKSD) {    /* TELNET */
  7447.     int x,z;
  7448. #ifdef OS2
  7449.     if (!tcp_avail) {
  7450.         printf("?Sorry, either TCP/IP is not available on this system or\n\
  7451. necessary DLLs did not load.  Use SHOW NETWORK to check network status.\n");
  7452.         success = 0;
  7453.         return(-9);
  7454.     } else
  7455. #endif /* OS2 */
  7456.       {
  7457.       x = nettype;            /* Save net type in case of failure */
  7458.       z = ttnproto;            /* Save protocol in case of failure */
  7459.       nettype = NET_TCPB;
  7460.       ttnproto = (cx == XXTEL) ? NP_TELNET : NP_KERMIT;
  7461.       if ((y = setlin(XYHOST,0,1)) < 0) {
  7462.               nettype = x;        /* Failed, restore net type. */
  7463.               ttnproto = z;        /* and protocol */
  7464.               success = 0;
  7465.       }
  7466.       didsetlin++;
  7467.         }
  7468.     return(y);
  7469.     }
  7470.  
  7471. #ifndef PTYORPIPE
  7472. #ifdef NETCMD
  7473. #define PTYORPIPE
  7474. #else
  7475. #ifdef NETPTY
  7476. #define PTYORPIPE
  7477. #endif /* NETPTY */
  7478. #endif /* NETCMD */
  7479. #endif /* PTYORPIPE */
  7480.  
  7481. #ifdef PTYORPIPE
  7482.     if (cx == XXPIPE || cx == XXPTY) {    /* PIPE or PTY */
  7483.     int x;
  7484.     extern int netsave;
  7485.     x = nettype;            /* Save net type in case of failure */
  7486.     nettype = (cx == XXPIPE) ? NET_CMD : NET_PTY;
  7487.     if ((y = setlin(XYHOST,0,1)) < 0) {
  7488.         nettype = x;        /* Failed, restore net type. */
  7489.         ttnproto = z;        /* and protocol */
  7490.         success = 0;
  7491.     }
  7492.     didsetlin++;
  7493.     netsave = x;
  7494.     return(y);
  7495.     }
  7496. #endif /* PTYORPIPE */
  7497.  
  7498.     if (cx == XXRLOG) {            /* RLOGIN */
  7499. #ifdef RLOGCODE
  7500.     int x,z;
  7501. #ifdef OS2
  7502.     if (!tcp_avail) {
  7503.         printf("?Sorry, either TCP/IP is not available on this system or\n\
  7504. necessary DLLs did not load.  Use SHOW NETWORK to check network status.\n"
  7505.            );
  7506.         success = 0;
  7507.         return(-9);
  7508.     } else {
  7509. #endif /* OS2 */
  7510.         x = nettype;        /* Save net type in case of failure */
  7511.         z = ttnproto;        /* Save protocol in case of failure */
  7512.         nettype = NET_TCPB;
  7513.         ttnproto = NP_RLOGIN;
  7514.         if ((y = setlin(XYHOST,0,1)) < 0) {
  7515.         nettype = x;        /* Failed, restore net type. */
  7516.         ttnproto = z;        /* and protocol */
  7517.         success = 0;
  7518.         }
  7519.         didsetlin++;
  7520. #ifdef OS2
  7521.     }
  7522. #endif /* OS2 */
  7523.     return(y);
  7524. #else
  7525.     printf("?Sorry, RLOGIN is not configured in this copy of C-Kermit.\n");
  7526.     return(-9);
  7527. #endif /* RLOGCODE */
  7528.     }
  7529. #endif /* NETCONN */
  7530. #endif /* NOLOCAL */
  7531.  
  7532. #ifndef NOXMIT
  7533.     if (cx == XXTRA) {            /* TRANSMIT */
  7534.     int i, n, xpipe = 0, xbinary = 0, xxlate = 1, xxnowait = 0, getval;
  7535.     char c;
  7536.     struct FDB sf, sw, tx;        /* FDBs for parse functions */
  7537. #ifndef NOCSETS
  7538.     extern int tcs_transp;        /* Term charset is transparent */
  7539. #else
  7540.     int tcs_transp = 1;
  7541. #endif /* NOCSETS */
  7542.  
  7543. #ifdef COMMENT
  7544.     xbinary = binary;        /* Default text/binary mode */
  7545. #else
  7546.     xbinary = 0;            /* Default is text */
  7547. #endif /* COMMENT */
  7548.  
  7549.     cmfdbi(&sw,            /* First FDB - command switches */
  7550.            _CMKEY,            /* fcode */
  7551.            "Filename, or switch",    /* hlpmsg */
  7552.            "",            /* default */
  7553.            "",            /* addtl string data */
  7554.            nxmitsw,            /* addtl numeric data 1: tbl size */
  7555.            4,            /* addtl numeric data 2: 4 = cmswi */
  7556.            xxstring,        /* Processing function */
  7557.            xmitsw,            /* Keyword table */
  7558.            &sf            /* Pointer to next FDB */
  7559.            );
  7560.     cmfdbi(&sf,            /* 2nd FDB - file to send */
  7561.            _CMIFI,            /* fcode */
  7562.            "File to transmit",    /* hlpmsg */
  7563.            "",            /* default */
  7564.            "",            /* addtl string data */
  7565.            0,            /* addtl numeric data 1 */
  7566.            0,            /* addtl numeric data 2 */
  7567.            xxstring,
  7568.            NULL,
  7569. #ifdef PIPESEND
  7570.            &tx
  7571. #else
  7572.            NULL
  7573. #endif /* PIPESEND */
  7574.            );
  7575. #ifdef PIPESEND
  7576.     cmfdbi(&tx,
  7577.          _CMTXT,            /* fcode */
  7578.          "Command",            /* hlpmsg */
  7579.            "",            /* default */
  7580.            "",            /* addtl string data */
  7581.            0,            /* addtl numeric data 1 */
  7582.            0,            /* addtl numeric data 2 */
  7583.            xxstring,
  7584.            NULL,
  7585.            NULL
  7586.            );
  7587. #endif /* PIPESEND */
  7588.  
  7589.     while (1) {
  7590.         x = cmfdb(&sw);
  7591.         if (x < 0)
  7592.           return(x);
  7593.         if (cmresult.fcode != _CMKEY)
  7594.           break;
  7595.         c = cmgbrk();        /* Have switch, get break character */
  7596.         if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  7597.         printf("?This switch does not take an argument\n");
  7598.         return(-9);
  7599.         }
  7600.         if (!getval && (cmgkwflgs() & CM_ARG)) {
  7601.         printf("?This switch requires an argument\n");
  7602.         return(-9);
  7603.         }
  7604.         n = cmresult.nresult;    /* Numeric result = switch ID */
  7605.         switch (n) {        /* Process the switch */
  7606. #ifdef PIPESEND
  7607.           case XMI_CMD:        /* Transmit from a command */
  7608.         if (nopush) {
  7609.             printf("?Sorry, system command access is disabled\n");
  7610.             return(-9);
  7611.         }
  7612.         sw.hlpmsg = "Command, or switch"; /* Change help message */
  7613.         xpipe = 1;        /* (No way to undo this one) */
  7614.         break;
  7615. #endif /* PIPESEND */
  7616.  
  7617.           case XMI_BIN:        /* Binary */
  7618.         xbinary = 1;
  7619.         xxlate = 0;        /* Don't translate charsets */
  7620.         break;
  7621.  
  7622.           case XMI_TXT:        /* Text */
  7623.         xbinary = 0;
  7624.         xxlate = !tcs_transp;    /* Translate if TERM CHAR not TRANSP */
  7625.         break;
  7626.  
  7627.           case XMI_TRA:        /* Transparent text */
  7628.         xbinary = 0;
  7629.         xxlate = 0;        /* But don't translate charsets */
  7630.         break;
  7631.  
  7632. #ifdef COMMENT
  7633.           case XMI_VRB:        /* /VERBOSE */
  7634.           case XMI_QUI:        /* /QUIET */
  7635.         break;            /* (not implemented yet) */
  7636. #endif /* COMMENT */
  7637.  
  7638.           case XMI_NOW:        /* /NOWAIT */
  7639.         xxnowait = 1;
  7640.         break;
  7641.  
  7642.           default:
  7643.         return(-2);
  7644.         }
  7645.  
  7646.     }
  7647.     if (cmresult.fcode != _CMIFI && cmresult.fcode != _CMTXT)
  7648.       return(-2);
  7649.     ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Filename */
  7650.     s = line;
  7651.     if ((y = cmcfm()) < 0)        /* Confirm */
  7652.       return(y);
  7653. #ifdef CK_APC
  7654.     if (apcactive == APC_LOCAL ||
  7655.         apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  7656.       return(success = 0);
  7657. #endif /* CK_APC */
  7658.     if (cmresult.nresult != 0) {
  7659.         printf("?Only a single file may be transmitted\n");
  7660.         return(-9);
  7661.     }
  7662. #ifdef PIPESEND
  7663.     if (xpipe) {
  7664.         s = brstrip(s);
  7665.         if (!*s) {
  7666.         printf("?Sorry, a command to send from is required\n");
  7667.         return(-9);
  7668.         }
  7669.         pipesend = 1;
  7670.     }
  7671. #endif /* PIPESEND */
  7672.     success = transmit(s,
  7673.                (xxnowait ? (char)0 : (char)xmitp),
  7674.                xxlate,
  7675.                xbinary
  7676.                );
  7677.     return(success);
  7678.     }
  7679. #endif /* NOXMIT */
  7680.  
  7681. #ifndef NOFRILLS
  7682.     if (cx == XXTYP || cx == XXMORE) {    /* TYPE or MORE */
  7683.     int paging = 0, havename = 0, head = 0, width = 0, count = 0;
  7684.     char pfxbuf[64], * prefix = NULL;
  7685.     extern int xaskmore;
  7686.     struct FDB sf, sw;
  7687.     char * pat = NULL;
  7688.  
  7689.     if (cx == XXMORE)
  7690.       paging = 1;
  7691.     else
  7692.       paging = (typ_page < 0) ? xaskmore : typ_page;
  7693.  
  7694. #ifdef IKSD
  7695.     if (inserver && !ENABLED(en_typ)) {
  7696.         printf("?Sorry, TYPE command disabled\n");
  7697.         return(-9);
  7698.     }
  7699. #endif /* IKSD */
  7700.  
  7701.     cmfdbi(&sw,                /* 2nd FDB - optional /PAGE switch */
  7702.        _CMKEY,            /* fcode */
  7703.        "Filename or switch",    /* hlpmsg */
  7704.        "",                /* default */
  7705.        "",                /* addtl string data */
  7706.        ntypetab,            /* addtl numeric data 1: tbl size */
  7707.        4,                /* addtl numeric data 2: 4 = cmswi */
  7708.        xxstring,            /* Processing function */
  7709.        typetab,            /* Keyword table */
  7710.        &sf                /* Pointer to next FDB */
  7711.        );
  7712.  
  7713.     cmfdbi(&sf,                /* 1st FDB - file to type */
  7714.        _CMIFI,            /* fcode */
  7715.        "",                /* hlpmsg */
  7716.        "",                /* default */
  7717.        "",                /* addtl string data */
  7718.        0,                /* addtl numeric data 1 */
  7719.        0,                /* addtl numeric data 2 */
  7720.        xxstring,
  7721.        NULL,
  7722.        NULL
  7723.        );
  7724.  
  7725.     while (!havename) {
  7726.         x = cmfdb(&sw);        /* Parse something */
  7727.         debug(F101,"dotype cmfdb","",x);
  7728.         debug(F101,"dotype cmresult.fcode","",cmresult.fcode);
  7729.         debug(F101,"dotype cmresult.nresult","",cmresult.nresult);
  7730.         if (x < 0)            /* Error */
  7731.           return(x);
  7732.         else if (cmresult.fcode == _CMKEY) {
  7733.         char c; int getval;
  7734.         c = cmgbrk();
  7735.         getval = (c == ':' || c == '=');
  7736.         if (getval && !(cmgkwflgs() & CM_ARG)) {
  7737.             printf("?This switch does not take an argument\n");
  7738.             return(-9);
  7739.         }
  7740. #ifdef COMMENT
  7741.         if (!getval && (cmgkwflgs() & CM_ARG)) {
  7742.             printf("?This switch requires an argument\n");
  7743.             /* Not if it has a default! */
  7744.             return(-9);
  7745.         }
  7746. #endif /* COMMENT */
  7747.         switch (cmresult.nresult) {
  7748. #ifdef CK_TTGWSIZ
  7749.           case TYP_PAG:
  7750.             paging = 1;
  7751.             break;
  7752.  
  7753.           case TYP_NOP:
  7754.             paging = 0;
  7755.             break;
  7756. #endif /* CK_TTGWSIZ */
  7757.  
  7758.           case TYP_COU:
  7759.             count = 1;
  7760.             break;
  7761.  
  7762.           case TYP_HEA:
  7763.           case TYP_TAI:
  7764.             y = 10;
  7765.             if (getval)
  7766.               if ((x = cmnum("Number of lines",
  7767.                      "10",10,&y,xxstring)) < 0)
  7768.             return(x);
  7769.             head = (cmresult.nresult == TYP_TAI) ? -y : y;
  7770.             break;
  7771.  
  7772.           case TYP_WID:
  7773.             y = typ_wid > -1 ? typ_wid : cmd_cols;
  7774.             if (getval)
  7775.               if ((x = cmnum("Column at which to truncate",
  7776.                      ckitoa(y),10,&y,xxstring)) < 0)
  7777.             return(x);
  7778.             width = y;
  7779.             break;
  7780.  
  7781.           case TYP_PAT:
  7782.             if (!getval && (cmgkwflgs() & CM_ARG)) {
  7783.             printf("?This switch requires an argument\n");
  7784.             return(-9);
  7785.             }
  7786.             if ((x = cmfld("pattern","",&s,xxstring)) < 0)
  7787.               return(x);
  7788.             ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  7789.             pat = tmpbuf;
  7790.             break;
  7791.  
  7792.           case TYP_PFX:
  7793.             if (!getval && (cmgkwflgs() & CM_ARG)) {
  7794.             printf("?This switch requires an argument\n");
  7795.             return(-9);
  7796.             }
  7797.             if ((x = cmfld("prefix for each line","",&s,xxstring)) < 0)
  7798.               return(x);
  7799.             if ((int)strlen(s) > 63) {
  7800.             printf("?Too long - 63 max\n");
  7801.             return(-9);
  7802.             }
  7803.             ckstrncpy(pfxbuf,s,64);
  7804.             prefix = brstrip(pfxbuf);
  7805.             break;
  7806.         }
  7807.         } else if (cmresult.fcode == _CMIFI)
  7808.           havename = 1;
  7809.         else
  7810.           return(-2);
  7811.     }
  7812.     if (havename) {
  7813.         ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
  7814.         y = cmresult.nresult;
  7815.     } else {
  7816.         if ((x = cmifi("Filename","",&s,&y,xxstring)) < 0) {
  7817.         if (x == -3) {
  7818.             printf("?Name of an existing file required\n");
  7819.             return(-9);
  7820.         } else return(x);
  7821.         }
  7822.         ckstrncpy(line,s,LINBUFSIZ);
  7823.     }
  7824.     if (y != 0) {
  7825.         printf("?A single file please\n");
  7826.         return(-9);
  7827.     }
  7828.     if ((y = cmcfm()) < 0)        /* Confirm the command */
  7829.       return(y);
  7830.  
  7831.     if (count) paging = -1;
  7832.     debug(F111,"dotype",line,paging);
  7833.     return(success = dotype(line,paging,0,head,pat,width,prefix));
  7834.     }
  7835. #endif /* NOFRILLS */
  7836.  
  7837. #ifndef NOCSETS
  7838.     if (cx == XXXLA)  {       /* TRANSLATE <ifn> from-cs to-cs <ofn> */
  7839. #ifdef OS2ONLY
  7840.         extern int tt_font;
  7841. #endif /* OS2ONLY */
  7842.     int incs, outcs;
  7843.         char * tocs = "";
  7844.     if ((x = cmifi("File to translate","",&s,&y,xxstring)) < 0) {
  7845.         if (x == -3) {
  7846.         printf("?Name of an existing file\n");
  7847.         return(-9);
  7848.         } else return(x);
  7849.     }
  7850.     if (y != 0) {
  7851.         printf("?A single file please\n");
  7852.         return(-9);
  7853.     }
  7854.     ckstrncpy(line,s,LINBUFSIZ);    /* Save copy of string just parsed. */
  7855.  
  7856.     if ((incs = cmkey(fcstab,nfilc,"from character-set","",xxstring)) < 0)
  7857.       return(incs);
  7858. #ifdef OS2
  7859.         if (isunicode()) {
  7860.         tocs = "ucs2";
  7861.         } else {
  7862.             y = os2getcp();        /* Default is current code page */
  7863.             switch (y) {
  7864.           case 437: tocs = "cp437"; break;
  7865.           case 850: tocs = "cp850"; break;
  7866.           case 852: tocs = "cp852"; break;
  7867.           case 857: tocs = "cp857"; break;
  7868.           case 858: tocs = "cp858"; break;
  7869.           case 862: tocs = "cp862"; break;
  7870.           case 866: tocs = "cp866"; break;
  7871.           case 869: tocs = "cp869"; break;
  7872.           case 1250: tocs = "cp1250"; break;
  7873.           case 1251: tocs = "cp1251"; break;
  7874.           case 1252: tocs = "cp1252"; break;
  7875.           case 1253: tocs = "cp1253"; break;
  7876.           case 1254: tocs = "cp1254"; break;
  7877.           case 1255: tocs = "cp1255"; break;
  7878.           case 1256: tocs = "cp1256"; break;
  7879.           case 1257: tocs = "cp1257"; break;
  7880.           case 1258: tocs = "cp1258"; break;
  7881.             }
  7882.         }
  7883. #ifdef OS2ONLY
  7884. /*
  7885.    If the user has loaded a font with SET TERMINAL FONT then we want
  7886.    to change the default code page to the font that was loaded.
  7887. */
  7888.     if (tt_font != TTF_ROM) {
  7889.             extern struct keytab termfont[];
  7890.             extern int ntermfont;
  7891.         for (y = 0; y < ntermfont; y++) {
  7892.         if (termfont[y].kwval == tt_font) {
  7893.             tocs = termfont[y].kwd;
  7894.             break;
  7895.         }
  7896.         }
  7897.     }
  7898. #endif /* OS2ONLY */
  7899. #else /* OS2 */
  7900.                     /* Make current file char set */
  7901.     for (y = 0; y <= nfilc; y++)    /* be the default... */
  7902.       if (fcstab[y].kwval == fcharset) {
  7903.           tocs = fcstab[y].kwd;
  7904.           break;
  7905.       }
  7906. #endif /* OS2 */
  7907.  
  7908.     if ((outcs = cmkey(fcstab,nfilc,"to character-set",tocs,xxstring)) < 0)
  7909.       return(outcs);
  7910.     if ((x = cmofi("output file",CTTNAM,&s,xxstring)) < 0) return(x);
  7911.     if (x > 1) {
  7912.         printf("?Directory name not allowed\n");
  7913.         return(-9);
  7914.     }
  7915.     ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  7916.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  7917.     return(success = xlate(line,tmpbuf,incs,outcs)); /* Execute it */
  7918.     }
  7919. #endif /* NOCSETS */
  7920.  
  7921.     if (cx == XXVER) {            /* VERSION */
  7922.     int n = 0;
  7923.     extern char * ck_patch, * ck_s_test;
  7924.     extern int hmtopline;
  7925.     if ((y = cmcfm()) < 0)
  7926.           return(y);
  7927.  
  7928.     printf("\n%s, for%s\n Numeric: %ld",versio,ckxsys,vernum);
  7929.     printf("\n");
  7930.     n = 3;
  7931.     if (*ck_s_test) {
  7932.         printf("\n THIS IS A TEST VERSION, NOT FOR PRODUCTION USE.\n");
  7933.         n += 2;
  7934.     }
  7935.     if (*ck_patch) {
  7936.         printf(" Patches: %s\n", ck_patch);
  7937.         n++;
  7938.     }
  7939. #ifdef OS2
  7940.     printf(" Type COPYRIGHT for copyright information.\n\n");
  7941.     shoreg();
  7942. #else
  7943.     hmtopline = n+1;
  7944.     hmsga(copyright);
  7945.     hmtopline = 0;
  7946. #endif /* OS2 */
  7947.     return(success = 1);
  7948.     }
  7949.  
  7950.     if (cx == XXCPR) {            /* COPYRIGHT */
  7951.     if ((y = cmcfm()) < 0)
  7952.           return(y);
  7953.     hmsga(copyright);
  7954.     return(success = 1);
  7955.     }
  7956.  
  7957. #ifndef MAC                /* Only for multiuser systems */
  7958. #ifndef OS2
  7959. #ifndef NOFRILLS
  7960.     if (cx == XXWHO) {            /* WHO */
  7961.     char *wc;
  7962. #ifdef IKSD
  7963.     if (inserver && !ENABLED(en_who)) {
  7964.         printf("?Sorry, WHO command disabled\n");
  7965.         return(-9);
  7966.     }
  7967. #endif /* IKSD */
  7968. #ifdef datageneral
  7969.     if ((z = cmcfm()) < 0) return(z);
  7970.     if (nopush) {
  7971.         printf("?Sorry, who not allowed\n");
  7972.         return(success = 0);
  7973.     }
  7974.         xsystem(WHOCMD);
  7975. #else
  7976.     if ((y = cmtxt("user name","",&s,xxstring)) < 0) return(y);
  7977.         if (nopush) {
  7978.         printf("?Sorry, WHO command disabled\n");
  7979.         return(success = 0);
  7980.     }
  7981.     if (!(wc = getenv("CK_WHO"))) wc = WHOCMD;
  7982.     if (wc)
  7983.       if ((int) strlen(wc) > 0) {
  7984.           sprintf(line,"%s %s",wc,s);
  7985.           xsystem(line);
  7986.       }
  7987. #endif /* datageneral */
  7988.     return(success = 1);
  7989.     }
  7990. #endif /* NOFRILLS */
  7991. #endif /* OS2 */
  7992. #endif /* MAC */
  7993.  
  7994. #ifndef NOFRILLS
  7995.     if (cx == XXWRI || cx == XXWRL || cx == XXWRBL) { /* WRITE */
  7996.     if ((x = cmkey(writab,nwri,"to file or log","",xxstring)) < 0) {
  7997.         if (x == -3) printf("?Write to what?\n");
  7998.         return(x);
  7999.     }
  8000.     if ((y = cmtxt("text","",&s,xxstring)) < 0) return(y);
  8001.     s = brstrip(s);
  8002.     switch (x) {
  8003.       case LOGD: y = ZDFILE; break;
  8004.       case LOGP: y = ZPFILE; break;
  8005. #ifndef NOLOCAL
  8006.       case LOGS: y = ZSFILE; break;
  8007. #endif /* NOLOCAL */
  8008.       case LOGT: y = ZTFILE; break;
  8009. #ifndef NOSPL
  8010.       case LOGW: y = ZWFILE; break;
  8011. #endif /* NOSPL */
  8012.       case LOGX:            /* SCREEN (stdout) */
  8013.       case LOGE:            /* ERROR  (stderr) */
  8014.         if (x == LOGE) {
  8015.         debug(F110,
  8016.               (cx == XXWRL) ? "WRITELN ERROR" : "WRITE ERROR", s,0);
  8017.         fprintf(stderr,"%s%s",s,(cx == XXWRL) ? "\n" : "");
  8018.         } else {
  8019.         debug(F110,
  8020.               (cx == XXWRL) ? "WRITELN SCREEN" : "WRITE SCREEN", s,0);
  8021.         printf("%s%s",s,(cx == XXWRL) ? "\n" : "");
  8022.         }
  8023.         return(success = 1);
  8024.       default: return(-2);
  8025.     }
  8026.     if (chkfn(y) > 0) {
  8027.         x = (cx == XXWRI) ? zsout(y,s) : zsoutl(y,s);
  8028.         if (x < 0) printf("?Write error\n");
  8029.     } else {
  8030.         x = -1;
  8031.         printf("?File or log not open\n");
  8032.     }
  8033.     return(success = (x == 0) ? 1 : 0);
  8034.     }
  8035. #endif /* NOFRILLS */
  8036.  
  8037. #ifndef NOXFER
  8038.     if (cx == XXASC || cx == XXBIN) {
  8039.     if ((x = cmcfm()) < 0) return(x);
  8040.     binary = (cx == XXASC) ? XYFT_T : XYFT_B;
  8041.     return(success = 1);
  8042.     }
  8043. #endif /* NOXFER */
  8044.  
  8045.     if (cx == XXCLS) {
  8046.     if ((x = cmcfm()) < 0) return(x);
  8047.     y = ck_cls();
  8048.     return(success = (y > -1) ? 1 : 0);
  8049.     }
  8050.  
  8051. #ifdef CK_MKDIR
  8052.     if (cx == XXMKDIR) {
  8053.     char *p;
  8054. #ifdef IKSD
  8055.     if (inserver && !ENABLED(en_mkd)) {
  8056.         printf("?Sorry, directory creation is disabled\n");
  8057.         return(-9);
  8058.     }
  8059. #endif /* IKSD */
  8060.     if ((x = cmfld("Name for new directory","",&s,xxstring)) < 0) {
  8061.         if (x != -3) {
  8062.         return(x);
  8063.         } else {
  8064.         printf("?Directory name required\n");
  8065.         return(-9);
  8066.         }
  8067.     }
  8068.     ckstrncpy(line,s,LINBUFSIZ);
  8069.     s = line;
  8070.     if ((x = cmcfm()) < 0) return(x);
  8071.     s = brstrip(s);
  8072.     x = ckmkdir(0,s,&p,msgflg,0);
  8073. #ifdef COMMENT
  8074.     if (msgflg && x == 0)
  8075.       printf("?Directory already exists\n");
  8076. #endif /* COMMENT */
  8077.     return(success = (x < 0) ? 0 : 1);
  8078.     }
  8079.     if (cx == XXRMDIR) {        /* RMDIR */
  8080.     char *p;
  8081. #ifdef IKSD
  8082.     if (inserver && !ENABLED(en_rmd)) {
  8083.         printf("?Sorry, directory removal is disabled\n");
  8084.         return(-9);
  8085.     }
  8086. #endif /* IKSD */
  8087.     if ((x = cmdir("Name of directory to be removed","",&s,xxstring)) < 0)
  8088.       return(x);
  8089.     ckstrncpy(line,s,LINBUFSIZ);
  8090.     s = line;
  8091.     if ((x = cmcfm()) < 0) return(x);
  8092.     s = brstrip(s);
  8093.     x = ckmkdir(1,s,&p,msgflg,0);
  8094.     return(success = (x < 0) ? 0 : 1);
  8095.     }
  8096. #endif /* CK_MKDIR */
  8097.  
  8098. #ifdef TCPSOCKET
  8099.     if (cx == XXTELOP) {
  8100.         if ((x = cmkey(telcmd, ntelcmd, "TELNET command", "", xxstring)) < 0 )
  8101.       return(x);
  8102.         switch (x) {
  8103.           case WILL:
  8104.           case WONT:
  8105.           case DO:
  8106.           case DONT:
  8107.             if ((y = cmkey(tnopts,ntnopts,"TELNET option","",xxstring)) < 0)
  8108.           return(y);
  8109.             if ((z = cmcfm()) < 0) return(z);
  8110.  
  8111.             switch (x) {
  8112.           case WILL:
  8113.         if (TELOPT_UNANSWERED_WILL(y))
  8114.           return(success = 0);
  8115.         break;
  8116.           case WONT:
  8117.         if (TELOPT_UNANSWERED_WONT(y))
  8118.           return(success = 0);
  8119.         break;
  8120.           case DO:
  8121.         if (TELOPT_UNANSWERED_DO(y))
  8122.           return(success = 0);
  8123.         break;
  8124.           case DONT:
  8125.         if (TELOPT_UNANSWERED_DONT(y))
  8126.           return(success = 0);
  8127.         break;
  8128.             }
  8129.             if (local) {
  8130.         success = ((tn_sopt(x,y) > -1) ? 1 : 0);
  8131.             } else {
  8132.         printf("ff%02x%02x\n",x,y);
  8133.         success = 1;
  8134.             }
  8135.             if (success) {
  8136.         switch (x) {
  8137.           case WILL:
  8138.             TELOPT_UNANSWERED_WILL(y) = 1;
  8139.             break;
  8140.           case WONT:
  8141.             TELOPT_UNANSWERED_WONT(y) = 1;
  8142.             break;
  8143.           case DO:
  8144.             TELOPT_UNANSWERED_DO(y) = 1;
  8145.             break;
  8146.           case DONT:
  8147.             TELOPT_UNANSWERED_DONT(y) = 1;
  8148.             break;
  8149.         }
  8150.         if (tn_wait("XXTELOP") < 0) {
  8151.             tn_push();
  8152.             success = 0;
  8153.         }
  8154.             }
  8155.             return(success);
  8156.           case SB:
  8157.             if ((y=cmkey(tnsbopts,ntnsbopts,"TELNET option","",xxstring)) < 0)
  8158.           return(y);
  8159.             switch (y) {
  8160.           case TELOPT_NAWS:
  8161.         /* Some compilers require switch() to have at least 1 case */
  8162. #ifdef CK_NAWS
  8163.                 TELOPT_SB(TELOPT_NAWS).naws.x = 0;
  8164.                 TELOPT_SB(TELOPT_NAWS).naws.y = 0;
  8165.                 if (local)
  8166.           return(success = ((tn_snaws() > -1) ? 1 : 0));
  8167.                 else
  8168.           return(success = 0);
  8169.                 break;
  8170. #else
  8171.         return(success = 0);
  8172. #endif /* CK_NAWS */
  8173.           default:
  8174.                 return(success = 0);
  8175.             }
  8176.             break;
  8177.       default:
  8178.             if ((z = cmcfm()) < 0) return(z);
  8179.             if (local) {
  8180.                 CHAR temp[3];
  8181.                 if (network && ttnproto == NP_TELNET) { /* TELNET */
  8182.                     temp[0] = (CHAR) IAC;
  8183.                     temp[1] = x;
  8184.                     temp[2] = NUL;
  8185.                     success = (ttol((CHAR *)temp,2) > -1 ? 1 : 0);
  8186.                     if (tn_deb || debses || deblog) {
  8187.                         sprintf(tn_msg,"TELNET SENT %s",TELCMD(x));
  8188.                         debug(F101,tn_msg,"",x);
  8189.                         if (debses || tn_deb) tn_debug(tn_msg);
  8190.                     }
  8191.                     return(success);
  8192.                 }
  8193.             } else {
  8194.                 printf("ff%02x\n",x);
  8195.                 return(success = 1);
  8196.             }
  8197.         }
  8198.     }
  8199. #endif /* TCPSOCKET */
  8200.  
  8201. #ifndef NOPUSH
  8202.     if (cx == XXNPSH) {
  8203.     if ((z = cmcfm()) < 0) return(z);
  8204.         nopush = 1;
  8205. #ifndef NOSERVER
  8206.         en_hos = 0;
  8207. #endif /* NOSERVER */
  8208. #ifdef PIPESEND
  8209.     usepipes = 0;
  8210. #endif /* PIPESEND */
  8211.         return(success = 1);
  8212.     }
  8213. #endif /* NOPUSH */
  8214.  
  8215. #ifndef NOSPL
  8216.     if (cx == XXLOCAL)            /* LOCAL variable declarations */
  8217.       return(success = dolocal());
  8218. #endif /* NOSPL */
  8219.  
  8220.     if (cx == XXKERMI) {        /* The KERMIT command */
  8221.     char * list[65];
  8222.     extern char **xargv;
  8223.     extern int xargc;
  8224.     int i;
  8225.     if ((y = cmtxt("kermit command-line arguments, -h for help",
  8226.                "",&s,xxstring)) < 0)
  8227.       return(y);
  8228.     strcpy(line,"kermit ");
  8229.     strncat(line,s,LINBUFSIZ-8);
  8230.     xwords(line,64,list,0);
  8231.     for (i = 1; i < 64; i++) {
  8232.         if (!list[i])
  8233.           break;
  8234.     }
  8235.     i--;
  8236.     xargc = i;
  8237.     xargv = list;
  8238.     xargv++;
  8239.     sstate = cmdlin();
  8240.     if (sstate) {
  8241.         extern int justone;
  8242.         debug(F000,"KERMIT sstate","",sstate);
  8243.         justone = 1;        /* Force return to command mode */
  8244.         proto();            /* after protocol */
  8245.         return(success);
  8246.     } else {
  8247.         debug(F101,"KERMIT sstate","",sstate);
  8248.         return(success = 1);    /* Not exactly right, but... */
  8249.     }
  8250.     }
  8251.     if (cx == XXDATE) {            /* DATE command */
  8252.     if ((y = cmtxt("date and/or time, or carriage return for current",
  8253.                "",&s,xxstring)) < 0)
  8254.       return(y);
  8255.     s = ckcvtdate(s,1);
  8256.     printf("%s\n",s);
  8257.     return(success = ((int)strcmp(s,"<BAD_DATE>") ? 1 : 0));
  8258.     }
  8259. #ifndef NOPUSH
  8260. #ifndef NOFRILLS
  8261.     if (cx == XXEDIT) {
  8262.     char * p = NULL;
  8263.     if (!editor[0]) {
  8264.         s = getenv("EDITOR");
  8265.         if (s) ckstrncpy(editor,s,CKMAXPATH);
  8266.         editor[CKMAXPATH] = NUL;
  8267.         if (!editor[0]) {
  8268.         printf("?Editor not defined - use SET EDITOR to define\n");
  8269.         return(-9);
  8270.         }
  8271.     }
  8272.     ckstrncpy(tmpbuf,editfile,TMPBUFSIZ);
  8273. /*
  8274.    cmiofi() lets us parse the name of an existing file, or the name of
  8275.    a nonexistent file to be created.
  8276. */
  8277.     x = cmiofi("File to edit", (char *)tmpbuf, &s, &y, xxstring);
  8278.     if (x < 0) {
  8279.         if (x == -9) {
  8280.         if (zchko(s) < 0) {
  8281.             printf("Can't create \"%s\"\n",s);
  8282.             return(x);
  8283.         }
  8284.         } else if (x != -3)
  8285.           return(x);
  8286.     }
  8287.     if (x == -3)
  8288.       tmpbuf[0] = NUL;
  8289.     else {
  8290.         ckstrncpy(tmpbuf,s,TMPBUFSIZ);
  8291.         if (iswild((char *)tmpbuf)) {
  8292.         printf("?A single file please\n");
  8293.         return(-9);
  8294.         }
  8295.     }
  8296.     if ((z = cmcfm()) < 0) return(z);
  8297.     if (nopush) {
  8298.         printf("?Sorry, editing not allowed\n");
  8299.         return(success = 0);
  8300.     }
  8301.     if (tmpbuf[0]) {
  8302.     /* Get full path in case we change directories between EDIT commands */
  8303.         zfnqfp(tmpbuf, CKMAXPATH, editfile);
  8304.         editfile[CKMAXPATH] = NUL;
  8305. #ifdef OS2
  8306.             p = editfile;        /* Flip the stupid slashes */
  8307.             while (*p) {
  8308.                 if (*p == '/') *p = '\\';
  8309.                 p++;
  8310.             }
  8311. #endif /* OS2 */
  8312.     } else
  8313.       editfile[0] = NUL;
  8314.     s = line;
  8315.     x = 0;
  8316.     if (editopts[0]) {
  8317. #ifdef OS2
  8318.         x = ckindex("%1",(char *)editopts,0,0,1);
  8319.         if (x > 0)
  8320.           editopts[x] = 's';
  8321.         else
  8322. #endif /* OS2 */
  8323.           x = ckindex("%s",(char *)editopts,0,0,1);
  8324.     }
  8325.     if (x)
  8326.       sprintf(tmpbuf,editopts,editfile);
  8327.     else
  8328.       sprintf(tmpbuf,"%s %s",editopts,editfile);
  8329.     sprintf(s,"%s %s",editor,tmpbuf);
  8330. #ifdef OS2
  8331.         p = s + strlen(editor);        /* And again with the slashes */
  8332.         while (p != s) {
  8333.             if (*p == '/') *p = '\\';
  8334.             p--;
  8335.         }
  8336. #endif /* OS2 */
  8337.     conres();
  8338.     x = zshcmd(s);
  8339.     concb((char)escape);
  8340.     return(x);
  8341.     }
  8342. #endif /* NOFRILLS */
  8343. #endif /* NOPUSH */
  8344.  
  8345. #ifdef BROWSER                /* Defined only ifndef NOPUSH */
  8346.     if (cx == XXBROWS) {
  8347. #ifdef OS2
  8348.         char * p = NULL;
  8349. #endif /* OS2 */
  8350.     if (nopush) {
  8351.         printf("?Sorry, browsing not allowed\n");
  8352.         return(success = 0);
  8353.     }
  8354. #ifndef NT
  8355.         /* Windows lets the Shell Execute the URL if no Browser is defined */
  8356.     if (!browser[0]) {
  8357.         s = getenv("BROWSER");
  8358.         if (s) ckstrncpy(browser,s,CKMAXPATH);
  8359.         browser[CKMAXPATH] = NUL;
  8360.         if (!browser[0]) {
  8361.         printf("?Browser not defined - use SET BROWSER to define\n");
  8362.         return(-9);
  8363.         }
  8364.     }
  8365. #endif /* NT */
  8366.     ckstrncpy(tmpbuf,browsurl,TMPBUFSIZ);
  8367.     if ((x = cmtxt("URL",(char *)browsurl,&s,xxstring)) < 0)
  8368.       return(x);
  8369.     ckstrncpy(browsurl,s,4096);
  8370.     s = line;
  8371.  
  8372.     x = 0;
  8373.     if (browsopts[0]) {
  8374. #ifdef OS2
  8375.         x = ckindex("%1",(char *)browsopts,0,0,1);
  8376.         if (x > 0)
  8377.           browsopts[x] = 's';
  8378.         else
  8379. #endif /* OS2 */
  8380.           x = ckindex("%s",(char *)browsopts,0,0,1);
  8381.     }
  8382.     if (x)
  8383.       sprintf(tmpbuf,browsopts,browsurl);
  8384.     else
  8385.       sprintf(tmpbuf,"%s %s",browsopts,browsurl);
  8386. #ifdef NT
  8387.         if ( !browser[0] ) {
  8388.             return(success = Win32ShellExecute( browsurl ));
  8389.         }
  8390. #endif /* NT */
  8391.     sprintf(s,"%s %s",browser,tmpbuf);
  8392. #ifdef OS2
  8393.         p = line + strlen(browser);    /* Flip slashes */
  8394.         while (p != line) {
  8395.             if (*p == '/') *p = '\\';
  8396.             p--;
  8397.         }
  8398. #endif /* OS2 */
  8399.     conres();
  8400.     x = zshcmd(s);
  8401.     concb((char)escape);
  8402.     return(x);
  8403.     }
  8404. #endif /* BROWSER */
  8405.  
  8406. #ifdef CK_TAPI
  8407.     if (cx == XXTAPI) {            /* Microsoft TAPI */
  8408.     return (success = dotapi());
  8409.     }
  8410. #endif /* CK_TAPI */
  8411.  
  8412. #ifndef NOXFER
  8413.     if (cx == XXWHERE) {
  8414.     extern char * rfspec, * sfspec, * srfspec, * rrfspec;
  8415.     if ((x = cmcfm()) < 0) return(x);
  8416.     printf("\nFile most recently...\n\n");
  8417.     printf("  Sent:       %s\n",   sfspec ? sfspec : "(none)");
  8418.     if (sfspec && srfspec) {
  8419.         printf("  Stored as:  %s\n",   srfspec);
  8420.         printf("\n");
  8421.     }
  8422.     printf("  Received:   %s\n",   rrfspec ? rrfspec : "(none)");
  8423.     if (rfspec && rrfspec)
  8424.     printf("  Stored as:  %s\n",   rfspec);
  8425.     printf(
  8426. "\nIf the full path is not shown, then the file is probably in your current\n"
  8427.            );
  8428.     printf(
  8429. "directory or your download directory (if any - SHOW FILE to find out).\n\n"
  8430.            );
  8431.     return(success = 1);
  8432.     }
  8433. #endif /* NOXFER */
  8434.  
  8435. #ifdef CK_RECALL
  8436.     if (cx == XXREDO) {            /* Find a previous cmd and redo it */
  8437.     extern int on_recall, in_recall;
  8438.     int x;
  8439.     char * p;
  8440.  
  8441.     if ((x = cmtxt(
  8442. "pattern, or first few characters of a previous command",
  8443.                "*",&s,xxstring)) < 0)
  8444.       return(x);
  8445.     ckstrncpy(line,s,LINBUFSIZ);
  8446.     x = strlen(s);
  8447.     s = line;
  8448.     if (*s == '{') {        /* Braces disable adding * to end */
  8449.         if (s[x-1] == '}') {
  8450.         s[x-1] = NUL;
  8451.         s++;
  8452.         x--;
  8453.         }
  8454.     } else {            /* No braces, add * to end. */
  8455.         s[x] = '*';
  8456.         s[x+1] = NUL;
  8457.     }
  8458.  
  8459.     while (x > 0 && s[x] == '*' && s[x-1] == '*') s[x--] = NUL;
  8460.  
  8461.     if (!on_recall || !in_recall) {
  8462.         printf("?Sorry, command recall can't be used now.\n");
  8463.         return(-9);
  8464.     }
  8465.     if (p = cmgetcmd(s)) {        /* Look for it history buffer */
  8466.         sprintf(cmdbuf,"%s%c",p,'\r'); /* Found - copy to command buffer */
  8467.         cmaddnext();        /* Force re-add to history buffer */
  8468.         return(cmflgs = -1);    /* Force reparse */
  8469.     } else {
  8470.         printf("?Sorry - \"%s\" not found\n", s);
  8471.         return(-9);
  8472.     }
  8473.     }
  8474. #endif /* CK_RECALL */
  8475.  
  8476. /* This is useless unless user is root.  Too bad, it's just what we need. */
  8477.  
  8478. #ifdef COMMENT
  8479.     if (cx == XXCHRT) {            /* Change root directory */
  8480. #ifdef UNIX
  8481.     if ((x = cmdir("Name of new root directory","",&s,xxstring)) < 0)
  8482.       return(x);
  8483.     ckstrncpy(line,s,LINBUFSIZ);
  8484.     s = line;
  8485.     if ((x = cmcfm()) < 0) return(x);
  8486.     s = brstrip(s);
  8487.     priv_on();            /* This doesn't work if setuid root */
  8488.     x = chroot(s);            /* See priv_ini() in ckutio.c. */
  8489.     priv_off();
  8490.     if (x) {
  8491.         printf("Error %d\n",errno);    /* 1 = EPERM (i.e. "not root") */
  8492.         perror("chroot");
  8493.         return(success = 0);
  8494.     }
  8495.     return(success = zchdir(s));
  8496. #else
  8497.     printf("?Sorry, not implemented\n");
  8498.     return(-9);
  8499. #endif /* UNIX */
  8500.     }
  8501. #endif /* COMMENT */
  8502.  
  8503. #ifdef CK_KERBEROS
  8504.     if (cx == XXAUTH) {            /* KERBEROS */
  8505.     x = cp_auth();            /* Parse it */
  8506.     if (x < 0)            /* Pass parse errors back */
  8507.       return(x);
  8508. #ifdef IKSD
  8509.         if (inserver) {
  8510.             printf("?Command disabled in IKSD.\r\n");
  8511.             return(success = 0);
  8512.         }
  8513. #endif /* IKSD */
  8514.     return(success = doauth(cx));
  8515.     }
  8516. #endif /* CK_KERBEROS */
  8517.  
  8518. #ifndef NOLOCAL
  8519.     if (cx == XXTERM) {
  8520.     return(settrmtyp());
  8521.     }
  8522. #endif /* NOLOCAL */
  8523.  
  8524.     if (cx == XXSTATUS) {
  8525.     if ((x = cmcfm()) < 0) return(x);
  8526.     printf( " %s\n", success ? "SUCCESS" : "FAILURE" );
  8527.     return(0);            /* Don't change it */
  8528.     }
  8529.  
  8530.     if (cx == XXFAIL) {
  8531.     if ((x = cmcfm()) < 0) return(x);
  8532.     return(success = 0);
  8533.     }
  8534.  
  8535.     if (cx == XXSUCC) {
  8536.     if ((x = cmcfm()) < 0) return(x);
  8537.     return(success = 1);
  8538.     }
  8539.  
  8540.     if (cx == XXNLCL) {
  8541.     extern int nolocal;
  8542.     if ((x = cmcfm()) < 0) return(x);
  8543.     nolocal = 1;
  8544.     return(success = 1);
  8545.     }
  8546.  
  8547. #ifndef NOXFER
  8548.     if (cx == XXRASG)            /* Shortcuts for REMOTE commands */
  8549.       return(dormt(XZASG));
  8550.     if (cx == XXRCWD)
  8551.       return(dormt(XZCWD));
  8552.     if (cx == XXRCPY)
  8553.       return(dormt(XZCPY));
  8554.     if (cx == XXRDEL)
  8555.       return(dormt(XZDEL));
  8556.     if (cx == XXRDIR)
  8557.       return(dormt(XZDIR));
  8558.     if (cx == XXRXIT)
  8559.       return(dormt(XZXIT));
  8560.     if (cx == XXRHLP)
  8561.       return(dormt(XZHLP));
  8562.     if (cx == XXRHOS)
  8563.       return(dormt(XZHOS));
  8564.     if (cx == XXRKER)
  8565.       return(dormt(XZKER));
  8566.     if (cx == XXRPWD)
  8567.       return(dormt(XZPWD));
  8568.     if (cx == XXRQUE)
  8569.       return(dormt(XZQUE));
  8570.     if (cx == XXRREN)
  8571.       return(dormt(XZREN));
  8572.     if (cx == XXRMKD)
  8573.       return(dormt(XZMKD));
  8574.     if (cx == XXRRMD)
  8575.       return(dormt(XZRMD));
  8576.     if (cx == XXRSET)
  8577.       return(dormt(XZSET));
  8578.     if (cx == XXRSPA)
  8579.       return(dormt(XZSPA));
  8580.     if (cx == XXRTYP)
  8581.       return(dormt(XZTYP));
  8582.     if (cx == XXRWHO)
  8583.       return(dormt(XZWHO));
  8584. #endif /* NOXFER */
  8585.  
  8586.     if (cx == XXRESET) {        /* RESET */
  8587.     if ((x = cmcfm()) < 0)
  8588.       return(x);
  8589.     doclean(0);            /* Close all files */
  8590.     return(success = 1);
  8591.     }
  8592.  
  8593. #ifndef NOXFER
  8594. #ifndef NOCSETS
  8595.     if (cx == XXASSOC) {        /* ASSOCIATE */
  8596.     extern struct keytab tcstab[];
  8597.     extern int ntcs;
  8598.         if ((x = cmkey(assoctab, nassoc, "", "", xxstring)) < 0 )
  8599.       return(x);
  8600.  
  8601.     switch (x) {            /* Associate what? */
  8602.  
  8603.       case ASSOC_TC:        /* Transfer character-set... */
  8604.         if ((x = cmkey(tcstab, ntcs,
  8605.                "transfer character-set name","",xxstring)) < 0)
  8606.           return(x);
  8607.         if ((y = cmkey(fcstab, nfilc,
  8608.                "with file character-set","", xxstring)) < 0)
  8609.           if (y != -3)
  8610.         return(y);
  8611.         if ((z = cmcfm()) < 0)
  8612.           return(z);
  8613.         axcset[x] = y;
  8614.         return(success = 1);
  8615.  
  8616.       case ASSOC_FC:        /* File character-set... */
  8617.         if ((x = cmkey(fcstab, nfilc,
  8618.                "file character-set name","",xxstring)) < 0)
  8619.           return(x);
  8620.         if ((y = cmkey(tcstab, ntcs,
  8621.                "with transfer character-set","", xxstring)) < 0)
  8622.           if (y != -3)
  8623.         return(y);
  8624.         if ((z = cmcfm()) < 0)
  8625.           return(z);
  8626.         afcset[x] = y;
  8627.         return(success = 1);
  8628.  
  8629.       default:
  8630.         return(-2);
  8631.     }
  8632.     }
  8633. #endif /* NOCSETS */
  8634. #endif /* NOXFER */
  8635.  
  8636. #ifndef NOSPL
  8637.     if (cx == XXSHIFT) {        /* SHIFT */
  8638.     if ((y = cmnum("Number of arguments to shift","1",10,&x,xxstring)) < 0)
  8639.       return(y);
  8640.     if ((z = cmcfm()) < 0)
  8641.       return(z);
  8642.     return(success = doshift(x));
  8643.     }
  8644. #endif /* NOSPL */
  8645.  
  8646. #ifndef NOHELP
  8647.     if (cx == XXMAN) {
  8648. #ifdef OS2
  8649.     if ((x = cmcfm()) < 0)
  8650.       return(x);
  8651.     if (nopush) {
  8652.         printf("?Sorry, access to system commands is disabled.\n");
  8653.         return(-9);
  8654.     }
  8655.         y = mxlook(mactab,"manual",nmac);
  8656.         if (y > -1) {
  8657.             z = maclvl;            /* save the current maclvl */
  8658.             dodo(y,NULL,cmdstk[cmdlvl].ccflgs);    /* Run the macro */
  8659.             while (maclvl > z) {
  8660.                 debug(F101,"XXMAN loop maclvl 1","",maclvl);
  8661.                 sstate = (CHAR) parser(1);
  8662.                 debug(F101,"XXMAN loop maclvl 2","",maclvl);
  8663.                 if (sstate) proto();
  8664.             }
  8665.             debug(F101,"XXMAN loop exit maclvl","",maclvl);
  8666.             return(success);
  8667.         }
  8668.         return(success = 0);
  8669. #else
  8670.     if ((x = cmtxt(
  8671. #ifdef UNIX
  8672.             "Carriage return to confirm the command, or manual topic",
  8673. #else
  8674.             "Carriage return to confirm the command, or help topic",
  8675. #endif /* UNIX */
  8676.                "kermit",
  8677.                &s,
  8678.                xxstring
  8679.                )
  8680.          ) < 0)
  8681.       return(x);
  8682. #endif /* OS2 */
  8683.  
  8684. #ifdef UNIX
  8685.     sprintf(tmpbuf,"man %s",s);
  8686. #else
  8687.     sprintf(tmpbuf,"help %s",s);
  8688. #endif /* UNIX */
  8689.     debug(F110,"MANUAL",tmpbuf,0);
  8690.     if (nopush) {
  8691.         printf("?Sorry, access to system commands is disabled.\n");
  8692.         return(-9);
  8693.     } else {
  8694.         conres();            /* Restore the console */
  8695.         success = zshcmd(tmpbuf);
  8696.         concb((char)escape);    /* Restore CBREAK mode */
  8697.         return(success);
  8698.     }
  8699.     }
  8700. #endif /* NOHELP */
  8701.  
  8702. #ifndef NOSPL
  8703.     if (cx == XXSORT)            /* SORT an array */
  8704.       return(dosort());
  8705. #endif /* NOSPL */
  8706.  
  8707.     if (cx == XXPURGE) {
  8708. #ifdef IKSD
  8709.     if (inserver && (!ENABLED(en_del)
  8710. #ifdef CK_LOGIN
  8711.                           || isguest
  8712. #endif /* CK_LOGIN */
  8713.              )) {
  8714.         printf("?Sorry, DELETE is disabled\n");
  8715.         return(-9);
  8716.     }
  8717. #endif /* IKSD */
  8718. #ifdef CK_APC
  8719.     if (apcactive == APC_LOCAL ||
  8720.         apcactive == APC_REMOTE && apcstatus != APC_UNCH) return(success = 0);
  8721. #endif /* CK_APC */
  8722. #ifdef CKPURGE
  8723.         return(dopurge());
  8724. #else
  8725. #ifdef VMS
  8726.     if ((x = cmtxt("optional switches followed by filespec",
  8727.                "",&s,xxstring)) < 0)
  8728.       return(x);
  8729.     if (nopush) {
  8730.         printf("?Sorry, DCL access is disabled\n");
  8731.         return(-9);
  8732.     }
  8733.     ckstrncpy(line,s,LINBUFSIZ);
  8734.     s = line;
  8735.     x = mlook(mactab,"purge",nmac);
  8736.     return(success = dodo(x,s,cmdstk[cmdlvl].ccflgs));
  8737. #else
  8738.     return(-2);
  8739. #endif /* VMS */
  8740. #endif /* CKPURGE */
  8741.     }
  8742.  
  8743. #ifndef NOSPL
  8744.     if (cx == XXFAST) {
  8745.     if ((x = cmcfm()) < 0) return(x);
  8746.     x = mlook(mactab,"fast",nmac);
  8747.     return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
  8748.     }
  8749.     if (cx == XXCAU) {
  8750.     if ((x = cmcfm()) < 0) return(x);
  8751.     x = mlook(mactab,"cautious",nmac);
  8752.     return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
  8753.     }
  8754.     if (cx == XXROB) {
  8755.     if ((x = cmcfm()) < 0) return(x);
  8756.     x = mlook(mactab,"robust",nmac);
  8757.     return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
  8758.     }
  8759. #endif /* NOSPL */
  8760.  
  8761.     if (cx == XXSCRN) {            /* SCREEN */
  8762.     int row, col;
  8763.     if ((x = cmkey(scntab, nscntab,"screen action","", xxstring)) < 0)
  8764.       return(x);
  8765.     switch (x) {            /* MOVE-TO (cursor position) */
  8766.       case SCN_MOV:
  8767.         if ((y = cmnum("Row (1-based)","",10,&z,xxstring)) < 0)
  8768.           return(y);
  8769.         row = z;
  8770.         y = cmnum("Column (1-based)","1",10,&z,xxstring);
  8771.         if (y < 0)
  8772.           return(y);
  8773.         col = z;
  8774.         if ((y = cmcfm()) < 0)
  8775.           return(y);
  8776.         if (row < 0 || col < 0) {
  8777.         printf("?Row and Column must be 1 or greater\n");
  8778.         return(-9);
  8779.         }
  8780.         if (cmd_rows > 0 && row > cmd_rows)
  8781.           row = cmd_rows;
  8782.         if (cmd_cols > 0 && col > cmd_cols)
  8783.           col = cmd_cols;
  8784.         y = ck_curpos(row,col);
  8785.         return(success = (y > -1) ? 1 : 0);
  8786.  
  8787.       case SCN_CLR:            /* CLEAR */
  8788.         if ((y = cmcfm()) < 0)
  8789.           return(y);
  8790.         debug(F100,"screen calling ck_cls()","",0);
  8791.         y = ck_cls();
  8792.         return(success = (y > -1) ? 1 : 0);
  8793.  
  8794.       case SCN_CLE:            /* CLEOL */
  8795.         if ((y = cmcfm()) < 0)
  8796.           return(y);
  8797.         y = ck_cleol();
  8798.         return(success = (y > -1) ? 1 : 0);
  8799.     }
  8800.     }
  8801.  
  8802. #ifndef NOHTTP
  8803. #ifdef TCPSOCKET
  8804.     if (cx == XXHTTP) {            /* HTTP */
  8805.     struct FDB sw, kw, fi;
  8806.     int n, getval;
  8807.     char c, * p;
  8808.  
  8809.     char * http_agent = NULL;    /* Parse results */
  8810.     char * http_hdr   = NULL;
  8811.     char * http_user  = NULL;
  8812.     char * http_pass  = NULL;
  8813.     char * http_mime  = NULL;
  8814.     char * http_lfile = NULL;
  8815.     char * http_rfile = NULL;
  8816.     char http_array = NUL;
  8817.     int http_action = -1;
  8818.  
  8819. #ifdef OS2
  8820.     p = "Kermit 95";        /* Default user agent */
  8821. #else
  8822.     p = "C-Kermit";
  8823. #endif /* OS2 */
  8824.     makestr(&http_agent,p);
  8825.     makestr(&http_mime,"text/HTML"); /* MIME type default */
  8826.  
  8827.     cmfdbi(&sw,            /* 1st FDB - general switches */
  8828.        _CMKEY,            /* fcode */
  8829.        "GET, HEAD, PUT, INDEX, or POST,\n or switch", /* hlpmsg */
  8830.        "",                /* default */
  8831.        "",                /* addtl string data */
  8832.        nhttpswtab,            /* addtl numeric data 1: tbl size */
  8833.        4,                /* addtl numeric data 2: 4 = cmswi */
  8834.        xxstring,            /* Processing function */
  8835.        httpswtab,            /* Keyword table */
  8836.        &kw                /* Pointer to next FDB */
  8837.        );
  8838.     cmfdbi(&kw,            /* 2nd FDB - commands */
  8839.        _CMKEY,            /* fcode */
  8840.        "Command",            /* hlpmsg */
  8841.        "",                /* default */
  8842.        "",                /* addtl string data */
  8843.        nhttptab,            /* addtl numeric data 1: tbl size */
  8844.        0,                /* addtl numeric data 2: 0 = keyword */
  8845.        xxstring,            /* Processing function */
  8846.        httptab,            /* Keyword table */
  8847.        NULL                /* Pointer to next FDB */
  8848.        );
  8849.  
  8850.     while (1) {
  8851.         x = cmfdb(&sw);        /* Parse something */
  8852.         if (x < 0)            /* Error */
  8853.           goto xhttp;
  8854.         n = cmresult.nresult;
  8855.         if (cmresult.fdbaddr == &kw) /* Command - exit this loop */
  8856.           break;
  8857.         c = cmgbrk();        /* Switch... */
  8858.         getval = (c == ':' || c == '=');
  8859.         if (getval && !(cmgkwflgs() & CM_ARG)) {
  8860.         printf("?This switch does not take an argument\n");
  8861.         x = -9;
  8862.         goto xhttp;
  8863.         }
  8864.         switch (cmresult.nresult) {    /* Handle each switch */
  8865.           case HT_SW_AG:        /* /AGENT */
  8866.         if (getval) {
  8867.             if ((x = cmfld("User agent",p,&s,xxstring)) < 0)
  8868.               goto xhttp;
  8869.         } else
  8870.           s = p;
  8871.         makestr(&http_agent,s);
  8872.         break;
  8873.           case HT_SW_HD:        /* /HEADER */
  8874.         s = NULL;
  8875.         if (getval) {
  8876.             if ((x = cmfld("Header line","",&s,xxstring)) < 0) {
  8877.             if (x == -3)
  8878.               s = NULL;
  8879.             else
  8880.               goto xhttp;
  8881.             }
  8882.         }
  8883.         makestr(&http_hdr,s);
  8884.         break;
  8885.           case HT_SW_US:        /* /USER */
  8886.         s = NULL;
  8887.         if (getval) {
  8888.             if ((x = cmfld("User ID","",&s,xxstring)) < 0)
  8889.               goto xhttp;
  8890.         }
  8891.         makestr(&http_user,s);
  8892.         break;
  8893.           case HT_SW_PW:        /* /PASSWORD */
  8894.         s = NULL;
  8895.         if (getval) {
  8896.             if ((x = cmfld("Password","",&s,xxstring)) < 0)
  8897.               goto xhttp;
  8898.         }
  8899.         makestr(&http_pass,s);
  8900.         break;
  8901. #ifndef NOSPL
  8902.           case HT_SW_AR: {        /* /ARRAY: */
  8903.           char * s2, array = NUL;
  8904.           if (!getval) {
  8905.               printf("?This switch requires an argument\n");
  8906.               x = -9;
  8907.               goto xhttp;
  8908.           }
  8909.           if ((x = cmfld("Array name (a single letter will do)",
  8910.                  "",
  8911.                  &s,
  8912.                  NULL
  8913.                  )) < 0) {
  8914.               if (x == -3) {
  8915.               printf("?Array name required\n");
  8916.               x = -9;
  8917.               goto xhttp;
  8918.               } else
  8919.             goto xhttp;
  8920.           }
  8921.           if (!*s) {
  8922.               printf("?Array name required\n");
  8923.               x = -9;
  8924.               goto xhttp;
  8925.           }
  8926.           s2 = s;
  8927.           if (*s == CMDQ) s++;
  8928.           if (*s == '&') s++;
  8929.           if (!isalpha(*s)) {
  8930.               printf("?Bad array name - \"%s\"\n",s2);
  8931.               x = -9;
  8932.               goto xhttp;
  8933.           }
  8934.           array = *s++;
  8935.           if (isupper(array))
  8936.             array = tolower(array);
  8937.           if (*s && (*s != '[' || *(s+1) != ']')) {
  8938.               printf("?Bad array name - \"%s\"\n",s2);
  8939.               http_array = NUL;
  8940.               x = -9;
  8941.               goto xhttp;
  8942.           }
  8943.           http_array = array;
  8944.           break;
  8945.           }
  8946. #endif /* NOSPL */
  8947.           default:
  8948.         x = -2;
  8949.         goto xhttp;
  8950.         }
  8951.     }
  8952.     http_action = n;        /* Save the action */
  8953.     if (http_action == HTTP_PUT || http_action == HTTP_POS) {
  8954.         cmfdbi(&sw,            /* 1st FDB - switch */
  8955.            _CMKEY,        /* fcode */
  8956.            "Local filename\n Or switch", /* help */
  8957.            "",            /* default */
  8958.            "",            /* addtl string data */
  8959.            nhttpptab,        /* keyword table size */
  8960.            4,            /* addtl numeric data 2: 4 = cmswi */
  8961.            xxstring,        /* Processing function */
  8962.            httpptab,        /* Keyword table */
  8963.            &fi            /* Pointer to next FDB */
  8964.            );
  8965.         cmfdbi(&fi,            /* 2nd FDB - filename */
  8966.            _CMIFI,        /* fcode */
  8967.            "Local filename",    /* hlpmsg */
  8968.            "",            /* default */
  8969.            "",            /* addtl string data */
  8970.            0,            /* addtl numeric data 1 */
  8971.            0,            /* addtl numeric data 2 */
  8972.            xxstring,
  8973.            NULL,
  8974.            NULL
  8975.            );
  8976.         while (1) {
  8977.         x = cmfdb(&sw);
  8978.         if (x < 0)
  8979.           goto xhttp;        /* Free any malloc'd temp strings */
  8980.         n = cmresult.nresult;
  8981.         if (cmresult.fcode != _CMKEY)
  8982.           break;
  8983.         c = cmgbrk();        /* Switch... */
  8984.         getval = (c == ':' || c == '=');
  8985.         if (getval && !(cmgkwflgs() & CM_ARG)) {
  8986.             printf("?This switch does not take an argument\n");
  8987.             x = -9;
  8988.             goto xhttp;
  8989.         }
  8990.         switch (n) {
  8991.           case HT_PP_MT:
  8992.             s = "text/HTML";
  8993.             if (getval) {
  8994.             if ((x = cmfld("MIME type",
  8995.                        "text/HTML",&s,xxstring)) < 0)
  8996.               goto xhttp;
  8997.             }
  8998.             makestr(&http_mime,s);
  8999.             break;
  9000.           default:
  9001.             x = -2;
  9002.             goto xhttp;
  9003.         }
  9004.         }
  9005.         makestr(&http_lfile,cmresult.sresult);
  9006.         if ((x = cmtxt("Remote filename","",&s,xxstring)) < 0)
  9007.           goto xhttp;
  9008.         if (!*s) s = http_lfile;
  9009.         makestr(&http_rfile,s);
  9010.     }
  9011.     switch (http_action) {
  9012.           case HTTP_DEL:                /* DELETE */
  9013.         if ((x = cmfld("Remote source file","",&s,xxstring)) < 0)
  9014.           goto xhttp;
  9015.         makestr(&http_rfile,s);
  9016.             break;
  9017.           case HTTP_HED:                /* HEAD */
  9018.               if ((x = cmfld("Remote source file","",&s,xxstring)) < 0)
  9019.                 goto xhttp;
  9020.               makestr(&http_rfile,s);
  9021.  
  9022.               n = ckindex("/",http_rfile,-1,1,0);
  9023.               if ( n )
  9024.                   p = &http_rfile[n];
  9025.               else
  9026.                   p = http_rfile;
  9027.               if ((x = cmofi("Local filename",p,&s,xxstring)) < 0)
  9028.                 goto xhttp;
  9029.               makestr(&http_lfile,s);
  9030.               break;
  9031.           case HTTP_GET:        /* GET */
  9032.           case HTTP_IDX:                /* INDEX */
  9033.         if ((x = cmfld("Remote source file","",&s,xxstring)) < 0)
  9034.           goto xhttp;
  9035.         makestr(&http_rfile,s);
  9036.         if ((x = cmofi("Local filename","",&s,xxstring)) < 0)
  9037.               if (x != -3)
  9038.                 goto xhttp;
  9039.         makestr(&http_lfile,s);
  9040.         break;
  9041.     }
  9042.     if ((x = cmcfm()) < 0)
  9043.       goto xhttp;
  9044.  
  9045.     x = dohttp(http_action,
  9046.            http_lfile,
  9047.            http_rfile,
  9048.            http_agent,
  9049.            http_hdr,
  9050.            http_user,
  9051.            http_pass,
  9052.            http_mime,
  9053.            http_array
  9054.            );
  9055.       xhttp:
  9056.     if (http_agent) free(http_agent);
  9057.     if (http_hdr)   free(http_hdr);
  9058.     if (http_user)  free(http_user);
  9059.     if (http_pass)  free(http_pass);
  9060.     if (http_mime)  free(http_mime);
  9061.     if (http_lfile) free(http_lfile);
  9062.     if (http_rfile) free(http_rfile);
  9063.     if (x > -1)
  9064.       success = x;
  9065.     return(x);
  9066.     }
  9067. #endif /* TCPSOCKET */
  9068. #endif /* NOHTTP */
  9069.  
  9070. #ifndef NOSPL
  9071.     if (cx == XXARRAY) {        /* ARRAY */
  9072. #ifndef NOSHOW
  9073.     extern int showarray();
  9074. #endif /* NOSHOW */
  9075.     if ((x = cmkey(arraytab, narraytab,"Array operation","",xxstring)) < 0)
  9076.       return(x);
  9077.     switch (x) {
  9078.       case ARR_DCL:
  9079.         return(dodcl());
  9080.       case ARR_SRT:
  9081.         return(dosort());
  9082. #ifndef NOSHOW
  9083.       case ARR_SHO:
  9084.         return(showarray());
  9085. #endif /* NOSHOW */
  9086.       case ARR_CPY:
  9087.         return(copyarray());
  9088.       case ARR_SET:
  9089.       case ARR_CLR:
  9090.         return(clrarray(x));
  9091.       case ARR_DST:
  9092.         return(unarray());
  9093.       case ARR_RSZ:
  9094.         return(rszarray());
  9095.       default:
  9096.         printf("?Sorry, not implemented yet - \"%s\"\n",cmdbuf);
  9097.         return(-9);
  9098.     }
  9099.     }
  9100.     if (cx == XXTRACE) {
  9101.     int on = 1;
  9102.     struct FDB sw, kw;
  9103.     cmfdbi(&sw,            /* 1st FDB - switch */
  9104.            _CMKEY,            /* fcode */
  9105.            "Trace object;\n Or switch", /* help */
  9106.            "",            /* default */
  9107.            "",            /* addtl string data */
  9108.            2,            /* keyword table size */
  9109.            4,            /* addtl numeric data 2: 4 = cmswi */
  9110.            xxstring,        /* Processing function */
  9111.            onoffsw,            /* Keyword table */
  9112.            &kw            /* Pointer to next FDB */
  9113.            );
  9114.     cmfdbi(&kw,            /* 2nd FDB - Trace object */
  9115.            _CMKEY,            /* fcode */
  9116.            "Trace object",        /* help */
  9117.            "all",            /* default */
  9118.            "",            /* addtl string data */
  9119.            ntracetab,        /* keyword table size */
  9120.            0,            /* addtl numeric data 2: 0 = keyword */
  9121.            xxstring,        /* Processing function */
  9122.            tracetab,        /* Keyword table */
  9123.            NULL            /* Pointer to next FDB */
  9124.            );
  9125.     if ((x = cmfdb(&sw)) < 0)
  9126.       return(x);
  9127.     if (cmresult.fdbaddr == &sw) {
  9128.         on = cmresult.nresult;
  9129.         if ((x = cmkey(tracetab, ntracetab,"","all",xxstring)) < 0)
  9130.           return(x);
  9131.     } else {
  9132.         x = cmresult.nresult;
  9133.     }
  9134.     if ((y = cmcfm()) < 0)
  9135.       return(y);
  9136.  
  9137.     switch (x) {
  9138.       case TRA_ASG:
  9139.         tra_asg = on;
  9140.         break;
  9141.       case TRA_CMD:
  9142.         tra_cmd = on;
  9143.         break;
  9144.       case TRA_ALL:
  9145.         tra_asg = on;
  9146.         tra_cmd = on;
  9147.         break;
  9148.       default:
  9149.         return(-2);
  9150.     }
  9151.     printf("TRACE %s\n", on ? "ON" : "OFF");
  9152.     return(success = 1);
  9153.     }
  9154.  
  9155.     if (cx == XXNOTAV) {        /* Command in table not available */
  9156.     ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ);
  9157.     if ((x = cmtxt("Rest of command","",&s,NULL)) < 0)
  9158.       return(x);
  9159.     printf("Sorry, \"%s\" not configured in this version of Kermit.\n",
  9160.            tmpbuf
  9161.            );
  9162.     return(success = 0);
  9163.     }
  9164. #endif /* NOSPL */
  9165.  
  9166.     return(-2);                /* None of the above */
  9167.  
  9168. } /* end of docmd() */
  9169.  
  9170. #endif /* NOICP */
  9171.