source: trunk/third/kermit/ckuusr.c @ 10780

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