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

  1. #include "ckcsym.h"
  2. char *userv = "User Interface 6.0.177, 6 Sep 96";
  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, 1996, Trustees of Columbia University in the City of New
  11.   York.  The C-Kermit software may not be, in whole or in part, licensed or
  12.   sold for profit as a software product itself, nor may it be included in or
  13.   distributed with commercial products or otherwise distributed by commercial
  14.   concerns to their clients or customers without written permission of the
  15.   Office of Kermit Development and Distribution, Columbia University.  This
  16.   copyright notice must not be removed, altered, or obscured.
  17. */
  18.  
  19. /*
  20.   NOTE: Because of the massive additions in functionality, and therefore
  21.   the increase in the number of commands, much code was moved from here to
  22.   the two new modules, ckuus4.c and ckuus5.c.  This module now contains only
  23.   the top-level command keyword table, the SET command keyword table, and
  24.   the top-level interactive command parser/dispatcher.  ckuus3.c contains the
  25.   rest of the SET and REMOTE command parsers; ckuus2.c contains the help
  26.   command parser and help text strings, and ckuus4.c and ckuus5.c contain
  27.   miscellaneous pieces that logically belong in the ckuusr.c file but had to
  28.   be moved because of size problems with some C compilers / linkers.
  29.   Later...  as the other modules became too large, a ckuus6.c was created.
  30.   Still later...  ckuus7.c.
  31.   Also: ckuusy.c contains the UNIX-style command-line interface;
  32.   ckuusx.c contains routines needed by both the command-line interface and
  33.   the interactive command parser.
  34. */
  35.  
  36. /*
  37.  The ckuus*.c modules depend on the existence of C library features like fopen,
  38.  fgets, feof, (f)printf, argv/argc, etc.  Other functions that are likely to
  39.  vary among Unix implementations -- like setting terminal modes or interrupts
  40.  -- are invoked via calls to functions that are defined in the system-
  41.  dependent modules, ck?[ft]io.c.  The command line parser processes any
  42.  arguments found on the command line, as passed to main() via argv/argc.  The
  43.  interactive parser uses the facilities of the cmd package (developed for this
  44.  program, but usable by any program).  Any command parser may be substituted
  45.  for this one.  The only requirements for the Kermit command parser are these:
  46.  
  47. 1. Set parameters via global variables like duplex, speed, ttname, etc.  See
  48.    ckmain.c for the declarations and descriptions of these variables.
  49.  
  50. 2. If a command can be executed without the use of Kermit protocol, then
  51.    execute the command directly and set the variable sstate to 0. Examples
  52.    include 'set' commands, local directory listings, the 'connect' command.
  53.  
  54. 3. If a command requires the Kermit protocol, set the following variables:
  55.  
  56.     sstate                             string data
  57.       'x' (enter server mode)            (none)
  58.       'r' (send a 'get' command)         cmarg, cmarg2
  59.       'v' (enter receive mode)           cmarg2
  60.       'g' (send a generic command)       cmarg
  61.       's' (send files)                   nfils, cmarg & cmarg2 OR cmlist
  62.       'c' (send a remote host command)   cmarg
  63.  
  64.     cmlist is an array of pointers to strings.
  65.     cmarg, cmarg2 are pointers to strings.
  66.     nfils is an integer.
  67.  
  68.     cmarg can be a filename string (possibly wild), or
  69.        a pointer to a prefabricated generic command string, or
  70.        a pointer to a host command string.
  71.     cmarg2 is the name to send a single file under, or
  72.        the name under which to store an incoming file; must not be wild.
  73.        If it's the name for receiving, a null value means to store the
  74.        file under the name it arrives with.
  75.     cmlist is a list of nonwild filenames, such as passed via argv.
  76.     nfils is an integer, interpreted as follows:
  77.       -1: filespec (possibly wild) in cmarg, must be expanded internally.
  78.        0: send from stdin (standard input).
  79.       >0: number of files to send, from cmlist.
  80.  
  81.  The screen() function is used to update the screen during file transfer.
  82.  The tlog() function writes to a transaction log.
  83.  The debug() function writes to a debugging log.
  84.  The intmsg() and chkint() functions provide the user i/o for interrupting
  85.    file transfers.
  86. */
  87.  
  88. #ifndef NOICP
  89. /* Includes */
  90.  
  91. #include "ckcdeb.h"
  92. #include "ckcasc.h"
  93. #include "ckcker.h"
  94. #include "ckuusr.h"
  95. #include "ckcxla.h"
  96. #include "ckcnet.h"            /* Network symbols */
  97. #ifdef OS2
  98. #ifndef NT
  99. #define INCL_NOPM
  100. #define INCL_VIO            /* Needed for ckocon.h */
  101. #include <os2.h> 
  102. #undef COMMENT
  103. #else 
  104. #define APIRET ULONG
  105. #include <windows.h>
  106. #include "cknwin.h"
  107. #include "ckntap.h"            /* CK_TAPI definition */
  108. #endif /* NT */
  109. #include "ckowin.h"
  110. #include "ckocon.h"
  111. extern int tcp_avail;
  112. extern bool viewonly;
  113. extern tt_status;
  114. #endif /* OS2 */
  115.  
  116. #ifdef datageneral
  117. #include <packets:common.h>
  118. #define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd)
  119. #endif /* datageneral */
  120.  
  121. /* External Kermit Variables, see ckmain.c for description. */
  122.  
  123. extern xx_strp xxstring;
  124. extern long xvernum;
  125. extern char *ck_ver;
  126.  
  127. extern int size, local, sndsrc, xitsta, server, displa, binary, msgflg,
  128.   escape, duplex, nfils, quiet, tlevel, pflag, zincnt, atcapr, atdiso, verwho,
  129.   ckxech, carrier, deblog, sendmode, epktflg, what, moving, protocol;
  130. extern int bye_active;
  131. extern long sendstart;
  132. #ifdef CK_TTYFD
  133. extern int ttyfd;
  134. #endif /* CK_TTYFD */
  135.  
  136. extern long vernum;
  137. extern char *versio, *copyright[];
  138. extern char *ckxsys, *cmarg, *cmarg2, **cmlist;
  139. #ifndef NOHELP
  140. extern char *introtxt[];
  141. extern char *newstxt[];
  142. #endif /* NOHELP */
  143. extern char *PWDCMD, *WHOCMD, *TYPCMD;
  144. extern char ttname[];
  145. #ifndef NOFRILLS
  146. extern int rmailf;            /* MAIL command items */
  147. extern char optbuf[];
  148. #endif /* NOFRILLS */
  149. extern CHAR sstate;
  150.  
  151. #ifdef NETCONN
  152. extern int network,            /* Have active network connection */
  153.   nettype,                  /* Type of network */
  154.   ttnproto;                /* Network Protocol */
  155. #endif /* NETCONN */
  156.  
  157. #ifndef NODIAL
  158. extern int dialsta, dialatmo, dialcon, dialcq; /* DIAL status, etc. */
  159. #endif /* NODIAL */
  160.  
  161. #ifdef CK_APC
  162. extern int apcactive, apcstatus;
  163. #endif /* CK_APC */
  164.  
  165. #ifndef NOMSEND                /* Multiple SEND */
  166. extern char *msfiles[];
  167. int filesinlist = 0;            /* And ADD ... */
  168. extern struct filelist * filehead;
  169. extern struct filelist * filetail;
  170. extern struct filelist * filenext;
  171. extern int addlist;
  172. static struct keytab addtab[] = {
  173.     "send-list", 0, 0
  174. };
  175. static int naddtab = sizeof(addtab)/sizeof(struct keytab);
  176. #endif /* NOMSEND */
  177.  
  178. extern char fspec[];            /* Most recent filespec */
  179.  
  180. #ifndef NOCSETS
  181. extern int nfilc;
  182. extern struct keytab fcstab[];
  183. #endif /* NOCSETS */
  184.  
  185. #ifdef CK_TMPDIR
  186. int f_tmpdir = 0;            /* Directory changed temporarily */
  187. char savdir[TMPDIRLEN];            /* For saving current directory */
  188. extern char * dldir;
  189. #endif /* CK_TMPDIR */
  190.  
  191. int activecmd = -1;
  192.  
  193. #ifdef COMMENT
  194. #ifdef pdp11
  195. /* Normally this is defined in ckcfns.c */
  196. #define ENCBUFL 200
  197. CHAR encbuf[ENCBUFL];
  198. #endif /* pdp11 */
  199. #endif /* COMMENT */
  200.  
  201. int rcflag = 0;                /* Pointer to home directory string */
  202. int repars,                /* Reparse needed */
  203.     techo = 0;                /* Take echo */
  204. #ifndef NOSCRIPT
  205. int secho = 1;
  206. #endif /* NOSCRIPT */
  207.  
  208. #ifdef OS2
  209. int xitwarn = 1;            /* Warn about open connection on exit */
  210. #else
  211. int xitwarn = 1;
  212. #endif /* OS2 */
  213.  
  214. #ifndef NOXMIT
  215. /* Variables for TRANSMIT command */
  216.  
  217. int xmitx = 1;            /* Whether to echo during TRANSMIT */
  218. int xmitf = 0;            /* Character to fill empty lines */
  219. int xmitl = 0;            /* 0 = Don't send linefeed too */
  220. int xmitp = LF;            /* Host line prompt */
  221. int xmits = 0;            /* Use shift-in/shift-out, 0 = no */
  222. int xmitw = 0;            /* Milliseconds to pause during TRANSMIT */
  223. #endif /* NOXMIT */
  224.  
  225. /* Declarations from ck?fio.c module */
  226.  
  227. extern char *SPACMD, *SPACM2;        /* SPACE commands */
  228.  
  229. /* Command-oriented items */
  230.  
  231. #ifdef DCMDBUF
  232. extern char *cmdbuf;            /* Command buffers */
  233. extern char *atmbuf;
  234. extern char *line;            /* Character buffer for anything */
  235. extern char *tmpbuf;            /* Short temporary string buffer */
  236. extern int *ifcmd;
  237. extern int *intime;
  238. #else
  239. extern char cmdbuf[];            /* Command buffers */
  240. extern char atmbuf[];
  241. extern char line[];            /* Character buffer for anything */
  242. extern char tmpbuf[];            /* Temporary buffer */
  243. extern int ifcmd[];
  244. extern int intime[];
  245. #endif /* DCMDBUF */
  246.  
  247. char *lp;                /* Pointer to line buffer */
  248.  
  249. #ifndef NOSPL
  250. char evalbuf[33];            /* EVALUATE result */
  251. extern char * inpbuf;            /* Buffer for INPUT and REINPUT */
  252. char *inpbp;                /* And pointer to same */
  253. extern char lblbuf[];            /* Buffer for labels */
  254. int m_found;                /* MINPUT result */
  255. int i_active = 0;            /* INPUT command is active */
  256. char *ms[MINPMAX];            /* Pointers to MINPUT strings */
  257. #endif /* NOSPL */
  258.  
  259. char psave[PROMPTL] = { NUL };        /* For saving & restoring prompt */
  260.  
  261. extern int success;            /* Command success/failure flag */
  262.  
  263. #ifndef NOSPL
  264. int                    /* SET INPUT parameters. */
  265. /* Note, INPUT TIMEOUT, intime[], is on the command-level stack. */
  266.   inbufsize = 0,            /* INPUT buffer size */
  267.   indef = 1,                /* default timeout, seconds */
  268.   inecho = 1,                /* 1 = echo on */
  269.   insilence = 0;            /* 0 = no silence constraint */
  270.  
  271. int maclvl = -1;            /* Macro nesting level */
  272. int mecho = 0;                /* Macro echo, 0 = don't */
  273. char varnam[6];                /* For variable names */
  274. extern int macargc[];            /* ARGC from macro invocation */
  275.  
  276. extern char *m_arg[MACLEVEL][NARGS];    /* Stack of macro arguments */
  277.  
  278. extern char **a_ptr[];            /* Array pointers */
  279. extern int a_dim[];            /* Array dimensions */
  280.  
  281. #ifdef DCMDBUF
  282. extern struct cmdptr *cmdstk;        /* The command stack itself */
  283. #else
  284. extern struct cmdptr cmdstk[];        /* The command stack itself */
  285. #endif /* DCMDBUF */
  286. extern int cmdlvl;            /* Current position in command stack */
  287.  
  288. long ck_alarm = 0;            /* SET ALARM value */
  289. char alrm_date[10] = { ' ',' ',' ',' ',' ',' ',' ',' ',' ' };
  290. char alrm_time[ 8] = { ' ',' ',' ',' ',' ',' ',' ' };
  291.  
  292. #endif /* NOSPL */
  293.  
  294. static int x, y, z = 0;            /* Local workers */
  295. static char *s;
  296.  
  297. #define xsystem(s) zsyscmd(s)
  298.  
  299. /* Top-Level Interactive Command Keyword Table */
  300. /* Keywords must be in lowercase and in alphabetical order. */
  301.  
  302. struct keytab cmdtab[] = {
  303. #ifndef NOPUSH
  304.     "!",       XXSHE, CM_INV,    /* Shell escape */
  305. #endif /* NOPUSH */
  306.     "#",           XXCOM, CM_INV,    /* Comment */
  307. #ifndef NOSPL
  308.     ":",           XXLBL, CM_INV,    /* Label */
  309. #endif /* NOSPL */
  310. #ifndef NOPUSH
  311. #ifdef CK_REDIR
  312.     "<",           XXFUN, CM_INV,    /* REDIRECT */
  313. #endif /* CK_REDIR */
  314.     "@",           XXSHE, CM_INV,    /* DCL escape */
  315. #endif /* NOPUSH */
  316.     "about",       XXVER, CM_INV,    /* Synonym for VERSION */
  317. #ifndef NOSPL
  318. #ifndef NOMSEND
  319.     "add",         XXADD, 0,        /* ADD */
  320. #endif /* NOMSEND */
  321. #ifndef NODIAL
  322.     "answer",      XXANSW, 0,        /* ANSWER the phone */
  323. #endif /* NODIAL */
  324.     "apc",         XXAPC, 0,        /* Application Program Command */
  325.     "ascii",       XXASC, CM_INV,
  326.     "asg",         XXASS, CM_INV,       /* Invisible synonym for ASSIGN */
  327.     "ask",         XXASK, 0,        /* ASK for text, assign to variable */
  328.     "askq",        XXASKQ,0,            /* ASK quietly (no echo) */
  329.     "assign",      XXASS, 0,            /* ASSIGN value to variable or macro */
  330. #endif /* NOSPL */
  331. #ifndef NOSPL
  332.     "beep",        XXBEEP,CM_INV,    /* BEEP */
  333. #endif /* NOSPL */
  334.     "binary",      XXBIN, CM_INV,
  335. #ifndef NOFRILLS
  336.     "bug",         XXBUG, 0,        /* BUG report instructions */
  337. #endif /* NOFRILLS */
  338.     "bye",         XXBYE, 0,        /* BYE to remote server */
  339. #ifndef NOLOCAL
  340.     "c",           XXCON, CM_INV|CM_ABR, /* invisible synonym for CONNECT */
  341. #endif /* NOLOCAL */
  342. #ifndef NOFRILLS
  343.     "cat",         XXTYP, CM_INV,    /* Invisible synonym for TYPE */
  344. #endif /* NOFRILLS */
  345.     "cd",          XXCWD, 0,        /* Change Directory */
  346.     "check",       XXCHK, 0,        /* CHECK for a feature */
  347. #ifndef NOFRILLS
  348.     "clear",       XXCLE, 0,        /* CLEAR input and/or device buffer */
  349. #endif /* NOFRILLS */
  350.     "close",       XXCLO, 0,        /* CLOSE a log or other file */
  351. #ifdef OS2
  352.     "cls",         XXCLS, CM_INV,    /* Clear Screen (CLS) */
  353. #endif /* OS2 */
  354.     "comment",     XXCOM, 0,        /* Introduce a comment */
  355. #ifndef NOLOCAL
  356.     "connect",     XXCON, 0,        /* Begin terminal connection */
  357. #endif /* NOLOCAL */
  358. #ifndef NOFRILLS
  359. #ifdef ZCOPY
  360.     "copy",        XXCPY, 0,        /* COPY a file */
  361. #endif /* ZCOPY */
  362. #endif /* NOFRILLS */
  363.     "cwd",       XXCWD, CM_INV,    /* Invisisble synonym for cd */
  364. #ifndef NOSPL
  365.     "date",        XXDATE,0,        /* DATE */
  366.     "dcl",         XXDCL, CM_INV,    /* DECLARE an array */
  367.     "declare",     XXDCL, 0,        /* DECLARE an array */
  368.     "decrement",   XXDEC, 0,        /* DECREMENT a numeric variable */
  369.     "define",      XXDEF, 0,        /* DEFINE a macro or variable */
  370. #endif /* NOSPL */
  371. #ifndef NOFRILLS
  372.     "delete",      XXDEL, 0,        /* DELETE a file */
  373. #endif /* NOFRILLS */
  374. #ifndef NODIAL
  375.     "dial",       XXDIAL,0,        /* DIAL a phone number */
  376. #endif /* NODIAL */
  377.     "directory",   XXDIR, 0,        /* DIRECTORY of files */
  378. #ifndef NOFRILLS
  379. #ifndef NOSERVER
  380.     "disable",     XXDIS, 0,        /* DISABLE a server function */
  381. #endif /* NOSERVER */
  382. #endif /* NOFRILLS */
  383. #ifndef NOSPL
  384.     "do",          XXDO,  0,        /* DO (execute) a macro */
  385. #endif /* NOSPL */
  386.     "e",           XXEXI, CM_INV|CM_ABR,
  387. #ifndef NOFRILLS
  388.     "e-packet",    XXERR, CM_INV,    /* Send an Error-Packet */
  389. #endif /* NOFRILLS */
  390.     "echo",        XXECH, 0,        /* ECHO text */
  391.     "eightbit",    XXEIGHT, 0,        /* EIGHTBIT */
  392. #ifndef NOSPL
  393.     "else",        XXELS, CM_INV,    /* ELSE part of IF statement */
  394. #endif /* NOSPL */
  395. #ifndef NOSERVER
  396. #ifndef NOFRILLS
  397.     "enable",      XXENA, 0,        /* ENABLE a server function */
  398. #endif /* NOFRILLS */
  399. #endif /* NOSERVER */
  400. #ifndef NOSPL
  401.     "end",         XXEND, 0,        /* END command file or macro */
  402.     "evaluate",    XXEVAL, 0,        /* EVALUATE */
  403. #endif /* NOSPL */
  404.     "ex",          XXEXI, CM_INV|CM_ABR, /* Let "ex" still be EXIT */
  405.     "exit",       XXEXI, 0,         /* EXIT from C-Kermit */
  406. #ifdef OS2
  407.     "extproc",     XXCOM, CM_INV,        /* Dummy command for OS/2 */
  408. #endif /* OS2 */
  409.     "f",           XXFIN, CM_INV|CM_ABR, /* Invisible abbreviation for... */
  410.     "finish",      XXFIN, 0,         /* FINISH */
  411. #ifndef NOSPL
  412.     "fo",          XXFOR, CM_INV|CM_ABR, /* Invisible abbreviation for... */
  413.     "for",         XXFOR, 0,        /* FOR loop */
  414.     "forward",     XXFWD, CM_INV,    /* FORWARD (ugh) */
  415. #endif /* NOSPL */
  416. #ifndef NOFRILLS
  417.     "fot",       XXDIR, CM_INV,    /* "fot" = "dir" (for Chris) */
  418. #endif /* NOFRILLS */
  419. #ifdef TCPSOCKET
  420.     "ftp",       XXFTP, 0,        /* FTP (for TCP/IP) */
  421. #endif /* TCPSOCKET */
  422.     "g",           XXGET, CM_INV|CM_ABR, /* Invisible abbreviation for GET */
  423. #ifndef NOSPL
  424.     "ge",          XXGET, CM_INV|CM_ABR, /* Ditto */
  425. #endif /* NOSPL */
  426.     "get",         XXGET, 0,        /* GET */
  427. #ifndef NOSPL
  428.     "getc",        XXGETC, 0,        /* GETC */
  429. #ifndef NOFRILLS
  430.     "getok",       XXGOK, 0,        /* GETOK (ask for Yes/No) */
  431. #endif /* NOFRILLS */
  432. #endif /* NOSPL */
  433. #ifndef NOSPL
  434.     "goto",        XXGOTO,0,        /* GOTO label in take file or macro */
  435. #endif /* NOSPL */
  436.     "h",           XXHLP, CM_INV|CM_ABR, /* Invisible synonym for HELP */
  437.     "hangup",      XXHAN, 0,         /* HANGUP the connection */
  438.     "help",       XXHLP, 0,         /* Display HELP text */
  439. #ifndef NOSPL
  440.     "i",           XXINP, CM_INV|CM_ABR, /* Invisible synonym for INPUT */
  441.     "if",          XXIF,  0,         /* IF (condition) command */
  442.     "in",          XXINP, CM_INV|CM_ABR, /* Invisible synonym for INPUT */
  443.     "increment",   XXINC, 0,         /* Increment a numeric variable */
  444.     "input",       XXINP, 0,         /* INPUT text from comm device */
  445. #endif /* NOSPL */
  446. #ifndef NOHELP
  447.      "introduction", XXINT, 0,        /* Print introductory text */
  448. #endif /* NOHELP */
  449.     "kermit",      XXKERMI, 0,        /* Hmmm what's this... */
  450. #ifndef NOFRILLS
  451.     "l",           XXLOG, CM_INV|CM_ABR, /* Invisible synonym for log */
  452. #endif /* NOFRILLS */
  453. #ifndef NOSPL
  454.     "local",       XXLOCAL, 0,        /* LOCAL variable declaration */
  455. #endif /* NOSPL */
  456.     "log",         XXLOG, 0,        /* Open a log file */
  457. #ifndef NOFRILLS
  458. #ifndef NODIAL
  459.     "lookup",      XXLOOK,0,        /* LOOKUP */
  460. #endif /* NODIAL */
  461.     "ls",          XXDIR, CM_INV,    /* Invisible synonym for DIRECTORY */
  462.     "mail",        XXMAI, 0,        /* Send a file as e-mail */
  463.     "man",         XXHLP, CM_INV,       /* Synonym for HELP */
  464. #endif /* NOFRILLS */
  465. #ifdef CK_MKDIR
  466.     "md",          XXMKDIR, CM_INV,    /* Synonym for MKDIR */
  467. #endif /* CK_MKDIR */
  468. #ifdef CK_MINPUT
  469.     "minput",      XXMINP, 0,        /* MINPUT */
  470. #endif /* CK_MINPUT */
  471. #ifndef NOMSEND
  472.     "mget",        XXGET, CM_INV,    /* MGET = GET */
  473. #endif /* NOMSEND */
  474. #ifdef CK_MKDIR
  475.     "mkdir",       XXMKDIR, 0,        /* MKDIR */
  476. #endif /* CK_MKDIR */
  477. #ifndef NOMSEND
  478.     "mmove",       XXMMOVE, 0,        /* MMOVE */
  479. #endif /* NOMSEND */
  480.     "move",        XXMOVE, 0,        /* MOVE  */
  481. #ifndef NOSPL
  482.     "mpause",      XXMSL, CM_INV,    /* Millisecond sleep */
  483. #endif /* NOSPL */
  484. #ifndef NOMSEND
  485.     "mput",        XXMSE, CM_INV,    /* MPUT = MSEND */
  486. #endif /* NOMSEND */
  487. #ifndef NOMSEND
  488.     "ms",          XXMSE, CM_INV|CM_ABR,
  489.     "msend",       XXMSE, 0,        /* Multiple SEND */
  490. #endif /* NOMSEND */
  491. #ifndef NOSPL
  492.     "msleep",      XXMSL, 0,        /* Millisecond sleep */
  493. #endif /* NOSPL */
  494. #ifndef NOFRILLS
  495.     "mv",          XXREN, CM_INV,    /* Synonym for rename */
  496. #endif /* NOFRILLS */
  497.     "news",        XXNEW, 0,        /* Display NEWS of new features */
  498.     "nopush",      XXNPSH, CM_INV,    /* Disable PUSH command/features */
  499. #ifndef NOSPL
  500.     "o",           XXOUT, CM_INV|CM_ABR, /* Invisible synonym for OUTPUT */
  501.     "open",        XXOPE, 0,        /* OPEN file for reading or writing */
  502.     "output",      XXOUT, 0,        /* OUTPUT text to comm device */
  503. #endif /* NOSPL */
  504. #ifdef ANYX25
  505.     "pad",         XXPAD, 0,            /* X.3 PAD commands */
  506. #endif /* ANYX25 */
  507. #ifndef NOSPL
  508.     "pause",       XXPAU, 0,        /* Sleep for specified interval */
  509. #endif /* NOSPL */
  510. #ifndef NODIAL
  511.     "pdial",       XXPDIA,0,        /* PDIAL (partial dial) */
  512. #endif /* NODIAL */
  513. #ifdef TCPSOCKET
  514.     "ping",        XXPNG, 0,        /* PING (for TCP/IP) */
  515. #endif /* TCPSOCKET */
  516. #ifndef NOSPL
  517.     "pop",         XXEND, CM_INV,    /* Invisible synonym for END */
  518. #endif /* NOSPL */
  519. #ifndef NOFRILLS
  520.     "print",       XXPRI, 0,        /* PRINT a file locally */
  521. #ifndef NOPUSH
  522. #ifdef CK_RESEND
  523.     "psend",       XXPSEN, 0,        /* PSEND */
  524. #endif /* CK_RESEND */
  525.     "pu",          XXSHE, CM_INV,    /* PU = PUSH */
  526.     "push",        XXSHE, 0,        /* PUSH command (like RUN, !) */
  527. #endif /* NOPUSH */
  528.     "put",       XXSEN, CM_INV,    /* PUT = SEND */
  529.     "pwd",         XXPWD, 0,            /* Print Working Directory */
  530. #endif /* NOFRILLS */
  531.     "quit",       XXQUI, 0,        /* QUIT from program = EXIT */
  532.     "r",           XXREC, CM_INV|CM_ABR, /* Invisible synonym for RECEIVE */
  533. #ifdef CK_MKDIR
  534.     "rd",          XXRMDIR, CM_INV,     /* RMDIR */
  535. #endif /* CK_MKDIR */
  536. #ifndef NOSPL
  537.     "read",        XXREA, 0,            /* READ a line from a file */
  538. #ifdef BINREAD
  539.     "readblock",   XXRDBL, 0,        /* READ a block */
  540. #endif /* BINREAD */
  541. #endif /* NOSPL */
  542.     "receive",       XXREC, 0,        /* RECEIVE files */
  543. #ifndef NODIAL
  544. #ifdef CK_REDIR
  545.     "red",         XXRED, CM_INV|CM_ABR, /* Invisible synonym for REDIAL */
  546.     "redi",        XXRED, CM_INV|CM_ABR, /* Invisible synonym for REDIAL */
  547. #endif /* CK_REDIR */
  548.     "redial",      XXRED, 0,        /* REDIAL last DIAL number */
  549. #endif /* NODIAL */
  550. #ifndef NOPUSH
  551. #ifdef CK_REDIR
  552. #ifdef OS2
  553.     "redirect",    XXFUN, CM_INV,    /* REDIRECT local command to ttyfd */
  554. #else /* OS2 */
  555.     "redirect",    XXFUN, 0,        /* REDIRECT local command to ttyfd */
  556. #endif /* OS2 */
  557. #endif /* CK_REDIR */
  558. #endif /* NOPUSH */
  559. #ifdef CK_RESEND
  560.     "reget",       XXREGET, 0,        /* REGET */
  561. #endif /* CK_RESEND */
  562. #ifndef NOSPL
  563.     "reinput",     XXREI, 0,            /* REINPUT (from INPUT buffer) */
  564. #endif /* NOSPL */
  565.     "remote",       XXREM, 0,        /* Send generic command to server */
  566. #ifndef NOFRILLS
  567.     "rename",      XXREN, 0,        /* RENAME a local file */
  568.     "replay",      XXTYP, CM_INV,    /* REPLAY (for now, just type) */
  569. #endif /* NOFRILLS */
  570. #ifdef CK_RESEND
  571.     "resend",      XXRSEN, 0,        /* RESEND */
  572. #ifndef NOSPL
  573.     "ret",         XXRET, CM_INV|CM_ABR,
  574. #endif /* NOSPL */
  575. #endif /* CK_RESEND */
  576.     "retrieve",    XXRETR, 0,           /* RETRIEVE */
  577. #ifndef NOSPL
  578.     "return",      XXRET, 0,        /* RETURN from a function */
  579. #endif /* NOSPL */
  580. #ifndef NOPUSH
  581. #ifdef CK_REXX
  582.     "rexx",       XXREXX, 0,        /* Execute a Rexx command */
  583. #endif /* CK_REXX */
  584. #endif /* NOPUSH */
  585. #ifdef TCPSOCKET
  586. #ifdef RLOGCODE
  587.     "rlogin",    XXRLOG, 0,        /* Rlogin to host */
  588. #endif /* RLOGCODE */
  589. #endif /* TCPSOCKET */
  590. #ifndef NOFRILLS
  591.     "rm",          XXDEL, CM_INV,    /* Invisible synonym for delete */
  592. #endif /* NOFRILLS */
  593. #ifdef CK_MKDIR
  594.     "rmdir",       XXRMDIR, 0,          /* RMDIR */
  595. #endif /* CK_MKDIR */
  596. #ifndef NOPUSH
  597.     "run",         XXSHE, 0,        /* RUN a program or command */
  598. #endif /* NOPUSH */
  599.     "s",           XXSEN, CM_INV|CM_ABR, /* Invisible synonym for send */
  600.     "save",       XXSAVE, 0,        /* SAVE parameters */
  601. #ifndef NOSCRIPT
  602.     "script",       XXLOGI,0,        /* Execute a UUCP-style script */
  603. #endif /* NOSCRIPT */
  604.     "send",       XXSEN, 0,        /* Send (a) file(s) */
  605. #ifndef NOSERVER
  606.     "server",       XXSER, 0,        /* Be a SERVER */
  607. #endif /* NOSERVER */
  608.     "set",       XXSET, 0,        /* SET parameters */
  609. #ifndef NOSHOW
  610.     "show",        XXSHO, 0,        /* SHOW parameters */
  611. #endif /* NOSHOW */
  612. #ifndef NOSPL
  613. #ifndef NOFRILLS
  614.     "sleep",       XXPAU, CM_INV,    /* SLEEP for specified interval */
  615. #endif /* NOFRILLS */
  616. #endif /* NOSPL */
  617. #ifndef MAC
  618. #ifndef NOFRILLS
  619.     "sp",          XXSPA, CM_INV|CM_ABR,
  620.     "spa",         XXSPA, CM_INV|CM_ABR,
  621. #endif /* NOFRILLS */
  622.     "space",       XXSPA, 0,        /* Show available disk SPACE */
  623. #endif /* MAC */
  624. #ifndef NOFRILLS
  625. #ifndef NOPUSH
  626.     "spawn",       XXSHE, CM_INV,    /* Synonym for PUSH, RUN */
  627. #endif /* NOPUSH */
  628. #endif /* NOFRILLS */
  629.     "statistics",  XXSTA, 0,        /* Display file transfer stats */
  630. #ifndef NOSPL
  631.     "stop",        XXSTO, 0,        /* STOP all take files and macros */
  632. #endif /* NOSPL */
  633. #ifndef NOJC
  634.     "suspend",     XXSUS, 0,        /* SUSPEND C-Kermit (UNIX only) */
  635. #endif /* NOJC */
  636. #ifndef NOSPL
  637.     "switch",      XXSWIT, 0,        /* SWITCH */
  638. #endif /* NOSPL */
  639.     "take",       XXTAK, 0,        /* TAKE commands from a file */
  640. #ifndef NOFRILLS
  641. #ifdef TCPSOCKET
  642.     "tel",         XXTEL, CM_INV|CM_ABR,
  643.     "telnet",      XXTEL, 0,        /* TELNET (TCP/IP only) */
  644.     "telopt",      XXTELOP, CM_INV,     /* TELOPT (ditto) */
  645. #endif /* TCPSOCKET */
  646. #ifdef DEBUG
  647.     "test",        XXTES, CM_INV,    /* (for testing) */
  648. #endif /* DEBUG */
  649. #endif /* NOFRILLS */
  650.     "text",        XXASC, CM_INV,
  651. #ifndef NOCSETS
  652.     "translate",   XXXLA, 0,        /* TRANSLATE local file char sets */
  653. #endif
  654. #ifndef NOXMIT
  655.     "transmit",    XXTRA, 0,        /* Send (upload) a file, no protocol */
  656. #endif /* NOXMIT */
  657. #ifndef NOFRILLS
  658.     "type",        XXTYP, 0,        /* Display a local file */
  659. #endif /* NOFRILLS */
  660. #ifndef NOSPL
  661.     "undefine",    XXUNDEF, 0,        /* UNDEFINE a variable or macro */
  662. #endif /* NOSPL */
  663. #ifdef OS2ONLY
  664.     "updates",     XXUPD, 0,        /* View UPDATES file */
  665. #endif /* OS2ONLY */
  666.     "version",     XXVER, 0,        /* VERSION-number display */
  667. #ifdef OS2
  668.     "viewonly",    XXVIEW, 0,        /* VIEWONLY Terminal Mode */
  669. #endif /* OS2 */
  670. #ifndef NOSPL
  671.     "wait",        XXWAI, 0,        /* WAIT (like pause) */
  672.     "while",       XXWHI, 0,        /* WHILE loop */
  673. #endif /* NOSPL */
  674. #ifndef OS2
  675. #ifndef MAC
  676. #ifndef NOFRILLS
  677.     "who",         XXWHO, 0,        /* WHO's logged in? */
  678. #endif /* NOFRILLS */
  679. #endif /* MAC */
  680. #endif /* OS2 */
  681. #ifndef NOSPL
  682.     "wr",          XXWRI, CM_INV|CM_ABR,
  683.     "wri",         XXWRI, CM_INV|CM_ABR,
  684.     "writ",        XXWRI, CM_INV|CM_ABR,
  685.     "write",       XXWRI, 0,        /* WRITE characters to a file */
  686.     "write-line",  XXWRL, 0,        /* WRITE a line to a file */
  687. #ifdef BINREAD
  688.     "writeblock",  XXWRBL, 0,        /* WRITE a block */
  689. #endif /* BINREAD */
  690.     "writeln",     XXWRL, CM_INV,    /* Pascalisch synonym for write-line */
  691. #endif /* NOSPL */
  692.     "xecho",       XXXECH,0,        /* XECHO */
  693. #ifndef NOSPL
  694.     "xif",         XXIFX, 0,        /* Extended IF command */
  695. #endif /* NOSPL */
  696. #ifndef NOCSETS
  697.     "xlate",       XXXLA, CM_INV,    /* Synonym for TRANSLATE */
  698. #endif /* NOCSETS */
  699. #ifndef NOXMIT
  700.     "xmit",        XXTRA, CM_INV,    /* Synonym for TRANSMIT */
  701. #endif /* NOXMIT */
  702. #ifndef OS2
  703.     "z",           XXSUS, CM_INV,    /* Synonym for SUSPEND */
  704. #endif /* OS2 */
  705. #ifndef NOSPL
  706.     "_asg",        XXASX, CM_INV,    /* Used internally by FOR, etc */
  707.     "_assign",     XXASX, CM_INV,    /* Used internally by FOR, etc */
  708.     "_define",     XXDFX, CM_INV,    /* Used internally by FOR, etc */
  709.     "_forward",    XXXFWD,CM_INV,    /* Used internally by SWITCH   */
  710.     "_getargs",    XXGTA, CM_INV,       /* Used internally by FOR, etc */
  711.     "_putargs",    XXPTA, CM_INV,       /* Used internally by FOR, etc */
  712. #endif /* NOSPL */
  713. "", 0, 0
  714. };
  715. int ncmd = (sizeof(cmdtab) / sizeof(struct keytab)) - 1;
  716.  
  717. char toktab[] = {
  718. #ifndef NOPUSH
  719.     '!',                /* Shell escape */
  720. #endif /* NOPUSH */
  721.     '#',                /* Comment */
  722.     ';',                /* Comment */
  723. #ifndef NOSPL
  724.     ':',                /* Label */
  725. #endif /* NOSPL */
  726. #ifndef NOPUSH
  727. #ifdef CK_REDIR
  728.     '<',                /* REDIRECT */
  729. #endif /* CK_REDIR */
  730.     '@',                /* DCL escape */
  731. #endif /* NOPUSH */
  732.     '\0'                /* End of this string */
  733. };
  734.  
  735. struct keytab yesno[] = {        /* Yes/No keyword table */
  736.     "no",    0, 0,
  737.     "ok",    1, 0,
  738.     "yes",   1, 0
  739. };
  740. int nyesno = (sizeof(yesno) / sizeof(struct keytab));
  741.  
  742. /* Save keyword table */
  743.  
  744. struct keytab savtab[] = {
  745. #ifndef NOSETKEY
  746.     "keymap", XSKEY, 0
  747. #else
  748.     "",     0,     0
  749. #endif    /* NOSETKEY */
  750. };
  751. int nsav = (sizeof(savtab) / sizeof(struct keytab));
  752.  
  753. /* Parameter keyword table */
  754.  
  755. struct keytab prmtab[] = {
  756.     "alarm",            XYALRM,  0,
  757.     "attributes",       XYATTR,  0,
  758.     "b",        XYBACK,  CM_INV|CM_ABR,
  759.     "ba",        XYBACK,  CM_INV|CM_ABR,
  760.     "background",       XYBACK,  0,
  761. #ifndef NOLOCAL
  762.     "baud",            XYSPEE,  CM_INV,
  763. #endif /* NOLOCAL */
  764. #ifdef OS2
  765.     "bell",             XYBELL,  0,
  766. #endif /* OS2 */
  767.     "block-check",      XYCHKT,  0,
  768. #ifdef DYNAMIC
  769.     "buffers",          XYBUF,   0,
  770. #endif /* DYNAMIC */
  771. #ifndef NOLOCAL
  772. #ifndef MAC
  773.     "carrier-watch",    XYCARR,  0,
  774. #endif /* MAC */
  775. #endif /* NOLOCAL */
  776. #ifndef NOSPL
  777.     "case",             XYCASE,  0,
  778. #endif /* NOSPL */
  779.     "cmd",              XYCMD,   CM_INV,
  780.     "command",          XYCMD,   0,
  781. #ifdef CK_SPEED
  782.     "con",              XYQCTL,  CM_INV|CM_ABR,
  783. #endif /* CK_SPEED */
  784.     "console",          XYCMD,   CM_INV,
  785. #ifdef CK_SPEED
  786.     "control-character",XYQCTL,  0,
  787. #endif /* CK_SPEED */
  788. #ifndef NOSPL
  789.     "count",            XYCOUN,  0,
  790. #endif /* NOSPL */
  791.     "d",        XYDELA,  CM_INV|CM_ABR,
  792.     "de",        XYDELA,  CM_INV|CM_ABR,
  793.     "debug",            XYDEBU,  CM_INV,
  794. #ifdef VMS
  795.     "default",          XYDFLT,  0,
  796. #else
  797. #ifndef MAC
  798.     "default",          XYDFLT,  CM_INV,
  799. #endif /* MAC */
  800. #endif /* VMS */
  801.     "delay",            XYDELA,  0,
  802.     "destination",    XYDEST,  0,
  803. #ifndef NODIAL
  804.     "dial",             XYDIAL,  0,
  805. #endif /* NODIAL */
  806. #ifdef OS2
  807.     "dialer",        XYDLR,   CM_INV,
  808. #endif /* OS2 */
  809. #ifndef NOLOCAL
  810.     "duplex",            XYDUPL,  0,
  811.     "escape-character", XYESC,   0,
  812. #endif /* NOLOCAL */
  813.     "exit",        XYEXIT,  0,
  814.     "file",           XYFILE,  0,
  815.     "flow-control",     XYFLOW,  0,
  816.     "handshake",        XYHAND,  0,
  817. #ifdef NETCONN
  818.     "host",             XYHOST,  0,
  819. #endif /* NETCONN */
  820. #ifndef NOSPL
  821.     "i",        XYINPU,  CM_INV|CM_ABR,
  822.     "in",        XYINPU,  CM_INV|CM_ABR,
  823. #endif /* NOSPL */
  824.     "incomplete",       XYIFD,   CM_INV,
  825. #ifndef NOSPL
  826.     "input",            XYINPU,  0,
  827. #endif /* NOSPL */
  828. #ifndef NOSETKEY
  829.     "key",        XYKEY,   0,
  830. #endif /* NOSETKEY */
  831.     "l",                XYLINE,  CM_INV|CM_ABR,
  832. #ifndef NOCSETS
  833.     "language",         XYLANG,  0,
  834. #endif /* NOCSETS */
  835.     "line",             XYLINE,  0,
  836. #ifndef NOLOCAL
  837.     "local-echo",    XYLCLE,  CM_INV,
  838. #endif /* NOLOCAL */
  839.     "login",        XYLOGIN, 0,
  840. #ifndef NOSPL
  841.     "macro",            XYMACR,  0,
  842. #endif /* NOSPL */
  843. #ifdef COMMENT
  844. #ifdef VMS
  845.     "messages",         XYMSGS,  0,
  846. #endif /* VMS */
  847. #endif /* COMMENT */
  848. #ifndef NODIAL
  849.     "modem",        XYMODM,     0,
  850. #endif /* NODIAL */
  851. #ifndef NOLOCAL
  852. #ifdef OS2MOUSE
  853.     "mouse",        XYMOUSE, 0,
  854. #endif /* OS2MOUSE */
  855. #endif /* NOLOCAL */
  856. #ifdef OS2
  857.     "mskermit",         XYMSK,   0,
  858. #endif /* OS2 */
  859. #ifdef NETCONN
  860.     "network",          XYNET,   0,
  861. #endif /* NETCONN */
  862. #ifndef NOSPL
  863.     "output",           XYOUTP,  0,
  864. #endif /* NOSPL */
  865. #ifdef ANYX25
  866.     "pad",              XYPAD,   0,
  867. #endif /* ANYX25 */
  868.     "parity",            XYPARI,   0,
  869. #ifdef OS2
  870.     "port",             XYLINE,   0,
  871. #else
  872.     "port",             XYLINE,   CM_INV,
  873. #endif /* OS2 */
  874.     "pr",               XYPROM,  CM_INV|CM_ABR,
  875.     "printer",          XYPRTR,  0,
  876. #ifdef OS2
  877.     "priority",         XYPRTY,  0,
  878. #endif /* OS2 */
  879. #ifdef CK_SPEED
  880.     "prefixing",        XYPREFIX, 0,
  881. #endif /* CK_SPEED */
  882. #ifndef NOFRILLS
  883.     "prompt",            XYPROM,  0,
  884. #endif /* NOFRILLS */
  885.     "protocol",        XYPROTO, 0,
  886.     "quiet",        XYQUIE,  0,
  887.     "receive",          XYRECV,  0,
  888.     "repeat",           XYREPT,  0,
  889.     "retry-limit",      XYRETR,  0,
  890. #ifndef NOSCRIPT
  891.     "script",        XYSCRI,  0,
  892. #endif /* NOSCRIPT */
  893.     "send",             XYSEND,  0,
  894. #ifndef NOSERVER
  895.     "server",           XYSERV,  0,
  896. #endif /* NOSERVER */
  897.  
  898. #ifndef NOLOCAL
  899. #ifdef UNIX
  900.     "session-log",      XYSESS,  0,
  901. #else
  902. #ifdef OSK
  903.     "session-log",      XYSESS,  0,
  904. #endif /* OSK */
  905. #endif /* UNIX */
  906. #endif /* NOLOCAL */
  907.  
  908. #ifndef NOLOCAL
  909.     "speed",            XYSPEE,  0,
  910. #endif /* NOLOCAL */
  911.  
  912. #ifndef NOSPL
  913.     "startup-file",     XYSTARTUP, CM_INV,
  914. #endif /* NOSPL */
  915.  
  916. #ifndef NOJC
  917.     "suspend",          XYSUSP,  0,
  918. #endif /* NOJC */
  919.     "take",             XYTAKE,  0,
  920. #ifdef CK_TAPI
  921.    "tapi",              XYTAPI,  0,
  922. #endif /* CK_TAPI */
  923. #ifndef NOTCPOPTS
  924. #ifdef TCPSOCKET
  925. #ifdef SOL_SOCKET
  926.    "tcp",               XYTCP, 0,
  927. #endif /* SOL_SOCKET */
  928. #endif /* TCPSOCKET */
  929. #endif /* NOTCPOPTS */
  930. #ifdef TNCODE
  931.     "telnet",           XYTEL,   0,
  932. #endif /* TNCODE */
  933.     "temp-directory",   XYTMPDIR,0,
  934. #ifndef NOLOCAL
  935.     "terminal",         XYTERM,  0,
  936. #endif /* NOLOCAL */
  937. #ifdef OS2
  938.     "title",        XYTITLE, 0,
  939. #endif /* OS2 */
  940.     "transfer",         XYXFER,  0,
  941. #ifndef NOXMIT
  942.     "transmit",         XYXMIT,  0,
  943. #endif /* NOXMIT */
  944. #ifndef NOCSETS
  945.     "unknown-char-set", XYUNCS,  0,
  946. #endif /* NOCSETS */
  947. #ifndef NOPUSH
  948. #ifdef UNIX
  949.     "wildcard-expansion", XYWILD, 0,
  950. #endif /* UNIX */
  951. #endif /* NOPUSH */
  952. #ifdef NT
  953.     "w",                XYWIND,  CM_INV|CM_ABR,
  954.     "wi",               XYWIND,  CM_INV|CM_ABR,
  955.     "win",              XYWIND,  CM_INV|CM_ABR,
  956. #endif /* NT */
  957.     "window-size",      XYWIND,  0,
  958. #ifdef NT
  959.     "win95",            XYWIN95, CM_INV,
  960. #endif /* NT */
  961. #ifdef ANYX25
  962.     "x.25",             XYX25,   0,
  963.     "x25",              XYX25,   CM_INV,
  964. #endif /* ANYX25 */
  965.     "xfer",             XYXFER,  CM_INV,
  966. #ifndef NOXMIT
  967.     "xmit",             XYXMIT,  CM_INV,
  968. #endif /* NOXMIT */
  969.     "", 0, 0
  970. };
  971. int nprm = (sizeof(prmtab) / sizeof(struct keytab)) - 1; /* How many */
  972.  
  973. /* Table of networks */
  974. #ifdef NETCONN
  975. struct keytab netcmd[] = {
  976. /*
  977.   This is for SET NETWORK { DIRECTORY, TYPE }.
  978.   The old form, SET NETWORK <name-of-network> is retained for compatibility,
  979.   but made invisible.  See netkey[], just below.  NOTE that the values for the
  980.   keywords in both tables should be consistent, and that the network-thing
  981.   keyword (DIRECTORY, TYPE) values must be distinct from the network-type
  982.   keywords values.  (This is exactly the same situation we have with SET MODEM
  983.   vs SET MODEM TYPE...)
  984. */
  985. #ifdef DECNET                /* DECnet / PATHWORKS */
  986.     "decnet",        NET_DEC,  CM_INV,
  987. #endif /* DECNET */
  988.  
  989.     "directory",     XYNET_D,  0,    /* DIRECTORY (no more yuk) */
  990.  
  991. #ifdef NETFILE
  992.     "file",           NET_FILE, CM_INV,  /* FILE (real crude) */
  993. #endif /* NETFILE */
  994.  
  995. #ifdef NPIPE                /* Named Pipes */
  996.     "named-pipe",    NET_PIPE, CM_INV,
  997. #endif /* NPIPE */
  998.  
  999. #ifdef CK_NETBIOS
  1000.     "netbios",       NET_BIOS, CM_INV,    /* NETBIOS */
  1001. #endif /* CK_NETBIOS */
  1002.  
  1003. #ifdef SUPERLAT
  1004.    "superlat",       NET_SLAT, CM_INV,  /* Meridian Technologies' SuperLAT */
  1005. #endif /* SUPERLAT */
  1006.  
  1007. #ifdef TCPSOCKET            /* TCP/IP sockets library */
  1008.     "tcp/ip",       NET_TCPB, CM_INV,
  1009. #endif /* TCPSOCKET */
  1010. #ifdef SUPERLAT
  1011.     "tes32",        NET_SLAT, CM_INV,  /* Emulux TES32 */
  1012. #endif /* SUPERLAT */
  1013.     "type",         XYNET_T,  0,
  1014. #ifdef ANYX25                /* X.25 */
  1015. #ifdef SUNX25
  1016.     "x",            NET_SX25, CM_INV|CM_ABR,
  1017.     "x.25",         NET_SX25, CM_INV,
  1018.     "x25",          NET_SX25, CM_INV,
  1019. #else
  1020. #ifdef STRATUSX25
  1021.     "x",            NET_VX25, CM_INV|CM_ABR,
  1022.     "x.25",         NET_VX25, CM_INV,
  1023.     "x25",          NET_VX25, CM_INV,
  1024. #endif /* STRATUSX25 */
  1025. #endif /* SUNX25 */
  1026. #endif /* ANYX25 */
  1027.     "", 0, 0
  1028. };
  1029. int nnets = (sizeof(netcmd) / sizeof(struct keytab)) - 1;
  1030.  
  1031. struct keytab netkey[] = {
  1032. /*
  1033.   These are the network types.
  1034. */
  1035. #ifdef DECNET                /* DECnet / PATHWORKS */
  1036.     "decnet",        NET_DEC,  0,
  1037. #endif /* DECNET */
  1038.  
  1039. #ifdef NETFILE
  1040.     "file",           NET_FILE, CM_INV,  /* FILE (real crude) */
  1041. #endif /* NETFILE */
  1042.  
  1043. #ifdef NPIPE                /* Named Pipes */
  1044.     "named-pipe",     NET_PIPE,  0,
  1045. #endif /* NPIPE */
  1046.  
  1047. #ifdef CK_NETBIOS
  1048.     "netbios",        NET_BIOS,  0,    /* NETBIOS */
  1049. #endif /* CK_NETBIOS */
  1050.  
  1051. #ifdef SUPERLAT
  1052.    "superlat",        NET_SLAT,  0,    /* Meridian Technologies' SuperLAT */
  1053. #endif /* SUPERLAT */
  1054.  
  1055. #ifdef TCPSOCKET            /* TCP/IP sockets library */
  1056.     "tcp/ip",       NET_TCPB,    0,
  1057. #endif /* TCPSOCKET */
  1058. #ifdef SUPERLAT
  1059.     "tes32",        NET_SLAT,   0,    /* Emulux TES32 */
  1060. #endif /* SUPERLAT */
  1061. #ifdef ANYX25                /* X.25 */
  1062. #ifdef SUNX25
  1063.     "x",            NET_SX25, CM_INV|CM_ABR,
  1064.     "x.25",         NET_SX25, 0,
  1065.     "x25",          NET_SX25, CM_INV,
  1066. #else
  1067. #ifdef STRATUSX25
  1068.     "x",            NET_VX25, CM_INV|CM_ABR,
  1069.     "x.25",         NET_VX25, 0,
  1070.     "x25",          NET_VX25, CM_INV,
  1071. #endif /* STRATUSX25 */
  1072. #endif /* SUNX25 */
  1073. #endif /* ANYX25 */
  1074.     "", 0, 0
  1075. };
  1076. int nnetkey = (sizeof(netkey) / sizeof(struct keytab)) - 1;
  1077.  
  1078. #ifndef NOTCPOPTS
  1079. #ifdef TCPSOCKET
  1080. #ifdef SOL_SOCKET
  1081.  
  1082. /* TCP options */
  1083.  
  1084. struct keytab tcpopt[] = {
  1085. #ifdef SO_KEEPALIVE
  1086.    "keepalive", XYTCP_KEEPALIVE, 0,
  1087. #endif /* SO_KEEPALIVE */
  1088. #ifdef SO_LINGER
  1089.    "linger", XYTCP_LINGER, 0,
  1090. #endif  /* SO_LINGER */
  1091. #ifdef TCP_NODELAY
  1092.    "nagle",  XYTCP_NODELAY, CM_INV,
  1093.    "nodelay", XYTCP_NODELAY, 0,
  1094. #endif /* TCP_NODELAY */
  1095. #ifdef SO_RCVBUF
  1096.    "recvbuf", XYTCP_RECVBUF, 0,
  1097. #endif /* SO_RCVBUF */
  1098. #ifdef SO_SNDBUF
  1099.    "sendbuf", XYTCP_SENDBUF, 0,
  1100. #endif /* SO_SNDBUF */
  1101.    "",0,0
  1102. };
  1103. int ntcpopt = (sizeof(tcpopt) / sizeof(struct keytab));
  1104. #endif /* SOL_SOCKET */
  1105. #endif /* TCPSOCKET */
  1106. #endif /* NOTCPOPTS */
  1107.  
  1108. #endif /* NETCONN */
  1109.  
  1110. /* Remote Command Table */
  1111.  
  1112. struct keytab remcmd[] = {
  1113. #ifndef NOSPL
  1114.     "as",     XZASG, CM_INV|CM_ABR,
  1115.     "asg",     XZASG, CM_INV,
  1116.     "assign",     XZASG, 0,
  1117. #endif /* NOSPL */
  1118.     "cd",        XZCWD, 0,
  1119.     "copy",      XZCPY, 0,
  1120.     "cwd",       XZCWD, CM_INV,
  1121.     "delete",    XZDEL, 0,
  1122.     "directory", XZDIR, 0,
  1123.     "help",      XZHLP, 0,
  1124. #ifndef NOPUSH
  1125.     "host",      XZHOS, 0,
  1126. #endif /* NOPUSH */
  1127. #ifndef NOFRILLS
  1128.     "kermit",    XZKER, 0,
  1129.     "login",     XZLGI, 0,
  1130.     "logout",    XZLGO, 0,
  1131.     "print",     XZPRI, 0,
  1132. #endif /* NOFRILLS */
  1133.     "pwd",       XZPWD, 0,
  1134. #ifndef NOSPL
  1135.     "query",     XZQUE, 0,
  1136. #endif /* NOSPL */
  1137.     "rename",    XZREN, 0,
  1138.     "set",       XZSET, 0,
  1139.     "space",     XZSPA, 0
  1140. #ifndef NOFRILLS
  1141. ,   "type",      XZTYP, 0,
  1142.     "who",       XZWHO, 0
  1143. #endif /* NOFRILLS */
  1144. };
  1145. int nrmt = (sizeof(remcmd) / sizeof(struct keytab));
  1146.  
  1147. struct keytab logtab[] = {
  1148. #ifdef DEBUG
  1149.     "debugging",    LOGD, 0,
  1150. #endif /* DEBUG */
  1151.     "packets",        LOGP, 0
  1152. #ifndef NOLOCAL
  1153. ,   "session",      LOGS, 0
  1154. #endif /* NOLOCAL */
  1155. #ifdef TLOG
  1156. ,   "transactions", LOGT, 0
  1157. #endif /* TLOG */
  1158. };
  1159. int nlog = (sizeof(logtab) / sizeof(struct keytab));
  1160.  
  1161. struct keytab writab[] = {
  1162. #ifndef NOSPL
  1163.     "append-file",     LOGW, CM_INV,
  1164. #endif /* NOSPL */
  1165.     "debug-log",       LOGD, 0,
  1166.     "error",           LOGE, 0,
  1167. #ifndef NOSPL
  1168.     "file",            LOGW, 0,
  1169. #endif /* NOSPL */
  1170.     "packet-log",      LOGP, 0,
  1171.     "screen",          LOGX, 0,
  1172. #ifndef NOLOCAL
  1173.     "session-log",     LOGS, 0,
  1174. #endif /* NOLOCAL */
  1175.     "sys$output",      LOGX, CM_INV,
  1176.     "transaction-log", LOGT, 0
  1177. #ifdef COMMENT
  1178. ,   "transactions",    LOGT, CM_INV
  1179. #endif /* COMMENT */
  1180. };
  1181. int nwri = (sizeof(writab) / sizeof(struct keytab));
  1182.  
  1183. static struct keytab clrtab[] = {    /* Keywords for CLEAR command */
  1184. #ifndef NOSPL
  1185. #ifdef CK_APC
  1186.     "apc",              CLR_APC,         0,
  1187. #endif /* CK_APC */
  1188.     "both",             CLR_DEV|CLR_INP, CM_INV,
  1189. #endif /* NOSPL */
  1190. #ifdef OS2
  1191.     "command-screen",   CLR_CMD,         0,
  1192. #endif /* OS2 */
  1193. #ifndef NOSPL
  1194.     "device",           CLR_DEV,         CM_INV|CM_ABR,
  1195.     "device-and-input", CLR_DEV|CLR_INP, 0,
  1196. #endif /* NOSPL */
  1197.     "device-buffer",    CLR_DEV,         0,
  1198. #ifndef NODIAL
  1199.     "dial-status",      CLR_DIA,     0,
  1200. #endif /* NODIAL */
  1201. #ifndef NOSPL
  1202.     "input-buffer",     CLR_INP,         0,
  1203. #endif /* NOSPL */
  1204.     "send-list",        CLR_SFL,         0,
  1205. #ifdef OS2
  1206.     "scrollback",       CLR_SCL,         CM_INV,
  1207.     "terminal-screen",  CLR_TRM,         0,
  1208. #endif /* OS2 */
  1209.     "", 0, 0
  1210. };
  1211. int nclear = (sizeof(clrtab) / sizeof(struct keytab)) - 1;
  1212.  
  1213. struct keytab clstab[] = {        /* Keywords for CLOSE command */
  1214. #ifndef NOSPL
  1215.     "append-file",     LOGW, CM_INV,
  1216. #endif /* NOSPL */
  1217. #ifdef DEBUG
  1218.     "debug-log",       LOGD, 0,
  1219. #endif /* DEBUG */
  1220.     "packet-log",      LOGP, 0
  1221. #ifndef NOSPL
  1222. ,   "read-file",       LOGR, 0
  1223. #endif /* NOSPL */
  1224. #ifndef NOLOCAL
  1225. ,   "session-log",     LOGS, 0
  1226. #endif /* NOLOCAL */
  1227. #ifdef TLOG
  1228. ,   "transaction-log", LOGT, 0
  1229. #endif /* TLOG */
  1230. #ifndef NOSPL
  1231. ,   "write-file",      LOGW, 0
  1232. #endif /* NOSPL */
  1233. };
  1234. int ncls = (sizeof(clstab) / sizeof(struct keytab));
  1235.  
  1236. /* SHOW command arguments */
  1237.  
  1238. struct keytab shotab[] = {
  1239. #ifndef NOSPL
  1240.     "alarm", SHALRM, 0,
  1241.     "arg",  SHARG, CM_INV|CM_ABR,
  1242.     "arguments", SHARG, 0,
  1243.     "args", SHARG, CM_INV,
  1244.     "arrays", SHARR, 0,
  1245. #endif /* NOSPL */
  1246.     "attributes", SHATT, 0,
  1247.     "character-sets", SHCSE, 0,
  1248.     "cmd",  SHCMD, CM_INV,
  1249.     "com",  SHCOM, CM_INV|CM_ABR,
  1250.     "comm", SHCOM, CM_INV|CM_ABR,
  1251.     "communications", SHCOM, 0,
  1252.     "command", SHCMD, 0,
  1253. #ifdef CK_SPEED
  1254.     "control-prefixing", SHCTL, 0,
  1255. #endif /* CK_SPEED */
  1256. #ifndef NOSPL
  1257.     "count", SHCOU, 0,
  1258. #endif /* NOSPL */
  1259.     "d",       SHDIA, CM_INV|CM_ABR,
  1260. #ifdef VMS
  1261.     "default", SHDFLT, 0,
  1262. #else
  1263.     "default", SHDFLT, CM_INV,
  1264. #endif /* VMS */
  1265. #ifndef NODIAL
  1266.     "dial", SHDIA, 0,
  1267. #endif /* NODIAL */
  1268. #ifndef NOLOCAL
  1269.     "escape", SHESC, 0,
  1270. #endif /* NOLOCAL */
  1271.     "exit", SHEXI, 0,
  1272.     "features", SHFEA, 0,
  1273.     "file", SHFIL, 0,
  1274. #ifndef NOSPL
  1275.     "functions", SHFUN, 0,
  1276.     "globals", SHVAR, 0,
  1277. #endif /* NOSPL */
  1278. #ifndef NOSETKEY
  1279.     "k",   SHKEY, CM_INV|CM_ABR,
  1280.     "key", SHKEY, 0,
  1281. #ifndef NOKVERBS
  1282.     "kverbs", SHKVB, 0,
  1283. #endif /* NOKVERBS */
  1284. #endif /* NOSETKEY */
  1285. #ifdef CK_LABELED
  1286.     "labeled-file-info", SHLBL, 0,
  1287. #endif /* CK_LABELED */
  1288. #ifndef NOCSETS
  1289.     "languages", SHLNG, 0,
  1290. #endif /* NOCSETS */
  1291. #ifndef NOSPL
  1292.     "macros", SHMAC, 0,
  1293. #endif /* NOSPL */
  1294. #ifndef NODIAL
  1295.     "modem", SHMOD, 0,
  1296. #else
  1297.     "modem-signals", SHCOM, CM_INV,
  1298. #endif /* NODIAL */
  1299. #ifndef NOLOCAL
  1300. #ifdef OS2MOUSE
  1301.     "mouse", SHMOU, 0,
  1302. #endif /* OS2MOUSE */
  1303. #endif /* NOLOCAL */
  1304. #ifdef NETCONN
  1305.     "network", SHNET, 0,
  1306. #endif /* NETCONN */
  1307. #ifdef ANYX25
  1308.     "pad", SHPAD, 0,
  1309. #endif /* ANYX25 */
  1310.     "parameters", SHPAR, CM_INV,
  1311.     "printer",  SHPRT, 0,
  1312. #ifdef CK_SPEED
  1313.     "prefixing", SHCTL, CM_INV,
  1314. #endif /* CK_SPEED */
  1315.     "protocol", SHPRO, 0,
  1316. #ifndef NOSPL
  1317.     "scripts", SHSCR, 0,
  1318. #endif /* NOSPL */
  1319.     "send-list", SHSFL, 0,
  1320. #ifndef NOSERVER
  1321.     "server", SHSER, 0,
  1322. #endif /* NOSERVER */
  1323.     "status", SHSTA, 0
  1324. #ifdef MAC
  1325. ,   "stack", SHSTK, 0            /* debugging */
  1326. #endif /* MAC */
  1327. #ifndef NOLOCAL
  1328. #ifdef OS2
  1329. ,   "tabs",SHTAB, CM_INV
  1330. #endif /* OS2 */
  1331. ,   "terminal", SHTER, 0
  1332. #endif /* NOLOCAL */
  1333. #ifndef NOXMIT
  1334. ,   "transmit", SHXMI, 0
  1335. #endif /* NOXMIT */
  1336. #ifndef NOSETKEY
  1337. #ifndef NOKVERBS
  1338. #ifdef OS2
  1339. ,    "udk", SHUDK, 0
  1340. #endif /* OS2 */
  1341. #endif /* NOKVERBS */
  1342. #endif /* NOSETKEY */
  1343. #ifndef NOSPL
  1344. ,   "variables", SHBUI, 0
  1345. #endif /* NOSPL */
  1346. #ifndef NOFRILLS
  1347. ,   "versions", SHVER, 0
  1348. #endif /* NOFRILLS */
  1349. #ifdef OS2
  1350. ,   "vscrn",    SHVSCRN, CM_INV
  1351. #endif /* OS2 */
  1352. #ifndef NOXMIT
  1353. ,   "xmit", SHXMI, CM_INV
  1354. #endif /* NOXMIT */
  1355. };
  1356. int nsho = (sizeof(shotab) / sizeof(struct keytab));
  1357.  
  1358. #ifdef ANYX25
  1359. struct keytab padtab[] = {              /* PAD commands */
  1360.     "clear",      XYPADL, 0,
  1361.     "interrupt",  XYPADI, 0,
  1362.     "reset",      XYPADR, 0,
  1363.     "status",     XYPADS, 0
  1364. };
  1365. int npadc = (sizeof(padtab) / sizeof(struct keytab));
  1366. #endif /* ANYX25 */
  1367.  
  1368. #ifndef NOSERVER
  1369. static struct keytab kmstab[] = {
  1370.     "both",    3, 0,
  1371.     "remote",  2, 0,
  1372.     "local",   1, 0
  1373. };
  1374.  
  1375. static struct keytab enatab[] = {    /* ENABLE commands */
  1376.     "all",        EN_ALL,  0,
  1377. #ifndef NOSPL
  1378.     "as",         EN_ASG,  CM_INV|CM_ABR,
  1379.     "asg",        EN_ASG,  CM_INV,
  1380.     "assign",     EN_ASG,  0,
  1381. #endif /* NOSPL */
  1382. #ifndef datageneral
  1383.     "bye",        EN_BYE,  0,
  1384. #endif /* datageneral */
  1385.     "cd",         EN_CWD,  0,
  1386. #ifdef ZCOPY
  1387.     "copy",       EN_CPY,  0,
  1388. #endif /* ZCOPY */
  1389.     "cwd",        EN_CWD,  CM_INV,
  1390.     "delete",     EN_DEL,  0,
  1391.     "directory",  EN_DIR,  0,
  1392.     "finish",     EN_FIN,  0,
  1393.     "get",        EN_GET,  0,
  1394.     "host",       EN_HOS,  0,
  1395.     "mail",       EN_MAI,  0,
  1396. #ifndef NOSPL
  1397.     "query",      EN_QUE,  0,
  1398. #endif /* NOSPL */
  1399.     "print",      EN_PRI,  0,
  1400.     "rename",     EN_REN,  0,
  1401.     "retrieve",   EN_RET,  0,
  1402.     "send",       EN_SEN,  0,
  1403.     "set",        EN_SET,  0,
  1404.     "space",      EN_SPA,  0,
  1405.     "type",       EN_TYP,  0,
  1406.     "who",        EN_WHO,  0
  1407. };
  1408. static int nena = (sizeof(enatab) / sizeof(struct keytab));
  1409. #endif /* NOSERVER */
  1410.  
  1411. #ifndef NOLOCAL
  1412. static struct keytab conntab[] = {    /* CONNECT options */
  1413.     "/quietly", 1, 0
  1414. };
  1415. #endif /* NOLOCAL */
  1416.  
  1417. #ifndef NOSPL
  1418. #ifdef COMMENT
  1419. struct mtab mactab[MAC_MAX] = {        /* Preinitialized macro table */
  1420.     NULL, NULL, 0
  1421. };
  1422. #else
  1423. struct mtab *mactab;            /* Dynamically allocated macro table */
  1424. #endif /* COMMENT */
  1425. int nmac = 0;
  1426.  
  1427. struct keytab mackey[MAC_MAX];        /* Macro names as command keywords */
  1428. #endif /* NOSPL */
  1429.  
  1430. #ifndef NOSPL
  1431. #ifdef  OS2
  1432. struct keytab beeptab[] = {      /* Beep options */
  1433.     "error", BP_FAIL, 0,
  1434.     "information", BP_NOTE, 0,
  1435.     "warning", BP_WARN, 0
  1436. };
  1437. int nbeeptab = sizeof(beeptab)/sizeof(struct keytab);
  1438.  
  1439. #define CLR_C_ALL 0
  1440. #define CLR_C_BOL 1
  1441. #define CLR_C_BOS 2
  1442. #define CLR_C_EOL 3
  1443. #define CLR_C_EOS 4
  1444. #define CLR_C_LIN 5
  1445. #define CLR_C_SCR 6
  1446.  
  1447. struct keytab clrcmdtab[] = {    /* CLEAR COMMMAND-SCREEN options */
  1448.     "all",     CLR_C_ALL, 0,
  1449.     "bol",     CLR_C_BOL, 0,
  1450.     "bos",     CLR_C_BOS, 0,
  1451.     "eol",     CLR_C_EOL, 0,
  1452.     "eos",     CLR_C_EOS, 0,
  1453.     "line",    CLR_C_LIN, 0,
  1454.     "scrollback", CLR_C_SCR, 0
  1455. };
  1456. int nclrcmd = sizeof(clrcmdtab)/sizeof(struct keytab);
  1457. #endif /* OS2 */
  1458. #endif /* NOSPL */
  1459.  
  1460. #ifndef NODIAL
  1461. static struct keytab looktab[] = {
  1462.     "dial", 0, 0
  1463. };
  1464. #endif /* NODIAL */
  1465.  
  1466. /* Forward declarations of functions */
  1467.  
  1468. _PROTOTYP (int doask,   ( int  ) );
  1469. _PROTOTYP (int dodef,   ( int  ) );
  1470. _PROTOTYP (int dodel,   ( void ) );
  1471. _PROTOTYP (int dodial,  ( int  ) );
  1472. _PROTOTYP (int dodir,   ( void ) );
  1473. _PROTOTYP (int doelse,  ( void ) );
  1474. _PROTOTYP (int dofor,   ( void ) );
  1475. _PROTOTYP (int dogta,   ( int  ) );
  1476. _PROTOTYP (int doincr,  ( int  ) );
  1477. _PROTOTYP (int dopaus,  ( int  ) );
  1478. _PROTOTYP (int doping,  ( void ) );
  1479. _PROTOTYP (int doftp,   ( void ) );
  1480. #ifndef NOFRILLS
  1481. _PROTOTYP (int dorenam, ( void ) );
  1482. #endif /* NOFRILLS */
  1483. #ifdef ZCOPY
  1484. _PROTOTYP (int docopy, ( void ) );
  1485. #endif /* ZCOPY */
  1486. #ifdef CK_REXX
  1487. _PROTOTYP (int dorexx,  ( void ) );
  1488. #endif /* CK_REXX */
  1489. #ifdef CK_REDIR
  1490. _PROTOTYP (int ttruncmd, ( char * ) );
  1491. #endif /* CK_REDIR */
  1492. _PROTOTYP (int dotype,   ( char * ) );
  1493.  
  1494. #ifdef TCPSOCKET
  1495. static struct keytab telcmd[] = {
  1496.    "do",   DO,   0,
  1497.    "dont", DONT, 0,
  1498.    "will", WILL, 0,
  1499.    "wont", WONT, 0
  1500. };
  1501.  
  1502. static struct keytab tnopts[] = {
  1503.     "binary", TELOPT_BINARY, 0,
  1504.     "echo", TELOPT_ECHO, 0,
  1505. #ifdef CK_NAWS
  1506.     "naws", TELOPT_NAWS, 0,
  1507. #endif /* CK_NAWS */
  1508.     "sga", TELOPT_SGA, 0,
  1509.     "ttype", TELOPT_TTYPE, 0,
  1510.     "", 0, 0
  1511. };
  1512. static int ntnopts = (sizeof(tnopts) / sizeof(struct keytab)) - 1;
  1513.  
  1514. int 
  1515. doftp() {
  1516.     char *p;
  1517.     int x;
  1518.  
  1519.     if (network)            /* If we have a current connection */
  1520.       strcpy(line,ttname);        /* get the host name */
  1521.     else *line = '\0';            /* as default host */
  1522.     for (p = line; *p; p++)        /* Remove ":service" from end. */
  1523.       if (*p == ':') { *p = '\0'; break; }
  1524.     if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
  1525.       return(x);
  1526. /* Construct FTP command */
  1527. #ifdef VMS
  1528. #ifdef MULTINET                /* TGV MultiNet */
  1529.     sprintf(line,"multinet ftp %s",s);
  1530. #else
  1531.     sprintf(line,"ftp %s",s);        /* Other VMS TCP/IP's */
  1532. #endif /* MULTINET */
  1533. #else                    /* Not VMS */
  1534.     sprintf(line,"ftp %s",s);
  1535. #endif /* VMS */
  1536.     conres();                /* Make console normal  */
  1537. #ifdef DEC_TCPIP
  1538.     printf("\n");            /* Prevent prompt-stomping */
  1539. #endif /* DEC_TCPIP */
  1540.     x = zshcmd(line);
  1541.     concb((char)escape);
  1542.     return(success = x);
  1543. }
  1544.    
  1545. int
  1546. doping() {
  1547.     char *p;
  1548.     int x;
  1549.  
  1550.     if (network)            /* If we have a current connection */
  1551.       strcpy(line,ttname);        /* get the host name */
  1552.     else *line = '\0';            /* as default host to be pinged. */
  1553.     for (p = line; *p; p++)        /* Remove ":service" from end. */
  1554.       if (*p == ':') { *p = '\0'; break; }
  1555.     if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
  1556.       return(x);
  1557. /* Construct PING command */
  1558. #ifdef VMS
  1559. #ifdef MULTINET                /* TGV MultiNet */
  1560.     sprintf(line,"multinet ping %s /num=1",s);
  1561. #else
  1562.     sprintf(line,"ping %s 56 1",s);    /* Other VMS TCP/IP's */
  1563. #endif /* MULTINET */
  1564. #else                    /* Not VMS */
  1565.     sprintf(line,"ping %s",s);
  1566. #endif /* VMS */
  1567.     conres();                /* Make console normal  */
  1568. #ifdef DEC_TCPIP
  1569.     printf("\n");            /* Prevent prompt-stomping */
  1570. #endif /* DEC_TCPIP */
  1571.     x = zshcmd(line);
  1572.     concb((char)escape);
  1573.     return(success = x);
  1574. }
  1575. #endif /* TCPSOCKET */
  1576.  
  1577. /*  D O C M D  --  Do a command  */
  1578.  
  1579. /*
  1580.  Returns:
  1581.    -2: user typed an illegal command
  1582.    -1: reparse needed
  1583.     0: parse was successful (even tho command may have failed).
  1584. */
  1585. int
  1586. docmd(cx) int cx; {
  1587.  
  1588.     debug(F101,"docmd entry, cx","",cx);
  1589.     activecmd = cx;
  1590.  
  1591. /*
  1592.   Massive switch() broken up into many smaller ones, for the benefit of
  1593.   compilers that run out of space when trying to handle large switch
  1594.   statements.
  1595. */
  1596.     switch (cx) {
  1597.       case -4:            /* EOF */
  1598. #ifdef OSK
  1599.     if (msgflg)  printf("\n");
  1600. #else
  1601.     if (msgflg)  printf("\r\n");
  1602. #endif /* OSK */
  1603.       doexit(GOOD_EXIT,xitsta);
  1604.       case -3:                /* Null command */
  1605.     return(0);
  1606.       case -9:                /* Like -2, but errmsg already done */
  1607.       case -1:                /* Reparse needed */
  1608.     return(cx);
  1609.       case -6:                /* Special */
  1610.       case -2:                /* Error, maybe */
  1611. #ifndef NOSPL
  1612. /*
  1613.   Maybe they typed a macro name.  Let's look it up and see.
  1614. */
  1615.     if (cx == -6)            /* If they typed CR */
  1616.       strcat(cmdbuf,"\015");    /*  add it back to command buffer. */
  1617.     if (ifcmd[cmdlvl] == 2)        /* Watch out for IF commands. */
  1618.       ifcmd[cmdlvl]--;
  1619.     repars = 1;            /* Force reparse */
  1620.     cmres();
  1621.     cx = XXDO;            /* Try DO command */
  1622. #else
  1623.     return(cx);
  1624. #endif /* NOSPL */
  1625.       default:
  1626.     break;
  1627.     }
  1628.  
  1629. #ifndef NOSPL
  1630. /* Copy macro args from/to two levels up, used internally by _floop et al. */
  1631.     if (cx == XXGTA || cx == XXPTA) {    /* _GETARGS, _PUTARGS */
  1632.     int x;
  1633.     debug(F101,"docmd XXGTA","",XXGTA);
  1634.     debug(F101,"docmd cx","",cx);
  1635.     debug(F101,"docmd XXGTA maclvl","",maclvl);
  1636.     x = dogta(cx);
  1637.     debug(F101,"docmd dogta returns","",x);
  1638.     debug(F101,"docmd dogta maclvl","",maclvl);
  1639.     return(x);
  1640.     }
  1641. #endif /* NOSPL */
  1642.  
  1643. #ifndef NOSPL
  1644. /* ASK, ASKQ, READ */
  1645.     if (cx == XXASK || cx == XXASKQ || cx == XXREA ||
  1646.     cx == XXRDBL || cx == XXGETC) {
  1647.     return(doask(cx));
  1648.     }
  1649. #endif /* NOSPL */
  1650.  
  1651. #ifndef NOFRILLS
  1652.     if (cx == XXBUG) {            /* BUG */
  1653.     if ((x = cmcfm()) < 0) return(x);
  1654.     return(dobug());
  1655.     }
  1656. #endif /* NOFRILLS */
  1657.  
  1658.     if (cx == XXBYE) {            /* BYE */
  1659.     bye_active = 1;
  1660. #ifdef CK_XYZ
  1661.     if (protocol != PROTO_K) {
  1662.         printf("Sorry, BYE only works with Kermit protocol\n");
  1663.         return(-9);
  1664.     }
  1665. #endif /* CK_XYZ */
  1666.     if ((x = cmcfm()) < 0) return(x);
  1667.     sstate = setgen('L',"","","");
  1668.     if (local) ttflui();        /* If local, flush tty input buffer */
  1669.     return(0);
  1670.     }
  1671.  
  1672. #ifndef NOSPL
  1673.     if ( cx == XXBEEP ) {        /* BEEP */
  1674.         int x;
  1675. #ifdef OS2
  1676.     int y;
  1677.         if ((y = cmkey( beeptab, nbeeptab, "which kind of beep", "information",
  1678.                xxstring)) < 0 )
  1679.       return (y);
  1680.         if ((x = cmcfm()) < 0) return(x);
  1681.         bleep(y);            /* y is one of the BP_ values */
  1682. #else  /* OS2 */
  1683.         if ((x = cmcfm()) < 0) return(x);
  1684.         bleep(BP_NOTE);
  1685. #endif /* OS2 */
  1686.         return(0);
  1687.     }
  1688. #endif /* NOSPL */
  1689.  
  1690. #ifndef NOFRILLS
  1691.     if (cx == XXCLE) {            /* CLEAR */
  1692.     if ((x = cmkey(clrtab,nclear,"item to clear",
  1693. #ifdef NOSPL
  1694.           "device-buffer"
  1695. #else
  1696.           "device-and-input"
  1697. #endif /* NOSPL */
  1698.           ,xxstring)) < 0) return(x);
  1699. #ifndef NOSPL
  1700. #ifdef OS2
  1701.         if ( x == CLR_CMD || x == CLR_TRM ) {
  1702.             if ((z = cmkey(clrcmdtab,nclrcmd,"how much screen to clear\n",
  1703.                "all",xxstring)) < 0)
  1704.           return(z);
  1705.         }
  1706. #endif /* OS2 */
  1707. #endif /* NOSPL */
  1708.     if ((y = cmcfm()) < 0) return(y);
  1709.  
  1710.     /* Clear device input buffer if requested */
  1711.     y = (x & CLR_DEV) ? ttflui() : 0;
  1712. #ifndef NOSPL
  1713.     /* Clear INPUT command buffer if requested */
  1714.     if (x & CLR_INP) {
  1715.         for (x = 0; x < inbufsize; x++)
  1716.           inpbuf[x] = NUL;
  1717.         inpbp = inpbuf;
  1718.         y = 0;
  1719.     }
  1720. #ifdef CK_APC
  1721.     if (x & CLR_APC) {
  1722.         apcactive = 0;
  1723.         y = 0;
  1724.     }
  1725. #endif /* CK_APC */
  1726. #endif /* NOSPL */
  1727.  
  1728. #ifndef NODIAL
  1729.     if (x & CLR_DIA) {
  1730.         dialsta = DIA_UNK;
  1731.         y = 0;
  1732.     }
  1733. #endif /* NODIAL */
  1734.  
  1735. #ifndef NOMSEND
  1736.     if (x & CLR_SFL) {        /* CLEAR SEND-LIST */
  1737.         if (filehead) {
  1738.         struct filelist * flp, * next;
  1739.         flp = filehead;
  1740.         while (flp) {
  1741.             if (flp->fl_name)
  1742.               free(flp->fl_name);
  1743.             if (flp->fl_alias)
  1744.               free(flp->fl_alias);
  1745.             next = flp->fl_next;
  1746.             free(flp);
  1747.             flp = next;
  1748.         }
  1749.         }
  1750.         filesinlist = 0;
  1751.         filehead = NULL;
  1752.         filetail = NULL;
  1753.         y = 0;
  1754.     }
  1755. #endif /* NOMSEND */
  1756.  
  1757. #ifdef OS2
  1758.     switch (x) {
  1759.       case CLR_SCL:
  1760.         clearscrollback(VTERM);
  1761.         break;
  1762.       case CLR_CMD:
  1763.         switch ( z ) {
  1764.           case CLR_C_ALL:
  1765.         clear();
  1766.         break;
  1767.           case CLR_C_BOS:
  1768.         clrboscr_escape(VCMD,SP);
  1769.         break;
  1770.           case CLR_C_BOL:
  1771.         clrbol_escape(VCMD,SP);
  1772.         break;
  1773.           case CLR_C_EOL:
  1774.         clrtoeoln(VCMD,SP);
  1775.         break;
  1776.           case CLR_C_EOS:
  1777.         clreoscr_escape(VCMD,SP);
  1778.         break;
  1779.           case CLR_C_LIN:
  1780.         clrline_escape(VCMD,SP);
  1781.         break;
  1782.           case CLR_C_SCR:
  1783.         clearscrollback(VCMD);
  1784.         break;
  1785.             default:
  1786.         printf("Not implemented yet, sorry.\n");
  1787.         break;
  1788.         }
  1789.         break;
  1790.  
  1791.       case CLR_TRM:
  1792.              switch ( z ) {
  1793.           case CLR_C_ALL:
  1794.                  if (VscrnGetBufferSize(VTERM) > 0 ) {
  1795.                      VscrnScroll(VTERM, UPWARD, 0, 
  1796.                  VscrnGetHeight(VTERM)-(tt_status?2:1),
  1797.                  VscrnGetHeight(VTERM) -
  1798.                  (tt_status?1:0), TRUE, SP
  1799.                  );
  1800.                      cleartermscreen(VTERM);
  1801.                  }
  1802.                  break;
  1803.           case CLR_C_BOS:
  1804.         clrboscr_escape(VTERM,SP);
  1805.         break;
  1806.           case CLR_C_BOL:
  1807.         clrbol_escape(VTERM,SP);
  1808.         break;
  1809.           case CLR_C_EOL:
  1810.         clrtoeoln(VTERM,SP);
  1811.         break;
  1812.           case CLR_C_EOS:
  1813.         clreoscr_escape(VTERM,SP);
  1814.         break;
  1815.           case CLR_C_LIN:
  1816.         clrline_escape(VTERM,SP);
  1817.         break;
  1818.              case CLR_C_SCR:
  1819.                  clearscrollback(VTERM);
  1820.                  break;
  1821.              default:
  1822.                  printf("Not implemented yet, sorry.\n");
  1823.                  break;
  1824.         }
  1825.         break;
  1826.     }
  1827.     y = 0;    
  1828. #endif /* OS2 */    
  1829.     return(success = (y == 0));
  1830.     }
  1831. #endif /* NOFRILLS */
  1832.  
  1833.     if (cx == XXCOM) {            /* COMMENT */
  1834.     if ((x = cmtxt("Text of comment line","",&s,NULL)) < 0)
  1835.       return(x);
  1836.     /* Don't change SUCCESS flag for this one */
  1837.     return(0);
  1838.     }
  1839.  
  1840. #ifndef NOLOCAL
  1841.     if (cx == XXCON) {            /* CONNECT */
  1842.     if ((x = cmkey(conntab,1,"Carriage return to confirm, or option",
  1843.                "",xxstring)) < 0) {
  1844.         if (x == -3)
  1845.           return(success = doconect(0));
  1846.         else return(x);
  1847.     }
  1848.     if ((y = cmcfm()) < 0)
  1849.       return(y);
  1850.     return(success = doconect(x));
  1851.     }
  1852. #endif /* NOLOCAL */
  1853.  
  1854. #ifndef NOFRILLS
  1855. #ifdef ZCOPY
  1856.     if (cx == XXCPY) {            /* COPY a file */
  1857. #ifdef CK_APC
  1858.     if (apcactive == APC_LOCAL || 
  1859.         apcactive == APC_REMOTE && apcstatus != APC_UNCH) return(success = 0);
  1860. #endif /* CK_APC */
  1861.     return(docopy());
  1862.     }
  1863. #endif /* ZCOPY */
  1864. #endif /* NOFRILLS */
  1865.  
  1866.     if (cx == XXCWD)            /* CWD */
  1867.       return(success = docd());
  1868.  
  1869.     if (cx == XXCHK)            /* CHECK */
  1870.       return(success = dochk());
  1871.  
  1872.     if (cx == XXCLO) {            /* CLOSE */
  1873.     x = cmkey(clstab,ncls,"Which log or file to close","",xxstring);
  1874.     if (x == -3) {
  1875.         printf("?You must say which file or log\n");
  1876.         return(-9);
  1877.     }
  1878.     if (x < 0) return(x);
  1879.     if ((y = cmcfm()) < 0) return(y);
  1880.     y = doclslog(x);
  1881.     success = (y == 1);
  1882.     return(success);
  1883.     }
  1884.  
  1885. #ifndef NOSPL
  1886.     if (cx == XXDEC || cx == XXINC)    /* DECREMENT, INCREMENT */
  1887.       return(doincr(cx));
  1888.  
  1889.     if (cx == XXEVAL) {
  1890.     char *p;
  1891.     if ((x = cmtxt("Integer arithmetic expression","",&s,xxstring)) < 0)
  1892.       return(x);
  1893.     p = evala(s);
  1894.     if (!p) p = "";
  1895.     if (*p)
  1896.       printf("%s\n", p);
  1897.     strncpy(evalbuf,p,32);
  1898.     return(success = *p ? 1 : 0);
  1899.     }
  1900. #endif /* NOSPL */
  1901.  
  1902. #ifndef NOSPL
  1903.     if (cx == XXDEF || cx == XXASS ||
  1904.     cx == XXDFX || cx == XXASX || cx == XXUNDEF)
  1905.       return(dodef(cx));        /* DEFINE, ASSIGN, etc... */
  1906. #endif /* NOSPL */
  1907.  
  1908. #ifndef NOSPL
  1909.     if (cx == XXDCL) {            /* DECLARE an array */
  1910.     if ((y = cmfld("Array name","",&s,NULL)) < 0) {
  1911.         if (y == -3) {
  1912.         printf("?Array name required\n");
  1913.         return(-9);
  1914.         } else return(y);
  1915.     }
  1916.     if ((y = arraynam(s,&x,&z)) < 0) return(y);
  1917.     if ((y = cmcfm()) < 0) return(y);
  1918.     if (dclarray((char)x,z) < 0) {
  1919.         printf("?Declare failed\n");
  1920.         return(success = 0);
  1921.     }
  1922.     return(success = 1);
  1923.     }
  1924. #endif /* NOSPL */
  1925.  
  1926. #ifndef NODIAL
  1927.     if (cx == XXRED  || cx == XXDIAL || cx == XXPDIA ||
  1928.     cx == XXANSW || cx == XXLOOK) { /* DIAL, REDIAL etc */
  1929.     x = dodial(cx);
  1930.     debug(F101,"dodial returns","",x);
  1931.     if ((cx == XXDIAL || cx == XXRED) &&
  1932.         (x > 0) &&            /* If DIAL or REDIAL succeeded */
  1933.         (dialcon > 0)) {
  1934.         if ( dialcon == 1 ||    /* And DIAL CONNECT is ON, */
  1935.         (dialcon == 2 &&    /* or DIAL CONNECT is AUTO */
  1936. #ifndef NOSPL                /* and we're at top level... */
  1937.          cmdlvl == 0
  1938. #else
  1939.          tlevel == -1         
  1940. #endif /* NOSPL */
  1941.          )) /* Or AUTO */
  1942.           x = doconect(dialcq);    /* Then also CONNECT */
  1943.     }
  1944.     return(success = x);
  1945.     }
  1946. #endif /* NODIAL */
  1947.  
  1948. #ifndef NOPUSH
  1949. #ifdef CK_REXX
  1950.     if (cx == XXREXX) {            /* REXX */
  1951.         extern int nopush;
  1952.         if ( nopush )
  1953.           return(success=0);
  1954.         return(dorexx());
  1955.     }
  1956. #endif /* CK_REXX */
  1957. #endif /* NOPUSH */
  1958.  
  1959. #ifndef NOFRILLS
  1960.     if (cx == XXDEL) {            /* DELETE */
  1961. #ifdef CK_APC
  1962.     if (apcactive == APC_LOCAL || 
  1963.         apcactive == APC_REMOTE && apcstatus != APC_UNCH) return(success = 0);
  1964. #endif /* CK_APC */
  1965.     return(dodel());
  1966.     }
  1967. #endif /* NOFRILLS */
  1968.  
  1969.     if (cx == XXDIR)            /* DIRECTORY */
  1970.       return(dodir());
  1971.  
  1972. #ifndef NOSPL
  1973.     if (cx == XXELS)            /* ELSE */
  1974.       return(doelse());
  1975. #endif /* NOSPL */
  1976.  
  1977. #ifndef NOSERVER
  1978. #ifndef NOFRILLS
  1979.     if (cx == XXENA || cx == XXDIS) {    /* ENABLE, DISABLE */
  1980.     s = (cx == XXENA) ?
  1981.       "Server function to enable" :
  1982.         "Server function to disable";
  1983.  
  1984.     if ((x = cmkey(enatab,nena,s,"",xxstring)) < 0) {
  1985.         if (x == -3) {
  1986.         printf("?Name of server function required\n");
  1987.         return(-9);
  1988.         } else return(x);
  1989.     }
  1990.     if ((y = cmkey(kmstab,3,"mode","both",xxstring)) < 0) {
  1991.         if (y == -3) {
  1992.         printf("?Please specify remote, local, or both\n");
  1993.         return(-9);
  1994.         } else return(y);
  1995.     }
  1996.     if (cx == XXDIS)        /* Disabling, not enabling */
  1997.       y = 3 - y; 
  1998.     if ((z = cmcfm()) < 0) return(z);
  1999. #ifdef CK_APC
  2000.     if (apcactive == APC_LOCAL || 
  2001.         apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  2002.       return(success = 0);
  2003. #endif /* CK_APC */
  2004.     return(doenable(y,x));
  2005.     }
  2006. #endif /* NOFRILLS */
  2007. #endif /* NOSERVER */
  2008.  
  2009. #ifndef NOSPL
  2010.     if (cx == XXRET) {            /* RETURN */
  2011.     if (cmdlvl == 0) {        /* At top level, nothing happens... */
  2012.         if ((x = cmcfm()) < 0)
  2013.           return(x);
  2014.         return(success = 1);
  2015.     } else if (cmdstk[cmdlvl].src == CMD_TF) { /* In TAKE file, like POP */
  2016.         if ((x = cmtxt("optional return value","",&s,NULL)) < 0)
  2017.           return(x);        /* Allow trailing text, but ignore. */
  2018.         if ((x = cmcfm()) < 0)
  2019.           return(x);
  2020.         popclvl();            /* pop command level */
  2021.         return(success = 1);    /* always succeeds */
  2022.     } else if (cmdstk[cmdlvl].src == CMD_MD) { /* Within macro */
  2023.         if ((x = cmtxt("optional return value","",&s,NULL)) < 0)
  2024.           return(x);
  2025.         return(doreturn(s));    /* Trailing text is return value. */
  2026.     } else return(-2);
  2027.     }
  2028. #endif /* NOSPL */
  2029.  
  2030. #ifndef NOSPL
  2031.     if (cx == XXDO) {            /* DO (a macro) */
  2032.     if (nmac == 0) {
  2033.         printf("\n?No macros defined\n");
  2034.         return(-2);
  2035.     }
  2036.     for (y = 0; y < nmac; y++) {    /* copy the macro table */
  2037.         mackey[y].kwd = mactab[y].kwd; /* into a regular keyword table */
  2038.         mackey[y].kwval = y;    /* with value = pointer to macro tbl */
  2039.         mackey[y].flgs = mactab[y].flgs;
  2040.     }
  2041.     /* parse name as keyword */
  2042.     if ((x = cmkey(mackey,nmac,"macro","",xxstring)) < 0) {
  2043.         if (x == -3) {
  2044.         printf("?Macro name required\n");
  2045.         return(-9);
  2046.         } else return(x);
  2047.     }
  2048.     if ((y = cmtxt("optional arguments","",&s,xxstring)) < 0)
  2049.       return(y);            /* get args */
  2050.     return(dodo(x,s,cmdstk[cmdlvl].ccflgs) < 1 ? (success = 0) : 1);
  2051.     }
  2052. #endif /* NOSPL */
  2053.  
  2054.     if (cx == XXECH || cx == XXXECH
  2055. #ifndef NOSPL
  2056.     || cx == XXAPC
  2057. #endif /* NOSPL */
  2058.     ) {                /* ECHO or APC */
  2059.     if ((x = cmtxt((cx == XXECH || cx == XXXECH) ?
  2060.                "Text to be echoed" :
  2061.                "Application Program Command text",
  2062.                "",&s,xxstring)) < 0)
  2063.       return(x);
  2064.     s = brstrip(s);            /* Strip braces */
  2065.     if (cx == XXECH) {        /* ECHO */
  2066.         printf("%s\n",s);
  2067.     } else if (cx == XXXECH) {    /* XECHO */
  2068.         printf("%s",s);
  2069.     } else {            /* APC */
  2070. #ifdef CK_APC
  2071.         if (apcactive == APC_LOCAL || 
  2072.             apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  2073.           return(success = 0);
  2074. #endif /* CK_APC */
  2075.         if (!local) {
  2076.         printf("%c_%s%c\\",ESC,s,ESC);
  2077. #ifdef UNIX
  2078.         fflush(stdout);
  2079. #endif /* UNIX */
  2080.  
  2081.         } else {
  2082. #ifndef NOSPL
  2083.         sprintf(tmpbuf,"%c_%s%c\\",ESC,s,ESC);
  2084.         return(success = dooutput(tmpbuf));
  2085. #else
  2086.         printf("%c_%s%c\\",ESC,s,ESC);
  2087. #endif /* NOSPL */
  2088.         }
  2089.     }
  2090.     return(1);            /* Always succeeds */
  2091.     }
  2092.  
  2093. #ifndef NOSPL
  2094.     if (cx == XXOPE)            /* OPEN */
  2095.       return(doopen());
  2096. #endif /* NOSPL */
  2097.  
  2098. #ifndef NOSPL
  2099.     if (cx == XXOUT) {            /* OUTPUT */
  2100.     int i;
  2101.  
  2102.     if ((x = cmtxt("Text to be output","",&s,NULL)) < 0)
  2103.       return(x);
  2104. #ifdef CK_APC
  2105.     if (apcactive == APC_LOCAL || 
  2106.         apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  2107.       return(success = 0);
  2108. #endif /* CK_APC */
  2109.     debug(F110,"OUTPUT 1",s,0);
  2110.     s = brstrip(s);            /* Strip enclosing braces, */
  2111.     debug(F110,"OUTPUT 2",s,0);
  2112. /*
  2113.   I don't think I could ever fully explain this in a million years...
  2114.   We have read the user's string without calling the variable-expander
  2115.   function.  Now, before we call it, we have to double backslashes that
  2116.   appear before \N, \B, \L, and \ itself, so the expander function will
  2117.   reduce them back to single backslashes, so when we call dooutput()...
  2118.   But it's more complicated than that.
  2119. */
  2120.     if (cmdgquo()) {        /* Only if COMMAND QUOTING ON ... */
  2121.         for (x = 0, y = 0; s[x]; x++, y++) {
  2122.         if (s[x] == CMDQ) {
  2123.             char c = s[x+1];
  2124.             if (c == 'n' || c == 'N' ||
  2125.             c == 'b' || c == 'B' ||
  2126.             c == 'l' || c == 'L' ||
  2127.             c == CMDQ)
  2128.               line[y++] = CMDQ;
  2129.         }
  2130.         line[y] = s[x];
  2131.         }
  2132.         line[y++] = '\0';        /* Now expand variables, etc. */
  2133.         debug(F110,"OUTPUT 3",line,0);
  2134.         s = line+y+1;
  2135.         x = LINBUFSIZ - (int) strlen(line) - 1;
  2136.         debug(F101,"OUTPUT size","",x);
  2137.         if (zzstring(line,&s,&x) < 0)
  2138.           return(success = 0);
  2139.         s = line+y+1;
  2140.         debug(F110,"OUTPUT 4",s,0);
  2141.     }
  2142.     success = dooutput(s);
  2143.     return(success);
  2144.     }
  2145. #endif /* NOSPL */
  2146.  
  2147. #ifdef ANYX25
  2148.     if (cx == XXPAD) {            /* PAD commands */
  2149.     x = cmkey(padtab,npadc,"PAD command","",xxstring);
  2150.     if (x == -3) {
  2151.         printf("?You must specify a PAD command to execute\n");
  2152.         return(-2);
  2153.     }
  2154.     if (x < 0) return(x);
  2155.  
  2156.     switch (x) {
  2157.       case XYPADL:
  2158.         if (x25stat() < 0)
  2159.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  2160.         else {
  2161.         x25clear();
  2162.         initpad();
  2163.         }
  2164.         break;
  2165.       case XYPADS:
  2166.         if (x25stat() < 0)
  2167.           printf("Not connected\r\n");
  2168.         else {
  2169.         extern int linkid, lcn;
  2170.         conol("Connected thru ");
  2171.         conol(ttname);
  2172.         printf(", Link id %d, Logical channel number %d\r\n",
  2173.                linkid,lcn);
  2174.         }
  2175.         break;
  2176.       case XYPADR:
  2177.         if (x25stat() < 0)
  2178.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  2179.         else
  2180.           x25reset(0,0);
  2181.         break;
  2182.       case XYPADI:
  2183.         if (x25stat() < 0)
  2184.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  2185.         else
  2186.           x25intr(0);
  2187.     }
  2188.     return(0);
  2189. }
  2190. #endif /* ANYX25 */
  2191.  
  2192. #ifndef NOSPL
  2193.     if (cx == XXPAU || cx == XXWAI || cx == XXMSL) /* PAUSE, WAIT, etc */
  2194.       return(dopaus(cx));
  2195. #endif /* NOSPL */
  2196.  
  2197. #ifndef NOFRILLS
  2198.     if (cx == XXPRI) {
  2199.     if ((x = cmifi("File to print","",&s,&y,xxstring)) < 0) {
  2200.         if (x == -3) {
  2201.         printf("?A file specification is required\n");
  2202.         return(-9);
  2203.         } else return(x);
  2204.     }
  2205.     if (y != 0) {
  2206.         printf("?Wildcards not allowed\n");
  2207.         return(-9);
  2208.     }
  2209.     strcpy(line,s);
  2210.     s = "";
  2211. #ifndef NT
  2212.     if ((x = cmtxt("Local print command options, or carriage return","",&s,
  2213.                xxstring)) < 0)
  2214.       return(x);
  2215. #endif /* NT */
  2216.     if ((x = cmcfm()) < 0)
  2217.       return(x);
  2218.     return(success = (zprint(s,line) == 0) ? 1 : 0);
  2219.     }
  2220.  
  2221. #ifdef TCPSOCKET
  2222.     if (cx == XXPNG)             /* PING an IP host */
  2223.       return(doping());
  2224.  
  2225.    if ( cx == XXFTP )            /* FTP an IP host */
  2226.       return(doftp());
  2227. #endif /* TCPSOCKET */
  2228.  
  2229.     if (cx == XXPWD) {            /* PWD */
  2230. #ifdef MAC
  2231.     char *pwp;
  2232. #else
  2233. #ifdef OS2
  2234.     char *pwp;
  2235. #endif
  2236. #endif /* MAC */
  2237.     if ((x = cmcfm()) < 0)
  2238.       return(x);
  2239. #ifndef MAC
  2240. #ifndef OS2
  2241.     xsystem(PWDCMD);
  2242.     return(success = 1);        /* blind faith */
  2243. #else
  2244.     if (pwp = zgtdir()) {
  2245.         printf("%s\n",pwp);
  2246.         return(success = ((int)strlen(pwp) > 0));
  2247.     } else return(success = 0);
  2248. #endif
  2249. #else
  2250.     if (pwp = zgtdir()) {
  2251.         printf("%s\n",pwp);
  2252.         return(success = ((int)strlen(pwp) > 0));
  2253.     } else return(success = 0);
  2254. #endif /* MAC */
  2255.     }
  2256.  
  2257. #endif /* NOFRILLS */
  2258.  
  2259.     if (cx == XXQUI || cx == XXEXI) {    /* EXIT, QUIT */
  2260.     if ((y = cmnum("exit status code","",10,&x,xxstring)) < 0) {
  2261.         if (y == -3)
  2262.           x = xitsta;
  2263.         else return(y);
  2264.     }
  2265.     if ((y = cmcfm()) < 0) return(y);
  2266.  
  2267.     if (!hupok(0))            /* Check if connection still open */
  2268.       return(success = 0);
  2269. #ifdef COMMENT
  2270. #ifndef NODIAL
  2271.     mdmhup();
  2272. #endif /* NODIAL */
  2273. #endif /* COMMENT */
  2274.  
  2275. #ifdef VMS
  2276.     doexit(GOOD_EXIT,x);
  2277. #else
  2278. #ifdef OSK
  2279. /* Returning any codes here makes the OS-9 shell print an error message. */
  2280.     doexit(GOOD_EXIT,-1);
  2281. #else
  2282. #ifdef datageneral
  2283.         doexit(GOOD_EXIT,x);
  2284. #else
  2285.     doexit(x,-1);
  2286. #endif /* datageneral */
  2287. #endif /* OSK */
  2288. #endif /* VMS */
  2289.     }
  2290.  
  2291. #ifndef NOFRILLS
  2292.     if (cx == XXERR) {            /* ERROR */
  2293. #ifdef CK_XYZ
  2294.     if (protocol != PROTO_K) {
  2295.         printf("Sorry, E-PACKET only works with Kermit protocol\n");
  2296.         return(-9);
  2297.     }
  2298. #endif /* CK_XYZ */
  2299.     if ((x = cmcfm()) < 0) return(x);
  2300.     ttflui();
  2301.     epktflg = 1;
  2302.     sstate = 'a';
  2303.     return(0);
  2304.     }
  2305. #endif /* NOFRILLS */
  2306.  
  2307.     if (cx == XXFIN) {            /* FINISH */
  2308. #ifdef CK_XYZ
  2309.     if (protocol != PROTO_K) {
  2310.         printf("Sorry, FINISH only works with Kermit protocol\n");
  2311.         return(-9);
  2312.     }
  2313. #endif /* CK_XYZ */
  2314.     if ((x = cmcfm()) < 0) return(x);
  2315.     sstate = setgen('F',"","","");
  2316.     if (local) ttflui();        /* If local, flush tty input buffer */
  2317.     return(0);
  2318.     }
  2319.  
  2320. #ifndef NOSPL
  2321.     if (cx == XXFOR)            /* FOR loop */
  2322.       return(dofor());
  2323. #endif /* NOSPL */
  2324.  
  2325.     /* GET MGET REGET RETRIEVE etc */
  2326.     if (cx == XXGET || cx == XXREGET || cx == XXRETR) {
  2327. #ifdef CK_XYZ
  2328.     if (protocol != PROTO_K) {
  2329.         printf("Sorry, \"%s\" only works with Kermit protocol\n", atmbuf);
  2330.         return(-9);
  2331.     }
  2332. #endif /* CK_XYZ */
  2333.     x = cmtxt("Name of remote file(s), or carriage return","",&cmarg,
  2334.           xxstring);
  2335. #ifndef NOFRILLS
  2336.     if ((x == -2) || (x == -1)) return(x);
  2337. #else
  2338.     if (x < 0) return(x);
  2339. #endif /* NOFRILLS */
  2340.     cmarg = brstrip(cmarg);        /* Strip braces */
  2341.     x = doget(cx);
  2342. #ifdef MAC
  2343.     what = W_RECV;
  2344.     if (sstate == 'r')
  2345.         scrcreate();
  2346. #endif /* MAC */
  2347.     return(x);
  2348.     }
  2349.  
  2350. #ifndef NOSPL
  2351. #ifndef NOFRILLS
  2352.     if (cx == XXGOK) {            /* GETOK */
  2353.     return(success = doask(cx));
  2354.     }
  2355. #endif /* NOFRILLS */
  2356. #endif /* NOSPL */
  2357.  
  2358.     if (cx == XXHLP) {            /* HELP */
  2359. #ifdef NOHELP
  2360.     return(dohlp(XXHLP));
  2361. #else
  2362.     x = cmkey2(cmdtab,ncmd,"C-Kermit command","help",toktab,xxstring,1);
  2363.     debug(F101,"HELP command x","",x);
  2364.     if (x == -5) {
  2365.         y = chktok(toktab);
  2366.         debug(F101,"top-level cmkey token","",y);
  2367.         ungword();
  2368.         switch (y) {
  2369. #ifndef NOPUSH
  2370.           case '!': x = XXSHE; break;
  2371. #endif /* NOPUSH */
  2372.           case '#': x = XXCOM; break;
  2373.           case ';': x = XXCOM; break;
  2374. #ifndef NOSPL
  2375.           case ':': x = XXLBL; break;
  2376. #endif /* NOSPL */
  2377.           case '&': x = XXECH; break;
  2378.           default:
  2379.         printf("\n?Invalid - %s\n",cmdbuf);
  2380.         x = -2;
  2381.         }
  2382.     }
  2383.     return(dohlp(x));
  2384. #endif /* NOHELP */
  2385.     }
  2386.  
  2387. #ifndef NOHELP
  2388.     if (cx == XXINT)            /* INTRO */
  2389.       return(hmsga(introtxt));
  2390.     if (cx == XXNEW)            /* NEWS */
  2391.       return(hmsga(newstxt));
  2392. #ifdef OS2ONLY
  2393.     if (cx == XXUPD) {            /* View UPDATE file */
  2394.         extern char exedir[];
  2395.         char * pTopic;
  2396.         char updstr[2048];
  2397.         if ((x = cmtxt("topic name","",&pTopic,xxstring)) < 0)
  2398.             return x;
  2399.     sprintf(updstr,
  2400.         "start view %s\\docs\\k2.inf+%s\\docs\\using_ck.inf+\
  2401. %s\\docs\\dialing.inf+%s\\docs\\modems.inf %s",
  2402.         exedir,exedir,exedir,exedir,pTopic
  2403.         );
  2404.         system(updstr);
  2405.         return(success = 1);
  2406.     }
  2407. #endif /* OS2ONLY */
  2408. #endif /* NOHELP */
  2409.  
  2410.     if (cx == XXHAN) {            /* HANGUP */
  2411.     if ((x = cmcfm()) < 0) return(x);
  2412. #ifndef NODIAL
  2413.     if ((x = mdmhup()) < 1)
  2414. #endif /* NODIAL */
  2415.       x = (tthang() > -1);
  2416. #ifdef OS2
  2417.     if (x)
  2418.       DialerSend(OPT_KERMIT_HANGUP, 0);
  2419. #endif /* OS2 */
  2420.     return(success = x);
  2421.     }
  2422.  
  2423. #ifndef NOSPL
  2424.     if (cx == XXGOTO || cx == XXFWD || cx == XXXFWD) { /* GOTO or FORWARD */
  2425. /* Note, here we don't set SUCCESS/FAILURE flag */
  2426.     if ((y = cmfld("label","",&s,xxstring)) < 0) {
  2427.         if (y == -3) {
  2428.         printf("?Label name required\n");
  2429.         return(-9);
  2430.         } else return(y);
  2431.     }
  2432.     strncpy(lblbuf,s,LBLSIZ);
  2433.     if ((x = cmcfm()) < 0) return(x);
  2434.     s = lblbuf;
  2435.     return(dogoto(s,cx));
  2436.     }
  2437. #endif /* NOSPL */
  2438.  
  2439. #ifndef NOSPL
  2440. /* IF, Extended IF, WHILE */
  2441.     if (cx == XXIF || cx == XXIFX || cx == XXWHI) {
  2442.     return(doif(cx));
  2443.     }
  2444.     if (cx == XXSWIT) {
  2445.     return(doswitch());
  2446.     }
  2447. #endif /* NOSPL */
  2448.  
  2449. #ifndef NOSPL
  2450.     /* INPUT, REINPUT, and MINPUT */
  2451.  
  2452.     if (cx == XXINP || cx == XXREI
  2453. #ifdef CK_MINPUT
  2454.     || cx == XXMINP
  2455. #endif /* CK_MINPUT */
  2456.     ) {
  2457.     long zz;
  2458.     extern int x_ifnum;
  2459.  
  2460.     sprintf(tmpbuf,"%d",indef);
  2461.     zz = -1L;
  2462.     x_ifnum = 1;            /* Turn off internal complaints */
  2463.     y = cmnum("seconds to wait for input, or time of day hh:mm:ss",
  2464.           (char *)tmpbuf, 10, &x, xxstring
  2465.           );
  2466.     x_ifnum = 0;
  2467.     if (y < 0) {
  2468.         if (y == -2) {        /* Invalid number or expression */
  2469.         zz = tod2sec(atmbuf);    /* Convert to secs since midnight */
  2470.         if (zz < 0L) {
  2471.             printf("?Number, expression, or time of day required\n");
  2472.             return(-9);
  2473.         } else {
  2474.             char now[32];    /* Current time */
  2475.             char *p;
  2476.             long tnow;
  2477.             p = now;
  2478.             ztime(&p);
  2479.             tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
  2480.             if (zz < tnow)    /* User's time before now */
  2481.               zz += 86400L;    /* So make it tomorrow */
  2482.             zz -= tnow;        /* Seconds from now. */
  2483.         }
  2484.         } else
  2485.           return(y);
  2486.     }
  2487.     if (zz > -1L) {
  2488.         x = zz;
  2489.         if (zz != (long) x) {
  2490.         printf(
  2491. "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
  2492.                );
  2493.         return(-9);
  2494.         }
  2495.     }
  2496.     for (y = 0; y < MINPMAX; y++) {    /* Initialize strings */
  2497.         if (ms[y]) {
  2498.         free(ms[y]);        /* Free old strings, if any */
  2499.         ms[y] = NULL;
  2500.         }
  2501.     }
  2502. #ifdef CK_MINPUT
  2503.     if (cx == XXMINP) {        /* MINPUT */
  2504.         int res = 0;
  2505.         for (y = 0; y < MINPMAX; y++) { /* Parse up to MINPMAX strings */
  2506.                 res = cmfld("List of input strings","",&s,xxstring);
  2507.                 if (res < 0) return(res);
  2508.         debug(F110,"MINPUT cmfld returns",s,0);
  2509.                 if (*s == '{') {
  2510.             char *ss;
  2511.             int n;
  2512.             ss = s; n = 0;
  2513.             while (*ss) {*ss = *(ss+1); ss++; n++; }
  2514.             while (--n > 0) if (s[n] == '}') break;
  2515.             if (n > 0) {
  2516.             ss = s + n;
  2517.             while (*ss) {*ss = *(ss+1); ss++; n++; }
  2518.             }
  2519.                 }
  2520.         if (!(ms[y] = malloc((int)strlen(s) + 1))) { /* Get memory */
  2521.             printf("?Memory allocation failure\n");
  2522.             return(-9);
  2523.         }
  2524.         strcpy(ms[y],s);    /* Got memory, copy. */
  2525.                 if (res == 1) break;
  2526.             }
  2527.         for (y++; y < MINPMAX; y++) { /* Clean up old strings */
  2528.         if (ms[y]) {
  2529.             free(ms[y]);    /* Free old strings, if any */
  2530.             ms[y] = NULL;
  2531.         }
  2532.             }
  2533. #ifdef DEBUG
  2534.         if (deblog) {        /* Check the parsing */
  2535.         for (y = 0; y < MINPMAX; y++)
  2536.           if (ms[y]) debug(F111,"MINPUT",ms[y],y);
  2537.         }
  2538. #endif /* DEBUG */
  2539.     
  2540.     } else
  2541. #endif /* CK_MINPUT */
  2542.     {
  2543.         if ((y = cmtxt("Material to be input","",&s,xxstring)) < 0)
  2544.           return(y);
  2545.  
  2546.         s = brstrip(s);
  2547.         if (!(ms[0] = malloc((int)strlen(s) + 1))) { /* Get memory */
  2548.         printf("?Memory allocation failure\n");
  2549.         return(-9);
  2550.         }
  2551.         strcpy(ms[0],s);        /* Got memory, copy. */
  2552.         ms[1] = NULL;
  2553.     }
  2554.     if (cx == XXINP            /* INPUT */
  2555. #ifdef CK_MINPUT
  2556.         || cx == XXMINP        /* or MINPUT */
  2557. #endif /* CK_MINPUT */
  2558.         ) {
  2559.         i_active = 1;
  2560.         success = doinput(x,ms);    /* Go try to input the search string */
  2561.         i_active = 0;
  2562.     } else {            /* REINPUT */
  2563.         debug(F110,"xxrei line",s,0);
  2564.         success = doreinp(x,s);
  2565.     }
  2566.     if (intime[cmdlvl] && !success) { /* TIMEOUT-ACTION = QUIT? */
  2567.         popclvl();            /* If so, pop command level. */
  2568.         if (pflag && cmdlvl == 0) {
  2569.         if (cx == XXINP)  printf("?INPUT timed out\n");
  2570.         if (cx == XXMINP) printf("?MINPUT timed out\n");
  2571.         if (cx == XXREI)  printf("?REINPUT failed\n");
  2572.         }
  2573.     }
  2574.     return(success);        /* Return do(re)input's return code */
  2575.     }
  2576.  
  2577. #endif /* NOSPL */
  2578.  
  2579. #ifndef NOSPL
  2580.     if (cx == XXLBL) {            /* LABEL */
  2581.     if ((x = cmfld("label","",&s,xxstring)) < 0) {
  2582.         if (x == -3) {
  2583.         printf("?Label name required\n");
  2584.         return(-9);
  2585.         } else return(x);
  2586.     }
  2587.     if ((x = cmcfm()) < 0) return(x);
  2588.     return(0);
  2589.     }
  2590. #endif /* NOSPL */
  2591.  
  2592.     if (cx == XXLOG) {            /* LOG */
  2593.     x = cmkey(logtab,nlog,"What to log","",xxstring);
  2594.     if (x == -3) {
  2595.         printf("?Type of log required\n");
  2596.         return(-9);
  2597.     }
  2598.     if (x < 0) return(x);
  2599.     x = dolog(x);
  2600.     if (x < 0)
  2601.       return(x);
  2602.     else
  2603.       return(success = x);
  2604.     }
  2605.  
  2606. #ifndef NOSCRIPT
  2607.     if (cx == XXLOGI) {            /* UUCP-style script */
  2608.     if ((x = cmtxt("expect-send expect-send ...","",&s,xxstring)) < 0)
  2609.       return(x);
  2610. #ifdef CK_APC
  2611.     if (apcactive == APC_LOCAL || 
  2612.         apcactive == APC_REMOTE && apcstatus != APC_UNCH) return(success = 0);
  2613. #endif /* CK_APC */
  2614. #ifdef VMS
  2615.     conres();            /* For Ctrl-C to work... */
  2616. #endif /* VMS */
  2617.     return(success = dologin(s));    /* Return 1=completed, 0=failed */
  2618.     }
  2619. #endif /* NOSCRIPT */
  2620.  
  2621.     if (cx == XXREC) {            /* RECEIVE */
  2622.     cmarg2 = "";
  2623.  
  2624. #ifdef COMMENT /* wrong place for this -- see protocol module */
  2625. #ifdef CK_TMPDIR
  2626.     if (dldir && !f_tmpdir) {    /* If they have a download directory */
  2627.         if (s = zgtdir()) {        /* Get current directory */
  2628.         if (zchdir(dldir)) {    /* Change to download directory */
  2629.             strncpy(savdir,s,TMPDIRLEN);
  2630.             f_tmpdir = 1;    /* Remember that we did this */
  2631.         }
  2632.         }
  2633.     }
  2634. #endif /* CK_TMPDIR */
  2635. #endif /* COMMENT */
  2636.  
  2637. #ifdef CK_XYZ
  2638.     if (protocol == PROTO_X) {
  2639.         x = cmofi("Name for incoming file", "", &s, xxstring);
  2640.     } else {
  2641. #endif /* CK_XYZ */
  2642.         x = cmofi(
  2643. #ifdef CK_TMPDIR
  2644. "\nName under which to store the (first) incoming file, or:\n\
  2645.  name of directory in which to store all the file(s), or:\n\
  2646.  confirm the command now to store the files in the current\n\
  2647.  directory under their own names.",
  2648. #else
  2649. "Name under which to store the file, or confirm to accept\n\
  2650.  the file with its own name.",
  2651. #endif /* CK_TMPDIR */
  2652.               "", &s, xxstring
  2653.               );
  2654. #ifdef CK_XYZ
  2655.     }
  2656. #endif /* CK_XYZ */
  2657.     if ((x == -1) || (x == -2) || (x == -9)) {
  2658. #ifdef CK_TMPDIR
  2659.         if (f_tmpdir) {
  2660.         zchdir(savdir);
  2661.         f_tmpdir = 0;
  2662.         }
  2663. #endif /* CK_TMPDIR */
  2664.         return(x);
  2665.     }
  2666. #ifdef CK_XYZ
  2667.     if (protocol == PROTO_X && x == -3) {
  2668.         printf(
  2669. "Sorry, you must specify a name when receiving a file with XMODEM protocol\n");
  2670. #ifdef CK_TMPDIR
  2671.         if (f_tmpdir) {
  2672.         zchdir(savdir);
  2673.         f_tmpdir = 0;
  2674.         }
  2675. #endif /* CK_TMPDIR */
  2676.         return(-9);
  2677.     }
  2678. #endif /* CK_XYZ */
  2679.     strcpy(line,s);
  2680.     if ((x = cmcfm()) < 0) {
  2681. #ifdef CK_TMPDIR
  2682.         if (f_tmpdir) {
  2683.         zchdir(savdir);
  2684.         f_tmpdir = 0;
  2685.         }
  2686. #endif /* CK_TMPDIR */
  2687.         return(x);
  2688.     }
  2689. #ifdef CK_TMPDIR
  2690. /*
  2691.    User can give a device &/or directory specification here,
  2692.    rather than an alternative filename.
  2693. */
  2694.     x = strlen(line);
  2695.     if (
  2696. #ifdef OS2
  2697.         (isalpha(line[0]) &&
  2698.          line[1] == ':' &&
  2699.          line[2] == '\0') ||
  2700.         isdir(line)
  2701. #else
  2702. #ifdef UNIX
  2703.         (x > 0 && line[x-1] == '/') || isdir(line)
  2704. #else
  2705. #ifdef VMS
  2706.         (x > 0) && isdir(line)
  2707. #else
  2708. /*
  2709.   Others -- Maybe this will work; if not, add another #ifdef..#endif.
  2710.   CK_TMPDIR should not be defined without an isdir() function.
  2711. */
  2712.         (x > 0) && isdir(line)
  2713. #endif /* VMS */
  2714. #endif /* UNIX */
  2715. #endif /* OS2 */
  2716.         ) {
  2717.         debug(F110,"DOWNLOAD arg disk or dir",line,0);
  2718.         if (!f_tmpdir) {    /* If not already cd'd to download directory */
  2719.         s = zgtdir();        /* Get current directory */
  2720.         if (s) {        /* Save it */
  2721.             strncpy(savdir,s,TMPDIRLEN);
  2722.             f_tmpdir = 1;    /* Remember that we did this */
  2723.             cmarg2 = "";    /* and we don't have an as-name. */
  2724.         } else {
  2725.             printf("?Can't get current directory\n");
  2726.             return(-9);
  2727.         }
  2728.         }
  2729.         if (!zchdir(line)) {    /* Change to given disk/directory, */
  2730.         printf("?Can't access %s\n",line);
  2731.         return(-9);
  2732.         }
  2733.     } else                /* It's an alternative filename */
  2734. #endif /* CK_TMPDIR */
  2735.       cmarg2 = line;
  2736.  
  2737.     debug(F111,"cmofi cmarg2",cmarg2,x);
  2738.     sstate = 'v';
  2739. #ifdef MAC
  2740.     what = W_RECV;
  2741.     scrcreate();
  2742. #endif /* MAC */
  2743.     if (local) displa = 1;
  2744.     return(0);
  2745.     }
  2746.  
  2747.     if (cx == XXREM) {            /* REMOTE */
  2748. #ifdef CK_XYZ
  2749.     if (protocol != PROTO_K) {
  2750.         printf("Sorry, REMOTE commands only work with Kermit protocol\n");
  2751.         return(-9);
  2752.     }
  2753. #endif /* CK_XYZ */
  2754.     x = cmkey(remcmd,nrmt,"Remote Kermit server command","",xxstring);
  2755.     if (x == -3) {
  2756.         printf("?You must specify a command for the remote server\n");
  2757.         return(-9);
  2758.     }
  2759.     return(dormt(x));
  2760.     }
  2761.  
  2762. #ifndef NOFRILLS
  2763.     if (cx == XXREN) {            /* RENAME */
  2764. #ifdef CK_APC
  2765.     if (apcactive == APC_LOCAL || 
  2766.         apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  2767.       return(success = 0);
  2768. #endif /* CK_APC */
  2769.     return(dorenam());
  2770.     }
  2771. #endif /* NOFRILLS */
  2772.  
  2773.     if (cx == XXEIGHT) {        /* EIGHTBIT */
  2774.     extern int parity, cmask, cmdmsk;
  2775.     if ((x = cmcfm()) < 0)
  2776.       return(x);
  2777.     parity = 0;
  2778.     cmask = 0xff;
  2779.     cmdmsk = 0xff;
  2780.     return(success = 1);
  2781.     }
  2782.  
  2783.     if (cx == XXSEN  || cx == XXMAI     /* SEND, MAIL */
  2784.     || cx == XXMOVE            /* MOVE */
  2785.     || cx == XXADD            /* ADD */
  2786. #ifdef CK_RESEND
  2787.     || cx == XXRSEN || cx == XXPSEN /* RESEND, PSEND */
  2788. #endif /* CK_RESEND */
  2789.     ) {
  2790.  
  2791. #ifdef CK_RESEND
  2792.     int seekto = 0;
  2793.     int filemode = XYFT_B;
  2794. #endif /* CK_RESEND */
  2795.  
  2796. #ifndef NOMSEND
  2797.     char * fmode = "";
  2798.     int xmode = 0;
  2799.  
  2800.     if (cx == XXADD) {
  2801.         if ((x = cmkey(addtab,
  2802.                naddtab,"Name of list","send-list",xxstring)) < 0)
  2803.           return(x);
  2804. #ifndef XYZ_INTERNAL
  2805.         if (protocol != PROTO_K) {
  2806.         printf(
  2807.         "?Sorry, ADD SEND-LIST does not work with external protocols\n"
  2808.                );
  2809.         return(-9);
  2810.         }
  2811. #endif /* XYZ_INTERNAL */
  2812.     }
  2813. #endif /* NOMSEND */
  2814.  
  2815. #ifdef CK_RESEND
  2816.     if (cx == XXRSEN && binary != XYFT_B
  2817. #ifdef VMS
  2818.         && binary != XYFT_I
  2819. #endif /* VMS */
  2820.         ) {
  2821.         printf(
  2822. #ifdef VMS
  2823.            "?Sorry, FILE TYPE must be BINARY\n"
  2824. #else
  2825.            "?Sorry, FILE TYPE must be BINARY or IMAGE\n"
  2826. #endif /* VMS */
  2827.            );
  2828.         return(-9);
  2829.     }
  2830. #ifdef CK_XYZ
  2831.     if (cx == XXRSEN) {
  2832.         if (protocol != PROTO_K && protocol != PROTO_Z) {
  2833.         printf(
  2834. "Sorry, RESEND is only possible with Kermit or ZMODEM protocol\n"
  2835.                );
  2836.         return(-9);
  2837.         
  2838.         }
  2839.     }
  2840. #endif /* CK_XYZ */
  2841. #endif /* CK_RESEND */
  2842.     if ((cx == XXMAI        /* MAIL */
  2843. #ifdef CK_RESEND
  2844.          || cx == XXRSEN        /* RESEND */
  2845. #endif /* CK_RESEND */
  2846.          ) &&
  2847.         (!atdiso || !atcapr)) {    /* Disposition attribute off? */
  2848.         printf("?Sorry, ATTRIBUTE DISPOSITION must be ON\n");
  2849.         return(-9);
  2850.     }
  2851.     cmarg = cmarg2 = "";
  2852. #ifdef CK_XYZ
  2853.     if (protocol == PROTO_X)
  2854.       x = cmifi("File to send","",&s,&y,xxstring);
  2855.     else
  2856. #endif /* CK_XYZ */
  2857.       x = cmifi("File(s) to send","",&s,&y,xxstring);
  2858.     if (x < 0) {
  2859.         if (x == -3) {
  2860. #ifndef NOMSEND
  2861.         if (filehead) {    /* SEND by itself with ADD list? */
  2862.             nfils = filesinlist;
  2863.             sndsrc = nfils;    /* Like MSEND */
  2864.             addlist = 1;    /* But using a different list... */
  2865.             filenext = filehead;
  2866.             sstate = 's';
  2867.             goto sendend;
  2868.         } else {        /* Oops, no list. */
  2869.             printf("?No send list - use ADD to make one.\n");
  2870.             return(-9);
  2871.         }
  2872. #else
  2873.         printf("?A file specification is required\n");
  2874.         return(-9);
  2875. #endif /* NOMSEND */
  2876.         } else return(x);
  2877.     }
  2878. #ifdef CK_XYZ
  2879.     if (y != 0 && protocol == PROTO_X) {
  2880.         printf(
  2881. "Sorry, you can only send one file at a time with XMODEM protocol\n"
  2882.            );
  2883.         return(-9);
  2884.     }
  2885. #endif /* CK_XYZ */
  2886.  
  2887.     nfils = -1;            /* Files come from internal list. */
  2888. #ifndef NOMSEND
  2889.         addlist = 0;            /* Don't use SEND-LIST. */
  2890.         filenext = NULL;
  2891. #endif /* NOMSEND */
  2892.     strcpy(line,s);            /* Save copy of string just parsed. */
  2893. #ifndef NOMSEND
  2894.     if (cx == XXADD) {
  2895.         if (filesinlist == 0)    /* Take care of \v(filespec) */
  2896.           fspec[0] = NUL;
  2897.         if (((int)strlen(fspec) + (int)strlen(s) + 1) < CKMAXPATH) {
  2898.         strcat(fspec,s);
  2899.         strcat(fspec," ");
  2900.         } else printf("WARNING - \\v(filespec) buffer overflow\n");
  2901.     } else
  2902. #endif /* NOMSEND */
  2903.       strncpy(fspec,s,CKMAXPATH);
  2904.  
  2905. #ifdef CK_RESEND
  2906.     if (cx == XXPSEN) {        /* PSEND */
  2907.         if (y != 0) {
  2908.         printf("?Sorry, wildcards not permitted in this command\n");
  2909.         return(-9);
  2910.         }
  2911.         if (sizeof(int) < 4) {
  2912.         printf("?Sorry, this command needs 32-bit integers\n");
  2913.         return(-9);
  2914.         }
  2915. #ifdef CK_XYZ
  2916.         if (protocol != PROTO_K) {
  2917.         printf("?Sorry, PSEND works only with Kermit protocol\n");
  2918.         return(-9);
  2919.         }
  2920. #endif /* CK_XYZ */
  2921.         x = cmnum("starting position (byte number)",
  2922.               "",10,&seekto,xxstring);
  2923.         if (x < 0)
  2924.           return(x);
  2925.     }
  2926. #endif /* CK_RESEND */
  2927. #ifndef NOMSEND
  2928.     if (cx == XXADD) {
  2929.         extern struct keytab fttab[];
  2930.         extern int nfttyp;
  2931.  
  2932.         fmode = gfmode(binary);
  2933.         if ((x = cmkey(fttab,nfttyp,
  2934.                "type of file transfer", fmode, xxstring)) < 0)
  2935.           return(x);
  2936.         xmode = x;
  2937.     }
  2938. #endif /* NOMSEND */
  2939.     if (cx == XXSEN            /* SEND command */
  2940.         || cx == XXMOVE        /* MOVE command */
  2941.         || cx == XXADD        /* ADD command */
  2942. #ifdef CK_RESEND
  2943.         || cx == XXRSEN || cx == XXPSEN /* RESEND or PSEND command */
  2944. #endif /* CK_RESEND */
  2945.         ) {
  2946.         debug(F101,"Send: wild","",y);
  2947.         if (y == 0) {
  2948.         if ((x = cmtxt("Name to send it with","",&cmarg2,
  2949.                    xxstring)) < 0)
  2950.           return(x);
  2951.         } else {
  2952.         if ((x = cmcfm()) < 0) return(x);
  2953.         }
  2954.         cmarg = line;        /* File to send */
  2955.         debug(F110,"Sending:",cmarg,0);
  2956.         if (*cmarg2 != '\0') debug(F110," as:",cmarg2,0);
  2957.     } else {            /* MAIL */
  2958. #ifndef NOFRILLS
  2959. #ifdef CK_XYZ
  2960.         if (protocol != PROTO_K) {
  2961.         printf("Sorry, MAIL can be sent using Kermit protocol\n");
  2962.         return(-9);
  2963.         }
  2964. #endif /* CK_XYZ */
  2965.         if (!atdiso || !atcapr) {    /* Disposition attribute off? */
  2966.         printf("?Disposition Attribute is Off\n");
  2967.         return(-9);
  2968.         }
  2969.         debug(F101,"Mail: wild","",y);
  2970.         *optbuf = NUL;        /* Wipe out any old options */
  2971.         if ((x = cmtxt("Address to mail to","",&s,xxstring)) < 0)
  2972.           return(x);
  2973.         if ((int)strlen(s) == 0) {
  2974.         printf("?Address required\n");
  2975.         return(-9);
  2976.         }
  2977.         strcpy(optbuf,s);
  2978.         if ((int)strlen(optbuf) > 94) { /* Ensure legal size */
  2979.         printf("?Option string too long\n");
  2980.         return(-9);
  2981.         }
  2982.         cmarg = line;        /* File to send */
  2983.         debug(F110,"Mailing:",cmarg,0);
  2984.         debug(F110,"To:",optbuf,0);
  2985.         rmailf = 1;            /* MAIL modifier flag for SEND */
  2986. #else
  2987.         printf("?Sorry, MAIL feature not configured.\n");
  2988.         return(-9);
  2989. #endif /* NOFRILLS */
  2990.     }
  2991. #ifdef CK_RESEND
  2992.     if (cx == XXPSEN)        /* Partial-send starting position */
  2993.       sendstart = seekto;
  2994.     else
  2995.       sendstart = 0L;
  2996. #endif /* CK_RESEND */
  2997.     if (cx == XXMOVE)
  2998.       moving = 1;
  2999. #ifndef NOMSEND
  3000.     if (cx != XXADD) {        /* Not ADD, really sending... */
  3001. #endif /* NOMSEND */
  3002.         sstate = 's';        /* Set start state to SEND */
  3003. #ifndef NOMSEND
  3004.         addlist = 0;
  3005.         filenext = NULL;
  3006.     } else {            /* Just ADDing... */
  3007.         struct filelist * flp;
  3008.         flp = (struct filelist *) malloc(sizeof(struct filelist));
  3009.         if (flp) {
  3010.         if (filetail)
  3011.           filetail->fl_next = flp;
  3012.         filetail = flp;
  3013.         if (!filehead)
  3014.           filehead = flp;
  3015.         x = (int) strlen(line);    /* Length of filename */
  3016.         s = (char *) malloc(x + 1);
  3017.         if (s) {
  3018.             strcpy(s,line);
  3019.             flp->fl_name = s;
  3020.             flp->fl_mode = xmode;
  3021.             x = (int) strlen(cmarg2); /* Length of as-name */
  3022.             if (x < 1) {
  3023.             flp->fl_alias = NULL;
  3024.             } else {
  3025.             s = (char *) malloc(x + 1);
  3026.             if (s) {
  3027.                 strcpy(s,cmarg2);
  3028.                 flp->fl_alias = s;
  3029.             } else {
  3030.                 printf("Sorry, can't allocate space for as-name");
  3031.                 return(-9);
  3032.             }
  3033.             }
  3034.             flp->fl_next = NULL;
  3035.             filesinlist++;    /* Count this node */
  3036.             return(0);        /* Finished adding this node */
  3037.         } else {
  3038.             printf("Sorry, can't allocate space for name");
  3039.             return(-9);
  3040.         }
  3041.         } else {
  3042.         printf("Sorry, can't allocate file list node");
  3043.         return(-9);
  3044.         }
  3045.     }
  3046. #endif /* NOMSEND */
  3047. sendend:
  3048.  
  3049. #ifdef CK_RESEND
  3050.     switch (cx) {
  3051.       case XXRSEN: sendmode = SM_RESEND; break;
  3052.       case XXPSEN: sendmode = SM_PSEND;  break;
  3053.       case XXSEN:
  3054.       default:     sendmode = SM_SEND;   break;
  3055.     }
  3056. #else
  3057.     sendmode = SM_SEND;
  3058. #endif /* CK_RESEND */
  3059. #ifdef MAC
  3060.     what = W_SEND;
  3061.     scrcreate();
  3062. #endif /* MAC */
  3063.     if (local) {            /* If in local mode, */
  3064.         displa = 1;            /* turn on file transfer display */
  3065.     }
  3066.     return(0);
  3067.     }
  3068.  
  3069. #ifndef NOMSEND
  3070.     if (cx == XXMSE || cx == XXMMOVE) {    /* MSEND and MMOVE commands */
  3071.     nfils = 0;            /* Like getting a list of */
  3072.     lp = line;            /* files on the command line */
  3073.     addlist = 0;            /* Do not use SEND-LIST */
  3074.     filenext = NULL;        /* Ditto ! */
  3075. #ifdef CK_XYZ
  3076.     if (protocol == PROTO_X) {
  3077.         printf(
  3078. "Sorry, you can only send one file at a time with XMODEM protocol\n"
  3079.            );
  3080.         return(-9);
  3081.     }
  3082. #endif /* CK_XYZ */
  3083.  
  3084.     while (1) {
  3085.         char *p;
  3086.         if ((x = cmifi("Names of files to send, separated by spaces","",
  3087.                &s,&y,xxstring)) < 0) {
  3088.         if (x == -3) {
  3089.             if (nfils <= 0) {
  3090.             printf("?A file specification is required\n");
  3091.             return(-9);
  3092.             } else break;
  3093.         }
  3094.         return(x);
  3095.         }
  3096.         msfiles[nfils++] = lp;    /* Got one, count it, point to it, */
  3097.         p = lp;            /* remember pointer, */
  3098.         while (*lp++ = *s++)    /* and copy it into buffer */
  3099.           if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
  3100.           printf("?MSEND list too long\n");
  3101.           line[0] = NUL;
  3102.           return(-9);
  3103.           }
  3104.         debug(F111,"msfiles",msfiles[nfils-1],nfils-1);
  3105.         if (nfils == 1) *fspec = NUL; /* Take care of \v(filespec) */
  3106.         if (((int)strlen(fspec) + (int)strlen(p) + 1) < CKMAXPATH) {
  3107.         strcat(fspec,p);
  3108.         strcat(fspec," ");
  3109.         } else printf("WARNING - \\v(filespec) buffer overflow\n");
  3110.     }
  3111.     cmlist = msfiles;        /* Point cmlist to pointer array */
  3112.     cmarg2 = "";            /* No internal expansion list (yet) */
  3113.     sndsrc = nfils;            /* Filenames come from cmlist */
  3114.     sendmode = SM_MSEND;        /* Remember this kind of SENDing */
  3115.     sstate = 's';            /* Set start state for SEND */
  3116.     if (cx == XXMMOVE)        /* If MMOVE'ing, */
  3117.       moving = 1;            /*  set this flag. */
  3118. #ifdef MAC
  3119.     what = W_SEND;
  3120.     scrcreate();
  3121. #endif /* MAC */
  3122.     if (local) {            /* If in local mode, */
  3123.         displa = 1;            /* turn on file transfer display */
  3124.         ttflui();            /* and flush tty input buffer. */
  3125.     }
  3126.     return(0);
  3127.     }
  3128. #endif /* NOMSEND */
  3129.  
  3130. #ifndef NOSERVER
  3131.     if (cx == XXSER) {            /* SERVER */
  3132. #ifdef CK_XYZ
  3133.     if (protocol != PROTO_K) {
  3134.         printf("Sorry, SERVER only works with Kermit protocol\n");
  3135.         return(-9);
  3136.     }
  3137. #endif /* CK_XYZ */
  3138. #ifdef COMMENT
  3139. /*
  3140.   Parse for time limit, but since we don't use it yet,
  3141.   the parsing is commented out.
  3142. */
  3143.     x_ifnum = 1;            /* Turn off internal complaints */
  3144.     y = cmnum("optional time limit, seconds, or time of day as hh:mm:ss",
  3145.           "0", 10, &x, xxstring
  3146.           );
  3147.     x_ifnum = 0;
  3148.     if (y < 0) {
  3149.         if (y == -2) {        /* Invalid number or expression */
  3150.         zz = tod2sec(atmbuf);    /* Convert to secs since midnight */
  3151.         if (zz < 0L) {
  3152.             printf("?Number, expression, or time of day required\n");
  3153.             return(-9);
  3154.         } else {
  3155.             char now[32];    /* Current time */
  3156.             char *p;
  3157.             long tnow;
  3158.             p = now;
  3159.             ztime(&p);
  3160.             tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
  3161.             if (zz < tnow)    /* User's time before now */
  3162.               zz += 86400L;    /* So make it tomorrow */
  3163.             zz -= tnow;        /* Seconds from now. */
  3164.         }
  3165.         } else
  3166.           return(y);
  3167.     }
  3168.     if (zz > -1L) {
  3169.         x = zz;
  3170.         if (zz != (long) x) {
  3171.         printf(
  3172. "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
  3173.                );
  3174.         return(-9);
  3175.         }
  3176.     }
  3177.     if (x < 0)
  3178.       x = 0;
  3179. #endif /* COMMENT */
  3180.  
  3181.     if ((x = cmcfm()) < 0) return(x);
  3182.     sstate = 'x';
  3183. #ifdef MAC
  3184.     what = W_RECV;
  3185.     scrcreate();
  3186. #endif /* MAC */
  3187.     if (local) displa = 1;
  3188. #ifdef AMIGA
  3189.     reqoff();            /* No DOS requestors while server */
  3190. #endif /* AMIGA */
  3191.     return(0);
  3192.     }
  3193. #endif /* NOSERVER */
  3194.  
  3195.     if (cx == XXSAVE) {            /* SAVE command */
  3196.     x = cmkey(savtab,nsav,"option","keymap",xxstring);
  3197.     if (x == -3) {
  3198.         printf("?You must specify an option to save\n");
  3199.         return(-9);
  3200.     }
  3201.     if (x < 0) return(x);
  3202.     /* have to set success separately for each item in doprm()... */
  3203.     /* actually not really, could have just had doprm return 0 or 1 */
  3204.     /* and set success here... */
  3205.     y = dosave(x);
  3206.     if (y == -3) {
  3207.         printf("?More fields required\n");
  3208.         return(-9);
  3209.     } else return(y);
  3210.     }
  3211.  
  3212.     if (cx == XXSET) {            /* SET command */
  3213.     x = cmkey(prmtab,nprm,"Parameter","",xxstring);
  3214.     if (x == -3) {
  3215.         printf("?You must specify a parameter to set\n");
  3216.         return(-9);
  3217.     }
  3218.     if (x < 0) return(x);
  3219.     /* have to set success separately for each item in doprm()... */
  3220.     /* actually not really, could have just had doprm return 0 or 1 */
  3221.     /* and set success here... */
  3222.     y = doprm(x,0);
  3223.     if (y == -3) {
  3224.         printf("?More fields required\n");
  3225.         return(-9);
  3226.     } else return(y);
  3227.     }
  3228.  
  3229. #ifndef NOPUSH
  3230.     if (cx == XXSHE) {            /* SHELL (system) command */
  3231.         extern int nopush;
  3232.     if (cmtxt("System command to execute","",&s,xxstring) < 0)
  3233.       return(-1);
  3234.        
  3235.         if (nopush)
  3236.           return(success = 0);
  3237. #ifdef CK_APC
  3238.     if (apcactive == APC_REMOTE && apcstatus != APC_UNCH)
  3239.       return(success = 0);
  3240. #endif /* CK_APC */
  3241.     conres();            /* Make console normal  */
  3242.     x = zshcmd(s);
  3243.     debug(F101,"RUN zshcmd code","",x);
  3244.     concb((char)escape);
  3245.     return(success = x);
  3246.     }
  3247. #ifdef CK_REDIR
  3248.     if (cx == XXFUN) {            /* REDIRECT */
  3249.         extern int nopush;
  3250.  
  3251.         if (nopush) {
  3252.             printf("?REDIRECT disabled\n");
  3253.             return(success=0);
  3254.         }
  3255. #ifdef CK_APC
  3256.     if (apcactive == APC_LOCAL || 
  3257.         apcactive == APC_REMOTE && apcstatus != APC_UNCH) return(success = 0);
  3258. #endif /* CK_APC */
  3259.     if (!local) {
  3260.         printf("?SET LINE or SET HOST required first\n");
  3261.         return(-9);
  3262.     }
  3263. #ifdef OS2ONLY
  3264. #ifdef NETCONN
  3265.     if (network) {
  3266.         printf("?Sorry, REDIRECT doesn't work on network connections\n");
  3267.         return(-9);
  3268.     }
  3269. #endif /* NETCONN */
  3270. #endif /* OS2ONLY */
  3271.  
  3272.     sprintf(tmpbuf,
  3273.         "Local command to run,\n\
  3274. with its standard input/output redirected to %s\n",
  3275.         ttname);
  3276.     if ((x = cmtxt(tmpbuf,"",&s,xxstring)) < 0)
  3277.       return(x);
  3278.     return(success = ttruncmd(s));
  3279.     }
  3280. #endif /* CK_REDIR */
  3281. #endif /* NOPUSH */
  3282.  
  3283. #ifndef NOSHOW
  3284.     if (cx == XXSHO) {            /* SHOW */
  3285.     x = cmkey(shotab,nsho,"","parameters",xxstring);
  3286.     if (x < 0) return(x);
  3287.     return(doshow(x));
  3288.     }
  3289. #endif /* NOSHOW */
  3290.  
  3291. #ifndef MAC
  3292.     if (cx == XXSPA) {            /* SPACE */
  3293. #ifdef datageneral
  3294.     /* AOS/VS can take an argument after its "space" command. */
  3295.     if ((x = cmtxt("Confirm, or local directory name","",&s,xxstring)) < 0)
  3296.       return(x);
  3297.     if (*s == NUL) {
  3298.         xsystem(SPACMD);
  3299.     } else {
  3300.         sprintf(line,"space %s",s);
  3301.         xsystem(line);
  3302.     }
  3303. #else
  3304. #ifdef OS2
  3305.     if ((x = cmtxt("Press Enter for current disk,\n\
  3306.  or specify a disk letter like A:","",&s,xxstring)) < 0)
  3307.       return(x);
  3308.     if (*s == NUL) {        /* Current disk */
  3309.         printf(" Free space: %ldK\n", zdskspace(0)/1024L);
  3310.     } else {
  3311.         int drive = toupper(*s);
  3312.         printf(" Drive %c: %ldK free\n", drive,
  3313.            zdskspace(drive - 'A' + 1) / 1024L);
  3314.     }
  3315. #else
  3316. #ifdef OSK
  3317. #define UNIX
  3318. #endif /* OSK */
  3319. #ifdef UNIX
  3320. #ifdef COMMENT
  3321.     if ((x = cmtxt("Confirm for current disk,\n\
  3322.  or specify a disk device or directory","",&s,xxstring)) < 0)
  3323.       return(x);
  3324. #else
  3325.     x = cmdir("Confirm for current disk,\n\
  3326.  or specify a disk device or directory","",&s,xxstring);
  3327.     if (x == -3)
  3328.       s = "";
  3329.     else if (x < 0)
  3330.       return(x);
  3331.     if ((x = cmcfm()) < 0) return(x);
  3332. #endif /* COMMENT */
  3333.     if (*s == NUL) {        /* Current disk */
  3334.         xsystem(SPACMD);
  3335.     } else {            /* Specified disk */
  3336.         sprintf(line,"%s %s",SPACM2,s);
  3337.         xsystem(line);
  3338.     }
  3339. #ifdef OSK
  3340. #undef UNIX
  3341. #endif /* OSK */
  3342. #else
  3343.     if ((x = cmcfm()) < 0) return(x);
  3344.     xsystem(SPACMD);
  3345. #endif /* UNIX */
  3346. #endif /* OS2 */
  3347. #endif /* datageneral */
  3348.     return(success = 1);        /* Pretend it worked */
  3349.     }
  3350. #endif /* MAC */
  3351.  
  3352.     if (cx == XXSTA) {            /* STATISTICS */
  3353.     if ((x = cmcfm()) < 0) return(x);
  3354.     return(success = dostat());
  3355.     }
  3356.  
  3357.     if (cx == XXSTO || cx == XXEND) {    /* STOP, END, or POP */
  3358.     if ((y = cmnum("exit status code","0",10,&x,xxstring)) < 0)
  3359.       return(y);
  3360.     if ((y = cmtxt("Message to print","",&s,xxstring)) < 0)
  3361.       return(y);
  3362.     s = brstrip(s);
  3363.     if (*s) printf("%s\n",s);
  3364.     if (cx == XXSTO) {
  3365.         dostop();
  3366.     } else {
  3367. #ifndef NOSPL
  3368.         /* Pop from all FOR/WHILE/XIFs */
  3369.         debug(F101,"END maclvl 1","",maclvl);
  3370.         while ((maclvl > 0) &&
  3371.            (m_arg[maclvl-1][0]) &&
  3372.            (cmdstk[cmdlvl].src == CMD_MD) &&
  3373.              (!strncmp(m_arg[maclvl-1][0],"_xif",4) ||
  3374.               !strncmp(m_arg[maclvl-1][0],"_for",4) ||
  3375.               !strncmp(m_arg[maclvl-1][0],"_whi",4))) {
  3376.         debug(F110,"END popping",m_arg[maclvl-1][0],0);
  3377.         dogta(XXPTA);        /* Put args back */
  3378.         popclvl();        /* Pop up two levels */
  3379.         popclvl();
  3380.         debug(F101,"END maclvl 2","",maclvl);
  3381.         }
  3382. #endif /* NOSPL */
  3383.         popclvl();            /* Now pop out of macro or TAKE file */
  3384. #ifndef NOSPL
  3385.         debug(F101,"END maclvl 3","",maclvl);
  3386. #endif /* NOSPL */
  3387.     }
  3388.     return(success = (x == 0));
  3389.     }
  3390.  
  3391.     if (cx == XXSUS) {            /* SUSPEND */
  3392.     if ((y = cmcfm()) < 0) return(y);
  3393. #ifdef NOJC
  3394.     printf("Sorry, this version of Kermit cannot be suspended\n");
  3395. #else
  3396.     stptrap(0);
  3397. #endif /* NOJC */
  3398.     return(0);
  3399.     }
  3400.  
  3401.     if (cx == XXTAK) {            /* TAKE */
  3402. #ifdef OS2
  3403.     extern char startupdir[],exedir[],inidir[];
  3404.     char * scriptenv, * keymapenv;
  3405. #endif /* OS2 */
  3406.     char takepath[1024];
  3407.  
  3408.     if (tlevel > MAXTAKE-1) {
  3409.         printf("?Take files nested too deeply\n");
  3410.         return(-2);
  3411.     }
  3412. #ifdef OS2    
  3413. #ifdef NT
  3414.     scriptenv = getenv("K95SCRIPTS");
  3415.     keymapenv = getenv("K95KEYMAPS");
  3416. #else /* NT */
  3417.     scriptenv = getenv("K2SCRIPTS");
  3418.     keymapenv = getenv("K2KEYMAPS");
  3419. #endif /* NT */
  3420.     if (!scriptenv)
  3421.       scriptenv = getenv("CK_SCRIPTS");
  3422.     if (!keymapenv)
  3423.       keymapenv = getenv("CK_KEYMAPS");
  3424.  
  3425.     sprintf(takepath,
  3426.                 /* semicolon-separated path list */
  3427.                 "%s%s%s%s%s;%s%s;%s%s;%s;%s%s;%s%s;%s;%s%s;%s%s", 
  3428.                 scriptenv?scriptenv:"",
  3429.                 (scriptenv && scriptenv[strlen(scriptenv)-1]==';')?"":";",
  3430.                 keymapenv?keymapenv:"",
  3431.                 (keymapenv && keymapenv[strlen(keymapenv)-1]==';')?"":";",
  3432.                 startupdir,
  3433.                 startupdir, "SCRIPTS/",    
  3434.                 startupdir, "KEYMAPS/",
  3435.                 inidir,
  3436.                 inidir, "SCRIPTS/",
  3437.                 inidir, "KEYMAPS/",
  3438.                 exedir,
  3439.                 exedir, "SCRIPTS/",
  3440.                 exedir, "KEYMAPS/"
  3441.                 );
  3442. #else /* not OS2 */
  3443.     y = 1024;
  3444.     s = takepath;
  3445.     zzstring("\\v(home)",&s,&y);
  3446. #endif /* OS2 */
  3447.  
  3448.     if ((y = cmifip("C-Kermit command file",
  3449.             "",&s,&x,0,takepath,xxstring)) < 0) {
  3450.         if (y == -3) {
  3451.         printf("?A file name is required\n");
  3452.         return(-9);
  3453.         } else
  3454.           return(y);
  3455.     }
  3456.     if (x != 0) {
  3457.         printf("?Wildcards not allowed in command file name\n");
  3458.         return(-9);
  3459.     }
  3460.     strcpy(line,s);
  3461.     if ((y = cmcfm()) < 0) return(y);
  3462.     return(success = dotake(line));
  3463.     }
  3464.  
  3465. #ifdef OS2
  3466.     if (cx == XXVIEW) {            /* VIEW Only Terminal mode */
  3467.     viewonly = TRUE;
  3468.     success = doconect(0);
  3469.     viewonly = FALSE;
  3470.     return success;
  3471.     }
  3472. #endif /* OS2 */
  3473.  
  3474. #ifdef NETCONN
  3475.     if (cx == XXTEL) {            /* TELNET */
  3476.     int x,z;
  3477. #ifdef OS2
  3478.     if (!tcp_avail) {
  3479.         printf("?Sorry, either TCP/IP is not available on this system or\n\
  3480. necessary DLLs did not load.  Use SHOW NETWORK to check network status.\n");
  3481.         success = 0;
  3482.         return(-9);
  3483.     } else
  3484. #endif /* OS2 */
  3485.       {
  3486.       x = nettype;            /* Save net type in case of failure */
  3487.       z = ttnproto;            /* Save protocol in case of failure */
  3488.       nettype = NET_TCPB;
  3489.       ttnproto = NP_TELNET;
  3490.       if ((y = setlin(XYHOST,0)) < 0) {
  3491.               nettype = x;        /* Failed, restore net type. */
  3492.               ttnproto = z;        /* and protocol */
  3493.               success = 0;
  3494.               return(y);
  3495.            }
  3496.         }
  3497.     return (success = (y == 0) ? 0 : doconect(0));
  3498.     }
  3499.  
  3500.  
  3501. #ifdef RLOGCODE
  3502.     if (cx == XXRLOG) {            /* RLOGIN */
  3503.     int x,z;
  3504. #ifdef OS2
  3505.     if ( !tcp_avail ) {
  3506.         printf("?Sorry, either TCP/IP is not available on this system or\n\
  3507. necessary DLLs did not load.  Use SHOW NETWORK to check network status.\n"
  3508.            );
  3509.         success = 0;
  3510.         return(-9);
  3511.     } else {
  3512. #endif /* OS2 */
  3513.         x = nettype;        /* Save net type in case of failure */
  3514.         z = ttnproto;        /* Save protocol in case of failure */
  3515.         nettype = NET_TCPB;
  3516.         ttnproto = NP_RLOGIN;
  3517.         if ((y = setlin(XYHOST,0)) < 0) {
  3518.         nettype = x;        /* Failed, restore net type. */
  3519.         ttnproto = z;        /* and protocol */
  3520.         success = 0;
  3521.         return(y);
  3522.         }
  3523. #ifdef OS2        
  3524.     }
  3525. #endif /* OS2 */
  3526.     return (success = (y == 0) ? 0 : doconect(0));
  3527.     }
  3528. #endif /* RLOGCODE */
  3529. #endif /* NETCONN */
  3530.  
  3531. #ifndef NOXMIT
  3532.     if (cx == XXTRA) {            /* TRANSMIT */
  3533.     if ((x = cmifi("File to transmit","",&s,&y,xxstring)) < 0) {
  3534.         if (x == -3) {
  3535.         printf("?Name of an existing file\n");
  3536.         return(-9);
  3537.         } else return(x);
  3538.     }
  3539.     if (y != 0) {
  3540.         printf("?Only a single file may be transmitted\n");
  3541.         return(-2);
  3542.     }
  3543.     strcpy(line,s);            /* Save copy of string just parsed. */
  3544.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  3545. #ifdef CK_APC
  3546.     if (apcactive == APC_LOCAL || 
  3547.         apcactive == APC_REMOTE && apcstatus != APC_UNCH) return(success = 0);
  3548. #endif /* CK_APC */
  3549.     debug(F111,"calling transmit",line,xmitp);
  3550.     return(success = transmit(line,(char)xmitp)); /* Do the command */
  3551.     }
  3552. #endif /* NOXMIT */
  3553.  
  3554. #ifndef NOFRILLS
  3555.     if (cx == XXTYP) {            /* TYPE */
  3556.     if ((x = cmifi("File to type","",&s,&y,xxstring)) < 0) {
  3557.         if (x == -3) {
  3558.         printf("?Name of an existing file\n");
  3559.         return(-9);
  3560.         } else return(x);
  3561.     }
  3562.     if (y != 0) {
  3563.         printf("?A single file please\n");
  3564.         return(-2);
  3565.     }
  3566.     strcpy(line,s);
  3567.     if ((y = cmcfm()) < 0)        /* Confirm the command */
  3568.       return(y);
  3569.     debug(F110,"TYPE",line,0);
  3570.     return(success = dotype(line));
  3571.     }
  3572. #endif /* NOFRILLS */
  3573.  
  3574. #ifndef NOFRILLS
  3575.     if (cx == XXTES) {            /* TEST */
  3576.     /* Fill this in with whatever is being tested... */
  3577.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  3578.  
  3579. #define CK_DUMPLOCALS            /* Define one or more of these. */
  3580.  
  3581. #ifdef CK_DUMPARRAYS
  3582. #ifndef NOSPL
  3583.     { int d, i, j;            /* Dump all arrays */
  3584.       char c, **p;
  3585.       for (i = 0; i < 27; i++) {
  3586.           p = a_ptr[i];
  3587.           d = a_dim[i];
  3588.           c = (i == 0) ? 64 : i + 96;
  3589.           if (d && p) {
  3590.           fprintf(stderr,"&%c[%d]\n",c,d);
  3591.           for (j = 0; j <= d; j++) {
  3592.               if (p[j]) {
  3593.               fprintf(stderr,"  &%c[%2d] = [%s]\n",c,j,p[j]);
  3594.               }
  3595.           }
  3596.           }
  3597.       }
  3598.       }
  3599. #endif /* NOSPL */
  3600. #endif /* CK_DUMPARRAYS */
  3601.  
  3602. #ifdef CK_DUMPSTACK
  3603. #ifndef NOSPL
  3604.     printf("cmdlvl = %d, tlevel = %d, maclvl = %d\n",
  3605.            cmdlvl,tlevel,maclvl);
  3606.     if (maclvl < 0) {
  3607.         printf("%s\n",
  3608.          "Call me from inside a macro and I'll dump the argument stack");
  3609.         return(0);
  3610.     }
  3611.     printf("Macro level: %d, ARGC = %d\n     ",maclvl,macargc[maclvl]);
  3612.     for (y = 0; y < 10; y++) printf("%7d",y);
  3613.     for (x = 0; x <= maclvl; x++) {
  3614.         printf("\n%2d:  ",x);
  3615.         for (y = 0; y < 10; y++) {
  3616.         s = m_arg[x][y];
  3617.         printf("%7s",s ? s : "(none)");
  3618.         }
  3619.     }
  3620.     printf("\n");
  3621.  
  3622. #endif /* NOSPL */
  3623. #endif /* CK_DUMPSTACK */
  3624.  
  3625. #ifdef CK_DUMPLOCALS
  3626. #ifndef NOSPL
  3627.     {
  3628.         extern struct localvar * localhead[];
  3629.         struct localvar * v;
  3630.         int i;
  3631.         printf("Command Level: %d\n",cmdlvl);
  3632.         for (i = 0; i <= cmdlvl; i++) {
  3633.         v = localhead[i];
  3634.         if (!v) continue;
  3635.         printf("Level %d\n",i);
  3636.         while (v) {
  3637.             printf("%s [%s]\n",v->lv_name,v->lv_value);
  3638.             v = v->lv_next;
  3639.         }
  3640.         }
  3641.     }
  3642. #endif /* NOSPL */
  3643. #endif /* CK_DUMPLOCALS */
  3644.  
  3645.     return(0);
  3646.     }
  3647. #endif /* NOFRILLS */
  3648.  
  3649. #ifndef NOCSETS
  3650.     if (cx == XXXLA) {       /* TRANSLATE <ifn> from-cs to-cs <ofn> */
  3651.     int incs, outcs;
  3652.     if ((x = cmifi("File to translate","",&s,&y,xxstring)) < 0) {
  3653.         if (x == -3) {
  3654.         printf("?Name of an existing file\n");
  3655.         return(-9);
  3656.         } else return(x);
  3657.     }
  3658.     if (y != 0) {
  3659.         printf("?A single file please\n");
  3660.         return(-2);
  3661.     }
  3662.     strcpy(line,s);            /* Save copy of string just parsed. */
  3663.  
  3664.     if ((incs = cmkey(fcstab,nfilc,"from character-set","",xxstring)) < 0)
  3665.       return(incs);
  3666.     if ((outcs = cmkey(fcstab,nfilc,"to character-set","",xxstring)) < 0)
  3667.       return(outcs);
  3668.     if ((x = cmofi("output file",CTTNAM,&s,xxstring)) < 0) return(x);
  3669.     if (x > 1) {
  3670.         printf("?Directory name not allowed\n");
  3671.         return(-9);
  3672.     }
  3673.     strncpy(tmpbuf,s,TMPBUFSIZ);
  3674.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  3675.     return(success = xlate(line,tmpbuf,incs,outcs)); /* Execute it */
  3676.     }
  3677. #endif /* NOCSETS */
  3678.  
  3679.     if (cx == XXVER) {            /* VERSION */
  3680.        if ((y = cmcfm()) < 0) 
  3681.           return(y);
  3682.  
  3683.        printf("%s, for%s\n Numeric: %ld",versio,ckxsys,vernum);
  3684.        if (xvernum)
  3685.      printf("C-Kermit %s\n",ck_ver);
  3686.        if (verwho) 
  3687.      printf("-%d\n",verwho); 
  3688.        else printf("\n");
  3689.        hmsga(copyright);
  3690. #ifdef OS2
  3691.        shoreg();
  3692. #endif /* OS2 */
  3693.  
  3694.     return(success = 1);
  3695.     }
  3696.  
  3697. #ifndef MAC                /* Only for multiuser systems */
  3698. #ifndef NOFRILLS
  3699.     if (cx == XXWHO) {            /* WHO */
  3700.     char *wc;
  3701. #ifdef datageneral
  3702.         xsystem(WHOCMD);
  3703. #else
  3704.     if ((y = cmtxt("user name","",&s,xxstring)) < 0) return(y);
  3705.     if (!(wc = getenv("CK_WHO"))) wc = WHOCMD;
  3706.     if (wc)
  3707.       if ((int) strlen(wc) > 0) {
  3708.           sprintf(line,"%s %s",wc,s);
  3709.           xsystem(line);
  3710.       }
  3711. #endif /* datageneral */
  3712.     return(success = 1);
  3713.     }
  3714. #endif /* NOFRILLS */
  3715. #endif /* MAC */
  3716.  
  3717. #ifndef NOFRILLS
  3718.     if (cx == XXWRI || cx == XXWRL || cx == XXWRBL) { /* WRITE */
  3719. #ifdef BINREAD
  3720.     if (cx == XXWRBL) {
  3721.         extern CHAR * readbuf;
  3722.         extern int readsize;
  3723.         if ((y = cmcfm()) < 0) return(y);
  3724.         y = zsoutx(ZWFILE, readbuf, readsize);
  3725.         printf("WRITEBLOCK = %d\n",y);
  3726.         return(y);
  3727.     }        
  3728. #endif /* BINREAD */
  3729.     if ((x = cmkey(writab,nwri,"to file or log","",xxstring)) < 0) {
  3730.         if (x == -3) printf("?Write to what?\n");
  3731.         return(x);
  3732.     }
  3733.     if ((y = cmtxt("text","",&s,xxstring)) < 0) return(y);
  3734.     s = brstrip(s);
  3735.     switch (x) {
  3736.       case LOGD: y = ZDFILE; break;
  3737.       case LOGP: y = ZPFILE; break;
  3738. #ifndef NOLOCAL
  3739.       case LOGS: y = ZSFILE; break;
  3740. #endif /* NOLOCAL */
  3741.       case LOGT: y = ZTFILE; break;
  3742. #ifndef NOSPL
  3743.       case LOGW: y = ZWFILE; break;
  3744. #endif /* NOSPL */
  3745.       case LOGX:
  3746.       case LOGE:
  3747.  
  3748. #ifndef MAC
  3749.         if (x == LOGE) fprintf(stderr,"%s",s);
  3750.         else
  3751. #endif /* MAC */
  3752.           printf("%s",s);
  3753.         if (
  3754. #ifndef NOSPL
  3755.         cmdlvl == 0
  3756. #else
  3757.         tlevel == -1
  3758. #endif /* NOSPL */
  3759.         )
  3760. #ifndef MAC
  3761.           if (x == LOGE) fprintf(stderr,"\n");
  3762.           else
  3763. #endif /* MAC */
  3764.         printf("\n");
  3765.         return(success = 1);
  3766.       default: return(-2);
  3767.     }
  3768.     if (chkfn(y) > 0) {
  3769.         x = (cx == XXWRI) ? zsout(y,s) : zsoutl(y,s);
  3770.         if (x < 0) printf("?Write error\n");
  3771.     } else {
  3772.         x = -1;
  3773.         printf("?File or log not open\n");
  3774.     }
  3775.     return(success = (x == 0) ? 1 : 0);
  3776.     }
  3777. #endif /* NOFRILLS */
  3778.  
  3779.     if (cx == XXASC || cx == XXBIN) {
  3780.     if ((x = cmcfm()) < 0) return(x);
  3781.     binary = (cx == XXASC) ? XYFT_T : XYFT_B;
  3782.     return(success = 1);
  3783.     }
  3784. #ifdef OS2
  3785.     if (cx == XXCLS) {
  3786.     if ((x = cmcfm()) < 0) return(x);    
  3787.     clear();
  3788.     return(success = 1);
  3789.     }
  3790. #endif /* OS2 */
  3791.  
  3792. #ifdef CK_MKDIR
  3793.     if (cx == XXMKDIR) {
  3794.     if ((x = cmofi("Name for new directory", "", &s, xxstring)) < 0)
  3795.       return(x);
  3796.     strcpy(line,s);
  3797.     if ((x = cmcfm()) < 0) return(x);
  3798.     /* Unfortunately, zmkdir() is not quite what we want here... */
  3799.     x =
  3800. #ifdef OS2
  3801.       _mkdir(line)
  3802. #else
  3803. #ifdef UNIX
  3804.       mkdir(line,0777)
  3805. #else
  3806.      -1
  3807. #endif /* UNIX */
  3808. #endif /* OS2 */
  3809.         ;
  3810.     return(success = (x < 0) ? 0 : 1);
  3811.     }
  3812.     if (cx == XXRMDIR) {
  3813.     if ((x = cmofi("Name of empty directory to remove",
  3814.                "", &s, xxstring)) < 0)
  3815.       return(x);
  3816.     strcpy(line,s);
  3817.     if ((x = cmcfm()) < 0) return(x);
  3818.     x =
  3819. #ifdef NT
  3820.       _rmdir(line)
  3821. #else
  3822. #ifdef UNIX
  3823.       rmdir(line)
  3824. #else
  3825.      -1
  3826. #endif /* UNIX */
  3827. #endif /* NT */
  3828.         ;
  3829.     return(success = (x < 0) ? 0 : 1);
  3830.     }
  3831. #ifdef TCPSOCKET
  3832.     if (cx == XXTELOP) {
  3833.         if ((x = cmkey( telcmd, 4, "TELNET command", "", xxstring)) < 0 )
  3834.       return(x);
  3835.         if ((y = cmkey( tnopts, ntnopts, "TELNET option", "", xxstring)) < 0 )
  3836.       return(y);    
  3837.     if ((z = cmcfm()) < 0) return(z);
  3838.     if (local) {
  3839.         return((tn_sopt(x,y) > -1) ? 1 : 0);
  3840.     } else {
  3841.         printf("ff%02x%02x\n",x,y);
  3842.         return(0);
  3843.     }
  3844.     }
  3845. #endif /* TCPSOCKET */
  3846.  
  3847. #endif /* CK_MKDIR */
  3848.                                             
  3849. #ifndef NOPUSH
  3850.     if ( cx == XXNPSH ) {
  3851.         extern int nopush;
  3852. #ifndef NOSERVER
  3853.     extern int en_hos;
  3854. #endif /* NOSERVER */
  3855.     if ((z = cmcfm()) < 0) return(z);
  3856.         nopush = 1;
  3857. #ifndef NOSERVER
  3858.         en_hos = 0;
  3859. #endif /* NOSERVER */
  3860.         return(success = 1);
  3861.     }
  3862. #endif /* NOPUSH */
  3863.  
  3864. #ifndef NOSPL
  3865.     if (cx == XXLOCAL)            /* LOCAL variable declarations */
  3866.       return(success = dolocal());
  3867. #endif /* NOSPL */
  3868.  
  3869.     if (cx == XXKERMI) {
  3870.     char * list[64];
  3871.     extern char **xargv;
  3872.     extern int xargc;
  3873.     int i;
  3874.     if ((y = cmtxt("kermit command-line arguments, -h for help",
  3875.                "",&s,xxstring)) < 0)
  3876.       return(y);
  3877.     strcpy(line,"kermit ");
  3878.     strcat(line,s);
  3879.     xwords(line,64,list,0);
  3880.     for (i = 1; i < 64; i++) {
  3881.         if (!list[i])
  3882.           break;
  3883.     }
  3884.     i--;
  3885.     xargc = i;
  3886.     xargv = list;
  3887.     xargv++;
  3888.     if (sstate = cmdlin()) {
  3889.         proto();
  3890.         return(success);
  3891.     } else return(success = 1);
  3892.     }
  3893.     if (cx == XXDATE) {
  3894.     if ((z = cmcfm()) < 0) return(z);
  3895.     ztime(&s);
  3896.     printf("%s\n",s);
  3897.     return(success = 1);
  3898.     }
  3899.  
  3900.     debug(F101,"docmd unk arg","",cx);
  3901.     return(-2);                /* None of the above. */
  3902. } /* end of docmnd() */
  3903.  
  3904. #endif /* NOICP */
  3905.