home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / ckc190.zip / ckuusr.c < prev    next >
C/C++ Source or Header  |  1994-11-12  |  73KB  |  2,561 lines

  1. #include "ckcsym.h"
  2. char *userv = "User Interface 5A(156), 4 Oct 94";
  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, FDCCU@CUVMA.BITNET),
  8.   Columbia University Academic Information Systems, New York City.
  9.  
  10.   Copyright (C) 1985, 1994, 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.  
  98. #ifdef datageneral
  99. #include <packets:common.h>
  100. #define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd)
  101. #endif /* datageneral */
  102.  
  103. /* External Kermit Variables, see ckmain.c for description. */
  104.  
  105. extern xx_strp xxstring;
  106.  
  107. extern int size, local, sndsrc, xitsta, server, displa, binary, msgflg,
  108.   escape, duplex, nfils, quiet, tlevel, pflag, zincnt, atcapr, atdiso, verwho,
  109.   ckxech, carrier, deblog, sendmode, epktflg, what;
  110. extern long sendstart;
  111. #ifdef CK_TTYFD
  112. extern int ttyfd;
  113. #endif /* CK_TTYFD */
  114.  
  115. extern long vernum;
  116. extern char *versio, *copyright[];
  117. extern char *ckxsys, *cmarg, *cmarg2, **cmlist;
  118. #ifndef NOHELP
  119. extern char *introtxt[];
  120. extern char *newstxt[];
  121. #endif /* NOHELP */
  122. extern char *PWDCMD, *WHOCMD, *TYPCMD;
  123. extern char ttname[];
  124. #ifndef NOFRILLS
  125. extern int rmailf;            /* MAIL command items */
  126. extern char optbuf[];
  127. #endif /* NOFRILLS */
  128. extern CHAR sstate;
  129.  
  130. #ifdef NETCONN
  131. extern int network,            /* Have active network connection */
  132.   nettype;                /* Type of network */
  133. #endif /* NETCONN */
  134.  
  135. #ifdef CK_APC
  136. extern int apcactive, apcstatus;
  137. #endif /* CK_APC */
  138.  
  139. #ifndef NOMSEND                /* Multiple SEND */
  140. extern char *msfiles[];
  141. #endif /* NOMSEND */
  142. extern char fspec[];            /* Most recent filespec */
  143.  
  144. #ifndef NOCSETS
  145. extern int nfilc;
  146. extern struct keytab fcstab[];
  147. #endif /* NOCSETS */
  148.  
  149. #ifdef CK_TMPDIR
  150. int f_tmpdir = 0;            /* Directory changed temporarily */
  151. char savdir[TMPDIRLEN];            /* For saving current directory */
  152. #endif /* CK_TMPDIR */
  153.  
  154. #ifdef COMMENT
  155. #ifdef pdp11
  156. /* Normally this is defined in ckcfns.c */
  157. #define ENCBUFL 200
  158. CHAR encbuf[ENCBUFL];
  159. #endif /* pdp11 */
  160. #endif /* COMMENT */
  161.  
  162. int rcflag = 0;                /* Pointer to home directory string */
  163. int repars,                /* Reparse needed */
  164.     techo = 0;                /* Take echo */
  165. #ifndef NOSCRIPT
  166. int secho = 1;
  167. #endif /* NOSCRIPT */
  168.  
  169. int xitwarn = 0;            /* Warn about open connection on exit */
  170.  
  171. #ifndef NOXMIT
  172. /* Variables for TRANSMIT command */
  173.  
  174. int xmitx = 1;            /* Whether to echo during TRANSMIT */
  175. int xmitf = 0;            /* Character to fill empty lines */
  176. int xmitl = 0;            /* 0 = Don't send linefeed too */
  177. int xmitp = LF;            /* Host line prompt */
  178. int xmits = 0;            /* Use shift-in/shift-out, 0 = no */
  179. int xmitw = 0;            /* Milliseconds to pause during TRANSMIT */
  180. #endif /* NOXMIT */
  181.  
  182. /* Declarations from ck?fio.c module */
  183.  
  184. extern char *SPACMD, *SPACM2;        /* SPACE commands */
  185.  
  186. /* Command-oriented items */
  187.  
  188. #ifdef DCMDBUF
  189. extern char *cmdbuf;            /* Command buffers */
  190. extern char *atmbuf;
  191. extern char *line;            /* Character buffer for anything */
  192. extern char *tmpbuf;            /* Short temporary string buffer */
  193. extern int *ifcmd;
  194. extern int *intime;
  195. #else
  196. extern char cmdbuf[];            /* Command buffers */
  197. extern char atmbuf[];
  198. extern char line[];            /* Character buffer for anything */
  199. extern char tmpbuf[];            /* Temporary buffer */
  200. extern int ifcmd[];
  201. extern int intime[];
  202. #endif /* DCMDBUF */
  203.  
  204. char *lp;                /* Pointer to line buffer */
  205.  
  206. #ifndef NOSPL
  207. char evalbuf[33];            /* EVALUATE result */
  208. extern char inpbuf[];            /* Buffer for INPUT and REINPUT */
  209. char *inpbp = inpbuf;            /* And pointer to same */
  210. extern char lblbuf[];            /* Buffer for labels */
  211. int m_found;                /* MINPUT result */
  212. char *ms[MINPMAX];            /* Pointers to MINPUT strings */
  213. #endif /* NOSPL */
  214.  
  215. char psave[PROMPTL] = { NUL };        /* For saving & restoring prompt */
  216.  
  217. extern int success;            /* Command success/failure flag */
  218.  
  219. #ifndef NOSPL
  220. int                    /* SET INPUT parameters. */
  221. /* Note, INPUT TIMEOUT, intime[], is on the command-level stack. */
  222.   indef = 1,                /* default timeout, seconds */
  223.   inecho = 1,                /* 1 = echo on */
  224.   insilence = 0;            /* 0 = no silence constraint */
  225.  
  226. int maclvl = -1;            /* Macro nesting level */
  227. int mecho = 0;                /* Macro echo, 0 = don't */
  228. char varnam[6];                /* For variable names */
  229. extern int macargc[];            /* ARGC from macro invocation */
  230.  
  231. extern char *m_arg[MACLEVEL][NARGS];    /* Stack of macro arguments */
  232.  
  233. extern char **a_ptr[];            /* Array pointers */
  234. extern int a_dim[];            /* Array dimensions */
  235.  
  236. #ifdef DCMDBUF
  237. extern struct cmdptr *cmdstk;        /* The command stack itself */
  238. #else
  239. extern struct cmdptr cmdstk[];        /* The command stack itself */
  240. #endif /* DCMDBUF */
  241. extern int cmdlvl;            /* Current position in command stack */
  242. #endif /* NOSPL */
  243.  
  244. static int x, y, z = 0;            /* Local workers */
  245. static char *s;
  246.  
  247. #define xsystem(s) zsyscmd(s)
  248.  
  249. /* Top-Level Interactive Command Keyword Table */
  250. /* Keywords must be in lowercase and in alphabetical order. */
  251.  
  252. struct keytab cmdtab[] = {
  253. #ifndef NOPUSH
  254.     "!",       XXSHE, CM_INV,    /* shell escape */
  255. #endif /* NOPUSH */
  256.     "#",           XXCOM, CM_INV,    /* comment */
  257. #ifndef NOSPL
  258.     ":",           XXLBL, CM_INV,    /* label */
  259. #endif /* NOSPL */
  260. #ifndef NOPUSH
  261. #ifdef CK_REDIR
  262.     "<",           XXFUN, CM_INV,    /* REDIRECT */
  263. #endif /* CK_REDIR */
  264.     "@",           XXSHE, CM_INV,    /* DCL escape */
  265. #endif /* NOPUSH */
  266. #ifndef NOSPL
  267.     "apc",         XXAPC, 0,        /* Application Program Command */
  268.     "asg",         XXASS, CM_INV,       /* invisible synonym for ASSIGN */
  269.     "ask",         XXASK, 0,        /* ASK for text, assign to variable */
  270.     "askq",        XXASKQ,0,            /* ASK quietly (no echo) */
  271.     "assign",      XXASS, 0,            /* ASSIGN value to variable or macro */
  272. #endif /* NOSPL */
  273. #ifndef NOFRILLS
  274.     "bug",         XXBUG, 0,        /* BUG report instructions */
  275. #endif /* NOFRILLS */
  276.     "bye",         XXBYE, 0,        /* BYE to remote server */
  277. #ifndef NOLOCAL
  278.     "c",           XXCON, CM_INV|CM_ABR, /* invisible synonym for CONNECT */
  279. #endif /* NOLOCAL */
  280. #ifndef NOFRILLS
  281.     "cat",         XXTYP, CM_INV,    /* Invisible synonym for TYPE */
  282. #endif /* NOFRILLS */
  283.     "cd",          XXCWD, 0,        /* Change Directory */
  284.     "check",       XXCHK, 0,        /* CHECK for a feature */
  285. #ifndef NOFRILLS
  286.     "clear",       XXCLE, 0,        /* CLEAR input and/or device buffer */
  287. #endif /* NOFRILLS */
  288.     "close",       XXCLO, 0,        /* CLOSE a log or other file */
  289. #ifdef NOFRILLS
  290.     "comment",     XXCOM, CM_INV,    /* Introduce a comment */
  291. #else
  292.     "comment",     XXCOM, 0,        /* COMMENT */
  293. #endif /* NOFRILLS */
  294. #ifndef NOLOCAL
  295.     "connect",     XXCON, 0,        /* Begin terminal connection */
  296. #endif /* NOLOCAL */
  297.     "cwd",       XXCWD, CM_INV,    /* Invisisble synonym for cd */
  298. #ifndef NOSPL
  299.     "dcl",         XXDCL, CM_INV,    /* DECLARE an array */
  300.     "declare",     XXDCL, 0,        /* DECLARE an array */
  301.     "decrement",   XXDEC, 0,        /* DECREMENT a numeric variable */
  302.     "define",      XXDEF, 0,        /* DEFINE a macro or variable */
  303. #endif /* NOSPL */
  304. #ifndef NOFRILLS
  305.     "delete",      XXDEL, 0,        /* DELETE a file */
  306. #endif /* NOFRILLS */
  307. #ifndef NODIAL
  308.     "dial",       XXDIAL,0,        /* DIAL a phone number */
  309. #endif /* NODIAL */
  310.     "directory",   XXDIR, 0,        /* DIRECTORY of files */
  311. #ifndef NOFRILLS
  312. #ifndef NOSERVER
  313.     "disable",     XXDIS, 0,        /* DISABLE a server function */
  314. #endif /* NOSERVER */
  315. #endif /* NOFRILLS */
  316. #ifndef NOSPL
  317.     "do",          XXDO,  0,        /* DO (execute) a macro */
  318. #endif /* NOSPL */
  319. #ifndef NOFRILLS
  320.     "e-packet",    XXERR, CM_INV,    /* Send an Error-Packet */
  321. #endif /* NOFRILLS */
  322.     "echo",        XXECH, 0,        /* ECHO text */
  323. #ifndef NOSPL
  324.     "else",        XXELS, CM_INV,    /* ELSE part of IF statement */
  325. #endif /* NOSPL */
  326. #ifndef NOSERVER
  327. #ifndef NOFRILLS
  328.     "enable",      XXENA, 0,        /* ENABLE a server function */
  329. #endif /* NOFRILLS */
  330. #endif /* NOSERVER */
  331. #ifndef NOSPL
  332.     "end",         XXEND, 0,        /* END command file or macro */
  333.     "evaluate",    XXEVAL, 0,        /* EVALUATE */
  334. #endif /* NOSPL */
  335.     "ex",          XXEXI, CM_INV|CM_ABR, /* Let "ex" still be EXIT */
  336.     "exit",       XXEXI, 0,         /* EXIT from C-Kermit */
  337.     "extproc",     XXCOM, CM_INV,        /* Dummy command for OS/2 */
  338.     "f",           XXFIN, CM_INV|CM_ABR, /* Invisible abbreviation for... */
  339.     "finish",      XXFIN, 0,         /* FINISH */
  340. #ifndef NOSPL
  341.     "fo",          XXFOR, CM_INV|CM_ABR, /* Invisible abbreviation for... */
  342.     "for",         XXFOR, 0,        /* FOR loop */
  343.     "forward",     XXFWD, CM_INV,    /* FORWARD (ugh) */
  344. #endif /* NOSPL */
  345. #ifndef NOFRILLS
  346.     "fot",       XXDIR, CM_INV,    /* "fot" = "dir" (for Chris) */
  347. #endif /* NOFRILLS */
  348.     "g",           XXGET, CM_INV|CM_ABR, /* Invisible abbreviation for GET */
  349. #ifndef NOSPL
  350.     "ge",          XXGET, CM_INV|CM_ABR, /* Ditto */
  351. #endif /* NOSPL */
  352.     "get",         XXGET, 0,        /* GET */
  353. #ifndef NOSPL
  354.     "getc",        XXGETC, 0,        /* GETC */
  355. #ifndef NOFRILLS
  356.     "getok",       XXGOK, 0,        /* GETOK (ask for Yes/No) */
  357. #endif /* NOFRILLS */
  358. #endif /* NOSPL */
  359. #ifndef NOSPL
  360.     "goto",        XXGOTO,0,        /* GOTO label in take file or macro */
  361. #endif /* NOSPL */
  362.     "hangup",      XXHAN, 0,        /* HANGUP the connection */
  363.     "help",       XXHLP, 0,        /* display HELP text */
  364. #ifndef NOSPL
  365.     "i",           XXINP, CM_INV|CM_ABR, /* Invisible synonym for INPUT */
  366.     "if",          XXIF,  0,         /* IF (condition) command */
  367.     "in",          XXINP, CM_INV|CM_ABR, /* Invisible synonym for INPUT */
  368.     "increment",   XXINC, 0,         /* Increment a numeric variable */
  369.     "input",       XXINP, 0,         /* INPUT text from comm device */
  370. #endif /* NOSPL */
  371. #ifndef NOHELP
  372.      "introduction", XXINT, 0,        /* Print introductory text */
  373. #endif /* NOHELP */
  374. #ifndef NOFRILLS
  375.     "l",           XXLOG, CM_INV|CM_ABR, /* Invisible synonym for log */
  376. #endif /* NOFRILLS */
  377.     "log",         XXLOG, 0,        /* Open a log file */
  378. #ifndef NOFRILLS
  379.     "ls",          XXDIR, CM_INV,    /* Invisible synonym for DIRECTORY */
  380.     "mail",        XXMAI, 0,        /* Send a file as e-mail */
  381.     "man",         XXHLP, CM_INV,       /* Synonym for HELP */
  382. #endif /* NOFRILLS */
  383. #ifdef CK_MINPUT
  384.     "minput",      XXMINP, 0,        /* MINPUT */
  385. #endif /* CK_MINPUT */
  386. #ifndef NOMSEND
  387.     "mget",        XXGET, CM_INV,    /* MGET = GET */
  388. #endif /* NOMSEND */
  389. #ifndef NOSPL
  390.     "mpause",      XXMSL, CM_INV,    /* Millisecond sleep */
  391. #endif /* NOSPL */
  392. #ifndef NOMSEND
  393.     "ms",          XXMSE, CM_INV|CM_ABR,
  394.     "msend",       XXMSE, 0,        /* Multiple SEND */
  395. #endif /* NOMSEND */
  396. #ifndef NOSPL
  397.     "msleep",      XXMSL, 0,        /* Millisecond sleep */
  398. #endif /* NOSPL */
  399. #ifndef NOMSEND
  400.     "mput",        XXMSE, CM_INV,    /* MPUT = MSEND */
  401. #endif /* NOMSEND */
  402. #ifndef NOFRILLS
  403.     "mv",          XXREN, CM_INV,    /* Synonym for rename */
  404. #endif /* NOFRILLS */
  405.     "news",        XXNEW, 0,        /* Display NEWS of new features */
  406. #ifndef NOSPL
  407.     "o",           XXOUT, CM_INV|CM_ABR, /* Invisible synonym for OUTPUT */
  408.     "open",        XXOPE, 0,        /* OPEN file for reading or writing */
  409.     "output",      XXOUT, 0,        /* OUTPUT text to comm device */
  410. #endif /* NOSPL */
  411. #ifdef ANYX25
  412.     "pad",         XXPAD, 0,            /* X.3 PAD commands */
  413. #endif /* ANYX25 */
  414. #ifndef NOSPL
  415.     "pause",       XXPAU, 0,        /* Sleep for specified interval */
  416. #ifdef TCPSOCKET
  417.     "ping",        XXPNG, 0,        /* PING (for TCP/IP) */
  418. #endif /* TCPSOCKET */
  419.     "pop",         XXEND, CM_INV,    /* Invisible synonym for END */
  420. #endif /* NOSPL */
  421. #ifndef NOFRILLS
  422.     "print",       XXPRI, 0,        /* PRINT a file locally */
  423. #ifndef NOPUSH
  424. #ifdef CK_RESEND
  425.     "psend",       XXPSEN, 0,        /* PSEND */
  426. #endif /* CK_RESEND */
  427.     "pu",          XXSHE, CM_INV,    /* PU = PUSH */
  428.     "push",        XXSHE, 0,        /* PUSH command (like RUN, !) */
  429. #endif /* NOPUSH */
  430.     "put",       XXSEN, CM_INV,    /* PUT = SEND */
  431.     "pwd",         XXPWD, 0,            /* Print Working Directory */
  432. #endif /* NOFRILLS */
  433.     "quit",       XXQUI, 0,        /* QUIT from program = EXIT */
  434.     "r",           XXREC, CM_INV|CM_ABR, /* Invisible synonym for RECEIVE */
  435. #ifndef NOSPL
  436.     "read",        XXREA, 0,            /* READ a line from a file */
  437. #endif /* NOSPL */
  438.     "receive",       XXREC, 0,        /* RECEIVE files */
  439. #ifndef NODIAL
  440. #ifdef CK_REDIR
  441.     "red",         XXRED, CM_INV|CM_ABR, /* Invisible synonym for REDIAL */
  442.     "redi",        XXRED, CM_INV|CM_ABR, /* Invisible synonym for REDIAL */
  443. #endif /* CK_REDIR */
  444.     "redial",      XXRED, 0,        /* REDIAL last DIAL number */
  445. #endif /* NODIAL */
  446. #ifndef NOPUSH
  447. #ifdef CK_REDIR
  448.     "redirect",    XXFUN, 0,        /* REDIRECT local command to ttyfd */
  449. #endif /* CK_REDIR */
  450. #endif /* NOPUSH */
  451. #ifndef NOSPL
  452.     "reinput",     XXREI, 0,            /* REINPUT (from INPUT buffer) */
  453. #endif /* NOSPL */
  454.     "remote",       XXREM, 0,        /* Send generic command to server */
  455. #ifndef NOFRILLS
  456.     "rename",      XXREN, 0,        /* RENAME a local file */
  457.     "replay",      XXTYP, CM_INV,    /* REPLAY (for now, just type) */
  458. #endif /* NOFRILLS */
  459. #ifdef CK_RESEND
  460.     "resend",      XXRSEN, 0,        /* RESEND */
  461. #endif /* CK_RESEND */
  462. #ifndef NOSPL
  463.     "return",      XXRET, 0,        /* RETURN from a function */
  464. #endif /* NOSPL */
  465. #ifndef NOPUSH
  466. #ifdef CK_REXX
  467.     "rexx",      XXREXX, 0,        /* Execute a Rexx command */
  468. #endif /* CK_REXX */
  469. #endif /* NOPUSH */
  470. #ifndef NOFRILLS
  471.     "rm",          XXDEL, CM_INV,    /* Invisible synonym for delete */
  472. #endif /* NOFRILLS */
  473. #ifndef NOPUSH
  474.     "run",         XXSHE, 0,        /* RUN a program or command */
  475. #endif /* NOPUSH */
  476.     "s",           XXSEN, CM_INV|CM_ABR, /* Invisible synonym for send */
  477. #ifndef NOSCRIPT
  478.     "script",       XXLOGI,0,        /* Execute a UUCP-style script */
  479. #endif /* NOSCRIPT */
  480.     "send",       XXSEN, 0,        /* Send (a) file(s) */
  481. #ifndef NOSERVER
  482.     "server",       XXSER, 0,        /* Be a SERVER */
  483. #endif /* NOSERVER */
  484.     "set",       XXSET, 0,        /* SET parameters */
  485. #ifndef NOSHOW
  486.     "show",        XXSHO, 0,        /* SHOW parameters */
  487. #endif /* NOSHOW */
  488. #ifndef NOSPL
  489. #ifndef NOFRILLS
  490.     "sleep",       XXPAU, CM_INV,    /* SLEEP for specified interval */
  491. #endif /* NOFRILLS */
  492. #endif /* NOSPL */
  493. #ifndef MAC
  494. #ifndef NOFRILLS
  495.     "sp",          XXSPA, CM_INV|CM_ABR,
  496.     "spa",         XXSPA, CM_INV|CM_ABR,
  497. #endif /* NOFRILLS */
  498.     "space",       XXSPA, 0,        /* Show available disk SPACE */
  499. #endif /* MAC */
  500. #ifndef NOFRILLS
  501. #ifndef NOPUSH
  502.     "spawn",       XXSHE, CM_INV,    /* Synonym for PUSH, RUN */
  503. #endif /* NOPUSH */
  504. #endif /* NOFRILLS */
  505.     "statistics",  XXSTA, 0,        /* Display file transfer stats */
  506. #ifndef NOSPL
  507.     "stop",        XXSTO, 0,        /* STOP all take files and macros */
  508. #endif /* NOSPL */
  509. #ifndef NOJC
  510.     "suspend",     XXSUS, 0,        /* SUSPEND C-Kermit (UNIX only) */
  511. #endif /* NOJC */
  512.     "take",       XXTAK, 0,        /* TAKE commands from a file */
  513. #ifndef NOFRILLS
  514. #ifdef TCPSOCKET
  515.     "telnet",      XXTEL, 0,        /* TELNET (TCP/IP only) */
  516. #endif /* TCPSOCKET */
  517. #ifdef DEBUG
  518.     "test",        XXTES, CM_INV,    /* (for testing) */
  519. #endif /* DEBUG */
  520. #endif /* NOFRILLS */
  521. #ifndef NOCSETS
  522.     "translate",   XXXLA, 0,        /* TRANSLATE local file char sets */
  523. #endif
  524. #ifndef NOXMIT
  525.     "transmit",    XXTRA, 0,        /* Send (upload) a file, no protocol */
  526. #endif /* NOXMIT */
  527. #ifndef NOFRILLS
  528.     "type",        XXTYP, 0,        /* Display a local file */
  529. #endif /* NOFRILLS */
  530.     "version",     XXVER, 0        /* VERSION-number display */
  531. #ifndef NOSPL
  532. ,   "wait",        XXWAI, 0        /* WAIT (like pause) */
  533. ,   "while",       XXWHI, 0        /* WHILE loop */
  534. #endif /* NOSPL */
  535. #ifndef MAC
  536. #ifndef NOFRILLS
  537. ,   "who",         XXWHO, 0        /* WHO's logged in? */
  538. #endif /* NOFRILLS */
  539. #endif /* MAC */
  540. #ifndef NOSPL
  541. ,   "wr",          XXWRI, CM_INV|CM_ABR
  542. ,   "wri",         XXWRI, CM_INV|CM_ABR
  543. ,   "writ",        XXWRI, CM_INV|CM_ABR
  544. ,   "write",       XXWRI, 0        /* WRITE characters to a file */
  545. ,   "write-line",  XXWRL, 0        /* WRITE a line to a file */
  546. ,   "writeln",     XXWRL, CM_INV    /* Pascalisch synonym for write-line */
  547. ,   "xif",         XXIFX, 0        /* Extended IF command */
  548. #endif /* NOSPL */
  549. #ifndef NOCSETS
  550. ,   "xlate",       XXXLA, CM_INV    /* Synonym for TRANSLATE */
  551. #endif
  552. #ifndef NOXMIT
  553. ,   "xmit",        XXTRA, CM_INV    /* Synonym for TRANSMIT */
  554. #endif /* NOXMIT */
  555. ,   "z",           XXSUS, CM_INV    /* Synonym for SUSPEND */
  556. #ifndef NOSPL
  557. ,   "_assign",     XXASX, CM_INV    /* Used internally by FOR, etc */
  558. ,   "_define",     XXDFX, CM_INV    /* Used internally by FOR, etc */
  559. ,   "_getargs",    XXGTA, CM_INV        /* Used internally by FOR, etc */
  560. ,   "_putargs",    XXPTA, CM_INV        /* Used internally by FOR, etc */
  561. #endif /* NOSPL */
  562. };
  563. int ncmd = (sizeof(cmdtab) / sizeof(struct keytab));
  564.  
  565. char toktab[] = {
  566. #ifndef NOPUSH
  567.     '!',                /* Shell escape */
  568. #endif /* NOPUSH */
  569.     '#',                /* Comment */
  570.     ';',                /* Comment */
  571. #ifndef NOSPL
  572.     ':',                /* Label */
  573. #endif /* NOSPL */
  574. #ifndef NOPUSH
  575. #ifdef CK_REDIR
  576.     '<',                /* REDIRECT */
  577. #endif /* CK_REDIR */
  578.     '@',                /* DCL escape */
  579. #endif /* NOPUSH */
  580.     '\0'                /* End of this string */
  581. };
  582.  
  583. struct keytab yesno[] = {        /* Yes/No keyword table */
  584.     "no",    0, 0,
  585.     "ok",    1, 0,
  586.     "yes",   1, 0
  587. };
  588. int nyesno = (sizeof(yesno) / sizeof(struct keytab));
  589.  
  590. /* Parameter keyword table */
  591.  
  592. struct keytab prmtab[] = {
  593.     "attributes",       XYATTR,  0,
  594.     "b",        XYBACK,  CM_INV|CM_ABR,
  595.     "ba",        XYBACK,  CM_INV|CM_ABR,
  596.     "background",       XYBACK,  0,
  597. #ifndef NOLOCAL
  598.     "baud",            XYSPEE,  CM_INV,
  599. #endif /* NOLOCAL */
  600.     "block-check",      XYCHKT,  0,
  601. #ifdef DYNAMIC
  602.     "buffers",          XYBUF,   0,
  603. #endif /* DYNAMIC */
  604. #ifndef NOLOCAL
  605. #ifndef MAC
  606.     "carrier",          XYCARR,  0,
  607. #endif /* MAC */
  608. #endif /* NOLOCAL */
  609. #ifndef NOSPL
  610.     "case",             XYCASE,  0,
  611. #endif /* NOSPL */
  612.     "cmd",              XYCMD,   CM_INV,
  613.     "command",          XYCMD,   0,
  614.     "con",              XYQCTL,  CM_INV|CM_ABR,
  615.     "console",          XYCMD,   CM_INV,
  616. #ifdef CK_SPEED
  617.     "control-character",XYQCTL,  0,
  618. #endif /* CK_SPEED */
  619. #ifndef NOSPL
  620.     "count",            XYCOUN,  0,
  621. #endif /* NOSPL */
  622.     "d",        XYDELA,  CM_INV|CM_ABR,
  623.     "de",        XYDELA,  CM_INV|CM_ABR,
  624.     "debug",            XYDEBU,  CM_INV,
  625. #ifdef VMS
  626.     "default",          XYDFLT,  0,
  627. #else
  628. #ifndef MAC
  629.     "default",          XYDFLT,  CM_INV,
  630. #endif /* MAC */
  631. #endif /* VMS */
  632.     "delay",            XYDELA,  0,
  633. #ifndef NODIAL
  634.     "dial",             XYDIAL,  0,
  635. #endif /* NODIAL */
  636. #ifndef NOLOCAL
  637.     "duplex",            XYDUPL,  0,
  638.     "escape-character", XYESC,   0,
  639. #endif /* NOLOCAL */
  640.     "exit",        XYEXIT,  0,
  641.     "file",           XYFILE,  0,
  642.     "flow-control",     XYFLOW,  0,
  643.     "handshake",        XYHAND,  0,
  644. #ifdef NETCONN
  645.     "host",             XYHOST,  0,
  646. #endif /* NETCONN */
  647.     "incomplete",       XYIFD,   CM_INV,
  648. #ifndef NOSPL
  649.     "i",        XYINPU,  CM_INV|CM_ABR,
  650.     "in",        XYINPU,  CM_INV|CM_ABR,
  651.     "input",            XYINPU,  0,
  652. #endif /* NOSPL */
  653. #ifndef NOSETKEY
  654.     "key",        XYKEY,   0,
  655. #endif /* NOSETKEY */
  656.     "l",                XYLINE,  CM_INV|CM_ABR,
  657. #ifndef NOCSETS
  658.     "language",         XYLANG,  0,
  659. #endif /* NOCSETS */
  660.     "line",             XYLINE,  0,
  661. #ifndef NOLOCAL
  662.     "local-echo",    XYLCLE,  CM_INV,
  663. #endif /* NOLOCAL */
  664. #ifndef NOSPL
  665.     "macro",            XYMACR,  0,
  666. #endif /* NOSPL */
  667. #ifdef COMMENT
  668. #ifdef VMS
  669.     "messages",         XYMSGS,  0,
  670. #endif /* VMS */
  671. #endif /* COMMENT */
  672. #ifndef NODIAL
  673.     "modem-dialer",    XYMODM,     0,
  674. #endif /* NODIAL */
  675. #ifdef NETCONN
  676.     "network",          XYNET,   0,
  677. #endif /* NETCONN */
  678. #ifndef NOSPL
  679.     "output",           XYOUTP,  0,
  680. #endif /* NOSPL */
  681. #ifdef ANYX25
  682.     "pad",              XYPAD,   0,
  683. #endif /* ANYX25 */
  684.     "parity",            XYPARI,  0,
  685.     "port",             XYLINE,  CM_INV,
  686. #ifdef OS2
  687.     "pr",            XYPROM,  CM_INV|CM_ABR,
  688.     "printer",          XYPRTR,  0,
  689. #endif /* OS2 */
  690. #ifndef NOFRILLS
  691.     "prompt",            XYPROM,  0,
  692. #endif /* NOFRILLS */
  693.     "quiet",        XYQUIE,  0,
  694.     "receive",          XYRECV,  0,
  695.     "repeat",           XYREPT,  0,
  696.     "retry-limit",      XYRETR,  0,
  697. #ifndef NOSCRIPT
  698.     "script",        XYSCRI,  0,
  699. #endif /* NOSCRIPT */
  700.     "send",             XYSEND,  0,
  701. #ifndef NOSERVER
  702.     "server",           XYSERV,  0,
  703. #endif /* NOSERVER */
  704. #ifdef UNIX
  705. #ifndef NOLOCAL
  706.     "session-log",      XYSESS,  0,
  707. #endif /* NOLOCAL */
  708. #endif /* UNIX */
  709. #ifndef NOLOCAL
  710.     "speed",            XYSPEE,  0,
  711. #endif /* NOLOCAL */
  712. #ifndef NOJC
  713.     "suspend",          XYSUSP,  0,
  714. #endif /* NOJC */
  715.     "take",             XYTAKE,  0,
  716. #ifdef TNCODE
  717.     "telnet",           XYTEL,   0,
  718. #endif /* TNCODE */
  719. #ifndef NOLOCAL
  720.     "terminal",         XYTERM,  0,
  721. #endif /* NOLOCAL */
  722.     "transfer",         XYXFER,  0,
  723. #ifndef NOXMIT
  724.     "transmit",         XYXMIT,  0,
  725. #endif /* NOXMIT */
  726. #ifndef NOCSETS
  727.     "unknown-char-set", XYUNCS,  0,
  728. #endif /* NOCSETS */
  729. #ifndef NOPUSH
  730. #ifdef UNIX
  731.     "wildcard-expansion", XYWILD, 0,
  732. #endif /* UNIX */
  733. #endif /* NOPUSH */
  734.     "window-size",      XYWIND,  0
  735. #ifdef ANYX25
  736. ,   "x.25",             XYX25,   0,
  737.     "x25",              XYX25,   CM_INV
  738. #endif /* ANYX25 */
  739. #ifndef NOCSETS
  740. ,   "xfer",             XYXFER,  CM_INV
  741. #endif /* NOCSETS */
  742. #ifndef NOXMIT
  743. ,   "xmit",             XYXMIT,  CM_INV
  744. #endif /* NOXMIT */
  745. };
  746. int nprm = (sizeof(prmtab) / sizeof(struct keytab)); /* How many parameters */
  747.  
  748. /* Table of networks */
  749. #ifdef NETCONN
  750. struct keytab netcmd[] = {
  751.  
  752. #ifdef NEEDCOMMA
  753. #undef NEEDCOMMA
  754. #endif /* NEEDCOMMA */
  755.  
  756. #ifdef DECNET                /* DECnet / PATHWORKS */
  757.     "decnet",        NET_DEC,  0
  758. #define NEEDCOMMA
  759. #endif /* DECNET */
  760.  
  761. #ifdef NPIPE                /* Named Pipes */
  762. #ifdef NEEDCOMMA
  763. ,
  764. #else
  765. #define NEEDCOMMA
  766. #endif /* NEEDCOMMA */
  767.     "named-pipe",    NET_PIPE, 0
  768. #endif /* NPIPE */
  769.  
  770. #ifdef CK_NETBIOS
  771. #ifdef NEEDCOMMA
  772. ,
  773. #else
  774. #define NEEDCOMMA
  775. #endif /* NEEDCOMMA */
  776.     "netbios",    NET_BIOS, 0
  777. #endif /* CK_NETBIOS */
  778.  
  779. #ifdef TCPSOCKET            /* TCP/IP sockets library */
  780. #ifdef NEEDCOMMA
  781. ,
  782. #else
  783. #define NEEDCOMMA
  784. #endif /* NEEDCOMMA */
  785.     "tcp/ip",        NET_TCPB, 0
  786. #endif /* TCPSOCKET */
  787.  
  788. #ifdef ANYX25                /* X.25 */
  789. #ifdef NEEDCOMMA
  790. ,
  791. #endif /* NEEDCOMMA */
  792. #ifdef SUNX25
  793.     "x",            NET_SX25, CM_INV|CM_ABR,
  794.     "x.25",         NET_SX25, 0,
  795.     "x25",          NET_SX25, CM_INV
  796. #else
  797. #ifdef STRATUSX25
  798.     "x",            NET_VX25, CM_INV|CM_ABR,
  799.     "x.25",         NET_VX25, 0,
  800.     "x25",          NET_VX25, CM_INV
  801. #endif /* STRATUSX25 */
  802. #endif /* SUNX25 */
  803. #endif /* ANYX25 */
  804.  
  805. #ifdef NEEDCOMMA            /* Get rid of clutter */
  806. #undef NEEDCOMMA
  807. #endif /* NEEDCOMMA */
  808. };
  809. int nnets = (sizeof(netcmd) / sizeof(struct keytab)); /* How many networks */
  810. #endif /* NETCONN */
  811.  
  812. /* Remote Command Table */
  813.  
  814. struct keytab remcmd[] = {
  815. #ifndef NOSPL
  816.     "as",     XZASG, CM_INV|CM_ABR,
  817.     "asg",     XZASG, CM_INV,
  818.     "assign",     XZASG, 0,
  819. #endif /* NOSPL */
  820.     "cd",        XZCWD, 0,
  821.     "cwd",       XZCWD, CM_INV,
  822.     "delete",    XZDEL, 0,
  823.     "directory", XZDIR, 0,
  824.     "help",      XZHLP, 0,
  825. #ifndef NOPUSH
  826.     "host",      XZHOS, 0,
  827. #endif /* NOPUSH */
  828. #ifndef NOFRILLS
  829.     "kermit",    XZKER, 0,
  830.     "login",     XZLGI, 0,
  831.     "logout",    XZLGO, 0,
  832.     "print",     XZPRI, 0,
  833. #endif /* NOFRILLS */
  834.     "pwd",       XZPWD, 0,
  835. #ifndef NOSPL
  836.     "query",     XZQUE, 0,
  837. #endif /* NOSPL */
  838.     "set",       XZSET, 0,
  839.     "space",     XZSPA, 0
  840. #ifndef NOFRILLS
  841. ,   "type",      XZTYP, 0,
  842.     "who",       XZWHO, 0
  843. #endif /* NOFRILLS */
  844. };
  845. int nrmt = (sizeof(remcmd) / sizeof(struct keytab));
  846.  
  847. struct keytab logtab[] = {
  848. #ifdef DEBUG
  849.     "debugging",    LOGD, 0,
  850. #endif /* DEBUG */
  851.     "packets",        LOGP, 0
  852. #ifndef NOLOCAL
  853. ,   "session",      LOGS, 0
  854. #endif /* NOLOCAL */
  855. #ifdef TLOG
  856. ,   "transactions", LOGT, 0
  857. #endif /* TLOG */
  858. };
  859. int nlog = (sizeof(logtab) / sizeof(struct keytab));
  860.  
  861. struct keytab writab[] = {
  862. #ifndef NOSPL
  863.     "append-file",     LOGW, CM_INV,
  864. #endif /* NOSPL */
  865.     "debug-log",       LOGD, 0,
  866.     "error",           LOGE, 0,
  867. #ifndef NOSPL
  868.     "file",            LOGW, 0,
  869. #endif /* NOSPL */
  870.     "packet-log",      LOGP, 0,
  871.     "screen",          LOGX, 0,
  872. #ifndef NOLOCAL
  873.     "session-log",     LOGS, 0,
  874. #endif /* NOLOCAL */
  875.     "sys$output",      LOGX, CM_INV,
  876.     "transaction-log", LOGT, 0
  877. #ifdef COMMENT
  878. ,   "transactions",    LOGT, CM_INV
  879. #endif /* COMMENT */
  880. };
  881. int nwri = (sizeof(writab) / sizeof(struct keytab));
  882.  
  883. #define CLR_DEV  1
  884. #define CLR_INP  2
  885.  
  886. static struct keytab clrtab[] = {    /* Keywords for CLEAR command */
  887. #ifndef NOSPL
  888.     "both",          CLR_DEV|CLR_INP, 0,
  889. #endif /* NOSPL */
  890.     "device-buffer", CLR_DEV,         0,
  891. #ifndef NOSPL
  892.     "input-buffer",  CLR_INP,         0
  893. #endif /* NOSPL */
  894. };
  895. int nclear = (sizeof(clrtab) / sizeof(struct keytab));
  896.  
  897. struct keytab clstab[] = {        /* Keywords for CLOSE command */
  898. #ifndef NOSPL
  899.     "append-file",     LOGW, CM_INV,
  900. #endif /* NOSPL */
  901. #ifdef DEBUG
  902.     "debug-log",       LOGD, 0,
  903. #endif /* DEBUG */
  904.     "packet-log",      LOGP, 0
  905. #ifndef NOSPL
  906. ,   "read-file",       LOGR, 0
  907. #endif /* NOSPL */
  908. #ifndef NOLOCAL
  909. ,   "session-log",     LOGS, 0
  910. #endif /* NOLOCAL */
  911. #ifdef TLOG
  912. ,   "transaction-log", LOGT, 0
  913. #endif /* TLOG */
  914. #ifndef NOSPL
  915. ,   "write-file",      LOGW, 0
  916. #endif /* NOSPL */
  917. };
  918. int ncls = (sizeof(clstab) / sizeof(struct keytab));
  919.  
  920. /* SHOW command arguments */
  921.  
  922. struct keytab shotab[] = {
  923. #ifndef NOSPL
  924.     "arguments", SHARG, 0,
  925.     "arrays", SHARR, 0,
  926. #endif /* NOSPL */
  927.     "attributes", SHATT, 0,
  928.     "character-sets", SHCSE, 0,
  929.     "cmd",  SHCMD, CM_INV,
  930.     "com",  SHCOM, CM_INV|CM_ABR,
  931.     "comm", SHCOM, CM_INV|CM_ABR,
  932.     "communications", SHCOM, 0,
  933.     "command", SHCMD, 0,
  934. #ifdef CK_SPEED
  935.     "control-prefixing", SHCTL, 0,
  936. #endif /* CK_SPEED */
  937. #ifndef NOSPL
  938.     "count", SHCOU, 0,
  939. #endif /* NOSPL */
  940.     "d",       SHDIA, CM_INV|CM_ABR,
  941. #ifdef VMS
  942.     "default", SHDFLT, 0,
  943. #else
  944.     "default", SHDFLT, CM_INV,
  945. #endif /* VMS */
  946. #ifndef NODIAL
  947.     "dial", SHDIA, 0,
  948. #endif /* NODIAL */
  949. #ifndef NOLOCAL
  950.     "escape", SHESC, 0,
  951. #endif /* NOLOCAL */
  952.     "exit", SHEXI, 0,
  953.     "features", SHFEA, 0,
  954.     "file", SHFIL, 0,
  955. #ifndef NOSPL
  956.     "functions", SHFUN, 0,
  957.     "globals", SHVAR, 0,
  958. #endif /* NOSPL */
  959. #ifndef NOSETKEY
  960.     "k",   SHKEY, CM_INV|CM_ABR,
  961.     "key", SHKEY, 0,
  962. #ifndef NOKVERBS
  963.     "kverbs", SHKVB, 0,
  964. #endif /* NOKVERBS */
  965. #endif /* NOSETKEY */
  966. #ifdef CK_LABELED
  967.     "labeled-file-info", SHLBL, 0,
  968. #endif /* CK_LABELED */
  969. #ifndef NOCSETS
  970.     "languages", SHLNG, 0,
  971. #endif /* NOCSETS */
  972. #ifndef NOSPL
  973.     "macros", SHMAC, 0,
  974. #endif /* NOSPL */
  975.     "modem-signals", SHMOD, 0,
  976. #ifdef NETCONN
  977.     "network", SHNET, 0,
  978. #endif /* NETCONN */
  979. #ifdef ANYX25
  980.     "pad", SHPAD, 0,
  981. #endif /* ANYX25 */
  982.     "parameters", SHPAR, CM_INV,
  983. #ifdef OS2
  984.     "pr",       SHPRO, CM_INV|CM_ABR,
  985.     "printer",  SHPRT, 0,
  986. #endif /* OS2 */
  987.     "protocol", SHPRO, 0,
  988. #ifndef NOSPL
  989.     "scripts", SHSCR, 0,
  990. #endif /* NOSPL */
  991. #ifndef NOSERVER
  992.     "server", SHSER, 0,
  993. #endif /* NOSERVER */
  994.     "status", SHSTA, 0
  995. #ifdef MAC
  996. ,   "stack", SHSTK, 0            /* debugging */
  997. #endif /* MAC */
  998. #ifndef NOLOCAL
  999. ,   "terminal", SHTER, 0
  1000. #endif /* NOLOCAL */
  1001. #ifndef NOXMIT
  1002. ,   "transmit", SHXMI, 0
  1003. #endif /* NOXMIT */
  1004. #ifndef NOSPL
  1005. ,   "variables", SHBUI, 0
  1006. #endif /* NOSPL */
  1007. #ifndef NOFRILLS
  1008. ,   "versions", SHVER, 0
  1009. #endif /* NOFRILLS */
  1010. #ifndef NOXMIT
  1011. ,   "xmit", SHXMI, CM_INV
  1012. #endif /* NOXMIT */
  1013. };
  1014. int nsho = (sizeof(shotab) / sizeof(struct keytab));
  1015.  
  1016. #ifdef ANYX25
  1017. struct keytab padtab[] = {              /* PAD commands */
  1018.     "clear",      XYPADL, 0,
  1019.     "interrupt",  XYPADI, 0,
  1020.     "reset",      XYPADR, 0,
  1021.     "status",     XYPADS, 0
  1022. };
  1023. int npadc = (sizeof(padtab) / sizeof(struct keytab));
  1024. #endif /* ANYX25 */
  1025.  
  1026. #ifndef NOSERVER
  1027. static struct keytab enatab[] = {    /* ENABLE commands */
  1028.     "all",        EN_ALL,  0,
  1029. #ifndef NOSPL
  1030.     "as",         EN_ASG,  CM_INV|CM_ABR,
  1031.     "asg",        EN_ASG,  CM_INV,
  1032.     "assign",     EN_ASG,  0,
  1033. #endif /* NOSPL */
  1034. #ifndef datageneral
  1035.     "bye",        EN_BYE,  0,
  1036. #endif /* datageneral */
  1037.     "cd",         EN_CWD,  0,
  1038.     "cwd",        EN_CWD,  CM_INV,
  1039.     "delete",     EN_DEL,  0,
  1040.     "directory",  EN_DIR,  0,
  1041.     "finish",     EN_FIN,  0,
  1042.     "get",        EN_GET,  0,
  1043.     "host",       EN_HOS,  0,
  1044. #ifndef NOSPL
  1045.     "query",      EN_QUE,  0,
  1046. #endif /* NOSPL */
  1047.     "send",       EN_SEN,  0,
  1048.     "set",        EN_SET,  0,
  1049.     "space",      EN_SPA,  0,
  1050.     "type",       EN_TYP,  0,
  1051.     "who",        EN_WHO,  0
  1052. };
  1053. static int nena = (sizeof(enatab) / sizeof(struct keytab));
  1054. #endif /* NOSERVER */
  1055.  
  1056. #ifndef NOLOCAL
  1057. static struct keytab conntab[] = {    /* CONNECT options */
  1058.     "/quietly", 1, 0
  1059. };
  1060. #endif /* NOLOCAL */
  1061.  
  1062. #ifndef NOSPL
  1063. #ifdef COMMENT
  1064. struct mtab mactab[MAC_MAX] = {        /* Preinitialized macro table */
  1065.     NULL, NULL, 0
  1066. };
  1067. #else
  1068. struct mtab *mactab;            /* Dynamically allocated macro table */
  1069. #endif /* COMMENT */
  1070. int nmac = 0;
  1071.  
  1072. struct keytab mackey[MAC_MAX];        /* Macro names as command keywords */
  1073. #endif /* NOSPL */
  1074.  
  1075. /* Forward declarations of functions */
  1076.  
  1077. _PROTOTYP (int doask,   ( int  ) );
  1078. _PROTOTYP (int dodef,   ( int  ) );
  1079. _PROTOTYP (int dodel,   ( void ) );
  1080. _PROTOTYP (int dodial,  ( int  ) );
  1081. _PROTOTYP (int dodir,   ( void ) );
  1082. _PROTOTYP (int doelse,  ( void ) );
  1083. _PROTOTYP (int dofor,   ( void ) );
  1084. _PROTOTYP (int dogta,   ( int  ) );
  1085. _PROTOTYP (int doincr,  ( int  ) );
  1086. _PROTOTYP (int dopaus,  ( int  ) );
  1087. _PROTOTYP (int doping,  ( void ) );
  1088. _PROTOTYP (int dorenam, ( void ) );
  1089. #ifdef CK_REXX
  1090. _PROTOTYP (int dorexx,  ( void ) );
  1091. #endif /* CK_REXX */
  1092. #ifdef CK_REDIR
  1093. _PROTOTYP (int ttruncmd, ( char * ) );
  1094. #endif /* CK_REDIR */
  1095.  
  1096. #ifdef TCPSOCKET
  1097. int
  1098. doping() {
  1099.     char *p;
  1100.     int x;
  1101.  
  1102.     if (network)            /* If we have a current connection */
  1103.       strcpy(line,ttname);        /* get the host name */
  1104.     else *line = '\0';            /* as default host to be pinged. */
  1105.     for (p = line; *p; p++)        /* Remove ":service" from end. */
  1106.       if (*p == ':') { *p = '\0'; break; }
  1107.     if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
  1108.       return(x);
  1109. /* Construct PING command */
  1110. #ifdef VMS
  1111. #ifdef MULTINET                /* TGV MultiNet */
  1112.     sprintf(line,"multinet ping %s /num=1",s);
  1113. #else
  1114.     sprintf(line,"ping %s 56 1",s);    /* Other VMS TCP/IP's */
  1115. #endif /* MULTINET */
  1116. #else                    /* Not VMS */
  1117.     sprintf(line,"ping %s",s);
  1118. #endif /* VMS */
  1119.     conres();                /* Make console normal  */
  1120. #ifdef DEC_TCPIP
  1121.     printf("\n");            /* Prevent prompt-stomping */
  1122. #endif /* DEC_TCPIP */
  1123.     x = zshcmd(line);
  1124.     concb((char)escape);
  1125.     return(success = 1);        /* We don't know the status */
  1126. }
  1127. #endif /* TCPSOCKET */
  1128.  
  1129. /*  D O C M D  --  Do a command  */
  1130.  
  1131. /*
  1132.  Returns:
  1133.    -2: user typed an illegal command
  1134.    -1: reparse needed
  1135.     0: parse was successful (even tho command may have failed).
  1136. */
  1137. int
  1138. docmd(cx) int cx; {
  1139.  
  1140.     debug(F101,"docmd entry, cx","",cx);
  1141.  
  1142. /*
  1143.   Massive switch() broken up into many smaller ones, for the benefit of
  1144.   compilers that run out of space when trying to handle large switch
  1145.   statements.
  1146. */
  1147.     switch (cx) {
  1148.       case -4:            /* EOF */
  1149. #ifdef OSK
  1150.     if (msgflg)  printf("\n");
  1151. #else
  1152.     if (msgflg)  printf("\r\n");
  1153. #endif /* OSK */
  1154.       doexit(GOOD_EXIT,xitsta);
  1155.       case -3:                /* Null command */
  1156.     return(0);
  1157.       case -9:                /* Like -2, but errmsg already done */
  1158.       case -1:                /* Reparse needed */
  1159.     return(cx);
  1160.       case -6:                /* Special */
  1161.       case -2:                /* Error, maybe */
  1162. #ifndef NOSPL
  1163. /*
  1164.   Maybe they typed a macro name.  Let's look it up and see.
  1165. */
  1166.     if (cx == -6)            /* If they typed CR */
  1167.       strcat(cmdbuf,"\015");    /*  add it back to command buffer. */
  1168.     if (ifcmd[cmdlvl] == 2)        /* Watch out for IF commands. */
  1169.       ifcmd[cmdlvl]--;
  1170.     repars = 1;            /* Force reparse */
  1171.     cmres();
  1172.     cx = XXDO;            /* Try DO command */
  1173. #else
  1174.     return(cx);
  1175. #endif /* NOSPL */
  1176.       default:
  1177.     break;
  1178.     }
  1179.  
  1180. #ifndef NOSPL
  1181. /* Copy macro args from/to two levels up, used internally by _floop et al. */
  1182.     if (cx == XXGTA || cx == XXPTA) {    /* _GETARGS, _PUTARGS */
  1183.     int x;
  1184.     debug(F101,"docmd XXGTA","",XXGTA);
  1185.     debug(F101,"docmd cx","",cx);
  1186.     debug(F101,"docmd XXGTA maclvl","",maclvl);
  1187.     x = dogta(cx);
  1188.     debug(F101,"docmd dogta returns","",x);
  1189.     debug(F101,"docmd dogta maclvl","",maclvl);
  1190.     return(x);
  1191.     }
  1192. #endif /* NOSPL */
  1193.  
  1194. #ifndef NOSPL
  1195. /* ASK, ASKQ, READ */
  1196.     if (cx == XXASK || cx == XXASKQ || cx == XXREA || cx == XXGETC) {
  1197.     return(doask(cx));
  1198.     }
  1199. #endif /* NOSPL */
  1200.  
  1201. #ifndef NOFRILLS
  1202.     if (cx == XXBUG) {            /* BUG */
  1203.     if ((x = cmcfm()) < 0) return(x);
  1204.     return(dobug());
  1205.     }
  1206. #endif /* NOFRILLS */
  1207.  
  1208.     if (cx == XXBYE) {            /* BYE */
  1209.     if ((x = cmcfm()) < 0) return(x);
  1210.     sstate = setgen('L',"","","");
  1211.     if (local) ttflui();        /* If local, flush tty input buffer */
  1212.     return(0);
  1213.     }
  1214.  
  1215. #ifndef NOFRILLS
  1216.     if (cx == XXCLE) {            /* CLEAR */
  1217.     if ((x = cmkey(clrtab,nclear,"buffer(s) to clear",
  1218. #ifdef NOSPL
  1219.           "device-buffer"
  1220. #else
  1221.           "both"
  1222. #endif /* NOSPL */
  1223.           ,xxstring)) < 0) return(x);
  1224.     if ((y = cmcfm()) < 0) return(y);
  1225.  
  1226.     /* Clear device input buffer if requested */
  1227.     y = (x & CLR_DEV) ? ttflui() : 0;
  1228. #ifndef NOSPL
  1229.     /* Clear INPUT command buffer if requested */
  1230.     if (x & CLR_INP) {
  1231.         for (x = 0; x < INPBUFSIZ; x++)
  1232.           inpbuf[x] = 0;
  1233.         inpbp = inpbuf;
  1234.     }
  1235. #endif /* NOSPL */
  1236.     return(success = (y == 0));
  1237.     }
  1238. #endif /* NOFRILLS */
  1239.  
  1240.     if (cx == XXCOM) {            /* COMMENT */
  1241.     if ((x = cmtxt("Text of comment line","",&s,NULL)) < 0)
  1242.       return(x);
  1243.     /* Don't change SUCCESS flag for this one */
  1244.     return(0);
  1245.     }
  1246.  
  1247. #ifndef NOLOCAL
  1248.     if (cx == XXCON) {            /* CONNECT */
  1249.     if ((x = cmkey(conntab,1,"Carriage return to confirm, or option",
  1250.                "",xxstring)) < 0) {
  1251.         if (x == -3)
  1252.           return(success = doconect(0));
  1253.         else return(x);
  1254.     }
  1255.     if ((y = cmcfm()) < 0)
  1256.       return(y);
  1257.     return(success = doconect(x));
  1258.     }
  1259. #endif /* NOLOCAL */
  1260.  
  1261.     if (cx == XXCWD)            /* CWD */
  1262.       return(success = docd());
  1263.  
  1264.     if (cx == XXCHK)            /* CHECK */
  1265.       return(success = dochk());
  1266.  
  1267.     if (cx == XXCLO) {            /* CLOSE */
  1268.     x = cmkey(clstab,ncls,"Which log or file to close","",xxstring);
  1269.     if (x == -3) {
  1270.         printf("?You must say which file or log\n");
  1271.         return(-9);
  1272.     }
  1273.     if (x < 0) return(x);
  1274.     if ((y = cmcfm()) < 0) return(y);
  1275.     y = doclslog(x);
  1276.     success = (y == 1);
  1277.     return(success);
  1278.     }
  1279.  
  1280. #ifndef NOSPL
  1281.     if (cx == XXDEC || cx == XXINC)    /* DECREMENT, INCREMENT */
  1282.       return(doincr(cx));
  1283.  
  1284.     if (cx == XXEVAL) {
  1285.     char *p;
  1286.     if ((x = cmtxt("Integer arithmetic expression","",&s,xxstring)) < 0)
  1287.       return(x);
  1288.     p = evala(s);
  1289.     if (!p) p = "";
  1290.     if (*p)
  1291.       printf("%s\n", p);
  1292.     strncpy(evalbuf,p,32);
  1293.     return(success = *p ? 1 : 0);
  1294.     }
  1295. #endif /* NOSPL */
  1296.  
  1297. #ifndef NOSPL
  1298.     if (cx == XXDEF || cx == XXASS || cx == XXASX || cx == XXDFX)
  1299.       return(dodef(cx));        /* DEFINE, ASSIGN */
  1300. #endif /* NOSPL */
  1301.  
  1302. #ifndef NOSPL
  1303.     if (cx == XXDCL) {            /* DECLARE an array */
  1304.     if ((y = cmfld("Array name","",&s,NULL)) < 0) {
  1305.         if (y == -3) {
  1306.         printf("?Array name required\n");
  1307.         return(-9);
  1308.         } else return(y);
  1309.     }
  1310.     if ((y = arraynam(s,&x,&z)) < 0) return(y);
  1311.     if ((y = cmcfm()) < 0) return(y);
  1312.     if (dclarray((char)x,z) < 0) {
  1313.         printf("?Declare failed\n");
  1314.         return(success = 0);
  1315.     }
  1316.     return(success = 1);
  1317.     }
  1318. #endif /* NOSPL */
  1319.  
  1320.  
  1321. #ifndef NODIAL
  1322.     if (cx == XXRED || cx == XXDIAL)    /* DIAL or REDIAL */
  1323.       return(dodial(cx));
  1324. #endif /* NODIAL */
  1325.  
  1326. #ifndef NOPUSH
  1327. #ifdef CK_REXX
  1328.     if (cx == XXREXX)            /* REXX */
  1329.       return(dorexx());
  1330. #endif /* CK_REXX */
  1331. #endif /* NOPUSH */
  1332.  
  1333. #ifndef NOFRILLS
  1334.     if (cx == XXDEL) {            /* DELETE */
  1335. #ifdef CK_APC
  1336.     if (apcactive && apcstatus != APC_UNCH) return(success = 0);
  1337. #endif /* CK_APC */
  1338.     return(dodel());
  1339.     }
  1340. #endif /* NOFRILLS */
  1341.  
  1342.     if (cx == XXDIR)            /* DIRECTORY */
  1343.       return(dodir());
  1344.  
  1345. #ifndef NOSPL
  1346.     if (cx == XXELS)            /* ELSE */
  1347.       return(doelse());
  1348. #endif /* NOSPL */
  1349.  
  1350. #ifndef NOSERVER
  1351. #ifndef NOFRILLS
  1352.     if (cx == XXENA || cx == XXDIS) {    /* ENABLE, DISABLE */
  1353.     s = (cx == XXENA) ?
  1354.       "Server function to enable" :
  1355.         "Server function to disable";
  1356.  
  1357.     if ((x = cmkey(enatab,nena,s,"",xxstring)) < 0) {
  1358.         if (x == -3) {
  1359.         printf("?Name of server function required\n");
  1360.         return(-9);
  1361.         } else return(x);
  1362.     }
  1363.     if ((y = cmcfm()) < 0) return(y);
  1364. #ifdef CK_APC
  1365.     if (apcactive && apcstatus != APC_UNCH) return(success = 0);
  1366. #endif /* CK_APC */
  1367.     return(doenable(cx,x));
  1368.     }
  1369. #endif /* NOFRILLS */
  1370. #endif /* NOSERVER */
  1371.  
  1372. #ifndef NOSPL
  1373.     if (cx == XXRET) {            /* RETURN */
  1374.     if (cmdlvl == 0) {        /* At top level, nothing happens... */
  1375.         if ((x = cmcfm()) < 0)
  1376.           return(x);
  1377.         return(success = 1);
  1378.     } else if (cmdstk[cmdlvl].src == CMD_TF) { /* In TAKE file, like POP */
  1379.         if ((x = cmtxt("optional return value","",&s,NULL)) < 0)
  1380.           return(x);        /* Allow trailing text, but ignore. */
  1381.         if ((x = cmcfm()) < 0)
  1382.           return(x);
  1383.         popclvl();            /* pop command level */
  1384.         return(success = 1);    /* always succeeds */
  1385.     } else if (cmdstk[cmdlvl].src == CMD_MD) { /* Within macro */
  1386.         if ((x = cmtxt("optional return value","",&s,NULL)) < 0)
  1387.           return(x);
  1388.         return(doreturn(s));    /* Trailing text is return value. */
  1389.     } else return(-2);
  1390.     }
  1391. #endif /* NOSPL */
  1392.  
  1393. #ifndef NOSPL
  1394.     if (cx == XXDO) {            /* DO (a macro) */
  1395.     if (nmac == 0) {
  1396.         printf("\n?No macros defined\n");
  1397.         return(-2);
  1398.     }
  1399.     for (y = 0; y < nmac; y++) {    /* copy the macro table */
  1400.         mackey[y].kwd = mactab[y].kwd; /* into a regular keyword table */
  1401.         mackey[y].kwval = y;    /* with value = pointer to macro tbl */
  1402.         mackey[y].flgs = mactab[y].flgs;
  1403.     }
  1404.     /* parse name as keyword */
  1405.     if ((x = cmkey(mackey,nmac,"macro","",xxstring)) < 0) {
  1406.         if (x == -3) {
  1407.         printf("?Macro name required\n");
  1408.         return(-9);
  1409.         } else return(x);
  1410.     }
  1411.     if ((y = cmtxt("optional arguments","",&s,xxstring)) < 0)
  1412.       return(y);            /* get args */
  1413.     return(dodo(x,s) < 1 ? (success = 0) : 1);
  1414.     }
  1415. #endif /* NOSPL */
  1416.  
  1417.     if (cx == XXECH || cx == XXAPC) {    /* ECHO or APC */
  1418.     if ((x = cmtxt((cx == XXECH) ?
  1419.                "Text to be echoed" :
  1420.                "Application Program Command text",
  1421.                "",&s,xxstring)) < 0)
  1422.       return(x);
  1423.     s = brstrip(s);            /* Strip braces */
  1424.     if (cx == XXAPC) {        /* APC */
  1425.         printf("%c_%s%c\\",ESC,s,ESC);
  1426. #ifdef UNIX
  1427.         fflush(stdout);
  1428. #endif /* UNIX */
  1429.     } else {            /* ECHO */
  1430.         printf("%s\n",s);
  1431.     }
  1432.     return(1);            /* Always succeeds */
  1433.     }
  1434.  
  1435. #ifndef NOSPL
  1436.     if (cx == XXOPE)            /* OPEN */
  1437.       return(doopen());
  1438. #endif /* NOSPL */
  1439.  
  1440. #ifndef NOSPL
  1441.     if (cx == XXOUT) {            /* OUTPUT */
  1442.     if ((x = cmtxt("Text to be output","",&s,NULL)) < 0)
  1443.       return(x);
  1444. #ifdef CK_APC
  1445.     if (apcactive && apcstatus != APC_UNCH) return(success = 0);
  1446. #endif /* CK_APC */
  1447.     debug(F110,"OUTPUT 1",s,0);
  1448.     s = brstrip(s);            /* Strip enclosing braces, */
  1449.     debug(F110,"OUTPUT 2",s,0);
  1450.     for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \B, \L to \\B, \\L */
  1451.         if (x > 0 &&
  1452.         (s[x] == 'B' || s[x] == 'b' || /* BREAK */
  1453.          s[x] == 'L' || s[x] == 'l' || /* Long BREAK */
  1454.          s[x] == 'N' || s[x] == 'n'))  /* NUL */
  1455.           if ((x == 1 && s[x-1] == CMDQ) ||
  1456.           (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ))
  1457.         line[y++] = CMDQ;
  1458.         line[y] = s[x];
  1459.     }
  1460.     line[y++] = '\0';        /* Now expand variables, etc. */
  1461.     debug(F110,"OUTPUT 3",line,0);
  1462.     s = line+y+1;
  1463.     x = LINBUFSIZ - (int) strlen(line) - 1;
  1464.     debug(F101,"OUTPUT size","",x);
  1465.     if (zzstring(line,&s,&x) < 0)
  1466.       return(success = 0);
  1467.     s = line+y+1;
  1468.     debug(F110,"OUTPUT 4",s,0);
  1469.     return(success = dooutput(s));
  1470.     }
  1471. #endif /* NOSPL */
  1472.  
  1473. #ifdef ANYX25
  1474.     if (cx == XXPAD) {            /* PAD commands */
  1475.     x = cmkey(padtab,npadc,"PAD command","",xxstring);
  1476.     if (x == -3) {
  1477.         printf("?You must specify a PAD command to execute\n");
  1478.         return(-2);
  1479.     }
  1480.     if (x < 0) return(x);
  1481.  
  1482.     switch (x) {
  1483.       case XYPADL:
  1484.         if (x25stat() < 0)
  1485.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  1486.         else {
  1487.         x25clear();
  1488.         initpad();
  1489.         }
  1490.         break;
  1491.       case XYPADS:
  1492.         if (x25stat() < 0)
  1493.           printf("Not connected\r\n");
  1494.         else {
  1495.         extern int linkid, lcn;
  1496.         conol("Connected thru ");
  1497.         conol(ttname);
  1498.         printf(", Link id %d, Logical channel number %d\r\n",
  1499.                linkid,lcn);
  1500.         }
  1501.         break;
  1502.       case XYPADR:
  1503.         if (x25stat() < 0)
  1504.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  1505.         else
  1506.           x25reset(0,0);
  1507.         break;
  1508.       case XYPADI:
  1509.         if (x25stat() < 0)
  1510.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  1511.         else
  1512.           x25intr(0);
  1513.     }
  1514.     return(0);
  1515. }
  1516. #endif /* ANYX25 */
  1517.  
  1518. #ifndef NOSPL
  1519.     if (cx == XXPAU || cx == XXWAI || cx == XXMSL) /* PAUSE, WAIT, etc */
  1520.       return(dopaus(cx));
  1521. #endif /* NOSPL */
  1522.  
  1523. #ifndef NOFRILLS
  1524.     if (cx == XXPRI) {
  1525.     if ((x = cmifi("File to print","",&s,&y,xxstring)) < 0) {
  1526.         if (x == -3) {
  1527.         printf("?A file specification is required\n");
  1528.         return(-9);
  1529.         } else return(x);
  1530.     }
  1531.     if (y != 0) {
  1532.         printf("?Wildcards not allowed\n");
  1533.         return(-9);
  1534.     }
  1535.     strcpy(line,s);
  1536.     if ((x = cmtxt("Local print command options, or carriage return","",&s,
  1537.                xxstring)) < 0) return(x);
  1538.     return(success = (zprint(s,line) == 0) ? 1 : 0);
  1539.     }
  1540.  
  1541. #ifdef TCPSOCKET
  1542.     if (cx == XXPNG)             /* PING an IP host */
  1543.       return(doping());
  1544. #endif /* TCPSOCKET */
  1545.  
  1546.  
  1547.     if (cx == XXPWD) {            /* PWD */
  1548. #ifdef MAC
  1549.     char *pwp;
  1550. #endif /* MAC */
  1551.     if ((x = cmcfm()) < 0)
  1552.       return(x);
  1553. #ifndef MAC
  1554.     xsystem(PWDCMD);
  1555.     return(success = 1);        /* blind faith */
  1556. #else
  1557.     if (pwp = zgtdir()) {
  1558.         printf("%s\n",pwp);
  1559.         return(success = ((int)strlen(pwp) > 0));
  1560.     } else return(success = 0);
  1561. #endif /* MAC */
  1562.     }
  1563.  
  1564. #endif /* NOFRILLS */
  1565.  
  1566.     if (cx == XXQUI || cx == XXEXI) {    /* EXIT, QUIT */
  1567.     if ((y = cmnum("exit status code","",10,&x,xxstring)) < 0) {
  1568.         if (y == -3)
  1569.           x = xitsta;
  1570.         else return(y);
  1571.     }
  1572.     if ((y = cmcfm()) < 0) return(y);
  1573.  
  1574.     if (!hupok(0))            /* Check if connection still open */
  1575.       return(success = 0);
  1576.  
  1577. #ifdef VMS
  1578.     doexit(GOOD_EXIT,x);
  1579. #else
  1580. #ifdef OSK
  1581. /* Returning any codes here makes the OS-9 shell print an error message. */
  1582.     doexit(GOOD_EXIT,-1);
  1583. #else
  1584. #ifdef datageneral
  1585.         doexit(GOOD_EXIT,x);
  1586. #else
  1587.     doexit(x,-1);
  1588. #endif /* datageneral */
  1589. #endif /* OSK */
  1590. #endif /* VMS */
  1591.     }
  1592.  
  1593. #ifndef NOFRILLS
  1594.     if (cx == XXERR) {            /* ERROR */
  1595.     if ((x = cmcfm()) < 0) return(x);
  1596.     ttflui();
  1597.     epktflg = 1;
  1598.     sstate = 'a';
  1599.     return(0);
  1600.     }
  1601. #endif /* NOFRILLS */
  1602.  
  1603.     if (cx == XXFIN) {            /* FINISH */
  1604.     if ((x = cmcfm()) < 0) return(x);
  1605.     sstate = setgen('F',"","","");
  1606.     if (local) ttflui();        /* If local, flush tty input buffer */
  1607.     return(0);
  1608.     }
  1609.  
  1610. #ifndef NOSPL
  1611.     if (cx == XXFOR)            /* FOR loop */
  1612.       return(dofor());
  1613. #endif /* NOSPL */
  1614.  
  1615.     if (cx == XXGET) {            /* GET */
  1616.     x = cmtxt("Name of remote file(s), or carriage return","",&cmarg,
  1617.           xxstring);
  1618. #ifndef NOFRILLS
  1619.     if ((x == -2) || (x == -1)) return(x);
  1620. #else
  1621.     if (x < 0) return(x);
  1622. #endif /* NOFRILLS */
  1623.     cmarg = brstrip(cmarg);        /* Strip braces */
  1624.     x = doget();
  1625. #ifdef MAC
  1626.     what = W_RECV;
  1627.     if (sstate == 'r')
  1628.         scrcreate();
  1629. #endif /* MAC */
  1630.     return(x);
  1631.     }
  1632.  
  1633. #ifndef NOSPL
  1634. #ifndef NOFRILLS
  1635.     if (cx == XXGOK) {            /* GETOK */
  1636.     return(success = doask(cx));
  1637.     }
  1638. #endif /* NOFRILLS */
  1639. #endif /* NOSPL */
  1640.  
  1641.     if (cx == XXHLP) {            /* HELP */
  1642. #ifdef NOHELP
  1643.     return(dohlp(XXHLP));
  1644. #else
  1645.     x = cmkey2(cmdtab,ncmd,"C-Kermit command","help",toktab,xxstring);
  1646.     debug(F101,"HELP command x","",x);
  1647.     if (x == -5) {
  1648.         y = chktok(toktab);
  1649.         debug(F101,"top-level cmkey token","",y);
  1650.         ungword();
  1651.         switch (y) {
  1652. #ifndef NOPUSH
  1653.           case '!': x = XXSHE; break;
  1654. #endif /* NOPUSH */
  1655.           case '#': x = XXCOM; break;
  1656.           case ';': x = XXCOM; break;
  1657. #ifndef NOSPL
  1658.           case ':': x = XXLBL; break;
  1659. #endif /* NOSPL */
  1660.           case '&': x = XXECH; break;
  1661.           default:
  1662.         printf("\n?Invalid - %s\n",cmdbuf);
  1663.         x = -2;
  1664.         }
  1665.     }
  1666.     return(dohlp(x));
  1667. #endif /* NOHELP */
  1668.     }
  1669.  
  1670. #ifndef NOHELP
  1671.     if (cx == XXINT)            /* INTRO */
  1672.       return(hmsga(introtxt));
  1673.     if (cx == XXNEW)            /* NEWS */
  1674.       return(hmsga(newstxt));
  1675. #endif /* NOHELP */
  1676.  
  1677.     if (cx == XXHAN) {            /* HANGUP */
  1678.     if ((x = cmcfm()) < 0) return(x);
  1679. #ifndef NODIAL
  1680.     if ((x = mdmhup()) < 1)
  1681. #endif /* NODIAL */
  1682.       x = (tthang() > -1);
  1683.     return(success = x);
  1684.     }
  1685.  
  1686. #ifndef NOSPL
  1687.     if (cx == XXGOTO || cx == XXFWD) {    /* GOTO or FORWARD */
  1688. /* Note, here we don't set SUCCESS/FAILURE flag */
  1689.     if ((y = cmfld("label","",&s,xxstring)) < 0) {
  1690.         if (y == -3) {
  1691.         printf("?Label name required\n");
  1692.         return(-9);
  1693.         } else return(y);
  1694.     }
  1695.     strncpy(lblbuf,s,LBLSIZ);
  1696.     if ((x = cmcfm()) < 0) return(x);
  1697.     s = lblbuf;
  1698.     return(dogoto(s,cx));
  1699.     }
  1700. #endif /* NOSPL */
  1701.  
  1702. #ifndef NOSPL
  1703. /* IF, Extended IF, WHILE */
  1704.     if (cx == XXIF || cx == XXIFX || cx == XXWHI) {
  1705.     return(doif(cx));
  1706.     }
  1707. #endif /* NOSPL */
  1708.  
  1709. #ifndef NOSPL
  1710.     /* INPUT, REINPUT, and MINPUT */
  1711.  
  1712.     if (cx == XXINP || cx == XXREI
  1713. #ifdef CK_MINPUT
  1714.     || cx == XXMINP
  1715. #endif /* CK_MINPUT */
  1716.     ) {
  1717.     sprintf(tmpbuf,"%d",indef);
  1718.     y = cmnum("seconds to wait for input",(char *)tmpbuf,10,&x,xxstring);
  1719.     if (y < 0)
  1720.       return(y);
  1721.     if (x <= 0) x = 1;
  1722.     for (y = 0; y < MINPMAX; y++) {    /* Initialize strings */
  1723.         if (ms[y]) {
  1724.         free(ms[y]);        /* Free old strings, if any */
  1725.         ms[y] = NULL;
  1726.         }
  1727.     }
  1728. #ifdef CK_MINPUT
  1729.     if (cx == XXMINP) {        /* MINPUT */
  1730.         char *s3, *p;
  1731.         int res = 0;
  1732.         for (y = 0; y < MINPMAX; y++) { /* Parse up to MINPMAX strings */
  1733.                 res = cmfld("List of input strings","",&s,xxstring);
  1734.                 if (res < 0) return(res);
  1735.         debug(F110,"MINPUT cmfld returns",s,0);
  1736.                 if (*s == '{') {
  1737.             char *ss;
  1738.             int n;
  1739.             ss = s; n = 0;
  1740.             while (*ss) {*ss = *(ss+1); ss++; n++; }
  1741.             while (--n > 0) if (s[n] == '}') break;
  1742.             if (n > 0) {
  1743.             ss = s + n;
  1744.             while (*ss) {*ss = *(ss+1); ss++; n++; }
  1745.             }
  1746.                 }
  1747.         if (!(ms[y] = malloc((int)strlen(s) + 1))) { /* Get memory */
  1748.             printf("?Memory allocation failure\n");
  1749.             return(-9);
  1750.         }
  1751.         strcpy(ms[y],s);    /* Got memory, copy. */
  1752.                 if (res == 1) break;
  1753.             }
  1754.         for (y++ ; y < MINPMAX; y++) { /* Clean up old strings */
  1755.         if (ms[y]) {
  1756.             free(ms[y]);    /* Free old strings, if any */
  1757.             ms[y] = NULL;
  1758.         }
  1759.             }
  1760. #ifdef DEBUG
  1761.         if (deblog) {        /* Check the parsing */
  1762.         for (y = 0; y < MINPMAX; y++)
  1763.           if (ms[y]) debug(F111,"MINPUT",ms[y],y);
  1764.         }
  1765. #endif /* DEBUG */
  1766.     
  1767.     } else
  1768. #endif /* CK_MINPUT */
  1769.     {
  1770.         if ((y = cmtxt("Material to be input","",&s,xxstring)) < 0)
  1771.           return(y);
  1772.  
  1773.         s = brstrip(s);
  1774.         if (!(ms[0] = malloc((int)strlen(s) + 1))) { /* Get memory */
  1775.         printf("?Memory allocation failure\n");
  1776.         return(-9);
  1777.         }
  1778.         strcpy(ms[0],s);        /* Got memory, copy. */
  1779.         ms[1] = NULL;
  1780.     }
  1781.     if (cx == XXINP            /* INPUT */
  1782. #ifdef CK_MINPUT
  1783.         || cx == XXMINP        /* or MINPUT */
  1784. #endif /* CK_MINPUT */
  1785.         ) {
  1786.         success = doinput(x,ms);    /* Go try to input the search string */
  1787.     } else {            /* REINPUT */
  1788.         debug(F110,"xxrei line",s,0);
  1789.         success = doreinp(x,s);
  1790.     }
  1791.     if (intime[cmdlvl] && !success) { /* TIMEOUT-ACTION = QUIT? */
  1792.         popclvl();            /* If so, pop command level. */
  1793.         if (pflag && cmdlvl == 0) {
  1794.         if (cx == XXINP)  printf("?INPUT timed out\n");
  1795.         if (cx == XXMINP) printf("?MINPUT timed out\n");
  1796.         if (cx == XXREI)  printf("?REINPUT failed\n");
  1797.         }
  1798.     }
  1799.     return(success);        /* Return do(re)input's return code */
  1800.     }
  1801.  
  1802. #endif /* NOSPL */
  1803.  
  1804. #ifndef NOSPL
  1805.     if (cx == XXLBL) {            /* LABEL */
  1806.     if ((x = cmfld("label","",&s,xxstring)) < 0) {
  1807.         if (x == -3) {
  1808.         printf("?Label name required\n");
  1809.         return(-9);
  1810.         } else return(x);
  1811.     }
  1812.     if ((x = cmcfm()) < 0) return(x);
  1813.     return(0);
  1814.     }
  1815. #endif /* NOSPL */
  1816.  
  1817.     if (cx == XXLOG) {            /* LOG */
  1818.     x = cmkey(logtab,nlog,"What to log","",xxstring);
  1819.     if (x == -3) {
  1820.         printf("?Type of log required\n");
  1821.         return(-9);
  1822.     }
  1823.     if (x < 0) return(x);
  1824.     x = dolog(x);
  1825.     if (x < 0)
  1826.       return(x);
  1827.     else
  1828.       return(success = x);
  1829.     }
  1830.  
  1831. #ifndef NOSCRIPT
  1832.     if (cx == XXLOGI) {            /* UUCP-style script */
  1833.     if ((x = cmtxt("expect-send expect-send ...","",&s,xxstring)) < 0)
  1834.       return(x);
  1835. #ifdef CK_APC
  1836.     if (apcactive && apcstatus != APC_UNCH) return(success = 0);
  1837. #endif /* CK_APC */
  1838. #ifdef VMS
  1839.     conres();            /* For Ctrl-C to work... */
  1840. #endif /* VMS */
  1841.     return(success = dologin(s));    /* Return 1=completed, 0=failed */
  1842.     }
  1843. #endif /* NOSCRIPT */
  1844.  
  1845.     if (cx == XXREC) {            /* RECEIVE */
  1846.     cmarg2 = "";
  1847.     x = cmofi(
  1848. #ifdef CK_TMPDIR
  1849. "\nName under which to store the (first) incoming file, or:\n\
  1850.  name of directory in which to store all the file(s), or:\n\
  1851.  confirm the command now to store the files in the current\n\
  1852.  directory under their own names.",
  1853. #else
  1854. "Name under which to store the file, or confirm to accept\n\
  1855.  the file with its own name.",
  1856. #endif /* CK_TMPDIR */
  1857.           "", &s, xxstring
  1858.           );
  1859.     if ((x == -1) || (x == -2) || (x == -9)) return(x);
  1860.     if ((x = cmcfm()) < 0) return(x);
  1861.     strcpy(line,s);
  1862. #ifdef CK_TMPDIR
  1863. /*
  1864.    User can give a device &/or directory specification here,
  1865.    rather than an alternative filename.
  1866. */
  1867.     x = strlen(line);
  1868.     if (
  1869. #ifdef OS2
  1870.         (isalpha(line[0]) &&
  1871.          line[1] == ':' &&
  1872.          line[2] == '\0') ||
  1873.         isdir(line)
  1874. #else
  1875. #ifdef UNIX
  1876.         (x > 0 && line[x-1] == '/') || isdir(line)
  1877. #else
  1878. #ifdef VMS
  1879.         (x > 0) && isdir(line)
  1880. #else
  1881. /*
  1882.   Others -- Maybe this will work; if not, add another #ifdef..#endif.
  1883.   CK_TMPDIR should not be defined without an isdir() function.
  1884. */
  1885.         (x > 0) && isdir(line)
  1886. #endif /* VMS */
  1887. #endif /* UNIX */
  1888. #endif /* OS2 */
  1889.         ) {
  1890.         debug(F110,"RECEIVE arg disk or dir",line,0);
  1891.         if (s = zgtdir()) {        /* Get current directory, */
  1892.         if (zchdir(line)) {    /* change to given disk/directory, */
  1893.             strncpy(savdir,s,TMPDIRLEN); /* remember old disk/dir */
  1894.             debug(F110,"tmpdir saving",savdir,0);
  1895.             debug(F110,"tmpdir changing",line,0);
  1896.             f_tmpdir = 1;    /* and that we did this */
  1897.             cmarg2 = "";    /* and we don't have an as-name. */
  1898.         } else {
  1899.             printf("?Can't access %s\n",line);
  1900.             f_tmpdir = 0;
  1901.             return(-9);
  1902.         }
  1903.         } else {
  1904.         printf("?Can't get current directory\n");
  1905.         f_tmpdir = 0;
  1906.         return(-9);
  1907.         }
  1908.     } else            /* It's an alternative filename */
  1909. #endif /* CK_TMPDIR */
  1910.       cmarg2 = line;
  1911.     debug(F111,"cmofi cmarg2",cmarg2,x);
  1912.     sstate = 'v';
  1913. #ifdef MAC
  1914.     what = W_RECV;
  1915.     scrcreate();
  1916. #endif /* MAC */
  1917.     if (local) displa = 1;
  1918.     return(0);
  1919.     }
  1920.  
  1921.     if (cx == XXREM) {            /* REMOTE */
  1922.     x = cmkey(remcmd,nrmt,"Remote Kermit server command","",xxstring);
  1923.     if (x == -3) {
  1924.         printf("?You must specify a command for the remote server\n");
  1925.         return(-9);
  1926.     }
  1927.     return(dormt(x));
  1928.     }
  1929.  
  1930. #ifndef NOFRILLS
  1931.     if (cx == XXREN) {            /* RENAME */
  1932. #ifdef CK_APC
  1933.     if (apcactive && apcstatus != APC_UNCH) return(success = 0);
  1934. #endif /* CK_APC */
  1935.     return(dorenam());
  1936.     }
  1937. #endif /* NOFRILLS */
  1938.  
  1939.     if (cx == XXSEN  || cx == XXMAI     /* SEND, MAIL */
  1940. #ifdef CK_RESEND
  1941.     || cx == XXRSEN || cx == XXPSEN /* RESEND, PSEND */
  1942. #endif /* CK_RESEND */
  1943.     ) {
  1944. #ifdef CK_RESEND
  1945.     int seekto = 0;
  1946.     if (cx == XXRSEN && binary != XYFT_B
  1947. #ifdef VMS
  1948.         && binary != XYFT_I
  1949. #endif /* VMS */
  1950.         ) {
  1951.         printf(
  1952. #ifdef VMS
  1953.            "?Sorry, FILE TYPE must be BINARY\n"
  1954. #else
  1955.            "?Sorry, FILE TYPE must be BINARY or IMAGE\n"
  1956. #endif /* VMS */
  1957.            );
  1958.         return(-9);
  1959.     }
  1960. #endif /* CK_RESEND */
  1961.     if ((cx == XXMAI
  1962. #ifdef CK_RESEND
  1963.          || cx == XXRSEN
  1964. #endif /* CK_RESEND */
  1965.          ) &&
  1966.         (!atdiso || !atcapr)) {    /* Disposition attribute off? */
  1967.         printf("?Sorry, ATTRIBUTE DISPOSITION must be ON\n");
  1968.         return(-9);
  1969.     }
  1970.     cmarg = cmarg2 = "";
  1971.     if ((x = cmifi("File(s) to send","",&s,&y,xxstring)) < 0) {
  1972.         if (x == -3) {
  1973.         printf("?A file specification is required\n");
  1974.         return(-9);
  1975.         } else return(x);
  1976.     }
  1977.     nfils = -1;            /* Files come from internal list. */
  1978.     strcpy(line,s);            /* Save copy of string just parsed. */
  1979.     strncpy(fspec,s,FSPECL);    /* and here for \v(filespec) */
  1980. #ifdef CK_RESEND
  1981.     if (cx == XXPSEN) {        /* PSEND */
  1982.         if (y != 0) {
  1983.         printf("?Sorry, wildcards not permitted in this command\n");
  1984.         return(-9);
  1985.         }
  1986.         if (sizeof(int) < 4) {
  1987.         printf("?Sorry, this command needs 32-bit integers\n");
  1988.         return(-9);
  1989.         }
  1990.         x = cmnum("starting position (byte number)",
  1991.               "",10,&seekto,xxstring);
  1992.         if (x < 0)
  1993.           return(x);
  1994.     }
  1995. #endif /* CK_RESEND */
  1996.     if (cx == XXSEN            /* SEND command */
  1997. #ifdef CK_RESEND
  1998.         || cx == XXRSEN || cx == XXPSEN /* RESEND or PSEND command */
  1999. #endif /* CK_RESEND */
  2000.         ) {
  2001.         debug(F101,"Send: wild","",y);
  2002.         if (y == 0) {
  2003.         if ((x = cmtxt("Name to send it with","",&cmarg2,
  2004.                    xxstring)) < 0)
  2005.           return(x);
  2006.         } else {
  2007.         if ((x = cmcfm()) < 0) return(x);
  2008.         }
  2009.         cmarg = line;        /* File to send */
  2010.         debug(F110,"Sending:",cmarg,0);
  2011.         if (*cmarg2 != '\0') debug(F110," as:",cmarg2,0);
  2012.     } else {            /* MAIL */
  2013. #ifndef NOFRILLS
  2014.         if (!atdiso || !atcapr) {    /* Disposition attribute off? */
  2015.         printf("?Disposition Attribute is Off\n");
  2016.         return(-9);
  2017.         }
  2018.         debug(F101,"Mail: wild","",y);
  2019.         *optbuf = NUL;        /* Wipe out any old options */
  2020.         if ((x = cmtxt("Address to mail to","",&s,xxstring)) < 0)
  2021.           return(x);
  2022.         if ((int)strlen(s) == 0) {
  2023.         printf("?Address required\n");
  2024.         return(-9);
  2025.         }
  2026.         strcpy(optbuf,s);
  2027.         if ((int)strlen(optbuf) > 94) { /* Ensure legal size */
  2028.         printf("?Option string too long\n");
  2029.         return(-2);
  2030.         }
  2031.         cmarg = line;        /* File to send */
  2032.         debug(F110,"Mailing:",cmarg,0);
  2033.         debug(F110,"To:",optbuf,0);
  2034.         rmailf = 1;            /* MAIL modifier flag for SEND */
  2035. #else
  2036.         printf("?Sorry, MAIL feature not configured.\n");
  2037.         return(-2);
  2038. #endif /* NOFRILLS */
  2039.     }
  2040. #ifdef CK_RESEND
  2041.     if (cx == XXPSEN)        /* Partial-send starting position */
  2042.       sendstart = seekto;
  2043.     else
  2044.       sendstart = 0L;
  2045. #endif /* CK_RESEND */
  2046.     sstate = 's';            /* Set start state to SEND */
  2047. #ifdef CK_RESEND
  2048.     switch (cx) {
  2049.       case XXRSEN: sendmode = SM_RESEND; break;
  2050.       case XXPSEN: sendmode = SM_PSEND;  break;
  2051.       case XXSEN:
  2052.       default:     sendmode = SM_SEND;   break;
  2053.     }
  2054. #else
  2055.     sendmode = SM_SEND;
  2056. #endif /* CK_RESEND */
  2057. #ifdef MAC
  2058.     what = W_SEND;
  2059.     scrcreate();
  2060. #endif /* MAC */
  2061.     if (local) {            /* If in local mode, */
  2062.         displa = 1;            /* turn on file transfer display */
  2063. #ifdef COMMENT
  2064. /* Redundant -- this is done later in sipkt() */
  2065.         ttflui();            /* and flush tty input buffer. */
  2066. #endif /* COMMENT */
  2067.     }
  2068.     return(0);
  2069.     }
  2070.  
  2071. #ifndef NOMSEND
  2072.     if (cx == XXMSE) {            /* MSEND command */
  2073.     nfils = 0;            /* Like getting a list of */
  2074.     lp = line;            /* files on the command line */
  2075.     while (1) {
  2076.         char *p;
  2077.         if ((x = cmifi("Names of files to send, separated by spaces","",
  2078.                &s,&y,xxstring)) < 0) {
  2079.         if (x == -3) {
  2080.             if (nfils <= 0) {
  2081.             printf("?A file specification is required\n");
  2082.             return(-9);
  2083.             } else break;
  2084.         }
  2085.         return(x);
  2086.         }
  2087.         msfiles[nfils++] = lp;    /* Got one, count it, point to it, */
  2088.         p = lp;            /* remember pointer, */
  2089.         while (*lp++ = *s++)    /* and copy it into buffer */
  2090.           if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
  2091.           printf("?MSEND list too long\n");
  2092.           line[0] = NUL;
  2093.           return(-9);
  2094.           }
  2095.         debug(F111,"msfiles",msfiles[nfils-1],nfils-1);
  2096.         if (nfils == 1) *fspec = NUL; /* Take care of \v(filespec) */
  2097.         if (((int)strlen(fspec) + (int)strlen(p) + 1) < FSPECL) {
  2098.         strcat(fspec,p);
  2099.         strcat(fspec," ");
  2100.         }
  2101.     }
  2102.     cmlist = msfiles;        /* Point cmlist to pointer array */
  2103.     cmarg2 = "";            /* No internal expansion list (yet) */
  2104.     sndsrc = nfils;            /* Filenames come from cmlist */
  2105.     sendmode = SM_MSEND;        /* Remember this kind of SENDing */
  2106.     sstate = 's';            /* Set start state for SEND */
  2107. #ifdef MAC
  2108.     what = W_SEND;
  2109.     scrcreate();
  2110. #endif /* MAC */
  2111.     if (local) {            /* If in local mode, */
  2112.         displa = 1;            /* turn on file transfer display */
  2113.         ttflui();            /* and flush tty input buffer. */
  2114.     }
  2115.     return(0);
  2116.     }
  2117. #endif /* NOMSEND */
  2118.  
  2119. #ifndef NOSERVER
  2120.     if (cx == XXSER) {            /* SERVER */
  2121.     if ((x = cmcfm()) < 0) return(x);
  2122.     sstate = 'x';
  2123. #ifdef MAC
  2124.     what = W_RECV;
  2125.     scrcreate();
  2126. #endif /* MAC */
  2127.     if (local) displa = 1;
  2128. #ifdef AMIGA
  2129.     reqoff();            /* No DOS requestors while server */
  2130. #endif /* AMIGA */
  2131.     return(0);
  2132.     }
  2133. #endif /* NOSERVER */
  2134.  
  2135.     if (cx == XXSET) {            /* SET command */
  2136.     x = cmkey(prmtab,nprm,"Parameter","",xxstring);
  2137.     if (x == -3) {
  2138.         printf("?You must specify a parameter to set\n");
  2139.         return(-9);
  2140.     }
  2141.     if (x < 0) return(x);
  2142.     /* have to set success separately for each item in doprm()... */
  2143.     /* actually not really, could have just had doprm return 0 or 1 */
  2144.     /* and set success here... */
  2145.     y = doprm(x,0);
  2146.     if (y == -3) {
  2147.         printf("?More fields required\n");
  2148.         return(-9);
  2149.     } else return(y);
  2150.     }
  2151.  
  2152. #ifndef NOPUSH
  2153.     if (cx == XXSHE) {            /* SHELL (system) command */
  2154.     if (cmtxt("System command to execute","",&s,xxstring) < 0)
  2155.       return(-1);
  2156. #ifdef CK_APC
  2157.     if (apcactive && apcstatus != APC_UNCH) return(success = 0);
  2158. #endif /* CK_APC */
  2159.     conres();            /* Make console normal  */
  2160.     x = zshcmd(s);
  2161.     debug(F101,"RUN zshcmd code","",x);
  2162.     concb((char)escape);
  2163.     return(success = (x > 0) ? 1 : 0);
  2164.     }
  2165. #ifdef CK_REDIR
  2166.     if (cx == XXFUN) {            /* REDIRECT */
  2167. #ifdef CK_APC
  2168.     if (apcactive && apcstatus != APC_UNCH) return(success = 0);
  2169. #endif /* CK_APC */
  2170.     if (!local) {
  2171.         printf("?SET LINE or SET HOST required first\n");
  2172.         return(-9);
  2173.     }
  2174. #ifdef OS2
  2175. #ifdef NETCONN
  2176.     if (network) {
  2177.         printf("?Sorry, REDIRECT doesn't work on network connections\n");
  2178.         return(-9);
  2179.     }
  2180. #endif /* NETCONN */
  2181. #endif /* OS2 */
  2182.  
  2183.     sprintf(tmpbuf,
  2184.         "Local command to run,\n\
  2185. with its standard input/output redirected to %s\n",
  2186.         ttname);
  2187.     if ((x = cmtxt(tmpbuf,"",&s,xxstring)) < 0)
  2188.       return(x);
  2189.     return(success = ttruncmd(s));
  2190.     }
  2191. #endif /* CK_REDIR */
  2192. #endif /* NOPUSH */
  2193.  
  2194. #ifndef NOSHOW
  2195.     if (cx == XXSHO) {            /* SHOW */
  2196.     x = cmkey(shotab,nsho,"","parameters",xxstring);
  2197.     if (x < 0) return(x);
  2198.     return(doshow(x));
  2199.     }
  2200. #endif /* NOSHOW */
  2201.  
  2202. #ifndef MAC
  2203.     if (cx == XXSPA) {            /* SPACE */
  2204. #ifdef datageneral
  2205.     /* AOS/VS can take an argument after its "space" command. */
  2206.     if ((x = cmtxt("Confirm, or local directory name","",&s,xxstring)) < 0)
  2207.       return(x);
  2208.     if (*s == NUL) xsystem(SPACMD);
  2209.     else {
  2210.         sprintf(line,"space %s",s);
  2211.         xsystem(line);
  2212.     }
  2213. #else
  2214. #ifdef OS2
  2215.     if ((x = cmtxt("Press Enter for current disk,\n\
  2216.  or specify a disk letter like A:","",&s,xxstring)) < 0)
  2217.       return(x);
  2218.     if (*s == NUL) {        /* Current disk */
  2219.         printf(" Free space: %ldK\n", zdskspace(0)/1024L);
  2220.     } else {
  2221.         int drive = toupper(*s);
  2222.         printf(" Drive %c: %ldK free\n", drive,
  2223.            zdskspace(drive - 'A' + 1) / 1024L);
  2224.     }
  2225. #else
  2226. #ifdef UNIX
  2227. #ifdef COMMENT
  2228.     if ((x = cmtxt("Confirm for current disk,\n\
  2229.  or specify a disk device or directory","",&s,xxstring)) < 0)
  2230.       return(x);
  2231. #else
  2232.     x = cmdir("Confirm for current disk,\n\
  2233.  or specify a disk device or directory","",&s,xxstring);
  2234.     if (x == -3)
  2235.       s = "";
  2236.     else if (x < 0)
  2237.       return(x);
  2238.     if ((x = cmcfm()) < 0) return(x);
  2239. #endif /* COMMENT */
  2240.     if (*s == NUL) {        /* Current disk */
  2241.         xsystem(SPACMD);
  2242.     } else {            /* Specified disk */
  2243.         sprintf(line,"%s %s",SPACM2,s);
  2244.         xsystem(line);
  2245.     }
  2246. #else
  2247.     if ((x = cmcfm()) < 0) return(x);
  2248.     xsystem(SPACMD);
  2249. #endif /* UNIX */
  2250. #endif /* OS2 */
  2251. #endif /* datageneral */
  2252.     return(success = 1);        /* Pretend it worked */
  2253.     }
  2254. #endif /* MAC */
  2255.  
  2256.     if (cx == XXSTA) {            /* STATISTICS */
  2257.     if ((x = cmcfm()) < 0) return(x);
  2258.     return(success = dostat());
  2259.     }
  2260.  
  2261.     if (cx == XXSTO || cx == XXEND) {    /* STOP, END, or POP */
  2262.     if ((y = cmnum("exit status code","0",10,&x,xxstring)) < 0)
  2263.       return(y);
  2264.     if ((y = cmtxt("Message to print","",&s,xxstring)) < 0)
  2265.       return(y);
  2266.     s = brstrip(s);
  2267.     if (*s) printf("%s\n",s);
  2268.     if (cx == XXSTO) {
  2269.         dostop();
  2270.     } else {
  2271. #ifndef NOSPL
  2272.         /* Pop from all FOR/WHILE/XIFs */
  2273.         debug(F101,"END maclvl 1","",maclvl);
  2274.         while ((maclvl > 0) &&
  2275.            (m_arg[maclvl-1][0]) &&
  2276.            (cmdstk[cmdlvl].src == CMD_MD) &&
  2277.              (!strncmp(m_arg[maclvl-1][0],"_xif",4) ||
  2278.               !strncmp(m_arg[maclvl-1][0],"_for",4) ||
  2279.               !strncmp(m_arg[maclvl-1][0],"_whi",4))) {
  2280.         debug(F110,"END popping",m_arg[maclvl-1][0],0);
  2281.         dogta(XXPTA);        /* Put args back */
  2282.         popclvl();        /* Pop up two levels */
  2283.         popclvl();
  2284.         debug(F101,"END maclvl 2","",maclvl);
  2285.         }
  2286. #endif /* NOSPL */
  2287.         popclvl();            /* Now pop out of macro or TAKE file */
  2288. #ifndef NOSPL
  2289.         debug(F101,"END maclvl 3","",maclvl);
  2290. #endif /* NOSPL */
  2291.     }
  2292.     return(success = (x == 0));
  2293.     }
  2294.  
  2295.     if (cx == XXSUS) {            /* SUSPEND */
  2296.     if ((y = cmcfm()) < 0) return(y);
  2297. #ifdef NOJC
  2298.     printf("Sorry, this version of Kermit cannot be suspended\n");
  2299. #else
  2300.     stptrap(0);
  2301. #endif /* NOJC */
  2302.     return(0);
  2303.     }
  2304.  
  2305.     if (cx == XXTAK) {            /* TAKE */
  2306.     if (tlevel > MAXTAKE-1) {
  2307.         printf("?Take files nested too deeply\n");
  2308.         return(-2);
  2309.     }
  2310.     if ((y = cmifi("C-Kermit command file","",&s,&x,xxstring)) < 0) {
  2311.         if (y == -3) {
  2312.         printf("?A file name is required\n");
  2313.         return(-9);
  2314.         } else return(y);
  2315.     }
  2316.     if (x != 0) {
  2317.         printf("?Wildcards not allowed in command file name\n");
  2318.         return(-9);
  2319.     }
  2320.     strcpy(line,s);
  2321.     if ((y = cmcfm()) < 0) return(y);
  2322.     return(success = dotake(line));
  2323.     }
  2324.  
  2325. #ifdef NETCONN
  2326.     if (cx == XXTEL) {            /* TELNET */
  2327.     int x;
  2328.     x = nettype;            /* Save net type in case of failure */
  2329.     nettype = NET_TCPB;
  2330.     if ((y = setlin(XYHOST,0)) < 0) {
  2331.         nettype = x;        /* Failed, restore net type. */
  2332.         return(y);
  2333.     }
  2334.     return (success = (y == 0) ? 0 : doconect(0));
  2335.     }
  2336. #endif /* NETCONN */
  2337.  
  2338. #ifndef NOXMIT
  2339.     if (cx == XXTRA) {            /* TRANSMIT */
  2340.     if ((x = cmifi("File to transmit","",&s,&y,xxstring)) < 0) {
  2341.         if (x == -3) {
  2342.         printf("?Name of an existing file\n");
  2343.         return(-9);
  2344.         } else return(x);
  2345.     }
  2346.     if (y != 0) {
  2347.         printf("?Only a single file may be transmitted\n");
  2348.         return(-2);
  2349.     }
  2350.     strcpy(line,s);            /* Save copy of string just parsed. */
  2351.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  2352. #ifdef CK_APC
  2353.     if (apcactive && apcstatus != APC_UNCH) return(success = 0);
  2354. #endif /* CK_APC */
  2355.     debug(F111,"calling transmit",line,xmitp);
  2356.     return(success = transmit(line,(char)xmitp)); /* Do the command */
  2357.     }
  2358. #endif /* NOXMIT */
  2359.  
  2360. #ifndef NOFRILLS
  2361.     if (cx == XXTYP) {            /* TYPE */
  2362. #ifndef MAC
  2363.     char *tc;
  2364. #endif /* MAC */
  2365.     if ((x = cmifi("File to type","",&s,&y,xxstring)) < 0) {
  2366.         if (x == -3) {
  2367.         printf("?Name of an existing file\n");
  2368.         return(-9);
  2369.         } else return(x);
  2370.     }
  2371.     if (y != 0) {
  2372.         printf("?A single file please\n");
  2373.         return(-2);
  2374.     }
  2375. #ifndef MAC
  2376.     if (!(tc = getenv("CK_TYPE"))) tc = TYPCMD;
  2377.     sprintf(line,"%s %s",tc,s);
  2378. #ifdef OS2
  2379.     {   /* Lower level functions change \ to /, not good for CMD.EXE. */
  2380.         char *p = line;
  2381.         while (*p) {        /* Change them back to \ */
  2382.         if (*p == '/') *p = '\\';
  2383.         p++;
  2384.         }
  2385.     }
  2386. #endif /* OS2 */
  2387.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  2388.     debug(F110,"TYPE",line,0);
  2389.     xsystem(line);
  2390.     return(success = 1);
  2391. #else
  2392.     strcpy(line,s);
  2393.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  2394.     return(success = dotype(line));
  2395. #endif /* MAC */
  2396.     }
  2397. #endif /* NOFRILLS */
  2398.  
  2399. #ifndef NOFRILLS
  2400.     if (cx == XXTES) {            /* TEST */
  2401.     /* Fill this in with whatever is being tested... */
  2402.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  2403.  
  2404. #ifndef NOSPL
  2405. #ifdef COMMENT
  2406.     { int d, i, j;            /* Dump all arrays */
  2407.       char c, **p;
  2408.       for (i = 0; i < 27; i++) {
  2409.           p = a_ptr[i];
  2410.           d = a_dim[i];
  2411.           c = (i == 0) ? 64 : i + 96;
  2412.           if (d && p) {
  2413.           fprintf(stderr,"&%c[%d]\n",c,d);
  2414.           for (j = 0; j <= d; j++) {
  2415.               if (p[j]) {
  2416.               fprintf(stderr,"  &%c[%2d] = [%s]\n",c,j,p[j]);
  2417.               }
  2418.           }
  2419.           }
  2420.       }
  2421.       }
  2422. #else /* Not COMMENT */
  2423.     printf("cmdlvl = %d, tlevel = %d, maclvl = %d\n",
  2424.            cmdlvl,tlevel,maclvl);
  2425.     if (maclvl < 0) {
  2426.         printf("%s\n",
  2427.          "Call me from inside a macro and I'll dump the argument stack");
  2428.         return(0);
  2429.     }
  2430.     printf("Macro level: %d, ARGC = %d\n     ",maclvl,macargc[maclvl]);
  2431.     for (y = 0; y < 10; y++) printf("%7d",y);
  2432.     for (x = 0; x <= maclvl; x++) {
  2433.         printf("\n%2d:  ",x);
  2434.         for (y = 0; y < 10; y++) {
  2435.         s = m_arg[x][y];
  2436.         printf("%7s",s ? s : "(none)");
  2437.         }
  2438.     }
  2439.     printf("\n");
  2440. #endif /* COMMENT */
  2441. #endif /* NOSPL */
  2442.     return(0);
  2443.     }
  2444. #endif /* NOFRILLS */
  2445.  
  2446. #ifndef NOCSETS
  2447.     if (cx == XXXLA) {       /* TRANSLATE <ifn> from-cs to-cs <ofn> */
  2448.     int incs, outcs;
  2449.     if ((x = cmifi("File to translate","",&s,&y,xxstring)) < 0) {
  2450.         if (x == -3) {
  2451.         printf("?Name of an existing file\n");
  2452.         return(-9);
  2453.         } else return(x);
  2454.     }
  2455.     if (y != 0) {
  2456.         printf("?A single file please\n");
  2457.         return(-2);
  2458.     }
  2459.     strcpy(line,s);            /* Save copy of string just parsed. */
  2460.  
  2461.     if ((incs = cmkey(fcstab,nfilc,"from character-set","",xxstring)) < 0)
  2462.       return(incs);
  2463.     if ((outcs = cmkey(fcstab,nfilc,"to character-set","",xxstring)) < 0)
  2464.       return(outcs);
  2465.     if ((x = cmofi("output file",CTTNAM,&s,xxstring)) < 0) return(x);
  2466.     if (x > 1) {
  2467.         printf("?Directory name not allowed\n");
  2468.         return(-9);
  2469.     }
  2470.     strncpy(tmpbuf,s,TMPBUFSIZ);
  2471.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  2472.     return(success = xlate(line,tmpbuf,incs,outcs)); /* Execute it */
  2473.     }
  2474. #endif /* NOCSETS */
  2475.  
  2476.     if (cx == XXVER) {            /* VERSION */
  2477.     if ((y = cmcfm()) < 0) return(y);
  2478.     printf("%s, for%s\n Numeric: %ld",versio,ckxsys,vernum);
  2479.     if (verwho) printf("-%d\n",verwho); else printf("\n");
  2480.     hmsga(copyright);
  2481.     return(success = 1);
  2482.     }
  2483.  
  2484. #ifndef MAC                /* Only for multiuser systems */
  2485. #ifndef NOFRILLS
  2486.     if (cx == XXWHO) {            /* WHO */
  2487.     char *wc;
  2488. #ifdef datageneral
  2489.         xsystem(WHOCMD);
  2490. #else
  2491.     if ((y = cmtxt("user name","",&s,xxstring)) < 0) return(y);
  2492.     if (!(wc = getenv("CK_WHO"))) wc = WHOCMD;
  2493.     if (wc)
  2494.       if ((int) strlen(wc) > 0) {
  2495.           sprintf(line,"%s %s",wc,s);
  2496.           xsystem(line);
  2497.       }
  2498. #endif /* datageneral */
  2499.     return(success = 1);
  2500.     }
  2501. #endif /* NOFRILLS */
  2502. #endif /* MAC */
  2503.  
  2504. #ifndef NOFRILLS
  2505.     if (cx == XXWRI || cx == XXWRL) {    /* WRITE */
  2506.     if ((x = cmkey(writab,nwri,"to file or log","",xxstring)) < 0) {
  2507.         if (x == -3) printf("?Write to what?\n");
  2508.         return(x);
  2509.     }
  2510.     if ((y = cmtxt("text","",&s,xxstring)) < 0) return(y);
  2511.     s = brstrip(s);
  2512.     switch (x) {
  2513.       case LOGD: y = ZDFILE; break;
  2514.       case LOGP: y = ZPFILE; break;
  2515. #ifndef NOLOCAL
  2516.       case LOGS: y = ZSFILE; break;
  2517. #endif /* NOLOCAL */
  2518.       case LOGT: y = ZTFILE; break;
  2519. #ifndef NOSPL
  2520.       case LOGW: y = ZWFILE; break;
  2521. #endif /* NOSPL */
  2522.       case LOGX:
  2523.       case LOGE:
  2524.  
  2525. #ifndef MAC
  2526.         if (x == LOGE) fprintf(stderr,"%s",s);
  2527.         else
  2528. #endif /* MAC */
  2529.           printf("%s",s);
  2530.         if (
  2531. #ifndef NOSPL
  2532.         cmdlvl == 0
  2533. #else
  2534.         tlevel == -1
  2535. #endif /* NOSPL */
  2536.         )
  2537. #ifndef MAC
  2538.           if (x == LOGE) fprintf(stderr,"\n");
  2539.           else
  2540. #endif /* MAC */
  2541.         printf("\n");
  2542.         return(success = 1);
  2543.       default: return(-2);
  2544.     }
  2545.     if (chkfn(y) > 0) {
  2546.         x = (cx == XXWRI) ? zsout(y,s) : zsoutl(y,s);
  2547.         if (x < 0) printf("?Write error\n");
  2548.     } else {
  2549.         x = -1;
  2550.         printf("?File or log not open\n");
  2551.     }
  2552.     return(success = (x == 0) ? 1 : 0);
  2553.     }
  2554. #endif /* NOFRILLS */
  2555.  
  2556.     debug(F101,"docmd unk arg","",cx);
  2557.     return(-2);                /* None of the above. */
  2558. } /* end of docmnd() */
  2559.  
  2560. #endif /* NOICP */
  2561.