6 char *userv = "User Interface 9.0.299, 9 Jun 2011";
8 /* C K U U S R -- "User Interface" for C-Kermit (Part 1) */
12 Frank da Cruz <fdc@columbia.edu>,
13 The Kermit Project, Columbia University, New York City
14 Jeffrey E Altman <jaltman@secure-endpoints.com>
15 Secure Endpoints Inc., New York City
17 Copyright (C) 1985, 2011,
18 Trustees of Columbia University in the City of New York.
19 All rights reserved. See the C-Kermit COPYING.TXT file or the
20 copyright text in the ckcmai.c module for disclaimer and permissions.
24 Originally the entire user interface was in one module, ckuusr.c. Over
25 the years it has been split into many modules: ckuus2.c, ckuus3.c, ...,
26 ckuus7.c. ckuus2.c contains the HELP command parser and help-text strings;
27 ckuusy.c contains the UNIX-style command-line interface; ckuusx.c contains
28 routines needed by both the command-line interface and the interactive
33 The ckuus*.c modules depend on the existence of C library features like
34 fopen, fgets, feof, (f)printf, argv/argc, etc. Other functions that are
35 likely to vary among different platforms -- like setting terminal modes or
36 interrupts -- are invoked via calls to functions that are defined in the
37 system- dependent modules, ck?[ft]io.c. The command line parser processes
38 any arguments found on the command line, as passed to main() via argv/argc.
39 The interactive parser uses the facilities of the cmd package (developed for
40 this program, but usable by any program). Any command parser may be
41 substituted for this one. The only requirements for the Kermit command
44 . Set parameters via global variables like duplex, speed, ttname, etc. See
45 ckcmai.c for the declarations and descriptions of these variables.
47 . If a command can be executed without the use of Kermit protocol, then
48 execute the command directly and set the variable sstate to 0. Examples
49 include 'set' commands, local directory listings, the 'connect' command.
51 . If a command requires the Kermit protocol, set the following variables:
54 'x' (enter server mode) (none)
55 'r' (send a 'get' command) cmarg, cmarg2
56 'v' (enter receive mode) cmarg2
57 'g' (send a generic command) cmarg
58 's' (send files) nfils, cmarg & cmarg2 OR cmlist
59 'c' (send a remote host command) cmarg
61 cmlist is an array of pointers to strings.
62 cmarg, cmarg2 are pointers to strings.
65 cmarg can be a filename string (possibly wild), or
66 a pointer to a prefabricated generic command string, or
67 a pointer to a host command string.
68 cmarg2 is an "as-name" - the name to send file(s) under, or
69 the name under which to store incoming file(s); must not be wild.
70 A null or empty value means to use the file's own name.
71 cmlist is a list of filenames, such as passed via argv.
72 nfils is an integer, interpreted as follows:
73 -1: filespec (possibly wild) in cmarg, must be expanded internally.
74 0: send from stdin (standard input).
75 >0: number of files to send, from cmlist.
77 The screen() function is used to update the screen during file transfer.
78 The tlog() function writes to a transaction log.
79 The debug() function writes to a debugging log.
80 The intmsg() and chkint() functions provide the user i/o for interrupting
87 #define MULTINET_OLD_STYLE /* Leave select prototype undefined */
93 #include "ckcnet.h" /* Network symbols */
97 int g_fncact = -1; /* Needed for NOICP builds */
98 int noinit = 0; /* Flag for skipping init file */
99 int nscanfile = SCANFILEBUF;
101 int rcdactive = 0; /* RCD active */
102 int keepallchars = 0; /* See cmfld() */
104 int locus = 1; /* Current LOCUS is LOCAL */
106 int autolocus = 2; /* Automatic LOCUS switching: ASK */
108 int autolocus = 1; /* Automatic LOCUS switching enabled */
114 #include <time.h> /* For CKLEARN */
120 #define INCL_VIO /* Needed for ckocon.h */
128 #include "ckntap.h" /* CK_TAPI definition */
132 extern int tcp_avail;
133 extern bool viewonly;
134 extern int k95stdout;
135 extern int tt_scroll;
137 extern tt_status[VNUM];
139 int display_demo = 1;
150 extern int ftpget, ftpisopen(), doftpres();
151 _PROTOTYP(int doftptyp,(int));
152 _PROTOTYP(VOID doftpglobaltype,(int));
160 #include <packets:common.h>
161 #define fgets(stringbuf,max,fd) dg_fgets(stringbuf,max,fd)
162 #endif /* datageneral */
164 extern int xcmdsrc, hints, cmflgs, whyclosed;
166 char * hlptok = NULL;
168 #ifdef CK_TTGWSIZ /* Whether to use more-prompting */
169 int xaskmore = 1; /* Momentary setting */
170 int saveask = 1; /* Permanent setting */
174 #endif /* CK_TTGWSIZ */
178 extern struct keytab fcstab[];
182 char * g_pswd = NULL;
186 extern int cmd_rows, cmd_cols;
189 extern int ckrooterr;
192 extern int inserver, filepeek;
195 FILE * learnfp = NULL;
196 char * learnfile = NULL;
201 extern int atcapr, atdiso, nfils, moving, protocol, sendmode, epktflg, size,
202 sndsrc, server, displa, fncnv, fnspath, fnrpath, xfermode, urpsiz,
203 spsizf, spsiz, spsizr, spmax, wslotr, prefixing, fncact, reliable,
208 #endif /* IKSDCONF */
212 #endif /* CK_LOGIN */
214 extern CK_OFF_T sendstart;
216 extern char *cmarg, *cmarg2, **cmlist, *dftty;
218 extern struct keytab fntab[]; extern int nfntab;
219 extern struct ck_p ptab[NPROTOS];
221 int sndcmd = 0; /* Last command was a SEND-class command. */
231 int g_prefixing = -1;
239 char * g_sfilter = NULL;
240 char * g_rfilter = NULL;
244 extern char *txtpatterns[], *binpatterns[];
246 #endif /* PATTERNS */
250 extern int usepipes, pipesend;
251 extern char * sndfilter;
252 #endif /* PIPESEND */
255 extern int sndxlo, sndxhi, sndxin;
258 extern char fspec[]; /* Most recent filespec */
259 extern int fspeclen; /* Length of fspec[] buffer */
262 extern int rmailf; /* MAIL command items */
263 extern char optbuf[];
264 #endif /* NOFRILLS */
267 en_cpy, en_cwd, en_del, en_dir, en_fin, en_get, en_bye, en_mai, en_pri,
268 en_hos, en_ren, en_sen, en_spa, en_set, en_typ, en_who, en_ret, en_xit,
269 en_mkd, en_rmd, en_asg;
271 #ifndef NOMSEND /* Multiple SEND */
272 extern char *msfiles[];
273 int filesinlist = 0; /* And ADD ... */
274 extern struct filelist * filehead;
275 extern struct filelist * filetail;
276 extern struct filelist * filenext;
280 static struct keytab addtab[] = {
282 { "binary-patterns", ADD_BIN, 0 },
283 #endif /* PATTERNS */
285 { "send-list", ADD_SND, 0 },
288 { "text-patterns", ADD_TXT, 0 },
289 #endif /* PATTERNS */
292 static int naddtab = sizeof(addtab)/sizeof(struct keytab) - 1;
295 struct keytab assoctab[] = {
296 { "file-character-set", ASSOC_FC, 0 },
297 { "transfer-character-set", ASSOC_TC, 0 },
298 { "xfer-character-set", ASSOC_TC, CM_INV }
300 static int nassoc = sizeof(assoctab)/sizeof(struct keytab);
301 extern int afcset[MAXFCSETS+1]; /* Character-set associations */
302 extern int axcset[MAXTCSETS+1];
312 #endif /* PATTERNS */
317 /* External Kermit Variables, see ckmain.c for description. */
319 extern xx_strp xxstring;
322 extern int local, xitsta, binary, msgflg, escape, duplex, quiet, tlevel,
323 pflag, zincnt, ckxech, carrier, what, nopush, haveline, bye_active;
326 extern char tn_msg[];
331 int g_recursive = -1;
336 extern char *versio, *copyright[];
339 extern char *introtxt[];
340 extern char *newstxt[];
350 extern char ttname[];
354 extern int network; /* Have active network connection */
355 extern int nettype; /* Type of network */
356 extern int ttnproto; /* NET_TCPB protocol */
359 extern int dialsta, dialatmo, dialcon, dialcq; /* DIAL status, etc. */
363 extern int apcactive, apcstatus;
368 extern char editor[];
369 extern char editopts[];
370 extern char editfile[];
371 #endif /* NOFRILLS */
375 extern char browser[]; /* Web browser application */
376 extern char browsopts[]; /* Web browser options */
377 extern char browsurl[]; /* Most recent URL */
380 char ftpapp[CKMAXPATH+1] = { NUL, NUL }; /* ftp executable */
381 char ftpopts[128] = { NUL, NUL }; /* ftp command-line options */
383 extern struct keytab onoff[]; /* On/Off keyword table */
386 int f_tmpdir = 0; /* Directory changed temporarily */
387 char savdir[TMPDIRLEN]; /* For saving current directory */
388 #endif /* CK_TMPDIR */
390 int activecmd = -1; /* Keyword index of active command */
391 int doconx = -1; /* CONNECT-class command active */
392 int ooflag = 0; /* User-settable on/off flag */
394 int rcflag = 0; /* Pointer to home directory string */
395 int repars, /* Reparse needed */
396 techo = 0; /* Take echo */
397 int secho = 1; /* SCRIPT echo */
399 int xitwarn = /* Warn about open connection on exit */
407 struct keytab onoffsw[] = {
413 struct keytab redirsw[] = {
414 { "/redirect", 1, 0 }
419 /* Variables for TRANSMIT command */
421 int xmitx = 1; /* Whether to echo during TRANSMIT */
422 int xmitf = 0; /* Character to fill empty lines */
423 int xmitl = 0; /* 0 = Don't send linefeed too */
424 int xmitp = LF; /* Host line prompt */
425 int xmits = 0; /* Use shift-in/shift-out, 0 = no */
426 int xmitw = 0; /* Milliseconds to pause during TRANSMIT */
427 int xmitt = 1; /* Seconds to wait for each char to echo */
428 int xmita = 1; /* Action upon timeout */
439 static struct keytab xmitsw[] = { /* TRANSMIT command options */
440 { "/binary", XMI_BIN, 0 },
442 { "/command", XMI_CMD, CM_INV|CM_PSH },
443 #endif /* PIPESEND */
444 { "/noecho", XMI_NOE, 0 },
445 { "/nowait", XMI_NOW, 0 },
447 { "/pipe", XMI_CMD, 0 },
448 #endif /* PIPESEND */
450 { "/quiet", XMI_QUI, 0 },
452 { "/text", XMI_TXT, 0 },
453 { "/transparent", XMI_TRA, 0 },
455 { "/verbose", XMI_VRB, 0 },
459 #define NXMITSW sizeof(xmitsw)/sizeof(struct keytab) - 1
460 static int nxmitsw = NXMITSW;
464 /* Declarations from ck?fio.c module */
466 extern char *SPACMD, *SPACM2; /* SPACE commands */
468 /* Command-oriented items */
471 extern char *cmdbuf; /* Command buffers */
473 extern char *line; /* Character buffer for anything */
474 extern char *tmpbuf; /* Short temporary string buffer */
479 extern char cmdbuf[]; /* Command buffers */
480 extern char atmbuf[];
481 extern char line[]; /* Character buffer for anything */
482 extern char tmpbuf[]; /* Temporary buffer */
489 extern char * prstring[];
492 char *lp; /* Pointer to line buffer */
495 int vareval = 1; /* Evaluation method */
496 int unkmacro = 0; /* Flag for in ON_UNKNOWN_COMMAND */
498 char evalbuf[33]; /* EVALUATE result */
499 extern char * inpbuf; /* Buffer for INPUT and REINPUT */
500 char *inpbp; /* And pointer to same */
501 int m_found; /* MINPUT result */
502 int i_active = 0; /* INPUT command is active */
503 char *ms[MINPMAX]; /* Pointers to MINPUT strings */
504 static int mpinited = 0; /* Flag they have been initialized */
505 static int mp[MINPMAX]; /* and MINPUT flags */
506 extern int fndiags, fnerror, fnsuccess; /* Function diagnostics */
508 char * lastsexp = NULL; /* S-Expressions */
509 char * sexpval = NULL;
510 int sexpecho = SET_AUTO;
514 char psave[PROMPTL] = { NUL }; /* For saving & restoring prompt */
516 extern int success; /* Command success/failure flag */
517 extern int cmdlvl; /* Current position in command stack */
520 int /* SET INPUT parameters. */
521 /* Note, INPUT TIMEOUT, intime[], is on the command-level stack. */
522 inbufsize = 0, /* INPUT buffer size */
523 indef = 1, /* default timeout, seconds */
524 inecho = 1, /* 1 = echo on */
525 inautodl = 0, /* INPUT autodownload */
526 inintr = 1, /* INPUT interrupion allowed */
527 insilence = 0; /* 0 = no silence constraint */
530 CKFLOAT inscale = 1.0; /* Timeout scale factor */
534 int interm = 1; /* Terminal emulator displays input */
536 int maclvl = -1; /* Macro nesting level */
537 int mecho = 0; /* Macro echo, 0 = don't */
538 char varnam[6]; /* For variable names */
539 extern int macargc[]; /* ARGC from macro invocation */
541 extern char *m_arg[MACLEVEL][NARGS]; /* Stack of macro arguments */
542 extern char *mrval[];
544 extern char **a_ptr[]; /* Array pointers */
545 extern int a_dim[]; /* Array dimensions */
549 extern struct cmdptr *cmdstk; /* The command stack itself */
551 extern struct cmdptr cmdstk[]; /* The command stack itself */
554 long ck_alarm = 0; /* SET ALARM value */
555 char alrm_date[24] = { ' ',' ',' ',' ',' ',' ',' ',' ',' ' };
556 char alrm_time[24] = { ' ',' ',' ',' ',' ',' ',' ' };
558 struct keytab inputsw[] = {
559 { "/clear", INPSW_CLR, 0 },
560 { "/count", INPSW_COU, CM_ARG },
561 { "/nomatch", INPSW_NOM, 0 },
562 { "/nowrap", INPSW_NOW, 0 }
564 static int ninputsw = sizeof(inputsw)/sizeof(struct keytab);
566 /* The following should be reconciled with the above */
568 #ifdef COMMENT /* INPUT switches not used yet... */
569 static struct keytab inswtab[] = {
571 { "/assign", IN_ASG, CM_ARG },
573 { "/autodownload", IN_ADL, CM_ARG },
574 { "/case", IN_CAS, CM_ARG },
575 { "/echo", IN_ECH, CM_ARG },
576 { "/interrupts", IN_NOI, CM_ARG },
577 { "/silence", IN_SIL, CM_ARG },
579 { "/pattern", IN_PAT, CM_ARG },
583 static int ninswtab = (sizeof(inswtab) / sizeof(struct keytab)) - 1;
589 static int x, y, z = 0; /* Local workers */
593 static char c1chars[] = { /* C1 control chars escept NUL */
594 001,002,003,004,005,006,007,010,011,012,013,014,015,016,017,020,
595 021,022,023,024,025,026,027,030,031,032,033,034,035,036,037
597 #endif /* CK_MINPUT */
599 #define xsystem(s) zsyscmd(s)
601 /* Top-Level Interactive Command Keyword Table */
602 /* Keywords must be in lowercase and in alphabetical order. */
604 struct keytab cmdtab[] = {
606 { "!", XXSHE, CM_INV|CM_PSH }, /* Shell escape */
608 { "!", XXNOTAV, CM_INV|CM_PSH },
610 { "#", XXCOM, CM_INV }, /* Comment */
612 { "(", XXSEXP,CM_INV }, /* S-Expression */
613 { ".", XXDEF, CM_INV }, /* Assignment */
614 { ":", XXLBL, CM_INV }, /* Label */
618 { "<", XXFUN, CM_INV|CM_PSH }, /* REDIRECT */
620 { "<", XXNOTAV, CM_INV|CM_PSH }, /* REDIRECT */
622 #endif /* CK_REDIR */
624 { "@", XXSHE, CM_INV|CM_PSH }, /* DCL escape */
626 { "@", XXNOTAV, CM_INV|CM_PSH }, /* DCL escape */
630 { "^", XXREDO,CM_INV|CM_NOR }, /* Synonym for REDO */
631 #endif /* CK_RECALL */
633 { "_asg", XXASX, CM_INV }, /* Used internally by FOR, etc */
634 { "_assign", XXASX, CM_INV }, /* Used internally by FOR, etc */
635 { "_decrement", XX_DECR, CM_INV },
636 { "_define", XXDFX, CM_INV }, /* Used internally by FOR, etc */
637 { "_evaluate", XX_EVAL, CM_INV },
638 { "_forward", XXXFWD, CM_INV }, /* Used internally by SWITCH */
639 { "_getargs", XXGTA, CM_INV }, /* Used internally by FOR, etc */
640 { "_increment", XX_INCR, CM_INV },
641 { "_putargs", XXPTA, CM_INV }, /* Used internally by FOR, etc */
642 { "_undefine", XXUNDFX, CM_INV },
645 { "about", XXVER, CM_INV }, /* Synonym for VERSION */
648 { "account", XXACCT, CM_INV }, /* (FTP) Account */
651 { "add", XXADD, 0 }, /* ADD */
654 { "answer", XXANSW, CM_LOC }, /* ANSWER the phone */
656 { "answer", XXNOTAV, CM_INV|CM_LOC }, /* ANSWER the phone */
658 { "apc", XXAPC, 0 }, /* Application Program Command */
660 { "array", XXARRAY, 0 }, /* Array operations */
662 { "ascii", XXASC, CM_INV }, /* == SET FILE TYPE TEXT */
663 { "asg", XXASS, CM_INV }, /* Invisible synonym for ASSIGN */
664 { "ask", XXASK, 0 }, /* ASK for text, assign to variable */
665 { "askq", XXASKQ,0 }, /* ASK quietly (no echo) */
667 { "ass", XXASS, CM_INV|CM_ABR }, /* ASSIGN */
668 { "assert", XXASSER, CM_INV }, /* ASSERT */
669 { "assign", XXASS, 0 }, /* ASSIGN */
673 { "associate", XXASSOC, 0 }, /* ASSOCIATE */
675 { "associate", XXNOTAV, CM_INV }, /* ASSOCIATE */
679 #ifdef CK_AUTHENTICATION
680 { "authenticate",XXAUTH, 0 }, /* Authentication */
682 { "authenticate",XXAUTH, CM_INV },
683 #endif /* CK_AUTHENTICATION */
684 #endif /* CK_KERBEROS */
687 { "back", XXBACK, 0 }, /* BACK to previous directory */
689 { "back", XXNOTAV,CM_INV },
690 #endif /* NOFRILLS */
691 { "beep", XXBEEP,CM_INV }, /* BEEP */
693 { "binary", XXBIN, CM_INV }, /* == SET FILE TYPE BINARY */
696 { "bug", XXBUG, CM_INV }, /* BUG report instructions */
698 { "bug", XXNOTAV, CM_INV },
699 #endif /* NOFRILLS */
701 { "browse", XXBROWS, CM_PSH|CM_LOC }, /* BROWSE (start browser) */
703 { "browse", XXNOTAV, CM_INV|CM_PSH|CM_LOC },
706 { "bye", XXBYE, 0 }, /* BYE to remote server */
709 { "c", XXCON, CM_INV|CM_ABR|CM_LOC }, /* (CONNECT) */
712 { "cat", XXCAT, CM_INV }, /* Invisible synonym for TYPE */
713 #endif /* NOFRILLS */
717 { "cautious", XXCAU, CM_INV },
722 { "cd", XXCWD, 0 }, /* Change Directory */
723 { "cdup", XXCDUP, CM_INV }, /* Change Directory Up */
727 { "cget", XXCGET, CM_INV|CM_PSH }, /* CGET */
729 { "cget", XXNOTAV, CM_INV|CM_PSH }, /* CGET */
730 #endif /* PIPESEND */
732 { "ch", XXCHK, CM_INV|CM_ABR },
733 { "check", XXCHK, 0 }, /* CHECK for a feature */
736 { "chmod", XXCHMOD, 0 }, /* CHMOD */
738 { "chmod", XXNOTAV, CM_INV },
741 { "chmod", XXNOTAV, CM_INV },
742 #endif /* CK_PERMS */
744 { "chroot", XXCHRT, CM_INV }, /* CHROOT */
746 { "ckermit", XXKERMI, CM_INV }, /* CKERMIT (like KERMIT) */
747 { "cl", XXCLO, CM_ABR|CM_INV },
749 { "clear", XXCLE, 0 }, /* CLEAR input and/or device buffer */
751 { "clear", XXNOTAV, CM_INV },
752 #endif /* NOFRILLS */
753 { "close", XXCLO, 0 }, /* CLOSE a log or other file */
754 { "cls", XXCLS, CM_INV }, /* Clear Screen (CLS) */
755 { "comment", XXCOM, CM_INV }, /* Introduce a comment */
757 { "connect", XXCON, CM_LOC }, /* Begin terminal connection */
759 { "connect", XXNOTAV, CM_LOC },
761 { "continue", XXCONT, CM_INV }, /* CONTINUE */
764 { "co", XXCPY, CM_INV|CM_ABR },
765 { "cop", XXCPY, CM_INV|CM_ABR },
766 { "copy", XXCPY, 0 }, /* COPY a file */
768 { "copy", XXNOTAV, CM_INV },
770 { "copyright", XXCPR, CM_INV }, /* COPYRIGHT */
772 { "cp", XXCPY, CM_INV }, /* COPY a file */
776 { "cq", XXCQ, CM_INV|CM_LOC }, /* CQ (connect quietly) */
781 { "creceive", XXCREC,CM_INV|CM_PSH }, /* RECEIVE to a command */
782 { "csend", XXCSEN,CM_INV|CM_PSH }, /* SEND from command */
784 { "creceive", XXNOTAV,CM_INV|CM_PSH },
785 { "csend", XXNOTAV,CM_INV|CM_PSH },
786 #endif /* PIPESEND */
788 #endif /* NOFRILLS */
790 { "cwd", XXCWD, CM_INV }, /* Traditional synonym for cd */
793 { "date", XXDATE, 0 }, /* DATE */
794 { "dcl", XXDCL, CM_INV }, /* DECLARE an array (see ARRAY) */
795 { "debug", XXDEBUG, 0 }, /* Print a debugging msg [9.0] */
796 { "declare", XXDCL, CM_INV }, /* DECLARE an array (see ARRAY) */
797 { "decrement", XXDEC, 0 }, /* DECREMENT a numeric variable */
798 { "define", XXDEF, 0 }, /* DEFINE a macro or variable */
800 { "date", XXNOTAV, CM_INV },
801 { "dcl", XXNOTAV, CM_INV },
802 { "declare", XXNOTAV, CM_INV },
803 { "decrement", XXNOTAV, CM_INV },
804 { "define", XXNOTAV, CM_INV },
808 { "delete", XXDEL, 0 }, /* DELETE a file */
810 { "delete", XXNOTAV, CM_INV },
811 #endif /* NOFRILLS */
814 { "dial", XXDIAL, CM_LOC }, /* DIAL a phone number */
816 { "dial", XXNOTAV, CM_INV|CM_LOC },
820 { "dialer", XXDIALER, CM_INV }, /* K95 Dialer */
823 { "directory", XXDIR, 0 }, /* DIRECTORY of files */
827 { "disable", XXDIS, 0 }, /* DISABLE a server function */
829 { "disable", XXNOTAV, CM_INV },
830 #endif /* NOSERVER */
831 #endif /* NOFRILLS */
834 { "do", XXDO, 0 }, /* DO (execute) a macro */
836 { "do", XXNOTAV, CM_INV },
839 { "e", XXEXI, CM_INV|CM_ABR },
843 { "e-packet", XXERR, CM_INV }, /* Send an Error-Packet */
845 #endif /* NOFRILLS */
847 { "echo", XXECH, 0 }, /* ECHO text */
851 { "edit", XXEDIT, CM_PSH }, /* EDIT */
853 { "edit", XXNOTAV, CM_INV|CM_PSH }, /* EDIT */
855 #endif /* NOFRILLS */
857 { "eightbit", XXEIGHT, CM_INV }, /* EIGHTBIT */
860 { "else", XXELS, CM_INV }, /* ELSE part of IF statement */
862 { "else", XXNOTAV, CM_INV }, /* ELSE part of IF statement */
867 { "enable", XXENA, 0 }, /* ENABLE a server function */
869 { "enable", XXNOTAV, CM_INV },
870 #endif /* NOFRILLS */
871 #endif /* NOSERVER */
874 { "end", XXEND, 0 }, /* END command file or macro */
876 { "end", XXNOTAV, CM_INV },
879 { "erase", XXDEL, CM_INV }, /* Synonym for DELETE */
882 { "evaluate", XXEVAL, 0 }, /* EVALUATE */
884 { "evaluate", XXNOTAV, CM_INV },
887 { "ex", XXEXI, CM_INV|CM_ABR }, /* Let "ex" still be EXIT */
890 { "exec", XXEXEC, CM_INV|CM_LOC }, /* exec() */
892 { "exec", XXNOTAV, CM_INV|CM_LOC },
895 { "exit", XXEXI, 0 }, /* EXIT from C-Kermit */
896 { "extended-options", XXXOPTS,CM_INV|CM_HLP }, /* Extended-Options */
899 { "extproc", XXCOM, CM_INV }, /* Dummy command for OS/2 */
903 { "f", XXFIN, CM_INV|CM_ABR }, /* Invisible abbrev for FIN */
907 { "fail", XXFAIL, CM_INV }, /* FAIL */
910 { "fast", XXFAST, CM_INV },
914 { "fclose", XXF_CL, CM_INV }, /* FCLOSE */
915 { "fcount", XXF_CO, CM_INV }, /* FCOUNT */
916 { "fflush", XXF_FL, CM_INV }, /* FFLUSH */
917 #endif /* CKCHANNELIO */
920 { "fi", XXFIN, CM_INV|CM_ABR }, /* FINISH */
924 { "file", XXFILE, 0 }, /* FILE */
925 #endif /* CKCHANNELIO */
929 { "fin", XXFIN, CM_INV|CM_ABR }, /* FINISH */
933 { "find", XXGREP, 0 }, /* FIND (grep) */
935 { "find", XXGREP,CM_INV },
936 #endif /* UNIXOROSK */
939 { "finish", XXFIN, 0 }, /* FINISH */
943 { "firewall", XXFIREW, CM_INV|CM_HLP },
944 #endif /* TCPSOCKET */
947 { "flist", XXF_LI, CM_INV }, /* FLIST */
948 { "fopen", XXF_OP, CM_INV }, /* FOPEN */
949 #endif /* CKCHANNELIO */
952 { "fo", XXFOR, CM_INV|CM_ABR }, /* Invisible abbrev for... */
953 { "for", XXFOR, 0 }, /* FOR loop */
954 { "forward", XXFWD, CM_INV }, /* FORWARD */
957 { "fot", XXDIR, CM_INV }, /* "fot" = "dir" (for Chris) */
958 #endif /* NOFRILLS */
961 { "fread", XXF_RE, CM_INV }, /* FREAD */
962 { "frewind", XXF_RW, CM_INV }, /* FREWIND */
963 { "fseek", XXF_SE, CM_INV }, /* FSEEK */
964 { "fstatus", XXF_ST, CM_INV }, /* FSTATUS */
965 #endif /* CKCHANNELIO */
971 { "ftp", XXFTP, CM_INV|CM_PSH|CM_LOC }, /* System FTP */
973 { "ftp", XXNOTAV, CM_INV|CM_PSH|CM_LOC },
976 { "ftp", XXFTP, 0 }, /* Built-in FTP */
979 { "ftp", XXNOTAV, CM_INV }, /* No FTP */
981 #endif /* TCPSOCKET */
984 { "function", XXFUNC, CM_INV|CM_HLP }, /* (for HELP FUNCTION) */
988 { "fwrite", XXF_WR, CM_INV }, /* FWRITE */
989 #endif /* CKCHANNELIO */
992 { "g", XXGET, CM_INV|CM_ABR }, /* Invisible abbrev for GET */
994 { "ge", XXGET, CM_INV|CM_ABR }, /* Ditto */
996 { "get", XXGET, 0 }, /* GET */
999 { "getc", XXGETC, 0 }, /* GETC */
1001 { "getkeycode", XXGETK, 0 }, /* GETKEYCODE */
1004 { "getok", XXGOK, 0 }, /* GETOK (ask for Yes/No/OK) */
1005 #endif /* NOFRILLS */
1008 { "goto", XXGOTO,0 }, /* GOTO label in take file or macro */
1011 { "grep", XXGREP,0 }, /* GREP (find) */
1013 { "grep", XXGREP,CM_INV }, /* GREP (find) */
1014 #endif /* UNIXOROSK */
1015 { "h", XXHLP, CM_INV|CM_ABR }, /* Invisible synonym for HELP */
1016 { "he", XXHLP, CM_INV|CM_ABR }, /* Invisible synonym for HELP */
1018 { "head", XXHEAD, 0 },
1019 #endif /* NOFRILLS */
1021 { "hangup", XXHAN, CM_LOC }, /* HANGUP the connection */
1022 #endif /* NOLOCAL */
1023 { "hdirectory", XXHDIR, CM_INV }, /* DIR sorted by size biggest first */
1024 { "HELP", XXHLP, 0 }, /* Display HELP text */
1027 { "http", XXHTTP, 0 }, /* HTTP operations */
1028 #endif /* TCPSOCKET */
1031 { "i", XXINP, CM_INV|CM_ABR }, /* Invisible synonym for INPUT */
1032 { "if", XXIF, 0 }, /* IF ( condition ) command */
1034 { "iksd", XXIKSD, CM_INV }, /* Make connection to IKSD */
1036 { "iksd", XXNOTAV, CM_INV },
1037 #endif /* TCPSOCKET */
1038 { "in", XXINP, CM_INV|CM_ABR }, /* Invisible synonym for INPUT */
1039 { "increment", XXINC, 0 }, /* Increment a numeric variable */
1040 { "input", XXINP, 0 }, /* INPUT text from comm device */
1044 { "int", XXINT, CM_INV|CM_ABR },
1045 { "intr", XXINT, CM_INV|CM_ABR },
1046 { "INTRO", XXINT, 0 },
1047 { "introduction",XXINT, CM_INV }, /* Print introductory text */
1049 { "intro", XXNOTAV, CM_INV },
1050 { "introduction",XXNOTAV, CM_INV },
1054 { "k95", XXKERMI, CM_INV }, /* Hmmm what's this... */
1058 { "kcd", XXKCD, 0 },
1061 { "kermit", XXKERMI, CM_INV },
1065 { "kverb", XXKVRB, CM_INV|CM_HLP }, /* Keyboard verb */
1066 #endif /* NOKVERBS */
1070 { "l", XXLOG, CM_INV|CM_ABR }, /* Invisible synonym for log */
1071 #endif /* NOFRILLS */
1073 { "lcd", XXLCWD, CM_INV },
1074 { "lcdup", XXLCDU, CM_INV },
1075 { "lcwd", XXLCWD, CM_INV },
1076 { "ldelete", XXLDEL, CM_INV },
1077 { "ldirectory", XXLDIR, CM_INV },
1080 { "learn", XXLEARN, 0 }, /* LEARN - automatic script writing */
1082 { "learn", XXNOTAV, CM_INV },
1083 #endif /* CKLEARN */
1085 { "li", XXLNOUT, CM_INV|CM_ABR },
1086 { "LICENSE", XXCPR, 0 }, /* LICENSE */
1089 { "lineout", XXLNOUT, 0 }, /* LINEOUT = OUTPUT + eol */
1093 { "link", XXLINK, 0 }, /* LINK source destination */
1096 { "lmkdir", XXLMKD, CM_INV },
1097 { "lmv", XXLREN, CM_INV },
1100 { "lo", XXLOG, CM_INV|CM_ABR }, /* Invisible synonym for log */
1101 #endif /* NOFRILLS */
1104 { "local", XXLOCAL, CM_INV }, /* LOCAL variable declaration */
1106 { "local", XXNOTAV, CM_INV },
1109 { "locus", XXLOCU, CM_INV|CM_HLP }, /* "help locus" */
1111 { "log", XXLOG, 0 }, /* Open a log file */
1113 { "login", XXLOGIN, 0 }, /* (REMOTE) LOGIN to server or IKSD */
1114 { "logout", XXLOGOUT, 0 }, /* LOGOUT from server or IKSD */
1118 { "lookup", XXLOOK, 0 }, /* LOOKUP */
1120 { "lookup", XXNOTAV, CM_INV },
1123 { "lpwd", XXLPWD, CM_INV },
1124 { "lrename", XXLREN, CM_INV },
1125 { "lrmdir", XXLRMD, CM_INV },
1128 { "ls", XXLS, CM_INV|CM_PSH }, /* UNIX ls command */
1130 { "ls", XXDIR, CM_INV }, /* Invisible synonym for DIR */
1131 #endif /* UNIXOROSK */
1133 { "mail", XXMAI, 0 }, /* Send a file as e-mail */
1136 { "manual", XXMAN, CM_PSH }, /* MAN(UAL) */
1138 { "manual", XXNOTAV, CM_INV|CM_PSH },
1140 #endif /* NOFRILLS */
1142 { "md", XXMKDIR, CM_INV }, /* Synonym for MKDIR */
1143 #endif /* CK_MKDIR */
1144 { "message", XXMSG, 0 }, /* Print debugging message */
1146 { "minput", XXMINP, 0 }, /* MINPUT */
1148 { "minput", XXNOTAV, CM_INV },
1149 #endif /* CK_MINPUT */
1151 { "mget", XXMGET, 0 }, /* MGET */
1153 { "mget", XXNOTAV, CM_INV },
1154 #endif /* NOMSEND */
1156 { "mkdir", XXMKDIR, 0 }, /* MKDIR */
1158 { "mkdir", XXNOTAV, CM_INV },
1159 #endif /* CK_MKDIR */
1163 { "mmove", XXMMOVE, 0 }, /* MMOVE */
1165 { "mmove", XXNOTAV, CM_INV },
1166 #endif /* NOMSEND */
1170 { "more", XXMORE, CM_INV }, /* MORE */
1171 #endif /* NOFRILLS */
1174 { "move", XXMOVE, 0 }, /* MOVE */
1178 { "mpause", XXMSL, CM_INV }, /* Millisecond sleep */
1180 { "mpause", XXNOTAV, CM_INV },
1185 { "mput", XXMSE, CM_INV }, /* MPUT = MSEND */
1186 { "ms", XXMSE, CM_INV|CM_ABR },
1187 { "msend", XXMSE, 0 }, /* Multiple SEND */
1189 { "mput", XXNOTAV, CM_INV },
1190 { "msend", XXNOTAV, CM_INV },
1191 #endif /* NOMSEND */
1193 { "msg", XXMSG, CM_INV }, /* Print debugging message */
1195 { "msleep", XXMSL, 0 }, /* Millisecond sleep */
1197 { "msleep", XXNOTAV, CM_INV },
1200 { "mv", XXREN, CM_INV }, /* Synonym for rename */
1201 #endif /* NOFRILLS */
1203 { "news", XXNEW, CM_INV }, /* Display NEWS of new features */
1205 { "news", XXNOTAV, CM_INV },
1207 { "nolocal", XXNLCL, CM_INV }, /* Disable SET LINE / SET HOST */
1208 { "nopush", XXNPSH, CM_INV }, /* Disable PUSH command/features */
1210 { "noscroll", XXNSCR, CM_INV }, /* Disable scroll operations */
1213 { "o", XXOUT, CM_INV|CM_ABR }, /* Invisible synonym for OUTPUT */
1214 { "open", XXOPE, 0 }, /* OPEN file for reading or writing */
1216 { "open", XXOPE, CM_INV }, /* OPEN */
1219 { "options", XXOPTS,CM_INV|CM_HLP }, /* Options */
1221 { "orientation", XXORIE, 0 },
1223 { "output", XXOUT, 0 }, /* OUTPUT text to comm device */
1225 { "output", XXNOTAV, CM_INV },
1229 { "pad", XXPAD, CM_LOC }, /* X.3 PAD commands */
1234 { "passive", XXPASV, CM_INV }, /* (FTP) PASSIVE */
1238 { "patterns", XXPAT,CM_INV|CM_HLP }, /* Pattern syntax */
1242 { "pause", XXPAU, 0 }, /* Sleep for specified interval */
1244 { "pause", XXNOTAV, CM_INV },
1247 { "pdial", XXPDIA, CM_LOC }, /* PDIAL (partial dial) */
1249 { "pdial", XXNOTAV, CM_INV|CM_LOC },
1253 { "ping", XXPNG, CM_INV|CM_PSH|CM_LOC }, /* PING */
1255 { "ping", XXNOTAV, CM_INV|CM_PSH|CM_LOC },
1257 #endif /* TCPSOCKET */
1260 { "pipe", XXPIPE, CM_PSH }, /* PIPE */
1262 { "pipe", XXNOTAV, CM_INV|CM_PSH }, /* PIPE */
1267 { "pop", XXEND, CM_INV }, /* Invisible synonym for END */
1270 { "print", XXPRI, 0 }, /* PRINT a file locally */
1271 #endif /* NOFRILLS */
1273 { "prompt", XXPROMP, CM_INV }, /* Go interactive (from script) */
1277 { "psend", XXPSEN, CM_INV }, /* PSEND */
1279 { "psend", XXNOTAV, CM_INV },
1280 #endif /* CK_RESEND */
1284 { "pty", XXPTY, CM_PSH }, /* PTY */
1286 { "pty", XXNOTAV, CM_INV|CM_PSH },
1290 { "pu", XXSHE, CM_INV|CM_ABR|CM_PSH }, /* PU = PUSH */
1294 { "purge", XXPURGE, 0 }, /* PURGE (real) */
1297 { "purge", XXPURGE, 0 }, /* PURGE (fake) */
1299 { "purge", XXNOTAV, CM_INV },
1301 #endif /* CKPURGE */
1304 { "push", XXSHE, CM_PSH }, /* PUSH command (like RUN, !) */
1306 { "push", XXNOTAV, CM_INV|CM_PSH },
1310 { "put", XXSEN, CM_INV }, /* PUT = SEND */
1315 { "putenv", XXPUTE, CM_INV }, /* PUTENV */
1316 #endif /* NOPUTENV */
1319 { "pwd", XXPWD, 0 }, /* Print Working Directory */
1320 { "q", XXQUI, CM_INV|CM_ABR }, /* Invisible synonym for QUIT */
1323 { "query", XXRQUE,CM_INV }, /* (= REMOTE QUERY) */
1326 { "quit", XXQUI, 0 }, /* QUIT from program = EXIT */
1329 { "r", XXREC, CM_INV|CM_ABR }, /* Inv synonym for RECEIVE */
1333 { "rasg", XXRASG, CM_INV }, /* REMOTE ASSIGN */
1334 { "rassign", XXRASG, CM_INV }, /* ditto */
1335 { "rcd", XXRCWD, CM_INV }, /* REMOTE CD */
1336 { "rcdup", XXRCDUP,CM_INV }, /* REMOTE CD */
1337 { "rcopy", XXRCPY, CM_INV }, /* REMOTE COPY */
1338 { "rcwd", XXRCWD, CM_INV }, /* REMOTE CWD */
1339 { "rdelete", XXRDEL, CM_INV }, /* REMOTE DELETE */
1340 { "rdirectory", XXRDIR, CM_INV }, /* REMODE DIRECTORY */
1344 { "read", XXREA, 0 }, /* READ a line from a file */
1346 { "read", XXNOTAV, CM_INV },
1350 { "receive", XXREC, 0 }, /* RECEIVE files */
1354 { "red", XXRED, CM_INV|CM_ABR|CM_LOC }, /* Inv syn for REDIAL */
1355 { "redi", XXRED, CM_INV|CM_ABR|CM_LOC }, /* ditto */
1356 { "redial", XXRED, CM_LOC }, /* REDIAL last DIAL number */
1358 { "red", XXNOTAV, CM_INV|CM_LOC },
1359 { "redi", XXNOTAV, CM_INV|CM_LOC },
1360 { "redial", XXNOTAV, CM_INV|CM_LOC },
1366 { "redirect", XXFUN, CM_INV|CM_PSH }, /* REDIRECT */
1368 { "redirect", XXNOTAV, CM_INV|CM_PSH },
1372 { "redirect", XXFUN, CM_PSH }, /* REDIRECT */
1374 { "redirect", XXNOTAV, CM_INV|CM_PSH },
1377 #endif /* CK_REDIR */
1380 { "redo", XXREDO, CM_NOR }, /* REDO */
1382 { "redo", XXNOTAV, CM_INV },
1383 #endif /* CK_RECALL */
1387 { "reget", XXREGET, 0 }, /* REGET */
1389 { "reget", XXNOTAV, CM_INV },
1390 #endif /* CK_RESEND */
1394 { "reinput", XXREI, CM_INV }, /* REINPUT (from INPUT buffer) */
1396 { "reinput", XXNOTAV, CM_INV },
1401 { "rem", XXREM, CM_INV|CM_ABR },
1402 { "remo", XXREM, CM_INV|CM_ABR },
1404 { "remote", XXREM, 0 }, /* Send REMOTE command to server */
1408 { "remove", XXREMV,0 }, /* REMOVE (something from a list) */
1410 { "remove", XXNOTAV, CM_INV },
1415 { "rename", XXREN, 0 }, /* RENAME a local file */
1417 { "rename", XXNOTAV, CM_INV },
1418 #endif /* NORENAME */
1419 { "replay", XXTYP, CM_INV }, /* REPLAY (for now, just type) */
1420 #endif /* NOFRILLS */
1424 { "rep", XXTYP, CM_INV|CM_ABR }, /* REPLAY abbreviation */
1425 { "reput", XXRSEN, CM_INV }, /* REPUT = RESEND */
1426 { "res", XXRSEN, CM_INV|CM_ABR }, /* RESEND */
1427 { "rese", XXRSEN, CM_INV|CM_ABR }, /* RESEND */
1428 { "resend", XXRSEN, 0 }, /* RESEND */
1430 { "reput", XXNOTAV, CM_INV },
1431 { "res", XXNOTAV, CM_INV },
1432 { "rese", XXNOTAV, CM_INV },
1433 { "resend", XXNOTAV, CM_INV },
1434 #endif /* CK_RESEND */
1437 { "reset", XXRESET, CM_INV }, /* RESET */
1441 { "ret", XXRET, CM_INV|CM_ABR },
1443 #endif /* CK_RESEND */
1446 { "retrieve", XXRETR, CM_INV }, /* RETRIEVE */
1450 { "return", XXRET, 0 }, /* RETURN from a function */
1452 { "return", XXNOTAV, CM_INV },
1456 { "rexit", XXRXIT, CM_INV }, /* REMOTE EXIT */
1461 { "rexx", XXREXX, CM_PSH }, /* Execute a Rexx command */
1463 { "rexx", XXNOTAV, CM_INV|CM_PSH },
1465 #endif /* CK_REXX */
1468 { "rhelp", XXRHLP, CM_INV }, /* REMOTE HELP */
1469 { "rhost", XXRHOS, CM_INV }, /* REMOTE HOST */
1470 { "rkermit", XXRKER, CM_INV }, /* REMOTE KERMIT */
1474 { "rlogin", XXRLOG, CM_LOC }, /* Make an Rlogin connection */
1476 { "rlogin", XXNOTAV, CM_INV|CM_LOC },
1477 #endif /* TCPSOCKET */
1480 { "rm", XXDEL, CM_INV }, /* Invisible synonym for delete */
1481 #endif /* NOFRILLS */
1484 { "rmdir", XXRMDIR, 0 }, /* RMDIR */
1486 { "rmdir", XXNOTAV, CM_INV },
1487 #endif /* CK_MKDIR */
1490 { "rmessage", XXRMSG, CM_INV }, /* REMOTE MESSAGE */
1491 { "rmkdir", XXRMKD, CM_INV }, /* REMOTE MKDIR */
1492 { "rmsg", XXRMSG, CM_INV }, /* REMOTE MESSAGE */
1494 { "robust", XXROB, CM_INV },
1496 { "robust", XXNOTAV, CM_INV },
1498 { "rprint", XXRPRI, CM_INV }, /* REMOTE PRINT */
1499 { "rpwd", XXRPWD, CM_INV }, /* REMOTE PWD */
1500 { "rquery", XXRQUE, CM_INV }, /* REMOTE QUERY */
1504 { "rr", XXREDO, CM_INV|CM_NOR },
1505 #endif /* CK_RECALL */
1508 { "rrename", XXRREN, CM_INV }, /* REMOTE RENAME */
1509 { "rrmdir", XXRRMD, CM_INV }, /* REMOTE REMDIR */
1510 { "rset", XXRSET, CM_INV }, /* REMOTE SET */
1511 { "rspace", XXRSPA, CM_INV }, /* REMOTE SPACE */
1512 { "rtype", XXRTYP, CM_INV }, /* REMOTE TYPE */
1516 { "run", XXSHE, CM_PSH }, /* RUN a program or command */
1518 { "run", XXNOTAV, CM_INV|CM_PSH },
1522 { "rwho", XXRWHO, CM_INV }, /* REMOTE WHO */
1523 { "s", XXSEN, CM_INV|CM_ABR }, /* Invisible synonym for send */
1528 { "save", XXSAVE, 0 }, /* SAVE something */
1530 { "save", XXSAVE, CM_INV },
1533 { "save", XXNOTAV, CM_INV },
1534 #endif /* NOSETKEY */
1537 { "sc", XXLOGI, CM_INV|CM_ABR|CM_LOC },
1538 { "scr", XXLOGI, CM_INV|CM_ABR|CM_LOC },
1539 #endif /* NOSCRIPT */
1540 { "screen", XXSCRN, 0 }, /* SCREEN actions */
1542 { "script", XXLOGI, CM_LOC }, /* Expect-Send-style script line */
1544 { "script", XXNOTAV, CM_INV|CM_LOC },
1545 #endif /* NOSCRIPT */
1547 { "search", XXGREP,CM_INV }, /* Synonym for GREP and FIND */
1550 { "send", XXSEN, 0 }, /* Send (a) file(s) */
1552 { "server", XXSER, 0 }, /* Be a SERVER */
1554 { "server", XXNOTAV, CM_INV },
1555 #endif /* NOSERVER */
1558 { "set", XXSET, 0 }, /* SET parameters */
1562 { "sexpression", XXSEXP, CM_INV|CM_HLP }, /* SEXPR */
1566 { "sftp", XXSFTP, 0 }, /* SFTP */
1567 #endif /* SFTP_BUILTIN */
1570 { "sh", XXSHO, CM_INV|CM_ABR }, /* SHOW parameters */
1572 { "shift", XXSHIFT, 0 }, /* SHIFT args */
1574 { "shift", XXNOTAV, CM_INV },
1578 { "show", XXSHO, 0 }, /* SHOW parameters */
1580 { "show", XXNOTAV, CM_INV },
1584 { "site", XXSITE, CM_INV }, /* (FTP) SITE */
1588 { "skermit", XXSKRM, 0 }, /* SKERMIT */
1589 #endif /* SSHBUILTIN */
1593 { "sleep", XXPAU, CM_INV }, /* SLEEP for specified interval */
1594 #endif /* NOFRILLS */
1598 { "sort", XXSORT, CM_INV }, /* (see ARRAY) */
1600 { "sort", XXNOTAV, CM_INV },
1605 { "sp", XXSPA, CM_INV|CM_ABR },
1606 { "spa", XXSPA, CM_INV|CM_ABR },
1607 #endif /* NOFRILLS */
1608 { "space", XXSPA, 0 }, /* Show available disk SPACE */
1613 { "spawn", XXSHE, CM_INV|CM_PSH }, /* Synonym for PUSH, RUN */
1615 { "spawn", XXNOTAV, CM_INV|CM_PSH }, /* Synonym for PUSH, RUN */
1617 #endif /* NOFRILLS */
1620 { "ssh", XXSSH, 0 },
1624 { "sta", XXSTA, CM_INV|CM_ABR },
1625 { "stat", XXSTA, CM_INV|CM_ABR },
1626 { "statistics", XXSTA, 0 }, /* Display file transfer stats */
1629 { "status", XXSTATUS,0 }, /* Show status of previous command */
1632 { "stop", XXSTO, 0 }, /* STOP all take files and macros */
1633 { "succeed", XXSUCC, CM_INV }, /* SUCCEED */
1635 { "stop", XXNOTAV, CM_INV },
1636 { "succeed", XXNOTAV, CM_INV },
1640 { "SUPPORT", XXBUG, 0 }, /* Tech support instructions */
1642 { "support", XXNOTAV, CM_INV },
1643 #endif /* NOFRILLS */
1646 { "suspend", XXSUS, CM_PSH }, /* SUSPEND C-Kermit (UNIX only) */
1648 { "suspend", XXNOTAV, CM_INV|CM_PSH },
1652 { "switch", XXSWIT, 0 }, /* SWITCH */
1654 { "switch", XXNOTAV, CM_INV },
1658 { "ta", XXTAK, CM_INV|CM_ABR }, /* (because of TAPI) */
1659 #endif /* CK_TAPI */
1662 { "tail", XXTAIL, 0 }, /* Display end of a local file */
1663 #endif /* NOFRILLS */
1665 { "take", XXTAK, 0 }, /* TAKE commands from a file */
1668 { "tapi", XXTAPI, CM_LOC }, /* Microsoft TAPI commands */
1670 { "tapi", XXNOTAV, CM_INV|CM_LOC },
1671 #endif /* CK_TAPI */
1675 { "tel", XXTEL, CM_INV|CM_ABR|CM_LOC },
1676 { "telnet", XXTEL, CM_LOC }, /* TELNET (TCP/IP only) */
1677 { "telopt", XXTELOP, CM_INV }, /* TELOPT (ditto) */
1679 { "tel", XXNOTAV, CM_INV|CM_LOC },
1680 { "telnet", XXNOTAV, CM_INV|CM_LOC },
1681 { "telopt", XXNOTAV, CM_INV },
1682 #endif /* TCPSOCKET */
1684 { "terminal", XXTERM, CM_INV|CM_LOC }, /* == SET TERMINAL TYPE */
1686 { "terminal", XXTERM, CM_INV },
1688 #endif /* NOFRILLS */
1690 { "text", XXASC, CM_INV }, /* == SET FILE TYPE TEXT */
1692 { "touch", XXTOUC, 0 }, /* TOUCH */
1694 { "trace", XXTRACE, 0 }, /* TRACE */
1696 { "trace", XXNOTAV, CM_INV },
1700 { "translate", XXXLA, 0 }, /* TRANSLATE local file char sets */
1702 { "translate", XXNOTAV, CM_INV },
1703 #endif /* NOCSETS */
1706 { "transmit", XXTRA, 0 }, /* Send (upload) a file, no protocol */
1708 { "transmit", XXNOTAV, CM_INV },
1712 { "type", XXTYP, 0 }, /* Display a local file */
1713 #endif /* NOFRILLS */
1716 { "undcl", XXUNDCL, CM_INV },
1717 { "undeclare", XXUNDCL, 0 }, /* UNDECLARE an array */
1718 { "undefine", XXUNDEF, 0 }, /* UNDEFINE a variable or macro */
1720 { "undcl", XXNOTAV, CM_INV },
1721 { "undeclare", XXNOTAV, CM_INV },
1722 { "undefine", XXNOTAV, CM_INV },
1726 { "user", XXUSER, CM_INV }, /* (FTP) USER */
1729 { "version", XXVER, 0 }, /* VERSION-number display */
1732 { "viewonly", XXVIEW, CM_LOC }, /* VIEWONLY Terminal Mode */
1735 { "void", XXVOID, 0 }, /* VOID */
1738 { "wait", XXWAI, 0 }, /* WAIT */
1740 { "wait", XXNOTAV, CM_INV },
1743 { "wdirectory", XXWDIR, CM_INV }, /* Like TOPS-20, reverse chron order */
1744 { "wermit", XXKERMI, CM_INV },
1747 { "where", XXWHERE, 0 }, /* WHERE (did my file go?) */
1751 { "while", XXWHI, 0 }, /* WHILE loop */
1753 { "while", XXNOTAV, CM_INV },
1759 { "who", XXWHO, CM_PSH }, /* WHO's logged in? */
1760 #endif /* NOFRILLS */
1765 { "wildcards", XXWILD,CM_INV|CM_HLP }, /* Wildcard syntax */
1769 { "wr", XXWRI, CM_INV|CM_ABR },
1770 { "wri", XXWRI, CM_INV|CM_ABR },
1771 { "writ", XXWRI, CM_INV|CM_ABR },
1772 { "write", XXWRI, 0 }, /* WRITE characters to a file */
1773 { "write-line", XXWRL, CM_INV }, /* WRITE a line to a file */
1774 { "writeln", XXWRL, CM_INV }, /* Pascalisch synonym for write-line */
1776 { "wr", XXNOTAV, CM_INV },
1777 { "wri", XXNOTAV, CM_INV },
1778 { "writ", XXNOTAV, CM_INV },
1779 { "write", XXNOTAV, CM_INV },
1780 { "write-line", XXNOTAV, CM_INV },
1781 { "writeln", XXNOTAV, CM_INV },
1785 { "xecho", XXXECH,0 }, /* XECHO */
1786 #endif /* NOFRILLS */
1789 { "xif", XXIFX, CM_INV }, /* Extended IF command (obsolete) */
1791 { "xif", XXNOTAV, CM_INV },
1795 { "xlate", XXXLA, CM_INV }, /* Synonym for TRANSLATE */
1797 { "xlate", XXNOTAV, CM_INV },
1798 #endif /* NOCSETS */
1801 { "xm", XXTRA, CM_INV|CM_ABR }, /* Avoid conflict with XMESSAGE */
1803 { "xm", XXNOTAV, CM_INV|CM_ABR }, /* Synonym for TRANSMIT */
1806 { "xmessage", XXXMSG, 0 }, /* Print debugging message */
1809 { "xmit", XXTRA, CM_INV }, /* Synonym for TRANSMIT */
1811 { "xmit", XXNOTAV, CM_INV },
1816 { "z", XXSUS, CM_INV|CM_PSH }, /* Synonym for SUSPEND */
1818 { "z", XXNOTAV, CM_INV|CM_PSH },
1823 { "{", XXMACRO, CM_INV }, /* Immediate macro */
1827 int ncmd = (sizeof(cmdtab) / sizeof(struct keytab)) - 1;
1829 /* NOTE: Tokens must also be entered above into cmdtab[]. */
1833 '!', /* Shell escape */
1837 '(', /* S-Expression */
1838 '.', /* Assignment */
1847 #endif /* CK_REDIR */
1848 '@', /* DCL escape */
1851 '^', /* Command recall */
1852 #endif /* CK_RECALL */
1854 '{', /* Immediate macro */
1856 '\0' /* End of this string */
1858 int xxdot = 0; /* Used with "." token */
1860 struct keytab yesno[] = { /* Yes/No keyword table */
1865 int nyesno = (sizeof(yesno) / sizeof(struct keytab));
1867 /* Save keyword table */
1869 struct keytab savtab[] = {
1871 { "command", XSCMD, 0 },
1874 { "command", XSCMD, 0 },
1875 #endif /* CK_RECALL */
1878 { "keymap", XSKEY, 0 },
1879 #endif /* NOSETKEY */
1881 { "terminal", XSTERM, 0 },
1885 int nsav = (sizeof(savtab) / sizeof(struct keytab)) - 1;
1887 /* Parameter keyword table */
1889 struct keytab prmtab[] = {
1890 { "alarm", XYALRM, 0 },
1891 #ifdef COMMENT /* SET ANSWER not implemented yet */
1893 { "answer", XYANSWER,0 },
1895 #endif /* COMMENT */
1896 { "ask-timer", XYTIMER, 0 },
1898 { "attributes", XYATTR, 0 },
1900 #ifdef CK_AUTHENTICATION
1901 { "authentication", XYAUTH, 0 },
1902 #else /* CK_AUTHENTICATION */
1904 { "authentication", XYAUTH, 0 },
1906 #endif /* CK_AUTHENTICATION */
1907 { "b", XYBACK, CM_INV|CM_ABR|CM_PSH },
1908 { "ba", XYBACK, CM_INV|CM_ABR|CM_PSH },
1910 { "background", XYBACK, CM_INV|CM_PSH },
1911 { "batch", XYBACK, CM_PSH },
1913 { "background", XYBACK, CM_PSH },
1914 { "batch", XYBACK, CM_INV|CM_PSH },
1917 { "baud", XYSPEE, CM_INV|CM_LOC },
1918 #endif /* NOLOCAL */
1919 { "bell", XYBELL, 0 },
1921 { "block-check", XYCHKT, 0 },
1925 { "bprinter", XYBDCP, CM_INV },
1929 { "browser", XYBROWSE,CM_PSH|CM_LOC },
1930 #endif /* BROWSER */
1933 { "buffers", XYBUF, 0 },
1934 #endif /* DYNAMIC */
1938 { "carrier-watch", XYCARR, CM_LOC },
1940 #endif /* NOLOCAL */
1942 { "case", XYCASE, 0 },
1946 { "cl", XYCLEAR, CM_INV|CM_ABR },
1947 { "cle", XYCLEAR, CM_INV|CM_ABR },
1948 { "clea", XYCLEAR, CM_INV|CM_ABR },
1949 { "clear", XYCLEAR, CM_INV|CM_ABR },
1950 { "clear-channel", XYCLEAR, 0 },
1951 { "clearchannel", XYCLEAR, CM_INV },
1954 { "close-on-disconnect", XYDISC, CM_INV|CM_LOC },
1955 #endif /* NOLOCAL */
1956 { "cmd", XYCMD, CM_INV },
1957 { "command", XYCMD, 0 },
1959 { "con", XYQCTL, CM_INV|CM_ABR },
1960 #endif /* CK_SPEED */
1961 { "console", XYCMD, CM_INV },
1963 { "control-character",XYQCTL, 0 },
1964 #endif /* CK_SPEED */
1966 { "count", XYCOUN, 0 },
1969 { "d", XYDELA, CM_INV|CM_ABR },
1970 { "de", XYDELA, CM_INV|CM_ABR },
1972 { "debug", XYDEBU, 0 },
1974 { "default", XYDFLT, 0 },
1977 { "default", XYDFLT, CM_INV },
1981 { "delay", XYDELA, 0 },
1982 { "destination", XYDEST, 0 },
1985 { "di", XYDIAL, CM_INV|CM_ABR|CM_LOC },
1986 { "dia", XYDIAL, CM_INV|CM_ABR|CM_LOC },
1987 { "dial", XYDIAL, CM_LOC },
1990 { "dialer", XYDLR, CM_INV },
1993 { "disconnect", XYDISC, CM_LOC },
1994 { "duplex", XYDUPL, CM_LOC },
1995 #endif /* NOLOCAL */
1998 { "editor", XYEDIT, CM_PSH },
1999 #endif /* NOFRILLS */
2002 { "eof", XYEOF, CM_INV },
2003 #endif /* CK_CTRLZ */
2005 { "escape-character", XYESC, CM_LOC },
2006 #endif /* NOLOCAL */
2008 { "evaluate", XYEVAL, CM_INV },
2010 { "exit", XYEXIT, 0 },
2014 #ifndef XYZ_INTERNAL
2015 { "external-protocol",XYEXTRN, 0 },
2016 #endif /* XYZ_INTERNAL */
2019 { "f-ack-bug", XYFACKB, CM_INV },
2020 { "f-ack-path", XYFACKP, CM_INV },
2022 { "file", XYFILE, 0 },
2023 { "fl", XYFLOW, CM_INV|CM_ABR },
2025 { "flag", XYFLAG, 0 },
2030 { "ft", XYFTPX, CM_INV|CM_ABR },
2031 { "ftp", XYFTPX, 0 },
2034 #endif /* TCPSOCKET */
2036 { "ftp-client", XYFTP, CM_PSH },
2037 #endif /* BROWSER */
2038 { "flow-control", XYFLOW, 0 },
2040 { "function", XYFUNC, 0 },
2043 { "get-put-remote", XYGPR, 0 },
2046 { "gui", XYGUI, 0 },
2048 { "handshake", XYHAND, 0 },
2049 { "hints", XYHINTS, 0 },
2051 { "host", XYHOST, CM_LOC },
2052 #endif /* NETCONN */
2054 { "i", XYINPU, CM_INV|CM_ABR },
2057 { "iks", XYIKS, 0 },
2059 { "iks", XYIKS, CM_INV },
2062 { "in", XYINPU, CM_INV|CM_ABR },
2065 { "incomplete", XYIFD, CM_INV },
2068 { "input", XYINPU, 0 },
2071 { "key", XYKEY, 0 },
2072 #endif /* NOSETKEY */
2073 { "l", XYLINE, CM_INV|CM_ABR },
2075 { "language", XYLANG, 0 },
2076 #endif /* NOCSETS */
2078 { "line", XYLINE, CM_LOC },
2079 { "local-echo", XYLCLE, CM_INV|CM_LOC },
2080 #endif /* NOLOCAL */
2082 { "locus", XYLOCUS, 0 },
2085 { "login", XYLOGIN, CM_LOC },
2088 { "macro", XYMACR, 0 },
2090 { "match", XYMATCH, 0 },
2093 { "messages", XYMSGS, 0 },
2095 #endif /* COMMENT */
2097 { "modem", XYMODM, CM_LOC },
2101 { "mouse", XYMOUSE, 0 },
2102 #endif /* OS2MOUSE */
2103 #endif /* NOLOCAL */
2105 { "mskermit", XYMSK, 0 },
2108 { "network", XYNET, CM_LOC },
2109 #endif /* NETCONN */
2111 { "output", XYOUTP, 0 },
2113 { "options", XYOPTS, 0 },
2114 { "pause", XYSLEEP, CM_INV },
2117 { "pad", XYPAD, CM_LOC },
2120 { "parity", XYPARI, 0 },
2123 { "port", XYLINE, CM_LOC },
2125 { "port", XYLINE, CM_INV|CM_LOC },
2127 #endif /* NOLOCAL */
2129 { "pr", XYPROM, CM_INV|CM_ABR },
2130 { "printer", XYPRTR, 0 },
2131 #endif /* NOFRILLS */
2133 { "priority", XYPRTY, 0 },
2136 { "prefixing", XYPREFIX, 0 },
2137 #endif /* CK_SPEED */
2139 { "prompt", XYPROM, 0 },
2140 #endif /* NOFRILLS */
2142 { "protocol", XYPROTO, 0 },
2144 { "q", XYQUIE, CM_INV|CM_ABR },
2146 { "q8flag", XYQ8FLG, CM_INV },
2149 { "qnx-port-lock", XYQNXPL, 0 },
2151 { "qnx-port-lock", XYQNXPL, CM_INV },
2153 { "quiet", XYQUIE, 0 },
2155 { "rec", XYRECV, CM_INV|CM_ABR },
2156 { "receive", XYRECV, 0 },
2157 { "recv", XYRECV, CM_INV },
2159 { "reliable", XYRELY, 0 },
2160 { "rename", XY_REN, 0 },
2162 { "repeat", XYREPT, 0 },
2163 { "retry-limit", XYRETR, 0 },
2166 { "root", XYROOT, 0 },
2169 { "script", XYSCRI, CM_LOC },
2170 #endif /* NOSCRIPT */
2172 { "send", XYSEND, 0 },
2175 { "ser", XYSERV, CM_INV|CM_ABR },
2176 #endif /* NOSERVER */
2178 { "serial", XYSERIAL,CM_LOC },
2179 #endif /* NOLOCAL */
2181 { "server", XYSERV, 0 },
2182 #endif /* NOSERVER */
2185 { "session-l", XYSESS, CM_INV|CM_ABR },
2186 #endif /* NOLOCAL */
2187 { "session-limit", XYLIMIT, CM_INV|CM_LOC }, /* Session Limit */
2188 #endif /* SESLIMIT */
2191 { "session-log", XYSESS, CM_LOC },
2192 #endif /* NOLOCAL */
2196 { "sexpression", XYSEXP, CM_INV },
2200 { "sleep", XYSLEEP, 0 },
2203 { "speed", XYSPEE, CM_LOC },
2204 #endif /* NOLOCAL */
2207 { "ssh", XYSSH, 0 },
2211 { "startup-file", XYSTARTUP, CM_INV },
2216 { "stop-bits", XYSTOP, CM_LOC },
2219 { "stop-bits", XYSTOP, CM_LOC },
2220 #endif /* TN_COMPORT */
2221 #endif /* HWPARITY */
2222 #endif /* NOLOCAL */
2226 { "streaming", XYSTREAM, 0 },
2227 #endif /* STREAMING */
2231 { "suspend", XYSUSP, CM_PSH },
2234 { "syslog", XYSYSL, CM_INV },
2235 #endif /* CKSYSLOG */
2236 { "take", XYTAKE, 0 },
2239 { "tapi", XYTAPI, CM_LOC },
2240 #endif /* CK_TAPI */
2244 { "tcp", XYTCP, CM_LOC },
2245 #endif /* TCPSOCKET */
2246 #endif /* NOTCPOPTS */
2249 { "tel", XYTEL, CM_INV|CM_ABR },
2250 { "telnet", XYTEL, 0 },
2251 { "telopt", XYTELOP, 0 },
2255 { "temp-directory", XYTMPDIR,0 },
2259 { "terminal", XYTERM, CM_LOC },
2260 #endif /* NOLOCAL */
2263 { "title", XYTITLE, CM_LOC },
2266 { "transaction-log", XYTLOG, 0 },
2269 { "transfer", XYXFER, 0 },
2272 { "transmit", XYXMIT, 0 },
2276 { "unknown-char-set", XYUNCS, 0 },
2277 #endif /* NOCSETS */
2279 { "variable-evaluation", XYVAREV, CM_INV },
2282 { "wait", XYSLEEP, CM_INV },
2285 { "wildcard-expansion", XYWILD, 0 },
2289 { "w", XYWIND, CM_INV|CM_ABR },
2290 { "wi", XYWIND, CM_INV|CM_ABR },
2291 { "win", XYWIND, CM_INV|CM_ABR },
2293 { "window-size", XYWIND, 0 },
2295 { "win95", XYWIN95, 0 },
2298 { "x.25", XYX25, CM_LOC },
2299 { "x25", XYX25, CM_INV|CM_LOC },
2301 { "xfer", XYXFER, CM_INV },
2303 { "xmit", XYXMIT, CM_INV },
2307 int nprm = (sizeof(prmtab) / sizeof(struct keytab)) - 1; /* How many */
2309 struct keytab scntab[] = { /* Screen commands */
2310 { "clear", SCN_CLR, 0 },
2311 { "cleol", SCN_CLE, 0 },
2312 { "move-to", SCN_MOV, 0 }
2314 int nscntab = (sizeof(scntab) / sizeof(struct keytab)); /* How many */
2316 #ifdef ANYSSH /* SSH command table */
2318 int ssh_pf_lcl_n = 0,
2320 struct ssh_pf ssh_pf_lcl[32] = { 0, NULL, 0 }; /* SSH Port Forwarding */
2321 struct ssh_pf ssh_pf_rmt[32] = { 0, NULL, 0 }; /* structs... */
2322 extern char * ssh_hst, * ssh_cmd, * ssh_prt;
2323 extern int ssh_ver, ssh_xfw;
2324 char * ssh_tmpuid = NULL, *ssh_tmpcmd = NULL, *ssh_tmpport = NULL,
2325 * ssh_tmpstr = NULL;
2328 sshk_type = SSHKT_2D, /* SSH KEY CREATE /TYPE:x */
2329 sshk_bits = 1024, /* SSH KEY CREATE /BITS:n */
2330 sshk_din = SKDF_OSSH, /* SSH KEY DISPLAY /IN-FORMAT: */
2331 sshk_dout = SKDF_OSSH; /* SSH KEY DISPLAY /OUT-FORMAT: */
2334 * sshk1_comment = NULL, /* SSH V1 COMMENT */
2335 * sshkp_old = NULL, /* Old key passphrase */
2336 * sshkp_new = NULL, /* New key passphrase */
2337 * sshkc_pass = NULL, /* KEY CREATE /PASS:xxx */
2338 * sshkc_comm = NULL, /* KEY CREATE /V1-RSA-COMMENT:xxx */
2339 * sshd_file = NULL, /* DISPLAY file */
2340 * sshk_file = NULL; /* SSH CREATE KEY file */
2342 static struct keytab sshclr[] = {
2343 { "local-port-forward", SSHC_LPF, 0 },
2344 { "remote-port-forward", SSHC_RPF, 0 },
2347 static int nsshclr = (sizeof(sshclr) / sizeof(struct keytab)) - 1;
2349 struct keytab sshopnsw[] = {
2350 { "/command", SSHSW_CMD, CM_ARG },
2351 { "/password", SSHSW_PWD, CM_ARG },
2352 { "/subsystem", SSHSW_SUB, CM_ARG },
2353 { "/user", SSHSW_USR, CM_ARG },
2354 { "/version", SSHSW_VER, CM_ARG },
2355 { "/x11-forwarding", SSHSW_X11, CM_ARG },
2358 int nsshopnsw = (sizeof(sshopnsw) / sizeof(struct keytab)) - 1;
2360 static struct keytab sshkwtab[] = {
2361 { "add", XSSH_ADD, 0 },
2362 { "agent", XSSH_AGT, 0 },
2363 { "clear", XSSH_CLR, 0 },
2364 { "forward-local-port", XSSH_FLP, CM_INV },
2365 { "forward-remote-port", XSSH_FRP, CM_INV },
2366 { "key", XSSH_KEY, 0 },
2367 { "open", XSSH_OPN, 0 },
2368 { "v2", XSSH_V2, 0 },
2371 static int nsshcmd = (sizeof(sshkwtab) / sizeof(struct keytab)) - 1;
2373 static struct keytab ssh2tab[] = {
2374 { "rekey", XSSH2_RKE, 0 },
2377 static int nssh2tab = (sizeof(ssh2tab) / sizeof(struct keytab));
2379 static struct keytab addfwd[] = { /* SET SSH ADD command table */
2380 { "local-port-forward", SSHF_LCL, 0 },
2381 { "remote-port-forward", SSHF_RMT, 0 },
2384 static int naddfwd = (sizeof(addfwd) / sizeof(struct keytab)) - 1;
2386 static struct keytab sshagent[] = { /* SET SSH AGENT command table */
2387 { "add", SSHA_ADD, 0 },
2388 { "delete", SSHA_DEL, 0 },
2389 { "list", SSHA_LST, 0 },
2392 static int nsshagent = (sizeof(sshagent) / sizeof(struct keytab)) - 1;
2394 static struct keytab sshagtsw[] = { /* SET SSH AGENT LIST switch table */
2395 { "/fingerprint", SSHASW_FP, 0 },
2398 static int nsshagtsw = (sizeof(sshagtsw) / sizeof(struct keytab)) - 1;
2400 static struct keytab sshkey[] = { /* SET SSH KEY command table */
2401 { "change-passphrase", SSHK_PASS, 0 },
2402 { "create", SSHK_CREA, 0 },
2403 { "display", SSHK_DISP, 0 },
2404 { "v1", SSHK_V1, 0 },
2407 static int nsshkey = (sizeof(sshkey) / sizeof(struct keytab)) - 1;
2409 static struct keytab sshkv1[] = { /* SET SSH KEY V1 command table */
2410 { "set-comment", 1, 0 }
2413 static struct keytab sshkpsw[] = { /* SET SSH KEY PASSPHRASE table */
2414 { "/new-passphrase", 2, CM_ARG },
2415 { "/old-passphrase", 1, CM_ARG }
2418 static struct keytab sshkcrea[] = { /* SSH KEY CREATE table */
2419 { "/bits", SSHKC_BI, CM_ARG },
2420 { "/passphrase", SSHKC_PP, CM_ARG },
2421 { "/type", SSHKC_TY, CM_ARG },
2422 { "/v1-rsa-comment", SSHKC_1R, CM_ARG }
2424 static int nsshkcrea = (sizeof(sshkcrea) / sizeof(struct keytab));
2426 static struct keytab sshkcty[] = { /* SSH KEY CREATE /TYPE:xxx */
2427 { "srp", SSHKT_SRP, 0 },
2428 { "v1-rsa", SSHKT_1R, 0 },
2429 { "v2-dsa", SSHKT_2D, 0 },
2430 { "v2-rsa", SSHKT_2R, 0 }
2432 static int nsshkcty = (sizeof(sshkcty) / sizeof(struct keytab));
2434 static struct keytab sshdswi[] = { /* SET SSH KEY DISPLAY /switches */
2435 { "/format", SSHKD_OUT, CM_ARG }
2437 static int nsshdswi = (sizeof(sshdswi) / sizeof(struct keytab));
2440 static struct keytab sshdifmt[] = { /* SSH KEY DISPLAY /IN-FORMAT: */
2441 { "openssh", SKDF_OSSH, 0 },
2442 { "ssh.com", SKDF_SSHC, 0 }
2444 static int nsshdifmt = (sizeof(sshdifmt) / sizeof(struct keytab));
2445 #endif /* COMMENT */
2447 static struct keytab sshdofmt[] = { /* SSH KEY DISPLAY /IN-FORMAT: */
2448 { "fingerprint", SKDF_FING, 0 },
2449 { "ietf", SKDF_IETF, 0 },
2450 { "openssh", SKDF_OSSH, 0 },
2451 { "ssh.com", SKDF_SSHC, 0 }
2453 static int nsshdofmt = (sizeof(sshdofmt) / sizeof(struct keytab));
2455 static struct keytab sshkermit[] = { /* SKERMIT */
2456 { "open", SKRM_OPN, 0 }
2458 static int nsshkermit = (sizeof(sshkermit) / sizeof(struct keytab));
2460 struct keytab sshkrmopnsw[] = {
2461 { "/password", SSHSW_PWD, CM_ARG },
2462 { "/user", SSHSW_USR, CM_ARG },
2463 { "/version", SSHSW_VER, CM_ARG },
2466 int nsshkrmopnsw = (sizeof(sshkrmopnsw) / sizeof(struct keytab)) - 1;
2467 #endif /* SSHBUILTIN */
2470 static struct keytab sftpkwtab[] = { /* SFTP */
2471 { "cd", SFTP_CD, 0 },
2472 { "chgrp", SFTP_CHGRP, 0 },
2473 { "chmod", SFTP_CHMOD, 0 },
2474 { "chown", SFTP_CHOWN, 0 },
2475 { "delete", SFTP_RM, 0 },
2476 { "dir", SFTP_DIR, 0 },
2477 { "get", SFTP_GET, 0 },
2478 { "mkdir", SFTP_MKDIR, 0 },
2479 { "open", SFTP_OPN, 0 },
2480 { "put", SFTP_PUT, 0 },
2481 { "pwd", SFTP_PWD, 0 },
2482 { "rename", SFTP_REN, 0 },
2483 { "rm", SFTP_RM, CM_INV },
2484 { "rmdir", SFTP_RMDIR, 0 },
2485 { "symlink", SFTP_LINK, 0 },
2486 { "version", SFTP_VER, 0 }
2488 static int nsftpkwtab = (sizeof(sftpkwtab) / sizeof(struct keytab));
2489 #endif /* SFTP_BUILTIN */
2493 struct keytab netkey[] = { /* SET NETWORK table */
2494 { "directory", XYNET_D, 0 },
2495 { "type", XYNET_T, 0 }
2497 int nnetkey = (sizeof(netkey) / sizeof(struct keytab));
2499 struct keytab netcmd[] = {
2501 These are the network types.
2504 { "command", NET_CMD, CM_INV }, /* Command */
2507 #ifdef DECNET /* DECnet / PATHWORKS */
2508 { "decnet", NET_DEC, 0 },
2512 { "dll", NET_DLL, CM_INV }, /* DLL to be loaded */
2516 { "file", NET_FILE, CM_INV }, /* FILE (real crude) */
2517 #endif /* NETFILE */
2519 #ifdef NPIPE /* Named Pipes */
2520 { "named-pipe", NET_PIPE, 0 },
2524 { "netbios", NET_BIOS, 0 }, /* NETBIOS */
2525 #endif /* CK_NETBIOS */
2527 #ifdef DECNET /* DECnet / PATHWORKS (alias) */
2528 { "pathworks", NET_DEC, CM_INV },
2532 { "pipe", NET_CMD, 0 }, /* Pipe */
2536 { "pseudoterminal",NET_PTY, 0 }, /* Pseudoterminal */
2540 { "pty", NET_PTY, CM_INV }, /* Inv syn for pseudoterm */
2544 { "ssh", NET_SSH, 0 },
2545 #endif /* SSHBUILTIN */
2548 { "superlat", NET_SLAT, 0 }, /* Meridian Technologies' SuperLAT */
2549 #endif /* SUPERLAT */
2551 #ifdef TCPSOCKET /* TCP/IP sockets library */
2552 { "tcp/ip", NET_TCPB, 0 },
2553 #endif /* TCPSOCKET */
2555 { "tes32", NET_SLAT, 0 }, /* Emulux TES32 */
2556 #endif /* SUPERLAT */
2557 #ifdef ANYX25 /* X.25 */
2559 { "x", NET_SX25, CM_INV|CM_ABR },
2560 { "x.25", NET_SX25, 0 },
2561 { "x25", NET_SX25, CM_INV },
2564 { "x", NET_VX25, CM_INV|CM_ABR },
2565 { "x.25", NET_VX25, 0 },
2566 { "x25", NET_VX25, CM_INV },
2567 #endif /* STRATUSX25 */
2570 { "x", NET_IX25, CM_INV|CM_ABR },
2571 { "x.25", NET_IX25, CM_INV },
2572 { "x25", NET_IX25, CM_INV },
2575 { "x", NET_IX25, CM_INV|CM_ABR },
2576 { "x.25", NET_IX25, 0 },
2577 { "x25", NET_IX25, CM_INV },
2582 int nnets = (sizeof(netcmd) / sizeof(struct keytab));
2589 struct keytab tcpopt[] = {
2590 { "address", XYTCP_ADDRESS, 0 },
2592 { "dns-service-records", XYTCP_DNS_SRV, 0 },
2593 #endif /* CK_DNS_SRV */
2595 { "dontroute", XYTCP_DONTROUTE, 0 },
2596 #endif /* SO_DONTROUTE */
2598 { "http-proxy", XYTCP_HTTP_PROXY, 0 },
2601 { "keepalive", XYTCP_KEEPALIVE, 0 },
2602 #endif /* SO_KEEPALIVE */
2604 { "linger", XYTCP_LINGER, 0 },
2605 #endif /* SO_LINGER */
2607 { "nagle", XYTCP_NAGLE, CM_INV },
2608 { "nodelay", XYTCP_NODELAY, 0 },
2609 #endif /* TCP_NODELAY */
2610 { "reverse-dns-lookup", XYTCP_RDNS, 0 },
2612 { "recvbuf", XYTCP_RECVBUF, 0 },
2613 #endif /* SO_RCVBUF */
2615 { "sendbuf", XYTCP_SENDBUF, 0 },
2616 #endif /* SO_SNDBUF */
2619 { "socks-server", XYTCP_SOCKS_SVR, 0 },
2620 #endif /* CK_SOCKS */
2624 { "ucx-port-bug", XYTCP_UCX, 0 },
2625 #endif /* DEC_TCPIP */
2629 int ntcpopt = (sizeof(tcpopt) / sizeof(struct keytab));
2630 #endif /* TCPSOCKET */
2631 #endif /* NOTCPOPTS */
2632 #endif /* NETCONN */
2635 /* K95 Manual Chapter Table -- Keep these two tables in sync! */
2637 static char * linktbl[] = { /* Internal links in k95.htm */
2640 "#install", /* 02 */
2643 "#entries", /* 05 */
2644 "#command", /* 06 */
2645 "#terminal", /* 07 */
2646 "#transfer", /* 08 */
2647 "#hostmode" /* 09 */
2650 static struct keytab chaptbl[] = {
2651 { "Command-Screen", 6, 0 },
2652 { "Contents", 0, 0 },
2653 { "Dialer-Entries", 5, 0 },
2654 { "File-Transfer", 8, 0 },
2655 { "Getting-Started", 3, 0 },
2656 { "Host-Mode", 9, 0 },
2657 { "Installation", 2, 0 },
2658 { "Terminal-Emulation", 7, 0 },
2659 { "Using-The-Dialer", 4, 0 },
2660 { "What-Is-K95", 1, 0 },
2663 static int nchaptbl = (sizeof(chaptbl) / sizeof(struct keytab) - 1);
2667 /* Remote Command Table */
2669 struct keytab remcmd[] = {
2671 { "as", XZASG, CM_INV|CM_ABR },
2672 { "asg", XZASG, CM_INV },
2673 { "assign", XZASG, 0 },
2676 { "cdup", XZCDU, CM_INV },
2677 { "copy", XZCPY, 0 },
2678 { "cwd", XZCWD, CM_INV },
2679 { "delete", XZDEL, 0 },
2680 { "directory", XZDIR, 0 },
2681 { "e", XZXIT, CM_ABR|CM_INV },
2682 { "erase", XZDEL, CM_INV },
2683 { "exit", XZXIT, 0 },
2684 { "help", XZHLP, 0 },
2686 { "host", XZHOS, 0 },
2689 { "kermit", XZKER, 0 },
2690 { "l", XZLGI, CM_ABR|CM_INV },
2691 { "lo", XZLGI, CM_ABR|CM_INV },
2692 { "log", XZLGI, CM_ABR|CM_INV },
2693 { "login", XZLGI, 0 },
2694 { "logout", XZLGO, 0 },
2695 { "message", XZMSG, 0 },
2696 { "mkdir", XZMKD, 0 },
2697 { "print", XZPRI, 0 },
2698 #endif /* NOFRILLS */
2699 { "pwd", XZPWD, 0 },
2701 { "query", XZQUE, 0 },
2703 { "rename", XZREN, 0 },
2704 { "rmdir", XZRMD, 0 },
2705 { "set", XZSET, 0 },
2706 { "space", XZSPA, 0 },
2708 { "type", XZTYP, 0 },
2709 { "who", XZWHO, 0 },
2710 #endif /* NOFRILLS */
2713 int nrmt = (sizeof(remcmd) / sizeof(struct keytab)) - 1;
2716 struct keytab logtab[] = {
2718 { "connections", LOGM, CM_INV },
2720 #endif /* CKLOGDIAL */
2722 { "debugging", LOGD, 0 },
2724 { "packets", LOGP, 0 },
2726 { "session", LOGS, 0 },
2727 #endif /* NOLOCAL */
2729 { "transactions", LOGT, 0 },
2733 int nlog = (sizeof(logtab) / sizeof(struct keytab)) - 1;
2735 struct keytab writab[] = {
2737 { "append-file", LOGW, CM_INV },
2739 { "debug-log", LOGD, 0 },
2740 { "error", LOGE, 0 },
2742 { "file", LOGW, 0 },
2744 { "packet-log", LOGP, 0 },
2745 { "screen", LOGX, 0 },
2747 { "session-log", LOGS, 0 },
2748 #endif /* NOLOCAL */
2749 { "sys$output", LOGX, CM_INV },
2750 { "t", LOGT, CM_ABR|CM_INV }, /* Because of a typo in */
2751 { "tr", LOGT, CM_ABR|CM_INV }, /* the book... */
2752 { "tra", LOGT, CM_ABR|CM_INV },
2753 { "tran", LOGT, CM_ABR|CM_INV },
2754 { "trans", LOGT, CM_ABR|CM_INV },
2755 { "transa", LOGT, CM_ABR|CM_INV },
2756 { "transac", LOGT, CM_ABR|CM_INV },
2757 { "transact", LOGT, CM_ABR|CM_INV },
2758 { "transacti", LOGT, CM_ABR|CM_INV },
2759 { "transactio", LOGT, CM_ABR|CM_INV },
2760 { "transaction", LOGT, CM_ABR|CM_INV },
2761 { "transaction-log", LOGT, 0 },
2762 { "transactions", LOGT, CM_INV }
2764 int nwri = (sizeof(writab) / sizeof(struct keytab));
2766 static struct keytab clrtab[] = { /* Keywords for CLEAR command */
2768 { "alarm", CLR_ALR, 0 },
2770 { "apc", CLR_APC, 0 },
2773 { "binary-patterns", CLR_BIN, 0 },
2774 #endif /* PATTERNS */
2775 { "both", CLR_DEV|CLR_INP, CM_INV },
2778 { "command-screen", CLR_CMD, 0 },
2781 { "device", CLR_DEV, CM_INV|CM_ABR },
2782 { "device-and-input", CLR_DEV|CLR_INP, 0 },
2784 { "device-buffer", CLR_DEV, 0 },
2786 { "dial-status", CLR_DIA, 0 },
2789 { "input-buffer", CLR_INP, 0 },
2791 { "keyboard-buffer", CLR_KBD, 0 },
2792 { "send-list", CLR_SFL, 0 },
2794 { "scr", CLR_SCL, CM_INV|CM_ABR },
2796 { "screen", CLR_SCR, 0 },
2798 { "scrollback", CLR_SCL, CM_INV },
2799 { "terminal-screen", CLR_TRM, 0 },
2802 { "text-patterns", CLR_TXT, 0 },
2803 #endif /* PATTERNS */
2806 int nclear = (sizeof(clrtab) / sizeof(struct keytab)) - 1;
2808 struct keytab clstab[] = { /* Keywords for CLOSE command */
2810 { "!read", LOGR, CM_INV },
2811 { "!write", LOGW, CM_INV },
2816 { "append-file", LOGW, CM_INV },
2819 { "connection", 9999, 0 },
2820 #endif /* NOLOCAL */
2822 { "cx-log", LOGM, 0 },
2823 #endif /* CKLOGDIAL */
2825 { "debug-log", LOGD, 0 },
2827 { "host", 9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
2828 { "line", 9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
2829 { "p", LOGP, CM_INV|CM_ABR },
2830 { "packet-log", LOGP, 0 },
2831 { "port", 9999, CM_INV }, /* Synonym for CLOSE CONNECTION */
2833 { "read-file", LOGR, 0 },
2836 { "session-log", LOGS, 0 },
2837 #endif /* NOLOCAL */
2839 { "t", LOGT, CM_ABR|CM_INV }, /* Because of a typo in */
2840 { "tr", LOGT, CM_ABR|CM_INV }, /* the book... */
2841 { "tra", LOGT, CM_ABR|CM_INV },
2842 { "tran", LOGT, CM_ABR|CM_INV },
2843 { "trans", LOGT, CM_ABR|CM_INV },
2844 { "transa", LOGT, CM_ABR|CM_INV },
2845 { "transac", LOGT, CM_ABR|CM_INV },
2846 { "transact", LOGT, CM_ABR|CM_INV },
2847 { "transacti", LOGT, CM_ABR|CM_INV },
2848 { "transactio", LOGT, CM_ABR|CM_INV },
2849 { "transaction", LOGT, CM_ABR|CM_INV },
2850 { "transaction-log", LOGT, 0 },
2851 { "transactions", LOGT, CM_INV },
2854 { "write-file", LOGW, 0 },
2858 int ncls = (sizeof(clstab) / sizeof(struct keytab)) - 1;
2860 /* SHOW command arguments */
2863 struct keytab shotab[] = {
2865 { "alarm", SHALRM, 0 },
2866 { "arg", SHARG, CM_INV|CM_ABR },
2867 { "arguments", SHARG, 0 },
2868 { "args", SHARG, CM_INV },
2869 { "arrays", SHARR, 0 },
2873 { "associations", SHASSOC, 0 },
2874 #endif /* NOCSETS */
2877 { "attributes", SHATT, 0 },
2880 #ifdef CK_AUTHENTICATION
2881 { "authentication", SHOAUTH, CM_INV },
2882 #endif /* CK_AUTHENTICATION */
2886 { "browser", SHBROWSE, CM_PSH|CM_LOC },
2887 #endif /* BROWSER */
2890 { "character-sets", SHCSE, 0 },
2891 { "cmd", SHCMD, CM_INV },
2893 { "com", SHCOM, CM_INV|CM_ABR },
2894 { "comm", SHCOM, CM_INV|CM_ABR },
2895 { "communications", SHCOM, 0 },
2896 #endif /* NOLOCAL */
2897 { "command", SHCMD, 0 },
2898 { "connection", SHCONNX, 0 },
2900 { "control-prefixing", SHCTL, 0 },
2901 #endif /* CK_SPEED */
2903 { "cx", SHCONNX, CM_INV },
2904 #endif /* CKLOGDIAL */
2906 { "count", SHCOU, 0 },
2908 { "d", SHDIA, CM_INV|CM_ABR },
2910 { "default", SHDFLT, 0 },
2912 { "default", SHDFLT, CM_INV },
2915 { "dial", SHDIA, CM_LOC },
2917 { "double/ignore",SHDBL, 0 },
2920 { "editor", SHEDIT, CM_PSH },
2921 #endif /* NOFRILLS */
2924 { "escape", SHESC, CM_LOC },
2925 #endif /* NOLOCAL */
2926 { "exit", SHEXI, 0 },
2927 { "extended-options", SHXOPT, CM_INV },
2928 { "features", SHFEA, 0 },
2929 { "file", SHFIL, 0 },
2931 { "flow-control", SHOFLO, 0 },
2932 #endif /* NOLOCAL */
2934 { "ftp", SHOFTP, CM_PSH|CM_LOC },
2939 { "ftp", SHOFTP, 0 }, /* (built-in ftp) */
2940 #endif /* TCPSOCKET */
2943 #endif /* BROWSER */
2945 { "functions", SHFUN, 0 },
2946 { "globals", SHVAR, 0 },
2949 { "gui", SHOGUI, 0 },
2952 { "history", SHHISTORY, 0 },
2953 #endif /* CK_RECALL */
2954 { "ignore/double",SHDBL, CM_INV },
2955 { "iksd", SHOIKS, CM_INV },
2957 { "input", SHINP, 0 },
2960 { "k", SHKEY, CM_INV|CM_ABR },
2961 { "key", SHKEY, 0 },
2963 { "kverbs", SHKVB, 0 },
2964 #endif /* NOKVERBS */
2965 #endif /* NOSETKEY */
2967 { "labeled-file-info", SHLBL, 0 },
2968 #endif /* CK_LABELED */
2970 { "languages", SHLNG, 0 },
2971 #endif /* NOCSETS */
2972 { "logs", SHLOG, 0 },
2974 { "macros", SHMAC, 0 },
2977 { "modem", SHMOD, CM_LOC },
2979 { "modem-signals",SHCOM, CM_INV|CM_LOC },
2983 { "mouse", SHMOU, CM_LOC },
2984 #endif /* OS2MOUSE */
2985 #endif /* NOLOCAL */
2987 { "network", SHNET, CM_LOC },
2989 { "network", SHNET, CM_INV|CM_LOC },
2990 #endif /* NETCONN */
2991 { "options", SHOPTS, 0 },
2993 { "output", SHOUTP, CM_INV },
2997 { "pad", SHPAD, CM_LOC },
3000 { "parameters", SHPAR, CM_INV },
3002 { "patterns", SHOPAT, 0 },
3003 #endif /* PATTERNS */
3004 { "printer", SHPRT, 0 },
3006 { "prefixing", SHCTL, CM_INV },
3007 #endif /* CK_SPEED */
3009 { "protocol", SHPRO, 0 },
3011 { "rename", SHOREN, 0 },
3013 { "scripts", SHSCR, CM_LOC },
3015 { "send-list", SHSFL, 0 },
3017 { "server", SHSER, 0 },
3018 #endif /* NOSERVER */
3020 { "sexpression", SHSEXP, 0 },
3023 { "ssh", SHOSSH, 0 },
3025 { "stack", SHSTK, 0 },
3026 { "status", SHSTA, 0 },
3028 { "streaming", SHOSTR, 0 },
3029 #endif /* STREAMING */
3032 { "tabs", SHTAB, CM_INV|CM_LOC },
3035 { "tapi", SHTAPI, CM_LOC },
3036 { "tapi-comm", SHTAPI_C, CM_INV|CM_LOC },
3037 { "tapi-location", SHTAPI_L, CM_INV|CM_LOC },
3038 { "tapi-modem", SHTAPI_M, CM_INV|CM_LOC },
3039 #endif /* CK_TAPI */
3040 { "tcp", SHTCP, CM_LOC },
3042 { "tel", SHTEL, CM_INV|CM_ABR },
3043 { "telnet", SHTEL, 0 },
3044 { "telopt", SHTOPT, 0 },
3046 { "terminal", SHTER, CM_LOC },
3047 #endif /* NOLOCAL */
3049 { "tr", SHXMI, CM_INV|CM_ABR },
3050 { "tra", SHXMI, CM_INV|CM_ABR },
3051 { "tran", SHXMI, CM_INV|CM_ABR },
3052 { "trans", SHXMI, CM_INV|CM_ABR },
3055 { "transfer", SHOXFER, 0 },
3058 { "transmit", SHXMI, 0 },
3061 { "trigger", SHTRIG, CM_LOC },
3062 #endif /* CK_TRIGGER */
3066 { "udk", SHUDK, CM_LOC },
3068 #endif /* NOKVERBS */
3069 #endif /* NOSETKEY */
3071 { "variables", SHBUI, 0 },
3074 { "versions", SHVER, 0 },
3075 #endif /* NOFRILLS */
3077 { "vscrn", SHVSCRN, CM_INV|CM_LOC },
3079 { "xfer", SHOXFER, CM_INV },
3081 { "xmit", SHXMI, CM_INV },
3085 int nsho = (sizeof(shotab) / sizeof(struct keytab)) - 1;
3090 struct keytab padtab[] = { /* PAD commands */
3091 { "clear", XYPADL, 0 },
3092 { "interrupt", XYPADI, 0 },
3093 { "reset", XYPADR, 0 },
3094 { "status", XYPADS, 0 }
3096 int npadc = (sizeof(padtab) / sizeof(struct keytab));
3101 static struct keytab kmstab[] = {
3107 static struct keytab enatab[] = { /* ENABLE commands */
3108 { "all", EN_ALL, 0 },
3110 { "as", EN_ASG, CM_INV|CM_ABR },
3111 { "asg", EN_ASG, CM_INV },
3112 { "assign", EN_ASG, 0 },
3115 { "bye", EN_BYE, 0 },
3116 #endif /* datageneral */
3117 { "cd", EN_CWD, 0 },
3119 { "copy", EN_CPY, 0 },
3121 { "cwd", EN_CWD, CM_INV },
3122 { "delete", EN_DEL, 0 },
3123 { "directory", EN_DIR, 0 },
3124 { "enable", EN_ENA, CM_INV },
3125 { "exit", EN_XIT, 0 },
3126 { "finish", EN_FIN, 0 },
3127 { "get", EN_GET, 0 },
3128 { "host", EN_HOS, 0 },
3129 { "mail", EN_MAI, 0 },
3130 { "mkdir", EN_MKD, 0 },
3131 { "print", EN_PRI, 0 },
3133 { "query", EN_QUE, 0 },
3135 { "rename", EN_REN, 0 },
3136 { "retrieve", EN_RET, CM_INV },
3137 { "rmdir", EN_RMD, 0 },
3138 { "send", EN_SEN, 0 },
3139 { "set", EN_SET, 0 },
3140 { "space", EN_SPA, 0 },
3141 { "type", EN_TYP, 0 },
3142 { "who", EN_WHO, 0 }
3144 static int nena = (sizeof(enatab) / sizeof(struct keytab));
3145 #endif /* NOSERVER */
3147 struct keytab txtbin[] = {
3154 static struct keytab sndtab[] = { /* SEND command options */
3155 { "/after", SND_AFT, CM_ARG },
3157 { "/array", SND_ARR, CM_ARG },
3159 { "/as-name", SND_ASN, CM_ARG },
3160 { "/b", SND_BIN, CM_INV|CM_ABR },
3161 { "/before", SND_BEF, CM_ARG },
3162 { "/binary", SND_BIN, 0 },
3164 { "/c", SND_CMD, CM_INV|CM_ABR },
3165 { "/calibrate", SND_CAL, CM_INV|CM_ARG },
3166 #endif /* CALIBRATE */
3167 { "/command", SND_CMD, CM_PSH },
3168 { "/delete", SND_DEL, 0 },
3170 { "/dotfiles", SND_DOT, 0 },
3171 #endif /* UNIXOROSK */
3172 { "/except", SND_EXC, CM_ARG },
3174 { "/filter", SND_FLT, CM_ARG|CM_PSH },
3175 #endif /* PIPESEND */
3176 { "/filenames", SND_NAM, CM_ARG },
3178 { "/followlinks", SND_LNK, 0 },
3179 #endif /* CKSYMLINK */
3181 { "/image", SND_IMG, 0 },
3183 { "/image", SND_BIN, CM_INV },
3186 { "/labeled", SND_LBL, 0 },
3187 #endif /* CK_LABELED */
3188 { "/larger-than", SND_LAR, CM_ARG },
3189 { "/listfile", SND_FIL, CM_ARG },
3191 { "/mail", SND_MAI, CM_ARG },
3192 #endif /* NOFRILLS */
3194 { "/move-to", SND_MOV, CM_ARG },
3195 #endif /* CK_TMPDIR */
3196 { "/nobackupfiles", SND_NOB, 0 },
3198 { "/nodotfiles", SND_NOD, 0 },
3199 #endif /* UNIXOROSK */
3201 { "/nofollowlinks", SND_NLK, 0 },
3202 #endif /* CKSYMLINK */
3203 { "/not-after", SND_NAF, CM_ARG },
3204 { "/not-before", SND_NBE, CM_ARG },
3205 { "/pathnames", SND_PTH, CM_ARG },
3206 { "/print", SND_PRI, CM_ARG },
3208 { "/protocol", SND_PRO, CM_ARG },
3210 { "/protocol", SND_PRO, CM_ARG|CM_INV },
3212 { "/quiet", SND_SHH, 0 },
3213 { "/recover", SND_RES, 0 },
3215 /* Systems where we do recursion */
3216 { "/recursive", SND_REC, 0 },
3219 /* Systems that do recursion themselves without our assistance */
3220 /* if we give them the right kind of wildcard */
3221 { "/recursive", SND_REC, 0 },
3224 { "/recursive", SND_REC, 0 },
3226 { "/recursive", SND_REC, CM_INV },
3227 #endif /* datageneral */
3229 #endif /* RECURSIVE */
3230 { "/rename-to", SND_REN, CM_ARG },
3231 { "/since", SND_AFT, CM_INV|CM_ARG },
3232 { "/smaller-than", SND_SMA, CM_ARG },
3233 { "/starting-at", SND_STA, CM_ARG },
3235 { "/su", SND_ASN, CM_ARG|CM_INV|CM_ABR },
3236 { "/sub", SND_ASN, CM_ARG|CM_INV|CM_ABR },
3237 { "/subject", SND_ASN, CM_ARG },
3238 #endif /* NOFRILLS */
3240 { "/subdirectories", SND_REC, CM_INV },
3241 #endif /* RECURSIVE */
3242 { "/text", SND_TXT, 0 },
3243 { "/transparent", SND_XPA, 0 },
3244 { "/type", SND_TYP, CM_ARG }
3246 #define NSNDTAB sizeof(sndtab)/sizeof(struct keytab)
3247 static int nsndtab = NSNDTAB;
3250 static struct keytab msndtab[] = { /* MSEND options */
3251 { "/after", SND_AFT, CM_ARG },
3252 { "/before", SND_BEF, CM_ARG },
3253 { "/binary", SND_BIN, 0 },
3254 { "/delete", SND_DEL, 0 },
3255 { "/except", SND_EXC, CM_ARG },
3256 { "/filenames", SND_NAM, CM_ARG },
3258 { "/followlinks", SND_LNK, 0 },
3259 #endif /* CKSYMLINK */
3261 { "/image", SND_IMG, 0 },
3263 { "/image", SND_BIN, CM_INV },
3266 { "/labeled", SND_LBL, 0 },
3267 #endif /* CK_LABELED */
3268 { "/larger-than", SND_LAR, CM_ARG },
3269 { "/list", SND_FIL, CM_ARG },
3271 { "/mail", SND_MAI, CM_ARG },
3272 #endif /* NOFRILLS */
3274 { "/move-to", SND_MOV, CM_ARG },
3275 #endif /* CK_TMPDIR */
3277 { "/nofollowlinks", SND_NLK, 0 },
3278 #endif /* CKSYMLINK */
3279 { "/not-after", SND_NAF, CM_ARG },
3280 { "/not-before", SND_NBE, CM_ARG },
3281 { "/pathnames", SND_PTH, CM_ARG },
3282 { "/print", SND_PRI, CM_ARG },
3284 { "/protocol", SND_PRO, CM_ARG },
3286 { "/quiet", SND_SHH, 0 },
3287 { "/recover", SND_RES, 0 },
3288 { "/rename-to", SND_REN, CM_ARG },
3289 { "/since", SND_AFT, CM_INV|CM_ARG },
3290 { "/smaller-than", SND_SMA, CM_ARG },
3291 { "/starting-at", SND_STA, CM_ARG },
3293 { "/subject", SND_ASN, CM_ARG },
3294 #endif /* NOFRILLS */
3295 { "/text", SND_TXT, 0 },
3296 { "/transparent", SND_XPA, 0 },
3297 { "/type", SND_TYP, CM_ARG }
3299 #define NMSNDTAB sizeof(msndtab)/sizeof(struct keytab)
3300 static int nmsndtab = NMSNDTAB;
3301 #endif /* NOMSEND */
3304 /* CONNECT command switches */
3306 #define CONN_II 0 /* Idle interval */
3307 #define CONN_IS 1 /* Idle string */
3308 #define CONN_IL 2 /* Idle limit */
3309 #define CONN_NV 3 /* Non-Verbose */
3310 #define CONN_TL 4 /* Time limit */
3311 #define CONN_TS 5 /* Trigger string */
3312 #define CONN_AS 6 /* Asynchronous */
3313 #define CONN_SY 7 /* Synchronous */
3314 #define CONN_MAX 7 /* Number of CONNECT switches */
3317 static struct keytab conntab[] = {
3319 { "/asynchronous", CONN_AS, CM_INV },
3322 { "/idle-interval", CONN_II, CM_ARG },
3323 { "/idle-limit", CONN_IL, CM_ARG },
3324 { "/idle-string", CONN_IS, CM_ARG },
3325 { "/quietly", CONN_NV, CM_INV },
3327 { "/quietly", CONN_NV, 0 },
3328 #endif /* XLIMITS */
3330 { "/synchronous", CONN_SY, CM_INV },
3333 { "/time-limit", CONN_TL, CM_ARG },
3334 #endif /* XLIMITS */
3336 { "/trigger", CONN_TS, CM_ARG },
3337 #endif /* CK_TRIGGER */
3340 #define NCONNTAB sizeof(conntab)/sizeof(struct keytab)
3341 static int nconntab = NCONNTAB;
3342 #endif /* NOLOCAL */
3345 static struct keytab stattab[] = { /* STATISTICS command switches */
3347 { "/verbose", 0, 0 }
3353 struct mtab mactab[MAC_MAX] = { /* Preinitialized macro table */
3357 struct mtab *mactab; /* Dynamically allocated macro table */
3358 #endif /* COMMENT */
3361 struct keytab mackey[MAC_MAX]; /* Macro names as command keywords */
3366 struct keytab beeptab[] = { /* Beep options */
3367 { "error", BP_FAIL, 0 },
3368 { "information", BP_NOTE, 0 },
3369 { "warning", BP_WARN, 0 }
3371 int nbeeptab = sizeof(beeptab)/sizeof(struct keytab);
3373 /* CLEAR COMMMAND-SCREEN options */
3383 struct keytab clrcmdtab[] = {
3384 { "all", CLR_C_ALL, 0 },
3385 { "bol", CLR_C_BOL, 0 },
3386 { "bos", CLR_C_BOS, 0 },
3387 { "eol", CLR_C_EOL, 0 },
3388 { "eos", CLR_C_EOS, 0 },
3389 { "line", CLR_C_LIN, 0 },
3390 { "scrollback", CLR_C_SCR, 0 }
3392 int nclrcmd = sizeof(clrcmdtab)/sizeof(struct keytab);
3397 /* Not used at present */
3398 static struct keytab pagetab[] = {
3399 { "/more", 1, CM_INV },
3400 { "/nopage", 0, 0 },
3403 int npagetab = sizeof(pagetab)/sizeof(struct keytab);
3404 #endif /* COMMENT */
3406 #define TYP_NOP 0 /* /NOPAGE */
3407 #define TYP_PAG 1 /* /PAGE */
3408 #define TYP_HEA 2 /* /HEAD:n */
3409 #define TYP_TAI 3 /* /TAIL:n */
3410 #define TYP_PAT 4 /* /MATCH:pattern */
3411 #define TYP_WID 5 /* /WIDTH:cols */
3412 #define TYP_COU 6 /* /COUNT */
3413 #define TYP_OUT 7 /* /OUTPUT:file */
3414 #define TYP_PFX 8 /* /PREFIX:string */
3416 #define TYP_XIN 9 /* /TRANSLATE-FROM:charset */
3417 #define TYP_XUT 10 /* /TRANSLATE-TO:charset */
3418 #define TYP_XPA 11 /* /TRANSPARENT */
3419 #endif /* UNICODE */
3421 #define TYP_GUI 12 /* /GUI:title */
3422 #define TYP_HIG 13 /* /HEIGHT:rows */
3424 #define TYP_NUM 14 /* /NUMBER */
3426 static struct keytab typetab[] = { /* TYPE command switches */
3427 { "/count", TYP_COU, 0 },
3429 { "/character-set", TYP_XIN, CM_ARG },
3430 #endif /* UNICODE */
3432 { "/gui", TYP_GUI, CM_ARG },
3434 { "/head", TYP_HEA, CM_ARG },
3436 { "/height", TYP_HIG, CM_ARG },
3438 { "/match", TYP_PAT, CM_ARG },
3440 { "/more", TYP_PAG, CM_INV },
3441 { "/nopage", TYP_NOP, 0 },
3442 { "/number", TYP_NUM, 0 },
3443 { "/output", TYP_OUT, CM_ARG },
3444 { "/page", TYP_PAG, 0 },
3445 #endif /* CK_TTGWSIZ */
3446 { "/prefix", TYP_PFX, CM_ARG },
3447 { "/tail", TYP_TAI, CM_ARG },
3449 { "/translate-to", TYP_XUT, CM_ARG },
3450 { "/transparent", TYP_XPA, 0 },
3451 #endif /* UNICODE */
3452 { "/width", TYP_WID, CM_ARG },
3454 { "/xlate-to", TYP_XUT, CM_INV|CM_ARG },
3455 #endif /* UNICODE */
3458 int ntypetab = sizeof(typetab)/sizeof(struct keytab) - 1;
3460 int typ_page = -1; /* TYPE /[NO]PAGE default */
3464 #define TRA_ALL 999 /* TRACE command */
3471 static struct keytab tracetab[] = { /* TRACE options */
3472 { "all", TRA_ALL, 0 },
3473 { "assignments", TRA_ASG, 0 },
3474 { "command-level", TRA_CMD, 0 }
3476 static int ntracetab = sizeof(tracetab)/sizeof(struct keytab);
3483 if (typ_page > -1) {
3484 prtopt(&optlines,typ_page ? "/PAGE" : "/NOPAGE");
3486 prtopt(&optlines,"(no options set)");
3488 ckmakmsg(tmpbuf,TMPBUFSIZ,"/WIDTH:",ckitoa(typ_wid),NULL,NULL);
3489 prtopt(&optlines,tmpbuf);
3491 prtopt(&optlines,"");
3496 /* isauto == 1 if locus is being switched automatically */
3499 setlocus(x, isauto) int x, isauto; {
3500 extern int quitting;
3502 if (x && locus) return;
3503 if (!x && !locus) return;
3504 /* Get here if it actually needs to be changed */
3506 if (isauto && /* Automatically switching */
3507 !quitting && /* not exiting */
3508 autolocus == 2) { /* and AUTOLOCUS is set to ASK */
3510 ckmakmsg(locmsg,300,
3511 "Switching Locus to ",
3512 x ? "LOCAL" : "REMOTE",
3513 " for file management commands\n"
3514 "such as CD, DIRECTORY, DELETE, RENAME. Type HELP SET\n"
3515 "LOCUS at the K-95> prompt for further info. Use the\n"
3517 "Actions menu or SET LOCUS command to disable automatic\n"
3518 "Locus switching or to disable these queries.",
3520 "SET LOCUS command to disable automatic locus switching\n"
3521 "or to disable these queries.",
3524 if (uq_ok(locmsg,"OK to switch Locus?",3,NULL,1)) {
3527 KuiSetProperty(KUI_LOCUS,x,0);
3533 if (isauto && msgflg && !quitting)
3534 printf("Switching LOCUS for file-management commands to %s %s.\n",
3535 x ? "LOCAL" : "REMOTE",
3536 "(HELP LOCUS for info)"
3541 KuiSetProperty(KUI_LOCUS,x,0);
3548 setautolocus(x) int x; {
3551 KuiSetProperty(KUI_AUTO_LOCUS,x,0);
3557 settypopts() { /* Set TYPE option defaults */
3561 if ((y = cmswi(typetab,ntypetab,"Switch","",xxstring)) < 0) {
3568 if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
3569 printf("?This switch does not take an argument\n");
3573 case TYP_NOP: xp = 0; break;
3574 case TYP_PAG: xp = 1; break;
3577 if ((x = cmnum("Column at which to truncate",
3578 ckitoa(cmd_cols),10,&y,xxstring)) < 0)
3584 printf("?Sorry, this option can not be set\n");
3588 if ((x = cmcfm()) < 0) /* Get confirmation */
3590 if (xp > -1) typ_page = xp; /* Confirmed, save defaults */
3591 return(success = 1);
3594 /* Forward declarations of functions local to this module */
3597 _PROTOTYP (int douchmod, ( void ) );
3600 _PROTOTYP (int dopurge, ( void ) );
3601 #endif /* CKPURGE */
3603 _PROTOTYP (int doundef, ( int ) );
3604 _PROTOTYP (int doask, ( int ) );
3605 _PROTOTYP (int dodef, ( int ) );
3606 _PROTOTYP (int doelse, ( void ) );
3607 _PROTOTYP (int dofor, ( void ) );
3610 _PROTOTYP (int dodial, ( int ) );
3612 _PROTOTYP (int dodel, ( void ) );
3613 _PROTOTYP (int dopaus, ( int ) );
3616 _PROTOTYP (int doping, ( void ) );
3617 _PROTOTYP (int doftp, ( void ) );
3618 #endif /* TCPSOCKET */
3622 _PROTOTYP (int dorenam, ( void ) );
3623 #endif /* NOFRILLS */
3624 #endif /* NORENAME */
3626 _PROTOTYP (int docopy, ( void ) );
3629 _PROTOTYP (int dolink, ( void ));
3632 _PROTOTYP (int dorexx, ( void ) );
3633 #endif /* CK_REXX */
3636 static struct keytab telcmd[] = {
3637 { "abort", TN_ABORT, CM_INV }, /* Emotionally toned - don't show */
3639 { "ayt", TN_AYT, 0 },
3640 { "break", BREAK, 0 },
3641 { "cancel",TN_ABORT, 0 },
3642 { "dmark", TN_DM, 0 },
3644 { "dont", DONT, 0 },
3647 { "eof", TN_EOF, 0 },
3648 { "eor", TN_EOR, 0 },
3652 { "forward", TN_FWD, CM_INV },
3654 #endif /* CK_KERBEROS */
3657 { "nop", TN_NOP, 0 },
3658 { "sak", TN_SAK, CM_INV },
3661 { "susp", TN_SUSP, 0 },
3662 { "will", WILL, 0 },
3665 static int ntelcmd = (sizeof(telcmd) / sizeof(struct keytab));
3667 static struct keytab tnopts[] = {
3668 #ifdef CK_AUTHENTICATION
3669 { "auth", TELOPT_AUTHENTICATION, 0 },
3671 { "auth", TELOPT_AUTHENTICATION, CM_INV },
3672 #endif /* CK_AUTHENTICATION */
3673 { "binary", TELOPT_BINARY, 0 },
3675 { "c", TELOPT_COMPORT, CM_INV|CM_ABR},
3676 { "co", TELOPT_COMPORT, CM_INV|CM_ABR},
3677 { "com", TELOPT_COMPORT, CM_INV|CM_ABR},
3678 { "com-port-control", TELOPT_COMPORT, 0 },
3679 { "comport-control", TELOPT_COMPORT, CM_INV},
3680 #else /* TN_COMPORT */
3681 { "com-port-control", TELOPT_COMPORT, CM_INV },
3682 { "comport-control", TELOPT_COMPORT, CM_INV},
3683 #endif /* TN_COMPORT */
3684 { "echo", TELOPT_ECHO, 0 },
3685 #ifdef CK_ENCRYPTION
3686 { "encrypt", TELOPT_ENCRYPTION, 0 },
3688 { "encrypt", TELOPT_ENCRYPTION, CM_INV },
3689 #endif /* CK_ENCRYPTION */
3691 { "forward-x", TELOPT_FORWARD_X, 0 },
3693 { "forward-x", TELOPT_FORWARD_X, CM_INV },
3694 #endif /* CK_FORWARD_X */
3696 { "kermit", TELOPT_KERMIT, 0 },
3698 { "kermit", TELOPT_KERMIT, CM_INV },
3699 #endif /* IKS_OPTION */
3700 { "lflow", TELOPT_LFLOW, CM_INV },
3701 { "logout", TELOPT_LOGOUT, CM_INV },
3703 { "naws", TELOPT_NAWS, 0 },
3705 { "naws", TELOPT_NAWS, CM_INV },
3706 #endif /* CK_NAWS */
3707 #ifdef CK_ENVIRONMENT
3708 { "new-environment", TELOPT_NEWENVIRON, 0 },
3710 { "new-environment", TELOPT_NEWENVIRON, CM_INV },
3711 #endif /* CK_ENVIRONMENT */
3712 { "pragma-heartbeat",TELOPT_PRAGMA_HEARTBEAT, CM_INV },
3713 { "pragma-logon", TELOPT_PRAGMA_LOGON, CM_INV },
3714 { "pragma-sspi", TELOPT_SSPI_LOGON, CM_INV },
3715 { "sak", TELOPT_IBM_SAK, CM_INV },
3717 { "send-location", TELOPT_SNDLOC, 0 },
3719 { "send-location", TELOPT_SNDLOC, CM_INV },
3720 #endif /* CK_SNDLOC */
3721 { "sga", TELOPT_SGA, 0 },
3723 { "start-tls", TELOPT_START_TLS, 0 },
3725 { "start-tls", TELOPT_START_TLS, CM_INV },
3727 { "ttype", TELOPT_TTYPE, 0 },
3728 #ifdef CK_ENVIRONMENT
3729 { "xdisplay-location", TELOPT_XDISPLOC, 0 },
3731 { "xdisplay-location", TELOPT_XDISPLOC, CM_INV },
3732 #endif /* CK_ENVIRONMENT */
3735 static int ntnopts = (sizeof(tnopts) / sizeof(struct keytab)) - 1;
3737 static struct keytab tnsbopts[] = {
3739 { "naws", TELOPT_NAWS, 0 },
3740 #endif /* CK_NAWS */
3743 static int ntnsbopts = (sizeof(tnsbopts) / sizeof(struct keytab)) - 1;
3750 doftp() { /* (External) FTP command */
3751 char *p, *f; /* (See doxftp() for internal one) */
3754 if (network) /* If we have a current connection */
3755 ckstrncpy(line,ttname,LINBUFSIZ); /* get the host name */
3756 else *line = '\0'; /* as default host */
3757 for (p = line; *p; p++) /* Remove ":service" from end. */
3758 if (*p == ':') { *p = '\0'; break; }
3759 if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
3762 printf("?Sorry, FTP command disabled\n");
3763 return(success = 0);
3765 /* Construct FTP command */
3767 #ifdef MULTINET /* TGV MultiNet */
3768 ckmakmsg(line,LINBUFSIZ,"multinet ftp ",s,NULL,NULL);
3770 ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
3771 #endif /* MULTINET */
3777 if (!f[0]) f = "ftp";
3778 ckmakmsg(line,LINBUFSIZ,f," ",s,NULL);
3780 p = line + strlen(ftpapp);
3782 if (*p == '/') *p = '\\';
3787 ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
3789 #else /* OS2ORUNIX */
3790 ckmakmsg(line,LINBUFSIZ,"ftp ",s,NULL,NULL);
3791 #endif /* OS2ORUNIX */
3793 conres(); /* Make console normal */
3795 printf("\n"); /* Prevent prompt-stomping */
3796 #endif /* DEC_TCPIP */
3798 concb((char)escape);
3799 return(success = x);
3804 doping() { /* PING command */
3805 char *p; /* just runs ping program */
3808 if (network) /* If we have a current connection */
3809 ckstrncpy(line,ttname,LINBUFSIZ); /* get the host name */
3810 else *line = '\0'; /* as default host to be pinged. */
3811 for (p = line; *p; p++) /* Remove ":service" from end. */
3812 if (*p == ':') { *p = '\0'; break; }
3813 if ((x = cmtxt("IP host name or number", line, &s, xxstring)) < 0)
3816 printf("?Sorry, PING command disabled\n");
3817 return(success = 0);
3820 /* Construct PING command */
3822 #ifdef MULTINET /* TGV MultiNet */
3823 ckmakmsg(line,LINBUFSIZ,"multinet ping ",s," /num=1",NULL);
3825 ckmakmsg(line,LINBUFSIZ,"ping ",s," 56 1",NULL); /* Other VMS TCP/IP's */
3826 #endif /* MULTINET */
3828 ckmakmsg(line,LINBUFSIZ,"ping ",s,NULL,NULL);
3830 conres(); /* Make console normal */
3832 printf("\n"); /* Prevent prompt-stomping */
3833 #endif /* DEC_TCPIP */
3835 concb((char)escape);
3836 return(success = x);
3839 #endif /* TCPSOCKET */
3844 /* Pop from all FOR/WHILE/XIF/SWITCH's */
3845 debug(F101,"doend maclvl 1","",maclvl);
3846 while ((maclvl > 0) &&
3847 (m_arg[maclvl-1][0]) &&
3848 (cmdstk[cmdlvl].src == CMD_MD) &&
3849 (!strncmp(m_arg[maclvl-1][0],"_xif",4) ||
3850 !strncmp(m_arg[maclvl-1][0],"_for",4) ||
3851 !strncmp(m_arg[maclvl-1][0],"_whi",4) ||
3852 !strncmp(m_arg[maclvl-1][0],"_swi",4))) {
3853 debug(F110,"END popping",m_arg[maclvl-1][0],0);
3854 dogta(XXPTA); /* Put args back */
3855 popclvl(); /* Pop up two levels */
3857 debug(F101,"doend maclvl 2","",maclvl);
3860 if (mrval[maclvl]) /* Free previous retval if any */
3861 free(mrval[maclvl]);
3862 mrval[maclvl] = malloc(16); /* Room for up to 15 digits */
3863 if (mrval[maclvl]) /* Record current retval */
3864 ckmakmsg(mrval[maclvl],16,ckitoa(x),NULL,NULL,NULL);
3867 popclvl(); /* Now pop out of macro or TAKE file */
3871 debug(F101,"END maclvl 3","",maclvl);
3872 debug(F111,"END mrval[maclvl]",mrval[maclvl],maclvl);
3873 debug(F111,"END mrval[maclvl+1]",mrval[maclvl+1],maclvl+1);
3882 if ((x = cmdir("Name of new root directory","",&s,xxstring)) < 0) {
3884 printf("?Directory name required\n");
3889 ckstrncpy(line,s,LINBUFSIZ);
3891 if ((x = cmcfm()) < 0) return(x);
3898 case -2: m = "Not a directory"; break;
3899 case -3: m = "Internal error"; break;
3900 case -4: m = "Access denied"; break;
3901 case -5: m = "Off limits"; break;
3903 if (m) printf("%s: \"%s\"\n", m, s);
3904 return(m ? -9 : -2);
3907 return(success = 1);
3913 static char * asnbuf = NULL; /* As-name buffer pointer */
3915 char sndxnam[] = { "_array_x_" }; /* (with replaceable x!) */
3918 The new SEND command, replacing BSEND, CSEND, PSEND, etc etc.
3919 Call with cx = top-level keyword value. Returns:
3921 0 On other type of failure (e.g. requested operation not allowed).
3922 1 On success with sstate set to 's' so protocol will begin.
3925 /* D O X S E N D -- Parse SEND and related commands with switches */
3928 doxsend(cx) int cx; {
3929 int c, i, n, wild, confirmed = 0; /* Workers */
3930 int x, y; /* of the world... */
3931 int getval = 0; /* Whether to get switch value */
3932 extern char * snd_move; /* Directory to move sent files to */
3933 extern char * snd_rename; /* What to rename sent files to */
3934 extern char * filefile; /* File containing filenames to send */
3935 extern int xfiletype; /* Send only text (or binary) files */
3936 extern struct keytab pathtab[]; /* PATHNAMES option keywords */
3937 extern int npathtab; /* How many of them */
3938 extern int recursive; /* Recursive directory traversal */
3939 extern int rprintf; /* REMOTE PRINT flag */
3940 extern int fdispla; /* TRANSFER DISPLAY setting */
3941 extern int skipbup; /* Skip backup files when sending */
3942 struct stringint pv[SND_MAX+1]; /* Temporary array for switch values */
3943 struct FDB sf, sw, fl, cm; /* FDBs for each parse function */
3944 int mlist = 0; /* Flag for MSEND or MMOVE */
3945 char * m; /* For making help messages */
3946 extern struct keytab protos[]; /* File transfer protocols */
3947 extern int xfrxla, g_xfrxla, nprotos;
3948 extern char sndbefore[], sndafter[], *sndexcept[]; /* Selection criteria */
3949 extern char sndnbefore[], sndnafter[];
3950 extern CK_OFF_T sndsmaller, sndlarger, calibrate;
3952 int range[2]; /* Array range */
3953 char ** ap = NULL; /* Array pointer */
3954 int arrayx = -1; /* Array index */
3958 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) {
3960 printf("?Sorry, No MAIL with FTP\n");
3963 return(doftpput(cx,0));
3967 for (i = 0; i <= SND_MAX; i++) { /* Initialize switch values */
3968 pv[i].sval = NULL; /* to null pointers */
3969 pv[i].ival = -1; /* and -1 int values */
3970 pv[i].wval = (CK_OFF_T)-1; /* and -1 wide values */
3975 sndxin = -1; /* Array index */
3977 sndarray = NULL; /* Array pointer */
3980 g_matchdot = matchdot; /* Match dot files */
3981 #endif /* UNIXOROSK */
3982 g_recursive = recursive; /* Recursive sending */
3983 recursive = 0; /* Save global value, set local */
3984 debug(F101,"xsend entry fncnv","",fncnv);
3986 /* Preset switch values based on top-level command that called us */
3989 case XXMSE: /* MSEND */
3991 case XXCSEN: /* CSEND */
3992 pv[SND_CMD].ival = 1; break;
3993 case XXMMOVE: /* MMOVE */
3995 case XXMOVE: /* MOVE */
3996 pv[SND_DEL].ival = 1; break;
3997 case XXRSEN: /* RESEND */
3998 pv[SND_BIN].ival = 1; /* Implies /BINARY */
3999 pv[SND_RES].ival = 1; break;
4000 case XXMAI: /* MAIL */
4001 pv[SND_MAI].ival = 1; break;
4004 /* Set up chained parse functions... */
4006 cmfdbi(&sw, /* First FDB - command switches */
4008 "Filename, or switch", /* hlpmsg */
4010 "", /* addtl string data */
4012 nsndtab, /* addtl numeric data 1: tbl size */
4014 mlist ? nmsndtab : nsndtab, /* addtl numeric data 1: tbl size */
4015 #endif /* NOMSEND */
4016 4, /* addtl numeric data 2: 4 = cmswi */
4017 xxstring, /* Processing function */
4019 sndtab, /* Keyword table */
4021 mlist ? msndtab : sndtab,
4022 #endif /* NOMSEND */
4023 &sf /* Pointer to next FDB */
4025 cmfdbi(&sf, /* 2nd FDB - file to send */
4027 "File(s) to send", /* hlpmsg */
4029 "", /* addtl string data */
4030 nolinks, /* addtl numeric data 1 */
4031 0, /* addtl numeric data 2 */
4036 cmfdbi(&fl, /* 3rd FDB - command to send from */
4038 "Command", /* hlpmsg */
4040 "", /* addtl string data */
4041 0, /* addtl numeric data 1 */
4042 0, /* addtl numeric data 2 */
4047 cmfdbi(&cm, /* 4th FDB - Confirmation */
4051 "", /* addtl string data */
4052 0, /* addtl numeric data 1 */
4053 0, /* addtl numeric data 2 */
4059 while (1) { /* Parse 0 or more switches */
4060 x = cmfdb(&sw); /* Parse something */
4061 debug(F101,"xsend cmfdb","",x);
4062 if (x < 0) /* Error */
4063 goto xsendx; /* or reparse needed */
4064 if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
4067 They gave a switch, but let's see how they terminated it.
4068 If they ended it with : or =, then we must parse a value.
4069 If they ended it with anything else, then we must NOT parse a value.
4071 c = cmgbrk(); /* Get break character */
4072 getval = (c == ':' || c == '='); /* to see how they ended the switch */
4073 if (getval && !(cmresult.kflags & CM_ARG)) {
4074 printf("?This switch does not take arguments\n");
4078 if (!getval && (cmgkwflgs() & CM_ARG)) {
4079 printf("?This switch requires an argument\n");
4083 n = cmresult.nresult; /* Numeric result = switch value */
4084 debug(F101,"xsend switch","",n);
4086 switch (n) { /* Process the switch */
4087 case SND_CMD: /* These take no args */
4089 printf("?Sorry, system command access is disabled\n");
4094 else if (sndfilter) {
4096 "?Sorry, no SEND /COMMAND or CSEND when SEND FILTER selected\n");
4100 #endif /* PIPESEND */
4101 sw.hlpmsg = "Command, or switch"; /* Change help message */
4102 pv[n].ival = 1; /* Just set the flag */
4103 pv[SND_ARR].ival = 0;
4106 case SND_REC: /* /RECURSIVE */
4107 recursive = 2; /* Set the real variable */
4108 pv[SND_PTH].ival = PATH_REL; /* Give them relative pathnames */
4109 pv[n].ival = 1; /* Just set the flag */
4112 case SND_RES: /* /RECOVER (resend) */
4113 pv[SND_ARR].ival = 0;
4114 pv[SND_BIN].ival = 1; /* Implies /BINARY */
4115 case SND_NOB: /* /NOBACKUP */
4116 case SND_DEL: /* /DELETE */
4117 case SND_SHH: /* /QUIET */
4118 pv[n].ival = 1; /* Just set the flag */
4122 /* Like recursive, these are set immediately because they affect cmifi() */
4123 case SND_DOT: /* /DOTFILES */
4126 case SND_NOD: /* /NODOTFILES */
4129 #endif /* UNIXOROSK */
4131 /* File transfer modes - each undoes the others */
4133 case SND_BIN: /* Binary */
4134 case SND_TXT: /* Text */
4135 case SND_IMG: /* Image */
4136 case SND_LBL: /* Labeled */
4137 pv[SND_BIN].ival = 0;
4138 pv[SND_TXT].ival = 0;
4139 pv[SND_IMG].ival = 0;
4140 pv[SND_LBL].ival = 0;
4147 nolinks = (n == SND_NLK) ? 2 : 0;
4148 cmfdbi(&sf, /* Redo cmifi() */
4150 "File(s) to send", /* hlpmsg */
4152 "", /* addtl string data */
4153 nolinks, /* addtl numeric data 1 */
4154 0, /* addtl numeric data 2 */
4160 #endif /* CKSYMLINK */
4162 case SND_EXC: /* Excludes */
4164 if ((x = cmfld("Pattern","",&s,xxstring)) < 0) {
4166 printf("?Pattern required\n");
4171 if (pv[n].sval) free(pv[n].sval);
4174 printf("?Pattern too long - 256 max\n");
4178 pv[n].sval = malloc(y+1);
4180 strcpy(pv[n].sval,s); /* safe */
4185 case SND_MOV: /* MOVE after */
4186 case SND_REN: /* RENAME after */
4188 if ((x = cmfld(n == SND_MOV ?
4189 "device and/or directory for source file after sending" :
4190 "new name for source file after sending",
4193 n == SND_MOV ? xxstring : NULL
4196 printf("%s\n", n == SND_MOV ?
4197 "?Destination required" :
4198 "?New name required"
4204 if (pv[n].sval) free(pv[n].sval);
4208 pv[n].sval = malloc(y+1);
4210 strcpy(pv[n].sval,s); /* safe */
4216 case SND_SMA: /* Smaller / larger than */
4220 if ((x = cmnumw("Size in bytes","0",10,&w,xxstring)) < 0)
4225 case SND_AFT: /* Send /AFTER:date-time */
4226 case SND_BEF: /* Send /BEFORE:date-time */
4227 case SND_NAF: /* Send /NOT-AFTER:date-time */
4228 case SND_NBE: /* Send /NOT-BEFORE:date-time */
4230 if ((x = cmdate("File date-time","",&s,0,xxstring)) < 0) {
4232 printf("?Date-time required\n");
4237 if (pv[n].sval) free(pv[n].sval);
4238 pv[n].sval = malloc((int)strlen(s)+1);
4240 strcpy(pv[n].sval,s); /* safe */
4245 case SND_MAI: /* Send as mail (= MAIL) */
4247 if (inserver && !ENABLED(en_mai)) {
4248 printf("?Sorry, sending files as mail is disabled\n");
4254 if ((x = cmfld("e-mail address","",&s,xxstring)) < 0) {
4256 printf("?address required\n");
4262 if (pv[n].sval) free(pv[n].sval);
4263 pv[n].sval = malloc((int)strlen(s)+1);
4265 strcpy(pv[n].sval,s); /* safe */
4268 case SND_PRI: /* Send to be printed (REMOTE PRINT) */
4270 if (inserver && !ENABLED(en_mai)) {
4271 printf("?Sorry, sending files for printing is disabled\n");
4277 if ((x = cmfld("Print options","",&s,xxstring)) < 0)
4278 if (x != -3) goto xsendx;
4280 if (pv[n].sval) free(pv[n].sval);
4281 pv[n].sval = malloc((int)strlen(s)+1);
4283 strcpy(pv[n].sval,s); /* safe */
4286 case SND_ASN: /* As-name */
4287 debug(F101,"xsend /as-name getval","",getval);
4289 if ((x = cmfld("Name to send under","",&s,NULL)) < 0) {
4291 printf("?name required\n");
4297 if ((y = strlen(s)) > 0) {
4298 if (pv[n].sval) free(pv[n].sval);
4299 pv[n].sval = malloc(y+1);
4301 strcpy(pv[n].sval,s); /* safe */
4307 case SND_STA: { /* Starting position (= PSEND) */
4310 if ((x = cmnumw("0-based position","0",10,&w,xxstring)) < 0)
4315 case SND_PRO: /* Protocol to use */
4317 if ((x = cmkey(protos,nprotos,"File-transfer protocol","",
4320 printf("?name of protocol required\n");
4329 case SND_FLT: /* Filter */
4330 debug(F101,"xsend /filter getval","",getval);
4332 if ((x = cmfld("Filter program to send through","",&s,NULL)) < 0) {
4338 if (*s) s = brstrip(s);
4340 for (x = 0; x < y; x++) { /* Make sure they included "\v(...)" */
4341 if (s[x] != '\\') continue;
4342 if (s[x+1] == 'v') break;
4346 "?Filter must contain a replacement variable for filename.\n"
4356 if ((y = strlen(s)) > 0) {
4357 if ((pv[n].sval = malloc(y+1)))
4358 strcpy(pv[n].sval,s); /* safe */
4361 #endif /* PIPESEND */
4363 case SND_PTH: /* Pathnames */
4365 pv[n].ival = PATH_REL;
4368 if ((x = cmkey(pathtab,npathtab,"","absolute",xxstring)) < 0)
4373 case SND_NAM: /* Filenames */
4375 if ((x = cmkey(fntab,nfntab,"","converted",xxstring)) < 0)
4377 debug(F101,"xsend /filenames","",x);
4382 case SND_CAL: { /* /CALIBRATE */
4385 if ((x = cmnumw("number of Kbytes to send",
4386 "1024",10,&w,xxstring)) < 0)
4391 pv[SND_ARR].ival = 0;
4394 #endif /* CALIBRATE */
4396 case SND_FIL: /* Name of file containing filnames */
4398 if ((x = cmifi("Name of file containing list of filenames",
4399 "",&s,&y,xxstring)) < 0) {
4401 printf("?Filename required\n");
4406 printf("?Wildcards not allowed\n");
4413 if ((pv[n].sval = malloc((int)strlen(s)+1))) {
4414 strcpy(pv[n].sval,s);
4416 pv[SND_ARR].ival = 0;
4422 case SND_ARR: /* SEND /ARRAY: */
4425 if ((x = cmfld("Array name (a single letter will do)",
4435 if ((x = arraybounds(s,&(range[0]),&(range[1]))) < 0) {
4436 printf("?Bad array: %s\n",s);
4439 if (!(ap = a_ptr[x])) {
4440 printf("?No such array: %s\n",s);
4444 pv[SND_CMD].ival = 0; /* Undo any conflicting ones... */
4445 pv[SND_RES].ival = 0;
4446 pv[SND_CAL].ival = 0;
4447 pv[SND_FIL].ival = 0;
4452 case SND_XPA: /* /TRANSPARENT */
4456 case SND_TYP: /* Only files of given type */
4458 if ((x = cmkey(txtbin,3,"","all",xxstring)) < 0)
4460 pv[n].ival = (x == 2) ? -1 : x;
4464 printf("?Unexpected switch value - %d\n",cmresult.nresult);
4469 debug(F101,"xsend cmresult fcode","",cmresult.fcode);
4472 /* List switch parsing results in debug log */
4473 for (i = 0; i <= SND_MAX; i++) {
4474 ckmakmsg(line,LINBUFSIZ,"xsend switch ",ckitoa(i),NULL,NULL);
4475 debug(F111,line, pv[i].sval, pv[i].ival);
4477 #endif /* COMMENT */
4479 /* Now we have all switches, plus maybe a filename or command, or nothing */
4482 if (protocol != PROTO_K && pv[SND_CMD].ival > 0) {
4483 printf("?Sorry, %s works only with Kermit protocol\n",
4484 (cx == XXCSEN) ? "CSEND" : "SEND /COMMAND");
4488 if (pv[SND_RES].ival > 0 || /* /RECOVER */
4489 pv[SND_STA].wval > 0) { /* or /STARTING */
4490 if (sndfilter || pv[SND_FLT].ival > 0) {
4491 printf("?Sorry, no /RECOVER or /START if SEND FILTER selected\n");
4496 #endif /* PIPESEND */
4504 switch (cmresult.fcode) { /* How did we get out of switch loop */
4505 case _CMIFI: /* Input filename */
4506 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Name */
4507 if (pv[SND_ARR].ival > 0)
4510 wild = cmresult.nresult; /* Wild flag */
4511 if (!recursive && !wild)
4514 case _CMFLD: /* Field */
4515 /* Only allowed with /COMMAND and /ARRAY */
4516 if (pv[SND_CMD].ival < 1 && pv[SND_ARR].ival < 1) {
4519 printf("?Off limits: %s\n",cmresult.sresult);
4522 printf("?%s - \"%s\"\n",
4523 iswild(cmresult.sresult) ?
4524 "No files match" : "File not found",
4530 ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
4531 if (pv[SND_ARR].ival > 0)
4534 case _CMCFM: /* Confirmation */
4539 printf("?Unexpected function code: %d\n",cmresult.fcode);
4543 debug(F110,"xsend string",s,0);
4544 debug(F101,"xsend confirmed","",confirmed);
4546 /* Save and change protocol and transfer mode */
4547 /* Global values are restored in main parse loop */
4549 g_proto = protocol; /* Save current global protocol */
4556 g_prefixing = prefixing;
4559 g_fnspath = fnspath;
4560 g_fnrpath = fnrpath;
4563 if (pv[SND_PRO].ival > -1) { /* Change according to switch */
4564 protocol = pv[SND_PRO].ival;
4565 if (ptab[protocol].rpktlen > -1) /* copied from initproto() */
4566 urpsiz = ptab[protocol].rpktlen;
4567 if (ptab[protocol].spktflg > -1)
4568 spsizf = ptab[protocol].spktflg;
4569 if (ptab[protocol].spktlen > -1) {
4570 spsiz = ptab[protocol].spktlen;
4572 spsizr = spmax = spsiz;
4574 if (ptab[protocol].winsize > -1)
4575 wslotr = ptab[protocol].winsize;
4576 if (ptab[protocol].prefix > -1)
4577 prefixing = ptab[protocol].prefix;
4578 if (ptab[protocol].fnca > -1)
4579 fncact = ptab[protocol].fnca;
4580 if (ptab[protocol].fncn > -1)
4581 fncnv = ptab[protocol].fncn;
4582 if (ptab[protocol].fnsp > -1)
4583 fnspath = ptab[protocol].fnsp;
4584 if (ptab[protocol].fnrp > -1)
4585 fnrpath = ptab[protocol].fnrp;
4587 debug(F101,"xsend protocol","",protocol);
4589 if (pv[SND_NOB].ival > -1) { /* /NOBACKUP (skip backup file) */
4590 g_skipbup = skipbup;
4593 if (pv[SND_REC].ival > 0) /* /RECURSIVE */
4596 if (pv[SND_TYP].ival > -1) { /* /TYPE */
4597 xfiletype = pv[SND_TYP].ival;
4601 g_binary = binary; /* Save global transfer mode */
4603 g_patterns = patterns; /* Save FILE PATTERNS setting */
4604 #endif /* PATTERNS */
4605 if (pv[SND_BIN].ival > 0) { /* Change according to switch */
4606 /* If they said /BINARY they mean /BINARY */
4607 patterns = 0; /* So no pattern-based switching */
4608 g_xfermode = xfermode; /* or automatic transfer mode */
4611 debug(F101,"doxsend /BINARY xfermode","",xfermode);
4612 } else if (pv[SND_TXT].ival > 0) { /* Ditto for /TEXT */
4614 g_xfermode = xfermode;
4617 debug(F101,"doxsend /TEXT xfermode","",xfermode);
4618 } else if (pv[SND_IMG].ival > 0) {
4626 else if (pv[SND_LBL].ival > 0) {
4629 #endif /* CK_LABELED */
4630 debug(F101,"xsend binary","",binary);
4632 if (pv[SND_XPA].ival > 0) /* /TRANSPARENT */
4633 xfrxla = 0; /* Don't translate character sets */
4635 /* Check for legal combinations of switches, filenames, etc */
4638 if (pv[SND_CMD].ival > 0) { /* COMMAND - strip any braces */
4639 debug(F110,"SEND /COMMAND before stripping",s,0);
4641 debug(F110,"SEND /COMMAND after stripping",s,0);
4643 printf("?Sorry, a command to send from is required\n");
4649 #endif /* PIPESEND */
4651 /* Set up /MOVE and /RENAME */
4653 if (pv[SND_DEL].ival > 0 &&
4654 (pv[SND_MOV].ival > 0 || pv[SND_REN].ival > 0)) {
4655 printf("?Sorry, /DELETE conflicts with /MOVE or /RENAME\n");
4660 if (pv[SND_MOV].ival > 0) {
4662 char * p = pv[SND_MOV].sval;
4665 printf("?Sorry, /MOVE-TO not available to guests\n");
4669 #endif /* CK_LOGIN */
4671 if (!isdir(p)) { /* Check directory */
4674 s = (char *)malloc(len + 4);
4676 strcpy(s,p); /* safe */
4678 if (s[len-1] != ':') { s[len++] = ':'; s[len] = NUL; }
4680 if (s[len-1] != '/') { s[len++] = '/'; s[len] = NUL; }
4681 #endif /* datageneral */
4687 printf("?Can't create \"%s\"\n",p);
4693 printf("?Directory \"%s\" not found\n",p);
4696 #endif /* CK_MKDIR */
4698 zfnqfp(p,LINBUFSIZ,tmpbuf);
4699 makestr(&snd_move,tmpbuf);
4701 #endif /* CK_TMPDIR */
4703 if (pv[SND_REN].ival > 0) { /* /RENAME */
4704 char * p = pv[SND_REN].sval;
4707 printf("?Sorry, /RENAME-TO not available to guests\n");
4711 #endif /* CK_LOGIN */
4714 printf("?New name required for /RENAME\n");
4720 /* If name given is wild, rename string must contain variables */
4725 if (!strcmp(tmpbuf,p)) {
4727 "?/RENAME for file group must contain variables such as \\v(filename)\n"
4734 makestr(&snd_rename,p);
4737 /* Handle /RECOVER and /START */
4740 if (pv[SND_RES].ival > 0 && binary != XYFT_B && !filepeek
4745 /* VMS sets text/binary automatically later when it opens the file */
4748 #endif /* PATTERNS */
4750 printf("?Sorry, /BINARY required\n");
4754 if (pv[SND_STA].wval > 0) { /* /START */
4756 printf("?Sorry, wildcards not permitted with /START\n");
4760 if (sizeof(int) < 4) {
4761 printf("?Sorry, this command needs at least 32-bit integers\n");
4766 if (protocol != PROTO_K) {
4767 printf("?Sorry, SEND /START works only with Kermit protocol\n");
4774 if (pv[SND_RES].ival > 0) {
4775 if (protocol != PROTO_K && protocol != PROTO_Z) {
4777 "Sorry, /RECOVER is possible only with Kermit or ZMODEM protocol\n"
4784 #endif /* CK_RESEND */
4786 if (protocol == PROTO_K) {
4787 if ((pv[SND_MAI].ival > 0 || /* MAIL */
4788 pv[SND_PRI].ival > 0 || /* PRINT */
4789 pv[SND_RES].ival > 0 /* RESEND */
4791 (!atdiso || !atcapr)) { /* Disposition attribute off? */
4792 printf("?Sorry, ATTRIBUTE DISPOSITION must be ON\n");
4799 if (wild && (protocol == PROTO_X || protocol == PROTO_XC)) {
4801 "Sorry, you can only send one file at a time with XMODEM protocol\n"
4808 if (!confirmed) { /* CR not typed yet, get more fields */
4810 if (mlist) { /* MSEND or MMOVE */
4811 nfils = 0; /* We already have the first one */
4813 msfiles[nfils++] = line; /* Store pointer */
4814 lp = line + (int)strlen(line) + 1; /* Point past it */
4815 debug(F111,"xsend msend",msfiles[nfils-1],nfils-1);
4816 while (1) { /* Get more filenames */
4818 if ((x = cmifi("Names of files to send, separated by spaces",
4819 "", &s,&y,xxstring)) < 0) {
4822 if ((x = cmcfm()) < 0)
4826 msfiles[nfils++] = lp; /* Got one, count it, point to it, */
4827 p = lp; /* remember pointer, */
4828 while ((*lp++ = *s++)) /* and copy it into buffer */
4829 if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
4830 printf("?MSEND list too long\n");
4835 debug(F111,"xsend msend",msfiles[nfils-1],nfils-1);
4836 if (nfils == 1) fspec[0] = NUL; /* Take care of \v(filespec) */
4838 zfnqfp(p,TMPBUFSIZ,tmpbuf);
4841 if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) {
4842 strcat(fspec,p); /* safe */
4843 strcat(fspec," "); /* safe */
4846 printf("WARNING - \\v(filespec) buffer overflow\n");
4848 debug(F101,"doxsend filespec buffer overflow","",0);
4849 #endif /* COMMENT */
4851 #endif /* NOMSEND */
4852 } else { /* Regular SEND */
4855 if (pv[SND_MAI].ival > 0)
4856 m = (pv[SND_MAI].sval) ?
4857 "e-mail address (optional)" :
4858 "e-mail address (required)";
4859 else if (pv[SND_PRI].ival > 0)
4860 m = "printer options (optional)";
4863 "\nOptional as-name template containing replacement variables \
4864 like \\v(filename)";
4866 m = "Optional name to send it with";
4867 if ((x = cmtxt(m,"",&p,NULL)) < 0)
4870 if (*p) { /* If some text was given... */
4871 p = brstrip(p); /* Replace /AS-NAME: value if any */
4872 if ((y = strlen(p)) > 0) {
4873 if (pv[SND_MAI].ival > 0) {
4874 makestr(&pv[SND_MAI].sval, p);
4876 if (pv[SND_ASN].sval) free(pv[SND_ASN].sval);
4877 pv[SND_ASN].sval = malloc(y+1);
4878 if (pv[SND_ASN].sval) {
4879 strcpy(pv[SND_ASN].sval,p); /* safe */
4880 pv[SND_ASN].ival = 1;
4887 /* Set cmarg2 from as-name, however we got it. */
4889 if (pv[SND_ASN].ival > 0 && pv[SND_ASN].sval && !*cmarg2) {
4892 ckstrncpy(line+x+2,pv[SND_ASN].sval,LINBUFSIZ-x-1);
4894 debug(F110,"doxsend cmarg2",cmarg2,0);
4898 if ((pv[SND_MAI].ival > 0) && (pv[SND_PRI].ival > 0)) {
4899 printf("Sorry, /MAIL and /PRINT are conflicting options\n");
4903 n = 0; /* /MAIL or /PRINT? */
4904 if (pv[SND_MAI].ival > 0)
4906 else if (pv[SND_PRI].ival > 0)
4908 if (n) { /* Yes... */
4915 debug(F111,"xsend",p,n);
4918 if (protocol != PROTO_K) {
4919 printf("Sorry, %s available only with Kermit protocol\n",
4920 (n == SND_MAI) ? "/MAIL" : "/PRINT"
4926 debug(F101,"xsend print/mail wild","",wild);
4927 *optbuf = NUL; /* Wipe out any old options */
4928 s = pv[n].sval; /* mail address or print switch val */
4930 debug(F110,"doxsend mail address or printer options",s,0);
4931 if (n == SND_MAI && !*s) {
4932 printf("?E-mail address required\n");
4935 } else if ((int)strlen(s) > 94) { /* Ensure legal size */
4936 printf("?%s too long\n",
4939 "Print option string"
4944 ckstrncpy(optbuf,s,OPTBUFLEN); /* OK, copy to option buffer */
4945 cmarg = line; /* File to send */
4947 debug(F110,"xsend mailing",cmarg,0);
4948 debug(F110,"xsend address:",optbuf,0);
4951 debug(F110,"xsend printing",cmarg,0);
4952 debug(F110,"xsend options",optbuf,0);
4956 #endif /* NOFRILLS */
4959 if (pv[SND_CAL].wval > 0) { /* Handle /CALIBRATE */
4961 calibrate = pv[SND_CAL].wval * (CK_OFF_T)1024;
4967 #endif /* NOMSEND */
4968 ckstrncpy(line,"CALIBRATION",LINBUFSIZ);
4970 if (!cmarg2) cmarg2 = "";
4971 debug(F110,"doxsend cmarg2 calibrate",cmarg2,0);
4972 } else if (line[0]) {
4974 pv[SND_CAL].ival = 0;
4975 pv[SND_CAL].wval = 0;
4978 #endif /* CALIBRATE */
4980 if (pv[SND_FIL].ival > 0) {
4981 if (confirmed && !calibrate) {
4982 if (zopeni(ZMFILE,pv[SND_FIL].sval) < 1) {
4983 debug(F110,"xsend can't open",pv[SND_FIL].sval,0);
4984 printf("?Failure to open %s\n",filefile);
4988 makestr(&filefile,pv[SND_FIL].sval); /* Open, remember name */
4989 debug(F110,"xsend opened",filefile,0);
4997 if (confirmed && pv[SND_ARR].ival > 0) {
4999 sndxnam[7] = (char)((arrayx == 1) ? 64 : arrayx + ARRAYBASE);
5007 if (confirmed && !line[0] && !filefile && !calibrate) {
5009 if (filehead) { /* OK if we have a SEND-LIST */
5010 nfils = filesinlist;
5011 sndsrc = nfils; /* Like MSEND */
5012 addlist = 1; /* But using a different list... */
5013 filenext = filehead;
5016 #endif /* NOMSEND */
5017 printf("?Filename required but not given\n");
5022 /* Not send-list or array */
5025 addlist = 0; /* Don't use SEND-LIST. */
5027 #endif /* NOMSEND */
5029 if (mlist) { /* MSEND or MMOVE */
5031 cmlist = msfiles; /* List of files to send */
5034 sendstart = (CK_OFF_T)0;
5035 #endif /* NOMSEND */
5038 #endif /* PIPESEND */
5039 } else if (filefile) { /* File contains list of filenames */
5047 } else if (!calibrate && pv[SND_ARR].ival < 1 && pv[SND_CMD].ival < 1) {
5049 nfils = sndsrc = -1; /* Not MSEND, MMOVE, /LIST, or /ARRAY */
5050 if ( /* or /COMMAND */
5053 !rmailf && !rprintf /* Not MAIL or PRINT */
5056 #endif /* NOFRILLS */
5058 CK_OFF_T y = (CK_OFF_T)1;
5061 if (y < (CK_OFF_T)0) {
5062 printf("?Read access denied - \"%s\"\n", s);
5066 if (s != line) /* We might already have done this. */
5067 ckstrncpy(line,s,LINBUFSIZ); /* Copy of string just parsed. */
5069 debug(F110,"doxsend line=s",line,0);
5070 cmarg = line; /* File to send */
5072 zfnqfp(cmarg,fspeclen,fspec);
5074 if (!mlist) { /* For all but MSEND... */
5076 if (pv[SND_CMD].ival > 0) /* /COMMAND sets pipesend flag */
5078 debug(F101,"xsend /COMMAND pipesend","",pipesend);
5079 if (pipesend && filefile) {
5080 printf("?Invalid switch combination\n");
5084 #endif /* PIPESEND */
5087 /* If as-name given and filespec is wild, as-name must contain variables */
5088 debug(F111,"doxsend cmarg2 wild",cmarg2,wild);
5089 if (wild && *cmarg2) {
5092 zzstring(cmarg2,&s,&x);
5093 if (!strcmp(tmpbuf,cmarg2)) {
5095 "?As-name for file group must contain variables such as \\v(filename)\n"
5103 /* Strip braces from as-name */
5104 debug(F110,"xsend cmarg2 before stripping",cmarg2,0);
5105 cmarg2 = brstrip(cmarg2);
5106 debug(F110,"xsend filename",cmarg,0);
5107 debug(F110,"xsend as-name",cmarg2,0);
5109 /* Copy as-name to a safe place */
5115 if ((y = strlen(cmarg2)) > 0) {
5116 asnbuf = (char *) malloc(y + 1);
5118 strcpy(asnbuf,cmarg2); /* safe */
5124 debug(F111,"xsend pv[SND_STA].ival","",pv[SND_STA].ival);
5125 if (pv[SND_STA].wval > (CK_OFF_T)-1) { /* /START position */
5127 printf("?/STARTING-AT may not be used with multiple files.\n");
5131 sendstart = pv[SND_STA].wval;
5133 sendstart = (CK_OFF_T)0;
5134 debug(F101,"xsend /STARTING","",sendstart);
5135 #endif /* CK_RESEND */
5138 sendend: /* Common successful exit */
5140 if (pv[SND_SHH].ival > 0) { /* SEND /QUIET... */
5143 debug(F101,"xsend display","",fdispla);
5146 #ifndef NOSPL /* SEND /ARRAY... */
5147 if (pv[SND_ARR].ival > 0) {
5148 if (!ap) { x = -2; goto xsendx; } /* (shouldn't happen) */
5149 if (range[0] == -1) /* If low end of range not specified */
5150 range[0] = 1; /* default to 1 */
5151 if (range[1] == -1) /* If high not specified */
5152 range[1] = a_dim[arrayx]; /* default to size of array */
5153 if ((range[0] < 0) || /* Check range */
5154 (range[0] > a_dim[arrayx]) ||
5155 (range[1] < range[0]) ||
5156 (range[1] > a_dim[arrayx])) {
5157 printf("?Bad array range - [%d:%d]\n",range[0],range[1]);
5161 sndarray = ap; /* Array pointer */
5162 sndxin = arrayx; /* Array index */
5163 sndxlo = range[0]; /* Array range */
5165 sndxnam[7] = (char)((sndxin == 1) ? 64 : sndxin + ARRAYBASE);
5168 printf("SENDING FROM ARRAY: &%c[]...\n", /* debugging */
5169 (sndxin == 1) ? 64 : sndxin + ARRAYBASE);
5170 printf("Lo=%d\nHi=%d\n", sndxlo, sndxhi);
5171 printf("cmarg=[%s]\ncmarg2=[%s]\n", cmarg, cmarg2);
5172 while ((x = agnbyte()) > -1) {
5176 #endif /* COMMENT */
5180 if (pv[SND_ARR].ival < 1) { /* File selection & disposition... */
5182 if (pv[SND_DEL].ival > 0) /* /DELETE was specified */
5184 debug(F101,"xsend /DELETE","",moving);
5185 if (pv[SND_AFT].ival > 0) /* Copy SEND criteria */
5186 ckstrncpy(sndafter,pv[SND_AFT].sval,19);
5187 if (pv[SND_BEF].ival > 0)
5188 ckstrncpy(sndbefore,pv[SND_BEF].sval,19);
5189 if (pv[SND_NAF].ival > 0)
5190 ckstrncpy(sndnafter,pv[SND_NAF].sval,19);
5191 if (pv[SND_NBE].ival > 0)
5192 ckstrncpy(sndnbefore,pv[SND_NBE].sval,19);
5193 if (pv[SND_EXC].ival > 0)
5194 makelist(pv[SND_EXC].sval,sndexcept,NSNDEXCEPT);
5195 if (pv[SND_SMA].wval > (CK_OFF_T)-1)
5196 sndsmaller = pv[SND_SMA].wval;
5197 if (pv[SND_LAR].wval > (CK_OFF_T)-1)
5198 sndlarger = pv[SND_LAR].wval;
5199 if (pv[SND_NAM].ival > -1) {
5200 g_fncnv = fncnv; /* Save global value */
5201 fncnv = pv[SND_NAM].ival;
5202 debug(F101,"xsend fncnv","",fncnv);
5204 if (pv[SND_PTH].ival > -1) {
5205 g_spath = fnspath; /* Save global values */
5206 fnspath = pv[SND_PTH].ival;
5208 if (fnspath != PATH_OFF) {
5209 g_fncnv = fncnv; /* Bad bad... */
5213 debug(F101,"xsend fnspath","",fnspath);
5214 debug(F101,"xsend fncnv","",fncnv);
5219 if (pv[SND_FLT].ival > 0) {
5220 makestr(&sndfilter,pv[SND_FLT].sval);
5221 debug(F110,"xsend /FILTER", sndfilter, 0);
5223 #endif /* PIPESEND */
5226 /* MOVE not allowed in APCs */
5228 (apcactive == APC_LOCAL || apcactive == APC_REMOTE)
5229 && !(apcstatus & APC_UNCH))
5230 return(success = 0);
5235 protocol == PROTO_K &&
5237 !iks_wait(KERMIT_REQ_START,1)) {
5238 printf("?A Kermit Server is not available to process this command.\n");
5239 printf("?Start a RECEIVE command to complement this command.\n");
5241 #endif /* IKS_OPTION */
5245 if (moving && inserver && isguest) {
5246 printf("?File deletion not allowed for guests.\n");
5249 #endif /* CK_LOGIN */
5252 sstate = 's'; /* Set start state to SEND */
5255 if (pv[SND_RES].ival > 0) /* Send sendmode appropriately */
5256 sendmode = SM_RESEND;
5257 else if (pv[SND_STA].ival > 0)
5258 sendmode = SM_PSEND;
5260 #endif /* CK_RESEND */
5262 sendmode = SM_MSEND;
5269 if (local && pv[SND_SHH].ival != 0) { /* If in local mode, */
5270 displa = 1; /* turn on file transfer display */
5274 xsendx: /* Common exit, including failure */
5275 debug(F101,"doxsend sndsrc","",sndsrc);
5276 for (i = 0; i <= SND_MAX; i++) { /* Free malloc'd memory */
5285 /* D O X C O N N -- CONNECT command parsing with switches */
5288 #define XLIMORTRIGGER
5291 #define XLIMORTRIGGER
5292 #endif /* CK_TRIGGER */
5293 #endif /* XLIMITS */
5296 int tt_idlelimit = 0; /* Terminal idle limit */
5297 int tt_idleact = IDLE_RET; /* Terminal idle action */
5298 #endif /* CKTIDLE */
5300 #ifdef OS2 /* K95 only: */
5302 tt_idlesnd_tmo; /* Idle interval */
5303 int tt_timelimit = 0; /* Time limit, 0 = none */
5304 extern char * /* Parse results - strings: */
5305 tt_idlesnd_str; /* Idle string */
5309 extern char *tt_trigger[];
5310 extern CHAR *tt_trmatch[];
5311 extern char *triggerval;
5312 static char *g_tt_trigger[TRIGGERS];
5313 #endif /* CK_TRIGGER */
5316 static int g_tt_idlesnd_tmo, g_tt_timelimit; /* For saving and restoring */
5317 static int g_tt_idlelimit, g_tt_saved = 0;
5318 static char * g_tt_idlesnd_str; /* global settings */
5321 static struct stringint pv[CONN_MAX+1];
5329 tt_idlelimit = g_tt_idlelimit;
5330 tt_idlesnd_tmo = g_tt_idlesnd_tmo;
5331 tt_timelimit = g_tt_timelimit;
5332 tt_idlesnd_str = g_tt_idlesnd_str;
5338 for (i = 0; i < TRIGGERS; i++)
5339 tt_trigger[i] = g_tt_trigger[i];
5340 #endif /* CK_TRIGGER */
5342 for (i = 0; i <= CONN_MAX; i++) { /* Free malloc'd memory */
5350 doxconn(cx) int cx; {
5351 int c, i, n; /* Workers */
5353 int getval = 0; /* Whether to get switch value */
5354 int async = 0; /* Make an async connect */
5355 struct FDB sw, cm; /* FDBs for each parse function */
5356 extern FILE * tfile[];
5357 extern char * macp[];
5360 g_tt_idlesnd_tmo = tt_idlesnd_tmo; /* Save global settings */
5361 g_tt_timelimit = tt_timelimit;
5362 g_tt_idlelimit = tt_idlelimit;
5363 g_tt_idlesnd_str = tt_idlesnd_str;
5368 if (!tt_trigger[0]) { /* First initialization */
5369 for (i = 1; i < TRIGGERS; i++)
5370 tt_trigger[i] = NULL;
5372 for (i = 0; i < TRIGGERS; i++)
5373 g_tt_trigger[i] = tt_trigger[i];
5378 #endif /* CK_TRIGGER */
5380 for (i = 0; i <= CONN_MAX; i++) { /* Initialize switch values */
5381 pv[i].sval = NULL; /* to null pointers */
5382 pv[i].ival = -1; /* and -1 int values */
5383 pv[i].wval = (CK_OFF_T)-1;
5385 if (cx == XXCQ) /* CQ == CONNECT /QUIETLY */
5386 pv[CONN_NV].ival = 1;
5388 /* Set up chained parse functions... */
5390 cmfdbi(&sw, /* First FDB - command switches */
5392 "Switch", /* hlpmsg */
5394 "", /* addtl string data */
5395 nconntab, /* addtl numeric data 1: tbl size */
5396 4, /* addtl numeric data 2: 4 = cmswi */
5397 xxstring, /* Processing function */
5398 conntab, /* Keyword table */
5399 &cm /* Pointer to next FDB */
5401 cmfdbi(&cm, /* 2nd FDB - Confirmation */
5405 "", /* addtl string data */
5406 0, /* addtl numeric data 1 */
5407 0, /* addtl numeric data 2 */
5413 while (1) { /* Parse 0 or more switches */
5414 x = cmfdb(&sw); /* Parse switch or confirmation */
5415 debug(F101,"doxconn cmfdb","",x);
5416 if (x < 0) { /* Error */
5417 if (x == -9 || x == -2)
5418 printf("?No switches match - \"%s\"\n",atmbuf);
5419 goto xconnx; /* or reparse needed */
5421 if (cmresult.fcode != _CMKEY) /* Break out if not a switch */
5423 c = cmgbrk(); /* Get break character */
5424 getval = (c == ':' || c == '='); /* to see how they ended the switch */
5425 if (getval && !(cmresult.kflags & CM_ARG)) {
5426 printf("?This switch does not take arguments\n");
5430 if (!getval && (cmgkwflgs() & CM_ARG)) {
5431 printf("?This switch requires an argument\n");
5434 n = cmresult.nresult; /* Numeric result = switch value */
5435 debug(F101,"doxconn switch","",n);
5437 switch (n) { /* Process the switch */
5439 case CONN_AS: /* Asynchronous */
5440 pv[CONN_AS].ival = 1;
5441 pv[CONN_SY].ival = 0;
5443 case CONN_SY: /* Synchronous */
5444 pv[CONN_SY].ival = 1;
5445 pv[CONN_AS].ival = 0;
5448 case CONN_NV: /* Non-verbal */
5452 case CONN_II: /* Idle-interval */
5453 case CONN_IL: /* Idle-limit */
5454 case CONN_TL: /* Time-limit */
5456 if ((x = cmnum("Seconds","0",10,&y,xxstring)) < 0)
5460 case CONN_IS: /* Idle-string */
5461 #endif /* XLIMITS */
5463 case CONN_TS: /* Trigger-string */
5464 #endif /* CK_TRIGGER */
5465 #ifdef XLIMORTRIGGER
5467 if ((x = cmfld("String (enclose in braces if it contains spaces)",
5468 "",&s,xxstring)) < 0) {
5470 printf("?String required\n");
5477 if ((y = strlen(s)) > 0) {
5478 if (pv[n].sval) free(pv[n].sval);
5479 pv[n].sval = malloc(y+1);
5481 strcpy(pv[n].sval,s); /* safe */
5486 #endif /* XLIMORTRIGGER */
5488 printf("?Unexpected switch value - %d\n",cmresult.nresult);
5493 debug(F101,"doxconn cmresult.fcode","",cmresult.fcode);
5494 if (cmresult.fcode != _CMCFM) {
5495 printf("?Unexpected function code: %d\n",cmresult.fcode);
5500 /* Command was confirmed so we can pre-pop command level. */
5501 /* This is so CONNECT module won't think we're executing a script */
5502 /* if CONNECT was the final command in the script. */
5507 #ifdef OS2 /* Make results available globally */
5508 if (pv[CONN_IL].ival > -1) /* Idle limit */
5509 tt_idlelimit = pv[CONN_IL].ival;
5510 if (pv[CONN_II].ival > -1) /* Idle limit */
5511 tt_idlesnd_tmo = pv[CONN_II].ival;
5512 if (pv[CONN_IS].sval) /* Idle string */
5513 if (tt_idlesnd_str = (char *)malloc((int)strlen(pv[CONN_IS].sval)+1))
5514 strcpy(tt_idlesnd_str,pv[CONN_IS].sval); /* safe */
5515 if (pv[CONN_TL].ival > -1) /* Session limit */
5516 tt_timelimit = pv[CONN_TL].ival;
5517 async = (pv[CONN_AS].ival > 0 ||
5518 pv[CONN_SY].ival <= 0 && cmdlvl == 0) ? 1 : 0;
5522 if (pv[CONN_TS].sval) /* Trigger strings */
5523 makelist(pv[CONN_TS].sval,tt_trigger,TRIGGERS);
5524 for (i = 0; i < TRIGGERS; i++) /* Trigger match pointers */
5525 tt_trmatch[i] = NULL;
5526 if (triggerval) { /* Reset trigger value */
5530 #endif /* CK_TRIGGER */
5535 The previous connection was through the external ssh client and now, with
5536 that connection closed, the user says "connect" and expects a new connection
5537 to be made to the same host, because that's how all the other connection
5538 methods work, so (and this is quite a hack)...
5540 if (!ckstrcmp("ssh ",ttname,4,0)) { /* Previous "host" was "ssh blah" */
5541 _PROTOTYP (int redossh, ( void ) );
5543 if (ttyfd < 0) { /* And connection is no longer open */
5545 xx = redossh(); /* So redo the SSH connection */
5546 if (xx < 0) return(xx);
5551 x = doconect((pv[CONN_NV].ival > 0) ? 1 : 0, async);
5554 debug(F101,"doxconn doconect returns","",x);
5555 if ((xx = ttchk()) < 0) dologend();
5556 debug(F101,"doxconn ttchk returns","",xx);
5560 debug(F111,"doxconn doconect triggerval",triggerval,x);
5561 #endif /* CK_TRIGGER */
5564 /* Back from CONNECT -- Restore global settings */
5569 success = (x > 0) ? 1 : 0;
5572 #endif /* NOLOCAL */
5575 /* cx == XXADD or XXREMV */
5576 /* fc == ADD_BIN or ADD_TXT */
5578 doadd(cx,fc) int cx, fc; {
5580 char * tmp[FTPATTERNS];
5582 int i, j, k, n = 0, x = 0, last;
5584 #endif /* PATTERNS */
5585 if (cx != XXADD && cx != XXREMV) {
5586 printf("?Unexpected function code: %d\n",cx);
5590 while (n < FTPATTERNS) { /* Collect new patterns */
5592 if ((x = cmfld("Pattern","",&s,xxstring)) < 0)
5594 ckstrncpy(line,s,LINBUFSIZ);
5596 makestr(&(tmp[n++]),s);
5602 p = (fc == ADD_BIN) ? binpatterns : txtpatterns; /* Which list */
5604 for (i = 0; i < FTPATTERNS; i++) { /* Find last one in list */
5610 if (cx == XXADD) { /* Adding */
5611 if (last + n > FTPATTERNS) { /* Check if too many */
5612 printf("?Too many patterns - %d is the maximum\n", FTPATTERNS);
5615 for (i = 0; i < n; i++) { /* Copy in the new ones. */
5616 for (j = 0, x = 0; x == 0 && j < last ; j++ )
5617 x = !ckstrcmp(tmp[i],p[j],-1,filecase); /* match */
5619 makestr(&(p[last++]),tmp[i]);
5621 makestr(&(p[last]),NULL); /* Null-terminate the list */
5623 goto xdoadd; /* Done */
5624 } else if (cx == XXREMV) { /* Remove something(s) */
5626 if (last == 0) /* List is empty */
5627 goto xdoadd; /* Nothing to remove */
5628 for (i = 0; i < n; i++) { /* i = Patterns they typed */
5629 for (j = 0; j < last; j++) { /* j = Patterns in list */
5630 /* Change this to ckstrcmp()... */
5632 x = !ckstrcmp(tmp[i],p[j],-1,filecase); /* match */
5634 x = ckstrcmp(tmp[i],p[j],-1,0); /* Case-independent match */
5635 if (x) { /* This one matches */
5636 makestr(&(p[j]),NULL); /* Free it */
5637 for (k = j; k < last; k++) /* Move the rest up */
5639 p[k] = NULL; /* Erase last one */
5646 xdoadd: /* Common exit */
5647 for (i = 0; i < n; i++)
5651 #endif /* PATTERNS */
5657 addsend(cx) int cx; {
5659 extern struct keytab fttab[];
5661 struct filelist * flp;
5665 #endif /* NOMSEND */
5668 printf("?Sorry, ADD/REMOVE SEND-LIST not available.\n");
5670 #endif /* NOMSEND */
5672 printf("?Sorry, REMOVE SEND-LIST not implemented yet.\n");
5676 #ifndef XYZ_INTERNAL
5677 if (protocol != PROTO_K) {
5678 printf("?Sorry, ADD SEND-LIST does not work with external protocols\n");
5681 #endif /* XYZ_INTERNAL */
5683 x = cmifi("File specification to add","", &s,&y,xxstring);
5686 printf("?A file specification is required\n");
5691 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
5693 if (filesinlist == 0) /* Take care of \v(filespec) */
5695 zfnqfp(s,LINBUFSIZ,line);
5697 if (((int)strlen(fspec) + (int)strlen(s) + 1) < fspeclen) {
5698 strcat(fspec,s); /* safe */
5699 strcat(fspec," "); /* safe */
5701 printf("WARNING - \\v(filespec) buffer overflow\n");
5705 if ((patterns || filepeek) /* FILE PATTERNS or SCAN is ON */
5707 && binary != XYFT_L /* And not if FILE TYPE LABELED */
5708 #endif /* CK_LABELED */
5710 && binary != XYFT_I /* or FILE TYPE IMAGE */
5715 k = scanfile(line,&x,nscanfile);
5716 if (k > 0) xbinary = (k == FT_BIN) ? XYFT_B : XYFT_T;
5718 fmode = gfmode(xbinary,0);
5719 if ((x = cmkey(fttab,nfttyp,
5720 "type of file transfer", fmode, xxstring)) < 0)
5726 "\nAs-name template containing replacement variables such as \\v(filename)" :
5727 "Name to send it with", "",&s,NULL)) < 0)
5735 if (!strcmp(tmpbuf,s)) {
5737 "?As-name for file group must contain variables such as \\v(filename)\n"
5743 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
5746 if ((x = cmcfm()) < 0)
5748 flp = (struct filelist *) malloc(sizeof(struct filelist));
5751 filetail->fl_next = flp;
5755 x = (int) strlen(line); /* Length of filename */
5756 s = (char *) malloc(x + 1);
5758 strcpy(s,line); /* safe */
5760 flp->fl_mode = xmode;
5761 x = (int) strlen(cmarg2); /* Length of as-name */
5763 flp->fl_alias = NULL;
5765 s = (char *) malloc(x + 1);
5767 strcpy(s,cmarg2); /* safe */
5770 printf("Sorry, can't allocate space for as-name");
5774 flp->fl_next = NULL;
5775 filesinlist++; /* Count this node */
5776 return(success = 1); /* Finished adding this node */
5778 printf("Sorry, can't allocate space for name");
5782 printf("Sorry, can't allocate file list node");
5785 #endif /* NOMSEND */
5789 #ifndef NOHTTP /* HTTP ops... */
5791 #define HTTP_GET 0 /* GET */
5792 #define HTTP_PUT 1 /* PUT */
5793 #define HTTP_POS 2 /* POST */
5794 #define HTTP_IDX 3 /* INDEX */
5795 #define HTTP_HED 4 /* HEAD */
5796 #define HTTP_DEL 5 /* DELETE */
5797 #define HTTP_CON 6 /* CONNECT */
5798 #define HTTP_OPN 7 /* OPEN */
5799 #define HTTP_CLS 8 /* CLOSE */
5801 static struct keytab httptab[] = {
5802 { "close", HTTP_CLS, 0 },
5803 { "connect", HTTP_CON, 0 },
5804 { "delete", HTTP_DEL, 0 },
5805 { "get", HTTP_GET, 0 },
5806 { "head", HTTP_HED, 0 },
5807 { "index", HTTP_IDX, 0 },
5808 { "open", HTTP_OPN, 0 },
5809 { "put", HTTP_PUT, 0 },
5810 { "post", HTTP_POS, 0 }
5812 static int nhttptab = sizeof(httptab)/sizeof(struct keytab);
5815 #define HT_SW_AG 0 /* /AGENT */
5816 #define HT_SW_HD 1 /* /HEADER */
5817 #define HT_SW_US 2 /* /USER */
5818 #define HT_SW_PW 3 /* /PASSWORD */
5819 #define HT_SW_AR 4 /* /ARRAY */
5820 #define HT_SW_TP 5 /* /TOSCREEN */
5822 static struct keytab httpswtab[] = {
5823 { "/agent", HT_SW_AG, CM_ARG },
5825 { "/array", HT_SW_AR, CM_ARG },
5827 { "/header", HT_SW_HD, CM_ARG },
5828 { "/password", HT_SW_PW, CM_ARG },
5829 { "/toscreen", HT_SW_TP, 0 },
5830 { "/user", HT_SW_US, CM_ARG },
5833 static int nhttpswtab = sizeof(httpswtab)/sizeof(struct keytab) - 1;
5835 /* HTTP PUT/POST switches */
5836 #define HT_PP_MT 0 /* /MIME-TYPE */
5838 static struct keytab httpptab[] = {
5839 { "/mime-type", HT_PP_MT, CM_ARG },
5842 static int nhttpptab = sizeof(httpptab)/sizeof(struct keytab) - 1;
5844 #define HTTP_MAXHDR 8
5847 xdohttp(action, lfile, rf, dfile, agent, hdr, user, pass, mime, array, type)
5849 char *lfile, *rf, *dfile, *agent, *hdr, *user, *pass, *mime, array;
5853 char * hdrlist[HTTP_MAXHDR];
5854 char rfile[CKMAXPATH+1];
5857 /* Check for a valid state to execute the command */
5859 printf("?The HTTP command may not be used from the IKS\r\n");
5860 } else if (httpfd == -1) {
5861 if (http_reopen() < 0)
5862 printf("?No connection\n");
5869 /* If the command is not valid, exit with failure */
5871 return(success = 0);
5873 if (action != HTTP_CON && rf[0] != '/') {
5875 ckstrncpy(&rfile[1],rf,CKMAXPATH);
5877 ckstrncpy(rfile,rf,CKMAXPATH);
5879 for (i = 0; i < HTTP_MAXHDR; i++) /* Initialize header list */
5881 makelist(hdr,hdrlist,HTTP_MAXHDR); /* Make header list */
5884 for (i = 0; i < nhttptab; i++) /* Find action keyword */
5885 if (httptab[i].kwval == action)
5887 if (i == nhttptab) { /* Shouldn't happen... */
5888 printf("?Invalid action - %d\n",action);
5889 return(0); /* Failure */
5892 printf("HTTP action: %s\n",httptab[i].kwd);
5893 printf(" Agent: %s\n",agent ? agent : "(null)");
5896 printf(" Header list: 1. %s\n",hdrlist[0]);
5897 for (i = 1; i < HTTP_MAXHDR && hdrlist[i]; i++)
5898 printf("%15d. %s\n",i+1,hdrlist[i]);
5900 printf(" Header: %s\n",hdrlist[0] ? hdrlist[0] : "(null)");
5902 printf(" User: %s\n",user ? user : "(null)");
5904 printf(" Password: %s\n",pass ? pass : "(null)");
5905 #endif /* COMMENT */
5909 printf(" Array: \\%%%c[]\n", array);
5911 printf(" Array: (none)\n");
5914 if (action == HTTP_PUT || action == HTTP_POS)
5915 printf(" Mime-type: %s\n",mime ? mime : "(null)");
5917 printf(" Local file: %s\n",lfile ? lfile : "(null)");
5918 printf(" Remote file: %s\n",rfile ? rfile : "(null)");
5919 printf(" Destination file: %s\n",dfile ? dfile : "(null)");
5920 #endif /* BETADEBUG */
5922 /* The http_xxxx() functions return 0 on success, -1 on failure */
5926 rc = http_connect(httpfd,agent,hdrlist,user,pass,array,rfile);
5930 rc = http_delete(agent,hdrlist,user,pass,array,rfile);
5933 rc = http_get(agent,hdrlist,user,pass,array,lfile,rfile,type);
5936 rc = http_head(agent,hdrlist,user,pass,array,lfile,rfile,type);
5939 rc = http_put(agent,hdrlist,mime,user,pass,array,lfile,rfile,dfile,
5943 rc = http_post(agent,hdrlist,mime,user,pass,array,lfile,rfile,dfile,
5947 rc = http_index(agent,hdrlist,user,pass,array,lfile,rfile,type);
5952 return(rc == 0 ? 1 : 0); /* Success is set by caller */
5954 #endif /* TCPSOCKET */
5957 #ifndef NOSPL /* ARRAY ops... */
5958 static struct keytab arraytab[] = {
5959 { "clear", ARR_CLR, 0 },
5960 { "copy", ARR_CPY, 0 },
5961 { "dcl", ARR_DCL, CM_INV },
5962 { "declare", ARR_DCL, 0 },
5963 { "destroy", ARR_DST, CM_INV },
5964 { "equate", ARR_EQU, CM_INV },
5965 { "link", ARR_EQU, 0 },
5966 { "resize", ARR_RSZ, 0 },
5967 { "set", ARR_SET, 0 },
5969 { "show", ARR_SHO, 0 },
5971 { "sort", ARR_SRT, 0 },
5972 { "undeclare", ARR_DST, 0 },
5975 static int narraytab = sizeof(arraytab)/sizeof(struct keytab) - 1;
5978 static struct keytab learnswi[] = {
5983 #endif /* CKLEARN */
5986 arrayitoa(x) int x; { /* Array index to array letter */
5989 else if (x < 0 || x > (122 - ARRAYBASE))
5992 return(x + ARRAYBASE);
5996 arrayatoi(c) int c; { /* Array letter to array index */
5999 if (c > 63 && c < 91)
6001 if (c < ARRAYBASE || c > 122)
6003 return(c - ARRAYBASE);
6006 static int /* Declare an array */
6008 int i, n, v, lo, hi, rc = 0;
6012 char tmp[64]; /* Local temporary string buffer */
6013 if ((y = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
6015 printf("?Array name required\n");
6019 ckstrncpy(line,s,LINBUFSIZ);
6021 x = arraybounds(s,&lo,&hi); /* Check syntax and get bounds */
6022 debug(F111,"dodcl arraybounds",s,x);
6023 if (x < 0) { /* Error - Maybe it's a variable */
6024 char * p; /* whose value is an array name */
6029 if (s[0] == CMDQ && s[1] == '&')
6031 if (zzstring(s,&p,&n) > -1) {
6033 x = arraybounds(s,&lo,&hi);
6034 debug(F111,"dodcl arraybounds 2",s,x);
6037 printf("?Bad array name - \"%s\"\n",s);
6041 debug(F101,"dodcl hi","",hi);
6042 debug(F101,"dodcl lo","",lo);
6043 debug(F101,"dodcl lo+1","",lo+1);
6045 if (lo == -1 && hi == -1) { /* Have good array name and bounds */
6048 } else if (hi > -1) {
6049 printf("?Segment notation not allowed in array declarations\n");
6051 } else if ((lo+1) < 0) {
6052 debug(F101,"dodcl underflow","",lo+1);
6053 printf("?Dimension underflow\n");
6058 if (cx == XXUNDCL) {
6061 if ((y = cmcfm()) < 0)
6064 p = (char **)malloc(sizeof(char **)*(n+1));
6066 printf("?Memory allocation error\n");
6069 v = 0; /* Highest initialized member */
6070 p[0] = NULL; /* Element 0 */
6072 while (n > 0 && v < n) { /* Parse initializers */
6076 "Initial value for \\&",
6081 NULL,NULL,NULL,NULL,NULL,NULL,NULL
6084 rc = cmfld((char *)tmp,"",&s,xxstring); /* Get field */
6085 if (rc < 0) { /* Error... */
6086 if (rc == -3) { /* Empty element */
6087 if (cmflgs == 1) /* because end of line? */
6088 break; /* Yes, done initializing */
6089 else /* No, it's just empty */
6090 continue; /* Go on to next one. */
6091 } else { /* Other parse error */
6092 goto dclx; /* Go free temp pointers */
6096 if (v == 0 && !strcmp(s,"=")) /* Skip the = sign. */
6098 s = brstrip(s); /* Strip any braces */
6099 makestr(&(p[++v]),s);
6102 if ((y = cmtxt("Carriage return to confirm","",&s,NULL)) < 0)
6107 if (dclarray((char)x,n) < 0) { /* Declare the array */
6108 printf("?Declare failed\n");
6111 for (i = 1; i <= v; i++) { /* Add any initial values */
6113 ckmakmsg(&tmp[1],63,ckctoa((char)x),"[",ckitoa(i),"]");
6114 if (addmac(tmp,p[i]) < 0) {
6115 printf("Array initialization error: %s %s\n",tmp,p[i]);
6122 for (i = 1; i <= v; i++)
6123 if (p[i]) free(p[i]);
6126 debug(F101,"DCL rc","",rc);
6127 return(success = rc);
6132 int i, x, y, n, lo, hi, islink = -1;
6133 char c, * s, ** ap = NULL;
6134 if ((x = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
6136 printf("?Array name required\n");
6140 ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of name */
6142 x = arraybounds(s,&lo,&hi);
6143 if (x < 0) { /* Parse the name, get index */
6144 printf("?Bad array reference - \"%s\"\n", s);
6147 if (lo < 0 && hi < 0) {
6148 y = cmnum("New size","",10,&lo,xxstring);
6151 printf("?New size required\n");
6155 if ((y = cmcfm()) < 0)
6157 if (a_link[x] > -1) { /* Link? */
6158 islink = x; /* Yes follow it */
6159 x = a_link[x]; /* and remember */
6162 printf("?Array not declared - \"%s\"\n", s);
6166 printf("?New size required\n");
6170 printf("?Array segments not allowed for this operation\n");
6173 c = arrayitoa(x); /* Get array letter */
6174 if (c == '@') { /* Argument vector array off limits */
6175 printf("?Sorry, \\&@[] is read-only\n");
6178 if (lo == 0) { /* If new size is 0... */
6179 dclarray(c,0); /* Undeclare the array */
6180 return(success = 1);
6182 n = a_dim[x]; /* Current size */
6183 ap = (char **) malloc((lo+1) * sizeof(char *)); /* New array */
6184 y = (n < lo) ? n : lo;
6185 for (i = 0; i <= y; i++) /* Copy the part that fits */
6186 ap[i] = a_ptr[x][i];
6187 if (n < lo) { /* If original array smaller */
6188 for (; i <= lo; i++) /* initialize extra elements in */
6189 ap[i] = NULL; /* new array to NULL. */
6190 } else if (n > lo) { /* If new array smaller */
6191 for (; i <= lo; i++) /* deallocate leftover elements */
6192 makestr(&(a_ptr[x][i]),NULL); /* from original array. */
6194 free((char *)a_ptr[x]); /* Free original array list */
6195 a_ptr[x] = ap; /* Replace with new one */
6196 a_dim[x] = lo; /* Record the new dimension */
6197 if (islink > -1) { /* Was this a link? */
6198 a_ptr[islink] = ap; /* If so point to the resized array */
6200 } else { /* If not are there links to here? */
6201 for (i = 0; i < (int) 'z' - ARRAYBASE; i++) { /* Any linked arrays? */
6202 if (i != x && a_link[i] == x) { /* Find and update them */
6208 return(success = 1);
6213 int i, j, x1, lo1, hi1, x2, lo2, hi2, whole = 0;
6214 char c1, c2, * a1, * a2;
6215 if ((y = cmfld("Name of source array","",&s,NULL)) < 0)
6217 ckstrncpy(line,s,LINBUFSIZ);
6219 if ((x1 = arraybounds(a1,&lo1,&hi1)) < 0) {
6220 printf("?Bad array reference - \"%s\"\n", a1);
6222 } else if (!a_ptr[x1]) {
6223 printf("?Array not declared - \"%s\"\n", a1);
6228 if ((y = cmfld("Name of destination array","",&s,NULL)) < 0)
6230 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
6232 if ((x2 = arraybounds(a2,&lo2,&hi2)) < 0) {
6233 printf("?Bad array reference - \"%s\"\n", a2);
6238 if ((x = cmcfm()) < 0)
6241 if (c2 == '@') { /* Argument vector array off limits */
6242 printf("?Sorry, \\&@[] is read-only\n");
6245 if (lo1 < 0 && lo2 < 0 && hi1 < 0 && hi2 < 0) /* Special case for */
6246 whole = 1; /* whole array... */
6248 if (lo1 < 0) lo1 = whole ? 0 : 1; /* Supply lower bound of source */
6249 if (hi1 < 0) hi1 = a_dim[x1]; /* Supply upper bound of source */
6250 if (lo2 < 0) lo2 = whole ? 0 : 1; /* Lower bound of target */
6251 if (hi2 < 0) hi2 = lo2 + hi1 - lo1; /* Upper bound of target */
6252 if (a_ptr[x2]) { /* Target array is already declared? */
6253 if (hi2 > a_dim[x2]) /* If upper bound out of range */
6254 hi2 = a_dim[x2]; /* shrink to fit */
6255 } else { /* Otherwise... */
6256 x2 = dclarray(c2, hi2); /* declare the target array */
6258 for (i = lo1, j = lo2; i <= hi1 && j <= hi2; i++,j++) { /* Copy */
6259 makestr(&(a_ptr[x2][j]),a_ptr[x1][i]);
6261 return(success = 1);
6264 static int /* Undeclare an array */
6266 int x, y, n, rc = 0;
6269 if ((y = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
6271 printf("?Array name required\n");
6275 ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of name */
6277 if ((y = cmcfm()) < 0)
6279 if ((x = arraybounds(s,&y,&n)) < 0) { /* Parse the name, get index */
6280 printf("?Bad array reference - \"%s\"\n", s);
6283 if (y > 0 || n > 0) {
6284 printf("?Partial arrays can not be destroyed\n");
6287 c = arrayitoa(x); /* Get array letter */
6288 if (a_ptr[x]) { /* If array is declared */
6289 if (c == '@') { /* Argument vector array off limits */
6290 printf("?Sorry, \\&@[] is read-only\n");
6293 rc = dclarray(c,-1); /* Undeclare the array */
6294 } else /* It wasn't declared */
6296 if (rc > -1) { /* Set return code and success */
6301 printf("?Failed - destroy \"\\&%c[]\"\n", c);
6308 clrarray(cx) int cx; {
6310 char c, * s, * val = NULL;
6312 if ((x = cmfld("Array name","",&s,NULL)) < 0) { /* Parse array name */
6314 printf("?Array name required\n");
6318 ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of name */
6320 if (cx == ARR_SET) { /* SET */
6321 if ((x = cmtxt("Value","",&val,xxstring)) < 0)
6323 ckstrncpy(tmpbuf,val,TMPBUFSIZ); /* Value to set */
6325 if (!*val) val = NULL;
6326 } else if ((x = cmcfm()) < 0) /* CLEAR */
6329 if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Parse the name */
6330 printf("?Bad array reference - \"%s\"\n", s);
6333 c = arrayitoa(x); /* Get array letter */
6334 if (!a_ptr[x]) { /* If array is declared */
6335 printf("?Array %s is not declared\n", s);
6337 } else if (c == '@') { /* Argument vector array off limits */
6338 printf("?Sorry, \\&@[] is read-only\n");
6342 if (hi < 0) hi = a_dim[x];
6343 for (i = lo; i <= hi; i++) /* Clear/Set selected range */
6344 makestr(&(a_ptr[x][i]),val);
6346 return(success = 1);
6349 extern char **aa_ptr[CMDSTKL][28];
6350 extern int aa_dim[CMDSTKL][28];
6352 static int /* Create symbolic link to an array */
6354 int i = 0, x, y, lo, hi, flag = 0;
6357 if ((x = cmfld("Array name not currently in use","",&s,NULL)) < 0) {
6359 printf("?Array name required\n");
6363 ckstrncpy(line,s,LINBUFSIZ); /* Make safe copy of link name */
6365 if ((x = cmfld("Name of existing array","",&p,xxstring)) < 0) {
6367 printf("?Array name required\n");
6371 ckstrncpy(tmpbuf,p,TMPBUFSIZ); /* Make safe copy of array name */
6373 if ((x = cmcfm()) < 0)
6376 if ((x = arraybounds(s,&lo,&hi)) < 0) { /* Parse the link name */
6377 printf("?Bad array reference - \"%s\"\n", s);
6380 if (a_ptr[x]) { /* Must not already exist */
6382 printf("?Array already exists: \\&%c[]\n", c);
6385 if (lo > -1 || hi > -1) {
6386 printf("?Sorry, whole arrays only: %s\n",s);
6389 if ((y = arraybounds(p,&lo,&hi)) < 0) { /* Parse the array name */
6390 printf("?Bad array reference - \"%s\"\n", s);
6393 if (lo > -1 || hi > -1) {
6394 printf("?Sorry, whole arrays only: %s\n",p);
6398 for (i = cmdlvl; i >= 0; i--)
6405 a_ptr[x] = aa_ptr[i][y]; /* Link to saved copy */
6406 a_dim[x] = aa_dim[i][y];
6407 } else { /* Otherwise... */
6408 c = arrayitoa(y); /* Check if it's declared */
6410 printf("?Array is not declared: \\&%c[]\n", c);
6413 if (a_link[y] > -1) { /* And if it's a link itself */
6414 printf("?Links to links not allowed: \\&%c[]\n", c);
6417 a_ptr[x] = a_ptr[y]; /* All OK, make the link */
6418 a_dim[x] = a_dim[y];
6421 return(success = 1);
6426 static char * dcsetname = NULL;
6428 /* Get Display Character-Set Name */
6435 extern int tt_font, ntermfont;
6436 extern struct keytab term_font[];
6437 #endif /* PCFONTS */
6441 y = os2getcp(); /* Default is current code page */
6443 case 437: s = "cp437"; break;
6444 case 850: s = "cp850"; break;
6445 case 852: s = "cp852"; break;
6446 case 857: s = "cp857"; break;
6447 case 858: s = "cp858"; break;
6448 case 862: s = "cp862"; break;
6449 case 866: s = "cp866"; break;
6450 case 869: s = "cp869"; break;
6451 case 1250: s = "cp1250"; break;
6452 case 1251: s = "cp1251"; break;
6453 case 1252: s = "cp1252"; break;
6454 case 1253: s = "cp1253"; break;
6455 case 1254: s = "cp1254"; break;
6456 case 1255: s = "cp1255"; break;
6457 case 1256: s = "cp1256"; break;
6458 case 1257: s = "cp1257"; break;
6459 case 1258: s = "cp1258"; break;
6463 If the user has loaded a font with SET TERMINAL FONT then we want
6464 to change the default code page to the font that was loaded.
6466 if (tt_font != TTF_ROM) {
6467 for (y = 0; y < ntermfont; y++ ) {
6468 if (term_font[y].kwval == tt_font) {
6469 s = term_font[y].kwd;
6474 #endif /* PCFONTS */
6477 /* Hack not needed as of C-Kermit 7.1 */
6478 if (fcharset == FC_1LATIN) {
6479 s = "latin1-iso"; /* Hack to avoid reporting "cp1252" */
6480 } else { /* Report current file character set */
6481 #endif /* COMMENT */
6482 for (y = 0; y <= nfilc; y++)
6483 if (fcstab[y].kwval == fcharset) {
6489 #endif /* COMMENT */
6491 makestr(&dcsetname,s); /* Return stable pointer */
6492 return((char *)dcsetname);
6494 #endif /* NOCSETS */
6499 if ((x = cmkey(clrtab,nclear,"item to clear",
6505 ,xxstring)) < 0) return(x);
6508 if (x == CLR_CMD || x == CLR_TRM) {
6509 if ((z = cmkey(clrcmdtab,nclrcmd,"how much screen to clear\n",
6510 "all",xxstring)) < 0)
6515 if ((y = cmcfm()) < 0)
6518 /* Clear device input buffer if requested */
6519 y = (x & CLR_DEV) ? ttflui() : 0;
6521 if (x & CLR_SCR) /* CLEAR SCREEN */
6522 y = ck_cls(); /* (= SCREEN CLEAR = CLS) */
6524 if (x & CLR_KBD) { /* CLEAR KEYBOARD */
6528 while (n-- > 0 && (y = coninc(0) > -1))
6530 y = (y > -1) ? 0 : -1;
6534 /* Clear INPUT command buffer if requested */
6536 for (z = 0; z < inbufsize; z++)
6543 debug(F101,"Executing CLEAR APC","",apcactive);
6555 if (x & (CLR_TXT|CLR_BIN)) {
6557 for (i = 0; i < FTPATTERNS; i++) {
6559 makestr(&txtpatterns[i],NULL);
6561 makestr(&binpatterns[i],NULL);
6565 #endif /* PATTERNS */
6575 if (x & CLR_SFL) { /* CLEAR SEND-LIST */
6577 struct filelist * flp, * next;
6583 free(flp->fl_alias);
6584 next = flp->fl_next;
6595 #endif /* NOMSEND */
6601 clearscrollback(VTERM);
6609 clrboscr_escape(VCMD,SP);
6612 clrbol_escape(VCMD,SP);
6618 clreoscr_escape(VCMD,SP);
6621 clrline_escape(VCMD,SP);
6624 clearscrollback(VCMD);
6627 printf("Not implemented yet, sorry.\n");
6636 if (VscrnGetBufferSize(VTERM) > 0 ) {
6637 VscrnScroll(VTERM, UPWARD, 0,
6638 VscrnGetHeight(VTERM)-(tt_status[VTERM]?2:1),
6639 VscrnGetHeight(VTERM) -
6640 (tt_status[VTERM]?1:0), TRUE, SP
6642 cleartermscreen(VTERM);
6646 clrboscr_escape(VTERM,SP);
6649 clrbol_escape(VTERM,SP);
6652 clrtoeoln(VTERM,SP);
6655 clreoscr_escape(VTERM,SP);
6658 clrline_escape(VTERM,SP);
6661 clearscrollback(VTERM);
6664 printf("Not implemented yet, sorry.\n");
6671 #endif /* NOLOCAL */
6673 return(success = (y == 0));
6675 #endif /* NOFRILLS */
6679 doeval(cx) int cx; {
6681 char vnambuf[VNAML], * vnp = NULL; /* These must be on the stack */
6683 if ((y = cmfld("Variable name","",&s,
6684 ((cx == XX_EVAL) ? xxstring : NULL))) < 0) {
6686 printf("?Variable name required\n");
6690 ckstrncpy(vnambuf,s,VNAML); /* Make a copy. */
6692 if (vnambuf[0] == CMDQ &&
6693 (vnambuf[1] == '%' || vnambuf[1] == '&'))
6696 if (*vnp == '%' || *vnp == '&') {
6697 if ((y = parsevar(vnp,&x,&z)) < 0)
6701 if ((x = cmtxt("Integer arithmetic expression","",&s,xxstring)) < 0)
6707 ckstrncpy(evalbuf,p,32);
6709 return(success = addmac(vnambuf,p));
6711 return(success = *p ? 1 : 0);
6718 if ((x = cmkey(telcmd, ntelcmd, "TELNET command", "", xxstring)) < 0 )
6725 if ((y = cmkey(tnopts,ntnopts,"TELNET option","",xxstring)) < 0)
6727 if ((z = cmcfm()) < 0) return(z);
6731 if (TELOPT_UNANSWERED_WILL(y))
6732 return(success = 0);
6735 if (TELOPT_UNANSWERED_WONT(y))
6736 return(success = 0);
6739 if (TELOPT_UNANSWERED_DO(y))
6740 return(success = 0);
6743 if (TELOPT_UNANSWERED_DONT(y))
6744 return(success = 0);
6748 success = ((tn_sopt(x,y) > -1) ? 1 : 0);
6750 printf("ff%02x%02x\n",x,y);
6756 TELOPT_UNANSWERED_WILL(y) = 1;
6760 TELOPT_UNANSWERED_WONT(y) = 1;
6763 TELOPT_UNANSWERED_DO(y) = 1;
6767 TELOPT_UNANSWERED_DONT(y) = 1;
6770 if (tn_wait("XXTELOP") < 0) {
6777 if ((y=cmkey(tnsbopts,ntnsbopts,"TELNET option","",xxstring)) < 0)
6781 /* Some compilers require switch() to have at least 1 case */
6783 TELOPT_SB(TELOPT_NAWS).naws.x = 0;
6784 TELOPT_SB(TELOPT_NAWS).naws.y = 0;
6786 return(success = ((tn_snaws() > -1) ? 1 : 0));
6788 return(success = 0);
6790 return(success = 0);
6791 #endif /* CK_NAWS */
6793 return(success = 0);
6798 success = (kerberos5_forward() == AUTH_SUCCESS);
6801 #endif /* CK_KERBEROS */
6804 if ((z = cmcfm()) < 0) return(z);
6808 if (network && IS_TELNET()) { /* TELNET */
6809 temp[0] = (CHAR) IAC;
6812 success = (ttol((CHAR *)temp,2) > -1 ? 1 : 0);
6813 if (tn_deb || debses || deblog) {
6814 /* TN_MSG_LEN is in ckctel.h */
6815 ckmakmsg(tn_msg,256,"TELNET SENT ",TELCMD(x),NULL,NULL);
6816 debug(F101,tn_msg,"",x);
6817 if (debses || tn_deb) tn_debug(tn_msg);
6821 return(success = 0);
6823 #endif /* NOLOCAL */
6824 printf("ff%02x\n",x);
6825 return(success = 1);
6828 #endif /* NOLOCAL */
6842 s = getenv("EDITOR");
6843 if (s) ckstrncpy(editor,s,CKMAXPATH);
6844 editor[CKMAXPATH] = NUL;
6846 printf("?Editor not defined - use SET EDITOR to define\n");
6850 ckstrncpy(tmpbuf,editfile,TMPBUFSIZ);
6852 cmiofi() lets us parse the name of an existing file, or the name of
6853 a nonexistent file to be created.
6855 x = cmiofi("File to edit", (char *)tmpbuf, &s, &y, xxstring);
6856 debug(F111,"edit",s,x);
6857 if (x < 0 && x != -3)
6862 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
6864 if ((z = cmcfm()) < 0) return(z);
6866 printf("?A single file please\n");
6870 printf("?Sorry, editing not allowed\n");
6871 return(success = 0);
6874 /* Get full path in case we change directories between EDIT commands */
6875 zfnqfp(tmpbuf, CKMAXPATH, editfile);
6876 editfile[CKMAXPATH] = NUL;
6878 p = editfile; /* Flip the stupid slashes */
6880 if (*p == '/') *p = '\\';
6887 if (zchki(editfile) < (CK_OFF_T)0 && zchko(editfile) < 0) {
6888 printf("?Access denied: %s\n",editfile);
6895 x = ckindex("%1",(char *)editopts,0,0,1);
6900 x = ckindex("%s",(char *)editopts,0,0,1);
6902 if (((int)strlen(editopts) + (int)strlen(editfile) + 1) < TMPBUFSIZ) {
6904 sprintf(tmpbuf,editopts,editfile);
6906 sprintf(tmpbuf,"%s %s",editopts,editfile);
6909 ckmakmsg(s,LINBUFSIZ,editor," ",tmpbuf,NULL);
6911 p = s + strlen(editor); /* And again with the slashes */
6913 if (*p == '/') *p = '\\';
6919 concb((char)escape);
6922 #endif /* NOFRILLS */
6932 printf("?Sorry, browsing not allowed\n");
6933 return(success = 0);
6936 /* Windows lets the Shell Execute the URL if no Browser is defined */
6938 s = getenv("BROWSER");
6939 if (s) ckstrncpy(browser,s,CKMAXPATH);
6940 browser[CKMAXPATH] = NUL;
6942 printf("?Browser not defined - use SET BROWSER to define\n");
6947 ckstrncpy(tmpbuf,browsurl,TMPBUFSIZ);
6948 if ((x = cmtxt("URL",(char *)browsurl,&s,xxstring)) < 0)
6950 ckstrncpy(browsurl,s,4096);
6954 x = ckindex("%1",(char *)browsopts,0,0,1);
6959 x = ckindex("%s",(char *)browsopts,0,0,1);
6961 if (((int)strlen(browsopts) + (int)strlen(browsurl) + 1) < TMPBUFSIZ) {
6963 sprintf(tmpbuf,browsopts,browsurl);
6965 sprintf(tmpbuf,"%s %s",browsopts,browsurl);
6969 return(success = Win32ShellExecute(browsurl));
6972 ckmakmsg(s,LINBUFSIZ,browser," ",tmpbuf,NULL);
6974 p = line + strlen(browser); /* Flip slashes */
6976 if (*p == '/') *p = '\\';
6982 concb((char)escape);
6985 #endif /* BROWSER */
6989 doredo() { /* Find a previous cmd and redo it */
6990 extern int on_recall, in_recall;
6995 "pattern, or first few characters of a previous command",
6996 "*",&s,xxstring)) < 0)
6998 ckstrncpy(line,s,LINBUFSIZ);
7001 if (*s == '{') { /* Braces disable adding * to end */
7002 if (s[x-1] == '}') {
7007 } else { /* No braces, add * to end. */
7012 while (x > 0 && s[x] == '*' && s[x-1] == '*') s[x--] = NUL;
7014 if (!on_recall || !in_recall) {
7015 printf("?Sorry, command recall can't be used now.\n");
7018 if ((p = cmgetcmd(s))) { /* Look for it history buffer */
7019 ckmakmsg(cmdbuf,CMDBL,p,"\r",NULL,NULL); /* Copy to command buffer */
7020 if (!quiet) /* Echo it */
7021 printf("%s\n",cmdbuf);
7022 cmaddnext(); /* Force re-add to history buffer */
7023 return(cmflgs = -1); /* Force reparse */
7025 printf("?Sorry - \"%s\" not found\n", s);
7029 #endif /* CK_RECALL */
7034 doassoc() { /* ASSOCIATE */
7035 extern struct keytab tcstab[];
7037 if ((x = cmkey(assoctab, nassoc, "", "", xxstring)) < 0 )
7040 switch (x) { /* Associate what? */
7042 case ASSOC_TC: /* Transfer character-set... */
7043 if ((x = cmkey(tcstab, ntcs,
7044 "transfer character-set name","",xxstring)) < 0)
7046 if ((y = cmkey(fcstab, nfilc,
7047 "with file character-set","", xxstring)) < 0)
7050 if ((z = cmcfm()) < 0)
7053 return(success = 1);
7055 case ASSOC_FC: /* File character-set... */
7056 if ((x = cmkey(fcstab, nfilc,
7057 "file character-set name","",xxstring)) < 0)
7059 if ((y = cmkey(tcstab, ntcs,
7060 "with transfer character-set","", xxstring)) < 0)
7063 if ((z = cmcfm()) < 0)
7066 return(success = 1);
7072 #endif /* NOCSETS */
7079 if ((x = cmcfm()) < 0)
7082 printf("?Sorry, access to system commands is disabled.\n");
7085 y = mxlook(mactab,"manual",nmac);
7087 z = maclvl; /* Save the current maclvl */
7088 dodo(y,NULL,cmdstk[cmdlvl].ccflgs); /* Run the macro */
7089 while (maclvl > z) {
7090 debug(F101,"XXMAN loop maclvl 1","",maclvl);
7091 sstate = (CHAR) parser(1);
7092 debug(F101,"XXMAN loop maclvl 2","",maclvl);
7093 if (sstate) proto();
7095 debug(F101,"XXMAN loop exit maclvl","",maclvl);
7098 return(success = 0);
7102 "Carriage return to confirm the command, or manual topic",
7104 "Carriage return to confirm the command, or help topic",
7115 ckmakmsg(tmpbuf,TMPBUFSIZ,"man ",s,NULL,NULL);
7117 ckmakmsg(tmpbuf,TMPBUFSIZ,"help ",s,NULL,NULL);
7119 debug(F110,"MANUAL",tmpbuf,0);
7121 printf("?Sorry, access to system commands is disabled.\n");
7124 conres(); /* Restore the console */
7125 success = zshcmd(tmpbuf);
7126 concb((char)escape); /* Restore CBREAK mode */
7134 static struct keytab sslswtab[] = {
7140 struct urldata http_url = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};
7144 dohttp() { /* HTTP */
7145 struct FDB sw, kw, fi;
7146 int n, getval, allinone = 0;
7150 char * http_agent = NULL; /* Parse results */
7151 char * http_hdr = NULL;
7152 char * http_user = NULL;
7153 char * http_pass = NULL;
7154 char * http_mime = NULL;
7155 char * http_lfile = NULL;
7156 char * http_rfile = NULL;
7157 char * http_dfile = NULL;
7158 char http_array = NUL;
7159 int http_action = -1;
7161 char * http_host = NULL;
7162 char * http_srv = NULL;
7165 static char * http_d_agent = NULL;
7166 static char * http_d_user = NULL;
7167 static char * http_d_pass = NULL;
7169 static int http_d_type = 0;
7170 int http_type = http_d_type;
7173 p = "Kermit 95"; /* Default user agent */
7177 makestr(&http_agent,p);
7178 makestr(&http_mime,"text/HTML"); /* MIME type default */
7181 cmfdbi(&sw, /* 1st FDB - general switches */
7183 "OPEN, CLOSE, GET, HEAD, PUT, INDEX, or POST,\n or switch", /* hlpmsg */
7185 "", /* addtl string data */
7186 nhttpswtab, /* addtl numeric data 1: tbl size */
7187 4, /* addtl numeric data 2: 4 = cmswi */
7188 xxstring, /* Processing function */
7189 httpswtab, /* Keyword table */
7190 &kw /* Pointer to next FDB */
7192 cmfdbi(&kw, /* 2nd FDB - commands */
7194 "Command", /* hlpmsg */
7196 "", /* addtl string data */
7197 nhttptab, /* addtl numeric data 1: tbl size */
7198 0, /* addtl numeric data 2: 0 = keyword */
7199 xxstring, /* Processing function */
7200 httptab, /* Keyword table */
7201 NULL /* Pointer to next FDB */
7205 x = cmfdb(&sw); /* Parse something */
7206 if (x < 0) /* Error */
7208 n = cmresult.nresult;
7209 if (cmresult.fdbaddr == &kw) /* Command - exit this loop */
7211 c = cmgbrk(); /* Switch... */
7212 getval = (c == ':' || c == '=');
7214 if (getval && !(cmgkwflgs() & CM_ARG)) {
7215 printf("?This switch does not take an argument\n");
7218 switch (cmresult.nresult) { /* Handle each switch */
7219 case HT_SW_TP: /* /TOSCREEN */
7222 case HT_SW_AG: /* /AGENT */
7224 if ((x = cmfld("User agent",p,&s,xxstring)) < 0)
7229 makestr(&http_agent,s);
7231 case HT_SW_HD: /* /HEADER */
7234 if ((x = cmfld("Header line","",&s,xxstring)) < 0) {
7241 makestr(&http_hdr,s);
7243 case HT_SW_US: /* /USER */
7246 if ((x = cmfld("User ID","",&s,xxstring)) < 0) {
7253 makestr(&http_user,s);
7255 case HT_SW_PW: /* /PASSWORD */
7259 if ((x = cmfld("Password","",&s,xxstring)) < 0)
7262 makestr(&http_pass,s);
7265 case HT_SW_AR: { /* /ARRAY: */
7266 char * s2, array = NUL;
7268 printf("?This switch requires an argument\n");
7272 if ((x = cmfld("Array name (a single letter will do)",
7278 printf("?Array name required\n");
7285 printf("?Array name required\n");
7290 if (*s == CMDQ) s++;
7293 printf("?Bad array name - \"%s\"\n",s2);
7299 array = tolower(array);
7300 if (*s && (*s != '[' || *(s+1) != ']')) {
7301 printf("?Bad array name - \"%s\"\n",s2);
7315 http_action = n; /* Save the action */
7316 if (http_action == HTTP_PUT || http_action == HTTP_POS) {
7317 cmfdbi(&sw, /* 1st FDB - switch */
7319 "Local filename\n Or switch", /* help */
7321 "", /* addtl string data */
7322 nhttpptab, /* keyword table size */
7323 4, /* addtl numeric data 2: 4 = cmswi */
7324 xxstring, /* Processing function */
7325 httpptab, /* Keyword table */
7326 &fi /* Pointer to next FDB */
7328 cmfdbi(&fi, /* 2nd FDB - filename */
7330 "Local filename", /* hlpmsg */
7332 "", /* addtl string data */
7333 0, /* addtl numeric data 1 */
7334 0, /* addtl numeric data 2 */
7342 goto xhttp; /* Free any malloc'd temp strings */
7343 n = cmresult.nresult;
7344 if (cmresult.fcode != _CMKEY)
7346 c = cmgbrk(); /* Switch... */
7347 getval = (c == ':' || c == '=');
7348 if (getval && !(cmgkwflgs() & CM_ARG)) {
7349 printf("?This switch does not take an argument\n");
7357 if ((x = cmfld("MIME type",
7358 "text/HTML",&s,xxstring)) < 0)
7361 makestr(&http_mime,s);
7368 makestr(&http_lfile,cmresult.sresult);
7369 n = ckindex("/",http_lfile,-1,1,0);
7374 if ((x = cmfld("URL or remote filename",p,&s,xxstring)) < 0) {
7376 printf("?%s what?\n",(http_action == HTTP_PUT) ? "Put" : "Post");
7382 makestr(&http_rfile,s);
7384 if ((x = cmtxt("Response filename","",&s,xxstring)) < 0) {
7389 makestr(&http_dfile,s);
7391 switch (http_action) {
7392 case HTTP_DEL: /* DELETE */
7393 if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
7395 printf("?Delete what?\n");
7400 makestr(&http_rfile,s);
7402 case HTTP_CON: /* CONNECT */
7403 if ((x = cmfld("Remote host[:port]","",&s,xxstring)) < 0) {
7405 printf("?Remote host[:port] is required\n");
7410 makestr(&http_rfile,s);
7412 case HTTP_HED: { /* HEAD */
7413 char buf[CKMAXPATH+1];
7414 if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
7416 printf("?Head of what?\n");
7421 makestr(&http_rfile,s);
7423 if (http_array || http_type) { /* Default result filename */
7424 p = ""; /* None if /ARRAY or /TOSCREEN */
7426 n = ckindex("/",http_rfile,-1,1,0); /* Otherwise strip path */
7427 if (n) /* and add ".head" */
7431 ckmakmsg(buf,CKMAXPATH,p,".head",NULL,NULL);
7434 if ((x = cmofi("Local filename",p,&s,xxstring)) < 0) {
7438 makestr(&http_lfile,s);
7441 case HTTP_GET: /* GET */
7442 case HTTP_IDX: { /* INDEX */
7446 if ((x = cmfld("URL or remote source file","",&s,xxstring)) < 0) {
7448 printf("?Get what?\n");
7453 makestr(&http_rfile,s);
7454 if (http_action == HTTP_GET && !http_type)
7455 zstrip(http_rfile,&lfile);
7456 /* URLs often contain question marks or other metacharacters */
7457 /* cmofi() doesn't like them */
7460 if ((x = cmofi("Local filename",lfile,&s,xxstring)) < 0) {
7466 makestr(&http_lfile,s);
7475 "IP host name or address, or switch", /* hlpmsg */
7477 "", /* addtl string data */
7478 2, /* addtl numeric data 1: tbl size */
7479 4, /* addtl numeric data 2: 4 = cmswi */
7480 xxstring, /* Processing function */
7481 sslswtab, /* Keyword table */
7482 &fl /* Pointer to next FDB */
7484 cmfdbi(&fl, /* 2nd FDB - host */
7488 "", /* addtl string data */
7489 0, /* addtl numeric data 1 */
7490 0, /* addtl numeric data 2 */
7495 x = cmfdb(&sw); /* Parse switch or host */
7496 if (x < 0) /* Error */
7498 if (cmresult.fcode == _CMFLD) { /* Host */
7499 s = cmresult.sresult; /* Set up expected pointer */
7500 goto havehost; /* Go parse rest of command */
7502 sslswitch = 1; /* /SSL or /TLS switch - set flag */
7507 if ((x = cmfld("URL, hostname, or ip-address","",&s,xxstring)) < 0) {
7509 printf("?Open what?\n");
7515 havehost: /* Come here with s -> host */
7517 x = urlparse(s,&http_url); /* Was a URL given? */
7518 if (x < 1) { /* Not a URL */
7520 makestr(&http_host,s);
7522 cmfld("Service name or port number",
7523 sslswitch ? "https" : "http",&s,xxstring)) < 0)
7526 makestr(&http_srv,s);
7528 } else if (ckstrcmp(http_url.svc,"http",-1,0) && /* Non-HTTP URL */
7529 ckstrcmp(http_url.svc,"https",-1,0)) {
7530 printf("?Non-HTTP URL\n");
7533 } else { /* Have HTTP URL */
7534 makestr(&http_srv, http_url.svc);
7535 makestr(&http_user,http_url.usr);
7536 makestr(&http_pass,http_url.psw);
7537 makestr(&http_host,http_url.hos);
7539 makestr(&http_srv,http_url.por);
7540 makestr(&http_rfile,http_url.pth);
7542 if (http_rfile) { /* Open, GET, and Close */
7543 printf("?Directory/file path not allowed in HTTP OPEN URL\n");
7547 if (!ckstrcmp("https",http_srv,-1,0) || sslswitch ||
7548 !ckstrcmp("443",http_srv,-1,0))
7556 if ((x = cmcfm()) < 0)
7559 if (http_action == HTTP_OPN) {
7560 x = (http_open(http_host,http_srv,http_ssl,rdns,128,http_agent) == 0);
7564 printf("Connected to %s [%s]\r\n",http_host,rdns);
7566 printf("Connected to %s\r\n",http_host);
7571 http_d_agent = http_agent;
7577 http_d_user = http_user;
7582 memset(http_d_pass,0,strlen(http_d_pass));
7585 http_d_pass = http_pass;
7588 http_d_type = http_type;
7591 printf("?HTTP Connection failed.\r\n");
7593 } else if (http_action == HTTP_CLS) {
7596 http_d_agent = NULL;
7603 memset(http_d_pass,0,strlen(http_d_pass));
7608 x = (http_close() == 0);
7610 if ((http_action != HTTP_CLS) &&
7611 (http_action != HTTP_CON) && http_rfile) { /* Remote file is URL? */
7613 /* All-in-one actions when a URL is given... */
7616 if (urlparse(http_rfile,&http_url) > 0) { /* Have URL? */
7617 if (ckstrcmp(http_url.svc,"http",-1,0) && /* It's an HTTP URL? */
7618 ckstrcmp(http_url.svc,"https",-1,0)) {
7619 printf("?Non-HTTP URL\n");
7622 } else { /* Yes, collect the pieces */
7623 makestr(&http_srv, http_url.svc);
7624 makestr(&http_user,http_url.usr);
7625 makestr(&http_pass,http_url.psw);
7626 makestr(&http_host,http_url.hos);
7628 makestr(&http_srv,http_url.por);
7629 makestr(&http_rfile,http_url.pth);
7631 if (!http_rfile) { /* Still have a path? */
7632 makestr(&http_rfile,"/");
7634 if (!ckstrcmp("https",http_srv,-1,0) || /* Check for SSL/TLS */
7635 !ckstrcmp("443",http_srv,-1,0))
7637 if (http_isconnected()) /* Close any open HTTP connection */
7639 if (http_pass == NULL && http_d_pass != NULL)
7640 makestr(&http_pass,http_d_pass);
7641 x = (http_open(http_host,
7642 http_srv,http_ssl,rdns,128,http_d_agent) == 0);
7650 if (http_pass == NULL && http_d_pass != NULL)
7651 makestr(&http_pass,http_d_pass);
7653 if (http_action == HTTP_OPN && allinone) {
7654 http_action = HTTP_GET;
7656 x = xdohttp(http_action,
7660 http_agent ? http_agent : http_d_agent,
7662 http_user ? http_user : http_d_user,
7663 http_pass ? http_pass : http_d_pass,
7669 x = (http_close() == 0);
7673 if (http_agent) free(http_agent);
7674 if (http_hdr) free(http_hdr);
7675 if (http_user) free(http_user);
7677 memset(http_pass,0,strlen(http_pass));
7680 if (http_mime) free(http_mime);
7681 if (http_lfile) free(http_lfile);
7682 if (http_rfile) free(http_rfile);
7683 if (http_dfile) free(http_dfile);
7684 if (http_host) free(http_host);
7685 if (http_srv) free(http_srv);
7691 #endif /* TCPSOCKET */
7700 cmfdbi(&sw, /* 1st FDB - switch */
7702 "Trace object;\n Or switch", /* help */
7704 "", /* addtl string data */
7705 2, /* keyword table size */
7706 4, /* addtl numeric data 2: 4 = cmswi */
7707 xxstring, /* Processing function */
7708 onoffsw, /* Keyword table */
7709 &kw /* Pointer to next FDB */
7711 cmfdbi(&kw, /* 2nd FDB - Trace object */
7713 "Trace object", /* help */
7714 "all", /* default */
7715 "", /* addtl string data */
7716 ntracetab, /* keyword table size */
7717 0, /* addtl numeric data 2: 0 = keyword */
7718 xxstring, /* Processing function */
7719 tracetab, /* Keyword table */
7720 NULL /* Pointer to next FDB */
7722 if ((x = cmfdb(&sw)) < 0)
7724 if (cmresult.fdbaddr == &sw) {
7725 on = cmresult.nresult;
7726 if ((x = cmkey(tracetab, ntracetab,"","all",xxstring)) < 0)
7729 x = cmresult.nresult;
7731 if ((y = cmcfm()) < 0)
7748 printf("TRACE %s\n", on ? "ON" : "OFF");
7749 return(success = 1);
7757 if ((x = cmtxt("Optional message","",&s,xxstring)) < 0)
7760 printf("?Sorry, PROMPT requires script programming language\n");
7763 debug(F101,"Prompt cmdlvl","",cmdlvl);
7765 if (cmdlvl > CMDSTKL) {
7766 printf("?Command stack overflow: %d\n",cmdlvl);
7771 cmdstk[cmdlvl].src = CMD_KB; /* Say we're at the prompt */
7772 cmdstk[cmdlvl].lvl = 0;
7773 cmdstk[cmdlvl].ccflgs = cmdstk[cmdlvl-1].ccflgs;
7775 printf("[%d] +P: \"(prompt)\"\n",cmdlvl);
7776 concb((char)escape);
7779 "(Recursive command prompt: Resume script with CONTINUE, STOP to stop...)\n"
7781 if (*s) { /* If prompt given */
7782 makestr(&(prstring[cmdlvl-1]),cmgetp()); /* Save current prompt */
7783 cmsetp(s); /* Set new one */
7785 return(success = 1);
7791 learncmd(s) char *s; { /* Record commands in learned script */
7794 if (learnfp && learning) { /* Only if open and on */
7795 k = ckstrncpy(buf,s,64);
7796 for (i = 0; i < k; i++) { /* Get top-level command keyword */
7802 k = lookup(cmdtab,buf,ncmd,NULL); /* Look it up */
7803 if (k == XXCON || k == XXLEARN) /* Don't record CONNECT or LEARN */
7806 fputs("SET HOST /NETWORK:TCP",learnfp);
7807 fputs(&s[i],learnfp);
7808 fputs(" TELNET /TELNET",learnfp);
7809 fputs("\nIF FAIL STOP 1 Connection failed\n",learnfp);
7812 fputs("\n",learnfp);
7816 #endif /* CKLEARN */
7822 Reopen a connection that was made with an external ssh client
7823 after it has been closed.
7829 debug(F111,"redossh nettype",ttname,nettype);
7830 if ((y = setlin(XXSSH,0,1)) < 0) {
7832 printf("?%s\n",ck_errstr());
7835 nettype = x; /* Failed, restore net type. */
7845 Like hmsga() in ckuus2.c but takes a single substitution parameter, s2,
7846 which replaces every occurrence of "%s" in the first argument.
7847 Added to print text containing the copyright year, so the year doesn't
7848 have to be hardwired into lots of scattered text strings.
7850 int /* Print an array of lines, */
7852 hmsgaa(char *s[], char *s2) /* pausing at end of each screen. */
7854 hmsgaa(s,s2) char *s[]; char *s2;
7855 #endif /* CK_ANSIC */
7857 extern int hmtopline;
7859 extern int tt_rows[], tt_cols[];
7861 extern int tt_rows, tt_cols;
7863 int x, y, i, j, k, n;
7864 if ((x = cmcfm()) < 0) return(x);
7870 /* Check whether window size changed */
7871 if (ttgwsiz() > 0) {
7872 if (tt_rows > 0 && tt_cols > 0) {
7878 #endif /* CK_TTGWSIZ */
7880 printf("\n"); /* Start off with a blank line */
7881 n = (hmtopline > 0) ? hmtopline : 1; /* Line counter */
7882 for (i = 0; *s[i]; i++) {
7883 printf((char *)s[i],s2); /* Print a line. */
7885 y = (int)strlen(s[i]);
7887 for (j = 0; j < y; j++) /* See how many newlines were */
7888 if (s[i][j] == '\n') k++; /* in the string... */
7890 if (n > (cmd_rows - 3) && *s[i+1]) /* After a screenful, give them */
7891 if (!askmore()) return(0); /* a "more?" prompt. */
7898 /* D O C M D -- Do a command */
7902 -2: user typed an illegal command
7904 0: parse was successful (even tho command may have failed).
7907 int cmdstats[256] = { -1, -1 };
7912 extern int nolocal, cmkwflgs;
7914 debug(F101,"docmd entry, cx","",cx);
7916 doconx = ((activecmd == XXCON) || (activecmd == XXTEL) ||
7917 (activecmd == XXRLOG) || (activecmd == XXPIPE) ||
7918 (activecmd == XXIKSD) || (activecmd == XXPTY));
7920 Originally all commands were handled with a big switch() statement,
7921 but eventually this started blowing up compilers. Now we have a series
7922 of separate if statements and small switches, with the commands that are
7923 most commonly executed in scipts and loops coming first, to speed up
7924 compute-bound scripts.
7928 if (cmdstats[0] == -1) { /* Count commands */
7929 int i; /* for tuning... */
7930 for (i = 0; i < 256; i++)
7938 if (msgflg) printf("\n");
7940 if (msgflg) printf("\r\n");
7942 doexit(GOOD_EXIT,xitsta);
7943 case -3: /* Null command */
7945 case -9: /* Like -2, but errmsg already done */
7946 case -1: /* Reparse needed */
7948 case -6: /* Special */
7949 case -2: /* Error, maybe */
7953 Maybe they typed a macro name. Let's look it up and see.
7955 if (cx == -6) /* If they typed CR */
7956 ckstrncat(cmdbuf,"\015",CMDBL); /* add it back to command buffer. */
7957 if (ifcmd[cmdlvl] == 2) /* Watch out for IF commands. */
7959 repars = 1; /* Force reparse */
7961 cx = XXDO; /* Try DO command */
7975 if ((cmkwflgs & CM_PSH)
7980 printf("?Access to system disabled\n");
7983 if ((cmkwflgs & CM_LOC)
7986 #endif /* NOLOCAL */
7988 printf("?Connections disabled\n");
7993 /* Used in FOR loops */
7995 if (cx == XX_INCR || cx == XXINC || /* _INCREMENT, INCREMENT */
7996 cx == XX_DECR || cx == XXDEC) /* _DECREMENT, DECREMENT */
7999 /* Define (or change the definition of) a macro or variable */
8001 if (cx == XXUNDEF || cx == XXUNDFX) {
8003 if (inserver && !ENABLED(en_asg)) {
8004 printf("?Sorry, DEFINE/ASSIGN disabled\n");
8008 return(doundef(cx)); /* [_]UNDEFINE */
8010 if (cx == XXDEF || cx == XXASS ||
8011 cx == XXDFX || cx == XXASX) {
8013 if (inserver && !ENABLED(en_asg)) {
8014 printf("?Sorry, DEFINE/ASSIGN disabled\n");
8018 if (atmbuf[0] == '.' && !atmbuf[1]) /* "." entered as keyword */
8019 xxdot = 1; /* i.e. with space after it... */
8020 return(dodef(cx)); /* DEFINE, ASSIGN, etc... */
8023 /* IF, WHILE, and friends */
8025 if (cx == XXIF || cx == XXIFX || cx == XXWHI || cx == XXASSER) {
8028 if (cx == XXSWIT) { /* SWITCH */
8032 /* GOTO, FORWARD, and _FORWARD (used internally by FOR, WHILE, etc) */
8034 if (cx == XXGOTO || cx == XXFWD || cx == XXXFWD) { /* GOTO or FORWARD */
8035 /* Note, here we don't set SUCCESS/FAILURE flag */
8037 if ((y = cmfld("label","",&s,xxstring)) < 0) {
8040 printf("?Label name required\n");
8046 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
8047 if ((x = cmcfm()) < 0) return(x);
8049 if ((y = cmtxt("label","",&s,xxstring)) < 0) {
8052 printf("?GOTO: Label name required: \"%s\" \"%s\"\n",
8060 ckstrncpy(tmpbuf,brstrip(s),TMPBUFSIZ);
8061 #endif /* COMMENT */
8063 debug(F111,"GOTO target",s,cx);
8064 return(dogoto(s,cx));
8066 if (cx == XXDO || cx == XXMACRO) { /* DO (a macro) */
8067 char mnamebuf[16]; /* (buffer for controlled temp name) */
8069 int mx; /* Macro index (on stack!) */
8071 debug(F101,"XXMACRO 0",line,cx);
8074 printf("\n?No macros defined\n");
8077 for (y = 0; y < nmac; y++) { /* copy the macro table into a */
8078 mackey[y].kwd = mactab[y].kwd; /* regular keyword table */
8079 mackey[y].kwval = y; /* with value = pointer to macro tbl */
8080 mackey[y].flgs = mactab[y].flgs;
8082 cmfdbi(&kw, /* First FDB - macro name */
8084 "Macro", /* hlpmsg */
8086 "", /* addtl string data */
8087 nmac, /* addtl numeric data 1: tbl size */
8088 0, /* addtl numeric data 2: 0 = cmkey */
8089 xxstring, /* Processing function */
8090 mackey, /* Keyword table */
8091 &fl /* Pointer to next FDB */
8093 cmfdbi(&fl, /* 2nd FDB - for "{" */
8097 "", /* addtl string data */
8098 0, /* addtl numeric data 1 */
8099 0, /* addtl numeric data 2 */
8104 x = cmfdb(&kw); /* Parse something */
8105 if (x < 0) { /* Error */
8107 printf("?Macro name required\n");
8112 if (cmresult.fcode == _CMKEY) {
8113 extern int mtchanged;
8114 char * macroname = NULL;
8116 /* In case args include an \fexec() that changes the macro table */
8118 mx = x; /* Save macro index on stack */
8119 mtchanged = 0; /* Mark state of macro table */
8120 makestr(¯oname,mactab[mx].kwd); /* Save name */
8122 if ((y = cmtxt("optional arguments","",&s,xxstring)) < 0)
8123 return(y); /* Get macro args */
8125 if (mtchanged) { /* Macro table changed? */
8126 mx = mlook(mactab,macroname,nmac); /* Look up name again */
8131 return(dodo(mx,s,cmdstk[cmdlvl].ccflgs) < 1 ?
8134 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* _CMFLD */
8135 if (atmbuf[0] == '{') {
8136 if ((y = cmcfm()) < 0)
8139 } else { /* XXMACRO ("immediate macro") */
8144 debug(F111,"XXMACRO A",line,k);
8145 if ((y = cmtxt("Braced list of commands","",&s,xxstring)) < 0)
8147 k = ckstrncpy(line+k,s,LINBUFSIZ-k);
8148 debug(F111,"XXMACRO B",line,k);
8151 if ((line[0] == '{' && line[x-1] != '}') || line[0] == '}')
8153 if (line[0] != '{' && line[x-1] != '}') {
8154 /* Unknown command. If ON_UNKNOWN_COMMAND macro is defined, */
8155 /* parse args and then execute it, but only if it is not */
8156 /* already active. */
8159 k = mxlook(mactab,"on_unknown_command",nmac);
8162 ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ);
8163 z = maclvl; /* Save the current maclvl */
8164 if ((y = cmtxt("text","",&s,xxstring)) < 0)
8166 ckstrncat(tmpbuf," ",TMPBUFSIZ);
8167 ckstrncat(tmpbuf,s,TMPBUFSIZ);
8169 debug(F110,"ON_UNKNOWN_COMMAND",s,0);
8170 dodo(k,tmpbuf,cmdstk[cmdlvl].ccflgs); /* Run the macro */
8171 while (maclvl > z) {
8172 sstate = (CHAR) parser(1);
8173 if (sstate) proto();
8175 debug(F101,"UNKMAC loop exit maclvl","",maclvl);
8180 printf("?Not a command or macro name: \"%s\"\n",line);
8182 printf("?Not a command or macro name.\n");
8186 sprintf(mnamebuf," ..tmp:%03d",cmdlvl); /* safe (16) */
8187 x = addmac(mnamebuf,s);
8188 return(dodo(x,NULL,cmdstk[cmdlvl].ccflgs) < 1 ? (success = 0) : 1);
8191 if (cx == XXLBL) { /* LABEL */
8192 if ((x = cmfld("label","",&s,xxstring)) < 0) {
8195 printf("?LABEL: Label name required: \"%s\"\n", cmdbuf);
8199 #endif /* COMMENT */
8203 debug(F111,"LABEL",s,x);
8204 if ((x = cmcfm()) < 0) return(x);
8208 if (cx == XXEVAL || cx == XX_EVAL) /* _EVALUATE, EVALUATE */
8212 if (cx == XXSEXP) { /* Lisp-like S-Expression */
8213 struct stringarray * q;
8214 char /* *p, *r, */ *tmp, *m;
8215 int i, k, n, quote = 0, contd = 0, size = 0, len = 0;
8216 extern int sexprc, sexppv;
8218 tmp = tmpbuf; /* Buffer to collect SEXP */
8219 tmpbuf[0] = NUL; /* Clear it */
8220 size = TMPBUFSIZ; /* Capacity of buffer */
8221 sexprc = -1; /* Assume bad input */
8222 n = 0; /* Paren balance counter */
8224 while (1) { /* Allow SEXP on multiple lines */
8226 "Continuation of S-Expression" :
8227 "S-Expression (\"help sexp\" for details)";
8228 x = cmtxt(m,"",&s,xxstring);
8231 if (!*s) /* Needed for (=) and (:) */
8232 s = cmdbuf+1; /* I can't explain why. */
8233 k = ckmakmsg(tmp, size, contd ? " " : "(", s, NULL, NULL);
8235 printf("?SEXP too long - %d max\n",TMPBUFSIZ);
8238 debug(F111,contd ? "sexp contd" : "sexp",s,k);
8240 for (i = len; i < len+k; i++) { /* Check balance */
8241 if (!quote && tmpbuf[i] == CMDQ) {
8249 if (tmpbuf[i] == '(')
8251 else if (tmpbuf[i] == ')')
8254 if (n == 0) { /* Break when balanced */
8257 if (n < 0) { /* Too many right parens */
8258 printf("?Unbalanced S-Expression: \"%s\"\n",tmpbuf);
8261 contd++; /* Need more right parens */
8262 cmini(ckxech); /* so keep parsing */
8263 tmp += k; /* adjust buffer pointer */
8264 size -= k; /* and capacity */
8265 len += k; /* and length so far */
8268 makestr(&lastsexp,s);
8269 q = cksplit(1,SEXPMAX,s,NULL,NULL,8,0,0); /* Precheck for > 1 SEXP */
8270 debug(F101,"sexp split","",q->a_size);
8272 if (q->a_size == 1) { /* We should get exactly one back */
8273 char * result, * dosexp();
8274 sexprc = 0; /* Reset out-of-band return code */
8275 result = dosexp(s); /* Get result */
8276 debug(F111,"sexp result",result,sexprc);
8277 if (sexprc == 0) { /* Success */
8278 /* Echo the result if desired */
8279 if ((!xcmdsrc && sexpecho != SET_OFF) || sexpecho == SET_ON)
8280 printf(" %s\n",result ? result : "");
8281 makestr(&sexpval,result);
8282 success = sexppv > -1 ? sexppv : 1;
8287 printf("?Invalid S-Expression: \"%s\"\n",lastsexp);
8294 if (cx == XXECH || cx == XXXECH || cx == XXVOID
8298 ) { /* ECHO or APC */
8299 if ((x = cmtxt((cx == XXECH || cx == XXXECH) ?
8300 "Text to be echoed" :
8301 ((cx == XXVOID) ? "Text" :
8302 "Application Program Command text"),
8311 /* This is to preserve the pre-8.0 behavior but it's too confusing */
8313 x = (x > 1) ? ((s[0] == '"' && s[x-1] == '"') ? 1 : 0) : 0;
8314 #endif /* COMMENT */
8315 s = brstrip(s); /* Strip braces and doublequotes */
8316 if (cx == XXECH) { /* ECHO */
8318 if (!fndiags || fnsuccess) {
8321 /* The "if (x)" business preserves previous behavior */
8322 /* by putting back the doublequotes if they were included. */
8324 printf("\"%s\"\n",s);
8326 #endif /* COMMENT */
8331 } else if (cx == XXXECH) { /* XECHO */
8339 } else if (cx == XXAPC) { /* APC */
8341 if (apcactive == APC_LOCAL ||
8342 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH)))
8343 return(success = 0);
8346 printf("%c_%s%c\\",ESC,s,ESC);
8351 } else { /* Local mode - have connection */
8353 if (ckmakxmsg(tmpbuf, /* Form APC string in buffer */
8360 NULL,NULL,NULL,NULL,NULL,NULL,NULL
8362 return(success = dooutput(tmpbuf, XXOUT));
8363 printf("?Too long\n");
8366 printf("%c_%s%c\\",ESC,s,ESC);
8370 return(success = 1);
8374 /* Copy macro args from/to two levels up, used internally by _floop et al. */
8375 if (cx == XXGTA || cx == XXPTA) { /* _GETARGS, _PUTARGS */
8377 debug(F101,"docmd XXGTA","",XXGTA);
8378 debug(F101,"docmd cx","",cx);
8379 debug(F101,"docmd XXGTA maclvl","",maclvl);
8381 debug(F101,"docmd dogta returns","",x);
8382 debug(F101,"docmd dogta maclvl","",maclvl);
8391 else if (cx == XXF_RE || cx == XXF_WR || cx == XXF_OP ||
8392 cx == XXF_CL || cx == XXF_SE || cx == XXF_RW ||
8393 cx == XXF_FL || cx == XXF_LI || cx == XXF_ST || cx == XXF_CO)
8395 #endif /* CKCHANNELIO */
8397 /* ASK, ASKQ, READ */
8398 if (cx == XXASK || cx == XXASKQ || cx == XXREA ||
8399 cx == XXRDBL || cx == XXGETC || cx == XXGETK) {
8406 if (cx == XXBUG) { /* BUG */
8407 if ((x = cmcfm()) < 0) return(x);
8411 #endif /* NOFRILLS */
8414 if (cx == XXBYE) { /* BYE */
8415 extern int ftp_cmdlin;
8416 if ((x = cmcfm()) < 0) return(x);
8419 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen())) {
8420 extern int stayflg, ftp_fai;
8422 if (ftp_cmdlin && !stayflg && !local)
8423 doexit(ftp_fai ? BAD_EXIT : GOOD_EXIT,-1);
8430 printf("?No connection - use EXIT to quit.\n");
8435 if (protocol != PROTO_K) {
8436 printf("?Sorry, BYE only works with Kermit protocol\n");
8444 protocol == PROTO_K &&
8446 !iks_wait(KERMIT_REQ_START,1)) {
8448 "?A Kermit Server is not available to process this command\n");
8449 return(-9); /* Correct the return code */
8451 #endif /* IKS_OPTION */
8454 sstate = setgen('L',"","","");
8455 if (local) ttflui(); /* If local, flush tty input buffer */
8460 if (cx == XXBEEP) { /* BEEP */
8464 if ((y = cmkey(beeptab, nbeeptab, "which kind of beep", "information",
8467 if ((x = cmcfm()) < 0) return(x);
8468 bleep((short)y); /* y is one of the BP_ values */
8470 if ((x = cmcfm()) < 0) return(x);
8481 if (cx == XXCLE) /* CLEAR */
8482 return(success = doclear());
8483 #endif /* NOFRILLS */
8485 if (cx == XXCOM) { /* COMMENT */
8486 if ((x = cmtxt("Text of comment line","",&s,NULL)) < 0)
8488 /* Don't change SUCCESS flag for this one */
8493 if (cx == XXCON || cx == XXCQ) /* CONNECT or CONNECT /QUIETLY */
8494 return(doxconn(cx));
8495 #endif /* NOLOCAL */
8499 if (cx == XXCPY) { /* COPY a file */
8501 if (inserver && !ENABLED(en_cpy)) {
8502 printf("?Sorry, COPY is disabled\n");
8507 if (apcactive == APC_LOCAL ||
8508 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
8510 return(success = 0);
8516 if ( cx == XXLINK ) {
8518 if (inserver && !ENABLED(en_cpy)) {
8519 printf("?Sorry, LINK (COPY) is disabled\n");
8524 if (apcactive == APC_LOCAL ||
8525 (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
8527 return(success = 0);
8532 #endif /* NOFRILLS */
8534 /* CD and friends */
8535 if (cx == XXCWD || cx == XXCDUP || cx == XXBACK ||
8536 cx == XXLCWD || cx == XXLCDU || cx == XXKCD) {
8543 return(dormt(XZCWD));
8545 } else if (cx == XXCDUP) {
8549 return(dormt(XZCDU));
8555 if (inserver && !ENABLED(en_cwd)) {
8556 printf("?Sorry, changing directories is disabled\n");
8560 return(success = docd(cx));
8563 if (cx == XXCHK) /* CHECK */
8564 return(success = dochk());
8566 if (cx == XXCLO) { /* CLOSE */
8567 x = cmkey(clstab,ncls,"\"CONNECTION\", or log or file to close",
8568 "connection",xxstring);
8570 printf("?You must say which file or log\n");
8573 if (x < 0) return(x);
8574 if ((y = cmcfm()) < 0) return(y);
8576 if (x == 9999) { /* CLOSE CONNECTION */
8580 if (msgflg) printf("?Connection was not open\n");
8584 whyclosed = WC_CLOS;
8589 #endif /* NOLOCAL */
8596 if (cx == XXDCL || cx == XXUNDCL) { /* DECLARE an array */
8602 if (cx == XXRED || cx == XXDIAL || cx == XXPDIA ||
8603 cx == XXANSW || cx == XXLOOK) { /* DIAL, REDIAL etc */
8609 #endif /* UNIXOROSK */
8612 debug(F101,"dodial returns","",x);
8613 if ((cx == XXDIAL || cx == XXRED || cx == XXANSW) &&
8614 (x > 0) && /* If DIAL or REDIAL succeeded */
8615 (dialsta != DIA_PART) && /* and it wasn't partial */
8617 if ((dialcon == 1 || /* And DIAL CONNECT is ON, */
8618 ((dialcon == 2) && /* or DIAL CONNECT is AUTO */
8619 !xcmdsrc /* and we're at top level... */
8621 && !batch /* Not if running from batch */
8624 && !backgrd /* Not if running in background */
8625 #endif /* UNIXOROSK */
8628 x = doconect(dialcq, /* Then also CONNECT */
8634 return(success = x);
8640 if (cx == XXREXX) { /* REXX */
8646 #endif /* CK_REXX */
8650 if (cx == XXDEL || cx == XXLDEL) { /* DELETE */
8652 if (!locus && cx != XXLDEL) {
8656 return(dormt(XZDEL));
8661 if (inserver && (!ENABLED(en_del)
8664 #endif /* CK_LOGIN */
8666 printf("?Sorry, DELETE is disabled\n");
8671 if ((apcactive == APC_LOCAL) ||
8672 ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
8673 return(success = 0);
8677 #endif /* NOFRILLS */
8679 if (cx == XXTOUC) /* TOUCH */
8682 /* DIRECTORY commands */
8684 if (cx == XXDIR || cx == XXLS || cx == XXLDIR ||
8685 cx == XXWDIR || cx == XXHDIR) {
8687 if (!locus && cx != XXLDIR) {
8691 return(dormt(XZDIR));
8696 if (inserver && !ENABLED(en_dir)) {
8697 printf("?Sorry, DIRECTORY is disabled\n");
8705 if (cx == XXELS) /* ELSE */
8711 if (cx == XXENA || cx == XXDIS) { /* ENABLE, DISABLE */
8713 "Server function to enable" :
8714 "Server function to disable";
8716 if ((x = cmkey(enatab,nena,s,"",xxstring)) < 0) {
8718 printf("?Name of server function required\n");
8722 if ((y = cmkey(kmstab,3,"mode","both",xxstring)) < 0) {
8724 printf("?Please specify remote, local, or both\n");
8728 if (cx == XXDIS) /* Disabling, not enabling */
8730 if ((z = cmcfm()) < 0) return(z);
8732 if ((apcactive == APC_LOCAL) ||
8733 ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
8734 return(success = 0);
8737 /* This may seem like it duplicates the work in doenable() */
8738 /* but this code returns failure whereas doenable() returns */
8743 #endif /* IKSDCONF */
8744 (x == EN_HOS || x == EN_PRI || x == EN_MAI || x == EN_WHO ||
8746 return(success = 0);
8748 return(doenable(y,x));
8750 #endif /* NOFRILLS */
8751 #endif /* NOSERVER */
8754 if (cx == XXRET) { /* RETURN */
8755 if ((x = cmtxt("Optional return value","",&s,NULL)) < 0)
8757 s = brstrip(s); /* Strip braces */
8758 if (cmdlvl == 0) /* At top level, nothing happens... */
8759 return(success = 1);
8760 switch (cmdstk[cmdlvl].src) { /* Action depends on command source */
8761 case CMD_TF: /* Command file */
8762 popclvl(); /* Pop command level */
8763 return(success = 1); /* always succeeds */
8764 case CMD_MD: /* Macro */
8765 case CMD_KB: /* Prompt */
8766 return(doreturn(s)); /* Trailing text is return value. */
8767 default: /* Shouldn't happen */
8774 if (cx == XXOPE) /* OPEN */
8779 if (cx == XXOUT || cx == XXLNOUT) { /* OUTPUT or LINEOUT */
8780 if ((x = cmtxt("Text to be output","",&s,NULL)) < 0)
8783 if ((apcactive == APC_LOCAL) ||
8784 ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
8785 return(success = 0);
8787 debug(F110,"OUTPUT 1",s,0);
8788 s = brstrip(s); /* Strip enclosing braces, */
8789 debug(F110,"OUTPUT 2",s,0);
8791 I don't think I could ever fully explain this in a million years...
8792 We have read the user's string without calling the variable-expander
8793 function. Now, before we call it, we have to double backslashes that
8794 appear before \N, \B, \L, and \ itself, so the expander function will
8795 reduce them back to single backslashes, so when we call dooutput()...
8796 But it's more complicated than that.
8798 if (cmdgquo()) { /* Only if COMMAND QUOTING ON ... */
8799 for (x = 0, y = 0; s[x]; x++, y++) {
8802 if (c == 'n' || c == 'N' ||
8803 c == 'b' || c == 'B' ||
8804 c == 'l' || c == 'L' ||
8810 line[y++] = '\0'; /* Now expand variables, etc. */
8811 debug(F110,"OUTPUT 3",line,0);
8813 x = LINBUFSIZ - (int) strlen(line) - 1;
8814 debug(F101,"OUTPUT size","",x);
8815 if (zzstring(line,&s,&x) < 0)
8816 return(success = 0);
8818 debug(F110,"OUTPUT 4",s,0);
8820 success = dooutput(s,cx);
8827 if (cx == XXPAD) { /* PAD commands */
8828 x = cmkey(padtab,npadc,"PAD command","",xxstring);
8830 printf("?You must specify a PAD command to execute\n");
8833 if (x < 0) return(x);
8838 printf("Sorry, you must 'set network' & 'set host' first\r\n");
8846 printf("Not connected\r\n");
8848 extern int linkid, lcn;
8849 conol("Connected thru ");
8851 printf(", Link id %d, Logical channel number %d\r\n",
8857 printf("Sorry, you must 'set network' & 'set host' first\r\n");
8863 printf("Sorry, you must 'set network' & 'set host' first\r\n");
8873 if (cx == XXPAU || cx == XXWAI || cx == XXMSL) /* PAUSE, WAIT, etc */
8881 if (inserver && (isguest || !ENABLED(en_pri))) {
8882 printf("?Sorry, printing is disabled\n");
8885 #endif /* CK_LOGIN */
8887 if ((x = cmifi("File to print","",&s,&y,xxstring)) < 0) {
8889 printf("?A file specification is required\n");
8894 printf("?Wildcards not allowed\n");
8897 ckstrncpy(line,s,LINBUFSIZ);
8900 if ((x = cmtxt("Local print command options, or carriage return","",&s,
8904 if ((x = cmcfm()) < 0)
8906 return(success = (zprint(s,line) == 0) ? 1 : 0);
8908 #endif /* NOFRILLS */
8912 if (cx == XXPNG) /* PING an IP host */
8917 if (cx == XXFTP) /* FTP */
8920 return(doftp()); /* Just runs system's ftp program */
8928 #endif /* TCPSOCKET */
8930 if (cx == XXPWD || cx == XXLPWD) { /* PWD */
8934 if ((x = cmcfm()) < 0)
8937 if (!locus && cx != XXLPWD) {
8941 return(dormt(XZPWD));
8949 printf("%s\n",zgtdir());
8953 return(success = 1); /* Blind faith */
8955 if (pwp = zgtdir()) {
8959 ckGetLongPathName(pwp,line,LINBUFSIZ);
8960 line[LINBUFSIZ-1] = NUL;
8962 GetShortPathName(pwp,tmpbuf,TMPBUFSIZ);
8963 tmpbuf[TMPBUFSIZ-1] = NUL;
8965 if (!strcmp(line,tmpbuf)) {
8970 printf(" Long name: %s\n",line);
8971 printf(" Short name: %s\n",tmpbuf);
8975 return(success = ((int)strlen(pwp) > 0));
8976 } else return(success = 0);
8979 if (pwp = zgtdir()) {
8981 return(success = ((int)strlen(pwp) > 0));
8982 } else return(success = 0);
8986 if (cx == XXQUI || cx == XXEXI) { /* EXIT, QUIT */
8987 extern int quitting;
8989 if ((y = cmnum("exit status code",ckitoa(xitsta),10,&x,xxstring)) < 0)
8991 if ((y = cmtxt("Optional EXIT message","",&s,xxstring)) < 0)
8994 ckstrncpy(line,s,LINBUFSIZ);
8996 if (!hupok(0)) /* Check if connection still open */
8997 return(success = 0);
8999 if (line[0]) /* Print EXIT message if given */
9000 printf("%s\n",(char *)line);
9002 quitting = 1; /* Flag that we are quitting. */
9005 doexit(GOOD_EXIT,x);
9008 /* Returning any codes here makes the OS-9 shell print an error message. */
9009 doexit(GOOD_EXIT,-1);
9012 doexit(GOOD_EXIT,x);
9015 #endif /* datageneral */
9022 if (cx == XXERR) { /* ERROR */
9024 if (protocol != PROTO_K) {
9025 printf("Sorry, E-PACKET only works with Kermit protocol\n");
9029 if ((x = cmcfm()) < 0) return(x);
9035 #endif /* NOFRILLS */
9037 if (cx == XXFIN) { /* FINISH */
9039 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
9043 if (protocol != PROTO_K) {
9044 printf("Sorry, FINISH only works with Kermit protocol\n");
9048 if ((x = cmcfm()) < 0) return(x);
9053 protocol == PROTO_K &&
9055 !iks_wait(KERMIT_REQ_START,1)) {
9057 "?A Kermit Server is not available to process this command\n");
9058 return(-9); /* Correct the return code */
9060 #endif /* IKS_OPTION */
9062 sstate = setgen('F',"","","");
9063 if (local) ttflui(); /* If local, flush tty input buffer */
9069 if (cx == XXFOR) /* FOR loop */
9074 /* GET MGET REGET RETRIEVE etc */
9075 if (cx == XXGET || cx == XXMGET || cx == XXREGET || cx == XXRETR) {
9077 if (inserver && !ENABLED(en_sen)) {
9078 printf("?Sorry, reception of files is disabled\n");
9088 if (cx == XXGOK) { /* GETOK */
9089 return(success = doask(cx));
9091 #endif /* NOFRILLS */
9094 if (cx == XXHLP) { /* HELP */
9096 return(dohlp(XXHLP));
9099 ncmd,"\nCommand or topic","help",toktab,xxstring,1+2+8);
9100 debug(F111,"HELP command x",cmdbuf,x);
9103 debug(F101,"HELP cmkey token","",y);
9108 case '@': x = XXSHE; break;
9109 case '<': x = XXFUN; break;
9111 case '#': x = XXCOM; break;
9112 case ';': x = XXCOM; break;
9114 case '.': x = XXDEF; break;
9115 case ':': x = XXLBL; break;
9117 case '(': x = XXSEXP; break;
9121 case '^': x = XXREDO; break;
9122 #endif /* CK_RECALL */
9123 case '&': x = XXECH; break; /* (what is this?) */
9125 printf("\n?Invalid - %s\n",cmdbuf);
9129 makestr(&hlptok,atmbuf);
9130 debug(F111,"HELP token",hlptok,x);
9136 if (cx == XXINT) /* INTRO */
9137 return(hmsga(introtxt));
9138 if (cx == XXNEW) { /* NEWS */
9140 extern char * k_info_dir;
9146 if (cx == XXUPD) { /* View UPDATE file */
9147 extern char exedir[];
9150 if ((x = cmtxt("topic name","",&pTopic,xxstring)) < 0)
9154 "start view %s\\docs\\k2.inf+%s\\docs\\using_ck.inf+\
9155 %s\\docs\\dialing.inf+%s\\docs\\modems.inf %s",
9156 exedir,exedir,exedir,exedir,pTopic
9159 if (ckmakxmsg(updstr,
9165 "\\docs\\using_ck.inf+",
9167 "\\docs\\dialing.inf+",
9169 "\\docs\\modems.inf ",
9174 #endif /* COMMENT */
9176 return(success = 1);
9178 #endif /* OS2ONLY */
9182 if (cx == XXHAN) { /* HANGUP */
9183 if ((x = cmcfm()) < 0) return(x);
9185 if ((ftpget == 1) || ((ftpget == 2) && !local && ftpisopen()))
9186 return(success = ftpbye());
9189 if ((x = mdmhup()) < 1) {
9190 debug(F101,"HANGUP mdmup","",x);
9193 debug(F101,"HANGUP tthang","",x);
9199 whyclosed = WC_CLOS;
9200 ttchk(); /* In case of CLOSE-ON-DISCONNECT */
9204 DialerSend(OPT_KERMIT_HANGUP, 0);
9206 if (x) haveline = 0;
9207 return(success = x);
9209 #endif /* NOLOCAL */
9212 /* INPUT, REINPUT, and MINPUT */
9214 if (cx == XXINP || cx == XXREI || cx == XXMINP) {
9216 int flags = 0, incount = 0;
9217 extern int itsapattern, isjoin, isinbuflen;
9220 struct FDB sw, nu, fl;
9221 int fc, havetime = 0;
9225 m = "Timeout in seconds (ignored)";
9227 m = "Seconds to wait for input,\n or time of day hh:mm:ss,\
9230 cmfdbi(&sw, /* First FDB - command switches */
9233 ckitoa(indef), /* default */
9234 "", /* addtl string data */
9235 ninputsw, /* addtl numeric data 1: tbl size */
9236 4, /* addtl numeric data 2: 4 = cmswi */
9237 xxstring, /* Processing function */
9238 inputsw, /* Keyword table */
9239 &nu /* Pointer to next FDB */
9242 _CMNUM, /* Number */
9243 m, /* Help message */
9244 ckitoa(indef), /* default */
9246 10, /* Radix = 10 */
9248 xxstring, /* Processing function */
9252 cmfdbi(&fl, /* Time of day hh:mm:ss */
9256 "", /* addtl string data */
9257 0, /* addtl numeric data 1 */
9258 0, /* addtl numeric data 2 */
9263 fc = (cx == XXREI) ? cmfdb(&nu) : cmfdb(&sw); /* Parse something */
9265 for (y = 0; y < MINPMAX; y++) { /* Initialize search strings */
9266 mp[y] = 0; /* Assume it's not a pattern */
9271 free(ms[y]); /* Free old strings, if any */
9277 if (fc < 0) { /* Error */
9279 printf("?Syntax error in INPUT-class command\n");
9284 switch (cmresult.fcode) {
9285 case _CMKEY: /* Switch */
9287 if ((getval = (c == ':' || c == '=')) &&
9288 !(cmgkwflgs() & CM_ARG)) {
9289 printf("?This switch does not take an argument\n");
9292 if (getval && cmresult.nresult == INPSW_COU) {
9293 if ((y = cmnum("Number of bytes to read",
9294 "",10,&x,xxstring)) < 0)
9298 flags |= cmresult.nresult;
9299 fc = cmfdb(&sw); /* Maybe parse more switches */
9302 case _CMNUM: /* Seconds to time out */
9303 x = cmresult.nresult;
9305 if (inscale != 1.0) /* Scale */
9307 #endif /* CKFLOAT */
9312 zz = tod2sec(atmbuf); /* Convert to secs since midnight */
9314 printf("?Number, expression, or time of day required\n");
9317 char now[32]; /* Current time */
9322 tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
9323 if (zz < tnow) /* User's time before now */
9324 zz += 86400L; /* So make it tomorrow */
9325 zz -= tnow; /* Seconds from now. */
9328 if (zz != (long) x) {
9330 "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
9339 printf("?Internal error\n");
9343 /* Now parse the search text */
9346 if (cx == XXMINP) { /* MINPUT */
9347 int i, k = 0, n = 0;
9348 struct stringarray * q;
9350 while (k < MINPMAX) {
9351 if ((y = cmfld("String or pattern","",&s,xxstring)) < 0) {
9353 if ((y = cmcfm()) < 0)
9360 debug(F111,"MINPUT field",s,k);
9362 if ((q = cksplit(1,0,s," ",(char *)c1chars,3,0,0))) {
9363 char ** ap = q->a_head;
9365 debug(F101,"minput cksplit size","",n);
9366 for (i = 1; i <= n && k < MINPMAX; i++) {
9367 if (!ap[i]) /* Add non-empty elements */
9371 makestr(&(ms[k]),ap[i]);
9372 debug(F111,"MINPUT JOIN",ms[k],k);
9378 makestr(&(ms[k]),brstrip(s));
9379 if (itsapattern) mp[k] = 1;
9380 debug(F111,"MINPUT",ms[k],itsapattern);
9387 #endif /* CK_MINPUT */
9389 /* INPUT or REINPUT */
9391 if (flags & INPSW_COU) {
9392 if ((y = cmcfm()) < 0)
9395 if ((y = cmtxt("Material to be input","",&s,xxstring)) < 0)
9398 mp[0] = itsapattern ? 1 : 0;
9399 makestr(&(ms[0]),brstrip(s));
9404 #endif /* CK_MINPUT */
9406 if (incount > 0) /* No searching if /COUNT: given */
9407 makestr(&(ms[0]),NULL);
9409 if (cx == XXINP || cx == XXMINP) { /* Not REINPUT... */
9411 /* Go try to input the search string */
9412 success = doinput(x,ms,mp,flags,incount);
9414 } else { /* REINPUT */
9415 success = doreinp(x,ms[0],itsapattern);
9417 if (intime[cmdlvl] && !success) { /* TIMEOUT-ACTION = QUIT? */
9418 popclvl(); /* If so, pop command level. */
9419 if (pflag && cmdlvl == 0) {
9420 if (cx == XXINP) printf("?INPUT timed out\n");
9421 if (cx == XXMINP) printf("?MINPUT timed out\n");
9422 if (cx == XXREI) printf("?REINPUT failed\n");
9425 return(success); /* Return do(re)input's return code */
9430 if (cx == XXLOG) { /* LOG */
9431 x = cmkey(logtab,nlog,"What to log","",xxstring);
9433 printf("?Type of log required\n");
9436 if (x < 0) return(x);
9441 return(success = x);
9444 if (cx == XXLOGIN) { /* (REMOTE) LOGIN */
9446 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
9447 return(success = doftpusr());
9451 printf("?Already logged in\n");
9459 return(dormt(XZLGI));
9463 if (cx == XXLOGOUT) { /* (REMOTE) LOGOUT */
9465 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
9466 return(success = doftpres());
9471 if ((x = cmcfm()) < 0)
9473 doexit(GOOD_EXIT,xitsta);
9476 if (!local || (network && ttchk() < 0)) {
9477 printf("?No connection.\n");
9483 return(dormt(XZLGO));
9489 if (cx == XXLOGI) { /* UUCP-style script */
9490 if ((x = cmtxt("expect-send expect-send ...","",&s,xxstring)) < 0)
9493 if ((apcactive == APC_LOCAL) ||
9494 ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
9495 return(success = 0);
9498 conres(); /* For Ctrl-C to work... */
9500 return(success = dologin(s)); /* Return 1=completed, 0=failed */
9502 #endif /* NOSCRIPT */
9506 if (cx == XXCREC) { /* CRECEIVE */
9507 if (protocol != PROTO_K) {
9508 printf("?Sorry, CRECEIVE works only with Kermit protocol\n");
9513 if (cx == XXCGET) { /* CGET */
9516 #endif /* PIPESEND */
9518 if (cx == XXREC) /* RECEIVE */
9523 if (cx == XXREM) { /* REMOTE */
9525 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
9526 return(doftprmt(0,0));
9529 if (protocol != PROTO_K) {
9530 printf("Sorry, REMOTE commands only work with Kermit protocol\n");
9534 x = cmkey(remcmd,nrmt,"Remote Kermit server command","",xxstring);
9536 printf("?You must specify a command for the remote server\n");
9545 if (cx == XXREN || cx == XXLREN) { /* RENAME */
9547 if (!locus && cx != XXLREN) {
9551 return(dormt(XZREN));
9556 if (inserver && (!ENABLED(en_ren)
9559 #endif /* CK_LOGIN */
9561 printf("?Sorry, renaming of files is disabled\n");
9566 if ((apcactive == APC_LOCAL) ||
9567 ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
9568 return(success = 0);
9572 #endif /* NOFRILLS */
9573 #endif /* NORENAME */
9575 if (cx == XXEIGHT) { /* EIGHTBIT */
9576 extern int parity, cmask, cmdmsk;
9577 if ((x = cmcfm()) < 0)
9582 return(success = 1);
9586 /* SEND, CSEND, MOVE, MAIL, and RESEND use the new common code */
9588 if (cx == XXSEN /* SEND */
9590 || cx == XXCSEN /* CSEND */
9591 #endif /* PIPESEND */
9592 || cx == XXMOVE /* MOVE */
9593 || cx == XXMAI /* MAIL */
9595 || cx == XXRSEN /* RESEND */
9596 #endif /* CK_RESEND */
9599 if (inserver && !ENABLED(en_get)) {
9600 printf("?Sorry, sending files is disabled\n");
9604 return(doxsend(cx));
9607 /* PSEND, ADD, and REMOVE use special parsing */
9610 /* ADD and REMOVE */
9611 if (cx == XXADD || cx == XXREMV) {
9613 m = (cx == XXADD) ? "Add to which list?" : "Remove from which list?";
9614 x = cmkey(addtab,naddtab,m,"",xxstring);
9619 return(addsend(cx));
9621 #endif /* NOMSEND */
9622 return(doadd(cx,x));
9627 if (cx == XXPSEN) { /* PSEND */
9628 int seekto = 0; /* FIX THIS */
9630 cmarg = cmarg2 = "";
9631 x = cmifi("File to partially send", "", &s, &y, xxstring);
9634 printf("?A file specification is required\n");
9638 nfils = -1; /* Files come from internal list. */
9640 addlist = 0; /* Don't use SEND-LIST. */
9642 #endif /* NOMSEND */
9643 ckstrncpy(line,s,LINBUFSIZ); /* Save copy of string just parsed. */
9644 debug(F110,"PSEND line",line,0);
9646 printf("?Sorry, wildcards not permitted in this command\n");
9649 if (sizeof(int) < 4) {
9650 printf("?Sorry, this command needs 32-bit integers\n");
9653 x = cmnum("starting position (byte number)",
9654 "",10,&seekto,xxstring);
9657 zfnqfp(s,fspeclen,fspec); /* Get full path */
9658 if ((x = cmtxt("Name to send it with","",&s,NULL)) < 0)
9660 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
9663 if (inserver && !ENABLED(en_get)) {
9664 printf("?Sorry, sending files is disabled\n");
9670 printf("?Sorry, no PSEND while SEND FILTER selected\n");
9673 #endif /* PIPESEND */
9675 if ((protocol == PROTO_X || protocol == PROTO_XC)) {
9676 printf("Sorry, PSEND works only with Kermit protocol\n");
9681 cmarg2 = brstrip(tmpbuf); /* Strip braces */
9682 cmarg = line; /* File to send */
9683 debug(F110,"PSEND filename",cmarg,0);
9684 debug(F110,"PSEND as-name",cmarg2,0);
9686 sstate = 's'; /* Set start state to SEND */
9690 #endif /* NOMSEND */
9691 sendmode = SM_PSEND;
9696 if (local) { /* If in local mode, */
9697 displa = 1; /* enable file transfer display */
9701 #endif /* CK_RESEND */
9706 if (cx == XXMSE || cx == XXMMOVE) {
9708 if ((ftpget == 1) || ((ftpget == 2) && ftpisopen()))
9709 return(doftpput(cx,0));
9712 if (protocol == PROTO_X || protocol == PROTO_XC) {
9714 "Sorry, you can only send one file at a time with XMODEM protocol\n"
9719 return(doxsend(cx));
9722 #ifdef COMMENT /* (moved to doxsend) */
9723 if (cx == XXMSE || cx == XXMMOVE) { /* MSEND and MMOVE commands */
9724 nfils = 0; /* Like getting a list of */
9725 lp = line; /* files on the command line */
9726 addlist = 0; /* Do not use SEND-LIST */
9727 filenext = NULL; /* Ditto ! */
9731 if ((x = cmifi("Names of files to send, separated by spaces","",
9732 &s,&y,xxstring)) < 0) {
9735 printf("?A file specification is required\n");
9741 msfiles[nfils++] = lp; /* Got one, count it, point to it, */
9742 p = lp; /* remember pointer, */
9743 while (*lp++ = *s++) /* and copy it into buffer */
9744 if (lp > (line + LINBUFSIZ)) { /* Avoid memory leak */
9745 printf("?MSEND list too long\n");
9749 debug(F111,"msfiles",msfiles[nfils-1],nfils-1);
9750 if (nfils == 1) *fspec = NUL; /* Take care of \v(filespec) */
9752 zfnqfp(p,TMPBUFSIZ,tmpbuf);
9755 if (((int)strlen(fspec) + (int)strlen(p) + 1) < fspeclen) {
9756 strcat(fspec,p); /* safe */
9757 strcat(fspec," "); /* safe */
9758 } else printf("WARNING - \\v(filespec) buffer overflow\n");
9760 cmlist = msfiles; /* Point cmlist to pointer array */
9761 cmarg2 = ""; /* No internal expansion list (yet) */
9762 sndsrc = nfils; /* Filenames come from cmlist */
9763 sendmode = SM_MSEND; /* Remember this kind of SENDing */
9764 sstate = 's'; /* Set start state for SEND */
9765 if (cx == XXMMOVE) /* If MMOVE'ing, */
9766 moving = 1; /* set this flag. */
9771 if (local) { /* If in local mode, */
9772 displa = 1; /* turn on file transfer display */
9773 ttflui(); /* and flush tty input buffer. */
9777 #endif /* COMMENT */
9778 #endif /* NOMSEND */
9782 if (cx == XXSER) { /* SERVER */
9784 if (protocol != PROTO_K) {
9785 printf("Sorry, SERVER only works with Kermit protocol\n");
9791 Parse for time limit, but since we don't use it yet,
9792 the parsing is commented out.
9794 x_ifnum = 1; /* Turn off internal complaints */
9795 y = cmnum("optional time limit, seconds, or time of day as hh:mm:ss",
9796 "0", 10, &x, xxstring
9800 if (y == -2) { /* Invalid number or expression */
9801 zz = tod2sec(atmbuf); /* Convert to secs since midnight */
9803 printf("?Number, expression, or time of day required\n");
9806 char now[32]; /* Current time */
9811 tnow = atol(p+11) * 3600L + atol(p+14) * 60L + atol(p+17);
9812 if (zz < tnow) /* User's time before now */
9813 zz += 86400L; /* So make it tomorrow */
9814 zz -= tnow; /* Seconds from now. */
9821 if (zz != (long) x) {
9823 "Sorry, arithmetic overflow - hh:mm:ss not usable on this platform.\n"
9830 #endif /* COMMENT */
9832 if ((x = cmcfm()) < 0) return(x);
9838 if (local) displa = 1;
9840 reqoff(); /* No DOS requestors while server */
9844 #endif /* NOSERVER */
9846 if (cx == XXSAVE) { /* SAVE command */
9847 x = cmkey(savtab,nsav,"option","keymap",xxstring);
9849 printf("?You must specify an option to save\n");
9852 if (x < 0) return(x);
9853 /* have to set success separately for each item in doprm()... */
9854 /* actually not really, could have just had doprm return 0 or 1 */
9855 /* and set success here... */
9858 printf("?More fields required\n");
9863 if (cx == XXSET) { /* SET command */
9864 x = cmkey(prmtab,nprm,"Parameter","",xxstring);
9866 printf("?You must specify a parameter to set\n");
9869 if (x < 0) return(x);
9870 /* have to set success separately for each item in doprm()... */
9871 /* actually not really, could have just had doprm return 0 or 1 */
9872 /* and set success here... */
9875 printf("?More fields required\n");
9881 if (cx == XXSHE /* SHELL (system) command */
9882 || cx == XXEXEC /* exec() */
9889 #endif /* UNIXOROSK */
9892 if (inserver && (nopush || !ENABLED(en_hos))) {
9893 printf("?Sorry, host command access is disabled\n");
9899 if (cx == XXEXEC) { /* EXEC (overlay ourselves) */
9901 cmfdbi(&sw, /* First FDB - command switches */
9903 "Command to overlay C-Kermit\n or switch", /* hlpmsg */
9905 "", /* addtl string data */
9906 1, /* addtl numeric data 1: tbl size */
9907 4, /* addtl numeric data 2: 4 = cmswi */
9908 xxstring, /* Processing function */
9909 redirsw, /* Keyword table */
9910 &fl /* Pointer to next FDB */
9912 cmfdbi(&fl, /* 2nd FDB - command to exec */
9914 "Command to overlay C-Kermit", /* hlpmsg */
9916 "", /* addtl string data */
9917 0, /* addtl numeric data 1 */
9918 0, /* addtl numeric data 2 */
9921 NULL /* No more after this */
9924 x = cmfdb(&sw); /* Parse something */
9925 debug(F101,"exec cmfdb","",x);
9928 /* Generalize this if we add more switches */
9929 if (cmresult.fcode == _CMKEY) {
9933 if (cmresult.fcode == _CMFLD)
9937 ckstrncpy(tmpbuf,cmresult.sresult,TMPBUFSIZ);
9939 printf("?Command required\n");
9942 p = brstrip(tmpbuf);
9943 args[0] = NULL; /* Set argv[0] to it */
9944 makestr(&args[0],p);
9945 for (i = 1; i < 255; i++) { /* Get arguments for command */
9946 if ((x = cmfld("Argument","",&s,xxstring)) < 0) {
9948 if ((x = cmcfm()) < 0)
9956 makestr(&args[i],s);
9961 if ((x = cmtxt("System command to execute","",&s,xxstring)) < 0)
9967 return(success = 0);
9969 if (apcactive == APC_REMOTE && !(apcstatus & APC_UNCH))
9970 return(success = 0);
9972 conres(); /* Make console normal */
9976 return(success = 1);
9981 debug(F101,"RUN zshcmd code","",x);
9982 concb((char)escape);
9983 return(success = x);
9988 debug(F111,"EXEC cmd",p,0);
9989 for (i = 0; i < 256 && args[i]; i++)
9990 debug(F111,"EXEC arg",args[i],i);
9994 z_exec(p,args,rx); /* Overlay ourself */
9995 debug(F100,"EXEC fails","",0);
9996 concb((char)escape); /* In case it returns */
9998 return(success = 0);
10004 if (cx == XXFUN) { /* REDIRECT */
10006 if ((apcactive == APC_LOCAL) ||
10007 ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
10008 return(success = 0);
10009 #endif /* CK_APC */
10012 "Local command to run,\n",
10013 "with its standard input/output redirected to ",
10014 local ? ttname : "the communications connection",
10017 if ((x = cmtxt(tmpbuf,"",&s,xxstring)) < 0)
10020 printf("?REDIRECT disabled\n");
10024 printf("?SET LINE or SET HOST required first\n");
10028 printf("?REDIRECT requires a command to redirect\n");
10031 return(success = ttruncmd(s));
10033 #endif /* CK_REDIR */
10034 #endif /* NOPUSH */
10037 if (cx == XXSHO) { /* SHOW */
10038 x = cmkey(shotab,nsho,"","parameters",xxstring);
10039 if (x < 0) return(x);
10042 #endif /* NOSHOW */
10045 if (cx == XXSPA) { /* SPACE */
10047 if (inserver && !ENABLED(en_spa)) {
10048 printf("?Sorry, SPACE command disabled\n");
10053 /* AOS/VS can take an argument after its "space" command. */
10054 if ((x = cmtxt("Confirm, or local directory name","",&s,xxstring)) < 0)
10057 printf("?Sorry, SPACE command disabled\n");
10059 } else if (*s == NUL) {
10062 ckmakmsg(line,LINBUFSIZ,"space ",s,NULL,NULL);
10067 if ((x = cmtxt("Press Enter for current disk,\n\
10068 or specify a disk letter like A:","",&s,xxstring)) < 0)
10070 if (*s == NUL) { /* Current disk */
10071 unsigned long space = zdskspace(0);
10072 if (space > 0 && space < 1024)
10073 printf(" Free space: unknown\n");
10075 printf(" Free space: %ldK\n", space/1024L);
10077 int drive = toupper(*s);
10078 unsigned long space = zdskspace(drive - 'A' + 1);
10079 if (space > 0 && space < 1024)
10080 printf(" Drive %c: unknown free\n");
10082 printf(" Drive %c: %ldK free\n", drive,space / 1024L);
10086 x = cmdir("Confirm for current disk,\n\
10087 or specify a disk device or directory","",&s,xxstring);
10092 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
10094 if ((x = cmcfm()) < 0) return(x);
10096 printf("?Sorry, SPACE command disabled\n");
10099 if (!*s) { /* Current disk */
10101 } else { /* Specified disk */
10102 ckmakmsg(line,LINBUFSIZ,SPACM2," ",s,NULL);
10106 if ((x = cmcfm()) < 0) return(x);
10108 printf("?Sorry, SPACE command disabled\n");
10112 #endif /* UNIXOROSK */
10114 #endif /* datageneral */
10115 return(success = 1); /* Pretend it worked */
10120 if (cx == XXSTA) { /* STATISTICS */
10121 if ((x = cmkey(stattab,2,"Carriage return, or option",
10122 "/brief",xxstring)) < 0)
10124 if ((y = cmcfm()) < 0) return(y);
10125 return(success = dostat(x));
10127 #endif /* NOXFER */
10129 if (cx == XXSTO || cx == XXEND) { /* STOP, END, or POP */
10130 if ((y = cmnum("exit status code","0",10,&x,xxstring)) < 0)
10132 if ((y = cmtxt("Message to print","",&s,xxstring)) < 0)
10135 if (*s) printf("%s\n",s);
10141 return(success = (x == 0));
10143 if (cx == XXSUS) { /* SUSPEND */
10144 if ((y = cmcfm()) < 0) return(y);
10146 printf("Sorry, this version of Kermit cannot be suspended\n");
10150 printf("?Sorry, IKSD can not be suspended\n");
10155 printf("?Sorry, access to system is disabled\n");
10163 if (cx == XXTAK) { /* TAKE */
10164 char * scriptenv = NULL;
10166 char * GetAppData(int);
10167 extern char startupdir[],exedir[],inidir[];
10168 char * keymapenv = NULL;
10169 char * appdata0 = NULL, *appdata1 = NULL;
10171 #define TAKEPATHLEN 4096
10173 #define TAKEPATHLEN 1024
10175 char takepath[TAKEPATHLEN];
10177 if (tlevel >= MAXTAKE-1) {
10178 printf("?Take files nested too deeply\n");
10183 scriptenv = getenv("K95SCRIPTS");
10184 keymapenv = getenv("K95KEYMAPS");
10185 makestr(&appdata0,(char *)GetAppData(0));
10186 makestr(&appdata1,(char *)GetAppData(1));
10188 scriptenv = getenv("K2SCRIPTS");
10189 keymapenv = getenv("K2KEYMAPS");
10193 if (!scriptenv) /* Let this work for Unix etc too */
10194 scriptenv = getenv("CK_SCRIPTS"); /* Use this if defined */
10196 if (!scriptenv) /* Otherwise use home directory */
10197 scriptenv = homepath();
10201 ckstrncpy(takepath,scriptenv,TAKEPATHLEN);
10202 debug(F110,"TAKE initial takepath",takepath,0);
10206 keymapenv = getenv("CK_KEYMAPS");
10210 ckstrncat(takepath,
10211 (scriptenv && scriptenv[strlen(scriptenv)-1]==';')?"":";",
10214 ckstrncat(takepath,keymapenv?keymapenv:"",TAKEPATHLEN);
10215 ckstrncat(takepath,
10216 (keymapenv && keymapenv[strlen(keymapenv)-1]==';')?"":";",
10219 ckstrncat(takepath,startupdir,TAKEPATHLEN);
10220 ckstrncat(takepath,";",TAKEPATHLEN);
10221 ckstrncat(takepath,startupdir,TAKEPATHLEN);
10222 ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
10223 ckstrncat(takepath,startupdir,TAKEPATHLEN);
10224 ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
10226 ckstrncat(takepath,appdata1,TAKEPATHLEN);
10227 ckstrncat(takepath,"Kermit 95/;",TAKEPATHLEN);
10228 ckstrncat(takepath,appdata1,TAKEPATHLEN);
10229 ckstrncat(takepath,"Kermit 95/SCRIPTS/;",TAKEPATHLEN);
10230 ckstrncat(takepath,appdata1,TAKEPATHLEN);
10231 ckstrncat(takepath,"Kermit 95/KEYMAPS/;",TAKEPATHLEN);
10233 ckstrncat(takepath,appdata0,TAKEPATHLEN);
10234 ckstrncat(takepath,"Kermit 95/;",TAKEPATHLEN);
10235 ckstrncat(takepath,appdata0,TAKEPATHLEN);
10236 ckstrncat(takepath,"Kermit 95/SCRIPTS/;",TAKEPATHLEN);
10237 ckstrncat(takepath,appdata0,TAKEPATHLEN);
10238 ckstrncat(takepath,"Kermit 95/KEYMAPS/;",TAKEPATHLEN);
10240 ckstrncat(takepath,inidir,TAKEPATHLEN);
10241 ckstrncat(takepath,";",TAKEPATHLEN);
10242 ckstrncat(takepath,inidir,TAKEPATHLEN);
10243 ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
10244 ckstrncat(takepath,inidir,TAKEPATHLEN);
10245 ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
10247 ckstrncat(takepath,zhome(),TAKEPATHLEN);
10248 ckstrncat(takepath,";",TAKEPATHLEN);
10249 ckstrncat(takepath,zhome(),TAKEPATHLEN);
10250 ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
10251 ckstrncat(takepath,zhome(),TAKEPATHLEN);
10252 ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
10254 ckstrncat(takepath,exedir,TAKEPATHLEN);
10255 ckstrncat(takepath,";",TAKEPATHLEN);
10256 ckstrncat(takepath,exedir,TAKEPATHLEN);
10257 ckstrncat(takepath,"SCRIPTS/;",TAKEPATHLEN);
10258 ckstrncat(takepath,exedir,TAKEPATHLEN);
10259 ckstrncat(takepath,"KEYMAPS/;",TAKEPATHLEN);
10261 debug(F110,"TAKE final takepath",takepath,0);
10263 if ((y = cmifip("Commands from file",
10264 "",&s,&x,0,takepath,xxstring)) < 0) {
10266 printf("?A file name is required\n");
10272 printf("?Wildcards not allowed in command file name\n");
10275 ckstrncpy(line,s,LINBUFSIZ);
10276 debug(F110,"TAKE file",s,0);
10278 printf("?Can't execute a directory - \"%s\"\n", s);
10285 debug(F111,"TAKE args",line,x);
10287 if ((y = cmtxt("Optional arguments","",&s,xxstring)) < 0)
10289 if (*s) { /* Args given? */
10290 ckstrncpy(p,s,LINBUFSIZ-x-1);
10292 zfnqfp(line,TMPBUFSIZ,tmpbuf);
10296 #endif /* ZFNQFP */
10297 debug(F110,"TAKE filename",s,0);
10299 debug(F101,"TAKE new len",s,x);
10303 This was added in C-Kermit 7.0 to allow args to be passed from the TAKE
10304 command to the command file. But it overwrites the current argument vector,
10305 which is at best surprising, and at worst unsafe.
10307 addmac("%0",s); /* Define %0 = name of file */
10310 debug(F110,"take arg 0",s,0);
10311 debug(F110,"take args",p,0);
10312 for (y = 1; y < 10; y++) { /* Clear current args %1..%9 */
10313 varnam[1] = (char) (y + '0');
10316 xwords(p,MAXARGLIST,NULL,0); /* Assign new args */
10317 debug(F110,"take args",p,0);
10320 This method is used in 8.0. If the TAKE command includes arguments, we
10321 insert an intermediate temporary macro between the current level; we pass
10322 the arguments to the macro and then the macro TAKEs the command file.
10323 If the user Ctrl-C's out of the TAKE file, some temporary macro definitions
10324 and other small malloc'd bits might be left behind.
10331 q = (char *)malloc(x+24);
10333 r = (char *)malloc(x+24);
10335 sprintf(q,"_file[%s](%d)",s,cmdlvl); /* safe */
10336 sprintf(r,"take %s",s); /* safe */
10340 while (maclvl > m) {
10341 sstate = (CHAR) parser(1);
10342 if (sstate) proto();
10352 return(success = 0);
10353 #endif /* COMMENT */
10357 if ((y = cmcfm()) < 0) return(y);
10358 #endif /* NOTAKEARGS */
10359 return(success = dotake(line));
10364 if (cx == XXVIEW) { /* VIEW Only Terminal mode */
10366 success = doconect(0, 0);
10373 if (cx == XXTEL || cx == XXIKSD) { /* TELNET */
10377 printf("?Sorry, either TCP/IP is not available on this system or\n\
10378 necessary DLLs did not load. Use SHOW NETWORK to check network status.\n");
10384 x = nettype; /* Save net type in case of failure */
10385 z = ttnproto; /* Save protocol in case of failure */
10386 nettype = NET_TCPB;
10387 ttnproto = (cx == XXTEL) ? NP_TELNET : NP_KERMIT;
10388 if ((y = setlin(XYHOST,0,1)) <= 0) {
10389 nettype = x; /* Failed, restore net type. */
10390 ttnproto = z; /* and protocol */
10404 #endif /* NETPTY */
10405 #endif /* NETCMD */
10406 #endif /* PTYORPIPE */
10409 if (cx == XXPIPE || cx == XXPTY) { /* PIPE or PTY */
10411 extern int netsave;
10412 x = nettype; /* Save net type in case of failure */
10413 nettype = (cx == XXPIPE) ? NET_CMD : NET_PTY;
10414 if ((y = setlin(XYHOST,0,1)) < 0) {
10415 nettype = x; /* Failed, restore net type. */
10416 ttnproto = z; /* and protocol */
10423 #endif /* PTYORPIPE */
10426 if (cx == XXSSH) { /* SSH (Secure Shell) */
10427 extern int netsave;
10429 int k, x, havehost = 0, trips = 0;
10430 int tmpver = -1, tmpxfw = -1;
10432 extern int sl_ssh_xfw, sl_ssh_xfw_saved;
10433 extern int sl_ssh_ver, sl_ssh_ver_saved;
10434 #endif /* SSHTEST */
10435 extern int mdmtyp, mdmsav, cxtype, sl_uid_saved;
10436 extern char * slmsg;
10437 extern char uidbuf[], sl_uidbuf[];
10438 extern char pwbuf[], * g_pswd;
10439 extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
10440 struct FDB sw, kw, fl;
10443 memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
10444 makestr(&ssh_tmpstr,NULL);
10445 makestr(&ssh_tmpuid,NULL);
10446 makestr(&ssh_tmpcmd,NULL);
10447 makestr(&ssh_tmpport,NULL);
10449 cmfdbi(&kw, /* 1st FDB - commands */
10450 _CMKEY, /* fcode */
10451 "host [ port ],\n or action", /* hlpmsg */
10453 "", /* addtl string data */
10454 nsshcmd, /* addtl numeric data 1: tbl size */
10455 0, /* addtl numeric data 2: 0 = keyword */
10456 xxstring, /* Processing function */
10457 sshkwtab, /* Keyword table */
10458 &fl /* Pointer to next FDB */
10460 cmfdbi(&fl, /* Host */
10461 _CMFLD, /* fcode */
10464 "", /* addtl string data */
10465 0, /* addtl numeric data 1 */
10466 0, /* addtl numeric data 2 */
10474 printf("?ssh what?\n");
10480 if (cmresult.fcode == _CMFLD) {
10482 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Hostname */
10483 cmresult.nresult = XSSH_OPN;
10485 switch (cmresult.nresult) { /* SSH keyword */
10486 case XSSH_OPN: /* SSH OPEN */
10488 if ((x = cmfld("Host","",&s,xxstring)) < 0)
10490 ckstrncpy(line,s,LINBUFSIZ);
10492 /* Parse [ port ] [ switches ] */
10493 cmfdbi(&kw, /* Switches */
10495 "Port number or service name,\nor switch",
10504 cmfdbi(&fl, /* Port number or service name */
10515 trips = 0; /* Explained below */
10516 while (1) { /* Parse port and switches */
10517 x = cmfdb(&kw); /* Get a field */
10518 if (x == -3) /* User typed CR so quit from loop */
10520 if (x < 0) /* Other parse error, pass it back */
10522 switch (cmresult.fcode) { /* Field or Keyword? */
10523 case _CMFLD: /* Field */
10524 makestr(&ssh_tmpport,cmresult.sresult);
10526 case _CMKEY: /* Keyword */
10527 switch (cmresult.nresult) { /* Which one? */
10528 case SSHSW_USR: /* /USER: */
10530 printf("?This switch requires an argument\n");
10533 if ((y = cmfld("Username","",&s,xxstring)) < 0)
10536 makestr(&ssh_tmpuid,s);
10540 printf("?This switch requires an argument\n");
10544 if ((x = cmfld("Password","",&s,xxstring)) < 0) {
10546 makestr(&ssh_tmpstr,"");
10552 if ((x = (int)strlen(s)) > PWBUFL) {
10553 makestr(&slmsg,"Internal error");
10554 printf("?Sorry, too long - max = %d\n",PWBUFL);
10557 makestr(&ssh_tmpstr,s);
10562 if ((x = cmnum("Number","",10,&z,xxstring)) < 0)
10564 if (z < 1 || z > 2) {
10565 printf("?Out of range: %d\n",z);
10572 if ((x = cmfld("Text","",&s,xxstring)) < 0)
10574 makestr(&ssh_tmpcmd,s);
10575 ssh_cas = (cmresult.nresult == SSHSW_SUB);
10578 if ((x = cmkey(onoff,2,"","on",xxstring)) < 0)
10586 if (trips++ == 0) { /* After first time through */
10587 cmfdbi(&kw, /* only parse switches, not port. */
10600 if ((x = cmcfm()) < 0) /* Get confirmation */
10602 if (clskconnx(1) < 0) { /* Close current Kermit connection */
10603 if ( ssh_tmpstr ) {
10604 memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
10605 makestr(&ssh_tmpstr,NULL);
10607 return(success = 0);
10609 makestr(&ssh_hst,line); /* Stash everything */
10611 if (!sl_uid_saved) {
10612 ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
10615 ckstrncpy(uidbuf,ssh_tmpuid,UIDBUFLEN);
10616 makestr(&ssh_tmpuid,NULL);
10619 makestr(&ssh_prt,ssh_tmpport);
10620 makestr(&ssh_tmpport,NULL);
10622 makestr(&ssh_prt,NULL);
10625 makestr(&ssh_cmd,brstrip(ssh_tmpcmd));
10626 makestr(&ssh_tmpcmd,NULL);
10628 makestr(&ssh_cmd,NULL);
10632 if (!sl_ssh_ver_saved) {
10633 sl_ssh_ver = ssh_ver;
10634 sl_ssh_ver_saved = 1;
10636 #endif /* SSHTEST */
10641 if (!sl_ssh_xfw_saved) {
10642 sl_ssh_xfw = ssh_xfw;
10643 sl_ssh_xfw_saved = 1;
10645 #endif /* SSHTEST */
10649 if (ssh_tmpstr[0]) {
10650 ckstrncpy(pwbuf,ssh_tmpstr,PWBUFL+1);
10655 makestr(&ssh_tmpstr,NULL);
10664 makestr(&g_pswd,pwbuf); /* Save global pwbuf */
10665 g_pflg = pwflg; /* and flag */
10669 /* Line parameter to ttopen() is ignored */
10670 debug(F110,"SSH line",line,0);
10671 k = ttopen(line,&x,mdmtyp, 0);
10673 printf("?Unable to connect to %s\n",ssh_hst);
10676 return(success = 0);
10678 duplex = 0; /* Remote echo */
10679 ckstrncpy(ttname,line,TTNAMLEN); /* Record the command */
10680 debug(F110,"ssh ttname",ttname,0);
10681 makestr(&slmsg,NULL); /* No SET LINE error message */
10685 #endif /* NODIAL */
10686 success = 1; /* SET LINE succeeded */
10687 network = 1; /* Network connection (not serial) */
10688 local = 1; /* Local mode (not remote) */
10689 if ((reliable != SET_OFF || !setreliable))
10690 reliable = SET_ON; /* Transport is reliable end to end */
10692 DialerSend(OPT_KERMIT_CONNECT, 0);
10694 setflow(); /* Set appropriate flow control */
10700 #endif /* NETCONN */
10701 #endif /* CKLOGDIAL */
10705 if (nmac) { /* Any macros defined? */
10707 k = mlook(mactab,"on_open",nmac); /* Look this up */
10708 if (k >= 0) { /* If found, */
10709 if (dodo(k,ssh_hst,0) > -1) /* set it up, */
10710 parser(1); /* and execute it */
10720 /* Command was confirmed so we can pre-pop command level. */
10721 /* This is so CONNECT module won't think we're executing a */
10722 /* script if CONNECT was the final command in the script. */
10725 success = doconect(0,cmdlvl == 0 ? 1 : 0);
10731 if ((y = cmkey(sshclr,nsshclr,"","", xxstring)) < 0) {
10733 printf("?clear what?\n");
10738 if ((x = cmcfm()) < 0)
10750 return(success = 1); /* or whatever */
10752 case XSSH_AGT: { /* SSH AGENT */
10754 if ((y = cmkey(sshagent,nsshagent,"","",xxstring)) < 0)
10757 case SSHA_ADD: /* SSH AGENT ADD ... */
10758 if ((x = cmifi("Identity file","",&s,&y,xxstring)) < 0) {
10760 if (x == -3) /* No name given */
10761 doeach = 1; /* so do them all */
10763 #endif /* SSHTEST */
10766 ckstrncpy(line,s,LINBUFSIZ);
10767 if ((x = cmcfm()) < 0)
10775 for (i = 0; i < ssh_idf_n; i++)
10776 x += ssh_agent_add_file(ssh_idf[i]);
10778 x = ssh_agent_add_file(line);
10779 #endif /* SSHTEST */
10780 return(success = (x == 0));
10782 case SSHA_DEL: { /* SSH AGENT DELETE ... */
10784 if ((x = cmifi("Identity file","",&s,&y,xxstring)) < 0) {
10786 if (x == -3) /* No name given */
10787 doall = 1; /* so do them all */
10789 #endif /* SSHTEST */
10792 ckstrncpy(line,s,LINBUFSIZ);
10793 if ((x = cmcfm()) < 0)
10799 x = ssh_agent_delete_all();
10801 x = ssh_agent_delete_file(line);
10802 #endif /* SSHTEST */
10803 return(success = (x == 0));
10806 int fingerprint = 0;
10807 if ((y = cmswi(sshagtsw,nsshagtsw,"","",xxstring)) < 0) {
10810 } else if (cmgbrk() > SP) {
10811 printf("?This switch does not take an argument\n");
10813 } else if (y == SSHASW_FP) {
10816 if ((x = cmcfm()) < 0)
10819 return(success = 1);
10822 (ssh_agent_list_identities(fingerprint) == 0));
10823 #endif /* SSHTEST */
10829 case XSSH_ADD: { /* SSH ADD */
10830 /* ssh add { local, remote } port host port */
10833 if ((cx = cmkey(addfwd,naddfwd,"","", xxstring)) < 0)
10835 if ((x = cmnum((cx == SSHF_LCL) ?
10836 "Local port number" : "Remote port number",
10837 "",10,&j,xxstring)) < 0)
10839 if ((x = cmfld("Host","",&s,xxstring)) < 0)
10842 if ((x = cmnum("Port","",10,&k,xxstring)) < 0)
10844 if ((x = cmcfm()) < 0)
10849 if (ssh_pf_lcl_n == 32) {
10851 "?Maximum number of local port forwardings already specified\n"
10854 return(success = 0);
10856 ssh_pf_lcl[ssh_pf_lcl_n].p1 = j;
10857 makestr(&(ssh_pf_lcl[ssh_pf_lcl_n].host),h);
10859 ssh_pf_lcl[ssh_pf_lcl_n].p2 = k;
10863 if (ssh_pf_rmt_n == 32) {
10865 "?Maximum number of remote port forwardings already specified\n"
10868 return(success = 0);
10870 ssh_pf_rmt[ssh_pf_rmt_n].p1 = j;
10871 makestr(&(ssh_pf_rmt[ssh_pf_rmt_n].host),h);
10873 ssh_pf_rmt[ssh_pf_rmt_n].p2 = k;
10876 return(success = 1);
10878 /* Not supporting arbitrary forwarding yet */
10879 case XSSH_FLP: /* SSH FORWARD-LOCAL-PORT */
10880 case XSSH_FRP: { /* SSH FORWARD-REMOTE-PORT */
10883 char * fw_host = NULL;
10885 if ((x = cmnum(cmresult.nresult == XSSH_FLP ?
10886 "local-port":"remote-port",
10887 "",10,&li_port,xxstring)) < 0)
10889 if (li_port < 1 || li_port > 65535) {
10890 printf("?Out range - min: 1, max: 65535\n");
10893 if ((x = cmfld("host",ssh_hst?ssh_hst:"",&s,xxstring)) < 0)
10895 n = ckstrncpy(tmpbuf,s,TMPBUFSIZ);
10897 if ((x = cmnum("host-port",ckuitoa(li_port),10,
10898 &to_port,xxstring)) < 0)
10900 if (to_port < 1 || to_port > 65535) {
10901 printf("?Out range - min: 1, max: 65535\n");
10904 if ((x = cmcfm()) < 0)
10906 switch (cmresult.nresult) {
10907 case XSSH_FLP: /* SSH FORWARD-LOCAL-PORT */
10909 ssh_fwd_local_port(li_port,fw_host,to_port);
10910 #endif /* SSHTEST */
10911 return(success = 1);
10912 case XSSH_FRP: /* SSH FORWARD-REMOTE-PORT */
10914 ssh_fwd_remote_port(li_port,fw_host,to_port);
10915 #endif /* SSHTEST */
10916 return(success = 1);
10918 return(success = 1);
10920 case XSSH_V2: /* SSH V2 */
10921 if ((cx = cmkey(ssh2tab,nssh2tab,"","", xxstring)) < 0)
10925 if ((x = cmcfm()) < 0)
10929 #endif /* SSHTEST */
10930 return(success = 1);
10935 if ((cx = cmkey(sshkey,nsshkey,"","", xxstring)) < 0)
10938 case SSHK_PASS: { /* Change passphrase */
10939 char * oldp = NULL, * newp = NULL;
10942 _CMKEY, /* fcode */
10943 "Filename, or switch", /* hlpmsg */
10945 "", /* addtl string data */
10946 2, /* addtl numeric data 1: tbl size */
10947 4, /* addtl numeric data 2: 4 = cmswi */
10948 xxstring, /* Processing function */
10949 sshkpsw, /* Keyword table */
10950 &df /* Pointer to next FDB */
10952 cmfdbi(&df, /* 2nd FDB - file for display */
10953 _CMIFI, /* output file */
10956 "", /* addtl string data */
10957 0, /* addtl numeric data 1 */
10958 0, /* addtl numeric data 2 */
10967 if (x == -3) break;
10970 if (cmresult.fcode != _CMKEY)
10973 printf("?This switch requires an argument\n");
10976 if ((y = cmfld("Passphrase","",&s,xxstring)) < 0)
10978 switch (cmresult.nresult) {
10986 if (cmresult.fcode == _CMIFI) { /* Filename */
10987 ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
10988 if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
10989 ckstrncpy(line,tmpbuf,LINBUFSIZ);
10991 if ((x = cmcfm()) < 0) return(x);
10994 x = sshkey_change_passphrase(line[0] ? line : NULL,
10996 #endif /* SSHTEST */
10997 makestr(&oldp,NULL);
10998 makestr(&newp,NULL);
10999 success = (x == 0);
11002 case SSHK_CREA: { /* SSH KEY CREATE /switches... */
11003 int bits = 1024, keytype = SSHKT_2R;
11004 char * pass = NULL, * comment = NULL;
11008 * char * sshkey_default_file(int keytype)
11009 * will provide the default filename for a given keytype
11010 * is it possible to have the default value for the 2nd
11011 * FDB set and changed when a /TYPE switch is provided?
11012 * Would this allow for tab completion of the filename?
11015 _CMKEY, /* fcode */
11016 "Filename, or switch", /* hlpmsg */
11018 "", /* addtl string data */
11019 nsshkcrea, /* addtl numeric data 1: tbl size */
11020 4, /* addtl numeric data 2: 4 = cmswi */
11021 xxstring, /* Processing function */
11022 sshkcrea, /* Keyword table */
11023 &df /* Pointer to next FDB */
11025 cmfdbi(&df, /* 2nd FDB - file for display */
11026 _CMOFI, /* output file */
11029 "", /* addtl string data */
11030 0, /* addtl numeric data 1 */
11031 0, /* addtl numeric data 2 */
11040 if (x == -3) break;
11043 if (cmresult.fcode != _CMKEY)
11046 printf("?This switch requires an argument\n");
11049 switch (cmresult.nresult) {
11050 case SSHKC_BI: /* /BITS:n */
11051 if ((y = cmnum("","1024",10,&z,xxstring)) < 0)
11053 if (z < 512 || z > 4096) {
11054 printf("?Out range - min: 512, max: 4096\n");
11059 case SSHKC_PP: /* /PASSPHRASE:blah */
11060 if ((y = cmfld("Passphrase","",&s,xxstring)) < 0)
11064 case SSHKC_TY: /* /TYPE:keyword */
11065 if ((y = cmkey(sshkcty,nsshkcty,"",
11066 "v2-rsa",xxstring)) < 0)
11070 case SSHKC_1R: /* /COMMENT */
11071 if ((y = cmfld("Text","",&s,xxstring)) < 0)
11073 makestr(&comment,s);
11077 if (cmresult.fcode == _CMOFI) { /* Filename */
11078 if (cmresult.sresult) {
11079 ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
11080 if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
11081 ckstrncpy(line,tmpbuf,LINBUFSIZ);
11084 if ((y = cmcfm()) < 0) /* Confirm */
11087 x = sshkey_create(line[0] ? line : NULL,
11088 bits, pass, keytype, comment);
11090 memset(pass,0,strlen(pass));
11091 #endif /* SSHTEST */
11092 makestr(&pass,NULL);
11093 makestr(&comment,NULL);
11094 return(success = (x == 0));
11096 case SSHK_DISP: { /* SSH KEY DISPLAY /switches... */
11098 int infmt = 0, outfmt = 0;
11101 _CMKEY, /* fcode */
11102 "Filename, or switch", /* hlpmsg */
11104 "", /* addtl string data */
11105 nsshdswi, /* addtl numeric data 1: tbl size */
11106 4, /* addtl numeric data 2: 4 = cmswi */
11107 xxstring, /* Processing function */
11108 sshdswi, /* Keyword table */
11109 &df /* Pointer to next FDB */
11111 cmfdbi(&df, /* 2nd FDB - file for display */
11112 _CMIFI, /* fcode */
11115 "", /* addtl string data */
11116 0, /* addtl numeric data 1 */
11117 0, /* addtl numeric data 2 */
11126 if (x == -3) break;
11129 if (cmresult.fcode != _CMKEY)
11132 printf("?This switch requires an argument\n");
11135 switch (cmresult.nresult) {
11137 case SSHKD_IN: /* /IN-FORMAT: */
11138 if ((y = cmkey(sshdifmt,nsshdifmt,
11139 "","",xxstring)) < 0)
11143 #endif /* COMMENT */
11144 case SSHKD_OUT: /* /FORMAT: */
11145 if ((y = cmkey(sshdofmt,nsshdofmt,
11146 "","",xxstring)) < 0)
11152 if (cmresult.fcode == _CMIFI) { /* Filename */
11153 ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
11154 if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
11155 ckstrncpy(line,tmpbuf,LINBUFSIZ);
11159 printf("?Key filename required\n");
11162 #endif /* COMMENT */
11163 if ((y = cmcfm()) < 0) /* Confirm */
11168 /* 2nd param is optional passphrase */
11169 x = sshkey_display_public(line[0] ? line : NULL, NULL);
11172 /* 2nd param is optional passphrase */
11173 x = sshkey_display_public_as_ssh2(line[0] ? line : NULL,
11177 x = sshkey_display_fingerprint(line[0] ? line : NULL, 1);
11180 x = sshkey_display_fingerprint(line[0] ? line : NULL, 0);
11183 #endif /* SSHTEST */
11184 return(success = (x == 0));
11186 case SSHK_V1: /* SSH KEY V1 SET-COMMENT */
11187 if ((x = cmkey(sshkv1,1,"","set-comment", xxstring)) < 0)
11189 if (x != 1) return(-2);
11190 if ((x = cmifi("Key file name","",&s,&y,xxstring)) < 0) {
11192 printf("?Name of key file required\n");
11196 ckstrncpy(line,s,LINBUFSIZ);
11197 if ((x = cmtxt("Comment text","",&s,xxstring)) < 0)
11200 x = sshkey_v1_change_comment(line, /* filename */
11201 s, /* new comment */
11202 NULL /* passphrase */
11204 #endif /* SSHTEST */
11205 success = (x == 0);
11211 #else /* SSHBUILTIN */
11214 if ((y = setlin(XXSSH,0,1)) < 0) {
11216 printf("?%s\n",ck_errstr());
11219 /* This isn't right either because it catches command editing */
11220 printf("?Sorry, pseudoterminal open failed\n");
11222 printf("Hint: Try \"ssh -t %s\"\n",line);
11225 #endif /* COMMENT */
11226 nettype = x; /* Failed, restore net type. */
11227 ttnproto = z; /* and protocol */
11233 #endif /* SSHCMD */
11234 #endif /* SSHBUILTIN */
11236 #endif /* ANYSSH */
11239 if (cx == XXSKRM) { /* SKERMIT (Secure Shell Kermit) */
11240 extern int netsave;
11241 int k, x, havehost = 0, trips = 0;
11242 int tmpver = -1, tmpxfw = -1;
11244 extern int sl_ssh_xfw, sl_ssh_xfw_saved;
11245 extern int sl_ssh_ver, sl_ssh_ver_saved;
11246 #endif /* SSHTEST */
11247 extern int mdmtyp, mdmsav, cxtype, sl_uid_saved;
11248 extern char * slmsg;
11249 extern char uidbuf[], sl_uidbuf[];
11250 extern char pwbuf[], * g_pswd;
11251 extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
11252 struct FDB sw, kw, fl;
11255 memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
11256 makestr(&ssh_tmpstr,NULL);
11257 makestr(&ssh_tmpuid,NULL);
11258 makestr(&ssh_tmpcmd,NULL);
11259 makestr(&ssh_tmpport,NULL);
11261 cmfdbi(&kw, /* 1st FDB - commands */
11262 _CMKEY, /* fcode */
11263 "host [ port ],\n or action", /* hlpmsg */
11265 "", /* addtl string data */
11266 nsshkermit, /* addtl numeric data 1: tbl size */
11267 0, /* addtl numeric data 2: 0 = keyword */
11268 xxstring, /* Processing function */
11269 sshkermit, /* Keyword table */
11270 &fl /* Pointer to next FDB */
11272 cmfdbi(&fl, /* Host */
11273 _CMFLD, /* fcode */
11276 "", /* addtl string data */
11277 0, /* addtl numeric data 1 */
11278 0, /* addtl numeric data 2 */
11286 printf("?skermit what?\n");
11292 if (cmresult.fcode == _CMFLD) {
11294 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Hostname */
11295 cmresult.nresult = SKRM_OPN;
11297 switch (cmresult.nresult) { /* SSH keyword */
11298 case SKRM_OPN: /* SSH OPEN */
11300 if ((x = cmfld("Host","",&s,xxstring)) < 0)
11302 ckstrncpy(line,s,LINBUFSIZ);
11304 /* Parse [ port ] [ switches ] */
11305 cmfdbi(&kw, /* Switches */
11307 "Port number or service name,\nor switch",
11316 cmfdbi(&fl, /* Port number or service name */
11327 trips = 0; /* Explained below */
11328 while (1) { /* Parse port and switches */
11329 x = cmfdb(&kw); /* Get a field */
11330 if (x == -3) /* User typed CR so quit from loop */
11332 if (x < 0) /* Other parse error, pass it back */
11334 switch (cmresult.fcode) { /* Field or Keyword? */
11335 case _CMFLD: /* Field */
11336 makestr(&ssh_tmpport,cmresult.sresult);
11338 case _CMKEY: /* Keyword */
11339 switch (cmresult.nresult) { /* Which one? */
11340 case SSHSW_USR: /* /USER: */
11342 printf("?This switch requires an argument\n");
11345 if ((y = cmfld("Username","",&s,xxstring)) < 0)
11348 makestr(&ssh_tmpuid,s);
11352 printf("?This switch requires an argument\n");
11356 if ((x = cmfld("Password","",&s,xxstring)) < 0) {
11358 makestr(&ssh_tmpstr,"");
11364 if ((x = (int)strlen(s)) > PWBUFL) {
11365 makestr(&slmsg,"Internal error");
11366 printf("?Sorry, too long - max = %d\n",PWBUFL);
11369 makestr(&ssh_tmpstr,s);
11374 if ((x = cmnum("Number","",10,&z,xxstring)) < 0)
11376 if (z < 1 || z > 2) {
11377 printf("?Out of range: %d\n",z);
11386 if (trips++ == 0) { /* After first time through */
11387 cmfdbi(&kw, /* only parse switches, not port. */
11400 if ((x = cmcfm()) < 0) /* Get confirmation */
11402 if (clskconnx(1) < 0) { /* Close current Kermit connection */
11403 if ( ssh_tmpstr ) {
11404 memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
11405 makestr(&ssh_tmpstr,NULL);
11407 return(success = 0);
11409 makestr(&ssh_hst,line); /* Stash everything */
11411 if (!sl_uid_saved) {
11412 ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
11415 ckstrncpy(uidbuf,ssh_tmpuid,UIDBUFLEN);
11416 makestr(&ssh_tmpuid,NULL);
11419 makestr(&ssh_prt,ssh_tmpport);
11420 makestr(&ssh_tmpport,NULL);
11422 makestr(&ssh_prt,NULL);
11424 /* Set the Subsystem to Kermit */
11426 makestr(&ssh_cmd,"kermit");
11430 if (!sl_ssh_ver_saved) {
11431 sl_ssh_ver = ssh_ver;
11432 sl_ssh_ver_saved = 1;
11434 #endif /* SSHTEST */
11437 /* Disable X11 Forwarding */
11439 if (!sl_ssh_xfw_saved) {
11440 sl_ssh_xfw = ssh_xfw;
11441 sl_ssh_xfw_saved = 1;
11443 #endif /* SSHTEST */
11447 if (ssh_tmpstr[0]) {
11448 ckstrncpy(pwbuf,ssh_tmpstr,PWBUFL+1);
11453 makestr(&ssh_tmpstr,NULL);
11462 makestr(&g_pswd,pwbuf); /* Save global pwbuf */
11463 g_pflg = pwflg; /* and flag */
11467 /* Line parameter to ttopen() is ignored */
11468 k = ttopen(line,&x,mdmtyp, 0);
11470 printf("?Unable to connect to %s\n",ssh_hst);
11473 return(success = 0);
11475 duplex = 0; /* Remote echo */
11476 ckstrncpy(ttname,line,TTNAMLEN); /* Record the command */
11477 debug(F110,"ssh ttname",ttname,0);
11478 makestr(&slmsg,NULL); /* No SET LINE error message */
11482 #endif /* NODIAL */
11483 success = 1; /* SET LINE succeeded */
11484 network = 1; /* Network connection (not serial) */
11485 local = 1; /* Local mode (not remote) */
11486 if ((reliable != SET_OFF || !setreliable))
11487 reliable = SET_ON; /* Transport is reliable end to end */
11489 DialerSend(OPT_KERMIT_CONNECT, 0);
11491 setflow(); /* Set appropriate flow control */
11497 #endif /* NETCONN */
11498 #endif /* CKLOGDIAL */
11502 if (nmac) { /* Any macros defined? */
11504 k = mlook(mactab,"on_open",nmac); /* Look this up */
11505 if (k >= 0) { /* If found, */
11506 if (dodo(k,ssh_hst,0) > -1) /* set it up, */
11507 parser(1); /* and execute it */
11517 /* Command was confirmed so we can pre-pop command level. */
11518 /* This is so CONNECT module won't think we're executing a */
11519 /* script if CONNECT was the final command in the script. */
11522 return(success = 1);
11528 #endif /* SSHBUILTIN */
11530 #ifdef SFTP_BUILTIN
11531 if (cx == XXSFTP) { /* SFTP (Secure Shell File Transfer) */
11532 extern int netsave;
11533 int k, x, havehost = 0, trips = 0;
11534 int tmpver = -1, tmpxfw = -1;
11536 extern int sl_ssh_xfw, sl_ssh_xfw_saved;
11537 extern int sl_ssh_ver, sl_ssh_ver_saved;
11538 #endif /* SSHTEST */
11539 extern int mdmtyp, mdmsav, cxtype, sl_uid_saved;
11540 extern char * slmsg;
11541 extern char uidbuf[], sl_uidbuf[];
11542 extern char pwbuf[], * g_pswd;
11543 extern int pwflg, pwcrypt, g_pflg, g_pcpt, nolocal;
11544 struct FDB sw, kw, fl;
11547 memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
11548 makestr(&ssh_tmpstr,NULL);
11549 makestr(&ssh_tmpuid,NULL);
11550 makestr(&ssh_tmpcmd,NULL);
11551 makestr(&ssh_tmpport,NULL);
11553 cmfdbi(&kw, /* 1st FDB - commands */
11554 _CMKEY, /* fcode */
11555 "host [ port ],\n or action", /* hlpmsg */
11557 "", /* addtl string data */
11558 nsftpkwtab, /* addtl numeric data 1: tbl size */
11559 0, /* addtl numeric data 2: 0 = keyword */
11560 xxstring, /* Processing function */
11561 sftpkwtab, /* Keyword table */
11562 &fl /* Pointer to next FDB */
11564 cmfdbi(&fl, /* Host */
11565 _CMFLD, /* fcode */
11568 "", /* addtl string data */
11569 0, /* addtl numeric data 1 */
11570 0, /* addtl numeric data 2 */
11578 printf("?sftp what?\n");
11584 if (cmresult.fcode == _CMFLD) {
11586 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Hostname */
11587 cmresult.nresult = SFTP_OPN;
11589 switch (cmresult.nresult) { /* SFTP keyword */
11590 case SFTP_OPN: /* SFTP OPEN */
11592 if ((x = cmfld("Host","",&s,xxstring)) < 0)
11594 ckstrncpy(line,s,LINBUFSIZ);
11596 /* Parse [ port ] [ switches ] */
11597 cmfdbi(&kw, /* Switches */
11599 "Port number or service name,\nor switch",
11608 cmfdbi(&fl, /* Port number or service name */
11619 trips = 0; /* Explained below */
11620 while (1) { /* Parse port and switches */
11621 x = cmfdb(&kw); /* Get a field */
11622 if (x == -3) /* User typed CR so quit from loop */
11624 if (x < 0) /* Other parse error, pass it back */
11626 switch (cmresult.fcode) { /* Field or Keyword? */
11627 case _CMFLD: /* Field */
11628 makestr(&ssh_tmpport,cmresult.sresult);
11630 case _CMKEY: /* Keyword */
11631 switch (cmresult.nresult) { /* Which one? */
11632 case SSHSW_USR: /* /USER: */
11634 printf("?This switch requires an argument\n");
11637 if ((y = cmfld("Username","",&s,xxstring)) < 0)
11640 makestr(&ssh_tmpuid,s);
11644 printf("?This switch requires an argument\n");
11648 if ((x = cmfld("Password","",&s,xxstring)) < 0) {
11650 makestr(&ssh_tmpstr,"");
11656 if ((x = (int)strlen(s)) > PWBUFL) {
11657 makestr(&slmsg,"Internal error");
11658 printf("?Sorry, too long - max = %d\n",PWBUFL);
11661 makestr(&ssh_tmpstr,s);
11666 if ((x = cmnum("Number","",10,&z,xxstring)) < 0)
11668 if (z < 1 || z > 2) {
11669 printf("?Out of range: %d\n",z);
11678 if (trips++ == 0) { /* After first time through */
11679 cmfdbi(&kw, /* only parse switches, not port. */
11692 if ((x = cmcfm()) < 0) /* Get confirmation */
11694 if (clskconnx(1) < 0) { /* Close current Kermit connection */
11695 if ( ssh_tmpstr ) {
11696 memset(ssh_tmpstr,0,strlen(ssh_tmpstr));
11697 makestr(&ssh_tmpstr,NULL);
11699 return(success = 0);
11701 makestr(&ssh_hst,line); /* Stash everything */
11703 if (!sl_uid_saved) {
11704 ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
11707 ckstrncpy(uidbuf,ssh_tmpuid,UIDBUFLEN);
11708 makestr(&ssh_tmpuid,NULL);
11711 makestr(&ssh_prt,ssh_tmpport);
11712 makestr(&ssh_tmpport,NULL);
11714 makestr(&ssh_prt,NULL);
11716 /* Set the Subsystem to Kermit */
11718 makestr(&ssh_cmd,"sftp");
11722 if (!sl_ssh_ver_saved) {
11723 sl_ssh_ver = ssh_ver;
11724 sl_ssh_ver_saved = 1;
11726 #endif /* SSHTEST */
11729 /* Disable X11 Forwarding */
11731 if (!sl_ssh_xfw_saved) {
11732 sl_ssh_xfw = ssh_xfw;
11733 sl_ssh_xfw_saved = 1;
11735 #endif /* SSHTEST */
11739 if (ssh_tmpstr[0]) {
11740 ckstrncpy(pwbuf,ssh_tmpstr,PWBUFL+1);
11745 makestr(&ssh_tmpstr,NULL);
11754 makestr(&g_pswd,pwbuf); /* Save global pwbuf */
11755 g_pflg = pwflg; /* and flag */
11759 /* Line parameter to ttopen() is ignored */
11760 k = ttopen(line,&x,mdmtyp, 0);
11762 printf("?Unable to connect to %s\n",ssh_hst);
11765 return(success = 0);
11767 duplex = 0; /* Remote echo */
11768 ckstrncpy(ttname,line,TTNAMLEN); /* Record the command */
11769 debug(F110,"ssh ttname",ttname,0);
11770 makestr(&slmsg,NULL); /* No SET LINE error message */
11774 #endif /* NODIAL */
11775 success = 1; /* SET LINE succeeded */
11776 network = 1; /* Network connection (not serial) */
11777 local = 1; /* Local mode (not remote) */
11778 if ((reliable != SET_OFF || !setreliable))
11779 reliable = SET_ON; /* Transport is reliable end to end */
11781 DialerSend(OPT_KERMIT_CONNECT, 0);
11783 setflow(); /* Set appropriate flow control */
11789 #endif /* NETCONN */
11790 #endif /* CKLOGDIAL */
11794 if (nmac) { /* Any macros defined? */
11796 k = mlook(mactab,"on_open",nmac); /* Look this up */
11797 if (k >= 0) { /* If found, */
11798 if (dodo(k,ssh_hst,0) > -1) /* set it up, */
11799 parser(1); /* and execute it */
11809 /* Command was confirmed so we can pre-pop command level. */
11810 /* This is so CONNECT module won't think we're executing a */
11811 /* script if CONNECT was the final command in the script. */
11815 success = sftp_do_init();
11816 return(success = 1);
11832 if ((y = cmtxt("command parameters","",&s,xxstring)) < 0)
11834 if (ssh_tchk() < 0 || !ssh_cas || strcmp(ssh_cmd,"sftp")) {
11835 printf("?Not connected to SFTP Service\n");
11836 return(success = 0);
11838 success = sftp_do_cmd(cmresult.nresult,s);
11844 #endif /* SFTP_BUILTIN */
11846 if (cx == XXRLOG) { /* RLOGIN */
11851 printf("?Sorry, either TCP/IP is not available on this system or\n\
11852 necessary DLLs did not load. Use SHOW NETWORK to check network status.\n"
11858 x = nettype; /* Save net type in case of failure */
11859 z = ttnproto; /* Save protocol in case of failure */
11860 nettype = NET_TCPB;
11861 ttnproto = NP_RLOGIN;
11862 if ((y = setlin(XYHOST,0,1)) <= 0) {
11863 nettype = x; /* Failed, restore net type. */
11864 ttnproto = z; /* and protocol */
11873 printf("?Sorry, RLOGIN is not configured in this copy of C-Kermit.\n");
11875 #endif /* RLOGCODE */
11877 #endif /* NETCONN */
11878 #endif /* NOLOCAL */
11881 if (cx == XXTRA) { /* TRANSMIT */
11883 int i, n, xpipe = 0, xbinary = 0, xxlate = 1, xxnowait = 0, getval;
11887 struct FDB sf, sw, tx; /* FDBs for parse functions */
11889 extern int tcs_transp; /* Term charset is transparent */
11891 int tcs_transp = 1;
11892 #endif /* NOCSETS */
11895 xbinary = binary; /* Default text/binary mode */
11897 xbinary = 0; /* Default is text */
11898 #endif /* COMMENT */
11901 cmfdbi(&sw, /* First FDB - command switches */
11902 _CMKEY, /* fcode */
11903 "Filename, or switch", /* hlpmsg */
11905 "", /* addtl string data */
11906 nxmitsw, /* addtl numeric data 1: tbl size */
11907 4, /* addtl numeric data 2: 4 = cmswi */
11908 xxstring, /* Processing function */
11909 xmitsw, /* Keyword table */
11910 &sf /* Pointer to next FDB */
11912 cmfdbi(&sf, /* 2nd FDB - file to send */
11913 _CMIFI, /* fcode */
11914 "File to transmit", /* hlpmsg */
11916 "", /* addtl string data */
11917 0, /* addtl numeric data 1 */
11918 0, /* addtl numeric data 2 */
11925 #endif /* PIPESEND */
11929 _CMTXT, /* fcode */
11930 "Command", /* hlpmsg */
11932 "", /* addtl string data */
11933 0, /* addtl numeric data 1 */
11934 0, /* addtl numeric data 2 */
11939 #endif /* PIPESEND */
11945 if (cmresult.fcode != _CMKEY)
11947 c = cmgbrk(); /* Have switch, get break character */
11948 if ((getval = (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
11949 printf("?This switch does not take an argument\n");
11952 if (!getval && (cmgkwflgs() & CM_ARG)) {
11953 printf("?This switch requires an argument\n");
11956 n = cmresult.nresult; /* Numeric result = switch ID */
11957 switch (n) { /* Process the switch */
11959 case XMI_CMD: /* Transmit from a command */
11961 printf("?Sorry, system command access is disabled\n");
11964 sw.hlpmsg = "Command, or switch"; /* Change help message */
11965 xpipe = 1; /* (No way to undo this one) */
11967 #endif /* PIPESEND */
11969 case XMI_BIN: /* Binary */
11971 xxlate = 0; /* Don't translate charsets */
11975 case XMI_TXT: /* Text */
11977 xxlate = !tcs_transp; /* Translate if TERM CHAR not TRANSP */
11981 case XMI_TRA: /* Transparent text */
11983 xxlate = 0; /* But don't translate charsets */
11988 case XMI_VRB: /* /VERBOSE */
11989 case XMI_QUI: /* /QUIET */
11990 break; /* (not implemented yet) */
11991 #endif /* COMMENT */
11993 case XMI_NOW: /* /NOWAIT */
11997 case XMI_NOE: /* /NOWAIT */
12006 if (cmresult.fcode != _CMIFI && cmresult.fcode != _CMTXT)
12008 ckstrncpy(line,cmresult.sresult,LINBUFSIZ); /* Filename */
12009 if (zfnqfp(line,TMPBUFSIZ,tmpbuf))
12010 ckstrncpy(line,tmpbuf,LINBUFSIZ);
12012 if ((y = cmcfm()) < 0) /* Confirm */
12015 if ((apcactive == APC_LOCAL) ||
12016 ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
12017 return(success = 0);
12018 #endif /* CK_APC */
12019 if (cmresult.nresult != 0) {
12020 printf("?Only a single file may be transmitted\n");
12027 printf("?Sorry, a command to send from is required\n");
12032 #endif /* PIPESEND */
12034 if (scan && (filepeek
12037 #endif /* NOXFER */
12038 )) { /* If user didn't specify type */
12039 int k, x; /* scan the file to see */
12041 k = scanfile(s,&x,nscanfile);
12042 if (k > 0) xbinary = (k == FT_BIN) ? XYFT_B : XYFT_T;
12044 if (!xfrxla) xxlate = 0;
12045 success = transmit(s,
12046 (char) (xxnowait ? '\0' : (char)xmitp),
12053 #endif /* NOXMIT */
12056 if (cx == XXTYP || cx == XXCAT || cx == XXMORE ||
12057 cx == XXHEAD || cx == XXTAIL) {
12058 int paging = 0, havename = 0, head = 0, width = 0;
12059 int height = 0, count = 0;
12060 char pfxbuf[64], * prefix = NULL;
12061 char outfile[CKMAXPATH+1];
12064 int incs = 0, outcs = 0, cset = -1, number = 0;
12067 extern int fileorder;
12070 char guibuf[128], * gui_title = NULL;
12074 extern int tcsr, tcsl;
12075 #endif /* NOCSETS */
12077 #endif /* UNICODE */
12083 else if (cx == XXCAT)
12086 paging = (typ_page < 0) ? xaskmore : typ_page;
12090 if (cx == XXHEAD) {
12093 } else if (cx == XXTAIL) {
12099 if (inserver && !ENABLED(en_typ)) {
12100 printf("?Sorry, TYPE command disabled\n");
12105 cmfdbi(&sw, /* 2nd FDB - optional /PAGE switch */
12106 _CMKEY, /* fcode */
12107 "Filename or switch", /* hlpmsg */
12109 "", /* addtl string data */
12110 ntypetab, /* addtl numeric data 1: tbl size */
12111 4, /* addtl numeric data 2: 4 = cmswi */
12112 xxstring, /* Processing function */
12113 typetab, /* Keyword table */
12114 &sf /* Pointer to next FDB */
12116 cmfdbi(&sf, /* 1st FDB - file to type */
12117 _CMIFI, /* fcode */
12120 "", /* addtl string data */
12121 0, /* addtl numeric data 1 */
12122 0, /* addtl numeric data 2 */
12128 while (!havename) {
12129 x = cmfdb(&sw); /* Parse something */
12130 debug(F101,"type cmfdb","",x);
12131 debug(F101,"type cmresult.fcode","",cmresult.fcode);
12132 debug(F101,"type cmresult.nresult","",cmresult.nresult);
12133 if (x < 0) { /* Error */
12136 printf("?Filename required\n");
12139 } else if (cmresult.fcode == _CMKEY) {
12140 char c; int getval;
12142 getval = (c == ':' || c == '=');
12143 if (getval && !(cmgkwflgs() & CM_ARG)) {
12144 printf("?This switch does not take an argument\n");
12148 if (!getval && (cmgkwflgs() & CM_ARG)) {
12149 printf("?This switch requires an argument\n");
12150 /* Not if it has a default! */
12153 #endif /* COMMENT */
12154 switch (cmresult.nresult) {
12163 #endif /* CK_TTGWSIZ */
12174 if ((x = cmnum("Number of lines",
12175 "10",10,&y,xxstring)) < 0)
12177 head = (cmresult.nresult == TYP_TAI) ? -y : y;
12181 y = typ_wid > -1 ? typ_wid : cmd_cols;
12183 if ((x = cmnum("Column at which to truncate",
12184 ckitoa(y),10,&y,xxstring)) < 0)
12192 if ((x = cmnum("Height of GUI dialog",
12193 ckitoa(y),10,&y,xxstring)) < 0)
12200 if (!getval && (cmgkwflgs() & CM_ARG)) {
12201 printf("?This switch requires an argument\n");
12204 if ((x = cmfld("pattern","",&s,xxstring)) < 0)
12206 ckstrncpy(tmpbuf,s,TMPBUFSIZ);
12211 if (!getval && (cmgkwflgs() & CM_ARG)) {
12212 printf("?This switch requires an argument\n");
12215 if ((x = cmfld("prefix for each line","",&s,xxstring)) < 0)
12217 if ((int)strlen(s) > 63) {
12218 printf("?Too long - 63 max\n");
12221 ckstrncpy(pfxbuf,s,64);
12222 prefix = brstrip(pfxbuf);
12228 if (!getval && (cmgkwflgs() & CM_ARG)) {
12229 printf("?This switch requires an argument\n");
12232 if ((x = cmfld("Dialog box title","",&s,xxstring)) < 0) {
12236 if ((int)strlen(s) > 127) {
12237 printf("?Too long - 127 max\n");
12240 ckstrncpy(guibuf,s,128);
12241 gui_title = brstrip(guibuf);
12247 case TYP_NUM: /* /NUMBER */
12253 case TYP_XPA: /* /TRANSPARENT */
12259 case TYP_XIN: /* /CHARACTER-SET: */
12260 if (!getval && (cmgkwflgs() & CM_ARG)) {
12261 printf("?This switch requires an argument\n");
12264 if ((incs = cmkey(fcstab,nfilc,
12265 "character-set name","",xxstring)) < 0) {
12266 if (incs == -3) /* Note: No default */
12273 case TYP_XUT: /* /TRANSLATE-TO: */
12274 if (!getval && (cmgkwflgs() & CM_ARG)) {
12275 printf("?This switch requires an argument\n");
12279 if (!inserver && !k95stdout) {
12283 tocs = rlookup(txrtab,ntxrtab,tcsl);
12285 extern struct keytab ttcstab[];
12286 extern int ntxrtab;
12287 tocs = rlookup(ttcstab,ntermc,tocs);
12290 #endif /* CKOUNI */
12295 if ((outcs = cmkey(fcstab,nfilc,
12296 "character-set",tocs,xxstring)) < 0)
12299 #endif /* UNICODE */
12301 if ((x = cmofi("File for result lines","",
12304 ckstrncpy(outfile,s,CKMAXPATH);
12307 } else if (cmresult.fcode == _CMIFI)
12313 ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
12314 y = cmresult.nresult;
12316 if ((x = cmifi("Filename","",&s,&y,xxstring)) < 0) {
12318 printf("?Name of an existing file required\n");
12322 ckstrncpy(line,s,LINBUFSIZ);
12325 printf("?A single file please\n");
12329 if ( outfile[0] && gui ) {
12330 printf("?/GUI and /OUTPUT are incompatible\n");
12335 if ((y = cmcfm()) < 0) /* Confirm the command */
12340 if (cset < 0 && filepeek) { /* If no charset switches given */
12342 k = scanfile(line,&x,nscanfile); /* Call file analyzer */
12343 debug(F111,"type scanfile",line,k);
12344 debug(F101,"type scanfile flag","",x);
12346 case FT_UTF8: /* which can detect UTF-8... */
12350 case FT_UCS2: /* and UCS-2... */
12353 fileorder = x; /* even if there is no BOM. */
12354 debug(F101,"type fileorder","",fileorder);
12359 if (cset < 0) { /* If input charset still not known */
12361 tocs = rlookup(txrtab,ntxrtab,tcsl);
12363 extern struct keytab ttcstab[];
12364 extern int ntxrtab;
12365 tocs = rlookup(ttcstab,ntermc,incs);
12368 #endif /* CKOUNI */
12369 incs = lookup(fcstab,tocs,nfilc,&x);
12373 if (outcs == 0 && incs != 0) { /* Supply default target charset */
12374 int x = 0; /* if switch not given. */
12376 outcs = lookup(fcstab,tocs,nfilc,&x);
12378 #else /* !UNICODE */
12379 if (cset < 0) incs = outcs = 0;
12380 #endif /* UNICODE */
12382 if (outfile[0] && paging) /* This combination makes no sense */
12383 paging = 0; /* so turn off paging */
12386 /* No paging when dialog is used */
12387 if ( gui && paging )
12390 if ( !gui && height ) {
12391 printf("?The /HEIGHT switch is not supported without /GUI\n");
12396 if (count) paging = -1;
12397 debug(F111,"type",line,paging);
12400 s = (char *)1; /* ok, its an ugly hack */
12401 if (gui_text_popup_create(gui_title ?
12402 gui_title : line, height,width) < 0) {
12403 printf("?/GUI not supported on this system\n");
12412 dotype(line,paging,0,head,pat,width,prefix,incs,outcs,s,number);
12415 #endif /* NOFRILLS */
12418 if (cx == XXXLA) { /* TRANSLATE file's charset */
12419 _PROTOTYP (int doxlate, ( void ) );
12422 #endif /* NOCSETS */
12424 if (cx == XXVER) { /* VERSION */
12426 extern char * ck_patch, * ck_s_test;
12428 extern int hmtopline;
12429 #endif /* COMMENT */
12430 if ((y = cmcfm()) < 0)
12434 printf("\n%s, for%s (64-bit)\n Numeric: %ld",versio,ckxsys,vernum);
12436 printf("\n%s, for%s\n Numeric: %ld",versio,ckxsys,vernum);
12437 #endif /* CK_64BIT */
12439 printf("Authors:\n");
12440 printf(" Frank da Cruz, Columbia University\n");
12441 printf(" Jeffrey Eric Altman, Secure Endpoints, Inc. %s\n",
12442 "<jaltman@secure-endpoints.com>"
12444 printf(" Contributions from many others.\n");
12447 printf("\nTHIS IS A TEST VERSION, NOT FOR PRODUCTION USE.\n");
12451 printf(" Patches: %s\n", ck_patch);
12454 printf(" Type COPYRIGHT for copyright and license.\n\n");
12462 #endif /* COMMENT */
12464 return(success = 1);
12467 if (cx == XXCPR) { /* COPYRIGHT or LICENSE */
12468 _PROTOTYP( int hmsgaa, (char * [], char *) );
12469 extern char * ck_cryear;
12470 if ((y = cmcfm()) < 0)
12472 hmsgaa(copyright,ck_cryear);
12473 return(success = 1);
12476 #ifndef MAC /* Only for multiuser systems */
12479 if (cx == XXWHO) { /* WHO */
12482 if (inserver && !ENABLED(en_who)) {
12483 printf("?Sorry, WHO command disabled\n");
12488 if ((z = cmcfm()) < 0) return(z);
12490 printf("?Sorry, who not allowed\n");
12491 return(success = 0);
12495 if ((y = cmtxt("user name","",&s,xxstring)) < 0) return(y);
12497 printf("?Sorry, WHO command disabled\n");
12498 return(success = 0);
12500 if (!(wc = getenv("CK_WHO"))) wc = WHOCMD;
12502 if ((int) strlen(wc) > 0) {
12503 ckmakmsg(line,LINBUFSIZ,wc," ",s,NULL);
12506 #endif /* datageneral */
12507 return(success = 1);
12509 #endif /* NOFRILLS */
12514 if (cx == XXWRI || cx == XXWRL || cx == XXWRBL) { /* WRITE */
12515 int x,y; /* On stack in case of \fexec() */
12516 if ((x = cmkey(writab,nwri,"to file or log","",xxstring)) < 0) {
12517 if (x == -3) printf("?Write to what?\n");
12520 if ((y = cmtxt("text","",&s,xxstring)) < 0) return(y);
12523 case LOGD: y = ZDFILE; break;
12524 case LOGP: y = ZPFILE; break;
12526 case LOGS: y = ZSFILE; break;
12527 #endif /* NOLOCAL */
12528 case LOGT: y = ZTFILE; break;
12530 case LOGW: y = ZWFILE; break;
12532 case LOGX: /* SCREEN (stdout) */
12533 case LOGE: /* ERROR (stderr) */
12536 (cx == XXWRL) ? "WRITELN ERROR" : "WRITE ERROR", s,0);
12537 fprintf(stderr,"%s%s",s,(cx == XXWRL) ? "\n" : "");
12540 (cx == XXWRL) ? "WRITELN SCREEN" : "WRITE SCREEN", s,0);
12541 printf("%s%s",s,(cx == XXWRL) ? "\n" : "");
12543 return(success = 1);
12544 default: return(-2);
12546 if (chkfn(y) > 0) {
12547 x = (cx == XXWRI) ? zsout(y,s) : zsoutl(y,s);
12548 debug(F111,"WRITE",
12549 (cx == XXWRI) ? "zsout" : "zsoutl",
12551 if (x < 0) printf("?Write error\n");
12554 printf("?File or log not open\n");
12556 debug(F101,"WRITE x","",x);
12557 return(success = (x == 0) ? 1 : 0);
12559 #endif /* NOFRILLS */
12562 if (cx == XXASC || cx == XXBIN) {
12563 if ((x = cmcfm()) < 0) return(x);
12566 Make C-Kermit work like other ftp clients, where
12567 the ASCII (TEXT) and BINARY commands are global settings.
12570 doftpglobaltype((cx == XXASC) ? XYFT_T : XYFT_B);
12571 /* Fall thru--the command it should apply to both FTP and Kermit */
12572 /* return(success = 1); */
12574 #endif /* NEWFTP */
12576 xfermode = XMODE_M; /* Set manual Kermit transfer mode */
12577 binary = (cx == XXASC) ? XYFT_T : XYFT_B;
12578 return(success = 1);
12580 #endif /* NOXFER */
12583 if ((x = cmcfm()) < 0) return(x);
12585 return(success = (y > -1) ? 1 : 0);
12589 if (cx == XXMKDIR || cx == XXLMKD) {
12592 if (!locus && cx != XXLMKD) {
12596 return(dormt(XZMKD));
12597 #endif /* NOXFER */
12601 if (inserver && !ENABLED(en_mkd)) {
12602 printf("?Sorry, directory creation is disabled\n");
12606 if ((x = cmfld("Name for new directory","",&s,xxstring)) < 0) {
12610 printf("?Directory name required\n");
12614 ckstrncpy(line,s,LINBUFSIZ);
12616 if ((x = cmcfm()) < 0) return(x);
12618 bgchk(); /* Set msgflg */
12619 x = ckmkdir(0,s,&p,msgflg,0);
12621 if (msgflg && x == 0)
12622 printf("?Directory already exists\n");
12623 #endif /* COMMENT */
12624 return(success = (x < 0) ? 0 : 1);
12626 if (cx == XXRMDIR || cx == XXLRMD) { /* RMDIR */
12629 if (!locus && cx != XXLRMD) {
12633 return(dormt(XZRMD));
12634 #endif /* NOXFER */
12638 if (inserver && !ENABLED(en_rmd)) {
12639 printf("?Sorry, directory removal is disabled\n");
12643 if ((x = cmdir("Name of directory to be removed","",&s,xxstring)) < 0)
12645 ckstrncpy(line,s,LINBUFSIZ);
12647 if ((x = cmcfm()) < 0) return(x);
12649 x = ckmkdir(1,s,&p,msgflg,0);
12650 return(success = (x < 0) ? 0 : 1);
12652 #endif /* CK_MKDIR */
12656 return(dotelopt());
12657 #endif /* TNCODE */
12660 if (cx == XXNPSH) {
12661 if ((z = cmcfm()) < 0) return(z);
12665 #endif /* NOSERVER */
12668 #endif /* PIPESEND */
12669 return(success = 1);
12671 #endif /* NOPUSH */
12674 if (cx == XXNSCR) {
12675 if ((z = cmcfm()) < 0) return(z);
12677 return(success = 1);
12682 if (cx == XXLOCAL) /* LOCAL variable declarations */
12683 return(success = dolocal());
12686 if (cx == XXKERMI) { /* The KERMIT command */
12688 extern char **xargv;
12691 if ((y = cmtxt("kermit command-line arguments, -h for help",
12692 "",&s,xxstring)) < 0)
12694 ckstrncpy(line,"kermit ",LINBUFSIZ);
12695 ckstrncat(line,s,LINBUFSIZ-8);
12696 xwords(line,64,list,0);
12697 for (i = 1; i < 64; i++) {
12707 extern int justone;
12708 debug(F000,"KERMIT sstate","",sstate);
12709 justone = 1; /* Force return to command mode */
12710 proto(); /* after protocol */
12713 debug(F101,"KERMIT sstate","",sstate);
12714 return(success = 1); /* Not exactly right, but... */
12717 if (cx == XXDATE) { /* DATE command */
12718 extern char cmdatebuf[], * cmdatemsg;
12722 if ((y = cmtxt("date and/or time, or carriage return for current",
12723 "",&s,xxstring)) < 0)
12726 dp = cmcvtdate(s,1);
12728 printf("?%s\n",cmdatemsg ? cmdatemsg : "Date conversion error");
12735 /* This works fine but messes up my "dates" torture-test script */
12737 if ((x = cmdate("Date and/or time, or carriage return for current",
12738 "",&s,0,xxstring)) < 0) {
12741 printf("%s\n",cmdatebuf);
12744 #endif /* COMMENT */
12751 #endif /* NOFRILLS */
12752 #endif /* NOPUSH */
12754 #ifdef BROWSER /* Defined only ifndef NOPUSH */
12756 return(dobrowse());
12757 #endif /* BROWSER */
12760 if (cx == XXTAPI) { /* Microsoft TAPI */
12761 return (success = dotapi());
12763 #endif /* CK_TAPI */
12766 if (cx == XXWHERE) {
12767 extern char * rfspec, * sfspec, * srfspec, * rrfspec;
12768 if ((x = cmcfm()) < 0) return(x);
12769 printf("\nFile most recently...\n\n");
12770 printf(" Sent: %s\n", sfspec ? sfspec : "(none)");
12771 if (sfspec && srfspec) {
12772 printf(" Stored as: %s\n", srfspec);
12775 printf(" Received: %s\n", rrfspec ? rrfspec : "(none)");
12776 if (rfspec && rrfspec)
12777 printf(" Stored as: %s\n", rfspec);
12779 "\nIf the full path is not shown, then the file is probably in your current\n"
12782 "directory or your download directory (if any - SHOW FILE to find out).\n\n"
12784 return(success = 1);
12786 #endif /* NOXFER */
12791 #endif /* CK_RECALL */
12794 if (cx == XXCHRT) /* Change Kermit's root directory */
12795 return(dochroot());
12796 #endif /* CKROOT */
12799 if (cx == XXAUTH) { /* KERBEROS */
12800 x = cp_auth(); /* Parse it */
12803 printf("?Command disabled in IKSD.\r\n");
12804 return(success = 0);
12807 if (x < 0) /* Pass parse errors back */
12809 return(success = doauth(cx));
12811 #endif /* CK_KERBEROS */
12814 if (cx == XXTERM) {
12815 return(settrmtyp());
12817 #endif /* NOLOCAL */
12819 if (cx == XXSTATUS) {
12820 if ((x = cmcfm()) < 0) return(x);
12821 printf( " %s\n", success ? "SUCCESS" : "FAILURE" );
12822 return(0); /* Don't change it */
12825 if (cx == XXFAIL) {
12826 if ((x = cmcfm()) < 0) return(x);
12827 return(success = 0);
12830 if (cx == XXSUCC) {
12831 if ((x = cmcfm()) < 0) return(x);
12832 return(success = 1);
12835 if (cx == XXNLCL) {
12836 extern int nolocal;
12837 if ((x = cmcfm()) < 0) return(x);
12839 return(success = 1);
12843 if (cx == XXRASG) /* Shortcuts for REMOTE commands */
12844 return(dormt(XZASG));
12846 return(dormt(XZCWD));
12848 return(dormt(XZCPY));
12850 return(dormt(XZDEL));
12852 return(dormt(XZDIR));
12854 return(dormt(XZXIT));
12856 return(dormt(XZHLP));
12858 return(dormt(XZHOS));
12860 return(dormt(XZKER));
12862 return(dormt(XZPWD));
12864 return(dormt(XZQUE));
12866 return(dormt(XZREN));
12868 return(dormt(XZMKD));
12870 return(dormt(XZMSG));
12872 return(dormt(XZRMD));
12874 return(dormt(XZSET));
12876 return(dormt(XZSPA));
12878 return(dormt(XZTYP));
12880 return(dormt(XZWHO));
12882 return(dormt(XZCDU));
12884 return(dormt(XZPRI));
12885 #endif /* NOXFER */
12887 if (cx == XXRESET) { /* RESET */
12888 if ((x = cmcfm()) < 0)
12890 concb((char)escape); /* Make command echoing to normal */
12891 doclean(0); /* Close all files */
12892 return(success = 1);
12897 if (cx == XXASSOC) /* ASSOCIATE */
12899 #endif /* NOCSETS */
12900 #endif /* NOXFER */
12903 if (cx == XXSHIFT) { /* SHIFT */
12904 if ((y = cmnum("Number of arguments to shift","1",10,&x,xxstring)) < 0)
12906 if ((z = cmcfm()) < 0)
12908 return(success = doshift(x));
12914 return(domanual());
12915 #endif /* NOHELP */
12918 if (cx == XXSORT) /* SORT an array */
12922 if (cx == XXPURGE) {
12924 if (inserver && (!ENABLED(en_del)
12927 #endif /* CK_LOGIN */
12929 printf("?Sorry, DELETE is disabled\n");
12934 if ((apcactive == APC_LOCAL) ||
12935 ((apcactive == APC_REMOTE) && (!(apcstatus & APC_UNCH))))
12936 return(success = 0);
12937 #endif /* CK_APC */
12942 if ((x = cmtxt("optional switches followed by filespec",
12943 "",&s,xxstring)) < 0)
12946 printf("?Sorry, DCL access is disabled\n");
12949 ckstrncpy(line,s,LINBUFSIZ);
12951 x = mlook(mactab,"purge",nmac);
12952 return(success = dodo(x,s,cmdstk[cmdlvl].ccflgs));
12956 #endif /* CKPURGE */
12960 if (cx == XXFAST) {
12961 if ((x = cmcfm()) < 0) return(x);
12962 x = mlook(mactab,"fast",nmac);
12963 return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
12966 if ((x = cmcfm()) < 0) return(x);
12967 x = mlook(mactab,"cautious",nmac);
12968 return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
12971 if ((x = cmcfm()) < 0) return(x);
12972 x = mlook(mactab,"robust",nmac);
12973 return(success = dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
12977 if (cx == XXSCRN) { /* SCREEN */
12979 if ((x = cmkey(scntab, nscntab,"screen action","", xxstring)) < 0)
12981 switch (x) { /* MOVE-TO (cursor position) */
12983 if ((y = cmnum("Row (1-based)","",10,&z,xxstring)) < 0)
12986 y = cmnum("Column (1-based)","1",10,&z,xxstring);
12990 if ((y = cmcfm()) < 0)
12992 if (row < 0 || col < 0) {
12993 printf("?Row and Column must be 1 or greater\n");
12996 if (cmd_rows > 0 && row > cmd_rows)
12998 if (cmd_cols > 0 && col > cmd_cols)
13000 y = ck_curpos(row,col);
13001 return(success = (y > -1) ? 1 : 0);
13003 case SCN_CLR: /* CLEAR */
13004 if ((y = cmcfm()) < 0)
13006 debug(F100,"screen calling ck_cls()","",0);
13008 return(success = (y > -1) ? 1 : 0);
13010 case SCN_CLE: /* CLEOL */
13011 if ((y = cmcfm()) < 0)
13014 return(success = (y > -1) ? 1 : 0);
13022 #endif /* TCPSOCKET */
13023 #endif /* NOHTTP */
13026 if (cx == XXARRAY) { /* ARRAY */
13028 extern int showarray();
13029 #endif /* NOSHOW */
13030 if ((x = cmkey(arraytab, narraytab,"Array operation","",xxstring)) < 0)
13034 return(dodcl(XXDCL));
13039 return(showarray());
13040 #endif /* NOSHOW */
13042 return(copyarray());
13045 return(clrarray(x));
13049 return(rszarray());
13051 return(linkarray());
13054 printf("?Sorry, not implemented yet - \"%s\"\n",cmdbuf);
13058 if (cx == XXTRACE) /* TRACE */
13065 return(douchmod()); /* Do Unix chmod */
13067 #endif /* CK_PERMS */
13070 return(doprompt());
13075 if (cx == XXDEBUG) { /* DEBUG */
13078 return(seton(&dummy));
13080 return(seton(&deblog));
13083 if (cx == XXMSG || cx == XXXMSG) { /* MESSAGE */
13084 extern int debmsg; /* Script debugging messages */
13085 if ((x = cmtxt("Message to print if SET DEBUG MESSAGE is ON or STDERR",
13086 "",&s,xxstring)) < 0)
13088 if (!s) /* Watch out for null result */
13089 s = ""; /* Make it an empty string */
13090 else /* Not null */
13091 s = brstrip(s); /* Strip braces and doublequotes */
13092 switch (debmsg) { /* Not debugging - don't print */
13096 printf("%s",s); /* Print to stdout */
13097 if (cx == XXMSG) printf("\n");
13100 fprintf(stderr,"%s",s); /* Ditto but print to stderr */
13101 if (cx == XXMSG) fprintf(stderr,"\n");
13104 return(0); /* Return without affecting SUCCESS */
13108 if (cx == XXLEARN) { /* LEARN */
13109 struct FDB of, sw, cm;
13110 int closing = 0, off = 0, on = 0, confirmed = 0;
13113 cmfdbi(&sw, /* 2nd FDB - optional /PAGE switch */
13114 _CMKEY, /* fcode */
13115 "Script file name, or switch", /* hlpmsg */
13117 "", /* addtl string data */
13118 3, /* addtl numeric data 1: tbl size */
13119 4, /* addtl numeric data 2: 4 = cmswi */
13120 xxstring, /* Processing function */
13121 learnswi, /* Keyword table */
13122 &of /* Pointer to next FDB */
13124 cmfdbi(&of,_CMOFI,"","","",0,0,xxstring,NULL,&cm);
13125 cmfdbi(&cm,_CMCFM,"","","",0,0,NULL,NULL,NULL);
13128 while (!confirmed) {
13129 x = cmfdb(&sw); /* Parse something */
13132 switch (cmresult.fcode) { /* What was it? */
13133 case _CMOFI: /* Output file name */
13134 ckstrncpy(line,cmresult.sresult,LINBUFSIZ);
13136 case _CMKEY: /* Switch */
13138 if ((c == ':' || c == '=') && !(cmgkwflgs() & CM_ARG)) {
13139 printf("?This switch does not take an argument\n");
13142 switch (cmresult.nresult) {
13143 case 2: /* /CLOSE */
13144 closing = 1; /* Fall thru on purpose */
13155 case _CMCFM: /* Confirmation */
13165 makestr(&learnfile,NULL);
13174 makestr(&learnfile,line);
13176 char * modes = "w";
13177 learnfp = fopen(learnfile,modes);
13179 debug(F110,"LEARN file open error",learnfile,0);
13184 if (zfnqfp(learnfile,TMPBUFSIZ,tmpbuf))
13185 makestr(&learnfile,tmpbuf);
13186 #endif /* ZFNQFP */
13187 debug(F110,"LEARN file open ok",learnfile,0);
13189 printf("Recording to %s...\n\n",learnfile);
13191 " WARNING: If you type your password during script recording, it will appear\n\
13192 in the file. Be sure to edit it or take other appropriate precautions.\n\n"
13195 fputs( "; Scriptfile: ",learnfp);
13196 fputs(learnfile,learnfp);
13197 fputs("\n; Directory: ",learnfp);
13198 fputs(zgtdir(),learnfp);
13199 fputs("\n; Recorded: ",learnfp);
13200 fputs(ckdate(),learnfp);
13201 fputs("\n",learnfp);
13210 debug(F101,"LEARN learning","",learning);
13211 return(success = 1);
13213 #endif /* CKLEARN */
13216 if (cx == XXUSER || cx == XXACCT) {
13217 if (!ftpisopen()) {
13218 printf("?FTP connection is not open\n");
13221 return(success = (cx == XXUSER) ? doftpusr() : doftpacct());
13223 if (cx == XXSITE || cx == XXPASV) {
13224 if (!ftpisopen()) {
13225 printf("?FTP connection is not open\n");
13228 return(success = (cx == XXSITE) ? doftpsite() : dosetftppsv());
13230 #endif /* NEWFTP */
13232 if (cx == XXORIE) { /* ORIENTATION */
13233 extern char * myname;
13235 char * s, *p, vbuf[32];
13236 char * vars[16]; char * legend[16];
13238 if ((y = cmcfm()) < 0)
13241 printf("\nProgram name:\n %s\n\n",myname);
13245 vars[0] = "home"; legend[0] = "Your home directory";
13246 vars[1] = "directory"; legend[1] = "K95's current directory";
13247 vars[2] = "exedir"; legend[2] = "K95 Program directory";
13248 vars[3] = "inidir"; legend[3] = "K95 Initialization file directory";
13249 vars[4] = "startup"; legend[4] = "Current directory when started";
13251 vars[5] = "common";
13252 legend[5] = "K95 data for all users and K95SITE.INI file";
13254 vars[6] = "personal"; legend[6] = "Your personal data directory tree";
13255 vars[7] = "desktop"; legend[7] = "Your deskop directory tree";
13257 vars[8] = "appdata";
13258 legend[8] = "Your personal K95 data tree and K95CUSTOM.INI file";
13260 vars[9] = "download"; legend[9] = "Your K95 download directory";
13261 vars[10] = "tmpdir"; legend[10] = "Your TEMP directory";
13262 vars[11] = NULL; legend[11] = NULL;
13264 for (i = 0; i < 16 && vars[i]; i++) {
13265 printf("%s:\n",legend[i]);
13266 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13267 ckmakmsg(vbuf,32,"\\v(",vars[i],")",NULL);
13268 printf(" Variable: %s\n",vbuf);
13269 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13272 zzstring(vbuf,&s,&y);
13274 ckGetLongPathName(tmpbuf,line,LINBUFSIZ);
13275 printf(" Long name: %s\n",line);
13276 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13278 GetShortPathName(tmpbuf,line,LINBUFSIZ);
13279 printf(" Short name: %s\n",line);
13280 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13282 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13286 vars[0] = "home"; legend[0] = "Your home directory";
13287 vars[1] = "directory"; legend[1] = "Kermit's current directory";
13288 vars[2] = "exedir"; legend[2] = "Kermit's program directory";
13289 vars[3] = "inidir"; legend[3] = "Initialization file directory";
13290 vars[4] = "startup"; legend[4] = "Current directory when started";
13291 vars[5] = "download"; legend[5] = "Kermit download directory";
13292 vars[6] = NULL; legend[6] = NULL;
13294 for (i = 0; i < 16 && vars[i]; i++) {
13295 printf("%s:\n",legend[i]);
13296 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13297 ckmakmsg(vbuf,32,"\\v(",vars[i],")",NULL);
13298 printf(" Variable: %s\n",vbuf);
13299 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13302 zzstring(vbuf,&s,&y);
13303 printf(" Value: %s\n",tmpbuf);
13304 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13306 if (++n > cmd_rows - 3) if (!askmore()) return(0); else n = 0;
13309 return(success = 1);
13313 if (cx == XXDIALER) {
13315 return(success = 1);
13319 if (cx == XXCONT) { /* CONTINUE */
13320 if ((x = cmcfm()) < 0)
13322 if (!xcmdsrc) { /* At prompt: continue script */
13324 popclvl(); /* Pop command level */
13325 return(success = 1); /* always succeeds */
13327 } else { /* In script: whatever... */
13328 x = mlook(mactab,"continue",nmac);
13329 /* Don't set success */
13330 return(dodo(x,NULL,cmdstk[cmdlvl].ccflgs));
13337 NOTE: Syntax is PUTENV name value, not PUTENV name=value.
13338 I could check for this but it would be too much magic.
13340 if (cx == XXPUTE) { /* PUTENV */
13341 char * t = tmpbuf; /* Create or alter environment var */
13342 char * s1 = NULL, * s2 = NULL;
13343 if ((x = cmfld("Variable name","",&s,xxstring)) < 0)
13345 if (s) if (s == "") s = NULL;
13346 (VOID) makestr(&s1,s);
13348 printf("?PUTENV - memory allocation failure\n");
13351 if ((x = cmtxt("Value","",&s,xxstring)) < 0)
13353 if (s) if (s == "") s = NULL;
13354 (VOID) makestr(&s2,s);
13355 success = doputenv(s1,s2);
13356 (VOID) makestr(&s1,NULL);
13357 (VOID) makestr(&s2,NULL);
13360 #endif /* NOPUTENV */
13363 if (cx == XXNOTAV) { /* Command in table not available */
13364 ckstrncpy(tmpbuf,atmbuf,TMPBUFSIZ);
13365 if ((x = cmtxt("Rest of command","",&s,NULL)) < 0)
13367 printf("Sorry, \"%s\" not configured in this version of Kermit.\n",
13370 return(success = 0);
13372 return(-2); /* None of the above */
13374 } /* end of docmd() */