home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 3 Comm / 03-Comm.zip / CK5A188S.ZIP / ckuusr.c < prev    next >
C/C++ Source or Header  |  1992-11-23  |  56KB  |  2,033 lines

  1. char *userv = "User Interface 5A(092), 23 Nov 92";
  2.  
  3. /*  C K U U S R --  "User Interface" for Unix Kermit (Part 1)  */
  4.  
  5. /*
  6.   Author: Frank da Cruz (fdc@columbia.edu, FDCCU@CUVMA.BITNET),
  7.   Columbia University Center for Computing Activities.
  8.   First released January 1985.
  9.   Copyright (C) 1985, 1992, Trustees of Columbia University in the City of New
  10.   York.  Permission is granted to any individual or institution to use this
  11.   software as long as it is not sold for profit.  This copyright notice must be
  12.   retained.  This software may not be included in commercial products without
  13.   written permission of Columbia University.
  14. */
  15.  
  16. /*
  17.   NOTE: Because of the massive additions in functionality, and therefore
  18.   the increase in the number of commands, much code was moved from here to
  19.   the two new modules, ckuus4.c and ckuus5.c.  This module now contains only
  20.   the top-level command keyword table, the SET command keyword table, and
  21.   the top-level interactive command parser/dispatcher.  ckuus3.c contains the
  22.   rest of the SET and REMOTE command parsers; ckuus2.c contains the help
  23.   command parser and help text strings, and ckuus4.c and ckuus5.c contain
  24.   miscellaneous pieces that logically belong in the ckuusr.c file but had to
  25.   be moved because of size problems with some C compilers / linkers.
  26.   Later...  as the other modules became too large, a ckuus6.c was created.
  27.   Still later...  ckuus7.c.
  28.   Also: ckuusy.c contains the UNIX-style command-line interface;
  29.   ckuusx.c contains routines needed by both the command-line interface and
  30.   the interactive command parser.
  31. */
  32.  
  33. /*
  34.  The ckuus*.c modules depend on the existence of C library features like fopen,
  35.  fgets, feof, (f)printf, argv/argc, etc.  Other functions that are likely to
  36.  vary among Unix implementations -- like setting terminal modes or interrupts
  37.  -- are invoked via calls to functions that are defined in the system-
  38.  dependent modules, ck?[ft]io.c.  The command line parser processes any
  39.  arguments found on the command line, as passed to main() via argv/argc.  The
  40.  interactive parser uses the facilities of the cmd package (developed for this
  41.  program, but usable by any program).  Any command parser may be substituted
  42.  for this one.  The only requirements for the Kermit command parser are these:
  43.  
  44. 1. Set parameters via global variables like duplex, speed, ttname, etc.  See
  45.    ckmain.c for the declarations and descriptions of these variables.
  46.  
  47. 2. If a command can be executed without the use of Kermit protocol, then
  48.    execute the command directly and set the variable sstate to 0. Examples
  49.    include 'set' commands, local directory listings, the 'connect' command.
  50.  
  51. 3. If a command requires the Kermit protocol, set the following variables:
  52.  
  53.     sstate                             string data
  54.       'x' (enter server mode)            (none)
  55.       'r' (send a 'get' command)         cmarg, cmarg2
  56.       'v' (enter receive mode)           cmarg2
  57.       'g' (send a generic command)       cmarg
  58.       's' (send files)                   nfils, cmarg & cmarg2 OR cmlist
  59.       'c' (send a remote host command)   cmarg
  60.  
  61.     cmlist is an array of pointers to strings.
  62.     cmarg, cmarg2 are pointers to strings.
  63.     nfils is an integer.
  64.  
  65.     cmarg can be a filename string (possibly wild), or
  66.        a pointer to a prefabricated generic command string, or
  67.        a pointer to a host command string.
  68.     cmarg2 is the name to send a single file under, or
  69.        the name under which to store an incoming file; must not be wild.
  70.        If it's the name for receiving, a null value means to store the
  71.        file under the name it arrives with.
  72.     cmlist is a list of nonwild filenames, such as passed via argv.
  73.     nfils is an integer, interpreted as follows:
  74.       -1: filespec (possibly wild) in cmarg, must be expanded internally.
  75.        0: send from stdin (standard input).
  76.       >0: number of files to send, from cmlist.
  77.  
  78.  The screen() function is used to update the screen during file transfer.
  79.  The tlog() function writes to a transaction log.
  80.  The debug() function writes to a debugging log.
  81.  The intmsg() and chkint() functions provide the user i/o for interrupting
  82.    file transfers.
  83. */
  84.  
  85. #ifndef NOICP
  86. /* Includes */
  87.  
  88. #include "ckcdeb.h"
  89. #include "ckcasc.h"
  90. #include "ckcker.h"
  91. #include "ckuusr.h"
  92. #include "ckcxla.h"
  93. #include "ckcnet.h"            /* Network symbols */
  94.  
  95. #ifdef datageneral
  96. #include <packets:common.h>
  97. #define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd)
  98. #endif /* datageneral */
  99.  
  100. /* External Kermit Variables, see ckmain.c for description. */
  101.  
  102. extern int size, local, sndsrc, xitsta, server, displa, binary, msgflg, 
  103.   escape, duplex, nfils, quiet, tlevel, pflag, zincnt, atcapr, atdiso, verwho;
  104.  
  105. extern long vernum;
  106. extern char *versio;
  107. extern char *ckxsys, *cmarg, *cmarg2, **cmlist;
  108. #ifndef NOHELP
  109. extern char *introtxt[];
  110. #endif /* NOHELP */
  111. extern char *PWDCMD, *WHOCMD, *TYPCMD;
  112. extern char ttname[];
  113. #ifndef NOFRILLS
  114. extern int rmailf;            /* MAIL command items */
  115. extern char optbuf[];
  116. #endif /* NOFRILLS */
  117. extern CHAR sstate;
  118.  
  119. #ifdef NETCONN
  120. extern int network;            /* Have active network connection */
  121. #endif /* NETCONN */
  122.  
  123. #ifndef NOMSEND                /* Multiple SEND */
  124. extern char *msfiles[];
  125. #endif /* NOMSEND */
  126. extern char fspec[];            /* Most recent filespec */
  127.  
  128. #ifndef NOCSETS
  129. extern int nfilc;
  130. extern struct keytab fcstab[];
  131. #endif /* NOCSETS */
  132.  
  133. int rcflag = 0;                /* Pointer to home directory string */
  134. int repars,                /* Reparse needed */
  135.     techo = 0,                /* Take echo */
  136.     terror = 0;                /* Take error action, 1 = quit */
  137. #ifndef NOSCRIPT
  138. int secho = 1;
  139. #endif /* NOSCRIPT */
  140.  
  141. #ifndef NOXMIT
  142. /* Variables for TRANSMIT command */
  143.  
  144. int xmitx = 1;            /* Whether to echo during TRANSMIT */
  145. int xmitf = 0;            /* Character to fill empty lines */
  146. int xmitl = 0;            /* 0 = Don't send linefeed too */
  147. int xmitp = LF;            /* Host line prompt */
  148. int xmits = 0;            /* Use shift-in/shift-out, 0 = no */
  149. int xmitw = 0;            /* Milliseconds to pause during TRANSMIT */
  150. #endif /* NOXMIT */
  151.  
  152. /* Declarations from ck?fio.c module */
  153.  
  154. extern char *SPACMD, *SPACM2;        /* SPACE commands */
  155.  
  156. /* Command-oriented items */
  157.  
  158. #ifdef DCMDBUF
  159. extern char *cmdbuf;            /* Command buffers */
  160. extern char *atmbuf;
  161. extern char *line;            /* Character buffer for anything */
  162. extern int *ifcmd;
  163. #else
  164. extern char cmdbuf[];            /* Command buffers */
  165. extern char atmbuf[];
  166. extern char line[];            /* Character buffer for anything */
  167. extern int ifcmd[];
  168. #endif /* DCMDBUF */
  169.  
  170. char *lp;                /* Pointer to line buffer */
  171.  
  172. #ifndef NOSPL
  173. extern char inpbuf[];            /* Buffer for INPUT and REINPUT */
  174. char *inpbp = inpbuf;            /* And pointer to same */
  175. extern char lblbuf[];            /* Buffer for labels */
  176. #endif /* NOSPL */
  177.  
  178. char psave[80] = { NUL };        /* For saving & restoring prompt */
  179.  
  180. extern char tmpbuf[];            /* Temporary buffer */
  181.  
  182. extern int success;            /* Command success/failure flag */
  183.  
  184. #ifndef NOSPL
  185. int                    /* SET INPUT parameters. */
  186.   indef = 5,                /* 5 seconds default timeout */
  187.   intime = 0,                /* 0 = proceed */
  188.   incase = 0,                /* 0 = ignore */
  189.   inecho = 1,                /* 1 = echo on */
  190.   insilence = 0;            /* 0 = no silence constraint */
  191.  
  192. int maclvl = -1;            /* Macro nesting level */
  193. int mecho = 0;                /* Macro echo, 0 = don't */
  194. int merror = 0;                /* Macro error action */
  195. char varnam[6];                /* For variable names */
  196. extern int macargc[];            /* ARGC from macro invocation */
  197.  
  198. extern char *m_arg[MACLEVEL][NARGS];    /* Stack of macro arguments */
  199.  
  200. extern char **a_ptr[];            /* Array pointers */
  201. extern int a_dim[];            /* Array dimensions */
  202.  
  203. #ifdef DCMDBUF
  204. extern struct cmdptr *cmdstk;        /* The command stack itself */
  205. #else
  206. extern struct cmdptr cmdstk[];        /* The command stack itself */
  207. #endif /* DCMDBUF */
  208. extern int cmdlvl;            /* Current position in command stack */
  209. #endif /* NOSPL */
  210.  
  211. static int x, y, z = 0;            /* Local workers */
  212. static char *s;
  213.  
  214. #define xsystem(s) zsyscmd(s)
  215.  
  216. /* Top-Level Interactive Command Keyword Table */
  217.  
  218. struct keytab cmdtab[] = {
  219. #ifndef NOPUSH
  220.     "!",       XXSHE, CM_INV,    /* shell escape */
  221. #endif /* NOPUSH */
  222.     "#",           XXCOM, CM_INV,    /* comment */
  223. #ifndef NOSPL
  224.     ":",           XXLBL, CM_INV,    /* label */
  225. #endif /* NOSPL */
  226. #ifndef NOPUSH
  227.     "@",           XXSHE, CM_INV,    /* DCL escape */
  228. #endif /* NOPUSH */
  229. #ifndef NOSPL
  230.     "asg",         XXASS, CM_INV,       /* invisible synonym for assign */
  231.     "ask",         XXASK, 0,        /* ask */
  232.     "askq",        XXASKQ,0,            /* ask quietly */
  233.     "assign",      XXASS, 0,            /* assign */
  234. #endif /* NOSPL */
  235. #ifndef NOFRILLS
  236.     "bug",         XXBUG, 0,        /* bug report instructions */
  237. #endif /* NOFRILLS */
  238.     "bye",         XXBYE, 0,        /* bye to remote server */
  239.     "c",           XXCON, CM_INV|CM_ABR, /* invisible synonym for connect */
  240. #ifndef NOFRILLS
  241.     "cat",         XXTYP, CM_INV,    /* display a local file */
  242. #endif /* NOFRILLS */
  243.     "cd",          XXCWD, 0,        /* change directory */
  244.     "check",       XXCHK, 0,        /* check for a feature */
  245. #ifndef NOFRILLS
  246.     "clear",       XXCLE, 0,        /* clear input buffer */
  247. #endif /* NOFRILLS */
  248.     "close",       XXCLO, 0,        /* close a log file */
  249. #ifdef NOFRILLS
  250.     "comment",     XXCOM, CM_INV,    /* comment */
  251. #else
  252.     "comment",     XXCOM, 0,        /* comment */
  253. #endif /* NOFRILLS */
  254.     "connect",     XXCON, 0,        /* connect to remote system */
  255.     "cwd",       XXCWD, CM_INV,    /* invisisble synonym for cd */
  256. #ifndef NOSPL
  257.     "dcl",         XXDCL, CM_INV,    /* declare an array */
  258.     "declare",     XXDCL, 0,        /* declare an array */
  259.     "decrement",   XXDEC, 0,        /* decrement a numeric variable */
  260.     "define",      XXDEF, 0,        /* define a macro */
  261. #endif /* NOSPL */
  262. #ifndef NOFRILLS
  263.     "delete",      XXDEL, 0,        /* delete a file */
  264. #endif /* NOFRILLS */
  265. #ifndef NODIAL
  266.     "dial",       XXDIAL,0,        /* dial a phone number */
  267. #endif /* NODIAL */
  268. #ifndef MAC
  269.     "directory",   XXDIR, 0,        /* directory of files */
  270. #endif /* MAC */
  271. #ifndef NOFRILLS
  272.     "disable",     XXDIS, 0,        /* disable server function */
  273. #endif /* NOFRILLS */
  274. #ifndef NOSPL
  275.     "do",          XXDO,  0,        /* execute a macro */
  276. #endif /* NOSPL */
  277. #ifndef NOFRILLS
  278.     "e-packet",    XXERR, CM_INV,    /* Send an Error packet */
  279. #endif /* NOFRILLS */
  280.     "echo",        XXECH, 0,        /* echo argument */
  281. #ifndef NOSPL
  282.     "else",        XXELS, CM_INV,    /* ELSE part of IF statement */
  283. #endif /* NOSPL */
  284. #ifndef NOFRILLS
  285.     "enable",      XXENA, 0,        /* ENABLE a server function */
  286. #endif /* NOFRILLS */
  287. #ifndef NOSPL
  288.     "end",         XXEND, 0,        /* END command file or macro */
  289. #endif /* NOSPL */
  290.     "ex",          XXEXI, CM_INV|CM_ABR, /* Let "ex" still be EXIT */
  291.     "exit",       XXEXI, 0,        /* exit the program */
  292.     "extproc",     XXCOM, CM_INV,       /* dummy command */
  293.     "finish",      XXFIN, 0,        /* FINISH */
  294. #ifndef NOSPL
  295.     "for",         XXFOR, 0,        /* FOR loop */
  296. #endif /* NOSPL */
  297. #ifndef NOFRILLS
  298. #ifndef MAC
  299.     "fot",       XXDIR, CM_INV,    /* "fot" = "dir" (for Chris) */
  300. #endif /* MAC */
  301. #endif /* NOFRILLS */
  302.     "g",           XXGET, CM_INV|CM_ABR, /* Invisible abbreviation for GET */
  303. #ifndef NOSPL
  304.     "ge",          XXGET, CM_INV|CM_ABR, /* Ditto */
  305. #endif /* NOSPL */
  306.     "get",         XXGET, 0,        /* GET */
  307. #ifndef NOSPL
  308. #ifndef NOFRILLS
  309.     "getok",       XXGOK, 0,        /* GETOK (ask for Yes/No) */
  310. #endif /* NOFRILLS */
  311. #endif /* NOSPL */
  312. #ifndef NOSPL
  313.     "goto",        XXGOTO,0,        /* goto label in take file or macro */
  314. #endif /* NOSPL */
  315.     "hangup",      XXHAN, 0,        /* hangup dialed phone connection */
  316.     "help",       XXHLP, 0,        /* display help text */
  317. #ifndef NOSPL
  318.     "i",           XXINP, CM_INV|CM_ABR, /* invisible synonym for INPUT */
  319.     "if",          XXIF,  0,        /* if (condition) command */
  320.     "in",          XXINP, CM_INV|CM_ABR, /* invisible synonym for INPUT */
  321.     "increment",   XXINC, 0,        /* increment a numeric variable */
  322.     "input",       XXINP, 0,        /* input string from comm line */
  323. #endif /* NOSPL */
  324. #ifndef NOHELP
  325.      "introduction", XXINT, 0,        /* Print introductory text */
  326. #endif /* NOHELP */
  327. #ifndef NOFRILLS
  328.     "l",           XXLOG, CM_INV|CM_ABR,/* invisible synonym for log */
  329. #endif /* NOFRILLS */
  330.     "log",         XXLOG, 0,        /* open a log file */
  331. #ifndef NOFRILLS
  332. #ifndef MAC
  333.     "ls",          XXDIR, CM_INV,    /* invisible synonym for directory */
  334. #endif /* MAC */
  335.     "mail",        XXMAI, 0,        /* mail file to user */
  336.     "man",         XXHLP, CM_INV,       /* Synonym for help */
  337. #endif /* NOFRILLS */
  338. #ifndef NOMSEND
  339.     "mget",        XXGET, CM_INV,    /* MGET = GET */
  340. #endif /* NOMSEND */
  341. #ifndef NOSPL
  342.     "mpause",      XXMSL, CM_INV,    /* Millisecond sleep */
  343. #endif /* NOSPL */
  344. #ifndef NOMSEND
  345.     "ms",          XXMSE, CM_INV|CM_ABR,
  346.     "msend",       XXMSE, 0,        /* Multiple SEND */
  347. #endif /* NOMSEND */
  348. #ifndef NOSPL
  349.     "msleep",      XXMSL, 0,        /* Millisecond sleep */
  350. #endif /* NOSPL */
  351. #ifndef NOMSEND
  352.     "mput",        XXMSE, CM_INV,    /* MPUT = MSEND */
  353. #endif /* NOMSEND */
  354. #ifndef NOFRILLS
  355.     "mv",          XXREN, CM_INV,    /* rename a local file */
  356. #endif /* NOFRILLS */
  357. #ifndef NOSPL
  358.     "o",           XXOUT, CM_INV|CM_ABR,/* invisible synonym for OUTPUT */
  359.     "open",        XXOPE, 0,        /* open file for reading or writing */
  360.     "output",      XXOUT, 0,        /* output string to comm line */
  361. #endif /* NOSPL */
  362. #ifdef SUNX25
  363.     "pad",         XXPAD, 0,            /* PAD commands */
  364. #endif /* SUNX25 */
  365. #ifndef NOSPL
  366.     "pause",       XXPAU, 0,        /* sleep for specified interval */
  367. #ifdef TCPSOCKET
  368.     "ping",        XXPNG, 0,        /* PING (for TCP/IP) */
  369. #endif /* TCPSOCKET */
  370.     "pop",         XXEND, CM_INV,    /* allow POP as synonym for END */
  371. #endif /* NOSPL */
  372. #ifndef NOFRILLS
  373.     "print",       XXPRI, 0,        /* PRINT */
  374. #ifndef NOPUSH
  375.     "pu",          XXSHE, CM_INV,    /* PU = PUSH */
  376.     "push",        XXSHE, 0,        /* PUSH command (like RUN, !) */
  377. #endif /* NOPUSH */
  378.     "put",       XXSEN, CM_INV,    /* PUT = SEND */
  379. #ifndef MAC
  380.     "pwd",         XXPWD, 0,            /* print working directory */
  381. #endif /* MAC */
  382. #endif /* NOFRILLS */
  383.     "quit",       XXQUI, 0,        /* quit from program = exit */
  384.     "r",           XXREC, CM_INV,    /* invisible synonym for receive */
  385. #ifndef NOSPL
  386.     "read",        XXREA, 0,            /* read */
  387. #endif /* NOSPL */
  388.     "receive",       XXREC, 0,        /* receive files */
  389. #ifndef NODIAL
  390.     "redial",      XXRED, 0,        /* redial */
  391. #endif /* NODIAL */
  392. #ifndef NOSPL
  393.     "reinput",     XXREI, 0,            /* reinput */
  394. #endif /* NOSPL */
  395.     "remote",       XXREM, 0,        /* send generic command to server */
  396. #ifndef NOFRILLS
  397.     "rename",      XXREN, 0,        /* rename a local file */
  398.     "replay",      XXTYP, CM_INV,    /* replay (for now, just type) */
  399. #endif /* NOFRILLS */
  400. #ifndef NOSPL
  401.     "return",      XXRET, 0,        /* return from function */
  402. #endif /* NOSPL */
  403. #ifndef NOFRILLS
  404.     "rm",          XXDEL, CM_INV,    /* invisible synonym for delete */
  405. #endif /* NOFRILLS */
  406. #ifndef NOPUSH
  407.     "run",         XXSHE, 0,        /* run a program or command */
  408. #endif /* NOPUSH */
  409.     "s",           XXSEN, CM_INV|CM_ABR, /* invisible synonym for send */
  410. #ifndef NOSCRIPT
  411.     "script",       XXLOGI,0,        /* execute a uucp-style script */
  412. #endif /* NOSCRIPT */
  413.     "send",       XXSEN, 0,        /* send files */
  414. #ifndef NOSERVER
  415.     "server",       XXSER, 0,        /* be a server */
  416. #endif /* NOSERVER */
  417.     "set",       XXSET, 0,        /* set parameters */
  418. #ifndef NOSHOW
  419.     "show",        XXSHO, 0,        /* show parameters */
  420. #endif /* NOSHOW */
  421. #ifndef NOSPL
  422. #ifndef NOFRILLS
  423.     "sleep",       XXPAU, CM_INV,    /* sleep for specified interval */
  424. #endif /* NOFRILLS */
  425. #endif /* NOSPL */
  426. #ifndef MAC
  427. #ifndef NOFRILLS
  428.     "sp",          XXSPA, CM_INV|CM_ABR,
  429.     "spa",         XXSPA, CM_INV|CM_ABR,
  430. #endif /* NOFRILLS */
  431.     "space",       XXSPA, 0,        /* show available disk space */
  432. #endif /* MAC */
  433. #ifndef NOFRILLS
  434. #ifndef NOPUSH
  435.     "spawn",       XXSHE, CM_INV,    /* synonym for PUSH, RUN */
  436. #endif /* NOPUSH */
  437. #endif /* NOFRILLS */
  438.     "statistics",  XXSTA, 0,        /* display file transfer stats */
  439. #ifndef NOSPL
  440.     "stop",        XXSTO, 0,        /* stop all take files */
  441. #endif /* NOSPL */
  442. #ifndef NOJC
  443.     "suspend",     XXSUS, 0,        /* Suspend */
  444. #endif /* NOJC */
  445.     "take",       XXTAK, 0,        /* take commands from file */
  446. #ifndef NOFRILLS
  447. #ifdef NETCONN
  448.     "telnet",      XXTEL, 0,        /* telnet */
  449. #endif /* NETCONN */
  450.     "test",        XXTES, CM_INV,    /* (for testing) */
  451. #endif /* NOFRILLS */
  452. #ifndef NOCSETS
  453.     "translate",   XXXLA, 0,        /* translate local file char sets */
  454. #endif
  455. #ifndef NOXMIT
  456.     "transmit",    XXTRA, 0,        /* raw upload file */
  457. #endif /* NOXMIT */
  458. #ifndef NOFRILLS
  459.     "type",        XXTYP, 0,        /* display a local file */
  460. #endif /* NOFRILLS */
  461.     "version",     XXVER, 0        /* version number display */
  462. #ifndef NOSPL
  463. ,   "wait",        XXWAI, 0        /* wait (like pause) */
  464. ,   "while",       XXWHI, 0        /* while */
  465. #endif /* NOSPL */
  466. #ifndef MAC
  467. #ifndef NOFRILLS
  468. ,   "who",         XXWHO, 0        /* who */
  469. #endif /* NOFRILLS */
  470. #endif /* MAC */
  471. #ifndef NOSPL
  472. ,   "write",       XXWRI, 0        /* write */
  473. ,   "xif",         XXIFX, 0        /* Extended IF */
  474. #endif /* NOSPL */
  475. #ifndef NOCSETS
  476. ,   "xlate",       XXXLA, CM_INV    /* translate local file char sets */
  477. #endif
  478. #ifndef NOXMIT
  479. ,   "xmit",        XXTRA, CM_INV    /* raw upload file */
  480. #endif /* NOXMIT */
  481. ,   "z",           XXSUS, CM_INV    /* Suspend */
  482. #ifndef NOSPL
  483. ,   "_assign",     XXASX, CM_INV    /* used internally by FOR, etc */
  484. ,   "_define",     XXDFX, CM_INV    /* used internally by FOR, etc */
  485. ,   "_getargs",    XXGTA, CM_INV        /* used internally by FOR, etc */
  486. ,   "_putargs",    XXPTA, CM_INV        /* used internally by FOR, etc */
  487. #endif /* NOSPL */
  488. };
  489. int ncmd = (sizeof(cmdtab) / sizeof(struct keytab));
  490.  
  491. char toktab[] = {
  492. #ifndef NOPUSH
  493.     '!',                /* Shell escape */
  494. #endif /* NOPUSH */
  495.     '#',                /* Comment */
  496.     ';',                /* Comment */
  497. #ifndef NOSPL
  498.     ':',                /* Label */
  499. #endif /* NOSPL */
  500. #ifndef NOPUSH
  501.     '@',                /* DCL escape */
  502. #endif /* NOPUSH */
  503.     '\0'                /* End of this string */
  504. };
  505.  
  506. #ifndef NOSPL
  507. #ifndef NOFRILLS
  508. struct keytab yesno[] = {
  509.     "no",    0, 0,
  510.     "ok",    1, 0,
  511.     "yes",   1, 0
  512. };
  513. int nyesno = (sizeof(yesno) / sizeof(struct keytab));
  514. #endif /* NOFRILLS */
  515. #endif /* NOSPL */
  516.  
  517. /* Parameter keyword table */
  518.  
  519. struct keytab prmtab[] = {
  520.     "attributes",       XYATTR,  0,
  521.     "b",        XYBACK,  CM_INV|CM_ABR,
  522.     "ba",        XYBACK,  CM_INV|CM_ABR,
  523.     "background",       XYBACK,  0,
  524.     "baud",            XYSPEE,  CM_INV,
  525.     "block-check",      XYCHKT,  0,
  526. #ifdef DYNAMIC
  527.     "buffers",          XYBUF,   0,
  528. #endif /* DYNAMIC */
  529. #ifndef MAC
  530.     "carrier",          XYCARR,  0,
  531. #endif /* MAC */
  532. #ifndef NOSPL
  533.     "case",             XYCASE,  0,
  534. #endif /* NOSPL */
  535.     "command",          XYCMD,   0,
  536. #ifndef NOSPL
  537.     "count",            XYCOUN,  0,
  538. #endif /* NOSPL */
  539.     "d",        XYDELA,  CM_INV|CM_ABR,
  540.     "de",        XYDELA,  CM_INV|CM_ABR,
  541.     "debug",            XYDEBU,  CM_INV,
  542. #ifdef VMS
  543.     "default",          XYDFLT,  0,
  544. #else
  545. #ifndef MAC
  546.     "default",          XYDFLT,  CM_INV,
  547. #endif /* MAC */
  548. #endif /* VMS */
  549.     "delay",            XYDELA,  0,
  550. #ifndef NODIAL
  551.     "dial",             XYDIAL,  0,
  552. #endif /* NODIAL */
  553.     "duplex",            XYDUPL,  0,
  554.     "escape-character", XYESC,   0,
  555.     "file",           XYFILE,  0,
  556.     "flow-control",     XYFLOW,  0,
  557.     "handshake",        XYHAND,  0,
  558. #ifdef NETCONN
  559.     "host",             XYHOST,  0,
  560. #endif /* NETCONN */
  561.     "incomplete",       XYIFD,   CM_INV,
  562. #ifndef NOSPL
  563.     "i",        XYINPU,  CM_INV|CM_ABR,
  564.     "in",        XYINPU,  CM_INV|CM_ABR,
  565.     "input",            XYINPU,  0,
  566. #ifndef MAC
  567. #ifndef NOSETKEY
  568.     "key",        XYKEY,   0,
  569. #endif /* NOSETKEY */
  570. #endif /* MAC */
  571. #endif /* NOSPL */
  572.     "l",                XYLINE,  CM_INV|CM_ABR,
  573. #ifndef NOCSETS
  574.     "language",         XYLANG,  0,
  575. #endif /* NOCSETS */
  576.     "line",             XYLINE,  0,
  577.     "local-echo",    XYLCLE,  CM_INV,
  578. #ifndef NOSPL
  579.     "macro",            XYMACR,  0,
  580. #endif /* NOSPL */
  581. #ifdef COMMENT
  582. #ifdef VMS
  583.     "messages",         XYMSGS,  0,
  584. #endif /* VMS */
  585. #endif /* COMMENT */
  586. #ifndef NODIAL
  587.     "modem-dialer",    XYMODM,     0,
  588. #endif
  589. #ifdef NETCONN
  590.     "network",          XYNET,   0,
  591. #endif /* NETCONN */
  592. #ifdef SUNX25
  593.     "pad",              XYPAD,   0,
  594. #endif /* SUNX25 */
  595.     "parity",            XYPARI,  0,
  596.     "port",             XYLINE,  CM_INV,
  597. #ifndef NOFRILLS
  598.     "prompt",            XYPROM,  0,
  599. #endif /* NOFRILLS */
  600.     "quiet",        XYQUIE,  0,
  601.     "receive",          XYRECV,  0,
  602.     "retry-limit",      XYRETR,  0,
  603. #ifndef NOSCRIPT
  604.     "script",        XYSCRI,  0,
  605. #endif /* NOSCRIPT */
  606.     "send",             XYSEND,  0,
  607. #ifndef NOSERVER
  608.     "server",           XYSERV,  0,
  609. #endif /* NOSERVER */
  610. #ifdef UNIX
  611.     "session-log",      XYSESS,  0,
  612. #endif /* UNIX */
  613.     "speed",            XYSPEE,  0,
  614. #ifndef NOJC
  615.     "suspend",          XYSUSP,  0,
  616. #endif /* NOJC */
  617.     "take",             XYTAKE,  0,
  618. #ifdef TNCODE
  619.     "telnet",           XYTEL,   0,
  620. #endif /* TNCODE */
  621.     "terminal",         XYTERM,  0,
  622.     "transfer",         XYXFER,  0,
  623. #ifndef NOXMIT
  624.     "transmit",         XYXMIT,  0,
  625. #endif /* NOXMIT */
  626. #ifndef NOCSETS
  627.     "unknown-char-set", XYUNCS,  0,
  628. #endif /* NOCSETS */
  629.     "window-size",      XYWIND,  0
  630. #ifdef UNIX
  631. ,   "wildcard-expansion", XYWILD, 0
  632. #endif /* UNIX */
  633. #ifdef SUNX25
  634. ,   "x.25",             XYX25,   0,
  635.     "x25",              XYX25,   CM_INV
  636. #endif /* SUNX25 */
  637. #ifndef NOCSETS
  638. ,   "xfer",             XYXFER,  CM_INV
  639. #endif /* NOCSETS */
  640. #ifndef NOXMIT
  641. ,   "xmit",             XYXMIT,  CM_INV
  642. #endif /* NOXMIT */
  643. };
  644. int nprm = (sizeof(prmtab) / sizeof(struct keytab)); /* How many parameters */
  645.  
  646. /* Table of networks */
  647. #ifdef NETCONN
  648. struct keytab netcmd[] = {
  649. #ifdef DECNET
  650.     "decnet",        NET_DEC,  0,
  651. #endif /* DECNET */
  652. #ifdef NPIPE
  653.     "named-pipe",    NET_PIPE, 0,
  654. #endif /* NPIPE */
  655. #ifdef TCPSOCKET
  656.     "tcp/ip",        NET_TCPB, 0
  657. #endif /* TCPSOCKET */
  658. #ifdef SUNX25
  659. ,   "x",            NET_SX25, CM_INV|CM_ABR,
  660.     "x.25",         NET_SX25, 0,
  661.     "x25",          NET_SX25, CM_INV
  662. #endif /* SUNX25 */
  663. };
  664. int nnets = (sizeof(netcmd) / sizeof(struct keytab)); /* How many networks */
  665. #endif /* NETCONN */
  666.  
  667. /* Remote Command Table */
  668.  
  669. struct keytab remcmd[] = {
  670.     "cd",        XZCWD, 0,
  671.     "cwd",       XZCWD, CM_INV,
  672.     "delete",    XZDEL, 0,
  673.     "directory", XZDIR, 0,
  674.     "help",      XZHLP, 0,
  675. #ifndef NOPUSH
  676.     "host",      XZHOS, 0,
  677. #endif /* NOPUSH */
  678. #ifndef NOFRILLS
  679.     "kermit",    XZKER, 0,
  680.     "login",     XZLGI, 0,
  681.     "logout",    XZLGO, 0,
  682.     "print",     XZPRI, 0,
  683. #endif /* NOFRILLS */
  684.     "set",       XZSET, 0,
  685.     "space",     XZSPA, 0
  686. #ifndef NOFRILLS
  687. ,   "type",      XZTYP, 0,
  688.     "who",       XZWHO, 0
  689. #endif /* NOFRILLS */
  690. };
  691. int nrmt = (sizeof(remcmd) / sizeof(struct keytab));
  692.  
  693. struct keytab logtab[] = {
  694. #ifdef DEBUG
  695.     "debugging",    LOGD, 0,
  696. #endif /* DEBUG */
  697.     "packets",        LOGP, 0,
  698.     "session",      LOGS, 0
  699. #ifdef TLOG
  700. ,   "transactions", LOGT, 0
  701. #endif /* TLOG */
  702. };
  703. int nlog = (sizeof(logtab) / sizeof(struct keytab));
  704.  
  705. struct keytab writab[] = {
  706. #ifndef NOSPL
  707.     "append-file",     LOGW, CM_INV,
  708. #endif /* NOSPL */
  709.     "debug-log",       LOGD, 0,
  710.     "error",           LOGE, 0,
  711. #ifndef NOSPL
  712.     "file",            LOGW, 0,
  713. #endif /* NOSPL */
  714.     "packet-log",      LOGP, 0,
  715.     "screen",          LOGX, 0,
  716.     "session-log",     LOGS, 0,
  717.     "sys$output",      LOGX, CM_INV,
  718.     "transaction-log", LOGT, 0
  719. };
  720. int nwri = (sizeof(writab) / sizeof(struct keytab));
  721.  
  722. #define CLR_DEV  1
  723. #define CLR_INP  2
  724.  
  725. static struct keytab clrtab[] = {    /* Keywords for CLEAR command */
  726. #ifndef NOSPL
  727.     "both",          CLR_DEV|CLR_INP, 0,
  728. #endif /* NOSPL */
  729.     "device-buffer", CLR_DEV,         0,
  730. #ifndef NOSPL
  731.     "input-buffer",  CLR_INP,         0
  732. #endif /* NOSPL */
  733. };
  734. int nclear = (sizeof(clrtab) / sizeof(struct keytab));
  735.  
  736. struct keytab clstab[] = {        /* Keywords for CLOSE command */
  737. #ifndef NOSPL
  738.     "append-file",     LOGW, CM_INV,
  739. #endif /* NOSPL */
  740. #ifdef DEBUG
  741.     "debug-log",       LOGD, 0,
  742. #endif /* DEBUG */
  743.     "packet-log",      LOGP, 0,
  744. #ifndef NOSPL
  745.     "read-file",       LOGR, 0,
  746. #endif /* NOSPL */
  747.     "session-log",     LOGS, 0
  748. #ifdef TLOG
  749. ,   "transaction-log", LOGT, 0
  750. #endif /* TLOG */
  751. #ifndef NOSPL
  752. ,   "write-file",      LOGW, 0
  753. #endif /* NOSPL */
  754. };
  755. int ncls = (sizeof(clstab) / sizeof(struct keytab));
  756.  
  757. /* SHOW command arguments */
  758.  
  759. struct keytab shotab[] = {
  760. #ifndef NOSPL
  761.     "arguments", SHARG, 0,
  762.     "arrays", SHARR, 0,
  763. #endif /* NOSPL */
  764.     "attributes", SHATT, 0,
  765.     "character-sets", SHCSE, 0,
  766.     "communications", SHCOM, 0,
  767. #ifndef NOSPL
  768.     "count", SHCOU, 0,
  769. #endif /* NOSPL */
  770. #ifdef VMS
  771.     "default", SHDFLT, 0,
  772. #else
  773.     "default", SHDFLT, CM_INV,
  774. #endif /* VMS */
  775. #ifndef NODIAL
  776.     "dial", SHDIA, 0,
  777. #endif /* NODIAL */
  778.     "escape", SHESC, 0,
  779.     "features", SHFEA, 0,
  780.     "file", SHFIL, 0,
  781. #ifndef NOSPL
  782.     "functions", SHFUN, 0,
  783.     "globals", SHVAR, 0,
  784. #endif /* NOSPL */
  785. #ifndef NOSETKEY
  786.     "key", SHKEY, 0,
  787. #endif /* NOSETKEY */
  788. #ifdef VMS
  789.     "labeled-file-info", SHLBL, 0,
  790. #endif /* VMS */
  791. #ifndef NOCSETS
  792.     "languages", SHLNG, 0,
  793. #endif /* NOCSETS */
  794. #ifndef NOSPL
  795.     "macros", SHMAC, 0,
  796. #endif /* NOSPL */
  797.     "modem-signals", SHMOD, 0,
  798.     "network", SHNET, 0,
  799. #ifdef SUNX25
  800.     "pad", SHPAD, 0,
  801. #endif /* SUNX25 */
  802.     "parameters", SHPAR, CM_INV,
  803.     "protocol", SHPRO, 0,
  804. #ifndef NOSPL
  805.     "scripts", SHSCR, 0,
  806. #endif /* NOSPL */
  807. #ifndef NOSERVER
  808.     "server", SHSER, 0,
  809. #endif /* NOSERVER */
  810.     "status", SHSTA, 0,
  811. #ifdef MAC
  812.     "stack", SHSTK, 0,            /* debugging */
  813. #endif /* MAC */
  814.     "terminal", SHTER, 0
  815. #ifndef NOXMIT
  816. ,   "transmit", SHXMI, 0
  817. #endif /* NOXMIT */
  818. #ifndef NOSPL
  819. ,   "variables", SHBUI, 0
  820. #endif /* NOSPL */
  821. #ifndef NOFRILLS
  822. ,   "versions", SHVER, 0
  823. #endif /* NOFRILLS */
  824. #ifndef NOXMIT
  825. ,   "xmit", SHXMI, CM_INV
  826. #endif /* NOXMIT */
  827. };
  828. int nsho = (sizeof(shotab) / sizeof(struct keytab));
  829.  
  830. #ifdef SUNX25
  831. struct keytab padtab[] = {              /* PAD commands */
  832.     "clear",      XYPADL, 0,
  833.     "interrupt",  XYPADI, 0,
  834.     "reset",      XYPADR, 0,
  835.     "status",     XYPADS, 0
  836. };
  837. int npadc = (sizeof(padtab) / sizeof(struct keytab));
  838. #endif /* SUNX25 */
  839.  
  840. struct keytab enatab[] = {        /* ENABLE commands */
  841.     "all",        EN_ALL,  0,
  842. #ifndef datageneral
  843.     "bye",        EN_BYE,  0,
  844. #endif /* datageneral */
  845.     "cd",         EN_CWD,  0,
  846.     "cwd",        EN_CWD,  CM_INV,
  847.     "delete",     EN_DEL,  0,
  848.     "directory",  EN_DIR,  0,
  849.     "finish",     EN_FIN,  0,
  850.     "get",        EN_GET,  0,
  851.     "host",       EN_HOS,  0,
  852.     "send",       EN_SEN,  0,
  853.     "set",        EN_SET,  0,
  854.     "space",      EN_SPA,  0,
  855.     "type",       EN_TYP,  0,
  856.     "who",        EN_WHO,  0
  857. };
  858. int nena = (sizeof(enatab) / sizeof(struct keytab));
  859.  
  860. #ifndef NOSPL
  861. #ifdef COMMENT
  862. struct mtab mactab[MAC_MAX] = {        /* Preinitialized macro table */
  863.     NULL, NULL, 0
  864. };
  865. #else
  866. struct mtab *mactab;            /* Dynamically allocated macro table */
  867. #endif /* COMMENT */
  868. int nmac = 0;
  869.  
  870. struct keytab mackey[MAC_MAX];        /* Macro names as command keywords */
  871. #endif /* NOSPL */
  872.  
  873. /* Forward declarations of functions */
  874.  
  875. _PROTOTYP (int doask,   ( int  ) );
  876. _PROTOTYP (int dodef,   ( int  ) );
  877. _PROTOTYP (int dodel,   ( void ) );
  878. _PROTOTYP (int dodial,  ( int  ) );
  879. _PROTOTYP (int dodir,   ( void ) );
  880. _PROTOTYP (int doelse,  ( void ) );
  881. _PROTOTYP (int dofor,   ( void ) );
  882. _PROTOTYP (int dogta,   ( int  ) );
  883. _PROTOTYP (int doincr,  ( int  ) );
  884. _PROTOTYP (int dopaus,  ( int  ) );
  885. _PROTOTYP (int doping,  ( void ) );
  886. _PROTOTYP (int dorenam, ( void ) );
  887.  
  888. #ifdef TCPSOCKET
  889. int
  890. doping() {
  891.     char *p;
  892.     int x;
  893.  
  894.     if (network)            /* If we have a current connection */
  895.       strcpy(line,ttname);        /* get the host name */
  896.     else *line = '\0';            /* as default host to be pinged. */
  897.     for (p = line; *p; p++)        /* Remove ":service" from end. */
  898.       if (*p == ':') { *p = '\0'; break; }
  899.     if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
  900.       return(x);
  901. /* Construct PING command */
  902. #ifdef VMS
  903. #ifdef MULTINET                /* TGV MultiNet */
  904.     sprintf(line,"multinet ping %s /num=1",s);
  905. #else
  906.     sprintf(line,"ping %s 56 1",s);    /* Other VMS TCP/IP's */
  907. #endif /* MULTINET */
  908. #else                    /* Not VMS */
  909.     sprintf(line,"ping %s",s);
  910. #endif /* VMS */
  911.     conres();                /* Make console normal  */
  912. #ifdef DEC_TCPIP
  913.     printf("\n");            /* Prevent prompt-stomping */
  914. #endif /* DEC_TCPIP */
  915.     x = zshcmd(line);
  916.     concb((char)escape);
  917.     return(success = 1);        /* We don't know the status */
  918. }
  919. #endif /* TCPSOCKET */
  920.  
  921. /*  D O C M D  --  Do a command  */
  922.  
  923. /*
  924.  Returns:
  925.    -2: user typed an illegal command
  926.    -1: reparse needed
  927.     0: parse was successful (even tho command may have failed).
  928. */ 
  929. int
  930. docmd(cx) int cx; {
  931.  
  932.     debug(F101,"docmd entry, cx","",cx);
  933.  
  934. /*
  935.   Massive switch() broken up into many smaller ones, for the benefit of
  936.   compilers that run out of space when trying to handle large switch
  937.   statements.
  938. */
  939.     switch (cx) {
  940.       case -4:            /* EOF */
  941. #ifdef OSK
  942.     if (msgflg)  printf("\n");
  943. #else
  944.     if (msgflg)  printf("\r\n");
  945. #endif /* OSK */
  946.       doexit(GOOD_EXIT,xitsta);
  947.       case -3:                /* Null command */
  948.     return(0);
  949.       case -9:                /* Like -2, but errmsg already done */
  950.       case -1:                /* Reparse needed */
  951.     return(cx);
  952.       case -6:                /* Special */
  953.       case -2:                /* Error, maybe */
  954. #ifndef NOSPL
  955. /*
  956.   Maybe they typed a macro name.  Let's look it up and see.
  957. */
  958.     if (cx == -6)            /* If they typed CR */
  959.       strcat(cmdbuf,"\015");    /*  add it back to command buffer. */
  960.     if (ifcmd[cmdlvl] == 2)        /* Watch out for IF commands. */
  961.       ifcmd[cmdlvl]--;
  962.     repars = 1;            /* Force reparse */
  963.     cmres();
  964.     cx = XXDO;            /* Try DO command */
  965. #else
  966.     return(cx);
  967. #endif /* NOSPL */
  968.       default:
  969.     break;
  970.     }
  971.  
  972. #ifndef NOSPL
  973. /* Copy macro args from/to two levels up, used internally by _floop et al. */
  974.     if (cx == XXGTA || cx == XXPTA) {    /* _GETARGS, _PUTARGS */
  975.     int x;
  976.     debug(F101,"docmd XXGTA","",XXGTA);
  977.     debug(F101,"docmd cx","",cx);
  978.     debug(F101,"docmd XXGTA maclvl","",maclvl);
  979.     x = dogta(cx);
  980.     debug(F101,"docmd dogta returns","",x);
  981.     debug(F101,"docmd dogta maclvl","",maclvl);
  982.     return(x);
  983.     }
  984. #endif /* NOSPL */
  985.  
  986. #ifndef NOSPL
  987. /* ASK, ASKQ, READ */
  988.     if (cx == XXASK || cx == XXASKQ || cx == XXREA) {
  989.     return(doask(cx));
  990.     }
  991. #endif /* NOSPL */
  992.  
  993. #ifndef NOFRILLS
  994.     if (cx == XXBUG) {            /* BUG */
  995.     if ((x = cmcfm()) < 0) return(x);
  996.     return(dobug());
  997.     }
  998. #endif /* NOFRILLS */
  999.  
  1000.     if (cx == XXBYE) {            /* BYE */
  1001.     if ((x = cmcfm()) < 0) return(x);
  1002.     sstate = setgen('L',"","","");
  1003.     if (local) ttflui();        /* If local, flush tty input buffer */
  1004.     return(0);
  1005.     } 
  1006.  
  1007. #ifndef NOFRILLS
  1008.     if (cx == XXCLE) {            /* CLEAR */
  1009.     if ((x = cmkey(clrtab,nclear,"buffer(s) to clear",
  1010. #ifdef NOSPL
  1011.           "device-buffer"
  1012. #else
  1013.           "both"
  1014. #endif /* NOSPL */
  1015.           ,xxstring)) < 0) return(x);
  1016.     if ((y = cmcfm()) < 0) return(y);
  1017.  
  1018.     /* Clear device input buffer if requested */
  1019.     y = (x & CLR_DEV) ? ttflui() : 0;
  1020. #ifndef NOSPL
  1021.     /* Clear INPUT command buffer if requested */
  1022.     if (x & CLR_INP) {
  1023.         for (x = 0; x < INPBUFSIZ; x++)
  1024.           inpbuf[x] = 0;
  1025.         inpbp = inpbuf;
  1026.     }
  1027. #endif /* NOSPL */
  1028.     return(success = (y == 0));
  1029.     }
  1030. #endif /* NOFRILLS */
  1031.  
  1032.     if (cx == XXCOM) {            /* COMMENT */
  1033.     if ((x = cmtxt("Text of comment line","",&s,NULL)) < 0)
  1034.       return(x);
  1035.     /* Don't change SUCCESS flag for this one */
  1036.     return(0);
  1037.     } 
  1038.  
  1039.     if (cx == XXCON) {            /* CONNECT */
  1040.     if ((x = cmcfm()) < 0)
  1041.       return(x);
  1042.     return(success = doconect());
  1043.     }
  1044.  
  1045.     if (cx == XXCWD)            /* CWD */
  1046.       return(success = docd());
  1047.  
  1048.     if (cx == XXCHK)            /* CHECK */
  1049.       return(success = dochk());
  1050.  
  1051.     if (cx == XXCLO) {            /* CLOSE */
  1052.     x = cmkey(clstab,ncls,"Which log or file to close","",xxstring);
  1053.     if (x == -3) {
  1054.         printf("?You must say which file or log\n");
  1055.         return(-9);
  1056.     }
  1057.     if (x < 0) return(x);
  1058.     if ((y = cmcfm()) < 0) return(y);
  1059.     y = doclslog(x);
  1060.     success = (y == 1);
  1061.     return(success);
  1062.     }
  1063.  
  1064. #ifndef NOSPL
  1065.     if (cx == XXDEC || cx == XXINC)    /* DECREMENT, INCREMENT */
  1066.       return(doincr(cx));
  1067. #endif /* NOSPL */
  1068.  
  1069. #ifndef NOSPL
  1070.     if (cx == XXDEF || cx == XXASS || cx == XXASX || cx == XXDFX)
  1071.       return(dodef(cx));        /* DEFINE, ASSIGN */
  1072. #endif /* NOSPL */
  1073.  
  1074. #ifndef NOSPL    
  1075.     if (cx == XXDCL) {            /* DECLARE an array */
  1076.     if ((y = cmfld("Array name","",&s,NULL)) < 0) {
  1077.         if (y == -3) {
  1078.         printf("?Array name required\n");
  1079.         return(-9);
  1080.         } else return(y);
  1081.     }
  1082.     if ((y = arraynam(s,&x,&z)) < 0) return(y);
  1083.     if ((y = cmcfm()) < 0) return(y);
  1084.     if (dclarray((char)x,z) < 0) {
  1085.         printf("?Declare failed\n");
  1086.         return(success = 0);
  1087.     }
  1088.     return(success = 1);
  1089.     }
  1090. #endif /* NOSPL */
  1091.  
  1092.  
  1093. #ifndef NODIAL
  1094.     if (cx == XXRED || cx == XXDIAL)    /* DIAL or REDIAL */
  1095.       return(dodial(cx));
  1096. #endif /* NODIAL */
  1097.  
  1098. #ifndef NOFRILLS
  1099.     if (cx == XXDEL)            /* DELETE */
  1100.       return(dodel());
  1101. #endif /* NOFRILLS */
  1102.  
  1103. #ifndef MAC
  1104.     if (cx == XXDIR)            /* DIRECTORY */
  1105.       return(dodir());
  1106. #endif /* MAC */
  1107.  
  1108. #ifndef NOSPL
  1109.     if (cx == XXELS)            /* ELSE */
  1110.       return(doelse());
  1111. #endif /* NOSPL */
  1112.  
  1113. #ifndef NOFRILLS
  1114.     if (cx == XXENA || cx == XXDIS) {    /* ENABLE, DISABLE */
  1115.     s = (cx == XXENA) ?
  1116.       "Server function to enable" :
  1117.         "Server function to disable";
  1118.  
  1119.     if ((x = cmkey(enatab,nena,s,"",xxstring)) < 0) {
  1120.         if (x == -3) {
  1121.         printf("?Name of server function required\n");
  1122.         return(-9);
  1123.         } else return(x);
  1124.     }
  1125.     if ((y = cmcfm()) < 0) return(y);
  1126.     return(doenable(cx,x));
  1127.     }
  1128. #endif /* NOFRILLS */
  1129.  
  1130. #ifndef NOSPL
  1131.     if (cx == XXRET) {            /* RETURN */
  1132.     if (cmdlvl == 0) {        /* At top level, nothing happens... */
  1133.         if ((x = cmcfm()) < 0)
  1134.           return(x);
  1135.         return(success = 1);
  1136.     } else if (cmdstk[cmdlvl].src == CMD_TF) { /* In TAKE file, like POP */
  1137.         if ((x = cmtxt("optional return value","",&s,NULL)) < 0)
  1138.           return(x);        /* Allow trailing text, but ignore. */
  1139.         if ((x = cmcfm()) < 0)
  1140.           return(x);
  1141.         popclvl();            /* pop command level */
  1142.         return(success = 1);    /* always succeeds */
  1143.     } else if (cmdstk[cmdlvl].src == CMD_MD) { /* Within macro */  
  1144.         if ((x = cmtxt("optional return value","",&s,NULL)) < 0)
  1145.           return(x);
  1146.         return(doreturn(s));    /* Trailing text is return value. */
  1147.     } else return(-2);
  1148.     }
  1149. #endif /* NOSPL */
  1150.  
  1151. #ifndef NOSPL
  1152.     if (cx == XXDO) {            /* DO (a macro) */
  1153.     if (nmac == 0) {
  1154.         printf("\n?No macros defined\n");
  1155.         return(-2);
  1156.     }
  1157.     for (y = 0; y < nmac; y++) {    /* copy the macro table */
  1158.         mackey[y].kwd = mactab[y].kwd; /* into a regular keyword table */
  1159.         mackey[y].kwval = y;    /* with value = pointer to macro tbl */
  1160.         mackey[y].flgs = mactab[y].flgs;
  1161.     }
  1162.     /* parse name as keyword */
  1163.     if ((x = cmkey(mackey,nmac,"macro","",xxstring)) < 0) {
  1164.         if (x == -3) {
  1165.         printf("?Macro name required\n");
  1166.         return(-9);
  1167.         } else return(x);
  1168.     }
  1169.     if ((y = cmtxt("optional arguments","",&s,xxstring)) < 0)
  1170.       return(y);            /* get args */
  1171.     return(dodo(x,s) < 1 ? (success = 0) : 1);
  1172.     }
  1173. #endif /* NOSPL */
  1174.  
  1175.     if (cx == XXECH) {            /* ECHO */
  1176.     if ((x = cmtxt("Material to be echoed","",&s,xxstring)) < 0)
  1177.       return(x);
  1178.     if (*s == '{') {        /* Strip enclosing braces */
  1179.         x = (int)strlen(s);
  1180.         if (s[x-1] == '}') {
  1181.         s[x-1] = NUL;
  1182.         s++;
  1183.         }
  1184.     }
  1185.     printf("%s\n",s);
  1186.     return(1);            /* Always succeeds */
  1187.     }
  1188.  
  1189. #ifndef NOSPL
  1190.     if (cx == XXOPE)            /* OPEN */
  1191.       return(doopen());
  1192. #endif /* NOSPL */
  1193.  
  1194. #ifndef NOSPL
  1195.     if (cx == XXOUT) {            /* OUTPUT */
  1196.     if ((x = cmtxt("Text to be output","",&s,NULL)) < 0)
  1197.       return(x);
  1198.     debug(F110,"OUTPUT 1",s,0);
  1199.     if (*s == '{') {        /* Strip enclosing braces, */
  1200.         x = (int)strlen(s);        /* if any. */
  1201.         if (s[x-1] == '}') {
  1202.         s[x-1] = NUL;
  1203.         s++;
  1204.         }
  1205.     }
  1206.     debug(F110,"OUTPUT 2",s,0);
  1207.     for (x = 0, y = 0; s[x]; x++, y++) { /* Convert \B, \L to \\B, \\L */
  1208.         if (x > 0 &&
  1209.         (s[x] == 'B' || s[x] == 'b' || s[x] == 'L' || s[x] == 'l'))
  1210.           if ((x == 1 && s[x-1] == CMDQ) ||
  1211.           (x > 1 && s[x-1] == CMDQ && s[x-2] != CMDQ))
  1212.         line[y++] = CMDQ;
  1213.         line[y] = s[x];
  1214.     }
  1215.     line[y++] = '\0';        /* Now expand variables, etc. */
  1216.     debug(F110,"OUTPUT 3",line,0);
  1217.     s = line+y+1;
  1218.     x = LINBUFSIZ - strlen(line) - 1;
  1219.     debug(F101,"OUTPUT size","",x);
  1220.     if (xxstring(line,&s,&x) < 0)
  1221.       return(success = 0);
  1222.     s = line+y+1;
  1223.     debug(F110,"OUTPUT 4",s,0);
  1224.     return(success = dooutput(s));
  1225.     }
  1226. #endif /* NOSPL */
  1227.  
  1228. #ifdef SUNX25
  1229.     if (cx == XXPAD) {            /* PAD commands */
  1230.     x = cmkey(padtab,npadc,"PAD command","",xxstring);
  1231.     if (x == -3) {
  1232.         printf("?You must specify a PAD command to execute\n");
  1233.         return(-2);
  1234.     }
  1235.     if (x < 0) return(x);
  1236.     
  1237.     switch (x) {
  1238.       case XYPADL: 
  1239.         if (x25stat() < 0)
  1240.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  1241.         else {
  1242.         x25clear();
  1243.         initpad();
  1244.         }
  1245.         break;
  1246.       case XYPADS:
  1247.         if (x25stat() < 0)
  1248.           printf("Not connected\r\n");
  1249.         else {
  1250.         extern int linkid, lcn;
  1251.         conol("Connected thru ");
  1252.         conol(ttname);
  1253.         printf(", Link id %d, Logical channel number %d\r\n",
  1254.                linkid,lcn);
  1255.         }
  1256.         break;
  1257.       case XYPADR:
  1258.         if (x25stat() < 0)
  1259.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  1260.         else
  1261.           x25reset(0,0);
  1262.         break;
  1263.       case XYPADI:
  1264.         if (x25stat() < 0)
  1265.           printf("Sorry, you must 'set network' & 'set host' first\r\n");
  1266.         else 
  1267.           x25intr(0);
  1268.     }
  1269.     return(0);
  1270. }
  1271. #endif /* SUNX25 */
  1272.  
  1273. #ifndef NOSPL
  1274.     if (cx == XXPAU || cx == XXWAI || cx == XXMSL) /* PAUSE, WAIT, etc */
  1275.       return(dopaus(cx));
  1276. #endif /* NOSPL */
  1277.  
  1278. #ifndef NOFRILLS
  1279.     if (cx == XXPRI) {
  1280.     if ((x = cmifi("File to print","",&s,&y,xxstring)) < 0) {
  1281.         if (x == -3) {
  1282.         printf("?A file specification is required\n");
  1283.         return(-9);
  1284.         } else return(x);
  1285.     }
  1286.     if (y != 0) {
  1287.         printf("?Wildcards not allowed\n");
  1288.         return(-9);
  1289.     }
  1290.     strcpy(line,s);
  1291.     if ((x = cmtxt("Local print command options, or carriage return","",&s,
  1292.                xxstring)) < 0) return(x);
  1293.     return(success = (zprint(s,line) == 0) ? 1 : 0);
  1294.     }
  1295.  
  1296. #ifdef TCPSOCKET
  1297.     if (cx == XXPNG)             /* PING an IP host */
  1298.       return(doping());
  1299. #endif /* TCPSOCKET */
  1300.  
  1301. #ifndef MAC
  1302.     if (cx == XXPWD) {            /* PWD */
  1303.     if ((x = cmcfm()) < 0) return(x);
  1304.     xsystem(PWDCMD);
  1305.     return(success = 1);        /* blind faith */
  1306.     }
  1307. #endif /* MAC */
  1308. #endif /* NOFRILLS */
  1309.  
  1310.     if (cx == XXQUI || cx == XXEXI) {    /* EXIT, QUIT */
  1311.     if ((y = cmnum("exit status code","",10,&x,xxstring)) < 0) {
  1312.         if (y == -3)
  1313.           x = xitsta;
  1314.         else return(y);
  1315.     }
  1316.     if ((y = cmcfm()) < 0) return(y);
  1317. #ifdef VMS
  1318.     doexit(GOOD_EXIT,x);
  1319. #else
  1320. #ifdef OSK
  1321. /* Returning any codes here makes the OS-9 shell print an error message. */
  1322.     doexit(GOOD_EXIT,-1);
  1323. #else
  1324. #ifdef datageneral
  1325.         doexit(GOOD_EXIT,x);
  1326. #else
  1327.     doexit(x,-1);
  1328. #endif /* datageneral */
  1329. #endif /* OSK */
  1330. #endif /* VMS */
  1331.     }
  1332.  
  1333. #ifndef NOFRILLS
  1334.     if (cx == XXERR) {            /* ERROR */
  1335.     if ((x = cmcfm()) < 0) return(x);
  1336.     ttflui();
  1337.     sstate = 'a';
  1338.     return(0);
  1339.     }
  1340. #endif /* NOFRILLS */
  1341.  
  1342.     if (cx == XXFIN) {            /* FINISH */
  1343.     if ((x = cmcfm()) < 0) return(x);
  1344.     sstate = setgen('F',"","","");
  1345.     if (local) ttflui();        /* If local, flush tty input buffer */
  1346.     return(0);
  1347.     }
  1348.  
  1349. #ifndef NOSPL
  1350.     if (cx == XXFOR)            /* FOR loop */
  1351.       return(dofor());
  1352. #endif /* NOSPL */
  1353.  
  1354.     if (cx == XXGET) {            /* GET */
  1355.     x = cmtxt("Name of remote file(s), or carriage return","",&cmarg,
  1356.           xxstring);
  1357. #ifndef NOFRILLS
  1358.     if ((x == -2) || (x == -1)) return(x);
  1359. #else
  1360.     if (x < 0) return(x);
  1361. #endif /* NOFRILLS */
  1362.     if (*cmarg == '{') {        /* Strip any enclosing braces */
  1363.         x = (int)strlen(cmarg);    /* This allows preservation of */
  1364.         if (cmarg[x-1] == '}') {    /* leading and/or trailing */
  1365.         cmarg[x-1] = NUL;    /* spaces. */
  1366.         cmarg++;
  1367.         }
  1368.     }
  1369.     x = doget();
  1370. #ifdef MAC
  1371.     if (sstate == 'r')
  1372.         scrcreate();
  1373. #endif /* MAC */
  1374.     return(x);
  1375.     }
  1376.  
  1377. #ifndef NOSPL
  1378. #ifndef NOFRILLS
  1379.     if (cx == XXGOK) {            /* GETOK */
  1380.     return(success = doask(cx));
  1381.     }
  1382. #endif /* NOFRILLS */
  1383. #endif /* NOSPL */
  1384.  
  1385.     if (cx == XXHLP) {            /* HELP */
  1386. #ifdef NOHELP
  1387.     return(dohlp(XXHLP));        
  1388. #else
  1389.     x = cmkey2(cmdtab,ncmd,"C-Kermit command","help",toktab,xxstring);
  1390.     debug(F101,"HELP command x","",x);
  1391.     if (x == -5) {
  1392.         y = chktok(toktab);
  1393.         debug(F101,"top-level cmkey token","",y);
  1394.         ungword();
  1395.         switch (y) {
  1396. #ifndef NOPUSH
  1397.           case '!': x = XXSHE; break;
  1398. #endif /* NOPUSH */
  1399.           case '#': x = XXCOM; break;
  1400.           case ';': x = XXCOM; break;
  1401. #ifndef NOSPL
  1402.           case ':': x = XXLBL; break;
  1403. #endif /* NOSPL */
  1404.           case '&': x = XXECH; break;
  1405.           default:
  1406.         printf("\n?Invalid - %s\n",cmdbuf);
  1407.         x = -2;
  1408.         }
  1409.     }
  1410.     return(dohlp(x));
  1411. #endif /* NOHELP */
  1412.     }
  1413.  
  1414. #ifndef NOHELP
  1415.     if (cx == XXINT)            /* INTRO */
  1416.       return(hmsga(introtxt));
  1417. #endif /* NOHELP */
  1418.  
  1419.     if (cx == XXHAN) {            /* HANGUP */
  1420.     if ((x = cmcfm()) < 0) return(x);
  1421. #ifndef NODIAL
  1422.     if ((x = mdmhup()) < 1)
  1423. #endif /* NODIAL */
  1424.       x = (tthang() > -1);
  1425.     return(success = x);
  1426.     }
  1427.  
  1428. #ifndef NOSPL
  1429.     if (cx == XXGOTO) {            /* GOTO */
  1430. /* Note, here we don't set SUCCESS/FAILURE flag */
  1431.     if ((y = cmfld("label","",&s,xxstring)) < 0) {
  1432.         if (y == -3) {
  1433.         printf("?Label name required\n");
  1434.         return(-9);
  1435.         } else return(y);
  1436.     }
  1437.     strcpy(lblbuf,s);
  1438.     if ((x = cmcfm()) < 0) return(x);
  1439.     s = lblbuf;
  1440.     return(dogoto(s));
  1441.     }
  1442. #endif /* NOSPL */
  1443.  
  1444. #ifndef NOSPL
  1445. /* IF, Extended IF, WHILE */
  1446.     if (cx == XXIF || cx == XXIFX || cx == XXWHI) {
  1447.     return(doif(cx));
  1448.     }
  1449. #endif /* NOSPL */
  1450.  
  1451. #ifndef NOSPL
  1452.     if (cx == XXINP || cx == XXREI) {    /* INPUT and REINPUT */
  1453.     y = cmnum("seconds to wait for input","1",10,&x,xxstring);
  1454.     if (y < 0) {
  1455.         return(y);
  1456.     }
  1457.     if (x <= 0) x = 1;
  1458.     if ((y = cmtxt("Material to be input","",&s,xxstring)) < 0)
  1459.       return(y);
  1460. #ifdef COMMENT
  1461. /*
  1462.   Now it's ok -- null argument means wait for any character.
  1463. */
  1464.     if (*s == '\0') {
  1465.         printf("?Text required\n");
  1466.         return(-9);
  1467.     }
  1468. #endif /* COMMENT */
  1469.     if (*s == '{') {
  1470.         y = (int)strlen(s);
  1471.         if (s[y-1] == '}') {
  1472.         s[y-1] = NUL;
  1473.         s++;
  1474.         }
  1475.     }
  1476.     if (cx == XXINP) {        /* INPUT */
  1477.         debug(F110,"calling doinput",s,0);
  1478.         success = doinput(x,s);    /* Go try to input the search string */
  1479.     } else {            /* REINPUT */
  1480.         debug(F110,"xxrei line",s,0);
  1481.         success = doreinp(x,s);
  1482.     }
  1483.     if (intime && !success) {    /* TIMEOUT-ACTION = QUIT? */
  1484.         popclvl();            /* If so, pop command level. */
  1485.         if (pflag && cmdlvl == 0) {
  1486.         if (cx == XXINP) printf("?Input timed out\n");
  1487.         if (cx == XXREI) printf("?Reinput failed\n");
  1488.         }
  1489.     }
  1490.     return(success);        /* Return do(re)input's return code */
  1491.     }
  1492. #endif /* NOSPL */
  1493.  
  1494. #ifndef NOSPL
  1495.     if (cx == XXLBL) {            /* LABEL */
  1496.     if ((x = cmfld("label","",&s,xxstring)) < 0) {
  1497.         if (x == -3) {
  1498.         printf("?Label name required\n");
  1499.         return(-9);
  1500.         } else return(x);
  1501.     }
  1502.     if ((x = cmcfm()) < 0) return(x);
  1503.     return(0);
  1504.     }
  1505. #endif /* NOSPL */
  1506.  
  1507.     if (cx == XXLOG) {            /* LOG */
  1508.     x = cmkey(logtab,nlog,"What to log","",xxstring);
  1509.     if (x == -3) {
  1510.         printf("?Type of log required\n");
  1511.         return(-9);
  1512.     }
  1513.     if (x < 0) return(x);
  1514.     x = dolog(x);
  1515.     if (x < 0)
  1516.       return(x);
  1517.     else
  1518.       return(success = x);
  1519.     }
  1520.  
  1521. #ifndef NOSCRIPT
  1522.     if (cx == XXLOGI) {            /* UUCP-style script */
  1523.     if ((x = cmtxt("expect-send expect-send ...","",&s,xxstring)) < 0)
  1524.       return(x);
  1525. #ifdef VMS
  1526.     conres();            /* For Ctrl-C to work... */
  1527. #endif /* VMS */
  1528.     return(success = dologin(s));    /* Return 1=completed, 0=failed */
  1529.     }
  1530. #endif /* NOSCRIPT */
  1531.  
  1532.     if (cx == XXREC) {            /* RECEIVE */
  1533.     cmarg2 = "";
  1534.     x = cmofi("Name under which to store the file, or CR","",&s,
  1535.           xxstring);
  1536.     if ((x == -1) || (x == -2)) return(x);
  1537.     if ((x = cmcfm()) < 0) return(x);
  1538.     strcpy(line,s);
  1539.     cmarg2 = line;
  1540.     debug(F111,"cmofi cmarg2",cmarg2,x);
  1541.     sstate = 'v';
  1542. #ifdef MAC
  1543.     scrcreate();
  1544. #endif /* MAC */
  1545.     if (local) displa = 1;
  1546.     return(0);
  1547.     }
  1548.  
  1549.     if (cx == XXREM) {            /* REMOTE */
  1550.     x = cmkey(remcmd,nrmt,"Remote Kermit server command","",xxstring);
  1551.     if (x == -3) {
  1552.         printf("?You must specify a command for the remote server\n");
  1553.         return(-9);
  1554.     }
  1555.     return(dormt(x));
  1556.     }
  1557.  
  1558. #ifndef NOFRILLS
  1559.     if (cx == XXREN)            /* RENAME */
  1560.       return(dorenam());
  1561. #endif /* NOFRILLS */
  1562.  
  1563.     if (cx == XXSEN || cx == XXMAI) {    /* SEND, MAIL */
  1564.     cmarg = cmarg2 = "";
  1565.     if ((x = cmifi("File(s) to send","",&s,&y,xxstring)) < 0) {
  1566.         if (x == -3) {
  1567.         printf("?A file specification is required\n");
  1568.         return(-9);
  1569.         } else return(x);
  1570.     }
  1571.     nfils = -1;            /* Files come from internal list. */
  1572.     strcpy(line,s);            /* Save copy of string just parsed. */
  1573.     strncpy(fspec,s,FSPECL);    /* and here for \v(filespec) */
  1574.     if (cx == XXSEN) {        /* SEND command */
  1575.         debug(F101,"Send: wild","",y);
  1576.         if (y == 0) {
  1577.         if ((x = cmtxt("Name to send it with","",&cmarg2,
  1578.                    xxstring)) < 0)
  1579.           return(x);
  1580.         } else {
  1581.         if ((x = cmcfm()) < 0) return(x);
  1582.         }
  1583.         cmarg = line;        /* File to send */
  1584.         debug(F110,"Sending:",cmarg,0);
  1585.         if (*cmarg2 != '\0') debug(F110," as:",cmarg2,0);
  1586.     } else {            /* MAIL */
  1587. #ifndef NOFRILLS
  1588.         if (!atdiso || !atcapr) {    /* Disposition attribute off? */
  1589.         printf("?Disposition Attribute is Off\n");
  1590.         return(-2);
  1591.         }
  1592.         debug(F101,"Mail: wild","",y);
  1593.         *optbuf = NUL;        /* Wipe out any old options */
  1594.         if ((x = cmtxt("Address to mail to","",&s,xxstring)) < 0)
  1595.           return(x);
  1596.         if ((int)strlen(s) == 0) {
  1597.         printf("?Address required\n");
  1598.         return(-9);
  1599.         }
  1600.         strcpy(optbuf,s);
  1601.         if ((int)strlen(optbuf) > 94) { /* Ensure legal size */
  1602.         printf("?Option string too long\n");
  1603.         return(-2);
  1604.         }
  1605.         cmarg = line;        /* File to send */
  1606.         debug(F110,"Mailing:",cmarg,0);
  1607.         debug(F110,"To:",optbuf,0);
  1608.         rmailf = 1;            /* MAIL modifier flag for SEND */
  1609. #else
  1610.         printf("?Sorry, MAIL feature not configured.\n");
  1611.         return(-2);
  1612. #endif /* NOFRILLS */
  1613.     }
  1614.     sstate = 's';            /* Set start state to SEND */
  1615. #ifdef MAC
  1616.     scrcreate();
  1617. #endif /* MAC */
  1618.     if (local) {            /* If in local mode, */
  1619.         displa = 1;            /* turn on file transfer display */
  1620. #ifdef COMMENT
  1621. /* Redundant -- this is done later in sipkt() */
  1622.         ttflui();            /* and flush tty input buffer. */
  1623. #endif /* COMMENT */
  1624.     }
  1625.     return(0);
  1626.     }
  1627.  
  1628. #ifndef NOMSEND
  1629.     if (cx == XXMSE) {            /* MSEND command */
  1630.     nfils = 0;            /* Like getting a list of */
  1631.     lp = line;            /* files on the command line */
  1632.     while (1) {
  1633.         char *p;
  1634.         if ((x = cmifi("Names of files to send, separated by spaces","",
  1635.                &s,&y,xxstring)) < 0) {
  1636.         if (x == -3) {
  1637.             if (nfils <= 0) {
  1638.             printf("?A file specification is required\n");
  1639.             return(-9);
  1640.             } else break;
  1641.         }
  1642.         return(x);
  1643.         }
  1644.         msfiles[nfils++] = lp;    /* Got one, count it, point to it, */
  1645.         p = lp;            /* remember pointer, */
  1646.         while (*lp++ = *s++) ;    /* and copy it into buffer */
  1647.         debug(F111,"msfiles",msfiles[nfils-1],nfils-1);
  1648.         if (nfils == 1) *fspec = NUL; /* Take care of \v(filespec) */
  1649.         if (((int)strlen(fspec) + (int)strlen(p) + 1) < FSPECL) {
  1650.         strcat(fspec,p);
  1651.         strcat(fspec," ");
  1652.         }
  1653.     }
  1654.     cmlist = msfiles;        /* Point cmlist to pointer array */
  1655.     cmarg2 = "";            /* No internal expansion list (yet) */
  1656.     sndsrc = nfils;            /* Filenames come from cmlist */
  1657.     sstate = 's';            /* Set start state to SEND */
  1658. #ifdef MAC
  1659.     scrcreate();
  1660. #endif /* MAC */
  1661.     if (local) {            /* If in local mode, */
  1662.         displa = 1;            /* turn on file transfer display */
  1663.         ttflui();            /* and flush tty input buffer. */
  1664.     }
  1665.     return(0);
  1666.     }
  1667. #endif /* NOMSEND */
  1668.  
  1669. #ifndef NOSERVER
  1670.     if (cx == XXSER) {            /* SERVER */
  1671.     if ((x = cmcfm()) < 0) return(x);
  1672.     sstate = 'x';
  1673. #ifdef MAC
  1674.     scrcreate();
  1675. #endif /* MAC */
  1676.     if (local) displa = 1;
  1677. #ifdef AMIGA
  1678.     reqoff();            /* No DOS requestors while server */
  1679. #endif /* AMIGA */
  1680.     return(0);
  1681.     }
  1682. #endif /* NOSERVER */
  1683.  
  1684.     if (cx == XXSET) {            /* SET command */
  1685.     x = cmkey(prmtab,nprm,"Parameter","",xxstring);
  1686.     if (x == -3) {
  1687.         printf("?You must specify a parameter to set\n");
  1688.         return(-9);
  1689.     }
  1690.     if (x < 0) return(x);
  1691.     /* have to set success separately for each item in doprm()... */
  1692.     /* actually not really, could have just had doprm return 0 or 1 */
  1693.     /* and set success here... */
  1694.     y = doprm(x,0);
  1695.     if (y == -3) {
  1696.         printf("?More fields required\n");
  1697.         return(-9);
  1698.     } else return(y);
  1699.     }
  1700.  
  1701. #ifndef NOPUSH
  1702.     if (cx == XXSHE) {            /* SHELL (system) command */
  1703.     if (cmtxt("System command to execute","",&s,xxstring) < 0)
  1704.       return(-1);
  1705.     conres();            /* Make console normal  */
  1706.     x = zshcmd(s);
  1707.     concb((char)escape);
  1708.     return(success = x);
  1709.     }
  1710. #endif /* NOPUSH */
  1711.  
  1712. #ifndef NOSHOW
  1713.     if (cx == XXSHO) {            /* SHOW */
  1714.     x = cmkey(shotab,nsho,"","parameters",xxstring);
  1715.     if (x < 0) return(x);
  1716.     return(doshow(x));
  1717.     }
  1718. #endif /* NOSHOW */
  1719.  
  1720. #ifndef MAC
  1721.     if (cx == XXSPA) {            /* SPACE */
  1722. #ifdef datageneral
  1723.     /* AOS/VS can take an argument after its "space" command. */
  1724.     if ((x = cmtxt("Confirm, or local directory name","",&s,xxstring)) < 0)
  1725.       return(x);
  1726.     if (*s == NUL) xsystem(SPACMD);
  1727.     else {
  1728.         sprintf(line,"space %s",s);
  1729.         xsystem(line);
  1730.     }
  1731. #else
  1732. #ifdef OS2
  1733.     if ((x = cmtxt("Press Enter for current disk,\n\
  1734.  or specify a disk letter like A:","",&s,xxstring)) < 0)
  1735.       return(x);
  1736.     if (*s == NUL) {        /* Current disk */
  1737.         printf(" Free space: %ldK\n", zdskspace(0)/1024L);
  1738.     } else {
  1739.         int drive = toupper(*s);
  1740.         printf(" Drive %c: %ldK free\n", drive, 
  1741.            zdskspace(drive - 'A' + 1) / 1024L);
  1742.     }
  1743. #else
  1744. #ifdef UNIX
  1745. #ifdef COMMENT
  1746.     if ((x = cmtxt("Confirm for current disk,\n\
  1747.  or specify a disk device or directory","",&s,xxstring)) < 0)
  1748.       return(x);
  1749. #else
  1750.     x = cmdir("Confirm for current disk,\n\
  1751.  or specify a disk device or directory","",&s,xxstring);
  1752.     if (x == -3)
  1753.       s = "";
  1754.     else if (x < 0)
  1755.       return(x);
  1756.     if ((x = cmcfm()) < 0) return(x);
  1757. #endif /* COMMENT */
  1758.     if (*s == NUL) {        /* Current disk */
  1759.         xsystem(SPACMD);
  1760.     } else {            /* Specified disk */
  1761.         sprintf(line,"%s %s",SPACM2,s);
  1762.         xsystem(line);
  1763.     }
  1764. #else
  1765.     if ((x = cmcfm()) < 0) return(x);
  1766.     xsystem(SPACMD);
  1767. #endif /* UNIX */
  1768. #endif /* OS2 */
  1769. #endif /* datageneral */
  1770.     return(success = 1);        /* Pretend it worked */
  1771.     }
  1772. #endif /* MAC */
  1773.  
  1774.     if (cx == XXSTA) {            /* STATISTICS */
  1775.     if ((x = cmcfm()) < 0) return(x);
  1776.     return(success = dostat());
  1777.     }
  1778.  
  1779.     if (cx == XXSTO || cx == XXEND) {    /* STOP, END, or POP */
  1780.     if ((y = cmnum("exit status code","0",10,&x,xxstring)) < 0)
  1781.       return(y);
  1782.     if ((y = cmtxt("Message to print","",&s,xxstring)) < 0)
  1783.       return(y);
  1784.     if (*s == '{') {        /* Strip any enclosing braces */
  1785.         x = (int)strlen(s);
  1786.         if (s[x-1] == '}') {
  1787.         s[x-1] = NUL;
  1788.         s++;
  1789.         }
  1790.     }
  1791.     if (*s) printf("%s\n",s);
  1792.     if (cx == XXSTO) dostop(); else popclvl(); 
  1793.     return(success = (x == 0));
  1794.     }
  1795.  
  1796.     if (cx == XXSUS) {            /* SUSPEND */
  1797.     if ((y = cmcfm()) < 0) return(y);
  1798. #ifdef NOJC
  1799.     printf("Sorry, this version of Kermit cannot be suspended\n");
  1800. #else
  1801.     stptrap(0);
  1802. #endif /* NOJC */
  1803.     return(0);
  1804.     }
  1805.  
  1806.     if (cx == XXTAK) {            /* TAKE */
  1807.     if (tlevel > MAXTAKE-1) {
  1808.         printf("?Take files nested too deeply\n");
  1809.         return(-2);
  1810.     }
  1811.     if ((y = cmifi("C-Kermit command file","",&s,&x,xxstring)) < 0) { 
  1812.         if (y == -3) {
  1813.         printf("?A file name is required\n");
  1814.         return(-9);
  1815.         } else return(y);
  1816.     }
  1817.     if (x != 0) {
  1818.         printf("?Wildcards not allowed in command file name\n");
  1819.         return(-9);
  1820.     }
  1821.     strcpy(line,s);
  1822.     if ((y = cmcfm()) < 0) return(y);
  1823.     return(success = dotake(line));
  1824.     }
  1825.  
  1826. #ifdef NETCONN
  1827.     if (cx == XXTEL) {            /* TELNET */
  1828.     if ((y = setlin(XYHOST,0)) < 0) return(y);
  1829.     return (success = (y == 0) ? 0 : doconect());
  1830.     }
  1831. #endif /* NETCONN */
  1832.  
  1833. #ifndef NOXMIT
  1834.     if (cx == XXTRA) {            /* TRANSMIT */
  1835.     if ((x = cmifi("File to transmit","",&s,&y,xxstring)) < 0) {
  1836.         if (x == -3) {
  1837.         printf("?Name of an existing file\n");
  1838.         return(-9);
  1839.         } else return(x);
  1840.     }
  1841.     if (y != 0) {
  1842.         printf("?Only a single file may be transmitted\n");
  1843.         return(-2);
  1844.     }
  1845.     strcpy(line,s);            /* Save copy of string just parsed. */
  1846.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  1847.     debug(F111,"calling transmit",line,xmitp);
  1848.     return(success = transmit(line,(char)xmitp)); /* Do the command */
  1849.     }
  1850. #endif /* NOXMIT */
  1851.  
  1852. #ifndef NOFRILLS
  1853.     if (cx == XXTYP) {            /* TYPE */
  1854. #ifndef MAC
  1855.     char *tc;
  1856. #endif /* MAC */
  1857.     if ((x = cmifi("File to type","",&s,&y,xxstring)) < 0) {
  1858.         if (x == -3) {
  1859.         printf("?Name of an existing file\n");
  1860.         return(-9);
  1861.         } else return(x);
  1862.     }
  1863.     if (y != 0) {
  1864.         printf("?A single file please\n");
  1865.         return(-2);
  1866.     }
  1867. #ifndef MAC
  1868.     if (!(tc = getenv("CK_TYPE"))) tc = TYPCMD;
  1869.     sprintf(line,"%s %s",tc,s);
  1870.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  1871.     xsystem(line);
  1872.     return(success = 1);
  1873. #else
  1874.     strcpy(line,s);
  1875.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  1876.     return(success = dotype(line));
  1877. #endif /* MAC */
  1878.     }
  1879. #endif /* NOFRILLS */
  1880.  
  1881. #ifndef NOFRILLS
  1882.     if (cx == XXTES) {            /* TEST */
  1883.     /* Fill this in with whatever is being tested... */
  1884.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  1885.  
  1886. #ifndef NOSPL
  1887. #ifdef COMMENT
  1888.     { int d, i, j;            /* Dump all arrays */
  1889.       char c, **p;
  1890.       for (i = 0; i < 27; i++) {
  1891.           p = a_ptr[i];
  1892.           d = a_dim[i];
  1893.           c = (i == 0) ? 64 : i + 96;
  1894.           if (d && p) {
  1895.           fprintf(stderr,"&%c[%d]\n",c,d);
  1896.           for (j = 0; j <= d; j++) {
  1897.               if (p[j]) {
  1898.               fprintf(stderr,"  &%c[%2d] = [%s]\n",c,j,p[j]);
  1899.               }
  1900.           }      
  1901.           }
  1902.       }
  1903.       }
  1904. #else /* Not COMMENT */
  1905.     printf("cmdlvl = %d, tlevel = %d, maclvl = %d\n",cmdlvl,tlevel,maclvl);
  1906.     if (maclvl < 0) {
  1907.         printf("%s\n",
  1908.          "Call me from inside a macro and I'll dump the argument stack");
  1909.         return(0);
  1910.     }
  1911.     printf("Macro level: %d, ARGC = %d\n     ",maclvl,macargc[maclvl]);
  1912.     for (y = 0; y < 10; y++) printf("%7d",y);
  1913.     for (x = 0; x <= maclvl; x++) {
  1914.         printf("\n%2d:  ",x);
  1915.         for (y = 0; y < 10; y++) {
  1916.         s = m_arg[x][y];
  1917.         printf("%7s",s ? s : "(none)");
  1918.         }
  1919.     }
  1920.     printf("\n");
  1921. #endif /* COMMENT */
  1922. #endif /* NOSPL */
  1923.     return(0);
  1924.     }
  1925. #endif /* NOFRILLS */
  1926.  
  1927. #ifndef NOCSETS
  1928.     if (cx == XXXLA) {       /* TRANSLATE <ifn> from-cs to-cs <ofn> */
  1929.     int incs, outcs;
  1930.     if ((x = cmifi("File to translate","",&s,&y,xxstring)) < 0) {
  1931.         if (x == -3) {
  1932.         printf("?Name of an existing file\n");
  1933.         return(-9);
  1934.         } else return(x);
  1935.     }
  1936.     if (y != 0) {
  1937.         printf("?A single file please\n");
  1938.         return(-2);
  1939.     }
  1940.     strcpy(line,s);            /* Save copy of string just parsed. */
  1941.  
  1942.     if ((incs = cmkey(fcstab,nfilc,"from character-set","",xxstring)) < 0)
  1943.       return(incs);
  1944.     if ((outcs = cmkey(fcstab,nfilc,"to character-set","",xxstring)) < 0)
  1945.       return(outcs);
  1946.     if ((x = cmofi("output file",CTTNAM,&s,xxstring)) < 0) return(x);
  1947.     strncpy(tmpbuf,s,50);
  1948.     if ((y = cmcfm()) < 0) return(y); /* Confirm the command */
  1949.     return(success = xlate(line,tmpbuf,incs,outcs)); /* Execute it */
  1950.     }
  1951. #endif /* NOCSETS */
  1952.  
  1953.     if (cx == XXVER) {            /* VERSION */
  1954.     if ((y = cmcfm()) < 0) return(y);
  1955.     printf("%s,%s\n Numeric: %ld",versio,ckxsys,vernum);
  1956.     if (verwho) printf("-%d\n",verwho); else printf("\n");
  1957.     return(success = 1);
  1958.     }
  1959.  
  1960. #ifndef MAC
  1961. #ifndef NOFRILLS
  1962.     if (cx == XXWHO) {            /* WHO */
  1963.     char *wc;
  1964. #ifdef datageneral
  1965.         xsystem(WHOCMD);
  1966. #else
  1967.     if ((y = cmtxt("user name","",&s,xxstring)) < 0) return(y);
  1968.     if (!(wc = getenv("CK_WHO"))) wc = WHOCMD;
  1969.     sprintf(line,"%s %s",wc,s);
  1970.     xsystem(line);
  1971. #endif /* datageneral */
  1972.     return(success = 1);
  1973.     }
  1974. #endif /* NOFRILLS */
  1975. #endif /* MAC */
  1976.  
  1977. #ifndef NOFRILLS
  1978.     if (cx == XXWRI) {            /* WRITE */
  1979.     if ((x = cmkey(writab,nwri,"to file or log","",xxstring)) < 0) {
  1980.         if (x == -3) printf("?Write to what?\n");
  1981.         return(x);
  1982.     }
  1983.     if ((y = cmtxt("text","",&s,xxstring)) < 0) return(y);
  1984.     if (*s == '{') {        /* Strip enclosing braces */
  1985.         y = (int)strlen(s);
  1986.         if (s[y-1] == '}') {
  1987.         s[y-1] = NUL;
  1988.         s++;
  1989.         }
  1990.     }
  1991.     switch (x) {
  1992.       case LOGD: y = ZDFILE; break;
  1993.       case LOGP: y = ZPFILE; break;
  1994.       case LOGS: y = ZSFILE; break;
  1995.       case LOGT: y = ZTFILE; break;
  1996. #ifndef NOSPL
  1997.       case LOGW: y = ZWFILE; break;
  1998. #endif /* NOSPL */
  1999.       case LOGX:
  2000.       case LOGE:
  2001.  
  2002. #ifndef MAC
  2003.         if (x == LOGE) fprintf(stderr,"%s",s);
  2004.         else
  2005. #endif /* MAC */
  2006.           printf("%s",s);
  2007.         if (
  2008. #ifndef NOSPL
  2009.         cmdlvl == 0
  2010. #else
  2011.         tlevel == -1
  2012. #endif /* NOSPL */
  2013.         )
  2014. #ifndef MAC
  2015.           if (x == LOGE) fprintf(stderr,"\n");
  2016.           else
  2017. #endif /* MAC */
  2018.         printf("\n");
  2019.         return(success = 1);
  2020.       default: return(-2);
  2021.     }
  2022.     if ((x = zsout(y,s)) < 0)
  2023.       printf("?File or log not open\n");
  2024.     return(success = (x == 0) ? 1 : 0);
  2025.     }
  2026. #endif /* NOFRILLS */
  2027.  
  2028.     debug(F101,"docmd unk arg","",cx);
  2029.     return(-2);                /* None of the above. */
  2030. } /* end of docmnd() */
  2031.  
  2032. #endif /* NOICP */
  2033.